深信服的笔试题

来源:互联网 发布:恒腾网络十大股东 编辑:程序博客网 时间:2024/04/27 20:57

 

软件工程师题:

NO1、平衡二叉树和哈希表
哈希表主要可以在O(1)时间内对查找对象定位,但是事实上,如果输入集合不确定的情况下,可能出现大量的冲突,虽然有很多好的哈希函

数,但是随着随机输入,大量冲突还是不可避免,可能出现最差情况。所以,哈希表如果用在输入集合确定(即以后只会做查询操作)的情况

下,选择合适的函数函数和解决冲突的方法(perfect hash)可以在O(1)时间内完成查找(有证明,看不懂)。
二叉树支持动态的插入和查找,保证操作在O(height)时间,这就是完成了哈希表不便完成的工作,动态性。但是二叉树有可能出现worst-

case,如果输入序列已经排序,则时间复杂度为O(N)
  平衡二叉树/红黑树就是为了将查找的时间复杂度保证在O(logN)范围内。
  所以如果输入结合确定,所需要的就是查询,则可以考虑使用哈希表,如果输入集合不确定,则考虑使用平衡二叉树/红黑树,保证达到最

大效率
NO2、fork和vfork的区别(待细看)
fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性,但是二者之间的通讯需要通

过专门的通讯机制,如:pipe,popen&pclose、协同进程、fifo,System V IPC(消息队列、信号量和共享内存)机制等, 另外通过fork创建

子进程系统开销很大,需要将上面描述的每种资源都复制一个副本。这样看来,fork是一个开销十分大的系统调用,这些开销并不是所有的情

况下都是必须的,比如某进程fork出一个子进程后,其子进程仅仅是为了调用exec执行另一个执行文件,那么在fork过程中对于虚存空间的复

制将是一个多余的过程(由于Linux中是采取了copy-on-write技术,所以这一步骤的所做的工作只是虚存管理部分的复制以及页表的创建 ,

而并没有包括物理也面的拷贝);

vfork系统调用不同于fork,用vfork创建的子进程共享地址空间,也就是说子进程完全运行在父进程的地址空间上,子进程对虚拟地址空间任

何数据的修改同样为父进程所见。但是用 vfork创建子进程后,父进程会被阻塞直到子进程调用exec或exit。这样的好处是在子进程被创建后

仅仅是为了调用exec执行另一个程序时,因为它就不会对父进程的地址空间有任何引用,所以对地址空间的复制是多余的,通过vfork可以减

少不必要的开销。

按指定条件创建子进程。Linux内核在2.0.x版本就已经实现了轻量进程,应用程序可以通过一个统一的clone()系统调用接口,用不同的参数指

定创建轻量进程还是普通进程。在内核中,clone()调用经过参数传递和解释后会调用do_fork(),这个核内函数同时也是fork()、vfork()系统

调用的最终实现


在fork之后,子进程和父进程都会继续执行fork调用之后的指令。子进程是父进程的副本。它将获得父进程的数据空间,堆和栈的副本,这些

都是副本,父子进程并不共享这部分的内存。也就是说,子进程对父进程中的同名变量进行修改并不会影响其在父进程中的值。但是父子进程

又共享一些东西,简单说来就是程序的正文段。正文段存放着由cpu执行的机器指令,通常是read-only的。

由于在fork之后我们常常都是跟个exec在后面,所以为了提高效率,很多的实现并不完全复制数据段和堆、栈,而是采用写时复制,有点类似

于某些cache与内存数据的同步方法。

另一种提高效率的方法就是使用vfork,vfork最早起源于2.9BSD,它与fork的不同就在于它并不将父进程的地址空间完全复制到子进程中,因为

子进程会立即调用exec。vfork出来的子进程是在父进程的空间中运行的,它的存在就是为了exec调用,所以它不需要复制这些东西,因为复制

了也没有用。如果这时子进程修改了某个变量,这将影响到父进程。
vfork与fork的另一区别是:vfork保证子进程先运行,在它调用exec或exit后父进程才可能调度运行。而fork的父子进程运行顺序是不定的,

它取决于内核的调度算法。

所以,fork的时候,程序代码被复用了——我指的程序代码就是由cpu执行的机器指令部分,这与有多少个进程在运行无关,即使是频繁执行的

程序在存储器中也只需一个副本,而且它在执行期可能是read-only的。当然,如果你exec了,那就是另一码事了。
另外,父进程中的数据空间和堆、栈可能会产生副本,具体情况要看你使用的是vfork还是fork。fork会产生副本,而vfork则共享这部分内存


NO3、spinlockmutex,semaphore,viticalsection的作用与区别?(待详细研究)
Critical Section,其他都能用于进程间同步,临界段只能用于进程内部,是轻量级同步对象。

spinlock是自旋锁,用于多cpu的情况

mutex就是普通的跨进程同步对象

semaphore用于对资源数的控制

NO4、strncpy,栈溢出问题,如何规避和解决?
Strcpy和Strncpy的区别- -
第一种情况:
char* p="how are you ?";
char name[20]="ABCDEFGHIJKLMNOPQRS";


strcpy(name,p); //name改变为"how are you ? OPQRS " ====>错误!
strncpy(name,p,sizeof(name)) //name改变为"how are you ? " ====>正确!

第二种情况:
char* p="how are you ?";
char name[20];

strcpy(name,p); //name改变为"how are you ? 未知字符 " ====>错误!
name[sizeof(name)-1]='\0' //和上一步组合,得到正确的结果!
strncpy(name,p,sizeof(name)); //name改变为"how are you ? " ====>正确!

第三种情况:
char* p="how are you ?";
char name[10];

strcpy(name,p); //name改变为"how are yo" ====>无结束符'\0',错误!
name[sizeof(name)-1]='\0' //和上一步组合,弥补结果。但要注意,字符传递错误!
strncpy(name,p,sizeof(name)); //和单纯的一步strcpy结果一样!

================================================
总结:strcpy
如果源长>目标长,则将源长中等于目标长的字符拷贝到目标字符串
如果源长<目标长,则源长全部拷贝到目标字符串,不包括'\0'
strncpy
如果目标长>指定长>源长,则将源长全部拷贝到目标长,自动加上'\0'
如果指定长<源长,则将源长中按指定长度拷贝到目标字符串,不包括'\0'
如果指定长>目标长,error happen!
strncpy(sptsf_cert.peer_ditm_no,clr_total.payint_acc+7,8) //从第8位后8位拷贝
strncpy(sptsf_cert.recv_inst,clr_total.payint_acc,4);//拷贝前四位

NO5、release版本,可执行程序文件过大,可能是什么原因?(有待后序整理)
不会,请赐教

NO6、如何减少和避免锁的使用?

NO7、c++赋值需要注意什么?

NO8、软件开发分为几个过程,每个过程如何保证质量?

还有些回忆不起来了

算法工程师的题:

算法题:
1.设计一个高效的路由表查找算法?
2.从internet上爬取了大量网页资源,将一部分经常访问的放入内存做缓冲,其他放入硬盘,当硬盘满的时候要将冷门网页删除。设计算法。
3.要从一个10G(硬盘上)的数据中查找一个4k的模式串,设计高效算法实现之(2ms左右,可用内存100M)

基础算法题:
1。有点长,题目没咋看懂
2.假设哈希函数是随机的,一个大小为N的桶放入M个元素平均占用多少个桶?(感觉题目有点不通顺,没太明 白)
3.写出你设计的字符串匹配算法,尝试尽可能多的手段,并说明如何优化?
4.如何判断一个点在多边形里面?
5.有两堆石头,每堆10块石头,设计一个尽可能简单的算法,使两堆石头重量大致相当。
6.有1001个球。甲乙两人交替取球,每次可取1、2、4个球,谁拿到最后一个球就算输。如 果甲先拿,问他有没有必胜的把握?为什么?

原创粉丝点击