筆試題記錄
1. 空元素 Empty Element
(滴滴筆試)
空元素是
HTML/SVG
裏的不可能存在子節點的元素。
個人理解就是:自閉和標籤
HTML
中的空元素:
<br/>
<hr>
<img>
<input/>
<link>
<meta>
<area>
<source>
<track>
<wbr>
<base>
<param>
<keygen>
<col>
<colgroup>
<command>
<embed>
2. <video src="movie.ogg" controls="controls">
(滴滴筆試)
<video>
video是閉合標籤</video>
,不用必須指定寬高
類似,<audio></audio>
也是閉合標籤
video
和audio
都有的屬性:
autoplay
loop
src
controls
3. 否定僞類 :not()
僞類
pseudo Class
爲一個元素的特定狀態應用樣式
僞元素pseudo Element
爲一個元素的特定部分應用樣式
僞類:
:active
:hover
:focus
:visited
:enabled
disabled
:invalid
:lang()
:not()
:optional
:out-of-range
:readonly
:read-write
:required
:root
:scope
:target
:valid
:checked
:default
:defined
:empty
:first
:focus-within
:host
:indeterminate
:in-range
:left
:link
- 長子
first-child
嫡長子first-of-type
幼子:last-child
嫡幼子:last-of-type
- 自定義規則
:nth-child()
:nth-of-type()
從後往前:nth-last-child()
:nth-last-of-type()
- 獨子
:only-child
:only-of-type
僞元素:
::after
::before
::first-letter
::first-line
::selection
::slotted
4. 狀態碼 (頭條面試)
301 永久移動
302 臨時移動
304 Not Modified
502 Bad Gateway
503 Service Unavailable
5. 獲取元素?getElementByLabel()?
document.getXXX
系列:
getElementById()
// idgetElementsByClassName()
// 類名getElementsByName()
// name屬性getElementsByTagName()
// 標籤名getElementsByTagNameNS()
// 使用命名空間的XML文檔
獲取元素還有Selector
:
document.queySelector()
document.querySelectorAll()
6. GET和POST區別 (騰訊、頭條面試)
GET - 從指定的資源請求數據
POST - 向指定資源提交要被處理的數據
GET:
- 請求可被緩存
- 請求保留在瀏覽器歷史記錄中
- 可被收藏成書籤
- 不應用於敏感數據
- 請求有長度限制
- 只應當用於取數據
- 請求參數只能是ASCII碼,所以需要encode編碼
POST:
- 請求不會被緩存
- 不保留在歷史記錄中
- 不能被收藏成書籤
- 對數據長度無要求
7. 死鎖
死鎖產生的四個必要條件:
- 互斥條件
- .不可剝奪條件
- 請求和保持條件
- 循環等待條件
死鎖預防:
- 破壞“不可剝奪”:一個進程不能獲得所需的全部資源便處於等待狀態,等待期間他佔有的資源被隱式地釋放
- 破壞“請求與保持”:一、靜態分配:每個進程在開始執行時就申請他所需的全部資源。二、動態分配:每個進程在申請所需資源時它本身不佔用系統資源。
- 破壞“循環等待”:按編號順序進行
8. CSS優先級問題(僞類+屬性選擇器)
<div class="main">
<div class="test"></div>
</div>
<style>
.main div{
width: 200px;
height: 200px;
border: 1px red solid;
}
.test {
border: 1px green solid;
}
</style>
.main div
要比.test
優先級高
ICE(Id > Class > Element)
<div class="text">
<p>僞類與類的優先級相等</p>
<p>所以後者起作用</p>
</div>
<style>
.text p{
color: red;
}
p:first-child{
color: green;
}
</style>
類和僞類優先級一致;元素和僞元素優先級一致
<div>
<p class="text" id="zpj">屬性選擇器</p>
</div>
<style>
p[class="text"]{
color: green;
}
[id="zpj"]{
color: blue;
}
.text{
color: red;
}
</style>
屬性選擇器的優先級等於類選擇器
9. innerHTML
和innerText
共同點是都可以讀寫。
text表文本;html表格式;inner是標籤內部;outer包含標籤本身;value只用於input和textarea
innerText
: 只要文本innerHTML
: HTML格式outerText
:包含標籤自己outerHTML
:包含標籤自己value
: input和textarea
10. 箭頭函數
- 箭頭函數更適用於那些本來需要匿名函數的地方
- 箭頭函數不能用作構造函數
- 沒有自己的this、arguments、super和new.target
- 箭頭函數不會創建自己的
this
,只能從自己的作用域鏈上一層繼承this - 使用剩餘參數相較於使用
arguments
是更好的選擇 - 箭頭函數不要用作對象方法,this指向問題
- 箭頭函數沒有
prototype
屬性 - 箭頭函數不能使用
yield
關鍵字,不能用作生成器
高級用法:
// 加括號的函數體返回對象字面量
() => ({name: 'zpj'});
// 支持剩餘參數和默認參數
(a =1,b =true,...rest) => {};
// 支持參數列表解構
([a,b]=[1,2], {name: c} ={name: a+b}) => a+b+c;
說到this,提一下setTimeout
setTimeout
調用的代碼運行在與所在函數完全分離的執行環境上。這會導致代碼中的this指向window
bind改變this指向,只改變一次
new.target
:在普通函數調用中,指向undefined; 在類的構造方法中,指向被new執行的構造函數
// 1. 使用new.target來保證構造函數正確使用
function Foo(){
if(!new.target) throw "Foo() must be called with new";
// construction
}
// 2. 使用instanceof & new操作符幹了什麼(作業幫面試)
function User(name, pw){
var self = this instanceof User ? this : Object.create(User.prototype);
self.name = name;
self.password = pw;
return self;
}
11. 能冒泡的事件
先說
on
和addEventListener/attachEvent
的區別
on+事件
,只能綁定一個事件,後面的會覆蓋前面的addEventListener(eventName, function, useCapture)
可以綁定多個事件- 移除事件有
removeEventListener/detachEvent()
事件模型一般分爲
capture -> target -> bubble
的過程
注意到useCapture
,true
是在捕獲階段處理事件,默認false
是在冒泡階段處理事件
有的事件沒有冒泡過程。每個event
都有一個event.bubles
屬性,可以知道他是否可以冒泡。
不冒泡的事件有:
abort
blur
error
focus
load
mouseenter
mouseleave
resize
unload
12. 組合選擇器 (美團面試)
A,B
任意選擇器, 所有A or BA B
後代選擇器, A後代中的BA>B
子選擇器,A的第一代BA+B
毗鄰選擇器,弟弟選擇器,next-sibling,A後的第一個B
13. <input/>
標籤的type類型 (頭條面試)
button
checkbox
color
date
datetime
datetime-local
email
file
hidden
image
month
number
password
radio
range
reset
search
submit
tel
text
ime
url
week
注意: 沒有textarea
, <textarea> </textarea>
是獨立的一個標籤
14. Array.from()
Object.keys()
(京東面試)
一、 Array.from(arrayLike, mapFunc, thisArg)
- 字符串、set、map、arguments
Array.from('foo');
// ['f', 'o', 'o']
let s = new Set(['foo', window]);
Array.from(s);
// ["foo", Window]
let m = new Map([[1,2],[3,4],[5,6]]);
Array.from(m);
// [[1, 2], [2, 4], [4, 8]]
function f(){
return Array.from(arguments);
}
f(1,2,3);
// [1,2,3]
如何將
arguments
轉化成真正的數組:
Array.from(arguments)
Array.prototype.slice.call(arguments)
說到arguments
,講一下arguments
和函數形參的聯繫
在非嚴格模式下,
arguments
指向的是形參的引用地址,一個改變,另一個跟着改變;
嚴格模式下,arguments
是靜態副本,二者互相獨立。
function add(a,b){
console.log(a,b); // 1 2
console.log(arguments); // 1 2
arguments[0] = 10;
console.log(a,b); // 10 2
console.log(arguments); // 10 2
return a+b;
}
add(1,2); // 12
// 嚴格模式
'use strict'
function add(a,b){
console.log(a,b); // 1 2
console.log(arguments); // 1 2
arguments[0] = 10;
console.log(a,b); // 1 2
console.log(arguments); // 10 2
return a+b;
}
add(1,2); // 3
二、Object.keys(obj)
- 遍歷自身的可枚舉屬性,順序和
for-in
一致,區別在於for-in會遍歷原型鏈上的可枚舉屬性
// simple Array
Object.keys([1,2,3]); // ['0', '1', '2']
// array like object
Object.keys({0: 1, 1: 2, 2: 3}); // ["0", "1", "2"]
// array like object with random key ordering
Object.keys({100: 'a', 2: 'b', 7: 'c'}); // ["2", "7", "100"]
【注意】:想要拿到不可枚舉屬性,使用getOenPropertyNames()
也就是說,遍歷對象屬性的三種方法:
for-in
:遍歷自身和原型鏈上的可枚舉屬性,一般配合hasOwnProperty()
使用Object.keys()
:遍歷自身的可枚舉屬性Object.getOwnPropertyNames()
:遍歷自身的所有屬性,包括不可枚舉屬性
15. instanceof
運算符 typeof
操作符 (京東面試)
一、 instanceof
測試構造函數的prototype屬性是否出現在對象的原型鏈中的任何位置
object instanceof constructor
檢測constructor.prototype
是否存在於object
的原型鏈上
實際上就是在問:constructor.prototype.isPrototypeOf(object);
function Car(){};
var c = new Car();
c instanceof Car;
c instanceof Object; // Object.prototype.isPrototypeOf(c);
二、 typeof
返回操作數的類型
類型 | 結果 |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
BigInt | "bigint" |
String | "string" |
Symbol | "symbol" |
Function | "function" |
其餘複雜對象(如:數組,Set, Map) | "object" |
typeof NaN === "number"
typeof Number(1) === "number"
typeof null === "object"
typeof /s/g === "object"
三、 Object.prototype.toString.call()
- 判斷類型最全面的方法:返回值爲
"[object Type]"
Object.prototype.toString.call(1); // "[object Number]"
Object.prototype.toString.call(/s/); // "[object RegExp]"
四、Array.isArray()
判斷數組
五、isNaN()
判斷NaN
16. 嚴格模式
問題 | 嚴格模式 | 非嚴格模式 |
---|---|---|
with |
禁止with |
不禁止 |
變量聲明 | 變量必須聲明 | 未聲明的變量將隱式聲明爲全局變量 |
this 指向 |
普通函數(非方法、非構造函數)中的this 指向undefined |
this 指向全局對象 |
this 指向 |
call 和apply 傳入null 和undefined ,保持原樣 |
會被轉換成全局對象 |
不可擴展 | 給只讀屬性和不可擴展對象創建新成員,拋錯 | 靜默失敗 |
eval |
eval 中不能定義變量和函數 |
變量和函數定義在新的作用域中 |
arguments |
arguments 擁有參數的靜態副本 |
arguments 和參數指向同一個值 |
delete |
delete 不可配置屬性會拋錯 |
靜默失敗,返回false |
對象字面量 | 定義多個同名屬性會報錯 | 保留最後一個 |
函數多個同名參數 | 報錯 | 最後一個爲準 |
八進制字面量 | 禁止 | 允許 |
關鍵字 | eval arguments 不能作變量名· |
- |
17. 語義化 (頭條面試)
- 語義化的優點:
- 易於閱讀,樣式丟失也能呈現清晰的結構
- SEO,搜索引起根據標籤來確定上下文和各個關鍵字的權重
- 便於多設備解析
- 利於代碼維護
- 常見語義化標籤
<header> <nav> <main> <article> <aside> <footer> <section>
18. 宏任務和微任務(setTimeout
和 Promise
的區別)(快手面試)
Event Loop
事件循環有很多tick,每個tick包括一隊宏任務和一隊微任務- 傳統異步(
setTimeout
)是事件循環(宏任務) promise
是任務隊列(微任務)
任務隊列是掛在事件循環隊列的每個tick之後的一個隊列。在事件循環的每個tick中,可能出現的異步動作不會導致一個完整的新事件添加到事件循環隊列中,而是會生成一個微任務,掛在當前事件循環的後面。
事件循環隊列類似於一個遊樂園遊戲:玩過了滑滑梯之後,你需要跑到隊尾才能再玩一次。而任務隊列等於玩過之後直接插隊繼續玩。
console.log(1); // 當前tick宏任務
setTimeout(function(){
console.log(2); // 下一個tick宏任務
}, 0);
var p = new Promise(function(resolve, reject){
console.log(3); // 當前tick宏任務
resolve();
});
p.then(res => {
console.log(4); // 當前tick微任務
});
console.log(5); // 當前tick宏任務
// 1 3 5 4 2
19. 強緩存和協商緩存 cache-control
(頭條面試)
請求設置
字段名 | 說明 |
---|---|
no-cache |
告知(代理)服務器,不要直接使用緩存,要求向原服務器發起請求 |
no-store |
所有內容不會被保存 |
max-age=delta-seconds |
客戶端會緩存delta秒 |
響應設置
字段名稱 | 說明 |
---|---|
public |
公開,任何情況下都緩存該資源 |
must-revalidate |
當前資源一定是向原服務器發去驗證的,請求失敗返回504 |
20. JSON.parse()
解析數字 (360筆試)
- 鍵:JSON中字段名只允許雙引號包裹
"name"
- 值:數字直接寫,字符串雙引號
JSON.parse('{"age": 23}'); // -> {age: 23}
JSON.parse('{"age": "23"}'); // -> {age: "23"}
21. 默認inherit
的css屬性 (360筆試)
- 並非所有未定義的css屬性會默認
inherit
color text-indent text-align line-height list-style-type list-style-image list-style cursor
direction word-spacing text-transform white-space border-collapse
22. url()
的寫法 (360筆試)
資源地址可以使用單引號或雙引號包起來,也可以不使用任何引號
url('image.gif)
url("image.gif")
url(image.gif)
使用@import
:
@import url("global.css)
@import url(global.css)
@import "global.css"
23. for-in
和for-of
的比較 (流利說面試)
一、forEach
遍歷數組,無法使用return
和break
挑出循環
二、for-in
遍歷普通對象
- index是字符串,而不是數字
- 作用於數組的for-in循環還會遍歷自定義屬性,以及原型鏈屬性
- 隨機順序遍歷數組
三、for-of
和Iterator
Iterator
一是爲各種數據結構提供一個統一的訪問接口;二是使數據結構成員能按某種次序排序for-of
只遍歷擁有Symbol.iterator
屬性的對象- 原生具備Iterator接口的數據結構:
Array Map Set String TypedArray arguments NodeList
- 阮一峯ES6
24. animation
動畫 (美團面試)
@keyframes mymovie{
from {top: 0px;}
to {top: 200px;}
}
div {
animation: mymovie 2s infinite;
position: relative;
}
兩件事:1. 定義關鍵幀; 2. animation播放設置
animation: name duration timing-function delay iteration-count direction;
值 | 描述 |
---|---|
animation-name |
keyframe 名 |
animation-duration |
持續時間,帶單位 2s |
animation-timing-function |
速度曲線 linear ease ease-in ease-out ease-in-out |
animation-delay |
延遲 2s |
animation-iteration-count |
播放次數 |
animation-direction |
normal alternate |
流利說面試:這道題還牽扯出top和transform的性能問題,transform合成計算,改變偏移量會引發迴流重繪。
迴流重繪的瀏覽器優化,維護隊列,操作到了一定數量或者到了一定的時間,批處理一個隊列。
添加刪除可見元素,元素位置改變,尺寸改變,margin、padding、border、content、width、height的改變都會迴流。
迴流一定重繪,重繪不一定迴流。
25. 返回頂部按鈕(寒武紀面試)
兩種思路:1. scroll API; 2. 錨點標記
<a href="#top"></a>
window.onscroll = function () {
var scrollTop = document.documentElement.scrollTop;
if (scrollTop < 1200) {
document.querySelector('#topbtn').style.display = 'none';
} else {
document.querySelector('#topbtn').style.display = 'block';
}
}
// 定時器實現思路
document.querySelector('#topbtn').onclick = function () {
var itvId = setInterval(function () {
var scrollTop = document.documentElement.scrollTop;
if (scrollTop > 0) {
window.scrollTo(0, scrollTop - 20);
} else {
clearInterval(itvId);
}
}, 16);
}
// requestAnimationFrame
document.querySelector('#topbtn').onclick = function () {
(function smoothscroll() {
var currentScroll = document.documentElement.scrollTop || document.body.scrollTop;
if (currentScroll > 0) {
window.requestAnimationFrame(smoothscroll);
window.scrollTo(0, currentScroll - 20);
}
})();
}
26. margin
可以百分比嗎?(愛奇藝筆試)
可以,基於父元素寬度的百分比,包括margin-top
margin-bottom
padding同理。爲什麼不是高度的百分比,會導致無限循環。
27. 堆排序,建堆過程 (寒武紀面試)
堆是一顆完全二叉樹
- 完全二叉樹
Complete Binary Tree
:除了最後一層外每一層都被填滿,最後一層保持左對齊 - 滿二叉樹
Perfect Binary Tree
:每一層都被填滿 - 滿二叉樹一定是完全二叉樹;完全二叉樹不一定是滿二叉樹
堆排序按原始順序建立完全二叉樹,然後找到第一個非葉子節點,從下至上開始不斷調整大小順序。完全二叉樹從零開始排列,可以用一個數組表示,結點元素完全和序列掛鉤。
// 建堆注意迭代,換完父節點,注意下一層節點還需要換,知道葉子結點
function bigHeap(array, i, length){
// 不用建樹,因爲完全二叉樹的節點和排序一一對應,所以直接用序列號即可
while(i <= Math.floor(length)/2 - 1){ // i代表父節點,父節點在非葉子節點範圍內則迭代
let left = 2*i+1;
let right = 2*i+2;
let bigChild = left; // 記錄被交換的節點序號
if(right < length){
if(array[right] > array[bigChild]){
bigChild = right;
}
}
if(array[bigChild] > array[i]){
let temp = array[bigChild];
array[bigChild] = array[i];
array[i] = temp;
}
// update
i = bigChild; // 被交換的子節點向下迭代
}
}
var a = [1,2,3,4,5,6,7,8];
// 初始化堆
for(let i = Math.floor(a.length/2)-1; i >= 0; i--){
bigHeap(a, i, a.length); // 從後往前依次建堆
}
console.log(a);
// 堆排序的話,每次更換堆頂點與堆尾
for(let i = a.length - 1; i > 0; i --){
let temp = a[i];
a[i] = a[0];
a[0] = temp;
bigHeap(a, 0, i); // 從後往前依次建堆
}
28. 前端性能優化(寒武紀面試)
- 減少請求資源大小和次數
- 打包工具,合併壓縮css和js
- 圖片資源懶加載,雪碧圖
- 緩存,減少cookie
- 代碼優化
- 動畫效果用css,不用js
- 減少DOM操作,都是爲了減少迴流重繪渲染的時間
<script>
defer和async,不阻塞渲染,提升首屏加載速度
- 存儲優化
- 利用本地存儲storage
29. 實現一個sleep()
函數 (頭條面試)
(async function(){
// something A
await sleep();
// something B
})();
function sleep(seconds){
return new Promise((resolve)=>{
setTimeout( function(){ resolve(); }, seconds);
});
}
30. let和var的區別 (流利說面試)
var age = 100;
let year = 6;
if(age > 12){
let age = 10;
var year = age * 3;
console.log(age, year);
}
console.log(age, year)
輸出:year
已經被聲明
因爲let
會生成一個暫時性死區,在let
形成的塊級作用域中不能再聲明同名變量。
31. 前端性能優化(寒武紀面試)
核心思想:
- 減少請求資源大小和請求次數: 打包工具,合併和壓縮css和js;圖片懶加載;
- 利用緩存和本地存儲:storage/cookie/304
- 代碼書寫上的優化:使用css做效果不是js(合成計算);迴流重繪;defer/async
32. 對稱加密(奇安信筆試)
對稱加密:加密和解密使用相同的密鑰
DES
(Data Encryption Standard
) 數據加密標準,強度不夠,能夠暴力破解3DES
使用3個密鑰進行DES加密,維護3個密鑰,增加維護成本AES(Advanced Encription Standard)
高級加密標準
33. animation
:top
和transform
的區別 (流利說面試)
.animation{
animation: myMovie 1s infinite;
}
@keyframes myMovie{
0%: {top: 0;} /* 或者 0%: { transform: translate(0, 0);} */
25%:{top: 100px;}
50%:{top: 200px;}
75%:{top: 300px}
100%:{top: 400px;}
}
transform
動畫由GPU控制,支持硬件加速,不需要軟件方面的渲染
瀏覽器接收到頁面文檔後,會將文檔中的標記語言解析爲DOM樹。DOM樹和CSS樹結合後形成瀏覽器構建頁面的渲染樹。渲染樹中包含大量的渲染元素,每個渲染元素會被分到一個圖層中,每個圖層又會被加載到GPU形成渲染紋理。使用transform
的圖層不會觸發repaint,最終都由獨立的合成器進程進行處理。
-
獨立的複合圖層
3D
或transform
<video>
和<canvas>
CSS filters
z-index
-
可以觸發GPU加速的CSS屬性
transform
opacity
filter
34. mouse
事件 (奇安信)
事件 | 描述 |
---|---|
mousedown |
鼠標按下 |
mouseup |
鼠標彈起,鼠標釋放 |
mousewheel |
鼠標滾輪滾動 |
mouseout |
鼠標移出 |
mouseover |
鼠標移動到元素上 |
mousemove |
鼠標在元素內移動 |
35. 值類型和引用類型 (招商銀行面試)
var n = 1;
// instanceof 和 isPrototypeOf 需要的參數是對象object
n instanceof Number; // false
Number.prototype.isPrototypeOf(n); // false
// 隱式類型轉換,原型鏈屬性
n.__proto__ === Number.prototype; // true
n.constructor === Number; // true
值類型存儲在棧內存中;引用類型存儲在堆內存中
深拷貝和淺拷貝
36. a:link
和a:hover
(海康威視筆試)
a標籤定義超鏈接,href
指向url,target
表明打開方式
僞類:
- link 未訪問前的樣式表屬性
- visited 已訪問
- hover 鼠標懸浮
- active 鼠標按下,激活連接
定義順序符合Love/Hate原則:LVHA
37. 多用局部變量,少用全局變量(海康筆試)
- 函數聲明時會創建
[[Scope]]
屬性,存儲作用於信息,是一個對象Variable Object
,列表中有可訪問的變量。 - 作用域鏈最前端是
Activation Object
, 最末端是全局對象Global Object
- 函數被執行時會創建執行對象
Execution Object
- 全局變量處在作用域鏈末端,查找變量的速度要比局部變量慢
在美團面試時,還被問到了,作用域鏈中未查找到的變量最後會輸出什麼?
屬性查找:靜默失敗(undefined)
變量查找:分爲LHS和RHS
LHS查詢:靜默創建全局屬性(非全局變量)
RHS查詢:查不到報錯(未聲明)
// 不聲明anything變量
window.anything; // undefined
anything; // ReferenceError: anything is not defined
// 屬性查找:undefined
function run(){
console.log(this.anything)
}
run(); // undefined
// 變量查找:RHS報錯
function run(){
console.log(anything);
}
run(); // ReferenceError: anything is not defined
// 變量查找:LHS靜默創建全局屬性
function run(){
anything = 'zpj';
console.log(anything);
}
run(); // 'zpj'
全局屬性和全局變量的區別:
var
聲明全局變量的同時會自動創建同名全局屬性,通過window.XXX
訪問- 全局屬性可以被
delete
刪除,但是全局變量不可以
function run(){
anything = 'zpj';
console.log(anything);
}
run(); // 'zpj'
anything; // 'zpj'
delete anything; // true
anything; // ReferenceError
var hahaha = 'zpj';
delete hahaha; // false
hahaha; // 'zpj'
38. substr()
和substring()
的區別(海康筆試)
substr(start, length)
substring(start, stop)
從stop到stop-1的所有字符,不接受負參數slice(start, end)
含首不含尾,負數表示從後往前splice(start, length)
39. CSS前景色和背景色(度小滿筆試)
前景就是文本和邊框;當時選項裏出現了
foreground-color
做干擾
前景色 color
border-color
: 前景包括文本和邊框
背景色 background-color
透明度 opacity
filter: alpha(opacity=80)
40. UNIQUE
和DISTINCT
區別(度小滿)
unique
是建表時約束某列值唯一
distinct
是查詢時過濾重複
41. 什麼是shell
?(度小滿)
shell是系統跟計算機硬件交互時使用的中間介質。用戶直接面對的不是計算機硬件,而是shell,用戶把指令告訴shell,然後shell再傳給系統內核,接着內核再去支配計算機硬件執行各種操作。
bash
: linux默認安裝的shell叫作bash,即Bourne Again Shell
是 Bourne Shell
的增強版本。Bourne Shell
是最早流行的一個shell,創始人是Steven Bourne
42. 提升性能(海康威視)
- 減少HTTP請求(資源大小和請求次數):雪碧圖,壓縮合並js和css
- 使用CDN(內容分發網略):選擇最近的服務器
- 緩存(Expires / cache-control: max-age)
- 壓縮(Accept-Encoding:gzip, deflate)(Content-Encoding: gzip)
- 樣式表放在頭部(減少重繪)
- 腳本放在底部(阻塞DOM樹的更新)
- 使用外部腳本和樣式文件(重複利用)
- DNS緩存(DNS域名解析)
- 避免重定向(301/302)
43. 行內元素和塊級元素的嵌套問題(海康)
p div h1-h6 form ul ol dl dd dt li table tr td th hr blockquote address header section article footer
塊級元素:
- 獨佔一行,沒有寬高時默認100%
- 塊級元素允許設置寬高,width、height、margin、padding、border都可控制
- 塊級元素可以包含行內元素、塊級元素
span a img input em b i q select textarea button
行內元素:
- 行內元素不換行
- 不能設置width、height、上下margin和上下padding
- 默認寬度是content寬度
- 行內元素只能包含文字、行內元素、行內塊元素
display: inline-block;
行內塊元素在行內元素的基礎上,可以設置寬高width、height