Skip to content

浮点数精度

约 2607 字大约 9 分钟

2025-10-03

  1. 将浮点数转换成整数进行计算,再将结果转回浮点数。如果位数过长容易导致结果溢出
  2. 四舍五入
  3. 转换成字符串处理
  4. 使用成熟的库

Mutation Observer

强缓存适合静态资源

  1. 更新频率低:css、js、图片等上线后一般不会频繁变动,属于“内容稳定、体积较大、可复用性高”的资源
  2. 可控的“缓存更新机制”:强缓存会发生的问题是:资源更新后,旧缓存可能还在用。但前端工程一般会配合 文件指纹 hash 来解决,既保证 命中率高,又保证 更新及时
  3. HTML一般变化频繁(比如新增功能、文案修改)所以适合协商缓存。如果html引用的静态资源发生改变那么对应的文件指纹hash也会改变,也就是html更改时对应静态资源更改会重新请求

进程、线程、协程的区别

进程

操作系统资源分配的基本单位。

  • 有自己独立的内存空间(代码段、数据段、堆、栈)。
  • 进程之间相互隔离,通信需要 IPC(管道、消息队列、共享内存)。
  • 创建/销毁开销大。

线程

操作系统调度的基本单位。

  • 属于进程的一部分,运行在进程里。
  • 同一进程的多个线程共享内存(堆/全局变量),但有各自的栈。
  • 切换开销比进程小。
  • 可能有线程安全问题(需要锁)。

协程

用户态的“轻量级线程”,由程序自身控制调度。

  • 不是操作系统调度,而是程序主动让出/切换。
  • 更轻量,不需要内核态切换。
  • 常用于异步编程、IO 密集场景。
  • 需要程序员写逻辑来决定何时切换。

出现网络波动,如何确保数据传输,保证用户体验

前端

  1. 乐观更新:如用户点赞时先把点赞数加上,如果请求成功则不做处理,如果请求失败则回滚(将点赞数减去)并提示
  2. 重连
  3. 离线队列:将用户操作保存在队列中,当重连成功后再发送,如:聊天应用的重发消息
  4. 资源嗅探:将未处理完成的数据存储在indexedDB中,下次再进来再重传时先检查本地数据库中是否有数据,如果有可以直接拿出来使用
  5. ui占位:loading、骨架屏、占位图等

网络层

  1. 心跳:每隔一段时间发送一个心跳包检测连接是否断开,如果断开则重连
  2. 断点续传

后端

  1. 幂等接口:保证接口的设计不管操作多少次得到的结果都是一样的(post请求可能难以保证,可以加唯一标识配合校验机制)
  2. 数据库事务

defineProperty不支持新增属性的响应式,vue2如何处理的

  1. 使用Vue.set / this.$set内部会使用 defineReactive 为新属性设置 getter/setter。
  2. 对于数组的函数做劫持

nextTick

Vue 的响应式系统会异步更新DOM。当修改响应式数据时,Vue 并不会立即更新DOM,而是先在内存中记录变化,等本轮事件循环(microtask 或 next tick)结束后再统一渲染。 DOM 更新完成之后执行回调

好处:

  1. 避免重复渲染,提高性能。
  2. 批量处理多次数据更新,只渲染一次 DOM。

修改数据后立即想获取最新 DOM、执行动画或操作元素。

any、unknown、never

any

任意类型,关闭类型检查

  • 可以赋值给任何类型
  • 任何类型都可以赋值给 any
  • 可以调用任意属性或方法,编译器不会报错

缺点:丧失类型安全,容易隐藏错误

unknown

未知类型,更安全的 any

  • 可以赋值给 anyunknown 类型
  • 不能直接赋值给其他类型,必须先做类型缩窄(类型检查或类型断言)

优点:保留灵活性,同时保证类型安全

never永远不会出现的类型

  • 用于永远不会有值的情况
  • 常用于函数抛出异常或死循环

vue-router的生命周期

类型钩子特点
组件内beforeRouteEnter进入前,无法访问 this
组件内beforeRouteUpdate当前组件复用时,路由改变
组件内beforeRouteLeave离开组件前,可访问 this
全局beforeEach全局前置守卫,可阻止导航
全局beforeResolve所有守卫及异步组件解析后执行
全局afterEach全局后置守卫,无法阻止导航

使用js实现不可变对象

  1. Object.freeze:将对象冻结,如果对象内部的属性有嵌套对象还需要递归冻结
  2. proxy拦截
握手阶段非对称加密安全交换对称密钥
数据传输阶段对称加密高效加密 HTTP 数据

非对称加密 → 保证密钥安全 对称加密 → 保证传输性能

get和post的区别

对比点GETPOST
语义获取数据提交数据
参数位置URL 查询参数请求体
长度限制理论上无限制
缓存可能缓存默认不缓存
幂等性
安全性参数暴露在 URL参数在 body,相对更安全
常见场景查询、搜索提交表单、上传文件

css实现三角形

原理:border 有宽度后,四角交接处会产生斜线,

块级作用域

es6之前没有块级作用域,所以在 forif 中用 var 声明的变量,会“泄漏”到外层作用域。

使用立即执行函数模拟块级作用域

(funciton(){
	var a=1
	console.log(a)
})()

异步组件

解决按需加载的问题

底层实现其实就是利用 JavaScript 的动态 import() + Promise + Vue 的响应式渲染机制来实现的。

cdn

类型说明注意点
静态资源JS、CSS、字体文件、图片、视频等内容不经常改动,缓存友好
第三方库Vue、React、Lodash、jQuery 等可以用官方 CDN,节省带宽
大文件/公用资源公用图片、图标、logo 等尽量去中心化,提升全球访问速度
不敏感内容不包含用户隐私或安全信息CDN 一般是公共访问

路由的实现原理

  1. 监听 URL 变化
  2. 根据路由匹配组件
  3. 更新视图(Vue 渲染管线)

vue事件和原生事件的区别

对比点Vue 事件原生事件
绑定方式@ (v-on 指令)addEventListener / onclick
this 指向组件实例(Vue 实例),可访问 datamethods触发事件的 DOM 节点
修饰符提供 .stop.prevent.once 等语法糖需手动调用 event.preventDefault()stopPropagation()
自定义事件子组件可用 $emit 触发,父组件用 @xxx 监听仅限于原生 DOM 事件
事件透传Vue2 用 .native;Vue3 用 $attrs不存在这个概念
解绑方式Vue 会在组件销毁时自动解绑需手动调用 removeEventListener

nextTick原理

  1. 数据变化触发响应式系统:数据变化后对应的Watcher(观察者)会被通知
  2. 观察者入队列:vue内部维护一个观察者队列,同一个观察者再一个tick内只会更新一次(去重),多次数据变化会被合并
  3. nextTick回调队列:vue内部维护nextTick回调队列多次调用 nextTick 会合并回调。
  4. 微任务执行:先执行更新dom,再执行nextTick回调

统一代码规范

语言规范

  • JavaScript/TypeScript:ESLint + Airbnb/Standard/自定义规则
  • CSS/SCSS/LESS:Stylelint + 规范化命名(BEM/SMACSS/ITCSS)
  • HTML/模板:格式化缩进、属性顺序、语义化标签 项目结构规范
  • 约定目录结构、文件命名、组件命名规则
  • 模块化方式:如 React/Vue/Angular 组件规范
  • 统一资源管理:图片、icon、字体、样式等 编码习惯
  • 缩进、分号、引号、行长度、空行规则
  • 函数、变量、组件命名规则
  • 注释规范:函数/类/接口文档化注释 Git 提交规范
  • 使用 commit message 规范,如 Conventional Commits
  • 分支策略:如 Git Flow、GitHub Flow
  • PR 模板,要求描述功能、截图、测试方法

为什么读取元素的宽高信息也会导致重排

有些属性会强制浏览器先把最新的样式和布局计算出来再返回值。

事件中的target和currentTarget

  • target:事件触发的实际元素
  • currentTarget:事件监听器绑定的元素,当前正在处理事件的元素

js执行阻塞页面渲染

原因:浏览器无法预测js是否会修改dom或样式,所以必须在执行完js前暂停渲染保证渲染的一致性

Map和WeakMap

特性MapWeakMap
键类型任意类型对象(弱引用)
遍历能力可遍历不可遍历
size 属性
垃圾回收键值存在Map的引用不回收键对象无引用可回收,如果没有外部使用它就会自动被垃圾回收
常用场景通用键值存储私有数据/对象缓存/防内存泄漏

微任务递归生成微任务会陷入死循环吗

不会陷入真正的“死循环”,但它可能会导致浏览器或 Node.js 的事件循环被连续占用,造成可感知的“卡顿”或性能问题。

微任务是异步执行的不会像普通函数递归那样占用调用栈 但事件循环会被微任务队列持续占用,页面或应用无法响应其他任务队列中的任务

避免方案

  1. 限制递归深度
  2. 使用宏任务分隔

为什么transform不会导致重排

transform 属于复合图层(composite layer)属性,只会修改元素在渲染层的矩阵变换(位置、旋转、缩放、倾斜等),而不改变 DOM 布局信息。

贡献者

PinkDopeyBug

公告

本博客内容原本使用obsidian编写,由于没有仔细配置,以至图片引用使用obsidian风格。

且图片存储路径频繁变更导致部分文章图片无法正常显示。

为您带来不便请谅解。

ps:贡献者一直都只有wynnsimon一人,显示Pink的贡献者是因为我没好好配置git。后面因为懒就没一个个修改。如果被提及的人不希望被显示可以联系我我会立即删除。