文章归档

2013总结

时间过的真快,转眼就已经毕业一年半了,回忆一下2013年,主要是工作,顺带对一些家庭和生活的感悟,算是对自己的一个总结吧。

一、关于工作

2013年的工作主题:

  1. 理解基础系统

2013年所做的过的事情:

  1. 开发分布式存储系统
  2. 研究git核心代码
  3. 研究c语言编译器lcc源码,go语言编译器runtime的实现,lua虚拟机的实现
  4. 研究xv6操作系统源码
  5. 研究linux内核文件系统源码,tcp/ip协议栈的实现,参与社区开发
  6. 研究openstack/分布式存储系统ceph,理解云计算的基础架构
  7. 开发pio

2013年花了大部分时间在基础系统的学习和理解上,目标是初步实现基础完备,为后面的深入研究打下基础。2013年最大的收获就是找准了自己对方法论的定义:是一套指导编码和实施的原则和方法的集合。以及找到了积累方法论的途径:在工作中不断的理解,反思,和总结。

2013年的不足和自我总结:

  1. 悟性不够,思维不够敏捷,需要提高大脑的活跃度,善于思考
  2. 代码产出低
  3. 学习的过程没有记录,所谓好记性不如烂笔头

2014年的工作主题:

  1. 基础架构
  2. 软件质量保障

2014年需要TODO的:

  1. 坚持每周写博文
  2. 15w的代码产出
  3. 关注基础架构,并思考实际编码中的软件质量保障,希望可以积累出一些相关的方法论。
  4. 多看书,上豆瓣积累一个书单

二、关于家庭和生活

9月份后给家里打电话的次数就越来越少了,一个月偶尔一两次,这一点做的很不好。应该多关心家里,父母身体不好,做孩子的应该上心。另外,和老婆沟通的也不够,导致她对毕业季的找工作安排不妥当,需要检讨。

其次,没能够坚持运动,注意身体,避免职业病。

htc touch hd升级安卓2.3.7

最近为了响应公司的号召,体验一把微米,于是决心研究下怎么把老爷机htc touch hd从屌丝wm6.1逆袭成安卓2.3.6。牛人早就把材料准备好了,移步请看:

  1. [ROM] {NAND} AOSP-GBX | < Kernel: 2.6.27 > | 2013.01.20
  2. Installation guide from Windows Mobile to the Android

研究了一下,安卓过程大概如下:

  1. 首先升级机器的HardSPL,我的是SPL1.56,对于经常刷机的机油来说,1.56不陌生了,我的默认就是。
  2. win xp请安装ActiveSync 4.5,vista/win7/win8会自动安装驱动,一般在你手机USB连接电脑时,自动搜索和更新驱动程序。然后HTC与电脑连接
  3. 从googlecode上下载rom文件,http://code.google.com/p/nandroid-for-htc-blackstone/downloads/list,我下载的是 FagyiDROID-V1-ODEXED.zip
  4. 从mediafile上下载其他刷机需要的文件,http://www.mediafire.com/?85m45naii6dpk,只需要三个即可:Adb-fastboot.zip,BLACIMG.NBH,BlackstoneAdvancedRUU和recovery.img

其他过程按照xda指引来做就是了,非常简单。刚装完是英文的,重启后变成中文了,真不错。

谈软件质量保障

这真是一个非常广阔的,难以囊括清楚的话题。我所理解的软件质量保证主要包括研发流程管理,质量控制和软件维护。稍微列一下提纲:

  • 研发流程
    • 为什么选择git而不是svn
    • 如何构建企业级的基础系统
  • 质量控制
    • 对象设计:SOLID原则和GOF模式实践
    • 模块化编程:解耦、解耦、还是解耦
    • 模块的可测试性和单元测试
    • 系统量化,让trace bug变得简明
  • 软件维护
    • 文档:wiki/PPT/man pages/docs
    • 自动化部署
    • 监控系统

一、研发流程 1)为什么选择git而不是svn

对于研发流程的选择,我比较偏向于开源社区的风格,例如linux内核。而在分布式协作的工具支持方面,git比svn更易用。

  • 每个人都应该熟悉整个系统(全栈工程师?):不用了解每一个细节,但应该知道它
  • 每个人都是code reviewer
  • 严格的代码提交和合并流程:git做了这一切事情

2)如何构建企业级的基础系统

这里有一个很重要的原则就是:动静分离。所谓动,就是代码中易变的部分,静,就是不易变的部分。将不易变化的代码剖离出来,简化系统架构。ok,举个例子,假如我们要实现一个web service,代码架构通常是这样的:

  • common/
  • core/
  • service/

当然,这是我常用的做法,首先是要完备基础库,接着实现核心模块,而service负责将这些模块组织架构起来,最终编译成一个可执行文件。也许service里就一个main.cc源文件 如果能理解这种模式的好处,我们就可以推广到整个企业系统里面去。例如,这个基础系统看起来可能是这个样子的:

向beyond致敬--被影响的一代人

一直以来可以坚持的事情有三:

  1. 看星爷的电影
  2. 听beyond的歌
  3. 陈扬的心灵地图电台

陈老师的电台在高二那年断了,非常可惜,虽然这几年还时不时拨弄一下收音机,但是再也听不到能匹美陈老师那么富有磁性的声音了,^_^。在那个连mp3和md都还不知道是什么东东的年代,大部分学生对心灵地图这个节目应该很熟悉的

另外就是beyond乐队,受beyond影响最深的一代应该80后,但是到我们读初中那会,很多人仍然是beyond的fans,主要是因为beyond的歌确实很励志。我记得我初中的第一个晚上时,因为是农村,条件没城里那么好,宿舍就是食堂二层临时搭建的工床,宿舍里热闹的炸开了窝,这个时候就两个人在玩弄磁带机,一个是我,在听心灵地图,另一个是我旁边的哥们,在听别安的歌,后来我们成了兄弟。

每个人都有一段很长的故事,偶尔回忆一下。。。

c语言可变参数类型

使用可变参数时,va_arg宏的第2个参数不能被指定为char、short或者float类型。因为在可变参数函数传递时,char和short会被提升为int类型,而float会被提升到double类型 。

例如,以下的代码是错误的

a = va_arg(ap, char);

因为我们无法传递一个char类型参数,如果传递了,它将会被自动转化为int类型。上面的式子应该写成:

a = va_arg(ap, int);

coredump记

造成程序coredump的成因很多:

  1. index类的索引造成的数组越界
  2. 多线程环境下使用了非线程安全的函数
  3. 多线程与释构
  4. 多线程环境下的数据互斥
  5. 空指针
  6. 对象delete后仍然被访问

为了避免这些情况,需要谨慎处理所有相关的资源:

  1. 对象必须全部初始化后才能使用
  2. 尽可能的不要缓存对象,使用统一的内存管理来避免内存碎片化的问题。除非你确定对象被重用时,相关的资源被正确的初始化。
  3. 对象该由谁创建,由谁来释放,delete需要全局感知,避免游离的对象指针
  4. 对于共享的资源,注意互斥和死锁
  5. 全局对象使用指针,统一new和delete
  6. 特别注意资源进入临界区的时机,例如初始化工作确认完毕。

数据+结构

数据是业务流密切相关的东西,容易发生变化,而结构通常都是大同小异。很多时候我们不得不为了各种各样的需求而设计复杂的数据结构。而且一旦它们之间呈现出复杂的依赖关系时,你会发现这就是一个噩梦:

  • 结构的逻辑变的相当复杂,而且难以分离
  • code review变得困难,让质量无法保证,代码难以维护

能不能让这个事情变的更简单一些呢?看看内核的红黑树和链表:

  • 链表
    • http://lxr.free-electrons.com/source/include/linux/list.h
  • 红黑数
    • http://lxr.free-electrons.com/source/include/linux/rbtree.h
    • http://lxr.free-electrons.com/source/lib/rbtree_test.c

一旦你习惯了这种设计模式,会发现它很有好处,而且可以轻松巧妙的解决很多问题。例如,在网络编程中,定时器是频繁被用到的一个组件,你会怎么设计它?

nginx slab管理

今天在看一个开源的内存管理,https://github.com/flygoast/flib/blob/master/src/slab.c#L296

有几个地方比较难理解,记录一下,代码在 void *slab_alloc_locked(slab_pool_t *pool, size_t size) 函数里

if (page) { if (shift < slab_exact_shift) { p = (page - pool->pages) << pagesize_shift; bitmap = (uintptr_t*)(pool->start + p); s = 1 << shift; n = (1 << (pagesize_shift - shift)) / 8 / s; if (n == 0) { n = 1; } bitmap[0] = (2 << n) - 1; map = (1 << (pagesize_shift - shift)) / (sizeof(uintptr_t) * 8); for (i = 1; i < map; ++i) { bitmap[i] = 0; } page->slab = shift; page->next = &slots[slot]; page->prev = (uintptr_t) &slots[slot] | SLAB_SMALL; slots[slot].next =

»» 继续阅读全文

cpeh: a scalable, high-perormance distributed file system

  1. system architecture
  2. system overview
    1. the ceph file system has three main components:
      • client: each instance of which exposes a near-POSIX file system interface to a host or process
      • osd cluster: sotres all data and metadata
      • mds cluster: manages the namespace(file names and directories) while coordinating security, consistency and coherence.
    2. primary goals
      • scalability: to hundreds of petabytes and beyond, considered in a variety of dimensions, including the overall storage capacity and throughput of the system.
      • performance: out target workload may include such extreme cases as tens or hundreds of thousands

        »» 继续阅读全文

多进程共享socket之close调用

当父子进程共享一个socket描述符时,如果其中一个进程执行close调用,那会不会发送FIN包,进而影响另一个进程的其他相关操作?只会减少引用计数,没什么其他的操作。

看下源码,可以顺着以下的调用栈看:

close ------------ open.c __close_fd ---- fs/file.c filp_close ---------- fs/open.c fput ------ fs/file_table.c __fput ---------- fs/file_table.c (the last op)

首先socket描述符本身也属于Unix文件的一种,其文件相关的file_operations实现在net/socket.c源文件,如下:

/* * Socket files have a set of 'special' operations as well as the generic file ones. * These don't appear in the operation structures but are done directly via the socketcall() * multiplexor. */ static const struct file_operations socket_file_ops = { .owner = THIS_MODULE, .llseek = no_llseek, .aio_read = sock_aio_read, .aio_write = sock_aio_write, .poll = sock_poll, .unlocked_ioctl = sock_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = compat_sock_ioctl, #endif .mmap = sock_mmap, .open = sock_no_open, /* special open code to disallow open

»» 继续阅读全文

第 6 页,共 13 页« 最新...45678...最旧 »