随笔(2014.12)

1. 虚拟内存,cpu分时,i/o等设计的目的是为了让程序员使用更容易,也就是“易用性”更强,为达到这样的目的,他们设计的出发点有一个——让每个进程看起来是独自享有硬件的,不必关心其他的进程。这样,在进程运行的时候,就可以放心的开启线程不必关系是否cpu被占用了,可以放心的new一块内存,不必关心是否这内存被别人用了。这样设计不仅是从易用性上考虑,也是从安全方面考虑,尤其是虚拟内存的设计,当一个进程挂掉的时候,操作系统可以进行地址保护,不影响到其他的进程。

2."建议慎用boost::weak_ptr来避免智能指针循环引用"http://blog.sina.com.cn/s/blog_48d4cf2d0100uhgt.html
"为何我反倒是建议慎用weak_ptr呢?这得回到实际编程中为何存在循环引用这个问题上来。为何两个对象要互相引用对方?我发现在绝大多数情况下几乎总是因为两个对象存在类似整体/部分的这种关系(要从广义角度理解整体-部分)。不管是否使用weak_ptr,甚至不管是否使用智能指针,都需要开发者正确识别出这种关系。使用weak_ptr,一般是让整体对象持有部分对象的strong ptr,部分持有整体的weak ptr,这样当然是ok。但我更喜欢让整体对象持有部分对象的strong ptr,部分对象则直接持有整体对象的原生指针甚至是引用(一般来说引用更好,要求构造部分对象的时候传入整体对象作为参数),然后保证整体对象的生命周期涵盖部分对象的生命周期。这两种方法相比,后者效率高(原生指针vs对象),编程简单(使用时无需提升+判断成败)。当然如果违背了整体对象生命周期涵盖部分对象生命周期的原则,会死得比较惨。但是我觉得大部分时候这是好事,因为符合Die fast 和 Die fierce 原则。使用weak_ptr,一团和气之下可能掩盖了错误的对象析构顺序,而这可能又是由其他逻辑错误导致的。
"

3. boost库中大量的使用模板,最重要的可能是从效率上考虑,而且库中有很多hpp文件,所有的声明与实现都在一个文件中,这样库使用的时候就非常方便,不用编译生成什么lib和dll文件。

4. firebird的存储过程名称长度有一定的要求,太长能够存入数据库,当时通过dbms调用接口不可以调用。

5. Google编程规范

6. boost::bind 的陷阱,bind的第二个参数,可以是对象指针,可以使对象引用,可以是对象的实体,但是在传对象的引用的时候要注意,必须加上一个boost:ref(object_ref),告诉bind,第二个参数是个引用,否则bind会把它当作一个实体,然后按照“闭包”来处理,在内部拷贝复制多次。这个拷贝赋值对于很多没有实现clone的对象来说都是隐患很大的,内部很多指针没有深拷贝,那么使用一次之后,实体里面的指针都会被析构掉。所以,c++的对象如果不希望被莫名的拷贝,要继承boost::noncopyable。bind函数之所以是这样做,可能是它更倾向于“闭包”,因为引用没有类型,传一个引用的时候,没法判断是引用还是对象的实体,所以为了让闭包实现,都认为是一个实体。如果都认为是引用,那么这个方法就没有方法传入实体对象,没法实现闭包了。

7.一种多线程框架:所有业务实体通过一个线程进行消息的接收,暂时叫做总线线程,总线线程驱动基本的增删改、扫描操作、消息的分发,当有设备增删改消息时,放入对应实体的任务队列,等待总线线程驱动操作,这样对于实体来说,所有的操作都是排队处理的,就不存在锁竞争的问题。对于实体要处理的一些业务,例如定时任务,当定时任务到达时候,并不是直接操作实体,而是根据实体id发送一个定时器任务到消息,消息经过总线,实体,到对应的处理业务对象。基本思想就是所有业务结果(尤其是会改变实体状态的操作)以消息的形式排队处理,这样要特别注意在总线线程中不能有一点的延迟阻塞,否则会影响到所有的业务。这样处理会减少很多锁的操作,减少死锁的可能,但是会导致实体的接口比较大,要处理各种消息,改进方法就是在实体中实现消息的订阅处理,这样会减少一定的接口,但对于修改实体状态的操作,一定要提前做,不能再放到线程中异步处理,否则会产生竞争。

8.读写锁的另一种使用场景,当读取数据较大且分散的时候,可以避免使用很多小颗粒的互斥锁,使用一个比较大的读锁,全部锁住小颗粒数据,但是不能有重入。这也是hot locks的一种场景,虽然一个锁很热,但是只是读的时候比较热,写的时候很少,这个时候使用读写锁,完全可以解决性能上的问题。

9. 消息分发处理框架 魔兽世界 Android

10.JVM 内存分配,垃圾回收,类加载。如何自定义el表达式的函数,servlet的过滤器,监听器。高并发的数据库该如何设计。IOC有哪些好处,DI有哪些好处。

11. 扩展点相关
http://www.blogjava.net/yangbutao/archive/2007/09/27/148500.html
http://www.51cto.com/specbook/319/44641.htm


12. OSGI

13. window异常处理机制,目前的ACE默认使用了windows的异常处理,在Windows2008下,产生了非法访问,不会导致进程退出,只会导致该线程退出。
解决方案
关闭ACE的使用windows的异常处理机制,修改ACE
注释掉# define ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS,如下
#if !defined (__MINGW32__)
// # define ACE_HAS_WIN32_STRUCTURAL_EXCEPTIONS
#endif /* __MINGW32__ */
重新编译ACE生成ACE_znv.dll

http://www.cnblogs.com/bitxj/archive/2012/10/08/2715967.html
http://www.cnblogs.com/bitxj/archive/2012/10/08/2715967.html

14. “取消告警”一个非需求功能,该功能直接把告警信息从数据库中删除,为了应付演示或者检查采用的一种临时措施,这可能导致告警不在上报。手动消除告警只会删除数据库,不会通知告警过滤的服务器,这时候告警过滤的服务器会一直以为客户端存在告警,从而让新产生的告警不在上报。

15."水平触发(level-triggered,也被称为条件触发)LT: 只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你)
边缘触发(edge-triggered)ET: 每当状态变化时,触发一个事件
“举个读socket的例子,假定经过长时间的沉默后,现在来了100个字节,这时无论边缘触发和条件触发都会产生一个read ready notification通知应用程序可读。应用程序读了50个字节,然后重新调用api等待io事件。这时条件触发的api会因为还有50个字节可读从 而立即返回用户一个read ready notification。而边缘触发的api会因为可读这个状态没有发生变化而陷入长期等待。 因此在使用边缘触发的api时,要注意每次都要读到socket返回EWOULDBLOCK为止,否则这个socket就算废了。而使用条件触发的api 时,如果应用程序不需要写就不要关注socket可写的事件,否则就会无限次的立即返回一个write ready notification。大家常用的select就是属于条件触发这一类,长期关注socket写事件会出现CPU 100%的毛病。
"参考(
http://blog.csdn.net/mafuli007/article/details/8090679

对于高性能的服务器,一般会使用边沿触发,水平触发感觉可靠性会高点,但是系统调用次数多(性能较低的一个原因)。

16. “防御式编程是提高软件质量技术的有益辅助手段。防御式编程的主要思想是:子程序应该不因传入错误数据而被破坏,哪怕是由其他子程序产生的错误数据。这种思想是将可能出现的错误造成的影响控制在有限的范围内。”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值