笔试题目记录

    笔试的感觉不是很好,部分题目不太会,这里简单记录一下不了解的题目。

    1、同一进程中的不同线程共享哪些资源?

    2、蒲丰投针的问题,与概率比较相关的问题。

         题目描述:平面上画很多平行线,间距为a, 向此平面内投掷长度为l(l<a) 的针,求此针与任一直线相交的概率?

    3、给出一系列的1*h的矩形,求矩形的最大面积。

        如图:

       

     笔试中这三个题目比较不知所以,操作系统的内容已经忘记了,所以第一个题目不太了解。第二个题目也很生疏,数学功底非常的弱。第三个题目想了一个奇葩的思路,当时就想应该会有O(n)的解法,但是当时怎么想都没有想到提高时间效率的方法,所以最后还是写了那个奇葩的思路。

1. 这个问题的答案参考两个地方,不太确定是否准确。

    多线程中每个线程独立的地方:    (http://laiyuanyuan7.blog.163.com/blog/static/15274321201241191321666/

    1.线程ID
      每个线程都有自己的线程ID,这个ID在本进程中是唯一的。进程用此来标
识线程。
 
    2.寄存器组的值
       由于线程间是并发运行的,每个线程有自己不同的运行线索,当从一个线
程切换到另一个线程上时,必须将原有的线程的寄存器集合的状态保存,以便将来该线程在被重新切换到时能得以恢复。
 
    3.线程的堆栈(这里的堆栈应该是栈的意思)
       堆栈是保证线程独立运行所必须的。
       线程函数可以调用函数,而被调用函数中又是可以层层嵌套的,所以线程
必须拥有自己的函数堆栈,使得函数调用可以正常执行,不受其他线程的影响。

    4.错误返回码
       由于同一个进程中有很多个线程在同时运行,可能某个线程进行系统调用
后设置了errno值,而在该线程还没有处理这个错误,另外一个线程就在此时被调度器投入运行,这样错误值就有可能被修改。所以,不同的线程应该拥有自己的错误返回码变量。

    5.线程的信号屏蔽码
       由于每个线程所感兴趣的信号不同,所以线程的信号屏蔽码应该由线程自
己管理。但所有的线程都共享同样的信号处理器。

    6.线程的优先级
       由于线程需要像进程那样能够被调度,那么就必须要有可供调度使用的参
数,这个参数就是线程的优先级。
   
    这里另外一个网友的说法,比较明确,信息应该比较准确。(http://blog.sina.com.cn/s/blog_4b9eab320100n2et.html
    
    共享的资源有
    a. 堆  由于堆是在进程空间中开辟出来的,所以它是理所当然地被共享的;因此new出来的都是共享的(16位平台上分全局堆和局部堆,局部堆是独享的)
    b. 全局变量 它是与具体某一函数无关的,所以也与特定线程无关;因此也是共享的
    c. 静态变量 虽然对于局部变量来说,它在代码中是“放”在某一函数中的,但是其存放位置和全局变量一样,存于堆中开辟的.bss和.data段,是共享的
    d. 文件等公用资源  这个是共享的,使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。
    独享的资源有
    a. 栈 栈是独享的
    b. 寄存器  这个可能会误解,因为电脑的寄存器是物理的,每个线程去取值难道不一样吗?其实线程里存放的是副本,包括程序计数器PC

2.    18世纪,法国数学家布丰和勒可莱尔提出的“投针问题”,记载于布丰1777年出版的著作中:“在平面上画有一组间距为a的平行线,将一根长度为l(l<a)的针任意掷在这个平面上,求此针与平行线中任一条相交的概率。”布丰本人证明了,这个概率是p=2l/(πd) π为圆周率。

       证明:(from 百度百科)下面就是一个简单而巧妙的证明。找一根铁丝弯成一个圆圈,使其直径恰恰等于平行线间的距离d。可以想象得到,对于这样的圆圈来说,不管怎么扔下,都将和平行线有两个交点。因此,如果圆圈扔下的次数为n次,那么相交的交点总数必为2n。现在设想把圆圈拉直,变成一条长为πd的铁丝。显然,这样的铁丝扔下时与平行线相交的情形要比圆圈复杂些,可能有4个交点,3个交点,2个交点,1个交点,甚至于都不相交。由于圆圈和直线的长度同为πd,根据机会均等的原理,当它们投掷次数较多,且相等时,两者与平行线组交点的总数期望也是一样的。这就是说,当长为πd的铁丝扔下n次时,与平行线相交的交点总数应大致为2n。现在转而讨论铁丝长为l的情形。当投掷次数n增大的时候,这种铁丝跟平行线相交的交点总数m应当与长度l成正比,因而有:m=kl,式中k是比例系数。为了求出k来,只需注意到,对于l=πd的特殊情形,有m=2n。于是求得k=(2n)/(πd)。代入前式就有:m≈(2ln)/(πd)从而π≈(2ln)/(dm)

 

3.(1)当时解题的思路比较诡异,一直想着要缩小问题的规模,然后得出的思路是:首先找出最短的一个矩形,然后这个最短的矩形高度*长度得出一个面积,然后利用最矮的矩形将原来的问题切割成为左边的一个子问题和右边的一个子问题。

这个解题思路如果是矩形排列比较好的情况下能够达到O(nlgn)的时间复杂度。但是后来想想,如果如果连续的矩形单调递减或者单调递增,这个算法的复杂度就会退化为O(n2),所以这个算法思路不是很好。

   (2)这里说一下穷举的思路其实时间复杂度也仅仅只有O(n2)而已。思路就是穷举每一个矩形条可以扩展的最大矩形面积。向左向右延伸,延伸结束的条件是出现高度小于其的矩形条,这样可以得到一个宽度,然后计算每个矩形条可以延伸的最大面积,最后得出最大的面积。

   (3)改进的思路也是基于穷举的思路进行改进的,穷举的时候因为有重复的计算,所以这里就存在的改进空间。搜索了一下网上提供的思路,都是单调堆栈的思路,应该就是这个改进方法了。(from http://blog.csdn.net/alongela/article/details/8230739

建立一个单调递增栈,所有元素各进栈和出栈一次即可。每个元素出栈的时候更新最大的矩形面积。

设栈内的元素为一个二元组(x, y),x表示矩形的高度,y表示矩形的宽度。

若原始矩形高度分别为2,1,4,5,1,3,3

高度为2的元素进栈,当前栈为(2,1)

高度为1的元素准备进栈,但必须从栈顶开始删除高度大于或等于1的矩形,因为2已经不可能延续到当前矩形。删除(2,1)这个元素之后,更新最大矩形面积为2*1=2,然后把它的宽度1累加到当前高度为1的准备进栈的矩形,然后进栈,当前栈为(1,2)

高度为4的元素进栈,当前栈为(1,2) (4,1)

高度为5的元素进栈,当前栈为(1,2) (4,1) (5,1)

高度为1的元素准备进栈,删除(5,1)这个元素,更新最大矩形面积为5*1=5,把1累加到下一个元素,得到(4,2),删除(4,2),更新最大矩形面积为4*2=8,把2累加到下一个元素,得到(1,4),1*4=4<8,不必更新,删除(1,4),把4累加到当前准备进栈的元素然后进栈,当前栈为(1,5)

高度为3的元素进栈,当前栈为(1,5) (3,1)

高度为3的元素准备进栈,删除(3,1),不必更新,把1累加到当前准备进栈的元素然后进栈,当前栈为(1,5) (3,2)

把余下的元素逐个出栈,(3,2)出栈,不必更新,把2累加到下一个元素,当前栈为(1,7),(1,7)出栈,不必更新。栈空,结束。

最后的答案就是8。

    

 

 

posted @ 2013-10-30 19:55  weixliu  阅读(1147)  评论(3编辑  收藏  举报