《程序员的思维修炼—-开发认知潜能的九堂课》,国内书商起个怪名字,其实重点在副标题。 原书标题根本不是这样的。
德雷福斯(Dreyfus)技能模型
新手(Novice)
新手缺乏经验,完成任务时需要操作指引。
即使某人在一个领域上工作了十年,对所有指引已经了然于心,但他只是不断重复执行指令,也依然是新手。
《程序员的思维修炼—-开发认知潜能的九堂课》,国内书商起个怪名字,其实重点在副标题。 原书标题根本不是这样的。
新手缺乏经验,完成任务时需要操作指引。
即使某人在一个领域上工作了十年,对所有指引已经了然于心,但他只是不断重复执行指令,也依然是新手。
最近买了一个EeeBox来做home server,装Ubuntu操作系统,有不少东西可以玩。
其中一个用途是连接到音响播放音乐。我比较喜欢听豆瓣电台,于是找一个豆瓣电台的客户端。Home server平常不接显示器,也不启动图形界面,常见的浏览器客户端、桌面客户端都不能用,要找命令行的。在github上找到Johnny Huang开发的fmd(Douban FM daemon),启动后在后台运行,正合我意。Fork下来给它增加了个安装脚本,能够安装为服务,开机就自动运行了。但fmd只是个后台进程,只有telnet命令接口,没法对它进行直接控制的,作者另外做了个命令行工具,叫做fmc(FMD client),用来控制fmd。但命令行工具在我这里也还是不能用—-没有显示器没有键盘—-必须能遥控才行。于是我在fmc基础上给它增加了一个web UI,称为fmweb,通过手机浏览器访问,就可以控制播放了。于是,我现在在家里任何地方,都可以控制我的豆瓣电台的播放,不喜欢听,跳下一首歌。
这是在Android浏览器上的截图,在iPhone、iPad上也可以用。
为了给老台式电脑升级,在Amazon买了主板、CPU、内存,但装起来加电后不亮。根据现象分析,主板故障的可能性最大,主板是华擎H61M-HVS。拿去华擎网站上列出的本地特约维修中心检查。那里的人说亚马逊网上买的他们不管,跟他沟通了一下,他才勉为其难的测试了一下,查出是主板故障,贴了张故障标签就算了。问他是否能出检测报告之类,我好退货,他说不行,本来检测都不是他们的责任。
想找Amazon客服咨询,才发现根本没有客服热线,只能上网。幸好智能手机能上网,在订单退货的页面里能够呼叫客服。客服回电话倒是非常快,说了情况后她让我保留好维修中心的故障标签,给我办理了退货申请。我现在就等着退货了。
就这次经历总结一下:
Update:
以前马桶放的洁厕宝(蓝泡泡)总是不耐用,声称普通使用可达一个月,但实际上头几天冲的水颜色很深,一个星期后颜色就非常淡了,根本用不到一个月,原因是溶解速度控制不了,太快了。
为了防止过快溶解,给洁厕宝增加一个”外套”。我选的是大开口的口香糖盒子,大小比较合适,能把整块洁厕宝放进去,瓶口合上比较严实。在瓶身开上几个直径3~5mm左右的洞,洞不能太小也不能太大。开始可以先开三四个,如果实验发现洁厕宝溶解不出来再加开几个。怎么开洞就看你手上有什么工具了,我试过几种工具,发现用美工刀最容易,三刀开出一个三角形的洞。做好后把洁厕宝放进去,盖上盖子,扔马桶水箱里就行了。因为盒子里有空气,可能它不会自己沉下去,需要把它按进水里,把空气排出来。水箱里有水垢,不是那么好看,就不把照片贴出来了。
加了”外套”后,效果相当显著,一颗洁厕宝大概能用三个月。去年家人出差多,竟然用了半年!
最近几个周末都跑超过10公里的长距离,但珠江边跑多了已经没有新鲜感。另外最近一段时间空气污染情况又偏高了,虽然头顶阳光灿烂,看远眺整个城市低空都笼罩在一层灰霾之中。于是就把目光投向了白云山:一方面离开市中心,也有高度,空气会好些;另外跑有坡度的路线,可以起到不一样的锻炼效果。
以往去珠江边跑,我都是从住处附近就开始跑,最后跑回家,因此可以穿短衣短裤。但去白云山跑来回都得坐车,穿衣就是个问题。为此专门去迪卡侬买了长袖跑步上衣和紧身7分跑步裤。本来还想买跑步背包的,没得卖,登山背包不适合跑步,只好算了。回来在网上查一下,似乎全国的店都没有卖跑步背包,看了现在玩户外hiking的人多了,但跑步得还是少数。这次背了自行车包,效果还行,没有腰带有点左右晃动,但只是放一件衣服重量不大,对跑步没什么影响。
从外语学院附近的西门进白云山,已经下午4点多,周末到白云山的人真多,路上游客络绎不绝。新买的衣裤很显眼,引来不少注目,所以很多人都建议买点貌似专业的装备,可以有助于坚持锻炼。
路线记录在RunKeeper,有地图和海拔、速度曲线。
西门上山的路是最平缓的,至明珠楼前的2km没有多少上升,正好作为热身。过了明珠楼,就是正式上山路了,2公里上升了150米,上坡时的步速在每公里6分钟多到7分钟多左右,步频大概坚持在160~170,但步幅缩得很小了。绕摩星岭有东西两条路,我先是选择了东面的路,在接近6km处经过了这段路的最高点275米,接下来的路就比较平缓了,上下坡交替,坡度没有前面大,下坡路我跑得很欢。这段路视野开阔,先是看到京溪、梅花园一带的楼房,然后拐过弯,就看到了天河的中信等高楼。看着笼罩在一片灰蒙蒙之中的高楼已经在脚下,感觉很爽。跑了45分钟,7.6km,到达山顶公园。我原计划就是跑到这里为止的,本来以为起码要一个多小时才能到,一停下来,觉得好像不累,还没跑够(其实前面上坡的时候挺吃力的)。从这里如果往南走,就一直是下山路,到云台花园出山,坡度要更大,我不敢跑这样的下坡路,于是回头,还是回外语学院那边好了。接下来的岔路,选择了摩星岭西侧的路,这样走的就是环线,不用全走回头路。没想到后面这一公里多的路真是要命,一路都是上坡,一点平缓都没有。后面有一段我都坚持不了走直线,只能之字形迂回。幸好这段路不长,锦绣南天(雷达站)处到达最高点340米,这一公里上升了90米,上坡步速每公里8~9分钟,比走路快不了多少。接下来就是一路下坡了,跑了一公里多,一直都要控制速度,想着到山底路还长,怕膝盖受不了,不敢继续跑了,就此结束。全程10.64km,耗时1:06:55,平均6.17min/km。
在10km跑总结里提到:这次10km跑成绩的提高最重要因素是步频的提高。
在网上看了一些资料,提到提高步频的好处,并指出长跑理想的步频应该在每分钟180步左右,就开始尝试练习提高步频。但是跑起来并不知道怎样的频率才是合适的,还需要有工具测量才行。想到可以用手机的加速度传感器来测量,跑步时把手机绑在手臂上或者拿手上,测量手的摆动周期应该就可以计算出步频。
有了想法后,就考虑怎样实现。先要知道跑步时加速度传感器得到的数据会是怎样的,在market上找到软件Accelero-meter Log,能显出加速度传感器三轴数据的曲线。拿着手机跑了几步看看曲线,发现完全不是想象中那么简单:从曲线可以看出每跑一步的加速度变化,但并不是一步一个脉冲那么理想,而是大脉冲中包含着小脉冲,波形很不规则;更要命的是不同轴测量到的数据频率会不一样,软件应该按那个轴的数据计算?后来才想到不同轴测量数据频率不同的原因是手摆动的频率与身体重心上下移动的频率不一致,只是一半,再加上手的活动太自如了,跑动过程中会有不同的动作,都会引起加速度变化。
上网找到一个开源的Android计步器的代码,看看它怎么做,发现它只是将三个轴的数值加在一起,然后判断变化量。根据前面看得的数据波形,我感觉这样的算法太不靠谱了,再看看这个软件的用户评价,果然不佳。
这时想到Nike的配合iPhone使用的计步器,是藏在鞋里面的。它应该是感应脚的每次着地,而且计步器是固定在鞋里的,有特定的安装方向,因此它可以只检测垂直地面的加速度。想到这里就豁然开朗了,原来测量摆臂的想法是错误的,应该测量脚着地的冲击,也就是垂直方向的加速度。但那个轴才是垂直地面的呢?我不能规定用户使用这个软件时手机摆放的方向啊,他可以绑在臂上,拿在手里,放裤袋中。。。因此首先要解决的问题是如何判断手机的姿态,找出垂直于地面的轴。
java.lang.NoClassDefFoundError 是个很讨厌的错误,你会发现明明它报告的class已经打包进应用里,没可能在classpath中找不到,然后百思不得其解。其实这个exception跟 ClassNotFoundException 不同,后者报告的类是真的找不到,而这个NoClassDefFoundError 的错误原因是:class loader无法加载这个类,因为它依赖的另外某些类无法找到。到底是什么类找不到?它不告诉你。
例如,看这个exception stack trace:
Caused By: java.lang.NoClassDefFoundError: net/sf/cglib/proxy/Enhancer
at org.springframework.aop.framework.Cglib2AopProxy.createEnhancer(Cglib2AopProxy.java:228)
at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:170)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:476)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.wrapIfNecessary(AbstractAutoProxyCreator.java:362)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.postProcessAfterInitialization(AbstractAutoProxyCreator.java:322)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:407)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1426)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
cglib.jar是在classpath里的,真正错误原因是CGLIB所依赖的asm.jar不存在。
有什么好方法查出NoClassDefFoundError的root cause吗?我不知道。不用Maven管理依赖的后果啊。
11月12日,完成了Nike Lunar Run 10公里跑,这是我第二次参加计时的跑步活动。其实准确的说,只是9.5km跑,因为赛道长度不足10km,多人的GPS测量结果和在Google Maps上面量度距离都证明了这点,但是官方公布的成绩又比实际冲线时计时显示的时间多了大约两分钟,大概是换算出10km的时间。
上一次参加10公里跑是2009年,成绩为58:30,当时定下了目标要提高到55:00(准备10km跑),也就是每公里5分30秒的步速。这次出来的成绩却是意想不到的好,官方公布的成绩是48:29,可能还需要减去过起跑线之前的10来秒,我自己的GPS只记录到8公里处就停止了(RunKeeper),总之步速大约是每公里4分50秒的样子。我之前从来没有想过步速可以迈进5分钟每公里大关的,对这个速度已经非常满意,下次再跑也没有速度目标了,保持这个水平并且不要受伤就好,希望能够尝试一下更长的距离。
虽然名字叫做Lunar Run,比赛是在早上9点进行的。前半程自己感觉状态并不好,步频提不到每分钟170~180步的目标,还不如平常晚上训练的感觉好。也许是早上活动不开,应该热身多一些才行。但跟两年前比较,整个过程跑下来轻松很多,09年那次到最后2公里有点拖着腿熬下来的感觉,最后看着终点在前面都完全没有办法加速了。因为怕最后会跑不动,这次一路上都有点留力,跑到最后一两公里时感觉有余力,还想最后500米可以加速冲一下的,结果一个不留神发现终点已经到了。
成绩提高首先是因为平常的训练增加了,最近一个多月基本保持每周跑两到三次。最重要的因素应该是提高步频的训练,以前习惯低步频大步幅,特别是跑到累的时候脚步沉了更是想靠增大步幅来弥补,最近知道这样不对后才有意识的提高步频,特别是前两个星期做了个Android应用来测量步频,按照180的目标来训练,速度明显提升,膝盖也基本不会怎么痛。我现在还是没办法达到180的步频,一般只能在160~170左右,但已经比以前好不少了。现在跑步的时候基本上就是默念着一件事情:保持步频。只要步频不降下去,速度就不会太慢,也能够压抑着增大步幅的欲望。另外还有些技巧性的因素:上次排在比较后的位置起跑,跑道上人太拥挤了,只能用比走路快不了太多的速度挪动,这次有经验就尽量往起跑区的前面靠,本来在第二区的,后来跟着人穿进了第一区,排在第一区的较前位置起跑,起跑跑出一两百米后就不会受人阻挡了。
To maintain the Spring application context in a large application is not an easy job. There may be dozens of beans, whenever you want to make changes, you have to be very clear on there dependency. After serveral rounds of update, some beans might be orphan, they’re unused any more but you don’t know.
Spring IDE provides bean cross reference view and bean graph view that can help to analysis the bean relationship. But what Spring IDE has is a static view of the beans. In our project the application context is complicated: it scans classpath for all bean definition XML files and load them; application context created in WAR package inherits parent application context which is defines in EJB classpath; some beans are marked with annotation and loaded by context:component-scan, rather than define in XML file. I doubt Spring IDE can show the dynamic bean view as it is in runtime. What’s more, Spring IDE isn’t available at our standard development environment.
Inspired by a StackOverflow answer, I created an ApplicationContextDumper. Add it into application context, it will dump all beans and their dependencies in the current context and parent contexts (if any) into log file when the application context initialization finishes. It also lists the beans which aren’t referenced.
Here is an example. We have two application contexts. Please be noticed that the ApplicationContextDumper has been added into applicationContext.xml.
parentBeanFactory is the parent of myBeanFactory: