既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
音频video 视频 audio、画布canvas、H5存储localStorage sessionStorage
语义化标签 : header nav main article section aside footer
语义化意味着顾名思义,HTML5的语义化指的是合理正确的使用语义化的标签来创建页面结构 如 header,footer,nav,从标签上即可以直观的知道这个标签的作用,而不是滥用div。
语义化的优点有:
- 代码结构清晰,易于阅读,利于开发和维护
- 方便其他设备解析(如屏幕阅读器)根据语义渲染网页。
- 有利于搜索引擎优化(SEO)
7. css盒子模型
CSS 盒模型本质上是一个盒子,盒子包裹着HTML 元素,盒子由四个属性组成,从内到外分别是:content 内容、padding 内填充、border 边框、外边距 margin
两种盒模型的区别
标准盒模型:
width = content-width
height = content-height
怪异盒模型:
width = content-width + padding-width + border-width
height = content-height + padding-height + border-height
如何在CSS 设置这两个模型
标准盒模型:
box-sizing: content-box
怪异盒模型:
box-sizing: border-box
8.请描述一下 cookies sessionStorage和localstorage区别(常见)
**相同点:**都存储在客户端
**不同点:**1.存储大小
· cookie数据大小不能超过4k。
· sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。
2.有效时间
· localStorage 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
· sessionStorage 数据在当前浏览器窗口关闭后自动删除。
· cookie 设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭
- 数据与服务器之间的交互方式
· cookie的数据会自动的传递到服务器,服务器端也可以写cookie到客户端
· sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。
9. 优先级
!important > 内联 > ID 选择器 > 类选择器 > 标签选择器。
- 每个选择器都有权值,权值越大越优先
- 继承的样式优先级低于自身指定样式
- 权值相同时,靠近元素的样式优先级高 顺序为内联样式表(标签内部)> 内部样式表(当前文件中)> 外部样式表(外部文件中)
10. BFC (会问到 概率也挺高–简单话术描述)
总结:BFC就是块级格式化上下文,让元素成为一个独立的空间 不受外界影响也不影响外面布局
BFC概念 也叫【块级格式化上下文】,简单来说,BFC 是一个完全独立的空间(布局环境),让空间里的子元素不会影响到外面的布局。
BFC是CSS布局的一个概念,是一个环境,里面的元素不会影响外面的元素。
BFC的布局规则
内部的Box会在垂直方向,一个接一个地放置。
Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠。
每个盒子(块盒与行盒)的margin box的左边,与包含块border box的左边相接触(对于从左往右的格式化,否则相反)。即使存在浮动也是如此。
BFC的区域不会与float box重叠。
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
计算BFC的高度时,浮动元素也参与计算
如何创建BFC
1、float的值不是none。
2、position的值不是static或者relative。
3、display的值是inline-block、table-cell、flex、table-caption或者inline-flex
4、overflow的值不是visible
BFC作用 (解决了什么问题)
- 阻止margin重叠
- 可以包含浮动元素 —— 清除内部浮动
- 自适应两栏布局
- 可以阻止元素被浮动元素覆盖
11. CSS3的新特性 (或者问介绍一下css3)
css3新特性 | 描述 |
box-shadow | 盒子阴影 |
border-radius | 圆角 |
box-sizing | 盒子模型 |
linear-gradient, radial-gradient | 渐变 |
transition | 过渡 |
animate | 动画 |
transform | 2D 转换/3D 转换 |
iconfont | 字体图标 |
flex | 弹性布局 |
12. var let const 的区别?(常见问题-最基本问题)
- const 定义常量, 不可以重复赋值 块级作用域 不存在变量提升
- var 定义变量,可以重复声明 var 全局作用域或函数作用域 有变量提升
- let 定义变量,不可以重复声明 , 块级作用域 不存在变量提升
13. javascript 有哪些基础数据类型?
- 基础数据类型String、Number、Boolean、Undefined、Null
- 引用数据类型: Object、Array、Function、Date等
- Symbol、BigInt是ES6之后新增的 属于基本数据类型
- Symbol
指的是独一无二的值
-
- BigInt
是一种数字类型的数据,它可以表示任意精度格式的整数
14. null和undefined区别
- 首先 Undefined 和 Null 都是基本数据类型,这两个基本数据类型分别都只有一个值,就是 undefined 和 null。
- undefined 代表的含义是
未定义,一般变量声明了但还没有定义的时候会返回 undefined
- null 代表的含义是
空对象。null主要用于赋值给一些可能会返回对象的变量,作为初始化。
15. == 与 === 的区别?
- 双等号(==)进行相等判断时,如果两边的类型不一致,会强制类型转化再进行比较。
- 三等号(===)进行相等判断时,如果两边的类型不一致,不强制类型准换,直接返回 false
16. js中那些数据在 if 判断时是 false
- 0、“”、false、null、undefined、NaN 判断为false (6个)
- 其他皆为true
注意:下面的判断结果
[]==false 和 ![]==false true
第一个 []false 转为数字 00
第二个 ![]false 转为布尔 falsefalse
[]==[] – >false
js中布尔值为false的六种情况
下面6种值转化为布尔值时为false,其他转化都为true
1、undefined(未定义,找不到值时出现)
2、null(代表空值)
3、false(布尔值的false,字符串"false"布尔值为true)
4、0(数字0,字符串"0"布尔值为true)
5、NaN(无法计算结果时出现,表示"非数值";但是typeof NaN===“number”)
6、“”(双引号)或’’(单引号) (空字符串,中间有空格时也是true)
注意空数组空对象,负值转的布尔值时都为true
17. 判断数据类型的方法有哪些,有什么区别 (常见)
判断数据类型的方法 | 描述 |
typeof | 判断基础数据类型(数组、对象、null都会被判断为object) |
instanceof | 判断引用数据类型,不能判断基本数据类型 |
constructor | 判断数据的类型 |
Object.prototype.toString.call() | 使用 Object 对象的原型方法 toString 来判断数据类型 |
JavaScript类型判断的四种方法
一、typeof
typeof是一个操作符而不是函数,其右侧跟一个一元表达式,并返回这个表达式的数据类型。
返回的结果用该类型的字符串(全小写字母)
用于判断数据类型,返回值为6个[字符串],分别为string、Boolean、number、function、object、undefined。
console.log(typeof undefined) // undefind
console.log(typeof null) // object
console.log(typeof true) // boolean
console.log(typeof 43) // number
console.log(typeof '21') // string
console.log(typeof {a:1}) // object
console.log(typeof Symbol()) // symbol
console.log(typeof 123n) // bigint
function a() {}
console.log(typeof a) // function
var date = new Date()
var error = new Error()
console.log(typeof date) // object
console.log(typeof error) // object
二、instanceof
instanceof 是用来判断 A 是否为 B 的实例,表达式为:A instanceof B,如果 A 是 B 的实例,则返回 true,否则返回 false。 在这里需要特别注意的是:instanceof 检测的是原型
instanceof用来判断对象,代码形式为obj1 instanceof obj2(obj1是否是obj2的实例),obj2必须为对象,否则会报错!其返回值为布尔值
通俗一些讲,instanceof 用来比较一个对象是否为某一个构造函数的实例。注意,instanceof可以准确的判断复杂数据类型,但是不能正确判断基本数据类型
console.log(12 instanceof Number) // false
console.log('22' instanceof String) // false
console.log(true instanceof Boolean) // false
console.log(null instanceof Object) // false
console.log(undefined instanceof Object) // false
console.log([] instanceof Array) // true
console.log({a: 1} instanceof Object) // true
console.log(json instanceof Object) // true
function a() {}
console.log(a instanceof Function) // true
console.log(new Date() instanceof Date) //true
console.log(reg instanceof RegExp) //true
console.log(error instanceof Error) // true
三、Object.prototype.toString.call()
toString() 是 Object 的原型方法,调用该方法,默认返回当前对象的 [[Class]] 。这是一个内部属性,其格式为 [object Xxx] ,其中 Xxx 就是对象的类型。
对于 Object 对象,直接调用 toString() 就能返回 [object Object] 。而对于其他对象,则需要通过 call / apply 来调用才能返回正确的类型信息。
console.log(Object.prototype.toString.call(1)) // [object Number]
console.log(Object.prototype.toString.call(1n)) // [object BigInt]
console.log(Object.prototype.toString.call('123')) // [object String]
console.log(Object.prototype.toString.call(true)) // [object Boolean]
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
console.log(Object.prototype.toString.call({})) // [object Object]
console.log(Object.prototype.toString.call([])) // [object Array]
console.log(Object.prototype.toString.call(function a() {})) // [object Function]
console.log(Object.prototype.toString.call(Symbol())) // [object Symbol]
console.log(Object.prototype.toString.call(Math)) // [object Math]
console.log(Object.prototype.toString.call(JSON)) // [object JSON]
console.log(Object.prototype.toString.call(new Date())) // [object Date]
console.log(Object.prototype.toString.call(new RegExp())) // [object RegExp]
console.log(Object.prototype.toString.call(new Error)) // [object Error]
console.log(Object.prototype.toString.call(window) // [object Window]
console.log(Object.prototype.toString.call(document) // [object HTMLD
四、constructor
constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。 constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,一般要同时修改constructor属性的指向。
constructor属性,可以得知某个实例对象,到底是哪一个构造函数产生的。
constructor属性表示原型对象与构造函数之间的关联关系,如果修改了原型对象,
一般会同时修改constructor属性,防止引用的时候出错。所以,修改原型对象时,
一般要同时修改constructor属性的指向。
console.log('22'.constructor === String) // true
console.log(true.constructor === Boolean) // true
console.log([].constructor === Array) // true
console.log(document.constructor === HTMLDocument) // true
console.log(window.constructor === Window) // true
console.log(new Number(22).constructor === Number) // true
console.log(new Function().constructor === Function) // true
console.log((new Date()).constructor === Date) // true
console.log(new RegExp().constructor === RegExp) // true
console.log(new Error().constructor === Error) // true
注意:
1、null 和 undefined 是无效的对象,因此是不会有 constructor 存在的,这两种类型的数据需要通过其他方式来判断。
2、函数的 constructor 是不稳定的,这个主要体现在自定义对象上,当开发者重写 prototype 后,原有的 constructor 引用会丢失,constructor 会默认为 Object
18. JS垃圾回收 (常见)
有两种垃圾回收策略:
- 标记清除:
标记阶段即为所有活动对象做上标记,清除阶段则把没有标记(也就是非活动对象)销毁。
- 引用计数:
它把对象是否不再需要简化定义为对象:有没有其他对象引用到它。如果没有引用指向该对象(引用计数为 0),对象将被垃圾回收机制回收。
19. 深拷贝、浅拷贝(笔试题)
【{},[]】
- 浅拷贝: 以赋值的形式拷贝引用对象,仍指向同一个地址,修改时原对象也会受到影响
- Object.assign
- 展开运算符 …
- 深拷贝: 完全拷贝一个新对象,修改时原对象不再受到任何影响
- JSON.parse(JSON.stringify(obj)): 性能最快
具有循环引用的对象时,报错
当值为函数、undefined、或symbol时,无法拷贝
-
递归进行逐一赋值
-
lodash工具库:cloneDeep
深拷贝:
arr=[100, [{a : 'hello'}, {b : "world"}], { c: "123456789" }];
//判断修改的是不是'object'或者null,如果不是 object 或者 null 那么直接返回
function deepClone(obj = {}) {
if (typeof obj !== 'object' || obj == null) {
return obj;
}
let result;
//判断上面下来的obj是不是数组 用instanceof来检测 因为是数组应用类型
obj instanceof Array?result=[]:result={}
for (var item in obj) {
//查找一个对象是否有某个属性
if (obj.hasOwnProperty(item)) {
// 递归调用
result[item] = deepClone(obj[item])
}
}
return result;
}
let arr1=deepClone(arr);
arr1[1][0].a='vue'
arr1[0]=99
console.log('原数组',arr)
console.log('新数组',arr1)
20. 数组的方法
数组的方法 | 描述 |
map | 遍历数组,返回回调返回值组成的新数组 |
forEach | 无法break,可以用try/catch中throw new Error来停止 |
filter | 过滤 |
some | 有一项返回true,则整体为`true |
every | 有一项返回false,则整体为`false |
join | 通过指定连接符生成字符串 |
push / pop | 末尾推入和弹出,改变原数组。push 返回数组长度, pop 返回原数组最后一项; |
unshift / shift | 头部推入和弹出,改变原数组,unshift 返回数组长度,shift 返回原数组第一项 ; |
sort(fn) / reverse | 排序与反转,改变原数组 |
concat | 连接数组,不影响原数组, 浅拷贝 |
slice(start, end) | 返回截断后的新数组,不改变原数组 |
splice(start, number, value…) | 返回删除元素组成的数组,value 为插入项,改变原数组 |
indexOf / lastIndexOf(value, fromIndex) | 查找数组项,返回对应的下标 |
reduce / reduceRight(fn(prev, cur), defaultPrev) | 两两执行,prev 为上次化简函数的return值,cur 为当前值 当传入 defaultPrev 时,从第一项开始; 当未传入时,则为第二项 |
21. js数组去重,能用几种方法实现?(笔记题)
- 使用es6 set方法
[…new Set(arr)]
let arr = [1,2,3,4,3,2,3,4,6,7,6]; let unique =(arr)=>[…newSet(arr); unique(arr);//[1,2,3,4,6,7]
-
利用新数组indexOf查找indexOf()方法可返回某个指定的元素在数组中首次出现的位置。如果没有就返回-1。
-
for双重循环通过判断第二层循环,去重的数组中是否含有该元素,如果有就退出第二层循环,如果没有j==result.length就相等,然后把对应的元素添加到最后的数组里面。
22. 作用域、作用域链
作用域:变量和函数起作用的范围。
作用域链:是js查找方式,决定的变量和函数向上查找的范围。
- 作用域是可访问的变量的
集合。在JavaScript中,作用域为可访问变量,对象,函数的集合,它分为局部作用域和全局作用域。作用域决定了这些变量的可访问性(可见性)。
作用域链
- 我们可以在执行上下文中访问到父级甚至全局的变量,这便是作用域链的功劳。作用域链可以理解为一组对象列表,包含
父级和自身的变量对象,因此我们便能通过作用域链访问到父级里声明的变量或者函数。
-
- 它由两部分组成:
- [[scope]]属性: 指向父级变量对象和作用域链,也就是包含了父级的[[scope]]和AO
- AO: 自身活动对象
- 它由两部分组成:
- 如此 [[scope]]包含[[scope]],便自上而下形成一条 链式作用域。
23. 构造函数、实例
- 构造函数:可以通过
new来 新建一个对象 的函数
- 实例: 通过构造函数和
new创建出来的对象,便是实例。 实例通过__proto__指向原型,通过constructor指向构造函数。
24. 原型、原型链? (常问)
1.原型: 对象中固有的__proto__属性,该属性指向对象的prototype原型属性。
原型链: 当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么它就会去它的原型对象里找这个属性,这个原型对象又会有自己的原型,于是就这样一直找下去,也就是原型链的概念。原型链的尽头一般来说都是Object.prototype所以这就是我们新建的对象为什么能够使用toString()等方法的原因
原型:
- 一个简单的对象,用于实现对象的属性继承。
- 每个JavaScript对象中都包含一个__proto__的属性指向该对象的原型,可obj.__proto__进行访问。
原型链
- 原型链是由原型对象组成,每个对象都有 __proto__ 属性,(该属性指向对象的prototype原型属性)指向了创建该对象的构造函数的原型,__proto__ 将对象连接起来组成了原型链。是一个用来实现继承和共享属性的有限的对象链。
25. this指向 (常问–用话术藐视出来才可以噢-加油)
this的指向主要有下面几种:
1、this出现在全局函数中,永远指向window
2、this出现在严格模式中 永远不会指向window
3、当某个函数为对象的一个属性时,在这个函数内部this指向这个对象
4、this出现在构造函数中,指向构造函数实例
5、当一个元素被绑定事件处理函数时,this指向被点击的这个元素
6、this出现在箭头函数中时,this和父级作用域的this指向相同
26. call、apply、bind
三者区别
- 三者都可以改变函数的this对象指向
- 三者第一个参数都是this要指向的对象,如果没有这个参数或参数为undefined或null,则默认指向全局window
- 三者都可以传参,
- call是参数列表,apply是数组,call和apply是一次性传入参数,
- bind是参数列表,但可以分为多次传入参数
- bind是返回绑定this之后的函数,apply、call 则是立即执行
应用场景
- call 经常做继承。
- apply 经常跟数组有关系,比如借助于数学对象实现数组最大值最小值。
- bind 不调用函数,但是还想改变this指向,比如改变定时器内部的this指向。
27. 闭包、闭包的使用场景
闭包的概念:
闭包:是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性
1.函数内再嵌套函数 2.内部函数可以引用外层的参数和变量 3.参数和变量不会被垃圾回收机制回收
闭包的优缺点
- 优点:延长变量生命周期、私有化变量
- 缺点:过多的闭包可能会导致内存泄漏
闭包的应用场景
- ajax请求的成功回调
- 事件绑定的回调方法
- setTimeout的延时回调
- 函数内部返回另一个匿名函数
- 函数节流、防抖 封装模块
28. 箭头函数和普通函数的区别
- 箭头函数比普通函数更加简洁
- 箭头函数没有自己的this
- 箭头函数继承来的this指向永远不会改变
- 箭头函数不能作为构造函数使用
- 箭头函数没有自己的arguments
- 箭头函数没有prototype
- call()、apply()、bind()等方法不能改变箭头函数中this的指向
29. forEach和map方法有什么区别
- forEach()方法会针对每一个元素执行提供的函数,对数据的操作会改变原数组,该方法没有返回值;
- map()方法不会改变原数组的值,返回一个新数组,新数组中的值为原数组调用函数处理之后的值;
注意:
- forEach()会改变原数组的方法
- 参数:item数组中的当前项,index当前项的索引,array原始数组;
- 数组中有几项,那么传递进去的匿名回调函数就需要执行几次
使用场景:当我们对数组的元素进行处理时(例如:增加元素,元素值改变),可以使用这个函数
注意:
item数组中的当前项,index当前项的索引,array原始数组
map的回调函数中支持return返回值,return的是啥,相当于把数组中的这一项变为啥(并不影响原来的数组,只是相当于把原数组克隆了一份,把克隆这一份的数组中的对应项改变了 );
map会改变原数组的方法,
map的执行速度更快,比forEach的执行速度快了70%;
使用场景:
map适用于你要改变数据值的时候,不仅在于它更快,而且返回一个新的数组,这样可以提高复用性(map(),filter(),reduce())等组合使用。
var arr = [1, 2, 3, 4, 5];
var newArr = arr.map(num => num * 2).filter(num => num > 5);
// newArr = [6, 8, 10]
总结:
- 能用forEach()做到的,map()同样可以。反之亦成立
- map()会分配内存空间存储新数组并返回,forEach()不会返回数组
- forEach()允许callback更改原始数组的元素。而map()返回新的数组
30. promise理解、手写promise
- Promise是异步编程的一种解决方案,它是一个对象,可以获取异步操作的消息,避免了地狱回调
- Promise有三种状态: pending(等待态),fulfilled(成功态),rejected(失败态) ;状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
- Promise拥有一个then方法,用以处理resolved或rejected状态下的值
- then方法接收两个函数作为参数,第一个参数是Promise执行成功时的回调,第二个参数是Promise执行失败时的回调。
- then方法返回一个新的Promise对象,因此可以通过链式调用then方法
function xxx(onResolved) {
// 这里叫做promise2
return new Promise((resolve,inject) => {
//计时器模拟请求
setTimeout(()=>{
if(){
resolve(res)
} else{
inject(err)
}
})
});
};
xx.then(fun,fun)
31. async await函数
- async/await函数是异步代码的新方式
- async/await是基于promise实现的
- async/await使异步代码更像同步代码
- await 只能在async函数中使用,不能再普通函数中使用,要成对出现
- 默认返回一个promise实例,不能被改变
- await下面的代码是异步,后面的代码是同步的
32. 防抖和节流
本质上是优化高频率执行代码的一种手段
如:浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用throttle(防抖)和debounce(节流)的方式来减少调用频率
定义:
- 节流: n 秒内只运行一次,若在 n 秒内重复触发,只有一次生效
- 防抖: n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时
一个经典的比喻:
想象每天上班大厦底下的电梯。把电梯完成一次运送,类比为一次函数的执行和响应
假设电梯有两种运行策略 debounce 和 throttle,超时设定为15秒,不考虑容量限制
电梯第一个人进来后,15秒后准时运送一次,这是节流。
电梯第一个人进来后,等待15秒。如果过程中又有人进来,15秒等待重新计时,直到15秒后开始运送,这是防抖。
防抖应用场景
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测 onchange / oninput事件
- 窗口大小计算。只需窗口调整完成后,计算窗口大小。防止重复渲染。
节流应用场景
- 懒加载、滚动加载、加载更多或监听滚动条位置;
- 百度搜索框,搜索联想功能;
- 防止高频点击提交,防止表单重复提交;
33. ES6新特性 (常问介绍一下ES6–尴尬)
- let const
- 字符串、数组、对象的方法扩展
- symbol、set、map新的数据类型和数据结构
- proxy
- 异步解决方案:promise,async、await
- class类
- module模块
34. 异步编程的实现方式?
回调函数
- 使用回调函数的方式有一个缺点是,多个回调函数嵌套的时候会造成回调函数地狱,上下两层的回调函数间的代码耦合度太高,不利于代码的可维护。
Promise
- 使用 Promise 的方式可以将嵌套的回调函数作为链式调用。但是使用这种方法,有时会造成多个 then 的链式调用,可能会造成代码的语义不够明确。
async 函数
- async 函数是 generator 和 promise 实现的一个自动执行的语法糖,它内部自带执行器,当函数内部执行到一个 await 语句的时候,如果语句返回一个 promise 对象,那么函数将会等待 promise 对象的状态变为 resolve 后再继续向下执行。因此可以将异步逻辑,转化为同步的顺序来书写,并且这个函数可以自动执行。
35. js继承方式有哪些?
- 原型链继承 核心: 将父类的实例作为子类的原型
- 构造继承 核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类
- 实例继承 核心:为父类实例添加新特性,作为子类实例返回
- 拷贝继承
- 组合继承 核心:通过调用父类构造,继承父类的属性并保留传参的优点,然后通过将父类实例作为子类原型,实现
函数复用
- 寄生组合继承 核心:通过寄生方式,砍掉父类的实例属性,这样,在调用两次父类的构造的时候,就不会初始化两次实
例方法/属性,避免的组合继承的缺点
36.http 和 https 有何区别?如何灵活使用?
http是HTTP协议运行在TCP之上。所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。
https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份
37.常见的HTTP状态码
2开头 (请求成功)表示成功处理了请求的状态代码。
200 (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。
201 (已创建) 请求成功并且服务器创建了新的资源。
202 (已接受) 服务器已接受请求,但尚未处理。
203 (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。
204 (无内容) 服务器成功处理了请求,但没有返回任何内容。
205 (重置内容) 服务器成功处理了请求,但没有返回任何内容。
206 (部分内容) 服务器成功处理了部分 GET 请求。
3开头 (请求被重定向)表示要完成请求,需要进一步操作。 通常,这些状态代码用来重定向。
300 (多种选择) 针对请求,服务器可执行多种操作。 服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择。
301 (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
302 (临时移动) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
303 (查看其他位置) 请求者应当对不同的位置使用单独的 GET 请求来检索响应时,服务器返回此代码。
304 (未修改) 自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
305 (使用代理) 请求者只能使用代理访问请求的网页。 如果服务器返回此响应,还表示请求者应使用代理。
307 (临时重定向) 服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
4开头 (请求错误)这些状态代码表示请求可能出错,妨碍了服务器的处理。
400 (错误请求) 服务器不理解请求的语法。
401 (未授权) 请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
403 (禁止) 服务器拒绝请求。
404 (未找到) 服务器找不到请求的网页。
405 (方法禁用) 禁用请求中指定的方法。
406 (不接受) 无法使用请求的内容特性响应请求的网页。
407 (需要代理授权) 此状态代码与 401(未授权)类似,但指定请求者应当授权使用代理。
408 (请求超时) 服务器等候请求时发生超时。
409 (冲突) 服务器在完成请求时发生冲突。 服务器必须在响应中包含有关冲突的信息。
410 (已删除) 如果请求的资源已永久删除,服务器就会返回此响应。
411 (需要有效长度) 服务器不接受不含有效内容长度标头字段的请求。
412 (未满足前提条件) 服务器未满足请求者在请求中设置的其中一个前提条件。
413 (请求实体过大) 服务器无法处理请求,因为请求实体过大,超出服务器的处理能力。
414 (请求的 URI 过长) 请求的 URI(通常为网址)过长,服务器无法处理。
415 (不支持的媒体类型) 请求的格式不受请求页面的支持。
416 (请求范围不符合要求) 如果页面无法提供请求的范围,则服务器会返回此状态代码。
417 (未满足期望值) 服务器未满足"期望"请求标头字段的要求。
5开头(服务器错误)这些状态代码表示服务器在尝试处理请求时发生内部错误。 这些错误可能是服务器本身的错误,而不是请求出错。
500 (服务器内部错误) 服务器遇到错误,无法完成请求。
501 (尚未实施) 服务器不具备完成请求的功能。 例如,服务器无法识别请求方法时可能会返回此代码。
502 (错误网关) 服务器作为网关或代理,从上游服务器收到无效响应。
503 (服务不可用) 服务器目前无法使用(由于超载或停机维护)。 通常,这只是暂时状态。
504 (网关超时) 服务器作为网关或代理,但是没有及时从上游服务器收到请求。
505 (HTTP 版本不受支持) 服务器不支持请求中所用的 HTTP 协议版本。
38. 如何进行网站性能优化
- 从用户角度而言,优化能够让页面加载得更快、对用户的操作响应得更及时,能够给用户提供更为友好的体验。
- 从服务商角度而言,优化能够减少页面请求数、或者减小请求所占带宽,能够节省可观的资源。
总之,恰当的优化不仅能够改善站点的用户体验并且能够节省相当的资源利用。
前端优化的途径有很多,按粒度大致可以分为两类,第一类是页面级别的优化,例如 HTTP请求数、脚本的无阻塞加载、内联脚本的位置优化等 ;第二类则是代码级别的优化,例如 Javascript中的DOM 操作优化、CSS选择符优化、图片优化以及 HTML结构优化等等。另外,本着提高投入产出比的目的,后文提到的各种优化策略大致按照投入产出比从大到小的顺序排列。
一、页面级优化 - JavaScript 压缩和模块打包
- 按需加载资源
- 在使用 DOM 操作库时用上 array-ids
- 缓存
- 启用 HTTP/2
- 应用性能分析
- 使用负载均衡方案
- 为了更快的启动时间考虑一下同构
- 使用索引加速数据库查询
- 使用更快的转译方案
- 避免或最小化 JavaScript 和 CSS 的使用而阻塞渲染
- 用于未来的一个建议:使用 service workers + 流
- 图片编码优化
39.优雅降级和渐进增强
渐进增强(Progressive Enhancement):一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验。
优雅降级(Graceful Degradation):一开始就构建站点的完整功能,然后针对浏览器测试和修复。比如一开始使用 CSS3 的特性构建了一个应用,然后逐步针对各大浏览器进行 hack 使其可以在低版本浏览器上正常浏览。
其实渐进增强和优雅降级并非什么新概念,只是旧的概念换了一个新的说法。在传统软件开发中,经常会提到向上兼容和向下兼容的概念。渐进增强相当于向上兼容,而优雅降级相当于向下兼容
40. JS哪些操作会造成内存泄露
1)意外的全局变量引起的内存泄露
2)闭包引起的内存泄露
3)没有清理的DOM元素引用
4)被遗忘的定时器或者回调
5)子元素存在引起的内存泄露
41. 浏览器缓存有哪些,通常缓存有哪几种
一、http缓存
二、websql
cookie
localstorage
sessionstorage
flash缓存
42.请解释JSONP的工作原理,以及它为什么不是真正的AJAX。
JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源。例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行,那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。
AJAX是不跨域的,而JSONP是一个是跨域的,还有就是二者接收参数形式不一样!
43.请解释一下JavaScript的同源策略
在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议, 相同的端口,相同的host,那么我们就可以认为它们是相同的域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的隐患。
44:从输入url到显示页面,都经历了什么
第一步:客户机提出域名解析请求,并将该请求发送给本地的域名服务器。
第二步:当本地的域名服务器收到请求后,就先查询本地的缓存,如果有该纪录项,则本地的域名服务器就直接把查询的结果返回。
第三步:如果本地的缓存中没有该纪录,则本地域名服务器就直接把请求发给根域名服务器,然后根域名服务器再返回给本地域名服务器一个所查询域(根的子域)的主域名服务器的地址。
第四步:本地服务器再向上一步返回的域名服务器发送请求,然后接受请求的服务器查询自己的缓存,如果没有该纪录,则返回相关的下级的域名服务器的地址。
第五步:重复第四步,直到找到正确的纪录。
第2种解释:
一般会经历以下几个过程:
1、首先,在浏览器地址栏中输入url
2、浏览器先查看浏览器缓存-系统缓存-路由器缓存,如果缓存中有,会直接在屏幕中显示页面内容。若没有,则跳到第三步操作。
3、在发送http请求前,需要域名解析(DNS解析)(DNS(域名系统,Domain Name System)是互联网的一项核心服务,它作为可以将域名和IP地址相互映射的一个分布式数据库,能够使人更方便的访问互联网,而不用去记住IP地址。),解析获取相应的IP地址。
4、浏览器向服务器发起tcp连接,与浏览器建立tcp三次握手。(TCP即传输控制协议。TCP连接是互联网连接协议集的一种。)
5、握手成功后,浏览器向服务器发送http请求,请求数据包。
6、服务器处理收到的请求,将数据返回至浏览器
7、浏览器收到HTTP响应
8、读取页面内容,**浏览器渲染,**解析html源码
9、生成Dom树、解析css样式、js交互
10、客户端和服务器交互
11、ajax查询
45:请写出你对闭包的理解,并列出简单的理解
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
Vue布局面试题
1、介绍一下MVC MVVM
1. 什么是MVVM?
在MVVM框架下视图和模型是不能直接通信的,只能通过ViewModel进行交互,它能够监听到数据的变化,然后通知视图进行自动更新,而当用户操作视图时,VM也能监听到视图的变化,然后通知数据做相应改动,这实际上就实现了数据的双向绑定。并且V和VM可以进行通信。
Model(模型)
模型是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。
收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
csdn.net/topics/618679757)。TCP连接是互联网连接协议集的一种。)
5、握手成功后,浏览器向服务器发送http请求,请求数据包。
6、服务器处理收到的请求,将数据返回至浏览器
7、浏览器收到HTTP响应
8、读取页面内容,**浏览器渲染,**解析html源码
9、生成Dom树、解析css样式、js交互
10、客户端和服务器交互
11、ajax查询
45:请写出你对闭包的理解,并列出简单的理解
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
闭包有三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数和变量
3.参数和变量不会被垃圾回收机制回收
Vue布局面试题
1、介绍一下MVC MVVM
1. 什么是MVVM?
在MVVM框架下视图和模型是不能直接通信的,只能通过ViewModel进行交互,它能够监听到数据的变化,然后通知视图进行自动更新,而当用户操作视图时,VM也能监听到视图的变化,然后通知数据做相应改动,这实际上就实现了数据的双向绑定。并且V和VM可以进行通信。
Model(模型)
模型是指代表真实状态内容的领域模型(面向对象),或指代表内容的数据访问层(以数据为中心)。
收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
[外链图片转存中…(img-FHmOPsb6-1715762456521)]
[外链图片转存中…(img-kBo8Z9UF-1715762456522)]
需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!