回答流程化
交代背景研究方案方案落地反思
问题一:js超过Number最大值的数怎么处理?
背景:
大数据的计算:金融、科学计算、数据分析
格式展示
用户输入
解决方案:
BigInt
decimal.js
big.js
总结:
bigint来处理大数据
decimal来处理
格式化,格式化成用户好读的格式
表单校验
问题二:如何解决页面请求接口大规模并发问题?
滑动窗口算法,是专门来控制流量的。
背景:
数据采集平台,低代码编辑平台,有序相对稳定发送到后端。
研究方案:
1.请求队列
class RequestQueue{ constructor(maxConcurrent){ this.maxConcurrent = maxConcurrent; //最大并发请求数 this.currentConcurrent = 0; //当前并发请求数 this.queue = []; //请求队列 } add(request){ return new Promise(resolve,reject) => { this.queue.push({request,resolve,reject}); this.processQueue(); } } processQueue(){ if(this.queue.length > 0 && this.curentConcurrent < this.maxConcurrent){ const {request,resolve,reject} = this.queue.shift(); this.currentConcurrennt++; request() .then(request) .catch(reject) .finally(()=>{ this.currentConcurrent--; this.processQueue()' }); } }}//示例请求函数function fetchData(url) { return fetch(url).then(response => response.json());}//使用请求队列const requestqueue = new RequestQueue(5);const urls = [ ' '; ' '; ]const requests = urls.map(url => () => fetchData(url));Promise.all(requests.map(request => requestQueue.add(request))) .then(results => { console.log('所有请求完成',results); }) .catch(error => { console.error('请求失败',error); });
2.防抖/节流
--防抖(Debounce):确保在指定时间内函数只执行一次,一般取最后一次,常用于输入框的搜索建议。
function Debounce (fun, wait){ let timeout; return function(...args){ clearTimeout(timeout); timeout = setTimeout(()=>{ func.apply(this,args); },wait); } }
--节流(Throttle):确保在指定时间间隔内函数执行一次,一般取第一次,常用于窗口的resize,scroll事件。
function throttle(func,limit){ let inThrottle; return function(...args){ if(!inThrottle){ func.apply(this,args); inThrottle = true; setTimeout(()=>inThrottle = false,limit); } };}
3.分页加载
落地、反思:
1.大数据量请求场景下,我们选用了请求队列,我主导封装了请求队列
2.防抖节流,用户交互层面上去解决减少请求的处理
3.分页,滚动加载,可视区绘制。
问题三:请说说大文件上传
背景:之前做xxx产品,我们会涉及到用户自定xxx文件上传。
经常遇到的一些问题:
--网络断开之后,之前传的没了。
--传着传着,网络波动,结果啥都没了。
--关机了,想接着传,做不到。
专业术语:
--断点续传
--断开重连重传
--切片上传
方案:
1.前端切片
2.将切片传递给后端,切片要取名:hash,index
3.后端组合切片
给面试官加料:
--前端切片:主线程做卡顿,web-worker多线程切片,处理完之后交给主进程发送。
--切完后,将blob存储到indexedDB,下次用户进来之后,嗅探一下是否存在未完成上传的切片,有就尝试继续上传。
--websocket,实时通知和请求序列的控制。
--整体说一说我主导这个大文件上传器整体设计:组件设计、props、事件、状态、拖拽上传、多文件选择、通用化不同文件的上传,上传统一协议。
const CHUNCK_SIZE = 5*1024*1024'; //每块大小为5MBfunction uploadFile(){ const file = document.getElementById('fileInput').files[0]; if(!file){ alert('Please select a file.'); } const tatalChuncks = Math.ceil(file.size / CHUNK_SIZE); let currrentChunk = 0; function uploadChunck(){ if(currentChunck >= totalChunks){ console.log('upload complete'); return; } const start = currentChunck *CHUNK_SIZE; const end = Math.min(start + CHUNK_SIZE,file.size); const chunk = file.silce(start,end); const formData = new FormData(): formData.append('file',chunk); formData.append('chunkNumber',currentChunk+1); formData.append('totalChunks',totalChunks); fetch('/upload',{ method:'POST'; body:formData }).then(response => { if(response.ok){ curentChunk++; uploadChunk(); }else{console.error('Chunk upload faild')}; )}.catch( error =>{console.error('Upload error',error)} ); uploadChunk():}
问题四:在前端怎么实现网页截图
背景:
飞书文档,内容在列表页想要查看
内容导出为png
设计类软件,出图
方案:
截图:
1.canvas
2.puppeteer
3.html2canvas
上传CDN
全页面截图/区域截图/特定区域截图
落地:
--截图工具的时候,需要考虑通用性,‘selector’
--设计具体协议
function takeScreenshot(){ const element = document.getElementById('screenshot-target'); html2canvas(element).then(canvas => { const img = canvas.toDataUrl('image/png'); const link = document.createElement('a'); link.ref = img; link.download = 'screenshot.png'; link.click(); });}
问题五:移动端适配问题如何解决
背景:
项目像支持PC、移动端。
方案:
1.根据不同端来开发不同的页面(成本最高)
2.根据不同端加载不同的CSS样式(可取)
3.根据响应式,来运行不同的样式规则(常用)
4.style预处理器来做
考虑的问题:
1.设置视窗,通过元信息配置 meta
2.掌握媒体查询
3.掌握弹性布局(flex布局)
4.图片响应式
5.视口单位rem/em
问题六:如何修改第三方 npm 包
背景:
来自于设计、产品、老板boss
方案:
1.稳定的库,node_modules,直接改
2.patch方案
‘patch-package’,自动化。
3.fork别人的,直接改源码,改完之后,构建,发布到npm私服。
问题七:使用同一个链接,如何实现PC打开是web应用,手机打开是一个H5应用
背景:
一个链接访问页面,想同时适配PC、Mobile
方案:
1.区分PC、Mobile
--先识别端
js识别,uesrAgent
正则判断
--端内容渲染器(内容加载器)
2.响应式来做
问题八:当QPS达到峰值,该如何处理
背景:
当前端应用的QPS(每秒查询次数)达到峰值时,会对服务器和应用的性能造成很大的压力,甚至可能导致系统崩溃。为了解决这个问题,我们需要采取一系列措施来优化和管理高并发请求。
方案:
1.请求限流
2.请求合并
3.请求缓存
4.任务队列
问题九:如何实现网页加载进度条
拆解:
怎么拿到进度(考虑兼容性、是使用ajax/fetch)
怎么绘制进度:dom、svg
背景:为了提升整站用户加载等待体验,考虑使用加载进度条反馈给给于虎加载过程
方案:
1.页面加载
监听页面加载事件,控制进度条绘制
function simulateLoadingProgress(){ const progressBar = document.getElementById('progress-bar'); let width = 0; const interval = setInterval(()=>{ if(width >= 100){ clearInterval(interval); progressBar.style.width = '100%'; setTimeout(()=>{ progressBar.style.display = 'none', },500); }else{ width += 10; progressBar.style.width = width + '%' } },200);}window.addEventListener('load',()=>{ simulateLoadingProgress(); })
2.请求实现
function loadResource(url){ const xhr = new XMLHttpRquest(); xhr.open('GET'.url,true); xhr.onprogress = function(event){ if(event.lengthComputeable){ const percentComplete = (event.loaded / even.total)*100; document.getElementById('progress-bar').style.width = percentComplete + '%'; } }; xhr.onload = function(){ if(xhr.status ===200){ document.getElementById('progress-bar').style.width = 100%; setTimeout(()=>{ document.getElementById('progress-bar').style.display = 'none'; },500) } }; xhr.send();}window.addEventListener('load',()=>{ loadResource('http://example.com/large-file') })
fetch不可以这样子!!
问题十:了解过前端水印功能吗?
背景:
为了保证用户隐私,数据相对安全,实现水印,飞书(名字)waterMar
文档保护/图片保护/视频保护
方案:
明水印:
背景添加水印
内容生成,svg
function createmarkSVG(text){ const svg = ' <svg xmlns = "http://www.w3.org/2000/svg" width="200" viewBox="0 0 200 200"> <text x="50%" y="50%" dy=".35em" text-anchor="middle" fill="rgba(0,0,0,0.1)" font-size="30" transform="rotate(-45,100,100)"> ${text} </text> </svg> '; return 'data:image/svg+xml;base64,${btoa(svg)}';}const watermarkText = "Confidential";document.body.style.backgroundImage = 'url('${createWatermarkSVG(watermarkText)}')';
图片水印 canvas
function addWatermark(imgsrc,watermarkText){ const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); const image = new Image(); image.src = imageSrc; image.onload = function(){ canvas.width = image.width; canvas.height = image.height; ctx.drawImage(image,0,0); ctx.font = '30px Arial'; ctx.fillstyle = 'rgba(255,255,255,0.5)'; ctx.fillText(watermarkText,image.width - 150,image.height - 30); const watermarkedImage = document.getElementById('watermarkedImage'); watermarkedImage.src = canvas.toDataUrl('image/png'); };}const imageSrc = document.getElementById('sourceImage').src;addWatermark(imageSrc,'Confidential');
暗水印:
黑科技,将信息写入到文件二进制代码里去。
问题十一:web应用中如何对静态资源加载失败的场景做降级处理
背景:
图片/css文件/javascript文件/CDN/字体文件/服务端渲染失败
方案:
图片:
1.占位图,alt来描述图片
2.重试机制(404/无权限)
3.上报
<img src="imagejpg" alt="Example Image" onerror="handleImageError(this)">function handleImageError(image){ image.onerror = null: //防止死循环 image.src = 'placeholder.jpg';//使用占位图}
css文件处理:
资源没加载到:
1.关键样式,通过内联
2.备用样式
3.上报
<link rel="stylesheet" href="style.css" onerror="handleCssError()">function handleCssError(){ //加载备用样式 const fallbackCss = document.createElement('link'); fallbackCss.rel = 'stylesheet’; fallbackCss.href = 'fallback-style.css'; document.head.appendChild(fallbacks);}
javascript文件处理:
网络异常,导致资源没加载:
1.内联脚本
2.备用脚本处理
3.上报
CND:
1.本地备份,如果cdn出错了,就使用本地备份
2.动态切换,切换到另一个有用的cdn服务
字体:
1.使用降级字体 apple、微软雅黑
2.webfont处理字体
ssr:
1.降级的html用作渲染
2.切换为客户端渲染
问题十二:怎样设计一个全站请求耗时统计工具
背景:
通过统计工具,可以更清晰地看到整个站点性能情况,首屏加载时间(FP/FCP)
1.监控请求耗时:HTTP、中间件,axios
2.前端监控,监控整个请求,记录耗时数据
3.后端监控:
4.数据汇总:数据清洗加工,数据可视化,可视化图表
方案:
问题十三:请说说你对函数式编程思想的理解
函数式编程的基本概念:
1.函数为一等公民,函数封装的方式解决问题
2.纯函数,没有任何副作用,相同输入(参数)得到相同输出(返回值)
3.不可变性,
4.高阶函数,函数柯里化
5.函数组合,类似于面向对象继承
总结优点:
1.可测试性,更好写单元测试
2.可维护性
3.并发
4.简洁
问题十四:请说说你对DNS协议的理解:(对应需要复习计算机网络)
将域名映射到IP上
域名解析整个过程:
1.用户输入,解析域名
2.检查自身DNS缓存
3.操作系统DNS缓存
4.本地域名服务器
5.根据本地DNS服务器去查找根DNS服务器、顶级域名服务器(TLD)、权威DNS服务器
6.返回结果,浏览器缓存并向IP发送请求
DNS记录类型:
1.A记录:将域名映射到IPv4地址
2.AAAA记录:将域名映射到IPv6地址
3.CNAME:将域名映射到另外一个域名
4.MX记录:知道邮件服务器
5.TXT:文本信息存储,域名验证,SPF记录
DNS常见问题:
1.DNS解析慢:DNS预解析/使用CDN,CDN节点用户就近/减少外部资源请求,自己域名+oss+cdn
2.DNS劫持:HTTPS,证书保证传输安全性/DNSSEC:DNS安全扩展
3.优化:DNS缓存/nslookup/dig/在线:dns.google.com
问题十五:我们是美团电影的,请问怎么实现一个电影票选座功能
使用canvas来实现选座功能
思路:
1.canvas基础处理
2.座位绘制
3.交互添加
4.座位状态管理,数据结构设计
5.优化,用户体验升级
问题十六:请说说图片性能优化的方案
方案:
1.loading=“lazy”
2.intersection observer检测是否已经到了视窗
3.滚动事件,监听scroll事件,最原始的做法
4.使用库
问题十七:移动端上拉加载,下拉刷新实现方案
背景:
长列表,需要通过上拉加载提升性能。
用户在页面顶部向下拉时,触发页面重新渲染
方案:
上拉加载:
1.滚动事件监听
2.怎么判断触底
3.回调触发列表加载更多
下拉刷新:
1.监听触摸事件,touch、tap
2.显示刷新指示器,显示有没有达到下拉阈值。
3.触发刷新操作
考虑的点:
1.性能优化:节流/防抖
2.用户体验:视觉反馈,下拉刷新的指示器/平滑动画/错误处理
3.兼容:触摸事件/CSS hack
问题十八:深度SEO优化,你都知道哪些细节
SEO优化思路:
1.页面结构优化:语义化标签
2.内容优化:保证页面中关键词的覆盖率
3.技术向SEO优化:站点地图、结构化数据、
问题十八:windows对象上频繁绑定内容,有什么风险
风险分析:
1.命名冲突
2.全局污染
3.安全风险
4.性能问题,增加内存开销
解决方案:
1.模块化
2.命名空间
3.IIFE(形成闭包,形成独立作用域)
4.开启严格模式
5.了解qiankun的快照沙箱实现原理
问题二十:小程序的双线程架构了解吗
双线层:
1.逻辑层(App Service):运行在JavaScriptCore引擎中,负责小程序业务逻辑;数据、时间、网络;不能直接操作视图,需通过通信机制。
2.渲染层(View):运行在WebView中,负责页面渲染;接收逻辑层UI更新指令;独立webview,并行渲染多个页面
双线层的交互:
优化思路:
1.分离业务逻辑和渲染逻辑
2.更新UI通过异步方式
3.并行页面处理,提升切换速度