2017網易實習前端面試題討論
歡迎來到2017網易前端開發實習題目的討論組
今天下午14到16點網易進行了18屆實習的第一次筆試,自我感覺心態有點小崩咧。
但是也並沒有到完全不能做的地步,畢竟只是實習的筆試,也不會太過困難地,但感覺距離還是不小,好好努力吧。
一、題型總結
總結了一下大概有以下筆試題型:
選擇題部分(30分)
- 元素出棧可能性
- 排序方法的優缺點
- HTTP請求方法
- 關係型資料庫種類
- 多執行緒(程序與執行緒共享)
- 計算機網路協議
- linux指令
- JQuery實現方法
程式設計題(60分)
- 集合
- 奇怪的表示式求值
- 消除重複元素
問答題(10分)
- JS實現Excel表格列項排序功能
二、重回戰場(選擇題)
1、
問題:元素1,2,3……7入棧,有多少種出棧的可能性?
考點:卡特蘭數,折現法
解析:
真的是,這種題目總是想搞些大新聞,搞一點沒人聽過的東西,其實很簡單,其實很自然,就是…沒做出來。
和這個題目一共有三個型別:
1、飯後,姐姐洗碗,妹妹把姐姐洗過的碗一個一個地放進碗櫥摞成一摞。一共有n個不同的碗,洗前也是摞成一摞的,也許因為小妹貪玩而使碗拿進碗櫥不及時,姐姐則把洗過的碗摞在旁邊,問:小妹摞起的碗有多少種可能的方式?
2、給定n個數,有多少種出棧序列?
3、一個有n個1和n個-1組成的字串,且前k個數的和均不小於0,那這種字串的總數為多少?
乍一看,一臉萌幣,該洗的洗,該放的放,咋還能這麼玩。
在查閱了資料以後整理了一下思路,特別是這兩張神圖,一定要看。
在 出棧入棧 的過程中,就好比一個人要從原點到達 (2n,0)這個點(入n出n)
入棧為右上方移動單位長度(記為操作1),出棧為向右下方移動單位長度(記為操作2)。出棧時,棧內必須要有元素,所以,曲線在x軸上方時,是合法的。
但是!在合法條件下完成計算並不是一件簡單的事情
我們可以嘗試從反面來做:即 合法步驟 = 所有步驟 - 非法步驟
1> 合法步驟可能性為C(2n,n),即在2n個操作步驟中隨機選取n個入棧過程即可
2> 接下來討論非法步驟,是比較繞的
我們可以看到,圖示所列的實線非法步驟越過了x軸,這是當然的。
但是當我們以y = -1為對稱軸將影象對稱後(即操作1和2互換),我們可以發現,所有的非法折現都到達了(2n,-2)這個點,經過研究後發現並不是巧合,也沒能看出是為什麼。
但是我們可以發現,對稱後,非法步驟中,操作2 比 操作1多了來了兩次。
即進行 n-1 次操作 1,n+1次操作2,即可完成非法操作。
所以答案為C(2n,n)-C(2n,n-1) = C(2n,n)/(n+1)
當n = 7時,次數為429次 (不會就蒙D…?)
2、
問題:在100 0000個數中選出最大的五個數字,那種排序方法最為快速?
考點: 堆排序,合併排序,快速排序,希爾排序(插入排序的一種,也稱縮小增量排序)
解析:
資料結構我真的沒有好好學嗎..
❤快速排序:真的,100 0000的資料量以內,見到快排,就選了吧。不跟你多..
原理:快速排序(Quicksort)是對氣泡排序的一種改進。它的基本思想是:通過一趟排序將要排序的資料分割成獨立的兩部分,其中一部分的所有資料都比另外一部分的所有資料都要小,然後再按此方法對這兩部分資料分別進行快速排序,整個排序過程可以遞迴進行,以此達到整個資料變成有序序列。
優勢:插入排序在對幾乎已經排好序的資料操作時,效率高,即可以達到線性排序的效率。
缺點:不穩定,在序列有序或者逆序的情況下最不利於發揮其長處
希爾排序:我怎麼就覺得這個快
原理:希爾排序(Shell Sort)是插入排序的一種。也稱縮小增量排序,是直接插入排序演算法的一種更高效的改進版本。希爾排序是非穩定排序演算法。希爾排序是把記錄按下標的一定增量分組,對每組使用直接插入排序演算法排序;隨著增量逐漸減少,每組包含的關鍵詞越來越多,當增量減至1時,整個檔案恰被分成一組,演算法便終止。
優勢:快,資料移動少
缺點:不穩定,d的取值是多少,應取多少個不同的值,都無法確切知道,只能憑經驗來取,並且插入排序一般來說是低效的,因為插入排序每次只能將資料移動一位。
❤堆排序:資料超過1000 0000的時候,他是老大
原理:堆排序(Heapsort)是指利用堆積樹(堆)這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即A[PARENT[i]] >= A[i]。在陣列的非降序排序中,需要使用的就是大根堆,因為根據大根堆的要求可知,最大的值一定在堆頂。
優勢:由於它在直接選擇排序的基礎上利用了比較結果形成。效率提高很大。它完成排序的總比較次數為O(nlog2n),它是對資料的有序性不敏感的一種演算法。
缺點:在小規模序列中使用它不合適(不要殺雞用牛刀?)
歸併排序:我怎麼就覺得這個快
原理:歸併排序是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(Divide and Conquer)的一個非常典型的應用。將已有序的子序列合併,得到完全有序的序列;即先使每個子序列有序,再使子序列段間有序。若將兩個有序表合併成一個有序表,稱為二路歸併。
優勢:使用它對兩個己有序的序列歸併,將有無比巨大的優勢。其時間複雜度無論是在最好情況下還是在最壞情況下均是O(nlog2n),且對資料的有序性不敏感。
缺點:需要與待排序序列一樣多的輔助空間,所以資料節點資料量大,則不適合使用
——————————
3、HTTP的請求方法
問題:以下不屬於HTTP的請求方法的是?(答案為:SET)
考點:關於HTTP(Hypertext Transfer Protocol)的八種請求方法
請求方法列表
方法 | 概述 |
---|---|
❤GET | 請求頁面的詳細資訊,並返回實體主體。 |
❤POST | 向指定資源提交資料進行資料請求(例如提交表單,或者上傳檔案)。資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 |
PUT | 從客戶端向伺服器傳送的資料取代指定的文件內容。 |
DELETE | 請伺服器刪除指定的頁面。 |
HEAD | 類似與Get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 |
CONNECT | HTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。 |
OPTIONS | 允許客戶端檢視伺服器的效能。 |
TRACE | 回顯伺服器收到的請求,主要用於測試或診斷。 |
4、關係資料庫的種類
問題:以下不屬於關係資料庫的是?
考點:資料庫基礎知識
解析:
資料庫型別主要可分為:網狀資料庫(Network Database)、關係資料庫(Relational Database)、樹狀資料庫(Hierarchical Database)、面向物件資料庫(Object-oriented Database)等
❤關係資料庫:(SQL)
原理:
1、關係型資料庫,是指採用了關係模型來組織
資料的資料庫;
2、關係型資料庫的最大特點就是事務的一致性;
3、簡單來說,關係模型指的就是二維表格模型,
而一個關係型資料庫就是由二維表及其之間的聯絡所組成的一個數據組織。
優勢:
1、容易理解:二維表結構是非常貼近邏輯世界一個概念,關係模型相對網狀、層次等其他模型來說更容易理解;
2、使用方便:通用的SQL語言使得操作關係型資料庫非常方便;
3、易於維護:豐富的完整性(實體完整性、參照完整性和使用者定義的完整性)大大減低了資料冗餘和資料不一致的概率;
4、支援SQL,可用於複雜的查詢。
1、為了維護一致性所付出的巨大代價就是其讀寫效能比較差;
2、固定的表結構;
3、高併發讀寫需求;
4、海量資料的高效率讀寫;
主流資料庫代表:
oracle、db2、sqlserver、sybase、mysql
非關係資料庫(Not Only SQL):(種類較多,也就不細分了)
定義:
1、使用鍵值對儲存資料;
2、分散式;
3、一般不支援ACID特性;
4、非關係型資料庫嚴格上不是一種資料庫,應該是一種資料結構化儲存方法的集合。
優勢:
1、使用鍵值對儲存資料;
2、分散式;
3、一般不支援ACID特性;
4、非關係型資料庫嚴格上不是一種資料庫,應該是一種資料結構化儲存方法的集合。
1、不提供sql支援,學習和使用成本較高;
2、無事務處理,附加功能bi和報表等支援也不好;
主流資料庫代表:
MongoDb、redis、HBase
5、多執行緒(程序與執行緒共享)
問題:以下屬於同一個程序內執行緒共享的部分是?
考點:多執行緒(我能怎麼辦,我也很絕望系列)中執行緒共享的環境
解析:
1>執行緒共享的環境包括:
1、程序程式碼段
2、程序的公有資料(利用這些共享的資料,易於執行緒間實現相互之間的通訊)
3、程序開啟的檔案描述符
4、訊號的處理器
5、程序的當前目錄
6、程序使用者ID與程序組ID。
7、執行緒的堆共有,棧私有
2>執行緒的非共享的個性包括:
1.執行緒ID
每個執行緒都有自己的執行緒ID,這個ID在本程序中是唯一的。程序用此來標識執行緒。
2.暫存器組的值
由於執行緒間是併發執行的,每個執行緒有自己不同的執行線索,當從一個執行緒切換到另一個執行緒上時,必須將原有的執行緒的暫存器集合的狀態儲存,以便將來該執行緒在被重新切換到時能得以恢復。
3.執行緒的棧
棧是保證執行緒獨立執行所必須的。
執行緒函式可以呼叫函式,而被呼叫函式中又是可以層層巢狀的,所以執行緒必須擁有自己的函式棧,使得函式呼叫可以正常執行,不受其他執行緒的影響。
4.錯誤返回碼
由於同一個程序中有很多個執行緒在同時執行,可能某個執行緒進行系統呼叫後設置了errno值,而在該執行緒還沒有處理這個錯誤,另外一個執行緒就在此時被排程器投入執行,這樣錯誤值就有可能被修改。 所以,不同的執行緒應該擁有自己的錯誤返回碼變數。
5.執行緒的訊號遮蔽碼
由於每個執行緒所感興趣的訊號不同,所以執行緒的訊號遮蔽碼應該由執行緒自己管理。但所有的執行緒都共享同樣的訊號處理器。
6.執行緒的優先順序
由於執行緒需要像程序那樣能夠被排程,那麼就必須要有可供排程使用的引數,這個引數就是執行緒的優先順序。
6、計算機網路
問題:以下說法正確的是:
考點:計算機網路
解析:
A: UDP是可靠服務(Wrong)
解析: UDP 是User Datagram Protocol的簡稱, 中文名是使用者資料報協議,是OSI(Open System Interconnection,開放式系統互聯) 參考模型中一種無連線的傳輸層協議,提供面向事務的簡單不可靠資訊傳送服務,IETF RFC 768是UDP的正式規範。UDP在IP報文的協議號是17。
B: NAT是一種把內部私有網路地址(IP地址)翻譯成合法網路IP地址的技術(Right)
解析: NAT(Network Address Translation,網路地址轉換)是1994年提出的。當在專用網內部的一些主機本來已經分配到了本地IP地址(即僅在本專用網內使用的專用地址),但現在又想和因特網上的主機通訊(並不需要加密)時,可使用NAT方法。
C: TCP建立和關閉連結都只需要四次握手(Shake hands?先mark)(Wrong)
解析: 三次握手建立連結,四次揮手關閉連線
所謂三次握手(Three-way Handshake),是指建立一個TCP連線時,需要客戶端和伺服器總共傳送3個包。三次握手的目的是連線伺服器指定埠,建立TCP連線,並同步連線雙方的序列號和確認號並交換 TCP 視窗大小資訊.在socket程式設計中,客戶端執行connect()時。將觸發三次握手。
第一次握手:客戶端傳送一個TCP的SYN標誌位置1的包指明客戶打算連線的伺服器的埠,以及初始序號X,儲存在包頭的序列號(Sequence Number)欄位裡。
第二次握手:伺服器發回確認包(ACK)應答。即SYN標誌位和ACK標誌位均為1同時,將確認序號(Acknowledgement Number)設定為客戶的I S N加1以.即X+1。
第三次握手:客戶端再次傳送確認包(ACK) SYN標誌位為0,ACK標誌位為1.並且把伺服器發來ACK的序號欄位+1,放在確定欄位中傳送給對方.並且在資料段放寫ISN的+1
D: HTTP返回碼302表示永久重定向,需要重新URL(Uniform resource locator)(Wrong)
解析:
301,302 都是HTTP狀態的編碼,都代表著某個URL發生了轉移,不同之處在於:
301 redirect: 301 代表永久性轉移(Permanently Moved)。
302 redirect: 302 代表暫時性轉移(Temporarily Moved )。
7、Linux指令
問題:下面Linux命令,不能列印該目錄下所有的檔案和資料夾的是?
考點:作業系統(網易不限門檻的實習意思就這麼明顯?)
解析:
ls命令是Linux下最常用的命令。ls命令就是list的縮寫。
預設下ls用來列印當前目錄的清單,如果ls指定其他目錄,那麼就會顯式指定目錄裡的檔案及資料夾清單,通過ls命令不僅可以檢視linux資料夾包含的檔案,而且可以檢視檔案許可權等等。
echo*: echo命令用於在shell中列印shell變數的值,或者直接輸出指定的字串。linux的echo命令,在shell程式設計中極為常用, 在終端下列印變數value的時候也是常常用到的,因此有必要了解下echo的用法echo命令的功能是在顯示器上顯示一段文字,一般起到一個提示的作用。
dir: dir命令是ls命令的一個別名,也是directory的縮寫。通常列出的檔案會以不同的顏色進行顯示,不同的顏色代表不同的檔案型別,下表列出了檔案型別與顏色的對應關係。
三、重回戰場(程式設計題)
1、
問題:
小易有一個長度為n序列,小易想移除掉裡面的重複元素,但是小易想是對於每種元素保留最後出現的那個。小易遇到了困難,希望你來幫助他。
輸入描述:
輸入包括兩行:
第一行為序列長度n(1 ≤ n ≤ 50)
第二行為n個數sequence[i](1 ≤ sequence[i] ≤ 1000),以空格分隔
輸出描述:
輸出消除重複元素之後的序列,以空格分隔,行末無空格
輸入例子:
9
100 100 100 99 99 99 100 100 100
輸出例子:
99 100
我只想說牛客網,對js一點都不!友!好!
加個node.js readline接收模組對於我這種小白簡直就
無發渴說
解析:
題目還是比較簡單的,題目的意思理解起來大概就是。
- 你把題目給你的資料存進陣列
- 反過來將沒有重複的元素放進新陣列
- 再講最後的新陣列反轉輸出即可
感覺這種用flag分兩段接收資料的JS接收方法真的是亮點!!
程式碼:
//引入node.js readline接收模組
var readline = require('readline');
//建立readline介面例項
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
//定義需要使用的變數
var sum = 0;//接收陣列長度
var bool = 0;//表示還未接收資料資料一,用於控制接收資料一後接收資料二
var sequence = [] ;//作為陣列元素
var check = [] ;//作為儲存滿足條件的元素陣列
//注意給變數定義一個型別,要不然報錯沒商量
//開始接收資料
rl.on('line', function(line){
if(bool == 0){//接受資料一
sum = parseInt(line.trim());
bool = 1;
}else{//接收資料2
sequence = line.split(" ").map(function(index){
return parseInt(index);
});//以空格為單位接收資料進陣列
sequence.reverse();//反轉陣列,舒服
for(var i = 0;i<sum;i++){//從後往前加入新元素
if(check.indexOf(sequence[i]) == -1)
check.push(sequence[i]);
}
check.reverse();//反轉2333
console.log(check.join(" "));//連線成字串
bool = 2;//表示接收了第二行資料,方便進行下一次迴圈檢測
}
if(bool == 2)//對bool進行初始化,當成flag用
bool = 0;
});
2、
問題:
常規的表示式求值,我們都會根據計算的優先順序來計算。比如/的優先順序就高於+-。但是小易所生活的世界的表示式規則很簡單,從左往右依次計算即可,而且小易所在的世界沒有除法,意味著表示式中沒有/,只有(+, - 和 )。現在給出一個表示式,需要你幫忙計算出小易所在的世界這個表示式的值為多少
輸入描述:
輸入為一行字串,即一個表示式。其中運算子只有-,+,*。參與計算的數字只有0~9.
保證表示式都是合法的,排列規則如樣例所示。
輸出描述:
輸出一個數,即表示式的值
輸入例子:
3+5*7
輸出例子:
56
解析:
一個半小時才做完這個題,我跟你說我就是這!表!情!
- 五分鐘理清思路,10分鐘程式設計,一個小時找錯誤(程式設計五分鐘,Debug2小時)
- 題目的意思很簡單,將資料分成兩個陣列進行運算即可,用正則表示式,則更為方便,但是不熟練,我還是選擇放棄用這個方法
- 血淚教訓:一定要嚴格化輸出輸入資料的格式和精度(parseInt and parseFloat是好朋友),否則可能就是在研究0+2為什麼等於02的路上越走越遠
程式碼:
var readline = require("readline");
const r1 = readline.createInterface({
input:process.stdin,
output:process.stdout
});
//定義需要使用的變數
var number = [];//數字陣列
var symbol = [];//符號陣列
var input = [];//輸入資料
var a = 0;//儲存計算結果的變數
//計運算元函式
function operate(numa,sym,numb){//不要忘記括號!!
switch (sym){
case '+': return parseFloat(numa) + parseFloat(numb);
case '-': return parseFloat(numa) - parseFloat(numb);
case '*': return parseFloat(numa) * parseFloat(numb);
}
}
r1.on('line',function(line){
//接收所有輸入資料
input = line.split("");
//按照順序分割成數字和符號陣列
for(var i = 0; i < input.length;i++){//var not int
if(i % 2 == 0)
number.push(input[i]);
else
symbol.push(input[i]);
}
//將儲存變數賦初值,為了方便後面的迴圈複製儲存
a = number[0];
for(var j = 1;j < symbol.length + 1;j++){
a = operate(a,symbol[j-1],number[j]);
}
console.log(a);
})
3、
問題:
小易最近在數學課上學習到了集合的概念,集合有三個特徵:1.確定性 2.互異性 3.無序性.
小易的老師給了小易這樣一個集合:
S = { p/q | w ≤ p ≤ x, y ≤ q ≤ z }
需要根據給定的w,x,y,z,求出集合中一共有多少個元素。小易才學習了集合還解決不了這個複雜的問題,需要你來幫助他。
輸入描述:
輸入包括一行:
一共4個整數分別是w(1 ≤ w ≤ x),x(1 ≤ x ≤ 100),y(1 ≤ y ≤ z),z(1 ≤ z ≤ 100).以空格分隔
輸出描述:
輸出集合中元素的個數
輸入例子:
1 10 1 1
輸出例子:
10
解析:
因為這個是第一題程式設計題,還是比較簡單的,當時JS不會寫,就用Java寫的,所見難度並不是很大,大家可以參考下程式碼就行啦
程式碼:
var readline = require("readline");
const r1 = readline.createInterface({
input:process.stdin,
output:process.stdout
});
var a = 0;
var c = [];
var b = [];
r1.on('line',function(line){
c = line.split(" ").map(function(index){
return parseInt(index);
})
for(var i = c[0];i < c[1] + 1;i++)
for(var j = c[2];j < c[3] + 1;j++){
a = i / j;
if(b.indexOf(a) == -1)
b.push(a);
}
console.log(b.length);
})
三、重回戰場(問答題)
題目:
在頁面上有如下表格,當點選成績的時候,所有行資料根據成績從低到高排序,再點選成績則變為從高到低排序,請用JavaScript實現以上功能,可以使用jQuery
名字 | 性別 | 成績 |
---|---|---|
張三 | 男 | 77 |
李四 | 女 | 87 |
王五 | 未知(這個6) | 50 |
解析:
這個坑先留著,等到實力夠了再來補上