[关闭]
@anoninz 2020-01-16T07:33:27.000000Z 字数 16658 阅读 663

云天常见问题 -- 面试部分



自我介绍

遇到问题的案例:

技术相关的:

离职原因

稳定性问题

技术层面

蘑菇街在做的项目

职业规划

更多问题

Q 想了解一下这个岗位的发展如何
Q 公司的培训体系如何

未解决

// 原型链的构建
// REST(Representational State Transfer) 可重新表达的状态迁移
// RESTful API
// 六个具体约束:
// 1. 通信只能由客户端发后面发起,表现为请求-相应的形式
// 2. 无状态: 通信的会话状态应该有客户端负责维护
// 3. 缓存:相应内容可以在通信链的某处被缓存,以改善网络效率
// 4. 统一接口:通信连的组件之间通过统一的接口相互通信,以提高交互的可见性
// 5. 分层系统:通过限制组件的行为(即每个组件只能看到与其交互的相邻层),将架构分解为若干等级的层
// 6. 按需代码:支持通过下载并执行一些代码,对客户端的功能进行扩展

HTML5 部分

HTML语义化

浏览器内部,不同页面数据通信

localStorage、sessionStorage、cookies 的区别

localStorage 本地存储,长期存在,大小一般为 10Mb,同源策略,因此可以用来跨页面交互数据
sessionStorage 同上,但关闭浏览器就会消失

  1. Storage.length // 返回一个整数,数据项数量
  1. Storage.setItem(key, value) // 储存 / 更新
  2. Storage.getItem(key) // 读取
  3. Storage.removeItem(key) // 删除
  4. Storage.clear() // 清空

cookies

  1. document.cookie = "yummy_cookie=choco"
  2. document.cookie = "tasty_cookie=strawberry"
  3. console.log(document.cookie)

FormData 表单对象

  1. var formData = new FormData(form)
  2. formData.append('username', 'Chris');
  3. // 在 html 中 name 是必须的
  4. <form id="myForm" name="myForm">
  5. <div>
  6. <label for="username">Enter name:</label>
  7. <input type="text" id="username" name="username">
  8. </div>
  9. <div>
  10. <label for="useracc">Enter account number:</label>
  11. <input type="text" id="useracc" name="useracc">
  12. </div>
  13. <div>
  14. <label for="userfile">Upload file:</label>
  15. <input type="file" id="userfile" name="userfile">
  16. </div>
  17. <input type="submit" value="Submit!">
  18. </form>
  19. var myForm = document.getElementById('myForm')
  20. formData = new FormData(myForm)

File API 预览图片使用

  1. File.lastModified // 最后修改时间
  2. File.lastModifiedDate // 最后修改时间的 Date 对象
  3. File.name // File 引用文件的名字
  4. File.size // 文件大小
  5. File.path // path 或者 Url
  6. File.type // 文件扩展类型

CSS 部分

px rem em 的区别

选择器优先级 权重

css 的实现原理 stacking block ?

在层叠上下文中,其子元素同样也按照上面解释的规则进行层叠。特别值得一提的是,其子元素的 z-index 值只在父级层叠上下文中有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。

总结:

float 略

position 略

display 略

两栏布局

  1. <div style="float:left;width:200px;"></div>
  2. <div style="margin-left: 200px;"></div>

三栏布局

  1. <div style="float:left;width:200px;"></div>
  2. <div style="float:right;width:200px;"></div>
  3. <div style="margin-left: 200px;margin-right: 200px;"></div>

水平居中

  1. son {
  2. width: 200px;
  3. margin: 0 auto;
  4. }
  1. father {
  2. display:table-cell;
  3. text-align:center;
  4. vertical-align:middle;
  5. }
  6. son {
  7. display: inline-block;
  8. vertical-align: middle;
  9. }
  1. father {
  2. display: flex;
  3. justity-content: center;
  4. }
  1. father {
  2. position: relative
  3. }
  4. son {
  5. position: absolute
  6. left: 50%;
  7. trnasform: translateX(-50%;)
  8. }

垂直居中

  1. div {
  2. line-height: 30px;
  3. height: 30px;
  4. }

讲一下浮动吧?和 absolute 的区别?

清除浮动有哪些方法?

margin 合并

- 相邻的两个块级元素,间距是两者 margin 的最大值
- 父子两个块级元素: 若第一个子元素的 top 上没有 border padding ,上方没有 inlineBlock  清除浮动的话,那么父子两元素的 margin 将合并,取两者的max

box-sizing 盒模型

- 标准 content-box width 只是 content 部分
- 怪异 border-box width 包含 margin+padding+border+content 部分

CSS3 动画

  1. div {
  2. transition: 1s 1s height ease, 1s 1s width ease;
  3. }
  4. // 可以通过增减 class 设置 transform 效果
  5. // 持续时间 延迟时间 方向/属性 弹性效果
  6. div {
  7. animation: 1s 1s rainbow linear 3 forwards normal;
  8. }
  9. // 持续时间 延迟时间 动画名称 时间线性弹性 循环次数(infinite) 播放方向
  10. @keyframes rainbow {
  11. 0% { background: #c00; }
  12. 50% { background: orange; }
  13. 100% { background: yellowgreen; }
  14. }

JS 部分

值类型与引用类型

  1. var a = {
  2. v: 1
  3. }
  4. var b = a
  5. console.log(b.v) // 1
  6. a.v = 2
  7. console.log(b.v) // 2
  8. a = {
  9. v: 3
  10. }
  11. console.log(b.v) // 2 b指向了 a 之前的对象,重置了 a,b 的指向没有变化

变量声明提升

  1. console.log(a) // undefined
  2. var a = 1
  3. // 相当于
  4. // var a
  5. // console.log(a)
  6. // a = 1
  1. console.log(b()) // 2 变量提升了
  2. function b() {
  3. return 2
  4. }
  1. console.log(c()) // c is not a function
  2. var c = function() {
  3. return 3
  4. }
  5. // 相当于
  6. // var c
  7. // console.log(c())
  8. // c = function() {return 3}
  1. console.log(d)
  2. let d = 4

this

  1. var x = 0
  2. function test() {
  3. console.log(this.x)
  4. }
  5. var o = {}
  6. o.x = 1
  7. o.m = test
  8. o.m.apply() // 0 apply 需要指定一个 this,null 或者 undefined 则指向了 window 所以是 0
  9. o.m() // 1 谁调用,指向谁
  1. var foo = {
  2. bar: function() {
  3. return this.baz
  4. },
  5. baz: 1,
  6. }
  7. (function() {
  8. return typeof arguments[0]()
  9. })(foo.bar)

call, apply, bind 的区别

  1. const log = console.log.bind(console)

简单的构造函数

  1. function Foo() {
  2. this.name = 'a'
  3. }
  4. var f1 = new Foo()
  5. f1.name = 'b'
  6. console.log(f1.name) // 'b'
  7. var f2 = new Foo()
  8. console.log(f2.name) // 'a'

原型链 prototype

继承时,JavaScript 只有一种结构:对象。每个对象都有一个私有属性(称之为 [[Prototype]]),它持有一个连接到另一个称为其 prototype 对象(原型对象)的链接。该 prototype 对象又具有一个自己的原型,层层向上直到一个对象的原型为 null。(译者注:Object.getPrototypeOf(Object.prototype) === null; // true)根据定义,null 没有原型,并作为这个原型链中的最后一个环节。

  1. function Foo() {
  2. this.name = 'a'
  3. }
  4. Foo.prototype.logName = function() {
  5. console.log('name is', this.name)
  6. }
  7. var f1 = new Foo()
  8. f1.logName() // name is a 没有修改原型 Foo 的 name
  9. var f2 = new Foo()
  10. f2.logName = function() {
  11. console.log('name')
  12. }
  13. f2.logName() // name 覆盖了 原型链上的 logName() 函数
  14. var f3 = new Foo()
  15. f3.name = 'c'
  16. f3.logName() // name is c 只覆盖了 Foo 上的 name

arguments 函数隐含的参数,是所有参数构成的一个类数组

  1. (function() {
  2. return typeof arguments
  3. })()

setTimeout 和 setInterval 两者的区别

  1. for (var i = 0; i < 5; i++) {
  2. setTimeout(function() {
  3. console.log(new Date(), i)
  4. }, 1000)
  5. }
  6. console.log(new Date(), i)
  7. // 00:00:00 5
  8. // 00:00:01 5
  9. // 00:00:01 5
  10. // 00:00:01 5
  11. // 00:00:01 5
  12. // 00:00:01 5

事件捕获, 事件冒泡, 事件委托

// 讲清楚这三个概念
addEventListener(event, callback, useCapture)

闭包

  1. var bibao = function() {
  2. var i = 0
  3. var addI = function() {
  4. i++
  5. return i
  6. }
  7. return addI
  8. }
  9. var a = bibao() // 这个 a 就是闭包
  10. // 改写一下
  11. var a = (function() {
  12. var i = 0
  13. return function() {
  14. i++
  15. return i
  16. }
  17. })()

浅拷贝 clone 和深拷贝 deepClone

  1. // 实现 deepClone 函数,JSON
  2. JSON.parse(JSON.stringify(obj)) // 一般业务数据够用了
  3. // 或者用 jQuery
  4. var newObject = jQuery.extend(true, {}, oldObject);
  5. //lodash 的
  6. _.clone(true, obj)
  7. // 浅复制数组
  8. var a = b.slice()
  9. var a = b.concat([])

实现原生的 ajax 函数

  1. var ajax = function(method, path, data, responseCallback) {
  2. var r = new XMLHttpRequest()
  3. // 设置请求方法和请求地址
  4. r.open(method, path, true)
  5. // 设置发送的数据的格式
  6. r.setRequestHeader('Content-Type', 'application/json')
  7. // 注册响应函数
  8. r.onreadystatechange = function() {
  9. if(r.readyState === 4) {
  10. responseCallback(r)
  11. }
  12. }
  13. // 发送请求
  14. r.send(data)
  15. }
  16. // 0 1 2 3 4 各代表什么含义
  17. // 0 代理被创建,但并未 open()
  18. // 1 已经调用 open()
  19. // 2 已经调用 send() 并且头部和状态已经获得了
  20. // 3 正在下载
  21. // 4 下载完成

HTTP 请求方法, 常见状态码, 头部常见字段

跨域(jsonp, postMessage, cors, 用服务器(比如 node)转发请求和响应)

DOM 操作(查找, 添加, 删除, 修改)

// DOM 查找/添加/删除/修改对应的 API 是什么

  1. // 新建
  2. document.createElement('div') // 创建节点
  3. document.createTextNode('我是新增的文本节点') // 创建文本节点
  4. document.querySelector('#div1').cloneNode(true) // true 深度克隆一个节点
  5. // 修改
  6. parent.appendChild(child) // 在 parent 最后位置插入 child
  7. a.insertBefore(b,c) // 在 a 的 c 元素之前插入 b,若 c 不存在会插入在最后
  8. a.insertAdjacentHTML('beforebegin', b) // 在 a 的第一个子元素之前加入 afterbegin beforeend afterend
  9. // 删除
  10. a.removeChild(b) 删除 a 中的 b 并返回 b 这个 dom
  11. parent.replaceChild(newNode,oldNode)
  12. // 设置
  13. a.setAttribute(prop, value) a 元素的 prop 元素设值 value
  14. a.innerHTML 获取/设置 dom
  15. a.innerText 获取文本
  16. a.value 获取/设置 input/select 的值
  17. // 查找
  18. document.querySelector('.test')
  19. document.querySelectorAll('.test')[0]
  20. element.childNodes // 子节点
  21. element.parentNode // 子节点
  22. ele.previousElementSibling 前一个节点
  23. ele.nextElementSibling 后一个节点
  24. closet(query) 可以用递归实现
  25. // 监听事件
  26. addEventListener('type', 函数名称, true/false) // 事件类型 回调函数 是否有捕获
  27. removeEventListener('type', 函数名称)

jQuery 常见 Apihttp://www.jianshu.com/p/8a26e66254ed

数据结构

Array 数组 [1,2,3,4]

  1. Array.length // 数组长度
  2. Array.prototype //数组原型
  1. Array.from(a) // 从类数组或迭代对象中创建一个新的数组实例
  2. Array.isArray(a) // 判断 a 是否是数组
  3. // 改变原数组的方法
  4. arr.push(b) // 尾部增加 b,并返回新数组长度
  5. arr.pop() // 尾部删除并返回删除的元素
  6. arr.unshift(b,c) // 头部增加 b,c 并返回新 length
  7. arr.shift() // 删除第一个元素,并返回该元素
  8. arr.reverse() // 数组倒序排列
  9. arr.sort((a,b)=>{return Number} //按照比较两个元素,最后根据返回值排序
  10. //返回值 <0 a,b >0 b,a =0 保持原顺序
  11. arr.splice(index, num, a,b,c) // 在 index 位置开始删除 num 个元素,并用后续参数代替
  12. // 不改变原数组,但返回值为期望值
  13. arr1.concat(arr2) // 返回 arr1 后续 arr2 的数组
  14. arr.inculudes(b) // 返回布尔值,arr是否包含 b 元素
  15. arr.join(str=',') // 返回一个用 str 分隔开的 字符串
  16. arr.slice(index1, index2) // 返回 arr 从 index1 开始,到 index2 前一个元素的数组
  17. arr.indexof(b) // 返回第一个等于 b 的元素的 index,若不含有则返回 -1
  18. arr.lastIndexof(b) // 返回倒数第一个等于 b 的元素的 index,不含有则返回 -1
  19. // 遍历方法
  20. arr.forEach((item, index)=> {
  21. console.log(item, index)
  22. }) // 为arr 的每个元素执行一次函数,改变原数组
  23. arr.map((item, index)=>{
  24. return
  25. }) // 返回每个回调函数的返回值组成的数组
  26. arr.every((item)=>{
  27. return Boolean
  28. }) // 函数遍历每个元素返回值为 true,返回 true 否则 false
  29. arr.some((item)=>{
  30. return Boolean
  31. }) // 函数遍历每个元素,返回值有一个 true ,则返回 true 否则 false
  32. arr.find((item)=>{
  33. return Boolean
  34. }) // 函数遍历每个元素,返回值为 true 的元素,会被返回,否则 undefined
  35. arr.findIndex((item)=>{
  36. return Boolean
  37. }) // 函数遍历每个元素,返回值为 true 的元素的 index 会被返回,否则 -1
var arr2 = arr1.slice() // 浅复制一个数组
  1. // 有这样一个 url: http://vip.qq.com/a.php?a=1&b=2&c=3&d=xxx&e
  2. // 写一段 JS 程序将 url 的参数转成对象的形式
  3. {
  4. a: 1,
  5. b: 2,
  6. c: 3,
  7. d: 'xxx',
  8. e: '',
  9. }

ES6

  1. var test = function(a,b, ...args) {
  2. // 参数 a b 可以直接用
  3. // args = [c,d,e ……]
  4. // 一个真实的数组
  5. }
  1. promise
  2. .then((res)=>{})
  3. .catch((err)=>{})
  4. .done()
  5. .finally()
  6. // Promise.all() 将多个 Promise 实例打包成新的 Promise,当所有都resolved 才回 resolved
  7. // 有一个 Promise 变成 rejected 则会变成 rejected
  8. var p1 = new Promise
  9. var p2 = new Promise
  10. var p = Promise.all([p1,p2])
  11. // Promise.race([p1,p2,p3]) 返回值是第一个发生改变的 promise 的返回值
  12. // Promise.resolve(res) 返回一个返回值是 res,且 resolved 的 Promise 实例
  13. // Promise.reject() 返回一个 reject 的 Promise 实例
  14. // 一个实际面试题,不过谁这么写代码我抽谁
  15. // 判断输出结果
  16. const a = (time) => {
  17. return new Promise((resolve, reject) => {
  18. setTimeout(() => {
  19. resolve('hhh')
  20. }, time)
  21. setTimeout(() => {
  22. reject('gua')
  23. }, 1000)
  24. })
  25. }
  26. a(500)
  27. .then((res) => {
  28. console.log(res)
  29. }, (err) => {
  30. console.log(err)
  31. })
  32. .then((res) => {
  33. console.log(res, 2)
  34. }, (err) => {
  35. console.log(err, 2)
  36. })
  37. .catch((res) => {
  38. console.log('catch', res)
  39. })
  40. // 两个 then 会先后执行,第一个 then 可以拿到 res,第二个 then 拿不到
  41. // 因为没有抛出的错误,所以 catch 拿不到任何信息
  42. a(1200)
  43. .then((res) => {
  44. console.log('resolved 1200', res)
  45. }, (err) => {
  46. console.error('rejected 1200', err)
  47. })
  48. .then((res) => {
  49. console.log('res2', res)
  50. }, (err) => {
  51. console.log('err2', err)
  52. })
  53. .catch((res) => {
  54. console.log('catch2', res)
  55. })
  56. // promise 变成rejected,执行第一个rejected 1200
  57. // 然后第二个 then 会执行resolved 函数,但是拿不到 res
  58. // 没有抛出错误,所以 catch 不执行
  59. // rejected 1200 gua
  60. // res2 undefined
  61. a(2000)
  62. .catch((res) => {
  63. console.log('catch2000, 1', res)
  64. })
  65. .catch((res) => {
  66. console.log('catch2000, 2', res)
  67. })
  68. // 第一个 catch 接住了抛出的错误,所以第二个没有得到
  69. // catch2000 1 gua
  70. a(3000)
  71. .catch((res) => {
  72. console.log('catch3000', res)
  73. })
  74. .then((res) => {
  75. console.log('then 3000', res)
  76. })
  77. // 第一个 catch 接住了 错误(默认返回了一个resolved promise),然后 then 可以继续接

构造函数

  1. function Person(a,b,c) {
  2. this.a = a
  3. this.b = b
  4. this.c = c
  5. this.friends = [1,2,3]
  6. }
  7. Person.prototype = {
  8. constructor: Person,
  9. sayName: function() {
  10. console.log(this.a)
  11. },
  12. }
  1. function Man(a,b,c,d) {
  2. Person.call(this, a, b, c)
  3. this.d = d
  4. }
  5. Man.prototype = new Person()
  6. Man.constructor = Man
  7. Man.prototype.logD = function() {
  8. console.log(this.d)
  9. }

class

  1. // 定义类
  2. class Point {
  3. // 构造函数
  4. constructor(x, y) {
  5. this.x = x;
  6. this.y = y;
  7. }
  8. get prop() { // Point.prop 的 getter 函数,调用时返回值
  9. // do something
  10. return 'hahaha'
  11. }
  12. set prop(value) { // Point.prop 的 setter 函数,在赋值的同时执行
  13. console.log('设置 prop 为' + value)
  14. }
  15. static method1() {
  16. // 一个静态方法,不会被实例获取的,但是会被子类继承调用
  17. console.log('静态函数 method1,可被类调用,不可被实例调用')
  18. }
  19. method2() {
  20. console.log('这里是 method 2,可被实例调用,可被子类继承')
  21. return '(' + this.x + ', ' + this.y + ')';
  22. }
  23. }
  24. // 继承类
  25. class ColorPoint extends Point {
  26. constructor(x, y, color) {
  27. super(x, y) // 调用父类的constructor(x, y)
  28. this.color = color
  29. }
  30. method3() {
  31. return this.color + ' ' + super.method2(); // 调用父类的toString()
  32. }
  33. }

ES6 模块中 export 与 export default 的区别

  1. exportexport default 均可用于导出常量、函数、文件、模块等
  2. 你可以在其它文件或模块中通过import a from '/path/b'的方式,将其导入,以便能够对其进行使用
  3. 在一个文件或模块中,exportimport可以有多个,export default仅有一个
  4. 通过export方式导出,在导入时要加{ }export default则不需要
  1. import defaultExport from "module-name" // export default
  2. import "module-name" // export default
  3. import * as name from "module-name" // export,引用时 name.a
  4. import { a as alias } from "module-name"; //export
  5. // alias 别名

Set Map

从输入 url 到页面加载的过程

https://zhuanlan.zhihu.com/p/23155051

其他

同源策略限制

从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
- 不同端口 不同协议(http https) 不同域名

#

如何检测audio video 的播放状况?

监听媒体元素的事件 onplay onpause onended 等等

AMD CMD 区别

amd 是 requireJS 推广时的定义模块规范,提前执行
cmd 是 seaJS 推广时的定义模块规范,延迟执行

webpack 模块打包器

yarn 和 npm 有什么本质区别

- yarn 并发安装,安全可靠,非常快 yarn.lock
- npm 允许安装 packages 时执行代码
- yarn 并非想要完全取代 npm ,它只是一个新的 CLI 工具,拉取的 packages 依然来自 npm。
- 都是通过 package.json 记录项目需要拉取的依赖文件。

前端优化: 雅虎 35 条军规

- 内容  
    - 减少 http 请求次数
    - 减少 DNS 查询
    - 减少重定向次数
    - ajax 可以缓存 Expires Cache Control Header 头
    - 首屏以外的组件延迟加载
    - 猜测用户的使用倾向,预加载
    - 减少 html 的 dom 数量
    - 跨域分离组件, 可以多服务器并行
    - 杜绝 404
    - 少用 iframe
- CSS:
    - 样式表放在顶部
    - 引入 css 时使用 link 不用 import
    - 避免使用滤镜
- JS :
    - script 放在最后
    - 少操作 dom,避免重绘
    - 去除重复的 script
    - 多用事件委托
- 图片:
    - 压缩图片
    - 使用雪碧图 / base64
    - 不用 html css 设置图片的大小,而尽量使用原图的大小
- cookie:
    - 给 cookie 减肥
    - 把静态资源放在与 cookie 无关的域名下

React

Vue

小程序相关

1px 分割线怎么处理?

先设置 height:1px transform:scaleY(0.5)

小程序组件

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注