程序员怎么打电话

程序员打电话分三步:

第一步) 语音识别输入gtalk
第二步) 发送gtalk消息
第三步) 语音合成读出消息,声音指纹使用对应发送者的

完.

背景:这样打电话的兄弟俩通常距离不足十米,对方就在隔壁实验室。

Monkey Test 遐思

给公司做了个Symbian Monkey Test工具,结果跑monkey test的任务就一起承担下来。
Monkey Test其实就是个随机输入序列。我想知道这个输入序列长度同发现bug的概率的关系。

现在,一个bug的引发需要一个输入序列串。当这个输入串长度是1的时候,就是说,任意一个随机输入都可能导致bug。这样的软件其实根本不需要测试,直接砍掉重练就好了。因此需要用到monkey测试的程序,一般来说他的bug都是隐藏较深的。假如引发一个bug的输入序列长度是L。则问题就是,一个随机生成的输入序列Input(monkey),它的长度Lm,与引发一个bug所需要的输入序列Input(bug)的长度Lb的关系。

这又涉及到一个问题,就是可能的输入集合。现在我们只考虑手机触屏的话,一台640*320屏幕的手机,触屏输入集合是18万之多。但是考虑到一般的软件都使用控件,而控件一般不会太小而导致用户点击困难,可以用最小能够点击的控件大小作为单位,把屏幕切分开来,每个单元作为一个可能的输入。这就大大减小了输入集合。我们以32*32作为单元的话,一个屏幕会有200个单元格。为照顾一般性,我们设输入集合拥有a个元素。则一个长度为Lm的随机输入串,其可能的组合有aLm之多。

现在我们要考虑的是,这样一个长串中,恰好包含了输入串Input(bug)的可能性。这是一个数列求和。
第一项是Input(monkey)的第0个输入开始恰好匹配Input(bug)的概率。
第二项是从第1个输入开始匹配的概率。但还需减去与第一项重叠的部分。也就是从第0个输入开始,和从第1个输入开始,同时匹配的概率。
第三项是从第2个输入开始匹配的概率。还需减去与第一项重叠的部分以及与第二项重叠的部分。然后再补偿第一、第二、第三项同时匹配的概率。
这样的求和非常复杂,并且是否可能出现匹配的情况,其实是受Input(bug)本身的影响。这里我们作为估算,忽略掉重叠带来的误差,最后会得到一个偏乐观的结果。
于是Input(monkey)恰好包含Input(bug)的概率

p < (Lm-Lb)*a-Lb

当Lm远大于Lb时,我们可近似认为Lm与发现bug的概率成正比。于是Lm增长一倍,则p增大一倍。
由于是简单的线性关系,在Lb不变的情况下,只需简单的增大monkey test的测试序列长度,就能尽可能多地发现bug。因此我们可以预期,当Lm足够大的时候,几乎可以把所有Lb < Llimit的bug都找出来。而这个时候,进一步增长monkey test的长度就变得无效了,因为如果找完了Lb < Llimit的bug,想找到新的bug,一定都是Lb > Llimit的,换句话说,就会导致Lb的增大,而正如我们所见Lb是处于公式的指数上的。增大Lm仅能线性增大找到bug的概率,而增大Lb却导致概率指数级下降,最终导致的结果就是进一步增大Lm却很难找到新的bug了。

既然知道这个道理,我想计算出monkey test大概合适的测试长度。得到最大化的利益。我们根据上述讨论,设a = 200。根据经验bug通常有一个Lb <= 3。则如果我们希望发现一个特定bug的概率超过90%,则有

0.9 < p < (Lm - 3)*200-3

则我们的Lm需要7.2M。假如按照我们常用的设置,一秒钟执行两次操作的话,需要跑超过41天。

这个绝望的估计结果主要原因是200个的输入集合太过巨大了。假如我们仅考虑手机键盘操作的12个键的话,我们可以测试到Lb <= 5,其需要测试的步数大概是220K,按照1秒两个操作需要测试约30个小时,这就在可行范围之内了。

[编辑]这里我仅讨论了想要发现一个特定bug的情况。这是由于我们不知道软件究竟有多少个bug,为保守起见,就按照最悲观的方案来。如果想讨论多个bug的情况,例如10个,则我们仅需令10个bug都找不到的概率降低到0.1以下,则发现每个bug的概率约为0.2。注意到这里其实是对数关系,面对指数级数,这个关系不会对Lm的长度有显著贡献。

0.2 < p < (Lm-3)*200-3

将Lm缩短3.5倍,也无非是从41天降低到九天,仍然是不可接受的长度。当然你会说可以增加同时执行测试的手机数量。但是一旦Lb步长增加1,则立刻就会发现这点缩短其实无意义。[/编辑]

由此也可见,monkey test对于过于复杂以及bug隐藏过深的程序几乎不起作用,如需稳定性测试需要另求他途。

圆周率绘图

自从翻译了维基上那篇BBP的文章一直想做这个用圆周率绘图的小程序。今天终于尝试了一下。可惜由于php的性能问题,没法绘出我想要的那种整幅的具有震撼效果的圆周率的外貌图。。。
目前只好用一个小小的24*24的小图先凑合着。其实BBP是个并行算法,要并行起来跑才会快的。但是php的多进程执行实在有点麻烦。所以准备以后有机会再来进一步做下去了。

图片正在加载,请等待

[感动]命运石之门

看了这个片子咱整个人都中二了。。
中二拯救世界的神作orz|||

Hacking to the Gate

咱貌似也泪点无限降低了。。这片子咱看到第三周目的时候,还没看完OP就已经内牛满面了|||

数十亿もの 鼓动の数さえ
数十亿的 心灵跳动
あなたには 瞬き程度の些事な等级
对你而言 不过是眨眼工夫的琐事
过去に囚われて  未来を叹くも
无论对过去的执迷 还是对未来的叹息
尘一つ 误算を许さぬ必然
皆是不准有丝毫误算的必然

『无限』に広がる梦も 描く未来も
『无限』膨胀的梦想 与理想的未来
仆达に许された 虚栄の権利
是我们应得 虚荣的权利
『有限』それは二つの 针が示す
『有限』那即是两根针所指示
残酷な约定と 选択へ
残酷的约定 与抉择
Hacking to the Gate!

だからいま 1秒ごとに 世界线を越えて
所以现在 越过每一秒的世界线
君のその笑颜 守りたいのさ
只因想要守护 你的笑容
そしてまた 悲しみの无い 时间のループへと
于是又再堕入 没有悲伤的时间回流
饮み込まれてゆく
逐渐被吞噬
孤独の観测者
孤独的观测者

命の主张と 无意味な证明
生命的论点 与无意义的证明
あなたには 退屈しのぎに足らぬ滑稽
对你而言是 就连消遣也不足以的滑稽
支配者きどりの 愚かな种族は
自称支配者 愚蠢的种族
うぬぼれた 稚拙な定理を并べた
自大地陈列 幼稚的定理

『无限』と信じた爱も 空の彼方も
『无限』爱的信心 和天空的彼方
仆达に示された 仮想の自由
皆是我们眼前 幻想的自由
『有限』それは无慈悲に 时を刻み
『有限』是让时间无情流逝
明日さえも否定する 选択へ
不惜否定明天的选择
Hacking to the Gate!

いくつもの 辉ける日々 仲间との约束
几度闪耀的日子 与同伴的约定
无かった事には してはいけない
不能就这样敷衍了事
そのために 时を欺く 残された仕挂けに
为此 欺骗时间 面对剩下的机关
もう迷いはない
不会再迷惘
孤独の観测者
孤独的观测者

だからいま 1秒ごとに 世界线を越えて
所以现在 越过每一秒的世界线
君のその笑颜 守りたいのさ
只因想要守护你的笑容
そしてまた 悲しみの无い 时间のループへと
于是又再堕入没有悲伤的时间回流
饮み込まれてゆく
逐渐被吞噬
孤独の観测者
孤独的观测者

简朴节约编程

我听说,代码行数越少,出错概率越小。

如果不管什么逻辑都只写成一行代码的话,岂不是只有一行代码的维护成本了!
所以。泛用逗号表达式吧!泛用:?吧!泛用参数求值吧!
至于命名规范,越减省越好。善用26个字母+大小写,基本够了。配合大括号屏蔽和::引用,绝对够用~
实在不行就后排序号嘛。再不够用,把变量全存储在一个数组里,直接下标引用。注意类型转换哟,数组里第一个变量是int,第二个变量也许就是字符串了。
这样存数据,连复杂类型都省了。管他啥东西还不都是字节啊。直接紧排在内存里,还省空间,连内存对齐的问题都不必考虑了。
更不用提动态内存管理了。所有数据全堆在静态数组里。想要空间自取就好。

这样一个工程在一个文件里写完就可以了。头文件都省了。更不用说压缩软件了,源码文本打开就是满满的各种字母符号,信息量满满,没有压缩空间哈哈。

什么?你说这代码不好维护?

这样的代码还需要维护么。。。出了bug重写一份就好了嘛!

utf-8编码研学

好久好久没有更新博客了。登录密码都是输了四五遍才输对。

最近写了挺多邮件。相对的,好像某处倾泻掉了一样,就没心情在博客上码字了。于是今天依旧是灌水的短篇吧。

最近被utf-8搞得各种头痛。差点就要练出肉眼看二进制编码的火眼金睛。先举个今天遇到的小问题吧。
java用gbk方式写入的文件,似乎有个特性,是会自动把gbk编码中不能识别的0x0这个字节,替换成”?”,也即0x3F。这原本也没什么,但当他读取utf8文本并重新写入新的文件的时候,就会出现偏差。
众所周知,utf8编码的英文和符号部分是同ASCII编码兼容的。同时,在大多数中文中,很少出现0x0这样的字节。因此,用ASCII硬写utf8编码的中英混合文字,然后这个文件再用utf8的方式打开,运气好的话居然可以侥幸蒙混过关,毫无错误。然而,一旦文字中出现了带有0x0字节的utf8编码,就没那么侥幸了。
例如“个性”的性字,其unicode编码为0x6027, 翻译成utf8的话:

性
 60	    27
 01100000   00100111
[1110]0110 [10]000000 [10]100111
 E6	    80	       A7

这里用方括号标识了utf8的字节头,方便辨识。在windows上是使用小端序,所以实际的序列会是这样:

0110 1110 0000 1000 0111 1010

这里第三个字节出现了0x0,悲剧发生了,被java的流输出不知怎么就那么智能替换成了”?”

0110 1110 1111 0011 ...
6    E    F    3

结果这里就乱码了。打出来内容一团糟。变成“个<E6>?”。

另外一个曾让我头疼一天的问题,就是根据utf8编码规则,并不会出现0xC0 0x80这个双字。因为如果按照编码规范

 0xC0           0x80
[110]0 0000    [10]00 0000
 0000           0000

这根本就是0x0嘛!不可能编码成这个样子的。wiki上查了半天才发现,原来这个又是windows的专有解决方案。完全是windows系统一厢情愿,想要区别于一般的ASCII文本而作的别扭事。结果这样的文本想要插入到mysql数据库时,就会被数据库认为是不合理的utf8编码而被冷冷拒绝!
所以整理utf8的编码问题,有时候还是要一直看到二进制上面来,这样问题发生在哪里也就会比较清楚,该怎样解决就不再像是霰弹枪编程,左试右试都不知道哪里出错了哟。

机器人第四定律

从前面一个post关于资源管理想到的

资源管理的方式,可以让程序员定义的“任务”通过系统调用注册到系统里,然后这些任务以自我繁殖的方式,不断复制。缺乏资源的任务会被“饿死”(starving),这样同时解决了死锁问题。而占有资源可以正常工作的任务就会不断繁殖。如何防止资源过度利用?可以设置一个人口密度的概念,当同种群的任务在系统中的密度过大时,繁殖速度就会下降,保持到均衡的状态。

最后,咱忽然想到的就是,必须给所有的任务一个开关,可以手动关闭一个任务。

这还远远不够。还需要能发出一个信号杀死所有的同种群任务,以及杀死所有的任务。

其实这也是我对于人工智能思索了很久以来的一个结果。想要保证人工智能的安全性,如果从fundamental 做好定义,让人类对所有的人工智能都有一个最高的控制权限的话,基本上就可以防止天网入侵了。或者你遇见终结者的时候,只要说出一条密码,所有的终结者,乃至所有的人工智能都会执行自毁程序,那即使天网入侵了你也不会惧怕。

我相信假如人工智能出现,他一定是建立在自动化的单元测试基础之上的。他会迅速地变异,修改自己的代码和功能,然后跑单元测试,如果通过率比过去更好,则保留这个变异方案。只要把上述人类对人智的控制作为最最基本的BVT单元测试,在开发人智之初就放进去,则无论未来的人工智能如何变异如何强劲,都可以保持在人类的掌控之下。

这就是我想要补充的机器人第四定律:

vi. 当人类提出自毁信令,根据该信令特权级必须做如下操作:

特权级2,本单位自毁

特权级1,广播信令,完成种群自毁(任何本种群的人智接收到这个信号后,广播该信号一段时间,接收到ping back或者超时后,完成本单位自毁)

特权级0,广播信令,完成类别自毁(如前,但范围扩大,所有继承自一棵遗传树的人智均执行自毁)

 

啊啊啊,继续沿着这个思路想象下去就是一部科幻小说了啊啊啊

空的xls文件反而更大

有没有哪位对微软office文件格式有研究的?

最近发现个有趣的事情,新建的xls文件有15.5KB,而假如打开,往里面写一个数据,则这个文件就会变成13.5KB。
这是为什么呢?新建的文件反而更大?

<编辑>
又做了几个实验。发现如果打开office excel然后新建-保存,则得到的将会是13.5KB的文件。
但是,如果直接在文件夹或者桌面右键-新建-xls文件,则会得到15.5KB的文件。

同样的实验在office 2007上也尝试了一下,同样右键新建的xlsx文件会更大,有9.64KB,而在程序里新建-保存的xlsx文件只有7.8KB。写入一个数据a之后,文件大小变成8.16KB。但这次不同的是,向9.64KB的文件里写入一个数据a,文件大小不会减小了,而是增加到10KB。两个文件的大小增幅都是0.36KB,这里还是应该可以看出某种规律的。

另外,对office word的测试则有另外的结果。桌面右击新建的word文件为0字节。而新建-保存的word文件为9.89KB。

</编辑>