跳至主要内容

博文

DAO层测试

<dependency> <groupId>com.wix</groupId> <artifactId>wix-embedded-mysql</artifactId> <version>2.1.4</version> <scope>test</scope> </dependency> 利用 wix-embedded-mysql 把MySQL嵌入到进程中,作为内存型的MySQL来做单元测试。 脚本: resources/migrations/mysql/<database>/<timestamp>_<action>.sql 但多个项目需要共享数据库脚本,可能可以用 git submodule 共享。
最新博文

OmniGroup

前几天买了OmniGroup全家桶,强迫自己熟悉这些“效率工具”。现记录一些自己的理解。 为什么这些工具的功能看起来有重叠? 我的理解是每一款应用都是面向特定领域的专业人士的,并不会真的有像我这么“变态”的人一下子买全家桶的。 每款工具各自的作用和区别? OmniFocus:面向个人的GTD工具,。 OmniPlan:面向小组的项目管理工具。OmniFocus和它的区别:前者管理个人的行动;后者管理一组人的任务。 OmniOutline:它和OmniFocus的功能重叠度很高,但作为区分:Focus更专注于Action,即动词;Outline更专注于清单,即名词。 OmniGraffle:这款应用和其他三款区别最大,它是画图软件。它用起来不像我自己开发的KingYoung那么“流畅”,但的确很漂亮。我为了方便使用,还把积灰已久的鼠标拿出来。 OmniFocus 收件箱:灵光一闪,马上收集 项目:根据项目,纵向地将Action组织到一起。项目的特点是有始有终。例如具体看某一本书 上下文:类似于Spring的AOP概念,从横向/切面上看Action。例如读书,可以贯穿所有读书项目 透视:其实就是搜索功能

在 Cygwin 下编译 netcat_1.10-38

我在《 Linux下用nc实现 DuplexPipe 》中提到,Win 版的 netcat 无法实现 DuplexPipe 的功能。 其实 Cygwin 版的 netcat 也是如此。Cygwin 用的是 netcat 原生的 1.10 版本(项目地址是:http://nc110.sourceforge.net/),该版本没提供 -c 选项。因为我最近在做的项目需要一个这样的工具来帮助测试,于是就决定自己编译 1.10-38 版的 nc。 编译 首先到 debian 下 netcat 的主页下载源代码(http://packages.qa.debian.org/n/netcat.html),测试版已 经到 1.10-39 版本了,我选择稳定版 v1.10-38(http://packages.debian.org/source/stable/netcat)。需要下载两个文件:其中 netcat_1.10.orig.tar.gz 是原生的 nc; netcat_1.10-38.diff.gz 是升级包。 下载完成后先解压: $ ls netcat_1.10-38.diff.gz* netcat_1.10.orig.tar.gz* $ tar xvf netcat_1.10.orig.tar.gz ... $ ls netcat-1.10.orig/ netcat_1.10-38.diff.gz* netcat_1.10.orig.tar.gz* 接着是释放补丁 $ cd netcat-1.10.orig $ ls Changelog README generic.h netcat.c stupidh* Makefile data/ netcat.blurb scripts/ $ zcat ../netcat_1.10-38.diff.gz | patch -p1 $ ls Changelog README debian/ nc.1 netcat.c stupidh* Makefile data/ generic.h netcat.blurb scripts/ 补丁被释放到 debian 目录下。然后就是给源代码打补丁了。 $ sed 's#^#patch -Np1 -i d

AutoHotKey 新手入门教程

AutoHotKey 真是一个好玩的工具!短短几行代码就是先了“窗口置顶”、“窗口透明”等功能,之前我还特意为此装了好几个小工具,现在都可以卸掉了。闲来无事,就把 Quick Start 翻译了一下,我没有逐字逐句地翻译,有时候我嫌原文罗嗦就用自己的话概括地描述了一下。 原文地址:http://www.autohotkey.com/docs/Tutorial.htm 教程目录 创建脚本 启动程序 模拟鼠标键盘 操纵窗口 输入 变量与剪切板 循环 操纵文件 其他特性 创建脚本 每个脚本都是一个纯文本文件,由一些能被 AutoHotKey.exe 执行的命令组成。一个脚本可能还包含 热键 和 热字符串 。如果没有热键和热字符串,脚本在启动的时候就会从头依次执行到尾。 创建一个新的脚本: 下载 并安装 AutoHotkey。 右击鼠标,选择 新建 -> 文本文档 。 输入文件名并确保以 .ahk 结尾。例如:Test.ahk。 右击文件,选择 编辑脚本 。 输入以下内容:#space::Run www.google.com 上一行的第一个字符 "#" 代表键盘上的 Windows 键;所以 #space 表示在按住 Windows 键后再按空格键。"::" 后面的命令会在热键激活后执行,在本例中则会打开谷歌主页。继续按下面步骤操作,来执行这个脚本: 保存并关闭该文件。 双击该文件来启动它。在系统托盘里会出现一个新图标。 按下 Windows 和空格键,网页会在默认的浏览器里打开。 右击系统托盘里的绿色图标可以退出或编辑当前脚本。 注意: 可以同时启动多个脚本,并且在系统托盘里都会有一个相应的图标。 每个脚本都能定义多个 热键 和 热字符串 。 想让某个脚本开机即启动,可以将它的 快捷方式放到开始菜单的启动目录里 。 启动程序 命令 Run 可以运行程序、打开文档、网页链接或快捷键。请参看以下示例: Run Notepad Run C:\My Documents\Address List.doc Run C:\My Documents\My Shortcut.lnk Run www.yahoo.com Run mailto:someone@somedoma

人所不欲,勿施于人

谁说博客也要像论文一样结构清晰、有条理?! 软件卸载 昨天整理自己的本本,卸载了 VMware 7.0 + 深度XP,MS Office 2007 以及 Visual Basic 6.0。我承认这些都是盗版软件,不过剩下的应用程序都是自由软件(freeware)或免费软件(freeware),这下我的计算机“干净”了。闲来无事,我就细数了一下当初装这些软件的原因: VMware + XP:当初刚买本本的时候,正好在上软件工程实践,紧遵老师的教导“将自己的开发环境随身携带”,自然第一款软件就是装了虚拟机(学校机房里是肆无忌惮地用盗版 VMware),另外上课指定使用 Visio 作图,那也只好一起装了;当然,也有部分原因是因为某些人的计算机装的是 XP,我这边有个 XP 环境也是为了方便问题重现(我的本本预装了 Vista)。 MS Office 2007:在毕设期间,我也还是用 Open Office 和 WPS 2010,但现在公司用的却是 Office 2007(正版)。我这次卸载这款办公软件其实也是在提醒自己:工作的事情要在工作时间里完成! VB 6:你可能无法想象在我们科班的毕业设计中有多少是 VB6 项目,从大二开始,每逢毕业将至,总会有人来找我帮忙看那些不晓得从哪儿搜罗来的 VB6 代码,经不住软磨硬泡,我总会帮着改改;另一个原因在我自己,我一直下不了决心去学 MFC 等,所以但凡要做 GUI 程序,我都是拿 VB6 来画界面,再调用由 C 语言开发的 DLL 库,不过现在改用 QT,于是 VB6 可以功成身退了。 己所不欲,勿施于人 有些人就喜欢把自己的事全盘交托给别人来做,我一直不明白他们既然有精力去说服别人,为什么就没耐心自己去完成(所以我下面说人和人之间是无法理解的)。既然自己都认为这是无聊的事情,为什么偏偏又假设其他人会愿意无偿地帮你来完成呢? 两千多年前,孔老夫子提出“己所不欲,勿施于人”的观点,但到了今天,我听到关于这句话时的语境普遍是,A说:“那个XX东西你也不要了(或要了也没用),不如就让给我吧?”,B就义正言辞地反对:“那怎么可以!己所不欲,勿施于人嘛。” 己所甚欲,勿施于人 易中天老师在《百家讲坛》讲解诸子百家时提到庄子的思想比起“己所不欲,勿施于人”更进一步:“己所甚欲,勿施于人。” 如果你对此还不甚了解,建议去看看《武林外

Pig 更新: 发布 0.7 版本

关于 Pig Pig 是一款文件格式化工具,它可以将“金山词霸”生词本软件导出的格式混乱的文件整理成网页格式,方便大家打印。更多内容可以参考以前的文章 《和 Pig 一起学英语》 。 Pig 距离上一次更新有快两年的时间了,期间发生了很多事。其中一个原因是我后来对自己电脑上的软件进行了正版化清理:诸如 Visual Basic 6.0 精简版、VMWare 等盗版软件都被我卸载了,而 Pig 之前的版本都是用 VB6 精简版 + Dev-C++ 开发的。 姗姗来迟的新版本 事隔这么久,期间也有几位热心网友发邮箱报告程序 Bug,并对程序新功能提出了展望。可惜这次的更新不仅没添加任何新功能,反而还砍掉了一些比较鸡肋的功能。 程序界面如右图所示,与以前的界面相比变化不大(这正是我想要的)。不过本质区别是:以前的 Pig 是一个独立的可执行程序调用一堆动态链接库来完成任务;如今的 Pig 只是一张网页,通过执行 JScript 和极少量的 VBScript 来实现功能。 新版本解决的问题有: 这次的开发编辑器用的是 Emacs,语言选的是 JavaScript 和 HTML。开发环境方面没有版权问题。 随着金山词霸本身的升级,生词本导出文件的格式出现了调整。有网友反映 Pig 不能处理这些新文件。这次更新也增强了这方面功能,现在 Pig 能处理到目前为止的所有版本生词本导出的文件。 Pig 之前的版本是用 VB 和 C 语言写的,源代码并没有随程序一起发布。这回简单了,JavaScript 和 VBScript 天生具有开源性质,源代码就是程序,你想怎么改都行。 更新了帮助文档。 砍掉的功能有: 合并“指定输出路径”和“生成单个文件”两个功能; 删除“输出卡片风格”(这功能真的没人用),统一用“列表”形式; 删除“图片格式”(当初有这个功能是因为 IE6 不能显示 Unicode 编码的音标,哪知我是费力不讨好:大家背单词并不关心音标); 删除“PDF格式”(也是费力不讨好的活); 删除“字段排序”功能(目前还没人把音标或解释放到单词前面来打印)。 下一步预期: 我自己的系统是 Vista,必须找台 XP 的电脑测试一下(毕竟目前的用户都是用 XP 的);(Done @ 2011-01-03) 生成 Excel 格式的文件; 在已安装

listfile.exe 用正则表达式来找文件

背景 最近的工作里,涉及到不少目录之间的批量操作(产品的部署、文件夹之间的同步等等)。工作的环境是 Win XP,没有自带诸如 Linux 下 find 这样方便的工具。当然,我在我自己的环境里安装了 Cygwin,但我不能要求其他同事仅仅为了使用这个命令而也装一个 Cygwin。而且,find 是用通配符去匹配文件名,我一直幻想着用正则表达式来匹配文件名/目录,所以我趁周末开发这个小工具。程序已经写好了,并发布到了 Google Code 上,主页是 http://code.google.com/p/listfile/ 。如下图: 正如下面版权里写的,你可以对这个程序/代码做任何你想做的事情:将这个工具用于你的工作中;拿源代码去交作业;向你的<(男|女)?朋友们?> 炫耀你开发/找到了一个好玩的东西…… 使用方法 lf [OPTIONS] PATTERN... 描述 lf 通过给定的模式来列出文件(或目录),类似 UNIX 系统下的 find (1) 命令,不过 find (1) 是用统配符来匹配文件名。比如:星号(*)代表零到多个字符;问号(?)代表单个任意字符。不过,用于匹配路径的话,正则表达式的功能更强大也更灵活。另一个好玩的特性是 lf 可以输出彩色信息,就像 UNIX 里 ls --color=auto 一样。 参数 -a, --all 显示所有文件(包括隐藏文件)。 -A, --absolute-path 输出的文件路径显示为绝对路径。 -e, --exec command 执行命令。可以通过<1> .. <n>来引用前面匹配的路径的每一项,而<0>则匹配完整路径。 此外,可以通过用逗号分隔范围中的第一个和最后一个数字指定一系列连续的文件名。因此<0>和<1,n>是等价的。 -h, --help 显示这个帮助文档,并退出。 -i, --ignore-case 匹配时忽略大小写。 -r, --relative-path 输出的文件路径显示为相对路径(相对于当前路径)。 模式 模式表达式同时支持通配符和正则表达式,其中正则表达式要放在尖括号里(“<”和“>”)。 环境变量 USERPROFILE

祝大家新春快乐

祝大家新春快乐 redraiment, 2010-02-13 昨天和前天我参加了小学、初中、高中同学会。自毕业以来,小学和初中同学还是第一次相聚,大家都很开心。我也是头一回喝这么多酒,晚上沿着S型曲线回家。 今早起来为自己泡了一杯蜂蜜解酒,并习惯性地打开Google Reader看看订阅的新闻。博客更新的也不少,同学们都发表日志畅谈新年感言。在这弱冠之年不免多愁善感,一些同学抱怨现在春节没有节日气氛、感叹对过年不再有小时候的期盼,还有同学说过年要被逼吃很多垃圾食品、说一些言不由衷的话…… 我觉得大家不必如此,节日对我们来说并不是一条法律规定的几月几号。只要快乐,任何一天都是我们的节日。同一天对于每个人来说都有不同的意义,大家都有自己的节日:比如生日、结婚纪念日等。以前对于小朋友来说,穿新衣服就是最快乐的事情,所以过年无疑是最有吸引力的;在谈成一笔大生意或考上重点大学时,我们也都会相邀庆祝;一些人过生日很讲究,但也有像Leonard(生活大爆炸)一样觉得自己从产道被排除并不是一向重大成就,因此不需要纪念…… 在忙碌一年后和家人团聚吃年夜饭,是大部分人都觉得开心的事情,所以春节自古就是大家共同的节日。如果哪天大家都觉得千里迢迢挤春运回来吃顿饭不快乐,那这一天也不再是全民庆祝了。同样的,随着年龄的增长、阅历变得丰富,我们不同时期追求亦不相同,小时候喜欢新衣服现在可能喜欢新房新车。有些同学感叹说变得现实、没有童真了,我倒是觉得这样也无可厚非,有些人只喜欢看鲜花绽放的瞬间(比如火影里的迪达拉),也有人喜欢恒久远永流传(像火影里的蝎),也有类似陶渊明的“园日涉以成趣”欣赏春来冬去、花开花谢的全过程…… 另一方面,每个人对如何庆祝节日的观点也不一样。有些人喜欢锣鼓喧天、鞭炮齐鸣、红旗招展、人山人海,也有一些朋友喜欢待在“蝉噪林愈静鸟鸣山更幽”的自在生活。前些时候好多朋友都和我说这个寒假时最后一个假期了,建议我出去旅游,我说这一年我东奔西跑,没多少时间待家里,如果我喜欢旅游还回家干嘛?对我来说,在家好好休息就是最好的庆祝方式。 我希望大家都能用自己喜欢的方式庆祝节日,但也要能包容其他人^_^。在此祝福大家新春快乐、身体健康、万事如意!

过滤分享的Chrome扩展开发详解

过滤分享的Chrome扩展开发详解 redraiment, 2010-02-08 明确需求   扩展的功能在前文《 眼不见为净——过滤人人网分享的chrome扩展 》中已做了介绍:把人人网中一些带有“不分享就如何如何”等诅咒信息的标题给屏蔽掉,眼不见为净!描述得更详细些就是: 过滤功能只在人人网域名(http://*.renren.com/*)下启用; 只有访问人人网时,扩展的图标才显示; 好友的分享信息会出现在很多地方(如好友主页、新鲜事、分享主页等),这些都要过滤; 我只是不想看到那些讨厌的标题,但分享的视频、图片等还是想看的。   其中(4)是核心功能,(2)可有可无。 Chrome扩展简介   Chrome扩展的主页是: http://code.google.com/chrome/extensions/index.html 。在此我只简单地介绍一下和本扩展相关的内容,更详细的信息请访问其主页。在本扩展中一共只有六个文件,其中三个是图片文件(用于图标),其他三个文件大小都不到1KB,所以无需“多事”把所谓的源码上传,直接把那几行代码贴到文章中即可。下面逐一介绍六个文件: 图标文件   图标文件有三个尺寸,都是由同一张图片修改而成。我没什么艺术细胞,原始图片的作者并不是我,只是觉得蛮符合这个扩展的主题,呵呵。如果您知道它的作者请给我留言,或者有志同道合的朋友帮忙贡献一张新图标,在此谢过! icon19.png :大小为19x19,用于地址栏中显示; icon48.png :大小为48x48,在Chrome的扩展管理页面(chrome://extensions)中显示; icon128.png :大小为128x128,安装此扩展时显示。   原始图片: manifest.json   这个Chrome扩展的配置文件,用JSON(JavaScript)来描述与扩展相关的信息,完整介绍请访问: http://code.google.com/chrome/extensions/manifest.html 。本扩展的配置信息如下: {   "name": "FRRS",   "version": "0.2.3",   "description": &q

眼不见为净——过滤人人网分享的chrome扩展

眼不见为净——过滤人人网分享的chrome扩展 redraiment, 2010-01-31 人人网的分享标题   进人人网(校内网)就免不了分享一些在线视频、音乐……有些同学进校内也纯粹是为了看分享,呵呵。分享原本是不错的东西,可以让新鲜事迅速传播。但最近有部分人,在分享链接时,在标题上赫然写着“看见不分享就倒霉一年”、“不分享的考试挂科”等诅咒信息,强奸我们的眼睛,唯恐天下不乱!   以前,在人人网中分享好友的“分享”时可以自己修改标题,所以我看到此类信息时都会手工去除恶意信息。但最近人人进行了升级,分享好友的“分享”时只能添加评论,不能修改标题。询问周围的同学,也有不少人对此类标题深恶痛绝! 我要过滤   本来这无可厚非,人家写这样的标题或许他/她们真觉得这个视频、音乐很不错,迫切地希望大家都能看/听到。但每个人的喜恶不同,这样的做法有点类似看电影时旁边一个同学向你絮絮叨叨后面的情景——好心办坏事。我还是希望每个人能比较客观地发表自己的意见,因此我不希望这些标题出现在我的首页上。   一开始,我还是打算像往常一样写个客户端程序,每次在进人人网之前先执行一下,把带此类标题的新鲜事标记为已读。但以我这样的马大哈还真不能保证每次记得执行;另外,我从人人网上下载的Java Client开发包,但找来找去也没找到个像样的文档。所以就放弃客户端的想法。   转念一想“如果浏览器本身提供这样的功能就好了”,再一想就想到开发浏览器的扩展/插件。我习惯用Chrome,最新版的也支持扩展开发了,而且在线文档也比较完整: http://code.google.com/chrome/extensions/index.html 。 Chrome扩展   我已经将扩展发布,如果你也有被相类似的问题困扰,并且也使用最新的 Chrome 浏览器,欢迎到项目主页 https://chrome.google.com/extensions/detail/kajehjgpeliapeaileldhcabdalkeflo 下载安装。   安装完后,当打开人人网时扩展就会启动,并在地址栏里显示图标:   在页面加载完后,扩展就会自动检查你的“新鲜事列表”,把所有带“不分享”的文字统统替换掉,下图是我和同学做的一个测试:   想关闭过滤功能,只要将它禁用即可。这个程序很小很简单,我会在下一篇文章中

Linux下用nc实现DuplexPipe

Linux下用nc实现DuplexPipe redraiment, 2010-01-25   nc 是一把网络的瑞士军刀,我以前在介绍 DuplexPipe 时也提到过,如果你没接触过它,可以先参看一下《 DuplexPipe二三事(二) 》。再来简单地介绍一下 DuplexPipe,顾名思义,它是一个“双向管道”。在 shell 中,我们通过“|”使用匿名管道,让前一条命令的输出作为后一条命令的输入;双向管道即在此基础上在加上“后一条命令的输入作为前一条命令的输入”。这是最初开发它的原因,但后来发现它更像是一个网络接口转换器,“DuplexPipe”这个名字反而不能体现它的功能。更多内容请参看 DuplexPipe系列文章 。 留言   今天网友 黄海 给我留言,他通过用 nc 的 -e 选项来执行 nc 本身来实现 DuplexPipe。留言原文如下: 哥们,你写的那个DuplexPipe, 我很欣赏。不过近日于网上逛发现此工具的功能竟然完全可以用netcat做到,有两种方法,我的博客上载了一种。简单描述如下: 在windows下: echo nc [ip] [port] > relay.bat nc -l -p [port2] -e relay.bat 其余的类推 第二种方法是用命名管道:(linux下) mknod backpipe p nc -l -p [port] 0<backpipe | nc [ip] [port12] | tee backpipe   其中选项 -e 的作用是: for NT:    -e prog        inbound program to exec [dangerous!!] for Linux: -e filename    program to exec after connect [dangerous!!] Windows下不行   在我开发 DuplexPipe 时确实考虑过功能会不会和 nc 重叠,当时只想着通过 shell 管道来连接,忘了 nc 自带了一个双向管道!我首先在 Vista 下做了测试,nc(win32) 是从 http://www.securityfocus.com/tools/139 下载。开启三个命令提示符,分别执行: 1) nc -l -p 1234 2)

用awk去除C语言注释

用awk去除C语言注释 redraiment, 2010-01-06   今天闲逛 Linux宝库 ,看到 论坛 里有人在讨论如何用 shell 脚本来处理 C 语言注释,发帖时间是 08-10-23(以前怎么都没注意到,失败...),但问题好像并没被解决。正好这两天玩 sed & awk,来小试一下身手。 C语句注释   本文讨论的是 C99 标准,它支持单行注释(“// ...”)和块注释(“/*...*/”),并且当单行注释以“\”结尾时也可以跨多行。测试代码如下: #include <stdlib.h> #include <stdio.h> int main (int argc, char *argv[]) { // not show\ not show\ not show // not show /* not show */     int is; // not show     int /* not show */ ms; /* not show */     double ds; // not show\     not show\     not show     double dm; /* ...     not show     not show */ float fs; /**                            * now show                            */     float /**/ fm;     char cs[] = "aaa // /***/";     char cm1[] = /* not show */ "hello*/";     char cm2[] = "/*redraiment" /* not show */ ;      /* printf("/////"); */     return EXIT_SUCCESS; }   其中绿色部分就是注释,经过处理后需要将它们全部移除或用替换成空字符。 论坛原帖 中没有处理以“\”结尾的单行注释,也没处理注释关键字出现在字符串中的情况。 工具的选择   sed 是一个流编辑器,它能对文件进行“插

awk学习笔记

awk学习笔记 redraiment, 2010-01-05 看完sed部分之后   花了几个晚上看完后面 awk 部分。awk 不同于 sed,它是一门模式匹配的程序设计语言。学习 sed 和 awk 时,正则表达式可能是一大障碍。但事有凑巧,去年我暑假我一个人出去散心时,顺带看完了《 精通正则表达式(第三版) 》,另外我还掌握一些 Bash、Perl 等脚步编程的经验,因此很快就能适应 awk 的风格。   写到此处,我突然联系到《倚天屠龙记》中的张无忌,他经常说“我有九阳神功护体,学什么武功都很快”;那我们程序员也可以牛气地喊“我掌握了正则表达式,UNIX下工具上手都很快”,哈哈。 环境的问题   比起 sed,使用 awk 时让我有点小意外,哈哈 。    一 、Debian 5.0 默认安装的 awk 是 mawk 。我一开始以为是 GNU awk,直到测试“gensub”函数(gawk特有)时才发现不对,于是通过 CD 盘安装了 GNU awk。 到目前为止,gawk 的最新版本是  3.1.7,但 Debian 5.0 的软件包中提供的是 v3.1.5 。而 fedora 默认安装的是 gawk v3.1.5,另外我在 Windows 下也使用 gawk.exe v3.1.5。    二 、在上文《 sed单行脚本学习笔记 》中已经提到用模式“[ -~]”来匹配任意可打印字符,这个特性在 mawk 中也可使用。理论上在 GNU gawk 中不能使用,但在 Windows 平台下的 gawk 却也具备此特性。为保持脚本的可移植性,应该用“[:print:]”来代替。    三 、gawk 支持扩展的正则表达式,在文档中指出操作符“\B”可以匹配单词中字符与字符之间的空白位置。例如模式“/\Bour/”可以匹配“course”,不能匹配“our”。但这一特性在 gawk v3.1.5 中实现有问题。 $ cat data  ABCDE ABCD ABC AB A $ awk --version | head -1 GNU Awk 3.1.5 $ awk '{gsub(/\B/,"-")}1' data  A-B-C-DE A-B-CD A-BC A-B A   如上所示,当单词长度大于二,在 gsub 中“\B”

sed单行脚本学习笔记

Sed单行脚本学习笔记 redraiment, 2009-12-31 回家真好   前段时间忙着找工作、项目结题、写报告……反正是总有做不完的事情,哈哈。好在暂时告一段落了,应老妈强烈要求回家休息几天。这次回家除了这身衣服,只带了一本《 sed与awk 》,我觉得这种小册子最适合茶余饭后休闲之用。如果你也有兴趣学 sed ,推荐你一起看《 sed与awk 》(可以在 谷歌图书 在线阅读英文版:D)。   花了两天时间,看完了前面 sed 的部分。要掌握一个工具就要熟悉它的规则,man 等参考手册向我们介绍这些规则,教程则演示如何使用这些规则,但要将这些规则运用自如,还需要去理解别人的代码并尝试自己解决问题。在 SourceForge 上有份经典的文档:《 SED单行脚本快速参考 》(单行脚本要求命令行长度小于65个字符),由 Eric Pement 整理, Joe Hong 翻译,通篇阅读后获益良多,故撰此文和大家分享。 精彩脚本摘录 # 在每一行后面增加一空行 sed G   在参考手册中,命令G的作用是“将换行符后的保持空间内容追加到模式空间”。就像前文提到的,看过教程后只是熟悉了规则,还不能将规则运用自如,我自己写的代码是:sed 's/$/\n/',就是因为我还不熟悉每个命令会对模式空间产生什么影响。所以看到这段参考代码时感觉眼前一亮:“原来还可以这样写!” # 显示文件中的最后10行 (模拟“tail”) sed -e :a -e '$q;N;11,$D;ba'   假设文件有 N 行(N 大于10),显示最后10行也就意味着删除前的 N-10 行。在多行模式中,命令“D”可以删除模式空间中第一行;命令“N”可以将下一行追加到模式空间中,建立多行模式。因此问题转化为:“1)将整个文件的内容放入一个模式空间中;2)删除前 N-10 行。”其中问题1)通过控制语句“b”来解决:sed ':a; N; ba';至于问题二,模式“1,$”代表文本中的所有行,因此紧跟着的命令被执行N次,同理,模式“11,$”匹配后面的 N-10 行,因此“11,$D”一个执行了 N-10 次。   其实,在 GNU sed 中,命令“$q”是可以删掉的,因为在最后一行执行命令“N”就会因出错而自动退出。   另外,在

戏说C语言变量

戏说C语言变量 redraiment, 2009-12-18 好玩的问题   今早帮老师去答疑,一位同学跑来问:“使用 printf 输出 %d、%c 时,后面传的参数都是变量的值,为什么 %s 看起来和它们不一样,要传一个地址?”我说:“小伙子很有前途,一般人不问这样的问题,哈哈!”   这个问题类似 Java 中基础类型传递值、对象传递引用,这么设计是为了提高效率。对于还没学完C语言的初学者来说,如果我给他扯一堆“底层设计”或“效率”等显然不合适,还极有可能掉进“值传递还是址传递”等文字游戏漩涡中,估计到了最后也只能在他听得晕头转向时搪塞一句“当初就是这么设计的”。为了尽快得给他满意的答复,我只要想办法让 %s “看起来”和其他标记一样就行了,于是写了如下的代码: #include <stdlib.h> #include <stdio.h> typedef char STRING[80]; int main ( void ) {     STRING s = "redraiment";     int i = 1;     printf("%s, %d\n", s, i);     return EXIT_SUCCESS; }   然后我告诉他:“因为C语言不够抽象,让你知道了太多的底层实现细节,比如你知道字符串在内存中是以字符数组的形式保存的。现在我用 typedef 定义了一个字符串类型,把这些细节屏蔽掉。通过 STRING s; 来定义一个名字是 s 的字符串类型变量,这样就和用 double d; int i; 等方式定义变量一样,你无需了解它们在内存中如何实现。此时,对于 printf 来说,%s、%d 后面跟着的 s, i 都是一回事了,它们都是变量的名字,里面保存着不同类型的数据。”很幸运,前面的话解决了他的疑惑,让我剩下不少口水:P。 指针和数组的定义是个BUG   我初学C语言时,也有过类似的困惑:指针和数组别样的定义方式让我以为它们有别于普通类型。所有普通类型、自定义的结构体类型的定义方式都是 TYPE name,数据类型后面紧跟着变量名。因此,就理论上来说,你定义一个指针 int* pi,其中表示指针类型的“*”应该从属于 int。但很遗憾,实际上它

好玩的数学——吉普赛读心术解密

好玩的数学——吉普赛读心术解密 redraiment, 2009-11-19 神奇的吉普赛读心术   闲着无聊窜寝室,看到一个同学在玩一个 flash 游戏:吉普赛读心术( http://gb.cri.cn/mmsource/flash/2006/04/10/er060410001.swf )。规则如下: 任意选择一个两位数(或者说,从10~99之间任意选择一个数),把这个数的十位与个位相加,再把任意选择的数减去这个和。例如:你选的数是23,然后2+3=5,然后23-5=18 在图表中找出与最后得出的数所相应的图形,并把这个图形牢记心中,然后点击水晶球。你会发现,水晶球所显示出来的图形就是你刚刚心里记下的那个图形。   咋看之下觉得很神奇,但仔细把玩两三回后你就会发现其中的奥秘: 右边的图标每次都会改变; 9、18、27、...、81 这9个图标永远是一样的。   假设你选择的两位数是 ab(即 ab=a×10+b),其中 1≤a≤9, 0≤b≤9 。按照规则计算就是 (a×10+b)-(a+b)=9×a,结果是 9 的倍数,∵ 1≤a≤9 ∴ 结果为 9、18、27、...、81 中的任意一个。又∵ 这9个图标是一样的,∴ 水晶球神奇地知道你记的图标。 手指计算器   无独有偶,记的小学数学课上老师教我们用手指计算任意两个5-10之间的数的积。   例如 6×8 ,一只手伸出 6-5=1 根指头,另一只手伸出 8-5=3 根指头。1+3=4,4 就是积的十位数;把两手弯曲的指头数相乘得 4×2=8,8 是积的个位数。则 6×8=48。   道理和上面相同:a×b=[(a-5)+(b-5)]×10+(10-a)×(10-b) 神秘的失踪   做这道题一定要的亲自动手才有滋味!否则就会像浮光掠影,印象不深。   将一个正方形分割成 7×7=49 的小方格,并按下图将它们分为“甲、乙、丙、丁、戊”五部分。   然后,甲块不动、乙块和丙块对调、戊块上移、丁块右移。得到新图如下:   经过这样重新组合拼成的新正方形,中间奇迹般地空出了一个洞!   实际上这只不过是一个小戏法,上面的新图形并不是真的正方形。 观察原始图可知 △ABC 和 △AED 是相似三角形 ∴ DE:CB=AD:AC=4:7 ∴ DE=8/7 ∴ EF=DE+DF=36/7 ∴ 上图

环境驱动编程

环境驱动编程——参加算法论坛后有感 redraiment, 2009-11-07 现场回顾   我很荣幸地作为特邀专家入京参加 CSDN 主办的 SD2.0 大会。大会以“移动+嵌入+云”为主题,举办了三天。白天有很多名家讲座,晚上还有5个主题沙龙,我参加的是算法论坛的沙龙。主持人是王尧(左轻侯),曾经先后工作于 Borland 中国公司和微软中国公司,现供职于 IBM 中国开发中心,从事 DB2 的研发工作。与会的还有五位嘉宾: 王炜:北京南天软件有限公司总架构师; 宋兴烈:起步软件公司总工程师; 云风:网易公司技术研发经理; 贾自艳:腾讯搜索技术研发中心研究员; 顾森:北大在校学生( http://www.matrix67.com/ )。   论坛围绕“在新一轮技术浪潮中,算法又重新站到了重要位置”这一话题展开讨论。本来有几个问题想和各位嘉宾讨论,但由于时间不足,加上我住处较远,只好忍痛在 21:20 出去赶班车,到家已经 23:40 了。不过收获还是不少,我结合大会上其他专家的一些观点,将其整理出来和大家分享。 算法重获重视   IT 行业经历了大型机时代、PC 时代、互联网时代,以及即将到来的移动终端+云计算时代。早期由于硬件的先天不足,需要靠软件后天来补;随着硬件的高速发展,一个普通的算法在十八个月以后性能就可以提升一倍,而且大部分经过高度优化的算法都被打包成类库,需要可以方便地调用;但随着互联网时代的到来,用户能够主动参与建设互联网,算法要处理的不再是几台 PC 中存储的数据,而是整个互联网中的信息。   引用李德毅院士的话:“ 集中统一的调度,顺序的、确定的输入,不能描述互联网的工作机理和交互机理,互联网突破了图灵机的描述范畴。 ”李院士将云计算定义为传统的“图灵计算”结合“大众计算”,“大众计算”意味着至少能处理这浩如烟海的互联网信息,因此算法也必须与时俱进。 环境驱动编程   在讨论中,王玮一直强调要灵活地运用算法,这个我以前提的“ 工具理论 ”不谋而合。他现场举了个例子:字符串匹配算法中,Rabin-Karp 算法理论上并非最优的,但在实际运用地比较好。这是由于硬盘的I/O效率远低于内存等高速存储器,并非理想的高效随机存储器。其他匹配算法都需要反复读取前面的数据,而 RK 算法只需按顺序从前往后以此处理,在处理大数据时避免了大量

用C语言写解释器(五)

用C语言写解释器(五)——其他一些东西 redraiment, 2009-11-05 写完解释器之后   这一篇文章我只想和大家侃侃编程语言的事情,不会被放到书中。因此可以天南地北地扯淡,不用像前几篇一样畏首畏尾的了。   经过前面几篇文章的讨论,已经把用纯 C 语言来实现一个解释器的方法介绍完了。但那些是写给我校 C 语言初学者看的,并不只是你,我得也觉得很不过瘾 ^_^。因此准备继续深入学习编译原理等课程,希望有志同道合的朋友和我一起交流! 富饶的语言(工具)   在前几篇文章中一直在鼓吹我拍脑袋想出的语言四大要素:“内存管理”、“表达式求值”、“输入/输出”、“按条件跳转”,在这篇文章中您就姑且信一回当它是真的。按照这四条准则去匹配,汇编语言是完全符合的。那为什么又需要 C 语言、Java、C# 等高级语言?这是因为编程除了需要“语言”之外还需要“抽象”!   “抽象”是个很有效的工具,相信你在为别人介绍自己房间时不会具体到每个木纤维、油漆分子和铁原子。同样的,我们也不乐意总是写一堆 JNZ、JMP 指令,而仅仅是为了实现 if、for、while 等控制结构。C 语言等高级语言提供的抽象的层次更高、表现力更强,允许用更少的语句描述更多的操作。感谢如此富饶的语言为我们带来不同的视角去审视这个世界。   高级语言相较于低级语言属于更高地抽象层次,高级语言之间的差别主要体现在适用范围上。比如一些语言适合写 WEB 程序,另一些适合做数值分析等。术业有专攻,你只需根据自己的问题来选择一门合适的语言。 什么时候需要创造新的语言   当我们碰到一类新的问题时,首先考虑的就是定义新的数据结构,并设计多个函数去操作它,最后将它们独立出来打包成一个类库方便在其他地方调用(比如处理图形图像的 OpenGL 库)。上面已经提过,每种语言都有它适合的领域,强行将一门语言用在它不擅长的领域中就出现冗长、繁琐的代码。自然语言也是如此:英语中有种语法叫虚拟语气,描述的是一种假设,并非事实。比如“If I have time, I will go to see you. ”。如果按原意一字不差地翻译相信会很繁琐,我知道台湾作家痞子蔡在使用中文式的虚拟语气很有一套: 如果我还能活一天, 我就要做你的爱侣。 我能活一天吗?可惜。 所以我不是你的爱侣。  ——《第一次亲密接触》   上面

用C语言写解释器(四)

用C语言写解释器(四)——语句分析 redraiment, 2009-11-02 语句   在前面的章节中已经成功实现了内存管理和表达式求值模块。之所以称表达式求值是解释器的核心部分,是因为几乎所有语句的操作都伴随着表达式求值。也许你已经迫不及待地给 eval 传值让它执行复杂的运输了,但目前来讲它充其量只是一个计算器。要想成为一门语言,还需要一套自成体系的语法,包括输入输出语句和控制语句。但在进行语法分析之前,首先需要将 BASIC 源码载入到内存中。 BASIC 源码载入   在《用C语言写解释器(一)》中附了一段 BASIC 参考代码,每一行的结构是一个行号+一条语句。其中行号为 1-9999 之间的正整数,且当前行号大于前面的行号;语句则由以下即将介绍的 3 条 I/O 语句和 8 条控制语句组成。为方便编码,程序中采用静态数组来保存源代码,读者可以尝试用链表结构实现动态申请的版本。下面是代码结构的定义。 // in basic_io.h #define PROGRAM_SIZE (10000) typedef struct {     int ln;     // line number     STRING line; } CODE; extern CODE code[PROGRAM_SIZE]; extern int cp; extern int code_size;   其中 code_size 的作用顾名思义:记录代码的行数。cp (0 ≤ cp < code_size)记录当前行的下标(比如 cp 等于5时表明执行到第5行)。下面是载入 BASIC 源码的参考代码,在载入源码的同时会去除两端的空白字符。 // in basic_io.c void load_program ( STRING filename ) {     FILE *fp = fopen ( filename, "r" );     int bg, ed;     if ( fp == NULL ) {         fprintf ( stderr, "文件 %s 无法打开!\n", filename );         exit ( EXIT_FAILURE );     }     while ( fscanf (