Thinking beyond source code

Recording my throughs


  • 首页

  • 关于

  • 归档

  • 标签

谈谈closure

发表于 2012-03-05 | 分类于 未分类

 

closure是functional programming中的很重要的一个概念,Scheme首创这个概念, 大致可以理解为一个东西可以以自己为开始并且结束, 最常见的形式莫过于回调函数了。这句话很难理解。

 

举个生活中的例子:

 

刚来上海的时候, 经常到一家小饭馆吃饭, 发现这个饭馆点菜很有方法。 这是一个小饭馆, 每个人点菜都不是很多, 点菜再前台, 点完以后拿到小票给服务员, 服务员走到桌子前, 打气桌子上写着桌号的小夹子加载小票上, 一起交给厨师。

 

然后上菜的时候另外一个服务员就可以通过夹子找到客人, 然后在把夹子放在桌子上。

 

全过程中, 这个菜单和夹子就是一个object, 它自我闭包, 不需要任何起其他记录(全局变量), 就可以完成完全不知道的两个服务员正确的送菜(多线程)。

 

从这个例子可以看到, 这个点菜过程完全是闭包的, 其中的对象可以说就是这个夹子(夹子上有桌号和菜单)。正因为这种closure, 这个饭馆可以随时更换增加和减少服务员和厨师数量的数量, 每个厨师和服务员都不需要记住任何客人的地方和菜单。只要这个夹子就可以知道所有上菜与做菜的东西。

 

其实在高度并发的环境下,增加程序的闭包性是最优雅,也是最快的解决办法。不需要上下文, 不需要复杂的记录object的数据, 完全由并发的个体自我完成。 

 

 

Kindle Touch几天来的感受

发表于 2012-02-26 | 分类于 未分类

Kindle Touch 已经入手一个星期了,对于一个书呆子来说,这个东西的魅力绝对是无法形容的。

它比纸书轻也方便带,直接放在上衣口袋里面就行了,也不会因为带着一本厚厚的书在地铁上拿出来招来异样的眼神。也不会像看其他的屏幕那样半个小时以后眼睛都睁不开,估计没看几本书眼镜就又多了100度闪光。

e-ink的屏幕看书的感觉和纸质的书几乎完全一样,但是有几个纸质书无法达到的地方:

  • 可以做标记, 我们看书的时候总是喜欢把自己喜欢的段落用笔勾挂下来, 可是这一本书看完勾画下来的那些难道还要再抄一遍么, 所以大部分的勾画都只是留在了书上,等待着下一个看这本书的人。而在Kindle上, 每本书,或者整个Kindle上面做过的标记, 都可以很容易的找出来。
  • 字典, 看英文书的最大困难就是有些单词不知道什么意思, 对于纸质书,你可能要打开你的iphone, 电脑, 文曲星?来查查什么意思, 我不知道这样10次下来你还能不能坚持继续看这本书了, 这种打断对于阅读是不好的, 而Kindle很好的解决了这个问题。 你只需要一直按着你不懂的那个单词, 辞典就会自动跳出来, 这也是我买touch版的原因。 辞典可以是自带的英英牛津辞典,也可以是自己安装的英汉辞典。所以说看英文书前所未有的好感。
  • 推送, 有人不喜欢拿着usb线拷贝文件那样的copy书的方式, 我也不喜欢。 所以kindle有一个功能,解决了这个问题。 在你注册了Amazon帐号以后, 你会得到一个Kindle的邮箱, 有了这个邮箱, 你可以把你想阅读的东西, 无论是什么格式的,发送到这个邮箱。 然后你会发现你的Kindle会自动下载这个文章, Amazon会为你转换格式, 所以也免去了转换格式这个麻烦的过程。 不过你要开wifi或者3g哦。
  • 购物, 如果说你想看原版小说, 而又不想看那些过时的东西, 你可以花一些钱在Amazon上购买Kindle版本的书籍, 其实小说这些书都不贵, 0.99$ 1.99$的比较多, 这个价钱也就是一个红薯的价钱(大一点的红薯)。不过我一般都是下下来Sample(免费的哦)看看, 想买的都比较贵, 不想买的看看Sample就行了。

可惜现在并没有可以买的电子书下载, 那些在LCD上看的不算。 豆瓣读书频道似乎有一些动作,不过还在起步阶段。如果说按美国的这个折扣卖电子书,小说几本都是1折或者2折, 专业书几本是对折, 我还是希望买的, 网上花时间下载所谓的pdf或者是阴影版实在是太奢侈了,浪费时间的说。 

最后推荐一本书:

美国宪政历程-影响美国宪政的25个司法大案 (任东来 白雪峰 陈伟) 

关于电信光纤不能上pptp的解决办法

发表于 2011-12-10 | 分类于 未分类

今天终于上了pptp了 。 twitter用的很爽。

前几天安装了电信的光纤, 网速还行就是不能用pptp, 网上搜到了方法, 破解进入电信的光猫里面,然后改一些配置然后让自己的路由来进行adsl拨号, 这样就绕开了那个猫HG226的bug了。

介绍下大概方法。 

1. 这个hg226有一个超级密码:fiberhomehg2x0 / hg2x0 进去以后改掉telecomadmin的密码, 然后关掉电信远程监控的那些服务。 

2. 然后配成桥接到你的路由器。

(1-2 请看这里)

3. 如果你不知道你的adsl帐号, 打10000号,报上你的姓名住址就可以知道了

4. 然后用你的路由进行拨号。

5. 如果为了方便, 可以把自己的路由器烧成dd-wrt,这http://thinksrc.com/?p=201001里面有提到怎么配置。

配置PPTP VPN服务器的一些注意事项

发表于 2011-12-08 | 分类于 未分类
由于一些“特殊”网站的访问需求, 在海岸另外一端配置了一台PPTP服务器,经过几天的折腾,终于达到了一些比较稳定的访问。

对于pptp服务器的安装,网上很多教程,这里我主要记录一下摔跤的地方。 这个链接也是一个好的checklist: http://www.dd-wrt.com/wiki/index.php/PPTP_Server_Configuration#Force_Encryption

刚弄好以后,发现WIN XP能够连接,其他的比如我的iphone, mac都不能连上去, 而且一些android设备连接也不稳定。于是很郁闷。

在 /etc/pptpd.conf 中

#stimeout 10

必须要注掉(也就是要加上#),这条会导致XP连接不上。

对于localip和remoteip的设置, 会决定你可以连多少台设备上去。

localip 192.168.0.1
remoteip 192.168.0.204-238,192.168.0.245
但是由于pptpd代码里面写死了,最多100个(MAX_CONNECTIONS的默认值), 所以你这里IP再多也只能是100个, 除非你重编代码。

 

在/etc/ppp/options.pptp中

一定要加上:

nopcomp
noaccomp
这两项,不然你的iOS设备就不能连了。

还有要加上

ms-dns

不加iOS设备也不爽。

还有你要打开

require-mppe-128

不然有些设备,Mac连不上。

当你连不上的时候, 通过

sudo tail -n 100  /var/log/daemon.log
来看看有什么错误。

这个网址也可以有一些解决办法:http://pptpclient.sourceforge.net/howto-diagnosis.phtml

 

我遇到了:

Dec  8 18:43:26 FAELAB pptpd[5091]: GRE: Bad checksum from pppd.
这个错误是因为iptable里面把GRE给禁掉导致的,

我就直接

iptables -F

把防火墙给干掉了。

不能废掉iptable,然不然nat就不work了,以下这样配置iptables.

4 防火墙设置:
1) 加入端口转发:
iptables -t nat -A POSTROUTING -p all -o eth0 -s 172.16.0.0/24 -j SNAT --to $ETH0IP

2) 开放端口TCP 1723
iptables -A INPUT -p tcp --dport 1723 -j ACCEPT
iptables -A INPUT -p gre -j ACCEPT

3) 如果是redhat/centos系列系统,防火墙中再加入
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

然后为了访问方便一点, 还找了一台buffalo WHR-G300N的WIFI AP刷了DD-WRT设置了自动拨PPTP, 受这篇文章启发:http://pagebrin.com/2011/06/%E5%AE%B6%E5%BA%AD%E7%BA%A7%E6%97%A0%E5%A2%99%E7%BD%91%E7%BB%9C%E6%96%B9%E6%A1%88/

具体刷机步骤参考,

(更新: 关于 G300NV2 不能VPN的问题, 我发现是DD WRT的版本问题, 我使用了r18000的版本以后发现PPTP拨号不成功, 但是回到标准的v24sp1版本就好了, G300NV2的要下载这个链接的firmware )

http://www.dd-wrt.com/wiki/index.php/Main_Page

http://www.anywlan.com/bbs/thread-45161-1-5.html

我是用tftp的方式(不是tfptd), 里面关于arp的设置非常重要。

刷完以后就用这个方法配VPN:

http://www.xbox-skyer.com/showthread.php?t=311507&page=1

终于能无缝访问了, 自己家里也想弄一个。 回去看看我的设备支持不。

一天的功夫没白费。

Debug Android and Linux suspend and resume (中文)

发表于 2011-10-31 | 分类于 未分类

积攒了一些关于调试Android和Linux下面的suspend 和 resume的经验, 在这里和大家分享一下。

希望可以有些帮助, (下面没有写Android专用的, 就是Linux通用的)。

1. no_console_suspend 

在kernel启动参数里面加上no_console_suspend, 这个是最基本的, 因为kernel在把console suspend掉以后, 不管里面出了什么事情, 从串口上都看不到。 大部分在suspend/resume时候的死机都可以通过串口看到kernel Panic的信息, 这样才会知道是哪里出了问题。因为有的时候resume出错, 或者suspend到很后面出错的console不加这个参数都看不到。

2. initcall_debug

这个也许知道的人不多, 其实有的时候你不知道哪个driver在suspend/resume的时候出错的时候,很迷茫, 就想在哪里加上一些调试信息来看看是哪里的driver, 其实有些时候加的不合适的话, 会看不到很多有用的信息。其实kernel本身已经有这样的功能了(只不过不是很人性化)。

 

echo 1 > /sys/module/kernel/parameters/initcall_debug

echo 9 > /proc/sys/kernel/printk

第一条命令是打开initcall_debug, 这个是所有的kernel都会有的, 也可以在启动参数里面加initcall_debug来默认打开这个参数, 这样可以调试系统启动。

因为这些信息都是KERN_DEBUG级别的, 所以需要提高printk的级别才可以看到, 要不然suspend/resume的时候死掉了,你就没有机会看到这些信息了。

3. suspend_test

这个方法可以用rtc这种软件的方式来做循环的suspend/resume, 尽管对于Android这样并不是很足够, (你得模拟一个POWER_KEY上去才够), 但是对于调试Driver的稳定性, 还是有一定用处的。 不要以为suspend了几次可以, 那么就可以通过几千次的测试。 这个suspend是5秒钟用RTC唤醒, 然后对于Android, 5秒钟又会自动睡下去, 但是对于通用Linux, 你得写个小脚本来让他一会再睡下去, 或许这个工具比较有用rtcwakeup(google rtcwakeup)。

使用方法:

编译一个有这个功能的kernel, make menuconfig 以后选上

CONFIG_PM_DEBBUG=y

CONFIG_PM_TEST_SUSPEND=y

这两个选项

烧写新的kernel,然后打开你需要测试的东东, 比如WIFI,3G

echo "core" > /sys/power/pm_test

echo "mem" > /sys/power/state

这样, 它就会循环休眠和唤醒了。

4. wakelock

轮到Android的调试了, Android里面和Power相关最大的就是wakelock,  有时候会碰到睡不下去,或者睡到最后弹起来的问题, 就是wakelock引起的,或者说是wakelock的使用者引起的。

怎么调试呢,用一下两个:

echo 15 > /sys/module/wakelock/parameters/debug_mask

echo 15 > /sys/module/userwakelock/parameters/debug_mask

15是代表16进制的F, 在wakelock里面就是把所有的debug信息打开, 起码现在是。如果以后不够了,估计得输入255.

这样你能看到kernel和frameworks层对于wakelock的操作, 申请和释放。 这样看申请和释放成对否就可以了。注意: wakelock有一种是timeout的, 就是说多少毫秒以后, 会自动释放, 对于这些wakelock, 申请和释放可能是不成对的。。

5. power.0

有的时候你会看到系统suspend到了最后, 然后遇到power.0 suspend失败,然后整个系统都又resume起来了。 这个是android专有的,因为power.0是android注册到suspend最后的一个回调, 它会在CPU进入suspend之前检查一下有没有wakelock, 如果这时候还有没有释放的wakelock, 那么它会返回-EBUSY然后导致整个suspend失败。 调试这个问题的方法就是把上面wakelock的debug信息打开, 然后看看是哪个家伙去申请了wakelock,然后干掉它。

这个错误的错误信息大概是这样的:

pm_noirq_op(): platform_pm_suspend_noirq+0x0/0x38 returns -11
PM: Device power.0 failed to suspend late: error -11

6. earlysuspend

差点忘掉这个哥们, android里面另外一个pm相关的大东东, 同样可以加:

echo 15 > /sys/module/earlysuspend/parameters/debug_mask

来把相关的debug信息打印出来, 比如那个earlysuspend要被call之类的。

7. suspend/resume time.

有的时候你要调试suspend/resume的时间太慢的问题。 一种方法是用initcall_debug, 然后把printk的时间戳打上, 然后看哪个很慢。

但是这样会让你的生活很枯燥:)

我有一个patch,专门用来调试这个问题的,但是upstream不接受, 说非要用这种折磨人的方法才行, 但是如果你想用可以下下来打上去用一下。

地址在这里:http://www.spinics.net/lists/linux-pm/msg24063.html

用法是, 打上这个PATCH以后, 在KERNEL里面选择上PM_DEBUG, SUSPEND_DEVICE_TIME_DEBUG 这两个选项。

然后

echo 微秒 > /sys/power/device_suspend_time_threshold

比如

echo 50000  > /sys/power/device_suspend_time_threshold  

注意这里是微秒哦。。。 它会把在suspend/resume的时候慢的那些driver打出来,然后你去干掉它。。。

Steve Jobs, You Are Living Forever In My Heart

发表于 2011-10-05 | 分类于 未分类

Steve Jobs 今天去世了。

今天早上得到这个消息的时候,愣了半个小时,不知道该做什么。 

难以想象,昨天看wwdc 2011的录像的时候,觉得他的声音缺少了很多中气,想必当时身体很差了已经。可是谁曾想到今天就去世了,上帝真的是不公平。脑中盘旋的,是他在斯坦福毕业典礼上的演讲:“生命是有限的“那句话;还有在wwdc中和每一个做demo的同事都说好多话,那时因为他知道,这时他最后一次wwdc了。

打开新买的Mac Book Pro,庆幸自己在这一切发生之前,加入了苹果教。打开Apple的主页,看到黑白的Jobs的头像。

好吧,这个实事只能接受了,愿你在天堂活的健康,在那里好好休息休息吧。

也许,天堂的标准就是一个人拥有苹果所有的,和将来的所有产品,在那里你就不用这么忙碌了。

以此纪念伟大的Steve Jobs。

Linux技巧: mount 同一个目录到两个地方

发表于 2011-09-18 | 分类于 未分类

今天新学了一个mount的参数, --bind, 可以把一个目录mount到两个地方。

故事是这样的, 别人给了一台linux的服务器, 可以里面的分区有些问题, /home/ 和 /没有分开。 慢慢的服务器空间就不够了, 买了一块硬盘。

mount 到 /home/下面, 原来的/home/下面的目录分别移的时候漏掉了一些目录(本来直接rsync就可以了,可是已经有人用了新的分区好长时间, 不能直接rsync,只能一个一个的rsync, 这样的重复作业还是漏掉了一个两个)。

服务器起来以后, 有人报告说自己的目录找不到了, 可是我没有把这些目录都sync到新的硬盘上(太费时间), 留在了原来的/home/目录下面。

但是旧的/home/目录已经无法访问了, 又不能重新mount, 因为很多人在用。

幸亏linux和google的强大, 有一条命令可以把一个目录mount到两个地方。

于是我随便找了一个目录, 暂且叫~/dir吧。

mount --bind / ~/dir
rsync -a ~/dir/home/xxxx /home/xxxx

这样就搞定了。

 

Use debugfs tracing in linux kernel.

发表于 2011-08-25 | 分类于 未分类

Just record how to use debugfs, tracing block IO.

 

Vivek Goyal  said on maillist:

"""

You can try using tracing functionality.

- mount -t debugfs none /sys/kernel/debug
- Enable tracing on the disk you are doing IO to.
 echo 1 > /sys/block/sda/trace/enable
- Enable block traces
 echo blk > /sys/kernel/debug/tracing/

current_tracer
- cat /sys/kernel/debug/tracing/trace_pipe > /tmp/trace_output

Let it run for few seconds. Interrupt and kill cat process.
/tmp/trace_output should have useful tracing info.

用go写的一个dd程序

发表于 2011-07-12 | 分类于 未分类

最近学了下go语言, 写了几个程序下来觉得确实很方便。

主要是有几点,

  • code syle定死了,省的以后浪费时间在code sytle上面的争论
  • 大括号必须跟在函数后边,只有if和for,简单啊。
  • 最方便的地方就是错误处理,可以返回一个返回值和一个专门处理错误码。
  • 还有就是打的字很少。
  • 用来处理参数的flag很好用,参数处理简单很多。

在主页http://golang.org 上面有许多文档, 另外还有几个中文的文档看着比较舒服:

http://code.google.com/p/golang-china/

http://code.google.com/p/ac-me/

 

package main

import (
	"os"
	"syscall"
	"flag"
	"fmt"
)

var ofile = flag.String("of", "","out file")
var ifile = flag.String("if", "", "in file")
var seek = flag.Int64("seek", 0, "seek bytes")
var skip = flag.Int64("skip", 0, "skip bytes")

func main() {

	flag.Parse()
	
	of := os.Stdout
	inf := os.Stdin
	err := os.EINVAL

	fmt.Printf("of :%s if:%s n", *ofile, *ifile);
	
	if *ofile != "" {
		of, err = os.Create(*ofile)
		if of == nil {
			fmt.Printf("can open of:%s:%sn",
				ofile, err.String())
			os.Exit(1)
		}
	}
	if *ifile != "" {
		inf, err = os.Open(*ifile)
		if inf == nil {
			fmt.Printf("can't oepn if:%s:%sn",
				ifile, err.String())
			os.Exit(1)
		}
	}

	if *seek != 0 {
		sr,err := of.Seek(*seek, os.SEEK_CUR)
		if sr < 0 {
			fmt.Printf("seek error:%s:%sn",
				of.Name(), err.String())
			os.Exit(1)
		}
	}
	if *skip != 0 {
		sr, err := inf.Seek(*skip, os.SEEK_CUR)
		if sr < 0 {
			fmt.Printf("skip error:%s:%sn",
				inf.Name(), err.String())
			os.Exit(1)
		}
	}

	fmt.Printf("dd :%s to %sn",
		inf.Name(), of.Name())
	
	const NBUF = 4096
	var buffer [NBUF]byte

	for {
		switch nr, er := inf.Read(buffer[0:]); true {
		case nr < 0:
			fmt.Fprintf(os.Stderr, "dd: error when reading from %s:%sn", inf.Name(), er.String())
			os.Exit(1)
		case nr == 0:
			inf.Close()
			of.Close()
			return
		case nr > 0:
			if nw, ew := of.Write(buffer[0:nr]); nw != nr{
				fmt.Fprintf(os.Stderr,"dd: error writing to %s:%sn", of.Name(), ew.String())
			}
		}
	}
	syscall.Sync()
}

 

编译:

$ 8g dd.go && 8l -o dd dd.8

运行:

./dd -if qi.tar.gz -of tmp

用一个400M的包做测试:

time ./dd -if qi.tar.gz -of tmp

real    0m16.636s
user    0m0.152s
sys    0m1.764s

比起来要比dd要快一点:

time dd if=qi.tar.gz of=tmp
记录了843029+1 的读入
记录了843029+1 的写出
431631274字节(432 MB)已复制,21.1584 秒,20.4 MB/秒

real    0m21.229s
user    0m0.516s
sys    0m4.624s

不过估计是因为我们的dd里面用的是4K的buffer吧。

time dd if=qi.tar.gz of=tmp bs=4096
记录了105378+1 的读入
记录了105378+1 的写出
431631274字节(432 MB)已复制,13.7601 秒,31.4 MB/秒

real    0m13.925s
user    0m0.040s
sys    0m1.424s

果然, 换成4096的buffer size要比go写的快一点。

总之,用go写程序比较爽。

How to Use Office Communicator under Ubuntu

发表于 2011-07-10 | 分类于 未分类

This artical is a description for how to enable "Windows Office Communicator" under ubuntu. These was some link have a description about this, like: http://sipe.sourceforge.net/install/

But it was out of date, can not success by following it.

Here is a detail operation:

  1. Add these lines to /etc/apt/sources.list:
    deb http://ppa.launchpad.net/aavelar/ppa/ubuntu jaunty main
    deb-src http://ppa.launchpad.net/aavelar/ppa/ubuntu jaunty main
  2. gpg -–keyserver keyserver.ubuntu.com -–recv BE79FA4B705B7C1
  3. gpg -–export --armor BE79FA4B705B7C1 | sudo apt-key add -
  4. apt-get update
  5. sudo apt-get install --reinstall pidgin pidgin-sipe
  6. if you failed with --resintall, please use this:
  7. sudo apt-get install pidgin pidgin-sipe

The create an account in your pindin account, the protocol please choose "Office Communicator".

If you meet some connection error after setup, please check your proxy setting in your account, maybe you need choose "No Proxy".



1234…11
Jiejing Zhang

Jiejing Zhang

110 日志
11 分类
24 标签
© 2017 Jiejing Zhang
由 Hexo 强力驱动
主题 - NexT.Pisces