|
|
整理的百度面经* m. z% ]* Q1 v- n" j$ O3 w
- E$ X4 Q$ M1 q( K/ N* u; w; l
zz
6 {, R, Y8 x5 h! O- T
) x" e3 v8 J1 n- W+ E6 l3 H1 d6 l; y0 S5 @. d+ G
一面1. 网络编程经验:
; _0 T7 r4 ]( p. Z* g 如何判断一个http请求,一个客户端请求已经结束;如何处理服务器多线程7 W1 o& u% ]; x0 }
获得一个http请求后,是如何处理的?返回什么?有没有试过返回图片?
+ P1 N: R1 p4 h2 |+ h3 Z& A 服务器给客户端请求时,是用什么函数写?服务器如何获取客户端请求,用什么函数6 P' U6 }3 D( W0 p
(需要函数级别的连接有一个认识): Z3 ~; `2 }9 p5 V7 m. y
0 L& z$ m0 W- _* L, e. Y
2. cv操作是什么函数 cv_init, cv_wait, cv_signal3 S9 x0 n4 l0 M3 |5 f
5 B8 K5 M8 t9 H9 x2 e
3. 有一些关键词点击次数的文件,如何输出最多点击的一百个(当时应该回答,组织一个100个元素的最大堆)& L. [) y3 k) J9 T
; A1 |' V8 n9 E& [% h9 n
4. 相交链表,如何找相交点(不能要标记) x! I8 q; @( `7 }& n! F' R
第一个头遍历到尾,知道他的长度;第二个头遍历到尾,知道他的长度。这样知道两截链表在交点前的长度,长的先走几步,然后一样长了,再轮流下走,就会相聚,相遇节点就是相交节点)/ G6 C6 e. O( [4 b* m
8 \# G* n. R! x, Q1 y9 A9 }. y4 O
5. 有些文件,频繁访问在磁盘里头的,现在要放到内存中了。采用什么策略来决定哪些放到内存中?如果是一些url文件,放在内存后,如何快速的找到某个url的位置(采用字典序或者b树之类树状结构来组织) 如何快速找到哪些文件太久没人访问了,把他替换出去?(再那一棵树,记录树里每个位置url的访问时间;同时,那个url树的节点,也有这个时间树的对应的位置信息。时间树采用最大堆组织。要替换出去时,就从树顶取走节点,并且从中获得这个节点在url树对应位置,把他从url树中取走。当url被访问时,由于url树节点有时间树的位置信息,所以也很快找到对应节点在时间树的位置,然后把他的访问时间更新,然后做堆调整,每次堆调整为logN)
+ N1 x+ M% E! ? v
9 N1 ?+ B4 Y$ \/ a& I6 V6. c语言相关:内联函数的好处?非内联函数被调用的过程是怎么样的?
2 _. q4 M0 J; A) i* a int,short,char的struct,这几个数应该怎么放,内存小?怎么防止头文件被include多次?
c% w i; m/ i* J, n0 M, ^
( U8 V$ q7 [& S! L7. 有没有什么问题想问的
4 m# a& G: t8 T2 ^& }8 linux 网络查看的命令
' e$ F) G- l6 O; [/ e$ Y9 _( D: E5 M8 F
二面
$ j2 K+ Y4 `2 m* O1. 介绍一个项目" r9 {6 J' ~0 a% L0 l. V: C
5 [6 v2 k2 \8 @; }! V2. 2.5亿个int数,可能有相同的。统计出这里头不同的数有多少个?只有2g内存。3 Z+ \% l1 l9 b& ~* r6 Z
(2.5*1000 000 000 * 4 =1G)
$ _; a2 b' K; a N2 L9 E. m统计数-用hash,key是数,value是1或0,标记是否出现。
+ A5 U) p% j# m如果key就是那个数,那么找一个数的时候,要遍历hash才知道有没有,慢(就是如果hash紧凑,慢)。
9 z& n& S4 m8 P2 p( S. F解决方案:把key作为连续的(就是hash是稀疏的,有个key值没有存在这2.5亿个数中),像数组下标一样,那么要访问第n个数,直接到第n个去看,复杂度是O(1)# o" s; D( a! p$ ~# p$ @
但是,如果连续,2.5亿个数,范围很广,而每个key用int存,会很大量,内存不一定够。/ {- U) x S- d
解决方案:每个key用一位bit来标志。即数字1放在第一个bit上,数字2放在第二个bit上。看第n位在不在,就找一下第n个bit是1,还是0
6 r; P. o6 {7 l. }/ r- z) X9 V具体方法:char a[] 数组。假设找3,那么3在3/8--0...3,所以在a[0]中,找第3个bit,如果是0,就设置为1。最后看看a[]的二进制表示有多少个1就有多少个数
6 [) F0 `( @+ l
! g& D, E$ T! W/ z% m3. 海量数据,在mysql中,cpu占用率很高。如何解决?
0 E% |2 ]: `6 x7 z4 b# m, I1 I% T, j1.show processlist,看哪个sql查询的多,建索引(问:建立联合索引时,要考虑什么,怎么建(哪个在前,哪个列在后?)
8 [8 U" B3 c' h( R; Y. _2.如果老是在拷贝到临时表,就改配置,把临时表内存改大些$ k8 I7 f/ l9 f. f& l$ M
3.还有什么方法:
/ |, z: }9 k$ h l& M3 t6 `1)分布式数据库 (问:如果你来设计分布式数据库,你会怎么设计?)6 l9 G* `/ s& ? k D3 ~0 V1 `" j
2)使用缓存 (问:如果缓存中的数据,被删除或跟新了,数据库怎么判断这个缓存的数据不能用了,是脏数据?)(不懂). v( f8 c+ p/ S* k2 g, ~
问:什么情况下cpu会高?(内存不足)为什么内存不足cpu会高(频繁io读写)* `7 i! H" \8 X$ c
7 O: [. T0 E; E F a6 L
4. n个无序int,(有正有负),给一个数v,如何找出其中的a+b=v的两个数
( C8 A0 B; f3 d E$ Z1 Y2 v(我的答案是:排序 O(nlogn),记录序列中,0,大于v,小于v的3位。; h- ^ Q' x: k/ c/ I1 i' [8 d
尝试最小的和最大的,最大不行,次大。。。,找到某个,加起来小于v了,停止) {9 g+ F" l. O; A3 p- C# n
尝试次小的,从上次大头停止的位置开始尝试
, l d/ P4 E& E+ }9 c---尝试范围两头不断缩小,复杂度为n)
0 { B% C9 r$ O& `+ ` h4 d; M8 o& f( q; n
5. 网络相册,一个人可以有多个相册,一个相册有多个图片,如何快速实现增删查移动等操作。web页面上,图片是翻页显示。4 i. Q/ p& i) d v8 }
(我回答:数据库记录:usr_id, book_id, item_id, position。相片放在磁盘上,目录为position/usr_id/book_id/item_id9 u6 p- a$ u) _3 f: [. k
一次查两个操作:1)数据库查找2)根据位置取图片
0 |( @" H# T B* a6 g3 c, q' N, c
0 m$ ?! u8 l8 \- J4 o3 o) ^5 g! U如果用户提取某个相册的所有图片,先给他第一个相片和所有item_id列表。然后用户翻页了,在客户端通过javascript能够知道翻的是哪个item,把item_id,book_id, usr_id发给服务器,服务器根据这个到目录下去找)
$ m2 A& M) ?5 `7 G7 w(你这种设计会有什么问题?(答不上来。。。)(如果用户频繁翻页,那么服务器上会不断地在传输图片)(如何解决?), t6 \0 i F. T
& k7 K+ N/ T" m" Y
第五题我想不出好办法,我觉得一般他们都show thumbnail
, Q: ?& u' x9 \4 e就是预览小图片不把原始图片show在页面上,点击后才能看单个图片& U6 e; D3 n& A% y1 i& w+ d
! i0 Z4 N! G2 ^5 c& w
8 g: I$ [ h/ C- b3 o0 \0 i) Y6. Unix系统里,一个简单的print hello world的c程序,从./a.out执行到屏幕打印出来这句话,是什么过程: w: j9 S9 ]) d+ q
(1.读elf,会从相对地址,计算出各个symbol的在进程中的绝对地址。然后找到入口main函数2 a) Y: B* l: r' _9 F$ o$ | f- E* ~4 j
1.用到std的库,所有有run time load。
: _$ m$ P4 `$ ]. c 2.然后是print调用的进栈
6 @# V. B; v% n& m2 E+ n 3.然后是系统调用,当前进程被挂起。系统调用会调用驱动。。。(内核切换,用户态到内核态), l, O0 W& m! P6 U' B6 [
4.内核处理完再唤醒当前进程。(切换)4 Y4 @& Y& u; j' V- v* A( S( ~
5.print调用完毕,退栈 g7 ?# Q6 d& b8 X7 B+ W1 f
6.main函数退栈
1 ^1 O, U4 e+ |, M)
- j4 G' i9 M: v' t2 ]0 \6 d问:哪个进程来调用的main?(不知道)
: x) D3 } A6 h8 I3 |应该是当前运行a.out的这个和用户交互的shell作为父进程,然后父进程fork子进程,子进程和父进程一样,然后调用execv会load执行文件,和把参数传到main的堆栈中
+ v) X% L3 x7 y/ ^* J
% K) k* s0 o) R7.socket编程,要注意什么问题
" x8 n+ A# x" O1 t( i8 n(服务器的serversocket的基本模型。
' i1 |* F2 L, T2 P; w: ^但是大量请求,会不能及时响应。所以要多线程。
: U$ v" i: C( m) ~" G一个监听线程,多个服务线程。服务线程一开始起来都阻塞在存放请求socket的tasklist上。wait$ ]; ]) X0 O/ O4 D' x
监听线程接受到client的socket,放入tasklist中,signal唤醒一个服务线程。服务线程处理它,并把它从list中移走
9 P: Q @( R. y$ \: R1 N注意问题:tasklist的存放的请求socket是会被放和移走的,消费者生产者问题。所以要synchronized来互斥?)1 `$ x: c7 E+ i6 U
( Q' n; E6 n( G
三面
0 A2 U: _" ]: K+ ~" u& q; @+ P6 w' }! U) f
$ A( ~, \8 i( y, \$ _# N; r2. fread的过程(文件系统-内核。。。)
1 A$ N0 W. O$ G) e& @3. 主DB在接到数据更新后同步到后台DB,如何避免网络丢失之类的问题
$ U, _ k3 E: A( _" i& ](参考答案1:传的是sql语句,接到后回ack,如果主DB发现一段时间没有回,重发;其实TCP传输,就保证了不会漏数据,所以不会考虑这个问题的)" @, c9 L# C" w" B1 G# }
(参考答案2:每次传sql语句和当前版本号,然后后台DB会对比版本号是不是正确,发现落后就发数据请求。主DB保留每次版本号更新关联的sql语句)
4 G, k# z N$ n5 }+ e( Y& h4. N个bit,如和判断其中有多少个1.(时间复杂度小于N)5 D+ H; r$ D H; g0 f+ N# \" o! _
预存一个2的8次方大小的数组,每个数组值是,这个下标的数的二进制的1的个数,例如:
" ?* W6 b$ ~! G* L2 B5 _: |$ E5 v. U3 Za[0]=0, a[1]=1, a[2]=1,a[3]=2....a[2^8-1]=7 (以空间换时间)
% x: D" F: ~4 T8 z
* v$ N/ ~( ~0 T0 b3 r+ f2 q& N然后一个byte一个byte的读,看看他的值,直接以这个值为下标去数组看他的1的个数
- Y7 y3 t4 X1 o9 [ P2 d
) Z- W/ B$ |8 |0 `7 H
! x. r" U& \1 b另一个方法:
# _3 u# } P) j3 H! Y
4 J( T! D1 G. C: i3 hwhile(v){# f$ k* u5 _2 L- F
v &= (v-1);& G: T) J0 v5 v* ^: W9 ]
num++;, x$ F/ [+ O i9 N! l
}" _0 k9 x5 p" X+ X' c i1 p0 k2 c
1000 & 0111 = 0, 所以每&一次,不为0,说明有1个1,&到为0为止,num就是1的个数。复杂度为1的个数。1 Z- k; |% B- x# Y# D) |" b
+ _; H0 G5 W; T) @% O+ X
Zz6 o$ F$ X! ?1 J
该内容转载自网络,版权归原作者所有。3 a6 E; ?$ V4 _9 Q+ [& C9 S
- u8 ?" o/ R4 Q8 ^0 P2 i% l……, a9 j$ K& M; T6 G0 O& L( P
http://bbs.aftjob.com/thread-164201-1-1.html s `9 M8 M! m/ p8 s
6 p- p' G7 @ J0 C. \* m0 S
# q# \% l! A0 T4 K7 o. ]: M# o百度(Baidu)求职俱乐部 6 O" v( w/ k' b, m f" N
http://bbs.aftjob.com/group-4-1.html
! T$ z p8 R- w* ~* K+ w6 b+ l8 g0 C) p
|
|