2015 二月 | 重归混沌的BLOG

为什么要使用算法

在接触算法之初, 我为诸如快速排序, 二分查找效率感到惊讶. 随着代码量的增加, 对于如动态规划之类以空间换取时间的算法, 我还能理解. 但是我始终不明白如二分查找这类需要前置条件算法为什么能提高程序效率, 虽然查找快了, 但是开销浪费在了排序上, 使用二分查找的一次读写的开销和, 甚至很可能比不使用算法还要慢. 最近在阅读了一些开源代码之后, 终于有点明白为什么如二分查找这类需要前置条件算法可以提高程序效率了. 在程序设计中, 使用如二分查找这类需要前置条件的算法之所以……

为什么会有自动化测试框架

在研究敏捷开发中的TDD过程中, 接触到了UT(UnitTest)框架的概念.The Lego Batman Movie (2017) 在我的印象中, 自动化测试只需要每一个C模块中写一个对应的测试代码文件, 然后在Makefile稍加修改即可完成, 类似下面这样: //module_a.h int module_a_dosomething(); //module_a_test.c int main() { module_a_dosomething(); } //Makefile .... test:module_a_test ./module_a_test module_a_test:module_a_test.c module_a.c module_a.h gcc -o $@ $^ 只……

lua_tothread的使用场景

在学习lua虚拟机与C交互过程中, 看到一个很令人奇怪的API, lua_tothread. lua官方手册上只是说明lua_tothread的作用是将一个thread(coroutine)以lua_State的形式表示出来, 但是总是搞不清这个API应该在什么情况下使用. 在做了一些实验后, 终于有点结论了. 在调用luaL_newstate函数去创建一个lua虚拟机时, lua就会自动在这个状态中创建一个新thread(coroutine), 这个线程被称为主线程. 除了调用lua_close之外, 这个主线程永远不会被回收. 在lua中每个coroutine都有一个lua_State与之……

linux下动态库的版本号

据说linux下的动态库管理机制可以避免微软件DLL Hell的问题. 今天抽了点时间研究了一下, 发现其实本质上是利用别名(soname)技术来实现的. 在编译so文件时, 通过参数-soname将别名传入链接器ld(gcc可通过参数-Wl来将-soname参数传入链接器), 那么生成的动态库文件中Dynamic section中的SONAME将会被填入输入的别名. 如果没有-soname参数, 则Dynamic section中将不会有SONAME字段生成. 当使用命令gcc -g -Wall -o main -L. -lver时, 在进行链接时, 链接器ld会首先去当前目录查找libve……

linux下动态库

今天无意间发现在linux下share object(dynamic library)中的函数竟然可以不通过回调的方式直接访问主程序中的函数,瞬间颠覆以前对于动态库的观念. 如代码所示libhi.so中有一个函数hello, 主程序main中有一个函数hi_out, 那么在main中调用libhi.so中的hello时,hello会自动找到main程序中的hi_output函数地址, 然后进行调用. 在感叹linux下动态库强大的同时, 对于其实现机制也产生了好奇. 经过一番努力终于在程序员的自我修养中第7.6.2章找到答案. “动态链接器在完成基本自举……

setjmp的使用

以前对于C语言的setjmp和longjmp从来都是知道有这么个函数, 但是不知道什么情况下要使用, 甚至于不知道setjmp的实现机制是什么样子的. 这次在实现coroutine的过程中虽然没有使用setjmp来实现, 但是由于setjmp来实现coroutine的所有操作都是可以在用户态进行的, 因此顺便研究了一下setjmp的实现机制. 与我猜测大致一样, 在call stack上来讲setjmp一定先于或等于longjmp处于的位置, 这样其实longjmp所做的不过就是将当前寄存器上下文恢复成setjmp函数保存的值即可. 调用longjmp的函数……