面试题
文章平均质量分 53
Always--Learning
选择远远大于努力
展开
-
这一次,彻底梳理各种布局问题
这种方式会使得超出的元素隐藏,对行内元素无效,必须是块级元素,隐藏之后元素依然占据着位置。这种方式会使得元素的透明度为0,隐藏,但是位置依然占据着。这种方式会使得元素不存在,但是占据的位置依然存在。这种方式会使得元素不存在,占据的位置也不存在。...原创 2022-07-20 20:43:54 · 724 阅读 · 1 评论 -
CSS元素隐藏的方式与区别
这种方式会使得超出的元素隐藏,对行内元素无效,必须是块级元素,隐藏之后元素依然占据着位置。这种方式会使得元素的透明度为0,隐藏,但是位置依然占据着。这种方式会使得元素不存在,但是占据的位置依然存在。这种方式会使得元素不存在,占据的位置也不存在。...原创 2022-07-15 18:21:51 · 1614 阅读 · 0 评论 -
LeetCode——226. 翻转二叉树(BFS)
二叉树镜像和反转二叉树是一个题目,总的来说通过BFS可以高效的解决这个问题。原创 2022-06-24 10:06:37 · 596 阅读 · 0 评论 -
LeetCode——二叉搜索树的第k大节点(借助中序遍历)
二叉搜索树的第K大节点是一个很好的题目,我原本想的是直接对二叉搜索树进行遍历,然后进行排序,然后返回第K大的节点,但是这样做显然是没有利用二叉搜索树的特点,尤其是没有利用二叉搜索树进行中序遍历的特点,只要知道了二叉搜索树的中序遍历的特点,便可迎刃而解。...原创 2022-06-20 10:22:57 · 413 阅读 · 1 评论 -
LeetCode——138. 复制带随机指针的链表(借用map实现复制)
复杂链表的复制看起来挺难的,但是实际上只要能够想到通过map这个数据结构来辅助我们进行复制,便可以极大的降低问题的复杂度,假如不借助map,直接在链表本身进行操作的话,我们不仅要考虑next指针还要考虑random指针,困难程度可想而知,所以能否想到借助map是本题的破题核心。...原创 2022-06-18 22:29:14 · 257 阅读 · 0 评论 -
嵌套数组反转(递归)
首先,最长递增子序列,中的序列二字如何理解,序列值得是可以不连续的,也就是说我们的代码只要能够找到给定数组中的最长递增的一组数即可,其实这类题目的本质就是考察动态规划,当前元素之前的最长递增子序列加上当前就是最长递增子序列,这也是整个动态规划的核心,因此,要想搞懂动态规划,必须深刻理解动态方程,理解dp[i]的含义,尤其是当我们拿到一个新题目没有思路的时候,就可以去理解动态方程的含义,然后跟着代码走一遍流程便可以理解这个题解。类似的题目还有很多,动态规划是面试中必考题之一,同时工作中也经常需要用到他们,动态原创 2022-06-15 10:34:34 · 494 阅读 · 0 评论 -
LeetCode——300. 最长递增子序列(动态规划)
首先,最长递增子序列,中的序列二字如何理解,序列值得是可以不连续的,也就是说我们的代码只要能够找到给定数组中的最长递增的一组数即可,其实这类题目的本质就是考察动态规划,当前元素之前的最长递增子序列加上当前就是最长递增子序列,这也是整个动态规划的核心,因此,要想搞懂动态规划,必须深刻理解动态方程,理解dp[i]的含义,尤其是当我们拿到一个新题目没有思路的时候,就可以去理解动态方程的含义,然后跟着代码走一遍流程便可以理解这个题解。类似的题目还有很多,动态规划是面试中必考题之一,同时工作中也经常需要用到他们,动态原创 2022-06-14 10:27:46 · 255 阅读 · 0 评论 -
LeetCode——24. 两两交换链表中的节点(三指针)
链表类的题目看似简单,其实不然,有很多链表的题目还是很烧脑的,尤其是光想不去动手画,很多思路只要动手画,很快就知道怎么做的,但是纯在脑子中想很难想明白,因此一定要画图。类似的题目还有很多,例如反转链表,K个一组翻转链表都是面试中的常考题....原创 2022-06-10 12:15:10 · 904 阅读 · 0 评论 -
LeetCode——42. 接雨水(双指针)
接雨水面试必考原创 2022-06-09 09:55:22 · 1026 阅读 · 0 评论 -
LeetCode——113. 路径总和 II(DFS)
题目描述解题思路DFS是解决这个问题的核心思路。首先判断传入的节点是否为空,如果为空,则返回空数组。定义DFS函数(节点,某条路径上剩余的和,临时数组)进入DFS函数就让临时数组收录当前节点的值。如果当前节点是叶子节点,并且剩余和与当前的值一致,则将临时数组放入结果数组中。如果左子节点存在就让左子节点,新的剩余和,临时数组的副本进入DFS函数。如果右子节点存在就让右子节点,新的剩余和,临时数组的副本进入DFS函数。AC代码var pathSum = function(root,原创 2022-05-30 18:15:41 · 296 阅读 · 0 评论 -
扫码登录的原理你真的了解吗?
为什么要了解扫码登录的原理?通过扫面二维码进行登录已经成为了一种常见的登录方式,这种方式可以在不输入用户名和密码的情况下快速的实现登录,其背后涉及到PC端、移动端和服务端三者之间的交互,无论是对前端开发者还是后端开发者而言,掌握了扫码登录的原理都可以很好的帮助我们设计一套登录机制为我们自己的应用服务。扫码登录的主要阶段阶段1:待扫描阶段待扫描阶段是PC端和服务端交互的过程,主要包括以下几个步骤:PC端携带着自身的设备信息,向服务端发送一个请求获取二维码信息。服务端生成一个唯一的二维码I原创 2022-04-23 07:31:51 · 1477 阅读 · 0 评论 -
Rem布局是如何实现响应式的?
从一个实际例子来看Rem布局是如何实现响应式的首先rem是一个相对单位,指的是相对于根元素html的font-size的大小,假如根元素font-size大小为16px,那么1rem就是16px,2rem就是32px,但是px是一个绝对单位,如果我们将根元素的font-size设置为一个绝对单位,那么是无法实现响应式布局的,因此,我们可以给根元素的font-size的大小设置为一个动态单位vw。给根元素的font-size指定为动态单位vw请看下面的例子:/* 100vw -->原创 2022-04-20 15:55:04 · 930 阅读 · 0 评论 -
null和undefined你还分不清?
基本数据类型有哪些?在介绍null和undefined的区别之前,首先介绍下JS的基本数据类型有哪些?undefinednumberbooleanstringbigintsymbolnull从上面的基本类型我们可以看出,null和undefined同为基本数据类型,那么下面我们来探讨一下他们之间有什么区别~undefinedundefined表示的是一个变量最原始的状态值,未定义的状态值,而非人为操作的结果。应用场景一:没有被赋值的变量let test;conso原创 2022-04-19 15:06:04 · 393 阅读 · 0 评论 -
多维数组的全排列问题
什么是多维数组的全排列问题?为了更好的说明这个问题,请看下面的这个题目。题目有什么特点?输出的结果并不是完全乱序的,从输入的顺序也可以看出二维数组中第一个数组的顺序大于第二个,第二个则大于第三个。后一个结果依赖于前一个结果。代码实现const permutate = (arr) => { // res为第一个数组 let res = arr[0].slice(); // 从第二个数组开始遍历 for (let i = 1; i < arr.原创 2022-04-18 10:10:34 · 460 阅读 · 0 评论 -
手写reduce方法
手写常用的数组方法是面试中的常考题目,同时学会这些API的原理也能更好的帮助我们去理解这些API并加运用,下面让我们来一起手写reduce吧~原生reduce接收几个参数?原生的reduce是在Array的原型对象上的一个方法,其接收两个参数:一个回调函数。这个回调函数的前两个参数,分别表示累积值和当前值。初始值。实现原生reduce的思路通过slice原型方法获取到调用reduce的数组。定义一个临时结果变量和开始的索引。如果传入了初始值,res就等于这个初始值,没有传入re.原创 2022-04-18 08:00:10 · 1775 阅读 · 1 评论 -
观察者模式和发布订阅者模式不是一回事?
什么是观察者模式?观察者(Observer)直接订阅(Subscribe)主题(Subject),而当主题被激活的时候,会触发观察者里的事件。观察者模式的代码实现// 被观察者class Subject { constructor(name) { this.state = '开心'; // 存储所有的观察者 this.observers = []; } // 收集所有的观察者 attach(o) {原创 2022-04-17 07:28:05 · 356 阅读 · 0 评论 -
为什么var可以重复声明?
请先看一段代码下面的这段代码输出的是undefined吗?var haha = '666';var haha;console.log(haha);上面的这段代码实际输出的是666,而不是undefined,这是为什么呢?为什么var又可以重复定义呢?var为什么可以重复定义?我们首先介绍下JS代码的运行机制:引擎负责整个代码的编译和执行。编译器负责语法分析、词法分析、代码生成等。作用域负责维护所有的标识符变量。编译器在对代码进行拆解的时候,遇到了var定义的变量会原创 2022-04-16 15:51:44 · 990 阅读 · 0 评论 -
JS模块化演变及其区别
为什么需要模块化?假如没有模块化,在前端开发时可能存在下面的问题:变量和方法不容易维护,容易污染到全局作用域。通过script标签进行大量引入资源,代码可读性和可维护性都比较差。代码一多就比较复杂。多人合作的场景下,资源的引入会带来比较大的困难。JS模块化的演变史1. CommonJS我们熟知的Node.js在模块化方面就是遵守的CommonJS规范。CommonJS模块化具有下面几个特点:模块内的代码运行在模拟作用域中,不会污染到全局作用域中。模块可以多次引入,但只会在第原创 2022-04-16 06:57:07 · 440 阅读 · 0 评论 -
你知道原型链?那你能实现一个new吗?
在学习前端知识的时候,我们不仅要会用工具和API,更要知道其实现原理,因为只有知道原理,我们的理解才能更上一层楼,这次让我们来一起解决最常见的new的实现原理吧。new在原型链中扮演什么样的角色?在this的指向规则中,有一种this指向是new绑定,new绑定会让构造函数的this指向我们新创建的对象,请看下面的例子:function sayHi(name){ this.name = name;}var Hi = new sayHi('zhangsan');console.log.原创 2022-04-15 07:37:34 · 305 阅读 · 0 评论 -
OSI七层网络模型,你了解多少?
OSI七层模型具体指的是哪七层?从底到上分别是:物理层数据链路层网络层传输层会话层表示层应用层每一层主要负责什么?都有什么协议?物理层物理层主要规定通信设备的电气特性,用以建立物理链路连接,例如规定了设备的规格尺寸、引脚数量和排列情况等,电气特性规定了物理连接上传输bit流时信号电平的大小、传输速率等,核心作用就是负责传输0和1的电信号。数据链路层数据链路层在物理层提供比特流的基础上,通过差错控制提供数据帧在信道上无差错的传输,这一层确定了0和1的分组方式。数原创 2022-04-13 10:11:40 · 2018 阅读 · 0 评论 -
Promise的异常捕获问题
Promise根据异常出现的位置不同采取的方案也不同Promise内部抛出异常通过then的第二个函数来捕捉异常。// Promise的异常捕获问题const promise = new Promise((resolve,reject) => { throw new Error('test')})// 通过then的第二个函数来进行捕捉promise.then(res => { console.log(res);},err => { conso原创 2022-04-11 14:48:53 · 1800 阅读 · 0 评论 -
Vue中的v-if和v-for为什么不能一起用?
假如v-if和v-for一起使用会出现什么情况?<ul> <li v-for="(item,index) in arr " v-if="flag" :key="index" > {{item}} </li></ul>一起使用,会出现下面的错误提示:为什么不能一起使用?因为v-for的优先级比v-if的优先级高,所以如果嵌套使用的话,每次v-for都会执行一次v-if,造成重复计算的问题,会影响性能,所以vue官方不推荐这样原创 2022-04-10 16:38:10 · 2215 阅读 · 0 评论 -
for...in和for....of的区别是什么?
核心区别:获取的内容不同for…in主要获取对象的key和数组的下标,同时for…in还能够遍历原型链上的可枚举属性。for…of主要获取对象的value值。const obj = {'a' : '111','b':'222'};for (let key in obj) { console.log(key); // a b}// 没有部署原生的iterator接口的对象不能直接遍历for (let value of Object.keys(obj)) { consol原创 2022-04-10 14:48:00 · 291 阅读 · 0 评论 -
这一次,彻底搞懂Vue中的keep-alive
keep-alive的使用场景及其特点用于Vue性能优化。缓存组件。频繁切换,不需要重复渲染。keep-alive有include和exclude属性,这两个属性决定了哪些组件可以进入缓存。keep-alive还有一个max属性,通过它可以设置最大缓存数,当缓存的实例超过max的时候,vue会删除最久没有使用的缓存,属于LRU缓存策略。keep-alive其内部所有嵌套的组件都具有两个生命周期钩子函数,分别是activated和deactivated,它们分别在组件激活和失活的时候触发。原创 2022-04-10 14:17:40 · 1808 阅读 · 0 评论 -
LeetCode——简化路径(辅助栈)
题目描述解题思路核心的解题思路就是借助一个栈来辅助我们,遇到空字符串和一个点的则跳过,遇到两个点的则出栈。AC代码var simplifyPath = function(path) { // 简化路径的核心就是借助辅助栈 const stack = []; // 分割字符串 const strArr = path.split('/'); // 遇到空字符串和一个点的直接跳过 // 遇到两个点则出栈 const res = [];原创 2022-04-10 07:15:45 · 616 阅读 · 0 评论 -
你了解Vue的动态加载组件和异步加载组件吗?
如何动态加载组件?引入可能被使用的组件import slotDemo from './components/slotDemo'import HelloWorld from './components/HelloWorld'通过动态属性is来读取组件名<component :is="comName"/>如何异步加载组件?通过import在注册组件的时候引入组件components: { FormDemo: () => import(`../xxxCo原创 2022-04-09 17:07:31 · 703 阅读 · 0 评论 -
Vue的作用域插槽slot有什么用?
一、基本使用由父组件向子组件中传递数据,子组件通过slot进行接收,不传递则显示的是默认的内容。父组件<template> <div id="app"> <slotDemo :url="website.url"> {{website.title}} </slotDemo> </div></template><script>import slotDemo from原创 2022-04-09 15:02:03 · 565 阅读 · 0 评论 -
浅析Vue中$nextTick的原理
一、$nextTick有什么用?Vue是异步渲染的框架。data改变之后,DOM不会立刻渲染。$nextTick会在DOM渲染之后被触发,以获取最新的DOM节点。连续多次的异步渲染,$nextTick只会执行最后一次渲染后的结果。二、$nextTick的原理$nextTick主要通过事件循环中的任务队列的方式异步执行传入的回调函数,首先会判断当前的执行环境是否支持Promise,MutationObserver,setImmediate,setTimeout。如果支持则创建对应的异步方法,原创 2022-04-09 10:51:05 · 3488 阅读 · 0 评论 -
你真的了解Vue的生命周期吗?
Vue生命周期的主要阶段创建前后beforeCreate:实例刚在内存中被创建出来,此时还没有初始化好data和methods属性。created:实例已经在内存中创建好,此时data和methods已经创建好,此时还没有开始编译模板。载入前后beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面上。mounted:此时已经编译好模板,并挂载到了页面指定的容器中。更新前后beforeUpdate:状态更新之前执行这个函数,此时data中的状态值是最新的,但是界面上显原创 2022-04-09 07:11:20 · 405 阅读 · 0 评论 -
Vue中的methods、watch、computed、filters到底有什么区别?
一、methodsmethods中存放的是事件的回调函数,具有以下几个特点:可以通过Vue实例访问方法,在方法中最好不要使用箭头函数,因为涉及到this指向的问题。重新渲染的时候,methods总会执行该函数。methods是函数调用,filters和computed、watch是属性调用。methods是不具有缓存性的。二、filtersfilters一般用于格式化输出的场景,比如日期格式化,filters过滤器可以进行串联调用,所以可以定义一些基础的filters,然后按需在组件原创 2022-04-07 16:34:45 · 994 阅读 · 0 评论 -
LeetCode——回文数(反转比较)
题目描述解题思路思路一:反转比较法回文数的一个特点是正着读和倒着读是一样的,那么我们可以定义一个临时变量来存储目标元素的反转,然后顺序比较每个元素是否相等,相等则返回true,反之false。var isPalindrome = function(x) { // 使用反转对比的方法来判断是否是回文数字 x = x.toString(); const temp = x.split('').reverse(); const xArr = x.split(''); for (l原创 2022-04-06 07:36:40 · 311 阅读 · 0 评论 -
手写函数柯里化
什么是函数柯里化?函数柯里化主要用于给函数分步传递参数,每次传递参数进行处理,并返回一个更具体的函数来接受剩下的参数,这中间可以嵌套多层,直至返回最后的结果。实现思路接收一个处理数据的函数。定义一个数组用于接收所有的参数。返回一个函数,如果返回的函数接收的参数的长度是0,则返回fn执行的结果,如果不是0,则将参数push进数组中,并返回函数。代码实现// 手写函数柯里化const curring = function(fn) { const args = []; re原创 2022-04-05 19:50:33 · 1025 阅读 · 0 评论 -
你知道多少种判断数据类型的方法?
方式一:通过constructor通过constructor可以直接找到元素的构造函数类型,这种方法能够区分引用数据类型到底是哪种类型,请看下面的例子。const arr = [1,2,3,5];const date = new Date();const num = 666;const map = new Map();const set = new Set();const reg = new RegExp();const str = '111';const sym = Symbol(6原创 2022-03-30 16:02:15 · 2755 阅读 · 0 评论 -
这一次,彻底搞懂Vue的组件通信
前言vue的组件通信无论是在工作中还是在面试中都是经常考到的知识,这一次让我们一起来系统的梳理下Vue的组件通信都有哪些方式吧~一、父组件向子组件进行传值核心:通过props就行传递。在父组件中引入子组件。通过在子组件的标签上进行传递。子组件中通过声明props进行接收。二、子组件向父组件传值核心:通过this.$emit('父组件中的函数名',传递参数)父组件给子组件绑定函数。子组件通过this.$emit出发父组件给子组件绑定的函数。三、子组件通过$parent来获取父原创 2022-03-30 10:32:08 · 418 阅读 · 0 评论 -
关于数组去重,你知道多少种方案?
方式一:通过Set// 借助Set实现数组去重const arr = [2,3,5,6,8,6,8,2,9];const unique = [...new Set(arr)]console.log(unique); // [2,3,5,6,8,9]方式二:通过对象首先让待去重的数组的每个元素在对象中key和value相等,如果已经存在的情况下,通过splice对数组进行删除,此时需要注意下标的变化。// 通过对象实现数组去重const arr = [2,3,5,6,8,6,8,2,原创 2022-03-22 19:59:16 · 736 阅读 · 0 评论 -
使用reduce实现数组扁平化
实现的目标使用数组原生的API,reduce来实现flat,又叫数组拍平。下面是一个数组拍平的例子:[1, [[2], 3, 4], 5] --> [1,2,3,4,5]原生flat具有的特点原生flat每调用一次,数组的维度减少1,多维数组在这种情况时可能处理起来很麻烦,无法一次性的边多维数组变为一维数组,比如下面这个例子。const arr = [1, [[2], 3, 4], 5];console.log(arr.flat()); // [1,[2],3,4,5原创 2022-03-19 09:50:26 · 2330 阅读 · 1 评论 -
使用reduce实现map
原生map方法的特点map不会对原数组产生影响。map返回的是一个新数组。一个数组一旦调用map方法,每一个元素都会执行map中的回调函数。map方法会跳过被delete删除或者未定义的元素。原生map接收的两个参数都有什么用?第一个参数:callbackmap接收的第一个参数是一个回调函数,这个参数是必须传入的,callback中有三个可选参数,分别代表着元素,索引和调用map方法的数组,也就是(item,index,arr)。第二个参数:thisArg(定义执行callback的原创 2022-03-17 09:40:29 · 653 阅读 · 0 评论 -
浏览器的渲染原理你了解吗?
从整体上看浏览器的渲染流程浏览器的渲染流程主要包括以下几个流程:解析HTML,生成DOM树,解析CSS,生成CSSOM树。将DOM树和CSSOM树进行结合,生成渲染树(Render Tree)。根据生成的渲染树,进行回流(Layout),得到节点的几何信息(位置,大小)。根据渲染树以及回流得到的几何信息,得到节点的绝对像素。将像素发送给GPU,展示在页面上。一、生成DOM树首先,浏览器会从内存或者网络中读取出HTML文件的二进制数据,然后将其转换为字符串,然后转换为Token。T原创 2022-03-14 10:17:33 · 672 阅读 · 0 评论 -
这一次,彻底搞懂进程与线程之间的联系
什么是进程?进程是系统进行资源调度和分配的基本单位,每个进程都有自己独立的一块内存空间,在Windows系统中,一个运行的exe程序就是一个进程。什么是线程?线程是进程的子任务,是CPU调度和分配的基本单位,用于保证程序的实时性,实现进程内部的并发,线程是操作系统可以识别的最小执行和调度单位,线程之间共享同一块地址空间。进程和线程的区别根本区别:进程是操作系统进行资源调度和分配的基本单位,而线程是CPU进行资源调度和分配的基本单位。从资源开销上讲:每个进程都有自己的内存空间,进程之间切原创 2022-03-13 13:42:30 · 747 阅读 · 0 评论 -
这一次,一起来了解下position的盲区
为什么要了解position?学习这个知识之前,我们首先要知道为什么要学习这个知识点,position不仅是面试中的常考点,很多CSS布局中也是不可获取的一种方案,因此我们必须熟练掌握这个知识。Position有哪些属性?1. 静态定位static静态定位指的是目标元素使用正常的布局,也就是按照元素在文档流中的默认位置进行排列布局,此时设置top、right、bottom、left和z-index属性是无效的。2. 相对定位relative相对定位是相对元素未添加定位时的位置进行移动,原创 2022-03-12 17:22:28 · 544 阅读 · 0 评论