简述几个印象比较深的题目
1. 一台电脑上面有一个几百G的文件,文件的内容是一行一行的字符串,求出出现频率排名前十的字符串。
答:老题目了,我给出的答案是对字符串进行哈希,每次只统计哈希函数的值域里面的一个值的键(也就是某些字符串)的个数,而这些字符串是可以放进内存的。最简单的哈希函数就是Hash(str) = first_character_of_str(str),也就是取这个字符串的首字母。例如Hash(abc)=a,Hash(bbc)=b,这样还是不能完全解决问题,加入a开头的单词不能完全装入内存怎么办,这个好办,假如a开头的字符串不能完全装入内存,那么我们可以对a开头的字符串进行再划分,比如Hash(abcd)=ab,Hash(acdb)=ac,这样继续下去总归到某一级可以全部装入内存的。
没统计一次,就把统计的结果写入到硬盘的一个文件上。等这一步都完成之后,开始建立堆,从第一组中选出排名前十的,建立好堆,再去第二个文件中选,就用刚才的堆,把每个文件都走一遍就统计出了所有字符串中出现频率排名前十的字符串。
2. 有一张teacher(tid,cid)表和一张student(sid,cid)表,tid是老师的编号,是teacher表的主键,sid是学生编号是student的主键,cid是班级编号,teacher表和student表没有主外键关系,写一条sql语句统计出cid相同的那些老师和学生,也就是输出(tid,cid,sid)
答:。。。。。。。。。。。。我感觉无力吐槽,这题目我一头雾水,感觉面试官脑门被驴踢了,不就是写个select * from teacher,student where teacher.cid=student.cid么。。。他说不对,这样会有语法错误,我写了这么多年的sql从来在这上面出过错,他提醒我这两张表没有主外键关系,这题我到现在没搞清楚面试官的意思,我回来在mysql上面试了,这个语句是没问题的,没有任何编译错误,求解释。
3. 各类排序算法的时间,空间复杂度以及应用场景
http://blog.sina.com.cn/s/blog_77795cad01011txt.html
4. TCP协议连接时和释放时所作的操作
http://www.51testing.com/?uid-351385-action-viewspace-itemid-814280
5. 有一个集群,里面有M个机器,在其中的一个节点上,有一个很大的数据(big file),现在要求将这个数据拷贝到集群中的每一个节点上,要求想一个高效的算法。
答:
我的想法一:集群中有M台机器,它们都是通过网络互相连接的,那么我们可以把big file划分成N份,并且我们维护一个标记数组flag[M][N],是布尔型的,flag[i][j]表示第i个节点上是否有第j个分片,有的话置flag[i][j]为true,否则置flag[i][j]为false,那么首先flag[0][0]...flag[0][n-1]肯定都是true,其他位置都是false,那么第一台机器做为集群主机可以将第k个分片发送给第编号为k%M的机器,这时候集群中的一些结点就有了某一些分片了,而且标记数组也改变了,这时候主机根据flag数组的信息发送命令,比如2号机器肯定有2号分片,那么1号机告诉2号机把2号分片发送给4号结点,于此同时1号结点本身将2号分片发送给3号结点。这个过程是并行进行的,然后按照该过程反复的迭代,直至flag数组里面的元素全部被标记为true。
我的这个算法是最快的办法,它充分的利用网络带宽,可是面试官说这个方法过于复杂,现在可以牺牲算法的性能来换取算法的简单性和可靠性。。。没想出来。
面试官:首先将集群中的结点编号1,2,3,4...M,将数据划片分为相等大小的数据片1,2,3...N,然后将结点按序串联成管道,让1...N分片在管道中流动,从头到尾,比如说一号分片在3号结点到4号结点流动的时候,2号分片正从2号结点流向3号结点,而3号分片正从1号结点流向2号结点,这样一直等所有分片都从头流到尾。那么设一个分片从一个结点流向另一个结点的时间是t,那么这个过程的时间应该是(m+n)*t。
我觉得这个算法还是没有我的算法好,因为在某个时刻对于一个特定的结点最多只有一个输入流和一个输出流,这样没有利用到计算机的并行处理能力,也浪费一部分带宽资源。
6. 关于Java中的HashMap
a. HashMap的底层数据结构
答:HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。首先,HashMap类的属性中定义了Entry类型的数组。
b. 对于HashMap<key,value>插入两个相同的key会出现什么情况
答:
import java.util.HashMap; public class Test { public static void main(String[] args) { HashMap<Integer,Integer> hashMap = new HashMap<Integer,Integer>(); hashMap.put(1, 1); System.out.println(hashMap.get(1)); hashMap.put(1, 2); System.out.println(hashMap.get(1)); } }
输出是:1 2,可以见HashMap是用覆盖来解决相同键的项的插入的。
c. 对一个类,如果它要成为HashMap的Key,需要做哪些工作
public class Student { int id; String name; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
这样一个类的对象是不能做为HashMap的key值的,我们必须首先重写equals方法,这个方法用来判定两个student是不是是同一个学生,这边要讲到一点HashMap的底层的知识,HashMap的底层实现是哈希链。来找到一个元素的插入位置需要经过两个步骤。1. 根据该元素的hashCode经过hash函数找到它所对应的链表的头指针 2根据这个元素的equals函数来判断它是否和该链表中的某一个对象是相同的。也就是说这边两个过程需要用到两个函数,一个是hashcode(),另一个是equals(),两个逻辑上相同的对象必须有相同的hashcode值并且调用equals函数返回值为真,所以需要重写上述两个函数:
public class Student { int id; String name; @Override public boolean equals(Object o) { Student s = (Student)o; return id==s.id?true:false; } @Override public int hashCode() { return id; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
具体见这篇文章http://blog.sina.com.cn/s/blog_6e5e2eb701012qxv.html
d:HashMap和HashTable的区别
答:HashMap 是Hashtable 的轻量级实现(非线程安全的实现),他们都完成了Map 接口,主要区别在于HashMap 允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。HashMap 允许将null 作为一个entry 的key 或者value,而Hashtable 不允许。HashMap 把Hashtable 的contains 方法去掉了,改成containsvalue 和containsKey。因为contains方法容易让人引起误解。Hashtable 继承自Dictionary 类,而HashMap 是Java1.2 引进的Map interface 的一个实现。最大的不同是,Hashtable 的方法是Synchronize 的,而HashMap 不是,在多个线程访问Hashtable 时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步。Hashtable 和HashMap 采用的hash/rehash 算法都大概一样,所以性能不会有很大的差异。
7. 大众点评问了三个数据挖掘算法,pagerank,naive bayes和kmeans,这个在这里就不细讲了。
8. SVM和核函数,也不细讲
9.不申请新的指针变量来实现链表倒置
答:递归
10.一个圆可以把平面分成两部分,N个圆可以把平面分成多少部分?
答:F(1) = 2 F(n) = f(n-1)+2*(n-1);
11.甲乙两人约好12:00-13:00之间碰面,如果某人先到,会等另一人15分钟。假设他们在12-13点之间到达的概率均等,问两人能碰面的概率是多少?
答:设甲乙到的时间分别是x y,(0<x,y<1),则(x,y)形成的面积为1,
约定条件为-0.25≦y-x≦0.25,在该条件下形成的面积为7/16,所以相遇概率为7/16。
12.一个正整数,
除以2余1,除以3余1,除以4余1,。。。除以10余1,
除以11余0
问这个数最小是多少?
答:X+1是2的倍数 x+1是3的倍数。。。
X-1是2-10的最小公倍数的倍数,而x是11的倍数
有x-1 = 2520m
2520*m+1 = 11n (m,n均为正数)
将11除至左边有229m+(1/11) m+1/11 = n
m = 10
13.输入一个double类型的数组A[0..n-1]和一个double类型的正数M,
求|M-A[i]*A[j]|的最小值(0<=i,j<n)
14.输入N,输出一个包含N个数还有+号或-号的序列,让这个序列的值等于0
例如输入N=7,
在1 2 3 4 5 6 7的六个空隙中插入符号(也可以不插入)
1-23-45+67=0
用递归和非递归写两种算法
15. 三个蛋,一个有金花,主持人知道。观众选一个,然后主持人会把剩下两个中砸开一个没有金花的蛋,
然后问观众,“现在给你一次机会,用你选的蛋换剩下两个中没有砸开的这个”,如果你是观众,为了选到金花,换不换?
答:换
因为流程不存在可变性,所以对于“换”和“不换”两个流程,我们可以观看整个流程,观众得到金花的概率:
如果不换,那么有1/3的可能观众得到金花,即金花在观众选的那个蛋里,
如果换,那么有2/3的可能金花在剩下的两个蛋中,只要换,这个蛋一定会被观众选中,所以观众选中金花的概率是2/3
16. A B C三个参与者进行博弈,任意两个人之间的对抗某一方取胜的概率都是1/2,那么首先A和B比,C直接和A与B比赛的胜者比,只有当某一位博弈者连续两次取胜这个博弈者才算取胜。那么C取胜的概率是多少?
答:设C取胜的概率是p,那么p = 0.5*0.5+0.5*0.5*0.5*p 所以p = 2/7;
17. 有三个红球和三个蓝球放入到两个盒子里,要求让某人从两个盒子里面随机的取一个球,拿到红球的概率最大,那么这个最大的概率是
答:一个盒子里面放1个红球,一个盒子里面放2和红球和三个蓝球,那么拿到红球的概率是(1/2)+(1/2)*(2/5)=9/10.
18.#include<iostream>
using namespace std;
class A
{
private:
int a;
public:
virtual void foo(){};
};
class B
{
private:
int b;
public:
virtual void foo(){};
};
class C:public A,public B
{
private:
int c;
public:
virtual void foo(){};
};
int main()
{
C* pc = new C;
B* pb = (B*)pc;
A* pa = (A*)pc;
cout<<((unsigned int)pc==(unsigned int)pa)<<endl;
cout<<((unsigned int)pc==(unsigned int)pb)<<endl;
cout<<((unsigned int)pa==(unsigned int)pb)<<endl;
}
http://chenuaizhang2008.blog.163.com/blog/static/72763572010724567118/
19.ArrrayList,StringBuffer,StringBuilder和Vector哪些是线程安全的?
答:Vector和StringBuffer是线程安全的,ArrayList和StringBuilder是线程不安全的