2010年09月07日 09:16
好久没扯淡了。扯两句。
前几天在猛禽的推荐下,看了看web.py这个微型web框架。并用了大半天的时间写了一个简单的小应用。
还不错。
由此想到了一些不相干的问题。
首先想到的当然是我们的一个私有项目。这个项目折腾了好几年,最终勉强上线。但是大家都已经被折腾得没了激情。上线在我看来,也是象征意义大于实际意义了。
在这个项目的开发过程中,我解决了很多问题,收获算是不小。但是现在想想,解决的问题中,真正属于业务处理的有多少呢?很少很少。大部分问题都集中在框架层别。比如如何实现优雅的用户认证机制,等等。
我们的项目功能算不上复杂,也就是一个blog的水平。为什么这么简单的东西会拖上如此之久呢?原因很多,大多不足与外人道。但是我也认为有一个比较重要的原因,就是产品迟迟处于开发期,得不到发布。
记得曾经看过一本书,《梦断代码》,里面一帮比我们牛的多的牛人,拥有比我们好的多的环境,资金,氛围,合力开发一个项目,仍然失败了。于是我们看到了一本相当优秀的总结书(笑)。那个产品也有一个大问题,就是优秀的想法非常多,但是都无法进入最终产品——因为最终产品迟迟得不到发布。
每一个有点理想和追求的程序员都会有一个梦想,希望自己的代码能简洁优雅,希望自己的程序架构清晰流畅,能经典到流芳百世。
但是再经典的代码得不到实践的检验,也是白搭。你永远也不会知道用户会以怎样BT的方法使用你的程序,也永远不会知道你的代码究竟有多抗压,甚至也许有很多隐藏至深的bug,不在特殊的应用环境中也不会暴露。
更别提你的程序也许根本不符合用户的需要,或者用户会有更多要求……
另外,很重要的一点是,能给程序员带来最终成就感的,我认为并不是代码本身,而是代码运行的结果。每个人都希望自己的作品广为人知,而不仅仅是孤芳自赏。
所以,尽早的把想法实现,非常重要。
像web.py这样的小框架,就可以让你用quick and dirty的手法尽快的实现一个小东西。当然它欠缺的东西很多,但是都可以用quick and dirty的方式人肉实现。
有了成品再进行改进,就会有目的的多了。
但是quick and dirty并不是解决问题的金钥匙。就像无数软件工程指南中指出的那样,dirty不断累积,最后就会造成整个系统的崩溃和无法维护。
所以,尽早拿出成品,这只是一个开始。真正的关键在于你是不是有恒心有毅力去持续维护和改进它
并且保持整体结构不会变得更加糟糕。
有必要的时候,推翻重写。
这才是真正的问题。
2010年09月04日 21:21
继续尝试简明扼要的风格。
今天拿出久违的单反拍了一堆照片,等到晚上准备导电脑时发现杯具了。
我那只恐龙化石级的CF卡读卡器被两个儿子玩得不成器形了都,两排针脚完全扭曲成了麻花。尝试拨乱反正未果。
于是尝试把USB插到相机上。但是很显然相机没有被挂载为U盘。用lsusb发现设备被正确识别成了佳能350D,心中略安。
网上一顿狂找,发现一个gphoto2的工具可以直接支持相机操作,遂安装之。
结果发现……很杯具。不能用。
正在决定放弃之时又看到一篇资料说gphoto2仅支持相机的PTP模式。虾米鬼PTP模式?不过想想应该在设置里,去相机菜单里找了一下,果然有一个数据传输设置,可以设置成“打印/PTP”,设置之后,重新尝试……。OK了。
简单记录一下操作步骤:
设置相机的数据传输设置模式为PTP
用USB连接到电脑
打开相机
在电脑(Linux操作系统)上执行 gphoto2 --auto-detect,如果连接正确会看到相机被列出。
然后执行 gphoto2 -L 查找相机中的照片。注意一下照片前面有序号,下面会用到。
最后执行 gphoto2 -p <序号范围> 导出需要的照片。比如我要导出相机中全部的照片,在上一步中发现最后一张是 #176,则执行命令 gphoto2 -p 1-176,这个命令会把指定的照片导入到电脑的当前目录。
然后……该怎么办就怎么办吧。
不过我觉得我还是要去买只新的读卡器,这种导法麻烦不说,速度也慢了很多。
2010年09月01日 14:20
觉得以前遇到问题,总会洋洋洒洒写上一堆。我写得累你也看得累。所以这次我尽量简明扼要。
背景:
我的系统是用wubi安装的Ubuntu 10.04,Windows和Ubuntu双系统。
问题的产生:
看到一个grub美化的帖子,一时手痒,安装了,使用了,并且没有注意到它的错误提示。安装完之后启动,发现不是平时看到的Windows NTLDR,而是grub引导界面,并且是出错直接进入了rescue模式。
杯具了……
问题的分析:
因为使用wubi安装,Linux分区实际上被安装在/host/ubuntu/disks/root.disk,它所在的分区会在启动时由wubi引导程序挂载成/host,grub引导程序实际是安装在这个host(/host/ubuntu/disks/boot)上,而非mbr。因此在wubi引导之前,ubuntu的分区实际并不存在,如果将grub直接装到mbr,就无法引导ubuntu了。
另外一方面,可能是因为虚拟硬盘的存在,自动安装的mbr并没有正确识别出windows的引导程序,于是装好的grub也不能正确引导启动windows。
两者都不行,于是整个就杯具了。
问题的解决:
其实我们的目标就是要修复mbr,恢复成windows的那个版本。
而目前我的手头没有windows启动盘或修复盘。只有一张Ubuntu 10.04的安装盘。
杯具中的杯具。
还好Ubuntu 10.04可以当作LiveCD来用。
进入liveCD(试用)模式,然后配好网络。然后,上网找资料。
(此处省略过程1万字……)
经过几次失败尝试之后,找到了一个很容易的解决方法:
sudo apt-get install lilo (安装lilo,好古老的东东)
忽略一切错误提示
sudo lilo -M /dev/sda mbr
重启。
搞定。
-----------------------------
我真是一个善于修电脑的……好人呀。
各种求……我要变坏人……
2010年07月21日 16:21
最近工作性质有所变化,离开了数据库开发部门,转回了老本行,做C++开发。考虑到开发的C++代码大部分都是在Linux下运行,所以我的心思又活络了,很久以前考虑过的使用Ubuntu做日常工作的想法又蹦回了脑海。经过几天的构思和实践,我发现使用Ubuntu工作基本是可行的。
当然,用Ubuntu工作跟个人使用不一样,因为工作性质的关系,需要做一些迁就,并且要考虑到各种问题,不能像个人使用那般激进。
安装
首先当然是Ubuntu的安装。工作机并不是新机器,上面已经有大量日常工作数据和资料,包括文档、代码和其它各种资料,另外还有大量的个人数据。如果要空出一个分区来安装,需要做大量的迁移工作。为了减少工作量以及由此带来的各种风险,我选择了使用wubi安装。
wubi在选择的分区上创建一个虚拟的分区(有点类似虚拟机的做法),最大容量可以到30G,然后将ubuntu系统安装在这个虚拟的分区上。并且修改Windows的Bootloader,增加一个Ubuntu的选项。进入Ubuntu之后,所有的Windows分区,除了安装所在分区之外,都会存在于位置列表中,当你点击打开时进行自动的挂载。而Ubuntu虚拟分区所在的实际分区,则会预先挂载到/host目录。
按这种方式安装好的系统,Windows下的一切都不需要改动,只是在安装所在的分区减少了30G的容量而已。如果觉得不需要则可以安全的卸载。可以使系统迁移的风险降到最低。
基本办公
邮件/日程安排使用Evolution,稍加设置即可,没有什么麻烦,值得一提的是日程可以设置跟Google日历同步,结合我的android手机,很方便。Office文档可以用OpenOffice阅读和编辑。
MSN/GTalk交流可以用Empathy。另外Ubuntu 10.04有一个提醒指示工具,直接集成了邮件/IM的提醒,很好用。
C++开发
这是我最重要的工作,找一些合适的工具当然是很必要的。这里要稍微介绍一下我们的代码规范。我们的代码以组件的形式分布在上百个目录中,用配置文件的形式指名组件间的依赖。有一个自制的工具负责产生项目代码,在Windows下,这个工具可以产生VC用的makefile和Visual Studio用的dsw/dsp文件,在Linux下,这个工具可以产生makefile。
makefile做构建没有问题,但是并不利于代码管理。而在几百个目录之间做代码管理,用VIM显然不太合适。必须要有一个IDE。在网上稍微找了一点资料之后,我选择了Code::Block作为C++开发的IDE。那么如何将产生的makefile导入成Code::Blcok的项目呢?一开始我想了很多办法,都没有得到满意的效果。后来找到一份资料,说Code::Block支持项目使用外部的makefile做构建,这让我茅塞顿开:我不需要创建一个跟makefile功能完全相同的项目,而只需要一个包含全部文件的项目,并指定用外部makefile就好了!后者简单得多。我稍微修改了我们的工具,增加了生成cbp(CodeBlock Project)文件和workspace文件的功能,并在project里指定使用外部makefile进行构建,这样既可以使用Code::Block做文件管理,又不用担心构建跟原来有所不同。一举两得。
数据库
我们的项目经常要跟oracle打交道,因此一个oracle的客户端还是必不可少的。还好oracle提供了一些免费的工具,可以让我们完成这个任务。可以去Oracle网站下载oracle-xe.deb做客户端基础(注意oracle-xe从定义上来说是server,按理oracle-xe-client才是我们要的,但实际中我发现client缺少很多必要的功能,比如tnsname.ora,所以我还是选择装server)。然后使用SQLDeveloper这个免费工具做GUI。说实话SQLDeveloper没有PLSQL developer好用,但还算是一件不错的工具。
版本控制
我们公司相当BT的使用Visual SourceSafe做版本控制。想要公司在短时间内改用subversion/CVS/mercurial/git是不现实的,于是我只能自己想办法迁就了。
首先为了使用VSS,wine是不可或缺的。安装完wine之后,可以去找一份现成的VSS 6.0直接拷贝到本地就可以了。然后输入命令:wine SSEXP.exe就可以启动VSS的图形化界面了。有可能第一次运行会失败,报找不到MFC42.DLL,这个也比较容易,去Windows目录下找一个DLL丢到VSS程序目录就可以了。
在Linux下运行VSS是无法直接访问远程目录的。不过好在Linux有mount这个强有力的工具。我们使用cifs文件类型将远程目录mount到本地目录,然后在VSS里选择本地目录就可以了。在mount的时候要注意权限。
根据wine网站的说明,check in/check out/getversion等常用功能都没有问题,different会出错,但我实际实验是正常的。另外还说加文件不行,这个还没条件试,改天试试。
-----------------------------------
基本上这么一来,我的日常工作在Ubuntu下就没有问题了。以后如果再碰到问题,再解决。
2010年07月05日 11:50
有个需求:Windows服务器上有一堆的LOG文件,需要定期清理掉一些之前的文件,将他们归档到指定目录(归档时保持原先的目录结构)。
用Shell其实挺简单的,不过Windows服务器上不能用,而且服务器原则上也不能安装第三方的软件。所以只能通过BAT实现了。
本来认为这是一个不可能的任务,但是后来一查资料,原来Windows还提供了一个不错的工具:forfiles,可以查找指定日期之前之后的文件,并针对这些文件执行一个命令。这个命令可以满足我的需求。
这个命令是Windows 2003以上的服务器版本自带的,XP没有。如果需要的话,可以去下载一份2003的版本,直接可用。
但是forfiles执行命令的时候有个问题,就是他会将当前目录设定为扫描到的文件所在的目录,这一点在实现我的需求的时候,造成了一些麻烦。不过最后我还是写出了这个批处理,现在贴出来希望给需要的人一些帮助。
archive.bat
@echo off
rem 注意,以下所有涉及路径的变量,均必须为绝对路径,不能为相对路径。
rem 在这个批处理的同目录下必须存在do.bat,用于实际的文件处理
rem ====================================
rem 配置设定
rem ====================================
rem 扫描的源文件夹。此程序对目标文件夹是递归扫描的。
set SRC_PATH=f:\temp\test\src
rem 目标文件夹。需要归档的文件将存放在这个文件夹里。
rem 注意该文件夹必须为绝对路径
set DEST_PATH=f:\temp\test\dest
rem -- 归档几天前的文件
set DAYS=5
rem ==============================================
rem 实际程序开始
rem ==============================================
rem 实际处理文件的批处理程序
set DO_BATCH=%~p0\do.bat
forfiles /P %SRC_PATH% /S /D -%DAYS% /C "cmd /c %DO_BATCH% @isdir @relpath @path %DEST_PATH%"
do.bat
@echo off
rem 参数:%1=isdir %2=relpath %3=fullpath %4=dest_path
rem 注意:%2是相对路径
set ISDIR=%1
set RELPATH=%~2
set FULLPATH=%~3
set DEST_ROOT=%~4
set DEST_PATH="%DEST_ROOT%%~p2"
set DEST_FILE="%DEST_ROOT%%RELPATH%"
rem 创建必需的目标目录
if %ISDIR%==TRUE mkdir "%DEST_FILE%"
if not EXIST "%DEST_PATH%" mkdir "%DEST_PATH%"
rem 复制文件到目标目录
if %ISDIR%==FALSE copy "%FULLPATH%" "%DEST_FILE%"
rem 删除源文件(如果源文件是目录则不删除)
if %ISDIR%==FALSE del "%FULLPATH%"
其中 %~2中~的意思是消除对应字符串的分号("),比如原先%2的值是"c:\program files",%~2的值就是 c:\program files
%~p2的~p的意思是获取文件所在的目录。
其他似乎没什么好解释的了。
2010年06月24日 15:17
由于有了自己的VPS,终于可以拥有一个自己的域名,并不用再战战兢兢的使用那个该死的1984端口了。
以后 http://ch-linghu.com/blog/ 将会是主力blog站点。而 http://ch-linghu.3322.org:1984/blog/ 则会作为镜像站点继续存在。
RSS feed等相关改动随后跟上。
2010年06月13日 17:50
今天才写《赤壁》,感觉是不是有点奇怪。因为今天才在央视电影频道看了完整的赤壁上下。(其实也不算完整,断断续续的看了而已)
对于电影的观后感,其实非常简单。两个字:失望。我对于赤壁大战的期望,几乎没有任何一点在电影中有所体现,相反倒是看到了很多笑料和不合常理。
对于这部电影,我不想讲太多了,我在思考的一件事是:假如我去拍赤壁,我会拍得更好吗?
想了半天,答案是:难。
记得当初听袁阔成的评书三国,赤壁大战一段听的是惊心动魄。舌战群儒,黄盖诈降,周瑜几次设计陷害诸葛亮,一环扣一环,高潮迭起精彩纷呈。
以弱胜强的仗,本来就不好打。非奇谋不能成功。而奇谋本身,就是一场冒险,有很大的失败的可能。在这样的氛围下,看高手如何出谋,以及计谋如何在种种运气的庇佑下成功实施,就是一大看点。
然而这种看点很难用电影去表现。电影适合渲染火爆场面,适合呈现个人英雄主义,却不适合表现谋术。让观众看半个小时诸葛亮跟群儒的坐而论道,即使辩论本身再精彩,也是让人厌烦的。在电影赤壁里舌战一场就被压缩到很短,但是这样又让人觉得很突兀和无力。
电影还是一个片段展现艺术。一部电影只有短短几个小时,要展现全局是必很困难,只能展现一个片段,比如赤壁大战。然而没有诸葛亮的隆中对,没有刘备之前一逃再逃的事实铺垫,他舌战群儒时的很多观点就会显得很苍白。但是要把背景一一交待清楚,似乎又不是一部电影足以承载的。
其实在我的印象中,赤壁大战最吸引人的就是一系列的计谋运用。实际上整部三国,我觉得重点也就在一个权谋,一个计谋。但是这恰恰是电影难以表现的。赤壁大战真正的战争部分,小说里笔墨不多,评书里也不多。因此在电影里,尽管在竭力渲染,总让人觉得在隔靴搔痒。
想把赤壁拍好,确实难阿。
2010年06月04日 17:15
今天要是再不来写点什么,那就太说不过去了。
今天是猛禽和京京领证的日子,恭喜他们。
明年的今天将会是他们喜宴的日子。
21年前的今天……是一个不应该被忘记的日子吧。