深信服单面

162 阅读6分钟

还是准备不够充分,即使是八股文,掌握的也不够熟练,稍微问深就答不上来了;

注重基础吧,项目要继续丰富

路由鉴权

主要思路:

前端携带用户身份信息(cookie、token)向后端请求用户的权限信息,不同的权限对应不同的路由,前端可以将这些数据储存在状态管理工具中,然后渲染在导航栏里;在进行路由跳转前,可以检查下我们存储的用户信息。如果没有登录就让用户登录,如果权限不足就提示下,重定向到其他页面。

实现方式:

用不同的框架可以有不同的实现方式,用vue可以使用vue-router的路由守卫实现,react的话可以封装一些高阶组件来实现

git是如何使用的

实习的时候常用的命令比较基本:主要是拉取、推送、还有分支,一般是一个功能创建一个分支,合并到主分支用拉取请求,如果出现冲突的话,就会把最新的代码重新拉取下来,在本地处理完冲突之后再重新提交

最好再多学习一下,只知道这些不太够用

什么是闭包,如何产生?除了返回函数

关于闭包面试题的坑:闭包与词法作用域密切相关,倘若答不上来两者之间的关系会被判定理解不足。另外,很多人对闭包存在误区,以为闭包就是那个特定的结构(返回的函数里有对外部变量的引用),但实则不然,这只是我们使用闭包的方法而已,不是闭包。

要说闭包,就要先说说JavaScript词法作用域了:

JavaScript的词法作用域

作用域:

作用域是指程序源码中定义的变量的访问规则————规定了如何查找变量,也就是确定了当前代码对变量的访问权限。

词法作用域:

就是代码在编写过程就体现出来的作用范围。代码一旦写好,不用执行,作用范围就已经确定好了,这个就是所谓的词法作用域。

与之相对的是动态作用域,函数的作用域是在函数调用的时候才决定的

作用域链:

当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链。

闭包

当代码执行的过程中会经过两个阶段——编译期和执行期

  • 编译期:这个过程会进行词法分析语法分析,然后生成可执行代码

  • 执行期:这个过程中会创建执行上下文,然后执行代码,最后垃圾回收

    创建执行上下文会做下面这些事:

    1. 创建内部变量对象

    2. 创建作用域链。

    3. 确定 this 指向。

    在创建作用域链的过程中,“闭包”就顺理成章的创建了,内部保存的就是对外部作用域中变量的引用。因此并不需要返回引用了外部变量的内部函数,闭包就已经创建了,但是返回之后,我们才可以拿到并使用。

一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包closure)。也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。

参考文章:从编译原理的角度彻底理解什么是闭包(Closure)

如何实现一个const,让它的属性也不能更改

用代理对象Porxy:只给get方法,set的时候直接返回不设置,或者报个警告

用类:将传入的普通对象储存在实例的属性上,给原型上加一个用于获取属性值的方法

用闭包:原理和类一样,用闭包创建私有空间保存变量,只返回访问属性的方法

事件循环:宏任务有哪些,微任务有哪些

单线程任务被分为同步任务和异步任务,在执行栈中,同步任务同步执行,异步任务会在异步任务有了结果后,将注册的回调函数放入任务队列中,并且会根据任务的类型(宏任务,微任务)进入不同的任务队列

微任务(micro task)

  • promise
  • async
  • await
  • process.nextTick(node)
  • mutationObserver(html5新特性,用于监听dom树事件)

宏任务(macro task)

  • script(整体代码)
  • setTimeout、setInterval定时器
  • setImmediate
  • I/O
  • UI render

vue组件通信方式

  • props
  • emit
  • v-model
  • refs
  • provide/inject
  • eventBus全局事件总线,Vue3中是mitt,但是不推荐使用
  • vuex/pinia(状态管理工具)

vuex解决了哪些问题

组件间数据的共享

cjs和ems,在编译上有什么区别

CommonJS

  • cjs是靠js运行时来实现的。
  • 只导出一个属性——module,并且导入的时候导入的是值的拷贝。
  • 动态加载,通过对每一个加载都存在缓存,有效的解决循环引用问题。
  • 同步加载并执行模块。
  • 默认非严格模式。

ES Module

  • 静态导入,不能放在块级作用域内,导入过程发生在编译时,因此很容易实现 Tree Shaking。
  • 可以导出多个属性和方法,可以单个导入导出,混合导入导出。
  • 模块提前加载并执行模块文件。并且导入的是值的引用,如果发生循环引用,引用了未被初始化的变量会报错。
  • 使用顶层 await 设计。因此cjs可以使用import()引入,但是引入的方法还是拷贝。
  • 默认严格模式。

参考文章:「万字进阶」深入浅出 Commonjs 和 Es Module

vue自定义指令,什么时候用比较好

编程题:查找树上的一个节点,不用for循环和forEach怎么做(数组的其他方法)

说了用栈模拟递归,面试官说用数组的其他方法就好了

想了用reduce,面试官说这样是把简单的事情搞复杂了

应该是用find,但是完全没想起来这API......

编程:用Promise实现一个sleep函数

css:垂直水平居中

  • 用flex很容易实现水平居中,垂直居中
  • 用table布局也很容易实现
  • 再有可以考虑用前后伪元素来实现水平居中
  • 或者直接用自动的左右外边距把两边填满
  • 用绝对定位定到50%的位置,或者用边距顶到50%上,再用 transform 把位置调整回来