|
|
整理的百度面经
, G& p) c+ p/ A# x2 m
( k- p2 c: R5 {% n! Czz0 N. X. p) ]; f6 B1 ~
! o1 l8 C5 i7 l0 T5 c2 ?
7 a# ]) I% a5 [2 I; o一面1. 网络编程经验:
) ~ v9 P- _1 _. T 如何判断一个http请求,一个客户端请求已经结束;如何处理服务器多线程
7 t, Y( Z6 j f8 T/ F e 获得一个http请求后,是如何处理的?返回什么?有没有试过返回图片?
+ Q0 B5 x# `) G3 D0 l5 a 服务器给客户端请求时,是用什么函数写?服务器如何获取客户端请求,用什么函数
0 m/ y) ~9 M- |7 ? n4 U (需要函数级别的连接有一个认识)
) f& U) j6 S0 C* u* ?* Y; P' L7 `1 H! s' j* M
2. cv操作是什么函数 cv_init, cv_wait, cv_signal( o% z! \, ?3 Q- b; J! o# j7 I
1 ~4 H' f3 q* D. O0 j% |* H
3. 有一些关键词点击次数的文件,如何输出最多点击的一百个(当时应该回答,组织一个100个元素的最大堆)8 z& D: y! |0 q: N
# ?! e# M% R% G/ S) h; M4. 相交链表,如何找相交点(不能要标记)3 s |1 z2 m1 ?4 E& ?8 }
第一个头遍历到尾,知道他的长度;第二个头遍历到尾,知道他的长度。这样知道两截链表在交点前的长度,长的先走几步,然后一样长了,再轮流下走,就会相聚,相遇节点就是相交节点)
2 _% b) i- u2 G5 S6 \1 f/ C- L X$ f
& V( l: q, W7 y. Y5. 有些文件,频繁访问在磁盘里头的,现在要放到内存中了。采用什么策略来决定哪些放到内存中?如果是一些url文件,放在内存后,如何快速的找到某个url的位置(采用字典序或者b树之类树状结构来组织) 如何快速找到哪些文件太久没人访问了,把他替换出去?(再那一棵树,记录树里每个位置url的访问时间;同时,那个url树的节点,也有这个时间树的对应的位置信息。时间树采用最大堆组织。要替换出去时,就从树顶取走节点,并且从中获得这个节点在url树对应位置,把他从url树中取走。当url被访问时,由于url树节点有时间树的位置信息,所以也很快找到对应节点在时间树的位置,然后把他的访问时间更新,然后做堆调整,每次堆调整为logN)6 i4 `0 ^0 m* ^/ V6 R# M
1 o4 q2 v u" ^& U5 p7 U1 i6. c语言相关:内联函数的好处?非内联函数被调用的过程是怎么样的?
" Z! J- Q2 ~+ A- ]& c int,short,char的struct,这几个数应该怎么放,内存小?怎么防止头文件被include多次?: G' U% x6 A/ j `
) I2 e2 J/ T+ g/ _! h* j4 i9 z( C
7. 有没有什么问题想问的
- N- i+ y1 e! x! `5 h: y! N8 linux 网络查看的命令 T; H4 k5 C. g
7 B8 X/ \' V1 G( o5 W二面
, L j; ?/ @! x( m( C6 l1. 介绍一个项目# V+ b( L2 m' H: `# k
* M! b* v" ^& k0 R# h
2. 2.5亿个int数,可能有相同的。统计出这里头不同的数有多少个?只有2g内存。
3 t, ]# m6 ]' O(2.5*1000 000 000 * 4 =1G)
$ b& K1 g I5 J统计数-用hash,key是数,value是1或0,标记是否出现。4 ^+ g4 W3 O8 Q) S
如果key就是那个数,那么找一个数的时候,要遍历hash才知道有没有,慢(就是如果hash紧凑,慢)。) }' F* S% E! t2 R/ e9 ?1 ^# G
解决方案:把key作为连续的(就是hash是稀疏的,有个key值没有存在这2.5亿个数中),像数组下标一样,那么要访问第n个数,直接到第n个去看,复杂度是O(1)8 O0 J9 _' [( `2 X2 F9 N
但是,如果连续,2.5亿个数,范围很广,而每个key用int存,会很大量,内存不一定够。
& P5 z# r2 O k! e6 T' o解决方案:每个key用一位bit来标志。即数字1放在第一个bit上,数字2放在第二个bit上。看第n位在不在,就找一下第n个bit是1,还是0: i. T1 J. D% ?
具体方法:char a[] 数组。假设找3,那么3在3/8--0...3,所以在a[0]中,找第3个bit,如果是0,就设置为1。最后看看a[]的二进制表示有多少个1就有多少个数& _# U5 A* a' n! y
* C6 H* r$ W) [& x1 _3 q3. 海量数据,在mysql中,cpu占用率很高。如何解决?$ G. u3 R4 B& ]% H0 y3 H) @3 }
1.show processlist,看哪个sql查询的多,建索引(问:建立联合索引时,要考虑什么,怎么建(哪个在前,哪个列在后?)
8 i- s# z% u; C% P! t2.如果老是在拷贝到临时表,就改配置,把临时表内存改大些
) m9 R! Y G, V2 K* B3.还有什么方法: V7 W- ^% o2 k% P6 G" n Q4 o
1)分布式数据库 (问:如果你来设计分布式数据库,你会怎么设计?)
m- h u' r( \4 R& C2)使用缓存 (问:如果缓存中的数据,被删除或跟新了,数据库怎么判断这个缓存的数据不能用了,是脏数据?)(不懂)
; x1 p/ B2 Z: G& ], |; Z问:什么情况下cpu会高?(内存不足)为什么内存不足cpu会高(频繁io读写)4 ~1 {- F5 L$ R P, y* p
2 p1 J2 c; d( Q: D4. n个无序int,(有正有负),给一个数v,如何找出其中的a+b=v的两个数
+ O0 p' v. d( t. c" Q(我的答案是:排序 O(nlogn),记录序列中,0,大于v,小于v的3位。
, z4 L0 s; x# S* c" {尝试最小的和最大的,最大不行,次大。。。,找到某个,加起来小于v了,停止7 X+ u/ S$ B v) }
尝试次小的,从上次大头停止的位置开始尝试
4 ~$ k3 E. ?6 u/ `. Z---尝试范围两头不断缩小,复杂度为n) W5 }. R$ S8 O( z8 Y* r& Z
J8 I; w/ t/ I+ ^. ?
5. 网络相册,一个人可以有多个相册,一个相册有多个图片,如何快速实现增删查移动等操作。web页面上,图片是翻页显示。; R `' U4 c4 f8 r7 t
(我回答:数据库记录:usr_id, book_id, item_id, position。相片放在磁盘上,目录为position/usr_id/book_id/item_id( E# e* J& b* c0 h3 {
一次查两个操作:1)数据库查找2)根据位置取图片8 ^0 h! w( S, Y; {
% n$ }- R z. E0 b4 u
如果用户提取某个相册的所有图片,先给他第一个相片和所有item_id列表。然后用户翻页了,在客户端通过javascript能够知道翻的是哪个item,把item_id,book_id, usr_id发给服务器,服务器根据这个到目录下去找)
) o" X- I- m) t( Y! \: Z. p+ P8 H0 s(你这种设计会有什么问题?(答不上来。。。)(如果用户频繁翻页,那么服务器上会不断地在传输图片)(如何解决?)$ d- B, `" O$ p3 H0 i F! e
9 U' E# m9 }& Q$ c& m
第五题我想不出好办法,我觉得一般他们都show thumbnail
$ o o- B9 N' B0 `3 ~" [- g! M就是预览小图片不把原始图片show在页面上,点击后才能看单个图片8 H# Z6 [+ I: B) j+ I! W x. w
. J2 v* ^: s6 J8 X
5 I& p3 k5 C( Q! d; z* a6. Unix系统里,一个简单的print hello world的c程序,从./a.out执行到屏幕打印出来这句话,是什么过程/ w/ e: {' v: A; g* b5 h
(1.读elf,会从相对地址,计算出各个symbol的在进程中的绝对地址。然后找到入口main函数
3 f# Y, f; b/ ` K 1.用到std的库,所有有run time load。4 U& f' B/ }* w/ v1 K4 I
2.然后是print调用的进栈
$ i6 Y& n. }: z( Z: I. [1 J 3.然后是系统调用,当前进程被挂起。系统调用会调用驱动。。。(内核切换,用户态到内核态)/ ]: N/ _' y5 ^; A
4.内核处理完再唤醒当前进程。(切换)
& G8 ~5 N/ C$ A& e 5.print调用完毕,退栈3 X2 W2 h- O) m* j& n ]* o* y
6.main函数退栈: ]9 z4 {+ y4 x/ \, G7 O2 B
)
5 o' s8 ~! [, i# D( ~$ e7 t问:哪个进程来调用的main?(不知道). `9 n- `4 ?+ P8 ?
应该是当前运行a.out的这个和用户交互的shell作为父进程,然后父进程fork子进程,子进程和父进程一样,然后调用execv会load执行文件,和把参数传到main的堆栈中: Y2 g8 j/ {8 N5 ~3 e: h
# g- T. K1 }1 V4 o; q- X
7.socket编程,要注意什么问题
. _' Z- P5 a5 [+ V/ s7 _(服务器的serversocket的基本模型。# w5 Y2 K H+ J! X! V' U4 Q4 ]
但是大量请求,会不能及时响应。所以要多线程。: M" ^8 q8 n9 J7 N8 P
一个监听线程,多个服务线程。服务线程一开始起来都阻塞在存放请求socket的tasklist上。wait
9 B6 ]" V, \4 E1 V8 ^) y- S监听线程接受到client的socket,放入tasklist中,signal唤醒一个服务线程。服务线程处理它,并把它从list中移走0 R* e: E& d) v8 F' i; |: ~4 X
注意问题:tasklist的存放的请求socket是会被放和移走的,消费者生产者问题。所以要synchronized来互斥?)% B. ^; M2 H9 Z- z3 }* S% c @9 i: d) T
, ~0 r* a- G$ A0 D
三面
% T) |$ w5 f2 G4 K7 d, o k( ?! B/ }' y* C9 J9 x4 v( n: S
! D3 Q. i9 O# V) l2. fread的过程(文件系统-内核。。。)
& s0 o r) n8 r2 _7 ?3. 主DB在接到数据更新后同步到后台DB,如何避免网络丢失之类的问题
0 e2 [5 t$ `) M8 v$ B(参考答案1:传的是sql语句,接到后回ack,如果主DB发现一段时间没有回,重发;其实TCP传输,就保证了不会漏数据,所以不会考虑这个问题的)' a' d3 Y% H e, a) q
(参考答案2:每次传sql语句和当前版本号,然后后台DB会对比版本号是不是正确,发现落后就发数据请求。主DB保留每次版本号更新关联的sql语句)
9 m" X' T4 p$ d8 Z5 ]4. N个bit,如和判断其中有多少个1.(时间复杂度小于N)$ y x- I" E$ g2 h2 M2 \
预存一个2的8次方大小的数组,每个数组值是,这个下标的数的二进制的1的个数,例如:
N9 g: C9 u+ }& wa[0]=0, a[1]=1, a[2]=1,a[3]=2....a[2^8-1]=7 (以空间换时间)2 Z. q- `9 ?# q7 c/ T
& r" i C+ m2 `! R7 o& M然后一个byte一个byte的读,看看他的值,直接以这个值为下标去数组看他的1的个数( i; P; |# B( l8 K$ Y9 b
! {7 N# ]( d- o) `
/ l7 d: Z0 p) T+ r( c另一个方法:7 a. H0 s- _, Z
# S( N0 x# { e8 g9 W+ h# c
while(v){
1 h1 _; u' S$ n2 l4 o1 P2 Ov &= (v-1);7 q/ Y+ |+ o8 l/ {% e
num++;
+ c5 }; Q2 {; V" L}# p I, B5 t4 Z1 M/ L$ T7 G
1000 & 0111 = 0, 所以每&一次,不为0,说明有1个1,&到为0为止,num就是1的个数。复杂度为1的个数。& P5 ^) }8 F$ N3 N/ k% h$ ?/ e' `
. c, D- @0 @3 }$ y$ cZz6 M/ g* H, S$ ]
该内容转载自网络,版权归原作者所有。6 J z, k6 @7 u; ^+ e; _6 z* C: \" ]
2 c3 m. @# c1 o/ H1 R) |& ^ g+ r' F# U. ?……' n! d6 s- X/ W- h8 }0 L
http://bbs.aftjob.com/thread-164201-1-1.html
6 D2 Q- [! G- f8 R6 L
. D. q V" s l. U- t1 v7 Z% U) d0 n( h; |7 R4 k- \+ }, f7 V
百度(Baidu)求职俱乐部
$ }4 s3 b n( ]2 z' g& K5 W% z' y/ m+ ^http://bbs.aftjob.com/group-4-1.html
( n7 X8 v/ K2 e7 e& k- s. I; W0 H; i m
# W+ W# m1 F" M& m( A7 i |
|