當裸辭遇到了面試難,你需要了解一下這些面試題
為了讓更多的小夥伴可以在面試的時候取的更好的
offer
,所以今天起我每天都會推送一到兩道面試題,俗稱每日一題(每日一坑)。方便找工作的小夥伴每日都會有新的收穫。
一道類陣列相關面試題
什麼是類陣列,類陣列就是 擁有
length
屬性,且其他屬性(索引)為非負整數的物件,且不具備陣列所用於的方法。比如我們常用的
document.querySelectorAll
返回的
NodeLists
就是一個類陣列。這道題就是和類陣列相關的內容.
題目
請說出以下程式碼輸出的內容,需要區分
nodejs
,
chrome
以及
chrome
去掉
splice
之後的輸出內容
var obj
=
{
'2'
:
3
,
'3'
:
4
,
'length'
:
2
,
'splice'
:
Array
.prototype
.splice
,
'push'
:
Array
.prototype
.push
}
obj
.
push
(
1
)
obj
.
push
(
2
)
console
.
log
(obj
)
答案
這道題一共問了三種情況下面的輸出,下面依次說明答案
1.
node
下面輸出
{
'2'
:
1
,
'3'
:
2
,
length
:
4
,
splice
:
[Function
: splice
]
,
push
:
[Function
: push
]
}
2.chrome
下面輸出
[empty ×
2
,
1
,
2
, splice
: ƒ
, push
: ƒ
]
3.chrome
去掉
splice
下面輸出
{2: 1, 3: 2, length: 4, push: ƒ}
通過上面輸出的內容,可以看出相同的程式碼,不同情況輸出的內容是有所不同的,下面進行詳細分解。
題解
在解答題目之前,我們再看看這段程式碼
const arr
=
new
Array
(
2
)
// 輸出 2 [empty * 2]
console
.
log
(arr
.length
, arr
)
arr
.
push
(
1
)
// 輸出 3 [empty * 2, 1]
console
.
log
(arr
.length
, arr
)
可以看到
push
方法會將陣列的
length + 1
, 然後將值放在索引為
length - 1
的位置,比如上面的程式碼,因為在初始化陣列的時候,已經將陣列長度指定為了
2
, 所以在
push
之後
length
就變成了
3
,然後
arr[3 - 1] = 1
在
MDN
上面對
push
的方法的解釋是:
push
方法具有通用性。該方法和call()
或apply()
一起使用時,可應用在類似陣列的物件上。push
方法根據length
屬性來決定從哪裡開始插入給定的值。如果length
不能被轉成一個數值,則插入的元素索引為 0,包括length
不存在時。當length
不存在時,將會建立它。
根據
MDN
解釋,
push
既可以使用到陣列中,也可以使用到類陣列中。而根據前文中對類陣列的解釋,可以看到題目中的
obj
就是一個標準的類陣列,那就可以在
obj
上面使用陣列的
push
方法。
再看
obj.push(1)
, 因為
obj.length = 2
, 所以會將
length + 1
就變成了
3
, 這時候 索引值時
obj[3 - 1] = 1
即
obj[2] = 1
, 同理
obj.push(2)
也一樣的。因為在
obj
中已經有了屬性(索引)
2
和
3
,所以在
push
的時候會覆蓋掉
2
和
3
上面的預設值。
所以在
nodejs
中就會輸出
{
'2'
:
1
,
'3'
:
2
,
length
:
4
,
splice
:
[Function
: splice
]
,
push
:
[Function
: push
]
}
但是在
chrome
控制檯中輸出
[empty × 2, 1, 2, splice: ƒ, push: ƒ]
很奇怪,為什麼會輸出這樣呢?這一塊有一個很特殊的陷阱,就是
chrome
控制檯是如何判斷列印的內容是陣列還是其他物件呢?對於這個,
chrome
就是通過判斷物件上面是否有
splice
和
length
這兩個屬性來判斷的,所以如果你將
splice
去掉之後,就會輸出以下內容
{
2
:
1
,
3
:
2
, length
:
4
, push
: ƒ
}
你也可以試試下面的程式碼:
console
.
log
(
{
splice
:
function
(
)
{
}
,length
:
1
}
)
console
.
log
(
{
slice
:
function
(
)
{
}
,length
:
1
}
)
邏輯面試題之小鼠喝毒-藥
小編當年畢業的時候面試就遇到過好幾次邏輯類的面試題,這道題就是一道邏輯類的面試題,一起來看看。
題目
有16瓶水,其中只有一瓶水有毒,小白鼠喝一滴之後一小時會死,請問最少用多少隻小白鼠,在1小時的時間一定可以找出有毒的水?
答案與題解
答案是至少需要
4
只小鼠,怎麼理解呢?我們可以用二進位制去推理一下:
假設有4只小鼠,分別是甲乙丙丁,使用二進位制來表示小鼠喝藥的順序,
1
代表喝藥,
0
代表不喝藥
甲:
1111 1111 0000 0000
乙:
1111 0000 1111 0000
丙:
1100 1100 1100 1100
丁:
1010 1010 1010 1010
那麼我們就可以這樣去判斷:
-
甲乙丙丁都死了,說明第一瓶有毒
-
甲乙丙死了,說明第二瓶有毒
-
甲乙丁死了,說明第三瓶有毒
-
甲乙死了,說明第四瓶有毒
-
甲丙丁死了,說明第五瓶有毒
-
。。。 依次類推
其實對於這道題,可以使用
2
的
n
次方來判斷,比如有
32
瓶水,那麼就是
2
的
5
次方,所以就需要
5
只小鼠。
arguments 面試題
在
ES6
中,我們如果一個函式引數個數不確定,我們一般會使用擴充套件運算子即
function(...rest){}
,得到一個引數陣列
rest
,但是在
ES6
之前,我們是不能使用擴充套件運算子的,這時候就需要考慮使用
arguments
題目
請說出以下程式輸出的內容(chrome輸出內容)
let obj
=
{
age
:
18
,
foo
:
function
(
func
)
{
func
(
)
arguments
[
0
]
(
)
}
}
var age
=
10
function
fn
(
)
{
console
.
log
(
this
.age
)
}
obj
.
foo
(fn
)
答案
本題的答案是:
// 第一個輸出 10
func
(
)
// 第一個輸出 undefined
arguments
[
0
]
(
)
有點出乎意料了嗎?
先來解釋一下第一個,為什麼不是輸出
18
呢,雖然
func()
是在
foo
函式裡面呼叫的,但是並沒有顯式指明作用域,這時候會使用預設作用域
window
,而對於瀏覽器來說,在全域性通過
var
宣告的變數會自動掛載到
window
上面,所以
var age = 10
相當於
window.age = 10
, 而第一個
func()
裡面的
this.age
相當於
window.age
第二個可能許多人有點蒙,為啥是
undefined
,先看一下下面的程式碼
const arr
=
[
function
(
)
{console
.
log
(
this
[
1
]
)
}
,
'我是子君'
]
// 輸出 我是子君
console
.
log
(arr
[
0
]
(
)
)
我們通過
arr[0]
獲取到函式,這時候函式的作用域就是這個陣列,所以再呼叫的時候,
this
就是
arr
, 所以
this[1]
就是陣列第二項。
這時候回過頭來看
arguments
,這個其實是一個類陣列,裡面存的是函式傳入的引數,第一項就是傳入的函式,和上面例子一樣,
arguments[0]
的作用域就是
arguments
,而
arguments
上面並沒有
age
屬性,所以是
undefined
this指向問題
this
指向問題一直是比較混亂的,在箭頭函式出現之前,
this
的指向與程式碼在哪裡定義並沒有關係,而是取決於是被誰執行的,正因為此,所以許多開發人員經常會搞不清楚
this
到底是誰。下面的兩道題都是和
this
指向相關的問題。
題目一(青銅)
請說出以下程式碼輸出的內容
var num
=
1
;
let obj
=
{
num
:
2
,
add
:
function
(
)
{
this
.num
=
3
;
(
function
(
)
{
console
.
log
(
this
.num
)
;
this
.num
=
4
;
}
)
(
)
;
console
.
log
(
this
.num
)
;
}
,
sub
:
function
(
)
{
console
.
log
(
this
.num
)
}
}
obj
.
add
(
)
;
console
.
log
(obj
.num
)
;
console
.
log
(num
)
;
const sub
= obj
.sub
;
sub
(
)
;
題目二(黃金)
請說出以下程式碼輸出的內容
var num
=
10
const obj
=
{num
:
20
}
obj
.fn
=
(
function
(
num
)
{
this
.num
= num
*
3
num
++
return
function
(
n
)
{
this
.num
+= n
num
++
console
.
log
(num
)
}
}
)
(obj
.num
)
var fn
= obj
.fn
fn
(
5
)
obj
.
fn
(
10
)
console
.
log
(num
, obj
.num
)
答案
題目一
輸出結果:
1
,
3
,
3
,
4
,
4
, 你答對了嗎?下面我們來看看程式碼解析
var num
=
1
;
let obj
=
{
num
:
2
,
add
:
function
(
)
{
this
.num
=
3
;
// 這裡的立即指向函式,因為我們沒有手動去指定它的this指向,所以都會指向window
(
function
(
)
{
// 所有這個 this.num 就等於 window.num
console
.
log
(
this
.num
)
;
this
.num
=
4
;
}
)
(
)
;
console
.
log
(
this
.num
)
;
}
,
sub
:
function
(
)
{
console
.
log
(
this
.num
)
}
}
// 下面逐行說明列印的內容
//java學習交流:737251827 進入可領取學習資源及對十年開發經驗大佬提問,免費解答!
/**
* 在通過obj.add 呼叫add 函式時,函式的this指向的是obj,這時候第一個this.num=3
* 相當於 obj.num = 3 但是裡面的立即指向函式this依然是window,
* 所以 立即執行函式裡面console.log(this.num)輸出1,同時 window.num = 4
*立即執行函式之後,再輸出`this.num`,這時候`this`是`obj`,所以輸出3
*/
obj
.
add
(
)
// 輸出 1 3
// 通過上面`obj.add`的執行,obj.name 已經變成了3
console
.
log
(obj
.num
)
// 輸出3
// 這個num是 window.num
console
.
log
(num
)
// 輸出4
// 如果將obj.sub 賦值給一個新的變數,那麼這個函式的作用域將會變成新變數的作用域
const sub
= obj
.sub
// 作用域變成了window window.num 是 4
sub
(
)
// 輸出4
題目二
輸出結果為:
22
23
65
30
, 你答對了嗎? 下面我們解析一下
var num
=
10
const obj
=
{num
:
20
}
obj
.fn
=
(
function
(
num
)
{
this
.num
= num
*
3
num
++
return
function
(
n
)
{
this
.num
+= n
num
++
console
.
log
(num
)
}
}
)
(obj
.num
)
var fn
= obj
.fn
fn
(
5
)
obj
.
fn
(
10
)
console
.
log
(num
, obj
.num
)
我們把上面的程式碼分為以下幾步進行分析
-
先看第三行程式碼,是一個賦值操作,我們知道賦值操作是從右向左的,而
=
號右邊是一個立即執行函式,所以會優先執行立即執行函式,立即執行函式沒有手動指定this
,這時候this = window
,而立即函式的引數num
是傳進來的obj.num
,所以num
引數預設值是20
-
第四行相當於
window.num = 20 * 3
-
第五行為傳入的引數加一,所以
num = 20 + 1
-
第六行
return
了一個函式,而這個函式就是obj.fn
的值, 但是因為return
的函式引用了立即執行函式裡面的num
,所以形成了閉包。這時候var fn = obj.fn
, 將obj.fn
賦值給新的變數,而這個變數的作用域是window
obj
.
fn
=
function
(
n
)
{
this
.num
+= n
// 這個num是立即執行函式裡面的num
num
++
console
.
log
(num
)
}
5. 在呼叫
fn(5)
的時候, 在第二步,
window.num
的值已經變成了
60
, 然後因為這時候
fn
的
this
是
window
,
this.num += n
相當於
window.num += n
, 即
window.num = 65
6.
num++
, 因為閉包的原因,第三步
num
是
21
,所以這一步
num
變成了
22
, 同時輸出
22
7.然後
obj.fn(10)
,這時候
fn
的
this
為
obj
,
obj.num
預設值是
20
,
this.num += n
相當於
obj.num += 10
8.和第七步一樣,
num + 1
輸出
23
9.
console.log(num, obj.num)
相當於
console.log(window.num, obj.num)
,從上面幾步可知,
window.num = 65
,
obj.num = 30
。
擴充套件題
如果將上面兩道題的
var
改成
let
, 又會輸出什麼結果呢?
資料型別轉換問題
雖然在日常開發中,我們隱氏型別轉換用的比較少(不一定),但是這個還是面試常問問題,掌握還是要掌握的,一起來看看這道題目吧.
題目(王炸/青銅,我也不知道)
請說出以下程式碼輸出的內容
console
.
log
(
[
]
+
[
]
)
console
.
log
(
{
}
+
[
]
)
console
.
log
(
[
]
==
!
[
]
)
console
.
log
(
true
+
false
)
答案
一起來看看答案吧
-
第一行程式碼
// 輸出 "" 空字串
console
.
log
(
[
]
+
[
]
)
這行程式碼輸出的是空字串
""
, 包裝型別在運算的時候,會先呼叫
valueOf
方法,如果
valueOf
返回的還是包裝型別,那麼再呼叫
toString
方法
// 還是 陣列
const val
=
[
]
.
valueOf
(
)
// 陣列 toString 預設會將陣列各項使用逗號 "," 隔開, 比如 [1,2,3].toSting 變成了"1,2,3",空陣列 toString 就是空字串
const val1
= val
.
toString
(
)
// val1 是空字串
所以上面的程式碼相當於
console.log("" + "")
2.第二行程式碼
和第一題道理一樣,物件
{}
隱氏轉換成了
[object Object]
,然後與
""
相加
// 輸出 "[object Object]"
console
.
log
(
{
}
+
[
]
)
3. 第三行程式碼對於
===
, 會嚴格比較兩者的值,但是對於
==
就不一樣了
1. 比如
null == undefined
2.如果非
number
與
number
比較,會將其轉換為
number
3.如果比較的雙方中由一方是
boolean
,那麼會先將
boolean
轉換為
number
所以對於上面的程式碼,看下面一步一步分析
// 這個輸出 false
console
.
log
(
!
[
]
)
// 套用上面第三條 將 false 轉換為 數值
// 這個輸出 0
console
.
log
(
Number
(
false
)
)
// 包裝型別與 基本型別 == 先將包裝型別通過 valueOf toString 轉換為基本型別
// 輸出 ""
console
.
log
(
[
]
.
toString
(
)
)
// 套用第2條, 將空字串轉換為數值、
// 輸出 0
console
.
log
(
Number
(
""
)
)
// 所以
console
.
log
(
0
==
0
)
4. 第四行程式碼
兩個基本型別相加,如果其中一方是字元,則將其他的轉換為字元相加,否則將型別轉換為
Number
,然後相加,
Number(true)
是
1
,
Number(false)
是
0
, 所以結果是
1
// 輸出 1
console
.
log
(
true
+
false
)
J ava 最常見 的 200+ 面試題:面試必備
總結
面試造火箭,工作擰螺絲。雖然我只想擰螺絲,但是我卻需要通過造火箭來找到擰螺絲的工作,每日一題,每天都有新的面試題目,
結語
不要吹滅你的靈感和你的想象力; 不要成為你的模型的奴隸。 ——文森特・梵高
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70010294/viewspace-2849058/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 當裸辭遇到面試難,這些面試題你需要了解一下面試題
- 最新阿里Java面試題,這些面試題你會嗎?阿里Java面試題
- 這10道springboot常見面試題你需要了解下Spring Boot面試題
- 這些 SpringBoot 面試題你會嗎?Spring Boot面試題
- 20 道 Spring Boot 面試題你需要了解下Spring Boot面試題
- 昨天去面試,這5個Python面試題都被考到了,Python面試題No6Python面試題
- 【面試篇】金九銀十面試季,這些面試題你都會了嗎?面試題
- 準備程式設計師面試?你需要了解這 14 種程式設計面試模式程式設計師面試模式
- 當面試遇到 Redis,我作為一個面試官是這麼“刁難”你的!面試Redis
- 面試現場:這些常問的面試題你都會了嗎面試題
- Linux常見面試題,這些你知道多少?Linux面試題
- 學習Python這些面試題你都知道嗎?Python面試題
- 邦芒面試:想面試成功,這些事你必須知道面試
- 面試 Netflix 前,你至少需要了解以下內容面試
- 當大潮退去沒有誰還能Android這行“裸泳”,10家大廠面試題,掌握這些讓你輕鬆面試Android面試題
- 看了這篇Dubbo RPC面試題,讓天下沒有難面的面試題!RPC面試題
- 面試 HTTP ,99% 的面試官都愛問這些問題面試HTTP
- Spring Boot面試題,你會需要的!Spring Boot面試題
- 安卓工程師大廠面試真實際遇,試題你來挑戰一下?安卓工程師面試
- 做到這些面試事半功倍面試
- 面試疑難問題面試
- 騰訊這套SpringMvc面試題你懂多少(面試必備)SpringMVC面試題
- Java面試愈發艱難?github上這份面試手冊,輕鬆解決你95%的面試Java面試Github
- 面試雲端計算崗位時這些面試題不能錯過面試題
- Java面試前需要了解的東西Java面試
- 反射面試題-請了解下反射面試題
- PHP面試題:ps這次的面試題有難度,歡迎挑戰留評。PHP面試題
- 我遇見的那些面試題面試題
- MyBatis面試題集合,90%會遇到這些問題MyBatis面試題
- 面試現場!月薪3w+的這些資料探勘SQL面試題你都掌握了嗎?SQL面試題
- 這些js原型及原型鏈面試題你能做對幾道JS原型面試題
- 簡單整理了一下最近遇到的一些面試題-面試進行中面試題
- 這些年背過的面試題——Kafka篇面試題Kafka
- 這些年背過的面試題——SpringCloud篇面試題SpringGCCloud
- 這些年背過的面試題——MySQL篇面試題MySql
- 這些年背過的面試題——Redis篇面試題Redis
- Android面試總結,有了這些中高階面試專題-大廠還會遠嗎?Android面試題及解析Android面試題
- 面試常遇的打家劫舍問題你學會了嗎~面試