笔试训练4

1.某系统中有3个并发进程,都需要同类资源4个,试问该系统不会发生死锁的最少资源数是多少

可能会发生死锁的上限资源数,为每个进程均只差一个资源的情况,为9个,只要再加一个资源就不可能发生死锁了,所以不会发生死锁的最少资源数为10。


2.内存相关

关于内存正确的是
A.内存的存取速度不能低于cpu速度,否则会造成数据丢失
B.程序只有在数据和代码等被调入内存后才能运行
C.采用虚拟内存技术后程序可以在硬盘上直接运行
D.某计算机的内存容量为16MB,那么他的地址总线为24位

B
A 内存的读取速度往往低于CPU的处理速度,慢的话可以等待,不会错。
B 正确
C 采用虚拟存储只是把现在不用的放到外存,需要时在调入内存。

D 至少是24位,一般要大于24位,因为要采用虚拟存储技术。


3.下列关于线性调度的叙述中,错误的是


A.调用线程的sleep()方法,可以使比当前线程优先级低的线程获得运行机会
B.调用线程的yeild()方法,只会是与当前线程相同优先级的线程获得运行机会
C.当有比当前线程的优先级高的线程出现时,高优先级线程抢占CPU并运行。
D.一个线程由于某些原因进入阻塞状态,会放弃CPU
E.具有相同优先级的多个线程的调度一定是分时的

F.分时调度模型是让所有线程轮流获得CPU使用权

B,E
A.sleep()让当前正在执行的线程暂停一段时间并进入阻塞状态,使其他线程得到运行的机会,不论进程优先级。
B. 让 yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。 当调用了yield方法后,只有优先级与当前线程相同,或者优先级比当前线程更高的就绪状态的线程才会获得执行的机会

E.也可以是抢占式调度


4.同步IO和异步IO的区别

异步文件IO也就是重叠IO。
在同步文件IO中,线程启动一个IO操作然后就立即进入等待状态,直到IO操作完成后才醒来继续执行。而异步文件IO方式中,线程发送一个IO请求到内核,然后继续处理其他的事情,内核完成IO请求后,将会通知线程IO操作完成了。
如果IO请求需要大量时间执行的话,异步文件IO方式可以显著提高效率,因为在线程等待的这段时间内,CPU将会调度其他线程进行执行,如果没有其他线程需要执行的话,这段时间将会浪费掉(可能会调度操作系统的零页线程)。如果IO请求操作很快,用异步IO方式反而还低效,还不如用同步IO方式。
同步IO在同一时刻只允许一个IO操作,也就是说对于同一个文件句柄的IO操作是序列化的,即使使用两个线程也不能同时对同一个文件句柄同时发出读写操作。重叠IO允许一个或多个线程同时发出IO请求。
异步IO在请求完成时,通过将文件句柄设为有信号状态来通知应用程序,或者应用程序通过GetOverlappedResult察看IO请求是否完成,也可以通过一个事件对象来通知应用程序。
例如DeviceIoControl这个函数,他就可以通过参数指定是同步或异步,如果是同步的话,则该函数将会等待结果返回后,才执行下一条语句。如果是异步的话,DeviceIoControl调用后马上返回,如果参数正确,则回返回ERROR_IO_PENDING(忘了怎样写,不过肯定是有PENDING这个词),然后你可以通过GetOverlappedResult获取返回结果,是一个overlap结构,是在你调用DeviceIoControl的最后一个参数传进去的``
简单的说``同步在编程里,一般是指某个操作执行完后,才可以执行后面的操作``拿到IO上来说``就是我要做完这个IO操作``才继续后面的操作```

异步则是,我交带了某个操作给系统(可以是windows,也可以是你自己的库),我呆会过来拿,我现在要去忙别的``拿到IO上说``我交带了某个IO操作给系统。。。。。


5.typedef与#define的比较

1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错。例如:
#define PI 3.1415926
程序中的:area=PI*r*r 会替换为3.1415926*r*r
如果你把#define语句中的数字9 写成字母g 预处理也照样带入。
2)typedef是在编译时处理的。它在自己的作用域内给一个已经存在的类型一个别名,但是You cannot use the typedef specifier inside a function definition。
3)typedef int * int_ptr;

#define int_ptr int * 
作用都是用int_ptr代表 int * ,但是二者不同,正如前面所说 ,#define在预处理 时进行简单的替换,而typedef不是简单替换 ,而是采用如同定义变量的方法那样来声明一种类型。也就是说;
//refer to (xzgyb(老达摩))
#define int_ptr int *
int_ptr a, b; //相当于int * a, b; 只是简单的宏替换
typedef int* int_ptr;
int_ptr a, b; //a, b 都为指向int的指针,typedef为int* 引入了一个新的助记符
这也说明了为什么下面观点成立
//QunKangLi(维护成本与程序员的创造力的平方成正比)
typedef int * pint ;
#define PINT int *
那么:
const pint p ;//p不可更改,但p指向的内容可更改
const PINT p ;//p可更改,但是p指向的内容不可更改。
pint是一种指针类型 const pint p 就是把指针给锁住了 p不可更改
而const PINT p 是const int * p 锁的是指针p所指的对象。
3)也许您已经注意到#define 不是语句 不要在行末加分号,否则 会连分号一块置换。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值