比较新的面试题
全局字体
1 | body { |
使用css实现一个持续的动画效果
1 | @keyframes mymove { |
水平垂直居中
1 | 1. |
多行文本溢出展示
1 | p { |
1.跨域解决方案
同源策略: 协议+域名+端口 防止XSS、CSFR等攻击 => httpOnly
跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
跨域解决方案
通过jsonp跨域 => 动态创建script jsonp缺点:只能实现get一种请求
document.domain + iframe跨域
location.hash + iframe
window.name + iframe跨域
postMessage跨域
跨域资源共享(CORS) 服务端设置Access-Control-Allow-Origin
nginx代理跨域
nodejs中间件代理跨域
WebSocket协议跨域
2.输入URL到页面加载显示完成,这个过程中都发生了什么?
url 浏览器缓存 > 本地域名解析 > 本地服务器DNS > 远程DNS服务器 跨域处理 (查询服务器地址) 可能 负载均衡
CDN处理请求
建立TCP/IP连接 ssl同信 握手 数据传输
页面加载html css js image
渲染 Dom Cssom Rendom树
3.浏览器内核:主要分成两部分:渲染引擎 和 jS引擎
4.编程范式: 面向过程 面向对象 函数式编程
5.
原型与原型链: Object.prototype的属性和方法 所有的引用类型(包括数组,对象,函数)都有隐性原型属性(proto),值也是一个普通的对象
作用域及闭包
异步和单线程
import、require、export、module.exports
关键在于 webpack_require 函数,这个函数就是 require 或者是 import 的替代
babel 在模块化的场景中充当了什么角色?以及 webpack ?哪个启到了关键作用?
babel 能提前将 es6 的 import 等模块关键字转换成 commonjs 的规范。这样 webpack 就无需再做处理,直接使用 webpack 运行时定义的 webpack_require 处理。
为何有的地方使用 require 去引用一个模块时需要加上 default? require(‘xx’).default
babel 对导出模块的转换,es6 的 export default 都会被转换成 exports.default,即使这个模块只有这一个输出
各大 UI 组件库时都会被介绍到为了避免引入全部文件,请使用 babel-plugin-component 等babel 插件
import { Button, Select } from ‘element-ui’
commonjs / commonjs2
exports[‘spon-ui’] => module.exports
面试流程题
1 | <p> |
媒体查询引入
1 | html |
阐述一下CSS Sprites: background-image background- repeat background-position
console类型:
1 | console.log('文字信息'); console.info('提示信息'); console.warn('警告信息'); console.error('错误信息'); |
vue 如何解析模板?
第一步是将非结构化的模板字符串,转变成结构化的 JS 对象,抽象语法树,即 AST 。
第二步,将 AST 转换成一个 render 函数,步骤是先转换为一段函数体的字符串,然后再用new Function(…)生成函数。
第三部,渲染时执行 render 函数,返回虚拟 DOM 对象,然后执行虚拟 DOM 的patch方法,渲染成真正的 html 。
vue内部渲染机制
React 的 setState 为何是异步渲染?
为了防止一次性执行多次setState而带来的渲染性能问题。
hybrid 和 h5 有何区别?
hybrid 是通过file协议加载的本地文件,h5是通过http协议加载的网络文件,前者速度快
hybrid 是通过为不同版本打包进行更新,而 h5 没有版本的概念,每次都获取服务端的最新版
hybrid 更加依赖于客户端的能力,因此会更多的和客户端通讯,而 h5 基本用不到和客户端通讯
:伪类 ::伪元素
伪类: 用于选择DOM树之外的信息,或是不能用简单选择器进行表示的信息。前者包含那些匹配指定状态的元素,比如:visited,:active;后者包含那些满足一定逻辑条件的DOM树中的元素,比如:first-child,:first-of-type,:target
伪元素: 为DOM树没有定义的虚拟元素。不同于其他选择器,它不以元素为最小选择单元,它选择的是元素指定内容
1 | console.log(typeof NaN === "number"); // "true" |
原生ajax
1 | var xhr = new XMLHttpRequest() |
Nodejs后台示例 (解决跨域)
1 | var http = require('http') |
封装一个函数,参数是定时器的时间,.then执行回调函数
1 | function sleep(time) { |
事件委托
1 | var oUl = document.getElementById('test'); |
Set 和 Map 数据结构
Set 它类似于数组 值都是唯一的
Map 类似于对象,也是键值对的集合
快速的让一个数组乱序
1 | var arr = [1,2,3,4,5,6,7,8,9] |
冒泡排序
1 | function sort(arr) { |
二分法查找
二分法查找算法:
采用二分法查找时,数据需是排好序的。
主要思想是:(设查找的数组区间为array[s, e])
(1)确定该区间的中间位置m
(2)将查找的值T与array[m]比较,若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。
区域确定如下:
这里设array从小到大排列,
array[m]>T由数组的有序性可知array[m,……,e]>T;
故新的区间为array[s,……,m-1],
类似上面查找区间array[s,……,m-1]。
每一次查找与中间值比较,判断是否查找成功,不成功当前查找区间缩小一半,循环查找,即可。
时间复杂度:O(log2n)。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
32let arr = [0, 1, 2, 4, 5, 6, 7, 8];
let arr2 = [88, 77, 66, 55, 44, 33, 22, 11];
BinarySearch(arr2, 77);
BinarySearch(arr, 2);
function BinarySearch(arr, target) {
let s = 0;
let e = arr.length - 1;
let m = Math.floor((s + e) / 2);
let sortTag = arr[s] <= arr[e];//确定排序顺序
while (s < e && arr[m] !== target) {
if (arr[m] > target) {
sortTag && (e = m - 1);
!sortTag && (s = m + 1);
} else {
!sortTag && (e = m - 1);
sortTag && (s = m + 1);
}
m = Math.floor((s + e) / 2);
}
if (arr[m] == target) {
console.log('找到了,位置%s', m);
return m;
} else {
console.log('没找到');
return -1;
}
}
解释同步\异步、阻塞\非阻塞、并行\并发之间的区别
同步:在发出一个同步调用时,在没有得到结果之前,该调用就不返回。
异步:在发出一个异步调用后,调用者不会立刻得到结果
阻塞这个词来自操作系统的线程/进程的状态模型中。经历的5个状态,创建,就绪,运行,阻塞/终止。
并行:运算中的两件或更多件事情在同一时刻发生
并发:至少两件事务在同一时间段发生