Apr 20
4月7日星期六在武大国际软件学院参加的笔试。投的是软件开发工程师。
试卷是全英文的,20道多项选择题。这里是试题。
因为答错了要减分,所以不确定的就没有填。
本来不报什么希望的,没想到一个星期之后收到了面试通知。

这个星期一直在搞django。没怎么准备,也不知道准备什么。下午四点的面试,路上车子超级堵,差点迟到了。
到4点钟了,HRmm把我引到一个房间开始面试。
面试官挺没什么特别的,一上来让我自我介绍,我也不知道说什么,就说了些废话,学校,名字。
我这个还真是个木头。
他问:然后呢?
我回答:没有然后。

让我把简历拿出来,看着我的简历就说当时看到我的简历很简洁,就一张纸,也没有过多的说明,觉得我这个人挺特别的。
我说写多了也没什么用。
然后说我就是不太注重细节,原来我打印的简历上面联系地址占用了两行,字体也有点问题。
唉,匆忙打印的,也没注意那么多。

问我英文怎么样?我说阅读,收/回复邮件没问题,又问我六级多少分,真不好意思跟他说啊。
然后让我说几句英语,结结巴巴,说一句:I like sports。!!太丢人了。
他也没为难我,拿了张草稿纸就让我写个atoi()函数。
噼里啪啦写完了,想给他看,他让我仔细检查,一定要考虑完善。
之后在提醒写完善了正负号,溢出点问题。

问我知道了解OO不,我说没怎么用过C++,java。
讨厌C++,不过挺喜欢Python的,他也觉得python挺美的。

问我知不知道虚函数是什么东西?
C++,好久没看过了,真不知道虚函数是干什么的。他就知道了:我确实不会c++。

之后主要是针对简历上的东西问。
看到我本科在腾讯财付通实习过,就问了我做什么。我跟他说了是优化网站性能。然后他问我怎么优化的。
当时就是在学习那个网站的代码,找出瓶颈是在查询上面,主要就是优化SQL语句。

看我对操作系统有所研究,就说问个系统问题。
malloc函数调用什么?(本来是说new的,我说:new?他才改说malloc的)
我只知道好像是调用brk,他问我brk做了什么,我就不知道了。
他就开始教育我了:不能只知道几个命令,会用,还要知道原理。
我也知道啊,原理学了不怎么用容易忘,对于现阶段的我,原理知道个大概就可以了。

又问了我web服务器怎么实现的。
我就说在linux下面用c语言socket实现的,实现了GET,POST方法,CGI和fastCGI。
他问我怎么提高性能,我说改进并发模型。他问我怎么改进。
我就用多进程,多线程,进程池,epoll等。

最后聊到python,我就说我正在用django写一个网站,顺便学习python。
是一个预约网站,在一个时间段访问量很大,大多数时候没什么人访问(类似12306)。他就问我怎么解决这个问题,
我就说用分两个方面1.服务器配置2.网站程序设计
网站程序方面:
1.使用ajax避免重复拉取数据。
2.优化数据库设计
本来想说cache,实在想不出cache什么原理,就没说了。
最后我说看过coolshell写过一篇分析这个问题的文章。然后他说他也看过,问我平时上网都看些什么。
我说看些牛人的博客。比如coolshell,刘未鹏,Matrix67等。听到Matrix67,他来劲了,说你也知道他?囧
那考你个数据结构的题:怎么从一个数组中去除重复的项?
我想了想,想到了
1.排序
2.hash
3.bitmap
不知道为什么,觉得hash不怎么好用,bitmap太占用空间,就没跟他说了(有点懊悔,至少也该跟面试官司交流下)。
我一直在想其它O(n)的方法,不占用太多空间。
最后实在想不出来,就跟他说了边排序,边判断。(比如用选择排序)
他问我时间复杂度,我就说等于排序的时间复杂度。
让我写出来代码,当时我真不想写代码,就说写不出来,最后就没写了。

最后好像HR有什么事,他让我等5分钟,不一会HRmm进来说,面试结束了,晚上会通知结果。

之间看过微软面试的一些有意思的题目,本来很期待有这样的题目的。
结果根本就没有,由于面试意外中止,也没有机会向面试官求解。
对于此次面试,难说满意 。
面试官问的所有问题,我几乎都没有进行深入的分析,只是回答了表面的东西。
理论不行,实践也不行,差距很大啊!
看来还是平时还是要多总结
一个项目做完了,要及时总结收获。
Sep 20

M67的那篇文章在这:http://www.matrix67.com/blog/archives/1598
很久之前就转到自己博客上来了,在这里,当时也没细看,当然也没看明白。
今天仔细分析了下,终于明白怎么回事了。
先用字符串“I love you to death! You are the cutest and sweetest girl I've ever met.”生成程序为:

     #include      <stdio.h>
   main(t ,_,a)  char*a;{return
 t<1?main(*a,a[-t],"=a-1kj3gnm:q\
ebh_cf*<r.d>i^+?,()[?qzyrjuvcdefg\
h,!kbpolwxs'.t main(")&&a[-t]&&main
(t-1,_,a):t/2?_==*a?putchar(32[a])
  :_%115<36||main(t,_,a+1):main(
    0,t,")?r<g:?1<3?+<#?#m:}(\
      w+b_?1<}3?tt(yk:?+|b:\
        ?n3+:>+?([m?>.::+\
          :>+?e)kr?)ig{\
            :?y:~g:k?\
              ,:+^")
                ;}

是一个很漂亮的心形,用gcc编译执行输出:

i love you to death! you are the cutest and sweetest girl i've ever met.#

Sep 20

     前段时间花了三天时间把买了好久《大话设计模式》看了一遍。

     我是先看的附录,也就是面向对象基础。
     这是一本通俗易通的好书,毋庸置疑。看完之后至少有三个收获:
1.对面向对象语言编程(书中用的是C#)有更深的理解。
       面向对象三大特性:封装,继承,多态。
       抽象类与接口是什么?
       泛型,事件,委托与代理。
    真如书中所说,看完比上一个月课,读几本砖头书印象深,理解透。
不是说看完了就学到很多东西,而是看完之后你会有“原来如此”感觉,理解了基础,再深入就不是问题。
2.UML类图
  UML包含的东西当然很多,但书中用一例子就把类图继承,依赖,接口等等基本要素都讲到了,
至少让你我这个从没用过UML的人,看到类图能明白是什么意思。
3.设计模式及面向对象原则
  全书围绕大鸟和小菜,讲解了GOF的23个设计模式+简单工厂模式,及面向对象的四大原则+其它几个原则。

  单一职责,开放-封装,依赖倒转,里氏代换是面向对象编程之所以有效的原则,它们让软件系统是可复用,可维护,可扩展,灵活性好的。也是这些设计模式所遵守的原则。

     看完了,想想应该练习下。可书中都是用面向对象语言实现的(C#,Java等)。可我不怎么用面向对象语言,我就想用C语言来
实现它们。可C语言如何面向对象呢?之前看过有用结构来模拟实现类的,但继承,多态这些怎么弄呢?想起了很久以前瞄过的一本书《OOC》,讲的是用标准c实现面向对象。把c和对象放在一起,大家就会想起C++,是啊!有C++不就行了,为什么要折腾c呢?可就是有很多人对c++不满意,Linux之父Linus就是力挺C而批判C++的。讨厌C++的人似乎认为C++过于复杂,内部机制陷阱过多等等。OOC作者也是由于对c++不满足而转向c。

OOC这本书中主要讲了以下两点:一个发现,一个实现。
1.发现c是完全面向对象的
2.利用c实现面向对象(这里不是用c实现一个面向对象的语言,而是就是用c实现面向对象)
从抽象数据类型说起,到面向对象的要素讨论,最后提出自己的对象模型,推导出了一个类树。包括对象,类,继承,多态,最后还实现了类型检查,异常处理。为了方便编程,作者实现了一个预处理器。这本书对理解面向对象原理,很有帮助。
这里有本书的原文和部分译文下载:http://wiki.chinaunix.net/OOC
我开始看前几章觉得很晦涩难懂,硬着头皮,中文加英文看下去,搞清楚了大概思路,作了一些变化,
自己也写了一个预处理器玩了下,现在也可以很容易定义类,实现继承、多态等。

     后来搜索“面向对象理论”,发现一篇自称是扯淡的文章:http://www.iteye.com/topic/89241
我觉得这文章还是很有启发意义的,至少知道了面向对象的历史,发展,知道了有类,无类语言,3P和4P的概念。

     看了评论发现《程序设计--实践之路》这本书,这是本讲如何设计语言的书,从编译原理,语言发展,到语言的各种要素。
大概看了下里面“10.数据抽象和面向对象”一章,才知道从基本类型(整数,浮点),函数类型,结构类型,后来发展出
模块类型,按理论,类是从模块类型发展而来,面向对象也应该按此发展。可事实上面向对象的基本要素都是从20世纪60年代
开发的simula语言中来的。

     关于c语言实现面向对象,最经典的应该是gtk+了,一个基于C语言的面向对象的图形编程环境。
其中GOjbect就是基于C语言的面向对象的实现,它和glib是gtk+的两大基石。
这里面有很多关于GObject的文章:http://ekd123.is-programmer.com/posts/28754.html
什么时间好好学习下GObject了。

Oct 19

typeof关键字是C语言中的一个新扩展。

typeof的参数可以是两种形式:表达式类型
下面是使用表达式的的例子:
    typeof(x[0](1)
这里假设x是一个函数指针数组,这样就可以得到这个函数返回值的类型了。
如果将typeof用于表达式,则该表达式不会执行。只会得到该表达式的类型。
以下示例声明了int类型的var变量,因为表达式foo()是int类型的。由于表达式不会被执行,所以不会调用foo函数。
   extern int foo();
   typeof(foo()) var;

下面是用类型作参数的例子:
   typeof(int *) a,b;
等价于:
   int *a,*b;

下面是两个等效声明,用于声明int类型的变量a。
   typeof(int) a; /*int类型*/
   typeof('b') a; /* GCC中这个表达式的类型是int(自动提升为int),
                  注意typeof(char)和typeof('b')得到的不是一样的,这个用sizeof可以看出来*/

Apr 27

其实这里讲的不是用C语言来实现面向对象,只是用了一点点面向对象的思想,来进行分层的模块化设计与简单的封装。

这里把一个软件分成了三层,用户层,接口层与实现层。上面是我自己根据理解自己起的名字。

还可以进行一下类比,就是用户,品牌P collapsedC厂商和硬件生产商。下面详细讲解:

首先是用户层:

#include "stdio.h"
#include "stdlib.h"

int main(void)
{
    printf("system start...\n");
	if (mod_init("mod_finished")<0) {
		exit(0);
	}
	mod_operation_1(0,1,2);
	mod_operation_2(0,1,2);
	mod_operation_3(0,1,2);
    return 0;
} 

Apr 27

注:这个程序是在软件设计师教程上看到,并做了一点点修改得到。。

在一个简化的绘图程序中,支持点(point)和圆(circle)两种图形,在设计过程中采用面向对象思想,认为所有的点和圆都是一种图形(shape),

并定义类型shape_t、point_t、circle_t分别表示基本图形、点和圆,点和圆自然具有基本图形的所有特征。

下面是利用C语言,通过函数指针和可变参数机制实现上面的类层次关系:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

// 程序中的两个图形:点和圆
typedef enum {point,circle}shape_type;
// 基本图形类型
typedef struct {
	shape_type type;
	void (*destroy)();
	void (*draw)();
}shape_t;
// 点类
typedef struct {
	shape_t common;
	int x,y;
}point_t;
// 圆类
typedef struct {
	shape_t common;
	point_t *center;
	int radius;
}circle_t;
/*

Apr 27
 // 一般使用方法
// #include <stdarg.h>
// void some_function(type1 var1,type2 last,...)
// {
//     va_list ap;
//     va_start(ap,last);
//     ...
//     typex var=va_arg(ap,typex);
//     ...
//     va_end;
//     return;
// }

// stdarg.h
// va_list 其实就是一个字节指针
typedef char *va_list;

// _va_size(type)总是4的倍数,因为系统在处理压栈的时候总是4字节对齐的。
#define	__va_size(type) \
	(((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))

// last是最后一个压栈的参数(也是第一个已知类型的参数),ap指向其后一个参数,即可变参数开始的地方。
#define	va_start(ap, last) \
	((ap) = (va_list)&(last) + __va_size(last))

// 得到类型为type的参数,并使ap指向下一个参数。
#define	va_arg(ap, type) \
	(*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))

// 为了结构的完整性而定义。
#define	va_end(ap)	((void)0)