- logs\localhost.xxxxx.log(运行时错误)
- webapps写入的log(非运行时错误)
分类: Java
如何写好干净的代码
# PCMonitor
为什么要这么构造包结构:
1) 同目录之间的包应该是同级的
2) class应该调用子包和同级目录中的class
3) 给予上级目录调用的等同于对外提供方法的应该提供Interface
4) 包与包之间之间除了Interface的接口其他不可互相调用
5) 不是包外可见的方法不要增加public关键字
关于巨大的Utils类这种存在,我们可以在包的根部写一个Abstract的Utils,然后每个包中写一个Utils并继承根包下的Utils(等效于只应该调用包内的class),如果有多个包共同调用的方法可以新建一个abstract表述清楚是哪几个package要调用,并继承根目录下的Utils,同时在包内的Util继承你刚编写的abstract Utils。
Junit编写说明:
1) 每一个method编写一个Test
2) 只关注Method的输入输出
3) public方法直接调用
private方法用反射调用
4)保持整个编码过程中,Junit测试的正确性
为什么单例要写成这种鬼样子
用过Struts2的同学应该会觉得我写的单例很熟悉。。嗯就是Struts里面的View的写法。。。
所以单例为什么要这么写。或者说volatile和synchronized关键字有什么作用
代码在单线程模式下执行顺序会看起来和代码的位置相同。无论是什么编程语言都会有这样的错觉这归功于现代CPU做了一系列的优化和保证措施。但实际上代码片段在内存中会分成更细的几个部分;
例如a++这个操作机器指令就至少有三条,CPU不保证三条操作中不会插入其他的操作,所以,即使是你写的代码是单进程的,因为CPU有N多代码片段要执行,CPU不能保证每一步都能使原子操作;
JVM就当成一个逻辑上的PC,类似的CPU模型,也会导致同样的问题。
一个java程序中可能会有多个代码片段需要getInstance,如果进程A和进程B同时getInstance,就会有概率出现getInstance时候验空会两个进程都得到个空,然后同时new一个新的对象导致实例过程不正确。
物理机上的X86 CPU有CAS模块硬件实现原子性操作,而java在早期是通过锁来实现的。用锁来保证一段时间内只有一个进程能访问到getInstance代码片段,从而防止出现A,B都getInstance的时候都会new操作。
而volatile的做法是,同时也是volatile的含义是:
每当局部变量需要读取volatile修饰的字段时候,JVM总能保证是从不会将读取的指令插入到上一条将本地内存往主存写的过程之间。
一个正确的单例
public class A{
public final static A instance = new A();
public static A getA(){
return instance;
}
//something to do
}
package com.liangyumingblog;
public class SimpleSinglton
{
private static class Instance
{
private final static SimpleSinglton instance = new SimpleSinglton();
}
public SimpleSinglton getInstance()
{
return Instance.instance;
}
}
代码
- 关于代码结构:
每个package就是一个subsystem,一个subsystem应该只实现一个功能。
- 关于性能和代码的阅读性:
最简单的,KMP算法用自动状态机解释比用next数组解释要清晰且容易理解。
AOP及SPRING AOP
Java中的类加载器
在Java中关于一个类是否相等,是通过类的全限定名称来判断的,这里的全限定名称包括了类加载器在内
如果同一个类由不同加载器加载则判定两个类不相同(尽管二进制文件一致)
测试代码:
利用注解,增加项目的可阅读性
平时的项目中,总有这样或者那样的字段我们是要加密之后存进数据库的。
那么能否在写JavaBean的时候直接注明哪些是加密字段,提交数据库和从数据库返回时自动加解密呢。
为了清晰易懂我选择了用Java注解配合Spring来完成这件事情
Junit和Spring配合
为什么我们要用getter/setter方法
第一,历史遗留原因,get/set方法从一种个人习惯被整个产业绑架了;
第二,面向对象的需要,我们可以把基本数据类型做输出前处理;
第三,我们可以把对数据的完整性的校验从流程类往基本对象身上推,逻辑层很少或者根本不用管理任何数据验证的事项,避免在逻辑代码中夹杂大量的数据校验(这个很重要,大部分业务代码为了尽快完成都是想到什么就是添加什么)。