初级前端面试题 - js
前言:众所周知,HTML,CSS,JS是学习前端所必备的。js的基础学好了,框架类的vue,react等都会接受的很快,因此js是前端很总要的一个部分,这篇文章将会结合面试题,对js的知识点进行总结
号外号外,这是一篇长长的博客,所以耐心耐心,希望能有收获哦,加油~~~
目录
1. 数据类型和转换
1.1 常见面试题
1.2 知识点
1.2.1 有哪些数据类型?
1.2.2 数据类型怎么分类,有什么区别?
1.2.3 typeof
1.2.4 变量计算 - 类型转换
1.3 面试题答案
2.原型和原型链
1.1 常见面试题
1.2 知识点
1.2.1 class和继承
1.2.2 判断类型instanceof
1.2.3 原型和原型链
1.3 面试题答案
3 作用域和闭包
3.1 常见面试题
3.2 知识点
3.2.1 作用域和自由变量
3.2.2 闭包
3.2.3 this
3.3 面试题答案
4. 异步和单线程
4.1 常见面试题
4.2 知识点
4.2.1 单线程和异步
4.2.2 应用场景
4.2.3 回调地狱(callback hell) 和 Promise
4.3 面试题答案
js Web Api
1. DOM操作 - Document Object Model(文档对象模型)
1.1 常见面试题
1.2 知识点
1.2.1 DOM的本质
1.2.2 DOM节点操作
1.2.3 DOM结构操作
1.2.4 DOM的性能
1.3 面试题答案
2 .BOM操作
2.1 常见面试题
2.2 知识点
2.2.2 screen
2.2.3 location
2.2.4 history
3.1 面试题答案
3.事件绑定
3.1 常见面试题
3.2 知识点
3.2.1 事件绑定
3.2.2 事件冒泡
3.2.3 事件代理
3.3 面试题答案
4.ajax
4.1 常见面试题
4.2 知识点
4.2.1 XMLHttpRequest
4.2.2 状态码
4.2.3 跨域 - 同源策略和其解决方案
4.2.4 ajax的工具
4.3 面试题答案
5.存储
5.1 常见面试题
5.2 知识点
5.2.2 localStorage和sessionStorage
5.3 面试题答案
3.浏览器相关
1 页面加载过程
1.1 常见面试题
1.2 知识点
1.2.1 加载资源的形式
1.2.2 加载资源的过程
1.2.3 渲染页面的过程
1.3 面试题答案
2 安全
2.1 XSS跨站请求攻击
什么是XSS攻击?
怎么预防?
2.2 XSRF攻击
什么是XSRF攻击?
怎么预防?
三.实际应用
1.git
2.调试工具
3.抓包
4.webpack和babel
5 性能优化
5.1 方法
让加载更快
让渲染更快
5.2 知识点
SSR
图片懒加载
缓存DOM查询,多个DOM一次性插入
防抖和节流
常考题
1. 数据类型和转换
1.1 常见面试题
(1)typeof可以判断哪些数据类型
(2)什么时候使用 == ? 什么时候使用 === ?
(3)值类型和引用类型的区别是什么?
(4)手写深拷贝
1.2 知识点
1.2.1 有哪些数据类型?
- Number,String ,Boolean, Object(Array,Fuction...), Undefined, Null,Symbol
1.2.2 数据类型怎么分类,有什么区别?
(1) 数据类型分为 - 值类型和引用类型
值类型 - undefined, Number, String, Boolean,Symbol
引用类型 - Object, Null
(2) 区别
根据内存空间和cpu的耗时,值类型和引用类型在存储,拷贝等方面都不同
①存储地址
首先,存储空间分为栈和堆,一般情况,栈从上往下排列,堆从下往上排列,两种数据类型在栈堆中的表现各不相同,通过例子来查看
值类型的存储:
例1
let a = 100;
let b = a;
a = 200
console.log(b)
打印出来的b显然是100,原因如下图:
值类型直接将值存储在栈中,在赋值过程中,开辟新的存储空间b,将a的值赋值给b,因此在去修改a与b无关了,a和b有各自的存储空间。
一般情况下 - 值类型,占用空间小
引用类型的存储:
例2
let a = {age: 20};
let b = a;
a.age = 21;
console.log(b)
这个时候的b的age已经被改变,为21,原因如下图:
引用类型,是在栈中开辟了一个堆的存储地址,a的存储value假设是0x12(一个16进制), 这个地址在堆中就是age为12,引用类型是将栈的value进行赋值,也就是b的value其实也是ox12,指向了同一个堆的地址,因此a的改变会影响b的改变。也就是,a与b有各自的存储空间,但是他们的数据,其实在堆中都是同一空间
引用类型 - 占用空间可能很大,像json数据,内容空间和cpu的耗时来区分
注意 - Null的指针其实是指向了一个空地址、因此他也是一个引用类型
②拷贝
拷贝有深拷贝和浅拷贝
因为之前已经写过一次拷贝了,所以就不重复写了
前端的深拷贝与浅拷贝_哆来A梦没有口袋的博客-CSDN博客
深拷贝就是拷贝引用类型,像例2一样,赋值后并不想数据相互影响,这个时候就需要深拷贝
1.2.3 typeof
typeof - 判断所有的值类型,判断是否为引用类型,是返回object,能判断函数,是函数,返回function
1.2.4 变量计算 - 类型转换
(1)字符串拼接
let a = 100 + 10 //110
let b = 100 + '10' // '10010'
let c = true + '10' // 'true10'
(2) ==
100 == '100' //true
0 == '' //true
0 == false //true
false == '' //true
null == undefined //true
所以,当要进行明确判断的时候,都用===
(3)if和逻辑计算
truly变量 !!变量 === true的变量 - 两次取反为true的变量
falsely变量 !!变量 == false的变量 - l两次取反为false的变量
if判断的是turely变量和falsely变量
逻辑计算,也是判断的truely变量和falsely变量
1.3 面试题答案
(1)typeof可以判断哪些数据类型
typeof可以判断所有的值类型,可以判断是否为引用类型,是则返回object,也可以判断函数,是函数,返回function
(2)什么时候使用 == ? 什么时候使用 === ?
== 存在隐式数据类型转换,因此除了 == null之外,其他的都用 === 最好啦
(3)值类型和引用类型的区别是什么?
值类型和引用类型在存储和拷贝过程中都有区别
存储,值类型是直接将数据存储在栈中
引用类型是将数据的存储在堆中,将存储数据的地址值存储在栈中
拷贝过程:要完全拷贝,对于引用类型需要进行深拷贝
(4)手写深拷贝
function deepClone(obj) {if(typeof obj !== 'object' || obj == null) {return obj;}let resultif(obj instanceOf Arrary){result = [];}else {result = {};}for(let key in obj){if(obj.hasOwnProperty(key)){result[key] = deepClone(obj[key])}}return result;}
当然,深拷贝不止这一种方法,这里只是写一下通过递归进行深拷贝
2.原型和原型链
1.1 常见面试题
(1)如何准备判断一个变量是不是数组?
(2)class的原型本质,怎么理解?
1.2 知识点
1.2.1 class和继承
(1) class
class是一个面向对象的一个实现,class本质类似于一个模板,可以去构建(constructor)一些东西(方法,属性)
//定义类
class Student{constructor(name, number){this.name = name; //this - 指向实例对象this.number = number;}sayHi() {console.log(`姓名:${this.name},学号:${number}`);}
}通过类声明 多个对象/实例
const lixian = new Student('李现', 20);
console.log(lixian.name, lixian.number);
lixian.sayHi();const li = new Student('李', 22);
console.log(li.name, li.number);
li.sayHi();
(2)继承
继承,是定义一个父类(具有公共特性,如人,都有名字,都有身份证,都能吃饭等等),子类(具有自己的属性,比如学生,需要学习,有学号)继承父类。
继承主要是通过extends关键字,然后利用super继承属性
//定义父类
class People{constructor(name, id){this.name = name; //this - 指向实例对象this.id= id;}eat() {console.log(`${this.name}吃东西了`);}
}//子类继承并含有特有的属性和方法
//学生类
class Student extends People {constructor(name, id, number){super(name, id);this.number = number;}study() {console.log('study了')}
}
//老师类
class Teacher extends People {constructor(name, id, subject){super(name, id);this.subject= subject;}teach() {console.log('上课了')}
}//实例化
const s1 = new Student('夏洛', 510524199710125420, 201544901114);
console.log(s1.name, s1.id, s1.number);
s1.eat();
s1.study();
注意的是,class只是es的一个规范,具体怎么实现还是引擎说了算
1.2.2 判断类型instanceof
instanceof是基于原型链进行判断的,判断是否属于一个类,是否属于一个构造函数
基本上面的例子
lixian instanceof People //true
s1 instanceof Student //true
s1 instanceof People //true
s1 instanceof Object //ture
怎么理解instanceof, a instanof b ,是看a是否是b构建出来的,当然,b也可以是构建a的父类(people),Object是所有类的父类,最顶层,是js引擎自己定义的,因此是否是ture,其实是基于原型链进行查找,就可以看下一个知识点 - 原型和原型链
1.2.3 原型和原型链
首先
typeof Student //function
typeof People //function
因此,类其实是一个方法,只是是一个特殊的方法
原型和原型链,需要知道的是隐式原型和显示原型,因为之前也非常详细的写过了,所以就暂时不继续写了
关于细节,请看这个 - 》不得不看的js原型链!_哆来A梦没有口袋的博客-CSDN博客
当然,对于懒的孩子,我直接将原型和原型链比较重要的几句话,粘贴过来了
1.每个函数(通常指构造函数,如Person)都有一个属性:prototype
2.prototype是一个对象, 里面有constructor , __proto__ 隐式原型
3.构造函数的原型对象指向当前构造函数 Person.prototype.constructor === Person
4.实例对象的隐式原型指向构造函数的显示原型
p1.__proto__ === Person.prototype
5.在构造函数显示原型中添加的方法,所有的实例对象共享
6.访问属性和方法,是基于原型连进行访问 在当前的实例对象去找--》构造函数的原型 ==》.... =》 Object的原型
如果感觉一看这几句话就懂了,就不需要再去看总结的原型和原型链了
这里是一个Student和实例,夏洛的一个图,看了原型和原型啦,在看这个图,就很清楚了
class Student{constructor(name, age){this.name = name;this.age = age;}sayHi(){console.log(this.name, this.age)}
}const xialuo = new Student('夏洛', 100)
xialuo.sayHi(); //'夏洛', 100
xialuo.__proto__.sayHi(); //undefined
可能会疑惑,实例对象xialuo执行sayHi有值,并且他就是通过隐式原型去找,为什么会是undefined,这里大家可以看下一个知识点this之后再回来理解
首先,类Student中sayHi的this,指向的实例对象也就是xialuo
因此很好理解xialuo.sayHi() => xialuo就是实例对象,可以理解为执行其实是,xialuo,__proto__.sayHi.call('xialuo')
而xialuo.__proto__ => 他并不是Student的实例对象
1.3 面试题答案
(1)如何准备判断一个变量是不是数组?
a instanceof Arrary
(2)class的原型本质,怎么理解?
class是es6的新特性之一,通过class关键字来定义一个类,可以理解class为一个模板,它的本质就是一个函数,可以通过constructor构造方法来构造一些属性,直接定义方法,定义子类进行继承。
3 作用域和闭包
3.1 常见面试题
(1)this在不同应用场景下如何取值
(2)手写bind函数
(3)闭包在实际开发总的应用场景
(4)创建10个a标签,点击弹出对应的序号
3.2 知识点
3.2.1 作用域和自由变量
作用域:变量的合法使用范围,如下面一个框就是一个作用域
作用域分类 - 全局作用域,函数作用域,块级作用域(es6新增的)
全局作用域 - 整个js文件都可以使用的变量
函数作用域 - 在函数中使用的变量
块级作用域 - es6中的,一般是指一个{}区域内的变量,声明块级作用域的变量 - 用 let
自由变量:作用域内如果没有该变量,从下往上找,如a2,在函数作用域中没有a2,往上一级找,找到为止
3.2.2 闭包
作用域应用的特殊情况,一般有两种情况 - 函数作为参数被传递,函数作为返回值返回,简单解释闭包 - 嵌套函数使用外部的变量
直接看两个题
函数作为返回值
function create () {let a = 100;return function () {console.log(a)}
}const fn = create()
const a = 200;
fn()
函数作为参数传递
function print(fn) {const a = 200;fn();
}
const a = 100;
function fn(){console.log(a)
}
print(fn)
注意 - 自由变量是在定义的位置向上级作用域查找,而不是在执行的位置,因此上面两道题都是100
如果没有搞懂闭包,可以看下这篇博客,详细的在了解一下闭包 闭包_哆来A梦没有口袋的博客-CSDN博客
3.2.3 this
this的指向在不同情况下,指代的不同,有下列几种情况
(1)作为普通函数
(2)使用call, apply , bind
(3)作为对象方法调用
(4)在class方法中调用
(5)箭头函数
this是什么值,是在函数执行的时候确定的
下面通过例子讲解上面5中情况
(1)作为普通函数,call.bind,apply
function fn(){console.log(this)
}fn(); //windowfn.call({x: 100}) //{x: 100}const fn2 = fn.bind({x: 200})
fn2(); //{x: 200}
定义的函数 - 在执行时候,this是指向window
而call,apply,bind是可以改变this指向,this指向调用的对象 ,他们的区别是什么?
apply和call基本是一致的,区别在与传参 - apply把需要传递给fn的参数放到一个数组(或者类数组)中传递进去,而call是单独传递的,第一个参数是更改this的对象
bind和他们的区别是 - bind需要自己调用一次,他是等待执行而不是立即执行,如上的例子,bind是返回了一个新函数,需要在执行新函数fn2
比如
function test(a,b){console.log(this)
}test.call({x:100}, 1 , 2)
test.apply({x: 100}, [1,2])
(2)对象的this和箭头函数的this
对象中的this是指向对象本身的,而箭头函数的this是指向上一级作用域的this
(3)类中的htis - 类中的this是指向实例对象
所以,到现在,记住了this的指向吗,不同情况的this指向不同,要根据确切的情况去判别
3.3 面试题答案
(1)this在不同应用场景下如何取值
作为普通函数 - 指向window
使用call, apply , bind - 指向传入的对象
作为对象方法调用 - 指向对象本身
在class方法中调用 - 指向实例对象
箭头函数 - 指向上级作用域的this
(2)手写bind函数
Function.prototype.bind1 = function() {//将所有参数的伪数组变为真数组const args = Array.prototype.slice.call(arguments);//取出第一个数组cosnt t = args.shift();fn.bind()中的fnconst self = this;//返回一个函数return function () {return self.apply(t, args)}
}
(3)闭包在实际开发总的应用场景,举例说明
(1)隐藏数据
(2)简单做一个缓存工具 - 闭包会缓存值 - 具有特定功能的js文件,将所有的数据和功能封装在一个函数内部,只向外暴露n个对象或者方法
function toCache(){const data = {} //定义的数据被隐藏,不被外界访问,只能在执行函数去保存修改值return {set: function(key, value){data[key] = value;},get: function(key){return date[key]}}
}const s = toCache();
s.set('a', 100) //存储
s.get('a') //获取值
(4)创建10个a标签,点击弹出对应的序号
for(let i = 0; i < 10; i++){let a = document.createElement('a');a.innerHTML = i + '<br>';a.addEventListener('click', (e) => {e.preventDefault();alert(i)})document.boy.appendChild(a)
}
为什么用var i不能,存在作用域为题,使用let是将每一个循环作为一个块级作用域,可以理解为保存了每个值。如果不是很能理解,可以查看闭包模块的知识点- 闭包_哆来A梦没有口袋的博客-CSDN博客
4. 异步和单线程
4.1 常见面试题
(1)同步和异步的区别是什么?
(2手写Promise加载一张图片?
(3)前端使用异步的场景有哪些?
(4)题目 - 输出顺序
console.log(1)
setTimeout(funciton(){
console.log(2)
},1000)
console.log(3)
setTimeout(funciton(){
console.log(4)
},0)
console.log(5)
4.2 知识点
4.2.1 单线程和异步
首先js是单线程语言,只能同时执行一件事。js和DOM渲染共用一个线程,因为js可以修改DOM结构,思考一下,如果不用一个线程,如果是在渲染DOM,但是js又修改了DOM那不是就没有意义了。那为什么需要异步??
遇到等待(网络请求,定时任务)不能卡住 - 需要异步 - 解决单线程问题,基于callback(在动动小脑瓜,如果是在请求一个图片或者其他资源的时候,浏览器卡住了,不能点击,不能做任何操作,是不是体验很差,而且等待时长多么的漫长,所以异步存在解决了这个问题)
毕竟等待的过程中,cpu是空闲状态,空闲不是浪费吗,所以异步多么的重要
异步 - 不会阻塞后面代码的执行
console.log(1)
setTimeout(() => {
consloe.log(2)
}, 1000)
consloe.log(3)
setTimeout就是典型的异步执行,代码的输出顺序是132
同步- 阻塞后面的代码
consoe.log(1)
alert(2)
consloe.log(3)
alert也是典型的同步操作,只有输出了2才能输出3,执行顺序123
4.2.2 应用场景
什么时候需要异步,也就是需要等待的情况
主要是 - 网络请求,像ajax请求
- 定时任务,像setTimeout
4.2.3 回调地狱(callback hell) 和 Promise
回调地狱也是之前已经总结过的,所以不太懂的可以看 解决回调地狱,异步变同步问题_哆来A梦没有口袋的博客-CSDN博客
总的来说 - 回调地狱就是出现了嵌套的网络请求,而Promise的出现解决了这一问题
关于promise没有进行详细的解释,需要掌握它的用法
4.3 面试题答案
(1)同步和异步的区别是什么?
异步不会阻塞代码的执行,同步会阻塞代码的执行
(2手写Promise加载一张图片?
这里的例子写的是加载两个图片哦
function loadImg(srv){返回一个promise,promise参数是一个函数,函数有两个参数,resolve,reject,也是一个函数return new Pomise((resolve, reject) => {const img = document.createElement('img')img.onload = () => {resolve(img) //resolve的数据用then接收}img.onerror = () => {reject('加载失败') //用catch接收}img.src = src})
}loadImg('图片地址').then((img) => {console.log(img)return img //return的数据,用then继续接收}).then((img) => {consloe.log(img)return loadImg('图片地址') //return 的是promise对象}).then((img) =>{consloe.log(img) //img是加载图片的resolve的数据}).catch((err) => {console.log(err)})
(3)前端使用异步的场景有哪些?
网络请求,像ajax请求
- 定时任务,像setTimeout
(4)题目 - 输出顺序
输入顺序 - 13542
js Web Api
js的规范是ECMA标准规定的,而Web API是操作网页api是W3C规定的
1. DOM操作 - Document Object Model(文档对象模型)
现在的框架,vue,react等其实已经封装了DOM操作,所以在使用框架的时候,其实很多都不需要在自己去操作DOM了,但是作为一个前端工程师,其实DOM操作是最基本的。
1.1 常见面试题
(1)DOM是哪种数据结构
(2)DOM操作的常见api
(3)属性attr和property的区别
(4)一次性插入多个DOM节点,考虑一下性能
1.2 知识点
1.2.1 DOM的本质
介绍之前,先了解另外一种mxl语言,xml也是由标签组成,与html不同的是,它的标签是可以自定义的,而html的标签必须按照标准写。
那什么是DOM? DOM的本质是HTML语言解析的一棵树。
1.2.2 DOM节点操作
(1)获取节点
document.getElementById('id名')
document.getElementsByTagName('标签名')
document.getElementsByClassName('类名')document.querySelector('选择器') //返回第一个满足css选择器条件的元素
document.querySelectorAll('选择器') //返回所有满足css选择器条件的元素
注意的是,除了id名和querySelector以外,其他的都是返回的一个满足条件的元素的伪数组
(2)修改节点
①property - 一种通过js进行修改获取属性的一种形式
const p = document.querySelector('p')p.style.width = '100px'; //设置属性
cosole.log(p.style.width) //获取属性
②attribute - 利用api直接修改获取修改属性
const p = document.getElementById('p')p.setAtrribute('data-name', 'name') //<p data-name="name">sss</p>
p.setAtrribute('style', 'font-size: 15px')
console.log(p.getAtrribute('data-name'))
③区别
property修改的并不会体现在HTML结构中,attribute会体现在HTML结构中,值得注意的是,两者都会引起DOM的重新渲染
对DOM节点的操作的属性有很多,上面只是讲解了常用部分,更多可以了解官方api - HTML DOM 元素对象 | 菜鸟教程
1.2.3 DOM结构操作
(1)新增/插入节点 - appendChild
const div = document.getElementById('div')const p = document.createElement("p") //创建p
p.innerHTML = 'this is p'div.appendChild(p) //将p插入div,注意如果是对现有的元素进行append会产生移动
(2)获取子节点,父节点 - parentNode, ChildNodes
const p = document.getElmentById('p')cosole.log(p.parentNode) //获取父节点const div = document.getElementBy('div')
console.log(div.childNodes) //获取子节点
这里需要注意的是,获取子节点的时候空格换行,文本节点<text>也会存在哦~
(3)删除节点 - removeChild
const div = document.getElementById('div')
const p = document.getElementById('p')div.removeChild(p)
同理,DOM的增删改查有很多种方法,这里只是列举了一些常见的方法,如果想要了解更多,可以查看文档api - HTML DOM 属性对象 | 菜鸟教程
1.2.4 DOM的性能
DOM操作占用的cpu很多,频繁操作很容易卡顿。因此在vue,react这些框架中,其实就有自己的diff算法,去更新DOM,提高性能。
提升DOM的性能,我们能做些什么?
对DOM查询做缓存,将频繁操作改为一次性操作(插入多次,改成插入一次等)
1.3 面试题答案
(1)DOM是哪种数据结构
DOM是一种数的结构
(2)DOM操作的常见api
参考上面1.2.3
(3)属性attr和property的区别
property修改的并不会体现在HTML结构中,attribute会体现在HTML结构中,值得注意的是,两者都会引起DOM的重新渲染
(4)一次性插入多个DOM节点,考虑一下性能
const frag = document.createDocumentFragment() //创建文档碎片,其实是一个虚拟DOM
const div = document.getElementById('div')for(let i = 0; i < 10; i++){const p = document.createElement('p')p.innerHtml = 'this p <br>'frag.appendChild(p)
}div.appendChild(frag) //真正插入真实DOM
2 .BOM操作
2.1 常见面试题
(1)如何识别浏览器的类型
(2)分析拆解url的各个部分
2.2 知识点
2.2.1 navigator
查看当前浏览器的信息
navigator.userAgent
谷歌浏览器的信息
2.2.2 screen
屏幕的高度,宽度
console.log(screen.width)
console.log(screen.height)
2.2.3 location
location有很多网址信息,可以去选择自己想要的
2.2.4 history
history主要是对方法的使用,前进啊,后退啊,history.back()等等
3.1 面试题答案
(1)如何识别浏览器的类型
navigator.userAgent
(2)分析拆解url的各个部分
location
3.事件绑定
事件绑定的一些api HTML DOM 事件对象 | 菜鸟教程
3.1 常见面试题
(1)编写一个通用的事件监听函数
(2)描述实践冒泡的流程
(3)无限下拉的图片列表,如何监听每个图片的点击?
3.2 知识点
3.2.1 事件绑定
let box = document.getElementById('box')//监听事件绑定
box.addEventListener('click', () => {})//直接绑定
box.onclick = function(){}
3.2.2 事件冒泡
事件冒泡:子级的事件会触发父级的(假设点击事件,父级也有点击事件,则会触发自己的点击事件,也会触发父亲的点击事件)
举个栗子
//结构
<div id="father"><p id="child"> 子元素 </p>
</div>//js代码
let father = document.getElementById('father')
let child = document.getElementById('child')father.addEventListener('click', () => {cosole.log('father')
})child .addEventListener('click', () => {cosole.log('child')
})
当点击p,会打印child,father,这就是事件冒泡
事件冒泡的存在会在一些场景下影响原有逻辑,所以常常我们会阻止事件冒泡 - e.stopPropagation()
child .addEventListener('click', (e) => {//阻止事件冒泡e.stopPropagation()cosole.log('child')
})
阻止事件冒泡后,只会打印child
3.2.3 事件代理
一般是在瀑布流的时候,将子元素的事件绑定在父元素身上
<div id="box"><a href="#">a1</a1><a href="#">a2</a1><a href="#">a3</a1><a href="#">a4</a1><button>加载更多</button>
</div>let box = document.getElementById("box")
box.addEventListener('cilck', e => {e.prevenDfault() //阻止默认行为if(e.target.nodeName === A){alert(e.target.innerHTML)}})
事件代理的好处是什么 - 代码简洁,减少浏览器内存占用(只绑定一次事件)
其实在jquery中,想想是不是对未来元素绑定事件也是绑定在父元素中的~
3.3 面试题答案
(1)编写一个通用的事件监听函数
//满足普通绑定和事件代理绑定,并且this永远指向触发元素
function bindEvent(el, type, selector, fn){if(fn == null){fn = selectorselector = null}el.addEventListener(type, event => {const target = event.targetif(selector){//触发元素是否与选择器相同,代理绑定if(target.matches(selecotr)){fn.call(target, event)}}else {fn.call(target, event)}})
}
(2)描述实践冒泡的流程
事件冒泡是基于DOM的树形结构,事件会顺着触发元素往上冒泡
(3)无限下拉的图片列表,如何监听每个图片的点击?
利用事件代理-如上例子
4.ajax
4.1 常见面试题
(1) 手写一个简易的ajax
(2) 跨域的常见方法
4.2 知识点
关于ajax的知识点,之前写过一篇基础使用和封装以及jquery的ajax: ajax_哆来A梦没有口袋的博客-CSDN博客
4.2.1 XMLHttpRequest
这里写一个基本的ajax的请求
get
//创建一个实例
const xhr = new XMLHttpRequerst()
//写入请求地址
xhr.open('GET', 'URL地址', true) //异步请求,false是同步
//监听状态
xhr.onreadystatechange = function() {if(xhr.readyState === 4){if(xhr.status === 200){console.log(xhr.responseText)}}
}
xhr.send()
post
var xhr = new XMLHttpRequest();xhr.open("post",'./server/mydate.json');xhr.setRequestHeader('Content-Typ','application/x-www-form-urlencoded'); //设置请求头xhr.send('username=name&age=12'); //传入参数xhr.onreadystatechange = function(){if(xhr.readyState === 4 && xhr.status === 200){console.log(xhr.responseText);}}
区别:
1.post 比 get在传递的时候多了一个头部结构
2.传递参数的方式不同 get: 传递在地址的后面 www.baidu.com?参数=值&参数=值
post: 传递在send()方法的里面 xhr.send('参数=值&参数=值')
3.get因为是地址传递 - 铭文传递 -不安全 - 传递的数据量小
4.2.2 状态码
2xx - 表示成功处理请求,如200
3xx - 需要重定向 301 302 304
4xx - 客户端请求错误,如404 403
5xx - 服务器端错误 500 501
4.2.3 跨域 - 同源策略和其解决方案
跨域的知识点,之前总结了一篇超级详细的博客,所以就不重复写了:跨域及其解决方案_哆来A梦没有口袋的博客-CSDN博客
4.2.4 ajax的工具
工具都是直接用就行了,还是比较简单,只是在这总结一下工具,具体的可以直接看官网
(1)jquery的ajax
(2)fetch -
官网: 使用 Fetch - Web API 接口参考 | MDN
(3)axios
官网 - axios中文文档|axios中文网 | axios
对axios的总结 - 封装axios_哆来A梦没有口袋的博客-CSDN博客
4.3 面试题答案
(1) 手写一个简易的ajax
let obj = {url: './server/mydate.json',type: 'get',data: {name: 'aaa',age: 18}}
//结合一下promise
function ajax(obj) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequrest()//初始化参数let params = '';if (obj.data != ''){for (key in obj.data) {params += `${key}=${obj.data[key]}&`;}params = params.substring(0, params.length - 1);}//接收传递类型并转为小写let type = obj.type.toLowerCase();xhr.open(type ,type == 'get' ? `${obj.url}?${params}` : obj.url);// post - 设置请求头if (type === 'post') {xhr.setRequestHeader('Content-Typ', 'application/x-www-form-urlencoded');}type == 'get' ? xhr.send() : xhr.send(params);xhr.onreadystatechange = function () {if (xhr.readyState === 4 && xhr.status === 200) {let result = xhr.responseText;resolve(result)}else {reject('错误')}}})
}ajax(obj).then(res => {}).catch(err => {})
(2) 跨域的常见方法
jsonp,cors,proxy等等
5.存储
5.1 常见面试题
(1)描述一下cookie,localStorage,sessionStorage的区别
5.2 知识点
web端的存储技术的总结 - web存储技术_哆来A梦没有口袋的博客-CSDN博客_web存储技术
5.2.1 cookie
本身是用于浏览器和server通讯,是被借用到本地存储。现在一般是用于身份标识
前端设置修改:
document.cookie = "a=200;b=100"
每一次是追加,不是覆盖,每次刷新,cookie是赋值后,不断刷新是继续存在的,因此可以利用来做本地存储
cookie只能存储4kb,并且是http请求的时候,cookie都会发送到服务端,增加了请求数据量
随意存储还是尽量不要用cookie
5.2.2 localStorage和sessionStorage
.这两个h5专门为存储设计的,最大可以存储5M
设置和获取
localStorage.setItem(key,value)
lcoalSotrage.getItem(key)sessionStorage.setItem(key,value)
sessionSotrage.getItem(key)
区别也很简单 - sessionStorage是临时存储,关闭浏览器清空
- localStorage是永久存储,只能手动删除
5.3 面试题答案
(1)描述一下cookie,localStorage,sessionStorage的区别?
容量: cookie只有4kb, 临时存储和永久存储5M
cookie会被http请求发送到后端
临时存储,关闭浏览器清空,localStorage只能手动清空
3.浏览器相关
前端的运行环境 - 浏览器(server端有nodejs) - 下载网页代码,渲染页面,并在次期间执行js,要保证代码在浏览器种稳定且高效
1 页面加载过程
1.1 常见面试题
(1)从输入url到渲染出页面的整个过程
(2)window.onload和DOMContentLoad的区别
1.2 知识点
1.2.1 加载资源的形式
前端加载资源 - 一般有htmld代码,媒体文件(图片,视频等等),js,css
1.2.2 加载资源的过程
DNS解析: 域名 -》 IP地址 (将域名转换为ip地址)
浏览器根据IP地址向服务器发起http服务(操作系统在发,三次握手等等)
服务器接收,处理http请求,并返回给浏览器
1.2.3 渲染页面的过程
根据html代码生成DOM Tree
根据css生成CSSOM(层叠样式表对象模型)
将DOM Tree 和 cssOM整合成renderDOM
根据Render Tree 渲染页面
遇到script标签,暂停渲染,优先加载并执行js代码(浏览器是单线程的 .js代码可能会改变css)
直到把Render Tree渲染完成
1.3 面试题答案
(1)从输入url到渲染出页面的整个过程?
①dns解析域名为ip地址
②浏览器根据ip地址向服务器发起http请求
③建立连接,服务器处理请求并返回
④浏览器对返回解析,解析DOM树,解析css,构建render Tree
⑤遇到script标签,暂停渲染加载执行js,在进行渲染,直至全部渲染完成
(2)window.onload和DOMContentLoad的区别?
window,.onload是资源(图片等)全部加载完成才会执行
DOMContentLoad是DOM加载结束就执行
2 安全
常见的web前端攻击方式有哪些?
2.1 XSS跨站请求攻击
什么是XSS攻击?
xss攻击通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。
举个栗子一篇博客网站,发表了一篇博客,其中嵌入了<script>脚本,脚本内容是:获取cookie(有个人的列表信息),并发送到我的服务器(服务器配合跨域),有人查看阅读,就可以轻松的获取访问者的cookie
假设有一篇博客
<body><p>xxx</p><p>xxx</p><scipt>alert(document.cookie);</script>
</body>
当访问,就获取到cookie,cookie里面可能就含有你的登录信息
怎么预防?
替换特殊字符,如:将 < 变为 < , > 变为 gt;,这个替换谁做?前端可以在显示的时候做,后端在存储的时候做
<body><p>xxx</p><p>xxx</p><scipt>alert(document.cookie); </scipt>
</body>
自己做一般可以正则匹配,也可以去下载工具 - npm install xss
2.2 XSRF攻击
什么是XSRF攻击?
假设你在购物,看中了某个商品id100,付费接口是xxx.com/pay?id=100,但是你没有验证,现在攻击者也看中了一个商品id200,攻击者向你发送了一封邮件,邮件隐藏了<img src="xxx.com/pay?id=200 /">(会带过去你的信息),你一看了这个邮件,你就付钱了
怎么预防?
使用post接口
增加验证,例如密码,短信验证码,指纹等等
三.实际应用
1.git
git的服务器,常见的github , coding,net等等,一般公司都有自己的服务器
git的相关知识点: git的相关用法_哆来A梦没有口袋的博客-CSDN博客
这里就列举一些常用命令
git add .
git checkout xxx
git commit -m 'xxx'
git push
git pull
git branch
git checkout -b xxx
git merge xxx
2.调试工具
chrome调试工具 -》 Elements, Console, debugger, NetWork, Application
3.抓包
移动端h5页,查看网络请求,需要用工具抓包
windows一般使用fiddler,手机和电脑连同一个局域网,将手机代理到电脑上,手机浏览网页,就可以抓包,查看网络请求,网址代理,https
抓包软件 Fiddler 了解一下?_CSDN资讯-CSDN博客
4.webpack和babel
webpakc打包工具,现在用的很多,像vue,react等等,都会使用到webpack,是前端模块化管理和打包工具,可以将许多松散的模块按照依赖和规则打包成前端资源, 还可以将模块按需加载。 通过loader的转换,任何形式的资源都可以视作模块。如, commonJS模块图片资源等
打包原理也很简单 - 根据入口文件-生成依赖图 - 转义形成css,js文件
首先ES6模块化,浏览器不支持,并且es6的语法,浏览器并不完全支持,所以babel用于转义,babel是提供一些插件为webpack使用
webpackl能压缩代码,整合代码,让网页加载更快
首先要有node环境,安装各个插件
html-webpack-plugin html编译插件
webpack-dev-server 启动服务插件
@babel/core babel的核心组件组合
npm init
npm install webpack webpack-cli html-webpack-plugin webpack-dev-server -D
nom install @babel/core @babel/preset-env babel-loader -D
新建.bebal的配置文件(与package.json同级) - .babelrc(一个json文件)。写如下配置,之后再webpack.config.js中编写module模块
{"presets": ["@babel/preset-env"]
}
新建文件webpack的配置文件 webpack.config.js(与package.json同级)
cosnt path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin') //引入插件module.exports = {mode: 'development', //模式 - 开发环境entry: path.join(__dirname, 'src', 'index.js'),//入口path拼接上src,index.js就是入口文件output: {filename: 'bundle.js',path: path.join(__dirname, 'dist') //__dirname 项目的绝对路径},module: { //模块rules: [ //定义规则数组{test: /\.js$/, //以js结尾的loader: ['babel-loader'], //bable-loader插件,将js的es6语法转义es5include: path.join(__dirname, 'src') , //哪些文件需要这个规则exclude: /node_modules/ //不需要转义的文件}]},plugins: [ //插件配置new HtmlWebpackPlugin ({template: path.join(__dirname, 'src', 'index.html') , //模板filename: 'index.html' //根据模板产出的文件名})],devServe: { //开启服务port: 3000,contentBase: path.join(__dirname, 'dist') //当前目录}}
在pages.json中修改一下打包
{"scripts": {"build": "webpack --config webpack.config.js", //打包命令"dev": "webpack-dev-server" //服务}
}
上面是devlopment是环境,下面在配置一下生产环境
新建文件webpack.prod.js
cosnt path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin') //引入插件module.exports = {mode: 'production', //模式 - 生产环境下的代码会被压缩,体积小entry: path.join(__dirname, 'src', 'index.js'),//入口path拼接上src,index.js就是入口文件output: {filename: 'bundle.[contenthash].js', //contenthash,标识,代码内容变了,会随之改变path: path.join(__dirname, 'dist') //__dirname 项目的绝对路径},module: { //模块rules: [ //定义规则数组{test: /\.js$/, //以js结尾的loader: ['babel-loader'], //bable-loader插件,将js的es6语法转义es5include: path.join(__dirname, 'src') , //哪些文件需要这个规则exclude: /node_modules/ //不需要转义的文件}]},plugins: [ //插件配置new HtmlWebpackPlugin ({template: path.join(__dirname, 'src', 'index.html') , //模板filename: 'index.html' //根据模板产出的文件名})],}
{"scripts": {"build": "webpack --config webpack.prod.js", //打包命令}
}
先讲一下contenthash
contenthash会根据内容改变而改变,url和文件不变,会自动触发http缓存,返回304,就不会再更新这些url和文件不变的文件。
那么上线,不会重新下载,浏览器会去下载新的hash改变的文件
这里在顺便讲一下模块化
es6的模块化利用export暴露,import引入,不同的是,export default在一个文件只能有一个
export default {} //对应 import xxx from ''
export const a = {} // import {a} from ''
5 性能优化
性能优化原则 - 多使用内存,缓存,减少cpu计算量,减少网络加载耗时(用空间换时间),从而让加载更快,让渲染更快
5.1 方法
让加载更快
减少资源体积:压缩代码(像webapack打包)
减少访问次数:合并代码(http请求很耗时,可以一次访问9kb(而不是三次请求3个3kb,), css的雪碧图),SSR服务器端渲染,缓存
使用更快的网络:cdn(就近访问服务器)
让渲染更快
css放在head,js放在body下,尽早执行js,用DOMContentLoad触发,懒加载
对DOM查询进行缓存(DOM操作很消耗性能),合并一起插入DOM结构
节流与防抖
5.2 知识点
SSR
服务器端渲染 - 将网页和数据一起加载渲染、
非SSR(前后端分离):先加载网页,在加载数据
图片懒加载
移步一下 - 关于图片懒加载问题 - 原理和实现_哆来A梦没有口袋的博客-CSDN博客_什么是图片懒加载 (写的超级详细,懒加载的原理和实现)
缓存DOM查询,多个DOM一次性插入
缓存DOM查询,在之前已经提过了,前面还有一道面试题,看过前面肯定有印象
防抖和节流
防抖和节流也是,写在了另外一篇 - 防抖和节流_哆来A梦没有口袋的博客-CSDN博客 (什么是防抖和节流,他们的区别和实现)
常考题
(1)var和let const的区别
var会存在变量提升,let和const没有变量提升,是es6的语法
var和let定义的变量可以修改,cosnt是定义了就不能更改
let和const是块级作用域
详细了解 - 关于ES6的 let 与 var_哆来A梦没有口袋的博客-CSDN博客
(2)列举强制类型转换和隐式类型转换
强制类型转换 - parseInt,parseFloat,toString,Boolean等方法
隐式转换 - ==, 做条件判断时,逻辑运算, +(拼接时候)
(3)手写深度比较,模拟lodash isEqual
利用递归,其实深度比较还可以直接转为值类型,JSON.stringify
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head><body><script>const obj1 = { a: 10, b: { x: 100, y: 200 }, c: 300 };const obj2 = { a: 10, b: { x: 100, y: 200 } };const obj3 = { a: 10, b: { x: 100, y: 200 } };function isObject(obj) {return typeof obj === 'object' && obj !== null}//深度比较两个引用类型的数据是否相同function isEqual(obj1, obj2) {//判断是否是对象if (!isObject(obj1) || !isObject(obj2)) {return obj1 === obj2}if (obj1 === obj2) {return true}//比较属性名的数量是否相同const obj1keys = Object.keys(obj1)const obj2keys = Object.keys(obj2)if(obj1keys.length !== obj2keys.length){return false}//以obj1为基准,与obj2进行比较for(let key in obj1){//比较当前属性值,递归比较const res = isEqual(obj1[key], obj2[key])//不相等if(!res){return false}}//全部循环都没有falsereturn true}console.log(isEqual(obj1, obj2))console.log(isEqual(obj2, obj3))</script>
</body></html>
(4)split()和join()的区别
split是拆分为数组,join是进行连接为字符串
'1-2-3'.split('-') //[1,2,3]
[1,2,3]'.join('-') //'1-2-3'
(5)数组的pop,push,unshift,shift分别是什么?
都会对原数组造成影响
pop是删除最后一个元素,返回的是删除元素
push数组末尾添加一个元素。返回的添加后的数组的长度
unshift是向数组的第一个添加元素,返回的添加后的数组的长度
shift是删除数组的第一个元素,返回的是删除的元素
(6)有哪些是数组的纯函数(不改变原数组,返回的是一个数组)
concat 连接数组
slice 截取数组
map 循环数组
filter 筛选
(7)[10,20,30].map(parseInt)返回的是什么?
[10, 20, 30].map((item, index) => {return parseInt(num, index) //Index 0,作为十进制处理,1,2不合法}) //[10,NaN,NaN]
(8)ajax的post和get的区别?
get传参参数是在是在地址栏,不安全,传递数据小,一般get用于查询操作
post一般是用于提交曹旭哦。易于防止CRSF
(9)事件代理和委托是什么?
(10)函数call和apply的区别?
前面其实已经提过了,他们只是传递参数不同的区别
fn.call(this, 1,2,3)
fn.apply(this, [1,2,3])
(11)闭包是什么?有什么特性?有什么影响?
闭包 - 嵌套函数使用了外部函数的变量
特性 - 闭包会保存值
影响 - 变量会常驻内存,得不到释放。
前面也详细的写过闭包,所以还不太清楚的,可以往前看看
(12)怎么阻止事件冒泡和默认行为?
e.preventDefault()
e.stopPropagation()
(13)解释jsop的原理,为何他不是真正的ajax?
ajax是XMLHttpRequest
jsop是通过script标签
(14)函数声明和函数表达式的区别?
function fn(){}
var fun = function(){}
函数声明会在代码执行之前预加载,函数表达式不会
(15)new Object()和Object.create()的区别?
{} 等同于new Object(),原型Object,prototype
Object,create(null)没有原型,Object,create({})指定一个原型
(16)this
(17)作用域和自由变量的场景题
for(let i = 1; i <= 3; i++){setTimeout(function() {console.log(i) }, 0)
}
打印出123
let a = 100;
function test(){alert(a)a = 10alert(a)
}test()
alert(a)
100,10,10
(18)判断字符串以字母开头,后面字母数字下划线,长度为6-30
const reg = /^[a-zA-Z]\w{5,29}/
(19)手写字符串trim,保证浏览器兼容性
String.prototype.trim = function(){return this.replace(/^\s+/, "").replace(/\s+$/, "")
}
(20)如何获取多个数字中的最大值
function max() {let arr = Array.prototype.slice.call(arguments);let max = arr[0];arr.forEach(item => {if(item > max){max= item}})return max
}max(10,20,30,40,5)Math.max(10,52,42,10)
(21)如何使用js实现继承
class继承,前面写过就不重复写了
(22)如何捕获js程序中的异常
try{}catch(err){} //手动捕获异常//自动捕获
window.onerror = function(message, source, lineNum, colNum, err) {}
//对于跨域的js,不会有详细的报错信息
//对于压缩的js,还要配合sourceMap反查到未压缩的行,列
(23)获取地址栏的参数
function query(name) {const search = location.search.substr(1);const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`, 'i') //&key=value&let res = search.match(reg)if(res === null){return null}return res[2]}function query2(name) {const search = location.searchcosnt p = new URLSearchParams(search); //注意兼容性问题return p.get(name)
}
(24)手写数组flatern,考虑多层级
var arr = [1,2, [3,4,50, [10,5]]] //将数组按顺序变为一维数组function flat(arr) {cosnt isDeep = arr.some(item => item instanceof Array)if(!isDeep){return arr}cosnt res = Array.prototype.concat.apply([], arr)return flat(res)}
(25)数组去重
let arr = [1,5,10,5,1,20]//第一种
[...new Set(arr)]//方法遍历
function unique(arr){cost res = []arr.forEach(item => {if(arr.indexOf(item) < 0){res.push(item)}})return res
}
(25)介绍一下RAF requestAnimationFrame
想要动画流畅,更新频率必须要60帧/s,即16.67ms更新一次视图
setTImeout要手动控制频率,而RAD浏览器会自动控制
后台标签或者隐藏在iframe中,RAF会暂停
#div {width: 100px;height: 100px;background: pink;}<div id = "div1">//已经引入jquery
<scirpt>//js把宽度从100px变为640px, 增加540px, 60帧/s, 3秒180帧, 每次变化3pxcosnt div1 = $("#div1")let curWidth = 100;const maxWidth = 640;//利用setTimeout来执行function animate(){curWidth = curWidth + 3;div1.css('width', curWidth)if(curWidth < maxWidth){setTimeout(animate, 16.7) //自己控制时间}
}</script>//利用requestAnimationFrame
<script>function animate(){curWidth = curWidth + 3;div1.css('width', curWidth)if(curWidth < maxWidth){window.requestAnimationFrame(animation) //浏览器自己执行}
}
</script>
写在最后:
其实代码面试还是很公平的,厉害的人就能进大厂,工资高
希望每个人都能有好的offer,其实对于答案,一开始很纠结是否要给出答案,因为其实在知识点里面已经包含了答案,纠结了很久,还是写了,觉得答案是一个参考吧,在面试过程中重要的是心态和对知识点的理解,其实问一个题,大多都是想了解你对这个知识点的掌握情况,因此在面试过程中要不仅仅是答题,要做衍生,结合自身的情况,将知识点讲的更透彻。码字不易,点个赞吧,哈哈~
相关文章:
初级前端面试题 - js
前言:众所周知,HTML,CSS,JS是学习前端所必备的。js的基础学好了,框架类的vue,react等都会接受的很快,因此js是前端很总要的一个部分,这篇文章将会结合面试题,对js的知识点进行总结 号外号外,这是…...
matlab的绘图的标题中(title)添加标量以及格式化输出
有时候我们需要在matlab绘制的图像的标题中添加一些变量,这样在修改某些参数后,标题会跟着一块儿变。可以采用如下的方法: x -10:0.1:10; %x轴的范围 mu 0; %均值 sigma 1; %标准差 y normpdf(x,mu,sigma); %使用normpdf函数生成高斯函数…...
51单片机——串口通信(重点)
1、通信 通信的方式可以分为多种,按照数据传送方式可分为串行通信和并行通信; 按照通信的数据同步方式,可分为异步通信和同步通信; 按照数据的传输方向又可分为单工、半双工和全双工通信 1.1 通信速率 衡量通信性能的一个非常…...
mapbox基础,style样式汇总,持续更新
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言二、🍀根属性2.1 so…...
用AI技术提升Flutter开发效率:ScriptEcho的力量
引言 在当今快速发展的技术时代,Flutter作为一种跨平台开发框架,正在越来越多的开发者中崭露头角。它不仅能够为开发者提供一套代码同时部署到iOS和Android平台的解决方案,还能帮助企业节省人力成本和开发时间。然而,对于新手开发…...
Java阶段四04
第4章-第4节 一、知识点 CSRF、token、JWT 二、目标 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验证和JWT验证的区别 学会使用JWT 三、内容分析 重点 理解什么是CSRF攻击以及如何防范 理解什么是token 理解什么是JWT 理解session验…...
vivado 时钟指南
时钟指南 每个 FPGA 架构都为时钟提供有专用资源。掌握 FPGA 架构中的时钟资源,使您能够规划好自己的时钟,从而实现时钟 资源的最佳利用。大多数设计无需您了解这些细节。但如果您能够控制布局,同时对每个时钟域上的扇出有良好的思 路&a…...
git项目提交步骤(简洁版)
1.创建仓库 2.填写 信息 3.点击这个按钮 4.找到要上传的文件,在目录内右键点击 5.依次执行命令 在命令窗口中输入:git init 复制仓库地址: 在命令窗口中输入:git remote add origin 仓库地址 在命令窗口中输入:…...
Jmeter-压测时接口如何按照顺序执行
Jmeter-压测时接口如何按照顺序执行-临界部分控制器 在进行压力测试时,需要按照顺序进行压测,比如按照接口1、接口2、接口3、接口4 进行执行 查询结果是很混乱的,如果请求次数少,可能会按照顺序执行,但是随着次数增加…...
模式识别-Ch5-线性判别函数
Ch5 线性判别函数 文章目录 Ch5 线性判别函数引言:生成模型 vs判别模型生成模型 vs 判别模型判别模型分类 线性判别函数与决策面线性判别函数两类情况下的决策多类问题下决策 多类情形-线性机器线性决策面优缺点 广义线性判别函数例:二次判别函数例1: 1-…...
数据结构二叉树-C语言
数据结构二叉树-C语言 1.树1.1树的概念与结构1.2树的相关术语1.3树的表示1.4树形结构实际运用场景 2.二叉树2.1概念与结构2.2特殊的二叉树2.2.1满二叉树2.2.2完全二叉树 2.3二叉树存储结构2.3.1顺序结构2.3.2链式结构 3.实现顺序结构的二叉树4.实现链式结构二叉树4.1前中后序遍…...
字节小米等后端岗位C++面试题
C 基础 引用和指针之间的区别?堆栈和堆中的内存分配有何区别?存在哪些类型的智能指针?unique_ptr 是如何实现的?我们如何强制在 unique_ptr 中仅存在一个对象所有者?shared_ptr 如何工作?对象之间如何同步…...
IOS HTTPS代理抓包工具使用教程
打开抓包软件 在设备列表中选择要抓包的 设备,然后选择功能区域中的 HTTPS代理抓包。根据弹出的提示按照配置文件和设置手机代理。如果是本机则会自动配置,只需要按照提醒操作即可。 iOS 抓包准备 通过 USB 将 iOS 设备连接到电脑,设备需解…...
renben-openstack-使用操作
管理员操作 (1)上传一个qcow2格式的centos7镜像 (2)管理员------>云主机类型------>创建云主机类型 名称:Centos7 VCPU数量:1 内存: 1024 根磁盘: 10G 其他的默认 点击创建云主机类型即可 界面会显示如下 创建公网络 (1)创建…...
HOW - Form 表单确认校验两种模式(以 Modal 场景为例)
目录 一、背景二、具体1. 模式一:点击确认进行校验提示2. 模式二:确认按钮依赖于表单内容实现说明 一、背景 基于react、antd form分别实现如下两种模式: 1、一个 Modal,点击确认进行校验提示2、一个 Modal,确认按钮…...
MATLAB算法实战应用案例精讲-【数模应用】图像边缘检测(附MATLAB和python代码实现)(二)
目录 前言 算法原理 相关概念 二值图像、灰度图像、彩色图像 邻接性、连通性 图像滤波 频率 滤波器 边缘检测算子:Sobel算子、Scharr算子、Laplacian算子、Canny算子 梯度计算 + 顶帽 + 黑帽 + 拉普拉斯金字塔 相位一致性(Phase Congruency,PC) 几种常见的算法…...
高考日语听力中常考2大类关键词
高考日语听力中,有些关键词的出现频率很高,同学们掌握这些关键词的读音和意思,可以提高听力答题的正确率,如时间类、地点类、天气类关键词……本文档为大家整理了干货,高考日语听力常考关键词,帮助同学们区分和积累常用词汇,记得要持续关注哦! 时间类关键词 1.星期 ∙…...
windows和linux的抓包方式
1.实验准备: 一台windows主机,一台linux主机 wireshark使用: 打开wireshark,这些有波动的就代表可以有流量经过该网卡,选择一张有流量经过的网卡 可以看到很多的流量,然后可以使用过滤器来过滤想要的流量…...
工业 4G 路由器赋能远程医疗,守护生命线
在医疗领域,尤其是偏远地区的医疗救治场景中,工业 4G 路由器正发挥着无可替代的关键作用,宛如一条坚韧的 “生命线”,为守护患者健康持续赋能。 偏远地区医疗资源相对匮乏,常常面临着专业医生短缺、诊疗设备有限等困境…...
《太阳之子》Build16524106官方中文学习版
《太阳之子》官方中文版https://pan.xunlei.com/s/VODabFuJ5gA7rCUACMulT5YGA1?pwdc47e# 集战术狙击、解谜与轻度潜行要素于一身,呈现独一无二的第三人称射击游戏体验。每关你只有一发子弹,但你可以进行在命中时重新瞄准、绕过障碍物、加速击穿护甲等操…...
shell-条件判断
目录 一、条件判断 1.按照文件类型进行判断 2.按照文件权限进行判断 3.两个文件之间进行比较 4.两个整数之间进行比较 5.字符串的判断 6.多重条件判断 二、if条件判断 1.单分支if条件语句 2.双分支if条件语句 (1)判断某文件是否存在 &#x…...
【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集
【TI毫米波雷达】DCA1000不使用mmWave Studio的数据采集方法,以及自动化实时数据采集 mmWave Studio提供的功能完全够用了 不用去纠结用DCA1000低延迟、无GUI传数据 速度最快又保证算力无非就是就是Linux板自己写驱动做串口和UDP 做雷达产品应用也不会采用DCA1000的…...
20250110_ PyTorch中的张量操作
文章目录 前言1、torch.cat 函数2、索引、维度扩展和张量的广播3、切片操作3.1、 encoded_first_node3.2、probs 4、长难代码分析4.1、selected4.1.1、multinomial(1)工作原理: 总结 前言 1、torch.cat 函数 torch.cat 函数将两个张量拼接起来,具体地是…...
【ROS2】☆ launch之Python
☆重点 ROS1和ROS2其中一个很大区别之一就是launch的编写方式。在ROS1中采用xml格式编写launch,而ROS2保留了XML 格式launch,还另外引入了Python和YAML 编写方式。选择哪种编写取决于每位开发人员的爱好,但是ROS2官方推荐使用Python方式编写…...
unity rb.velocity和transform.position
rb.velocity和transform.position是用来控制物体位置的两种方式,前者通常用来控制人物的移动,它们的主要区别和适用场景如下 一,rb.velocity(控制刚体的速度) 它可以直接控制物体的速度,而不是物体的位置…...
景芯SOC设计实战
终身辅导、一对一辅导,手把手教您完成SoC全流程设计,从入门到进阶,带您掌握SoC芯片架构、算法、设计、验证、DFT、后端及低功耗全流程!直播视频不定期升级!让您快速超越同龄人! 景芯团队主打文档服务器实战…...
【WRF运行报错】总结WRF运行时报错及解决方案(持续更新)
目录 ./real.exe错误1:ERROR while reading namelist physics./wrf.exe错误1:FATAL CALLED FROM FILE: <stdin> LINE: 2419 Warning: too many input landuse types参考./real.exe 错误1:ERROR while reading namelist physics 执行./real.exe时,报错如下: taski…...
Mysql快速列出来所有列信息
文章目录 需求描述实现思路1、如何查表信息2、如何取字段描述信息3、如何将列信息一行展示4、拼接最终结果 需求描述 如何将MySQL数据库中指定表【tb_order】的所有字段都展示出来,以备注中的中文名为列名。 实现思路 最终展示效果,即拼接出可执行执行…...
spring boot发送邮箱,java实现邮箱发送(邮件带附件)3中方式【保姆级教程一,代码直接用】
文章目录 Java发送邮箱的方式1. 基于 Javax.mail 实现关于附件上传的方法 2. 基于 org.apache.commons.mail 实现常见报错 3. 基于 spring-boot-starter-mail 实现(推荐) 实际开发时需要实现邮件发送,本文章实现如何从零实现邮件发送。也就是…...
数据集-目标检测系列- 电话 测数据集 call_phone >> DataBall
数据集-目标检测系列- 电话 测数据集 call DataBall 助力快速掌握数据集的信息和使用方式,会员享有 百种数据集,持续增加中。 需要更多数据资源和技术解决方案,知识星球: “DataBall - X 数据球(free)” 贵在坚持! …...
Zstandard压缩算法
简介 Zstandard(缩写为zstd)是一种开源的无损数据压缩算法,主要设计目标是提供高比率的压缩和快速的解压缩速度。它由Yann Collet开发,并于2015年首次发布。 特点 高比率的压缩(通常比gzip更好)。快速的解压缩速度(通常比gzip更快)。支持流式解压缩。可以选择不同的压…...
npm i 报错
nodejs中 使用npm install命令时报错 npm err! file C: \user\admin\package.json_package.json 里缺少 description 和 repository 两个n字段。-CSDN博客...
【LeetCode】力扣刷题热题100道(26-30题)附源码 轮转数组 乘积 矩阵 螺旋矩阵 旋转图像(C++)
目录 1.轮转数组 2.除自身以外数组的乘积 3.矩阵置零 4.螺旋矩阵 5.旋转图像 1.轮转数组 给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 class Solution { public:void rotate(vector<int>& nums, int k) …...
EFCore HasDefaultValueSql
今天小伙伴在代码中遇到了有关 HasDefaultValue 的疑问,这里整理澄清下... 在使用 Entity Framework Core (EFCore) 配置实体时,HasDefaultValue 方法会为数据库列设置一个默认值。该默认值的行为取决于以下条件: 1. 配置 HasDefaultValue 的…...
【数据结构】栈
目录 1.1 什么是栈 1.2 顺序栈 1.2.1 特性 1.3 链式栈 1.3.1 特性 总结: 1.1 什么是栈 栈是只能在一端进行插入和删除操作的线性表(又称为堆栈),进行插入和删除操作的一端称为栈顶,另一端称为栈底。 特点:栈是先进后出FILO…...
C++初阶—CC++内存管理
第一章:C/C内存分布 int globalVar 1; static int staticGlobalVar 1; void Test() {static int staticVar 1;int localVar 1;int num1[10] { 1, 2, 3, 4 };char char2[] "abcd";const char* pChar3 "abcd";int* ptr1 (int*)malloc(si…...
【机器视觉】OpenCV 图像基本变换
文章目录 介绍机器视觉的核心组成部分机器视觉的关键技术和趋势 4. 图像的基本变换4.1 图像的放大与缩小4.2 图像的翻转4.3 图像的旋转4.4 仿射变换之图像平移4.5 仿射变换之获取变换矩阵4.6 透视变换 介绍 机器视觉(Machine Vision)是一门跨学科的领域…...
【数据库】四、数据库管理与维护
文章目录 四、数据库管理与维护1 安全性管理2 事务概述3 并发控制4 备份与恢复管理 四、数据库管理与维护 1 安全性管理 安全性管理是指保护数据库,以避免非法用户进行窃取数据、篡改数据、删除数据和破坏数据库结构等操作 三个级别认证: 服务器级别…...
徐克版射雕唤醒热血武侠魂,共赴新春侠义之约
2025年大年初一,由徐克执导的古装武侠电影《射雕英雄传:侠之大者》将在影院拉开帷幕,在精彩纷呈的春节档电影中,“大IP”“大导演”“大场面”等标签让这部电影自定档起便备受关注,其精良的制作和传统中国武侠风的设定…...
设计模式(观察者模式)
设计模式(观察者模式) 第三章 设计模式之观察者模式 观察者模式介绍 观察者模式(Observer Design Pattern) 也被称为发布订阅模式 。模式定义:在对象之间定义一个一对多的依赖,当一个对象状态改变的时候…...
能量函数和能量守恒
在之前的文章1中讨论了与循环坐标相对应的动量守恒定律和动量矩守恒定律,本文将由拉格朗日方程中导出能量函数,进一步讨论能量守恒定律,并给出耗散系统的处理方法,这其中用到的一个关键数学定理是欧拉定理(描述如何将一…...
【pycharm发现找不到python打包工具,且无法下载】
发现找不到python打包工具,且无法下载 解决方法: 第一步:安装distutils,在CMD命令行输入: python -m ensurepip --default-pip第二步:检查和安装setuptools和wheel: python -m pip install --upgrade …...
使用 Maxwell 计算母线的电动势
三相短路事件的动力学 三相短路事件在电气系统中至关重要,因为三相之间的意外连接会导致电流大幅激增。如果管理不当,这些事件可能会造成损坏,因为它们会对电气元件(尤其是母线)产生极大的力和热效应。 短路时&#x…...
【Python】Python之Selenium基础教程+实战demo:提升你的测试+测试数据构造的效率!
这里写目录标题 什么是Selenium?Selenium基础用法详解环境搭建编写第一个Selenium脚本解析脚本常用的元素定位方法常用的WebDriver方法等待机制 Selenium高级技巧详解页面元素操作处理弹窗和警告框截图和日志记录多窗口和多标签页操作 一个实战的小demo步骤一&#…...
Ubuntu中批量重命名,rename
你可以使用下面的命令批量重命名这些文件,在文件名中插入 _1: 方式一 使用 mv 命令批量重命名 如果你已经在终端中,且当前目录包含这些文件,可以执行以下命令: mv ai.c ai_1.c mv ai.h ai_1.h mv ao.c ao_1.c mv a…...
LINUX 下 NODE 安装与配置
一、官网地址: (中文网)https://nodejs.cn/ (英文网)https://nodejs.org/en/ 二、下载安装包 2.1、下载地址:下载 | Node.js 中文网 https://nodejs.cn/download/ 2.2、使用 wget 命令下载到linux 服务器…...
Vue3 el-tree-v2渲染慢的问题
一、现象 使用el-tree-v2处理组织架构权限时,整个树的数据在8500条,勾选数据8200条,打开页面需要8~10秒,用户无法接受。 经调试,发现主要卡在树的渲染回显上(勾选数据少时,很快,勾选…...
【redis初阶】浅谈分布式系统
目录 一、常见概念 1.1 基本概念 2.2 评价指标(Metric) 二、架构演进 2.1 单机架构 2.2 应用数据分离架构 2.3 应用服务集群架构 2.4 读写分离/主从分离架构 2.5 引入缓存 ⸺ 冷热分离架构 2.6 数据库分库分表 2.7 业务拆分 ⸺ 引入微服务 redis学习&…...
模式识别与机器学习 | 十一章 概率图模型基础
隐马尔科夫模型(Hidden Markov Model,HMM) HMM是建模序列数据的图模型 1、第一个状态节点对应一个初始状态概率分布 2、状态转移矩阵A, 3、发射矩阵概率B 4、对特定的(x,y)的联合概率可以表示为 α递归计算——前向算法β递归…...
Linux基本指令(1)
一、ls指令 功能:对于目录,显示这个目录下的目录名以及文件名;对于文件,显示文件名 后面可接命令行选项配合使用,接选项时ls与选项以及选项与选项之间要有一个空格; 这里先学习了两个选项:-l…...