垃圾回收机制(GC)核心思想垃圾回收器会定期检查堆内存的对象,判断哪些对象仍然被引用(“可达”)或不再被引用(“不可达”)
对于不可达的对象,垃圾回收器会将其占用的内存进行回收
可达:该对象可以通过作用域链、全局对象或其他对象的引用来访问
回收算法引用计数(已很少使用)每个对象都有一个引用计数器,记录有多少引用指向它
当引用计数为 0 时,表示该对象不可达,可以被回收
但无法处理循环引用问题
123456789function createCycle() { let obj1 = {}; let obj2 = {}; obj1.ref = obj2; // obj1 引用 obj2 obj2.ref = obj1; // obj2 引用 obj1 return [obj1, obj2];}let cycle = createCycle();cycle = null; // 即使外部没有引用,obj1 和 obj2 仍然互相引用
标记清除(最常用)垃圾回收器从根对象(如全局对象)开始,递归地标 ...
V8引擎
是一个由 Google 开发的高性能 JavaScript 引擎
为了提高 Chrome 浏览器中的 JavaScript 执行速度而设计的
能够将 JavaScript 代码直接编译成原生机器码并执行,而不是解释执行
工作原理
解析(Parsing):当 JavaScript 代码被加载时,V8 首先将其解析为抽象语法树(AST)
Ignition(解释器):V8 使用名为 Ignition 的解释器来解释执行 AST
TurboFan(优化编译器):针对频繁执行的代码段,Ignition 会收集运行时信息,并将这些代码传递给 TurboFan 进行优化编译。TurboFan 能够生成高度优化的机器码,显著提高性能。
垃圾回收(Garbage Collection, GC):V8 实现了高效的内存管理机制,通过标记清除、分代收集等策略自动回收不再使用的对象,减少内存泄漏的风险。
特性
即时编译(JIT Compilation):不同于传统的解释型语言,V8 采用即时编译技术,在运行时动态地将字节码转换为机器码,以提升执行效率。
隐藏类(Hidden Classes):为了 ...
栈/堆内存栈内存主要存储基本数据类型的值( Number、String、Boolean、Undefined、Null、Symbol 和 BigInt)
还存储变量的引用地址(指向堆内存的对象)
函数调用时的执行上下文也会压入栈中
内存是连续分配的,大小固定,内存的访问、分配、释放都非常快
123456789let a = 10; // 基本数据类型,存储在栈内存中let b = "Hello"; // 基本数据类型,存储在栈内存中let c = null; // 基本数据类型,存储在栈内存中function foo(x) { let y = 20; // 局部变量,存储在栈内存中 console.log(x + y);}foo(5); // 函数调用时,函数的执行上下文会被压入栈中
堆内存存储复杂数据类型的值(对象、数组、函数等)
还存储对象的属性、方法 & 数组的元素
内存非连续分配,大小不固定,分配和释放都慢,因为需要动态管理内存,而且需要通过引用地址间接访问
1234567let obj = { n ...
闭包
函数 与其 词法作用域 的结合
当一个 内部函数 访问其外部函数作用域中的变量时,即使外部函数已经执行完毕,内部函数仍然保留对外部变量的引用。
闭包的形成是因为函数的作用域链(Scope Chain)在定义时就已经确定,而非执行时。
示例计数器1234567891011function createCounter() { let count = 0; // 当createCounter函数执行后本该被销毁 return { increment: () => count++, // 但函数保留了对count的引用 getCount: () => count, };}const counter = createCounter();counter.increment();console.log(counter.getCount()); // 1
函数柯里化
一种函数式编程技术,它将一个多参数函数转换为一系列单参数函数
柯里化可以逐步传递参数,而不是一次性传递所有参数
123456 ...
事件循环
JS是单线程语言,同一时间只能执行一个任务
如果一个任务耗时过长(网络请求、文件读取),会阻塞后续代码的进行
同步任务:立刻放入JS引擎(JS主线程)执行,原地等待结果
异步任务:先放入宿主环境(浏览器/Node),不阻塞主线程,在将来执行
执行过程
过程中一共有三块环境:执行栈、宿主环境、任务队列
按代码上下文顺序
将同步任务压入执行栈
将异步任务压入宿主环境
在宿主环境中执行时机到来时(比如定时器到期),将宿主环境中异步任务(比如定时器)的回调函数推送给任务队列
此时执行栈会去看任务队列有没有异步任务需要执行,如果有则将异步任务推送到执行栈中执行
执行栈在同步任务执行完后会反复地去任务队列看有没有需要执行的异步任务
这个反复查找的过程就叫事件循环
宏任务/微任务
JS将 异步任务 分为宏任务和微任务
宏任务 由 宿主 发起
script (代码块)
setTimeout / setInterval 定时器
微任务 由 JS引擎 发起
promise (promise内部是同步,then/catch是回调异步)
Asy ...
Proxy
允许你创建一个代理对象来拦截并自定义基本操作(属性查找、赋值、枚举、函数调用等)
怎么用1const proxy = new Proxy(target, handler);
target: 要代理的目标对象。
handler: 一个包含 get/set 等拦截方法的对象。
1234567891011121314151617let target = {};let handler = { get: function(obj, prop) { if (prop in obj) { console.log(`Getting ${prop}: ${obj[prop]}`); return obj[prop]; } else { console.log(`${prop} 属性不存在`); return undefined ...
Promise什么是promise作为异步函数,有四种状态
Pending 进行中(Pending) 用 new Promise() 创建对象
Fulfilled 成功(Resolved) 用 .then() 处理成功的结果
Rejected 失败 (Rejected) 用 .catch() 处理失败
Finally 结束 () 用 .finally() 结束
怎么用异步函数
1234567891011const step_1 = new Promise((resolve, reject) => { //Promise对象 setTimeout(() => resolve("奶茶"), 1000);});const step_2 = (tea) => new Promise((resolve, reject) => { //函数 setTimeout(() => resolve(tea + "+珍珠"), 1000);});const step_3 = (tea) ...
GO?VO?AO?我用 「剧场演出」 来比喻这些概念
GO (Global Object)全局上下文对象(就是全局变量)
12var globalProp = "剧场灯光"; // 🎯 放入GOfunction stageManager() { /*...*/ } // 🎯 放入GO
预编译阶段
1234GO = { globalProp: undefined, // 先摆上道具标签 stageManager: function(){...} // 导演剧本提前挂好}
执行阶段
1234GO = { globalProp: "剧场灯光", // 道具就位 stageManager: function(){...}}
VO (Variable Object)变量对象
每个执行上下文都有
上下文创建到销毁
AO (Activation Object)活动对象
函数调用时临时创建,调用结束销毁
用一个面试题例子来理解12345 ...
音视频基础录制原理
播放原理
位深和帧率
1.5 码率视频文件在单位时间内使用的数据流量。比如1Mbps。大多数情况下码率越高 分辨率越高,也就越清晰。但模糊的视频文件大小(码率)也可以很大,分辨率小的视频文件可能也比分辨率大的视频文件清晰。对于同一个原始图像源的时候,同样的编码算法,则码率越高,图像的失真就会越小视频画面就会越清晰
视频基础RGB & BGR
YUV
444
422
420(最常见)
420 NV12
420 数据格式参考
RGB / YUV转换
帧I帧(Intra coded frames)
I帧不需要参考其他画面而生成,解码时仅靠自己就重构完整图像I帧图像采用帧内编码方式;I帧所占数据的信息量比较大:I帧图像是周期性出现在图像序列中的,出现频率可由编码器选择:I帧是P帧和B帧的参考帧(其质量直接影响到同组中以后各的质量)I帧是帧组GOP的基础帧(第一帧),在一组中只有一个|帧;I帧不需要考虑运动矢量;
类似截图,独立解码
P帧类似视频,依靠上一帧的数据,连续解码
B帧
依据前后帧解码
解码顺序先解出I帧,再解出P帧,进而解出B帧
音频 ...
FFmpeg实战ffmpeg
Hyper fast Audio and Video encoder 超快音视频编码器 (类似剪辑)
ffplay:
Simple media player 简单媒体播放器
ffprobe:
Simple multimedia streams analyzer 简单多媒体流分析器
处理流程1ffmpeg -i test 1920x1080.mp4 -acodec copy -vcodec libx264-s 1280x720 test 1280x720.flv
ffmpeg命令
复用器和解复用器的区别
复用器(Multiplexer, MUX):(E)
功能:将多个信号或数据流合并成一个单一的信号或数据流进行传输。
应用场景:在数据传输中,复用器常用于将多个低速信号合并为一个高速信号,以便在单一通道上传输,从而提高传输效率。
解复用器(Demultiplexer, DEMUX):(D)
功能:将单个合并后的信号或数据流分解回原始的多个信号或数据流。
应用场景:在数据接收端,解复用器负责将传输过来的合并信号还原为原始的多个信号,以 ...