2011年1月27日星期四

autotools的复杂关系

autoscan生成configure.scan,手动将configure.scan重命名成configure.in
autoconf根据configure.in生成configure
automake根据Makefile.am生成Makefile.in
configure生成config.h(可选的),然后configure把config.h和Makefile.in当作输入生成Makefile

其中configure.scan重命名成configure.in后一般要根据需要手动修改下,可能是大改
Makefile.am是要手写

--
caosuwei

2011年1月11日星期二

hash表中取下标的一个小技巧

今天看redis的源码,看到了一个以前没见到过的技巧
int mask = hash_table_size - 1;
int index_in_hash_table = calculate_hash_key(key) & mask;
这是一个快速取得hash表中下标的算法
--
caosuwei <caosuwei@gmail.com>

2011年1月10日星期一

从别人那儿转来的

·         重构自己的代码如果是开发人员,随时要记得的事情是如何改善自己的代码质量。要让自己成为更好的技术人,重构或许是是随手可作的并且切实可以提高自己能力的一件事情。有好的代码为基础,才有可能随时面对更大的系统压力。要记住小网站有可能发展为大网站,技术人需要的是提前做好准备,为你的代码,为你自己,为你的团队。

·         自动化日常工作有人说,萝卜快了不洗泥,团队什么事情都要我做,我怎么有时间去搞什么重构?那么,是否可以将一些日常需要重复做的事情尽可能的自动化,比如日常发布是否 可以自动化?测试工作是否可以自动化?安全检查是否可以自动化?有了这些为前提,你肯定有足够的时间去做你想要做的事情。

·         良好的开发习惯在一个团队中,如果养成良好的开发习惯会让你节省时间和精力。比如对版本工具的掌握程度,如果连 SVN 都缺少使用意识的话,很难想象团队协作开发的时候会搞成什么样的局面。也不要抱怨团队的同事没有好习惯,他们或许正需要你的帮助呢...用你的行动,去带 动他们。顺便问一下,你平时为代码写注释么?

·         改进自己的产品复杂未必是最大的竞争力,细致精致有的时候是更好的竞争力。很多技术人员做到最后发现自己做了很多对用户并不重要的功能和产品,而最重要的产品反而疏于改进。这未必都是别人的错,如果自己能够对产品和业务有足够的了理解的话,你或许会驱动团队少走弯路,做更正确的事情。

·         提高资源使用率别人用数台机器支撑的访问量,换了你,能否用更少的硬件支撑?这些方案是可扩展的么?是可验证的么?遗憾的是,我看到多数小团队硬件利用率甚至比一些大团队更低。如果听任低效的代码、冗杂的产品功能不去改变,那么可能的确要面临资源利用率相对较低的窘境。

·         规划资源的能力团队小的时候,整个产品架构、整个网站架构的信息收集并不难,让你建立起一个全局的观念相对更为容易一些。注意分析整体架构的演变,根据自己的理解,一步一步预期将来可能出现的问题。这是非常难得的锻炼自己的机会。顺便问一下,你给自己的网站画过架构示意图么?

·         保持学习的热情我在前面说到了网络上的技术资源的丰富性,你是否能够持之以恒的去学习、吸收这些技术经验,是否养成了评估某项技术成熟度的能力? 什么,学了用不上?问题是再大的公司在技术上也是要有取舍的,更多的时候都是在用更为合适的技术而不是看起来更"先进"的技术。


--
tianyuan

2011年1月5日星期三

chdir带来的问题

今天帮同事看了一个小问题。本来这个问题不算什么,但是这个问题是我以前就碰到过,随手就解决了。然后这次反而花了一段时间才解决的。
问题是这样的,同事觉得自己的程序不够快,就想拿gprof测一下,结果发现程序一直都没有在当前目录下生成gmon.out文件。反复尝试了几次都不行,因为调用了我写的库,所以他跑来问我。我帮他查了快一个小时才查出问题来,当然这里面有程序运行的时间。原因是他在自己的代码里面调用了 chdir(),结果所有的gmon.out都写到了另外一个地方。

而我当时碰到这个问题的情形是找不到core文件。那时我想也没想,随手就在根目录下面 find了一把,一下子就找到了原因。

另外再说一句,今天看到LWN上说Linux kernel的2.6.37版有针对prof的更新。针对有动态链接的程序,还是得靠prof和Oprofile了。
--
caosuwei <caosuwei@gmail.com>

一个可以并行化的取取数组中第K大元素的算法

一个无序的数组A,长度是N,想要取出其中的第K大的元素.

1. 如果数组长度够小,那么对数组整体排序,取第K个
2. 如果数组长度太长,那么对数组做切分,对切分的每个部分排序,取出这个部分的中间元素.
3. 在中间元素中递归的取中间值,直到取出整个数组A中间值M.
4. 将整个数组A跟据这个中间值M划分为三个部分,大于M的,小于M的,和等于M的.
5. 根据这三个部分的大小来判断第k大的元素在哪个部分,对该部分递归的做上面的操作.

--
caosuwei <caosuwei@gmail.com>

lambda表达式

对于std::for_each()这样的算法,是最适合使用lambda表达式这样的小技巧的

lambda表示并不是一个必须的东西,跟它有相同作用的还有function object和函数指针.函数指针的缺点在于没办法保存中间状态,但是效率相对较高.而function object作为一个自定义类型当然能保持中间状态,但是写起来也太繁琐了.

lambda表达式算是综合了这个两个的优点.

这儿有一个例子

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int main()
{
// Create a vector object that contains 10 elements.
vector<int> v;
for (int i = 0; i < 10; ++i)
{
v.push_back(i);
}

// Count the number of even numbers in the vector by
// using the for_each function and a lambda expression.
int evenCount = 0;
for_each(v.begin(), v.end(), [&evenCount] (int n) {
cout << n;

if (n % 2 == 0)
{
cout << " is even " << endl;

// Increment the counter.
evenCount++;
}
else
{
cout << " is odd " << endl;
}
});

// Print the count of even numbers to the console.
cout << "There are " << evenCount
<< " even numbers in the vector." << endl;
}

总的来说,基本规则就是
1. [=], [&] 表示在lambda函数里可以访问当前所有变量,其中=隐含了this
2. [=, &a, &b] 表示除ab按引用传递,其他均按值传递
3. [a, &b] a按值传递,b按引用传递

这儿有个参考: http://msdn.microsoft.com/en-us/library/dd293599.aspx
g++ 4.5版本之后才支持这个东西, vc我没有查过,貌似也是vc2010才支持

--
caosuwei <caosuwei@gmail.com>

libssh2中的奇怪设定

最近用libssh2自己轮了一个scp函数出来,用到了 libssh2_userauth_publickey_fromfile() 这个接口,但是很奇怪的是,这个函数里做认证的时候,同时需要public key和private key作为参数, 任何一个为NULL都会导致认证失败,幸好最后一个passphrase参数可以为NULL

翻了翻libssh2的开发邮件列表,发现还有别人很烦这个东西,并且提供了一个patch,可以用NULL的public key而不会报错了.

链接在这里
--
caosuwei <caosuwei@gmail.com>

gcc -fPIC

不加fPIC编译出来的so,是要再加载时根据加载到的位置再次重定位的.(因为它里面的代码并不是位置无关代码)
如果被多个应用程序共同使用,那么它们必须每个程序维护一份so的代码副本了.(因为so被每个程序加载的位置都不同,显然这些重定位后的代码也不同,当然不能共享)
这样就失去了共享库的好处,实际上和静态库的区别并不大,在运行时占用的内存是类似的,仅仅是二进制代码占的硬盘空间小一些.而且在加载时才重定位的开销也很大(这一点使得这种做法更加没有意义).
--
caosuwei <caosuwei@gmail.com>

2011年1月2日星期日

2011年终总结

经过一年半的痛苦挣扎,终于咋去年年底得到了一份新的工作,当当网,有机会了解互联网行业,搜索,并发,大数据量处理等等技术。而且实际上,这份工作也开阔了我的眼界,并且在一些基础的语言细节和算法方面,也让我有了迅速和本质上的提高。
但是在四月底的时候,却迅速被辞退,然后投简历,面试。在推掉taobao的offer之后来到了现在这个刚起步的公司。如果可以说稳定的话,算是初步稳定下来了。
往回看看,毕业之后的去的那间公司完全是个失败的尝试,我并不适合去干嵌入式方面的公司,而且还是一个养老公司,几乎就是荒废了一年半时间。
3,4月份在当当的时候,迅速的把我以前自学过,但是一直没有实战机会的知识应用到了实际的项目中,这是一个加深和巩固的过程,最直接的好处就是在我到现在这个公司的时候,我的能力马上就得到了认可,隐隐已经是部门最好的人之一。但是这个似乎并不是算是一件好事:公司的技术力量并不强,项目组也并不需要多复杂的技术。项目组需要的是一个7×24稳定的系统。
当我的能力得到认可之后,我也就有了一定的自由度,这样我也就可以用这些时间研究一些开源的项目。2011年,我希望我能在某个开源项目中贡献出自己的代码。

今年的两次跳槽,我的工资从4k涨到了10k,比例不小,但是绝对值还是不大。希望2011能通过加薪或者跳槽至少到15k,或者翻倍。

在技术上,我不知道我现在这样能不能有大的突破了,或者还是去个大公司历练一下才是正途?

年中和年底和妈提起的在北京买房的计划随着北京房价的一路飙升和我一家人的犹豫不决彻底泡汤了,爸妈还是希望能在老家住套新房子,那样也好吧,老家的房子住了二十多年来,也该换换口味了。至于我的房子,还是靠我自己吧。

2011年,我已经奔向26岁了,工作上已经找到了自己的定位和方向,往前冲就是了。感情上和zm的还是犹豫不决,我不想去南京。身体上,到了2011,年纪已经不小了,锻炼已经要当成一件正式的任务来完成了。平时如果没事,去考个驾照吧。呵呵
--
tianyuan