前端面试常考基础题目详解

embedded/2025/3/29 16:13:49/

前端面试常考基础题目详解

一、HTML/CSS 高频考点

1. 盒模型

  • 标准盒模型(box-sizing: content-box):元素的宽度/高度仅包含内容区域,内边距(padding)和边框(border)会增加整体尺寸。

  • IE盒模型(box-sizing: border-box):元素的宽度/高度包含内容、内边距和边框,适合布局计算。

  • 应用场景:通过调整盒模型可避免布局错位,例如响应式设计常用border-box简化计算。

2. BFC(块级格式化上下文)

  • 触发条件:float非none、overflow非visible、position: absolute/fixed等。

  • 作用:隔离渲染区域,解决浮动元素导致的父元素高度塌陷、外边距重叠等问题。

  • 示例:清除浮动时,父元素设置overflow: hidden即可触发BFC。

3. Flex布局与Grid布局

  • Flex:适合一维布局,通过justify-content和align-items实现快速居中。

  • Grid:适合二维布局,place-items: center可一键实现水平垂直居中。

  • 对比:Flex更灵活,Grid更适合复杂网格结构(如仪表盘)。

4. 响应式设计实现

  • 媒体查询:@media (max-width: 768px)适配不同屏幕尺寸。

  • 视口单位:使用vw、vh实现基于视口的动态尺寸。

  • 示例:移动端1像素边框可通过transform: scaleY(0.5)缩放实现。

5. CSS选择器优先级

  • 优先级顺序:!important > 内联样式 > ID选择器 > 类/伪类 > 元素选择器 > 通配符。

  • 计算规则:权重由(行内, ID数, 类数, 元素数)组成,如.class a的权重为(0,0,1,1)。

二、JavaScript 核心问题

1. 闭包(Closure)

  • 定义:函数能访问并记住其词法作用域,即使函数在外部执行。

  • 用途:实现私有变量、防抖/节流函数、模块化开发。

  • 风险:不当使用可能导致内存泄漏(如未释放的DOM引用)。

2. 原型链与继承

  • 原型链:通过__proto__实现对象间的继承关系,prototype是构造函数的属性。

  • ES6继承:class语法糖基于原型链,对比ES5的寄生组合继承更简洁。

3. 事件循环(Event Loop)

  • 机制:同步任务进入主线程,异步任务(如setTimeout、Promise)由任务队列管理。

  • 执行顺序:宏任务(脚本、I/O) → 微任务(Promise.then) → UI渲染。

4. 防抖(Debounce)与节流(Throttle)

  • 防抖:连续触发时只执行最后一次(如搜索框输入)。

function debounce(fn, delay) {
  let timer;
  return (...args) => {
    clearTimeout(timer);
    timer = setTimeout(() => fn(...args), delay);
  };
}


  • 节流:固定时间间隔执行一次(如滚动事件)。

5. ES6+特性

  • 模块化:import/export替代require/module.exports,支持静态加载。

  • 箭头函数:无自身this,继承外层作用域的this,简化回调。

三、框架与工具(React/Vue)

1. React中key的作用

  • 虚拟DOM优化:key帮助React识别元素变化,减少不必要的重渲染。

  • 示例:列表删除中间项时,无key会导致后续元素全部重新渲染。

2. Vue双向绑定原理

  • 数据劫持:通过Object.defineProperty或Proxy监听数据变化。

  • 发布-订阅:数据变更时触发视图更新,视图输入触发数据修改(如v-model)。

3. Redux与Vuex设计思想

  • 共同点:单一数据源、状态不可变。

  • 差异:Redux依赖纯函数Reducer,Vuex集成Vue响应式系统。

四、性能优化与浏览器

1. 减少重绘与回流

  • 回流(Reflow):布局变化(如修改宽度)引发渲染树重新计算。

  • 优化策略:使用transform代替top/left,避免频繁操作DOM。

2. HTTP缓存策略

  • 强缓存:Cache-Control: max-age=3600直接复用本地资源。

  • 协商缓存:ETag和Last-Modified验证资源是否更新。

3. Webpack优化

  • 代码分割:SplitChunksPlugin拆分公共代码,按需加载。

  • Tree Shaking:删除未引用代码(需ES6模块语法)。

五、高频手写代码题

1. 深拷贝函数

function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (map.has(obj)) return map.get(obj);
  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      clone[key] = deepClone(obj[key], map);
    }
  }
  return clone;
}


2. 数组去重

const unique = arr => [...new Set(arr)];
// 或
const unique = arr => arr.filter((item, index) => arr.indexOf(item) === index);


总结与建议

以上题目覆盖了前端面试中80%以上的高频考点,建议结合实际项目经验进行深度理解,例如用BFC解决布局问题、用闭包优化性能等。更多完整题目可参考来源文档。

---

接下来,思考如何扩展现有部分:

1. HTML/CSS:

  • 增加HTML5新特性,如语义化标签(header, nav, main, footer, article, section),表单验证属性(required, pattern),多媒体标签(video, audio)。参考网页[2][4]。

  • 补充CSS动画(transition和animation的区别),响应式设计的媒体查询示例,视口单位的使用。参考网页[2][4][6]。

2. JavaScript:

  • 添加ES6+的更多特性,如解构赋值、模板字符串、模块化导入导出。参考网页[1][2][6]。

  • 扩展事件循环,详细讲解宏任务和微任务,给出执行顺序的例子。参考网页[2][4][6]。

  • 增加Promise的链式调用、async/await的错误处理。参考网页[1][3][6]。

3. 框架与工具:

  • 补充React Hooks的使用(useState, useEffect),Vue3的Composition API。参考网页[6][7]。

  • 增加Webpack的常见配置,如Loader和Plugin的区别,代码分割的实现。参考网页[1][5][7]。

4. 浏览器与网络:

  • 扩展HTTP缓存策略,强缓存和协商缓存的头部字段,如Cache-Control, ETag, Last-Modified。参考网页[2][5][6]。

  • 补充跨域解决方案,如CORS、JSONP、PostMessage。参考网页[4][6]。

5. 手写代码题:

  • 添加更多常见手写题,如Promise.all实现、数组扁平化、柯里化函数。参考网页[2][7][8]。

需要确保每个新增内容都有对应的引用来源,并正确标注。例如,HTML5新特性来自网页[2]和[4],CSS动画参考网页[2][6],ES6+特性来自网页[1][2][6]等。同时,注意不要重复已有的内容,而是补充新的知识点或更详细的解释。

最后,检查所有引用是否准确,信息是否相关,结构是否清晰,确保回答满足用户需求,提供更多有价值的前端面试基础题目详解。

前端面试常考基础题目扩展详解

一、HTML/CSS 扩展考点

1. HTML5 新特性

  • 语义化标签:<header>, <nav>, <main>, <article>, <section> 等,提升代码可读性和 SEO 效果。

  • 表单验证:新增属性如 required(必填)、pattern(正则校验)、type="email"(邮箱输入),简化客户端验证逻辑。

  • 多媒体支持:<video> 和 <audio> 标签实现音视频嵌入,支持播放控制;<canvas> 用于绘制动态图形,<svg> 用于矢量图渲染。

2. CSS 动画与响应式

  • Transition vs Animation:

    ◦ transition 用于简单属性过渡(如 hover 效果),需触发条件;

    ◦ animation 通过关键帧(@keyframes)实现复杂动画,可循环播放。

  • 媒体查询优化:

@media (min-width: 768px) and (max-width: 1024px) { 
  /* 适配平板设备 */ 
}


结合 vw/vh 视口单位,实现动态布局调整。

二、JavaScript 扩展核心问题

1. ES6+ 特性深化

  • 解构赋值:快速提取对象或数组数据,如:

const { name, age } = user; 
const [first, ...rest] = [1, 2, 3];


  • 模板字符串:支持多行文本和变量插值,如:

const greeting = `Hello, ${name}!`;


  • 模块化:import/export 实现代码拆分,支持按需加载(如动态 import())。

2. 事件循环与异步进阶

  • 宏任务与微任务执行顺序:
示例:

setTimeout(() => console.log('宏任务'), 0);
Promise.resolve().then(() => console.log('微任务'));
// 输出顺序:微任务 → 宏任务


微任务(Promise.then、MutationObserver)优先于宏任务(setTimeout、setInterval)执行。

  • Async/Await 错误处理:

async function fetchData() {
  try {
    const res = await fetch(url);
  } catch (error) {
    console.error('请求失败:', error);
  }
}


三、框架与工具扩展

1. React 进阶

  • Hooks 核心:

    ◦ useState 管理组件状态,useEffect 处理副作用(数据请求、事件监听)。

    ◦ 自定义 Hooks 封装复用逻辑(如 useFetch 数据请求)。

  • 虚拟 DOM 优化:通过 Diff 算法减少 DOM 操作,key 属性提升列表渲染效率。

2. Webpack 工程化配置

  • Loader 与 Plugin 区别:

    ◦ Loader 处理文件转换(如 babel-loader 转译 ES6);

    ◦ Plugin 扩展功能(如 HtmlWebpackPlugin 生成 HTML 入口)。

  • Tree Shaking:通过 ES6 模块语法(import/export)移除未使用代码,需配合 sideEffects 配置。

四、浏览器与网络扩展

1. HTTP 缓存策略

  • 强缓存:

    ◦ Cache-Control: max-age=3600 表示资源缓存 1 小时;

    ◦ Expires 基于绝对时间,优先级低于 Cache-Control。

  • 协商缓存:

    ◦ ETag(哈希值)和 Last-Modified(最后修改时间)由服务器验证资源是否更新。

2. 跨域解决方案

  • CORS:通过响应头 Access-Control-Allow-Origin: * 允许跨域请求。

  • JSONP:动态创建 <script> 标签绕过同源限制,仅支持 GET 请求。

  • PostMessage:window.postMessage 实现跨窗口通信(如嵌入 iframe)。

五、高频手写代码扩展

1. Promise 相关

  • 实现 Promise.all:

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    let results = [];
    let completed = 0;
    promises.forEach((promise, index) => {
      promise.then(res => {
        results[index] = res;
        if (++completed === promises.length) resolve(results);
      }).catch(reject);
    });
  });
}


  • 数组扁平化:

const flatten = arr => arr.reduce((acc, cur) => 
  acc.concat(Array.isArray(cur) ? flatten(cur) : cur), []
);


总结与建议

以上扩展内容覆盖了 HTML5 语义化、CSS 动画、ES6+ 高级语法、框架底层原理及工程化工具配置,建议结合项目实践深入理解,例如:

• 用 postMessage 实现微前端通信;

• 通过 Webpack 代码分割优化首屏加载速度。

---

更多 JavaScript 基础题目详解(附答案)

一、数据类型与类型转换

1. 数据类型

  • 基本类型:number, string, boolean, null, undefined, symbol, bigint。

  • 引用类型:object(包含 array, function 等子类型)。

  • 特殊值:typeof null 返回 "object"(历史遗留问题)。

2. 类型比较

  • == vs ===:== 会进行隐式类型转换(如 "5" == 5 为 true),=== 严格比较类型和值。

  • 示例:0.1 + 0.2 !== 0.3,因 IEEE 754 浮点数精度丢失。

二、作用域与闭包

1. 作用域链与变量提升

  • 变量提升:var 声明的变量会提升到作用域顶部,值为 undefined;let/const 存在暂时性死区。

  • 示例:

console.log(a); // undefined(变量提升)
var a = 1;


2. 闭包

  • 定义:函数能够访问并保留其词法作用域外的变量(如内部函数引用外部变量)。

  • 应用:私有变量、防抖/节流函数。

  • 风险:内存泄漏(未释放的 DOM 引用)。

三、原型链与继承

1. 原型链机制

  • 原型对象:每个对象都有 __proto__ 指向其构造函数的 prototype,形成链式结构。

  • 继承:通过 new 操作符创建实例,继承构造函数原型属性。

2. 手动实现继承

  • 寄生组合继承(ES5):

function Child() { Parent.call(this); }
Child.prototype = Object.create(Parent.prototype);
Child.prototype.constructor = Child;


  • ES6 继承:class Child extends Parent。

四、事件与异步

1. 事件流与事件委托

  • 三个阶段:捕获 → 目标 → 冒泡。

  • 示例:

<div οnclick="console.log('div')"><p οnclick="console.log('p')"></p></div>


点击 <p> 输出 p → div(冒泡阶段处理)。

2. 异步编程

  • 事件循环顺序:宏任务(setTimeout)→ 微任务(Promise.then)→ UI 渲染。

  • 手写 Promise.all:

function promiseAll(promises) {
  return new Promise((resolve, reject) => {
    let results = [], completed = 0;
    promises.forEach((promise, i) => {
      promise.then(res => {
        results[i] = res;
        if (++completed === promises.length) resolve(results);
      }).catch(reject);
    });
  });
}
```[7](@ref)

 

五、手写核心函数

1. call/apply/bind 实现

  • call:

Function.prototype.myCall = function(context, ...args) {
  context = context || window;
  context.fn = this;
  const result = context.fn(...args);
  delete context.fn;
  return result;
};
```[7](@ref)

 

2. new 操作符原理

  • 步骤:创建空对象 → 绑定原型 → 执行构造函数 → 返回对象。

  • 手写 new:

function myNew(fn, ...args) {
  const obj = Object.create(fn.prototype);
  const result = fn.apply(obj, args);
  return result instanceof Object ? result : obj;
}
```[7](@ref)

 

六、高频代码题

1. 深拷贝

function deepClone(obj, map = new WeakMap()) {
  if (obj === null || typeof obj !== 'object') return obj;
  if (map.has(obj)) return map.get(obj);
  const clone = Array.isArray(obj) ? [] : {};
  map.set(obj, clone);
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) clone[key] = deepClone(obj[key], map);
  }
  return clone;
}
```[3,7](@ref)

 

2. 数组去重

const unique = arr => [...new Set(arr)];
// 或
const unique = arr => arr.filter((item, i) => arr.indexOf(item) === i);
```[3](@ref)

 

总结与建议

以上题目覆盖了 数据类型、作用域、闭包、原型链、异步编程及手写核心函数 等高频考点。建议结合示例代码理解原理,并通过实际项目加深印象(如用闭包优化性能、手写 Promise 等)。更多完整题目可参考来源文档。

---

以下是 call、apply 和 bind 函数的手写实现及原理详解,结合了多个实现方案的优化思路:

1. 手写 call 函数

功能:立即调用函数,指定 this 指向并逐个传递参数。
实现步骤:

1. 检查调用者是否为函数(非函数调用需报错);

2. 处理上下文 context(若未传入则默认 window);

3. 为 context 添加唯一标识符(如 Symbol)避免属性覆盖;

4. 执行函数并保存结果,删除临时属性;

5. 返回执行结果。

Function.prototype.myCall = function(context, ...args) {
  if (typeof this !== 'function') throw new TypeError('Not a function');
  context = context || window;
  const fnKey = Symbol('fn');
  context[fnKey] = this;
  const result = context[fnKey](...args);
  delete context[fnKey];
  return result;
};


示例:

function greet(greeting) { console.log(`${greeting}, ${this.name}`); }
const obj = { name: 'Alice' };
greet.myCall(obj, 'Hello'); // 输出 "Hello, Alice"


2. 手写 apply 函数

功能:与 call 类似,但参数以数组形式传递。
关键区别:

• 第二个参数需校验是否为数组(非数组需报错);

• 无参数时默认空数组。

Function.prototype.myApply = function(context, argsArray) {
  if (typeof this !== 'function') throw new TypeError('Not a function');
  context = context || window;
  const fnKey = Symbol('fn');
  context[fnKey] = this;
  const result = argsArray?.length ? context[fnKey](...argsArray) : context[fnKey]();
  delete context[fnKey];
  return result;
};


示例:

function sum(a, b) { return a + b + this.offset; }
const context = { offset: 10 };
sum.myApply(context, [3, 5]); // 返回 18 (3+5+10)


3. 手写 bind 函数

功能:返回一个新函数,永久绑定 this 和预设参数,支持参数合并与构造函数调用。
核心逻辑:

1. 闭包保存原函数 fn、绑定上下文 context 和预设参数;

2. 返回的新函数需判断是否通过 new 调用(若是,则 this 指向新实例而非 context);

3. 合并预设参数与调用时参数。

Function.prototype.myBind = function(context, ...presetArgs) {
  if (typeof this !== 'function') throw new TypeError('Not a function');
  const fn = this;
  const boundFn = function(...callArgs) {
    // 判断是否为 new 调用(this 是否是 boundFn 的实例)
    const isNewCall = this instanceof boundFn;
    return fn.apply(isNewCall ? this : context, [...presetArgs, ...callArgs]);
  };
  // 继承原函数原型(解决 new 调用时的原型链问题)
  boundFn.prototype = Object.create(fn.prototype);
  return boundFn;
};


示例:

const obj = { x: 100 };
function logX(y) { console.log(this.x + y); }
const boundLog = logX.myBind(obj, 20);
boundLog(5); // 输出 120(100+20)

// new 调用场景
function Person(name) { this.name = name; }
const BoundPerson = Person.myBind({});
const p = new BoundPerson('Bob');
console.log(p.name); // 输出 "Bob"(this 指向新实例,而非空对象)


关键点总结

1. call/apply 差异:call 参数逐个传递,apply 参数为数组;

2. bind 的特殊性:

  • 返回函数支持参数合并(柯里化);

  • 处理 new 调用场景(忽略预设 this);

3. 错误处理:校验调用者类型,避免非函数调用;

4. 属性冲突:使用 Symbol 避免覆盖对象原有属性。

引用来源:

• call/apply 实现原理:

• bind 的构造函数处理:

• 参数合并与柯里化:

 

---

前端面试常考 LeetCode 题目详解

一、数组与字符串高频题

1. 两数之和(Two Sum)

  • 题目描述:在数组中找到两个数,使它们的和等于目标值。

  • 核心思路:使用哈希表(对象或 Map)存储已遍历元素的值和索引,将时间复杂度从 O(n²) 优化至 O(n)。

  • 代码示例:

const twoSum = (nums, target) => {
  const map = new Map();
  for (let i = 0; i < nums.length; i++) {
    const complement = target - nums[i];
    if (map.has(complement)) return [map.get(complement), i];
    map.set(nums[i], i);
  }
};


2. 三数之和(3Sum)

  • 题目描述:找出数组中所有不重复的三元组,使其和为 0。

  • 核心思路:排序后使用双指针法,固定一个数,左右指针向中间逼近,跳过重复值避免重复解。

  • 时间复杂度:O(n²),优于暴力解法的 O(n³)。

3. 最长无重复子串(Longest Substring Without Repeating Characters)

  • 题目描述:寻找字符串中最长的不含重复字符的子串。

  • 核心思路:滑动窗口 + 哈希表记录字符最后一次出现的位置,动态调整窗口左边界。

二、链表高频题

1. 反转链表(Reverse Linked List)

  • 题目描述:将单链表反转。

  • 核心思路:迭代法(三指针)或递归法,修改节点指向实现反转。

  • 迭代示例:

const reverseList = (head) => {
  let prev = null, curr = head;
  while (curr) {
    const next = curr.next;
    curr.next = prev;
    prev = curr;
    curr = next;
  }
  return prev;
};


2. 环形链表(Linked List Cycle)

  • 题目描述:判断链表是否有环。

  • 核心思路:快慢指针法,快指针每次走两步,慢指针一步,相遇则有环。

3. 合并两个有序链表(Merge Two Sorted Lists)

  • 题目描述:将两个升序链表合并为一个新链表。

  • 核心思路:递归比较节点值,或迭代法构建虚拟头节点简化操作。

三、二叉树高频题

1. 二叉树层序遍历(Binary Tree Level Order Traversal)

  • 题目描述:按层输出节点值。

  • 核心思路:使用队列(BFS)逐层遍历,记录每层节点数。

  • 代码示例:

const levelOrder = (root) => {
  if (!root) return [];
  const queue = [root], res = [];
  while (queue.length) {
    const level = [];
    const size = queue.length;
    for (let i = 0; i < size; i++) {
      const node = queue.shift();
      level.push(node.val);
      if (node.left) queue.push(node.left);
      if (node.right) queue.push(node.right);
    }
    res.push(level);
  }
  return res;
};


2. 验证二叉搜索树(Validate BST)

  • 题目描述:判断二叉树是否为二叉搜索树。

  • 核心思路:中序遍历结果为升序,或递归传递上下界验证节点值范围。

3. 二叉树的最大深度(Maximum Depth of Binary Tree)

  • 题目描述:计算二叉树的最大深度。

  • 核心思路:递归法(深度优先)或 BFS 层序遍历统计层数。

四、动态规划与回溯高频题

1. 爬楼梯(Climbing Stairs)

  • 题目描述:每次爬 1 或 2 阶,求到达第 n 阶的方法数。

  • 核心思路:动态规划,状态转移方程 dp[n] = dp[n-1] + dp[n-2]。

2. 打家劫舍(House Robber)

  • 题目描述:不能偷相邻房屋,求最大收益。

  • 核心思路:动态规划,状态转移方程 dp[i] = max(dp[i-1], dp[i-2] + nums[i])。

3. 全排列(Permutations)

  • 题目描述:生成数组所有可能的排列。

  • 核心思路:回溯法 + 剪枝,通过交换元素位置减少空间复杂度。

五、其他高频题型

1. 合并区间(Merge Intervals)

  • 题目描述:合并所有重叠的区间。

  • 核心思路:排序后遍历,比较当前区间与结果数组最后一个区间的结束位置。

2. LRU 缓存(LRU Cache)

  • 题目描述:设计一个最近最少使用缓存。

  • 核心思路:哈希表 + 双向链表实现 O(1) 的插入和删除。

总结与建议

1. 刷题策略:按类别集中突破(如先刷完所有链表题),避免零散刷题;

2. 核心思想:

  • 空间换时间:哈希表、缓存机制(如 LRU);

  • 双指针优化:滑动窗口、快慢指针;

3. 面试技巧:

  • 先澄清题意(如边界条件、输入输出要求);

  • 从暴力解法入手,逐步优化并解释思路。


http://www.ppmy.cn/embedded/174427.html

相关文章

spring boot+mybaits多条件模糊查询和分页查询

我们首先写一下多条件的模糊查询&#xff0c;首先在controller里面写一个接口&#xff0c;进行传参&#xff0c;我们这里要注意&#xff0c;之前写修改和增加的时候用的注解都是RequestBody,也就是说&#xff01;前端传过来一个json&#xff0c;数组也行&#xff0c;然后我们后…

美颜SDK x AIGC:如何用滤镜API结合AI生成技术打造创意视觉特效?

时下&#xff0c;AIGC的崛起&#xff0c;使得滤镜API不再局限于基础的磨皮、美白&#xff0c;而是可以结合深度学习和生成式AI&#xff0c;打造更加智能和独特的视觉特效。本文将探讨如何将美颜SDK的滤镜API与AIGC结合&#xff0c;打造突破传统美颜效果的创意视觉体验。 一、滤…

深入解析 .NET 中的依赖项加载机制:原理、实现与最佳实践

在现代应用程序的开发中&#xff0c;依赖项管理与加载是非常重要的组成部分&#xff0c;尤其是在大型系统中&#xff0c;如何高效地加载和管理依赖项可以极大地影响应用程序的性能、可维护性和扩展性。在 .NET 中&#xff0c;依赖项加载不仅涉及静态依赖的管理&#xff0c;还包…

数据结构与算法-图论-拓扑排序

前置芝士 概念 拓扑排序&#xff08;Topological Sorting&#xff09;是对有向无环图&#xff08;DAG&#xff0c;Directed Acyclic Graph&#xff09;的顶点进行排序的一种算法。它将图中的所有顶点排成一个线性序列&#xff0c;使得对于图中的任意一条有向边 (u, v)&#x…

MySQL 简记

MySQL 简记 mysql中的数据存储的结构是B树 其与B树的相同点是&#xff0c;B树一个节点也可以存放多条数据&#xff0c;并且从左到右依次增大&#xff1b;不同点是&#xff0c;B树的叶子结点之间也能相互连接。那么实际上是采取利用空间换区时间的策略。 那么B树的树结构like…

dfs(二十二)78. 子集

78. 子集 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 &#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[],[1],[2],[1,2]…

MySQL5.7主从同步配置

环境&#xff1a; 使用2台虚拟机&#xff0c;如图-1所示。其中192.168.4.51是主服务器,另一台192.168.4.52作为从服务器&#xff0c;通过调取主服务器上的binlog日志&#xff0c;在本地重做对应的库、表&#xff0c;实现与主服务器的数据同步。 主服务器、从服务器都已安装好my…

electron框架(4.0)electron-builde和electron Forge的打包方式

----使用electron-builder打包&#xff08;需要魔法&#xff09; --安装electron-builder: npm install electron-builder -D--package.json中进行相关配置&#xff1a; {"name": "video-tools","version": "1.0.0","main&quo…