前端面试题合辑

一、HTML面试题

1. 对 HTML 语义化的理解

  1. 让人更容易读懂(增加代码可读性)。
  2. 让搜索引擎更容易读懂 (搜索引擎优化:SEO)。

常见的语义化标签:

<header></header>  头部

<nav></nav>  导航栏

<section></section>  区块(有语义化的div)

<main></main>  主要区域

<article></article>  主要内容

<aside></aside>  侧边栏

<footer></footer>  底部

2. 默认情况下,哪些是块级元素、哪些是行内块元素、哪些是行内元素?

2.1 块级元素:

  • display: block/table; 有 div、h1~h6、table、form、ul、ol、dl、p 等。

2.2 行内块元素:

  • display: inline-block; 有 img、input、button、select、textarea 等。

2.3 行内元素:

  • display: inline; 有 a、span、strong、b、em、i、label、br 等。

2.4 区别:

类别是否独占一行能否设置宽高能否设置margin能否设置padding
块级元素
行内块元素
行内元素仅左右有效

HTML面试题详解链接:HTML面试题-CSDN博客

二、CSS面试题

1. 盒模型宽度计算

  • offsetWidth = ( 内容宽度 + 内边距 + 边框 ),无外边距。
  • 这里的offsetWidth是 122px。
  • 如果让 offsetWidth 等于 100px ,该如何做?
  • 添加: box-sizing: border-box;

2. margin 纵向重叠问题

  • 相邻元素的 margin-top 和 margin-bottom 会发生重叠,取两者的最大值作为它们之间的距离
  • 空白内容的 <p></p> 也会重叠。

3. margin 负值问题

  • margin-top 和 margin-left 负值,不会增加元素高度和宽度,元素向上、向左移动
  • margin-right 设置负值不会产生位移,只会减小元素供CSS读取的宽度
  • margin-bottom 设置负值不会产生位移,只会减小元素供CSS读取的高度
  • 在元素没有设定width属性或width:auto时,设置左右margin负值会增加元素的宽度

参考:margin负值问题-CSDN博客

4. BFC 的理解和应用

4.1 什么是 BFC?如何应用?

  • Block format context ,块级格式化上下文。
  • 一块独立渲染区域,内部元素的渲染不会影响边界以外的元素。

4.2 形成 BFC 的常见条件

  • float 不是 none。
  • position 是 absolute 或 fixed。
  • overflow 不是 visible。
  • display 是 flex inline-block 等。

4.3 BFC 的常见应用

  • 清除浮动
  • 解决margin的重叠问题

5. float 布局的问题,及clearfix

5.1 圣杯布局:

  • 利用浮动和负边距来实现。
  • 父级元素设置左右的 padding,三列均设置向左浮动。
  • 中间一列放在最前面,宽度设置为父级元素的宽度,因此后面两列都被挤到了下一行。
  • 通过设置 margin 负值将其移动到上一行,再利用相对定位,定位到两边。
.outer {
  height: 100px;
  padding-left: 100px;
  padding-right: 200px;
}

.left {
  position: relative;
  left: -100px;

  float: left;
  margin-left: -100%;

  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  position: relative;
  left: 200px;

  float: right;
  margin-left: -200px;

  width: 200px;
  height: 100px;
  background: gold;
}

.center {
  float: left;

  width: 100%;
  height: 100px;
  background: lightgreen;
}

5.2 双飞翼布局:

  • 双飞翼布局相对于圣杯布局来说,左右位置的保留是通过中间列的 margin 值来实现的。
  • 而不是通过父元素的 padding 来实现的。本质上来说,也是通过浮动和外边距负值来实现的。
.outer {
  height: 100px;
}

.left {
  float: left;
  margin-left: -100%;

  width: 100px;
  height: 100px;
  background: tomato;
}

.right {
  float: left;
  margin-left: -200px;

  width: 200px;
  height: 100px;
  background: gold;
}

.wrapper {
  float: left;

  width: 100%;
  height: 100px;
  background: lightgreen;
}

.center {
  margin-left: 100px;
  margin-right: 200px;
  height: 100px;
}

5.3 圣杯布局和双飞翼布局的技术总结

  1. 使用 float 布局。
  2. 两侧使用 margin 负值,以便和中间内容横向重叠。
  3. 防止中间内容被两侧覆盖,圣杯布局在父元素设置 padding,双飞翼布局在center上设置 margin

5.4 手写 clearfix

/* 手写 clearfix */
.clearfix:after {
    content: '';
    display: table;
    clear: both;
}
.clearfix {
    /* 兼容 IE 低版本 */
    *zoom: 1; 
}

6. flex 画色子

6.1 常用语法

  • 容器属性:flex-direction(决定主轴的方向)、justify-content(主轴上的对齐)、flex-wrap(是否换行)、align-items(交叉轴上如何对齐)。
  • 项目属性:align-self(该项目在交叉轴的对齐方式)。
  • 详细介绍地址:flex布局--入门_小豪boy的博客-CSDN博客

6.2 flex 实现一个三点的色子

<!DOCTYPE html>
<html>
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>flex 画骰子</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            border: 2px solid #ccc;
            border-radius: 10px;
            padding: 20px;
            /* flex 布局 */
            display: flex;
            /* 两端对齐 */
            justify-content: space-between;
        }
        .item {
            /* 点的样式 */
            display: block;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            background-color: #666;
        }
        .item:nth-child(2) {
            /* 第二项居中对齐 */
            align-self: center;
        }
        .item:nth-child(3) {
            /* 第三项尾对齐 */
            align-self: flex-end;
        }
    </style>
</head>
 
<body>
    <div class="box">
        <span class="item"></span>
        <span class="item"></span>
        <span class="item"></span>
    </div>
</body>
 
</html>

7. absolute 和 relative 分别依据什么进行定位?

  • relative 依据自身定位。
  • absolute 依据最近一层的定位元素定位。
  • 定位元素:
    • absolute relative fixed
    • body

8. 居中对齐有哪些实现方式?

8.1 水平居中

文本水平居中:

  • 文本内容居中:text-align: center;

div水平居中:

  • 有固定宽度:margin: 0 auto;
  • absolute 定位,知道元素宽度:left: 50% ;margin-left:负宽度的一半;
  • absolute 定位,元素宽度未知:left: 50%;transform:translateX(-50%);
  • absolute 定位:left: 0; right: 0; margin: 0 auto;
  • flex布局:justify-content: center;

8.2 垂直居中

文本垂直居中:

  • 设置行高等于所在区域的高度:height: 200px; line-height: 200px;
  • vertical-align实现文本的垂直居中:display:table-cell; vertical-align:middle;

div垂直居中:

  • absolute 定位,知道元素高度:top: 50%;margin-top:负高度的一半;
  • absolute 定位,元素高度未知:top: 50%;transform: translateY(-50%);
  • absolute 定位:top: 0; bottom: 0; margin: auto 0;
  • flex布局:align-items:center;

8.3 水平垂直居中

文本水平垂直居中:

  • text-align: center;height: 200px; line-height: 200px;
  • text-align: center;display:table-cell; vertical-align:middle;

div水平垂直居中:

  • absolute 定位,知道元素宽高:left: 50% ;margin-left:负宽度的一半;top: 50%;margin-top:负高度的一半;
  • absolute 定位,元素宽高未知:left: 50%; top: 50%;transform: translate(-50%,-50%);
  • absolute 定位:left: 0; right: 0; top: 0; bottom: 0; margin: auto;
  • flex布局:justify-content: center; align-items:center;

9. line-height 的继承问题

  • 带单位:px 是固定值,而 em 会参考父元素 font-size 值计算自身的行高
  • 纯数字:会把比例传递给后代。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px
  • 百分比:将计算后的值传递给后代

10. rem 是什么?

  • rem 是一个长度单位。
  • em ,相对长度单位,相对于父元素,不常用。
  • px ,绝对长度单位,最常用。
  • rem ,相对长度单位,相对于根元素,常用于响应式布局。

11. 如何实现响应式?

  1. media-query,根据不同的屏幕宽度设置根元素 font-size。
  2. rem,基于根元素的相对单位。
<!DOCTYPE html>
<html>
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>响应式布局</title>
    <style>
        @media only screen and (max-width: 374px) {
 
            /* iphone5 或者更小的尺寸,以 iphone5 的宽度(320px)比例设置 font-size */
            html {
                font-size: 86px;
            }
        }
 
        @media only screen and (min-width: 375px) and (max-width: 413px) {
 
            /* iphone6/7/8 和 iphone x */
            html {
                font-size: 100px;
            }
        }
 
        @media only screen and (min-width: 414px) {
 
            /* iphone6p 或者更大的尺寸,以 iphone6p 的宽度(414px)比例设置 font-size */
            html {
                font-size: 110px;
            }
        }
 
        body {
            font-size: 0.16rem;
        }
 
        #div1 {
            width: 1rem;
            height: 1rem;
            background-color: gold;
        }
    </style>
</head>
 
<body>
    <div id="div1"></div>
</body>
 
</html>

CSS面试题详解链接:CSS面试题-CSDN博客

三、JavaScript面试题

1. JavaScript有哪些数据类型?

  • JavaScript共有八种数据类型,分别是 Undefined、Null、Boolean、Number、String、Object、Symbol、BigInt。
  • 其中 Symbol 和 BigInt 是ES6 中新增的数据类型。
  • 基本数据类型(值类型):Undefined、Null、Boolean、Number、String、Symbol、BigInt,除了 null 和 undefined之外,所有基本类型都有其对应的包装对象。
  • 引用类型(对象):Object。

2. typeof 能判断哪些类型?

console.log(typeof 2);               // number
console.log(typeof true);            // boolean
console.log(typeof 'str');           // string
console.log(typeof []);              // object    
console.log(typeof function(){});    // function
console.log(typeof {});              // object
console.log(typeof undefined);       // undefined
console.log(typeof null);            // object
  • 其中数组、对象、null都会被判断为object,其他判断都正确。

3. 何时使用 === 何时使用 == ?

4. 值类型和引用类型的区别?

  • 声明变量时不同的内存分配:栈与堆。
  • 不同的访问机制:直接访问与引用访问。
  • 复制变量时不同:直接复制值与复制内存地址。
  • 参数传递的不同:传递值和传递内存地址。

5. 手写深拷贝

  1. 判断值类型和引用类型。
  2. 判断是数组还是对象。
  3. 判断 key 是不是原型的属性
  4. 递归。
/**
 * 深拷贝
 * @param {Object} obj 要拷贝的对象
 */
function deepClone(obj = {}) {
    if (typeof obj !== 'object' || obj == null) {
        // obj 是 null ,或者不是对象和数组,直接返回
        return obj
    }
 
    // 初始化返回结果
    let result
    if (obj instanceof Array) {
        result = []
    } else {
        result = {}
    }
 
    for (let key in obj) {
        // 保证 key 不是原型的属性
        if (obj.hasOwnProperty(key)) {
            // 递归调用!!!
            result[key] = deepClone(obj[key])
        }
    }
 
    // 返回结果
    return result
}

6. 如何准确判断一个变量是不是数组?

  • instanceof可以正确判断对象的类型,其内部运行机制是判断在其原型链中能否找到该类型的原型
console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true
  • 可以看到,instanceof只能正确判断引用数据类型,而不能判断基本数据类型。

7. class 的原型本质,怎么理解?

  • class 是ES6语法规范,实际上是函数,可见是语法糖,具体实现还是使用的原型与原型链。

  • 隐世原型(__proto__)和显示原型(prototype)。
  • 每个 class都有显示原型 prototype
  • 每个实例都有隐式原型 __proto__
  • 实例的 __proto__ 指向对应 class 的 prototype 。

原型链:

  • 获取实例的属性或执行方法时,先在自身属性和方法中寻找,如果找不到则自动去隐式原型 __proto__ 中查找,若还是没有找到,则逐级向上查找,当查找到目标或隐式原型 __proto__ 为 null 时,结束查找。

8. 手写一个简易的 JQuery 考虑插件和扩展性

  • 简易的jQuery
class jQuery {
    constructor(selector) {
        const result = document.querySelectorAll(selector)
        const length = result.length
        for (let i = 0; i < length; i++) {
            this[i] = result[i]
        }
        this.length = length
        this.selector = selector
    }
    get(index) {
        return this[index]
    }
    each(fn) {
        for (let i = 0; i< this.length; i++) {
            const elem = this[i]
            fn(elem)
        }
    }
    on(type, fn) {
        return this.each(elem => {
            elem.addEventListener(type, fn, false)
        })
    }
}
  • 插件
// 插件
jQuery.prototype.dialog = function (info) {
    alert(info)
}
  • 扩展性--“造轮子”
// “造轮子”
class myJQuery extends jQuery {
    constructor(selector) {
        super(selector)
    }
    // 扩展自己的方法
    addClass(className) {
 
    }
    style(data) {
        
    }
}

9. this 的不同应用场景,如何取值?

10. 手写 bind 函数

// 模拟 bind
Function.prototype.bind1 = function () {
    // 将参数拆解为数组
    const args = Array.prototype.slice.call(arguments)
 
    // 获取 this (数组的第一项,数组剩余的就是传递的参数)
    const t = args.shift()
 
    // fn1.bind(...) 中的 fn1
    const self = this
 
    // 返回一个函数
    return function () {
        // 执行原函数,并返回结果
        return self.apply(t, args)
    }
}

11. 实际开发中闭包的应用场景,举例说明

  • 做一个简单的 cache 隐藏工具
// 闭包隐藏数据,只提供 API
function createCache() {
    // 闭包中的数据,被隐藏,不被外界访问
    const data = {}
    return {
        set: function (key, val) {
            data[key] = val
        },
        get: function (key) {
            return data[key]
        }
    }
}

12. 创建 10 个 a 标签,点击的时候弹出对应的序号

<!DOCTYPE html>
<html>
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial=1.0">
    <title>作用域</title>
</head>
 
<body>
    <script>
        // 创建 10 个 <a> ,在块级作用域中,声明序号 i ,点击时弹出来的序号与标签中的序号对应。
        let a
        for (let i = 0; i < 10; i++) {
            a = document.createElement('a')
            a.innerHTML = i + '<br>'
            a.addEventListener('click', (e) => {
                e.preventDefault
                console.log(i)
            })
            document.body.appendChild(a)
        }
    </script>
</body>
 
</html>

13. 同步和异步的区别是什么?

  • 异步不会阻塞代码执行。
  • 同步会阻塞代码执行。

14. 手写用 Promise 加载一张图片

// 异步加载图片。
function loadImg(src) {
    const p = new Promise(
        (resolve, reject) => {
            const img = document.createElement('img')
            img.onload = () => {
                resolve(img)
            }
            img.onerror = () => {
                const err = new Error(`图片加载失败 ${src}`)
                reject(err)
            }
            img.src = src
        }
    )
    return p
}

15. 前端使用异步的场景有哪些?

  • 网络请求,如 ajax 图片加载。
  • 定时任务,如 setTimeout。

16. 请描述 event loop(事件循环/事件轮询)的机制,可画图

  1. 同步代码,一行一行放在 Call Stack 执行。
  2. 遇到异步,会先 “记录” 下,等待时机(定时、网络请求等)。
  3. 时机到了,就移动到 Callback Queue。
  4. 同步代码执行完 Call Stack 为空,Event Loop 开始工作。
  5. 轮询查找 Callback Queue,如有则移动到 Call Stack 执行。
  6. 然后继续轮询查找(永动机一样)。

17. 什么是宏任务和微任务,两者有什么区别?

  • 宏任务:DOM渲染后触发,setTimeout,setInterval,Ajax,DOM事件。
  • 微任务:DOM渲染前触发,Promise,async/await。
  • 微任务执行时机比宏任务要早。

18. Promise有哪三种状态?如何变化?

  • Promise 有 3 种状态,一开始是 pending(未完成)。

  • 执行 resolve,变成 fulfilled(resolved),已成功。

  • 执行 reject,变成 rejected,已失败。

19. then 和 catch 的链式调用题目

  • Promise 的实例化为同步部分会立即执行,后面的 then 和 catch 才进行异步处理

20. async/await是什么

  • async/await 是同步语法,彻底消灭回调函数。
  • 本质上只是一个语法糖,具体实现还是得有异步,还是得基于 event loop。
  • async是一个加在函数前的修饰符,被async定义的函数会默认返回一个Promise对象resolve的值。
  • await 操作符用于等待一个 Promise 对象,它只能在异步函数 async function 内部使用。

21. async/await 和 Promise 的关系

  • 执行 async 函数,返回的是 Promise 对象。
  • await相当于 Promise 的 then。
  • try- catch可捕获异常,代替了 Promise的 catch。

22. async/await 的执行流程

  • 只要遇到了 await,await 本身会立即执行,而 await 后面的代码都相当于放在 callback 里,进行异步处理。
async function async1() {
    console.log('async1 start')  // 2
    await async2() // 这一句会同步执行,返回 Promise ,其中的 `console.log('async2')` 也会同步执行
    console.log('async1 end') // 5 上面有 await ,下面就变成了“异步”,类似 callback 的功能(微任务)
}
 
async function async2() {
    console.log('async2')  // 3
}
 
console.log('script start')  // 1
async1()
console.log('script end')  // 4
async function async1() {
    console.log('async1 start')      // 2
    await async2() // 这一句会同步执行,返回 Promise ,其中的 `console.log('async2')` 也会同步执行
 
    // 上面有 await ,下面就变成了“异步”,类似 callback 的功能(微任务)
    console.log('async1 end')        // 6
}
 
async function async2() {
    console.log('async2')            // 3
}
 
console.log('script start')          // 1
 
setTimeout(function () { // 异步,宏任务
    console.log('setTimeout')        // 8
}, 0)
 
async1()
 
// 初始化 Promise 时,传入的函数会立刻被执行
new Promise(function (resolve) {
    // 返回 Promise 之后,即同步执行完成,then 是异步代码
    console.log('promise1')          // 4
    resolve()
}).then(function () { // 异步,微任务
    console.log('promise2')          // 7
})
 
console.log('script end')            // 5
 
// 同步代码执行完,(event loop - call stack 被清空)
// 执行微任务
// (尝试触发 DOM 渲染)
// 触发 Event Loop,执行宏任务

23.for of 与 for in的区别

for of

  • 遍历可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)。
  • 在每次迭代时,得到的是不同属性的值(value)。
  • 不能遍历对象。

for in:

  • 遍历一个对象(包含数组)。
  • 在每次迭代时,得到的是不同属性的键名(key)。

JS面试题详解链接:

  1. js面试题--变量类型和计算-CSDN博客
  2. js面试题--原型和原型链-CSDN博客
  3. js面试题--作用域和闭包-CSDN博客
  4. js面试题--异步和单线程-CSDN博客

补充:

JS Web API:

  • DOM:文档对象模型,处理网页内容的方法和接口。
  • BOM:浏览器对象模型,与浏览器交互的方法和接口。
  • 事件:视图层到逻辑层的通讯方式。
  • ajax:异步的 JavaScript 和 XML,是一种用于创建快速动态网页的技术。
  • 存储:本地存储。

四、DOM 题目

1. DOM是哪种数据结构

  • DOM是JS操控HTML和CSS的桥梁。
  • DOM是哪种基本的数据结构? ——  树。

2. DOM操作的常用API

2.1 节点操作:

2.2 结构操作:

  • 添加新节点:创建新节点,向 DOM 树上的节点插入新节点。

  • 移动节点:将已经挂载到DOM树上的节点成为appendChild()的参数,这个节点将会被移动。

  • 获取父节点

  • 获取子元素节点(childNodes会获取所有的子节点,其中可能包括很多元素节点之外的其他节点)

  • 删除子节点

3. attribute 和 property的区别

  • attribute 是 dom 元素在⽂档中作为 html 标签拥有的属性;

  • property 就是 dom 元素在 js 中作为对象拥有的属性。

  • 对于 html 的标准属性来说,attribute 和 property 是同步的,是会⾃动更新的。

  • 但是对于⾃定义的属性来说,他们是不同步的。

4. 一次性插入多个 DOM 节点,考虑性能

  • 关键在于创建一个文档片段:document.createDocumentFragment()。

DOM 面试题详解链接:JS-Web-API-DOM面试题-CSDN博客

五、BOM 题目

1. 如何识别浏览器的类型

2. 分析拆解url 各个部分

BOM 面试题详解链接:JS-Web-API-BOM面试题-CSDN博客

六、事件题目

1. 编写一个通用的事件监听函数

注:

  •         selector: 是个css选择器字符串。
  •         target.matches(selector) : 如果元素被指定的选择器(selector)字符串选择返回true; 否则返回false。

2. 描述事件冒泡的流程

  • 基于 DOM 树形结构。
  • 事件会顺着触发元素向上冒泡。
  • 应用场景:代理。

3. 无限下拉的图片列表,如何监听每个图片的点击?

  • 事件代理又叫事件委托,原理是利用事件冒泡机制,将后代元素事件委托给祖先元素。
  • 当有大量类似元素需要批量添加事件监听时,使用事件委托可以减少内存开销。
<!DOCTYPE html>
<html>
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>事件代理</title>
</head>
 
<body>
    <div id="div3">
        <a href="#">a1</a><br>
        <a href="#">a2</a><br>
        <a href="#">a3</a><br>
        <a href="#">a4</a><br>
        <button>加载更多...</button>
    </div>
    <script>
        // 通用事件绑定函数
        function bindEvent(elem, type, selector, fn) {
            // 处理只传3个参数的情况
            if (fn == null) {
                fn = selector
                selector = null
            }
            elem.addEventListener(type, event => {
                const target = event.target
                if (selector) {
                    // 代理绑定
                    if (target.matches(selector)) {
                        fn.call(target, event)
                    }
                } else {
                    // 普通绑定
                    fn.call(target, event)
                }
            })
        }
 
        // 代理绑定
        const div3 = document.getElementById('div3')
        bindEvent(div3, 'click', 'a', function (event) {
            event.preventDefault() // 阻止默认行为
            alert(this.innerHTML)
        })
    </script>
</body>
 
</html>

事件面试题详解链接:JS-Web-API-事件-面试题-CSDN博客

七、ajax 题目

1. 手写一个简易的 ajax

  1. 创建 xhr 对象
  2. 准备发送请求
  3. 监听事件,处理响应
  4. 发送请求
function ajax(url) {
    const p = new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()
        xhr.open('GEt', url, true)
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4) {
                if (xhr.status === 200) {
                    resolve(
                        JSON.parse(xhr.responseText)
                    )
                } else if (xhr.status === 404 || xhr.status === 500) {
                    reject(new Error('404 not found'))
                }
            }
        }
        xhr.send(null)
    })
    return p
}

2. 跨域的常用实现方式

  • ① CORS 跨域资源共享
  • ② JSONP
  • 优先使用 CORS 跨域资源共享,如果浏览器不支持 CORS 的话,再使用 JSONP。

ajax 面试题详解链接:JS-Web-API-Ajax-面试题-CSDN博客

八、存储题目

1. 描述 cookie localStorage sessionStorage区别

  • 容量 :cookie(<4K),localStorage 和 sessionStorage(<5M)。
  • API易用性:cookie(document.cookie),localStorage 和 sessionStorage(setitem getitem)。
  • 是否跟随http请求发送出去:cookie(跟随),localStorage 和 sessionStorage(不跟随)。
  • 存储时间:cookie 和 localStorage 数据只存在于当前会话,浏览器关闭则清空;localStorage 数据会永久存储,除非代码或手动删除。

存储面试题详解链接:JS-Web-API-存储-面试题-CSDN博客

九、页面加载过程+性能优化+安全题目

1. 从输入 url 到渲染出页面的整个过程

  1. 下载资源:各个资源类型,下载过程。
  2. 渲染页面:
    • 根据 HTML 代码生成 DOM Tree 。
    • 根据 CSS 代码生成 CSSOM 。
    • 将 DOM Tree 和 CSSOM 整合形成 Render Tree 。
    • 根据 Render Tree 渲染页面 。
    • 遇到 <script> 则暂停渲染,优先加载并执行 JS 代码,完成再继续。
    • 直至把 Render Tree 渲染完成。

2. load和 DOMContentLoaded 的区别

  • load:资源全部加载完才能执行,包括图片。
  • DOMContentLoaded:DOM 渲染完成即可,图片可能尚未下载。

3. 前端常见性能优化方案

3.1 让加载更快

  • 减少资源体积:压缩代码。
  • 减少访问次数∶合并代码、SSR服务器端渲染、緩存。
  • 使用更快的网络:CDN。

3.2 让渲染更快

  • CSS 放在 head,JS 放在 body 最下面。
  • 尽早开始执行JS,用 DOMContentloaded 触发。
  • 懒加载(图片懒加载,上滑加载更多)。
  • 对 DOM 查询进行缓存。
  • 频繁 DOM 操作,合并到一起插入 DOM 结构。

4. 手写节流和防抖

  • 防抖:
// 防抖
function debounce(fn, delay = 500) {
    // timer 是闭包中的
    let timer = null

    return function () {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}
  • 节流:
// 节流
function throttle(fn, delay = 100) {
    // timer 是闭包中的
    let timer = null

    return function () {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments)
            timer = null
        }, delay)
    }
}

5. Web前端常见的安全攻击方式和预防

5.1 攻击方式

  • XSS 跨站请求攻击

  • XSRF/CSRF 跨站请求伪造

5.2 预防

  • XSS 预防:替换特殊字符串
  • XSRF/CSRF 预防:使用 post 接口、增加验证,如:密码、短信验证码等。

页面加载过程+性能优化+安全面试题详解链接:小豪boy的博客

十、http 题目

1. http 常见的状态码有哪些?

1xx 服务器收到请求;

2xx 请求成功;

  • 200 成功。

3xx 重定向;

  • 301 永久重定向(配合 location,浏览器自动处理)。
  • 302 临时重定向(配合 location,浏览器自动处理)。
  • 304 资源未被修改。

4xx 客户端错误;

  • 404 资源未找到。
  • 403 没有权限。

5xx 服务器错误;

  • 500 服务器错误。
  • 504 网关超时。

2. http 常见的 header 有哪些?

2.1 Request Headers

2.2 Responce Headers

3. http methods

  • get 获取数据
  • post 新建数据
  • patch/put 更新数据
  • delete 删除数据

4. 什么是 Restful API

  • 传统 API 设计:把每个 url 当作一个功能。
  • Restful API 设计:把每个 url 当作一个唯一的资源。

如何设计成一个资源?

  • 尽量不用 url 参数。

  • 用 method 表示操作类型。

5. 描述以下 http 的缓存机制

5.1 强制缓存:

  • 强制缓存在缓存数据未失效的情况下(即Cache-Control的max-age没有过期或者Expires的缓存时间没有过期),那么就会直接使用浏览器的缓存数据,不会再向服务器发送任何请求。

5.2 协商缓存(对比缓存):

  • 服务器判断客户端资源,是否和服务器端资源一样。
  • 一致则返回 304,否则返回 200 和最新资源。

5.3 http 缓存流程图

http面试题详解链接:http 面试题-CSDN博客

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值