• 回乡杂记

    回了一趟家。
    家乡依然如故。只是回家的路越坏了,到处是坑,一路颠簸。一眼望去,还是荒山野岭,零星几点野草。听见我们来了,父亲和阿姨到门上接我们。父亲的气色明显比以前好了。父亲本来就不善于交际,每天除了侍弄他那几亩庄稼,也没别的嗜好,不抽烟不喝酒不打麻将。打自母亲去世之后,屋里连个说话的人都没了,几年下来,父亲越发沉默寡言了。以前每次回家,家里到处都盖着厚厚一层灰尘,仿佛多年无人居住。阿姨说她整整收拾了三天,屋里才收拾的像个样子。阿姨心劲很强,屋里破旧的东西都给拆换掉了,还计划着要把屋里的地面弄成瓷砖的,把厨房给重盖一下。以前在电话里劝父亲别尽忙地里的活了,闲了就收拾收拾屋子,自己好好弄点吃的,父亲虽然口头上应着,但我能想象的到,父亲每天从地里忙回来,一见空荡荡的屋子,连个说话的人都没,弄饭吃的心劲都没了,更别说收拾下屋子改善生活啥的了。几年来,孤独与寂寞不断侵蚀着父亲,父亲迅速老去。现在总算好了,父亲能有个伴了,我们在外面也能安心工作了。

    第二天去母亲的坟上。母亲的坟在村南的山脚下。路被邻村的人开垦弄
    没了,车过不去,我和弟弟就走了去。一个多小时的山路,其实实际距离不很远,但山头的样子都差不多,比较难找。没有墓碑,更没什么标志性的东西,连那一掊
    黄土,也掩映在大山的土色里,不到近处分辨不出来。

    故乡扫墓的习俗是烧纸钱,没有印好的纸钱,我们就带了几张黄纸在坟前点了。虽然烧纸钱这样的习俗对我这样顽固的无神论者来说有些荒诞,但纪念逝者总要有个仪式。逝者已逝,纪念活动也仅仅是慰藉一下生者的心灵,又何必执着于用哪种仪式。我和弟弟在母亲坟前坐了一会。几年了,我现在才算真真把这掊黄土和母亲联系起来。记得安葬母亲的时候,我看见这掊黄土堆了起来,但我老觉得母亲不会在这掊黄土下,母亲应该在家里的炕头坐着等我回去。每次回家远远看到院门,总觉得母亲会从门里出来接我们。我曾经说过人只有经历了亲人的逝去之后才能成熟起来,但其实那时候我还没成熟起来,因为我还老躲在自己的幻想里,逃避压力与责任。但我想我现在成熟起来了,也能承担起自己的责任了。

    和家里人聊天的时候,得知我一个表叔,还有他两个儿子,一家三口去广州打工,全被骗到传销里出不来,传销那边向家里要钱。这个传销还是用暴力限制人身自由的那种,也不卖啥东西,就是明目张胆的绑架勒索。这样的事情已经听了许多了。好多同学还有亲戚出去打工都有过黑煤窑黑金矿黑砖厂,传销,等被骗或者强制劳动的经历。以前以为就我们那山村落后,出去的人太老实所以常被骗。结果出来才知道,这种事情太普遍了。管中窥豹,按照这个比例,中国现在应该有一个及其庞大的人口奴役市场。并且这种事情除了去年网上报道出来的那几个黑砖窑事件,别的都处于没人管的状态。两边的公安局互相扯皮,哪边都不管。更有甚着,公安局直接和这样的团伙勾结赚钱,把钱直接交给公安局,公安局批个条子,就能去传销团伙里把人领出来。前些年孙志刚案发生之前,政府收容遣送制度下,官匪结合,奴役外出打工人员的案例更是比比皆是。我们这代农村青年,已经不像父辈那样能安于那几亩庄稼,但寻找新的出路确实不容易。要么读书,跳出农门,但就业,成家的压力依然不小。还有就是外出进城打工。干最累的活,挣最少的钱,还常常被拖欠,在城市里看不到希望,更无法立足,唯一的希望就是攒点钱回老家去,还不小心就被骗被奴役。但在外面漂了几年的人,心已经野了,回到偏僻的山村,很难在安心下来。再就是干些法律边缘的事情,用高风险追求高收益。这样的人已经不安于踏踏实实赚钱过日子,尽谋划着怎么暴富。虽然这样的希望也是微乎其微,但还是有人前赴后继。主要是勤劳致富的案例不多,反倒为非作歹发家的案例却不少。榜样的力量在这里体现。我们这代从农村出来的青年,已经不适应农村的生存土壤,但又很难融入城市生活,城市用令人望而却步的房价和户口制度设置了一条很难跨越的墙。我们在两边徘徊,找不到归宿。

    又了解了一下农村税费改革和医疗合作的情况。 税费改革还算比较彻底,现在每年每亩地还能收到几十元的补贴。医疗合作只有一个红本,父亲已经交了三年,原来每年10元,今年涨到20元。但具体怎么个报销法,哪些医疗费用能报销,也没个明确的说明。网上查了一下,说是各地的政策不同,有的只报销大病,有的只报销小病。标准,上线都不一样。还听说了有新政策给农村的老人发养老生活补贴。但说是要80岁以上的老人才行,还必须是贫困家庭。标准也就每年400-500块钱。就这样,村里人还要托关系走门路争取名额。农村的养老确实是一大问题了,已经听说好几起儿子媳妇抛弃或者虐待公婆事情。传统的父权制的崩溃,导致老人在家庭没有了经济地位,同时传统家族体制的消失,导致老人的权益无人主张。单凭一个“孝”已经很难承担起农村养老的重担了。因为传统的孝道的背后是父权制和家族制在支撑。计划生育已经搞了20多年了,而相应的农村养老制度却迟迟没有出台。回来的路上还看见墙上的宣传标语:独生子女户夫妻65岁后每年奖励650元。我的同龄同学朋友在农村的也大都步入婚姻生儿育女了,但等我们65岁的时候,谁知道那时候的650元能买个火柴还是萝卜?计划生育要靠养老制度来保障,而不是这种廉价的奖励。

     

    庭院里当年种的一棵小梨树现在也枝叶繁茂,开花结果了。

    记得当年种下它的时候,它和我的个头一般高,当时我还对它发愁,这么小棵树,啥时候能结梨子让我吃上呢,何况这地方干旱少雨,不知道能活下来不。父亲说现在每到秋天,满满一树的梨子都把它的枝桠压弯,要垂到地上了。父亲现在还每天要担一担水来给它浇了。这棵树让庭院里立刻充满绿意,让人暂时忘却屋外的荒山与沙漠。

    生命有自己的运行规律,有些事情是抗拒不了的。以前对结婚成家这样的事情总觉得很遥远,但这趟回家后发现这个问题已经是家里阿姨阿婆们关心的主要问题了。在她们眼里,估计我就像这个当年的小梨树,现在也该到结果的时候了吧。以前对这些事情都比较排斥,现在算想明白了,很多事情顺其自然便好,勉强为之或者勉强不为都不好。  

    我的大脑对时间总有点麻木,所以经常恍惚间不知道是何年何月。在屋里坐在坐着,突然觉得自己还是个初中生,夏天躺在屋檐下朗诵庄子,看着天上的云彩,想象着山外那个世界。然后思绪忽然又飘了回来,掐指一算,竟然那已经是十年前的事情了,母亲去世都已经六年了。心里便一阵莫名的惶恐,仿佛我现在还处在记忆中,再恍惚一下,我就一下变成了一个老人坐在院子里回忆往事呢。人一长大对时间的流逝就无法保持童年的那种坦然态度了,想做的事太多,但做了的事情又太少,总是匆匆忙忙的,还总是觉得时间不够用。家里呆了两天就又匆匆回北京了。本来好像有好多话和家里人聊聊,但见了父亲又聊不了几句,都是不善言谈的人。回北京的时候坐在飞机上,突然又想起很多事没有聊,本来出门的时候要给父亲和阿姨好好说几句告别的话,但车来的匆忙,竟然也没顾上。

    人或许就是这样,或者说人生或许就是这样,处处留着遗憾,即便你知道了也没法预防,总是顾此失彼,捉襟见肘。

     

     

     

     

     

     

     

     

     

     

     

  • Linux通过socks连接ssh服务器

    公司的服务器设置了防火墙,要通过socks才能连接到ssh服务器。
    windows下的很多ssh客户端,比方putty,等都内置了socks功能,设置一下就可以了。但我用的是linux,要找个linux下的解决方案。

    搜索了一下,找到一个 dante 。

    官方网站:

    opensuse的源上就有,安装很简单,下面是我的配置过程。

    编辑/etc/socks.conf文件,在最后添加:

     

    route {
           from: 0.0.0.0/0   to: 0.0.0.0/0   via: yoursocksserver port = socksserverport
           protocol: tcp udp
           proxyprotocol: socks_v4 socks_v5
           method: username
    }
    

    把yoursocksserver替换成你的socks服务器ip,socksserverport替换成你的socks服务器端口。method指socks的认证方式。如果不需要认证就改成none。

    如果是通过用户名验证的,则需要设置一个环境变量:

     

    export SOCKS_USERNAME=yoursocksusername
    

     

     这个变量就是你的socks服务器的用户名。dante会通过这个环境变量来获取socks用户名。如果没有设置就用当前用户。

    然后用socksify脚本来执行需要使用socks的程序,在这里是ssh。

     

    socksify ssh root@yoursshserverip
    

     

    执行后可以看到,先要求你输入socks服务器的密码,输入正确之后,再提示你输入ssh服务器的密码。如果没有成功,你可以修改socks.conf文件,激活下面这两个选项:

     

    #debug: 1           # uncomment to enable debugging
    
    #logoutput: stdout  # users usually don't want to be bothered with that.
    

     

    看报什么错误。

    查看一下socksify脚本,可以看到它做的事情很简单,就是在执行ssh前先加载libdsocks.so库。

    至此,目的虽然达到了,但还有个问题就是每次登录服务器都需要输入两次密码,太麻烦,能不能让它自动化?

    我又找到一个很有用的工具expect(如果不存在这个命令请先从源上安装)。这个工具是专门来让这样的交互式程序自动化的。
    写一个脚本:

    #!/usr/bin/expect
    set sockspasswd "yoursockspassword"
    set sshpasswd "yoursshpassword"
    spawn socksify ssh root@yoursshserverip "[lindex $argv 0]";
    expect "*password:";
    send "$sockspasswdr";
    expect "*password:";
    send "$sshpasswdr";
    interact;
    

     

    保存后执行它,是不是自动登录到你的ssh服务器上了?

    其实还不需要手动写这个脚本,expect有个工具,叫autoexpect,可以帮你自动生成这个脚本。
    直接运行 

    autoexpect -f autologinserver socksify ssh root@yoursshserverip

    按步骤完成输入,登录后退出。autoexpect就会录制下你的输入,给你生成一个名叫autologinserver(-f 参数指定)的文件。

    运行它,是不是自动登录了?当然这个文件还需要修改下,因为它会把你登录后的ssh输出的内容也给记录下。

    最后,这个问题算圆满解决了。

    expect的功能很强大,这里只是它最简单的一个应用而已,详细的请参看man手册或者官方网站。
    dante也可以做socks服务端,这里就不介绍了,具体参看官方网站。

    享受生活,享受linux。

     

  • JDK 6 Update 14内置VisualVM 1.1.1

    VisualVM 是一个集成了一些JDK的命令行工具的可视化的工具,为您提供强大的分析能力。它捆绑了包括jstat , JConsole , jstack , jmap和jinfo,这些工具都您都可以在标准的JDK里找到。

    VisualVM可以让您生成和分析堆数据,跟踪内存泄漏,监测垃圾收集器和内存CPU的性能,以及能够浏览和操作MBeans 。虽然VisualVM运行在JDK6上,但它可以监控创建自JDK1.4以上版本的应用程序 。

    如果您的jkd没有更新到最新版本,您可以到以下地址下载:

    下面这篇文章用Visualvm比较测试了三个java IDE( NetBeans 6.5.1 (JavaSE only version), Eclipse (for Java Developers) and IntelliJ IDEA (8.1.2) )的性能:

    本文的VisualVM介绍也是翻译自该文。

    VisualVM同时提供IDE插件,可以在IDE中直接使用VisualVM。

    Sun还搞了个博客大赛,鼓励大家写博客介绍VisualVM,前三名都有奖励,最高奖励价值500美元,不过要求博客必须是英文写的。

    如何启用tomcat的JMX,对远程tomcat进行监控,最简单的方式就是在tomcat的启动脚本里加上:

     

    CATALINA_OPTS="-Dcom.sun.management.jmxremote
        -Dcom.sun.management.jmxremote.port=$my.jmx.port
        -Dcom.sun.management.jmxremote.ssl=false
        -Dcom.sun.management.jmxremote.authenticate=false
        -Djava.rmi.server.hostname=$my.jmx.host"
    

     $my.jmx.port $my.jmx.host这两个变量请根据具体情况替换。

     

    如果要设置权限,以及更详细的配置,请参看下面这几篇文章:

    下图是本站的VisualVM监控截图:

  • Javascript(Ajax)开发测试工具

    IDEs

    NetBeans, IntelliJ, 以及 Eclipse 等ide都内置或者插件支持javascript的编辑开发。eclipse的插件很丰富,我个人认为 aptana 的html/css/javascript开发插件做的比较专业。

    Firebug

    这个鼎鼎大名的firefox插件不用多说。它的出现是划时代的。用作者的一句话说就是”开发web应用没有firebu就像用vi编写java代码–虽然可以完成,但不值得忍受这样的痛苦”。

    Firebug Lite

    Firebug Lite 是为非firefox的浏览器准备的。只需要在页面里包含一个js,就可以在其他浏览器中享受firebug带来的便利。或者把它作为一个bookmarklet收藏到收藏夹里,在需要调试的页面运行就可以。

    YSlow

    YSlow是一个firebug的插件,由Yahoo!的开发团队开发。用来给网页提供优化建议。

    Hammerhead

    Hammerhead 是个检测网页加载速度以及提供便利的清空cache操作的firefox插件。

    测试JavaScript 代码

    JsUnit

    JsUnit是一个javascript测试框架,类似于java中的JUnit。它提供一个**JsUnit Server, **这样你可以把JsUnit tests 并入你的 continuous-integration (CI) server,在服务器端用JUnit或者Ant脚本测试Javascript。它提供跨浏览器跨系统的javascript测试。

    JSSpec

    JSSpec将 BDD(behavior driven development)带入了Javascript。可用来进行Javascript的无人职守测试,不过它只能在浏览器中运行。

    YUI Test

    YUI Test 是一个javascript测试世界里的新成员。和JsUnit和JSSpec不同的是,YUI Test允许你模拟基本的用户行为 例如鼠标点击和键盘事件,它允许暂停测试,等待对服务器的异步请求返回结果。

    Crosscheck

    Crosscheck,顾名思义,它是检查javascript跨平台功能的一个程序。它运行在JVM之上,不需要启动浏览器就可以进行测试。因为它内部模拟了各种的 浏览器/操作系统 组合。

    测试UI

    Selenium

    Selenium 是ThoughtWorks开发的一款web测试工具,是一个firefox插件。它可以记录鼠标点击,键盘键入等用户操作用于测试。你还可以在浏览器中进行回放。

    Watir

    Watir是ThoughtWorks开发的另一款web测试工具,是专门为quality-assurance (QA)人员开发的工具。

    其他小工具

    JSLint

    JSLint可以检查你的javascript代码,然后找出其中的错误或者不良操作并给出修改建议。

    压缩工具

    Javascript的压缩工具很多,例如:JSMinYUI Compressor

    文档工具

    Javascript虽然没有类似于Java Doc的标准,但也有类似的替代品。如Prototype 的 PDoc, YUI 的 YUI Doc

    结论

    JavaScript开发地位越来越重要,不应该让JavaScript的开发降级到用alert和文字编辑器的程度。今天,我们有IDE的自动完成,全方位的调试工具,以及各种测试工具。 今天,JavaScript在任何Web应用中都是一流公民,JavaScript开发者应该有世界一流的开发工具用来制作世界一流的互动应用。

    关于本文

    本文是Ajax: Tools of the trade的摘要翻译。原文请参看:

  • 参加了一下Android技术大会

    大会的名头不小,首届 亚太地区Android技术大会。刚开始我以为是google搞的,结果不是。

    随便询问了一下,像我这样自己花钱来参加的寥寥无几。门票400元,幸亏我买的是社区票,280,稍便宜点。

    会场给人的感觉就不好,投影仪太小,出现图表干脆就看不清楚,我去的还比较早,在前面坐着。发了本讲义,但讲义上一页印好几页幻灯片,图表还是看不
    清楚。后来上来了一个哥们,看着就像做技术的,估计也没怎么讲过课,对着幻灯片上的流程图就开始乌拉乌拉讲,也不管下面的人听明白不。

    请了一个日本教授,就上去念了一下幻灯片上的英语。还有个韩国的讲师,据说是开发Android的牛人,但英语发音是在太烂,不知所云。

    下午一个讲师讲android的多媒体架构,确实不错。

    然后一个日本的开发人员给演示了一下几个Android相关的应用。一个叫 Dalvik
    VM,好像是在j2me上又加了一层,可以让Android上的应用运行在支持j2me的手机上。一个叫
    ikoto,Android上的模拟中国古琴的软件,从屏幕上划过的时候就发出琴弦被拨动的声音,挺好玩。还有一个叫Droidget,运行在
    Android上的桌面小控件程序,可以用javascript写控件。

  • javascript库的延迟加载

    如果只是简单的让js延迟加载,那只需要在页面尾部加上这样的代码:

     

    var oHead = document.getElementsByTagName('HEAD').item(0);
    	  var oScript= document.createElement("script");
    	  oScript.id = id;
    	  oScript.type = "text/javascript";
    	  oScript.src=src;
    	  oHead.appendChild(oScript); 
    

     

     但这样加载有个问题,如果我立刻在后面调用这个延迟加载的js里面的方法或者变量就会报错,因为新加载的js还没执行完呢。并且document的onload方法不会等待这样的延迟js加载成功。

    还有就是这样加载的js不能保证顺序。也就是不能保证先append的js先执行。如果后面的js依赖于前面的js,而前面的js比较大,加载延迟,则后面的js执行的时候就可能报错。

    我在修改这个高亮代码的脚本的时候就遇到了这样的问题。

    并不是所有的文章都有代码,并且每篇文章可能出现的代码语言不一样,需要根据内容加载不同的库。

    shCore.js是核心js,需要先加载。然后是各个语言的js,具体取决于文章内容中出现的代码语言。如  shBrushJava.js,shBrushBash.js等。

    后面这些js都依赖于shCore.js。当所有的js都加载完的时候,才能调用:

    SyntaxHighlighter.highlight();

    高亮代码。

    参考了一些文章,终于弄出一个解决方案:

     

    if(!window.BrushUtils) var BrushUtils = (function(){
    	var ut = {
    		baseurl:"",
    		resources:[],
    		brushMap : {js:"JScript",jscript:"JScript",javascript:"JScript",
    					  bash:"Bash",shell:"Bash",css:"Css",actionscript3:"AS3",as3:"AS3",cpp:"Cpp",c:"Cpp",
    					  csharp:"CSharp",groovy:"Groovy",java:"Java",javafx:"JavaFX",jfx:"JavaFX",
    					  perl:"Perl",pl:"Perl",php:"Php",text:"Plain",plain:"Plain",py:"Python",python:"Python",
    					  ruby:"Ruby",ror:"Ruby",rails:"Ruby",scala:"Scala",sql:"Sql",xml:"Xml",html:"Xml",xhtml:"Xml",xslt:"Xml"
    		},
    		parseBrush :function(){
    			  var pres = document.getElementsByTagName("pre");
    			  var brushs = new Array();
    			  for(var i=0;i0?function(){ut.loadNext();}:function(){SyntaxHighlighter.config.clipboardSwf = ut.baseurl 'scripts/clipboard.swf';SyntaxHighlighter.highlight();};
    				if(resource.type=='js'){
    					ut.loadJs(resource.url,callback);
    				}else if(resource.type='css'){
    					ut.loadStyle(resource.url,callback);
    				}
    			}
    		},
    		loadJs : function(src,callback){
    				  var scriptTags = document.getElementsByTagName('script');
    				  var oHead = document.getElementsByTagName('HEAD').item(0);
    				  var script= document.createElement("script");
    				  script.type = "text/javascript";
    				  script.src=src;
    				  script.onreadystatechange= function () {
    							if (this.readyState == 'loaded' || this.readyState == 'complete') {
    								callback();
    							}
    						}
    				  script.onload= callback;
    				  oHead.appendChild(script);
    			   },
    		 loadStyle : function(url){
    				   var oHead = document.getElementsByTagName('HEAD').item(0);
    					var style= document.createElement("link");
    					style.type = "text/css";
    					style.rel="stylesheet";
    					style.href=url;
    				   oHead.appendChild(style);
    		  }
    		};
    	return ut;
    	})();
    

     

     

    调用:

     

    var syntaxhighlighter_url = "/scripts/syntaxhighlighter/";
       BrushUtils.loadLibs(syntaxhighlighter_url);
    

     

     

    主要在于对script的加载成功事件的监听。ie的事件是onreadystatechange,firefox的是onload.把需要加载的js放在一个队列里,当前一个加载完成时候,从队列里取出下一个js,继续加载。

    经过测试,这个方法在ie,firefox,opera上都可以使用。但据说Safari上是没这个事件的(未测试)。

    本来想给样式表也加上事件监听,结果发现样式表加载成功在firefox下是不触发事件的,ie下可以。

    参考网址:

    http://unixpapa.com/js/dyna.html

subscribe via RSS