Apr
26
由于是报名截止前两个小时才想起去注册的,于是赶紧先注册了队伍,顺手就把Land填上去了。
然后再给Eire打电话,问他有没有参加,是不是要参加,才把他的信息要了补充进去,嗯。
早上一觉睡到12点十几,随便买了点东西赶过去,然后才发现没有拿筷子- - 抑郁
比赛8题,于是我看前ABCD,Eire负责EFGH。看完以后觉得ABF比较有搞头,虽然A题6min就有人出了。因为Eire考研也很久了,对概率论没啥印象了,我就更没印象了,因此先搞F,一个简单的BFS。
Eire很快就写完了,通过测试样例,准备提交,我说等等,测一下19 0 0,然后果断RE。检查了一下,发现是BFS实现的小错误,先搜索后标记,导致重复搜索,栈溢出。修正以后Eire又提出了其他几组简单的测试数据,比如只有一个点等。提了Clar,但是Judge的回复很无厘头,导致我们对题意完全无法理解。
其间我仔细看了G题和A题。对G题推导出了模拟方式,其实就是把所有的格子从后往前,从下往上,从左往右依次画上去就行了,并推出了格子坐标的计算公式;对于A题,虽然没想出靠谱的计算方式,但是发现了一个暴力解法。
由于F题被Judge搞抑郁了,1h30m的时候决定开始写A题,通过开一个50,000*40的数组暴力了30个数据打表,几经修正,提交,2h的时候AC。
因为需要去参加tx的面试,于是先闪人。其后大约一个小时的时间里,Eire根据我的思路把G题大致实现了,我3h的时候赶回来坐下两分钟,就得到了第二个气球。
然后发挥在校赛时锲而不舍的精神继续诘问Judge,迫使judge无奈地返回一个sorry,然后再问其他曾经返回错误的Clar,于是一切明朗。把1多小时前的那段代码叫上去,AC。
剩下的半个多小时看B题。写了一些F(N, P)的公式,但是写着写着发现错了。后来跟Eire又讨论了一下,改完只有不到2min了,还没测就赶紧先提交了,结果不小心交到F题- -| 再准备提交,就已经STOP了,悲痛欲绝啊。然后测了一下,发现还是WA =。= 作罢。
-----分割线-----
总的来说这次比赛的题目不难,如果Judge没有搞出那点事情、中途没有离开一个小时去面试,那么我们做出4题的概率还是比较高的,尤其是B题已经有比较成熟的想法了。不过另一方面也暴露出我和Eire对校赛那个质数题的不重视,如果校赛之后能把那题搞出来,这次就铁定四题了,挺遗憾的。
不过就像每次比赛一样,我的参赛主旨总是开心第一,成绩第二,虽然最后在Rank6可能还没有奖金甚至名次(国软也太抠门了吧。。。),但是能够有机会参加这个曾经帮了一年、参加了一年的比赛,还是很开心的,尤其是和老队友(3年半了!)Eire组队,每次都很开心:)
最后,希望WHUACM能够走得更远,够好。
然后再给Eire打电话,问他有没有参加,是不是要参加,才把他的信息要了补充进去,嗯。
早上一觉睡到12点十几,随便买了点东西赶过去,然后才发现没有拿筷子- - 抑郁
比赛8题,于是我看前ABCD,Eire负责EFGH。看完以后觉得ABF比较有搞头,虽然A题6min就有人出了。因为Eire考研也很久了,对概率论没啥印象了,我就更没印象了,因此先搞F,一个简单的BFS。
Eire很快就写完了,通过测试样例,准备提交,我说等等,测一下19 0 0,然后果断RE。检查了一下,发现是BFS实现的小错误,先搜索后标记,导致重复搜索,栈溢出。修正以后Eire又提出了其他几组简单的测试数据,比如只有一个点等。提了Clar,但是Judge的回复很无厘头,导致我们对题意完全无法理解。
其间我仔细看了G题和A题。对G题推导出了模拟方式,其实就是把所有的格子从后往前,从下往上,从左往右依次画上去就行了,并推出了格子坐标的计算公式;对于A题,虽然没想出靠谱的计算方式,但是发现了一个暴力解法。
由于F题被Judge搞抑郁了,1h30m的时候决定开始写A题,通过开一个50,000*40的数组暴力了30个数据打表,几经修正,提交,2h的时候AC。
因为需要去参加tx的面试,于是先闪人。其后大约一个小时的时间里,Eire根据我的思路把G题大致实现了,我3h的时候赶回来坐下两分钟,就得到了第二个气球。
然后发挥在校赛时锲而不舍的精神继续诘问Judge,迫使judge无奈地返回一个sorry,然后再问其他曾经返回错误的Clar,于是一切明朗。把1多小时前的那段代码叫上去,AC。
剩下的半个多小时看B题。写了一些F(N, P)的公式,但是写着写着发现错了。后来跟Eire又讨论了一下,改完只有不到2min了,还没测就赶紧先提交了,结果不小心交到F题- -| 再准备提交,就已经STOP了,悲痛欲绝啊。然后测了一下,发现还是WA =。= 作罢。
-----分割线-----
总的来说这次比赛的题目不难,如果Judge没有搞出那点事情、中途没有离开一个小时去面试,那么我们做出4题的概率还是比较高的,尤其是B题已经有比较成熟的想法了。不过另一方面也暴露出我和Eire对校赛那个质数题的不重视,如果校赛之后能把那题搞出来,这次就铁定四题了,挺遗憾的。
不过就像每次比赛一样,我的参赛主旨总是开心第一,成绩第二,虽然最后在Rank6可能还没有奖金甚至名次(国软也太抠门了吧。。。),但是能够有机会参加这个曾经帮了一年、参加了一年的比赛,还是很开心的,尤其是和老队友(3年半了!)Eire组队,每次都很开心:)
最后,希望WHUACM能够走得更远,够好。
Apr
18
由于开学以来一直在开发我们的WOJ-Land,所以组队的时候起名就直接用了Land,两个队友还是很支持的,嗯。。
预赛的时候,由于回老家扫墓,只能和两位队友异地交流做题,非常遗憾,而且由于没有什么会做的,也没能帮上忙。
不过还好校内队伍门槛低,虽然排名119,还是进了决赛:D
昨天的练习赛,也一样没啥会的,只能帮忙DEBUG,而且最后还是因为算法错,只AC了最简单那题。
今天的决赛就更囧了。7点45的闹钟,摁掉继续睡到8点10分,然后急急忙忙赶到现场,wcb同学更杯具地把手机扔厕所里了,还好都有惊无险及时赶到。开赛后按3,3,4分题给zhf、wcb和我,分别看题。同时强烈关注board,期望有个明星队伍赶紧出个简单题让我们能跟上,结果发现盯到了30+min才有人出题,Orz出题那帮家伙。
然后发现里面所有的题目里面,有思路的就只有A题:计算器模拟。大致列了一下,然后上去写。最初是用一堆flag来记录状态,发现写着写着就乱的一塌糊涂了。期间wcb看了E题麻将,觉得可写。于是打印代码,换wcb上去写。然后重新构思了一下题目的算法,在找到一个很清晰的思路,于是趁着wcb的E题卡住的时段继续写A。很快写完,然后对着PC^2里面所有关于A题的Clar测试自己的代码,修正了N多错误。提交,WA。修正,提交Wa....甚至还搞个随机生成数据的程序来测试....
于是再换wcb,我和zhf则去考虑其他的题目。中间还看了B题,看错题意,误导zhf跟我一起很happy地分析,然后提交,WA。时间如流水哗啦啦,突然发现已经封board了。wcb的E题几经修改,终于提交了,WA。 检查后发现,多输出了个\b呢。然后wcb说,他想用\b来删除行末的空格
改了再提交又WA,因为行末空格还是没有处理....终于在封board 8min以后,AC了这道题。
然后本来想在考虑考虑B题的,虽然有些头绪,但是离结论还远。于是zhf建议继续搞A题。在反复地测试了n个数据以后突然灵光一闪,会不会有空行捏?于是提交了一个Clar, will there be an empty line as case input? XE的Judge回复,"No response. Read the problem statement",我怒啊,再提 "Only 'less than 100' is provided, no proof that can be or can not be of length 0'。XE的Judge(后来才知道是加菲)继续忽悠我, "What do you mean?"。于是我锲而不舍地提第三个Clar,Judge才被迫无奈地说,Perhaps。于是马上改,测试,提交。这个时候离比赛只有12min的时间了,在Land队到了最危险的时候,我们被迫着发出最后的吼声:来个球!于是真的就来了个球.....然后我们很happy地向气球mm打招呼表示欢迎,但是她不鸟我们=。=
然后也没什么好想的了,收拾东西,等待比赛结束......
这场比赛真是有惊无险,到封board的时候还一直没有出题,我甚至一度以为我们队出不了题了,超囧。不过还好,在我们的坚持下,中算是A了2题,保住了校内的铜奖~~~
回头想想,觉得比赛的时候,尤其是对于实力不很强的队伍,有几点还是很值得注意的
1. 保持良好的心态
整个比赛过程中我们都没有太急躁的表现,做题气氛一直很好,就算是WA了好几次,也没有太大影响。这对最后一个小时的表现影响是很大的。
2. 坚持
赛后momo在群里点名批评了cw同学,说他从来没有坚持完一场比赛。也许是OI后遗症吧,但是对于希望参与ACM赛事的队员/队伍,把一场赛事坚持下来,应该是个最基本的要求。今天比赛结束即将的时候还有一支队伍A题,狂喜拥抱,以至路过围观的不明真相的群众都被感动得纷纷鼓掌。
3. 适度的自信
对于每个人,都有些题目可做,有些题目不可做。坚持自己可做的题目,放弃自己不可做的题目。虽然过A题的队伍很少,但是还好最后我们没有放弃A题,才终于能出。
4. 写题前的基本准备
把自己的思路写一写,尤其是要和队友说清楚。如果没能说清楚就开始写,很可能会导致写的时候卡住,然后发现算法不对,或者代码混乱.....这个可能主要是在说我自己,嗯。
最后,觉得自己最近OJ写了这么久,思考问题也相对周全了不少,才能把A题写出来,甚至发现A题数据中可能存在的trick。
OVER.
预赛的时候,由于回老家扫墓,只能和两位队友异地交流做题,非常遗憾,而且由于没有什么会做的,也没能帮上忙。
不过还好校内队伍门槛低,虽然排名119,还是进了决赛:D
昨天的练习赛,也一样没啥会的,只能帮忙DEBUG,而且最后还是因为算法错,只AC了最简单那题。
今天的决赛就更囧了。7点45的闹钟,摁掉继续睡到8点10分,然后急急忙忙赶到现场,wcb同学更杯具地把手机扔厕所里了,还好都有惊无险及时赶到。开赛后按3,3,4分题给zhf、wcb和我,分别看题。同时强烈关注board,期望有个明星队伍赶紧出个简单题让我们能跟上,结果发现盯到了30+min才有人出题,Orz出题那帮家伙。
然后发现里面所有的题目里面,有思路的就只有A题:计算器模拟。大致列了一下,然后上去写。最初是用一堆flag来记录状态,发现写着写着就乱的一塌糊涂了。期间wcb看了E题麻将,觉得可写。于是打印代码,换wcb上去写。然后重新构思了一下题目的算法,在找到一个很清晰的思路,于是趁着wcb的E题卡住的时段继续写A。很快写完,然后对着PC^2里面所有关于A题的Clar测试自己的代码,修正了N多错误。提交,WA。修正,提交Wa....甚至还搞个随机生成数据的程序来测试....
于是再换wcb,我和zhf则去考虑其他的题目。中间还看了B题,看错题意,误导zhf跟我一起很happy地分析,然后提交,WA。时间如流水哗啦啦,突然发现已经封board了。wcb的E题几经修改,终于提交了,WA。 检查后发现,多输出了个\b呢。然后wcb说,他想用\b来删除行末的空格
改了再提交又WA,因为行末空格还是没有处理....终于在封board 8min以后,AC了这道题。
然后本来想在考虑考虑B题的,虽然有些头绪,但是离结论还远。于是zhf建议继续搞A题。在反复地测试了n个数据以后突然灵光一闪,会不会有空行捏?于是提交了一个Clar, will there be an empty line as case input? XE的Judge回复,"No response. Read the problem statement",我怒啊,再提 "Only 'less than 100' is provided, no proof that can be or can not be of length 0'。XE的Judge(后来才知道是加菲)继续忽悠我, "What do you mean?"。于是我锲而不舍地提第三个Clar,Judge才被迫无奈地说,Perhaps。于是马上改,测试,提交。这个时候离比赛只有12min的时间了,在Land队到了最危险的时候,我们被迫着发出最后的吼声:来个球!于是真的就来了个球.....然后我们很happy地向气球mm打招呼表示欢迎,但是她不鸟我们=。=
然后也没什么好想的了,收拾东西,等待比赛结束......
这场比赛真是有惊无险,到封board的时候还一直没有出题,我甚至一度以为我们队出不了题了,超囧。不过还好,在我们的坚持下,中算是A了2题,保住了校内的铜奖~~~
回头想想,觉得比赛的时候,尤其是对于实力不很强的队伍,有几点还是很值得注意的
1. 保持良好的心态
整个比赛过程中我们都没有太急躁的表现,做题气氛一直很好,就算是WA了好几次,也没有太大影响。这对最后一个小时的表现影响是很大的。
2. 坚持
赛后momo在群里点名批评了cw同学,说他从来没有坚持完一场比赛。也许是OI后遗症吧,但是对于希望参与ACM赛事的队员/队伍,把一场赛事坚持下来,应该是个最基本的要求。今天比赛结束即将的时候还有一支队伍A题,狂喜拥抱,以至路过围观的不明真相的群众都被感动得纷纷鼓掌。
3. 适度的自信
对于每个人,都有些题目可做,有些题目不可做。坚持自己可做的题目,放弃自己不可做的题目。虽然过A题的队伍很少,但是还好最后我们没有放弃A题,才终于能出。
4. 写题前的基本准备
把自己的思路写一写,尤其是要和队友说清楚。如果没能说清楚就开始写,很可能会导致写的时候卡住,然后发现算法不对,或者代码混乱.....这个可能主要是在说我自己,嗯。
最后,觉得自己最近OJ写了这么久,思考问题也相对周全了不少,才能把A题写出来,甚至发现A题数据中可能存在的trick。
OVER.
Mar
29
@2010-10-30 建議看 加強版: http://www.felix021.com/blog/read.php?1921
用VirtualBox在Windows上搭建一个Ubuntu工作站
目标
1. 没有多余窗口
2. Ubuntu少占资源
3. Ubuntu可以上外网
4. 可以ssh连上去搞开发
实现
1. 在Vbox上安装一个Ubuntu
2. 整两个网卡,一个host-only,一个NAT。
3. 安装好ssh-server
4. 如果有gdm(desktop/alternative),干掉 sudo update-rc.d -f gdm remove; cd /etc/X11/,在default-display-manager的第一行(gdm)前加个#注释掉
5. 编译这个东西,可执行程序放到program files\sun\virtualbox\下面,比如叫做startvm
7. 打开SecureCRT连上去干活吧
8. 可以使用VBoxManage controlvm "虚拟机名" start|poweroff|pause|resume|savestate...等来控制虚拟机的运行状态
其他
1. 如果需要开机自启动,稍微改改这个程序或者搞个bat扔到startup里面去,或者干脆注册一个服务。
用VirtualBox在Windows上搭建一个Ubuntu工作站
目标
1. 没有多余窗口
2. Ubuntu少占资源
3. Ubuntu可以上外网
4. 可以ssh连上去搞开发
实现
1. 在Vbox上安装一个Ubuntu
2. 整两个网卡,一个host-only,一个NAT。
3. 安装好ssh-server
4. 如果有gdm(desktop/alternative),干掉 sudo update-rc.d -f gdm remove; cd /etc/X11/,在default-display-manager的第一行(gdm)前加个#注释掉
5. 编译这个东西,可执行程序放到program files\sun\virtualbox\下面,比如叫做startvm
#include <iostream>
#include <windows.h>
using namespace std;
int main(int argc, char * argv[])
{
string param = string(" -startvm ") + argv[1];
ShellExecute(NULL, "open",
"vboxheadless", param.c_str(),
"c:", SW_HIDE); //使用SW_HIDE就不会看到vboxheadless的命令行窗口了
return 0;
}
6. 运行 startvm "虚拟机名" #include <windows.h>
using namespace std;
int main(int argc, char * argv[])
{
string param = string(" -startvm ") + argv[1];
ShellExecute(NULL, "open",
"vboxheadless", param.c_str(),
"c:", SW_HIDE); //使用SW_HIDE就不会看到vboxheadless的命令行窗口了
return 0;
}
7. 打开SecureCRT连上去干活吧
8. 可以使用VBoxManage controlvm "虚拟机名" start|poweroff|pause|resume|savestate...等来控制虚拟机的运行状态
其他
1. 如果需要开机自启动,稍微改改这个程序或者搞个bat扔到startup里面去,或者干脆注册一个服务。
Mar
27
注:以下测试都是在Ubuntu 9.10 + Gcc 4.4下测试。
1.c
2.c
说明如果没有return语句,那么返回值应该是不确定的。
3.c
增加一个程序test.c
分别运行1.c 2.c 3.c编译后的可执行程序,可以发现,1.exe的返回值是不确定的,但末2位都是0; 2.exe的返回值总是0; 3.exe的返回值总是0 。如果修改2.c的return 0为return 1或2,又或者修改3.c里面的 $0 为 $1 或者 $2 ,可以发现返回值就变成了 100 和 200。这说明在x86下,主函数结束后会将返回值存放在EAX这个寄存器中。
1.c
int main(){}
$ gcc -S 1.c .file "1.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section .note.GNU-stack,"",@progbits
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
popl %ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section .note.GNU-stack,"",@progbits
2.c
int main(){ return 0; }
$ gcc -S 2.c .file "2.c"
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section .note.GNU-stack,"",@progbits
.text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
movl $0, %eax
popl %ebp
ret
.size main, .-main
.ident "GCC: (Ubuntu 4.4.1-4ubuntu9) 4.4.1"
.section .note.GNU-stack,"",@progbits
说明如果没有return语句,那么返回值应该是不确定的。
3.c
int main() {__asm__("movl $0, %eax"); }
增加一个程序test.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
int s = system("./1.exe");
printf("return: %x\n", s); //16进制输出
return 0;
}
#include <stdlib.h>
int main()
{
int s = system("./1.exe");
printf("return: %x\n", s); //16进制输出
return 0;
}
分别运行1.c 2.c 3.c编译后的可执行程序,可以发现,1.exe的返回值是不确定的,但末2位都是0; 2.exe的返回值总是0; 3.exe的返回值总是0 。如果修改2.c的return 0为return 1或2,又或者修改3.c里面的 $0 为 $1 或者 $2 ,可以发现返回值就变成了 100 和 200。这说明在x86下,主函数结束后会将返回值存放在EAX这个寄存器中。
Mar
26
php用fsockopen打开的fp是行缓冲的, 想要数据立即发送到服务器, 就在每次fwrite的数据后面加一个\n。
php的fwrite是atomic的。
java的wait()和notify()是任何对象(基本数据类型不行)都可以用的, 因为每个对象都有一个锁。在针对对象x的时候, 必须处于synchronized(x){}代码段内使用,否则会抛出一个 IllegalMonitorStateException: Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
java的finalize不是析构函数, 只有gc运行起来的时候才可能会调用到它, 而且还不能继承。不能完全依赖它来作一些对象结束时本该作的事情。比较靠谱但是又比较丑陋的是用try-catch-finally来完成。
在linux下如果先chroot再getpwnam失败, 很可能是因为chroot以后就找不到/etc/passwd了。TODO chroot以后无法调用可执行程序的问题还需要再了解一下原因。
WIFEXITED/WIFSIGNALED等宏的详细说明在man 2 wait里面。
ptrace捕获到的每个syscall大部分都有进和出2次;除了execve, 只有一次。
用这个命令来计算代码行数。@3-25目前的结果是4741行。
php的fwrite是atomic的。
java的wait()和notify()是任何对象(基本数据类型不行)都可以用的, 因为每个对象都有一个锁。在针对对象x的时候, 必须处于synchronized(x){}代码段内使用,否则会抛出一个 IllegalMonitorStateException: Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
java的finalize不是析构函数, 只有gc运行起来的时候才可能会调用到它, 而且还不能继承。不能完全依赖它来作一些对象结束时本该作的事情。比较靠谱但是又比较丑陋的是用try-catch-finally来完成。
在linux下如果先chroot再getpwnam失败, 很可能是因为chroot以后就找不到/etc/passwd了。TODO chroot以后无法调用可执行程序的问题还需要再了解一下原因。
WIFEXITED/WIFSIGNALED等宏的详细说明在man 2 wait里面。
ptrace捕获到的每个syscall大部分都有进和出2次;除了execve, 只有一次。
用这个命令来计算代码行数。@3-25目前的结果是4741行。
引用
find -regex ".*\.\(java\|cpp\|c\|h\|sh\|css\|js\|php\)" -exec wc -l {} \; | awk '{sum+=$1}END{print sum}'
Mar
22
就是前面那个 c/c++版 logger.h 到php的移植。使用基本一致。
代码详见: http://code.google.com/p/woj-land/source/browse/trunk/code/web/lib/logger.lib.php
另附针对此日志格式的php写的查看工具:
http://code.google.com/p/woj-land/source/browse/trunk/tools/logviewer/
代码详见: http://code.google.com/p/woj-land/source/browse/trunk/code/web/lib/logger.lib.php
另附针对此日志格式的php写的查看工具:
http://code.google.com/p/woj-land/source/browse/trunk/tools/logviewer/
Mar
10
LOGGER v0.0.3
A simple logger for c/c++ under linux, multiprocess-safe
---- CopyLeft by Felix021 @ http://www.felix021.com ----
一个最简单的使用这个日志系统的程序:
@ 2010-03-22 p.s. 增加了php移植版
A simple logger for c/c++ under linux, multiprocess-safe
---- CopyLeft by Felix021 @ http://www.felix021.com ----
一个最简单的使用这个日志系统的程序:
#include "logger.h"
int main()
{
log_open("log.txt");
log_add_info("id:1001");
FM_LOG_DEBUG("test %d", 123);
return 0;
}
记录日志内容为:int main()
{
log_open("log.txt");
log_add_info("id:1001");
FM_LOG_DEBUG("test %d", 123);
return 0;
}
引用
--NOTICE-- [2010-03-10 18:10:18] [logger.h:91] log_open
--DEBUG-- [2010-03-10 18:10:18] [main.c:7] [id:1001] test 123
--NOTICE-- [2010-03-10 18:10:18] [logger.h:99] [id:1001] log_close
--DEBUG-- [2010-03-10 18:10:18] [main.c:7] [id:1001] test 123
--NOTICE-- [2010-03-10 18:10:18] [logger.h:99] [id:1001] log_close
下载文件 (已下载 1896 次)
@ 2010-03-22 p.s. 增加了php移植版
Mar
8
zz from http://bbs.sysu.edu.cn/bbstcon?board=CS&file=M.1267951351.A
发信人: kyhpudding (只要衫除实得~), 信区: CS
标 题: IT 民工男的 CS 课程记忆
发信站: 逸仙时空 Yat-Sen Channel (Sun Mar 7 16:42:31 2010), 转信
先介绍下自己, 03CS 本科
在某更懂中文的地方混了两年多, 做社区产品, 后来做基础平台
带项目带新人前端到后端应用到底层跟各部门死磕无处不折腾
每年都为可以公费回广东回来校招, 据说是杀手, 不过我不觉得
最近在一以企鹅为吉祥物的公司继续折腾
此文仅代表个人观点, 也只包含个人经验
聊聊 CS 本科各种课程对实际工程工作,
更准确点, 对典型互联网行业的工程工作的影响
试图回答: 这些课程有啥用? 以及, 为啥面试会问这种 BT 问题?
不过如果你不希望走技术方向, 或者希望折腾一下技术就"转管理"
请忽略这篇文章
首先是数学, 我本科四年最后悔的事就是没把数学学好. 掩面, 这个问题先不谈.
程序设计, 首先是语言问题. 可能大家会抱怨出来工作基本都是 java C# 了, 为毛
大学还在教 C++, 落后! 好吧, 我最熟悉的语言其实是 C 语言......
我们看程序设计担负的任务. 一方面, 你必须掌握一门跟计算机沟通的语言, 否则后面
的课根本没法学. 另一方面, 通过学习程序设计 --- 而不是某一门特定语言, 掌握一些
基础的设计方法和一些思路, 为进行真正的工程开发做准备.
从掌握计算机原理, 以有效利用计算机的角度考虑, 应该选一门相对低级的高级语言,
这自然是 C, 它对于一些底层问题: 硬件, 数据结构, 底层操作系统机制等
提供了合适程度的抽象, 把我们对计算机的认识从底至上衔接起来: 写汇编时, 你得知道
指令对底层硬件的意义; 同样的, 你需要能把 C 的循环, 数组寻址, 指针在汇编上
到底是什么解释清楚, 你需要知道函数调用压栈的到底是什么数据, memcpy 到底怎么
拷的数据 (经典问题). 到学 OS 时, 如果用 linux (或任何 UNIX-like) 做教材样本,
你得有很扎实的 C 语言功底, 才做得来操作系统实验, 或者至少理解系统调用用怎么
完成. C 是系统底层的标准语言, 扎实的 C 语言基础是了解系统底层原理的
敲门砖, 至于为什么要对这些计算机系统底层如此了解的原因, 我们下面再谈.
另一方面的任务, 涉及到许多人每天的工作 --- 程序设计. 两个分支: 数据结构和算法,
软件设计范式, 抽象, 建模现实世界问题, 提供计算机解决. 这要求有一个能让底层细节
不会阻碍思考, 而且相对实用的语言. 越来越多的大学使用 Java, 当然也有不少人讨厌
这个, MIT 使用 scheme 和 python. 从达到教学要求角度看, 我觉得都没什么问题.
前提就是: 你依然得有很好的 C 语言和其他底层知识基础. 数据结构和算法下面我们
还会说到. 设计范式, 抽象, 建模等问题, 相当地困难 (数据结构也是一种抽象方法).
我那时的程序设计书好像就是讲了一堆 C 的知识, 然后后面附加讲了点 "面向对象设计",
其实是在讲 C++ 的语言特性, 非常生硬难懂. 我觉得首先得解决的是一个关于 "如何
抽象问题, 建立模型" 的问题, 而"面向对象" *仅仅是其中一种可选方法*! 而如何使
用语言特性去实现这些抽象方法, 那更是细枝末节. 在这方面, 我还是觉得 MIT 原
6.001 课程 SICP 做得最好, 逐步引导越来越高层的抽象, 一步步教导经典设计思路,
而不是一次过塞给你一坨似是而非的理论以及非常恐怖的语言特性. 至于 design
pattern --- 专指 GoF, 我认为是应该在有相当的开发经验后自行修炼的, 不适宜在
课堂上讲授.
说回来, 我认为程序设计课应该分成两部分: 为了解计算机系统底层原理准备的 C 课程.
以及为学习计算机的高层理论知识提供趁手的高级语言工具. MIT 以前用 scheme,
现在用 python, 两个课程链接:
6.001 SICP
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-001Spring-2005/CourseHome/in
dex.htm
6.189, 这门课的教材就叫 How to Think Like a Computer Scientist
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-189January--IAP--2008/Course
Home/index.htm
程序设计是一个 *准备* 课程, 好戏在后头. 在实际开发中, 底层我们用 C/C++
应用层我们用 Java PHP Python 等等等等, 还有各种脚本, 甚至自己设计语言. 从语言
角度, 我不认为深入掌握 C 和 Scheme 的人学习任何还算正常的语言会有多难.
至于应用框架/系统, 那是另一个问题, 有兴趣的自行学习, 许多大公司对此自有一套,
大学不是什么培训机构, 要在课堂上讲这些, 会让人笑掉大牙.
数据结构与算法, 这咚咚每天都要跟它打交道. 基础数据结构, 是这行的通用语言. 面试时
要考察 candidate 是否对此熟练掌握, 其重要考虑就是: 不掌握无以沟通. 没人有功夫
跟你解释 B+ 树是怎么回事, 如果我说这个模块维护了个 B+ 树你看着我一面惘然, 那
大家都会很痛苦, That's it. 当然, 有的数据结构, 比如倒排表, 你没听说过我觉得很
正常, 但我可以三言两语就让你明白这是怎么回事, 你可以马上运用它来解决问题, 那就
行了.
算法 --- 参加 ACM 对此有帮助, 但专门钻研算法的奇怪技巧却没太大帮助. 同理, 一些
基础算法, 例如排序, 是行业通用语言, 不掌握无以沟通. 而每个专业分支都会有其专门
的一些算法, 这些也不是本科计算机课程可以和需要教授的, 本来就应该在工作之后再
学习.
但另一方面, 我们往往需要设计算法 --- 往往是某些算法的变体和结合, 我们更往往要
分析算法复杂度 --- 这是个要命问题. 这是可以在课堂上学习到一些基本方法的, 虽然
会令这门课看起来更难, 而且需要更好的数学知识 (知道我为啥后悔了吧, 顺便说一下,
某大牛的观点, CS 数学是应该学数学分析的, 深以为然). 但我认为, 有基础的人就算
不知道某算法, 也会一听就明白, 并能利用. 但算法分析, 这个不抓紧时间在课堂上学
好, 以后就难了.
算法方面还是建议看 Introduction to Algorithms 吧, MIT 课程
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/CourseHome/ind
ex.htm
微机原理/计组/体系结构. 对我来说, 这些课程的作用就是让我知道, 我折腾的拿个铁
盒子到底是怎么一回事. 考虑一些系统性能问题, 做设计权衡时, 我必须考虑实际的计算
机体系, 各部分的性能状况 --- 有了基础, 还要时刻紧跟随摩尔定律发展的潮流. 我们
必须时常考虑, 硬盘的读写特性是怎样的? Cache 能多有效, 怎么利用多核 etc
操作系统原理, 这是一门核心课程. 在我的工作中, 它有两方面用途. 一方面, 为了实现
高效的低层应用, 我需要清楚操作系统的行为, 需要了解我的 API --- 系统调用的实现
原理, 效率情况. 我这行在服务端通常使用 linux 系统, 而 OS 教学在传统上以 UNIX
为范本, 有的甚至直接采用分析 linux 内核的方法, 这就很好地结合起来了. 基本上,
扎实的 OS 知识, 再加上 APUE, linux 系统编程就问题不大了.
OS 也提供了一些常用的概念和抽象方法: 例如锁, 线程和进程. 你会在各种地方碰到他们
你需要利用它, 你有时候需要自己实现它, 你有时候还会发现一个自旋锁耗掉多少 CPU
指令是影响你的程序性能的关键......
另一方面, 可能是大家容易忽视的, 是 OS 乃一门非常重要的工程入门课 --- 我认为这
才是 OS 最大的意义: 开始学习设计实际系统.
- 学习一个真正的大型系统. 真实的操作系统都非常复杂, 你可以看到现实世界的
模块划分和抽象方法, 你可以看到闪光的设计思想 --- 以及一些丑陋的既成事实, 这
比任何一本所谓 "设计方法" 的书都来得精彩. ps. 看看 APUE 吧.
- 分析瓶颈, 考虑权衡: 当你面对的是一个系统而不是一个单一问题点的时候,
分析瓶颈成了一种重要能力. 没有最优算法的说法, 调度方案等等有得必有失, 方案取舍
必须在充分的分析基础上进行. linux 的调度算法, cache 设计是怎么样并不重要.
重要的是: 它为什么要这么设计? 解决什么问题? 这个方案基于什么假设? 对什么有利
而什么不利? 是否与应用模式相吻合? 我们用什么方法来精确测量, 验证这些问题?
这些都是非常重要的工程能力. 我遇到过一位同学, 解决一个模块的性能问题, 上来
看了一通代码, 然后跟我说: 那个函数复杂度是 O(N^2) 可以优化成 O(NLogN) 的,
但实际上那个函数的数据规模只是几十, 更重要的是, 此时模块的瓶颈在 IO. OS 的课程
教会我们这些重要的分析方法, 还有一些非常精妙的设计思路 --- 这会在应用其他地方
用得着.
网络, 这门课同样有两方面意义. 一方面是掌握常识: 我们总得知道什么叫 "四层设备",
总得能分清楚交换机和路由. 当然, 一些网络编程知识也包含其中. 另一方面, 我认为对
协议设计的理解, 尤其是 TCP 设计的理解, 提供了设计分布式系统的基本思路和基本知
识, TCP 的许多设计方法, 在高层次通讯协议的设计中照样适用. 我在文后会给两个例子.
数据库, 我觉得这门课非常难教. 讲理论吧, 讲成数学了. 讲实现吧, 不现实, 讲 SQL?
这不搞笑么? 实际上我们每样都得学点. 数据库跟 OS 课程很相似的一点是: 它是许多
学科重点知识和问题的集中体现, 要看看那些稀奇古怪的知识是怎么用到现实中的?
看看 OS 和数据库吧.
数据库一方面得讲经典的关系理论 --- 基本上只要还是在设计存储系统, 就很难撇得
开它, 这还得有很好的数学基础. 同时也掌握了基本的范式, 基本的设计方法. 在思考
一个实际问题的存储方案时, 这是你的思考起点. 业界这两年流行讲反范式, 或者干脆
讲 NoSQL, No-RDBMS, 不过相信我, 经典的关系理论往往还是你思考的起点.
数据库总会有个地方讲并发, 讲 ACID, 讲事务. 嘿嘿, 欢迎来到业界第一大坑, OS 的
锁知识学好没? 准备了点分布式系统常识没? 准备好了就跳吧. 业界流行对 ACID 进行
取舍, 以达到可扩展性等目的, 我们不是要盲目去接受这些 "流行" 的东西, 我们有
时间在课堂上好好搞清楚 ACID 各为的是什么? 怎么实现? 会有什么问题? 怎么个死锁法?
最好再来点实现内容, 数据库的 index 是个什么原理? 存储具体该怎么实现? 一个查询
语句, 结合 index, 你可以怎么做?
当然我们还是得知道的 SQL 的, 这东西实在太好懂, 表达工具而已, 抠细节则不必.
我想课堂上自然也不会详细讲 MySQL 怎么配置啊, Oracle 有什么 BT 特性啊之类的
东西.
编译原理, 这门课放在本科承载的内容有点杂了. 首先得讲一下基础中的基础, 自动机.
又得讲经典的词法分析语法分析内容. 还得讲怎么编译到机器语言.
从实用角度来讲. 一方面自动机的知识词法语法分析的知识给我们提供解决相关问题
的基本思路 --- 这些都是 CS 最基础的问题. 另一方面就如一开头所说, 我们有时候
不得不设计语言, 在设计语法, 设计解析器的时候, 了解基本的编译原理知识, 并熟练
运用 lex&yacc 成了必须.
至于代码生成的部分, 我不敢说重要性有多高, 但至少我用到过相关的知识.
软件工程, 恕我直言, 这不是应该在 CS 上讲的课程, 至少不应该看得很重. 这有很多
是管理问题, 又有不断更新的新概念, 新理论. 更重要的, 我认为它更多的是 Art,
而不是 Science, 更应该在实际工作中学习积累, 做成选修课不好?
反正放心吧, 无论讲不讲, 你铁定不会一出来就是项目经理的.
我还要推荐 joelonsoftware 的一篇著名文章
Advice for Computer Science College Students
http://joelonsoftware.com/articles/CollegeAdvice.html
最后, 这里提供几个问题, 帮助大家检查一下, 自己的本科学习是否牢固,
以支撑工程需要. 这全部是基本问题, 算法问题就不列了
这不是面试经验, 每个公司的面试都有不同风格,
但解决以下这些问题的能力在我的工作中是必要的.
1. 请实现 memcpy
2. 用 PV 信号量或 mutex, 实现一个读写锁
3. 说说 fread 从一开始到读到磁盘的整个调用过程?
4. malloc 是操作系统内核实现的吗? 实现一对 malloc/free
5. 说说 TCP 三次握手? 为什么是三次? 为什么关闭连接要来四次? SYN Flodd 怎么弄,
怎么预防?
6. 说说 TCP 的滑动窗口机制, 自己实现一下.
7. 设计一个内存垃圾回收方法, 说说它的优势和局限.
8. 假设我已经有一个 B+ 树的存储实现. 请利用它实现一个基本的数据库系统: 针对
某类查询, 如何建 index, 如何执行查询, 如何完成一条更新操作?
补一门 MIT 的工程课, 建议所有希望投入到工程的同学学习
Computer System Engineering
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-033Spring-2009/CourseHome/in
dex.htm
本科的时间, 不花在学习课程上, 去学习某样流行的技术, 也许能令你找到一份令人
羡慕的工作, 但是别怪我乌鸦嘴, 你很快会是那个抱怨知识更新太快, 跟不上,
年纪大了失去竞争力的人.
--
Just for fun
※ 来源:.逸仙时空 Yat-Sen Channel argo.sysu.edu.cn.[FROM: 112.94.249.26]
※ 修改:.kyhpudding 于 Mar 7 18:40:18 修改本文.[FROM: 112.94.249.26]
发信人: kyhpudding (只要衫除实得~), 信区: CS
标 题: IT 民工男的 CS 课程记忆
发信站: 逸仙时空 Yat-Sen Channel (Sun Mar 7 16:42:31 2010), 转信
先介绍下自己, 03CS 本科
在某更懂中文的地方混了两年多, 做社区产品, 后来做基础平台
带项目带新人前端到后端应用到底层跟各部门死磕无处不折腾
每年都为可以公费回广东回来校招, 据说是杀手, 不过我不觉得
最近在一以企鹅为吉祥物的公司继续折腾
此文仅代表个人观点, 也只包含个人经验
聊聊 CS 本科各种课程对实际工程工作,
更准确点, 对典型互联网行业的工程工作的影响
试图回答: 这些课程有啥用? 以及, 为啥面试会问这种 BT 问题?
不过如果你不希望走技术方向, 或者希望折腾一下技术就"转管理"
请忽略这篇文章
首先是数学, 我本科四年最后悔的事就是没把数学学好. 掩面, 这个问题先不谈.
程序设计, 首先是语言问题. 可能大家会抱怨出来工作基本都是 java C# 了, 为毛
大学还在教 C++, 落后! 好吧, 我最熟悉的语言其实是 C 语言......
我们看程序设计担负的任务. 一方面, 你必须掌握一门跟计算机沟通的语言, 否则后面
的课根本没法学. 另一方面, 通过学习程序设计 --- 而不是某一门特定语言, 掌握一些
基础的设计方法和一些思路, 为进行真正的工程开发做准备.
从掌握计算机原理, 以有效利用计算机的角度考虑, 应该选一门相对低级的高级语言,
这自然是 C, 它对于一些底层问题: 硬件, 数据结构, 底层操作系统机制等
提供了合适程度的抽象, 把我们对计算机的认识从底至上衔接起来: 写汇编时, 你得知道
指令对底层硬件的意义; 同样的, 你需要能把 C 的循环, 数组寻址, 指针在汇编上
到底是什么解释清楚, 你需要知道函数调用压栈的到底是什么数据, memcpy 到底怎么
拷的数据 (经典问题). 到学 OS 时, 如果用 linux (或任何 UNIX-like) 做教材样本,
你得有很扎实的 C 语言功底, 才做得来操作系统实验, 或者至少理解系统调用用怎么
完成. C 是系统底层的标准语言, 扎实的 C 语言基础是了解系统底层原理的
敲门砖, 至于为什么要对这些计算机系统底层如此了解的原因, 我们下面再谈.
另一方面的任务, 涉及到许多人每天的工作 --- 程序设计. 两个分支: 数据结构和算法,
软件设计范式, 抽象, 建模现实世界问题, 提供计算机解决. 这要求有一个能让底层细节
不会阻碍思考, 而且相对实用的语言. 越来越多的大学使用 Java, 当然也有不少人讨厌
这个, MIT 使用 scheme 和 python. 从达到教学要求角度看, 我觉得都没什么问题.
前提就是: 你依然得有很好的 C 语言和其他底层知识基础. 数据结构和算法下面我们
还会说到. 设计范式, 抽象, 建模等问题, 相当地困难 (数据结构也是一种抽象方法).
我那时的程序设计书好像就是讲了一堆 C 的知识, 然后后面附加讲了点 "面向对象设计",
其实是在讲 C++ 的语言特性, 非常生硬难懂. 我觉得首先得解决的是一个关于 "如何
抽象问题, 建立模型" 的问题, 而"面向对象" *仅仅是其中一种可选方法*! 而如何使
用语言特性去实现这些抽象方法, 那更是细枝末节. 在这方面, 我还是觉得 MIT 原
6.001 课程 SICP 做得最好, 逐步引导越来越高层的抽象, 一步步教导经典设计思路,
而不是一次过塞给你一坨似是而非的理论以及非常恐怖的语言特性. 至于 design
pattern --- 专指 GoF, 我认为是应该在有相当的开发经验后自行修炼的, 不适宜在
课堂上讲授.
说回来, 我认为程序设计课应该分成两部分: 为了解计算机系统底层原理准备的 C 课程.
以及为学习计算机的高层理论知识提供趁手的高级语言工具. MIT 以前用 scheme,
现在用 python, 两个课程链接:
6.001 SICP
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-001Spring-2005/CourseHome/in
dex.htm
6.189, 这门课的教材就叫 How to Think Like a Computer Scientist
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-189January--IAP--2008/Course
Home/index.htm
程序设计是一个 *准备* 课程, 好戏在后头. 在实际开发中, 底层我们用 C/C++
应用层我们用 Java PHP Python 等等等等, 还有各种脚本, 甚至自己设计语言. 从语言
角度, 我不认为深入掌握 C 和 Scheme 的人学习任何还算正常的语言会有多难.
至于应用框架/系统, 那是另一个问题, 有兴趣的自行学习, 许多大公司对此自有一套,
大学不是什么培训机构, 要在课堂上讲这些, 会让人笑掉大牙.
数据结构与算法, 这咚咚每天都要跟它打交道. 基础数据结构, 是这行的通用语言. 面试时
要考察 candidate 是否对此熟练掌握, 其重要考虑就是: 不掌握无以沟通. 没人有功夫
跟你解释 B+ 树是怎么回事, 如果我说这个模块维护了个 B+ 树你看着我一面惘然, 那
大家都会很痛苦, That's it. 当然, 有的数据结构, 比如倒排表, 你没听说过我觉得很
正常, 但我可以三言两语就让你明白这是怎么回事, 你可以马上运用它来解决问题, 那就
行了.
算法 --- 参加 ACM 对此有帮助, 但专门钻研算法的奇怪技巧却没太大帮助. 同理, 一些
基础算法, 例如排序, 是行业通用语言, 不掌握无以沟通. 而每个专业分支都会有其专门
的一些算法, 这些也不是本科计算机课程可以和需要教授的, 本来就应该在工作之后再
学习.
但另一方面, 我们往往需要设计算法 --- 往往是某些算法的变体和结合, 我们更往往要
分析算法复杂度 --- 这是个要命问题. 这是可以在课堂上学习到一些基本方法的, 虽然
会令这门课看起来更难, 而且需要更好的数学知识 (知道我为啥后悔了吧, 顺便说一下,
某大牛的观点, CS 数学是应该学数学分析的, 深以为然). 但我认为, 有基础的人就算
不知道某算法, 也会一听就明白, 并能利用. 但算法分析, 这个不抓紧时间在课堂上学
好, 以后就难了.
算法方面还是建议看 Introduction to Algorithms 吧, MIT 课程
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-046JFall-2005/CourseHome/ind
ex.htm
微机原理/计组/体系结构. 对我来说, 这些课程的作用就是让我知道, 我折腾的拿个铁
盒子到底是怎么一回事. 考虑一些系统性能问题, 做设计权衡时, 我必须考虑实际的计算
机体系, 各部分的性能状况 --- 有了基础, 还要时刻紧跟随摩尔定律发展的潮流. 我们
必须时常考虑, 硬盘的读写特性是怎样的? Cache 能多有效, 怎么利用多核 etc
操作系统原理, 这是一门核心课程. 在我的工作中, 它有两方面用途. 一方面, 为了实现
高效的低层应用, 我需要清楚操作系统的行为, 需要了解我的 API --- 系统调用的实现
原理, 效率情况. 我这行在服务端通常使用 linux 系统, 而 OS 教学在传统上以 UNIX
为范本, 有的甚至直接采用分析 linux 内核的方法, 这就很好地结合起来了. 基本上,
扎实的 OS 知识, 再加上 APUE, linux 系统编程就问题不大了.
OS 也提供了一些常用的概念和抽象方法: 例如锁, 线程和进程. 你会在各种地方碰到他们
你需要利用它, 你有时候需要自己实现它, 你有时候还会发现一个自旋锁耗掉多少 CPU
指令是影响你的程序性能的关键......
另一方面, 可能是大家容易忽视的, 是 OS 乃一门非常重要的工程入门课 --- 我认为这
才是 OS 最大的意义: 开始学习设计实际系统.
- 学习一个真正的大型系统. 真实的操作系统都非常复杂, 你可以看到现实世界的
模块划分和抽象方法, 你可以看到闪光的设计思想 --- 以及一些丑陋的既成事实, 这
比任何一本所谓 "设计方法" 的书都来得精彩. ps. 看看 APUE 吧.
- 分析瓶颈, 考虑权衡: 当你面对的是一个系统而不是一个单一问题点的时候,
分析瓶颈成了一种重要能力. 没有最优算法的说法, 调度方案等等有得必有失, 方案取舍
必须在充分的分析基础上进行. linux 的调度算法, cache 设计是怎么样并不重要.
重要的是: 它为什么要这么设计? 解决什么问题? 这个方案基于什么假设? 对什么有利
而什么不利? 是否与应用模式相吻合? 我们用什么方法来精确测量, 验证这些问题?
这些都是非常重要的工程能力. 我遇到过一位同学, 解决一个模块的性能问题, 上来
看了一通代码, 然后跟我说: 那个函数复杂度是 O(N^2) 可以优化成 O(NLogN) 的,
但实际上那个函数的数据规模只是几十, 更重要的是, 此时模块的瓶颈在 IO. OS 的课程
教会我们这些重要的分析方法, 还有一些非常精妙的设计思路 --- 这会在应用其他地方
用得着.
网络, 这门课同样有两方面意义. 一方面是掌握常识: 我们总得知道什么叫 "四层设备",
总得能分清楚交换机和路由. 当然, 一些网络编程知识也包含其中. 另一方面, 我认为对
协议设计的理解, 尤其是 TCP 设计的理解, 提供了设计分布式系统的基本思路和基本知
识, TCP 的许多设计方法, 在高层次通讯协议的设计中照样适用. 我在文后会给两个例子.
数据库, 我觉得这门课非常难教. 讲理论吧, 讲成数学了. 讲实现吧, 不现实, 讲 SQL?
这不搞笑么? 实际上我们每样都得学点. 数据库跟 OS 课程很相似的一点是: 它是许多
学科重点知识和问题的集中体现, 要看看那些稀奇古怪的知识是怎么用到现实中的?
看看 OS 和数据库吧.
数据库一方面得讲经典的关系理论 --- 基本上只要还是在设计存储系统, 就很难撇得
开它, 这还得有很好的数学基础. 同时也掌握了基本的范式, 基本的设计方法. 在思考
一个实际问题的存储方案时, 这是你的思考起点. 业界这两年流行讲反范式, 或者干脆
讲 NoSQL, No-RDBMS, 不过相信我, 经典的关系理论往往还是你思考的起点.
数据库总会有个地方讲并发, 讲 ACID, 讲事务. 嘿嘿, 欢迎来到业界第一大坑, OS 的
锁知识学好没? 准备了点分布式系统常识没? 准备好了就跳吧. 业界流行对 ACID 进行
取舍, 以达到可扩展性等目的, 我们不是要盲目去接受这些 "流行" 的东西, 我们有
时间在课堂上好好搞清楚 ACID 各为的是什么? 怎么实现? 会有什么问题? 怎么个死锁法?
最好再来点实现内容, 数据库的 index 是个什么原理? 存储具体该怎么实现? 一个查询
语句, 结合 index, 你可以怎么做?
当然我们还是得知道的 SQL 的, 这东西实在太好懂, 表达工具而已, 抠细节则不必.
我想课堂上自然也不会详细讲 MySQL 怎么配置啊, Oracle 有什么 BT 特性啊之类的
东西.
编译原理, 这门课放在本科承载的内容有点杂了. 首先得讲一下基础中的基础, 自动机.
又得讲经典的词法分析语法分析内容. 还得讲怎么编译到机器语言.
从实用角度来讲. 一方面自动机的知识词法语法分析的知识给我们提供解决相关问题
的基本思路 --- 这些都是 CS 最基础的问题. 另一方面就如一开头所说, 我们有时候
不得不设计语言, 在设计语法, 设计解析器的时候, 了解基本的编译原理知识, 并熟练
运用 lex&yacc 成了必须.
至于代码生成的部分, 我不敢说重要性有多高, 但至少我用到过相关的知识.
软件工程, 恕我直言, 这不是应该在 CS 上讲的课程, 至少不应该看得很重. 这有很多
是管理问题, 又有不断更新的新概念, 新理论. 更重要的, 我认为它更多的是 Art,
而不是 Science, 更应该在实际工作中学习积累, 做成选修课不好?
反正放心吧, 无论讲不讲, 你铁定不会一出来就是项目经理的.
我还要推荐 joelonsoftware 的一篇著名文章
Advice for Computer Science College Students
http://joelonsoftware.com/articles/CollegeAdvice.html
最后, 这里提供几个问题, 帮助大家检查一下, 自己的本科学习是否牢固,
以支撑工程需要. 这全部是基本问题, 算法问题就不列了
这不是面试经验, 每个公司的面试都有不同风格,
但解决以下这些问题的能力在我的工作中是必要的.
1. 请实现 memcpy
2. 用 PV 信号量或 mutex, 实现一个读写锁
3. 说说 fread 从一开始到读到磁盘的整个调用过程?
4. malloc 是操作系统内核实现的吗? 实现一对 malloc/free
5. 说说 TCP 三次握手? 为什么是三次? 为什么关闭连接要来四次? SYN Flodd 怎么弄,
怎么预防?
6. 说说 TCP 的滑动窗口机制, 自己实现一下.
7. 设计一个内存垃圾回收方法, 说说它的优势和局限.
8. 假设我已经有一个 B+ 树的存储实现. 请利用它实现一个基本的数据库系统: 针对
某类查询, 如何建 index, 如何执行查询, 如何完成一条更新操作?
补一门 MIT 的工程课, 建议所有希望投入到工程的同学学习
Computer System Engineering
http://ocw.mit.edu/OcwWeb/Electrical-Engineering-and-Computer-Science/6-033Spring-2009/CourseHome/in
dex.htm
本科的时间, 不花在学习课程上, 去学习某样流行的技术, 也许能令你找到一份令人
羡慕的工作, 但是别怪我乌鸦嘴, 你很快会是那个抱怨知识更新太快, 跟不上,
年纪大了失去竞争力的人.
--
Just for fun
※ 来源:.逸仙时空 Yat-Sen Channel argo.sysu.edu.cn.[FROM: 112.94.249.26]
※ 修改:.kyhpudding 于 Mar 7 18:40:18 修改本文.[FROM: 112.94.249.26]