【置顶】交换链接

星空夜话 发表于 2013-07-22 15:54:47

Blog好久不更新,今天删除了一些失效的友情链接,有朋友需要交换链接请回复本文,我会把您的链接添加到页面上。

[zz] Declaration of C: Right-Left-Rule

星空夜话 发表于 2011-01-21 14:17:56

[ From: http://ieng9.ucsd.edu/~cs30x/rt_lt.rule.html ]

The "right-left" rule is a completely regular rule for deciphering C
declarations.  It can also be useful in creating them.
First, symbols.  Read
     *		as "pointer to"			- always on the left side
     [] 	as "array of"			- always on the right side
     ()		as "function returning"		- always on the right side
as you encounter them in the declaration.
STEP 1
------
Find the identifier.  This is your starting point.  Then say to yourself,
"identifier is."  You've started your declaration.
STEP 2
------
Look at the symbols on the right of the identifier.  If, say, you find "()"
there, then you know that this is the declaration for a function.  So you
would then have "identifier is function returning".  Or if you found a 
"[]" there, you would say "identifier is array of".  Continue right until
you run out of symbols *OR* hit a *right* parenthesis ")".  (If you hit a 
left parenthesis, that's the beginning of a () symbol, even if there
is stuff in between the parentheses.  More on that below.)
STEP 3
------
Look at the symbols to the left of the identifier.  If it is not one of our
symbols above (say, something like "int"), just say it.  Otherwise, translate
it into English using that table above.  Keep going left until you run out of
symbols *OR* hit a *left* parenthesis "(".  
Now repeat steps 2 and 3 until you've formed your declaration.  Here are some
examples:
     int *p[];
1) Find identifier.          int *p[];
                                  ^
   "p is"
2) Move right until out of symbols or left parenthesis hit.
                             int *p[];
                                   ^^
   "p is array of"
3) Can't move right anymore (out of symbols), so move left and find:
                             int *p[];
                                 ^
   "p is array of pointer to"
4) Keep going left and find:
                             int *p[];
                             ^^^
   "p is array of pointer to int". 
   (or "p is an array where each element is of type pointer to int")
Another example:
   int *(*func())();
1) Find the identifier.      int *(*func())();
                                    ^^^^
   "func is"
2) Move right.               int *(*func())();
                                        ^^
   "func is function returning"
3) Can't move right anymore because of the right parenthesis, so move left.
                             int *(*func())();
                                   ^
   "func is function returning pointer to"
4) Can't move left anymore because of the left parenthesis, so keep going
   right.                    int *(*func())();
                                           ^^
   "func is function returning pointer to function returning"
5) Can't move right anymore because we're out of symbols, so go left.
                             int *(*func())();
                                 ^
   "func is function returning pointer to function returning pointer to"
6) And finally, keep going left, because there's nothing left on the right.
                             int *(*func())();
                             ^^^
   "func is function returning pointer to function returning pointer to int".
As you can see, this rule can be quite useful.  You can also use it to
sanity check yourself while you are creating declarations, and to give
you a hint about where to put the next symbol and whether parentheses
are required.
Some declarations look much more complicated than they are due to array
sizes and argument lists in prototype form.  If you see "[3]", that's
read as "array (size 3) of...".  If you see "(char *,int)" that's read
as "function expecting (char *,int) and returning...".  Here's a fun
one:
                 int (*(*fun_one)(char *,double))[9][20];
I won't go through each of the steps to decipher this one.
Ok.  It's:
     "fun_one is pointer to function expecting (char *,double) and 
      returning pointer to array (size 9) of array (size 20) of int."
As you can see, it's not as complicated if you get rid of the array sizes
and argument lists:
     int (*(*fun_one)())[][];
You can decipher it that way, and then put in the array sizes and argument
lists later.
Some final words:
It is quite possible to make illegal declarations using this rule,
so some knowledge of what's legal in C is necessary.  For instance,
if the above had been:
     int *((*fun_one)())[][];
it would have been "fun_one is pointer to function returning array of array of
                                          ^^^^^^^^^^^^^^^^^^^^^^^^
pointer to int".  Since a function cannot return an array, but only a 
pointer to an array, that declaration is illegal.
Illegal combinations include:
	 []() - cannot have an array of functions
	 ()() - cannot have a function that returns a function
	 ()[] - cannot have a function that returns an array
In all the above cases, you would need a set of parens to bind a *
symbol on the left between these () and [] right-side symbols in order
for the declaration to be legal.
Here are some legal and illegal examples:
int i;                  an int
int *p;                 an int pointer (ptr to an int)
int a[];                an array of ints
int f();                a function returning an int
int **pp;               a pointer to an int pointer (ptr to a ptr to an int)
int (*pa)[];            a pointer to an array of ints
int (*pf)();            a pointer to a function returning an int
int *ap[];              an array of int pointers (array of ptrs to ints)
int aa[][];             an array of arrays of ints
int af[]();             an array of functions returning an int (ILLEGAL)
int *fp();              a function returning an int pointer
int fa()[];             a function returning an array of ints (ILLEGAL)
int ff()();             a function returning a function returning an int
                                (ILLEGAL)
int ***ppp;             a pointer to a pointer to an int pointer
int (**ppa)[];          a pointer to a pointer to an array of ints
int (**ppf)();          a pointer to a pointer to a function returning an int
int *(*pap)[];          a pointer to an array of int pointers
int (*paa)[][];         a pointer to an array of arrays of ints
int (*paf)[]();         a pointer to a an array of functions returning an int
                                (ILLEGAL)
int *(*pfp)();          a pointer to a function returning an int pointer
int (*pfa)()[];         a pointer to a function returning an array of ints
                                (ILLEGAL)
int (*pff)()();         a pointer to a function returning a function
                                returning an int (ILLEGAL)
int **app[];            an array of pointers to int pointers
int (*apa[])[];         an array of pointers to arrays of ints
int (*apf[])();         an array of pointers to functions returning an int
int *aap[][];           an array of arrays of int pointers
int aaa[][][];          an array of arrays of arrays of ints
int aaf[][]();          an array of arrays of functions returning an int
                                (ILLEGAL)
int *afp[]();           an array of functions returning int pointers (ILLEGAL)
int afa[]()[];          an array of functions returning an array of ints
                                (ILLEGAL)
int aff[]()();          an array of functions returning functions
                                returning an int (ILLEGAL)
int **fpp();            a function returning a pointer to an int pointer
int (*fpa())[];         a function returning a pointer to an array of ints
int (*fpf())();         a function returning a pointer to a function
                                returning an int
int *fap()[];           a function returning an array of int pointers (ILLEGAL)
int faa()[][];          a function returning an array of arrays of ints
                                (ILLEGAL)
int faf()[]();          a function returning an array of functions
                                returning an int (ILLEGAL)
int *ffp()();           a function returning a function
                                returning an int pointer (ILLEGAL)
关键词(Tag): c programming language

百度电子商务事业部诚招2011年优秀毕业生

星空夜话 发表于 2010-09-21 23:38:42

目前招聘的三个技术职位有:

电子商务事业部_电子商务研发工程师(2011校园招聘)
电子商务事业部
_测试工程师(2011校园招聘)
电子商务事业部
_前端开发工程师(2011校园招聘)

有需要内部推荐的同学,请联系我~
发站内信或者将你的简历发到
wantao[at]baidu.com

从要求来看,研发职位的要求大于另外两个职位,如果你觉得够优秀或者有信心变得优秀,那就来试试吧~~

温馨提示:公司对应届生应聘时主要看学生的基础知识是否扎实,比如程序设计能力、算法与数据结构、操作系统、网络、数据库,其中有1-2个方面有突出更好。

招聘职位信息就不全贴出来了(仅附上链接)

电子商务事业部_电子商务研发工程师(2011校园招聘)
http://hr.baidu.com/www/job/jobDetail.action?jobId=2258

电子商务事业部_测试工程师(2011校园招聘)
http://hr.baidu.com/www/job/jobDetail.action?jobId=2260

电子商务事业部_前端开发工程师(2011校园招聘)
http://hr.baidu.com/www/job/jobDetail.action?jobId=2259

偶然考古到一篇自己的文章

星空夜话 发表于 2010-06-18 17:54:23

今天偶然间在百度上搜到自己在05年刚参加ACM比赛时写的一篇文章,感觉当时很幼稚啊... 不过还是感谢nuanran同学,是他的blog zz后才让我搜到的。

[转载]致05年天大ACM全体战友(WTommy)
各位ACM战友:
 
 ACM关键性的比赛已经迫近了,我们经过了一个假期的集训,是到该收获的时候了。然而,大家也看到了,四川赛区的比赛结果并不近如人意。今天是九月的最后一天,明天开始就是十一的长假,可是今天的训练没有人到。也许这么长时间的训练,大家多少都有些疲劳,但是为了天大的ACM事业,也为了我们的努力不付诸流水,更为了一直都支持我们、一直为天大ACM事业日夜操劳的于老师,我们应该咬紧牙关,坚持到最后。
 
 我想对于我们每个人来说,ACM都给了我们无论是在专业知识与实践能力还是人生道路很多益处。在专业与能力上的好处不用说大家都清楚,而在我们的人生道路上,因为有了ACM/ICPC,我们应该更多的学到一种责任和处世态度。做一件事,就要认真做,努力做到最好,否则就不要做!时刻准备自己,才能在最关键的时候脱影而出!人生要有所追求,有了目标就要不辞辛苦,达到目的!我想这些是最基本的做人的道理,大家应该明白。换句话说,对于ACM所付出的努力,不会对我们造成什么损失,顶多少玩一点,为了一个自己想要得到的目标,这样的付出再少不过了。于老师为我们付出了这么多都没有怨言,因为他心中也有一个梦,就是要振兴天大的ACM,亲眼看见天大学子出现在世界ACM赛场上。他应该是我们一个最好的榜样。再者,作为天津大学的一员,我们出去就代表天大,大家应该都会有这样一种为校争光的荣誉感。
 
 说到实质问题,大家也知道,天大对ACM的投入向来不是很多,我们今年有这样一些良好的机会也是因为去年的ACM老队员们在国际上取得了很好的成绩。作为天大ACM承前启后的一代,我们有责任接过他们手中的成果,甚至要比他们更好,这样才能让我们的ACM在成长的道路上更加畅通无阻的发展。
 十一过后,我们又将迎来浙大的网络比赛了,这是一场对我们而言十分重要的比赛。如果我们继续失利,将意味着我们可能有的队伍没有出去比赛的机会。借着今年大好的时机,却平白的失去出去锻炼的机会,我想这也是大家不愿意看到的。
 接下来的七天,我希望能和所有的队员为了理想努力拼搏,弥补不足,希望能在各方面有一个新的飞跃!前面的比赛等着我们,希望看到我们胜利的拥抱!
                
      05年队长
                                                 05.9.30

Topcoder SRM468

星空夜话 发表于 2010-04-21 16:43:34

平时工作很少用到算法,昨天晚上无聊在公司做了一场srm,结果表现差强人意。250pt的题目阅读起来慢了半拍只有173分,500pt算法还好,最后实现上有个bug,挂掉了。1000pt想了个大概,不会做… 看来是该有空捡捡算法了
 
简单说说题目的做法吧:
 
1.250pt:完全的阅读理解题目,题目太长,没什么算法可说,完全的模拟+暴力。
 
2.500pt:不算很难的题目。首先生成road和fly的花费,然后对于每段i到i+1的花费算一下road[i] – fly[i],可以知道road比fly要多花费的cost(这个值可能为负)。接下来的问题就转化为一个序列最大m子段和的问题,但要注意这个题目最多可以选择m段,不是一定选择m段,所以还要选择一个最大的m’。整个复杂度是线性的。
 
3. 1000pt:算是我遇到的比较简单的hard,不过现场还是没有完全想明白算法,赛后简单考虑了一下算法。题目的大意是有一栋楼有N层,每层至少会有一个station,相邻楼层的某两个station之间可能会有扶梯,还有一种特殊的扶梯是从1层直达N层的。每个station最多设置一个保安,每个扶梯两段不能都设置保安,问这栋楼最多可以设置几个保安?(N为10到50,所有station数量不超过100)
 
起初的想法是把扶梯对应着图中的edge进行建图,可以很容易的得到一个G=<V,E>,问题就变成了求图G中的一个最大独立集。我们知道对于一般图的最大独立集是NPc问题,因为最大独立集等于它的补图的最大团。当图G是二分图时才有多项式解,|最大独立集| = N – |二分图最大匹配|。
 
由于扶梯连接的特点可知,当N为偶数的时候,可以把奇数楼层和偶数楼层的点分开建立二分图,但当N为奇数的时候无法建立(含奇环的无向图肯定不是二分图)。当注意到题目数据范围后,可以采取一种穷举的做法。(比赛的时候没注意范围T_T)
 
因为stations的总量不超过100,楼层最少要10层,因此含有stations最少的那个楼层最多有10个stations。由于可以把N个楼层看做是一个环,设含有stations最少的楼层为k-th floor,那么可以枚举k层上所有的stations是否设置保安,总枚举数量不超过210=1024,再去掉不能选择的stations,那么对于剩下的N-1层可以做二分图最大匹配,选取一种最优的枚举方案则可以求出整个问题的最优解。


后记: 官方解题报告

python脚本辅助开发测试总结(一) -- python struct module

星空夜话 发表于 2010-04-07 16:36:21

Python脚本是什么就不多介绍了,由于平时在linux系统上做C的开发较多,在开发结束后的单元测试中通常会写很多检验的程序,通常情况下Bash shell就足够了~ 但当需要写与C语言粘性较强的测试时,python还是比较适合的语言,不愧被称为“胶水语言”。
 
我通常使用到python进行测试的情况有三种:
1.       利用python脚本的便利,检查数据文件是否符合预期要求,LOG分析等
2.       利用python的socket接口写简单的测试桩(server or client)
3.       当开发通用基础库时,利用python脚本写测试.so或者.a的小单元测试程序
今天简单总结一下第一种情况,首先正则表达式相关的就不用多说了,python与perl语言中的正则是分析数据的利器,尤其是分析线上LOG文件。接下来主要说的是,利用python中的struct module,利用struct读取&分析C语言模块中的数据结构。
 
例如有个二进制文件data.bat,其中存储了以下这个结构体:
 
typedef struct _index_t {
    uint32_t id;
    uint32_t birth_year:12;
    uint32_t birth_month:10;
    uint32_t birth_day:10;
    uint64_t offset:40;
    uint64_t len:24;
} index_t;
 
如果不了解C语言的结构体对齐,请先找基础书籍看看:)
下面讲解一个简单的sample python code,解析data.bat中的数据
 
首先要了解的是python struct module中需要定义个format格式表,该格式表对应的就是你需要load进来的结构体,可以在"python doc: struct"上查看详细的对应关系。可在表格查到对应uint32_t的格式是I(大写), 对应uint64_t的格式是Q(大写)。那么上述的index_t结构format可以定义为"IIQ”(这里需要对C语言补齐规则有所了解,如果结构体最后需要补齐的话,在format中也要有相应的占位符,具体内容稍后分析)。定义好format以后可以通过struct.calcsize(fmt)计算这个结构的大小(所占字节数),直接读取数据就ok了,下面看这段简单的sample python code:
import struct
 
fp = open("./data.bat", "rb")
fp.seek(0);
 
data_format = 'IIQ'
data_size = struct.calcsize(data_format)
 
while 1:
    data = fp.read(data_size)
    if len(data) <= 0:
        break  
    (id, birth, offset_len) = struct.unpack(data_format, data)
print 'id=', id, 'birth=', birth, 'offset_len=', offset_len
 
其中对于birth和offset_len变量没有具体的解析,如果需要解析的话直接位操作就好了,但要注意的是结构体中存储顺序和二进制的高低位关系,先存的数据在低位上,例如通过offset_len得到len具体的值,需要用offset_len>>40位,而offset_len & 0xffffffffff则是offset的值。
 
说个题外的问题,如果结构体定义的不够完美,定义如下:
typedef struct _index2_t {
    uint32_t id;
    uint64_t offset:40;
    uint64_t len:24;
    uint32_t birth_year:12;
    uint32_t birth_month:10;
    uint32_t birth_day:10;
} index2_t;
 
与之前的定义不同之处在于把birth相关的信息放到了末尾,这样按照C语言对齐规则的话,则需要在id和birth_day后面都要补充一个sizeof(uint32_t)大小的空间,也就是说sizeof(index_t) = 16,而sizeof(index2_t)为24。此时如果利用python struct module去load数据的时候要注意format的定义。当然你可以完全的按照C语言对齐规则把缺少的位置都给填写好,例如”IIQII”,其中第二个和最后一个I都是补齐的uint32_t。这样每次unpack出来5个变量就ok了。还有一种更智能的做法,python语言是可以通过你定义的format结构来自动进行补齐的,但不能保证整个结构体末尾的补齐,依据这个原则我们可以省去第二个I,format格式设成’IQII’,python会自动略去那个空缺的uint32_t位置。应用此特性的时候一定不能忘记补充最后的空位,否则从第二个数据开始就是错的了:)
 
技术不难,希望这份总结能够提高您的工作效率,相关的后两种python简单应用以后会陆续做出总结。
关键词(Tag): python struct

一些字符串相关的算法

星空夜话 发表于 2010-03-16 14:40:53

最近在公司技术交流的时候,分享了一些字符串相关的算法:

1. Brute Force
2. Rabin-Karp
3. Knuth-Morris-Pratt
4. Boyer-Moore & Horspool & Sunday
5. Trie
6.
Aho-Corasick Algorithm
7. Suffix Tree

……

基本包含了比较使用的字符串算法集合。
关键词(Tag): 算法 字符串

周末和同事看房

星空夜话 发表于 2010-03-09 16:52:42

周末和同事去回龙观、北苑、立水桥等地看房,这次主要集中看新房。

回龙观城铁对面“智慧社”要开盘了,整栋楼全部都是89平米的二居实用户型,分为南北通透和阳面单朝向户型,由于是高层的“伪板楼”(之所以这么说,是因为南北通透的房子阳面都是凹进去的,采光很不好)。房子的优势在于离回龙观城铁很近,对面马路就是。不好的地方有:首先回龙观属于昌平区,其次这个房子的得房率太低,只有74%(一梯2-3户),还有就是厅里的窗户是普通悬空那种窗户,既不是飘窗,也不是小阳台的落地窗,弄得很土。。。

北苑的楼盘这次开盘的和要开盘的比较多,一共有三个:中国铁建国际城、华贸城、天润福熙大道。依次说说观点:
中铁国际城:房子比较靠谱,价格稍微高一点,位置不错,不过要等5-6月份才能有开盘消息
华贸城:房子非常靠谱,现在在卖的14#,都是LOFT复式结构,平均在53-67平米,举架高4.98米,3月份在卖的是2.2w一平米,价格很便宜,27#楼要等5月份才可能开盘,预计价格在2.5-2.6w左右。
天润福熙大道:房子质量比较高,价格太贵,都是2w+一平米的普通板楼,买不起。

由于时间原因立水桥只去了桥南的美立方,不过房子早就售完了。


综合来看,回龙观对于上班还是蛮近的,周边设施还算齐全,就是属于昌平区,得房率太低。北苑属于朝阳,但周围高压线环绕,虽然房子都建在66-100米外,但人们还是有一点点顾忌。其实从科学上讲,可能这些电线的辐射还没我们使用的手机强,但大家都认为花这么多钱买房子,就应该买个十全十美的。。。。

转个bbs搞笑的评论: 有人说不买北苑高压线附近的房子不是因为怕辐射,是因为怕高压线塔倒了砸到他们。而事实上,如果发生了意外恶劣的天气灾害,我估计塔还没倒,房子早就倒了,不要对现在盖的楼盘质量报有那么大的自信。

关键词(Tag): 看房

Query Suggestion

星空夜话 发表于 2010-01-22 13:44:00

前几天要升级平台的suggest功能,偶然读到了cnbeta上的一篇文章“Google Suggest开始支持中文拼音缩写”, 我向来是不愿意看社会上的IT论坛,因为我觉得大部分的网友都是在扯淡,但我从这篇文章里面还发现了个内行的评论。

首先文章讲了一下在2009年10月左右g.cn(谷歌)升级了自己平台首页的query suggestion功能,主要的改进是支持了拼音首字母的suggest,如图:

谷歌suggest


接下来就是各路网友评价每个搜索引擎的suggest功能,有很多人都抱怨baidu.com上的suggest功能过于简单,我也简单的调研了一下,发现百度首页的功能确实比较简单,谷歌和有道的功能比较全。但普通网友是有些误解的,例如有人质疑这算不算创新,其实不然,query suggestion功能已经是很旧的技术了,但处于对服务器压力的考虑,访问量的网站都不愿意把suggest功能做的复杂,因为suggest的访问量往往是搜索引擎搜索query次数的10-20倍。

其中有一个网友还是很内行的,写了这么一段话:

评论


网友对于产品的热衷可以理解,但有时候确实是过了。如果你稍微懂一点技术,也许好多问题就都可以迎刃而解了~
关键词(Tag): suggestion query

驾照交规考试总结

星空夜话 发表于 2009-11-17 22:41:39

交规的法培是在周末,本来平时上班就比较累,周末必然翘课了。这2-3天看了交规的1370道题目,感慨万千啊,有些常识的很简单,有些真的很容易记混,尤其是罚款和法律相关的比较难记。明早要考试了,写一下我总结的10条答题规律:

1. 关于罚款的有“200元以上2000元以下”的题目就选这个,感觉正确率90%以上。如果没有,就选择“20元以上200元以下”。如果答案都是固定的钱数,选“200元”或者“100元”,未配备有效器具的选“50元”。
2. 关于机动车缺少或伪造证件的处罚(例如检验合格标志、保险标志、行驶证等)都选“扣留机动车”选项,和驾照无关
3. 自己犯的错误(包括无证驾驶等)除了罚款要选“拘留15日以下”,特别注意自己超速50%的时候是“吊销驾照”。其余的让他人犯错误的(包括借给无驾照人开车等)都是“吊销驾照”
4. 在普通道路能见度在50米以内或者下坡、急转弯、过铁路等时候,车速限制都选“30公里”
5. 关于不准停车的题目,只有“30米”和“50米”是有可能对的,其他都是错的。凡是题目中有“站”字的都选“30米”,其他都是选“50米”。
6. 关于高速公路车速和车距的控制。能见度小于50米的,车速选“20公里”;能见度小于100米的,车距选“50米”;能见度小于200米的,车速选“60公里”
7. 救护类的选择题都选C,有出血的先止血,能救人的就先救人,其他都是错误的
8. 当“减速、避让”出现时,基本它就是对的
9. 关于紧急踩制动踏板停车的,基本都是错的
10. 判断题目中如果有“严禁”、“必须”等强制话语词时,一定是对的

以上规律未必都正确,请谨慎使用!

关键词(Tag): 驾照 交规考试