给silly增加热更新

最新抽了点时间给silly增加了一个silly.patch模块,用于对热更新提供一些有限的支持。 热更新最麻烦之处莫过于“数据迁移”, 即怎么使新函数(要更新的函数)以“运行时数据”的状态运行。 其实http这类无状态协议是最为简单的,因为他们不需要“数据迁移”的过程。http的这种架构,使得所有的函数都是无副作用的,所有的数据在请求结束给出Response的同时, 数据就已经存入了数据库。当需要热更新函数时,根本就不需要考虑数据的问题,直接替换就可以完美解决。 与此相对的是,通常的服务……

为什么要有头文件

我在写C文件时,一般会首先确定这个模块需要哪些功能,然后在头文件中定义相应的接口函数。之后才是在C文件中实现,在实现过程中除非有遗漏的接口,不然是不会再切回头文件的,一般辅助函数我都是直接以static的方式定义在C文件中。 在写C++代码时,这些代码辅助类的函数,都必需要以private的方式在头文件中声明。这会导致在写代码时,需要频繁在h/cpp之间切换,极度令人不舒服。 因此每次在写C++代码时,都免不了在心里抱怨几句为什么不把private函数直接定义在cpp文件中,或者干……

实现了一个lualint

在使用动态语言的过程中,由于其运行时检查特性,很多手误并不能在刚运行时暴露出来。虽然并不会导致程序个程序crash掉,但总归是很麻烦的。 网上找了一个lualint试了试,效果还不错。这个工具的原理就是基于在写lua代码时并不会使用全局变量。在检测到全局变量时直接报警即可。 仔细研究了一下这个lualint的原理。 lua自带的工具luac是可以把编译后的OPCODE打印出来的,更关键的是自带注释。 利用OPCODE和注释就可以分析出在哪一行哪些变量是使用了什么全局变量。只要我们在代码中……

使用lua过程中需要注意事项

最近一段时间写了不少lua代码,由于这一次的代码量比以往都多,因此也就遇到了以前没有遇到问题, 需要说明的是,这就是一篇lua问题大集合, 并不涉及其他。 先说说遇到的问题及解决方案。 在lua中没有多余的数据结构,全靠一张表,这也是他简洁的根本所在。 当索引为全为数字时即可当数组使用,然而需要注意的是lua假设数组的索引一定是连续的,在此基础上lua尽可能快的优化了取数据长度的算法,因此lua对‘#’操作符的描述是“当table[i]不为nil, 而table[i+1]为nil时,则数组的长度为i……

C++默认构造函数

在C++中,如果不为某个struct/class实现一个构造函数,那么编译器就会自动为这个类添加一个默认构造函数,而这个默认构造函数什么也不干。 但是我却从来不知道,默认构造函数在不同的情况下,会出现不一样的效果(当然这是C++03之后的标准). 先看一段代码: struct test { int a; int b; }; void *operator new(size_t sz) { void *p = malloc(sz); for (size_t i = 0; i < sz; i++) ((char *)p)[i] = 0x01; return p; } int main() { struct test *t1……

迭代器模式

在写C++代码时,首先接触的就是迭代器。甚至于设计模式都有一种模式叫迭代器模式。虽说网上到处都说迭代器用于隐藏数据结构的细节,但我却一直没有真正搞明白为什么需要迭代器去隐藏数据结构细节。 在写C++代码时,一般我每用一个数据结构都会去查一下,他大致是如何实现的(不然用起来不太放心:D)。 因此一般情况下我在c++下都是使用类似类似for(size_t i = 0; i < vector.size(); i++)的方式去遍历vector的每个元素。 直到最近的一次重构我才大概明白什么时候去使用迭代器模式……

模板的高级用法

一直以来都是通过C用基于对象的设计方法来写代码。即使工作中使用C++, 也是尽可能少的使用超出C的一些特性。当然这并不是C++不好,而是C++实在太复杂了。以我的脑力来讲, 如果使用C++过多的特性, 很容易让我过于陷入语法特性之中, 而忽略了设计。因此, 对于C++的一些高级特性, 如模板等并没有深入研究过。 模板对我来讲, 仅限于知道可以实现泛型。至于怎么巧妙的利用泛型来实现其他特性, 从来没有深入研究过。最近工作中,碰到了一些看起来比较高端的模板用法,令人有一种耳……

c语言部分的开销测试

最近在写c代码时底气越来越弱,原因在于某些调用的开销,我心里并不是十分明确。写起代码来由于纠结也就变的畏畏缩缩。 今天终于抽时间测了一下,仅测试了最近常遇到的一些调用的开销。 测试环境如下: CentOS release 6.7(Final) CPU:Intel(R)Xeon(R)CPU E3-1230 V2 @ 3.30GHz 采用gcc(glibc)编译,未开任何优化。 在测试时,大部分操作cache均会命中,因此如果cache经常命中失效,还需要另外考虑。 测试结果如下: 可以看出for循环是最廉价的。 malloc是开销最大的,这……

lua gc的使用

主流的垃圾回收一般都是基于引用计数和标记清除算法. 从内存占用量上来讲, 引用计数无疑是有优势的, 当引用计数为0时, 直接就会将相应的对象清除, 典型的应用就是C++的智能指针. 但是基于引用计数的gc有一个坏处, 它无法解决循环引用问题. 如果A引用B会导致B的引用计数+1, B引用A也会导致A的引用计数+1, 这样A,B对象永远也不会删除. 记得在OC中似乎使用了弱引用来解决这个问题, 但总感觉这样会给代码中埋下坑. 标记清楚算法可以完美的解决循环引用问题, 其做法是从root遍历所有可达……

lua的debug_hook接口应用

lua本身并没有提供调试器, 但是提供了一组称为debug_hook的API, 这组API可以用来编写自己的调试器或者一些其他的东西。 这两天的工作主要就是研究了一下debug_hook这组接口, 写了一个极简化的lua调试器和一个lua性能分析器. lua调试器现在仅支持break point, step, print, coutinue这几个功能。 由于最近写lua已经习惯于不用调试器了, 因为实现的比较简单。 下断点时, 将要断点所在的文件与行号存入表中。 在不考虑效率的前提下, 直接用line mode来hook中每一行的运行,然后……