1.下列減小內存碎片的方法有哪些是正確的?php
增長實際申請和釋放的次數 頻繁調用的子函數儘可能使用棧內存 系統申請一大塊內存,本身實現內存分配和釋放,定時清理內存 下降虛擬內存的大小
解答:html
答案2,3
是正確的。屬於操做系統中內存管理的問題。前端
考點:Stack與Heap的區別:vue
stack | heap | |
---|---|---|
分配 | 編譯後就已經固定下來 | 手動向內核申請 |
釋放 | 運行後自動pop釋放 | 手動釋放/使用ARC(iOS)/使用GC(Java),這裏注意內存泄露 |
性能 | faster | slower |
適用場景 | 基本類型,函數 | 大的數值,動態數組,對象 |
考點:虛擬內存(Virtual memory)linux
在32位Unix下,進程啓動後,能夠獲取到4GB的虛擬內存,其中內核佔用1G,用戶佔用3G,虛擬內存是經過物理內存(physical memory)與交換空間(swap)進行分配的,它對於進程是透明的,系統經過地址轉換功能(好比MMU,內存管理單元)進行虛擬內存與實際內存的轉換。android
如下爲進程中內存的分配管理nginx
什麼是內存碎片?程序員
- 內部碎片: 線程佔用內存而不利用或者釋放的內存空間。
- 外部碎片: 內存空間過小以致於沒法分配的內存空間。
2.給定一個數組a[M],其中M爲常量值,下列哪幾個表達式可求出數組a的長度大小?golang
sizeof(a); sizeof(a)/size(*a); sizeof(a[0]); sizeof(a)/sizeof(a[0]);
解答:
個人答案是2,4。考的是指針類型。
int*
與 int[M]
的類型是不一樣的,可是能夠強制類型轉換;總結以下
&a | a | *a | |
---|---|---|---|
type | int * | int [M] | int |
size | 8(on 64bitOS) | M * 4 | 4 |
3.如下哪些是HTTP協議裏面定義的URL組成部分:
schema path port host query-string
解答:
這道題答案是除第一個之外
。考的是實際中對網絡編程的理解。
URL實際上就是是對資源的一種描述:
<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]<query-string>
scheme 指協議類型,常見的協議類型有market,http,content,media,file,固然協議類型也能夠自定義,好比簡書中使用的就是 jianshu
做爲默認URL的。
好比HTTP-GET的例子:
http://www.blackswift.com:8080/api/v2/getimagelist?limit=10
很顯然,這個HTTP例子中除了HTTP
自己已經有了,其它全部的組成都有體現。
4.關於主鍵和惟一索引如下哪些說法是正確的?
惟一索引能夠有多個 惟一索引所在的列不容許空值 惟一性所在的列並非表的主鍵列 一個表必須有主鍵列
解答:
答案1,3,4是對的。
主鍵 | 惟一索引 | |
---|---|---|
個數 | 有且只有一個 | 0,1,多個 |
Allow NULL | x | √ |
與對方的關係 | 充分沒必要要 | 必要不充分 |
5.已知人臉檢測器的檢出率(人臉圖被檢測爲人臉的機率)爲90%,誤檢率(非人臉被檢測爲人臉的機率)爲1%. 請問當一張被人臉檢測器識別爲人臉時,該圖爲人臉圖的機率是多少?若給定一個圖片集中,其中20%的圖片爲人臉圖,80%的圖爲非人臉圖,當該集合中的某一張圖被人臉檢測器檢測爲人臉時,該圖爲人臉的機率又是多少?
1. 沒法肯定, 45/47 2. 90/91, 45/47 3. 沒法肯定,90/91 4. 90/91,90/91
解答:
選擇1
;
第一問,
A = P(圖片是人臉);
B = P(機器檢測出人臉);
P(B|A) = 90%;
P(B|~A) = 1%;
P(B) = P(B|A)xP(A) + P(B|~A)* P(~A) = 0.9A + 0.01(1-A);
根據貝葉斯公示:
P(A|B) = P(B|A) * P(A)/P(B) = 0.9 * P(A)/(0.89A + 0.01)
A爲止,因此沒法肯定。
第二問,
P(A) = 0.2,代入完成。
6.MongoDB採用了一下哪一種分佈式方式?
1. Single-Master 2. p2p 3. Master-Slave 4. Replica Sets
解答:
解答我放棄了...英文資料都不多,只知道這個技術在LeanCloud上引起過一次事故,可是新技術仍是值得推廣。
MongoDB屬於NOSQL(Not Only SQL)數據庫,是一種開源的分佈式,基於k-v,基於文本(好比磁盤/RAM)的數據庫。
7.iOS開發中,非ARC下這段代碼執行的結果是什麼?
//相似於Java,用註解定義接口 @interface OCObject : NSObject -(void)printDescription; @end //接口的實現 @implementation OCObject -(void)printDescription{ NSLog(@"OCObject printDescription!"); } @end //手動分配內存,alloc並init OCObject *obj = [[OCObject alloc]init]; //執行方法,`performSelector`相似於Java中的反射,也是在運行時找的。 [obj performSelector:@selector(printDescription) withObject:nil afterDelay:60]; [obj release];
1. 不會打出任何消息 2. 會輸出OCObject printDescription! 3. 會crash 4. 編譯不經過
解答:
答案是2
ARC是 Automatic Reference Counting
,即自動引用計數器,在iOS開發中,蘋果不但願開發者控制內存,因此使用ARC幫助開發者在編譯的時候自動加上內存回收的代碼。
如下爲測試結果:
Xcode6.3/ARC on/iOS8.3
下,編譯不經過,要求刪除release,刪除後編譯經過,輸出Log;
Xcode6.3/ARC off/iOS8.3
下,編譯經過,輸出Log。
若是有懂得iOS開發的就留言解釋一下吧,我畢竟是寫Java的。
8.如下對C++(C++98標準)語言描述中正確的是
1. C++提供了對全局對象初始化順序控制的機制 2. C++沒有提供固定大小的整型 3. C++支持多維數組 4. C++支持類類型的成員常量
解答:
答案是1
3
4
int8_t
,int16_t
,int32_t
, 甚至int64_t
,因此是有固定大小的整型;const
修飾。9.Java中BufferedInputStream,DataInputStream等IO類是哪一種設計模式的典型應用?
1. Adapter 2. Decorator 3. Factory 4. Observer
解答:
網上的答案是1
2
。
Adapter:是適配器模式,數據源 -> Adaper -> 另外一個數據格式,常見的有充電器,ListView這樣的設計。Stream是對輸入/輸出的抽象,爲使用者提供一個統一的接口,使用者使用這個接口而沒必要關心它的實現。在Java I/O中提writer與stream的轉換。
Decorator:是裝飾模式,經過給對象進行裝飾封裝而不改變結構,達到實現更多功能的做用。好比File,Data等Stream都是裝飾出來的。還有常見的外包項目,不想重構的話就裝飾一下吧。
Factory:工廠模式,在構造函數中使用,stream中沒有使用。
Oberser:觀察者模式,經過發佈-更新
進行數據處理,好比RxJava,Otto。
更多設計模式能夠看 ——> 這裏
10.請問下列代碼,當x =0x7c和x=0f2時,運行結果分別是什麼?
int main(){ char x = 0xF2; int nConut = 0; //這裏的x 就是 x!= 0x00; for (; x; x>>=1) { ++nConut; } printf("nCount = %d ",nConut); }
解答:
答案分別是7
,死循環
。
第一個是簡單二進制操做題目,用於判斷它有多少位。至於第二個,是負數。
0x00 ~ 0x7f | 0x80 ~ 0xff | |
---|---|---|
char | 0 ~ 127 | -128 ~ -1 |
負數右移是補1,最後就是0xffffffff了
11110010 11111001 11111100 11111110 11111111
因爲-1始終不爲0,因此會死循環。
無符號右移(unsigned right shift)在iOS中是沒有的,在Java中是有的。
看到
char
,第一步要想到寫防衛代碼
11.下列方法獲得的NSString對象不同凡響的是:
NSString *str = @"Hello"; NSString *str2 = [NSString stringWithFormat:@"%s","Hello"]; NSString *str3 = [NSString stringWithFormat:@"%s","Hello"]; NSString *str4 = [[NSString alloc]initWithString:@"Hello"];
解答:
答案是第四個,它調用了malloc,是在堆中(運行時)申請的,須要手動釋放(若是沒有用arc的話),而其它幾個是編譯時(棧中)就已經固定在_DATA段了。
12.在一個路由表中,假設有下面三條路由:192.168.128.0/24, 192,168.130.0/24, 192.168.132.0/24,若是進行路由匯聚,能覆蓋這三條路由的地址是:
192.168.128.0/21 192.168.128.0/22 192.168.130.0/22 192.168.130.0/23
解答:
答案是第一個。
1100 0000.1010 1000.1000 0000.0000 0000 1100 0000.1010 1000.1000 0010.0000 0000 1100 0000.1010 1000.1000 0100.0000 0000
能夠看出,公共節點在21位。
13.程序運行的結果是?
#include<stdio.h> struct A { unsigned char x; unsigned char y; int z; }; int main(){ struct A a; a.x = 10; a.y = 20; a.z = 30; *((int*)&a) = 0x010101ff; printf("%d,%d,%d,%d",sizeof(a),a.x,a.y,a.z); return 0; }
解答:
8,255,1,30
本題有2個重點:
在結構體對齊中,咱們要知道,爲了提升內存讀取效率,須要把結構體中的成員按照2^n(Power-of-two)來進行對齊(align)的,對齊準則是
MIN(Max(DateType),#pragma pack(n));
意思就是找出結構體中佔用空間最大的數據類型,並以它爲基本對齊。若是使用#pragma pack(n)
手動指定對齊的話,就取它們兩個的最小值。在OSX(LP64)中,根據官方的文檔,對齊標準是這樣的。
DateType | ILP32size | ILP32alignment | LP64size | LP64alignment |
---|---|---|---|---|
char | 1 | 1 | 1 | 1 |
short | 2 | 2 | 2 | 2 |
int | 4 | 4 | 4 | 4 |
long | 4 | 4 | 8 | 8 |
pointer | 4 | 4 | 8 | 8 |
size_t | 4 | 4 | 8 | 8 |
long long | 8 | 4 | 8 | 8 |
fpost_t | 8 | 4 | 8 | 8 |
off_t | 8 | 4 | 8 | 8 |
回到題目,咱們能夠看出,結構體是按照Int,也就是4byte來對齊的
value | x | y | 填充0 | z |
---|---|---|---|---|
address | 0x00 | 0x01 | ... | 0x44~0x47 |
因此sizeof爲 (4+4) = 8
.
接下來,是指針問題,咱們先翻譯這句話
*((int*)&a) = 0x010101ff;
它實際上就是取a的地址,而後把a到(a+4)byte中的內容換成0x010101ff。僞代碼以下,注意這裏與大小端無關,變量是放在棧上的
a.x = (0x010101ff)&0xff;//替換低位值 a.y = (0x010101ff>>2)&0xff; a,z不受影響啦
也就是這樣
address | 0x00 | 0x01 | ... | 0x44~0x47 |
---|---|---|---|---|
value | 0xff | 0x01 | 填充0 | 仍是30不變 |
這下你明白了吧,若是咱們再進一步修改
*((long*)&a) = 0x01ffff01ff;
輸出結果就是 8,255,1,1
在64中,除了long與pointer是八位的,其它的差異不大。
14.在SQL語句中,與X BETWWEN 20 AND 30 等價的表達式是:__?
解答;
20<= x <= 30,是包括邊界的,最多能夠取出11個數。
15.在iOS開發中,須要實踐一個簡單的http協議通信,可用的工具/組件有?
BSD Socket API CFSocket NSStrem NSSURLConnection
解答:
答案是NSSTream
與 NSSURLConnection
。
前面兩個Socket是屬於傳輸層的,面向底層網絡鏈接,要是本身重寫一個HTTP那還不得累死。在Android中,有URLConnnection
,OkHttp
,Volley
等組件。
- 有興趣的能夠看下我寫的OkHttp源碼分析
- 說個題外話,若是使用第三方庫的話,建議加個適配器,以避免之後升級改動麻煩
16.下列關於棧的說法哪些是正確的?
1. 棧是後進先出的 2. 一般棧空間大小在編譯時指定,並在程序運行時由操做系統管理(分配,釋放等) 3. 全部定義在函數內部的變量都是從棧上分配內存 4. 棧的使用效率比堆高 5. 棧內存具備讀,寫屬性
解答:除了3
是錯的,別的都是對的。注意函數內部的malloc。
17.忘了,題目考了TCP的握手
18.如下js代碼的運行結果是?
function Parent(){ this.sayHi = function(){ alert("hi Parent"); } } function Child(){ Parent.apply(this); this.sayHi = function(){ alert("hi Child"); } } var p = new Parent(); var c = new Child(); var p = c; p.sayHi();
解答:
答案是hi Child
, Java引用基礎題。另外還有靜態-構造函數-繼承
優先級這樣的問題,本身查詢。
19.如下哪些是前端的構建工具?
Grunt Gulp Nodejs Angularjs BootStrap
解答:這個回答看運氣了....突飛猛進的前端。
第一,二個確定是,不少招聘帖上都寫的有。第三個不肯定,它徹底是新的一套引擎(解釋器都換了),包管理也是npm纔對。後面兩個是前端框架。
突飛猛進的前端,目前還有vue.js, Native.js, framework7,rxjs等等。前端每天在吵架,然並卵,就像在android中神話了的MVVM,代碼量並無減少。
我我的比較看好React-Native,一次學習,四處編寫。
20.二進制0.101001B等於十進制()?
0.640625D 0.620125D 0.820325D 0.804625D
解答:0.640625D。
1/2 + 1/8 + 1/64 = 0.5 + 0.125 + 0.015625 = 0.640624D
21.關於數據類型的取值範圍,在Java中執行語句 byte b = (byte)128,請問b的值是多少?
1. -1 2. 128 3. -128 4. 出錯
解答:
答案爲128
;
第一,強制轉換實際上就是添加mask,僞代碼以下
0x80 & 0xff;
第二,char與byte的區別(特指C中)
0x00 ~ 0x7f | 0x80 ~ 0xff | |
---|---|---|
byte | 0 ~ 127 | 128 ~ 255 |
char | 0 ~ 127 | -128 ~ -1 |
若是咱們把byte改爲char,結果就是-128
了,由於java中的char是有符號並且是雙子節的。
22.關於下面程序執行的結果,有哪些是正確的:
var a = 10; function fn(a){ var a = 20; alert(a); } fn(a); alert(a); var a; alert(a); var a = 30; alert(a);
1. 20,10,10,30 2. 20,10,undefined,30 3. 20,20,100,30 4. 10,20,undefined,30
解答:
答案是20,10,10,30
。這個題目要是在C語言中運行的話,會報錯3次redefined a
,而本題中最迷惑的就是 var a;
,在js中
23.Python代碼....咳咳,題目圖片自己就壓了好幾遍。
解答:單例模式
24.網絡帶寬擁堵可能致使如下哪些問題?
1. UDP丟包變嚴重 2. tcp數據被寫亂 3. tcp丟包 4. tcp傳輸速度驟降
解答:1
3
4
網絡擁塞通常是由三個緣由照成:
解決擁塞:知足上面三個短板,或者用不道德的工具(好比銳速)搶出口。
25.看不清了,題目自己就不清楚。
26.下列函數的時間複雜度是
int foo(int n){ int i = 1; while(1 <= n){ i = i*2; } return 1; }
解答:
答案是O(log2N)
,很是簡單。這裏的 i = i*2
能夠用 i <<= 1
來優化哦。
27.使用快速排序對{83,123,69,179,118,13,190}進行升序排序,請問以下那個是第一趟快排交換後的結果?
1. {13,69,83,179,118,123,190} 2. {13,83,69,179,118,123,190} 3. {13,69,83,118,179,123,190} 4. {13,123,69,179,118,83,190}
13 69 123 179 118 83 190
解答:答案是 1
選擇83做爲pivot,i,j同時從左邊走,i表示最左邊的大於83的數,j用於向右開擴;
83,123,69,179,118,13,190
83,69,123,179,118,13,190(69 resolved)
83,69,13,179,118,123,190(13 resolved)
13, 69, 83,179,118,123,190 (83 inserted)
原理能夠參考 http://me.dt.in.th/page/Quicksort/ 的 Partitioning
28.關於TCP和UDP協議的說法正確的有:
1. TCP是面向鏈接的協議,而UDP是無鏈接的協議 2. TCP創建鏈接過程當中,協議棧須要進行三次握手,而關閉鏈接則須要進行4次握手; 3. UDP協議經常用於容忍丟數據,但須要更高傳送性能的業務場景; 4. UDP和TCP協議棧都具有保證數據包時序性的能力,並經過滑動窗口機制進行擁塞控制。
解答:1
2
3
29.假設代碼以下:
#include<stdio.h> #pragma pack(8) struct X{ uint8_t a; uint32_t b; uint16_t c; }; #pragma pack() int main(){ struct X x; printf("%d\n",sizeof(x)); return 0; }
解答:
答案是12。同剛剛的那道結構體對齊的題目,公式以下
MIN(MAX(DataType),#pragram pack(8)) = MIN(4,8); = 4;
因此以4byte爲準則進行對齊,它的內存佈局以下
address | 0x00 | 0x01 ~ 0x03 | 0x04 ~ 0x07 | 0x08 ~ 0x09 | 0xa0 ~ 0xa1 |
---|---|---|---|---|---|
value | a | padding | b | c | padding |
若是咱們如今改一下結構體的佈局
struct X{ uint8_t a; uint16_t c; uint32_t b; };
它的佈局是這樣的
address | 0x00 | 0x01 | 0x02 ~ 0x03 | 0x04 ~ 0x07 |
---|---|---|---|---|
value | a | padding | b | c |
這樣,結構體的佔用就變少了,sizeof由12變成了8。
在底層中,一般用
UCHAR reserved[]
進行手動填充,以避免被編譯器等外部條件坑。
30.一顆二叉樹有5個節點,樹的形態有多少種?
1. 38 2. 42 3. 46 4. 58
解答:42
考的是遞推。以根節點爲開始,按照左一右零,左一右一,左零右一的三個方向進行調用,網上有公式。
大題(60分鐘)
1.請儘量多的列舉/描述出你所瞭解的個進程間通訊機制已經對應的應用場景,各自的優缺點。
這個有點hold不住,我儘量說本身可以有參考的答案。
ASM。在android中,咱們常說的廣播,Intent本質都是ASM,好比Binder,AIDL,共享同一個內存而不用複製,在linux中,映射爲/dev/ashmem
文件。
Socket。好處固然是便於服務器控制,並且方便抓包減小互相推諉的可能性,並且當你走內部地址(好比環回地址)時,數據不用通過物理網卡,OS內核還能夠進行某些優化。使用上在android中好比百度全家桶後門自動用IPC喚醒甚至靜默安裝APP;在跨平臺開發中,大部分使用socket進行通訊;
管道(Pipe)。最簡單的例子就是linux的命令,好比ls | grep *.png
,中間就是管道;在好比說在golang中,天生自帶管道。android中的handler,在native中也是經過讀寫管道來控制Looper阻塞的。
剩下的還有消息隊列,信號(Signal),信號量(semaphore),目前接觸很少,就不寫了。
2.已知結構體StructA定義以下
#include<stdio.h> typedef struct _StruckA{ unsigned int val1; unsigned char bSuccess; unsigned int val2; unsigned char bInitialize; }structA, *pStructA; int main(){ structA a; a.val1 = 0x12345678; a.bSuccess = 0; a.val2 = 0xABCDEF01; a.bInitialize = 1; //請給出變量a在x86,x64下的內存分佈狀況 return 0; }
解答:
address | 0x00 ~ 0x03 | 0x04 | 0x05 ~ 0x7 | 0x08 ~ 0x0b | 0x0c | 0x0d ~ 0x0f |
---|---|---|---|---|---|---|
value | val1 | bSuccess | padding | val2 | bInitialize | padding |
仍是按照4byte對齊,共16bype,具體原理我在前面的字節對其中已經講了
並且我沒有32位的機子測試啊,全是LP64的....運行如下代碼
printf("%d\n",sizeof(a)); printf("%p\n",&a); printf("%p\n",&a.val1); printf("%p\n",&a.bSuccess); printf("%p\n",&a.val2); printf("%p\n",&a.bInitialize);
Xcode6.3
16 0x7fff5fbff838 0x7fff5fbff838 0x7fff5fbff83c 0x7fff5fbff840 0x7fff5fbff844
Ubuntu14.10 x64
16 0x7fff652a4880 0x7fff652a4880 0x7fff652a4884 0x7fff652a4888 0x7fff652a488c
而後我又在在線編譯測試了一下,仍然是同樣的,若是有用32位的小夥伴,幫我測試一下哦。
3.設計抽卡程序,策劃人員填寫物品出現機率,程序按照機率隨機抽出物品。配置表以下:
<data> <item id="1">10</item> <item id="2">50</item> </data>
4.用C寫一個程序,得出當前系統的整型數字長(16位,32位,64位等),不能使用sizeof()
解答:
使用數組便可
#include<stdio.h> unsigned int getSize(){ int a[2] = {1,2}; return (char*)(a+1) - (char*)a; }
或者
unsigned int getSize(){ int *a; return (char*)(a+1) - (char*)a; }
5.在傳統的CS網絡模型中,server端須要控制請求量,對超過某個閥值的請求量直接拋棄或者返回錯誤,以保護本身(過載保護)。假設一個Server服務的能力爲1W Qps,設計一個過濾機制,對於超過服務能力的請求直接拋棄。
明顯的一個Dispatcher機制,若是瞭解過nginx,flux的話,很是容易瞭解。這個題目我以爲加個緩存更好。