每章提出一个自己不懂的或最想解决的问题以及期末解答
每章提出一个自己不懂的或最想解决的问题
第一章《计算机系统的漫游》
- 问题:如何理解信息=位+上下文;
- 期末解答:源程序实际上就是一个由值0和1组成的位(bit)序列,8个位被组织成一组,称为字节。每个字节表示程序中某个文本字符。系统中所有的信息—包括磁盘文件、存储器中的程序、存储器中存放的用户数据以及网络上传送的数据,都是由一串位表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。上下文就是程序运行的环境;
第二章《信息的表示和处理》
- 问题:有符号和无符号数之间的转换
- 期末解答:在第一章里提过,信息=位+上下文;有符号数与无符号数,底层位不变,上层解释改变;例如,-12345的16位补码表示与53191的16位无符号表示是完全一样的,即位表示不变,而解释这些位的方式发生改变,
第三章《程序的机器级表示》
- 问题:如何利用缓冲区溢出进行网络攻击
- 期末解答:通过学习本门课程和信息安全技术,我对这个问题有了些许理解,缓冲区溢出会使程序执行它本来不会执行的函数,例如,利用缓冲区溢出,使一个指向攻击代码的指针覆盖返回地址,执行返回指令的的效果就是跳转到了攻击代码。
第四章《处理器体系结构》
- 问题:汇编指令如何与机器对应
- 期末解答:处理器在执行一系列指令时,指令被编码为由一个或多个字节序列组成的二进制格式。每条指令需要1~10个字节不等,这取决于需要哪些字段。并且指令集的另一个重要性质就是字节编码必须有唯一的解释,每条指令的第一个字节有唯一的代码和功能组合,给定这个字节,可以决定所有其他附加字节的长度和含义,从而保证了处理器可以准确的执行目标代码程序;
第五章《优化程序性能》
-
问题:如何实现优化程序性能,以及实现的方法:
-
期末解答:
1、编写高效程序:合适的数据结构和算法,编译器能够有效优化以转换为高效可执行代码的源码,对处理量特别大的计算将任务分为多个部分;
2、程序优化:消除不必要的内容(函数调用,条件测试,存储器引用);
3、使程序性能最大化:需要一个目标机器的模型,指明如何处理指令,以及各个操作的时序特性;
4、利用处理器提供的指令级并行能力同时执行多条指令;
5、降低计算不同部分之间的数据相关,增加并行度,同时执行;
6、研究程序的编译代码表示,是理解编译器以及产生的代码如何运行的最有效的手段之一;
7、确认关键路径,决定执行一个循环所需要的时间(至少是一个时间下界);
8、关键路径是在循环的反复执行过程中形参的数据相关链;
第六章《存储器层次结构》
- 问题:什么是局部性原理,一个具有良好局部性的程序会有哪些优点?
- 期末解答:在谢婷婷老师的操作系统里也有讲过这个问题,局部性指空间局部性和时间局部性,好的时间局部性指被引用过一次的内存位置在不久的将来会被多次引用,好的空间局部性指,如果一个内存位置被引用了一次,那么程序很可能在不远的将来引用附近的一个内存位置。具有良好局部性的程序倾向于访问相同的数据项集合,或者倾向于访问临近的数据项集合,所以倾向于从存储器层次结构中较高层次处访问数据项,因此运行更快。
第七章《链接》
- 问题:为什么要用静态库和动态库:
- 期末解答:库是别人写好的现有的,成熟的,可以复用的代码,你可以使用但要记得遵守许可协议。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。共享库的好处是,不同的应用程序如果调用相同的库,那么在内存里只需要有一份该共享库的实例。当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被copy到最终的可执行文件中。这就会导致最终生成的可执行代码量相对变多,相当于编译器将代码补充完整了,这样运行起来相对就快些。不过会有个缺点: 占用磁盘和内存空间.静态库会被添加到和它连接的每个程序中, 而且这些程序运行时,都会被加载到内存中.无形中又多消耗了更多的内存空间.与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时, 那些需要的函数代码才被拷贝到内存中。这样就使可执行文件比较小, 节省磁盘空间,更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用,也同时节约了内存。不过由于运行时要去链接库会花费一定的时间,执行速度相对会慢一些,总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率。
第八章《异常控制流》
- 问题:什么是异常控制流:
- 期末解答:异常控制流是程序运行时,应对一些函数调用或者分支跳转都无法处理的事情:I/O中断(ctrl+c)或者计时器中断(进程切换)所创立的一套机制。异常分为同步异常和异步异常(中断):
异步异常:CPU无法预料是否会发生的异常,也称作中断。如I/O中断(ctrl+c)或者计时器中断(进程切换)。
同步异常:CPU能预见有可能发生的异常。如:page fault(读取数据的时候预料到有可能),trap(调用某些系统函数,如open的时候,触发陷阱,进行系统调用)。其实还有一个叫abort,发生严重错误,无法恢复运行。
第九章《虚拟内存》
- 问题:虚拟内存是什么?有什么用处?
- 期末解答:虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。虚拟内存可以大于物理内存,一般为物理内存的1.5倍到3倍,从而可以运行比物理内存大的程序,进而使得更多的程序可以同时执行,提高了多道程序的程度,增加了CPU的使用率,并且使得进程之间的独立性得到了更好的体现。
第十章《系统级I/O》
- 问题:在linux中一切皆文件,那么是如何对其进行操作的;
- 期末解答:内核用三个相关的数据结构来表示打开的文件:描述符表、文件表、v-node表。内核中,对应于每个进程都有一个独立的文件描述符表,表示这个进程打开的所有文件。文件描述符表中每一项都是一个指针,指向一个用于描述打卡的文件的数据块——文件表,所有进程共享这张表文件表的表项包括当前的文件位置、引用计数(即当前指向该表项的描述符表项数)、以及一个指向v—node表中对应表项的指针,所有进程共享v-node表,每个表项包含stat结构中的大多数信息。
第十一章《网络编程》
- 问题:什么要使用套接字进行网络编程?套接字到底是什么?
- 期末解答:这部分我们在刘念老师的课上也学习过,所以理解更好的一点。Linux环境下使用套接字进行进程之间的通信。套接字接口(socket interface)是一组函数,也是操作系统提供给应用程序的接口。在Unix系统中,套接字和Unix I/O函数结合起来,用来创建网络应用程序。(也就是说,操作系统对外只提供了套接字作为网络通信的接口,假如想进行网络通信,套接字我们用也得用,不用也得用,而且使用套接字来进行网络通信是十分通用的方法)。这里最典型的就是客户端--服务器模型。一个“套接字”是连接的一个端点。每个套接字都有相应的“套接字地址”,是由一个因特网地址(IP地址)和一个16位的整数“端口”组成的,用"地址:端口"来表示。当客户端发起一个连接请求时,客户端套接字地址中的端口是由内核自动分配的,称为“临时端口”(ephemeral port)。然而,服务器套接字地址中的端口通常是和某个“知名”的端口,是和这个服务相对应的。例如,Web服务器通常使用端口80,而电子邮件服务器使用端口25
第十二章《并发编程》
-
问题:有哪几种构造并发编程的方法,分别为什么?
-
期末解答:
1、进程。用这种方法,每个逻辑控制流都是一个进程,由内核来调度和维护。因为进程有独立的虚拟地址空间,想要和其他流通信,控制流必须使用某种显式的进程间通信机制。
2、I/O多路复用。在这种形式的并发编程中,应用程序在一个进程的上下文中显式地调度它们自己的逻辑流。逻辑流被模型化为状态机,数据到达文件描述符后,主程序显式地从一个状态转换到另一个状态。因为程序是一个单进程,所以所有的流都共享同一地址空间。
3、线程。线程是运行在一个单一进程上下文中的逻辑流,由内核进行调度。你可以把线程看成是其他两种方式的混合体,像进程流一样由内核进行调度,而像I/O多路复用流一样共享同一虚拟地址空间。