騰訊筆試題涵蓋的基礎知識

騰訊2015實習生-客戶端筆試題目解析

 

1.下列減小內存碎片的方法有哪些是正確的?php

增長實際申請和釋放的次數
頻繁調用的子函數儘可能使用棧內存
系統申請一大塊內存,本身實現內存分配和釋放,定時清理內存
下降虛擬內存的大小

解答:html

答案2,3是正確的。屬於操做系統中內存管理的問題。前端

  • C/C++中的malloc/free是從堆中動態申請和釋放內存的,是很是耗時的;
  • 棧內存速度比堆內存快,由於棧結構簡單,只須要彈出或者入棧就能夠移動指針了,而在堆中,須要查找空閒內存,申請內存等操做,因此比較慢;
  • 分配一大塊內存池,而後本身進行管理,有經驗的程序員是能夠作到的。好比在nginx中,它就首先分配了不少的內存,而後再重寫malloc/free進行自主管理的。在android中的Fresco中,使用native方法管理Ashmem,極大的減小了GC的調用(與GC後碎片的產生);在通訊設備中,因爲設備老舊,開發者甚至須要用匯編去壓榨malloc的性能。
  • 關於虛擬內存,確定是越多越好啊,升級64位最顯著的優點就是可使用64EB的內存,這裏不要把虛擬內存腦補爲swap分區。

考點:Stack與Heap的區別:vue

  stack heap
分配 編譯後就已經固定下來 手動向內核申請
釋放 運行後自動pop釋放 手動釋放/使用ARC(iOS)/使用GC(Java),這裏注意內存泄露
性能 faster slower
適用場景 基本類型,函數 大的數值,動態數組,對象

更多對比 -> 點我或者看視頻學習java

考點:虛擬內存(Virtual memory)linux

在32位Unix下,進程啓動後,能夠獲取到4GB的虛擬內存,其中內核佔用1G,用戶佔用3G,虛擬內存是經過物理內存(physical memory)與交換空間(swap)進行分配的,它對於進程是透明的,系統經過地址轉換功能(好比MMU,內存管理單元)進行虛擬內存與實際內存的轉換。android


virtual-memory

如下爲進程中內存的分配管理nginx


Virtual Memory Management
  • Data is the portion(一部分) of variables and data that are non-zero on startup.
  • BSS (Block Started by Symbol) are the ones that are zero on startup.

什麼是內存碎片?程序員

  • 內部碎片: 線程佔用內存而不利用或者釋放的內存空間。
  • 外部碎片: 內存空間過小以致於沒法分配的內存空間。

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]的類型是不一樣的,可是能夠強制類型轉換;
  • sizeof是編譯器運算的,而不是運行時計算出來的;

總結以下

  &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自己已經有了,其它全部的組成都有體現。

詳見:Android下的Uri開發


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

  • 全局對象若是有依賴的話,就須要對初始化順序進行控制,C++已經有了這個機制;
  • C++中有int8_t,int16_t,int32_t, 甚至int64_t,因此是有固定大小的整型;
  • 多維數組確定支持,連C語言都支持;
  • 類類型的成員常量是支持的,用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,因此會死循環。

  1. 無符號右移(unsigned right shift)在iOS中是沒有的,在Java中是有的。

  2. 看到 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

解答:

答案是NSSTreamNSSURLConnection

前面兩個Socket是屬於傳輸層的,面向底層網絡鏈接,要是本身重寫一個HTTP那還不得累死。在Android中,有URLConnnection,OkHttp,Volley等組件。

  1. 有興趣的能夠看下我寫的OkHttp源碼分析
  2. 說個題外話,若是使用第三方庫的話,建議加個適配器,以避免之後升級改動麻煩

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中

  • 若是其中一個是undefined,那麼就取那個非undefined
  • 若是都不是undefined,那就取最新的值

23.Python代碼....咳咳,題目圖片自己就壓了好幾遍。


Python Singleton

解答:單例模式


24.網絡帶寬擁堵可能致使如下哪些問題?

1. UDP丟包變嚴重
2. tcp數據被寫亂
3. tcp丟包
4. tcp傳輸速度驟降

解答:1 3 4

網絡擁塞通常是由三個緣由照成:

  • 存儲空間(緩存),好比緩存隊列滿了就會被路由器丟包;
  • 帶寬不足,好比出國帶寬;
  • 處理器不足,特別是在openwrt路由器上,因爲MIPS的CPU性能優化不足,好比沒有打開HWNAT,致使網速降低。

解決擁塞:知足上面三個短板,或者用不道德的工具(好比銳速)搶出口。


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不住,我儘量說本身可以有參考的答案。

  1. ASM。在android中,咱們常說的廣播,Intent本質都是ASM,好比Binder,AIDL,共享同一個內存而不用複製,在linux中,映射爲/dev/ashmem文件。

  2. Socket。好處固然是便於服務器控制,並且方便抓包減小互相推諉的可能性,並且當你走內部地址(好比環回地址)時,數據不用通過物理網卡,OS內核還能夠進行某些優化。使用上在android中好比百度全家桶後門自動用IPC喚醒甚至靜默安裝APP;在跨平臺開發中,大部分使用socket進行通訊;

  3. 管道(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的話,很是容易瞭解。這個題目我以爲加個緩存更好。

參考OkHttp3源碼分析[任務隊列]

相關文章
相關標籤/搜索