• 【面试题】前端面试真题 年前端面试


    a公司

    • (√)自我介绍
    • (√)是否在职;离职原因;未来团队期待,主要看中啥
    • (√)职业规划,发展方向
    • (√)关注的前端方向:vue3;ts;vite;小程序
    • (√)深拷贝和浅拷贝的区别,实现方式有哪些;

    deepClone 手写递归,具体实现方式,特别数据的边界处理(时间,function,正则);如何解决循环引用的问题,处理方式,判断条件终止,deepClone 如何终止的?

    1. export function deepClone(obj, hash = new WeakMap()) {
    2. // 处理null或者undefined
    3. if (obj === null) return obj;
    4. // 处理日期类型
    5. if (obj instanceof Date) return new Date(obj);
    6. // 处理正则类型
    7. if (obj instanceof RegExp) return new RegExp(obj);
    8. // 普通值或函数不需要深拷贝
    9. if (typeof obj !== "object") return obj;
    10. // 对象进行深拷贝
    11. if (hash.get(obj)) return hash.get(obj);
    12. let cloneObj = new obj.constructor();
    13. // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
    14. hash.set(obj, cloneObj);
    15. for (let key in obj) {
    16. if (obj.hasOwnProperty(key)) {
    17. // 实现一个递归拷贝
    18. cloneObj[key] = deepClone(obj[key], hash);
    19. }
    20. }
    21. return cloneObj;
    22. }
    23. 复制代码
    • (√)防抖和节流的区别,使用场景;如何选择使用防抖和节流,用户体验和用户操作来区分吧;防抖的实现过程,具体实现方式,例如定时器
    • (√)ES6 常用属性
    • (√)Promise 解决地狱回调的问题;async/await 使用,异步过程同步化;
    • 一个接口+一个事件监听返回结果,实现同步的封装,onbus,具体流程,用一个 promise 解决
    • (√)http 协议的理解:1.0,1.1,2.0,3.0 的区别;强缓存和协商缓存,etag 详细,if-modify-since 详细,两者的优先级
    • (√)网络安全:xss,csrf(具体实现方式),sql 注入;防止 token 或 cookie 被窃取的方式(https 或者安全域名限制);
    • (√)vue 响应式原理:观察者订阅者模式,2.0 是 defineProproty;3.0 是 proxy
    • (√)虚拟 dom 原理
    • (√)diff 算法基于啥算法实现的,原理
    • (√)vue 组件传值方式,兄弟组件的传值
    • created 为啥不能用箭头函数定义?this 指向不对;如果用箭头函数定义,this 是啥值
    • (√)前端性能优化思路,具体实现

    b公司

    • 一面
      • (√)自我介绍,离职原因
      • (√)前端期间,印象深刻的问题
        • H5 兼容性问题,头部兼容性处理(H5 头部,混合 APP 头部,微信头部,刘海屏,华为内嵌键盘)
        • 定制化组件开发:改源码;基于组件本身,二次开发;造轮子,重写
        • 虚拟列表功能实现
      • (√)浏览器
        • 从输入 url 到浏览器渲染经过了哪些流程
        • 强缓存,协商缓存;两种方案优势缺点;分别使用情况,使用条件
      • (√)nexttick 实现原理,怎么实现 dom 循环完之后回调(Promise.then、MutationObserver、setImmediate、setTimeout)
      • (√)js 事件循环机制
      • (√)前端性能优化,如何做的
      • (√)写博客,最近写了些啥
      • (√)看书吗,看啥技术视频
      • (√)webpack 个性化配置:拆包;less,sass 处理;打包加速优化;dll plugins;图片资源压缩
    • 二面
      • (√)自我介绍
      • (√)离职原因
      • (√)H5 混合开发
      • (√)性能优化处理
      • (√)最近做的项目,做的啥,介绍项目

    c公司

    • (√)呆过的公司的团队规模介绍,前端人员规模,自己承担的职责
    • (√)前端性能优化:具体实现,优化指标等,骨架屏优化;减少重排或者重绘等(骨架屏,图标 resize,v-show 的处理)
    • (√)白屏时间的计算,优化的衡量指标,如何评价优化好与不好,优化结果对比等等
    • (√)比较关注的性能指标:包大小,请求数量,浏览器缓存合理使用,页面渲染阻塞情况
    • (√)对自己简历写的东西要熟悉,也要能扛得住问,问的时候会一步一步的深度挖掘,提问
    • 动画,做的比较少,也没啥好说了
    • 如何衡量组件封装的好与不好:扩展性;如何设置扩展性比较好(预留插槽);
    • code view,代码审核,看别人的代码;组件的分层和分治
    • 测试脚本,边界测试衡量
    • 写过 react native,感觉咋样,哪些比较难:底层 java 编写;用的比较多的,图表和列表
    • (√)uniapp 写过一些,小活动
    • (√)最近在写 vite,ts,学习啥新的技术
    • (√)webpack 的版本,相关配置,对 webpack 的理解
    • (√)tree shaking 的实现,如何实现的,import/export
    • 最棘手的问题:兼容性问题,你的手机没问题,他的有问题;怎么解决,模拟用户问题的情况,看日志查,错误处理系统;效率高吗?
    • 封装,提升效率的方式:组件封装,公共函数封装(时间格式化等),公共功能封装(分享,登陆等),引入新的工具或技术(sass)提升效率;
    • 写打包的脚本,优化打包发布脚本啥的:应该是运维写的吧,jenkins

    d公司

    • 一面
      • 自我介绍
      • html header 头部标签;rem 实现,一般 H5 使用,PC 没咋使用(media);
      • (√)两栏布局实现:flex;定位;grid;float 布局(右边能自适应嘛)
      • (√)flex: 1 代表啥(1 0 width);
      • (√)H5 项目:抽取公共样式,引入 sass,实现方案;css name 的规范;不同颜色主题包的实现方案
      • (√)项目难点:封装哪些组件?你的上传和默认的上传有哪些区别?封装过程中,如何设计组件?透传 props 如何做的,默认组件的参数如何处理的,$attr
      • (√)大数据性能渲染问题:分页加载,虚拟 dom 实现;接口处理,相当于避开了问题;虚拟列表,可以承受几万条
      • (√)性能优化,白屏的处理:百度统计优化(defer,async);缓存(强缓存,协商缓存),CDN,CDN 返回的响应头;优化工具,分析工具;
      • (√)koa 写过服务端嘛
      • (√)复杂的权限管理如何实现的(菜单权限,角色权限,路由权限,页面内部权限);权限的封装(and 和 or 多条件处理);有没有统一的权限处理
      • (√)vue3.x 和 2.x 区别,体验:Composition API;TypeScript 优点,解决了哪些问题
      • 什么逻辑适合放在 Composition API;什么适合放在页面
      • (√)vuex 用过吗?组件内部,公共变量函数啥的
      • vite,webpack,babel 看过源代码吗?看过相关的书,如 js 红宝书?js 如何学的
      • JS 实现:菜单 ul,li,li 的第三项点击实现字体变为红色;querySelectAll(),返回对象,[0]是数组;
      • js 如何判断是不是数组:Array.isArray(arr);arr instanceof Array;Object.prototype.toString.call(arr) === '[object Array]'
      • 你比较擅长的是啥?PC 端和 H5 主要差异是啥?
      • uniapp 跨端方案如何
      • 周边生态(webpack,nodejs,sass,babel)等熟悉源码,做二次开发,还是只是单纯使用
    • 二面
      • 自我介绍
      • 团队有哪些成长,吸收了哪些营养
      • 写代码:求平均数
    1. // 求平均时间
    2. var arr = ["8:01", "9:30", "11:50"];
    3. const average = (arr) => {
    4. let minutes = 0;
    5. arr.forEach((o) => {
    6. let a = o.split(":");
    7. minutes = minutes + a[0] * 60 + parseInt(a[1]);
    8. });
    9. minutes = minutes / arr.length;
    10. let hour = Math.floor(minutes / 60);
    11. let minute = minutes - 60 * hour;
    12. console.log(hour, "...", minute);
    13. return `${hour}:${minute}`;
    14. };
    15. console.log(average(["8:01", "9:30", "11:50"])); // 9:47
    16. 复制代码

    感谢评论区[MoTou]提供的如下方法,更加简洁:

    1. var arr = ['8:01', '9:30', '11:50']
    2. let res = 0
    3. arr.forEach(el => {
    4. res += new Date('2000/01/01 ' + el).getTime()
    5. })
    6. const a = new Date(res / arr.length)
    7. console.log(`${a.getHours()}:${a.getMinutes()}`)
    8. 复制代码
    • (√)浏览器打开页面:cookie 的理解;domain(域名,顶级域名), path, expires(session), http-only
    • 接口服务端定义的:接口文档,沟通交流;后端定义接口不规范咋办?数据的处理由前端,还是后端处理;如何定义规划的
    • 封装的公共组件和公共函数有哪些人使用,提出了哪些问题?

    e公司

    • 一面
      • vue style scoped 属性作用是啥,如何是样式仅在当前模块生效
        • 作用:实现组件的私有化,不对全局造成样式污染,表示当前 style 属性只属于当前模块
        • 原理:打包之后,编译成特定样式,data-v-[hash],即 CSS 带属性选择器
      • (√)token 失效刷新如何实现的,token 和登录的处理
      • (√)角色权限的处理,路由守卫导航,动态路由匹配
      • (√)脚手架,一般会改哪些配置;压缩的处理:插件的压缩处理,gzip 压缩,代码压缩
      • (√)代码层级的性能优化
      • ES6,promise 链式调用如何实现;promise.then().catch().then().catch(),有报错,如何实现,走的流程
      • (√)常用的深浅拷贝;手写深拷贝如何实现;递归调用,处理特殊的边界问题;防止死循环;解决引用递归问题
      • (√)ES6 常用属性和方法
      • async/await 的使用,和 promise 使用的区别
        • 错误捕捉方式:promise 使用.catch;async/await 可以.then.catch,也可以 try/catch
        • 调用方式:promsie 连续调用,链式调用;async/await 简洁易懂,异步操作同步化
      • (√)js 事件循环:nodejs 里面的,koa 用的多吗
      • 让元素看不见:dispaly:none;opacity:0;
      • 四个 div,宽度 25%,第四个会被挤下去,不考虑宽高的问题?
      • (√)http 协议的理解:1.1 和 2.0 的区别;长链接如何做到的,分成更小的帧,二进制传输
    • 二面
      • 了解过哪些媒体技术:直播,弹幕,通信
      • 了解及时通信嘛:如微信 web 端,websocket,消息推送等,有没有了解过
      • 做过一些浏览器兼容性问题,手机端的:微信浏览器,IOS safiri,谷歌内核浏览器
      • 小程序,uniapp使用过嘛

    f公司

    一面

    • H5 开发,如何做真机调试
      • react native 可以进行真机调试:usb 调试
      • vConsole / Eruda 查看报错信息
      • Fildder(手机和 fildder 链接同一个网络,然后手机开启手动代理并安装证书)
      • android 手机 chrome 浏览器,开启 usb 调试,chrome://inspect/#devices
      • Charles 代理调试
    • (√)移动端 1px 的问题
    • 小程序开发,uniapp 熟悉嘛?
    • 小程序 api 有 setData 方法,为啥要合并操作,减少操作次数的原因
      • 会导致卡顿,操作反馈延迟严重,渲染结果不实时
      • 当数据量过大时会增加脚本的编译执行时间,占用 WebView JS 线程
    • (√)性能优化,具体介绍一下:图片优化,指的是减少图片体积;
    • (√)http1.1 和 2.0 的区别
    • 图片上传预览:图片存在本地,通过 base64 转化;云库实现,用到了吗?
    • (√)webpack 性能优化:并行压缩;dllplugin;splitchunk;混淆压缩;happypack 多线程;includes 减少范围;cache 属性,对性能优化作用最大,改善构建速度
    • (√)js 数据类型
    • 遍历数组的方式:forEach;for in;for of;
      • forEach 和 map 的区别;
        • map 不写 return,默认返回 undefined,返回一个数组长度的 undefined 的数组;
      • forEach 中断循环
        • 用数组的方法,return false;
        • 数组的 api,使用 some 或者 every 实现
        • 使用 for 循环或者 for in 代替
        • 使用 throw 抛出异常
    • 遍历对象的方式
      • for in:主要用来遍历对象(for keys in obj)
        • 遍历自身和继承的可枚举属性(延续原型链遍历出对象的原型属性)
        • 有什么问题:要使用 hasOwnProperty 判断,只处理自身的,不处理继承的
      • for of: ES6 新增的,遍历所有数据结构的统一的方法
        • 只要部署了 Symbol.iterator 属性,就被视为具有 iterator 接口,就可以用 for…of 循环遍历它的成员
        • 包括数组、Set 和 Map 结构、某些类似数组的对象(比如 arguments 对象、DOM NodeList 对象)、Generator 对象,以及字符串
      • Object.keys:返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)
      • Object.getOwnPropertyNames(obj):返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)
      • Object.getOwnPropertySymbols()
      • Reflect.ownKeys(obj)遍历:返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 或字符串,也不管是否可枚举
    • (√)vue 的组件通信方式:attr;父组件调用子组件的方法(attr;父组件调用子组件的方法(attr;父组件调用子组件的方法(emit;$refs)
    • vue-router 路由参数,从一个商品跳入到另一个商品,路由参数变化,但是路由不变化,渲染会出现的问题,
      • 原因:同一个组件不会挂载两次
      • 解决办法:
        • 监听路由参数变化,watch 实现
        • 组件内的路由导航:
          • 路由独享守卫,beforeEnter
          • 组件内的守卫 beforeRouteEnter beforeRouteUpdate (2.2 新增) beforeRouteLeave
    • 手写题:js 原型链
    1. // 构造函数的原型
    2. // function的原型
    3. // object的原型
    4. function Foo() {}
    5. const foo = new Foo()
    6. Foo.__proto__ = ?
    7. foo.__proto__ = ?
    8. Foo.prototype.__proto__ = ?
    9. 复制代码
    • 手写题:发布订阅者模式
    1. class EventEmitter {
    2. constructor() {
    3. this.arr = {}
    4. }
    5. on(name, fn) {
    6. this.arr[name] ? this.arr[name].push(fn) : this.arr[name] = [fn]
    7. }
    8. off(name, fn) {
    9. if(this.arr[name)) {
    10. if(fn) {
    11. this.arr[name] = this.arr[name].filter(o => o!==fn);
    12. } else {
    13. delete this.arr[name]
    14. }
    15. }
    16. }
    17. once(name, fn) {
    18. this.arr[name] = fn
    19. }
    20. emit(name, params) {
    21. // this.$emit('change', params)
    22. if(Array.isArray(this.arr[name]))
    23. {
    24. this.arr[name].forEach(fn => {
    25. fn(params)
    26. })
    27. } else{
    28. this.arr[name](params)
    29. off(name)
    30. }
    31. }
    32. }
    33. 复制代码

    二面

    • 最近的项目,针对项目问
      • 单点登录实现,前端还是后端实现;
      • 权限管理(后端、菜单、路由、页面级;动态路由加载 自定义指令按钮级 路由导航;)
      • 前端性能优化处理
      • SSR 渲染原理,用过该技术嘛
      • 发布,上线的流程,工具等;jerkins,;docker,看过编译运行代码嘛;
    • 前端安全的控制:xss,csrf,sql 注入;怎样的 token 才是安全的 token;其他保证安全的方式;
    • 统一登陆处理,第三方登录对接;如何做这种系统,如果你做的话,怎么安排,怎么设计(技术选型,第三方对接,渠道对接,项目结构)
    • 百来个人开发一个项目,如何协调,用啥技术(微应用吧 优点:兼容不同技术 新旧系统)
    • H5 的混合开发项目:h5 和原生的通信(jsbridge)
    • react native 开发:选用技术原因;类似技术有哪些
    • 用到了 vue3 嘛,vue3 对 vue2 大的更新;vue3 和最新的 react 有啥区别,对比有啥优势
    • 了解过微信公众号,小程序的开发嘛:两个的区别,登陆的过程;微信公众号如何判断你是谁,怎么获取 unnid
    • PC 端的扫码登陆实现
    • 团队前端人数,任务分工;团队技术栈规划;团队前端,代码质量如何管控;

    三面

    • 针对项目:做了哪些开发工作;个人价值体现最大的地方;大数据量的问题处理(分页,分片,虚拟滚动,关键字远程搜索,异步加载);
    • 前端美工设计:专门的 UI;Ui 定义了一套自己的组件库规范
    • 未来的职业发展定位,职业规划
    • 现在项目面对的客户群体,
    • 自己评价性格:中性,外向,内向等
    • 工作内容:除了技术本身,toB 行业,会面临各式各样的客户,会有不同的沟通方式和交流,会有挑战;怎么平衡技术和客户需求
    • 前后端联调,任务划分,有明显的界限划分嘛

     前端面试题库 (面试必备)     推荐:★★★★★

    地址:前端面试题库

    g公司

    • (√)new 操作符具体干了啥?
    • (√)箭头函数与普通函数的区别
    • (√)数组常用方法
      • push;pop;shift;unshift;slice;splice
      • indexOf;includes;find
      • reverse;sort;
      • join;split;concat;
      • some;every;forEach;filter;map
      • reduce;reduceRight
    • reduce 作用
    1. // accumulator-累加器;currentValue-当前值;currentIndex-当前值索引;initialValue-初始值;
    2. array.reduce(function(accumulator, currentValue, currentIndex, array), initialValue)
    3. // 1. 数组求和
    4. let total = [1, 2, 3, 4].reduce((acc, cur) => (acc += cur), 90);
    5. // 2. 数组去重 [1,2,4,null]
    6. // 2.1 filter
    7. let arr = [1, 2, 2, 4, null, null].filter((item, index, arr) => arr.indexOf(item) === index);
    8. // 2.2 new Set
    9. let arr = [...new Set([1, 2, 2, 4, null, null])];
    10. // 2.3 reduce
    11. let arr = [1, 2, 2, 4, null, null].reduce((acc, cur) => {
    12. return acc.includes(cur) ? acc : acc.concat(cur);
    13. }, []);
    14. // 3. 扁平化多维数组 [0, 1, 2, 3, 4, 5, 6, 7]
    15. let arr = [0,[1],[2, 3],[4, [5, 6, 7]]]
    16. // 3.1 flat
    17. arr.flat(Infinity);
    18. // 3.2 reduce
    19. let dimensionReduction = function (arr) {
    20. return arr.reduce((acc, cur) => {
    21. return acc.concat(
    22. Array.isArray(cur) ?
    23. dimensionReduction(cur) :
    24. cur
    25. );
    26. }, []);
    27. }
    28. dimensionReduction(arr);
    29. // 4. 求字符串中字母出现的次数
    30. const str = 'sfhjasfjgfasjuwqrqadqeiqsajsdaiwqdaklldflas-cmxzmnha';
    31. const res = str.split('').reduce((acc, cur) => {acc[cur] ? acc[cur]++ : acc[cur] = 1; return acc;}, {});
    32. // 5. 数组转对象 按照id 取出stream
    33. var streams = [{name: '技术', id: 1}, {name: '设计', id: 2}];
    34. var obj = streams.reduce((acc, cur) => {acc[cur.id] = cur; return acc;}, {});
    35. 复制代码
    • 手写 reduce
    1. Array.prototype.myReduce = function (cb, initValue) {
    2. const array = this; // 获取数组
    3. let pre = initValue || array[0];
    4. const startIndex = initValue ? 1 : 0;
    5. for (let i = startIndex; i < array.length; i++) {
    6. const cur = array[i];
    7. pre = cb(pre, cur, i, array);
    8. }
    9. return pre;
    10. };
    11. 复制代码
    • (√)web 攻击方式:攻击目标,预防方式
      • XSS (Cross Site Scripting) 跨站脚本攻击
      • CSRF(Cross-site request forgery)跨站请求伪造
        • token 实现安全的原理
      • SQL 注入攻击
    • (√)http1.0,htt1.1,http2.0,http3.0 的区别
      • http 是有状态还是无状态的,请求有无区别(无状态,携带辅助信息)
    • (√)Restful API 请求方式
      • get 和 post 请求的区别
    • (√)前端性能优化
    • (√)async 和 defer 区别;prefetch 和 preload 区别
    • (√)vue diff 算法
      • 比较只会在同层级进行, 不会跨层级比较:节点类型不同,直接用新的替换旧的;相同,就比较子节点
      • 在 diff 比较的过程中,循环从两边向中间比较
    • (√)vue 虚拟 DOM 的作用
      • 不会进行回流和重绘;
      • 对于频繁操作,只进行一次对比差异并修改真实 DOM,减少了真实 DOM 中多次回流重绘引起的性能损耗;
      • 有效降低大面积的重绘与排版,只更新差异部分,进行渲染局部;
    • (√)vue key 的作用:高效的更新虚拟 dom
    • (√)v-if 和 v-for
    • (√)JS 事件循环机制
      • 同步、异步(宏任务、微任务);
      • 一段代码,输出执行顺序
    • (√)项目错误处理
      • 后端接口报错:axios 的响应拦截器处理
      • 代码逻辑错误
      • 对象属性未定义错误处理:可选链 obj?.name
      • 错误拦截:try、catch
      • vue 内置错误处理机制:errorHandler;errorCaptured
    • (√)树结构数据中找和为 n 的路径[算法]

    给定一个二叉树和一个数字 n,判断二叉树中是否有一个路径上的数字之和等于给定的数字 n

    1. function hasPathSum(root, sum) {
    2. if (!root) {
    3. return false;
    4. }
    5. if (!root.left && !root.right) {
    6. return sum === root.val;
    7. }
    8. return (
    9. hasPathSum(root.left, sum - root.val) ||
    10. hasPathSum(root.right, sum - root.val)
    11. );
    12. }
    13. 复制代码
    • (√)保证 3 个请求结果顺序显示[开放题]
      • 粗暴型:顺序请求,一个请求完了再请求另一个
      • 优化型:promise.all 一起请求,通过函数控制结果顺序显示
        • 简单通过 flag 标志实现顺序显示
        • 写一个函数控制顺序显示,链式调用

    h公司

    • 一面
      • 盒模型;BFC;
      • 高阶函数作用:柯里化(curry);组合函数(compose);管道函数(pipe)
      • 页面自适应方案,flexible 本质
      • WebSocket 了解嘛?
      • 跨域问题解决:JSONP;iframe;postMessage;CORS;Proxy;WebSocket
      • vue 双向数据绑定:数据劫持结合发布者-订阅者模式
      • vue 组件通信方式
      • vue 生命周期
      • vue3.0 特性
      • 扩展运算符的应用(ES6)
      • 浏览器解析流程
    1. URL 解析
    2. DNS 查询
    3. TCP 连接(三次握手) 第一次握手:建立连接时,客户端发送 syn(建立联机)包到服务器,并进入 syn_send 状态,等待服务器确认; 第二次握手:服务器收到 syn 包,确认包信息,同时自己也发送一个 syn + ack(确认)包并进入 syn_recv 状态; 第三次握手:客户端收到 syn+ack 包,向服务器发送 ack 包,发送完后,客户端和服务器都进入 established 状态,完成三次握手;
    4. HTTP 请求
    5. 服务器响应请求
    6. 页面渲染 解析 HTML,构建 DOM 树(script 会下载 并解析 js,异步下载完执行是仍会阻塞 DOM 解析) 解析 CSS(link 或 style 标签),生成 CSS 规则树(HTML 和 CSS 解析相互独立) 合并 DOM 树和 CSS 规则,生成 render 树 布局 render 树( Layout / reflow 回流),负责各元素尺寸、位置的计算 绘制 render 树( paint 重绘),绘制页面像素信息 浏览器会将各层的信息发送给 GPU,GPU 会将各层合成( composite ),显示在屏幕上
    • 二面
      • 定制化组件是哪些?
      • 组件封装,提升效率,考虑组件化,发布远程通用
      • 性能优化之 Performance 面板
      • ES5 和 ES6 继承的区别
      • H5 混合开发 JSBridge 通信
      • h5 手机端兼容性

    i公司

    • 一面
      • H5 混合开发:客户端交互,APP 交互,微信交互;jsbridge 通信,如何封装的,看过吗
      • 大数据处理:分页;虚拟列表;后端远程搜索
      • 前端性能优化
      • 首页白屏解决:缓存;骨架屏;重绘,重排;减少包大小;解决阻塞;
      • webpack 打包优化方式
      • SPA 单页应用;SSR 服务端原理(NuxtJS);webpack 热更新
      • NextTick 的理解
      • keep-alive 动态组件
      • vuex 模块化实现
      • 大数加法[算法]

    实现两个字符串型数字的加法运算,返回字符串型的数字的和

    注意:无法直接对传入参数进行转换成数字

    思路:一位数一位数相加,采用隐式转化的方式相加

    1. sum("1233", "233"); // '1466'
    2. function sum(num_str1, num_str2) {
    3. // 字符串转字符数组
    4. const num_arr1 = num_str1.split("");
    5. // 字符串转字符数组
    6. const num_arr2 = num_str2.split("");
    7. // 竖式加法计算次数
    8. let sum_length = Math.max(num_arr1.length, num_arr2.length);
    9. // 求和结果
    10. const sum = [];
    11. // 进位标志位
    12. let CF = 0;
    13. // 循环语句为什么加CF进位存在判断呢,因为当最高位产生进位,(如 999 + 9999)
    14. // 计算到千分位9的时候,并且没有更多数要参与运算时,仍然需要进位参与一次运算,否则丢失进位。
    15. while (sum_length-- > 0 || CF) {
    16. // 求和,注意数组长度不够,按0算
    17. let temp =
    18. Number.parseInt(num_arr1.pop() || 0) +
    19. Number.parseInt(num_arr2.pop() || 0) +
    20. CF;
    21. if (temp >= 10) {
    22. temp %= 10; // 取个位数
    23. CF = 1; // 产生进位(对于加法,最多产生1个进位)
    24. } else {
    25. CF = 0; // 未产生进位
    26. }
    27. sum.unshift(temp); // 记录求和数据(从头插入)
    28. }
    29. return sum.join("");
    30. }
    31. 复制代码
    • 二面(针对项目提问)
      • 组件的定制化改造,二次封装还是自己写的
      • select 分页实现:滚动,分片,远程搜索,虚拟列表,数据处理部分展示
      • 单点登陆的实现;
      • 权限管理的实现;自定义指令控制操作权限,按钮级别;数据权限实现
      • 大量数据性能优化;表格遇到的问题,怎么解决的;
      • 前端性能优化
        • 哪个优化提升最明显;
        • 首屏渲染为啥那么长,包为啥那么大,如何优化;
        • 如何实现 ssr
      • 项目中遇到的问题,难题
        • pwa 使用场景;
        • 和安卓通信交互,和原生的相机,相册如何交互的;如何获取相册图片;照片 js 如何拿到的;input 和原生的相册如何交互,串起来;js 调用原生的相机
      • 微信账号和手机号账号绑定实现:微信提供 uuid,绑定原理和过程
      • webpack 构建过程,plugin 的实现
      • 对未来的团队和技术有啥要求,职业规划类的吧
      • 开发方向,自我定位

    如何实现一个拖拽指令?

    vue.js 自定义指令(拖拽、拖动、移动) 指令 v-drag

    j公司

    • 挑战性项目;项目难点

    • 虚拟 dom 作用:多次数据变化,一次更新;怎么收集数据变化;

    • 对象的深拷贝实现,递归调用死循环问题如何解决

    • 浏览器缓存对比:cookie;localStorage;sessionStorage

    • 权限管理实现:咋实现的?具体怎么处理,代码实现

      • 路由权限;菜单权限(路由守卫导航);按钮权限(v-if,自定义指令);接口权限
    • 单点登录 SSO 实现

    • vue2.0 和 vue3.0 区别

      • 2.0
        • 双向数据绑定:Object.defineProperty
      • 3.0
        • 双向数据绑定:Proxy,Reflect
        • Composition API:更好的逻辑复用和代码组织
        • Fragment:可以用多个根元素
        • Teleport(任意门)
        • 使用 Typescript 开发
        • 重构 Virtual DOM,修改了 diff 算法
    • v-model 在 2.0 和 3.0 里面的区别,实现原理

      • 破坏性的: 当用在 自定义组件 上的时候,v-model 的 prop 与 event 的默认名已变更:
        • prop: value -> modelValue;
        • event: input -> update:modelValue;
      • 破坏性的: v-bind 的 .sync 修饰符以及 model 选项已删除,取而代之的是 v-model 的一个参数;
      • 新的: 现在可以在一个组件上使用多个 v-model 来绑定数据了;
      • 新的: 新增了自定义 v-model 修饰符的功能。
    • flex 弹性布局

      • flex:1,等价于 0 1 auto,各个参数含义
      • 实现纵向三栏布局,中间 flex:1,如果中间宽度大于外层宽度,怎样表现?
    • z-index 无效问题:生效范围;什么情况下会失效,边界条件

      1. 父级元素溢出隐藏或者不显示:父元素设置了 overflow:hidden /display:none/ 等,那么子元素如果在父元素外部绝对定位,那么调节子元素 z-index 可能不会显示
      2. 父级元素层级低,z-index 被覆盖
      3. 没有设置定位(position)属性
      4. 父级元素 position 属性为 relative
      5. 含有浮动(float)属性
      6. IE 不兼容
    • 移动端 1px 边框

      1. 针对 IOS:border:0.5px solid #E5E5E5
      2. 使用边框图片
      3. 使用 box-shadow 实现:试了下,看不出效果
      4. 使用伪元素:设置绝对定位,和父元素左上角对齐。将伪元素的长和宽先放大 2 倍,然后再设置一个边框,以左上角为中心,缩放到原来的 0.5 倍
      5. 设置 viewport 的 scale 值
    • 协商缓存和强缓存使用场景

      1. 强缓存:访问服务器获取到数据后缓存下来,过期时间之内不会再重复请求,而是直接从本地缓存数据库读取

      • http1.0:Expire 相应头。expires 表示未来资源会过期的时间

      • http1.1:Cache-Control。max-age=xxx(缓存的资源将在 xxx 秒后过期);no-cache(需要使用协商缓存来验证是否过期);no-store(不可缓存)

      1. 协商缓存:每次读取数据都要和服务端通信,增加缓存标志。如果不匹配,表示资源更新,返回新数据;匹配则表示没有更新,返回 304

      • http1.0:Last-Modified;If-Modified-Since;弊端是时间的精确度只能在秒,资源没变但时间变了,也会更新

      • http1.1:Etag; If-None-Match

      1. 常见情况

      • 输入 url 回车进入:根据实际缓存策略处理,没有设置 no-cache 或 no-store,默认先走强制缓存路线
      • 按钮刷新,F5 刷新,右键重新加载:将 cache-control 的 max-age 直接设置成了 0,让缓存立即过期,直接走协商缓存路线
      • ctrl+F5 强刷:浏览器会强行设置 no-cache,强制获取最新的资源
    • vue-router 实现原理

      • 怎么知道页面变化了,更新页面;3.0 通过响应式,监听变量,响应机制;局部刷新
      • hash 模式:hashchange
      • history 模式:pushState 和 replaceState
    • 快排实现:核心递归[算法]

    1. //快排实现
    2. var a = [3, 2, 8, 4, 5, 6, 7, 1];
    3. //递归调用
    4. QuickSort(a, 0, a.length - 1);
    5. console.log(a.toString());
    6. function QuickSort(a, l, r) {
    7. if (l >= r) {
    8. return;
    9. }
    10. var target = a[l];
    11. var left = l,
    12. right = r;
    13. while (left < right) {
    14. while (left < right && target <= a[right]) {
    15. //B往左走寻找比挖出来的第一个萝卜轻,且位置在A右边的萝卜
    16. right--;
    17. }
    18. a[left] = a[right];
    19. while (left < right && a[left] <= target) {
    20. //A要往右寻找比一个萝卜重,且位置在B左边的萝卜
    21. left++;
    22. }
    23. a[right] = a[left];
    24. }
    25. a[left] = target;
    26. QuickSort(a, l, left);
    27. QuickSort(a, left + 1, r);
    28. }
    29. 复制代码

    k公司

    1. 自我介绍
    2. 工作中遇到的难点
    3. 服务端渲染和客户端渲染的区别,NuxtJS 的实现
    4. 从输入一个 URL 地址到浏览器完成渲染的整个过程
    5. 计算机网络浏览器缓存:强缓存和协商缓存
    6. 前端性能优化
    7. 跨域方式
    8. css 选择器及优先级
    9. flex 布局属性及意义;水平垂直居中实现
    10. JS 事件循环机制
    11. js 作用域和作用域链
    12. 闭包及其作用
    13. let,const 和 var 区别
    14. 对象的深拷贝:深拷贝与浅拷贝的区别?
    • 浅拷贝:创建新的数据,这个数据有着原始数据属性值的一份精确拷贝
      • 基本类型,拷贝的就是基本类型的值
      • 引用类型,拷贝的就是内存地址(共享)
      • 方式:Object.assign;slice;concat;拓展运算符
    • 深拷贝:开辟一个新的栈,对应两个不同的地址
      • 方式:_.cloneDeep();jQuery.extend();JSON.stringify();循环递归实现
      • 递归碰到循环调用问题,死循环,如何解决?
        • 尾递归优化
        • 循环重写
    1. ES6 常用方法和属性
    • 类 class,extends
    • 模块化 import/export
    • 箭头函数
    • 模板字符串
    • 函数参数默认值
    • 解构赋值
    • 扩展运算符(...)
    • let, var, const
    • Promise, .then, .catch, .finally, .all(), .race,
    • async/await
    • includes;Object.values();Object.entries()
    1. props 传值无法更新问题

    通过 props 传值不随着变化而变化,原因及解决方法(实际问题)

    • watch 监听:immediate;deep
    • this.$set()
    • 使用 v-if
    • Object.assign()
    1. Promise 常用方法
    • Promise
      • 异步编程的一种解决方案,解决地狱回调
      • 三种状态:pending(进行中);fulfilled(已成功);rejected(已失败)
      • then,catch,finally
      • all,race,allSettled,resolve,reject,try
    • async/await:Generator(yield,next) 的语法糖
    1. 手写 Promise.all;Promise.all 和 Promise.race 的区别?
    1. // Promise.all
    2. export const all = (promiseArr) => {
    3. let result = [];
    4. let count = 0;
    5. return new myPromise((resolve, reject) => {
    6. for (let i = 0; i < promiseArr.length; i++) {
    7. Promise.resolve(promiseArr[i]).then(
    8. (res) => {
    9. result[i] = res;
    10. count++;
    11. // 全部promise执行成功之后才resolve
    12. if (count === promiseArr.length) {
    13. resolve(result);
    14. }
    15. },
    16. (err) => {
    17. reject(err);
    18. }
    19. );
    20. }
    21. });
    22. };
    23. // Promise.race
    24. export const race = (promiseArr) => {
    25. return new myPromise((resolve, reject) => {
    26. for (let i = 0; i < promiseArr.length; i++) {
    27. Promise.resolve(promiseArr[i]).then(
    28. (res) => {
    29. // 只要有任何一个promise状态变更就resolve
    30. resolve(res);
    31. },
    32. (err) => {
    33. reject(err);
    34. }
    35. );
    36. }
    37. });
    38. };
    39. 复制代码
    1. 爬楼梯方式
    1. // 1 1
    2. // 2 2
    3. // 3 4 111 12 21 3
    4. // 4 1111 121 112 211 13 31 4 22
    5. // 四级台阶有多少种方法?
    6. const sum = (n) => {
    7. if (n == 1 || n == 2) {
    8. return n;
    9. }
    10. return sum(n - 1) + sum(n - 2);
    11. };
    12. 复制代码

    其他

    1. 职业规划,对架构师的理解
    2. 工程化,组件化,模块化
    3. 渐进式 Web 应用(PWA)
    4. WebAssembly
    5. 重绘和重排
    6. jquery 和 vue 操作 dom 渲染的区别
    • 区别:操作 dom 和操作数据
    • 实现及时:虚拟 dom;diff 算法,渲染的优化处理 diff 算法
    1. 如何实现发包之后改前端配置,不发布也可以更新
    2. 元素在页面隐藏的方式
    • display:none
    • visibility:hidden
    • opacity:0
    • 设置 height、width 模型属性为 0
    • position:absolute,将元素移出可视区域
    • transform 偏移:同上
    • clip-path:裁剪
    1. CSS 高度塌陷的原因;如何解决(BFC)

      • 原因:
        • 子元素浮动,父元素就会塌陷
        • 当子元素添加了 positive:absolute 属性,父元素高度塌陷,高度为 0
      • 解决:
        • 触发 BFC:overflow hidden
        • 清除浮动:clear both;after 伪元素
    2. 敏捷开发的理解

    3. 遇到的问题,怎么解决的

    4. 自己估计的工作量和实际不符,完不成的情况?

    5. 频繁变更了需求,会咋办,改咋处理?

    6. webGL 三维场景渲染优化

    7. 改变 this 指向的方式:apply,call,bind()

    8. 有一个请求,没有收到数据,如何排查:postman,联调方式,日志工具

    9. 如何节省沟通成本

      • 和 HR 有需求不同的讨论,如何 battle
      • 和后端接口对接,如何确定哪些后端实现,那些前端实现:不能靠感觉,标准是啥?如性能,用户体验等等
      • 会对需求提出意见吗?有反驳过产品的需求吗
    10. 数据埋点如何实现

    11. 模块化方式,import 和 require 区别

      • CommonJs (典型代表:node.js 早期):用于服务端
        • 都运行在模块作用域,不会污染全局作用域
        • 同步加载的,即只有加载完成,才能执行后面的操作
        • 首次执行后就会缓存,再次加载只返回缓存结果,如果想要再次执行,可清除缓存
        • require 返回的值是被输出的值的拷贝,模块内部的变化也不会影响这个值
      • AMD (典型代表:require.js):异步模块定义
        • 所有依赖模块的语句,都定义在一个回调函数中,等到模块加载完成之后,这个回调函数才会运行
        • require
      • CMD (典型代表:sea.js)
      • ES6 的 Module:import/export
        • CommonJS 和 AMD 模块,都只能在运行时确定这些东西
        • ES6 设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量
        • import()允许您仅在需要时动态加载模块,而不必预先加载所有模块
    12. 前端性能优化:评价指标;具体优化实现;

    13. webpack 配置,优化实现;核心概念:plugin,loader;loader 实现原理,如对 css 的处理解析

     前端面试题库 (面试必备)     推荐:★★★★★

    地址:前端面试题库

  • 相关阅读:
    什么是日志分析?为什么IT管理员需要日志分析?
    Linux软件包管理— rpm包的校验和证书
    单兵渗透工具-Yakit-Windows安装使用
    MySQL性能优化指南:深入分析重做日志刷新到磁盘的机制
    【软考设计师】【计算机系统】E01 计算机硬件组成与CPU
    第三、四、五场面试
    长尾效应和肥尾效应
    linux中.a和.so库文件
    BUGKU-simple_SSTI_1漏洞注入
    HashMap和Hashtable的区别源码对比(一)
  • 原文地址:https://blog.csdn.net/weixin_42981560/article/details/128104444