Archive for the ‘programming’ Category

读书 - 2 - False Consensus Bias

Tuesday, March 2nd, 2010

我们都不自觉的认为他人和自己的想法是一样的,但其实不是。心理学家称其为”False Consensus Bias”,译为“虚假同感偏差”。当别人的想法或行为和自己不一样时,我们很容易(下意识地)认为别人多少有点脑子进水。

由于此种偏见的存在,程序员很难设身处地于用户之境地。甚至软件工程中有句信条就是:用户永远是愚蠢的。要解决该偏见并非易事,当年Fred Brooks就在《人月神话》中写下诸多笔墨。有部电影叫《巴别塔》,深刻描述了误解带来的灾难性后果。程序员关注的是解决问题的策略,而用户则对此丝毫没有兴趣 - 他们只关心用户界面。所以与其拍脑袋想象用户的行为,而不如直接观察之,或者单刀直入 - 询问用户。并且记住:

  1. 千万不要打断他们;
  2. 用户所说的或许压根儿就不是心里真正所想的。

有时,大量的帮助文档体现的并非是软件设计得多么完备,而是恰恰表明它有多么难于使用。如果非要不可,请合理安排帮助的位置,或者使用Tool Tips.

随机密码生成器

Wednesday, January 6th, 2010

花了一天时间用Bash写了个生成随机密码的脚本。生成的密码符合以下条件:

  1. 长度为8~20个字符;
  2. 包含至少一个大写字母;
  3. 包含至少一个小写字母;
  4. 包含至少一个数字;
  5. 包含至少一个特殊字符。

总的来说,我还是比较喜欢这个脚本的,够简单也够简洁。

PW_LEN=$((8 + (RANDOM % 12)))
DIGITS='0 1 2 3 4 5 6 7 8 9'
LCHARS='a b c d e f g h i j k l m n o p q r s t u v w x y z'
UCHARS='A B C D E F G H I J K L M N O P Q R S T U V W X Y Z'
SCHARS='! @ # $ % ^ & ` ( ) { } [ ] ; : " , . < > ? / \ | ~'

DISPTB=(DIGITS LCHARS UCHARS SCHARS)
DISPTB_LEN=${#DISPTB[*]}

# randomly select one character from randomly selected char table
function random_select()
{
    local table=${DISPTB[$((RANDOM % DISPTB_LEN))]}
    local n_ele=
    local clist=

    eval clist=(\$$table)   # clist contains char table
    n_ele=${#clist[*]}      # length of array `clist'

    echo -n ${clist[$((RANDOM % n_ele))]}
}

function pwgen()
{
    local passwd=

    for ((cnt=0; cnt<PW_LEN; cnt++)); do
        passwd=$passwd random_select
    done

    echo $passwd
}

# check whether given password conforms to policy
function is_valid()
{
    local pw_len=$(expr length "$1")
    local nr_lower=$(echo "$1" | fold -w1 | grep -c '[[:lower:]]')
    local nr_upper=$(echo "$1" | fold -w1 | grep -c '[[:upper:]]')
    local nr_digit=$(echo "$1" | fold -w1 | grep -c '[[:digit:]]')
    local nr_schar=$((pw_len - nr_lower - nr_upper - nr_digit))

    [ $nr_lower -eq 0 -o $nr_upper -eq 0 -o \
      $nr_digit -eq 0 -o $nr_schar -eq 0 ] && return 1

    return 0
}

while true; do
    pw=$(pwgen); if is_valid "$pw"; then
      echo "$pw"; exit 0
    fi
done

Java Now!

Tuesday, December 22nd, 2009

最近一个月的任务是为我们的API提供一套Java接口。因为“时间紧、任务急”,于是任务稍微轻松一点的我就被拉了壮丁。善哉!我不入地狱,谁入地狱!除了04年大学毕业时的暑假自己抱了本Java书啃了几百页,此后几乎再未接触过。我并不是个OOP的推崇者,我甚至强烈怀疑OOP有易于将简单事情复杂化的倾向。

随大流嘛,我顺便也用上了Eclipse,比起纯粹用裸vim/emacs确实方便不少,有些功能颇有点惊艳的感觉。就纯粹易用性和实用性来说,我目前最喜欢的语言应该是:C和Ruby;如果从语言洁癖上来谈,我喜欢Haskell和Scheme。

程序随笔 - 7

Friday, November 20th, 2009

前些日子兴致起来,学了点OCaml,因为不太习惯Haskell的那么pure,或者是太习惯了“printf大法”。OCaml除了impure之外,和Haskell非常相像 — 可能这也是很多从命令式编程(imperative programming)转到FP的时候,更喜欢OCaml而非Haskell的原因吧。

很巧的是,前几天为一些同事做了关于Linux File I/O programming的培训。我一直在想,如果时间充裕的话(虚拟语气)我应该会聊一些关于 side-effect 之类的东西。讲File I/O的时候我讲了一些关于pipe的东西,而学 Haskell Monad 的时候,我脑子里蹦出来的是两个东西:pipe和Scheme中的continuation。

这几天我断断续续的在想,一个理想中的程序[1]是不是本来就不应该如此直接[2]。突然意识到,像Haskell那样小心翼翼的把pure和impure分隔开简直是个绝妙的想法!硬件设计者或许会在心里痛斥软件设计者的不思进取,因为系统性能的提高很多时候是靠硬件的进步而非软件 — 软件越来越臃肿,即使是硬件的并发性能提高到令人惊讶的程度,而软件的发展却始终是原地踏步。MSDN Channel 9上Brain Beckman博士有一个长达一个多小时的视频:Don’t fear the Monad,深入浅出,相当精彩。无需任何FP背景,只要稍微了解一点编程就能心领神会。

[1] 我也无法描述心中的理想的程序,不过至少应该是简洁、易扩展、高并发吧;

[2] 就像C中可以到处插入printf,添加全局变量等等。

似已登堂,尚未入室

Saturday, November 7th, 2009

曾经立志成为Linux内核高手,并为此努力研究了几年,后来无论是实习、还是现在的第一份工作都与此有所背离,于是就希望在compiler方面有所建树 — 想要成为一个有功力、有底气的非内核程序员,这个应该是一个有意义的方向。于是就先读了SICP(当然其中还有老大的影响),学了Scheme — 记得当时在某个邮件列表上看见说Scheme很适合用来模拟别的语言。读SICP还是相当令人愉悦的,从中学到了很多有益的思想并有了一点函数式编程思维。

SICP中有一章是用Scheme写个Scheme解释器,比较好玩。后来看见网上有份详细的教程,用Haskell写个Scheme解释器 — 因此顺便学了点Haskell,中间因为工作需要,学了Ruby。Ruby很适合用来实现DSL,而Scheme(包括其他Lisp方言)的macro系统也及其牛b。Haskell的ADT比较酷,加上Parsec,还有酷酷的pattern matching,使得它写parser相当轻松。

嗯,我要把Haskell学学好。:-)