- 浏览: 125963 次
- 性别:
- 来自: 上海
最新评论
-
lliiqiang:
最简单的显示 存储分离,有的时候错别字与错误数据存储兼容。还有 ...
关于软件可扩展性与代码防御性编程的一点思考 -
bmqnc:
cqh520llr 写道sb,不帖代码,以后人家搜索到了浪费人 ...
今天自己做了redo-undo功能 -
cqh520llr:
我也觉得,代码风格和不定性样式太多了,
编码风格不取决于自己,取决于领导班子和现有代码 -
cqh520llr:
sb,不帖代码,以后人家搜索到了浪费人家时间,而且这个代码贴出 ...
今天自己做了redo-undo功能 -
shiqicai:
太隐晦,看不懂。
康神与顿神
文章列表
LinkedHashMap源代码解析
- 博客分类:
- java
LinkedHashMap源代码比较简单,由于LinkedHashMap继承自HashMap,Hash和存放那部分操作和HashMap是相同的。只要看懂了HashMap那部分代码,这个都不难看懂。
唯一与HashMap的区别就是在里面还维护了由header构成头指针形成的一个双向链表。每次addEntry和remove的时候要维护这个链表。
唯一困惑的地方是containsValue那个函数,函数注解说覆盖了HashMap的该方法,因为该方法更快,但实际上因为元素的个数是一样的,并且采用的都是暴力遍历的那种方式,复杂度都是一样的。唯一的区别是覆盖的方法更简洁些,如果硬要说这个速度比较快的话, ...
这篇文章说的其实是重复造成代码的code smell,这点深有体会,现在的项目中之前的程序员很多地方都是拷贝黏贴,造成大量的重复,这样其实坏处很多:
1.代码code smell加重,代码显得冗余啰嗦,为以后的代码阅读和维护人员造成不便。这一点正如郑老师讲的。
2.代码膨胀(记得看过云风的blog,他说大话的核心代码只有10w(?)左右),现在很多项目本身不是特别大,但代码却非常多,这里面很多因素造成的。一是很多程序员本身素质确实有待提高,二是出现很多很官僚化的做法就是经常问你代码写了多少,包括公司内部的考核和应聘的面试,虽然代码量是考核程序员的一种手段,但肯定不是唯一的手段,而且不是关键的 ...
这篇文章的核心思想实际依然是对语句块的一种重构,其实简单来说,就是郑老师说的写代码不能平铺直叙,这样写代码是体力活,简单的运用一些编程技巧其实会很是代码简洁干净很多。
其实我觉得要真是用体力写代码的话,不但自己以后维护代码体力,关键是让接手维护代码的人感觉更体力,而且这种体力是成倍的增加,以为代码多了,代码乱了。
第六篇文章里其实讲的是核心思想就是要将变量的声明与使用尽量放在一起,这其实很有道理,这样才能便于查看在函数使用的地方变量在哪里初始化与声明,更容易的阅读和控制代码。
之前项目的程序员应该之前用过c,将所有的变量放在函数的起始地方进行声明,我觉得这样非常不好。
正如郑老师讲的,如果出现大段的变量声明与使用分家,实际上很可能意味着这个函数需要重构为更小的函数。
最后一句话我觉得说得很有意思:在干净的代码世界里,大函数是不受欢迎的。
最近一直在关注代码之丑系列的文章,郑老师之前开篇说的挺有意思,之前有代码之美系列的文章了,因此他准备写些关于代码之丑的文章,很精辟,就像模式与反模式的关系一样。
看了看,觉得很有收获。
第9个讲的是是否允许多层缩进的问题,很有启发。
不过我觉得多层缩进的造成的问题其实是代码变得很乱,实际上可能造成单个函数体很大,郑老师这篇文章其实核心的思想还是说需要将函数进行拆分,否则大段的语句嵌套,造成代码逻辑不可阅读性变大,说到底,还是对代码的驾驭能力,以及模块化和oo的思想很重要。
在类库中很多函数设计很巧妙,至今我还在体会他们的设计哲学是怎么样的,比如关于LinkedList的,里面有一个函数:
public E getFirst() {
if (size==0)
throw new NoSuchElementException();
return header.next.element;
}
返回第一个元素,如果之前我没看过这段代码的话,让我自己写的话,我可能会返回一个null值,但类库里是抛出一个异常。很多类库的函数(比如remove操作等)都是这样设计的。
仔细想想这样确实有道理。
因为返回null和抛出异常实际上两个 ...
public boolean addAll(int index, Collection<? extends E> c) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Object[] a = c.toArray ...
看下entry的代码:
/**
* Returns the indexed entry.
*/
private Entry<E> entry(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: " ...
git这个工具说是分布式的,但我看了看,很多地方还是值得商量的,不是每个公司就一定适合拿这个工具来作版本管理,就拿所谓的分布式来说吧,其实很多公司还是做的是集中式管理(特别是很多小公司,中型公司也有),就是基本上整个开发部门地点比较集中,我觉得从管理上来说集中式的那种版本管理可能更好,不用所谓的分布式,而且git目前我感觉可用的第三方工具不是很多,而且大家这么几年都习惯用中式那种版本管理系统,如果当前的系统可以工作的很好,其实不用为了git而git,这样反而不好。因为任何一个工具的使用都是有一定的成本的,包括学习的成本。
有一个比较Tricky的地方是toArray方法,看下面的代码:
public <T> T[] toArray(T[] a) {
if (a.length < size)
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
...
今天看了一下HashMap的源代码,除了数学Hash部分没看懂,其他基本都看懂了。
HashMap中其实主要使用一个数组来保存值的,一个对象在map中要想相等,有两个条件,第一个是它的哈希码必须相等,即在map的内部数组的桶索引必须相等,第二是它的key值也必须相等,因为map中是不允许存在key值相同的对象的。
唯一看到一个地方感觉不爽的是containsValue方法,因为这个方法是遍历整个数组来进行查找,不过本身map对value值就没有做出限制,因此这里也只能用这种方式进行查找。
还有一个比较有意思的地方时它对null key的处理,map中将所有null key放置在内部数组的i ...
HashSet里面主要是利用了HashMap的数据结构,我感觉挺简单的。所有的add,size,isEmpty等等都映射到了内置的成员变量map(是个HashMap或者LinkedHashMap)上,如add方法:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
就是用到了map,不过这里放置的时候每个key的value都是同一个,都是内置的一个Object对象:
private static final Object PRESENT = new Object();
不过里面有个构造函 ...
很多时候哨兵能简化问题的处理方式,今天做了一个字符串处理的函数,发现原来想的很复杂,要考虑很多种情况,后来发现在原来的字符串后面加上哨兵字符后,能够简化很多处理的问题,不用分成多种情况考虑字符串的边界情况。这个很无敌。。。。
我总结了一些,应该是字符串处理的时候很多边界情况最难处理,如果我们能在处理上做一些简化(需要一些技巧性的东西),代码就能清楚和整洁一些。
这样带来的好处是代码不会显得特别乱,对于后期代码维护人员来说更友好一些。(我感觉公司目前的这个产品代码的很差的地方就在这),原来的程序员我感觉写代码的时候不考虑后期的维护,属于那种自己写代码自己看得懂的那种,那样写出来的代码只能是to ...
关于将多个数组并为一个的实用函数
- 博客分类:
- java
这里,取字符串数组为例,对象比较麻烦,因为本身要判断各个数组的大小,java中对象又用引用表示,所以有点麻烦,做也能做,但就是比较麻烦。
我今天写的代码,是我感觉比较得意的,看下:
/**
* 将多个String类型的数 ...
很长时间没写数据结构了,我发现我写Trie tree的速度都有点慢了,今天在公司写了一个trie,用了很长时间,太恶心了!
不过也有可能是因为trie对不同的应用,有不同的实现模式,不过我感觉大部分都用了做字符串前缀匹配的。。。。总而言之,速度慢了。。。