2009年9月28日星期一

读书:《长尾理论》

上一篇书评提到了“长尾理论”,今天想聊聊这本书。 这部书提供我们一些新的视角来理解我们所处的世代。分析长尾的奥妙的章节写得很妙。以下是长尾的奥妙:
s1935122 1. 生产力普及: 工具制造者,生产者 - 数字摄像机,博客工具
2. 传播普及:集合器    - 亚马逊,ebay
3. 供需相连:过滤器    - Google,博客,畅销榜
为什么Google这么强大,本书对这个问题也通过长尾理论的角度进行了回答:“搜索引擎之所以成为硅谷的一大经济力量,这是因为我们认识到来衡量和分析大众行为的价值。在一个无限选择的时代,统治一切的不是内容,而是寻找内容的方式。”
这本书最让我感兴趣的是其中关于亚马逊和Salesforce.com的分析。它们的例子可以让人感到一些的“思维颠覆”,看来这些例子的同时似乎也呼吸到了新经济模式中的精妙,颠覆的味道,其中“亚马逊即需及印的概念。在理想化的情况下,一本书在出售以前一直只是数字文件而已。”而Salesforce.com,“第三方开发商们可以编写某个指定的小应用程序,这个程序 会在Salesforce的服务器上运行,于Salesforce的其他软件合为一体。Salesforce希望成百上千的小开发商能够满足顾客们的各种特殊的需求,这样的话,Salesforce就可以把精力集中在更常见的需求上。”Salesforce.com的模式,也许是未来软件行业发展的一个重要的方向,它结合了云计算技术,体现了“软件即服务 saas”的思想,同时也抓住了长尾理论的精髓,这个案例也许很值得计算机行业的从业人员分析和学习。
这里摘录一些我最喜欢的观点:
“集合器可以瞄准特定的细分市场。”
“纯数字模式下,每一种产品都只是数据库中的一个条目而已,实际上没有任何存储存储成本。传输成本只是带宽字节,这种东西可以大批量购买,价格也正在迅速降低,而仅在产品被订购的情况下才需使用。”
”当我们的文化碎裂成千千万万的小文化碎片,小名人们也随之崛起了。“
“大城市之所以存在,是因为秘籍聚居的文化和经济优势完全可以弥补城市的成本。颇有讽刺意味的是,其中一个优势是无奇不有的细分市场。”
“对零售商店来说,可获得性和便捷性就等于更高的销量。消费者在选择更多的情况下更容易消费。”
”不存在大众,只存在把人们看作大众的方法。现在是百花齐放的小众文化时代。“
“博客可以专注于某些特殊的主题,这样的专业化程度,媒体企业的记者们没几个能做到。”
本书还谈到一个可以自我出书的网站:http://www.lulu.com/index.php, 哈,很有趣吧。
在一个无聊的午后或晚上,阅读《长尾理论》,了解一些关于“这个一个无限选择的时代,百花齐放的小众文化时代,网络时代……”的商业道理的同时,你一定还会感受一些新思维的冲击,这就是本书的过人之处。

2009年9月26日星期六

读书:《C++编程规范:101条规则、准则与最佳实践》

我很喜欢看书,也看了不少书,各种各样五花八门。在“一个无限选择的时代”,就像《长尾理论》说的我们的一些评论可以起到“过滤器”的作用,提供他人一些参考。我很乐意写一些书评关于某些我感兴趣的书,并将它们放在这里和豆瓣上,希望能对“同好”在选择书的时候有所帮助。

今天谈的书为《C++编程规范:101条规则、准则与最佳实践》,这本书相当适合和象我一样有一定C++编程经验的初级,中级程序员阅读。这本书讨论了101个规则,每个规则都按照,固定的格式(包括条款标题,摘要,讨论,示例等部分)进行说明。这样的编排方式即清晰又符合我们理解接受的渐进过程。C  编程规范
也许可以边看书边试着做一些回忆,想想自己是否在编程时候使用或注意到这些规范。还可以问自己一些问题,例如在我们的设计风格中是否注意了,”对一个函数之赋予一种职责“,”正确,简单和清晰第一,软件简单为美(Keep It Simple Software, KISS)“,”优先使用线性算法或者尽可能快的算法:例如O(N)“,”尽量减少全局和共享数据(会增加耦合度,从而降低可维护性,通常还会降低性能)“等等。
我们也可以考虑一下我们的编程风格,并问自己: 我们有没有做到避免使用宏, 尽可能局部声明变量, 总是初始化变量,避免函数过长,避免嵌套过深,是否做到确保所编写的每个头文件都能够独自进行编译。
C++之父Bjarne Stroustrup说过“软件开发最重要的一个方面就是弄清楚自己要构建的是什么”,对于类的设计与继承这一部分也相当值得一读,例如以下条款“用小类代替巨类”,“ 用组合代替继承”,“避免从并非要设计成基类的类中继承”,“优先提供抽象接口”,“共用继承即可替换性。继承,不是为了重用,而是为了被重用,Liskov替换原则: Liskov Substitution Principle,共用继承所建模的必须总是“是一个is a”,更精确的“其行为象一个 works like a ”关系:所有基类约定必须满足这一点。”等等,也许我们对这些规则都了然于胸,但是我们是否时时刻刻注意到这些规则呢,这本书就提供了这样一个“小声音”,提醒我们,在经过一段时间的编程后,我们也许常常会被一些“坏习惯”占据,这个“小声音”,也许就是摒除这些“坏习惯”的利器,
也许你和我一样在编写C++的时候会不自觉地使用了一些不先进的C的方式,例如使用数组,匈牙利标法,switch等等,看了这本书后绝对会大有启发,例如以下的部分书摘:
”匈牙利记法:将类型信息并入变量名的记法,是混用了类型不安全语言(特别是C)中的设施,这在面向对象语言中是可以存在的,但是有害无益,在泛型编程则更不不行。所以,任何C++编程规范都不应该要求使用匈牙利记法,而在规范中选择禁用该记法则是合理的。“
”通过类型分支(type switching)来定制行为既不牢固,容易出错,又不安全,而且是企图用C++编写C代码的明显标志。这是一种很不灵活的技术,要添加新特性时必须回过头对现有代码进行修改。它还不安全,因为添加新类型时,如果忘记修改所有分支,编译器也不会告知。“
“不要使用C语言风格的数组,指针运算和内存管理原语操作实现数组抽象。使用vector或者string不仅更轻松,而且还有助于编写更安全,伸缩性更好的软件。毋庸置疑,在当今软件中缓冲区溢出和安全缺陷是罪魁祸首。固定长度的数组所带来的愚蠢限制,即使仍在正确界限内,也是软件开发人员的一大困扰。”
”不要使用C风格的强制转换。“
初级,中级程序员看了本书后一定会大有收获,掌握这些规范,也许是成长为优秀程序员的重要的坚实一步。

2009年9月20日星期日

电子工程师乱弹编程-使用开源代码技巧

还记得我们学语言的时候,就是从模仿开始的。对我们这些外行人,第一件事不是试着”说话“,而是应该学习如何做到“牙牙学语”。今天我想乱弹的问题是如何阅读别人写的代码,并使用它。通过读别人的代码来学习技术即实际也很有效率。现在很容易就可以搜索到很多优质的开源代码,读懂别人的代码然后加以修改加入我们的项目,外行人或技术落后者也可以做出和专业人士一样高质量的软件。这里我想到一件事,中国最早的第二代坦克80式有:德国730匹柴油发动机+英国的双向稳定火炮控制系统+奥地利的105毫米线膛炮。通过引进吸收十几年过去了,中国的99式,第三代主战坦克,已经是世界上最先进的主战坦克之一,所有的配件完全国产,并掌握所有相关技术。以下我想结合这个坦克制造这个例子谈谈阅读使用开源代码的技巧。

技巧:

整合资源阶段:若想在我们的坦克中加入德国730匹柴油发动机,那么首先应了解这个发动机的性能参数,搞定一切我们所需要的资源,使用开源代码也是一样。


# 下载源码文档。
# 找到源码文档的网页(例如通过文档生成器的doxygen写的文档),我们可以轻松地通过这个网页阅读程序,这种方式的阅读效率也是很高的。
# 找到自己感兴趣的部分,通过这个部分可以"解决我们需要的一个特定的问题"。
# 了解命名规则(或惯例)。
# 试着在网上找一下“专业人士”对该代码的分析,这样会对我们理解整个系统代码概括达到事半功倍的效果。例如,我们想要使用FFmpeg的源码,我可以找到很多关于源码分析的文章,我们可以很轻松的理解FFmpeg的数据结构,理解它们的关系,例如“AVFormatContext派生出AVStream派生出AVCCodecContext派生出AVCodec”。通过网上的文件我们可以快速地理解FFmpeg的初始化函数和编码函数的使用方式,有些数据结构和函数比较生涩难懂,但是如果有了这些文章的帮助,我们可以迅速上手。
# 保存归纳搜索到的资源。
# 背景知识的准备,也许有时需要一些背景知识,还是FFmpeg这个例子,例如有些概念需要理解mux, demux, encode, decode, codec, yuv, 容器格式,视频格式等等。这对于真正理解源代码也很重要。如果只是停留在代码的层级上理解,其实并不是真正读懂了这个代码。也许这是我们学电子学生的优势,也许我们的抽象力不如学计算机学生,但我们可能会更容易地从现实层面知识背景层面理解代码的内涵。如果我们彻底了掌握了我们的坦克中要加入德国730匹柴油发动机的技术,那么离我们自主创新也不远了。

修改拆解,编译,调试阶段:如何将英国的双向稳定火炮控制系统放入我们坦克系统中,让它发挥出效能,是这部分我们要谈谈的内容。


# 拆解代码,然后将拆解的代码加入我们的项目中。
# 编译调试代码,在编译的过程中一定会有很多问题,一定要有耐心,细致。(也许有时先注释掉一些代码,然后再编译也是一个方法。),也许有时编译不通过 是因为没有完整加入所需要的全部元素。
# 编译成功后,试着让它能正确运行。
# 反复调试,如果可以,这时加入单元测试。

优化,提炼,系统整合阶段:继续开篇的例子,坦克系统相当复杂,如何优化,提炼,系统整合这些新加入的配件,绝对是成败的关键。


# 统一编程风格。我们整合的原代码的编码风格肯定和我们自己的风格不一样,先统一风格。
# 改善代码的结构。
# 优化代码,整合系统,考虑系统效能
# 除去一些不必要的代码,提高系统效能。

总结:整合资源,修改拆解,编译,调试,优化,提炼,系统整合并试着锻练自己的阅读技巧。

预告:下一篇文章我想结合我的一些经验和教训,谈谈电子工程师编程时的“坏习惯”和(群体成员背景和价值观的相似性产生的)“团体迷思”,文章选题比较泛将分篇释出。

2009年9月18日星期五

电子工程师乱弹编程-谈谈工具

使用源码控制软件,在软件开发中非常重要,使用SVN吧,我以前谈过,比CVS强大很多。

编程的时候请给自己找一个安静的工作环境,现在笔记本非常普及大可以很轻松地找到一个安静舒适的环境,在桌上准备一根笔和一张纸,很多抽象并不是简单的通过纯思考就可以构建出来,在具体解决问题的时候,有时你也可以在纸上画一个脑图,以理清思路。

使用最好,最适合自己的工具,很多工具非常好但是并不是最适合自己的,IDE和编辑器几乎是你手的延伸。

IDE没什么好说了,具体使用Eclipse或Visual Studio因情况条件而异,但是熟悉这个IDE的所有特性是非常重要的。这里想谈谈编辑器,精通一种编辑器就如同你装了一个机器手一样顿时生产力有了质的飞跃,你甚至不需要用鼠标,必须的操作甚至只是一种条件反射。编辑器的选择因人而异,例如编辑器Emacs很强大,很多高级的特性对于我们这种外行人来说并不是很适合,因此我选择轻量级的notepad++,但是它基本的拓展性,可配置性一点也不差,使用notepad++的最简单技巧我在以前的文章也提过了。

说到工具,不得不提到计算机硬件,我以前的一台古董笔记本陪我很多年,但是因为有了远程登入的这个功能,古董的笔记本也可以有第二春,远程登入一台性能强大的台式机,你可以获得强大的计算力,笔记本这时候就是一个客户端只需要能上网即可,我和我的导师共同远程使用一台配置了Ci7 CPU的计算机,这台高性能的计算机就如同云端,提供类云计算的服务,强大的硬件也可以在另一方面提高工作效率,我刚刚装了一台新的台式机,但是我还是远程登入学校的计算机来编程,我完全不需要在本地安装编程或工作需要的各种软件,这样不仅节约了配置软件的时间,同时云端上的计算机的数据的安全性也远高于本地数据。

总结:源码控制软件, IDE, 编辑器,安静的环境,较好的计算机硬件。

电子工程师乱弹编程系列-开篇

作为一个电子系的学生,我以前和很多同学一样对编程有些排斥,总是认为编程这种事是程序员干的,作为电子工程师应该是“做电子工程师该做的事“,其实在内心对编程有些害怕,所以才会产生抗拒感。去年,我被导师“推入”一个比较大的软件项目的开发,因为这是我们电子系的一个项目,这个项目既有软件也有硬件开发部分,因为一时找不到学计算机的学生来做软件,只好死马当活马医,学电子的上。一开始和大家一样很排斥编程,痛苦不已,而且还是使用我几乎毫无基础的C++。还好有7*24小时的解答,终年无休Google老师,和它无数次的”交流”后,一段时间静下心一步步的痛苦编程后,现在项目快做完了,但是我早已经喜欢上编程,其实编程非常有趣,和很多人说的一样它是一种工艺,或艺术。看了一些大牛写的书,计算机的书真是相当的多,看完后真是获益匪浅,很多书谈的不仅仅是编程,更深层的是告诉我们一些思考问题的方法,看世界的观点,我们电子的教材相较之下逊色很多,还有一点很有感触,很多计算机的大牛不仅在他的领域很强,他们的文笔非常漂亮,行文相当生动,譬如Joel Spolsky的书。学电子的会软件编程,可以让我们对于事物的抽象能力得到很大的锻炼,逻辑思维能力也会得到一定的拓展,可谓是相当有益,并且以后再很多工作场合可以“软硬兼施”,大展身手呢。

很早就想写这个系列文章,我不写什么教程(想写也写不出,呵呵),而是每篇文章聊一个小问题,这些问题的探讨将基于我有限的经验,如果文章中有错误,请读者大方指出,我将要讨论的问题天马行空,并不仅仅局限于编程,并且对这些问题的讨论一般不会很深入,文章也会比较短,希望对和我一样的学电子出身的你有所帮助。当然了,这不仅写给学电子学生,本系列文章的目标读者为和我一样“半路出家”对编程没什么基础的同学。

2009年9月17日星期四

ffmpeg的使用,及发送媒体流的一些简单介绍

在以前的文章谈过对ffmpeg的编译。这里谈谈ffmpeg的最简单的使用。

ffmpeg使用语法:

ffmpeg [[options][`-i' input_file]]... {[options] output_file}...

最简单的使用:ffmpeg –i test_mp4.mp4 test_mpg.mpg (将输入的mp4容器格式的文件转换成mpg格式文件)

我在做一些机器人控制实验时常常会得到很多的jpg格式的文件,将这些文件改成连续的名称,例如test_jpg00001, test_jpg00002等等,然后可以通过ffmpeg生成一个视频文件,这会很方便演示,例如:
  ffmpeg -r 15 -b 1800 -i test_jpg00%03d.jpg test_mp4.mp4 (这里,-r 代表fps 设置帧频;–b 代表bitrate 设置比特率; test_jpg00%03d.jpg中%03d代表最后三位数字)

做实验时,直接通过摄像头可以得到raw picture(也就是YUV或RGB文件),这时也可以通过ffmpeg将它们转换成mpg或任意容器格式。例如:ffmpeg -s 320*240 -i test_yuv.yuv test_mpg.mpg (这里请注意在写入输入文件之前,必须给ffmpeg传入帧大小,也就是通过 –s 来设置帧大小)。当然了,你也可以将例如mpg格式的文件转换成YUV文件,即,ffmpeg -i test_mpg.mpg test_yuv.yuv。
 

除了转换格式ffmpeg还可以做更多的事,例如发送媒体流,通过rtp协议,可以输入以下的命令:

ffmpeg -fflags +genpts -re -i test.mpg -vcodec copy -an -f rtp rtp://127.0.0.1:10000 -vn -acodec copy -f rtp rtp://127.0.0.1:20000 -newaudio

其中,-re 代表本地帧频读数据;-an 代表不使能音频纪录;127.0.0.1也就是本地回环地址,我们常常使用它来测试本机的网络配置,通过PING127.0.0.1来检测本机的网卡和IP协议;当然我们还可以使用它来代替SERVER的IP地址,这样程序就可以在同一台机器上运行,所有的SERVER的资源就可以装在本机,我们程序就可以运行。

使用ffmpeg发送了媒体流后,我们可以在写字板里写一个SDP文件(附注:文件的后缀也是.sdp),例如:

v=0
  o=- 0 0 IN IPV4 127.0.0.1
  t=0 0
  s=No Name 
  a=tool:libavformat 52.23.1
  m=video 10000 RTP/AVP 32
  c=IN IP4 127.0.0.1
  b=AS:104857
  m=audio 20000 RTP/AVP 14
  c=IN IP4 127.0.0.1
  b=AS:64

然后通过vlc就打开这个sdp文件,就可以播放我们发送的媒体流了。

#####    #####

谈到了媒体流的发送,我想继续延伸聊聊:我们也可以使用以前介绍过的LIVE555.COM提供的LIVE555 Media Server,来发送媒体流,很简单:可以直接下载live555MediaServer.exe,然后输入: “live555MediaServer 你的文件”,例如live555MediaServer D:\test.mpg。媒体流就发送了。然后可以使用vlc来播放,vlc rtsp://本机IP/文件名(附注:在Window里通过ipconfig可以看本机IP), 例如 vlc rtsp://131.***.**.101/D:\test.mpg。

结语:播放媒体流使用vlc或一些其他的工具就在GUI里可以简单的执行了,这篇文章最后一部分是希望给读者提供一些思路,例如使用ffmpeg,LIVE555发送,并使用不同的发送方式和接受方式。

2009年9月2日星期三

最常用的Notepad++的快捷键

如果Notepad++是程序员的一个生产工具,那么快捷键的使用就可以提高生产效率,记住一些快捷键是挺有用的:-)。

http://notepad-plus.sourceforge.net/uk/shortcuts.php这上面有完整的快捷键表格,但是很多都记不住,因为很少用。除了Ctrl-C,Ctrl-X,Ctrl-V,Ctrl-Y,Ctrl-A,Ctrl-F,Ctrl-S,Ctrl-O,Ctrl-N,Ctrl-W,Ctrl-Tab,Ctrl-P,Alt-F4这些基本的,也许有些简单的比较有用的快捷键,你可能有兴趣知道。

Ctrl-H 打开Find / Replace 对话框
Ctrl-D 复制当前行
Ctrl-L 删除当前行
Ctrl-T 上下行交换
F3 找下一个
Shift-F3 找上一个
Ctrl-Shift-F 在文件中找
Ctrl-F2 触发书签
F2 到前一个书签
Shift-F2 到下一个书签
F5 打开run对话框
Ctrl-Space 打开CallTip列表框
Tab (selection of several lines) 加入Space
Shift-Tab (selection of several lines) 移除Space
F11 全屏
Alt-0 折叠全部
Alt-Shift-0 展开全部
Ctrl-U 变为小写
Ctrl-Shift-U 变为大写
Ctrl-Q 块注释/消除注释

使用ModelSim做simulation一些小问题的简单解决方法

使用ModelSim做模拟常常会遇到一些小问题,常常没有很在意但是常常又发生:-),这里谈谈遇到以下几个小问题的解决方法。

1.遇到类似以下的问题:

# ** Error: /homes/ethernet/eth_spram_256x32.v(151): Module 'RAMB4_S8' is not defined.
  # **Error: /homes/ethernet/xilinx_dist_ram_16x32.v(20): Module 'RAM16X1D' is not defined.

解决方法:进入Simulation Properties: Libraries --> 在Search Libraries中加入unisim(如果是要做 UNISIM-based RTL simulation)
如下图所示:

SearchLibraries_Modelsim

2.遇到类似以下的问题:

# ** Fatal: (vsim-3693) The minimum time resolution limit (10ps) in the Verilog source is smaller than the one chosen for SystemC or VHDL units in the design. Use the vsim -t option to specify the desired resolution.
#    Time: 0 ns  Iteration: 0  Instance: /sample_tb File: /homes/sample_tb.vhd Line: UNKNOWN
# FATAL ERROR while loading design

解决方法:改变Simulation Properties: Libraries --> 在Search Libraries中加入unisim(如果是要做 UNISIM-based RTL simulation)
如下图所示:也是进入Simulation Properties,然后如下图所示,改变Resolution。

Simulation_Properties_ModelSim

3.遇到类似以下的问题:

# ** Error: (vsim-3601) Iteration limit reached at time 0 ps.

# ** Note: (vsim-3602) Delays were truncated during elaboration of the design.

解决方法:进入Simulation -> Runtime Options,然后改变Iteration Limit,将它改成例如5000。如下图所示:

RuntimeOptions_Modelsim