面试笔记3

(1)快排是递归排序,为啥排序效率也挺高?快排是通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。最坏情况下的复杂度和冒泡一样,最好的情况复杂度为O(nlogn)

<div class="cnblogs_Highlighter">
<pre class="brush:java;gutter:true;">public static int binSearch(int srcArray[],int start,int end,int key) {
int mid = (end - start) / 2 + start;
if (srcArray[mid] == key) {
return mid;
}
if (start >= end) {
return -1;
} else if (key > srcArray[mid]) {
return binSearch(srcArray,mid + 1,end,key);
} else if (key < srcArray[mid]) {
return binSearch(srcArray,start,mid - 1,key);
}
return -1;
}

(3)TCP协议属于哪一层?特点是什么?怎么建立连接?TCP是一种面向连接的、可靠的传输层协议;TCP协议建立在不可靠的网络层IP协议之上,IP不能提供任何可靠性机制,TCP的可靠性完全由自己实现;TCP采用的最基本的可靠性技术是:确认与超时重传流量控制TCP是因特网中的传输层协议,使用三次握手协议建立连接。当主动方发出SYN连接请求后,等待对方回答SYN,ACK。这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议。第一次握手:建立连接时,客户端发送SYN包(SEQ=x)到服务器,并进入SYN_SEND状态,等待服务器确认。第二次握手:服务器收到SYN包,必须确认客户的SYN(ACK=x+1),同时自己也送一个SYN包(SEQ=y),即SYN+ACK包,此时服务器进入SYN_RECV状态。第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=y+1),此包发送完毕,客户端和服务器时入Established状态,完成三次握手。

(4)产生死锁的原因?产生死锁的条件和如何避免死锁?产生死锁的原因主要是:  (1) 因为系统资源不足。  (2) 进程运行推进的顺序不合适。  (3) 资源分配不当等。  如果系统资源充足,进程的资源请求都能够得到满足,死锁出现的可能性就很低,否则  就会因争夺有限的资源而陷入死锁。其次,进程运行推进顺序与速度不同,也可能产生死锁。产生死锁的四个必要条件:  (1) 互斥条件:一个资源每次只能被一个进程使用。  (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。  (3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺。  (4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。  这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之  一不满足,就不会发生死锁。死锁的解除与预防:  理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和  解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确  定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态  的情况下占用资源。因此,对资源的分配要给予合理的规划。

(5)轮询和抢占式任务调度有什么区别?轮询任务调度与抢占式任务调度的区别在于抢占式调度可以因为优先级高的任务抢占cpu,而轮询的不能。

逻辑地址(Logical Address) 是指由程式产生的和段相关的偏移地址部分。例如,你在进行C语言指针编程中,能读取指针变量本身值(&操作),实际上这个值就是逻辑地址,他是相对于你当前进程数据段的地址,不和绝对物理地址相干。只有在Intel实模式下,逻辑地址才和物理地址相等(因为实模式没有分段或分页机制,Cpu不进行自动地址转换);逻辑也就是在Intel保护模式下程式执行代码段限长内的偏移地址(假定代码段、数据段如果完全相同)。应用程式员仅需和逻辑地址打交道,而分段和分页机制对你来说是完全透明的,仅由系统编程人员涉及。应用程式员虽然自己能直接操作内存,那也只能在操作系统给你分配的内存段操作。线性地址(Linear Address) 是逻辑地址到物理地址变换之间的中间层。程式代码会产生逻辑地址,或说是段中的偏移地址,加上相应段的基地址就生成了一个线性地址。如果启用了分页机制,那么线性地址能再经变换以产生一个物理地址。若没有启用分页机制,那么线性地址直接就是物理地址。Intel 80386的线性地址空间容量为4G(2的32次方即32根地址总线寻址)。物理地址(Physical Address) 是指出目前CPU外部地址总线上的寻址物理内存的地址信号,是如何地址变换的最终结果地址。如果启用了分页机制,那么线性地址会使用页目录和页表中的项变换成物理地址。如果没有启用分页机制,那么线性地址就直接成为物理地址了。

流水线是通过细化流水、提高主频,使得在一个机器周期内完成一个甚至多个操作,其实质是以空间换取时间

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 不是语句 不要在行末加分号,否则 会连分号一块置换。

相关文章

在 Java 语言中,提高程序的执行效率有两种实现方法,一个是...
在 Java 中停止线程的实现方法有以下 3 种: 自定义中断标识...
在多线程编程中,wait 方法是让当前线程进入休眠状态,直到另...
在 Java 语言中,并发编程都是通过创建线程池来实现的,而线...
sleep 方法和 wait 方法都是用来将线程进入休眠状态的,并且...
在 Java 中,线程的创建方法有 7 种,分为以下 3 大类: 继承...