前端的自我修养

前端的自我修养

JiangWen Lv4

CSS部分

问:css盒模型是什么?

答: 在html中所有的元素都可以看成一个盒子,盒子由外边距margin、内边距padding、边框border、内容content四部分构成;盒子的类型分为两种:

  • 标准盒模型:margin border + padding + content

  • IE盒模型:margin + content(border + padding)

    通过控制css属性box-sizing: 默认值(标准盒模型)| border-box(IE盒模型)

    总结: 标准盒模型的宽高设置的是内容content, IE盒模型的宽高设置的是border + padding + content三者相加的总和

问:css选择器的优先级?

答:css的特性包括:继承性、层叠性、优先级;当一个元素有多个样式的时候,显示权重高的样式,权限的优先级分为

important > 行内样式 > id > 类/伪类/属性> 标签 > 全局选择器*

问:隐藏元素的方式有哪些?

答:display: none | opacity: 0 | visibility: hidden,其中只有第一种隐藏方式的元素不占据空间

问:px 和 rem 的区别是什么?

答: px属于绝对单位长度,代表显示器上的一个像素单位;rem属于相对单位长度,代表相当于html根节点的值,例如:

设置根节点的font-size: 62.5%,得到的1rem实际单位长度为16px * 62.5% = 10px, 即1rem = 10px

问: 重排和重绘有什么区别?

答:

​ 重排也称回流:浏览器渲染引擎会根据所有元素的样式计算出盒模型在页面中的位置和大小;当对Dom的大小、位置进行修改后,引擎需要进行重新计算,就会触发重排机制,重排必然引起重绘。

​ 重绘:浏览器渲染引擎计算好盒模型的位置、大小等基本属性后,对每个盒模型的其他特性进行绘制;对Dom的样式进行修改,比如background-color,渲染引擎不需要重新计算几何属性,只需对元素的样式进行绘制,就只会触发重绘机制

问: 元素水平垂直居中的方式?

答: 一般常见的有以下几种方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/* 方式1: 定位+margin */
.container {
...
position: relative;
}
.box {
...
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}

/* 方式2: 定位+transform */
.container {
...
position: relative;
}
.box {
...
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}

/* 方式3: flex布局 */
.container {
...
display: flex;
justify-content: center;
align-items: center;
}
/* 方式4: grid布局 */
/* 方式5: table布局 */
问: css中哪些属性可以继承?

答:以下元素属性没有设置值时,则默认继承父级属性值:

  1. 字体系列属性: fontfont-familyfont-weightfont-sizefontstyle
  2. 文本属性: colorline-heightword-spacingletter-spacingtext-transformtext-indenttext-align
  3. 元素可见性: visibility
  4. 表格布局属性: caption-sideborder-collapseborder-spacingempty-cellstable-layout
  5. 列表布局属性:list-style
  6. 光标属性:cursor

HTML部分

javascript部分

问: js由哪三部分构成?

答:ECMAScript(核心)、DOM(文档对象模型)、BOM(浏览器对象模型)

问: js对数据类的检测方式有哪些?

问:js有哪些内置对象?

答:常见的有StringNumberBooleanArrayObjectFunctionMathDateRegExp 等…

答:一般通过以下方式

  1. typeof: 只能检测基本数据类型
  2. instanceof: 只能检测引用数据类型
  3. constructor: 可以判断基本和引用数据类型,但是对于构造函数而言,如果改变它的原型指向,会导致检测结果不正确
  4. Object.prototype.toString.call: 最佳检测方式
1
2
3
4
5
6
7
8
9
10
11
const res_1 = typeof '123' // => string
const res_2 = [] instanceof Array // => true

function A(name) {
this.name = name
}
let a = new A('jiangwen')
const res_3 = a.constructor === A // => true
A.prototype = Array
const res_4 = a.constructor === A // => false , 指向的constructor变为Array
const res_5 = Object.prototype.toString.call('abc') // => [object String]
问:什么是闭包,闭包有什么特点?

答: 闭包在JavaScript高级程序设计 (第3版)中是这样描述:闭包是指有权访问另一个函数作用域中的变量的函数。

闭包的特点是:

  • 可以在函数的外部访问到函数内部的局部变量。
  • 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。

使用场景:

  • 防抖
  • 节流
  • 函数嵌套避免全局污染
问:前端中的内存泄露是什么?

答: js的垃圾回收机制没有释放已经分配了内存地址的对象,造成长期的内存占用、内存资源浪费,导致运行速度慢,甚至崩溃的情况。会导致内存泄露的因素:

  1. 一些未声明直接赋值的变量
  2. 未清空的定时器
  3. 过渡闭包
  4. 引用的元素没有被清除
问:什么是原型链?

答:原型就是一个普通的对象,为构造函数的实例共享属性和方法;所有实例对象中引用的原型都是同一个对象,使用prototype可以把属性、方法挂载到原型对象中进行共享,而内存仅需保存一份;实例对象中的属性__proto__,指向了构造函数的原型对象prototype,一个实例对象在调用属性、方法的时候,会依次从实例本身 => 构造函数的原型对象 => 原型对象的原型对象,进行查找,这些原型关系就构成了原型链。

img

小结

  • 所有构造函数的__proto__都指向Function.prototype,包括Function本身
  • 所有原型对象的__proto__都指向Object.prototype, 而Object.prototype本身的__proto__指向null
问:new 操作符具体做了什么?

答:具体分为以下步骤:

1
2
3
4
5
6
7
8
9
10
function newFn(Fn, ...args) {
// 1. 创建一个空对象
let newObj = {};
// 2. 把空对象和构造函数通过原型链进行关联
newObj.__proto__ = Fn.prototype
// 3. 将构造函数的`this`绑定到空对象上
let res = Fn.apply(newObj, args)
// 4. 根据构造函数返回的类型判断;如果是值类型,则返回对象,如果是引用类型,则返回这个引用类型
return res instanceof Object ? res : newObj
}
问:js是如何实现继承的?

答: 常见的有以下几种方式

  1. 原型链继承
  2. 借用构造函数继承
  3. 组合式继承
  4. ES6的class类继承
问:js中关于this指向的问题?

答: 分为以下情况

  1. 全局对象中的this指向的是window

  2. 全局作用域、普通函数中的this指向全局window

  3. 匿名函数的执行环境具有全局性,因此匿名函数中的this永远指向window

  4. this永远指向最后调用它的那个对象

  5. new关键字改变了this的指向

  6. 不是箭头函数的时候,callapplybind可以改变this的指向

  7. 箭头函数中的this指向,在它定义的时候就已经确定了,箭头函数本身没有this,看外层的函数是否有this,有就是外层函数的this,没有就是指向window

问: async 和 defer 有什么区别?

答:它们两个属性都是指定浏览器进行脚本的异步加载,但是加载后的执行时机不同,defer需要所有元素加载完成之后才执行,asyncHTML5新增的属性,只要脚本加载完成之后就马上执行,因此async不能确保脚本的执行顺序,而defer则可以。

问: ES6的新特性有哪些?

答:有以下新特性:

  1. 新增了块级作用域(let,const)

  2. 新增了定义类语法糖(class)

  3. 新增了基本数据类型(symbol)

  4. 新增了解构赋值

  5. 新增了函数参数的默认值

  6. 新增了数组的API

  7. 对象和数组新增了扩展运算符(…)

  8. 新增了promise

    • 把异步操作队列化,解决了回调地狱的问题
    • all,reject,resolve,race方法
    • 原型有thencatch
    • 三种状态pending|rejected|fulfilled, 状态一旦从pending => rejected或者pending => fulfilled改变,状态就确定了,不可逆
    • asyncawait: 同步代码做异步操作,两者必须搭配使用
  9. 新增了模块化(import、export)

  10. 新增了set 和map数据结构

    • set 数据结构不存在重复
    • map 数据结构的key类型不受限制
  11. 新增了generator构造器

  12. 新增了箭头函数

问: 箭头函数和普通函数有什么区别?

答:有以下区别

  1. 箭头函数不能使用new操作符, 来作为构造函数使用
  2. 箭头函数没有原型
  3. 箭头函数没有arguments
  4. 箭头函数不能用callcallcall去改变this的执行
  5. 箭头函数的this执行外层函数的第一个this
问: 如何实现一个深拷贝?

答:一般可以通过以下方式:

  1. 扩展运算符实现

    1
    let oo_1 = { ...o}  // 缺点: 对于对象中的引用数据类型还是浅拷贝
  2. JSON.parse(JSON.stringify())

    1
    let oo_1 = JSON.parse(JSON.stringify(o))  // 缺点: 对象中的函数不会拷贝
  3. 递归复制

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
    * origin: 拷贝源对象
    * deep: 是否使用深拷贝
    */
    function deepClone(origin, deep) {
    let obj = {}
    if (origin instanceof Array) obj = [];
    for (let key in origin) {
    let value = origin[key]
    obj[key] = (!!deep && typeof value === "object" && value !== null) ? deepClone(value, deep) : value
    }
    return obj
    }

    let oo_1 = deepClone(o, true)
问: 说一下事件循环?

答: js是一个单线程脚本语言,

经典试题

  1. 三次握手和四次挥手详细介绍

  2. TCP有哪些手段保证可靠交付

  3. URL从输入到页面渲染全流程

  4. 如何预防中间人攻击

  5. DNS解析会出错吗,为什么

  6. ES6的Set内部实现

  7. 如何应对流量劫持

  8. 算法:top-K问题,分成top-1,top-2,top-K三小问

  9. 跨域

  10. webpack的plugins和loaders的实现原理

  11. vue和react谈谈区别和选型考虑

  12. webpack如何优化编译速度

  13. 事件循环机制,node和浏览器的事件循环机制区别

  14. 单元测试编写有哪些原则

  15. 一个大型项目如何分配前端开发的工作

  16. 怼项目

  17. typescript有什么好处

  18. vue项目中如何约束rxjs数据的类型

  19. rxjs高阶数据流定义,常用高阶数据流操作符

  20. JWT优缺点

  21. 选择器优先级

  22. 基本数据类型

  23. RxJS冷热流区别

  24. RxJS调试方法

  25. nginx负载均衡配置

  26. 前端性能优化手段

  27. 针对React的性能优化手段

  28. 301 302 307 308 401 403

  29. vue的nextTick实现原理以及应用场景

  30. vue组件间通信

  31. 谈谈XSS防御,以及Content-Security-Policy细节

  32. 场景题:一个气球从右上角移动到中间,然后抖动,如何实现

  33. 场景题:一个关于外边距合并的高度计算

  34. mobx-react如何驱动react组件重渲染

  35. forceUpdate经历了哪些生命周期,子组件呢?

  36. React key场景题:列表使用index做key,删除其中一个后,如何表现?

  37. 算法:实现setter(obj, ‘a.b.c’ ,val)

  38. RxJS相对于其他状态管理方案的优势?

  39. 手写冒泡排序

  40. JWT细节,适用场景

  41. 跨域

  42. 方案题:不同前端技术栈的项目,如何实现一套通用组件方案?

  43. ES6特性

    闭包和this一起谈谈

    postcss配置

    Promise内部实现原理

    vuex, mobx, redux各自的特点和区别

    react生命周期

    各方面谈谈性能优化

    serviceworker如何保证离线缓存资源更新

    virtual dom有哪些好处

    1. Vue3 proxy解决了哪些问题?

    2. Vue响应式原理

    3. 发布订阅模式和观察者模式的异同

    4. 图片懒加载实现

    5. css垂直居中

    6. CI/CD流程

    7. 谈谈性能优化

    8. react生命周期

key的作用

hooks

vue和react区别,选型考虑

   canvas优化绘制性能

   webpack性能优化手段

   事件循环

   如何解决同步调用代码耗时太高的问题

   手写Promise实现

   1. Promise实现原理
  1. vue组件间通信
    1. 性能优化
  2. vuex数据流动过程
    1. 谈谈css预处理器机制
  3. 算法:Promise串行

JavaScript

1、原型/原型链/构造函数/实例/继承

2、有几种方式可以实现继承

3、用原型实现继承有什么缺点,怎么解决

4、arguments

5、数据类型判断

6、作用域链、闭包、作用域

7、Ajax的原生写法

8、对象深拷贝、浅拷贝

9、图片懒加载、预加载

10、实现页面加载进度条

11、this关键字

12、函数式编程

13、手动实现parseInt

14、为什么会有同源策略

15、怎么判断两个对象是否相等

16、事件模型

  • 事件委托、代理
  • 如何让事件先冒泡后捕获

17、window的onload事件和domcontentloaded

18、for…in迭代和for…of有什么区别

19、函数柯里化

20、call apply区别,原生实现bind

  • call,apply,bind 三者用法和区别:角度可为参数、绑定规则(显示绑定和强绑定),运行效率、运行情况。

21、async/await

22、立即执行函数和使用场景

23、设计模式(要求说出如何实现,应用,优缺点)/单例模式实现

24、iframe的缺点有哪些

25、数组问题

  • 数组去重
  • 数组常用方法
  • 查找数组重复项
  • 扁平化数组
  • 按数组中各项和特定值差值排序

26、BOM属性对象方法

27、服务端渲染

28、垃圾回收机制

29、eventloop

  • 进程和线程
  • 任务队列

30、如何快速让字符串变成已千为精度的数字

ES6

1、声明 let、const

2、解构赋值

3、声明类与继承:class、extend

4、Promise的使用与实现

5、generator(异步编程、yield、next()、await 、async)

6、箭头函数this指向问题、拓展运算符

7、map和set有没有用过,如何实现一个数组去重,map数据结构有什么优点?

8、ES6怎么编译成ES5,css-loader原理,过程

9、ES6转成ES5的常见例子

  • 使用es5实现es6的class

浏览器

1、输入url到展示页面过程发生了什么?

2、重绘与回流

  • 重绘(repaint): 当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此 损耗较少
  • 回流(reflow): 当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。会触发回流的操作:
    * 页面初次渲染
    * 浏览器窗口大小改变
    * 元素尺寸、位置、内容发生改变
    * 元素字体大小变化
    * 添加或者删除可见的 dom 元素
    * 激活 CSS 伪类(例如::hover)
    * 查询某些属性或调用某些方法
    * clientWidth、clientHeight、clientTop、clientLeft
    * offsetWidth、offsetHeight、offsetTop、offsetLeft
    * scrollWidth、scrollHeight、scrollTop、scrollLeft
    * getComputedStyle()
    * getBoundingClientRect()
    * scrollTo()
    回流必定触发重绘,重绘不一定触发回流。重绘的开销较小,回流的代价较高。

3、防抖与节流

4、cookies、session、sessionStorage、localStorage

5、浏览器内核

服务端与网络

1、常见状态码

2、缓存

  • 200 From cache和200 ok
  • 400,401,403状态码分别代表什么
  • 浏览器缓存

3、cookie, session, token

4、前端持久化的方式、区别

5、DNS是怎么解析的

6、cdn

7、计算机网络的相关协议

8、http/https/http2.0

9、get post区别

10、ajax、 axios库

11、tcp三次握手,四次挥手流程

12、跨域

13、前端安全XSS、CSRF

14、websocket

15、Http请求中的keep-alive有了解吗

16、网络分层

17、即时通信,除了Ajax和websocket

18、模块化,commonJS,es6,cmd,amd

框架(Vue)

1、vue解决了什么问题

2、MVVM的理解

3、如何实现一个自定义组件,不同组件之间如何通信的?

4、nextTick

5、生命周期

6、虚拟dom的原理

7、双向绑定的原理?数据劫持?

8、组件通信

  • 父->子
  • 子->父
  • 非父子组件

9、Proxy 相比于 defineProperty 的优势

10、watch computed区别

11、virtual dom 原理实现

12、vue-router(hash, HTML5 新增的 pushState

  • 单页应用,如何实现其路由功能—路由原理
  • vue-router如何做用户登录权限等
  • 你在项目中怎么实现路由的嵌套

13、vuex的理解

性能优化

  • 页面DOM节点太多,会出现什么问题?如何优化?
  • 如何做性能监测

SEO和语义化

微信小程序和h5差异,如果有开发weex的经验,可能会加上weex

微信小程序

微信小程序和h5差异,如果有开发weex的经验,可能会加上weex

Git

一些基本命令

打包工具webpack

1、打包原理

2、打包插件

3、webpack热更新原理

4、优化构建速度

算法与数据结构

1、排序算法

2、动态规划,参见背包问题

3、二叉树

4、加油站问题(贪心算法)

5、二分法

6、二叉树遍历

7、单链表反转

8、取1000个数字里面的质数

9、找出数组中和为给定值的两个元素,如:[1, 2, 3, 4, 5]中找出和为6的两个元素。

10、线性顺序存储结构和链式存储结构有什么区别?以及优缺点

移动端

1、自适应

2、pwa

3、移动端手势

附加题

1、无限滚动方案

2、如何处理兼容性问题

3、你遇到过最难的问题是什么

4、ES6 class与ES5 function区别及联系

5、vue怎么监听数组

6、写过webpack loader吗

7、微信网页版登录机制思考

  • 标题: 前端的自我修养
  • 作者: JiangWen
  • 创建于: 2023-03-06 18:50:24
  • 更新于: 2023-06-18 15:54:09
  • 链接: https://blog.jiangwen.site/2023/03/06/开发学习/前端的自我修养/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论