程序员疫苗:代码注入

程序员疫苗:代码注入

几个月在我的微博上说过要建一个程序员疫苗网站,希望大家一起来提交一些错误示例的代码,来帮助我们新入行的程序员,不要让我们的程序员一代又一代的再重复地犯一些错误。很多程序上错误就像人类世界的病毒一样,我们应该给我们的新入行的程序员注射一些疫苗,就像给新生儿打疫苗一样,希望程序员从入行时就对这些错误有抵抗力。

我的那个疫苗网站正在建议中(不好意思拖了很久),不过,我可以先写一些关于程序员疫苗性质的文章,也算是热热身。希望大家喜欢,先向大家介绍第一注疫苗——代码注入。

Shell注入

我们先来看一段perl的代码:

[perl]use CGI qw(:standard);
$name = param(‘name’);
$nslookup = "/path/to/nslookup";
print header;
if (open($fh, "$nslookup $name|")) {
  while (<$fh>) {
print escapeHTML($_);
print "<br>\n";
}
close($fh);
}[/perl]

如果用户输入的参数是:

sou-ip.com%20%3B%20/bin/ls%20-l

那么,这段perl的程序就成了:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (41 人打了分,平均分: 4.07 )
Loading...
你可能不知道的Shell

你可能不知道的Shell

Shell也叫做命令行界面,它是*nix操作系统下用户和计算机的交互界面。Shell这个词是指操作系统中提供访问内核服务的程序。

这篇文章向大家介绍Shell一些非广为人知、但却实用有趣的知识,权当品尝shell主食后的甜点吧。

科普

先科普几个你可能不知道的事实:

  • Shell几乎是和Unix操作系统一起诞生,第一个Unix Shell是肯·汤普逊(Ken Thompson)以Multics上的Shell为模范在1971年改写而成,并命名Thompson sh。即便是后来流行的bash(shell的一种变体),它的年龄实际上比当前流行的所有的Linux kernel都大,可谓在Linux系统上是先有Shell再有Kernel。
  • 当前绝大部分*nix和MacOS操作系统里的默认的Shell都是bash,bash由Brian Fox在1987年创造,全称Bourne Again shell ( bash)。
  • 你或许听说除了bash之外,还有Bourne shell ( sh),Korn shell ( ksh),C shell (包括 csh and tcsh),但是你知道这个星球上一共存在着大约50多种不同的shell么?想了解他们,请参考 http://www.freebsd.org/ports/shells.html
  • 每个月tiobe上都会给一个编程语言的排名,来显示各种语言的流行度。排名指数综合了全球范围内使用该语言的工程师人数、教学的课程数和第三方供应商数。截止至2012年11月份,tiobe公布的编程语言排行榜里,bash的指数是0.56%排名22位。如果算上它旗下的awk 0.21%和tcl 0.146%,大概就能排到14名。注意这里还不包括bash的同源的兄弟姐妹csh、ksh等,算上它们,shell家族有望接近前十。值得一提的是一直以来shell的排名就很稳定,不像某些“暴发户”语言,比如objective-c,这些语言的流行完全是因为当前Apple系的崛起,但这种热潮极有可能来得快去得更快。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (34 人打了分,平均分: 4.38 )
Loading...
如何测试洗牌程序

如何测试洗牌程序

我希望本文有助于你了解测试软件是一件很重要也是一件不简单的事。

我们有一个程序,叫ShuffleArray(),是用来洗牌的,我见过N多千变万化的ShuffleArray(),但是似乎从来没人去想过怎么去测试这个算法。所以,我在面试中我经常会问应聘者如何测试ShuffleArray(),没想到这个问题居然难倒了很多有多年编程经验的人。对于这类的问题,其实,测试程序可能比算法更难写,代码更多。而这个问题正好可以加强一下我在《我们需要专职的QA吗?》中我所推崇的——开发人员更适合做测试的观点。

我们先来看几个算法(第一个用递归二分随机抽牌,第二个比较偷机取巧,第三个比较通俗易懂

递归二分随机抽牌

有一次是有一个朋友做了一个网页版的扑克游戏,他用到的算法就是想模拟平时我们玩牌时用手洗牌的方式,是用递归+二分法,我说这个程序恐怕不对吧。他觉得挺对的,说测试了没有问题。他的程序大致如下(原来的是用Javascript写的,我在这里凭记忆用C复现一下):

//递归二分方法
const size_t MAXLEN = 10;
const char TestArr[MAXLEN] = {'A','B','C','D','E','F','G','H','I','J'};

static char RecurArr[MAXLEN]={0};
static int cnt = 0;
void ShuffleArray_Recursive_Tmp(char* arr, int len)
{
    if(cnt > MAXLEN || len <=0){
        return;
    }

    int pos = rand() % len;
    RecurArr[cnt++] = arr[pos];
    if (len==1) return;
    ShuffleArray_Recursive_Tmp(arr, pos);
    ShuffleArray_Recursive_Tmp(arr+pos+1, len-pos-1);
}

void ShuffleArray_Recursive(char* arr, int len)
{
    memset(RecurArr, 0, sizeof(RecurArr));
    cnt=0;
    ShuffleArray_Recursive_Tmp(arr, len);
    memcpy(arr, RecurArr, len);
}

void main()
{
    char temp[MAXLEN]={0};
    for(int i=0; i<5; i++) {
        strncpy(temp, TestArr, MAXLEN);
        ShuffleArray_Recursive((char*)temp, MAXLEN);
    }
}

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (31 人打了分,平均分: 4.00 )
Loading...
Go 语言简介(下)— 特性

Go 语言简介(下)— 特性

希望你看到这篇文章的时候还是在公交车和地铁上正在上下班的时间,我希望我的这篇文章可以让你利用这段时间了解一门语言。当然,希望你不会因为看我的文章而错过站。呵呵。

如果你还不了解Go语言的语法,还请你移步先看一下上篇——《Go语言简介(上):语法

goroutine

GoRoutine主要是使用go关键字来调用函数,你还可以使用匿名函数,如下所示:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (35 人打了分,平均分: 4.23 )
Loading...
Go 语言简介(上)— 语法

Go 语言简介(上)— 语法

周末天气不好,只能宅在家里,于是就顺便看了一下Go语言,觉得比较有意思,所以写篇文章介绍一下。我想写一篇你可以在乘坐地铁或公交车上下班时就可以初步了解一门语言的文章。所以,下面的文章主要是以代码和注释为主。只需要你对C语言,Unix,Python有一点基础,我相信你会在30分钟左右读完并对Go语言有一些初步了解的。

Hello World

//文件名:hello.go
package main //声明本文件的package名

import "fmt" //import语言的fmt库——用于输出

func main() {
    fmt.Println("hello world")
}

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (41 人打了分,平均分: 4.37 )
Loading...
TF-IDF模型的概率解释

TF-IDF模型的概率解释

(感谢 @猫叔shiro(以前的todd) 投递此文)

信息检索概述

信息检索是当前应用十分广泛的一种技术,论文检索、搜索引擎都属于信息检索的范畴。通常,人们把信息检索问题抽象为:在文档集合D上,对于由关键词w[1] … w[k]组成的查询串q,返回一个按查询q和文档d匹配度relevance(q, d)排序的相关文档列表D’。

对于这一问题,先后出现了布尔模型、向量模型等各种经典的信息检索模型,它们从不同的角度提出了自己的一套解决方案。布尔模型以集合的布尔运算为基础,查询效率高,但模型过于简单,无法有效地对不同文档进行排序,查询效果不佳。向量模型把文档和查询串都视为词所构成的多维向量,而文档与查询的相关性即对应于向量间的夹角。不过,由于通常词的数量巨大,向量维度非常高,而大量的维度都是0,计算向量夹角的效果并不好。另外,庞大的计算量也使得向量模型几乎不具有在互联网搜索引擎这样海量数据集上实施的可行性。

tf-idf模型

目前,真正在搜索引擎等实际应用中广泛使用的是tf-idf模型。tf-idf模型的主要思想是:如果词w在一篇文档d中出现的频率高,并且在其他文档中很少出现,则认为词w具有很好的区分能力,适合用来把文章d和其他文章区分开来。该模型主要包含了两个因素:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (23 人打了分,平均分: 3.65 )
Loading...
xkcd 神图“Click and Drag”

xkcd 神图“Click and Drag”

xkcd对于经常浏览国外网站的朋友一定不会陌生。不过,还是先让我来介绍一下xkcd(维基百科词条)。这是一个漫画网站,它主要是发布一些很简单的随手画的漫画,它主要有四种体裁——浪漫、讽刺、数学 和 语言。也会经常出现一些和IT有关的漫画,比如下面这个漫画—— (懂Unix的人一眼就看懂了,不懂的怎么看也看不懂)

本质上来说,xkcd是一种Geek文化,里面的东西都非常的Geek和晦涩,讽刺很辛辣,但很多只有特定人群可以看得懂。而且表达的形式自由到天马行空,飘忽不定。

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (44 人打了分,平均分: 4.23 )
Loading...
Bret Victor – Learnable Programming

Bret Victor – Learnable Programming

大家是否还记得之前宝酷向大家介绍的苹果设计师Bret Victor一种可视编程的视频《Bret Victor – Inventing on Principle》,最近,他写了一篇文章—— Learnable Programming,写这篇文章的原因是因为“可汗学院(Khan Academy)”近期上线的一个在线编程环境,根据他的演讲提供了一堆基于Javascript的“实时编程”的环境,因为这个环境是引用了他的想法,所以,他有必要出来喷两句。

这篇文章的开头就是一个问题——“How do we get people to understand programming?”,我们怎么让人们懂得编程?

然后,他说了两条——

  • 编程是一种思考,而不是一种死记硬背的技能!你学会了“for循环”并不是说你就学会了编程,这就好像你知道有铅笔这个东西,但是你对绘画还是什么不懂。(对于这一条,正好这两天我在微博上和人辩论“基础算法面试题是否好”(还有微博一微博二),而且我以前也写过一篇《为什么我反对纯算法面试》,这里借用Bret的话再加强一下我的观点——“我们一方面在骂中国的应试教育毁了学生,另一方面我们又在把我们的面试变成“考八股文”式的考试!  你会qsort有什么用?你只不过是会用一支高级铅笔而已罢了。”)
  • 人只有看得见,才能理解。如果一个程序员不能看到他的程序在干什么,那么她就不能理解程序。(对于这一条,让我想到了Donald Knuth的话——“An algorithm must be seen to be believe!”)

所以,Bret 觉得编程软件的目标是——

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (24 人打了分,平均分: 3.92 )
Loading...
C/C++语言中闭包的探究及比较

C/C++语言中闭包的探究及比较

感谢投稿人 @思禽饮霜 

这里主要讨论的是C语言的扩展特性block。该特性是Apple为C、C++、Objective-C增加的扩展,让这些语言可以用类Lambda表达式的语法来创建闭包。前段时间,在对CoreData存取进行封装时(让开发人员可以更简洁快速地写相关代码),我对block机制有了进一步了解,觉得可以和C++ 11中的Lambda表达式相互印证,所以最近重新做了下整理,分享给大家。

0. 简单创建匿名函数

下面两段代码的作用都是创建匿名函数并调用,输出Hello, World语句。分别使用Objective-C和C++ 11:

^{ printf("Hello, World!\n"); } ();
[] { cout << "Hello, World" << endl; } ();

Lambda表达式的一个好处就是让开发人员可以在需要的时候临时创建函数,便捷。

在创建闭包(或者说Lambda函数)的语法上,Objective-C采用的是上尖号^,而C++ 11采用的是配对的方括号[]

不过“匿名函数”一词是针对程序员而言的,编译器还是采取了一定的命名规则。

比如下面Objective-C代码中的3个block,

#import <Foundation/Foundation.h>

int (^maxBlk)(int , int) = ^(int m, int n){ return m > n ? m : n; };

int main(int argc, const char * argv[])
{
    ^{ printf("Hello, World!\n"); } ();

    int i = 1024;
    void (^blk)(void) = ^{ printf("%d\n", i); };
    blk();

    return 0;
}

会产生对应的3个函数:

阅读全文 Read More

好烂啊有点差凑合看看还不错很精彩 (19 人打了分,平均分: 3.89 )
Loading...
对九个超级程序员的采访

对九个超级程序员的采访

原文:《Q&A With Nine Great Programmers》时间有限,我只能粗译,难免错误。

这篇访谈源自2006年,最先发布在波兰程序员 Jaroslaw “sztywny” Rzeszótko (AKA “Stiff”) 的博客上。但是这篇博文现在找不到了。非常感谢他能授权我重新发布这个博文。

在一个炎热无聊的下午,我突发奇想。我想通过电子邮件的方式对那些我非常感兴趣和非常敬重的程序员问10个问题。准备这10个问题我只花了5分钟,这些都是我个人想问他们的问题,所以,我基本上没想太多要问他们什么。最后两个问题和编程没有什么关系,我就是想问题这些人的一些兴趣爱好。另外,不是每一个人都想回答我的,这是我第一次做“访谈”,所以,我犯了一些错误,一些问题没有得到回答。不管怎么样,我得到了很多很有意思的内容,所以,这对我绝对是一次很有意义的经历。

并不是每一个人都回了我的邮件,也并不是每一个人都同意回答我的这些问题,也许在我发布这篇文章后我会得到那些回答,但是我已经迫不及待想把这些东西发布了,所以,我可能会更新这篇文章(更新:2006年3月8日,我收到了Bjarne Stroustrup的回信

— Jaroslaw

介绍

  • Dave Thomas – “Pragmatic Programmer”(注:douban) 和 “Programming Ruby”(注:douban) 以及其它一些优秀书籍的作者。 你可以在 这里 读读他对编程的一些想法。
  • Steve Yegge – 他可能并不那么知名,但是他给了很多有意思的回答。他有一个很火的关于编程的 blog,他也是游戏 “Wyvern” 的作者。(宝酷注:他最火的是去年在google+上对google和amazon的吐槽,06年他应该在google了)
好烂啊有点差凑合看看还不错很精彩 (29 人打了分,平均分: 3.97 )
Loading...