操作系统教学中,我经常向学生灌输一个观点,就是不要对操作系统的知识太“较真”,因为这东西本身就完全是人造的,没有任何自然定律支配它,所以什么是对,什么是错,咋说都有道理。学操作系统的关键在于要领会精神,了解细节,但不要纠缠细节。比如,我们都知道操作系统提供给应用程序的接口是“系统调用”,这个貌似没有争议。但如果硬找麻烦的话,对于像DOS和一些嵌入式OS等不区分用户态、内核态的,应用程序除了系统调用,还可以直接读写内核空间里的数据,直接调用甚至修改内核里任意一条指令;对于Java OS(别讨论它是不是OS,因为OS压根没有精确的定义),应用程序和系统之间的接口是Java API,根本到不了系统调用的级别。
所以,我认为机械的选择、判断题根本不适合操作系统这个博大精深的东西,很难经得起推敲。甚至于说,操作系统根本不适合被考试,不适合用简单的“对”和“错”来评价一个学生对这门学问的理解。最近拿到了2010年考研统考题的真题和官方标准答案,从中找到了不少刺,再次证明了我的观点。摘录几个:
23题:
下列选项中,操作系统提供给应用程序的接口是
A. 系统调用 B. 中断 C.库函数 D. 原语
标准答案是A。
挑刺:
- 很多系统的系统调用都是用软中断实现的,所以不能说中断就不是这个接口。
- 大多数应用程序都是通过库函数间接调用系统调用的,而操作系统可以将库函数和内核、系统程序等打包在一起提供给用户,所以库函数也是一种接口。这个命题让我想起我在课上问过的一个经典问题“扫雷是不是Windows操作系统的一部分?”
- 不过,从选出“最符合题目要求”的答案角度看,这道题还能算是合理的。
24题:
下列选项中,导致创建新进程的操作是
I. 用户登录成功 II. 设备分配 III. 启动程序执行
A. 仅I和II B. 仅II和III C. 仅I和III D. I、II和III
标准答案是C,仅I和III。
I.的挑刺:
- 用户一定是OS用户吗?FireBBS系统中的BBS用户,只要连接进来,就建立进程,然后才是登录操作,而且无论登录成功还是不成功,都只是这一个进程为其服务。
- 就算用户是OS用户,假设这是一个字符界面的单用户的简单系统,启动后,shell就控制着终端,等待用户输入用户名和密码。验证通过后,shell才打印命令提示符,并接受用户的命令。这样,在用户登录过程中,没有任何新进程被建立。
II.的挑刺:
- 很多虚拟设备都是靠建立进程实现虚拟的,比如spooling方式的虚拟打印机的实现就可以这么做
- 一定有物理设备驱动程序的设计中,就用到了进程,每当这个设备被分配,就建个进程做些数据处理之类的工作。我举不出具体的例子,但相信肯定可以这么做。
III.的挑刺:
- 这个描述本身就不清楚。是“启动程序”被执行,还是启动一个程序并执行?
- 如果是“启动程序”被执行,并把启动程序理解为boot,那么这时候还没有进程的概念呢
- 如果是启动一个程序并执行,那么这个程序必须是应用程序吗?就不能是中断响应程序、引导程序、子程序什么的吗?就算它是应用程序,进程A调用execve()启动程序B,这个过程中有新进程建立吗?
45题:
题目太长,不敲了,是关于C-SCAN算法的。这道题刚考完试的时候,就有考生提出了质疑。这个考生能在高压力的考试情况下看到这一点,很厉害。这个争议的根源在于对C-SCAN算法描述的差异。统考的事实标准参考书(汤子瀛编著)里,说C-SCAN扫描的最远点是有访问请求的点,还有些资料(我查阅了《Operating System Concepts》,wikipedia)里说C-SCAN扫描的最远点是磁盘边界。汤式C-SCAN在这些资料里叫C-LOOK。虽然描述不同,但他们都是对的,思想上是一致的。46题涉及的Clock算法也有类似问题。这并不是问题,因为真正研究操作系统的人都不是学究,不会追求与教科书保持一致,会根据自己的需要去改造、创造算法。但在考试中,这就是问题了。不看汤本的学生,在这道题上会多少遇到一些杯具,至少得多费点儿时间。这很糟糕,有点儿颠倒。
说这些,不针对任何人,任何组织。我本科时学的就是汤老师的教材,对我的帮助很大。命题人的工作做得已经相当好了,能明显看出来他们在费尽心力地精确题目描述,避免各种意外。但没办法,操作系统这门学问的本质决定了,它不可能被机械地考核。考试形式不改,统考的制度不打破,就不可能真正地考查出学生的实际水平。