写这个系列的目的:

  • 了解一下自己拿着手机再看啥,看看能否整理所看的;
  • 看看自己能能够坚持写多少期

标题:最伟大的计算机程序员是如何诞生的?——解读高德纳(Donald E.Knuth)

阅读笔记

本文是高德纳的小传,看完之后,他是一个极为聪明和勤奋细心的人。成长路上离不开家庭和所接触的朋友。死磕细节可以看他在写算法圣书得到诠释。还有具体下面的例子:

与朋友相交

他与戴克斯彻相处的思考:

他的长处在于永不妥协的审美品味,我呢,总是意志不坚,摇摆不定。如果他对我说他喜欢我做的某件事,那么他就是真的喜欢;如果他说不喜欢,那么就是真的不喜欢。所以我视他为难得的诤友。

死磕细节

1.写书的例子

《计算机程序设计艺术》书中对提及的每一个理论,书中都会巨细无遗地讨论所有细节。在解释某个算法后,还会再给出一个程序实例——目的是确保读者不会产生误解。这是其对待课题一丝不苟的态度结果,也是他不厌其烦求证结果。(ps:本人木有看过此书,只粗略的翻了一下,确实如此。)

2.编程竞赛的例子

艾伦.凯在斯坦福大学从事AI项目时(20世纪60年代末),每个感恩节我们都会与在湾区 做研究项目的人们进行一次编程竞赛。奖品是一只火鸡。 麦卡锡为竞赛出题。高德纳参加的那一年,他一举拿下了两个奖项:程序调试所用的 时间最少、算法执行效率最高。而且他用的是所有参赛者中最烂的系统,叫做Wilbur系统,只能远程批处理。可以说他把所有人都打得屁滚尿流。然后他们问他:“你怎么这么牛?”他回答说:“我学编程的时候,一天能摸5分钟计算机就不错了。想让程序跑起来,就必须写得没有错误。所以编程就像在石头上雕刻一样,必须小心翼翼。我就是这样学编程的。”


HashMap的死循环总结

JDK7中的HashMap在多线程环境下可能造成CPU 100%的现象,这个由于在扩容的时候transfer时产生了死链,由此会在get时造成了CPU 100%。

误用的例子与分析

使用hashmap作缓存

代码中使用HashMap的方式类似如下1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class xxxxx{
private static Map<String,List<String>> caches = new HashMap<String,List<String>>();
public void load(){
caches = new HashMap<String,List<String>>();
// 往此caches放东西
for...{
caches.put(...
}
}

public List<String> get(String key){
return caches.get(key);
}
}

是因为出现这种场景:可能会出现正在往caches里put东西的时候,其他的线程在get,直接就导致并发问题,HashMap.get的并发问题有可能会导致get方法中的下面这段代码进入死循环:

1
2
3
4
5
6
7
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
return e.value;
}

还有一个例子也是作缓存,代码类似如下:

1
2
3
4
5
6
private static Map...  cache = new HashMap...
Object object = cache.get(key);
if(object == null){
object = **一个比较耗资源的获取Object动作...**
cache.put(key,object);
}

为什么会出现死循环

是什么情况下才会让for循环变成死循环呢?如下解释:2

出现死循环是因为map中的桶链表出现了循环链表,循环链表是因为并发put操作造成的,同时进行了resize方法而触发调用transfer方法在rehash的时候,恰巧又在同一个桶中,此时修改链表的指向,导致出现环。如果只有一个线程进行put操作,是不会出现循环链表,所以读写并发不会出现死循环,只有写写并发才有可能出现死循环。

在资料3,4,有大量的图描述如何产生环而构成死循环。比如:

hashmap_endless_loop

解决方案

hashmap出现死循环,并非其bug,别人已经明确告诉你:不支持并发。那我们对于想利用hashmap特性,咋整。用ConcurrentHashMap来替换hashmap,比如例一,但在例二中还要考虑使用Future,一是等待资源,二是get/put不是原子操作。


标题:婴儿教育,最重要的是什么

阅读笔记:

什么是婴儿期最重要的事情呢?
答:让宝宝听你的话,做他的男神女神,并且理解他懂他。
第一条:少或者不朝宝宝发火、大喊大叫、粗暴错怪他,构建你的影响力。
第二条:理解孩子、懂孩子。这就不仅仅需要我们温柔高雅,还需要我们具备一些有关孩子成长的知识,至少让我们比算命的离他的心更近。

更为重要的是多回应宝宝,那么什么是回应呢。

回应就是观察、跟随孩子的状态,做他想做的。跟随孩子的眼睛,学会领会孩子的精神状态。听他想说的,在他想要安静的时候给他空间,在他想要爱的时候给他拥抱。


  1. 1.又一起并发场景下错误使用HashMap的Case
  2. 2.并发场景下HashMap.get导致cpu耗光的原因分析
  3. 3.老生常谈,HashMap的死循环
  4. 4.疫苗:JAVA HASHMAP的死循环