常见笔试面试题目与解析(1)

一想到也快要到自己找工作的时候了,也就准备一下这方面的东西吧,今天比较无聊,随便在网上看了几道题目,这里记录一下:

(1)1个文本中存了100亿条数据,排好序的,怎么快速查找某个数据?

解答:这种题目,一看到已经排好序,那么就首选二分查找,但是这里有个问题,数据量很大,而且是保存在文本中的,也就是不是常规的内存中在数组当中进行二分查找。。。所以这里文本中数据时怎么保存的就非常关键了。。。如果是按照字符保存的,那么我就不知道这题目该怎么解答了,如果是按照二进制进行保存的,那么每个数据它占用的字节数就已经确定了,那么通过对文件偏移,来进行类似于数组的访问就可以了。。。。


(2)1个文本中存了100亿数据,无序,如何查找出前100小(大)的数据?

解析:我貌似没有想到特别精巧的方法,首先想到的方法是位向量的方法,不过感觉好像不太好,毕竟就算用位了保存100亿也很多了,而且有的数字还有重复,

接着想到的方法就是用一个索引结果来动态的维护,例如用红黑树,那么这里要严格的限制整个树的大小不能超过100个节点,例如这里如果是选出前100小的,那么首先建立一颗红黑树,然后按顺序遍历当前的文件中的数据,

如果当前红黑树的节点少于100或者当前数据比红黑树最右边的那个节点还要小,那么将这个数据擦入红黑树中,擦入后,如果数目的节点数目超过了100,那么删除最右边的那个节点。。。

上述方法的总体时间复杂度大概是O(N)吧,应为红黑树的高度已经基本确定下来了。。。

另外这里数据结构也可以采用堆结构来替代红黑树。。。。

嗯,貌似也想不出其他的方法了。。。


(3)java中ThreadLocal变量的作用?实现原理?initialValue方法在什么时候被调用?

解析:java的题目,其实这应该算是很常见而且很简单的题目吧,

作用:实现线程封闭,好处有减少参数的传递,比较方便。

原理:Thread对象自己会有一个map对象用于维护当前线程的ThreadLocal变量,从而实现线程之间变量的隔离。

调用时间:如果事先没有调用set方法赋值,那么第一次get方法会调用initialValue方法。

具体的内容我以前的一篇博客应该讲的蛮清楚的。。。


(4)一道代码题,算是并发编程方面的吧:

常见笔试面试题目与解析(1)_第1张图片

         


嗯,题目上面截图搞出来了

解析:

首先来看看这段代码是干嘛用的,嗯,它是一个资源容器,用于协同对资源的访问,以及维护对资源的初始化,要保证一个key它所对应的资源唯一性(只被初始化一次)。。。嗯,他的应用场景大概想到了有如下:

1,session容器(有时间看看jetty中生成session的过程,看看是不是类似这样的)      2,用于缓存计算,保证同一个key他的计算只计算一次,并将结果缓存起来。。。

而且可以看到它用了读写锁,那么大概可以猜到value的初始化过程应该是比较重的计算过程。。。

想到这里就能猜到这段代码问题在哪里,这里initData方法中,只是使用了keyLock这一个锁进行同步,用于保证只有一个线程可以进行key的value的初始化,对于其他同一个key的访问,那么其他的这些线程就只有等着获取读锁了,从而等待前面那个初始化value的线程搞完了之后才能获取value,

对于同一key没啥问题,但是如果同时访问不同的key就有问题了,因为是不同的key,那么这些key的初始化就应该可以并行的执行,但是这里由于只是用了一个锁,所以就没有办法,而且这里会出现错误,那就是本来同时访问两个key的时候,由于一个线程上了锁,那么另外一个线程就以为自己的key的value正在初始化,但是其实这里初始化的是另外一个key,所以当他获取读锁的时候,并不能获得当前key的value。。。

所以看到前面有一个ConcurrentHashMap变量,就可以知道其实这里应该为每一个key都分配一个锁,在初始化过程中每个key的初始化都用自己的锁来进行协同。。。。

这里keyLock变量应该用于同步对key对应的锁的访问和创建。。。。

这样一来既保证了正确性也能保证性能。。。

具体的改正后的代码就不搞了,太麻烦。。。


5)当浏览器中输入一个网址后浏览器都多了啥?

解析:这题,貌似见过不少次,首先访问DNS,获取域名的IP,然后向这个IP提交GET请求,得到返回后渲染html。。。这里可能还有一些细节,例如DNS的负载均衡,host文件啥的。。。以及端口什么的。。


(6)给你8块石头,其中一块比其余7块重一些,那么要找到这块石头,最少应该要称多少次?

解析:经常这道题会给答案3次,因为按照二分的方法,将石头按照如下的方式进行分:

4:4,然后是2:2,然后是1:1,

其实不然这道题的答案是2,分法应该是:

将8块石头分成3,3,2的三堆。。。。。具体的称法就不说了吧。。。。

(想吐嘲一下,干嘛计算机专业的人要考这种题,脑筋急转弯么,我相信大多数人都应该会想到二分的方法,而且这也是一种通用的解决方法。。。通用这应该才是更重要的,有可能他在有的时候确实会稍微慢了点,但这有啥关系呢,而这种题不知道是要突出什么,强调什么?)


你可能感兴趣的:(常见笔试面试题目与解析(1))