From b00d16de811e8d4c8049a8d5b43fa0332d6d9eba Mon Sep 17 00:00:00 2001 From: Jiacheng787 Date: Sat, 16 Mar 2024 14:35:30 +0000 Subject: [PATCH] :sparkles: feat: add 2024-03-17 section --- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- 2021/archive/index.html | 8 +++---- 2021/index.html | 8 +++---- .../index.html" | 8 +++---- 2021/tags/browserslist/index.html | 8 +++---- 2021/tags/chrome/index.html | 8 +++---- 2021/tags/common-js/index.html | 8 +++---- 2021/tags/css-in-js/index.html | 8 +++---- .../index.html" | 8 +++---- 2021/tags/golang/index.html | 8 +++---- 2021/tags/index.html | 8 +++---- 2021/tags/node-js/index.html | 8 +++---- .../npm-\345\217\221\345\214\205/index.html" | 8 +++---- 2021/tags/npm/index.html | 8 +++---- 2021/tags/promise/index.html | 8 +++---- 2021/tags/react-docs/index.html | 8 +++---- 2021/tags/react/index.html | 8 +++---- 2021/tags/type-script/index.html | 8 +++---- 2021/tags/vue-3/index.html | 8 +++---- 2021/tags/vue/index.html | 8 +++---- 2021/tags/webpack/index.html | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- 2022/archive/index.html | 8 +++---- 2022/index.html | 8 +++---- 2022/page/2/index.html | 8 +++---- 2022/page/3/index.html | 8 +++---- 2022/page/4/index.html | 8 +++---- 2022/page/5/index.html | 8 +++---- 2022/page/6/index.html | 8 +++---- 2022/tags/babel/index.html | 8 +++---- .../cli-\345\267\245\345\205\267/index.html" | 8 +++---- 2022/tags/code-review/index.html | 8 +++---- 2022/tags/cra/index.html | 8 +++---- 2022/tags/css/index.html | 8 +++---- 2022/tags/css/page/2/index.html | 8 +++---- .../diff-\347\256\227\346\263\225/index.html" | 8 +++---- 2022/tags/diff/index.html | 8 +++---- 2022/tags/es-lint/index.html | 8 +++---- 2022/tags/es-next/index.html | 8 +++---- .../index.html" | 8 +++---- 2022/tags/git/index.html | 8 +++---- 2022/tags/git/page/2/index.html | 8 +++---- 2022/tags/golang/index.html | 8 +++---- 2022/tags/golang/page/2/index.html | 8 +++---- .../http-\347\274\223\345\255\230/index.html" | 8 +++---- 2022/tags/idea/index.html | 8 +++---- 2022/tags/index.html | 8 +++---- .../index.html" | 8 +++---- 2022/tags/leetcode/index.html | 8 +++---- 2022/tags/monorepo/index.html | 8 +++---- 2022/tags/next-js/index.html | 8 +++---- 2022/tags/node-js/index.html | 8 +++---- 2022/tags/performance/index.html | 8 +++---- 2022/tags/post-css/index.html | 8 +++---- 2022/tags/prettier/index.html | 8 +++---- 2022/tags/quic/index.html | 8 +++---- .../index.html" | 8 +++---- 2022/tags/react-native/index.html | 8 +++---- 2022/tags/react/index.html | 8 +++---- 2022/tags/rollup/index.html | 8 +++---- 2022/tags/type-script/index.html | 8 +++---- 2022/tags/vs-code/index.html | 8 +++---- 2022/tags/vue-3/index.html | 8 +++---- 2022/tags/vue/index.html | 8 +++---- 2022/tags/webpack-hmr/index.html | 8 +++---- 2022/tags/webpack-loader/index.html | 8 +++---- 2022/tags/yaml/index.html | 8 +++---- 2022/tags/yarn-2/index.html | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- .../index.html" | 8 +++---- 2023/archive/index.html | 8 +++---- 2023/index.html | 8 +++---- 2023/page/2/index.html | 8 +++---- 2023/page/3/index.html | 8 +++---- 2023/page/4/index.html | 8 +++---- 2023/page/5/index.html | 8 +++---- 2023/page/6/index.html | 8 +++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 23 +++++++++++++++++++ .../index.html" | 10 ++++---- 2024/archive/index.html | 10 ++++---- 2024/atom.xml | 12 ++++++++++ 2024/index.html | 10 ++++---- 2024/page/2/index.html | 10 ++++---- 2024/rss.xml | 8 +++++++ 2024/tags/golang/index.html | 10 ++++---- 2024/tags/index.html | 10 ++++---- 2024/tags/java/index.html | 10 ++++---- 2024/tags/type-script/index.html | 10 ++++---- 2024/tags/webpack/index.html | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- .../index.html" | 10 ++++---- 2024/welcome/index.html | 12 +++++----- 404.html | 8 +++---- ...c4d36.8ee62fb4.js => 212c4d36.d41a866e.js} | 2 +- assets/js/59c08185.185e672d.js | 1 - assets/js/59c08185.959fce08.js | 1 + ...acaa9.540967e8.js => 5e7acaa9.3c001628.js} | 2 +- assets/js/76cc166b.6f9972d1.js | 1 + assets/js/76cc166b.759427f0.js | 1 - assets/js/7811d1e5.86244e40.js | 1 + ...fd697.91d6ac12.js => 8e0fd697.eba8e2bf.js} | 2 +- assets/js/a02a2c89.d92da2a4.js | 1 + ...1c7d8.a34fd5b2.js => cb01c7d8.2c68cf60.js} | 2 +- ...f8616.827be279.js => ce5f8616.7ae6b609.js} | 2 +- ...1db8d.eda2dc73.js => fbf1db8d.e483494e.js} | 2 +- assets/js/main.2ced05e0.js | 2 ++ ...CENSE.txt => main.2ced05e0.js.LICENSE.txt} | 0 assets/js/main.4afc04c4.js | 2 -- assets/js/runtime~main.0821bb32.js | 1 + assets/js/runtime~main.96ede3ad.js | 1 - index.html | 8 +++---- markdown-page/index.html | 8 +++---- sitemap.xml | 2 +- 252 files changed, 1008 insertions(+), 963 deletions(-) create mode 100644 "2024/3\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" rename assets/js/{212c4d36.8ee62fb4.js => 212c4d36.d41a866e.js} (99%) delete mode 100644 assets/js/59c08185.185e672d.js create mode 100644 assets/js/59c08185.959fce08.js rename assets/js/{5e7acaa9.540967e8.js => 5e7acaa9.3c001628.js} (80%) create mode 100644 assets/js/76cc166b.6f9972d1.js delete mode 100644 assets/js/76cc166b.759427f0.js create mode 100644 assets/js/7811d1e5.86244e40.js rename assets/js/{8e0fd697.91d6ac12.js => 8e0fd697.eba8e2bf.js} (92%) create mode 100644 assets/js/a02a2c89.d92da2a4.js rename assets/js/{cb01c7d8.a34fd5b2.js => cb01c7d8.2c68cf60.js} (97%) rename assets/js/{ce5f8616.827be279.js => ce5f8616.7ae6b609.js} (79%) rename assets/js/{fbf1db8d.eda2dc73.js => fbf1db8d.e483494e.js} (56%) create mode 100644 assets/js/main.2ced05e0.js rename assets/js/{main.4afc04c4.js.LICENSE.txt => main.2ced05e0.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.4afc04c4.js create mode 100644 assets/js/runtime~main.0821bb32.js delete mode 100644 assets/js/runtime~main.96ede3ad.js diff --git "a/2021/11\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/11\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 8816513a88..6af6142a81 100644 --- "a/2021/11\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/11\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,15 +11,15 @@ - - + +
Skip to main content

11月14日内容汇总

· 5 min read
加菲猫

📒 构建提效

  • 打包工具:webpack -> rollup
  • 生成 AST :babel -> acorn
  • 语法转换:babel -> swc
  • 代码压缩:terser -> esbuild

📒 代码规范相关

  • ESLint 用于代码规范检查,在开发阶段提前规避问题,提升代码健壮性
  • Prettier 用于代码风格校验,统一团队编码风格

实际上编写文档、单元测试、类型声明、tsconfig.json 、ESLint 、Prettier 、lint-staged 、husky 这些对实现功能上来说没有任何作用,但是可以保障代码交付质量

📒 生成自增 ID :

看到一个通过 generator 函数生成自增 ID 的方法:

function *customIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

看了下其实还可以通过闭包实现:

function customIdGenerator() {
let i = 0;
return {
next() {
return i++;
}
}
}

const IDGenerator = customIdGenerator();
IDGenerator.next(); // 0
IDGenerator.next(); // 1
IDGenerator.next(); // 2
IDGenerator.next(); // 3
IDGenerator.next(); // 4
IDGenerator.next(); // 5
tip

注意:

++i 是先加再作为表达式的值去赋值,相当于 (i = i + 1)

i++ 是先把原来的值作为表达式的值赋值再加

📒 专业名词

缓存命中 规则命中 增量构建

📒 Promise 四种常用工具方法

  • Promise.all() :接收一个 Promise 数组,如果所有 Promisefulfilled 则返回结果数组,只要有一个 Promise 变为 rejected ,则返回最先 rejected 的 Promise ,通常用于并发请求
  • Promise.race() :接收一个 Promise 数组,race 意思就是比谁快,返回状态最先改变的 Promise ,不管成功还是失败,通常用于请求超时处理
  • Promise.any() :接收一个 Promise 数组,返回最先 fulfilledPromise ,如果没有 Promise 状态转为 fulfilled ,则抛出一个 AggregateError
  • Promise.allSettled() :接收一个 Promise 数组,在所有 Promise 状态改变(fulfilled 或者 rejected)之后返回结果数组。Promise.allSettled 适用于异步任务互相不依赖,Promise.all 适用于异步任务互相之间需要依赖其他任务的结果;

📒 什么时候不能使用箭头函数

  • 需要函数提升时(箭头函数只能写成表达式形式);
  • 需要使用函数的 thisargumentsprototype 时;
  • 需要使用命名函数时(箭头函数是匿名的);
  • 需要作为构造函数时(箭头函数不能作为构造函数);
  • 需要在对象方法中访问当前对象时;
let obj = {
a: 1,
fn1: () => {
console.log(this)
},
fn2: function() {
console.log(this)
}
}
obj.fn1(); // Window
obj.fn2(); // {a: 1, fn1: ƒ, fn2: ƒ} ,这是 this 的隐式绑定

const f1 = obj.fn1;
const f2 = obj.fn2;
f1(); // Window
f2(); // Window ,隐式绑定取决于谁来调用,谁调用就指向谁

使用箭头函数之所以会指向 Window 是因为箭头函数等价于下面的代码:

var that = this; // 直接使用闭包缓存 this
let obj = {
a: 1,
fn1: function() {
console.log(that);
}
}

在对象方法(例如 Vue Options API)的异步回调中经常会遇到 this 丢失的情况,一般会使用闭包进行缓存:

// 使用 _this 变量进行缓存
const _this = this;
api.get("/api/xxx", function(res) {
_this.tableData = res;
})

// 除了使用闭包缓存 this ,还可以使用箭头函数
api.get("/api/xxx", (res) => {
this.tableData = res;
})

总结一下:箭头函数没有自己的 this ,没有 argument 对象,没有 prototype ,不能作为构造函数(用 new 调用会报错)。箭头函数会自动捕获上级词法作用域的 this ,并且箭头函数的 this 在声明的时候就已经确定了,不能通过 call 或者 apply 修改

- - + + \ No newline at end of file diff --git "a/2021/11\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/11\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 414b68d7a8..6e793aeebd 100644 --- "a/2021/11\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/11\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git "a/2021/11\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/11\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 1c31d2cc22..f071d9ba0e 100644 --- "a/2021/11\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/11\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git "a/2021/12\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/12\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3fc352e99d..0ffa821c4d 100644 --- "a/2021/12\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/12\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月12日内容汇总

· 6 min read
加菲猫

📒 优雅获取 package.json 文件

这里需要注意一个问题,在 ES module 规范下无法直接引入 JSON 文件,只能通过 require 获取:

// ES module 模块
import React from "react";
import { debounce } from "lodash-es";
// JSON 模块只能通过 CJS 方式加载
const package = require("package.json");

import 命令目前只能用于加载 ES 模块,现在有一个提案,允许加载 JSON 模块。import 命令能够直接加载 JSON 模块以后,就可以像下面这样写:

import configData from './config.json' assert { type: "json" };
console.log(configData.appName);

import 命令导入 JSON 模块时,命令结尾的 assert {type: "json"} 不可缺少。这叫做导入断言,用来告诉 JavaScript 引擎,现在加载的是 JSON 模块

除此之外,还可以使用第三方库 read-pkg 获取,原理是通过 fs 模块读取 package.json 文件,然后反序列化为 JS 对象:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

export async function readPackage({cwd = process.cwd(), normalize = true} = {}) {
const filePath = path.resolve(cwd, 'package.json');
const json = parseJson(await fsPromises.readFile(filePath, 'utf8'));

if (normalize) {
normalizePackageData(json);
}

return json;
}

📒 如何覆盖某些元素的浏览器默认样式

很多元素,例如 <button><input type="text" /><input type="checkbox" /> 具有浏览器默认样式,有时候需要自己指定样式,如何覆盖浏览器默认样式,只需要下面一行代码:

input {
-webkit-appearance: none;
}

📒 如何让 div 按比例缩放

有时希望 div 自适应页面宽度的时候,可以按比例缩放,这种情况下可以使用 aspect-ratio 属性:

div {
aspect-ratio: auto 1 / 1;
}

推荐在 ratio 前面加 auto ,对于 input 等具有固有宽高比的替换元素将使用默认宽高比,否则就使用指定的宽高比。

注意 aspect-ratio 兼容 Chrome > 87 ,所有的 IE 浏览器都不兼容

aspect-ratio - MDN

📒 如何维护一个大型的 Next.js 应用

📒 Goober:CSS-in-JS 方案

这是一个 1 KB 大小的 CSS-in-JS 方案,可以替代 23 KB 的 styled-components 和 emotion 组合。而且如果你可以减少 goober 库 gzip 后的体积,他们还会奖励你美元。

https://github.com/cristianbote/goober

📒 使用支持 Tree Shaking 的包

如果可以的话,应尽量使用支持 Tree Shaking 的 npm 包,例如:

  • 使用 lodash-es 替代 lodash ,或者使用 babel-plugin-lodash 实现类似效果

📒 win10 安装 nvm-windows

下载地址:

https://github.com/coreybutler/nvm-windows/releases

用法跟 mac 上的 nvm 类似:

# 安装 nodejs v16.13.1
$ nvm install 16.13.1

# 查看已安装的 nodejs 版本
$ nvm list

# 使用指定版本的 nodejs
$ nvm use 16.13.1

# 卸载某个版本的 nodejs
$ nvm uninstall 16.13.1

个人猜测是通过修改环境变量实现 node 版本切换

在使用的时候遇到两个问题:

  1. 安装老版本 nodejs 的时候,node 安装成功,但是 npm 安装失败;
  2. 使用 nvm use 切换 node 版本的时候报错;

第一个问题,给 nvm 配置淘宝镜像即可解决。找到 nvm 安装目录下的 settings.txt 文件,添加配置:

node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

第二个问题,首先检查 nvm 安装路径没有中文、没有空格,然后如果问题还在,那就是权限问题,使用管理员权限打开 cmd 即可正常切换。

📒 获取 worker 线程最大并发数

通过下面的只读属性获取用户计算机的逻辑内核数:

logicalProcessors = window.navigator.hardwareConcurrency

下面的代码中,为每一个逻辑内核创建一个 worker 线程,充分利用 CPU 资源:

let workerList = [];

for (let i = 0; i < window.navigator.hardwareConcurrency; i++) {
let newWorker = {
worker: new Worker('cpuworker.js'),
inUse: false
};
workerList.push(newWorker);
}

Navigator.hardwareConcurrency - MDN

📒 TypeScript类型中的逆变协变

📒 如何优雅引入 node 内置模块

在引用 node 内置模块的时候可以加 node: 前缀,比如:

import util from 'node:util';
import { promisify } from 'node:util';
import { spawn, exec } from 'node:child_process';

通过增加前缀,可以将 node 内置模块与其他第三方模块区分开:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

看到这边有同学会问,为啥 node 中可以使用 ES module,实际上现在 node 已经支持了 ES module ,只需要在 package.json 中设置如下字段即可:

{
name: "xxx",
version: "1.0.0"
type: "module", // 默认 commonjs
}

从 vue-cli 源码中,我发现27行读取 json 文件有趣的 npm 包

📒 gradient-string: 在终端中输出漂亮的渐变色

image

https://github.com/bokub/gradient-string

📒 手写系列-实现一个铂金段位的 React

- - + + \ No newline at end of file diff --git "a/2021/12\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/12\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 372f21d575..8adae966b6 100644 --- "a/2021/12\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/12\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月19日内容汇总

· 4 min read
加菲猫

⭐️ Webpack 分包最佳实践

SplitChunksPlugin 进行分包的三要素:

  1. minChunks: 一个模块是否最少被 minChunks 个 chunk 所引用
  2. maxInitialRequests/maxAsyncRequests: 最多只能有 maxInitialRequests/maxAsyncRequests 个 chunk 需要同时加载 (如一个 Chunk 依赖 VendorChunk 才可正常工作,此时同时加载 chunk 数为 2)
  3. minSize/maxSize: chunk 的体积必须介于 (minSize, maxSize) 之间

哪些应该单独分包:

  1. Webpack 运行时
  2. React Framework 运行时,包括 React/React-DOM 及它们所有的依赖
  3. 大型库,体积特别大的库
  4. 公共库,至少被 4 个 Chunk 所引用的公共模块
tip

Webpack 配置最佳实践,除了 Vue-cli 和 CRA 源码,还可以参考 next.js 源码:

https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts

Webpack 性能系列四:分包优化

📒 【内部分享】看向未来 - 近期 TC39 提案汇总

📒 如何移除代码中的 console

  1. 使用 uglifyjs-webpack-pluginterser-webpack-plugin 中的 drop_console 配置;

  2. 使用 Babel 插件 babel-plugin-transform-remove-console

  3. 简单粗暴删除,直接重写 console.log 方法;

    console.log = function() {};
  4. 手写 webpack loader 删除;

    // clearConsole.js
    const reg = /(console.log\()(.*)(\))/g;
    module.exports = function(source) {
    source = source.replace(reg, "")
    return source;
    }

    基于正则匹配还是有一些问题,例如 const { log } = console 或者 const log = console.log.bind(console) 这种就匹配不到

📒 WebRTC 录屏技术

WebRTC 是一套基于音视轨的实时数据流传播的技术方案。通过浏览器原生 API navigator.mediaDevices.getDisplayMedia 方法实现提示用户选择和授权捕获展示的窗口,进而获取 stream (录制的屏幕音视流)。我们可以对 stream 进行转化处理,转成相对应的媒体数据,并将其数据存储。

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia

📒 Go 1.18 Beta 1 已经正支持泛型

📒 使用Golang、Gin和React、esbuild开发的Blog

📒 使用 patch-package 修复 npm 库的紧急问题

如果使用的 npm 库有 bug,可以使用 patch-package 创建一个补丁包。

工程化知识卡片 022: 质量保障篇之如何优雅某个 npm 库的紧急问题

📒 5 种有趣的 useEffect 无限循环类型

📒 用 CSS 来代替 JS 的实现

📒 React18 新特性:transition

📒 「2021」我给Vue.js生态贡献代码的这一年

⭐️ ⭐️ fiber:受到 Express 启发的 Web 应用框架,使用 Go 开发,与 Express 的 API 非常接近

package main

import "github.com/gofiber/fiber/v2"

func main() {
app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World 👋!")
})

app.Listen(":3000")
}

https://github.com/gofiber/fiber

- - + + \ No newline at end of file diff --git "a/2021/12\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/12\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d0a625d741..a09455e749 100644 --- "a/2021/12\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/12\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月26日内容汇总

· 6 min read
加菲猫

📒 腾讯技术工程相关文章

⭐️ 收藏 | 腾讯技术 2020 年精华文章合集

🐛 生产环境如何 debug

  • 定位错误是前端还是后端接口返回的
    • 前端代码全局搜索关键字(vscode 或者 chorme devtools 中搜索)
    • 翻阅 network 面板中的请求,使用 ⌘ + F 打开 network search 面板进行搜索
  • 如何调试混淆压缩后的 JS
    • 使用 source 面板中的 pretty-print 选项
    • 这样还是存在问题,例如很多变量名、方法名都被混淆压缩了,然后 babel 会将 ES2015+ 语法进行语法转换,代码可读性降低
  • 如何在生产环境中使用 sourceMap 调试
    • 打开混淆压缩的代码,右键选择 Add source map
    • 这里需要添加一个 source map URL,可以将本地项目添加到 source 面板中的 Filesystem 中,或者启用静态资源服务
    • 添加之后就可以直接搜索项目中的源文件了
  • 如何在 chrome 中修改代码并调试
    • chrome devtools 提供了 local overrides 能力,指定修改后的文件的本地保存目录,当修改完代码保存的时候,就会将修改后的文件保存到你指定的目录目录下,当再次加载页面的时候,对应的文件不再读取网络上的文件,而是读取存储在本地修改过的文件
    • 打开 sources 下的 overrides 面板,点击 select folder overrides 选择修改后的文件件存储地址,我们就可以打开文件修改,修改完成后保存,重新刷新页面后,修改后的代码就被执行到了

前端工程师生产环境 debugger 技巧

📒 如何在 React 中优雅使用 ECharts

初始化 ECharts 的时候不要使用 id,否则无法渲染多个组件实例:

import * as React from "react";
import * as echarts from "echarts";

const LineChart = (props) => {
const chartRef = React.useRef();

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);
}, [props])

return <div ref={chartRef} className="chart"></div>
}

export default React.memo(LineChart);

如何让 ECharts 实现自适应,可以在窗口尺寸变化的时候,调用 chart 实例上的 resize 方法:

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);

const handleResize = () => {
chart.resize();
}

// 绑定 resize 事件监听器
window.addEventListener("resize", handleResize);

return () => {
// 组件更新或者卸载时移除监听
window.removeEventListener("resize", handleResize);
}
}, [props])

推荐使用 addEventListener 绑定事件,可以多次绑定,但是要注意及时 remove,不然会导致内存泄漏

📒 看火焰图分析调用栈的时候,看到一个 asyncGeneratorStep 的函数,一直没搞清楚这个在哪里用到了

image

事后才想到这是 babel 语法转换引入的 helper 函数

image

📒 使用 webpack-chain 对 vue-cli 默认配置进行修改

https://github.com/Yatoo2018/webpack-chain/tree/zh-cmn-Hans

📒 如何对 webpack 打包产物进行分析

经常需要分析打包产物的体积,看哪个包体积过大,做针对性优化。可以使用 Webpack Bundle Analyzer:

$ yarn add webpack-bundle-analyzer -D

webpack.config.js 中添加如下配置:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}

然后执行打包构建命令:

$ yarn build --report

https://github.com/webpack-contrib/webpack-bundle-analyzer

📒 create-react-app 发布 5.0 版本

本次的 5.0 版本优化了快速刷新(Fast Refresh),支持了 Tailwind,并更新了不少内部依赖库,如 Webpack 5、Jest 27 和 EsLint 8 等。

https://github.com/facebook/create-react-app/releases/tag/v5.0.0

📒 处理你应用中的内存泄漏

作者 Stoyan 提到:“任何大小合理的应用中,都会存在一定程度的内存泄漏”。因此知道如何处理泄漏是一件很有用的事。在本文中,作者举了一个 React 中的例子,不过它的基本理念却可以运用在任何地方。

https://calendar.perfplanet.com/2021/plugging-memory-leaks-in-your-app/

📒 kalidokit:人体动作表情解读同步

效果还是和牛逼的,真人测试。

https://github.com/yeemachine/kalidokit

📒 xterm:把命令行搬到浏览器

https://xtermjs.org/

📒 microdiff:轻量快速的对比库

https://github.com/AsyncBanana/microdiff

- - + + \ No newline at end of file diff --git "a/2021/12\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2021/12\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d1fc6d5a66..779b6fa540 100644 --- "a/2021/12\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2021/12\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月5日内容汇总

· 2 min read
加菲猫

📒 如何切换后端环境

在前端项目中,后端接口请求通常都通过 devServer 代理,这样解决了跨域问题。但是开发的时候经常需要切换后端环境,每次切换都要重启 devServer,这就导致每次都要重新构建,比较麻烦。

一种解决思路是,前端项目中后端接口地址使用 域名,在 系统 host 文件 中配置域名与 IP 地址的映射,这样每次切换后端环境,只需要修改系统 host 文件,然后在浏览器中刷新页面就可以实现切换。

但是每次手动修改 host 文件有点麻烦,可以使用 SwitchHost 工具,一键切换,非常方便。

📒 Vue 3 技术栈

  • Vue3.2:核心库
  • Vite2.6:官方推出的基于 ESM 的构建工具
  • vue-router-next:Vue3 官方路由
  • pinia:官方推出的状态管理库
  • TypeScript:静态类型检查
  • Volar:Vue3 的 vscode 插件

📒 Chrome 调试小技巧

在断点位置按 F9,可以一步一步往下执行,调试源码的时候查看调用栈特别有用。当然很多时候调用栈比较复杂,这时候通过 Performance 面板的火焰图看比较直观,火焰图的宽度代表执行耗时,火焰图的高度代表调用栈的深度。

📒 CommonJS 中的模块导出

CommonJS 规范中只有一种模块导出:module.exports ,而 exports 仅仅只是 module.exports 的引用而已

📒 推荐两个网站

  • caniuse:查询 api 兼容性
  • codeif:变量命名
- - + + \ No newline at end of file diff --git a/2021/archive/index.html b/2021/archive/index.html index 275d80299b..26edc9fd69 100644 --- a/2021/archive/index.html +++ b/2021/archive/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/2021/index.html b/2021/index.html index 1ba4fcf813..bd72590a40 100644 --- a/2021/index.html +++ b/2021/index.html @@ -11,8 +11,8 @@ - - + +
@@ -22,7 +22,7 @@ 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

· 5 min read
加菲猫

📒 构建提效

  • 打包工具:webpack -> rollup
  • 生成 AST :babel -> acorn
  • 语法转换:babel -> swc
  • 代码压缩:terser -> esbuild

📒 代码规范相关

  • ESLint 用于代码规范检查,在开发阶段提前规避问题,提升代码健壮性
  • Prettier 用于代码风格校验,统一团队编码风格

实际上编写文档、单元测试、类型声明、tsconfig.json 、ESLint 、Prettier 、lint-staged 、husky 这些对实现功能上来说没有任何作用,但是可以保障代码交付质量

📒 生成自增 ID :

看到一个通过 generator 函数生成自增 ID 的方法:

function *customIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

看了下其实还可以通过闭包实现:

function customIdGenerator() {
let i = 0;
return {
next() {
return i++;
}
}
}

const IDGenerator = customIdGenerator();
IDGenerator.next(); // 0
IDGenerator.next(); // 1
IDGenerator.next(); // 2
IDGenerator.next(); // 3
IDGenerator.next(); // 4
IDGenerator.next(); // 5
tip

注意:

++i 是先加再作为表达式的值去赋值,相当于 (i = i + 1)

i++ 是先把原来的值作为表达式的值赋值再加

📒 专业名词

缓存命中 规则命中 增量构建

📒 Promise 四种常用工具方法

  • Promise.all() :接收一个 Promise 数组,如果所有 Promisefulfilled 则返回结果数组,只要有一个 Promise 变为 rejected ,则返回最先 rejected 的 Promise ,通常用于并发请求
  • Promise.race() :接收一个 Promise 数组,race 意思就是比谁快,返回状态最先改变的 Promise ,不管成功还是失败,通常用于请求超时处理
  • Promise.any() :接收一个 Promise 数组,返回最先 fulfilledPromise ,如果没有 Promise 状态转为 fulfilled ,则抛出一个 AggregateError
  • Promise.allSettled() :接收一个 Promise 数组,在所有 Promise 状态改变(fulfilled 或者 rejected)之后返回结果数组。Promise.allSettled 适用于异步任务互相不依赖,Promise.all 适用于异步任务互相之间需要依赖其他任务的结果;

📒 什么时候不能使用箭头函数

  • 需要函数提升时(箭头函数只能写成表达式形式);
  • 需要使用函数的 thisargumentsprototype 时;
  • 需要使用命名函数时(箭头函数是匿名的);
  • 需要作为构造函数时(箭头函数不能作为构造函数);
  • 需要在对象方法中访问当前对象时;
let obj = {
a: 1,
fn1: () => {
console.log(this)
},
fn2: function() {
console.log(this)
}
}
obj.fn1(); // Window
obj.fn2(); // {a: 1, fn1: ƒ, fn2: ƒ} ,这是 this 的隐式绑定

const f1 = obj.fn1;
const f2 = obj.fn2;
f1(); // Window
f2(); // Window ,隐式绑定取决于谁来调用,谁调用就指向谁

使用箭头函数之所以会指向 Window 是因为箭头函数等价于下面的代码:

var that = this; // 直接使用闭包缓存 this
let obj = {
a: 1,
fn1: function() {
console.log(that);
}
}

在对象方法(例如 Vue Options API)的异步回调中经常会遇到 this 丢失的情况,一般会使用闭包进行缓存:

// 使用 _this 变量进行缓存
const _this = this;
api.get("/api/xxx", function(res) {
_this.tableData = res;
})

// 除了使用闭包缓存 this ,还可以使用箭头函数
api.get("/api/xxx", (res) => {
this.tableData = res;
})

总结一下:箭头函数没有自己的 this ,没有 argument 对象,没有 prototype ,不能作为构造函数(用 new 调用会报错)。箭头函数会自动捕获上级词法作用域的 this ,并且箭头函数的 this 在声明的时候就已经确定了,不能通过 call 或者 apply 修改

- - + + \ No newline at end of file diff --git "a/2021/tags/babel-\346\217\222\344\273\266/index.html" "b/2021/tags/babel-\346\217\222\344\273\266/index.html" index b2fb417592..2770357a8f 100644 --- "a/2021/tags/babel-\346\217\222\344\273\266/index.html" +++ "b/2021/tags/babel-\346\217\222\344\273\266/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git a/2021/tags/browserslist/index.html b/2021/tags/browserslist/index.html index d504f00c4d..60de7ecabd 100644 --- a/2021/tags/browserslist/index.html +++ b/2021/tags/browserslist/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/2021/tags/chrome/index.html b/2021/tags/chrome/index.html index 5022c6d763..22e34a13b4 100644 --- a/2021/tags/chrome/index.html +++ b/2021/tags/chrome/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Chrome"

View All Tags

· 2 min read
加菲猫

📒 如何切换后端环境

在前端项目中,后端接口请求通常都通过 devServer 代理,这样解决了跨域问题。但是开发的时候经常需要切换后端环境,每次切换都要重启 devServer,这就导致每次都要重新构建,比较麻烦。

一种解决思路是,前端项目中后端接口地址使用 域名,在 系统 host 文件 中配置域名与 IP 地址的映射,这样每次切换后端环境,只需要修改系统 host 文件,然后在浏览器中刷新页面就可以实现切换。

但是每次手动修改 host 文件有点麻烦,可以使用 SwitchHost 工具,一键切换,非常方便。

📒 Vue 3 技术栈

  • Vue3.2:核心库
  • Vite2.6:官方推出的基于 ESM 的构建工具
  • vue-router-next:Vue3 官方路由
  • pinia:官方推出的状态管理库
  • TypeScript:静态类型检查
  • Volar:Vue3 的 vscode 插件

📒 Chrome 调试小技巧

在断点位置按 F9,可以一步一步往下执行,调试源码的时候查看调用栈特别有用。当然很多时候调用栈比较复杂,这时候通过 Performance 面板的火焰图看比较直观,火焰图的宽度代表执行耗时,火焰图的高度代表调用栈的深度。

📒 CommonJS 中的模块导出

CommonJS 规范中只有一种模块导出:module.exports ,而 exports 仅仅只是 module.exports 的引用而已

📒 推荐两个网站

  • caniuse:查询 api 兼容性
  • codeif:变量命名
- - + + \ No newline at end of file diff --git a/2021/tags/common-js/index.html b/2021/tags/common-js/index.html index 00f105c56b..ec2b900bad 100644 --- a/2021/tags/common-js/index.html +++ b/2021/tags/common-js/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "CommonJS"

View All Tags

· 2 min read
加菲猫

📒 如何切换后端环境

在前端项目中,后端接口请求通常都通过 devServer 代理,这样解决了跨域问题。但是开发的时候经常需要切换后端环境,每次切换都要重启 devServer,这就导致每次都要重新构建,比较麻烦。

一种解决思路是,前端项目中后端接口地址使用 域名,在 系统 host 文件 中配置域名与 IP 地址的映射,这样每次切换后端环境,只需要修改系统 host 文件,然后在浏览器中刷新页面就可以实现切换。

但是每次手动修改 host 文件有点麻烦,可以使用 SwitchHost 工具,一键切换,非常方便。

📒 Vue 3 技术栈

  • Vue3.2:核心库
  • Vite2.6:官方推出的基于 ESM 的构建工具
  • vue-router-next:Vue3 官方路由
  • pinia:官方推出的状态管理库
  • TypeScript:静态类型检查
  • Volar:Vue3 的 vscode 插件

📒 Chrome 调试小技巧

在断点位置按 F9,可以一步一步往下执行,调试源码的时候查看调用栈特别有用。当然很多时候调用栈比较复杂,这时候通过 Performance 面板的火焰图看比较直观,火焰图的宽度代表执行耗时,火焰图的高度代表调用栈的深度。

📒 CommonJS 中的模块导出

CommonJS 规范中只有一种模块导出:module.exports ,而 exports 仅仅只是 module.exports 的引用而已

📒 推荐两个网站

  • caniuse:查询 api 兼容性
  • codeif:变量命名
- - + + \ No newline at end of file diff --git a/2021/tags/css-in-js/index.html b/2021/tags/css-in-js/index.html index a8422a8d9d..dc27872459 100644 --- a/2021/tags/css-in-js/index.html +++ b/2021/tags/css-in-js/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "CSS in JS"

View All Tags

· 6 min read
加菲猫

📒 优雅获取 package.json 文件

这里需要注意一个问题,在 ES module 规范下无法直接引入 JSON 文件,只能通过 require 获取:

// ES module 模块
import React from "react";
import { debounce } from "lodash-es";
// JSON 模块只能通过 CJS 方式加载
const package = require("package.json");

import 命令目前只能用于加载 ES 模块,现在有一个提案,允许加载 JSON 模块。import 命令能够直接加载 JSON 模块以后,就可以像下面这样写:

import configData from './config.json' assert { type: "json" };
console.log(configData.appName);

import 命令导入 JSON 模块时,命令结尾的 assert {type: "json"} 不可缺少。这叫做导入断言,用来告诉 JavaScript 引擎,现在加载的是 JSON 模块

除此之外,还可以使用第三方库 read-pkg 获取,原理是通过 fs 模块读取 package.json 文件,然后反序列化为 JS 对象:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

export async function readPackage({cwd = process.cwd(), normalize = true} = {}) {
const filePath = path.resolve(cwd, 'package.json');
const json = parseJson(await fsPromises.readFile(filePath, 'utf8'));

if (normalize) {
normalizePackageData(json);
}

return json;
}

📒 如何覆盖某些元素的浏览器默认样式

很多元素,例如 <button><input type="text" /><input type="checkbox" /> 具有浏览器默认样式,有时候需要自己指定样式,如何覆盖浏览器默认样式,只需要下面一行代码:

input {
-webkit-appearance: none;
}

📒 如何让 div 按比例缩放

有时希望 div 自适应页面宽度的时候,可以按比例缩放,这种情况下可以使用 aspect-ratio 属性:

div {
aspect-ratio: auto 1 / 1;
}

推荐在 ratio 前面加 auto ,对于 input 等具有固有宽高比的替换元素将使用默认宽高比,否则就使用指定的宽高比。

注意 aspect-ratio 兼容 Chrome > 87 ,所有的 IE 浏览器都不兼容

aspect-ratio - MDN

📒 如何维护一个大型的 Next.js 应用

📒 Goober:CSS-in-JS 方案

这是一个 1 KB 大小的 CSS-in-JS 方案,可以替代 23 KB 的 styled-components 和 emotion 组合。而且如果你可以减少 goober 库 gzip 后的体积,他们还会奖励你美元。

https://github.com/cristianbote/goober

📒 使用支持 Tree Shaking 的包

如果可以的话,应尽量使用支持 Tree Shaking 的 npm 包,例如:

  • 使用 lodash-es 替代 lodash ,或者使用 babel-plugin-lodash 实现类似效果

📒 win10 安装 nvm-windows

下载地址:

https://github.com/coreybutler/nvm-windows/releases

用法跟 mac 上的 nvm 类似:

# 安装 nodejs v16.13.1
$ nvm install 16.13.1

# 查看已安装的 nodejs 版本
$ nvm list

# 使用指定版本的 nodejs
$ nvm use 16.13.1

# 卸载某个版本的 nodejs
$ nvm uninstall 16.13.1

个人猜测是通过修改环境变量实现 node 版本切换

在使用的时候遇到两个问题:

  1. 安装老版本 nodejs 的时候,node 安装成功,但是 npm 安装失败;
  2. 使用 nvm use 切换 node 版本的时候报错;

第一个问题,给 nvm 配置淘宝镜像即可解决。找到 nvm 安装目录下的 settings.txt 文件,添加配置:

node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

第二个问题,首先检查 nvm 安装路径没有中文、没有空格,然后如果问题还在,那就是权限问题,使用管理员权限打开 cmd 即可正常切换。

📒 获取 worker 线程最大并发数

通过下面的只读属性获取用户计算机的逻辑内核数:

logicalProcessors = window.navigator.hardwareConcurrency

下面的代码中,为每一个逻辑内核创建一个 worker 线程,充分利用 CPU 资源:

let workerList = [];

for (let i = 0; i < window.navigator.hardwareConcurrency; i++) {
let newWorker = {
worker: new Worker('cpuworker.js'),
inUse: false
};
workerList.push(newWorker);
}

Navigator.hardwareConcurrency - MDN

📒 TypeScript类型中的逆变协变

📒 如何优雅引入 node 内置模块

在引用 node 内置模块的时候可以加 node: 前缀,比如:

import util from 'node:util';
import { promisify } from 'node:util';
import { spawn, exec } from 'node:child_process';

通过增加前缀,可以将 node 内置模块与其他第三方模块区分开:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

看到这边有同学会问,为啥 node 中可以使用 ES module,实际上现在 node 已经支持了 ES module ,只需要在 package.json 中设置如下字段即可:

{
name: "xxx",
version: "1.0.0"
type: "module", // 默认 commonjs
}

从 vue-cli 源码中,我发现27行读取 json 文件有趣的 npm 包

📒 gradient-string: 在终端中输出漂亮的渐变色

image

https://github.com/bokub/gradient-string

📒 手写系列-实现一个铂金段位的 React

- - + + \ No newline at end of file diff --git "a/2021/tags/git-\345\260\217\346\212\200\345\267\247/index.html" "b/2021/tags/git-\345\260\217\346\212\200\345\267\247/index.html" index 13b791b09d..7d135ec002 100644 --- "a/2021/tags/git-\345\260\217\346\212\200\345\267\247/index.html" +++ "b/2021/tags/git-\345\260\217\346\212\200\345\267\247/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git a/2021/tags/golang/index.html b/2021/tags/golang/index.html index 3641b8febe..ed204ecb2f 100644 --- a/2021/tags/golang/index.html +++ b/2021/tags/golang/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

2 posts tagged with "Golang"

View All Tags

· 4 min read
加菲猫

⭐️ Webpack 分包最佳实践

SplitChunksPlugin 进行分包的三要素:

  1. minChunks: 一个模块是否最少被 minChunks 个 chunk 所引用
  2. maxInitialRequests/maxAsyncRequests: 最多只能有 maxInitialRequests/maxAsyncRequests 个 chunk 需要同时加载 (如一个 Chunk 依赖 VendorChunk 才可正常工作,此时同时加载 chunk 数为 2)
  3. minSize/maxSize: chunk 的体积必须介于 (minSize, maxSize) 之间

哪些应该单独分包:

  1. Webpack 运行时
  2. React Framework 运行时,包括 React/React-DOM 及它们所有的依赖
  3. 大型库,体积特别大的库
  4. 公共库,至少被 4 个 Chunk 所引用的公共模块
tip

Webpack 配置最佳实践,除了 Vue-cli 和 CRA 源码,还可以参考 next.js 源码:

https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts

Webpack 性能系列四:分包优化

📒 【内部分享】看向未来 - 近期 TC39 提案汇总

📒 如何移除代码中的 console

  1. 使用 uglifyjs-webpack-pluginterser-webpack-plugin 中的 drop_console 配置;

  2. 使用 Babel 插件 babel-plugin-transform-remove-console

  3. 简单粗暴删除,直接重写 console.log 方法;

    console.log = function() {};
  4. 手写 webpack loader 删除;

    // clearConsole.js
    const reg = /(console.log\()(.*)(\))/g;
    module.exports = function(source) {
    source = source.replace(reg, "")
    return source;
    }

    基于正则匹配还是有一些问题,例如 const { log } = console 或者 const log = console.log.bind(console) 这种就匹配不到

📒 WebRTC 录屏技术

WebRTC 是一套基于音视轨的实时数据流传播的技术方案。通过浏览器原生 API navigator.mediaDevices.getDisplayMedia 方法实现提示用户选择和授权捕获展示的窗口,进而获取 stream (录制的屏幕音视流)。我们可以对 stream 进行转化处理,转成相对应的媒体数据,并将其数据存储。

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia

📒 Go 1.18 Beta 1 已经正支持泛型

📒 使用Golang、Gin和React、esbuild开发的Blog

📒 使用 patch-package 修复 npm 库的紧急问题

如果使用的 npm 库有 bug,可以使用 patch-package 创建一个补丁包。

工程化知识卡片 022: 质量保障篇之如何优雅某个 npm 库的紧急问题

📒 5 种有趣的 useEffect 无限循环类型

📒 用 CSS 来代替 JS 的实现

📒 React18 新特性:transition

📒 「2021」我给Vue.js生态贡献代码的这一年

⭐️ ⭐️ fiber:受到 Express 启发的 Web 应用框架,使用 Go 开发,与 Express 的 API 非常接近

package main

import "github.com/gofiber/fiber/v2"

func main() {
app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World 👋!")
})

app.Listen(":3000")
}

https://github.com/gofiber/fiber

- - + + \ No newline at end of file diff --git a/2021/tags/index.html b/2021/tags/index.html index 1f546a2ade..254ed61fd6 100644 --- a/2021/tags/index.html +++ b/2021/tags/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/2021/tags/node-js/index.html b/2021/tags/node-js/index.html index 3bccac3239..84f3e513a4 100644 --- a/2021/tags/node-js/index.html +++ b/2021/tags/node-js/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Node.js"

View All Tags

· 6 min read
加菲猫

📒 优雅获取 package.json 文件

这里需要注意一个问题,在 ES module 规范下无法直接引入 JSON 文件,只能通过 require 获取:

// ES module 模块
import React from "react";
import { debounce } from "lodash-es";
// JSON 模块只能通过 CJS 方式加载
const package = require("package.json");

import 命令目前只能用于加载 ES 模块,现在有一个提案,允许加载 JSON 模块。import 命令能够直接加载 JSON 模块以后,就可以像下面这样写:

import configData from './config.json' assert { type: "json" };
console.log(configData.appName);

import 命令导入 JSON 模块时,命令结尾的 assert {type: "json"} 不可缺少。这叫做导入断言,用来告诉 JavaScript 引擎,现在加载的是 JSON 模块

除此之外,还可以使用第三方库 read-pkg 获取,原理是通过 fs 模块读取 package.json 文件,然后反序列化为 JS 对象:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

export async function readPackage({cwd = process.cwd(), normalize = true} = {}) {
const filePath = path.resolve(cwd, 'package.json');
const json = parseJson(await fsPromises.readFile(filePath, 'utf8'));

if (normalize) {
normalizePackageData(json);
}

return json;
}

📒 如何覆盖某些元素的浏览器默认样式

很多元素,例如 <button><input type="text" /><input type="checkbox" /> 具有浏览器默认样式,有时候需要自己指定样式,如何覆盖浏览器默认样式,只需要下面一行代码:

input {
-webkit-appearance: none;
}

📒 如何让 div 按比例缩放

有时希望 div 自适应页面宽度的时候,可以按比例缩放,这种情况下可以使用 aspect-ratio 属性:

div {
aspect-ratio: auto 1 / 1;
}

推荐在 ratio 前面加 auto ,对于 input 等具有固有宽高比的替换元素将使用默认宽高比,否则就使用指定的宽高比。

注意 aspect-ratio 兼容 Chrome > 87 ,所有的 IE 浏览器都不兼容

aspect-ratio - MDN

📒 如何维护一个大型的 Next.js 应用

📒 Goober:CSS-in-JS 方案

这是一个 1 KB 大小的 CSS-in-JS 方案,可以替代 23 KB 的 styled-components 和 emotion 组合。而且如果你可以减少 goober 库 gzip 后的体积,他们还会奖励你美元。

https://github.com/cristianbote/goober

📒 使用支持 Tree Shaking 的包

如果可以的话,应尽量使用支持 Tree Shaking 的 npm 包,例如:

  • 使用 lodash-es 替代 lodash ,或者使用 babel-plugin-lodash 实现类似效果

📒 win10 安装 nvm-windows

下载地址:

https://github.com/coreybutler/nvm-windows/releases

用法跟 mac 上的 nvm 类似:

# 安装 nodejs v16.13.1
$ nvm install 16.13.1

# 查看已安装的 nodejs 版本
$ nvm list

# 使用指定版本的 nodejs
$ nvm use 16.13.1

# 卸载某个版本的 nodejs
$ nvm uninstall 16.13.1

个人猜测是通过修改环境变量实现 node 版本切换

在使用的时候遇到两个问题:

  1. 安装老版本 nodejs 的时候,node 安装成功,但是 npm 安装失败;
  2. 使用 nvm use 切换 node 版本的时候报错;

第一个问题,给 nvm 配置淘宝镜像即可解决。找到 nvm 安装目录下的 settings.txt 文件,添加配置:

node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

第二个问题,首先检查 nvm 安装路径没有中文、没有空格,然后如果问题还在,那就是权限问题,使用管理员权限打开 cmd 即可正常切换。

📒 获取 worker 线程最大并发数

通过下面的只读属性获取用户计算机的逻辑内核数:

logicalProcessors = window.navigator.hardwareConcurrency

下面的代码中,为每一个逻辑内核创建一个 worker 线程,充分利用 CPU 资源:

let workerList = [];

for (let i = 0; i < window.navigator.hardwareConcurrency; i++) {
let newWorker = {
worker: new Worker('cpuworker.js'),
inUse: false
};
workerList.push(newWorker);
}

Navigator.hardwareConcurrency - MDN

📒 TypeScript类型中的逆变协变

📒 如何优雅引入 node 内置模块

在引用 node 内置模块的时候可以加 node: 前缀,比如:

import util from 'node:util';
import { promisify } from 'node:util';
import { spawn, exec } from 'node:child_process';

通过增加前缀,可以将 node 内置模块与其他第三方模块区分开:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

看到这边有同学会问,为啥 node 中可以使用 ES module,实际上现在 node 已经支持了 ES module ,只需要在 package.json 中设置如下字段即可:

{
name: "xxx",
version: "1.0.0"
type: "module", // 默认 commonjs
}

从 vue-cli 源码中,我发现27行读取 json 文件有趣的 npm 包

📒 gradient-string: 在终端中输出漂亮的渐变色

image

https://github.com/bokub/gradient-string

📒 手写系列-实现一个铂金段位的 React

- - + + \ No newline at end of file diff --git "a/2021/tags/npm-\345\217\221\345\214\205/index.html" "b/2021/tags/npm-\345\217\221\345\214\205/index.html" index 23fd854685..230182c430 100644 --- "a/2021/tags/npm-\345\217\221\345\214\205/index.html" +++ "b/2021/tags/npm-\345\217\221\345\214\205/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git a/2021/tags/npm/index.html b/2021/tags/npm/index.html index 55fc827745..953dd90e1a 100644 --- a/2021/tags/npm/index.html +++ b/2021/tags/npm/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

2 posts tagged with "NPM"

View All Tags

· 6 min read
加菲猫

📒 腾讯技术工程相关文章

⭐️ 收藏 | 腾讯技术 2020 年精华文章合集

🐛 生产环境如何 debug

  • 定位错误是前端还是后端接口返回的
    • 前端代码全局搜索关键字(vscode 或者 chorme devtools 中搜索)
    • 翻阅 network 面板中的请求,使用 ⌘ + F 打开 network search 面板进行搜索
  • 如何调试混淆压缩后的 JS
    • 使用 source 面板中的 pretty-print 选项
    • 这样还是存在问题,例如很多变量名、方法名都被混淆压缩了,然后 babel 会将 ES2015+ 语法进行语法转换,代码可读性降低
  • 如何在生产环境中使用 sourceMap 调试
    • 打开混淆压缩的代码,右键选择 Add source map
    • 这里需要添加一个 source map URL,可以将本地项目添加到 source 面板中的 Filesystem 中,或者启用静态资源服务
    • 添加之后就可以直接搜索项目中的源文件了
  • 如何在 chrome 中修改代码并调试
    • chrome devtools 提供了 local overrides 能力,指定修改后的文件的本地保存目录,当修改完代码保存的时候,就会将修改后的文件保存到你指定的目录目录下,当再次加载页面的时候,对应的文件不再读取网络上的文件,而是读取存储在本地修改过的文件
    • 打开 sources 下的 overrides 面板,点击 select folder overrides 选择修改后的文件件存储地址,我们就可以打开文件修改,修改完成后保存,重新刷新页面后,修改后的代码就被执行到了

前端工程师生产环境 debugger 技巧

📒 如何在 React 中优雅使用 ECharts

初始化 ECharts 的时候不要使用 id,否则无法渲染多个组件实例:

import * as React from "react";
import * as echarts from "echarts";

const LineChart = (props) => {
const chartRef = React.useRef();

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);
}, [props])

return <div ref={chartRef} className="chart"></div>
}

export default React.memo(LineChart);

如何让 ECharts 实现自适应,可以在窗口尺寸变化的时候,调用 chart 实例上的 resize 方法:

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);

const handleResize = () => {
chart.resize();
}

// 绑定 resize 事件监听器
window.addEventListener("resize", handleResize);

return () => {
// 组件更新或者卸载时移除监听
window.removeEventListener("resize", handleResize);
}
}, [props])

推荐使用 addEventListener 绑定事件,可以多次绑定,但是要注意及时 remove,不然会导致内存泄漏

📒 看火焰图分析调用栈的时候,看到一个 asyncGeneratorStep 的函数,一直没搞清楚这个在哪里用到了

image

事后才想到这是 babel 语法转换引入的 helper 函数

image

📒 使用 webpack-chain 对 vue-cli 默认配置进行修改

https://github.com/Yatoo2018/webpack-chain/tree/zh-cmn-Hans

📒 如何对 webpack 打包产物进行分析

经常需要分析打包产物的体积,看哪个包体积过大,做针对性优化。可以使用 Webpack Bundle Analyzer:

$ yarn add webpack-bundle-analyzer -D

webpack.config.js 中添加如下配置:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}

然后执行打包构建命令:

$ yarn build --report

https://github.com/webpack-contrib/webpack-bundle-analyzer

📒 create-react-app 发布 5.0 版本

本次的 5.0 版本优化了快速刷新(Fast Refresh),支持了 Tailwind,并更新了不少内部依赖库,如 Webpack 5、Jest 27 和 EsLint 8 等。

https://github.com/facebook/create-react-app/releases/tag/v5.0.0

📒 处理你应用中的内存泄漏

作者 Stoyan 提到:“任何大小合理的应用中,都会存在一定程度的内存泄漏”。因此知道如何处理泄漏是一件很有用的事。在本文中,作者举了一个 React 中的例子,不过它的基本理念却可以运用在任何地方。

https://calendar.perfplanet.com/2021/plugging-memory-leaks-in-your-app/

📒 kalidokit:人体动作表情解读同步

效果还是和牛逼的,真人测试。

https://github.com/yeemachine/kalidokit

📒 xterm:把命令行搬到浏览器

https://xtermjs.org/

📒 microdiff:轻量快速的对比库

https://github.com/AsyncBanana/microdiff

· 4 min read
加菲猫

⭐️ Webpack 分包最佳实践

SplitChunksPlugin 进行分包的三要素:

  1. minChunks: 一个模块是否最少被 minChunks 个 chunk 所引用
  2. maxInitialRequests/maxAsyncRequests: 最多只能有 maxInitialRequests/maxAsyncRequests 个 chunk 需要同时加载 (如一个 Chunk 依赖 VendorChunk 才可正常工作,此时同时加载 chunk 数为 2)
  3. minSize/maxSize: chunk 的体积必须介于 (minSize, maxSize) 之间

哪些应该单独分包:

  1. Webpack 运行时
  2. React Framework 运行时,包括 React/React-DOM 及它们所有的依赖
  3. 大型库,体积特别大的库
  4. 公共库,至少被 4 个 Chunk 所引用的公共模块
tip

Webpack 配置最佳实践,除了 Vue-cli 和 CRA 源码,还可以参考 next.js 源码:

https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts

Webpack 性能系列四:分包优化

📒 【内部分享】看向未来 - 近期 TC39 提案汇总

📒 如何移除代码中的 console

  1. 使用 uglifyjs-webpack-pluginterser-webpack-plugin 中的 drop_console 配置;

  2. 使用 Babel 插件 babel-plugin-transform-remove-console

  3. 简单粗暴删除,直接重写 console.log 方法;

    console.log = function() {};
  4. 手写 webpack loader 删除;

    // clearConsole.js
    const reg = /(console.log\()(.*)(\))/g;
    module.exports = function(source) {
    source = source.replace(reg, "")
    return source;
    }

    基于正则匹配还是有一些问题,例如 const { log } = console 或者 const log = console.log.bind(console) 这种就匹配不到

📒 WebRTC 录屏技术

WebRTC 是一套基于音视轨的实时数据流传播的技术方案。通过浏览器原生 API navigator.mediaDevices.getDisplayMedia 方法实现提示用户选择和授权捕获展示的窗口,进而获取 stream (录制的屏幕音视流)。我们可以对 stream 进行转化处理,转成相对应的媒体数据,并将其数据存储。

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia

📒 Go 1.18 Beta 1 已经正支持泛型

📒 使用Golang、Gin和React、esbuild开发的Blog

📒 使用 patch-package 修复 npm 库的紧急问题

如果使用的 npm 库有 bug,可以使用 patch-package 创建一个补丁包。

工程化知识卡片 022: 质量保障篇之如何优雅某个 npm 库的紧急问题

📒 5 种有趣的 useEffect 无限循环类型

📒 用 CSS 来代替 JS 的实现

📒 React18 新特性:transition

📒 「2021」我给Vue.js生态贡献代码的这一年

⭐️ ⭐️ fiber:受到 Express 启发的 Web 应用框架,使用 Go 开发,与 Express 的 API 非常接近

package main

import "github.com/gofiber/fiber/v2"

func main() {
app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World 👋!")
})

app.Listen(":3000")
}

https://github.com/gofiber/fiber

- - + + \ No newline at end of file diff --git a/2021/tags/promise/index.html b/2021/tags/promise/index.html index fd283008a7..d9bce7c9a4 100644 --- a/2021/tags/promise/index.html +++ b/2021/tags/promise/index.html @@ -11,15 +11,15 @@ - - + +
Skip to main content

One post tagged with "Promise"

View All Tags

· 5 min read
加菲猫

📒 构建提效

  • 打包工具:webpack -> rollup
  • 生成 AST :babel -> acorn
  • 语法转换:babel -> swc
  • 代码压缩:terser -> esbuild

📒 代码规范相关

  • ESLint 用于代码规范检查,在开发阶段提前规避问题,提升代码健壮性
  • Prettier 用于代码风格校验,统一团队编码风格

实际上编写文档、单元测试、类型声明、tsconfig.json 、ESLint 、Prettier 、lint-staged 、husky 这些对实现功能上来说没有任何作用,但是可以保障代码交付质量

📒 生成自增 ID :

看到一个通过 generator 函数生成自增 ID 的方法:

function *customIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

看了下其实还可以通过闭包实现:

function customIdGenerator() {
let i = 0;
return {
next() {
return i++;
}
}
}

const IDGenerator = customIdGenerator();
IDGenerator.next(); // 0
IDGenerator.next(); // 1
IDGenerator.next(); // 2
IDGenerator.next(); // 3
IDGenerator.next(); // 4
IDGenerator.next(); // 5
tip

注意:

++i 是先加再作为表达式的值去赋值,相当于 (i = i + 1)

i++ 是先把原来的值作为表达式的值赋值再加

📒 专业名词

缓存命中 规则命中 增量构建

📒 Promise 四种常用工具方法

  • Promise.all() :接收一个 Promise 数组,如果所有 Promisefulfilled 则返回结果数组,只要有一个 Promise 变为 rejected ,则返回最先 rejected 的 Promise ,通常用于并发请求
  • Promise.race() :接收一个 Promise 数组,race 意思就是比谁快,返回状态最先改变的 Promise ,不管成功还是失败,通常用于请求超时处理
  • Promise.any() :接收一个 Promise 数组,返回最先 fulfilledPromise ,如果没有 Promise 状态转为 fulfilled ,则抛出一个 AggregateError
  • Promise.allSettled() :接收一个 Promise 数组,在所有 Promise 状态改变(fulfilled 或者 rejected)之后返回结果数组。Promise.allSettled 适用于异步任务互相不依赖,Promise.all 适用于异步任务互相之间需要依赖其他任务的结果;

📒 什么时候不能使用箭头函数

  • 需要函数提升时(箭头函数只能写成表达式形式);
  • 需要使用函数的 thisargumentsprototype 时;
  • 需要使用命名函数时(箭头函数是匿名的);
  • 需要作为构造函数时(箭头函数不能作为构造函数);
  • 需要在对象方法中访问当前对象时;
let obj = {
a: 1,
fn1: () => {
console.log(this)
},
fn2: function() {
console.log(this)
}
}
obj.fn1(); // Window
obj.fn2(); // {a: 1, fn1: ƒ, fn2: ƒ} ,这是 this 的隐式绑定

const f1 = obj.fn1;
const f2 = obj.fn2;
f1(); // Window
f2(); // Window ,隐式绑定取决于谁来调用,谁调用就指向谁

使用箭头函数之所以会指向 Window 是因为箭头函数等价于下面的代码:

var that = this; // 直接使用闭包缓存 this
let obj = {
a: 1,
fn1: function() {
console.log(that);
}
}

在对象方法(例如 Vue Options API)的异步回调中经常会遇到 this 丢失的情况,一般会使用闭包进行缓存:

// 使用 _this 变量进行缓存
const _this = this;
api.get("/api/xxx", function(res) {
_this.tableData = res;
})

// 除了使用闭包缓存 this ,还可以使用箭头函数
api.get("/api/xxx", (res) => {
this.tableData = res;
})

总结一下:箭头函数没有自己的 this ,没有 argument 对象,没有 prototype ,不能作为构造函数(用 new 调用会报错)。箭头函数会自动捕获上级词法作用域的 this ,并且箭头函数的 this 在声明的时候就已经确定了,不能通过 call 或者 apply 修改

- - + + \ No newline at end of file diff --git a/2021/tags/react-docs/index.html b/2021/tags/react-docs/index.html index c42b330cbe..6ddd585074 100644 --- a/2021/tags/react-docs/index.html +++ b/2021/tags/react-docs/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git a/2021/tags/react/index.html b/2021/tags/react/index.html index 05e4e251ab..495deb186e 100644 --- a/2021/tags/react/index.html +++ b/2021/tags/react/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

3 posts tagged with "React"

View All Tags

· 6 min read
加菲猫

📒 腾讯技术工程相关文章

⭐️ 收藏 | 腾讯技术 2020 年精华文章合集

🐛 生产环境如何 debug

  • 定位错误是前端还是后端接口返回的
    • 前端代码全局搜索关键字(vscode 或者 chorme devtools 中搜索)
    • 翻阅 network 面板中的请求,使用 ⌘ + F 打开 network search 面板进行搜索
  • 如何调试混淆压缩后的 JS
    • 使用 source 面板中的 pretty-print 选项
    • 这样还是存在问题,例如很多变量名、方法名都被混淆压缩了,然后 babel 会将 ES2015+ 语法进行语法转换,代码可读性降低
  • 如何在生产环境中使用 sourceMap 调试
    • 打开混淆压缩的代码,右键选择 Add source map
    • 这里需要添加一个 source map URL,可以将本地项目添加到 source 面板中的 Filesystem 中,或者启用静态资源服务
    • 添加之后就可以直接搜索项目中的源文件了
  • 如何在 chrome 中修改代码并调试
    • chrome devtools 提供了 local overrides 能力,指定修改后的文件的本地保存目录,当修改完代码保存的时候,就会将修改后的文件保存到你指定的目录目录下,当再次加载页面的时候,对应的文件不再读取网络上的文件,而是读取存储在本地修改过的文件
    • 打开 sources 下的 overrides 面板,点击 select folder overrides 选择修改后的文件件存储地址,我们就可以打开文件修改,修改完成后保存,重新刷新页面后,修改后的代码就被执行到了

前端工程师生产环境 debugger 技巧

📒 如何在 React 中优雅使用 ECharts

初始化 ECharts 的时候不要使用 id,否则无法渲染多个组件实例:

import * as React from "react";
import * as echarts from "echarts";

const LineChart = (props) => {
const chartRef = React.useRef();

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);
}, [props])

return <div ref={chartRef} className="chart"></div>
}

export default React.memo(LineChart);

如何让 ECharts 实现自适应,可以在窗口尺寸变化的时候,调用 chart 实例上的 resize 方法:

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);

const handleResize = () => {
chart.resize();
}

// 绑定 resize 事件监听器
window.addEventListener("resize", handleResize);

return () => {
// 组件更新或者卸载时移除监听
window.removeEventListener("resize", handleResize);
}
}, [props])

推荐使用 addEventListener 绑定事件,可以多次绑定,但是要注意及时 remove,不然会导致内存泄漏

📒 看火焰图分析调用栈的时候,看到一个 asyncGeneratorStep 的函数,一直没搞清楚这个在哪里用到了

image

事后才想到这是 babel 语法转换引入的 helper 函数

image

📒 使用 webpack-chain 对 vue-cli 默认配置进行修改

https://github.com/Yatoo2018/webpack-chain/tree/zh-cmn-Hans

📒 如何对 webpack 打包产物进行分析

经常需要分析打包产物的体积,看哪个包体积过大,做针对性优化。可以使用 Webpack Bundle Analyzer:

$ yarn add webpack-bundle-analyzer -D

webpack.config.js 中添加如下配置:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}

然后执行打包构建命令:

$ yarn build --report

https://github.com/webpack-contrib/webpack-bundle-analyzer

📒 create-react-app 发布 5.0 版本

本次的 5.0 版本优化了快速刷新(Fast Refresh),支持了 Tailwind,并更新了不少内部依赖库,如 Webpack 5、Jest 27 和 EsLint 8 等。

https://github.com/facebook/create-react-app/releases/tag/v5.0.0

📒 处理你应用中的内存泄漏

作者 Stoyan 提到:“任何大小合理的应用中,都会存在一定程度的内存泄漏”。因此知道如何处理泄漏是一件很有用的事。在本文中,作者举了一个 React 中的例子,不过它的基本理念却可以运用在任何地方。

https://calendar.perfplanet.com/2021/plugging-memory-leaks-in-your-app/

📒 kalidokit:人体动作表情解读同步

效果还是和牛逼的,真人测试。

https://github.com/yeemachine/kalidokit

📒 xterm:把命令行搬到浏览器

https://xtermjs.org/

📒 microdiff:轻量快速的对比库

https://github.com/AsyncBanana/microdiff

· 4 min read
加菲猫

⭐️ Webpack 分包最佳实践

SplitChunksPlugin 进行分包的三要素:

  1. minChunks: 一个模块是否最少被 minChunks 个 chunk 所引用
  2. maxInitialRequests/maxAsyncRequests: 最多只能有 maxInitialRequests/maxAsyncRequests 个 chunk 需要同时加载 (如一个 Chunk 依赖 VendorChunk 才可正常工作,此时同时加载 chunk 数为 2)
  3. minSize/maxSize: chunk 的体积必须介于 (minSize, maxSize) 之间

哪些应该单独分包:

  1. Webpack 运行时
  2. React Framework 运行时,包括 React/React-DOM 及它们所有的依赖
  3. 大型库,体积特别大的库
  4. 公共库,至少被 4 个 Chunk 所引用的公共模块
tip

Webpack 配置最佳实践,除了 Vue-cli 和 CRA 源码,还可以参考 next.js 源码:

https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts

Webpack 性能系列四:分包优化

📒 【内部分享】看向未来 - 近期 TC39 提案汇总

📒 如何移除代码中的 console

  1. 使用 uglifyjs-webpack-pluginterser-webpack-plugin 中的 drop_console 配置;

  2. 使用 Babel 插件 babel-plugin-transform-remove-console

  3. 简单粗暴删除,直接重写 console.log 方法;

    console.log = function() {};
  4. 手写 webpack loader 删除;

    // clearConsole.js
    const reg = /(console.log\()(.*)(\))/g;
    module.exports = function(source) {
    source = source.replace(reg, "")
    return source;
    }

    基于正则匹配还是有一些问题,例如 const { log } = console 或者 const log = console.log.bind(console) 这种就匹配不到

📒 WebRTC 录屏技术

WebRTC 是一套基于音视轨的实时数据流传播的技术方案。通过浏览器原生 API navigator.mediaDevices.getDisplayMedia 方法实现提示用户选择和授权捕获展示的窗口,进而获取 stream (录制的屏幕音视流)。我们可以对 stream 进行转化处理,转成相对应的媒体数据,并将其数据存储。

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia

📒 Go 1.18 Beta 1 已经正支持泛型

📒 使用Golang、Gin和React、esbuild开发的Blog

📒 使用 patch-package 修复 npm 库的紧急问题

如果使用的 npm 库有 bug,可以使用 patch-package 创建一个补丁包。

工程化知识卡片 022: 质量保障篇之如何优雅某个 npm 库的紧急问题

📒 5 种有趣的 useEffect 无限循环类型

📒 用 CSS 来代替 JS 的实现

📒 React18 新特性:transition

📒 「2021」我给Vue.js生态贡献代码的这一年

⭐️ ⭐️ fiber:受到 Express 启发的 Web 应用框架,使用 Go 开发,与 Express 的 API 非常接近

package main

import "github.com/gofiber/fiber/v2"

func main() {
app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World 👋!")
})

app.Listen(":3000")
}

https://github.com/gofiber/fiber

· 6 min read
加菲猫

📒 优雅获取 package.json 文件

这里需要注意一个问题,在 ES module 规范下无法直接引入 JSON 文件,只能通过 require 获取:

// ES module 模块
import React from "react";
import { debounce } from "lodash-es";
// JSON 模块只能通过 CJS 方式加载
const package = require("package.json");

import 命令目前只能用于加载 ES 模块,现在有一个提案,允许加载 JSON 模块。import 命令能够直接加载 JSON 模块以后,就可以像下面这样写:

import configData from './config.json' assert { type: "json" };
console.log(configData.appName);

import 命令导入 JSON 模块时,命令结尾的 assert {type: "json"} 不可缺少。这叫做导入断言,用来告诉 JavaScript 引擎,现在加载的是 JSON 模块

除此之外,还可以使用第三方库 read-pkg 获取,原理是通过 fs 模块读取 package.json 文件,然后反序列化为 JS 对象:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

export async function readPackage({cwd = process.cwd(), normalize = true} = {}) {
const filePath = path.resolve(cwd, 'package.json');
const json = parseJson(await fsPromises.readFile(filePath, 'utf8'));

if (normalize) {
normalizePackageData(json);
}

return json;
}

📒 如何覆盖某些元素的浏览器默认样式

很多元素,例如 <button><input type="text" /><input type="checkbox" /> 具有浏览器默认样式,有时候需要自己指定样式,如何覆盖浏览器默认样式,只需要下面一行代码:

input {
-webkit-appearance: none;
}

📒 如何让 div 按比例缩放

有时希望 div 自适应页面宽度的时候,可以按比例缩放,这种情况下可以使用 aspect-ratio 属性:

div {
aspect-ratio: auto 1 / 1;
}

推荐在 ratio 前面加 auto ,对于 input 等具有固有宽高比的替换元素将使用默认宽高比,否则就使用指定的宽高比。

注意 aspect-ratio 兼容 Chrome > 87 ,所有的 IE 浏览器都不兼容

aspect-ratio - MDN

📒 如何维护一个大型的 Next.js 应用

📒 Goober:CSS-in-JS 方案

这是一个 1 KB 大小的 CSS-in-JS 方案,可以替代 23 KB 的 styled-components 和 emotion 组合。而且如果你可以减少 goober 库 gzip 后的体积,他们还会奖励你美元。

https://github.com/cristianbote/goober

📒 使用支持 Tree Shaking 的包

如果可以的话,应尽量使用支持 Tree Shaking 的 npm 包,例如:

  • 使用 lodash-es 替代 lodash ,或者使用 babel-plugin-lodash 实现类似效果

📒 win10 安装 nvm-windows

下载地址:

https://github.com/coreybutler/nvm-windows/releases

用法跟 mac 上的 nvm 类似:

# 安装 nodejs v16.13.1
$ nvm install 16.13.1

# 查看已安装的 nodejs 版本
$ nvm list

# 使用指定版本的 nodejs
$ nvm use 16.13.1

# 卸载某个版本的 nodejs
$ nvm uninstall 16.13.1

个人猜测是通过修改环境变量实现 node 版本切换

在使用的时候遇到两个问题:

  1. 安装老版本 nodejs 的时候,node 安装成功,但是 npm 安装失败;
  2. 使用 nvm use 切换 node 版本的时候报错;

第一个问题,给 nvm 配置淘宝镜像即可解决。找到 nvm 安装目录下的 settings.txt 文件,添加配置:

node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

第二个问题,首先检查 nvm 安装路径没有中文、没有空格,然后如果问题还在,那就是权限问题,使用管理员权限打开 cmd 即可正常切换。

📒 获取 worker 线程最大并发数

通过下面的只读属性获取用户计算机的逻辑内核数:

logicalProcessors = window.navigator.hardwareConcurrency

下面的代码中,为每一个逻辑内核创建一个 worker 线程,充分利用 CPU 资源:

let workerList = [];

for (let i = 0; i < window.navigator.hardwareConcurrency; i++) {
let newWorker = {
worker: new Worker('cpuworker.js'),
inUse: false
};
workerList.push(newWorker);
}

Navigator.hardwareConcurrency - MDN

📒 TypeScript类型中的逆变协变

📒 如何优雅引入 node 内置模块

在引用 node 内置模块的时候可以加 node: 前缀,比如:

import util from 'node:util';
import { promisify } from 'node:util';
import { spawn, exec } from 'node:child_process';

通过增加前缀,可以将 node 内置模块与其他第三方模块区分开:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

看到这边有同学会问,为啥 node 中可以使用 ES module,实际上现在 node 已经支持了 ES module ,只需要在 package.json 中设置如下字段即可:

{
name: "xxx",
version: "1.0.0"
type: "module", // 默认 commonjs
}

从 vue-cli 源码中,我发现27行读取 json 文件有趣的 npm 包

📒 gradient-string: 在终端中输出漂亮的渐变色

image

https://github.com/bokub/gradient-string

📒 手写系列-实现一个铂金段位的 React

- - + + \ No newline at end of file diff --git a/2021/tags/type-script/index.html b/2021/tags/type-script/index.html index b98b6309b9..04c8ea8d93 100644 --- a/2021/tags/type-script/index.html +++ b/2021/tags/type-script/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "TypeScript"

View All Tags

· 6 min read
加菲猫

📒 优雅获取 package.json 文件

这里需要注意一个问题,在 ES module 规范下无法直接引入 JSON 文件,只能通过 require 获取:

// ES module 模块
import React from "react";
import { debounce } from "lodash-es";
// JSON 模块只能通过 CJS 方式加载
const package = require("package.json");

import 命令目前只能用于加载 ES 模块,现在有一个提案,允许加载 JSON 模块。import 命令能够直接加载 JSON 模块以后,就可以像下面这样写:

import configData from './config.json' assert { type: "json" };
console.log(configData.appName);

import 命令导入 JSON 模块时,命令结尾的 assert {type: "json"} 不可缺少。这叫做导入断言,用来告诉 JavaScript 引擎,现在加载的是 JSON 模块

除此之外,还可以使用第三方库 read-pkg 获取,原理是通过 fs 模块读取 package.json 文件,然后反序列化为 JS 对象:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

export async function readPackage({cwd = process.cwd(), normalize = true} = {}) {
const filePath = path.resolve(cwd, 'package.json');
const json = parseJson(await fsPromises.readFile(filePath, 'utf8'));

if (normalize) {
normalizePackageData(json);
}

return json;
}

📒 如何覆盖某些元素的浏览器默认样式

很多元素,例如 <button><input type="text" /><input type="checkbox" /> 具有浏览器默认样式,有时候需要自己指定样式,如何覆盖浏览器默认样式,只需要下面一行代码:

input {
-webkit-appearance: none;
}

📒 如何让 div 按比例缩放

有时希望 div 自适应页面宽度的时候,可以按比例缩放,这种情况下可以使用 aspect-ratio 属性:

div {
aspect-ratio: auto 1 / 1;
}

推荐在 ratio 前面加 auto ,对于 input 等具有固有宽高比的替换元素将使用默认宽高比,否则就使用指定的宽高比。

注意 aspect-ratio 兼容 Chrome > 87 ,所有的 IE 浏览器都不兼容

aspect-ratio - MDN

📒 如何维护一个大型的 Next.js 应用

📒 Goober:CSS-in-JS 方案

这是一个 1 KB 大小的 CSS-in-JS 方案,可以替代 23 KB 的 styled-components 和 emotion 组合。而且如果你可以减少 goober 库 gzip 后的体积,他们还会奖励你美元。

https://github.com/cristianbote/goober

📒 使用支持 Tree Shaking 的包

如果可以的话,应尽量使用支持 Tree Shaking 的 npm 包,例如:

  • 使用 lodash-es 替代 lodash ,或者使用 babel-plugin-lodash 实现类似效果

📒 win10 安装 nvm-windows

下载地址:

https://github.com/coreybutler/nvm-windows/releases

用法跟 mac 上的 nvm 类似:

# 安装 nodejs v16.13.1
$ nvm install 16.13.1

# 查看已安装的 nodejs 版本
$ nvm list

# 使用指定版本的 nodejs
$ nvm use 16.13.1

# 卸载某个版本的 nodejs
$ nvm uninstall 16.13.1

个人猜测是通过修改环境变量实现 node 版本切换

在使用的时候遇到两个问题:

  1. 安装老版本 nodejs 的时候,node 安装成功,但是 npm 安装失败;
  2. 使用 nvm use 切换 node 版本的时候报错;

第一个问题,给 nvm 配置淘宝镜像即可解决。找到 nvm 安装目录下的 settings.txt 文件,添加配置:

node_mirror: https://npm.taobao.org/mirrors/node/
npm_mirror: https://npm.taobao.org/mirrors/npm/

第二个问题,首先检查 nvm 安装路径没有中文、没有空格,然后如果问题还在,那就是权限问题,使用管理员权限打开 cmd 即可正常切换。

📒 获取 worker 线程最大并发数

通过下面的只读属性获取用户计算机的逻辑内核数:

logicalProcessors = window.navigator.hardwareConcurrency

下面的代码中,为每一个逻辑内核创建一个 worker 线程,充分利用 CPU 资源:

let workerList = [];

for (let i = 0; i < window.navigator.hardwareConcurrency; i++) {
let newWorker = {
worker: new Worker('cpuworker.js'),
inUse: false
};
workerList.push(newWorker);
}

Navigator.hardwareConcurrency - MDN

📒 TypeScript类型中的逆变协变

📒 如何优雅引入 node 内置模块

在引用 node 内置模块的时候可以加 node: 前缀,比如:

import util from 'node:util';
import { promisify } from 'node:util';
import { spawn, exec } from 'node:child_process';

通过增加前缀,可以将 node 内置模块与其他第三方模块区分开:

import process from 'node:process';
import fs, {promises as fsPromises} from 'node:fs';
import path from 'node:path';
import parseJson from 'parse-json';
import normalizePackageData from 'normalize-package-data';

看到这边有同学会问,为啥 node 中可以使用 ES module,实际上现在 node 已经支持了 ES module ,只需要在 package.json 中设置如下字段即可:

{
name: "xxx",
version: "1.0.0"
type: "module", // 默认 commonjs
}

从 vue-cli 源码中,我发现27行读取 json 文件有趣的 npm 包

📒 gradient-string: 在终端中输出漂亮的渐变色

image

https://github.com/bokub/gradient-string

📒 手写系列-实现一个铂金段位的 React

- - + + \ No newline at end of file diff --git a/2021/tags/vue-3/index.html b/2021/tags/vue-3/index.html index 2c4d73ee69..b5a4b6af2c 100644 --- a/2021/tags/vue-3/index.html +++ b/2021/tags/vue-3/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Vue3"

View All Tags

· 2 min read
加菲猫

📒 如何切换后端环境

在前端项目中,后端接口请求通常都通过 devServer 代理,这样解决了跨域问题。但是开发的时候经常需要切换后端环境,每次切换都要重启 devServer,这就导致每次都要重新构建,比较麻烦。

一种解决思路是,前端项目中后端接口地址使用 域名,在 系统 host 文件 中配置域名与 IP 地址的映射,这样每次切换后端环境,只需要修改系统 host 文件,然后在浏览器中刷新页面就可以实现切换。

但是每次手动修改 host 文件有点麻烦,可以使用 SwitchHost 工具,一键切换,非常方便。

📒 Vue 3 技术栈

  • Vue3.2:核心库
  • Vite2.6:官方推出的基于 ESM 的构建工具
  • vue-router-next:Vue3 官方路由
  • pinia:官方推出的状态管理库
  • TypeScript:静态类型检查
  • Volar:Vue3 的 vscode 插件

📒 Chrome 调试小技巧

在断点位置按 F9,可以一步一步往下执行,调试源码的时候查看调用栈特别有用。当然很多时候调用栈比较复杂,这时候通过 Performance 面板的火焰图看比较直观,火焰图的宽度代表执行耗时,火焰图的高度代表调用栈的深度。

📒 CommonJS 中的模块导出

CommonJS 规范中只有一种模块导出:module.exports ,而 exports 仅仅只是 module.exports 的引用而已

📒 推荐两个网站

  • caniuse:查询 api 兼容性
  • codeif:变量命名
- - + + \ No newline at end of file diff --git a/2021/tags/vue/index.html b/2021/tags/vue/index.html index 071a86459f..b726e25521 100644 --- a/2021/tags/vue/index.html +++ b/2021/tags/vue/index.html @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git a/2021/tags/webpack/index.html b/2021/tags/webpack/index.html index 7f5c6af405..06984ca906 100644 --- a/2021/tags/webpack/index.html +++ b/2021/tags/webpack/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

2 posts tagged with "Webpack"

View All Tags

· 6 min read
加菲猫

📒 腾讯技术工程相关文章

⭐️ 收藏 | 腾讯技术 2020 年精华文章合集

🐛 生产环境如何 debug

  • 定位错误是前端还是后端接口返回的
    • 前端代码全局搜索关键字(vscode 或者 chorme devtools 中搜索)
    • 翻阅 network 面板中的请求,使用 ⌘ + F 打开 network search 面板进行搜索
  • 如何调试混淆压缩后的 JS
    • 使用 source 面板中的 pretty-print 选项
    • 这样还是存在问题,例如很多变量名、方法名都被混淆压缩了,然后 babel 会将 ES2015+ 语法进行语法转换,代码可读性降低
  • 如何在生产环境中使用 sourceMap 调试
    • 打开混淆压缩的代码,右键选择 Add source map
    • 这里需要添加一个 source map URL,可以将本地项目添加到 source 面板中的 Filesystem 中,或者启用静态资源服务
    • 添加之后就可以直接搜索项目中的源文件了
  • 如何在 chrome 中修改代码并调试
    • chrome devtools 提供了 local overrides 能力,指定修改后的文件的本地保存目录,当修改完代码保存的时候,就会将修改后的文件保存到你指定的目录目录下,当再次加载页面的时候,对应的文件不再读取网络上的文件,而是读取存储在本地修改过的文件
    • 打开 sources 下的 overrides 面板,点击 select folder overrides 选择修改后的文件件存储地址,我们就可以打开文件修改,修改完成后保存,重新刷新页面后,修改后的代码就被执行到了

前端工程师生产环境 debugger 技巧

📒 如何在 React 中优雅使用 ECharts

初始化 ECharts 的时候不要使用 id,否则无法渲染多个组件实例:

import * as React from "react";
import * as echarts from "echarts";

const LineChart = (props) => {
const chartRef = React.useRef();

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);
}, [props])

return <div ref={chartRef} className="chart"></div>
}

export default React.memo(LineChart);

如何让 ECharts 实现自适应,可以在窗口尺寸变化的时候,调用 chart 实例上的 resize 方法:

React.useEffect(() => {
const chart = echarts.init(chartRef.current);
const option = {
// ...
}
chart.setOptions(option);

const handleResize = () => {
chart.resize();
}

// 绑定 resize 事件监听器
window.addEventListener("resize", handleResize);

return () => {
// 组件更新或者卸载时移除监听
window.removeEventListener("resize", handleResize);
}
}, [props])

推荐使用 addEventListener 绑定事件,可以多次绑定,但是要注意及时 remove,不然会导致内存泄漏

📒 看火焰图分析调用栈的时候,看到一个 asyncGeneratorStep 的函数,一直没搞清楚这个在哪里用到了

image

事后才想到这是 babel 语法转换引入的 helper 函数

image

📒 使用 webpack-chain 对 vue-cli 默认配置进行修改

https://github.com/Yatoo2018/webpack-chain/tree/zh-cmn-Hans

📒 如何对 webpack 打包产物进行分析

经常需要分析打包产物的体积,看哪个包体积过大,做针对性优化。可以使用 Webpack Bundle Analyzer:

$ yarn add webpack-bundle-analyzer -D

webpack.config.js 中添加如下配置:

const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');

module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
}

然后执行打包构建命令:

$ yarn build --report

https://github.com/webpack-contrib/webpack-bundle-analyzer

📒 create-react-app 发布 5.0 版本

本次的 5.0 版本优化了快速刷新(Fast Refresh),支持了 Tailwind,并更新了不少内部依赖库,如 Webpack 5、Jest 27 和 EsLint 8 等。

https://github.com/facebook/create-react-app/releases/tag/v5.0.0

📒 处理你应用中的内存泄漏

作者 Stoyan 提到:“任何大小合理的应用中,都会存在一定程度的内存泄漏”。因此知道如何处理泄漏是一件很有用的事。在本文中,作者举了一个 React 中的例子,不过它的基本理念却可以运用在任何地方。

https://calendar.perfplanet.com/2021/plugging-memory-leaks-in-your-app/

📒 kalidokit:人体动作表情解读同步

效果还是和牛逼的,真人测试。

https://github.com/yeemachine/kalidokit

📒 xterm:把命令行搬到浏览器

https://xtermjs.org/

📒 microdiff:轻量快速的对比库

https://github.com/AsyncBanana/microdiff

· 4 min read
加菲猫

⭐️ Webpack 分包最佳实践

SplitChunksPlugin 进行分包的三要素:

  1. minChunks: 一个模块是否最少被 minChunks 个 chunk 所引用
  2. maxInitialRequests/maxAsyncRequests: 最多只能有 maxInitialRequests/maxAsyncRequests 个 chunk 需要同时加载 (如一个 Chunk 依赖 VendorChunk 才可正常工作,此时同时加载 chunk 数为 2)
  3. minSize/maxSize: chunk 的体积必须介于 (minSize, maxSize) 之间

哪些应该单独分包:

  1. Webpack 运行时
  2. React Framework 运行时,包括 React/React-DOM 及它们所有的依赖
  3. 大型库,体积特别大的库
  4. 公共库,至少被 4 个 Chunk 所引用的公共模块
tip

Webpack 配置最佳实践,除了 Vue-cli 和 CRA 源码,还可以参考 next.js 源码:

https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts

Webpack 性能系列四:分包优化

📒 【内部分享】看向未来 - 近期 TC39 提案汇总

📒 如何移除代码中的 console

  1. 使用 uglifyjs-webpack-pluginterser-webpack-plugin 中的 drop_console 配置;

  2. 使用 Babel 插件 babel-plugin-transform-remove-console

  3. 简单粗暴删除,直接重写 console.log 方法;

    console.log = function() {};
  4. 手写 webpack loader 删除;

    // clearConsole.js
    const reg = /(console.log\()(.*)(\))/g;
    module.exports = function(source) {
    source = source.replace(reg, "")
    return source;
    }

    基于正则匹配还是有一些问题,例如 const { log } = console 或者 const log = console.log.bind(console) 这种就匹配不到

📒 WebRTC 录屏技术

WebRTC 是一套基于音视轨的实时数据流传播的技术方案。通过浏览器原生 API navigator.mediaDevices.getDisplayMedia 方法实现提示用户选择和授权捕获展示的窗口,进而获取 stream (录制的屏幕音视流)。我们可以对 stream 进行转化处理,转成相对应的媒体数据,并将其数据存储。

var promise = navigator.mediaDevices.getDisplayMedia(constraints);

https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getDisplayMedia

📒 Go 1.18 Beta 1 已经正支持泛型

📒 使用Golang、Gin和React、esbuild开发的Blog

📒 使用 patch-package 修复 npm 库的紧急问题

如果使用的 npm 库有 bug,可以使用 patch-package 创建一个补丁包。

工程化知识卡片 022: 质量保障篇之如何优雅某个 npm 库的紧急问题

📒 5 种有趣的 useEffect 无限循环类型

📒 用 CSS 来代替 JS 的实现

📒 React18 新特性:transition

📒 「2021」我给Vue.js生态贡献代码的这一年

⭐️ ⭐️ fiber:受到 Express 启发的 Web 应用框架,使用 Go 开发,与 Express 的 API 非常接近

package main

import "github.com/gofiber/fiber/v2"

func main() {
app := fiber.New()

app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("Hello, World 👋!")
})

app.Listen(":3000")
}

https://github.com/gofiber/fiber

- - + + \ No newline at end of file diff --git "a/2021/tags/\344\273\243\347\240\201\350\247\204\350\214\203/index.html" "b/2021/tags/\344\273\243\347\240\201\350\247\204\350\214\203/index.html" index 31bdc9f16e..967c1c0e52 100644 --- "a/2021/tags/\344\273\243\347\240\201\350\247\204\350\214\203/index.html" +++ "b/2021/tags/\344\273\243\347\240\201\350\247\204\350\214\203/index.html" @@ -11,15 +11,15 @@ - - + +
Skip to main content

One post tagged with "代码规范"

View All Tags

· 5 min read
加菲猫

📒 构建提效

  • 打包工具:webpack -> rollup
  • 生成 AST :babel -> acorn
  • 语法转换:babel -> swc
  • 代码压缩:terser -> esbuild

📒 代码规范相关

  • ESLint 用于代码规范检查,在开发阶段提前规避问题,提升代码健壮性
  • Prettier 用于代码风格校验,统一团队编码风格

实际上编写文档、单元测试、类型声明、tsconfig.json 、ESLint 、Prettier 、lint-staged 、husky 这些对实现功能上来说没有任何作用,但是可以保障代码交付质量

📒 生成自增 ID :

看到一个通过 generator 函数生成自增 ID 的方法:

function *customIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

看了下其实还可以通过闭包实现:

function customIdGenerator() {
let i = 0;
return {
next() {
return i++;
}
}
}

const IDGenerator = customIdGenerator();
IDGenerator.next(); // 0
IDGenerator.next(); // 1
IDGenerator.next(); // 2
IDGenerator.next(); // 3
IDGenerator.next(); // 4
IDGenerator.next(); // 5
tip

注意:

++i 是先加再作为表达式的值去赋值,相当于 (i = i + 1)

i++ 是先把原来的值作为表达式的值赋值再加

📒 专业名词

缓存命中 规则命中 增量构建

📒 Promise 四种常用工具方法

  • Promise.all() :接收一个 Promise 数组,如果所有 Promisefulfilled 则返回结果数组,只要有一个 Promise 变为 rejected ,则返回最先 rejected 的 Promise ,通常用于并发请求
  • Promise.race() :接收一个 Promise 数组,race 意思就是比谁快,返回状态最先改变的 Promise ,不管成功还是失败,通常用于请求超时处理
  • Promise.any() :接收一个 Promise 数组,返回最先 fulfilledPromise ,如果没有 Promise 状态转为 fulfilled ,则抛出一个 AggregateError
  • Promise.allSettled() :接收一个 Promise 数组,在所有 Promise 状态改变(fulfilled 或者 rejected)之后返回结果数组。Promise.allSettled 适用于异步任务互相不依赖,Promise.all 适用于异步任务互相之间需要依赖其他任务的结果;

📒 什么时候不能使用箭头函数

  • 需要函数提升时(箭头函数只能写成表达式形式);
  • 需要使用函数的 thisargumentsprototype 时;
  • 需要使用命名函数时(箭头函数是匿名的);
  • 需要作为构造函数时(箭头函数不能作为构造函数);
  • 需要在对象方法中访问当前对象时;
let obj = {
a: 1,
fn1: () => {
console.log(this)
},
fn2: function() {
console.log(this)
}
}
obj.fn1(); // Window
obj.fn2(); // {a: 1, fn1: ƒ, fn2: ƒ} ,这是 this 的隐式绑定

const f1 = obj.fn1;
const f2 = obj.fn2;
f1(); // Window
f2(); // Window ,隐式绑定取决于谁来调用,谁调用就指向谁

使用箭头函数之所以会指向 Window 是因为箭头函数等价于下面的代码:

var that = this; // 直接使用闭包缓存 this
let obj = {
a: 1,
fn1: function() {
console.log(that);
}
}

在对象方法(例如 Vue Options API)的异步回调中经常会遇到 this 丢失的情况,一般会使用闭包进行缓存:

// 使用 _this 变量进行缓存
const _this = this;
api.get("/api/xxx", function(res) {
_this.tableData = res;
})

// 除了使用闭包缓存 this ,还可以使用箭头函数
api.get("/api/xxx", (res) => {
this.tableData = res;
})

总结一下:箭头函数没有自己的 this ,没有 argument 对象,没有 prototype ,不能作为构造函数(用 new 调用会报错)。箭头函数会自动捕获上级词法作用域的 this ,并且箭头函数的 this 在声明的时候就已经确定了,不能通过 call 或者 apply 修改

- - + + \ No newline at end of file diff --git "a/2021/tags/\345\233\236\346\272\257\347\256\227\346\263\225/index.html" "b/2021/tags/\345\233\236\346\272\257\347\256\227\346\263\225/index.html" index 78318ef010..b8598d21b3 100644 --- "a/2021/tags/\345\233\236\346\272\257\347\256\227\346\263\225/index.html" +++ "b/2021/tags/\345\233\236\346\272\257\347\256\227\346\263\225/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git "a/2021/tags/\345\274\200\345\217\221\350\247\204\350\214\203/index.html" "b/2021/tags/\345\274\200\345\217\221\350\247\204\350\214\203/index.html" index e4fad9a5f1..6e7456be9f 100644 --- "a/2021/tags/\345\274\200\345\217\221\350\247\204\350\214\203/index.html" +++ "b/2021/tags/\345\274\200\345\217\221\350\247\204\350\214\203/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content
- - + + \ No newline at end of file diff --git "a/2021/tags/\346\226\207\346\241\243\351\203\250\347\275\262/index.html" "b/2021/tags/\346\226\207\346\241\243\351\203\250\347\275\262/index.html" index 4edbfeb4d4..c6bd711729 100644 --- "a/2021/tags/\346\226\207\346\241\243\351\203\250\347\275\262/index.html" +++ "b/2021/tags/\346\226\207\346\241\243\351\203\250\347\275\262/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git "a/2021/tags/\346\236\204\345\273\272\345\267\245\345\205\267/index.html" "b/2021/tags/\346\236\204\345\273\272\345\267\245\345\205\267/index.html" index 3da9df516c..21ff68c237 100644 --- "a/2021/tags/\346\236\204\345\273\272\345\267\245\345\205\267/index.html" +++ "b/2021/tags/\346\236\204\345\273\272\345\267\245\345\205\267/index.html" @@ -11,15 +11,15 @@ - - + +
Skip to main content

One post tagged with "构建工具"

View All Tags

· 5 min read
加菲猫

📒 构建提效

  • 打包工具:webpack -> rollup
  • 生成 AST :babel -> acorn
  • 语法转换:babel -> swc
  • 代码压缩:terser -> esbuild

📒 代码规范相关

  • ESLint 用于代码规范检查,在开发阶段提前规避问题,提升代码健壮性
  • Prettier 用于代码风格校验,统一团队编码风格

实际上编写文档、单元测试、类型声明、tsconfig.json 、ESLint 、Prettier 、lint-staged 、husky 这些对实现功能上来说没有任何作用,但是可以保障代码交付质量

📒 生成自增 ID :

看到一个通过 generator 函数生成自增 ID 的方法:

function *customIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

看了下其实还可以通过闭包实现:

function customIdGenerator() {
let i = 0;
return {
next() {
return i++;
}
}
}

const IDGenerator = customIdGenerator();
IDGenerator.next(); // 0
IDGenerator.next(); // 1
IDGenerator.next(); // 2
IDGenerator.next(); // 3
IDGenerator.next(); // 4
IDGenerator.next(); // 5
tip

注意:

++i 是先加再作为表达式的值去赋值,相当于 (i = i + 1)

i++ 是先把原来的值作为表达式的值赋值再加

📒 专业名词

缓存命中 规则命中 增量构建

📒 Promise 四种常用工具方法

  • Promise.all() :接收一个 Promise 数组,如果所有 Promisefulfilled 则返回结果数组,只要有一个 Promise 变为 rejected ,则返回最先 rejected 的 Promise ,通常用于并发请求
  • Promise.race() :接收一个 Promise 数组,race 意思就是比谁快,返回状态最先改变的 Promise ,不管成功还是失败,通常用于请求超时处理
  • Promise.any() :接收一个 Promise 数组,返回最先 fulfilledPromise ,如果没有 Promise 状态转为 fulfilled ,则抛出一个 AggregateError
  • Promise.allSettled() :接收一个 Promise 数组,在所有 Promise 状态改变(fulfilled 或者 rejected)之后返回结果数组。Promise.allSettled 适用于异步任务互相不依赖,Promise.all 适用于异步任务互相之间需要依赖其他任务的结果;

📒 什么时候不能使用箭头函数

  • 需要函数提升时(箭头函数只能写成表达式形式);
  • 需要使用函数的 thisargumentsprototype 时;
  • 需要使用命名函数时(箭头函数是匿名的);
  • 需要作为构造函数时(箭头函数不能作为构造函数);
  • 需要在对象方法中访问当前对象时;
let obj = {
a: 1,
fn1: () => {
console.log(this)
},
fn2: function() {
console.log(this)
}
}
obj.fn1(); // Window
obj.fn2(); // {a: 1, fn1: ƒ, fn2: ƒ} ,这是 this 的隐式绑定

const f1 = obj.fn1;
const f2 = obj.fn2;
f1(); // Window
f2(); // Window ,隐式绑定取决于谁来调用,谁调用就指向谁

使用箭头函数之所以会指向 Window 是因为箭头函数等价于下面的代码:

var that = this; // 直接使用闭包缓存 this
let obj = {
a: 1,
fn1: function() {
console.log(that);
}
}

在对象方法(例如 Vue Options API)的异步回调中经常会遇到 this 丢失的情况,一般会使用闭包进行缓存:

// 使用 _this 变量进行缓存
const _this = this;
api.get("/api/xxx", function(res) {
_this.tableData = res;
})

// 除了使用闭包缓存 this ,还可以使用箭头函数
api.get("/api/xxx", (res) => {
this.tableData = res;
})

总结一下:箭头函数没有自己的 this ,没有 argument 对象,没有 prototype ,不能作为构造函数(用 new 调用会报错)。箭头函数会自动捕获上级词法作用域的 this ,并且箭头函数的 this 在声明的时候就已经确定了,不能通过 call 或者 apply 修改

- - + + \ No newline at end of file diff --git "a/2021/tags/\347\254\254\344\270\211\346\226\271\345\272\223-lockfile/index.html" "b/2021/tags/\347\254\254\344\270\211\346\226\271\345\272\223-lockfile/index.html" index 2c4f12421a..fe74245026 100644 --- "a/2021/tags/\347\254\254\344\270\211\346\226\271\345\272\223-lockfile/index.html" +++ "b/2021/tags/\347\254\254\344\270\211\346\226\271\345\272\223-lockfile/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git "a/2021/tags/\347\256\255\345\244\264\345\207\275\346\225\260/index.html" "b/2021/tags/\347\256\255\345\244\264\345\207\275\346\225\260/index.html" index 1cc2ebf1c3..a57bc0f83c 100644 --- "a/2021/tags/\347\256\255\345\244\264\345\207\275\346\225\260/index.html" +++ "b/2021/tags/\347\256\255\345\244\264\345\207\275\346\225\260/index.html" @@ -11,15 +11,15 @@ - - + +
Skip to main content

One post tagged with "箭头函数"

View All Tags

· 5 min read
加菲猫

📒 构建提效

  • 打包工具:webpack -> rollup
  • 生成 AST :babel -> acorn
  • 语法转换:babel -> swc
  • 代码压缩:terser -> esbuild

📒 代码规范相关

  • ESLint 用于代码规范检查,在开发阶段提前规避问题,提升代码健壮性
  • Prettier 用于代码风格校验,统一团队编码风格

实际上编写文档、单元测试、类型声明、tsconfig.json 、ESLint 、Prettier 、lint-staged 、husky 这些对实现功能上来说没有任何作用,但是可以保障代码交付质量

📒 生成自增 ID :

看到一个通过 generator 函数生成自增 ID 的方法:

function *customIdGenerator() {
let i = 0;
while (true) {
yield i++;
}
}

看了下其实还可以通过闭包实现:

function customIdGenerator() {
let i = 0;
return {
next() {
return i++;
}
}
}

const IDGenerator = customIdGenerator();
IDGenerator.next(); // 0
IDGenerator.next(); // 1
IDGenerator.next(); // 2
IDGenerator.next(); // 3
IDGenerator.next(); // 4
IDGenerator.next(); // 5
tip

注意:

++i 是先加再作为表达式的值去赋值,相当于 (i = i + 1)

i++ 是先把原来的值作为表达式的值赋值再加

📒 专业名词

缓存命中 规则命中 增量构建

📒 Promise 四种常用工具方法

  • Promise.all() :接收一个 Promise 数组,如果所有 Promisefulfilled 则返回结果数组,只要有一个 Promise 变为 rejected ,则返回最先 rejected 的 Promise ,通常用于并发请求
  • Promise.race() :接收一个 Promise 数组,race 意思就是比谁快,返回状态最先改变的 Promise ,不管成功还是失败,通常用于请求超时处理
  • Promise.any() :接收一个 Promise 数组,返回最先 fulfilledPromise ,如果没有 Promise 状态转为 fulfilled ,则抛出一个 AggregateError
  • Promise.allSettled() :接收一个 Promise 数组,在所有 Promise 状态改变(fulfilled 或者 rejected)之后返回结果数组。Promise.allSettled 适用于异步任务互相不依赖,Promise.all 适用于异步任务互相之间需要依赖其他任务的结果;

📒 什么时候不能使用箭头函数

  • 需要函数提升时(箭头函数只能写成表达式形式);
  • 需要使用函数的 thisargumentsprototype 时;
  • 需要使用命名函数时(箭头函数是匿名的);
  • 需要作为构造函数时(箭头函数不能作为构造函数);
  • 需要在对象方法中访问当前对象时;
let obj = {
a: 1,
fn1: () => {
console.log(this)
},
fn2: function() {
console.log(this)
}
}
obj.fn1(); // Window
obj.fn2(); // {a: 1, fn1: ƒ, fn2: ƒ} ,这是 this 的隐式绑定

const f1 = obj.fn1;
const f2 = obj.fn2;
f1(); // Window
f2(); // Window ,隐式绑定取决于谁来调用,谁调用就指向谁

使用箭头函数之所以会指向 Window 是因为箭头函数等价于下面的代码:

var that = this; // 直接使用闭包缓存 this
let obj = {
a: 1,
fn1: function() {
console.log(that);
}
}

在对象方法(例如 Vue Options API)的异步回调中经常会遇到 this 丢失的情况,一般会使用闭包进行缓存:

// 使用 _this 变量进行缓存
const _this = this;
api.get("/api/xxx", function(res) {
_this.tableData = res;
})

// 除了使用闭包缓存 this ,还可以使用箭头函数
api.get("/api/xxx", (res) => {
this.tableData = res;
})

总结一下:箭头函数没有自己的 this ,没有 argument 对象,没有 prototype ,不能作为构造函数(用 new 调用会报错)。箭头函数会自动捕获上级词法作用域的 this ,并且箭头函数的 this 在声明的时候就已经确定了,不能通过 call 或者 apply 修改

- - + + \ No newline at end of file diff --git "a/2021/tags/\350\257\255\344\271\211\345\214\226\347\211\210\346\234\254/index.html" "b/2021/tags/\350\257\255\344\271\211\345\214\226\347\211\210\346\234\254/index.html" index aa68240f45..fda525ff0f 100644 --- "a/2021/tags/\350\257\255\344\271\211\345\214\226\347\211\210\346\234\254/index.html" +++ "b/2021/tags/\350\257\255\344\271\211\345\214\226\347\211\210\346\234\254/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -20,7 +20,7 @@ 对于 ^1.2.3 而言,它的版本号范围是 >=1.2.3 <2.0.0

当我们 npm i 时,默认的版本号是 ^,可最大限度地在向后兼容与新特性之间做取舍,但是有些库有可能不遵循该规则,我们在项目时应当使用 yarn.lock/package-lock.json 锁定版本号。

📒 Vue 3.2 响应式优化相关

Object.defineProperty 处理深度嵌套对象需要进行递归,而 Proxy 同样也只能监听当前层级的对象,如果深度嵌套也需要递归的,所以才有了 reactiveshallowReactive

之前看了黄轶老师写的 Vue3.2 响应式优化,Proxy 实际上比 Object.defineProperty 要慢,Vue 2.x 是直接在初始化阶段就进行深度递归,而 Vue3 的响应式优化就体现在只有访问对象属性的时候,再递归响应式,也就是延迟处理子对象,所以在初始化阶段性能较好。

📒 手把手实现一个 babel 插件

这篇做的 demo 是一个简单的 babel-plugin-import 深入Babel,这一篇就够了

这篇做的 demo 类似 Java 中的 lambok 保姆级教学!这次一定学会babel插件开发!

📒 从 16 个方向逐步搭建基于 vue3 的前端架构

📒 VuePress + Travis CI + Github Pages 全自动上线文档

- - + + \ No newline at end of file diff --git "a/2022/10\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/10\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d99f759937..44551a41b7 100644 --- "a/2022/10\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/10\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月16日内容汇总

· 3 min read
加菲猫

📒 开发小技巧总结

如何优雅删除数组中的元素:

const [imageList, setImageList] = useState([]);

const handleRemoveImage = (idx) => {
// 第一种:mutable 方式
// 由于 `splice` 方法直接修改原数组,所以数组指针实际上没有变化
// 当 setState 的时候,React 内部使用 `Object.is` 严格相等比较
// 由于指针没有改变,不会触发 React 调度更新
// 这里需要手动浅拷贝,创建一个新数组
imageList.splice(idx, 1);
setImageList([...imageList]);

// 第二种:immutable 方式
// 用 `filter` 返回一个新数组,简单直接
setImageList(l => l.filter((_, index) => index !== idx));
}

📒 如何优雅地编写一个高逼格的JS插件

📒 React 渲染的未来

📒 不破不立 —— 挥别 less-loader,Ant Design 5.0 Alpha 发布

📒 Vue3组件库打包指南,一次生成esm、esm-bundle、commonjs、umd四种格式

📒 Three.js 进阶之旅:模型光源结合生成明暗变化的创意页面-光与影之诗 💡

📒 Three.js 进阶之旅:基础入门(下)

📒 Three.js 进阶之旅:基础入门(上)

📒 使用 Vite 插件自动化实现骨架屏

📒 刚插上网线,电脑怎么知道自己的IP是什么

⭐️ Redis 实现分布式锁的 7 种方案

📒 Koa的洋葱中间件,Redux的中间件,Axios的拦截器让你迷惑吗?实现一个精简版的就彻底搞懂了

📒 学习 Babel 插件,把 Vue2 语法自动转成 Vue3!

📒 如何编写神奇的「插件机制」,优化基于 Antd Table 封装表格的混乱代码

📒 从龟速 11s 到闪电 1s,详解前端性能优化之首屏加载

📒 前端框架:性能与灵活性的取舍

⭐️ 【面试高频题】难度 1.5/5,多解法经典面试题

📒 React 中常见的 8 个错误,如何避免

⭐️ 在撸 Vue 的 ⌘+K 唤起菜单库时,我学到了很多

📒 Go 实战技巧:避免内存分配的小技巧

- - + + \ No newline at end of file diff --git "a/2022/10\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/10\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 18eb8ad64d..89d6710d38 100644 --- "a/2022/10\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/10\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月23日内容汇总

· 10 min read
加菲猫

📒 React 服务端渲染在跨端领域中的新视界

📒 学会这 20 个库,让你快速看懂 vue3 和 vite3 源码 🚀

📒 面试官:你会看 Vite 源码吗

📒 用 Go 程序打包和压缩文件,我们可以这么做

📒 Go语言中常见100问题-#17 Creating confusion with octal literals

📒 如何挑选最适合的 Node.js Docker 镜像

当你在编写 DockerFile 时会忽略 FROM node 的含义,作者分享了一些对于版本选择上的考虑。

https://snyk.io/blog/choosing-the-best-node-js-docker-image/

📒 Lerna Reborn:第六个版本更新了什么

使用 Nrwl 管理,面向 Lerna monorepo 的 JavaScript 构建系统并没有过时或弃用,它正在向前迈进一大步。v6 在默认情况下通过高效的任务调度和缓存、VS Code 扩展、Prettier 支持等获得了很大的速度。

https://blog.nrwl.io/lerna-reborn-whats-new-in-v6-10aec6e9091c?gi=ba929beec06d

📒 Node v18.11.0 发布

Node 的最新版本虽然并没有更新很多功能,但却实验性的支持了 --watch 功能。当导入的文件发生变化时,会自动重新启动运行中的进程(这个功能让人想起了 nodemon) – 这个功能最近被 详细讨论过

https://nodejs.org/en/blog/release/v18.11.0/

📒 【综合笔试题】难度 4.5/5,扫描线的特殊运用(详尽答疑)

📒 复活了! Lerna V6 带来了哪些新东西

⭐️ 【第2757期】软件架构的23个基本原则

⭐️ 【第2677期】如何在React中应用SOLID原则

📒 前端架构带你 封装axios,一次封装终身受益「美团后端连连点赞」

📒 如何编写 CommonJS 模块,以便它们的导出可以从 ES 模块实现按照名称导入

如果你曾经在使用 CommonJS 和 ES 模块之间纠结过,那么这篇文章或许值得一读。Axel 博士在这里解决了一个关键的交叉兼容性问题。

https://2ality.com/2022/10/commonjs-named-exports.html

📒 njt:快速导航至 npm 包资源

如果你想要快速访问 npm 包的首页、仓库、issues,甚至包成本估算,那么 njt 将会是一个不错的选择。njt 提供了一个快速跳转到与 npm 包相关的各种资源目的地的方法。你可以在终端中安装并使用,也可以通过 LaunchX 扩展程序 将 njt 添加至 VS Code 的命令面板然后使用,或者在 Google 与 Firefox 浏览器进行配置然后搜索,亦或 直接在网页上使用它。如果你对此有兴趣,可以来看看 GitHub 仓库。

https://www.npmjs.com/package/njt

📒 换一种方式对工程中的Api进行封装吧(fashion-axios)

📒 Element Plus 组件库相关技术揭秘:3.ESLint 核心原理剖析

📒 Element Plus 组件库相关技术揭秘:2. 组件库工程化实战之 Monorepo 架构搭建

📒 开源推荐

lazygit

git 命令的 terminal UI 工具,基于 Go 实现。

https://github.com/jesseduffield/lazygit

knip

又一个废代码检测工具,支持检测未使用的文件、依赖和 exports。

$ knip --reporter codeowners
--- UNUSED FILES (2)
@org/team src/chat/helpers.ts
@org/owner src/components/SideBar.tsx
--- UNUSED DEPENDENCIES (1)
@org/admin moment
--- UNLISTED DEPENDENCIES (1)
@org/owner src/components/Registration.tsx react
--- UNUSED EXPORTS (4)
@org/team src/common/src/string/index.ts: lowercaseFirstLetter
@org/owner src/components/Registration.tsx: RegistrationBox
@org/owner src/css.ts: clamp
@org/owner src/services/authentication.ts: restoreSession, PREFIX
--- UNUSED TYPES (3)
@org/owner src/components/Registration/registrationMachine.ts: RegistrationServices, RegistrationAction
@org/owner src/components/Registration.tsx: ComponentProps
@org/owner src/types/Product.ts: ProductDetail
--- DUPLICATE EXPORTS (2)
@org/owner src/components/Registration.tsx: Registration, default
@org/owner src/components/Products.tsx: ProductsList, default

https://github.com/webpro/knip

📒 手写 React 渲染器

由于有 react-reconciler,让自定义 React 渲染器变地相当简单。

import ReactReconciler from "react-reconciler";

const reconciler = ReactReconciler({
// ... configuration options ...
// 启用突变模式
// Reconciler 有两种不同的渲染模式,1)突变模式,2)持久模式
supportsMutation: true,

createInstance(type, props) {
const element = document.createElement(type);
Object.keys(props).forEach((prop) => {
// Filter out non-HTML attributes like:
if (!["children", "onClick", "key"].includes(prop)) {
// Appends each html attribute to the element
element[prop] = props[prop];
}
});
// return the HTML element
return element;
},
createTextInstance: (text) => {
return document.createTextNode(text);
},
getRootHostContext: () => null,
getChildHostContext: () => null,
shouldSetTextContent: () => null,
prepareForCommit: () => null,
clearContainer: () => null,
resetAfterCommit: () => null,
appendInitialChild: () => null,
appendChildToContainer: () => null,
finalizeInitialChildren: () => null,
removeChildFromContainer: () => null,
});

const render = (element, container) => {
const root = reconciler.createContainer(container, false, false);
reconciler.updateContainer(element, root, null, null);
};

export { render };

然后就可以拿这个 render 方法进行渲染了。

render(<App />, document.getElementById('root'))

https://www.markcodes.dev/posts/build-react-custom-renderer-part-1

📒 最快前端模板

Jest 作者梳理了他认为最快的 2022 最快前端工具集以及与之配套的 github 仓库模板,结论是 Vite + tailwind + pnpm + eslint & prettier + TypeScript + React。我觉得这里的快有两个含义,1)速度快,2)用于快速启动项目的最小模板。

  • Vite 无需多说
  • Tailwind 也无需多说,但如果你有自己的 Design System,作者推荐用 emotion
  • pnpm 除了快,对 monorepo 的支持也很好
  • ESLint & prettier 有一些注意点,1)要分开用,别在 eslint 规则里加 prettier 规则,会慢,2)prettier 和 eslint 都有 --cache 参数,要开启,3)推荐用 @trivago/prettier-plugin-sort-imports 和 prettier-plugin-tailwindcss 对 import 和 tailwindcss 类进行排序,4)期待 rome 的 formatter 和 lint
  • npm-run-all 用于并行执行多个命令
  • NodeJS 脚本编写,基于 native esm,使用 ts-node + @swc/core + nodemon 的依赖组合实现,没有用基于 esbuild 方案比如 tsx,因为测下来在一些场景会莫名其妙地慢
  • TypeScript 无需多说
  • VSCode,作者推荐了 4 个插件

大家可能会好奇,作为 Jest 作者,测试工具他选的啥?虽然文章里没提,但从代码里可以看到,用的是 Vitest,哈哈。

https://cpojer.net/posts/fastest-frontend-tooling-in-2022

📒 MDH 前端周刊第 73 期:TypeScript 10 年、最快前端模板、whyframe、template 元素

📒 文章推荐

📒 Storybook 7.0 中 Vite 成为内置选项

https://storybook.js.org/blog/first-class-vite-support-in-storybook/

📒 用 Sandpack 打造世界级 Playground

CodeSandbox 开源了 Sandpack,本文教你使用 Sandpack 打造出一个功能齐全的 Playground。

https://www.joshwcomeau.com/react/next-level-playground/

📒 Resumable vs. Hydration

本文介绍了 Qwik 框架可恢复性的实现原理以及与常规补水相比具有的优势。

https://qwik.builder.io/docs/concepts/resumable/

📒 TypeScript 十年,不忘初心

📒 Rollup v3.0.0

Rollup 发布 v3.0.0,带来了大量更新。其中 Breaking Change 包括最低支持 Node 14.18.0、浏览器构建拆成单独的包 @rollup/browse、Node 构建使用 node: 前缀导入内置模块、移除一些以前被废弃的功能,使用时提示警告等。还有包括 Options 配置、插件 API、以及一系列的新特性。

Rollup 3.0 意味着 Vite 即将发布大版本

https://github.com/rollup/rollup/releases/tag/v3.0.0

📒 前端食堂技术周刊第 55 期:Rollup v3.0.0、Volar 1.0 Nika、TypeScript 十年

📒 如何使用 React、SSR 和 Tailwind CSS 构建 SVG 折线图

关于如何在基于 Next.js 或 Gatsby 的服务器端渲染 React 应用程序中创建你自己的基于 SVG 的折线图的教程。

https://thenewstack.io/how-to-build-svg-line-charts-with-react-ssr-and-tailwind-css/

📒 React 渲染的未来

首先回顾当前的渲染模式 (CSR/SSR)然后转向一些新的渲染模式,例如流式 SSR 和服务器组件。这也是在 React Bangalore 的 最近访谈 中的话题。

https://prateeksurana.me/blog/future-of-rendering-in-react/

📒 React Table:一个 “几乎无头” 的表格组件

https://react-table-library.com/

📒 Islands 架构原理和实践

📒 你不需要Next.js(和SSR)

📒 【面试高频题】难度 1.5/5,常规滑动窗口运用题

⭐️ 精读《Headless 组件用法与原理》

📒 学习了!GoMap 会内存泄露

📒 如何让 Go 反射变快

⭐️ Go Gin框架请求自动验证和数据绑定,看完这篇就会用了

📒 一文搞懂Go内联优化

⭐️ Go常见错误集锦之函数式选项模式

📒 Go语言爱好者周刊:第 163 期 —— 错误处理新提案

- - + + \ No newline at end of file diff --git "a/2022/10\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/10\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 4e8519c55b..dab52a9dcf 100644 --- "a/2022/10\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/10\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月2日内容汇总

· 7 min read
加菲猫

📒 你写 Go 代码写注释吗?谈谈 Go 代码注释问题

📒 程序员新人频繁使用count(*),被组长批评后怒怼:性能并不拉垮!

📒 【第2745期】React 可组合 API 的设计原则

📒 推荐12个值得学习的TypeScript宝库!

📒 【第2744期】更好的 React SSR

📒 Java19 正式 GA!虚拟线程性能炸裂!!

📒 [翻译]Go 运行时的未来 Go Runtime: 4 years later

📒 我认为 Go 的成功归功于这 5 个方面

⭐️ 给想转Go或者Go进阶同学的一些建议

📒 【第2742期】Remesh 介绍:用以开发大型复杂 Web App 的 DDD 框架

📒 Monorepo Handbook 新鲜出炉

TurboRepo 团队近日发布了 Monorepo 手册,包含关于 Monorepo 你需要知道的一切,并提供了详尽的配置示例,内容如下:

  • 什么是 Monorepo?
  • 安装包 (npm、pnpm、Yarn 1、Yarn >=2)
  • Workspaces 工作区
  • 迁移到 Monorepo
  • 任务编排
  • 构建
  • Docker 部署
  • 共享代码
  • Lint
  • 测试
  • 发布 (Changesets)
  • @manypkg/cli 处理包版本依赖

https://turborepo.org/docs/handbook/what-is-a-monorepo

📒 前端食堂技术周刊第 54 期:TS 4.9 Beta、Monorepo Handbook、第 92 次 TC39 会议、将 StoryBook Stories

📒 HTTPS 就一定安全?我不信

从客户端的角度看,其实并不知道网络中存在中间人服务器这个角色。

那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于,中间人能够 “偷看” 浏览器与服务端之间的 HTTPS 请求和响应的数据。

但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书

中间人服务器与客户端在 TLS 握手过程中,实际上发送了自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器(客户端)识别出是非法的,于是就会提醒用户该证书存在问题。

抓包工具 之所以可以明文看到 HTTPS 数据,工作原理与中间人一致的。

对于 HTTPS 连接来说,中间人要满足以下两点,才能实现真正的明文代理:

  • 中间人,作为客户端与真实服务端建立连接这一步不会有问题,因为服务端不会校验客户端的身份;
  • 中间人,作为服务端与真实客户端建立连接,这里会有客户端信任服务端的问题,也就是服务端必须有对应域名的私钥;

中间人要拿到私钥只能通过如下方式:

  • 去网站服务端拿到私钥;
  • 去CA处拿域名签发私钥;
  • 自己签发证书,且被浏览器信任;

不用解释,抓包工具只能使用第三种方式取得中间人的身份。

使用抓包工具进行 HTTPS 抓包的时候,需要在客户端安装根证书,这里实际上起认证中心(CA)的作用。

我们要保证自己电脑的安全,不要被病毒乘虚而入,而且也不要点击任何证书非法的网站,这样 HTTPS 数据就不会被中间人截取到了。

当然,我们还可以通过 HTTPS 双向认证来避免这种问题。

一般我们的 HTTPS 是单向认证,客户端只会验证了服务端的身份,但是服务端并不会验证客户端的身份。

如果用了双向认证方式,不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。

HTTPS 就一定安全?我不信

📒 tauri 快速上手

快速上手 3 命令。

$ npm create tauri-app
$ npm run tauri dev
$ npm run tauri build

https://blog.logrocket.com/tauri-electron-comparison-migration-guide/

📒 新一波 JavaScript 框架

作者从 Web 之初、CGI、PHP 开始讲起,讲 JavaScript 历史画卷一幅幅展开,既有 Ajax、jQuery、Backbone、YUI 等一代代的 JavaScript 库前辈,又有 Astro、Fresh、Remix 等新一波的 JavaScript 框架。推荐阅读,从中可以了解为什么会有这些库和框架,以及他们都是为了解什么而生的?

所以,既然每个框架都会被历史所代替,前端开发者应该如何保持竞争力?

https://frontendmastery.com/posts/the-new-wave-of-javascript-web-frameworks/

📒 TypeScript 4.9 satisfies

satisfies 是 TypeScript 4.9 新引入的操作符,用于只做校验但不改变表达式的类型结果。通常用于 Object 声明,因为既需要保留每个属性的类型,又需要做 key 值校验。

比如,

type Colors = 'red' | 'green' | 'blue';
const foo = {
red: [1],
green: true,
blue: 'ok',
black: {},
//~~~~~~~~~~ 既校验了 key,要求满足 Colors,这里的 black 会抛错
} satisfies Record<Colors, unknown>;

// 又让每个属性拥有完整类型
foo.red.at(0);
foo.blue.startsWith('o');

https://devblogs.microsoft.com/typescript/announcing-typescript-4-9-beta/#the-satisfies-operator

📒 Go语言中常见100问题-#11 Not using the functional options pattern

📒 Go语言爱好者周刊:第 161 期

- - + + \ No newline at end of file diff --git "a/2022/10\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/10\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 9c6ec9336d..83fecbeec8 100644 --- "a/2022/10\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/10\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月30日内容汇总

· 3 min read
加菲猫

📒 Next.js 13 相关文章

你好,Next.js 13

https://nextjs.org/blog/next-13

https://beta.nextjs.org/docs/data-fetching/fundamentals#

📒 Monorepo,大型前端项目管理模式实践

📒 React Hooks不优雅

📒 运用「博弈论」分析「先手必胜态」序列具有何种性质,以及如何思考「博弈论」问题

📒 Go 大佬良心发现,愿意给 map 加清除了

📒 Turbopack 很火? 那么就从前端角度看 Rust

📒 Docker夺命连环15问,你能坚持第几问

📒 当函数设计遇到切片

📒 使用Go语言批量同步微信读书笔记到Flomo

⭐️ 一文了解 NextJS 并对性能优化做出最佳实践

📒 比Webpack快700倍的Turbopack,到底快在哪

⭐️ 课代表:Turborepo 笔记

📒 Go标准库依赖的那些modules

📒 使用 Vitest 和 React Testing Library 给 Next.js 应用单元测试

📒 前端初学 ECS 架构,实现超炫的粒子碰撞动画

📒 Go HTTP服务用了优雅关闭,为什么还是报错

⭐️ 【羊了个羊】之我用vue3+ts+vite3从0到1开发了个【兔了个兔】

📒 【第2763期】接入成本最低微前端框架:京东零售micro-app

📒 聊一聊关于微前端架构的几种技术选型

📒 前端食堂技术周刊第 56 期:Solid v1.6.0、State of GraphQL、ViteConf回放、Lerna v6

📒 MDH 前端周刊第 74 期:use、htmx、Stately Studio、TypeRunner、画中画

📒 一文教你搞定所有前端鉴权与后端鉴权方案,让你不再迷惘

📒 1024,我们的节日,Gopher 该干点啥

📒 Go try 新提案靠谱吗?想简化错误处理了

📒 Go语言中常见100问题-#18 Neglecting integer overflows

📒 Go语言爱好者周刊:第 164 期

- - + + \ No newline at end of file diff --git "a/2022/10\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/10\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d312dd724d..fac67ed2de 100644 --- "a/2022/10\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/10\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,15 +11,15 @@ - - + +
Skip to main content

10月9日内容汇总

· 9 min read
加菲猫

📒 看了 web.dev 的 631 篇博客,我总结了这些内容

📒 Go开源库、大项目的公共包,是这么用建造者模式的

📒 【第2747期】Islands Architecture(上)

📒 Go语言中常见100问题-#13 Creating utility packages

📒 快速在你的vue/react应用中实现ssr(服务端渲染)

📒 探究 Go 源码中 panic & recover 有哪些坑

📒 抖音二面:为什么模块循环依赖不会死循环?CommonJS和ES Module的处理不同

📒 Go语言中常见100问题-#12 Project misorganization

📒 Go 的 IO 流怎么并发?小技巧分享

📒 构建 webpack5 知识体系【近万字总结】

📒 如何实现卡片滚动效果

实现一个横向卡片滚动的效果,有两个需求:

  • 需要有滚动条,这样可以支持有触摸板的设备(即不能通过 overflow: hidden; 加上 transform: translateX(); 或者相对定位偏移实现)
  • 还要提供左右切换的按钮,这样便于鼠标操作,同时点击需要过渡动画

根据第一点就可以确定,滚动的实现是父容器设置 overflow-x: auto; 实现的。那怎么实现第二个需求呢?

观察一下 ahooks 的 useInfiniteScroll 源码,控制滚动的核心就是 scrollTopscrollHeightclientHeight 这几个参数:

packages/hooks/src/useInfiniteScroll/index.tsx:81
// 滚动触发的回调函数
const scrollMethod = () => {
const el = getTargetElement(target);
if (!el) {
return;
}

const scrollTop = getScrollTop(el); // 滚动的距离,该参数值可以动态修改
const scrollHeight = getScrollHeight(el); // 滚动内容实际的高度,该参数值只读
const clientHeight = getClientHeight(el); // 外部滚动容器的高度,该参数值只读

if (scrollHeight - scrollTop <= clientHeight + threshold) {
loadMore();
}
};

// 绑定滚动事件监听器
useEventListener(
'scroll',
() => {
if (loading || loadingMore) {
return;
}
scrollMethod();
},
{ target },
);

https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useInfiniteScroll/index.tsx

那么在卡片滚动的需求中,对应的参数值为 scrollLeftscrollWidthclientWidth。只要 scrollLeft + clientWidth < scrollWidth,就可以继续向右滚动:

import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useMemorizedFn } from "ahooks";

export const useCarouselScroll = <T extends HTMLElement>({
target,
customWidth,
}: {
target: React.MutableRefObject<T>;
customWidth?: number;
}) => {
const [enablePrev, setEnablePrev] = useState(false);
const [enableNext, setEnableNext] = useState(false);

const { scrollLeft, clientWidth, scrollWidth } = target.current;
const threshold = customWidth || clientWidth; // 一次滚动的距离

useEffect(() => {
setEnablePrev(scrollLeft > 0);
setEnableNext(scrollLeft + clientWidth < scrollWidth);
}, []);

const prev = () => {
if (enablePrev) {
if (threshold < scrollLeft) {
// 可以滚动一屏的距离
target.current.scrollLeft -= threshold;
} else {
// 滚动不足一屏距离
target.current.scrollLeft -= scrollLeft;
setEnablePrev(false);
}

setEnableNext(true);
}
};

const next = () => {
if (enableNext) {
if (scrollLeft + clientWidth + threshold < scrollWidth) {
// 可以滚动一屏的距离
target.current.scrollLeft += threshold;
} else {
// 滚动不足一屏距离
target.current.scrollLeft += (scrollWidth - scrollLeft - clientWidth);
setEnableNext(false);
}

setEnablePrev(true);
}
};

return {
enablePrev,
enableNext,
prev: useMemorizedFn(prev),
next: useMemorizedFn(next),
};
};

过渡动画的实现就很简单了,一行 CSS 代码搞定:

scroll-behavior: smooth;

📒 Next.js prefetch 策略

很多全栈框架,例如 Next.js 都会做 prefetch 预加载 chunk。Next.js 提供了一个 <Link /> 组件,可以实现 client-side route transitions,同时这个 <Link /> 还具有 prefetch 功能:

Any <Link /> that is in the viewport (initially or through scroll) will be preloaded. Prefetch can be disabled by passing prefetch={false}. When prefetch is set to false, prefetching will still occur on hover. Pages using Static Generation will preload JSON files with the data for faster page transitions. Prefetching is only enabled in production.

参考一下 <Link /> 源码实现:

https://github.com/vercel/next.js/blob/canary/packages/next/client/link.tsx#L205

📒 【一库】yalc: 可能是最好的前端link调试方案(已经非常谦虚了)

📒 使用antv/G2生态半年有感

📒 Go:符号表是什么?如何使用?

📒 Dracula UI

刚开源,特点如下。

1、为黑暗模式而建。大多数模板都是使用浅色的,后来才改成深色的。深色主题不应该是一个事后的想法,它们应该是一个首要任务。

2、设计师友好。通过使用一个高度可配置的设计系统,加快原型设计阶段。通过利用精心制作的Figma文件,轻松进行合作。

3、友好的开发者体验。不用担心类名,只需使用 Visual Studio 的代码片段。你可以利用自动完成的优势,也可以从你的代码编辑器中直接访问整个文档。

https://ui.draculatheme.com/

📒 React 18 快在哪

主要是 3 点。

1、由于 React 18 有 Automatic Batching,多个 setState 只会触发一次渲染,而在 18 之前,setState 几次就会渲染几次 2、React 18 引入了新的服务器渲染架构,会带来显著的性能提升,请检查你的框架是否支持 3、React 18 引入了用于把状态更新标记为可终端的 startTransition,虽然不能让页面变快,但如果用户在可中断的状态更新中点击,会让你的应用更具有响应性

https://www.reddit.com/r/reactjs/comments/xmr9tg/comment/ippsuin/

📒 再见 useEvent

useEvent 原计划解两个问题,1)渲染优化,2)useEffect 重新触发问题。但是发现没办法一下子做两件事。于是 useEvent RFC 废弃,这两个问题会拆开了来解。渲染优化问题倾向用 React Forgot 解,useEffect 重新触发问题会通过另一个专门解此问题的 RFC 来解,命名上应该不再会用 useEvent。

https://github.com/reactjs/rfcs/pull/220#issuecomment-1259938816

📒 Umi x Valtio

Umi 在 4.0.23 中加入了 Valtio 插件。这是在大量调研之后,基于中台项目的场景做的决定,使用 Valtio 作为下一代的数据流。

为啥是 valtio?

valtio 的特点是外部多 Store + 基于 Proxy。1)个人用不惯 jotai 和 recoil 这种 react 内部原子化的数据流方案,感觉和被 redux 培养起来的心智模型有冲突,所以会更倾向于外部 Store 一些,2)由于场景是中后台,对于兼容性的容忍度比较高,比如不用兼容 IE11,所以完全可以用基于 Proxy 的数据流方案,这类数据流方案在更新数据和读取数据时都更简单。

为啥不是 zustand?

1、zustand 和 valtio 是同一个作者写的,功能覆盖上其实比较类似,最大的区别是 valtio 基于 proxy 而 zustand 不是。个人有几个方面的考虑,1)更新数据,2)读取数据,3)类型提示。

2、更新数据的方式更符合人性,比如可以直接 state.todos['321'].completed = true,而不用 setState(todos => ({ …todos, 321: { …todos['321'], completed: true } }))。当然,这一点非 proxy 方案可基于 immer 实现和 proxy 方案类似的操作。

3、读取数据默认高性能,无需 selector。非 proxy 方案比如 react-redux 和 zustand 为了性能优化,避免不必要的 re-render,通常会通过 selector 选择 store 的一部分,这会带来不必要的心智负担。基于 Proxy 的方案是响应式的,无需 selector,默认高性能。

4、类型提示的差异主要在扩展上。valtio 用的是组合式,zustand 用的是 middleware。没具体试过 zustand 的 middleware,但个人理解,理论上 middleware 的类型提示没有 valtio 友好。比如 valtio 的 proxyWithHistory 会把数据结构改成 { value, history, redo, undo, … } 这种,在类型提示上可以完美衔接。

https://umijs.org/docs/max/valtio

- - + + \ No newline at end of file diff --git "a/2022/11\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/11\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 14a61910c0..31dda75902 100644 --- "a/2022/11\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/11\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月13日内容汇总

· 5 min read
加菲猫

📒 相关文章推荐

基于 Amplify Studio 使用少量代码实现 Figma-to-React 组件

https://aws.amazon.com/blogs/mobile/new-build-responsive-figma-to-react-components-with-almost-no-code/

JavaScript 中的 “realm” 是什么

https://weizman.github.io/page-what-is-a-realm-in-js/

2022 年如何构建,测试并发布一个 TypeScript 编写的 npm 包

https://www.strictmode.io/articles/build-test-and-publish-npm-package-2022

'Next.js 打包出的产物会感谢你' — 如果你的 Next.js 应用打包出的产物比预期的更加大一些,前端工程师 Renato 的打包优化建议会使你受益。

https://renatopozzi.me/articles/your-nextjs-bundle-will-thank-you

基于 Storybook test runner 实践代码测试的覆盖率

https://storybook.js.org/blog/code-coverage-with-the-storybook-test-runner/

教你打包并发布一个 Vue.js 3.0 插件的 npm 包 — 使用 Vite 打包构建出产物,使用 vue-tsc 生成类型带来更好的开发体验。

https://vueschool.io/articles/vuejs-tutorials/how-to-package-and-distribute-a-vue-js-3-plugin-on-npm/

📒 Element Plus 组件库相关技术揭秘:6. CSS 架构模式之 BEM 在组件库中的实践

📒 【第2780期】如何用油猴提升前端开发效率

🌛 从零实现一个迷你 Webpack

📒 【第2779期】离开后端说前端加密都是空谈

📒 前缀树在前端路由系统中的应用

📒 选择 Go 还是 Rust?CloudWeGo-Volo 基于 Rust 语言的探索实践

📒 还在服务器上捞日志?快搭建一个ELK日志系统吧,真心强大!

📒 开启 GODEBUG 更直观地理解 Go 程序的调度过程

📒 Go语言中常见100问题-#20 Not understanding slice length and capacity

⭐️ Go 13 周年啦!

⭐️ 基于 MF 的组件化共享工作流

📒 快收藏!超强图解Docker常见命令与实战!

📒 Chrome DevTools中的这些骚操作,你都知道吗

📒 【第2777期】React最新提出了一个名为use的Hook

📒 20个常见的前端算法题,你全都会吗

📒 阿里面试官:如何给所有的async函数添加try/catch

📒 「历时8个月」10万字前端知识体系总结(工程化篇)🔥

📒 React 进阶实践指南 - 渲染控制

https://juejin.cn/book/6945998773818490884/section/6958058637042384900

📒 如何用 TypeScript 声明 React HOC

https://react-typescript-cheatsheet.netlify.app/docs/hoc/full_example

https://medium.com/@jrwebdev/react-higher-order-component-patterns-in-typescript-42278f7590fb

📒 云谦:前端框架的趋势与实践(文字稿)

📒 这30 个优秀的 Go 编码习惯,你都在用吗

⭐️ 一文搞懂Go标准库context包

📒 记一次使用time.Duration类型踩过的坑

📒 golang中time包使用教程之基础使用篇

⭐️ 字节开源WEB框架Hertz太香啦!

📒 面试必问之 JS 事件循环(Event Loop),看这一篇足够

📒 信仰崩了?Preact 开始采用 Vue3 的响应式设计

📒 【常见题型总结】序列 DP 模板题(总结「线性 DP」和「序列 DP」本质区别)

📒 点击页面元素跳转IDE对应代码,试试这几个工具!

📒 Go 十年了,终于想起要统一 log 库了!

📒 前端食堂技术周刊第 58 期:TypeScript 4.9 RC、10 月登陆浏览器的新功能、Turbopack 真的比 Vite 快 10 倍吗

📒 由 transform 被占用引发的思考🤔

📒 TypeScript 4.9 发布!重点新特性解读 ~

📒 聊一聊常见的浏览器数据存储方案

⭐️ MDH 前端周刊第 75 期:CSS-in-JS、Node 18、完美提交、ChiselStrike、Ultra

📒 Happens before 原则在 Go 内存模型中的应用举例

📒 这些最常用的 Go CLI 命令,新手 Gopher 应该掌握

📒 「每周译Go」如何在 Go 中编写包

- - + + \ No newline at end of file diff --git "a/2022/11\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/11\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 9fe0f293f4..013810290d 100644 --- "a/2022/11\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/11\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月20日内容汇总

· 7 min read
加菲猫

📒 相关文章推荐

一个 Next.js 13 的演示教程,里面讲了一个 use 导致的无限循环 bug

https://www.youtube.com/watch?v=zwQs4wXr9Bg

如何用 JavaScript 来对 2800 万数据进行去重? — 这是 Stack Overflow 上一个很有趣的问题

https://stackoverflow.com/questions/74329830/deduping-28-million-strings-using-javascript

Sourcegraph 公司讲述了为什么他们选择从 Monaco 编辑器切换到 CodeMirror

https://about.sourcegraph.com/blog/migrating-monaco-codemirror

新的 JavaScript 时间 API 提案 --- Temporal(已进入 stage 3)

https://vladmihet.hashnode.dev/temporal-api-javascript-dates-but-better

Rome v10:由 Rust 驱动的 JS Linting 与格式化工具 — 由 Babel 的作者 创建的项目自然会引起大家的兴趣

https://rome.tools/blog/2022/11/08/rome-10/

Node 安全版本:v19.0.1、v18.12.1、v16.18.1 和 v14.21.1

https://nodejs.org/en/blog/vulnerability/november-2022-security-releases/

Hapi v21:简单、安全的 Node 应用程序框架 - 专注于现代化和全面 Node v18(和 ESM)支持。值得注意的是 Hapi 不光没有外部依赖,还提供了很多开箱即用的功能

https://github.com/hapijs/hapi

在多个云提供商上部署一个简单的 Node 应用程序

https://medium.com/eleven-sh/deploying-a-simple-node-js-app-with-https-on-cloud-providers-in-2022-heroku-render-fly-io-aws-9358294803c5

将 TypeScript 与 Node.js 结合使用

https://www.robinwieruch.de/typescript-node/

用 Wails 和 React 在 Go 中构建一个桌面应用程序 — Wails 于 Go(lang) 就像 Electron 于 Node 一样,你可以前端用 JavaScript,后端用 GO 在 Mac、Linux 和 Windows 上开发桌面应用程序

https://react.statuscode.com/link/131395/web

CRACO v7.0:覆盖 Create React App 配置 — 如果你仍然喜欢 Create React App,而不是如 Next.js 之类的更大的 React 应用构建方式,CRACO 让你继续使用 CRA,但增加了一个可理解的配置层

https://github.com/dilanx/craco

📒 当谈论协程时,我们在谈论什么

⭐️ 看一遍就理解:IO模型详解

⭐️ 🎉 dumi 2,它来了它来了它来了

⭐️ 面试必备:零拷贝详解

📒 2022年我的面试万字总结(代码篇)

📒 【第2785期】雪球跨端架构建设之跨端容器篇

⭐️ Go 1.20新特性前瞻

⭐️ 实战总结!18种接口优化方案的总结

📒 深入理解 Golang map 设计理念与实现原理

📒 为什么我抓不到baidu的数据包

📒 React这25个精选库,将助你工作更上一层楼

📒 React 中的重新渲染

📒 【常见题型总结】二分以及为何能二分(二段性的拓展)

📒 保姆级教程!2 万字 + 30 张图搞懂 MySQL 是怎么加行级锁的

📒 我修复了一个 Vite Bug,让我的项目首屏性能提高了 25%

📒 Nuxt.js 3.0 正式发布!

📒 【第2784期】从cdnjs 的漏洞来看前端的供应链攻击与防御

📒 Go1.20 中两个关于 Time 的更新,终于不用背 2006-01-02 15:04:05 了!

📒 JavaScript错误处理完整指南

⭐️ 使用反射操作channel

⭐️ 成为 Go 高手的 8 个 GitHub 开源项目

🌛 使用useReducer + useContext 代替 react-redux

📒 前端食堂技术周刊第 59 期:GitHub Universe 2022、Rome v10、Parcel v2.8.0、可扩展的 CSS 演变

⭐️ 万字图文讲透数据库缓存一致性问题

📒 【面试高频题】难度 2/5,经典区间 DP 模板题(详解如何思考区间 DP 问题)

📒 打脸了兄弟们,Go1.20 arena 来了!

📒 【第2782期】得物API一站式协作平台探索与落地

📒 如何在测试中发现goroutine泄漏

⭐️ 忘了又看,看了又忘?保姆级教学,一口气教你玩转 3 种高频设计模式!

📒 【中级/高级前端】为什么我建议你一定要读一读 Tapable 源码

📒 MDH 前端周刊第 76 期:可扩展的 CSS、TanStack Router、Solid Start Beta、Rome 10

React Router 6 提供了 deferred API,让我们可以区分页面的关键数据和可选数据。可选数据不应该影响页面渲染,比如博客文章的评论、购物车中的推荐产品、最近的搜索等。用法如下。同时可选数据加载报错不会让整体路由渲染报错。

const critical1Promise = fetch('/xxx').then(res => res.json);
const critical2Promise = fetch('/xxx').then(res => res.json);
const lazy1Promise = fetch('/xxx').then(res => res.json);
const lazy2Promise = fetch('/xxx').then(res => res.json);
export const loader = async () => {
return defer({
critical1: await critical1Promise,
critical2: await critical2Promise,
lazy1: lazy1Promise,
lazy2: lazy2Promise,
});
}

这和在组件里用 useEffect 有啥区别?useEffect 的方式,不能做到所有请求并行发起,相比之下会慢一些。「The earlier you initiate a fetch, the better, because the sooner it starts, the sooner it can finish.」

https://dev.to/infoxicator/react-router-6-deferred-fetch-4k68

MDH 前端周刊第 76 期:可扩展的 CSS、TanStack Router、Solid Start Beta、Rome 10

📒 Node.js 安全最佳实践

📒 2种方式!带你快速实现前端截图

⭐️ Go学设计模式-程序流程要动态切换?用这个模式写更丝滑

📒 2022 年 JavaScript 从 ES6 到 ES12 新特性汇总

📒 【第2781期】React 渲染的未来

📒 Go语言爱好者周刊:第 167 期 —— 结构化日志期待下

- - + + \ No newline at end of file diff --git "a/2022/11\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/11\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 10ac5f94a6..be5cc972a3 100644 --- "a/2022/11\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/11\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,15 +11,15 @@ - - + +
Skip to main content

11月27日内容汇总

· 7 min read
加菲猫

📒 相关文章推荐

重构 React 代码:减少 43% 代码并且数据结构更加清晰

https://profy.dev/article/react-junior-code-review-and-refactoring-1

使用 TypeScript 编写 React 组件

https://www.robinwieruch.de/typescript-react-component/

What and Why:Next.js 13 中的 React Server Components

https://thetombomb.com/posts/react-server-components-nextjs

Twix: 使用 Tailwind CSS 实现 React 组件样式

https://github.com/Idered/twix

Deno v1.28 发布:现在有 130 万个新模块。Deno 现在正式支持以“稳定”的方式使用 npm 模块,并且不需要涉及 node_modulespackage.jsonnpm install 这些出现在 Node 中的内容

https://deno.com/blog/v1.28

https://www.youtube.com/watch?v=X2qxpDriWjY

Wireit:升级 npm 脚本,使它们更智能、更高效

https://github.com/google/wireit

使用 WebAssembly 增强 Node.js

https://www.youtube.com/watch?v=bYCrCKNJBW8

函数式编程到底有什么优点 — 本篇文章是由即将出版的 《Skeptic’s Guide to Functional Programming with JavaScript》的作者 James 以一种更容易理解的方式书写的函数式编程思想的文章,相信你读完本篇文章会大有收获

https://jrsinclair.com/articles/2022/whats-so-great-about-functional-programming-anyway/

用 Storyboook 和 Nightwatch 实践组件驱动开发

https://pineview.io/supercharge-your-storybook-with-nightwatch-testing/

tslog v4.0:支持 JS、TS 的日志输出库— 功能丰富,类型齐全,可以通过本机 V8 进行堆栈跟踪 API、显示代码框架等。现在支持 Node 和浏览器

https://tslog.js.org/

📒 开源低代码表单方案 Formily 的核心设计思路

📒 微前端场景下的代码共享

📒 相关文章推荐

How to Create and Publish a React Component Library

How to Build a Rust CLI Tool to Generate Typescript Types from Rust

Build Micro frontends in NextJS and ReactJS with Webpack 5 Module Federation

Building React App with Module Federation and NextJS/React

📒 Next.js 相关内容

使用 Next.js 搭建 Monorepo 组件库文档

理解 Next.js 中的 CSR、SSR、SSG、ISR 以及 Streaming

Next.js 13 新增特性:

  • 启用实验性 app 目录实现约定式路由,路由每个片段必须要有一个目录承载,内部包含一个 page.tsx 作为主页面,还可以包含 layout.tsx 作为该路由的公共导航,切换路由时,不会刷新

  • app 目录下的组件默认启用 Server Component(当然也可用于 SSG 渲染),与传统的 SSR 不同,优点是拥有 流式 HTML 和选择性注水

  • React Suspense API 解锁了 React 18 中的两个主要 SSR 功能:

    • 在服务器上流式传输 HTML 要实现这个功能,需要从原来的方法切换 renderToString 切换到新 renderToPipeableStream 方法
    • 客户端的选择性注水作用 使用 hydrateRoot 代替 createRoot 方法
  • 区分服务端组件和客户端组件

    • Next.js 12 在 useEffectonChange 等回调函数可以在客户端执行(一般针对浏览器和 Node API 判断)
    • 在 Next13 中 , 在 app 目录下由于启用了 Server Component,无法使用 client-only 特性(例如 useStateuseEffect createContext),因此判断环境非常重要。如要使用 useState 等状态管理的 hook,那么该组件只在客户端执行,需要在首行加入 'use client' 指令
  • 数据请求。Next.js 13 的 app 目录不再需要 getStaticPropsgetServerSideProps,而是默认启用了 Static Rendering(相当于 SSG),如果需要切换渲染模式,只需要修改 fetch 的缓存策略:

    fetch('https://...'); // 默认 'force-cache',相当于 `getStaticProps`

    fetch('https://...', { next: { revalidate: 10 } }); // 请求被缓存 10s,相当于 `getStaticProps` 加上 `revalidate` 参数

    fetch('https://...', { cache: 'no-store' }); // 每次刷新都会重新请求,相当于 `getServerSideProps`

    获取数据之后可以直接用 use() 在服务端消费,渲染 UI。注意 app 目录下的 Server Component 不能用 useState(虽然可以加上 'use client' 改为客户端组件),Next.js 13 建议都在服务端调接口获取数据

  • 此外在 SSG 渲染中常用的 getStaticPaths 改为了 generateStaticParams

参考:

https://beta.nextjs.org/docs/rendering/server-and-client-components#when-to-use-server-vs-client-components

https://beta.nextjs.org/docs/rendering/static-and-dynamic-rendering

https://beta.nextjs.org/docs/data-fetching/fetching

https://beta.nextjs.org/docs/upgrade-guide#dynamic-paths-getstaticpaths

一个 Next.js 13 的演示教程,里面讲了一个 use 导致的无限循环 bug

https://www.youtube.com/watch?v=zwQs4wXr9Bg

你好,Next.js 13

📒 React-query 相关文章

React Query 原理与设计

用react-query解决你一半的状态管理问题

📒 适合团队和个人项目的 Golang 编码规范

📒 优化 CSS 代码的12个小技巧

📒 推荐一款SQL自动检查神器,再也不用担心SQL出错了!

📒 【第2791期】可扩展 CSS 的演变

📒 接口502了,运维和研发谁的锅

📒 Element Plus 组件库相关技术揭秘:7. 组件实现的基本流程及 Icon 组件的实现

📒 突破 etcd 限制!字节自研 K8s 存储 KubeBrain

📒 有趣的 Go HttpClient 超时机制

📒 【综合笔试题】难度 3.5/5,常见序列 DP 题目及其优化思路

📒 socket是并发安全的吗

📒 PGO 是啥,咋就让 Go 更快更猛了

📒 前端食堂技术周刊第 60 期:TypeScript 4.9、Ant Design 5.0、用 vanilla-extract 编写高性能的 CSS

📒 MDH 前端周刊第 77 期:布局动画、Arrow JS、vanilla-extract、antd 5、dumi 2

📒 三种获取Go项目根目录的方式,让你做架构,选哪种

📒 【第2788期】去哪儿低代码平台跨端渲染方案及落地

📒 Gophers如何准备面试

📒 一步一图带你深入理解 Linux 物理内存管理

📒 「每周译Go」理解 Go 中包的可见性

📒 Go语言中常见100问题-#21 Inefficient slice initialization

📒 Go Time 第 256 期

https://changelog.com/gotime/256

📒 Google Go 风格指南

https://google.github.io/styleguide/go/index

📒 Go语言爱好者周刊:第 168 期 — GoLand 2022.3 RC 发布

- - + + \ No newline at end of file diff --git "a/2022/11\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/11\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 260b0d351b..70876abf71 100644 --- "a/2022/11\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/11\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月6日内容汇总

· 7 min read
加菲猫

📒 相关文章推荐

理解 useMemo and useCallback

https://www.joshwcomeau.com/react/usememo-and-usecallback/

React 错误边界指南

https://meticulous.ai/blog/react-error-boundaries-complete-guide/

何时使用 useLayoutEffect 而不是 useEffect

https://javascript.plainenglish.io/react-hooks-when-to-use-uselayouteffect-instead-of-useeffect-3271a96d881a?gi=622ccbf807f3

深度解析好文:为了让 React 更好

https://acko.net/blog/get-in-zoomer-we-re-saving-react/

创建现代 npm 包的最佳实践

https://snyk.io/blog/best-practices-create-modern-npm-package/

useSyncExternalStore:被低估的 React API

https://thisweekinreact.com/articles/useSyncExternalStore-the-underrated-react-api

为什么每个 React 开发者都应该学习函数组合

https://medium.com/javascript-scene/why-every-react-developer-should-learn-function-composition-23f41d4db3b1

“为什么我们要放弃 CSS-in-JS” - Emotion 是一个用 JavaScript 编写 CSS 的流行库,但它的一位贡献者讲述了为什么他的团队总体上放弃了 CSS-in-JS 的想法。

https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b

在 React 中使用 use - 一个新的 Hook 即将到来

https://vived.io/new-hook-is-coming-to-react-frontend-weekly-vol-109/

⭐️ 理解 Next.js 中的 CSR、SSR、SSG、ISR 以及 Streaming

⭐️ 【第2774期】基于 Module Federation 的模块化跨栈方案探索

⭐️ 组件库Monmrepo架构与开发调试环境构建

📒 你了解 Cookie 中的 SameSite 属性吗

📒 配个 json,表单就出来了?FormRender 初探

⭐️ Go每日一库之调用外部命令的几种姿势

📒 带你提前看看 Go 1.20 包括哪些重大变更和性能提升

📒 GitHub上高质量数据结构与算法项目推荐!

📒 如何使用官方的 Node.js Docker 镜像

https://www.docker.com/blog/how-to-use-the-node-docker-official-image/

📒 Node v18 现在进入 LTS 阶段(v18.12.0)

直至 2023 年 10 月,之前作为 current 版本的 v18 将作为 active LTS 存在,并拥有所有最新的功能特性。本版本的代号是 “氢”——宇宙中最丰富的元素。

https://nodejs.org/en/blog/release/v18.12.0/

📒 route-list:显示 Express/Koa/Hapi/Fastify 路由

如果你想以一种优雅的方式查看基于 Node 的 webapp 的所有路由,那么可以试试它。

https://github.com/VladimirMikulic/route-list

📒 现代 CSS 指南 -- at-rule 规则必知必会

📒 深入浅出 Vite - 推荐阅读

📒 开发小技巧

npm scripts 中的 -- 可以用来转发命令行参数:

{
"scripts": {
"build:weapp": "taro build --type=miniprogram",
"dev:weapp": "npm run build:weapp -- --watch"
}
}

⭐️ 极致编译速度,一文搞定webpack5升级

📒 Element Plus 组件库核心技术揭秘:5. 从终端命令解析器说起谈谈 npm 包管理工具的运行原理

📒 一文吃透 React 和 Vue 的多节点 diff 原理

📒 看 Go 中的 struct 如何被优化,还有小插曲

📒 Go for 循环有时候真的很坑

📒 用Go学设计模式-提炼流程,减少重复开发就靠它了!

📒 vue中动态引入图片为什么要是require, 你不知道的那些事

⭐️ 聊一聊常见的构建工具关于插件机制的那些通用套路

📒 Chrome 最近带来了哪些有意思的新东西

📒 深入剖析容器技术基础

📒 前端食堂技术周刊第 57 期:Turbopack、Next.js13、Chrome107、Vite3.2、图解 TLS 1.3

📒 Go 语言终极搜索插件

📒 压缩 70% 下载流量 - 记一次店铺优化专项

📒 我们如何用 Next.js 提高 70% 的 React 加载时间

通过用 Next.js 替换 Create React App,商业计划平台 Causal 通过减少加载时间显著改善了用户体验。怎么做到的?一点 SSR 就能帮你很多。

https://www.causal.app/blog/next-js

📒 “为什么我们要放弃 CSS-in-JS”

Emotion 是一个用 JavaScript 编写 CSS 的流行库,但它的一位贡献者讲述了为什么他的团队总体上放弃了 CSS-in-JS 的想法。

https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b

📒 在 React 中使用 use - 一个新的 Hook 即将到来

上周我们在一个叫做 use 的新 Hook 后面介绍了 RFC —— 这里有一个更容易理解的介绍。“这个不起眼的发明可能永远改变我们将数据输入应用程序的方式。”

https://vived.io/new-hook-is-coming-to-react-frontend-weekly-vol-109/

📒 程序员应该遵守的编程原则(不止Gopher哦)

📒 前端工程化基建探索:从内部机制和核心原理了解npm

📒 哈啰下一代跨技术栈前端组件库 Quark Design 正式开源!

📒 深入浅出JavaScript异步编程

📒 深度解密Go语言之关于 interface 的 10 个问题

📒 手撸源码系列 - cache2go

📒 《 关于我用拓展运算符把项目搞崩这件事 》

注意函数调用不能接受过长的参数:

const items = [];
const newItems=new Array(1000000)

// ❎ 以下两种情况,如果 newItems 很长容易导致爆栈问题
items.push(...newItems);
items.push.apply(items, newItems);

// ✅ 合理做法
items.concat(newItems);
items = [...items, ...newItems];

《 关于我用拓展运算符把项目搞崩这件事 》

📒 前端性能优化到底该怎么做(下)- 直捣黄龙

📒 Go语言爱好者周刊:第 165 期 —— 基于 fyne 实现一个简单计算器

- - + + \ No newline at end of file diff --git "a/2022/12\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/12\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index fd61d0c874..e74f25d80b 100644 --- "a/2022/12\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/12\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月11日内容汇总

· 5 min read
加菲猫

📒 相关文章推荐

Storybook 发布了 一个新的 API。本次更新旨在使对 Vite、Next.js、Svelte、Remix 和 Nuxt 等的支持在 2023 年更容易发布。"对任何框架的零配置支持"。

https://storybook.js.org/blog/framework-api/

入门 Zustand — 本文给出了几个使用 Zustand 的技巧。Zustand 是一个相对最小的状态管理库,拥有很多热情的用户

https://tkdodo.eu/blog/working-with-zustand

Shopify 衡量 React Native 渲染时间的解决方案 — 阅读本文可以了解更多关于 Shopify 的开源库 react-native-performance 是如何工作的,用户如何使用该库,以及为什么测量性能如此重要

https://shopify.engineering/measuring-react-native-rendering-times

给 React 开发者的一篇 CSS 变量教程 — 这是一篇新推出的文章,对如何在项目中使用 CSS 变量(自定义属性)进行了深入的研究

https://www.joshwcomeau.com/css/css-variables-for-react-devs/

📒 【VueConf 2022】尤雨溪:Vue的进化历程

📒 Nodejs 的 stream 操作

import { Readable } from "node:stream";
import fs from "node:fs";

const readable = new Readable();
readable.push("测试内容");
readable.push(null); // no more data

// 将可读流复制到标准输出
readable.pipe(process.stdout);

// 将可读流复制到文件
const writable = fs.createWriteStream("/xxx");
readable.pipe(writable);

Node.js 流(stream):你需要知道的一切

📒 Vite 4.0 正式发布!

📒 Go1.20 将禁止匿名接口循环导入!这是一次打破 Go1 兼容性承诺的真实案例

📒 【第2806期】从Lint工具窥探前端的clean-code

📒 Go1.20 继续优化 errors 库

📒 《MiniReact》带你循环渐进了解React原理

📒 从0.5到1用golang上线一个web项目

📒 从0到0.5用golang写一个web项目

📒 我们是如何追逐元宇宙、XR等“概念股”浪潮的

⭐️ []Uber 的 Go语言开发规范

📒 【第2805期】React 数据获取与性能优化

📒 就在刚刚 Go 1.20 rc 1 发布啦!

📒 CSS 小技巧

background 有哪些属性:

  • background-color
  • background-image
  • background-position
  • background-size
  • background-repeat

常见用法:

background-image: url(xxx);

/** 背景图片填充,适配短边,两个属性通常一起用 */
background-size: contain;
background-repeat: no-repeat;

/** 背景图片填充,适配长边 */
background-size: contain;

/** 自定义背景图片大小,同时自定义布局 */
background-size: 58px 48px;
background-position: top 0 left 6px;

transition 动画可以配合 will-change 属性一起用:

background: transparent;
will-change: background;
transition: background 0.3s ease;

📒 React Streaming SSR 原理解析

⭐️ Nest.js进阶系列四:Node.js中使用Redis原来这么简单!

⭐️ Redis学习-入门篇

📒 【面试高频题】难度 2/5,回溯算法经典运用

📒 【第2804期】Islands 架构原理和实践

📒 Go 1.19.4 和 Go 1.18.9 发布安全更新,涉及 os http 以及 http2 header 缓存等问题

⭐️ 源码深度解析之 Spring IOC

📒 前端食堂技术周刊第 62 期:11 月登陆浏览器的新特性、VueConf 2022、第 93 次 TC39 会议、TS 挑战

📒 还在用HttpUtil?SpringBoot 3.0全新HTTP客户端工具来了,用起来够优雅!

📒 历时8个月,10w字!前端知识体系+大厂面试总结(基础知识篇)

📒 你也是业务开发?提前用这个设计模式预防产品加需求吧

📒 美团二面:TCP 四次挥手,可以变成三次吗

📒 Go1.20 继续小修小补 errors 库

📒 MDH 前端周刊第 78 期:技术文档框架、CSS Architecture、Tailwind 抽象泄漏、调试战术

原文链接:

https://www.yuque.com/chencheng/mdh-weekly/hdwfxidpn4u2bboo

MDH 前端周刊第 78 期:技术文档框架、CSS Architecture、Tailwind 抽象泄漏、调试战术

📒 【面试高频题】难度 3/5,状态压缩 DP 及其优化

📒 面试官:net/http库知道吗?能说说优缺点吗

📒 Go语言中常见100问题-#23 Not properly checking if a slice is empty

📒 【第2802期】Islands Architecture(孤岛架构)在携程新版首页的实践

📒 Go 语言代码风格规范-指南篇

📒 Redis 7.0 源码调试环境搭建与源码导读技巧

- - + + \ No newline at end of file diff --git "a/2022/12\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/12\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 53c69cf981..9fb2d0d89f 100644 --- "a/2022/12\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/12\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月18日内容汇总

· 5 min read
加菲猫

📒 相关文章推荐

何时使用 gRPC 与 GraphQL - 本篇文章比较了两个流行的 API 协议,以了解每个协议在哪些方面最有效

https://stackoverflow.blog/2022/11/28/when-to-use-grpc-vs-graphql/

关于使用 Rust 优化 JavaScript 的讨论 — 在最近的 Next.js 会议上与 Vercel 的 Lee Robinson 交谈

https://stackoverflow.blog/2022/12/09/ready-to-optimize-your-javascript-with-rust/

用于安全发布和安全消费的新 npm 功能 — GitHub 正在继续努力使 npm 生态系统更加安全。这篇文章介绍了两个新东西:细粒度访问令牌 用于帮助包所有者控制对发布工作流程的访问,以及一个新的 代码浏览器,可以直接查看来自官方 npm 站点的包的内容

https://github.blog/2022-12-06-new-npm-features-for-secure-publishing-and-safe-consumption/

在 2023 年使用 TypeScript 设置 Node.js — 这是一本方便、制作精良的入门读物,可以帮助你在短短四分钟内掌握使用 TypeScript 和 Node 的基本知识。

https://www.youtube.com/watch?v=H91aqUHn8sE

40+ Node.js 集成测试最佳实践 — 组件/集成测试正在成为越来越受欢迎的后端测试技术。这个仓库深入研究了各种快速模式和实践,以创建良好的组件测试。同时,还有一个演示应用程序和使用 Jest、Mocha、Express、Fastify 和 Nest.js 的示例

https://github.com/testjavascript/nodejs-integration-tests-best-practices

“停止编写虚假的 React 代码” — Jack 不喜欢在 React 应用中使用普通的 JavaScript,因为惯用的 React 风格的方法会让人感觉更自然。他分享了一些避免自己陷入同样问题的规则

https://www.youtube.com/watch?v=s-lumOeD2fk

Storybook 团队已经分享了对包括 Next.js、SvelteKit 和 Remix 在内的框架的 未来支持的更新。其中大部分将于 2023 年到来

https://storybook.js.org/blog/framework-api/

📒 Redis分布式锁的10个坑

📒 一文彻底理解Go语言栈内存/堆内存

📒 Rollup 与 Webpack 的 Tree-shaking

📒 Rollup源码:模块打包与Tree-Shaking

📒 Vite 特性和部分源码解析

📒 【第2814期】如何更新 NPM 依赖

📒 Webpack深度进阶:两张图彻底讲明白热更新原理!

📒 二十张图片彻底讲明白Webpack设计理念,以看懂为目的

📒 谈谈复杂应用的状态管理(下):基于 Zustand 的渐进式状态管理实践

📒 谈谈复杂应用的状态管理(上):为什么是 Zustand

📒 React Native工程Monorepo改造实践

📒 【第2813期】网易严选APP端上H5容器化建设

📒 Go 1.20 新特性之 time.Compare

📒 【综合笔试题】难度 3.5/5,括号相关剪枝搜索题

📒 Umi 中如何根据服务端响应数据动态更新路由

📒 深度解析 React 性能优化 API

📒 Go1.20 将会修改全局变量的初始化顺序。梅度二开,继续打破 Go1 兼容性承诺!

⭐️ 两种 Option 编程模式的实现,Uber推荐这一种

📒 哔哩哔哩 Web 首页重构——回首2021

📒 前端食堂技术周刊第 63 期:Vite 4.0、State of CSS 2022、Rome v11、Web 性能日历、VueConf 2022 PPT

📒 【综合笔试题】难度 3/5,多解法热门搜索题

📒 ChatGPT 以及相关开源项目体验

📒 Webpack 构建流程

玩转webpack(一)上篇:webpack的基本架构和构建流程

玩转webpack(一)下篇:webpack的基本架构和构建流程

📒 MDH 前端周刊第 79 期:ChatGPT、Vite 4、SWR 2、Intl.Segmenter

📒 Google Go 编程规范

⭐️ Go版本大于1.13,程序里这样做错误处理才地道

📒 【第2809期】大型会场活动线上保障方案

📒 Go语言爱好者周刊:第 171 期

- - + + \ No newline at end of file diff --git "a/2022/12\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/12\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 203c924b73..301014b1ea 100644 --- "a/2022/12\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/12\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月25日内容汇总

· 10 min read
加菲猫

📒 相关文章推荐

Dr. Axel 提出两个提案:Iterator Helpers 和 Set Methods — 本篇文章所讲的内容值得你去研究! Dr. Axel 提出了两个具有前瞻性的 ECMAScript 提案,并在本文中介绍了它们,以及解释了为什么它们会对 JavaScript 开发者有用的原因。第一个提案是关于 iterator helpers (用于处理可迭代数据的新的实用方法),第二个提案是关于 Set methods,它扩展了 ES6 的 Set 对象

https://2ality.com/2022/12/iterator-helpers.html

构建同构 JS 库的五个挑战 — 在 JS 中,同构的意思就是在服务端和浏览器端通过最少的适配使用相同的代码

https://doordash.engineering/2022/12/06/five-challenges-to-building-an-isomorphic-javascript-library/

Next, Nest, Nuxt… Nust? — “这篇博客文章是为在寻找新的 JavaScript 后端框架的人准备的。”如果这些框架的名字你分不清,那么这篇文章就是为你准备的。Marius 解释了 Next 和 Gatsby 等系统做了什么,并触及了一些不同之处

https://www.twilio.com/blog/comparing-nextjs-nestjs-nuxt-gatsby

优化 INP 指标,提升用户体验 — 文章仔细介绍了INP指标,如何计算以及如何优化。INP 指标 -— 从用户交互到页面渲染下一帧的时间差,越短越好

https://web.dev/optimize-inp/

我们是如何为 Monorepo 项目配置 pnpm 和 Turborepo 的

https://nhost.io/blog/how-we-configured-pnpm-and-turborepo-for-our-monorepo

Node 之道:关于设计、架构与最佳实践 — “全图鸟瞰” 式的总结是非常受欢迎的。我们都在为架构设计探索新的设计思路、处理之道。作者在文中总结了在构建高质量 Node 应用程序时,所获得的所有来之不易的最佳实践

https://alexkondov.com/tao-of-node/

新选型流行的 Node 开发模式与工具

https://practica.dev/blog/popular-nodejs-pattern-and-tools-to-reconsider/

制作现代 npm 包的最佳实践 — 手把手引导如何基于最新的最佳实践创造自己的 npm 包。如果你已经掌握了,也值得再次访问,这是一个很好的、常看常新的资源

https://snyk.io/blog/best-practices-create-modern-npm-package/

SWR v2.0: 用于数据获取的 React Hooks — SWR(Stale-While-Revalidate) 的第二个主要版本包括新的 Mutation API、改进的乐观更新 UI 功能、新的开发人员工具以及改进的对并发渲染的支持

https://swr.vercel.app/blog/swr-v2

避免这些常见的 useState 陷阱 — “你首先需要了解 useState 的潜在问题,以便于避免它们,” 所以 Johannes 带我们用一个案例来深入分析和了解

https://profy.dev/article/react-usestate-pitfalls

Josh W Comeau 更新了他的热门文章 - Why React Re-Renders

https://www.joshwcomeau.com/react/why-react-re-renders/

用 Three.js 和 react-three-fiber 创建一个 3D 的圣诞体验

https://www.youtube.com/watch?v=tyNt9Qse1mg

📒 Learning Go by examples: part 7 - Create a cross-platform GUI/Desktop app in Go

📒 解决 Antd 样式预设影响全局样式问题

注意 Antd 打包默认会带一套 global.less 样式预设,在某些老工程用的时候,样式预设可能会影响全局样式。由于 Antd 的组件样式都是建立在这个格式化后的样式上的,不引入这个文件则会导致组件内部样式出问题。解决方案是 收敛 global.less,并保证外部的全局样式无法轻易覆盖 antd 的样式

首先需要限定 global.less,手动套一层作用域:

node_modules/antd/lib/style/core/index.less
*[class*='ant-'] {
@import 'global.less';
}

antd 相关的组件都至少会有一个以 ant- 开头的 class,我们只要利用好这个特点及 CSS 属性选择器即可达到目的

这里存在一个问题,如何将 Antd 的 global.less 文件替换为自己的模块,有两种解决方案:

  • patch-package 打补丁,但是如果第三方库体积过大会 OOM
  • 另一种思路是用 NormalModuleReplacementPlugin 在构建阶段去替换模块

下一步是提升组件样式的权重,此举还能间接提升所有 antd 的样式的权重,避免外部的全局样式对 antd 造成侵入。

既然是改样式,那就用 CSS 界的 babel —— PostCSS,写个 PostCSS 插件,将所有 .ant 开头的类选择器都同样升高即可。利用的是 postcss-selector-parser 这个 PostCSS 官方提供的解析选择器的库,过滤出「第一个以 ant- 开头的类选择器」,在其前面添加一个属性选择器 [class*='ant-'],如果这个选择器排在当前 rule 的第一个或者前面是一个 combinator,则再加一个通配符 *

如何优雅地彻底解决 antd 全局样式问题

📒 对于“前端状态”相关问题,如何思考比较全面

📒 二十张图片彻底讲明白Webpack设计理念,以看懂为目的

📒 【第2820期】去哪儿网用户体验之端上优化实践

📒 有趣的 Go HttpClient 超时机制

📒 JavaScript 中文周刊 #68 - 如何优化 INP 指标,提升用户体验

📒 原生拖拽太拉跨了,纯JS自己手写一个拖拽效果,纵享丝滑

📒 【综合笔试题】难度 4/5,有一定代码量的图论搜索题

📒 别乱用了,用新的。Go SliceHeader 和 StringHeader 将会被废弃!

⭐️ 看了这篇你会发现,你是懂Go内存分配的

📒 你构建的代码为什么这么大

📒 Go语言中常见100问题-#24 Not making slice copies correctly

📒 理解 Go generate

https://go.dev/blog/generate

https://blog.carlmjohnson.net/post/2016-11-27-how-to-use-go-generate/

📒 专注性能的多端研发框架 - ice.js 3 正式发布!

📒 【综合笔试题】难度 1.5/5,常规二叉树爆搜题

📒 低代码没有做到的事情,ChatGPT做到了

⭐️ Vue3生命周期Hooks的原理及其与调度器(Scheduler)的关系

📒 开始做请求方案的调研,这是 Umi/Bigfish 今年最佳实践的最后一个拼图。第一个深入看的是 React Query,翻了 Practical React Query | TkDodo's blog 系列文章后做了两篇笔记。然后对 React Query 路转粉,学习到不少关于请求的细节处理思路,推荐大家都好好读一读

https://tkdodo.eu/blog/practical-react-query

📒 DebugBear 更新了一篇《2022 In Review: What’s New In Web Performance?》 总结 2022 年 Web 性能领域的变化,包括提升资源优先级的 Priority Hints、Chrome 不做 OSCP 证书校验后的性能提升、用于衡量交互后响应速度的 INP 指标、Google 将 Core Web Vitals 纳入排名因素、Chrome 浏览器支持前进后退缓存、HTTP/3 标准化、Chrome DevTool 和 performance API 会提示哪些资源会 block、用于提前提供资源列表的 103 响应、Chrome 108 开始支持全页面预渲染、Safari 支持 AVIF、Safari 原生支持图片懒加载

https://www.debugbear.com/blog/2022-in-web-performance

📒 StackDiary 更新了《The Most Popular Node.js Frameworks in 2022》和《The Most Popular CSS-in-JS Libraries in 2022》,分别由 Next.js 和 Styled-Components 拔得头筹,Styled-Components 已连续 4 年第一

https://stackdiary.com/node-js-frameworks/

https://stackdiary.com/css-in-js-libraries/

📒 发现一本免费的算法书《Hello 算法》,没细看,感兴趣可关注

https://www.hello-algo.com/

📒 React 的 useEvent RFC 里,useEvent 更名为 useEffectEvent,Event function 更名为 Effect Event

https://github.com/reactjs/reactjs.org/pull/5373

📒 看到 Codux 发布,来自 Wix 联合创始人的作品。这是一个 React 组件可视化编辑器,类似 Storybook,特点是和代码之间双向同步

https://dev.to/codux/introducing-codux-15j5

📒 React Router 发布 6.5,支持 Optional Route Segments。在任何 path 段末尾添加一个 ? 会使整个路径段成为可选,对静态段和动态参数都有效

https://github.com/remix-run/react-router/releases/tag/react-router%406.5.0

📒 Tauri Mobile 发布 Alpha,支持 iOS 和 Andriod,需要用 2.0.0-alpha.0 版本的依赖

https://tauri.app/blog/2022/12/09/tauri-mobile-alpha/

📒 MDH 前端周刊第 80 期:SvelteKit 1、Tauri Mobile、RR 6.5、useEffectEvent

📒 🌼 细数那些惊艳一时的 CSS 属性

📒 关于无感刷新Token,我是这样子做的

📒 JavaScript 中的依赖注入

📒 我的Vue.js生态开源之旅

📒 为什么用公钥加密却不能用公钥解密

⭐️ 「Go工具箱」一文读懂主流web框架中路由的实现原理

⭐️ Go类型系统:有何与众不同

- - + + \ No newline at end of file diff --git "a/2022/12\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/12\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e9bcdb85e5..9034359d1b 100644 --- "a/2022/12\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/12\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月4日内容汇总

· 5 min read
加菲猫

📒 相关文章推荐

Ant Design v5.0: 企业级设计语言 React UI 组件库 — Ant Design 5.0 版本提供了更多的组件,简约的设计以及更强的动态主题和定制主题。这里有面向老用户的升级指南:从 v4 到 v5 – 官方首页。

https://github.com/ant-design/ant-design/issues/38671

如何优化 Vue.js 应用程序 — 涵盖了构建 Vue 应用程序时要牢记的一些基本思想。

https://www.smashingmagazine.com/2022/11/optimizing-vue-app/

以正确的方式编写和组织 Node API 测试

https://larswaechter.dev/blog/nodejs-api-testing/

使用 TypeScript 生成原生的 ESM

https://2ality.com/2021/06/typescript-esm-nodejs.html

需要避免的 Node.js 架构陷阱

https://blog.appsignal.com/2022/11/23/nodejs-architecture-pitfalls-to-avoid.html

Hyperstack:一个受 Rails 启发的新的 Node.js Web 框架

https://hyperstackjs.io/

将 React 交互时间缩短 4 倍

https://www.causal.app/blog/react-perf

在 Deno 中使用框架构建应用程序.. 比如 Reac

https://deno.com/blog/frameworks-with-npm

在 React 应用中使用几种数据结构的真实案例

https://profy.dev/article/javascript-data-structures

Clapy:一款 Figma 插件,可基于 Figma 设计产出 React 组件

https://clapy.co/

📒 GoLand 迎来五周年,同时发布 2022.3:有彩蛋

📒 了解微前端,深入前端架构的前世今生

📒 CSS 方案 2022

⭐️ 公司新来一个同事,把优惠券系统设计的炉火纯青!

⭐️ 傻瓜方式分析前端应用的体积

📒 Go语言中常见100问题-#22 Being confused about nil vs. empty slices

📒 18.6K Star!这款 JSON 数据可视化工具太优雅了!

📒 Go 服务自动收集线上问题现场

📒 TypeScript从平凡到不凡(基础篇)

⭐️ Webpack配置全解析(优化篇)

📒 用 Wireshark 让你看见 TCP 到底是什么样!

📒 大象在云端起舞:后 Hadoop 时代的字节跳动云原生计算平台——云原生计算团队采访

📒 【面试高频题】难度 3/5,设计跳表(数据结构经典考察)

📒 动图图解 | UDP就一定比TCP快吗

⭐️ 深入理解 golang 的互斥锁

📒 说两个 Go 循环里的坑,第二个在JS里也有

📒 React Server Component: 混合式渲染

📒 前端工程化基建探索(5)Vite4.0.0都悄悄在“卷”出来了,是时候去探索Vite的设计和实现了

📒 前端工程化基建探索(4)从源码出发探索理解webpack核心特性

📒 前端食堂技术周刊第 61 期:State of JavaScript、Prettier 2.8、Flexbox 交互式指南

📒 彻底搞懂 React 18 并发机制的原理

📒 读完《重构》我学到了这些提升代码质量的编程技巧

📒 一款好用的 Go 调用链可视化工具

📒 用Go学设计模式- 模板模式

📒 Go Context 怎么用,原理是啥,看完这篇就清晰了

📒 Go 模糊测试fuzzing的原理分析

📒 为iframe正名,你可能并不需要微前端

📒 现代CSS样式重置最佳实践!

📒 如何解决前端领域的竞态问题

📒 【第2795期】雪球跨端架构建设之三端同构篇

📒 【第2785期】雪球跨端架构建设之跨端容器篇

📒 Go 语言代码风格规范-概述篇

📒 DNS中有哪些值得学习的优秀设计

📒 Go语言爱好者周刊:第 169 期 — 正确率 23%

- - + + \ No newline at end of file diff --git "a/2022/1\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/1\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d41b71efc2..af024bd01f 100644 --- "a/2022/1\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/1\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月16日内容汇总

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git "a/2022/1\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/1\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 0044e256f3..2398d97e3f 100644 --- "a/2022/1\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/1\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月23日内容汇总

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git "a/2022/1\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/1\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3e925af9d2..c9741ed314 100644 --- "a/2022/1\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/1\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月2日内容汇总

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git "a/2022/1\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/1\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 25bd4e507f..296e00ca56 100644 --- "a/2022/1\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/1\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月30日内容汇总

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

- - + + \ No newline at end of file diff --git "a/2022/1\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/1\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e5047ddfc9..75f4340b9c 100644 --- "a/2022/1\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/1\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

1月9日内容汇总

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/2\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/2\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e2aba74f4b..a945d450d3 100644 --- "a/2022/2\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/2\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月13日内容汇总

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

- - + + \ No newline at end of file diff --git "a/2022/2\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/2\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 72dbe7a6af..f4262f8e06 100644 --- "a/2022/2\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/2\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月20日内容汇总

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

- - + + \ No newline at end of file diff --git "a/2022/2\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/2\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index ee20c04aa7..3129843158 100644 --- "a/2022/2\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/2\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月27日内容汇总

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git "a/2022/2\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/2\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index ac65d057cd..96332f8601 100644 --- "a/2022/2\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/2\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月6日内容汇总

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析
- - + + \ No newline at end of file diff --git "a/2022/3\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/3\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 47e2a1680f..063c040d35 100644 --- "a/2022/3\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/3\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月13日内容汇总

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

- - + + \ No newline at end of file diff --git "a/2022/3\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/3\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 1a769a60ad..5611d9a53d 100644 --- "a/2022/3\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/3\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月20日内容汇总

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

- - + + \ No newline at end of file diff --git "a/2022/3\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/3\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 93f64c79ef..69fce8e2a7 100644 --- "a/2022/3\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/3\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

3月27日内容汇总

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

- - + + \ No newline at end of file diff --git "a/2022/3\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/3\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 42e5f50c59..6d35bf5b73 100644 --- "a/2022/3\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/3\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月6日内容汇总

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

- - + + \ No newline at end of file diff --git "a/2022/4\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/4\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d6025e1624..fdade82f89 100644 --- "a/2022/4\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/4\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月10日内容汇总

· 7 min read
加菲猫

📒 编译 ts 代码用 tsc 还是 babel

📒 第三方库是否应该提交 lockfile

在业务项目中,每次依赖安装的版本号都从 lock 文件中进行获取,锁定依赖和依赖的依赖,避免了不可测的依赖风险。但是仍然存在间接依赖不可控的问题,例如 React 依赖 object-assign,在 React 中 lockfile 锁定的版本为 object-assign@4.1.0,但是前端项目实际安装的版本为 object-assign@4.99.99

  • 第三方库的 devDependencies 必须锁定,这样 Contributor 可根据 lockfile 很容易将项目跑起来
  • 第三方库的 dependencies 虽然有可能存在不可控问题,但是可通过锁死依赖或者勤加更新的方式来解决

如果没有 package-lock.json,那将如何

📒 工程化知识卡片 023:node_modules 版本重复的困境

npmv3 之后 node_modules 为平铺结构,但是仍然存在依赖重复安装的问题。

工程化知识卡片 023:node_modules 版本重复的困境

📒 Vue 开发小技巧

分享 15 个 Vue3 全家桶开发的避坑经验

vue3中可以帮助你早点下班的9个开发技巧

📒 【混淆系列】三问:npx、npm、cnpm、pnpm区别你搞清楚了吗?

📒 Webpack组件库打包超详细指南

📒 Node.js 技术架构

Node 是怎么实现的?简言之:用 V8 运行 JS、用 bindings 实现 JS 与 C/C++ 沟通、用 C/C++ 库高效处理 IO、用 Node.js 标准库简化 JS 代码、用 Event Loop 管理事件处理顺序、用 libuv 实现异步 I/O 操作。

Node.js 技术架构

📒 Web 框架的替代方案

📒 写好 JavaScript 异步代码的几个推荐做法

📒 Node.js 进阶 - 多文件 Stream 合并,串行和并发两种模式实现

重要的事情再说一遍,pipe 方法默认情况下会自动关闭可写流,但是如果可读流期间发生错误,则写入的目标流将不会关闭,所以如果使用 pipe 需要监听错误事件,手动关闭可写流,防止文件句柄泄露。

Node.js 进阶 - 多文件 Stream 合并,串行和并发两种模式实现

📒 服务端渲染SSR及实现原理

📒 手摸手服务端渲染-react

📒 如何在项目中用好 TypeScript

📒 Golang 和 JS 创建对象方式对比

Golang 与 JS 创建对象非常类似,Golang 在创建对象的时候需要定义 schema 进行类型约束:

type Person struct {
Name string
Age int
Sex bool
}

person := Person{
Name: "dbydm",
Age: 12,
Sex: true,
}

Golang 创建对象数组:

list := []*Person{
&Person{
Name: "dbydm",
Age: 12,
Sex: true,
},
&Person{
Name: "dm",
Age: 2333,
Sex: false,
},
}

📒 Node.js 常见的系统信号

  • SIGHUP:不通过 ctrl+c 停止进程,而是直接关闭命令行终端,会触发该信号
  • SIGINT:按下 ctrl+c 停止进程时触发;pm2 重启或者停止子进程时,也会向子进程发送该信号
  • SIGTERM:一般用于通知进程优雅退出,如 k8s 删除 pod 时,就会向 pod 发送 SIGTERM 信号,pod 可以在超时时间内(默认 30s)做一些退出清理动作
  • SIGBREAK:在 window 系统上,按下 ctrl+break 会触发该信号
  • SIGKILL:强制退出进程,进程无法做任何清理动作,执行命令 kill -9 pid,进程会收到该信号。k8s 删除 pod 时,如果超过 30s,pod 还没退出,k8s 会向 pod 发送 SIGKILL 信号,立即退出 pod 进程;pm2 在重启或者停止进程时,如果超过 1.6s,进程还没退出,也会发送 SIGKILL 信号

📒 2022 年,Babel vs TypeScript,谁更适合代码编译

📒 React 常用状态管理库

  • Redux
  • Mobx
  • Recoil
  • Hookstate
  • Rematch
  • Jotai
  • Zustand

📒 从源码理清 useEffect 第二个参数是怎么处理的

📒 腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检?

📒 如何在 Node 环境使用 ESM 模块规范

首先明确一点,Node 环境并非不支持 ESM 规范,只是没有启用而已,默认使用 CJS 规范,可通过如下方式启用:

  • 单文件使用 ESM 规范,可以将该文件后缀改为 .mjs
  • 整个工程使用 ESM 规范,可以在 package.json 中配置 "type": "module"

假如不想通过上述方式启用,还有一些方法:

  • 通过 Webpack 等打包工具支持 ESM 模块(Webpack 默认使用 web 环境构建,需要配置 target: "node" 避免打包 Node 内置模块);
  • 还可以使用 ts-nodejiti 等 runtime 支持 ESM 模块(内部使用 tsc 或者 babel 进行编译);

📒 如何生成随机 ID

一种是直接使用 Math.random()

const randomId = () => Math.random().toString().slice(2, 8);

另一种是使用查表的方式:

// 生成 [0..9] 的数组
const nums = Array.from({ length: 10 }, (_, index) => index);

// 从 nums 数组中随机选取元素
const sample = (arr) => arr[Math.floor(Math.random() * arr.length)];
const randomId = () => Array.from({ length: 6 }, () => sample(nums)).join("");

📒 跨域如何携带 Cookie

  • 如果通过网关层代理(例如 nginx)则不用担心,对于浏览器来说实际上并没有跨域,可正常携带 Cookie
  • 如果通过 CORS 跨域,浏览器默认不会携带 Cookie,此时有两种方案:
    • 在请求头中添加 Authorization 字段发送 Cookie(在 axios 中配置请求拦截添加)
    • 后端响应头添加 Access-Control-Allow-Credentials,前端发送请求时配置 xhr.withCredentials = true
- - + + \ No newline at end of file diff --git "a/2022/4\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/4\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3f358710b8..a2f815fcad 100644 --- "a/2022/4\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/4\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月17日内容汇总

· 5 min read
加菲猫

📒 JS 相关技巧

// 1. 数组转对象
const dict: Record<number, boolean> = Object.fromEntries(
array.map(i => [i, true])
)

// 2. 使用 Array.from 初始化数组
const digits = Array.from({ length: 10 }, (_, i) => i);

// 3. 字符串转数组,然后用数组方法遍历
// 常规方法是用 split()
String(num).split("").reduce(...)
// 由于字符串实现了 iterator 接口,因此可以使用扩展运算符展开到数组中
[...String(num)].reduce(...)

📒 用Rust锈化Vue Compiler

📒 TS 类型体操性能分析

$ tsc index.ts –-diagnostics

📒 前端动画实现方案

  • CSS 方案:transitionanimation
  • JS 方案:setTimeoutrequestAnimationFrame

一个实验性 API Element.animate(),可以在渲染进程的时候就执行,性能更好。

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/animate

📒 我是如何带领团队从零到一建立前端规范的

📒 血泪教训之请不要再轻视Git —— 我在工作中是如何使用 Git 的

📒 https://nextjs.org/learn/basics/create-nextjs-app

📒 https://nextjs.org/docs

📒 手把手教你用神器nextjs一键导出你的github博客文章生成静态html

📒 Golang 三数之和

package algorithm

import (
"sort"
)

func ThreeSum(nums []int) [][]int {
ans := make([][]int, 0)
// 数组元素个数小于 3,直接返回
if len(nums) < 3 {
return ans
}
// 排序
sort.Ints(nums)
// 遍历到倒数第二个,因为是三个数总和
for i := 0; i < len(nums) - 2; i++ {
// 规定 nums[i] < nums[left] < nums[right]
// 如果 nums[i] > 0 则不存在另外两个值使得相加等于 0
// 大于 0 可以直接跳出循环了
if nums[i] > 0 {
break
}
// 过滤 nums[i] 重复
if i > 0 && nums[i] == nums[i-1] {
continue
}
// 先确定一个值 nums[i]
// 再去找另外两个值 nums[left] 和 nums[right]
// 需要满足 nums[i] < nums[left] < nums[right]
target := -nums[i]
left, right := i + 1, len(nums) - 1

// 使用双指针法确定剩下两个值
for left < right {
sum := nums[left] + nums[right]
if sum < target {
left++
} else if sum > target {
right--
} else if sum == target {
ans = append(ans, []int{nums[i], nums[left], nums[right]})
// 找到目标值,左右指针分别移动一位
left++
right--
// 过滤 nums[left] 重复
for left < right && nums[left] == nums[left-1] {
left++
}
// 过滤 nums[right] 重复
for left < right && nums[right] == nums[right+1] {
right--
}
}
}
}
return ans
}

📒 Golang 手写数组方法

package main

import (
"fmt"
)

func ForEach(nums []int, fn func(int, int)) {
for index, item := range nums {
fn(item, index)
}
}

func Map(nums []int, fn func(int, int) int) []int {
res := make([]int, 0)
for index, item := range nums {
res = append(res, fn(item, index))
}
return res;
}

func Filter(nums []int, fn func(int, int) bool) []int {
res := make([]int, 0)
for index, item := range nums {
if fn(item, index) {
res = append(res, item)
}
}
return res
}

func Reduce(nums []int, fn func(int, int, int) int, initValue int) int {
res := initValue
for index, item := range nums {
res = fn(res, item, index)
}
return res
}

func main() {
s := []int{1, 2, 3, 4}
ForEach(s, func(item, index int) {
fmt.Println("===forEach", item, index)
})
mapped := Map(s, func(item, index int) int {
return item * 2
})
fmt.Println(mapped)
filtered := Filter(s, func(item, index int) bool {
return item % 2 == 0
})
fmt.Println(filtered)
reduced := Reduce(s, func(accu, cur, index int) int {
return accu + cur
}, 0)
fmt.Println(reduced)
}

📒 选择第三方 NPM 包时的 5 条最佳实践

📒 Vue3.2 vDOM diff流程分析之一:diff算法

📒 从零到一,我们来一起造个 JS 的编译器

⭐️ 2022 年的 React 生态

📒 linux后台开发具备能力集锦

📒 Linux下C++后台服务器开发

📒 Go 语言与并发编程

📒 打造轻量级 WebIDE,看这一篇文章就够啦

📒 developer-roadmap

developer-roadmap 是一个开发人员路线图,包含了前端路线图、后端路线图、DevOps 路线图、React 路线图、Angular 路线图、Android 路线图、Python 路线图、Go 路线图、Java 路线图、DBA 路线图。

https://github.com/kamranahmedse/developer-roadmap

📒 pkg: 把 Node.js 项目打包为可执行文件

- - + + \ No newline at end of file diff --git "a/2022/4\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/4\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 39c9affc83..bf3db7e418 100644 --- "a/2022/4\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/4\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月24日内容汇总

· 14 min read
加菲猫

📒 Ubuntu 22.04 LTS 安装

https://phoenixnap.com/kb/ubuntu-22-04-lts

https://releases.ubuntu.com/jammy/

📒 计算机程序的构造和解释 — JavaScript 版

这本由麻省理工学院出版的著作终于有了 JavaScript 语言版本,可以帮助你建立对计算机程序的心智模型。

https://github.com/source-academy/sicp

📒 为什么要使用 Redux Toolkit

Redux 官方发布的这篇博客讲解了 Redux Toolkit 的 Why 和 How,并强烈推荐使用。

一句话总结:Redux Toolkit 是使用 Redux 的最佳实践。

https://redux.js.org/introduction/why-rtk-is-redux-today

⭐️ Node.js 18 新特性解读

📒 那些你应该说再见的 npm 祖传老库

📒 如何实现数组转对象

传入一个 paramKeys 数组,获取 query 参数的值,然后以对象形式返回,使用 reduce 方法:

function getSearchParams(paramKeys: string[]): Record<string, string> {
const searchParams = new URLSearchParams(window.location.search);
return paramKeys.reduce<Record<string, string>>((accu, cur) => {
accu[cur] = searchParams.get(cur) || '';
return accu;
}, {});
}

// 使用
const searchParams = getSearchParams(['name', 'age']);

以上流程还可以封装成自定义 hook:

import * as React from 'react';

function useSearchParams(paramKeys: string[]): Record<string, string> {
const query = window.location.search;
return React.useMemo(() => {
const searchParams = new URLSearchParams(query);
return paramKeys.reduce<Record<string, string>>((accu, cur) => {
accu[cur] = searchParams.get(cur) || '';
return accu;
}, {});
}, [paramKeys, query]);
}

看了 antfu 大佬的代码,还可以使用 Object.fromEntries() 方法:

function useSearchParams(paramKeys: string[]): Record<string, string> {
const searchParams = new URLSearchParams(window.location.search);
return Object.fromEntries(
paramKeys.map((key) => [key, searchParams.get(key)])
);
}

注意:Object.fromEntries() 是 ES2019 中的语法,存在兼容性问题(Chrome >= 73),不过只要正确配置 polyfill 就可以放心使用

📒 使用 defineConfig 约束配置对象

在项目中经常需要用到配置对象,例如 Webpack、rollup 的配置,我们可以使用 TS 来约束配置对象的 API schema,告知用户应该传哪些字段以及对应的类型,这样有两个好处:

  • 对用户更加友好,不需要看文档就能直接上手
  • 在开发阶段就能提前检查出配置项错误,不用到运行阶段再去校验了

一般来说我们需要导出一个接口类型:

export type IConfig = {
name: string;
age: number;
sex?: boolean;
};

用户在使用的时候需要导入类型,然后自己添加注解,这样编写配置对象就能得到类型提示了:

import type { IConfig } from "xxx";

const config: IConfig[] = [
{
name: "dbydm",
age: 23
}
]

但是这样对用户来说还是太麻烦了,我们可以定义一个 defineConfig 函数,这个函数做的事情很简单,就是把接收到的参数原封不动地返回,但在这个过程中,就可以实现参数类型的校验:

type IConfig = {
name: string;
age: number;
sex?: boolean;
};

export function defineConfig(config: IConfig[]) {
return config;
}

用户只需导入 defineConfig 编写配置就可以实现参数类型的校验:

import { defineConfig } from "xxx";

export default defineConfig([
{
name: "dbydm",
age: 23
}
])

📒 Elasticsearch 基础入门详文

📒 如何把前端项目写成一座屎山

📒 浅谈JS内存机制

📒 深入理解 scheduler 原理

📒 前端框架如何实现预渲染

首先预渲染根据渲染时机分为以下两种:

  • 静态站点生成(SSG),构建的时候获取数据进行渲染,数据不一定是最新的
  • 服务端渲染(SSR),用户访问的时候服务端获取数据进行渲染,数据实时获取

两种渲染方案都可以实现 首屏性能优化SEO 优化,不同的是 SSR 需要在服务端运行 JS,并且每次用户请求的时候都会进行渲染;SSG 已经将每个页面渲染成静态 html,因此可以将资源托管到 CDN 上

获取数据又可以分为以下几种方式:

  • 本地文件系统读取
  • 调接口获取
  • 查询数据库获取

实际上,React 本身已经提供了服务端渲染和静态生成相关的 API。在前端项目中,我们一般会使用下面的 API 挂载 React 组件:

ReactDOM.render(element, container[, callback])

为了实现 SSR 渲染,我们可以使用下面的 API 将 React 组件直接渲染为 HTML 字符串:

ReactDOMServer.renderToString(element)

使用 renderToString 方法渲染出的 HTML 字符串会带有特定标记,我们可以使用下面的 API 在客户端进行激活,对标记的节点挂载相应的事件监听器:

ReactDOM.hydrate(element, container[, callback])

在 SSG 渲染中,我们不需要在客户端进行激活,因此不用在 HTML 字符串中添加标记,只需渲染出纯的 HTML 字符串:

ReactDOMServer.renderToStaticMarkup(element)

📒 2万字系统总结,带你实现 Linux 命令自由

📒 还在手撸 Nginx 配置?试试这款可视化配置工具吧,真心强大

📒 esno,基于 Esbuild 的神器

📒 「React进阶」换个姿势看 hooks ! 灵感来源组合和HOC 模式下逻辑视图分离新创意

useMemo 类似 Vue 中的计算属性,当依赖项发生变化,会重新计算。但实际上 useMemo 比计算属性更强大,除了缓存值之外,还能缓存组件:

function Index({ value }){
const [number, setNumber] = React.useState(0);
const element = React.useMemo(() => <Test />, [value]);

return (
<div>
{element}
<button onClick={() => setNumber(number + 1)}>点击 {number}</button>
</div>
)
}

有时候在父组件定义的事件处理函数,需要作为 prop 传入子组件。如果父组件重新渲染,会导致函数重新生成,相当于 prop 发生变化,即使子组件内部使用 React.memo() 包裹也会导致重新渲染。常规做法是使用 React.useCallback() 包裹事件处理函数,但实际上用 React.useRef() 包裹也是可以的,都是把事件处理函数缓存到 Fiber 节点上。

function MyApp() {
const onClickRef = React.useRef(() => {
console.log("666");
});

// const onClick = React.useCallback(() => {}, []);

return (
<div>
<h1>Welcome to my app</h1>
<MyButton onClick={onClickRef.current} />
</div>
);
}

「React进阶」换个姿势看 hooks ! 灵感来源组合和HOC 模式下逻辑视图分离新创意

📒 React 18 升级踩坑汇总

1. React.StrictMode 导致所有组件重复挂载两次

使用 CRA 5.0.1 搭建 React 项目,默认的项目模板中,根组件使用了 React.StrictMode 包裹,结果出现了所有组件都重复挂载的情况,导致组件中接口调了两次。看了下文档,确实是 React 18 中引入的 Breaking Change,启用严格模式,会导致所有组件重复挂载两次(即使用了 React.memo 也会重复挂载):

Stricter Strict Mode: In the future, React will provide a feature that lets components preserve state between unmounts. To prepare for it, React 18 introduces a new development-only check to Strict Mode. React will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount. If this breaks your app, consider removing Strict Mode until you can fix the components to be resilient to remounting with existing state

tip

使用 CRA 创建的 React 18 项目,建议移除 React.StrictMode

2. React 18 中使用了 antd 的 message 组件控制台打印警告信息

React 18 使用了新的 ReactDOM.createRoot() API 挂载根节点,Concurrent Mode 需要通过此 API 开启,但是 antd 中的 message 等组件内部仍使用 ReactDOM.render() 挂载根节点,此时在控制台会打印警告,注意这并不是报错,仅仅只是 fallback 到 legacy mode 而已。

tip

升级前最好仔细看一遍官方的说明,特别是 Breaking Change:

https://github.com/facebook/react/releases/tag/v18.0.0

📒 为什么需要 peerDependencies

例如开发一个 React 组件库的时候,有三个诉求:

  • 该组件库开发的时候需要安装 React;
  • 用户引入该组件库的时候不能重复安装 React;
  • 组件库的 React 版本与目标环境不一致的时候需要被包管理器发现并打印警告;

如果安装到 dependencies 下,显然会导致重复安装;如果安装到 devDependencies 下虽然不会导致重复安装,但包管理器不会检查版本,当版本不一致的时候不会打印警告。所以 peerDependencies 是最优选择。

在老版本 React 项目中引入某些依赖库(例如 antdreact-transition-group),一般不能直接安装最新的版本(大概率会报错),此时应该根据依赖库的 package.json 中指定的 peerDependencies 字段选择合适的依赖库版本

⭐️ 什么是 JavaScript 的函数组合

本篇文章以一个简略的 Markdown 的例子为主线,讲述了什么是函数组合,以及如何使用函数组合的思想编写代码,是一篇非常不错的编程思想类文章。

https://jrsinclair.com/articles/2022/javascript-function-composition-whats-the-big-deal/

📒 一些关于react的keep-alive功能相关知识在这里(下)

📒 一些关于react的keep-alive功能相关知识在这里(上)

📒 理清 HTTP 下的 TCP 流程,让你的 HTTP 水平更上一层

📒 React 18 系列

React 18 全览

React 18 对 Hooks 的影响

React 的心智模型

你不知道的 React v18 的任务调度机制

📒 React 几个小技巧

1. React 内置工具类型

// 使用 React.ComponentType 同时表示类组件和函数组件
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

// 使用 React.Key 来表示列表渲染 key 的类型
type Key = string | number;

参考:

精读《@types react 值得注意的 TS 技巧》

从 @types/react 的类型定义中,我学到了什么

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/v17/index.d.ts

2. 自定义组件如何绑定 className

className 作为 prop 传入,内部使用 classnames 这个库进行拼接:

import cx from "classnames";
import s from "./style.module.less";

type IProps = {
className: string;
}

const App: React.FC<IProps> = ({ className }) => {
return (
<div className={cx(s.wrapper, className)}>
...
</div>
)
}

更进一步,把以上流程封装成高阶组件(HOC):

function withClassName<T>(Component: React.ComponentType<T>): React.FC<T & { className: string }> {
return ({ className, ...restProps }) => {
return (
<div className={className}>
<Component {...restProps} />
</div>
)
}
}

3. Input 如何变为受控组件

Antd 中的 Input 默认是非受控组件,可以绑定 value,然后监听 onChange 修改 value 实现受控(v-model 的原理):

const App: React.FC<{}> = () => {
const [num, setNum] = React.useState(1);

return (
<InputNumber value={num} onChange={setNum} />
)
}

📒 我帮一朋友重构了点代码,他直呼牛批,但基操勿六

📒 React + TypeScript:如何处理常见事件

📒 单例模式 4 种经典实现方法

📒 如何实现 useClickAway

如何监听元素外的点击,类似 Vue 的 ClickOutSide 指令

官方文档:https://ahooks.js.org/hooks/use-click-away

源码:https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useClickAway/index.ts

📒 快速理解 TypeScript 的逆变、协变

📒 都 2022 年了,手动搭建 React 开发环境很难吗

📒 这篇手写 Promise 你一定要康康

📒 超全面的前端新一代构建工具对比: esbuild、Snowpack、Vite、wmr

- - + + \ No newline at end of file diff --git "a/2022/4\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/4\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 12e837e506..9e9559f93a 100644 --- "a/2022/4\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/4\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月3日内容汇总

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

- - + + \ No newline at end of file diff --git "a/2022/5\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/5\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index b56cfa11c0..25aba3c892 100644 --- "a/2022/5\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/5\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月15日内容汇总

· 18 min read
加菲猫

📒 解决 Vite 打包 React 组件库无法排除 peerDependencies 的问题

轮子系列:使用vite从零开发React组件库

如何使用Rollup打包React组件库

使用 dumi 实现组件库文档自动化

https://d.umijs.org/zh-CN/guide/advanced#%E7%BB%84%E4%BB%B6-api-%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90

📒 NodeJs进阶开发、性能优化指南

📒 使用 URLSearchParams 注意事项

很多同学都会用 URLSearchParams 解析、拼接 query 参数,非常方便,而且还能自动进行参数编码、解码。但是在使用的时候,有几个注意事项:

const p = new URLSearchParams();

// 1. 当某个 value 为 undefined 时,会直接转为字符串拼接到 URL 上
p.set("dby", undefined);
p.set("dm", 2333);
p.toString(); // 'dby=undefined&dm=2333'

// 解决方案,使用逻辑或操作
p.set("dby", undefined || "");
p.toString(); // 'dby=&dm=2333'

// 2. get 一个不存在的值,返回的是 null,因此 TS 会推导为联合类型
const foo = p.get("foo"); // string | null

// 解决方案,使用逻辑或操作,实现类型守卫
const foo = p.get("foo") || ""; // string

📒 写给前端的手动内存管理基础入门(一)返璞归真:从引用类型到裸指针

📒 React如何原生实现防抖

📒 你想知道vite核心原理吗,我来手写告诉你(80行源代码)

📒 Rust 入门 - 资源与生命周期

📒 The Ultimate Guide To Software Engineering

📒 Tree shaking问题排查指南来啦

Tree shaking在不同工具里的意义不太统一,为了统一后续讨论,我们规范各个术语:

  • minify:编译优化手段,指在不影响代码语义的情况下,尽可能的减小程序的体积,常见的 minify 工具如 terser、uglify,swc 和 esbuid 也自带 minify 功能
  • Dead code elimination(DCE):即死代码优化,一种编译器优化手段,用于移除不影响程序结果的代码,实现DCE的手段有很多种,如 const folding (常量折叠)、Control flow analysis、也包括下面的 LTO
  • Link Time Optimization:指 link 期优化的手段,可以进行跨模块的分析优化,如可以分析模块之间的引用关系,删掉其他模块未使用的导出变量,也可以进行跨模块对符号进行 mangle http://johanengelen.github.io/ldc/2016/11/10/Link-Time-Optimization-LDC.html
  • Tree shaking:一种在 Javascript 社区流行的一个术语,是一种死代码优化手段,其依赖于 ES2015 的模块语法,由 rollup 引入。这里的 tree shaking 通常指的是基于 module 的跨模块死代码删除技术,即基于 LTO 的 DCE,其区别于一般的 DCE 在于,其只进行 top-level 和跨模块引用分析,并不会去尝试优化如函数里的实现的 DCE

Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. import and export. The name and concept have been popularized by the ES2015 module bundler rollup.

https://webpack.js.org/guides/tree-shaking/

  • mangle:即符号压缩,将变量名以更短的变量名进行替换
  • 副作用:对程序状态造成影响,死代码优化一般不能删除副作用代码,即使副作用代码的结果在其他地方没用到
  • 模块内部副作用:副作用影响范围仅限于当前模块,如果外部模块不依赖当前模块,那么该副作用代码可以跟随当前模块一起被删除,如果外部模块依赖了当前模块,则该副作用代码不能被删除

image

因此我们的后续讨论,所说的 tree shaking 均是指基于 LTO 的 DCE,而 DCE 指的是不包含 tree shaking 的其他 DCE 部分。

简单来说即是,tree shaking 负责移除未引用的 top-level 语句,而 DCE 删除无用的语句

Tree shaking问题排查指南来啦

📒 [科普] JS中Object的keys是无序的吗

1. Object.keys() 返回类型始终为 string[]

因为 JS 对象 key 的类型只有三种:numberstringSymbol,需要注意 number 类型底层也是按 string 进行存储,而 Symbol 类型不可枚举。

2. ES2015 之后 Object.keys() 输出顺序是可以预测的

我们说普通对象的 Key 是无序的,不可靠的,指的是不能正确维护插入顺序,与之相对的是 Map 实例会维护键值对的插入顺序。

在 ES2015 之后,普通对象 Key 顺序是可预测的。先按照自然数升序进行排序,然后按照非数字的 String 的加入时间排序,然后按照 Symbol 的时间顺序进行排序。也就是说他们会先按照上述的分类进行拆分,先按照自然数、非自然数、Symbol 的顺序进行排序,然后根据上述三种类型下内部的顺序进行排序。

使用 Object.keys() 只会输出对象自身可枚举属性的 key,不含 Symbol 类型的 key。如果要输出 Symbol 类型 key,可以使用 Reflect.ownKeys()

[科普] JS中Object的keys是无序的吗

📒 如何设计更优雅的 React 组件

📒 代码覆盖率在性能优化上的一种可行应用

由于 JS 资源需要通过网络加载,代码的体积直接影响页面加载性能。很多时候我们“喂”给浏览器的代码,并不会全部执行,因此我们可以做分包优化,即 code-spliting,只“喂”给浏览器渲染当前页面所需的资源。

注意区分以下两个概念:

  • Dead code

    也叫无用代码,这个概念应是在编译时静态分析出的对执行无影响的代码。通常我们用 Tree Shaking 在编译时移除这些 dead code 以减小代码体积。

  • 冗余代码

    代码覆盖率中的概念,适用于运行时,而 Dead code 适用于编译时。Dead code 是任何情况下都不会执行的代码,所以可以在编译阶段将其剔除。冗余代码是某些特定的业务逻辑之下并不会执行到这些代码逻辑(比如:在首屏加载时,某个前端组件完全不会加载,那么对于“首屏”这个业务逻辑用例来讲,该前端代码就是冗余的)。

如何进行合理分包呢?这就需要统计代码覆盖率。代码覆盖率(Code coverage)是软件测试中的一种度量指标。即描述测试过程中(运行时)被执行的源代码占全部源代码的比例。

如何统计代码覆盖率:

1. Chrome 浏览器 Dev Tools

chrome 浏览器的 DevTools 给我们提供了度量页面代码(JS、CSS)覆盖率的工具 Coverage。使用方式:Dev tools —— More tools —— Coverage

由于一般都会对 JS、CSS 资源进行混淆压缩,因此建议导入 Source Map 以便查看源代码的覆盖率。

2. Istanbul(NYC)

Istanbul或者 NYC(New York City,基于 istanbul 实现) 是度量 JavaScript 程序的代码覆盖率工具,目前绝大多数的node代码测试框架使用该工具来获得测试报告,其有四个测量维度:

  • line coverage(行覆盖率):每一行是否都执行了 【一般我们关注这个信息】
  • function coverage(函数覆盖率):每个函数是否都调用了
  • branch coverage(分支覆盖率):是否每个 if 代码块都执行了
  • statement coverage(语句覆盖率):是否每个语句都执行了

缺点:目前使用 istanbul 度量网页前端JS代码覆盖率没有非侵入的方案,采用的是在编译构建时修改构建结果的方式埋入统计代码,再在运行时进行统计展示。

我们可以使用 babel-plugin-istanbul 插件在对源代码在 AST 级别进行包装重写,这种编译方式也叫 代码插桩 / 插桩构建(instrument)。

代码覆盖率在性能优化上的一种可行应用

📒 关于“环境变量”需要注意的问题

1. 为什么使用 cross-env 设置环境变量

有时候我们需要用 npm scripts 设置 Node.js 的环境变量,通常都会使用 cross-env 这个库。其实设置环境变量,在 MacOS 和 linux 系统直接通过 shell 命令就可以了,例如 PORT=8066,但是 Win 设置的方式不太一样,所以 cross-env 实际上是实现了跨平台设置环境变量。

2. .env 文件是如何生效的

可以使用 dotenv 这个库,可以将 .env 文件下的内容加载到 Node.js 的 process.env 对象中,注意 key 和 value 都是 string 类型。

3. 前端项目的环境变量是如何生效的

前端项目的环境变量,实际上不是真正的环境变量,因为浏览器环境下是访问不到 process 对象的,需要通过 DefinePlugin 在打包构建的时候,将变量替换为对应的值。

注意这里有个坑,DefinePlugin 默认直接进行文本替换,如果想要替换为字符串字面量,则需要在字符串中再加一个引号,或者用 JSON.stringify 包裹:

// webpack.config.js
new webpack.DefinePlugin({
__DEV__: "true", // 替换为布尔值
"process.env.NODE_ENV": JSON.stringify("development"), // 替换为字符串字面量
})

// 源码
if (__DEV__) {
// ...
}

if (process.env.NODE_ENV === "development") {
// ...
}

// 替换得到的结果
if (true) {
// ...
}

if ("development" === "development") {
// ...
}

使用 DefinePlugin 遇到的问题

在开发一个组件库,需要区分运行环境,根据环境打包相应的模块代码。根据 Webpack 代码优化(生产环境默认启用)的时候,terser 会做 DCE(无用代码移除)处理,进而优化打包体积:

// 在 Webpack 代码优化的时候
// terser 会识别出“业务2”的代码为无用代码,进而移除掉
// 只保留“业务1”的代码

if (true) {
// 业务 1
}

if (false) {
// 业务 2
}

原先的方式在一个模块中定义常量,然后其他模块引入常量进行判断。这里要注意一个问题,在 Webpack 代码优化的时候,terser 并不会做程序流分析,也就是说访问不到模块的上下文信息。这种情况下,terser 可能还是会将模块导出的常量当做变量处理,从而导致 DCE 失效。这种情况下,我们不能通过模块方式引入常量,而是要用 DefinePlugin 直接把变量替换为对应的字面量。

📒 治理项目模块依赖关系,试试这艘「依赖巡洋舰」

📒 【前端部署十二篇】使用 CI 中的缓存进行 Pipeline 优化

当我们使用 webpack 5 进行构建时,如果使用了 filesystem cache,因为在磁盘中含有缓存 (node_modules/.cache),二次构建往往比一次构建快速十几倍。

而在 CICD 中,这些都失去了意义,因为 CICD 每次 Job 都相当于新建了一个目录,「每次构建都相当于是首次构建」。

但是,CI 提供了一些缓存机制,可以将一些资源进行缓存。如果每次可以将缓存取出来,则大大加速了前端部署的速度。

【前端部署十二篇】使用 CI 中的缓存进行 Pipeline 优化

📒 UMI3源码解析系列之核心service类初始化

📒 【第2610期】JavaScript Containers

📒 【前端部署十一篇】通过 CICD 实践 Lint、Test、Performance 等前端质量保障工程

在 CI 操作保障代码质量的环节中,可确定以下时机:

# 1. 当功能分支代码 push 到远程仓库后,进行 CI
on:
push:
branches:
- 'feature/**'

# 2. 当功能分支代码 push 到远程仓库以及是 Pull Request 后,进行 CI
on:
pull_request:
types:
# 当新建了一个 PR 时
- opened
# 当提交 PR 的分支,未合并前并拥有新的 Commit 时
- synchronize
branches:
- 'feature/**'

CRA 内部使用 ESLint Plugin 进行代码检查,而非命令的方式。当 ESLint 存在问题时,CRA 如果判断当前是 CI 环境,则直接报错并退出进程,导致打包失败:

new ESLintPlugin({
// Plugin options
// ...
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
})

Lint 和 Test 仅是 CI 中最常见的阶段。为了保障我们的前端代码质量,还可以添加以下阶段:

  • Audit: 使用 npm audit 或者 snyk 检查依赖的安全风险
  • Quality: 使用 SonarQube 检查代码质量
  • Container Image: 使用 trivy 扫描容器镜像安全风险
  • End to End: 使用 Playwright 进行 UI 自动化测试
  • Bundle Chunk Size Limit: 使用 size-limit 限制打包体积,打包体积过大则无法通过合并
  • Performance (Lighthouse CI): 使用 lighthouse CI 为每次 PR 通过 Lighthouse 打分,如打分过低则无法通过合并

有些细心并知识面广泛的同学可能注意到了,某些 CI 工作也可在 Git Hooks 完成,确实如此。

它们的最大的区别在于一个是客户端检查,一个是服务端检查。而客户端检查是天生不可信任的。

而针对 git hooks 而言,很容易通过 git commit --no-verify 而跳过。

【前端部署十一篇】通过 CICD 实践 Lint、Test、Performance 等前端质量保障工程

📒 【第2609期】Javascript之迪米特法则

📒 React 并发渲染的前世今生

📒 如何优雅实现轮询

  • 初级:使用定时器(setInterval
  • 中级:使用基于事件循环的递归(setTimeout 递归调用)
  • 高级:使用轮询调度器

📒 npm 包的入口点

注意 exports 字段优先级最高,当提供 exports 字段后,mainmodule 字段会被覆盖。

exports 可以更容易地控制子目录的访问路径,不在 exports 字段中的模块,即使直接访问路径,也无法引用!

工程化知识卡片 014: 发包篇之 package.json 中 main、export、module 的区别何在

http://nodejs.cn/api/packages.html#main-entry-point-export

📒 使用 Next.js 和 MDX 构建你自己的博客

https://www.freecodecamp.org/news/how-to-build-your-own-blog-with-next-js-and-mdx/

📒 React Concurrent 的故事

https://www.youtube.com/watch?v=NZoRlVi3MjQ

⭐️ TCP 重传、滑动窗口、流量控制、拥塞控好难?看完图解就不愁了

⭐️ TCP 就没什么缺陷吗?

📒 React Server Components:我们即将和 API 告别?

- - + + \ No newline at end of file diff --git "a/2022/5\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/5\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 0f9997be92..7d1c447622 100644 --- "a/2022/5\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/5\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月1日内容汇总

· 18 min read
加菲猫

📒 实现一个 Code Pen:(三)10 行代码实现代码格式化

📒 为什么用链表实现队列

很多时候用数组也能实现队列,我们知道数组尾部操作(例如 pushpop)时间复杂度都是 O(1),但如果在数组头部增删元素(例如 shiftunshift),需要移动其他元素的下标,因此时间复杂度为 O(n)

而链表增删元素实际上都是修改指针指向,不需要移动下标,因此时间复杂度都是 O(1)。链表只有查找元素需要遍历,时间复杂度为 O(n),但是队列并不需要查找,而且链表的 size 属性可以在增删操作的时候进行维护,所以用链表实现队列非常合适。

思考题:如何在常数时间内删除数组中的元素。我们知道 splice 删除元素也需要移动其他元素下标,时间复杂度为 O(n),但是在数组尾部操作时间复杂度都是 O(1),因此可以先把要删除的元素交换到数组尾部,然后直接删除尾部元素即可。

📒 写给前端的 K8S 上手指南

📒 Web页面全链路性能优化指南

📒 系统困境与软件复杂度,为什么我们的系统会如此复杂

📒 【第2602期】设置 NPM Registry 的 4 种姿势

📒 前端算法系统练习: 栈和队列篇

📒 怎么解决MySQL死锁问题的

📒 【第2598期】ServiceWorker 缓存与 HTTP 缓存

📒 Monorepo 的过去、现在、和未来

📒 【第2597期】如何用JavaScript实现一门编程语言 - AST

📒 TS 类型体操:索引类型的映射再映射

📒 ESBuild & SWC浅谈: 新一代构建工具

📒 InnoDB原理篇:如何用好索引

我们都知道 InnoDB 索引结构是 B+ 树组织的,但是根据 数据存储形式不同 可以分为两类,分别是 聚簇索引二级索引

其实聚簇索引的本质就是主键索引。因为每张表只能拥有一个主键字段,所以每张表只有一个聚簇索引。另外聚簇索引还有一个特点,表的数据和主键是一起存储的,它的叶子节点存放的是整张表的行数据(树的最后一层),叶子节点又称为数据页。

很简单记住一句话:找到了索引就找到了行数据,那么这个索引就是聚簇索引

知道了聚簇索引,再来看看二级索引是什么,简单概括,除主键索引以外的索引,都是二级索引,像我们平时建立的联合索引、前缀索引、唯一索引等。

二级索引的叶子节点存储的是索引值 + 主键 id。所以二级索引与聚簇索引的区别在于 叶子节点是否存放整行记录

也就意味着,仅仅靠二级索引无法拿到完整行数据,只能拿到 id 信息

假设,我们有一个主键列为 id 的表,表中有字段 kk 上有索引。

我们执行一条主键查询语句 select * from T where id = 100,只需要搜索 id 聚簇索引树就能查询整行数据。

接着再执行一条 select * from T where k = 1,此时要搜索 k 的二级索引树,具体过程如下:

  • k 索引树上找 k = 1 的记录,取得 id = 100
  • 再到聚簇索引树查 id = 100 对应的行数据
  • 回到 k 索引树取下一个值 k = 2,不满足条件,循环结束

上述过程中,回到聚簇索引树搜索的过程,我们称为 回表

也就是说,基于二级索引的查询需要多扫描一棵聚簇索引树,因此在开发中尽量使用主键查询

可是有时候我们确实需要使用二级索引查询,有没有办法避免回表呢?

办法是有的,但需要结合业务场景来使用,比如本次查询只返回 id 值,查询语句可以这样写 select id from T where k = 1,过程如下

  • k 索引树上找 k = 1 的记录,取得 id = 100
  • 返回 id
  • 回到 k 索引树取下一个值 k = 2,不满足条件,循环结束

在这个查询中,索引 k 已经覆盖了我们的查询需求,不需要回表,这个操作称为覆盖索引

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段

假设现在有一个高频的业务场景,根据 k 查询,返回 name,我们可以把 k 索引变更成 kname 的联合索引。

InnoDB原理篇:如何用好索引

InnoDB原理篇:聊聊数据页变成索引这件事

📒 一分钟看懂TCP粘包拆包

TCP 是一个面向「流」的协议,所谓流就是没有界限的一长串二进制数据。在实际的传输过程中,TCP 会根据网络情况将数据包进行拆分或者拼装,如果业务没有定义一个明确的界限规则,在应用层的业务上就会出现粘包拆包的现象。

针对 TCP 粘包拆包的现象,常见的解决思路如下:

  1. 发送端给每个数据包 添加包首部
  2. 发送端将每个数据包 封装为固定长度
  3. 可以在数据包之间 设置边界

为了解决粘包拆包,Netty 框架也提供了很多开箱即用的编解码器,极大简化网络编程解决此类问题的难度。

一分钟看懂TCP粘包拆包

📒 什么是有区分度的好的面试问题,来看看字节跳动这道实现异步 sum 的问题

📒 【前端部署第三篇】通过 docker 学习 nginx 配置,及基于 nginx 部署最简前端项目

📒 使用 CRA 搭建 React + TS 项目

都 2022 年了,手动搭建 React 开发环境很难吗

会写 TypeScript 但你真的会 TS 编译配置吗

用 Redux 做状态管理,真的很简单🦆

「React进阶」react-router v6 通关指南

📒 Usage With TypeScript - Redux Toolkit

https://redux-toolkit.js.org/usage/usage-with-typescript

📒 全局状态和状态管理的区别

全局状态可以很简单,例如只要一个 JS 对象 {} 就可以实现,但是如果尝试修改全局状态的值,无法触发组件更新。

状态管理,除了具有全局状态的功能,还提供了一套发布订阅机制,即状态改变的时候通知对应组件更新。

Redux 本身其实就是全局状态,为了实现状态改变通知组件更新,还需要一个 UI-binding,即 React-redux。

📒 浅谈V8垃圾回收机制

📒 打造 Go 语言最快的排序算法

📒 实现一个 Codepen:(二)在 Next.js 中使用 Monaco Editor

📒 【架构师(第十八篇)】脚手架之项目模板的安装

📒 【前端部署第二篇】基于 docker/compose 部署一个最简单的前端项目

📒 7 段小代码,玩转Java程序常见的崩溃场景

如何排查 CPU 飙升问题,获取问题代码通常可以使用下面的方法:

  1. 使用 top 命令,查找到使用 CPU 最多的某个进程,记录它的 pid。使用 Shift + P 快捷键可以按 CPU 的使用率进行排序
  2. 再次使用 top 命令,加 -H 参数,查看某个进程中使用 CPU 最多的某个线程,记录线程的 ID
  3. 使用 printf 函数,将十进制的 tid 转化成十六进制
  4. 使用 jstack 命令,查看 Java 进程的线程栈
  5. 使用 less 命令查看生成的文件,并查找刚才转化的十六进制 tid,找到发生问题的线程上下文

7 段小代码,玩转Java程序常见的崩溃场景

📒 看完这篇你一定能掌握Linux

📒 ObjectMapper,别再像个二货一样一直new了

📒 [科普] Service Worker 入门指南

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 前端历史项目的 Vite 迁移实践总结

📒 手写 css-modules 来深入理解它的原理

📒 在 Webpack 5 中开启懒编译(Lazy Compilation)

Webpack 5 的实验特性,可以针对多入口(Initial Chunk)和动态加载(Async Chunk)进行懒编译。开启懒编译之后,可以实现按需编译,提升启动速度,若再配合 Webpack 5 持久化缓存,则可以直接秒杀 Vite。

module.exports = {
// …
experiments: {
lazyCompilation: {
imports: true,
entries: true,
},
},
};

由于实验特性具有相对宽松的语义版本,可能会有重大的变更,所以你需要锁定 Webpack 的小版本号,例如 "webpack": "~5.4.3",或者锁定版本号

在 Webpack 5 中开启懒编译(Lazy Compilation)

📒 浅谈文档的实时协同编辑

📒 腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检

首先为什么要有同源策略?浏览器需要记住用户的登录状态(即登录凭证),这样用户下次访问页面就无需重复登录。这样的话,就需要有一些安全策略,否则很容易出现 CSRF 攻击等问题。如果是其他的 http client 则没有同源策略。

CORS策略的心智模型是:所有跨域请求都是不安全的,浏览器要带上来源给服务器检验

同源策略会限制哪些行为:

  • 跨域情况下获取 DOM 元素(例如跨域的 iframe)、localStorage、Cookie 等
  • 跨域情况下发送 ajax 请求,浏览器会拒绝解析响应报文

注意,浏览器默认的表单提交不受同源策略限制

CORS 即跨域资源共享,这里注意 CORS 的目的不是拦截请求,反倒是为了让其能正常请求。CORS 的诞生背景就是同源策略,这是一个相当严苛的规定,它禁止了跨域的AJAX请求。但实际的开发中又有这样的需求,于是开一个口子——只要配置了CORS的对应规则,跨域请求就能正常进行。

如何配置 CORS?前端在发送请求的时候,浏览器会在请求头添加 Origin 字段,这样后端就能知道请求的来源,然后后端在响应头添加 Access-Control-Allow-Origin,这个值就是前端发送的来源地址(或者直接加 * 表示允许所有地址)。

跨域请求的流程,CORS把请求分成简单请求和复杂请求,划分的依据是“是否会产生副作用”。同时满足下面这两个条件的是 简单请求,否则就是 非简单请求

  • 请求方法是 HEAD/GET/POST
  • 请求体的 Conent-Type 只能是 form-urlencodedform-datatext/plain

对于简单请求,流程如下:

  1. 浏览器发起请求,并且自动加上请求的来源 origin 给服务器检查;
  2. 服务器返回数据,并返回检查结果,配置CORS响应头;
  3. 浏览器检查CORS响应头,如果包含了当前的源则放行,反之拦截;

这里需要注意,浏览器是拦截响应,而不是拦截请求,跨域请求是发出去的,并且服务端做了响应,只是浏览器拦截了下来

对于复杂请求,流程如下:

  1. 浏览器发起预检请求,带上请求的来源 origin,不包含请求体;
  2. 服务器返回检查结果,配置CORS头;
  3. 浏览器发起真正请求;
  4. 浏览器返回数据;

浏览器会检查第2步中拿到的CORS头,如果没有包含当前的源,后续的第3、4步都不会进行,也就是不会发起真正请求

为什么只对复杂请求做预检?上文提到,划分简单请求和复杂请求的依据是“是否产生副作用”。这里的副作用指对 数据库做出修改:使用GET请求获取新闻列表,数据库中的记录不会做出改变,而使用PUT请求去修改一条记录,数据库中的记录就发生了改变。

假设网站被CSRF攻击了——黑客网站向银行的服务器发起跨域请求,并且这个银行的安全意识很弱,只要有登录凭证cookie就可以成功响应,考虑下面两种情况:

  • 黑客网站发起一个GET请求,目的是查看受害用户本月的账单。银行的服务器会返回正确的数据,不过影响并不大,而且由于浏览器的拦截,最后黑客也没有拿到这份数据;
  • 黑客网站发起一个PUT请求,目的是把受害用户的账户余额清零。浏览器会首先做一次预检,发现收到的响应并没有带上CORS响应头,于是真正的PUT请求不会发出;

幸好有预检机制,否则PUT请求一旦发出,黑客的攻击就成功了。

这种情况下,后端也需要遵循 RESTful 规范,否则要么面临攻击风险,要么会多发一次预检请求

腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检

腾讯三面:Cookie的SameSite了解吧,那SameParty呢

📒 Axios 三个优点

  • Promisify
  • 责任链(拦截器机制)
  • 适配器(同时支持浏览器和 node 环境)

📒 深入理解 Promise 之手把手教你写一版

📒 2022 年 JavaScript 开发工具的生态

📒 自动化生成骨架屏的技术方案设计与落地

- - + + \ No newline at end of file diff --git "a/2022/5\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/5\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 53056ced0b..b7b4dc7cae 100644 --- "a/2022/5\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/5\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月22日内容汇总

· 10 min read
加菲猫

📒 PNPM 源码结构 - 前端包管理工具具有哪些功能

首先 pnpm 整个项目的主入口包文件为 packages/pnpm 这个包里面,这个包名称也直接叫做 pnpm ,其中 main.ts 文件是其入口文件,这个文件会处理掉用户传进来的一些参数,然后根据处理后的不同的参数对各命令做一个下发执行工作,下发后的命令参数再到各个包里面去,从而执行里面对应的逻辑。

处理参数用到的包为 @pnpm/parse-cli-args ,它会接收到用户传递进来的命令行参数,然后将其处理成一个 pnpm 内部的统一格式,例如用户输入如下命令:

$ pnpm add -D axios

这里传进来的一些参数都会被 parseCliArgs 这个方法处理:

例如 add 会被处理给 cmd 字段,一些裸的参数例如 axios 会被放进 cliParams 这个数组中,-D 这个参数在 cliOptions 里面去。处理后的这些变量以及参数用于主入口文件后续代码执行逻辑的判断。具体的判断逻辑可以在调试的时候遇到了,再去看对应的入口逻辑判断调试即可,这里不做具体的介绍。

main.ts 中会通过调用当前包下面的 cmd 目录下面的方法(pnpmCmds),来完成各命令的分发。

  • 依赖管理:如果 cmd 值为 addinstallupdate 等这些涉及和依赖安装相关的包,则会走 @pnpm/plugin-commands-installation 这个包里面对应的子命令逻辑(基本上 pnpm 所有的核心模块都围绕依赖安装这一块展开)
  • 打包发布:如果 cmd 值为 packpublish 这一类涉及到打包发布的包,则会走 @pnpm/plugin-commands-publishing 这个包的逻辑
  • 命令执行:如果 cmd 值为 runexecdlx 等这些和命令执行相关的方法,则会走 @pnpm/plugin-commands-script-runners 这个包的逻辑

📒 学习 swr 获取数据的思路

最近遇到很多列表渲染的场景,例如根据筛选项和分页参数获取列表数据。在代码中看到虽然用了 React Hooks,但是获取数据依旧是 jQuery 时代的 命令式 写法。

我们知道,前端框架都是数据驱动、声明式渲染的,即渲染视图不需要命令式地操作 DOM,而是声明式地修改数据就行。因此,获取数据也可以使用 声明式 写法,这样代码更容易维护。

import useSWR from 'swr'

function Profile() {
const { data, error } = useSWR('/api/user', fetcher)

if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}

https://swr.vercel.app/docs/getting-started

📒 【第2618期】手把手教你定制一套适合团队的微前端体系

📒 Vite 相关 issue 梳理

https://github.com/vitejs/vite/discussions/8232

📒 Chrome debugger 小技巧

在 Chrome 浏览器中打断点调试,此时切到控制台,可以访问断点位置上下文信息,也就是说可以访问、甚至修改变量。

⭐️ 前端必学的动画实现思路,高逼格的效果老板看了都会大声称赞

📒 【第2617期】React 组件库 CSS 样式方案分析

📒 【第2616期】解释JavaScript的内存管理

📒 UMI3源码解析系列之插件化架构核心

插件机制实现的方式:

  • umi:基于 tapable 的发布订阅模式,在路由、生成文件、构建打包、HTML 操作、命令等方面提供能力
  • babel:基于 visitor 的访问者模式,对于 AST 的操作等
  • rollup:基于 hook 的回调模式,定制构建和打包阶段的能力
  • webpack:基于 tapable 的发布订阅模式,loader 不能实现的都靠它
  • vue-cli:基于 hook 的回调模式,在生成项目、项目运行和 vue ui 阶段提供能力

UMI3源码解析系列之插件化架构核心

📒 写了一个基于 MacOS + iTerm2 自动执行化执行工具

📒 介绍全新的 JSX 转换

由于浏览器无法识别 JSX 语法,所以我们需要通过 Babel、TypeScript 等工具将 JSX 编译为浏览器能识别的 render 函数。在 React 17 之前,JSX 会转换为 React.createElement(...) 调用:

import React from 'react';

function App() {
return React.createElement('h1', null, 'Hello world');
}

正是因为 JSX 会转换为 React.createElement(...),所以每个组件顶部必须导入 React

在 React 17 版本,React 的 package 中引入了两个新入口,这些入口只会被 Babel 和 TypeScript 等编译器使用。新的 JSX 转换不会将 JSX 转换为 React.createElement,而是自动从 React 的 package 中引入新的入口函数并调用。下方是新 JSX 被转换编译后的结果:

// 由编译器引入(禁止自己引入!)
import { jsx as _jsx } from 'react/jsx-runtime';

function App() {
return _jsx('h1', { children: 'Hello world' });
}

注意,此时源代码无需引入 React 即可使用 JSX 了!(但是如果使用 React 提供的 Hook 或其他导出,这种情况下仍需引入 React)

新的 JSX 转换对应的配置是 runtime: "automatic"

// babel.config.js

module.exports = {
presets: [
[
"@babel/preset-react",
{
// 新的 JSX 转换 -> automatic
// 旧的 JSX 转换 -> classic
runtime: "automatic"
}
]
]
}
tip

可以直接在 Babel Playground 看编译结果:

https://babeljs.io/repl

官方文档表示,新的 JSX 转换会略微优化包体积,个人认为优化还是比较有限。虽说 React.createElement() 变成了更短的调用,但是又多出来一段运行时代码。

https://react.docschina.org/blog/2020/09/22/introducing-the-new-jsx-transform.html

📒 从 Turborepo 看 Monorepo 工具的任务编排能力

📒 大牛书单 | 学习 Golang 资料

📒 解决前端常见问题:竞态条件

📒 React Router v6 新手指南

https://www.youtube.com/watch?v=59IXY5IDrBA

📒 [调研报告] 新一代前端构建工具汇总

📒 Google 最新的性能优化方案,LCP 提升30%!

📒 React useEvent:砖家说的没问题

useEvent 会将一个函数「持久化」,同时可以保证函数内部的变量引用永远是最新的。如果你用过 ahooks 的 useMemoizedFn,实现的效果是几乎一致的。再强调下 useEvent 的两个特性:

  • 函数地址永远是不变的
  • 函数内引用的变量永远是最新的

通过 useEvent 代替 useCallback 后,不用写 deps 函数了,并且函数地址永远是固定的,内部的 state 变量也永远是最新的。

useEvent 的实现原理比较简单:

function useEvent(handler) {
const handlerRef = useRef(null);

// 用于确保函数内引用的变量永远是最新的
useLayoutEffect(() => {
handlerRef.current = handler;
});

// 用于确保返回的函数地址永远不变
return useCallback((...args) => {
const fn = handlerRef.current;
return fn(...args);
}, []);
}

React useEvent:砖家说的没问题

📒 为什么用 Vite 打包 React 组件库

  • 生产环境 rollup 打包 + 开发环境 devServer
  • 开发环境可以通过 @vitejs/plugin-react 插件支持 fast-refresh
  • 生产环境默认使用 esbuild 代码压缩,效率是 terser 的 20-40 倍
  • esbuild 在语法转换这块尚不完善,但是组件库打包不用考虑兼容性问题,兼容性问题交给业务项目解决
  • Vite 提供了很多 esbuild 尚不支持的特性(例如 CSS 模块化等)
  • 开发环境和生产环境几乎可以复用一套配置(Vite 抹平了 esbulid 和 rollup 配置差异)
- - + + \ No newline at end of file diff --git "a/2022/5\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/5\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 15c8d8efa5..22c1c6f91b 100644 --- "a/2022/5\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/5\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月29日内容汇总

· 11 min read
加菲猫

📒 如何将数组转为对象

之前在业务中遇到一个场景,配置 Webpack alias 的时候,会出现很多模板代码:

module.exports = {
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"@foo": path.resolve(__dirname, "src/foo"),
"@bar": path.resolve(__dirname, "src/bar"),
}
}
}

那么其实是可以通过数组的方式干掉模板代码:

function constructAlias(arr: string[]): Record<string, string> {
return Object.fromEntries(
arr.map(item => [
item,
path.resolve(cwd, item.replace(/^\@(.*?)$/, '$1'))
])
);
}

const config = ['@', '@foo', '@bar'];

const res = constructAlias(config);
console.log(res);

使用数组的 map 方法映射出一个 entry 数组,可以表示为形如 [key, value][] 的结构,然后使用 Object.fromEntries 将 entry 数组转为对象

这里需要注意,Object.fromEntries 是 ES2019 语法,支持 Chrome >= 73 和 Node.js >= 12.0.0。浏览器环境问题不大,一般都会配置 Babel polyfill 兼容,但是 Node.js 环境就会出一些问题,例如一些 CI 环境的 Node.js 版本很老,就会报错进而导致构建失败。因此通常开发的话,我们应该尽量用数组的 reduce 替代:

function constructAlias(arr: string[]): Record<string, string> {
return arr.reduce((accu, cur) => {
accu[cur] = path.resolve(cwd, cur.replace(/^\@(.*?)$/, '$1'));
return accu;
}, {});
}

📒 An introductory guide to Contiuous Integration and Delivery/Deployment (CI/CD) for Frontend Developers

https://blog.tegadev.xyz/an-introductory-guide-to-ci-cd-for-frontend-developers

📒 基于设计稿识别的可视化低代码系统实践

📒 被diss性能差,Dan连夜优化React新文档

📒 Node.js 调试一路走来经历了什么

📒 如何解决组件库打包条件引入

由于 import 语句必须放在顶层,不能放在条件判断中。如果同时保留两个 import 语句则会导致两个包都被打包进去。所以解决的方案就是在构建阶段动态修改 import 语句,但是需要注意两个问题:

  • 要注意修改时机,假如打包工具依赖分析已经完成,这时候再修改就太迟了
  • 另外还要注意不同打包工具的兼容性,如果开发 rollup 插件,可能导致 webpack、vite 等工具不兼容

因此选择开发 babel 插件,可以兼容各种打包工具。

📒 UMI3源码解析系列之运行时插件机制

📒 推荐一个前端技术选型神器

📒 Webpack 模块构建缓存

模块构建缓存,推荐使用 Webpack5 的 filesystem cache,技术更成熟,可以参考 CRA 的 Webpack 配置:

module.exports = {
cache: {
type: 'filesystem',
version: createEnvironmentHash(env.raw),
cacheDirectory: paths.appWebpackCache,
store: 'pack',
buildDependencies: {
defaultWebpack: ['webpack/lib/'],
config: [__filename],
tsconfig: [paths.appTsConfig, paths.appJsConfig].filter(f =>
fs.existsSync(f)
),
},
},
}

关于持久化缓存,有两个地方需要注意:

  • 默认缓存的路径是 node_modules/.cache/webpack,也就是说,只要删除 node_modules,相当于缓存也被清空了
  • 本地和 CI 环境的缓存是相互独立的,本地的缓存无法在 CI 环境使用。在 CI 环境中需要使用 CI 的缓存机制

https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js

📒 最高性能的包管理器-pnpm

📒 【第2624期】Fastify 如何实现更快的 JSON 序列化

📒 如何设置 npm 私有源

在项目根目录建一个 .yarnrc 文件,配置如下:

# 淘宝源
registry=https://registry.npmmirror.com
# 私有源
@myscope:registry=https://mycustomregistry.example.org

这样的话,package.json 中带有 @myscope 前缀的依赖,例如 @myscope/design-system 都会从私有源下载。

📒 前端多线程编程探索

📒 精妙的配合!文字轮播与图片轮播?CSS 不在话下

📒 并发渲染优化:让文件树的渲染又快又稳

📒 UMI3源码解析系列之构建原理

⭐️ 看了9个开源的 Vue3 组件库,发现了这些前端的流行趋势

对包管理器的总结非常好,推荐看一下。

npm@v3 之前

  • 嵌套结构(nest),会出现大量重复装包的问题
  • 因为是树型结构,node_modules 嵌套层级过深,导致文件路径过长
  • 模块实例不能共享,例如在两个不同包引入的 React 不是同一个模块实例

npm@v3 / yarn

  • 分身依赖:npm@v3 使用扁平化(flat)的方式安装依赖,一定程度上解决了重复装包的问题,但是注意并没有完全解决,例如 A 和 B 依赖了不同版本的 C,会导致 C 被安装两次
  • 幽灵依赖:由于使用扁平化方式安装,package.json 里并没有写入的包竟然也可以在项目中使用了
  • 平铺减少安装没有减省时间,因为扁平化算法比较复杂,时间居然还增加了

npm@v5 / yarn

该版本引入了一个 lock 文件,以解决 node_modules 安装中的不确定因素。这使得无论你安装多少次,都能有一个一样结构的node_modules

然而,平铺式的算法的复杂性,幽灵依赖之类的问题还是没有解决。

看了9个开源的 Vue3 组件库,发现了这些前端的流行趋势

📒 Node.js Web 框架 Midway 入门实战

📒 肝了一个月的 DDD,一文带你掌握

📒 使用 rollup 构建第三方库包括哪些过程

  • 浏览器不兼容的语法转换
    • Vue 文件处理:rollup-plugin-vue
    • JSX、TS 语法编译:rollup-plugin-babel
    • 支持 CSS 加载、添加前缀、压缩、scss/less 预编译:rollup-plugin-postcss
  • 编译兼容
    • 仅限语法转换,不建议 polyfill:rollup-plugin-babel
  • 混淆压缩
    • 对应:rollup-plugin-terser
  • 打包为一份文件(注意 peerDependencies 外部化),多种打包格式,生成类型声明文件等
  • 工程质量保障,例如 ESLint、TS 类型检查、单元测试等
tip

前面两步可以避免业务项目的 babel-loader 处理 node_modules 下的模块,提升构建效率。

📒 如何实现主题切换

关键看场景,如果需要在运行环境动态切换,就需要打包两套样式,然后通过媒体查询之类的方式进行切换。如果不需要动态切换,可以在构建的时候进行变量注入。

自己开发的组件库是否有必要设置主题?样式都不打包,less 变量注入肯定没用的;如果搞个 theme-reset.less,肯定会污染到全局。最好还是在业务工程里面设置主题。

📒 如何做首屏性能优化

1. 路由懒加载

首先想到的就是解决资源冗余问题,我们可以按需投喂 JS 资源,只把渲染当前页面需要的资源投喂给浏览器,对应的方案是路由懒加载。

2. 分包优化

在按需投喂 JS 资源的基础上,对于一些不需频繁修改、体积又很大的依赖进行拆包处理,例如 reactreact-dom,单独分包设置强缓存。

3. 服务端渲染

如果按需投喂 JS 资源还是太慢,可以考虑服务端渲染(SSR),在服务端直接把当前页面的 HTML 丢给浏览器,可以理解为按需投喂 HTML 页面。

4. 静态生成 && 混合渲染

服务端渲染可以理解为在服务端调接口渲染出 HTML 丢给浏览器,但是这个过程还是存在性能开销。对于一些不需要动态数据的页面,例如文档、博客等,可以考虑静态生成(SSG),即在构建的时候就渲染出 HTML,可以极大提升首屏性能,当然更多时候是 SSG 和 SSR 混合渲染。

📒 深入理解 Linux CPU 上下文切换

📒 中后台 CSS Modules 最佳实践

📒 在 React 中实现条件渲染的 7 种方法

⭐️ 2022年值得使用的 Node.js 框架

📒 解决 Vite 无法全局启用 css module 的问题

在这里打个断点看看:

packages/vite/src/node/plugins/css.ts:688
const {
modules: modulesOptions,
preprocessorOptions,
devSourcemap
} = config.css || {}
const isModule = modulesOptions !== false && cssModuleRE.test(id)

📒 useRef 在列表渲染场景需要特别注意

在列表渲染的时候,不能对列表的每一项使用 ref,否则会出现 bug。这种情况下,应该将列表的每一项封装为组件,在组件内部使用 ref

type IProps = {
questionList: string[];
}

const App: React.FC<IProps> = ({ questionList }) => {
const ref = React.useRef();

return (
<>
{questionList.map((item, index) => (
<div
classNames="list-item"
key={index}
ref={ref}
>
{item}
</div>
))}
</>
)
}

📒 100 行代码实现 React 路由

https://github.com/ashok-khanna/react-snippets/blob/main/Router.js

精读《react-snippets - Router 源码》

📒 如何实现多行文本省略

这个功能不需要自己实现,自己实现还可能存在兼容性问题。只需要使用 antd 的 Typography 组件就可以了:

import * as React from "react";
import { Typography } from "antd";

const { Paragraph } = Typography;

const App: React.FC<{}> = () => {
return (
<Paragraph
ellipsis={{ rows: 2, expandable: true, symbol: 'more' }}
>
...
</Paragraph>
)
}

📒 HTTP 的缓存为什么这么设计

📒 vscode插件原理浅析与实战

- - + + \ No newline at end of file diff --git "a/2022/5\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/5\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e4f406aeae..fbc05bc3f5 100644 --- "a/2022/5\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/5\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月8日内容汇总

· 16 min read
加菲猫

📒 从零开始构建 JavaScript Bundler

Jest 作者的最新系列文章,并且配套视频,内容绝对硬核。

https://cpojer.net/posts/building-a-javascript-bundler

📒 JavaScript 框架的四个时代

这篇文章作者以自身多年的开发经历还原了 JavaScript 框架的发展历程,并划分出了四个时代。

  • 远古时代:无框架
  • 框架初期:Backbone.js、Angular 1、Knockout.js、SproutCore、Ember.js、Meteor.js
  • 以组件为中心的时代:React.js、Vue.js、Svelte、Polymer.js
  • 全栈框架:Next.js、Nuxt.js、Remix、SvelteKit、Gastby 和 Astro

https://www.pzuraq.com/blog/four-eras-of-javascript-frameworks

📒 pnpm v7.0.0

pnpm 发布了 v7.0.0,带来了大量的更新。如:不再支持 Node.js 12、pnpm run <script> 脚本名称后的所有命令行参数都会传递给 argv 等等。

https://github.com/pnpm/pnpm/releases/tag/v7.0.0

⭐️ 2022 年的前端行业,咋样啦

ESR(Edge Side Rendering,边缘渲染)是最近的一大热门趋势,可以直接在 CDN 级别实现按需渲染。Nuxt 3、Remix 以及 Sveltekit 等框架都在朝着这个方向发展,目测会在未来的一到两年会成为一大焦点。

2022 年的前端行业,咋样啦

📒 docker-node - Node.js 官方 Docker 镜像

📒 JS 新的日期 API:Temporal

这项特性提案时间为 2021 年 7 月,不到一年的时间已经进展到 stage-3 阶段,目前组委会已经在在做它的功能实现,有望在下个版本推出。

tip

该项提案的初衷来自这篇文章,因为 JavaScript 最初关于日期的实现是照搬的 Java 方案,但由于各种限制和问题,Java 早在 1997 年就实现 Calendar 做了功能改进,而 JavaScript 时至今日用的还是老旧方案,改进优化实在是迫在眉睫。

https://maggiepint.com/2017/04/09/fixing-javascript-date-getting-started/

官方文档(打开控制台就可以体验 Polyfill):

https://tc39.es/proposal-temporal/docs/

或者在 RunKit 上体验(浏览器端运行 node 模块):

https://npm.runkit.com/proposal-temporal

📒 【工程化】探索webpack5中的Module Federation

📒 我们如何使用 Webpack 将启动时间减少 80%

📒 React官方团队出手,补齐原生Hook短板

📒 你可能并没有理解的 babel 配置的原理

📒 前端抢饭碗系列之Docker进阶部署

📒 前端抢饭碗系列之初识Docker容器化部署

📒 从零开始发布自己的NPM包

⭐️ Umi 4 特性合集,比 Vite 还要快?

📒 HTTP分块传输 如何在 React18 中应用

📒 下集」React性能优化,你需要知道的一切

📒 htmlparser2 8.0:快速且高容错的 HTML 和 XML 解析器

https://github.com/fb55/htmlparser2

📒 Node v18 test 模块

注意 Node v18 test 模块是第一个 Prefix-Only Core Modules,也就是说加载该模块必须带上 node: 前缀:

import test from 'node:test';  // Uses the node: prefix. Loads from core.
import assert from 'assert'; // Does not use the node: prefix. Loads from core.
tip

假如没有带上 node: 前缀,则会尝试从用户空间加载 test 模块。但是对于 Node 其他内置模块来说,加不加 node: 前缀都是一样的。

https://fusebit.io/blog/node-18-prefix-only-modules/

📒 Node v16.15.0 (LTS) 发布

现在 Node v16 可以使用实验性支持的 Fetch API 了

https://nodejs.org/en/blog/release/v16.15.0/

📒 升级到 React 18 所对应的 TypeScript 类型定义的改动

https://blog.logrocket.com/upgrading-react-18-typescript/

📒 如何理解 React Hooks 的闭包陷阱

函数组件更新,实际上就是函数重新执行,生成一个新的执行上下文,所有变量、函数重新创建,hooks 重新执行。

一般来说,当函数执行完毕,内部的变量就会销毁、被垃圾回收机制回收。当然也有例外情况,在下面的代码中,函数 baz 依赖了 bar 内部的变量 a,并且 baz 作为返回值传递给了 foo,因此 a 并不会被垃圾回收机制回收,而是会作为闭包缓存下来。只要 foo 的引用不解除,a 就会一直缓存:

function bar() {
const a = 1;
return function baz() {
console.log(a);
}
}

const foo = bar();

再来看这个场景:useEffect 的回调函数依赖了 state 变量,而我们知道这个回调函数在下次 rerender 之前都是缓存在 fiber 节点上的,这样一来就创建了闭包,即使函数组件已经执行完毕,但是 state 变量仍会被缓存下来。

当组件更新的时候,会生成一个新的执行上下文,state 变量也会重新生成,但是 useEffect 回调函数仍然引用了旧的闭包。但是为什么 useEffect 依赖项变化、回调函数执行的时候,总是可以获取到新的值呢?这是因为每次函数组件重新渲染,useEffect 都会重新执行,回调函数也会重新生成(但不一定都会执行),在 updateEffectImpl 内部用重新生成的函数替换了 fiber 节点缓存的函数,这样一来,回调函数执行的时候,始终都能获取到最新的值了。

你可能会觉得这样没什么问题,但是如果在 useEffect 中使用定时器,大概率都会遇到闭包陷阱。

另一个会遇到闭包陷阱的是 useCallback。很多同学觉得 useCallback 依赖项似乎没什么用,习惯性传递空数组,这就会导致函数一直被缓存,假如内部依赖了 state 变量,则始终会缓存旧的闭包。正确做法应该是把 state 变量添加到依赖项数组中,在 state 改变的时候重新生成函数,这样就可以获取到最新的值。

tip

函数组件 rerender 过程中,缓存状态的 fiber 节点(相当于组件实例)并不会销毁,但函数组件是重新执行了,会生成一个新的上下文环境,如果 useEffect 回调依赖了 state 变量,则会一直缓存旧的闭包。所以要避免闭包陷阱,只需要 保证每次渲染的时候,函数都重新生成 就行。

📒 TypeScript 小技巧:常量断言

在讲常量断言之前,先提一下,TS 会区别对待可修改和不可修改的值的类型推断:

// 推断成单值类型 'dbydm'
const immutable = 'dbydm';

// 推断成通用的 string 类型
let mutable = 'dn';

// 由于对象的属性都具有可修改性,TS 都会对它们「从宽」类型推断
// 例如下面的 prop 的类型被推断为 string
const obj = { prop: 'foo' }

再来看下面的代码,例如我们实现了一个用 ref 维护状态的 hook:

import * as React from "react";

const useRenderlessState = <T>(initialState: T) => {
const stateRef = React.useRef(initialState);

const setState = (nextState: T) => stateRef.current = nextState;

return [stateRef.current, setState];
}

此时我们会发现上面 hook 的返回值的类型被推导成了如下的数组类型:

(T | ((nextState: T) => T))[]

这就导致我们在使用的时候无法对它进行准确的解构:

const [value, setValue] = useRenderlessState(0);

一般来说我们可以 显示声明返回类型 或者 对返回值做类型断言,告诉 TS 返回值类型是元组而不是数组:

// 显示声明返回类型
const useRenderlessState = <T>(initialState: T): [T, (nextValue: T) => T] => {/*...*/}

// 对返回值对类型断言
const useRenderlessState = <T>(initialState: T) => {
// ...
return [state, setState] as [typeof value, typeof setValue];
}

上面的两种写法都各有冗余成分,算不上优雅。

其实从语义层面来分析,TS 之所以没能将返回值推断为元组类型是因为它认为该返回值仍有可能被 push 值,被修改。所以我们真正需要做的是告诉 TS,这个返回值是一个 final,其本身和属性都是不可篡改的,而这正是常量断言所做的事。

常量断言可以把一个值标记为一个不可篡改的常量,从而让 TS 以最严格的策略来进行类型推断:

const useRenderlessState = <T>(initialState: T) => {
// ...
return [state, setState] as const
}

这下 useRenderlessState 的返回类型就被推断成了如下的 readonly 值:

readonly [T, (nextState: T) => T]
tip

as const 与 ES6 const 常量声明的区别:

  • const 常量声明是 ES6 的语法,对 TS 而言,它只能反映该常量本身是不可被重新赋值的,它的子属性仍然可以被修改,故 TS 只会对它们做松散的类型推断
  • as const 是 TS 的语法,它告诉 TS 它所断言的值以及该值的所有层级的子属性都是不可篡改的,故对每一级子属性都会做最严格的类型推断(所有的字面量都会被推断为单值类型)

常量断言可以让我们不需要 enum 关键字就能定义枚举对象:

const EnvEnum = {
DEV: "development",
PROD: "production",
TEST: "test",
} as const;

TypeScript 夜点心:常量断言

📒 了解 Symbol.toStringTag 的用法吗

Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的值是字符串类型,用来表示该对象的自定义类型标签。通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。

const foo = {};
const bar = {
[Symbol.toStringTag]: "测试内容"
}

foo.toString(); // '[object Object]'
bar.toString(); // '[object 测试内容]'

Symbol.toStringTag - MDN 文档

📒 函数组合中的 composeflowpipe

compose 实现如下,注意调用顺序是反过来的:

const compose = (...fns) => x0 => fns.reduceRight(
(x, f) => f(x),
x0
);

// 接受参数后,返回一个待执行函数
// 需要再接受一个初始值才开始执行
const processComment = compose(
linkify,
imagify,
emphasize,
headalize
);

flow 实现如下,注意这里调用顺序是从左到右:

const flow = (...fns) => x0 => fns.reduce(
(x, f) => f(x),
x0
);

// 注意这里仍然是返回一个待执行函数
const processComment = flow(
headalize,
emphasize,
imagify,
linkify,
codify
);

pipe 实现如下,调用顺序也是从左到右:

// 注意 pipe 直接执行所有的函数,返回一个值
// 而 flow 返回一个待执行函数,需要再接受一个初始值才开始执行
const pipe = (x0, ...fns) => fns.reduce(
(x, f) => f(x),
x0
);

const map = f => arr => arr.map(f);
const filter = p => arr => arr.filter(p);
const take = n => arr => arr.slice(0, n);
const join = s => arr => arr.join(s);

const comments = pipe(commentStrs,
filter(noNazi),
take(10),
map(emphasize),
map(itemize),
join('\n'),
);

什么是 JavaScript 的函数组合

📒 基于依赖倒置原则实现插件机制

依赖倒置原则(DIP)

核心思想:依赖一个抽象的服务接口,而不是去依赖一个具体的服务执行者,从依赖具体实现转向到依赖抽象接口,倒置过来

例如在 Webpack 中包含一套插件机制:

module.exports = {
// ...
plugins: [
new WebpackBar(),
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css',
chunkFilename: '[id].css'
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, '../public/index.html'),
title: "React App",
filename: "index.html",
})
]
}

Webpack 插件需要实现一个统一的接口,即:

interface IPlugin {
apply(compiler: ICompiler): void;
}

class MyPlugin implements IPlugin {
constructor() {
// 构造器可以在初始化的时候接受配置参数
}

@Override
apply(compiler) {
// ...
}
}

这样 Webpack 只需要遍历 plugins 数组,顺次调用每个插件上的 apply 方法,传入 compiler 对象即可:

plugins.forEach(plugin => plugin.apply(compiler));

顺便提一下,有同学会问,为啥插件要写成 class 的形式,直接用一个对象可以吗,例如:

const MyPlugin = {
apply(compiler) {
// ...
}
}

直接用一个对象也是可以的,但是用 class 显然更灵活,可以在初始化的时候接受配置参数

📒 浏览器 JavaScript 和 Node.js 的区别

  • API 区别:浏览器 JavaScript 是面向浏览器编程,调用浏览器的 API,例如 documentwindow。而 Node.js 是面向操作系统编程,没有浏览器 API,相反可以调用 Node 提供的标准库,与操作系统进行交互
  • 运行环境区别:浏览器 JavaScript 的特殊性(JS 代码需要经过网络请求,在客户端下载并执行),因此无法选择运行环境,需要考虑语法、API 兼容性问题,需要使用 Babel 处理。而 Node.js 通常在本地开发环境、CI 环境、服务端运行,可以控制运行环境,无需考虑兼容性问题
  • 模块规范区别:浏览器原本没有模块机制,但可以自行实现模块命名空间机制(例如 browserifywebpack),从 Chrome 61 开始支持 <script type="module">,即浏览器原生支持 import 命令加载模块(需要注意这种方式也是要经过网络请求)。而 Node.js 自带了一套 CommonJS 模块机制,在 Node 14 之后支持 ES Module 规范(注意 CommonJS 仍然是默认启用的模块规范)
- - + + \ No newline at end of file diff --git "a/2022/6\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/6\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 59c1d17de6..91ebb9db77 100644 --- "a/2022/6\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/6\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月12日内容汇总

· 6 min read
加菲猫

📒 【第2638期】前端安全之 CSRF 攻击原理和防护方法

📒 何时发起 fetch 请求?试试在 React Router 中吧

这是一则近期在 Reactathon 中的演讲。Remix 创始人之一的 Ryan Florence 极力推荐了在 React Router 中去做 fetch 请求。

https://www.youtube.com/watch?v=95B8mnhzoCM

📒 React Route v6.4 版本已进入预发布阶段

https://github.com/remix-run/react-router/releases/tag/v6.4.0-pre.2

📒 最新一期的 20minJS 请来了 Mark Erikson,主要讨论了 状态管理以及 Redux Toolkit

https://podcast.20minjs.com/1952066/10665172-episode-12-redux-toolkit-and-state-management-in-react-with-mark-erikson

📒 Storybook v6.5 版发布:旨在提升生产力的新工作流

这款流行的组件开发工具库本次发布了许多新功能,包括在浏览器中验证用户行为的交互测试,一个将 story 和 variant 连结起来的 Figma 插件以及引入了 Webpack 5 的惰性编译用来提高启动速度等。

https://storybook.js.org/blog/storybook-6-5/

📒 Glide Data Grid v4.0 版发布:一款高效的 React 数据网格库

它自称是一款“毫不妥协,速度飞快的数据网格”。它支持高达百万条数据的多样化渲染,且支持 TypeScript。主页上还有一个简洁的 Demo,它支持 MIT 许可证。详情请看 GitHub 仓库。

https://grid.glideapps.com/

📒 开发一个浏览器插件从未如此简单

📒 深入浅出 npm & yarn & pnpm 包管理机制

📒 pkg.land:发现 npm 包的替代品的方式

https://pkg.land/

📒 平时的工作如何体现一个人的技术深度?

📒 关于前端大管家 package.json,你知道多少?

📒 【第2636期】从"微前端"到“微模块”

📒 你还在直接用 localStorage 么?该提升下逼格了

📒 ahooks 中那些控制“时机”的hook都是怎么实现的?

📒 实现一个实时预览的 json 编辑器组件(react 版)

📒 微信团队分享:微信后台在海量并发请求下是如何做到不崩溃的

📒 使用 -force 被认为是有害的;了解 Git 的 -force-with-lease 命令

📒 使用 Three.js 实现"雪糕"地球,让地球也凉爽一夏

📒 从0到1带你用webpack 5构建monorepo项目——上篇

📒 content-visibility 再探究,完美替代 Lazyload?

直接看结论:

  • 在一些需要被频繁切换显示、隐藏状态的元素上,使用 content-visibility: hidden,用户代理无需重头开始渲染它和它的子元素,能有效地提升切换时的渲染性能;
  • content-visibility: auto 的作用更加类似于虚拟列表,使用它能极大地提升长列表、长文本页面的渲染性能;
  • 合理使用 contain-intrinsic-size 预估设置了 content-visibility: auto 元素的高宽,可以有效避免滚动条在滚动过程中的抖动;
  • content-visibility: auto 无法直接替代 LazyLoad,设置了 content-visibility: auto 的元素在可视区外只是未被渲染,但是其中的静态资源仍旧会在页面初始化的时候被全部加载;
  • 即便存在设置了 content-visibility: auto 的未被渲染的元素,也并不会影响全局的搜索功能。

content-visibility 再探究,完美替代 Lazyload?

📒 冷知识!使用 display: contents 实现幽灵节点?

📒 基于 Vue3 和 TypeScript 项目大量实践后的思考

📒 ahooks 是怎么解决用户多次提交问题?

📒 这还是我最熟悉的package.json吗?

📒 npm init @vitejs/app的背后,仅是npm CLI的冰山一角

📒 不到 100 行代码,实现 React Router 核心逻辑

📒 ahooks 是怎么解决 React 的闭包问题的?

📒 如何使用插件化机制优雅的封装你的请求hook

📒 【第2633期】JavaScript运行时环境和标准

📒 TS 的 esModuleInterop 与 allowSyntheticDefaultImports 配置

📒 NPM 发包脚本加上下面这段代码

const npmPublish = async () => {
const scripts = [
"npm set-script postinstall \"\"",
"npm publish",
"npm set-script postinstall \"patch-package\"",
];
await scripts.reduce(
(prev, script) => prev.then(() => runScript(script)),
Promise.resolve()
);
}

这里的 reduce() 确保了 Promise 按顺序调用,而 Promise.all() 并发执行不保证顺序

📒 【第2632期】微前端框架 Satum 的性能优化策略

📒 大家都能看得懂的源码(一)ahooks 整体架构篇

📒 React新文档:不要滥用effect哦

📒 你还不会写 vite 插件吗?没关系,我教你啊

📒 用 Node.js 手写一个 DNS 服务器

- - + + \ No newline at end of file diff --git "a/2022/6\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/6\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 52656ae0b9..a4276dd944 100644 --- "a/2022/6\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/6\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月19日内容汇总

· 6 min read
加菲猫

📒 组件库开发新工具 Histoire

Vue 核心团队成员开发,底层基于 Vite,目测比 dumi 好用:

https://github.com/histoire-dev/histoire

📒 如何做好一个技术分享

最近有同事做了技术分享,发现了一些问题,在这里总结一下。

做技术分享也跟写文章一样,是有条理的,例如:

  • 先讲项目背景,现有方案存在哪些痛点(重点,技术不能为了用而用)
  • 然后再讲讲怎么做技术选型的,有哪些竞品,各自优缺点,可以简单介绍实现原理(有自己的思考,而不是上级让你做 xx 预研就直接做了)
  • 再讲团队中是如何落地的,实践过程中遇到哪些问题,是如何解决的,存量工程迁移方案(重点,节省其他同事的时间,避免重复踩坑)
  • 最后可以总结一下,该方案落地相比现有方案提升的点,此外还存在哪些问题,在选型的时候需要重点考虑

需要避免的几个点:

  • 避免开门见山,可以做一些必要的铺垫,以防有同事对相关技术不了解,为了理解你的内容,还得自己查资料
  • 避免长篇大论都在讲底层架构、底层原理,没多少人会感兴趣,还不如多讲一下自己在实践过程中遇到哪些问题、怎么解决,有哪些心得体会,这样对别人帮助更大
  • 避免内容空洞,例如讲了一大堆新特性,但都没有自己实践过,亦或是说各种性能好、各种优化,但没有实际的数据支撑,没有可以量化的指标、没有与竞品对比等等
  • 搞清楚技术分享的目的,不是给其他同事上课,而是重在分享经验。可以是自己实践过程中踩了哪些坑,或者自己搭建了一套项目模板,可以直接开箱即用

📒 执行 yarn create 命令背后做了哪些

执行 yarn create <starter-kit-package>,会先全局安装 create-<starter-kit-package>,如果已安装则会更新到最新版本,然后会执行 bin 字段中定义的脚本。

例如,yarn create react-app my-app 相当于:

$ yarn global add create-react-app
$ create-react-app my-app

📒 HTTP/3发布了,我们来谈谈HTTP/3

📒 GitHub中文排行榜

📒 80%的Linux都不懂的内存问题

📒 十分钟带你入门 Web Components

📒 前端开发技术与业务的思考

📒 【第2642期】基于 Serverless 的业务轻研发模式探索

📒 React新文档:不要滥用Ref哦

📒 async 函数注意事项

async 函数中,当有一个 await 后面的 Promise 状态变为 rejected,整个 async 函数执行就中断了。

这个在串行请求中非常有用。在很多场景下,我们需要将上一个请求返回的结果,作为参数进行下一次请求。假如上一个请求报错,那么结果自然获取不到,如果此时还进行下一个请求,这个逻辑显然有问题。因此,借助 async 函数的特性,在上一个请求报错的情况下,整个函数执行就断掉了,后续不会再发请求,无需手动进行异常处理。

📒 我与Go的故事、我为什么推荐你学Go以及我的学习路线

📒 CDN 为什么这么设计

📒 Vue3.0 响应性原理

📒 一文读懂 TypeScript 泛型及应用

📒 记录一次切换包管理器引发的血案

📒 数据库表结构设计一点心得和经验

📒 2021-2022,我在大厂的前端最佳实践

monorepo 工具除了最基本的代码共享能力外,还应当至少具备三种能力,即:

  • 依赖管理能力。随着依赖数量的增加,依旧能够保持依赖结构的正确性、稳定性以及安装效率
  • 任务编排能力。能够以最大的效率以及正确的顺序执行 Monorepo 内项目的任务(可以狭义理解为 npm scripts,如 build、test 以及 lint 等),且复杂度不会随着 Monorepo 内项目增多而增加
  • 版本发布能力。能够基于改动的项目,结合项目依赖关系,正确地进行版本号变更、CHANGELOG 生成以及项目发布

2021-2022,我在大厂的前端最佳实践

📒 Ramda 哪些让人困惑的函数签名规则

📒 Github上8个很棒的React项目

📒 全网最强 JVM 来袭

📒 useEffect 怎么支持 async...await

- - + + \ No newline at end of file diff --git "a/2022/6\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/6\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index a3bcb9f601..ce2f41d450 100644 --- "a/2022/6\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/6\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月26日内容汇总

· 4 min read
加菲猫

📒 如何从微小细节着手,参与开源贡献

📒 【第2650期】研发同学应该如何负责好一个项目

📒 手写 Vue3 响应式系统:实现 computed

📒 ECMAScript 2022 正式发布,有哪些新特性

📒 手写 Vue3 响应式系统:核心就一个数据结构

📒 通过这两个 hook 回顾 Set/Map 基础知识

📒 React Hooks 使用注意事项

哪些变量应该放进依赖项里面:

  • 与视图渲染有关的变量,例如 propsstatecontext
  • 一些派生的状态,例如 useCallbackuseMemo 的返回值

哪些不应该放进依赖项里面:

  • 与视图渲染无关的变量,例如 ref

这是因为 useRef 返回的引用在整个组件生命周期中保持不变,不存在闭包陷阱问题

📒 React 性能优化策略

引起组件更新的因素:

  • props(包括父组件 rerender 引起子组件 rerender)
  • state(在组件内部 setState 触发调度更新)
  • context(全局状态改变,通知订阅状态的组件更新)

在不做任何优化的情况下,即使 props 没有改变,但是如果父组件 rerender,会导致子组件 props 对象重新生成,由于 React 默认的性能优化策略是 props 严格相等比较,所以不可避免地导致子组件以及所有的子孙组件 rerender。

严格相等比较 高效但是难命中,只有当前组件没有 rerender 才能保证后续组件树都不 rerender

使用了 React.memo 之后,会改为对 props 进行 浅比较,这样可以避免一些不必要的 rerender。

浅比较 容易命中但是有一定性能开销,因为需要遍历对象

📒 如何封装 cookie/localStorage/sessionStorage hook

📒 【第2648期】如何在 Vue 项目中,通过点击 DOM 自动定位VSCode中的代码行

📒 HTTP史记 - 从HTTP/1到HTTP/3

📒 Umi 4 发布啦!

📒 记录第一次给开源项目提 PR

📒 Redis 高可用原理

📒 如何移除你项目中99%的JS代码

📒 浅谈前端项目里如何用 Logger 做好日志管理

📒 如何让定时器在页面最小化的时候不执行

📒 一道有挑战性的 React Hook 场景题,考考你的功底

📒 TypeScript 深水区:3 种类型来源和 3 种模块语法

📒 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景

- - + + \ No newline at end of file diff --git "a/2022/6\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/6\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 8edbecc4c8..ecc07d18b9 100644 --- "a/2022/6\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/6\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月5日内容汇总

· 9 min read
加菲猫

📒 为什么不建议用 switch...case 实现策略模式

相比 if...else 来说,switch...case 已经有了明显提升,但还是不适合用来编写策略模式。

这是因为 switch...case 实际上违背了 开闭原则,即对扩展开放,对修改封闭。例如当我们需要增加规则的时候,就需要靠修改代码来实现。

从这一点来说,用 JS 对象或者 Map 对象来实现策略模式就要灵活很多,可以动态扩展规则。

📒 干货 | 携程机票前端Svelte生产实践

📒 通过 Preact 看 Diff 算法细节

📒 Vite 打包流程

首先调用 rollup 方法(Rollup 的编程式 API)编译出 bundle 添加到 build 数组中,接下来就是遍历它,进行 bundle 的写操作(即输出到硬盘上),因为 vite 使用的是 Rollup 完成文件的打包,所以这里调用的是 bundle.write 来将文件输出到硬盘上。

packages/vite/src/node/build.ts
for (const build of builds) {
const bundle = await build.bundle;
const { output } = await bundle[write ? 'write' : 'generate']({
dir: resolvedAssetsPath,
format: 'es',
sourcemap,
entryFileNames: `[name].[hash].js`,
chunkFileNames: `[name].[hash].js`,
assetFileNames: `[name].[hash].[ext]`,
...config.rollupOutputOptions
});
build.html = await renderIndex(output);
build.assets = output
await postBuildHooks.reduce(
(queue, hook) => queue.then(() => hook(build as any)),
Promise.resolve();
)
}
tip

注意 Vite 2.x 源码结构稍有不同,但是整体流程还是类似的:

https://github.com/vitejs/vite/blob/ab23e6e7b490cf610a4465cc533f671a729fdfa8/packages/vite/src/node/build.ts#L543

这里有一个值得学习的地方,这边 postBuildHooks 的类型定义是 ((build: any) => Promise<any>)[],如何保证调用顺序,即上一次调用完成后进行下一次调用?

通常我们用 reduce 做管道操作都是不能用于 Promise,因为管道操作需要将上一次调用的返回值,作为参数传入下一次调用,但 Promise 的话很可能是 pending,根本拿不到上一次调用的返回值。所以一般来说我们只能将 reduce 改成普通 FOR 循环:

let initialValue = Promise.resolve();

for (const hooks of postBuildHooks) {
initialValue = await hook(build);
}

而源码中对 reducer 函数进行了包装,将 hook 的执行放到 then 方法回调中,这样就可以保证调用顺序:

await postBuildHooks.reduce(
(queue, hook) => queue.then(() => hook(build as any)),
Promise.resolve();
)

vite 不支持 ie 11?configureBuild Hook 帮你定制 bundle 打包过程

📒 VS Code 如何快速定位到问题代码

在 TS 项目中,经常会因为类型问题出现报错,因此需要快速定位到问题代码。

在 VS Code 中可以使用 Ctrl + Shift + M 快捷键打开问题面板,可以看到当前文件中所有的 errors 和 warnings。此时,按 F8 可以依次跳转查看当前文件中的问题。

📒 20个GitHub仓库助你成为React大师

📒 从零开始实现一个简单的低代码编辑器

⭐️ 从arco-design的collapse组件分析如何吸收开源项目的知识

📒 模块联邦浅析

📒 我们是怎么在项目中落地qiankun的

📒 【第2631期】浅谈 Atomic CSS 的发展背景与 Tailwind CSS

📒 通过 JS 运行时堆快照进行 Web 爬虫

当网站提供的接口无法满足需求的时候(甚至可能连接口都没有),爬虫可能是一种不太理想的解决方案。虽然 Puppeteer 和 Playwright 使控制无头浏览器变得容易,但是获取你需要的数据,还是会很复杂。如果你可以从网站的页面堆中提取数据呢?Puppeteer Heap Snapshot 是这个实验的最终结果。

https://www.adriancooney.ie/blog/web-scraping-via-javascript-heap-snapshots

📒 JS 清空数组的方式

以下两种清空数组的方式有何区别:

let arr = [...];

// 这种是 immutable 的方式
// 即创建一个空数组,用该空数组指针替换原数组的指针
// 不影响其他引用原数组内存地址的变量
arr = [];

// 这种是 mutable 的方式
// 即直接修改原数组,不创建新数组,仍然是原数组指针
// 会影响其他引用原数组内存地址的变量
arr.length = 0;

📒 【零基础】充分理解WebGL(三)

📒 Go Error 处理最佳实践

📒 Map 对象小技巧

Map 对象可以记住键值对插入顺序,那么如何获取顺序呢?答案是通过迭代器接口。然后迭代器接口可以直接遍历,也可以转为数组,这样就变成获取数组第一个元素了。

按照这个思路,实际上也可以用 Map 实现队列

📒 Web3.0开发入门

📒 从源码中来,到业务中去,React性能优化终极指南

📒 剖析React核心设计原理—Virtual Dom

📒 前端工程化:保姆级教学 Jenkins 部署前端项目

📒 正则表达式完整指南

📒 【第2630期】javascript中的依赖注入

📒 【前端部署附录一】写给前端的 docker 使用指南

📒 Chrome 如何调试移动端 H5 页面

chrome://inspect/#devices

📒 支付宝体验科技 Umi 系列文章

Umi 4 特性 05:稳定白盒性能好的 ESLint

📒 如何回滚 Git 分支代码

# 找到需要回滚的版本哈希,执行 git reset
$ git reset --hard HEAD^
# 然后强制 push
$ git push -f -u origin pre

拜托,不要再问我Git如何回滚代码

📒 如何华丽的实现一套脚手架 - 以umicli和转转zzcli为例

📒 深入浅出 npm & yarn & pnpm 包管理机制

📒 一文带你进入微前端世界

📒 你还在手动部署埋点吗?从0到1开发Babel埋点自动植入插件

📒 一个三小时的 React Native 速成课

https://www.youtube.com/watch?v=VozPNrt-LfE

📒 使用 Three.js:一款流行的 3D JavaScript 库

https://betterprogramming.pub/working-with-three-js-the-popular-3d-javascript-library-bd2e9b03c95a?gi=8c31e429644f

📒 Next.js 后续规划的 RFC:即将到来的重大变化

https://nextjs.org/blog/layouts-rfc

📒 2022 年 React 状态管理库综述

React 的优势在于它可以灵活地适应不同的开发方式,其中也包括状态管理方面。这篇文章总结了几个流行的状态管理库,包括 Zustand、Recoil(来自 Facebook)、XState,当然还有 Redux。

https://www.albertgao.xyz/2022/02/19/react-state-management-libraries-2022/

📒 深入浅出前端做控制反转与依赖注入

⭐️ ⭐️ 现代 Monorepo 工程技术选型,聊聊我的思考

总结一下:

  • 使用 PNPM 作为 monorepo 项目的包管理工具
  • 使用 Changesets 作为 monorepo 项目的发包工具
  • 使用 Turborepo 作为 monorepo 项目多包任务执行工具

现代 Monorepo 工程技术选型,聊聊我的思考

📒 MySQL 主从,6 分钟带你掌握

📒 【第2628期】基于设计稿识别的可视化低代码系统实践

📒 前端配置化真香~上班又多了60%的摸🐟时间

- - + + \ No newline at end of file diff --git "a/2022/7\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/7\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 1e2aa96bc2..50dbf383bd 100644 --- "a/2022/7\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/7\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月10日内容汇总

· 3 min read
加菲猫

📒 为什么 React 的 Diff 算法不采用 Vue 的双端对比算法

📒 Module Federation最佳实践

📒 react18新特性及实践总结

📒 模块加载机制

commonjs 加载一个 module

webpack_require -> vm.runInContext

📒 Nodejs Module Wrapper

Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:

(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});

https://nodejs.org/api/modules.html#the-module-wrapper

📒 微前端/qiankun

📒 如何进阶TypeScript功底?一文带你理解TS中各种高级语法

📒 【第2662期】低代码平台架构深度剖析

📒 那些关于DOM的常见Hook封装(二)

📒 antd mobile 作者教你写 React 受控组件和非受控组件

📒 我对 React 实现原理的理解

📒 WebAssembly生态及关键技术综述

📒 HTTP3 RFC标准正式发布,QUIC会成为传输技术的新一代颠覆者吗

📒 如何将传统 Web 框架部署到 Serverless

📒 新来个技术总监,把 RabbitMQ 讲的那叫一个透彻,佩服!

📒 关于前端主题切换的思考和现代前端样式的解决方案落地

⭐️ Data Flow in Remix

React 第一次和大家见面时,最引人注目的特点之一是他的「单向数据流」。这在官方文档 Thinking in React 里仍有介绍。用一句话概况即:UI 是状态的函数,或者叫 ui=fn(state)

而后有不少遵从这种思想的数据流方案,比如 Redux、MobX 等,以 View -> Action -> State 这种循环的单向数据流方式进行。他们的缺点是这个数据流只在客户端运转,而一个应用通常还需要持久化数据和同步数据,这意味着还要有另一条数据流来和服务端做交互。

那有没有贯穿服务端和客户端的单向数据流?Remix!哈哈。Remix 将这一理念延伸到持久化数据的 API 层,通过 Loader 和 Action 把数据流串了起来,形成 Loader > Component > Action 的单向数据流。所以在 Remix 中,开发者也无需使用 Redux 等其他数据流方案。

Data Flow in Remix

MDH 前端周刊第 60 期:Fresh 1、SPA、框架流行度、1X 工程师、Father 4 RC

📒 巨石瓦解!我把Vue3巨石项目拆成了十几个微应用

- - + + \ No newline at end of file diff --git "a/2022/7\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/7\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 8d30d60396..6ebedad09e 100644 --- "a/2022/7\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/7\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月17日内容汇总

· 4 min read
加菲猫

📒 Vite 3.0 正式版发布

Vite 3.0 发布: 核心更新盘点与分析

Vite 3.0 正式发布,下一代前端构建工具!

https://vitejs.dev/blog/announcing-vite3.html#dev-improvements

📒 nestjs + prisma 开发全栈项目

https://www.prisma.io/docs/getting-started

https://www.prisma.io/nestjs

📒 成为优秀的TS体操高手 之 TS 类型体操前置知识储备

📒 如何在React中应用SOLID原则

📒 2022 年 CSS-in-JS 技术的又一匹黑马!

📒 还在用命令行看日志?快用Kibana吧,可视化日志分析YYDS!

📒 【面试造火箭,入职拧螺丝】万字详解如何从0开始手写一个Promise

⭐️ Webpack5 核心原理与应用实践

📒 Webpack 特有的优化策略

由于 Webpack 出现的时候,还没有 ESM 规范,所以 Webpack 底层根据 CJS 规范实现 __webpack_require__ 加载模块,这就导致 Webpack 打包会出现大量模板代码,增加打包后体积。相比之下,Rollup 基于 ESM 规范打包,产物代码就很干净。

1. Scope Hoisting

作用域提升,个人觉得这个应该是参考了 Rollup,但是 Webpack 的模块合并还是非常有限,必须是只引用了一次的模块才能合并,否则会造成模块冗余问题。

默认 optimization.concatenateModules 在生产环境下会启用:

module.exports = {
//...
optimization: {
concatenateModules: true,
},
};

https://webpack.docschina.org/plugins/module-concatenation-plugin/

2. 确定性模块 ID

生产环境下,Webpack 的模块 ID 默认按模块解析顺序自增,即使源码没有修改,但是有时模块 ID 会发生变化,导致哈希改变,文件缓存失效。通过配置 moduleIds: 'deterministic' 有利于持久化缓存:

module.exports = {
//...
optimization: {
moduleIds: 'deterministic',
},
};

https://webpack.docschina.org/configuration/optimization/#optimizationmoduleids

3. Runtime Chunk

运行时代码单独分包,一般 SPA 应用问题不大,多页应用打包,运行时代码单独分包可以配置持久化缓存。配置 runtimeChunk: 'multiple' 会为每一个 Initial Chunk 添加一个 Runtime Chunk,配置 runtimeChunk: 'single' 则会创建一个所有 Initial Chunk 共享的 Runtime Chunk:

module.exports = {
//...
optimization: {
runtimeChunk: {
name: 'runtime',
},
},
};

https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk

📒 MySQL Redo Log 深入探索

⭐️ 详解 Vite 依赖预构建流程

⭐️ VueUse scripts,他们都模仿过的脚本

⭐️ 【第2669期】前端开发中的流程自动化与提效实践

📒 隔离并修复 Node 应用程序中的内存泄漏

📒 硬件加速中的“层”和层叠上下文中的“层”,是一个东西吗

📒 《Go学习路线图》带你少走弯路,Let's Go !

📒 前端原型链污染漏洞竟可以拿下服务器shell

📒 我在 Shopee 工作这两年

📒 五个 React-Query 和 SWR 的小技巧

⭐️ ⭐️ 「React 进阶」 React 全部 Hooks 使用大全 (包含 React v18 版本 )

📒 React 状态管理的新浪潮

⭐️ ⭐️ 函数式编程术语

- - + + \ No newline at end of file diff --git "a/2022/7\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/7\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 2786e36102..cb56be9a2e 100644 --- "a/2022/7\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/7\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月24日内容汇总

· 8 min read
加菲猫

📒 NestJS v9 发布

https://trilon.io/blog/nestjs-9-is-now-available

📒 如何遍历 map

首先,map 本身是可迭代对象,可以通过 for...of 遍历。

第二,可以将 map 转为数组进行遍历,实际还是利用了迭代器接口,但是可以利用数组方法链式调用。

map 默认迭代器接口是 entries,可以自定义例如 [...map.values()]

📒 开发小技巧

Antd 的 Modal 既可以通过组件方式,也可以通过 modal method 方式使用,后者比组件更方便,不需要自己维护状态,但是会有一个问题,如果需要通过弹框内部的按钮,控制弹框更新、关闭,我们没办法直接给弹框内部的元素传递 modal.update,因为此时 Modal.success() 还没有执行结束,modalundefined,如何解决呢?

实际上可以通过不可变引用解决这个问题,我们先定义一个对象 ctx,在里面定义一个 update 方法,但什么也不做。然后给弹框内部按钮传入 (e) => ctx.update(e),这样是可以正常调用,不会报错。然后在 Modal.success() 执行完成之后,这个时候就可以访问 modal 对象了,我们用 modal.update 去替换之前的空函数,这样当事件触发之后,调用的 modal.update() 就可以控制弹框更新了。

const renderQuizModal = ({
quizId,
unitId,
handleOk,
}) => {
const ctx = {
update: (e: CheckboxChangeEvent) => {},
};

const modal = Modal.success({
title: quizName,
width: 600,
okButtonProps: {
disabled: true,
},
content: (
<Checkbox onChange={(e: CheckboxChangeEvent) => ctx.update(e)}>
勾选此项
</Checkbox>
),
onOk: () => {
handleOk?.();
},
})

ctx.update = (e: CheckboxChangeEvent) =>
modal.update({
okButtonProps: {
disabled: !e.target.checked,
},
});
}

如何强制重新挂载组件?如果修改 props 或者 setState 只是触发组件 rerender,实际上是组件更新的过程,有时候需要强制组件重新挂载,可以修改组件的 key

为何有时候没有给域名配置 host 还是可以访问?这是因为在容器中部署,可以通过 Docker 的 Networking 实现容器通信。

⭐️ 「React进阶」React中没有keepalive?没事!手把手教你从零到一设计并实现一个!

⭐️ 现在前端面试都问什么「字节、蚂蚁、美团、滴滴面试小记」

📒 2022 年值得推荐的 Vue 库

📒 【第2676期】一个 Safari 的小 Bug,探索出了 fetch 和 xhr的新玩法

📒 Vite 也可以模块联邦

📒 开发一个 CLI 模板库可以点亮哪些技能点

📒 Golang 实现一个 JS 打包器

Golang 解析 JS AST:

Webpack 打包原理:

📒 天天造轮子第七天 - 中间件实现 - Compose 的 N 种姿势

📒 使用Vite和TypeScript带你从零打造一个属于自己的Vue3组件库

📒 如何使用 React Hooks 重构类组件

📒 Why DRY is the most over-rated programming principle

https://gordonc.bearblog.dev/dry-most-over-rated-programming-principle/

📒 What makes a great software engineer

https://swizec.com/blog/what-makes-a-great-software-engineer/

📒 构建面向未来的前端架构

本文是关于前端架构的组件部分。如果有写过组件,可能都有遇到随着业务迭代而快速增加复杂度,最终写出臃肿不堪难以维护的组件。为啥别人写的代码简洁易懂?缺的是经验吗?不是,缺的是方法论。我觉得此方法同样适用非组件场景。

心智模型的重要性。心智模型会影响我们的决定,进而影响代码的整体结构。如果一直做错误的大大小小的决定,那代码很快就会变成屎山。每个人的心智模型不可能完全一样,所以注定会做出不同的决定。对于团队而言,用框架和工具约束,让大家不做或少做决定是个很好的策略,比如用 prettier 统一编码风格。

文中有个例子。你写了一个组件,过了一周,产品迭代,而之前写的组件不能很好满足新需求。这时你有两个选择,A)思考之前的抽象是否正确,如果不正确,分解了重新做,B)增加一个额外 props,组件里加一些恶心的条件判断。你会如何选择?你会在乎之前投入的沉没成本还是面向未来考虑更多?其实没有对错,注意 By Scene。

自上而下 vs. 自下而上。「你可以自上而下或自下而上地构建。也就是说,你可以从构建层次结构中较高的组件开始。在比较简单的例子中,通常自上而下更容易,而在较大的项目中,自下而上更容易,并在构建过程中编写测试。」

自上而下是直观的、能快速出货的,大家通常也会这么干。当涉及到分解用户界面时,在功能区域周围画上方框,然后成为你的组件。这种功能分解的过程是自上而下的,通常会直接导致创建具有特定抽象性的专门组件。需求会改变。而在几个迭代过程中,这些组件很容易迅速变成单体巨石组件。

单体巨石组件有不少问题,包括 1)不容易复用子组件 2)包变大,比如 SSR 场景可能只希望渲染第一时间被用户看到的组件从而提速 3)rerender 问题导致运行时性能不好,也会让代码复杂,出现很多不必要的 memo 调用 4)不好的抽象导致项目复杂,迭代困难。「敏捷软件开发最重要的经验之一是迭代的价值;这在软件开发的各个层面都是正确的,包括架构。」

自下而上不那么直观,最初可能比较慢。因为这种方式会产生很多小组件,而实际中不是每个小组件在最初都需要可复用。所以前期需要花更多时间和努力,让复杂性被封装在每个小组件里。好处是长远看会更快,因为适应性更强。同时避免了单体巨石组件和前面介绍的他会带来的大量问题。

https://frontendmastery.com/posts/building-future-facing-frontend-architectures/

- - + + \ No newline at end of file diff --git "a/2022/7\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/7\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index a5740f9757..d01cfccb6c 100644 --- "a/2022/7\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/7\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月31日内容汇总

· 5 min read
加菲猫

📒 全网最优雅的 React 源码调试方式

📒 如何实现一个跨框架的组件库文档

📒 入职Apifox研发组半年,我所提升的软技能|文末抽书

⭐️ 几个提升Go语言开发效率的小技巧

📒 最近对前端构建工具的一些理解

📒 Go语言中常见100问题-#86 Sleeping in unit tests

📒 超实用的Chrome DevTools调试技巧

📒 开源项目推荐

用 Go 写的 GUI gRPC 客户端。作者在调试 gPRC 接口时,发现没有类似 postman 趁手的 gPRC 客户端,所以就自己动手写了一个然后开源了。

https://github.com/crossoverJie/ptg

Go DDD 示例项目。该项目通过一个预约系统的示例,展示了如何在 Go 项目中实现领域驱动设计(DDD)和读写分离架构(CQRS)。

https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example

一款静态应用程序安全测试(SAST)工具。它可以检测项目中是否包含密码、API Key、token 等信息,还能够轻松整合到 Git Hook 和 GitHub Action,实现提交代码时自动检测,通过告警和阻止 push 等方式,有效地防止敏感信息泄漏。

https://github.com/zricethezav/gitleaks

在线可视化正则编辑器。该项目可将输入的正则表达式,自动生成对应的可视化图形,支持通过编辑图形节点修改正则表达式,以及对正则表达式进行测试等功能。

https://github.com/Bowen7/regex-vis

📒 前端构建效率优化之路

📒 Esbuild Bundler HMR

📒 面试突击69:TCP 可靠吗?为什么

📒 招银网络一面:AOP 了解吗?有什么用?切面执行顺序如何控制

⭐️ Nest 的实现原理?理解了 reflect metadata 就懂了

📒 耽误你十分钟!🎃你可能用得上这些webpack5新特性

📒 入职即巅峰?🧨基建优化项目体积减少20%!

📒 简单好用的前端拖拽排序库

📒 你能给前端工程化下个定义么

📒 你需要知道的ES6—ES13开发技巧!

📒 【第2682期】前端场景下请求的Race Conditions

📒 介绍几个相对冷门的 React Hook

https://css-tricks.com/react-hooks-the-deep-cuts/

📒 Remix 和 Next.js 的区别

本文对这两个基于 React 的框架进行了逐个特性的比较,它们有很多相似之处,但也有一些关键的区别。

https://www.smashingmagazine.com/2022/07/look-remix-differences-next/

📒 阅读源码之 React 篇

本文并不是要详尽地描述 React 是如何工作的,而是主要关注了 React 的设计和 React 开发人员多年来采用的实践。

https://alexkondov.com/readint-source-code-react/

📒 编程语言是如何实现泛型的

📒 Vue 编译三部曲

Vue 编译三部曲:如何将 template 编译成 AST

Vue 编译三部曲:模型树优化

Vue 编译三部曲:最后一曲,render code 生成

📒 字节一面:TCP 和 UDP 可以使用同一个端口吗

📒 如何在繁重的工作中管理好自己的时间和精力

📒 「万字总结」🍒动画 + 大白话讲清楚React渲染原理

📒 Go语言中常见100问题-#85 Not using table-driven tests

📒 小程序不让用 JS 解释器?那我再肛一次鹅厂

- - + + \ No newline at end of file diff --git "a/2022/7\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/7\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index b2551295eb..349359a16d 100644 --- "a/2022/7\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/7\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月3日内容汇总

· 7 min read
加菲猫

📒 前端四种序列化

1. JSON 序列化

使用 JSON.stringify() 进行序列化,对应的 Content-Type 是 application/json

2. Query String 序列化

使用 new URLSearchParams() 进行序列化,对应的 Content-Type 是 application/x-www-form-urlencoded

注意 URL query string 与 body 发送的 query string 略有不同,特别是对空格的处理

3. FormData 序列化

使用 new FormData() 创建,对应的 Content-Type 是 multipart/form-data

4. XML 序列化

使用 new XMLSerializer() 进行序列化,一般用于 DOM 对象。

📒 React 18 新特性

  • Selective Hydration
  • Offscreen

📒 Vue 2.7 正式发布,代号为 Naruto

📒 线上服务器老是卡,该如何优化

📒 【第2657期】前端JS攻防对抗

📒 Redis 唯快不破的秘密

📒 新一代 npm 包构建工具 father 4 RC 发布

father 4 支持 Bundless 和 Bundle 两种构建模式。

  • Bundless 指把所有源码文件单独编译、平行输出做发布。在 father 4 中,输出 ESModule 及 CommonJS 产物时会使用 Bundless 构建模式
  • Bundle 指把源码按 entry 打包成 1 个或多个文件做发布,也就是 Webpack 的打包模式。在 father 4 中,输出 UMD 及依赖预打包产物时会使用 Bundle 构建模式

依赖预打包

  • 一是 NPM 包发布后安装体积更小、速度更快
  • 二是不担心三方依赖更新引起 Bug
  • 三是NPM 包发布后安装 0 warning

不过,由于依赖中可能存在 dynamic require/import 等复杂的情况,现阶段不一定每个依赖都能顺利打包,father 4 会在 RC 阶段持续优化,将这项功能变得更加好用。

新一代 npm 包构建工具 father 4 RC 发布

📒 【第2656期】使用 React Testing Library 的 15 个常见错误

📒 【第2655期】携程基于 GraphQL 的前端 BFF 服务开发实践

📒 聊聊 Vue 的双端 diff 算法

📒 面试官:Vue的KeepAlive怎么实现的?我:这有啥好问的

📒 如何优雅的写 Controller 层代码

📒 这些 hook 更优雅的管理你的状态

📒 干货 | Trip.com APP QUIC应用和优化实践

📒 基于 qiankun 的微前端实践

📒 [科普文] 浅谈 Function Programing 编程范式

📒 Taze - 一个让你的依赖保鲜的现代 cli 工具,支持定制、支持 monorepo

https://github.com/antfu/taze

📒 如何利用 Why、What、How 框架更好地写作

做项目时,要写三种类型的文档,单页文档、设计文档和 Review 文档,见图1,分别是写于启动前、实施前和完成后。单页文档写给老板看,介绍问题、预期结果、建议的解决方案和其他高层次的点;设计文档程序员可以理解为 RFC,写给同行或下属看,包含方法论、系统设计、实验结果等;Review 文档用于 Review 成功和失败的点。

文档怎么写?用「Why、What、How」的框架。听起来很简单,小学一年级老师也这么教,但作者的大部分文档都是用这个框架。Why 是让听众理解问题和背景,注意站在听众的角度,比如不要对着老板聊技术的 Why,也不要对着技术同学聊规划的 Why;What 讲解决方案是什么样子,以及可以做什么;How 讲如何实现 Why 和 What。

其中「Why」部分可以用 5 Why(https://en.wikipedia.org/wiki/Five_whys)的方法,连续问 5 个 Why,以便找出问题的根本原因。

此外还要注意「Who」,即你的听众是谁。为老板和为工程师写的文档差异会很大,因为不同人关注的点不同,前者更关心客户痛点、商业成果、投资回报率,后者更关心技术要求、设计选择、API 规范。

不同文档类型应用上述框架的例子见图 2。

文章内还有个金句,「Writing docs is expensive, but cheap.」文档很贵,需要花时间写、Review 和迭代,这些时间本可以花在写代码上。文档又很便宜,通过文档可以避免建立不靠谱的兔子洞项目,不靠谱的项目就算做出来也没人用,这个浪费是巨大的。所以,不要做「问题模糊、解决方案有争议」的项目。

https://eugeneyan.com/writing/writing-docs-why-what-how/

⭐️ 看懂 Lighthouse 中 Performance 核心指标

📒 前端抢饭碗系列之Docker容器编排

📒 为什么 2022 年 ESM 又被发布了一次

📒 漫谈 CSS 方法论

📒 HTTP 新增的 103 状态码,这次终于派上用场了!

📒 买啥高并发课程,白嫖不香么?(包括 PDF)

📒 小程序长列表优化实践

📒 前端食堂技术周刊第 42 期:Vue 2.7 Beta、TS 4.8 Beta、React 开源奖、ECMAScript 2022

📒 封装一个管理 url 状态的 hook

- - + + \ No newline at end of file diff --git "a/2022/8\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/8\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index ce377b706e..940c626e99 100644 --- "a/2022/8\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/8\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月14日内容汇总

· 9 min read
加菲猫

📒 将微前端做到极致-无界方案

📒 【第2701期】技术Leader如何创造业务价值

📒 Monorepo 下的模块包设计实践

📒 【TypeScript】never 和 unknown 的优雅之道

📒 Bundle-less 的思考和实践分享

📒 React Fiber架构原理剖析

📒 【万字】优化Webpack?肘,跟我进屋聊聊

📒 字节的前端监控 SDK 是怎样设计的

📒 别再乱打日志了,这份 Java 日志规范,应有尽有,建议收藏!

📒 explain | 索引优化的这把绝世好剑,你真的会用吗

📒 这11条接口性能优化技巧,利好每日睡眠

📒 顺丰快递:请签收MySQL灵魂十连

📒 Go Mod小知识:伪版本

📒 Go ORM 单元测试全流程讲解

📒 超全总结:Go语言如何操作文件

📒 React 服务端渲染遇到的问题

在服务端渲染场景下,不能使用 style-loader,需要用 isomorphic-style-loader 注入样式。

style-loader 内部使用了 dom API 把样式注入到 style 标签中,在 Node 环境下会报错

React 期望在服务端和客户端渲染的内容是相同的,客户端渲染会默认复用服务端渲染的 dom。如果需要在服务端和客户端上渲染不同的内容,可以设置一个 isClient 变量:

class MyComponent extends React.PureComponent {
state = {
isClient: false,
}

componentDidMount() {
// 这里在客户端 hydrate 的时候执行
this.setState({ isClient: true });
}

render() {
const { isClient } = this.state;

if (!isClient) {
// 当需要渲染的组件需要访问浏览器 API,在 Node 环境会报错
// 这里可以渲染 fallback 的内容
return ...
}

// 在客户端可以正常渲染组件
return ...
}
}
tip

当需要渲染的组件需要访问浏览器 API(例如 windowdocumentlocation),在 Node 环境会报错。在服务端渲染的时候,可以先渲染 fallback 内容,在客户端 hydrate 的时候,再渲染正常组件。

另外有一些 SDK,内部可能也访问了浏览器 API,这种情况下不能直接在构造器中初始化实例,可以在 componentDidMount 钩子中延迟初始化。

https://17.reactjs.org/docs/react-dom.html#hydrate

📒 vite 代码压缩遇到的问题

vite 默认使用 esbuild 压缩,esbuild 不仅会做常规的压缩,而且还会在 target 配置允许的范围内做一些语法转换,进一步减小 bundle 体积。

例如在业务中有下面一段代码:

try {
// ...
} catch (err) {
// 这边没有用到 err 参数
return false;
}

经过 esbuild 压缩之后,try...catch 后面的括号直接不见了(这实际上是 ES2019 中的 optional-catch-binding 语法),在一个老业务工程构建的时候,Babel 无法识别这种语法,直接报错了:

try {
// ...
} catch {
return false;
}

有两种解决方案:

  • 一种是使用 terser 压缩,设置 minify: "terser"
  • 另一种继续使用 esbuild,但是手动设置 target: "es2015"

https://vitejs.dev/config/build-options.html#build-target

tip

在一般前端项目中,target 配置是针对 Babel 的,即最终的产物兼容性由 Babel 决定。

但是在 Vite 中,Babel 只参与部分 esbuild 尚不支持的提案阶段的语法转换,并不决定最终产物兼容性,最终的兼容性由 esbuild 决定。注意 esbuild 默认的 target 值为 "esnest",即 esbuild 认为环境支持最新的 JS 语法特性。但是在 Vite 中,build.target 默认为一个特殊值 "modules"(即支持原生 ES Module、动态导入语法和 import.meta 语法,对应 Chrome >=87),最低可以支持 "es2015"

注意 Vite 默认只做语法转换,并不会引入 polyfill(适合第三方库开发,由业务工程 @babel/preset-env 配置 useBuiltIns: "entry" 统一引入 polyfill)。如果产物需要直接在浏览器中运行,则需要 @vitejs/plugin-legacy 插件。该插件会对最终 bundle 中每个 chunk,使用 @babel/preset-env 转换生成对应的 legacy chunk,同时根据 target 配置的目标浏览器兼容性和实际用到的 API,生成一个 polyfill chunk。

https://vitejs.dev/guide/build.html#browser-compatibility

📒 Golang 标准库 strings

重点看一下 strings.Builder 的用法。

Go 学习之 strings.Builder 篇

Go 字符串拼接6种,最快的方式 -- strings.builder

Go拼接字串的三种方法 Go1.10中的strings.Builder

https://pkg.go.dev/strings@go1.19

📒 你需要知道的TypeScript高级类型

📒 Go 的时间转换和时区校对总记不住?给你一份备忘单

📒 两个真实线上升级故障让你彻底搞懂package.json中的脱字符(^)

📒 【第2696期】React 状态管理的新浪潮

📒 Go 创始人教你如何处理错误

⭐️ 总监又来了,人狠话不多,这篇 gRPC,小弟佩服!

📒 React 性能优化, 从 500 毫秒到 1.7 毫秒

https://orizens.com/blog/500ms-to-1-7ms-in-react-a-journey-and-a%20checklist/

📒 UMD 的包如何导出 TS 类型

📒 为什么 React 的 Diff 算法不采用 Vue 的双端对比算法

📒 🚀Turborepo:发布当月就激增 3.8k Star,这款超神的新兴 Monorepo 方案,你不打算尝试下吗

📒 搞清楚 Go Mod的版本和伪版本,下次别乱用了

📒 掌握 TypeScript 中的映射类型

📒 React Re-render 指南

什么是 re-render?什么是必要的 re-render 和不必要的 re-render?如果你对这些问题还模模糊糊的,在这篇文章中可以找到答案。

有四个原因可以让一个组件重新渲染自己:状态变化、父级(或子级)重新渲染、上下文变化和 hooks 变化。

通过 composition(组合)可以避免 re-render。有几种方式,1)把状态下移,避免上层组件 re-render,让 re-render 保持在一个很小的范围之内,2)children as props,作为 props,子组件不会受 state 变更的影响,3)component as props,避免 component re-render。

通过 React.memo 可以避免 re-render,被 memo 的组件只在 props 变更时会 re-render。有几种方式,1)对于带 props 的 component,需对非原始值的 props 做 memo,2)components as props or children,对子组件做 memo 而不要对父组件做 memo。

什么时候应该用 useMemo/useCallback?1)React.memo 过的组件的 props 应该用,因为他们只有 props 变更时才会 re-render,所以反之非 React.memo 过的组件的 props 无需使用,因为都会 re-render,用了也白用,2)useEffect、useMemo、useCallback 中非原始值的依赖应该用,3)重消耗(比如生成渲染树)的部分应该用,反之轻消耗不要用,因为 useMemo/useCallback 本身也有消耗。

如何防止 Context 引起的 re-render?1)memo context value,避免父级组件 re-render 导致 value 变更从而让依赖 context 的地方全部 re-render,2)拆分 data 和 API(getter 和 setter),这样 getter 变更时依赖 setter 的部分不会 re-render,3)把数据拆小,4)使用 context selector 比如 use-context-selector。

https://www.developerway.com/posts/react-re-renders-guide

📒 明明加了唯一索引,为什么还是产生重复数据

📒 现代前端测试框架 Vitest 的一些落地实践感悟

📒 如何用 Project Reference 优化 tsc 编译性能

- - + + \ No newline at end of file diff --git "a/2022/8\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/8\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 2d3e2f4687..55876acad7 100644 --- "a/2022/8\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/8\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月21日内容汇总

· 11 min read
加菲猫

📒 玩转 Chrome DevTools,定制自己的调试工具

📒 【第2707期】由 esbuild JavaScript API 看跨语言调用

📒 Go 中闭包的底层原理是

⭐️ 使用 TypeScript 编写 React 的最佳实践!

📒 Webpack 构建优化

https://tsejx.github.io/webpack-guidebook/best-practice/optimization/collection

https://webpack.js.org/guides/code-splitting/

📒 k8s 部署相关

使用 Docker Desktop 搭建 k8s 集群

从Go程序第一行代码,到在 K8s 上运行,要经历多少步

在K8S上的Web服务该怎么做域名解析呢

https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

📒 字节一面:HTTPS 一定安全可靠吗

📒 如何在项目开发中逐步成长

📒 Golang 相关文章

Go 语言里使用 io.Readerio.Writer 两个 interface 来抽象 I/O,他们的定义如下:

type Reader interface {
Read(p []byte) (n int, err error)
}

type Writer interface {
Write(p []byte) (n int, err error)
}

io.Reader 接口代表一个可以从中读取字节流的实体,而 io.Writer 则代表一个可以向其写入字节流的实体。

⭐️ 能ping通,TCP就一定能连通吗

📒 Linux 是如何收发网络包的

📒 Golang 依赖注入相关文章

https://dev.to/dryrainbow/dependency-injection-in-golang-35oa

https://medium.com/avenue-tech/dependency-injection-in-go-35293ef7b6

https://medium.com/thirdfort/go-best-practices-how-to-code-comfortably-60118a27def8

https://levelup.gitconnected.com/better-error-handling-in-golang-theory-and-practical-tips-758b90d3f6b4

📒 【第2704期】网易严选多端组件库OSSA正式开源

📒 Golang 相关文章

Go 语言 Web 编程

Go 语言并发编程

Go 微服务实战

📒 React 18 新特性:Selective Hydration

https://github.com/reactwg/react-18/discussions/37

📒 一个简洁、强大、可扩展的前端项目架构是什么样的

📒 大家都能看得懂的源码之ahooks useInfiniteScroll

📒 esModuleInterop 是如何影响 tsc 的

📒 【第2703期】软件架构手册

📒 如何在 Web 上构建一个插件系统

📒 Go 的常量为什么只支持数字、字符串这样的基础类型

📒 两万字详解!InnoDB锁专题!

📒 细数线程池的10个坑

📒 Chrome DevTools 远程调试安卓网页的原理

📒 Windows 滚动条如何美化成 macOS 那样

📒 Go逃逸分析详解

📒 GO面试必知必会面试题

📒 最简单的单例模式,Go版本的实现你写对了吗

📒 伙计,Go项目怎么使用枚举

📒 Astro 1.0 正式发布,给前端带来了什么

📒 gum

迷人的 shell 脚本工具库,基于 go。

https://github.com/charmbracelet/gum

📒 React Query 转 RTK

本文是作者和 React Query 斗争了一年之后,最终弃 React Query 投 RTK 的故事。

React Query 处理了复杂的缓存,并根据需要重新加载数据。用户使用 useQuery 调用 API 时,数据被存储在 React Query 的缓存中。缓存的数据可通过 getQueryData 读取。如果要更新数据,使用 useMutation 会更新服务群上的数据,同时在 onSuccess 或 onMutate 中更新 React Query 缓存中的数据。更新的最简单方法是调用 invalidateQueries。而缓存失效正是作者觉得 React Query 难以驾驭的主要原因。

然后作者在对比之后选择了 Redux + Redux Toolkit(RTK)。作者希望选择全局 store 的数据流,同时还对比了竞品比如 Valtio(见上图)。Redux 的优点是社区、文档、明确的数据结构,缺点是更多脚手架代码、需要用 reselect 或其他来做渲染优化、尺寸比较大(18K)。

编者注:如果我是作者,在需要全局 store 的前提下,会更倾向于选择 valtio 或 zustand。1)脚手架代码少,这一点对外来说很关键,2)性能更好(valtio 基于使用决定 re-render),3)redux 的单 store 在未来可能成为瓶颈,比如要做组件提取时,多 store 会更灵活一些。

https://www.basedash.com/blog/why-we-had-to-move-away-from-react-query

📒 Suspense

作者在一年前写了第一篇,这是第二篇。时隔一年,这篇是他几个月的研究成果。

这段时间发生了什么?1)React 团队创建 React 18 工作小组讨论区,提供更多深入的信息,同时用于收集反馈,2)React 18 稳定版发布,3)一篇 React Labs 的帖子,介绍 React 团队正在探索的内容。

React 18 有啥新特性?1)没有并发模式,取而代之的是并发功能,仅在子树中启用,原因是为了向后兼容,2)Transition 允许将不紧急的更新标记为过渡(未来可能成为默认行为),3)基于 Suspense 的 Streaming SSR 允许在所有 HTML 被渲染之前进行流化,并且在 HTML 被完全流化之前就可以开始水化(目前需搭配 React.lazy 使用),4)选择性水化,5)新 Hooks,比如 useId 可用来生成在客户端和服务端稳定的 ID,6)自动批处理 让多个 setState 只导致单一渲染。

React 下一步做什么?1)Cache 组件,允许请求库做与 Suspense + 并发渲染兼容的数据缓存,这是 Suspense 目前缺的一环,2)React Server Component,3)用于 Assets 资源加载的 Suspense,比如字体、CSS 和字体等会在加载时导致布局偏移和混乱,4)React 编译器优化,React 慢的原因之一是因为有大量不必要的 re-render,自动插入 memo hook 可以提升性能,这在 React Conf 2021 中有过介绍,5)SuspenseList,在处理 Suspense 列表时有用,比如文章、评论或消息,允许协调子节点,决定他们显示的顺序,6)Offscreen API,允许保留 unmount 组件的状态,或者预先渲染用户可能会执行的 transition,比如做基于路由的预渲染。

跳出 React 从整体社区角度看。1)流式服务端渲染是为了提高响应速度,所以尽可能早地 flush,MarkoJS 在 2014 年开始支持,更早一些 Facebook 在 2009 年也有一门叫 BigPipe 的技术,2)SSR 在网络方面会更快,但同步水化依旧会成为大型项目的性能瓶颈,Islands architecture(群岛架构) 可以解这个问题,3)细粒度响应式,「React 虽然叫 react,但实际上不是 react」,响应式是框架中很流行的一种优化方法,比如 SolidJS,React 团队也有考虑过这个问题,但选择不追求,Dan 早在 2019 年就写过这个话题,4)Transition API 不算新技术,谷歌地图也有类似实现,同时 Scheduling(调度)问题正在通过标准的方式解决,5)SRC(服务端渲染组件)也不是新想法,2018 年就有 Phoenix LiveView 的实现,通过服务端状态和渲染实现 0 JS 的交互功能。

最后,作者还发现,React 项目内部子项目代号均是以 F 开头。比如 Fiber 是实现了异步渲染的重写的核心代号;Fizz 是新的服务器端渲染架构的代号、Flight 是服务器组件的代号、Fire、Flare 等。

https://blog.6nok.org/the-suspense-is-killing-me:-part-2/

📒 React TypeScript 备忘录

一份很全面的 React TypeScript 备忘录。

https://react-typescript-cheatsheet.netlify.app/

📒 React re-render 指南

关于 React 重渲染的系列指南,图文并茂,同时提供了代码示例和扩展资料。

https://www.developerway.com/posts/react-re-renders-guide

📒 ESLint 推出新的配置系统

回顾当前的 eslintrc 配置系统演进史,每一步的演化在当时来看都是不错的选择,比如 extends、Personal configs、多种配置文件格式、可共享的配置和依赖项(npm 背锅)、root、overrides、添加 extends 到 overrides 等等。

然而时至今日,随着 JavaScript 项目越来越庞大,从整体上再来看这些配置就太复杂了。为了简化配置,ESLint 团队经过 18 个月的修订和讨论,决定着手构建一个全新的配置系统 flat config,现在可以在 ESLint v8.21.0 中通过 API 使用。

https://eslint.org/blog/2022/08/new-config-system-part-1/

https://eslint.org/blog/2022/08/new-config-system-part-2/

https://eslint.org/blog/2022/08/new-config-system-part-3/

📒 字节一面:TCP 和 UDP 可以使用同一个端口吗

- - + + \ No newline at end of file diff --git "a/2022/8\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/8\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index b3df6fdab3..37114028d4 100644 --- "a/2022/8\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/8\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月28日内容汇总

· 8 min read
加菲猫

📒 【第2714期】从Multirepo到Monorepo 袋鼠云数栈前端研发效率提升探索之路

📒 抖音平台多产物代码隔离技术的实践与探索

📒 Hooks时代,如何写出高质量的react和vue组件

⭐️ Vite 约定式路由的最佳实践

📒 Go使用泛型后,这么写单元测试会失效

📒 如何保证数据库和缓存双写一致性

⭐️ 【第2713期】工程化思维:主题切换架构

📒 为了拿捏 Redis 数据结构,我画了 40 张图(完整版)

📒 美团一面:如何在 100 亿数据中找到中位数

📒 解决老工程 toast 组件问题

老工程 React 15.x,Webpack 2.x,工程里面原先没有组件库。

关于 npm 包可能存在部分 ES6 语法,低版本 Webpack 无法解析问题,可以用 Babel 转一下。同理 NPM 包使用了 ES Module 模块语法,也可以用 Babel 转为 CommonJS。现在主要的问题是,大多数 toast 组件,底层都用了 React Hooks,即使 ES 语法兼容,但是运行环境 React 版本太老还是无法兼容。最终还是选用 rc-notification,参考 antd 封装:

https://github.com/react-component/notification/tree/2.0.6

https://github.com/ant-design/ant-design/blob/2.13.14/components/message/index.tsx

📒 Kubernetes原理与架构初探

📒 VS Code 1.70 新特性

3-way merge editor

三路合并编辑器是在1.69版本里上线的,这个功能允许用户在VS Code内快速解决 Git 合并冲突。该功能启用后,可以通过点击「源代码控制视图」中的冲突文件来打开合并编辑器。

settings.json
{
"git.mergeEditor": true
}

Git 提交辅助操作

可以使用 git.postCommitCommand 来设置控制辅助操作,比如允许用户在提交信息后进行推送或者同步。

settings.json
{
"git.postCommitCommand": "sync"
}

分支保护

在之前的1.68版本中,VS Code就添加了 git.branchProtection 以用于配置受保护的特定分支。

settings.json
{
"git.branchProtection": [
"main"
]
}

Command Center

Command Center 功能启用后,其位于编辑器顶部的长条空间,让用户可以快速搜索项目中的文件。

settings.json
{
"window.commandCenter": true
}

sticky scroll

当用户在编辑器中滚动鼠标查看代码时,每个子模块(比如:类/接口/命名空间/函数/方法等等)代码的第一行会置顶固定住,以方便查看。

这对于一些长代码模块(比如一个很长的函数)的阅读体验提升还是非常有帮助的。

settings.json
{
"editor.experimental.stickyScroll.enabled": true
}

📒 Java中的语法糖甜不甜?巧用枚举实现订单状态转换!

📒 看 Go 中的 struct 如何被优化,还有小插曲

📒 Rust 与 Go 可以互操作

📒 SWC 入门介绍

📒 听说TCP能保证不丢包?图解TCP六大丢包场景

📒 Vue3中defineEmits、defineProps 是怎么做到不用引入就能直接用的

📒 浅析神经网络 Neural Networks

📒 在 Go 里用 CGO?这 7 个问题你要关注!

📒 分布式接口幂等性、分布式限流:Guava 、nginx和lua限流

📒 Go 探讨了 13 年,怎么解决再赋值的坑

📒 TypeScript Collections

用 TypeScript 编写的数据结构合集

https://github.com/basarat/typescript-collections

📒 Vite Rollup Plugins

Vite3 中使用 Rollup 插件的兼容性列表

https://github.com/patak-dev/vite-rollup-plugins

📒 Go语言从0到1实现最简单的数据库!

📒 一文读懂TypeScript类型兼容性

📒 Communicating Effectively As A Tech Lead

Addy Osmani 的新作,从 Simplify、Be concise and on point、Communicating with executives、Listen、Be proactive、Be thorough 和 Take notes 7 个维度介绍作为 TL 时如何高效沟通。

https://addyosmani.com/blog/communication-tech-lead/

📒 React Re-Renders

通过这篇文章,我学到了「两个误解」、「一个比喻」和「一个技巧」。

两个误解是,1)state 变更会让整个 app re-render?不是,state 变更只会让当前组件及其子组件 re-render,2)组件 re-render 是因为 props 变更?也不是,props 往上可以追溯到 state 变更,是 state 变更导致了子组件 re-render,而不是由 props 变更引起。

上述误解 2 的一个例外是 React.memo,应用 React.memo 后的组件只有 props 变更才会触发 re-render。你可能会想:为什么这不是默认行为?因为作为开发者,我们往往高估了重新渲染的成本。对于 props 很多且没有很多子组件的组件来说,相比 re-render,检查 props 是否变更带来的消耗可能更大。因此,如果对每个组件都进行 React.memo,可能会产生反效果。

一个比喻是,每次渲染都是由照相机拍摄的快照,React 通过玩「找不同」的游戏找出两张照片之间的差异,然后决定是否 re-render。而 React.memo 则是懒惰的摄影师,如果你要求他为完全相同的东西拍 5 张照片,它会拍 1 张照片并给你 5 份。只有当你的指令改变时,他才会拍下一张新的照片。

一个技巧是,借助 React Devtools Chrome 插件,在「设置 > Profiler」里开启「Record why each component rendered while profiling」,再通过录制的方式排查,就能知道每个 re-render 的原因。

原文链接:

https://www.joshwcomeau.com/react/why-react-re-renders/

中文翻译:

【第2709期】一份详尽的 React re-render 指南

📒 深入解读新一代全栈框架 Fresh

从定位上来看,Fresh 属于 Web 全栈开发框架,相比 Next.js 和 Remix, Fresh 有哪些值得一提的亮点:

  • Fresh 基于 Deno 运行时,由 Deno 原班人马开发,享有 Deno 一系列工具链和生态的优势,比如内置的测试工具、支持 http import 等等
  • 渲染性能方面,Fresh 整体采用 Islands SSR 架构(之前介绍的 Astro 也是类似),实现了客户端按需 Hydration,有一定的渲染性能优势
  • 还有一个比较出色的点是构建层做到了 Bundle-less,即应用代码不需要打包即可直接部署上线
  • 最后,不同于 Next.js 和 Remix,Fresh 的前端渲染层由 Preact 完成,包括 Islands 架构的实现也是基于 Preact,且不支持其它前端框架

开发者并不需要手写路由文件,Fresh 可以自动地生成服务端的路由到文件的映射关系。很明显 Fresh 实现了 约定式路由 的功能,跟 Next.js 类似。

深入解读新一代全栈框架 Fresh

- - + + \ No newline at end of file diff --git "a/2022/8\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/8\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 6be892c6e7..30f9867dea 100644 --- "a/2022/8\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/8\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月7日内容汇总

· 4 min read
加菲猫

📒 互联网公司都怎么实现分页的,拿 MySQL 使劲Limit

📒 拒绝 Go 代码臃肿,其实在这几块可以用下观察者模式

📒 记一次线上超时问题的发现、排查、定位以及解决过程

📒 这不会又是一个Go的BUG吧

📒 这三个 Go 水平自测题,手写不出来还是先老实上班吧

📒 不想Go 错误处理太臃肿,可以参考这个代码设计

📒 关于Go程序错误处理的一些建议

📒 你见过哪些目瞪口呆的 Java 代码优化技巧

📒 聊聊 13 种锁的实现方式

📒 代码越写越乱?那是因为你没用责任链!

⭐️ 社招后端21连问(三年工作经验一面)

📒 Spring Boot 实现接口幂等性的 4 种方案

📒 前端运维部署那些事

📒 rollup 最佳实践!可调试、编译的小型开源项目思路

tsc 可以只生成类型声明文件:

$ tsc  --emitDeclarationOnly --declaration --project ts.config.json --outDir dist/esm

rollup 最佳实践!可调试、编译的小型开源项目思路

📒 脚本任务执行器 —— npm-run-all 源码解析

📒 2022年值得推荐的React库!

📒 超大体量项目,微前端落地方案,看完后悔来找我

📒 如何解决前端常见的竞态问题

📒 Go语言中常见100问题-#88-1 Not using testing utility packages

📒 字节二面,差点没答好

📒 如何提高 TypeScript 的代码质量

📒 谁说 Mysql 单表最大 2000 W ?我硬要塞它 1 个亿!

📒 初探 Vue3 编译之美

📒 Go 1.19 is released

$ go install golang.org/dl/go1.19@latest

go 命令使用:https://pkg.go.dev/cmd/go

📒 GitHub Trending - TypeScript

https://github.com/trending/typescript

📒 【表达式计算】双栈 : 表达式计算问题的通用解法

📒 构建自己的 Web 框架

这篇文章解释了如何构建基于 React 的简易 Web 框架,并使用 Vercel 的 Build Output API 进行部署。

Build Output API 是一个基于文件系统的规范,用于生成 Vercel 部署的目录结构。框架作者可以将此目录结构实现为他们构建命令的输出,以便框架可以利用所有 Vercel 的平台功能(Serverless Functions,Edge Functions,路由,缓存等),Astro已经成功与 Vercel 集成。

https://vercel.com/blog/build-your-own-web-framework

📒 从零实现 React v18 的核心功能

📒 Roll your own JavaScript runtime

📒 用 TS 的类型系统实现一个 TS 类型系统

📒 像小说一样品读 Linux 0.11 核心代码

📒 前端食堂技术周刊第 46 期:Chrome 三方 cookie 计划、npm 引入更多安全增强功能、Awesome Bun

⭐️ 看一下 React 15.x 源码

https://github.com/Lucifier129/react-lite

📒 Go语言中常见100问题-#87 Not dealing with the time API efficiently

📒 用了TCP协议,就一定不会丢包吗

📒 【第2688期】关于低代码平台建设的思考与实践暨BPM表单设计器前端技术解析

- - + + \ No newline at end of file diff --git "a/2022/9\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/9\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 106ea0238c..ef2f711f2f 100644 --- "a/2022/9\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/9\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月11日内容汇总

· 28 min read
加菲猫

📒 CSS 如何实现文本换行

在开发的时候遇到一个问题,后端给的文本包含换行符 /n,前端如何实现换行展示。最开始以为只能通过富文本展示,但实际上 CSS 中有一个属性可以支持换行:

white-space: pre-wrap;

https://developer.mozilla.org/zh-CN/docs/Web/CSS/white-space

📒 Go 生态:Prometheus的四种指标类型,我终于搞懂了

📒 Go 语言创始人:复制亿点点代码比用别人轮子好!

📒 「Go工具箱」推荐一个实现进度条功能的工具:uiprogress

📒 给蚂蚁金服antv提个PR,以为是改个错别字,未曾想背后的原因竟如此复杂!

📒 前端相关文章汇总

https://medium.com/@bytefer

https://medium.com/pixel-and-ink/a-peek-at-userequest-hook-ba960cbddbf8

https://javascript.plainenglish.io/15-utility-types-that-every-typescript-developer-should-know-6cf121d4047c

https://blog.bitsrc.io/6-best-ways-to-create-a-new-react-application-57b17e5d331a

📒 Golang 技术方案

https://kms.netease.com/topics/topic/612/item/14727

https://kms.netease.com/article/27452#%E9%80%89%E5%9E%8B

https://github.com/NetEase-Media/ngo

📒 依赖注入简介

https://blog.codeminer42.com/dependency-injection-in-js-ts-part-1/

📒 JavaScript 模块中的默认导出很糟糕吗

https://www.lloydatkinson.net/posts/2022/default-exports-in-javascript-modules-are-terrible/

📒 VS Code 发布新版本

保持上下文的 "粘性滚动"不再是一个实验性功能。将与 TypeScript v4.8 一起发布。

https://code.visualstudio.com/updates/v1_71

📒 使用 gRPC 构建安全 API

一个允许两个 Node 应用程序通过 HTTP/2 和基于协议缓冲区的 gRPC 机制进行通信的演练教程。

https://snyk.io/blog/building-a-secure-api-with-grpc/

📒 最小化依赖关系的四种方法

在接连不断的供应链事故(和漏洞),或者查看了 node_modules 文件夹的最终体积后,你可能会想要将依赖关系保持在最低限度。这篇文章介绍了一些方法。

https://blog.appsignal.com/2022/08/31/4-ways-to-minimize-your-dependencies-in-nodejs.html

📒 安装并运行 bin 脚本

npm 包可以通过 package.json 的 bin 属性指定它们提供的 shell 脚本和可运行文件。Axel 深入研究了它的工作原理,并且提供了两种方式来安装提供此类脚本的软件包。

https://2ality.com/2022/08/installing-nodejs-bin-scripts.html

📒 Create Rust App: 用一行命令开启现代 Rust + React Web 应用程序

如果你想用 Rust 构建应用程序的后端,那么该库提供了一种 CRA 式的体验。它使用 Vite 并且新增了 SQLite 支持。

https://github.com/Wulf/create-rust-app

📒 何时使用 useLayoutEffect 而不是 useEffect

你的 UI 渲染过程中有烦人的闪烁吗?可能是你错误使用了其中之一的 Hook : 这与 Hook 是在浏览器绘制之前还是之后触发有关。

https://javascript.plainenglish.io/react-hooks-when-to-use-uselayouteffect-instead-of-useeffect-3271a96d881a?gi=622ccbf807f3

📒 美团二面:考我幻读,结果答的不好

📒 码住!Golang并发安全与引用传递总结

先看一个在Go中关于Map类型并发读写的经典例子:

var testMap  = map[string]string{}
func main() {
go func() {
for{
_ = testMap["bar"]
}
}()
go func() {
for {
testMap["bar"] = "foo"
}
}()
select{}
}

以上例子会引发一个Fatal error:

fatal error: concurrent map read and map write

产生这个错误的原因就是在Go中Map类型并不是并发安全的,出于安全的考虑,此时会引发一个致命错误以保证程序不出现数据的混乱。

Golang 如何检测 Map 并发异常?

对于查询操作,大致检查并发错误的流程如下:在查询前检查并发flag是否存在,如果存在就抛出异常。

if h.flags&hashWriting != 0 {
throw("concurrent map read and map write")
}

对于修改操作则如下:

  • 写入前检查一次标记位,通过后打上标记
  • 写入完成再次检查标记位,通过后还原标记
 //各类前置操作
....
if h.flags&amp;hashWriting != 0 {
//检查是否存在并发
throw("concurrent map writes")
}

//赋值标记位
h.flags ^= hashWriting
....
//后续操作
done:
//完成修改后,再次检查标记位
if h.flags&hashWriting == 0 {
throw("concurrent map writes")
}
//还原标记位取消hashWriting标记
h.flags &^= hashWriting

如何避免 Map 的并发问题?

go官方认为因为Map并发的问题在实际开发中并不常见,如果把Map原生设计成并发安全的会带来巨大的性能开销。因此需要使用额外方式来实现。

  1. 自行使用锁和map来解决并发问题
type cocurrentMap = struct {
sync.RWMutex
m map[string]string
}

func main() {
var testMap = &cocurrentMap{m:make(map[string]string)}
//写
testMap.Lock()
testMap.m["a"] = "foo"
testMap.Unlock()
//读
testMap.RLock()
fmt.Println(testMap.m["a"])
testMap.RUnlock()
}

这个方法存在问题就是并发量巨大的时候,锁的竞争也会带来巨量消耗,性能一般

  1. 使用sync.Map

sync.Map通过巧妙的设计来提高并发安全下Map的性能,其设计思路是通过空间换时间来实现的,同时维护2份数据,read&dirty。read主要用来避免读写冲突。

其数据结构如下:

type Map struct {
mu Mutex //锁
read atomic.Value //readOnly
dirty map[interface{}]*entry //*entry
misses int
}

type readOnly struct {
m map[interface{}]*entry
amended bool // true if the dirty map contains some key not in m.
}

type entry struct {
p unsafe.Pointer // *interface{}
}

使用示例如下:

var m sync.Map
// 写
m.Store("test", 1)
m.Store(1, true)

// 读
val1, _ := m.Load("test")
val2, _ := m.Load(1)
fmt.Println(val1.(int))
fmt.Println(val2.(bool))

//遍历
m.Range(func(key, value interface{}) bool {
//....
return true
})

//删除
m.Delete("test")

//读取或写入
m.LoadOrStore("test", 1)

这里对sync.Map的原理不做深入展开,只提几点特性:

  • read和dirty是共享内存的,尽量减少冗余内存的开销
  • read是原子性的,可以并发读,写需要加锁
  • 读的时候先read中取,如果没有则会尝试去dirty中读取(需要有标记位readOnly.amended配合)
  • dirty就是原生Map类型,需要配合各类锁读写
  • 当read中miss次数等于dirty长度时,dirty会提升为read,并且清理已经删除的k-v(延迟更新,具体如何清理需要enrty中的p标记位配合)
  • 双检查(在加锁后会再次对值检查一遍是否依然符合条件)
  • sync.Map适用于读多写少的场景
  • sync.Map没有提供获取长度size的方法,需要通过遍历来计算

切片类型 Slice 是并发安全的吗

与Map一样,Slice也不是并发安全的。但是在切片中并不会引发panic,如果程序无意中对切片使用了并发读写,严重的话会导致获取的数据和之后存储的数据错乱,所以这里要格外小心,可以通过加锁来避免。

切片除了并发有问题外,还有几点注意:

  • Go只会对基础值类型在传参中使用深拷贝,实际上对于Slice和Map类型,使用的是浅拷贝,Slice作为传参,其指向的内存地址依然是原数据
  • Slice扩容机制的影响:向Slice中添加元素超出容量的时候,我们知道会触发扩容机制,而扩容机制会创建一份新的【原数据】此时,它与浅拷贝获取到的变量是没有任何关联的

码住!Golang并发安全与引用传递总结

📒 ES6你用过哪些惊艳的写法

📒 用代码画时序图!YYDS

📒 面试官:mysql查询 limit 1000,10 和limit 10 速度一样快吗

📒 10 best practices to build a Java container with Docker

📒 How to create a systemd service in Linux

📒 Go 1.19.1 和 Go 1.18.6 终究还是来了

📒 5分钟自建数据库可视化平台,在线管理数据库也太方便了!

📒 匿名 iframe:COEP 的福音!

📒 这些强大的 JS 操作符,你都知道吗

📒 「Go工具箱」一个基于双向链表实现的LRU缓存工具

📒 这个 Go 开发的网络抓包工具,不仅好用还支持ES检索

📒 一道简单又有意思的 JavaScript 手写题 — 异步加法 asyncAdd

📒 高并发下的网络 IO 模型设计

📒 qiankun微前端改造实战(架构设计+代码实现)-超级详细vue代码干货篇!(伸手党福利)

📒 Go语言中常见100问题-#8 any says nothing

📒 读 Node.js 源码深入理解 cjs 模块系统

📒 当 React Query 遇见 React Router

React Router 6.4 即将正式发布,React Router 也加入了远程状态管理的数据获取游戏。本文将带你了解 React Router 和现有的远程状态管理库(如:React Query)之间的竞争和关联,作者认为他们是天造地设的一对。

https://beta.reactrouter.com/en/dev

https://tkdodo.eu/blog/react-query-meets-react-router

隔壁家 Vue Router 的数据获取相关提案 Vue Router Data Loaders。

https://github.com/vuejs/rfcs/discussions/460

📒 重新思考流行的 Node.js 模式和工具

Node.js 最佳实践、JavaScript 和 Node.js 测试最佳实践 的作者 Yoni Goldberg 对 Node.js 中的流行工具发出了灵魂拷问,并给出了他的思考:

  • Node-convictDotenv 更好;
  • 从 Controller 调用 Service 时,要尽量抽象 Service 的内容(多用心封装封装),尽可能屏蔽掉技术细节和复杂性,让看你代码的同学赏心悦目一些;
  • Nest.js 中万物皆可依赖注入,但简单点也许世界会更美好;
  • 不一定要用 Passport.js
  • SuperTest 的三合一语法有时候并没有那么好用;
  • Fastify 装饰器错误姿势
  • catch 子句的正确姿势;
  • 避免重复使用日志工具 Morgan
  • 减少使用 process.env.NODE_ENV 当作判断条件。

https://practica.dev/blog/popular-nodejs-pattern-and-tools-to-reconsider/

📒 8 月登陆网络平台的新内容

Firefox 104、Chrome 104、Chrome 105 发布稳定版本。

  • Chrome 104 新增 CSS transform 属性单独定义
  • Chrome 104 新增 媒体查询的新语法,支持比较运算符,更加符合人体工程学
  • Chrome 105 新增 容器查询和 :has(),响应式的最佳拍档
  • Chrome 105 新增 Sanitizer API,防止 XSS 攻击的灭菌武器
  • Chrome 105 新增 :modal 伪类
  • Firefox 104 支持 The findLast() 和 findLastIndex()

https://web.dev/web-platform-08-2022/

📒 pnpm v7.10.0

Time-based 依赖解析模式

  1. 直接依赖将安装其最低版本,比如 foo@^1.1.0,将会安装 1.1.0
  2. 间接依赖只会安装被选中的直接依赖在其发布时间点之前的版本

据作者说,这种模式是为了减少供应链攻击导致项目“噶”的风险,因为它能保证间接依赖不会比直接依赖更加新。这样如果间接依赖被攻击,也不会安装被攻击的版本。不过这种解析模式需要拿到 npm 的完整元数据,所以速度会很慢。解法是自建 Verdaccio,并将 registry-supports-time-field 设置为 true。

能减少供应链攻击的风险是好事,但是感觉这种模式本身存在很多问题,比如不遵守 semver 语义,虽然社区里很多项目都没有好好遵守 :)、或者当旧的间接依赖修复了某个 bug,但是有 bug 的版本还是会被安装。

https://github.com/pnpm/pnpm/releases/tag/v7.10.0

📒 前端食堂技术周刊第 51 期:pnpm v7.10.0、8 月登陆网络平台的新内容、重新思考流行的 Node.js 模式和工具、打包 JavaScript 库的

📒 从Vuex到Pinia

📒 程序员有很厉害,不外传的代码吗?可以运行,但不能动的那种!

📒 你想知道的前后端协作规范都在这了

📒 1.3w字,一文详解死锁!

📒 【第2724期】前后端数据接口协作提效实践

📒 去字节面试,直接让人出门左拐:Bean 生命周期都不知道!

📒 聊聊数据库建表的15个小技巧

📒 如何优化你的 Node.js API

📒 金九银十Go面试题进阶知识点:select和channel

📒 禁用 Cookie 后会怎样

会报错!解法很简单也很粗暴,就是加 try…catch。

https://blog.tomayac.com/2022/08/30/things-not-available-when-someone-blocks-all-cookies/

📒 现代 JS 库打包

这是一篇关于如何打包 JavaScript 库的现代化指南,介绍了维护 JavaScript 库的一些基础知识和最佳实践,推荐作为入门阅读。

https://github.com/frehner/modern-guide-to-packaging-js-library

📒 Error Boundary 指南

虽然理想情况下是在生产之前捕获错误,但有些错误是会躲过测试的,比如网络错误,而如果没有正确处理,这些错误会导致 React 声明周期崩溃,导致白屏,并最终影响你的用户。正确的方式是提供适当的视觉反馈和潜在的行动指引(例如:重试机制)来优雅的处理这些错误。

你可能会有几个疑问。1)为啥会白屏?因为从 React 16 开始,没有被捕获的错误将导致整个 React 组件树的卸载。2)为啥 try.catch 不行?因为 React Hooks 执行是异步的,捕获不了。

解法当然就是用 React 官方提供的 Error Boundary 了,通过 Error Boundary 把组件包起来,可以想象成是包了一层 try…catch,组件报错会到此为止,不会再往上报。一个简单的 ErrorBoundary 如下。

class ErrorBoundarySimple extends React.Component {
state = { hasError: false };
componentDidCatch(error: unknown) {
// report the error to your favorite Error Tracking tool (ex: Sentry, Bugsnag)
console.error(error);
}
static getDerivedStateFromError(error: unknown) {
// Update state so the next render will show the fallback UI.
return { hasError: true };
}
render() {
if (this.state.hasError) { return <p>Failed to fetch users.</p>; }
return this.props.children;
}
}

但是官方的 Error Boundary 其实有缺陷,他不支持以下场景的报错,包括 Event handlers、异步代码比如 setTimeout 或 requestAnimationFrame 回调、SSR、Error Boundary 自己抛的错。同时,我们可能还需要提供重试机制等行动指南。解法是用 react-error-boundary 这个库。

react-error-boundary 如何支持重试?他提供的 ErrorBoundary 组件可以配置 FallbackComponent 组件,而这个组件有 error 和 resetErrorBoundary 两个 props,后者用于重试。

import { ErrorBoundary } from 'react-error-boundary';
function ErrorFallback({ error, resetErrorBoundary }) {
return <>
<pre>error.message</pre>
<button onClick={resetErrorBoundary}>retry</button>
</>
}
export default function App() {
return <ErrorBoundary FallbackComponent={ErrorFallback}><Users /><ErrorBoundary>;
}

react-error-boundary 如何捕获 React 生命周期外的错误?比如 Event Handler 和异步代码。react-error-boundary 提供 useErrorHander hook,他会返回处理错误的函数。

import { useErrorHandler } from 'react-error-boundary';
export default App() {
const handleError = useErrorHandler();
function handleSubmit(event) {
fetch(xxx).then(...).catch(e => handleError(e));
}
// do render
}

https://meticulous.ai/blog/react-error-boundaries-complete-guide/

📒 10 个 React 新手陷阱

React 是 unopinionated 的,同样的问题会存在许多不同的解法,这给开发者留下了大量的空间来用自己愚蠢的想法把事情搞砸。在今天的文章中,我们将看看 React 中的 10 个陷阱(反模式),以及改进我们代码的技巧和窍门,同时也可以为前端技术面试做准备。

1、巨型组件。就是一个组件内很大,通常是因为不知道如何组织代码,或者不想把时间浪费在组织代码上。这样的组件很难理解、重构和测试。通过 WebStorm 的「Refactor - Move」或者 VSCode 的 Glean 插件快速提速代码到文件,可以节省你不少时间。

2、嵌套陷阱。不要在组件内定义子组件,比如 function Parent() { const Child = () => <div>Child</div>; return <><Child /></> },解法是把 Child 定义提到外面。

3、没有用 useMemo/useCallback。遇到重计算的点,每次 re-render 会重新执行导致性能消耗严重,比如 const total = expensiveCal(count)。解法是用 useMemo 避免重复计算,比如 const total = useMemo(() => expensiveCal(count), [count])。如果遇到函数,记得切换到 useCallback。

4、无意义的 div 元素。React 组件只能由一个根组件,当需要渲染多个相邻的元素时,你可能会引入 div 元素。但这不是必要的,不必要的 div 元素可能导致可访问性和 CSS 样式问题。更好的做法是用 Fragment 组件,比如 <><Foo /><Bar /></>

5、混乱的文件。随着组件越来越多,在一个文件中导出多个组件是「诱人」的。但是这样,也会很快让事情变得复杂。更好的做法是有一套自己的文件组织规范,比如一个组件一个文件,或者一个组件一个文件夹,同时在文件夹下可能还会有自己的测试文件等。

6、巨大的 Bundle 产物。大型复杂应用的最大问题之一就是产物很大,这会让页面加载变慢,因为浏览器需要很长时间来下载、解析和执行 JavaScript Bundle 产物。解法是应用内置了 code splitting 功能的框架,或者使用 Suepense + React.lazy + import()。

7、Prop Drilling。当上层组件中持有 state,而一个深度嵌套的组件需要使用这个 state 时,一种做法是用 props 透过中间组件一层层往下传,而实际上中间组件并不需要他们,这就是 Prop Drilling。解法是用 Redux 或其他数据流工具,或者使用 Context。

剩下 3 个是 Prop Plowing、Try Some Curry 和 Code Smarter,感觉不太重要,是为了凑 10 个加的,我就不介绍了,有兴趣的可以查看原文。

https://medium.com/@imranfarooq0306/10-react-traps-to-avoid-as-react-developer-5570808e346b

📒 useMemo + useCallback

这是一篇很好的 useMemo 和 useCallback 入门文章,但没有引入啥新知识,我就不展开了。

https://www.joshwcomeau.com/react/usememo-and-usecallback/

📒 React 18 SSR 流式渲染

React 18 SSR 流式渲染可基于 Suspense + Lazy、renderToPipeableStream 和 hydrateRoot 实现。Suspense + Lazy 在客户端用于代码拆分和懒加载,在服务端则用于流式渲染,renderToPipeableStream 用于流式返回数据,hydrateRoot 用于在流式返回后就开始注水而无需等到全部内容都返回。

以上完成了流式渲染,但还有个问题需要解,即「数据怎么获得」?并且需要同时考虑服务端和客户端。作者给的解是还处于实验阶段的 Data Fetching API。

const resource = fetchProfileData();

function Posts() {
const posts = resource.posts.read();
// render with posts
}

目前要支持 Data Fetching API,可将 Promise 包装成 Data Fetching API。

function wrapPromise(p) {
let status = 'pending';
let result;
let suspensder = p.then(r => {
status = 'success';
result = r;
}).catch(e => {
status = 'error';
result = e;
});
return {
read() {
if (status === 'pending') throw suspensder;
else if (status === 'error') throw result;
else if (status === 'success') return result;
}
}
}

Suspense 识别 Data Fetching 的 loading 状态是基于 read 方法的返回值。如果 throw promise 即还在 loading,如果 throw error 则出错,如果返回数据则完成 loading。

在 React 18 下,如何实现产品级的 SSR 和流式渲染

📒 开源推荐

1. clean-pkg-json

NPM 发包时不需要的 package.json 字段

https://github.com/privatenumber/clean-pkg-json

2. ts-prune

用于找到 TypeScript 项目未使用的 export 信息,消除 dead code

https://github.com/nadeesha/ts-prune

3. module-federation/typescript

Typescript Types Support For Module Federation

https://github.com/module-federation/typescript

4. React Router 6.4 将于下周发布

📒 Go 眼中的文件系统是什么? io.FS

Go 理解的文件系统,只要能实现一个 Open 方法,返回一个 File 的 interface ,这个 File 只需要实现 Stat,Read,Close 方法即可。

// 文件系统的接口
type FS interface {
Open(name string) (File, error)
}

// 文件的接口
type File interface {
Stat() (FileInfo, error)
Read([]byte) (int, error)
Close() error
}

有没有发现,OS 的 FS 已经满足了条件。所以,Go 的 FS 可以是 OS 的 FS ,自然也可以是其他的实现。

Go 在此 io.FS 的基础上,再去扩展接口,增加文件系统的功能。比如,加个 ReadDir 就是一个有读目录的文件系统 ReadDirFS :

type ReadDirFS interface {
FS
// 读目录
ReadDir(name string) ([]DirEntry, error)
}
tip

以上是 Golang 接口继承的写法,ReadDirFS 接口继承了 FS 接口,同时扩展了 ReadDir 方法。注意,Golang 是不支持面向对象的。

加个 Glob 方法,就成为一个具备路径通配符查询的文件系统:

type GlobFS interface {
FS
// 路径通配符的功能
Glob(pattern string) ([]string, error)
}

加个 Stat ,就变成一个路径查询的文件系统:

type StatFS interface {
FS
// 查询某个路径的文件信息
Stat(name string) (FileInfo, error)
}

这些非常经典的文件系统的定义 Go 在 io/fs 里面已经做好了。

我们的目标是实现一个 Go 的 FS ,这个定义已经在 io.FS 有了。我们只需要写一个结构体,实现它的方法,那么你就可以说这是一个 FS 了。

这里其实就可以有非常多的想象空间,比如,可以是 OS 的 FS,也可以是 memory FS ,hash FS 等等。网上有不少例子。但其实标准库已经有一个最好的例子,那就是 embed FS 。

我们来看下 embed 怎么实现一个内嵌的文件系统。embed 的实现在 embed/embed.go 这个文件中,非常精简。

首先,在 embed package 里定义了一个结构体 FS ,这个结构体将是 io.FS 的具体实现。

// 作为具体 FS 的实现
type FS struct {
files *[]file
}

// 代表一个内嵌文件
type file struct {
name string
data string // 文件的数据全在内存里
hash [16]byte // truncated SHA256 hash
}

embed 里面的 FS 结构体只需要实现 Open 这个方法即可:

// Open 的具体实现
func (f FS) Open(name string) (fs.File, error) {
// 通过名字匹配查找到 file 对象
file := f.lookup(name)
// 如果没找到
if file == nil {
return nil, &fs.PathError{Op: "open", Path: name, Err: fs.ErrNotExist}
}
// 如果是目录结构
if file.IsDir() {
return &openDir{file, f.readDir(name), 0}, nil
}
// 找到了就封装成 openFile 结构体
return &openFile{file, 0}, nil
}

上面的 Open ,如果是文件的化,返回的是一个 openFile 的结构体 ,作为 io.File 接口的具体实现:

// 代表一个文件的实现
type openFile struct {
f *file // the file itself
offset int64 // current read offset
}
func (f *openFile) Close() error { return nil }
func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil }
func (f *openFile) Read(b []byte) (int, error) {
// 判断偏移是否符合预期
if f.offset >= int64(len(f.f.data)) {
return 0, io.EOF
}
if f.offset < 0 {
return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid}
}
// 从内存拷贝数据
n := copy(b, f.f.data[f.offset:])
f.offset += int64(n)
return n, nil
}

如上,只需要实现 Read,Stat,Close 方法即可。这就是一个完整的、Go 层面的 FS 的实现。

tip

Go 的 FS 封装有啥用呢

  • 单测方便了,可以直接对应用进行测试,不必依赖底层实现
  • 封装出一个 io.FS 的抽象,意图和 OS 的 FS 解耦,类似 embed FS 这种非 OS 文件系统的需求,可以有方法扩展了

Go 眼中的文件系统是什么? io.FS

📒 对 Go2 错误处理提案的批判

📒 微服务配置中心, 这个方案 Go 里用起来不输 SpringCloud

📒 Go语言爱好者周刊:第 158 期

- - + + \ No newline at end of file diff --git "a/2022/9\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/9\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e8cf1c8b60..c9f7f21717 100644 --- "a/2022/9\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/9\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月18日内容汇总

· 9 min read
加菲猫

📒 Babel 插件:30分钟从入门到实战

⭐️ 全面解读!Golang中泛型的使用

📒 Umi4.0多页签设计

📒 V8 是如何执行 JavaScript 代码的

📒 「Go工具箱」推荐一个非常简单的深拷贝工具:deepcopy

📒 ECMAScript 2023将新增的9个数组方法

📒 关于 React Re-Render

📒 Go:基于 Redis 实现的延迟队列详解

📒 这个帮你理清Go程序调用栈的工具,1.17以上可用

📒 一起来实现一个Antd Form

📒 如何检测 JavaScript 原生函数是否被打过 "猴子补丁"

📒 鹅厂后台大佬教你Go内存管理!

📒 Plasmo Framework:次世代的浏览器插件开发框架

⭐️ 不得不知道的Golang之sync.Map解读!

📒 前端食堂技术周刊第 52 期:Babel 7.19.0、Fresh 1.1、React为什么重新渲染、新的 Web 性能指标

📒 我被骂了,但我学会了如何构造高性能的树状结构

📒 「Go工具箱」一个将非负整数转换成唯一、无序ID的工具:hashids

📒 【图书】程序员的底层思维

📒 作为大厂面试官,原来这种学生最吃香!

📒 Why Storybook in 2022

https://storybook.js.org/blog/why-storybook-in-2022/

📒 如何像gitlab-runner那样将Go应用安装为系统服务

📒 React Router v6 完全指南

📒 【第2726期】开发模式 "Development Mode" 是如何工作的

📒 你信吗?Go 泛型竟然已经被迅速采用

📒 做一个不崩溃的核酸系统到底有多难

📒 写给前端仔的自动化测试入门小作文

📒 「Go工具箱」一个兼具单机和集群模式的轻量级限流器:throttled

📒 CSR 最佳实践

随着 Next.js 和 Remix 的流行,SSR 看似已成为 React 社区的首选。但如果你用 SSR 是为了性能和 SEO,那可能可以重新考虑下,因为 CSR 也能做到。

关于性能。

1、减少尺寸。1)少用依赖,2)选择轻量级的依赖,比如用 day.js 代替 moment,用 zustand 代替 redux toolkit。

2、缓存。利用 webpack 的 cacheGroups 设置,提取依赖,当依赖没有变更时,hash 值不变,提高缓存利用率。推荐配置如下,让每个依赖拥有单独的文件和 hash,这样单个依赖变更时不会影响其他依赖。

optimization: {
runtimeChunk: 'single',
splitChunks: {
chunks: 'initial',
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
// 加这句可以避免异步 chunk 的 vendor 重复问题,比如 a 和 b 都依赖 moment,不加这句 moment 会被打两遍而不是被提取出来
chunk: 'all',
// 让每个依赖拥有单独的文件和 hash
name: ({ context }) => (context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/) || [])[1]
}
}
}
}

3、Code Splitting。通常有两种,1)基于路由的 Code Splitting,当用户访问页面 A 时无需加载页面 B、C、D 的脚本,2)大依赖 Code Splitting,让整体页面更快出来,让大依赖的部分不影响页面渲染速度。

4、预加载异步 Chunk。主要避免出现下图中最后一个资源文件的瀑布流现象,思路是生成和路由对应的 assets 表,然后在 HTML 最前面加入「匹配路由生成 link preload 标签」的脚本。

5、生成静态数据。在 build 阶段从 CMD 或服务器上把数据拉下来,存成 json 或其他格式,用户请求时就只需从本地读取即可,访问本地或就近的 CDN 肯定比访问远程服务器更快。如果要重新生成数据,重新跑 build 或者重新执行脚本就好。

6、预加载数据。这和「4」类似,4 预加载的是 JS,这里需要预加载数据。做法也和「4」类似,把数据请求和路由做关联,然后运行时「匹配路由生成针对数据请求的 link preload 标签」。

7、预加载其他页面的数据。当 hover(desktop)或进入 viewport(mobile)时,做的对应 Link 的 preload as fetch。

8、避免序列化的渲染。比如一个应用有 Nav 导航 + 主内容,是应该先出导航再出主内容,还是应该导航和主内容都好了之后一起出?作者觉得应该是后者,实现方法是通过调整 Suspense 元素的位置。这一点其实我是有疑问的,我觉得前一种渲染方式也挺好,避免长时间的白屏。

9、Transition 切换页面(依赖 React 18)。当我们切换页面时,有两个选择。1)切过去,等 loading,渲染;2)等 loading,切过去+渲染。基于 React 18 的 useTransition 可以实现后者,代码如下。

const n = useNavigate();
startTransition(() => n(to));

10、预加载异步页面。作者介绍了个方法,把 React.lazy 封一下,在 window load 事件之后延迟自动执行。

const lazyPrefetch = chunk => {
window.addEventListener('load', () => {
setTimeout(chunk, 200)
}, { once: true });
return React.lazy(chunk);
}

11、Module Federation。

https://github.com/theninthsky/client-side-rendering

📒 人手 10x 工程师

先看两种 10x 工程师。1)写 10x 代码的工程师,但这类工程师对于负责 Review 他代码的同学会很有挑战,2)能评估复杂问题,站在技术前沿,先人一步拿出优雅解决方案的工程师,这类工程师一个团队通常没有几个。

你可能会觉得这两种都比较遥远,别灰心,还有一种 10x 工程师。他关注开发体验(dx)和团队健康,关注小但有倍增效应的事。比如添加缓存以加快持续集成,比如定期修复项目 setup 说明,比如增加 precommit 或加快自动化测试后让故障发生在本地而不是 CI 环境。这些变化随着时间推移所产生的累积效应,虽然不是你自己做了 10x 的工作,但通过提高一群工程师的生产力也能达到 10x 提效。

https://typeofnan.dev/10x-engineering-for-the-rest-of-us/

📒 开源相关

  • Next.js 发布 12.3,Fast Refresh 支持 .env 和 tsconfig.json,检测到 ts 或 tsx 文件自动完成 TypeScript 配置、SWC Minifier Stable
  • Meta 开源 shumai,基于 Bun + Flashlight 的 JavaScript 机器学习库
  • module-federation/nextjs-mf,让 Next.js 支持 Module Federation,目前 CSR Only
  • gradejs/gradejs,GradeJS 无需源码即可分析生产阶段的 webpack 产物构成,包括潜在问题,依赖了哪些包,等等

📒 Go语言爱好者周刊:第 159 期 — 这道题目有点意思

- - + + \ No newline at end of file diff --git "a/2022/9\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/9\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 317f2e8088..2bc6a8b7cf 100644 --- "a/2022/9\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/9\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月25日内容汇总

· 8 min read
加菲猫

📒 前端也要懂算法,不会算法也能微调一个 NLP 预训练模型

📒 Go 语言官方依赖注入工具 Wire 使用指北

📒 超干货!彻底搞懂Golang内存管理和垃圾回收

📒 好用的map-struct转换库 mergo

⭐️ 分享三个阅读 Go 源码的窍门

⭐️ 聊聊分布式一致性!

📒 深入浅出带你走进Redis!

📒 工作中常见的 6 种设计模式,你用过几种

📒 基于 Next.js 和 tailwind.css 搭建博客

https://tailwindcss.com/docs/typography-plugin#adding-custom-color-themes

使用 Next.js 和掘金 API 打造个性博客

⭐️ 如何保障 MySQL 和 Redis 的数据一致性

📒 electron-vite:新一代 Electron 开发利器,带你轻松玩转 Electron

📒 create-vite 原理揭秘

📒 字节二面:Redis 的大 Key 对持久化有什么影响

📒 美团三面:一直追问我, MySQL 幻读被彻底解决了吗

⭐️ Go学设计模式--原型模式的考查点和使用推荐

📒 使用viper实现yaml配置文件的合并

📒 「Go工具箱」一个简单、易用、安全的类型转换工具

📒 探索组件在线预览和调试

📒 Golang 面试相关

LeetCode 刷题指南

https://www.yuque.com/go-interview/set/xq5788

面试题库收集

https://www.yuque.com/go-interview/set/interview-index

📒 已入字节的大佬各厂三年Go面经

📒 掌握了这一招,Go的多版本管理不用愁

📒 react-spring 如何用旁路设计赋能前端交互

📒 解读 State of CSS 2022,让你早点下班的新特性

📒 从useEffect看React、Vue设计理念的不同

📒 前端食堂技术周刊第 53 期:React Router 6.4、VS Code August 2022、2022 Google 谷歌开发者大会、Meta 开源

📒 语雀桌面端技术架构实践

📒 package.json 配置完全解读

📒 函数组合

函数组合有很多场景,这篇文章介绍了如何把他用在 React 项目中,换一种代码组织方式,让代码更简洁、优雅和可扩展。

假如你有一个项目,项目里有这样的需求,1)检查用户登录状态,2)特性检测按需渲染,3)埋点日志需求,4)layout 渲染。你可能会这么写。

const App = () => {
useEffect(() => {
if (!user.isLogin) signIn()
}, []);

useEffect(() => {
log({ pageName, uid })
}, []);

return user.isAdmin
? <AdminComponent />
: <>{ features.includes('foo') && <Foo /> }<Conent /></>;
}

这里的 问题是,如果有多个组件都需要类似的逻辑,你可能就要复制粘贴了。解是用 Provider + HOC + Composition + Currying。

const App = withProviders({ showFooter: false })(() => {
return <Content />;
});

withProviders 如下。

const withProviders = (options) =>
compose(
withUser,
withFeatures,
withLogger,
withLayout(options)
);

withLogger 如下。

const withLogger = (WrappedComponent) => {
return (props) => {
useEffect(() => { log({ pageName, uid }) }, []);
return <WrappedComponent {...props} />;
};
}

https://medium.com/javascript-scene/why-every-react-developer-should-learn-function-composition-23f41d4db3b1

📒 初级程序员 vs. 高级程序员

要分别初级程序员和高级程序员,其中一点是看他们关注的是「软件」还是「系统」。

初级工程师关心编写软件的问题。 他们重视代码质量,采用最佳实践,努力采用最先进的技术。他们在学习新技术方面投入了大量时间。对他们来说,最终的目标是创建优雅的、可执行的、可维护的软件。

高级工程师关心的是建立系统。 对他们来说,创建软件只是其中的一个步骤。首先,他们会质疑这个软件是否需要被建造。他们会问它能解决什么问题,为什么要解决这些问题。他们询问谁将会使用这个软件,在什么规模上使用。他们考虑软件将在哪里运行,以及他们将如何监测它是否正常工作。他们还决定如何衡量该软件是否真正解决了它应该解决的问题。

https://codewithstyle.info/software-vs-systems/

📒 React Router 6.4

React Router 发布 6.4,大量新功能,包括数据加载/突变/重新验证、错误/中断/竞争条件处理以及支持 Suspense 的加载/骨架 UI 等。

1、路由创建方式变更,之前用 BrowserRouter + Routes,现在改用 createBrowserRouter 创建路由和 RouterProvider 渲染路由。

<RouterProvider router={createBrowserRouter([
{ path: '/', element: <Root /> }
])} />

2、路由级的数据流,基于 loader + action + Form,在路由配置中声明 loader 和 action,然后如下使用即可。

处理数据加载。

// 声明数据
export async function loader() {}
// 使用数据
useLoaderData();

处理数据提交。

// 使用定制表单元素
<Form />
// 处理表单提交
export async function action() {}

3、延迟数据加载方案,基于 defer + useAsyncValue/Await。由于考虑到 CLS(Content Layout Shift),默认没有做延迟数据加载,开发者可以手动开启。用哪种方式其实是需要权衡的,各有利弊。

// 1、loader 里延迟返回
export async function loader() {
return defer({ count: 0 });
}

// 2、渲染时用 Await 延迟渲染,不阻塞 Suspense 的瀑布流
<Await resolve={data.count} errorElement={<p>error load count</p>}>
{(count) => <p>{count}</p>}
</Await>

4、ScrollRestoration 可以模拟浏览器在加载器完成后位置变化时的滚动恢复,以确保滚动位置恢复到正确的位置,甚至跨域。

<ScrollRestoration />

📒 Go 代码风格没人喜欢?不对,Gofmt 是所有人的最爱...

⭐️ 程序里对象很深很大,可以用这个设计模式缓解一下

📒 「Go工具箱」推荐一个变量调试神器:go-spew

📒 【第2734期】JavaScript & Node.js 的测试最佳实践 - 第二章:后端测试

📒 Go语言爱好者周刊:第 160 期 — 竟然这么多人不理解 map 的 make 含义

📒 简单的 redis get 为什么也会有秒级的延迟

📒 golang net/url 路径穿越漏洞

- - + + \ No newline at end of file diff --git "a/2022/9\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2022/9\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3d712cf8c7..02bb9e87cb 100644 --- "a/2022/9\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2022/9\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,8 +11,8 @@ - - + +
@@ -24,7 +24,7 @@ 6、「安全」Tauri 胜。Tauri 内置大量安全功能,可以明确启用或禁用某些 API。Electron 中则可以完全访问 Node 的 API,所以相比来说更容易被黑客利用。 7、「自动更新」Electron 胜。Tauri 和 Electron 都内置了自动更新器,而 Tauri 的相对简单,同时需要维护依赖并手动更新 JSON,而 Electron 可基于 electron-updater 并直接从 Github 发布的二进制文件中提取,要方便很多。 8、「开发体验」Tauri 胜。基于 Tauri CLI 就会包含热重载、为所有平台构建你的应用程序、生成应用程序图标等全部功能,而 Electron 啥都没有提供,只有框架本身。

https://www.levminer.com/blog/tauri-vs-electron

📒 father 4 正式发布

father 4 的具备如下核心特性:

📒 3种方式!Go Error处理最佳实践

📒 超大体量项目,微前端落地方案,看完后悔来找我

📒 快速搭建 SpringCloud Alibaba Nacos 配置中心!

📒 k8s下微前端如何做金丝雀发布

- - + + \ No newline at end of file diff --git a/2022/archive/index.html b/2022/archive/index.html index 7364fb7e99..a1915f3124 100644 --- a/2022/archive/index.html +++ b/2022/archive/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

Archive

Archive

2022

- - + + \ No newline at end of file diff --git a/2022/index.html b/2022/index.html index 8e785fe994..5684fe62ec 100644 --- a/2022/index.html +++ b/2022/index.html @@ -11,15 +11,15 @@ - - + +
Skip to main content

· 10 min read
加菲猫

📒 相关文章推荐

Dr. Axel 提出两个提案:Iterator Helpers 和 Set Methods — 本篇文章所讲的内容值得你去研究! Dr. Axel 提出了两个具有前瞻性的 ECMAScript 提案,并在本文中介绍了它们,以及解释了为什么它们会对 JavaScript 开发者有用的原因。第一个提案是关于 iterator helpers (用于处理可迭代数据的新的实用方法),第二个提案是关于 Set methods,它扩展了 ES6 的 Set 对象

https://2ality.com/2022/12/iterator-helpers.html

构建同构 JS 库的五个挑战 — 在 JS 中,同构的意思就是在服务端和浏览器端通过最少的适配使用相同的代码

https://doordash.engineering/2022/12/06/five-challenges-to-building-an-isomorphic-javascript-library/

Next, Nest, Nuxt… Nust? — “这篇博客文章是为在寻找新的 JavaScript 后端框架的人准备的。”如果这些框架的名字你分不清,那么这篇文章就是为你准备的。Marius 解释了 Next 和 Gatsby 等系统做了什么,并触及了一些不同之处

https://www.twilio.com/blog/comparing-nextjs-nestjs-nuxt-gatsby

优化 INP 指标,提升用户体验 — 文章仔细介绍了INP指标,如何计算以及如何优化。INP 指标 -— 从用户交互到页面渲染下一帧的时间差,越短越好

https://web.dev/optimize-inp/

我们是如何为 Monorepo 项目配置 pnpm 和 Turborepo 的

https://nhost.io/blog/how-we-configured-pnpm-and-turborepo-for-our-monorepo

Node 之道:关于设计、架构与最佳实践 — “全图鸟瞰” 式的总结是非常受欢迎的。我们都在为架构设计探索新的设计思路、处理之道。作者在文中总结了在构建高质量 Node 应用程序时,所获得的所有来之不易的最佳实践

https://alexkondov.com/tao-of-node/

新选型流行的 Node 开发模式与工具

https://practica.dev/blog/popular-nodejs-pattern-and-tools-to-reconsider/

制作现代 npm 包的最佳实践 — 手把手引导如何基于最新的最佳实践创造自己的 npm 包。如果你已经掌握了,也值得再次访问,这是一个很好的、常看常新的资源

https://snyk.io/blog/best-practices-create-modern-npm-package/

SWR v2.0: 用于数据获取的 React Hooks — SWR(Stale-While-Revalidate) 的第二个主要版本包括新的 Mutation API、改进的乐观更新 UI 功能、新的开发人员工具以及改进的对并发渲染的支持

https://swr.vercel.app/blog/swr-v2

避免这些常见的 useState 陷阱 — “你首先需要了解 useState 的潜在问题,以便于避免它们,” 所以 Johannes 带我们用一个案例来深入分析和了解

https://profy.dev/article/react-usestate-pitfalls

Josh W Comeau 更新了他的热门文章 - Why React Re-Renders

https://www.joshwcomeau.com/react/why-react-re-renders/

用 Three.js 和 react-three-fiber 创建一个 3D 的圣诞体验

https://www.youtube.com/watch?v=tyNt9Qse1mg

📒 Learning Go by examples: part 7 - Create a cross-platform GUI/Desktop app in Go

📒 解决 Antd 样式预设影响全局样式问题

注意 Antd 打包默认会带一套 global.less 样式预设,在某些老工程用的时候,样式预设可能会影响全局样式。由于 Antd 的组件样式都是建立在这个格式化后的样式上的,不引入这个文件则会导致组件内部样式出问题。解决方案是 收敛 global.less,并保证外部的全局样式无法轻易覆盖 antd 的样式

首先需要限定 global.less,手动套一层作用域:

node_modules/antd/lib/style/core/index.less
*[class*='ant-'] {
@import 'global.less';
}

antd 相关的组件都至少会有一个以 ant- 开头的 class,我们只要利用好这个特点及 CSS 属性选择器即可达到目的

这里存在一个问题,如何将 Antd 的 global.less 文件替换为自己的模块,有两种解决方案:

  • patch-package 打补丁,但是如果第三方库体积过大会 OOM
  • 另一种思路是用 NormalModuleReplacementPlugin 在构建阶段去替换模块

下一步是提升组件样式的权重,此举还能间接提升所有 antd 的样式的权重,避免外部的全局样式对 antd 造成侵入。

既然是改样式,那就用 CSS 界的 babel —— PostCSS,写个 PostCSS 插件,将所有 .ant 开头的类选择器都同样升高即可。利用的是 postcss-selector-parser 这个 PostCSS 官方提供的解析选择器的库,过滤出「第一个以 ant- 开头的类选择器」,在其前面添加一个属性选择器 [class*='ant-'],如果这个选择器排在当前 rule 的第一个或者前面是一个 combinator,则再加一个通配符 *

如何优雅地彻底解决 antd 全局样式问题

📒 对于“前端状态”相关问题,如何思考比较全面

📒 二十张图片彻底讲明白Webpack设计理念,以看懂为目的

📒 【第2820期】去哪儿网用户体验之端上优化实践

📒 有趣的 Go HttpClient 超时机制

📒 JavaScript 中文周刊 #68 - 如何优化 INP 指标,提升用户体验

📒 原生拖拽太拉跨了,纯JS自己手写一个拖拽效果,纵享丝滑

📒 【综合笔试题】难度 4/5,有一定代码量的图论搜索题

📒 别乱用了,用新的。Go SliceHeader 和 StringHeader 将会被废弃!

⭐️ 看了这篇你会发现,你是懂Go内存分配的

📒 你构建的代码为什么这么大

📒 Go语言中常见100问题-#24 Not making slice copies correctly

📒 理解 Go generate

https://go.dev/blog/generate

https://blog.carlmjohnson.net/post/2016-11-27-how-to-use-go-generate/

📒 专注性能的多端研发框架 - ice.js 3 正式发布!

📒 【综合笔试题】难度 1.5/5,常规二叉树爆搜题

📒 低代码没有做到的事情,ChatGPT做到了

⭐️ Vue3生命周期Hooks的原理及其与调度器(Scheduler)的关系

📒 开始做请求方案的调研,这是 Umi/Bigfish 今年最佳实践的最后一个拼图。第一个深入看的是 React Query,翻了 Practical React Query | TkDodo's blog 系列文章后做了两篇笔记。然后对 React Query 路转粉,学习到不少关于请求的细节处理思路,推荐大家都好好读一读

https://tkdodo.eu/blog/practical-react-query

📒 DebugBear 更新了一篇《2022 In Review: What’s New In Web Performance?》 总结 2022 年 Web 性能领域的变化,包括提升资源优先级的 Priority Hints、Chrome 不做 OSCP 证书校验后的性能提升、用于衡量交互后响应速度的 INP 指标、Google 将 Core Web Vitals 纳入排名因素、Chrome 浏览器支持前进后退缓存、HTTP/3 标准化、Chrome DevTool 和 performance API 会提示哪些资源会 block、用于提前提供资源列表的 103 响应、Chrome 108 开始支持全页面预渲染、Safari 支持 AVIF、Safari 原生支持图片懒加载

https://www.debugbear.com/blog/2022-in-web-performance

📒 StackDiary 更新了《The Most Popular Node.js Frameworks in 2022》和《The Most Popular CSS-in-JS Libraries in 2022》,分别由 Next.js 和 Styled-Components 拔得头筹,Styled-Components 已连续 4 年第一

https://stackdiary.com/node-js-frameworks/

https://stackdiary.com/css-in-js-libraries/

📒 发现一本免费的算法书《Hello 算法》,没细看,感兴趣可关注

https://www.hello-algo.com/

📒 React 的 useEvent RFC 里,useEvent 更名为 useEffectEvent,Event function 更名为 Effect Event

https://github.com/reactjs/reactjs.org/pull/5373

📒 看到 Codux 发布,来自 Wix 联合创始人的作品。这是一个 React 组件可视化编辑器,类似 Storybook,特点是和代码之间双向同步

https://dev.to/codux/introducing-codux-15j5

📒 React Router 发布 6.5,支持 Optional Route Segments。在任何 path 段末尾添加一个 ? 会使整个路径段成为可选,对静态段和动态参数都有效

https://github.com/remix-run/react-router/releases/tag/react-router%406.5.0

📒 Tauri Mobile 发布 Alpha,支持 iOS 和 Andriod,需要用 2.0.0-alpha.0 版本的依赖

https://tauri.app/blog/2022/12/09/tauri-mobile-alpha/

📒 MDH 前端周刊第 80 期:SvelteKit 1、Tauri Mobile、RR 6.5、useEffectEvent

📒 🌼 细数那些惊艳一时的 CSS 属性

📒 关于无感刷新Token,我是这样子做的

📒 JavaScript 中的依赖注入

📒 我的Vue.js生态开源之旅

📒 为什么用公钥加密却不能用公钥解密

⭐️ 「Go工具箱」一文读懂主流web框架中路由的实现原理

⭐️ Go类型系统:有何与众不同

· 5 min read
加菲猫

📒 相关文章推荐

何时使用 gRPC 与 GraphQL - 本篇文章比较了两个流行的 API 协议,以了解每个协议在哪些方面最有效

https://stackoverflow.blog/2022/11/28/when-to-use-grpc-vs-graphql/

关于使用 Rust 优化 JavaScript 的讨论 — 在最近的 Next.js 会议上与 Vercel 的 Lee Robinson 交谈

https://stackoverflow.blog/2022/12/09/ready-to-optimize-your-javascript-with-rust/

用于安全发布和安全消费的新 npm 功能 — GitHub 正在继续努力使 npm 生态系统更加安全。这篇文章介绍了两个新东西:细粒度访问令牌 用于帮助包所有者控制对发布工作流程的访问,以及一个新的 代码浏览器,可以直接查看来自官方 npm 站点的包的内容

https://github.blog/2022-12-06-new-npm-features-for-secure-publishing-and-safe-consumption/

在 2023 年使用 TypeScript 设置 Node.js — 这是一本方便、制作精良的入门读物,可以帮助你在短短四分钟内掌握使用 TypeScript 和 Node 的基本知识。

https://www.youtube.com/watch?v=H91aqUHn8sE

40+ Node.js 集成测试最佳实践 — 组件/集成测试正在成为越来越受欢迎的后端测试技术。这个仓库深入研究了各种快速模式和实践,以创建良好的组件测试。同时,还有一个演示应用程序和使用 Jest、Mocha、Express、Fastify 和 Nest.js 的示例

https://github.com/testjavascript/nodejs-integration-tests-best-practices

“停止编写虚假的 React 代码” — Jack 不喜欢在 React 应用中使用普通的 JavaScript,因为惯用的 React 风格的方法会让人感觉更自然。他分享了一些避免自己陷入同样问题的规则

https://www.youtube.com/watch?v=s-lumOeD2fk

Storybook 团队已经分享了对包括 Next.js、SvelteKit 和 Remix 在内的框架的 未来支持的更新。其中大部分将于 2023 年到来

https://storybook.js.org/blog/framework-api/

📒 Redis分布式锁的10个坑

📒 一文彻底理解Go语言栈内存/堆内存

📒 Rollup 与 Webpack 的 Tree-shaking

📒 Rollup源码:模块打包与Tree-Shaking

📒 Vite 特性和部分源码解析

📒 【第2814期】如何更新 NPM 依赖

📒 Webpack深度进阶:两张图彻底讲明白热更新原理!

📒 二十张图片彻底讲明白Webpack设计理念,以看懂为目的

📒 谈谈复杂应用的状态管理(下):基于 Zustand 的渐进式状态管理实践

📒 谈谈复杂应用的状态管理(上):为什么是 Zustand

📒 React Native工程Monorepo改造实践

📒 【第2813期】网易严选APP端上H5容器化建设

📒 Go 1.20 新特性之 time.Compare

📒 【综合笔试题】难度 3.5/5,括号相关剪枝搜索题

📒 Umi 中如何根据服务端响应数据动态更新路由

📒 深度解析 React 性能优化 API

📒 Go1.20 将会修改全局变量的初始化顺序。梅度二开,继续打破 Go1 兼容性承诺!

⭐️ 两种 Option 编程模式的实现,Uber推荐这一种

📒 哔哩哔哩 Web 首页重构——回首2021

📒 前端食堂技术周刊第 63 期:Vite 4.0、State of CSS 2022、Rome v11、Web 性能日历、VueConf 2022 PPT

📒 【综合笔试题】难度 3/5,多解法热门搜索题

📒 ChatGPT 以及相关开源项目体验

📒 Webpack 构建流程

玩转webpack(一)上篇:webpack的基本架构和构建流程

玩转webpack(一)下篇:webpack的基本架构和构建流程

📒 MDH 前端周刊第 79 期:ChatGPT、Vite 4、SWR 2、Intl.Segmenter

📒 Google Go 编程规范

⭐️ Go版本大于1.13,程序里这样做错误处理才地道

📒 【第2809期】大型会场活动线上保障方案

📒 Go语言爱好者周刊:第 171 期

· 5 min read
加菲猫

📒 相关文章推荐

Storybook 发布了 一个新的 API。本次更新旨在使对 Vite、Next.js、Svelte、Remix 和 Nuxt 等的支持在 2023 年更容易发布。"对任何框架的零配置支持"。

https://storybook.js.org/blog/framework-api/

入门 Zustand — 本文给出了几个使用 Zustand 的技巧。Zustand 是一个相对最小的状态管理库,拥有很多热情的用户

https://tkdodo.eu/blog/working-with-zustand

Shopify 衡量 React Native 渲染时间的解决方案 — 阅读本文可以了解更多关于 Shopify 的开源库 react-native-performance 是如何工作的,用户如何使用该库,以及为什么测量性能如此重要

https://shopify.engineering/measuring-react-native-rendering-times

给 React 开发者的一篇 CSS 变量教程 — 这是一篇新推出的文章,对如何在项目中使用 CSS 变量(自定义属性)进行了深入的研究

https://www.joshwcomeau.com/css/css-variables-for-react-devs/

📒 【VueConf 2022】尤雨溪:Vue的进化历程

📒 Nodejs 的 stream 操作

import { Readable } from "node:stream";
import fs from "node:fs";

const readable = new Readable();
readable.push("测试内容");
readable.push(null); // no more data

// 将可读流复制到标准输出
readable.pipe(process.stdout);

// 将可读流复制到文件
const writable = fs.createWriteStream("/xxx");
readable.pipe(writable);

Node.js 流(stream):你需要知道的一切

📒 Vite 4.0 正式发布!

📒 Go1.20 将禁止匿名接口循环导入!这是一次打破 Go1 兼容性承诺的真实案例

📒 【第2806期】从Lint工具窥探前端的clean-code

📒 Go1.20 继续优化 errors 库

📒 《MiniReact》带你循环渐进了解React原理

📒 从0.5到1用golang上线一个web项目

📒 从0到0.5用golang写一个web项目

📒 我们是如何追逐元宇宙、XR等“概念股”浪潮的

⭐️ []Uber 的 Go语言开发规范

📒 【第2805期】React 数据获取与性能优化

📒 就在刚刚 Go 1.20 rc 1 发布啦!

📒 CSS 小技巧

background 有哪些属性:

  • background-color
  • background-image
  • background-position
  • background-size
  • background-repeat

常见用法:

background-image: url(xxx);

/** 背景图片填充,适配短边,两个属性通常一起用 */
background-size: contain;
background-repeat: no-repeat;

/** 背景图片填充,适配长边 */
background-size: contain;

/** 自定义背景图片大小,同时自定义布局 */
background-size: 58px 48px;
background-position: top 0 left 6px;

transition 动画可以配合 will-change 属性一起用:

background: transparent;
will-change: background;
transition: background 0.3s ease;

📒 React Streaming SSR 原理解析

⭐️ Nest.js进阶系列四:Node.js中使用Redis原来这么简单!

⭐️ Redis学习-入门篇

📒 【面试高频题】难度 2/5,回溯算法经典运用

📒 【第2804期】Islands 架构原理和实践

📒 Go 1.19.4 和 Go 1.18.9 发布安全更新,涉及 os http 以及 http2 header 缓存等问题

⭐️ 源码深度解析之 Spring IOC

📒 前端食堂技术周刊第 62 期:11 月登陆浏览器的新特性、VueConf 2022、第 93 次 TC39 会议、TS 挑战

📒 还在用HttpUtil?SpringBoot 3.0全新HTTP客户端工具来了,用起来够优雅!

📒 历时8个月,10w字!前端知识体系+大厂面试总结(基础知识篇)

📒 你也是业务开发?提前用这个设计模式预防产品加需求吧

📒 美团二面:TCP 四次挥手,可以变成三次吗

📒 Go1.20 继续小修小补 errors 库

📒 MDH 前端周刊第 78 期:技术文档框架、CSS Architecture、Tailwind 抽象泄漏、调试战术

原文链接:

https://www.yuque.com/chencheng/mdh-weekly/hdwfxidpn4u2bboo

MDH 前端周刊第 78 期:技术文档框架、CSS Architecture、Tailwind 抽象泄漏、调试战术

📒 【面试高频题】难度 3/5,状态压缩 DP 及其优化

📒 面试官:net/http库知道吗?能说说优缺点吗

📒 Go语言中常见100问题-#23 Not properly checking if a slice is empty

📒 【第2802期】Islands Architecture(孤岛架构)在携程新版首页的实践

📒 Go 语言代码风格规范-指南篇

📒 Redis 7.0 源码调试环境搭建与源码导读技巧

· 5 min read
加菲猫

📒 相关文章推荐

Ant Design v5.0: 企业级设计语言 React UI 组件库 — Ant Design 5.0 版本提供了更多的组件,简约的设计以及更强的动态主题和定制主题。这里有面向老用户的升级指南:从 v4 到 v5 – 官方首页。

https://github.com/ant-design/ant-design/issues/38671

如何优化 Vue.js 应用程序 — 涵盖了构建 Vue 应用程序时要牢记的一些基本思想。

https://www.smashingmagazine.com/2022/11/optimizing-vue-app/

以正确的方式编写和组织 Node API 测试

https://larswaechter.dev/blog/nodejs-api-testing/

使用 TypeScript 生成原生的 ESM

https://2ality.com/2021/06/typescript-esm-nodejs.html

需要避免的 Node.js 架构陷阱

https://blog.appsignal.com/2022/11/23/nodejs-architecture-pitfalls-to-avoid.html

Hyperstack:一个受 Rails 启发的新的 Node.js Web 框架

https://hyperstackjs.io/

将 React 交互时间缩短 4 倍

https://www.causal.app/blog/react-perf

在 Deno 中使用框架构建应用程序.. 比如 Reac

https://deno.com/blog/frameworks-with-npm

在 React 应用中使用几种数据结构的真实案例

https://profy.dev/article/javascript-data-structures

Clapy:一款 Figma 插件,可基于 Figma 设计产出 React 组件

https://clapy.co/

📒 GoLand 迎来五周年,同时发布 2022.3:有彩蛋

📒 了解微前端,深入前端架构的前世今生

📒 CSS 方案 2022

⭐️ 公司新来一个同事,把优惠券系统设计的炉火纯青!

⭐️ 傻瓜方式分析前端应用的体积

📒 Go语言中常见100问题-#22 Being confused about nil vs. empty slices

📒 18.6K Star!这款 JSON 数据可视化工具太优雅了!

📒 Go 服务自动收集线上问题现场

📒 TypeScript从平凡到不凡(基础篇)

⭐️ Webpack配置全解析(优化篇)

📒 用 Wireshark 让你看见 TCP 到底是什么样!

📒 大象在云端起舞:后 Hadoop 时代的字节跳动云原生计算平台——云原生计算团队采访

📒 【面试高频题】难度 3/5,设计跳表(数据结构经典考察)

📒 动图图解 | UDP就一定比TCP快吗

⭐️ 深入理解 golang 的互斥锁

📒 说两个 Go 循环里的坑,第二个在JS里也有

📒 React Server Component: 混合式渲染

📒 前端工程化基建探索(5)Vite4.0.0都悄悄在“卷”出来了,是时候去探索Vite的设计和实现了

📒 前端工程化基建探索(4)从源码出发探索理解webpack核心特性

📒 前端食堂技术周刊第 61 期:State of JavaScript、Prettier 2.8、Flexbox 交互式指南

📒 彻底搞懂 React 18 并发机制的原理

📒 读完《重构》我学到了这些提升代码质量的编程技巧

📒 一款好用的 Go 调用链可视化工具

📒 用Go学设计模式- 模板模式

📒 Go Context 怎么用,原理是啥,看完这篇就清晰了

📒 Go 模糊测试fuzzing的原理分析

📒 为iframe正名,你可能并不需要微前端

📒 现代CSS样式重置最佳实践!

📒 如何解决前端领域的竞态问题

📒 【第2795期】雪球跨端架构建设之三端同构篇

📒 【第2785期】雪球跨端架构建设之跨端容器篇

📒 Go 语言代码风格规范-概述篇

📒 DNS中有哪些值得学习的优秀设计

📒 Go语言爱好者周刊:第 169 期 — 正确率 23%

· 7 min read
加菲猫

📒 相关文章推荐

重构 React 代码:减少 43% 代码并且数据结构更加清晰

https://profy.dev/article/react-junior-code-review-and-refactoring-1

使用 TypeScript 编写 React 组件

https://www.robinwieruch.de/typescript-react-component/

What and Why:Next.js 13 中的 React Server Components

https://thetombomb.com/posts/react-server-components-nextjs

Twix: 使用 Tailwind CSS 实现 React 组件样式

https://github.com/Idered/twix

Deno v1.28 发布:现在有 130 万个新模块。Deno 现在正式支持以“稳定”的方式使用 npm 模块,并且不需要涉及 node_modulespackage.jsonnpm install 这些出现在 Node 中的内容

https://deno.com/blog/v1.28

https://www.youtube.com/watch?v=X2qxpDriWjY

Wireit:升级 npm 脚本,使它们更智能、更高效

https://github.com/google/wireit

使用 WebAssembly 增强 Node.js

https://www.youtube.com/watch?v=bYCrCKNJBW8

函数式编程到底有什么优点 — 本篇文章是由即将出版的 《Skeptic’s Guide to Functional Programming with JavaScript》的作者 James 以一种更容易理解的方式书写的函数式编程思想的文章,相信你读完本篇文章会大有收获

https://jrsinclair.com/articles/2022/whats-so-great-about-functional-programming-anyway/

用 Storyboook 和 Nightwatch 实践组件驱动开发

https://pineview.io/supercharge-your-storybook-with-nightwatch-testing/

tslog v4.0:支持 JS、TS 的日志输出库— 功能丰富,类型齐全,可以通过本机 V8 进行堆栈跟踪 API、显示代码框架等。现在支持 Node 和浏览器

https://tslog.js.org/

📒 开源低代码表单方案 Formily 的核心设计思路

📒 微前端场景下的代码共享

📒 相关文章推荐

How to Create and Publish a React Component Library

How to Build a Rust CLI Tool to Generate Typescript Types from Rust

Build Micro frontends in NextJS and ReactJS with Webpack 5 Module Federation

Building React App with Module Federation and NextJS/React

📒 Next.js 相关内容

使用 Next.js 搭建 Monorepo 组件库文档

理解 Next.js 中的 CSR、SSR、SSG、ISR 以及 Streaming

Next.js 13 新增特性:

  • 启用实验性 app 目录实现约定式路由,路由每个片段必须要有一个目录承载,内部包含一个 page.tsx 作为主页面,还可以包含 layout.tsx 作为该路由的公共导航,切换路由时,不会刷新

  • app 目录下的组件默认启用 Server Component(当然也可用于 SSG 渲染),与传统的 SSR 不同,优点是拥有 流式 HTML 和选择性注水

  • React Suspense API 解锁了 React 18 中的两个主要 SSR 功能:

    • 在服务器上流式传输 HTML 要实现这个功能,需要从原来的方法切换 renderToString 切换到新 renderToPipeableStream 方法
    • 客户端的选择性注水作用 使用 hydrateRoot 代替 createRoot 方法
  • 区分服务端组件和客户端组件

    • Next.js 12 在 useEffectonChange 等回调函数可以在客户端执行(一般针对浏览器和 Node API 判断)
    • 在 Next13 中 , 在 app 目录下由于启用了 Server Component,无法使用 client-only 特性(例如 useStateuseEffect createContext),因此判断环境非常重要。如要使用 useState 等状态管理的 hook,那么该组件只在客户端执行,需要在首行加入 'use client' 指令
  • 数据请求。Next.js 13 的 app 目录不再需要 getStaticPropsgetServerSideProps,而是默认启用了 Static Rendering(相当于 SSG),如果需要切换渲染模式,只需要修改 fetch 的缓存策略:

    fetch('https://...'); // 默认 'force-cache',相当于 `getStaticProps`

    fetch('https://...', { next: { revalidate: 10 } }); // 请求被缓存 10s,相当于 `getStaticProps` 加上 `revalidate` 参数

    fetch('https://...', { cache: 'no-store' }); // 每次刷新都会重新请求,相当于 `getServerSideProps`

    获取数据之后可以直接用 use() 在服务端消费,渲染 UI。注意 app 目录下的 Server Component 不能用 useState(虽然可以加上 'use client' 改为客户端组件),Next.js 13 建议都在服务端调接口获取数据

  • 此外在 SSG 渲染中常用的 getStaticPaths 改为了 generateStaticParams

参考:

https://beta.nextjs.org/docs/rendering/server-and-client-components#when-to-use-server-vs-client-components

https://beta.nextjs.org/docs/rendering/static-and-dynamic-rendering

https://beta.nextjs.org/docs/data-fetching/fetching

https://beta.nextjs.org/docs/upgrade-guide#dynamic-paths-getstaticpaths

一个 Next.js 13 的演示教程,里面讲了一个 use 导致的无限循环 bug

https://www.youtube.com/watch?v=zwQs4wXr9Bg

你好,Next.js 13

📒 React-query 相关文章

React Query 原理与设计

用react-query解决你一半的状态管理问题

📒 适合团队和个人项目的 Golang 编码规范

📒 优化 CSS 代码的12个小技巧

📒 推荐一款SQL自动检查神器,再也不用担心SQL出错了!

📒 【第2791期】可扩展 CSS 的演变

📒 接口502了,运维和研发谁的锅

📒 Element Plus 组件库相关技术揭秘:7. 组件实现的基本流程及 Icon 组件的实现

📒 突破 etcd 限制!字节自研 K8s 存储 KubeBrain

📒 有趣的 Go HttpClient 超时机制

📒 【综合笔试题】难度 3.5/5,常见序列 DP 题目及其优化思路

📒 socket是并发安全的吗

📒 PGO 是啥,咋就让 Go 更快更猛了

📒 前端食堂技术周刊第 60 期:TypeScript 4.9、Ant Design 5.0、用 vanilla-extract 编写高性能的 CSS

📒 MDH 前端周刊第 77 期:布局动画、Arrow JS、vanilla-extract、antd 5、dumi 2

📒 三种获取Go项目根目录的方式,让你做架构,选哪种

📒 【第2788期】去哪儿低代码平台跨端渲染方案及落地

📒 Gophers如何准备面试

📒 一步一图带你深入理解 Linux 物理内存管理

📒 「每周译Go」理解 Go 中包的可见性

📒 Go语言中常见100问题-#21 Inefficient slice initialization

📒 Go Time 第 256 期

https://changelog.com/gotime/256

📒 Google Go 风格指南

https://google.github.io/styleguide/go/index

📒 Go语言爱好者周刊:第 168 期 — GoLand 2022.3 RC 发布

· 7 min read
加菲猫

📒 相关文章推荐

一个 Next.js 13 的演示教程,里面讲了一个 use 导致的无限循环 bug

https://www.youtube.com/watch?v=zwQs4wXr9Bg

如何用 JavaScript 来对 2800 万数据进行去重? — 这是 Stack Overflow 上一个很有趣的问题

https://stackoverflow.com/questions/74329830/deduping-28-million-strings-using-javascript

Sourcegraph 公司讲述了为什么他们选择从 Monaco 编辑器切换到 CodeMirror

https://about.sourcegraph.com/blog/migrating-monaco-codemirror

新的 JavaScript 时间 API 提案 --- Temporal(已进入 stage 3)

https://vladmihet.hashnode.dev/temporal-api-javascript-dates-but-better

Rome v10:由 Rust 驱动的 JS Linting 与格式化工具 — 由 Babel 的作者 创建的项目自然会引起大家的兴趣

https://rome.tools/blog/2022/11/08/rome-10/

Node 安全版本:v19.0.1、v18.12.1、v16.18.1 和 v14.21.1

https://nodejs.org/en/blog/vulnerability/november-2022-security-releases/

Hapi v21:简单、安全的 Node 应用程序框架 - 专注于现代化和全面 Node v18(和 ESM)支持。值得注意的是 Hapi 不光没有外部依赖,还提供了很多开箱即用的功能

https://github.com/hapijs/hapi

在多个云提供商上部署一个简单的 Node 应用程序

https://medium.com/eleven-sh/deploying-a-simple-node-js-app-with-https-on-cloud-providers-in-2022-heroku-render-fly-io-aws-9358294803c5

将 TypeScript 与 Node.js 结合使用

https://www.robinwieruch.de/typescript-node/

用 Wails 和 React 在 Go 中构建一个桌面应用程序 — Wails 于 Go(lang) 就像 Electron 于 Node 一样,你可以前端用 JavaScript,后端用 GO 在 Mac、Linux 和 Windows 上开发桌面应用程序

https://react.statuscode.com/link/131395/web

CRACO v7.0:覆盖 Create React App 配置 — 如果你仍然喜欢 Create React App,而不是如 Next.js 之类的更大的 React 应用构建方式,CRACO 让你继续使用 CRA,但增加了一个可理解的配置层

https://github.com/dilanx/craco

📒 当谈论协程时,我们在谈论什么

⭐️ 看一遍就理解:IO模型详解

⭐️ 🎉 dumi 2,它来了它来了它来了

⭐️ 面试必备:零拷贝详解

📒 2022年我的面试万字总结(代码篇)

📒 【第2785期】雪球跨端架构建设之跨端容器篇

⭐️ Go 1.20新特性前瞻

⭐️ 实战总结!18种接口优化方案的总结

📒 深入理解 Golang map 设计理念与实现原理

📒 为什么我抓不到baidu的数据包

📒 React这25个精选库,将助你工作更上一层楼

📒 React 中的重新渲染

📒 【常见题型总结】二分以及为何能二分(二段性的拓展)

📒 保姆级教程!2 万字 + 30 张图搞懂 MySQL 是怎么加行级锁的

📒 我修复了一个 Vite Bug,让我的项目首屏性能提高了 25%

📒 Nuxt.js 3.0 正式发布!

📒 【第2784期】从cdnjs 的漏洞来看前端的供应链攻击与防御

📒 Go1.20 中两个关于 Time 的更新,终于不用背 2006-01-02 15:04:05 了!

📒 JavaScript错误处理完整指南

⭐️ 使用反射操作channel

⭐️ 成为 Go 高手的 8 个 GitHub 开源项目

🌛 使用useReducer + useContext 代替 react-redux

📒 前端食堂技术周刊第 59 期:GitHub Universe 2022、Rome v10、Parcel v2.8.0、可扩展的 CSS 演变

⭐️ 万字图文讲透数据库缓存一致性问题

📒 【面试高频题】难度 2/5,经典区间 DP 模板题(详解如何思考区间 DP 问题)

📒 打脸了兄弟们,Go1.20 arena 来了!

📒 【第2782期】得物API一站式协作平台探索与落地

📒 如何在测试中发现goroutine泄漏

⭐️ 忘了又看,看了又忘?保姆级教学,一口气教你玩转 3 种高频设计模式!

📒 【中级/高级前端】为什么我建议你一定要读一读 Tapable 源码

📒 MDH 前端周刊第 76 期:可扩展的 CSS、TanStack Router、Solid Start Beta、Rome 10

React Router 6 提供了 deferred API,让我们可以区分页面的关键数据和可选数据。可选数据不应该影响页面渲染,比如博客文章的评论、购物车中的推荐产品、最近的搜索等。用法如下。同时可选数据加载报错不会让整体路由渲染报错。

const critical1Promise = fetch('/xxx').then(res => res.json);
const critical2Promise = fetch('/xxx').then(res => res.json);
const lazy1Promise = fetch('/xxx').then(res => res.json);
const lazy2Promise = fetch('/xxx').then(res => res.json);
export const loader = async () => {
return defer({
critical1: await critical1Promise,
critical2: await critical2Promise,
lazy1: lazy1Promise,
lazy2: lazy2Promise,
});
}

这和在组件里用 useEffect 有啥区别?useEffect 的方式,不能做到所有请求并行发起,相比之下会慢一些。「The earlier you initiate a fetch, the better, because the sooner it starts, the sooner it can finish.」

https://dev.to/infoxicator/react-router-6-deferred-fetch-4k68

MDH 前端周刊第 76 期:可扩展的 CSS、TanStack Router、Solid Start Beta、Rome 10

📒 Node.js 安全最佳实践

📒 2种方式!带你快速实现前端截图

⭐️ Go学设计模式-程序流程要动态切换?用这个模式写更丝滑

📒 2022 年 JavaScript 从 ES6 到 ES12 新特性汇总

📒 【第2781期】React 渲染的未来

📒 Go语言爱好者周刊:第 167 期 —— 结构化日志期待下

· 5 min read
加菲猫

📒 相关文章推荐

基于 Amplify Studio 使用少量代码实现 Figma-to-React 组件

https://aws.amazon.com/blogs/mobile/new-build-responsive-figma-to-react-components-with-almost-no-code/

JavaScript 中的 “realm” 是什么

https://weizman.github.io/page-what-is-a-realm-in-js/

2022 年如何构建,测试并发布一个 TypeScript 编写的 npm 包

https://www.strictmode.io/articles/build-test-and-publish-npm-package-2022

'Next.js 打包出的产物会感谢你' — 如果你的 Next.js 应用打包出的产物比预期的更加大一些,前端工程师 Renato 的打包优化建议会使你受益。

https://renatopozzi.me/articles/your-nextjs-bundle-will-thank-you

基于 Storybook test runner 实践代码测试的覆盖率

https://storybook.js.org/blog/code-coverage-with-the-storybook-test-runner/

教你打包并发布一个 Vue.js 3.0 插件的 npm 包 — 使用 Vite 打包构建出产物,使用 vue-tsc 生成类型带来更好的开发体验。

https://vueschool.io/articles/vuejs-tutorials/how-to-package-and-distribute-a-vue-js-3-plugin-on-npm/

📒 Element Plus 组件库相关技术揭秘:6. CSS 架构模式之 BEM 在组件库中的实践

📒 【第2780期】如何用油猴提升前端开发效率

🌛 从零实现一个迷你 Webpack

📒 【第2779期】离开后端说前端加密都是空谈

📒 前缀树在前端路由系统中的应用

📒 选择 Go 还是 Rust?CloudWeGo-Volo 基于 Rust 语言的探索实践

📒 还在服务器上捞日志?快搭建一个ELK日志系统吧,真心强大!

📒 开启 GODEBUG 更直观地理解 Go 程序的调度过程

📒 Go语言中常见100问题-#20 Not understanding slice length and capacity

⭐️ Go 13 周年啦!

⭐️ 基于 MF 的组件化共享工作流

📒 快收藏!超强图解Docker常见命令与实战!

📒 Chrome DevTools中的这些骚操作,你都知道吗

📒 【第2777期】React最新提出了一个名为use的Hook

📒 20个常见的前端算法题,你全都会吗

📒 阿里面试官:如何给所有的async函数添加try/catch

📒 「历时8个月」10万字前端知识体系总结(工程化篇)🔥

📒 React 进阶实践指南 - 渲染控制

https://juejin.cn/book/6945998773818490884/section/6958058637042384900

📒 如何用 TypeScript 声明 React HOC

https://react-typescript-cheatsheet.netlify.app/docs/hoc/full_example

https://medium.com/@jrwebdev/react-higher-order-component-patterns-in-typescript-42278f7590fb

📒 云谦:前端框架的趋势与实践(文字稿)

📒 这30 个优秀的 Go 编码习惯,你都在用吗

⭐️ 一文搞懂Go标准库context包

📒 记一次使用time.Duration类型踩过的坑

📒 golang中time包使用教程之基础使用篇

⭐️ 字节开源WEB框架Hertz太香啦!

📒 面试必问之 JS 事件循环(Event Loop),看这一篇足够

📒 信仰崩了?Preact 开始采用 Vue3 的响应式设计

📒 【常见题型总结】序列 DP 模板题(总结「线性 DP」和「序列 DP」本质区别)

📒 点击页面元素跳转IDE对应代码,试试这几个工具!

📒 Go 十年了,终于想起要统一 log 库了!

📒 前端食堂技术周刊第 58 期:TypeScript 4.9 RC、10 月登陆浏览器的新功能、Turbopack 真的比 Vite 快 10 倍吗

📒 由 transform 被占用引发的思考🤔

📒 TypeScript 4.9 发布!重点新特性解读 ~

📒 聊一聊常见的浏览器数据存储方案

⭐️ MDH 前端周刊第 75 期:CSS-in-JS、Node 18、完美提交、ChiselStrike、Ultra

📒 Happens before 原则在 Go 内存模型中的应用举例

📒 这些最常用的 Go CLI 命令,新手 Gopher 应该掌握

📒 「每周译Go」如何在 Go 中编写包

· 7 min read
加菲猫

📒 相关文章推荐

理解 useMemo and useCallback

https://www.joshwcomeau.com/react/usememo-and-usecallback/

React 错误边界指南

https://meticulous.ai/blog/react-error-boundaries-complete-guide/

何时使用 useLayoutEffect 而不是 useEffect

https://javascript.plainenglish.io/react-hooks-when-to-use-uselayouteffect-instead-of-useeffect-3271a96d881a?gi=622ccbf807f3

深度解析好文:为了让 React 更好

https://acko.net/blog/get-in-zoomer-we-re-saving-react/

创建现代 npm 包的最佳实践

https://snyk.io/blog/best-practices-create-modern-npm-package/

useSyncExternalStore:被低估的 React API

https://thisweekinreact.com/articles/useSyncExternalStore-the-underrated-react-api

为什么每个 React 开发者都应该学习函数组合

https://medium.com/javascript-scene/why-every-react-developer-should-learn-function-composition-23f41d4db3b1

“为什么我们要放弃 CSS-in-JS” - Emotion 是一个用 JavaScript 编写 CSS 的流行库,但它的一位贡献者讲述了为什么他的团队总体上放弃了 CSS-in-JS 的想法。

https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b

在 React 中使用 use - 一个新的 Hook 即将到来

https://vived.io/new-hook-is-coming-to-react-frontend-weekly-vol-109/

⭐️ 理解 Next.js 中的 CSR、SSR、SSG、ISR 以及 Streaming

⭐️ 【第2774期】基于 Module Federation 的模块化跨栈方案探索

⭐️ 组件库Monmrepo架构与开发调试环境构建

📒 你了解 Cookie 中的 SameSite 属性吗

📒 配个 json,表单就出来了?FormRender 初探

⭐️ Go每日一库之调用外部命令的几种姿势

📒 带你提前看看 Go 1.20 包括哪些重大变更和性能提升

📒 GitHub上高质量数据结构与算法项目推荐!

📒 如何使用官方的 Node.js Docker 镜像

https://www.docker.com/blog/how-to-use-the-node-docker-official-image/

📒 Node v18 现在进入 LTS 阶段(v18.12.0)

直至 2023 年 10 月,之前作为 current 版本的 v18 将作为 active LTS 存在,并拥有所有最新的功能特性。本版本的代号是 “氢”——宇宙中最丰富的元素。

https://nodejs.org/en/blog/release/v18.12.0/

📒 route-list:显示 Express/Koa/Hapi/Fastify 路由

如果你想以一种优雅的方式查看基于 Node 的 webapp 的所有路由,那么可以试试它。

https://github.com/VladimirMikulic/route-list

📒 现代 CSS 指南 -- at-rule 规则必知必会

📒 深入浅出 Vite - 推荐阅读

📒 开发小技巧

npm scripts 中的 -- 可以用来转发命令行参数:

{
"scripts": {
"build:weapp": "taro build --type=miniprogram",
"dev:weapp": "npm run build:weapp -- --watch"
}
}

⭐️ 极致编译速度,一文搞定webpack5升级

📒 Element Plus 组件库核心技术揭秘:5. 从终端命令解析器说起谈谈 npm 包管理工具的运行原理

📒 一文吃透 React 和 Vue 的多节点 diff 原理

📒 看 Go 中的 struct 如何被优化,还有小插曲

📒 Go for 循环有时候真的很坑

📒 用Go学设计模式-提炼流程,减少重复开发就靠它了!

📒 vue中动态引入图片为什么要是require, 你不知道的那些事

⭐️ 聊一聊常见的构建工具关于插件机制的那些通用套路

📒 Chrome 最近带来了哪些有意思的新东西

📒 深入剖析容器技术基础

📒 前端食堂技术周刊第 57 期:Turbopack、Next.js13、Chrome107、Vite3.2、图解 TLS 1.3

📒 Go 语言终极搜索插件

📒 压缩 70% 下载流量 - 记一次店铺优化专项

📒 我们如何用 Next.js 提高 70% 的 React 加载时间

通过用 Next.js 替换 Create React App,商业计划平台 Causal 通过减少加载时间显著改善了用户体验。怎么做到的?一点 SSR 就能帮你很多。

https://www.causal.app/blog/next-js

📒 “为什么我们要放弃 CSS-in-JS”

Emotion 是一个用 JavaScript 编写 CSS 的流行库,但它的一位贡献者讲述了为什么他的团队总体上放弃了 CSS-in-JS 的想法。

https://dev.to/srmagura/why-were-breaking-up-wiht-css-in-js-4g9b

📒 在 React 中使用 use - 一个新的 Hook 即将到来

上周我们在一个叫做 use 的新 Hook 后面介绍了 RFC —— 这里有一个更容易理解的介绍。“这个不起眼的发明可能永远改变我们将数据输入应用程序的方式。”

https://vived.io/new-hook-is-coming-to-react-frontend-weekly-vol-109/

📒 程序员应该遵守的编程原则(不止Gopher哦)

📒 前端工程化基建探索:从内部机制和核心原理了解npm

📒 哈啰下一代跨技术栈前端组件库 Quark Design 正式开源!

📒 深入浅出JavaScript异步编程

📒 深度解密Go语言之关于 interface 的 10 个问题

📒 手撸源码系列 - cache2go

📒 《 关于我用拓展运算符把项目搞崩这件事 》

注意函数调用不能接受过长的参数:

const items = [];
const newItems=new Array(1000000)

// ❎ 以下两种情况,如果 newItems 很长容易导致爆栈问题
items.push(...newItems);
items.push.apply(items, newItems);

// ✅ 合理做法
items.concat(newItems);
items = [...items, ...newItems];

《 关于我用拓展运算符把项目搞崩这件事 》

📒 前端性能优化到底该怎么做(下)- 直捣黄龙

📒 Go语言爱好者周刊:第 165 期 —— 基于 fyne 实现一个简单计算器

· 3 min read
加菲猫

📒 Next.js 13 相关文章

你好,Next.js 13

https://nextjs.org/blog/next-13

https://beta.nextjs.org/docs/data-fetching/fundamentals#

📒 Monorepo,大型前端项目管理模式实践

📒 React Hooks不优雅

📒 运用「博弈论」分析「先手必胜态」序列具有何种性质,以及如何思考「博弈论」问题

📒 Go 大佬良心发现,愿意给 map 加清除了

📒 Turbopack 很火? 那么就从前端角度看 Rust

📒 Docker夺命连环15问,你能坚持第几问

📒 当函数设计遇到切片

📒 使用Go语言批量同步微信读书笔记到Flomo

⭐️ 一文了解 NextJS 并对性能优化做出最佳实践

📒 比Webpack快700倍的Turbopack,到底快在哪

⭐️ 课代表:Turborepo 笔记

📒 Go标准库依赖的那些modules

📒 使用 Vitest 和 React Testing Library 给 Next.js 应用单元测试

📒 前端初学 ECS 架构,实现超炫的粒子碰撞动画

📒 Go HTTP服务用了优雅关闭,为什么还是报错

⭐️ 【羊了个羊】之我用vue3+ts+vite3从0到1开发了个【兔了个兔】

📒 【第2763期】接入成本最低微前端框架:京东零售micro-app

📒 聊一聊关于微前端架构的几种技术选型

📒 前端食堂技术周刊第 56 期:Solid v1.6.0、State of GraphQL、ViteConf回放、Lerna v6

📒 MDH 前端周刊第 74 期:use、htmx、Stately Studio、TypeRunner、画中画

📒 一文教你搞定所有前端鉴权与后端鉴权方案,让你不再迷惘

📒 1024,我们的节日,Gopher 该干点啥

📒 Go try 新提案靠谱吗?想简化错误处理了

📒 Go语言中常见100问题-#18 Neglecting integer overflows

📒 Go语言爱好者周刊:第 164 期

· 10 min read
加菲猫

📒 React 服务端渲染在跨端领域中的新视界

📒 学会这 20 个库,让你快速看懂 vue3 和 vite3 源码 🚀

📒 面试官:你会看 Vite 源码吗

📒 用 Go 程序打包和压缩文件,我们可以这么做

📒 Go语言中常见100问题-#17 Creating confusion with octal literals

📒 如何挑选最适合的 Node.js Docker 镜像

当你在编写 DockerFile 时会忽略 FROM node 的含义,作者分享了一些对于版本选择上的考虑。

https://snyk.io/blog/choosing-the-best-node-js-docker-image/

📒 Lerna Reborn:第六个版本更新了什么

使用 Nrwl 管理,面向 Lerna monorepo 的 JavaScript 构建系统并没有过时或弃用,它正在向前迈进一大步。v6 在默认情况下通过高效的任务调度和缓存、VS Code 扩展、Prettier 支持等获得了很大的速度。

https://blog.nrwl.io/lerna-reborn-whats-new-in-v6-10aec6e9091c?gi=ba929beec06d

📒 Node v18.11.0 发布

Node 的最新版本虽然并没有更新很多功能,但却实验性的支持了 --watch 功能。当导入的文件发生变化时,会自动重新启动运行中的进程(这个功能让人想起了 nodemon) – 这个功能最近被 详细讨论过

https://nodejs.org/en/blog/release/v18.11.0/

📒 【综合笔试题】难度 4.5/5,扫描线的特殊运用(详尽答疑)

📒 复活了! Lerna V6 带来了哪些新东西

⭐️ 【第2757期】软件架构的23个基本原则

⭐️ 【第2677期】如何在React中应用SOLID原则

📒 前端架构带你 封装axios,一次封装终身受益「美团后端连连点赞」

📒 如何编写 CommonJS 模块,以便它们的导出可以从 ES 模块实现按照名称导入

如果你曾经在使用 CommonJS 和 ES 模块之间纠结过,那么这篇文章或许值得一读。Axel 博士在这里解决了一个关键的交叉兼容性问题。

https://2ality.com/2022/10/commonjs-named-exports.html

📒 njt:快速导航至 npm 包资源

如果你想要快速访问 npm 包的首页、仓库、issues,甚至包成本估算,那么 njt 将会是一个不错的选择。njt 提供了一个快速跳转到与 npm 包相关的各种资源目的地的方法。你可以在终端中安装并使用,也可以通过 LaunchX 扩展程序 将 njt 添加至 VS Code 的命令面板然后使用,或者在 Google 与 Firefox 浏览器进行配置然后搜索,亦或 直接在网页上使用它。如果你对此有兴趣,可以来看看 GitHub 仓库。

https://www.npmjs.com/package/njt

📒 换一种方式对工程中的Api进行封装吧(fashion-axios)

📒 Element Plus 组件库相关技术揭秘:3.ESLint 核心原理剖析

📒 Element Plus 组件库相关技术揭秘:2. 组件库工程化实战之 Monorepo 架构搭建

📒 开源推荐

lazygit

git 命令的 terminal UI 工具,基于 Go 实现。

https://github.com/jesseduffield/lazygit

knip

又一个废代码检测工具,支持检测未使用的文件、依赖和 exports。

$ knip --reporter codeowners
--- UNUSED FILES (2)
@org/team src/chat/helpers.ts
@org/owner src/components/SideBar.tsx
--- UNUSED DEPENDENCIES (1)
@org/admin moment
--- UNLISTED DEPENDENCIES (1)
@org/owner src/components/Registration.tsx react
--- UNUSED EXPORTS (4)
@org/team src/common/src/string/index.ts: lowercaseFirstLetter
@org/owner src/components/Registration.tsx: RegistrationBox
@org/owner src/css.ts: clamp
@org/owner src/services/authentication.ts: restoreSession, PREFIX
--- UNUSED TYPES (3)
@org/owner src/components/Registration/registrationMachine.ts: RegistrationServices, RegistrationAction
@org/owner src/components/Registration.tsx: ComponentProps
@org/owner src/types/Product.ts: ProductDetail
--- DUPLICATE EXPORTS (2)
@org/owner src/components/Registration.tsx: Registration, default
@org/owner src/components/Products.tsx: ProductsList, default

https://github.com/webpro/knip

📒 手写 React 渲染器

由于有 react-reconciler,让自定义 React 渲染器变地相当简单。

import ReactReconciler from "react-reconciler";

const reconciler = ReactReconciler({
// ... configuration options ...
// 启用突变模式
// Reconciler 有两种不同的渲染模式,1)突变模式,2)持久模式
supportsMutation: true,

createInstance(type, props) {
const element = document.createElement(type);
Object.keys(props).forEach((prop) => {
// Filter out non-HTML attributes like:
if (!["children", "onClick", "key"].includes(prop)) {
// Appends each html attribute to the element
element[prop] = props[prop];
}
});
// return the HTML element
return element;
},
createTextInstance: (text) => {
return document.createTextNode(text);
},
getRootHostContext: () => null,
getChildHostContext: () => null,
shouldSetTextContent: () => null,
prepareForCommit: () => null,
clearContainer: () => null,
resetAfterCommit: () => null,
appendInitialChild: () => null,
appendChildToContainer: () => null,
finalizeInitialChildren: () => null,
removeChildFromContainer: () => null,
});

const render = (element, container) => {
const root = reconciler.createContainer(container, false, false);
reconciler.updateContainer(element, root, null, null);
};

export { render };

然后就可以拿这个 render 方法进行渲染了。

render(<App />, document.getElementById('root'))

https://www.markcodes.dev/posts/build-react-custom-renderer-part-1

📒 最快前端模板

Jest 作者梳理了他认为最快的 2022 最快前端工具集以及与之配套的 github 仓库模板,结论是 Vite + tailwind + pnpm + eslint & prettier + TypeScript + React。我觉得这里的快有两个含义,1)速度快,2)用于快速启动项目的最小模板。

  • Vite 无需多说
  • Tailwind 也无需多说,但如果你有自己的 Design System,作者推荐用 emotion
  • pnpm 除了快,对 monorepo 的支持也很好
  • ESLint & prettier 有一些注意点,1)要分开用,别在 eslint 规则里加 prettier 规则,会慢,2)prettier 和 eslint 都有 --cache 参数,要开启,3)推荐用 @trivago/prettier-plugin-sort-imports 和 prettier-plugin-tailwindcss 对 import 和 tailwindcss 类进行排序,4)期待 rome 的 formatter 和 lint
  • npm-run-all 用于并行执行多个命令
  • NodeJS 脚本编写,基于 native esm,使用 ts-node + @swc/core + nodemon 的依赖组合实现,没有用基于 esbuild 方案比如 tsx,因为测下来在一些场景会莫名其妙地慢
  • TypeScript 无需多说
  • VSCode,作者推荐了 4 个插件

大家可能会好奇,作为 Jest 作者,测试工具他选的啥?虽然文章里没提,但从代码里可以看到,用的是 Vitest,哈哈。

https://cpojer.net/posts/fastest-frontend-tooling-in-2022

📒 MDH 前端周刊第 73 期:TypeScript 10 年、最快前端模板、whyframe、template 元素

📒 文章推荐

📒 Storybook 7.0 中 Vite 成为内置选项

https://storybook.js.org/blog/first-class-vite-support-in-storybook/

📒 用 Sandpack 打造世界级 Playground

CodeSandbox 开源了 Sandpack,本文教你使用 Sandpack 打造出一个功能齐全的 Playground。

https://www.joshwcomeau.com/react/next-level-playground/

📒 Resumable vs. Hydration

本文介绍了 Qwik 框架可恢复性的实现原理以及与常规补水相比具有的优势。

https://qwik.builder.io/docs/concepts/resumable/

📒 TypeScript 十年,不忘初心

📒 Rollup v3.0.0

Rollup 发布 v3.0.0,带来了大量更新。其中 Breaking Change 包括最低支持 Node 14.18.0、浏览器构建拆成单独的包 @rollup/browse、Node 构建使用 node: 前缀导入内置模块、移除一些以前被废弃的功能,使用时提示警告等。还有包括 Options 配置、插件 API、以及一系列的新特性。

Rollup 3.0 意味着 Vite 即将发布大版本

https://github.com/rollup/rollup/releases/tag/v3.0.0

📒 前端食堂技术周刊第 55 期:Rollup v3.0.0、Volar 1.0 Nika、TypeScript 十年

📒 如何使用 React、SSR 和 Tailwind CSS 构建 SVG 折线图

关于如何在基于 Next.js 或 Gatsby 的服务器端渲染 React 应用程序中创建你自己的基于 SVG 的折线图的教程。

https://thenewstack.io/how-to-build-svg-line-charts-with-react-ssr-and-tailwind-css/

📒 React 渲染的未来

首先回顾当前的渲染模式 (CSR/SSR)然后转向一些新的渲染模式,例如流式 SSR 和服务器组件。这也是在 React Bangalore 的 最近访谈 中的话题。

https://prateeksurana.me/blog/future-of-rendering-in-react/

📒 React Table:一个 “几乎无头” 的表格组件

https://react-table-library.com/

📒 Islands 架构原理和实践

📒 你不需要Next.js(和SSR)

📒 【面试高频题】难度 1.5/5,常规滑动窗口运用题

⭐️ 精读《Headless 组件用法与原理》

📒 学习了!GoMap 会内存泄露

📒 如何让 Go 反射变快

⭐️ Go Gin框架请求自动验证和数据绑定,看完这篇就会用了

📒 一文搞懂Go内联优化

⭐️ Go常见错误集锦之函数式选项模式

📒 Go语言爱好者周刊:第 163 期 —— 错误处理新提案

- - + + \ No newline at end of file diff --git a/2022/page/2/index.html b/2022/page/2/index.html index 1159852eb0..e07d1cf8e6 100644 --- a/2022/page/2/index.html +++ b/2022/page/2/index.html @@ -11,8 +11,8 @@ - - + +
@@ -26,7 +26,7 @@ 6、「安全」Tauri 胜。Tauri 内置大量安全功能,可以明确启用或禁用某些 API。Electron 中则可以完全访问 Node 的 API,所以相比来说更容易被黑客利用。 7、「自动更新」Electron 胜。Tauri 和 Electron 都内置了自动更新器,而 Tauri 的相对简单,同时需要维护依赖并手动更新 JSON,而 Electron 可基于 electron-updater 并直接从 Github 发布的二进制文件中提取,要方便很多。 8、「开发体验」Tauri 胜。基于 Tauri CLI 就会包含热重载、为所有平台构建你的应用程序、生成应用程序图标等全部功能,而 Electron 啥都没有提供,只有框架本身。

https://www.levminer.com/blog/tauri-vs-electron

📒 father 4 正式发布

father 4 的具备如下核心特性:

📒 3种方式!Go Error处理最佳实践

📒 超大体量项目,微前端落地方案,看完后悔来找我

📒 快速搭建 SpringCloud Alibaba Nacos 配置中心!

📒 k8s下微前端如何做金丝雀发布

· 8 min read
加菲猫

📒 【第2714期】从Multirepo到Monorepo 袋鼠云数栈前端研发效率提升探索之路

📒 抖音平台多产物代码隔离技术的实践与探索

📒 Hooks时代,如何写出高质量的react和vue组件

⭐️ Vite 约定式路由的最佳实践

📒 Go使用泛型后,这么写单元测试会失效

📒 如何保证数据库和缓存双写一致性

⭐️ 【第2713期】工程化思维:主题切换架构

📒 为了拿捏 Redis 数据结构,我画了 40 张图(完整版)

📒 美团一面:如何在 100 亿数据中找到中位数

📒 解决老工程 toast 组件问题

老工程 React 15.x,Webpack 2.x,工程里面原先没有组件库。

关于 npm 包可能存在部分 ES6 语法,低版本 Webpack 无法解析问题,可以用 Babel 转一下。同理 NPM 包使用了 ES Module 模块语法,也可以用 Babel 转为 CommonJS。现在主要的问题是,大多数 toast 组件,底层都用了 React Hooks,即使 ES 语法兼容,但是运行环境 React 版本太老还是无法兼容。最终还是选用 rc-notification,参考 antd 封装:

https://github.com/react-component/notification/tree/2.0.6

https://github.com/ant-design/ant-design/blob/2.13.14/components/message/index.tsx

📒 Kubernetes原理与架构初探

📒 VS Code 1.70 新特性

3-way merge editor

三路合并编辑器是在1.69版本里上线的,这个功能允许用户在VS Code内快速解决 Git 合并冲突。该功能启用后,可以通过点击「源代码控制视图」中的冲突文件来打开合并编辑器。

settings.json
{
"git.mergeEditor": true
}

Git 提交辅助操作

可以使用 git.postCommitCommand 来设置控制辅助操作,比如允许用户在提交信息后进行推送或者同步。

settings.json
{
"git.postCommitCommand": "sync"
}

分支保护

在之前的1.68版本中,VS Code就添加了 git.branchProtection 以用于配置受保护的特定分支。

settings.json
{
"git.branchProtection": [
"main"
]
}

Command Center

Command Center 功能启用后,其位于编辑器顶部的长条空间,让用户可以快速搜索项目中的文件。

settings.json
{
"window.commandCenter": true
}

sticky scroll

当用户在编辑器中滚动鼠标查看代码时,每个子模块(比如:类/接口/命名空间/函数/方法等等)代码的第一行会置顶固定住,以方便查看。

这对于一些长代码模块(比如一个很长的函数)的阅读体验提升还是非常有帮助的。

settings.json
{
"editor.experimental.stickyScroll.enabled": true
}

📒 Java中的语法糖甜不甜?巧用枚举实现订单状态转换!

📒 看 Go 中的 struct 如何被优化,还有小插曲

📒 Rust 与 Go 可以互操作

📒 SWC 入门介绍

📒 听说TCP能保证不丢包?图解TCP六大丢包场景

📒 Vue3中defineEmits、defineProps 是怎么做到不用引入就能直接用的

📒 浅析神经网络 Neural Networks

📒 在 Go 里用 CGO?这 7 个问题你要关注!

📒 分布式接口幂等性、分布式限流:Guava 、nginx和lua限流

📒 Go 探讨了 13 年,怎么解决再赋值的坑

📒 TypeScript Collections

用 TypeScript 编写的数据结构合集

https://github.com/basarat/typescript-collections

📒 Vite Rollup Plugins

Vite3 中使用 Rollup 插件的兼容性列表

https://github.com/patak-dev/vite-rollup-plugins

📒 Go语言从0到1实现最简单的数据库!

📒 一文读懂TypeScript类型兼容性

📒 Communicating Effectively As A Tech Lead

Addy Osmani 的新作,从 Simplify、Be concise and on point、Communicating with executives、Listen、Be proactive、Be thorough 和 Take notes 7 个维度介绍作为 TL 时如何高效沟通。

https://addyosmani.com/blog/communication-tech-lead/

📒 React Re-Renders

通过这篇文章,我学到了「两个误解」、「一个比喻」和「一个技巧」。

两个误解是,1)state 变更会让整个 app re-render?不是,state 变更只会让当前组件及其子组件 re-render,2)组件 re-render 是因为 props 变更?也不是,props 往上可以追溯到 state 变更,是 state 变更导致了子组件 re-render,而不是由 props 变更引起。

上述误解 2 的一个例外是 React.memo,应用 React.memo 后的组件只有 props 变更才会触发 re-render。你可能会想:为什么这不是默认行为?因为作为开发者,我们往往高估了重新渲染的成本。对于 props 很多且没有很多子组件的组件来说,相比 re-render,检查 props 是否变更带来的消耗可能更大。因此,如果对每个组件都进行 React.memo,可能会产生反效果。

一个比喻是,每次渲染都是由照相机拍摄的快照,React 通过玩「找不同」的游戏找出两张照片之间的差异,然后决定是否 re-render。而 React.memo 则是懒惰的摄影师,如果你要求他为完全相同的东西拍 5 张照片,它会拍 1 张照片并给你 5 份。只有当你的指令改变时,他才会拍下一张新的照片。

一个技巧是,借助 React Devtools Chrome 插件,在「设置 > Profiler」里开启「Record why each component rendered while profiling」,再通过录制的方式排查,就能知道每个 re-render 的原因。

原文链接:

https://www.joshwcomeau.com/react/why-react-re-renders/

中文翻译:

【第2709期】一份详尽的 React re-render 指南

📒 深入解读新一代全栈框架 Fresh

从定位上来看,Fresh 属于 Web 全栈开发框架,相比 Next.js 和 Remix, Fresh 有哪些值得一提的亮点:

  • Fresh 基于 Deno 运行时,由 Deno 原班人马开发,享有 Deno 一系列工具链和生态的优势,比如内置的测试工具、支持 http import 等等
  • 渲染性能方面,Fresh 整体采用 Islands SSR 架构(之前介绍的 Astro 也是类似),实现了客户端按需 Hydration,有一定的渲染性能优势
  • 还有一个比较出色的点是构建层做到了 Bundle-less,即应用代码不需要打包即可直接部署上线
  • 最后,不同于 Next.js 和 Remix,Fresh 的前端渲染层由 Preact 完成,包括 Islands 架构的实现也是基于 Preact,且不支持其它前端框架

开发者并不需要手写路由文件,Fresh 可以自动地生成服务端的路由到文件的映射关系。很明显 Fresh 实现了 约定式路由 的功能,跟 Next.js 类似。

深入解读新一代全栈框架 Fresh

· 11 min read
加菲猫

📒 玩转 Chrome DevTools,定制自己的调试工具

📒 【第2707期】由 esbuild JavaScript API 看跨语言调用

📒 Go 中闭包的底层原理是

⭐️ 使用 TypeScript 编写 React 的最佳实践!

📒 Webpack 构建优化

https://tsejx.github.io/webpack-guidebook/best-practice/optimization/collection

https://webpack.js.org/guides/code-splitting/

📒 k8s 部署相关

使用 Docker Desktop 搭建 k8s 集群

从Go程序第一行代码,到在 K8s 上运行,要经历多少步

在K8S上的Web服务该怎么做域名解析呢

https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/

📒 字节一面:HTTPS 一定安全可靠吗

📒 如何在项目开发中逐步成长

📒 Golang 相关文章

Go 语言里使用 io.Readerio.Writer 两个 interface 来抽象 I/O,他们的定义如下:

type Reader interface {
Read(p []byte) (n int, err error)
}

type Writer interface {
Write(p []byte) (n int, err error)
}

io.Reader 接口代表一个可以从中读取字节流的实体,而 io.Writer 则代表一个可以向其写入字节流的实体。

⭐️ 能ping通,TCP就一定能连通吗

📒 Linux 是如何收发网络包的

📒 Golang 依赖注入相关文章

https://dev.to/dryrainbow/dependency-injection-in-golang-35oa

https://medium.com/avenue-tech/dependency-injection-in-go-35293ef7b6

https://medium.com/thirdfort/go-best-practices-how-to-code-comfortably-60118a27def8

https://levelup.gitconnected.com/better-error-handling-in-golang-theory-and-practical-tips-758b90d3f6b4

📒 【第2704期】网易严选多端组件库OSSA正式开源

📒 Golang 相关文章

Go 语言 Web 编程

Go 语言并发编程

Go 微服务实战

📒 React 18 新特性:Selective Hydration

https://github.com/reactwg/react-18/discussions/37

📒 一个简洁、强大、可扩展的前端项目架构是什么样的

📒 大家都能看得懂的源码之ahooks useInfiniteScroll

📒 esModuleInterop 是如何影响 tsc 的

📒 【第2703期】软件架构手册

📒 如何在 Web 上构建一个插件系统

📒 Go 的常量为什么只支持数字、字符串这样的基础类型

📒 两万字详解!InnoDB锁专题!

📒 细数线程池的10个坑

📒 Chrome DevTools 远程调试安卓网页的原理

📒 Windows 滚动条如何美化成 macOS 那样

📒 Go逃逸分析详解

📒 GO面试必知必会面试题

📒 最简单的单例模式,Go版本的实现你写对了吗

📒 伙计,Go项目怎么使用枚举

📒 Astro 1.0 正式发布,给前端带来了什么

📒 gum

迷人的 shell 脚本工具库,基于 go。

https://github.com/charmbracelet/gum

📒 React Query 转 RTK

本文是作者和 React Query 斗争了一年之后,最终弃 React Query 投 RTK 的故事。

React Query 处理了复杂的缓存,并根据需要重新加载数据。用户使用 useQuery 调用 API 时,数据被存储在 React Query 的缓存中。缓存的数据可通过 getQueryData 读取。如果要更新数据,使用 useMutation 会更新服务群上的数据,同时在 onSuccess 或 onMutate 中更新 React Query 缓存中的数据。更新的最简单方法是调用 invalidateQueries。而缓存失效正是作者觉得 React Query 难以驾驭的主要原因。

然后作者在对比之后选择了 Redux + Redux Toolkit(RTK)。作者希望选择全局 store 的数据流,同时还对比了竞品比如 Valtio(见上图)。Redux 的优点是社区、文档、明确的数据结构,缺点是更多脚手架代码、需要用 reselect 或其他来做渲染优化、尺寸比较大(18K)。

编者注:如果我是作者,在需要全局 store 的前提下,会更倾向于选择 valtio 或 zustand。1)脚手架代码少,这一点对外来说很关键,2)性能更好(valtio 基于使用决定 re-render),3)redux 的单 store 在未来可能成为瓶颈,比如要做组件提取时,多 store 会更灵活一些。

https://www.basedash.com/blog/why-we-had-to-move-away-from-react-query

📒 Suspense

作者在一年前写了第一篇,这是第二篇。时隔一年,这篇是他几个月的研究成果。

这段时间发生了什么?1)React 团队创建 React 18 工作小组讨论区,提供更多深入的信息,同时用于收集反馈,2)React 18 稳定版发布,3)一篇 React Labs 的帖子,介绍 React 团队正在探索的内容。

React 18 有啥新特性?1)没有并发模式,取而代之的是并发功能,仅在子树中启用,原因是为了向后兼容,2)Transition 允许将不紧急的更新标记为过渡(未来可能成为默认行为),3)基于 Suspense 的 Streaming SSR 允许在所有 HTML 被渲染之前进行流化,并且在 HTML 被完全流化之前就可以开始水化(目前需搭配 React.lazy 使用),4)选择性水化,5)新 Hooks,比如 useId 可用来生成在客户端和服务端稳定的 ID,6)自动批处理 让多个 setState 只导致单一渲染。

React 下一步做什么?1)Cache 组件,允许请求库做与 Suspense + 并发渲染兼容的数据缓存,这是 Suspense 目前缺的一环,2)React Server Component,3)用于 Assets 资源加载的 Suspense,比如字体、CSS 和字体等会在加载时导致布局偏移和混乱,4)React 编译器优化,React 慢的原因之一是因为有大量不必要的 re-render,自动插入 memo hook 可以提升性能,这在 React Conf 2021 中有过介绍,5)SuspenseList,在处理 Suspense 列表时有用,比如文章、评论或消息,允许协调子节点,决定他们显示的顺序,6)Offscreen API,允许保留 unmount 组件的状态,或者预先渲染用户可能会执行的 transition,比如做基于路由的预渲染。

跳出 React 从整体社区角度看。1)流式服务端渲染是为了提高响应速度,所以尽可能早地 flush,MarkoJS 在 2014 年开始支持,更早一些 Facebook 在 2009 年也有一门叫 BigPipe 的技术,2)SSR 在网络方面会更快,但同步水化依旧会成为大型项目的性能瓶颈,Islands architecture(群岛架构) 可以解这个问题,3)细粒度响应式,「React 虽然叫 react,但实际上不是 react」,响应式是框架中很流行的一种优化方法,比如 SolidJS,React 团队也有考虑过这个问题,但选择不追求,Dan 早在 2019 年就写过这个话题,4)Transition API 不算新技术,谷歌地图也有类似实现,同时 Scheduling(调度)问题正在通过标准的方式解决,5)SRC(服务端渲染组件)也不是新想法,2018 年就有 Phoenix LiveView 的实现,通过服务端状态和渲染实现 0 JS 的交互功能。

最后,作者还发现,React 项目内部子项目代号均是以 F 开头。比如 Fiber 是实现了异步渲染的重写的核心代号;Fizz 是新的服务器端渲染架构的代号、Flight 是服务器组件的代号、Fire、Flare 等。

https://blog.6nok.org/the-suspense-is-killing-me:-part-2/

📒 React TypeScript 备忘录

一份很全面的 React TypeScript 备忘录。

https://react-typescript-cheatsheet.netlify.app/

📒 React re-render 指南

关于 React 重渲染的系列指南,图文并茂,同时提供了代码示例和扩展资料。

https://www.developerway.com/posts/react-re-renders-guide

📒 ESLint 推出新的配置系统

回顾当前的 eslintrc 配置系统演进史,每一步的演化在当时来看都是不错的选择,比如 extends、Personal configs、多种配置文件格式、可共享的配置和依赖项(npm 背锅)、root、overrides、添加 extends 到 overrides 等等。

然而时至今日,随着 JavaScript 项目越来越庞大,从整体上再来看这些配置就太复杂了。为了简化配置,ESLint 团队经过 18 个月的修订和讨论,决定着手构建一个全新的配置系统 flat config,现在可以在 ESLint v8.21.0 中通过 API 使用。

https://eslint.org/blog/2022/08/new-config-system-part-1/

https://eslint.org/blog/2022/08/new-config-system-part-2/

https://eslint.org/blog/2022/08/new-config-system-part-3/

📒 字节一面:TCP 和 UDP 可以使用同一个端口吗

· 9 min read
加菲猫

📒 将微前端做到极致-无界方案

📒 【第2701期】技术Leader如何创造业务价值

📒 Monorepo 下的模块包设计实践

📒 【TypeScript】never 和 unknown 的优雅之道

📒 Bundle-less 的思考和实践分享

📒 React Fiber架构原理剖析

📒 【万字】优化Webpack?肘,跟我进屋聊聊

📒 字节的前端监控 SDK 是怎样设计的

📒 别再乱打日志了,这份 Java 日志规范,应有尽有,建议收藏!

📒 explain | 索引优化的这把绝世好剑,你真的会用吗

📒 这11条接口性能优化技巧,利好每日睡眠

📒 顺丰快递:请签收MySQL灵魂十连

📒 Go Mod小知识:伪版本

📒 Go ORM 单元测试全流程讲解

📒 超全总结:Go语言如何操作文件

📒 React 服务端渲染遇到的问题

在服务端渲染场景下,不能使用 style-loader,需要用 isomorphic-style-loader 注入样式。

style-loader 内部使用了 dom API 把样式注入到 style 标签中,在 Node 环境下会报错

React 期望在服务端和客户端渲染的内容是相同的,客户端渲染会默认复用服务端渲染的 dom。如果需要在服务端和客户端上渲染不同的内容,可以设置一个 isClient 变量:

class MyComponent extends React.PureComponent {
state = {
isClient: false,
}

componentDidMount() {
// 这里在客户端 hydrate 的时候执行
this.setState({ isClient: true });
}

render() {
const { isClient } = this.state;

if (!isClient) {
// 当需要渲染的组件需要访问浏览器 API,在 Node 环境会报错
// 这里可以渲染 fallback 的内容
return ...
}

// 在客户端可以正常渲染组件
return ...
}
}
tip

当需要渲染的组件需要访问浏览器 API(例如 windowdocumentlocation),在 Node 环境会报错。在服务端渲染的时候,可以先渲染 fallback 内容,在客户端 hydrate 的时候,再渲染正常组件。

另外有一些 SDK,内部可能也访问了浏览器 API,这种情况下不能直接在构造器中初始化实例,可以在 componentDidMount 钩子中延迟初始化。

https://17.reactjs.org/docs/react-dom.html#hydrate

📒 vite 代码压缩遇到的问题

vite 默认使用 esbuild 压缩,esbuild 不仅会做常规的压缩,而且还会在 target 配置允许的范围内做一些语法转换,进一步减小 bundle 体积。

例如在业务中有下面一段代码:

try {
// ...
} catch (err) {
// 这边没有用到 err 参数
return false;
}

经过 esbuild 压缩之后,try...catch 后面的括号直接不见了(这实际上是 ES2019 中的 optional-catch-binding 语法),在一个老业务工程构建的时候,Babel 无法识别这种语法,直接报错了:

try {
// ...
} catch {
return false;
}

有两种解决方案:

  • 一种是使用 terser 压缩,设置 minify: "terser"
  • 另一种继续使用 esbuild,但是手动设置 target: "es2015"

https://vitejs.dev/config/build-options.html#build-target

tip

在一般前端项目中,target 配置是针对 Babel 的,即最终的产物兼容性由 Babel 决定。

但是在 Vite 中,Babel 只参与部分 esbuild 尚不支持的提案阶段的语法转换,并不决定最终产物兼容性,最终的兼容性由 esbuild 决定。注意 esbuild 默认的 target 值为 "esnest",即 esbuild 认为环境支持最新的 JS 语法特性。但是在 Vite 中,build.target 默认为一个特殊值 "modules"(即支持原生 ES Module、动态导入语法和 import.meta 语法,对应 Chrome >=87),最低可以支持 "es2015"

注意 Vite 默认只做语法转换,并不会引入 polyfill(适合第三方库开发,由业务工程 @babel/preset-env 配置 useBuiltIns: "entry" 统一引入 polyfill)。如果产物需要直接在浏览器中运行,则需要 @vitejs/plugin-legacy 插件。该插件会对最终 bundle 中每个 chunk,使用 @babel/preset-env 转换生成对应的 legacy chunk,同时根据 target 配置的目标浏览器兼容性和实际用到的 API,生成一个 polyfill chunk。

https://vitejs.dev/guide/build.html#browser-compatibility

📒 Golang 标准库 strings

重点看一下 strings.Builder 的用法。

Go 学习之 strings.Builder 篇

Go 字符串拼接6种,最快的方式 -- strings.builder

Go拼接字串的三种方法 Go1.10中的strings.Builder

https://pkg.go.dev/strings@go1.19

📒 你需要知道的TypeScript高级类型

📒 Go 的时间转换和时区校对总记不住?给你一份备忘单

📒 两个真实线上升级故障让你彻底搞懂package.json中的脱字符(^)

📒 【第2696期】React 状态管理的新浪潮

📒 Go 创始人教你如何处理错误

⭐️ 总监又来了,人狠话不多,这篇 gRPC,小弟佩服!

📒 React 性能优化, 从 500 毫秒到 1.7 毫秒

https://orizens.com/blog/500ms-to-1-7ms-in-react-a-journey-and-a%20checklist/

📒 UMD 的包如何导出 TS 类型

📒 为什么 React 的 Diff 算法不采用 Vue 的双端对比算法

📒 🚀Turborepo:发布当月就激增 3.8k Star,这款超神的新兴 Monorepo 方案,你不打算尝试下吗

📒 搞清楚 Go Mod的版本和伪版本,下次别乱用了

📒 掌握 TypeScript 中的映射类型

📒 React Re-render 指南

什么是 re-render?什么是必要的 re-render 和不必要的 re-render?如果你对这些问题还模模糊糊的,在这篇文章中可以找到答案。

有四个原因可以让一个组件重新渲染自己:状态变化、父级(或子级)重新渲染、上下文变化和 hooks 变化。

通过 composition(组合)可以避免 re-render。有几种方式,1)把状态下移,避免上层组件 re-render,让 re-render 保持在一个很小的范围之内,2)children as props,作为 props,子组件不会受 state 变更的影响,3)component as props,避免 component re-render。

通过 React.memo 可以避免 re-render,被 memo 的组件只在 props 变更时会 re-render。有几种方式,1)对于带 props 的 component,需对非原始值的 props 做 memo,2)components as props or children,对子组件做 memo 而不要对父组件做 memo。

什么时候应该用 useMemo/useCallback?1)React.memo 过的组件的 props 应该用,因为他们只有 props 变更时才会 re-render,所以反之非 React.memo 过的组件的 props 无需使用,因为都会 re-render,用了也白用,2)useEffect、useMemo、useCallback 中非原始值的依赖应该用,3)重消耗(比如生成渲染树)的部分应该用,反之轻消耗不要用,因为 useMemo/useCallback 本身也有消耗。

如何防止 Context 引起的 re-render?1)memo context value,避免父级组件 re-render 导致 value 变更从而让依赖 context 的地方全部 re-render,2)拆分 data 和 API(getter 和 setter),这样 getter 变更时依赖 setter 的部分不会 re-render,3)把数据拆小,4)使用 context selector 比如 use-context-selector。

https://www.developerway.com/posts/react-re-renders-guide

📒 明明加了唯一索引,为什么还是产生重复数据

📒 现代前端测试框架 Vitest 的一些落地实践感悟

📒 如何用 Project Reference 优化 tsc 编译性能

- - + + \ No newline at end of file diff --git a/2022/page/3/index.html b/2022/page/3/index.html index 588da64303..f63b056d1e 100644 --- a/2022/page/3/index.html +++ b/2022/page/3/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 4 min read
加菲猫

📒 互联网公司都怎么实现分页的,拿 MySQL 使劲Limit

📒 拒绝 Go 代码臃肿,其实在这几块可以用下观察者模式

📒 记一次线上超时问题的发现、排查、定位以及解决过程

📒 这不会又是一个Go的BUG吧

📒 这三个 Go 水平自测题,手写不出来还是先老实上班吧

📒 不想Go 错误处理太臃肿,可以参考这个代码设计

📒 关于Go程序错误处理的一些建议

📒 你见过哪些目瞪口呆的 Java 代码优化技巧

📒 聊聊 13 种锁的实现方式

📒 代码越写越乱?那是因为你没用责任链!

⭐️ 社招后端21连问(三年工作经验一面)

📒 Spring Boot 实现接口幂等性的 4 种方案

📒 前端运维部署那些事

📒 rollup 最佳实践!可调试、编译的小型开源项目思路

tsc 可以只生成类型声明文件:

$ tsc  --emitDeclarationOnly --declaration --project ts.config.json --outDir dist/esm

rollup 最佳实践!可调试、编译的小型开源项目思路

📒 脚本任务执行器 —— npm-run-all 源码解析

📒 2022年值得推荐的React库!

📒 超大体量项目,微前端落地方案,看完后悔来找我

📒 如何解决前端常见的竞态问题

📒 Go语言中常见100问题-#88-1 Not using testing utility packages

📒 字节二面,差点没答好

📒 如何提高 TypeScript 的代码质量

📒 谁说 Mysql 单表最大 2000 W ?我硬要塞它 1 个亿!

📒 初探 Vue3 编译之美

📒 Go 1.19 is released

$ go install golang.org/dl/go1.19@latest

go 命令使用:https://pkg.go.dev/cmd/go

📒 GitHub Trending - TypeScript

https://github.com/trending/typescript

📒 【表达式计算】双栈 : 表达式计算问题的通用解法

📒 构建自己的 Web 框架

这篇文章解释了如何构建基于 React 的简易 Web 框架,并使用 Vercel 的 Build Output API 进行部署。

Build Output API 是一个基于文件系统的规范,用于生成 Vercel 部署的目录结构。框架作者可以将此目录结构实现为他们构建命令的输出,以便框架可以利用所有 Vercel 的平台功能(Serverless Functions,Edge Functions,路由,缓存等),Astro已经成功与 Vercel 集成。

https://vercel.com/blog/build-your-own-web-framework

📒 从零实现 React v18 的核心功能

📒 Roll your own JavaScript runtime

📒 用 TS 的类型系统实现一个 TS 类型系统

📒 像小说一样品读 Linux 0.11 核心代码

📒 前端食堂技术周刊第 46 期:Chrome 三方 cookie 计划、npm 引入更多安全增强功能、Awesome Bun

⭐️ 看一下 React 15.x 源码

https://github.com/Lucifier129/react-lite

📒 Go语言中常见100问题-#87 Not dealing with the time API efficiently

📒 用了TCP协议,就一定不会丢包吗

📒 【第2688期】关于低代码平台建设的思考与实践暨BPM表单设计器前端技术解析

· 5 min read
加菲猫

📒 全网最优雅的 React 源码调试方式

📒 如何实现一个跨框架的组件库文档

📒 入职Apifox研发组半年,我所提升的软技能|文末抽书

⭐️ 几个提升Go语言开发效率的小技巧

📒 最近对前端构建工具的一些理解

📒 Go语言中常见100问题-#86 Sleeping in unit tests

📒 超实用的Chrome DevTools调试技巧

📒 开源项目推荐

用 Go 写的 GUI gRPC 客户端。作者在调试 gPRC 接口时,发现没有类似 postman 趁手的 gPRC 客户端,所以就自己动手写了一个然后开源了。

https://github.com/crossoverJie/ptg

Go DDD 示例项目。该项目通过一个预约系统的示例,展示了如何在 Go 项目中实现领域驱动设计(DDD)和读写分离架构(CQRS)。

https://github.com/ThreeDotsLabs/wild-workouts-go-ddd-example

一款静态应用程序安全测试(SAST)工具。它可以检测项目中是否包含密码、API Key、token 等信息,还能够轻松整合到 Git Hook 和 GitHub Action,实现提交代码时自动检测,通过告警和阻止 push 等方式,有效地防止敏感信息泄漏。

https://github.com/zricethezav/gitleaks

在线可视化正则编辑器。该项目可将输入的正则表达式,自动生成对应的可视化图形,支持通过编辑图形节点修改正则表达式,以及对正则表达式进行测试等功能。

https://github.com/Bowen7/regex-vis

📒 前端构建效率优化之路

📒 Esbuild Bundler HMR

📒 面试突击69:TCP 可靠吗?为什么

📒 招银网络一面:AOP 了解吗?有什么用?切面执行顺序如何控制

⭐️ Nest 的实现原理?理解了 reflect metadata 就懂了

📒 耽误你十分钟!🎃你可能用得上这些webpack5新特性

📒 入职即巅峰?🧨基建优化项目体积减少20%!

📒 简单好用的前端拖拽排序库

📒 你能给前端工程化下个定义么

📒 你需要知道的ES6—ES13开发技巧!

📒 【第2682期】前端场景下请求的Race Conditions

📒 介绍几个相对冷门的 React Hook

https://css-tricks.com/react-hooks-the-deep-cuts/

📒 Remix 和 Next.js 的区别

本文对这两个基于 React 的框架进行了逐个特性的比较,它们有很多相似之处,但也有一些关键的区别。

https://www.smashingmagazine.com/2022/07/look-remix-differences-next/

📒 阅读源码之 React 篇

本文并不是要详尽地描述 React 是如何工作的,而是主要关注了 React 的设计和 React 开发人员多年来采用的实践。

https://alexkondov.com/readint-source-code-react/

📒 编程语言是如何实现泛型的

📒 Vue 编译三部曲

Vue 编译三部曲:如何将 template 编译成 AST

Vue 编译三部曲:模型树优化

Vue 编译三部曲:最后一曲,render code 生成

📒 字节一面:TCP 和 UDP 可以使用同一个端口吗

📒 如何在繁重的工作中管理好自己的时间和精力

📒 「万字总结」🍒动画 + 大白话讲清楚React渲染原理

📒 Go语言中常见100问题-#85 Not using table-driven tests

📒 小程序不让用 JS 解释器?那我再肛一次鹅厂

· 8 min read
加菲猫

📒 NestJS v9 发布

https://trilon.io/blog/nestjs-9-is-now-available

📒 如何遍历 map

首先,map 本身是可迭代对象,可以通过 for...of 遍历。

第二,可以将 map 转为数组进行遍历,实际还是利用了迭代器接口,但是可以利用数组方法链式调用。

map 默认迭代器接口是 entries,可以自定义例如 [...map.values()]

📒 开发小技巧

Antd 的 Modal 既可以通过组件方式,也可以通过 modal method 方式使用,后者比组件更方便,不需要自己维护状态,但是会有一个问题,如果需要通过弹框内部的按钮,控制弹框更新、关闭,我们没办法直接给弹框内部的元素传递 modal.update,因为此时 Modal.success() 还没有执行结束,modalundefined,如何解决呢?

实际上可以通过不可变引用解决这个问题,我们先定义一个对象 ctx,在里面定义一个 update 方法,但什么也不做。然后给弹框内部按钮传入 (e) => ctx.update(e),这样是可以正常调用,不会报错。然后在 Modal.success() 执行完成之后,这个时候就可以访问 modal 对象了,我们用 modal.update 去替换之前的空函数,这样当事件触发之后,调用的 modal.update() 就可以控制弹框更新了。

const renderQuizModal = ({
quizId,
unitId,
handleOk,
}) => {
const ctx = {
update: (e: CheckboxChangeEvent) => {},
};

const modal = Modal.success({
title: quizName,
width: 600,
okButtonProps: {
disabled: true,
},
content: (
<Checkbox onChange={(e: CheckboxChangeEvent) => ctx.update(e)}>
勾选此项
</Checkbox>
),
onOk: () => {
handleOk?.();
},
})

ctx.update = (e: CheckboxChangeEvent) =>
modal.update({
okButtonProps: {
disabled: !e.target.checked,
},
});
}

如何强制重新挂载组件?如果修改 props 或者 setState 只是触发组件 rerender,实际上是组件更新的过程,有时候需要强制组件重新挂载,可以修改组件的 key

为何有时候没有给域名配置 host 还是可以访问?这是因为在容器中部署,可以通过 Docker 的 Networking 实现容器通信。

⭐️ 「React进阶」React中没有keepalive?没事!手把手教你从零到一设计并实现一个!

⭐️ 现在前端面试都问什么「字节、蚂蚁、美团、滴滴面试小记」

📒 2022 年值得推荐的 Vue 库

📒 【第2676期】一个 Safari 的小 Bug,探索出了 fetch 和 xhr的新玩法

📒 Vite 也可以模块联邦

📒 开发一个 CLI 模板库可以点亮哪些技能点

📒 Golang 实现一个 JS 打包器

Golang 解析 JS AST:

Webpack 打包原理:

📒 天天造轮子第七天 - 中间件实现 - Compose 的 N 种姿势

📒 使用Vite和TypeScript带你从零打造一个属于自己的Vue3组件库

📒 如何使用 React Hooks 重构类组件

📒 Why DRY is the most over-rated programming principle

https://gordonc.bearblog.dev/dry-most-over-rated-programming-principle/

📒 What makes a great software engineer

https://swizec.com/blog/what-makes-a-great-software-engineer/

📒 构建面向未来的前端架构

本文是关于前端架构的组件部分。如果有写过组件,可能都有遇到随着业务迭代而快速增加复杂度,最终写出臃肿不堪难以维护的组件。为啥别人写的代码简洁易懂?缺的是经验吗?不是,缺的是方法论。我觉得此方法同样适用非组件场景。

心智模型的重要性。心智模型会影响我们的决定,进而影响代码的整体结构。如果一直做错误的大大小小的决定,那代码很快就会变成屎山。每个人的心智模型不可能完全一样,所以注定会做出不同的决定。对于团队而言,用框架和工具约束,让大家不做或少做决定是个很好的策略,比如用 prettier 统一编码风格。

文中有个例子。你写了一个组件,过了一周,产品迭代,而之前写的组件不能很好满足新需求。这时你有两个选择,A)思考之前的抽象是否正确,如果不正确,分解了重新做,B)增加一个额外 props,组件里加一些恶心的条件判断。你会如何选择?你会在乎之前投入的沉没成本还是面向未来考虑更多?其实没有对错,注意 By Scene。

自上而下 vs. 自下而上。「你可以自上而下或自下而上地构建。也就是说,你可以从构建层次结构中较高的组件开始。在比较简单的例子中,通常自上而下更容易,而在较大的项目中,自下而上更容易,并在构建过程中编写测试。」

自上而下是直观的、能快速出货的,大家通常也会这么干。当涉及到分解用户界面时,在功能区域周围画上方框,然后成为你的组件。这种功能分解的过程是自上而下的,通常会直接导致创建具有特定抽象性的专门组件。需求会改变。而在几个迭代过程中,这些组件很容易迅速变成单体巨石组件。

单体巨石组件有不少问题,包括 1)不容易复用子组件 2)包变大,比如 SSR 场景可能只希望渲染第一时间被用户看到的组件从而提速 3)rerender 问题导致运行时性能不好,也会让代码复杂,出现很多不必要的 memo 调用 4)不好的抽象导致项目复杂,迭代困难。「敏捷软件开发最重要的经验之一是迭代的价值;这在软件开发的各个层面都是正确的,包括架构。」

自下而上不那么直观,最初可能比较慢。因为这种方式会产生很多小组件,而实际中不是每个小组件在最初都需要可复用。所以前期需要花更多时间和努力,让复杂性被封装在每个小组件里。好处是长远看会更快,因为适应性更强。同时避免了单体巨石组件和前面介绍的他会带来的大量问题。

https://frontendmastery.com/posts/building-future-facing-frontend-architectures/

· 4 min read
加菲猫

📒 Vite 3.0 正式版发布

Vite 3.0 发布: 核心更新盘点与分析

Vite 3.0 正式发布,下一代前端构建工具!

https://vitejs.dev/blog/announcing-vite3.html#dev-improvements

📒 nestjs + prisma 开发全栈项目

https://www.prisma.io/docs/getting-started

https://www.prisma.io/nestjs

📒 成为优秀的TS体操高手 之 TS 类型体操前置知识储备

📒 如何在React中应用SOLID原则

📒 2022 年 CSS-in-JS 技术的又一匹黑马!

📒 还在用命令行看日志?快用Kibana吧,可视化日志分析YYDS!

📒 【面试造火箭,入职拧螺丝】万字详解如何从0开始手写一个Promise

⭐️ Webpack5 核心原理与应用实践

📒 Webpack 特有的优化策略

由于 Webpack 出现的时候,还没有 ESM 规范,所以 Webpack 底层根据 CJS 规范实现 __webpack_require__ 加载模块,这就导致 Webpack 打包会出现大量模板代码,增加打包后体积。相比之下,Rollup 基于 ESM 规范打包,产物代码就很干净。

1. Scope Hoisting

作用域提升,个人觉得这个应该是参考了 Rollup,但是 Webpack 的模块合并还是非常有限,必须是只引用了一次的模块才能合并,否则会造成模块冗余问题。

默认 optimization.concatenateModules 在生产环境下会启用:

module.exports = {
//...
optimization: {
concatenateModules: true,
},
};

https://webpack.docschina.org/plugins/module-concatenation-plugin/

2. 确定性模块 ID

生产环境下,Webpack 的模块 ID 默认按模块解析顺序自增,即使源码没有修改,但是有时模块 ID 会发生变化,导致哈希改变,文件缓存失效。通过配置 moduleIds: 'deterministic' 有利于持久化缓存:

module.exports = {
//...
optimization: {
moduleIds: 'deterministic',
},
};

https://webpack.docschina.org/configuration/optimization/#optimizationmoduleids

3. Runtime Chunk

运行时代码单独分包,一般 SPA 应用问题不大,多页应用打包,运行时代码单独分包可以配置持久化缓存。配置 runtimeChunk: 'multiple' 会为每一个 Initial Chunk 添加一个 Runtime Chunk,配置 runtimeChunk: 'single' 则会创建一个所有 Initial Chunk 共享的 Runtime Chunk:

module.exports = {
//...
optimization: {
runtimeChunk: {
name: 'runtime',
},
},
};

https://webpack.docschina.org/configuration/optimization/#optimizationruntimechunk

📒 MySQL Redo Log 深入探索

⭐️ 详解 Vite 依赖预构建流程

⭐️ VueUse scripts,他们都模仿过的脚本

⭐️ 【第2669期】前端开发中的流程自动化与提效实践

📒 隔离并修复 Node 应用程序中的内存泄漏

📒 硬件加速中的“层”和层叠上下文中的“层”,是一个东西吗

📒 《Go学习路线图》带你少走弯路,Let's Go !

📒 前端原型链污染漏洞竟可以拿下服务器shell

📒 我在 Shopee 工作这两年

📒 五个 React-Query 和 SWR 的小技巧

⭐️ ⭐️ 「React 进阶」 React 全部 Hooks 使用大全 (包含 React v18 版本 )

📒 React 状态管理的新浪潮

⭐️ ⭐️ 函数式编程术语

· 3 min read
加菲猫

📒 为什么 React 的 Diff 算法不采用 Vue 的双端对比算法

📒 Module Federation最佳实践

📒 react18新特性及实践总结

📒 模块加载机制

commonjs 加载一个 module

webpack_require -> vm.runInContext

📒 Nodejs Module Wrapper

Before a module's code is executed, Node.js will wrap it with a function wrapper that looks like the following:

(function(exports, require, module, __filename, __dirname) {
// Module code actually lives in here
});

https://nodejs.org/api/modules.html#the-module-wrapper

📒 微前端/qiankun

📒 如何进阶TypeScript功底?一文带你理解TS中各种高级语法

📒 【第2662期】低代码平台架构深度剖析

📒 那些关于DOM的常见Hook封装(二)

📒 antd mobile 作者教你写 React 受控组件和非受控组件

📒 我对 React 实现原理的理解

📒 WebAssembly生态及关键技术综述

📒 HTTP3 RFC标准正式发布,QUIC会成为传输技术的新一代颠覆者吗

📒 如何将传统 Web 框架部署到 Serverless

📒 新来个技术总监,把 RabbitMQ 讲的那叫一个透彻,佩服!

📒 关于前端主题切换的思考和现代前端样式的解决方案落地

⭐️ Data Flow in Remix

React 第一次和大家见面时,最引人注目的特点之一是他的「单向数据流」。这在官方文档 Thinking in React 里仍有介绍。用一句话概况即:UI 是状态的函数,或者叫 ui=fn(state)

而后有不少遵从这种思想的数据流方案,比如 Redux、MobX 等,以 View -> Action -> State 这种循环的单向数据流方式进行。他们的缺点是这个数据流只在客户端运转,而一个应用通常还需要持久化数据和同步数据,这意味着还要有另一条数据流来和服务端做交互。

那有没有贯穿服务端和客户端的单向数据流?Remix!哈哈。Remix 将这一理念延伸到持久化数据的 API 层,通过 Loader 和 Action 把数据流串了起来,形成 Loader > Component > Action 的单向数据流。所以在 Remix 中,开发者也无需使用 Redux 等其他数据流方案。

Data Flow in Remix

MDH 前端周刊第 60 期:Fresh 1、SPA、框架流行度、1X 工程师、Father 4 RC

📒 巨石瓦解!我把Vue3巨石项目拆成了十几个微应用

· 7 min read
加菲猫

📒 前端四种序列化

1. JSON 序列化

使用 JSON.stringify() 进行序列化,对应的 Content-Type 是 application/json

2. Query String 序列化

使用 new URLSearchParams() 进行序列化,对应的 Content-Type 是 application/x-www-form-urlencoded

注意 URL query string 与 body 发送的 query string 略有不同,特别是对空格的处理

3. FormData 序列化

使用 new FormData() 创建,对应的 Content-Type 是 multipart/form-data

4. XML 序列化

使用 new XMLSerializer() 进行序列化,一般用于 DOM 对象。

📒 React 18 新特性

  • Selective Hydration
  • Offscreen

📒 Vue 2.7 正式发布,代号为 Naruto

📒 线上服务器老是卡,该如何优化

📒 【第2657期】前端JS攻防对抗

📒 Redis 唯快不破的秘密

📒 新一代 npm 包构建工具 father 4 RC 发布

father 4 支持 Bundless 和 Bundle 两种构建模式。

  • Bundless 指把所有源码文件单独编译、平行输出做发布。在 father 4 中,输出 ESModule 及 CommonJS 产物时会使用 Bundless 构建模式
  • Bundle 指把源码按 entry 打包成 1 个或多个文件做发布,也就是 Webpack 的打包模式。在 father 4 中,输出 UMD 及依赖预打包产物时会使用 Bundle 构建模式

依赖预打包

  • 一是 NPM 包发布后安装体积更小、速度更快
  • 二是不担心三方依赖更新引起 Bug
  • 三是NPM 包发布后安装 0 warning

不过,由于依赖中可能存在 dynamic require/import 等复杂的情况,现阶段不一定每个依赖都能顺利打包,father 4 会在 RC 阶段持续优化,将这项功能变得更加好用。

新一代 npm 包构建工具 father 4 RC 发布

📒 【第2656期】使用 React Testing Library 的 15 个常见错误

📒 【第2655期】携程基于 GraphQL 的前端 BFF 服务开发实践

📒 聊聊 Vue 的双端 diff 算法

📒 面试官:Vue的KeepAlive怎么实现的?我:这有啥好问的

📒 如何优雅的写 Controller 层代码

📒 这些 hook 更优雅的管理你的状态

📒 干货 | Trip.com APP QUIC应用和优化实践

📒 基于 qiankun 的微前端实践

📒 [科普文] 浅谈 Function Programing 编程范式

📒 Taze - 一个让你的依赖保鲜的现代 cli 工具,支持定制、支持 monorepo

https://github.com/antfu/taze

📒 如何利用 Why、What、How 框架更好地写作

做项目时,要写三种类型的文档,单页文档、设计文档和 Review 文档,见图1,分别是写于启动前、实施前和完成后。单页文档写给老板看,介绍问题、预期结果、建议的解决方案和其他高层次的点;设计文档程序员可以理解为 RFC,写给同行或下属看,包含方法论、系统设计、实验结果等;Review 文档用于 Review 成功和失败的点。

文档怎么写?用「Why、What、How」的框架。听起来很简单,小学一年级老师也这么教,但作者的大部分文档都是用这个框架。Why 是让听众理解问题和背景,注意站在听众的角度,比如不要对着老板聊技术的 Why,也不要对着技术同学聊规划的 Why;What 讲解决方案是什么样子,以及可以做什么;How 讲如何实现 Why 和 What。

其中「Why」部分可以用 5 Why(https://en.wikipedia.org/wiki/Five_whys)的方法,连续问 5 个 Why,以便找出问题的根本原因。

此外还要注意「Who」,即你的听众是谁。为老板和为工程师写的文档差异会很大,因为不同人关注的点不同,前者更关心客户痛点、商业成果、投资回报率,后者更关心技术要求、设计选择、API 规范。

不同文档类型应用上述框架的例子见图 2。

文章内还有个金句,「Writing docs is expensive, but cheap.」文档很贵,需要花时间写、Review 和迭代,这些时间本可以花在写代码上。文档又很便宜,通过文档可以避免建立不靠谱的兔子洞项目,不靠谱的项目就算做出来也没人用,这个浪费是巨大的。所以,不要做「问题模糊、解决方案有争议」的项目。

https://eugeneyan.com/writing/writing-docs-why-what-how/

⭐️ 看懂 Lighthouse 中 Performance 核心指标

📒 前端抢饭碗系列之Docker容器编排

📒 为什么 2022 年 ESM 又被发布了一次

📒 漫谈 CSS 方法论

📒 HTTP 新增的 103 状态码,这次终于派上用场了!

📒 买啥高并发课程,白嫖不香么?(包括 PDF)

📒 小程序长列表优化实践

📒 前端食堂技术周刊第 42 期:Vue 2.7 Beta、TS 4.8 Beta、React 开源奖、ECMAScript 2022

📒 封装一个管理 url 状态的 hook

· 4 min read
加菲猫

📒 如何从微小细节着手,参与开源贡献

📒 【第2650期】研发同学应该如何负责好一个项目

📒 手写 Vue3 响应式系统:实现 computed

📒 ECMAScript 2022 正式发布,有哪些新特性

📒 手写 Vue3 响应式系统:核心就一个数据结构

📒 通过这两个 hook 回顾 Set/Map 基础知识

📒 React Hooks 使用注意事项

哪些变量应该放进依赖项里面:

  • 与视图渲染有关的变量,例如 propsstatecontext
  • 一些派生的状态,例如 useCallbackuseMemo 的返回值

哪些不应该放进依赖项里面:

  • 与视图渲染无关的变量,例如 ref

这是因为 useRef 返回的引用在整个组件生命周期中保持不变,不存在闭包陷阱问题

📒 React 性能优化策略

引起组件更新的因素:

  • props(包括父组件 rerender 引起子组件 rerender)
  • state(在组件内部 setState 触发调度更新)
  • context(全局状态改变,通知订阅状态的组件更新)

在不做任何优化的情况下,即使 props 没有改变,但是如果父组件 rerender,会导致子组件 props 对象重新生成,由于 React 默认的性能优化策略是 props 严格相等比较,所以不可避免地导致子组件以及所有的子孙组件 rerender。

严格相等比较 高效但是难命中,只有当前组件没有 rerender 才能保证后续组件树都不 rerender

使用了 React.memo 之后,会改为对 props 进行 浅比较,这样可以避免一些不必要的 rerender。

浅比较 容易命中但是有一定性能开销,因为需要遍历对象

📒 如何封装 cookie/localStorage/sessionStorage hook

📒 【第2648期】如何在 Vue 项目中,通过点击 DOM 自动定位VSCode中的代码行

📒 HTTP史记 - 从HTTP/1到HTTP/3

📒 Umi 4 发布啦!

📒 记录第一次给开源项目提 PR

📒 Redis 高可用原理

📒 如何移除你项目中99%的JS代码

📒 浅谈前端项目里如何用 Logger 做好日志管理

📒 如何让定时器在页面最小化的时候不执行

📒 一道有挑战性的 React Hook 场景题,考考你的功底

📒 TypeScript 深水区:3 种类型来源和 3 种模块语法

📒 我为 Netty 贡献源码 | 且看 Netty 如何应对 TCP 连接的正常关闭,异常关闭,半关闭场景

· 6 min read
加菲猫

📒 组件库开发新工具 Histoire

Vue 核心团队成员开发,底层基于 Vite,目测比 dumi 好用:

https://github.com/histoire-dev/histoire

📒 如何做好一个技术分享

最近有同事做了技术分享,发现了一些问题,在这里总结一下。

做技术分享也跟写文章一样,是有条理的,例如:

  • 先讲项目背景,现有方案存在哪些痛点(重点,技术不能为了用而用)
  • 然后再讲讲怎么做技术选型的,有哪些竞品,各自优缺点,可以简单介绍实现原理(有自己的思考,而不是上级让你做 xx 预研就直接做了)
  • 再讲团队中是如何落地的,实践过程中遇到哪些问题,是如何解决的,存量工程迁移方案(重点,节省其他同事的时间,避免重复踩坑)
  • 最后可以总结一下,该方案落地相比现有方案提升的点,此外还存在哪些问题,在选型的时候需要重点考虑

需要避免的几个点:

  • 避免开门见山,可以做一些必要的铺垫,以防有同事对相关技术不了解,为了理解你的内容,还得自己查资料
  • 避免长篇大论都在讲底层架构、底层原理,没多少人会感兴趣,还不如多讲一下自己在实践过程中遇到哪些问题、怎么解决,有哪些心得体会,这样对别人帮助更大
  • 避免内容空洞,例如讲了一大堆新特性,但都没有自己实践过,亦或是说各种性能好、各种优化,但没有实际的数据支撑,没有可以量化的指标、没有与竞品对比等等
  • 搞清楚技术分享的目的,不是给其他同事上课,而是重在分享经验。可以是自己实践过程中踩了哪些坑,或者自己搭建了一套项目模板,可以直接开箱即用

📒 执行 yarn create 命令背后做了哪些

执行 yarn create <starter-kit-package>,会先全局安装 create-<starter-kit-package>,如果已安装则会更新到最新版本,然后会执行 bin 字段中定义的脚本。

例如,yarn create react-app my-app 相当于:

$ yarn global add create-react-app
$ create-react-app my-app

📒 HTTP/3发布了,我们来谈谈HTTP/3

📒 GitHub中文排行榜

📒 80%的Linux都不懂的内存问题

📒 十分钟带你入门 Web Components

📒 前端开发技术与业务的思考

📒 【第2642期】基于 Serverless 的业务轻研发模式探索

📒 React新文档:不要滥用Ref哦

📒 async 函数注意事项

async 函数中,当有一个 await 后面的 Promise 状态变为 rejected,整个 async 函数执行就中断了。

这个在串行请求中非常有用。在很多场景下,我们需要将上一个请求返回的结果,作为参数进行下一次请求。假如上一个请求报错,那么结果自然获取不到,如果此时还进行下一个请求,这个逻辑显然有问题。因此,借助 async 函数的特性,在上一个请求报错的情况下,整个函数执行就断掉了,后续不会再发请求,无需手动进行异常处理。

📒 我与Go的故事、我为什么推荐你学Go以及我的学习路线

📒 CDN 为什么这么设计

📒 Vue3.0 响应性原理

📒 一文读懂 TypeScript 泛型及应用

📒 记录一次切换包管理器引发的血案

📒 数据库表结构设计一点心得和经验

📒 2021-2022,我在大厂的前端最佳实践

monorepo 工具除了最基本的代码共享能力外,还应当至少具备三种能力,即:

  • 依赖管理能力。随着依赖数量的增加,依旧能够保持依赖结构的正确性、稳定性以及安装效率
  • 任务编排能力。能够以最大的效率以及正确的顺序执行 Monorepo 内项目的任务(可以狭义理解为 npm scripts,如 build、test 以及 lint 等),且复杂度不会随着 Monorepo 内项目增多而增加
  • 版本发布能力。能够基于改动的项目,结合项目依赖关系,正确地进行版本号变更、CHANGELOG 生成以及项目发布

2021-2022,我在大厂的前端最佳实践

📒 Ramda 哪些让人困惑的函数签名规则

📒 Github上8个很棒的React项目

📒 全网最强 JVM 来袭

📒 useEffect 怎么支持 async...await

· 6 min read
加菲猫

📒 【第2638期】前端安全之 CSRF 攻击原理和防护方法

📒 何时发起 fetch 请求?试试在 React Router 中吧

这是一则近期在 Reactathon 中的演讲。Remix 创始人之一的 Ryan Florence 极力推荐了在 React Router 中去做 fetch 请求。

https://www.youtube.com/watch?v=95B8mnhzoCM

📒 React Route v6.4 版本已进入预发布阶段

https://github.com/remix-run/react-router/releases/tag/v6.4.0-pre.2

📒 最新一期的 20minJS 请来了 Mark Erikson,主要讨论了 状态管理以及 Redux Toolkit

https://podcast.20minjs.com/1952066/10665172-episode-12-redux-toolkit-and-state-management-in-react-with-mark-erikson

📒 Storybook v6.5 版发布:旨在提升生产力的新工作流

这款流行的组件开发工具库本次发布了许多新功能,包括在浏览器中验证用户行为的交互测试,一个将 story 和 variant 连结起来的 Figma 插件以及引入了 Webpack 5 的惰性编译用来提高启动速度等。

https://storybook.js.org/blog/storybook-6-5/

📒 Glide Data Grid v4.0 版发布:一款高效的 React 数据网格库

它自称是一款“毫不妥协,速度飞快的数据网格”。它支持高达百万条数据的多样化渲染,且支持 TypeScript。主页上还有一个简洁的 Demo,它支持 MIT 许可证。详情请看 GitHub 仓库。

https://grid.glideapps.com/

📒 开发一个浏览器插件从未如此简单

📒 深入浅出 npm & yarn & pnpm 包管理机制

📒 pkg.land:发现 npm 包的替代品的方式

https://pkg.land/

📒 平时的工作如何体现一个人的技术深度?

📒 关于前端大管家 package.json,你知道多少?

📒 【第2636期】从"微前端"到“微模块”

📒 你还在直接用 localStorage 么?该提升下逼格了

📒 ahooks 中那些控制“时机”的hook都是怎么实现的?

📒 实现一个实时预览的 json 编辑器组件(react 版)

📒 微信团队分享:微信后台在海量并发请求下是如何做到不崩溃的

📒 使用 -force 被认为是有害的;了解 Git 的 -force-with-lease 命令

📒 使用 Three.js 实现"雪糕"地球,让地球也凉爽一夏

📒 从0到1带你用webpack 5构建monorepo项目——上篇

📒 content-visibility 再探究,完美替代 Lazyload?

直接看结论:

  • 在一些需要被频繁切换显示、隐藏状态的元素上,使用 content-visibility: hidden,用户代理无需重头开始渲染它和它的子元素,能有效地提升切换时的渲染性能;
  • content-visibility: auto 的作用更加类似于虚拟列表,使用它能极大地提升长列表、长文本页面的渲染性能;
  • 合理使用 contain-intrinsic-size 预估设置了 content-visibility: auto 元素的高宽,可以有效避免滚动条在滚动过程中的抖动;
  • content-visibility: auto 无法直接替代 LazyLoad,设置了 content-visibility: auto 的元素在可视区外只是未被渲染,但是其中的静态资源仍旧会在页面初始化的时候被全部加载;
  • 即便存在设置了 content-visibility: auto 的未被渲染的元素,也并不会影响全局的搜索功能。

content-visibility 再探究,完美替代 Lazyload?

📒 冷知识!使用 display: contents 实现幽灵节点?

📒 基于 Vue3 和 TypeScript 项目大量实践后的思考

📒 ahooks 是怎么解决用户多次提交问题?

📒 这还是我最熟悉的package.json吗?

📒 npm init @vitejs/app的背后,仅是npm CLI的冰山一角

📒 不到 100 行代码,实现 React Router 核心逻辑

📒 ahooks 是怎么解决 React 的闭包问题的?

📒 如何使用插件化机制优雅的封装你的请求hook

📒 【第2633期】JavaScript运行时环境和标准

📒 TS 的 esModuleInterop 与 allowSyntheticDefaultImports 配置

📒 NPM 发包脚本加上下面这段代码

const npmPublish = async () => {
const scripts = [
"npm set-script postinstall \"\"",
"npm publish",
"npm set-script postinstall \"patch-package\"",
];
await scripts.reduce(
(prev, script) => prev.then(() => runScript(script)),
Promise.resolve()
);
}

这里的 reduce() 确保了 Promise 按顺序调用,而 Promise.all() 并发执行不保证顺序

📒 【第2632期】微前端框架 Satum 的性能优化策略

📒 大家都能看得懂的源码(一)ahooks 整体架构篇

📒 React新文档:不要滥用effect哦

📒 你还不会写 vite 插件吗?没关系,我教你啊

📒 用 Node.js 手写一个 DNS 服务器

· 9 min read
加菲猫

📒 为什么不建议用 switch...case 实现策略模式

相比 if...else 来说,switch...case 已经有了明显提升,但还是不适合用来编写策略模式。

这是因为 switch...case 实际上违背了 开闭原则,即对扩展开放,对修改封闭。例如当我们需要增加规则的时候,就需要靠修改代码来实现。

从这一点来说,用 JS 对象或者 Map 对象来实现策略模式就要灵活很多,可以动态扩展规则。

📒 干货 | 携程机票前端Svelte生产实践

📒 通过 Preact 看 Diff 算法细节

📒 Vite 打包流程

首先调用 rollup 方法(Rollup 的编程式 API)编译出 bundle 添加到 build 数组中,接下来就是遍历它,进行 bundle 的写操作(即输出到硬盘上),因为 vite 使用的是 Rollup 完成文件的打包,所以这里调用的是 bundle.write 来将文件输出到硬盘上。

packages/vite/src/node/build.ts
for (const build of builds) {
const bundle = await build.bundle;
const { output } = await bundle[write ? 'write' : 'generate']({
dir: resolvedAssetsPath,
format: 'es',
sourcemap,
entryFileNames: `[name].[hash].js`,
chunkFileNames: `[name].[hash].js`,
assetFileNames: `[name].[hash].[ext]`,
...config.rollupOutputOptions
});
build.html = await renderIndex(output);
build.assets = output
await postBuildHooks.reduce(
(queue, hook) => queue.then(() => hook(build as any)),
Promise.resolve();
)
}
tip

注意 Vite 2.x 源码结构稍有不同,但是整体流程还是类似的:

https://github.com/vitejs/vite/blob/ab23e6e7b490cf610a4465cc533f671a729fdfa8/packages/vite/src/node/build.ts#L543

这里有一个值得学习的地方,这边 postBuildHooks 的类型定义是 ((build: any) => Promise<any>)[],如何保证调用顺序,即上一次调用完成后进行下一次调用?

通常我们用 reduce 做管道操作都是不能用于 Promise,因为管道操作需要将上一次调用的返回值,作为参数传入下一次调用,但 Promise 的话很可能是 pending,根本拿不到上一次调用的返回值。所以一般来说我们只能将 reduce 改成普通 FOR 循环:

let initialValue = Promise.resolve();

for (const hooks of postBuildHooks) {
initialValue = await hook(build);
}

而源码中对 reducer 函数进行了包装,将 hook 的执行放到 then 方法回调中,这样就可以保证调用顺序:

await postBuildHooks.reduce(
(queue, hook) => queue.then(() => hook(build as any)),
Promise.resolve();
)

vite 不支持 ie 11?configureBuild Hook 帮你定制 bundle 打包过程

📒 VS Code 如何快速定位到问题代码

在 TS 项目中,经常会因为类型问题出现报错,因此需要快速定位到问题代码。

在 VS Code 中可以使用 Ctrl + Shift + M 快捷键打开问题面板,可以看到当前文件中所有的 errors 和 warnings。此时,按 F8 可以依次跳转查看当前文件中的问题。

📒 20个GitHub仓库助你成为React大师

📒 从零开始实现一个简单的低代码编辑器

⭐️ 从arco-design的collapse组件分析如何吸收开源项目的知识

📒 模块联邦浅析

📒 我们是怎么在项目中落地qiankun的

📒 【第2631期】浅谈 Atomic CSS 的发展背景与 Tailwind CSS

📒 通过 JS 运行时堆快照进行 Web 爬虫

当网站提供的接口无法满足需求的时候(甚至可能连接口都没有),爬虫可能是一种不太理想的解决方案。虽然 Puppeteer 和 Playwright 使控制无头浏览器变得容易,但是获取你需要的数据,还是会很复杂。如果你可以从网站的页面堆中提取数据呢?Puppeteer Heap Snapshot 是这个实验的最终结果。

https://www.adriancooney.ie/blog/web-scraping-via-javascript-heap-snapshots

📒 JS 清空数组的方式

以下两种清空数组的方式有何区别:

let arr = [...];

// 这种是 immutable 的方式
// 即创建一个空数组,用该空数组指针替换原数组的指针
// 不影响其他引用原数组内存地址的变量
arr = [];

// 这种是 mutable 的方式
// 即直接修改原数组,不创建新数组,仍然是原数组指针
// 会影响其他引用原数组内存地址的变量
arr.length = 0;

📒 【零基础】充分理解WebGL(三)

📒 Go Error 处理最佳实践

📒 Map 对象小技巧

Map 对象可以记住键值对插入顺序,那么如何获取顺序呢?答案是通过迭代器接口。然后迭代器接口可以直接遍历,也可以转为数组,这样就变成获取数组第一个元素了。

按照这个思路,实际上也可以用 Map 实现队列

📒 Web3.0开发入门

📒 从源码中来,到业务中去,React性能优化终极指南

📒 剖析React核心设计原理—Virtual Dom

📒 前端工程化:保姆级教学 Jenkins 部署前端项目

📒 正则表达式完整指南

📒 【第2630期】javascript中的依赖注入

📒 【前端部署附录一】写给前端的 docker 使用指南

📒 Chrome 如何调试移动端 H5 页面

chrome://inspect/#devices

📒 支付宝体验科技 Umi 系列文章

Umi 4 特性 05:稳定白盒性能好的 ESLint

📒 如何回滚 Git 分支代码

# 找到需要回滚的版本哈希,执行 git reset
$ git reset --hard HEAD^
# 然后强制 push
$ git push -f -u origin pre

拜托,不要再问我Git如何回滚代码

📒 如何华丽的实现一套脚手架 - 以umicli和转转zzcli为例

📒 深入浅出 npm & yarn & pnpm 包管理机制

📒 一文带你进入微前端世界

📒 你还在手动部署埋点吗?从0到1开发Babel埋点自动植入插件

📒 一个三小时的 React Native 速成课

https://www.youtube.com/watch?v=VozPNrt-LfE

📒 使用 Three.js:一款流行的 3D JavaScript 库

https://betterprogramming.pub/working-with-three-js-the-popular-3d-javascript-library-bd2e9b03c95a?gi=8c31e429644f

📒 Next.js 后续规划的 RFC:即将到来的重大变化

https://nextjs.org/blog/layouts-rfc

📒 2022 年 React 状态管理库综述

React 的优势在于它可以灵活地适应不同的开发方式,其中也包括状态管理方面。这篇文章总结了几个流行的状态管理库,包括 Zustand、Recoil(来自 Facebook)、XState,当然还有 Redux。

https://www.albertgao.xyz/2022/02/19/react-state-management-libraries-2022/

📒 深入浅出前端做控制反转与依赖注入

⭐️ ⭐️ 现代 Monorepo 工程技术选型,聊聊我的思考

总结一下:

  • 使用 PNPM 作为 monorepo 项目的包管理工具
  • 使用 Changesets 作为 monorepo 项目的发包工具
  • 使用 Turborepo 作为 monorepo 项目多包任务执行工具

现代 Monorepo 工程技术选型,聊聊我的思考

📒 MySQL 主从,6 分钟带你掌握

📒 【第2628期】基于设计稿识别的可视化低代码系统实践

📒 前端配置化真香~上班又多了60%的摸🐟时间

- - + + \ No newline at end of file diff --git a/2022/page/4/index.html b/2022/page/4/index.html index db94268623..558b751cc1 100644 --- a/2022/page/4/index.html +++ b/2022/page/4/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

· 11 min read
加菲猫

📒 如何将数组转为对象

之前在业务中遇到一个场景,配置 Webpack alias 的时候,会出现很多模板代码:

module.exports = {
resolve: {
alias: {
"@": path.resolve(__dirname, "src"),
"@foo": path.resolve(__dirname, "src/foo"),
"@bar": path.resolve(__dirname, "src/bar"),
}
}
}

那么其实是可以通过数组的方式干掉模板代码:

function constructAlias(arr: string[]): Record<string, string> {
return Object.fromEntries(
arr.map(item => [
item,
path.resolve(cwd, item.replace(/^\@(.*?)$/, '$1'))
])
);
}

const config = ['@', '@foo', '@bar'];

const res = constructAlias(config);
console.log(res);

使用数组的 map 方法映射出一个 entry 数组,可以表示为形如 [key, value][] 的结构,然后使用 Object.fromEntries 将 entry 数组转为对象

这里需要注意,Object.fromEntries 是 ES2019 语法,支持 Chrome >= 73 和 Node.js >= 12.0.0。浏览器环境问题不大,一般都会配置 Babel polyfill 兼容,但是 Node.js 环境就会出一些问题,例如一些 CI 环境的 Node.js 版本很老,就会报错进而导致构建失败。因此通常开发的话,我们应该尽量用数组的 reduce 替代:

function constructAlias(arr: string[]): Record<string, string> {
return arr.reduce((accu, cur) => {
accu[cur] = path.resolve(cwd, cur.replace(/^\@(.*?)$/, '$1'));
return accu;
}, {});
}

📒 An introductory guide to Contiuous Integration and Delivery/Deployment (CI/CD) for Frontend Developers

https://blog.tegadev.xyz/an-introductory-guide-to-ci-cd-for-frontend-developers

📒 基于设计稿识别的可视化低代码系统实践

📒 被diss性能差,Dan连夜优化React新文档

📒 Node.js 调试一路走来经历了什么

📒 如何解决组件库打包条件引入

由于 import 语句必须放在顶层,不能放在条件判断中。如果同时保留两个 import 语句则会导致两个包都被打包进去。所以解决的方案就是在构建阶段动态修改 import 语句,但是需要注意两个问题:

  • 要注意修改时机,假如打包工具依赖分析已经完成,这时候再修改就太迟了
  • 另外还要注意不同打包工具的兼容性,如果开发 rollup 插件,可能导致 webpack、vite 等工具不兼容

因此选择开发 babel 插件,可以兼容各种打包工具。

📒 UMI3源码解析系列之运行时插件机制

📒 推荐一个前端技术选型神器

📒 Webpack 模块构建缓存

模块构建缓存,推荐使用 Webpack5 的 filesystem cache,技术更成熟,可以参考 CRA 的 Webpack 配置:

module.exports = {
cache: {
type: 'filesystem',
version: createEnvironmentHash(env.raw),
cacheDirectory: paths.appWebpackCache,
store: 'pack',
buildDependencies: {
defaultWebpack: ['webpack/lib/'],
config: [__filename],
tsconfig: [paths.appTsConfig, paths.appJsConfig].filter(f =>
fs.existsSync(f)
),
},
},
}

关于持久化缓存,有两个地方需要注意:

  • 默认缓存的路径是 node_modules/.cache/webpack,也就是说,只要删除 node_modules,相当于缓存也被清空了
  • 本地和 CI 环境的缓存是相互独立的,本地的缓存无法在 CI 环境使用。在 CI 环境中需要使用 CI 的缓存机制

https://github.com/facebook/create-react-app/blob/main/packages/react-scripts/config/webpack.config.js

📒 最高性能的包管理器-pnpm

📒 【第2624期】Fastify 如何实现更快的 JSON 序列化

📒 如何设置 npm 私有源

在项目根目录建一个 .yarnrc 文件,配置如下:

# 淘宝源
registry=https://registry.npmmirror.com
# 私有源
@myscope:registry=https://mycustomregistry.example.org

这样的话,package.json 中带有 @myscope 前缀的依赖,例如 @myscope/design-system 都会从私有源下载。

📒 前端多线程编程探索

📒 精妙的配合!文字轮播与图片轮播?CSS 不在话下

📒 并发渲染优化:让文件树的渲染又快又稳

📒 UMI3源码解析系列之构建原理

⭐️ 看了9个开源的 Vue3 组件库,发现了这些前端的流行趋势

对包管理器的总结非常好,推荐看一下。

npm@v3 之前

  • 嵌套结构(nest),会出现大量重复装包的问题
  • 因为是树型结构,node_modules 嵌套层级过深,导致文件路径过长
  • 模块实例不能共享,例如在两个不同包引入的 React 不是同一个模块实例

npm@v3 / yarn

  • 分身依赖:npm@v3 使用扁平化(flat)的方式安装依赖,一定程度上解决了重复装包的问题,但是注意并没有完全解决,例如 A 和 B 依赖了不同版本的 C,会导致 C 被安装两次
  • 幽灵依赖:由于使用扁平化方式安装,package.json 里并没有写入的包竟然也可以在项目中使用了
  • 平铺减少安装没有减省时间,因为扁平化算法比较复杂,时间居然还增加了

npm@v5 / yarn

该版本引入了一个 lock 文件,以解决 node_modules 安装中的不确定因素。这使得无论你安装多少次,都能有一个一样结构的node_modules

然而,平铺式的算法的复杂性,幽灵依赖之类的问题还是没有解决。

看了9个开源的 Vue3 组件库,发现了这些前端的流行趋势

📒 Node.js Web 框架 Midway 入门实战

📒 肝了一个月的 DDD,一文带你掌握

📒 使用 rollup 构建第三方库包括哪些过程

  • 浏览器不兼容的语法转换
    • Vue 文件处理:rollup-plugin-vue
    • JSX、TS 语法编译:rollup-plugin-babel
    • 支持 CSS 加载、添加前缀、压缩、scss/less 预编译:rollup-plugin-postcss
  • 编译兼容
    • 仅限语法转换,不建议 polyfill:rollup-plugin-babel
  • 混淆压缩
    • 对应:rollup-plugin-terser
  • 打包为一份文件(注意 peerDependencies 外部化),多种打包格式,生成类型声明文件等
  • 工程质量保障,例如 ESLint、TS 类型检查、单元测试等
tip

前面两步可以避免业务项目的 babel-loader 处理 node_modules 下的模块,提升构建效率。

📒 如何实现主题切换

关键看场景,如果需要在运行环境动态切换,就需要打包两套样式,然后通过媒体查询之类的方式进行切换。如果不需要动态切换,可以在构建的时候进行变量注入。

自己开发的组件库是否有必要设置主题?样式都不打包,less 变量注入肯定没用的;如果搞个 theme-reset.less,肯定会污染到全局。最好还是在业务工程里面设置主题。

📒 如何做首屏性能优化

1. 路由懒加载

首先想到的就是解决资源冗余问题,我们可以按需投喂 JS 资源,只把渲染当前页面需要的资源投喂给浏览器,对应的方案是路由懒加载。

2. 分包优化

在按需投喂 JS 资源的基础上,对于一些不需频繁修改、体积又很大的依赖进行拆包处理,例如 reactreact-dom,单独分包设置强缓存。

3. 服务端渲染

如果按需投喂 JS 资源还是太慢,可以考虑服务端渲染(SSR),在服务端直接把当前页面的 HTML 丢给浏览器,可以理解为按需投喂 HTML 页面。

4. 静态生成 && 混合渲染

服务端渲染可以理解为在服务端调接口渲染出 HTML 丢给浏览器,但是这个过程还是存在性能开销。对于一些不需要动态数据的页面,例如文档、博客等,可以考虑静态生成(SSG),即在构建的时候就渲染出 HTML,可以极大提升首屏性能,当然更多时候是 SSG 和 SSR 混合渲染。

📒 深入理解 Linux CPU 上下文切换

📒 中后台 CSS Modules 最佳实践

📒 在 React 中实现条件渲染的 7 种方法

⭐️ 2022年值得使用的 Node.js 框架

📒 解决 Vite 无法全局启用 css module 的问题

在这里打个断点看看:

packages/vite/src/node/plugins/css.ts:688
const {
modules: modulesOptions,
preprocessorOptions,
devSourcemap
} = config.css || {}
const isModule = modulesOptions !== false && cssModuleRE.test(id)

📒 useRef 在列表渲染场景需要特别注意

在列表渲染的时候,不能对列表的每一项使用 ref,否则会出现 bug。这种情况下,应该将列表的每一项封装为组件,在组件内部使用 ref

type IProps = {
questionList: string[];
}

const App: React.FC<IProps> = ({ questionList }) => {
const ref = React.useRef();

return (
<>
{questionList.map((item, index) => (
<div
classNames="list-item"
key={index}
ref={ref}
>
{item}
</div>
))}
</>
)
}

📒 100 行代码实现 React 路由

https://github.com/ashok-khanna/react-snippets/blob/main/Router.js

精读《react-snippets - Router 源码》

📒 如何实现多行文本省略

这个功能不需要自己实现,自己实现还可能存在兼容性问题。只需要使用 antd 的 Typography 组件就可以了:

import * as React from "react";
import { Typography } from "antd";

const { Paragraph } = Typography;

const App: React.FC<{}> = () => {
return (
<Paragraph
ellipsis={{ rows: 2, expandable: true, symbol: 'more' }}
>
...
</Paragraph>
)
}

📒 HTTP 的缓存为什么这么设计

📒 vscode插件原理浅析与实战

· 10 min read
加菲猫

📒 PNPM 源码结构 - 前端包管理工具具有哪些功能

首先 pnpm 整个项目的主入口包文件为 packages/pnpm 这个包里面,这个包名称也直接叫做 pnpm ,其中 main.ts 文件是其入口文件,这个文件会处理掉用户传进来的一些参数,然后根据处理后的不同的参数对各命令做一个下发执行工作,下发后的命令参数再到各个包里面去,从而执行里面对应的逻辑。

处理参数用到的包为 @pnpm/parse-cli-args ,它会接收到用户传递进来的命令行参数,然后将其处理成一个 pnpm 内部的统一格式,例如用户输入如下命令:

$ pnpm add -D axios

这里传进来的一些参数都会被 parseCliArgs 这个方法处理:

例如 add 会被处理给 cmd 字段,一些裸的参数例如 axios 会被放进 cliParams 这个数组中,-D 这个参数在 cliOptions 里面去。处理后的这些变量以及参数用于主入口文件后续代码执行逻辑的判断。具体的判断逻辑可以在调试的时候遇到了,再去看对应的入口逻辑判断调试即可,这里不做具体的介绍。

main.ts 中会通过调用当前包下面的 cmd 目录下面的方法(pnpmCmds),来完成各命令的分发。

  • 依赖管理:如果 cmd 值为 addinstallupdate 等这些涉及和依赖安装相关的包,则会走 @pnpm/plugin-commands-installation 这个包里面对应的子命令逻辑(基本上 pnpm 所有的核心模块都围绕依赖安装这一块展开)
  • 打包发布:如果 cmd 值为 packpublish 这一类涉及到打包发布的包,则会走 @pnpm/plugin-commands-publishing 这个包的逻辑
  • 命令执行:如果 cmd 值为 runexecdlx 等这些和命令执行相关的方法,则会走 @pnpm/plugin-commands-script-runners 这个包的逻辑

📒 学习 swr 获取数据的思路

最近遇到很多列表渲染的场景,例如根据筛选项和分页参数获取列表数据。在代码中看到虽然用了 React Hooks,但是获取数据依旧是 jQuery 时代的 命令式 写法。

我们知道,前端框架都是数据驱动、声明式渲染的,即渲染视图不需要命令式地操作 DOM,而是声明式地修改数据就行。因此,获取数据也可以使用 声明式 写法,这样代码更容易维护。

import useSWR from 'swr'

function Profile() {
const { data, error } = useSWR('/api/user', fetcher)

if (error) return <div>failed to load</div>
if (!data) return <div>loading...</div>
return <div>hello {data.name}!</div>
}

https://swr.vercel.app/docs/getting-started

📒 【第2618期】手把手教你定制一套适合团队的微前端体系

📒 Vite 相关 issue 梳理

https://github.com/vitejs/vite/discussions/8232

📒 Chrome debugger 小技巧

在 Chrome 浏览器中打断点调试,此时切到控制台,可以访问断点位置上下文信息,也就是说可以访问、甚至修改变量。

⭐️ 前端必学的动画实现思路,高逼格的效果老板看了都会大声称赞

📒 【第2617期】React 组件库 CSS 样式方案分析

📒 【第2616期】解释JavaScript的内存管理

📒 UMI3源码解析系列之插件化架构核心

插件机制实现的方式:

  • umi:基于 tapable 的发布订阅模式,在路由、生成文件、构建打包、HTML 操作、命令等方面提供能力
  • babel:基于 visitor 的访问者模式,对于 AST 的操作等
  • rollup:基于 hook 的回调模式,定制构建和打包阶段的能力
  • webpack:基于 tapable 的发布订阅模式,loader 不能实现的都靠它
  • vue-cli:基于 hook 的回调模式,在生成项目、项目运行和 vue ui 阶段提供能力

UMI3源码解析系列之插件化架构核心

📒 写了一个基于 MacOS + iTerm2 自动执行化执行工具

📒 介绍全新的 JSX 转换

由于浏览器无法识别 JSX 语法,所以我们需要通过 Babel、TypeScript 等工具将 JSX 编译为浏览器能识别的 render 函数。在 React 17 之前,JSX 会转换为 React.createElement(...) 调用:

import React from 'react';

function App() {
return React.createElement('h1', null, 'Hello world');
}

正是因为 JSX 会转换为 React.createElement(...),所以每个组件顶部必须导入 React

在 React 17 版本,React 的 package 中引入了两个新入口,这些入口只会被 Babel 和 TypeScript 等编译器使用。新的 JSX 转换不会将 JSX 转换为 React.createElement,而是自动从 React 的 package 中引入新的入口函数并调用。下方是新 JSX 被转换编译后的结果:

// 由编译器引入(禁止自己引入!)
import { jsx as _jsx } from 'react/jsx-runtime';

function App() {
return _jsx('h1', { children: 'Hello world' });
}

注意,此时源代码无需引入 React 即可使用 JSX 了!(但是如果使用 React 提供的 Hook 或其他导出,这种情况下仍需引入 React)

新的 JSX 转换对应的配置是 runtime: "automatic"

// babel.config.js

module.exports = {
presets: [
[
"@babel/preset-react",
{
// 新的 JSX 转换 -> automatic
// 旧的 JSX 转换 -> classic
runtime: "automatic"
}
]
]
}
tip

可以直接在 Babel Playground 看编译结果:

https://babeljs.io/repl

官方文档表示,新的 JSX 转换会略微优化包体积,个人认为优化还是比较有限。虽说 React.createElement() 变成了更短的调用,但是又多出来一段运行时代码。

https://react.docschina.org/blog/2020/09/22/introducing-the-new-jsx-transform.html

📒 从 Turborepo 看 Monorepo 工具的任务编排能力

📒 大牛书单 | 学习 Golang 资料

📒 解决前端常见问题:竞态条件

📒 React Router v6 新手指南

https://www.youtube.com/watch?v=59IXY5IDrBA

📒 [调研报告] 新一代前端构建工具汇总

📒 Google 最新的性能优化方案,LCP 提升30%!

📒 React useEvent:砖家说的没问题

useEvent 会将一个函数「持久化」,同时可以保证函数内部的变量引用永远是最新的。如果你用过 ahooks 的 useMemoizedFn,实现的效果是几乎一致的。再强调下 useEvent 的两个特性:

  • 函数地址永远是不变的
  • 函数内引用的变量永远是最新的

通过 useEvent 代替 useCallback 后,不用写 deps 函数了,并且函数地址永远是固定的,内部的 state 变量也永远是最新的。

useEvent 的实现原理比较简单:

function useEvent(handler) {
const handlerRef = useRef(null);

// 用于确保函数内引用的变量永远是最新的
useLayoutEffect(() => {
handlerRef.current = handler;
});

// 用于确保返回的函数地址永远不变
return useCallback((...args) => {
const fn = handlerRef.current;
return fn(...args);
}, []);
}

React useEvent:砖家说的没问题

📒 为什么用 Vite 打包 React 组件库

  • 生产环境 rollup 打包 + 开发环境 devServer
  • 开发环境可以通过 @vitejs/plugin-react 插件支持 fast-refresh
  • 生产环境默认使用 esbuild 代码压缩,效率是 terser 的 20-40 倍
  • esbuild 在语法转换这块尚不完善,但是组件库打包不用考虑兼容性问题,兼容性问题交给业务项目解决
  • Vite 提供了很多 esbuild 尚不支持的特性(例如 CSS 模块化等)
  • 开发环境和生产环境几乎可以复用一套配置(Vite 抹平了 esbulid 和 rollup 配置差异)

· 18 min read
加菲猫

📒 解决 Vite 打包 React 组件库无法排除 peerDependencies 的问题

轮子系列:使用vite从零开发React组件库

如何使用Rollup打包React组件库

使用 dumi 实现组件库文档自动化

https://d.umijs.org/zh-CN/guide/advanced#%E7%BB%84%E4%BB%B6-api-%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90

📒 NodeJs进阶开发、性能优化指南

📒 使用 URLSearchParams 注意事项

很多同学都会用 URLSearchParams 解析、拼接 query 参数,非常方便,而且还能自动进行参数编码、解码。但是在使用的时候,有几个注意事项:

const p = new URLSearchParams();

// 1. 当某个 value 为 undefined 时,会直接转为字符串拼接到 URL 上
p.set("dby", undefined);
p.set("dm", 2333);
p.toString(); // 'dby=undefined&dm=2333'

// 解决方案,使用逻辑或操作
p.set("dby", undefined || "");
p.toString(); // 'dby=&dm=2333'

// 2. get 一个不存在的值,返回的是 null,因此 TS 会推导为联合类型
const foo = p.get("foo"); // string | null

// 解决方案,使用逻辑或操作,实现类型守卫
const foo = p.get("foo") || ""; // string

📒 写给前端的手动内存管理基础入门(一)返璞归真:从引用类型到裸指针

📒 React如何原生实现防抖

📒 你想知道vite核心原理吗,我来手写告诉你(80行源代码)

📒 Rust 入门 - 资源与生命周期

📒 The Ultimate Guide To Software Engineering

📒 Tree shaking问题排查指南来啦

Tree shaking在不同工具里的意义不太统一,为了统一后续讨论,我们规范各个术语:

  • minify:编译优化手段,指在不影响代码语义的情况下,尽可能的减小程序的体积,常见的 minify 工具如 terser、uglify,swc 和 esbuid 也自带 minify 功能
  • Dead code elimination(DCE):即死代码优化,一种编译器优化手段,用于移除不影响程序结果的代码,实现DCE的手段有很多种,如 const folding (常量折叠)、Control flow analysis、也包括下面的 LTO
  • Link Time Optimization:指 link 期优化的手段,可以进行跨模块的分析优化,如可以分析模块之间的引用关系,删掉其他模块未使用的导出变量,也可以进行跨模块对符号进行 mangle http://johanengelen.github.io/ldc/2016/11/10/Link-Time-Optimization-LDC.html
  • Tree shaking:一种在 Javascript 社区流行的一个术语,是一种死代码优化手段,其依赖于 ES2015 的模块语法,由 rollup 引入。这里的 tree shaking 通常指的是基于 module 的跨模块死代码删除技术,即基于 LTO 的 DCE,其区别于一般的 DCE 在于,其只进行 top-level 和跨模块引用分析,并不会去尝试优化如函数里的实现的 DCE

Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. import and export. The name and concept have been popularized by the ES2015 module bundler rollup.

https://webpack.js.org/guides/tree-shaking/

  • mangle:即符号压缩,将变量名以更短的变量名进行替换
  • 副作用:对程序状态造成影响,死代码优化一般不能删除副作用代码,即使副作用代码的结果在其他地方没用到
  • 模块内部副作用:副作用影响范围仅限于当前模块,如果外部模块不依赖当前模块,那么该副作用代码可以跟随当前模块一起被删除,如果外部模块依赖了当前模块,则该副作用代码不能被删除

image

因此我们的后续讨论,所说的 tree shaking 均是指基于 LTO 的 DCE,而 DCE 指的是不包含 tree shaking 的其他 DCE 部分。

简单来说即是,tree shaking 负责移除未引用的 top-level 语句,而 DCE 删除无用的语句

Tree shaking问题排查指南来啦

📒 [科普] JS中Object的keys是无序的吗

1. Object.keys() 返回类型始终为 string[]

因为 JS 对象 key 的类型只有三种:numberstringSymbol,需要注意 number 类型底层也是按 string 进行存储,而 Symbol 类型不可枚举。

2. ES2015 之后 Object.keys() 输出顺序是可以预测的

我们说普通对象的 Key 是无序的,不可靠的,指的是不能正确维护插入顺序,与之相对的是 Map 实例会维护键值对的插入顺序。

在 ES2015 之后,普通对象 Key 顺序是可预测的。先按照自然数升序进行排序,然后按照非数字的 String 的加入时间排序,然后按照 Symbol 的时间顺序进行排序。也就是说他们会先按照上述的分类进行拆分,先按照自然数、非自然数、Symbol 的顺序进行排序,然后根据上述三种类型下内部的顺序进行排序。

使用 Object.keys() 只会输出对象自身可枚举属性的 key,不含 Symbol 类型的 key。如果要输出 Symbol 类型 key,可以使用 Reflect.ownKeys()

[科普] JS中Object的keys是无序的吗

📒 如何设计更优雅的 React 组件

📒 代码覆盖率在性能优化上的一种可行应用

由于 JS 资源需要通过网络加载,代码的体积直接影响页面加载性能。很多时候我们“喂”给浏览器的代码,并不会全部执行,因此我们可以做分包优化,即 code-spliting,只“喂”给浏览器渲染当前页面所需的资源。

注意区分以下两个概念:

  • Dead code

    也叫无用代码,这个概念应是在编译时静态分析出的对执行无影响的代码。通常我们用 Tree Shaking 在编译时移除这些 dead code 以减小代码体积。

  • 冗余代码

    代码覆盖率中的概念,适用于运行时,而 Dead code 适用于编译时。Dead code 是任何情况下都不会执行的代码,所以可以在编译阶段将其剔除。冗余代码是某些特定的业务逻辑之下并不会执行到这些代码逻辑(比如:在首屏加载时,某个前端组件完全不会加载,那么对于“首屏”这个业务逻辑用例来讲,该前端代码就是冗余的)。

如何进行合理分包呢?这就需要统计代码覆盖率。代码覆盖率(Code coverage)是软件测试中的一种度量指标。即描述测试过程中(运行时)被执行的源代码占全部源代码的比例。

如何统计代码覆盖率:

1. Chrome 浏览器 Dev Tools

chrome 浏览器的 DevTools 给我们提供了度量页面代码(JS、CSS)覆盖率的工具 Coverage。使用方式:Dev tools —— More tools —— Coverage

由于一般都会对 JS、CSS 资源进行混淆压缩,因此建议导入 Source Map 以便查看源代码的覆盖率。

2. Istanbul(NYC)

Istanbul或者 NYC(New York City,基于 istanbul 实现) 是度量 JavaScript 程序的代码覆盖率工具,目前绝大多数的node代码测试框架使用该工具来获得测试报告,其有四个测量维度:

  • line coverage(行覆盖率):每一行是否都执行了 【一般我们关注这个信息】
  • function coverage(函数覆盖率):每个函数是否都调用了
  • branch coverage(分支覆盖率):是否每个 if 代码块都执行了
  • statement coverage(语句覆盖率):是否每个语句都执行了

缺点:目前使用 istanbul 度量网页前端JS代码覆盖率没有非侵入的方案,采用的是在编译构建时修改构建结果的方式埋入统计代码,再在运行时进行统计展示。

我们可以使用 babel-plugin-istanbul 插件在对源代码在 AST 级别进行包装重写,这种编译方式也叫 代码插桩 / 插桩构建(instrument)。

代码覆盖率在性能优化上的一种可行应用

📒 关于“环境变量”需要注意的问题

1. 为什么使用 cross-env 设置环境变量

有时候我们需要用 npm scripts 设置 Node.js 的环境变量,通常都会使用 cross-env 这个库。其实设置环境变量,在 MacOS 和 linux 系统直接通过 shell 命令就可以了,例如 PORT=8066,但是 Win 设置的方式不太一样,所以 cross-env 实际上是实现了跨平台设置环境变量。

2. .env 文件是如何生效的

可以使用 dotenv 这个库,可以将 .env 文件下的内容加载到 Node.js 的 process.env 对象中,注意 key 和 value 都是 string 类型。

3. 前端项目的环境变量是如何生效的

前端项目的环境变量,实际上不是真正的环境变量,因为浏览器环境下是访问不到 process 对象的,需要通过 DefinePlugin 在打包构建的时候,将变量替换为对应的值。

注意这里有个坑,DefinePlugin 默认直接进行文本替换,如果想要替换为字符串字面量,则需要在字符串中再加一个引号,或者用 JSON.stringify 包裹:

// webpack.config.js
new webpack.DefinePlugin({
__DEV__: "true", // 替换为布尔值
"process.env.NODE_ENV": JSON.stringify("development"), // 替换为字符串字面量
})

// 源码
if (__DEV__) {
// ...
}

if (process.env.NODE_ENV === "development") {
// ...
}

// 替换得到的结果
if (true) {
// ...
}

if ("development" === "development") {
// ...
}

使用 DefinePlugin 遇到的问题

在开发一个组件库,需要区分运行环境,根据环境打包相应的模块代码。根据 Webpack 代码优化(生产环境默认启用)的时候,terser 会做 DCE(无用代码移除)处理,进而优化打包体积:

// 在 Webpack 代码优化的时候
// terser 会识别出“业务2”的代码为无用代码,进而移除掉
// 只保留“业务1”的代码

if (true) {
// 业务 1
}

if (false) {
// 业务 2
}

原先的方式在一个模块中定义常量,然后其他模块引入常量进行判断。这里要注意一个问题,在 Webpack 代码优化的时候,terser 并不会做程序流分析,也就是说访问不到模块的上下文信息。这种情况下,terser 可能还是会将模块导出的常量当做变量处理,从而导致 DCE 失效。这种情况下,我们不能通过模块方式引入常量,而是要用 DefinePlugin 直接把变量替换为对应的字面量。

📒 治理项目模块依赖关系,试试这艘「依赖巡洋舰」

📒 【前端部署十二篇】使用 CI 中的缓存进行 Pipeline 优化

当我们使用 webpack 5 进行构建时,如果使用了 filesystem cache,因为在磁盘中含有缓存 (node_modules/.cache),二次构建往往比一次构建快速十几倍。

而在 CICD 中,这些都失去了意义,因为 CICD 每次 Job 都相当于新建了一个目录,「每次构建都相当于是首次构建」。

但是,CI 提供了一些缓存机制,可以将一些资源进行缓存。如果每次可以将缓存取出来,则大大加速了前端部署的速度。

【前端部署十二篇】使用 CI 中的缓存进行 Pipeline 优化

📒 UMI3源码解析系列之核心service类初始化

📒 【第2610期】JavaScript Containers

📒 【前端部署十一篇】通过 CICD 实践 Lint、Test、Performance 等前端质量保障工程

在 CI 操作保障代码质量的环节中,可确定以下时机:

# 1. 当功能分支代码 push 到远程仓库后,进行 CI
on:
push:
branches:
- 'feature/**'

# 2. 当功能分支代码 push 到远程仓库以及是 Pull Request 后,进行 CI
on:
pull_request:
types:
# 当新建了一个 PR 时
- opened
# 当提交 PR 的分支,未合并前并拥有新的 Commit 时
- synchronize
branches:
- 'feature/**'

CRA 内部使用 ESLint Plugin 进行代码检查,而非命令的方式。当 ESLint 存在问题时,CRA 如果判断当前是 CI 环境,则直接报错并退出进程,导致打包失败:

new ESLintPlugin({
// Plugin options
// ...
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
})

Lint 和 Test 仅是 CI 中最常见的阶段。为了保障我们的前端代码质量,还可以添加以下阶段:

  • Audit: 使用 npm audit 或者 snyk 检查依赖的安全风险
  • Quality: 使用 SonarQube 检查代码质量
  • Container Image: 使用 trivy 扫描容器镜像安全风险
  • End to End: 使用 Playwright 进行 UI 自动化测试
  • Bundle Chunk Size Limit: 使用 size-limit 限制打包体积,打包体积过大则无法通过合并
  • Performance (Lighthouse CI): 使用 lighthouse CI 为每次 PR 通过 Lighthouse 打分,如打分过低则无法通过合并

有些细心并知识面广泛的同学可能注意到了,某些 CI 工作也可在 Git Hooks 完成,确实如此。

它们的最大的区别在于一个是客户端检查,一个是服务端检查。而客户端检查是天生不可信任的。

而针对 git hooks 而言,很容易通过 git commit --no-verify 而跳过。

【前端部署十一篇】通过 CICD 实践 Lint、Test、Performance 等前端质量保障工程

📒 【第2609期】Javascript之迪米特法则

📒 React 并发渲染的前世今生

📒 如何优雅实现轮询

  • 初级:使用定时器(setInterval
  • 中级:使用基于事件循环的递归(setTimeout 递归调用)
  • 高级:使用轮询调度器

📒 npm 包的入口点

注意 exports 字段优先级最高,当提供 exports 字段后,mainmodule 字段会被覆盖。

exports 可以更容易地控制子目录的访问路径,不在 exports 字段中的模块,即使直接访问路径,也无法引用!

工程化知识卡片 014: 发包篇之 package.json 中 main、export、module 的区别何在

http://nodejs.cn/api/packages.html#main-entry-point-export

📒 使用 Next.js 和 MDX 构建你自己的博客

https://www.freecodecamp.org/news/how-to-build-your-own-blog-with-next-js-and-mdx/

📒 React Concurrent 的故事

https://www.youtube.com/watch?v=NZoRlVi3MjQ

⭐️ TCP 重传、滑动窗口、流量控制、拥塞控好难?看完图解就不愁了

⭐️ TCP 就没什么缺陷吗?

📒 React Server Components:我们即将和 API 告别?

· 16 min read
加菲猫

📒 从零开始构建 JavaScript Bundler

Jest 作者的最新系列文章,并且配套视频,内容绝对硬核。

https://cpojer.net/posts/building-a-javascript-bundler

📒 JavaScript 框架的四个时代

这篇文章作者以自身多年的开发经历还原了 JavaScript 框架的发展历程,并划分出了四个时代。

  • 远古时代:无框架
  • 框架初期:Backbone.js、Angular 1、Knockout.js、SproutCore、Ember.js、Meteor.js
  • 以组件为中心的时代:React.js、Vue.js、Svelte、Polymer.js
  • 全栈框架:Next.js、Nuxt.js、Remix、SvelteKit、Gastby 和 Astro

https://www.pzuraq.com/blog/four-eras-of-javascript-frameworks

📒 pnpm v7.0.0

pnpm 发布了 v7.0.0,带来了大量的更新。如:不再支持 Node.js 12、pnpm run <script> 脚本名称后的所有命令行参数都会传递给 argv 等等。

https://github.com/pnpm/pnpm/releases/tag/v7.0.0

⭐️ 2022 年的前端行业,咋样啦

ESR(Edge Side Rendering,边缘渲染)是最近的一大热门趋势,可以直接在 CDN 级别实现按需渲染。Nuxt 3、Remix 以及 Sveltekit 等框架都在朝着这个方向发展,目测会在未来的一到两年会成为一大焦点。

2022 年的前端行业,咋样啦

📒 docker-node - Node.js 官方 Docker 镜像

📒 JS 新的日期 API:Temporal

这项特性提案时间为 2021 年 7 月,不到一年的时间已经进展到 stage-3 阶段,目前组委会已经在在做它的功能实现,有望在下个版本推出。

tip

该项提案的初衷来自这篇文章,因为 JavaScript 最初关于日期的实现是照搬的 Java 方案,但由于各种限制和问题,Java 早在 1997 年就实现 Calendar 做了功能改进,而 JavaScript 时至今日用的还是老旧方案,改进优化实在是迫在眉睫。

https://maggiepint.com/2017/04/09/fixing-javascript-date-getting-started/

官方文档(打开控制台就可以体验 Polyfill):

https://tc39.es/proposal-temporal/docs/

或者在 RunKit 上体验(浏览器端运行 node 模块):

https://npm.runkit.com/proposal-temporal

📒 【工程化】探索webpack5中的Module Federation

📒 我们如何使用 Webpack 将启动时间减少 80%

📒 React官方团队出手,补齐原生Hook短板

📒 你可能并没有理解的 babel 配置的原理

📒 前端抢饭碗系列之Docker进阶部署

📒 前端抢饭碗系列之初识Docker容器化部署

📒 从零开始发布自己的NPM包

⭐️ Umi 4 特性合集,比 Vite 还要快?

📒 HTTP分块传输 如何在 React18 中应用

📒 下集」React性能优化,你需要知道的一切

📒 htmlparser2 8.0:快速且高容错的 HTML 和 XML 解析器

https://github.com/fb55/htmlparser2

📒 Node v18 test 模块

注意 Node v18 test 模块是第一个 Prefix-Only Core Modules,也就是说加载该模块必须带上 node: 前缀:

import test from 'node:test';  // Uses the node: prefix. Loads from core.
import assert from 'assert'; // Does not use the node: prefix. Loads from core.
tip

假如没有带上 node: 前缀,则会尝试从用户空间加载 test 模块。但是对于 Node 其他内置模块来说,加不加 node: 前缀都是一样的。

https://fusebit.io/blog/node-18-prefix-only-modules/

📒 Node v16.15.0 (LTS) 发布

现在 Node v16 可以使用实验性支持的 Fetch API 了

https://nodejs.org/en/blog/release/v16.15.0/

📒 升级到 React 18 所对应的 TypeScript 类型定义的改动

https://blog.logrocket.com/upgrading-react-18-typescript/

📒 如何理解 React Hooks 的闭包陷阱

函数组件更新,实际上就是函数重新执行,生成一个新的执行上下文,所有变量、函数重新创建,hooks 重新执行。

一般来说,当函数执行完毕,内部的变量就会销毁、被垃圾回收机制回收。当然也有例外情况,在下面的代码中,函数 baz 依赖了 bar 内部的变量 a,并且 baz 作为返回值传递给了 foo,因此 a 并不会被垃圾回收机制回收,而是会作为闭包缓存下来。只要 foo 的引用不解除,a 就会一直缓存:

function bar() {
const a = 1;
return function baz() {
console.log(a);
}
}

const foo = bar();

再来看这个场景:useEffect 的回调函数依赖了 state 变量,而我们知道这个回调函数在下次 rerender 之前都是缓存在 fiber 节点上的,这样一来就创建了闭包,即使函数组件已经执行完毕,但是 state 变量仍会被缓存下来。

当组件更新的时候,会生成一个新的执行上下文,state 变量也会重新生成,但是 useEffect 回调函数仍然引用了旧的闭包。但是为什么 useEffect 依赖项变化、回调函数执行的时候,总是可以获取到新的值呢?这是因为每次函数组件重新渲染,useEffect 都会重新执行,回调函数也会重新生成(但不一定都会执行),在 updateEffectImpl 内部用重新生成的函数替换了 fiber 节点缓存的函数,这样一来,回调函数执行的时候,始终都能获取到最新的值了。

你可能会觉得这样没什么问题,但是如果在 useEffect 中使用定时器,大概率都会遇到闭包陷阱。

另一个会遇到闭包陷阱的是 useCallback。很多同学觉得 useCallback 依赖项似乎没什么用,习惯性传递空数组,这就会导致函数一直被缓存,假如内部依赖了 state 变量,则始终会缓存旧的闭包。正确做法应该是把 state 变量添加到依赖项数组中,在 state 改变的时候重新生成函数,这样就可以获取到最新的值。

tip

函数组件 rerender 过程中,缓存状态的 fiber 节点(相当于组件实例)并不会销毁,但函数组件是重新执行了,会生成一个新的上下文环境,如果 useEffect 回调依赖了 state 变量,则会一直缓存旧的闭包。所以要避免闭包陷阱,只需要 保证每次渲染的时候,函数都重新生成 就行。

📒 TypeScript 小技巧:常量断言

在讲常量断言之前,先提一下,TS 会区别对待可修改和不可修改的值的类型推断:

// 推断成单值类型 'dbydm'
const immutable = 'dbydm';

// 推断成通用的 string 类型
let mutable = 'dn';

// 由于对象的属性都具有可修改性,TS 都会对它们「从宽」类型推断
// 例如下面的 prop 的类型被推断为 string
const obj = { prop: 'foo' }

再来看下面的代码,例如我们实现了一个用 ref 维护状态的 hook:

import * as React from "react";

const useRenderlessState = <T>(initialState: T) => {
const stateRef = React.useRef(initialState);

const setState = (nextState: T) => stateRef.current = nextState;

return [stateRef.current, setState];
}

此时我们会发现上面 hook 的返回值的类型被推导成了如下的数组类型:

(T | ((nextState: T) => T))[]

这就导致我们在使用的时候无法对它进行准确的解构:

const [value, setValue] = useRenderlessState(0);

一般来说我们可以 显示声明返回类型 或者 对返回值做类型断言,告诉 TS 返回值类型是元组而不是数组:

// 显示声明返回类型
const useRenderlessState = <T>(initialState: T): [T, (nextValue: T) => T] => {/*...*/}

// 对返回值对类型断言
const useRenderlessState = <T>(initialState: T) => {
// ...
return [state, setState] as [typeof value, typeof setValue];
}

上面的两种写法都各有冗余成分,算不上优雅。

其实从语义层面来分析,TS 之所以没能将返回值推断为元组类型是因为它认为该返回值仍有可能被 push 值,被修改。所以我们真正需要做的是告诉 TS,这个返回值是一个 final,其本身和属性都是不可篡改的,而这正是常量断言所做的事。

常量断言可以把一个值标记为一个不可篡改的常量,从而让 TS 以最严格的策略来进行类型推断:

const useRenderlessState = <T>(initialState: T) => {
// ...
return [state, setState] as const
}

这下 useRenderlessState 的返回类型就被推断成了如下的 readonly 值:

readonly [T, (nextState: T) => T]
tip

as const 与 ES6 const 常量声明的区别:

  • const 常量声明是 ES6 的语法,对 TS 而言,它只能反映该常量本身是不可被重新赋值的,它的子属性仍然可以被修改,故 TS 只会对它们做松散的类型推断
  • as const 是 TS 的语法,它告诉 TS 它所断言的值以及该值的所有层级的子属性都是不可篡改的,故对每一级子属性都会做最严格的类型推断(所有的字面量都会被推断为单值类型)

常量断言可以让我们不需要 enum 关键字就能定义枚举对象:

const EnvEnum = {
DEV: "development",
PROD: "production",
TEST: "test",
} as const;

TypeScript 夜点心:常量断言

📒 了解 Symbol.toStringTag 的用法吗

Symbol.toStringTag 是一个内置 symbol,它通常作为对象的属性键使用,对应的值是字符串类型,用来表示该对象的自定义类型标签。通常只有内置的 Object.prototype.toString() 方法会去读取这个标签并把它包含在自己的返回值里。

const foo = {};
const bar = {
[Symbol.toStringTag]: "测试内容"
}

foo.toString(); // '[object Object]'
bar.toString(); // '[object 测试内容]'

Symbol.toStringTag - MDN 文档

📒 函数组合中的 composeflowpipe

compose 实现如下,注意调用顺序是反过来的:

const compose = (...fns) => x0 => fns.reduceRight(
(x, f) => f(x),
x0
);

// 接受参数后,返回一个待执行函数
// 需要再接受一个初始值才开始执行
const processComment = compose(
linkify,
imagify,
emphasize,
headalize
);

flow 实现如下,注意这里调用顺序是从左到右:

const flow = (...fns) => x0 => fns.reduce(
(x, f) => f(x),
x0
);

// 注意这里仍然是返回一个待执行函数
const processComment = flow(
headalize,
emphasize,
imagify,
linkify,
codify
);

pipe 实现如下,调用顺序也是从左到右:

// 注意 pipe 直接执行所有的函数,返回一个值
// 而 flow 返回一个待执行函数,需要再接受一个初始值才开始执行
const pipe = (x0, ...fns) => fns.reduce(
(x, f) => f(x),
x0
);

const map = f => arr => arr.map(f);
const filter = p => arr => arr.filter(p);
const take = n => arr => arr.slice(0, n);
const join = s => arr => arr.join(s);

const comments = pipe(commentStrs,
filter(noNazi),
take(10),
map(emphasize),
map(itemize),
join('\n'),
);

什么是 JavaScript 的函数组合

📒 基于依赖倒置原则实现插件机制

依赖倒置原则(DIP)

核心思想:依赖一个抽象的服务接口,而不是去依赖一个具体的服务执行者,从依赖具体实现转向到依赖抽象接口,倒置过来

例如在 Webpack 中包含一套插件机制:

module.exports = {
// ...
plugins: [
new WebpackBar(),
new webpack.HotModuleReplacementPlugin(),
new MiniCssExtractPlugin({
filename: 'css/[name].[contenthash:8].css',
chunkFilename: '[id].css'
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, '../public/index.html'),
title: "React App",
filename: "index.html",
})
]
}

Webpack 插件需要实现一个统一的接口,即:

interface IPlugin {
apply(compiler: ICompiler): void;
}

class MyPlugin implements IPlugin {
constructor() {
// 构造器可以在初始化的时候接受配置参数
}

@Override
apply(compiler) {
// ...
}
}

这样 Webpack 只需要遍历 plugins 数组,顺次调用每个插件上的 apply 方法,传入 compiler 对象即可:

plugins.forEach(plugin => plugin.apply(compiler));

顺便提一下,有同学会问,为啥插件要写成 class 的形式,直接用一个对象可以吗,例如:

const MyPlugin = {
apply(compiler) {
// ...
}
}

直接用一个对象也是可以的,但是用 class 显然更灵活,可以在初始化的时候接受配置参数

📒 浏览器 JavaScript 和 Node.js 的区别

  • API 区别:浏览器 JavaScript 是面向浏览器编程,调用浏览器的 API,例如 documentwindow。而 Node.js 是面向操作系统编程,没有浏览器 API,相反可以调用 Node 提供的标准库,与操作系统进行交互
  • 运行环境区别:浏览器 JavaScript 的特殊性(JS 代码需要经过网络请求,在客户端下载并执行),因此无法选择运行环境,需要考虑语法、API 兼容性问题,需要使用 Babel 处理。而 Node.js 通常在本地开发环境、CI 环境、服务端运行,可以控制运行环境,无需考虑兼容性问题
  • 模块规范区别:浏览器原本没有模块机制,但可以自行实现模块命名空间机制(例如 browserifywebpack),从 Chrome 61 开始支持 <script type="module">,即浏览器原生支持 import 命令加载模块(需要注意这种方式也是要经过网络请求)。而 Node.js 自带了一套 CommonJS 模块机制,在 Node 14 之后支持 ES Module 规范(注意 CommonJS 仍然是默认启用的模块规范)

· 18 min read
加菲猫

📒 实现一个 Code Pen:(三)10 行代码实现代码格式化

📒 为什么用链表实现队列

很多时候用数组也能实现队列,我们知道数组尾部操作(例如 pushpop)时间复杂度都是 O(1),但如果在数组头部增删元素(例如 shiftunshift),需要移动其他元素的下标,因此时间复杂度为 O(n)

而链表增删元素实际上都是修改指针指向,不需要移动下标,因此时间复杂度都是 O(1)。链表只有查找元素需要遍历,时间复杂度为 O(n),但是队列并不需要查找,而且链表的 size 属性可以在增删操作的时候进行维护,所以用链表实现队列非常合适。

思考题:如何在常数时间内删除数组中的元素。我们知道 splice 删除元素也需要移动其他元素下标,时间复杂度为 O(n),但是在数组尾部操作时间复杂度都是 O(1),因此可以先把要删除的元素交换到数组尾部,然后直接删除尾部元素即可。

📒 写给前端的 K8S 上手指南

📒 Web页面全链路性能优化指南

📒 系统困境与软件复杂度,为什么我们的系统会如此复杂

📒 【第2602期】设置 NPM Registry 的 4 种姿势

📒 前端算法系统练习: 栈和队列篇

📒 怎么解决MySQL死锁问题的

📒 【第2598期】ServiceWorker 缓存与 HTTP 缓存

📒 Monorepo 的过去、现在、和未来

📒 【第2597期】如何用JavaScript实现一门编程语言 - AST

📒 TS 类型体操:索引类型的映射再映射

📒 ESBuild & SWC浅谈: 新一代构建工具

📒 InnoDB原理篇:如何用好索引

我们都知道 InnoDB 索引结构是 B+ 树组织的,但是根据 数据存储形式不同 可以分为两类,分别是 聚簇索引二级索引

其实聚簇索引的本质就是主键索引。因为每张表只能拥有一个主键字段,所以每张表只有一个聚簇索引。另外聚簇索引还有一个特点,表的数据和主键是一起存储的,它的叶子节点存放的是整张表的行数据(树的最后一层),叶子节点又称为数据页。

很简单记住一句话:找到了索引就找到了行数据,那么这个索引就是聚簇索引

知道了聚簇索引,再来看看二级索引是什么,简单概括,除主键索引以外的索引,都是二级索引,像我们平时建立的联合索引、前缀索引、唯一索引等。

二级索引的叶子节点存储的是索引值 + 主键 id。所以二级索引与聚簇索引的区别在于 叶子节点是否存放整行记录

也就意味着,仅仅靠二级索引无法拿到完整行数据,只能拿到 id 信息

假设,我们有一个主键列为 id 的表,表中有字段 kk 上有索引。

我们执行一条主键查询语句 select * from T where id = 100,只需要搜索 id 聚簇索引树就能查询整行数据。

接着再执行一条 select * from T where k = 1,此时要搜索 k 的二级索引树,具体过程如下:

  • k 索引树上找 k = 1 的记录,取得 id = 100
  • 再到聚簇索引树查 id = 100 对应的行数据
  • 回到 k 索引树取下一个值 k = 2,不满足条件,循环结束

上述过程中,回到聚簇索引树搜索的过程,我们称为 回表

也就是说,基于二级索引的查询需要多扫描一棵聚簇索引树,因此在开发中尽量使用主键查询

可是有时候我们确实需要使用二级索引查询,有没有办法避免回表呢?

办法是有的,但需要结合业务场景来使用,比如本次查询只返回 id 值,查询语句可以这样写 select id from T where k = 1,过程如下

  • k 索引树上找 k = 1 的记录,取得 id = 100
  • 返回 id
  • 回到 k 索引树取下一个值 k = 2,不满足条件,循环结束

在这个查询中,索引 k 已经覆盖了我们的查询需求,不需要回表,这个操作称为覆盖索引

由于覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段

假设现在有一个高频的业务场景,根据 k 查询,返回 name,我们可以把 k 索引变更成 kname 的联合索引。

InnoDB原理篇:如何用好索引

InnoDB原理篇:聊聊数据页变成索引这件事

📒 一分钟看懂TCP粘包拆包

TCP 是一个面向「流」的协议,所谓流就是没有界限的一长串二进制数据。在实际的传输过程中,TCP 会根据网络情况将数据包进行拆分或者拼装,如果业务没有定义一个明确的界限规则,在应用层的业务上就会出现粘包拆包的现象。

针对 TCP 粘包拆包的现象,常见的解决思路如下:

  1. 发送端给每个数据包 添加包首部
  2. 发送端将每个数据包 封装为固定长度
  3. 可以在数据包之间 设置边界

为了解决粘包拆包,Netty 框架也提供了很多开箱即用的编解码器,极大简化网络编程解决此类问题的难度。

一分钟看懂TCP粘包拆包

📒 什么是有区分度的好的面试问题,来看看字节跳动这道实现异步 sum 的问题

📒 【前端部署第三篇】通过 docker 学习 nginx 配置,及基于 nginx 部署最简前端项目

📒 使用 CRA 搭建 React + TS 项目

都 2022 年了,手动搭建 React 开发环境很难吗

会写 TypeScript 但你真的会 TS 编译配置吗

用 Redux 做状态管理,真的很简单🦆

「React进阶」react-router v6 通关指南

📒 Usage With TypeScript - Redux Toolkit

https://redux-toolkit.js.org/usage/usage-with-typescript

📒 全局状态和状态管理的区别

全局状态可以很简单,例如只要一个 JS 对象 {} 就可以实现,但是如果尝试修改全局状态的值,无法触发组件更新。

状态管理,除了具有全局状态的功能,还提供了一套发布订阅机制,即状态改变的时候通知对应组件更新。

Redux 本身其实就是全局状态,为了实现状态改变通知组件更新,还需要一个 UI-binding,即 React-redux。

📒 浅谈V8垃圾回收机制

📒 打造 Go 语言最快的排序算法

📒 实现一个 Codepen:(二)在 Next.js 中使用 Monaco Editor

📒 【架构师(第十八篇)】脚手架之项目模板的安装

📒 【前端部署第二篇】基于 docker/compose 部署一个最简单的前端项目

📒 7 段小代码,玩转Java程序常见的崩溃场景

如何排查 CPU 飙升问题,获取问题代码通常可以使用下面的方法:

  1. 使用 top 命令,查找到使用 CPU 最多的某个进程,记录它的 pid。使用 Shift + P 快捷键可以按 CPU 的使用率进行排序
  2. 再次使用 top 命令,加 -H 参数,查看某个进程中使用 CPU 最多的某个线程,记录线程的 ID
  3. 使用 printf 函数,将十进制的 tid 转化成十六进制
  4. 使用 jstack 命令,查看 Java 进程的线程栈
  5. 使用 less 命令查看生成的文件,并查找刚才转化的十六进制 tid,找到发生问题的线程上下文

7 段小代码,玩转Java程序常见的崩溃场景

📒 看完这篇你一定能掌握Linux

📒 ObjectMapper,别再像个二货一样一直new了

📒 [科普] Service Worker 入门指南

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 前端历史项目的 Vite 迁移实践总结

📒 手写 css-modules 来深入理解它的原理

📒 在 Webpack 5 中开启懒编译(Lazy Compilation)

Webpack 5 的实验特性,可以针对多入口(Initial Chunk)和动态加载(Async Chunk)进行懒编译。开启懒编译之后,可以实现按需编译,提升启动速度,若再配合 Webpack 5 持久化缓存,则可以直接秒杀 Vite。

module.exports = {
// …
experiments: {
lazyCompilation: {
imports: true,
entries: true,
},
},
};

由于实验特性具有相对宽松的语义版本,可能会有重大的变更,所以你需要锁定 Webpack 的小版本号,例如 "webpack": "~5.4.3",或者锁定版本号

在 Webpack 5 中开启懒编译(Lazy Compilation)

📒 浅谈文档的实时协同编辑

📒 腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检

首先为什么要有同源策略?浏览器需要记住用户的登录状态(即登录凭证),这样用户下次访问页面就无需重复登录。这样的话,就需要有一些安全策略,否则很容易出现 CSRF 攻击等问题。如果是其他的 http client 则没有同源策略。

CORS策略的心智模型是:所有跨域请求都是不安全的,浏览器要带上来源给服务器检验

同源策略会限制哪些行为:

  • 跨域情况下获取 DOM 元素(例如跨域的 iframe)、localStorage、Cookie 等
  • 跨域情况下发送 ajax 请求,浏览器会拒绝解析响应报文

注意,浏览器默认的表单提交不受同源策略限制

CORS 即跨域资源共享,这里注意 CORS 的目的不是拦截请求,反倒是为了让其能正常请求。CORS 的诞生背景就是同源策略,这是一个相当严苛的规定,它禁止了跨域的AJAX请求。但实际的开发中又有这样的需求,于是开一个口子——只要配置了CORS的对应规则,跨域请求就能正常进行。

如何配置 CORS?前端在发送请求的时候,浏览器会在请求头添加 Origin 字段,这样后端就能知道请求的来源,然后后端在响应头添加 Access-Control-Allow-Origin,这个值就是前端发送的来源地址(或者直接加 * 表示允许所有地址)。

跨域请求的流程,CORS把请求分成简单请求和复杂请求,划分的依据是“是否会产生副作用”。同时满足下面这两个条件的是 简单请求,否则就是 非简单请求

  • 请求方法是 HEAD/GET/POST
  • 请求体的 Conent-Type 只能是 form-urlencodedform-datatext/plain

对于简单请求,流程如下:

  1. 浏览器发起请求,并且自动加上请求的来源 origin 给服务器检查;
  2. 服务器返回数据,并返回检查结果,配置CORS响应头;
  3. 浏览器检查CORS响应头,如果包含了当前的源则放行,反之拦截;

这里需要注意,浏览器是拦截响应,而不是拦截请求,跨域请求是发出去的,并且服务端做了响应,只是浏览器拦截了下来

对于复杂请求,流程如下:

  1. 浏览器发起预检请求,带上请求的来源 origin,不包含请求体;
  2. 服务器返回检查结果,配置CORS头;
  3. 浏览器发起真正请求;
  4. 浏览器返回数据;

浏览器会检查第2步中拿到的CORS头,如果没有包含当前的源,后续的第3、4步都不会进行,也就是不会发起真正请求

为什么只对复杂请求做预检?上文提到,划分简单请求和复杂请求的依据是“是否产生副作用”。这里的副作用指对 数据库做出修改:使用GET请求获取新闻列表,数据库中的记录不会做出改变,而使用PUT请求去修改一条记录,数据库中的记录就发生了改变。

假设网站被CSRF攻击了——黑客网站向银行的服务器发起跨域请求,并且这个银行的安全意识很弱,只要有登录凭证cookie就可以成功响应,考虑下面两种情况:

  • 黑客网站发起一个GET请求,目的是查看受害用户本月的账单。银行的服务器会返回正确的数据,不过影响并不大,而且由于浏览器的拦截,最后黑客也没有拿到这份数据;
  • 黑客网站发起一个PUT请求,目的是把受害用户的账户余额清零。浏览器会首先做一次预检,发现收到的响应并没有带上CORS响应头,于是真正的PUT请求不会发出;

幸好有预检机制,否则PUT请求一旦发出,黑客的攻击就成功了。

这种情况下,后端也需要遵循 RESTful 规范,否则要么面临攻击风险,要么会多发一次预检请求

腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检

腾讯三面:Cookie的SameSite了解吧,那SameParty呢

📒 Axios 三个优点

  • Promisify
  • 责任链(拦截器机制)
  • 适配器(同时支持浏览器和 node 环境)

📒 深入理解 Promise 之手把手教你写一版

📒 2022 年 JavaScript 开发工具的生态

📒 自动化生成骨架屏的技术方案设计与落地

· 14 min read
加菲猫

📒 Ubuntu 22.04 LTS 安装

https://phoenixnap.com/kb/ubuntu-22-04-lts

https://releases.ubuntu.com/jammy/

📒 计算机程序的构造和解释 — JavaScript 版

这本由麻省理工学院出版的著作终于有了 JavaScript 语言版本,可以帮助你建立对计算机程序的心智模型。

https://github.com/source-academy/sicp

📒 为什么要使用 Redux Toolkit

Redux 官方发布的这篇博客讲解了 Redux Toolkit 的 Why 和 How,并强烈推荐使用。

一句话总结:Redux Toolkit 是使用 Redux 的最佳实践。

https://redux.js.org/introduction/why-rtk-is-redux-today

⭐️ Node.js 18 新特性解读

📒 那些你应该说再见的 npm 祖传老库

📒 如何实现数组转对象

传入一个 paramKeys 数组,获取 query 参数的值,然后以对象形式返回,使用 reduce 方法:

function getSearchParams(paramKeys: string[]): Record<string, string> {
const searchParams = new URLSearchParams(window.location.search);
return paramKeys.reduce<Record<string, string>>((accu, cur) => {
accu[cur] = searchParams.get(cur) || '';
return accu;
}, {});
}

// 使用
const searchParams = getSearchParams(['name', 'age']);

以上流程还可以封装成自定义 hook:

import * as React from 'react';

function useSearchParams(paramKeys: string[]): Record<string, string> {
const query = window.location.search;
return React.useMemo(() => {
const searchParams = new URLSearchParams(query);
return paramKeys.reduce<Record<string, string>>((accu, cur) => {
accu[cur] = searchParams.get(cur) || '';
return accu;
}, {});
}, [paramKeys, query]);
}

看了 antfu 大佬的代码,还可以使用 Object.fromEntries() 方法:

function useSearchParams(paramKeys: string[]): Record<string, string> {
const searchParams = new URLSearchParams(window.location.search);
return Object.fromEntries(
paramKeys.map((key) => [key, searchParams.get(key)])
);
}

注意:Object.fromEntries() 是 ES2019 中的语法,存在兼容性问题(Chrome >= 73),不过只要正确配置 polyfill 就可以放心使用

📒 使用 defineConfig 约束配置对象

在项目中经常需要用到配置对象,例如 Webpack、rollup 的配置,我们可以使用 TS 来约束配置对象的 API schema,告知用户应该传哪些字段以及对应的类型,这样有两个好处:

  • 对用户更加友好,不需要看文档就能直接上手
  • 在开发阶段就能提前检查出配置项错误,不用到运行阶段再去校验了

一般来说我们需要导出一个接口类型:

export type IConfig = {
name: string;
age: number;
sex?: boolean;
};

用户在使用的时候需要导入类型,然后自己添加注解,这样编写配置对象就能得到类型提示了:

import type { IConfig } from "xxx";

const config: IConfig[] = [
{
name: "dbydm",
age: 23
}
]

但是这样对用户来说还是太麻烦了,我们可以定义一个 defineConfig 函数,这个函数做的事情很简单,就是把接收到的参数原封不动地返回,但在这个过程中,就可以实现参数类型的校验:

type IConfig = {
name: string;
age: number;
sex?: boolean;
};

export function defineConfig(config: IConfig[]) {
return config;
}

用户只需导入 defineConfig 编写配置就可以实现参数类型的校验:

import { defineConfig } from "xxx";

export default defineConfig([
{
name: "dbydm",
age: 23
}
])

📒 Elasticsearch 基础入门详文

📒 如何把前端项目写成一座屎山

📒 浅谈JS内存机制

📒 深入理解 scheduler 原理

📒 前端框架如何实现预渲染

首先预渲染根据渲染时机分为以下两种:

  • 静态站点生成(SSG),构建的时候获取数据进行渲染,数据不一定是最新的
  • 服务端渲染(SSR),用户访问的时候服务端获取数据进行渲染,数据实时获取

两种渲染方案都可以实现 首屏性能优化SEO 优化,不同的是 SSR 需要在服务端运行 JS,并且每次用户请求的时候都会进行渲染;SSG 已经将每个页面渲染成静态 html,因此可以将资源托管到 CDN 上

获取数据又可以分为以下几种方式:

  • 本地文件系统读取
  • 调接口获取
  • 查询数据库获取

实际上,React 本身已经提供了服务端渲染和静态生成相关的 API。在前端项目中,我们一般会使用下面的 API 挂载 React 组件:

ReactDOM.render(element, container[, callback])

为了实现 SSR 渲染,我们可以使用下面的 API 将 React 组件直接渲染为 HTML 字符串:

ReactDOMServer.renderToString(element)

使用 renderToString 方法渲染出的 HTML 字符串会带有特定标记,我们可以使用下面的 API 在客户端进行激活,对标记的节点挂载相应的事件监听器:

ReactDOM.hydrate(element, container[, callback])

在 SSG 渲染中,我们不需要在客户端进行激活,因此不用在 HTML 字符串中添加标记,只需渲染出纯的 HTML 字符串:

ReactDOMServer.renderToStaticMarkup(element)

📒 2万字系统总结,带你实现 Linux 命令自由

📒 还在手撸 Nginx 配置?试试这款可视化配置工具吧,真心强大

📒 esno,基于 Esbuild 的神器

📒 「React进阶」换个姿势看 hooks ! 灵感来源组合和HOC 模式下逻辑视图分离新创意

useMemo 类似 Vue 中的计算属性,当依赖项发生变化,会重新计算。但实际上 useMemo 比计算属性更强大,除了缓存值之外,还能缓存组件:

function Index({ value }){
const [number, setNumber] = React.useState(0);
const element = React.useMemo(() => <Test />, [value]);

return (
<div>
{element}
<button onClick={() => setNumber(number + 1)}>点击 {number}</button>
</div>
)
}

有时候在父组件定义的事件处理函数,需要作为 prop 传入子组件。如果父组件重新渲染,会导致函数重新生成,相当于 prop 发生变化,即使子组件内部使用 React.memo() 包裹也会导致重新渲染。常规做法是使用 React.useCallback() 包裹事件处理函数,但实际上用 React.useRef() 包裹也是可以的,都是把事件处理函数缓存到 Fiber 节点上。

function MyApp() {
const onClickRef = React.useRef(() => {
console.log("666");
});

// const onClick = React.useCallback(() => {}, []);

return (
<div>
<h1>Welcome to my app</h1>
<MyButton onClick={onClickRef.current} />
</div>
);
}

「React进阶」换个姿势看 hooks ! 灵感来源组合和HOC 模式下逻辑视图分离新创意

📒 React 18 升级踩坑汇总

1. React.StrictMode 导致所有组件重复挂载两次

使用 CRA 5.0.1 搭建 React 项目,默认的项目模板中,根组件使用了 React.StrictMode 包裹,结果出现了所有组件都重复挂载的情况,导致组件中接口调了两次。看了下文档,确实是 React 18 中引入的 Breaking Change,启用严格模式,会导致所有组件重复挂载两次(即使用了 React.memo 也会重复挂载):

Stricter Strict Mode: In the future, React will provide a feature that lets components preserve state between unmounts. To prepare for it, React 18 introduces a new development-only check to Strict Mode. React will automatically unmount and remount every component, whenever a component mounts for the first time, restoring the previous state on the second mount. If this breaks your app, consider removing Strict Mode until you can fix the components to be resilient to remounting with existing state

tip

使用 CRA 创建的 React 18 项目,建议移除 React.StrictMode

2. React 18 中使用了 antd 的 message 组件控制台打印警告信息

React 18 使用了新的 ReactDOM.createRoot() API 挂载根节点,Concurrent Mode 需要通过此 API 开启,但是 antd 中的 message 等组件内部仍使用 ReactDOM.render() 挂载根节点,此时在控制台会打印警告,注意这并不是报错,仅仅只是 fallback 到 legacy mode 而已。

tip

升级前最好仔细看一遍官方的说明,特别是 Breaking Change:

https://github.com/facebook/react/releases/tag/v18.0.0

📒 为什么需要 peerDependencies

例如开发一个 React 组件库的时候,有三个诉求:

  • 该组件库开发的时候需要安装 React;
  • 用户引入该组件库的时候不能重复安装 React;
  • 组件库的 React 版本与目标环境不一致的时候需要被包管理器发现并打印警告;

如果安装到 dependencies 下,显然会导致重复安装;如果安装到 devDependencies 下虽然不会导致重复安装,但包管理器不会检查版本,当版本不一致的时候不会打印警告。所以 peerDependencies 是最优选择。

在老版本 React 项目中引入某些依赖库(例如 antdreact-transition-group),一般不能直接安装最新的版本(大概率会报错),此时应该根据依赖库的 package.json 中指定的 peerDependencies 字段选择合适的依赖库版本

⭐️ 什么是 JavaScript 的函数组合

本篇文章以一个简略的 Markdown 的例子为主线,讲述了什么是函数组合,以及如何使用函数组合的思想编写代码,是一篇非常不错的编程思想类文章。

https://jrsinclair.com/articles/2022/javascript-function-composition-whats-the-big-deal/

📒 一些关于react的keep-alive功能相关知识在这里(下)

📒 一些关于react的keep-alive功能相关知识在这里(上)

📒 理清 HTTP 下的 TCP 流程,让你的 HTTP 水平更上一层

📒 React 18 系列

React 18 全览

React 18 对 Hooks 的影响

React 的心智模型

你不知道的 React v18 的任务调度机制

📒 React 几个小技巧

1. React 内置工具类型

// 使用 React.ComponentType 同时表示类组件和函数组件
type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;

// 使用 React.Key 来表示列表渲染 key 的类型
type Key = string | number;

参考:

精读《@types react 值得注意的 TS 技巧》

从 @types/react 的类型定义中,我学到了什么

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react/v17/index.d.ts

2. 自定义组件如何绑定 className

className 作为 prop 传入,内部使用 classnames 这个库进行拼接:

import cx from "classnames";
import s from "./style.module.less";

type IProps = {
className: string;
}

const App: React.FC<IProps> = ({ className }) => {
return (
<div className={cx(s.wrapper, className)}>
...
</div>
)
}

更进一步,把以上流程封装成高阶组件(HOC):

function withClassName<T>(Component: React.ComponentType<T>): React.FC<T & { className: string }> {
return ({ className, ...restProps }) => {
return (
<div className={className}>
<Component {...restProps} />
</div>
)
}
}

3. Input 如何变为受控组件

Antd 中的 Input 默认是非受控组件,可以绑定 value,然后监听 onChange 修改 value 实现受控(v-model 的原理):

const App: React.FC<{}> = () => {
const [num, setNum] = React.useState(1);

return (
<InputNumber value={num} onChange={setNum} />
)
}

📒 我帮一朋友重构了点代码,他直呼牛批,但基操勿六

📒 React + TypeScript:如何处理常见事件

📒 单例模式 4 种经典实现方法

📒 如何实现 useClickAway

如何监听元素外的点击,类似 Vue 的 ClickOutSide 指令

官方文档:https://ahooks.js.org/hooks/use-click-away

源码:https://github.com/alibaba/hooks/blob/master/packages/hooks/src/useClickAway/index.ts

📒 快速理解 TypeScript 的逆变、协变

📒 都 2022 年了,手动搭建 React 开发环境很难吗

📒 这篇手写 Promise 你一定要康康

📒 超全面的前端新一代构建工具对比: esbuild、Snowpack、Vite、wmr

· 5 min read
加菲猫

📒 JS 相关技巧

// 1. 数组转对象
const dict: Record<number, boolean> = Object.fromEntries(
array.map(i => [i, true])
)

// 2. 使用 Array.from 初始化数组
const digits = Array.from({ length: 10 }, (_, i) => i);

// 3. 字符串转数组,然后用数组方法遍历
// 常规方法是用 split()
String(num).split("").reduce(...)
// 由于字符串实现了 iterator 接口,因此可以使用扩展运算符展开到数组中
[...String(num)].reduce(...)

📒 用Rust锈化Vue Compiler

📒 TS 类型体操性能分析

$ tsc index.ts –-diagnostics

📒 前端动画实现方案

  • CSS 方案:transitionanimation
  • JS 方案:setTimeoutrequestAnimationFrame

一个实验性 API Element.animate(),可以在渲染进程的时候就执行,性能更好。

https://developer.mozilla.org/zh-CN/docs/Web/API/Element/animate

📒 我是如何带领团队从零到一建立前端规范的

📒 血泪教训之请不要再轻视Git —— 我在工作中是如何使用 Git 的

📒 https://nextjs.org/learn/basics/create-nextjs-app

📒 https://nextjs.org/docs

📒 手把手教你用神器nextjs一键导出你的github博客文章生成静态html

📒 Golang 三数之和

package algorithm

import (
"sort"
)

func ThreeSum(nums []int) [][]int {
ans := make([][]int, 0)
// 数组元素个数小于 3,直接返回
if len(nums) < 3 {
return ans
}
// 排序
sort.Ints(nums)
// 遍历到倒数第二个,因为是三个数总和
for i := 0; i < len(nums) - 2; i++ {
// 规定 nums[i] < nums[left] < nums[right]
// 如果 nums[i] > 0 则不存在另外两个值使得相加等于 0
// 大于 0 可以直接跳出循环了
if nums[i] > 0 {
break
}
// 过滤 nums[i] 重复
if i > 0 && nums[i] == nums[i-1] {
continue
}
// 先确定一个值 nums[i]
// 再去找另外两个值 nums[left] 和 nums[right]
// 需要满足 nums[i] < nums[left] < nums[right]
target := -nums[i]
left, right := i + 1, len(nums) - 1

// 使用双指针法确定剩下两个值
for left < right {
sum := nums[left] + nums[right]
if sum < target {
left++
} else if sum > target {
right--
} else if sum == target {
ans = append(ans, []int{nums[i], nums[left], nums[right]})
// 找到目标值,左右指针分别移动一位
left++
right--
// 过滤 nums[left] 重复
for left < right && nums[left] == nums[left-1] {
left++
}
// 过滤 nums[right] 重复
for left < right && nums[right] == nums[right+1] {
right--
}
}
}
}
return ans
}

📒 Golang 手写数组方法

package main

import (
"fmt"
)

func ForEach(nums []int, fn func(int, int)) {
for index, item := range nums {
fn(item, index)
}
}

func Map(nums []int, fn func(int, int) int) []int {
res := make([]int, 0)
for index, item := range nums {
res = append(res, fn(item, index))
}
return res;
}

func Filter(nums []int, fn func(int, int) bool) []int {
res := make([]int, 0)
for index, item := range nums {
if fn(item, index) {
res = append(res, item)
}
}
return res
}

func Reduce(nums []int, fn func(int, int, int) int, initValue int) int {
res := initValue
for index, item := range nums {
res = fn(res, item, index)
}
return res
}

func main() {
s := []int{1, 2, 3, 4}
ForEach(s, func(item, index int) {
fmt.Println("===forEach", item, index)
})
mapped := Map(s, func(item, index int) int {
return item * 2
})
fmt.Println(mapped)
filtered := Filter(s, func(item, index int) bool {
return item % 2 == 0
})
fmt.Println(filtered)
reduced := Reduce(s, func(accu, cur, index int) int {
return accu + cur
}, 0)
fmt.Println(reduced)
}

📒 选择第三方 NPM 包时的 5 条最佳实践

📒 Vue3.2 vDOM diff流程分析之一:diff算法

📒 从零到一,我们来一起造个 JS 的编译器

⭐️ 2022 年的 React 生态

📒 linux后台开发具备能力集锦

📒 Linux下C++后台服务器开发

📒 Go 语言与并发编程

📒 打造轻量级 WebIDE,看这一篇文章就够啦

📒 developer-roadmap

developer-roadmap 是一个开发人员路线图,包含了前端路线图、后端路线图、DevOps 路线图、React 路线图、Angular 路线图、Android 路线图、Python 路线图、Go 路线图、Java 路线图、DBA 路线图。

https://github.com/kamranahmedse/developer-roadmap

📒 pkg: 把 Node.js 项目打包为可执行文件

· 7 min read
加菲猫

📒 编译 ts 代码用 tsc 还是 babel

📒 第三方库是否应该提交 lockfile

在业务项目中,每次依赖安装的版本号都从 lock 文件中进行获取,锁定依赖和依赖的依赖,避免了不可测的依赖风险。但是仍然存在间接依赖不可控的问题,例如 React 依赖 object-assign,在 React 中 lockfile 锁定的版本为 object-assign@4.1.0,但是前端项目实际安装的版本为 object-assign@4.99.99

  • 第三方库的 devDependencies 必须锁定,这样 Contributor 可根据 lockfile 很容易将项目跑起来
  • 第三方库的 dependencies 虽然有可能存在不可控问题,但是可通过锁死依赖或者勤加更新的方式来解决

如果没有 package-lock.json,那将如何

📒 工程化知识卡片 023:node_modules 版本重复的困境

npmv3 之后 node_modules 为平铺结构,但是仍然存在依赖重复安装的问题。

工程化知识卡片 023:node_modules 版本重复的困境

📒 Vue 开发小技巧

分享 15 个 Vue3 全家桶开发的避坑经验

vue3中可以帮助你早点下班的9个开发技巧

📒 【混淆系列】三问:npx、npm、cnpm、pnpm区别你搞清楚了吗?

📒 Webpack组件库打包超详细指南

📒 Node.js 技术架构

Node 是怎么实现的?简言之:用 V8 运行 JS、用 bindings 实现 JS 与 C/C++ 沟通、用 C/C++ 库高效处理 IO、用 Node.js 标准库简化 JS 代码、用 Event Loop 管理事件处理顺序、用 libuv 实现异步 I/O 操作。

Node.js 技术架构

📒 Web 框架的替代方案

📒 写好 JavaScript 异步代码的几个推荐做法

📒 Node.js 进阶 - 多文件 Stream 合并,串行和并发两种模式实现

重要的事情再说一遍,pipe 方法默认情况下会自动关闭可写流,但是如果可读流期间发生错误,则写入的目标流将不会关闭,所以如果使用 pipe 需要监听错误事件,手动关闭可写流,防止文件句柄泄露。

Node.js 进阶 - 多文件 Stream 合并,串行和并发两种模式实现

📒 服务端渲染SSR及实现原理

📒 手摸手服务端渲染-react

📒 如何在项目中用好 TypeScript

📒 Golang 和 JS 创建对象方式对比

Golang 与 JS 创建对象非常类似,Golang 在创建对象的时候需要定义 schema 进行类型约束:

type Person struct {
Name string
Age int
Sex bool
}

person := Person{
Name: "dbydm",
Age: 12,
Sex: true,
}

Golang 创建对象数组:

list := []*Person{
&Person{
Name: "dbydm",
Age: 12,
Sex: true,
},
&Person{
Name: "dm",
Age: 2333,
Sex: false,
},
}

📒 Node.js 常见的系统信号

  • SIGHUP:不通过 ctrl+c 停止进程,而是直接关闭命令行终端,会触发该信号
  • SIGINT:按下 ctrl+c 停止进程时触发;pm2 重启或者停止子进程时,也会向子进程发送该信号
  • SIGTERM:一般用于通知进程优雅退出,如 k8s 删除 pod 时,就会向 pod 发送 SIGTERM 信号,pod 可以在超时时间内(默认 30s)做一些退出清理动作
  • SIGBREAK:在 window 系统上,按下 ctrl+break 会触发该信号
  • SIGKILL:强制退出进程,进程无法做任何清理动作,执行命令 kill -9 pid,进程会收到该信号。k8s 删除 pod 时,如果超过 30s,pod 还没退出,k8s 会向 pod 发送 SIGKILL 信号,立即退出 pod 进程;pm2 在重启或者停止进程时,如果超过 1.6s,进程还没退出,也会发送 SIGKILL 信号

📒 2022 年,Babel vs TypeScript,谁更适合代码编译

📒 React 常用状态管理库

  • Redux
  • Mobx
  • Recoil
  • Hookstate
  • Rematch
  • Jotai
  • Zustand

📒 从源码理清 useEffect 第二个参数是怎么处理的

📒 腾讯一面:CORS为什么能保障安全?为什么只对复杂请求做预检?

📒 如何在 Node 环境使用 ESM 模块规范

首先明确一点,Node 环境并非不支持 ESM 规范,只是没有启用而已,默认使用 CJS 规范,可通过如下方式启用:

  • 单文件使用 ESM 规范,可以将该文件后缀改为 .mjs
  • 整个工程使用 ESM 规范,可以在 package.json 中配置 "type": "module"

假如不想通过上述方式启用,还有一些方法:

  • 通过 Webpack 等打包工具支持 ESM 模块(Webpack 默认使用 web 环境构建,需要配置 target: "node" 避免打包 Node 内置模块);
  • 还可以使用 ts-nodejiti 等 runtime 支持 ESM 模块(内部使用 tsc 或者 babel 进行编译);

📒 如何生成随机 ID

一种是直接使用 Math.random()

const randomId = () => Math.random().toString().slice(2, 8);

另一种是使用查表的方式:

// 生成 [0..9] 的数组
const nums = Array.from({ length: 10 }, (_, index) => index);

// 从 nums 数组中随机选取元素
const sample = (arr) => arr[Math.floor(Math.random() * arr.length)];
const randomId = () => Array.from({ length: 6 }, () => sample(nums)).join("");

📒 跨域如何携带 Cookie

  • 如果通过网关层代理(例如 nginx)则不用担心,对于浏览器来说实际上并没有跨域,可正常携带 Cookie
  • 如果通过 CORS 跨域,浏览器默认不会携带 Cookie,此时有两种方案:
    • 在请求头中添加 Authorization 字段发送 Cookie(在 axios 中配置请求拦截添加)
    • 后端响应头添加 Access-Control-Allow-Credentials,前端发送请求时配置 xhr.withCredentials = true

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

- - + + \ No newline at end of file diff --git a/2022/page/5/index.html b/2022/page/5/index.html index dfcedebca5..31f44af0e3 100644 --- a/2022/page/5/index.html +++ b/2022/page/5/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git a/2022/page/6/index.html b/2022/page/6/index.html index fbbd3d1cb4..f731576f5a 100644 --- a/2022/page/6/index.html +++ b/2022/page/6/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/babel/index.html b/2022/tags/babel/index.html index 97cc8bf99a..59ea9c6119 100644 --- a/2022/tags/babel/index.html +++ b/2022/tags/babel/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Babel"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git "a/2022/tags/cli-\345\267\245\345\205\267/index.html" "b/2022/tags/cli-\345\267\245\345\205\267/index.html" index f240c94ea3..c99c3cd9d2 100644 --- "a/2022/tags/cli-\345\267\245\345\205\267/index.html" +++ "b/2022/tags/cli-\345\267\245\345\205\267/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "CLI 工具"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git a/2022/tags/code-review/index.html b/2022/tags/code-review/index.html index ac07032b5a..05e167615f 100644 --- a/2022/tags/code-review/index.html +++ b/2022/tags/code-review/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Code Review"

View All Tags

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/cra/index.html b/2022/tags/cra/index.html index cde5f2032d..dcc81ea3d5 100644 --- a/2022/tags/cra/index.html +++ b/2022/tags/cra/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "CRA"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/css/index.html b/2022/tags/css/index.html index f5f2c5db59..31be155f90 100644 --- a/2022/tags/css/index.html +++ b/2022/tags/css/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

11 posts tagged with "CSS"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

- - + + \ No newline at end of file diff --git a/2022/tags/css/page/2/index.html b/2022/tags/css/page/2/index.html index 6e048c9d85..d7cc992359 100644 --- a/2022/tags/css/page/2/index.html +++ b/2022/tags/css/page/2/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

11 posts tagged with "CSS"

View All Tags

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git "a/2022/tags/diff-\347\256\227\346\263\225/index.html" "b/2022/tags/diff-\347\256\227\346\263\225/index.html" index b342f4f6a3..c7f31415bb 100644 --- "a/2022/tags/diff-\347\256\227\346\263\225/index.html" +++ "b/2022/tags/diff-\347\256\227\346\263\225/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Diff 算法"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git a/2022/tags/diff/index.html b/2022/tags/diff/index.html index 255c338441..c636ebd07a 100644 --- a/2022/tags/diff/index.html +++ b/2022/tags/diff/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "Diff"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/es-lint/index.html b/2022/tags/es-lint/index.html index e80845e83b..894f11e321 100644 --- a/2022/tags/es-lint/index.html +++ b/2022/tags/es-lint/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

10 posts tagged with "ESLint"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/es-next/index.html b/2022/tags/es-next/index.html index 958b7ab7e9..922e5c9461 100644 --- a/2022/tags/es-next/index.html +++ b/2022/tags/es-next/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "ESNext"

View All Tags

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git "a/2022/tags/git-hub-\345\256\232\346\227\266\344\273\273\345\212\241/index.html" "b/2022/tags/git-hub-\345\256\232\346\227\266\344\273\273\345\212\241/index.html" index 29d54c07f7..466fddca85 100644 --- "a/2022/tags/git-hub-\345\256\232\346\227\266\344\273\273\345\212\241/index.html" +++ "b/2022/tags/git-hub-\345\256\232\346\227\266\344\273\273\345\212\241/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "GitHub 定时任务"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git a/2022/tags/git/index.html b/2022/tags/git/index.html index 3b19ea36d5..7014acee03 100644 --- a/2022/tags/git/index.html +++ b/2022/tags/git/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

11 posts tagged with "git"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/git/page/2/index.html b/2022/tags/git/page/2/index.html index a282311c79..aab8bcd1e2 100644 --- a/2022/tags/git/page/2/index.html +++ b/2022/tags/git/page/2/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

11 posts tagged with "git"

View All Tags

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/golang/index.html b/2022/tags/golang/index.html index a8c4e0dec4..73d86ecc87 100644 --- a/2022/tags/golang/index.html +++ b/2022/tags/golang/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

11 posts tagged with "Golang"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/golang/page/2/index.html b/2022/tags/golang/page/2/index.html index 5413ed18b0..23761e99dd 100644 --- a/2022/tags/golang/page/2/index.html +++ b/2022/tags/golang/page/2/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

11 posts tagged with "Golang"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git "a/2022/tags/http-\347\274\223\345\255\230/index.html" "b/2022/tags/http-\347\274\223\345\255\230/index.html" index 072f498fdc..a4612e38f6 100644 --- "a/2022/tags/http-\347\274\223\345\255\230/index.html" +++ "b/2022/tags/http-\347\274\223\345\255\230/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "HTTP 缓存"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git a/2022/tags/idea/index.html b/2022/tags/idea/index.html index 3b940fb52e..ebf8162d96 100644 --- a/2022/tags/idea/index.html +++ b/2022/tags/idea/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "IDEA"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/index.html b/2022/tags/index.html index 27267803f8..484db2a669 100644 --- a/2022/tags/index.html +++ b/2022/tags/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

Tags

- - + + \ No newline at end of file diff --git "a/2022/tags/json-\345\272\217\345\210\227\345\214\226/index.html" "b/2022/tags/json-\345\272\217\345\210\227\345\214\226/index.html" index 2367ce0c8b..1bba47d1b8 100644 --- "a/2022/tags/json-\345\272\217\345\210\227\345\214\226/index.html" +++ "b/2022/tags/json-\345\272\217\345\210\227\345\214\226/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

10 posts tagged with "JSON 序列化"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/leetcode/index.html b/2022/tags/leetcode/index.html index 6fd740304d..46b08cc906 100644 --- a/2022/tags/leetcode/index.html +++ b/2022/tags/leetcode/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Leetcode"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git a/2022/tags/monorepo/index.html b/2022/tags/monorepo/index.html index 0259cbe52d..41c64ee24e 100644 --- a/2022/tags/monorepo/index.html +++ b/2022/tags/monorepo/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "monorepo"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/next-js/index.html b/2022/tags/next-js/index.html index 177d251066..a35c789dba 100644 --- a/2022/tags/next-js/index.html +++ b/2022/tags/next-js/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

2 posts tagged with "NextJS"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/node-js/index.html b/2022/tags/node-js/index.html index 3d53cf09d1..1d87211f57 100644 --- a/2022/tags/node-js/index.html +++ b/2022/tags/node-js/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Node.js"

View All Tags

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/performance/index.html b/2022/tags/performance/index.html index 52647c88a7..a024b9b3e3 100644 --- a/2022/tags/performance/index.html +++ b/2022/tags/performance/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Performance"

View All Tags

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/post-css/index.html b/2022/tags/post-css/index.html index 1bd9f9f23b..8474da3343 100644 --- a/2022/tags/post-css/index.html +++ b/2022/tags/post-css/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "PostCSS"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/prettier/index.html b/2022/tags/prettier/index.html index d72cee7b29..263b8c9d3b 100644 --- a/2022/tags/prettier/index.html +++ b/2022/tags/prettier/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

10 posts tagged with "Prettier"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/quic/index.html b/2022/tags/quic/index.html index b6a4b8690c..7dbfafe507 100644 --- a/2022/tags/quic/index.html +++ b/2022/tags/quic/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

2 posts tagged with "QUIC"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/tags/react-hooks-\347\212\266\346\200\201\347\256\241\347\220\206/index.html" "b/2022/tags/react-hooks-\347\212\266\346\200\201\347\256\241\347\220\206/index.html" index 3aa076fe2f..07171ecfe9 100644 --- "a/2022/tags/react-hooks-\347\212\266\346\200\201\347\256\241\347\220\206/index.html" +++ "b/2022/tags/react-hooks-\347\212\266\346\200\201\347\256\241\347\220\206/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "React Hooks 状态管理"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git a/2022/tags/react-native/index.html b/2022/tags/react-native/index.html index 3fc2cd2c39..d94e39ae38 100644 --- a/2022/tags/react-native/index.html +++ b/2022/tags/react-native/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "React Native"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git a/2022/tags/react/index.html b/2022/tags/react/index.html index bd8a02e09a..243ec39f03 100644 --- a/2022/tags/react/index.html +++ b/2022/tags/react/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

2 posts tagged with "React"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/rollup/index.html b/2022/tags/rollup/index.html index ff1cb0f1cd..9a566137e3 100644 --- a/2022/tags/rollup/index.html +++ b/2022/tags/rollup/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Rollup"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git a/2022/tags/type-script/index.html b/2022/tags/type-script/index.html index a62c031557..eca0ac746c 100644 --- a/2022/tags/type-script/index.html +++ b/2022/tags/type-script/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "TypeScript"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/vs-code/index.html b/2022/tags/vs-code/index.html index e2ae48fa07..56567f08a8 100644 --- a/2022/tags/vs-code/index.html +++ b/2022/tags/vs-code/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

3 posts tagged with "VS Code"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/vue-3/index.html b/2022/tags/vue-3/index.html index 76db0b7d36..b8aa39b09c 100644 --- a/2022/tags/vue-3/index.html +++ b/2022/tags/vue-3/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

10 posts tagged with "Vue3"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/vue/index.html b/2022/tags/vue/index.html index 867fc4b082..1de8133043 100644 --- a/2022/tags/vue/index.html +++ b/2022/tags/vue/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

2 posts tagged with "Vue"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git a/2022/tags/webpack-hmr/index.html b/2022/tags/webpack-hmr/index.html index bdb93646f1..1318a88e25 100644 --- a/2022/tags/webpack-hmr/index.html +++ b/2022/tags/webpack-hmr/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "Webpack HMR"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git a/2022/tags/webpack-loader/index.html b/2022/tags/webpack-loader/index.html index 90f571ced9..e9cbd6e448 100644 --- a/2022/tags/webpack-loader/index.html +++ b/2022/tags/webpack-loader/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Webpack loader"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git a/2022/tags/yaml/index.html b/2022/tags/yaml/index.html index 51595fb20f..97fa9366e9 100644 --- a/2022/tags/yaml/index.html +++ b/2022/tags/yaml/index.html @@ -11,14 +11,14 @@ - - + +
Skip to main content

10 posts tagged with "yaml"

View All Tags

· 13 min read
加菲猫

📒 rollup 配置优化方案

// 打包引用主入口文件
const appIndex = ["ESM", "CJS"].map(format => ({
input: path.resolve(__dirname, 'index.js'),
format,
external: ["./pyodide.worker.js"],
output: {
file: path.resolve(__dirname, 'dist/client', 'env.mjs'),
sourcemap: true
}
}));

// 打包 worker 文件
// 目的是让 rollup 也处理下这个文件
const worker = [
{
input: path.resolve(__dirname, 'pyodide.worker.js'),
output: {
file: path.resolve(__dirname, 'dist/client', 'pyodide.worker.js'),
sourcemap: true
}
}
]

export default [...appIndex, ...worker];

📒 Git merge 三种策略

  • git merge:默认使用 fast-forward 方式,git 直接把 HEAD 指针指向合并分支的头,完成合并。属于“快进方式”,不过这种情况如果删除分支,则会丢失分支信息。因为在这个过程中没有创建 commit
  • git merge --no-ff:强行关闭 fast-forward 方式,可以保存之前的分支历史。能够更好的查看 merge 历史,以及 branch 状态
  • git merge --squash:用来把一些不必要 commit 进行压缩,比如说,你的 feature 在开发的时候写的 commit 很乱,那么我们合并的时候不希望把这些历史 commit 带过来,于是使用 --squash 进行合并,需要进行一次额外的 commit 来“总结”一下,完成最终的合并

📒 Git 如何变基拉取代码

在本地 commit 之后,下一步一般会执行 git pull 合并远程分支代码。我们知道 git pull 相当于 git fetch && git merge,通过 merge 方式合并代码,缺点就是会导致时间线比较混乱,出现大量没用的 commit 记录,给 Code Review 带来不便。另一种方式是变基拉取:

$ git pull --rebase

在变基操作的时候,我们不去合并别人的代码,而是直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。变基的好处之一是可以使我们的时间线变得非常干净。

变基操作的时候,会创建一个临时的 rebasing branch,如有冲突,合并完冲突的文件,添加到暂存区后,执行:

$ git rebase --continue

此时会进入 commit message 编辑界面,输入 :q 就会提交 commit,后续只要推送远程仓库即可。

如果不想继续变基操作,执行:

$ git rebase --abort

📒 Git 操作之 git push -f

在开发一个项目的时候,本人将自己的 feature 分支合并到公共 test 分支,并且在测试环境部署成功。

几天后再去看的时候,发现测试环境提交的代码都不见了,本人在 test 分支的提交记录也都没了,只有另外一个同事留下的提交记录。最后重新将 feature 分支合到 test,再次部署到测试环境。

这个事情虽然影响不是很大,毕竟只是部署测试环境的分支,没有影响到 feature 分支,但是后来一直在想,究竟什么操作可以覆盖别人的提交记录。想来想去,应该只有下面几种情况:

  • git reset:回退版本,实际上就是向后移动 HEAD 指针,该操作不会产生 commit 记录
  • git revert:撤销某次操作,用一次新的 commit 来回滚之前的 commit,HEAD 继续前进,该操作之前和之后的 commit 和 history 都会保留
  • git push -f:将自己本地的代码强制推送到远程仓库。当使用 git push 推送报错时,除了耐心解决冲突再提交之外,还可以使用这个命令强制推送,但通常会造成严重后果,例如覆盖别人的提交记录

由于开发一般都在自己的 feature 分支上,只有在需要测试的时候才会合并 test 分支,因此使用 git reset 可能性不大。git revert 更不可能,不仅不会修改 history,同时还会创建一条新的 commit 记录。因此可能性最大的就是 git push -f 了。

一般我们推送代码之前都会习惯性执行 git pull,就算不执行 git pull,直接推送,只要有人在你之前推送过也会报错:

$ git push -u origin main

error: failed to push some refs to 'https://github.com/Jiacheng787/git-operate-demo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

在这种情况下,常规做法是执行 git pull 更新本地提交记录,如有冲突则解决冲突,然后再次推送。另一种做法就是强制推送:

$ git push -f origin main

可以看到就算没有事先 git pull 也不会报错,但是这样会导致远程仓库的提交记录被覆盖,远程仓库的提交记录变成了你本地的记录,你上次同步代码之后别人的提交记录都丢失了。

如何删除所有 commit 记录

初始化一个仓库:

$ git init

本地提交:

$ git add .
$ git commit -m "Initial commit"

下一步强制推送到远程仓库即可:

$ git branch -m main
$ git remote add origin <REPO_TARGET>
$ git push -f origin main

📒 Docker 容器如何实现持久化

Docker 容器本身是无状态的,无法持久化存储,在 Docker 容器中构建前端项目,如何缓存 node_modules 从而提升构建效率?可以给 Docker 容器挂载外部数据卷,映射到本地文件系统,就可以实现持久化存储。

📒 复盘 Node 项目中遇到的13+常见问题和解决方案

📒 GitHub 最受欢迎的Top 20 JavaScript 项目

GitHub 最受欢迎的Top 20 JavaScript 项目

📒 保护自己 - 深入链路探究网络安全

📒 50 多个提高前端人效率的工具、网站和书籍整理

📒 如何成为一个优秀的复制粘贴工程师

📒 原创精选荟萃(2022.03.14)

📒 只会用传统开发模式?10分钟教你玩转敏捷!

📒 如何提升 GitHub Page 访问速度

打包构建

使用 GitHub Action 作为 CI 环境,使用 Docker 进行构建,充分利用缓存,如 package.json 没变就不重复装包。

部署

打包之后将静态资源上传至阿里云 OSS(需要配置 Webpack 的 output.publicPath),提升页面加载速度。

HTML 页面暂时可以不上传,使用 GitHub Page 托管,这样访问速度可以保证,但是不能解决 GitHub Page 偶尔会挂的问题。还是要将 HTML 页面上传(Cache-Control:no-cache),此时整个网站完全托管在阿里云 OSS 上面,需要域名备案。

tip

如果页面需要后端服务,也可以不用服务器,直接使用 云数据库 + 云存储 + Serverless 云函数,免去运维成本。

📒 Golang 算法

https://github.com/fangbinwei/algorithm-practice

📒 Golang 项目参考

https://github.com/fangbinwei/aliyun-oss-website-action

📒 你知道的前端优化手段

📒 函数式编程(FP)

lodash 中的 FP

在lodash的官网上,我们很容易找到一个 function program guide 。在 lodash / fp 模块中提供了实用的对函数式编程友好的方法。里面的方式有以下的特性:

  • 不可变
  • 已柯里化(auto-curried)
  • 迭代前置(iteratee-first)
  • 数据后置(data-last)

假如需要将字符串进行如下转换,该如何实现呢?

例如:CAN YOU FEEL MY WORLD -> can-you-feel-my-world

import _ from 'lodash';

const str = "CAN YOU FEEL MY WORLD";

const split = _.curry((sep, str) => _.split(str, sep));
const join = _.curry((sep, arr) => _.join(arr, sep));
const map = _.curry((fn, arr) => _.map(arr, fn));

const f = _.flow(split(' '), map(_.toLower), join('-'));

f(str); // 'can-you-feel-my-world'

我们在使用 lodash 时,做能很多额外的转化动作,那我们试试 fp 模块吧。

import fp from 'lodash/fp';

const str = "CAN YOU FEEL MY WORLD";
const f = fp.flow(fp.split(' '), fp.map(fp.toLower), fp.join('-'));

f(str); // 'can-you-feel-my-world'

这种编程方式我们称之为 PointFree,它有 3 个特点:

  • 不需要指明处理的数据
  • 只需要合成运算过程
  • 需要定义一些辅助的基本运算函数

注意:FP 中的 map 方法和 lodash 中的 map 方法参数的个数是不同的,FP 中的 map 方法回调函数只接受一个参数

函数式编程(FP)

📒 一文颠覆大众对闭包的认知

📒 React v18 正式版发布

📒 答好这5个问题,就入门Docker了

📒 手写 Webpack

手写webpack核心原理,再也不怕面试官问我webpack原理

100行代码实现一个组件引用次数统计插件

📒 Golang 指针几点注意

  • Golang 中赋值操作、函数参数、函数返回值都是 copy
  • 基本类型、slice、map 直接传递就行,对于 struct、array 需要特别注意,建议一律传递指针类型

📒 Dum:Rust 编写的 npm 脚本运行器

延续了使用不是 JavaScript 来构建 JavaScript 工具的趋势。这个奇怪的名字 “Dum”,旨在取代 npm runnpx 来减少任务启动时间的毫秒数。

https://github.com/egoist/dum

📒 Node 之道:关于设计、架构与最佳实践

https://alexkondov.com/tao-of-node/

📒 Hooks 的 ”危害性“

作者声称“每周都能找到十几个与 hooks 相关的问题”,并利用这段经历给出了一些例子和解决方法,以避免“API 的不足之处”。

https://labs.factorialhr.com/posts/hooks-considered-harmful

📒 Dockerfile 配置

# 两段式构建
# 第一段构建源码镜像
ARG PROJECT_DIR=/project
ARG BB_ENV=prod
FROM harbor.hiktest.com/public/vue:2.5-node10 as src
ARG PROJECT_DIR
ARG BB_ENV


COPY . ${PROJECT_DIR}/
WORKDIR ${PROJECT_DIR}/

RUN npm install && npm run build:${BB_ENV}


# 第二段从源码镜像中拷贝出编译的dist,做成目标镜像
FROM harbor.hiktest.com/hikvision/nginx:1.12
ARG PROJECT_DIR

ENV LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

COPY --from=src ${PROJECT_DIR}/dist /usr/share/nginx/html/
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./default.conf /etc/nginx/conf.d/default.conf

📒 万字长文助你上手软件领域驱动设计 DDD

📒 TypeScript 终极初学者指南

· 12 min read
加菲猫

📒 从 React 源码的类型定义中,我学到了什么?

📒 前端单测为什么不要测代码实现细节?

📒 React+Ts,这样学起来确实简单!!!

📒 高频 LeetCode 面试题分类

📒 如何在常数时间插入、删除数组中的元素

之前看到过一个用数组实现队列的方案,移除元素使用 shift,导致时间复杂度为 O(n),后来改为使用双向链表实现队列,插入删除时间复杂度都为 O(1)。如果使用链表的话,如何在常数时间内查找元素呢,可以使用 Map 存储链表节点指针,从而实现哈希链表的结构。

话说回来,如果使用数组的方案,如何实现常数时间插入、删除数组元素呢?可以做到!对数组尾部进行插入和删除操作不会涉及数据搬移,时间复杂度是 O(1)所以,如果我们想在 O(1) 的时间删除数组中的某一个元素 val,可以先把这个元素交换到数组的尾部,然后再 pop

📒 Typeit:轻量级代码录制回放

📒 React 18 超全升级指南

📒 「多图详解」NodeJs中EventLoop与浏览器下的差异性

📒 超爽!VSCode 实现自动原子化 CSS 样式

📒 云计算时代,你还不会 Docker ? 一万字总结(建议收藏)

📒 腾讯云后端15连问

三数之和,可以先对数组进行排序,然后使用左右指针

腾讯云后端15连问!

📒 十道腾讯算法真题解析!

📒 [科普文] Vue3 到底更新了什么?

📒 基于 TypeScript 理解程序设计的 SOLID 原则

📒 晋升,如何减少 50%+ 的答辩材料准备时间、调整心态(个人经验总结)

📒 【Anthony Fu】写个聪明的打字机!直播录像

📒 https://github.com/unjs

📒 如何理解 partition 函数

利用左右指针,其实有点类似反转数组,只不过反转数组对每个元素都交换一下,而 partition 只有在特定条件下进行交换:

  • 左指针向右移动,直到 nums[i] > pivot 停止移动,此时再移动右指针,接下来会有两种情况
    • 右指针遇到 nums[j] <= pivot 时停止移动,此时进行元素交换
    • 左指针右侧的元素都大于 pivot,没有元素需要交换,最终两个指针重合,停止操作
  • 不断重复上述步骤,直到交换结束,此时 nums[j] 为较小值,将 pivotnums[j] 交换
const partition = (nums: number[], lo: number, hi: number) => {
const pivot = nums[lo];
let i = lo + 1,
j = hi;
while (true) {
while (i < hi && nums[i] <= pivot) {
i++;
}
while (j > lo && nums[j] > pivot) {
j--;
}
if (i >= j) {
break;
}
swap(nums, i, j);
}
swap(nums, lo, j);
return j;
};

const swap = (nums: number[], i: number, j: number) => {
const temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
};

📒 在项目中用ts封装axios,一次封装整个团队受益😁

📒 阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

为什么递归遍历 vdom 树不能中断

这种遍历有一个特点,必须一次性完成。假设遍历发生了中断,虽然可以保留当下进行中节点的索引,下次继续时,我们的确可以继续遍历该节点下面的所有子节点,但是没有办法找到其父节点——因为每个节点只有其子节点的指向。断点没有办法恢复,只能从头再来一遍。

在新的架构中,每个节点有三个指针:分别指向第一个子节点、下一个兄弟节点、父节点。这种数据结构就是fiber,它的遍历规则如下:

  1. 从根节点开始,依次遍历该节点的子节点、兄弟节点,如果两者都遍历了,则回到它的父节点;
  2. 当一个节点的所有子节点遍历完成,才认为该节点遍历完成;

提出问题:render 阶段 vdom 转 fiber 还是通过递归的方式,那么 fiber 链表可中断遍历是在哪一步

阿里三面:灵魂拷问——有react fiber,为什么不需要vue fiber呢

React 技术揭秘

📒 Vue组件库设计 | Vue3组件在线交互解释器

📒 React 类组件注意事项

1. 为了避免组件不必要的 rerender,建议继承 PureComponent

class MyCompoment extends React.PureComponent {
// ...
}

PureComponent 相当于函数组件使用 React.memo

2. 在构造方法中如要使用 this,则必须先调用 super()

class MyCompoment extends React.Component {
constructor(props) {
// 如果想在构造方法中使用 this,则必须先调用 super()
// super 实际上就是父类构造方法,类似盗用构造函数继承
// 下面是一个声明 state 的例子
super(props);
this.state = {
// ...
}
}
}

如果使用 ES2022 Class Properties 语法,则可以直接干掉构造方法,更加简洁:

class MyCompoment extends React.Component {
// 使用 ES2022 Class Properties 语法
state = {
// ...
}
}

3. 状态更新可能是异步的

React 可能会对多次 setState() 调用进行批处理,使组件只更新一次,因此 this.propsthis.state 可能会异步更新。所以不能依赖 this.state 计算下一个状态,这种情况下,可以使用函数式更新:

this.setState((prevState, prevProps) => ({
counter: prevState.counter + prevProps.increment
}));

4 类组件中需要注意事件处理函数的 this 绑定问题

class MyCompoment extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}

handleClick() {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

如果使用 ES2022 Class Properties 语法,也可以让语法更简洁:

class MyCompoment extends React.Component {
handleClick = () => {
console.log('===点击事件');
}

render() {
return (
<button onClick={this.handleClick}>点击</button>
)
}
}

📒 箭头函数两个注意点

查看详情

1. 箭头函数中 this 指向能否改变

以下引用阮一峰 ES6 教程:

箭头函数没有自己的 this 对象,内部的 this 就是定义时上层作用域中的 this。也就是说,箭头函数内部的 this 指向是固定的,相比之下,普通函数的 this 指向是可变的

看了上面这段描述,很多同学可能都认为,箭头函数的 this 是无法改变的,但实际上箭头函数的 this 是跟着上层作用域走的,只要上层作用域的 this 改变,箭头函数中的 this 也会相应改变:

function foo() {
const bar = () => {
// 箭头函数的 this 来自 foo 函数
console.log(this.name);
}
bar();
}

const o1 = { name: "2333" };
const o2 = { name: "666" };

foo.bind(o1)(); // 2333
foo.bind(o2)(); // 666

如果将上述代码编译为 ES5 就能很容易理解上述过程:

function foo() {
var _this = this;
var bar = function() {
console.log(_this.name);
}
bar();
}

2. 为什么“类方法”可以使用箭头函数

在博客中看到有这样的代码:

class Person {
constructor(name) {
this.name = name;
}

getName = () => {
console.log(this.name);
}
}

咋一看好像没有问题,但是仔细一想发现不对,原型对象在所有实例之间是共享的,因此类方法的 this 必须要动态绑定,而箭头函数的 this 是静态的,这样不就有 bug 了,但是试验发现并没有问题:

const p1 = new Person("2333");
p1.getName(); // 2333
const p2 = new Person("666");
p2.getName(); // 666

这是因为,getName 实际并不是类方法,而是 ES2022 中类属性的写法,getName 实际上是一个对象的自有属性,可以使用下面的代码证明:

Object.prototype.hasOwnProperty.call(p1, "getName"); // true

这一点在 React 文档事件处理函数 this 绑定中也有说明:

class Foo extends Component {
// Note: this syntax is experimental and not standardized yet.
handleClick = () => {
console.log('Click happened');
}
render() {
return <button onClick={this.handleClick}>Click Me</button>;
}
}

https://reactjs.org/docs/faq-functions.html#how-do-i-bind-a-function-to-a-component-instance

而类方法有且仅有下面这种写法:

class Person {
constructor(name) {
this.name = name;
}

getName() {
console.log(this.name);
}
}

使用箭头函数作为类属性时,绑定 this 的过程如下:

function Person(name) {
this.name = name;
this.getName = () => {
console.log(this.name);
}
}

const o = {};
Person.bind(o)("2333");
o.getName(); // 2333

new 调用过程中,Person 函数的 this 会绑定到实例对象上,箭头函数的 this 就是 Person 函数的 this,因此箭头函数的 this 会指向实例对象,并且由于箭头函数作为类的自有属性,会在每次 new 的时候重新生成,因此不同实例之间不会影响

📒 我的第一次webpack优化,首屏渲染从9s到1s

📒 几个一看就会的 TypeScript 小技巧

📒 Next.js 官方发布全新教程

· 8 min read
加菲猫

📒 以 pnpm 为例谈谈如何调试大型项目

📒 如何实现双向链表

查看详情

在项目中遇到一个问题,源码中使用数组模拟队列,添加使用 unshift,移除使用 pop,导致添加元素的时间复杂度为 O(n)。这里使用双向链表模拟队列,两端均可添加、删除元素,且时间复杂度均为 O(1)

/**
* 链表节点
*/
class ListNode<T> {
public next: ListNode<T> = null;
public prev: ListNode<T> = null;
public val: T = undefined;

constructor(val: T) {
this.val = val;
}
}

/**
* 实现双向链表
*/
class LinkedList<T> {
private head: ListNode<T> = null;
private end: ListNode<T> = null;
private _size: number = 0;

/**
* add() 相当于 addLast()
* @param val
* @returns
*/
public add(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
} else {
// 把新节点挂到链表最后
this.end.next = node;
// 新节点 prev 指向前一节点
node.prev = this.end;
// end 指针后移一位
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* addFirst() 在链表头部添加
* @param val
* @returns
*/
public addFirst(val: T): boolean {
const node = new ListNode<T>(val);
if (this.head == null) {
// 初始化 head 指针
this.head = node;
} else {
// 把新节点挂到链表头部
this.head.prev = node;
// 新节点 next 指向下一节点
node.next = this.head;
// head 指针前移一位
this.head = node;
}
if (this.end == null) {
// 初始化 end 指针
this.end = node;
}
// 维护 size
this._size++;
return true;
}

/**
* poll() 相当于 pollFirst()
* @returns
*/
public poll(): T {
// 缓存需要删除的节点
const node = this.head;
// head 指向下一节点
this.head = this.head.next;
// 切断与前一节点的联系
this.head.prev = null;
// 维护 size
this._size--;
return node.val;
}

/**
* pollLast() 移除链表尾部元素
* @returns
*/
public pollLast(): T {
// 缓存需要删除的节点
const node = this.end;
// end 指向前一节点
this.end = this.end.prev;
// 切断与后一节点的联系
this.end.next = null;
// 维护 size
this._size--;
return node.val;
}

/**
* 获取链表长度
* @returns
*/
public size(): number {
return this._size;
}

/**
* 序列化为字符串
* @returns
*/
public toString(): string {
let res: T[] = [];
let list = this.head;
while (list != null) {
res.push(list.val);
list = list.next;
}
return `[ ${res.join(" ")} ]`;
}
}

📒 Nest.js 的 AOP 架构的好处,你感受到了么?

📒 React Hooks 源码分析

React 函数组件通过 renderWithHooks 函数进行渲染,里面有个 workingInProgress 的对象就是当前的 fiber 节点,fiber 节点的 memorizedState 就是保存 hooks 数据的地方。它是一个通过 next 串联的链表。

这个 memorizedState 链表是什么时候创建的呢?确实有个链表创建的过程,也就是 mountXxx。链表只需要创建一次,后面只需要 update。所以第一次调用 useState 会执行 mountState,后面再调用 useState 会执行 updateState

每个 Hook 的 memorizedState 链表节点是通过 mountWorkInProgressHook 函数创建的:

function mountWorkInProgressHook(): Hook {
const hook = {
memoizedState: null,
baseState: null,
baseQueue: null,
queue: null,
next: null,
};

if (workInProgressHook === null) {
// This is the first hook in the list
currentlyRenderingFiber.memoizedState = workInProgressHook = hook;
} else {
// Append to the end of the list
workInProgressHook = workInProgressHook.next = hook;
}
return workInProgressHook;
}

函数组件本身是没有挂载、更新的概念的,每次 rerender 就是执行这个函数,但是挂载、更新的逻辑体现在 Hooks 里面,首次执行的时候调用 mountWorkInProgressHook 创建链表节点,后续执行的时候调用 updateWorkInProgressHook 访问并更新链表节点

React Hooks 的原理,有的简单有的不简单

React 进阶实战指南 - 原理篇:Hooks 原理

📒 前端工程师如何快速使用一个NLP模型

2017年谷歌提出了Transformer架构模型,2018年底,基于Transformer架构,谷歌推出了bert模型,bert模型一诞生,便在各大11项NLP基础任务中展现出了卓越的性能,现在很多模型都是基于或参考Bert模型进行改造。

tip

如果想了解 Transformer 和 bert,可以看这个视频

https://www.bilibili.com/video/BV1P4411F77q

https://www.bilibili.com/video/BV1Mt411J734

前端工程师如何快速使用一个NLP模型

📒 Lerna 运行流程剖析

⭐️ Git不要只会pull和push,试试这5条提高效率的命令

📒 React内部的性能优化没有达到极致?

📒 reduce 方法注意事项

初始值非空初始值为空
数组非空首次执行回调,accu 为初始值,cur 为数组第一项首次执行回调,accu 为数组第一项,cur 为数组第二项
数组为空不执行回调,直接返回初始值报错(建议任何情况下都传递初始值)

📒 npm 安装依赖默认添加 ^ 前缀,当再次执行 npm install 命令时,会自动安装这个包在此大版本下的最新版本。如果想要修改这个功能,可以执行以下命令:

$ npm config set save-prefix='~'

执行完该命令之后,就会把 ^ 符号改为 ~ 符号。当再次安装新模块时,就从只允许小版本的升级变成了只允许补丁包的升级

如果想要锁定当前的版本,可以执行以下命令:

$ npm config set save-exact true

这样每次 npm install xxx --save 时就会锁定依赖的版本号,相当于加了 --save-exact 参数。建议线上的应用都采用这种锁定版本号的方式

既然可以锁定依赖版本,为什么还需要 lcok-file 呢,个人理解锁定依赖只能锁定当前项目中的依赖版本,但是还存在间接依赖,即依赖还有依赖,直接锁定依赖版本无法解决间接依赖的问题,间接依赖版本还是不受控制,需要借助 lock-file 锁定间接依赖的版本。

📒 函数式编程三种形式:

  • 函数赋值给变量
    • 可作为数组的元素,进而实现 compose 函数组合,或者管道操作
  • 函数作为参数
    • 常见的有 forEachPromisesetTimeout 等,React 技术栈也有很多 API
  • 函数作为返回值

📒 GitLab CI 打造一条自己的流水线

📒 type-challenges

type-challenges 是一个 TypeScript 类型体操姿势合集。本项目意在于让你更好的了解 TS 的类型系统,编写你自己的类型工具,或者只是单纯的享受挑战的乐趣!

https://github.com/type-challenges/type-challenges

· 11 min read
加菲猫

📒 React 18 RC 版本发布啦,生产环境用起来!

安装最新的 React 18 RC 版本(Release Candidate候选版本):

$ yarn add react@rc react-dom@rc

注意在 React 18 中新增了 concurrent Mode 模式,通过新增的 createRoot API 开启:

import ReactDOM from 'react-dom'

// 通过 createRoot 创建 root
const root = ReactDOM.createRoot(document.getElementById('app'))
// 调用 root 的 render 方法
root.render(<App/>)

startTransition 特性依赖 concurrent Mode 模式运行

如果使用传统 legacy 模式,会按 React 17 的方式运行:

import ReactDOM from 'react-dom'

// 通过 ReactDOM.render
ReactDOM.render(
<App />,
document.getElementById('app')
)

React 18 主要是对自动批处理进行优化。在 React 18 之前实际上已经有批处理机制,但是只针对同步代码,如果放在 PromisesetTimeout 等异步回调中,自动批处理会失效。

class Example extends React.Component {
constructor() {
super();
this.state = {
val: 0
};
}

componentDidMount() {
// 自动批处理更新
// 注意此时 setState 是异步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1});
console.log(this.state.val);

setTimeout(() => {
// 自动批处理失效
// 此时 setState 是同步的
this.setState({val: this.state.val + 1});
console.log(this.state.val);
this.setState({val: this.state.val + 1};
console.log(this.state.val);
}, 0);
}
};

在 React 18 版本之前,上面代码的打印顺序是 0、0、2、3

React 18 版本解决了这个问题,在异步回调中更新状态也能触发自动批处理,打印的顺序是 0、0、1、1

总结一下主要有以下几个新特性:

  • 新的 ReactDOM.createRoot() API(替换 ReactDOM.render()
  • 新的 startTransition API(用于非紧急状态更新)
  • 渲染的自动批处理优化(主要解决异步回调中无法批处理的问题)
  • 支持 React.lazy 的 全新 SSR 架构(支持 <Suspense> 组件)

React 18 RC 版本发布啦,生产环境用起来!

📒 CSS TreeShaking 原理揭秘: 手写一个 PurgeCss

📒 「源码解析」一文吃透react-redux源码(useMemo经典源码级案例)

📒 Recoil实现原理浅析-异步请求

📒 WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

HTTP 和 WebSocket 都属于应用层协议,都是基于 TCP 来传输数据的,可以理解为对 TCP 的封装,都要遵循 TCP 的三次握手和四次挥手,只是在连接之后发送的内容(报文格式)不同,或者是断开的时间不同。

如何使用 Wireshark 抓包:

  • 在 Capture 中选择本机回环网络
  • 在 filter 中写入过滤条件 tcp.port == 3000

WebSocket 基础与应用系列(一)—— 抓个 WebSocket 的包

📒 CSS 代码优化的12个小技巧

📒 JS 框架解决了什么问题

📒 反向操作,用 Object.defineProperty 重写 @vue/reactivity

📒 antfu 大佬的 eslint 配置

https://github.com/antfu/eslint-config

📒 antfu 大佬的 vscode 配置

https://github.com/antfu/vscode-settings

📒 使用 tsdoc 编写规范的注释

https://tsdoc.org/

📒 npm 包发布工具

https://github.com/JS-DevTools/version-bump-prompt

📒 使用 pnpm 作为包管理工具

基本用法:

  • pnpm add <pkg>:安装依赖
  • pnpm add -D <pkg>:安装依赖到 devDependencies
  • pnpm install:安装所有依赖
  • pnpm -r update:递归更新每个包的依赖
  • pnpm -r update typescript@latest:将每个包的 typescript 更新为最新版本
  • pnpm remove:移除依赖

如何支持 monorepo 项目:https://pnpm.io/zh/workspaces

pnpm -r 带一个参数 -r 表示进行递归操作。

pnpm 官方文档

为什么 vue 源码以及生态仓库要迁移 pnpm?

📒 推荐两个打包工具

📒 seedrandom:JS 种子随机数生成器

种子随机数生成器,生成是随机的,但是每次调用生成的值是固定的:

const seedrandom = require('seedrandom');
const rng = seedrandom('hello.');

console.log(rng()); // 第一次调用总是 0.9282578795792454
console.log(rng()); // 第二次调用总是 0.3752569768646784

https://github.com/davidbau/seedrandom

📒 深入Node.js的模块加载机制,手写require函数

📒 require加载器实现原理

📒 聊一聊前端算法面试——递归

📒 589. N 叉树的前序遍历 :「递归」&「非递归」&「通用非递归」

📒 Million v1.5:一种快速虚拟 DOM 的实现

专注于性能和大小,压缩后小于 1KB,如果您想要一个抽象的 VDOM 实现,Million 是你构建自己的框架或库时理想的选择

https://millionjs.org/

📒 200 行代码使用 React 实现俄罗斯方块

https://blog.ag-grid.com/tetris-to-learn-react/

📒 真实案例说明 TypeScript 类型体操的意义

📒 「React 进阶」 学好这些 React 设计模式,能让你的 React 项目飞起来🛫️

📒 「1.9W字总结」一份通俗易懂的 TS 教程,入门 + 实战!

📒 Oclif v2.5:Heroku 开源的 CLI 框架

一个用于构建 CLI 脚手架的成熟框架,无论是简单的参数解析还是很多功能指令都可以驾驭。

https://github.com/oclif/oclif

📒 使用 Rust 与 WebAssembly 重新实现了 Node 的 URL 解析器

https://www.yagiz.co/implementing-node-js-url-parser-in-webassembly-with-rust/

📒 PDF:从 JavaScript 到 Rust:新书免费发布

https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf

📒 Red Hat 和 IBM 团队的 Node.js “架构参考”

https://github.com/nodeshift/nodejs-reference-architecture

📒 在 Node 环境下使用 execa 运行命令

https://blog.logrocket.com/running-commands-with-execa-in-node-js/

📒 万字长文详解从零搭建企业级 vue3 + vite2+ ts4 框架全过程

📒 从 Linux 源码的角度解释进程

📒 10 React Antipatterns to Avoid - Code This, Not That!

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 markdown 编辑器滚动如何实现联动

const ScrollTarget = {
NONE: "NONE",
EDITOR: "EDITOR",
RENDER: "RENDER",
};

let curTarget = ScrollTarget.NONE;
let timer = null;

const scrollManager = (handler) => (target) => {
if ((curTarget = ScrollTarget.NONE)) {
curTarget = target;
}
if (curTarget === target) {
handler(target);
if (timer) clearTimeout(timer);
timer = setTimeout(() => {
curTarget = ScrollTarget.NONE;
}, 100);
}
};

const scrollFn = scrollManager(handleScroll);

📒 Webpack 的模块规范

Webpack 基于 CJS 和 ESM 规范实现了模块机制,但也不是完全基于,而是在这些模块规范基础上扩展了一套自己的 api,用于增强功能,例如:

  • require.context
  • 使用 import 加载 .json 模块

在 ESM 规范中 import 只能用于加载 JS 模块,只有 require 可以加载 json 模块

📒 如何将对象序列化为查询字符串

const aaa = {a: 1, b: 2, c: "2333"}

第一种手动拼接,简单直接,一行代码搞定:

const _stringify =
(obj) => Object.entries(obj).map(([key, val]) => `${key}=${val}`).join("&");

还可以使用 URLSearchParams 对象进行拼接:

const _stringify = obj => Object.entries(obj).reduce((accu, [key, val]) => {
accu.append(key, val);
return accu;
}, new URLSearchParams)

📒 「深入浅出」主流前端框架更新批处理方式

浏览器环境下,宏任务的执行并不会影响到浏览器的渲染和响应,即宏任务优先级低于页面渲染。

function run(){
setTimeout(() => {
console.log('----宏任务执行----')
run()
}, 0)
}
// 通过递归调用 run 函数,让 setTimeout 宏任务反复执行
// 这种情况下 setTimeout 执行并不影响页面渲染和交互事件
run()

微任务会在当前 event loop 中执行完毕,会阻塞浏览器的渲染和响应,即微任务优先级高于页面渲染。

function run(){
Promise.resolve().then(() => {
run()
})
}
// 在这种情况下,页面直接卡死了,没有响应
run()

这里主要就是理解关键渲染路径,即浏览器渲染一帧会先执行脚本,再页面布局,绘制渲染。如果是宏任务,浏览器会把每一次事件回调放在下一帧渲染前执行,这样可以确保浏览器每一帧都能正常渲染。如果是微任务,浏览器在执行渲染之前会清空微任务队列,会导致一直停留在当前 event loop,相当于脚本一直在执行,如果长时间不把控制权交还给浏览器,就会影响下一帧的渲染,导致页面出现卡顿和事件响应不及时。

「深入浅出」主流前端框架更新批处理方式

· 19 min read
加菲猫

📒 通过Vue自定义指令实现前端埋点

📒 Deno 简介:它比 Node.js 更好吗?

📒 快来玩转这 19 个 css 技巧

📒 解决了 Redis 大 key 问题,同事们都说牛皮!

📒 图解|Linux内存背后的那些神秘往事

📒 深入理解Go Json.Unmarshal精度丢失之谜

📒 如何理解快速排序和归并排序

快速排序实际就是二叉树的前序遍历,归并排序实际就是二叉树的后序遍历。

快速排序的逻辑是,若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1]nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

快速排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
/****** 前序遍历位置 ******/
// 通过交换元素构建分界点 p
int p = partition(nums, lo, hi);
/************************/

sort(nums, lo, p - 1);
sort(nums, p + 1, hi);
}

先构造分界点,然后去左右子数组构造分界点,你看这不就是一个二叉树的前序遍历吗

再说说归并排序的逻辑,若要对 nums[lo..hi] 进行排序,我们先对 nums[lo..mid] 排序,再对 nums[mid+1..hi] 排序,最后把这两个有序的子数组合并,整个数组就排好序了。

归并排序的代码框架如下:

void sort(int[] nums, int lo, int hi) {
int mid = (lo + hi) / 2;
// 排序 nums[lo..mid]
sort(nums, lo, mid);
// 排序 nums[mid+1..hi]
sort(nums, mid + 1, hi);

/****** 后序位置 ******/
// 合并 nums[lo..mid] 和 nums[mid+1..hi]
merge(nums, lo, mid, hi);
/*********************/
}

先对左右子数组排序,然后合并(类似合并有序链表的逻辑),你看这是不是二叉树的后序遍历框架?另外,这不就是传说中的分治算法嘛,不过如此呀

说了这么多,旨在说明,二叉树的算法思想的运用广泛,甚至可以说,只要涉及递归,都可以抽象成二叉树的问题。

📒 Leetcode 236 二叉树最近公共祖先

lowestCommonAncestor 方法的定义:给该函数输入三个参数 rootpq,它会返回一个节点。

  • 情况 1,如果 pq 都在以 root 为根的树中,函数返回的即 pq 的最近公共祖先节点。
  • 情况 2,如果 pq 都不在以 root 为根的树中,则理所当然地返回 null 呗。
  • 情况 3,如果 pq 只有一个存在于 root 为根的树中,函数就返回那个节点。
tip

题目说了输入的 pq 一定存在于以 root 为根的树中,但是递归过程中,以上三种情况都有可能发生,所以说这里要定义清楚,后续这些定义都会在代码中体现。

函数参数中的变量是 root,因为根据框架,lowestCommonAncestor(root) 会递归调用 root.leftroot.right;至于 pq,我们要求它俩的公共祖先,它俩肯定不会变化的。你也可以理解这是「状态转移」,每次递归在做什么?不就是在把「以root为根」转移成「以root的子节点为根」,不断缩小问题规模嘛

class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
// 两个 base case
// 1.如果 root 为空,直接返回 null
if (root == null) return null;
// 2.如果 root 本身就是 p 或者 q
// 例如 root 是 p 节点,如果 q 存在于以 root 为根的树中,显然 root 就是最近公共祖先
// 即使 q 不存在于以 root 为根的树中,按照情况 3 的定义,也应该返回 root 节点
if (root == p || root == q) return root;

TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);

// 在后序位置分情况讨论
// 情况 1,如果 p 和 q 都在以 root 为根的树中
// 那么 left 和 right 一定分别是 p 和 q(从 base case 看出)
// 由于后序位置是从下往上,就好比从 p 和 q 出发往上走
// 第一次相交的节点就是这个 root,显然就是最近公共祖先
if (left != null && right != null) {
return root;
}
// 情况 2,如果 p 和 q 都不在以 root 为根的树中,直接返回 null
if (left == null && right == null) {
return null;
}
// 情况 3,如果 p 和 q 只有一个存在于 root 为根的树中,函数返回该节点
return left == null ? right : left;
}
}

在前序位置搜索节点,如果是空节点直接返回,如果搜索到 p 或者 q 返回该节点,否则继续递归

在后序位置接收前序的返回值,如果 leftright 都不为空,说明分别是 pq,当前 root 就是最近公共祖先,直接返回 root 节点。如果一个为空另一个不为空,说明找到一个节点,把这个节点向上传递,查找另一个节点,直到出现两个都不为空,此时 root 就是最近公共祖先,直接返回 root 节点

📒 如何写对二分查找

  • 不要使用 else,而是把所有情况用 else if 写清楚
  • 计算 mid 时需要防止溢出,使用 left + (right - left) / 2 先减后加这样的写法
  • while 循环的条件 <= 对应 right 初始值为 nums.length - 1,此时终止条件是 left == right + 1,例如 [3, 2]
  • 如果 while 循环的条件 <,需要把 right 初始值改为 nums.length,此时终止条件是 left == right,例如 [2, 2],这样会漏掉最后一个区间的元素,需要单独判断下
  • mid 不是要找的 target 时,下一步应该搜索 [left, mid-1] 或者 [mid+1, right],对应 left = mid + 1 或者 right = mid - 1
  • 二分查找时间复杂度 O(logn)
class Solution {
public int search(int[] nums, int target) {
int left = 0;
int right = nums.length - 1; // 注意

while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
} else if (nums[mid] < target) {
left = mid + 1; // 注意
} else if (nums[mid] > target) {
right = mid - 1; // 注意
}
}
return -1;
}
}

📒 前端三种 Content-Type

application/json:这种应该是接口请求用到最多的,可以使用 JSON.stringify() 序列化得到,实际传递的内容类似于:

{"a": "111", "b": "222"}

application/x-www-form-urlencoded:这是表单提交对应的 Content-Type,实际上就是通过 body 传递 query 参数,如使用 HTML 的表单元素,浏览器会自动进行拼接,也可通过 URLSearchParams 拼接得到,实际传递的内容类似于:

a=111&b=222

multipart/form-data:是通过 FormData 对象构造出来的表单格式,通常用于文件上传,实际传递的报文内容类似于:

POST /test.html HTTP/1.1
Host: example.org
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="field1"

value1
--boundary
Content-Disposition: form-data; name="field2"; filename="example.txt"

value2
--boundary--

顺便提一下,文件下载对应的 Content-Type 是 application/octet-stream

📒 如何理解 Node.js 模块

一个模块实际上可以看做一个 once 函数,头部的 require 命令可以看做入参,module.exports 可以看做返回值。

当首次加载一个模块的时候,就会运行这个模块代码,可以看做是调用一个函数,执行结束后得到导出的内容并被缓存,可以看做函数返回一个值。当再次加载这个模块,不再执行这个模块代码,而是直接从缓存中取值。

在一个函数中,我们知道可以使用 return 语句提前结束运行,那么在模块中如何实现呢,答案是使用 process.exit(1)

const fs = require("node:fs");
const path = require("node:path");
const webpack = require("webpack");

const workDir = process.cwd();
const envFilePath = path.resolve(workDir, "./.env.local");
const hasEnvFile = fs.existsSync(envFilePath);

if (!hasEnvFile) {
process.exit(1);
}

module.exports = {
mode: "development",
entry: './src/index.js',
output: {
path: path.resolve(__dirname, './dist'),
filename: '[chunkhash].bundle.js',
clean: true
},
}

这里注意下,fs.exists() 方法已经废弃了,但是 fs.existsSync() 仍然可用。此外还可使用 fs.stat() 或者 fs.access() 检查文件是否存在

📒 在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?

📒 一键部署 K8S 环境,10分钟玩转,这款开源神器实在太香了!

📒 charles 如何连接手机抓包

  • 确保手机和电脑连接的是同一个网络
  • 首先打开 charles,会启动一个服务,查看端口:proxy -> proxy setting
  • 勾选 Enable transparent HTTP proxying
  • 查看本机 IP
  • 在手机上设置 http 代理服务器,输入 IP 和端口
  • 此时 charles 会弹出提示,有新的连接,点击 allow

📒 前端项目的 .env 文件是如何生效的,一句话总结

通过 dotenv 这个包解析 .env 文件,加载到 process.ENV 里面,这时候可以通过 process.ENV.xxx 访问到环境变量,适用于 Node.js 项目,但是由于浏览器环境访问不到 process 对象,所以对于前端项目,还需要使用 Webpack 的 DefinePlugin 在打包构建阶段将变量替换为对应的值。

📒 如何防止用户篡改 url 参数

http://localhost:8080/codepc/live?codeTime=1646038261531&liveId=5e24dd3cf03a&sign=e8fe282676f584ceab7e35f84cbc52ff&keyFrom=youdao

前端的直播链接带有 codeTimeliveId,如何防止用户篡改。只需要后端在返回 codeTimeliveId 的时候,同时计算一个签名 sign 返回给前端,前端提交给后端的时候,同时传递三个参数,后端计算一个新的签名,与前端传过来的 sign 进行比对,如果一样就说明没有篡改。

但是计算签名用的 md5 是一个公开的算法,假如有人篡改了 codeTimeliveId ,只要他使用 md5 计算一个新的签名 sign ,这样传给后端校验必然可以通过。这就需要后端签名的时候拼接一个加密串进去,验签的时候也用这个加密串。这样由于别人不知道加密串,即便生成新的签名,后端校验也不会通过。

📒 了解下Rust 模块使用方式

🌛 一文秒杀排列组合问题的 9 种题型

📒 Screenshot: 不依赖浏览器原生能力的截屏库

该库基于 MediaDevice API 来提供了易于截屏的抽象。如果你有兴趣可以来看看 GitHub 仓库

https://github.com/xataio/screenshot

📒 enum-xyz:使用 Proxy 实现 JavaScript 中的枚举

一个 js-weekly 的读者,分享的有趣实现思路。源码很短,推荐看一下

https://github.com/chasefleming/enum-xyz

📒 使用 React 和 Tailwind 创建阅读进度条

📒 React内部让人迷惑的性能优化策略

📒 Nest.js 基于 Express 但也不是完全基于

📒 如何使用代理模式优化代码

开发环境下打印日志:

const dev = process.env.NODE_ENV === 'development';
const createDevFn = (cb) => {
return (...args) => dev && cb(...args);
};

const log = createDevFn(console.log);
log("23333"); // "2333"

异常捕获:

class ExceptionsZone {
static handle(exception) {
console.log('Error:',exception.message, exception.stack);
}

static run(callback) {
try {
callback();
} catch (e) {
this.handle(e);
}
}
}

function createExceptionZone(target) {
return (...args) => {
let result;
ExceptionsZone.run(() => {
result = target(...args);
});
return result;
};
}

const request = () => new Promise((resolve) => setTimeout(resolve, 2000));
const requestWithHandler = createExceptionZone(request);
requestWithHandler().then(res => console.log("请求结果:", res));

如何用 Proxy 更优雅地处理异常

📒 VuePress 博客优化之开启 Algolia 全文搜索

📒 Git 分支操作流程

在 Git Flow 中,有两个长期存在且不会被删除的分支:masterdevelop

  • master 主要用于对外发布稳定的新版本,该分支时常保持着软件可以正常运行的状态,不允许开发者直接对 master 分支的代码进行修改和提交。当需要发布新版本时,将会与 master 分支进行合并,发布时将会附加版本编号的 Git 标签
  • develop 则用来存放我们最新开发的代码,这个分支是我们开发过程中代码中心分支,这个分支也不允许开发者直接进行修改和提交。程序员要以 develop 分支为起点新建 feature 分支,在 feature 分支中进行新功能的开发或者代码的修正

注意 develop 合并的时候,不要使用 fast-farward merge,建议加上 --no-ff 参数,这样在 master 上就会有合并记录

除了这两个永久分支,还有三个临时分支:feature brancheshotfixes 以及 release branches

  • feature branches 是特性分支,也叫功能分支。当你需要开发一个新的功能的时候,可以新建一个 feature-xxx 的分支,在里边开发新功能,开发完成后,将之并入 develop 分支中
  • hotfixes 就是用来修复 BUG 的。当我们的项目上线后,发现有 BUG 需要修复,那么就从 master 上拉一个名为 fixbug-xxx 的分支,然后进行 BUG 修复,修复完成后,再将代码合并到 masterdevelop 两个分支中,然后删除 hotfix 分支
  • release branches 是发版的时候拉的分支。当我们所有的功能做完之后,准备要将代码合并到 master 的时候,从 develop 上拉一个 release-xxx 分支出来,这个分支一般处理发版前的一些提交以及客户体验之后小 BUG 的修复(BUG 修复后也可以将之合并进 develop),不要在这个里边去开发功能,在预发布结束后,将该分支合并进 develop 以及 master,然后删除 release

image

📒 大厂动态规划面试汇总,重量级干货,彻夜整理

⭐️ 通过几行 JS 就可以读取电脑上的所有数据?

📒 百行代码带你实现通过872条Promise/A+用例的Promise

📒 颜值爆表!Redis 官方可视化工具来啦,功能真心强大!

📒 程序员开源月刊《HelloGitHub》第 71 期

C 项目

chibicc:迷你 C 编译器。虽然它只是一个玩具级的编译器,但是实现了大多数 C11 特性,而且能够成功编译几十万行的 C 语言项目,其中包括 Git、SQLite 等知名项目。而且它项目结构清晰、每次提交都是精心设计、代码容易理解,对编译器感兴趣的同学可以从第一个提交开始学习

https://github.com/rui314/chibicc

Go 项目

nali:离线查询 IP 地理信息和 CDN 服务提供商的命令行工具

https://github.com/zu1k/nali

revive:快速且易扩展的 Go 代码检查工具。它比 golint 更快、更灵活,深受广大 Go 开发者的喜爱

https://github.com/mgechev/revive

go-chart:Go 原生图表库。支持折线图、柱状图、饼图等

https://github.com/wcharczuk/go-chart

Java 项目

thingsboard:完全开源的物联网 IoT 平台。它使用行业的标准物联网协议 MQTT、CoAP 和 HTTP 连接设备,支持数据收集、处理、可视化和设备管理等功能。通过该项目可快速实现物联网平台搭建,从而成为众多大型企业的首选,行业覆盖电信、智慧城市、环境监测等

https://github.com/thingsboard/thingsboard

from-java-to-kotlin:展示 Java 和 Kotlin 语法上差别的项目。让有 Java 基础的程序员可以快速上手 Kotlin

https://github.com/MindorksOpenSource/from-java-to-kotlin

⭐️ ⭐️ 「React进阶」react-router v6 通关指南

· 12 min read
加菲猫

📒 一致性哈希算法解决的问题

  • 大多数网站都是 多节点部署,需要根据不同场景使用不同的 负载均衡策略
  • 最简单的算法就是使用 加权轮询,这种场景建立在每个节点存储的数据都是相同的前提下,访问任意一个节点都能得到结果
  • 当我们想提高系统的容量,就会将数据水平切分到不同的节点来存储,也就是将数据分布到了不同的节点。加权轮询算法是无法应对「分布式系统」的,因为分布式系统中,每个节点存储的数据是不同的,不是说任意访问一个节点都可以得到缓存结果的
  • 这种场景可以使用 哈希算法,对同一个关键字进行哈希计算,每次计算都是相同的值,这样就可以将某个 key 映射到一个节点了,可以满足分布式系统的负载均衡需求
  • 哈希算法最简单的做法就是进行取模运算,比如分布式系统中有 3 个节点,基于 hash(key) % 3 公式对数据进行了映射,如果计算后得到的值是 0,就说明该 key 需要去第一个节点获取
  • 但是哈希算法存在一个问题,如果 节点数量发生了变化,也就是在对系统做扩容或者缩容时,意味取模哈希函数中基数的变化,这样会导致 大部分映射关系改变,必须迁移改变了映射关系的数据,否则会出现查询不到数据的问题
  • 假设总数据条数为 M,哈希算法在面对节点数量变化时,最坏情况下所有数据都需要迁移,所以它的数据迁移规模是 O(M),这样数据的迁移成本太高了
  • 一致性哈希算法就很好地解决了分布式系统在扩容或者缩容时,发生过多的数据迁移的问题

微信一面:什么是一致性哈希?用在什么场景?解决了什么问题?

📒 前端项目 nginx 配置总结

有段时间没搞项目部署了,结果最近有同事在部署前端项目的时候,访问页面路由,响应都是 404,排查了半天,这里再总结一下。

前端单页应用路由分两种:哈希模式和历史模式。

哈希模式部署不会遇到啥问题,但是一般只用于本地调试,没人直接部署到生产环境。历史模式的路由跳转通过 pushStatereplaceState 实现,不会触发浏览器刷新页面,不会给服务器发送请求,且会触发 popState 事件,因此可以实现纯前端路由。

需要注意,使用历史模式的时候,还是有两种情况会导致浏览器发送请求给服务器:

  • 输入地址直接访问
  • 刷新页面

在这两种情况下,如果当前地址不是根路径,因为都是前端路由,服务器端根本不存在对应的文件,则会直接导致服务器直接响应 404。因此需要在服务器端进行配置:

server {
listen 80;
server_name www.bili98.com;
location / {
root /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;
}
}
tip

try_files 的作用就是按顺序检查文件是否存在,返回第一个找到的文件。$uri 是 nginx 提供的变量,指当前请求的 URI,不包括任何参数

当请求静态资源文件的时候,命中 $uri 规则;当请求页面路由的时候,命中 /index.html 规则

此外,在部署的时候不使用根路径,例如希望通过这样的路径去访问 /i/top.gif,如果直接修改 location 发现还会响应 404:

location /i/ {
root /data/w3;
try_files $uri $uri/ /index.html;
}

这是因为 root 是直接拼接 root + location,访问 /i/top.gif,实际会查找 /data/w3/i/top.gif 文件

这种情况下推荐使用 alias

location /i/ {
alias /data/w3;
try_files $uri $uri/ /index.html;
}

alias 是用 alias 替换 location 中的路径,访问 /i/top.gif,实际会查找 /data/w3/top.gif 文件

现在页面部署成功了,但是接口请求会出错,这是因为还没有对接口请求进行代理,下面配置一下:

location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

完整的 nginx 配置如下:

server {
listen 80;
server_name www.bili98.com;

location /ruoyi/ {
# 支持 /ruoyi 子路径访问
alias /root/workspace/ruoyi-ui/dist;

# history 模式重点就是这里
try_files $uri $uri/ /index.html;

# html 文件不可设置强缓存,设置协商缓存即可
add_header Cache-Control 'no-cache, must-revalidate, proxy-revalidate, max-age=0';
}

# 接口请求代理
location ^~ /prod-api/ {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.31.101:8080/;
}

location ~* \.(?:css(\.map)?|js(\.map)?|gif|svg|jfif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
# 静态资源设置一年强缓存
add_header Cache-Control 'public, max-age=31536000';
}
}

location 的匹配规则:

  • = 表示精确匹配。只有请求的url路径与后面的字符串完全相等时,才会命中。
  • ^~ 表示如果该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查找。
  • ~ 表示该规则是使用正则定义的,区分大小写。
  • ~* 表示该规则是使用正则定义的,不区分大小写。

nginx 的匹配优先顺序按照上面的顺序进行优先匹配,而且 只要某一个匹配命中直接退出,不再进行往下的匹配

剩下的普通匹配会按照 最长匹配长度优先级来匹配,就是谁匹配的越多就用谁。

前端到底用nginx来做啥

一份简单够用的 Nginx Location 配置讲解

📒 零基础理解 PostCSS 的主流程

📒 Jest + React Testing Library 单测总结

📒 使用lerna管理monorepo及发npm包实战教程

📒 从源码中来,到业务中去,React性能优化终极指南

📒 React核心设计原理--(React Fiber)异步执行调度

📒 如何在浏览器使用后端语言进行编程

你可能会认为这是关于使用 WebAssembly 在浏览器中运行 Python 之类的代码,但这并不是作者想分享的。作者提到的是通过服务端的 WebSocket 连接浏览器平台,由服务端处理 HTML 渲染更新到浏览器,这种方案日益流行,并且已经在 Elixir 和 Rails 全栈框架中支持。

https://github.com/readme/featured/server-side-languages-for-front-end

📒 正则表达式如何实现千分位分隔符

实现如下的需求:

  • 从后往前每三个数字前加一个逗号
  • 开头不能加逗号

这样看起来非常符合 (?=p) 的规律,p 可以表示每三个数字,要添加逗号所处的位置正好是 (?=p) 匹配出来的位置。

第一步,先尝试把最后一个逗号弄出来:

"300000000".replace(/(?=\d{3}$)/, ",")
// '300000,000'

第二步,把所有逗号都弄出来:

"300000000".replace(/(?=(\d{3})+$)/g, ",")
// ',300,000,000'

使用括号把一个 p 模式变成一个整体

第三步,去掉首位的逗号:

"300000000".replace(/(?!^)(?=(\d{3})+$)/g, ",")
// '300,000,000'

⭐️ 如何使用高阶函数编程提升代码的简洁性

📒 React Router v6 和私有路由 (也称作保护路由)

https://www.robinwieruch.de/react-router-private-routes/

📒 React Router v6 的身份验证简介

在一个简单的示例应用程序中,通过 React Router v6 实现身份验证的实用演练。

https://www.robinwieruch.de/react-router-authentication/

📒 Etsy 从 React 15.6 迁移到了 Preact (而不是 React 16)

在这篇 关于在 Etsy 更新 React 的文章中,对这个决定有一个完整的解释。但事实证明,拥有相同 API 的小型 React 替代品 Preact 是他们的正确选择。

https://twitter.com/sangster/status/1486382892326563845

📒 Promise 两点总结

不建议在 Promise 里面使用 try...catch,这样即使 Promise 内部报错,状态仍然是 fullfilled,会进入 then 方法回调,不会进入 catch 方法回调。

function request() {
return new Promise((resolve, reject) => {
try {
// ...
resolve("ok");
} catch(e) {
console.log(e);
}
})
}

request()
.then(res => {
console.log("请求结果:", res);
})
.catch(err => {
// 由于在 Promise 中使用了 try...catch
// 因此即使 Promise 内部报错,也不会被 catch 捕捉到
console.log(err);
})

Promise 内部的异常,老老实实往外抛就行,让 catch 方法来处理,符合单一职责原则

不建议在 async 函数中,既不使用 await,也不使用 return,这样就算内部的 Promise reject 也无法捕捉到:

async function handleFetchUser(userList) {
// 这里既没有使用 await,也没有使用 return
Promise.all(userList.map(u => request(u)));
}

handleFetchUser(userList)
.then(res => {
// 由于没有返回值,这里拿到的是 undefined
console.log(res);
})
.catch(err => {
// 即使 handleFetchUser 内部的 Promise reject
// async 函数返回的 Promise 仍然是 fullfilled
// 此时仍然会进入 then 方法回调,无法被 catch 捕捉到
console.log(err);
})

如果确实有这种需求,建议不要使用 async 函数,直接改用普通函数即可

📒 Rollup 配置

前端组件/库打包利器rollup使用与配置实战

📒 Docker 使用,Gitlab CI 实践

GitLab CI 从入门到实践

📒 总结一下 Babel 插件开发基本操作

https://github.com/BoBoooooo/AST-Learning

📒 记一次 Vue2 迁移 Vue3 的实践总结

· 8 min read
加菲猫

📒 浏览器技术架构的演进过程和背景

📒 从chromium源码来窥探浏览器的渲染

📒 从 0 开始手把手带你搭建一套规范的 Vue3.x 项目工程环境

📒 为什么 React 中要使用 immutable 数据流

PureComponentmemo 中会将新旧 props 进行 浅层比对,逻辑非常简单:

function shallowEqual (objA: mixed, objB: mixed): boolean {
// 下面的 is 相当于 === 的功能
// 只是对 + 0 和 - 0,以及 NaN 和 NaN 的情况进行了特殊处理
// 第一关:基础数据类型直接比较出结果
if (is (objA, objB)) {
return true;
}
// 第二关:只要有一个不是对象数据类型就返回 false
if (
typeof objA !== 'object' ||
objA === null ||
typeof objB !== 'object' ||
objB === null
) {
return false;
}

// 第三关:在这里已经可以保证两个都是对象数据类型,比较两者的属性数量
const keysA = Object.keys (objA);
const keysB = Object.keys (objB);

if (keysA.length !== keysB.length) {
return false;
}

// 第四关:比较两者的属性是否相等,值是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call (objB, keysA [i]) ||
!is (objA [keysA [i]], objB [keysA [i]])
) {
return false;
}
}

return true;
}

但浅层比较相当于只是比较第一层,还是会存在一些问题,如果修改深层嵌套的对象,浅层比较会认为相等。

为解决这个问题,可以手动在 shouldComponentUpdate 钩子中实现深层比对,但缺点就是浪费性能。最好的解决方案就是使用 immutable 数据流。immutable 对象内部采用的是多叉树的结构,只要有节点被修改,那么该节点和与之相关的所有父节点会直接拷贝到一个新的对象中(创建一个新的引用)。也就是说,修改任意一个子节点,改动都会冒泡到根节点,这样浅比较就能感知到数据改变了。

React Hooks 与 Immutable 数据流实战

📒 操作 JavaScript 的 AST

acornEspree@babel/parser 三种解析器用法说明

操作 JavaScript 的 AST

📒 React fiber 架构浅析

在 React 16 之前,vdom 以递归的方式进行 patch 和渲染,一个 vdom 节点可以表示如下:

class VNode {
type: string;
props: Record<string, any>;
children: VNode[];
}

在 React 16 之后引入了 fiber 架构,vdom 不再直接渲染,而是先转成 fiber,一个 fiber 节点可以表示如下:

class FiberNode {
type: string;
props: Record<string, any>;
dom: HTMLElement; // 提前创建 dom 节点
child?: FiberNode;
sibling?: FiberNode;
return?: FiberNode;
effectTag: string; // 做 diff,确定是增、删还是改
}

在 fiber 架构中,将 vdom 树结构转成了链表,每个 fiber 节点的 child 关联第一个子节点,然后通过 sibling 串联同一层级的节点,所有的节点可以 return 到父节点:

image

先把 vdom 转 fiber,也就是 reconcile 的过程,因为 fiber 是链表,就可以打断,用 schedule 来空闲时调度(requestIdleCallback)就行,最后全部转完之后,再一次性 render,这个过程叫做 commit。

schedule 就是通过空闲调度每个 fiber 节点的 reconcile(vdom 转 fiber),全部 reconcile 完了就执行 commit。

reconcile 除了将 vdom 转 fiber 外,还会做两件事:一个是 提前创建对应的 dom 节点,另一个是 做 diff,确定是增、删还是改,通过 schdule 的调度,最终把整个 vdom 树转成了 fiber 链表。

commit 就是对 dom 的增删改,把 reconcile 产生的 fiber 链表一次性添加到 dom 中,因为 dom 节点都提前创建好了、是增是删还是改也都知道了,所以这个阶段很快。每个 fiber 节点的渲染就是按照 child、sibling 的顺序以此插入到 dom 中,这里每个 fiber 节点都要往上找它的父节点(之前保存的 return 指针),因为我们只是新增,那么只需要 appendChild 就行。

手写简易版 React 来彻底搞懂 fiber 架构

📒 Chrome 99新特性:@layers 规则浅析

📒 WebVM.io:基于 Web 的“无服务端”虚拟 Linux 环境

浏览器端运行的 Linux 环境,基于 JavaScript 和 WebAssembly 的 CheerpX x86 虚拟化引擎驱动。虽然它不是一个完全基于 JavaScript 的项目,但它很好地展示了 Web 技术的发展程度。它已经内置了 Node v10.24.0,但要注意它首次加载速度可能会有点慢。

https://webvm.io/

这里有一篇关于它如何工作的文章。

https://leaningtech.com/webvm-server-less-x86-virtual-machines-in-the-browser/

📒 如何使用 Vue 3、Vite、Pinia 开发应用程序

非常完善的开发、测试、部署指南。

https://labs.pineview.io/learn-how-to-build-test-and-deploy-a-single-page-app-with-vue-3-vite-and-pinia/

📒 用代码分割来提高打包 JavaScript 时的性能

https://www.smashingmagazine.com/2022/02/javascript-bundle-performance-code-splitting/

📒 提升 VSCode 扩展插件的运行速度

插件开发者必读

image

https://jason-williams.co.uk/speeding-up-vscode-extensions-in-2022

📒 Babel 发布 v7.17.0

该版本对 装饰器提案 的支持已稳定,还对装饰器的解析和转换进行了支持。

https://babeljs.io/blog/2022/02/02/7.17.0

📒 使用 Streams 模块构建高性能的 Node 应用

https://blog.appsignal.com/2022/02/02/use-streams-to-build-high-performing-nodejs-applications.html

📒 Node.js 新增 Fetch API

对 Fetch API (一般是浏览器端用来获取资源)的支持已经合并到 Node.js,将在提供 ‑‑experimental‑fetch 标志后可以开启,Node v18 或者更高版本会默认启用。

https://fusebit.io/blog/node-fetch/

⭐️ 来自未来,2022 年的前端人都在做什么?

⭐️ 最全的前端性能定位总结

📒 接近天花板的TS类型体操,看懂你就能玩转TS了

📒 2022年必会Vue3.0学习 (强烈建议)

📒 如何利用 SCSS 实现一键换肤

📒 手写 JS 引擎来解释一道赋值面试题

📒 10 分钟讲述 React 的故事

https://www.youtube.com/watch?v=Wm_xI7KntDs

📒 2022 年值得关注的 React 趋势

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

📒 React 18 中的自动批处理(Automatic Batching)

https://blog.bitsrc.io/automatic-batching-in-react-18-what-you-should-know-d50141dc096e?gi=aa52794e9a07

📒 React Mentions:在 Textarea 中提及某人

· 8 min read
加菲猫

📒 很多人上来就删除的 package.json,还有这么多你不知道的

📒 React hooks 使用注意事项

惰性初始化 State:

// React hook 会在每次组件重新渲染的时候调用
const [count, setCount] = React.useState(ExpensiveCal());

// 如果 useState 的初始值需要通过复杂计算获取,可以传入一个函数惰性初始化
// 这个函数只会在组件挂载的时候执行一次,后续更新都不会执行
const [count, setCount] = React.useState(() => ExpensiveCal());

不需要视图渲染的变量,不要用 useState

const App: React.FC<{}> = () => {
// count 与视图渲染无关
// 如果使用 useState,每次 count 变化都会触发组件重新渲染
const [count, setCount] = React.useState(0);
// 这里推荐使用 useRef
const count = React.useRef(0);

const handleClick = () => setCount(c => c + 1);

return (
<button onClick={handleClick}>Counter</button>
)
}

函数式更新:

const [count, setCount] = React.useState(0);

// 下面这样虽然调用了两次
// 但由于一次渲染中获取的 count 都是闭包中老的值
// 因此最终 count 还是 1
setCount(count + 1);
setCount(count + 1);

// 如果要获取到上一次更新的值,可以使用函数式更新
// 最终 count 为 2
setCount(c => c + 1);
setCount(c => c + 1);

useEffect 清除副作用:

React.useEffect(() => {
// ...
return () => {
// useEffect 的回调函数中可以返回一个函数
// 这个函数会在组件卸载的时候执行
// 用于清理各种事件监听器、定时器等
}
}, []);

React.useCallback 需要配合 React.memo 使用,其中任意一个单独使用是没用的。

tip

React.useCallback 使用的一个场景是:

  • 一个父组件中有一个复杂的自定义组件,需要传入事件处理函数作为 prop,为避免父组件渲染导致该子组件重新渲染,使用 React.memo 包裹一下;
  • 包裹之后发现父组件重新渲染,该子组件还是会重新渲染,这是因为事件处理函数在父组件每次渲染的时候都重新生成,因而传入子组件的 prop 变化导致 React.memo 失效;
  • 将事件处理函数用 React.useCallback 包裹一下,对事件处理函数进行缓存,避免每次父组件渲染都重新生成,这样父组件重新渲染就不会导致子组件重新渲染;
  • 需要注意 React.useCallback 缓存本身也是有性能开销的,因此只有在子组件渲染比较昂贵的时候,才进行缓存处理;

📒 Golang 中的包管理机制

Golang 中的包管理使用 go.mod 文件,可以使用下面的命令在项目根目录初始化一个 go.mod

# 初始化一个 v0 或者 v1 的包
$ go mod init example.com/m
# 初始化指定版本的包
$ go mod init example.com/m/v2

安装依赖:

$ go get -u github.com/gin-gonic/gin

-u 安装全局变量类似 npm i -g cobra

如果直接下载请求超时,可以设置镜像源:

$ go env -w GO111MODULE=on
$ go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct

类似 npm config set registry

安装之后就可以看到 go.mod 里面多了些东西:

module github.com/Jiacheng787/goexample

go 1.17

require (
github.com/gin-gonic/gin v1.7.7
)

下载项目依赖:

$ go get ./...

三分钟掌握Go mod常用与高级操作

📒 如何解决 CSS 兼容性问题

对于 JS 的兼容性,我们可以使用 Babel 进行语法转换以及对 API 进行 polyfill。那么对于 CSS 的兼容性如何适配呢?可以使用 PostCSS,最完善的 CSS 工程化解决方案:

  • autoprefixer:根据 Can I Use 的数据给 CSS 属性添加厂商前缀
  • postcss-preset-env:允许使用一些提案阶段的特性

此外还提供各种插件:

  • postcss-modules:CSS 模块化
  • postcss-initial:重置默认样式
  • sugarss:支持缩进语法编写 CSS 样式

https://github.com/postcss/postcss

📒 How To Process Images in Node.js With Sharp

📒 字节跳动开源项目

📒 前端项目 babel 配置

编译一个前端项目,一般需要安装如下依赖:

  • @babel/core:核心库
  • babel-loader:配合 Webpack 打包场景使用
  • @babel/preset-env:语法转换的预设插件集,同时支持 api 兼容
  • @babel/preset-react:编译 React 的 JSX 语法
  • @babel/preset-typescript:可选,编译 TypeScript 语法
tip

@babel/core 是核心库,里面包含:

  • @babel/parser:一个 ast 解析器,之前叫 Babylon,基于 acorn 魔改而来,负责解析生成 ast
  • @babel/traverse:负责通过访问者模式遍历并操作 ast 节点
  • @babel/generator:负责根据 ast 生成代码

babel-loader 用于配合 Webpack 打包场景使用,如果想通过命令行的方式使用,则需要安装 @babel/cli

@babel/preset-env 的 api 兼容是通过引入 core-js polyfill 实现的。core-js 引入有多种方式,可以配置 entry,即在入口文件处根据根据 browserslist 配置需要适配的目标环境全量引入 polyfill,也可以配置 usage,根据 browserslist 配置和实际用的 api 按需引入 polyfill。@babel/preset-env 是通过全局污染的形式引入的,一般在前端项目中没问题,但是作为第三方库就不合适了,这时候需要使用 @babel/plugin-transform-runtime 通过沙箱机制引入 polyfill,这种引入方式有个缺点,无法根据 browserslist 配置动态调整引入的 polyfill。

@babel/preset-typescript 实际上就是简单删除掉类型注解。因为 Babel 是单文件处理,不可能进行类型检查,类型检查可以交给 VSCode 插件,或者 ForkTsCheckerWebpackPlugin 单独起一个进程进行类型检查,这时候 tsc 的作用就是类型检查器,需要配置 "noEmit": true

📒 写文章集合

  • Redux 在完善下,增加 UI-binding
  • 深入源码分析 Koa 中间件与洋葱圈模型
  • 前端项目的 env 文件是如何被加载的
  • Webpack 打包的图片和字体的哈希是如何生成的 - file-loader 源码分析

· 8 min read
加菲猫

📒 推荐使用 stylus

推荐使用 stylus,所有的 {}: 以及 ; 都是可省略的:

.page
padding-bottom 2rem
display block

.content-lock
display none
text-align center
padding 2rem
font-size 1em

这就类似为什么建议使用 yaml 替代 json,在 yaml 中不需要引号,简单省事

📒 页面性能优化技巧

分析代码执行耗时可以通过 火焰图,分析内存占用情况可以通过 堆快照

⭐️ react-use - 一个 React Hooks 库

📒 Next.js 提供的渲染方式

  • SSR: Server-side rendering (服务端渲染)
  • SSG: Static-site generation (静态站点生成)
  • CSR: Client-side rendering (客户端渲染)
  • Dynamic routing (动态路由)
  • ISR: Incremental Static Regeneration (增量静态再生)
tip

CSR、SSR、SSG 的区别?

CSR 是在用户浏览器端调接口请求数据进行渲染;SSR 是在用户请求页面的时候,服务器端请求数据并进行渲染;SSG 是直接在构建阶段就进行渲染,一般用于文档网站。

📒 Node 案发现场揭秘 —— 未定义 “window” 对象引发的 SSR 内存泄露

📒 从头开始,彻底理解服务端渲染原理(8千字汇总长文)

📒 【7000字】一晚上爆肝浏览器从输入到渲染完毕原理

📒 爆肝三天,学习Scss-看这篇就够了

⭐️ 编译技术在前端的实践(二)—— Antlr 及其应用

⭐️ 编译技术在前端的实践(一)—— 编译原理基础

📒 如何实从零实现 husky

看下如何做 测试驱动开发

从零实现husky

📒 如何让一个构造函数只能用 new 调用

使用 ES6 class 会检查是否通过 new 调用,而普通构造函数不会检查是否通过 new 调用,这种情况下需要手动进行判断,通常都会这样做:

function MyClass() {
if (!(this instanceof MyClass)) {
throw new Error("MyClass must call with new");
}
// ...
}

这样的话,如果不通过 new 调用,就会抛出异常。其实更好的方案是进行兼容处理,即不使用 new 调用,自动改用 new 调用:

function MyClass() {
if (!(this instanceof MyClass)) {
// 如果没有使用 `new` 调用,自动改用 `new` 调用
// 通过 `return` 中断函数执行,并返回创建的实例
return new MyClass();
}
// ...
}

📒 为什么 React Hook 底层使用链表而不是数组

React Hooks 核心实现

深入浅出 React

React 技术揭秘

📒 React 17 架构

图解 React 原理系列

React16架构

📒 数组的 flatMap 方法

数组的 [].map() 可以实现一对一的映射,映射后的数组长度与原数组相同。有时候需要过滤掉一些元素,或者实现一对多的映射,这时候只用 map 就无法实现了。这种情况下就可以使用 flatMap

// 需要过滤掉 0,并且使其余各元素的值翻倍
const numbers = [0, 3, 6];

// 常规方法是 map 和 filter 搭配
const doubled = numbers
.filter(n => n !== 0)
.map(n => n * 2)

// 使用 flatMap 实现
const doubled = numbers.flatMap(number => {
return number === 0 ? [] : [2 * number];
})

此外还可以实现一对多的映射:

const numbers = [1, 4];
const trippled = numbers.flatMap(number => {
return [number, 2 * number, 3 * number];
})
console.log(trippled); // [1, 2, 3, 4, 8, 12]
tip

flatMap 实际上是先 mapflat,理解了这一点就能掌握了

📒 如何用 TypeScript 配置一个 Node 项目

📒 Remix vs Next.js

📒 你应该知道的三个 React 组件设计模式

📒 V8 Promise源码全面解读,其实你对Promise一无所知

⭐️ 60+ 实用 React 工具库,助力你高效开发!

⭐️ 如何编写更好的 JSX 语句

查看详情

列表不为空的时候进行渲染:

// 注意这种写法有 bug
// 如果 data 数组为空,则会直接渲染 `0` 到页面上
{data.length && <div>{data.map((d) => d)}</div>}

// 使用 && 的时候需要手动转换布尔值
data.length > 0 && jsx
!!data.length && jsx
Boolean(data.length) && jsx

不要使用 props 传递的 React 元素作为判断条件:

// 这样的判断不准确
// props.children 可能是一个空数组 []
// 使用 children.length 也不严谨,因为 children 也可能是单个元素
// 使用 React.Children.count(props.children) 支持单个和多个 children
// 但是对于存在多个无效节点,例如 false 无法准确判断
// 使用 React.Children.toArray(props.children) 可以删除无效节点
// 但是对于一个空片段,例如 <></> 又会被识别为有效的元素
// 所以为了避免出错,建议不要这样判断
const Wrap = (props) => {
if (!props.children) return null;
return <div>{props.children}</div>
};

重新挂载还是更新:

// 使用三元运算符分支编写的 JSX 看上去就像完全独立的代码
{hasItem ? <Item id={1} /> : <Item id={2} />}

// 但实际上 hasItem 切换时,React 仍然会保留挂载的实例,然后更新 props
// 因此上面的代码实际上等价于下面这样
<Item id={hasItem ? 1 : 2} />

// 一般来讲不会有什么问题,但是对于非受控组件,就可能导致 bug
// 例如 mode 属性变化,会发现之前输入的信息还在
{mode === 'name'
? <input placeholder="name" />
: <input placeholder="phone" />}

// 由于 React 会尽可能复用组件实例
// 因此我们可以传递 key,告诉 React 这是两个完全不一样的元素,让 React 强制重新渲染
{mode === 'name'
? <input placeholder="name" key="name" />
: <input placeholder="phone" key="phone" />}

// 或者使用 && 替代三元运算符
{mode === 'name' && < input placeholder = "name" /> }
{mode !== 'name' && < input placeholder = "phone" /> }

// 相反,如果在同一个元素上的逻辑条件不太一样
// 可以试着将条件拆分为两个单独的 JSX 提高可读性
<Button
aria-busy={loading}
onClick={loading ? null : submit}
>
{loading ? <Spinner /> : 'submit'}
</Button>

// 可以改为下面这样
{loading
? <Button aria-busy><Spinner /></Button>
: <Button onClick={submit}>submit</Button>}

// 或者使用 &&
{loading && <Button key="submit" aria-busy><Spinner /></Button>}
{!loading && <Button key="submit" onClick={submit}>submit</Button>}

写好 JSX 条件语句的几个建议

📒 Node.js 十大设计缺陷 - Ryan Dahl - JSConf EU

📒 为什么说 WebAssembly 是 Web 的未来?

📒 浅析TypeScript Compiler 原理

📒 TypeScript 4.6 beta 发布:递归类型检查增强、参数的控制流分析支持、索引访问的类型推导

· 7 min read
加菲猫

📒 Golang 如何根据指针访问对应的值

原始类型需要手动使用 * 操作符,复杂对象会自动解除指针引用:

num := &42
fmt.Println(num) // 打印的是内存地址
fmt.Println(*num) // 42

ms := &myStruct{foo: 42}
(*ms).foo = 17
fmt.Println((*ms).foo) // 17
// 对于复杂对象,直接操作就行
ms.foo = 17
fmt.Println(ms.foo) // 17

📒 Golang 创建对象指针的三种方式

Golang 中所有的赋值操作都是 copy,例如原始类型、arraystruct,有两种例外:mapslice,它们具有内部指针,在赋值的时候传递指针类型。

// 第一种:对已有的值类型使用 `&` 操作符
ms := myStruct{foo: 42}
p := &ms

// 第二种:在初始化的时候使用 `&` 操作符
p := &myStruct{foo: 42}

// 第三种:使用 `new` 关键字,这种方法不能在初始化的时候进行赋值
var ms *myStruct = new(myStruct)

📒 如何渲染虚拟 DOM

所谓虚拟 DOM 其实就是一棵多叉树,可以使用下面的结构表示:

class VDOM {
type: ElementTagName;
props: ElementProps;
children: VDOM[];
}

渲染虚拟 DOM,很明显要用递归,对不同的类型做不同的处理:

  • 如果是文本类型,就要用 document.createTextNode 创建文本节点;
  • 如果是元素类型,就要用 document.createElement 创建元素节点,元素节点还有属性要处理,并且要递归渲染子节点;

实现 render 函数如下:

const render = (vdom, parent = null) => {
const mount = (el) => {
if (!parent) return el;
// 如有父节点则挂载到父节点,组装为 DOM 树
return parent.appendChild(el);
}
if (isTextVdom(vdom)) {
// 创建文本节点
return mount(document.createTextNode(vdom));
} else if (isElementVdom(vdom)) {
// 创建元素节点
const dom = mount(document.createElement(vdom.type));
// 递归渲染子节点,这里使用深度优先遍历
for (const child of vdom.children) {
render(child, dom);
}
// 给元素添加属性
for (const prop in vdom.props) {
setAttribute(dom, prop, vdom.props[prop]);
}
return dom;
}
};

如何判断文本节点:

function isTextVdom(vdom) {
return typeof vdom == 'string' || typeof vdom == 'number';
}

如何判断元素节点:

function isElementVdom(vdom) {
return typeof vdom == 'object' && typeof vdom.type == 'string';
}

如何处理样式、事件、属性:

const setAttribute = (dom, key, value) => {
if (typeof value == 'function' && key.startsWith('on')) {
// 事件处理,使用 `addEventListener` 设置
const eventType = key.slice(2).toLowerCase();
dom.addEventListener(eventType, value);
} else if (key == 'style' && typeof value == 'object') {
// 样式处理,合并样式
Object.assign(dom.style, value);
} else if (typeof value != 'object' && typeof value != 'function') {
// 属性处理,使用 `setAttribute` 设置
dom.setAttribute(key, value);
}
}

📒 能用js实现的最终用js实现,Shell脚本也不例外

📒 heapify:最快的 JavaScript 优先级队列库

📒 easyjson:Golang 中的序列化库,比 encoding/json 快 4-5 倍

📒 fast-json-stringify:比 JSON.stringify 快两倍

📒 六千字详解!vue3 响应式是如何实现的?

📒 Nodejs 如何将图片转为 base64

使用 Buffer 对象:

import fs from "node:fs";
import path from "node:path";

const raw = fs.readFileSync(path.join(__dirname, './2333.png'), 'binary');
const buf = Buffer.from(raw, 'binary');
const string = buf.toString('base64');

同理可以将 base64 转回图片:

const raw =  Buffer.from(string, 'base64').toString('binary');

📒 Nodejs 如何实现图片处理

推荐使用 sharp 这个库,可以实现图片压缩,转 JPEG、PNG、WebP 等格式:

https://github.com/lovell/sharp

📒 如何打印 26 个字母的字符串

一行代码搞定:

String.fromCharCode(...Array.from({ length: 26 }, (_, index) => 97 + index));
// 'abcdefghijklmnopqrstuvwxyz'

📒 如何用 Map 实现 Set

关于 Map 和 Set 是两个抽象数据结构,Map 存储一个键值对集合,其中键不重复,Set 存储一个不重复的元素集合。本质上 Set 可以视为一种特殊的 Map,Set 其实就是 Map 中的键:

class NewSet<T extends unknown> {
private collection: Map<T, undefined>;

constructor(iterable: T[] = []) {
this.collection = new Map(
iterable.map(it => [it, undefined])
);
}
}

📒 方法重载与参数默认值

为了支持可变参数,在 Java 中通过 方法重载 实现,通过定义多个方法签名,根据实际调用传递的参数去匹配签名。在 TypeScript 中也提供了方法重载特性,但在开发中很少用到,一般都通过 参数默认值 实现可变参数:

type NewSet<T> = (iterable: T[] = []) => void

注意使用参数默认值之后,TS 会自动将这个参数推导为可变参数,例如上面这个会推导为 NewSet<T>(iterable?: T[]): void

📒 项目常用工具库

  • dayjs:与 moment 的 API 设计保持一样,但体积仅有 2KB;
  • qs:解析 URL query 参数的库;
  • js-cookie:简单、轻量的处理 cookie 的库;
  • flv.js:bilibili 开源的 HTML5 flash 播放器,使浏览器在不借助 flash 插件的情况下可以播放 flv;
  • vConsole:一个轻量、可拓展、针对手机网页的前端开发者调试面板;
  • animate.css:一个跨浏览器的 css3 动画库,内置了很多典型的 css3 动画,兼容性好,使用方便;
  • lodash:一个一致性、模块化、高性能的 JavaScript 实用工具库;

⭐️ elf: 使用 RxJs 的响应式状态管理

📒 如何防止 CSS 样式污染

  • 使用命名约定
  • CSS Modules
  • CSS in JS

其中命名约定最流行的方式是 BEM 101。它代表了 BlockElementModifier 方法。

[block]__[element]--[modifier]
/* Example */
.menu__link--blue {
...
}

📒 现代配置指南——YAML 比 JSON 高级在哪?

📒 前端架构师神技,三招统一团队代码风格

📒 前端架构师的 git 功力,你有几成火候?

- - + + \ No newline at end of file diff --git a/2022/tags/yarn-2/index.html b/2022/tags/yarn-2/index.html index 3db6c25de9..a3562593cc 100644 --- a/2022/tags/yarn-2/index.html +++ b/2022/tags/yarn-2/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "Yarn2"

View All Tags

· 11 min read
加菲猫

📒 clsx:classnames 的替代方案

📒 TS 类型系统实现大数相加

一位数相加,总共只有 100 种情况,为了提高性能,可以选择 打表

用 TS 类型系统实现大数加法

📒 盘点那些让开发效率翻倍的React Hook

⭐️ ESM 与 CJS 的 Interop 来世今生

📒 浏览器渲染中的合成层与 will-change

合成就是将页面的各个部分分成多个层、单独 光栅化(浏览器根据文档的结构、每个元素的样式、页面的几何形状和绘制顺序转换为屏幕上的像素的过程)它们并在合成器线程中合成为一个页面的技术。

一般来说,拥有一些特定属性的渲染层,会被浏览器自动提升为合成层。合成层拥有单独的图层(GraphicsLayer),和其他图层之间无不影响。而其它不是合成层的渲染层,则和第一个拥有图层的父层共用一个,也就是普通文档流中的内容,我们看一些常见的提升为合成层的属性。

  • 设置 transform: translateZ(0)
  • backface-visibility: hidden 指定当元素背面朝向观察者时是否可见
  • will-change 该属性告诉浏览器该元素会有哪些变化,这样浏览器可以提前做好对应的优化准备工作
  • videocanvasiframe 等元素
tip

使用 transform 和 opacity 来实现动画

在开发中经常会实现一些动画,有时候我们可能会选择改变 top/left 去实现,那么这个节点的渲染会发生在普通文档流中。而使用 transformopacity 实现动画能够让节点被放置到一个独立合成层中进行渲染绘制,动画不会影响其他图层,并且 GPU 渲染相比 CPU 能够更快,这会让你的动画变的更加流畅。

按照下面的操作打开查看帧率的界面:

Preview

通过 transform 来实现动画,页面的 fps 能够稳定在 60 左右,而通过 left 来实现存在波动,fps 大概稳定在 30 左右,这会影响你的用户体验指标。

浏览器渲染魔法之合成层

⭐️ 前端 Code Review 不完全指北(万字长文,50+case)

📒 Node.js 相关

Node.js 适合 IO 密集型任务,例如处理网络请求、文件 IO 等等;

Node.js 不适合 CPU 密集型任务,例如 MD5、SHA 加密算法等;

📒 升级Yarn 2,摆脱node_modules

📒 什么是 inode

inode (index nodes) 是操作系统中重要的概念,是一种文件数据结构,用于存储有关除名称和数据之外的任何 Linux 文件的信息。

软链接&硬链接在前端中的应用

📒 gitlab上代码回滚把自己坑了后, 陷入思考🤔"bug是谁"?

⭐️ 提交代码的时候使用 rebase

一般提交代码都是先本地 commit,然后执行 git pull 将仓库的代码拉取到本地 merge,然后再 push 到仓库。这样会导致时间线很不干净,提交记录中混杂很多 merge 分支的无用记录。

在拉取仓库代码的时候,我们可以不进行合并,而是使用 rebase(变基),直接把我们原先的基础变掉,变成以别人修改过后的新代码为基础,把我们的修改在这个新的基础之上重新进行。使用变基之后,就可以使我们的时间线变得非常干净。

两条命令让你的git自动变基

📒 如何使用 VS Code 任务

开发经典模式:从主仓库 fork => 从个人仓库提 Merge Request

【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

📒 如何分析每行代码的执行耗时

首先使用 Performance 工具分析页面性能。

在分析性能的时候,为排除插件的影响,需要启用无痕模式

在火焰图中找到长任务,点击顶部 Task,点击 Button-Up,这时候可以看到根据耗时列出的调用栈:

Preview

找到那个执行耗时最长的,然后点击右侧源码地址,可以跳到 source 对应的源码:

Preview

📒 关于数组遍历方法的比较

  • 相比 forEachmap 性能略差一些,因为需要创建新数组
  • 数据量大的时候,手写 for 循环性能明显优于 forEachmap
    • 倒序 for 循环性能最好,因为只访问了一次 array.length
      // 正序
      for (let i=0; i<arr.length; i++)
      // 倒序
      for (let i=arr.length-1; i>=0; i--)
    • 如果想提升正序遍历性能,可以这样写
      for (let i=0, len=arr.length-1; i<len; i++)
    • 无论遍历数组还是对象,都尽量少用 for...in 循环,性能比较烂
  • 无论 new Array() 还是 Array.from() 性能都不如写一个 for 循环往空数组里面 push
  • 另外不推荐使用 [].fill() 方法,TS 无法推导类型,建议使用 Array.from({length: 10}, () => 1) 的方式

📒 如何指定一个项目所需的 node 最小版本

指定一个项目所需的 node 最小版本,这属于一个项目的质量工程。我们可以在 package.json 中的 engines 字段中指定 Node 版本号:

{
"engines": {
"node": ">=14.0.0"
}
}

如果本地运行的 Node 版本不匹配,yarn 将会报错,npm 则会打印警告信息。engines 字段不仅可以用于前端项目,也可用于第三方库。

tip

如果项目的 package.json 中没用 engines 字段,可查看 Dockerfile 中 node 镜像确定项目所需的 node 版本号。

📒 Vue SFC playground

https://sfc.vuejs.org/

研究下插槽的实现

📒 写一个 Vue3 自定义指令

Vue 自定义指令的范式:

const lazyPlugin = {
install (app, options) {
app.directive('lazy', {
// install 方法的第一个参数可以拿到 Vue 构造器
// 这块可以参考 Vue.use 源码
})
}
}

export default lazyPlugin

在项目中使用如下:

import { createApp } from 'vue'
import App from './App.vue'
import lazyPlugin from 'vue3-lazy'

createApp(App).use(lazyPlugin, {
// 添加一些配置参数
})

手把手带你写一个 Vue3 的自定义指令

📒 揭秘 Vue.js 九个性能优化技巧

📒 2020最新React Hooks+TS项目最佳实践

📒 「react进阶」一文吃透react-hooks原理

📒 useCallback 使用场景

在 React 中经常需要将父组件定义的方法传入子组件(即事件钩子,也可以看作子组件状态提升到父组件),例如:

const Parent = () => {
const handleSearch = (val) => {
console.log("搜索结果:", val);
}

return <Input onSearch={handleSearch} />
}

const Input = React.memo(({ onSearch }) => {
return (
<form onSubmit={(e) => {
const submitData = Array.from(
e.target.childNodes,
item => ({ name: item.name, value: item.value })
);
onSearch(submitData);
}}>
<input type="text" name="search" />
</form>
)
})

在上面的代码中,如果父组件重新渲染,则会导致 handleSearch 方法重新生成,进而导致 onSearch prop 改变,即使子组件用了 React.memo,子组件还是会重新渲染。在这种情况下,就可以使用 useCallback 缓存函数,避免函数重复生成,进而避免子组件重复渲染,提高性能:

const Parent = () => {
const handleSearch = React.useCallback((val) => {
console.log("搜索结果:", val);
}, []);

return <Input onSearch={handleSearch} />
}
tip

注意 useCallback 需要和 React.memo 一起使用。如果不用 React.memo,只要父组件重新渲染,即使 prop 没有改变,子组件还是会重新渲染

React Hooks 详解 【近 1W 字】+ 项目实战

📒 老板:你来弄一个团队代码规范!?

📒 前端工程化系列文章

https://shanyue.tech/frontend-engineering/npm-install.html#%E4%BD%BF%E7%94%A8-npm-ci-%E6%9B%BF%E4%BB%A3-npm-i

📒 ES 新语法 Array.prototype.groupBy

一个专门用来做数据分组的提案 Array.prototype.groupBy 已经到达 Stage 3

const array = [1, 2, 3, 4, 5];

// groupBy groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
array.groupBy((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd';
});

// => { odd: [1, 3, 5], even: [2, 4] }

https://github.com/tc39/proposal-array-grouping

📒 基于 Next.js 的 SSR/SSG 方案了解一下?

- - + + \ No newline at end of file diff --git "a/2022/tags/\345\211\215\347\253\257\346\212\200\346\234\257\346\226\271\345\220\221/index.html" "b/2022/tags/\345\211\215\347\253\257\346\212\200\346\234\257\346\226\271\345\220\221/index.html" index cf4a462383..b28547b919 100644 --- "a/2022/tags/\345\211\215\347\253\257\346\212\200\346\234\257\346\226\271\345\220\221/index.html" +++ "b/2022/tags/\345\211\215\347\253\257\346\212\200\346\234\257\346\226\271\345\220\221/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "前端技术方向"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/tags/\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267/index.html" "b/2022/tags/\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267/index.html" index eebb5b10e0..5e4eb5eb98 100644 --- "a/2022/tags/\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267/index.html" +++ "b/2022/tags/\345\221\275\344\273\244\350\241\214\345\267\245\345\205\267/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "命令行工具"

View All Tags

· 9 min read
加菲猫

📒 实现一个 WebAssembily 版本的 Python 解释器

  • wasm 可以把代码编译出来,但是能否执行
  • 如果 Python 代码涉及系统调用,例如代码中经常需要进行文件 IO,这种情况下 wasm 能否实现

https://github.com/pyodide/pyodide

📒 Webpack5 配置了 devServer.hot = true 是否会自动配置 HotModuleReplacementPlugin

📒 看下 axios 源码,响应拦截中第一个回调 reject 能否进入第二个回调

📒 webpack-dev-server 如何配置代理

查看详情

在 CRA 搭建的项目中,我们知道可以在 src/setupProxy.js 文件中写入代理配置:

const proxy = require('http-proxy-middleware');

module.exports = function(app) {
app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)
}

那么手动搭建的项目该如何配置代理呢?我们看一下 CRA 源码:

// react-scripts/config/paths.js:87

module.exports = {
// ...
proxySetup: resolveApp('src/setupProxy.js'),
// ...
}

然后去找哪里用到了 proxySetup

// react-scripts/config/webpackDevServer.config.js:112

onBeforeSetupMiddleware(devServer) {
// Keep `evalSourceMapMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
devServer.app.use(evalSourceMapMiddleware(devServer));

if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(devServer.app);
}
},

看了下上面的配置,说明应该是这么用的:

const compiler = webpack(config);
const devServer = new WebpackDevServer(options, compiler);

devServer.app.use(
proxy(
'/course',
{
target: 'https://ke.study.163.com',
changeOrigin: true,
},
),
)

📒 不优雅的 React Hooks

📒 为什么可以用函数模拟一个模块

在一个模块中,有一些属性和方法是私有的,另外一些是对外暴露的:

// main.js
let foo = 1;
let bar = 2;

export const getFoo = () => foo;
export const getBar = () => bar;
const defaultExport = () => foo + bar;
export default defaultExport;

// index.js
import main, { getFoo, getBar } from "./main";

这种行为就可以通过函数模拟出来,其中私有变量、方法以闭包的形式实现,这样只有模块内部才能访问:

const main = (function() {
let foo = 1;
let bar = 2;
const getFoo = () => foo;
const getBar = () => bar;
const defaultExport = () => foo + bar;

return {
getFoo,
getBar,
default: defaultExport
}
})();
tip

可以看到给默认导出加了一个 deafult 属性。

另外推荐看看 browserify 这个库,如何在浏览器端实现 CommonJS 模块机制:

https://browserify.org/

📒 Webpack 中 loader 处理流程

有点像责任链模式,上一个函数的返回值会作为参数传入下一个函数。需要注意使用 call 方法让每个 loader 内部可以获取到 loaderAPI:

import { readFileSync } from 'node:fs';

const loaders = [];
const raw = readFileSync('xxx');

const loaderAPI = {
emitFile: () => {},
}

const parsed = loaders.reduce(
(accu, cur) => cur.call(loaderAPI, accu),
raw
);

📒 字体文件的 hash 是如何生成的,file-loader 中如何处理的

写一篇文章:《你不知道的 Webpack loader —— file-loader 源码探秘》

webpack 源码解析:file-loader 和 url-loader

file-loader - GitHub

loader-utils - GitHub

📒 Golang 编译为 WebAssembly

在 Golang 中可以使用 syscall/js 这个库与 JS 环境进行交互,可以调用 JS 的 API,以及传递 JSON 数据:

package main

import (
"encoding/json"
"fmt"
"syscall/js"
)

type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}

func main() {
// Work around for passing structs to JS
frank := &Person{Name: "Frank", Age: 28}
p, err := json.Marshal(frank)
if err != nil {
fmt.Println(err)
return
}
obj := js.Global().Get("JSON").Call("parse", string(p))
js.Global().Set("aObject", obj)
}

Compiling Go to WebAssembly

📒 Golang 中的指针

对于原始类型来说,赋值就等于 copy,相当于在内存中创建一个一模一样的值,具有不同的内存地址:

func main() {
a := 42
b := a
fmt.Println(a, b) // 42 42
a = 27
fmt.Println(a, b) // 27 42
}

可以通过 & 操作符取到内存地址:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, b) // 42 0×1040a124
}

还可以通过 * 操作符根据内存地址访问对应的值:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
}

由于 b 实际持有的是 a 的指针引用,因此修改 a 会导致 b 指向的值发生变化:

func main() {
var a int = 42
var b *int = &a
fmt.Println(a, *b) // 42 42
a = 27
fmt.Println(a, *b) // 27 27
*b = 14
fmt.Println(a, *b) // 14 14
}

📒 Golang 中的 struct

注意 structslicemap 不同,下面这个操作实际上是完整 copy 了一个对象,内存开销较大:

package main

import (
"fmt"
)

type Doctor struct {
name string
}

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {John Pertwee}
fmt.Println(anotherDoctor) // {Tom Baker}
}

可以使用 & 操作符拿到对象的指针进行赋值,这时候两边就是联动的:

func main() {
aDoctor := Doctor{
name: "John Pertwee"
}
anotherDoctor := &aDoctor
anotherDoctor.name = "Tom Baker"
fmt.Println(aDoctor) // {Tom Baker}
fmt.Println(anotherDoctor) // &{Tom Baker}
}

注意 array 进行赋值也会 copy:

func main() {
a := [3]int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 42, 3] [1, 2, 3]
}

但如果将 array 改为 slice,赋值传递的就是指针:

func main() {
a := []int{1, 2, 3}
b := a
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
a[1] = 42
fmt.Println(a, b) // [1, 2, 3] [1, 2, 3]
}

📒 年终盘点:2022基于Monorepo的首个大趋势-TurboRepo

⭐️ 2022年如何成为一名优秀的大前端Leader?

📒 GitHub 定时任务

下面的代码中,on 字段指定了两种触发条件,一个是代码 push 进仓库,另一种是定时任务,每天在国际标准时间21点(北京时间早上5点)运行。

on:
push:
schedule:
- cron: '0 21 * * *'

定时任务配置参考:

https://github.com/lxchuan12/juejin-actions

另外推荐一个项目,可以使用 curl wttr.in 命令获取天气预报:

https://github.com/chubin/wttr.in

📒 如何开发一个 CLI 工具

参考下尤大的项目:

const templateDir = path.join(__dirname, `template-${template}`)

const write = (file, content) => {
const targetPath = renameFiles[file]
? path.join(root, renameFiles[file])
: path.join(root, file)
if (content) {
fs.writeFileSync(targetPath, content)
} else {
copy(path.join(templateDir, file), targetPath)
}
}

const files = fs.readdirSync(templateDir)
for (const file of files.filter((f) => f !== 'package.json')) {
write(file)
}

注意这里有两个文件要处理下,一个是给 package.json 修改包名:

const pkg = require(path.join(templateDir, `package.json`))

pkg.name = packageName || targetDir

write('package.json', JSON.stringify(pkg, null, 2))

还有是 .gitignore 修改文件名:

const renameFiles = {
_gitignore: '.gitignore'
}

https://github.com/vitejs/vite/blob/main/packages/create-vite/index.js

📒 命令行工具开发技术栈

  • chalk/kolorist
  • inquirer/prompts
  • ora
  • semver
  • pkg-install
  • ncp
  • commander/yargs
  • execa(个人觉得 Node 原生 child_processexec 就够用了)
  • minimist
tip

网上一些文章也都实现了递归拷贝文件,但是是否考虑到了跨平台,可以看下 ncp 的实现

https://github.com/AvianFlu/ncp

Node.js 原生的 child_process.exec 也可以执行命令,看下 execa 是如何支持 Promise 的

https://github.com/sindresorhus/execa

现在开发已经不需要自己组装 pick 了,common-binoclif 这两个,约定式路由。

另外脚手架工具,可以看看 plopyeoman,一个是基于 actioninquirer 的生态,一个是内核加自定义模板项目。

其实最简单的脚手架,不是通过cli界面选择模板,然后到 github 上去下载对应的模板文件,而是 start-kit

https://github.com/digipolisantwerp/starter-kit-ui_app_nodejs

📒 「前端基建」探索不同项目场景下Babel最佳实践方案

📒 说不清rollup能输出哪6种格式😥差点被鄙视

📒 【手把手】学会VS Code"任务"神技,成为项目组最靓的崽!

- - + + \ No newline at end of file diff --git "a/2022/tags/\345\267\245\347\250\213\345\214\226\346\226\271\346\241\210/index.html" "b/2022/tags/\345\267\245\347\250\213\345\214\226\346\226\271\346\241\210/index.html" index a249286bdd..eb861c0a4d 100644 --- "a/2022/tags/\345\267\245\347\250\213\345\214\226\346\226\271\346\241\210/index.html" +++ "b/2022/tags/\345\267\245\347\250\213\345\214\226\346\226\271\346\241\210/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "工程化方案"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/tags/\345\271\264\345\272\246\351\253\230\350\265\236\346\226\207\347\253\240/index.html" "b/2022/tags/\345\271\264\345\272\246\351\253\230\350\265\236\346\226\207\347\253\240/index.html" index 8a1be82a91..086dedeb00 100644 --- "a/2022/tags/\345\271\264\345\272\246\351\253\230\350\265\236\346\226\207\347\253\240/index.html" +++ "b/2022/tags/\345\271\264\345\272\246\351\253\230\350\265\236\346\226\207\347\253\240/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "年度高赞文章"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/tags/\345\275\222\345\271\266\346\216\222\345\272\217/index.html" "b/2022/tags/\345\275\222\345\271\266\346\216\222\345\272\217/index.html" index a5b4249062..24c0eb1e63 100644 --- "a/2022/tags/\345\275\222\345\271\266\346\216\222\345\272\217/index.html" +++ "b/2022/tags/\345\275\222\345\271\266\346\216\222\345\272\217/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "归并排序"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git "a/2022/tags/\346\207\222\345\212\240\350\275\275/index.html" "b/2022/tags/\346\207\222\345\212\240\350\275\275/index.html" index 19d6ca60db..aeb0f0c770 100644 --- "a/2022/tags/\346\207\222\345\212\240\350\275\275/index.html" +++ "b/2022/tags/\346\207\222\345\212\240\350\275\275/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "懒加载"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/tags/\351\235\231\346\200\201\351\241\265\351\235\242\351\203\250\347\275\262/index.html" "b/2022/tags/\351\235\231\346\200\201\351\241\265\351\235\242\351\203\250\347\275\262/index.html" index d31b11ab9f..25cb737698 100644 --- "a/2022/tags/\351\235\231\346\200\201\351\241\265\351\235\242\351\203\250\347\275\262/index.html" +++ "b/2022/tags/\351\235\231\346\200\201\351\241\265\351\235\242\351\203\250\347\275\262/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "静态页面部署"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217/index.html" "b/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217/index.html" index 108a48edd4..ff995b2d4f 100644 --- "a/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217/index.html" +++ "b/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

One post tagged with "黑暗模式"

View All Tags

· 17 min read
加菲猫

📒 Vue diff 算法

Vue2 diff 算法核心流程如下:

  • diff 的入口函数为 patch,使用 sameVnode 比较节点是否相同,如相同则使用 patchVnode 继续进行深层比较,否则就使用 createEle 方法渲染出真实 DOM 节点,然后替换旧元素节点
  • sameVnode 通过比较 key 值是否一样、标签名是否一样、是否都为注释节点、是否都定义 data、当标签为 input 时,type 是否相同来判断两个节点是否相同
  • patchVnode 方法如何对节点深层比较
    • 拿到真实 DOM 的节点 el(即 oldVnode.el
    • 判断当前 newVnodeoldVnode 是否指向同一对象,如果是直接 return
    • 如果新旧虚拟节点是文本节点,且文本不一样,则直接将真实 DOM 中文本更新为新虚拟节点的文本;若文本没有变化,则继续对比新旧节点的 children
    • 如果 oldVnode 有子节点而 newVnode 没有,则删除 el 的子节点
    • 如果 oldVnode 没有子节点而 newVnode 有,则将 newVnode 的子节点渲染出真实 DOM 添加到 el(Vue 源码中会判断是否有 key 重复)
    • 如果两者都有子节点,则执行 updateChildren 函数比较子节点
  • updateChildren 是 diff 算法核心部分,当发现新旧虚拟节点的子节点都存在时,需要判断哪些节点是需要移动的,哪些节点是可以直接复用的,进而提高 diff 的效率
    • 通过 首尾指针法,在新旧子节点的首位定义四个指针,然后不断对比找到可复用的节点,同时判断需要移动的节点
    • 非理想状态下只能通过节点映射的方式去找可复用节点,时间复杂度为 O(n^2)
    • Vue3 的 diff 算法在非理想状态下的节点对比使用了最长递增子序列来处理,时间复杂度为 O(nlgn)~O(n^2)

image

图解Diff算法——Vue篇

浅析 Snabbdom 中 vnode 和 diff 算法

📒 Leetcode 300 最长递增子序列

常规方式是使用动态规划,时间复杂度 O(n^2)。这里注意 dp[i] 的定义是 nums[i] 这个数结尾的最长递增子序列长度

class Solution {
public int lengthOfLIS(int[] nums) {
// 定义 dp 数组
// dp[i] 表示以 nums[i] 这个数结尾的最长递增子序列长度
int[] dp = new int[nums.length];
// 初始值填充 1(子序列至少包含当前元素自己)
Arrays.fill(dp, 1);
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < i; j++) {
// 假设 dp[0...i-1] 都已知,需要求出 dp[i]
// 只需要遍历 nums[0...i-1],找到结尾比 nums[i] 小的子序列长度 dp[j]
// 然后把 nums[i] 接到最后,就可以形成一个新的递增子序列,长度为 dp[j] + 1
// 显然,可能形成很多种新的子序列,只需要选择最长的,作为 dp[i] 的值即可
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
// 遍历 dp 数组,找出最大值
int res = 0;
for (int i = 0; i < dp.length; i++) {
res = Math.max(res, dp[i]);
}
return res;
}
}

📒 CSS 中的 object-fit 属性用法

在项目中有一个需求,图片尺寸较小时,需要保存图片原有大小,图片尺寸大于容器大小时,需要缩放以适合容器大小,同时保持原有比例。

查阅 MDN 文档可知,在 <img><video> 等替换元素上可以使用 object-fit 属性,用于设置替换元素该如何适配容器,可以取以下几个值:

  • object-fit: fill:图片被拉伸以适应容器,这种方式不会保持长宽比
  • object-fit: contain:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较短边会留出空白
  • object-fit: cover:图片被缩放以适应容器,同时保持长宽比,如果图片与容器长宽比不匹配,较长边会被剪裁
  • object-fit: none:图片不会调整大小
  • object-fit: scale-down:图片较小时使用 none,图片较大时使用 contain

综上,使用 object-fit: scale-down 就可以实现项目需求。

注意 IE 11 不支持 object-fit

object-fit - MDN

📒 理解归并排序

归并排序就是对数组的左半边和右半边分别排序,然后再合并两个有序数组。

  • 归并排序的过程可以在逻辑上抽象成一棵二叉树,树上的每个节点的值可以认为是 nums[lo..hi],叶子节点的值就是数组中的单个元素
  • 然后,在每个节点的后序位置(左右子节点已经被排好序)的时候执行 merge 函数,合并两个子节点上的子数组
  • 这个 merge 操作会在二叉树的每个节点上都执行一遍,执行顺序是二叉树后序遍历的顺序

一句话总结,归并排序实际上就是先对数组不断进行二分,分到只有一个元素为止,此时 merge 方法开始发挥作用,将两个元素为一组,合并为长度为 2 的有序数组,再将两个长度为 2 的有序数组为一组,合并为长度为 4 的有序数组,以此类推

class Merge {

// 用于辅助合并有序数组(不能原地合并,需要借助额外空间)
private static int[] temp;

public static void sort(int[] nums) {
// 避免递归中频繁分配和释放内存可能产生的性能问题
// 提前给辅助数组开辟内存空间
temp = new int[nums.length];
// 原地修改的方式对整个数组进行排序
sort(nums, 0, nums.length - 1);
}

// 定义:将子数组 nums[lo..hi] 进行排序
private static void sort(int[] nums, int lo, int hi) {
if (lo == hi) {
// 单个元素不用排序
return;
}
// 这样写是为了防止溢出,效果等同于 (hi + lo) / 2
// 注意:对于无法整除的情况,Java 中 int 类型会自动向下取整
int mid = lo + (hi - lo) / 2;
// 先对左半部分数组 nums[lo..mid] 排序
sort(nums, lo, mid);
// 再对右半部分数组 nums[mid+1..hi] 排序
sort(nums, mid + 1, hi);
// 将两部分有序数组合并成一个有序数组
merge(nums, lo, mid, hi);
}

// 将 nums[lo..mid] 和 nums[mid+1..hi] 这两个有序数组合并成一个有序数组
private static void merge(int[] nums, int lo, int mid, int hi) {
// 先把 nums[lo..hi] 复制到辅助数组中
// 以便合并后的结果能够直接存入 nums
for (int i = lo; i <= hi; i++) {
temp[i] = nums[i];
}

// 数组双指针技巧,合并两个有序数组
// i => 左半边数组起始下标
// j => 右半边数组起始下标
int i = lo, j = mid + 1;
for (int p = lo; p <= hi; p++) {
if (i == mid + 1) {
// 左半边数组已全部被合并,只需把右半边数组合并过来即可
nums[p] = temp[j++];
} else if (j == hi + 1) {
// 右半边数组已全部被合并,只需把左半边数组合并过来即可
nums[p] = temp[i++];
} else if (temp[i] > temp[j]) {
// 将较小的元素合入,同时下标前进一位,此时是升序
// 只要将 > 改为 < 就可以把结果改为降序
nums[p] = temp[j++];
} else {
nums[p] = temp[i++];
}
}
}
}

归并排序时间复杂度为 O(nlogn)

归并排序的正确理解方式及运用

🌛 Leetcode 112 路径总和

判断是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

class Solution {
public boolean hasPathSum(TreeNode root, int targetSum) {
if (root == null) return false;
if (root.left == null && root.right == null) {
return (targetSum - root.val) == 0;
}
boolean leftResult = hasPathSum(root.left, targetSum - root.val);
boolean rightResult = hasPathSum(root.right, targetSum - root.val);
return leftResult || rightResult;
}
}

📒 Podman 已成 Linux 官方标配!Docker 没戏了?

⭐️ 不懂动态规划?21道 LeetCode题目带你学会动态规划!

⭐️ 浅析 Snabbdom 中 vnode 和 diff 算法

📒 HTTP 缓存最佳实践

在配置 nginx 的时候,可以配置合理的缓存策略,例如:

  • html 文件配置协商缓存
  • js、css、图片、字体等文件由于带有哈希,可以配置一年强缓存
tip

这里的缓存更新逻辑:

当 js、css 等静态资源文件修改后,文件哈希发生变化,对应引入 html 的文件地址也发生变化,等于 html 文件也被修改。因此浏览器端会获取到最新的 html 文件,然后根据带有哈希的路径加载最新的静态资源文件。

这样配置缓存之后,可以极大提升资源二次加载速度,进而提升用户体验。以上这些是从性能角度考虑的,从安全角度考虑,推荐如下配置:

  • 为了防止中介缓存,建议设置 Cache-Control: private,这可以禁用掉所有 Public Cache(比如代理),这就减少了攻击者跨界访问到公共内存的可能性
  • 默认情况下,浏览器使用 URL请求方法 作为缓存 key,这意味着,如果一个网站需要登录,不同用户的请求由于它们的请求URL和方法相同,数据会被缓存到一块内存里。如果我们请求的响应是跟请求的 Cookie 相关的,建议设置 Vary: Cookie 作为二级缓存 key

HTTP 缓存别再乱用了!推荐一个缓存设置的最佳姿势!

📒 跨域,不止CORS

通常提到跨域问题的时候,相信大家首先会想到的是 CORS (Cross Origin Resource Sharing),其实 CORS 只是众多跨域访问场景中安全策略的一种,类似的策略还有:

  • COEP (Cross Origin Embedder Policy):跨源嵌入程序策略
  • COOP (Cross Origin Opener Policy):跨源开放者政策
  • CORP (Cross Origin Resource Policy):跨源资源策略
  • CORB (Cross Origin Read Blocking):跨源读取阻止

为何有时候服务端没有给响应头设置 Content-Type,浏览器还能正确识别资源类型

当服务端没有设置 Content-Type 或者浏览器认为类型不正确时,浏览器会读取资源的字节流,进行 MIME 类型嗅探。这就可能导致一些敏感数据被提交到内存,攻击者随后可以利用 Spectre 之类的漏洞来潜在地读取该内存块。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types#mime_sniffing

为了使我们的网站更加安全,建议所有网站都开启 CORB,只需要下面的操作:

  • 配置正确的 Content-Type(例如,HTML 资源设置 text/html
  • 开启 X-Content-Type-Options: nosniff 来禁止客户端进行自动 MIME 嗅探

跨域,不止CORS

新的跨域策略:使用COOP、COEP为浏览器创建更安全的环境

📒 如何监听系统黑暗模式

在 CSS 中可以通过 prefers-color-scheme 媒体查询实现:

body {
color: black;
background: white;
}
@media (prefers-color-scheme: dark) {
body {
color: white;
background: black;
}
}

在 JS 中可以使用 window.matchMedia 媒体查询:

import React from "react";

export type ThemeName = "light" | "dark";

function useTheme() {
const [themeName, setThemeName] = React.useState<ThemeName>("light");

React.useEffect(() => {
// 设置初始皮肤
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
setThemeName("dark");
} else {
setThemeName("light");
}

// 监听系统颜色切换
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (event.matches) {
setThemeName("dark");
} else {
setThemeName("light");
}
});
}, []);

return {
themeName,
isDarkMode: themeName === "dark",
isLightMode: themeName === "light",
}
}

https://developer.mozilla.org/zh-CN/docs/Web/API/Window/matchMedia

自定义 hook 实际上就是 mixin,把一段可复用的逻辑抽离出来

📒 搜索 JS、Go、Java、Python 的第三方库

https://openbase.com/

例如搜索 Redux 的替代方案:

https://openbase.com/js/redux/alternatives

⭐️ React hooks 状态管理方案解析

📒 深入理解 React Native 的新架构

照 React Native 团队去年发表的一篇 博客 的说法,他们会在今年发布新的架构。本文将会详细介绍新架构的相关内容。

https://medium.com/coox-tech/deep-dive-into-react-natives-new-architecture-fb67ae615ccd

📒 QUIC——快速UDP网络连接协议

  • QUIC 的Stream流基于Stream ID+Offset进行包确认,流量控制需要保证所发送的所有包offset小于 最大绝对字节偏移量 ( maximum absolute byte offset ), 该值是基于当前 已经提交的字节偏移量(offset of data consumed) 而进行确定的,QUIC会把连续的已确认的offset数据向上层应用提交。QUIC支持乱序确认,但本身也是按序(offset顺序)发送数据包
  • QUIC利用ack frame来进行数据包的确认,来保证可靠传输。一个ack frame只包含多个确认信息,没有正文
  • 如果数据包N超时,发送端将超时数据包N重新设置编号M(即下一个顺序的数据包编号) 后发送给接收端
  • 在一个数据包发生超时后,其余的已经发送的数据包依旧可以基于Offset得到确认,避免了TCP利用SACK才能解决的重传问题
tip

其实QUIC的乱序确认设计思想并不新鲜,大量网络视频流就是通过类似的基于UDP的RUDP、RTP、UDT等协议来实现快速可靠传输的。他们同样支持乱序确认,所以就会导致这样的观看体验:明明进度条显示还有一段缓存,但是画面就是卡着不动了,如果跳过的话视频又能够播放了

QUIC——快速UDP网络连接协议

- - + + \ No newline at end of file diff --git "a/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217\351\200\202\351\205\215/index.html" "b/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217\351\200\202\351\205\215/index.html" index 9622817995..ef4f55688c 100644 --- "a/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217\351\200\202\351\205\215/index.html" +++ "b/2022/tags/\351\273\221\346\232\227\346\250\241\345\274\217\351\200\202\351\205\215/index.html" @@ -11,14 +11,14 @@ - - + +
Skip to main content

One post tagged with "黑暗模式适配"

View All Tags

· 10 min read
加菲猫

📒 Golang 模拟 JS 的 Promise

https://www.bilibili.com/video/BV11v411h7t5

📒 Golang 如何通过 WebAssembly 调用 JS API

https://github.com/elliotforbes/go-webassembly-framework

📒 「目前全网唯一&2万字长文」从JS上下文到Chromium源码的极限拉扯!!兄弟姐妹们接好了!!

📒 浅谈 Vite 2.0 原理,依赖预编译,插件机制是如何兼容 Rollup 的?

📒 JS 两个注意点

  • 判断对象是否存在某属性,通常都用 Object.prototype.hasOwnProperty.call()。有同学问为什么不能直接 obj.hasOwnProperty() 去判断,因为有些对象是通过 Object.create(null) 创建的,这种情况下原型上就访问不到 hasOwnProperty,必须通过 Object.prototype.hasOwnProperty.call()

  • ES2016 新增的 Array.prototype.includes() 可以识别 NaN,而 Array.prototype.indexOf() 不能识别:

    const arr = ['es6', 'es7', NaN, 'es8'];
    arr.includes(NaN); // true
    arr.indexOf(NaN); // -1

📒 今年最受欢迎的项目:谷歌的 zx

使用 zx 可以编写简单的命令行脚本:

#!/usr/bin/env zx

await $`cat package.json | grep name`

let branch = await $`git branch --show-current`
await $`dep deploy --branch=${branch}`

await Promise.all([
$`sleep 1; echo 1`,
$`sleep 2; echo 2`,
$`sleep 3; echo 3`,
])

let name = 'foo bar'
await $`mkdir /tmp/${name}`

zx 涵盖了多个软件包提供的功能:

  • node-fetch:使用与浏览器中相同的 API 发出 HTTP 请求
  • fs-extra:运行文件系统

这块源码不是很多,推荐看一下:

https://github.com/google/zx

📒 工程化方案总结下

2021 年 TypeScript + React 工程化指南

2021 年当我们聊前端部署时,我们在聊什么

📒 TypeScript 类型体操

TypeScript 类型编程: 从基础到编译器实战

知其然,知其所以然:TypeScript 中的协变与逆变

📒 monorepo 项目

One For All:基于pnpm + lerna + typescript的最佳项目实践 - 理论篇

📒 漫画图解 Chrome 浏览器从输入到渲染的原理(7000 字)

📒 QUIC 协议

推荐看看 QUIC 101 视频以及 The QUIC transport protocol: design and Internet-scale deployment 论文

📒 ES2015+ 的代码要不要转为 ES5

Babel 主要做了两件事,一是语法转换,二是 api 兼容,其中 api 兼容是通过引入 core-js 的 polyfill 实现的。一般来说转换之后体积肯定会增大,并且很多语法转换的时候会引入 helper 函数,这就产生了副作用,导致无法 Tree-Shaking。

ES6 以上版本代码要不要转码成 ES5?

📒 如何覆盖 CRA 默认 webpack 配置

查看详情

在 CRA 创建的项目中,经常需要修改默认 webpack 配置。但是 CRA 不像 Vue-cli 可以提供自定义 webpack 配置,而 eject 又会把全部配置暴露出来,很麻烦。这种情况下可以使用 react-app-rewired 这个库:

$ yarn add react-app-rewired -D

在项目根目录创建一个 config-overrides.js 文件,添加自定义 webpack 配置:

/* config-overrides.js */

module.exports = function override(config, env) {
//do stuff with the webpack config...
return config;
}

最后在 package.json 中修改 npm scripts:

/* package.json */

"scripts": {
- "start": "react-scripts start",
+ "start": "react-app-rewired start",
- "build": "react-scripts build",
+ "build": "react-app-rewired build",
- "test": "react-scripts test",
+ "test": "react-app-rewired test",
"eject": "react-scripts eject"
}

这个库源码不是很多,推荐看一下:

https://github.com/timarney/react-app-rewired

tip

通常 react-app-rewired 会搭配 customize-cra 这个库一起用:

$ yarn add customize-cra react-app-rewired -D

支持在 config-overrides.js 中编写函数式的 API 去修改 webpack 配置:

const {
override,
addDecoratorsLegacy,
disableEsLint,
addWebpackAlias
} = require("customize-cra");
const path = require("path");

module.exports = override(
// enable legacy decorators babel plugin
addDecoratorsLegacy(),

// disable eslint in webpack
disableEsLint(),

// add an alias for "ag-grid-react" imports
addWebpackAlias({
["ag-grid-react$"]: path.resolve(__dirname, "src/shared/agGridWrapper.js")
}),
);

https://github.com/arackaf/customize-cra

📒 React 组件懒加载实现思路

项目中经常需要长列表渲染,一般都使用懒加载,滚动到底部时渲染下一屏数据,需要判断元素是否在 viewport 内。过去通常会监听滚动事件,然后调用 Element.getBoundingClientRect() 方法以获取元素的边界信息。由于滚动事件触发非常频繁,频繁调用会导致性能问题。

这种情况下可以使用 Intersection Observer API,仅在被监听元素进入或者退出 viewport 时触发回调,这样就不会大量占用主线程。

let observer = new IntersectionObserver(callback, options);
let target = document.querySelector('#listItem');
observer.observe(target);
tip

在 React 项目中,还可以使用 react-intersection-observer 这个库。

react-intersection-observer - npm

Intersection Observer API - MDN

懒加载 React 长页面 - 动态渲染组件

📒 如何避免 React 组件重复渲染

📒 React 16 架构

React16架构可以分为三层:

  • Scheduler(调度器)—— 核心职责只有 1 个, 就是执行回调。把react-reconciler提供的回调函数, 包装到一个任务对象中.在内部维护一个任务队列, 优先级高的排在最前面。循环消费任务队列, 直到队列清空
  • Reconciler(协调器)—— 负责找出变化的组件,16版本主要是Fiber,15版本是stack。区别在于增加了优先级系统,通过遍历的方式实现可中断的递归,将fiber树的构造过程包装在一个回调函数中, 并将此回调函数传入到scheduler包等待调度
  • Renderer(渲染器)—— 负责将变化的组件渲染到页面上,能够将react-reconciler包构造出来的fiber树表现出来, 生成 dom 节点(浏览器中), 生成字符串(ssr),比如说react-dom、react-native。 所以react-native的作用主要是将react提供的节点,渲染到app页面上

我们书写的react-native组件,比如说View、Text等,需要通过react-native-web来变成react-dom可以识别的节点

📒 如何在 JB 全家桶中使用 VS Code 的快捷键

查看详情

JB 全家桶,例如 IDEA、WebStorm、GoLand 等支持多种 keymap,如要使用 VS Code 的快捷键,只需要安装对应的 Keymap 即可:

Preview

安装后应用即可:

Preview

同理主题也可以安装,在 JB 全家桶中推荐使用 One Dark Theme,安装完成后点击 apply 即可:

Preview

📒 静态页面部署方案

一篇教你代码同步 Github 和 Gitee

教你如何使用vercel服务免费部署前端项目和serverless api

📒 webpack 热模块替换看下源码

webpack模块热更新原理

Webpack 原理系列十:HMR 原理全解析

📒 聊一聊前端算法面试——递归

📒 前端单元测试入门与最佳实践

📒 淘宝店铺的 TypeScript ESLint 规则集考量

📒 自动发布脚本

https://github.com/release-it/release-it

📒 diff 算法相关

https://github.com/snabbdom/snabbdom

DIff算法看不懂就一起来砍我(带图)

📒 如何盘点出掘金的年度高赞文章?

📒 盘点掘金 2021 高赞 Vue 文章

📒 盘点掘金 2021 高赞 React 文章

📒 盘点掘金 2021 点赞高达 6000,收藏过万的文章

📒 如何测试驱动开发 React 组件?

📒 一起来写 VS Code 插件:为你的团队提供常用代码片段

📒 黑暗模式常用换肤方案

CSS Variables

css variables 是 Web 标准实现了对深色模式的支持,以下代码通过 CSS 媒体查询:

:root {
color-scheme: light dark;
--nav-bg-color: #F7F7F7;
--content-bg-color: #FFFFFF;
--font-color: rgba(0,0,0,.9);
}

@media (prefers-color-scheme: dark) {
:root {
--nav-bg-color: #2F2F2F;
--content-bg-color: #2C2C2C;
--font-color: rgba(255, 255, 255, .8);
}
}

:root {
color: var(--font-color);
}

.header {
background-color: var(--nav-bg-color);
}

.content {
background-color: var(--content-bg-color);
}

优点:代码量最少,实现起来方便

缺点:存在浏览器兼容性,需要 edge16+ 才支持

打包多份 css

当然也可以手动打包 2 份 CSS 样式,通过动态引入样式文件进行切换。这种方式存在一个问题,当点击切换的时候会引起整个页面重排,因此我们需要单独打包出只包含颜色的样式文件。从这个思路出发,我们就接触到了 PostCSS。

使用 PostCSS 插件让你的网站支持暗黑模式

📒 使用 NextJS 和 TailwindCSS 重构我的博客

⭐️ 2022 前端技术领域会有哪些新的变化?

- - + + \ No newline at end of file diff --git "a/2023/10\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/10\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index ff58c1813a..7805ae787e 100644 --- "a/2023/10\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/10\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月15日内容汇总

· 3 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

Go TLS服务端绑定证书的几种方式

Go 夜读第 147 期:roseduan 带你了解高性能预写日志(Write Ahead Log)的设计与实现

SpringCloud 微服务架构:实现分布式系统的无缝协作

记一次 MySQL 主从同步异常的排查记录,百转千回!

Go 标准库想增加 metrics 指标,你支持吗

GitLab部署和实战教程

RocketMQ 5.0 从入门到精通

实战!用 Arthas 定位 Spring Boot 接口的超时问题,让应用起飞~

两个实验让我彻底弄懂了「订阅关系一致」

Go 1.21.2 仅发布 5 天,又发布了 net/http2 的一个安全更新

使用rust重写mping: 和Go版本比较

RabbitMQ vs Kafka,别再选错了!!!

2万字 + 10图剖析Spring依赖注入和SpEL表达式

大象转身-平台架构如何拥抱业务创新

Kubernetes Pod 服务质量等级

Service Weaver:以单体形式编码,以微服务形式部署

看资深Kubernetes运维是如何选型Ingress网关

Java21上手体验-分代ZGC和虚拟线程 | 京东云技术团队

Go slog 包:开启结构化日志的奇妙之旅

喝了100杯酱香拿铁,我开窍了

速率限制:控制服务资源利用和质量的关键工具

📒 前端相关

用 TypeScript 手写数组内置的 20 个方法!!!

我,前端,不想卷技术了……卷下整洁架构

我不允许有人不会封装 ECharts

MDH 前端周刊第 108 期:Cloudflare Fonts、GPT-4 Vision、Bun 炒作、简历、可拖拽

- - + + \ No newline at end of file diff --git "a/2023/10\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/10\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 84b12f2bb6..c1d1d4a59d 100644 --- "a/2023/10\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/10\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月1日内容汇总

· 3 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

Java 8 的 Stream 不好调试?试试 IDEA 的调试神器 Stream Trace!

@Async注解的坑,小心

折腾一个周末,撸Nacos可真不容易

图解ReentrantLock的基石AQS源码-独占锁的获取与释放

下单时如何保证数据一致性

一个关于 i++ 和 ++i 的面试题打趴了所有人

Deconstructing Type Parameters

MySQL到TiDB:Hive Metastore横向扩展之路

谁家面试往死里问事务啊

从5s到0.5s!看看人家项目中的异步任务优化技巧,确实优雅!

使用 查询分离 后 从20s优化到500ms

业务系统架构实践总结

一文了解负载均衡器、反向代理、API 网关区别

Golang GC 从理论到针对服务的定制化应用

Kubernetes 应用最佳实践 - 水平自动伸缩

还不会部署微服务项目?保姆级教程来啦!

专为小白打造—Kafka一篇文章从入门到入土 | 京东云技术团队

美团二面拷打:如何设计一个优先级任务线程池

深入理解 RocketMQ 广播消费

Kubernetes 应用最佳实践 - 亲和性和污点容忍度

一文带你深入理解Kubernetes Service

鹅厂练习13年Coding后,我悟了

定了:Go 1.22将修复for循环变量错误

给你一个亿的keys,Redis如何统计

HyperLogLog 算法原理及其在 Redis 中的实现

快速掌握 Go 工作区模式

麻了啊!一个烂分页,踩了三个坑!

Go 1.21.0 新增标准库 slices 和 maps 详解

Go语言爱好者周刊:第 201 期

📒 前端相关

面试被问到低代码细节?听我这样吹🤯(含架构和原理)

加速 JavaScript 生态系统:Polyfills 出现问题了吗

MDH 前端周刊第 107 期:Safari 17、stylex、Svelte 5、线性代码

- - + + \ No newline at end of file diff --git "a/2023/10\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/10\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 0a6be9be32..9380ca0bdc 100644 --- "a/2023/10\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/10\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月22日内容汇总

· 2 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

Kubernetes 应用最佳实践 - 优雅关闭长连接

Go 项目标准布局?Go 官方出指南了

不看就落后了,Go 1.22 中更好的http router

Go和C++通用性能优化黑魔法——PGO!

Spring技术内幕4,深度解析Spring内置作用域及其在实践中的应用

EDAS 让 Spring Cloud Gateway 生产可用的二三策

Go中的流量限制:有效控制流量

优化Rust代码性能的10种最佳实践

太强了!三种方案优化 2000w 数据大表!

图解Dubbo,Dubbo 服务治理详解

被 Go 团队打脸了,已接受的提案也能一句话推翻!!!

Kubernetes Service 类型和会话亲和性

一文让你搞明白集群弹性伸缩是如何运作的

golang select 机制

成本最高降低70%,腾讯大规模业务集群的云原生成本优化实践!

Redis 只能做缓存 ?你 out了!

Rust并发编程 - 容器类并发原语

📒 前端相关

完美搭配,微前端与Monorepo的架构设计

译:我们如何优化 Next.js 中的软件包导入

原神启动!three.js 复刻原神登录界面技术浅析

Vue 源码思想在工作中的应用

MDH 前端周刊第 109 期:Astro 3.3、桶文件、软技能、推和拉、程序员健康、No Build

- - + + \ No newline at end of file diff --git "a/2023/10\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/10\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 02c39c10a0..d99b5b4182 100644 --- "a/2023/10\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/10\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月29日内容汇总

· One min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

Kubernetes Pod 设计与实现 - Pause 容器

Rust并发编程6 - 并发集合

Kafka消息队列,Kafka批处理与流处理详解

Dubbo 路由及负载均衡性能优化

Kubernetes - kube-proxy 代理模式工程优化

Go 语言如何获取 CPU 利用率

Go 周刊一览#1:1.22 增强 ServeMux 路由、新版本发布、新开源包等

Rust并发编程5 - 基本并发原语

Go语言爱好者周刊:第 202 期 — 官方出指南了

📒 前端相关

前端工程化与模块化

三种虚拟列表原理与实现

MDH 前端周刊第 110 期:React Query 5、PS Web、命名、开发人员建议、useTransition

- - + + \ No newline at end of file diff --git "a/2023/10\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/10\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 10787fb0af..98393586a5 100644 --- "a/2023/10\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/10\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

10月8日内容汇总

· 3 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

精进云原生 – Dubbo Kubernetes 最佳实践

如何使用Higress快速实现金丝雀与蓝绿发布

Kubernetes 应用最佳实践 - 金丝雀发布

PGO: 为你的Go程序提效5%

一个泛型的有序Go Map实现

Go 1.21中 sync.Once的新扩展

怎么阻止一个Go程序退出

字节三面:如何设计一个高性能短链系统

40 个定时任务,带你理解 RocketMQ 设计精髓!

在Golang中玩转依赖注入-dig篇

简单聊一聊公平锁和非公平锁,parallel并行流

高频面试:Spring 如何解决循环依赖

Go 1.21 不仅修复了 go 命令行的安全问题,还修复了一个编译大文件的问题!

Go项目目录该怎么组织?官方终于出指南了!

DDD的奇幻世界:从小积木到艺术品的设计之旅

相较于RocketMQ的事务消息,本地消息表才是真正的王者

仅此一招,再无消息乱序的烦恼

消息队列技术选型:这 7 种消息场景一定要考虑!

Kafka 架构、核心机制和场景解读

为什么 MyBatis 源码中,没有我那种 if···else

解密DDD:领域事件--系统解耦的终极武器

DDD 与 CQRS 才是黄金组合

DDD 必备架构--六边形架构

📒 前端相关

某大厂一面: 讲讲 Fiber 架构以及它是如何实现增量渲染的🥱🥱🥱

面试被问到低代码细节?听我这样吹(含架构和原理)

前端铜九铁十面试必备八股文——工程化

Threejs 中秋佳节感受闽南名俗 | 中秋博饼🥮🥮🥮

【动图+大白话🍓解析React源码】Render阶段中Fiber树的初始化与对比更新~

- - + + \ No newline at end of file diff --git "a/2023/11\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/11\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index c39ed31aa2..cdd967a068 100644 --- "a/2023/11\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/11\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月12日内容汇总

· 9 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

两全其美:Sidecarless 与 Sidecar 模式融合的服务网格新形态

Fourteen Years of Go

Go 团队发布 Go 14 周年回顾!附加更完整新特性脑图!

米哈游大数据云原生实践

没用过微服务?别慌,丐版架构图,让你轻松拿捏面试官

并发编程巅峰对决:Go vs Rust

Sentinel为什么这么强,我扒了扒背后的实现原理

写给go开发者的gRPC教程-gRPC Gateway

Rust 中的异步编程模型

Rust 作为一门现代的系统级编程语言,旨在提供高效、安全和可靠的异步编程能力。Rust 异步编程的目标是实现高性能、无安全漏洞的异步应用程序,同时提供简洁的语法和丰富的异步库。

由于并发编程在现代社会非常重要,因此每个主流语言都对自己的并发模型进行过权衡取舍和精心设计,Rust 语言也不例外。下面的列表可以帮助大家理解不同并发模型的取舍:

  • OS 线程, 它最简单,也无需改变任何编程模型(业务/代码逻辑),因此非常适合作为语言的原生并发模型,我们在多线程章节[3]也提到过,Rust 就选择了原生支持线程级的并发编程。但是,这种模型也有缺点,例如线程间的同步将变得更加困难,线程间的上下文切换损耗较大。使用线程池在一定程度上可以提升性能,但是对于 IO 密集的场景来说,线程池还是不够看。
  • 事件驱动(Event driven), 这个名词你可能比较陌生,如果说事件驱动常常跟回调( Callback )一起使用,相信大家就恍然大悟了。这种模型性能相当的好,但最大的问题就是存在回调地狱的风险:非线性的控制流和结果处理导致了数据流向和错误传播变得难以掌控,还会导致代码可维护性和可读性的大幅降低,大名鼎鼎的 JS 曾经就存在回调地狱。
  • 协程(Coroutines) 可能是目前最火的并发模型,Go 语言的协程设计就非常优秀,这也是 Go 语言能够迅速火遍全球的杀手锏之一。协程跟线程类似,无需改变编程模型,同时,它也跟 async 类似,可以支持大量的任务并发运行。但协程抽象层次过高,导致用户无法接触到底层的细节,这对于系统编程语言和自定义异步运行时是难以接受的
  • actor 模型是 erlang 的杀手锏之一,它将所有并发计算分割成一个一个单元,这些单元被称为 actor , 单元之间通过消息传递的方式进行通信和数据传递,跟分布式系统的设计理念非常相像。由于 actor 模型跟现实很贴近,因此它相对来说更容易实现,但是一旦遇到流控制、失败重试等场景时,就会变得不太好用
  • async/await, 该模型性能高,还能支持底层编程,同时又像线程和协程那样无需过多的改变编程模型,但有得必有失,async 模型的问题就是内部实现机制过于复杂,对于用户来说,理解和使用起来也没有线程和协程简单,好在前者的复杂性开发者们已经帮我们封装好,而理解和使用起来不够简单,正是本章试图解决的问题。

Rust并发编程 - 第三章 async/await 异步编程

只改一个参数让Golang GC耗时暴降到1/30!

不想引入mq?试试debezium

考考你,给32位系统的电脑插个8G的内存条会发生什么

Redis 消息队列和 Kafka 有啥区别

Kafka 消息会落盘,会持久化,但是 Redis 是基于内存的消息队列,如果实例重启会导致数据丢失。Redis 如何实现高可用,有两种方式,1)生产环境会用 Redis 集群模式,有多个副本,读写操作都是针对主节点,会异步复制给从节点,保证最终一致性。假如主节点挂了,则会在从节点中选举一个新的主节点,2)Redis 也支持持久化。

此外,Kafka 相对于 Redis 消息队列在吞吐量和延迟方面更为优秀(同一个 Topic 下可以有多个 Partition),可以处理更高的消息流量,并且具备较低的延迟。

RPC 调用和浏览器 HTTP 请求有啥区别

RPC 也称为内部调用,client 启动的时候会创建一个连接池,提前建立 tcp 链接,后续调用都复用 tcp 链接,避免频繁的 tcp 三次握手,提升性能。此外 RPC 调用还有一套服务发现机制(类似 DNS),可以直接用服务名的方式调用。由于内部调用不经过网关,因此需要在调用方实现负载均衡,比如 OpenFeign 底层基于 Ribbon 实现负载均衡。

浏览器发送 HTTP 请求则需要在发送请求的时候实现 DNS 解析、TCP 三次握手等操作,一定程度上会影响性能。之前写过一个 Node 服务,在 Node 环境用 http 模块去调用其他接口,实际上会带来一定的性能开销。如果在程序频繁执行到的关键路径上,改用微服务 RPC 调用方式可以提升性能。

Apache RocketMQ,构建云原生统一消息引擎

25张图盘点 RocketMQ 11 种消息类型!

聊聊如何在Java应用中发送短信

Go1.21.4 发布了:官方图片竟然用的 loong64

Golang面试题从浅入深高频必刷「2023版」| 文末送书

盘点golang中的开发神器

Go 透明文件夹的特性,有没有必要加

24 个 Docker 常见问题处理技巧

烂大街的 RPC 项目,如何和字节面试官聊出花儿来

一次 Netty 代码不健壮导致的大量 CLOSE_WAIT 连接原因分析

应用容器化后为什么性能下降这么多

只改一行语句,锁这么多

Rust并发编程番外篇: Mutex内部实现

📒 前端相关

2023云栖大会的新鲜事

不是吧?async/await异常捕获你还在用try-catch~

Why You Want React Query

Rspack 的设计背景和探索之路

ECMAScript 2023:为JavaScript带来新的数组复制方法

Antd Procomponent 之 proForm - 高级表单

Guide to React Suspense: From Code Splitting to Data Fetching

MDH 前端周刊第 112 期:Docusaurus 3、Remix & Vite、D2、React Forget

- - + + \ No newline at end of file diff --git "a/2023/11\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/11\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 4679f1b032..a1d46f3f69 100644 --- "a/2023/11\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/11\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月19日内容汇总

· 11 min read
加菲猫

🌟 AI 相关

Transformer模型--模型架构

使用 Redis 构建轻量的向量数据库应用:图片搜索引擎(一)

⭐️ Golang 相关

【升职加薪秘籍】我在服务监控方面的实践(4)-日志监控

Go语言微服务框架重磅升级:dubbo-go v3.2.0 -alpha 版本预览

一文告诉你让SSH 变好用的正确姿势!

腾讯重复造轮子?我们真的需要这么多RPC框架吗

学习gorm系列七:如何高效建立数据库连接

Vite 5.0 正式发布

Git常用命令思维导图

实战:Nacos配置中心的Pull原理,附源码

Kubernetes - CRI 概述

解密defer语句:避免踩坑,掌握延迟执行的正确姿势

提升应用性能:Go中的同步与异步处理

Prometheus 14 点实践经验分享

老后端被借调去写Java了,含泪总结的Java多线程编程基础

史上最全の图论圣经: 涵盖所有「存图方式」与「最短路算法」

HBase详细介绍及原理解析!

微服务框架之争:Quarkus 即将替代Spring Boot

关系代数、SQL语句和Go语言示例

K8S 和 容器中的退出状态码含义,看你知道几个

Unix 编程艺术名句摘录

从4万行代码降到1.8万,腾讯视频竟然用DDD做架构重构

Web 实时消息推送的 7 种实现方案

最新进展:Go arena 手动管理内存,鸽了!

微服务不香了?单体化改造为我们节省上万核 CPU!

Golang 编译速度为什么这么快

写出高质量代码的秘诀:Golang中的测试驱动开发(TDD)

实战!接口中的大事务,该如何进行优化

用了这么多年Docker,殊不知你还有这么多弯弯绕!

Kubernetes上生产环境后,99%都会遇到这2个故障

Go语言爱好者周刊:第 204 期 —— Go 14 周年

📒 前端相关

前端基建有哪些?大小公司偏重啥

不是吧?async/await异常捕获你还在用try-catch~

IntersectionObserver:实现滚动动画、懒加载、虚拟列表

Introducing GPTs。OpenAI 正在推出一种新的定制版本的 ChatGPT—— GPTs。用户可创建专门用途的 GPT,无需编程知识,方便在日常生活、工作或学习等各种场景中使用,甚至可以和他人分享。用户可以在 chat.openai.com/create 上进行创建试用。ChatGPT Plus 和企业版用户今天就可以试用,包括 Canva 和 Zapier AI Actions。此外,本月晚些时候,OpenAI 将推出 GPT 商店,展示被认证的开发者的作品。在未来几个月,GPT 使用者也将有机会通过使用频率赚钱。OpenAI 表示,GPT 的所有措施都考虑到了隐私和安全,用户完全可以控制自己的数据。此外,开发者也可以将 GPT 连接到真实世界,定义自定义动作,连接到数据库,插入电子邮件,或者使用购物助手等。企业版用户也可以部署仅限内部的 GPT,满足特定使用场景,部门或具有专有数据集的需求。

Vue design patterns guide。Vue是一个流行的用于构建用户界面的渐进式JavaScript框架。与其他的全功能框架不同,Vue被设计为可逐步采用,这意味着其入门易如jQuery,但与现代化工具和支持库结合使用时,有潜力支持复杂的应用程序。理解和利用Vue的模式可以大大帮助编写清晰、高效和可维护的代码。本站将详细讲解Vue的特定模式和行为,包括可组合函数、脚本设置、状态管理、提供/注入、动态组件等概念。无论你是初学者,还是希望更好地理解一些有用的模式,这里都能提供帮助。

Github 推出新的字体。

Rust 在 nightly 版本中通过并行前端技术加速编译过程。Rust 编译器的前端现在可以使用并行执行功能,以大大缩短编译时间。用户可以通过使用 - Z threads=8 选项在夜间编译器上尝试此功能。这项功能现在还处于实验阶段,预计将在 2024 年的稳定版编译器中进行发布。通过使用 Rayon 实现细粒度的并行任务,新的前端可以并行执行许多编译任务。用户可以通过 - Z threads 选项打开多线程模式。测试结果表明,编译时间可以减少多达 50%,但结果取决于代码的特性和构建配置。尽管并行前端运行在单线程模式下,编译时间一般仅慢 0% 到 2%。因此,用户应几乎不会注意到增加的延迟。此外,Rust 编译器的实现遵循 jobserver 协议,将创建的线程数量限制在内核数量以内,因此不会出现效率低下的情况。

《你为什么需要 React Query》。 文章主要讨论了 React Query 的实用性和特性,反驳了一些声称不需要 React Query 进行数据获取的观点。作者认为,尽管像 fetch-in-useEffect 这样的标准例子看似简单,但在处理边界情况和状态管理时,会引入诸多复杂性和问题。反观 React Query,它能解决这些问题并简化开发。优点包括自动防止竞态条件,免费获得加载、数据和错误状态,显然分离没有数据的状态,根据需要获取前一个类别的数据或错误等。作者最后挑战读者在下一个项目中尝试使用 React Query,他认为这不仅可以使代码更加易于维护和扩展,而且可以提供更强大的功能。

《re-re-reselct - 简化 React 状态管理》。 Causal 博客文章介绍了他们设计和实现的状态管理解决方案——Causal Selectors。文章先分析了管理复杂网页应用中状态数据的挑战,然后解释了两种类型的 Causal Selectors —— 叶子选择器和组合选择器的工作原理。文章还阐述了它们如何优化性能,减少不必要的重渲染,并与React进行整合。但新框架的初步效果并不理想,所以他们通过优化选择器的性能和订阅管理,最终使其性能回到原始水平,同时使状态管理更容易使用。他们计划完成所有组件的迁移,缓存拓扑排序以增加速度,并将状态从Redux移出,以便更好地管理后端查询的状态。

《利用 NextJS、Trigger.dev 和 GPT4 打造一款简历制作工具》。 本文教你如何使用 NextJS、Trigger.dev、Resend 和 OpenAI 创建一个简历生成器。内容包括基本信息(如名字、姓氏以及最后工作的地方),生成和创建 PDF, 最后发送给你的邮箱。我们使用 NextJS 创建一个简单的表单,使用 react-hook-form 进行字段验证和表单信息保存,利用 NextJS 提供的路由处理网络请求。我们利用 Trigger.dev 进行后台任务处理,例如用 ChatGPT 生成内容,创建 PDF 和通过邮件发送。然后通过 OpenAI 构建 ChatGPT,通过 jsPdf 库创建 PDF,最后通过 Trigger.dev 的 Resend 集成包实现邮件发送。 完整的源代码可以在 Github 上找到。

《React 设计模式》。 本文介绍了 React 设计模式,包括容器和演示模式,钩子组件组合,使用 Reducer 的状态管理,使用 Provider 的数据管理,使用 HOCs(高阶组件)进行组件增强,复合组件,属性组合,受控输入以及使用 fowardRefs 管理自定义组件等。通过运用这些设计模式和最佳实践,可以提升代码质量,推动团队协作,并让你的应用变得更加可扩展、灵活、可维护。

MDH 前端周刊第 113 期:Angular.dev & 17、pacquet、设计模式、Rust Prettier 悬赏

- - + + \ No newline at end of file diff --git "a/2023/11\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/11\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 8630511014..c57aadbc08 100644 --- "a/2023/11\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/11\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月26日内容汇总

· 12 min read
加菲猫

🌟 AI 相关

部署必备—triton-inference-server的backend(一)——关于推理框架的一些讨论

⭐️ Golang 相关

一文搞懂Go gRPC服务Handler单元测试

TCP 重传、滑动窗口、流量控制、拥塞控好难?看完图解就不愁了(重制)

揭秘 Go 中的模板:一份全面而广泛的指南

Kubernetes Pod 设计与实现 - 创建流程

2023年最新Docker网络讲解保姆级教程

Go语言项目命名规范(2023年最新版)

云音乐RPC稳定性建设与实践

完了,又被腾讯面试官拷打了 。。。

1.5万字+30张图盘点索引常见的11个知识点

Go 命名规范:全面指南

10个令人惊叹的Go语言技巧,让你的代码更加优雅

Go 内存分配:结构体中的优化技巧

注解方式优雅的实现 Redisson 分布式锁

Git 提交竟然还能这么用

Go怎么让协程跑一半就退出

从腾讯视频架构重构,看DDD的概念与方法

不少人面试都挂在这道题了!

99%的程序员容易忽视的“系统”健康问题

Kubernetes 探针设计与实现

Prometheus Go client library 详解

刷到一个比较骚的 Go 错误处理新提案。。。

Go 每日一库之 goose — 数据库版本管理工具

听GPT 讲Rust源代码--library/core/src(8)

我们公司都用哪些软件?强烈推荐这些!

微服务基本功:增加便利的监控服务指标

📒 前端相关

理解了Event Loop就理解了前端

微前端时代:打造高效、灵活的前端开发体系

函数组件 和 函数式编程 有关系么

「React 进阶」React 优雅的捕获并处理渲染异常

《别人不会告诉你的 10 个程序员工作的真相》。如何做合理的排期。例如,当项目经理要求你在周五之前实现 X 功能时,你不会说 "哦,我可以在周二之前完成"。相反,你会说"当然,没问题"。为什么?因为如果你承诺在周二之前完成,但遇到了一些问题,你就无法兑现承诺。相反,如果你接受周五为最后期限,并在周三之前完成,你就可以提前两天交付。关于如何进行估算,有很多公式,每个人都有自己的规则。我也有自己的规则。如果我需要交付某个功能,而我认为需要 2 天时间,为了安全起见,我会 多加大约 40% 的时间。因此,在这种情况下,预计时间是 3 天。之后,如果我在 2 天内完成了,我就可以提前交付。

《用 Rust 构建企业级 REST API》。 本文详细讲解了使用 Rust、Actix 网络框架和关系数据库开发企业级 REST API 的过程。文章从架构原则入手,分析了 API 的分层结构,着重解释了三个核心层级:基础设施层、服务层和存储 / 数据层。它详细介绍了使用各种流行的 Rust 插件和模式如何创建可测试和可维护的企业应用程序。讲解了如何进行单元测试每个层的可靠性,并提供了详细的代码示例。同时,文章指出设计中存在的问题,并讨论了可能的解决方案。最后强调了测试导向的开发方式和运用 OpenAPI 规范进行 API 文档化的重要性。

《在 Rust 中使用异步流》。 异步编程在处理随时间产生的数据(如网络响应或文件流)等程序性能提升方面非常有用。在 Rust 中,操作通常是同步的,即它们会阻塞线程直到完成。而异步操作允许在等待操作完成时运行其他任务,特别适用于 IO 绑定任务(如网络或文件操作)。Rust 的流可以被视为迭代器的异步版本,可以在整个序列准备就绪前,按照项目可用的顺序进行处理。Rust 的异步流主要通过 futures 和 tokio crates 实现。当处理大量随时间产生的数据,或无限序列(如股市报价)时,异步流是理想之选。在应用程序大部分时间都在等待 IO 操作的场景下,异步流可以显著提高吞吐量。对于需要实时处理数据的应用程序而言,如聊天应用,实时分析,或直播,异步流也十分有效。

《Rust 中的函数式编程模式》。 Rust 编程语言以内存安全和并发编程而闻名,但这并不是全部。实际上,Rust 在函数编程模式方面也有很强大的功能。尽管 Rust 不是纯函数式语言,但它借鉴了很多函数式编程的范例,使你能编写出清晰易维护的代码。函数式编程将计算视为数学函数的求值过程,并避免改变状态和可变数据。面向对象编程(OOP)围绕封装了状态(数据)和行为(方法)的对象来展开,依赖类的概念作为对象的蓝图,并常常使用继承来在类之间共享和扩展行为。而函数式编程(FP)侧重于没有状态的函数,它们操作不可变数据,函数充当一等公民,被用于抽象、封装和组合,迭代过程通常通过递归来表达。

《将 Javascript 应用程序部署到 Kubernetes 的最快方法》。 这篇文章教你如何将你的第一个 JavaScript 应用部署到 Kubernetes(一个容器编排平台)上。我们将使用 Minikube 在本地部署一个返回样本 JSON 对象的简单 Express 服务器。首先,我们通过 npm 初始化项目,并在 package.json 中安装 Express.js 框架。然后我们创建一个服务器,并使用 npm 运行它,确保它能够正确响应 GET 请求。接着,我们编写 Dockerfile 并用 Docker 构建和运行容器。最后,我们开启 Minikube,并使用 kubectl 执行部署 yaml 文件,成功将 Express 服务器部署到本地 Kubernetes 中。

《async Rust 的四年计划》。 本文作者讨论了四年前 Rust 发布的 async/await 特性,并指出 Rust 项目在此功能上几乎没有扩展。作者认为这是 async Rust 获得负面评价的主要原因。文章中,作者列出了他认为 async Rust 需要的一些功能,包括短期、中期和长期的功能。短期功能主要包括 AsyncIterator 和 async generators;中期功能包括 Objective-safe coroutine 方法和 Async destructors;长期功能包括改变 Rust 的一些基本规则。他建议 Rust 项目应有更清晰的开发方向和与社区的交流,并感谢那些在设计问题上与他交流的项目成员。

《React Router v6:新手指南》。 React Router 是 React 的标准路由库,能够管理具有多个视图的 React 应用的 URL。本教程介绍了 React Router v6 及其用法,包括基础导航路由、嵌套路由、带路径参数的嵌套路由和保护路由。在 React Router v6 中,使用 <Routes><Route> 组件进行路由,可以在 <Routes> 组件中嵌套 <Route> 组件以方便实现嵌套路由。还可以使用 useParams 钩子访问 URL 参数,useNavigate 钩子进行程序化导航。此外提供了用于实现路由保护的自定义路由。React Router v6.4 版本引入了由 Remix 启发的新特性,包括数据加载器和 create BrowserRouter,以改进数据获取和提交。

《掌握在 React 中使用 Framer Motion 进行 SVG 动画》。 本指南探讨了如何在 React 应用程序中使用 Framer Motion 动画库来创建 SVG 动画。首先,我们需要在 React 项目中安装 Framer Motion 并为动画准备 SVG。然后了解 Framer Motion 的动画原理,包括 motion 组件和 animate 属性的使用,在此基础上创建简单和复杂的 SVG 路径动画。进一步讲解了如何为常见的 SVG 形状添加动画,如何使用键盘事件等用户交互事件进行交互性动画设计,以及如何优化动画性能。无论是创建简单的悬停效果还是复杂的入场动画,Framer Motion 都提供了丰富的创意工具,使 SVG 动画的缩放和性能优势得以充分发挥。

MDH 前端周刊第 114 期:Vite 5、Prettier 3.1、恶意软件、FramerMotion SVG 动画、桶文件

- - + + \ No newline at end of file diff --git "a/2023/11\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/11\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index be09400c3a..5d925a91d4 100644 --- "a/2023/11\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/11\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

11月5日内容汇总

· 2 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

通过redis学网络(1)-用go基于epoll实现最简单网络通信框架

【升职加薪秘籍】我在服务监控方面的实践(2)-监控组件配置

玩转 Go Slices 切片泛型库

Go etcd 的依赖问题终于解决了。。。

史上最全后台开发成长指南

如何更直观地理解 Go 调度过程

在 Go 中管理多个数据库连接

动动手指,Prometheus 部署流程收入囊中

iptables 以及 Go操作库

给 Go 提问题?充分了解 Go 提案流程

像Redis作者那样,使用Go实现一个聊天服务器,不到100行代码

Go语言爱好者周刊:第 203 期 — encoding/json 升级版你支持吗

📒 前端相关

Speeding up the JavaScript ecosystem - Tailwind CSS

辟殊 - Rust 在前端构建高性能前端打包工具

Announcing Docusaurus 3.0

2023年软件工程师的 Mac 工具箱

如何让开发者丝滑的接入你的组件库

chrome 升级 117后可能会导致你的网站无法访问

让 web 再次伟大:用 CanvasKit 实现超级丝滑的原神地图(已开源)!!!

MDH 前端周刊第 111 期:MSW 2、Yarn 4、Next.js 14、useFormSate、WinterJS

- - + + \ No newline at end of file diff --git "a/2023/12\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/12\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index d0075b2c1c..cda842a6a0 100644 --- "a/2023/12\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/12\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月10日内容汇总

· 4 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

《大明王朝》沈一石的“生机”

用Rust刷LeetCode之26 删除有序数组中的重复项

Spring Boot 单体应用升级 Spring Cloud 微服务

2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

[go 面试] 一致性哈希:数据分片与负载均衡的黄金法则

依赖注入与控制反转:优化Go语言REST API客户端

书籍推荐: 深入理解Go并发编程

《大明王朝》阴阳对垒,千里布局

Redis 除了用作缓存还能干吗

万字串讲 git 版本控制底层原理及实战分享

如何提升研发效率-工具篇

用Rust刷LeetCode之66 加一

从底层逻辑聊日报如何提升公司效率

GORM最佳实践之不定参数的用法

[go 面试] 深入理解并发控制:掌握锁的精髓

OpenTelemetry Metrics 基础

模型服务网格:云原生下的模型服务管理

刚刚 Go 发布了 Go 1.21.5 安全补丁更新

Go errors 默认加堆栈信息,有用不

有效表达软件架构的最小图集

高并发场景下JVM调优实践之路

使用Rust Rayon库提升程序运行速度

没错,数据库确实应该放入 K8s 里!

更高精度的 Sleep

[go 面试] 接口测试的方法与技巧

Go 1.21.5 发布了

[go 面试] 前端请求到后端API的中间件流程解析

这个限流库两个大bug存在了半年之久,没人发现

手把手教你写设计方案

精要主义:你的生活是否一团乱麻

深入理解Go标准库-ServeMux的使用与模式匹配

如何一键生成前端代码

微服务架构是如何演进的

空降:新官的三把火会如何烧

一文搞懂Go gRPC服务Handler单元测试

把数据库放入 Docker是一个好主意吗

如何保留 Go 程序崩溃现场

2023年 Go 并发库的变化

Go Kit中读取原始HTTP请求体的方法

📒 前端相关

Facebook、Instagram 都在用的 CSS 解决方案开源了!

你了解 JSX,那你了解 StyleX 么

如何实现原生的 “跨组件” 通信

前端开发者们,这些知识tips你必须知道

封装一个用户体验非常棒的下拉选择框

译:Prettier 的命令行界面:性能深度剖析

京东快递小程序分包优化实践

MDH 前端周刊第 116 期:Astro 4 Beta、XState 5、Fresh1.6、Prettier 性能、Biome

- - + + \ No newline at end of file diff --git "a/2023/12\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/12\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 41928242d4..26c3523fc8 100644 --- "a/2023/12\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/12\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月17日内容汇总

· 6 min read
加菲猫

🌟 AI 相关

【AIGC篇】NLP任务入门:分词、词性标注与命名实体识别

CPU 混合推理,非常见大模型量化方案:“二三五六” 位量化

⭐️ Go & 云原生 & Rust 相关

谷歌的开源供应链安全

盘点2023年在地球上举行的Gopher盛会

深入理解 Go Modules:高效管理你的 Golang 项目依赖

通过实例理解OAuth2授权

从方法论到最佳实践,深度解析企业云原生 DevSecOps 体系构建

Golang的websocket使用和实现代码分析

容器故障?别慌:debug 不行,还有superdebug

放弃自己造轮子,才能给微服务搭一个牛X的注册中心!

「GoCN酷Go推荐」我用go写了魔兽世界登录器

卷起来,老程序员也得了解errors包的新变化

什么是大端序和小端序,为什么要有字节序

Go Testing By Example--Russ Cox在GopherCon Australia 2023的演讲

回归单体成为潮流?腾讯文档如何实现灵活架构切换

成功上岸Go面经:百度滴滴小米360小红书展盟优咔科技

奶茶上云,原生的更好喝

[go 面试] 雪花算法与分布式ID生成

简单之道

如果你还对Go并发编程感到迷茫,也许是好事情

用Rust刷LeetCode之27 移除元素

Go函数指针是如何让你的程序变慢的

Go单线程运行也会有并发问题

Kubernetes 是怎么靠边车模式打败Docker的

Go语言中常见100问题-#92 Writing concurrent code that leads to false

Go Changes--Russ Cox在GopherCon 2023的演讲

Go未来演进:基于共同目标和数据驱动的决策

Go 语言字符串使用方式与技巧

📒 后端相关

CentOS7下快速搭建K8s集群实践

MySQL 深入学习总结

哈啰一面:如何优化大表的查询速度

面试官:网关如何实现限流

从零开始:使用Prometheus与Grafana搭建监控系统

给祖传系统做了点 GC调优,暂停时间降低了 90% | 京东云技术团队

MYSQL 事务的底层原理 | 京东物流技术团队

直播房间服务基于CQRS的架构演进实践

高并发系统设计的15个建议

《大明王朝》局部最优,严嵩父子的牢笼

Nacos 2.3.0 正式版发布,Nacos Controller 项目开源

关于消息队列的知识总结

从实现原理来讲,Nacos 为什么这么强

什么Leader值得追随

西瓜视频RenderThread引起的闪退问题攻坚历程

MyBatis Plus 解决大数据量查询慢问题

好好的“代码优化”是怎么一步步变成“过度设计”的

聊聊工作中常用的方法论

GitHub.com跑了1200多台MySQL主机,如何无缝升级到8.0

《瞬变》卡点的原因往往简单而愚蠢

从一个crash问题展开,探索gcc编译优化细节

放弃 ELK!SpringBoot接入轻量级分布式日志框架GrayLog

腾讯有点顶,连环追问我基础细节!

无语!我是来面Java的,你怎么问我大数据的Kafka

系统性思考:你考虑过传话筒的感受吗

📒 前端相关

StyleX:Meta 新出的原子化 CSS in JS 方案

网易云音乐 RN 新架构升级实践

【第3140期】在 Console 中更直观地展示 Reactive Objects

DevTools 不让粘贴执行代码了

深入浅出 Vite5 中依赖预构建

Chrome 120 有哪些值得关注的更新

微前端项目难点解决

MDH 前端周刊第 117 期:stylex、Vitest 1、Astro 4、React Forget、TanStack 路由

- - + + \ No newline at end of file diff --git "a/2023/12\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/12\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 2713e18387..d75fd37cde 100644 --- "a/2023/12\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/12\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月24日内容汇总

· 14 min read
加菲猫

🌟 AI 相关

多模态融合:基于机器学习的文本图像关联分析

⭐️ Go & 云原生 & Rust 相关

用Rust刷LeetCode之58 最后一个单词的长度

Golang优雅实现按比例切分流量

AIOps在美团的探索与实践——事件管理篇

通过实例理解OpenID身份认证

Rust中peekable的使用

Nacos 在云原生架构下的演进

智能化运维:KoPylot为k8S带来AI监控诊断

Kubernetes EndPoint 设计与实现

Kubefirst:新手也能轻松快速打造生产就绪K8S平台

轻松提升Golang日志性能:无需修改代码的异步写入解决方案

10个令人惊叹的Go语言技巧,让你的代码更加优雅

Go 1.22 RC1 发布新特性:for range, math/rand/v2

Kubernetes Informer 设计与实现 (下篇)

鲜有人了解的同步原语Phaser,和Barrier有啥区别

当 OpenTelemetry 遇上阿里云 Prometheus

Go Context 到底放第一个参数传,还是放结构体里

Kubernetes Informer 设计与实现 (上篇)

为大模型工程提效,基于阿里云 ACK 的云原生 AI 工程化实践

Go 语言为什么很少使用数组

每个Go程序员必犯之错

Go语言爱好者周刊:第 205 期

📒 后端相关

腾讯工作13年之所思所想,那些优秀程序员的共性特征

半年下云省千万:DHH下云FAQ答疑

用ElasticSearch时,必须先搞明白这几个基础

一文详解 Java 限流接口实现

什么时候都用微服务,只会害了你

对抗复杂度的圣杯战争:软件架构究竟该如何设计

如何应对 RocketMQ 消息堆积

年底了,应该如何做汇报

从腾讯视频架构重构,看DDD的概念与方法

DDD架构下的防御式编程:5大关卡共同保障业务数据的有效性

银行软开,不难!

每天精心Coding 8小时,3个月后你将得到一座……“屎山”

欺上瞒下:什么是信息差创造价值

TLA+ 入门教程(4):两阶段提交

TLA+ 入门教程(5):Paxos

TLA+ 入门教程(6):Raft

Paxos vs. Raft:共识算法的相同点和不同点

ZooKeeper 设计原理

主从复制(Primary/Backup Replication)

分布式数据库是怎么实现的

分布式存储系统在大数据处理中扮演着怎样的角色

30张图,搞懂分布式追踪系统

理解本质:从经济学角度看管理

8000字+22张图探秘SpringCloud配置中心的核心原理

MySQL高级进阶:索引优化

技术人必修课:利用金字塔原理高效思考与表达

MySQL 单表可以放多少数据,最多 2000 万

Redis数据已经删除了,为什么内存占用还是很高

4 个维度搞懂 Nacos 注册中心

Redis 性能优化 13 条军规

📒 前端相关

网易云音乐大前端监控体系(Corona)建设实践-开篇

字节前端监控实践

如何写好一篇技术分享文章

技术人如何做好业务

依枫在蚂蚁的四周年

How React 18 Improves Application Performance

重新思考 React 最佳实践

React Libraries for 2023

v0:AI 驱动的组件创造器正式开放

7个Js async/await高级用法

前端性能优化就是这么简单,你会了吗

《A 1-hour introduction to Next.js and React》。 本教程是一份关于如何使用 Next.js 14、React、Prisma、Tailwind 以及 MySQL 搭建 Twitch 克隆应用的全套课程,是 2023 年最新版本的第一部分。在课程中,学员将了解到如何使用 JavaScript 和 SQL 语言以及其他现代编程技术和工具,步步为营地创建出一个功能完整,外观现代的线上视频游戏直播平台。该实战课程为初级到中级开发者设计,旨在提升学员记录写代码、解决问题和探索新技术的能力,最后成功搭建出 Twitch 样式的应用。

《React Suspense 和 use Hook 使用指南》。 React 的 Suspense 在 React 18 的版本中得到了重要的升级,包括对服务端渲染流和局部 hydration 的支持,并且最近在新版的 React 文档中记录了一个名为 use 的新钩子,这能大大简化 Suspense 在数据获取环节的使用。然而,Suspense 在数据获取环节上的功能并未被 React 团队认为是足够成熟且适合在生产中使用的,因此并未推荐在生产环境中使用。此外,尽管进行了新增并进行了升级,但是 use 钩子并没有被作为 React 稳定版本的一部分对外发布,要想尝试使用它,您需要使用 canary 或 experimental 的 React 渠道。Suspense 目前的使用场景包括错误隔离与数据获取等。而有趣的是,use 钩子可以在条件和循环等特殊场景下使用,扩大了 Suspense 的实际使用场景。

《开始使用 Axum - Rust 最受欢迎的 Web 框架》。 本文详细介绍了 Rust 后端框架 Axum 的使用方法,包括路由设置、连接数据库、实现 App 状态、使用 Extractors 等。Axum 对 REST 风格的 API 和 Express 风格的 API 都有很好的支持,可以通过 handler 函数轻松设置路由。在数据库设置中,可以通过 Shuttle 来进行简化操作。对于 App 状态的设置,通常是使用 struct,并需要实现 Clone。对于 HTML 识别,我们可以使用 axum::Json 来将 HTTP 请求转为 json 格式。并且,axum 与 tower 有很好的兼容性,可以直接使用 tower 中的 middleware。还介绍了如何通过 Axum 来服务静态文件,如何部署 Axum 等问题。总的来说,Axum 是一个有强大团队支持且与 Rust Web 生态系统高度兼容的框架,现在是开始编写 Rust Rest API 的好时机。

《常见的 Rust 生命周期误解》。 在 Rust 中,泛型 T 包括所有可能的类型,包括 &T 和 &mut T,且不能直接指定某种数据类型。另外,生命周期'static 指的不是变量数据所存在的全部时间,它包括所有 &'static T 以及所有拥有类型,比如 String,Vec 等。同时要清楚,几乎所有的 Rust 代码都是泛型代码。此外,生命周期不能在运行时变化,生命周期都是在编译时静态验证的,生命周期不能在运行时增长或缩小或以任何方式改变。Rust 的生命周期推断规则并不总是正确的,Rust 并不比你更了解你程序的语义。由于 Rust 可以隐式地重新借用 mut ref,所以你可能在意识到这个问题之前很容易碰到这个问题。这些都是对于 Rust 中的生命周期的误解。

《用 Rust 编写操作系统》。 这份博客系列从零开始用 Rust 编程语言写一个操作系统,由浅入深地演示和讲解了用 Rust 编写操作系统的全部过程。包括最基础的内核构建、异常处理、硬件中断、内存管理以及异步等关键部分,以及操作系统设计的各种常见问题和解决办法,不仅提供了完整的教程,同时也在 Github 上公开了所有相关的源代码。

《从零开始用 Rust 编写文件系统》。 本文详细阐述了文件系统 (File System) 的工作原理和各部分组成,包括数据在硬盘或 SSD 上的结构、超级块和位图、i 节点、索引节点、数据块及其用途,以及多层次索引等概念。文章也解释了如何通过文件系统构建和管理磁盘的不同部分,以及文件和目录在文件系统中是如何表示的。最后,作者通过一个名为 GotenksFS 的项目,展示了如何用 Rust 语言编写自己的文件系统,并在其中实现了一些 ext4 的技术。

《Non-lexical lifetimes: introduction》。 这篇文章探讨的是 Rust 的借用检查器和对生命周期的理论,在 Rust 中,借用检查器确保在值被借用期间,不能对其进行移动或修改。这是通过为每次创建的借用分配生命周期去实现的。文章分别详述了生命周期和范围的概念,并通过实例阐释了它们之间的关系。接着给出了几个在实际编程中遇到的问题案例,再就这几个案例,作者展示了如何通过调整代码结构的方式绕过 Rust 现有的编译检查。作者表示这样的做法并不理想,并提出了通过改进编译器来解决这个问题的计划。

《2024 年的 React 状态管理》。 本文作者从三个角度对 React 状态管理库进行了分类:基于 reducer 的,如 Redux 和 Zustand;基于 atom 的,如 Recoil 和 Jotai;基于 mutable 的,如 MobX 和 Valtio。每种方法都有其优势和劣势。Reducer 的优势在于其强大的状态机和时间机制,对于开发者工具的支持最好,但是需要编写大量的模板代码,学习曲线陡峭。Atom 的优势在于对 React 特性的充分利用,具有简单和可扩展性,但对开发者工具的支持较弱,不能在组件外使用状态。Mutable 往往提供最简单的 API,并具有高度的灵活性和反应性,但 “自动反应” 也可能带来问题,可能导致数据竞争和异步更新问题。作者个人更偏向于使用 Jotai,因为它没有键的要求,更加高效。

《介绍 Waku》。 Waku 是一款 React 的微型框架,它支持探究 React 服务器组件(RSC)的核心功能,并独立于传统的静态站点生成(SSG)和服务器端渲染(SSR)策略来发现 RSC 最佳实践。Waku 基于 Vite,并尽可能依赖其 API 和生态系统。其服务器入口 API 使用名为 entries.tsx 的文件,该文件位于 src 文件夹的根目录,并返回一个包含 JSX 元素的对象。客户端会向服务器发送初始请求,得到服务器的响应并通过 Slot 组件进行渲染。为了使 Waku 支持在 Vercel 上部署,利用了其构建输出 API,通过自定义 “content-type” 头部并以函数方式定义 Waku 服务器,实现了客户端发送请求到服务器并返回 RSC 负载的功能。

MDH 前端周刊第 118 期:Electron 28、Safa 17.2、SvelteKit 2、状态管理、Waku

- - + + \ No newline at end of file diff --git "a/2023/12\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/12\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 917f144e3b..7504e5a33b 100644 --- "a/2023/12\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/12\346\234\21031\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月31日内容汇总

· 6 min read
加菲猫

🌟 AI 相关

秒速出图!体验 TensorRT 加速 Stable Diffusion 图像创作

⭐️ Go & 云原生 & Rust 相关

2023年Go语言盘点:稳中求新,稳中求变

Rust开发⼲货集(1)--迭代器与消费器

轻松实现Go应用的优雅关闭:提升服务质量与稳定性

今天把 Rust 更新到最新的 1.75 版本,跑一下 rustup update 这个命令就行:

$ rustup update
info: syncing channel updates for 'stable-aarch64-apple-darwin'
info: latest update on 2023-12-28, rust version 1.75.0 (82e1608df 2023-12-21)
info: downloading component 'rust-src'
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: removing previous version of component 'rust-src'
info: removing previous version of component 'cargo'
info: removing previous version of component 'clippy'
info: removing previous version of component 'rust-docs'
info: removing previous version of component 'rust-std'
info: removing previous version of component 'rustc'
info: removing previous version of component 'rustfmt'
info: installing component 'rust-src'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
info: installing component 'rust-std'
info: installing component 'rustc'
info: installing component 'rustfmt'
info: checking for self-update

stable-aarch64-apple-darwin updated - rustc 1.75.0 (82e1608df 2023-12-21) (from rustc 1.69.0 (84c898d65 2023-04-16))

info: cleaning up downloads & tmp directories

$ cargo --version
cargo 1.75.0 (1d8b05cdd 2023-11-20)

2023 文章集锦

《深入理解Rust并发编程》可以下载了

你可能不知道的Go语言小细节【文末赠书】

C++中的同步原语

Kubernetes Daemonset 设计与实现

Go 1.22 http.ServeMux中的模式匹配

熔断、隔离、重试、降级、超时、限流,高可用架构流量治理核心策略全掌握

新提案:Go panic 能不能加个 PanicError

Go语言“正统”在中国?这6点教你写好Go代码!

Go 1.22新特性前瞻

Kubernetes ReplicaSet 设计与实现

新包降临 math/rand/v2, 在Go 1.22中

北海 - Rust与面向对象(四)

北海 - Rust与面向对象(三)

【投稿】北海 - Rust与面向对象(二)

微服务配置中心, 这个方案 Go 里用起来不输 SpringCloud

从Go channel中批量读取数据

Go语言的自给自足:编译自身的神奇之旅

圣诞福利|吃透Go并发编程,看这本书就够啦

📒 后端相关

Spring Boot 单体应用升级 Spring Cloud 微服务

账号多租户架构升级与落地实践

每天100w次登陆请求, 8G 内存该如何设置JVM参数

从混乱到优雅:基于DDD的六边形架构的代码翻新指南 | 京东物流技术团队

从工程师到技术leader的思维升级

设计一个海量的任务调度系统

公司用了6年的 SpringBoot 项目部署方案,稳得一批!

慢聊Golang协程池Ants实现原理

Redis主从复制原理和复制方式那点事!

Redis为什么使用哈希槽而不用一致性哈希

不愧是字节,面个实习也满头大汗!

可观测实践丨如何利用 AI 算法解决告警配置三大难题

管理的焦虑:技术丢了怎么办

监控告警系列-使用Promethues监控系统指标并进行告警通知

📒 前端相关

如何写好一份晋升PPT(附PPT模板)

前端DevOps平台的探索及设计理念

​云音乐D2C设计稿转代码建设实践

Esbuild深度调研:吹了三年,能上生产了吗

【第3156期】突破 ToB 前端开发场景中的 antd Table 性能瓶颈

⚡️卡顿减少 95% — 记一次React性能优化实践(性能篇)

从 0 到 1 构建基于 Node.js 的 RPC 服务

字节三年,谈谈一线团队如何搞工程化一(全景篇)

2023 年前端大事记

前端基建处理之组件库优化方案

网易云音乐 RN 低代码体系建设思考与实践

可视化全链路日志追踪

NodeJs进阶开发、性能优化指南

- - + + \ No newline at end of file diff --git "a/2023/12\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/12\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 404fa99c55..e20f442680 100644 --- "a/2023/12\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/12\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

12月3日内容汇总

· 12 min read
加菲猫

🌟 AI 相关

TensorFlow.js,让你的应用更加高级,更具逼格

为什么你应该把 Google / StackOverflow / 文档搜索都扔掉,改用 devv.ai

本地运行“李开复”的零一万物 34B 大模型

⭐️ Golang 相关

亲测体验Go语言PGO

降本增笑的P0事故背后,是开猿节流引发的代码异常吗

通过实例理解API网关的主要功能特性

编码相关的软技能,我看了这些书

1.5万字 + 25张图盘点RocketMQ 11种消息类型,你知道几种

为什么要建立研发数据指标

分享几个美团的秋招面试题

[go 面试] 为并发加锁:保障数据一致性(分布式锁)

使用Go Validator在Go应用中有效验证数据

Rust的Vec优化

如何在Go中进行内存优化和垃圾收集器管理(GC)

[go 面试] 并发与数据一致性:事务的保障

利用 Golang 中的 Recover 处理错误

向上管理:让你主动汇报就这么难

刷新了对GODEBUG的认知

[go 面试] 深入理解进程、线程和协程的概念及区别

如何成为优秀工程师之软技能篇

新晋总监生存指南

从单体到微服务,腾讯文档微服务网关工程化的演进实践

颠覆认知——Redis会遇到的15个「坑」,你踩过几个

正式开源!高性能轻量级跨平台QUIC协议库TQUIC来啦!

如何基于PrometheusAlert扩展告警值班功能

一线Leader怎么做?经理的速成宝典

Rust内存布局

使用 sync.Cond 来协调并发 goroutine 的访问共享资源

降本增效 - 应用优化 (三) 日志成本降低 100 倍

干掉复杂代码 — Spring Boot 与 CQRS 才是黄金组合!

go 1.22优化了string转byte切片的实现

分布式锁的各种实现,看完这篇你就懂了!

结合图文一起搞懂MySQL事务、MVCC、ReadView!

如何使用Redis数据类型进行亿级别统计数据

「有问必答」秒杀系统 Go并发编程实践!

当「华为还是备选,迪爹还是迪子」时宇宙厂一面原题

Prometheus 的查询语言 PromQL 详解

数据库死锁排查思路分享(纠正篇)

学习gorm系列八:探秘gorm.Save函数

一文搞懂Go gRPC服务Handler单元测试

第三个五年,独立思考、承受风雨

第二个五年,找到擅长的事

4 种消息队列,如何选型

Go语言中常见100问题-#91 Not understanding CPU caches

Go HTTP GET 请求可以发送 body 吗

📒 前端相关

【第3130期】Taro高性能小程序的最佳实践

Solid 作者从 React 中学到最重要的是什么

8个问题带你进阶 React

Next.js 超实用进阶技巧【持续更新】

嘿,vue中keep-alive有个「大坑」你可能还不知道

两行CSS让长列表性能渲染提升7倍!

《Why Rust in Production》。 近年来,Rust 的热度已经飙升,微软、谷歌、亚马逊等科技巨头正积极把 Rust 的优势应用于关键系统。然而,关于 Rust 的讨论仍然大多来自那些没有在大规模生产中使用 Rust,或者仅在非关键系统中使用过 Rust 的人。这导致对 Rust 在生产环境中应用的理解存在偏差,尤其对于中小企业来说更是如此。作为 Rust 顾问,从我与众多大小公司接触中发现,公司更看重效率、稳定性和长期可维护性,而不只是性能。然而,Rust 也有其缺点,如尚处在成熟中的生态系统,硬寻找拥有专业 Rust 经验的开发人员,编译时间较长等。尽管如此,这些挑战并不是难以克服的,只是需要对 Rust 承诺,并愿意投资于培训和工具。考虑到 Rust 所能带来的长期成功,专门的指导和支持是至关重要的。

《Building a Web App in Rust》。 这篇文章分享了作者使用 Rust 编程语言构建网络应用程序 JustFax Online 的经验。作者热爱 Rust 的理由包括其低内存使用、出色的安全性、异步开发、真正的类型安全性等优点。然而,作者也谈到了 Rust 的一些困难之处,例如借用检查器的复杂性、对于初学者的启动难度、相对较长的编译时间以及与 NodeJS 或 Python 相比较小的生态系统。尽管如此,作者仍表示非常享受使用 Rust 构建项目,并认为他能有效运行许多项目而无需花费大量资金。

《Rust without crates.io》。 文章提到了程序员对 crated.io 让大家自由上传和下载代码的依赖,并指出了这种行为的潜在风险:包括单点故障、黑客攻击、国家安全等问题。作者认为,我们应该从开发速度的祭坛上退后一步,理想情况下需要有一个独立于作者进行策展的角色来审视依赖。然而在现实中,这种人力评审的路径很难实现。对此,Linux 发行版如 Debian 的解决方案是将大量库的完整 Rust 源码打包进 librust-cratename-dev,虽然没有进行审计,但已经是一个很大的改进。此外,作者也介绍了如何通过几个简单的命令来实现这一过程。这给予作者对 Rust 更大的信心,他原本担心由 crates.io 的自由选择依赖版本的方式,抵制任何旧方法的语言,例如 C++。幸运的是,Debian 证明了他是错误的。

《我如何将 Rust 的编译时间提高 75%》。 这篇博客主要关于如何改善 Rust 编译时间,通过使用不同的优化方法和替代的编译器链接器。作者测试了多种不同的方法,包括使用 Mold 链接器,Cranelift 编码器,和更高的优化等级,他发现使用 Mold 链接器和 Cranelift 代码生成器可以最大程度地提高编译速度,能使编译时间分别减少 75% 和 25%。此外,博主对 Rust 的热重载提出了替代方法,即 cargo-leptos 的 --hot-reload 标志,它可以在更改检测时通过 web socket 连接向浏览器发送 html 和 css 补丁,并在后台编译。

《我怎么知道自己做得对不对》。 作者分享了自我学习新技术时的验证假设与自我提升的有效方法。首先,查找可靠的文档和示例,如 MDN 和 web.dev,他们通常能以实际用例解释理论知识;其次,利用编程语言的 linter 插件指导编程,这有助于改进编码习惯;接着,使用诸如 Lighthouse 和 Accessibility Insights 等测量性能的工具以评估是否妥协了性能或可访问性;此外,利用 AI 工具如 Copilot 简化代码。但对于新手来说,要对 AI 生成的指导持怀疑态度;也可以通过向行业内人士询问学习新信息的方式,来学习。最后,查找有关主题的教程以对照使用情况。学到新知识后,应考虑写下来分享,提高自我理解和提高他人。

《React 18 中的并发性》。 React 18 新增的并发功能是一种执行模型,允许程序的不同部分无序执行而不影响最终结果。在浏览器中的 JavaScript 只能访问一个线程,因此采用了一种称为协作多任务处理的并发模型。React 18 分为紧急状态更新和转换状态更新两种更新类型。默认情况下,所有状态更新都是紧急的,不可中断的。如果希望进入并发渲染,需要使用 startTransition 或 useDeferredValue 将更新标记为低优先级。若在渲染低优先级更新时出现高优先级更新,React 会中断当前渲染并转向渲染高优先级更新。另一个重要更新是 Suspense 组件的行为,它在低优先级更新过程中的挂起行为稍有不同。还引入了新的钩子函数 useTransition 和 useDeferredValue,使用这些工具可以处理复杂的状态更新场景。

TypeScript 发布 5.3。 微软发布了 TypeScript 5.3 版本,主要引入了众多新特性,包括导入属性和稳定地支持在所有模块模式中使用 resolution-mode。此外,这个版本提供了针对布尔值的缩窄对比,以及通过 Symbol.hasInstance 进行 instanceof 缩窄。对于 “超级” 的属性访问,TypeScript 5.3 还进行了检查。此外,新版本中的其他改进包括跳过 JSDoc 解析以进行优化,比较非标准化交集以进行优化,以及在 tsserverlibrary.js 和 typescript.js 间进行整合。这个新版本还修复了一些断裂的变化,并进行了正确性改进。

MDH 前端周刊第 115 期:TypeScript 5.3、RSC、30 条建议、0.6 + 0.3、CI 时间

- - + + \ No newline at end of file diff --git "a/2023/1\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/1\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 33a7970e0f..9f43d24e9f 100644 --- "a/2023/1\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/1\346\234\21015\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月15日内容汇总

· 10 min read
加菲猫

📒 相关文章推荐

Gluon:基于网站创建桌面应用的框架 — 这是一种使用 Node 和已安装的浏览器把 Web 站点构建为桌面应用的新方案。值得注意的是,Gluon 同时支持 Chromium 和 Firefox。Deno 也可以替代 Node。已经支持 Windows 和 Linux,本周刚刚完成了对 macOS 的初步支持。

https://gluonjs.org/

Node v19.3.0 (Current) 发布 — 这是几周前发布的版本,v19.3 是一个典型的增量更新版本,内容包含了 npm 升级到 v9.2.0,这本身是一个足够需要阅读发行说明的内容。

https://nodejs.org/en/blog/release/v19.3.0/

构建同构 JS 库的五大挑战 — 同构(isomorphic)的意思是代码可以同时在客户端和服务器上以最小调整就可以运行的代码或者库。

https://doordash.engineering/2022/12/06/five-challenges-to-building-an-isomorphic-javascript-library/

2023 年如何发布 npm — 这是一个指南,描述了如何在 2023 年将开源包发布到 npm 以及需要注意的事项。如果你想在 2023 年编写和发布一个包,你需要用 Typescript 编写它并将其发布为 ES 模块。

https://blog.taskli.st/posts/how-to-publish-to-npm-in-2023

🌟 2022 年的 JavaScript 新星项目 — Michael Rambeau 第七次以 JavaScript 领域的"趋势项目"综述为我们的 2023 年度揭幕。Bun 占据了 2022 年的头把交椅,但我们会把其他的留给你去看。一些特邀作者也分享了他们对生态系统的看法。

https://risingstars.js.org/2022/en

Evan You 回顾 2022 年与展望 2023 年 — 你可能会因为 Vue.js 和 Vite 而认识 Evan,在这里他回顾了 2022 年 Vue 世界发生的事情(比如 Vue 3.x 成为新的默认版本)以及我们在 2023 年 可以期待的事情,包括神秘的 Vapor 模式。他还提醒我们,Vue 2.x 还有一年才会失效。

https://blog.vuejs.org/posts/2022-year-in-review.html

JS Function Composition:有什么大不了的? — James 关于 JavaScript 基础知识的文章总是很受欢迎,去年我们得到了一篇新鲜的文章,关注一个常见的活动:函数组成。"这有什么大不了的?"他问道。

https://jrsinclair.com/articles/2022/javascript-function-composition-whats-the-big-deal/

开发人员面临的十个常见的 JavaScript 问题 — 这可是一篇好文章。如果你已经用 JavaScript 工作了很多年,这些都是你(可能)知道要避免的坑,但是这里有足够的东西可以让你反复思考。

https://www.toptal.com/javascript/10-most-common-javascript-mistakes

Storybook v7.0 进入 Beta 阶段 — 这是近两年来这个流行的前端 UI 开发工具的第一个大版本更新(这里会有 Breaking Change)。有很多新功能,包括性能改进、交互测试等等。在此查看 完整的更改日志。您现在可以通过 迁移指南 尝试 Beta 版。

https://storybook.js.org/blog/7-0-beta

在 React Native 中对 TypeScript 进行头等支持 — 随着新发布的 v0.71,你会得到一个新的“默认是 TypeScript (TS)”的应用程序模板 —— TS 声明随基本包一起发布,文档现在也是 TypeScript 优先的(当然,Flow 或常规 JavaScript 仍然是可以使用的)。

https://reactnative.dev/blog/2023/01/03/typescript-first

在 Reddit 上,有一个关于 为什么人们喜欢使用 Next.js 的讨论。

https://www.reddit.com/r/reactjs/comments/zprham/why_do_people_like_using_nextjs/

⭐️ Next.js 刚刚在 GitHub 中 超过了 Create React App 的 Star 数,如果你喜欢这种受欢迎程度的测量方式。

https://twitter.com/i/web/status/1610165503468658689

3 个导致 App 崩溃的 React 错误 — 一位名为 Jack Herrington 的 React YouTuber 讲解了三个编写 React 时会犯的错误(以及如何解决它们)。

https://www.youtube.com/watch?v=QuLfCUh-iwI

在 TypeScript 中像专家一样处理错误 — “学习我用来处理错误和编写更简洁代码的设计模式。”

https://engineering.udacity.com/handling-errors-like-a-pro-in-typescript-d7a314ad4991?gi=c2ed84ad0ecd

📒 了解JS静态分析,打开前端优化新思路

📒 用代码画一只小兔子给大家拜年啦!

📒 记落地vite到项目中的遇到一个bug, 最终被vite官方merge pr

📒 聊聊Go与TLS 1.3

📒 Google 出品的 Rust 教程

https://github.com/google/comprehensive-rust

📒 你可能并不需要微前端

📒 UMI 微生成器调研

https://umijs.org/docs/guides/generator

https://github.com/umijs/umi/blob/master/packages/preset-umi/src/commands/generators/component.ts

📒 【面试高频题】难度 3.5/5,综合最短路的 DP 问题

🌟 我的信息流 2023.1

⭐️ Go 1.19.5、1.18.10 更新涉及 compiler, linker, net/http, sync/atomic

📒 面试问 Dockerfile 的优化, 千万不要只会说减少层数

📒 Go 服务网络不通?net/http自带的这个工具帮你快速定位

📒 面试官:net/http库知道吗?能说说优缺点吗

⭐️ 模块联邦在微前端架构中的实践

📒 【综合笔试题】难度 4.5/5,经典次短路问题

⭐️ 加大力度!Go 将会增强 Go1 向后兼容性

⭐️ 聊聊Prometheus Gauge的增减操作实现

📒 Git操作不规范,战友提刀来相见!「文末抽奖」

📒 前端食堂技术周刊第 66 期:2022 JS Rising Stars、Lightning CSS、年度最受欢迎文章

📒 写出易维护的代码|React开发的设计模式及原则

📒 MDH 前端周刊第 82 期:Lightning CSS、Tailwindcss、HTTPie AI、chalk-next 投毒

《Zustand vs. Signals》,作者从 DX、性能和 Devtool 三个方面了对比这两个「小众」的状态管理库,简单说就是,1)Zustand 生态和周边更好,而 Signals 性能更好和更自动,2)作者下一个大型项目的选择还是 Zustand,因为对 Signals 的实践以及用的 React 内部 API 不太方向。

https://medium.com/@kevinschaffter/zustand-vs-signals-e664bff2ce4a

Evan You 写了一篇 《2022 Year In Review》,介绍 2022 总结和 2023 规划。2022 主要是默认 Vue 3、Volar 1、Vue Npm 下载量 x2、回传 Vue 3 功能的 Vue 2.7;2023 则是细粒度 Mirror 版本、类 Solid 的 Vapor Mode 编译模式等。

https://blog.vuejs.org/posts/2022-year-in-review.html

《How to ship》 包含了 4 个关于产品如何准时发布的 Tips,1)明确 MAVP(最小实际可行产品)的边界,注意不是偏 DEMO 类的 MVP,2)在前者的基础上削减范围,3)搭配可灵活调整的 Deadline,4)别让自己成为团队卡点。

https://www.industrialempathy.com/posts/how-to-ship/

《React ref Callback Use–Cases》,你可能不知道 ref 除了是 object 以外,还可以是 function,即 ref callback。ref callback 有一些应用场景,比如 mount 时(新增一个 list item 时)做滚动或聚焦、计算 DOM 尺寸或滚动位置、传递 DOM 给多个消费者等。

https://julesblom.com/writing/ref-callback-use-cases

《A React Developer’s First Take on Solid》,一个 React 开发者对 Solid 的第一印象。1)Solid 的优点是小和快,2)同时也有一些由于引入 Proxy 以及 Solid 不同的组件渲染机制后的缺点,比如 prop 不能在函数参数里析构等,3)SolidStart 是一个测试软件,有大量粗糙的边界场景,4)会在真实项目中用吗?不会!

https://jakelazaroff.com/words/a-react-developers-first-take-on-solid/

《Getting started with SolidStart》,SolidStart 入门文章,手把手教你写一个旅行 App。注:SolidStart 是基于 Solid 的元框架。

https://blog.logrocket.com/getting-started-solidstart-solid-js-framework/

《JavaScript Rising Stars 2022》,一年一期,这是第 7 期,可以了解 2022 JavaScript 社区的变化,但是以 Github Star 为衡量标准,并不能完全代表其流行度。

https://risingstars.js.org/2022/zh

MDH 前端周刊第 82 期:Lightning CSS、Tailwindcss、HTTPie AI、chalk-next 投毒

📒 2022 年前端大事记

⭐️ Go1.20 新特性:context支持自定义取消原因

⭐️ Go学设计模式--装饰器和职责链,哪个模式实现中间件更科学

📒 平时的工作如何体现一个人的技术深度?

📒 【第2832期】V8 执行 JavaScript 的过程

⭐️ Golang 库: 为什么 Golang slog 库不支持 Fatal

⭐️ Golang 库: golang slog 怎么设置日志 Debug 等级

⭐️ Golang slog 介绍

⭐️ 一文读懂 Go Http Server 原理

⭐️ 「每周译Go」了解 Go 中的 defer

📒 Go语言爱好者周刊:第 173 期 — 这个并发库真心好

- - + + \ No newline at end of file diff --git "a/2023/1\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/1\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 2ffb942b4e..f92f33e10b 100644 --- "a/2023/1\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/1\346\234\2101\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月1日内容汇总

· 11 min read
加菲猫

📒 相关文章推荐

一个关于 useEffect 的可视化指南 — 奇怪的是,最受欢迎的文章出现在 2022 年的第一期中。作者创建了一系列 React 渲染的可视化指南文章(比如关于 useMemo 和 props 的文章),在这篇文章中他把注意力转向了 useEffect。如果你想了解更多,还有一个关于 头等函数如何工作的可视化演示

https://alexsidorenko.com/blog/useeffect/

我们能承认 React Hooks 是个坏主意吗? — 第二受欢迎的项目是一个“快速链接”,但这个话题有足够的争议,让很多人谈论!Amy 认为“React Hooks 是个坏主意”。不管你喜不喜欢,你都会有自己的看法

https://medium.com/codex/can-we-all-just-admit-react-hooks-were-a-bad-idea-c48120c5188d

2022 React 库 — React 生态系统已经变得如此之大,问题更多的是选择太多,而不是没有需要的东西。如果您正在为一个新项目选择库,那么这个列表(Robin 多年来一直在更新)仍然很有用。希望我们能看到 2023 年的版本

https://www.robinwieruch.de/react-libraries/

回顾 2022 的 React 趋势 — 在今年年初,作者看了看他认为 2022 年重要的事情。他在 Remix、服务端渲染、并发渲染和行为测试方面做得很好,这些都是今年讨论最多的话题

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

Awesome React Components:一个精心整理的组件清单

https://github.com/brillout/awesome-react-components

React Render Tracker:发现有关意外重渲染的性能问题 — 这个工具可以显示组件树状态随时间变化的差异,这样您就可以更好地研究发生了什么

https://github.com/lahmatiy/react-render-tracker

Plasmo:“它就像浏览器扩展的 Next.js” — 一个面向 React 和 TypeScript 的框架,用于构建您自己的浏览器扩展

https://github.com/PlasmoHQ/plasmo

<ClickToComponent />:快速跳转到组件源代码

https://github.com/ericclemmons/click-to-component

要避免的 10 个 React 反模式 — 一个精心呈现的 8 分钟视频,快速介绍了各种替代的更优方法(或至少值得斟酌)

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 Golang 相关文章

Go 1.18 新增三大功能之一“模糊测试”使用方式

Go 1.18 新增三大功能之一“泛型”怎么使用

Go 语言开源项目使用的函数选项模式

Go 语言 context 最佳实践

Go 语言 errgroup 库的使用方式和实现原理

Go 语言一次性定时器使用方式和实现原理

  • new:为变量分配存储空间,返回指针类型,一般不常用
  • make:为复合数据类型(slicemapchan)分配存储空间

在 Go 语言中,原生类型都有默认值,即类型的零值

  • 布尔型的零值:false
  • 整型的零值:0
  • 字符串类型的零值:""
  • 指针、函数、接口、Slice、Map、Channel 的零值:nil

需要注意的是,Go 语言类型的零值初始化是递归完成的,即 数组结构体 的每个元素都进行零值初始化。

在 Go 语言中,推荐定义零值可用的结构体,不仅对程序的安全性和正确性非常重要,它还可以无需预先显式初始化即可直接使用,使 Go 程序代码更优雅。

Go 语言为什么建议定义零值可用的结构体

总结一下,短变量声明在同一作用域内重复使用,只是重新赋值,不会重新创建变量(即指针还是同一个),但是如果在不同作用域(例如 if 语句块),就会创建一个新的变量(内存地址与之前不同)。

Go 语言怎么解决编译器错误“err is shadowed during return”

Go 语言怎么处理三方接口返回数据

Go 语言使用 goroutine 运行闭包的“坑”

Go 语言内存逃逸案例

Go 语言逃逸分析

Go 语言怎么使用变长参数函数

Go 语言错误处理为什么更推荐使用 pkg/errors 三方库

Go 项目使用 Makefile

Go 应用程序设计标准

Go 语言整洁架构实践

Go 语言怎么使用 Docker 部署项目

Golang 语言怎么打印结构体指针类型字段的值

Golang 语言怎么避免空指针引发的 panic

Golang 语言该用命名返回值吗

总结一下:

  • unsafe.Pointer 主要用来实现 指针类型转换,任意指针类型 *T 都可以转换为 unsafe.Pointerunsafe.Pointer 可以转换为任何类型的指针值 *T
  • uintptr 主要用来实现 指针运算,实际是数值类型,可以用于存储内存地址。将 unsafe.Pointer 转换为 uintptr,然后使用 uintptr 值进行算术运算,最后将运算结果 uintptr 值再转换为 unsafe.Pointer

Golang 语言中的非类型安全指针

显式类型转换:

// 整型变量省略类型,编译器根据字面量推导默认是 int
var a = 100
a := 100

// 如果需要声明指定类型的整型变量,也可用显式类型转换,例如:
var a = int8(100)
b := int8(60)

变量声明块:

var (
a int = 100
b int = 200
)

var (
c = 300
d = 3.14
f = true
)

var (
e, f, g int = 10, 20, 30
h, i, j string = "a", "b", "c"
)

Golang 语言的多种变量声明方式和使用场景

Golang 语言中的内置函数 make 和 new

深入理解 go reflect - 反射基本原理

go interface 设计与实现

go Context 设计与实现

深入理解 go unsafe

📒 天呐!我用 go 从零开始写了一个 k8s 应用管理工具(附完整代码和开发过程)

⭐️ 没想到在 Docker 容器中设置时区这么简单

📒 先聊聊「内存分配」,再聊聊Go的「逃逸分析」

📒 字节一面:服务端挂了,客户端的 TCP 连接还在吗

📒 详解全网最快Go泛型跳表【内附源码】

📒 2022年Go语言盘点:泛型落地,无趣很好,稳定为王

📒 【第2824期】图解浏览器的多进程渲染机制

📒 在 Docker build 环境持久化 node_modules 目录

想在 docker build 环境中持久化 node_modules 需要使用到 BuildKitmount 功能,该功能有几个前置条件:

  • docker 版本必须高于 18.09
  • BuildKit 需要手工启用,可在 docker build 命令前添加环境变量 DOCKER_BUILDKIT=1 启用
  • 如果前两个条件不满足,则需要具备 Jenkins 和构建机的读写权限,以调整构建环境参数
  • 修改 Dockerfile,使用 RUN --mount=type=cache 运行 npm installnpm run build 指令(--mount=type=cache

开启 BuildKit 还有其他特性,比如输出日志更友好,基本每一步都会输出耗时,就这一条,值了!

实际操作分为 2 步:

修改 Jenkins 配置,在 docker build 命令前加上环境变量。修改后镜像构建命令长这样:

$  DOCKER_BUILDKIT=1 docker build .

修改 Dockerfile,将 RUN npm installRUN npm run build 指令前面加上 RUN --mount=type=cache npm xxx

FROM node:alpine as builder

WORKDIR /app

COPY package.json /app/

RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
--mount=type=cache,target=/root/.npm,id=npm_cache \
npm i --registry=https://registry.npmmirror.com/

COPY src /app/src

RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
npm run build

参考:

加3行代码减少80%构建时间

Docker 从入门到实践 - 使用 BuildKit 构建镜像

https://docs.docker.com/build/buildkit/

📒 Monorepo 下 Git 工作流的最佳实践

📒 Prometheus 数据存储那些事儿

📒 Go1.20 一次打破 Go1 兼容性承诺的真实案例

📒 基于 GraphQL 的云音乐 BFF 建设实践

⭐️ 【第2823期】打包JavaScript库的现代化指南

⭐️ 通过分析gin、beego源码,读懂web框架对http请求处理流程的本质

📒 极端情况下Go的Map也会发生内存泄漏

📒 这两个特性将在 Go1.20 中被弃用,受影响最大的居然是国内的面试官

📒 Go:讲一个故事说明使用汇编语言的必要性

📒 Go学设计模式--怕把核心代码改乱,记得用代理模式

📒 Go语言中常见100问题-#25 Unexpected side effects using slice append

- - + + \ No newline at end of file diff --git "a/2023/1\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/1\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e2abebdcfc..565b4e1e65 100644 --- "a/2023/1\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/1\346\234\21022\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月22日内容汇总

· 7 min read
加菲猫

image

封面图:卷饼兔。

⭐️ 装了啥 2023

  • 编辑器主 WebStorm 开发项目,辅 VSCode 临时编辑项目,再辅 CotEditor 临时打开文件(注:如果是 Rust 项目,会用 VSCode)
  • WebStorm 插件只装了两个,Github Copilot、Inspection Lens,前者大幅提升编码效率,后者大幅提升编码体验
  • 编程字体用 Monolisa、Dank Mono 和 Operator Mono,一个用久了看腻了切另一个
  • Terminal 工具是 iTerm2 + zsh + oh-my-zsh 的组合,zsh 额外装了 zsh-autosuggestions 和 fast-syntax-highlighting 插件

装了啥 2023

📒 Golang 相关文章

Golang实现一个linux命令ls命令(命令行工具构建)

GO并发之好用的sync包

Go语言原子操作

Go 并发安全与锁

Go定时器的三种实现方式

10秒改struct性能直接提升15%,产品姐姐都夸我好棒

📒 相关文章推荐

关于未捕获 Promise 异常状态的问题 — 你可能会无感知地遇到 promise 的异常问题,Jake 就解决了这么一个关于 promise 报 unhandled promise rejection 错误的问题。

https://jakearchibald.com/2023/unhandled-rejections/

关于 React 'Concurrent Mode' 的所有内容都在这 — 本文对 Concurrent Mode 进行深入的、以实例为导向的探索(并发模式已经是整合到 React 18 中的一组功能,而不是一个独特的"模式")。

https://blog.codeminer42.com/everything-you-need-to-know-about-concurrent-react-with-a-little-bit-of-suspense/

使用 GitHub Copilot 编写单元测试? — 即使你觉得像 Copilot 这样的 AI 工具在编写生产代码上不太靠谱,但它可能在快速编写单元测试上有一定的作用。

https://www.strictmode.io/articles/using-github-copilot-for-testing

类型安全的 React Query —— 一切都与信任有关 — 类型定义应该是值得信赖的。如果他们不是,他们“成为一个纯粹的建议”断言这篇文章建议可以做些什么来使他们成为这样。

https://tkdodo.eu/blog/type-safe-react-query

Zustand vs Signals:对比 React 状态管理库 — 将最时髦的状态管理库之一——zustand 与 Signals 进行比较,后者是 Preact 团队最新发布的一个状态管理库。

https://medium.com/@kevinschaffter/zustand-vs-signals-e664bff2ce4a

⭐️ 掌握了这篇 Dockerfile 中的 ARG 作用域, 就算 Build 镜像 CI 入门了 【文末抽奖】

⭐️ 「Go语言进阶」并发编程详解 | 文末抽奖

📒 前端食堂技术周刊第 67 期:2022 State of JS、ESLint 2022、pnpm 2022、大淘宝 Web 端技术概览

📒 MDH 前端周刊第 83 期:React Query、CSS 3D、JavaScript Wrapped 2022、React 新文档

《Type-safe React Query》,Dominik 的每篇文章都值得深入阅读。React Query 的类型可以定义在哪?1)useQuery<Todos>,2)const queryFn: Promise<Todos>,3)axios.get<Todos>,4)res.data as Todos,5)不定义。不定义怎么有类型?用 zod,然后定义 schema,schema 不仅可用于校验后端数据,还会返回类型。

https://tkdodo.eu/blog/type-safe-react-query

《Data binding in React: how to work with forms in React》,johnwcomeau 的每篇文章也值得阅读,这篇比较新手向,深入解答了面试必问问题「受控和不受控」。

https://www.joshwcomeau.com/react/data-binding/

《Clever Code Considered Harmful》,johnwcomeau 这周的另一篇文章。判断代码好不好的一个标准是,一个初级开发人员,一个职业生涯刚刚起步的人,会不会在理解这段代码时遇到困难?

https://www.joshwcomeau.com/career/clever-code-considered-harmful/

《React JS Best Practices From The New Docs》,Sebastian Carlos 阅读完 React 新官网文档后总结的 160 条笔记。我帮我节省了大量时间,我读完他的笔记后记了 20 多条笔记。但如果有空,还是应该完整阅读 React 的新文档。

https://sebastiancarlos.medium.com/react-js-best-practices-from-the-new-docs-1c65570e785d

《JavaScript Wrapped 2022》,作者整理了 TypeScript、React、Angular、Vue、SSR、Node|Deno|Bun 的 2022 发展和 2023 展望,建议熟读。

https://vived.io/javascript-wrapped-2022-frontend-weekly-vol-119/

《3D in CSS》,交互式的 3D CSS 教程。主要是 4 个 CSS 属性,包括 perspective、perspectiveOrigin、translateZ 和 rotate3d。

https://garden.bradwoods.io/notes/css/3d

《Building a fast, animated image gallery with Next.js》,Vercel 把 Next.js Conf 2022 的照片搬上网,同时把这套代码开源。技术栈包括 Cloudinary、Next.js 图像组件、imagemin、Framer Motion、以及用 ai 生成 alt 文本等。

https://vercel.com/blog/building-a-fast-animated-image-gallery-with-next-js

《Our top Core Web Vitals recommendations for 2023》,本文 Google DevRel 团队认为在 2023 年提高 Core Web Vitals 性能的最有效方法的最佳实践集合。涉及的性能指标包括 LCP、TTFB、CLS、FID 和 INP,同时给出了每个指标提升的注意点和可执行操作。

https://web.dev/top-cwv-2023/

《The hardest part of web dev》,关于 timing 的知识。其中 react 中,1)渲染函数在React更新DOM之前运行,2)useInsertionEffect回调在React更新DOM后运行,但在浏览器重新计算页面布局之前,3)useLayoutEffect回调在浏览器重新计算页面布局后运行(考虑到useInsertionEffect回调注入的任何CSS),但在浏览器重新绘制之前,4)useEffect回调在浏览器完成重绘后运行。

https://alexvipond.dev/blog/the-hardest-part-of-web-dev

MDH 前端周刊第 83 期:React Query、CSS 3D、JavaScript Wrapped 2022、React 新文档

📒 自从项目上了SkyWalking,睡觉真香!

⭐️ Go 语言 Web 应用怎么使用 Nginx 部署

⭐️ 发现conc并发库一个有趣的问题

⭐️ 醒醒吧,未来不会有 Go2 了!

⭐️ Go语言中常见100问题-#27 Inefficient map initialization

⭐️ 「每周译Go」了解 Go 中的 init

⭐️ Go 设计模式|组合,一个对数据结构算法和职场都有提升的设计模式

📒 八个 Web Components 前端框架,一定有一个你用得上

📒 Go语言爱好者周刊:第 174 期

- - + + \ No newline at end of file diff --git "a/2023/1\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/1\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3c02d06989..248de90b65 100644 --- "a/2023/1\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/1\346\234\21029\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月29日内容汇总

· 8 min read
加菲猫

image

题图:擅用工具的兔子工程师。

📒 相关文章推荐

修复生产版本 Node 程序的内存泄露问题 — Kent 在他的 Node 程序中遇到了各种奇怪的内存和 CPU 使用率峰值问题,于是他决定查找原因。这篇文章完整介绍了他对此的探寻过程,最戏剧性的是根本原因完全出乎他的意料。

https://kentcdodds.com/blog/fixing-a-memory-leak-in-a-production-node-js-app

在 Go 应用中嵌入 React UI — Flipt 通过一个 Go 构建的单一二进制文件为其 web 应用提供服务,并将静态资源嵌入其中。Go 在 1.16 版本中支持原生嵌入后,帮助 Flipt 走上了一条通往 React 的道路,而且不需要 Next.js 就可以实现很好的效果。

https://www.flipt.io/blog/embedding-react-in-go

在 Next.js v13 中使用异步 React — React 正在原生的支持异步,现在你可以在 Next.js 中试用它,作者提供了一个快速概览。

https://swizec.com/blog/async-react-with-nextjs-13/

React Native 发布了 v0.71 — 这是一个“功能丰富”的版本,包括“默认 TypeScript 文件”,使用 Flexbox Gap 简化布局,以及受网络标准启发的可访问性、样式和事件 props。

https://reactnative.dev/blog/2023/01/12/version-071

用 React Hook Form 和 Zod 构建表单 — 这是作者承诺的一系列录屏视频中的第一个,不仅涉及到开发一个集成后端 API 的表单,还涉及到开发时常遇到的一些问题。该视频的时长长达 95 分钟。

https://www.youtube.com/watch?v=FXWD_etMJWA

⭐️ lerna + dumi + eslint多包管理实践

⭐️ PHP转Go实践:xjson解析神器「开源工具集」

⭐️ 经过99次失败后, 我总结了几点 Golang 反射的经验(附源码)

📒 前端食堂技术周刊第 68 期:Astro 2.0、Nuxt v3.1.0、Bun v0.5、TS 实现 Stage 3 Decorators 提案

Turborepo 1.7

Turborepo 1.7 专注于改善开发者体验,为任务带来更多清晰性,主要特性如下:

  • 改进对持久化任务的支持,"persistent": true
  • 更清晰的输出,需要明确指定 outputs
  • 支持全局安装
  • 只显示错误的输出模式,让日志更清晰,turbo build --output-logs=errors-only

Turborepo 1.7

Turborepo 1.7 发布视频版

加速 JavaScript 生态系统之模块解析

module resolution (模块解析)有着大量的性能损耗,本文对此进行探讨并给出以下建议:

  • 尽可能避免调用文件系统
  • 尽可能使用缓存来表面调用文件系统
  • 使用 fs.stat 或者 fs.statSync 时,总是设置 throwIfNoEntry: false
  • 尽可能限制向上遍历的行为

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-2/

React 新文档中的最佳实践

https://sebastiancarlos.com/react-js-best-practices-from-the-new-docs-1c65570e785d

React 服务器组件深度指南

https://www.plasmic.app/blog/how-react-server-components-work

📒 一篇文章告诉你 golang 环境变量的所有基础操作

📒 CSS 原生嵌套语法来了!

📒 腾讯云开发者 2022 年度热文

手把手实践一个DAPP,通往Web3.0之路!

探秘微信业务优化:DDD从入门到实践

揭秘前端眼中的Rust!

⭐️ 【好文分享】基于Jira的运维发布平台的设计与实现

📒 DevopsCamp 第一期作业: 《cobra - 02 配置文件的读取与保存(简单)》 解题答案

📒 《DevOpsCamp作业: cobra - 01 实现编译与参数绑定(简单)》 解题答案

📒 TS、Vue、React、SSR、Node、Deno、Bun:回顾2022,展望2023

📒 MDH 前端周刊第 84 期:tRPC、Zod、慢 Jest、React Debounce、SSSVG

《6 Common SVG Fails (and How to Fix Them)》,出自 CSS Tricks。作者梳理了 6 种常见错误(编者注:后几种感觉不常见),包括 viewbox 错误、width 和 height 缺失、无意 fill 或 stroke 的颜色、id 缺失、clipping 和 masking 冲突、命名空间缺失,并给出了针对这些问题的解法。

https://css-tricks.com/6-common-svg-fails-and-how-to-fix-them/

《为何开发人员开始喜欢tRPC啦?》。tRPC 的优点包括:1)无需再次封装,直接使用函数调用远程服务,2)与Zod深度结合,可以直接使用Zod进行数据校验,3)使用非常简单,可以用在任何框架中,4)tRPC over HTTP协议非常简单,无论客户端还是服务端实现都非常简单。

https://linux-china.davao.page/blog/2023-01-14-why-trpc/

《Zod: The Next Biggest thing after Typescript》。看完这篇文章后,你可能不想再使用任何其他的验证库了!

https://dev.to/jareechang/zod-the-next-biggest-thing-after-typescript-4phh

《Speeding up the JavaScript ecosystem - module resolution》,出自 marvinhagemeist。构建、测试、Lint 时有个性能大户是 module resolution,即如何找到文件,虽然规范层有规范层的解法(ESM 引用文件要带后缀),但在规范没大范围落地之前,也可以有一些解法。作者总结了几点,1)尽量避免对文件系统的调用,2)尽可能多的缓存以避免调用文件系统,3)当你使用 fs.stat 或 fs.statSync 时,总是设置 throwIfNoEntry: false,找不到文件时不抛错而是给 undefined,4)尽可能地限制向上的遍历行为。看完这篇,我给 umi 提了个 pr,调整了 webpack 配置里 extensions 的顺序。

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-2/

https://github.com/umijs/umi/pull/10326

《How to debounce and throttle in React without losing your mind》,作者是 NADIA MAKAREVICH,必读作者系列。关于如何在 React 中做 debounce 和 throttle 而不失去理智。作者先介绍了 debouce 和 throttle 的区别,以及各自的场景是什么,比如 throttle 的场景是拥有自动保存功能的编辑器,及时保存用户输入,以减少因意外情况可能导致的数据丢失。然后介绍了在 React 中使用 debouce 有多困难,你会面临 re-render、陈旧的 state、陈旧的闭包等问题,最终解法是 useRef + useEffect + 保存函数到 ref.current,因为 ref 是 mutable 的,不会有闭包数据陈旧问题。

https://www.developerway.com/posts/debouncing-in-react

MDH 前端周刊第 84 期:tRPC、Zod、慢 Jest、React Debounce、SSSVG

📒 一期每日一GO群分享-flag、viper、协程池、异常处理

- - + + \ No newline at end of file diff --git "a/2023/1\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/1\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 04b2df4fc9..f730042b77 100644 --- "a/2023/1\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/1\346\234\2108\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

1月8日内容汇总

· 2 min read
加菲猫

📒 【第2831期】低代码技术在研发团队的应用模式探讨

📒 Golang 内存管理

https://golang.design/under-the-hood/zh-cn/part2runtime/ch07alloc/basic/

https://zhuanlan.zhihu.com/p/27807169

https://medium.com/a-journey-with-go/go-memory-management-and-allocation-a7396d430f44

📒 【中级/高级前端】为什么我建议你一定要读一读 Tapable 源码

📒 二十张图片彻底讲明白Webpack设计理念,以看懂为目的

⭐️ Go语言中常见100问题-#26 slices and memory leaks

⭐️ 一个 Go 程序的 Benchmark 基准分析工具

📒 El-Table 源码解析(二)——探究多级表头实现原理

📒 【综合笔试题】难度 3/5,近期小厂面试原题

📒 我所知道的webpack5那些不太一样的改变

📒 【第2826期】2022 年回顾:Web 性能有哪些新变化

⭐️ Golang知识点(defer): 面试经常变量在 defer 中的值, 其实在问变量的作用域

⭐️ Go Modules知识点总结

📒 「每周译Go」如何在 Go 中使用可变参数函数

📒 MDH 前端周刊第 81 期:Next.js 13.1、Bun 0.4、WASM napi、React Query

📒 Go语言爱好者周刊:第 172 期 —— 元旦快乐!还有没阳的吗

- - + + \ No newline at end of file diff --git "a/2023/2\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/2\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 81a633364f..8bf117811f 100644 --- "a/2023/2\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/2\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月12日内容汇总

· 7 min read
加菲猫

image

题图:dannyhowe @ unsplash。

⭐️ Go 并发编程 - 数据竞态

⭐️ x/exp/maps, slices 纷纷被同意加入 Go 标准库

📒 怎么把自己造的轮子发布到 Go Module上

📒 【面试高频题】难度 2.5/5,综合贪心的序列 DP 题

⭐️ 聊聊Golang饱受争议的error

⭐️ 万字长文告诉你Go 1.20中值得关注的几个变化

📒 向 Swift 学习?Go 考虑简单字符串插值特性

📒 如何从 0 开始配置 Mac

📒 Understanding HTML Form Encoding: URL Encoded and Multipart Forms

📒 从 0 实现 use-context-selector

📒 为什么说Go的函数是“一等公民”

⭐️ Go 陷阱 - 错误处理三剑客

🌟 上次给 UMI 的文档提了两个 PR 被合并,成了 UMI contributor:

image

https://github.com/umijs/umi/releases/tag/v4.0.48

📒 「每周译Go」了解 Go 中的指针

📒 【面试高频题】难度 1/5,简单二叉树寻值问题

var ans, k int

func kthSmallest(root *TreeNode, _k int) int {
k = _k
dfs(root)
return ans
}

func dfs(root *TreeNode) {
if root == nil || k == 0 {
return
}
dfs(root.Left)
if k--; k == 0 {
ans = root.Val
}
dfs(root.Right)
}

常规解法是先遍历所有树节点再排序,或者遍历树节点+优先队列(看做是 top K 问题),但这两种解法都没有利用该树为二叉搜索树的特性,而我们知道,二叉搜索树的中序遍历是有序的,因此我们只需要对二叉搜索树执行中序遍历,并返回第 k 小的值即可。中序遍历有「迭代」和「递归」两种写法。

【面试高频题】难度 1/5,简单二叉树寻值问题

📒 TypeScript 5.0 将支持全新的装饰器写法!

⭐️ Go异步任务处理解决方案:Asynq

📒 MDH 前端周刊第 86 期:CRA 未来、吐槽 React、React 清依赖小技巧、Darkmode

《The Future of Create React App and Why It Exists》。Dan 写了篇长文梳理了 CRA 的问题和规划。一些问题包括,1)脚手架的困境,一旦 clone 就很难再更新,然后你的项目配置会逐渐变得陈旧,要么放弃,要么需要花大量精力换新,2)因为是 CSR 所以有空 HTML 的问题,但 Dan 也并不喜欢 MPA,比如 astro,混用多种技术影响 DX,完整的页面刷新让客户端状态失效影响 UX,3)请求瀑布问题,比较好的解法是让数据获取和路由结合,这就需要元框架,4)懒加载(await import)问题,引入额外的请求瀑布,解法是数据获取+路由+构建工具,一样也需要元框架。Dan 期望 CRA 具备 SSG and SSR, automatic code splitting, no client-server waterfalls, route prefetching, navigation preserving client UI state 等功能,然后考虑多 CRA 的多条路,决定不做了,把 CRA 变成一个社区方案的启动器。

https://github.com/reactjs/reactjs.org/pull/5487#issuecomment-1409720741

《React I Love You, But You're Bringing Me Down》。骂得好,哈哈,爱之深,责之切啊。如果你想吐槽 React,照着念就完了。1)表单没有稳定官方方案,一路用社区库过来,目前相对好的是 Formik 和 React-hook-form,看看人家 Svelte,2)Context 太敏感,一碰就 re-render,为了性能而拆大量的 Provider 瀑布流组件,太难看了,提供一个 useContextSelector 有那么难吗?3)关于 DOM 和 ref,React.forwardRef + TypeScript 写通用组件太难了,同时 ref 不仅仅是 关于 dom,每次用 ref 都是因为 useEffect API 太奇怪,换句话说,refs 是对 react 创造的问题的一种解决方案,4)关于 useEffect,需要阅读一篇 61 页 的论文才能用好也太难了,看看人家 Solid.js,5)关于 Hooks 规则,Rules of Hooks 不容易记住,6)关于老父亲 Facebook,略。那作者为啥还留下?因为「It's the ecosystem, stupid.」

https://marmelab.com/blog/2022/09/20/react-i-love-you.html

《Little React Things: Cleaning up dependencies - Zeke Hernandez》。Zeke Hernandez 介绍了一个减少列表项 rerender 的小技巧,虽然对用户来说性能提升不明显,但至少打开 react devtool 的「Highlight Updates」时会看起来很爽,这就够了。方法是,event handler 用 useCallback 包一下,同时清空依赖,没有依赖就不会触发 event handler 生成新的了。那依赖怎么清?1) setState 无需写入依赖,2)setState 用 function 的形式。

https://www.zekehernandez.com/posts/cleaning-up-dependencies

《4 Common Mistakes Made by Node.js Developers》。文章介绍了 4 个 Node 开发的常见错题。1)没有明确定义的日志级别,可尝试 winston, pino, morgan 等库,2)无脑选择 Docker 基础镜像,又大又耗性能,比如 node:18 300M+,选 slim 或 alpine 就够了,slim 70M,alpine 50M,3)签署 JWT 时不使用非对称加密,对称加密不够安全,4)Storing passwords without unique salting。

https://amplication.com/blog/4-common-mistakes-made-by-nodejs-developers

MDH 前端周刊第 86 期:CRA 未来、吐槽 React、React 清依赖小技巧、Darkmode

⭐️ Go 陷阱 - nil != nil

⭐️ Go1.20 那些事:错误处理优化、编译速度提高、PGO 提效等新特性,你知道多少

📒 Go语言爱好者周刊:第 175 期 — Go 2023 调查问卷

- - + + \ No newline at end of file diff --git "a/2023/2\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/2\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e9a87b38b3..c7d315264f 100644 --- "a/2023/2\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/2\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月19日内容汇总

· 6 min read
加菲猫

image

题图:Bigfish x 情人节。

📒 ChatGPT ✖️ 前端 = 有点er意思

📒 基于gpt3引擎实现CLI版本的chatgpt~(数量取胜的go语言学习法)

📒 基于qwik和iris(go)写全栈啦-短链服务(数量取胜的go语言学习法)

📒 云原生运维相关文章

Linux 命令行工具之 jq 最佳实践

令人拍手叫绝的运维小技巧

2022年 SRE、DevOps技能图谱

Linux 命令工具之 grep

Linux 命令工具之 awk

Golang中的逃逸分析

据说成功人士都是这样管理时间的

📒 告别“复制粘贴”,带你自己配一个Babel

⭐️ Go 陷阱 - 接口方法调用

📒 【面试高频题】难度 4/5,单调栈的热门运用

📒 【第2858期】React 纪录片心得 — 重新思考最佳实践

⭐️ Go 陷阱 - 缓冲区内容不输出

⭐️ 百里挑 15 个 Git 技巧

📒 组件库实战——按需加载工程化

📒 Go 也要过情人节,并发布了安全更新 Go 1.20.1 和 Go 1.19.6

Go 1.20.1 发布了

Go 也要过情人节,并发布了安全更新 Go 1.20.1 和 Go 1.19.6

📒 前端食堂技术周刊第 70 期:Volar 的新开端、Lighthouse 10、良好的组件设计、React 纪录片、2022 大前端总结

⭐️ 聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

⭐️ Go 高性能 - 字符串拼接 1000+ 倍优化

📒 技术角度告诉你ChatGPT是什么?和一些深度思考

📒 闲鱼大终端UI组件库——FishUI建设之路

📒 ChatGPT 相关

AI量化投资训练营-基础班

https://twitter.com/kliu128/status/1623472922374574080/

https://tanstack.com/

https://platform.openai.com/docs/api-reference/completions/create#completions/create-prompt

https://huggingface.co/datasets/fka/awesome-chatgpt-prompts

https://github.com/f/awesome-chatgpt-prompts

https://github.com/lencx/ChatGPT

📒 细说 Vue 响应式原理的 10 个细节!

📒 MDH 前端周刊第 87 期:re-render、Resumable React、ESLint 性能、监控

《React recursively re-renders child components, but there is a nuance》。Alex Sidorenko 的 React 可视化渲染系列文章 +1。通过可视化的方式告诉你为啥通过 children 渲染子组件,能避免 state 变更时子组件 re-render。

https://alexsidorenko.com/blog/react-render-children-prop/

《Resumable React: How To Use React Inside Qwik》。关于如何在 Qwik 内使用 React,你可以建立 React 应用程序,而无需在用户的浏览器中加载 React。当然,在你需要交互的时候,还是需要动态加载 React(感觉不一定是件好事,没解决问题,只是把问题转移了,可能在交互时会卡一下)。

https://www.builder.io/blog/resumable-react-how-to-use-react-inside-qwik

《Speeding up the JavaScript ecosystem - eslint》。Speeding up 系列的第三篇。1)检测方法是 --cpu-prof + Speedscope(通常还可以用上 hyperfine 跑多次做 benchmark),2)解析器从 @typescript-eslint/parser 换成 @babel/eslint-parser + @babel/preset-typescript 可以节省不少时间,从 2.1s 到 0.6s,缺点是不支持 type-aware 的 linting 规则(我们通常也不会用他们),3)rslint 值得关注。

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-3/

《Vite with ESLint》。手把手教你如何在 Vite 项目中加上和 Vite 集成的 ESLint,基于 vite-plugin-eslint。但个人感觉 ESLint 不应该集成(因为会影响构建速度),而应该单独用,同时编辑器里也有提示了,所以在提交和 CI 里做校验就够了。

https://www.robinwieruch.de/vite-eslint/

《Custom React Hooks and When to Use Them》。关于自定义 Hooks,是什么、可复用的提取、不可复用的提取、提取数量等,最后还是要注意抽象的代价,抽象不是免费的,有时适当重复反而更好,推荐下 Dan 的 The Wet Codebase 分享。

https://thoughtbot.com/blog/custom-react-hooks

《2022大前端总结和2023就业分析》。来自狼叔的年度大作,推荐。

https://mp.weixin.qq.com/s/SicYTABGjXcJJTqYEbL5dQ

《字节前端监控实践》。感觉含金量挺高的,摘录其中错误报警的部分。1)sourcemap 结果可以用 mozila 的 sourcemap 库进行反解,2)为了保密,sourcemap 不会传到公网,而是传给后端存在内部,Sentry 有类似工具(注:sourcemap 构建慢怎么办?并发多跑一次带 sourcemap 的),3)要做堆栈聚合,合并同类错误,4)通过记录 commit + git blame 可以直接分配报错信息到人。

https://juejin.cn/post/7195496297150709821

MDH 前端周刊第 87 期:re-render、Resumable React、ESLint 性能、监控

📒 「每周译Go」在 Go 中定义结构体

📒 leader要我三天时间搭一套react-cli出来,我答应了

⭐️ Go for range 一不小心就掉坑里了

📒 Go 工具链想主动上报使用数据,你愿意吗

📒 Go语言爱好者周刊:第 176 期 —— 题目来了

- - + + \ No newline at end of file diff --git "a/2023/2\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/2\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 51fa559d41..007dc5dc39 100644 --- "a/2023/2\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/2\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月26日内容汇总

· 5 min read
加菲猫

image

题图:爱心猫

📒 bun 文档网站上线了

https://bun.sh/docs

推荐用来跑 npm scripts,极快。

📒 封装新版axios(v0.22.0)中的取消请求

📒 微前端接入Sentry的不完美但已尽力的实践总结

📒 总是跳转到国内版(cn.bing.com)?New Bing使用全攻略

📒 怎么在5分钟之内跑起来一个完整项目之gin

⭐️ Go 高性能 - 切片比数组快吗

⭐️ Go 高性能 - 切片预分配 N 倍+ 优化

📒 PNPM 如何给第三方库打补丁

https://github.com/antfu/pnpm-patch-i

📒 「Go框架」iris框架中mvc使用进阶

📒 Go1.20 arena 能手动管理内存了,怎么用

⭐️ Go语言空结构体这3种妙用,你知道吗

⭐️ 一文吃透 Go 内置 RPC 原理

⭐️ 外观模式,一个每天都在用,却被多数人在面试中忽视的模式

📒 一起玩转Vue中的JSX:让你一次性掌握它的特性!

📒 分享6款yyds的可视化搭建开源项目

📒 类型编程原理和编写类型安全代码

📒 前端食堂技术周刊第 71 期:LightningCSS、State of React Native、Sandpack 2.0、ChatGPT 与前端、2023

📒 「每周译Go」在 Go 中定义方法

📒 「读源码」为什么注册路由时没有传入上下文,在接口方法中却能取到

⭐️ 一文告诉你如何判断Go接口变量是否相等

📒 PHP vs Go,为什么 Go 不支持命名参数调用函数

📒 MDH 前端周刊第 88 期:错误处理、CSS 嵌套、应用模块化、useWorker

React 实现了下发服务器端函数的引用,类似 RPC 。

https://twitter.com/wongmjane/status/1625166863062958081

React Native 年度报告显示 Turborepo 是最受欢迎的 monorepo 工具。

https://results.stateofreactnative.com/monorepo-tools/

Nextjs 新增了 Api routes 的替代品 route handler 。

https://beta.nextjs.org/docs/routing/route-handlers

React Hook Form 支持跨框架使用了,建议更名为 @tanstack/hook-form,哈哈。

https://github.com/react-hook-form/core

《How to handle errors in React: full guide》。直接 try…catch 会有不少限制,但使用 React 官方的 ErrorBoundary 也有不少限制。这个限制是,React生命周期之外的错误不捕获,比如 resolved promises, async code with setTimeout, various callbacks and event handlers。怎么解?dan 给了个 Hack 方案,简单说就是 try {} catch(e) { setState(() => throw e) }。基于此,我们可以稍微封装下,比如 useThrowAsyncErroruseCallbackWithErrorHandling,这样就不需要每次声明一个新的 setState 了。同时也可以考虑用 bvaughn/react-error-boundary

https://www.developerway.com/posts/how-to-handle-errors-in-react

《TypeScript Brand type with Zod》。Brand Type 可以用来创建一个新类型,比如把 string 包装成 Email。然后结合 Type Guards,即可确保类型安全,又能做数据校验。Type Guards 的部分可以用 zod 。

https://linux-china.davao.page/blog/2023-02-16-ts-brand-with-zod/

《Modularizing React Applications with Established UI Patterns》。好文,作者通过案例教你如何用成熟的 UI 模式把 React 应用模块化。说人话就是,把大组件拆小。几个思路,1)提取子组件以拆分视图,2)提取非视图逻辑到 hooks,3)提取领域模型以封装逻辑。但是也要注意别过度优化。

https://martinfowler.com/articles/modularizing-react-apps.html

《React Component Composition》。图解 Composition。

https://punits.dev/jargon-free-intros/react-component-composition/

Umi 例行每周四发一版,我觉得有趣的功能包括,1)基于 @clack/prompts 优化 create-umi 界面,2)优化命令行执行速度,该 lazyImport 的 lazyImport,同时优化了 @ant-design/icons 集合的读取方式,3)新增 legacy 模式支持做产物的 es5 校验,4)升级 Vite 到 4.1。

Umi 新增 Roadmap 2023,是 Umi 团队每周迭代的一部分,每周四更新,有兴趣共享的同学欢迎直接回 issue 认领。一个非 docs PR 即可加入 Umi Contributor 群。

Umi 团队新增一条规则,每人每周需共享 1-2 个想法,每周三开 Discussion 征集,这是试运行第一周的 Discussion 链接

MDH 前端周刊第 88 期:错误处理、CSS 嵌套、应用模块化、useWorker

📒 Golang 语言标准库 io 详解

📒 Go语言爱好者周刊:第 177 期 — Go 版 ElasticSearch

- - + + \ No newline at end of file diff --git "a/2023/2\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/2\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index f9e46acef5..54ad3f481b 100644 --- "a/2023/2\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/2\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

2月5日内容汇总

· 5 min read
加菲猫

image

题图:烟花兔。

📒 10 GitHub Repositories You Should Know as a JavaScript Developer

⭐️ Go 高性能 - 字符串 & 切片转换提升 10 倍+

⭐️ Go 高性能 - 两种内存大小为 0 的数据类型

⭐️ Taro 正式发布 3.6 版本:支持跨端路由、请求库,支持纵向拓展鸿蒙、Web 端平台插件,小程序持续集成 CI 能力升级

⭐️ 深入理解 go sync.Cond

📒 React团队回应用Vite替换Create React App的建议

📒 React为什么不将Vite作为默认推荐

⭐️ 将Roaring Bitmap序列化为JSON

📒 Flag 2023

📒 Go 1.20 已发布!性能和构建速度上有很大提升!

⭐️ Go 工程化 - 如何实现 implements

⭐️ 「好文推荐」转Go必看 《 Go 工程化 - 面向对象,存在吗》

⭐️ Go字符串操作不是你想的那么简单!

📒 相关文章推荐

24个JavaScript循环遍历方法,你都知道吗

JavaScript 数组方法 reduce 的妙用之处

⭐️ 为什么 Go 不支持 []T 转换为 []interface

📒 「Go框架」深入理解web框架的中间件运行机制

📒 TypeScript 5.0 beta 发布:新版 ES 装饰器、泛型参数的常量修饰、枚举增强等

📒 【面试高频题】难度 2/5,简单的复工面试题

⭐️ 如何使用jenkins搭建一个中小企业前端项目部署环境

⭐️ 这些关于 Golang timezone 时区的坑, 我已经帮你踩过了

📒 还能这样玩?Go 将会增强 Go1 向前兼容性

⭐️ 一文入门Go云原生微服务「爆肝6千字」

⭐️ sourcegraph 出品的并发库 conc 详解

⭐️ Go语言实现的可读性更高的并发神库

📒 MDH 前端周刊第 85 期:MDH Weekly 官网、2023 趋势、CSS Wish List、Astro

《10 Web Development Trends in 2023》,ROBIN WIERUCH 分析了 2023 年 Web 开发的 10 个趋势,推荐一读。10 个领域包括元框架、应用和渲染模式、Edge ServerLess、数据库复兴、JavaScript Runtime、MonoRepo、Utility-First CSS、类型安全、构建工具、AI 驱动开发。

https://www.robinwieruch.de/web-development-trends/

《20 Things I've Learned in my 20 Years as a Software Engineer》,一篇老文,讲述 20 年工作经验工程师的 20 条 Tips,我读完很有收获,推荐一读。

https://www.simplethread.com/20-things-ive-learned-in-my-20-years-as-a-software-engineer/

《Capture heap snapshots in Node.js》。作者介绍了关于捕获堆快照的 3 个方法,1)node --inspect index.mjs--inspect-brk,2)借助 Node 12 支持的 --heapsnapshot-signal flag,node --heapsnapshot-signal=SIGUSR1 index.mjs,3)用 v8.writeHeapSnapshot() method 手动写。

https://pawelgrzybek.com/capture-heap-snapshots-in-node-js/

《Things I want to see in JavaScript and Frontend development in 2023》,Paul Armstrong 关于 2023 年期望发生的变化。1)axios 别发展了,因为用浏览器原生支持的 fetch 可以省去 7-11kB 的尺寸,2)CSS 方案更少分歧,主要是 tailwind 和 css in js 之间,3)少一些资本支持的开源,因为当资本进入时,同时意味着他们期望得到巨大的金钱回报,4)少 eslint 规则和配置,自动帮你改代码或能解实际错误的规则除外,5)react 要不振作起来要不就 gg 吧,作者吐槽了好多都在点上,主要是发货太慢。

https://paularmstrong.dev/blog/2023/01/20/javascript-and-frontend-things-to-see-in-2023/

MDH 前端周刊第 85 期:MDH Weekly 官网、2023 趋势、CSS Wish List、Astro

📒 Typescript 严格模式有多严格

📒 一个全新的 JavaScript 事件!

📒 DevopsCamp 第一期作业: 《cobra - 03 交互式命令(简单)》 解题答案

- - + + \ No newline at end of file diff --git "a/2023/3\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/3\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index a9d0203bd7..5bab155a80 100644 --- "a/2023/3\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/3\346\234\21012\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月12日内容汇总

· 15 min read
加菲猫

⭐️ Go 高性能 - map 优化 (三)

⭐️ Go 高性能 - map 优化 (二)

⭐️ Go 语言中结构体嵌入结构体

⭐️ Go Slice 扩容的这些坑你踩过吗

📒 Go 为什么不像 Rust 用 ?!做错误处理

📒 字节跳动自研 Web 构建工具 Rspack 正式发布

⭐️ 跟着 Go 作者学泛型

⭐️ Webpack 迁移 Rspack 速攻实战教程(前瞻版)

⭐️ Go 高性能 - 内存对齐

⭐️ Go 高性能 - map 优化 (一)

📒 Next.js了解篇|一文带你梳理清楚 Next.js 的功能

📒 Go 在 3.8 妇女节(女神节)发布最新版本 Go 1.20.2 和 Go 1.19.7 安全更新

📒 解析 React 性能优化 API

⭐️ Go 高性能 - 逃逸分析

📒 一篇文章带你理解 React 中最“臭名昭著”的 useMemo 和 useCallback

📒 GSAP从入门到精通

⭐️ 最新最全Go主流框架高频面试题大全

📒 2023 年静态站点生成器 (SSG) 指南

📒 Node.js Toolbox:发现 Node.js 包的一种新方法

https://nodejstoolbox.com/

⭐️ Golang下的ORM框架gorm的介绍和使用

⭐️ 如何使用 splitChunks 精细控制代码分割

📒 浅析 SplitChunksPlugin 及代码分割的意义

📒 5W1H 带你入门 Monorepo

⭐️ 面试官:请说一下如何优化结构体的性能

⭐️ Go 高性能 - 打印调用堆栈

⭐️ Go 高性能 - 结构体优化 (一)

⭐️ Go 高性能 - index vs value in for

⭐️ Go 高性能 - int to string

📒 参考云谦大佬的项目,用 ChatGPT 给前端相关文章写总结

https://github.com/sorrycc/url-system

https://github.com/advancedlogic/GoOse

https://pkg.go.dev/golang.org/x/net/html

📒 前端构建工具进化历程

📒 18个很有用的 CSS 技巧

📒 Go 语言怎么一键生成一个 gRPC 服务

⭐️ Go 最细节篇|内存回收又踩坑了

⭐️ Go设计模式实战--用状态模式实现系统工作流和状态机

⭐️ 「每周译Go」如何在 Go 中使用结构体标签(文末有GIFT)

⭐️ Go设计模式--享元模式,节省内存的好帮手

📒 MDH 前端周刊第 90 期:Signals、Signia、Replit、ChatGPT、CHIPS、技术债

《Demystifying Create React Signals Internals · Daishi Kato's blog》。本文主要介绍了 create-react-signals 库的内部工作原理,这个库的主要目的是将 React 组件中的状态管理从 React 自身分离出来,并使用 signals 来实现状态管理。Signals 是一种包含订阅、获取和设置值等功能的存储对象。文章讲解了如何使用自定义 JSX 转换器将 Signals 转换为可在 React 中使用的组件,以及如何处理对象类型的信号和跳过 diffing 等问题。作者认为,Signals 仍然是 React 中一个开放的研究领域,而使用 Observable 作为新的基元可以进一步探索这种方法。

https://blog.axlight.com/posts/demystifying-create-react-signals-internals/

《The JavaScript Site Generator Review》。该篇文章对当前流行的七种 JavaScript 网站生成器进行了评论。对于 npm 安装时间、客户端 JavaScript 基线、node_modules 权重、npm 审计、遥测(TELEMETRY)等内容进行了测试。其中,有些工具使用创建 x 包来安装依赖,并且包括了帮助用户安装依赖的步骤。然而,这些工具中有一些隐藏了 npm 审计结果(包括关于高严重度的安全漏洞)。还有一些工具默认开启了遥测功能,需要用户选择退出。此外,该文还附带了作者之前的评论和文章链接。

https://www.zachleat.com/web/site-generator-review/

《Effective Higher-Order Components :: Building Better Software Slower》。本文介绍了 React 中的高阶组件(Higher-Order Components,简称 HOC),它是一个接受组件的函数,并在附加逻辑的包裹下返回它。作者指出,虽然 HOC 带来了无限的可能性,但实际应用应限于透明地添加包装或逻辑。同时,作者提出了 HOC 的一些惯例和注意事项,例如 HOC 不应该改变所提供的组件的 API,HOC 应该有一个符合 withNoun 模式的名字,除了组件本身之外,HOCs 不应该有任何参数等等。此外,作者还介绍了一些最常见的 HOC,例如 Props记录、添加格式化等。最后,作者强调,HOC 应该是一个减轻 JSX 精神负担的工具,而不是炫耀函数式编程技巧的机会。钩子是一个更可预测的、明确的模式,但好的 HOC 依然存在并提供了强大的模式。

https://www.bbss.dev/posts/effective-hocs/

《Introducing ChatGPT and Whisper APIs》。OpenAI 宣布,其 ChatGPT 和 Whisper 模型现已可用于 API,让开发者能够使用尖端的语言和语音转文本功能。通过一系列系统级别的优化,自去年 12 月以来,ChatGPT 的成本降低了 90%;现在将这些节省成本传递给 API 用户。开发者现在可以在 API 中使用我们的开源 Whisper large-v2 模型,获得更快速、更具成本效益的结果。Snap Inc.、Quizlet、Instacart 和 Shopify 等公司已经开始使用 ChatGPT API 和 Whisper API。OpenAI 还改进了 API 服务条款以更好地满足开发者的需求。同时,OpenAI 还提供专用实例,使开发者能够深入控制特定模型版本和系统性能。

https://openai.com/blog/introducing-chatgpt-and-whisper-apis

《ChatGPT use case examples for programming - RisingStack Engineering》。本文介绍了一些人们如何在职业网页开发中使用 GPT 等 “AI” 工具。作者分享了他的同事们使用 GPT 及其各种变体的经验,以帮助读者更好地理解它们的实用性。例如,Code GPT 是一个 VS Code 插件,可以从注释提示中生成代码、生成单元测试、查找问题、重构代码、记录和解释代码、以及提出问题。ChatGPT 则可用于编写 Mongo 查询、代替 StackOverflow 等。然而,作者指出,使用这些工具时需要小心检查生成的内容,因为 GPT 可能会产生不对的结果。此外,尽管 “AI” 不会大规模取代就业岗位,但它将提高生产力,就像 Photoshop 是更好的画笔一样。

https://blog.risingstack.com/chatgpt-use-case-examples-for-programming/

《React vs Signals: 10 Years Later》。本文探讨了 JavaScript 中的信号(Signals)技术,以及它与 React 的区别和联系。信号是一种细粒度的响应式编程技术,可以用于前端开发中的数据流管理。尽管在 React 和虚拟 DOM 的兴起中,信号被认为是不可预测和危险的模式,但实际上信号从未消失,而是以第三方库或框架的形式存在。本文介绍了 SolidJS,这是一种新型的信号技术,它采用了组合、单向数据流和显式变异等原则,并将所有东西都视为 Effect,与 React 不同的是,它不会将所有操作视为纯函数,而是通过隔离更新来实现状态变化。作者认为,React 曾经 “修复” 了前端开发,但现在信号技术的复兴又将其推向了新的竞争时代。

https://dev.to/this-is-learning/react-vs-signals-10-years-later-3k71

《I'm not sure I understood this article. I think... — DEV Community》。这是 Dan 对于上一篇文章(Signals 主题)的评论。他探讨了 React 和 Solid 在处理渲染逻辑上的不同策略。React 的核心思想是,能够编写渲染逻辑,使其在初始化和更新时都能够运行,并且不会与传递的数据不同步。Solid 则只有模板中的 “空洞” 是响应式的,因此不能像 React 那样使用 if 语句和控制流。作者认为,Solid 的优点在于可以避免部分逻辑的重新执行,但这并不是最终的理想状态。通过编译器,可以实现在不重组代码的情况下自动确定 “组”,以达到类似 useMemo 的优化效果。最后,作者指出 React 不需要将渲染逻辑从内向外编写才能实现更新,这是 React 默认具备的响应性。

https://dev.to/dan_abramov/comment/256g9

《Remote Access to Your Repls via SSH》。Replit 是一个基于云的编码平台,它的所有付费计划都增加了使用 SSH 远程访问 Repls 的功能。订阅了付费计划的用户可以添加他们的 SSH 密钥,并远程操作他们的 Repl。此举使用户能够充分利用 Replit 的功能,同时继续使用其本地开发环境。Replit 将每个 Repl 放入自己的容器中,一旦连接被打开就会运行。在该容器内,一个 SSH 服务器处理所有远程访问需求。一个代理接收连接,验证密钥,并将 SSH 连接通过加密的 SSH 隧道路由到 Repl。

https://blog.replit.com/ssh

《Introducing Signia》。TLDraw 的开发团队发布了其核心反应式状态管理系统的开源项目 Signia。该库是用于使用基于逻辑时钟的新惰性反应模型处理细粒度反应值(称为 “信号”)的原始库,它诞生的原因是需要高效地处理经常更改的大型派生不可变集合。除了核心库之外,还发布了与 React 绑定的内容。Signia 的 API 类似于 Jotai、@preact/signals 和 Recoil 等类库,其主要区别特征是具有增量派生和内置支持回滚的事务。Signia 的反应性系统基于单个整数,即全局逻辑时钟,每当更新根状态值时,该时钟就会递增。比较时钟值允许 Signia 始终缓存派生值,而不管它们是否正在被积极观察。Signia 的响应式系统基于逻辑时钟和差异,可以实现增量计算派生值。

https://tldraw.substack.com/p/introducing-signia

《The 25 Percent Rule for Tackling Technical Debt》。这篇文章讨论了技术债务的不同类型,并提出了一种 “25% 规则”,即每周花费 10%的时间解决日常技术债务,另外 10%的时间解决每周技术债务,剩下的 5%用于处理每月和每年的技术债务。作者认为,解决技术债务并不是大规模修复的问题,而是通过文化建设来实现。通过改进日常工作中的代码、庆祝重构代码的能力以及知道何时选择好的而不是完美的,可以帮助解决技术债务问题。

https://shopify.engineering/technical-debt-25-percent-rule

《You Don't Need a Build Step》。本文探讨了为什么现代 Web 开发需要构建步骤,以及如何使用 Deno 和 Fresh 等工具实现无需构建的开发。文章介绍了构建步骤的来龙去脉,包括编译、压缩、打包和代码分割等过程,并列举了一些流行的构建工具。作者认为,构建步骤是现代 Web 开发不可避免的一部分,但也带来了复杂性和长时间的构建时间。使用 Deno 和 Fresh 可以实现无需构建的开发,从而提高开发效率和代码质量。

https://deno.com/blog/you-dont-need-a-build-step

《Three ways to activate an inspector in Node.js | pawelgrzybek.com》。本文介绍了三种激活 Node.js inspector 的方法,其中一种是使用 NODE_OPTIONS 环境变量来调试间接运行 Node 的进程。如果您是 Node.js 调试器的新手,可以查看作者之前发布的两篇文章:“在 Google Chrome 中进行基本的 Node.js 调试” 和 “解释 Visual Studio Code 调试器中的继续、步过、步入和步出操作”。

https://pawelgrzybek.com/three-ways-to-activate-an-inspector-in-node-js/

MDH 前端周刊第 90 期:Signals、Signia、Replit、ChatGPT、CHIPS、技术债

📒 Go语言爱好者周刊:第 179 期 —— Google 出品的分布式应用 Go 框架 weaver

- - + + \ No newline at end of file diff --git "a/2023/3\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/3\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index ddb5f0b6d1..da15cdaa0e 100644 --- "a/2023/3\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/3\346\234\21019\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月19日内容汇总

· 11 min read
加菲猫

📒 小技巧集合

新学到一个省时间的技巧,随机分支,再也不需要为分支名发愁了!我写了个自定义脚本,会随机 checkout 到名为「sorrycc-xxxx」的分支。脚本大致逻辑是这样,const length = 4;const id = (Math.random() * 1e20).toString(36).substring(0, length);await $反引号git checkout -b sorrycc-${id}反引号;

gh 命令可以在命令行里操作 github,比如提 PR、绑定 ssh key 等,相见恨晚。

https://github.com/cli/cli

利用 openai 帮你写 commit 信息,可以省去部分重复劳动,适用于对 commit 信息要求不高的业务项目。

https://goonlinetools.com/snapshot/code/#42rshrrrk3gq5h171lxiu

在「Privacy & Security > Developer Tools」里把 Terminal 等开发者工具加上,绕开系统的安全策略,据说可以让请求和编译更快。

习惯用 Purrple Cat 作为工作背景音。

查 IP 或运营商数据可在命令行中输入「curl cip.cc」。

换了个 VSCode 主题「Nako」,红色系,挺好看。

📒 dynamicgo 开源 :基于原始字节流的高性能+动态化 Go 数据处理

⭐️ Go语言中嵌入类型的一些重要规则,你知道多少

⭐️ Go 高性能 - channel 缓冲区

⭐️ Go 高性能 - singleflight 防止缓存击穿

📒 开源工作者福音,用 ChatGPT 评审 Pull Request,解决双手又能多提交两个commit了

📒 【webpack核心库】耗时7个小时,用近50张图来学习enhance-resolve中的数据流动和插件调度机制

⭐️ 并发编程--协同等待WaitGroup的最佳实践

⭐️ 一文搞懂Go subtest

📒 Webpack 最近的任意代码漏洞是怎么回事

⭐️ Go语言中部分实现的接口(技巧)

⭐️ 别乱用了,用新的。Go SliceHeader 和 StringHeader 将会被废弃!

📒 拒绝搬运文档,从实际出发介绍几个开发中用得上的TypeScript技巧

⭐️ Go 高性能 - timer 内存优化到 0 分配

⭐️ Go 高性能 - defer 优化

📒 .vue 怎么变成 .js,我们来试一试!看完会更懂 Vue 吗

⭐️ Go 高性能 - 对象池

⭐️ Go 高性能 - 切片过滤器

⭐️ 【译】该如何使用合理 Go 语言的 struct

⭐️ 【译】Go语言:使用 Singleflight 优化你的代码

⭐️ 【Go官方博文】Go 切片:用法和内部结构

⭐️ 【译】Go语言:深入探究 array 与 slice

⭐️ Go 中的性能分析和执行跟踪

⭐️ Go 语言中接口嵌入接口

📒 2个奇怪的React写法

⭐️ Go 开源库推荐

Generic goroutine pool: Submit, Map, Async

⭐️ Learn Go with tests

https://studygolang.gitbook.io/learn-go-with-tests

https://quii.gitbook.io/learn-go-with-tests/

📒 React 中文周刊 #131 - React hooks 是一个错误吗

⭐️ Go 高性能 - 互斥锁和读写锁

⭐️ Go是一门面向对象编程语言吗

⭐️ 「每周译Go」如何在 Go 使用 interface

⭐️ Go设计模式--桥接模式,让代码既能多维度扩展又不会臃肿

⭐️ Go语言中常见100问题-#29 Comparing values incorrectly

📒 深入理解Render阶段Fiber树的初始化与更新

📒 你不知道的 async、await 魔鬼细节

📒 2023 年 Web 框架性能报告

⭐️ Go 语言各个版本支持 Go Modules 的演进史

📒 MDH 前端周刊第 91 期:代码提取、Turborepo、Farm、React 常见错误、tRPC、技术债

pnpm v8.0.0-beta.0 发布,默认去除重复对等依赖项等。

  • auto-install-peers is true by default
  • dedupe-peer-dependents is true by default
  • The registry field is removed from the resolution object in pnpm-lock.yaml
  • save-workspace-protocol is rolling by default
  • resolve-peers-from-workspace-root is true by default

https://github.com/pnpm/pnpm/releases/tag/v8.0.0-beta.0

《WTF 是代码提取?》。本文介绍了一种新的开发方式 —— 代码共存(code collocation),即将服务器端和客户端代码放在同一个文件中。作者认为这种方式可以提高开发效率,因为大部分代码都在两个位置上运行,没有必要将它们分开成不同的文件。然而,由于服务器端和客户端有不同的限制,需要将它们分开并创建代码包。文章介绍了三种策略:导出抽取、函数抽取和闭包抽取,并详细解释了如何使用这些策略来实现代码共存。最后,作者还介绍了一种称为 “标记函数” 的方法,可以让开发者自定义标记以及相应的转换过程。(编者注:元框架开发必备技能)

https://www.builder.io/blog/wtf-is-code-extraction

《为什么 Turborepo 从 Go 迁移到 Rust - Vercel》。Turborepo 是一个用于 JavaScript 和 TypeScript 代码库的高性能构建系统。该系统通过增量构建、并行执行和远程缓存来避免重复工作。随着使用量的增加和产品需求的变化,Turborepo 决定从 Go 逐步迁移到 Rust。该迁移主要基于 Rust 的正确性、强大的生态系统以及开发人员的愉悦度等因素。Turborepo 正在采取渐进式的迁移方式,目前已经实现了 “Rust-Go-Rust Sandwich” 的状态,即 Rust 是入口点,可以选择使用 Rust 或 Go 来实现特定命令的功能。

https://vercel.com/blog/turborepo-migration-go-rust

《如何为你完全不了解的项目做出贡献?》。本文介绍了一个名为 Bun 的 JavaScript/TypeScript 运行时,它与 Deno/Node 类似,但具有更快的启动时间。作者通过编写测试套件来测试 Bun 的性能,并在测试过程中遇到了问题。作者分享了自己处理问题的方法,包括询问前任维护者、规范功能 / 问题、运行测试、编写测试用例并更改代码等步骤。

https://grifel.dev/how-to-contribute-without-knowledge

《比 Vite 快 5 倍?2ms HMR?Farm:基于 Rust 的极速构建引擎!》。Farm 是一个使用 Rust 编写的构建引擎,比 Webpack 快 10 倍以上,比 Vite 快 5 倍。它支持 HTML、CSS、JavaScript、静态资源等模块的编译能力,并且采用按需编译,在加载时编译除首屏需要的模块外的其他模块,理论上对任意规模的项目都能支持秒启动。所有能力都由插件实现,支持 Rust 和 Js 插件。

https://zhuanlan.zhihu.com/p/611603260

《React 初学者常见错误》。这篇文章介绍了 React 开发中常见的 9 种陷阱,包括:使用零进行条件判断、直接修改状态、未生成 key、缺少空格、在更改状态后访问它、返回多个元素、从不受控制到受控制的转换、缺少样式括号和异步效果函数。对于每种陷阱,文章都提供了解决方法,并给出了示例代码。

https://www.joshwcomeau.com/react/common-beginner-mistakes/

《@githubnext/github-copilot-cli》。GitHub Copilot CLI 是一个命令行体验,可以让 GitHub Copilot 在命令行中帮助你。它将自然语言转换为 shell 命令,并具有不同领域的模式。安装后,您可以使用以下三个命令:??:将自然语言翻译为任意 shell 命令;git?:将自然语言翻译为 Git 命令;gh?:将自然语言翻译为 GitHub CLI 命令。(编者注:装完再也没用过,因为 git 命令已成肌肉记忆)

https://www.npmjs.com/package/@githubnext/github-copilot-cli#whats-the-point-of-the-eval-and-alias-stuff

《使用 tRPC 和 React 的全栈 TypeScript》。tRPC 是一种使用 TypeScript 在全栈应用程序中创建完全类型安全 API 的方法。 tRPC 服务器应用程序生成具有类型安全函数的类型安全路由器(例如 CRUD 操作:创建用户,按标识符获取用户,获取所有用户),客户端应用程序可以直接调用这些函数。 在幕后,仍然使用 HTTP 在客户端和服务器之间通信。相比 GraphQL 和 REST,tRPC 主要用于较小的项目,其中不需要协调许多服务(例如 GraphQL),或者我们不一定按照标准化的 RESTful 方法工作。但是,随时可以从 tRPC 迁移到 GraphQL / REST,因为 tRPC 最终只是服务器上的函数,可以直接在 REST 路由器或 GraphQL 解析器中使用。

https://www.robinwieruch.de/react-trpc/

《优秀工程师和卓越工程师的区别》。Intercom 的 CTO DARRAGH CURRAN 概述了造就杰出工程师的六个特征。其中包括野心和决心,习惯性简化,快速调试任何东西的能力,愿意帮助别人成为伟大的人,知道什么是有价值的,以及有创造力和积极性。Kotlyar说,工程文化是由被雇用的人、他们采取的行动以及被奖励和赞美的特质所塑造的。

https://www.intercom.com/blog/traits-of-exceptional-engineers/

monorepo 项目用 pnpm publish 可以自动替换 Workspace Protocol 为实际的版本号,可以让发布省不少事。

https://github.com/umijs/umi/pull/10719

MDH 前端周刊第 91 期:代码提取、Turborepo、Farm、React 常见错误、tRPC、技术债

📒 Go语言爱好者周刊:第 180 期 —— 通用 goroutine 池

- - + + \ No newline at end of file diff --git "a/2023/3\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/3\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index a68bf9075e..5ff52087b9 100644 --- "a/2023/3\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/3\346\234\21026\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月26日内容汇总

· 11 min read
加菲猫

⭐️ Go开发命令行程序指南

⭐️ Go 内存模型

📒 ChatGPT推出插件功能:可联网、可执行代码

📒 【webpack核心库】耗时7个小时,用近50张图来学习enhance-resolve中的数据流动和插件调度机制

📒 Go每日一库之Pie :一个高性能、类型安全的slice操作库

📒 基于 openai 开发 CLI 工具

https://platform.openai.com/docs/guides/completion/introduction

https://platform.openai.com/docs/api-reference/authentication

https://github.com/sashabaranov/go-openai

⭐️ 源码阅读 - 切片扩容过程

⭐️ 聊聊Go语言的全局变量

⭐️ 「高频必考」Go并发编程面试题和答案

📒 ECMAScript 2023 有哪些更新

⭐️ 「从0实现React18系列」Reconciler架构的双缓存树实现原理

📒 monorepo 相关文章

monorepo工作流基础之changesets打开与进阶

https://sakina.blog.csdn.net/?type=blog

https://modernjs.dev/guides/topic-detail/changesets/release-pre.html

⭐️ Lazy Loading Routes in React Router 6.4+

📒 如何规范地发布一个现代化的 NPM 包

⭐️ 「Go框架」bind函数:gin框架中是如何将请求数据映射到结构体的

⭐️ 基于性能分析的优化预览

📒 做量化交易发愁写代码?一招教你白嫖GPT-4智能编程神器

⭐️ Go 语言并发模式代码模板

⭐️ 「从0实现React18系列」Fiber架构的实现原理

⭐️ 「从0实现React18系列」自己动手实现一个JSX转换

⭐️ Go 错误处理:100+ 提案全部被拒绝,为何现阶段仍用 if err != nil

⭐️ 如何做好表结构设计

📒 React 中文周刊 #132 - Vite 简介以及为什么使用它来替代 Create React App

📒 TypeScript 5.0 已发布!看看增加了什么新功能

📒 Chrome 101:fetchpriority

⭐️ Go Slice 扩容的这些坑你踩过吗

📒 Three.js 进阶之旅:物理效果-碰撞和声音 💥

📒 Three.js 进阶之旅:新春特典-Rabbit craft go 🐇

⭐️ Go 语言自带设计模式

⭐️ 「每周译Go」在不同的操作系统和架构编译 Go 应用

📒 你可能不知道的 async、await 细节

async函数在抛出返回值时,会根据返回值类型开启不同数目的微任务

  • return 结果值:非 thenable、非 promise(不等待)
  • return 结果值:thenable(等待 1个 then 的时间)
  • return 结果值:promise(等待 2个 then 的时间)

await右值类型区别

  • 接非 thenable 类型,会立即向微任务队列添加一个微任务 then,但不需等待
  • thenable 类型,需要等待一个 then 的时间之后执行
  • Promise 类型(有确定的返回值),会立即向微任务队列添加一个微任务 then,但不需等待

你可能不知道的 async、await 细节

⭐️ Go语言中常见100问题-#30 Ignoring the fact that elements are copied

⭐️ Go 语言实现创建型设计模式 - 单例模式

⭐️ 聊聊godoc、go doc与pkgsite

📒 把React新文档投喂给 GPT-4 后

📒 MDH 前端周刊第 92 期:react.dev、npm 安全、Execa 7、Reactivity、React Query

《介绍 react.dev》。React 官方文档网站已经更新,现在的网址是 react.dev。新网站教授使用函数组件和 Hooks 的现代 React,并包括了图表、插图、挑战和 600 多个交互式示例。旧版 React 文档网站已移至 legacy.reactjs.org。新网站分为 “学习 React” 和 “API 参考” 两个主要部分,前者是一个自定进度的课程,后者提供每个 React API 的详细信息和用法示例。新网站还添加了很多沙盒,让用户可以快速玩转 React API、探索想法并检查理解。

https://react.dev/blog/2023/03/16/introducing-react-dev

《介绍 “安全 npm”,一个 Socket npm 包装器 - Socket》。Socket 推出了一款名为 “safe npm” 的 CLI 工具,用于保护开发人员在使用 npm install 时免受恶意软件、拼写错误、安装脚本、抗议软件和遥测等方面的影响。该工具透明地包装了 npm 命令,并在安装过程中保护开发人员免受恶意软件、拼写错误、安装脚本、抗议软件、遥测等 11 种问题的影响。

https://socket.dev/blog/introducing-safe-npm

《GitHub - gajus/turbowatch:Node.js 的极速文件变更检测器和任务编排工具。》。Turbowatch 是一个用于 Node.js 的极快文件更改检测器和任务编排器。它可用于自动化响应文件更改的任何操作,例如运行(并自动重新启动)长时间运行的进程(如您的 Node.js 应用程序)或构建资产(如 Docker 镜像)。

https://github.com/gajus/turbowatch/

《JulesBlom.com - React API 地图》。这篇文章介绍了一种学习 React API 的方法,即通过将其组织成一个空间地图来帮助理解。作者将 React 的不同部分联系在一起,形成了一个可供探索的结构,并在 “推荐阅读” 部分中添加了一些经过筛选的优质博客文章链接,以便更好地理解 React API。

https://julesblom.com/writing/map-of-react-api

《发布 v6.9.0・remix-run/react-router》。React Router 发布了 6.9.0 版本,支持使用 React 组件定义路由元素和错误元素字段。此外,还引入了 Lazy Route Modules,以保持应用程序包的小巧和支持代码分割路由。此功能通过 lazy () 路由属性实现,是一个异步函数,解析路由定义的非匹配部分。

https://github.com/remix-run/react-router/releases/tag/react-router%406.9.0

《Execa 7 的无 Shell 脚本 | ITNEXT》。Execa 7 提供了类似于 zx 的模式,但采用更简单的纯 JavaScript 方法。使用 Execa,不需要记忆任何 shell 语法,几乎所有特定于 shell 的功能都可以在 JavaScript 中表达。

https://itnext.io/shell-free-scripts-with-execa-7-885fb3b42f83

《2023 年每个前端开发人员都应该知道的 6 个 CSS 片段》。本文介绍了六个有用的 CSS 技巧,包括使用容器查询、创建滚动吸附效果、避免使用 grid 的 position: absolute、快速制作圆形、使用层叠样式表(cascade layers)控制变体和使用逻辑属性(logical properties)来减少代码量。

https://web.dev/6-css-snippets-every-front-end-developer-should-know-in-2023/

《Nuxt 3.3》。Nuxt.js 发布了新版本,增加了本地模块开发、自动重启服务器和性能优化等功能。该版本还提供了一些新的组件和可组合函数,包括错误处理组件 <NuxtClientFallback> 和处理不受信任用户输入的 useHeadSafe 可组合函数。此外,该版本还改进了类型定义和 Nitro 引擎,支持自定义配置模式,并且有更好的 Chrome DevTools 支持。

https://nuxt.com/blog/v3-3

《深入探究 TanStack 查询中的突变》。TanStack Query 有三个主要概念:查询、变异和查询失效。本文将重点介绍变异,包括变异的副作用、失效和并行实现。通过使用 useMutation Hook,可以轻松地处理所有更新、创建和删除请求。同时,乐观更新是使用 TanStack Query 变异的关键优势之一。

https://blog.logrocket.com/deep-dive-mutations-tanstack-query/

《React Hooks 是一个错误吗?| jakelazaroff.com》。本文探讨了 React 编程模型的不同之处,以及为什么有些人更喜欢使用 signal-based components。作者认为,人们对组件的心理模型与 React 中的函数组件和 hooks 的工作方式不匹配。与类组件相比,signal-based components 更加相似。文章还介绍了 Solid 等信号驱动框架,并讨论了它们与 React hooks 之间的区别和权衡。最后,作者总结说,现在的框架似乎正在尝试在 hooks 的可组合性和类的稳定性之间取得平衡。

https://jakelazaroff.com/words/were-react-hooks-a-mistake/

《基于 React Query 的请求防抖》。React Query 不支持 deboucing,因此需要将其包装在一个简单的抽象中。作者提出了一种方法来扩展 React Query 以添加新功能,代码行数少于 40 行。通过动画演示,展示了防抖的实际效果,使用防抖后,应用程序只触发了 1 个请求并交换了 294 B 的数据,请求减少了 91%,传输的数据减少了 99%。

https://rafaelcamargo.com/blog/deboucing-requests-with-react-query/

《零配置类型安全》。SvelteKit 现在可以自动生成类型注释,无需手动添加。通过在 SvelteKit 应用程序中添加类型注释,可以实现网络全面的类型安全性。现在,SvelteKit 框架可以为我们类型化 load 和 data,这是计算机所擅长的 —— 让我们专注于创造性的工作。使用 VSCode 的用户只需升级到最新版本的 Svelte 扩展即可,其他编辑器的扩展也可以使用此功能,只要它们支持 Language Server Protocol 和 TypeScript 插件。

https://svelte.dev/blog/zero-config-type-safety

MDH 前端周刊第 92 期:react.dev、npm 安全、Execa 7、Reactivity、React Query

📒 Go语言爱好者周刊:第 181 期 —— ChatGPT + Golang

- - + + \ No newline at end of file diff --git "a/2023/3\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/3\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 759da1cdf8..4b632a1381 100644 --- "a/2023/3\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/3\346\234\2105\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

3月5日内容汇总

· 9 min read
加菲猫

⭐️ 小厂内部私有Go module拉取方案3

📒 知识星球相关文章

269 - 《基于 ChatGPT 的 URL 系统》

268 - 《我的 RSS 订阅》

267 - 《读书笔记:交办的技术》

259 - 《程序员高效工作法》

📒 前端工程 dotfile 相关

umi-fabric - 一个包含 prettier,eslint,stylelint 的配置文件合集

https://github.com/umijs/fabric

tsconfig/bases - 提供各种前端工程的 tsconfig.json 配置

https://github.com/tsconfig/bases

⭐️ 论文分享 | 大语言模型的 few-shot 或许会改变机器翻译的范式

📒 如何使用乾坤实现微前端架构(附 vue + react 演示)

⭐️ 你说 Go 的切片原生支持并发吗

📒 前端组件级别的抽象方向

📒 OpenAI 又放大招了,GPT3.5 API 开放使用,1分钟上手体验!

📒 uni-app 黑魔法探秘 (一)——重写内置标签

📒 「Go工具箱」Pie :一个高性能、类型安全的slice操作库

📒 全网最详细 去中心化 Module Federation的实现原理

📒 最全的React拖拽排序组件库对比研究

📒 掌握 JavaScript 中的迭代器和生成器

📒 CSS容器查询获得主流浏览器支持,是什么?怎么用

⭐️ 一文吃透 Go 内置 RPC 原理

⭐️ 用Go语言0代码10分钟完成一个学生管理系统带页面,私活必备

⭐️ Go 陷阱 - goroutine 竞态

⭐️ Go 陷阱 - interface{} 和 *interface{} 相等吗

⭐️ Redis 官方 Go 客户端来了!!!

Gopher 们应该都有使用过 Redis 吧,那 Go 的 Redis 客户端你用的哪一个呢?

不少人可能用是 github.com/go-redis/redis,毕竟这个 Star 数最多:

最近这个库被 Redis 官方”收“了,成为了 Redis 官方支持的客户端。最新版本 v9 导入地址变为:

import "github.com/redis/go-redis/v9"

Redis 官方 Go 客户端来了!!!

📒 从微信 JS-SDK 出发,一起了解 JSBridge 的神奇功能

📒 人物志|缨缨:一个有故事的女同学

⭐️ 不会「函数选项模式」的Gopher看过来~

📒 前端食堂技术周刊第 72 期:Signals 是前端框架的未来、Chrome Headless、ts-reset、magic-regexp、Bun 新文档

⭐️ 通过 React Router V6 源码,掌握前端路由

📒 MDH 前端周刊第 89 期:HTML-first、Node 调试、Dead 组件探测、框架鹰鸽博弈、沙箱

《Debugging Node.js, The Right Way》。作者介绍了如何使用 Node.js 进行调试,而不是依赖于 console.log()。首先需要使用 --inspect-brk Flag 启动Node.js进程,然后打开浏览器的开发工具,连接到 Node 进程。通过使用调试器语句和添加断点,可以方便地调试代码,并且可以通过添加条件断点来跳过不感兴趣的迭代。文章还介绍了如何在 VS Code 中直接调试,以及如何调试通过 NODE_OPTIONS 启动的 Node 脚本。

https://www.builder.io/blog/debug-nodejs

《Self hosting in 2023》。作者介绍了如何将静态页面托管在树莓派上,以及如何设置自己的 DDNS,从而将域名连接到本地服务器。作者通过购买一个二手的树莓派、安装 Coolify 和 DDClient 等简单的步骤,仅花费了大约一个小时的时间便将博客部署在了自己的本地服务器上。这样做不仅节约了成本,而且提供了更好的开发体验。文章还提到了一些可能的运营成本,如一次性成本、电费、域名费用等。

https://grifel.dev/decentralization/

《React Hooks: Compound Components》。一篇老文,作者介绍了复合组件的概念,以及如何使用 React Context 来创建具有良好表达性和实用性的组件 API 。它使用一个例子来展示复合组件 API 的好处,以及如何使用 React.cloneElement 和 React Context 来实现它。

https://kentcdodds.com/blog/compound-components-with-react-hooks

《Maximising performance with React code splitting techniques》。React 是一个流行的 JavaScript 库,用于构建用户界面,但随着应用程序规模的增长,JavaScript 包的大小会变得很大,导致加载时间慢和性能差。为了解决这个问题,React 提供了多种代码分割技术,允许你将代码分割成更小的块,减少初始 JavaScript 捆绑的大小,提高应用程序的性能。这篇文章介绍了 React 的代码分割技术,包括动态导入、带 Suspense 的 React Lazy、可加载组件、基于路由的代码拆分、预加载、嵌入关键的 CSS 和动态块。

https://edvins.io/react-code-splitting-techniques

《Improved type safety in Storybook 7》。本文介绍了 Storybook 7 中的类型安全改进。Storybook 7为组件 Story 格式(CSF)3和新的TypeScript(4.9+)满足操作者的组合实现了增强的类型安全。新的 Meta 和 StoryObj 类型可以自动推断出组件道具的类型。通过使用 satisfies 操作符,TypeScript现在能够更好地显示这些警告。Storybook 7 测试版中已经可以使用新的 Meta 和 StoryObj 类型。

https://storybook.js.org/blog/improved-type-safety-in-storybook-7/

《The case for frameworks》。本文探讨了 JavaScript 框架的使用和开发者的自我利益,其中涉及了进化博弈论中的鹰鸽博弈概念。文章指出,即使 JavaScript 框架的性能不佳,但由于其在经济层面的优势,它们仍然非常受欢迎。「当71%的开发者已经在使用React时,招聘React开发者就变得容易了,从经济角度来看,这是一个巨大的优势。」React 作为一个具体的JS框架被讨论,并且指出单页应用程序的开发对于某些网站是很有用的,而 React 可以帮助开发者省去时间和成本。「开发人员是昂贵的。他们的工资最终是由客户支付的。但并不是所有的客户都同样有价值。」

https://seldo.com/posts/the_case_for_frameworks

《useSyncExternalStore First Look》。关于 useSyncExternalStore 的介绍。1)useSyncExternalStore 主要是用于库,但不只是用于库。 它是用来订阅外部状态的,但意义比我想象的要广,浏览器是一个外部存储,你可能想在你的 React 应用中与之同步 它是并发安全的,所以可以避免 UI 中的视觉不一致,2)如果订阅函数参数不稳定,React 会在每次渲染时重新订阅到 Store,3)getSnapshot 函数参数必须返回不可变的值,4)其可选的第三个函数参数 getServerSnapshot 是为了支持 SSR 它必须在初始客户端渲染时返回与服务器上完全相同的数据,这意味着你不能在服务器上读取浏览器的API。 如果你不能在服务器上提供一个初始值,通过在服务器上抛出一个错误并将其包裹在边界中来显示一个回退,使该组件只在客户端使用。

https://julesblom.com/writing/usesyncexternalstore

MDH 前端周刊第 89 期:HTML-first、Node 调试、Dead 组件探测、框架鹰鸽博弈、沙箱

📒 Vue3中watch与watchEffect有什么区别

📒 「每周译Go」如何构建和安装 Go 程序

📒 Go语言爱好者周刊:第 178 期 — Go 实现的纸牌游戏

- - + + \ No newline at end of file diff --git "a/2023/4\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/4\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 85390eb9bf..b829e98838 100644 --- "a/2023/4\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/4\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月16日内容汇总

· 9 min read
加菲猫

image

题图:an asian city, in the style of japanese traditional art influence。

⭐️ Go 1.20.3 又是一堆安全问题,我们还是抽空更新一下吧

⭐️ 技术文章配图指南

📒 2023 年如何搭建新的 React 项目

1、create-next-app

$ pnpm create next-app@latest nextjs-app

2、create-t3-app

了解了下 T3 App 架构。T3 App 是一套全栈的技术栈,一个脚手架,包含客户端的 Next.js、Tailwind,服务端的 Prisma、Next Auth,API 侧的 tRPC。主打类型安全,所以 T3 的 T 即 Typed(类型安全)。3 个 T 分别是 React 前端、数据库客户端和 API 调用端的类型安全。

image

T3 App 的 3 个理念值得学习。1)解决问题,不添加「所有」东西,只加能解决问题的技术,2)负责任的做技术革新,在风险小的地方使用风险大的技术,3)类型安全不是可用可无,因为可以提高生产力和减少错误发生。

全栈技术栈除了 T3 App,还有其他选择,见下图。图中有个变化是 Bison 也将切换 GraphQL 到 tRPC,他们还写了文章介绍他们《为啥舍弃 GraphQL 而选择 tRPC》(Why we ditched GraphQL for tRPC),主要原因是,1)可以少写一半的样板代码,2)避免不必要的代码生成,tRPC 基于类型推导,3)Client 包尺寸,GraphQL 是 tRPC 的 3.5 倍,4)tRPC 可结合 React Query 使用,Apollo 搞不太好的缓存啥的都属于基础功能。

image

tRPC 发布 10,似乎正在成为越来越多人的选择,不仅是 T3 App 技术栈的选择,同时 Bison 团队也写了文章介绍他们《为啥舍弃 GraphQL 而选择 tRPC》

Tailwind 其实不是类型安全的,需要借助编辑器辅助。比如 VSCode 要装 Tailwind CSS IntelliSense,WebStorm 则是内置支持。

NextAuth 内置的是 Discord 登录,因为配置最简单,只要在 .env 里提供 token 即可,也可稍做配置切换到 github、twitter、google 等登录方式。

部署时可以把数据库部署到 Railway 或 PlanetScale,然后把其余部分部署到 Vercel、Railway、Render 或 Fly。Vercel 虽然部署起来简单,但缺点也很明显,问题是在 Lambda 函数里跑 Prisma 会有明显的冷启动时间,性能不太好。

本地实操跑了个 Blog 的 CURD + 部署流程,部署到 Railway 的 postgresql 数据库和 Vercel 的前端,一切顺利。

文档中的「其他推荐」也值得一看,包括数据流、组件库、动画、部署和基础设施、统计等维度的推荐。

$ pnpm create t3-app@latest

参考:

Create T3 App

GitHub - t3-oss/create-t3-app: The best way to sta...

https://dev.to/ajcwebdev/a-first-look-at-create-t3...

Prisma | Next-generation ORM for Node.js & TypeScr...

Railway

Why we ditched GraphQL for tRPC

📒 webpack核心模块tapable源码解析

📒 速度提高几百倍,记一次数据结构在实际工作中的运用

📒 如何终止某个端口运行的进程

发现 VS Code 有个 bug,终端结束 Next.js 服务(在 3000 端口运行)之后再启动,此时发现 3000 端口被占用了,自动改成 3001 端口,说明原先 Next.js 进程还在继续跑。

可以用 lsof -i 命令查看某个端口正在运行的进程 ID:

$ lsof -i :3000

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 61440 garfield 21u IPv6 0x44c3c99e2d153375 0t0 TCP *:hbci (LISTEN)

找到 PID 之后,用 kill 命令终止进程:

$ kill 61440

📒 我问了鹅厂程序员:你们工作中怎么用ChatGPT?如何高效Prompt

⭐️ singleflight 设计与实现

📒 🤩 如何解决 SVG 图片中字体失效的问题

⭐️ Go sync.Once:简约而不简单的并发利器

📒 React 中文周刊 #135 - Dan Abramov 探索 React 服务端组件

⭐️ Go 环境变量 - GODEBUG 详解

📒 2023再谈前端状态管理

📒 Vite 4.3 性能大幅提升!

📒 前端食堂技术周刊第 78 期:WebGPU、Astro 2.2、Node.js 事件循环可视化指南、实用 Web API 规范

📒 useState与useReducer性能居然有区别

⭐️ Go语言中常见100问题-#32 Ignoring the impact of using pointer ...

📒 mysql的varchar字段最大长度真的是65535吗?

📒 几个你不知道却非常实用的JavaScript APIs

⭐️ Go设计模式--访客模式

⭐️ Go 语言 15 个内置函数详解

⭐️ GoLand 2023.1 正式发布,看有哪些新功能

📒 MDH 前端周刊第 95 期:-10x 工程师、Next.js、WebGPU、Chakra UI、写作

  • Vercel Edge Config 已普遍可用。
  • Nextjs v13.3 发布,新路由约定等。
  • Vite v4.3 比 Turbopack 启动快。

《如何成为一名 -10x 工程师》。本文指出,虽然 “10 倍工程师” 可能是神话,但确实存在 “-10 倍工程师”。为了成为一名 “-10 倍工程师”,可以采用以下策略:使 10 个工程师的输出无效;尽可能在开发过程中更改需求以避免责任;创建 400 小时的忙碌工作;让团队执行类似于工作的任务;创建毫无意义的仪式等。此外,还可以浪费 400 小时的编译 / 构建时间,编写毫无意义的测试,将 10 个工程师困在技术讨论中等等。

https://taylor.town/-10x

《程序员被打断:中断和上下文切换的真正成本》。编程中的中断和上下文切换是直接影响程序员日常生产力的两个最昂贵因素。虽然没有永久避免它们的方法,但有一些有趣的策略可以最小化它们的影响。根据各种科学研究,经过中断后需要至少 10-15 分钟才能重新进入 “区域”(Parnin:10,vanSolingen:98)。基于任务的复杂性和你的精神能量,肯定需要更多的时间。当你有很多未完成的代码时,中断发生时,返回到流状态可能会更具挑战性。

https://contextkeeper.io/blog/the-real-cost-of-an-interruption-and-context-switching/

《Next.js 13.3》。Next.js 13.3 发布,新增了社区请求的流行功能,包括:基于文件的元数据 API、动态 Open Graph 图像、应用程序路由器的静态导出、并行路由和拦截等。其中,基于文件的元数据 API 可以方便地自定义页面以改善 SEO 和 Web 共享;动态 Open Graph 图像可以使用 JSX、HTML 和 CSS 生成 OG 图像;应用程序路由器的静态导出支持完全静态导出,可避免在客户端加载不必要的 JavaScript 代码,减小捆绑大小并实现更快的页面加载;并行路由和拦截可以同时在同一视图中呈现一个或多个页面,如复杂的仪表板或模态框。

https://nextjs.org/blog/next-13-3

《从 Webpack 迁移到 Remix》。Remix 宣布推出基于 Webpack 的编译器和开发服务器,以帮助使用 Webpack 的应用程序逐步迁移到 Remix。这个版本可以让用户从第一天开始使用所有的 Webpack 加载器和插件,并逐渐将每个路由迁移到 Remix。Remix 还提供了一个迁移指南,以帮助 Webpack 用户更容易地进行迁移。

https://remix.run/blog/migrate-from-webpack

MDH 前端周刊第 95 期:-10x 工程师、Next.js、WebGPU、Chakra UI、写作

- - + + \ No newline at end of file diff --git "a/2023/4\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/4\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 6d1dda19b2..a87392c324 100644 --- "a/2023/4\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/4\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月23日内容汇总

· 11 min read
加菲猫

image

题图:rainy day, a water wheel in the green river, green plants and flowers in the foreground, mountains and water in the distance。

📒 【第2924期】如何在 Gitlab 中使用 ChatGPT 进行 CodeReview

📒 「Go框架」深入理解gin框中Context的Request和Writer对象

📒 聊聊React中的隐藏彩蛋功能

⭐️ Go内存分配与逃逸分析

一文详解Go内存分配与逃逸分析

Go 为什么性能高? 一文带你了解“逃逸分析”

先聊聊「内存分配」,再聊聊Go的「逃逸分析」

「刷起来」Go必看的进阶面试题详解

Go内存分配和逃逸分析-实践总结篇

通过实例理解Go逃逸分析

『每周译Go』Go如何做逃逸分析

📒 给想玩AI的新手|Stable Diffusion 保姆级入门手册

⭐️ Go 方法接收器:选择值接收器还是指针接收器

⭐️ Go 内存模型

Go 内存模型

Happens before 原则在 Go 内存模型中的应用举例

『每周译Go』更新Go内存模型

参考:

https://go.dev/ref/mem

https://research.swtch.com/gomm

⭐️ sync.RWMutex 设计与实现

⭐️ Go 单元测测时尽量用 fake object

📒 定制自己的文档问答机器人

⭐️ Go语言中常见100问题-#33 Making wrong assumptions during map iterations

📒 我把我的简历丢给chatGPT,他问了我这些问题

⭐️ sync.Mutex 设计与实现

📒 React的并发悖论

📒 How I improve my skills in Typescript #2 : Mapped Type

📒 TypeScript 4.9 satisfies

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator

# TypeScript 4.9: satisfies operator

# Typescript’s new ‘satisfies’ operator

⭐️ Go语言中常见100问题-#72 Forgetting about sync.Cond

⭐️ Golang package sync 剖析(二): sync.WaitGroup

⭐️ Golang package sync 剖析(三):sync.Cond

⭐️ Golang package sync 剖析(四):sync.Map

⭐️ Golang语言标准库 sync 包的 Cond 怎么使用

⭐️ Go标准库sync.Cond详解 | Gopher Daily (2021.04.13) ʕ◔ϖ◔

⭐️ sync.WaitGroup 设计与实现

📒 实践指南-前端性能提升 270%

⭐️ Bytes 发布 React, Visualized 教程

⭐️ Mastering React: Techniques to Take Your UI to the Next Level

⭐️ Go 语言中没有枚举类型,但是我们可以这样做

📒 React Query 完全指南,时下最热辣的请求库!

📒 React 中文周刊 #136 - “forwardRef()”: 如何将 ref 传给子组件

📒 gin框架中如何让日志文字带颜色输出

⭐️ sync/atomic 设计与实现

⭐️ 理解unsafe-assume-no-moving-gc包

📒 做量化交易发愁写代码?一招教你白嫖GPT智能编程神器(重制版)

📒 Uber实践:运维大型分布式系统的一些心得

📒 Go 语言怎么通过通信共享内存

⭐️ Go设计模式--备忘录模式,带暂存的业务功能可以参考它来实现

📒 一文带你快速入门TLS/SSL

⭐️ Go 汇编语言快速入门

📒 MDH 前端周刊第 96 期:lazyrepo、CodeWhisperer、taxonomy、WP Playground、MVP

《GitHub - ds300/lazyrepo: 用于 npm/pnpm/yarn monorepos 的缓存任务运行器。》。lazyrepo 是一个针对 npm/pnpm/yarn monorepos 的零配置缓存任务运行器。它适合于 turborepo 所开创的领域:使 package.json “scripts” 扩展,而无需采用像 nx、bazel、rush 或 buck 这样的大型工业级构建系统。lazyrepo 非常快速,尽管它是用 TypeScript 编写而不是一些年轻、英俊、聪明、有趣的系统语言,但它比 turborepo 要快得多。

https://github.com/ds300/lazyrepo

《ChatGPT 的工作原理:深入探究 | Dan Hollick 🇿🇦》。本文介绍了大型语言模型 ChatGPT 的工作原理。这些模型通过计算输入和输出之间的概率来预测下一个单词或符号。为了实现这一点,它们使用神经网络来处理输入并生成输出的概率。在简单的情况下,神经网络由输入层、隐藏层和输出层组成,其中每个神经元都与相邻层中的神经元相连,并具有一个权重。当输入值通过神经元时,它会乘以该神经元的权重,并将结果传递给下一层中的所有神经元。然后,神经元将这些值相加,并将结果压缩到 - 1 到 1 之间,并将其传递给下一层中的每个神经元。最后一个隐藏层的神经元也是如此,但是将值压缩到 0 到 1 之间,并将其传递到输出层。

https://typefully.com/DanHollick/yA3ppZC

《在页面退出时显示未保存的表单数据警告。》。本文介绍了如何实现一个 FormPrompt 组件,以提高 Web 应用程序的用户体验。该组件可以在用户尝试离开具有未保存更改的页面时发出警告。作者讨论了使用纯 JavaScript 的 beforeunload 事件处理此类情况,以及使用 React Router v5 中的 Prompt 组件和 React Router v6 中的 useBeforeUnload 和 unstable_useBlocker 钩子的 React 特定解决方案。

https://claritydev.net/blog/display-warning-for-unsaved-form-data-on-page-exit

《Amazon CodeWhisperer,个人免费使用,现已普遍提供 | Amazon Web Services》。Amazon CodeWhisperer 是一款实时 AI 编码助手,现已正式推出。它可以帮助开发人员快速、安全地编写代码,而无需离开他们的 IDE 进行研究。CodeWhisperer 可以在多个 IDE 中使用,包括 Visual Studio Code、IntelliJ IDEA 等,并支持 Python、Java、JavaScript、TypeScript 和 C# 等多种语言。此外,它还具有筛选可能被认为是有偏见或不公平的代码建议的功能,以及扫描生成和开发人员编写的代码以查找难以检测的漏洞并提供修复建议的安全扫描功能。CodeWhisperer 的个人版免费使用,可通过电子邮件注册。专业版则提供了更多的管理功能和安全扫描限制。

https://aws.amazon.com/blogs/aws/amazon-codewhisperer-free-for-individual-use-is-now-generally-available/

《用 LLM 替换我的最好的朋友,训练了 50 万个群聊消息》。作者用一个大型语言模型训练了他和他的好友们在大学时期使用的聊天记录,并通过 Modal 和 Hex 完成了这个项目。作者将原始聊天数据转换成了可供微调的格式,然后使用 LLaMa 进行微调。最终,作者将模型部署到了 Modal 上,并建立了一个类似于 iMessage 的前端界面,使得所有人都可以与 “机器人男孩” 聊天。作者强烈鼓励大家尝试这种无聊但复杂的 AI 项目,因为它是一个入门级别的 AI 项目,可以让你更深入地了解 LLMs 以及如何针对特定场景进行微调。

https://www.izzy.co/blogs/robo-boys.html

《RFC:next/third-parties・vercel/next.js・讨论 #48256》。Next.js 计划推出 next/third-parties 包,以简化开发人员在应用程序中加载流行第三方库的体验。该包将提供预配置的包装器组件,以确保流行的第三方资源能够高效加载,并随着最佳实践的演变而持续高效。为了避免增加 Next.js 的安装 / 包大小,这个包可以单独存在于核心 next 库之外,但仍然在同一个 monorepo 中。此外,Next.js 还将考虑支持其他流行的第三方库,例如 Sentry、DataDog 和 Facebook Pixel。

https://github.com/vercel/next.js/discussions/48256

《有两种类型的软件工程师》。这篇文章探讨了两种软件工程师的思维方式。第一种类型认为问题很容易解决,只需要要求人们做 X 即可。而第二种类型则认为问题很难解决,因为它需要人们去做 X。第一种类型认为只要不是技术问题就很容易解决,因为 “我们可以要求人们做 X”。而第二种类型则认为这很难,因为它不是技术问题。作者称第一种类型的工程师相信大写字母 E 的工程学,认为存在着冷酷、坚实的真理;有数学和物理;是应用科学。而第二种类型的工程师则更注重人,他们知道在所有的工程工作(和问题)中,人是核心所在。他们接受了事情变得混乱的事实,并迎接了一个更大的挑战,尽管这会带来混乱,但仍然要做出有价值和有影响力的工作。

https://registerspill.thorstenball.com/p/two-types-of-software-engineers

《最有价值程序员》。本文讨论了成为最有价值的程序员(MVP)的概念。与 “最小可行产品” 类似,MVP 并不是一个具体的概念,而是一个追求的目标。这篇文章提供了一些建议,帮助程序员成为更有价值的人,包括不要过度关注代码风格、正确性、DRY 和性能,而是关注业务需求、解决问题以及与同事沟通。此外,作者还提到了保持身心健康的重要性,因为只有这样才能保持高效率和创造力。

https://arendjr.nl/2023/04/mvp-the-most-valuable-programmer

MDH 前端周刊第 96 期:lazyrepo、CodeWhisperer、taxonomy、WP Playground、MVP

- - + + \ No newline at end of file diff --git "a/2023/4\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/4\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index f4d74eceea..8d50ae7a05 100644 --- "a/2023/4\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/4\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月2日内容汇总

· 13 min read
加菲猫

image

题图:Landscape illustration, Hayao Miyazaki, in the sea of flowers, clouds, fantastic sky, warm colors, simple composition。

📒 地表最强动画基础库:framer-motion

framer-motion v10.6 特性:animate api 可以控制随时停止、取消、完成。

https://www.framer.com/motion/animate-function/#controls

📒 PromQL 相关内容

Introduction to PromQL, the Prometheus query language

https://promlabs.com/promql-cheat-sheet/

为 Apache SkyWalking 构建 Grafana Dashboard —— 原生 PromQL 支持

📒 学会 Go select 语句,轻松实现高效并发

⭐️ 使用go test框架驱动的自动化测试

📒 面试遇到 性能优化 必答的 9 个点,加分

几点补充:

1、SPA 项目,一个路由对应一个页面,如果不做处理,项目打包后,会把所有页面打包成一个文件

实际 Webpack 打包的时候,会综合考虑 chunk 大小、缓存复用率、减少模块冗余、并行请求数等因素,不一定把 Initial Chunk 打包为单文件,也可以是多个文件,但是这些文件一定是 同步加载 的。

可以参考 optimization.splitChunks 内置分包规则:

https://webpack.js.org/plugins/split-chunks-plugin/#defaults

2、将路由全部改成懒加载,重新打包后,首页资源拆分为 app.js 和 home.js,以及对应的 css 文件,通过路由懒加载,该项目的首页资源压缩约 52%

Code-Splitting 不一定能明显优化首屏加载性能。例如 Initial Chunk 和 Async Chunk 都有一些体积较大的公共依赖,例如 reactreact-domreact-router-dom 等,这种情况下,即使针对每个页面组件做了懒加载,公共依赖仍会被视为同步 chunk(因为首屏加载需要依赖这些公共包),实际异步加载的只有体积很小的业务代码。

当然 Code-Splitting 在特定场景下还是非常有用的,例如有上百个路由的后台管理系统,虽然每个页面的业务代码体积很小,但是首屏一次性加载几百个页面,压力还是有点大(首屏时间随业务规模线性增长)。如果做了路由懒加载,则可以按需加载当前页面的业务代码,保证首屏时间都是 O(1) 复杂度。

3、项目打包后,发现 home.js 和 about.js 均包括了该弹框组件的代码

与第一点类似,Webpack 打包的时候,不仅考虑模块冗余问题,还会考虑减少并行请求数。例如两个以上 Async Chunk 存在公共依赖,若公共依赖体积较小,则 Webpack 可能不会单独抽提 chunk,而是给每个 Async Chunk 都打包一份公共依赖,好处是可以减少网络请求数量。

面试遇到 性能优化 必答的 9 个点,加分!

📒 Go Mutex:保护并发访问共享资源的利器

⭐️ 【补充代码】Go BIO/NIO探讨(3): 基于系统调用实现tcp echo server

📒 「高频必考」Docker&K8S面试题和答案

⭐️ gin框架中Context的Get、Query、Param函数都是从哪里获取数据的

⭐️ 深入解析非阻塞Golang IO框架nbio

⭐️ Go 调试工具 - delve 快速入门

⭐️ Golang反射学习:手写一个RPC

📒 相关链接

推荐部署平台 Railway,可以部署 Docker 容器

https://railway.app/dashboard

谁会拒绝一个免费的部署服务呢

TiDB 是一个开源、云原生、分布式、与 MySQL 兼容的数据库,用于弹性规模和实时分析

https://github.com/pingcap/tidb

⭐️ Go如何自动解压缩包?| 文末送书

⭐️ 高并发系统设计(1): 如何实现抖音关注/粉丝列表

⭐️ Go协程池(2): 如何实现协程池

⭐️ Go协程池(1): 线程vs协程

⭐️ 简洁而不简单的 sync.Once

📒 axios的替代方案的思考和实践

axios 存在哪些问题:

  • 与React、Vue等框架割裂
  • 在性能方面毫无作为(例如没有缓存、无法避免重复请求等等)
  • 臃肿的体积
  • TS 类型定义混乱(在拦截器中对响应数据进行解构,但是接口请求响应的数据还是 AxiosResponse 类型,需要手动用 as 断言)

axios的替代方案的思考和实践

📒 chatgpt逐字逐行回答的效果是如何实现的

一句话总结:通过 Content-Type: text/event-stream 做流式响应。

chatgpt逐字逐行回答的效果是如何实现的

📒 可视化搭建 - keepAlive 模式

⭐️ Go 语言实现创建型设计模式 - 工厂模式

⭐️ 为什么 Go 不支持 []T 转换为 []interface

⭐️ Go设计模式-迭代器到底是不是一个多此一举的模式

📒 MDH 前端周刊第 93 期:npm、sharp images、React Labs、fzf、手写 Signals

《从 ts-node 迁移到 Bun》。本文介绍了如何将一个使用 ts-node 编写的控制台应用程序迁移到 Bun,以及在迁移过程中遇到的一些问题和解决方案。作者发现 Bun 比 ts-node 快 50%,并且迁移过程相对容易。他认为这让他对 Bun 充满信心,并期待未来更多地使用它。

https://johnnyreilly.com/migrating-from-ts-node-to-bun

《加速 JavaScript 生态系统 - npm 脚本》。本文介绍了如何优化 JavaScript 中常用的 “npm scripts”,以减少其约 400 毫秒的开销。作者通过分析 npm CLI 的代码结构,发现大部分时间都花费在加载组成 npm CLI 的模块上。作者通过惰性加载、减小模块图等方式,将运行 npm scripts 的时间从 400 毫秒降至 22 毫秒。作者指出,JavaScript 工具中普遍存在的问题是没有简便的方法来缩短模块图,因此可以考虑在发布时将代码打包,以减少加载时间。

个人理解再总结一下:

1)如何检测 npm scripts。which npm 命令可以拿到 npm 解释器路径,因此可以通过 node --cpu-prof $(which npm) run myscript 运行脚本、生成 profile;

2)惰性加载。通过 profile 可以发现,npm cli 运行大部分时间其实都在加载模块。我们知道,Node 具有 JIT 特性,因此 require 实际上是非常昂贵的(回顾一下 require 加载机制)。建议按需 require,将 require 推迟到要用的时候再去加载,例如放在条件判断里面,可以显著提升 cli 启动性能(例如 Babel 插件、Webpack loader 支持配置字符串而不是传递实例,实际上也是延迟加载);

3)减小模块图。解释器在遇到 top level import or require 语句时,就会加载、解析模块(还是回顾一下 require 加载机制),引起大量文件 IO。与 Web 工程不同,Node 工程可以将所有代码打包到一个单文件中(target: "node"、禁用 Webpack 默认分包规则 optimization.splitChunks.cacheGroups.default: false),这样避免了模块加载开销,可以显著提升 cli 应用启动性能。需要注意的是,如果一次性投喂代码太多,还是会影响性能,解法是和上面提到的惰性加载结合用(也就是 Node 不需要 bundle-splitting 分包,但可以用 code-splitting 做异步懒加载)。

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-4/

《如何获得一个酷炫的 NPM 包名?》。本文介绍了如何通过 NPM 的争议政策来申请将占位包的所有权转移给自己。对于长期没有更新或仅仅是占位的包,NPM 工作人员会在 4 周后自动将包的 owner 设置为申请者的用户名。申请者需要发送邮件至包的所有者并抄送 support@npmjs.com,并说明申请转移的原因、包名以及自己的 npm username。

https://unix.bio/posts/how-to-get-npm-package-name

《您可能不需要的 Hooks》。本文介绍了 React Hooks 中一些不太常用的 Hook。

https://reacttraining.com/blog/hooks-you-probably-dont-need

《React Labs:我们正在进行的工作》。React Labs 发布了最新的研究进展,包括 React Server Components、Asset Loading、Document Metadata、React Optimizing Compiler、Offscreen Rendering 和 Transition Tracing 等。其中,React Server Components 是由 React 团队设计的一种新的应用架构,提供了一种新的组件类型 —— Server Components,它们可以在构建期间运行,也可以在服务器上运行,让您无需构建 API 即可访问数据层。另外,React Labs 还在开发 Suspense、Transition Tracing 等功能,以提高 React 的性能和用户体验。

https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023

《GitHub Copilot X:AI 动力的开发者体验 | GitHub 博客》。GitHub Copilot X 是 GitHub 的新一代 AI 辅助开发工具,它将 AI 引入整个开发生命周期中。除了自动完成注释和代码外,Copilot X 还支持聊天和语音交互,并在 pull requests、命令行和文档中提供 AI 支持。Copilot X 基于 OpenAI 的 GPT-4 模型,可以为开发人员生成单元测试、修复错误等。此外,Copilot X 还支持针对文档的 ChatGPT 接口,让开发人员能够快速获取关于 React、Azure Docs 和 MDN 等文档的答案。

https://github.blog/2023-03-22-github-copilot-x-the-ai-powered-developer-experience/

《如何在 2023 年开始一个 React 项目》。本文介绍了几种新 React 项目的起始套件,包括 React with Vite、React with Next、React with Astro 等。作者对每种套件的优缺点、开发者所需技能水平以及针对 React 开发者提供的特性进行了分析,并给出了不同需求的三种解决方案。最后,文章总结了一些关于 React 起始项目的思考和建议。

https://www.robinwieruch.de/react-starter/

《使用 useImperativeHandle 进行细调 refs》。本文介绍了在 React 中使用 refs 和 useImperativeHandle 的方法。Refs 是一种用于在组件之间传递数据的机制,可以让你访问 DOM 节点并使用原生 JavaScript DOM API 对其进行操作。useImperativeHandle 允许你自定义要公开的 ref 处理程序,以便只公开子组件的特定方法。然而,需要注意的是,在 React 中,最好不要使用 refs 来实现可以通过 props 实现的命令式行为,因为这违反了 React 的核心原则。

https://prateeksurana.me/blog/fine-tuning-refs-with-useimperativehandle/

Umi 例行每周四发一版,我觉得有趣的功能包括,1)基于 Rust 实现类 es-module-lexer 解析器用于 prepare 阶段采集 import 数据,2)配置校验陆续从 joi 迁移到 zod,3)新增 umi? 命令,这是框架结合 openai 的第一个尝试,4)MFSU 支持 WASM。

📒 Golang 相关文章

The one-and-only, must-have, eternal Go project layout

https://appliedgo.com/blog/go-project-layout

OpenAI 的 Golang SDK,包括 ChatGPT、GPT-3、GPT-4 等。

https://github.com/sashabaranov/go-openai

一个检测结构体是否可以占用更少内存的工具。

https://github.com/dkorunic/betteralign

基于 Docker 的热重载开发。

https://github.com/dkfbasel/hot-reload

📒 Go语言爱好者周刊:第 182 期 —— GPT Go SDK

- - + + \ No newline at end of file diff --git "a/2023/4\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/4\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 9853af24f8..23b779b2c1 100644 --- "a/2023/4\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/4\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月30日内容汇总

· 12 min read
加菲猫

📒 写给开发同学AI强化学习入门指南

📒 TypeScript 5.1 beta 发布:函数返回值类型优化、Getter/Setter 类型优化、JSX 增强

📒 TypeScript 5.0 beta 发布:新版 ES 装饰器、泛型参数的常量修饰、枚举增强等

📒 TypeScript 4.9 beta 发布:鸽置的 ES 装饰器、satisfies 操作符、类型收窄增强、单文件级别配置等

📒 ES2020 可选链语法一个注意点

ES2020 中的可选链语法可以安全访问对象中的属性:

obj?.prop       // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call

实际开发中的示例如下:

import * as React from "react";

const { useCallback } = React;

type IProps = {
value?: string;
onChange?: (value: string) => void;
}

const Comp: React.FC<IProps> = ({ value, onChange }) => {
const handleChange = useCallback((val: string) => {
// 调用 `onChange` 需要可选链语法
onChange?.(val);
}, []);

const resolvedValue = value || "";

return (
<LayoutWrapper
value={resolvedValue}
onChange={handleChange}
/>
)
}

最近看到同事写的代码用到可选链,结果报错了:

// ❎ Invalid left-hand side in assignment expression.
document.querySelector(".content-main")?.style.display = "block";

但是以上代码,如果不用可选链则可以正常赋值:

// ✅ Correct
document.querySelector(".content-main").style.display = "block";

我们可以看下 Babel 编译的结果:

// 源码
document.querySelector(".content-main")?.style.display;

// 编译结果
var _document$querySelect;
(_document$querySelect = document.querySelector(".content-main")) === null ||
_document$querySelect === void 0
? void 0
: _document$querySelect.style.display;

document.querySelector(".content-main") 返回的值不为 null 的时候,此时原始表达式可以正常访问,也可以进行赋值。但问题就在于 document.querySelector(".content-main") 返回值为 null 的时候,可选链语法会将整个表达式的值转为 undefined,此时如果再赋值就相当于给 undefined 赋值,这个行为显然是不符合预期的。因此,需要注意,可选链语法只能访问对象属性,不能进行赋值。

顺便再提两个可选链语法的细节:1)为啥用一个 _document$querySelect 临时变量缓存 ?. 前面的执行结果,答案是为了避免对象属性重复访问、方法重新调用等,可以提升性能,2)为啥用 void 0 代替 undefined,个人猜测是为了更好的语义性,因为 undefined = "aaa"; 这个赋值虽然无效,但是在非严格模式下不会报错,因为 undefined 实际上是 window 对象上的只读属性,而 void 0 = "aaa"; 这句即使非严格模式也会报错。

参考:

https://babeljs.io/docs/babel-plugin-proposal-optional-chaining

https://github.com/tc39/proposal-optional-chaining

📒 【第2929期】React Refs: 从访问 DOM 到命令式 API

⭐️ GMP 调度器(下篇)- 线程

⭐️ 并发编程-信号量的使用方法和其实现原理

⭐️ 并发编程--用SingleFlight合并重复请求

⭐️ Go的atomic.Value为什么不加锁也能保证数据线程安全

⭐️ Golang 五种原子性操作的用法详解

⭐️ Webpack4的压缩阶段的性能优化和踩坑

⭐️ GMP 调度器(中篇)- 算法

⭐️ 快速上手 Go CGO,掌握在 Go 里写 C!

📒 在 Git 中撤消更改的 6 种方法!

⭐️ Go 1.21新特性前瞻

📒 一个低代码拖拽的表单编辑器,开源咯!!!

⭐️ GMP 调度器(上篇)- 数据结构

⭐️ Go pprof 相关

Go 服务自动收集线上问题现场

go pprof实战

生产环境Go程序内存泄露,用pprof如何快速定位

⭐️ 为什么 recover 必须在 defer 中调用

📒 React 相关汇总

Awesome React:近 500 个 React 项目和资源 — 这是一个与 React 生态系统相关,经常更新且深入的文章和资源集合。

https://github.com/enaqx/awesome-react

Storybook v7.0 发布 — 几周前发布了 v7.0 版本,但官方博文直到上周才发布。无论如何,对于这个受欢迎的组件开发工具来说,这是一个重要的版本更新,现在包括一流的 Vite 支持、对 Next.js 和 SvelteKit 的零配置支持、焕然一新的 UI 等更多功能。

https://storybook.js.org/blog/storybook-7-0/

必须知道的 React 可移植性模式 — 采用这些模式有助于避免“元框架锁定”,如果你选择的工具发生了你不喜欢的演变,你就不会被束缚。

https://www.youtube.com/watch?v=yi8UCnXPu8U

使用 React Hook Form 实现高级多步表单

https://claritydev.net/blog/advanced-multistep-forms-with-react

next-route-visualizer: 将 Next.js v13+ 应用路由结构树形可视化 — 一款用于可视化 Next.js 应用目录路由的软件包,该软件包的功能可以参考这个 演示。

https://github.com/DiiiaZoTe/next-route-visualizer

Simple Light v2.0: 一款用 Tailwind CSS 和 React 实现的落地页模版 — 旨在为开发人员提供创建面向 SaaS 产品、在线服务等落地页所需的所有基本组件。

https://github.com/cruip/tailwind-landing-page-template

📒 一文教你搞定所有前端鉴权与后端鉴权方案,让你不再迷惘

📒 protoc 插件-protoc-gen-grpc-gateway-gosdk

⭐️ 为什么 defer 的执行顺序和注册顺序不同

📒 MDH 前端周刊第 97 期:Vite 4.3、Node 20、pretty-ts-errors、React Query 5

《发布 v5.80.0・webpack/webpack》。Webpack v5.80.0 的新增功能包括支持在 import.meta 中使用解构赋值、支持带有 AwaitExpression 的解构赋值的树摇、引入 errorsSpace 和 warningsSpace 以获得更可读的跟踪信息等。Bug 修复主要涉及 CSS 相关问题、语法错误、模块 ID 分配等。

https://github.com/webpack/webpack/releases/tag/v5.80.0

《Deno vs. Node:没有人准备好迎接这个变化 | .cult by Honeypot》。本文介绍了 Node.js 和 Deno 两个 JavaScript 运行环境的比较。Node.js 是一个流行的服务器端、开源、跨平台的 JavaScript 运行环境,自 2009 年以来一直占据着 Web 开发世界的主导地位。相比之下,Deno 在设计上有所改进,提供了更安全的框架和现代特性,由 Node.js 的创始人 Ryan Dahl 推出。然而,尽管 Deno 解决了 Node.js 的一些设计缺陷,但采用 Deno 的速度非常缓慢,大多数开发人员仍然满意于 Node.js。本文将探讨这种现象背后的原因,并对 Node.js 和 Deno 进行比较,从第三方包管理、API、安全性和 TypeScript 支持等方面进行分析。

https://cult.honeypot.io/reads/deno-vs-node-main-differences/

《发布 Vite 4.3。》。Vite 4.3 发布,主要改进了开发服务器的性能。该版本优化了解析逻辑,改进了热路径,并实现了智能缓存,以查找 package.json、TS 配置文件和已解决的 URL。此外,该团队正在开发一个官方基准测试工具,以获取每个 Pull Request 的性能指标,并通过 vite-plugin-inspect 提供更多的性能相关功能来帮助用户识别应用程序的瓶颈。明年他们将发布 Vite 5,这将是今年唯一的 Vite 主要版本,同时也会放弃对 Node.js 14 和 16 的支持。

https://vitejs.dev/blog/announcing-vite4-3.html

《我们如何让 Vite 4.3 更快》。这篇文章介绍了 Vite 4.3 是如何通过优化解析策略、使用异步函数、并行处理和 JavaScript 优化等方式来提高性能的。

https://sun0day.github.io/blog/vite/why-vite4_3-is-faster.html

《用 Next.js 13 和 React Server Components 建立博客》。本文介绍了如何使用 Next.js 13 和 React Server Components 构建博客,并提供了实际示例。文章包括设置项目、文件结构、动态路由、获取和呈现 Markdown、SEO、部署等内容。作者还介绍了如何使用 next-mdx-remote 和 Bright 进行语法高亮。本文旨在帮助读者快速搭建自己的博客,并鼓励读者进行自己的实验和探索。

https://maxleiter.com/blog/build-a-blog-with-nextjs-13

《发布 TypeScript 5.1 Beta - TypeScript。》。TypeScript 5.1 测试版已经发布,其特点是未定义返回函数的隐式返回更容易,以及 getters 和 setters 的非相关类型。该版本还包括 JJSX 元素和 JJSX 标签类型之间的解耦类型检查、命名的 JJSX 属性以及同时自动编辑多个位置的能力。TypeScript 现在在 TypeScript 和 JavaScript 文件中键入 @param 标签时提供片段补全。

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-beta/

《GitHub - yoavbls/pretty-ts-errors:在 VSCode 中使 TypeScript 错误更漂亮和易读》。这是一个名为“Pretty TypeScript Errors”的Visual Studio Code扩展,旨在让TypeScript错误变得更加美观和易于阅读。当类型的复杂性增加时,TypeScript错误会变得越来越混乱。这个扩展能帮助您更好地理解错误信息。主要功能包括:为错误信息中的类型提供语法高亮,支持深色和浅色主题;在错误信息中的类型旁边提供一个按钮,可以跳转到相关类型声明;提供一个按钮,可以将您导航到typescript.tv,那里有详细的解释,有时还有视频;提供一个按钮,可以将您导航到ts-error-translator,那里可以用简单的英语阅读错误。

https://github.com/yoavbls/pretty-ts-errors

《ECMAScript 2023 有什么新特性 | pawelgrzybek.com》。JavaScript 的新功能列表已经确定,最终版本的 ECMAScript 规范预计将于 6 月底发布。这些新功能包括在 Array 和 TypedArray 原型上添加 findLast() 和 findLastIndex() 方法、标准化 Hashbang 语法、允许使用符号作为 WeakMap 键以及在 Array.prototype 上添加返回新副本的方法等。这些功能都已达到第 4 阶段,并预计将包含在即将发布的 ECMAScript 版本中。

https://pawelgrzybek.com/whats-new-in-ecmascript-2023/

MDH 前端周刊第 97 期:Vite 4.3、Node 20、pretty-ts-errors、React Query 5

- - + + \ No newline at end of file diff --git "a/2023/4\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/4\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 314ed075ad..6caf2fb79a 100644 --- "a/2023/4\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/4\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

4月9日内容汇总

· 9 min read
加菲猫

image

题图:Cute and adorable cartoon Korean girl, along side pet。

⭐️ Go RWMutex:高并发读多写少场景下的性能优化利器

⭐️ Go Mutex:保护并发访问共享资源的利器

⭐️ 学会 Go select 语句,轻松实现高效并发

⭐️ Go 编译器优化

⭐️ 从.go文本文件到可执行文件

📒 深入浅出 Kubernetes Pod 实现原理

⭐️ fasthttp 为什么比标准库快 10 倍

📒 为什么 Python、Go 和 Rust 都不支持三元运算符

为什么 Python、Go 和 Rust 都不支持三元运算符

https://go.dev/doc/faq#Does_Go_have_a_ternary_form

⭐️ 深入探索Go语言的unsafe包,揭秘它的黑科技和应用场景!

⭐️ 从零到一实现 Rust 的 channel 并发处理模型

⭐️ Go 性能加速器:你需要知道的 5 个诀窍和技巧

⭐️ 「刷起来」Go必看的进阶面试题详解

📒 Node 中文周刊 #83 - 新的 npm 包有一半是垃圾包吗

⭐️ 字节跳动开源 Shmipc:基于共享内存的高性能 IPC

⭐️ iptables 的五表五链

📒 前端食堂技术周刊第 77 期:三月登陆浏览器的新功能、Nuxt DevTools、pnpm v8.0.0、重新思考 React 最佳实践、CLI 脚手架工具生态

📒 有趣!深挖推特开源算法;ChatGPT封号对策汇总;ControlNet最全教程;搭建ChatGPT应用;构建开源项目阅读工作流 | ShowMeAI日报

📒 GPT 会上网了!!ChatGPT 插件的原理揭秘

⭐️ Go语言中常见100问题-#31 Ignoring how arguments are evaluated in ...

📒 「每周译Go」在 Go 里面如何使用 Flag 包

⭐️ 一文告诉你哪些map element类型支持就地更新

📒 前端同学都是如何玩转 ChatGPT 的

⭐️ Go 高性能代码的 30 个 Tips

⭐️ ChatGPT 如何辅助我的开发日常

⭐️ CPU 缓存体系对 Go 程序的影响

⭐️ Go 语言标准库 bufio 详解

📒 MDH 前端周刊第 94 期:Socket AI、CSS 遮罩、Qwik RC、Source Map、1000X 工程师

《介绍 Socket AI - ChatGPT 驱动的威胁分析 - Socket》。Socket 宣布推出基于人工智能的源代码分析解决方案,利用 ChatGPT 检查每个 npm 和 PyPI 包。当检测到包中存在潜在问题时,Socket 会将其标记并请求 ChatGPT 对其进行总结。Socket 的 AI 警告应视为建议而非绝对分析,因为 LLMs 的限制意味着跨文件分析等任务仍需持续改进。此外,Socket 还在不断增强静态分析功能,未来预计将进一步整合 LLMs,实现更复杂的 AI 引导分析。

https://socket.dev/blog/introducing-socket-ai-chatgpt-powered-threat-analysis

《使用 Zod 和 JSDoc 进行 JavaScript 类型定义》。本文介绍了如何在纯 JavaScript 文件中使用 JSDoc 注释和 Zod 类型库来推断类型。通过这种方法,可以在编写代码时获得类型提示和检查,并在运行时使用类型。这种方法不需要编译、转换或配置任何东西,因此非常适合小型项目。

https://blog.jim-nielsen.com/2023/types-in-jsdoc-with-zod/

《Twitter 的推荐算法》。Twitter 公布了其推荐算法的工作原理,该算法将每天发布的大约 5 亿条推文缩减到最终出现在用户设备上的少数优质推文。Twitter 的推荐系统由许多相互连接的服务和作业组成,包括从不同的推荐来源提取最佳推文、使用机器学习模型对每个推文进行排名、过滤掉用户已屏蔽的推文等。这篇博客将介绍算法如何为用户的时间轴选择推文。

https://blog.twitter.com/engineering/en_us/topics/open-source/2023/twitter-recommendation-algorithm

《如何拥有充裕的时间》。本文介绍了一种管理时间的技巧,即将相关任务放入一个桶中,让这个桶积累直到满,然后一次性处理。这与试图在数不清的打断管道中捕捉每个任务形成对比,如果你让它们滴答滴答地流逝,它们会将你的一天淹没。作者强调,时间并不是稀缺资源,注意力才是,找到你的桶,培养耐心让它们填满,然后逐个清空。这是 10X 生产力的窍门。

https://world.hey.com/dhh/how-to-have-buckets-of-time-38693993

《发布 react-router@6.10.0・remix-run/react-router》。React Router 6.10.0 发布,增加了一些数据路由标志,包括 future.v7_normalizeFormMethod,可以将 useNavigation() 和 useFetcher() 的 formMethod 字段规范化为大写 HTTP 方法,以与 fetch()(以及某些 Remix)行为对齐。此外,还修复了一些错误,并更新了 @remix-run/web-fetch@4.3.3

https://github.com/remix-run/react-router/releases/tag/react-router%406.10.0

《1000X 工程师》。本文介绍如何通过一系列命令行包装函数来使用 OpenAI API 提高程序员的生产力。作者首先介绍了如何获取 OpenAI API 密钥,然后演示了如何使用 API 来回答各种问题、生成数据集、创建图像等。作者认为,未来的开发者生产力将会是一个重要的竞争优势,而采用借助人工智能的工作流程可能会更加高效。虽然这并不意味着程序员将被替代,但它提供了一种解决模糊领域中更大问题的有趣新方法。

https://kadekillary.work/posts/1000x-eng/

《发布 GitHub Actions 扩展适用于 VS Code | GitHub 博客》。GitHub 发布了官方的 GitHub Actions VS Code 扩展程序的公共测试版。该扩展程序支持编写和编辑工作流程,并帮助用户管理工作流程运行,无需离开 IDE。使用该扩展程序,用户可以在不离开编辑器的情况下管理工作流程,轻松监控存储库中的工作流程运行,取消和重新运行它们,或者为手动触发的工作流程触发新的运行。此外,用户还可以列出所有受支持级别(组织、存储库和环境)的可用密钥和变量。扩展程序提供了语法高亮、集成文档、验证和代码完成等功能,以提高编辑工作流程的体验。

https://github.blog/2023-03-28-announcing-the-github-actions-extension-for-vs-code/

MDH 前端周刊第 94 期:Socket AI、CSS 遮罩、Qwik RC、Source Map、1000X 工程师

📒 Go语言爱好者周刊:第 183 期 —— Go1 正式发布 11 周年

TiDB 7.0 发布: Go 实现的分布式数据库。

https://docs.pingcap.com/tidb/v7.0/release-7.0.0

ferret 0.18发布: 一个声明式的 Web 爬虫系统,既可以单独使用,也可以嵌入其他 Go 项目使用。

https://github.com/MontFerret/ferret

hertz 0.6.1 发布: 一个 Golang 微服务 HTTP 框架。

https://github.com/cloudwego/hertz

ElasticSearch Go 8.7 发布: ElasticSearch Go 8.7 官方客户端发布。

https://github.com/elastic/go-elasticsearch

为什么 Go 不支持 []T 转换为 []interface

https://mp.weixin.qq.com/s/lG-sswO8i6w_6sMztvyOjw

如何用 Go 进行正确的性能剖析

https://blog.pickme.lk/how-to-get-profiling-right-with-go-813ff89d4757

nats.go: NATS 的 Golang 客户端,云原生消息系统。

https://github.com/nats-io/nats.go

zeropool: Go 的零分配类型安全池,sync.Pool 的替代品。

https://github.com/colega/zeropool

Go语言爱好者周刊:第 183 期 —— Go1 正式发布 11 周年

- - + + \ No newline at end of file diff --git "a/2023/5\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/5\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 93d83995bc..47141c119d 100644 --- "a/2023/5\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/5\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月14日内容汇总

· 24 min read
加菲猫

image

题图:rainy day, a water wheel in the green river, green plants and flowers in the foreground, mountains and water in the distance。

📒 一文通透讲解webpack5 module federation

⭐️ 一文搞懂Go错误链

📒 Webpack5构建性能优化:构建耗时从150s到60s再到10s | 京东云技术团队

📒 三十分钟掌握Webpack性能优化

⭐️ 不背锅运维相关文章

上篇:带你手工体验从写代码、编译、打包镜像、部署到K8S的全过程

下篇:使用jenkins发布go项目到k8s,接上篇的手工体验改造为自动化发布

值得收藏:K8S的kubectl常用命令已经按场景分好类,请您查阅

避坑:Go并发编程时,如何避免发生竞态条件和数据竞争

Go接口:运维开发场景中,go的接口到底怎么用

📒 Vue3.3 正式发布!

⭐️ 容器中如何正确配置 GOMAXPROCS

⭐️ Go项目组织:在单一repo中管理多个Go module指南

📒 React全新实验性Hooks:useOptimistic、useFormStatus

⭐️ Go 笔试 - 交叉顺序输出奇偶数

⭐️ zookeeper到nacos的迁移实践

⭐️ 「必知必会」 Nacos 的面试题和详解

⭐️ 使用增强版 singleflight 合并事件推送,效果炸裂!

singleflight 把每次请求定义为 call,每个 call 对象包含了一个 waitGroup,一个 val,即请求的返回值,一个 err,即请求返回的错误。

type call struct {
wg sync.WaitGroup
val interface{}
err error
}

再定义全局的 Group,包含一个互斥锁 Mutex,一个 key 为 string,value 为 call 的 map。

type Group struct {
mu sync.Mutex
m map[string]*call
}

Group 对象有一个 Do 方法,其第一个参数是 string 类型的 key,这个 key 也就是上面说的 map 的 key,相同的 key 标志着他们是相同的请求,只有相同的请求会被抑制;第二个参数是一个函数 fn,这个函数是真正要执行的函数,例如调用 MySQL;返回值比较好理解,即最终调用的返回值和错误信息。

func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
// 懒加载方式初始化 map
// 注意 map 不是并发安全的,这里用了 Mutex 保护 map 操作
g.mu.Lock()
if g.m == nil {
g.m = make(map[string]*call)
}

// 如果当前 key 存在,即相同请求正在调用中,就等它完成
// 完成后直接使用它的 value 和 error
if c, ok := g.m[key]; ok {
g.mu.Unlock()
c.wg.Wait()
return c.val, c.err
}

// 如果当前 key 不存在,即没有相同请求正在调用中
// 就创建一个 call 对象,并把它放进 map
c := new(call)
c.wg.Add(1)
g.m[key] = c
g.mu.Unlock()

// 接着执行 fn 函数
c.val, c.err = fn()
// 函数执行完唤醒 waitGroup
c.wg.Done()

// 删除 map 相应的 key
g.mu.Lock()
delete(g.m, key)
g.mu.Unlock()

// 返回 value 和 error
return c.val, c.err
}

使用增强版 singleflight 合并事件推送,效果炸裂!

⭐️ Go 反射应用与三大定律

📒 Go1.20.4 新版本发布,修复了一个神奇的内联 BUG!

⭐️ sync.Cond 设计与实现

📒 React 正式推出 Canary 版本!

⭐️ 解读 pkg.go.dev 的设计和实现

解读 pkg.go.dev 的设计和实现:设计篇

本地搭建一个 pkg.go.dev:遇到的问题和解决

Go 开源的 pkgsite,据说是应届生代码水平

⭐️ Go语言中常见100问题-#34 Ignoring how the break statement works

⭐️ 「Go框架」bind函数:gin框架中是如何将请求数据映射到结构体的

⭐️ 「Go框架」深入解析gin中使用validator包对请求体进行验证

📒 Go 语言内置 I/O 多路复用机制

📒 图解TCP 三次握手和四次挥手的高频面试题(2023最新版)

⭐️ pkgsite 新增本地模式下的跳转与搜索功能

⭐️ Go 高性能 - 无锁编程

📒 MDH 前端周刊第 98 期:Angular 16、Vercel Storage、类型测试、React Canaries

  • React Native macOS v0.71 发布
  • Pnpm v8.4.0 发布,支持包校验等
  • React 发布 canary 版本
  • VSCode v1.78 发布,体验改善等
  • Nextjs v13.4 发布,App Router 稳定等

《Next.js 发布 13.4》。Next.js 13.4 是一个重要的版本,标志着 App Router 的稳定性。这个版本增加了许多新特性,包括 React Server Components、嵌套路由和布局、简化数据获取、流式渲染和 Suspense、内置 SEO 支持等。其中最重要的是 App Router,它是 Next.js 的核心组件,可以让开发者更方便地定义页面布局和数据获取方式。此外,Turbopack 也是一个值得关注的新功能,它可以加速本地开发和生产构建过程。最后,Server Actions 是一个实验性的功能,可以在服务器端直接修改数据,不需要客户端 JavaScript。

https://nextjs.org/blog/next-13-4

《使用 Vercel Spaces 实现规模化的高质量软件 - Vercel》。Vercel 推出了 Vercel Spaces,它提供了强大的工具和惯例,可以与 monorepo 集成,使开发人员能够在保持质量的同时有效地扩展。Spaces 仪表板提供了对开发工作流程、代码健康状况和构建日志的洞察力,并包括通过 Conformance、Code Owners 和 Vercel Runs 提升效率和消除障碍的新功能。

https://vercel.com/blog/vercel-spaces

《Tauri 发布 1.3.0》。Tauri 团队发布了 1.3 版本,包括安全改进、新功能和重要的错误修复。该版本新增了 NSIS,可以使用 NSIS 创建 Windows 应用程序安装程序,还有其他一些改进和修复。

https://tauri.app/blog/2023/05/03/tauri-1-3/

《TailwindCSS vs. UnoCSS》。本文对比了 TailwindCSS 和 UnoCSS 两个工具,总结了它们的特点、语言、文档、自定义样式和编辑器支持等方面。TailwindCSS 拥有完整的 CSS 特性类名,可以通过任意值、变体和属性来进行全面的样式设计,而 UnoCSS 则支持所有 TailwindCSS 的功能,并提供了一些额外的功能,如变体组、CSS 网格流体列和更多动画效果。在语言方面,TailwindCSS 有一个相对规范的类名命名方式,UnoCSS 则更加灵活。在文档和自定义样式方面,两者都有不错的表现,但 UnoCSS 的交互式文档和颜色提示更加出色。在编辑器支持方面,TailwindCSS 支持较好,但存在一些缺陷,而 UnoCSS 的高亮显示和颜色提示则更为出色。作者认为,如果你看重灵活性和额外的功能,你可能会喜欢 UnoCSS,但如果你看重约束和更清晰的编写语言,则应该选择 TailwindCSS。

https://dev.to/mapleleaf/tailwindcss-vs-unocss-2a53

《10 种使用 ChatGPT 学习更好的方法 - 斯科特・H・扬》。这篇文章总结了读者们如何使用大型语言模型(LLMs)来学习和研究的建议,并探讨了使用这些工具的优缺点。作者提醒读者要注意,虽然 ChatGPT 可以进行人类般的对话,但它并不是真正的人类,有时会提供错误的答案。然而,ChatGPT 在许多任务上都很有用,例如作为个人导师、语言教练、生成摘要、与长文本对话、简化专业术语等。作者还提到了一些不应该使用 AI 工具的情况,例如期望它们正确地获取事实、引用和数学等方面。

https://www.scotthyoung.com/blog/2023/05/02/chatgpt-learning-tips/

《React Canaries:在 Meta 之外启用增量功能发布》。React 团队推出了一个新的官方支持的 Canary 版本,让开发者可以在稳定版本发布之前就采用新功能。这个 Canary 版本只包含 React 团队相信已经准备好被采用的特性,而不像实验性版本那样可能会有重大变化。React 将按照 semver 规范每个稳定版本进行更新,同时也会在博客上发布 Canary 版本中的重大变更和新特性。Canary 版本需要被固定版本号,以避免包含重大变更。除此之外,React 的稳定版本不会有任何改变。

https://react.dev/blog/2023/05/03/react-canaries

《为什么我喜欢使用 Map(和 WeakMaps)来处理 DOM 节点》。本文介绍了在处理大量 DOM 节点时,Maps(和 WeakMaps)是特别有用的工具的原因。与使用对象作为键 / 值存储相比,使用 Map 可以更简单、更强大、更高效地管理状态,并且不需要设置或读取唯一属性。此外,Map 还具有自动垃圾回收的功能,可以更有效地管理内存。总之,Map 对于处理大量 DOM 节点非常有用。

https://www.macarthur.me/posts/maps-for-dom-nodes

《React Native macOS 发布 0.71》。React Native macOS 发布了 0.71 版本,这是该平台首次与 iOS、Android 和 Windows 保持同步。为了实现这个目标,开发团队不得不跳过了一些中间版本,并开始着手 0.72 版本。此外,该版本还加入了对 Fabric 的实验性支持,但需要注意的是这只是一个概念验证,存在不稳定性。

https://devblogs.microsoft.com/react-native/2023-04-27-announcing-macos-71/

《如何在 React 中编写注释:好的、坏的和丑陋的》。这篇文章介绍了在 React 中添加注释的三种方法。第一种是使用 JSX 注释语法,但这种方式有些冗长;第二种是在 JSX 标签外使用 JavaScript 注释,可以更简洁地添加注释;第三种是在 JSX 标签内部使用 JavaScript 注释,可以针对特定元素添加注释。作者认为第三种方法最好,因为它简洁明了且针对性强。

https://dmitripavlutin.com/react-comments/

《React Router 发布 v6.11.0》。这篇文章介绍了 React Router 版本 6.11.0 的更新内容。其中,一些小的改动包括在 useFetcher 中启用 basename 支持,更新 @remix-run/router 依赖等。此外,fetchers 不再在搜索参数更改或路由到相同 URL 时重新验证,并且只会在操作提交或 router.revalidate 调用时重新验证。

https://github.com/remix-run/react-router/releases/tag/react-router%406.11.0

《Prompt 工程 vs 盲目 Prompting》。本文介绍了 Prompt Engineering,即利用提示来有效地从语言模型中提取信息的过程,通常用于实际应用。文章指出,许多人声称正在进行 Prompt Engineering,但实际上只是盲目 Prompting。因此,本文提供了一种基于实验方法的 Prompt Engineering 示例,以展示如何为应用程序构建可靠的功能。作者强调了选择问题、演示集、提示候选项和测试提示等步骤的重要性,并解释了如何选择最终的提示方案。

https://mitchellh.com/writing/prompt-engineering-vs-blind-prompting

《使用 Rust 在 10 分钟或更短的时间内构建和部署 URL 缩短器》。这篇文章讲述了一个软件开发人员在凌晨时分突然想到的一个想法:能否在不需要担心基础架构的情况下快速构建一个有用的应用程序。他使用了 Rust 编程语言,结合 serverless 平台 Shuttle 和 Postgres 数据库,最终成功地构建了一个简单的 URL 缩短服务。作者认为,虽然现实中的软件工程很复杂,涉及到不同团队和技能集的协作,但这种新型的无需关注基础架构的开发模式是可行的,并且可以带来更好的体验。

https://www.shuttle.rs/blog/2022/03/13/url-shortener

《Vercel 发布 Vercel Storage》。Vercel 宣布了一套无服务器存储解决方案,包括 Vercel KV,一个无服务器的 Redis 解决方案;Vercel Postgres,一个为前端建立的无服务器SQL数据库;以及 Vercel Blob,一个在边缘上传和服务文件的解决方案。这些解决方案旨在使数据库成为 Vercel 前端云的一流部分,并使开发人员能够管理他们的前端存储需求,而不必担心基础设施。

https://vercel.com/blog/vercel-storage

《Deno 发布 KV》。Deno KV 是一款全球复制、强一致性的键值数据库,可在 35 个地区实现低延迟读取。它可以无缝集成到开源 Deno 运行时中,无需任何配置即可在本地或作为托管服务运行。Deno KV 是一个简单但功能强大的一流原语,只暴露了少量方法来存储、检索、删除和枚举数据。

https://deno.com/blog/kv

《React 渲染的交互式指南》。本文主要介绍了 React 的渲染机制,即 React 只有在状态改变时才会重新渲染组件。当事件处理程序被调用时,如果其中包含 useState 的更新函数,并且新状态与快照中的状态不同,React 将触发重新渲染。此外,本文还介绍了 React 的批处理算法和 StrictMode 组件。

https://ui.dev/why-react-renders

《如何使用 Rust 和 Napi RS 在 NodeJs 中将 CSV 文件处理速度提高五倍》。本文介绍了如何使用 Rust 和 Napi RS 在 NodeJs 中处理 CSV 文件。作者使用了 readline 模块来处理 CSV 文件,并记录了处理时间和吞吐量。然后作者使用了 Rust 编写了相同的代码,并通过 pv 命令进行了基准测试,发现 Rust 版本比 Nodejs 版本快五倍。最后,作者介绍了如何使用 Napi rs 将 Rust 代码编译成动态库,并在 Nodejs 中调用。总之,结合 Rust 和 Nodejs 可以实现更好的性能和效率。

https://www.alxolr.com/articles/how-to-process-a-csv-file-five-times-faster-in-node-js-with-rust-and-napi-rs

《实现 experimental_useFormStatus by acdlite・Pull Request #26722・facebook/react》。这篇文章介绍了一个新的 React Hook,可以读取其祖先表单组件的状态,用于实现加载指示器等功能。目前该 Hook 只在实验版本中可用,随着其稳定性的提高,将会发布更多 API 和文档。该 Hook 内部使用 startTransition 和上下文对象实现,但实际实现细节可能会发生变化。由于表单元素不能嵌套,因此实现者不需要跟踪多个嵌套的 “转换提供者”。虽然它使用通用的 Fiber 配置方法进行实现,但它目前仍基于 React DOM 的要求进行一些假设。

https://github.com/facebook/react/pull/26722

《我作为新经理所犯的一些错误》。这篇文章讲述了作者成为管理者的经历,以及他在这个过程中犯下的错误和解决策略。作者指出,作为一名管理者,最初的困难之一是难以确定自己的工作是否有用。他提供了三种应对策略:与上级领导沟通,寻求反馈,多元化生活体验。此外,作者还分享了其他的经验教训,如管理的重要性、任务相关成熟度、拖延维护、直接询问等。最后,作者总结了成为新管理者的困难所在,并鼓励读者不要害怕犯错,因为这是成长的必经之路。

https://www.benkuhn.net/newmgr/

《TypeScript 装饰器:完整指南》。本文介绍了 TypeScript 的装饰器,装饰器本质上是函数,可以用于给类、方法、属性等应用可重用的行为。不同类型的装饰器包括类装饰器、方法装饰器、属性装饰器、访问器装饰器和参数装饰器。装饰器可以用于实现各种功能,如前 / 后钩子、监视属性更改和方法调用、转换参数、自动序列化和反序列化、依赖注入等。使用装饰器的优点包括跨越关注点、依赖注入、验证和代码组织。

https://deadsimplechat.com/blog/typescript-decorators-a-complete-guide/

《批判性思维是软件工程师最重要的技能吗?》。这篇文章谈到了两个现象:技术术语的使用和 “思想领袖” 在社交媒体上的崛起,以及这些现象对批判性思维的影响。作者认为,过度使用技术术语可能掩盖了人们对某一概念的真正理解,而 “思想领袖” 的观点也不应该被轻易地接受,需要进行深入的研究和验证。作者建议人们提高批判性思维能力,包括理解技术术语、验证信息、问 “为什么” 和 “如何”,并避免跟风。最后,作者强调批判性思维将在未来变得越来越重要,因为随着人工智能工具的普及,我们需要更多的人来质疑和思考。

https://blog.pragmaticengineer.com/critical-thinking/

《不要 "闪烁" 的 UI:使用 useLayoutEffect,绘画和浏览器故事》。本文介绍了在 React 中如何根据 DOM 测量更改元素的基础知识。文章首先通过一个响应式导航组件的例子,讲解了如何使用 useEffect 来计算容器大小和每个元素的尺寸,并且根据这些信息来调整元素的数量。然而,这种方法会导致初始渲染时出现闪烁问题。为了解决这个问题,文章介绍了 useLayoutEffect 的用法,并解释了浏览器渲染、绘制和事件循环等相关概念。最后,文章还讨论了在 Next.js 等服务器端渲染框架中使用 useLayoutEffect 的问题。

https://www.developerway.com/posts/no-more-flickering-ui

《关于 LLM 的八件事 | Swizec Teller》。这篇文章总结了最近人工智能(AI)的进展和引起人们兴奋的原因。其中提到了以下几点:1. 大型语言模型(LLMs)随着规模的增大而变得更好;2.LLMs 具有出人意料的新颖能力,包括 few-shot 和上下文学习;3.LLMs 表现出 “心理模型”;4. 无法可靠地控制 LLMs;5. 目前还没有人知道 LLMs 是如何工作的;6.LLMs 可以胜过人类;7.LLMs 存在偏见问题;8.LLMs 表现很好。作者还提供了一些资源来帮助读者更深入地了解这些问题。

https://swizec.com/blog/eight-things-to-know-about-llms/

《Mojo 可能是数十年来最大的编程语言进步。》。文章介绍了一种名为 Mojo 的新编程语言,它是 Python 的超集,并且可以通过使用 “fn” 和 “struct” 等新语法来实现高性能代码。该语言建立在强大的基础上,包括 LLVM 和 MLIR 等核心技术,使其快速发展和易于开发。作者认为 Mojo 将成为 AI 模型开发的替代 Python 的重要工具,并且预计它将比预期更快地发展和扩展。

https://www.fast.ai/posts/2023-05-03-mojo-launch.html

MDH 前端周刊第 98 期:Angular 16、Vercel Storage、类型测试、React Canaries

📒 Go语言爱好者周刊:第 185 期 —— 归来了

Grafana Pyroscope 解决 Go 内存泄露。

https://grafana.com/blog/2023/04/19/how-to-troubleshoot-memory-leaks-in-go-with-grafana-pyroscope/

go-openai 1.9.1 发布 - OpenAI 的 Golang SDK,包括 ChatGPT、GPT-3、GPT-4 等。

https://github.com/sashabaranov/go-openai

queue - 线程安全、泛型的多队列实现(堵塞队列、优先队列、环形队列)。

https://github.com/adrianbrad/queue

Go Time 第 273 期 - Go 中使用领域驱动设计。

https://changelog.com/gotime/273

强大的装饰器模式。

https://www.youtube.com/watch?v=GipAZwKFgoA

Go语言爱好者周刊:第 185 期 —— 归来了

- - + + \ No newline at end of file diff --git "a/2023/5\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/5\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 551722b10c..5f29f561d2 100644 --- "a/2023/5\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/5\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月21日内容汇总

· 8 min read
加菲猫

image

题图:王国之泪。

⭐️ Go与神经网络:张量运算

⭐️ 掌握 GoLang 中的指针:高效代码的提示和技巧

⭐️ 通过源码分析告诉你:当访问K8S API的代码运行在POD里的容器时,在集群内是如何进行身份验证的

⭐️ 「Go工具箱」redis官网推荐的go版本的分布式锁:redsync

📒 通俗直观介绍ChatGPT背后的大语言模型理论知识

⭐️ Golang网络IO模型源码分析-goroutinue+epoll

⭐️ 什么是无头浏览器?用Go模拟用户操作、实现网页浏览和截图

📒 Nuxt 3.5 正式发布,支持 Vue 3.3!

⭐️ 翻车了,被读者找出 BUG

⭐️ sync.Map Code Review

⭐️ 一文掌握 Go 并发模式 Context 上下文

⭐️ React 性能优化 | 包括原理、技巧、Demo、工具使用

📒 关于组件化链路设计的分享

📒 硬核,图解bufio包系列之读取原理

📒 6 个 TypeScript 的高级技巧,帮你写出更清晰的代码

📒 日常开发中,提升技术的13个建议

⭐️ 开发工具 All In One

⭐️ 从一次 PR 经历谈谈 Go 和 MySQL 的时区问题

⭐️ 玩转Netty,从“Hello World”开始!

📒 面试官:一千万的数据,你是怎么查询的

⭐️ context.Context Code Review

⭐️ 提升 Web 核心性能指标的 9 个建议

📒 Vue 转 React的开发者,常犯的10个错误

📒 你们喜欢用forEach吗?说说我为啥不喜欢用forEach

⭐️ Go语言中常见100问题-#35 Using defer inside a loop

⭐️ Go设计模式--解释器模式

📒 分布式唯一 ID 通用选型

📒 MDH 前端周刊第 99 期:jQuery 3.7、Vue 3.3、Deopt Explorer、粘性菜单、Remix、SSC

《使用 Deno 在 Rust 中运行 JavaScript》。本文介绍了作者创建的一个名为 “js-in-rs” 的基于 Rust 的 CLI 工具,用于使用 JavaScript 表达式过滤文件。与 grep 工具使用正则表达式不同,js-in-rs 使用 JavaScript 表达式进行过滤。文章详细介绍了 js-in-rs 的工作原理和代码实现,并探讨了在 Rust 应用程序中运行 JavaScript 代码的潜在应用,例如 Web 服务器、数据管道和数据库用户定义函数等。

https://austinpoor.com/blog/js-in-rs

《发布 Vue 3.3》。Vue 3.3 "Rurouni Kenshin" 已经发布,重点是改善开发者在使用 Vue 与 TypeScript 时的体验。该更新包括改进 SFC <script setup> 与 TypeScript 的使用,宏中的导入和复杂类型支持,通用组件,更符合人体工程学的 defineEmits ,带有 defineSlots 的类型槽,以及反应式道具 destructure 和 defineModel 等实验性功能。

https://blog.vuejs.org/posts/vue-3-3

《React 协调:它是如何工作的,为什么我们应该关心》。本文详细介绍了 React 的协调算法,以及它如何影响我们的日常代码。文章探讨了条件渲染、"key" 属性和为什么不应该在其他组件内声明组件等问题,并提供了解决方法。作者通过分析 React 的虚拟 DOM 和状态更新过程,解释了为什么在条件渲染中声明组件会重新挂载,以及为什么需要使用 "key" 属性来避免组件重复挂载或保证元素的唯一性。最后,作者提供了多个示例来说明这些概念。

https://www.developerway.com/posts/reconciliation-in-react

《介绍 Deopt Explorer - TypeScript》。本文介绍了如何使用内联缓存(inline caching)优化 JavaScript 代码的性能,并讲解了在 TypeScript 编译器中如何使用 Deopt Explorer 工具来分析性能问题和减少多态现象。文章详细介绍了内联缓存的概念、不同类型的缓存以及多态现象的产生原因。通过实例分析,作者展示了如何使用 Deopt Explorer 工具来分析 V8 引擎生成的 ICs 和对象类型,并通过优化 Symbol 类型的属性访问,将编译时间平均缩短了 8-10%。

https://devblogs.microsoft.com/typescript/introducing-deopt-explorer/

《我的 Remix 之路》。这篇文章讨论了作者使用 Remix 框架的经验和遇到的问题。作者认为 Remix 是一个很好的框架,但是也存在一些缺点。作者提出了四个主要问题:开发体验、路由过于神秘、仍然不够成熟以及控制不是默认的。作者指出,Remix 在某些方面缺乏对开发者的控制权,例如构建过程和静态资源处理。此外,Remix 的路由语法可能会使人感到困惑,并且更新时可能会出现问题。

https://redd.one/blog/my-struggle-with-remix

《不阻塞事件循环的实用指南》。本文介绍了 JavaScript 在单线程环境下的事件循环机制,以及如何避免同步任务阻塞事件循环。作者提出了三种解决方案:增加节点数量、将同步任务改为异步任务、将同步任务转移到另一个线程。其中,将同步任务转移到另一个线程需要使用 Worker,并且有数据传输限制。作者还介绍了将同步任务改为异步任务的具体实现方法,即通过将代码块分散到事件循环中来添加同步执行之间的间隙,从而让事件循环得以运行。

https://www.bbss.dev/posts/eventloop/

《React 服务器组件是什么?》。React Server Components 是在服务器上渲染的 React 组件,旨在减少网络瀑布效应。与传统的服务器端渲染 (SSR)、并行获取和架构更改相比,Server Components 具有更好的用户体验、更快的构建速度和更易于维护的特点。Server Components 可以通过在 JS 和 HTML 中填充一些初始数据来减少客户端请求次数,而且这种方式可以嵌套使用,只需要向顶层组件和其子组件发出一次请求即可。Server Components 还可以减小 JS 包的大小,只发送必要的数据给客户端,从而提高性能。

https://www.viget.com/articles/what-even-are-react-server-components/

MDH 前端周刊第 99 期:jQuery 3.7、Vue 3.3、Deopt Explorer、粘性菜单、Remix、SSC

📒 Go语言爱好者周刊:第 186 期 — 可视化 Go 程序调用

- - + + \ No newline at end of file diff --git "a/2023/5\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/5\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index dd2c26ee42..4ec52d29cd 100644 --- "a/2023/5\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/5\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月28日内容汇总

· 20 min read
加菲猫

image

题图:王国之泪。

📒 支付系统就该这么设计,稳的一批!!

⭐️ 聊聊Go语言的控制语句

⭐️ 不背锅运维:Go语言切片内存优化技巧和实战案例

⭐️ Go:4个场景就可以让你知道Goroutine和通道是怎么用的

⭐️ 「Go开源包」asynq:一个基于redis的,简单、可靠、高效的分布式任务队列包

⭐️ goroutine 泄漏与检测

📒 字节都在用的代码自动生成

📒 Hook 革命!浅谈 React 新 Hook 的未来与思想

⭐️ Go Sync 包:并发的 6 个关键概念

📒 Bun发布全新Bundler:比Webpack快220倍

Bun发布全新Bundler:比Webpack快220倍

https://bun.sh/blog/bun-bundler

⭐️ 大大大模型部署方案抛砖引玉

📒 ChatGPT和Claude 对比测试(以Review MLIR Codegen代码为例)更新官方ChatGPT的结果

⭐️ Everything App: HuggingFace Transformers Agent

📒 【第2950期】vite-plugin-vue-devtools:写一个Vue DevTools,让开发体验飞一会

⭐️ Go timer Code Review

📒 H5加载性能优化

对于大部分用户而言,我们根本不需要把代码编译到 ES5,不仅体积大,而且运行速度慢。我们需要做的,就是把代码编译到 ES2015+,然后为少数使用老旧浏览器的用户保留一个 ES5 标准的备胎即可。

具体的解决方法就是 <script type="module"> 标签。

支持 <script type="module"> 的浏览器,必然支持下面的特性:

  • async/await
  • Promise
  • Class
  • 箭头函数、Map/Set、fetch 等等...

而不支持 <script type="module"> 的老旧浏览器,会因为无法识别这个标签,而不去加载 ES2015+ 的代码。另外老旧的浏览器同样无法识别 nomodule 熟悉,会自动忽略它,从而加载 ES5 标准的代码。

image

# React 16 加载性能优化指南

# 让老板虎躯一震的前端技术,KPI杀手

📒 tcmalloc 解内存分配问题

https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/6722

# 深入Golang内存管理(一) TCMalloc篇

# Go内存管理之TCMalloc

# TCMalloc : Thread-Caching Malloc

# Go 内存管理(二): TCMalloc分配算法

⭐️ XML 处理,Go 标准库太简单了怎么办

📒 我用ChatGPT,给RabbitMQ加了个连接池

📒 React组件封装实践:如何拆解复杂的页面

📒 现代 Web 应用 Devtools 调试技巧

📒 在服务端写 React 组件是什么体验

⭐️ Go 空结构体:零内存的魔力

📒 这个线上BUG,让你彻底搞懂了MySQL的字符集,别问我咋知道的

⭐️ LLaMA 模型调研

当前 HuggingFace 已经实现了 LLaMA 模型 代码,可通过以下方式直接调用:

from transformers import LlamaForCausalLM
model = LlamaForCausalLM.from_pretrained(
base_model,
load_in_8bit=load_8bit,
torch_dtype=torch.float16,
device_map="auto",
)
if not load_8bit:
model.half() # seems to fix bugs for some users.
model.eval()

https://github.com/pengxiao-song/LaWGPT

https://github.com/pengxiao-song/LaWGPT/blob/f329433cad833a44c2cd14c5165a1655cf9d68ad/src/generate.py#L7

https://huggingface.co/docs/transformers/main/model_doc/llama

NLP(九):LLaMA, Alpaca, ColossalChat 系列模型研究

使用 Google Colab 训练 Stable Diffusion LoRA 模型教程

https://colab.research.google.com/#scrollTo=-Rh3-Vt9Nev9

⭐️ 「Go 框架」深入理解 gin 框中 Context 的 Request 和 Writer 对象

⭐️ Go1.22 可能会解决循环变量的坑,真好!!

📒 SpringBoot + 规则引擎 URule,太强了!

📒 2023 年你还在兼容旧版浏览器吗

📒 mysql的varchar字段最大长度真的是65535吗

在 mysql 建表 sql 里,我们经常会有定义字符串类型的需求。mysql 里有两个类型比较适合这个场景:charvarchar

声明它们都需要在字段边上加个数组,比如 char(100)varchar(100),这个 100 是指当前字段能放的最大字符数。

charvarchar 的区别在于,varchar 虽然声明了最大能放 100 个字符,但一开始不需要分配 100 个字符的空间,可以根据需要慢慢增加空间。而 char 一开始声明是多少,就固定预留多少空间。

所以,varchar比起char更省空间,一般没啥大事,大家都爱用varchar。

mysql的varchar字段最大长度真的是65535吗

⭐️ Go 细节篇-内存回收又踩坑了

📒 【第2948期】得物前端巡检平台的建设和应用:建设篇

⭐️ Go设计模式--中介者,最后的模式!

⭐️ channel 的 15 条规则和底层实现

操作规则

操作nil已关闭的 channel未关闭有缓冲区的 channel未关闭无缓冲区的 channel
关闭panicpanic成功关闭,然后可以读取缓冲区的值,读取完之后,继续读取到的是 channel 类型的默认值成功关闭,之后读取到的是 channel 类型的默认值
接收阻塞不阻塞,读取到的是 channel 类型的默认值不阻塞,正常读取值阻塞
发送阻塞panic不阻塞,正常写入值阻塞

编译规则

操作
接收只写 channel编译错误
发送只读 channel编译错误
关闭只读 channel编译错误

channel 的 15 条规则和底层实现

📒 三分钟,教你3种前端埋点方式!

📒 MDH 前端周刊第 100 期:React Query、演讲、Reactivity、Bun Bundler、Rome、infer

《你可能不需要 React Query》。这篇文章讨论了 React Server Components 是否会取代 React Query。作者认为,每个工具都应该帮助我们解决我们遇到的问题。传统上,React 在数据获取方面并不强调如何处理,这就是 React Query 和 swr 等库产生的原因。随着服务端渲染的出现,React Query 也扮演了重要的角色。但是,随着 React Server Components 的出现,如果您的数据获取仅发生在服务器上,那么您可能不需要 React Query。最后,作者提醒读者,不要盲目追随新技术,一切都有权衡。

https://tkdodo.eu/blog/you-might-not-need-react-query

《Nuxt 发布 3.5》。Nuxt 3.5.0 发布了,带来了许多令人兴奋的功能,特别是在类型支持方面。此外还有 Nitropack v2.4 和丰富的 JSON 负载等更新。Nuxt 3.5.0 还支持交互式服务器组件、环境配置、完全类型化页面和 “捆绑器” 模块解析等功能。

https://nuxt.com/blog/v3-5

《发布 TypeScript 5.1 RC》。TypeScript 5.1 已经作为候选版本发布,除了关键的错误修复外,预计在稳定版发布前不会有进一步的变化。新版本包括更容易的未定义返回函数的隐式返回,getters 和 setters 的不相关类型, JJSX 元素和 JJSX 标签类型之间的解耦类型检查,命名的 JJSX 属性,以及其他。TypeScript 5.1 还支持 JJSX 标签的链接光标,@param JSDoc 标签的片段补全,以及优化,如避免不必要的类型实例化和联合字面的负数检查。

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-rc/

《在科技会议上从参会者到演讲者的 9 个技巧 | GitHub博客》。GitHub Universe 是一年一度的全球开发者和客户活动,今年将于 11 月 8 日至 9 日在线上和线下举行。文章提供了一些撰写成功演讲提案的技巧,例如标题要吸引人、具体说明内容的收获、突出会议性质等。此外,还提供了演讲者个人介绍的公式和其他有用资源,如往年活动的回顾、联系前任演讲者、关注行业热点等。最后,文章呼吁有兴趣参加演讲的人提交他们的想法,并列出了被选中的好处。

https://github.blog/2023-05-18-9-tips-to-go-from-attendee-to-speaker-at-a-tech-conference/

《GitHub - DukeLuo/eslint-plugin-check-file》。本文介绍了一个名为 eslint-plugin-check-file 的 ESLint 插件,该插件可以帮助开发者强制规范化文件和文件夹的命名方式。插件支持多种规则,例如强制指定文件夹名称、文件名命名规范等。开发者只需要在 .eslintrc 配置文件中添加相应的规则即可使用。

https://github.com/DukeLuo/eslint-plugin-check-file

《揭开魔法的面纱:探索各种框架的反应性》。本文深入探讨了各种前端框架中的响应性(reactivity)机制,着重比较了粗粒度和细粒度响应性之间的差异。React 和 Angular 属于粗粒度系统,需要重新执行组件树来检测更改并更新 DOM;Svelte、Vue、Qwik 和 Solid 属于细粒度系统,可以更加高效地检测和更新 DOM。Qwik 是唯一一个不需要预热的框架,它通过 SSR/SSG 将状态与 DOM 相关联,并在客户端恢复这些信息,从而避免了下载大量应用代码的问题。作者认为,虽然粗粒度系统 “随便用” 会更方便,但是使用细粒度系统可能会更高效,因为后者已经进行了优化。

https://www.builder.io/blog/reactivity-across-frameworks

《介绍一下 Legend-State 1.0:更快地构建更快的应用程序》。文章介绍了一个名为 Legend-State 的 React 状态库,它具有极快的速度、易用性、自然的细粒度反应和内置持久性等四个主要优点。该库基于可观察对象实现,使用 Proxy 跟踪对象中的路径,从而在速度和内存使用方面超越其他 React 状态库。使用该库不需要繁琐的模板代码和上下文、动作、规约、分派器等,只需调用 get() 获取原始数据并使用 set() 更改数据即可。此外,该库还支持细粒度反应,使得组件能够在特定值更改时更新,从而减少重新渲染的次数。最后,该库还内置了持久化功能,可以保存和同步应用程序状态。未来,该库将添加更多的持久化插件和辅助可观察对象和钩子函数。

https://legendapp.com/open-source/legend-state-v1/

《管理 GitHub 通知》。这篇文章介绍了一种名为 “Notification-driven Developement” 的方法来管理 GitHub 上的项目。该作者通过使用 GitHub 的通知系统来管理他所维护的各种规模的项目,以保持项目的活跃度和稳定性。他提出了 “Inbox-Zero” 概念,即每天处理完所有收到的通知,以便快速响应社区成员并控制维护工作量。文章还分享了一些减少通知数量和组织通知的技巧,并介绍了一个用户脚本来自动化通知处理。最后,作者强调了享受工作和保持良好的工作与生活平衡的重要性。

https://antfu.me/posts/manage-github-notifcations-2023

《Bun Bundler》。Bun bundler 是一个快速的本地打包工具,现在已经进入了 beta 测试阶段。它可以通过 bun build CLI 命令或新的 Bun.build() JavaScript API 来使用。该工具可以用于构建前端应用程序,并提供了内置的 Bun.build () 函数和 bun build CLI 命令。文章指出,JavaScript 生态系统的复杂性不断增加,如何运行 TypeScript 文件、如何为生产环境构建 / 打包代码等问题使得开发变得越来越复杂。Bun bundler 的目标是将打包引入 JavaScript 运行时,从而使前端和全栈代码的发布更简单、更快速。该工具的优点包括:插件执行快速、生成预转换文件以提高运行性能、统一的插件 API、构建输出数组、支持 ESM 模块系统、支持 tree-shaking、支持源码映射、支持 JS 压缩器等。未来,Bun bundler 还将与 Bun 的 HTTP 服务器 API(Bun.serve)集成,从而实现用简单的声明式 API 代替

https://bun.sh/blog/bun-bundler

《将 Next.js App Router 用于生产的 5 条经验之谈》。Next.js 13 的新功能 App Router 引入了 Nested Layouts、Server Components 和 Streaming 等多项新特性,是第一个开源实现 React 18 原语的工具。从 Next.js 13.4 开始,App Router 已被认为是生产就绪状态。使用 App Router 可以更轻松地在路由之间共享 UI、更好地利用服务器组件、更快地展示页面部分内容以及准备未来。但是,在应用 App Router 时需要注意两个缓存、URL 搜索参数在布局服务器组件中的问题、文件结构的优点以及学习新技术和资源有限的挑战。建议先仔细阅读官方文档,如果遇到问题可以查看 GitHub 和 Twitter 上的讨论,并且分享经验和解决方案有助于建立更加实质性的知识库。总体而言,采用 App Router 可以提高用户和开发者的体验,但需要耐心和深入挖掘。

https://www.inngest.com/blog/5-lessons-learned-from-taking-next-js-app-router-to-production

《理解 useRef 和 useState 用于跟踪 React 中的组件渲染次数》。本文介绍了在 React 中使用 useRef 和 useState 来追踪组件渲染次数的实际例子。通过自定义一个名为 useComponentRenderCount 的 hook,使用 useRef 来存储渲染次数,并使用 useState 来管理组件内的不同状态值。通过将状态值分开控制,可以提高代码可读性并更轻松地管理每个值的状态更新。理解何时使用 useRef 以及如何与 useState 一起使用对于管理复杂的组件行为至关重要。在开发 React 应用程序时,需要平衡性能和功能,才能创建高质量的应用程序。

https://peterkellner.net//2023/05/05/Understanding-useRef-and-useState-for-Tracking-Component-Render-Count-in-React/

《反应全局状态为局部状态》。这篇文章介绍了一种基于 React 的全局状态管理方案,使用 useGlobalState 钩子来读取全局存储对象,并在其更新时强制所有已订阅的组件重新渲染。相比于 Redux 和 Context,这种方案更加简单且没有繁琐的代码。该方案不需要依赖库,支持测试和 TypeScript。文章详细介绍了如何实现这个钩子,包括 JavaScript 和 TypeScript 的实现以及测试用例。作者表示这种方案虽然简单,但也具有可扩展性,可以在其上构建中间件、错误处理和动作等功能。作者在几个项目中尝试了 createGlobalState,目前已成为他的默认选择。

https://webup.org/blog/react-global-state-as-local-state/

《Rome 发布 v12.1.0》。Rome v12.1.0 发布了,支持新的 Stage 3 装饰器、VCS 集成和新的 lint 规则。现在,Rome 可以解析和格式化大多数框架中的装饰器,并且支持 git VCS 集成。此外,还添加了许多新的 lint 规则,并提供了一个新的命令来更新配置文件。还有一个新的 CLI 帮助提示库,可以从源代码生成输出。

https://rome.tools/blog/2023/05/10/rome12_1/

《掌握 TypeScript 中的 infer - JavaScript in Plain English》。本文介绍了 TypeScript 中 infer 关键字的用法,它可以从现有的代码中提取和推断类型。使用 infer 关键字可以增加代码的类型安全性、效率和组织性。infer 关键字可以在泛型类型、函数参数和返回值、映射类型中使用,但只能在条件类型中使用。同时,文章还提供了一些实际的例子来展示 infer 关键字的使用方法。

https://javascript.plainenglish.io/mastering-infer-in-typescript-6cf3f93cca86

MDH 前端周刊第 100 期:React Query、演讲、Reactivity、Bun Bundler、Rome、infer

📒 Go语言爱好者周刊:第 187 期

gobot v2.0 发布 - 使用 Go 编程语言的 IOT 框架(机器人框架)。

https://github.com/hybridgroup/gobot

Mage v1.15 发布 - Mage 是使用 Go 的类似 make/rake 的构建工具。您编写普通的 go 函数,Mage 会自动将它们用作类似于 Makefile 的可运行目标。

https://github.com/magefile/mage

几种使用Go发送IP包的方法 - 本文尝试介绍几种收发IP packet的方式。

https://colobu.com/2023/05/13/send-IP-packets-in-Go/

lingoose - 一个 Go 框架,用于使用管道开发基于 LLM 的应用程序。

https://github.com/henomis/lingoose

Go语言爱好者周刊:第 187 期

- - + + \ No newline at end of file diff --git "a/2023/5\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/5\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 1f354131ef..3017c9d6cb 100644 --- "a/2023/5\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/5\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

5月7日内容汇总

· 11 min read
加菲猫

⭐️ GMP 调度器(附录)- QA

⭐️ 前端工程化相关文章

一起来看看一个体系完善的前端React组件库是如何搭建出来的!

干货 | 耗时缩短2/3,Taro编译打包优化实践

干货 | 30+条业务线,携程微信小程序如何协同开发

干货 | 秒开率70%+,携程金融SSR应用性能监测与优化

干货 | 携程微信小程序如何进行Size治理

干货 | 携程小程序生态之Taro跨端解决方案

携程跨端解决方案的新选择:Taro-CRN

⭐️ LangChain 中文入门教程

LangChain 是一个用于开发由语言模型驱动的应用程序的框架,主要拥有「将 LLM 模型与外部数据源进行连接」「允许与 LLM 模型进行交互」这2个能力,已经在GitHub获得35K Star,并且快速迭代中。例如可以实现一些功能:

  • 对超长文本进行总结
  • 构建本地知识库问答机器人
  • 使用GPT3.5模型构建油管频道问答机器人

假如我们想要用 openai api 对一个段文本进行总结,我们通常的做法就是直接发给 api 让他总结。但是如果文本超过了 api 最大的 token 限制就会报错。

这时,我们一般会进行对文章进行分段,比如通过 tiktoken 计算并分割,然后将各段发送给 api 进行总结,最后将各段的总结再进行一个全部的总结。

如果,你用是 LangChain,他很好的帮我们处理了这个过程,使得我们编写代码变的非常简单。

from langchain.document_loaders import UnstructuredFileLoader
from langchain.chains.summarize import load_summarize_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain import OpenAI

# 导入文本
loader = UnstructuredFileLoader("/content/sample_data/data/lg_test.txt")
# 将文本转成 Document 对象
document = loader.load()
print(f'documents:{len(document)}')

# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 500,
chunk_overlap = 0
)

# 切分文本
split_documents = text_splitter.split_documents(document)
print(f'documents:{len(split_documents)}')

# 加载 llm 模型
llm = OpenAI(model_name="text-davinci-003", max_tokens=1500)

# 创建总结链
chain = load_summarize_chain(llm, chain_type="refine", verbose=True)

# 执行总结链,(为了快速演示,只总结前5段)
chain.run(split_documents[:5])

参考:

https://github.com/liaokongVFX/LangChain-Chinese-Getting-Started-Guide

⭐️ 万字长文:LLM - 大语言模型发展简史

📒 Mojo 发布引出 Go 语言重大变革提案:用 .ʕ◔ϖ◔ʔ 替代 .go​

⭐️ Go:值与指针

⭐️ map 设计与实现(下篇)- 扩容和 QA

⭐️ Java与Go到底差别在哪,谁要被时代抛弃

📒 如何利用 IOC 改善工程设计:以 Eclipse Theia 为例

📒 TailwindCSS vs. UnoCSS

https://dev.to/mapleleaf/tailwindcss-vs-unocss-2a53

📒 React :新增实验性 API :useOptimisticState

https://github.com/facebook/react/pull/26740

⭐️ Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库

以下是社区提供的一个泛型快速 Demo,可以跟着思考运行一下,看看自己泛型的基本使用掌握的如何。

代码如下:

package main

import "fmt"

func MapKeys[K comparable, V any](m map[K]V) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}

type List[T any] struct {
head, tail *element[T]
}

type element[T any] struct {
next *element[T]
val T
}

func (lst *List[T]) Push(v T) {
if lst.tail == nil {
lst.head = &element[T]{val: v}
lst.tail = lst.head
} else {
lst.tail.next = &element[T]{val: v}
lst.tail = lst.tail.next
}
}

func (lst *List[T]) GetAll() []T {
var elems []T
for e := lst.head; e != nil; e = e.next {
elems = append(elems, e.val)
}
return elems
}

func main() {
var m = map[int]string{1: "2", 2: "4", 4: "8"}

fmt.Println("keys:", MapKeys(m))

_ = MapKeys[int, string](m)

lst := List[int]{}
lst.Push(10)
lst.Push(13)
lst.Push(23)
fmt.Println("list:", lst.GetAll())
}

注意 map 遍历顺序是不可预测的

Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库

⭐️ map 设计与实现(上篇)- 数据结构

📒 Next.js 项目参考

https://github.com/okisdev/ChatChat

📒 通过实现一个简易版 react-redux ,我更理解了!

⭐️ Go设计模式--命令模式

📒 TypeScript 前端工程最佳实践

📒 2023年谈谈前端代码加密与混淆

为啥最近突然需要关注这个:

  • Chrome 110 开始默认对源文件 pretty prints,降低用户调试难度(可以直接打断点);
  • 混淆压缩后的代码,即使 pretty prints 也需要对 Webpack 代码打包、Babel 转译、Terser 压缩非常熟悉,才能转换出源代码,对于普通开发者来说破解难度仍然很大。但是现在可以借助 AI 手段,AI 介入解释代码,加速代码反编译进程,源文件放入 chatgpt 进行释义,降低了破解难度。

前端代码安全与混淆

https://developer.chrome.com/blog/new-in-devtools-110/

📒 相关文章汇总

强大的基于 Web 的 3D 框架 v6.0 版本发布 — Babylon.js 仍然是世界领先的基于 WebGL 的图形引擎之一,具有可视化场景构建器和最佳的基于物理的渲染。v6.0 版本包括具有大量文档和 演示 的 新物理插件、流体渲染、对 反射 处理的重大改进、屏幕阅读器支持 等等。这是 JavaScript 生态系统中一个重大发布,我们无法详细描述,但是在 官网 上有更多内容。

https://doc.babylonjs.com/features/featuresDeepDive/physics/rigidBodies

事实证明,连任天堂也在使用 JavaScript。一位开发者发现,2015 年的 Wii U 和 3DS 上的 Mario vs. Donkey Kong: Tipping Stars 是用 HTML 和 JavaScript 作为底层编写的,他还设法构建了一个 shim,让它可以在正常的浏览器中运行。

https://twitter.com/JasperRLZ/status/1648046875675856897

Chrome 113 的 DevTools 将允许你覆盖网络响应头,包括 CORS 头。它还提供 Nuxt、Vite 和 Rollup 调试改进。

https://developer.chrome.com/blog/new-in-devtools-113/

从 webpack + babel 切换到 rspack,我们的构建时间减少了 85%。

https://twitter.com/shawnrmcknight/status/1651275500118065175

探索 Web Workers 在网页多线程中的潜力 — 这篇文章探讨了 Web Workers 在浏览器中多线程的重要性,包括使用它们的局限性和考虑因素,以及缓解与它们相关的潜在问题的策略。

https://www.smashingmagazine.com/2023/04/potential-web-workers-multithreading-web/

使用 Fuse.js 进行快速便捷的模糊搜索 — Fuse.js 是一个零依赖的模糊搜索库,您可以使用它在浏览器中提供搜索功能,而无需专门的面向搜索的后端。

https://spin.atomicobject.com/2023/04/27/fuse-js-fuzzy-search/

在 React 中如何编写注释:好的、坏的和丑陋的风格 — {/* 像这样编写注释 */} 是在 JSX 中编写注释的常见方法,但还有另外两种方法你也应该知道。

https://dmitripavlutin.com/react-comments/

React Router 6 的九小时探究 — 来自 Scrimba 的 Bob Ziroll 为我们呈现了一个基于 React Router 的应用程序的开发全过程,完整观看需要较长时间,但它是免费的。

https://www.youtube.com/watch?v=nDGA3km5He4

Create React App 的现代替代方案 — create-react-app 曾经是构建单页 React 应用程序的首选工具,但是这篇文章介绍了现在常用的各种替代方案。(我们支持 Vite!)

https://codingpastor.dev/goodbye-create-react-app-a-new-approach

使用 React Server Components 在博客上显示访问计数器 — 使用 React Server Components 在博客上显示访问计数器 — 听说过 React Server Components,但还没有机会尝试?这篇简明教程使用一个常见且易于理解的用例来试用 RSC。此外,它还让我们想起了 90 年代,这永远是一个好的氛围。

https://scastiel.dev/view-counter-react-server-components

使用 Zustand 简化 React 状态管理 — Zustand 是一个简单且不冗长的 Redux 替代品,Niklas Ziermann 在 YouTube 上进行了全面介绍(75 分钟)。

https://www.youtube.com/watch?v=fZPgBnL2x-Q

使用 Tauri 和 React 构建笔记应用程序 — Tauri 是一个基于 Rust 的框架,用于构建桌面应用程序。

https://betterprogramming.pub/building-cross-platform-desktop-applications-with-tauri-part-ii-8d6ad1927093?gi=2e3c50c25e6c

使用 Rust 和 NAPI-RS 在 Node 中快速处理 CSV 文件 — NAPI-RS 是一个用于在 Rust 中构建预编译的 Node.js 插件的框架。本文探讨了如何将其用于实际用途,即能够以高性能处理 CSV 数据。

https://www.alxolr.com/articles/how-to-process-a-csv-file-five-times-faster-in-node-js-with-rust-and-napi-rs

使用 Node 和 Connect 构建现代 gRPC 微服务 — 这篇有趣的教程深入探讨了 Dopt 工程师如何使用 Node 和 Connect 构建 gRPC 驱动的内部微服务。这是一篇基于真实的、生产级别的经验的教程。

https://blog.dopt.com/building-a-modern-grpc-powered-microservice

剖析 npm 恶意软件:五个软件包及其邪恶的安装脚本 — npm 相关的安全问题仍然是一个大话题,而一个常见的安全漏洞是在安装包时运行的安装脚本。

https://blog.sandworm.dev/dissecting-npm-malware-five-packages-and-their-evil-install-scripts

- - + + \ No newline at end of file diff --git "a/2023/6\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/6\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index cdd7d590aa..1d3545c06c 100644 --- "a/2023/6\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/6\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月11日内容汇总

· 5 min read
加菲猫

📒 13条咒语挖掘GPT-4最大潜力,Github万星AI导师火了,网友:隔行再也不隔山了

⭐️ GORM 相关文章

第二期Go开源说实录:GORM 剖析与最佳实践

golang orm 框架之 gorm

gorm常用使用

GORM 强大的代码生成工具 —— gorm/gen

📒 网易云音乐开源的云原生应用部署平台 - Horizon

⭐️ 借助ChatGPT快速上手ElasticSearch dsl

⭐️ 通过源码剖析Go的map扩容底层实现

📒 一个好的技术头狼是怎样的

📒 鹅厂程序员的9个生存法则

⭐️ Go 1.20.5 发布有关 SUID 和 cgo 的安全修复更新

📒 【第2966期】云音乐低代码 + ChatGPT 实践方案与思考

⭐️ 收藏!!!一图掌握 Go 中 IO 包的关系

📒 现有React架构无法解决的问题

📒 完美搭配,微前端与Monorepo的架构设计

📒 原来懒加载有这些玩法,你确定不看看

⭐️ Go 函数选项模式(Functional Options Pattern)

📒 手把手教你实现一个常用的 antd form 组件

⭐️ 一图胜千言,帮你搞懂Go面试中常问的channel问题!

⭐️ Go1.21 速览:新内置函数 clear、min、max 和新标准库包 cmp!

⭐️ 「Go开源包」requests:一个比net/http包更简洁、高效的开源包

⭐️ OKR之剑·实战篇05:OKR致胜法宝-氛围&业绩双轮驱动(上)

⭐️ 探究|Go JSON 三方包哪家强

⭐️ 超全避坑指南: 盘点 Go 的常见典型错误

⭐️ Go1.21.0 新特性:不需要循环 delete map 元素了

⭐️ 相关文章汇总

AI 加持的代码编写实战:快速实现 Nginx 配置格式化工具

使用 Docker 和 Alpaca LoRA 对 LLaMA 65B 大模型进行 Fine-Tune

基于 Docker 的深度学习环境:入门篇

模型杂谈:使用 IN8 量化推理运行 Meta “开源泄露”的大模型(LLaMA)

模型杂谈:快速上手元宇宙大厂 Meta “开源泄露”的大模型(LLaMA)

RSS Can:借助 V8 让 Golang 应用具备动态化能力(二)

在搭载 M1 及 M2 芯片 MacBook设备上玩 Stable Diffusion 模型

Linux 软件包下载加速工具:APT Proxy

轻量高可用的 K8s 集群搭建方案:MicroK8s

向量数据库入坑:使用 Docker 和 Milvus 快速构建本地轻量图片搜索引擎

向量数据库入坑:入门向量数据库 Milvus 的 Docker 工具镜像

向量数据库入坑:传统文本检索方式的降维打击,使用 Faiss 实现向量语义检索

⭐️ 【GoCN酷Go推荐】Html解析利器-goquery库

⭐️ 「GoCN酷Go推荐」高性能中文分词库 gojieba

📒 【第2962期】WebGL在次元秀的实践

📒 【面试高频题】难度 2.5/5,转换「最长公共子序列」问题

📒 一文搞懂业务架构、应用架构、数据架构

📒 页面一打开就有30个重复请求,我要怎么优化

📒 我放弃 antd 的理由

⭐️ Go语言中JSON处理技巧总结

⭐️ Go语言中常见100问题-#36 Not understanding the concept of a rune

⭐️ 合订本|用Go语言实现23种设计模式及学习重点

⭐️ Go语言爱好者周刊:第 189 期 —— Go 新的版本命名规则

- - + + \ No newline at end of file diff --git "a/2023/6\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/6\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 384e090eba..1f196bd043 100644 --- "a/2023/6\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/6\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月18日内容汇总

· 7 min read
加菲猫

📒 能输出网页的AI应用来了,赶紧测评下

⭐️ SIMD能力初体验

⭐️ 【第2973期】携程Web组件在跨端场景的实践

⭐️ sync.Pool 高性能设计之集大成者

⭐️ Go 1.21.0 带来了什么新特性?min 和 max 内置函数解析

⭐️ K8S资源限制实战:优化性能与资源管理

📒 如何优雅的使用 React Context

⭐️ 聊聊为什么 IDL 只能扩展字段而非修改

📒 【第2972期】Wukong 动态化组件能力实践

⭐️ Gin 框架是如何处理 panic 的

⭐️ 深入解析go channel各状态下的操作结果

📒 React Server Component 从理念到原理

⭐️ 一文实战K8S中的服务发现和负载均衡

⭐️ Go 语言 error 处理

Go error 处理最佳实践

# Go项目中,GRPC框架的error处理,我放在HTTP中1样的好用

⭐️ Go 语言 GC 相关

Go GC 使用三色标记法,在 GC 压力大时用户态 goroutine 是要 assit 协助标记对象的,每个业务goroutine都有机会参与到GC标记工作中来!并且,这种标记辅助采用的是一种补偿机制,即该业务goroutine分配的内存越多,它要辅助标记的内存就越多。

如何优化 GC 的开销:

  • 减少GC次数来间接减少STW次数,缺点是以整个程序的内存开销增大为代价的,稍有不慎可能就会触发OMM killed。
  • 减少堆内存的分配和释放。GC开销大的根源在于heap object多,Go的每轮GC都是FullGC,每轮都要将所有heap object标记(mark)一遍,即便大多数heap object都是长期alive的,因此,一个直观的降低GC开销的方法就是减少heap object的数量,即减少alloc。

Go GC:了解便利背后的开销

真实环境下大内存 Go 服务性能优化一例

⭐️ Go 内存管理概述

📒 或许,你根本不需要全局状态管理

📒 项目规范:让你的代码更上一层楼

📒 Vue和React权限控制的那些事

⭐️ Go fasthttp 相关文章

fasthttp 为什么比标准库快 10 倍

fasthttp:比net/http快十倍的Go框架(server 篇)

Go标准库http与fasthttp服务端性能比较

Golang fasthttp实践

⭐️ 「有问必答」Gopher如何优雅的对时间进行格式化

📒 揭秘 JavaScript 代码整洁技巧,让你的项目更出众

📒 技术派中ES集成的实现姿势

⭐️ Go1.21 速览:go.mod 的 Go 版本号将会约束 Go 程序构建,要特别注意了!

⭐️ 基于 Docker 的深度学习环境:入门篇

📒 网易云音乐大前端监控体系(Corona)建设实践-开篇

⭐️ Go 配置管理库 Viper 怎么读取结构体嵌套的配置信息

📒 如何基于 napi-rs 打造 Rust 前端工具链

📒 深入理解Render阶段Fiber树的初始化与更新

📒 虚拟滚动的3种实现方式~学完直接写简历亮点上!

📒 【第2969期】FormRender 2.0 开箱即用表单方案

⭐️ The State Of Go 2023

⭐️ Go协程池(1): 线程vs协程

📒 相关文章汇总

关于 Node 调试工具和方法的介绍 —— 这是一份信息丰富的初学者指南。文章从简单内容开始进行介绍,如使用 IDE 扩展程序突出潜在问题、使用控制台日志,再到使用 V8 检查器并通过 Chrome 进行调试。

https://blog.openreplay.com/an-introduction-to-debugging-in-nodejs/

Node v20.3.0(Current)发布 —— 此版本在升级 libuv(提供 Node 异步 I/O 功能的库)后带来了显著的 Linux 性能提升。此外,还引入了 AbortSignal.any(),并且开始正式认可 Ruy Adorno 在 Node.js TSC 中的地位。

https://nodejs.org/en/blog/release/v20.3.0

TypeScript v5.1 发布 — 这个版本开始支持 JSX 标记名称的链接编辑、namespace JSX 属性、具有无关类型的 getter 与 setter,以及不需显式返回 undefined 的函数。

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1/

Dan Abramov 深入讲解 React 服务器组件 — 面对关于服务器组件的一系列问题,Dan 决定写一系列文章,从零开始 重新实现 一个基本形式的 RSC。这并不针对日常的 React 开发者,而是面向那些想要理解 RSC 背后思想的人。

https://github.com/reactwg/server-components/discussions/5

2023 年的 React 生态 — 这是一个稍微有些杂乱无章的导览,介绍了当前流行的 React 生态系统工具和库的种类,混合了一些可靠的老面孔和一些新面孔。

https://www.builder.io/blog/react-js-in-2023

服务器组件是否真的将 React 变成了 PHP? — React YouTuber Jack 是那种看起来像标题党,但视频确实富有教育性和洞察力的稀有自媒体作者之一。如果你在权衡选择,这是一个很好的开发者体验的比较参考。

https://www.youtube.com/watch?v=hr_y1hIdZHs

Goxygen v0.4:快速为前端 JavaScript 项目生成 Go 语言的后端项目 — 这个工具可以创建一个前端基于 React、Angular 或 Vue,后端基于 Go(lang) 的新项目,再结合 Docker 和 Docker Compose 文件,形成一个完整可运行的项目。

https://github.com/Shpota/goxygen

⭐️ Go语言爱好者周刊:第 190 期 —— GopherChina 2023 PPT 下载

- - + + \ No newline at end of file diff --git "a/2023/6\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/6\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index b04759d641..cffa50e988 100644 --- "a/2023/6\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/6\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月25日内容汇总

· 8 min read
加菲猫

⭐️ Go 语言日志库

Go 每日一库之 logrus

Awesome Logging in Go With Logrus

Zap Logger

一文告诉你如何用好uber开源的zap日志库

⭐️ Go Concurrency Patterns

Go 语言并发模式代码模板

https://go.dev/talks/2012/concurrency.slide#1

https://go.dev/talks/2013/advconc.slide#1

Go Concurrency Patterns: Context

Go Concurrency Patterns: Pipelines and cancellation

Go Concurrency Patterns: Timing out, moving on

https://go.dev/doc/effective_go#concurrency

⭐️ 泛型版 slice、map

Go1.21 速览:新内置函数 clear、min、max 和新标准库包 cmp!

Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库

⭐️ 手写K8S的YAML很痛苦,看完这篇让你信手拈来

⭐️ Go 项目分层下的最佳 error 处理方式

⭐️ Go 将引入标准库 v2 版本,首个动手的是:math/rand/v2!

⭐️ 瞬间高并发,goroutine执行结束后的资源占用问题

⭐️ Go语言中常见100问题-#37 Inaccurate string iteration

📒 超越所有开源模型,击败 Claude、Bard,专门用于编程任务的大模型来了

⭐️ 死锁、活锁、饥饿、自旋锁

⭐️ 一个悄然崛起的AI开源项目 !!

📒 前端食堂技术周刊第 87 期:2023 Stackoverflow、Bun v0.6.9、React 是否迎来了 Angular.js 时刻、Vercel AI

⭐️ Introducing the Vercel AI SDK

Vercel 推出了全新的工具来改善 AI 体验:

  • Vercel AI SDK:轻松地从 AI 模型中获取 API 响应;
  • Chat & Prompt Playground:探索来自 OpenAI、Hugging Face 等的模型;
  • AI Chatbot:使用 Next.js 构建的开源 AI 聊天应用模板。

Vercel AI SDK 是一个开源库,旨在帮助开发者在 JavaScript 和 TypeScript 中构建 AI 流式聊天应用。该 SDK 支持 React/Next.js、Svelte/SvelteKit,即将支持 Nuxt/Vue。

可以在终端中输入以下命令来安装此 SDK:

$ npm install ai

Vercel 的 AI SDK 支持互操作性,并为 OpenAI、LangChain 和 Hugging Face Inference 提供一流的支持。这意味着无论首选的 AI 模型提供商是哪个,都可以利用 Vercel AI SDK 创建前沿的流式 UI 体验。

import { OpenAIStream, StreamingTextResponse } from 'ai'
import { Configuration, OpenAIApi } from 'openai-edge'

// 创建一个 OpenAI API 客户端
const config = new Configuration({
apiKey: process.env.OPENAI_API_KEY
})
const openai = new OpenAIApi(config)

// 将运行时设置为 edge
export const runtime = 'edge'

export async function POST(req: Request) {
// 从请求正文中提取 messages
const { messages } = await req.json()

// 根据提示要求 OpenAI 完成流式聊天
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
stream: true,
messages
})
// 将响应转换为友好的文本流
const stream = OpenAIStream(response)
// 响应流
return new StreamingTextResponse(stream)
}

Vercel AI SDK 包括用于数据获取和渲染流式文本响应的 React 和 Svelte 钩子。这些钩子使得应用能够实时、动态地渲染数据,为用户提供沉浸式和交互式的体验。

现在,借助 useChatuseCompletion,构建丰富的聊天或完成接口只需要几行代码:

'use client'

import { useChat } from 'ai/react'

export default function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat()

return (
<div>
{messages.map(m => (
<div key={m.id}>
{m.role}: {m.content}
</div>
))}

<form onSubmit={handleSubmit}>
<input
value={input}
placeholder="Say something..."
onChange={handleInputChange}
/>
</form>
</div>
)
}

参考:

https://vercel.com/blog/introducing-the-vercel-ai-sdk

📒 Vercel 推出 AI SDK、AI 应用模板,快速构建 AI 应用!

📒 芜湖,埋点还可以这么做?这也太简单了

⭐️ [代码附录] SIMD能力初体验

📒 【第2976期】前端构建工具的未来

⭐️ Go语言包设计指南

📒 相关文章汇总

Node.js 安全版本已发布 —— Node.js 16.x、18.x 和 20.x 系列都发布了新版本以修复各种中高危安全问题,也包括一些与 OpenSSL 相关的安全更新。如果你想尽快升级,请留意这篇文章。

https://nodejs.org/en/blog/vulnerability/june-2023-security-releases

2023 年可以在何处托管 Remix 应用

https://www.jacobparis.com/content/where-to-host-remix

Toad Scheduler:Node.js 内存和浏览器任务调度程序 —— 提供了比 setTimeout 或 setInterval 多一点的结构,也支持 cron 风格的调度。

https://github.com/kibertoad/toad-scheduler

openGraphScraper:Open Graph 和 Twitter Card 元数据抓取器 —— 很多网页都包含元数据,以帮助像 Facebook 和 Twitter 这样的社交网络创建更有吸引力的链接——这个库可以让你更容易挖掘这些信息。

https://github.com/jshemas/openGraphScraper

Chrome for Testing 是一个全新的官方 Chrome“版本”,专门针对 Web 测试和自动化用例。你已可以使用 Puppeteer。

https://developer.chrome.com/blog/chrome-for-testing/

在你的下一个前端 Pull Request 之前,请使用 Checklist —— 使用 Checklist 避免 Pull Request 中的常见错误,文章的内容涵盖了最小化包大小、确保可访问性、使用语义化标记,以及保持代码整洁等领域。

https://evilmartians.com/chronicles/before-your-next-frontend-pull-request-use-this-checklist

Million.js:以性能为重点的 React VDOM 替代方案 — 两年前 Million 诞生时是一个不依赖任何库的,轻量的虚拟 DOM 实现。最近,它又作为 React 性能提升的一种方式出现:「想象一下 React 组件能以原生 JavaScript 的速度运行。」不过,要想达到这个目标也需要做出一些妥协,官方的 快速入门文档 演示了 React 集成 Million 的示例。

https://million.dev/

为什么使用了 React 服务端组件,客户端组件仍然可以被 SSR 成 HTML? — 当理解服务器组件时不要恐慌,它并不会改变你原有对 React 工作原理的理解。你可以在心智模型上开辟一块新的空间来接纳这个知识点。为了避免混淆,请将概念分为 “React 服务器”和 “React 客户端”,而不是更容易混淆的“服务器”和“客户端”。这将有助于更好地理解 React 在不同环境下的工作方式。

https://github.com/reactwg/server-components/discussions/4

React Redux v8.1 已经发布,增加了针对常见错误的开发模式安全检查,以及修复了 React-Redux hook 被 React 服务器组件引用时的问题。

https://github.com/reduxjs/react-redux/releases/tag/v8.1.0

⭐️ Go语言爱好者周刊:第 191 期 —— 父亲节快乐

- - + + \ No newline at end of file diff --git "a/2023/6\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/6\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 6a33338c60..193fba90db 100644 --- "a/2023/6\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/6\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

6月4日内容汇总

· 15 min read
加菲猫

⭐️ Go语言反射编程指南

⭐️ Go 1.21 确认添加 cmp 包以及 min, max built-in 函数

📒 TypeScript 5.1 正式发布!

⭐️ 识别「ChatGPT造假」,效果超越OpenAI:北大、华为的AI生成检测器来了

⭐️ 给面试官一点小小的 gpt 震撼

⭐️ 非广告| DDD 到底是银弹还是垃圾

⭐️ 开通个人博客啦!附带全部 Hexo + Nginx + Git 教程

⭐️ Go error 处理最佳实践

⭐️ 为什么泛型使你的程序变慢

📒 使用require.context实现优雅的预加载!

⭐️ 聊聊 rust trait

⭐️ Go 编译器优化

⭐️ 从Go源码到可执行文件的编译过程详解

⭐️ 为什么取消了Go1.21,而采用了Go1.21.0的版本命名规则

⭐️ Ranking and Tuning: 解锁预训练模型库的新范式

⭐️ Golang中的25个常见错误:更好地进行go编程的综合指南

⭐️ 颠覆微服务架构?谷歌最新开源service weaver初体验

📒 连尤大都要借鉴的开源项目也会有一些迷惑行为

⭐️ Go1.21 速览:骚操作 panic(nil) 将成为历史!以后别这么干了

⭐️ Go channel FAQ

📒 form元素是React的未来

⭐️ 不要写 clean code, 要写 CRISP code

⭐️ channel 的 15 条规则和底层实现

⭐️ Go netpoll (下篇)- 数据接收发送和关闭

📒 【第2956期】如何编写一个友好支持 Tree-shaking 的库

⭐️ Go 高性能 - singleflight 防止缓存击穿

⭐️ 阅读破10万的学Go建议,不管初学还是进阶Go都值得一看!

⭐️ 深入浅出Go调度器中的GMP模型

⭐️ Go netpoll (上篇)- 数据结构和初始化

📒 ​未来全栈框架会卷的方向

⭐️ 抽丝剥茧,记一次 Go 程序性能优化之旅

📒 原生 popover 终于要来了!

📒 INP 即将代替 FID 成为新的核心 Web 指标

📒 相关文章推荐

《DeviceScript:专为微型设备设计的 TypeScript》。DeviceScript 是微软新推出的一种语言,旨在将 TypeScript 的编程体验应用到低资源的微控制器设备中。它被编译为一种自定义的虚拟机字节码,可以在这样的受限环境中运行(类似于 Go 的 TinyGo)。虽然主要面向 VS Code 用户,但也提供了 命令行选项。

《Deno v1.34:现在 deno compile 也支持 npm 包》。Deno 1.34版本主要增强了与npm和Node.js的兼容性,提高了开发者体验,并为未来的性能优化奠定了基础。此次更新最重要的功能包括:deno compile支持npm包、在deno.json和CLI标志中支持Glob以及TLS证书与IP地址。除此之外,还有许多其他改进和错误修复值得一提。其中,deno compile是本次更新中最受期待的功能之一,它使开发人员可以将项目编译成单个可执行文件,并且现在也支持使用npm包进行编译。同时,在配置文件方面也有所改进,例如新增排除所有子命令下某些文件或文件夹等功能。Deno 1.34还升级了V8至11.5版以及TypeScript至5.0.4版等内容。

《TC39 第 96 次会议的一些更新》。这篇文章介绍了2023年5月16日至18日举行的第96次TC39会议,讨论了几个JavaScript/ECMAScript的特性提案。这些包括Atomics.waitAsync、带有set符号和字符串属性的RegExp v标志、格式良好的Unicode字符串、装饰器元数据(扩展装饰器提案)、TypedArrays/DataView/Math.f16round上的Float16Array、Uint8Array:ArrayBuffer到/from Base64 的Base64编码解码,Promise.withResolvers(创建具有reject/resolve/promise函数作为方法的Promise),时区规范化(在Temporal基础上堆叠的提案)以及Intl.ZonedDateTimeFormat(用于Temporal.ZonedDateTime的Intl格式)。

《Web Components 简介》。这篇文章介绍了如何使用Web Component实现选项卡面板。首先,需要创建一个扩展HTMLElement的类,并将其注册为自定义元素。然后,在connectedCallback生命周期方法中,可以读取提供的子元素并生成UI以显示它们作为选项卡。还介绍了启用阴影DOM来提供范围化的CSS样式和激活标签状态等其他功能。最后,通过添加样式完成了选项卡组件的设计。

《比较三种非破坏性处理数组的方法》。有这篇文章介绍了三种处理数组的方法:for-of 循环、reduce() 和 flatMap()。作者通过实现一些功能来演示这三个特性,包括过滤输入数组以生成输出数组、将每个输入数组元素映射到一个输出数组元素、将每个输入数组元素扩展为零或多个输出数组元素等。对于每种方法,作者都提供了相应的代码示例,并讨论了它们的优缺点以及何时使用它们。总体而言,for-of循环是最通用的工具,而.reduce()适合计算汇总信息(例如所有元素之和),flatMap()则擅长于筛选-映射和将输入元素扩展为零或多个输出元素。

《我是如何将我的 Angular 应用转换为独立组件模式的》。这篇文章介绍了如何使用Angular的独立组件方法来避免使用ngModules。作者解释了独立组件的概念,它可以通过删除不必要的导入来大幅简化应用程序并减小包大小。在示例代码中,作者展示了如何在没有任何模块声明的情况下创建一个组件,并讨论了其优点和缺点。此外,作者还提供了一些工具和技巧,例如Bit开源工具链等,以帮助管理和共享这些独立组件。最后,作者演示了如何将现有项目从ngModule迁移到独立组件方法,并提供相应的代码示例进行说明。

《理解 React 并发》。这篇文章介绍了React v18.0中引入的一项新特性:并发模式。它的基本原则是重新设计渲染过程,使得在渲染下一个视图时,当前视图仍然保持响应性。为此,React团队提出了Concurrent Mode这个概念,并将其实现为可中断工作单元。具体来说,在组件渲染过程中使用requestIdleCallback()函数来实现并发模式。但由于向后兼容问题,Concurrent Mode计划未能实现。因此React团队转而推出了Concurrent Features这个方案,并引入了两个新钩子useTransition和useDeferredValue以支持并发渲染。其中useTransition返回一个布尔标志isPending和一个startTransition函数;而useDeferredValue则用于处理父组件传递给子组件的值更新等情况。需要注意的是,虽然这些钩子可以优化应用程序性能并提高用户体验,但它们也有自己的限制和缺点。如果想要深入理解如何使用React Concurrency,请参考官方文档及相关资源进行学习和掌握。

《你可能不需要 React Query》。这篇文章讨论了React Query在React Server Components出现后是否还有存在的必要性。作者认为,如果数据获取只发生在服务器端,那么使用React Query就没有必要了。但是,在过渡期间,可以将一些组件移动到仅在服务器上获取数据或使用Server Components预取缓存并将结果传递给客户端组件。此外,对于某些情况(例如无限滚动列表、离线应用程序等),结合React Query和Server Components可能会更好地解决问题。总之,作者认为不需要立即全部转移到Server Components,并且React Query仍然有其存在的价值和用途。

《Storybook Day 的 3D 动画是如何实现的》。这篇文章介绍了团队如何使用React Three Fiber(R3F)构建一个视觉上令人惊叹的三维动画,以Storybook的俄罗斯方块品牌为灵感创作出一个引人注目的三维插图。文章涵盖了创建场景时使用的几种技术,包括通过球体堆积避免对象重叠、使用挤压几何模型化俄罗斯方块、利用深度和阴影等效果增强视觉效果、通过减少材质数量和使用材质存储库进行性能优化等。该团队使用NextJS和@react-three/fiber构建活动网站。他们采用pack-sphere库来平均分配方块并防止任何潜在重叠问题。为解决“7.0”文本与方块之间的重叠问题,他们稍微沿z轴移动球体而不是检测球体与文本几何之间的碰撞。他们还利用Three.js中提供的ExtrudeGeometry对类似SVG路径或CSS形状这样的2D形状进行挤压,并将其沿着z轴拉伸成3D物体。为了增加一些特效,他们添加了阴影和景深效果,使其具有更多电影般感觉,并通过Material Store技术降低需要渲染材质数量从而提高性能。总之,这是一个非常好的指南,适合任何想学习如何在React Three Fiber(R3F)中构建视觉上令人惊叹的三维动画。

《如何开发一个自定义的 debounce Hook》。本文介绍了如何使用React创建自定义防抖钩子。在前端Web应用程序中,常见的功能之一是为输入添加防抖。 防抖可以让我们在输入值更改后延迟执行操作。 本文将演示如何使用React创建自定义防抖钩子。首先,我们需要了解什么是自定义Hooks以及它们的作用。 自定义Hook只是一个纯函数,它使用其他Hook来实现特定目标,并且不会产生任何副作用。接下来,文章介绍了如何通过useState和useEffect Hook创建一个名为useFetch的自定义Hook,该Hook可获取数据并返回数据和加载状态。然后文章进一步说明了如何通过useState、useEffect和useRef Hook创建名为useDebounce的自定义钩子,并演示了如何在组件中使用该钩子以实现对输入进行防抖处理。总之,本文提供了有关如何构建具有高度重复利用性能力的React Hooks(包括获取数据、防抖等)的详细指南。

《 JavaScript 安全: 最佳实践和提示》。在一个网络威胁日益复杂的时代,理解如何编写安全的 JavaScript 代码比以往任何时候都更加重要。在这篇文章中,Alex Ivanovs 解释了常见的 JavaScript 漏洞,从跨网站脚本(XSS)和跨站请求伪造(CSRF)到更复杂的问题,比如原型污染和不安全的依赖。

《Node.js 性能状况 2023》。今年是2023年,我们已经发布了 Node.js v20.0。本文对不同版本的 node.js 的性能进行了比较分析。它强调了这些改进和改进,并提供了对这些更改背后原因的深入了解,而没有与其他 JavaScript 运行时进行比较。基准测试结果包含一个可重复的示例和硬件细节。使用了 AWS 专用主机。

⭐️ Go语言爱好者周刊:第 188 期 —— Go 适合开发操作系统吗

- - + + \ No newline at end of file diff --git "a/2023/7\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/7\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 9e1729f02c..659980013f 100644 --- "a/2023/7\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/7\346\234\21016\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月16日内容汇总

· 4 min read
加菲猫

⭐️ 服务架构:大数据架构

⭐️ 使用testify包辅助Go测试指南

⭐️ 另一种视角:我为什么放弃 Go 语言

⭐️ Go进阶面试题详解 | 文末送书

⭐️ HTTP Router 算法演进

⭐️ Go语言开发者的Apache Arrow使用指南:数据操作

📒 一个新的React概念:Effect Event

📒 干货 | 携程商旅大前端 React Streaming 的探索之路

⭐️ go channel应用系列之控制协程数量

⭐️ 24 张图搞定 ICMP :最常用的网络命令 ping 和 tracert

📒 “Rust难学”只是一个谎言

⭐️ Go实战:开发一个简单的gRPC Demo

⭐️ 你用过 httpguts 包吗?通过 Go 1.20.6 和 Go 1.19.11 安全更新即可了解

⭐️ 微服务最重要的10个设计模式

⭐️ Docker 制作容器镜像的时候, 一定不能 All in One 吗

⭐️ Go defer 去掉闭包函数,靠谱吗

⭐️ 布谷鸟过滤器

⭐️ Go 语言泛型

# 跟着 Go 作者学泛型

# Go 泛型入门教程

# Go泛型系列:maps 包讲解

# Go 1.18 中的 any 是什么

# Go泛型系列:slices 包讲解

# Go泛型系列:Go1.18 类型约束那些事

⭐️ 泛型版 singleflight

singleflight.Group 是一个结构体类型,没有导出任何字段,它代表一类工作并形成一个命名空间,在该命名空间中可以抑制工作单元的重复执行。

该类型有三个方法,它们的功能见注释:

// 执行并返回给定函数的结果,确保对于给定的键,fn 函数只会执行一次。
// 如果有重复的进来,重复的调用者会等待最原始的调用完成并收到相同的结果。
// 返回值 shared 指示是否将 v 提供给多个调用者。
// 返回值 v 是 fn 的执行结果
// 返回值 err 是 fn 返回的 err
func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool)
// 和 Do 类似,但返回一个 channel(只能接收),用来接收结果。Result 是一个结构体,有三个字段,即 Do 返回的那三个。
func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result
func (g *Group) Forget(key string)

泛型版 singleflight:Go 中如何防止缓存击穿

⭐️ Gin 框架 Bind 函数如何实现参数绑定

gin 源码阅读(4) - 友好的请求参数处理

「Go 框架」bind 函数:gin 框架中是如何绑定请求数据的

📒 nginx反向代理https域名时,请求报错502问题排查

📒 【第2994期】如意设计助手:Figma Dev Mode下生成React代码

⭐️ Google SRE 创始人讲解 SRE 方法论

⭐️ Docker 多架构镜像介绍和最佳实践

⭐️ 基于Redis实现一个简单的固定窗口限流器

⭐️ Go语言爱好者周刊:第 194 期 — 开销从20%下降到不到1%

- - + + \ No newline at end of file diff --git "a/2023/7\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/7\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3c8f859388..f2a489a358 100644 --- "a/2023/7\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/7\346\234\21023\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月23日内容汇总

· 5 min read
加菲猫

🌟 AI 相关

使用 Transformers 量化 Meta AI LLaMA2 中文版大模型

刷屏的Llama 2性能究竟如何

Fine-tuning Stable Diffusion Models on Intel CPUs

Deploy LLMs with Hugging Face Inference Endpoints

使用 Docker 快速上手中文版 LLaMA2 开源大模型

使用 Docker 快速上手官方版 LLaMA2 开源大模型

Stable Diffusion 腾讯云云原生容器部署实践

一键安装!机器学习和大模型联手了!

⭐️ Golang 相关

Go语言开发者的Apache Arrow使用指南:扩展compute包

服务架构:微服务架构

OpenTelemetry:将跟踪从 Ingress-Nginx 发送到多租户 Grafana Tempo

Rust vs Go:常用语法对比(一)

抽丝剥茧,记一次 Go 程序性能优化之旅

漏桶算法和令牌桶算法

Russ Cox 的个人博客

https://research.swtch.com/coro

美团面试:为什么MySQL不建议使用NULL作为列默认值

深度好文:如何发现及处理 MySQL 主从延迟问题

Go的这个库,让你的命令行输出变得专业

「Go开源包」snappy:google开源的快速、无损压缩包

一文吃透 Go 语言解密之上下文 context

为什么 Go map 和 slice 是非线性安全的

高阶函数编程:探索Go语言中的函数一等公民

线程安全是指在多线程环境下,程序的执行能够正确地处理多个线程并发访问共享数据的情况,保证程序的正确性和可靠性。

能被称之为:线程安全,需要在多个线程同时访问共享数据时,满足如下几个条件:

  • 不会出现数据竞争(data race):多个线程同时对同一数据进行读写操作,导致数据不一致或未定义的行为。
  • 不会出现死锁(deadlock):多个线程互相等待对方释放资源而无法继续执行的情况。
  • 不会出现饥饿(starvation):某个线程因为资源分配不公而无法得到执行的情况。

Go 面试题:string 是线程安全的吗

「Go开源包」xxhash:比标准库更快,基于xxHash算法实现的64位的整型hash值

Go:使用Cobra打造强大命令行应用

开源的Datadog?可观测性平台SigNoz是否名副其实

听GPT 讲K8s源代码--pkg(四)

Traefik v3.0 Docker 全面使用指南:基础篇

答网友问:golang中的slice作为函数参数时是值传递还是引用传递

写给开发者的gRPC教程-服务发现与负载均衡

jsonparser 为什么比 encoding/json 快 10 倍

Go slice扩容N连问

听GPT 讲K8s源代码--pkg(三)

什么是布谷鸟过滤器?它与布隆过滤器有何不同

「Go开源包」env:一个将系统环境变量解析到结构体的库

配图清新的Protobuf 编码&避坑指南

Go语言爱好者周刊:第 195 期 —— Go 终极教程

📒 前端相关

【第3005期】前端简洁架构

架构师对于 Vue 响应式编程的思路梳理,从 RxJS 身上学到这么多

Chrome 115 有哪些值得关注的新特性

前端文件流、切片下载和上传:优化文件传输效率与用户体验

- - + + \ No newline at end of file diff --git "a/2023/7\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/7\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 7bcc7a9002..9a9d0cd7f1 100644 --- "a/2023/7\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/7\346\234\2102\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月2日内容汇总

· 6 min read
加菲猫

⭐️ 干货|携程Web组件在跨端场景的实践

📒 Chrome 震撼新特性:文档画中画!

📒 TypeScript 5.2 beta 发布:using 关键字、装饰器元数据、元组匿名与具名元素混用

⭐️ Go语言开发者的Apache Arrow使用指南:内存管理

⭐️ K8S面试题,有57道题,呕心沥血整理并附答案,赶紧收藏!

⭐️ 云原生监控--VictoriaMetrics 之基础篇

⭐️ Go1.21 速览:Context 可以设置取消原因和回调函数了,等的可太久了!

⭐️ Go 面试题:Go interface 的一个 “坑” 及原理分析

⭐️ Go 新关键字 any,interface{} 会成为历史吗

⭐️ 为什么 Go 里值为 nil 可以调用函数

📒 如何排查 Electron V8 引发的内存 OOM 问题

📒 ECMAScript 2023 正式发布,有哪些新特性

⭐️ 为什么 Linux “一切皆文件”

📒 32K star 的 Chakra UI,以及未来的展望

⭐️ 「Go开源包」chromedp:一个基于Chrome DevTools协议的库,支持数据采集、截取网页长图

⭐️ Go 1.21的PGO正式GA,性能提升,更快更猛!

⭐️ 我不允许你还没有这张《K8S容器云平台排错一览图》

⭐️ 精选Go高频面试题和答案汇总,阅读破万,收藏230+

📒 前端食堂技术周刊第 88 期:Svelte4、NestJS 10、State of CSS、Vitest 1.0 Roadmap

  • Svelte 4 主要是一个维护版本,为下一个版本做铺垫,包尺寸减少近 75%,依赖项从 61 个减少到 16 个,开发者体验提升。
  • State of React 2023 先行版 先不用着急回答,答了也没用。
  • Vitest 1.0 Roadmap Vitest 1.0 将和 Vite 5 同步发布,1.0 版本将放弃对 Vite 4 和 Vite 3 的支持,意味着将不再支持 Node.js 16。
  • Rspack v0.2.3 性能优化(依赖缓存、tree shaking)、内置 swc-loader 等。

TypeScript 5.2 前瞻:

前端食堂技术周刊第 88 期:Svelte4、NestJS 10、State of CSS、Vitest 1.0 Roadmap

⭐️ 「Go开源包」nunu:一个快速构建应用程序的脚手架

📒 Web Components 初探:我终于学会了如何在其他框架中使用 Vue 组件

⭐️ 敲黑板!鹅厂程序员面试也考了这些算法知识

📒 Go 语言类型转换的陷阱

⭐️ 精选8道ES高频面试题和答案,后悔没早点看

📒 ”渐进式页面渲染“:详解 React Streaming 过程

⭐️ 这些年在阿里学到的方法论

⭐️ Go 语言并发模式代码模板

⭐️ Go 并发编程 - 数据竞态

⭐️ Go 中线程安全 map 方案选型

⭐️ 保护数据隐私:深入探索Golang中的SM4加密解密算法

📒 2023 React 生态系统,以及我的一些吐槽

Redux Toolkit 还包括一个强大的数据获取和缓存功能,我们将其称为 "RTK Query"。它作为一个独立的入口点包含在软件包中。它是可选的,但可以消除手动编写数据获取逻辑的需求。

2023 React 生态系统,以及我的一些吐槽

⭐️ Go 泛型的二十一个陷阱

选自GopherChina 2023大会的分享《谈谈go泛型》。

https://github.com/smallnest/talk-about-go-generics

Go 泛型的二十一个陷阱

⭐️ Go语言中常见100问题-#38 Misusing trim functions

⭐️ Go1.21 RC2 发布了,没有 RC1

⭐️ Go语言开发者的Apache Arrow使用指南:数据类型

⭐️ 「有问必答」Gopher如何优雅的对时间进行格式化

⭐️ 相关文章汇总

AutoAnimate:通过一行代码为应用添加动画效果——可以在页面上查看一些漂亮的示例,并且这个库可以与 React、Vue、Svelte 或原生 JavaScript 一起使用。

https://auto-animate.formkit.com/

Toad Scheduler:内存中的 Node 和浏览器任务调度器——提供了比 setTimeout 或 setInterval 更多的结构,并支持类似 cron 的调度。

https://github.com/kibertoad/toad-scheduler

⭐️ Go语言爱好者周刊:第 192 期 —— 初始化大 map 的性能

初始化大 map 的性能

一个泛型的有序 Go Map 实现。Go 内建的 map类 型对于插入的元素并没有保持它们的插入顺序,遍历的时候也故意设置成随机的。因此,如果我们想让map保持元素的插入顺序,需要借助第三方的库才行,今天就给大家介绍一个这样的库 OrderedMap。

Go语言爱好者周刊:第 192 期 —— 初始化大 map 的性能

- - + + \ No newline at end of file diff --git "a/2023/7\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/7\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 5917e50859..56e96351b0 100644 --- "a/2023/7\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/7\346\234\21030\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月30日内容汇总

· 4 min read
加菲猫

🌟 AI 相关

基于 Docker 的深度学习环境:Windows 篇

使用 Docker 快速上手 Stability AI 的 SDXL 1.0 正式版

Colab 在线运行 llama-2:

https://github.com/camenduru/text-generation-webui-colab

OpenAI Code Interpreter 的开源实现:GPT Code UI

构建能够使用 CPU 运行的 MetaAI LLaMA2 中文大模型

⭐️ Golang 相关

5000字,10张图,完全掌握 MySQL 事务隔离级别

服务架构:分层架构

本地开发如何用 Dev Container,前端工程配置参考:

version: '3'
services:
node-app:
image: node:18-alpine
ports:
- "3000:3000"
environment:
- NODE_ENV=development
volumes:
# 表示将当前工作目录挂载到容器内的 `/app` 目录
- .:/app
# 当容器被重新启动时,`node_modules` 目录不会被重新构建,从而加快了容器的启动速度。
- node_modules:/app/node_modules
working_dir: /app
command: pnpm run dev
# 将 Docker 容器内的 `/node_modules` 目录挂载到卷上
# 在容器重新启动时,该目录中的依赖项不会被重新构建,从而加快容器的启动速度
volumes:
node_modules:

然后运行下面命令启动容器:

$ docker-compose up

Golang 工程配置参考:

version: '3'
services:
go-app:
image: golang:latest
ports:
- "8080:8080"
environment:
- GOPATH=/go
- PATH=$GOPATH/bin:/usr/local/go/bin:$PATH
volumes:
- .:/go/src/app
working_dir: /go/src/app
command: go run main.go

go channel应用系列二:协程间信息同步

超越 MyBatis-Plus?来领略一下 MyBatis-Flex 的优雅魅力!

WebStorm 2023.2 正式发布

Go可用性(七) 总结: 一张图串联可用性知识点

Go 工程化(十) 如何在整洁架构中使用事务

Go 工程化(十一) 如何优雅的写出 repo 层代码

一个小技巧,如何用 openssl 生成密码:

$ openssl rand -base64 [password length]

全面解读!Golang中泛型的使用

Go 1.19 中的原子指针

服务治理到底治什么,10张图告诉你答案

Go 语言的安全守护者:你用了吗

关于Dockerfile的最佳实践技巧

[Go开源工具] go-optioner:轻松生成函数选项模式代码

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

白皮书:事件 OnCall 中心建设方法

微服务中的熔断算法

Nacos 配置管理最佳实践

「必知必会」 Nacos 的面试题和详解

谈谈Kubernetes的存储设计理念

Go语言爱好者周刊:第 196 期

📒 前端相关

用Rust生成Ant-Design Table Columns | 京东云技术团队

前端简洁架构

How React 18 Improves Application Performance

- - + + \ No newline at end of file diff --git "a/2023/7\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/7\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 3dd56615b1..88691998c0 100644 --- "a/2023/7\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/7\346\234\2109\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

7月9日内容汇总

· 9 min read
加菲猫

⭐️ Google 工作 10+ 年的感悟,有看到 Go 核心团队的影子吗

⭐️ 万字长文说透分布式锁

⭐️ 服务架构简介

⭐️ 使用 Linux 网络虚拟化技术探究容器网络原理

⭐️ Go语言开发者的Apache Arrow使用指南:高级数据结构

⭐️ 字节跳动开源 Go HTTP 框架 Hertz 设计实践

字节跳动开源 Go HTTP 框架 Hertz 设计实践

「字节开源」基于Hertz和Kitex的Go微服务开源项目 | 文末福利

📒 【第2991期】从自研走向开源的 TinyVue 组件库

⭐️ 我如何用两行代码节省了30%的CPU

📒 第二次重写个人网站,分享一些感想

⭐️ fastcache 高性能设计与实现

📒 找不到好用的 gRPC 调试工具?Apifox 表示我可以!

⭐️ 一句话搞定数据分析,浙大全新大模型数据助手,连搜集都省了

📒 干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案

📒 【第2990】如意设计助手× TDesign:产品设计的绝佳搭档

📒 如何方便的检测React项目的性能

⭐️ Go 团队将修改 for 循环变量的语义,Go1.21 新版本即可体验!

⭐️ 如何基于 IDL 生成 Go 项目模板

https://dev.to/justlorain/high-performance-go-http-framework-tasting-25li

https://www.cloudwego.io/docs/hertz/tutorials/toolkit/usage/usage-thrift/

⭐️ nginx 配置 HTTP/2

# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;

ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

# Specify SSL config if using a shared one.
#include conf.d/ssl/ssl.conf;

# Allow large attachments
client_max_body_size 128M;

location / {
proxy_pass http://127.0.0.1:10020;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /notifications/hub {
proxy_pass http://127.0.0.1:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

location /notifications/hub/negotiate {
proxy_pass http://127.0.0.1:10020;
}
}

⭐️ 不藏着了,构建并减少Docker镜像容量的优化技巧都分享给你们!

📒 团队把图标方案从iconfont换成iconify了,说说我们的思考

📒 前端食堂技术周刊第 89 期:ES 2023、MDN Playground、TS 5.2 Beta、逆向分析 GitHub Copilot

逆向分析 GitHub Copilot

  • 对于编辑器输入的边界判断,包括太少、太多、取消等等很多场景齐全的考虑;
  • 缓存思想,利用多级缓存策略保护后台,模型运算本身就是一件昂贵的事情;
  • prompt 的设计,不仅仅包含了上下文代码,在文件解析、编辑器打开的相关代码上还做了很多;
  • 利用简单的 Jaccard 算法计算分词后的文本相似度,能够快速决策出当前上下文相关的 snippet;
  • 实验特性,在 Copilot 中,大量的参数、优先级、设置字段都是通过实验来控制的,有一套完整的监控上报体系,帮助 Copilot 去调整这些参数,以达到更好的效果。

字节跳动的前端工程化实践

  • 自研 Monorepo 工具,用于降低多项目的维护成本;
  • 对原有的微前端框架进行升级,进一步降低多人开发的协作成本;
  • 开发 Bundler 和 Build System,来加快巨型应用的构建速度;
  • 提供诊断工具,来有效地防止应用劣化。

前端食堂技术周刊第 89 期:ES 2023、MDN Playground、TS 5.2 Beta、逆向分析 Copilot

📒 不用 React 框架,同事就要打架!

⭐️ Go中这么多创建error的方式,你真的了解它们各自的应用场景吗

⭐️ ants Code Reading

⭐️ How to Deploy Cross-Platform Rust Binaries with GitHub Actions

⭐️ Go 语言 Context 用法

3W 解析 Golang Context:用法、源码

Go组件:context学习笔记!

Go 语言 context 都能做什么

Go Context 怎么用,原理是啥,看完这篇就清晰了

⭐️ 分享6个Linux必备的安全设置,建议收藏!

📒 企业级 React API 调用架构设计

⭐️ Go 语言使用 XORM 操作 MySQL 的陷阱

⭐️ C++/Go 调用约定的原理

⭐️ Go 语言 iota 的神奇力量

📒 相关文章汇总

聊聊 Redux 的下一个计划 — 这位 React YouTuber 之王暂时离开他通常的屏幕演示形式,与 Redux 维护者 Mark Erikson 坐下来讨论 Redux 和 Redux Toolkit 的当前状态和未来状态,两者都离重大新版本不远了。

https://www.youtube.com/watch?v=n5FK8_EXcbs

在 Next.js 13 中为服务器组件配置使用基于 cookie 的身份验证 — 这篇教程非常有意义,尤其是对 Supabase Auth 用户来说。

https://www.youtube.com/watch?v=ywvXGW6P4Gs

你知道 React 可以 在渲染过程中更新状态 吗?Markd Erikson 提供了关于此的 更多信息。

https://swizec.com/blog/react-can-update-state-during-render/

HouseForm:简单易用的基于字段的 React 表单验证 — 基于 Zod 构建,适用于任何支持 React 的环境。相比于类似的解决方案,HouseForm 验证速度更快。

https://houseform.dev/

shadcn/ui:可复制粘贴的 Tailwind CSS 组件 — 如果你经常使用 Tailwind CSS,这些组件将非常适合你。正如创建者所说:“这不是一个组件库。它是一系列可以复制粘贴到你的应用程序中的可重用组件。”

https://ui.shadcn.com/

TypeScript v5.2 现已进入 beta 阶段

https://devblogs.microsoft.com/typescript/announcing-typescript-5-2-beta/

CommonJS 正在损伤 JavaScript —— 这是关于 Node 默认模块系统的有趣观点,文章涵盖了它的历史、缺点以及同时管理 CommonJS 和 ES 模块的复杂性。毫不奇怪,Andy 希望我们尽快加入 ESM 阵营,而将 CommonJS 留在历史中。

https://deno.com/blog/commonjs-is-hurting-javascript

npm 生态系统的一个严重 Bug —— 作者曾在 npm CLI 团队工作,认为这是一个大问题。我们不在此剧透太多,但简言之,包映射表和实际的包内容可能不匹配,这可以被人利用,甚至可能会混淆审计工具。

https://blog.vlt.sh/blog/the-massive-hole-in-the-npm-ecosystem

Next.js 应用路由更新— Next.js v13+ 中的 应用路由 为组织 Next.js 应用提供了一种新的方法,并推荐在未来的项目中使用(在上个月的 Next.js v13.4 中已经稳定)。这篇文章提供了关于该功能如何发展以及团队如何继续与 React 整体进行集成。

https://nextjs.org/blog/june-2023-update

从零开始实现 React Server Components: 视频版 — 最近,Dan Abramov 发布了一个关于 从零开始重新实现 React Server Components(RSC)教程。他在 Twitter 上询问是否有人可以用视频形式记录这篇文章,Jesse 则为其增添了 “戏剧性朗读” 的效果。

https://www.youtube.com/watch?v=8aD58kGBJYc

关于 Next.js 的 Image 组件的一些你可能不知道的事情 — Next.js 的 Image 组件具有许多有用的功能,你可能不知道。

https://dev.to/alex_barashkov/things-you-might-not-know-about-next-image-5go8

⭐️ Go语言爱好者周刊:第 193 期 —— Go1.21 RC 发布

- - + + \ No newline at end of file diff --git "a/2023/8\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/8\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 4b2014ca4e..7363a6c00e 100644 --- "a/2023/8\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/8\346\234\21013\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月13日内容汇总

· 4 min read
加菲猫

🌟 AI 相关

🦙使用数据集微调Llama 2最简单方法 ,Llama 2 “烹饪”食谱,附colab完整笔记

硬件笔记:能快速更换的散热耗材,固态硅脂

⭐️ Golang 相关

Prometheus入门

Go项目初始化不再困扰你:gonew全方位解析

云原生运维相关:

基于Openresty+Lua实现微服务Api 网关

挖掘Kubernetes 弹性伸缩:扩展监控指标实现丰富弹性

挖掘Kubernetes 弹性伸缩:水平 Pod 自动扩展的全部潜力

Kubernetes运维必掌握的12个Kubectl命令

下一代云原生网关Higress:基于Wasm开发JWT认证插件

万字长文带你看全网最详细Dockerfile教程

别再用 offset 和 limit 分页了,性能太差!

Go 语言中的零拷贝

Git 速查表:中级用户必备的 12 个 Git 命令

浅谈 K8s Pod IP 分配机制

Go context.WithCancel()的使用

「Go面经」算法 并发模型 缓存落盘 etcd actor模型

Go 1.21 延迟 8 天发布,包大小直降超过 30%

Asynq: 基于Redis实现的Go生态分布式任务队列和异步处理库

多网卡管理高手:Multus-CNI的奇妙之旅

又有新功能!Go 将有生成新模板的 gonew 工具链

不想引入MQ?试试debezium

Go程序里该不该使用 runtime.KeepAlive 这类操作

服务缓存设计指南

使用 OpenTelemetry 构建可观测性 01 - 介绍

Go 1.21 新内置函数:min、max 和 clear

大型 Go 代码库的 3 种最佳设计模式

Go1.21 那些事:泛型库、for 语义变更、统一 log/slog、WASI 等新特性,你知道多少

使用go-zero快速构建微服务

听GPT 讲K8s源代码--pkg(八)

业务规则引擎演变简述

图解Redis和Zookeeper分布式锁 | 京东云技术团队

Kafka实时数据即席查询应用与实践

证书管理:从手工到平台化

听GPT 讲K8s源代码--pkg(七)

Gopher Daily改版了

Go语言爱好者周刊:第 197 期 —— Go 开发者调查

📒 前端相关

探索跨端开发的常用解决方案:条件编译的实现

干货 | 携程度假基于 RPC 和 TypeScript 的 BFF 设计与实践

代码之外的尤雨溪:在新加坡的生活,以及如何面对黑粉

- - + + \ No newline at end of file diff --git "a/2023/8\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/8\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 0c50c6e5c6..29167f95e3 100644 --- "a/2023/8\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/8\346\234\21020\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月20日内容汇总

· 4 min read
加菲猫

image

题图:博德之门3,上周末沉浸式体验了 20+ 小时。。

🌟 AI 相关

用YOLOv8一站式解决图像分类、检测、分割……

谈谈RNN生成文本的小原理,动手实现AI写藏头诗

⭐️ Golang 相关

Elasticsearch 保姆级入门篇

借助ChatGPT快速上手ElasticSearch dsl

从Kafka中学习高性能系统如何设计 | 京东云技术团队

Kubernetes 核心概念

Rust 编程第一课

https://time.geekbang.org/column/article/408409

Prometheus-Operator:自定义监控

Golang并发模式之扇入扇出

Go 常见并发模式实现(一):调度后台处理任务的作业程序

Go 并发编程实战课

https://time.geekbang.org/column/intro/100061801

https://pursuitking.com/go_2/

吵翻了!到底该选 Rust 还是 Go,成2023年最大技术分歧

干!vivo 容器集群监控系统优化之道

当 Go struct 遇上 Mutex:也许不太一样了

Go go-queue 库实现 kafka 的发布/订阅

Go Mutex 之4种易错场景盘点

异步请求-响应模式

Ingress企业实战:URL重写与高级玩法

zap (附录) - FAQ

Backward Compatibility, Go 1.21, and Go 2

使用 uber-go/zap 实现一个极简日志系统

Docker 部署 Prometheus 实现一个极简的 QPS 监控

「Go开源」vegeta: http压力测试工具库

Ingress企业实战:HTTPS证书管理与双向认证篇

zap 高性能设计与实现

Go 将增加内置的零值标识符 zero!

字节二面:10Wqps会员系统,如何设计

深入探索 Go 1.21.0 中的 maps 工具库

用了Go匿名结构体,搬砖效率更高,产量更足了

go的net/http有哪些值得关注的细节

Ingress企业实战:金丝雀与蓝绿发布篇

Go异常处理机制panic和recover

实战!使用 阿里 Arthas 工具分析 CPU 飙高

📒 前端相关

WebRTC这么火🔥,前端靓仔,请收下这篇入门教程

现代 React 开发必备的 13 个神库,路由、UI 组件库、拖拽、虚拟列表都齐了

提高 React 项目整洁度的 21 个最佳实践

React 核心技术分析—让跨端动态化成为可能

前端食堂技术周刊第 94 期:TS 5.2 RC、从零实现 RSC、Redux 迁移至 ESM 之旅、HTML 满汉全席

MDH 前端周刊第 101 期:MDH Weekly 恢复、RSC Devtool、Node 配置地狱、npm包 ESM、技术债

- - + + \ No newline at end of file diff --git "a/2023/8\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/8\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 335b518acf..9bfc4a836d 100644 --- "a/2023/8\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/8\346\234\21027\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月27日内容汇总

· 4 min read
加菲猫

🌟 AI 相关

发布一天,Code Llama代码能力突飞猛进,微调版HumanEval得分超GPT-4

⭐️ Golang 相关

使用 OpenTelemetry Collector 收集 Kubernetes 日志数据

《谷歌的软件工程》笔记(二)

《谷歌的软件工程》笔记(一)

kafka producer 在 aws 又挂了

『曹大带我学 Go 』系列文章汇总

曹大带我学 Go(11)—— 从 map 的 extra 字段谈起

曹大带我学 Go(10)—— 如何给 Go 提性能优化的 pr

曹大带我学 Go(3)—— 如何用汇编打同事的脸

曹大带我学 Go(2)—— 迷惑的 goroutine 执行顺序

曹大带我学 Go(1)——调度的本质

深度阅读之《100 Go Mistakes and How to Avoid Them》

Canal 同步数据坑太多?来试试 Logstash!

还在为MySQL数据同步Elasticsearch发愁?快来试试Canal!

Structured Logging with slog

使用 OpenTelemetry Collector 采集 Kubernetes 指标数据

面试官:什么是大事务?小林哥:就是 很大...的...事务

Go语言中常见100问题-#90 Not exploring all the Go testing features

从 0 开发工作流引擎 003|服务拆分

Prometheus-Operator:告警路由配置

【面试高频题】值得仔细推敲的贪心及其证明

听GPT 讲Prometheus源代码--promql/promdb

Traefik 企业实战:部署生产级Traefik篇

学习gorm系列二:如何指定数据表

【全套换新】还在用mvn构建SpringBoot? 新项目都在用java17+gradle+k8s(5000字附源码)

13 秒插入 30 万条数据,这才是批量插入正确的姿势!

一个 MySQL 隐式转换的坑,差点把服务器搞挂了

除了缓存,性能优化还可以这么搞

听GPT 讲Prometheus源代码--util

内存分配不再神秘:深入剖析malloc函数实现原理与机制

Ingress企业实战:部署多个Ingress控制器

Go 零值和空值的判断问题

10张图总结并发编程最佳学习路线,上车!

优化重复冗余代码的8种方式!

听GPT 讲Prometheus源代码--rules/scrape等

HTTP1 到 HTTP3 的工程优化

Sidecar模式

Prometheus-Operator:自定义告警

Go 1.21中值得关注的几个变化

关于Linux 网络抓包的一些笔记整理

net/http 库关于性能和线程安全的FAQ

学习gorm系列一:创建数据库连接

Prometheus-Operator:自动发现

📒 前端相关

不一样的"代码拆分"+"预加载"实现应用性能及体验兼得

提高 React 项目整洁度的 21 个最佳实践

[性能优化] The Cost Of JavaScript (2017 - 2023) | JavaScript 性能优化之旅

JavaScript 中文周刊 #102 - 创建 web 3D 体验的完整指南

React 服务端渲染在跨端领域中的新视界

MDH 前端周刊第 102 期:Million 自动模式、Fresh、公开写作、Suspense 节流

- - + + \ No newline at end of file diff --git "a/2023/8\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/8\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 33c25bc9ee..7587b2c90e 100644 --- "a/2023/8\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/8\346\234\2106\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

8月6日内容汇总

· 5 min read
加菲猫

🌟 AI 相关

Stable Diffusion 硬核生存指南:WebUI 中的 GFPGAN

Stable Diffusion 硬核生存指南:WebUI 中的 CodeFormer

Stable Diffusion 硬核生存指南:WebUI 中的 VAE

⭐️ Golang 相关

Golang实现单机百万长连接服务 - 美图的三年优化经验

一站式Golang内存洗髓经[Go三关典藏版]

深入理解Golang协程调度GPM[Go三关典藏版]

Golang三色标记混合写屏障GC模式全分析[Go三关典藏版]

了解go在协程调度上的改进

浅析bitset的实现原理:一个将非负整数映射到布尔值的位集合库

PromQL看这个就够了

Go Runtime功能初探

Go 性能分析工具从入门到精通

服务架构:Web-Queue-Worker架构

Golang 如何操作 Kafka

Go社区主流Kakfa客户端简要对比

一篇搞定:消息队列概念、kafka入门、Kafka Golang客户端库

Go语言如何操纵Kafka保证无消息丢失

Golang 语言中 kafka 客户端库 sarama

19.Go语言编程之Kafka基础介绍与发布订阅实践

Go 1.21 发布已延期,昨天才发布 Go 1.20.7 和 Go 1.21rc4

Opentelemetry 实践分享 - Golang篇

Go项目实现日志按时间及文件大小切割并压缩

使用 Go 语言实现二叉搜索树

拜托,别在 agent 中依赖 fastjson 了

一款 IDEA 插件帮你优雅转化 DTO、VO、BO、PO、DO

制作crate并发布到Crates.io

Go 改版本号规则,主版本号终于支持第三位数字 0 了

如何用 Docker 容器运行单节点 Kafka 环境

version: '3'
services:
zookeeper:
image: confluentinc/cp-zookeeper
hostname: zookeeper
container_name: zookeeper
ports:
- "2181:2181"
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
kafka:
image: confluentinc/cp-kafka
depends_on:
- zookeeper
hostname: kafka
container_name: kafka
ports:
- "9092:9092"
environment:
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

运行以下命令启动 Kafka:

$ docker-compose up -d

使用以下命令进入 Kafka 容器并使用 Kafka 的命令行工具进行操作:

$ docker exec -it kafka /bin/bash

然后可以使用 Kafka 的命令行工具进行操作,例如,下面的命令会创建一个名为 test 的主题,并将其配置为单个分区和单个副本因子:

$ kafka-topics --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test

使用 Kafka 命令行工具中的 kafka-console-producer.sh 脚本来启动一个生产者,可以将消息发送到 test 主题中。在命令行窗口中运行以下命令。当命令行提示符出现时,你可以开始输入消息。每输入一行,该消息就会被发布到 test 主题中。

$ kafka-console-producer --broker-list localhost:9092 --topic test

新开一个终端,使用 Kafka 命令行工具中的 kafka-console-consumer.sh 脚本来启动一个消费者,可以从 test 主题中接收消息。在命令行窗口中运行以下命令。该命令将打印 test 主题中的所有消息。

$ docker exec -it kafka /bin/bash

$ kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning

推荐 GoLand 提供的 Kafka 插件:

https://www.jetbrains.com/help/idea/2023.2/big-data-tools-kafka.html#connect_to_kafka_custom

一文总结 MetaQ/RocketMQ 原理

Go语言开发者的Apache Arrow使用指南:读写Parquet文件

使用Redis,你必须知道的21个注意要点

缓存的策略和模式

GoLand 2023.2 发布:有 AI 助手

https://www.jetbrains.com/go/whatsnew/#:~:text=GoLand%202023.2%20offers%20improved%20integration,integration%2C%20and%20the%20Kafka%20plugin.

GoLand 2023.2 发布:有 AI 助手

Go语言中常见100问题-#41 substrings and memory leaks

OpenKruise 中 OpenKruiseGame介绍

📒 前端相关

curl 上手指南,前端开发必会

JavaScript 中隐秘而强大的 compose 和 pipe

一文吃透 React DSL 应用并从零到一实现

从 antDesign 来窥探移动端“滚动穿透”行为

- - + + \ No newline at end of file diff --git "a/2023/9\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/9\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 5bee6b792a..68cc047c36 100644 --- "a/2023/9\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/9\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月10日内容汇总

· 5 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

OpenTelemetry入门看这一篇就够了|公开课

盘点 Go 语言的那些日志库:你用了哪个

Apache RocketMQ 5.0 消息进阶:如何支撑复杂的业务消息场景

你折腾一天都装不上的插件,函数计算部署 Stable Diffusion 都内置了

如何让 Llama2、通义千问开源大语言模型快速跑在函数计算上

降本增效 - 应用优化 (一)

【面试高频题】二叉树"神级遍历"入门

ELK Stack生产实践

在云原生微服务架构模式下,应用程序通常被设计成无状态(stateless)的,即应用程序不依赖于特定的运行环境状态。这种设计理念使得应用程序可以更加灵活地部署和扩展。

在 Kubernetes 中,容器的标准输出流(stdout)和标准错误流(stderr)默认被重定向到 Pod 的 stdout 和 stderr。这样,应用程序在容器中的日志输出将被重定向到 Pod 的 stdout,可以通过 Kubernetes 日志收集器(如 Fluentd、ELK Stack 等)将这些日志收集并发送到日志存储或分析系统中。

通过将日志输出到 Pod 的 stdout,可以实现以下好处:

  • 简化日志收集:无需在应用程序中实现特定的日志收集逻辑,只需将日志输出到 stdout 即可,由 Kubernetes 的日志收集器负责收集和处理。
  • 可移植性:无论应用程序在何种环境中运行(如本地开发环境、云平台等),日志输出都可以保持一致,不需要修改代码。
  • 可扩展性:由于容器是可以水平扩展的,多个容器实例共享同一个 stdout,可以方便地集中管理和处理日志。

ELK Stack生产实践——Docker部署ELK8.8与日志采集

ELK Stack生产实践——ES索引策略配置与管理

ELK Stack生产实践——数据查询与数据可视化(Kibana)

ELK Stack生产实践——数据查询与数据可视化(Grafana)

ELK Stack生产实践——ELK监控与告警(Kibana)

ELK Stack生产实践——ELK监控与告警(Prometheus)

ELK Stack生产实践——pod日志采集(Elastic Agent方案)

Linux防火墙Iptables原来这么简单(图文并茂)

Go 1.21 是不是还没用上?新版又来了

00 后架构师,那可能么

一文带你了解Docker与Containerd的区别

Ingress企业实战:实现GRPC与WebSocket服务访问

Kubernetes 应用最佳实践 - 资源请求和限制

Traefik 企业实战:TraefikService篇

探索 Go1.21 中的 slices 包:原理,特点和示例

「GoCN酷Go推荐」协程池ants介绍

「GoCN酷Go推荐」使用 cmux 实现服务端连接多路复用

MySQL连环炮,你扛得住嘛

深入剖析 Golang 程序启动原理 - 从 ELF 入口点到GMP初始化到执行 main!

Prometheus-Operator:告警排班功能实现

slog实战:文件日志、轮转与kafka集成

电脑用GoLand太卡,记录下自己把VsCode定制成Go IDE的步骤和过程

Go语言爱好者周刊:第 199 期 —— 一图掌握 Go1.21 的新特性

📒 前端相关

Chrome 117 发布:新 Web 开发调试技巧都在这了!

/[通明境 · React架构/]通俗地讲React,优雅地理解React

React-Router 6.10+KeepAlive的约定式路由最佳实践

干货!我是如何在一线大厂实践webpack优化的

构建高性能 React Native 跨端应用—图片与内存

MDH 前端周刊第 104 期:Astro 3、Npm 10、Biome、State of CSS 2023

- - + + \ No newline at end of file diff --git "a/2023/9\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/9\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 77d9733ffd..ac85f5d9c3 100644 --- "a/2023/9\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/9\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月17日内容汇总

· 3 min read
加菲猫

🌟 AI 相关

硬件笔记:组装“固态 U 盘”的八年,从 100 块到 1000 块

廉价的全闪存雷电 NAS 折腾笔记:NUC9 操作系统踩坑

⭐️ Golang 相关

Go 语言 GC 分析

动态调整 GOGC 优化 Go 的 GC 标记 CPU 占用

Kubernetes 应用最佳实践 - init 容器和钩子函数

如何使用Kaniko在 Kubernetes 集群中构建容器镜像

Golang高性能编程实践

Go1.21 中的这个新包有用过吗

Kubernetes架构原来这么简单

用 Go 编写简洁代码的最佳实践

Go 常量为什么只支持基本数据类型

【月度刷题计划同款】验证二叉树的前序序列化

ELK 处理 Spring Boot 日志,不错!

如何设计一个无状态应用

使用 Go 和 Linux Kernel 技术探究容器化原理

如何快速实现Prometheus告警聚合

Kubernetes 应用最佳实践 - 探针

万字+20张图剖析Spring启动时核心的12个步骤

【月度刷题计划同款】从区间 DP 到卡特兰数

一文带你掌握Kubernetes VPA(Pod纵向自动扩缩)

聊聊Go语言的向前兼容性和toolchain规则

Go 语言为什么适合开发网络服务

Guava中这些Map的骚操作,让我的代码量减少了50%

Go语言爱好者周刊:第 200 期

📒 前端相关

G2 项目线上和线下不一致:Tree Shaking 和 sideEffects 到底该怎么用

竟然可以在一个项目中混用 Vue 和 React

浅谈领域驱动在前端的应⽤

MDH 前端周刊第 105 期:Bun 1、RSC、Code Coverage

- - + + \ No newline at end of file diff --git "a/2023/9\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/9\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 0617375d84..2f8b72a572 100644 --- "a/2023/9\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/9\346\234\21024\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月24日内容汇总

· 4 min read
加菲猫

🌟 AI 相关

从教师到学生:神奇的“知识蒸馏”之旅——原理详解篇

⭐️ Golang 相关

使用Go和WebRTC data channel实现端到端实时通信

go vet中的那些检测项

【树形 DP】如何从"方向"角度理解树形 DP

用这4招 优雅的实现Spring Boot 异步线程间数据传递

盘点 Go 语言的那些日志库:你用了哪个

一文入门Istio架构原理及实战应用

降本增效 - 应用优化 (二)

一文讲透Redis分布式锁安全问题

程序员新人频繁使用count(*),被组长批评后怒怼:性能并不拉垮!

【树形 DP】树形 DP 的通用思路

Kubernetes 应用最佳实践 - Sidecar 模式

替代ELK:ClickHouse+Kafka+FlieBeat才是最绝的

开源框架中的责任链模式实践

硬核!美团秋招一面

Grafana 开源了一款 eBPF 采集器 Beyla

Go 语言如何获取 CPU 利用率

使用Singleflight优化Go代码

结合 pprof 分析了启用 PGO 前后性能差异。比较意思的点,启用 PGO 之后性能提升最明显的竟然是 GC(runtime.scanobject)。为啥可以提升 GC 性能,因为 PGO 可以分析 hot function 调用,让这些函数内联(正常编译器不一定会内联),原本一个函数返回结构体指针,会逃逸到堆内存,内联之后就分配到栈内存了,因此可以减少堆内存分配,进而减少 GC 压力。相比之下,业务代码的性能反而会略微下降。

Profile-guided optimization in Go 1.21

Perfectly Reproducible, Verified Go Toolchains

SpringBoot 玩一玩代码混淆,防止反编译代码泄露

Go 项目必备:深入浅出 Wire 依赖注入工具

Golang channel 三大坑,你踩过了嘛

长达 1.7 万字的 explain 关键字指南!

从内核世界透视 mmap 内存映射的本质(原理篇)

做好这四步,服务端轻松成为全栈化人才

如何在Kubernetes中使用Init Container

Go 官方新玩具:漏洞管理和扫描,看看自己项目有没有坑

📒 前端相关

基于 RPC 和 TypeScript 的 BFF 设计与实践

前端食堂技术周刊第 99 期:Remix 2.0、v0、2023 组件库盘点、TS Config 备忘录、Hello 算法

MDH 前端周刊第 106 期:v0、Remix 2、TSConfig、Bun

- - + + \ No newline at end of file diff --git "a/2023/9\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2023/9\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index e6b7051e55..25ff9157ea 100644 --- "a/2023/9\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2023/9\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
Skip to main content

9月3日内容汇总

· 3 min read
加菲猫

🌟 AI 相关

廉价的全闪存雷电 NAS 折腾笔记:组网方案的选择

廉价的家用工作站方案:ThinkPad 存储升级及数据迁移

SDXL LoRA 模型推荐

⭐️ Golang 相关

腾讯 13 年,我所总结的Code Review终极大法

【GoCN酷Go推荐】Shopify 出品的完整度最完善的 Kafka 客户端_sarama

slog正式版来了:Go日志记录新选择!

Prometheus-Operator:告警自动创建钉钉群

Kubernetes 应用最佳实践 - 开篇

后端思维专栏:通过层层代码去重,我又搞了一个通用模板

外卖骑手一面,也很不容易!

编译Go应用的黑盒挑战:无源码只有.a文件,你能搞定吗

详解 canal 同步 MySQL 增量数据到 ES

挖掘Kubernetes 弹性伸缩:利用 KEDA实现基于事件驱动的自动缩放器

SpringBoot+Redis BitMap 实现签到与统计功能

解锁Golang模板的力量:动态文本生成的初学者指南

Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理

Go 负责人说以后不会有 Go2 了

异或运算的妙用

Traefik 企业实战:路由规则篇

一文告诉你怎么打造对本地友好的 Kubernetes 工作环境

一文告诉你怎么将应用搭上云原生这趟便车(上)

Go Gin 框架系列 - 入门篇

Redis 热 key 是什么问题,如何导致的?有什么解决方案

RocketMQ 事务消息初体验

Sonic: Go语言的超级JSON库,解析与编码速度狂飙

Prometheus-Operator:告警认领功能实现

go-zero 的自适应熔断器

万字长文,教你用go开发区块链应用

Go语言爱好者周刊:第 198 期 —— 回来了

📒 前端相关

译:React 并发模式的基本原理

精读《算法题 - 地下城游戏》

前端首屏优化 | 借助客户端能力提升 H5 首屏的 8 个手段

构建高性能 React Native 跨端应用—引擎与渲染

前端食堂技术周刊第 96 期:2023 CSS 状态、Nuxt 3.7、TypeScript 5.2、eBay 性能优化

MDH 前端周刊第 103 期:TypeScript 5.3、贝塞尔曲线、Suspense、React 并发模式

- - + + \ No newline at end of file diff --git a/2023/archive/index.html b/2023/archive/index.html index 55b2a0e45e..7324dcfdb3 100644 --- a/2023/archive/index.html +++ b/2023/archive/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

Archive

Archive

2023

- - + + \ No newline at end of file diff --git a/2023/index.html b/2023/index.html index 49b3770a5f..bad275e087 100644 --- a/2023/index.html +++ b/2023/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 6 min read
加菲猫

🌟 AI 相关

秒速出图!体验 TensorRT 加速 Stable Diffusion 图像创作

⭐️ Go & 云原生 & Rust 相关

2023年Go语言盘点:稳中求新,稳中求变

Rust开发⼲货集(1)--迭代器与消费器

轻松实现Go应用的优雅关闭:提升服务质量与稳定性

今天把 Rust 更新到最新的 1.75 版本,跑一下 rustup update 这个命令就行:

$ rustup update
info: syncing channel updates for 'stable-aarch64-apple-darwin'
info: latest update on 2023-12-28, rust version 1.75.0 (82e1608df 2023-12-21)
info: downloading component 'rust-src'
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: removing previous version of component 'rust-src'
info: removing previous version of component 'cargo'
info: removing previous version of component 'clippy'
info: removing previous version of component 'rust-docs'
info: removing previous version of component 'rust-std'
info: removing previous version of component 'rustc'
info: removing previous version of component 'rustfmt'
info: installing component 'rust-src'
info: installing component 'cargo'
info: installing component 'clippy'
info: installing component 'rust-docs'
info: installing component 'rust-std'
info: installing component 'rustc'
info: installing component 'rustfmt'
info: checking for self-update

stable-aarch64-apple-darwin updated - rustc 1.75.0 (82e1608df 2023-12-21) (from rustc 1.69.0 (84c898d65 2023-04-16))

info: cleaning up downloads & tmp directories

$ cargo --version
cargo 1.75.0 (1d8b05cdd 2023-11-20)

2023 文章集锦

《深入理解Rust并发编程》可以下载了

你可能不知道的Go语言小细节【文末赠书】

C++中的同步原语

Kubernetes Daemonset 设计与实现

Go 1.22 http.ServeMux中的模式匹配

熔断、隔离、重试、降级、超时、限流,高可用架构流量治理核心策略全掌握

新提案:Go panic 能不能加个 PanicError

Go语言“正统”在中国?这6点教你写好Go代码!

Go 1.22新特性前瞻

Kubernetes ReplicaSet 设计与实现

新包降临 math/rand/v2, 在Go 1.22中

北海 - Rust与面向对象(四)

北海 - Rust与面向对象(三)

【投稿】北海 - Rust与面向对象(二)

微服务配置中心, 这个方案 Go 里用起来不输 SpringCloud

从Go channel中批量读取数据

Go语言的自给自足:编译自身的神奇之旅

圣诞福利|吃透Go并发编程,看这本书就够啦

📒 后端相关

Spring Boot 单体应用升级 Spring Cloud 微服务

账号多租户架构升级与落地实践

每天100w次登陆请求, 8G 内存该如何设置JVM参数

从混乱到优雅:基于DDD的六边形架构的代码翻新指南 | 京东物流技术团队

从工程师到技术leader的思维升级

设计一个海量的任务调度系统

公司用了6年的 SpringBoot 项目部署方案,稳得一批!

慢聊Golang协程池Ants实现原理

Redis主从复制原理和复制方式那点事!

Redis为什么使用哈希槽而不用一致性哈希

不愧是字节,面个实习也满头大汗!

可观测实践丨如何利用 AI 算法解决告警配置三大难题

管理的焦虑:技术丢了怎么办

监控告警系列-使用Promethues监控系统指标并进行告警通知

📒 前端相关

如何写好一份晋升PPT(附PPT模板)

前端DevOps平台的探索及设计理念

​云音乐D2C设计稿转代码建设实践

Esbuild深度调研:吹了三年,能上生产了吗

【第3156期】突破 ToB 前端开发场景中的 antd Table 性能瓶颈

⚡️卡顿减少 95% — 记一次React性能优化实践(性能篇)

从 0 到 1 构建基于 Node.js 的 RPC 服务

字节三年,谈谈一线团队如何搞工程化一(全景篇)

2023 年前端大事记

前端基建处理之组件库优化方案

网易云音乐 RN 低代码体系建设思考与实践

可视化全链路日志追踪

NodeJs进阶开发、性能优化指南

· 14 min read
加菲猫

🌟 AI 相关

多模态融合:基于机器学习的文本图像关联分析

⭐️ Go & 云原生 & Rust 相关

用Rust刷LeetCode之58 最后一个单词的长度

Golang优雅实现按比例切分流量

AIOps在美团的探索与实践——事件管理篇

通过实例理解OpenID身份认证

Rust中peekable的使用

Nacos 在云原生架构下的演进

智能化运维:KoPylot为k8S带来AI监控诊断

Kubernetes EndPoint 设计与实现

Kubefirst:新手也能轻松快速打造生产就绪K8S平台

轻松提升Golang日志性能:无需修改代码的异步写入解决方案

10个令人惊叹的Go语言技巧,让你的代码更加优雅

Go 1.22 RC1 发布新特性:for range, math/rand/v2

Kubernetes Informer 设计与实现 (下篇)

鲜有人了解的同步原语Phaser,和Barrier有啥区别

当 OpenTelemetry 遇上阿里云 Prometheus

Go Context 到底放第一个参数传,还是放结构体里

Kubernetes Informer 设计与实现 (上篇)

为大模型工程提效,基于阿里云 ACK 的云原生 AI 工程化实践

Go 语言为什么很少使用数组

每个Go程序员必犯之错

Go语言爱好者周刊:第 205 期

📒 后端相关

腾讯工作13年之所思所想,那些优秀程序员的共性特征

半年下云省千万:DHH下云FAQ答疑

用ElasticSearch时,必须先搞明白这几个基础

一文详解 Java 限流接口实现

什么时候都用微服务,只会害了你

对抗复杂度的圣杯战争:软件架构究竟该如何设计

如何应对 RocketMQ 消息堆积

年底了,应该如何做汇报

从腾讯视频架构重构,看DDD的概念与方法

DDD架构下的防御式编程:5大关卡共同保障业务数据的有效性

银行软开,不难!

每天精心Coding 8小时,3个月后你将得到一座……“屎山”

欺上瞒下:什么是信息差创造价值

TLA+ 入门教程(4):两阶段提交

TLA+ 入门教程(5):Paxos

TLA+ 入门教程(6):Raft

Paxos vs. Raft:共识算法的相同点和不同点

ZooKeeper 设计原理

主从复制(Primary/Backup Replication)

分布式数据库是怎么实现的

分布式存储系统在大数据处理中扮演着怎样的角色

30张图,搞懂分布式追踪系统

理解本质:从经济学角度看管理

8000字+22张图探秘SpringCloud配置中心的核心原理

MySQL高级进阶:索引优化

技术人必修课:利用金字塔原理高效思考与表达

MySQL 单表可以放多少数据,最多 2000 万

Redis数据已经删除了,为什么内存占用还是很高

4 个维度搞懂 Nacos 注册中心

Redis 性能优化 13 条军规

📒 前端相关

网易云音乐大前端监控体系(Corona)建设实践-开篇

字节前端监控实践

如何写好一篇技术分享文章

技术人如何做好业务

依枫在蚂蚁的四周年

How React 18 Improves Application Performance

重新思考 React 最佳实践

React Libraries for 2023

v0:AI 驱动的组件创造器正式开放

7个Js async/await高级用法

前端性能优化就是这么简单,你会了吗

《A 1-hour introduction to Next.js and React》。 本教程是一份关于如何使用 Next.js 14、React、Prisma、Tailwind 以及 MySQL 搭建 Twitch 克隆应用的全套课程,是 2023 年最新版本的第一部分。在课程中,学员将了解到如何使用 JavaScript 和 SQL 语言以及其他现代编程技术和工具,步步为营地创建出一个功能完整,外观现代的线上视频游戏直播平台。该实战课程为初级到中级开发者设计,旨在提升学员记录写代码、解决问题和探索新技术的能力,最后成功搭建出 Twitch 样式的应用。

《React Suspense 和 use Hook 使用指南》。 React 的 Suspense 在 React 18 的版本中得到了重要的升级,包括对服务端渲染流和局部 hydration 的支持,并且最近在新版的 React 文档中记录了一个名为 use 的新钩子,这能大大简化 Suspense 在数据获取环节的使用。然而,Suspense 在数据获取环节上的功能并未被 React 团队认为是足够成熟且适合在生产中使用的,因此并未推荐在生产环境中使用。此外,尽管进行了新增并进行了升级,但是 use 钩子并没有被作为 React 稳定版本的一部分对外发布,要想尝试使用它,您需要使用 canary 或 experimental 的 React 渠道。Suspense 目前的使用场景包括错误隔离与数据获取等。而有趣的是,use 钩子可以在条件和循环等特殊场景下使用,扩大了 Suspense 的实际使用场景。

《开始使用 Axum - Rust 最受欢迎的 Web 框架》。 本文详细介绍了 Rust 后端框架 Axum 的使用方法,包括路由设置、连接数据库、实现 App 状态、使用 Extractors 等。Axum 对 REST 风格的 API 和 Express 风格的 API 都有很好的支持,可以通过 handler 函数轻松设置路由。在数据库设置中,可以通过 Shuttle 来进行简化操作。对于 App 状态的设置,通常是使用 struct,并需要实现 Clone。对于 HTML 识别,我们可以使用 axum::Json 来将 HTTP 请求转为 json 格式。并且,axum 与 tower 有很好的兼容性,可以直接使用 tower 中的 middleware。还介绍了如何通过 Axum 来服务静态文件,如何部署 Axum 等问题。总的来说,Axum 是一个有强大团队支持且与 Rust Web 生态系统高度兼容的框架,现在是开始编写 Rust Rest API 的好时机。

《常见的 Rust 生命周期误解》。 在 Rust 中,泛型 T 包括所有可能的类型,包括 &T 和 &mut T,且不能直接指定某种数据类型。另外,生命周期'static 指的不是变量数据所存在的全部时间,它包括所有 &'static T 以及所有拥有类型,比如 String,Vec 等。同时要清楚,几乎所有的 Rust 代码都是泛型代码。此外,生命周期不能在运行时变化,生命周期都是在编译时静态验证的,生命周期不能在运行时增长或缩小或以任何方式改变。Rust 的生命周期推断规则并不总是正确的,Rust 并不比你更了解你程序的语义。由于 Rust 可以隐式地重新借用 mut ref,所以你可能在意识到这个问题之前很容易碰到这个问题。这些都是对于 Rust 中的生命周期的误解。

《用 Rust 编写操作系统》。 这份博客系列从零开始用 Rust 编程语言写一个操作系统,由浅入深地演示和讲解了用 Rust 编写操作系统的全部过程。包括最基础的内核构建、异常处理、硬件中断、内存管理以及异步等关键部分,以及操作系统设计的各种常见问题和解决办法,不仅提供了完整的教程,同时也在 Github 上公开了所有相关的源代码。

《从零开始用 Rust 编写文件系统》。 本文详细阐述了文件系统 (File System) 的工作原理和各部分组成,包括数据在硬盘或 SSD 上的结构、超级块和位图、i 节点、索引节点、数据块及其用途,以及多层次索引等概念。文章也解释了如何通过文件系统构建和管理磁盘的不同部分,以及文件和目录在文件系统中是如何表示的。最后,作者通过一个名为 GotenksFS 的项目,展示了如何用 Rust 语言编写自己的文件系统,并在其中实现了一些 ext4 的技术。

《Non-lexical lifetimes: introduction》。 这篇文章探讨的是 Rust 的借用检查器和对生命周期的理论,在 Rust 中,借用检查器确保在值被借用期间,不能对其进行移动或修改。这是通过为每次创建的借用分配生命周期去实现的。文章分别详述了生命周期和范围的概念,并通过实例阐释了它们之间的关系。接着给出了几个在实际编程中遇到的问题案例,再就这几个案例,作者展示了如何通过调整代码结构的方式绕过 Rust 现有的编译检查。作者表示这样的做法并不理想,并提出了通过改进编译器来解决这个问题的计划。

《2024 年的 React 状态管理》。 本文作者从三个角度对 React 状态管理库进行了分类:基于 reducer 的,如 Redux 和 Zustand;基于 atom 的,如 Recoil 和 Jotai;基于 mutable 的,如 MobX 和 Valtio。每种方法都有其优势和劣势。Reducer 的优势在于其强大的状态机和时间机制,对于开发者工具的支持最好,但是需要编写大量的模板代码,学习曲线陡峭。Atom 的优势在于对 React 特性的充分利用,具有简单和可扩展性,但对开发者工具的支持较弱,不能在组件外使用状态。Mutable 往往提供最简单的 API,并具有高度的灵活性和反应性,但 “自动反应” 也可能带来问题,可能导致数据竞争和异步更新问题。作者个人更偏向于使用 Jotai,因为它没有键的要求,更加高效。

《介绍 Waku》。 Waku 是一款 React 的微型框架,它支持探究 React 服务器组件(RSC)的核心功能,并独立于传统的静态站点生成(SSG)和服务器端渲染(SSR)策略来发现 RSC 最佳实践。Waku 基于 Vite,并尽可能依赖其 API 和生态系统。其服务器入口 API 使用名为 entries.tsx 的文件,该文件位于 src 文件夹的根目录,并返回一个包含 JSX 元素的对象。客户端会向服务器发送初始请求,得到服务器的响应并通过 Slot 组件进行渲染。为了使 Waku 支持在 Vercel 上部署,利用了其构建输出 API,通过自定义 “content-type” 头部并以函数方式定义 Waku 服务器,实现了客户端发送请求到服务器并返回 RSC 负载的功能。

MDH 前端周刊第 118 期:Electron 28、Safa 17.2、SvelteKit 2、状态管理、Waku

· 6 min read
加菲猫

🌟 AI 相关

【AIGC篇】NLP任务入门:分词、词性标注与命名实体识别

CPU 混合推理,非常见大模型量化方案:“二三五六” 位量化

⭐️ Go & 云原生 & Rust 相关

谷歌的开源供应链安全

盘点2023年在地球上举行的Gopher盛会

深入理解 Go Modules:高效管理你的 Golang 项目依赖

通过实例理解OAuth2授权

从方法论到最佳实践,深度解析企业云原生 DevSecOps 体系构建

Golang的websocket使用和实现代码分析

容器故障?别慌:debug 不行,还有superdebug

放弃自己造轮子,才能给微服务搭一个牛X的注册中心!

「GoCN酷Go推荐」我用go写了魔兽世界登录器

卷起来,老程序员也得了解errors包的新变化

什么是大端序和小端序,为什么要有字节序

Go Testing By Example--Russ Cox在GopherCon Australia 2023的演讲

回归单体成为潮流?腾讯文档如何实现灵活架构切换

成功上岸Go面经:百度滴滴小米360小红书展盟优咔科技

奶茶上云,原生的更好喝

[go 面试] 雪花算法与分布式ID生成

简单之道

如果你还对Go并发编程感到迷茫,也许是好事情

用Rust刷LeetCode之27 移除元素

Go函数指针是如何让你的程序变慢的

Go单线程运行也会有并发问题

Kubernetes 是怎么靠边车模式打败Docker的

Go语言中常见100问题-#92 Writing concurrent code that leads to false

Go Changes--Russ Cox在GopherCon 2023的演讲

Go未来演进:基于共同目标和数据驱动的决策

Go 语言字符串使用方式与技巧

📒 后端相关

CentOS7下快速搭建K8s集群实践

MySQL 深入学习总结

哈啰一面:如何优化大表的查询速度

面试官:网关如何实现限流

从零开始:使用Prometheus与Grafana搭建监控系统

给祖传系统做了点 GC调优,暂停时间降低了 90% | 京东云技术团队

MYSQL 事务的底层原理 | 京东物流技术团队

直播房间服务基于CQRS的架构演进实践

高并发系统设计的15个建议

《大明王朝》局部最优,严嵩父子的牢笼

Nacos 2.3.0 正式版发布,Nacos Controller 项目开源

关于消息队列的知识总结

从实现原理来讲,Nacos 为什么这么强

什么Leader值得追随

西瓜视频RenderThread引起的闪退问题攻坚历程

MyBatis Plus 解决大数据量查询慢问题

好好的“代码优化”是怎么一步步变成“过度设计”的

聊聊工作中常用的方法论

GitHub.com跑了1200多台MySQL主机,如何无缝升级到8.0

《瞬变》卡点的原因往往简单而愚蠢

从一个crash问题展开,探索gcc编译优化细节

放弃 ELK!SpringBoot接入轻量级分布式日志框架GrayLog

腾讯有点顶,连环追问我基础细节!

无语!我是来面Java的,你怎么问我大数据的Kafka

系统性思考:你考虑过传话筒的感受吗

📒 前端相关

StyleX:Meta 新出的原子化 CSS in JS 方案

网易云音乐 RN 新架构升级实践

【第3140期】在 Console 中更直观地展示 Reactive Objects

DevTools 不让粘贴执行代码了

深入浅出 Vite5 中依赖预构建

Chrome 120 有哪些值得关注的更新

微前端项目难点解决

MDH 前端周刊第 117 期:stylex、Vitest 1、Astro 4、React Forget、TanStack 路由

· 4 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

《大明王朝》沈一石的“生机”

用Rust刷LeetCode之26 删除有序数组中的重复项

Spring Boot 单体应用升级 Spring Cloud 微服务

2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

[go 面试] 一致性哈希:数据分片与负载均衡的黄金法则

依赖注入与控制反转:优化Go语言REST API客户端

书籍推荐: 深入理解Go并发编程

《大明王朝》阴阳对垒,千里布局

Redis 除了用作缓存还能干吗

万字串讲 git 版本控制底层原理及实战分享

如何提升研发效率-工具篇

用Rust刷LeetCode之66 加一

从底层逻辑聊日报如何提升公司效率

GORM最佳实践之不定参数的用法

[go 面试] 深入理解并发控制:掌握锁的精髓

OpenTelemetry Metrics 基础

模型服务网格:云原生下的模型服务管理

刚刚 Go 发布了 Go 1.21.5 安全补丁更新

Go errors 默认加堆栈信息,有用不

有效表达软件架构的最小图集

高并发场景下JVM调优实践之路

使用Rust Rayon库提升程序运行速度

没错,数据库确实应该放入 K8s 里!

更高精度的 Sleep

[go 面试] 接口测试的方法与技巧

Go 1.21.5 发布了

[go 面试] 前端请求到后端API的中间件流程解析

这个限流库两个大bug存在了半年之久,没人发现

手把手教你写设计方案

精要主义:你的生活是否一团乱麻

深入理解Go标准库-ServeMux的使用与模式匹配

如何一键生成前端代码

微服务架构是如何演进的

空降:新官的三把火会如何烧

一文搞懂Go gRPC服务Handler单元测试

把数据库放入 Docker是一个好主意吗

如何保留 Go 程序崩溃现场

2023年 Go 并发库的变化

Go Kit中读取原始HTTP请求体的方法

📒 前端相关

Facebook、Instagram 都在用的 CSS 解决方案开源了!

你了解 JSX,那你了解 StyleX 么

如何实现原生的 “跨组件” 通信

前端开发者们,这些知识tips你必须知道

封装一个用户体验非常棒的下拉选择框

译:Prettier 的命令行界面:性能深度剖析

京东快递小程序分包优化实践

MDH 前端周刊第 116 期:Astro 4 Beta、XState 5、Fresh1.6、Prettier 性能、Biome

· 12 min read
加菲猫

🌟 AI 相关

TensorFlow.js,让你的应用更加高级,更具逼格

为什么你应该把 Google / StackOverflow / 文档搜索都扔掉,改用 devv.ai

本地运行“李开复”的零一万物 34B 大模型

⭐️ Golang 相关

亲测体验Go语言PGO

降本增笑的P0事故背后,是开猿节流引发的代码异常吗

通过实例理解API网关的主要功能特性

编码相关的软技能,我看了这些书

1.5万字 + 25张图盘点RocketMQ 11种消息类型,你知道几种

为什么要建立研发数据指标

分享几个美团的秋招面试题

[go 面试] 为并发加锁:保障数据一致性(分布式锁)

使用Go Validator在Go应用中有效验证数据

Rust的Vec优化

如何在Go中进行内存优化和垃圾收集器管理(GC)

[go 面试] 并发与数据一致性:事务的保障

利用 Golang 中的 Recover 处理错误

向上管理:让你主动汇报就这么难

刷新了对GODEBUG的认知

[go 面试] 深入理解进程、线程和协程的概念及区别

如何成为优秀工程师之软技能篇

新晋总监生存指南

从单体到微服务,腾讯文档微服务网关工程化的演进实践

颠覆认知——Redis会遇到的15个「坑」,你踩过几个

正式开源!高性能轻量级跨平台QUIC协议库TQUIC来啦!

如何基于PrometheusAlert扩展告警值班功能

一线Leader怎么做?经理的速成宝典

Rust内存布局

使用 sync.Cond 来协调并发 goroutine 的访问共享资源

降本增效 - 应用优化 (三) 日志成本降低 100 倍

干掉复杂代码 — Spring Boot 与 CQRS 才是黄金组合!

go 1.22优化了string转byte切片的实现

分布式锁的各种实现,看完这篇你就懂了!

结合图文一起搞懂MySQL事务、MVCC、ReadView!

如何使用Redis数据类型进行亿级别统计数据

「有问必答」秒杀系统 Go并发编程实践!

当「华为还是备选,迪爹还是迪子」时宇宙厂一面原题

Prometheus 的查询语言 PromQL 详解

数据库死锁排查思路分享(纠正篇)

学习gorm系列八:探秘gorm.Save函数

一文搞懂Go gRPC服务Handler单元测试

第三个五年,独立思考、承受风雨

第二个五年,找到擅长的事

4 种消息队列,如何选型

Go语言中常见100问题-#91 Not understanding CPU caches

Go HTTP GET 请求可以发送 body 吗

📒 前端相关

【第3130期】Taro高性能小程序的最佳实践

Solid 作者从 React 中学到最重要的是什么

8个问题带你进阶 React

Next.js 超实用进阶技巧【持续更新】

嘿,vue中keep-alive有个「大坑」你可能还不知道

两行CSS让长列表性能渲染提升7倍!

《Why Rust in Production》。 近年来,Rust 的热度已经飙升,微软、谷歌、亚马逊等科技巨头正积极把 Rust 的优势应用于关键系统。然而,关于 Rust 的讨论仍然大多来自那些没有在大规模生产中使用 Rust,或者仅在非关键系统中使用过 Rust 的人。这导致对 Rust 在生产环境中应用的理解存在偏差,尤其对于中小企业来说更是如此。作为 Rust 顾问,从我与众多大小公司接触中发现,公司更看重效率、稳定性和长期可维护性,而不只是性能。然而,Rust 也有其缺点,如尚处在成熟中的生态系统,硬寻找拥有专业 Rust 经验的开发人员,编译时间较长等。尽管如此,这些挑战并不是难以克服的,只是需要对 Rust 承诺,并愿意投资于培训和工具。考虑到 Rust 所能带来的长期成功,专门的指导和支持是至关重要的。

《Building a Web App in Rust》。 这篇文章分享了作者使用 Rust 编程语言构建网络应用程序 JustFax Online 的经验。作者热爱 Rust 的理由包括其低内存使用、出色的安全性、异步开发、真正的类型安全性等优点。然而,作者也谈到了 Rust 的一些困难之处,例如借用检查器的复杂性、对于初学者的启动难度、相对较长的编译时间以及与 NodeJS 或 Python 相比较小的生态系统。尽管如此,作者仍表示非常享受使用 Rust 构建项目,并认为他能有效运行许多项目而无需花费大量资金。

《Rust without crates.io》。 文章提到了程序员对 crated.io 让大家自由上传和下载代码的依赖,并指出了这种行为的潜在风险:包括单点故障、黑客攻击、国家安全等问题。作者认为,我们应该从开发速度的祭坛上退后一步,理想情况下需要有一个独立于作者进行策展的角色来审视依赖。然而在现实中,这种人力评审的路径很难实现。对此,Linux 发行版如 Debian 的解决方案是将大量库的完整 Rust 源码打包进 librust-cratename-dev,虽然没有进行审计,但已经是一个很大的改进。此外,作者也介绍了如何通过几个简单的命令来实现这一过程。这给予作者对 Rust 更大的信心,他原本担心由 crates.io 的自由选择依赖版本的方式,抵制任何旧方法的语言,例如 C++。幸运的是,Debian 证明了他是错误的。

《我如何将 Rust 的编译时间提高 75%》。 这篇博客主要关于如何改善 Rust 编译时间,通过使用不同的优化方法和替代的编译器链接器。作者测试了多种不同的方法,包括使用 Mold 链接器,Cranelift 编码器,和更高的优化等级,他发现使用 Mold 链接器和 Cranelift 代码生成器可以最大程度地提高编译速度,能使编译时间分别减少 75% 和 25%。此外,博主对 Rust 的热重载提出了替代方法,即 cargo-leptos 的 --hot-reload 标志,它可以在更改检测时通过 web socket 连接向浏览器发送 html 和 css 补丁,并在后台编译。

《我怎么知道自己做得对不对》。 作者分享了自我学习新技术时的验证假设与自我提升的有效方法。首先,查找可靠的文档和示例,如 MDN 和 web.dev,他们通常能以实际用例解释理论知识;其次,利用编程语言的 linter 插件指导编程,这有助于改进编码习惯;接着,使用诸如 Lighthouse 和 Accessibility Insights 等测量性能的工具以评估是否妥协了性能或可访问性;此外,利用 AI 工具如 Copilot 简化代码。但对于新手来说,要对 AI 生成的指导持怀疑态度;也可以通过向行业内人士询问学习新信息的方式,来学习。最后,查找有关主题的教程以对照使用情况。学到新知识后,应考虑写下来分享,提高自我理解和提高他人。

《React 18 中的并发性》。 React 18 新增的并发功能是一种执行模型,允许程序的不同部分无序执行而不影响最终结果。在浏览器中的 JavaScript 只能访问一个线程,因此采用了一种称为协作多任务处理的并发模型。React 18 分为紧急状态更新和转换状态更新两种更新类型。默认情况下,所有状态更新都是紧急的,不可中断的。如果希望进入并发渲染,需要使用 startTransition 或 useDeferredValue 将更新标记为低优先级。若在渲染低优先级更新时出现高优先级更新,React 会中断当前渲染并转向渲染高优先级更新。另一个重要更新是 Suspense 组件的行为,它在低优先级更新过程中的挂起行为稍有不同。还引入了新的钩子函数 useTransition 和 useDeferredValue,使用这些工具可以处理复杂的状态更新场景。

TypeScript 发布 5.3。 微软发布了 TypeScript 5.3 版本,主要引入了众多新特性,包括导入属性和稳定地支持在所有模块模式中使用 resolution-mode。此外,这个版本提供了针对布尔值的缩窄对比,以及通过 Symbol.hasInstance 进行 instanceof 缩窄。对于 “超级” 的属性访问,TypeScript 5.3 还进行了检查。此外,新版本中的其他改进包括跳过 JSDoc 解析以进行优化,比较非标准化交集以进行优化,以及在 tsserverlibrary.js 和 typescript.js 间进行整合。这个新版本还修复了一些断裂的变化,并进行了正确性改进。

MDH 前端周刊第 115 期:TypeScript 5.3、RSC、30 条建议、0.6 + 0.3、CI 时间

· 12 min read
加菲猫

🌟 AI 相关

部署必备—triton-inference-server的backend(一)——关于推理框架的一些讨论

⭐️ Golang 相关

一文搞懂Go gRPC服务Handler单元测试

TCP 重传、滑动窗口、流量控制、拥塞控好难?看完图解就不愁了(重制)

揭秘 Go 中的模板:一份全面而广泛的指南

Kubernetes Pod 设计与实现 - 创建流程

2023年最新Docker网络讲解保姆级教程

Go语言项目命名规范(2023年最新版)

云音乐RPC稳定性建设与实践

完了,又被腾讯面试官拷打了 。。。

1.5万字+30张图盘点索引常见的11个知识点

Go 命名规范:全面指南

10个令人惊叹的Go语言技巧,让你的代码更加优雅

Go 内存分配:结构体中的优化技巧

注解方式优雅的实现 Redisson 分布式锁

Git 提交竟然还能这么用

Go怎么让协程跑一半就退出

从腾讯视频架构重构,看DDD的概念与方法

不少人面试都挂在这道题了!

99%的程序员容易忽视的“系统”健康问题

Kubernetes 探针设计与实现

Prometheus Go client library 详解

刷到一个比较骚的 Go 错误处理新提案。。。

Go 每日一库之 goose — 数据库版本管理工具

听GPT 讲Rust源代码--library/core/src(8)

我们公司都用哪些软件?强烈推荐这些!

微服务基本功:增加便利的监控服务指标

📒 前端相关

理解了Event Loop就理解了前端

微前端时代:打造高效、灵活的前端开发体系

函数组件 和 函数式编程 有关系么

「React 进阶」React 优雅的捕获并处理渲染异常

《别人不会告诉你的 10 个程序员工作的真相》。如何做合理的排期。例如,当项目经理要求你在周五之前实现 X 功能时,你不会说 "哦,我可以在周二之前完成"。相反,你会说"当然,没问题"。为什么?因为如果你承诺在周二之前完成,但遇到了一些问题,你就无法兑现承诺。相反,如果你接受周五为最后期限,并在周三之前完成,你就可以提前两天交付。关于如何进行估算,有很多公式,每个人都有自己的规则。我也有自己的规则。如果我需要交付某个功能,而我认为需要 2 天时间,为了安全起见,我会 多加大约 40% 的时间。因此,在这种情况下,预计时间是 3 天。之后,如果我在 2 天内完成了,我就可以提前交付。

《用 Rust 构建企业级 REST API》。 本文详细讲解了使用 Rust、Actix 网络框架和关系数据库开发企业级 REST API 的过程。文章从架构原则入手,分析了 API 的分层结构,着重解释了三个核心层级:基础设施层、服务层和存储 / 数据层。它详细介绍了使用各种流行的 Rust 插件和模式如何创建可测试和可维护的企业应用程序。讲解了如何进行单元测试每个层的可靠性,并提供了详细的代码示例。同时,文章指出设计中存在的问题,并讨论了可能的解决方案。最后强调了测试导向的开发方式和运用 OpenAPI 规范进行 API 文档化的重要性。

《在 Rust 中使用异步流》。 异步编程在处理随时间产生的数据(如网络响应或文件流)等程序性能提升方面非常有用。在 Rust 中,操作通常是同步的,即它们会阻塞线程直到完成。而异步操作允许在等待操作完成时运行其他任务,特别适用于 IO 绑定任务(如网络或文件操作)。Rust 的流可以被视为迭代器的异步版本,可以在整个序列准备就绪前,按照项目可用的顺序进行处理。Rust 的异步流主要通过 futures 和 tokio crates 实现。当处理大量随时间产生的数据,或无限序列(如股市报价)时,异步流是理想之选。在应用程序大部分时间都在等待 IO 操作的场景下,异步流可以显著提高吞吐量。对于需要实时处理数据的应用程序而言,如聊天应用,实时分析,或直播,异步流也十分有效。

《Rust 中的函数式编程模式》。 Rust 编程语言以内存安全和并发编程而闻名,但这并不是全部。实际上,Rust 在函数编程模式方面也有很强大的功能。尽管 Rust 不是纯函数式语言,但它借鉴了很多函数式编程的范例,使你能编写出清晰易维护的代码。函数式编程将计算视为数学函数的求值过程,并避免改变状态和可变数据。面向对象编程(OOP)围绕封装了状态(数据)和行为(方法)的对象来展开,依赖类的概念作为对象的蓝图,并常常使用继承来在类之间共享和扩展行为。而函数式编程(FP)侧重于没有状态的函数,它们操作不可变数据,函数充当一等公民,被用于抽象、封装和组合,迭代过程通常通过递归来表达。

《将 Javascript 应用程序部署到 Kubernetes 的最快方法》。 这篇文章教你如何将你的第一个 JavaScript 应用部署到 Kubernetes(一个容器编排平台)上。我们将使用 Minikube 在本地部署一个返回样本 JSON 对象的简单 Express 服务器。首先,我们通过 npm 初始化项目,并在 package.json 中安装 Express.js 框架。然后我们创建一个服务器,并使用 npm 运行它,确保它能够正确响应 GET 请求。接着,我们编写 Dockerfile 并用 Docker 构建和运行容器。最后,我们开启 Minikube,并使用 kubectl 执行部署 yaml 文件,成功将 Express 服务器部署到本地 Kubernetes 中。

《async Rust 的四年计划》。 本文作者讨论了四年前 Rust 发布的 async/await 特性,并指出 Rust 项目在此功能上几乎没有扩展。作者认为这是 async Rust 获得负面评价的主要原因。文章中,作者列出了他认为 async Rust 需要的一些功能,包括短期、中期和长期的功能。短期功能主要包括 AsyncIterator 和 async generators;中期功能包括 Objective-safe coroutine 方法和 Async destructors;长期功能包括改变 Rust 的一些基本规则。他建议 Rust 项目应有更清晰的开发方向和与社区的交流,并感谢那些在设计问题上与他交流的项目成员。

《React Router v6:新手指南》。 React Router 是 React 的标准路由库,能够管理具有多个视图的 React 应用的 URL。本教程介绍了 React Router v6 及其用法,包括基础导航路由、嵌套路由、带路径参数的嵌套路由和保护路由。在 React Router v6 中,使用 <Routes><Route> 组件进行路由,可以在 <Routes> 组件中嵌套 <Route> 组件以方便实现嵌套路由。还可以使用 useParams 钩子访问 URL 参数,useNavigate 钩子进行程序化导航。此外提供了用于实现路由保护的自定义路由。React Router v6.4 版本引入了由 Remix 启发的新特性,包括数据加载器和 create BrowserRouter,以改进数据获取和提交。

《掌握在 React 中使用 Framer Motion 进行 SVG 动画》。 本指南探讨了如何在 React 应用程序中使用 Framer Motion 动画库来创建 SVG 动画。首先,我们需要在 React 项目中安装 Framer Motion 并为动画准备 SVG。然后了解 Framer Motion 的动画原理,包括 motion 组件和 animate 属性的使用,在此基础上创建简单和复杂的 SVG 路径动画。进一步讲解了如何为常见的 SVG 形状添加动画,如何使用键盘事件等用户交互事件进行交互性动画设计,以及如何优化动画性能。无论是创建简单的悬停效果还是复杂的入场动画,Framer Motion 都提供了丰富的创意工具,使 SVG 动画的缩放和性能优势得以充分发挥。

MDH 前端周刊第 114 期:Vite 5、Prettier 3.1、恶意软件、FramerMotion SVG 动画、桶文件

· 11 min read
加菲猫

🌟 AI 相关

Transformer模型--模型架构

使用 Redis 构建轻量的向量数据库应用:图片搜索引擎(一)

⭐️ Golang 相关

【升职加薪秘籍】我在服务监控方面的实践(4)-日志监控

Go语言微服务框架重磅升级:dubbo-go v3.2.0 -alpha 版本预览

一文告诉你让SSH 变好用的正确姿势!

腾讯重复造轮子?我们真的需要这么多RPC框架吗

学习gorm系列七:如何高效建立数据库连接

Vite 5.0 正式发布

Git常用命令思维导图

实战:Nacos配置中心的Pull原理,附源码

Kubernetes - CRI 概述

解密defer语句:避免踩坑,掌握延迟执行的正确姿势

提升应用性能:Go中的同步与异步处理

Prometheus 14 点实践经验分享

老后端被借调去写Java了,含泪总结的Java多线程编程基础

史上最全の图论圣经: 涵盖所有「存图方式」与「最短路算法」

HBase详细介绍及原理解析!

微服务框架之争:Quarkus 即将替代Spring Boot

关系代数、SQL语句和Go语言示例

K8S 和 容器中的退出状态码含义,看你知道几个

Unix 编程艺术名句摘录

从4万行代码降到1.8万,腾讯视频竟然用DDD做架构重构

Web 实时消息推送的 7 种实现方案

最新进展:Go arena 手动管理内存,鸽了!

微服务不香了?单体化改造为我们节省上万核 CPU!

Golang 编译速度为什么这么快

写出高质量代码的秘诀:Golang中的测试驱动开发(TDD)

实战!接口中的大事务,该如何进行优化

用了这么多年Docker,殊不知你还有这么多弯弯绕!

Kubernetes上生产环境后,99%都会遇到这2个故障

Go语言爱好者周刊:第 204 期 —— Go 14 周年

📒 前端相关

前端基建有哪些?大小公司偏重啥

不是吧?async/await异常捕获你还在用try-catch~

IntersectionObserver:实现滚动动画、懒加载、虚拟列表

Introducing GPTs。OpenAI 正在推出一种新的定制版本的 ChatGPT—— GPTs。用户可创建专门用途的 GPT,无需编程知识,方便在日常生活、工作或学习等各种场景中使用,甚至可以和他人分享。用户可以在 chat.openai.com/create 上进行创建试用。ChatGPT Plus 和企业版用户今天就可以试用,包括 Canva 和 Zapier AI Actions。此外,本月晚些时候,OpenAI 将推出 GPT 商店,展示被认证的开发者的作品。在未来几个月,GPT 使用者也将有机会通过使用频率赚钱。OpenAI 表示,GPT 的所有措施都考虑到了隐私和安全,用户完全可以控制自己的数据。此外,开发者也可以将 GPT 连接到真实世界,定义自定义动作,连接到数据库,插入电子邮件,或者使用购物助手等。企业版用户也可以部署仅限内部的 GPT,满足特定使用场景,部门或具有专有数据集的需求。

Vue design patterns guide。Vue是一个流行的用于构建用户界面的渐进式JavaScript框架。与其他的全功能框架不同,Vue被设计为可逐步采用,这意味着其入门易如jQuery,但与现代化工具和支持库结合使用时,有潜力支持复杂的应用程序。理解和利用Vue的模式可以大大帮助编写清晰、高效和可维护的代码。本站将详细讲解Vue的特定模式和行为,包括可组合函数、脚本设置、状态管理、提供/注入、动态组件等概念。无论你是初学者,还是希望更好地理解一些有用的模式,这里都能提供帮助。

Github 推出新的字体。

Rust 在 nightly 版本中通过并行前端技术加速编译过程。Rust 编译器的前端现在可以使用并行执行功能,以大大缩短编译时间。用户可以通过使用 - Z threads=8 选项在夜间编译器上尝试此功能。这项功能现在还处于实验阶段,预计将在 2024 年的稳定版编译器中进行发布。通过使用 Rayon 实现细粒度的并行任务,新的前端可以并行执行许多编译任务。用户可以通过 - Z threads 选项打开多线程模式。测试结果表明,编译时间可以减少多达 50%,但结果取决于代码的特性和构建配置。尽管并行前端运行在单线程模式下,编译时间一般仅慢 0% 到 2%。因此,用户应几乎不会注意到增加的延迟。此外,Rust 编译器的实现遵循 jobserver 协议,将创建的线程数量限制在内核数量以内,因此不会出现效率低下的情况。

《你为什么需要 React Query》。 文章主要讨论了 React Query 的实用性和特性,反驳了一些声称不需要 React Query 进行数据获取的观点。作者认为,尽管像 fetch-in-useEffect 这样的标准例子看似简单,但在处理边界情况和状态管理时,会引入诸多复杂性和问题。反观 React Query,它能解决这些问题并简化开发。优点包括自动防止竞态条件,免费获得加载、数据和错误状态,显然分离没有数据的状态,根据需要获取前一个类别的数据或错误等。作者最后挑战读者在下一个项目中尝试使用 React Query,他认为这不仅可以使代码更加易于维护和扩展,而且可以提供更强大的功能。

《re-re-reselct - 简化 React 状态管理》。 Causal 博客文章介绍了他们设计和实现的状态管理解决方案——Causal Selectors。文章先分析了管理复杂网页应用中状态数据的挑战,然后解释了两种类型的 Causal Selectors —— 叶子选择器和组合选择器的工作原理。文章还阐述了它们如何优化性能,减少不必要的重渲染,并与React进行整合。但新框架的初步效果并不理想,所以他们通过优化选择器的性能和订阅管理,最终使其性能回到原始水平,同时使状态管理更容易使用。他们计划完成所有组件的迁移,缓存拓扑排序以增加速度,并将状态从Redux移出,以便更好地管理后端查询的状态。

《利用 NextJS、Trigger.dev 和 GPT4 打造一款简历制作工具》。 本文教你如何使用 NextJS、Trigger.dev、Resend 和 OpenAI 创建一个简历生成器。内容包括基本信息(如名字、姓氏以及最后工作的地方),生成和创建 PDF, 最后发送给你的邮箱。我们使用 NextJS 创建一个简单的表单,使用 react-hook-form 进行字段验证和表单信息保存,利用 NextJS 提供的路由处理网络请求。我们利用 Trigger.dev 进行后台任务处理,例如用 ChatGPT 生成内容,创建 PDF 和通过邮件发送。然后通过 OpenAI 构建 ChatGPT,通过 jsPdf 库创建 PDF,最后通过 Trigger.dev 的 Resend 集成包实现邮件发送。 完整的源代码可以在 Github 上找到。

《React 设计模式》。 本文介绍了 React 设计模式,包括容器和演示模式,钩子组件组合,使用 Reducer 的状态管理,使用 Provider 的数据管理,使用 HOCs(高阶组件)进行组件增强,复合组件,属性组合,受控输入以及使用 fowardRefs 管理自定义组件等。通过运用这些设计模式和最佳实践,可以提升代码质量,推动团队协作,并让你的应用变得更加可扩展、灵活、可维护。

MDH 前端周刊第 113 期:Angular.dev & 17、pacquet、设计模式、Rust Prettier 悬赏

· 9 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

两全其美:Sidecarless 与 Sidecar 模式融合的服务网格新形态

Fourteen Years of Go

Go 团队发布 Go 14 周年回顾!附加更完整新特性脑图!

米哈游大数据云原生实践

没用过微服务?别慌,丐版架构图,让你轻松拿捏面试官

并发编程巅峰对决:Go vs Rust

Sentinel为什么这么强,我扒了扒背后的实现原理

写给go开发者的gRPC教程-gRPC Gateway

Rust 中的异步编程模型

Rust 作为一门现代的系统级编程语言,旨在提供高效、安全和可靠的异步编程能力。Rust 异步编程的目标是实现高性能、无安全漏洞的异步应用程序,同时提供简洁的语法和丰富的异步库。

由于并发编程在现代社会非常重要,因此每个主流语言都对自己的并发模型进行过权衡取舍和精心设计,Rust 语言也不例外。下面的列表可以帮助大家理解不同并发模型的取舍:

  • OS 线程, 它最简单,也无需改变任何编程模型(业务/代码逻辑),因此非常适合作为语言的原生并发模型,我们在多线程章节[3]也提到过,Rust 就选择了原生支持线程级的并发编程。但是,这种模型也有缺点,例如线程间的同步将变得更加困难,线程间的上下文切换损耗较大。使用线程池在一定程度上可以提升性能,但是对于 IO 密集的场景来说,线程池还是不够看。
  • 事件驱动(Event driven), 这个名词你可能比较陌生,如果说事件驱动常常跟回调( Callback )一起使用,相信大家就恍然大悟了。这种模型性能相当的好,但最大的问题就是存在回调地狱的风险:非线性的控制流和结果处理导致了数据流向和错误传播变得难以掌控,还会导致代码可维护性和可读性的大幅降低,大名鼎鼎的 JS 曾经就存在回调地狱。
  • 协程(Coroutines) 可能是目前最火的并发模型,Go 语言的协程设计就非常优秀,这也是 Go 语言能够迅速火遍全球的杀手锏之一。协程跟线程类似,无需改变编程模型,同时,它也跟 async 类似,可以支持大量的任务并发运行。但协程抽象层次过高,导致用户无法接触到底层的细节,这对于系统编程语言和自定义异步运行时是难以接受的
  • actor 模型是 erlang 的杀手锏之一,它将所有并发计算分割成一个一个单元,这些单元被称为 actor , 单元之间通过消息传递的方式进行通信和数据传递,跟分布式系统的设计理念非常相像。由于 actor 模型跟现实很贴近,因此它相对来说更容易实现,但是一旦遇到流控制、失败重试等场景时,就会变得不太好用
  • async/await, 该模型性能高,还能支持底层编程,同时又像线程和协程那样无需过多的改变编程模型,但有得必有失,async 模型的问题就是内部实现机制过于复杂,对于用户来说,理解和使用起来也没有线程和协程简单,好在前者的复杂性开发者们已经帮我们封装好,而理解和使用起来不够简单,正是本章试图解决的问题。

Rust并发编程 - 第三章 async/await 异步编程

只改一个参数让Golang GC耗时暴降到1/30!

不想引入mq?试试debezium

考考你,给32位系统的电脑插个8G的内存条会发生什么

Redis 消息队列和 Kafka 有啥区别

Kafka 消息会落盘,会持久化,但是 Redis 是基于内存的消息队列,如果实例重启会导致数据丢失。Redis 如何实现高可用,有两种方式,1)生产环境会用 Redis 集群模式,有多个副本,读写操作都是针对主节点,会异步复制给从节点,保证最终一致性。假如主节点挂了,则会在从节点中选举一个新的主节点,2)Redis 也支持持久化。

此外,Kafka 相对于 Redis 消息队列在吞吐量和延迟方面更为优秀(同一个 Topic 下可以有多个 Partition),可以处理更高的消息流量,并且具备较低的延迟。

RPC 调用和浏览器 HTTP 请求有啥区别

RPC 也称为内部调用,client 启动的时候会创建一个连接池,提前建立 tcp 链接,后续调用都复用 tcp 链接,避免频繁的 tcp 三次握手,提升性能。此外 RPC 调用还有一套服务发现机制(类似 DNS),可以直接用服务名的方式调用。由于内部调用不经过网关,因此需要在调用方实现负载均衡,比如 OpenFeign 底层基于 Ribbon 实现负载均衡。

浏览器发送 HTTP 请求则需要在发送请求的时候实现 DNS 解析、TCP 三次握手等操作,一定程度上会影响性能。之前写过一个 Node 服务,在 Node 环境用 http 模块去调用其他接口,实际上会带来一定的性能开销。如果在程序频繁执行到的关键路径上,改用微服务 RPC 调用方式可以提升性能。

Apache RocketMQ,构建云原生统一消息引擎

25张图盘点 RocketMQ 11 种消息类型!

聊聊如何在Java应用中发送短信

Go1.21.4 发布了:官方图片竟然用的 loong64

Golang面试题从浅入深高频必刷「2023版」| 文末送书

盘点golang中的开发神器

Go 透明文件夹的特性,有没有必要加

24 个 Docker 常见问题处理技巧

烂大街的 RPC 项目,如何和字节面试官聊出花儿来

一次 Netty 代码不健壮导致的大量 CLOSE_WAIT 连接原因分析

应用容器化后为什么性能下降这么多

只改一行语句,锁这么多

Rust并发编程番外篇: Mutex内部实现

📒 前端相关

2023云栖大会的新鲜事

不是吧?async/await异常捕获你还在用try-catch~

Why You Want React Query

Rspack 的设计背景和探索之路

ECMAScript 2023:为JavaScript带来新的数组复制方法

Antd Procomponent 之 proForm - 高级表单

Guide to React Suspense: From Code Splitting to Data Fetching

MDH 前端周刊第 112 期:Docusaurus 3、Remix & Vite、D2、React Forget

· 2 min read
加菲猫

· One min read
加菲猫
- - + + \ No newline at end of file diff --git a/2023/page/2/index.html b/2023/page/2/index.html index b022e87150..84286b3d63 100644 --- a/2023/page/2/index.html +++ b/2023/page/2/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 2 min read
加菲猫

· 3 min read
加菲猫

· 3 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

精进云原生 – Dubbo Kubernetes 最佳实践

如何使用Higress快速实现金丝雀与蓝绿发布

Kubernetes 应用最佳实践 - 金丝雀发布

PGO: 为你的Go程序提效5%

一个泛型的有序Go Map实现

Go 1.21中 sync.Once的新扩展

怎么阻止一个Go程序退出

字节三面:如何设计一个高性能短链系统

40 个定时任务,带你理解 RocketMQ 设计精髓!

在Golang中玩转依赖注入-dig篇

简单聊一聊公平锁和非公平锁,parallel并行流

高频面试:Spring 如何解决循环依赖

Go 1.21 不仅修复了 go 命令行的安全问题,还修复了一个编译大文件的问题!

Go项目目录该怎么组织?官方终于出指南了!

DDD的奇幻世界:从小积木到艺术品的设计之旅

相较于RocketMQ的事务消息,本地消息表才是真正的王者

仅此一招,再无消息乱序的烦恼

消息队列技术选型:这 7 种消息场景一定要考虑!

Kafka 架构、核心机制和场景解读

为什么 MyBatis 源码中,没有我那种 if···else

解密DDD:领域事件--系统解耦的终极武器

DDD 与 CQRS 才是黄金组合

DDD 必备架构--六边形架构

📒 前端相关

某大厂一面: 讲讲 Fiber 架构以及它是如何实现增量渲染的🥱🥱🥱

面试被问到低代码细节?听我这样吹(含架构和原理)

前端铜九铁十面试必备八股文——工程化

Threejs 中秋佳节感受闽南名俗 | 中秋博饼🥮🥮🥮

【动图+大白话🍓解析React源码】Render阶段中Fiber树的初始化与对比更新~

· 3 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

Java 8 的 Stream 不好调试?试试 IDEA 的调试神器 Stream Trace!

@Async注解的坑,小心

折腾一个周末,撸Nacos可真不容易

图解ReentrantLock的基石AQS源码-独占锁的获取与释放

下单时如何保证数据一致性

一个关于 i++ 和 ++i 的面试题打趴了所有人

Deconstructing Type Parameters

MySQL到TiDB:Hive Metastore横向扩展之路

谁家面试往死里问事务啊

从5s到0.5s!看看人家项目中的异步任务优化技巧,确实优雅!

使用 查询分离 后 从20s优化到500ms

业务系统架构实践总结

一文了解负载均衡器、反向代理、API 网关区别

Golang GC 从理论到针对服务的定制化应用

Kubernetes 应用最佳实践 - 水平自动伸缩

还不会部署微服务项目?保姆级教程来啦!

专为小白打造—Kafka一篇文章从入门到入土 | 京东云技术团队

美团二面拷打:如何设计一个优先级任务线程池

深入理解 RocketMQ 广播消费

Kubernetes 应用最佳实践 - 亲和性和污点容忍度

一文带你深入理解Kubernetes Service

鹅厂练习13年Coding后,我悟了

定了:Go 1.22将修复for循环变量错误

给你一个亿的keys,Redis如何统计

HyperLogLog 算法原理及其在 Redis 中的实现

快速掌握 Go 工作区模式

麻了啊!一个烂分页,踩了三个坑!

Go 1.21.0 新增标准库 slices 和 maps 详解

Go语言爱好者周刊:第 201 期

📒 前端相关

面试被问到低代码细节?听我这样吹🤯(含架构和原理)

加速 JavaScript 生态系统:Polyfills 出现问题了吗

MDH 前端周刊第 107 期:Safari 17、stylex、Svelte 5、线性代码

· 4 min read
加菲猫

🌟 AI 相关

从教师到学生:神奇的“知识蒸馏”之旅——原理详解篇

⭐️ Golang 相关

使用Go和WebRTC data channel实现端到端实时通信

go vet中的那些检测项

【树形 DP】如何从"方向"角度理解树形 DP

用这4招 优雅的实现Spring Boot 异步线程间数据传递

盘点 Go 语言的那些日志库:你用了哪个

一文入门Istio架构原理及实战应用

降本增效 - 应用优化 (二)

一文讲透Redis分布式锁安全问题

程序员新人频繁使用count(*),被组长批评后怒怼:性能并不拉垮!

【树形 DP】树形 DP 的通用思路

Kubernetes 应用最佳实践 - Sidecar 模式

替代ELK:ClickHouse+Kafka+FlieBeat才是最绝的

开源框架中的责任链模式实践

硬核!美团秋招一面

Grafana 开源了一款 eBPF 采集器 Beyla

Go 语言如何获取 CPU 利用率

使用Singleflight优化Go代码

结合 pprof 分析了启用 PGO 前后性能差异。比较意思的点,启用 PGO 之后性能提升最明显的竟然是 GC(runtime.scanobject)。为啥可以提升 GC 性能,因为 PGO 可以分析 hot function 调用,让这些函数内联(正常编译器不一定会内联),原本一个函数返回结构体指针,会逃逸到堆内存,内联之后就分配到栈内存了,因此可以减少堆内存分配,进而减少 GC 压力。相比之下,业务代码的性能反而会略微下降。

Profile-guided optimization in Go 1.21

Perfectly Reproducible, Verified Go Toolchains

SpringBoot 玩一玩代码混淆,防止反编译代码泄露

Go 项目必备:深入浅出 Wire 依赖注入工具

Golang channel 三大坑,你踩过了嘛

长达 1.7 万字的 explain 关键字指南!

从内核世界透视 mmap 内存映射的本质(原理篇)

做好这四步,服务端轻松成为全栈化人才

如何在Kubernetes中使用Init Container

Go 官方新玩具:漏洞管理和扫描,看看自己项目有没有坑

📒 前端相关

基于 RPC 和 TypeScript 的 BFF 设计与实践

前端食堂技术周刊第 99 期:Remix 2.0、v0、2023 组件库盘点、TS Config 备忘录、Hello 算法

MDH 前端周刊第 106 期:v0、Remix 2、TSConfig、Bun

· 3 min read
加菲猫

· 5 min read
加菲猫

🌟 AI 相关

⭐️ Golang 相关

OpenTelemetry入门看这一篇就够了|公开课

盘点 Go 语言的那些日志库:你用了哪个

Apache RocketMQ 5.0 消息进阶:如何支撑复杂的业务消息场景

你折腾一天都装不上的插件,函数计算部署 Stable Diffusion 都内置了

如何让 Llama2、通义千问开源大语言模型快速跑在函数计算上

降本增效 - 应用优化 (一)

【面试高频题】二叉树"神级遍历"入门

ELK Stack生产实践

在云原生微服务架构模式下,应用程序通常被设计成无状态(stateless)的,即应用程序不依赖于特定的运行环境状态。这种设计理念使得应用程序可以更加灵活地部署和扩展。

在 Kubernetes 中,容器的标准输出流(stdout)和标准错误流(stderr)默认被重定向到 Pod 的 stdout 和 stderr。这样,应用程序在容器中的日志输出将被重定向到 Pod 的 stdout,可以通过 Kubernetes 日志收集器(如 Fluentd、ELK Stack 等)将这些日志收集并发送到日志存储或分析系统中。

通过将日志输出到 Pod 的 stdout,可以实现以下好处:

  • 简化日志收集:无需在应用程序中实现特定的日志收集逻辑,只需将日志输出到 stdout 即可,由 Kubernetes 的日志收集器负责收集和处理。
  • 可移植性:无论应用程序在何种环境中运行(如本地开发环境、云平台等),日志输出都可以保持一致,不需要修改代码。
  • 可扩展性:由于容器是可以水平扩展的,多个容器实例共享同一个 stdout,可以方便地集中管理和处理日志。

ELK Stack生产实践——Docker部署ELK8.8与日志采集

ELK Stack生产实践——ES索引策略配置与管理

ELK Stack生产实践——数据查询与数据可视化(Kibana)

ELK Stack生产实践——数据查询与数据可视化(Grafana)

ELK Stack生产实践——ELK监控与告警(Kibana)

ELK Stack生产实践——ELK监控与告警(Prometheus)

ELK Stack生产实践——pod日志采集(Elastic Agent方案)

Linux防火墙Iptables原来这么简单(图文并茂)

Go 1.21 是不是还没用上?新版又来了

00 后架构师,那可能么

一文带你了解Docker与Containerd的区别

Ingress企业实战:实现GRPC与WebSocket服务访问

Kubernetes 应用最佳实践 - 资源请求和限制

Traefik 企业实战:TraefikService篇

探索 Go1.21 中的 slices 包:原理,特点和示例

「GoCN酷Go推荐」协程池ants介绍

「GoCN酷Go推荐」使用 cmux 实现服务端连接多路复用

MySQL连环炮,你扛得住嘛

深入剖析 Golang 程序启动原理 - 从 ELF 入口点到GMP初始化到执行 main!

Prometheus-Operator:告警排班功能实现

slog实战:文件日志、轮转与kafka集成

电脑用GoLand太卡,记录下自己把VsCode定制成Go IDE的步骤和过程

Go语言爱好者周刊:第 199 期 —— 一图掌握 Go1.21 的新特性

📒 前端相关

Chrome 117 发布:新 Web 开发调试技巧都在这了!

/[通明境 · React架构/]通俗地讲React,优雅地理解React

React-Router 6.10+KeepAlive的约定式路由最佳实践

干货!我是如何在一线大厂实践webpack优化的

构建高性能 React Native 跨端应用—图片与内存

MDH 前端周刊第 104 期:Astro 3、Npm 10、Biome、State of CSS 2023

· 3 min read
加菲猫

🌟 AI 相关

廉价的全闪存雷电 NAS 折腾笔记:组网方案的选择

廉价的家用工作站方案:ThinkPad 存储升级及数据迁移

SDXL LoRA 模型推荐

⭐️ Golang 相关

腾讯 13 年,我所总结的Code Review终极大法

【GoCN酷Go推荐】Shopify 出品的完整度最完善的 Kafka 客户端_sarama

slog正式版来了:Go日志记录新选择!

Prometheus-Operator:告警自动创建钉钉群

Kubernetes 应用最佳实践 - 开篇

后端思维专栏:通过层层代码去重,我又搞了一个通用模板

外卖骑手一面,也很不容易!

编译Go应用的黑盒挑战:无源码只有.a文件,你能搞定吗

详解 canal 同步 MySQL 增量数据到 ES

挖掘Kubernetes 弹性伸缩:利用 KEDA实现基于事件驱动的自动缩放器

SpringBoot+Redis BitMap 实现签到与统计功能

解锁Golang模板的力量:动态文本生成的初学者指南

Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理

Go 负责人说以后不会有 Go2 了

异或运算的妙用

Traefik 企业实战:路由规则篇

一文告诉你怎么打造对本地友好的 Kubernetes 工作环境

一文告诉你怎么将应用搭上云原生这趟便车(上)

Go Gin 框架系列 - 入门篇

Redis 热 key 是什么问题,如何导致的?有什么解决方案

RocketMQ 事务消息初体验

Sonic: Go语言的超级JSON库,解析与编码速度狂飙

Prometheus-Operator:告警认领功能实现

go-zero 的自适应熔断器

万字长文,教你用go开发区块链应用

Go语言爱好者周刊:第 198 期 —— 回来了

📒 前端相关

译:React 并发模式的基本原理

精读《算法题 - 地下城游戏》

前端首屏优化 | 借助客户端能力提升 H5 首屏的 8 个手段

构建高性能 React Native 跨端应用—引擎与渲染

前端食堂技术周刊第 96 期:2023 CSS 状态、Nuxt 3.7、TypeScript 5.2、eBay 性能优化

MDH 前端周刊第 103 期:TypeScript 5.3、贝塞尔曲线、Suspense、React 并发模式

· 4 min read
加菲猫

🌟 AI 相关

发布一天,Code Llama代码能力突飞猛进,微调版HumanEval得分超GPT-4

⭐️ Golang 相关

使用 OpenTelemetry Collector 收集 Kubernetes 日志数据

《谷歌的软件工程》笔记(二)

《谷歌的软件工程》笔记(一)

kafka producer 在 aws 又挂了

『曹大带我学 Go 』系列文章汇总

曹大带我学 Go(11)—— 从 map 的 extra 字段谈起

曹大带我学 Go(10)—— 如何给 Go 提性能优化的 pr

曹大带我学 Go(3)—— 如何用汇编打同事的脸

曹大带我学 Go(2)—— 迷惑的 goroutine 执行顺序

曹大带我学 Go(1)——调度的本质

深度阅读之《100 Go Mistakes and How to Avoid Them》

Canal 同步数据坑太多?来试试 Logstash!

还在为MySQL数据同步Elasticsearch发愁?快来试试Canal!

Structured Logging with slog

使用 OpenTelemetry Collector 采集 Kubernetes 指标数据

面试官:什么是大事务?小林哥:就是 很大...的...事务

Go语言中常见100问题-#90 Not exploring all the Go testing features

从 0 开发工作流引擎 003|服务拆分

Prometheus-Operator:告警路由配置

【面试高频题】值得仔细推敲的贪心及其证明

听GPT 讲Prometheus源代码--promql/promdb

Traefik 企业实战:部署生产级Traefik篇

学习gorm系列二:如何指定数据表

【全套换新】还在用mvn构建SpringBoot? 新项目都在用java17+gradle+k8s(5000字附源码)

13 秒插入 30 万条数据,这才是批量插入正确的姿势!

一个 MySQL 隐式转换的坑,差点把服务器搞挂了

除了缓存,性能优化还可以这么搞

听GPT 讲Prometheus源代码--util

内存分配不再神秘:深入剖析malloc函数实现原理与机制

Ingress企业实战:部署多个Ingress控制器

Go 零值和空值的判断问题

10张图总结并发编程最佳学习路线,上车!

优化重复冗余代码的8种方式!

听GPT 讲Prometheus源代码--rules/scrape等

HTTP1 到 HTTP3 的工程优化

Sidecar模式

Prometheus-Operator:自定义告警

Go 1.21中值得关注的几个变化

关于Linux 网络抓包的一些笔记整理

net/http 库关于性能和线程安全的FAQ

学习gorm系列一:创建数据库连接

Prometheus-Operator:自动发现

📒 前端相关

不一样的"代码拆分"+"预加载"实现应用性能及体验兼得

提高 React 项目整洁度的 21 个最佳实践

[性能优化] The Cost Of JavaScript (2017 - 2023) | JavaScript 性能优化之旅

JavaScript 中文周刊 #102 - 创建 web 3D 体验的完整指南

React 服务端渲染在跨端领域中的新视界

MDH 前端周刊第 102 期:Million 自动模式、Fresh、公开写作、Suspense 节流

· 4 min read
加菲猫

image

题图:博德之门3,上周末沉浸式体验了 20+ 小时。。

🌟 AI 相关

用YOLOv8一站式解决图像分类、检测、分割……

谈谈RNN生成文本的小原理,动手实现AI写藏头诗

⭐️ Golang 相关

Elasticsearch 保姆级入门篇

借助ChatGPT快速上手ElasticSearch dsl

从Kafka中学习高性能系统如何设计 | 京东云技术团队

Kubernetes 核心概念

Rust 编程第一课

https://time.geekbang.org/column/article/408409

Prometheus-Operator:自定义监控

Golang并发模式之扇入扇出

Go 常见并发模式实现(一):调度后台处理任务的作业程序

Go 并发编程实战课

https://time.geekbang.org/column/intro/100061801

https://pursuitking.com/go_2/

吵翻了!到底该选 Rust 还是 Go,成2023年最大技术分歧

干!vivo 容器集群监控系统优化之道

当 Go struct 遇上 Mutex:也许不太一样了

Go go-queue 库实现 kafka 的发布/订阅

Go Mutex 之4种易错场景盘点

异步请求-响应模式

Ingress企业实战:URL重写与高级玩法

zap (附录) - FAQ

Backward Compatibility, Go 1.21, and Go 2

使用 uber-go/zap 实现一个极简日志系统

Docker 部署 Prometheus 实现一个极简的 QPS 监控

「Go开源」vegeta: http压力测试工具库

Ingress企业实战:HTTPS证书管理与双向认证篇

zap 高性能设计与实现

Go 将增加内置的零值标识符 zero!

字节二面:10Wqps会员系统,如何设计

深入探索 Go 1.21.0 中的 maps 工具库

用了Go匿名结构体,搬砖效率更高,产量更足了

go的net/http有哪些值得关注的细节

Ingress企业实战:金丝雀与蓝绿发布篇

Go异常处理机制panic和recover

实战!使用 阿里 Arthas 工具分析 CPU 飙高

📒 前端相关

WebRTC这么火🔥,前端靓仔,请收下这篇入门教程

现代 React 开发必备的 13 个神库,路由、UI 组件库、拖拽、虚拟列表都齐了

提高 React 项目整洁度的 21 个最佳实践

React 核心技术分析—让跨端动态化成为可能

前端食堂技术周刊第 94 期:TS 5.2 RC、从零实现 RSC、Redux 迁移至 ESM 之旅、HTML 满汉全席

MDH 前端周刊第 101 期:MDH Weekly 恢复、RSC Devtool、Node 配置地狱、npm包 ESM、技术债

- - + + \ No newline at end of file diff --git a/2023/page/3/index.html b/2023/page/3/index.html index 2c40631054..a3719728aa 100644 --- a/2023/page/3/index.html +++ b/2023/page/3/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 4 min read
加菲猫

🌟 AI 相关

🦙使用数据集微调Llama 2最简单方法 ,Llama 2 “烹饪”食谱,附colab完整笔记

硬件笔记:能快速更换的散热耗材,固态硅脂

⭐️ Golang 相关

Prometheus入门

Go项目初始化不再困扰你:gonew全方位解析

云原生运维相关:

基于Openresty+Lua实现微服务Api 网关

挖掘Kubernetes 弹性伸缩:扩展监控指标实现丰富弹性

挖掘Kubernetes 弹性伸缩:水平 Pod 自动扩展的全部潜力

Kubernetes运维必掌握的12个Kubectl命令

下一代云原生网关Higress:基于Wasm开发JWT认证插件

万字长文带你看全网最详细Dockerfile教程

别再用 offset 和 limit 分页了,性能太差!

Go 语言中的零拷贝

Git 速查表:中级用户必备的 12 个 Git 命令

浅谈 K8s Pod IP 分配机制

Go context.WithCancel()的使用

「Go面经」算法 并发模型 缓存落盘 etcd actor模型

Go 1.21 延迟 8 天发布,包大小直降超过 30%

Asynq: 基于Redis实现的Go生态分布式任务队列和异步处理库

多网卡管理高手:Multus-CNI的奇妙之旅

又有新功能!Go 将有生成新模板的 gonew 工具链

不想引入MQ?试试debezium

Go程序里该不该使用 runtime.KeepAlive 这类操作

服务缓存设计指南

使用 OpenTelemetry 构建可观测性 01 - 介绍

Go 1.21 新内置函数:min、max 和 clear

大型 Go 代码库的 3 种最佳设计模式

Go1.21 那些事:泛型库、for 语义变更、统一 log/slog、WASI 等新特性,你知道多少

使用go-zero快速构建微服务

听GPT 讲K8s源代码--pkg(八)

业务规则引擎演变简述

图解Redis和Zookeeper分布式锁 | 京东云技术团队

Kafka实时数据即席查询应用与实践

证书管理:从手工到平台化

听GPT 讲K8s源代码--pkg(七)

Gopher Daily改版了

Go语言爱好者周刊:第 197 期 —— Go 开发者调查

📒 前端相关

探索跨端开发的常用解决方案:条件编译的实现

干货 | 携程度假基于 RPC 和 TypeScript 的 BFF 设计与实践

代码之外的尤雨溪:在新加坡的生活,以及如何面对黑粉

· 5 min read
加菲猫

🌟 AI 相关

Stable Diffusion 硬核生存指南:WebUI 中的 GFPGAN

Stable Diffusion 硬核生存指南:WebUI 中的 CodeFormer

Stable Diffusion 硬核生存指南:WebUI 中的 VAE

⭐️ Golang 相关

Golang实现单机百万长连接服务 - 美图的三年优化经验

一站式Golang内存洗髓经[Go三关典藏版]

深入理解Golang协程调度GPM[Go三关典藏版]

Golang三色标记混合写屏障GC模式全分析[Go三关典藏版]

了解go在协程调度上的改进

浅析bitset的实现原理:一个将非负整数映射到布尔值的位集合库

PromQL看这个就够了

Go Runtime功能初探

Go 性能分析工具从入门到精通

服务架构:Web-Queue-Worker架构

Golang 如何操作 Kafka

Go社区主流Kakfa客户端简要对比

一篇搞定:消息队列概念、kafka入门、Kafka Golang客户端库

Go语言如何操纵Kafka保证无消息丢失

Golang 语言中 kafka 客户端库 sarama

19.Go语言编程之Kafka基础介绍与发布订阅实践

Go 1.21 发布已延期,昨天才发布 Go 1.20.7 和 Go 1.21rc4

Opentelemetry 实践分享 - Golang篇

Go项目实现日志按时间及文件大小切割并压缩

使用 Go 语言实现二叉搜索树

拜托,别在 agent 中依赖 fastjson 了

一款 IDEA 插件帮你优雅转化 DTO、VO、BO、PO、DO

制作crate并发布到Crates.io

Go 改版本号规则,主版本号终于支持第三位数字 0 了

如何用 Docker 容器运行单节点 Kafka 环境

version: '3'
services:
zookeeper:
image: confluentinc/cp-zookeeper
hostname: zookeeper
container_name: zookeeper
ports:
- "2181:2181"
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
kafka:
image: confluentinc/cp-kafka
depends_on:
- zookeeper
hostname: kafka
container_name: kafka
ports:
- "9092:9092"
environment:
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

运行以下命令启动 Kafka:

$ docker-compose up -d

使用以下命令进入 Kafka 容器并使用 Kafka 的命令行工具进行操作:

$ docker exec -it kafka /bin/bash

然后可以使用 Kafka 的命令行工具进行操作,例如,下面的命令会创建一个名为 test 的主题,并将其配置为单个分区和单个副本因子:

$ kafka-topics --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test

使用 Kafka 命令行工具中的 kafka-console-producer.sh 脚本来启动一个生产者,可以将消息发送到 test 主题中。在命令行窗口中运行以下命令。当命令行提示符出现时,你可以开始输入消息。每输入一行,该消息就会被发布到 test 主题中。

$ kafka-console-producer --broker-list localhost:9092 --topic test

新开一个终端,使用 Kafka 命令行工具中的 kafka-console-consumer.sh 脚本来启动一个消费者,可以从 test 主题中接收消息。在命令行窗口中运行以下命令。该命令将打印 test 主题中的所有消息。

$ docker exec -it kafka /bin/bash

$ kafka-console-consumer --bootstrap-server localhost:9092 --topic test --from-beginning

推荐 GoLand 提供的 Kafka 插件:

https://www.jetbrains.com/help/idea/2023.2/big-data-tools-kafka.html#connect_to_kafka_custom

一文总结 MetaQ/RocketMQ 原理

Go语言开发者的Apache Arrow使用指南:读写Parquet文件

使用Redis,你必须知道的21个注意要点

缓存的策略和模式

GoLand 2023.2 发布:有 AI 助手

https://www.jetbrains.com/go/whatsnew/#:~:text=GoLand%202023.2%20offers%20improved%20integration,integration%2C%20and%20the%20Kafka%20plugin.

GoLand 2023.2 发布:有 AI 助手

Go语言中常见100问题-#41 substrings and memory leaks

OpenKruise 中 OpenKruiseGame介绍

📒 前端相关

curl 上手指南,前端开发必会

JavaScript 中隐秘而强大的 compose 和 pipe

一文吃透 React DSL 应用并从零到一实现

从 antDesign 来窥探移动端“滚动穿透”行为

· 4 min read
加菲猫

🌟 AI 相关

基于 Docker 的深度学习环境:Windows 篇

使用 Docker 快速上手 Stability AI 的 SDXL 1.0 正式版

Colab 在线运行 llama-2:

https://github.com/camenduru/text-generation-webui-colab

OpenAI Code Interpreter 的开源实现:GPT Code UI

构建能够使用 CPU 运行的 MetaAI LLaMA2 中文大模型

⭐️ Golang 相关

5000字,10张图,完全掌握 MySQL 事务隔离级别

服务架构:分层架构

本地开发如何用 Dev Container,前端工程配置参考:

version: '3'
services:
node-app:
image: node:18-alpine
ports:
- "3000:3000"
environment:
- NODE_ENV=development
volumes:
# 表示将当前工作目录挂载到容器内的 `/app` 目录
- .:/app
# 当容器被重新启动时,`node_modules` 目录不会被重新构建,从而加快了容器的启动速度。
- node_modules:/app/node_modules
working_dir: /app
command: pnpm run dev
# 将 Docker 容器内的 `/node_modules` 目录挂载到卷上
# 在容器重新启动时,该目录中的依赖项不会被重新构建,从而加快容器的启动速度
volumes:
node_modules:

然后运行下面命令启动容器:

$ docker-compose up

Golang 工程配置参考:

version: '3'
services:
go-app:
image: golang:latest
ports:
- "8080:8080"
environment:
- GOPATH=/go
- PATH=$GOPATH/bin:/usr/local/go/bin:$PATH
volumes:
- .:/go/src/app
working_dir: /go/src/app
command: go run main.go

go channel应用系列二:协程间信息同步

超越 MyBatis-Plus?来领略一下 MyBatis-Flex 的优雅魅力!

WebStorm 2023.2 正式发布

Go可用性(七) 总结: 一张图串联可用性知识点

Go 工程化(十) 如何在整洁架构中使用事务

Go 工程化(十一) 如何优雅的写出 repo 层代码

一个小技巧,如何用 openssl 生成密码:

$ openssl rand -base64 [password length]

全面解读!Golang中泛型的使用

Go 1.19 中的原子指针

服务治理到底治什么,10张图告诉你答案

Go 语言的安全守护者:你用了吗

关于Dockerfile的最佳实践技巧

[Go开源工具] go-optioner:轻松生成函数选项模式代码

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

白皮书:事件 OnCall 中心建设方法

微服务中的熔断算法

Nacos 配置管理最佳实践

「必知必会」 Nacos 的面试题和详解

谈谈Kubernetes的存储设计理念

Go语言爱好者周刊:第 196 期

📒 前端相关

用Rust生成Ant-Design Table Columns | 京东云技术团队

前端简洁架构

How React 18 Improves Application Performance

· 5 min read
加菲猫

🌟 AI 相关

使用 Transformers 量化 Meta AI LLaMA2 中文版大模型

刷屏的Llama 2性能究竟如何

Fine-tuning Stable Diffusion Models on Intel CPUs

Deploy LLMs with Hugging Face Inference Endpoints

使用 Docker 快速上手中文版 LLaMA2 开源大模型

使用 Docker 快速上手官方版 LLaMA2 开源大模型

Stable Diffusion 腾讯云云原生容器部署实践

一键安装!机器学习和大模型联手了!

⭐️ Golang 相关

Go语言开发者的Apache Arrow使用指南:扩展compute包

服务架构:微服务架构

OpenTelemetry:将跟踪从 Ingress-Nginx 发送到多租户 Grafana Tempo

Rust vs Go:常用语法对比(一)

抽丝剥茧,记一次 Go 程序性能优化之旅

漏桶算法和令牌桶算法

Russ Cox 的个人博客

https://research.swtch.com/coro

美团面试:为什么MySQL不建议使用NULL作为列默认值

深度好文:如何发现及处理 MySQL 主从延迟问题

Go的这个库,让你的命令行输出变得专业

「Go开源包」snappy:google开源的快速、无损压缩包

一文吃透 Go 语言解密之上下文 context

为什么 Go map 和 slice 是非线性安全的

高阶函数编程:探索Go语言中的函数一等公民

线程安全是指在多线程环境下,程序的执行能够正确地处理多个线程并发访问共享数据的情况,保证程序的正确性和可靠性。

能被称之为:线程安全,需要在多个线程同时访问共享数据时,满足如下几个条件:

  • 不会出现数据竞争(data race):多个线程同时对同一数据进行读写操作,导致数据不一致或未定义的行为。
  • 不会出现死锁(deadlock):多个线程互相等待对方释放资源而无法继续执行的情况。
  • 不会出现饥饿(starvation):某个线程因为资源分配不公而无法得到执行的情况。

Go 面试题:string 是线程安全的吗

「Go开源包」xxhash:比标准库更快,基于xxHash算法实现的64位的整型hash值

Go:使用Cobra打造强大命令行应用

开源的Datadog?可观测性平台SigNoz是否名副其实

听GPT 讲K8s源代码--pkg(四)

Traefik v3.0 Docker 全面使用指南:基础篇

答网友问:golang中的slice作为函数参数时是值传递还是引用传递

写给开发者的gRPC教程-服务发现与负载均衡

jsonparser 为什么比 encoding/json 快 10 倍

Go slice扩容N连问

听GPT 讲K8s源代码--pkg(三)

什么是布谷鸟过滤器?它与布隆过滤器有何不同

「Go开源包」env:一个将系统环境变量解析到结构体的库

配图清新的Protobuf 编码&避坑指南

Go语言爱好者周刊:第 195 期 —— Go 终极教程

📒 前端相关

【第3005期】前端简洁架构

架构师对于 Vue 响应式编程的思路梳理,从 RxJS 身上学到这么多

Chrome 115 有哪些值得关注的新特性

前端文件流、切片下载和上传:优化文件传输效率与用户体验

· 4 min read
加菲猫

⭐️ 服务架构:大数据架构

⭐️ 使用testify包辅助Go测试指南

⭐️ 另一种视角:我为什么放弃 Go 语言

⭐️ Go进阶面试题详解 | 文末送书

⭐️ HTTP Router 算法演进

⭐️ Go语言开发者的Apache Arrow使用指南:数据操作

📒 一个新的React概念:Effect Event

📒 干货 | 携程商旅大前端 React Streaming 的探索之路

⭐️ go channel应用系列之控制协程数量

⭐️ 24 张图搞定 ICMP :最常用的网络命令 ping 和 tracert

📒 “Rust难学”只是一个谎言

⭐️ Go实战:开发一个简单的gRPC Demo

⭐️ 你用过 httpguts 包吗?通过 Go 1.20.6 和 Go 1.19.11 安全更新即可了解

⭐️ 微服务最重要的10个设计模式

⭐️ Docker 制作容器镜像的时候, 一定不能 All in One 吗

⭐️ Go defer 去掉闭包函数,靠谱吗

⭐️ 布谷鸟过滤器

⭐️ Go 语言泛型

# 跟着 Go 作者学泛型

# Go 泛型入门教程

# Go泛型系列:maps 包讲解

# Go 1.18 中的 any 是什么

# Go泛型系列:slices 包讲解

# Go泛型系列:Go1.18 类型约束那些事

⭐️ 泛型版 singleflight

singleflight.Group 是一个结构体类型,没有导出任何字段,它代表一类工作并形成一个命名空间,在该命名空间中可以抑制工作单元的重复执行。

该类型有三个方法,它们的功能见注释:

// 执行并返回给定函数的结果,确保对于给定的键,fn 函数只会执行一次。
// 如果有重复的进来,重复的调用者会等待最原始的调用完成并收到相同的结果。
// 返回值 shared 指示是否将 v 提供给多个调用者。
// 返回值 v 是 fn 的执行结果
// 返回值 err 是 fn 返回的 err
func (g *Group) Do(key string, fn func() (interface{}, error)) (v interface{}, err error, shared bool)
// 和 Do 类似,但返回一个 channel(只能接收),用来接收结果。Result 是一个结构体,有三个字段,即 Do 返回的那三个。
func (g *Group) DoChan(key string, fn func() (interface{}, error)) <-chan Result
func (g *Group) Forget(key string)

泛型版 singleflight:Go 中如何防止缓存击穿

⭐️ Gin 框架 Bind 函数如何实现参数绑定

gin 源码阅读(4) - 友好的请求参数处理

「Go 框架」bind 函数:gin 框架中是如何绑定请求数据的

📒 nginx反向代理https域名时,请求报错502问题排查

📒 【第2994期】如意设计助手:Figma Dev Mode下生成React代码

⭐️ Google SRE 创始人讲解 SRE 方法论

⭐️ Docker 多架构镜像介绍和最佳实践

⭐️ 基于Redis实现一个简单的固定窗口限流器

⭐️ Go语言爱好者周刊:第 194 期 — 开销从20%下降到不到1%

· 9 min read
加菲猫

⭐️ Google 工作 10+ 年的感悟,有看到 Go 核心团队的影子吗

⭐️ 万字长文说透分布式锁

⭐️ 服务架构简介

⭐️ 使用 Linux 网络虚拟化技术探究容器网络原理

⭐️ Go语言开发者的Apache Arrow使用指南:高级数据结构

⭐️ 字节跳动开源 Go HTTP 框架 Hertz 设计实践

字节跳动开源 Go HTTP 框架 Hertz 设计实践

「字节开源」基于Hertz和Kitex的Go微服务开源项目 | 文末福利

📒 【第2991期】从自研走向开源的 TinyVue 组件库

⭐️ 我如何用两行代码节省了30%的CPU

📒 第二次重写个人网站,分享一些感想

⭐️ fastcache 高性能设计与实现

📒 找不到好用的 gRPC 调试工具?Apifox 表示我可以!

⭐️ 一句话搞定数据分析,浙大全新大模型数据助手,连搜集都省了

📒 干货 | 瘦身50%-70%,携程 Taro 小程序样式 Size 缩减方案

📒 【第2990】如意设计助手× TDesign:产品设计的绝佳搭档

📒 如何方便的检测React项目的性能

⭐️ Go 团队将修改 for 循环变量的语义,Go1.21 新版本即可体验!

⭐️ 如何基于 IDL 生成 Go 项目模板

https://dev.to/justlorain/high-performance-go-http-framework-tasting-25li

https://www.cloudwego.io/docs/hertz/tutorials/toolkit/usage/usage-thrift/

⭐️ nginx 配置 HTTP/2

# Redirect HTTP to HTTPS
server {
listen 80;
listen [::]:80;
server_name www.example.com;
return 301 https://$host$request_uri;
}

server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.example.com;

ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;

# Specify SSL config if using a shared one.
#include conf.d/ssl/ssl.conf;

# Allow large attachments
client_max_body_size 128M;

location / {
proxy_pass http://127.0.0.1:10020;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}

location /notifications/hub {
proxy_pass http://127.0.0.1:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}

location /notifications/hub/negotiate {
proxy_pass http://127.0.0.1:10020;
}
}

⭐️ 不藏着了,构建并减少Docker镜像容量的优化技巧都分享给你们!

📒 团队把图标方案从iconfont换成iconify了,说说我们的思考

📒 前端食堂技术周刊第 89 期:ES 2023、MDN Playground、TS 5.2 Beta、逆向分析 GitHub Copilot

逆向分析 GitHub Copilot

  • 对于编辑器输入的边界判断,包括太少、太多、取消等等很多场景齐全的考虑;
  • 缓存思想,利用多级缓存策略保护后台,模型运算本身就是一件昂贵的事情;
  • prompt 的设计,不仅仅包含了上下文代码,在文件解析、编辑器打开的相关代码上还做了很多;
  • 利用简单的 Jaccard 算法计算分词后的文本相似度,能够快速决策出当前上下文相关的 snippet;
  • 实验特性,在 Copilot 中,大量的参数、优先级、设置字段都是通过实验来控制的,有一套完整的监控上报体系,帮助 Copilot 去调整这些参数,以达到更好的效果。

字节跳动的前端工程化实践

  • 自研 Monorepo 工具,用于降低多项目的维护成本;
  • 对原有的微前端框架进行升级,进一步降低多人开发的协作成本;
  • 开发 Bundler 和 Build System,来加快巨型应用的构建速度;
  • 提供诊断工具,来有效地防止应用劣化。

前端食堂技术周刊第 89 期:ES 2023、MDN Playground、TS 5.2 Beta、逆向分析 Copilot

📒 不用 React 框架,同事就要打架!

⭐️ Go中这么多创建error的方式,你真的了解它们各自的应用场景吗

⭐️ ants Code Reading

⭐️ How to Deploy Cross-Platform Rust Binaries with GitHub Actions

⭐️ Go 语言 Context 用法

3W 解析 Golang Context:用法、源码

Go组件:context学习笔记!

Go 语言 context 都能做什么

Go Context 怎么用,原理是啥,看完这篇就清晰了

⭐️ 分享6个Linux必备的安全设置,建议收藏!

📒 企业级 React API 调用架构设计

⭐️ Go 语言使用 XORM 操作 MySQL 的陷阱

⭐️ C++/Go 调用约定的原理

⭐️ Go 语言 iota 的神奇力量

📒 相关文章汇总

聊聊 Redux 的下一个计划 — 这位 React YouTuber 之王暂时离开他通常的屏幕演示形式,与 Redux 维护者 Mark Erikson 坐下来讨论 Redux 和 Redux Toolkit 的当前状态和未来状态,两者都离重大新版本不远了。

https://www.youtube.com/watch?v=n5FK8_EXcbs

在 Next.js 13 中为服务器组件配置使用基于 cookie 的身份验证 — 这篇教程非常有意义,尤其是对 Supabase Auth 用户来说。

https://www.youtube.com/watch?v=ywvXGW6P4Gs

你知道 React 可以 在渲染过程中更新状态 吗?Markd Erikson 提供了关于此的 更多信息。

https://swizec.com/blog/react-can-update-state-during-render/

HouseForm:简单易用的基于字段的 React 表单验证 — 基于 Zod 构建,适用于任何支持 React 的环境。相比于类似的解决方案,HouseForm 验证速度更快。

https://houseform.dev/

shadcn/ui:可复制粘贴的 Tailwind CSS 组件 — 如果你经常使用 Tailwind CSS,这些组件将非常适合你。正如创建者所说:“这不是一个组件库。它是一系列可以复制粘贴到你的应用程序中的可重用组件。”

https://ui.shadcn.com/

TypeScript v5.2 现已进入 beta 阶段

https://devblogs.microsoft.com/typescript/announcing-typescript-5-2-beta/

CommonJS 正在损伤 JavaScript —— 这是关于 Node 默认模块系统的有趣观点,文章涵盖了它的历史、缺点以及同时管理 CommonJS 和 ES 模块的复杂性。毫不奇怪,Andy 希望我们尽快加入 ESM 阵营,而将 CommonJS 留在历史中。

https://deno.com/blog/commonjs-is-hurting-javascript

npm 生态系统的一个严重 Bug —— 作者曾在 npm CLI 团队工作,认为这是一个大问题。我们不在此剧透太多,但简言之,包映射表和实际的包内容可能不匹配,这可以被人利用,甚至可能会混淆审计工具。

https://blog.vlt.sh/blog/the-massive-hole-in-the-npm-ecosystem

Next.js 应用路由更新— Next.js v13+ 中的 应用路由 为组织 Next.js 应用提供了一种新的方法,并推荐在未来的项目中使用(在上个月的 Next.js v13.4 中已经稳定)。这篇文章提供了关于该功能如何发展以及团队如何继续与 React 整体进行集成。

https://nextjs.org/blog/june-2023-update

从零开始实现 React Server Components: 视频版 — 最近,Dan Abramov 发布了一个关于 从零开始重新实现 React Server Components(RSC)教程。他在 Twitter 上询问是否有人可以用视频形式记录这篇文章,Jesse 则为其增添了 “戏剧性朗读” 的效果。

https://www.youtube.com/watch?v=8aD58kGBJYc

关于 Next.js 的 Image 组件的一些你可能不知道的事情 — Next.js 的 Image 组件具有许多有用的功能,你可能不知道。

https://dev.to/alex_barashkov/things-you-might-not-know-about-next-image-5go8

⭐️ Go语言爱好者周刊:第 193 期 —— Go1.21 RC 发布

· 6 min read
加菲猫

⭐️ 干货|携程Web组件在跨端场景的实践

📒 Chrome 震撼新特性:文档画中画!

📒 TypeScript 5.2 beta 发布:using 关键字、装饰器元数据、元组匿名与具名元素混用

⭐️ Go语言开发者的Apache Arrow使用指南:内存管理

⭐️ K8S面试题,有57道题,呕心沥血整理并附答案,赶紧收藏!

⭐️ 云原生监控--VictoriaMetrics 之基础篇

⭐️ Go1.21 速览:Context 可以设置取消原因和回调函数了,等的可太久了!

⭐️ Go 面试题:Go interface 的一个 “坑” 及原理分析

⭐️ Go 新关键字 any,interface{} 会成为历史吗

⭐️ 为什么 Go 里值为 nil 可以调用函数

📒 如何排查 Electron V8 引发的内存 OOM 问题

📒 ECMAScript 2023 正式发布,有哪些新特性

⭐️ 为什么 Linux “一切皆文件”

📒 32K star 的 Chakra UI,以及未来的展望

⭐️ 「Go开源包」chromedp:一个基于Chrome DevTools协议的库,支持数据采集、截取网页长图

⭐️ Go 1.21的PGO正式GA,性能提升,更快更猛!

⭐️ 我不允许你还没有这张《K8S容器云平台排错一览图》

⭐️ 精选Go高频面试题和答案汇总,阅读破万,收藏230+

📒 前端食堂技术周刊第 88 期:Svelte4、NestJS 10、State of CSS、Vitest 1.0 Roadmap

  • Svelte 4 主要是一个维护版本,为下一个版本做铺垫,包尺寸减少近 75%,依赖项从 61 个减少到 16 个,开发者体验提升。
  • State of React 2023 先行版 先不用着急回答,答了也没用。
  • Vitest 1.0 Roadmap Vitest 1.0 将和 Vite 5 同步发布,1.0 版本将放弃对 Vite 4 和 Vite 3 的支持,意味着将不再支持 Node.js 16。
  • Rspack v0.2.3 性能优化(依赖缓存、tree shaking)、内置 swc-loader 等。

TypeScript 5.2 前瞻:

前端食堂技术周刊第 88 期:Svelte4、NestJS 10、State of CSS、Vitest 1.0 Roadmap

⭐️ 「Go开源包」nunu:一个快速构建应用程序的脚手架

📒 Web Components 初探:我终于学会了如何在其他框架中使用 Vue 组件

⭐️ 敲黑板!鹅厂程序员面试也考了这些算法知识

📒 Go 语言类型转换的陷阱

⭐️ 精选8道ES高频面试题和答案,后悔没早点看

📒 ”渐进式页面渲染“:详解 React Streaming 过程

⭐️ 这些年在阿里学到的方法论

⭐️ Go 语言并发模式代码模板

⭐️ Go 并发编程 - 数据竞态

⭐️ Go 中线程安全 map 方案选型

⭐️ 保护数据隐私:深入探索Golang中的SM4加密解密算法

📒 2023 React 生态系统,以及我的一些吐槽

Redux Toolkit 还包括一个强大的数据获取和缓存功能,我们将其称为 "RTK Query"。它作为一个独立的入口点包含在软件包中。它是可选的,但可以消除手动编写数据获取逻辑的需求。

2023 React 生态系统,以及我的一些吐槽

⭐️ Go 泛型的二十一个陷阱

选自GopherChina 2023大会的分享《谈谈go泛型》。

https://github.com/smallnest/talk-about-go-generics

Go 泛型的二十一个陷阱

⭐️ Go语言中常见100问题-#38 Misusing trim functions

⭐️ Go1.21 RC2 发布了,没有 RC1

⭐️ Go语言开发者的Apache Arrow使用指南:数据类型

⭐️ 「有问必答」Gopher如何优雅的对时间进行格式化

⭐️ 相关文章汇总

AutoAnimate:通过一行代码为应用添加动画效果——可以在页面上查看一些漂亮的示例,并且这个库可以与 React、Vue、Svelte 或原生 JavaScript 一起使用。

https://auto-animate.formkit.com/

Toad Scheduler:内存中的 Node 和浏览器任务调度器——提供了比 setTimeout 或 setInterval 更多的结构,并支持类似 cron 的调度。

https://github.com/kibertoad/toad-scheduler

⭐️ Go语言爱好者周刊:第 192 期 —— 初始化大 map 的性能

初始化大 map 的性能

一个泛型的有序 Go Map 实现。Go 内建的 map类 型对于插入的元素并没有保持它们的插入顺序,遍历的时候也故意设置成随机的。因此,如果我们想让map保持元素的插入顺序,需要借助第三方的库才行,今天就给大家介绍一个这样的库 OrderedMap。

Go语言爱好者周刊:第 192 期 —— 初始化大 map 的性能

· 8 min read
加菲猫

⭐️ Go 语言日志库

Go 每日一库之 logrus

Awesome Logging in Go With Logrus

Zap Logger

一文告诉你如何用好uber开源的zap日志库

⭐️ Go Concurrency Patterns

Go 语言并发模式代码模板

https://go.dev/talks/2012/concurrency.slide#1

https://go.dev/talks/2013/advconc.slide#1

Go Concurrency Patterns: Context

Go Concurrency Patterns: Pipelines and cancellation

Go Concurrency Patterns: Timing out, moving on

https://go.dev/doc/effective_go#concurrency

⭐️ 泛型版 slice、map

Go1.21 速览:新内置函数 clear、min、max 和新标准库包 cmp!

Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库

⭐️ 手写K8S的YAML很痛苦,看完这篇让你信手拈来

⭐️ Go 项目分层下的最佳 error 处理方式

⭐️ Go 将引入标准库 v2 版本,首个动手的是:math/rand/v2!

⭐️ 瞬间高并发,goroutine执行结束后的资源占用问题

⭐️ Go语言中常见100问题-#37 Inaccurate string iteration

📒 超越所有开源模型,击败 Claude、Bard,专门用于编程任务的大模型来了

⭐️ 死锁、活锁、饥饿、自旋锁

⭐️ 一个悄然崛起的AI开源项目 !!

📒 前端食堂技术周刊第 87 期:2023 Stackoverflow、Bun v0.6.9、React 是否迎来了 Angular.js 时刻、Vercel AI

⭐️ Introducing the Vercel AI SDK

Vercel 推出了全新的工具来改善 AI 体验:

  • Vercel AI SDK:轻松地从 AI 模型中获取 API 响应;
  • Chat & Prompt Playground:探索来自 OpenAI、Hugging Face 等的模型;
  • AI Chatbot:使用 Next.js 构建的开源 AI 聊天应用模板。

Vercel AI SDK 是一个开源库,旨在帮助开发者在 JavaScript 和 TypeScript 中构建 AI 流式聊天应用。该 SDK 支持 React/Next.js、Svelte/SvelteKit,即将支持 Nuxt/Vue。

可以在终端中输入以下命令来安装此 SDK:

$ npm install ai

Vercel 的 AI SDK 支持互操作性,并为 OpenAI、LangChain 和 Hugging Face Inference 提供一流的支持。这意味着无论首选的 AI 模型提供商是哪个,都可以利用 Vercel AI SDK 创建前沿的流式 UI 体验。

import { OpenAIStream, StreamingTextResponse } from 'ai'
import { Configuration, OpenAIApi } from 'openai-edge'

// 创建一个 OpenAI API 客户端
const config = new Configuration({
apiKey: process.env.OPENAI_API_KEY
})
const openai = new OpenAIApi(config)

// 将运行时设置为 edge
export const runtime = 'edge'

export async function POST(req: Request) {
// 从请求正文中提取 messages
const { messages } = await req.json()

// 根据提示要求 OpenAI 完成流式聊天
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
stream: true,
messages
})
// 将响应转换为友好的文本流
const stream = OpenAIStream(response)
// 响应流
return new StreamingTextResponse(stream)
}

Vercel AI SDK 包括用于数据获取和渲染流式文本响应的 React 和 Svelte 钩子。这些钩子使得应用能够实时、动态地渲染数据,为用户提供沉浸式和交互式的体验。

现在,借助 useChatuseCompletion,构建丰富的聊天或完成接口只需要几行代码:

'use client'

import { useChat } from 'ai/react'

export default function Chat() {
const { messages, input, handleInputChange, handleSubmit } = useChat()

return (
<div>
{messages.map(m => (
<div key={m.id}>
{m.role}: {m.content}
</div>
))}

<form onSubmit={handleSubmit}>
<input
value={input}
placeholder="Say something..."
onChange={handleInputChange}
/>
</form>
</div>
)
}

参考:

https://vercel.com/blog/introducing-the-vercel-ai-sdk

📒 Vercel 推出 AI SDK、AI 应用模板,快速构建 AI 应用!

📒 芜湖,埋点还可以这么做?这也太简单了

⭐️ [代码附录] SIMD能力初体验

📒 【第2976期】前端构建工具的未来

⭐️ Go语言包设计指南

📒 相关文章汇总

Node.js 安全版本已发布 —— Node.js 16.x、18.x 和 20.x 系列都发布了新版本以修复各种中高危安全问题,也包括一些与 OpenSSL 相关的安全更新。如果你想尽快升级,请留意这篇文章。

https://nodejs.org/en/blog/vulnerability/june-2023-security-releases

2023 年可以在何处托管 Remix 应用

https://www.jacobparis.com/content/where-to-host-remix

Toad Scheduler:Node.js 内存和浏览器任务调度程序 —— 提供了比 setTimeout 或 setInterval 多一点的结构,也支持 cron 风格的调度。

https://github.com/kibertoad/toad-scheduler

openGraphScraper:Open Graph 和 Twitter Card 元数据抓取器 —— 很多网页都包含元数据,以帮助像 Facebook 和 Twitter 这样的社交网络创建更有吸引力的链接——这个库可以让你更容易挖掘这些信息。

https://github.com/jshemas/openGraphScraper

Chrome for Testing 是一个全新的官方 Chrome“版本”,专门针对 Web 测试和自动化用例。你已可以使用 Puppeteer。

https://developer.chrome.com/blog/chrome-for-testing/

在你的下一个前端 Pull Request 之前,请使用 Checklist —— 使用 Checklist 避免 Pull Request 中的常见错误,文章的内容涵盖了最小化包大小、确保可访问性、使用语义化标记,以及保持代码整洁等领域。

https://evilmartians.com/chronicles/before-your-next-frontend-pull-request-use-this-checklist

Million.js:以性能为重点的 React VDOM 替代方案 — 两年前 Million 诞生时是一个不依赖任何库的,轻量的虚拟 DOM 实现。最近,它又作为 React 性能提升的一种方式出现:「想象一下 React 组件能以原生 JavaScript 的速度运行。」不过,要想达到这个目标也需要做出一些妥协,官方的 快速入门文档 演示了 React 集成 Million 的示例。

https://million.dev/

为什么使用了 React 服务端组件,客户端组件仍然可以被 SSR 成 HTML? — 当理解服务器组件时不要恐慌,它并不会改变你原有对 React 工作原理的理解。你可以在心智模型上开辟一块新的空间来接纳这个知识点。为了避免混淆,请将概念分为 “React 服务器”和 “React 客户端”,而不是更容易混淆的“服务器”和“客户端”。这将有助于更好地理解 React 在不同环境下的工作方式。

https://github.com/reactwg/server-components/discussions/4

React Redux v8.1 已经发布,增加了针对常见错误的开发模式安全检查,以及修复了 React-Redux hook 被 React 服务器组件引用时的问题。

https://github.com/reduxjs/react-redux/releases/tag/v8.1.0

⭐️ Go语言爱好者周刊:第 191 期 —— 父亲节快乐

· 7 min read
加菲猫

📒 能输出网页的AI应用来了,赶紧测评下

⭐️ SIMD能力初体验

⭐️ 【第2973期】携程Web组件在跨端场景的实践

⭐️ sync.Pool 高性能设计之集大成者

⭐️ Go 1.21.0 带来了什么新特性?min 和 max 内置函数解析

⭐️ K8S资源限制实战:优化性能与资源管理

📒 如何优雅的使用 React Context

⭐️ 聊聊为什么 IDL 只能扩展字段而非修改

📒 【第2972期】Wukong 动态化组件能力实践

⭐️ Gin 框架是如何处理 panic 的

⭐️ 深入解析go channel各状态下的操作结果

📒 React Server Component 从理念到原理

⭐️ 一文实战K8S中的服务发现和负载均衡

⭐️ Go 语言 error 处理

Go error 处理最佳实践

# Go项目中,GRPC框架的error处理,我放在HTTP中1样的好用

⭐️ Go 语言 GC 相关

Go GC 使用三色标记法,在 GC 压力大时用户态 goroutine 是要 assit 协助标记对象的,每个业务goroutine都有机会参与到GC标记工作中来!并且,这种标记辅助采用的是一种补偿机制,即该业务goroutine分配的内存越多,它要辅助标记的内存就越多。

如何优化 GC 的开销:

  • 减少GC次数来间接减少STW次数,缺点是以整个程序的内存开销增大为代价的,稍有不慎可能就会触发OMM killed。
  • 减少堆内存的分配和释放。GC开销大的根源在于heap object多,Go的每轮GC都是FullGC,每轮都要将所有heap object标记(mark)一遍,即便大多数heap object都是长期alive的,因此,一个直观的降低GC开销的方法就是减少heap object的数量,即减少alloc。

Go GC:了解便利背后的开销

真实环境下大内存 Go 服务性能优化一例

⭐️ Go 内存管理概述

📒 或许,你根本不需要全局状态管理

📒 项目规范:让你的代码更上一层楼

📒 Vue和React权限控制的那些事

⭐️ Go fasthttp 相关文章

fasthttp 为什么比标准库快 10 倍

fasthttp:比net/http快十倍的Go框架(server 篇)

Go标准库http与fasthttp服务端性能比较

Golang fasthttp实践

⭐️ 「有问必答」Gopher如何优雅的对时间进行格式化

📒 揭秘 JavaScript 代码整洁技巧,让你的项目更出众

📒 技术派中ES集成的实现姿势

⭐️ Go1.21 速览:go.mod 的 Go 版本号将会约束 Go 程序构建,要特别注意了!

⭐️ 基于 Docker 的深度学习环境:入门篇

📒 网易云音乐大前端监控体系(Corona)建设实践-开篇

⭐️ Go 配置管理库 Viper 怎么读取结构体嵌套的配置信息

📒 如何基于 napi-rs 打造 Rust 前端工具链

📒 深入理解Render阶段Fiber树的初始化与更新

📒 虚拟滚动的3种实现方式~学完直接写简历亮点上!

📒 【第2969期】FormRender 2.0 开箱即用表单方案

⭐️ The State Of Go 2023

⭐️ Go协程池(1): 线程vs协程

📒 相关文章汇总

关于 Node 调试工具和方法的介绍 —— 这是一份信息丰富的初学者指南。文章从简单内容开始进行介绍,如使用 IDE 扩展程序突出潜在问题、使用控制台日志,再到使用 V8 检查器并通过 Chrome 进行调试。

https://blog.openreplay.com/an-introduction-to-debugging-in-nodejs/

Node v20.3.0(Current)发布 —— 此版本在升级 libuv(提供 Node 异步 I/O 功能的库)后带来了显著的 Linux 性能提升。此外,还引入了 AbortSignal.any(),并且开始正式认可 Ruy Adorno 在 Node.js TSC 中的地位。

https://nodejs.org/en/blog/release/v20.3.0

TypeScript v5.1 发布 — 这个版本开始支持 JSX 标记名称的链接编辑、namespace JSX 属性、具有无关类型的 getter 与 setter,以及不需显式返回 undefined 的函数。

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1/

Dan Abramov 深入讲解 React 服务器组件 — 面对关于服务器组件的一系列问题,Dan 决定写一系列文章,从零开始 重新实现 一个基本形式的 RSC。这并不针对日常的 React 开发者,而是面向那些想要理解 RSC 背后思想的人。

https://github.com/reactwg/server-components/discussions/5

2023 年的 React 生态 — 这是一个稍微有些杂乱无章的导览,介绍了当前流行的 React 生态系统工具和库的种类,混合了一些可靠的老面孔和一些新面孔。

https://www.builder.io/blog/react-js-in-2023

服务器组件是否真的将 React 变成了 PHP? — React YouTuber Jack 是那种看起来像标题党,但视频确实富有教育性和洞察力的稀有自媒体作者之一。如果你在权衡选择,这是一个很好的开发者体验的比较参考。

https://www.youtube.com/watch?v=hr_y1hIdZHs

Goxygen v0.4:快速为前端 JavaScript 项目生成 Go 语言的后端项目 — 这个工具可以创建一个前端基于 React、Angular 或 Vue,后端基于 Go(lang) 的新项目,再结合 Docker 和 Docker Compose 文件,形成一个完整可运行的项目。

https://github.com/Shpota/goxygen

⭐️ Go语言爱好者周刊:第 190 期 —— GopherChina 2023 PPT 下载

· 5 min read
加菲猫

📒 13条咒语挖掘GPT-4最大潜力,Github万星AI导师火了,网友:隔行再也不隔山了

⭐️ GORM 相关文章

第二期Go开源说实录:GORM 剖析与最佳实践

golang orm 框架之 gorm

gorm常用使用

GORM 强大的代码生成工具 —— gorm/gen

📒 网易云音乐开源的云原生应用部署平台 - Horizon

⭐️ 借助ChatGPT快速上手ElasticSearch dsl

⭐️ 通过源码剖析Go的map扩容底层实现

📒 一个好的技术头狼是怎样的

📒 鹅厂程序员的9个生存法则

⭐️ Go 1.20.5 发布有关 SUID 和 cgo 的安全修复更新

📒 【第2966期】云音乐低代码 + ChatGPT 实践方案与思考

⭐️ 收藏!!!一图掌握 Go 中 IO 包的关系

📒 现有React架构无法解决的问题

📒 完美搭配,微前端与Monorepo的架构设计

📒 原来懒加载有这些玩法,你确定不看看

⭐️ Go 函数选项模式(Functional Options Pattern)

📒 手把手教你实现一个常用的 antd form 组件

⭐️ 一图胜千言,帮你搞懂Go面试中常问的channel问题!

⭐️ Go1.21 速览:新内置函数 clear、min、max 和新标准库包 cmp!

⭐️ 「Go开源包」requests:一个比net/http包更简洁、高效的开源包

⭐️ OKR之剑·实战篇05:OKR致胜法宝-氛围&业绩双轮驱动(上)

⭐️ 探究|Go JSON 三方包哪家强

⭐️ 超全避坑指南: 盘点 Go 的常见典型错误

⭐️ Go1.21.0 新特性:不需要循环 delete map 元素了

⭐️ 相关文章汇总

AI 加持的代码编写实战:快速实现 Nginx 配置格式化工具

使用 Docker 和 Alpaca LoRA 对 LLaMA 65B 大模型进行 Fine-Tune

基于 Docker 的深度学习环境:入门篇

模型杂谈:使用 IN8 量化推理运行 Meta “开源泄露”的大模型(LLaMA)

模型杂谈:快速上手元宇宙大厂 Meta “开源泄露”的大模型(LLaMA)

RSS Can:借助 V8 让 Golang 应用具备动态化能力(二)

在搭载 M1 及 M2 芯片 MacBook设备上玩 Stable Diffusion 模型

Linux 软件包下载加速工具:APT Proxy

轻量高可用的 K8s 集群搭建方案:MicroK8s

向量数据库入坑:使用 Docker 和 Milvus 快速构建本地轻量图片搜索引擎

向量数据库入坑:入门向量数据库 Milvus 的 Docker 工具镜像

向量数据库入坑:传统文本检索方式的降维打击,使用 Faiss 实现向量语义检索

⭐️ 【GoCN酷Go推荐】Html解析利器-goquery库

⭐️ 「GoCN酷Go推荐」高性能中文分词库 gojieba

📒 【第2962期】WebGL在次元秀的实践

📒 【面试高频题】难度 2.5/5,转换「最长公共子序列」问题

📒 一文搞懂业务架构、应用架构、数据架构

📒 页面一打开就有30个重复请求,我要怎么优化

📒 我放弃 antd 的理由

⭐️ Go语言中JSON处理技巧总结

⭐️ Go语言中常见100问题-#36 Not understanding the concept of a rune

⭐️ 合订本|用Go语言实现23种设计模式及学习重点

⭐️ Go语言爱好者周刊:第 189 期 —— Go 新的版本命名规则

- - + + \ No newline at end of file diff --git a/2023/page/4/index.html b/2023/page/4/index.html index 0a8e43e376..f5a35cb590 100644 --- a/2023/page/4/index.html +++ b/2023/page/4/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 15 min read
加菲猫

⭐️ Go语言反射编程指南

⭐️ Go 1.21 确认添加 cmp 包以及 min, max built-in 函数

📒 TypeScript 5.1 正式发布!

⭐️ 识别「ChatGPT造假」,效果超越OpenAI:北大、华为的AI生成检测器来了

⭐️ 给面试官一点小小的 gpt 震撼

⭐️ 非广告| DDD 到底是银弹还是垃圾

⭐️ 开通个人博客啦!附带全部 Hexo + Nginx + Git 教程

⭐️ Go error 处理最佳实践

⭐️ 为什么泛型使你的程序变慢

📒 使用require.context实现优雅的预加载!

⭐️ 聊聊 rust trait

⭐️ Go 编译器优化

⭐️ 从Go源码到可执行文件的编译过程详解

⭐️ 为什么取消了Go1.21,而采用了Go1.21.0的版本命名规则

⭐️ Ranking and Tuning: 解锁预训练模型库的新范式

⭐️ Golang中的25个常见错误:更好地进行go编程的综合指南

⭐️ 颠覆微服务架构?谷歌最新开源service weaver初体验

📒 连尤大都要借鉴的开源项目也会有一些迷惑行为

⭐️ Go1.21 速览:骚操作 panic(nil) 将成为历史!以后别这么干了

⭐️ Go channel FAQ

📒 form元素是React的未来

⭐️ 不要写 clean code, 要写 CRISP code

⭐️ channel 的 15 条规则和底层实现

⭐️ Go netpoll (下篇)- 数据接收发送和关闭

📒 【第2956期】如何编写一个友好支持 Tree-shaking 的库

⭐️ Go 高性能 - singleflight 防止缓存击穿

⭐️ 阅读破10万的学Go建议,不管初学还是进阶Go都值得一看!

⭐️ 深入浅出Go调度器中的GMP模型

⭐️ Go netpoll (上篇)- 数据结构和初始化

📒 ​未来全栈框架会卷的方向

⭐️ 抽丝剥茧,记一次 Go 程序性能优化之旅

📒 原生 popover 终于要来了!

📒 INP 即将代替 FID 成为新的核心 Web 指标

📒 相关文章推荐

《DeviceScript:专为微型设备设计的 TypeScript》。DeviceScript 是微软新推出的一种语言,旨在将 TypeScript 的编程体验应用到低资源的微控制器设备中。它被编译为一种自定义的虚拟机字节码,可以在这样的受限环境中运行(类似于 Go 的 TinyGo)。虽然主要面向 VS Code 用户,但也提供了 命令行选项。

《Deno v1.34:现在 deno compile 也支持 npm 包》。Deno 1.34版本主要增强了与npm和Node.js的兼容性,提高了开发者体验,并为未来的性能优化奠定了基础。此次更新最重要的功能包括:deno compile支持npm包、在deno.json和CLI标志中支持Glob以及TLS证书与IP地址。除此之外,还有许多其他改进和错误修复值得一提。其中,deno compile是本次更新中最受期待的功能之一,它使开发人员可以将项目编译成单个可执行文件,并且现在也支持使用npm包进行编译。同时,在配置文件方面也有所改进,例如新增排除所有子命令下某些文件或文件夹等功能。Deno 1.34还升级了V8至11.5版以及TypeScript至5.0.4版等内容。

《TC39 第 96 次会议的一些更新》。这篇文章介绍了2023年5月16日至18日举行的第96次TC39会议,讨论了几个JavaScript/ECMAScript的特性提案。这些包括Atomics.waitAsync、带有set符号和字符串属性的RegExp v标志、格式良好的Unicode字符串、装饰器元数据(扩展装饰器提案)、TypedArrays/DataView/Math.f16round上的Float16Array、Uint8Array:ArrayBuffer到/from Base64 的Base64编码解码,Promise.withResolvers(创建具有reject/resolve/promise函数作为方法的Promise),时区规范化(在Temporal基础上堆叠的提案)以及Intl.ZonedDateTimeFormat(用于Temporal.ZonedDateTime的Intl格式)。

《Web Components 简介》。这篇文章介绍了如何使用Web Component实现选项卡面板。首先,需要创建一个扩展HTMLElement的类,并将其注册为自定义元素。然后,在connectedCallback生命周期方法中,可以读取提供的子元素并生成UI以显示它们作为选项卡。还介绍了启用阴影DOM来提供范围化的CSS样式和激活标签状态等其他功能。最后,通过添加样式完成了选项卡组件的设计。

《比较三种非破坏性处理数组的方法》。有这篇文章介绍了三种处理数组的方法:for-of 循环、reduce() 和 flatMap()。作者通过实现一些功能来演示这三个特性,包括过滤输入数组以生成输出数组、将每个输入数组元素映射到一个输出数组元素、将每个输入数组元素扩展为零或多个输出数组元素等。对于每种方法,作者都提供了相应的代码示例,并讨论了它们的优缺点以及何时使用它们。总体而言,for-of循环是最通用的工具,而.reduce()适合计算汇总信息(例如所有元素之和),flatMap()则擅长于筛选-映射和将输入元素扩展为零或多个输出元素。

《我是如何将我的 Angular 应用转换为独立组件模式的》。这篇文章介绍了如何使用Angular的独立组件方法来避免使用ngModules。作者解释了独立组件的概念,它可以通过删除不必要的导入来大幅简化应用程序并减小包大小。在示例代码中,作者展示了如何在没有任何模块声明的情况下创建一个组件,并讨论了其优点和缺点。此外,作者还提供了一些工具和技巧,例如Bit开源工具链等,以帮助管理和共享这些独立组件。最后,作者演示了如何将现有项目从ngModule迁移到独立组件方法,并提供相应的代码示例进行说明。

《理解 React 并发》。这篇文章介绍了React v18.0中引入的一项新特性:并发模式。它的基本原则是重新设计渲染过程,使得在渲染下一个视图时,当前视图仍然保持响应性。为此,React团队提出了Concurrent Mode这个概念,并将其实现为可中断工作单元。具体来说,在组件渲染过程中使用requestIdleCallback()函数来实现并发模式。但由于向后兼容问题,Concurrent Mode计划未能实现。因此React团队转而推出了Concurrent Features这个方案,并引入了两个新钩子useTransition和useDeferredValue以支持并发渲染。其中useTransition返回一个布尔标志isPending和一个startTransition函数;而useDeferredValue则用于处理父组件传递给子组件的值更新等情况。需要注意的是,虽然这些钩子可以优化应用程序性能并提高用户体验,但它们也有自己的限制和缺点。如果想要深入理解如何使用React Concurrency,请参考官方文档及相关资源进行学习和掌握。

《你可能不需要 React Query》。这篇文章讨论了React Query在React Server Components出现后是否还有存在的必要性。作者认为,如果数据获取只发生在服务器端,那么使用React Query就没有必要了。但是,在过渡期间,可以将一些组件移动到仅在服务器上获取数据或使用Server Components预取缓存并将结果传递给客户端组件。此外,对于某些情况(例如无限滚动列表、离线应用程序等),结合React Query和Server Components可能会更好地解决问题。总之,作者认为不需要立即全部转移到Server Components,并且React Query仍然有其存在的价值和用途。

《Storybook Day 的 3D 动画是如何实现的》。这篇文章介绍了团队如何使用React Three Fiber(R3F)构建一个视觉上令人惊叹的三维动画,以Storybook的俄罗斯方块品牌为灵感创作出一个引人注目的三维插图。文章涵盖了创建场景时使用的几种技术,包括通过球体堆积避免对象重叠、使用挤压几何模型化俄罗斯方块、利用深度和阴影等效果增强视觉效果、通过减少材质数量和使用材质存储库进行性能优化等。该团队使用NextJS和@react-three/fiber构建活动网站。他们采用pack-sphere库来平均分配方块并防止任何潜在重叠问题。为解决“7.0”文本与方块之间的重叠问题,他们稍微沿z轴移动球体而不是检测球体与文本几何之间的碰撞。他们还利用Three.js中提供的ExtrudeGeometry对类似SVG路径或CSS形状这样的2D形状进行挤压,并将其沿着z轴拉伸成3D物体。为了增加一些特效,他们添加了阴影和景深效果,使其具有更多电影般感觉,并通过Material Store技术降低需要渲染材质数量从而提高性能。总之,这是一个非常好的指南,适合任何想学习如何在React Three Fiber(R3F)中构建视觉上令人惊叹的三维动画。

《如何开发一个自定义的 debounce Hook》。本文介绍了如何使用React创建自定义防抖钩子。在前端Web应用程序中,常见的功能之一是为输入添加防抖。 防抖可以让我们在输入值更改后延迟执行操作。 本文将演示如何使用React创建自定义防抖钩子。首先,我们需要了解什么是自定义Hooks以及它们的作用。 自定义Hook只是一个纯函数,它使用其他Hook来实现特定目标,并且不会产生任何副作用。接下来,文章介绍了如何通过useState和useEffect Hook创建一个名为useFetch的自定义Hook,该Hook可获取数据并返回数据和加载状态。然后文章进一步说明了如何通过useState、useEffect和useRef Hook创建名为useDebounce的自定义钩子,并演示了如何在组件中使用该钩子以实现对输入进行防抖处理。总之,本文提供了有关如何构建具有高度重复利用性能力的React Hooks(包括获取数据、防抖等)的详细指南。

《 JavaScript 安全: 最佳实践和提示》。在一个网络威胁日益复杂的时代,理解如何编写安全的 JavaScript 代码比以往任何时候都更加重要。在这篇文章中,Alex Ivanovs 解释了常见的 JavaScript 漏洞,从跨网站脚本(XSS)和跨站请求伪造(CSRF)到更复杂的问题,比如原型污染和不安全的依赖。

《Node.js 性能状况 2023》。今年是2023年,我们已经发布了 Node.js v20.0。本文对不同版本的 node.js 的性能进行了比较分析。它强调了这些改进和改进,并提供了对这些更改背后原因的深入了解,而没有与其他 JavaScript 运行时进行比较。基准测试结果包含一个可重复的示例和硬件细节。使用了 AWS 专用主机。

⭐️ Go语言爱好者周刊:第 188 期 —— Go 适合开发操作系统吗

· 20 min read
加菲猫

image

题图:王国之泪。

📒 支付系统就该这么设计,稳的一批!!

⭐️ 聊聊Go语言的控制语句

⭐️ 不背锅运维:Go语言切片内存优化技巧和实战案例

⭐️ Go:4个场景就可以让你知道Goroutine和通道是怎么用的

⭐️ 「Go开源包」asynq:一个基于redis的,简单、可靠、高效的分布式任务队列包

⭐️ goroutine 泄漏与检测

📒 字节都在用的代码自动生成

📒 Hook 革命!浅谈 React 新 Hook 的未来与思想

⭐️ Go Sync 包:并发的 6 个关键概念

📒 Bun发布全新Bundler:比Webpack快220倍

Bun发布全新Bundler:比Webpack快220倍

https://bun.sh/blog/bun-bundler

⭐️ 大大大模型部署方案抛砖引玉

📒 ChatGPT和Claude 对比测试(以Review MLIR Codegen代码为例)更新官方ChatGPT的结果

⭐️ Everything App: HuggingFace Transformers Agent

📒 【第2950期】vite-plugin-vue-devtools:写一个Vue DevTools,让开发体验飞一会

⭐️ Go timer Code Review

📒 H5加载性能优化

对于大部分用户而言,我们根本不需要把代码编译到 ES5,不仅体积大,而且运行速度慢。我们需要做的,就是把代码编译到 ES2015+,然后为少数使用老旧浏览器的用户保留一个 ES5 标准的备胎即可。

具体的解决方法就是 <script type="module"> 标签。

支持 <script type="module"> 的浏览器,必然支持下面的特性:

  • async/await
  • Promise
  • Class
  • 箭头函数、Map/Set、fetch 等等...

而不支持 <script type="module"> 的老旧浏览器,会因为无法识别这个标签,而不去加载 ES2015+ 的代码。另外老旧的浏览器同样无法识别 nomodule 熟悉,会自动忽略它,从而加载 ES5 标准的代码。

image

# React 16 加载性能优化指南

# 让老板虎躯一震的前端技术,KPI杀手

📒 tcmalloc 解内存分配问题

https://github.com/AUTOMATIC1111/stable-diffusion-webui/discussions/6722

# 深入Golang内存管理(一) TCMalloc篇

# Go内存管理之TCMalloc

# TCMalloc : Thread-Caching Malloc

# Go 内存管理(二): TCMalloc分配算法

⭐️ XML 处理,Go 标准库太简单了怎么办

📒 我用ChatGPT,给RabbitMQ加了个连接池

📒 React组件封装实践:如何拆解复杂的页面

📒 现代 Web 应用 Devtools 调试技巧

📒 在服务端写 React 组件是什么体验

⭐️ Go 空结构体:零内存的魔力

📒 这个线上BUG,让你彻底搞懂了MySQL的字符集,别问我咋知道的

⭐️ LLaMA 模型调研

当前 HuggingFace 已经实现了 LLaMA 模型 代码,可通过以下方式直接调用:

from transformers import LlamaForCausalLM
model = LlamaForCausalLM.from_pretrained(
base_model,
load_in_8bit=load_8bit,
torch_dtype=torch.float16,
device_map="auto",
)
if not load_8bit:
model.half() # seems to fix bugs for some users.
model.eval()

https://github.com/pengxiao-song/LaWGPT

https://github.com/pengxiao-song/LaWGPT/blob/f329433cad833a44c2cd14c5165a1655cf9d68ad/src/generate.py#L7

https://huggingface.co/docs/transformers/main/model_doc/llama

NLP(九):LLaMA, Alpaca, ColossalChat 系列模型研究

使用 Google Colab 训练 Stable Diffusion LoRA 模型教程

https://colab.research.google.com/#scrollTo=-Rh3-Vt9Nev9

⭐️ 「Go 框架」深入理解 gin 框中 Context 的 Request 和 Writer 对象

⭐️ Go1.22 可能会解决循环变量的坑,真好!!

📒 SpringBoot + 规则引擎 URule,太强了!

📒 2023 年你还在兼容旧版浏览器吗

📒 mysql的varchar字段最大长度真的是65535吗

在 mysql 建表 sql 里,我们经常会有定义字符串类型的需求。mysql 里有两个类型比较适合这个场景:charvarchar

声明它们都需要在字段边上加个数组,比如 char(100)varchar(100),这个 100 是指当前字段能放的最大字符数。

charvarchar 的区别在于,varchar 虽然声明了最大能放 100 个字符,但一开始不需要分配 100 个字符的空间,可以根据需要慢慢增加空间。而 char 一开始声明是多少,就固定预留多少空间。

所以,varchar比起char更省空间,一般没啥大事,大家都爱用varchar。

mysql的varchar字段最大长度真的是65535吗

⭐️ Go 细节篇-内存回收又踩坑了

📒 【第2948期】得物前端巡检平台的建设和应用:建设篇

⭐️ Go设计模式--中介者,最后的模式!

⭐️ channel 的 15 条规则和底层实现

操作规则

操作nil已关闭的 channel未关闭有缓冲区的 channel未关闭无缓冲区的 channel
关闭panicpanic成功关闭,然后可以读取缓冲区的值,读取完之后,继续读取到的是 channel 类型的默认值成功关闭,之后读取到的是 channel 类型的默认值
接收阻塞不阻塞,读取到的是 channel 类型的默认值不阻塞,正常读取值阻塞
发送阻塞panic不阻塞,正常写入值阻塞

编译规则

操作
接收只写 channel编译错误
发送只读 channel编译错误
关闭只读 channel编译错误

channel 的 15 条规则和底层实现

📒 三分钟,教你3种前端埋点方式!

📒 MDH 前端周刊第 100 期:React Query、演讲、Reactivity、Bun Bundler、Rome、infer

《你可能不需要 React Query》。这篇文章讨论了 React Server Components 是否会取代 React Query。作者认为,每个工具都应该帮助我们解决我们遇到的问题。传统上,React 在数据获取方面并不强调如何处理,这就是 React Query 和 swr 等库产生的原因。随着服务端渲染的出现,React Query 也扮演了重要的角色。但是,随着 React Server Components 的出现,如果您的数据获取仅发生在服务器上,那么您可能不需要 React Query。最后,作者提醒读者,不要盲目追随新技术,一切都有权衡。

https://tkdodo.eu/blog/you-might-not-need-react-query

《Nuxt 发布 3.5》。Nuxt 3.5.0 发布了,带来了许多令人兴奋的功能,特别是在类型支持方面。此外还有 Nitropack v2.4 和丰富的 JSON 负载等更新。Nuxt 3.5.0 还支持交互式服务器组件、环境配置、完全类型化页面和 “捆绑器” 模块解析等功能。

https://nuxt.com/blog/v3-5

《发布 TypeScript 5.1 RC》。TypeScript 5.1 已经作为候选版本发布,除了关键的错误修复外,预计在稳定版发布前不会有进一步的变化。新版本包括更容易的未定义返回函数的隐式返回,getters 和 setters 的不相关类型, JJSX 元素和 JJSX 标签类型之间的解耦类型检查,命名的 JJSX 属性,以及其他。TypeScript 5.1 还支持 JJSX 标签的链接光标,@param JSDoc 标签的片段补全,以及优化,如避免不必要的类型实例化和联合字面的负数检查。

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-rc/

《在科技会议上从参会者到演讲者的 9 个技巧 | GitHub博客》。GitHub Universe 是一年一度的全球开发者和客户活动,今年将于 11 月 8 日至 9 日在线上和线下举行。文章提供了一些撰写成功演讲提案的技巧,例如标题要吸引人、具体说明内容的收获、突出会议性质等。此外,还提供了演讲者个人介绍的公式和其他有用资源,如往年活动的回顾、联系前任演讲者、关注行业热点等。最后,文章呼吁有兴趣参加演讲的人提交他们的想法,并列出了被选中的好处。

https://github.blog/2023-05-18-9-tips-to-go-from-attendee-to-speaker-at-a-tech-conference/

《GitHub - DukeLuo/eslint-plugin-check-file》。本文介绍了一个名为 eslint-plugin-check-file 的 ESLint 插件,该插件可以帮助开发者强制规范化文件和文件夹的命名方式。插件支持多种规则,例如强制指定文件夹名称、文件名命名规范等。开发者只需要在 .eslintrc 配置文件中添加相应的规则即可使用。

https://github.com/DukeLuo/eslint-plugin-check-file

《揭开魔法的面纱:探索各种框架的反应性》。本文深入探讨了各种前端框架中的响应性(reactivity)机制,着重比较了粗粒度和细粒度响应性之间的差异。React 和 Angular 属于粗粒度系统,需要重新执行组件树来检测更改并更新 DOM;Svelte、Vue、Qwik 和 Solid 属于细粒度系统,可以更加高效地检测和更新 DOM。Qwik 是唯一一个不需要预热的框架,它通过 SSR/SSG 将状态与 DOM 相关联,并在客户端恢复这些信息,从而避免了下载大量应用代码的问题。作者认为,虽然粗粒度系统 “随便用” 会更方便,但是使用细粒度系统可能会更高效,因为后者已经进行了优化。

https://www.builder.io/blog/reactivity-across-frameworks

《介绍一下 Legend-State 1.0:更快地构建更快的应用程序》。文章介绍了一个名为 Legend-State 的 React 状态库,它具有极快的速度、易用性、自然的细粒度反应和内置持久性等四个主要优点。该库基于可观察对象实现,使用 Proxy 跟踪对象中的路径,从而在速度和内存使用方面超越其他 React 状态库。使用该库不需要繁琐的模板代码和上下文、动作、规约、分派器等,只需调用 get() 获取原始数据并使用 set() 更改数据即可。此外,该库还支持细粒度反应,使得组件能够在特定值更改时更新,从而减少重新渲染的次数。最后,该库还内置了持久化功能,可以保存和同步应用程序状态。未来,该库将添加更多的持久化插件和辅助可观察对象和钩子函数。

https://legendapp.com/open-source/legend-state-v1/

《管理 GitHub 通知》。这篇文章介绍了一种名为 “Notification-driven Developement” 的方法来管理 GitHub 上的项目。该作者通过使用 GitHub 的通知系统来管理他所维护的各种规模的项目,以保持项目的活跃度和稳定性。他提出了 “Inbox-Zero” 概念,即每天处理完所有收到的通知,以便快速响应社区成员并控制维护工作量。文章还分享了一些减少通知数量和组织通知的技巧,并介绍了一个用户脚本来自动化通知处理。最后,作者强调了享受工作和保持良好的工作与生活平衡的重要性。

https://antfu.me/posts/manage-github-notifcations-2023

《Bun Bundler》。Bun bundler 是一个快速的本地打包工具,现在已经进入了 beta 测试阶段。它可以通过 bun build CLI 命令或新的 Bun.build() JavaScript API 来使用。该工具可以用于构建前端应用程序,并提供了内置的 Bun.build () 函数和 bun build CLI 命令。文章指出,JavaScript 生态系统的复杂性不断增加,如何运行 TypeScript 文件、如何为生产环境构建 / 打包代码等问题使得开发变得越来越复杂。Bun bundler 的目标是将打包引入 JavaScript 运行时,从而使前端和全栈代码的发布更简单、更快速。该工具的优点包括:插件执行快速、生成预转换文件以提高运行性能、统一的插件 API、构建输出数组、支持 ESM 模块系统、支持 tree-shaking、支持源码映射、支持 JS 压缩器等。未来,Bun bundler 还将与 Bun 的 HTTP 服务器 API(Bun.serve)集成,从而实现用简单的声明式 API 代替

https://bun.sh/blog/bun-bundler

《将 Next.js App Router 用于生产的 5 条经验之谈》。Next.js 13 的新功能 App Router 引入了 Nested Layouts、Server Components 和 Streaming 等多项新特性,是第一个开源实现 React 18 原语的工具。从 Next.js 13.4 开始,App Router 已被认为是生产就绪状态。使用 App Router 可以更轻松地在路由之间共享 UI、更好地利用服务器组件、更快地展示页面部分内容以及准备未来。但是,在应用 App Router 时需要注意两个缓存、URL 搜索参数在布局服务器组件中的问题、文件结构的优点以及学习新技术和资源有限的挑战。建议先仔细阅读官方文档,如果遇到问题可以查看 GitHub 和 Twitter 上的讨论,并且分享经验和解决方案有助于建立更加实质性的知识库。总体而言,采用 App Router 可以提高用户和开发者的体验,但需要耐心和深入挖掘。

https://www.inngest.com/blog/5-lessons-learned-from-taking-next-js-app-router-to-production

《理解 useRef 和 useState 用于跟踪 React 中的组件渲染次数》。本文介绍了在 React 中使用 useRef 和 useState 来追踪组件渲染次数的实际例子。通过自定义一个名为 useComponentRenderCount 的 hook,使用 useRef 来存储渲染次数,并使用 useState 来管理组件内的不同状态值。通过将状态值分开控制,可以提高代码可读性并更轻松地管理每个值的状态更新。理解何时使用 useRef 以及如何与 useState 一起使用对于管理复杂的组件行为至关重要。在开发 React 应用程序时,需要平衡性能和功能,才能创建高质量的应用程序。

https://peterkellner.net//2023/05/05/Understanding-useRef-and-useState-for-Tracking-Component-Render-Count-in-React/

《反应全局状态为局部状态》。这篇文章介绍了一种基于 React 的全局状态管理方案,使用 useGlobalState 钩子来读取全局存储对象,并在其更新时强制所有已订阅的组件重新渲染。相比于 Redux 和 Context,这种方案更加简单且没有繁琐的代码。该方案不需要依赖库,支持测试和 TypeScript。文章详细介绍了如何实现这个钩子,包括 JavaScript 和 TypeScript 的实现以及测试用例。作者表示这种方案虽然简单,但也具有可扩展性,可以在其上构建中间件、错误处理和动作等功能。作者在几个项目中尝试了 createGlobalState,目前已成为他的默认选择。

https://webup.org/blog/react-global-state-as-local-state/

《Rome 发布 v12.1.0》。Rome v12.1.0 发布了,支持新的 Stage 3 装饰器、VCS 集成和新的 lint 规则。现在,Rome 可以解析和格式化大多数框架中的装饰器,并且支持 git VCS 集成。此外,还添加了许多新的 lint 规则,并提供了一个新的命令来更新配置文件。还有一个新的 CLI 帮助提示库,可以从源代码生成输出。

https://rome.tools/blog/2023/05/10/rome12_1/

《掌握 TypeScript 中的 infer - JavaScript in Plain English》。本文介绍了 TypeScript 中 infer 关键字的用法,它可以从现有的代码中提取和推断类型。使用 infer 关键字可以增加代码的类型安全性、效率和组织性。infer 关键字可以在泛型类型、函数参数和返回值、映射类型中使用,但只能在条件类型中使用。同时,文章还提供了一些实际的例子来展示 infer 关键字的使用方法。

https://javascript.plainenglish.io/mastering-infer-in-typescript-6cf3f93cca86

MDH 前端周刊第 100 期:React Query、演讲、Reactivity、Bun Bundler、Rome、infer

📒 Go语言爱好者周刊:第 187 期

gobot v2.0 发布 - 使用 Go 编程语言的 IOT 框架(机器人框架)。

https://github.com/hybridgroup/gobot

Mage v1.15 发布 - Mage 是使用 Go 的类似 make/rake 的构建工具。您编写普通的 go 函数,Mage 会自动将它们用作类似于 Makefile 的可运行目标。

https://github.com/magefile/mage

几种使用Go发送IP包的方法 - 本文尝试介绍几种收发IP packet的方式。

https://colobu.com/2023/05/13/send-IP-packets-in-Go/

lingoose - 一个 Go 框架,用于使用管道开发基于 LLM 的应用程序。

https://github.com/henomis/lingoose

Go语言爱好者周刊:第 187 期

· 8 min read
加菲猫

image

题图:王国之泪。

⭐️ Go与神经网络:张量运算

⭐️ 掌握 GoLang 中的指针:高效代码的提示和技巧

⭐️ 通过源码分析告诉你:当访问K8S API的代码运行在POD里的容器时,在集群内是如何进行身份验证的

⭐️ 「Go工具箱」redis官网推荐的go版本的分布式锁:redsync

📒 通俗直观介绍ChatGPT背后的大语言模型理论知识

⭐️ Golang网络IO模型源码分析-goroutinue+epoll

⭐️ 什么是无头浏览器?用Go模拟用户操作、实现网页浏览和截图

📒 Nuxt 3.5 正式发布,支持 Vue 3.3!

⭐️ 翻车了,被读者找出 BUG

⭐️ sync.Map Code Review

⭐️ 一文掌握 Go 并发模式 Context 上下文

⭐️ React 性能优化 | 包括原理、技巧、Demo、工具使用

📒 关于组件化链路设计的分享

📒 硬核,图解bufio包系列之读取原理

📒 6 个 TypeScript 的高级技巧,帮你写出更清晰的代码

📒 日常开发中,提升技术的13个建议

⭐️ 开发工具 All In One

⭐️ 从一次 PR 经历谈谈 Go 和 MySQL 的时区问题

⭐️ 玩转Netty,从“Hello World”开始!

📒 面试官:一千万的数据,你是怎么查询的

⭐️ context.Context Code Review

⭐️ 提升 Web 核心性能指标的 9 个建议

📒 Vue 转 React的开发者,常犯的10个错误

📒 你们喜欢用forEach吗?说说我为啥不喜欢用forEach

⭐️ Go语言中常见100问题-#35 Using defer inside a loop

⭐️ Go设计模式--解释器模式

📒 分布式唯一 ID 通用选型

📒 MDH 前端周刊第 99 期:jQuery 3.7、Vue 3.3、Deopt Explorer、粘性菜单、Remix、SSC

《使用 Deno 在 Rust 中运行 JavaScript》。本文介绍了作者创建的一个名为 “js-in-rs” 的基于 Rust 的 CLI 工具,用于使用 JavaScript 表达式过滤文件。与 grep 工具使用正则表达式不同,js-in-rs 使用 JavaScript 表达式进行过滤。文章详细介绍了 js-in-rs 的工作原理和代码实现,并探讨了在 Rust 应用程序中运行 JavaScript 代码的潜在应用,例如 Web 服务器、数据管道和数据库用户定义函数等。

https://austinpoor.com/blog/js-in-rs

《发布 Vue 3.3》。Vue 3.3 "Rurouni Kenshin" 已经发布,重点是改善开发者在使用 Vue 与 TypeScript 时的体验。该更新包括改进 SFC <script setup> 与 TypeScript 的使用,宏中的导入和复杂类型支持,通用组件,更符合人体工程学的 defineEmits ,带有 defineSlots 的类型槽,以及反应式道具 destructure 和 defineModel 等实验性功能。

https://blog.vuejs.org/posts/vue-3-3

《React 协调:它是如何工作的,为什么我们应该关心》。本文详细介绍了 React 的协调算法,以及它如何影响我们的日常代码。文章探讨了条件渲染、"key" 属性和为什么不应该在其他组件内声明组件等问题,并提供了解决方法。作者通过分析 React 的虚拟 DOM 和状态更新过程,解释了为什么在条件渲染中声明组件会重新挂载,以及为什么需要使用 "key" 属性来避免组件重复挂载或保证元素的唯一性。最后,作者提供了多个示例来说明这些概念。

https://www.developerway.com/posts/reconciliation-in-react

《介绍 Deopt Explorer - TypeScript》。本文介绍了如何使用内联缓存(inline caching)优化 JavaScript 代码的性能,并讲解了在 TypeScript 编译器中如何使用 Deopt Explorer 工具来分析性能问题和减少多态现象。文章详细介绍了内联缓存的概念、不同类型的缓存以及多态现象的产生原因。通过实例分析,作者展示了如何使用 Deopt Explorer 工具来分析 V8 引擎生成的 ICs 和对象类型,并通过优化 Symbol 类型的属性访问,将编译时间平均缩短了 8-10%。

https://devblogs.microsoft.com/typescript/introducing-deopt-explorer/

《我的 Remix 之路》。这篇文章讨论了作者使用 Remix 框架的经验和遇到的问题。作者认为 Remix 是一个很好的框架,但是也存在一些缺点。作者提出了四个主要问题:开发体验、路由过于神秘、仍然不够成熟以及控制不是默认的。作者指出,Remix 在某些方面缺乏对开发者的控制权,例如构建过程和静态资源处理。此外,Remix 的路由语法可能会使人感到困惑,并且更新时可能会出现问题。

https://redd.one/blog/my-struggle-with-remix

《不阻塞事件循环的实用指南》。本文介绍了 JavaScript 在单线程环境下的事件循环机制,以及如何避免同步任务阻塞事件循环。作者提出了三种解决方案:增加节点数量、将同步任务改为异步任务、将同步任务转移到另一个线程。其中,将同步任务转移到另一个线程需要使用 Worker,并且有数据传输限制。作者还介绍了将同步任务改为异步任务的具体实现方法,即通过将代码块分散到事件循环中来添加同步执行之间的间隙,从而让事件循环得以运行。

https://www.bbss.dev/posts/eventloop/

《React 服务器组件是什么?》。React Server Components 是在服务器上渲染的 React 组件,旨在减少网络瀑布效应。与传统的服务器端渲染 (SSR)、并行获取和架构更改相比,Server Components 具有更好的用户体验、更快的构建速度和更易于维护的特点。Server Components 可以通过在 JS 和 HTML 中填充一些初始数据来减少客户端请求次数,而且这种方式可以嵌套使用,只需要向顶层组件和其子组件发出一次请求即可。Server Components 还可以减小 JS 包的大小,只发送必要的数据给客户端,从而提高性能。

https://www.viget.com/articles/what-even-are-react-server-components/

MDH 前端周刊第 99 期:jQuery 3.7、Vue 3.3、Deopt Explorer、粘性菜单、Remix、SSC

📒 Go语言爱好者周刊:第 186 期 — 可视化 Go 程序调用

· 24 min read
加菲猫

image

题图:rainy day, a water wheel in the green river, green plants and flowers in the foreground, mountains and water in the distance。

📒 一文通透讲解webpack5 module federation

⭐️ 一文搞懂Go错误链

📒 Webpack5构建性能优化:构建耗时从150s到60s再到10s | 京东云技术团队

📒 三十分钟掌握Webpack性能优化

⭐️ 不背锅运维相关文章

上篇:带你手工体验从写代码、编译、打包镜像、部署到K8S的全过程

下篇:使用jenkins发布go项目到k8s,接上篇的手工体验改造为自动化发布

值得收藏:K8S的kubectl常用命令已经按场景分好类,请您查阅

避坑:Go并发编程时,如何避免发生竞态条件和数据竞争

Go接口:运维开发场景中,go的接口到底怎么用

📒 Vue3.3 正式发布!

⭐️ 容器中如何正确配置 GOMAXPROCS

⭐️ Go项目组织:在单一repo中管理多个Go module指南

📒 React全新实验性Hooks:useOptimistic、useFormStatus

⭐️ Go 笔试 - 交叉顺序输出奇偶数

⭐️ zookeeper到nacos的迁移实践

⭐️ 「必知必会」 Nacos 的面试题和详解

⭐️ 使用增强版 singleflight 合并事件推送,效果炸裂!

singleflight 把每次请求定义为 call,每个 call 对象包含了一个 waitGroup,一个 val,即请求的返回值,一个 err,即请求返回的错误。

type call struct {
wg sync.WaitGroup
val interface{}
err error
}

再定义全局的 Group,包含一个互斥锁 Mutex,一个 key 为 string,value 为 call 的 map。

type Group struct {
mu sync.Mutex
m map[string]*call
}

Group 对象有一个 Do 方法,其第一个参数是 string 类型的 key,这个 key 也就是上面说的 map 的 key,相同的 key 标志着他们是相同的请求,只有相同的请求会被抑制;第二个参数是一个函数 fn,这个函数是真正要执行的函数,例如调用 MySQL;返回值比较好理解,即最终调用的返回值和错误信息。

func (g *Group) Do(key string, fn func() (interface{}, error)) (interface{}, error) {
// 懒加载方式初始化 map
// 注意 map 不是并发安全的,这里用了 Mutex 保护 map 操作
g.mu.Lock()
if g.m == nil {
g.m = make(map[string]*call)
}

// 如果当前 key 存在,即相同请求正在调用中,就等它完成
// 完成后直接使用它的 value 和 error
if c, ok := g.m[key]; ok {
g.mu.Unlock()
c.wg.Wait()
return c.val, c.err
}

// 如果当前 key 不存在,即没有相同请求正在调用中
// 就创建一个 call 对象,并把它放进 map
c := new(call)
c.wg.Add(1)
g.m[key] = c
g.mu.Unlock()

// 接着执行 fn 函数
c.val, c.err = fn()
// 函数执行完唤醒 waitGroup
c.wg.Done()

// 删除 map 相应的 key
g.mu.Lock()
delete(g.m, key)
g.mu.Unlock()

// 返回 value 和 error
return c.val, c.err
}

使用增强版 singleflight 合并事件推送,效果炸裂!

⭐️ Go 反射应用与三大定律

📒 Go1.20.4 新版本发布,修复了一个神奇的内联 BUG!

⭐️ sync.Cond 设计与实现

📒 React 正式推出 Canary 版本!

⭐️ 解读 pkg.go.dev 的设计和实现

解读 pkg.go.dev 的设计和实现:设计篇

本地搭建一个 pkg.go.dev:遇到的问题和解决

Go 开源的 pkgsite,据说是应届生代码水平

⭐️ Go语言中常见100问题-#34 Ignoring how the break statement works

⭐️ 「Go框架」bind函数:gin框架中是如何将请求数据映射到结构体的

⭐️ 「Go框架」深入解析gin中使用validator包对请求体进行验证

📒 Go 语言内置 I/O 多路复用机制

📒 图解TCP 三次握手和四次挥手的高频面试题(2023最新版)

⭐️ pkgsite 新增本地模式下的跳转与搜索功能

⭐️ Go 高性能 - 无锁编程

📒 MDH 前端周刊第 98 期:Angular 16、Vercel Storage、类型测试、React Canaries

  • React Native macOS v0.71 发布
  • Pnpm v8.4.0 发布,支持包校验等
  • React 发布 canary 版本
  • VSCode v1.78 发布,体验改善等
  • Nextjs v13.4 发布,App Router 稳定等

《Next.js 发布 13.4》。Next.js 13.4 是一个重要的版本,标志着 App Router 的稳定性。这个版本增加了许多新特性,包括 React Server Components、嵌套路由和布局、简化数据获取、流式渲染和 Suspense、内置 SEO 支持等。其中最重要的是 App Router,它是 Next.js 的核心组件,可以让开发者更方便地定义页面布局和数据获取方式。此外,Turbopack 也是一个值得关注的新功能,它可以加速本地开发和生产构建过程。最后,Server Actions 是一个实验性的功能,可以在服务器端直接修改数据,不需要客户端 JavaScript。

https://nextjs.org/blog/next-13-4

《使用 Vercel Spaces 实现规模化的高质量软件 - Vercel》。Vercel 推出了 Vercel Spaces,它提供了强大的工具和惯例,可以与 monorepo 集成,使开发人员能够在保持质量的同时有效地扩展。Spaces 仪表板提供了对开发工作流程、代码健康状况和构建日志的洞察力,并包括通过 Conformance、Code Owners 和 Vercel Runs 提升效率和消除障碍的新功能。

https://vercel.com/blog/vercel-spaces

《Tauri 发布 1.3.0》。Tauri 团队发布了 1.3 版本,包括安全改进、新功能和重要的错误修复。该版本新增了 NSIS,可以使用 NSIS 创建 Windows 应用程序安装程序,还有其他一些改进和修复。

https://tauri.app/blog/2023/05/03/tauri-1-3/

《TailwindCSS vs. UnoCSS》。本文对比了 TailwindCSS 和 UnoCSS 两个工具,总结了它们的特点、语言、文档、自定义样式和编辑器支持等方面。TailwindCSS 拥有完整的 CSS 特性类名,可以通过任意值、变体和属性来进行全面的样式设计,而 UnoCSS 则支持所有 TailwindCSS 的功能,并提供了一些额外的功能,如变体组、CSS 网格流体列和更多动画效果。在语言方面,TailwindCSS 有一个相对规范的类名命名方式,UnoCSS 则更加灵活。在文档和自定义样式方面,两者都有不错的表现,但 UnoCSS 的交互式文档和颜色提示更加出色。在编辑器支持方面,TailwindCSS 支持较好,但存在一些缺陷,而 UnoCSS 的高亮显示和颜色提示则更为出色。作者认为,如果你看重灵活性和额外的功能,你可能会喜欢 UnoCSS,但如果你看重约束和更清晰的编写语言,则应该选择 TailwindCSS。

https://dev.to/mapleleaf/tailwindcss-vs-unocss-2a53

《10 种使用 ChatGPT 学习更好的方法 - 斯科特・H・扬》。这篇文章总结了读者们如何使用大型语言模型(LLMs)来学习和研究的建议,并探讨了使用这些工具的优缺点。作者提醒读者要注意,虽然 ChatGPT 可以进行人类般的对话,但它并不是真正的人类,有时会提供错误的答案。然而,ChatGPT 在许多任务上都很有用,例如作为个人导师、语言教练、生成摘要、与长文本对话、简化专业术语等。作者还提到了一些不应该使用 AI 工具的情况,例如期望它们正确地获取事实、引用和数学等方面。

https://www.scotthyoung.com/blog/2023/05/02/chatgpt-learning-tips/

《React Canaries:在 Meta 之外启用增量功能发布》。React 团队推出了一个新的官方支持的 Canary 版本,让开发者可以在稳定版本发布之前就采用新功能。这个 Canary 版本只包含 React 团队相信已经准备好被采用的特性,而不像实验性版本那样可能会有重大变化。React 将按照 semver 规范每个稳定版本进行更新,同时也会在博客上发布 Canary 版本中的重大变更和新特性。Canary 版本需要被固定版本号,以避免包含重大变更。除此之外,React 的稳定版本不会有任何改变。

https://react.dev/blog/2023/05/03/react-canaries

《为什么我喜欢使用 Map(和 WeakMaps)来处理 DOM 节点》。本文介绍了在处理大量 DOM 节点时,Maps(和 WeakMaps)是特别有用的工具的原因。与使用对象作为键 / 值存储相比,使用 Map 可以更简单、更强大、更高效地管理状态,并且不需要设置或读取唯一属性。此外,Map 还具有自动垃圾回收的功能,可以更有效地管理内存。总之,Map 对于处理大量 DOM 节点非常有用。

https://www.macarthur.me/posts/maps-for-dom-nodes

《React Native macOS 发布 0.71》。React Native macOS 发布了 0.71 版本,这是该平台首次与 iOS、Android 和 Windows 保持同步。为了实现这个目标,开发团队不得不跳过了一些中间版本,并开始着手 0.72 版本。此外,该版本还加入了对 Fabric 的实验性支持,但需要注意的是这只是一个概念验证,存在不稳定性。

https://devblogs.microsoft.com/react-native/2023-04-27-announcing-macos-71/

《如何在 React 中编写注释:好的、坏的和丑陋的》。这篇文章介绍了在 React 中添加注释的三种方法。第一种是使用 JSX 注释语法,但这种方式有些冗长;第二种是在 JSX 标签外使用 JavaScript 注释,可以更简洁地添加注释;第三种是在 JSX 标签内部使用 JavaScript 注释,可以针对特定元素添加注释。作者认为第三种方法最好,因为它简洁明了且针对性强。

https://dmitripavlutin.com/react-comments/

《React Router 发布 v6.11.0》。这篇文章介绍了 React Router 版本 6.11.0 的更新内容。其中,一些小的改动包括在 useFetcher 中启用 basename 支持,更新 @remix-run/router 依赖等。此外,fetchers 不再在搜索参数更改或路由到相同 URL 时重新验证,并且只会在操作提交或 router.revalidate 调用时重新验证。

https://github.com/remix-run/react-router/releases/tag/react-router%406.11.0

《Prompt 工程 vs 盲目 Prompting》。本文介绍了 Prompt Engineering,即利用提示来有效地从语言模型中提取信息的过程,通常用于实际应用。文章指出,许多人声称正在进行 Prompt Engineering,但实际上只是盲目 Prompting。因此,本文提供了一种基于实验方法的 Prompt Engineering 示例,以展示如何为应用程序构建可靠的功能。作者强调了选择问题、演示集、提示候选项和测试提示等步骤的重要性,并解释了如何选择最终的提示方案。

https://mitchellh.com/writing/prompt-engineering-vs-blind-prompting

《使用 Rust 在 10 分钟或更短的时间内构建和部署 URL 缩短器》。这篇文章讲述了一个软件开发人员在凌晨时分突然想到的一个想法:能否在不需要担心基础架构的情况下快速构建一个有用的应用程序。他使用了 Rust 编程语言,结合 serverless 平台 Shuttle 和 Postgres 数据库,最终成功地构建了一个简单的 URL 缩短服务。作者认为,虽然现实中的软件工程很复杂,涉及到不同团队和技能集的协作,但这种新型的无需关注基础架构的开发模式是可行的,并且可以带来更好的体验。

https://www.shuttle.rs/blog/2022/03/13/url-shortener

《Vercel 发布 Vercel Storage》。Vercel 宣布了一套无服务器存储解决方案,包括 Vercel KV,一个无服务器的 Redis 解决方案;Vercel Postgres,一个为前端建立的无服务器SQL数据库;以及 Vercel Blob,一个在边缘上传和服务文件的解决方案。这些解决方案旨在使数据库成为 Vercel 前端云的一流部分,并使开发人员能够管理他们的前端存储需求,而不必担心基础设施。

https://vercel.com/blog/vercel-storage

《Deno 发布 KV》。Deno KV 是一款全球复制、强一致性的键值数据库,可在 35 个地区实现低延迟读取。它可以无缝集成到开源 Deno 运行时中,无需任何配置即可在本地或作为托管服务运行。Deno KV 是一个简单但功能强大的一流原语,只暴露了少量方法来存储、检索、删除和枚举数据。

https://deno.com/blog/kv

《React 渲染的交互式指南》。本文主要介绍了 React 的渲染机制,即 React 只有在状态改变时才会重新渲染组件。当事件处理程序被调用时,如果其中包含 useState 的更新函数,并且新状态与快照中的状态不同,React 将触发重新渲染。此外,本文还介绍了 React 的批处理算法和 StrictMode 组件。

https://ui.dev/why-react-renders

《如何使用 Rust 和 Napi RS 在 NodeJs 中将 CSV 文件处理速度提高五倍》。本文介绍了如何使用 Rust 和 Napi RS 在 NodeJs 中处理 CSV 文件。作者使用了 readline 模块来处理 CSV 文件,并记录了处理时间和吞吐量。然后作者使用了 Rust 编写了相同的代码,并通过 pv 命令进行了基准测试,发现 Rust 版本比 Nodejs 版本快五倍。最后,作者介绍了如何使用 Napi rs 将 Rust 代码编译成动态库,并在 Nodejs 中调用。总之,结合 Rust 和 Nodejs 可以实现更好的性能和效率。

https://www.alxolr.com/articles/how-to-process-a-csv-file-five-times-faster-in-node-js-with-rust-and-napi-rs

《实现 experimental_useFormStatus by acdlite・Pull Request #26722・facebook/react》。这篇文章介绍了一个新的 React Hook,可以读取其祖先表单组件的状态,用于实现加载指示器等功能。目前该 Hook 只在实验版本中可用,随着其稳定性的提高,将会发布更多 API 和文档。该 Hook 内部使用 startTransition 和上下文对象实现,但实际实现细节可能会发生变化。由于表单元素不能嵌套,因此实现者不需要跟踪多个嵌套的 “转换提供者”。虽然它使用通用的 Fiber 配置方法进行实现,但它目前仍基于 React DOM 的要求进行一些假设。

https://github.com/facebook/react/pull/26722

《我作为新经理所犯的一些错误》。这篇文章讲述了作者成为管理者的经历,以及他在这个过程中犯下的错误和解决策略。作者指出,作为一名管理者,最初的困难之一是难以确定自己的工作是否有用。他提供了三种应对策略:与上级领导沟通,寻求反馈,多元化生活体验。此外,作者还分享了其他的经验教训,如管理的重要性、任务相关成熟度、拖延维护、直接询问等。最后,作者总结了成为新管理者的困难所在,并鼓励读者不要害怕犯错,因为这是成长的必经之路。

https://www.benkuhn.net/newmgr/

《TypeScript 装饰器:完整指南》。本文介绍了 TypeScript 的装饰器,装饰器本质上是函数,可以用于给类、方法、属性等应用可重用的行为。不同类型的装饰器包括类装饰器、方法装饰器、属性装饰器、访问器装饰器和参数装饰器。装饰器可以用于实现各种功能,如前 / 后钩子、监视属性更改和方法调用、转换参数、自动序列化和反序列化、依赖注入等。使用装饰器的优点包括跨越关注点、依赖注入、验证和代码组织。

https://deadsimplechat.com/blog/typescript-decorators-a-complete-guide/

《批判性思维是软件工程师最重要的技能吗?》。这篇文章谈到了两个现象:技术术语的使用和 “思想领袖” 在社交媒体上的崛起,以及这些现象对批判性思维的影响。作者认为,过度使用技术术语可能掩盖了人们对某一概念的真正理解,而 “思想领袖” 的观点也不应该被轻易地接受,需要进行深入的研究和验证。作者建议人们提高批判性思维能力,包括理解技术术语、验证信息、问 “为什么” 和 “如何”,并避免跟风。最后,作者强调批判性思维将在未来变得越来越重要,因为随着人工智能工具的普及,我们需要更多的人来质疑和思考。

https://blog.pragmaticengineer.com/critical-thinking/

《不要 "闪烁" 的 UI:使用 useLayoutEffect,绘画和浏览器故事》。本文介绍了在 React 中如何根据 DOM 测量更改元素的基础知识。文章首先通过一个响应式导航组件的例子,讲解了如何使用 useEffect 来计算容器大小和每个元素的尺寸,并且根据这些信息来调整元素的数量。然而,这种方法会导致初始渲染时出现闪烁问题。为了解决这个问题,文章介绍了 useLayoutEffect 的用法,并解释了浏览器渲染、绘制和事件循环等相关概念。最后,文章还讨论了在 Next.js 等服务器端渲染框架中使用 useLayoutEffect 的问题。

https://www.developerway.com/posts/no-more-flickering-ui

《关于 LLM 的八件事 | Swizec Teller》。这篇文章总结了最近人工智能(AI)的进展和引起人们兴奋的原因。其中提到了以下几点:1. 大型语言模型(LLMs)随着规模的增大而变得更好;2.LLMs 具有出人意料的新颖能力,包括 few-shot 和上下文学习;3.LLMs 表现出 “心理模型”;4. 无法可靠地控制 LLMs;5. 目前还没有人知道 LLMs 是如何工作的;6.LLMs 可以胜过人类;7.LLMs 存在偏见问题;8.LLMs 表现很好。作者还提供了一些资源来帮助读者更深入地了解这些问题。

https://swizec.com/blog/eight-things-to-know-about-llms/

《Mojo 可能是数十年来最大的编程语言进步。》。文章介绍了一种名为 Mojo 的新编程语言,它是 Python 的超集,并且可以通过使用 “fn” 和 “struct” 等新语法来实现高性能代码。该语言建立在强大的基础上,包括 LLVM 和 MLIR 等核心技术,使其快速发展和易于开发。作者认为 Mojo 将成为 AI 模型开发的替代 Python 的重要工具,并且预计它将比预期更快地发展和扩展。

https://www.fast.ai/posts/2023-05-03-mojo-launch.html

MDH 前端周刊第 98 期:Angular 16、Vercel Storage、类型测试、React Canaries

📒 Go语言爱好者周刊:第 185 期 —— 归来了

Grafana Pyroscope 解决 Go 内存泄露。

https://grafana.com/blog/2023/04/19/how-to-troubleshoot-memory-leaks-in-go-with-grafana-pyroscope/

go-openai 1.9.1 发布 - OpenAI 的 Golang SDK,包括 ChatGPT、GPT-3、GPT-4 等。

https://github.com/sashabaranov/go-openai

queue - 线程安全、泛型的多队列实现(堵塞队列、优先队列、环形队列)。

https://github.com/adrianbrad/queue

Go Time 第 273 期 - Go 中使用领域驱动设计。

https://changelog.com/gotime/273

强大的装饰器模式。

https://www.youtube.com/watch?v=GipAZwKFgoA

Go语言爱好者周刊:第 185 期 —— 归来了

· 11 min read
加菲猫

⭐️ GMP 调度器(附录)- QA

⭐️ 前端工程化相关文章

一起来看看一个体系完善的前端React组件库是如何搭建出来的!

干货 | 耗时缩短2/3,Taro编译打包优化实践

干货 | 30+条业务线,携程微信小程序如何协同开发

干货 | 秒开率70%+,携程金融SSR应用性能监测与优化

干货 | 携程微信小程序如何进行Size治理

干货 | 携程小程序生态之Taro跨端解决方案

携程跨端解决方案的新选择:Taro-CRN

⭐️ LangChain 中文入门教程

LangChain 是一个用于开发由语言模型驱动的应用程序的框架,主要拥有「将 LLM 模型与外部数据源进行连接」「允许与 LLM 模型进行交互」这2个能力,已经在GitHub获得35K Star,并且快速迭代中。例如可以实现一些功能:

  • 对超长文本进行总结
  • 构建本地知识库问答机器人
  • 使用GPT3.5模型构建油管频道问答机器人

假如我们想要用 openai api 对一个段文本进行总结,我们通常的做法就是直接发给 api 让他总结。但是如果文本超过了 api 最大的 token 限制就会报错。

这时,我们一般会进行对文章进行分段,比如通过 tiktoken 计算并分割,然后将各段发送给 api 进行总结,最后将各段的总结再进行一个全部的总结。

如果,你用是 LangChain,他很好的帮我们处理了这个过程,使得我们编写代码变的非常简单。

from langchain.document_loaders import UnstructuredFileLoader
from langchain.chains.summarize import load_summarize_chain
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain import OpenAI

# 导入文本
loader = UnstructuredFileLoader("/content/sample_data/data/lg_test.txt")
# 将文本转成 Document 对象
document = loader.load()
print(f'documents:{len(document)}')

# 初始化文本分割器
text_splitter = RecursiveCharacterTextSplitter(
chunk_size = 500,
chunk_overlap = 0
)

# 切分文本
split_documents = text_splitter.split_documents(document)
print(f'documents:{len(split_documents)}')

# 加载 llm 模型
llm = OpenAI(model_name="text-davinci-003", max_tokens=1500)

# 创建总结链
chain = load_summarize_chain(llm, chain_type="refine", verbose=True)

# 执行总结链,(为了快速演示,只总结前5段)
chain.run(split_documents[:5])

参考:

https://github.com/liaokongVFX/LangChain-Chinese-Getting-Started-Guide

⭐️ 万字长文:LLM - 大语言模型发展简史

📒 Mojo 发布引出 Go 语言重大变革提案:用 .ʕ◔ϖ◔ʔ 替代 .go​

⭐️ Go:值与指针

⭐️ map 设计与实现(下篇)- 扩容和 QA

⭐️ Java与Go到底差别在哪,谁要被时代抛弃

📒 如何利用 IOC 改善工程设计:以 Eclipse Theia 为例

📒 TailwindCSS vs. UnoCSS

https://dev.to/mapleleaf/tailwindcss-vs-unocss-2a53

📒 React :新增实验性 API :useOptimisticState

https://github.com/facebook/react/pull/26740

⭐️ Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库

以下是社区提供的一个泛型快速 Demo,可以跟着思考运行一下,看看自己泛型的基本使用掌握的如何。

代码如下:

package main

import "fmt"

func MapKeys[K comparable, V any](m map[K]V) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}

type List[T any] struct {
head, tail *element[T]
}

type element[T any] struct {
next *element[T]
val T
}

func (lst *List[T]) Push(v T) {
if lst.tail == nil {
lst.head = &element[T]{val: v}
lst.tail = lst.head
} else {
lst.tail.next = &element[T]{val: v}
lst.tail = lst.tail.next
}
}

func (lst *List[T]) GetAll() []T {
var elems []T
for e := lst.head; e != nil; e = e.next {
elems = append(elems, e.val)
}
return elems
}

func main() {
var m = map[int]string{1: "2", 2: "4", 4: "8"}

fmt.Println("keys:", MapKeys(m))

_ = MapKeys[int, string](m)

lst := List[int]{}
lst.Push(10)
lst.Push(13)
lst.Push(23)
fmt.Println("list:", lst.GetAll())
}

注意 map 遍历顺序是不可预测的

Go1.21 速览:过了一年半,slices、maps 泛型库终于要加入标准库

⭐️ map 设计与实现(上篇)- 数据结构

📒 Next.js 项目参考

https://github.com/okisdev/ChatChat

📒 通过实现一个简易版 react-redux ,我更理解了!

⭐️ Go设计模式--命令模式

📒 TypeScript 前端工程最佳实践

📒 2023年谈谈前端代码加密与混淆

为啥最近突然需要关注这个:

  • Chrome 110 开始默认对源文件 pretty prints,降低用户调试难度(可以直接打断点);
  • 混淆压缩后的代码,即使 pretty prints 也需要对 Webpack 代码打包、Babel 转译、Terser 压缩非常熟悉,才能转换出源代码,对于普通开发者来说破解难度仍然很大。但是现在可以借助 AI 手段,AI 介入解释代码,加速代码反编译进程,源文件放入 chatgpt 进行释义,降低了破解难度。

前端代码安全与混淆

https://developer.chrome.com/blog/new-in-devtools-110/

📒 相关文章汇总

强大的基于 Web 的 3D 框架 v6.0 版本发布 — Babylon.js 仍然是世界领先的基于 WebGL 的图形引擎之一,具有可视化场景构建器和最佳的基于物理的渲染。v6.0 版本包括具有大量文档和 演示 的 新物理插件、流体渲染、对 反射 处理的重大改进、屏幕阅读器支持 等等。这是 JavaScript 生态系统中一个重大发布,我们无法详细描述,但是在 官网 上有更多内容。

https://doc.babylonjs.com/features/featuresDeepDive/physics/rigidBodies

事实证明,连任天堂也在使用 JavaScript。一位开发者发现,2015 年的 Wii U 和 3DS 上的 Mario vs. Donkey Kong: Tipping Stars 是用 HTML 和 JavaScript 作为底层编写的,他还设法构建了一个 shim,让它可以在正常的浏览器中运行。

https://twitter.com/JasperRLZ/status/1648046875675856897

Chrome 113 的 DevTools 将允许你覆盖网络响应头,包括 CORS 头。它还提供 Nuxt、Vite 和 Rollup 调试改进。

https://developer.chrome.com/blog/new-in-devtools-113/

从 webpack + babel 切换到 rspack,我们的构建时间减少了 85%。

https://twitter.com/shawnrmcknight/status/1651275500118065175

探索 Web Workers 在网页多线程中的潜力 — 这篇文章探讨了 Web Workers 在浏览器中多线程的重要性,包括使用它们的局限性和考虑因素,以及缓解与它们相关的潜在问题的策略。

https://www.smashingmagazine.com/2023/04/potential-web-workers-multithreading-web/

使用 Fuse.js 进行快速便捷的模糊搜索 — Fuse.js 是一个零依赖的模糊搜索库,您可以使用它在浏览器中提供搜索功能,而无需专门的面向搜索的后端。

https://spin.atomicobject.com/2023/04/27/fuse-js-fuzzy-search/

在 React 中如何编写注释:好的、坏的和丑陋的风格 — {/* 像这样编写注释 */} 是在 JSX 中编写注释的常见方法,但还有另外两种方法你也应该知道。

https://dmitripavlutin.com/react-comments/

React Router 6 的九小时探究 — 来自 Scrimba 的 Bob Ziroll 为我们呈现了一个基于 React Router 的应用程序的开发全过程,完整观看需要较长时间,但它是免费的。

https://www.youtube.com/watch?v=nDGA3km5He4

Create React App 的现代替代方案 — create-react-app 曾经是构建单页 React 应用程序的首选工具,但是这篇文章介绍了现在常用的各种替代方案。(我们支持 Vite!)

https://codingpastor.dev/goodbye-create-react-app-a-new-approach

使用 React Server Components 在博客上显示访问计数器 — 使用 React Server Components 在博客上显示访问计数器 — 听说过 React Server Components,但还没有机会尝试?这篇简明教程使用一个常见且易于理解的用例来试用 RSC。此外,它还让我们想起了 90 年代,这永远是一个好的氛围。

https://scastiel.dev/view-counter-react-server-components

使用 Zustand 简化 React 状态管理 — Zustand 是一个简单且不冗长的 Redux 替代品,Niklas Ziermann 在 YouTube 上进行了全面介绍(75 分钟)。

https://www.youtube.com/watch?v=fZPgBnL2x-Q

使用 Tauri 和 React 构建笔记应用程序 — Tauri 是一个基于 Rust 的框架,用于构建桌面应用程序。

https://betterprogramming.pub/building-cross-platform-desktop-applications-with-tauri-part-ii-8d6ad1927093?gi=2e3c50c25e6c

使用 Rust 和 NAPI-RS 在 Node 中快速处理 CSV 文件 — NAPI-RS 是一个用于在 Rust 中构建预编译的 Node.js 插件的框架。本文探讨了如何将其用于实际用途,即能够以高性能处理 CSV 数据。

https://www.alxolr.com/articles/how-to-process-a-csv-file-five-times-faster-in-node-js-with-rust-and-napi-rs

使用 Node 和 Connect 构建现代 gRPC 微服务 — 这篇有趣的教程深入探讨了 Dopt 工程师如何使用 Node 和 Connect 构建 gRPC 驱动的内部微服务。这是一篇基于真实的、生产级别的经验的教程。

https://blog.dopt.com/building-a-modern-grpc-powered-microservice

剖析 npm 恶意软件:五个软件包及其邪恶的安装脚本 — npm 相关的安全问题仍然是一个大话题,而一个常见的安全漏洞是在安装包时运行的安装脚本。

https://blog.sandworm.dev/dissecting-npm-malware-five-packages-and-their-evil-install-scripts

· 12 min read
加菲猫

📒 写给开发同学AI强化学习入门指南

📒 TypeScript 5.1 beta 发布:函数返回值类型优化、Getter/Setter 类型优化、JSX 增强

📒 TypeScript 5.0 beta 发布:新版 ES 装饰器、泛型参数的常量修饰、枚举增强等

📒 TypeScript 4.9 beta 发布:鸽置的 ES 装饰器、satisfies 操作符、类型收窄增强、单文件级别配置等

📒 ES2020 可选链语法一个注意点

ES2020 中的可选链语法可以安全访问对象中的属性:

obj?.prop       // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call

实际开发中的示例如下:

import * as React from "react";

const { useCallback } = React;

type IProps = {
value?: string;
onChange?: (value: string) => void;
}

const Comp: React.FC<IProps> = ({ value, onChange }) => {
const handleChange = useCallback((val: string) => {
// 调用 `onChange` 需要可选链语法
onChange?.(val);
}, []);

const resolvedValue = value || "";

return (
<LayoutWrapper
value={resolvedValue}
onChange={handleChange}
/>
)
}

最近看到同事写的代码用到可选链,结果报错了:

// ❎ Invalid left-hand side in assignment expression.
document.querySelector(".content-main")?.style.display = "block";

但是以上代码,如果不用可选链则可以正常赋值:

// ✅ Correct
document.querySelector(".content-main").style.display = "block";

我们可以看下 Babel 编译的结果:

// 源码
document.querySelector(".content-main")?.style.display;

// 编译结果
var _document$querySelect;
(_document$querySelect = document.querySelector(".content-main")) === null ||
_document$querySelect === void 0
? void 0
: _document$querySelect.style.display;

document.querySelector(".content-main") 返回的值不为 null 的时候,此时原始表达式可以正常访问,也可以进行赋值。但问题就在于 document.querySelector(".content-main") 返回值为 null 的时候,可选链语法会将整个表达式的值转为 undefined,此时如果再赋值就相当于给 undefined 赋值,这个行为显然是不符合预期的。因此,需要注意,可选链语法只能访问对象属性,不能进行赋值。

顺便再提两个可选链语法的细节:1)为啥用一个 _document$querySelect 临时变量缓存 ?. 前面的执行结果,答案是为了避免对象属性重复访问、方法重新调用等,可以提升性能,2)为啥用 void 0 代替 undefined,个人猜测是为了更好的语义性,因为 undefined = "aaa"; 这个赋值虽然无效,但是在非严格模式下不会报错,因为 undefined 实际上是 window 对象上的只读属性,而 void 0 = "aaa"; 这句即使非严格模式也会报错。

参考:

https://babeljs.io/docs/babel-plugin-proposal-optional-chaining

https://github.com/tc39/proposal-optional-chaining

📒 【第2929期】React Refs: 从访问 DOM 到命令式 API

⭐️ GMP 调度器(下篇)- 线程

⭐️ 并发编程-信号量的使用方法和其实现原理

⭐️ 并发编程--用SingleFlight合并重复请求

⭐️ Go的atomic.Value为什么不加锁也能保证数据线程安全

⭐️ Golang 五种原子性操作的用法详解

⭐️ Webpack4的压缩阶段的性能优化和踩坑

⭐️ GMP 调度器(中篇)- 算法

⭐️ 快速上手 Go CGO,掌握在 Go 里写 C!

📒 在 Git 中撤消更改的 6 种方法!

⭐️ Go 1.21新特性前瞻

📒 一个低代码拖拽的表单编辑器,开源咯!!!

⭐️ GMP 调度器(上篇)- 数据结构

⭐️ Go pprof 相关

Go 服务自动收集线上问题现场

go pprof实战

生产环境Go程序内存泄露,用pprof如何快速定位

⭐️ 为什么 recover 必须在 defer 中调用

📒 React 相关汇总

Awesome React:近 500 个 React 项目和资源 — 这是一个与 React 生态系统相关,经常更新且深入的文章和资源集合。

https://github.com/enaqx/awesome-react

Storybook v7.0 发布 — 几周前发布了 v7.0 版本,但官方博文直到上周才发布。无论如何,对于这个受欢迎的组件开发工具来说,这是一个重要的版本更新,现在包括一流的 Vite 支持、对 Next.js 和 SvelteKit 的零配置支持、焕然一新的 UI 等更多功能。

https://storybook.js.org/blog/storybook-7-0/

必须知道的 React 可移植性模式 — 采用这些模式有助于避免“元框架锁定”,如果你选择的工具发生了你不喜欢的演变,你就不会被束缚。

https://www.youtube.com/watch?v=yi8UCnXPu8U

使用 React Hook Form 实现高级多步表单

https://claritydev.net/blog/advanced-multistep-forms-with-react

next-route-visualizer: 将 Next.js v13+ 应用路由结构树形可视化 — 一款用于可视化 Next.js 应用目录路由的软件包,该软件包的功能可以参考这个 演示。

https://github.com/DiiiaZoTe/next-route-visualizer

Simple Light v2.0: 一款用 Tailwind CSS 和 React 实现的落地页模版 — 旨在为开发人员提供创建面向 SaaS 产品、在线服务等落地页所需的所有基本组件。

https://github.com/cruip/tailwind-landing-page-template

📒 一文教你搞定所有前端鉴权与后端鉴权方案,让你不再迷惘

📒 protoc 插件-protoc-gen-grpc-gateway-gosdk

⭐️ 为什么 defer 的执行顺序和注册顺序不同

📒 MDH 前端周刊第 97 期:Vite 4.3、Node 20、pretty-ts-errors、React Query 5

《发布 v5.80.0・webpack/webpack》。Webpack v5.80.0 的新增功能包括支持在 import.meta 中使用解构赋值、支持带有 AwaitExpression 的解构赋值的树摇、引入 errorsSpace 和 warningsSpace 以获得更可读的跟踪信息等。Bug 修复主要涉及 CSS 相关问题、语法错误、模块 ID 分配等。

https://github.com/webpack/webpack/releases/tag/v5.80.0

《Deno vs. Node:没有人准备好迎接这个变化 | .cult by Honeypot》。本文介绍了 Node.js 和 Deno 两个 JavaScript 运行环境的比较。Node.js 是一个流行的服务器端、开源、跨平台的 JavaScript 运行环境,自 2009 年以来一直占据着 Web 开发世界的主导地位。相比之下,Deno 在设计上有所改进,提供了更安全的框架和现代特性,由 Node.js 的创始人 Ryan Dahl 推出。然而,尽管 Deno 解决了 Node.js 的一些设计缺陷,但采用 Deno 的速度非常缓慢,大多数开发人员仍然满意于 Node.js。本文将探讨这种现象背后的原因,并对 Node.js 和 Deno 进行比较,从第三方包管理、API、安全性和 TypeScript 支持等方面进行分析。

https://cult.honeypot.io/reads/deno-vs-node-main-differences/

《发布 Vite 4.3。》。Vite 4.3 发布,主要改进了开发服务器的性能。该版本优化了解析逻辑,改进了热路径,并实现了智能缓存,以查找 package.json、TS 配置文件和已解决的 URL。此外,该团队正在开发一个官方基准测试工具,以获取每个 Pull Request 的性能指标,并通过 vite-plugin-inspect 提供更多的性能相关功能来帮助用户识别应用程序的瓶颈。明年他们将发布 Vite 5,这将是今年唯一的 Vite 主要版本,同时也会放弃对 Node.js 14 和 16 的支持。

https://vitejs.dev/blog/announcing-vite4-3.html

《我们如何让 Vite 4.3 更快》。这篇文章介绍了 Vite 4.3 是如何通过优化解析策略、使用异步函数、并行处理和 JavaScript 优化等方式来提高性能的。

https://sun0day.github.io/blog/vite/why-vite4_3-is-faster.html

《用 Next.js 13 和 React Server Components 建立博客》。本文介绍了如何使用 Next.js 13 和 React Server Components 构建博客,并提供了实际示例。文章包括设置项目、文件结构、动态路由、获取和呈现 Markdown、SEO、部署等内容。作者还介绍了如何使用 next-mdx-remote 和 Bright 进行语法高亮。本文旨在帮助读者快速搭建自己的博客,并鼓励读者进行自己的实验和探索。

https://maxleiter.com/blog/build-a-blog-with-nextjs-13

《发布 TypeScript 5.1 Beta - TypeScript。》。TypeScript 5.1 测试版已经发布,其特点是未定义返回函数的隐式返回更容易,以及 getters 和 setters 的非相关类型。该版本还包括 JJSX 元素和 JJSX 标签类型之间的解耦类型检查、命名的 JJSX 属性以及同时自动编辑多个位置的能力。TypeScript 现在在 TypeScript 和 JavaScript 文件中键入 @param 标签时提供片段补全。

https://devblogs.microsoft.com/typescript/announcing-typescript-5-1-beta/

《GitHub - yoavbls/pretty-ts-errors:在 VSCode 中使 TypeScript 错误更漂亮和易读》。这是一个名为“Pretty TypeScript Errors”的Visual Studio Code扩展,旨在让TypeScript错误变得更加美观和易于阅读。当类型的复杂性增加时,TypeScript错误会变得越来越混乱。这个扩展能帮助您更好地理解错误信息。主要功能包括:为错误信息中的类型提供语法高亮,支持深色和浅色主题;在错误信息中的类型旁边提供一个按钮,可以跳转到相关类型声明;提供一个按钮,可以将您导航到typescript.tv,那里有详细的解释,有时还有视频;提供一个按钮,可以将您导航到ts-error-translator,那里可以用简单的英语阅读错误。

https://github.com/yoavbls/pretty-ts-errors

《ECMAScript 2023 有什么新特性 | pawelgrzybek.com》。JavaScript 的新功能列表已经确定,最终版本的 ECMAScript 规范预计将于 6 月底发布。这些新功能包括在 Array 和 TypedArray 原型上添加 findLast() 和 findLastIndex() 方法、标准化 Hashbang 语法、允许使用符号作为 WeakMap 键以及在 Array.prototype 上添加返回新副本的方法等。这些功能都已达到第 4 阶段,并预计将包含在即将发布的 ECMAScript 版本中。

https://pawelgrzybek.com/whats-new-in-ecmascript-2023/

MDH 前端周刊第 97 期:Vite 4.3、Node 20、pretty-ts-errors、React Query 5

· 11 min read
加菲猫

image

题图:rainy day, a water wheel in the green river, green plants and flowers in the foreground, mountains and water in the distance。

📒 【第2924期】如何在 Gitlab 中使用 ChatGPT 进行 CodeReview

📒 「Go框架」深入理解gin框中Context的Request和Writer对象

📒 聊聊React中的隐藏彩蛋功能

⭐️ Go内存分配与逃逸分析

一文详解Go内存分配与逃逸分析

Go 为什么性能高? 一文带你了解“逃逸分析”

先聊聊「内存分配」,再聊聊Go的「逃逸分析」

「刷起来」Go必看的进阶面试题详解

Go内存分配和逃逸分析-实践总结篇

通过实例理解Go逃逸分析

『每周译Go』Go如何做逃逸分析

📒 给想玩AI的新手|Stable Diffusion 保姆级入门手册

⭐️ Go 方法接收器:选择值接收器还是指针接收器

⭐️ Go 内存模型

Go 内存模型

Happens before 原则在 Go 内存模型中的应用举例

『每周译Go』更新Go内存模型

参考:

https://go.dev/ref/mem

https://research.swtch.com/gomm

⭐️ sync.RWMutex 设计与实现

⭐️ Go 单元测测时尽量用 fake object

📒 定制自己的文档问答机器人

⭐️ Go语言中常见100问题-#33 Making wrong assumptions during map iterations

📒 我把我的简历丢给chatGPT,他问了我这些问题

⭐️ sync.Mutex 设计与实现

📒 React的并发悖论

📒 How I improve my skills in Typescript #2 : Mapped Type

📒 TypeScript 4.9 satisfies

https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator

# TypeScript 4.9: satisfies operator

# Typescript’s new ‘satisfies’ operator

⭐️ Go语言中常见100问题-#72 Forgetting about sync.Cond

⭐️ Golang package sync 剖析(二): sync.WaitGroup

⭐️ Golang package sync 剖析(三):sync.Cond

⭐️ Golang package sync 剖析(四):sync.Map

⭐️ Golang语言标准库 sync 包的 Cond 怎么使用

⭐️ Go标准库sync.Cond详解 | Gopher Daily (2021.04.13) ʕ◔ϖ◔

⭐️ sync.WaitGroup 设计与实现

📒 实践指南-前端性能提升 270%

⭐️ Bytes 发布 React, Visualized 教程

⭐️ Mastering React: Techniques to Take Your UI to the Next Level

⭐️ Go 语言中没有枚举类型,但是我们可以这样做

📒 React Query 完全指南,时下最热辣的请求库!

📒 React 中文周刊 #136 - “forwardRef()”: 如何将 ref 传给子组件

📒 gin框架中如何让日志文字带颜色输出

⭐️ sync/atomic 设计与实现

⭐️ 理解unsafe-assume-no-moving-gc包

📒 做量化交易发愁写代码?一招教你白嫖GPT智能编程神器(重制版)

📒 Uber实践:运维大型分布式系统的一些心得

📒 Go 语言怎么通过通信共享内存

⭐️ Go设计模式--备忘录模式,带暂存的业务功能可以参考它来实现

📒 一文带你快速入门TLS/SSL

⭐️ Go 汇编语言快速入门

📒 MDH 前端周刊第 96 期:lazyrepo、CodeWhisperer、taxonomy、WP Playground、MVP

《GitHub - ds300/lazyrepo: 用于 npm/pnpm/yarn monorepos 的缓存任务运行器。》。lazyrepo 是一个针对 npm/pnpm/yarn monorepos 的零配置缓存任务运行器。它适合于 turborepo 所开创的领域:使 package.json “scripts” 扩展,而无需采用像 nx、bazel、rush 或 buck 这样的大型工业级构建系统。lazyrepo 非常快速,尽管它是用 TypeScript 编写而不是一些年轻、英俊、聪明、有趣的系统语言,但它比 turborepo 要快得多。

https://github.com/ds300/lazyrepo

《ChatGPT 的工作原理:深入探究 | Dan Hollick 🇿🇦》。本文介绍了大型语言模型 ChatGPT 的工作原理。这些模型通过计算输入和输出之间的概率来预测下一个单词或符号。为了实现这一点,它们使用神经网络来处理输入并生成输出的概率。在简单的情况下,神经网络由输入层、隐藏层和输出层组成,其中每个神经元都与相邻层中的神经元相连,并具有一个权重。当输入值通过神经元时,它会乘以该神经元的权重,并将结果传递给下一层中的所有神经元。然后,神经元将这些值相加,并将结果压缩到 - 1 到 1 之间,并将其传递给下一层中的每个神经元。最后一个隐藏层的神经元也是如此,但是将值压缩到 0 到 1 之间,并将其传递到输出层。

https://typefully.com/DanHollick/yA3ppZC

《在页面退出时显示未保存的表单数据警告。》。本文介绍了如何实现一个 FormPrompt 组件,以提高 Web 应用程序的用户体验。该组件可以在用户尝试离开具有未保存更改的页面时发出警告。作者讨论了使用纯 JavaScript 的 beforeunload 事件处理此类情况,以及使用 React Router v5 中的 Prompt 组件和 React Router v6 中的 useBeforeUnload 和 unstable_useBlocker 钩子的 React 特定解决方案。

https://claritydev.net/blog/display-warning-for-unsaved-form-data-on-page-exit

《Amazon CodeWhisperer,个人免费使用,现已普遍提供 | Amazon Web Services》。Amazon CodeWhisperer 是一款实时 AI 编码助手,现已正式推出。它可以帮助开发人员快速、安全地编写代码,而无需离开他们的 IDE 进行研究。CodeWhisperer 可以在多个 IDE 中使用,包括 Visual Studio Code、IntelliJ IDEA 等,并支持 Python、Java、JavaScript、TypeScript 和 C# 等多种语言。此外,它还具有筛选可能被认为是有偏见或不公平的代码建议的功能,以及扫描生成和开发人员编写的代码以查找难以检测的漏洞并提供修复建议的安全扫描功能。CodeWhisperer 的个人版免费使用,可通过电子邮件注册。专业版则提供了更多的管理功能和安全扫描限制。

https://aws.amazon.com/blogs/aws/amazon-codewhisperer-free-for-individual-use-is-now-generally-available/

《用 LLM 替换我的最好的朋友,训练了 50 万个群聊消息》。作者用一个大型语言模型训练了他和他的好友们在大学时期使用的聊天记录,并通过 Modal 和 Hex 完成了这个项目。作者将原始聊天数据转换成了可供微调的格式,然后使用 LLaMa 进行微调。最终,作者将模型部署到了 Modal 上,并建立了一个类似于 iMessage 的前端界面,使得所有人都可以与 “机器人男孩” 聊天。作者强烈鼓励大家尝试这种无聊但复杂的 AI 项目,因为它是一个入门级别的 AI 项目,可以让你更深入地了解 LLMs 以及如何针对特定场景进行微调。

https://www.izzy.co/blogs/robo-boys.html

《RFC:next/third-parties・vercel/next.js・讨论 #48256》。Next.js 计划推出 next/third-parties 包,以简化开发人员在应用程序中加载流行第三方库的体验。该包将提供预配置的包装器组件,以确保流行的第三方资源能够高效加载,并随着最佳实践的演变而持续高效。为了避免增加 Next.js 的安装 / 包大小,这个包可以单独存在于核心 next 库之外,但仍然在同一个 monorepo 中。此外,Next.js 还将考虑支持其他流行的第三方库,例如 Sentry、DataDog 和 Facebook Pixel。

https://github.com/vercel/next.js/discussions/48256

《有两种类型的软件工程师》。这篇文章探讨了两种软件工程师的思维方式。第一种类型认为问题很容易解决,只需要要求人们做 X 即可。而第二种类型则认为问题很难解决,因为它需要人们去做 X。第一种类型认为只要不是技术问题就很容易解决,因为 “我们可以要求人们做 X”。而第二种类型则认为这很难,因为它不是技术问题。作者称第一种类型的工程师相信大写字母 E 的工程学,认为存在着冷酷、坚实的真理;有数学和物理;是应用科学。而第二种类型的工程师则更注重人,他们知道在所有的工程工作(和问题)中,人是核心所在。他们接受了事情变得混乱的事实,并迎接了一个更大的挑战,尽管这会带来混乱,但仍然要做出有价值和有影响力的工作。

https://registerspill.thorstenball.com/p/two-types-of-software-engineers

《最有价值程序员》。本文讨论了成为最有价值的程序员(MVP)的概念。与 “最小可行产品” 类似,MVP 并不是一个具体的概念,而是一个追求的目标。这篇文章提供了一些建议,帮助程序员成为更有价值的人,包括不要过度关注代码风格、正确性、DRY 和性能,而是关注业务需求、解决问题以及与同事沟通。此外,作者还提到了保持身心健康的重要性,因为只有这样才能保持高效率和创造力。

https://arendjr.nl/2023/04/mvp-the-most-valuable-programmer

MDH 前端周刊第 96 期:lazyrepo、CodeWhisperer、taxonomy、WP Playground、MVP

· 9 min read
加菲猫

image

题图:an asian city, in the style of japanese traditional art influence。

⭐️ Go 1.20.3 又是一堆安全问题,我们还是抽空更新一下吧

⭐️ 技术文章配图指南

📒 2023 年如何搭建新的 React 项目

1、create-next-app

$ pnpm create next-app@latest nextjs-app

2、create-t3-app

了解了下 T3 App 架构。T3 App 是一套全栈的技术栈,一个脚手架,包含客户端的 Next.js、Tailwind,服务端的 Prisma、Next Auth,API 侧的 tRPC。主打类型安全,所以 T3 的 T 即 Typed(类型安全)。3 个 T 分别是 React 前端、数据库客户端和 API 调用端的类型安全。

image

T3 App 的 3 个理念值得学习。1)解决问题,不添加「所有」东西,只加能解决问题的技术,2)负责任的做技术革新,在风险小的地方使用风险大的技术,3)类型安全不是可用可无,因为可以提高生产力和减少错误发生。

全栈技术栈除了 T3 App,还有其他选择,见下图。图中有个变化是 Bison 也将切换 GraphQL 到 tRPC,他们还写了文章介绍他们《为啥舍弃 GraphQL 而选择 tRPC》(Why we ditched GraphQL for tRPC),主要原因是,1)可以少写一半的样板代码,2)避免不必要的代码生成,tRPC 基于类型推导,3)Client 包尺寸,GraphQL 是 tRPC 的 3.5 倍,4)tRPC 可结合 React Query 使用,Apollo 搞不太好的缓存啥的都属于基础功能。

image

tRPC 发布 10,似乎正在成为越来越多人的选择,不仅是 T3 App 技术栈的选择,同时 Bison 团队也写了文章介绍他们《为啥舍弃 GraphQL 而选择 tRPC》

Tailwind 其实不是类型安全的,需要借助编辑器辅助。比如 VSCode 要装 Tailwind CSS IntelliSense,WebStorm 则是内置支持。

NextAuth 内置的是 Discord 登录,因为配置最简单,只要在 .env 里提供 token 即可,也可稍做配置切换到 github、twitter、google 等登录方式。

部署时可以把数据库部署到 Railway 或 PlanetScale,然后把其余部分部署到 Vercel、Railway、Render 或 Fly。Vercel 虽然部署起来简单,但缺点也很明显,问题是在 Lambda 函数里跑 Prisma 会有明显的冷启动时间,性能不太好。

本地实操跑了个 Blog 的 CURD + 部署流程,部署到 Railway 的 postgresql 数据库和 Vercel 的前端,一切顺利。

文档中的「其他推荐」也值得一看,包括数据流、组件库、动画、部署和基础设施、统计等维度的推荐。

$ pnpm create t3-app@latest

参考:

Create T3 App

GitHub - t3-oss/create-t3-app: The best way to sta...

https://dev.to/ajcwebdev/a-first-look-at-create-t3...

Prisma | Next-generation ORM for Node.js & TypeScr...

Railway

Why we ditched GraphQL for tRPC

📒 webpack核心模块tapable源码解析

📒 速度提高几百倍,记一次数据结构在实际工作中的运用

📒 如何终止某个端口运行的进程

发现 VS Code 有个 bug,终端结束 Next.js 服务(在 3000 端口运行)之后再启动,此时发现 3000 端口被占用了,自动改成 3001 端口,说明原先 Next.js 进程还在继续跑。

可以用 lsof -i 命令查看某个端口正在运行的进程 ID:

$ lsof -i :3000

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 61440 garfield 21u IPv6 0x44c3c99e2d153375 0t0 TCP *:hbci (LISTEN)

找到 PID 之后,用 kill 命令终止进程:

$ kill 61440

📒 我问了鹅厂程序员:你们工作中怎么用ChatGPT?如何高效Prompt

⭐️ singleflight 设计与实现

📒 🤩 如何解决 SVG 图片中字体失效的问题

⭐️ Go sync.Once:简约而不简单的并发利器

📒 React 中文周刊 #135 - Dan Abramov 探索 React 服务端组件

⭐️ Go 环境变量 - GODEBUG 详解

📒 2023再谈前端状态管理

📒 Vite 4.3 性能大幅提升!

📒 前端食堂技术周刊第 78 期:WebGPU、Astro 2.2、Node.js 事件循环可视化指南、实用 Web API 规范

📒 useState与useReducer性能居然有区别

⭐️ Go语言中常见100问题-#32 Ignoring the impact of using pointer ...

📒 mysql的varchar字段最大长度真的是65535吗?

📒 几个你不知道却非常实用的JavaScript APIs

⭐️ Go设计模式--访客模式

⭐️ Go 语言 15 个内置函数详解

⭐️ GoLand 2023.1 正式发布,看有哪些新功能

📒 MDH 前端周刊第 95 期:-10x 工程师、Next.js、WebGPU、Chakra UI、写作

  • Vercel Edge Config 已普遍可用。
  • Nextjs v13.3 发布,新路由约定等。
  • Vite v4.3 比 Turbopack 启动快。

《如何成为一名 -10x 工程师》。本文指出,虽然 “10 倍工程师” 可能是神话,但确实存在 “-10 倍工程师”。为了成为一名 “-10 倍工程师”,可以采用以下策略:使 10 个工程师的输出无效;尽可能在开发过程中更改需求以避免责任;创建 400 小时的忙碌工作;让团队执行类似于工作的任务;创建毫无意义的仪式等。此外,还可以浪费 400 小时的编译 / 构建时间,编写毫无意义的测试,将 10 个工程师困在技术讨论中等等。

https://taylor.town/-10x

《程序员被打断:中断和上下文切换的真正成本》。编程中的中断和上下文切换是直接影响程序员日常生产力的两个最昂贵因素。虽然没有永久避免它们的方法,但有一些有趣的策略可以最小化它们的影响。根据各种科学研究,经过中断后需要至少 10-15 分钟才能重新进入 “区域”(Parnin:10,vanSolingen:98)。基于任务的复杂性和你的精神能量,肯定需要更多的时间。当你有很多未完成的代码时,中断发生时,返回到流状态可能会更具挑战性。

https://contextkeeper.io/blog/the-real-cost-of-an-interruption-and-context-switching/

《Next.js 13.3》。Next.js 13.3 发布,新增了社区请求的流行功能,包括:基于文件的元数据 API、动态 Open Graph 图像、应用程序路由器的静态导出、并行路由和拦截等。其中,基于文件的元数据 API 可以方便地自定义页面以改善 SEO 和 Web 共享;动态 Open Graph 图像可以使用 JSX、HTML 和 CSS 生成 OG 图像;应用程序路由器的静态导出支持完全静态导出,可避免在客户端加载不必要的 JavaScript 代码,减小捆绑大小并实现更快的页面加载;并行路由和拦截可以同时在同一视图中呈现一个或多个页面,如复杂的仪表板或模态框。

https://nextjs.org/blog/next-13-3

《从 Webpack 迁移到 Remix》。Remix 宣布推出基于 Webpack 的编译器和开发服务器,以帮助使用 Webpack 的应用程序逐步迁移到 Remix。这个版本可以让用户从第一天开始使用所有的 Webpack 加载器和插件,并逐渐将每个路由迁移到 Remix。Remix 还提供了一个迁移指南,以帮助 Webpack 用户更容易地进行迁移。

https://remix.run/blog/migrate-from-webpack

MDH 前端周刊第 95 期:-10x 工程师、Next.js、WebGPU、Chakra UI、写作

· 9 min read
加菲猫

image

题图:Cute and adorable cartoon Korean girl, along side pet。

⭐️ Go RWMutex:高并发读多写少场景下的性能优化利器

⭐️ Go Mutex:保护并发访问共享资源的利器

⭐️ 学会 Go select 语句,轻松实现高效并发

⭐️ Go 编译器优化

⭐️ 从.go文本文件到可执行文件

📒 深入浅出 Kubernetes Pod 实现原理

⭐️ fasthttp 为什么比标准库快 10 倍

📒 为什么 Python、Go 和 Rust 都不支持三元运算符

为什么 Python、Go 和 Rust 都不支持三元运算符

https://go.dev/doc/faq#Does_Go_have_a_ternary_form

⭐️ 深入探索Go语言的unsafe包,揭秘它的黑科技和应用场景!

⭐️ 从零到一实现 Rust 的 channel 并发处理模型

⭐️ Go 性能加速器:你需要知道的 5 个诀窍和技巧

⭐️ 「刷起来」Go必看的进阶面试题详解

📒 Node 中文周刊 #83 - 新的 npm 包有一半是垃圾包吗

⭐️ 字节跳动开源 Shmipc:基于共享内存的高性能 IPC

⭐️ iptables 的五表五链

📒 前端食堂技术周刊第 77 期:三月登陆浏览器的新功能、Nuxt DevTools、pnpm v8.0.0、重新思考 React 最佳实践、CLI 脚手架工具生态

📒 有趣!深挖推特开源算法;ChatGPT封号对策汇总;ControlNet最全教程;搭建ChatGPT应用;构建开源项目阅读工作流 | ShowMeAI日报

📒 GPT 会上网了!!ChatGPT 插件的原理揭秘

⭐️ Go语言中常见100问题-#31 Ignoring how arguments are evaluated in ...

📒 「每周译Go」在 Go 里面如何使用 Flag 包

⭐️ 一文告诉你哪些map element类型支持就地更新

📒 前端同学都是如何玩转 ChatGPT 的

⭐️ Go 高性能代码的 30 个 Tips

⭐️ ChatGPT 如何辅助我的开发日常

⭐️ CPU 缓存体系对 Go 程序的影响

⭐️ Go 语言标准库 bufio 详解

📒 MDH 前端周刊第 94 期:Socket AI、CSS 遮罩、Qwik RC、Source Map、1000X 工程师

《介绍 Socket AI - ChatGPT 驱动的威胁分析 - Socket》。Socket 宣布推出基于人工智能的源代码分析解决方案,利用 ChatGPT 检查每个 npm 和 PyPI 包。当检测到包中存在潜在问题时,Socket 会将其标记并请求 ChatGPT 对其进行总结。Socket 的 AI 警告应视为建议而非绝对分析,因为 LLMs 的限制意味着跨文件分析等任务仍需持续改进。此外,Socket 还在不断增强静态分析功能,未来预计将进一步整合 LLMs,实现更复杂的 AI 引导分析。

https://socket.dev/blog/introducing-socket-ai-chatgpt-powered-threat-analysis

《使用 Zod 和 JSDoc 进行 JavaScript 类型定义》。本文介绍了如何在纯 JavaScript 文件中使用 JSDoc 注释和 Zod 类型库来推断类型。通过这种方法,可以在编写代码时获得类型提示和检查,并在运行时使用类型。这种方法不需要编译、转换或配置任何东西,因此非常适合小型项目。

https://blog.jim-nielsen.com/2023/types-in-jsdoc-with-zod/

《Twitter 的推荐算法》。Twitter 公布了其推荐算法的工作原理,该算法将每天发布的大约 5 亿条推文缩减到最终出现在用户设备上的少数优质推文。Twitter 的推荐系统由许多相互连接的服务和作业组成,包括从不同的推荐来源提取最佳推文、使用机器学习模型对每个推文进行排名、过滤掉用户已屏蔽的推文等。这篇博客将介绍算法如何为用户的时间轴选择推文。

https://blog.twitter.com/engineering/en_us/topics/open-source/2023/twitter-recommendation-algorithm

《如何拥有充裕的时间》。本文介绍了一种管理时间的技巧,即将相关任务放入一个桶中,让这个桶积累直到满,然后一次性处理。这与试图在数不清的打断管道中捕捉每个任务形成对比,如果你让它们滴答滴答地流逝,它们会将你的一天淹没。作者强调,时间并不是稀缺资源,注意力才是,找到你的桶,培养耐心让它们填满,然后逐个清空。这是 10X 生产力的窍门。

https://world.hey.com/dhh/how-to-have-buckets-of-time-38693993

《发布 react-router@6.10.0・remix-run/react-router》。React Router 6.10.0 发布,增加了一些数据路由标志,包括 future.v7_normalizeFormMethod,可以将 useNavigation() 和 useFetcher() 的 formMethod 字段规范化为大写 HTTP 方法,以与 fetch()(以及某些 Remix)行为对齐。此外,还修复了一些错误,并更新了 @remix-run/web-fetch@4.3.3

https://github.com/remix-run/react-router/releases/tag/react-router%406.10.0

《1000X 工程师》。本文介绍如何通过一系列命令行包装函数来使用 OpenAI API 提高程序员的生产力。作者首先介绍了如何获取 OpenAI API 密钥,然后演示了如何使用 API 来回答各种问题、生成数据集、创建图像等。作者认为,未来的开发者生产力将会是一个重要的竞争优势,而采用借助人工智能的工作流程可能会更加高效。虽然这并不意味着程序员将被替代,但它提供了一种解决模糊领域中更大问题的有趣新方法。

https://kadekillary.work/posts/1000x-eng/

《发布 GitHub Actions 扩展适用于 VS Code | GitHub 博客》。GitHub 发布了官方的 GitHub Actions VS Code 扩展程序的公共测试版。该扩展程序支持编写和编辑工作流程,并帮助用户管理工作流程运行,无需离开 IDE。使用该扩展程序,用户可以在不离开编辑器的情况下管理工作流程,轻松监控存储库中的工作流程运行,取消和重新运行它们,或者为手动触发的工作流程触发新的运行。此外,用户还可以列出所有受支持级别(组织、存储库和环境)的可用密钥和变量。扩展程序提供了语法高亮、集成文档、验证和代码完成等功能,以提高编辑工作流程的体验。

https://github.blog/2023-03-28-announcing-the-github-actions-extension-for-vs-code/

MDH 前端周刊第 94 期:Socket AI、CSS 遮罩、Qwik RC、Source Map、1000X 工程师

📒 Go语言爱好者周刊:第 183 期 —— Go1 正式发布 11 周年

TiDB 7.0 发布: Go 实现的分布式数据库。

https://docs.pingcap.com/tidb/v7.0/release-7.0.0

ferret 0.18发布: 一个声明式的 Web 爬虫系统,既可以单独使用,也可以嵌入其他 Go 项目使用。

https://github.com/MontFerret/ferret

hertz 0.6.1 发布: 一个 Golang 微服务 HTTP 框架。

https://github.com/cloudwego/hertz

ElasticSearch Go 8.7 发布: ElasticSearch Go 8.7 官方客户端发布。

https://github.com/elastic/go-elasticsearch

为什么 Go 不支持 []T 转换为 []interface

https://mp.weixin.qq.com/s/lG-sswO8i6w_6sMztvyOjw

如何用 Go 进行正确的性能剖析

https://blog.pickme.lk/how-to-get-profiling-right-with-go-813ff89d4757

nats.go: NATS 的 Golang 客户端,云原生消息系统。

https://github.com/nats-io/nats.go

zeropool: Go 的零分配类型安全池,sync.Pool 的替代品。

https://github.com/colega/zeropool

Go语言爱好者周刊:第 183 期 —— Go1 正式发布 11 周年

· 13 min read
加菲猫

image

题图:Landscape illustration, Hayao Miyazaki, in the sea of flowers, clouds, fantastic sky, warm colors, simple composition。

📒 地表最强动画基础库:framer-motion

framer-motion v10.6 特性:animate api 可以控制随时停止、取消、完成。

https://www.framer.com/motion/animate-function/#controls

📒 PromQL 相关内容

Introduction to PromQL, the Prometheus query language

https://promlabs.com/promql-cheat-sheet/

为 Apache SkyWalking 构建 Grafana Dashboard —— 原生 PromQL 支持

📒 学会 Go select 语句,轻松实现高效并发

⭐️ 使用go test框架驱动的自动化测试

📒 面试遇到 性能优化 必答的 9 个点,加分

几点补充:

1、SPA 项目,一个路由对应一个页面,如果不做处理,项目打包后,会把所有页面打包成一个文件

实际 Webpack 打包的时候,会综合考虑 chunk 大小、缓存复用率、减少模块冗余、并行请求数等因素,不一定把 Initial Chunk 打包为单文件,也可以是多个文件,但是这些文件一定是 同步加载 的。

可以参考 optimization.splitChunks 内置分包规则:

https://webpack.js.org/plugins/split-chunks-plugin/#defaults

2、将路由全部改成懒加载,重新打包后,首页资源拆分为 app.js 和 home.js,以及对应的 css 文件,通过路由懒加载,该项目的首页资源压缩约 52%

Code-Splitting 不一定能明显优化首屏加载性能。例如 Initial Chunk 和 Async Chunk 都有一些体积较大的公共依赖,例如 reactreact-domreact-router-dom 等,这种情况下,即使针对每个页面组件做了懒加载,公共依赖仍会被视为同步 chunk(因为首屏加载需要依赖这些公共包),实际异步加载的只有体积很小的业务代码。

当然 Code-Splitting 在特定场景下还是非常有用的,例如有上百个路由的后台管理系统,虽然每个页面的业务代码体积很小,但是首屏一次性加载几百个页面,压力还是有点大(首屏时间随业务规模线性增长)。如果做了路由懒加载,则可以按需加载当前页面的业务代码,保证首屏时间都是 O(1) 复杂度。

3、项目打包后,发现 home.js 和 about.js 均包括了该弹框组件的代码

与第一点类似,Webpack 打包的时候,不仅考虑模块冗余问题,还会考虑减少并行请求数。例如两个以上 Async Chunk 存在公共依赖,若公共依赖体积较小,则 Webpack 可能不会单独抽提 chunk,而是给每个 Async Chunk 都打包一份公共依赖,好处是可以减少网络请求数量。

面试遇到 性能优化 必答的 9 个点,加分!

📒 Go Mutex:保护并发访问共享资源的利器

⭐️ 【补充代码】Go BIO/NIO探讨(3): 基于系统调用实现tcp echo server

📒 「高频必考」Docker&K8S面试题和答案

⭐️ gin框架中Context的Get、Query、Param函数都是从哪里获取数据的

⭐️ 深入解析非阻塞Golang IO框架nbio

⭐️ Go 调试工具 - delve 快速入门

⭐️ Golang反射学习:手写一个RPC

📒 相关链接

推荐部署平台 Railway,可以部署 Docker 容器

https://railway.app/dashboard

谁会拒绝一个免费的部署服务呢

TiDB 是一个开源、云原生、分布式、与 MySQL 兼容的数据库,用于弹性规模和实时分析

https://github.com/pingcap/tidb

⭐️ Go如何自动解压缩包?| 文末送书

⭐️ 高并发系统设计(1): 如何实现抖音关注/粉丝列表

⭐️ Go协程池(2): 如何实现协程池

⭐️ Go协程池(1): 线程vs协程

⭐️ 简洁而不简单的 sync.Once

📒 axios的替代方案的思考和实践

axios 存在哪些问题:

  • 与React、Vue等框架割裂
  • 在性能方面毫无作为(例如没有缓存、无法避免重复请求等等)
  • 臃肿的体积
  • TS 类型定义混乱(在拦截器中对响应数据进行解构,但是接口请求响应的数据还是 AxiosResponse 类型,需要手动用 as 断言)

axios的替代方案的思考和实践

📒 chatgpt逐字逐行回答的效果是如何实现的

一句话总结:通过 Content-Type: text/event-stream 做流式响应。

chatgpt逐字逐行回答的效果是如何实现的

📒 可视化搭建 - keepAlive 模式

⭐️ Go 语言实现创建型设计模式 - 工厂模式

⭐️ 为什么 Go 不支持 []T 转换为 []interface

⭐️ Go设计模式-迭代器到底是不是一个多此一举的模式

📒 MDH 前端周刊第 93 期:npm、sharp images、React Labs、fzf、手写 Signals

《从 ts-node 迁移到 Bun》。本文介绍了如何将一个使用 ts-node 编写的控制台应用程序迁移到 Bun,以及在迁移过程中遇到的一些问题和解决方案。作者发现 Bun 比 ts-node 快 50%,并且迁移过程相对容易。他认为这让他对 Bun 充满信心,并期待未来更多地使用它。

https://johnnyreilly.com/migrating-from-ts-node-to-bun

《加速 JavaScript 生态系统 - npm 脚本》。本文介绍了如何优化 JavaScript 中常用的 “npm scripts”,以减少其约 400 毫秒的开销。作者通过分析 npm CLI 的代码结构,发现大部分时间都花费在加载组成 npm CLI 的模块上。作者通过惰性加载、减小模块图等方式,将运行 npm scripts 的时间从 400 毫秒降至 22 毫秒。作者指出,JavaScript 工具中普遍存在的问题是没有简便的方法来缩短模块图,因此可以考虑在发布时将代码打包,以减少加载时间。

个人理解再总结一下:

1)如何检测 npm scripts。which npm 命令可以拿到 npm 解释器路径,因此可以通过 node --cpu-prof $(which npm) run myscript 运行脚本、生成 profile;

2)惰性加载。通过 profile 可以发现,npm cli 运行大部分时间其实都在加载模块。我们知道,Node 具有 JIT 特性,因此 require 实际上是非常昂贵的(回顾一下 require 加载机制)。建议按需 require,将 require 推迟到要用的时候再去加载,例如放在条件判断里面,可以显著提升 cli 启动性能(例如 Babel 插件、Webpack loader 支持配置字符串而不是传递实例,实际上也是延迟加载);

3)减小模块图。解释器在遇到 top level import or require 语句时,就会加载、解析模块(还是回顾一下 require 加载机制),引起大量文件 IO。与 Web 工程不同,Node 工程可以将所有代码打包到一个单文件中(target: "node"、禁用 Webpack 默认分包规则 optimization.splitChunks.cacheGroups.default: false),这样避免了模块加载开销,可以显著提升 cli 应用启动性能。需要注意的是,如果一次性投喂代码太多,还是会影响性能,解法是和上面提到的惰性加载结合用(也就是 Node 不需要 bundle-splitting 分包,但可以用 code-splitting 做异步懒加载)。

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-4/

《如何获得一个酷炫的 NPM 包名?》。本文介绍了如何通过 NPM 的争议政策来申请将占位包的所有权转移给自己。对于长期没有更新或仅仅是占位的包,NPM 工作人员会在 4 周后自动将包的 owner 设置为申请者的用户名。申请者需要发送邮件至包的所有者并抄送 support@npmjs.com,并说明申请转移的原因、包名以及自己的 npm username。

https://unix.bio/posts/how-to-get-npm-package-name

《您可能不需要的 Hooks》。本文介绍了 React Hooks 中一些不太常用的 Hook。

https://reacttraining.com/blog/hooks-you-probably-dont-need

《React Labs:我们正在进行的工作》。React Labs 发布了最新的研究进展,包括 React Server Components、Asset Loading、Document Metadata、React Optimizing Compiler、Offscreen Rendering 和 Transition Tracing 等。其中,React Server Components 是由 React 团队设计的一种新的应用架构,提供了一种新的组件类型 —— Server Components,它们可以在构建期间运行,也可以在服务器上运行,让您无需构建 API 即可访问数据层。另外,React Labs 还在开发 Suspense、Transition Tracing 等功能,以提高 React 的性能和用户体验。

https://react.dev/blog/2023/03/22/react-labs-what-we-have-been-working-on-march-2023

《GitHub Copilot X:AI 动力的开发者体验 | GitHub 博客》。GitHub Copilot X 是 GitHub 的新一代 AI 辅助开发工具,它将 AI 引入整个开发生命周期中。除了自动完成注释和代码外,Copilot X 还支持聊天和语音交互,并在 pull requests、命令行和文档中提供 AI 支持。Copilot X 基于 OpenAI 的 GPT-4 模型,可以为开发人员生成单元测试、修复错误等。此外,Copilot X 还支持针对文档的 ChatGPT 接口,让开发人员能够快速获取关于 React、Azure Docs 和 MDN 等文档的答案。

https://github.blog/2023-03-22-github-copilot-x-the-ai-powered-developer-experience/

《如何在 2023 年开始一个 React 项目》。本文介绍了几种新 React 项目的起始套件,包括 React with Vite、React with Next、React with Astro 等。作者对每种套件的优缺点、开发者所需技能水平以及针对 React 开发者提供的特性进行了分析,并给出了不同需求的三种解决方案。最后,文章总结了一些关于 React 起始项目的思考和建议。

https://www.robinwieruch.de/react-starter/

《使用 useImperativeHandle 进行细调 refs》。本文介绍了在 React 中使用 refs 和 useImperativeHandle 的方法。Refs 是一种用于在组件之间传递数据的机制,可以让你访问 DOM 节点并使用原生 JavaScript DOM API 对其进行操作。useImperativeHandle 允许你自定义要公开的 ref 处理程序,以便只公开子组件的特定方法。然而,需要注意的是,在 React 中,最好不要使用 refs 来实现可以通过 props 实现的命令式行为,因为这违反了 React 的核心原则。

https://prateeksurana.me/blog/fine-tuning-refs-with-useimperativehandle/

Umi 例行每周四发一版,我觉得有趣的功能包括,1)基于 Rust 实现类 es-module-lexer 解析器用于 prepare 阶段采集 import 数据,2)配置校验陆续从 joi 迁移到 zod,3)新增 umi? 命令,这是框架结合 openai 的第一个尝试,4)MFSU 支持 WASM。

📒 Golang 相关文章

The one-and-only, must-have, eternal Go project layout

https://appliedgo.com/blog/go-project-layout

OpenAI 的 Golang SDK,包括 ChatGPT、GPT-3、GPT-4 等。

https://github.com/sashabaranov/go-openai

一个检测结构体是否可以占用更少内存的工具。

https://github.com/dkorunic/betteralign

基于 Docker 的热重载开发。

https://github.com/dkfbasel/hot-reload

📒 Go语言爱好者周刊:第 182 期 —— GPT Go SDK

- - + + \ No newline at end of file diff --git a/2023/page/5/index.html b/2023/page/5/index.html index df4a51ccb1..48496f37e8 100644 --- a/2023/page/5/index.html +++ b/2023/page/5/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 11 min read
加菲猫

⭐️ Go开发命令行程序指南

⭐️ Go 内存模型

📒 ChatGPT推出插件功能:可联网、可执行代码

📒 【webpack核心库】耗时7个小时,用近50张图来学习enhance-resolve中的数据流动和插件调度机制

📒 Go每日一库之Pie :一个高性能、类型安全的slice操作库

📒 基于 openai 开发 CLI 工具

https://platform.openai.com/docs/guides/completion/introduction

https://platform.openai.com/docs/api-reference/authentication

https://github.com/sashabaranov/go-openai

⭐️ 源码阅读 - 切片扩容过程

⭐️ 聊聊Go语言的全局变量

⭐️ 「高频必考」Go并发编程面试题和答案

📒 ECMAScript 2023 有哪些更新

⭐️ 「从0实现React18系列」Reconciler架构的双缓存树实现原理

📒 monorepo 相关文章

monorepo工作流基础之changesets打开与进阶

https://sakina.blog.csdn.net/?type=blog

https://modernjs.dev/guides/topic-detail/changesets/release-pre.html

⭐️ Lazy Loading Routes in React Router 6.4+

📒 如何规范地发布一个现代化的 NPM 包

⭐️ 「Go框架」bind函数:gin框架中是如何将请求数据映射到结构体的

⭐️ 基于性能分析的优化预览

📒 做量化交易发愁写代码?一招教你白嫖GPT-4智能编程神器

⭐️ Go 语言并发模式代码模板

⭐️ 「从0实现React18系列」Fiber架构的实现原理

⭐️ 「从0实现React18系列」自己动手实现一个JSX转换

⭐️ Go 错误处理:100+ 提案全部被拒绝,为何现阶段仍用 if err != nil

⭐️ 如何做好表结构设计

📒 React 中文周刊 #132 - Vite 简介以及为什么使用它来替代 Create React App

📒 TypeScript 5.0 已发布!看看增加了什么新功能

📒 Chrome 101:fetchpriority

⭐️ Go Slice 扩容的这些坑你踩过吗

📒 Three.js 进阶之旅:物理效果-碰撞和声音 💥

📒 Three.js 进阶之旅:新春特典-Rabbit craft go 🐇

⭐️ Go 语言自带设计模式

⭐️ 「每周译Go」在不同的操作系统和架构编译 Go 应用

📒 你可能不知道的 async、await 细节

async函数在抛出返回值时,会根据返回值类型开启不同数目的微任务

  • return 结果值:非 thenable、非 promise(不等待)
  • return 结果值:thenable(等待 1个 then 的时间)
  • return 结果值:promise(等待 2个 then 的时间)

await右值类型区别

  • 接非 thenable 类型,会立即向微任务队列添加一个微任务 then,但不需等待
  • thenable 类型,需要等待一个 then 的时间之后执行
  • Promise 类型(有确定的返回值),会立即向微任务队列添加一个微任务 then,但不需等待

你可能不知道的 async、await 细节

⭐️ Go语言中常见100问题-#30 Ignoring the fact that elements are copied

⭐️ Go 语言实现创建型设计模式 - 单例模式

⭐️ 聊聊godoc、go doc与pkgsite

📒 把React新文档投喂给 GPT-4 后

📒 MDH 前端周刊第 92 期:react.dev、npm 安全、Execa 7、Reactivity、React Query

《介绍 react.dev》。React 官方文档网站已经更新,现在的网址是 react.dev。新网站教授使用函数组件和 Hooks 的现代 React,并包括了图表、插图、挑战和 600 多个交互式示例。旧版 React 文档网站已移至 legacy.reactjs.org。新网站分为 “学习 React” 和 “API 参考” 两个主要部分,前者是一个自定进度的课程,后者提供每个 React API 的详细信息和用法示例。新网站还添加了很多沙盒,让用户可以快速玩转 React API、探索想法并检查理解。

https://react.dev/blog/2023/03/16/introducing-react-dev

《介绍 “安全 npm”,一个 Socket npm 包装器 - Socket》。Socket 推出了一款名为 “safe npm” 的 CLI 工具,用于保护开发人员在使用 npm install 时免受恶意软件、拼写错误、安装脚本、抗议软件和遥测等方面的影响。该工具透明地包装了 npm 命令,并在安装过程中保护开发人员免受恶意软件、拼写错误、安装脚本、抗议软件、遥测等 11 种问题的影响。

https://socket.dev/blog/introducing-safe-npm

《GitHub - gajus/turbowatch:Node.js 的极速文件变更检测器和任务编排工具。》。Turbowatch 是一个用于 Node.js 的极快文件更改检测器和任务编排器。它可用于自动化响应文件更改的任何操作,例如运行(并自动重新启动)长时间运行的进程(如您的 Node.js 应用程序)或构建资产(如 Docker 镜像)。

https://github.com/gajus/turbowatch/

《JulesBlom.com - React API 地图》。这篇文章介绍了一种学习 React API 的方法,即通过将其组织成一个空间地图来帮助理解。作者将 React 的不同部分联系在一起,形成了一个可供探索的结构,并在 “推荐阅读” 部分中添加了一些经过筛选的优质博客文章链接,以便更好地理解 React API。

https://julesblom.com/writing/map-of-react-api

《发布 v6.9.0・remix-run/react-router》。React Router 发布了 6.9.0 版本,支持使用 React 组件定义路由元素和错误元素字段。此外,还引入了 Lazy Route Modules,以保持应用程序包的小巧和支持代码分割路由。此功能通过 lazy () 路由属性实现,是一个异步函数,解析路由定义的非匹配部分。

https://github.com/remix-run/react-router/releases/tag/react-router%406.9.0

《Execa 7 的无 Shell 脚本 | ITNEXT》。Execa 7 提供了类似于 zx 的模式,但采用更简单的纯 JavaScript 方法。使用 Execa,不需要记忆任何 shell 语法,几乎所有特定于 shell 的功能都可以在 JavaScript 中表达。

https://itnext.io/shell-free-scripts-with-execa-7-885fb3b42f83

《2023 年每个前端开发人员都应该知道的 6 个 CSS 片段》。本文介绍了六个有用的 CSS 技巧,包括使用容器查询、创建滚动吸附效果、避免使用 grid 的 position: absolute、快速制作圆形、使用层叠样式表(cascade layers)控制变体和使用逻辑属性(logical properties)来减少代码量。

https://web.dev/6-css-snippets-every-front-end-developer-should-know-in-2023/

《Nuxt 3.3》。Nuxt.js 发布了新版本,增加了本地模块开发、自动重启服务器和性能优化等功能。该版本还提供了一些新的组件和可组合函数,包括错误处理组件 <NuxtClientFallback> 和处理不受信任用户输入的 useHeadSafe 可组合函数。此外,该版本还改进了类型定义和 Nitro 引擎,支持自定义配置模式,并且有更好的 Chrome DevTools 支持。

https://nuxt.com/blog/v3-3

《深入探究 TanStack 查询中的突变》。TanStack Query 有三个主要概念:查询、变异和查询失效。本文将重点介绍变异,包括变异的副作用、失效和并行实现。通过使用 useMutation Hook,可以轻松地处理所有更新、创建和删除请求。同时,乐观更新是使用 TanStack Query 变异的关键优势之一。

https://blog.logrocket.com/deep-dive-mutations-tanstack-query/

《React Hooks 是一个错误吗?| jakelazaroff.com》。本文探讨了 React 编程模型的不同之处,以及为什么有些人更喜欢使用 signal-based components。作者认为,人们对组件的心理模型与 React 中的函数组件和 hooks 的工作方式不匹配。与类组件相比,signal-based components 更加相似。文章还介绍了 Solid 等信号驱动框架,并讨论了它们与 React hooks 之间的区别和权衡。最后,作者总结说,现在的框架似乎正在尝试在 hooks 的可组合性和类的稳定性之间取得平衡。

https://jakelazaroff.com/words/were-react-hooks-a-mistake/

《基于 React Query 的请求防抖》。React Query 不支持 deboucing,因此需要将其包装在一个简单的抽象中。作者提出了一种方法来扩展 React Query 以添加新功能,代码行数少于 40 行。通过动画演示,展示了防抖的实际效果,使用防抖后,应用程序只触发了 1 个请求并交换了 294 B 的数据,请求减少了 91%,传输的数据减少了 99%。

https://rafaelcamargo.com/blog/deboucing-requests-with-react-query/

《零配置类型安全》。SvelteKit 现在可以自动生成类型注释,无需手动添加。通过在 SvelteKit 应用程序中添加类型注释,可以实现网络全面的类型安全性。现在,SvelteKit 框架可以为我们类型化 load 和 data,这是计算机所擅长的 —— 让我们专注于创造性的工作。使用 VSCode 的用户只需升级到最新版本的 Svelte 扩展即可,其他编辑器的扩展也可以使用此功能,只要它们支持 Language Server Protocol 和 TypeScript 插件。

https://svelte.dev/blog/zero-config-type-safety

MDH 前端周刊第 92 期:react.dev、npm 安全、Execa 7、Reactivity、React Query

📒 Go语言爱好者周刊:第 181 期 —— ChatGPT + Golang

· 11 min read
加菲猫

📒 小技巧集合

新学到一个省时间的技巧,随机分支,再也不需要为分支名发愁了!我写了个自定义脚本,会随机 checkout 到名为「sorrycc-xxxx」的分支。脚本大致逻辑是这样,const length = 4;const id = (Math.random() * 1e20).toString(36).substring(0, length);await $反引号git checkout -b sorrycc-${id}反引号;

gh 命令可以在命令行里操作 github,比如提 PR、绑定 ssh key 等,相见恨晚。

https://github.com/cli/cli

利用 openai 帮你写 commit 信息,可以省去部分重复劳动,适用于对 commit 信息要求不高的业务项目。

https://goonlinetools.com/snapshot/code/#42rshrrrk3gq5h171lxiu

在「Privacy & Security > Developer Tools」里把 Terminal 等开发者工具加上,绕开系统的安全策略,据说可以让请求和编译更快。

习惯用 Purrple Cat 作为工作背景音。

查 IP 或运营商数据可在命令行中输入「curl cip.cc」。

换了个 VSCode 主题「Nako」,红色系,挺好看。

📒 dynamicgo 开源 :基于原始字节流的高性能+动态化 Go 数据处理

⭐️ Go语言中嵌入类型的一些重要规则,你知道多少

⭐️ Go 高性能 - channel 缓冲区

⭐️ Go 高性能 - singleflight 防止缓存击穿

📒 开源工作者福音,用 ChatGPT 评审 Pull Request,解决双手又能多提交两个commit了

📒 【webpack核心库】耗时7个小时,用近50张图来学习enhance-resolve中的数据流动和插件调度机制

⭐️ 并发编程--协同等待WaitGroup的最佳实践

⭐️ 一文搞懂Go subtest

📒 Webpack 最近的任意代码漏洞是怎么回事

⭐️ Go语言中部分实现的接口(技巧)

⭐️ 别乱用了,用新的。Go SliceHeader 和 StringHeader 将会被废弃!

📒 拒绝搬运文档,从实际出发介绍几个开发中用得上的TypeScript技巧

⭐️ Go 高性能 - timer 内存优化到 0 分配

⭐️ Go 高性能 - defer 优化

📒 .vue 怎么变成 .js,我们来试一试!看完会更懂 Vue 吗

⭐️ Go 高性能 - 对象池

⭐️ Go 高性能 - 切片过滤器

⭐️ 【译】该如何使用合理 Go 语言的 struct

⭐️ 【译】Go语言:使用 Singleflight 优化你的代码

⭐️ 【Go官方博文】Go 切片:用法和内部结构

⭐️ 【译】Go语言:深入探究 array 与 slice

⭐️ Go 中的性能分析和执行跟踪

⭐️ Go 语言中接口嵌入接口

📒 2个奇怪的React写法

⭐️ Go 开源库推荐

Generic goroutine pool: Submit, Map, Async

⭐️ Learn Go with tests

https://studygolang.gitbook.io/learn-go-with-tests

https://quii.gitbook.io/learn-go-with-tests/

📒 React 中文周刊 #131 - React hooks 是一个错误吗

⭐️ Go 高性能 - 互斥锁和读写锁

⭐️ Go是一门面向对象编程语言吗

⭐️ 「每周译Go」如何在 Go 使用 interface

⭐️ Go设计模式--桥接模式,让代码既能多维度扩展又不会臃肿

⭐️ Go语言中常见100问题-#29 Comparing values incorrectly

📒 深入理解Render阶段Fiber树的初始化与更新

📒 你不知道的 async、await 魔鬼细节

📒 2023 年 Web 框架性能报告

⭐️ Go 语言各个版本支持 Go Modules 的演进史

📒 MDH 前端周刊第 91 期:代码提取、Turborepo、Farm、React 常见错误、tRPC、技术债

pnpm v8.0.0-beta.0 发布,默认去除重复对等依赖项等。

  • auto-install-peers is true by default
  • dedupe-peer-dependents is true by default
  • The registry field is removed from the resolution object in pnpm-lock.yaml
  • save-workspace-protocol is rolling by default
  • resolve-peers-from-workspace-root is true by default

https://github.com/pnpm/pnpm/releases/tag/v8.0.0-beta.0

《WTF 是代码提取?》。本文介绍了一种新的开发方式 —— 代码共存(code collocation),即将服务器端和客户端代码放在同一个文件中。作者认为这种方式可以提高开发效率,因为大部分代码都在两个位置上运行,没有必要将它们分开成不同的文件。然而,由于服务器端和客户端有不同的限制,需要将它们分开并创建代码包。文章介绍了三种策略:导出抽取、函数抽取和闭包抽取,并详细解释了如何使用这些策略来实现代码共存。最后,作者还介绍了一种称为 “标记函数” 的方法,可以让开发者自定义标记以及相应的转换过程。(编者注:元框架开发必备技能)

https://www.builder.io/blog/wtf-is-code-extraction

《为什么 Turborepo 从 Go 迁移到 Rust - Vercel》。Turborepo 是一个用于 JavaScript 和 TypeScript 代码库的高性能构建系统。该系统通过增量构建、并行执行和远程缓存来避免重复工作。随着使用量的增加和产品需求的变化,Turborepo 决定从 Go 逐步迁移到 Rust。该迁移主要基于 Rust 的正确性、强大的生态系统以及开发人员的愉悦度等因素。Turborepo 正在采取渐进式的迁移方式,目前已经实现了 “Rust-Go-Rust Sandwich” 的状态,即 Rust 是入口点,可以选择使用 Rust 或 Go 来实现特定命令的功能。

https://vercel.com/blog/turborepo-migration-go-rust

《如何为你完全不了解的项目做出贡献?》。本文介绍了一个名为 Bun 的 JavaScript/TypeScript 运行时,它与 Deno/Node 类似,但具有更快的启动时间。作者通过编写测试套件来测试 Bun 的性能,并在测试过程中遇到了问题。作者分享了自己处理问题的方法,包括询问前任维护者、规范功能 / 问题、运行测试、编写测试用例并更改代码等步骤。

https://grifel.dev/how-to-contribute-without-knowledge

《比 Vite 快 5 倍?2ms HMR?Farm:基于 Rust 的极速构建引擎!》。Farm 是一个使用 Rust 编写的构建引擎,比 Webpack 快 10 倍以上,比 Vite 快 5 倍。它支持 HTML、CSS、JavaScript、静态资源等模块的编译能力,并且采用按需编译,在加载时编译除首屏需要的模块外的其他模块,理论上对任意规模的项目都能支持秒启动。所有能力都由插件实现,支持 Rust 和 Js 插件。

https://zhuanlan.zhihu.com/p/611603260

《React 初学者常见错误》。这篇文章介绍了 React 开发中常见的 9 种陷阱,包括:使用零进行条件判断、直接修改状态、未生成 key、缺少空格、在更改状态后访问它、返回多个元素、从不受控制到受控制的转换、缺少样式括号和异步效果函数。对于每种陷阱,文章都提供了解决方法,并给出了示例代码。

https://www.joshwcomeau.com/react/common-beginner-mistakes/

《@githubnext/github-copilot-cli》。GitHub Copilot CLI 是一个命令行体验,可以让 GitHub Copilot 在命令行中帮助你。它将自然语言转换为 shell 命令,并具有不同领域的模式。安装后,您可以使用以下三个命令:??:将自然语言翻译为任意 shell 命令;git?:将自然语言翻译为 Git 命令;gh?:将自然语言翻译为 GitHub CLI 命令。(编者注:装完再也没用过,因为 git 命令已成肌肉记忆)

https://www.npmjs.com/package/@githubnext/github-copilot-cli#whats-the-point-of-the-eval-and-alias-stuff

《使用 tRPC 和 React 的全栈 TypeScript》。tRPC 是一种使用 TypeScript 在全栈应用程序中创建完全类型安全 API 的方法。 tRPC 服务器应用程序生成具有类型安全函数的类型安全路由器(例如 CRUD 操作:创建用户,按标识符获取用户,获取所有用户),客户端应用程序可以直接调用这些函数。 在幕后,仍然使用 HTTP 在客户端和服务器之间通信。相比 GraphQL 和 REST,tRPC 主要用于较小的项目,其中不需要协调许多服务(例如 GraphQL),或者我们不一定按照标准化的 RESTful 方法工作。但是,随时可以从 tRPC 迁移到 GraphQL / REST,因为 tRPC 最终只是服务器上的函数,可以直接在 REST 路由器或 GraphQL 解析器中使用。

https://www.robinwieruch.de/react-trpc/

《优秀工程师和卓越工程师的区别》。Intercom 的 CTO DARRAGH CURRAN 概述了造就杰出工程师的六个特征。其中包括野心和决心,习惯性简化,快速调试任何东西的能力,愿意帮助别人成为伟大的人,知道什么是有价值的,以及有创造力和积极性。Kotlyar说,工程文化是由被雇用的人、他们采取的行动以及被奖励和赞美的特质所塑造的。

https://www.intercom.com/blog/traits-of-exceptional-engineers/

monorepo 项目用 pnpm publish 可以自动替换 Workspace Protocol 为实际的版本号,可以让发布省不少事。

https://github.com/umijs/umi/pull/10719

MDH 前端周刊第 91 期:代码提取、Turborepo、Farm、React 常见错误、tRPC、技术债

📒 Go语言爱好者周刊:第 180 期 —— 通用 goroutine 池

· 15 min read
加菲猫

⭐️ Go 高性能 - map 优化 (三)

⭐️ Go 高性能 - map 优化 (二)

⭐️ Go 语言中结构体嵌入结构体

⭐️ Go Slice 扩容的这些坑你踩过吗

📒 Go 为什么不像 Rust 用 ?!做错误处理

📒 字节跳动自研 Web 构建工具 Rspack 正式发布

⭐️ 跟着 Go 作者学泛型

⭐️ Webpack 迁移 Rspack 速攻实战教程(前瞻版)

⭐️ Go 高性能 - 内存对齐

⭐️ Go 高性能 - map 优化 (一)

📒 Next.js了解篇|一文带你梳理清楚 Next.js 的功能

📒 Go 在 3.8 妇女节(女神节)发布最新版本 Go 1.20.2 和 Go 1.19.7 安全更新

📒 解析 React 性能优化 API

⭐️ Go 高性能 - 逃逸分析

📒 一篇文章带你理解 React 中最“臭名昭著”的 useMemo 和 useCallback

📒 GSAP从入门到精通

⭐️ 最新最全Go主流框架高频面试题大全

📒 2023 年静态站点生成器 (SSG) 指南

📒 Node.js Toolbox:发现 Node.js 包的一种新方法

https://nodejstoolbox.com/

⭐️ Golang下的ORM框架gorm的介绍和使用

⭐️ 如何使用 splitChunks 精细控制代码分割

📒 浅析 SplitChunksPlugin 及代码分割的意义

📒 5W1H 带你入门 Monorepo

⭐️ 面试官:请说一下如何优化结构体的性能

⭐️ Go 高性能 - 打印调用堆栈

⭐️ Go 高性能 - 结构体优化 (一)

⭐️ Go 高性能 - index vs value in for

⭐️ Go 高性能 - int to string

📒 参考云谦大佬的项目,用 ChatGPT 给前端相关文章写总结

https://github.com/sorrycc/url-system

https://github.com/advancedlogic/GoOse

https://pkg.go.dev/golang.org/x/net/html

📒 前端构建工具进化历程

📒 18个很有用的 CSS 技巧

📒 Go 语言怎么一键生成一个 gRPC 服务

⭐️ Go 最细节篇|内存回收又踩坑了

⭐️ Go设计模式实战--用状态模式实现系统工作流和状态机

⭐️ 「每周译Go」如何在 Go 中使用结构体标签(文末有GIFT)

⭐️ Go设计模式--享元模式,节省内存的好帮手

📒 MDH 前端周刊第 90 期:Signals、Signia、Replit、ChatGPT、CHIPS、技术债

《Demystifying Create React Signals Internals · Daishi Kato's blog》。本文主要介绍了 create-react-signals 库的内部工作原理,这个库的主要目的是将 React 组件中的状态管理从 React 自身分离出来,并使用 signals 来实现状态管理。Signals 是一种包含订阅、获取和设置值等功能的存储对象。文章讲解了如何使用自定义 JSX 转换器将 Signals 转换为可在 React 中使用的组件,以及如何处理对象类型的信号和跳过 diffing 等问题。作者认为,Signals 仍然是 React 中一个开放的研究领域,而使用 Observable 作为新的基元可以进一步探索这种方法。

https://blog.axlight.com/posts/demystifying-create-react-signals-internals/

《The JavaScript Site Generator Review》。该篇文章对当前流行的七种 JavaScript 网站生成器进行了评论。对于 npm 安装时间、客户端 JavaScript 基线、node_modules 权重、npm 审计、遥测(TELEMETRY)等内容进行了测试。其中,有些工具使用创建 x 包来安装依赖,并且包括了帮助用户安装依赖的步骤。然而,这些工具中有一些隐藏了 npm 审计结果(包括关于高严重度的安全漏洞)。还有一些工具默认开启了遥测功能,需要用户选择退出。此外,该文还附带了作者之前的评论和文章链接。

https://www.zachleat.com/web/site-generator-review/

《Effective Higher-Order Components :: Building Better Software Slower》。本文介绍了 React 中的高阶组件(Higher-Order Components,简称 HOC),它是一个接受组件的函数,并在附加逻辑的包裹下返回它。作者指出,虽然 HOC 带来了无限的可能性,但实际应用应限于透明地添加包装或逻辑。同时,作者提出了 HOC 的一些惯例和注意事项,例如 HOC 不应该改变所提供的组件的 API,HOC 应该有一个符合 withNoun 模式的名字,除了组件本身之外,HOCs 不应该有任何参数等等。此外,作者还介绍了一些最常见的 HOC,例如 Props记录、添加格式化等。最后,作者强调,HOC 应该是一个减轻 JSX 精神负担的工具,而不是炫耀函数式编程技巧的机会。钩子是一个更可预测的、明确的模式,但好的 HOC 依然存在并提供了强大的模式。

https://www.bbss.dev/posts/effective-hocs/

《Introducing ChatGPT and Whisper APIs》。OpenAI 宣布,其 ChatGPT 和 Whisper 模型现已可用于 API,让开发者能够使用尖端的语言和语音转文本功能。通过一系列系统级别的优化,自去年 12 月以来,ChatGPT 的成本降低了 90%;现在将这些节省成本传递给 API 用户。开发者现在可以在 API 中使用我们的开源 Whisper large-v2 模型,获得更快速、更具成本效益的结果。Snap Inc.、Quizlet、Instacart 和 Shopify 等公司已经开始使用 ChatGPT API 和 Whisper API。OpenAI 还改进了 API 服务条款以更好地满足开发者的需求。同时,OpenAI 还提供专用实例,使开发者能够深入控制特定模型版本和系统性能。

https://openai.com/blog/introducing-chatgpt-and-whisper-apis

《ChatGPT use case examples for programming - RisingStack Engineering》。本文介绍了一些人们如何在职业网页开发中使用 GPT 等 “AI” 工具。作者分享了他的同事们使用 GPT 及其各种变体的经验,以帮助读者更好地理解它们的实用性。例如,Code GPT 是一个 VS Code 插件,可以从注释提示中生成代码、生成单元测试、查找问题、重构代码、记录和解释代码、以及提出问题。ChatGPT 则可用于编写 Mongo 查询、代替 StackOverflow 等。然而,作者指出,使用这些工具时需要小心检查生成的内容,因为 GPT 可能会产生不对的结果。此外,尽管 “AI” 不会大规模取代就业岗位,但它将提高生产力,就像 Photoshop 是更好的画笔一样。

https://blog.risingstack.com/chatgpt-use-case-examples-for-programming/

《React vs Signals: 10 Years Later》。本文探讨了 JavaScript 中的信号(Signals)技术,以及它与 React 的区别和联系。信号是一种细粒度的响应式编程技术,可以用于前端开发中的数据流管理。尽管在 React 和虚拟 DOM 的兴起中,信号被认为是不可预测和危险的模式,但实际上信号从未消失,而是以第三方库或框架的形式存在。本文介绍了 SolidJS,这是一种新型的信号技术,它采用了组合、单向数据流和显式变异等原则,并将所有东西都视为 Effect,与 React 不同的是,它不会将所有操作视为纯函数,而是通过隔离更新来实现状态变化。作者认为,React 曾经 “修复” 了前端开发,但现在信号技术的复兴又将其推向了新的竞争时代。

https://dev.to/this-is-learning/react-vs-signals-10-years-later-3k71

《I'm not sure I understood this article. I think... — DEV Community》。这是 Dan 对于上一篇文章(Signals 主题)的评论。他探讨了 React 和 Solid 在处理渲染逻辑上的不同策略。React 的核心思想是,能够编写渲染逻辑,使其在初始化和更新时都能够运行,并且不会与传递的数据不同步。Solid 则只有模板中的 “空洞” 是响应式的,因此不能像 React 那样使用 if 语句和控制流。作者认为,Solid 的优点在于可以避免部分逻辑的重新执行,但这并不是最终的理想状态。通过编译器,可以实现在不重组代码的情况下自动确定 “组”,以达到类似 useMemo 的优化效果。最后,作者指出 React 不需要将渲染逻辑从内向外编写才能实现更新,这是 React 默认具备的响应性。

https://dev.to/dan_abramov/comment/256g9

《Remote Access to Your Repls via SSH》。Replit 是一个基于云的编码平台,它的所有付费计划都增加了使用 SSH 远程访问 Repls 的功能。订阅了付费计划的用户可以添加他们的 SSH 密钥,并远程操作他们的 Repl。此举使用户能够充分利用 Replit 的功能,同时继续使用其本地开发环境。Replit 将每个 Repl 放入自己的容器中,一旦连接被打开就会运行。在该容器内,一个 SSH 服务器处理所有远程访问需求。一个代理接收连接,验证密钥,并将 SSH 连接通过加密的 SSH 隧道路由到 Repl。

https://blog.replit.com/ssh

《Introducing Signia》。TLDraw 的开发团队发布了其核心反应式状态管理系统的开源项目 Signia。该库是用于使用基于逻辑时钟的新惰性反应模型处理细粒度反应值(称为 “信号”)的原始库,它诞生的原因是需要高效地处理经常更改的大型派生不可变集合。除了核心库之外,还发布了与 React 绑定的内容。Signia 的 API 类似于 Jotai、@preact/signals 和 Recoil 等类库,其主要区别特征是具有增量派生和内置支持回滚的事务。Signia 的反应性系统基于单个整数,即全局逻辑时钟,每当更新根状态值时,该时钟就会递增。比较时钟值允许 Signia 始终缓存派生值,而不管它们是否正在被积极观察。Signia 的响应式系统基于逻辑时钟和差异,可以实现增量计算派生值。

https://tldraw.substack.com/p/introducing-signia

《The 25 Percent Rule for Tackling Technical Debt》。这篇文章讨论了技术债务的不同类型,并提出了一种 “25% 规则”,即每周花费 10%的时间解决日常技术债务,另外 10%的时间解决每周技术债务,剩下的 5%用于处理每月和每年的技术债务。作者认为,解决技术债务并不是大规模修复的问题,而是通过文化建设来实现。通过改进日常工作中的代码、庆祝重构代码的能力以及知道何时选择好的而不是完美的,可以帮助解决技术债务问题。

https://shopify.engineering/technical-debt-25-percent-rule

《You Don't Need a Build Step》。本文探讨了为什么现代 Web 开发需要构建步骤,以及如何使用 Deno 和 Fresh 等工具实现无需构建的开发。文章介绍了构建步骤的来龙去脉,包括编译、压缩、打包和代码分割等过程,并列举了一些流行的构建工具。作者认为,构建步骤是现代 Web 开发不可避免的一部分,但也带来了复杂性和长时间的构建时间。使用 Deno 和 Fresh 可以实现无需构建的开发,从而提高开发效率和代码质量。

https://deno.com/blog/you-dont-need-a-build-step

《Three ways to activate an inspector in Node.js | pawelgrzybek.com》。本文介绍了三种激活 Node.js inspector 的方法,其中一种是使用 NODE_OPTIONS 环境变量来调试间接运行 Node 的进程。如果您是 Node.js 调试器的新手,可以查看作者之前发布的两篇文章:“在 Google Chrome 中进行基本的 Node.js 调试” 和 “解释 Visual Studio Code 调试器中的继续、步过、步入和步出操作”。

https://pawelgrzybek.com/three-ways-to-activate-an-inspector-in-node-js/

MDH 前端周刊第 90 期:Signals、Signia、Replit、ChatGPT、CHIPS、技术债

📒 Go语言爱好者周刊:第 179 期 —— Google 出品的分布式应用 Go 框架 weaver

· 9 min read
加菲猫

⭐️ 小厂内部私有Go module拉取方案3

📒 知识星球相关文章

269 - 《基于 ChatGPT 的 URL 系统》

268 - 《我的 RSS 订阅》

267 - 《读书笔记:交办的技术》

259 - 《程序员高效工作法》

📒 前端工程 dotfile 相关

umi-fabric - 一个包含 prettier,eslint,stylelint 的配置文件合集

https://github.com/umijs/fabric

tsconfig/bases - 提供各种前端工程的 tsconfig.json 配置

https://github.com/tsconfig/bases

⭐️ 论文分享 | 大语言模型的 few-shot 或许会改变机器翻译的范式

📒 如何使用乾坤实现微前端架构(附 vue + react 演示)

⭐️ 你说 Go 的切片原生支持并发吗

📒 前端组件级别的抽象方向

📒 OpenAI 又放大招了,GPT3.5 API 开放使用,1分钟上手体验!

📒 uni-app 黑魔法探秘 (一)——重写内置标签

📒 「Go工具箱」Pie :一个高性能、类型安全的slice操作库

📒 全网最详细 去中心化 Module Federation的实现原理

📒 最全的React拖拽排序组件库对比研究

📒 掌握 JavaScript 中的迭代器和生成器

📒 CSS容器查询获得主流浏览器支持,是什么?怎么用

⭐️ 一文吃透 Go 内置 RPC 原理

⭐️ 用Go语言0代码10分钟完成一个学生管理系统带页面,私活必备

⭐️ Go 陷阱 - goroutine 竞态

⭐️ Go 陷阱 - interface{} 和 *interface{} 相等吗

⭐️ Redis 官方 Go 客户端来了!!!

Gopher 们应该都有使用过 Redis 吧,那 Go 的 Redis 客户端你用的哪一个呢?

不少人可能用是 github.com/go-redis/redis,毕竟这个 Star 数最多:

最近这个库被 Redis 官方”收“了,成为了 Redis 官方支持的客户端。最新版本 v9 导入地址变为:

import "github.com/redis/go-redis/v9"

Redis 官方 Go 客户端来了!!!

📒 从微信 JS-SDK 出发,一起了解 JSBridge 的神奇功能

📒 人物志|缨缨:一个有故事的女同学

⭐️ 不会「函数选项模式」的Gopher看过来~

📒 前端食堂技术周刊第 72 期:Signals 是前端框架的未来、Chrome Headless、ts-reset、magic-regexp、Bun 新文档

⭐️ 通过 React Router V6 源码,掌握前端路由

📒 MDH 前端周刊第 89 期:HTML-first、Node 调试、Dead 组件探测、框架鹰鸽博弈、沙箱

《Debugging Node.js, The Right Way》。作者介绍了如何使用 Node.js 进行调试,而不是依赖于 console.log()。首先需要使用 --inspect-brk Flag 启动Node.js进程,然后打开浏览器的开发工具,连接到 Node 进程。通过使用调试器语句和添加断点,可以方便地调试代码,并且可以通过添加条件断点来跳过不感兴趣的迭代。文章还介绍了如何在 VS Code 中直接调试,以及如何调试通过 NODE_OPTIONS 启动的 Node 脚本。

https://www.builder.io/blog/debug-nodejs

《Self hosting in 2023》。作者介绍了如何将静态页面托管在树莓派上,以及如何设置自己的 DDNS,从而将域名连接到本地服务器。作者通过购买一个二手的树莓派、安装 Coolify 和 DDClient 等简单的步骤,仅花费了大约一个小时的时间便将博客部署在了自己的本地服务器上。这样做不仅节约了成本,而且提供了更好的开发体验。文章还提到了一些可能的运营成本,如一次性成本、电费、域名费用等。

https://grifel.dev/decentralization/

《React Hooks: Compound Components》。一篇老文,作者介绍了复合组件的概念,以及如何使用 React Context 来创建具有良好表达性和实用性的组件 API 。它使用一个例子来展示复合组件 API 的好处,以及如何使用 React.cloneElement 和 React Context 来实现它。

https://kentcdodds.com/blog/compound-components-with-react-hooks

《Maximising performance with React code splitting techniques》。React 是一个流行的 JavaScript 库,用于构建用户界面,但随着应用程序规模的增长,JavaScript 包的大小会变得很大,导致加载时间慢和性能差。为了解决这个问题,React 提供了多种代码分割技术,允许你将代码分割成更小的块,减少初始 JavaScript 捆绑的大小,提高应用程序的性能。这篇文章介绍了 React 的代码分割技术,包括动态导入、带 Suspense 的 React Lazy、可加载组件、基于路由的代码拆分、预加载、嵌入关键的 CSS 和动态块。

https://edvins.io/react-code-splitting-techniques

《Improved type safety in Storybook 7》。本文介绍了 Storybook 7 中的类型安全改进。Storybook 7为组件 Story 格式(CSF)3和新的TypeScript(4.9+)满足操作者的组合实现了增强的类型安全。新的 Meta 和 StoryObj 类型可以自动推断出组件道具的类型。通过使用 satisfies 操作符,TypeScript现在能够更好地显示这些警告。Storybook 7 测试版中已经可以使用新的 Meta 和 StoryObj 类型。

https://storybook.js.org/blog/improved-type-safety-in-storybook-7/

《The case for frameworks》。本文探讨了 JavaScript 框架的使用和开发者的自我利益,其中涉及了进化博弈论中的鹰鸽博弈概念。文章指出,即使 JavaScript 框架的性能不佳,但由于其在经济层面的优势,它们仍然非常受欢迎。「当71%的开发者已经在使用React时,招聘React开发者就变得容易了,从经济角度来看,这是一个巨大的优势。」React 作为一个具体的JS框架被讨论,并且指出单页应用程序的开发对于某些网站是很有用的,而 React 可以帮助开发者省去时间和成本。「开发人员是昂贵的。他们的工资最终是由客户支付的。但并不是所有的客户都同样有价值。」

https://seldo.com/posts/the_case_for_frameworks

《useSyncExternalStore First Look》。关于 useSyncExternalStore 的介绍。1)useSyncExternalStore 主要是用于库,但不只是用于库。 它是用来订阅外部状态的,但意义比我想象的要广,浏览器是一个外部存储,你可能想在你的 React 应用中与之同步 它是并发安全的,所以可以避免 UI 中的视觉不一致,2)如果订阅函数参数不稳定,React 会在每次渲染时重新订阅到 Store,3)getSnapshot 函数参数必须返回不可变的值,4)其可选的第三个函数参数 getServerSnapshot 是为了支持 SSR 它必须在初始客户端渲染时返回与服务器上完全相同的数据,这意味着你不能在服务器上读取浏览器的API。 如果你不能在服务器上提供一个初始值,通过在服务器上抛出一个错误并将其包裹在边界中来显示一个回退,使该组件只在客户端使用。

https://julesblom.com/writing/usesyncexternalstore

MDH 前端周刊第 89 期:HTML-first、Node 调试、Dead 组件探测、框架鹰鸽博弈、沙箱

📒 Vue3中watch与watchEffect有什么区别

📒 「每周译Go」如何构建和安装 Go 程序

📒 Go语言爱好者周刊:第 178 期 — Go 实现的纸牌游戏

· 5 min read
加菲猫

image

题图:爱心猫

📒 bun 文档网站上线了

https://bun.sh/docs

推荐用来跑 npm scripts,极快。

📒 封装新版axios(v0.22.0)中的取消请求

📒 微前端接入Sentry的不完美但已尽力的实践总结

📒 总是跳转到国内版(cn.bing.com)?New Bing使用全攻略

📒 怎么在5分钟之内跑起来一个完整项目之gin

⭐️ Go 高性能 - 切片比数组快吗

⭐️ Go 高性能 - 切片预分配 N 倍+ 优化

📒 PNPM 如何给第三方库打补丁

https://github.com/antfu/pnpm-patch-i

📒 「Go框架」iris框架中mvc使用进阶

📒 Go1.20 arena 能手动管理内存了,怎么用

⭐️ Go语言空结构体这3种妙用,你知道吗

⭐️ 一文吃透 Go 内置 RPC 原理

⭐️ 外观模式,一个每天都在用,却被多数人在面试中忽视的模式

📒 一起玩转Vue中的JSX:让你一次性掌握它的特性!

📒 分享6款yyds的可视化搭建开源项目

📒 类型编程原理和编写类型安全代码

📒 前端食堂技术周刊第 71 期:LightningCSS、State of React Native、Sandpack 2.0、ChatGPT 与前端、2023

📒 「每周译Go」在 Go 中定义方法

📒 「读源码」为什么注册路由时没有传入上下文,在接口方法中却能取到

⭐️ 一文告诉你如何判断Go接口变量是否相等

📒 PHP vs Go,为什么 Go 不支持命名参数调用函数

📒 MDH 前端周刊第 88 期:错误处理、CSS 嵌套、应用模块化、useWorker

React 实现了下发服务器端函数的引用,类似 RPC 。

https://twitter.com/wongmjane/status/1625166863062958081

React Native 年度报告显示 Turborepo 是最受欢迎的 monorepo 工具。

https://results.stateofreactnative.com/monorepo-tools/

Nextjs 新增了 Api routes 的替代品 route handler 。

https://beta.nextjs.org/docs/routing/route-handlers

React Hook Form 支持跨框架使用了,建议更名为 @tanstack/hook-form,哈哈。

https://github.com/react-hook-form/core

《How to handle errors in React: full guide》。直接 try…catch 会有不少限制,但使用 React 官方的 ErrorBoundary 也有不少限制。这个限制是,React生命周期之外的错误不捕获,比如 resolved promises, async code with setTimeout, various callbacks and event handlers。怎么解?dan 给了个 Hack 方案,简单说就是 try {} catch(e) { setState(() => throw e) }。基于此,我们可以稍微封装下,比如 useThrowAsyncErroruseCallbackWithErrorHandling,这样就不需要每次声明一个新的 setState 了。同时也可以考虑用 bvaughn/react-error-boundary

https://www.developerway.com/posts/how-to-handle-errors-in-react

《TypeScript Brand type with Zod》。Brand Type 可以用来创建一个新类型,比如把 string 包装成 Email。然后结合 Type Guards,即可确保类型安全,又能做数据校验。Type Guards 的部分可以用 zod 。

https://linux-china.davao.page/blog/2023-02-16-ts-brand-with-zod/

《Modularizing React Applications with Established UI Patterns》。好文,作者通过案例教你如何用成熟的 UI 模式把 React 应用模块化。说人话就是,把大组件拆小。几个思路,1)提取子组件以拆分视图,2)提取非视图逻辑到 hooks,3)提取领域模型以封装逻辑。但是也要注意别过度优化。

https://martinfowler.com/articles/modularizing-react-apps.html

《React Component Composition》。图解 Composition。

https://punits.dev/jargon-free-intros/react-component-composition/

Umi 例行每周四发一版,我觉得有趣的功能包括,1)基于 @clack/prompts 优化 create-umi 界面,2)优化命令行执行速度,该 lazyImport 的 lazyImport,同时优化了 @ant-design/icons 集合的读取方式,3)新增 legacy 模式支持做产物的 es5 校验,4)升级 Vite 到 4.1。

Umi 新增 Roadmap 2023,是 Umi 团队每周迭代的一部分,每周四更新,有兴趣共享的同学欢迎直接回 issue 认领。一个非 docs PR 即可加入 Umi Contributor 群。

Umi 团队新增一条规则,每人每周需共享 1-2 个想法,每周三开 Discussion 征集,这是试运行第一周的 Discussion 链接

MDH 前端周刊第 88 期:错误处理、CSS 嵌套、应用模块化、useWorker

📒 Golang 语言标准库 io 详解

📒 Go语言爱好者周刊:第 177 期 — Go 版 ElasticSearch

· 6 min read
加菲猫

image

题图:Bigfish x 情人节。

📒 ChatGPT ✖️ 前端 = 有点er意思

📒 基于gpt3引擎实现CLI版本的chatgpt~(数量取胜的go语言学习法)

📒 基于qwik和iris(go)写全栈啦-短链服务(数量取胜的go语言学习法)

📒 云原生运维相关文章

Linux 命令行工具之 jq 最佳实践

令人拍手叫绝的运维小技巧

2022年 SRE、DevOps技能图谱

Linux 命令工具之 grep

Linux 命令工具之 awk

Golang中的逃逸分析

据说成功人士都是这样管理时间的

📒 告别“复制粘贴”,带你自己配一个Babel

⭐️ Go 陷阱 - 接口方法调用

📒 【面试高频题】难度 4/5,单调栈的热门运用

📒 【第2858期】React 纪录片心得 — 重新思考最佳实践

⭐️ Go 陷阱 - 缓冲区内容不输出

⭐️ 百里挑 15 个 Git 技巧

📒 组件库实战——按需加载工程化

📒 Go 也要过情人节,并发布了安全更新 Go 1.20.1 和 Go 1.19.6

Go 1.20.1 发布了

Go 也要过情人节,并发布了安全更新 Go 1.20.1 和 Go 1.19.6

📒 前端食堂技术周刊第 70 期:Volar 的新开端、Lighthouse 10、良好的组件设计、React 纪录片、2022 大前端总结

⭐️ 聊聊 Ant Design V5 的主题(上):CSSinJS 动态主题的花活

⭐️ Go 高性能 - 字符串拼接 1000+ 倍优化

📒 技术角度告诉你ChatGPT是什么?和一些深度思考

📒 闲鱼大终端UI组件库——FishUI建设之路

📒 ChatGPT 相关

AI量化投资训练营-基础班

https://twitter.com/kliu128/status/1623472922374574080/

https://tanstack.com/

https://platform.openai.com/docs/api-reference/completions/create#completions/create-prompt

https://huggingface.co/datasets/fka/awesome-chatgpt-prompts

https://github.com/f/awesome-chatgpt-prompts

https://github.com/lencx/ChatGPT

📒 细说 Vue 响应式原理的 10 个细节!

📒 MDH 前端周刊第 87 期:re-render、Resumable React、ESLint 性能、监控

《React recursively re-renders child components, but there is a nuance》。Alex Sidorenko 的 React 可视化渲染系列文章 +1。通过可视化的方式告诉你为啥通过 children 渲染子组件,能避免 state 变更时子组件 re-render。

https://alexsidorenko.com/blog/react-render-children-prop/

《Resumable React: How To Use React Inside Qwik》。关于如何在 Qwik 内使用 React,你可以建立 React 应用程序,而无需在用户的浏览器中加载 React。当然,在你需要交互的时候,还是需要动态加载 React(感觉不一定是件好事,没解决问题,只是把问题转移了,可能在交互时会卡一下)。

https://www.builder.io/blog/resumable-react-how-to-use-react-inside-qwik

《Speeding up the JavaScript ecosystem - eslint》。Speeding up 系列的第三篇。1)检测方法是 --cpu-prof + Speedscope(通常还可以用上 hyperfine 跑多次做 benchmark),2)解析器从 @typescript-eslint/parser 换成 @babel/eslint-parser + @babel/preset-typescript 可以节省不少时间,从 2.1s 到 0.6s,缺点是不支持 type-aware 的 linting 规则(我们通常也不会用他们),3)rslint 值得关注。

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-3/

《Vite with ESLint》。手把手教你如何在 Vite 项目中加上和 Vite 集成的 ESLint,基于 vite-plugin-eslint。但个人感觉 ESLint 不应该集成(因为会影响构建速度),而应该单独用,同时编辑器里也有提示了,所以在提交和 CI 里做校验就够了。

https://www.robinwieruch.de/vite-eslint/

《Custom React Hooks and When to Use Them》。关于自定义 Hooks,是什么、可复用的提取、不可复用的提取、提取数量等,最后还是要注意抽象的代价,抽象不是免费的,有时适当重复反而更好,推荐下 Dan 的 The Wet Codebase 分享。

https://thoughtbot.com/blog/custom-react-hooks

《2022大前端总结和2023就业分析》。来自狼叔的年度大作,推荐。

https://mp.weixin.qq.com/s/SicYTABGjXcJJTqYEbL5dQ

《字节前端监控实践》。感觉含金量挺高的,摘录其中错误报警的部分。1)sourcemap 结果可以用 mozila 的 sourcemap 库进行反解,2)为了保密,sourcemap 不会传到公网,而是传给后端存在内部,Sentry 有类似工具(注:sourcemap 构建慢怎么办?并发多跑一次带 sourcemap 的),3)要做堆栈聚合,合并同类错误,4)通过记录 commit + git blame 可以直接分配报错信息到人。

https://juejin.cn/post/7195496297150709821

MDH 前端周刊第 87 期:re-render、Resumable React、ESLint 性能、监控

📒 「每周译Go」在 Go 中定义结构体

📒 leader要我三天时间搭一套react-cli出来,我答应了

⭐️ Go for range 一不小心就掉坑里了

📒 Go 工具链想主动上报使用数据,你愿意吗

📒 Go语言爱好者周刊:第 176 期 —— 题目来了

· 7 min read
加菲猫

image

题图:dannyhowe @ unsplash。

⭐️ Go 并发编程 - 数据竞态

⭐️ x/exp/maps, slices 纷纷被同意加入 Go 标准库

📒 怎么把自己造的轮子发布到 Go Module上

📒 【面试高频题】难度 2.5/5,综合贪心的序列 DP 题

⭐️ 聊聊Golang饱受争议的error

⭐️ 万字长文告诉你Go 1.20中值得关注的几个变化

📒 向 Swift 学习?Go 考虑简单字符串插值特性

📒 如何从 0 开始配置 Mac

📒 Understanding HTML Form Encoding: URL Encoded and Multipart Forms

📒 从 0 实现 use-context-selector

📒 为什么说Go的函数是“一等公民”

⭐️ Go 陷阱 - 错误处理三剑客

🌟 上次给 UMI 的文档提了两个 PR 被合并,成了 UMI contributor:

image

https://github.com/umijs/umi/releases/tag/v4.0.48

📒 「每周译Go」了解 Go 中的指针

📒 【面试高频题】难度 1/5,简单二叉树寻值问题

var ans, k int

func kthSmallest(root *TreeNode, _k int) int {
k = _k
dfs(root)
return ans
}

func dfs(root *TreeNode) {
if root == nil || k == 0 {
return
}
dfs(root.Left)
if k--; k == 0 {
ans = root.Val
}
dfs(root.Right)
}

常规解法是先遍历所有树节点再排序,或者遍历树节点+优先队列(看做是 top K 问题),但这两种解法都没有利用该树为二叉搜索树的特性,而我们知道,二叉搜索树的中序遍历是有序的,因此我们只需要对二叉搜索树执行中序遍历,并返回第 k 小的值即可。中序遍历有「迭代」和「递归」两种写法。

【面试高频题】难度 1/5,简单二叉树寻值问题

📒 TypeScript 5.0 将支持全新的装饰器写法!

⭐️ Go异步任务处理解决方案:Asynq

📒 MDH 前端周刊第 86 期:CRA 未来、吐槽 React、React 清依赖小技巧、Darkmode

《The Future of Create React App and Why It Exists》。Dan 写了篇长文梳理了 CRA 的问题和规划。一些问题包括,1)脚手架的困境,一旦 clone 就很难再更新,然后你的项目配置会逐渐变得陈旧,要么放弃,要么需要花大量精力换新,2)因为是 CSR 所以有空 HTML 的问题,但 Dan 也并不喜欢 MPA,比如 astro,混用多种技术影响 DX,完整的页面刷新让客户端状态失效影响 UX,3)请求瀑布问题,比较好的解法是让数据获取和路由结合,这就需要元框架,4)懒加载(await import)问题,引入额外的请求瀑布,解法是数据获取+路由+构建工具,一样也需要元框架。Dan 期望 CRA 具备 SSG and SSR, automatic code splitting, no client-server waterfalls, route prefetching, navigation preserving client UI state 等功能,然后考虑多 CRA 的多条路,决定不做了,把 CRA 变成一个社区方案的启动器。

https://github.com/reactjs/reactjs.org/pull/5487#issuecomment-1409720741

《React I Love You, But You're Bringing Me Down》。骂得好,哈哈,爱之深,责之切啊。如果你想吐槽 React,照着念就完了。1)表单没有稳定官方方案,一路用社区库过来,目前相对好的是 Formik 和 React-hook-form,看看人家 Svelte,2)Context 太敏感,一碰就 re-render,为了性能而拆大量的 Provider 瀑布流组件,太难看了,提供一个 useContextSelector 有那么难吗?3)关于 DOM 和 ref,React.forwardRef + TypeScript 写通用组件太难了,同时 ref 不仅仅是 关于 dom,每次用 ref 都是因为 useEffect API 太奇怪,换句话说,refs 是对 react 创造的问题的一种解决方案,4)关于 useEffect,需要阅读一篇 61 页 的论文才能用好也太难了,看看人家 Solid.js,5)关于 Hooks 规则,Rules of Hooks 不容易记住,6)关于老父亲 Facebook,略。那作者为啥还留下?因为「It's the ecosystem, stupid.」

https://marmelab.com/blog/2022/09/20/react-i-love-you.html

《Little React Things: Cleaning up dependencies - Zeke Hernandez》。Zeke Hernandez 介绍了一个减少列表项 rerender 的小技巧,虽然对用户来说性能提升不明显,但至少打开 react devtool 的「Highlight Updates」时会看起来很爽,这就够了。方法是,event handler 用 useCallback 包一下,同时清空依赖,没有依赖就不会触发 event handler 生成新的了。那依赖怎么清?1) setState 无需写入依赖,2)setState 用 function 的形式。

https://www.zekehernandez.com/posts/cleaning-up-dependencies

《4 Common Mistakes Made by Node.js Developers》。文章介绍了 4 个 Node 开发的常见错题。1)没有明确定义的日志级别,可尝试 winston, pino, morgan 等库,2)无脑选择 Docker 基础镜像,又大又耗性能,比如 node:18 300M+,选 slim 或 alpine 就够了,slim 70M,alpine 50M,3)签署 JWT 时不使用非对称加密,对称加密不够安全,4)Storing passwords without unique salting。

https://amplication.com/blog/4-common-mistakes-made-by-nodejs-developers

MDH 前端周刊第 86 期:CRA 未来、吐槽 React、React 清依赖小技巧、Darkmode

⭐️ Go 陷阱 - nil != nil

⭐️ Go1.20 那些事:错误处理优化、编译速度提高、PGO 提效等新特性,你知道多少

📒 Go语言爱好者周刊:第 175 期 — Go 2023 调查问卷

· 5 min read
加菲猫

image

题图:烟花兔。

📒 10 GitHub Repositories You Should Know as a JavaScript Developer

⭐️ Go 高性能 - 字符串 & 切片转换提升 10 倍+

⭐️ Go 高性能 - 两种内存大小为 0 的数据类型

⭐️ Taro 正式发布 3.6 版本:支持跨端路由、请求库,支持纵向拓展鸿蒙、Web 端平台插件,小程序持续集成 CI 能力升级

⭐️ 深入理解 go sync.Cond

📒 React团队回应用Vite替换Create React App的建议

📒 React为什么不将Vite作为默认推荐

⭐️ 将Roaring Bitmap序列化为JSON

📒 Flag 2023

📒 Go 1.20 已发布!性能和构建速度上有很大提升!

⭐️ Go 工程化 - 如何实现 implements

⭐️ 「好文推荐」转Go必看 《 Go 工程化 - 面向对象,存在吗》

⭐️ Go字符串操作不是你想的那么简单!

📒 相关文章推荐

24个JavaScript循环遍历方法,你都知道吗

JavaScript 数组方法 reduce 的妙用之处

⭐️ 为什么 Go 不支持 []T 转换为 []interface

📒 「Go框架」深入理解web框架的中间件运行机制

📒 TypeScript 5.0 beta 发布:新版 ES 装饰器、泛型参数的常量修饰、枚举增强等

📒 【面试高频题】难度 2/5,简单的复工面试题

⭐️ 如何使用jenkins搭建一个中小企业前端项目部署环境

⭐️ 这些关于 Golang timezone 时区的坑, 我已经帮你踩过了

📒 还能这样玩?Go 将会增强 Go1 向前兼容性

⭐️ 一文入门Go云原生微服务「爆肝6千字」

⭐️ sourcegraph 出品的并发库 conc 详解

⭐️ Go语言实现的可读性更高的并发神库

📒 MDH 前端周刊第 85 期:MDH Weekly 官网、2023 趋势、CSS Wish List、Astro

《10 Web Development Trends in 2023》,ROBIN WIERUCH 分析了 2023 年 Web 开发的 10 个趋势,推荐一读。10 个领域包括元框架、应用和渲染模式、Edge ServerLess、数据库复兴、JavaScript Runtime、MonoRepo、Utility-First CSS、类型安全、构建工具、AI 驱动开发。

https://www.robinwieruch.de/web-development-trends/

《20 Things I've Learned in my 20 Years as a Software Engineer》,一篇老文,讲述 20 年工作经验工程师的 20 条 Tips,我读完很有收获,推荐一读。

https://www.simplethread.com/20-things-ive-learned-in-my-20-years-as-a-software-engineer/

《Capture heap snapshots in Node.js》。作者介绍了关于捕获堆快照的 3 个方法,1)node --inspect index.mjs--inspect-brk,2)借助 Node 12 支持的 --heapsnapshot-signal flag,node --heapsnapshot-signal=SIGUSR1 index.mjs,3)用 v8.writeHeapSnapshot() method 手动写。

https://pawelgrzybek.com/capture-heap-snapshots-in-node-js/

《Things I want to see in JavaScript and Frontend development in 2023》,Paul Armstrong 关于 2023 年期望发生的变化。1)axios 别发展了,因为用浏览器原生支持的 fetch 可以省去 7-11kB 的尺寸,2)CSS 方案更少分歧,主要是 tailwind 和 css in js 之间,3)少一些资本支持的开源,因为当资本进入时,同时意味着他们期望得到巨大的金钱回报,4)少 eslint 规则和配置,自动帮你改代码或能解实际错误的规则除外,5)react 要不振作起来要不就 gg 吧,作者吐槽了好多都在点上,主要是发货太慢。

https://paularmstrong.dev/blog/2023/01/20/javascript-and-frontend-things-to-see-in-2023/

MDH 前端周刊第 85 期:MDH Weekly 官网、2023 趋势、CSS Wish List、Astro

📒 Typescript 严格模式有多严格

📒 一个全新的 JavaScript 事件!

📒 DevopsCamp 第一期作业: 《cobra - 03 交互式命令(简单)》 解题答案

· 8 min read
加菲猫

image

题图:擅用工具的兔子工程师。

📒 相关文章推荐

修复生产版本 Node 程序的内存泄露问题 — Kent 在他的 Node 程序中遇到了各种奇怪的内存和 CPU 使用率峰值问题,于是他决定查找原因。这篇文章完整介绍了他对此的探寻过程,最戏剧性的是根本原因完全出乎他的意料。

https://kentcdodds.com/blog/fixing-a-memory-leak-in-a-production-node-js-app

在 Go 应用中嵌入 React UI — Flipt 通过一个 Go 构建的单一二进制文件为其 web 应用提供服务,并将静态资源嵌入其中。Go 在 1.16 版本中支持原生嵌入后,帮助 Flipt 走上了一条通往 React 的道路,而且不需要 Next.js 就可以实现很好的效果。

https://www.flipt.io/blog/embedding-react-in-go

在 Next.js v13 中使用异步 React — React 正在原生的支持异步,现在你可以在 Next.js 中试用它,作者提供了一个快速概览。

https://swizec.com/blog/async-react-with-nextjs-13/

React Native 发布了 v0.71 — 这是一个“功能丰富”的版本,包括“默认 TypeScript 文件”,使用 Flexbox Gap 简化布局,以及受网络标准启发的可访问性、样式和事件 props。

https://reactnative.dev/blog/2023/01/12/version-071

用 React Hook Form 和 Zod 构建表单 — 这是作者承诺的一系列录屏视频中的第一个,不仅涉及到开发一个集成后端 API 的表单,还涉及到开发时常遇到的一些问题。该视频的时长长达 95 分钟。

https://www.youtube.com/watch?v=FXWD_etMJWA

⭐️ lerna + dumi + eslint多包管理实践

⭐️ PHP转Go实践:xjson解析神器「开源工具集」

⭐️ 经过99次失败后, 我总结了几点 Golang 反射的经验(附源码)

📒 前端食堂技术周刊第 68 期:Astro 2.0、Nuxt v3.1.0、Bun v0.5、TS 实现 Stage 3 Decorators 提案

Turborepo 1.7

Turborepo 1.7 专注于改善开发者体验,为任务带来更多清晰性,主要特性如下:

  • 改进对持久化任务的支持,"persistent": true
  • 更清晰的输出,需要明确指定 outputs
  • 支持全局安装
  • 只显示错误的输出模式,让日志更清晰,turbo build --output-logs=errors-only

Turborepo 1.7

Turborepo 1.7 发布视频版

加速 JavaScript 生态系统之模块解析

module resolution (模块解析)有着大量的性能损耗,本文对此进行探讨并给出以下建议:

  • 尽可能避免调用文件系统
  • 尽可能使用缓存来表面调用文件系统
  • 使用 fs.stat 或者 fs.statSync 时,总是设置 throwIfNoEntry: false
  • 尽可能限制向上遍历的行为

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-2/

React 新文档中的最佳实践

https://sebastiancarlos.com/react-js-best-practices-from-the-new-docs-1c65570e785d

React 服务器组件深度指南

https://www.plasmic.app/blog/how-react-server-components-work

📒 一篇文章告诉你 golang 环境变量的所有基础操作

📒 CSS 原生嵌套语法来了!

📒 腾讯云开发者 2022 年度热文

手把手实践一个DAPP,通往Web3.0之路!

探秘微信业务优化:DDD从入门到实践

揭秘前端眼中的Rust!

⭐️ 【好文分享】基于Jira的运维发布平台的设计与实现

📒 DevopsCamp 第一期作业: 《cobra - 02 配置文件的读取与保存(简单)》 解题答案

📒 《DevOpsCamp作业: cobra - 01 实现编译与参数绑定(简单)》 解题答案

📒 TS、Vue、React、SSR、Node、Deno、Bun:回顾2022,展望2023

📒 MDH 前端周刊第 84 期:tRPC、Zod、慢 Jest、React Debounce、SSSVG

《6 Common SVG Fails (and How to Fix Them)》,出自 CSS Tricks。作者梳理了 6 种常见错误(编者注:后几种感觉不常见),包括 viewbox 错误、width 和 height 缺失、无意 fill 或 stroke 的颜色、id 缺失、clipping 和 masking 冲突、命名空间缺失,并给出了针对这些问题的解法。

https://css-tricks.com/6-common-svg-fails-and-how-to-fix-them/

《为何开发人员开始喜欢tRPC啦?》。tRPC 的优点包括:1)无需再次封装,直接使用函数调用远程服务,2)与Zod深度结合,可以直接使用Zod进行数据校验,3)使用非常简单,可以用在任何框架中,4)tRPC over HTTP协议非常简单,无论客户端还是服务端实现都非常简单。

https://linux-china.davao.page/blog/2023-01-14-why-trpc/

《Zod: The Next Biggest thing after Typescript》。看完这篇文章后,你可能不想再使用任何其他的验证库了!

https://dev.to/jareechang/zod-the-next-biggest-thing-after-typescript-4phh

《Speeding up the JavaScript ecosystem - module resolution》,出自 marvinhagemeist。构建、测试、Lint 时有个性能大户是 module resolution,即如何找到文件,虽然规范层有规范层的解法(ESM 引用文件要带后缀),但在规范没大范围落地之前,也可以有一些解法。作者总结了几点,1)尽量避免对文件系统的调用,2)尽可能多的缓存以避免调用文件系统,3)当你使用 fs.stat 或 fs.statSync 时,总是设置 throwIfNoEntry: false,找不到文件时不抛错而是给 undefined,4)尽可能地限制向上的遍历行为。看完这篇,我给 umi 提了个 pr,调整了 webpack 配置里 extensions 的顺序。

https://marvinh.dev/blog/speeding-up-javascript-ecosystem-part-2/

https://github.com/umijs/umi/pull/10326

《How to debounce and throttle in React without losing your mind》,作者是 NADIA MAKAREVICH,必读作者系列。关于如何在 React 中做 debounce 和 throttle 而不失去理智。作者先介绍了 debouce 和 throttle 的区别,以及各自的场景是什么,比如 throttle 的场景是拥有自动保存功能的编辑器,及时保存用户输入,以减少因意外情况可能导致的数据丢失。然后介绍了在 React 中使用 debouce 有多困难,你会面临 re-render、陈旧的 state、陈旧的闭包等问题,最终解法是 useRef + useEffect + 保存函数到 ref.current,因为 ref 是 mutable 的,不会有闭包数据陈旧问题。

https://www.developerway.com/posts/debouncing-in-react

MDH 前端周刊第 84 期:tRPC、Zod、慢 Jest、React Debounce、SSSVG

📒 一期每日一GO群分享-flag、viper、协程池、异常处理

· 7 min read
加菲猫

image

封面图:卷饼兔。

⭐️ 装了啥 2023

  • 编辑器主 WebStorm 开发项目,辅 VSCode 临时编辑项目,再辅 CotEditor 临时打开文件(注:如果是 Rust 项目,会用 VSCode)
  • WebStorm 插件只装了两个,Github Copilot、Inspection Lens,前者大幅提升编码效率,后者大幅提升编码体验
  • 编程字体用 Monolisa、Dank Mono 和 Operator Mono,一个用久了看腻了切另一个
  • Terminal 工具是 iTerm2 + zsh + oh-my-zsh 的组合,zsh 额外装了 zsh-autosuggestions 和 fast-syntax-highlighting 插件

装了啥 2023

📒 Golang 相关文章

Golang实现一个linux命令ls命令(命令行工具构建)

GO并发之好用的sync包

Go语言原子操作

Go 并发安全与锁

Go定时器的三种实现方式

10秒改struct性能直接提升15%,产品姐姐都夸我好棒

📒 相关文章推荐

关于未捕获 Promise 异常状态的问题 — 你可能会无感知地遇到 promise 的异常问题,Jake 就解决了这么一个关于 promise 报 unhandled promise rejection 错误的问题。

https://jakearchibald.com/2023/unhandled-rejections/

关于 React 'Concurrent Mode' 的所有内容都在这 — 本文对 Concurrent Mode 进行深入的、以实例为导向的探索(并发模式已经是整合到 React 18 中的一组功能,而不是一个独特的"模式")。

https://blog.codeminer42.com/everything-you-need-to-know-about-concurrent-react-with-a-little-bit-of-suspense/

使用 GitHub Copilot 编写单元测试? — 即使你觉得像 Copilot 这样的 AI 工具在编写生产代码上不太靠谱,但它可能在快速编写单元测试上有一定的作用。

https://www.strictmode.io/articles/using-github-copilot-for-testing

类型安全的 React Query —— 一切都与信任有关 — 类型定义应该是值得信赖的。如果他们不是,他们“成为一个纯粹的建议”断言这篇文章建议可以做些什么来使他们成为这样。

https://tkdodo.eu/blog/type-safe-react-query

Zustand vs Signals:对比 React 状态管理库 — 将最时髦的状态管理库之一——zustand 与 Signals 进行比较,后者是 Preact 团队最新发布的一个状态管理库。

https://medium.com/@kevinschaffter/zustand-vs-signals-e664bff2ce4a

⭐️ 掌握了这篇 Dockerfile 中的 ARG 作用域, 就算 Build 镜像 CI 入门了 【文末抽奖】

⭐️ 「Go语言进阶」并发编程详解 | 文末抽奖

📒 前端食堂技术周刊第 67 期:2022 State of JS、ESLint 2022、pnpm 2022、大淘宝 Web 端技术概览

📒 MDH 前端周刊第 83 期:React Query、CSS 3D、JavaScript Wrapped 2022、React 新文档

《Type-safe React Query》,Dominik 的每篇文章都值得深入阅读。React Query 的类型可以定义在哪?1)useQuery<Todos>,2)const queryFn: Promise<Todos>,3)axios.get<Todos>,4)res.data as Todos,5)不定义。不定义怎么有类型?用 zod,然后定义 schema,schema 不仅可用于校验后端数据,还会返回类型。

https://tkdodo.eu/blog/type-safe-react-query

《Data binding in React: how to work with forms in React》,johnwcomeau 的每篇文章也值得阅读,这篇比较新手向,深入解答了面试必问问题「受控和不受控」。

https://www.joshwcomeau.com/react/data-binding/

《Clever Code Considered Harmful》,johnwcomeau 这周的另一篇文章。判断代码好不好的一个标准是,一个初级开发人员,一个职业生涯刚刚起步的人,会不会在理解这段代码时遇到困难?

https://www.joshwcomeau.com/career/clever-code-considered-harmful/

《React JS Best Practices From The New Docs》,Sebastian Carlos 阅读完 React 新官网文档后总结的 160 条笔记。我帮我节省了大量时间,我读完他的笔记后记了 20 多条笔记。但如果有空,还是应该完整阅读 React 的新文档。

https://sebastiancarlos.medium.com/react-js-best-practices-from-the-new-docs-1c65570e785d

《JavaScript Wrapped 2022》,作者整理了 TypeScript、React、Angular、Vue、SSR、Node|Deno|Bun 的 2022 发展和 2023 展望,建议熟读。

https://vived.io/javascript-wrapped-2022-frontend-weekly-vol-119/

《3D in CSS》,交互式的 3D CSS 教程。主要是 4 个 CSS 属性,包括 perspective、perspectiveOrigin、translateZ 和 rotate3d。

https://garden.bradwoods.io/notes/css/3d

《Building a fast, animated image gallery with Next.js》,Vercel 把 Next.js Conf 2022 的照片搬上网,同时把这套代码开源。技术栈包括 Cloudinary、Next.js 图像组件、imagemin、Framer Motion、以及用 ai 生成 alt 文本等。

https://vercel.com/blog/building-a-fast-animated-image-gallery-with-next-js

《Our top Core Web Vitals recommendations for 2023》,本文 Google DevRel 团队认为在 2023 年提高 Core Web Vitals 性能的最有效方法的最佳实践集合。涉及的性能指标包括 LCP、TTFB、CLS、FID 和 INP,同时给出了每个指标提升的注意点和可执行操作。

https://web.dev/top-cwv-2023/

《The hardest part of web dev》,关于 timing 的知识。其中 react 中,1)渲染函数在React更新DOM之前运行,2)useInsertionEffect回调在React更新DOM后运行,但在浏览器重新计算页面布局之前,3)useLayoutEffect回调在浏览器重新计算页面布局后运行(考虑到useInsertionEffect回调注入的任何CSS),但在浏览器重新绘制之前,4)useEffect回调在浏览器完成重绘后运行。

https://alexvipond.dev/blog/the-hardest-part-of-web-dev

MDH 前端周刊第 83 期:React Query、CSS 3D、JavaScript Wrapped 2022、React 新文档

📒 自从项目上了SkyWalking,睡觉真香!

⭐️ Go 语言 Web 应用怎么使用 Nginx 部署

⭐️ 发现conc并发库一个有趣的问题

⭐️ 醒醒吧,未来不会有 Go2 了!

⭐️ Go语言中常见100问题-#27 Inefficient map initialization

⭐️ 「每周译Go」了解 Go 中的 init

⭐️ Go 设计模式|组合,一个对数据结构算法和职场都有提升的设计模式

📒 八个 Web Components 前端框架,一定有一个你用得上

📒 Go语言爱好者周刊:第 174 期

- - + + \ No newline at end of file diff --git a/2023/page/6/index.html b/2023/page/6/index.html index 3c852e655d..733af66b6e 100644 --- a/2023/page/6/index.html +++ b/2023/page/6/index.html @@ -11,13 +11,13 @@ - - + +
Skip to main content

· 10 min read
加菲猫

📒 相关文章推荐

Gluon:基于网站创建桌面应用的框架 — 这是一种使用 Node 和已安装的浏览器把 Web 站点构建为桌面应用的新方案。值得注意的是,Gluon 同时支持 Chromium 和 Firefox。Deno 也可以替代 Node。已经支持 Windows 和 Linux,本周刚刚完成了对 macOS 的初步支持。

https://gluonjs.org/

Node v19.3.0 (Current) 发布 — 这是几周前发布的版本,v19.3 是一个典型的增量更新版本,内容包含了 npm 升级到 v9.2.0,这本身是一个足够需要阅读发行说明的内容。

https://nodejs.org/en/blog/release/v19.3.0/

构建同构 JS 库的五大挑战 — 同构(isomorphic)的意思是代码可以同时在客户端和服务器上以最小调整就可以运行的代码或者库。

https://doordash.engineering/2022/12/06/five-challenges-to-building-an-isomorphic-javascript-library/

2023 年如何发布 npm — 这是一个指南,描述了如何在 2023 年将开源包发布到 npm 以及需要注意的事项。如果你想在 2023 年编写和发布一个包,你需要用 Typescript 编写它并将其发布为 ES 模块。

https://blog.taskli.st/posts/how-to-publish-to-npm-in-2023

🌟 2022 年的 JavaScript 新星项目 — Michael Rambeau 第七次以 JavaScript 领域的"趋势项目"综述为我们的 2023 年度揭幕。Bun 占据了 2022 年的头把交椅,但我们会把其他的留给你去看。一些特邀作者也分享了他们对生态系统的看法。

https://risingstars.js.org/2022/en

Evan You 回顾 2022 年与展望 2023 年 — 你可能会因为 Vue.js 和 Vite 而认识 Evan,在这里他回顾了 2022 年 Vue 世界发生的事情(比如 Vue 3.x 成为新的默认版本)以及我们在 2023 年 可以期待的事情,包括神秘的 Vapor 模式。他还提醒我们,Vue 2.x 还有一年才会失效。

https://blog.vuejs.org/posts/2022-year-in-review.html

JS Function Composition:有什么大不了的? — James 关于 JavaScript 基础知识的文章总是很受欢迎,去年我们得到了一篇新鲜的文章,关注一个常见的活动:函数组成。"这有什么大不了的?"他问道。

https://jrsinclair.com/articles/2022/javascript-function-composition-whats-the-big-deal/

开发人员面临的十个常见的 JavaScript 问题 — 这可是一篇好文章。如果你已经用 JavaScript 工作了很多年,这些都是你(可能)知道要避免的坑,但是这里有足够的东西可以让你反复思考。

https://www.toptal.com/javascript/10-most-common-javascript-mistakes

Storybook v7.0 进入 Beta 阶段 — 这是近两年来这个流行的前端 UI 开发工具的第一个大版本更新(这里会有 Breaking Change)。有很多新功能,包括性能改进、交互测试等等。在此查看 完整的更改日志。您现在可以通过 迁移指南 尝试 Beta 版。

https://storybook.js.org/blog/7-0-beta

在 React Native 中对 TypeScript 进行头等支持 — 随着新发布的 v0.71,你会得到一个新的“默认是 TypeScript (TS)”的应用程序模板 —— TS 声明随基本包一起发布,文档现在也是 TypeScript 优先的(当然,Flow 或常规 JavaScript 仍然是可以使用的)。

https://reactnative.dev/blog/2023/01/03/typescript-first

在 Reddit 上,有一个关于 为什么人们喜欢使用 Next.js 的讨论。

https://www.reddit.com/r/reactjs/comments/zprham/why_do_people_like_using_nextjs/

⭐️ Next.js 刚刚在 GitHub 中 超过了 Create React App 的 Star 数,如果你喜欢这种受欢迎程度的测量方式。

https://twitter.com/i/web/status/1610165503468658689

3 个导致 App 崩溃的 React 错误 — 一位名为 Jack Herrington 的 React YouTuber 讲解了三个编写 React 时会犯的错误(以及如何解决它们)。

https://www.youtube.com/watch?v=QuLfCUh-iwI

在 TypeScript 中像专家一样处理错误 — “学习我用来处理错误和编写更简洁代码的设计模式。”

https://engineering.udacity.com/handling-errors-like-a-pro-in-typescript-d7a314ad4991?gi=c2ed84ad0ecd

📒 了解JS静态分析,打开前端优化新思路

📒 用代码画一只小兔子给大家拜年啦!

📒 记落地vite到项目中的遇到一个bug, 最终被vite官方merge pr

📒 聊聊Go与TLS 1.3

📒 Google 出品的 Rust 教程

https://github.com/google/comprehensive-rust

📒 你可能并不需要微前端

📒 UMI 微生成器调研

https://umijs.org/docs/guides/generator

https://github.com/umijs/umi/blob/master/packages/preset-umi/src/commands/generators/component.ts

📒 【面试高频题】难度 3.5/5,综合最短路的 DP 问题

🌟 我的信息流 2023.1

⭐️ Go 1.19.5、1.18.10 更新涉及 compiler, linker, net/http, sync/atomic

📒 面试问 Dockerfile 的优化, 千万不要只会说减少层数

📒 Go 服务网络不通?net/http自带的这个工具帮你快速定位

📒 面试官:net/http库知道吗?能说说优缺点吗

⭐️ 模块联邦在微前端架构中的实践

📒 【综合笔试题】难度 4.5/5,经典次短路问题

⭐️ 加大力度!Go 将会增强 Go1 向后兼容性

⭐️ 聊聊Prometheus Gauge的增减操作实现

📒 Git操作不规范,战友提刀来相见!「文末抽奖」

📒 前端食堂技术周刊第 66 期:2022 JS Rising Stars、Lightning CSS、年度最受欢迎文章

📒 写出易维护的代码|React开发的设计模式及原则

📒 MDH 前端周刊第 82 期:Lightning CSS、Tailwindcss、HTTPie AI、chalk-next 投毒

《Zustand vs. Signals》,作者从 DX、性能和 Devtool 三个方面了对比这两个「小众」的状态管理库,简单说就是,1)Zustand 生态和周边更好,而 Signals 性能更好和更自动,2)作者下一个大型项目的选择还是 Zustand,因为对 Signals 的实践以及用的 React 内部 API 不太方向。

https://medium.com/@kevinschaffter/zustand-vs-signals-e664bff2ce4a

Evan You 写了一篇 《2022 Year In Review》,介绍 2022 总结和 2023 规划。2022 主要是默认 Vue 3、Volar 1、Vue Npm 下载量 x2、回传 Vue 3 功能的 Vue 2.7;2023 则是细粒度 Mirror 版本、类 Solid 的 Vapor Mode 编译模式等。

https://blog.vuejs.org/posts/2022-year-in-review.html

《How to ship》 包含了 4 个关于产品如何准时发布的 Tips,1)明确 MAVP(最小实际可行产品)的边界,注意不是偏 DEMO 类的 MVP,2)在前者的基础上削减范围,3)搭配可灵活调整的 Deadline,4)别让自己成为团队卡点。

https://www.industrialempathy.com/posts/how-to-ship/

《React ref Callback Use–Cases》,你可能不知道 ref 除了是 object 以外,还可以是 function,即 ref callback。ref callback 有一些应用场景,比如 mount 时(新增一个 list item 时)做滚动或聚焦、计算 DOM 尺寸或滚动位置、传递 DOM 给多个消费者等。

https://julesblom.com/writing/ref-callback-use-cases

《A React Developer’s First Take on Solid》,一个 React 开发者对 Solid 的第一印象。1)Solid 的优点是小和快,2)同时也有一些由于引入 Proxy 以及 Solid 不同的组件渲染机制后的缺点,比如 prop 不能在函数参数里析构等,3)SolidStart 是一个测试软件,有大量粗糙的边界场景,4)会在真实项目中用吗?不会!

https://jakelazaroff.com/words/a-react-developers-first-take-on-solid/

《Getting started with SolidStart》,SolidStart 入门文章,手把手教你写一个旅行 App。注:SolidStart 是基于 Solid 的元框架。

https://blog.logrocket.com/getting-started-solidstart-solid-js-framework/

《JavaScript Rising Stars 2022》,一年一期,这是第 7 期,可以了解 2022 JavaScript 社区的变化,但是以 Github Star 为衡量标准,并不能完全代表其流行度。

https://risingstars.js.org/2022/zh

MDH 前端周刊第 82 期:Lightning CSS、Tailwindcss、HTTPie AI、chalk-next 投毒

📒 2022 年前端大事记

⭐️ Go1.20 新特性:context支持自定义取消原因

⭐️ Go学设计模式--装饰器和职责链,哪个模式实现中间件更科学

📒 平时的工作如何体现一个人的技术深度?

📒 【第2832期】V8 执行 JavaScript 的过程

⭐️ Golang 库: 为什么 Golang slog 库不支持 Fatal

⭐️ Golang 库: golang slog 怎么设置日志 Debug 等级

⭐️ Golang slog 介绍

⭐️ 一文读懂 Go Http Server 原理

⭐️ 「每周译Go」了解 Go 中的 defer

📒 Go语言爱好者周刊:第 173 期 — 这个并发库真心好

· 2 min read
加菲猫

· 11 min read
加菲猫

📒 相关文章推荐

一个关于 useEffect 的可视化指南 — 奇怪的是,最受欢迎的文章出现在 2022 年的第一期中。作者创建了一系列 React 渲染的可视化指南文章(比如关于 useMemo 和 props 的文章),在这篇文章中他把注意力转向了 useEffect。如果你想了解更多,还有一个关于 头等函数如何工作的可视化演示

https://alexsidorenko.com/blog/useeffect/

我们能承认 React Hooks 是个坏主意吗? — 第二受欢迎的项目是一个“快速链接”,但这个话题有足够的争议,让很多人谈论!Amy 认为“React Hooks 是个坏主意”。不管你喜不喜欢,你都会有自己的看法

https://medium.com/codex/can-we-all-just-admit-react-hooks-were-a-bad-idea-c48120c5188d

2022 React 库 — React 生态系统已经变得如此之大,问题更多的是选择太多,而不是没有需要的东西。如果您正在为一个新项目选择库,那么这个列表(Robin 多年来一直在更新)仍然很有用。希望我们能看到 2023 年的版本

https://www.robinwieruch.de/react-libraries/

回顾 2022 的 React 趋势 — 在今年年初,作者看了看他认为 2022 年重要的事情。他在 Remix、服务端渲染、并发渲染和行为测试方面做得很好,这些都是今年讨论最多的话题

https://www.chakshunyu.com/blog/what-you-should-definitely-look-out-for-in-react-in-2022/

Awesome React Components:一个精心整理的组件清单

https://github.com/brillout/awesome-react-components

React Render Tracker:发现有关意外重渲染的性能问题 — 这个工具可以显示组件树状态随时间变化的差异,这样您就可以更好地研究发生了什么

https://github.com/lahmatiy/react-render-tracker

Plasmo:“它就像浏览器扩展的 Next.js” — 一个面向 React 和 TypeScript 的框架,用于构建您自己的浏览器扩展

https://github.com/PlasmoHQ/plasmo

<ClickToComponent />:快速跳转到组件源代码

https://github.com/ericclemmons/click-to-component

要避免的 10 个 React 反模式 — 一个精心呈现的 8 分钟视频,快速介绍了各种替代的更优方法(或至少值得斟酌)

https://www.youtube.com/watch?v=b0IZo2Aho9Y

📒 Golang 相关文章

Go 1.18 新增三大功能之一“模糊测试”使用方式

Go 1.18 新增三大功能之一“泛型”怎么使用

Go 语言开源项目使用的函数选项模式

Go 语言 context 最佳实践

Go 语言 errgroup 库的使用方式和实现原理

Go 语言一次性定时器使用方式和实现原理

  • new:为变量分配存储空间,返回指针类型,一般不常用
  • make:为复合数据类型(slicemapchan)分配存储空间

在 Go 语言中,原生类型都有默认值,即类型的零值

  • 布尔型的零值:false
  • 整型的零值:0
  • 字符串类型的零值:""
  • 指针、函数、接口、Slice、Map、Channel 的零值:nil

需要注意的是,Go 语言类型的零值初始化是递归完成的,即 数组结构体 的每个元素都进行零值初始化。

在 Go 语言中,推荐定义零值可用的结构体,不仅对程序的安全性和正确性非常重要,它还可以无需预先显式初始化即可直接使用,使 Go 程序代码更优雅。

Go 语言为什么建议定义零值可用的结构体

总结一下,短变量声明在同一作用域内重复使用,只是重新赋值,不会重新创建变量(即指针还是同一个),但是如果在不同作用域(例如 if 语句块),就会创建一个新的变量(内存地址与之前不同)。

Go 语言怎么解决编译器错误“err is shadowed during return”

Go 语言怎么处理三方接口返回数据

Go 语言使用 goroutine 运行闭包的“坑”

Go 语言内存逃逸案例

Go 语言逃逸分析

Go 语言怎么使用变长参数函数

Go 语言错误处理为什么更推荐使用 pkg/errors 三方库

Go 项目使用 Makefile

Go 应用程序设计标准

Go 语言整洁架构实践

Go 语言怎么使用 Docker 部署项目

Golang 语言怎么打印结构体指针类型字段的值

Golang 语言怎么避免空指针引发的 panic

Golang 语言该用命名返回值吗

总结一下:

  • unsafe.Pointer 主要用来实现 指针类型转换,任意指针类型 *T 都可以转换为 unsafe.Pointerunsafe.Pointer 可以转换为任何类型的指针值 *T
  • uintptr 主要用来实现 指针运算,实际是数值类型,可以用于存储内存地址。将 unsafe.Pointer 转换为 uintptr,然后使用 uintptr 值进行算术运算,最后将运算结果 uintptr 值再转换为 unsafe.Pointer

Golang 语言中的非类型安全指针

显式类型转换:

// 整型变量省略类型,编译器根据字面量推导默认是 int
var a = 100
a := 100

// 如果需要声明指定类型的整型变量,也可用显式类型转换,例如:
var a = int8(100)
b := int8(60)

变量声明块:

var (
a int = 100
b int = 200
)

var (
c = 300
d = 3.14
f = true
)

var (
e, f, g int = 10, 20, 30
h, i, j string = "a", "b", "c"
)

Golang 语言的多种变量声明方式和使用场景

Golang 语言中的内置函数 make 和 new

深入理解 go reflect - 反射基本原理

go interface 设计与实现

go Context 设计与实现

深入理解 go unsafe

📒 天呐!我用 go 从零开始写了一个 k8s 应用管理工具(附完整代码和开发过程)

⭐️ 没想到在 Docker 容器中设置时区这么简单

📒 先聊聊「内存分配」,再聊聊Go的「逃逸分析」

📒 字节一面:服务端挂了,客户端的 TCP 连接还在吗

📒 详解全网最快Go泛型跳表【内附源码】

📒 2022年Go语言盘点:泛型落地,无趣很好,稳定为王

📒 【第2824期】图解浏览器的多进程渲染机制

📒 在 Docker build 环境持久化 node_modules 目录

想在 docker build 环境中持久化 node_modules 需要使用到 BuildKitmount 功能,该功能有几个前置条件:

  • docker 版本必须高于 18.09
  • BuildKit 需要手工启用,可在 docker build 命令前添加环境变量 DOCKER_BUILDKIT=1 启用
  • 如果前两个条件不满足,则需要具备 Jenkins 和构建机的读写权限,以调整构建环境参数
  • 修改 Dockerfile,使用 RUN --mount=type=cache 运行 npm installnpm run build 指令(--mount=type=cache

开启 BuildKit 还有其他特性,比如输出日志更友好,基本每一步都会输出耗时,就这一条,值了!

实际操作分为 2 步:

修改 Jenkins 配置,在 docker build 命令前加上环境变量。修改后镜像构建命令长这样:

$  DOCKER_BUILDKIT=1 docker build .

修改 Dockerfile,将 RUN npm installRUN npm run build 指令前面加上 RUN --mount=type=cache npm xxx

FROM node:alpine as builder

WORKDIR /app

COPY package.json /app/

RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
--mount=type=cache,target=/root/.npm,id=npm_cache \
npm i --registry=https://registry.npmmirror.com/

COPY src /app/src

RUN --mount=type=cache,target=/app/node_modules,id=my_app_npm_module,sharing=locked \
npm run build

参考:

加3行代码减少80%构建时间

Docker 从入门到实践 - 使用 BuildKit 构建镜像

https://docs.docker.com/build/buildkit/

📒 Monorepo 下 Git 工作流的最佳实践

📒 Prometheus 数据存储那些事儿

📒 Go1.20 一次打破 Go1 兼容性承诺的真实案例

📒 基于 GraphQL 的云音乐 BFF 建设实践

⭐️ 【第2823期】打包JavaScript库的现代化指南

⭐️ 通过分析gin、beego源码,读懂web框架对http请求处理流程的本质

📒 极端情况下Go的Map也会发生内存泄漏

📒 这两个特性将在 Go1.20 中被弃用,受影响最大的居然是国内的面试官

📒 Go:讲一个故事说明使用汇编语言的必要性

📒 Go学设计模式--怕把核心代码改乱,记得用代理模式

📒 Go语言中常见100问题-#25 Unexpected side effects using slice append

- - + + \ No newline at end of file diff --git "a/2024/1\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/1\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index db2376e81f..a12291b3d9 100644 --- "a/2024/1\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/1\346\234\21014\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

1月14日内容汇总

· 7 min read
加菲猫

🌟 AI 相关

中信建投 | AI前沿系列(一):混合专家模型技术(MoE)

《开源大模型食用指南》发布,7个小时,一杯奶茶速通大模型!

Stable Diffusion XL Turbo 文生图和图生图实践

在 Nvidia Docker 容器编译构建显存优化加速组件 xFormers

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用

节省时间:AI 模型靠谱下载方案汇总

修复 OpenCV 依赖错误的小工具:OpenCV Fixer

⭐️ Go & 云原生 & Rust 相关

Linux 6.8 网络优化, 大量并发连接的TCP性能提高40%左右

深入探索 Rust 中的 Panic 机制

探究 Go 源码中 panic & recover 有哪些坑

从《100 Go Mistakes》我总结了什么

3.深入TiDB:执行优化讲解

亲测体验Go语言模糊测试

Go 发布了一个非安全补丁的 Go 1.21.6

Go1.22 新特性:新的 math/rand/v2 库,更快更标准!

每秒百万数据点 Go 应用监控系统演进

别再用GDB了,一文掌握Go最好用的调试器Delve

Kubernetes CronJob 设计与实现

[go 面试] 实现服务高可用的策略和实践

我是如何实现Go性能5倍提升的

深入理解Go标准库-ServeMux的使用与模式匹配

深入理解Go标准库-http server的启动

使用 Grafana 和 Loki 监控传说中的武当纵云梯

Grafana 教程 - 构建你的第一个仪表盘

成本更低、更可控,云原生可观测新计费模式正式上线

Kubernetes Job 设计与实现

依赖Kafka的Go单元测试例解

Go1.22 新特性:for 循环不再共享循环变量,且支持整数范围

Go运行时的并发原语

Go语言中常见100问题-#94 Not being aware of data alignment

Go 语言中 defer 使用时有哪些陷阱

Go语言之父的反思:我们做对了什么,做错了什么

学习C++20, 为Go的atomic类型插上一双翅膀

📒 后端相关

一张图总结架构设计的40个黄金法则

这些年背过的面试题 — 架构设计篇

这些年背过的面试题——Spring篇

mysql 的 binlog、redolog、undolog 是啥:

  • Binlog(二进制日志):
    • 用于复制:在主从复制中,从数据库会重放主数据库中存储的 binlog,以实现主从同步。
    • 数据库恢复:binlog 可以用于数据库的按时间点还原。
  • Redo log(重做日志):
    • 确保事务的持久性:在事务提交前,redo log 会将事务的修改操作记录下来,以确保在系统崩溃或重启时,可以重新执行这些操作。
    • 防止脏页写入:在系统崩溃时,redo log 可以防止脏页(未提交的数据页)被写入磁盘。
  • Undo log(撤销日志):
    • 用于事务的回滚:在事务执行过程中,undo log 记录了事务修改前的数据版本,以便在事务回滚时恢复数据。
    • 多版本并发控制(MVCC):undo log 支持数据库的多版本并发控制机制,允许事务在不加锁的情况下读取一致的数据。

这些日志文件在 MySQL 中扮演着不同的角色,确保了数据库的一致性、持久性和并发控制。

使用懒加载 + 零拷贝后,程序的秒开率提升至99.99%

万字+20张图探秘Nacos注册中心核心实现原理

7000字+30张图看懂分布式追踪系统原理

拒绝用复杂度自慰:下云高可用的秘诀

公司为什么要使用OKR,目的是什么

阿里面试:说说Rocketmq推模式、拉模式

分布式事务概述与项目实战

分布式锁最终解决方案是RedLock吗?为什么

刷了四百道算法题,我在项目里用过几道呢

烂大街的缓存穿透、缓存击穿和缓存雪崩,你真的懂了

抖音提前批二面:为啥不推荐使用外键

增加索引 + 异步 + 不落地后,从 12h 优化到 15 min

📒 前端相关

有了它 Antd 样式覆盖不要太爽

一文带你从0到1做性能优化——国际化业务中台性能优化实践(上)

Bun 如何设置 npm registry,有时会用到 bunx 命令,会自动下载 npm 包,因此需要配置 npm registry:

# 在根目录建一个 `.bunfig.toml` 配置文件
$ vi $HOME/.bunfig.toml

写入如下内容:

[install]
# set default registry as a string
registry = "https://registry.npmjs.org"

参考:https://bun.sh/docs/install/registries

两个 React

2024 年前端预测

业务中后台用户体验优化方法论总结(体验篇)

分享4 个你可能感兴趣的 TikTok 前端面试题

Chrome 三方 Cookie 禁用已正式开始!

使用 Taro 开发鸿蒙原生应用 —— 快速上手,鸿蒙应用开发指南

- - +
Skip to main content

1月14日内容汇总

· 7 min read
加菲猫

🌟 AI 相关

中信建投 | AI前沿系列(一):混合专家模型技术(MoE)

《开源大模型食用指南》发布,7个小时,一杯奶茶速通大模型!

Stable Diffusion XL Turbo 文生图和图生图实践

在 Nvidia Docker 容器编译构建显存优化加速组件 xFormers

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用

节省时间:AI 模型靠谱下载方案汇总

修复 OpenCV 依赖错误的小工具:OpenCV Fixer

⭐️ Go & 云原生 & Rust 相关

Linux 6.8 网络优化, 大量并发连接的TCP性能提高40%左右

深入探索 Rust 中的 Panic 机制

探究 Go 源码中 panic & recover 有哪些坑

从《100 Go Mistakes》我总结了什么

3.深入TiDB:执行优化讲解

亲测体验Go语言模糊测试

Go 发布了一个非安全补丁的 Go 1.21.6

Go1.22 新特性:新的 math/rand/v2 库,更快更标准!

每秒百万数据点 Go 应用监控系统演进

别再用GDB了,一文掌握Go最好用的调试器Delve

Kubernetes CronJob 设计与实现

[go 面试] 实现服务高可用的策略和实践

我是如何实现Go性能5倍提升的

深入理解Go标准库-ServeMux的使用与模式匹配

深入理解Go标准库-http server的启动

使用 Grafana 和 Loki 监控传说中的武当纵云梯

Grafana 教程 - 构建你的第一个仪表盘

成本更低、更可控,云原生可观测新计费模式正式上线

Kubernetes Job 设计与实现

依赖Kafka的Go单元测试例解

Go1.22 新特性:for 循环不再共享循环变量,且支持整数范围

Go运行时的并发原语

Go语言中常见100问题-#94 Not being aware of data alignment

Go 语言中 defer 使用时有哪些陷阱

Go语言之父的反思:我们做对了什么,做错了什么

学习C++20, 为Go的atomic类型插上一双翅膀

📒 后端相关

一张图总结架构设计的40个黄金法则

这些年背过的面试题 — 架构设计篇

这些年背过的面试题——Spring篇

mysql 的 binlog、redolog、undolog 是啥:

  • Binlog(二进制日志):
    • 用于复制:在主从复制中,从数据库会重放主数据库中存储的 binlog,以实现主从同步。
    • 数据库恢复:binlog 可以用于数据库的按时间点还原。
  • Redo log(重做日志):
    • 确保事务的持久性:在事务提交前,redo log 会将事务的修改操作记录下来,以确保在系统崩溃或重启时,可以重新执行这些操作。
    • 防止脏页写入:在系统崩溃时,redo log 可以防止脏页(未提交的数据页)被写入磁盘。
  • Undo log(撤销日志):
    • 用于事务的回滚:在事务执行过程中,undo log 记录了事务修改前的数据版本,以便在事务回滚时恢复数据。
    • 多版本并发控制(MVCC):undo log 支持数据库的多版本并发控制机制,允许事务在不加锁的情况下读取一致的数据。

这些日志文件在 MySQL 中扮演着不同的角色,确保了数据库的一致性、持久性和并发控制。

使用懒加载 + 零拷贝后,程序的秒开率提升至99.99%

万字+20张图探秘Nacos注册中心核心实现原理

7000字+30张图看懂分布式追踪系统原理

拒绝用复杂度自慰:下云高可用的秘诀

公司为什么要使用OKR,目的是什么

阿里面试:说说Rocketmq推模式、拉模式

分布式事务概述与项目实战

分布式锁最终解决方案是RedLock吗?为什么

刷了四百道算法题,我在项目里用过几道呢

烂大街的缓存穿透、缓存击穿和缓存雪崩,你真的懂了

抖音提前批二面:为啥不推荐使用外键

增加索引 + 异步 + 不落地后,从 12h 优化到 15 min

📒 前端相关

有了它 Antd 样式覆盖不要太爽

一文带你从0到1做性能优化——国际化业务中台性能优化实践(上)

Bun 如何设置 npm registry,有时会用到 bunx 命令,会自动下载 npm 包,因此需要配置 npm registry:

# 在根目录建一个 `.bunfig.toml` 配置文件
$ vi $HOME/.bunfig.toml

写入如下内容:

[install]
# set default registry as a string
registry = "https://registry.npmjs.org"

参考:https://bun.sh/docs/install/registries

两个 React

2024 年前端预测

业务中后台用户体验优化方法论总结(体验篇)

分享4 个你可能感兴趣的 TikTok 前端面试题

Chrome 三方 Cookie 禁用已正式开始!

使用 Taro 开发鸿蒙原生应用 —— 快速上手,鸿蒙应用开发指南

+ + \ No newline at end of file diff --git "a/2024/1\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/1\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 8b795fd59a..db0f65e90e 100644 --- "a/2024/1\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/1\346\234\21021\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

1月21日内容汇总

· 5 min read
加菲猫

🌟 AI 相关

专补大模型短板的RAG有哪些新进展?这篇综述讲明白了

用检索增强生成让大模型更强大,这里有个手把手的Python实现

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

⭐️ Go & 云原生 & Rust 相关

慢聊Golang协程池Ants实现原理

Kubernetes Networking Model & CNI

for-range一个函数,还可以这么用

跟我一起编写 Buildpacks:Go 版本篇

探索Cloud Native Buildpacks的奇妙世界

哈啰云原生弹性伸缩控制器实现细节

使用 Rust 后,我写 Go 的方法都变了!

Go1.22 新特性:Slices 变更 Concat、Delete、Insert 等函数,对开发挺有帮助!

Go 简单设计和实现可扩展、高性能的泛型本地缓存

Kubernetes HPA 设计与实现

从零开始:使用Prometheus与Grafana搭建监控系统

十分钟教你在 k8s 中部署一个前后端应用

Go 夜读第 149 期:如何设计现代云原生网关: Easegress

Go Context 到底放第一个参数传,还是放结构体里

优雅判断 interface 是否为 nil

高效I/O并发处理:双缓冲和Exchanger

📒 后端相关

CPU中的高科技:流水线、超标量、SIMD

让你的代码运行更快:掌握零拷贝技术

电商库存系统的防超卖和高并发扣减方案 | 京东云技术团队

向上管理:让你主动汇报就这么难

RocketMQ 事务消息初体验

云音乐服务端可视化编排平台 TangoFlow 设计与实现

八分钟了解一致性算法 -- Raft算法

代码之外:工程师的成长进阶秘籍

复盘总结,不要错失最大财富

为了让小白也能看懂这个死锁case,我请来了小黑

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

SpringCloud 远程调用为啥要采用HTTP,而不是RPC

业务型团队开发生存指南

DDD领域驱动工程落地实战

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

DDD 四层微服务架构,开箱即用!

2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

Redis 除了缓存,还支持哪些场景

Spring Boot + 规则引擎 URule,太强了!

单租户时代:SaaS范式转移

系统的可观察性是指什么

你管这破玩意儿叫高可用

如何判断业务做不做,什么是UE模型

并发编程的12条规范

性能优化2.0,新增缓存后,程序的秒开率不升反降

📒 前端相关

前端性能优化手册 - RoadMap

React 代码如何跑在小程序上

Taro编译mini-runner包的作用

穿越时空:2023年前端技术盘点与2024年技术展望

Monorepo 项目实现共享 Tailwind 配置

前端食堂技术周刊第 111 期:JS Rising Stars、2024 年如何写 CSS、两个 React、npm 年度回顾

- - +
Skip to main content

1月21日内容汇总

· 5 min read
加菲猫

🌟 AI 相关

专补大模型短板的RAG有哪些新进展?这篇综述讲明白了

用检索增强生成让大模型更强大,这里有个手把手的Python实现

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

⭐️ Go & 云原生 & Rust 相关

慢聊Golang协程池Ants实现原理

Kubernetes Networking Model & CNI

for-range一个函数,还可以这么用

跟我一起编写 Buildpacks:Go 版本篇

探索Cloud Native Buildpacks的奇妙世界

哈啰云原生弹性伸缩控制器实现细节

使用 Rust 后,我写 Go 的方法都变了!

Go1.22 新特性:Slices 变更 Concat、Delete、Insert 等函数,对开发挺有帮助!

Go 简单设计和实现可扩展、高性能的泛型本地缓存

Kubernetes HPA 设计与实现

从零开始:使用Prometheus与Grafana搭建监控系统

十分钟教你在 k8s 中部署一个前后端应用

Go 夜读第 149 期:如何设计现代云原生网关: Easegress

Go Context 到底放第一个参数传,还是放结构体里

优雅判断 interface 是否为 nil

高效I/O并发处理:双缓冲和Exchanger

📒 后端相关

CPU中的高科技:流水线、超标量、SIMD

让你的代码运行更快:掌握零拷贝技术

电商库存系统的防超卖和高并发扣减方案 | 京东云技术团队

向上管理:让你主动汇报就这么难

RocketMQ 事务消息初体验

云音乐服务端可视化编排平台 TangoFlow 设计与实现

八分钟了解一致性算法 -- Raft算法

代码之外:工程师的成长进阶秘籍

复盘总结,不要错失最大财富

为了让小白也能看懂这个死锁case,我请来了小黑

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

SpringCloud 远程调用为啥要采用HTTP,而不是RPC

业务型团队开发生存指南

DDD领域驱动工程落地实战

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

DDD 四层微服务架构,开箱即用!

2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

Redis 除了缓存,还支持哪些场景

Spring Boot + 规则引擎 URule,太强了!

单租户时代:SaaS范式转移

系统的可观察性是指什么

你管这破玩意儿叫高可用

如何判断业务做不做,什么是UE模型

并发编程的12条规范

性能优化2.0,新增缓存后,程序的秒开率不升反降

📒 前端相关

前端性能优化手册 - RoadMap

React 代码如何跑在小程序上

Taro编译mini-runner包的作用

穿越时空:2023年前端技术盘点与2024年技术展望

Monorepo 项目实现共享 Tailwind 配置

前端食堂技术周刊第 111 期:JS Rising Stars、2024 年如何写 CSS、两个 React、npm 年度回顾

+ + \ No newline at end of file diff --git "a/2024/1\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/1\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 1e249af71d..015bc4898a 100644 --- "a/2024/1\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/1\346\234\21028\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

1月28日内容汇总

· 7 min read
加菲猫

🌟 AI 相关

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

⭐️ Go & 云原生 & Rust 相关

#150 Go 并发模式介绍和创新创造【Go 夜读】

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

从 Context 看 Go 设计模式:接口、封装和并发控制

50 条争论的文章发生了啥:Go 标准库 encoding/json 真的慢吗

Kubernetes 控制器管理总结

使用cmux实现网络端口复用

毫巅之微---不同写法的性能差异 番外篇

2024年的Rust与Go

Go 1.22 rc2 刚刚发布,多个新特性等着大家 forloop,math/rand/v2,增强 http routing

Go 服务网络不通?net/http自带的这个工具帮你快速定位

golang pprof 监控系列(1) —— go trace 统计原理与使用

Go 定时器:Timer 和 Ticker

Go1.22 新特性:增强 http.ServerMux 路由能力,将有更强的表现力!

细节对线,让你写出更安全的 Dockerfile

Go 语言中高效切片拼接和 GO 1.22 提供的新方法

GO 中高效 int 转换 string 的方法与源码剖析

Go合集 | 上新 腾讯Go安全指南

《Go题库·16》读写锁底层是怎么实现的

《Go题库·15》go struct 能不能比较

Kubernetes GC 设计与实现

Go 夜读第 150 期 Go 并发模式介绍和创新创造

跟着老猫来搞GO-内建容器Map

这是我见过最酷的服务端日志收集方案!

Go语言中常见100问题-#95 Not understanding stack vs. heap

Go 语言实战:构建强大的延迟任务队列

为什么 Go1.22 for 循环要支持整数范围

📒 后端相关

万字详解微服务世纪难题:如何平滑拆分单体

没用过微服务?别慌,丐版架构图,让你轻松拿捏面试官

从4万行代码降到1.8万,腾讯视频竟然用DDD做架构重构

转转支付通道监控系统的搭建

微服务架构下网关的技术选型

Linux进程管理工具 Supervisor详解

SpringBoot + SpEL,轻松搞定复杂权限控制,非常优雅!

后端程序员必备:书写高质量SQL的30条建议

云音乐RPC稳定性建设与实践

临时抱佛脚必看|一个月速通高级系统架构设计师!

第一性原理:养猪还是读大学

第二遍读俞军的神作《产品方法论》,真香!

阿里面试:Sentinel熔断降级,是如何实现的

深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!

搞懂异地多活,看这篇就够了

一键部署 SpringCloud 微服务,yyds!

Redis、ZooKeeper、Etcd,谁有最好用的分布式锁

提炼设计框架,一文搞懂Redis/MySQL/Kafka为什么这样设计

腾讯一面:32 位 4GB 系统,访问 2GB 数据,虚拟内存会发生什么

1.5万字+30张图盘点索引常见的11个知识点

腾讯三面:一台服务器,最大支持的TCP连接数是多少

这些年背过的面试题——多线程篇

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

使用双异步后,如何保证数据一致性

📒 前端相关

虚实之间有一期播客讲「拼多多出海的 - TEMU 增长背后黄铮的创业哲学和中企出海之路」听下来讲得很有逻辑,聊到了全托管模式如何简化,拼多多的传统技能低价,以及如何实现的低价,包括中国企业出海的几个阶段,很通俗易懂,值得学习。

https://www.xiaoyuzhoufm.com/episode/657fc03f991e2ee608f54f98

当你想将 feature 分支上的多个 commit 合并到 release 分支,并且希望在 release 分支上只看到一个合并提交时,可以使用 git merge --squash 命令:

# 确保你在 release 分支上
$ git checkout release

# 进行 squash 合并
$ git merge feature --squash

# 在解决完所有冲突后,需要将已解决的文件添加到暂存区
$ git add .

# 提交合并结果为一个新的单个 commit(注意:这里没有自动提交,需要手动提交)
$ git commit -m "Squashed commit from feature-branch: Implemented XYZ feature"

注意,在 GitLab 提 Merge Request,可以在 Merge Request 页面中勾选 squash commit 选项

合并代码遇到冲突,想回退到合并前的状态:

$ git merge --abort

一个小技巧,which 命令可以用来查找可执行文件的路径:

$ which npm

/Users/bytedance/.nvm/versions/node/v18.16.0/bin/npm

框架中的类型编程: Hono 中的模板字符串类型编程

框架中的类型编程:tRPC & Prisma 中的泛型应用

React 19 即将推出的 4 个全新 Hooks,很实用!

我用埋点让老板安静 (埋点篇)

Rust性能很高?不,它完全顶不住我的代码

[]深度解析Webpack打包过程(2万字预警)

MDH Weekly 119 – 《周刊重启和博客》

- - +
Skip to main content

1月28日内容汇总

· 7 min read
加菲猫

🌟 AI 相关

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

⭐️ Go & 云原生 & Rust 相关

#150 Go 并发模式介绍和创新创造【Go 夜读】

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

从 Context 看 Go 设计模式:接口、封装和并发控制

50 条争论的文章发生了啥:Go 标准库 encoding/json 真的慢吗

Kubernetes 控制器管理总结

使用cmux实现网络端口复用

毫巅之微---不同写法的性能差异 番外篇

2024年的Rust与Go

Go 1.22 rc2 刚刚发布,多个新特性等着大家 forloop,math/rand/v2,增强 http routing

Go 服务网络不通?net/http自带的这个工具帮你快速定位

golang pprof 监控系列(1) —— go trace 统计原理与使用

Go 定时器:Timer 和 Ticker

Go1.22 新特性:增强 http.ServerMux 路由能力,将有更强的表现力!

细节对线,让你写出更安全的 Dockerfile

Go 语言中高效切片拼接和 GO 1.22 提供的新方法

GO 中高效 int 转换 string 的方法与源码剖析

Go合集 | 上新 腾讯Go安全指南

《Go题库·16》读写锁底层是怎么实现的

《Go题库·15》go struct 能不能比较

Kubernetes GC 设计与实现

Go 夜读第 150 期 Go 并发模式介绍和创新创造

跟着老猫来搞GO-内建容器Map

这是我见过最酷的服务端日志收集方案!

Go语言中常见100问题-#95 Not understanding stack vs. heap

Go 语言实战:构建强大的延迟任务队列

为什么 Go1.22 for 循环要支持整数范围

📒 后端相关

万字详解微服务世纪难题:如何平滑拆分单体

没用过微服务?别慌,丐版架构图,让你轻松拿捏面试官

从4万行代码降到1.8万,腾讯视频竟然用DDD做架构重构

转转支付通道监控系统的搭建

微服务架构下网关的技术选型

Linux进程管理工具 Supervisor详解

SpringBoot + SpEL,轻松搞定复杂权限控制,非常优雅!

后端程序员必备:书写高质量SQL的30条建议

云音乐RPC稳定性建设与实践

临时抱佛脚必看|一个月速通高级系统架构设计师!

第一性原理:养猪还是读大学

第二遍读俞军的神作《产品方法论》,真香!

阿里面试:Sentinel熔断降级,是如何实现的

深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!

搞懂异地多活,看这篇就够了

一键部署 SpringCloud 微服务,yyds!

Redis、ZooKeeper、Etcd,谁有最好用的分布式锁

提炼设计框架,一文搞懂Redis/MySQL/Kafka为什么这样设计

腾讯一面:32 位 4GB 系统,访问 2GB 数据,虚拟内存会发生什么

1.5万字+30张图盘点索引常见的11个知识点

腾讯三面:一台服务器,最大支持的TCP连接数是多少

这些年背过的面试题——多线程篇

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

使用双异步后,如何保证数据一致性

📒 前端相关

虚实之间有一期播客讲「拼多多出海的 - TEMU 增长背后黄铮的创业哲学和中企出海之路」听下来讲得很有逻辑,聊到了全托管模式如何简化,拼多多的传统技能低价,以及如何实现的低价,包括中国企业出海的几个阶段,很通俗易懂,值得学习。

https://www.xiaoyuzhoufm.com/episode/657fc03f991e2ee608f54f98

当你想将 feature 分支上的多个 commit 合并到 release 分支,并且希望在 release 分支上只看到一个合并提交时,可以使用 git merge --squash 命令:

# 确保你在 release 分支上
$ git checkout release

# 进行 squash 合并
$ git merge feature --squash

# 在解决完所有冲突后,需要将已解决的文件添加到暂存区
$ git add .

# 提交合并结果为一个新的单个 commit(注意:这里没有自动提交,需要手动提交)
$ git commit -m "Squashed commit from feature-branch: Implemented XYZ feature"

注意,在 GitLab 提 Merge Request,可以在 Merge Request 页面中勾选 squash commit 选项

合并代码遇到冲突,想回退到合并前的状态:

$ git merge --abort

一个小技巧,which 命令可以用来查找可执行文件的路径:

$ which npm

/Users/bytedance/.nvm/versions/node/v18.16.0/bin/npm

框架中的类型编程: Hono 中的模板字符串类型编程

框架中的类型编程:tRPC & Prisma 中的泛型应用

React 19 即将推出的 4 个全新 Hooks,很实用!

我用埋点让老板安静 (埋点篇)

Rust性能很高?不,它完全顶不住我的代码

[]深度解析Webpack打包过程(2万字预警)

MDH Weekly 119 – 《周刊重启和博客》

+ + \ No newline at end of file diff --git "a/2024/1\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/1\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 60f161d862..8c07481b9c 100644 --- "a/2024/1\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/1\346\234\2107\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

1月7日内容汇总

· 10 min read
加菲猫

🌟 AI 相关

GPT-4 Technical Report

Today's top trending papers in Computer Science

⭐️ Go & 云原生 & Rust 相关

小红书可观测 Metrics 架构演进,如何实现数十倍性能提升

Java与Go到底差别在哪,谁要被时代抛弃

既然问题是 GC 占用的 CPU 过高,首先我们分析一下 CPU 热点,进一步确认一下问题。

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/profile

这个命令用于进行 30s 的 CPU 性能分析,在完成之后会进入 profile 的交互工具:

Alt text

这里直接输入 top 10 可以输出 flat 占比最高的 10 个函数,可以看到 runtime.mallocgc 的 cum 占比已经达到了 15%,占用了快到 3s CPU 时间。

Flat vs Cum:

  • Flat 占比是指这个函数自身的代码使用了多少 CPU,不计算子函数的耗时。
  • 而 Cum 则代表这个函数实际执行消耗了多少 CPU,也就是包括了所有的子函数(和子函数的子函数...)的耗时。

交互工具这里输入 web 就会自动生成调用图(callgraph)并在浏览器里打开 ,限于文档空间这里只展示重要的部分 :

Alt text

先分析一下主流程,这里业务逻辑一共占用了 54% 左右的 CPU(最上面的 endpoint.handler 方法),再往下看,其中 33% 是 RPC 调用(左下角的 client.Invoke),12% 是结果输出(右边的 endpoint.httpOutput,包括写出 HTTP Response,日志上报,监控)。剩下 9% 左右就是实际的各种业务逻辑了,因为非常分散且没有集中的点,所以图上没有显示出来。

纵观这个图可以看出,除了 HTTP/RPC 网络调用占用了大部分 CPU 外,并没有其他很明显的 CPU 热点,这就让最后一个热点凸显了出来:

Alt text

GC 占用的 CPU 在这次 Profiling 过程中占了 15%,比业务逻辑还高!到这里基本确认,GC 一定存在某些问题。

我们可以用另一个 pprof 工具 allocs 来确认猜测是否成立,这个工具会记录堆上的对象创建和内存分配,只需要把上面的 HTTP Path 最后的 profile 换成 allocs 即可:

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/allocs

和 CPU Profile 不一样,Allocs 的 Profile 会记录四个不同的信息,可以输入 o 查看 sample_index 的可选值:

Alt text

  • alloc_object:新建对象数量记录;
  • alloc_space:分配空间大小记录;
  • inuse_object:常驻内存对象数量记录;
  • inuse_space:常驻内存空间大小记录。

一般来说,inuse 相关的记录可以用于排查内存泄漏,OOM 等问题。这里我们是 GC 的问题,主要和内存申请和释放有关,所以先看下 alloc_space:

输入命令,sample_index=alloc_space,然后再 top 10 看下:

Alt text

可以发现,这 30s 一共申请了 1300M 的内存,其中绝大多数都是框架和框架组件,比如 RPC 的网络读取(consumeBytes, ReadFrame),pb 的解析和序列化(marshal),名字服务的选址(Select),日志输出(log),监控上报(ReportAttr)。也没有明显的可疑对象。

我们进行一些简单计算:进行 profiling 的线上节点是 2C2G 配置,看监控单节点大约是 800 QPS 的流量,所以 30s 就是 2w4 的请求,申请了 1300M 的空间,平均一个请求就是大约 50KB 左右。

这个量也比较合理,毕竟一次请求我们需要储存 HTTP 包内容,解析成结构体,还需要调用两次 RPC 接口,最后做日志写出和监控上报,最后再给出返回值,50KB 的资源使用并不算大。而且绝大多数都是框架使用,即使用对象池把业务上的一些小对象复用,对这个内存申请也影响不大。

虽然这个步骤没有排查到想查的问题,但是却发现了一些其他的代码中的小问题,这里也顺便记录下。

首先,上面的 top 10 看不出任何问题,但是为了保险起见,看了一下 top 20:

Alt text

这里有三个我们业务代码里的函数,flat 都很少,占比加起来也不到 4.5%,不过既然发现了他们 ,就深入看一下函数里各行的分配情况,看看有没有什么问题。

只改一个参数让Golang GC耗时暴降到1/30!

字节跳动云原生成本治理落地实践

Go 的 DDD 工程化项目实践

Rust 的所有权、借用和生命周期

Kubernetes Deployment 滚动更新实现原理

[go 面试] 分布式事务框架选择与实践

我是如何实现Go性能5倍提升的

完善 Golang Gin 框架的静态中间件:Gin-Static

Kubernetes 为什么需要 Ingress

Uber Go 出了个静态分析工具 NilAway,还挺实用!

Go语言中常见100问题-#93 Not taking into account instruction-level

Rust使用gRPC

这些流行的K8S工具,你都用上了吗

Go测试的20个实用建议

『每周译Go』Go 的抢占式调度(文末有彩蛋)

了解go在协程调度上的改进

Go 语言为什么不支持并发读写 map

第一篇 旧话重提:获取和利用 goroutine id, machine id 和 process id

📒 后端相关

HBase深度历险 | 京东物流技术团队

项目中遇到一个问题,需要记住弹窗频控,一般来说跟着设备走,也就是在前端缓存。如果需要以用户维度,需要怎么设计,可以用 Redis Bitmap 实现。

Redis Bitmap:实现千万级用户签到的秘密武器

这些年在阿里学到的方法论

架构面试:全链路压测,你是怎么设计的

阿里面试:如何保证RocketMQ消息有序?如何解决RocketMQ消息积压

网易面试:亿级用户,如何做微服务底层架构

美团面试:亿级数据 在线统计,如何实现

美团面试:ES+Redis+MySQL高可用,如何试实现

字节面试:DDD架构,如何落地

微服务下必须了解的4种部署策略!

自从用了这款链路追踪系统,睡觉真香!!

逆风时刻,管理动作或成噪音

这些年背过的面试题——架构设计篇

还得是腾讯,捞了我一把!

文末福利丨2023哔哩哔哩技术精选技术干货

能ping通,TCP就一定能连通吗

微服务全做错了!谷歌提出新方法,成本直接降9倍!

备考两年,关于软考的经验都在这了

我在阿里做开发的高效打工技巧总结

一文讲透消息队列RocketMQ实现消费幂等

订单场景-基于Redisson实现订单号生成

📒 前端相关

【第3162期】前端APM指标采集大冒险

2023年最火的前端项目出炉,竟然是它

你的网站或许不需要前端构建(二)

2023 年 Node.js 性能状态

【第3157期】解锁前端新潜能:如何使用 Rust 锈化前端工具链

前端食堂技术周刊第 110 期:Vue3.4、新版 Vue DevTools 开源、AI 2023 年度总结合集

- - +
Skip to main content

1月7日内容汇总

· 10 min read
加菲猫

🌟 AI 相关

GPT-4 Technical Report

Today's top trending papers in Computer Science

⭐️ Go & 云原生 & Rust 相关

小红书可观测 Metrics 架构演进,如何实现数十倍性能提升

Java与Go到底差别在哪,谁要被时代抛弃

既然问题是 GC 占用的 CPU 过高,首先我们分析一下 CPU 热点,进一步确认一下问题。

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/profile

这个命令用于进行 30s 的 CPU 性能分析,在完成之后会进入 profile 的交互工具:

Alt text

这里直接输入 top 10 可以输出 flat 占比最高的 10 个函数,可以看到 runtime.mallocgc 的 cum 占比已经达到了 15%,占用了快到 3s CPU 时间。

Flat vs Cum:

  • Flat 占比是指这个函数自身的代码使用了多少 CPU,不计算子函数的耗时。
  • 而 Cum 则代表这个函数实际执行消耗了多少 CPU,也就是包括了所有的子函数(和子函数的子函数...)的耗时。

交互工具这里输入 web 就会自动生成调用图(callgraph)并在浏览器里打开 ,限于文档空间这里只展示重要的部分 :

Alt text

先分析一下主流程,这里业务逻辑一共占用了 54% 左右的 CPU(最上面的 endpoint.handler 方法),再往下看,其中 33% 是 RPC 调用(左下角的 client.Invoke),12% 是结果输出(右边的 endpoint.httpOutput,包括写出 HTTP Response,日志上报,监控)。剩下 9% 左右就是实际的各种业务逻辑了,因为非常分散且没有集中的点,所以图上没有显示出来。

纵观这个图可以看出,除了 HTTP/RPC 网络调用占用了大部分 CPU 外,并没有其他很明显的 CPU 热点,这就让最后一个热点凸显了出来:

Alt text

GC 占用的 CPU 在这次 Profiling 过程中占了 15%,比业务逻辑还高!到这里基本确认,GC 一定存在某些问题。

我们可以用另一个 pprof 工具 allocs 来确认猜测是否成立,这个工具会记录堆上的对象创建和内存分配,只需要把上面的 HTTP Path 最后的 profile 换成 allocs 即可:

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/allocs

和 CPU Profile 不一样,Allocs 的 Profile 会记录四个不同的信息,可以输入 o 查看 sample_index 的可选值:

Alt text

  • alloc_object:新建对象数量记录;
  • alloc_space:分配空间大小记录;
  • inuse_object:常驻内存对象数量记录;
  • inuse_space:常驻内存空间大小记录。

一般来说,inuse 相关的记录可以用于排查内存泄漏,OOM 等问题。这里我们是 GC 的问题,主要和内存申请和释放有关,所以先看下 alloc_space:

输入命令,sample_index=alloc_space,然后再 top 10 看下:

Alt text

可以发现,这 30s 一共申请了 1300M 的内存,其中绝大多数都是框架和框架组件,比如 RPC 的网络读取(consumeBytes, ReadFrame),pb 的解析和序列化(marshal),名字服务的选址(Select),日志输出(log),监控上报(ReportAttr)。也没有明显的可疑对象。

我们进行一些简单计算:进行 profiling 的线上节点是 2C2G 配置,看监控单节点大约是 800 QPS 的流量,所以 30s 就是 2w4 的请求,申请了 1300M 的空间,平均一个请求就是大约 50KB 左右。

这个量也比较合理,毕竟一次请求我们需要储存 HTTP 包内容,解析成结构体,还需要调用两次 RPC 接口,最后做日志写出和监控上报,最后再给出返回值,50KB 的资源使用并不算大。而且绝大多数都是框架使用,即使用对象池把业务上的一些小对象复用,对这个内存申请也影响不大。

虽然这个步骤没有排查到想查的问题,但是却发现了一些其他的代码中的小问题,这里也顺便记录下。

首先,上面的 top 10 看不出任何问题,但是为了保险起见,看了一下 top 20:

Alt text

这里有三个我们业务代码里的函数,flat 都很少,占比加起来也不到 4.5%,不过既然发现了他们 ,就深入看一下函数里各行的分配情况,看看有没有什么问题。

只改一个参数让Golang GC耗时暴降到1/30!

字节跳动云原生成本治理落地实践

Go 的 DDD 工程化项目实践

Rust 的所有权、借用和生命周期

Kubernetes Deployment 滚动更新实现原理

[go 面试] 分布式事务框架选择与实践

我是如何实现Go性能5倍提升的

完善 Golang Gin 框架的静态中间件:Gin-Static

Kubernetes 为什么需要 Ingress

Uber Go 出了个静态分析工具 NilAway,还挺实用!

Go语言中常见100问题-#93 Not taking into account instruction-level

Rust使用gRPC

这些流行的K8S工具,你都用上了吗

Go测试的20个实用建议

『每周译Go』Go 的抢占式调度(文末有彩蛋)

了解go在协程调度上的改进

Go 语言为什么不支持并发读写 map

第一篇 旧话重提:获取和利用 goroutine id, machine id 和 process id

📒 后端相关

HBase深度历险 | 京东物流技术团队

项目中遇到一个问题,需要记住弹窗频控,一般来说跟着设备走,也就是在前端缓存。如果需要以用户维度,需要怎么设计,可以用 Redis Bitmap 实现。

Redis Bitmap:实现千万级用户签到的秘密武器

这些年在阿里学到的方法论

架构面试:全链路压测,你是怎么设计的

阿里面试:如何保证RocketMQ消息有序?如何解决RocketMQ消息积压

网易面试:亿级用户,如何做微服务底层架构

美团面试:亿级数据 在线统计,如何实现

美团面试:ES+Redis+MySQL高可用,如何试实现

字节面试:DDD架构,如何落地

微服务下必须了解的4种部署策略!

自从用了这款链路追踪系统,睡觉真香!!

逆风时刻,管理动作或成噪音

这些年背过的面试题——架构设计篇

还得是腾讯,捞了我一把!

文末福利丨2023哔哩哔哩技术精选技术干货

能ping通,TCP就一定能连通吗

微服务全做错了!谷歌提出新方法,成本直接降9倍!

备考两年,关于软考的经验都在这了

我在阿里做开发的高效打工技巧总结

一文讲透消息队列RocketMQ实现消费幂等

订单场景-基于Redisson实现订单号生成

📒 前端相关

【第3162期】前端APM指标采集大冒险

2023年最火的前端项目出炉,竟然是它

你的网站或许不需要前端构建(二)

2023 年 Node.js 性能状态

【第3157期】解锁前端新潜能:如何使用 Rust 锈化前端工具链

前端食堂技术周刊第 110 期:Vue3.4、新版 Vue DevTools 开源、AI 2023 年度总结合集

+ + \ No newline at end of file diff --git "a/2024/2\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/2\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index be326f1900..6349a80267 100644 --- "a/2024/2\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/2\346\234\21011\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

2月11日内容汇总

· 4 min read
加菲猫

alt text

封面图:Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

🌟 AI 相关

MultiHop-RAG: Benchmarking Retrieval-Augmented Generation for Multi-Hop Queries

手把手教你,从零开始实现一个稀疏混合专家架构语言模型(MoE)

苹果为自家芯片打造开源框架MLX,实现Llama 7B并在M2 Ultra上运行

如何用LLM和自有知识库搭建智能Agent

万字详解专家混合:MoE模型

Prompt Engineering:大模型 PUA 指南!

Mixtral-8x7B 模型挖坑

精彩手绘全解:RAG技术,从入门到精通

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

白话Embedding:普通人都能懂的科普文

Mixtral 8x7B: 超越GPT-3.5与Llama 2 70B的稀疏混合专家架构新篇章

3B模型不输7B LLaVA!北大多模态MoE模型登GitHub热榜

GPT-4推理能力暴涨32%,谷歌新型思维链效果超CoT,计算成本可降至1/40

阿里大模型春节礼包来了:代码可执行率超GPT-4,1.5版本全系列开源

刚刚,谷歌弃Bard发布超大杯Gemini,全面对标GPT-4,前2个月免费!

无需RLHF显著提升GPT-4/Llama2性能,北大团队提出Aligner对齐新范式

手撕LangChain代码,新手请进

MoE 卷起来啦!又一微调版 Mixtral-8x7B 发布,试试效果怎么样

不是 GPT4 用不起,而是本地运行 Mixtral-8x7B 更有性价比

在 Mac 运行 OpenChat 3.5 大模型,AI推理APP仅2MB 完全可移植

⭐️ Go & 云原生 & Rust 相关

代码验证斯特林公式的准确性

一些笔记工具工具以及memos介绍

Go 1.22.0 可称之为一次史诗级更新

Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

实现基于 Grafana Loki 的日志报警

齐活了,Grafana 发布大规模持续性能分析开源数据库 - Phlare

📒 后端相关

DDD落地:从携程订单系统重构,看DDD的巨大价值

一次由于八股文引起的内存泄漏

网易面试:请设计一个高可用性的软件架构,说明设计思路

这些年背过的面试题——MySQL篇

天天写业务代码,如何破局业务开发的本质

📒 前端相关

瀑布流优化:我把小红书的瀑布流虚拟列表撕出来了

心遇APP站内玩法H5体验优化实践

译:如何避免 SSR 渲染本地日期时的 FOUC 问题

译:危险的注水

译:React 19 计划推出的新 Hook

译:使用 Promise.withResolvers 延迟 Promise

2024 年你需要知道的 5 个 CSS 代码片段

Partial Prerendering 的 What、Why 和 How

2024 年如何启动 React 项目

MDH Weekly 120 - 《小册》

- - +
Skip to main content

2月11日内容汇总

· 4 min read
加菲猫

alt text

封面图:Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

🌟 AI 相关

MultiHop-RAG: Benchmarking Retrieval-Augmented Generation for Multi-Hop Queries

手把手教你,从零开始实现一个稀疏混合专家架构语言模型(MoE)

苹果为自家芯片打造开源框架MLX,实现Llama 7B并在M2 Ultra上运行

如何用LLM和自有知识库搭建智能Agent

万字详解专家混合:MoE模型

Prompt Engineering:大模型 PUA 指南!

Mixtral-8x7B 模型挖坑

精彩手绘全解:RAG技术,从入门到精通

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

白话Embedding:普通人都能懂的科普文

Mixtral 8x7B: 超越GPT-3.5与Llama 2 70B的稀疏混合专家架构新篇章

3B模型不输7B LLaVA!北大多模态MoE模型登GitHub热榜

GPT-4推理能力暴涨32%,谷歌新型思维链效果超CoT,计算成本可降至1/40

阿里大模型春节礼包来了:代码可执行率超GPT-4,1.5版本全系列开源

刚刚,谷歌弃Bard发布超大杯Gemini,全面对标GPT-4,前2个月免费!

无需RLHF显著提升GPT-4/Llama2性能,北大团队提出Aligner对齐新范式

手撕LangChain代码,新手请进

MoE 卷起来啦!又一微调版 Mixtral-8x7B 发布,试试效果怎么样

不是 GPT4 用不起,而是本地运行 Mixtral-8x7B 更有性价比

在 Mac 运行 OpenChat 3.5 大模型,AI推理APP仅2MB 完全可移植

⭐️ Go & 云原生 & Rust 相关

代码验证斯特林公式的准确性

一些笔记工具工具以及memos介绍

Go 1.22.0 可称之为一次史诗级更新

Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

实现基于 Grafana Loki 的日志报警

齐活了,Grafana 发布大规模持续性能分析开源数据库 - Phlare

📒 后端相关

DDD落地:从携程订单系统重构,看DDD的巨大价值

一次由于八股文引起的内存泄漏

网易面试:请设计一个高可用性的软件架构,说明设计思路

这些年背过的面试题——MySQL篇

天天写业务代码,如何破局业务开发的本质

📒 前端相关

瀑布流优化:我把小红书的瀑布流虚拟列表撕出来了

心遇APP站内玩法H5体验优化实践

译:如何避免 SSR 渲染本地日期时的 FOUC 问题

译:危险的注水

译:React 19 计划推出的新 Hook

译:使用 Promise.withResolvers 延迟 Promise

2024 年你需要知道的 5 个 CSS 代码片段

Partial Prerendering 的 What、Why 和 How

2024 年如何启动 React 项目

MDH Weekly 120 - 《小册》

+ + \ No newline at end of file diff --git "a/2024/2\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/2\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index b7cc2f4de2..74c586c13c 100644 --- "a/2024/2\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/2\346\234\21018\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

2月18日内容汇总

· 7 min read
加菲猫

alt text

封面图:牛逼了!2月编程语言榜单:Go首次进入前十

🌟 AI 相关

How to Cut RAG Costs by 80% Using Prompt Compression

RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture

RAG vs Finetuning — Which Is the Best Tool to Boost Your LLM Application

大语言模型之LlaMA系列- LlaMA 2及LLaMA2_chat(上)

RAG还是微调?微软出了一份特定领域大模型应用建设流程指南

谷歌全新大模型突然发布!100万token完爆GPT-4,仅靠提示词就能学会新语言

扩展说明: 指令微调 Llama 2

社区供稿 | 图解大模型推理优化之 KV Cache

大模型性能优化之Prompt工程全面梳理:从zero shot到chain of thought再到花式XOT

大模型RAG问答行业最佳案例及微调、推理双阶段实现模式:基于模块化(Modular)RAG自定义RAG Flow

值得一看的大模型RAG问答总括性梳理:模块化(Modular)RAG范式的定义、构成及机遇

【有腔调的RAG】01 半结构化数据上的RAG

省钱!微软开源框架LLMLingua + LlamaIndex实现提示词压缩

Ollama Python开发包实例 | 基于本地部署开源大模型的Streamlit聊天应用

【隐私优先】Llama 2 + GPT4All + Chroma实现100%本地化RAG

大模型时代还不理解自注意力?这篇文章教你从头写代码实现

陈丹琦团队新作:数据量砍95%,大模型性能更强了!Less is More

【AI 初体验】 llama2与LangChain 的 SQLDatabaseChain

⭐️ Go & 云原生 & Rust 相关

从物理机到K8S:应用系统部署方式的演进及其影响

Leetcode 算法题解精选

牛逼了!2月编程语言榜单:Go首次进入前十

Go语言中常见100问题-#99 Not understanding how the GC works

Go语言中常见100问题-#98 Not using Go diagnostics tooling

一文搞懂Go GC演进史,讲的太细致了!

Rust 中的并发模型和所有权系统

Kitex:微服务架构下的高性能优化实践

探究 Go 的高级特性之 【处理1分钟百万请求】

探究 Go 的高级特性之 【领域驱动设计中篇】

用 Go 语言实现刘谦 2024 春晚魔术,还原尼格买提汗流浃背的尴尬瞬间!

还不敢写多线程程序?看看Go如何让并发控制简单有趣

从 fatal 错误到 sync.Map:Go中 Map 的并发策略

16. Go调度器系列解读(三):GMP 模型调度时机

15. Go调度器系列解读(二):Go 程序启动都干了些什么

14. Go调度器系列解读(一):什么是 GMP

13. 入门 go 语言汇编,看懂 GMP 源码

8. 看 Go 源码,你需要了解 unsafe.Pointer

5. golang map 源码的逐句解读

一文搞懂Kubernetes 部署策略

滚动更新和回滚部署在 Kubernetes 中的工作原理

Go 项目标准布局?Go 官方出指南了

📒 后端相关

阿里终面:Netty 如何做到单机百万并发

8种专坑同事 SQL写法,性能降低100倍,不来看看

亿级推送,得物是怎么架构的

详解Redis三大集群模式,轻松实现高可用!

阿里Java面试官:CopyOnWriteArrayList底层是怎么保证线程安全的

还搞不懂ConcurrentHashMap底层源码,看这篇就够了

只需七步,教你轻松解决Redis热点Key问题

一文详解Redis中BigKey、HotKey的发现与处理

Java 十亿行数据计算,最快6秒出结果,你能吗

从Kafka中学习高性能系统如何设计 | 京东云技术团队

由浅入深的介绍扣减业务中的一些高并发构建方案(上)

如何在微服务下保证事务的一致性 | 京东云技术团队

【Redis高可用系列】主从复制原理和复制方式分析

Redis删除数据后,为什么内存占用率还是很高

感觉Redis变慢了,这些可能的原因你查了没 (上)

感觉Redis变慢了,这些可能的原因你查了没 (下)

位图(bitmap)原理以及实现

亿万用户在线,一张bitmap统计全解密

如何使用Redis数据类型进行亿级别统计数据

MySQL事务未提交redolog能持久化到磁盘吗

结合MySQL更新流程看 undolog、redolog、binlog

📒 前端相关

致所有渴望学习Rust的人的信

前端项目里都有啥

白嫖ChatGPT4.0 (第二弹)

字节跳动最热门的 15 个前端开源项目

刘谦春晚魔术揭秘:约瑟夫环的数学魅力,JS实现下!

我写了一个根据项目自动切换node版本的插件,再也不用手动使用命令切换了

- - +
Skip to main content

2月18日内容汇总

· 7 min read
加菲猫

alt text

封面图:牛逼了!2月编程语言榜单:Go首次进入前十

🌟 AI 相关

How to Cut RAG Costs by 80% Using Prompt Compression

RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture

RAG vs Finetuning — Which Is the Best Tool to Boost Your LLM Application

大语言模型之LlaMA系列- LlaMA 2及LLaMA2_chat(上)

RAG还是微调?微软出了一份特定领域大模型应用建设流程指南

谷歌全新大模型突然发布!100万token完爆GPT-4,仅靠提示词就能学会新语言

扩展说明: 指令微调 Llama 2

社区供稿 | 图解大模型推理优化之 KV Cache

大模型性能优化之Prompt工程全面梳理:从zero shot到chain of thought再到花式XOT

大模型RAG问答行业最佳案例及微调、推理双阶段实现模式:基于模块化(Modular)RAG自定义RAG Flow

值得一看的大模型RAG问答总括性梳理:模块化(Modular)RAG范式的定义、构成及机遇

【有腔调的RAG】01 半结构化数据上的RAG

省钱!微软开源框架LLMLingua + LlamaIndex实现提示词压缩

Ollama Python开发包实例 | 基于本地部署开源大模型的Streamlit聊天应用

【隐私优先】Llama 2 + GPT4All + Chroma实现100%本地化RAG

大模型时代还不理解自注意力?这篇文章教你从头写代码实现

陈丹琦团队新作:数据量砍95%,大模型性能更强了!Less is More

【AI 初体验】 llama2与LangChain 的 SQLDatabaseChain

⭐️ Go & 云原生 & Rust 相关

从物理机到K8S:应用系统部署方式的演进及其影响

Leetcode 算法题解精选

牛逼了!2月编程语言榜单:Go首次进入前十

Go语言中常见100问题-#99 Not understanding how the GC works

Go语言中常见100问题-#98 Not using Go diagnostics tooling

一文搞懂Go GC演进史,讲的太细致了!

Rust 中的并发模型和所有权系统

Kitex:微服务架构下的高性能优化实践

探究 Go 的高级特性之 【处理1分钟百万请求】

探究 Go 的高级特性之 【领域驱动设计中篇】

用 Go 语言实现刘谦 2024 春晚魔术,还原尼格买提汗流浃背的尴尬瞬间!

还不敢写多线程程序?看看Go如何让并发控制简单有趣

从 fatal 错误到 sync.Map:Go中 Map 的并发策略

16. Go调度器系列解读(三):GMP 模型调度时机

15. Go调度器系列解读(二):Go 程序启动都干了些什么

14. Go调度器系列解读(一):什么是 GMP

13. 入门 go 语言汇编,看懂 GMP 源码

8. 看 Go 源码,你需要了解 unsafe.Pointer

5. golang map 源码的逐句解读

一文搞懂Kubernetes 部署策略

滚动更新和回滚部署在 Kubernetes 中的工作原理

Go 项目标准布局?Go 官方出指南了

📒 后端相关

阿里终面:Netty 如何做到单机百万并发

8种专坑同事 SQL写法,性能降低100倍,不来看看

亿级推送,得物是怎么架构的

详解Redis三大集群模式,轻松实现高可用!

阿里Java面试官:CopyOnWriteArrayList底层是怎么保证线程安全的

还搞不懂ConcurrentHashMap底层源码,看这篇就够了

只需七步,教你轻松解决Redis热点Key问题

一文详解Redis中BigKey、HotKey的发现与处理

Java 十亿行数据计算,最快6秒出结果,你能吗

从Kafka中学习高性能系统如何设计 | 京东云技术团队

由浅入深的介绍扣减业务中的一些高并发构建方案(上)

如何在微服务下保证事务的一致性 | 京东云技术团队

【Redis高可用系列】主从复制原理和复制方式分析

Redis删除数据后,为什么内存占用率还是很高

感觉Redis变慢了,这些可能的原因你查了没 (上)

感觉Redis变慢了,这些可能的原因你查了没 (下)

位图(bitmap)原理以及实现

亿万用户在线,一张bitmap统计全解密

如何使用Redis数据类型进行亿级别统计数据

MySQL事务未提交redolog能持久化到磁盘吗

结合MySQL更新流程看 undolog、redolog、binlog

📒 前端相关

致所有渴望学习Rust的人的信

前端项目里都有啥

白嫖ChatGPT4.0 (第二弹)

字节跳动最热门的 15 个前端开源项目

刘谦春晚魔术揭秘:约瑟夫环的数学魅力,JS实现下!

我写了一个根据项目自动切换node版本的插件,再也不用手动使用命令切换了

+ + \ No newline at end of file diff --git "a/2024/2\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/2\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 390467398b..3ee07202eb 100644 --- "a/2024/2\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/2\346\234\21025\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

2月25日内容汇总

· 6 min read
加菲猫

🌟 AI 相关

Large Language Models for Data Annotation: A Survey

ACTIVERAG: Revealing the Treasures of Knowledge via Active Learning

关于Generative-Diffusion-Model的全面综述,可以作为了解sora的基础知识

云音乐 CMS 平台 AIGC 实践与新特性实现总结

云音乐D2C设计稿转代码建设实践

云音乐 AI Agent 探索实践

云音乐低代码 + ChatGPT 实践方案与思考

🦜🕸️ LangGraph:Plan-Execute Agents 实战

Pinecone总结一:大模型角度

使用 Hugging Face 微调 Gemma 模型

开源大语言模型作为 LangChain 智能体

200万上下文窗口创飞Gemini 1.5!微软来砸谷歌场子了(doge)

如何利用大模型进行数据标注与知识蒸馏:兼看ActiveRAG上下文去噪的大模型RAG问答范式

树形结构与RAG的完美结合:T-RAG方法在组织内部信息查询中的突破

领先99%小白的Sora关键信息!

AI, Machine Learning和 Deep Learning有什么差异

模型融合、混合专家、更小的LLM,几篇论文看懂2024年LLM发展方向

开源大模型王座易主!谷歌Gemma杀入场,笔记本可跑,可商用

关于Google开源Gemma的一些想法

LangChain原理学习笔记

工具增强型大模型:引领智能新时代

AI 实战:手把手教你使用「扣子/coze」来搭建个人blog知识库

大模型推理优化实践:KV cache复用与投机采样

NLP研究在大模型时代的创新飞跃

下一代RAG范式:RAG-Fusion

图解大模型计算加速系列:Flash Attention V2,从原理到并行计算

如何在小公司做大模型

机器学习简介: 寻找函数的艺术

OpenAl 视频生成模型 —— Sora技术报告解读

⭐️ Go & 云原生 & Rust 相关

etcd存储引擎之主干框架

Rust 高性能编程指南

Go map 加有序排序的一些挣扎

云音乐 GitOps 最佳实践

KisFlow-基于Golang的流式计算框架实战(1)

相同型号物理机,容器性能不如虚拟机

听GPT 讲Rust源代码--library/portable-simd

Go deadcode:查找没意义的死代码,对于维护项目挺有用!

通俗易懂剖析Go Channel:理解并发通信的核心机制

竟然是"你"偷走了那0.001的服务可用性

精心设计的 DNS Failover 策略在 Go 中竟然带来了反效果,发生了什么

Go语言中常见100问题-#100 Not understanding the impacts of running Go

《从慢速到SIMD》聊Go 边界检查消除

Go项目中的Labels

Go 更强的代码洁癖,可以把 gofmt 给换了!

Go 终于把这个傻缺特性去掉了,多少陈年老BUG都是因为它!

Go 1.22 slices 库的更新:高效拼接、零化处理和越界插入优化

Go 1.22中值得关注的几个变化

Go中最常用的数据校验库

📒 后端相关

美团面试:说说OOM三大场景和解决方案? (绝对史上最全)

(九)深入并发编程之并发容器:阻塞队列、写时复制容器、锁分段容器原理详谈

(八)深入并发之Runnable、Callable、FutureTask及CompletableFuture原理分析

四十五图,一万五千字!一文让你走出迷雾玩转Maven!

踩了一堆坑,终于把微服务系统全面升级 JDK17 和 SpringBoot3 了

奇思妙想的SQL|兼顾性能的数据倾斜处理新姿势

如何成为一线 Leader

ForkJoinPool:大任务拆分,让并行嗨起来!

写了这么多年DateUtils,殊不知你还有这么多弯弯绕!

这些年背过的面试题——Kafka篇

📒 前端相关

🤯 [性能优化] 浏览器跨域带来的一些性能问题

🧐 [跨端开发] 如何定位 Hybrid Web 页面中 Native 注入的 JS 代码

413 - 《读书笔记:A Philosophy of Software Design》

如何在泛型组件中使用 forwardRef

译:Hot Module Replacement 原理

MDH Weekly 121 - 《开工大吉》

- - +
Skip to main content

2月25日内容汇总

· 6 min read
加菲猫

🌟 AI 相关

Large Language Models for Data Annotation: A Survey

ACTIVERAG: Revealing the Treasures of Knowledge via Active Learning

关于Generative-Diffusion-Model的全面综述,可以作为了解sora的基础知识

云音乐 CMS 平台 AIGC 实践与新特性实现总结

云音乐D2C设计稿转代码建设实践

云音乐 AI Agent 探索实践

云音乐低代码 + ChatGPT 实践方案与思考

🦜🕸️ LangGraph:Plan-Execute Agents 实战

Pinecone总结一:大模型角度

使用 Hugging Face 微调 Gemma 模型

开源大语言模型作为 LangChain 智能体

200万上下文窗口创飞Gemini 1.5!微软来砸谷歌场子了(doge)

如何利用大模型进行数据标注与知识蒸馏:兼看ActiveRAG上下文去噪的大模型RAG问答范式

树形结构与RAG的完美结合:T-RAG方法在组织内部信息查询中的突破

领先99%小白的Sora关键信息!

AI, Machine Learning和 Deep Learning有什么差异

模型融合、混合专家、更小的LLM,几篇论文看懂2024年LLM发展方向

开源大模型王座易主!谷歌Gemma杀入场,笔记本可跑,可商用

关于Google开源Gemma的一些想法

LangChain原理学习笔记

工具增强型大模型:引领智能新时代

AI 实战:手把手教你使用「扣子/coze」来搭建个人blog知识库

大模型推理优化实践:KV cache复用与投机采样

NLP研究在大模型时代的创新飞跃

下一代RAG范式:RAG-Fusion

图解大模型计算加速系列:Flash Attention V2,从原理到并行计算

如何在小公司做大模型

机器学习简介: 寻找函数的艺术

OpenAl 视频生成模型 —— Sora技术报告解读

⭐️ Go & 云原生 & Rust 相关

etcd存储引擎之主干框架

Rust 高性能编程指南

Go map 加有序排序的一些挣扎

云音乐 GitOps 最佳实践

KisFlow-基于Golang的流式计算框架实战(1)

相同型号物理机,容器性能不如虚拟机

听GPT 讲Rust源代码--library/portable-simd

Go deadcode:查找没意义的死代码,对于维护项目挺有用!

通俗易懂剖析Go Channel:理解并发通信的核心机制

竟然是"你"偷走了那0.001的服务可用性

精心设计的 DNS Failover 策略在 Go 中竟然带来了反效果,发生了什么

Go语言中常见100问题-#100 Not understanding the impacts of running Go

《从慢速到SIMD》聊Go 边界检查消除

Go项目中的Labels

Go 更强的代码洁癖,可以把 gofmt 给换了!

Go 终于把这个傻缺特性去掉了,多少陈年老BUG都是因为它!

Go 1.22 slices 库的更新:高效拼接、零化处理和越界插入优化

Go 1.22中值得关注的几个变化

Go中最常用的数据校验库

📒 后端相关

美团面试:说说OOM三大场景和解决方案? (绝对史上最全)

(九)深入并发编程之并发容器:阻塞队列、写时复制容器、锁分段容器原理详谈

(八)深入并发之Runnable、Callable、FutureTask及CompletableFuture原理分析

四十五图,一万五千字!一文让你走出迷雾玩转Maven!

踩了一堆坑,终于把微服务系统全面升级 JDK17 和 SpringBoot3 了

奇思妙想的SQL|兼顾性能的数据倾斜处理新姿势

如何成为一线 Leader

ForkJoinPool:大任务拆分,让并行嗨起来!

写了这么多年DateUtils,殊不知你还有这么多弯弯绕!

这些年背过的面试题——Kafka篇

📒 前端相关

🤯 [性能优化] 浏览器跨域带来的一些性能问题

🧐 [跨端开发] 如何定位 Hybrid Web 页面中 Native 注入的 JS 代码

413 - 《读书笔记:A Philosophy of Software Design》

如何在泛型组件中使用 forwardRef

译:Hot Module Replacement 原理

MDH Weekly 121 - 《开工大吉》

+ + \ No newline at end of file diff --git "a/2024/2\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/2\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index 5ccfad0869..0f71e7f4fb 100644 --- "a/2024/2\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/2\346\234\2104\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

2月4日内容汇总

· 5 min read
加菲猫

alt text

封面图:图文吃透Golang net/http 标准库--服务端

🌟 AI 相关

Large Language Models for Mathematical Reasoning: Progresses and Challenges

A Comprehensive Survey of Compression Algorithms for Language Models

The Power of Noise: Redefining Retrieval for RAG Systems

Corrective Retrieval Augmented Generation

从零构建现代深度学习框架(TinyDL-0.01)

本地运行面壁智能的“贺岁模型”:MiniCPM 2B

「我在淘天做技术」2024年看AIGC是如何让1688主图焕发新春的

大模型推理框架RTP-LLM对LoRA的支持

LLM之LangChain(五)| 使用LangChain Agent分析非结构化数据

LLM之RAG理论(六)| 高级RAG指南和技巧

从零手搓MoE大模型,大神级教程来了

RAG进阶 多用户多文档

RAG 进阶 LlamaIndex多文档

RAG 进阶 多模态图片检索

RAG 进阶 半结构化数据

LlamIndex二 RAG应用开发

LlamaIndex 一 简单文档查询

使用 Docker 快速上手中文版 LLaMA2 开源大模型

部署必备—triton-inference-server的backend(一)——关于推理框架的一些讨论

TensorRT-LLM初探(一)运行llama,以及triton tensorrt llm backend服务化

H100推理飙升8倍!英伟达官宣开源TensorRT-LLM,支持10+模型

大语言模型推理提速:TensorRT-LLM 高性能推理实践

⭐️ Go & 云原生 & Rust 相关

Go1.22 新特性:性能提高、Trace 大修、工作区支持 vendor 等

json.Marshal为什么会对[]byte类型进行base64编码处理

Go调度器系列解读(二):Go 程序启动都干了些什么

Go语言中的Pinner.Pin

Kubernetes 调度器队列 - 设计与实现

Go语言通知协程退出(取消)的几种方式

Go语言中常见100问题-#97 Not relying on inlining

程序员才懂的乐趣:10亿行的挑战

Kubernetes 调度器 - 核心流程 (下篇)

Go调度器系列解读(一):什么是 GMP

Kubernetes 调度器 - 核心流程 (上篇)

图文讲透Golang标准库 net/http实现原理 -- 服务端

利用 ChatGPT 高效搜索Go问题:举一反三的思考方式,高效查找解决方案

Go语言中常见100问题-#96 Not knowing how to reduce allocations

从慢速到SIMG: 一个Go优化的故事

📒 后端相关

8种专坑同事的 SQL 写法,性能降低100倍,不来看看

批量执行Redis命令的四种方式!

阿里面试:设计一个大并发、大数据的系统架构,说说设计思路

码哥字节 124 篇优秀文章精选

Kafka性能篇:为何Kafka这么"快"

Redis 核心篇:唯快不破的秘密

链路追踪落地过程中的挑战与解决方案

美团面试:Sentinel底层滑动时间窗限流算法怎么实现的

字节二面:Spring Boot Redis 可重入分布式锁实现原理

纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式

分库分表的 21 条法则,hold 住!

腾讯二面:epoll性能那么高,为什么

📒 前端相关

扩展你的前端知识库,毫无废话!

TypeScript 5.4 beta: NoInfer 类型、闭包类型分析优化、条件类型判断优化等

升级到 React 18 的经验和教训

- - +
Skip to main content

2月4日内容汇总

· 5 min read
加菲猫

alt text

封面图:图文吃透Golang net/http 标准库--服务端

🌟 AI 相关

Large Language Models for Mathematical Reasoning: Progresses and Challenges

A Comprehensive Survey of Compression Algorithms for Language Models

The Power of Noise: Redefining Retrieval for RAG Systems

Corrective Retrieval Augmented Generation

从零构建现代深度学习框架(TinyDL-0.01)

本地运行面壁智能的“贺岁模型”:MiniCPM 2B

「我在淘天做技术」2024年看AIGC是如何让1688主图焕发新春的

大模型推理框架RTP-LLM对LoRA的支持

LLM之LangChain(五)| 使用LangChain Agent分析非结构化数据

LLM之RAG理论(六)| 高级RAG指南和技巧

从零手搓MoE大模型,大神级教程来了

RAG进阶 多用户多文档

RAG 进阶 LlamaIndex多文档

RAG 进阶 多模态图片检索

RAG 进阶 半结构化数据

LlamIndex二 RAG应用开发

LlamaIndex 一 简单文档查询

使用 Docker 快速上手中文版 LLaMA2 开源大模型

部署必备—triton-inference-server的backend(一)——关于推理框架的一些讨论

TensorRT-LLM初探(一)运行llama,以及triton tensorrt llm backend服务化

H100推理飙升8倍!英伟达官宣开源TensorRT-LLM,支持10+模型

大语言模型推理提速:TensorRT-LLM 高性能推理实践

⭐️ Go & 云原生 & Rust 相关

Go1.22 新特性:性能提高、Trace 大修、工作区支持 vendor 等

json.Marshal为什么会对[]byte类型进行base64编码处理

Go调度器系列解读(二):Go 程序启动都干了些什么

Go语言中的Pinner.Pin

Kubernetes 调度器队列 - 设计与实现

Go语言通知协程退出(取消)的几种方式

Go语言中常见100问题-#97 Not relying on inlining

程序员才懂的乐趣:10亿行的挑战

Kubernetes 调度器 - 核心流程 (下篇)

Go调度器系列解读(一):什么是 GMP

Kubernetes 调度器 - 核心流程 (上篇)

图文讲透Golang标准库 net/http实现原理 -- 服务端

利用 ChatGPT 高效搜索Go问题:举一反三的思考方式,高效查找解决方案

Go语言中常见100问题-#96 Not knowing how to reduce allocations

从慢速到SIMG: 一个Go优化的故事

📒 后端相关

8种专坑同事的 SQL 写法,性能降低100倍,不来看看

批量执行Redis命令的四种方式!

阿里面试:设计一个大并发、大数据的系统架构,说说设计思路

码哥字节 124 篇优秀文章精选

Kafka性能篇:为何Kafka这么"快"

Redis 核心篇:唯快不破的秘密

链路追踪落地过程中的挑战与解决方案

美团面试:Sentinel底层滑动时间窗限流算法怎么实现的

字节二面:Spring Boot Redis 可重入分布式锁实现原理

纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式

分库分表的 21 条法则,hold 住!

腾讯二面:epoll性能那么高,为什么

📒 前端相关

扩展你的前端知识库,毫无废话!

TypeScript 5.4 beta: NoInfer 类型、闭包类型分析优化、条件类型判断优化等

升级到 React 18 的经验和教训

+ + \ No newline at end of file diff --git "a/2024/3\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/3\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index ea021b2df9..822f29ed39 100644 --- "a/2024/3\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/3\346\234\21010\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

3月10日内容汇总

· 35 min read
加菲猫

alt text

封面图:Understanding the Go runtime - Jesus Espino

🌟 AI 相关

《In-context Learning with Retrieved Demonstrations for Language Models: A Survey》。这篇题为 "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" 的文章,主要讨论了语言模型,尤其是大型预训练语言模型如何通过获取的演示进行少量情景学习。这项技术能有效地改进学习过程的效率和可扩展性,并降低手动选择样例时的固有偏见。文章对此领域进行了广泛的研究回顾,对检索模型、检索训练过程和推理算法的不同设计选择进行了讨论和比较。

《碾压LoRA!Meta & CMU | 提出高效大模型微调方法:GaLore,内存可减少63.3%》。Meta和CMU合作提出了一种新的大模型微调方法——Gradient Low-Rank Projection(GaLore)。GaLore通过梯度的低秩投影代替权重的低秩适配,不仅支持全参数学习,而且显著降低了内存占用,减少了63.3%的内存需求。不同于LoRA的低秩权重更新,GaLore利用权重梯度的低秩特性,结合逐层权重更新和8位优化器,有效地优化了内存效率。此外,GaLore还引入了可调整的超参数,提高了其适应性。经实验验证,GaLore的表现优于LoRA,尤其是在预训练模型微调上表现更佳,为大模型训练提供了新的解决策略。

使用 GPT4V+AI Agent 做自动 UI 测试的探索 | 京东云技术团队

Gemini修bug神了!录网页视频把代码库甩给它就行,网友坐不住了:想要访问权限

一键开启 GPU 闲置模式,基于函数计算低成本部署 Google Gemma 模型服务

《Yi技术报告细节分享》。该文章分享了Yi模型的具体实现细节和思路,强调了模型设计围绕模型规模、数据规模和数据质量。Yi模型的预训练阶段数据处理流程包括启发式过滤、学习式过滤、聚类过滤以及去重等步骤,以提高数据质量。微调阶段,Yi模型仅采用了10K数据进行模型微调,强调数据质量胜过数量。在分词器、模型结构及微调参数方面,Yi模型采用了一系列优化措施,包括Transformer-Decoder结构、Grouped-Query Attention等。总的来说,Yi模型通过优化数据处理流程、微调策略、调整模型结构和参数等多方面实现了高效的技术实现。

重新定义大模型推理!Google | 提出SELF-DISCOVER框架,大模型可自写推理结构!

《斯坦福 && 微软 | 发布前端代码生成大模型:Design2Code-18B,助力前端自动化!》。这篇文章主要介绍了一种新的前端代码生成大模型:Design2Code-18B,它可以将网页视觉设计转换成功能性代码。文章首先介绍了将网页视觉设计转换成功能性代码的挑战性和现有方法的局限性,然后提出了Design2Code基准和多模态提示方法,以激发多模态大型语言模型(如GPT-4V和Gemini)的潜力。接着,文章介绍了开源的18B微调模型Design2Code-18B,它基于CogAgent-18B,在多种数据集上进行了预训练,并使用了Huggingface发布的WebSight数据集进行微调。最后,文章展示了Design2Code-18B在Design2Code基准上的优越性能,并提供了一些未来研究方向。

可控文本生成新方法,人大&&南开 | 提出DATG架构,准确性提升19.29%,效率提升1倍

《Auto-Prompt | 大模型提示(Prompt)优化新方法IPC:可根据用户意图进行定向优化》。这篇文章提出了一种名为 Intent-based Prompt Calibration(IPC)的系统,主要目的是通过使用合成案例样本来优化大型语言模型的提示工程。它基于模型生成的数据集进行提示优化,以解决大语言模型对给定提示的敏感性等问题。这种方法的核心思想是根据用户意图迭代细化提示。同时,文章还对 IPC 系统的整体架构和实现流程进行了详细介绍,并展示了一些实验结果。

《更智能的 Agent,Plan-and-Execute Agents 计划和执行》。这篇文章介绍了几种新型的智能 Agent 设计方法,包括 Plan-and-Execute Agents、ReWOO Agent 和 LLMCompiler。Plan-and-Execute Agent 设计法通过明确规划来优化智能 Agent 功能。ReWOO Agent 设计法凭借变量分配功能使得不必对每个任务都使用 LLM。LLMCompiler 则通过任务格式化为 DAG 来提高工具调用的效率。这些新型设计都在不同程度上优化了智能 Agent 的工作流程,提高了工作效率。

《OpenAI Function Calling 与 LangChain Agent 工作原理及区别》。这篇文章介绍了OpenAI Function Calling 与 LangChain Agent的工作原理及它们之间的区别。文章首先列举了大型语言模型的限制,并解释了为何需要Agent。然后,文章介绍了React Agent的工作方式,通过“Reason Only”(向内求索)、“Act Only”(向外探索)和“ReAct”(内外兼修)三种模式优化模型的功能。此外,文章还以一个简单的实例,解释了如何利用ReAct Agent来解答一个包含搜索和计算两个步骤的问题,展示了其实际应用的流程。

《ReAct Agent 回答 RAG 系统中的复杂问题》。这篇文章主要讲述了“ReAct Agent 用于回答 RAG 系统中复杂问题的方式”。随着输入问题的复杂度升高,使用传统的聊天机器人已不能足够有效。于是,作者提出了利用 ReAct Agent,通过自然语言模型(LLMs)逐步规划并执行处理问题的步骤,并定义功能性工具(如时间计算、文本搜索、列表长度计算、百分比变化计算等)以辅助任务完成。这种方法能够更好地干预和控制问题的解决过程,从而提高任务的完成质量。

更智能的 Agent,Plan-and-Execute Agents 计划和执行

ChatGPT也能画图?教你一键生成时序图、类图、流程图、状态图以及用例图

三个被忽视的大模型提示

关于Sora和Stable Diffusion 3,你需要知道的一切

消费级显卡可用!李开复零一万物发布并开源90亿参数Yi模型,代码数学能力史上最强

详解大模型微调全流程

南大俞扬教授:什么是world models/世界模型

深入浅出LangChain与智能Agent:构建下一代AI助手

尤洋教授:开源完整的Sora复现方案来了!

《T-RAG=RAG+微调+实体识别》。这篇文章名为"T-RAG=RAG+微调+实体识别",主要介绍了T-RAG技术,这是一种将RAG架构与微调语言模型和实体树向量数据库相结合的方法,用于支持语境检索。它概述了在敏感文档的背景下如何保护数据隐私,以及如何在有限的计算资源和基于现有文档建立的小型训练数据集中保证用户提问的准确回答。文中还着重介绍了T-RAG的工作流程和实体树的作用。最后,还提出了一个新的评估指标“Correct-Verbose”,用以评价生成回复的质量。此研究不仅是理论研究,也是实践中LLM应用的经验总结,具有实际的指导意义。

《高级 RAG(Self-Reflective RAG)》。这篇文章名为"高级 RAG(Self-Reflective RAG)",主要介绍了Self-Reflective RAG的理念和工作流程。在基本的RAG pipeline中,我们的过程往往受限于被动的检索和生成,而实际操作中,我们需要根据生成的结果进行优化,如改变问题或筛选和排列内容。为了解决这个问题,文章介绍了一种新的自我修正框架,包括Corrective RAG(CRAG)和Self-Reflective RAG。这两种RAG都围绕着对检索和生成内容的评估和反馈进行自我修正,并通过特定标识进行调控。在一定条件下,进一步改进了RAG,使其产生更好的检索和生成效果。

RAG不够聪明?打造更强大的智能体

Anthropic发布Claude3,效果已超越GPT4

从0开始预训练1.4b中文大模型实践

《分类算法入门:以鸢尾花数据集为例》。这篇文章以鸢尾花数据集为例,全面而详细地阐述了机器学习中的分类算法基础知识。首先介绍了人工智能、机器学习和深度学习的基本概念,讲解了机器学习各种分类方法的理论背景。随后通过鸢尾花数据集,展示了如何使用 Python 工具(包括 pandas、sklearn、matplotlib 和 seaborn)进行数据处理、分析和可视化。文章详细讲述了决策树、逻辑回归、支持向量机、K近邻等经典的分类算法,并用图形化的方式展示了分类效果。最后,读者可以通过本文所提供的丰富学习资料来深化对机器学习分类任务的理解和应用。

《万字详解LLM Agents的现状,问题与未来》。这篇文章名为"写在跨年之前:聊聊LLM Agents的现状,问题与未来",主要涉及到LLM Agents的当前状态,面临的问题和未来的可能发展。文章探讨了包括全参微调、Prompt Tuning、LoRA、P-Tuning等在内的SFT(Selective Fine Tuning)范畴的各种技术。其中尤其强调了对于{prompt,response}的单轮问答对的微调是最简单的SFT实现方式。具体的内容细节大概需要阅读原文才能获得更深入的理解。

⭐️ Go & 云原生 & Rust 相关

《Robust generic functions on slices》。这篇文章名为"Robust generic functions on slices",主要探讨了Go的slices包如何提供对切片进行操作的通用函数。该文章首先介绍了如何通过类型参数,一次性为所有类型的切片编写类似slices.Index等函数,而无需针对每种不同的元素类型重新实现。随后,文章深入讲述了新的函数(如Insert, Replace,Delete等)如何修改切片,并通过详述切片在内存中的表现形式及其对垃圾回收器的影响,来帮助读者理解这些函数的工作方式和正确使用它们。文章特别指出,新的Delete函数提供了更清晰地表达程序员意图的方式,而且它不需要分配新的数组,这样就可以在适当时清除无用的元素,帮助垃圾回收。文章强调,调用这些函数后,必须认为原始切片已无效,因为底层数组已被修改。最后,文章还讨论了在处理内存泄漏和元素零值设置等问题时的策略和选项,它们在新版本Go给出的解决方案,以及这些改变可能导致的一些测试问题。此外,作者鼓励开发人员正确使用新功能,并尽量避免上述列举的陷阱。

《Routing Enhancements for Go 1.22》。这篇文章名为"Routing Enhancements for Go 1.22",主要介绍了 Go 1.22 版本中 net/http 包的路由器提供的新特性:方法匹配和通配符。这些新特性让你可以使用模式,而非 Go 代码,来表达常见的路由。这种新功能,尽管简单易懂,但要选择出多个匹配请求的最佳模式却是一项挑战。文章还详细阐释了如何在新版 Go 中使用这些新特性,以及这些引入的变化如何影响了 ServeMux 方法 handle 和 handleFunc 。此外,还描述了新模式如何更具优先级,并解释了其背后的原理。同时,为了保持新旧版本的兼容性,作者们也努力使新的模式语法能覆盖旧的,并使新的优先级规则能泛化旧的规则。总体上,这些改变是 Go 语言团队不断努力使 Go 成为构建生产系统的优秀语言的一个持续过程的一部分。

听GPT 讲Rust源代码--compiler(6)

使用Apache Kafka的Golang实践指南

《Go 为什么不支持从 main 包中导入函数》。这篇由煎鱼撰写的文章,题为 "Go 为什么不支持从 main 包中导入函数?",对于这个话题进行了深度解析。其首先提到,虽然Go的规范并没有明确禁止从main包中导入函数,但我们在实际运行中会被拒绝,提示main包是一个程序而非可以导入的包。这一现象的原因来自于经过多次变动的规定,如2011年移除了 "程序中的其他包都不能命名为 main" 的要求,然后在2015年又新增了限制。这样的变化主要是为了避免增加复杂度和不安全性。比如,一个函数可能会做出自己拥有完全控制权的假设,所以如果引入多个main包中的函数,可能会产生在初始化顺序、全局变量的注册等方面的冲突。这篇文章认为Go官方的做法在理论上可以解决复杂度和安全性问题,但对于有历史债务的项目,对于需要维护多个Go项目工程,相当于磨灭了一条道路,其实比较尴尬。

《fasthttp是如何做到比net/http快十倍的》。这篇文章讲解了fasthttp如何做到比net/http快十倍的原理。fasthttp相比于net/http在处理流程上有所差异,net/http是一个连接新建一个goroutine,当连接数非常多的时候会给系统带来一定的压力。而fasthttp则是建立了workerPool,每个workerChan在后台都会有一个Goroutine来处理其中的连接。此外,fasthttp的快速也得益于几个方面的优化:连接复用,大量使用了sync.Pool进行内存复用以及通过unsafe.Pointer指针进行[]byte和string转换来避免内存分配和拷贝的消耗。

《万字长文讲解Golang pprof 的使用》。这篇文章主要讲述了Golang的pprof工具的使用。pprof工具是Golang中用于性能分析的一个工具,它可以分析出cpu使用情况、内存占用、阻塞情况、线程和协程等信息。文章中详细阐述了如何使用此工具,主要有两种方式,一种是通过http接口的方式暴露出pprof的采集控制界面,另一种是在程序中通过代码来启动相应指标的采集示例。文章还详细介绍了如何解析通过这两种方式获取的输出信息。本文的主要目的是将pprof工具的使用方式用思维导图的形式展示出来,这样可以帮助读者更好地理解和使用pprof工具。

《一篇实用的关于云上K8s应用分账实践》。本文讲述云上Kubernetes(K8s)应用的成本分摊实践,涵盖了成本分摊的核心概念及阿里云ACK FinOps套件的应用。文中首先以前期预算为集群规划的依据,并讨论了随着业务发展对成本分摊精准度的提升需求。介绍了如何根据Pod的核/时成本,通过ACK集群、计算节点、命名空间和应用Pod这四个维度进行费用分摊。文章还分析了单资源和混合资源分摊模型,并讨论了如何设置Request和Limit来优化资源利用。对于多云和混合云场景,分享了如何通过ACK One实现统一管理和成本分析。针对复杂业务场景,讲述了自定义定价模版的使用方式,允许通过配置实现成本定制需求。对于追求细节管理和精细化运营的团队,这篇文章提供了宝贵的指导。

《如何使用 K8s 两大利器"审计"和"事件"帮你摆脱运维困境》。这篇文章主要讲述了如何使用 Kubernetes(K8s)的"审计"和"事件"功能来帮助进行日常集群运维工作。文章首先指出了运维工作中可能出现的一些问题,例如应用被删除、Apiserver负载突变、集群节点出现问题、节点自动扩容等。随后,文章进一步解释了 Kubernetes的审计和事件是如何运作的,强调了善用这两种工具可以提高集群的可观察性,为运维工作带来极大的便利。总的来说,这篇文章为运维人员提供了一种解决方案,通过使用 Kubernetes的审计和事件,可以更好地管理和监测集群的状态。

【Go 工具】竞态条件检测神器 Race Detector

使用Redis入门Golang

一道面试题: Top K 问题

《理解 Docker 容器中 UID 和 GID 的工作原理》。这篇文章详细解析了 Docker 容器中 UID 和 GID 的工作原理。首先,作者概述了用户名、组名、用户ID(UID)和组ID(GID)在容器内运行的进程与主机系统之间的映射对于构建安全系统的重要性。随后,文章分析了uid/gid在Linux系统的安全性,强调了单一内核概念以及uid/gid的分配方式。接着,作者运用实例解释了Docker运行的过程以及如何通过Dockerfile定义和启动不同用户。最后,文章讲述了如何掌控和控制容器的访问权限。在阐述以上内容的同时,文章也提供了一些实际示例来说明这些观点。

《如何基于Docker镜像逆向生成Dockerfile》。这篇文章介绍了如何将Docker镜像逆向生成Dockerfile。文章主要讲述了利用开源工具Dedockify的操作方法与工作原理。该工具通过Python脚本,利用存储在每个镜像层旁边的元数据,逐步遍历层级树,收集与每个层相关联的命令,重建镜像构建过程中执行的命令序列,从而得到近似的Dockerfile。不过,因为无法访问执行原始docker build命令时存在的构建上下文,如果使用了COPY或ADD指令,生成的输出可能不完全匹配原始的Dockerfile。

《通过多阶段构建减小Golang镜像的大小》。本篇文章主要介绍了如何通过多阶段构建减小Golang镜像的大小。首先,作者提出了一个通用的Dockerfile,并指出其生成的镜像大小超过300MB,主要因为包含了所有的Golang工具。然后,作者提出了多阶段构建的方法,它能从不同的基础镜像构建,有选择地将文件从一个阶段传递到下一个阶段,从而减小镜像大小。在本例中,通过二级构建,镜像大小已降至11.7MB。最后,还探讨了使用名为scratch的空白镜像进一步减小镜像大小的可能性,使得镜像最后降至6.34MB,但作者强调这需要慎重考虑,因为最后生成的镜像将完全没有任何工具。

《k8s 到底是什么,架构是怎么样的》。这篇文章主要讲述了 Kubernetes(K8s)的基本概念、架构和工作原理。Kubernetes,因单词过长,我们通常简化为k8s。k8s 是一种容器的协调工具,位于应用服务和服务器之间,能以策略的方式协调和管理多个应用服务。通过一个 yaml 文件的配置,可以定义应用的部署顺序等信息,自动部署应用到各个服务器上,还能让它们崩溃后自动重启,可以自动扩容和缩容。Kubernetes 的服务器分为两部分:控制平面和工作节点,前者负责控制和管理各个节点,后者则负责实际运行各个应用服务。k8s 的命令行工具为 kubectl,用于执行各类操作命令。

《Go 泛型有没有可能在后期改为 <> 尖括号》。这篇文章主要讨论了Go语言在处理泛型时,为何并没有采用类似Java和C++的 <> 尖括号表示法,而是选择了中括号 []. 首先,使用尖括号可能导致语义混淆,如 a, b := w < x, y > (z) 此句,如果使用尖括号,程序可能在编译阶段无法确定该行表达式的具体含义。其次,使用圆括号也会导致同样的问题,比如 func F(T any)(v T)(r1, r2 T), 无法快速准确判断出参数和返回值部分。此外,Go官方也不希望使用非ASCII的字符。作者还提到社区中对Go的处理方式存在一些争议,部分社区成员认为如果使得编译器解释尖括号不再困难,就可以采用这种符号。然而,总的来说,基于已有的实践和规范,Go语言在未来可能也不会改变其泛型的表示方式。

《Rust中channel的使用》。这篇文章主要介绍了Rust编程语言中Channel的用法。其中,Channel是Rust中用于在不同线程间传递信息的通信机制,实现了线程间的消息传递。每个Channel由发送端和接收端两部分组成,其设计理念是“通过通信来共享内存,而非通过共享内存来通信”,以此避免了数据竞争和共享内存的复杂性。该文章进一步详细介绍了如何在Rust中创建和使用Channel,并给出了相关代码示例。最后,文章阐述了多种Channel模型,包括Rust标准库中所使用的MPSC(多生产者,单消费者)模型。

K8s部署方式大全:从基础到进阶,一文带你掌握所有技巧

k8s从入门到精通 -- 更适合中国宝宝体质

📒 后端相关

《万字+33张图探秘OpenFeign核心架构原理》。本篇文章深入探讨了SpringCloud核心组件OpenFeign的核心架构原理。文章分为四个部分,首先解释原始Feign的使用和基于SpringCloud的进化过历程;然后详细讲解了Feign底层工作原理,依赖于JDK动态代理和核心组件如Contract、Encoder、Decoder等;接下来分析了SpringCloud是如何整合Feign的,并且讨论了OpenFeign的多种配置方式及其优先级;最后,文章通过丰富的图示和代码示例,使读者可以更好地理解并运用这一工具。这篇文章对于理解和运用OpenFeign非常有帮助,无论是对于初学者还是有经验的开发者。

《三万字长文:如何去排查JVM内存问题》。这篇文章是一份详尽的指导,讲述了如何排查JVM内存问题。文中首先定位了技术问题的范围,确定适用于JDK8至JDK11。接着,作者提出了系统化的排查原则,并提供了一步步的诊断流程,从基本信息收集、判断内存增长原因,到具体分析内存问题的可能来源。文章详细介绍了如何利用不同的命令和工具(如jmap、jstat、Arthas等)进行详细的分析,并根据内存使用情况,向读者展示了如何确定是堆内存问题还是堆外内存问题。总之,文章为那些需要深入理解和处理JVM内存问题的开发者和运维人员提供了宝贵的知识和技巧。

《如何避免MYSQL主从延迟带来的读写问题》。这篇文章讨论了如何处理在MySQL主从部署架构中普遍存在的主从同步延迟问题,以保持读写操作的一致性。文章首先介绍了主从延迟产生的场景及其对读写分离原则的影响。然后,详细解释了主从复制的原理,并提出了两种避免主从数据不一致的技术方案:一是使用select master_pos_wait函数来等待从库同步至特定的binlog位置点;二是在开启GTID模式的情况下,通过select wait_for_executed_gtid_set函数检查GTID集合是否已同步。这两种方法均旨在确保从库数据的准确性,从而整体上减轻主库的压力。总体上,文章为MySQL数据库管理员提供了缓解主从延迟导致的读写问题的具体实施方案。

《这些年背过的面试题——ES篇》。这篇文章是一篇针对Elasticsearch(ES)的面试指南,它涵盖ES基础知识点和面试过程中常见问题。内容包括ES的功能特性介绍(如分布式架构、全文搜索、数据分析等)、主要的使用场景描述、与其他搜索引擎的对比(Lucene和Solr)、以及ES的基本概念解释。文章还详细探讨了ES的高级特性,如映射、DSL查询、聚合分析和智能搜索建议器。此外,作者还分享了关于数据索引优化的实战技巧和策略,提供了写优化、读优化和索引重建的方案,这些方案对ES数据存储和查询的性能有显著影响,最后还对Deep Paging性能问题提供了解决方法。对正在准备面试或者希望巩固ES知识的读者而言,这篇文章是一个宝贵的资源。

《什么是MySQL锁?有哪些锁类型》。这篇文章详细地介绍了MySQL中的锁定机制及其类型。起初概述了锁的作用,即协调多进程或线程对资源的并发访问,在数据库环境下,锁对于保持事务的正确性与一致性至关重要。作者明确区分了MySQL中锁的级别,从全局锁、表锁(读锁、写锁)到元数据锁、意向锁,直到行锁的多种形式(记录锁、间隙锁和临键锁)。文中还探讨了AUTO-INC锁的作用和相关优化,举例说明了其在INSERT操作中的应用。此外,文章也涉及了如何根据不同的情况优化锁的使用以及如何避免由锁产生的性能瓶颈。这篇文章为理解MySQL的各种锁类型和锁机制提供了宝贵的信息,特别对于数据库管理员和那些需要管理并发数据访问问题的开发人员来说,具有很高的实用价值。

📒 前端相关

Vue 团队正式开源 Rolldown:基于 Rust 的超快 JavaScrip 打包工具!

打造舒适的vscode开发环境

相比于 Node.js,Deno 和 Bun 到底能带来什么

MDH Weekly 122 - 《招人》

- - +
Skip to main content

3月10日内容汇总

· 35 min read
加菲猫

alt text

封面图:Understanding the Go runtime - Jesus Espino

🌟 AI 相关

《In-context Learning with Retrieved Demonstrations for Language Models: A Survey》。这篇题为 "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" 的文章,主要讨论了语言模型,尤其是大型预训练语言模型如何通过获取的演示进行少量情景学习。这项技术能有效地改进学习过程的效率和可扩展性,并降低手动选择样例时的固有偏见。文章对此领域进行了广泛的研究回顾,对检索模型、检索训练过程和推理算法的不同设计选择进行了讨论和比较。

《碾压LoRA!Meta & CMU | 提出高效大模型微调方法:GaLore,内存可减少63.3%》。Meta和CMU合作提出了一种新的大模型微调方法——Gradient Low-Rank Projection(GaLore)。GaLore通过梯度的低秩投影代替权重的低秩适配,不仅支持全参数学习,而且显著降低了内存占用,减少了63.3%的内存需求。不同于LoRA的低秩权重更新,GaLore利用权重梯度的低秩特性,结合逐层权重更新和8位优化器,有效地优化了内存效率。此外,GaLore还引入了可调整的超参数,提高了其适应性。经实验验证,GaLore的表现优于LoRA,尤其是在预训练模型微调上表现更佳,为大模型训练提供了新的解决策略。

使用 GPT4V+AI Agent 做自动 UI 测试的探索 | 京东云技术团队

Gemini修bug神了!录网页视频把代码库甩给它就行,网友坐不住了:想要访问权限

一键开启 GPU 闲置模式,基于函数计算低成本部署 Google Gemma 模型服务

《Yi技术报告细节分享》。该文章分享了Yi模型的具体实现细节和思路,强调了模型设计围绕模型规模、数据规模和数据质量。Yi模型的预训练阶段数据处理流程包括启发式过滤、学习式过滤、聚类过滤以及去重等步骤,以提高数据质量。微调阶段,Yi模型仅采用了10K数据进行模型微调,强调数据质量胜过数量。在分词器、模型结构及微调参数方面,Yi模型采用了一系列优化措施,包括Transformer-Decoder结构、Grouped-Query Attention等。总的来说,Yi模型通过优化数据处理流程、微调策略、调整模型结构和参数等多方面实现了高效的技术实现。

重新定义大模型推理!Google | 提出SELF-DISCOVER框架,大模型可自写推理结构!

《斯坦福 && 微软 | 发布前端代码生成大模型:Design2Code-18B,助力前端自动化!》。这篇文章主要介绍了一种新的前端代码生成大模型:Design2Code-18B,它可以将网页视觉设计转换成功能性代码。文章首先介绍了将网页视觉设计转换成功能性代码的挑战性和现有方法的局限性,然后提出了Design2Code基准和多模态提示方法,以激发多模态大型语言模型(如GPT-4V和Gemini)的潜力。接着,文章介绍了开源的18B微调模型Design2Code-18B,它基于CogAgent-18B,在多种数据集上进行了预训练,并使用了Huggingface发布的WebSight数据集进行微调。最后,文章展示了Design2Code-18B在Design2Code基准上的优越性能,并提供了一些未来研究方向。

可控文本生成新方法,人大&&南开 | 提出DATG架构,准确性提升19.29%,效率提升1倍

《Auto-Prompt | 大模型提示(Prompt)优化新方法IPC:可根据用户意图进行定向优化》。这篇文章提出了一种名为 Intent-based Prompt Calibration(IPC)的系统,主要目的是通过使用合成案例样本来优化大型语言模型的提示工程。它基于模型生成的数据集进行提示优化,以解决大语言模型对给定提示的敏感性等问题。这种方法的核心思想是根据用户意图迭代细化提示。同时,文章还对 IPC 系统的整体架构和实现流程进行了详细介绍,并展示了一些实验结果。

《更智能的 Agent,Plan-and-Execute Agents 计划和执行》。这篇文章介绍了几种新型的智能 Agent 设计方法,包括 Plan-and-Execute Agents、ReWOO Agent 和 LLMCompiler。Plan-and-Execute Agent 设计法通过明确规划来优化智能 Agent 功能。ReWOO Agent 设计法凭借变量分配功能使得不必对每个任务都使用 LLM。LLMCompiler 则通过任务格式化为 DAG 来提高工具调用的效率。这些新型设计都在不同程度上优化了智能 Agent 的工作流程,提高了工作效率。

《OpenAI Function Calling 与 LangChain Agent 工作原理及区别》。这篇文章介绍了OpenAI Function Calling 与 LangChain Agent的工作原理及它们之间的区别。文章首先列举了大型语言模型的限制,并解释了为何需要Agent。然后,文章介绍了React Agent的工作方式,通过“Reason Only”(向内求索)、“Act Only”(向外探索)和“ReAct”(内外兼修)三种模式优化模型的功能。此外,文章还以一个简单的实例,解释了如何利用ReAct Agent来解答一个包含搜索和计算两个步骤的问题,展示了其实际应用的流程。

《ReAct Agent 回答 RAG 系统中的复杂问题》。这篇文章主要讲述了“ReAct Agent 用于回答 RAG 系统中复杂问题的方式”。随着输入问题的复杂度升高,使用传统的聊天机器人已不能足够有效。于是,作者提出了利用 ReAct Agent,通过自然语言模型(LLMs)逐步规划并执行处理问题的步骤,并定义功能性工具(如时间计算、文本搜索、列表长度计算、百分比变化计算等)以辅助任务完成。这种方法能够更好地干预和控制问题的解决过程,从而提高任务的完成质量。

更智能的 Agent,Plan-and-Execute Agents 计划和执行

ChatGPT也能画图?教你一键生成时序图、类图、流程图、状态图以及用例图

三个被忽视的大模型提示

关于Sora和Stable Diffusion 3,你需要知道的一切

消费级显卡可用!李开复零一万物发布并开源90亿参数Yi模型,代码数学能力史上最强

详解大模型微调全流程

南大俞扬教授:什么是world models/世界模型

深入浅出LangChain与智能Agent:构建下一代AI助手

尤洋教授:开源完整的Sora复现方案来了!

《T-RAG=RAG+微调+实体识别》。这篇文章名为"T-RAG=RAG+微调+实体识别",主要介绍了T-RAG技术,这是一种将RAG架构与微调语言模型和实体树向量数据库相结合的方法,用于支持语境检索。它概述了在敏感文档的背景下如何保护数据隐私,以及如何在有限的计算资源和基于现有文档建立的小型训练数据集中保证用户提问的准确回答。文中还着重介绍了T-RAG的工作流程和实体树的作用。最后,还提出了一个新的评估指标“Correct-Verbose”,用以评价生成回复的质量。此研究不仅是理论研究,也是实践中LLM应用的经验总结,具有实际的指导意义。

《高级 RAG(Self-Reflective RAG)》。这篇文章名为"高级 RAG(Self-Reflective RAG)",主要介绍了Self-Reflective RAG的理念和工作流程。在基本的RAG pipeline中,我们的过程往往受限于被动的检索和生成,而实际操作中,我们需要根据生成的结果进行优化,如改变问题或筛选和排列内容。为了解决这个问题,文章介绍了一种新的自我修正框架,包括Corrective RAG(CRAG)和Self-Reflective RAG。这两种RAG都围绕着对检索和生成内容的评估和反馈进行自我修正,并通过特定标识进行调控。在一定条件下,进一步改进了RAG,使其产生更好的检索和生成效果。

RAG不够聪明?打造更强大的智能体

Anthropic发布Claude3,效果已超越GPT4

从0开始预训练1.4b中文大模型实践

《分类算法入门:以鸢尾花数据集为例》。这篇文章以鸢尾花数据集为例,全面而详细地阐述了机器学习中的分类算法基础知识。首先介绍了人工智能、机器学习和深度学习的基本概念,讲解了机器学习各种分类方法的理论背景。随后通过鸢尾花数据集,展示了如何使用 Python 工具(包括 pandas、sklearn、matplotlib 和 seaborn)进行数据处理、分析和可视化。文章详细讲述了决策树、逻辑回归、支持向量机、K近邻等经典的分类算法,并用图形化的方式展示了分类效果。最后,读者可以通过本文所提供的丰富学习资料来深化对机器学习分类任务的理解和应用。

《万字详解LLM Agents的现状,问题与未来》。这篇文章名为"写在跨年之前:聊聊LLM Agents的现状,问题与未来",主要涉及到LLM Agents的当前状态,面临的问题和未来的可能发展。文章探讨了包括全参微调、Prompt Tuning、LoRA、P-Tuning等在内的SFT(Selective Fine Tuning)范畴的各种技术。其中尤其强调了对于{prompt,response}的单轮问答对的微调是最简单的SFT实现方式。具体的内容细节大概需要阅读原文才能获得更深入的理解。

⭐️ Go & 云原生 & Rust 相关

《Robust generic functions on slices》。这篇文章名为"Robust generic functions on slices",主要探讨了Go的slices包如何提供对切片进行操作的通用函数。该文章首先介绍了如何通过类型参数,一次性为所有类型的切片编写类似slices.Index等函数,而无需针对每种不同的元素类型重新实现。随后,文章深入讲述了新的函数(如Insert, Replace,Delete等)如何修改切片,并通过详述切片在内存中的表现形式及其对垃圾回收器的影响,来帮助读者理解这些函数的工作方式和正确使用它们。文章特别指出,新的Delete函数提供了更清晰地表达程序员意图的方式,而且它不需要分配新的数组,这样就可以在适当时清除无用的元素,帮助垃圾回收。文章强调,调用这些函数后,必须认为原始切片已无效,因为底层数组已被修改。最后,文章还讨论了在处理内存泄漏和元素零值设置等问题时的策略和选项,它们在新版本Go给出的解决方案,以及这些改变可能导致的一些测试问题。此外,作者鼓励开发人员正确使用新功能,并尽量避免上述列举的陷阱。

《Routing Enhancements for Go 1.22》。这篇文章名为"Routing Enhancements for Go 1.22",主要介绍了 Go 1.22 版本中 net/http 包的路由器提供的新特性:方法匹配和通配符。这些新特性让你可以使用模式,而非 Go 代码,来表达常见的路由。这种新功能,尽管简单易懂,但要选择出多个匹配请求的最佳模式却是一项挑战。文章还详细阐释了如何在新版 Go 中使用这些新特性,以及这些引入的变化如何影响了 ServeMux 方法 handle 和 handleFunc 。此外,还描述了新模式如何更具优先级,并解释了其背后的原理。同时,为了保持新旧版本的兼容性,作者们也努力使新的模式语法能覆盖旧的,并使新的优先级规则能泛化旧的规则。总体上,这些改变是 Go 语言团队不断努力使 Go 成为构建生产系统的优秀语言的一个持续过程的一部分。

听GPT 讲Rust源代码--compiler(6)

使用Apache Kafka的Golang实践指南

《Go 为什么不支持从 main 包中导入函数》。这篇由煎鱼撰写的文章,题为 "Go 为什么不支持从 main 包中导入函数?",对于这个话题进行了深度解析。其首先提到,虽然Go的规范并没有明确禁止从main包中导入函数,但我们在实际运行中会被拒绝,提示main包是一个程序而非可以导入的包。这一现象的原因来自于经过多次变动的规定,如2011年移除了 "程序中的其他包都不能命名为 main" 的要求,然后在2015年又新增了限制。这样的变化主要是为了避免增加复杂度和不安全性。比如,一个函数可能会做出自己拥有完全控制权的假设,所以如果引入多个main包中的函数,可能会产生在初始化顺序、全局变量的注册等方面的冲突。这篇文章认为Go官方的做法在理论上可以解决复杂度和安全性问题,但对于有历史债务的项目,对于需要维护多个Go项目工程,相当于磨灭了一条道路,其实比较尴尬。

《fasthttp是如何做到比net/http快十倍的》。这篇文章讲解了fasthttp如何做到比net/http快十倍的原理。fasthttp相比于net/http在处理流程上有所差异,net/http是一个连接新建一个goroutine,当连接数非常多的时候会给系统带来一定的压力。而fasthttp则是建立了workerPool,每个workerChan在后台都会有一个Goroutine来处理其中的连接。此外,fasthttp的快速也得益于几个方面的优化:连接复用,大量使用了sync.Pool进行内存复用以及通过unsafe.Pointer指针进行[]byte和string转换来避免内存分配和拷贝的消耗。

《万字长文讲解Golang pprof 的使用》。这篇文章主要讲述了Golang的pprof工具的使用。pprof工具是Golang中用于性能分析的一个工具,它可以分析出cpu使用情况、内存占用、阻塞情况、线程和协程等信息。文章中详细阐述了如何使用此工具,主要有两种方式,一种是通过http接口的方式暴露出pprof的采集控制界面,另一种是在程序中通过代码来启动相应指标的采集示例。文章还详细介绍了如何解析通过这两种方式获取的输出信息。本文的主要目的是将pprof工具的使用方式用思维导图的形式展示出来,这样可以帮助读者更好地理解和使用pprof工具。

《一篇实用的关于云上K8s应用分账实践》。本文讲述云上Kubernetes(K8s)应用的成本分摊实践,涵盖了成本分摊的核心概念及阿里云ACK FinOps套件的应用。文中首先以前期预算为集群规划的依据,并讨论了随着业务发展对成本分摊精准度的提升需求。介绍了如何根据Pod的核/时成本,通过ACK集群、计算节点、命名空间和应用Pod这四个维度进行费用分摊。文章还分析了单资源和混合资源分摊模型,并讨论了如何设置Request和Limit来优化资源利用。对于多云和混合云场景,分享了如何通过ACK One实现统一管理和成本分析。针对复杂业务场景,讲述了自定义定价模版的使用方式,允许通过配置实现成本定制需求。对于追求细节管理和精细化运营的团队,这篇文章提供了宝贵的指导。

《如何使用 K8s 两大利器"审计"和"事件"帮你摆脱运维困境》。这篇文章主要讲述了如何使用 Kubernetes(K8s)的"审计"和"事件"功能来帮助进行日常集群运维工作。文章首先指出了运维工作中可能出现的一些问题,例如应用被删除、Apiserver负载突变、集群节点出现问题、节点自动扩容等。随后,文章进一步解释了 Kubernetes的审计和事件是如何运作的,强调了善用这两种工具可以提高集群的可观察性,为运维工作带来极大的便利。总的来说,这篇文章为运维人员提供了一种解决方案,通过使用 Kubernetes的审计和事件,可以更好地管理和监测集群的状态。

【Go 工具】竞态条件检测神器 Race Detector

使用Redis入门Golang

一道面试题: Top K 问题

《理解 Docker 容器中 UID 和 GID 的工作原理》。这篇文章详细解析了 Docker 容器中 UID 和 GID 的工作原理。首先,作者概述了用户名、组名、用户ID(UID)和组ID(GID)在容器内运行的进程与主机系统之间的映射对于构建安全系统的重要性。随后,文章分析了uid/gid在Linux系统的安全性,强调了单一内核概念以及uid/gid的分配方式。接着,作者运用实例解释了Docker运行的过程以及如何通过Dockerfile定义和启动不同用户。最后,文章讲述了如何掌控和控制容器的访问权限。在阐述以上内容的同时,文章也提供了一些实际示例来说明这些观点。

《如何基于Docker镜像逆向生成Dockerfile》。这篇文章介绍了如何将Docker镜像逆向生成Dockerfile。文章主要讲述了利用开源工具Dedockify的操作方法与工作原理。该工具通过Python脚本,利用存储在每个镜像层旁边的元数据,逐步遍历层级树,收集与每个层相关联的命令,重建镜像构建过程中执行的命令序列,从而得到近似的Dockerfile。不过,因为无法访问执行原始docker build命令时存在的构建上下文,如果使用了COPY或ADD指令,生成的输出可能不完全匹配原始的Dockerfile。

《通过多阶段构建减小Golang镜像的大小》。本篇文章主要介绍了如何通过多阶段构建减小Golang镜像的大小。首先,作者提出了一个通用的Dockerfile,并指出其生成的镜像大小超过300MB,主要因为包含了所有的Golang工具。然后,作者提出了多阶段构建的方法,它能从不同的基础镜像构建,有选择地将文件从一个阶段传递到下一个阶段,从而减小镜像大小。在本例中,通过二级构建,镜像大小已降至11.7MB。最后,还探讨了使用名为scratch的空白镜像进一步减小镜像大小的可能性,使得镜像最后降至6.34MB,但作者强调这需要慎重考虑,因为最后生成的镜像将完全没有任何工具。

《k8s 到底是什么,架构是怎么样的》。这篇文章主要讲述了 Kubernetes(K8s)的基本概念、架构和工作原理。Kubernetes,因单词过长,我们通常简化为k8s。k8s 是一种容器的协调工具,位于应用服务和服务器之间,能以策略的方式协调和管理多个应用服务。通过一个 yaml 文件的配置,可以定义应用的部署顺序等信息,自动部署应用到各个服务器上,还能让它们崩溃后自动重启,可以自动扩容和缩容。Kubernetes 的服务器分为两部分:控制平面和工作节点,前者负责控制和管理各个节点,后者则负责实际运行各个应用服务。k8s 的命令行工具为 kubectl,用于执行各类操作命令。

《Go 泛型有没有可能在后期改为 <> 尖括号》。这篇文章主要讨论了Go语言在处理泛型时,为何并没有采用类似Java和C++的 <> 尖括号表示法,而是选择了中括号 []. 首先,使用尖括号可能导致语义混淆,如 a, b := w < x, y > (z) 此句,如果使用尖括号,程序可能在编译阶段无法确定该行表达式的具体含义。其次,使用圆括号也会导致同样的问题,比如 func F(T any)(v T)(r1, r2 T), 无法快速准确判断出参数和返回值部分。此外,Go官方也不希望使用非ASCII的字符。作者还提到社区中对Go的处理方式存在一些争议,部分社区成员认为如果使得编译器解释尖括号不再困难,就可以采用这种符号。然而,总的来说,基于已有的实践和规范,Go语言在未来可能也不会改变其泛型的表示方式。

《Rust中channel的使用》。这篇文章主要介绍了Rust编程语言中Channel的用法。其中,Channel是Rust中用于在不同线程间传递信息的通信机制,实现了线程间的消息传递。每个Channel由发送端和接收端两部分组成,其设计理念是“通过通信来共享内存,而非通过共享内存来通信”,以此避免了数据竞争和共享内存的复杂性。该文章进一步详细介绍了如何在Rust中创建和使用Channel,并给出了相关代码示例。最后,文章阐述了多种Channel模型,包括Rust标准库中所使用的MPSC(多生产者,单消费者)模型。

K8s部署方式大全:从基础到进阶,一文带你掌握所有技巧

k8s从入门到精通 -- 更适合中国宝宝体质

📒 后端相关

《万字+33张图探秘OpenFeign核心架构原理》。本篇文章深入探讨了SpringCloud核心组件OpenFeign的核心架构原理。文章分为四个部分,首先解释原始Feign的使用和基于SpringCloud的进化过历程;然后详细讲解了Feign底层工作原理,依赖于JDK动态代理和核心组件如Contract、Encoder、Decoder等;接下来分析了SpringCloud是如何整合Feign的,并且讨论了OpenFeign的多种配置方式及其优先级;最后,文章通过丰富的图示和代码示例,使读者可以更好地理解并运用这一工具。这篇文章对于理解和运用OpenFeign非常有帮助,无论是对于初学者还是有经验的开发者。

《三万字长文:如何去排查JVM内存问题》。这篇文章是一份详尽的指导,讲述了如何排查JVM内存问题。文中首先定位了技术问题的范围,确定适用于JDK8至JDK11。接着,作者提出了系统化的排查原则,并提供了一步步的诊断流程,从基本信息收集、判断内存增长原因,到具体分析内存问题的可能来源。文章详细介绍了如何利用不同的命令和工具(如jmap、jstat、Arthas等)进行详细的分析,并根据内存使用情况,向读者展示了如何确定是堆内存问题还是堆外内存问题。总之,文章为那些需要深入理解和处理JVM内存问题的开发者和运维人员提供了宝贵的知识和技巧。

《如何避免MYSQL主从延迟带来的读写问题》。这篇文章讨论了如何处理在MySQL主从部署架构中普遍存在的主从同步延迟问题,以保持读写操作的一致性。文章首先介绍了主从延迟产生的场景及其对读写分离原则的影响。然后,详细解释了主从复制的原理,并提出了两种避免主从数据不一致的技术方案:一是使用select master_pos_wait函数来等待从库同步至特定的binlog位置点;二是在开启GTID模式的情况下,通过select wait_for_executed_gtid_set函数检查GTID集合是否已同步。这两种方法均旨在确保从库数据的准确性,从而整体上减轻主库的压力。总体上,文章为MySQL数据库管理员提供了缓解主从延迟导致的读写问题的具体实施方案。

《这些年背过的面试题——ES篇》。这篇文章是一篇针对Elasticsearch(ES)的面试指南,它涵盖ES基础知识点和面试过程中常见问题。内容包括ES的功能特性介绍(如分布式架构、全文搜索、数据分析等)、主要的使用场景描述、与其他搜索引擎的对比(Lucene和Solr)、以及ES的基本概念解释。文章还详细探讨了ES的高级特性,如映射、DSL查询、聚合分析和智能搜索建议器。此外,作者还分享了关于数据索引优化的实战技巧和策略,提供了写优化、读优化和索引重建的方案,这些方案对ES数据存储和查询的性能有显著影响,最后还对Deep Paging性能问题提供了解决方法。对正在准备面试或者希望巩固ES知识的读者而言,这篇文章是一个宝贵的资源。

《什么是MySQL锁?有哪些锁类型》。这篇文章详细地介绍了MySQL中的锁定机制及其类型。起初概述了锁的作用,即协调多进程或线程对资源的并发访问,在数据库环境下,锁对于保持事务的正确性与一致性至关重要。作者明确区分了MySQL中锁的级别,从全局锁、表锁(读锁、写锁)到元数据锁、意向锁,直到行锁的多种形式(记录锁、间隙锁和临键锁)。文中还探讨了AUTO-INC锁的作用和相关优化,举例说明了其在INSERT操作中的应用。此外,文章也涉及了如何根据不同的情况优化锁的使用以及如何避免由锁产生的性能瓶颈。这篇文章为理解MySQL的各种锁类型和锁机制提供了宝贵的信息,特别对于数据库管理员和那些需要管理并发数据访问问题的开发人员来说,具有很高的实用价值。

📒 前端相关

Vue 团队正式开源 Rolldown:基于 Rust 的超快 JavaScrip 打包工具!

打造舒适的vscode开发环境

相比于 Node.js,Deno 和 Bun 到底能带来什么

MDH Weekly 122 - 《招人》

+ + \ No newline at end of file diff --git "a/2024/3\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/3\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" new file mode 100644 index 0000000000..1ece06c281 --- /dev/null +++ "b/2024/3\346\234\21017\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -0,0 +1,23 @@ + + + + + +3月17日内容汇总 | Frontend Weekly + + + + + + + + + + + +
+
Skip to main content

3月17日内容汇总

· 46 min read
加菲猫

🌟 AI 相关

《南洋理工发布多模态金融交易Agent,平均利润提高36%!》。本文介绍了南洋理工大学发布的多模态金融交易Agent,通过融合大语言模型(LLMs)和多模态数据处理,提高了金融交易的效益。传统基于规则的交易系统在适应市场波动方面存在不足,而基于强化学习的系统虽然适应性更好,但在处理多模态数据和可解释性方面仍面临挑战。该文中提出的FinAgent是一种先进的多模态基础代理,能够综合分析多种形式的金融数据,提供精确的市场趋势分析和决策支持。实验证明,使用FinAgent进行金融交易可以平均提高36%的利润。论文链接:https://arxiv.org/pdf/2402.18485.pdf

《大模型推理:A100/H100 太贵,何不用 4090?》。本文介绍了大模型推理时,为什么可以考虑使用4090显卡。相比于A100和H100显卡,4090在性价比上更高,尤其在极致优化的情况下,甚至可以达到H100的2倍性能。文章指出,A100、H100和4090在算力方面的差距并不大,最大的区别在通信和内存方面。由于大模型训练使用高性能的通信,4090通信效率相对较低,因此在大模型训练中并不适用。然而,在推理(inference/serving)方面,4090在性价比上有优势,尤其是相对于H100显卡而言。文章还提到了GPU的训练性能和成本对比,以及大模型训练所需的算力和GPU数量等问题。详细内容可参考文章链接。

《精度提升!南加大等 | 提出分治Prompt策略,提升LLM分辨力》。本文介绍了一种基于分治算法的Prompt策略,旨在提高大语言模型(LLM)的分辨力。现有的提示策略在处理涉及重复子任务和含有欺骗性内容的任务时存在一定限制。为了解决这个问题,研究人员提出了一种基于分治算法的提示策略,利用分治程序来引导LLM的求解过程。该策略将任务划分为子问题并分别求解,然后合并子问题的答案。通过实验证明,这种分治策略能够提升模型在大整数乘法、幻觉检测和新闻验证等任务中的性能,相比传统提示策略具有更好的准确率和性能指标。论文地址:https://arxiv.org/pdf/2402.05359.pdf

《开源版“Devin”AI程序员炸场:自己分析股票、做报表、建模型》。这篇文章介绍了一个基于MetaGPT的开源项目Data Interpreter,该项目旨在处理数据实时变化、任务之间的复杂依赖关系、流程优化需求以及执行结果反馈的逻辑一致性等挑战。通过演示,展示了Data Interpreter在分析股票、预测葡萄酒质量、自动抠图、预测疾病进展和预测机器运行状态等方面的能力。该项目由MetaGPT团队与多所高校合作推出,提供了一种自主进行数据分析和建模的开源工具。

《【原创】一文读懂RAG的来源、发展和前沿》。本文介绍了检索增强生成(RAG)技术,该技术结合了检索和生成过程,旨在提高机器生成文本的相关性、准确性和多样性。文章详细解释了幻觉问题的存在以及解决幻觉问题的几种常见方法。RAG利用外部数据源进行信息检索,将检索到的信息作为上下文输入到生成模型中,从而帮助生成正确的响应。讨论了RAG的核心部件,如向量数据库、查询检索和重新排序。同时介绍了RAG在知识图谱和树结构方面的拓展。

《万字长文解析:大模型需要怎样的硬件算力》。这篇文章探讨了大模型在算力、存储、通信等多个方面上硬件资源的挑战和瓶颈。文章分析了以Transformer结构为核心的大模型在算力瓶颈、显存瓶颈和通信瓶颈方面的困境,以及当前所采取的硬件资源优化技术。此外,文章还提供了对大模型参数量和算力需求的量化估算,为选择合适的硬件设备和评估资源需求提供了指导。

《什么是好的大模型训练数据?》。本文基于Lilian Weng的博客,讨论了大模型如LLM在训练过程中对高质量数据的需求。认为高质量数据来源于“高质量人类”产生的标注数据,并强调了数据处理的重要性,提到了数据标注、质量控制和错误修正的重要步骤。文章还讨论了用于评估数据质量的多种方法,如Influence Functions和Noisy Cross-Validation,并提出了专注于“搭建高质量的数据标注pipeline”的企业方向。最后指出,在AI时代大量产出的数据中维护数据质量,是一个值得关注的挑战。

《读过的最白话讲清楚RAG原理的文章》。这篇文章直观地阐释了检索增强生成(RAG)的概念和工作原理,它是一种结合检索和生成的问答系统。该系统首先通过检索步骤找到与用户问题最相关的知识库内容,然后将这些内容与问题共同输入大型语言模型(例如ChatGPT)以生成答案。文章详细介绍了如何利用嵌入模型对知识库文本进行索引,以便协助语言模型进行精确的检索。此外,它还探讨了语义搜索背后的核心原则和技术细节点,如何通过嵌入找到与用户输入最匹配的知识,以及如何格式化文档以供语言模型使用,以便获得更高效的回答。

《LLM推理算法简述》。本文介绍了用于提高大型语言模型(LLM)推理性能的关键技术与策略。内容涵盖显存优化方法,如KV Cache减少显存浪费、MQA和GQA减少KV-Cache数量、Page Attention进行显存管理,以及提高推理速度的FlashAttention改进。文章还探讨了算子融合技术,比如FasterTransformer和DeepSpeed Inference的应用,以及调度优化策略如Async Serving和Dynamic Batch,最后介绍了用于处理大模型的分布式并行技术。这些优化手段能显著提高LLM推理过程中的性能与效率。

《数学推理增强!微软 | 提出数据合成框架:KPDDS,微调Mistral-7B性能超34B模型!》。微软的研究团队为提升大型语言模型(Large Language Models, LLMs)在数学推理任务的性能,提出了关键点驱动的数据合成(KPDDS)框架。KPDDS利用真实数据源中的关键点和示例对生成高质量问答对来训练语言模型。研究者基于此框架创建了KPMath数据集,进一步结合推理密集型数据形成KPMath-Plus数据集。在MATH测试集上,微调后的Mistral-7B模型达到了39.3%的零样本通过率,超越了数量更多的34B模型,证明了KPDDS的有效性与创新性。这一成果标志着LLMs在数学推理方面的性能得到显著提升。

《首个AI软件工程师上线!已通过公司面试抢程序员饭碗,华人创始团队手握10块IOI金牌》。在这篇文章中介绍了由华人创立的Cognition AI公司开发出来的首个人工智能软件工程师Devin。与现有GPT-4等模型不同,Devin能够独立完成复杂的编程任务,并已成功通过人工智能公司的面试和在自由职业平台Upwork上接单。得益于Cognition AI在长期推理和规划方面的进步,Devin在做决策和执行任务时,能回想相关上下文、随时间学习并修复错误。这标志着人工智能在理解真实世界软件工程问题方面取得了突破,为AI领域迈向更高层级的自动化及监督性工作开辟道路。

《向数字世界AGI迈进!智能体已经从头开玩「荒野大镖客 2」了》。这篇文章展示了如何使用Cradle这一通用计算机控制智能体框架进行AI的研究与应用,在无需内部API支持下控制键盘和鼠标以及与各类软件交互。文章来源于北京智源人工智能研究院、新加坡南洋理工大学和北京大学的联合研究。Cradle由六大模块组成,包括信息收集、自我反思、任务推断、技能管理、行动计划和记忆模块。这些模块让智能体能够自主进行决策和任务执行。研究团队通过将Cradle部署于《荒野大镖客 2》这一复杂的3A游戏中证明其通用性,Cradle能够自主完成游戏主线和探索开放世界。智能体的这种通用能力标志着智能体研究向通用人工智能(AGI)迈进的重要一步。

《深入浅出 LangChain 与智能 Agent:构建下一代 AI 助手》。文章深入讲解了LangChain工具箱及其如何赋能智能Agent,以构建更加智能的AI助手。LangChain利用大型语言模型如GPT-4,提供了一个开源软件框架,可助力开发者搭建基于语言模型的应用。它提供了六大类组件,如模型、提示模板、索引、文档加载器、文本分割器和向量存储,让GPT-4等模型不仅能处理语言,还能与外部API互动、管理用户上下文。文章以构建人脸技术问题排查助手为例,展示如何运用LangChain来协助问题诊断与智能交互,朝向自主、高效的智能应用发展。

《使用零一万物 200K 模型和 Dify 快速搭建模型应用》。本文详细介绍了如何使用零一万物的200K模型和Dify(LLM IDE)快速构建模型应用程序。作者首先对一个机器学习电子书进行翻译,并分享了源代码,然后引导读者如何申请和配置零一万物模型API。随后,作者说明了如何使用Dify IDE快速搭建和调试模型应用程序,以及如何使用Golang和AI模型自动化电子书的翻译过程。最后,作者总结了自动翻译程序的构建过程并展示了批量翻译内容的方法。整篇文章不仅是使用Dify的实操指南,还提供了一种效率化、自动化处理文本内容的示例,适合那些在寻找快速开发和集成大语言模型到应用中的开发者参考。

《一文看完多模态:从视觉表征到多模态大模型》。本文为读者系统梳理了图文多模态与多模态大模型领域的发展,尤其聚焦在视觉表征和视觉与文本融合方法上。文章从卷积神经网络(CNN)及其预训练方法开始讲起,从图像处理的视角介绍了多模态融合的初期方法,如LXMERT、VL-BERT和UNITER等。进一步,文章论述了Vision Transformer(ViT)及其预训练方案如MAE和BEIT,以及基于ViT的多模态对齐与预训练技术,如CLIP和VILT等。作者通过丰富的示例和对比,使读者能够理解这些模型在结构和功能上的不同与联系,为进一步研究提供了宝贵的资源和视角。

《浙大&中科院让Agent学会自我进化,玩德州扑克心机尽显》。Wenqi Zhang等研究者介绍了名为Agent-Pro的AI智能体,它使用大模型(GPT-4)为基础,配合自我优化的策略,能够运用虚张声势、主动放弃等复杂策略玩转德州扑克和21点等非完美信息博弈游戏。Agent-Pro的设计使其能够自我进化,适应复杂和动态的游戏环境,并通过策略层面的反思和世界模型的优化来提高自己的表现。该研究展示了AI在博弈领域的进步,同时为解决多agent现实世界问题提供了新策略。

《面向工业级推荐!“小”LLM也能做好推荐系统》。本文由蚂蚁集团AI创新研发部门NextEvo撰写,介绍了他们的论文《Can Small Language Models be Good Reasoners for Sequential Recommendation?》获得WWW 2024 (Oral)录用。文章针对大语言模型(LLM)在推荐系统应用时代价高昂的问题,提出了一种名为SLIM的基于蒸馏的大模型推荐框架。SLIM通过知识蒸馏技术,将大模型的知识和推理能力迁移到较小的模型上,从而达到用更少参数实现高效推荐的效果。论文强调SLIM在处理长尾物品和新用户推荐的优势,改进了传统基于交互数据的推荐系统偏差问题,并在保持推荐准确度和可解释性的同时降低资源消耗。

《AIOps 智能运维:有没有比专家经验更优雅的错/慢调用分析工具?》。本文介绍了阿里云应用实时监控服务 ARMS 最新推出的错/慢 Trace 分析功能。此功能不依赖专家经验,能对比分析错/慢 Trace 和正常 Trace 的每个维度,从而快速定位问题根源。针对生产环境下调用时延和错误调用的多种因素(如流量不均、单机故障等),ARMS 通过对错/慢 Trace 和正常 Trace 的对比,帮助用户发现异常的共同特征,从而定位到具体问题。这个工具提供了一种优于传统专家经验的快速、有效诊断系统问题的方法,并且附有最佳实践案例。文章最后提供了免登录的 demo 体验链接,引导用户了解和使用该功能。

《CUDA编程优化方法——Memory coalescing》。这篇文章对CUDA编程中的内存合并技术—— Memory coalescing进行了详细介绍。文章首先解释了全局内存的特点以及为何访问速度慢,并阐述了Memory coalescing的目的是通过合并内存访问操作来有效地利用带宽。通过对多维数组的存储方式及访问模式的解析,文章进一步讲解了Memory coalescing的具体实现细节,如何在多维数组访问和矩阵乘法中实现内存访问的合并。最后,文章提供了优化策略,以改进计算的内存访问模式,并提高CUDA内存传输的效率。

《扩散模型如何构建新一代决策智能体?超越自回归,同时生成长序列规划轨迹》。本篇文章介绍了扩散模型在强化学习中的多种应用场景,探讨了如何超越传统的自回归方法,同时生成长序列规划轨迹来模仿人类的决策过程。上海交通大学的团队所作的综述梳理了扩散模型在强化学习中的运用如轨迹规划、策略表征、数据合成,及其解决长序列规划误差累积、策略表达能力受限和数据稀缺等问题的巨大潜力。最终,文章对扩散模型未来的发展方向进行了展望,提出了生成式仿真环境、加入安全约束、检索增强生成及组合多种技能等多个研究方向。

《动手做一个最小RAG——TinyRAG》。本文由不要葱姜蒜指导读者如何一步步实现基于检索增强生成技术(RAG)的简化模型——TinyRAG。TinyRAG仅包含RAG核心功能,即Retrieval(检索)和Generation(生成)两个模块。文章详细介绍了RAG的基本结构,包括向量化模块、文档加载与切分模块、数据库和检索模块,以及如何根据检索内容生成回答。此外,还提供了对应的开源项目代码,助力理解语言模型与RAG的原理,并能够在实践中加以应用和拓展。

《聊一聊Transformer中的FFN》。这篇文章探讨了为什么Transformer的前馈神经网络(FFN)部分长期以来几乎没有大的改动。文章通过比较不同的激活函数,如ReLU、GeLU和Swish等,分析它们在Transformer中的应用效果和局限性。同时探讨了线性投影的必要性、参数量及其对模型容量和记忆力的影响。此外,文章还涉及了混合专家模型(Mixture-of-Experts,MoE)以提升Transformer的效率,并讨论了构建通用人工智能(AGI)所需要的结构特性,特别是放缩定律(Scaling Law)、上下文学习(In-Context Learning)、效率提升(Better Efficiency)和终生学习(Life-long learning)的重要性,最后对未来结构创新给出透彻见解。

⭐️ Go & 云原生 & Rust 相关

《More powerful Go execution traces》。Go的runtime/trace包提供了用于理解和排查Go程序的强大工具,允许对goroutine的执行进行跟踪。新版本Go大幅度降低了执行跟踪的运行时开销,从多数应用中的10-20% CPU下降到1-2%。文章介绍了如何通过将trace分割,从而使得trace可以扩展且保持低开销,还实现了飞行记录功能,使得即使在事件发生后也能从trace中获取信息。Go也提供了一个实验性的trace读取API,使程序性的跟踪分析成为可能。

《Rust: 实现比特币的交易模型》。本文详细介绍了比特币的交易模型中的UTXO(未花费交易输出)模型,并使用 Rust 语言来实现和展示其运作过程。UTXO 模型与传统的账户余额模型不同,将用户的余额分散存储在多个UTXO中。每个UTXO代表比特币网络上一笔可用于未来交易的输出。文章解释了UTXO模型的工作原理、优势以及交易处理流程,包括选择输入、生成输出、签名交易和广播交易。接着,文章提供了一个 Rust 实现的简化示例,展示了如何定义交易结构体、输入、输出以及UTXO集合,并介绍了基本的操作方法。如果你对比特币交易模型和 Rust 编程感兴趣,可以阅读该文章了解更多细节。

《深入理解 Go Modules: 高效管理你的 Golang 项目依赖》。本文详细介绍了 Go Modules 在 Golang 项目中的使用方法和原理。文章首先回顾了 Go 依赖管理的历史,从 GOPATH、Go Vendor 到 Go Module 的演进过程。然后讲解了模块、包和版本的概念,包括模块路径、包路径以及版本的格式和语义。接着,文章介绍了 Go Modules 的环境配置,包括 go env 环境变量和依赖管理文件(go.mod 和 go.sum)的作用和使用方法。最后,文章提供了一些实用技巧和常见问题的解答,帮助读者更好地理解和应用 Go Modules。如果你对 Golang 项目的依赖管理感兴趣,可以阅读该文章了解更多详情。

《Kubernetes集群节点处于Not Ready问题排查》。当Kubernetes集群中的节点显示为"Not Ready"状态时,这篇文章提供了一系列的排查步骤。首先,通过运行特定的kubectl命令来确认节点的状态并获取节点详细信息,检查可能的错误消息或者警告。接着,进入节点系统查看各种系统日志,并使用相关命令如grep、cat或tail来辅助分析。文章还建议检查kubelet服务状态和配置文件,确认系统资源是否充足,试图解决可能存在的磁盘空间和网络问题。最后,通过使用诸如ping、traceroute等诊断工具确保节点能够与主节点通信,并检查重要的网络端口是否开放。确保Kubelet能正确连接到Kubernetes API,并使用Kubernetes的诊断工具如kubectl get componentstatus检查组件状态。通过这些步骤,可以系统地排查并解决"Not Ready"的问题,保持集群健康。

《Go 错误处理: 用 select-case 来解决这个历史难题?》。煎鱼在这篇文章中介绍了一个新的Go语言错误处理提案,这个提案尝试用select-case结构作为错误检查的替代。这个新语法允许在select关键字之后声明一个变量为“陷阱”,赋值给该变量时触发case检查,以减少传统的if err != nil检查的繁琐性。新提案保持了Go1代码的兼容性,尝试提供一个更简洁、向后兼容的错误处理方式,尽管目前社区内对此仍未达成共识。

《K8s蓝绿部署:优雅应对应用程序更新挑战》。本文详细探讨了使用Kubernetes(K8s)进行蓝绿部署的方法,以达到无缝更新应用程序并最小化宕机时间。蓝绿部署是一个运行两个相同生产环境的模式,能够在更新时切换流量,确认无误后便去除旧环境。文章指导了从创建命名空间、创建和应用部署、服务及其路由规则、执行蓝绿切换,到最后的验证和回滚过程。这一过程不仅优化了应用版本的滚动更新,也为开发者提供了快速回滚的方案,以应对可能出现的问题。

《Go 中的高速数据包处理:从 net.Dial 到 AF_XDP》。文章介绍了使用 Go 语言进行高速数据包处理的多种方法,包括 net.Dial、原始套接字、系统调用、pcap 和 AF_PACKET,直至最新的 AF_XDP 方式。作者详细对比了每种方法的性能,从简单的 net.Dial 模式演进到 AF_XDP,逐步提高数据包每秒处理数量,同时指出各方法的使用场合和限制。通过基准测试,发现使用 AF_XDP 可实现最高性能,处理速度是使用 net.Dial 方法的4倍多。这些技术探讨对于需要大量网络数据包处理的场景,如网络监控、性能评估等都是非常重要的。

《数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)》。文章探讨了在云原生时代下,有状态服务(如生产环境的数据库)是否适用于容器化并由Kubernetes进行管理的问题。以B站Elasticsearch和Clickhouse的容器化和Kubernetes编排实践为例,文章详细介绍了在容器环境中部署这些有状态服务的挑战和解决方案,包括控制器的选择、持久化存储、磁盘调度、调度器、容器网络、服务发现以及如何保证集群和数据的高可用性。作者分享了通过Operator管理有状态服务应用、使用本地盘PV提升性能、LVM技术的动态扩缩容方案以及通过macvlan进行容器间高效通信的技术细节。

《一文带您探索 Kubernetes 中的容器类型》。文章介绍了在 Kubernetes 系统中常见的四种容器类型:初始化容器(Init Container)、边车容器(Sidecar Container)、临时容器(Ephemeral Container)和多容器(Multi Container)。初始化容器用于运行 Pod 中主容器启动前的准备工作,而边车容器则与主应用容器并行运行,为其提供支持服务。临时容器主要用于故障排除,而多容器 Pods 允许并行运行多个容器,共享资源和数据。文章提供了每种容器的详细使用案例、配置方法和命令,并强调了各自的特点与应用场景。

《4 秒处理 10 亿行数据! Go 语言的 9 大代码方案,一个比一个快》。软件工程师Ben Hoyt挑战使用Go语言处理10亿行数据,并提出了9种解决方案,其中最快在4秒内完成。这些方案只使用Go标准库,包括简单但优化的map处理、并行化处理等。Ben的方案虽未最快,但展现了独立思考的价值。他的测试表明,彻底地数据处理和算法优化可显著提高性能,减少计算成本。

《Go arena 民间库来了,可以手动管理内存!》。文中作者煎鱼介绍了Go语言的一个新的第三方库ortuman/nuke,这个库允许开发者手动管理内存。文章首先回顾了Go官方对于arena手动内存管理提案的停滞现状,然后重点介绍了如何使用ortuman/nuke库进行内存管理,包括库的安装、使用案例以及如何在并发场景下保持线程安全。文章详细讲解了arena内存管理的优点,例如高效率和一次性释放,并对库的实际用法,如通过context在HTTP请求周期中管理内存,进行了展示。最后,基于性能考虑,文章还提供了并发与非并发业务场景下的基准测试结果以及性能差异。

Go 语言中如何大小端字节序?int 转 byte 是如何进行的

Go 中如何实现三元运算符?Rust 和 Python 是怎么做的

Go语言中 enum 实现方式有哪些?一定要绝对类型安全吗

Go 中如何打印结构体? 代码调试效率提升

《快看! Go 1.22 对for循环进行了两个大更新》。文章讨论了Go语言在 1.22 版本中针对for循环作出的两项主要更新:1. 每次迭代的for循环都将定义一个新的变量,不再共用同一个变量;2. 引入了对整数范围的循环迭代支持。这些更新解决了闭包在并发执行时共享变量带来的问题,同时也简化了循环结构,提高了编写对整数范围进行迭代代码的方便性。文中提供了详细的代码示例来展示新旧版本之间的差异,并说明了如何利用新特性来编写更高效的Go代码。

《从慢速到SIMD》聊Go边界检查消除》。本文讨论了Go语言中边界检查消除(BCE)的相关技巧和最佳实践。文章首先回答了为何在Go代码中优化时选择使用a[i:i+4:i+4]而不是a[i:i+4]的问题,指出前者能减少编译器工作量从而提高性能。然后,介绍了Go101提出的BCE技术详解与应用实例,以及如何使用编译命令来检测边界检查的存在。文中还全面梳理了Go BCE技术的发展历程,以及在不同场景下消除冗余边界检查的方法,包括利用循环变量、常量索引等策略来提高代码执行效率。最后,提供了多种编程技巧以及相关讨论和参考资料,针对遇到的编程问题提出解决方案。

📒 后端相关

《分库分表已成为过去式,使用分布式数据库才是未来》。本文讨论了随着Mysql数据库性能下降,分库分表的局限性及其所引发的问题,如性能、事务、数据迁移等,并提出使用分布式数据库作为解决方案。文章详细介绍了TiDB这款分布式数据库的架构、特性和优势,包括其金融级的高可用性、水平扩容能力、兼容性以及云原生设计。文章强调TiDB在处理大规模数据时的效率和可维护性,终结分库分表的做法,并通过性能测试展示了TiDB与MySQL在不同场景下的性能表现。最终总结,对于数据量大的应用场景,采用TiDB来适应未来数据存储的需求是一个更优的策略。

《手把手带你精简代码-京东零售后端实践》。本文分享了京东零售后端在面临代码库日渐庞大和腐化的问题时,采用的代码精简方法。文章分为背景介绍、代码精简步骤和实施方法三部分,着重介绍了使用IntelliJ IDEA自带工具和PMD插件进行静态代码检查的步骤、配置和优缺点,以及如何借助京东jacoco流水线进行动态代码检查。本文旨在降低代码维护成本、提升可理解性,并详细阐述了代码精简的实践过程和预期结果。

《跟着iLogtail学习无锁化编程》。文章探讨了在多线程情况下,如何通过无锁化编程优化软件性能。详细讲述了iLogtail在实现无锁高效日志采集时采取的策略,比如自旋锁的使用、原子操作、内存顺序、内存屏障等概念。还分析了不同类型的锁的适用场景与特点,包括互斥锁、递归互斥锁和读写锁等。此外,文章还描述了如何将大的锁细分为多个小锁,通过降低锁粒度提升并发性能,以及在iLogtail中如何通过双Buffer机制来读写分离,减少锁的争用。最终,通过无锁化编程提高了iLogtail的日志采集性能,实现了低资源消耗和高性能。

《MYSQL 是如何保证binlog 和redo log同时提交的?》。文章讨论了如何确保在MYSQL中binlog(备份和主从同步用的日志)与redo log(InnoDB引擎层的日志,用于崩溃恢复)同步提交,以及为什么这一点对于防止主从数据不一致至关重要。文中解释了事务处理中的两个关键参数:innodb_flush_log_at_trx_commitsync_binlog,这两个值设置为1时可以确保两种日志的同步提交。该文还介绍了MYSQL的两阶段提交机制如何工作,并提出了业务开发中两阶段提交逻辑的思考,指出在有依赖关系的服务操作中,通过预锁定资源、请求成功后递减资源来保持数据的最终一致性。

《这些年背过的面试题——分布式篇》。本文从分布式系统的基础概念、发展历程及核心问题出发,详细介绍了分布式系统设计中的关键技术点。文章涵盖了负载均衡、服务的拆分与集群、分布式事务、数据一致性问题以及分区容错性等话题,并探讨了CAP理论与BASE理论在实际应用中的权衡。同时,文中还详细解读了常见的一致性算法如2PC、3PC、Paxos、Raft的机制和用例。此外,作者针对如何实现分布式Session、如何确保分布式事务的一致性等常见面试题目提供了详尽的解答,适合做为面试备考资料。

《RocketMQ为什么这么快?我从源码中扒出了10大原因!》。这篇文章详细分析了RocketMQ高性能的10个关键因素:批量发送消息降低通信次数,消息压缩减少带宽和存储压力,基于Netty的高效网络通信模型,零拷贝技术优化磁盘读写性能,顺序写提高数据写入速度,高效数据存储结构,异步机制包括异步刷盘和异步主从复制提升存储效率,批量处理减少网络通信次数和资源消耗,锁优化以及线程池隔离提升并发处理能力。作者通过深入分析源码给出了RocketMQ快速处理和拉取消息的内在原因,并深入讨论了每种技术的优势和实现。

《领导叫我接手一个新业务系统,我是这样熟悉项目的!》。本文作者小许分享了接手新业务系统的熟悉流程和实践方法。包括与产品经理交流了解业务现状,绘制用例图、ER图以明确业务与数据模型,梳理后端模型和核心流程,并运用状态机流转图和时序图深度解析复杂逻辑。最后,还提到了绘制类图以理解代码结构。文章提供了一套系统性的工具和方法,目的是帮助新成员或负责新项目的开发人员快速掌握业务逻辑,有效推进项目进度。

📒 前端相关

《Tango 低代码引擎沙箱实现解析》。本文介绍了Tango低代码引擎的沙箱实现。Tango是一个用于快速构建低代码平台的低代码设计器框架,通过对源代码进行执行和渲染前端视图,实现了低代码可视化搭建能力。借助Tango构建的低代码工具或平台可以实现源码进出的效果,并与企业内部现有的研发体系进行无缝集成。Tango的设计器引擎部分已经开源,并提供了相应的开源代码库、文档和社区讨论组。欢迎加入社区参与到Tango低代码引擎的开源建设中。更多相关文章可以在文中提供的链接中找到。

《未来只需要 2% 的程序员?》。DHH在这篇文章中提出一个激进的观点,预测未来程序员的需求可能会大幅度减少。他比较了农业从97%的人口需求降至2%的变迁,暗示软件开发也可能面临着类似缩减。尽管这个行业曾经经历招聘热潮,但现在许多程序员面临职业前景不稳定。文章讨论了人工智能的发展给程序员职业带来的压力,同时也指出职业变革的不确定性。DHH认为,未来大多数程序员可能无需手动编程,但同时指出科技行业将更加融合进社会,并提高了它的价值。他鼓励程序员接受这一变化,并享受行业的黄金时代。

《前端智能化,扣子(coze.cn)能做什么?》。这篇文章探讨了扣子(coze.cn)平台如何通过提供一个简单的交互式界面来创建聊天机器人(Chatbot)。用户通过与扣子的对话,可以快速设置一个Chatbot,如自动化微信订阅号内容发布等。文章强调了平台的易用性和界面友好性,同时指出了一些潜在缺点,包括无法解决深度问题和偶尔遇到的技术故障。另外,通过知识库和数据库的集成,可进一步提升Bot的功能。作者对扣子的机器人创建过程、优势、建议和改进进行了详细介绍,并通过实操案例展示了前端智能化机器人的搭建过程。

+ + + + \ No newline at end of file diff --git "a/2024/3\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" "b/2024/3\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" index c6e8483178..b8c6deab65 100644 --- "a/2024/3\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" +++ "b/2024/3\346\234\2103\346\227\245\345\206\205\345\256\271\346\261\207\346\200\273/index.html" @@ -11,13 +11,13 @@ - - + +
-
Skip to main content

3月3日内容汇总

· 4 min read
加菲猫

alt text

封面图:用 switch-case 来解决 Go 错误处理的难题

🌟 AI 相关

LangChain 实战:Agent思维

详解大模型RLHF过程(配代码解读)

PromptFlow高质量AI应用 - 基于LLM的文档QA机器人

图解大模型计算加速系列:Flash Attention V1,从硬件到计算逻辑

使用搭载骁龙 8 Gen 3 的安卓手机运行 AI 大模型

生成式 AI 的发展方向,是 Chat 还是 Agent

聊聊大模型Agent技术,及和具身智能又有什么异同

复旦NLP团队发布80页大模型Agent综述,一文纵览AI智能体的现状与未来

知识问答系统的优化实践:LLM与RAG的结合艺术

一文解构大模型RAG问答关键环节及与LLM微调对比总结

Mistral AI发布Mistral Large模型

Mistral AI新模型对标GPT-4,不开源且与微软合作,网友:忘了初心

大模型微调新范式:当LoRA遇见MoE

Mistral Large,Le Chat来了!Mistral AI连放两个大招!

探索2024年1月的AI研究前沿:模型合并、专家混合与小型LLM的崛起

⭐️ Go & 云原生 & Rust 相关

Cargo的自定义命令扩展功能

听GPT 讲Rust源代码--compiler(2)

元老与新秀:Go sort.Search()和sort.Find()

KisFlow-基于Golang的流式计算框架实战(6)-Connector

跳槽必看のMySQL索引:B+树原理揭秘与索引优缺点分析

听GPT 讲Rust源代码--compiler(1)

KisFlow-基于Golang的流式计算框架实战(5)

用 switch-case 来解决 Go 错误处理的难题

KisFlow-基于Golang的流式计算框架实战(4)

KisFlow-基于Golang的流式计算框架实战(3)

图文讲透Golang标准库 net/http实现原理 -- 客户端

使用docker init编写Dockerfile和docker-compose配置

Go语言中常见100问题-#完结撒花

KisFlow-基于Golang的流式计算框架实战(2)

golang 高性能无 GC 的缓存库 bigcache 是怎么实现的

📒 后端相关

从0到1构建一个稳定、高性能Redis集群

这些年背过的面试题——SpringCloud篇

如何设计订单超时自动取消

📒 前端相关

2024 AI & 前端:回首展望,光芒未至,破晓之前!

看完zustand源码后,我的TypeScript水平突飞猛进

ElTable 二次封装:我用 Vue3.3 新特性完美解决了列插槽数据无类型提示问题!!!

ECharts 迎来重大更新,运行时包体积可减少 98%!

FFmpeg前端视频合成实践

2024 使用 TS 搭建 Node.js 服务器 - 快速教程

前端食堂技术周刊第 113 期:Node 年终总结、Node 新吉祥物、Qwik 2.0、React Labs 工作进展

- - +
Skip to main content

3月3日内容汇总

· 4 min read
加菲猫

alt text

封面图:用 switch-case 来解决 Go 错误处理的难题

🌟 AI 相关

LangChain 实战:Agent思维

详解大模型RLHF过程(配代码解读)

PromptFlow高质量AI应用 - 基于LLM的文档QA机器人

图解大模型计算加速系列:Flash Attention V1,从硬件到计算逻辑

使用搭载骁龙 8 Gen 3 的安卓手机运行 AI 大模型

生成式 AI 的发展方向,是 Chat 还是 Agent

聊聊大模型Agent技术,及和具身智能又有什么异同

复旦NLP团队发布80页大模型Agent综述,一文纵览AI智能体的现状与未来

知识问答系统的优化实践:LLM与RAG的结合艺术

一文解构大模型RAG问答关键环节及与LLM微调对比总结

Mistral AI发布Mistral Large模型

Mistral AI新模型对标GPT-4,不开源且与微软合作,网友:忘了初心

大模型微调新范式:当LoRA遇见MoE

Mistral Large,Le Chat来了!Mistral AI连放两个大招!

探索2024年1月的AI研究前沿:模型合并、专家混合与小型LLM的崛起

⭐️ Go & 云原生 & Rust 相关

Cargo的自定义命令扩展功能

听GPT 讲Rust源代码--compiler(2)

元老与新秀:Go sort.Search()和sort.Find()

KisFlow-基于Golang的流式计算框架实战(6)-Connector

跳槽必看のMySQL索引:B+树原理揭秘与索引优缺点分析

听GPT 讲Rust源代码--compiler(1)

KisFlow-基于Golang的流式计算框架实战(5)

用 switch-case 来解决 Go 错误处理的难题

KisFlow-基于Golang的流式计算框架实战(4)

KisFlow-基于Golang的流式计算框架实战(3)

图文讲透Golang标准库 net/http实现原理 -- 客户端

使用docker init编写Dockerfile和docker-compose配置

Go语言中常见100问题-#完结撒花

KisFlow-基于Golang的流式计算框架实战(2)

golang 高性能无 GC 的缓存库 bigcache 是怎么实现的

📒 后端相关

从0到1构建一个稳定、高性能Redis集群

这些年背过的面试题——SpringCloud篇

如何设计订单超时自动取消

📒 前端相关

2024 AI & 前端:回首展望,光芒未至,破晓之前!

看完zustand源码后,我的TypeScript水平突飞猛进

ElTable 二次封装:我用 Vue3.3 新特性完美解决了列插槽数据无类型提示问题!!!

ECharts 迎来重大更新,运行时包体积可减少 98%!

FFmpeg前端视频合成实践

2024 使用 TS 搭建 Node.js 服务器 - 快速教程

前端食堂技术周刊第 113 期:Node 年终总结、Node 新吉祥物、Qwik 2.0、React Labs 工作进展

+ + \ No newline at end of file diff --git a/2024/archive/index.html b/2024/archive/index.html index 1aad80c96f..d682efb706 100644 --- a/2024/archive/index.html +++ b/2024/archive/index.html @@ -11,13 +11,13 @@ - - + +
-
Skip to main content
- - +
Skip to main content

Archive

Archive

+ + \ No newline at end of file diff --git a/2024/atom.xml b/2024/atom.xml index c7fea2144d..336860aa73 100644 --- a/2024/atom.xml +++ b/2024/atom.xml @@ -31,6 +31,18 @@ + + <![CDATA[3月17日内容汇总]]> + https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/frontend-weekly/2024/3月17日内容汇总 + + 2024-03-17T00:00:00.000Z + + 🌟 AI 相关

《南洋理工发布多模态金融交易Agent,平均利润提高36%!》。本文介绍了南洋理工大学发布的多模态金融交易Agent,通过融合大语言模型(LLMs)和多模态数据处理,提高了金融交易的效益。传统基于规则的交易系统在适应市场波动方面存在不足,而基于强化学习的系统虽然适应性更好,但在处理多模态数据和可解释性方面仍面临挑战。该文中提出的FinAgent是一种先进的多模态基础代理,能够综合分析多种形式的金融数据,提供精确的市场趋势分析和决策支持。实验证明,使用FinAgent进行金融交易可以平均提高36%的利润。论文链接:https://arxiv.org/pdf/2402.18485.pdf

《大模型推理:A100/H100 太贵,何不用 4090?》。本文介绍了大模型推理时,为什么可以考虑使用4090显卡。相比于A100和H100显卡,4090在性价比上更高,尤其在极致优化的情况下,甚至可以达到H100的2倍性能。文章指出,A100、H100和4090在算力方面的差距并不大,最大的区别在通信和内存方面。由于大模型训练使用高性能的通信,4090通信效率相对较低,因此在大模型训练中并不适用。然而,在推理(inference/serving)方面,4090在性价比上有优势,尤其是相对于H100显卡而言。文章还提到了GPU的训练性能和成本对比,以及大模型训练所需的算力和GPU数量等问题。详细内容可参考文章链接。

《精度提升!南加大等 | 提出分治Prompt策略,提升LLM分辨力》。本文介绍了一种基于分治算法的Prompt策略,旨在提高大语言模型(LLM)的分辨力。现有的提示策略在处理涉及重复子任务和含有欺骗性内容的任务时存在一定限制。为了解决这个问题,研究人员提出了一种基于分治算法的提示策略,利用分治程序来引导LLM的求解过程。该策略将任务划分为子问题并分别求解,然后合并子问题的答案。通过实验证明,这种分治策略能够提升模型在大整数乘法、幻觉检测和新闻验证等任务中的性能,相比传统提示策略具有更好的准确率和性能指标。论文地址:https://arxiv.org/pdf/2402.05359.pdf

《开源版“Devin”AI程序员炸场:自己分析股票、做报表、建模型》。这篇文章介绍了一个基于MetaGPT的开源项目Data Interpreter,该项目旨在处理数据实时变化、任务之间的复杂依赖关系、流程优化需求以及执行结果反馈的逻辑一致性等挑战。通过演示,展示了Data Interpreter在分析股票、预测葡萄酒质量、自动抠图、预测疾病进展和预测机器运行状态等方面的能力。该项目由MetaGPT团队与多所高校合作推出,提供了一种自主进行数据分析和建模的开源工具。

《【原创】一文读懂RAG的来源、发展和前沿》。本文介绍了检索增强生成(RAG)技术,该技术结合了检索和生成过程,旨在提高机器生成文本的相关性、准确性和多样性。文章详细解释了幻觉问题的存在以及解决幻觉问题的几种常见方法。RAG利用外部数据源进行信息检索,将检索到的信息作为上下文输入到生成模型中,从而帮助生成正确的响应。讨论了RAG的核心部件,如向量数据库、查询检索和重新排序。同时介绍了RAG在知识图谱和树结构方面的拓展。

《万字长文解析:大模型需要怎样的硬件算力》。这篇文章探讨了大模型在算力、存储、通信等多个方面上硬件资源的挑战和瓶颈。文章分析了以Transformer结构为核心的大模型在算力瓶颈、显存瓶颈和通信瓶颈方面的困境,以及当前所采取的硬件资源优化技术。此外,文章还提供了对大模型参数量和算力需求的量化估算,为选择合适的硬件设备和评估资源需求提供了指导。

《什么是好的大模型训练数据?》。本文基于Lilian Weng的博客,讨论了大模型如LLM在训练过程中对高质量数据的需求。认为高质量数据来源于“高质量人类”产生的标注数据,并强调了数据处理的重要性,提到了数据标注、质量控制和错误修正的重要步骤。文章还讨论了用于评估数据质量的多种方法,如Influence Functions和Noisy Cross-Validation,并提出了专注于“搭建高质量的数据标注pipeline”的企业方向。最后指出,在AI时代大量产出的数据中维护数据质量,是一个值得关注的挑战。

《读过的最白话讲清楚RAG原理的文章》。这篇文章直观地阐释了检索增强生成(RAG)的概念和工作原理,它是一种结合检索和生成的问答系统。该系统首先通过检索步骤找到与用户问题最相关的知识库内容,然后将这些内容与问题共同输入大型语言模型(例如ChatGPT)以生成答案。文章详细介绍了如何利用嵌入模型对知识库文本进行索引,以便协助语言模型进行精确的检索。此外,它还探讨了语义搜索背后的核心原则和技术细节点,如何通过嵌入找到与用户输入最匹配的知识,以及如何格式化文档以供语言模型使用,以便获得更高效的回答。

《LLM推理算法简述》。本文介绍了用于提高大型语言模型(LLM)推理性能的关键技术与策略。内容涵盖显存优化方法,如KV Cache减少显存浪费、MQA和GQA减少KV-Cache数量、Page Attention进行显存管理,以及提高推理速度的FlashAttention改进。文章还探讨了算子融合技术,比如FasterTransformer和DeepSpeed Inference的应用,以及调度优化策略如Async Serving和Dynamic Batch,最后介绍了用于处理大模型的分布式并行技术。这些优化手段能显著提高LLM推理过程中的性能与效率。

《数学推理增强!微软 | 提出数据合成框架:KPDDS,微调Mistral-7B性能超34B模型!》。微软的研究团队为提升大型语言模型(Large Language Models, LLMs)在数学推理任务的性能,提出了关键点驱动的数据合成(KPDDS)框架。KPDDS利用真实数据源中的关键点和示例对生成高质量问答对来训练语言模型。研究者基于此框架创建了KPMath数据集,进一步结合推理密集型数据形成KPMath-Plus数据集。在MATH测试集上,微调后的Mistral-7B模型达到了39.3%的零样本通过率,超越了数量更多的34B模型,证明了KPDDS的有效性与创新性。这一成果标志着LLMs在数学推理方面的性能得到显著提升。

《首个AI软件工程师上线!已通过公司面试抢程序员饭碗,华人创始团队手握10块IOI金牌》。在这篇文章中介绍了由华人创立的Cognition AI公司开发出来的首个人工智能软件工程师Devin。与现有GPT-4等模型不同,Devin能够独立完成复杂的编程任务,并已成功通过人工智能公司的面试和在自由职业平台Upwork上接单。得益于Cognition AI在长期推理和规划方面的进步,Devin在做决策和执行任务时,能回想相关上下文、随时间学习并修复错误。这标志着人工智能在理解真实世界软件工程问题方面取得了突破,为AI领域迈向更高层级的自动化及监督性工作开辟道路。

《向数字世界AGI迈进!智能体已经从头开玩「荒野大镖客 2」了》。这篇文章展示了如何使用Cradle这一通用计算机控制智能体框架进行AI的研究与应用,在无需内部API支持下控制键盘和鼠标以及与各类软件交互。文章来源于北京智源人工智能研究院、新加坡南洋理工大学和北京大学的联合研究。Cradle由六大模块组成,包括信息收集、自我反思、任务推断、技能管理、行动计划和记忆模块。这些模块让智能体能够自主进行决策和任务执行。研究团队通过将Cradle部署于《荒野大镖客 2》这一复杂的3A游戏中证明其通用性,Cradle能够自主完成游戏主线和探索开放世界。智能体的这种通用能力标志着智能体研究向通用人工智能(AGI)迈进的重要一步。

《深入浅出 LangChain 与智能 Agent:构建下一代 AI 助手》。文章深入讲解了LangChain工具箱及其如何赋能智能Agent,以构建更加智能的AI助手。LangChain利用大型语言模型如GPT-4,提供了一个开源软件框架,可助力开发者搭建基于语言模型的应用。它提供了六大类组件,如模型、提示模板、索引、文档加载器、文本分割器和向量存储,让GPT-4等模型不仅能处理语言,还能与外部API互动、管理用户上下文。文章以构建人脸技术问题排查助手为例,展示如何运用LangChain来协助问题诊断与智能交互,朝向自主、高效的智能应用发展。

《使用零一万物 200K 模型和 Dify 快速搭建模型应用》。本文详细介绍了如何使用零一万物的200K模型和Dify(LLM IDE)快速构建模型应用程序。作者首先对一个机器学习电子书进行翻译,并分享了源代码,然后引导读者如何申请和配置零一万物模型API。随后,作者说明了如何使用Dify IDE快速搭建和调试模型应用程序,以及如何使用Golang和AI模型自动化电子书的翻译过程。最后,作者总结了自动翻译程序的构建过程并展示了批量翻译内容的方法。整篇文章不仅是使用Dify的实操指南,还提供了一种效率化、自动化处理文本内容的示例,适合那些在寻找快速开发和集成大语言模型到应用中的开发者参考。

《一文看完多模态:从视觉表征到多模态大模型》。本文为读者系统梳理了图文多模态与多模态大模型领域的发展,尤其聚焦在视觉表征和视觉与文本融合方法上。文章从卷积神经网络(CNN)及其预训练方法开始讲起,从图像处理的视角介绍了多模态融合的初期方法,如LXMERT、VL-BERT和UNITER等。进一步,文章论述了Vision Transformer(ViT)及其预训练方案如MAE和BEIT,以及基于ViT的多模态对齐与预训练技术,如CLIP和VILT等。作者通过丰富的示例和对比,使读者能够理解这些模型在结构和功能上的不同与联系,为进一步研究提供了宝贵的资源和视角。

《浙大&中科院让Agent学会自我进化,玩德州扑克心机尽显》。Wenqi Zhang等研究者介绍了名为Agent-Pro的AI智能体,它使用大模型(GPT-4)为基础,配合自我优化的策略,能够运用虚张声势、主动放弃等复杂策略玩转德州扑克和21点等非完美信息博弈游戏。Agent-Pro的设计使其能够自我进化,适应复杂和动态的游戏环境,并通过策略层面的反思和世界模型的优化来提高自己的表现。该研究展示了AI在博弈领域的进步,同时为解决多agent现实世界问题提供了新策略。

《面向工业级推荐!“小”LLM也能做好推荐系统》。本文由蚂蚁集团AI创新研发部门NextEvo撰写,介绍了他们的论文《Can Small Language Models be Good Reasoners for Sequential Recommendation?》获得WWW 2024 (Oral)录用。文章针对大语言模型(LLM)在推荐系统应用时代价高昂的问题,提出了一种名为SLIM的基于蒸馏的大模型推荐框架。SLIM通过知识蒸馏技术,将大模型的知识和推理能力迁移到较小的模型上,从而达到用更少参数实现高效推荐的效果。论文强调SLIM在处理长尾物品和新用户推荐的优势,改进了传统基于交互数据的推荐系统偏差问题,并在保持推荐准确度和可解释性的同时降低资源消耗。

《AIOps 智能运维:有没有比专家经验更优雅的错/慢调用分析工具?》。本文介绍了阿里云应用实时监控服务 ARMS 最新推出的错/慢 Trace 分析功能。此功能不依赖专家经验,能对比分析错/慢 Trace 和正常 Trace 的每个维度,从而快速定位问题根源。针对生产环境下调用时延和错误调用的多种因素(如流量不均、单机故障等),ARMS 通过对错/慢 Trace 和正常 Trace 的对比,帮助用户发现异常的共同特征,从而定位到具体问题。这个工具提供了一种优于传统专家经验的快速、有效诊断系统问题的方法,并且附有最佳实践案例。文章最后提供了免登录的 demo 体验链接,引导用户了解和使用该功能。

《CUDA编程优化方法——Memory coalescing》。这篇文章对CUDA编程中的内存合并技术—— Memory coalescing进行了详细介绍。文章首先解释了全局内存的特点以及为何访问速度慢,并阐述了Memory coalescing的目的是通过合并内存访问操作来有效地利用带宽。通过对多维数组的存储方式及访问模式的解析,文章进一步讲解了Memory coalescing的具体实现细节,如何在多维数组访问和矩阵乘法中实现内存访问的合并。最后,文章提供了优化策略,以改进计算的内存访问模式,并提高CUDA内存传输的效率。

《扩散模型如何构建新一代决策智能体?超越自回归,同时生成长序列规划轨迹》。本篇文章介绍了扩散模型在强化学习中的多种应用场景,探讨了如何超越传统的自回归方法,同时生成长序列规划轨迹来模仿人类的决策过程。上海交通大学的团队所作的综述梳理了扩散模型在强化学习中的运用如轨迹规划、策略表征、数据合成,及其解决长序列规划误差累积、策略表达能力受限和数据稀缺等问题的巨大潜力。最终,文章对扩散模型未来的发展方向进行了展望,提出了生成式仿真环境、加入安全约束、检索增强生成及组合多种技能等多个研究方向。

《动手做一个最小RAG——TinyRAG》。本文由不要葱姜蒜指导读者如何一步步实现基于检索增强生成技术(RAG)的简化模型——TinyRAG。TinyRAG仅包含RAG核心功能,即Retrieval(检索)和Generation(生成)两个模块。文章详细介绍了RAG的基本结构,包括向量化模块、文档加载与切分模块、数据库和检索模块,以及如何根据检索内容生成回答。此外,还提供了对应的开源项目代码,助力理解语言模型与RAG的原理,并能够在实践中加以应用和拓展。

《聊一聊Transformer中的FFN》。这篇文章探讨了为什么Transformer的前馈神经网络(FFN)部分长期以来几乎没有大的改动。文章通过比较不同的激活函数,如ReLU、GeLU和Swish等,分析它们在Transformer中的应用效果和局限性。同时探讨了线性投影的必要性、参数量及其对模型容量和记忆力的影响。此外,文章还涉及了混合专家模型(Mixture-of-Experts,MoE)以提升Transformer的效率,并讨论了构建通用人工智能(AGI)所需要的结构特性,特别是放缩定律(Scaling Law)、上下文学习(In-Context Learning)、效率提升(Better Efficiency)和终生学习(Life-long learning)的重要性,最后对未来结构创新给出透彻见解。

⭐️ Go & 云原生 & Rust 相关

《More powerful Go execution traces》。Go的runtime/trace包提供了用于理解和排查Go程序的强大工具,允许对goroutine的执行进行跟踪。新版本Go大幅度降低了执行跟踪的运行时开销,从多数应用中的10-20% CPU下降到1-2%。文章介绍了如何通过将trace分割,从而使得trace可以扩展且保持低开销,还实现了飞行记录功能,使得即使在事件发生后也能从trace中获取信息。Go也提供了一个实验性的trace读取API,使程序性的跟踪分析成为可能。

《Rust: 实现比特币的交易模型》。本文详细介绍了比特币的交易模型中的UTXO(未花费交易输出)模型,并使用 Rust 语言来实现和展示其运作过程。UTXO 模型与传统的账户余额模型不同,将用户的余额分散存储在多个UTXO中。每个UTXO代表比特币网络上一笔可用于未来交易的输出。文章解释了UTXO模型的工作原理、优势以及交易处理流程,包括选择输入、生成输出、签名交易和广播交易。接着,文章提供了一个 Rust 实现的简化示例,展示了如何定义交易结构体、输入、输出以及UTXO集合,并介绍了基本的操作方法。如果你对比特币交易模型和 Rust 编程感兴趣,可以阅读该文章了解更多细节。

《深入理解 Go Modules: 高效管理你的 Golang 项目依赖》。本文详细介绍了 Go Modules 在 Golang 项目中的使用方法和原理。文章首先回顾了 Go 依赖管理的历史,从 GOPATH、Go Vendor 到 Go Module 的演进过程。然后讲解了模块、包和版本的概念,包括模块路径、包路径以及版本的格式和语义。接着,文章介绍了 Go Modules 的环境配置,包括 go env 环境变量和依赖管理文件(go.mod 和 go.sum)的作用和使用方法。最后,文章提供了一些实用技巧和常见问题的解答,帮助读者更好地理解和应用 Go Modules。如果你对 Golang 项目的依赖管理感兴趣,可以阅读该文章了解更多详情。

《Kubernetes集群节点处于Not Ready问题排查》。当Kubernetes集群中的节点显示为"Not Ready"状态时,这篇文章提供了一系列的排查步骤。首先,通过运行特定的kubectl命令来确认节点的状态并获取节点详细信息,检查可能的错误消息或者警告。接着,进入节点系统查看各种系统日志,并使用相关命令如grep、cat或tail来辅助分析。文章还建议检查kubelet服务状态和配置文件,确认系统资源是否充足,试图解决可能存在的磁盘空间和网络问题。最后,通过使用诸如ping、traceroute等诊断工具确保节点能够与主节点通信,并检查重要的网络端口是否开放。确保Kubelet能正确连接到Kubernetes API,并使用Kubernetes的诊断工具如kubectl get componentstatus检查组件状态。通过这些步骤,可以系统地排查并解决"Not Ready"的问题,保持集群健康。

《Go 错误处理: 用 select-case 来解决这个历史难题?》。煎鱼在这篇文章中介绍了一个新的Go语言错误处理提案,这个提案尝试用select-case结构作为错误检查的替代。这个新语法允许在select关键字之后声明一个变量为“陷阱”,赋值给该变量时触发case检查,以减少传统的if err != nil检查的繁琐性。新提案保持了Go1代码的兼容性,尝试提供一个更简洁、向后兼容的错误处理方式,尽管目前社区内对此仍未达成共识。

《K8s蓝绿部署:优雅应对应用程序更新挑战》。本文详细探讨了使用Kubernetes(K8s)进行蓝绿部署的方法,以达到无缝更新应用程序并最小化宕机时间。蓝绿部署是一个运行两个相同生产环境的模式,能够在更新时切换流量,确认无误后便去除旧环境。文章指导了从创建命名空间、创建和应用部署、服务及其路由规则、执行蓝绿切换,到最后的验证和回滚过程。这一过程不仅优化了应用版本的滚动更新,也为开发者提供了快速回滚的方案,以应对可能出现的问题。

《Go 中的高速数据包处理:从 net.Dial 到 AF_XDP》。文章介绍了使用 Go 语言进行高速数据包处理的多种方法,包括 net.Dial、原始套接字、系统调用、pcap 和 AF_PACKET,直至最新的 AF_XDP 方式。作者详细对比了每种方法的性能,从简单的 net.Dial 模式演进到 AF_XDP,逐步提高数据包每秒处理数量,同时指出各方法的使用场合和限制。通过基准测试,发现使用 AF_XDP 可实现最高性能,处理速度是使用 net.Dial 方法的4倍多。这些技术探讨对于需要大量网络数据包处理的场景,如网络监控、性能评估等都是非常重要的。

《数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)》。文章探讨了在云原生时代下,有状态服务(如生产环境的数据库)是否适用于容器化并由Kubernetes进行管理的问题。以B站Elasticsearch和Clickhouse的容器化和Kubernetes编排实践为例,文章详细介绍了在容器环境中部署这些有状态服务的挑战和解决方案,包括控制器的选择、持久化存储、磁盘调度、调度器、容器网络、服务发现以及如何保证集群和数据的高可用性。作者分享了通过Operator管理有状态服务应用、使用本地盘PV提升性能、LVM技术的动态扩缩容方案以及通过macvlan进行容器间高效通信的技术细节。

《一文带您探索 Kubernetes 中的容器类型》。文章介绍了在 Kubernetes 系统中常见的四种容器类型:初始化容器(Init Container)、边车容器(Sidecar Container)、临时容器(Ephemeral Container)和多容器(Multi Container)。初始化容器用于运行 Pod 中主容器启动前的准备工作,而边车容器则与主应用容器并行运行,为其提供支持服务。临时容器主要用于故障排除,而多容器 Pods 允许并行运行多个容器,共享资源和数据。文章提供了每种容器的详细使用案例、配置方法和命令,并强调了各自的特点与应用场景。

《4 秒处理 10 亿行数据! Go 语言的 9 大代码方案,一个比一个快》。软件工程师Ben Hoyt挑战使用Go语言处理10亿行数据,并提出了9种解决方案,其中最快在4秒内完成。这些方案只使用Go标准库,包括简单但优化的map处理、并行化处理等。Ben的方案虽未最快,但展现了独立思考的价值。他的测试表明,彻底地数据处理和算法优化可显著提高性能,减少计算成本。

《Go arena 民间库来了,可以手动管理内存!》。文中作者煎鱼介绍了Go语言的一个新的第三方库ortuman/nuke,这个库允许开发者手动管理内存。文章首先回顾了Go官方对于arena手动内存管理提案的停滞现状,然后重点介绍了如何使用ortuman/nuke库进行内存管理,包括库的安装、使用案例以及如何在并发场景下保持线程安全。文章详细讲解了arena内存管理的优点,例如高效率和一次性释放,并对库的实际用法,如通过context在HTTP请求周期中管理内存,进行了展示。最后,基于性能考虑,文章还提供了并发与非并发业务场景下的基准测试结果以及性能差异。

Go 语言中如何大小端字节序?int 转 byte 是如何进行的

Go 中如何实现三元运算符?Rust 和 Python 是怎么做的

Go语言中 enum 实现方式有哪些?一定要绝对类型安全吗

Go 中如何打印结构体? 代码调试效率提升

《快看! Go 1.22 对for循环进行了两个大更新》。文章讨论了Go语言在 1.22 版本中针对for循环作出的两项主要更新:1. 每次迭代的for循环都将定义一个新的变量,不再共用同一个变量;2. 引入了对整数范围的循环迭代支持。这些更新解决了闭包在并发执行时共享变量带来的问题,同时也简化了循环结构,提高了编写对整数范围进行迭代代码的方便性。文中提供了详细的代码示例来展示新旧版本之间的差异,并说明了如何利用新特性来编写更高效的Go代码。

《从慢速到SIMD》聊Go边界检查消除》。本文讨论了Go语言中边界检查消除(BCE)的相关技巧和最佳实践。文章首先回答了为何在Go代码中优化时选择使用a[i:i+4:i+4]而不是a[i:i+4]的问题,指出前者能减少编译器工作量从而提高性能。然后,介绍了Go101提出的BCE技术详解与应用实例,以及如何使用编译命令来检测边界检查的存在。文中还全面梳理了Go BCE技术的发展历程,以及在不同场景下消除冗余边界检查的方法,包括利用循环变量、常量索引等策略来提高代码执行效率。最后,提供了多种编程技巧以及相关讨论和参考资料,针对遇到的编程问题提出解决方案。

📒 后端相关

《分库分表已成为过去式,使用分布式数据库才是未来》。本文讨论了随着Mysql数据库性能下降,分库分表的局限性及其所引发的问题,如性能、事务、数据迁移等,并提出使用分布式数据库作为解决方案。文章详细介绍了TiDB这款分布式数据库的架构、特性和优势,包括其金融级的高可用性、水平扩容能力、兼容性以及云原生设计。文章强调TiDB在处理大规模数据时的效率和可维护性,终结分库分表的做法,并通过性能测试展示了TiDB与MySQL在不同场景下的性能表现。最终总结,对于数据量大的应用场景,采用TiDB来适应未来数据存储的需求是一个更优的策略。

《手把手带你精简代码-京东零售后端实践》。本文分享了京东零售后端在面临代码库日渐庞大和腐化的问题时,采用的代码精简方法。文章分为背景介绍、代码精简步骤和实施方法三部分,着重介绍了使用IntelliJ IDEA自带工具和PMD插件进行静态代码检查的步骤、配置和优缺点,以及如何借助京东jacoco流水线进行动态代码检查。本文旨在降低代码维护成本、提升可理解性,并详细阐述了代码精简的实践过程和预期结果。

《跟着iLogtail学习无锁化编程》。文章探讨了在多线程情况下,如何通过无锁化编程优化软件性能。详细讲述了iLogtail在实现无锁高效日志采集时采取的策略,比如自旋锁的使用、原子操作、内存顺序、内存屏障等概念。还分析了不同类型的锁的适用场景与特点,包括互斥锁、递归互斥锁和读写锁等。此外,文章还描述了如何将大的锁细分为多个小锁,通过降低锁粒度提升并发性能,以及在iLogtail中如何通过双Buffer机制来读写分离,减少锁的争用。最终,通过无锁化编程提高了iLogtail的日志采集性能,实现了低资源消耗和高性能。

《MYSQL 是如何保证binlog 和redo log同时提交的?》。文章讨论了如何确保在MYSQL中binlog(备份和主从同步用的日志)与redo log(InnoDB引擎层的日志,用于崩溃恢复)同步提交,以及为什么这一点对于防止主从数据不一致至关重要。文中解释了事务处理中的两个关键参数:innodb_flush_log_at_trx_commitsync_binlog,这两个值设置为1时可以确保两种日志的同步提交。该文还介绍了MYSQL的两阶段提交机制如何工作,并提出了业务开发中两阶段提交逻辑的思考,指出在有依赖关系的服务操作中,通过预锁定资源、请求成功后递减资源来保持数据的最终一致性。

《这些年背过的面试题——分布式篇》。本文从分布式系统的基础概念、发展历程及核心问题出发,详细介绍了分布式系统设计中的关键技术点。文章涵盖了负载均衡、服务的拆分与集群、分布式事务、数据一致性问题以及分区容错性等话题,并探讨了CAP理论与BASE理论在实际应用中的权衡。同时,文中还详细解读了常见的一致性算法如2PC、3PC、Paxos、Raft的机制和用例。此外,作者针对如何实现分布式Session、如何确保分布式事务的一致性等常见面试题目提供了详尽的解答,适合做为面试备考资料。

《RocketMQ为什么这么快?我从源码中扒出了10大原因!》。这篇文章详细分析了RocketMQ高性能的10个关键因素:批量发送消息降低通信次数,消息压缩减少带宽和存储压力,基于Netty的高效网络通信模型,零拷贝技术优化磁盘读写性能,顺序写提高数据写入速度,高效数据存储结构,异步机制包括异步刷盘和异步主从复制提升存储效率,批量处理减少网络通信次数和资源消耗,锁优化以及线程池隔离提升并发处理能力。作者通过深入分析源码给出了RocketMQ快速处理和拉取消息的内在原因,并深入讨论了每种技术的优势和实现。

《领导叫我接手一个新业务系统,我是这样熟悉项目的!》。本文作者小许分享了接手新业务系统的熟悉流程和实践方法。包括与产品经理交流了解业务现状,绘制用例图、ER图以明确业务与数据模型,梳理后端模型和核心流程,并运用状态机流转图和时序图深度解析复杂逻辑。最后,还提到了绘制类图以理解代码结构。文章提供了一套系统性的工具和方法,目的是帮助新成员或负责新项目的开发人员快速掌握业务逻辑,有效推进项目进度。

📒 前端相关

《Tango 低代码引擎沙箱实现解析》。本文介绍了Tango低代码引擎的沙箱实现。Tango是一个用于快速构建低代码平台的低代码设计器框架,通过对源代码进行执行和渲染前端视图,实现了低代码可视化搭建能力。借助Tango构建的低代码工具或平台可以实现源码进出的效果,并与企业内部现有的研发体系进行无缝集成。Tango的设计器引擎部分已经开源,并提供了相应的开源代码库、文档和社区讨论组。欢迎加入社区参与到Tango低代码引擎的开源建设中。更多相关文章可以在文中提供的链接中找到。

《未来只需要 2% 的程序员?》。DHH在这篇文章中提出一个激进的观点,预测未来程序员的需求可能会大幅度减少。他比较了农业从97%的人口需求降至2%的变迁,暗示软件开发也可能面临着类似缩减。尽管这个行业曾经经历招聘热潮,但现在许多程序员面临职业前景不稳定。文章讨论了人工智能的发展给程序员职业带来的压力,同时也指出职业变革的不确定性。DHH认为,未来大多数程序员可能无需手动编程,但同时指出科技行业将更加融合进社会,并提高了它的价值。他鼓励程序员接受这一变化,并享受行业的黄金时代。

《前端智能化,扣子(coze.cn)能做什么?》。这篇文章探讨了扣子(coze.cn)平台如何通过提供一个简单的交互式界面来创建聊天机器人(Chatbot)。用户通过与扣子的对话,可以快速设置一个Chatbot,如自动化微信订阅号内容发布等。文章强调了平台的易用性和界面友好性,同时指出了一些潜在缺点,包括无法解决深度问题和偶尔遇到的技术故障。另外,通过知识库和数据库的集成,可进一步提升Bot的功能。作者对扣子的机器人创建过程、优势、建议和改进进行了详细介绍,并通过实操案例展示了前端智能化机器人的搭建过程。

]]>
+ + 加菲猫 + https://github.com/Jiacheng787 + +
<![CDATA[3月10日内容汇总]]> https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/frontend-weekly/2024/3月10日内容汇总 diff --git a/2024/index.html b/2024/index.html index cb0106eed2..c82c6853a6 100644 --- a/2024/index.html +++ b/2024/index.html @@ -11,13 +11,13 @@ - - + +
-

· 35 min read
加菲猫

alt text

封面图:Understanding the Go runtime - Jesus Espino

🌟 AI 相关

《In-context Learning with Retrieved Demonstrations for Language Models: A Survey》。这篇题为 "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" 的文章,主要讨论了语言模型,尤其是大型预训练语言模型如何通过获取的演示进行少量情景学习。这项技术能有效地改进学习过程的效率和可扩展性,并降低手动选择样例时的固有偏见。文章对此领域进行了广泛的研究回顾,对检索模型、检索训练过程和推理算法的不同设计选择进行了讨论和比较。

《碾压LoRA!Meta & CMU | 提出高效大模型微调方法:GaLore,内存可减少63.3%》。Meta和CMU合作提出了一种新的大模型微调方法——Gradient Low-Rank Projection(GaLore)。GaLore通过梯度的低秩投影代替权重的低秩适配,不仅支持全参数学习,而且显著降低了内存占用,减少了63.3%的内存需求。不同于LoRA的低秩权重更新,GaLore利用权重梯度的低秩特性,结合逐层权重更新和8位优化器,有效地优化了内存效率。此外,GaLore还引入了可调整的超参数,提高了其适应性。经实验验证,GaLore的表现优于LoRA,尤其是在预训练模型微调上表现更佳,为大模型训练提供了新的解决策略。

使用 GPT4V+AI Agent 做自动 UI 测试的探索 | 京东云技术团队

Gemini修bug神了!录网页视频把代码库甩给它就行,网友坐不住了:想要访问权限

一键开启 GPU 闲置模式,基于函数计算低成本部署 Google Gemma 模型服务

《Yi技术报告细节分享》。该文章分享了Yi模型的具体实现细节和思路,强调了模型设计围绕模型规模、数据规模和数据质量。Yi模型的预训练阶段数据处理流程包括启发式过滤、学习式过滤、聚类过滤以及去重等步骤,以提高数据质量。微调阶段,Yi模型仅采用了10K数据进行模型微调,强调数据质量胜过数量。在分词器、模型结构及微调参数方面,Yi模型采用了一系列优化措施,包括Transformer-Decoder结构、Grouped-Query Attention等。总的来说,Yi模型通过优化数据处理流程、微调策略、调整模型结构和参数等多方面实现了高效的技术实现。

重新定义大模型推理!Google | 提出SELF-DISCOVER框架,大模型可自写推理结构!

《斯坦福 && 微软 | 发布前端代码生成大模型:Design2Code-18B,助力前端自动化!》。这篇文章主要介绍了一种新的前端代码生成大模型:Design2Code-18B,它可以将网页视觉设计转换成功能性代码。文章首先介绍了将网页视觉设计转换成功能性代码的挑战性和现有方法的局限性,然后提出了Design2Code基准和多模态提示方法,以激发多模态大型语言模型(如GPT-4V和Gemini)的潜力。接着,文章介绍了开源的18B微调模型Design2Code-18B,它基于CogAgent-18B,在多种数据集上进行了预训练,并使用了Huggingface发布的WebSight数据集进行微调。最后,文章展示了Design2Code-18B在Design2Code基准上的优越性能,并提供了一些未来研究方向。

可控文本生成新方法,人大&&南开 | 提出DATG架构,准确性提升19.29%,效率提升1倍

《Auto-Prompt | 大模型提示(Prompt)优化新方法IPC:可根据用户意图进行定向优化》。这篇文章提出了一种名为 Intent-based Prompt Calibration(IPC)的系统,主要目的是通过使用合成案例样本来优化大型语言模型的提示工程。它基于模型生成的数据集进行提示优化,以解决大语言模型对给定提示的敏感性等问题。这种方法的核心思想是根据用户意图迭代细化提示。同时,文章还对 IPC 系统的整体架构和实现流程进行了详细介绍,并展示了一些实验结果。

《更智能的 Agent,Plan-and-Execute Agents 计划和执行》。这篇文章介绍了几种新型的智能 Agent 设计方法,包括 Plan-and-Execute Agents、ReWOO Agent 和 LLMCompiler。Plan-and-Execute Agent 设计法通过明确规划来优化智能 Agent 功能。ReWOO Agent 设计法凭借变量分配功能使得不必对每个任务都使用 LLM。LLMCompiler 则通过任务格式化为 DAG 来提高工具调用的效率。这些新型设计都在不同程度上优化了智能 Agent 的工作流程,提高了工作效率。

《OpenAI Function Calling 与 LangChain Agent 工作原理及区别》。这篇文章介绍了OpenAI Function Calling 与 LangChain Agent的工作原理及它们之间的区别。文章首先列举了大型语言模型的限制,并解释了为何需要Agent。然后,文章介绍了React Agent的工作方式,通过“Reason Only”(向内求索)、“Act Only”(向外探索)和“ReAct”(内外兼修)三种模式优化模型的功能。此外,文章还以一个简单的实例,解释了如何利用ReAct Agent来解答一个包含搜索和计算两个步骤的问题,展示了其实际应用的流程。

《ReAct Agent 回答 RAG 系统中的复杂问题》。这篇文章主要讲述了“ReAct Agent 用于回答 RAG 系统中复杂问题的方式”。随着输入问题的复杂度升高,使用传统的聊天机器人已不能足够有效。于是,作者提出了利用 ReAct Agent,通过自然语言模型(LLMs)逐步规划并执行处理问题的步骤,并定义功能性工具(如时间计算、文本搜索、列表长度计算、百分比变化计算等)以辅助任务完成。这种方法能够更好地干预和控制问题的解决过程,从而提高任务的完成质量。

更智能的 Agent,Plan-and-Execute Agents 计划和执行

ChatGPT也能画图?教你一键生成时序图、类图、流程图、状态图以及用例图

三个被忽视的大模型提示

关于Sora和Stable Diffusion 3,你需要知道的一切

消费级显卡可用!李开复零一万物发布并开源90亿参数Yi模型,代码数学能力史上最强

详解大模型微调全流程

南大俞扬教授:什么是world models/世界模型

深入浅出LangChain与智能Agent:构建下一代AI助手

尤洋教授:开源完整的Sora复现方案来了!

《T-RAG=RAG+微调+实体识别》。这篇文章名为"T-RAG=RAG+微调+实体识别",主要介绍了T-RAG技术,这是一种将RAG架构与微调语言模型和实体树向量数据库相结合的方法,用于支持语境检索。它概述了在敏感文档的背景下如何保护数据隐私,以及如何在有限的计算资源和基于现有文档建立的小型训练数据集中保证用户提问的准确回答。文中还着重介绍了T-RAG的工作流程和实体树的作用。最后,还提出了一个新的评估指标“Correct-Verbose”,用以评价生成回复的质量。此研究不仅是理论研究,也是实践中LLM应用的经验总结,具有实际的指导意义。

《高级 RAG(Self-Reflective RAG)》。这篇文章名为"高级 RAG(Self-Reflective RAG)",主要介绍了Self-Reflective RAG的理念和工作流程。在基本的RAG pipeline中,我们的过程往往受限于被动的检索和生成,而实际操作中,我们需要根据生成的结果进行优化,如改变问题或筛选和排列内容。为了解决这个问题,文章介绍了一种新的自我修正框架,包括Corrective RAG(CRAG)和Self-Reflective RAG。这两种RAG都围绕着对检索和生成内容的评估和反馈进行自我修正,并通过特定标识进行调控。在一定条件下,进一步改进了RAG,使其产生更好的检索和生成效果。

RAG不够聪明?打造更强大的智能体

Anthropic发布Claude3,效果已超越GPT4

从0开始预训练1.4b中文大模型实践

《分类算法入门:以鸢尾花数据集为例》。这篇文章以鸢尾花数据集为例,全面而详细地阐述了机器学习中的分类算法基础知识。首先介绍了人工智能、机器学习和深度学习的基本概念,讲解了机器学习各种分类方法的理论背景。随后通过鸢尾花数据集,展示了如何使用 Python 工具(包括 pandas、sklearn、matplotlib 和 seaborn)进行数据处理、分析和可视化。文章详细讲述了决策树、逻辑回归、支持向量机、K近邻等经典的分类算法,并用图形化的方式展示了分类效果。最后,读者可以通过本文所提供的丰富学习资料来深化对机器学习分类任务的理解和应用。

《万字详解LLM Agents的现状,问题与未来》。这篇文章名为"写在跨年之前:聊聊LLM Agents的现状,问题与未来",主要涉及到LLM Agents的当前状态,面临的问题和未来的可能发展。文章探讨了包括全参微调、Prompt Tuning、LoRA、P-Tuning等在内的SFT(Selective Fine Tuning)范畴的各种技术。其中尤其强调了对于{prompt,response}的单轮问答对的微调是最简单的SFT实现方式。具体的内容细节大概需要阅读原文才能获得更深入的理解。

⭐️ Go & 云原生 & Rust 相关

《Robust generic functions on slices》。这篇文章名为"Robust generic functions on slices",主要探讨了Go的slices包如何提供对切片进行操作的通用函数。该文章首先介绍了如何通过类型参数,一次性为所有类型的切片编写类似slices.Index等函数,而无需针对每种不同的元素类型重新实现。随后,文章深入讲述了新的函数(如Insert, Replace,Delete等)如何修改切片,并通过详述切片在内存中的表现形式及其对垃圾回收器的影响,来帮助读者理解这些函数的工作方式和正确使用它们。文章特别指出,新的Delete函数提供了更清晰地表达程序员意图的方式,而且它不需要分配新的数组,这样就可以在适当时清除无用的元素,帮助垃圾回收。文章强调,调用这些函数后,必须认为原始切片已无效,因为底层数组已被修改。最后,文章还讨论了在处理内存泄漏和元素零值设置等问题时的策略和选项,它们在新版本Go给出的解决方案,以及这些改变可能导致的一些测试问题。此外,作者鼓励开发人员正确使用新功能,并尽量避免上述列举的陷阱。

《Routing Enhancements for Go 1.22》。这篇文章名为"Routing Enhancements for Go 1.22",主要介绍了 Go 1.22 版本中 net/http 包的路由器提供的新特性:方法匹配和通配符。这些新特性让你可以使用模式,而非 Go 代码,来表达常见的路由。这种新功能,尽管简单易懂,但要选择出多个匹配请求的最佳模式却是一项挑战。文章还详细阐释了如何在新版 Go 中使用这些新特性,以及这些引入的变化如何影响了 ServeMux 方法 handle 和 handleFunc 。此外,还描述了新模式如何更具优先级,并解释了其背后的原理。同时,为了保持新旧版本的兼容性,作者们也努力使新的模式语法能覆盖旧的,并使新的优先级规则能泛化旧的规则。总体上,这些改变是 Go 语言团队不断努力使 Go 成为构建生产系统的优秀语言的一个持续过程的一部分。

听GPT 讲Rust源代码--compiler(6)

使用Apache Kafka的Golang实践指南

《Go 为什么不支持从 main 包中导入函数》。这篇由煎鱼撰写的文章,题为 "Go 为什么不支持从 main 包中导入函数?",对于这个话题进行了深度解析。其首先提到,虽然Go的规范并没有明确禁止从main包中导入函数,但我们在实际运行中会被拒绝,提示main包是一个程序而非可以导入的包。这一现象的原因来自于经过多次变动的规定,如2011年移除了 "程序中的其他包都不能命名为 main" 的要求,然后在2015年又新增了限制。这样的变化主要是为了避免增加复杂度和不安全性。比如,一个函数可能会做出自己拥有完全控制权的假设,所以如果引入多个main包中的函数,可能会产生在初始化顺序、全局变量的注册等方面的冲突。这篇文章认为Go官方的做法在理论上可以解决复杂度和安全性问题,但对于有历史债务的项目,对于需要维护多个Go项目工程,相当于磨灭了一条道路,其实比较尴尬。

《fasthttp是如何做到比net/http快十倍的》。这篇文章讲解了fasthttp如何做到比net/http快十倍的原理。fasthttp相比于net/http在处理流程上有所差异,net/http是一个连接新建一个goroutine,当连接数非常多的时候会给系统带来一定的压力。而fasthttp则是建立了workerPool,每个workerChan在后台都会有一个Goroutine来处理其中的连接。此外,fasthttp的快速也得益于几个方面的优化:连接复用,大量使用了sync.Pool进行内存复用以及通过unsafe.Pointer指针进行[]byte和string转换来避免内存分配和拷贝的消耗。

《万字长文讲解Golang pprof 的使用》。这篇文章主要讲述了Golang的pprof工具的使用。pprof工具是Golang中用于性能分析的一个工具,它可以分析出cpu使用情况、内存占用、阻塞情况、线程和协程等信息。文章中详细阐述了如何使用此工具,主要有两种方式,一种是通过http接口的方式暴露出pprof的采集控制界面,另一种是在程序中通过代码来启动相应指标的采集示例。文章还详细介绍了如何解析通过这两种方式获取的输出信息。本文的主要目的是将pprof工具的使用方式用思维导图的形式展示出来,这样可以帮助读者更好地理解和使用pprof工具。

《一篇实用的关于云上K8s应用分账实践》。本文讲述云上Kubernetes(K8s)应用的成本分摊实践,涵盖了成本分摊的核心概念及阿里云ACK FinOps套件的应用。文中首先以前期预算为集群规划的依据,并讨论了随着业务发展对成本分摊精准度的提升需求。介绍了如何根据Pod的核/时成本,通过ACK集群、计算节点、命名空间和应用Pod这四个维度进行费用分摊。文章还分析了单资源和混合资源分摊模型,并讨论了如何设置Request和Limit来优化资源利用。对于多云和混合云场景,分享了如何通过ACK One实现统一管理和成本分析。针对复杂业务场景,讲述了自定义定价模版的使用方式,允许通过配置实现成本定制需求。对于追求细节管理和精细化运营的团队,这篇文章提供了宝贵的指导。

《如何使用 K8s 两大利器"审计"和"事件"帮你摆脱运维困境》。这篇文章主要讲述了如何使用 Kubernetes(K8s)的"审计"和"事件"功能来帮助进行日常集群运维工作。文章首先指出了运维工作中可能出现的一些问题,例如应用被删除、Apiserver负载突变、集群节点出现问题、节点自动扩容等。随后,文章进一步解释了 Kubernetes的审计和事件是如何运作的,强调了善用这两种工具可以提高集群的可观察性,为运维工作带来极大的便利。总的来说,这篇文章为运维人员提供了一种解决方案,通过使用 Kubernetes的审计和事件,可以更好地管理和监测集群的状态。

【Go 工具】竞态条件检测神器 Race Detector

使用Redis入门Golang

一道面试题: Top K 问题

《理解 Docker 容器中 UID 和 GID 的工作原理》。这篇文章详细解析了 Docker 容器中 UID 和 GID 的工作原理。首先,作者概述了用户名、组名、用户ID(UID)和组ID(GID)在容器内运行的进程与主机系统之间的映射对于构建安全系统的重要性。随后,文章分析了uid/gid在Linux系统的安全性,强调了单一内核概念以及uid/gid的分配方式。接着,作者运用实例解释了Docker运行的过程以及如何通过Dockerfile定义和启动不同用户。最后,文章讲述了如何掌控和控制容器的访问权限。在阐述以上内容的同时,文章也提供了一些实际示例来说明这些观点。

《如何基于Docker镜像逆向生成Dockerfile》。这篇文章介绍了如何将Docker镜像逆向生成Dockerfile。文章主要讲述了利用开源工具Dedockify的操作方法与工作原理。该工具通过Python脚本,利用存储在每个镜像层旁边的元数据,逐步遍历层级树,收集与每个层相关联的命令,重建镜像构建过程中执行的命令序列,从而得到近似的Dockerfile。不过,因为无法访问执行原始docker build命令时存在的构建上下文,如果使用了COPY或ADD指令,生成的输出可能不完全匹配原始的Dockerfile。

《通过多阶段构建减小Golang镜像的大小》。本篇文章主要介绍了如何通过多阶段构建减小Golang镜像的大小。首先,作者提出了一个通用的Dockerfile,并指出其生成的镜像大小超过300MB,主要因为包含了所有的Golang工具。然后,作者提出了多阶段构建的方法,它能从不同的基础镜像构建,有选择地将文件从一个阶段传递到下一个阶段,从而减小镜像大小。在本例中,通过二级构建,镜像大小已降至11.7MB。最后,还探讨了使用名为scratch的空白镜像进一步减小镜像大小的可能性,使得镜像最后降至6.34MB,但作者强调这需要慎重考虑,因为最后生成的镜像将完全没有任何工具。

《k8s 到底是什么,架构是怎么样的》。这篇文章主要讲述了 Kubernetes(K8s)的基本概念、架构和工作原理。Kubernetes,因单词过长,我们通常简化为k8s。k8s 是一种容器的协调工具,位于应用服务和服务器之间,能以策略的方式协调和管理多个应用服务。通过一个 yaml 文件的配置,可以定义应用的部署顺序等信息,自动部署应用到各个服务器上,还能让它们崩溃后自动重启,可以自动扩容和缩容。Kubernetes 的服务器分为两部分:控制平面和工作节点,前者负责控制和管理各个节点,后者则负责实际运行各个应用服务。k8s 的命令行工具为 kubectl,用于执行各类操作命令。

《Go 泛型有没有可能在后期改为 <> 尖括号》。这篇文章主要讨论了Go语言在处理泛型时,为何并没有采用类似Java和C++的 <> 尖括号表示法,而是选择了中括号 []. 首先,使用尖括号可能导致语义混淆,如 a, b := w < x, y > (z) 此句,如果使用尖括号,程序可能在编译阶段无法确定该行表达式的具体含义。其次,使用圆括号也会导致同样的问题,比如 func F(T any)(v T)(r1, r2 T), 无法快速准确判断出参数和返回值部分。此外,Go官方也不希望使用非ASCII的字符。作者还提到社区中对Go的处理方式存在一些争议,部分社区成员认为如果使得编译器解释尖括号不再困难,就可以采用这种符号。然而,总的来说,基于已有的实践和规范,Go语言在未来可能也不会改变其泛型的表示方式。

《Rust中channel的使用》。这篇文章主要介绍了Rust编程语言中Channel的用法。其中,Channel是Rust中用于在不同线程间传递信息的通信机制,实现了线程间的消息传递。每个Channel由发送端和接收端两部分组成,其设计理念是“通过通信来共享内存,而非通过共享内存来通信”,以此避免了数据竞争和共享内存的复杂性。该文章进一步详细介绍了如何在Rust中创建和使用Channel,并给出了相关代码示例。最后,文章阐述了多种Channel模型,包括Rust标准库中所使用的MPSC(多生产者,单消费者)模型。

K8s部署方式大全:从基础到进阶,一文带你掌握所有技巧

k8s从入门到精通 -- 更适合中国宝宝体质

📒 后端相关

《万字+33张图探秘OpenFeign核心架构原理》。本篇文章深入探讨了SpringCloud核心组件OpenFeign的核心架构原理。文章分为四个部分,首先解释原始Feign的使用和基于SpringCloud的进化过历程;然后详细讲解了Feign底层工作原理,依赖于JDK动态代理和核心组件如Contract、Encoder、Decoder等;接下来分析了SpringCloud是如何整合Feign的,并且讨论了OpenFeign的多种配置方式及其优先级;最后,文章通过丰富的图示和代码示例,使读者可以更好地理解并运用这一工具。这篇文章对于理解和运用OpenFeign非常有帮助,无论是对于初学者还是有经验的开发者。

《三万字长文:如何去排查JVM内存问题》。这篇文章是一份详尽的指导,讲述了如何排查JVM内存问题。文中首先定位了技术问题的范围,确定适用于JDK8至JDK11。接着,作者提出了系统化的排查原则,并提供了一步步的诊断流程,从基本信息收集、判断内存增长原因,到具体分析内存问题的可能来源。文章详细介绍了如何利用不同的命令和工具(如jmap、jstat、Arthas等)进行详细的分析,并根据内存使用情况,向读者展示了如何确定是堆内存问题还是堆外内存问题。总之,文章为那些需要深入理解和处理JVM内存问题的开发者和运维人员提供了宝贵的知识和技巧。

《如何避免MYSQL主从延迟带来的读写问题》。这篇文章讨论了如何处理在MySQL主从部署架构中普遍存在的主从同步延迟问题,以保持读写操作的一致性。文章首先介绍了主从延迟产生的场景及其对读写分离原则的影响。然后,详细解释了主从复制的原理,并提出了两种避免主从数据不一致的技术方案:一是使用select master_pos_wait函数来等待从库同步至特定的binlog位置点;二是在开启GTID模式的情况下,通过select wait_for_executed_gtid_set函数检查GTID集合是否已同步。这两种方法均旨在确保从库数据的准确性,从而整体上减轻主库的压力。总体上,文章为MySQL数据库管理员提供了缓解主从延迟导致的读写问题的具体实施方案。

《这些年背过的面试题——ES篇》。这篇文章是一篇针对Elasticsearch(ES)的面试指南,它涵盖ES基础知识点和面试过程中常见问题。内容包括ES的功能特性介绍(如分布式架构、全文搜索、数据分析等)、主要的使用场景描述、与其他搜索引擎的对比(Lucene和Solr)、以及ES的基本概念解释。文章还详细探讨了ES的高级特性,如映射、DSL查询、聚合分析和智能搜索建议器。此外,作者还分享了关于数据索引优化的实战技巧和策略,提供了写优化、读优化和索引重建的方案,这些方案对ES数据存储和查询的性能有显著影响,最后还对Deep Paging性能问题提供了解决方法。对正在准备面试或者希望巩固ES知识的读者而言,这篇文章是一个宝贵的资源。

《什么是MySQL锁?有哪些锁类型》。这篇文章详细地介绍了MySQL中的锁定机制及其类型。起初概述了锁的作用,即协调多进程或线程对资源的并发访问,在数据库环境下,锁对于保持事务的正确性与一致性至关重要。作者明确区分了MySQL中锁的级别,从全局锁、表锁(读锁、写锁)到元数据锁、意向锁,直到行锁的多种形式(记录锁、间隙锁和临键锁)。文中还探讨了AUTO-INC锁的作用和相关优化,举例说明了其在INSERT操作中的应用。此外,文章也涉及了如何根据不同的情况优化锁的使用以及如何避免由锁产生的性能瓶颈。这篇文章为理解MySQL的各种锁类型和锁机制提供了宝贵的信息,特别对于数据库管理员和那些需要管理并发数据访问问题的开发人员来说,具有很高的实用价值。

📒 前端相关

Vue 团队正式开源 Rolldown:基于 Rust 的超快 JavaScrip 打包工具!

打造舒适的vscode开发环境

相比于 Node.js,Deno 和 Bun 到底能带来什么

MDH Weekly 122 - 《招人》

· 4 min read
加菲猫

alt text

封面图:用 switch-case 来解决 Go 错误处理的难题

🌟 AI 相关

LangChain 实战:Agent思维

详解大模型RLHF过程(配代码解读)

PromptFlow高质量AI应用 - 基于LLM的文档QA机器人

图解大模型计算加速系列:Flash Attention V1,从硬件到计算逻辑

使用搭载骁龙 8 Gen 3 的安卓手机运行 AI 大模型

生成式 AI 的发展方向,是 Chat 还是 Agent

聊聊大模型Agent技术,及和具身智能又有什么异同

复旦NLP团队发布80页大模型Agent综述,一文纵览AI智能体的现状与未来

知识问答系统的优化实践:LLM与RAG的结合艺术

一文解构大模型RAG问答关键环节及与LLM微调对比总结

Mistral AI发布Mistral Large模型

Mistral AI新模型对标GPT-4,不开源且与微软合作,网友:忘了初心

大模型微调新范式:当LoRA遇见MoE

Mistral Large,Le Chat来了!Mistral AI连放两个大招!

探索2024年1月的AI研究前沿:模型合并、专家混合与小型LLM的崛起

⭐️ Go & 云原生 & Rust 相关

Cargo的自定义命令扩展功能

听GPT 讲Rust源代码--compiler(2)

元老与新秀:Go sort.Search()和sort.Find()

KisFlow-基于Golang的流式计算框架实战(6)-Connector

跳槽必看のMySQL索引:B+树原理揭秘与索引优缺点分析

听GPT 讲Rust源代码--compiler(1)

KisFlow-基于Golang的流式计算框架实战(5)

用 switch-case 来解决 Go 错误处理的难题

KisFlow-基于Golang的流式计算框架实战(4)

KisFlow-基于Golang的流式计算框架实战(3)

图文讲透Golang标准库 net/http实现原理 -- 客户端

使用docker init编写Dockerfile和docker-compose配置

Go语言中常见100问题-#完结撒花

KisFlow-基于Golang的流式计算框架实战(2)

golang 高性能无 GC 的缓存库 bigcache 是怎么实现的

📒 后端相关

从0到1构建一个稳定、高性能Redis集群

这些年背过的面试题——SpringCloud篇

如何设计订单超时自动取消

📒 前端相关

2024 AI & 前端:回首展望,光芒未至,破晓之前!

看完zustand源码后,我的TypeScript水平突飞猛进

ElTable 二次封装:我用 Vue3.3 新特性完美解决了列插槽数据无类型提示问题!!!

ECharts 迎来重大更新,运行时包体积可减少 98%!

FFmpeg前端视频合成实践

2024 使用 TS 搭建 Node.js 服务器 - 快速教程

前端食堂技术周刊第 113 期:Node 年终总结、Node 新吉祥物、Qwik 2.0、React Labs 工作进展

· 6 min read
加菲猫

🌟 AI 相关

Large Language Models for Data Annotation: A Survey

ACTIVERAG: Revealing the Treasures of Knowledge via Active Learning

关于Generative-Diffusion-Model的全面综述,可以作为了解sora的基础知识

云音乐 CMS 平台 AIGC 实践与新特性实现总结

云音乐D2C设计稿转代码建设实践

云音乐 AI Agent 探索实践

云音乐低代码 + ChatGPT 实践方案与思考

🦜🕸️ LangGraph:Plan-Execute Agents 实战

Pinecone总结一:大模型角度

使用 Hugging Face 微调 Gemma 模型

开源大语言模型作为 LangChain 智能体

200万上下文窗口创飞Gemini 1.5!微软来砸谷歌场子了(doge)

如何利用大模型进行数据标注与知识蒸馏:兼看ActiveRAG上下文去噪的大模型RAG问答范式

树形结构与RAG的完美结合:T-RAG方法在组织内部信息查询中的突破

领先99%小白的Sora关键信息!

AI, Machine Learning和 Deep Learning有什么差异

模型融合、混合专家、更小的LLM,几篇论文看懂2024年LLM发展方向

开源大模型王座易主!谷歌Gemma杀入场,笔记本可跑,可商用

关于Google开源Gemma的一些想法

LangChain原理学习笔记

工具增强型大模型:引领智能新时代

AI 实战:手把手教你使用「扣子/coze」来搭建个人blog知识库

大模型推理优化实践:KV cache复用与投机采样

NLP研究在大模型时代的创新飞跃

下一代RAG范式:RAG-Fusion

图解大模型计算加速系列:Flash Attention V2,从原理到并行计算

如何在小公司做大模型

机器学习简介: 寻找函数的艺术

OpenAl 视频生成模型 —— Sora技术报告解读

⭐️ Go & 云原生 & Rust 相关

etcd存储引擎之主干框架

Rust 高性能编程指南

Go map 加有序排序的一些挣扎

云音乐 GitOps 最佳实践

KisFlow-基于Golang的流式计算框架实战(1)

相同型号物理机,容器性能不如虚拟机

听GPT 讲Rust源代码--library/portable-simd

Go deadcode:查找没意义的死代码,对于维护项目挺有用!

通俗易懂剖析Go Channel:理解并发通信的核心机制

竟然是"你"偷走了那0.001的服务可用性

精心设计的 DNS Failover 策略在 Go 中竟然带来了反效果,发生了什么

Go语言中常见100问题-#100 Not understanding the impacts of running Go

《从慢速到SIMD》聊Go 边界检查消除

Go项目中的Labels

Go 更强的代码洁癖,可以把 gofmt 给换了!

Go 终于把这个傻缺特性去掉了,多少陈年老BUG都是因为它!

Go 1.22 slices 库的更新:高效拼接、零化处理和越界插入优化

Go 1.22中值得关注的几个变化

Go中最常用的数据校验库

📒 后端相关

美团面试:说说OOM三大场景和解决方案? (绝对史上最全)

(九)深入并发编程之并发容器:阻塞队列、写时复制容器、锁分段容器原理详谈

(八)深入并发之Runnable、Callable、FutureTask及CompletableFuture原理分析

四十五图,一万五千字!一文让你走出迷雾玩转Maven!

踩了一堆坑,终于把微服务系统全面升级 JDK17 和 SpringBoot3 了

奇思妙想的SQL|兼顾性能的数据倾斜处理新姿势

如何成为一线 Leader

ForkJoinPool:大任务拆分,让并行嗨起来!

写了这么多年DateUtils,殊不知你还有这么多弯弯绕!

这些年背过的面试题——Kafka篇

📒 前端相关

🤯 [性能优化] 浏览器跨域带来的一些性能问题

🧐 [跨端开发] 如何定位 Hybrid Web 页面中 Native 注入的 JS 代码

413 - 《读书笔记:A Philosophy of Software Design》

如何在泛型组件中使用 forwardRef

译:Hot Module Replacement 原理

MDH Weekly 121 - 《开工大吉》

· 7 min read
加菲猫

alt text

封面图:牛逼了!2月编程语言榜单:Go首次进入前十

🌟 AI 相关

How to Cut RAG Costs by 80% Using Prompt Compression

RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture

RAG vs Finetuning — Which Is the Best Tool to Boost Your LLM Application

大语言模型之LlaMA系列- LlaMA 2及LLaMA2_chat(上)

RAG还是微调?微软出了一份特定领域大模型应用建设流程指南

谷歌全新大模型突然发布!100万token完爆GPT-4,仅靠提示词就能学会新语言

扩展说明: 指令微调 Llama 2

社区供稿 | 图解大模型推理优化之 KV Cache

大模型性能优化之Prompt工程全面梳理:从zero shot到chain of thought再到花式XOT

大模型RAG问答行业最佳案例及微调、推理双阶段实现模式:基于模块化(Modular)RAG自定义RAG Flow

值得一看的大模型RAG问答总括性梳理:模块化(Modular)RAG范式的定义、构成及机遇

【有腔调的RAG】01 半结构化数据上的RAG

省钱!微软开源框架LLMLingua + LlamaIndex实现提示词压缩

Ollama Python开发包实例 | 基于本地部署开源大模型的Streamlit聊天应用

【隐私优先】Llama 2 + GPT4All + Chroma实现100%本地化RAG

大模型时代还不理解自注意力?这篇文章教你从头写代码实现

陈丹琦团队新作:数据量砍95%,大模型性能更强了!Less is More

【AI 初体验】 llama2与LangChain 的 SQLDatabaseChain

⭐️ Go & 云原生 & Rust 相关

从物理机到K8S:应用系统部署方式的演进及其影响

Leetcode 算法题解精选

牛逼了!2月编程语言榜单:Go首次进入前十

Go语言中常见100问题-#99 Not understanding how the GC works

Go语言中常见100问题-#98 Not using Go diagnostics tooling

一文搞懂Go GC演进史,讲的太细致了!

Rust 中的并发模型和所有权系统

Kitex:微服务架构下的高性能优化实践

探究 Go 的高级特性之 【处理1分钟百万请求】

探究 Go 的高级特性之 【领域驱动设计中篇】

用 Go 语言实现刘谦 2024 春晚魔术,还原尼格买提汗流浃背的尴尬瞬间!

还不敢写多线程程序?看看Go如何让并发控制简单有趣

从 fatal 错误到 sync.Map:Go中 Map 的并发策略

16. Go调度器系列解读(三):GMP 模型调度时机

15. Go调度器系列解读(二):Go 程序启动都干了些什么

14. Go调度器系列解读(一):什么是 GMP

13. 入门 go 语言汇编,看懂 GMP 源码

8. 看 Go 源码,你需要了解 unsafe.Pointer

5. golang map 源码的逐句解读

一文搞懂Kubernetes 部署策略

滚动更新和回滚部署在 Kubernetes 中的工作原理

Go 项目标准布局?Go 官方出指南了

📒 后端相关

阿里终面:Netty 如何做到单机百万并发

8种专坑同事 SQL写法,性能降低100倍,不来看看

亿级推送,得物是怎么架构的

详解Redis三大集群模式,轻松实现高可用!

阿里Java面试官:CopyOnWriteArrayList底层是怎么保证线程安全的

还搞不懂ConcurrentHashMap底层源码,看这篇就够了

只需七步,教你轻松解决Redis热点Key问题

一文详解Redis中BigKey、HotKey的发现与处理

Java 十亿行数据计算,最快6秒出结果,你能吗

从Kafka中学习高性能系统如何设计 | 京东云技术团队

由浅入深的介绍扣减业务中的一些高并发构建方案(上)

如何在微服务下保证事务的一致性 | 京东云技术团队

【Redis高可用系列】主从复制原理和复制方式分析

Redis删除数据后,为什么内存占用率还是很高

感觉Redis变慢了,这些可能的原因你查了没 (上)

感觉Redis变慢了,这些可能的原因你查了没 (下)

位图(bitmap)原理以及实现

亿万用户在线,一张bitmap统计全解密

如何使用Redis数据类型进行亿级别统计数据

MySQL事务未提交redolog能持久化到磁盘吗

结合MySQL更新流程看 undolog、redolog、binlog

📒 前端相关

致所有渴望学习Rust的人的信

前端项目里都有啥

白嫖ChatGPT4.0 (第二弹)

字节跳动最热门的 15 个前端开源项目

刘谦春晚魔术揭秘:约瑟夫环的数学魅力,JS实现下!

我写了一个根据项目自动切换node版本的插件,再也不用手动使用命令切换了

· 4 min read
加菲猫

alt text

封面图:Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

🌟 AI 相关

MultiHop-RAG: Benchmarking Retrieval-Augmented Generation for Multi-Hop Queries

手把手教你,从零开始实现一个稀疏混合专家架构语言模型(MoE)

苹果为自家芯片打造开源框架MLX,实现Llama 7B并在M2 Ultra上运行

如何用LLM和自有知识库搭建智能Agent

万字详解专家混合:MoE模型

Prompt Engineering:大模型 PUA 指南!

Mixtral-8x7B 模型挖坑

精彩手绘全解:RAG技术,从入门到精通

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

白话Embedding:普通人都能懂的科普文

Mixtral 8x7B: 超越GPT-3.5与Llama 2 70B的稀疏混合专家架构新篇章

3B模型不输7B LLaVA!北大多模态MoE模型登GitHub热榜

GPT-4推理能力暴涨32%,谷歌新型思维链效果超CoT,计算成本可降至1/40

阿里大模型春节礼包来了:代码可执行率超GPT-4,1.5版本全系列开源

刚刚,谷歌弃Bard发布超大杯Gemini,全面对标GPT-4,前2个月免费!

无需RLHF显著提升GPT-4/Llama2性能,北大团队提出Aligner对齐新范式

手撕LangChain代码,新手请进

MoE 卷起来啦!又一微调版 Mixtral-8x7B 发布,试试效果怎么样

不是 GPT4 用不起,而是本地运行 Mixtral-8x7B 更有性价比

在 Mac 运行 OpenChat 3.5 大模型,AI推理APP仅2MB 完全可移植

⭐️ Go & 云原生 & Rust 相关

代码验证斯特林公式的准确性

一些笔记工具工具以及memos介绍

Go 1.22.0 可称之为一次史诗级更新

Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

实现基于 Grafana Loki 的日志报警

齐活了,Grafana 发布大规模持续性能分析开源数据库 - Phlare

📒 后端相关

DDD落地:从携程订单系统重构,看DDD的巨大价值

一次由于八股文引起的内存泄漏

网易面试:请设计一个高可用性的软件架构,说明设计思路

这些年背过的面试题——MySQL篇

天天写业务代码,如何破局业务开发的本质

📒 前端相关

瀑布流优化:我把小红书的瀑布流虚拟列表撕出来了

心遇APP站内玩法H5体验优化实践

译:如何避免 SSR 渲染本地日期时的 FOUC 问题

译:危险的注水

译:React 19 计划推出的新 Hook

译:使用 Promise.withResolvers 延迟 Promise

2024 年你需要知道的 5 个 CSS 代码片段

Partial Prerendering 的 What、Why 和 How

2024 年如何启动 React 项目

MDH Weekly 120 - 《小册》

· 5 min read
加菲猫

alt text

封面图:图文吃透Golang net/http 标准库--服务端

🌟 AI 相关

Large Language Models for Mathematical Reasoning: Progresses and Challenges

A Comprehensive Survey of Compression Algorithms for Language Models

The Power of Noise: Redefining Retrieval for RAG Systems

Corrective Retrieval Augmented Generation

从零构建现代深度学习框架(TinyDL-0.01)

本地运行面壁智能的“贺岁模型”:MiniCPM 2B

「我在淘天做技术」2024年看AIGC是如何让1688主图焕发新春的

大模型推理框架RTP-LLM对LoRA的支持

LLM之LangChain(五)| 使用LangChain Agent分析非结构化数据

LLM之RAG理论(六)| 高级RAG指南和技巧

从零手搓MoE大模型,大神级教程来了

RAG进阶 多用户多文档

RAG 进阶 LlamaIndex多文档

RAG 进阶 多模态图片检索

RAG 进阶 半结构化数据

LlamIndex二 RAG应用开发

LlamaIndex 一 简单文档查询

使用 Docker 快速上手中文版 LLaMA2 开源大模型

部署必备—triton-inference-server的backend(一)——关于推理框架的一些讨论

TensorRT-LLM初探(一)运行llama,以及triton tensorrt llm backend服务化

H100推理飙升8倍!英伟达官宣开源TensorRT-LLM,支持10+模型

大语言模型推理提速:TensorRT-LLM 高性能推理实践

⭐️ Go & 云原生 & Rust 相关

Go1.22 新特性:性能提高、Trace 大修、工作区支持 vendor 等

json.Marshal为什么会对[]byte类型进行base64编码处理

Go调度器系列解读(二):Go 程序启动都干了些什么

Go语言中的Pinner.Pin

Kubernetes 调度器队列 - 设计与实现

Go语言通知协程退出(取消)的几种方式

Go语言中常见100问题-#97 Not relying on inlining

程序员才懂的乐趣:10亿行的挑战

Kubernetes 调度器 - 核心流程 (下篇)

Go调度器系列解读(一):什么是 GMP

Kubernetes 调度器 - 核心流程 (上篇)

图文讲透Golang标准库 net/http实现原理 -- 服务端

利用 ChatGPT 高效搜索Go问题:举一反三的思考方式,高效查找解决方案

Go语言中常见100问题-#96 Not knowing how to reduce allocations

从慢速到SIMG: 一个Go优化的故事

📒 后端相关

8种专坑同事的 SQL 写法,性能降低100倍,不来看看

批量执行Redis命令的四种方式!

阿里面试:设计一个大并发、大数据的系统架构,说说设计思路

码哥字节 124 篇优秀文章精选

Kafka性能篇:为何Kafka这么"快"

Redis 核心篇:唯快不破的秘密

链路追踪落地过程中的挑战与解决方案

美团面试:Sentinel底层滑动时间窗限流算法怎么实现的

字节二面:Spring Boot Redis 可重入分布式锁实现原理

纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式

分库分表的 21 条法则,hold 住!

腾讯二面:epoll性能那么高,为什么

📒 前端相关

扩展你的前端知识库,毫无废话!

TypeScript 5.4 beta: NoInfer 类型、闭包类型分析优化、条件类型判断优化等

升级到 React 18 的经验和教训

· 7 min read
加菲猫

🌟 AI 相关

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

⭐️ Go & 云原生 & Rust 相关

#150 Go 并发模式介绍和创新创造【Go 夜读】

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

从 Context 看 Go 设计模式:接口、封装和并发控制

50 条争论的文章发生了啥:Go 标准库 encoding/json 真的慢吗

Kubernetes 控制器管理总结

使用cmux实现网络端口复用

毫巅之微---不同写法的性能差异 番外篇

2024年的Rust与Go

Go 1.22 rc2 刚刚发布,多个新特性等着大家 forloop,math/rand/v2,增强 http routing

Go 服务网络不通?net/http自带的这个工具帮你快速定位

golang pprof 监控系列(1) —— go trace 统计原理与使用

Go 定时器:Timer 和 Ticker

Go1.22 新特性:增强 http.ServerMux 路由能力,将有更强的表现力!

细节对线,让你写出更安全的 Dockerfile

Go 语言中高效切片拼接和 GO 1.22 提供的新方法

GO 中高效 int 转换 string 的方法与源码剖析

Go合集 | 上新 腾讯Go安全指南

《Go题库·16》读写锁底层是怎么实现的

《Go题库·15》go struct 能不能比较

Kubernetes GC 设计与实现

Go 夜读第 150 期 Go 并发模式介绍和创新创造

跟着老猫来搞GO-内建容器Map

这是我见过最酷的服务端日志收集方案!

Go语言中常见100问题-#95 Not understanding stack vs. heap

Go 语言实战:构建强大的延迟任务队列

为什么 Go1.22 for 循环要支持整数范围

📒 后端相关

万字详解微服务世纪难题:如何平滑拆分单体

没用过微服务?别慌,丐版架构图,让你轻松拿捏面试官

从4万行代码降到1.8万,腾讯视频竟然用DDD做架构重构

转转支付通道监控系统的搭建

微服务架构下网关的技术选型

Linux进程管理工具 Supervisor详解

SpringBoot + SpEL,轻松搞定复杂权限控制,非常优雅!

后端程序员必备:书写高质量SQL的30条建议

云音乐RPC稳定性建设与实践

临时抱佛脚必看|一个月速通高级系统架构设计师!

第一性原理:养猪还是读大学

第二遍读俞军的神作《产品方法论》,真香!

阿里面试:Sentinel熔断降级,是如何实现的

深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!

搞懂异地多活,看这篇就够了

一键部署 SpringCloud 微服务,yyds!

Redis、ZooKeeper、Etcd,谁有最好用的分布式锁

提炼设计框架,一文搞懂Redis/MySQL/Kafka为什么这样设计

腾讯一面:32 位 4GB 系统,访问 2GB 数据,虚拟内存会发生什么

1.5万字+30张图盘点索引常见的11个知识点

腾讯三面:一台服务器,最大支持的TCP连接数是多少

这些年背过的面试题——多线程篇

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

使用双异步后,如何保证数据一致性

📒 前端相关

虚实之间有一期播客讲「拼多多出海的 - TEMU 增长背后黄铮的创业哲学和中企出海之路」听下来讲得很有逻辑,聊到了全托管模式如何简化,拼多多的传统技能低价,以及如何实现的低价,包括中国企业出海的几个阶段,很通俗易懂,值得学习。

https://www.xiaoyuzhoufm.com/episode/657fc03f991e2ee608f54f98

当你想将 feature 分支上的多个 commit 合并到 release 分支,并且希望在 release 分支上只看到一个合并提交时,可以使用 git merge --squash 命令:

# 确保你在 release 分支上
$ git checkout release

# 进行 squash 合并
$ git merge feature --squash

# 在解决完所有冲突后,需要将已解决的文件添加到暂存区
$ git add .

# 提交合并结果为一个新的单个 commit(注意:这里没有自动提交,需要手动提交)
$ git commit -m "Squashed commit from feature-branch: Implemented XYZ feature"

注意,在 GitLab 提 Merge Request,可以在 Merge Request 页面中勾选 squash commit 选项

合并代码遇到冲突,想回退到合并前的状态:

$ git merge --abort

一个小技巧,which 命令可以用来查找可执行文件的路径:

$ which npm

/Users/bytedance/.nvm/versions/node/v18.16.0/bin/npm

框架中的类型编程: Hono 中的模板字符串类型编程

框架中的类型编程:tRPC & Prisma 中的泛型应用

React 19 即将推出的 4 个全新 Hooks,很实用!

我用埋点让老板安静 (埋点篇)

Rust性能很高?不,它完全顶不住我的代码

[]深度解析Webpack打包过程(2万字预警)

MDH Weekly 119 – 《周刊重启和博客》

· 5 min read
加菲猫

🌟 AI 相关

专补大模型短板的RAG有哪些新进展?这篇综述讲明白了

用检索增强生成让大模型更强大,这里有个手把手的Python实现

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

⭐️ Go & 云原生 & Rust 相关

慢聊Golang协程池Ants实现原理

Kubernetes Networking Model & CNI

for-range一个函数,还可以这么用

跟我一起编写 Buildpacks:Go 版本篇

探索Cloud Native Buildpacks的奇妙世界

哈啰云原生弹性伸缩控制器实现细节

使用 Rust 后,我写 Go 的方法都变了!

Go1.22 新特性:Slices 变更 Concat、Delete、Insert 等函数,对开发挺有帮助!

Go 简单设计和实现可扩展、高性能的泛型本地缓存

Kubernetes HPA 设计与实现

从零开始:使用Prometheus与Grafana搭建监控系统

十分钟教你在 k8s 中部署一个前后端应用

Go 夜读第 149 期:如何设计现代云原生网关: Easegress

Go Context 到底放第一个参数传,还是放结构体里

优雅判断 interface 是否为 nil

高效I/O并发处理:双缓冲和Exchanger

📒 后端相关

CPU中的高科技:流水线、超标量、SIMD

让你的代码运行更快:掌握零拷贝技术

电商库存系统的防超卖和高并发扣减方案 | 京东云技术团队

向上管理:让你主动汇报就这么难

RocketMQ 事务消息初体验

云音乐服务端可视化编排平台 TangoFlow 设计与实现

八分钟了解一致性算法 -- Raft算法

代码之外:工程师的成长进阶秘籍

复盘总结,不要错失最大财富

为了让小白也能看懂这个死锁case,我请来了小黑

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

SpringCloud 远程调用为啥要采用HTTP,而不是RPC

业务型团队开发生存指南

DDD领域驱动工程落地实战

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

DDD 四层微服务架构,开箱即用!

2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

Redis 除了缓存,还支持哪些场景

Spring Boot + 规则引擎 URule,太强了!

单租户时代:SaaS范式转移

系统的可观察性是指什么

你管这破玩意儿叫高可用

如何判断业务做不做,什么是UE模型

并发编程的12条规范

性能优化2.0,新增缓存后,程序的秒开率不升反降

📒 前端相关

前端性能优化手册 - RoadMap

React 代码如何跑在小程序上

Taro编译mini-runner包的作用

穿越时空:2023年前端技术盘点与2024年技术展望

Monorepo 项目实现共享 Tailwind 配置

前端食堂技术周刊第 111 期:JS Rising Stars、2024 年如何写 CSS、两个 React、npm 年度回顾

· 7 min read
加菲猫

🌟 AI 相关

中信建投 | AI前沿系列(一):混合专家模型技术(MoE)

《开源大模型食用指南》发布,7个小时,一杯奶茶速通大模型!

Stable Diffusion XL Turbo 文生图和图生图实践

在 Nvidia Docker 容器编译构建显存优化加速组件 xFormers

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用

节省时间:AI 模型靠谱下载方案汇总

修复 OpenCV 依赖错误的小工具:OpenCV Fixer

⭐️ Go & 云原生 & Rust 相关

Linux 6.8 网络优化, 大量并发连接的TCP性能提高40%左右

深入探索 Rust 中的 Panic 机制

探究 Go 源码中 panic & recover 有哪些坑

从《100 Go Mistakes》我总结了什么

3.深入TiDB:执行优化讲解

亲测体验Go语言模糊测试

Go 发布了一个非安全补丁的 Go 1.21.6

Go1.22 新特性:新的 math/rand/v2 库,更快更标准!

每秒百万数据点 Go 应用监控系统演进

别再用GDB了,一文掌握Go最好用的调试器Delve

Kubernetes CronJob 设计与实现

[go 面试] 实现服务高可用的策略和实践

我是如何实现Go性能5倍提升的

深入理解Go标准库-ServeMux的使用与模式匹配

深入理解Go标准库-http server的启动

使用 Grafana 和 Loki 监控传说中的武当纵云梯

Grafana 教程 - 构建你的第一个仪表盘

成本更低、更可控,云原生可观测新计费模式正式上线

Kubernetes Job 设计与实现

依赖Kafka的Go单元测试例解

Go1.22 新特性:for 循环不再共享循环变量,且支持整数范围

Go运行时的并发原语

Go语言中常见100问题-#94 Not being aware of data alignment

Go 语言中 defer 使用时有哪些陷阱

Go语言之父的反思:我们做对了什么,做错了什么

学习C++20, 为Go的atomic类型插上一双翅膀

📒 后端相关

一张图总结架构设计的40个黄金法则

这些年背过的面试题 — 架构设计篇

这些年背过的面试题——Spring篇

mysql 的 binlog、redolog、undolog 是啥:

  • Binlog(二进制日志):
    • 用于复制:在主从复制中,从数据库会重放主数据库中存储的 binlog,以实现主从同步。
    • 数据库恢复:binlog 可以用于数据库的按时间点还原。
  • Redo log(重做日志):
    • 确保事务的持久性:在事务提交前,redo log 会将事务的修改操作记录下来,以确保在系统崩溃或重启时,可以重新执行这些操作。
    • 防止脏页写入:在系统崩溃时,redo log 可以防止脏页(未提交的数据页)被写入磁盘。
  • Undo log(撤销日志):
    • 用于事务的回滚:在事务执行过程中,undo log 记录了事务修改前的数据版本,以便在事务回滚时恢复数据。
    • 多版本并发控制(MVCC):undo log 支持数据库的多版本并发控制机制,允许事务在不加锁的情况下读取一致的数据。

这些日志文件在 MySQL 中扮演着不同的角色,确保了数据库的一致性、持久性和并发控制。

使用懒加载 + 零拷贝后,程序的秒开率提升至99.99%

万字+20张图探秘Nacos注册中心核心实现原理

7000字+30张图看懂分布式追踪系统原理

拒绝用复杂度自慰:下云高可用的秘诀

公司为什么要使用OKR,目的是什么

阿里面试:说说Rocketmq推模式、拉模式

分布式事务概述与项目实战

分布式锁最终解决方案是RedLock吗?为什么

刷了四百道算法题,我在项目里用过几道呢

烂大街的缓存穿透、缓存击穿和缓存雪崩,你真的懂了

抖音提前批二面:为啥不推荐使用外键

增加索引 + 异步 + 不落地后,从 12h 优化到 15 min

📒 前端相关

有了它 Antd 样式覆盖不要太爽

一文带你从0到1做性能优化——国际化业务中台性能优化实践(上)

Bun 如何设置 npm registry,有时会用到 bunx 命令,会自动下载 npm 包,因此需要配置 npm registry:

# 在根目录建一个 `.bunfig.toml` 配置文件
$ vi $HOME/.bunfig.toml

写入如下内容:

[install]
# set default registry as a string
registry = "https://registry.npmjs.org"

参考:https://bun.sh/docs/install/registries

两个 React

2024 年前端预测

业务中后台用户体验优化方法论总结(体验篇)

分享4 个你可能感兴趣的 TikTok 前端面试题

Chrome 三方 Cookie 禁用已正式开始!

使用 Taro 开发鸿蒙原生应用 —— 快速上手,鸿蒙应用开发指南

- - +
Skip to main content

· 46 min read
加菲猫

🌟 AI 相关

《南洋理工发布多模态金融交易Agent,平均利润提高36%!》。本文介绍了南洋理工大学发布的多模态金融交易Agent,通过融合大语言模型(LLMs)和多模态数据处理,提高了金融交易的效益。传统基于规则的交易系统在适应市场波动方面存在不足,而基于强化学习的系统虽然适应性更好,但在处理多模态数据和可解释性方面仍面临挑战。该文中提出的FinAgent是一种先进的多模态基础代理,能够综合分析多种形式的金融数据,提供精确的市场趋势分析和决策支持。实验证明,使用FinAgent进行金融交易可以平均提高36%的利润。论文链接:https://arxiv.org/pdf/2402.18485.pdf

《大模型推理:A100/H100 太贵,何不用 4090?》。本文介绍了大模型推理时,为什么可以考虑使用4090显卡。相比于A100和H100显卡,4090在性价比上更高,尤其在极致优化的情况下,甚至可以达到H100的2倍性能。文章指出,A100、H100和4090在算力方面的差距并不大,最大的区别在通信和内存方面。由于大模型训练使用高性能的通信,4090通信效率相对较低,因此在大模型训练中并不适用。然而,在推理(inference/serving)方面,4090在性价比上有优势,尤其是相对于H100显卡而言。文章还提到了GPU的训练性能和成本对比,以及大模型训练所需的算力和GPU数量等问题。详细内容可参考文章链接。

《精度提升!南加大等 | 提出分治Prompt策略,提升LLM分辨力》。本文介绍了一种基于分治算法的Prompt策略,旨在提高大语言模型(LLM)的分辨力。现有的提示策略在处理涉及重复子任务和含有欺骗性内容的任务时存在一定限制。为了解决这个问题,研究人员提出了一种基于分治算法的提示策略,利用分治程序来引导LLM的求解过程。该策略将任务划分为子问题并分别求解,然后合并子问题的答案。通过实验证明,这种分治策略能够提升模型在大整数乘法、幻觉检测和新闻验证等任务中的性能,相比传统提示策略具有更好的准确率和性能指标。论文地址:https://arxiv.org/pdf/2402.05359.pdf

《开源版“Devin”AI程序员炸场:自己分析股票、做报表、建模型》。这篇文章介绍了一个基于MetaGPT的开源项目Data Interpreter,该项目旨在处理数据实时变化、任务之间的复杂依赖关系、流程优化需求以及执行结果反馈的逻辑一致性等挑战。通过演示,展示了Data Interpreter在分析股票、预测葡萄酒质量、自动抠图、预测疾病进展和预测机器运行状态等方面的能力。该项目由MetaGPT团队与多所高校合作推出,提供了一种自主进行数据分析和建模的开源工具。

《【原创】一文读懂RAG的来源、发展和前沿》。本文介绍了检索增强生成(RAG)技术,该技术结合了检索和生成过程,旨在提高机器生成文本的相关性、准确性和多样性。文章详细解释了幻觉问题的存在以及解决幻觉问题的几种常见方法。RAG利用外部数据源进行信息检索,将检索到的信息作为上下文输入到生成模型中,从而帮助生成正确的响应。讨论了RAG的核心部件,如向量数据库、查询检索和重新排序。同时介绍了RAG在知识图谱和树结构方面的拓展。

《万字长文解析:大模型需要怎样的硬件算力》。这篇文章探讨了大模型在算力、存储、通信等多个方面上硬件资源的挑战和瓶颈。文章分析了以Transformer结构为核心的大模型在算力瓶颈、显存瓶颈和通信瓶颈方面的困境,以及当前所采取的硬件资源优化技术。此外,文章还提供了对大模型参数量和算力需求的量化估算,为选择合适的硬件设备和评估资源需求提供了指导。

《什么是好的大模型训练数据?》。本文基于Lilian Weng的博客,讨论了大模型如LLM在训练过程中对高质量数据的需求。认为高质量数据来源于“高质量人类”产生的标注数据,并强调了数据处理的重要性,提到了数据标注、质量控制和错误修正的重要步骤。文章还讨论了用于评估数据质量的多种方法,如Influence Functions和Noisy Cross-Validation,并提出了专注于“搭建高质量的数据标注pipeline”的企业方向。最后指出,在AI时代大量产出的数据中维护数据质量,是一个值得关注的挑战。

《读过的最白话讲清楚RAG原理的文章》。这篇文章直观地阐释了检索增强生成(RAG)的概念和工作原理,它是一种结合检索和生成的问答系统。该系统首先通过检索步骤找到与用户问题最相关的知识库内容,然后将这些内容与问题共同输入大型语言模型(例如ChatGPT)以生成答案。文章详细介绍了如何利用嵌入模型对知识库文本进行索引,以便协助语言模型进行精确的检索。此外,它还探讨了语义搜索背后的核心原则和技术细节点,如何通过嵌入找到与用户输入最匹配的知识,以及如何格式化文档以供语言模型使用,以便获得更高效的回答。

《LLM推理算法简述》。本文介绍了用于提高大型语言模型(LLM)推理性能的关键技术与策略。内容涵盖显存优化方法,如KV Cache减少显存浪费、MQA和GQA减少KV-Cache数量、Page Attention进行显存管理,以及提高推理速度的FlashAttention改进。文章还探讨了算子融合技术,比如FasterTransformer和DeepSpeed Inference的应用,以及调度优化策略如Async Serving和Dynamic Batch,最后介绍了用于处理大模型的分布式并行技术。这些优化手段能显著提高LLM推理过程中的性能与效率。

《数学推理增强!微软 | 提出数据合成框架:KPDDS,微调Mistral-7B性能超34B模型!》。微软的研究团队为提升大型语言模型(Large Language Models, LLMs)在数学推理任务的性能,提出了关键点驱动的数据合成(KPDDS)框架。KPDDS利用真实数据源中的关键点和示例对生成高质量问答对来训练语言模型。研究者基于此框架创建了KPMath数据集,进一步结合推理密集型数据形成KPMath-Plus数据集。在MATH测试集上,微调后的Mistral-7B模型达到了39.3%的零样本通过率,超越了数量更多的34B模型,证明了KPDDS的有效性与创新性。这一成果标志着LLMs在数学推理方面的性能得到显著提升。

《首个AI软件工程师上线!已通过公司面试抢程序员饭碗,华人创始团队手握10块IOI金牌》。在这篇文章中介绍了由华人创立的Cognition AI公司开发出来的首个人工智能软件工程师Devin。与现有GPT-4等模型不同,Devin能够独立完成复杂的编程任务,并已成功通过人工智能公司的面试和在自由职业平台Upwork上接单。得益于Cognition AI在长期推理和规划方面的进步,Devin在做决策和执行任务时,能回想相关上下文、随时间学习并修复错误。这标志着人工智能在理解真实世界软件工程问题方面取得了突破,为AI领域迈向更高层级的自动化及监督性工作开辟道路。

《向数字世界AGI迈进!智能体已经从头开玩「荒野大镖客 2」了》。这篇文章展示了如何使用Cradle这一通用计算机控制智能体框架进行AI的研究与应用,在无需内部API支持下控制键盘和鼠标以及与各类软件交互。文章来源于北京智源人工智能研究院、新加坡南洋理工大学和北京大学的联合研究。Cradle由六大模块组成,包括信息收集、自我反思、任务推断、技能管理、行动计划和记忆模块。这些模块让智能体能够自主进行决策和任务执行。研究团队通过将Cradle部署于《荒野大镖客 2》这一复杂的3A游戏中证明其通用性,Cradle能够自主完成游戏主线和探索开放世界。智能体的这种通用能力标志着智能体研究向通用人工智能(AGI)迈进的重要一步。

《深入浅出 LangChain 与智能 Agent:构建下一代 AI 助手》。文章深入讲解了LangChain工具箱及其如何赋能智能Agent,以构建更加智能的AI助手。LangChain利用大型语言模型如GPT-4,提供了一个开源软件框架,可助力开发者搭建基于语言模型的应用。它提供了六大类组件,如模型、提示模板、索引、文档加载器、文本分割器和向量存储,让GPT-4等模型不仅能处理语言,还能与外部API互动、管理用户上下文。文章以构建人脸技术问题排查助手为例,展示如何运用LangChain来协助问题诊断与智能交互,朝向自主、高效的智能应用发展。

《使用零一万物 200K 模型和 Dify 快速搭建模型应用》。本文详细介绍了如何使用零一万物的200K模型和Dify(LLM IDE)快速构建模型应用程序。作者首先对一个机器学习电子书进行翻译,并分享了源代码,然后引导读者如何申请和配置零一万物模型API。随后,作者说明了如何使用Dify IDE快速搭建和调试模型应用程序,以及如何使用Golang和AI模型自动化电子书的翻译过程。最后,作者总结了自动翻译程序的构建过程并展示了批量翻译内容的方法。整篇文章不仅是使用Dify的实操指南,还提供了一种效率化、自动化处理文本内容的示例,适合那些在寻找快速开发和集成大语言模型到应用中的开发者参考。

《一文看完多模态:从视觉表征到多模态大模型》。本文为读者系统梳理了图文多模态与多模态大模型领域的发展,尤其聚焦在视觉表征和视觉与文本融合方法上。文章从卷积神经网络(CNN)及其预训练方法开始讲起,从图像处理的视角介绍了多模态融合的初期方法,如LXMERT、VL-BERT和UNITER等。进一步,文章论述了Vision Transformer(ViT)及其预训练方案如MAE和BEIT,以及基于ViT的多模态对齐与预训练技术,如CLIP和VILT等。作者通过丰富的示例和对比,使读者能够理解这些模型在结构和功能上的不同与联系,为进一步研究提供了宝贵的资源和视角。

《浙大&中科院让Agent学会自我进化,玩德州扑克心机尽显》。Wenqi Zhang等研究者介绍了名为Agent-Pro的AI智能体,它使用大模型(GPT-4)为基础,配合自我优化的策略,能够运用虚张声势、主动放弃等复杂策略玩转德州扑克和21点等非完美信息博弈游戏。Agent-Pro的设计使其能够自我进化,适应复杂和动态的游戏环境,并通过策略层面的反思和世界模型的优化来提高自己的表现。该研究展示了AI在博弈领域的进步,同时为解决多agent现实世界问题提供了新策略。

《面向工业级推荐!“小”LLM也能做好推荐系统》。本文由蚂蚁集团AI创新研发部门NextEvo撰写,介绍了他们的论文《Can Small Language Models be Good Reasoners for Sequential Recommendation?》获得WWW 2024 (Oral)录用。文章针对大语言模型(LLM)在推荐系统应用时代价高昂的问题,提出了一种名为SLIM的基于蒸馏的大模型推荐框架。SLIM通过知识蒸馏技术,将大模型的知识和推理能力迁移到较小的模型上,从而达到用更少参数实现高效推荐的效果。论文强调SLIM在处理长尾物品和新用户推荐的优势,改进了传统基于交互数据的推荐系统偏差问题,并在保持推荐准确度和可解释性的同时降低资源消耗。

《AIOps 智能运维:有没有比专家经验更优雅的错/慢调用分析工具?》。本文介绍了阿里云应用实时监控服务 ARMS 最新推出的错/慢 Trace 分析功能。此功能不依赖专家经验,能对比分析错/慢 Trace 和正常 Trace 的每个维度,从而快速定位问题根源。针对生产环境下调用时延和错误调用的多种因素(如流量不均、单机故障等),ARMS 通过对错/慢 Trace 和正常 Trace 的对比,帮助用户发现异常的共同特征,从而定位到具体问题。这个工具提供了一种优于传统专家经验的快速、有效诊断系统问题的方法,并且附有最佳实践案例。文章最后提供了免登录的 demo 体验链接,引导用户了解和使用该功能。

《CUDA编程优化方法——Memory coalescing》。这篇文章对CUDA编程中的内存合并技术—— Memory coalescing进行了详细介绍。文章首先解释了全局内存的特点以及为何访问速度慢,并阐述了Memory coalescing的目的是通过合并内存访问操作来有效地利用带宽。通过对多维数组的存储方式及访问模式的解析,文章进一步讲解了Memory coalescing的具体实现细节,如何在多维数组访问和矩阵乘法中实现内存访问的合并。最后,文章提供了优化策略,以改进计算的内存访问模式,并提高CUDA内存传输的效率。

《扩散模型如何构建新一代决策智能体?超越自回归,同时生成长序列规划轨迹》。本篇文章介绍了扩散模型在强化学习中的多种应用场景,探讨了如何超越传统的自回归方法,同时生成长序列规划轨迹来模仿人类的决策过程。上海交通大学的团队所作的综述梳理了扩散模型在强化学习中的运用如轨迹规划、策略表征、数据合成,及其解决长序列规划误差累积、策略表达能力受限和数据稀缺等问题的巨大潜力。最终,文章对扩散模型未来的发展方向进行了展望,提出了生成式仿真环境、加入安全约束、检索增强生成及组合多种技能等多个研究方向。

《动手做一个最小RAG——TinyRAG》。本文由不要葱姜蒜指导读者如何一步步实现基于检索增强生成技术(RAG)的简化模型——TinyRAG。TinyRAG仅包含RAG核心功能,即Retrieval(检索)和Generation(生成)两个模块。文章详细介绍了RAG的基本结构,包括向量化模块、文档加载与切分模块、数据库和检索模块,以及如何根据检索内容生成回答。此外,还提供了对应的开源项目代码,助力理解语言模型与RAG的原理,并能够在实践中加以应用和拓展。

《聊一聊Transformer中的FFN》。这篇文章探讨了为什么Transformer的前馈神经网络(FFN)部分长期以来几乎没有大的改动。文章通过比较不同的激活函数,如ReLU、GeLU和Swish等,分析它们在Transformer中的应用效果和局限性。同时探讨了线性投影的必要性、参数量及其对模型容量和记忆力的影响。此外,文章还涉及了混合专家模型(Mixture-of-Experts,MoE)以提升Transformer的效率,并讨论了构建通用人工智能(AGI)所需要的结构特性,特别是放缩定律(Scaling Law)、上下文学习(In-Context Learning)、效率提升(Better Efficiency)和终生学习(Life-long learning)的重要性,最后对未来结构创新给出透彻见解。

⭐️ Go & 云原生 & Rust 相关

《More powerful Go execution traces》。Go的runtime/trace包提供了用于理解和排查Go程序的强大工具,允许对goroutine的执行进行跟踪。新版本Go大幅度降低了执行跟踪的运行时开销,从多数应用中的10-20% CPU下降到1-2%。文章介绍了如何通过将trace分割,从而使得trace可以扩展且保持低开销,还实现了飞行记录功能,使得即使在事件发生后也能从trace中获取信息。Go也提供了一个实验性的trace读取API,使程序性的跟踪分析成为可能。

《Rust: 实现比特币的交易模型》。本文详细介绍了比特币的交易模型中的UTXO(未花费交易输出)模型,并使用 Rust 语言来实现和展示其运作过程。UTXO 模型与传统的账户余额模型不同,将用户的余额分散存储在多个UTXO中。每个UTXO代表比特币网络上一笔可用于未来交易的输出。文章解释了UTXO模型的工作原理、优势以及交易处理流程,包括选择输入、生成输出、签名交易和广播交易。接着,文章提供了一个 Rust 实现的简化示例,展示了如何定义交易结构体、输入、输出以及UTXO集合,并介绍了基本的操作方法。如果你对比特币交易模型和 Rust 编程感兴趣,可以阅读该文章了解更多细节。

《深入理解 Go Modules: 高效管理你的 Golang 项目依赖》。本文详细介绍了 Go Modules 在 Golang 项目中的使用方法和原理。文章首先回顾了 Go 依赖管理的历史,从 GOPATH、Go Vendor 到 Go Module 的演进过程。然后讲解了模块、包和版本的概念,包括模块路径、包路径以及版本的格式和语义。接着,文章介绍了 Go Modules 的环境配置,包括 go env 环境变量和依赖管理文件(go.mod 和 go.sum)的作用和使用方法。最后,文章提供了一些实用技巧和常见问题的解答,帮助读者更好地理解和应用 Go Modules。如果你对 Golang 项目的依赖管理感兴趣,可以阅读该文章了解更多详情。

《Kubernetes集群节点处于Not Ready问题排查》。当Kubernetes集群中的节点显示为"Not Ready"状态时,这篇文章提供了一系列的排查步骤。首先,通过运行特定的kubectl命令来确认节点的状态并获取节点详细信息,检查可能的错误消息或者警告。接着,进入节点系统查看各种系统日志,并使用相关命令如grep、cat或tail来辅助分析。文章还建议检查kubelet服务状态和配置文件,确认系统资源是否充足,试图解决可能存在的磁盘空间和网络问题。最后,通过使用诸如ping、traceroute等诊断工具确保节点能够与主节点通信,并检查重要的网络端口是否开放。确保Kubelet能正确连接到Kubernetes API,并使用Kubernetes的诊断工具如kubectl get componentstatus检查组件状态。通过这些步骤,可以系统地排查并解决"Not Ready"的问题,保持集群健康。

《Go 错误处理: 用 select-case 来解决这个历史难题?》。煎鱼在这篇文章中介绍了一个新的Go语言错误处理提案,这个提案尝试用select-case结构作为错误检查的替代。这个新语法允许在select关键字之后声明一个变量为“陷阱”,赋值给该变量时触发case检查,以减少传统的if err != nil检查的繁琐性。新提案保持了Go1代码的兼容性,尝试提供一个更简洁、向后兼容的错误处理方式,尽管目前社区内对此仍未达成共识。

《K8s蓝绿部署:优雅应对应用程序更新挑战》。本文详细探讨了使用Kubernetes(K8s)进行蓝绿部署的方法,以达到无缝更新应用程序并最小化宕机时间。蓝绿部署是一个运行两个相同生产环境的模式,能够在更新时切换流量,确认无误后便去除旧环境。文章指导了从创建命名空间、创建和应用部署、服务及其路由规则、执行蓝绿切换,到最后的验证和回滚过程。这一过程不仅优化了应用版本的滚动更新,也为开发者提供了快速回滚的方案,以应对可能出现的问题。

《Go 中的高速数据包处理:从 net.Dial 到 AF_XDP》。文章介绍了使用 Go 语言进行高速数据包处理的多种方法,包括 net.Dial、原始套接字、系统调用、pcap 和 AF_PACKET,直至最新的 AF_XDP 方式。作者详细对比了每种方法的性能,从简单的 net.Dial 模式演进到 AF_XDP,逐步提高数据包每秒处理数量,同时指出各方法的使用场合和限制。通过基准测试,发现使用 AF_XDP 可实现最高性能,处理速度是使用 net.Dial 方法的4倍多。这些技术探讨对于需要大量网络数据包处理的场景,如网络监控、性能评估等都是非常重要的。

《数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)》。文章探讨了在云原生时代下,有状态服务(如生产环境的数据库)是否适用于容器化并由Kubernetes进行管理的问题。以B站Elasticsearch和Clickhouse的容器化和Kubernetes编排实践为例,文章详细介绍了在容器环境中部署这些有状态服务的挑战和解决方案,包括控制器的选择、持久化存储、磁盘调度、调度器、容器网络、服务发现以及如何保证集群和数据的高可用性。作者分享了通过Operator管理有状态服务应用、使用本地盘PV提升性能、LVM技术的动态扩缩容方案以及通过macvlan进行容器间高效通信的技术细节。

《一文带您探索 Kubernetes 中的容器类型》。文章介绍了在 Kubernetes 系统中常见的四种容器类型:初始化容器(Init Container)、边车容器(Sidecar Container)、临时容器(Ephemeral Container)和多容器(Multi Container)。初始化容器用于运行 Pod 中主容器启动前的准备工作,而边车容器则与主应用容器并行运行,为其提供支持服务。临时容器主要用于故障排除,而多容器 Pods 允许并行运行多个容器,共享资源和数据。文章提供了每种容器的详细使用案例、配置方法和命令,并强调了各自的特点与应用场景。

《4 秒处理 10 亿行数据! Go 语言的 9 大代码方案,一个比一个快》。软件工程师Ben Hoyt挑战使用Go语言处理10亿行数据,并提出了9种解决方案,其中最快在4秒内完成。这些方案只使用Go标准库,包括简单但优化的map处理、并行化处理等。Ben的方案虽未最快,但展现了独立思考的价值。他的测试表明,彻底地数据处理和算法优化可显著提高性能,减少计算成本。

《Go arena 民间库来了,可以手动管理内存!》。文中作者煎鱼介绍了Go语言的一个新的第三方库ortuman/nuke,这个库允许开发者手动管理内存。文章首先回顾了Go官方对于arena手动内存管理提案的停滞现状,然后重点介绍了如何使用ortuman/nuke库进行内存管理,包括库的安装、使用案例以及如何在并发场景下保持线程安全。文章详细讲解了arena内存管理的优点,例如高效率和一次性释放,并对库的实际用法,如通过context在HTTP请求周期中管理内存,进行了展示。最后,基于性能考虑,文章还提供了并发与非并发业务场景下的基准测试结果以及性能差异。

Go 语言中如何大小端字节序?int 转 byte 是如何进行的

Go 中如何实现三元运算符?Rust 和 Python 是怎么做的

Go语言中 enum 实现方式有哪些?一定要绝对类型安全吗

Go 中如何打印结构体? 代码调试效率提升

《快看! Go 1.22 对for循环进行了两个大更新》。文章讨论了Go语言在 1.22 版本中针对for循环作出的两项主要更新:1. 每次迭代的for循环都将定义一个新的变量,不再共用同一个变量;2. 引入了对整数范围的循环迭代支持。这些更新解决了闭包在并发执行时共享变量带来的问题,同时也简化了循环结构,提高了编写对整数范围进行迭代代码的方便性。文中提供了详细的代码示例来展示新旧版本之间的差异,并说明了如何利用新特性来编写更高效的Go代码。

《从慢速到SIMD》聊Go边界检查消除》。本文讨论了Go语言中边界检查消除(BCE)的相关技巧和最佳实践。文章首先回答了为何在Go代码中优化时选择使用a[i:i+4:i+4]而不是a[i:i+4]的问题,指出前者能减少编译器工作量从而提高性能。然后,介绍了Go101提出的BCE技术详解与应用实例,以及如何使用编译命令来检测边界检查的存在。文中还全面梳理了Go BCE技术的发展历程,以及在不同场景下消除冗余边界检查的方法,包括利用循环变量、常量索引等策略来提高代码执行效率。最后,提供了多种编程技巧以及相关讨论和参考资料,针对遇到的编程问题提出解决方案。

📒 后端相关

《分库分表已成为过去式,使用分布式数据库才是未来》。本文讨论了随着Mysql数据库性能下降,分库分表的局限性及其所引发的问题,如性能、事务、数据迁移等,并提出使用分布式数据库作为解决方案。文章详细介绍了TiDB这款分布式数据库的架构、特性和优势,包括其金融级的高可用性、水平扩容能力、兼容性以及云原生设计。文章强调TiDB在处理大规模数据时的效率和可维护性,终结分库分表的做法,并通过性能测试展示了TiDB与MySQL在不同场景下的性能表现。最终总结,对于数据量大的应用场景,采用TiDB来适应未来数据存储的需求是一个更优的策略。

《手把手带你精简代码-京东零售后端实践》。本文分享了京东零售后端在面临代码库日渐庞大和腐化的问题时,采用的代码精简方法。文章分为背景介绍、代码精简步骤和实施方法三部分,着重介绍了使用IntelliJ IDEA自带工具和PMD插件进行静态代码检查的步骤、配置和优缺点,以及如何借助京东jacoco流水线进行动态代码检查。本文旨在降低代码维护成本、提升可理解性,并详细阐述了代码精简的实践过程和预期结果。

《跟着iLogtail学习无锁化编程》。文章探讨了在多线程情况下,如何通过无锁化编程优化软件性能。详细讲述了iLogtail在实现无锁高效日志采集时采取的策略,比如自旋锁的使用、原子操作、内存顺序、内存屏障等概念。还分析了不同类型的锁的适用场景与特点,包括互斥锁、递归互斥锁和读写锁等。此外,文章还描述了如何将大的锁细分为多个小锁,通过降低锁粒度提升并发性能,以及在iLogtail中如何通过双Buffer机制来读写分离,减少锁的争用。最终,通过无锁化编程提高了iLogtail的日志采集性能,实现了低资源消耗和高性能。

《MYSQL 是如何保证binlog 和redo log同时提交的?》。文章讨论了如何确保在MYSQL中binlog(备份和主从同步用的日志)与redo log(InnoDB引擎层的日志,用于崩溃恢复)同步提交,以及为什么这一点对于防止主从数据不一致至关重要。文中解释了事务处理中的两个关键参数:innodb_flush_log_at_trx_commitsync_binlog,这两个值设置为1时可以确保两种日志的同步提交。该文还介绍了MYSQL的两阶段提交机制如何工作,并提出了业务开发中两阶段提交逻辑的思考,指出在有依赖关系的服务操作中,通过预锁定资源、请求成功后递减资源来保持数据的最终一致性。

《这些年背过的面试题——分布式篇》。本文从分布式系统的基础概念、发展历程及核心问题出发,详细介绍了分布式系统设计中的关键技术点。文章涵盖了负载均衡、服务的拆分与集群、分布式事务、数据一致性问题以及分区容错性等话题,并探讨了CAP理论与BASE理论在实际应用中的权衡。同时,文中还详细解读了常见的一致性算法如2PC、3PC、Paxos、Raft的机制和用例。此外,作者针对如何实现分布式Session、如何确保分布式事务的一致性等常见面试题目提供了详尽的解答,适合做为面试备考资料。

《RocketMQ为什么这么快?我从源码中扒出了10大原因!》。这篇文章详细分析了RocketMQ高性能的10个关键因素:批量发送消息降低通信次数,消息压缩减少带宽和存储压力,基于Netty的高效网络通信模型,零拷贝技术优化磁盘读写性能,顺序写提高数据写入速度,高效数据存储结构,异步机制包括异步刷盘和异步主从复制提升存储效率,批量处理减少网络通信次数和资源消耗,锁优化以及线程池隔离提升并发处理能力。作者通过深入分析源码给出了RocketMQ快速处理和拉取消息的内在原因,并深入讨论了每种技术的优势和实现。

《领导叫我接手一个新业务系统,我是这样熟悉项目的!》。本文作者小许分享了接手新业务系统的熟悉流程和实践方法。包括与产品经理交流了解业务现状,绘制用例图、ER图以明确业务与数据模型,梳理后端模型和核心流程,并运用状态机流转图和时序图深度解析复杂逻辑。最后,还提到了绘制类图以理解代码结构。文章提供了一套系统性的工具和方法,目的是帮助新成员或负责新项目的开发人员快速掌握业务逻辑,有效推进项目进度。

📒 前端相关

《Tango 低代码引擎沙箱实现解析》。本文介绍了Tango低代码引擎的沙箱实现。Tango是一个用于快速构建低代码平台的低代码设计器框架,通过对源代码进行执行和渲染前端视图,实现了低代码可视化搭建能力。借助Tango构建的低代码工具或平台可以实现源码进出的效果,并与企业内部现有的研发体系进行无缝集成。Tango的设计器引擎部分已经开源,并提供了相应的开源代码库、文档和社区讨论组。欢迎加入社区参与到Tango低代码引擎的开源建设中。更多相关文章可以在文中提供的链接中找到。

《未来只需要 2% 的程序员?》。DHH在这篇文章中提出一个激进的观点,预测未来程序员的需求可能会大幅度减少。他比较了农业从97%的人口需求降至2%的变迁,暗示软件开发也可能面临着类似缩减。尽管这个行业曾经经历招聘热潮,但现在许多程序员面临职业前景不稳定。文章讨论了人工智能的发展给程序员职业带来的压力,同时也指出职业变革的不确定性。DHH认为,未来大多数程序员可能无需手动编程,但同时指出科技行业将更加融合进社会,并提高了它的价值。他鼓励程序员接受这一变化,并享受行业的黄金时代。

《前端智能化,扣子(coze.cn)能做什么?》。这篇文章探讨了扣子(coze.cn)平台如何通过提供一个简单的交互式界面来创建聊天机器人(Chatbot)。用户通过与扣子的对话,可以快速设置一个Chatbot,如自动化微信订阅号内容发布等。文章强调了平台的易用性和界面友好性,同时指出了一些潜在缺点,包括无法解决深度问题和偶尔遇到的技术故障。另外,通过知识库和数据库的集成,可进一步提升Bot的功能。作者对扣子的机器人创建过程、优势、建议和改进进行了详细介绍,并通过实操案例展示了前端智能化机器人的搭建过程。

· 35 min read
加菲猫

alt text

封面图:Understanding the Go runtime - Jesus Espino

🌟 AI 相关

《In-context Learning with Retrieved Demonstrations for Language Models: A Survey》。这篇题为 "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" 的文章,主要讨论了语言模型,尤其是大型预训练语言模型如何通过获取的演示进行少量情景学习。这项技术能有效地改进学习过程的效率和可扩展性,并降低手动选择样例时的固有偏见。文章对此领域进行了广泛的研究回顾,对检索模型、检索训练过程和推理算法的不同设计选择进行了讨论和比较。

《碾压LoRA!Meta & CMU | 提出高效大模型微调方法:GaLore,内存可减少63.3%》。Meta和CMU合作提出了一种新的大模型微调方法——Gradient Low-Rank Projection(GaLore)。GaLore通过梯度的低秩投影代替权重的低秩适配,不仅支持全参数学习,而且显著降低了内存占用,减少了63.3%的内存需求。不同于LoRA的低秩权重更新,GaLore利用权重梯度的低秩特性,结合逐层权重更新和8位优化器,有效地优化了内存效率。此外,GaLore还引入了可调整的超参数,提高了其适应性。经实验验证,GaLore的表现优于LoRA,尤其是在预训练模型微调上表现更佳,为大模型训练提供了新的解决策略。

使用 GPT4V+AI Agent 做自动 UI 测试的探索 | 京东云技术团队

Gemini修bug神了!录网页视频把代码库甩给它就行,网友坐不住了:想要访问权限

一键开启 GPU 闲置模式,基于函数计算低成本部署 Google Gemma 模型服务

《Yi技术报告细节分享》。该文章分享了Yi模型的具体实现细节和思路,强调了模型设计围绕模型规模、数据规模和数据质量。Yi模型的预训练阶段数据处理流程包括启发式过滤、学习式过滤、聚类过滤以及去重等步骤,以提高数据质量。微调阶段,Yi模型仅采用了10K数据进行模型微调,强调数据质量胜过数量。在分词器、模型结构及微调参数方面,Yi模型采用了一系列优化措施,包括Transformer-Decoder结构、Grouped-Query Attention等。总的来说,Yi模型通过优化数据处理流程、微调策略、调整模型结构和参数等多方面实现了高效的技术实现。

重新定义大模型推理!Google | 提出SELF-DISCOVER框架,大模型可自写推理结构!

《斯坦福 && 微软 | 发布前端代码生成大模型:Design2Code-18B,助力前端自动化!》。这篇文章主要介绍了一种新的前端代码生成大模型:Design2Code-18B,它可以将网页视觉设计转换成功能性代码。文章首先介绍了将网页视觉设计转换成功能性代码的挑战性和现有方法的局限性,然后提出了Design2Code基准和多模态提示方法,以激发多模态大型语言模型(如GPT-4V和Gemini)的潜力。接着,文章介绍了开源的18B微调模型Design2Code-18B,它基于CogAgent-18B,在多种数据集上进行了预训练,并使用了Huggingface发布的WebSight数据集进行微调。最后,文章展示了Design2Code-18B在Design2Code基准上的优越性能,并提供了一些未来研究方向。

可控文本生成新方法,人大&&南开 | 提出DATG架构,准确性提升19.29%,效率提升1倍

《Auto-Prompt | 大模型提示(Prompt)优化新方法IPC:可根据用户意图进行定向优化》。这篇文章提出了一种名为 Intent-based Prompt Calibration(IPC)的系统,主要目的是通过使用合成案例样本来优化大型语言模型的提示工程。它基于模型生成的数据集进行提示优化,以解决大语言模型对给定提示的敏感性等问题。这种方法的核心思想是根据用户意图迭代细化提示。同时,文章还对 IPC 系统的整体架构和实现流程进行了详细介绍,并展示了一些实验结果。

《更智能的 Agent,Plan-and-Execute Agents 计划和执行》。这篇文章介绍了几种新型的智能 Agent 设计方法,包括 Plan-and-Execute Agents、ReWOO Agent 和 LLMCompiler。Plan-and-Execute Agent 设计法通过明确规划来优化智能 Agent 功能。ReWOO Agent 设计法凭借变量分配功能使得不必对每个任务都使用 LLM。LLMCompiler 则通过任务格式化为 DAG 来提高工具调用的效率。这些新型设计都在不同程度上优化了智能 Agent 的工作流程,提高了工作效率。

《OpenAI Function Calling 与 LangChain Agent 工作原理及区别》。这篇文章介绍了OpenAI Function Calling 与 LangChain Agent的工作原理及它们之间的区别。文章首先列举了大型语言模型的限制,并解释了为何需要Agent。然后,文章介绍了React Agent的工作方式,通过“Reason Only”(向内求索)、“Act Only”(向外探索)和“ReAct”(内外兼修)三种模式优化模型的功能。此外,文章还以一个简单的实例,解释了如何利用ReAct Agent来解答一个包含搜索和计算两个步骤的问题,展示了其实际应用的流程。

《ReAct Agent 回答 RAG 系统中的复杂问题》。这篇文章主要讲述了“ReAct Agent 用于回答 RAG 系统中复杂问题的方式”。随着输入问题的复杂度升高,使用传统的聊天机器人已不能足够有效。于是,作者提出了利用 ReAct Agent,通过自然语言模型(LLMs)逐步规划并执行处理问题的步骤,并定义功能性工具(如时间计算、文本搜索、列表长度计算、百分比变化计算等)以辅助任务完成。这种方法能够更好地干预和控制问题的解决过程,从而提高任务的完成质量。

更智能的 Agent,Plan-and-Execute Agents 计划和执行

ChatGPT也能画图?教你一键生成时序图、类图、流程图、状态图以及用例图

三个被忽视的大模型提示

关于Sora和Stable Diffusion 3,你需要知道的一切

消费级显卡可用!李开复零一万物发布并开源90亿参数Yi模型,代码数学能力史上最强

详解大模型微调全流程

南大俞扬教授:什么是world models/世界模型

深入浅出LangChain与智能Agent:构建下一代AI助手

尤洋教授:开源完整的Sora复现方案来了!

《T-RAG=RAG+微调+实体识别》。这篇文章名为"T-RAG=RAG+微调+实体识别",主要介绍了T-RAG技术,这是一种将RAG架构与微调语言模型和实体树向量数据库相结合的方法,用于支持语境检索。它概述了在敏感文档的背景下如何保护数据隐私,以及如何在有限的计算资源和基于现有文档建立的小型训练数据集中保证用户提问的准确回答。文中还着重介绍了T-RAG的工作流程和实体树的作用。最后,还提出了一个新的评估指标“Correct-Verbose”,用以评价生成回复的质量。此研究不仅是理论研究,也是实践中LLM应用的经验总结,具有实际的指导意义。

《高级 RAG(Self-Reflective RAG)》。这篇文章名为"高级 RAG(Self-Reflective RAG)",主要介绍了Self-Reflective RAG的理念和工作流程。在基本的RAG pipeline中,我们的过程往往受限于被动的检索和生成,而实际操作中,我们需要根据生成的结果进行优化,如改变问题或筛选和排列内容。为了解决这个问题,文章介绍了一种新的自我修正框架,包括Corrective RAG(CRAG)和Self-Reflective RAG。这两种RAG都围绕着对检索和生成内容的评估和反馈进行自我修正,并通过特定标识进行调控。在一定条件下,进一步改进了RAG,使其产生更好的检索和生成效果。

RAG不够聪明?打造更强大的智能体

Anthropic发布Claude3,效果已超越GPT4

从0开始预训练1.4b中文大模型实践

《分类算法入门:以鸢尾花数据集为例》。这篇文章以鸢尾花数据集为例,全面而详细地阐述了机器学习中的分类算法基础知识。首先介绍了人工智能、机器学习和深度学习的基本概念,讲解了机器学习各种分类方法的理论背景。随后通过鸢尾花数据集,展示了如何使用 Python 工具(包括 pandas、sklearn、matplotlib 和 seaborn)进行数据处理、分析和可视化。文章详细讲述了决策树、逻辑回归、支持向量机、K近邻等经典的分类算法,并用图形化的方式展示了分类效果。最后,读者可以通过本文所提供的丰富学习资料来深化对机器学习分类任务的理解和应用。

《万字详解LLM Agents的现状,问题与未来》。这篇文章名为"写在跨年之前:聊聊LLM Agents的现状,问题与未来",主要涉及到LLM Agents的当前状态,面临的问题和未来的可能发展。文章探讨了包括全参微调、Prompt Tuning、LoRA、P-Tuning等在内的SFT(Selective Fine Tuning)范畴的各种技术。其中尤其强调了对于{prompt,response}的单轮问答对的微调是最简单的SFT实现方式。具体的内容细节大概需要阅读原文才能获得更深入的理解。

⭐️ Go & 云原生 & Rust 相关

《Robust generic functions on slices》。这篇文章名为"Robust generic functions on slices",主要探讨了Go的slices包如何提供对切片进行操作的通用函数。该文章首先介绍了如何通过类型参数,一次性为所有类型的切片编写类似slices.Index等函数,而无需针对每种不同的元素类型重新实现。随后,文章深入讲述了新的函数(如Insert, Replace,Delete等)如何修改切片,并通过详述切片在内存中的表现形式及其对垃圾回收器的影响,来帮助读者理解这些函数的工作方式和正确使用它们。文章特别指出,新的Delete函数提供了更清晰地表达程序员意图的方式,而且它不需要分配新的数组,这样就可以在适当时清除无用的元素,帮助垃圾回收。文章强调,调用这些函数后,必须认为原始切片已无效,因为底层数组已被修改。最后,文章还讨论了在处理内存泄漏和元素零值设置等问题时的策略和选项,它们在新版本Go给出的解决方案,以及这些改变可能导致的一些测试问题。此外,作者鼓励开发人员正确使用新功能,并尽量避免上述列举的陷阱。

《Routing Enhancements for Go 1.22》。这篇文章名为"Routing Enhancements for Go 1.22",主要介绍了 Go 1.22 版本中 net/http 包的路由器提供的新特性:方法匹配和通配符。这些新特性让你可以使用模式,而非 Go 代码,来表达常见的路由。这种新功能,尽管简单易懂,但要选择出多个匹配请求的最佳模式却是一项挑战。文章还详细阐释了如何在新版 Go 中使用这些新特性,以及这些引入的变化如何影响了 ServeMux 方法 handle 和 handleFunc 。此外,还描述了新模式如何更具优先级,并解释了其背后的原理。同时,为了保持新旧版本的兼容性,作者们也努力使新的模式语法能覆盖旧的,并使新的优先级规则能泛化旧的规则。总体上,这些改变是 Go 语言团队不断努力使 Go 成为构建生产系统的优秀语言的一个持续过程的一部分。

听GPT 讲Rust源代码--compiler(6)

使用Apache Kafka的Golang实践指南

《Go 为什么不支持从 main 包中导入函数》。这篇由煎鱼撰写的文章,题为 "Go 为什么不支持从 main 包中导入函数?",对于这个话题进行了深度解析。其首先提到,虽然Go的规范并没有明确禁止从main包中导入函数,但我们在实际运行中会被拒绝,提示main包是一个程序而非可以导入的包。这一现象的原因来自于经过多次变动的规定,如2011年移除了 "程序中的其他包都不能命名为 main" 的要求,然后在2015年又新增了限制。这样的变化主要是为了避免增加复杂度和不安全性。比如,一个函数可能会做出自己拥有完全控制权的假设,所以如果引入多个main包中的函数,可能会产生在初始化顺序、全局变量的注册等方面的冲突。这篇文章认为Go官方的做法在理论上可以解决复杂度和安全性问题,但对于有历史债务的项目,对于需要维护多个Go项目工程,相当于磨灭了一条道路,其实比较尴尬。

《fasthttp是如何做到比net/http快十倍的》。这篇文章讲解了fasthttp如何做到比net/http快十倍的原理。fasthttp相比于net/http在处理流程上有所差异,net/http是一个连接新建一个goroutine,当连接数非常多的时候会给系统带来一定的压力。而fasthttp则是建立了workerPool,每个workerChan在后台都会有一个Goroutine来处理其中的连接。此外,fasthttp的快速也得益于几个方面的优化:连接复用,大量使用了sync.Pool进行内存复用以及通过unsafe.Pointer指针进行[]byte和string转换来避免内存分配和拷贝的消耗。

《万字长文讲解Golang pprof 的使用》。这篇文章主要讲述了Golang的pprof工具的使用。pprof工具是Golang中用于性能分析的一个工具,它可以分析出cpu使用情况、内存占用、阻塞情况、线程和协程等信息。文章中详细阐述了如何使用此工具,主要有两种方式,一种是通过http接口的方式暴露出pprof的采集控制界面,另一种是在程序中通过代码来启动相应指标的采集示例。文章还详细介绍了如何解析通过这两种方式获取的输出信息。本文的主要目的是将pprof工具的使用方式用思维导图的形式展示出来,这样可以帮助读者更好地理解和使用pprof工具。

《一篇实用的关于云上K8s应用分账实践》。本文讲述云上Kubernetes(K8s)应用的成本分摊实践,涵盖了成本分摊的核心概念及阿里云ACK FinOps套件的应用。文中首先以前期预算为集群规划的依据,并讨论了随着业务发展对成本分摊精准度的提升需求。介绍了如何根据Pod的核/时成本,通过ACK集群、计算节点、命名空间和应用Pod这四个维度进行费用分摊。文章还分析了单资源和混合资源分摊模型,并讨论了如何设置Request和Limit来优化资源利用。对于多云和混合云场景,分享了如何通过ACK One实现统一管理和成本分析。针对复杂业务场景,讲述了自定义定价模版的使用方式,允许通过配置实现成本定制需求。对于追求细节管理和精细化运营的团队,这篇文章提供了宝贵的指导。

《如何使用 K8s 两大利器"审计"和"事件"帮你摆脱运维困境》。这篇文章主要讲述了如何使用 Kubernetes(K8s)的"审计"和"事件"功能来帮助进行日常集群运维工作。文章首先指出了运维工作中可能出现的一些问题,例如应用被删除、Apiserver负载突变、集群节点出现问题、节点自动扩容等。随后,文章进一步解释了 Kubernetes的审计和事件是如何运作的,强调了善用这两种工具可以提高集群的可观察性,为运维工作带来极大的便利。总的来说,这篇文章为运维人员提供了一种解决方案,通过使用 Kubernetes的审计和事件,可以更好地管理和监测集群的状态。

【Go 工具】竞态条件检测神器 Race Detector

使用Redis入门Golang

一道面试题: Top K 问题

《理解 Docker 容器中 UID 和 GID 的工作原理》。这篇文章详细解析了 Docker 容器中 UID 和 GID 的工作原理。首先,作者概述了用户名、组名、用户ID(UID)和组ID(GID)在容器内运行的进程与主机系统之间的映射对于构建安全系统的重要性。随后,文章分析了uid/gid在Linux系统的安全性,强调了单一内核概念以及uid/gid的分配方式。接着,作者运用实例解释了Docker运行的过程以及如何通过Dockerfile定义和启动不同用户。最后,文章讲述了如何掌控和控制容器的访问权限。在阐述以上内容的同时,文章也提供了一些实际示例来说明这些观点。

《如何基于Docker镜像逆向生成Dockerfile》。这篇文章介绍了如何将Docker镜像逆向生成Dockerfile。文章主要讲述了利用开源工具Dedockify的操作方法与工作原理。该工具通过Python脚本,利用存储在每个镜像层旁边的元数据,逐步遍历层级树,收集与每个层相关联的命令,重建镜像构建过程中执行的命令序列,从而得到近似的Dockerfile。不过,因为无法访问执行原始docker build命令时存在的构建上下文,如果使用了COPY或ADD指令,生成的输出可能不完全匹配原始的Dockerfile。

《通过多阶段构建减小Golang镜像的大小》。本篇文章主要介绍了如何通过多阶段构建减小Golang镜像的大小。首先,作者提出了一个通用的Dockerfile,并指出其生成的镜像大小超过300MB,主要因为包含了所有的Golang工具。然后,作者提出了多阶段构建的方法,它能从不同的基础镜像构建,有选择地将文件从一个阶段传递到下一个阶段,从而减小镜像大小。在本例中,通过二级构建,镜像大小已降至11.7MB。最后,还探讨了使用名为scratch的空白镜像进一步减小镜像大小的可能性,使得镜像最后降至6.34MB,但作者强调这需要慎重考虑,因为最后生成的镜像将完全没有任何工具。

《k8s 到底是什么,架构是怎么样的》。这篇文章主要讲述了 Kubernetes(K8s)的基本概念、架构和工作原理。Kubernetes,因单词过长,我们通常简化为k8s。k8s 是一种容器的协调工具,位于应用服务和服务器之间,能以策略的方式协调和管理多个应用服务。通过一个 yaml 文件的配置,可以定义应用的部署顺序等信息,自动部署应用到各个服务器上,还能让它们崩溃后自动重启,可以自动扩容和缩容。Kubernetes 的服务器分为两部分:控制平面和工作节点,前者负责控制和管理各个节点,后者则负责实际运行各个应用服务。k8s 的命令行工具为 kubectl,用于执行各类操作命令。

《Go 泛型有没有可能在后期改为 <> 尖括号》。这篇文章主要讨论了Go语言在处理泛型时,为何并没有采用类似Java和C++的 <> 尖括号表示法,而是选择了中括号 []. 首先,使用尖括号可能导致语义混淆,如 a, b := w < x, y > (z) 此句,如果使用尖括号,程序可能在编译阶段无法确定该行表达式的具体含义。其次,使用圆括号也会导致同样的问题,比如 func F(T any)(v T)(r1, r2 T), 无法快速准确判断出参数和返回值部分。此外,Go官方也不希望使用非ASCII的字符。作者还提到社区中对Go的处理方式存在一些争议,部分社区成员认为如果使得编译器解释尖括号不再困难,就可以采用这种符号。然而,总的来说,基于已有的实践和规范,Go语言在未来可能也不会改变其泛型的表示方式。

《Rust中channel的使用》。这篇文章主要介绍了Rust编程语言中Channel的用法。其中,Channel是Rust中用于在不同线程间传递信息的通信机制,实现了线程间的消息传递。每个Channel由发送端和接收端两部分组成,其设计理念是“通过通信来共享内存,而非通过共享内存来通信”,以此避免了数据竞争和共享内存的复杂性。该文章进一步详细介绍了如何在Rust中创建和使用Channel,并给出了相关代码示例。最后,文章阐述了多种Channel模型,包括Rust标准库中所使用的MPSC(多生产者,单消费者)模型。

K8s部署方式大全:从基础到进阶,一文带你掌握所有技巧

k8s从入门到精通 -- 更适合中国宝宝体质

📒 后端相关

《万字+33张图探秘OpenFeign核心架构原理》。本篇文章深入探讨了SpringCloud核心组件OpenFeign的核心架构原理。文章分为四个部分,首先解释原始Feign的使用和基于SpringCloud的进化过历程;然后详细讲解了Feign底层工作原理,依赖于JDK动态代理和核心组件如Contract、Encoder、Decoder等;接下来分析了SpringCloud是如何整合Feign的,并且讨论了OpenFeign的多种配置方式及其优先级;最后,文章通过丰富的图示和代码示例,使读者可以更好地理解并运用这一工具。这篇文章对于理解和运用OpenFeign非常有帮助,无论是对于初学者还是有经验的开发者。

《三万字长文:如何去排查JVM内存问题》。这篇文章是一份详尽的指导,讲述了如何排查JVM内存问题。文中首先定位了技术问题的范围,确定适用于JDK8至JDK11。接着,作者提出了系统化的排查原则,并提供了一步步的诊断流程,从基本信息收集、判断内存增长原因,到具体分析内存问题的可能来源。文章详细介绍了如何利用不同的命令和工具(如jmap、jstat、Arthas等)进行详细的分析,并根据内存使用情况,向读者展示了如何确定是堆内存问题还是堆外内存问题。总之,文章为那些需要深入理解和处理JVM内存问题的开发者和运维人员提供了宝贵的知识和技巧。

《如何避免MYSQL主从延迟带来的读写问题》。这篇文章讨论了如何处理在MySQL主从部署架构中普遍存在的主从同步延迟问题,以保持读写操作的一致性。文章首先介绍了主从延迟产生的场景及其对读写分离原则的影响。然后,详细解释了主从复制的原理,并提出了两种避免主从数据不一致的技术方案:一是使用select master_pos_wait函数来等待从库同步至特定的binlog位置点;二是在开启GTID模式的情况下,通过select wait_for_executed_gtid_set函数检查GTID集合是否已同步。这两种方法均旨在确保从库数据的准确性,从而整体上减轻主库的压力。总体上,文章为MySQL数据库管理员提供了缓解主从延迟导致的读写问题的具体实施方案。

《这些年背过的面试题——ES篇》。这篇文章是一篇针对Elasticsearch(ES)的面试指南,它涵盖ES基础知识点和面试过程中常见问题。内容包括ES的功能特性介绍(如分布式架构、全文搜索、数据分析等)、主要的使用场景描述、与其他搜索引擎的对比(Lucene和Solr)、以及ES的基本概念解释。文章还详细探讨了ES的高级特性,如映射、DSL查询、聚合分析和智能搜索建议器。此外,作者还分享了关于数据索引优化的实战技巧和策略,提供了写优化、读优化和索引重建的方案,这些方案对ES数据存储和查询的性能有显著影响,最后还对Deep Paging性能问题提供了解决方法。对正在准备面试或者希望巩固ES知识的读者而言,这篇文章是一个宝贵的资源。

《什么是MySQL锁?有哪些锁类型》。这篇文章详细地介绍了MySQL中的锁定机制及其类型。起初概述了锁的作用,即协调多进程或线程对资源的并发访问,在数据库环境下,锁对于保持事务的正确性与一致性至关重要。作者明确区分了MySQL中锁的级别,从全局锁、表锁(读锁、写锁)到元数据锁、意向锁,直到行锁的多种形式(记录锁、间隙锁和临键锁)。文中还探讨了AUTO-INC锁的作用和相关优化,举例说明了其在INSERT操作中的应用。此外,文章也涉及了如何根据不同的情况优化锁的使用以及如何避免由锁产生的性能瓶颈。这篇文章为理解MySQL的各种锁类型和锁机制提供了宝贵的信息,特别对于数据库管理员和那些需要管理并发数据访问问题的开发人员来说,具有很高的实用价值。

📒 前端相关

Vue 团队正式开源 Rolldown:基于 Rust 的超快 JavaScrip 打包工具!

打造舒适的vscode开发环境

相比于 Node.js,Deno 和 Bun 到底能带来什么

MDH Weekly 122 - 《招人》

· 4 min read
加菲猫

alt text

封面图:用 switch-case 来解决 Go 错误处理的难题

🌟 AI 相关

LangChain 实战:Agent思维

详解大模型RLHF过程(配代码解读)

PromptFlow高质量AI应用 - 基于LLM的文档QA机器人

图解大模型计算加速系列:Flash Attention V1,从硬件到计算逻辑

使用搭载骁龙 8 Gen 3 的安卓手机运行 AI 大模型

生成式 AI 的发展方向,是 Chat 还是 Agent

聊聊大模型Agent技术,及和具身智能又有什么异同

复旦NLP团队发布80页大模型Agent综述,一文纵览AI智能体的现状与未来

知识问答系统的优化实践:LLM与RAG的结合艺术

一文解构大模型RAG问答关键环节及与LLM微调对比总结

Mistral AI发布Mistral Large模型

Mistral AI新模型对标GPT-4,不开源且与微软合作,网友:忘了初心

大模型微调新范式:当LoRA遇见MoE

Mistral Large,Le Chat来了!Mistral AI连放两个大招!

探索2024年1月的AI研究前沿:模型合并、专家混合与小型LLM的崛起

⭐️ Go & 云原生 & Rust 相关

Cargo的自定义命令扩展功能

听GPT 讲Rust源代码--compiler(2)

元老与新秀:Go sort.Search()和sort.Find()

KisFlow-基于Golang的流式计算框架实战(6)-Connector

跳槽必看のMySQL索引:B+树原理揭秘与索引优缺点分析

听GPT 讲Rust源代码--compiler(1)

KisFlow-基于Golang的流式计算框架实战(5)

用 switch-case 来解决 Go 错误处理的难题

KisFlow-基于Golang的流式计算框架实战(4)

KisFlow-基于Golang的流式计算框架实战(3)

图文讲透Golang标准库 net/http实现原理 -- 客户端

使用docker init编写Dockerfile和docker-compose配置

Go语言中常见100问题-#完结撒花

KisFlow-基于Golang的流式计算框架实战(2)

golang 高性能无 GC 的缓存库 bigcache 是怎么实现的

📒 后端相关

从0到1构建一个稳定、高性能Redis集群

这些年背过的面试题——SpringCloud篇

如何设计订单超时自动取消

📒 前端相关

2024 AI & 前端:回首展望,光芒未至,破晓之前!

看完zustand源码后,我的TypeScript水平突飞猛进

ElTable 二次封装:我用 Vue3.3 新特性完美解决了列插槽数据无类型提示问题!!!

ECharts 迎来重大更新,运行时包体积可减少 98%!

FFmpeg前端视频合成实践

2024 使用 TS 搭建 Node.js 服务器 - 快速教程

前端食堂技术周刊第 113 期:Node 年终总结、Node 新吉祥物、Qwik 2.0、React Labs 工作进展

· 6 min read
加菲猫

🌟 AI 相关

Large Language Models for Data Annotation: A Survey

ACTIVERAG: Revealing the Treasures of Knowledge via Active Learning

关于Generative-Diffusion-Model的全面综述,可以作为了解sora的基础知识

云音乐 CMS 平台 AIGC 实践与新特性实现总结

云音乐D2C设计稿转代码建设实践

云音乐 AI Agent 探索实践

云音乐低代码 + ChatGPT 实践方案与思考

🦜🕸️ LangGraph:Plan-Execute Agents 实战

Pinecone总结一:大模型角度

使用 Hugging Face 微调 Gemma 模型

开源大语言模型作为 LangChain 智能体

200万上下文窗口创飞Gemini 1.5!微软来砸谷歌场子了(doge)

如何利用大模型进行数据标注与知识蒸馏:兼看ActiveRAG上下文去噪的大模型RAG问答范式

树形结构与RAG的完美结合:T-RAG方法在组织内部信息查询中的突破

领先99%小白的Sora关键信息!

AI, Machine Learning和 Deep Learning有什么差异

模型融合、混合专家、更小的LLM,几篇论文看懂2024年LLM发展方向

开源大模型王座易主!谷歌Gemma杀入场,笔记本可跑,可商用

关于Google开源Gemma的一些想法

LangChain原理学习笔记

工具增强型大模型:引领智能新时代

AI 实战:手把手教你使用「扣子/coze」来搭建个人blog知识库

大模型推理优化实践:KV cache复用与投机采样

NLP研究在大模型时代的创新飞跃

下一代RAG范式:RAG-Fusion

图解大模型计算加速系列:Flash Attention V2,从原理到并行计算

如何在小公司做大模型

机器学习简介: 寻找函数的艺术

OpenAl 视频生成模型 —— Sora技术报告解读

⭐️ Go & 云原生 & Rust 相关

etcd存储引擎之主干框架

Rust 高性能编程指南

Go map 加有序排序的一些挣扎

云音乐 GitOps 最佳实践

KisFlow-基于Golang的流式计算框架实战(1)

相同型号物理机,容器性能不如虚拟机

听GPT 讲Rust源代码--library/portable-simd

Go deadcode:查找没意义的死代码,对于维护项目挺有用!

通俗易懂剖析Go Channel:理解并发通信的核心机制

竟然是"你"偷走了那0.001的服务可用性

精心设计的 DNS Failover 策略在 Go 中竟然带来了反效果,发生了什么

Go语言中常见100问题-#100 Not understanding the impacts of running Go

《从慢速到SIMD》聊Go 边界检查消除

Go项目中的Labels

Go 更强的代码洁癖,可以把 gofmt 给换了!

Go 终于把这个傻缺特性去掉了,多少陈年老BUG都是因为它!

Go 1.22 slices 库的更新:高效拼接、零化处理和越界插入优化

Go 1.22中值得关注的几个变化

Go中最常用的数据校验库

📒 后端相关

美团面试:说说OOM三大场景和解决方案? (绝对史上最全)

(九)深入并发编程之并发容器:阻塞队列、写时复制容器、锁分段容器原理详谈

(八)深入并发之Runnable、Callable、FutureTask及CompletableFuture原理分析

四十五图,一万五千字!一文让你走出迷雾玩转Maven!

踩了一堆坑,终于把微服务系统全面升级 JDK17 和 SpringBoot3 了

奇思妙想的SQL|兼顾性能的数据倾斜处理新姿势

如何成为一线 Leader

ForkJoinPool:大任务拆分,让并行嗨起来!

写了这么多年DateUtils,殊不知你还有这么多弯弯绕!

这些年背过的面试题——Kafka篇

📒 前端相关

🤯 [性能优化] 浏览器跨域带来的一些性能问题

🧐 [跨端开发] 如何定位 Hybrid Web 页面中 Native 注入的 JS 代码

413 - 《读书笔记:A Philosophy of Software Design》

如何在泛型组件中使用 forwardRef

译:Hot Module Replacement 原理

MDH Weekly 121 - 《开工大吉》

· 7 min read
加菲猫

alt text

封面图:牛逼了!2月编程语言榜单:Go首次进入前十

🌟 AI 相关

How to Cut RAG Costs by 80% Using Prompt Compression

RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture

RAG vs Finetuning — Which Is the Best Tool to Boost Your LLM Application

大语言模型之LlaMA系列- LlaMA 2及LLaMA2_chat(上)

RAG还是微调?微软出了一份特定领域大模型应用建设流程指南

谷歌全新大模型突然发布!100万token完爆GPT-4,仅靠提示词就能学会新语言

扩展说明: 指令微调 Llama 2

社区供稿 | 图解大模型推理优化之 KV Cache

大模型性能优化之Prompt工程全面梳理:从zero shot到chain of thought再到花式XOT

大模型RAG问答行业最佳案例及微调、推理双阶段实现模式:基于模块化(Modular)RAG自定义RAG Flow

值得一看的大模型RAG问答总括性梳理:模块化(Modular)RAG范式的定义、构成及机遇

【有腔调的RAG】01 半结构化数据上的RAG

省钱!微软开源框架LLMLingua + LlamaIndex实现提示词压缩

Ollama Python开发包实例 | 基于本地部署开源大模型的Streamlit聊天应用

【隐私优先】Llama 2 + GPT4All + Chroma实现100%本地化RAG

大模型时代还不理解自注意力?这篇文章教你从头写代码实现

陈丹琦团队新作:数据量砍95%,大模型性能更强了!Less is More

【AI 初体验】 llama2与LangChain 的 SQLDatabaseChain

⭐️ Go & 云原生 & Rust 相关

从物理机到K8S:应用系统部署方式的演进及其影响

Leetcode 算法题解精选

牛逼了!2月编程语言榜单:Go首次进入前十

Go语言中常见100问题-#99 Not understanding how the GC works

Go语言中常见100问题-#98 Not using Go diagnostics tooling

一文搞懂Go GC演进史,讲的太细致了!

Rust 中的并发模型和所有权系统

Kitex:微服务架构下的高性能优化实践

探究 Go 的高级特性之 【处理1分钟百万请求】

探究 Go 的高级特性之 【领域驱动设计中篇】

用 Go 语言实现刘谦 2024 春晚魔术,还原尼格买提汗流浃背的尴尬瞬间!

还不敢写多线程程序?看看Go如何让并发控制简单有趣

从 fatal 错误到 sync.Map:Go中 Map 的并发策略

16. Go调度器系列解读(三):GMP 模型调度时机

15. Go调度器系列解读(二):Go 程序启动都干了些什么

14. Go调度器系列解读(一):什么是 GMP

13. 入门 go 语言汇编,看懂 GMP 源码

8. 看 Go 源码,你需要了解 unsafe.Pointer

5. golang map 源码的逐句解读

一文搞懂Kubernetes 部署策略

滚动更新和回滚部署在 Kubernetes 中的工作原理

Go 项目标准布局?Go 官方出指南了

📒 后端相关

阿里终面:Netty 如何做到单机百万并发

8种专坑同事 SQL写法,性能降低100倍,不来看看

亿级推送,得物是怎么架构的

详解Redis三大集群模式,轻松实现高可用!

阿里Java面试官:CopyOnWriteArrayList底层是怎么保证线程安全的

还搞不懂ConcurrentHashMap底层源码,看这篇就够了

只需七步,教你轻松解决Redis热点Key问题

一文详解Redis中BigKey、HotKey的发现与处理

Java 十亿行数据计算,最快6秒出结果,你能吗

从Kafka中学习高性能系统如何设计 | 京东云技术团队

由浅入深的介绍扣减业务中的一些高并发构建方案(上)

如何在微服务下保证事务的一致性 | 京东云技术团队

【Redis高可用系列】主从复制原理和复制方式分析

Redis删除数据后,为什么内存占用率还是很高

感觉Redis变慢了,这些可能的原因你查了没 (上)

感觉Redis变慢了,这些可能的原因你查了没 (下)

位图(bitmap)原理以及实现

亿万用户在线,一张bitmap统计全解密

如何使用Redis数据类型进行亿级别统计数据

MySQL事务未提交redolog能持久化到磁盘吗

结合MySQL更新流程看 undolog、redolog、binlog

📒 前端相关

致所有渴望学习Rust的人的信

前端项目里都有啥

白嫖ChatGPT4.0 (第二弹)

字节跳动最热门的 15 个前端开源项目

刘谦春晚魔术揭秘:约瑟夫环的数学魅力,JS实现下!

我写了一个根据项目自动切换node版本的插件,再也不用手动使用命令切换了

· 4 min read
加菲猫

alt text

封面图:Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

🌟 AI 相关

MultiHop-RAG: Benchmarking Retrieval-Augmented Generation for Multi-Hop Queries

手把手教你,从零开始实现一个稀疏混合专家架构语言模型(MoE)

苹果为自家芯片打造开源框架MLX,实现Llama 7B并在M2 Ultra上运行

如何用LLM和自有知识库搭建智能Agent

万字详解专家混合:MoE模型

Prompt Engineering:大模型 PUA 指南!

Mixtral-8x7B 模型挖坑

精彩手绘全解:RAG技术,从入门到精通

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

白话Embedding:普通人都能懂的科普文

Mixtral 8x7B: 超越GPT-3.5与Llama 2 70B的稀疏混合专家架构新篇章

3B模型不输7B LLaVA!北大多模态MoE模型登GitHub热榜

GPT-4推理能力暴涨32%,谷歌新型思维链效果超CoT,计算成本可降至1/40

阿里大模型春节礼包来了:代码可执行率超GPT-4,1.5版本全系列开源

刚刚,谷歌弃Bard发布超大杯Gemini,全面对标GPT-4,前2个月免费!

无需RLHF显著提升GPT-4/Llama2性能,北大团队提出Aligner对齐新范式

手撕LangChain代码,新手请进

MoE 卷起来啦!又一微调版 Mixtral-8x7B 发布,试试效果怎么样

不是 GPT4 用不起,而是本地运行 Mixtral-8x7B 更有性价比

在 Mac 运行 OpenChat 3.5 大模型,AI推理APP仅2MB 完全可移植

⭐️ Go & 云原生 & Rust 相关

代码验证斯特林公式的准确性

一些笔记工具工具以及memos介绍

Go 1.22.0 可称之为一次史诗级更新

Go1.22 正式发布!包含语言变化、性能提高、标准库变动等重要特性

实现基于 Grafana Loki 的日志报警

齐活了,Grafana 发布大规模持续性能分析开源数据库 - Phlare

📒 后端相关

DDD落地:从携程订单系统重构,看DDD的巨大价值

一次由于八股文引起的内存泄漏

网易面试:请设计一个高可用性的软件架构,说明设计思路

这些年背过的面试题——MySQL篇

天天写业务代码,如何破局业务开发的本质

📒 前端相关

瀑布流优化:我把小红书的瀑布流虚拟列表撕出来了

心遇APP站内玩法H5体验优化实践

译:如何避免 SSR 渲染本地日期时的 FOUC 问题

译:危险的注水

译:React 19 计划推出的新 Hook

译:使用 Promise.withResolvers 延迟 Promise

2024 年你需要知道的 5 个 CSS 代码片段

Partial Prerendering 的 What、Why 和 How

2024 年如何启动 React 项目

MDH Weekly 120 - 《小册》

· 5 min read
加菲猫

alt text

封面图:图文吃透Golang net/http 标准库--服务端

🌟 AI 相关

Large Language Models for Mathematical Reasoning: Progresses and Challenges

A Comprehensive Survey of Compression Algorithms for Language Models

The Power of Noise: Redefining Retrieval for RAG Systems

Corrective Retrieval Augmented Generation

从零构建现代深度学习框架(TinyDL-0.01)

本地运行面壁智能的“贺岁模型”:MiniCPM 2B

「我在淘天做技术」2024年看AIGC是如何让1688主图焕发新春的

大模型推理框架RTP-LLM对LoRA的支持

LLM之LangChain(五)| 使用LangChain Agent分析非结构化数据

LLM之RAG理论(六)| 高级RAG指南和技巧

从零手搓MoE大模型,大神级教程来了

RAG进阶 多用户多文档

RAG 进阶 LlamaIndex多文档

RAG 进阶 多模态图片检索

RAG 进阶 半结构化数据

LlamIndex二 RAG应用开发

LlamaIndex 一 简单文档查询

使用 Docker 快速上手中文版 LLaMA2 开源大模型

部署必备—triton-inference-server的backend(一)——关于推理框架的一些讨论

TensorRT-LLM初探(一)运行llama,以及triton tensorrt llm backend服务化

H100推理飙升8倍!英伟达官宣开源TensorRT-LLM,支持10+模型

大语言模型推理提速:TensorRT-LLM 高性能推理实践

⭐️ Go & 云原生 & Rust 相关

Go1.22 新特性:性能提高、Trace 大修、工作区支持 vendor 等

json.Marshal为什么会对[]byte类型进行base64编码处理

Go调度器系列解读(二):Go 程序启动都干了些什么

Go语言中的Pinner.Pin

Kubernetes 调度器队列 - 设计与实现

Go语言通知协程退出(取消)的几种方式

Go语言中常见100问题-#97 Not relying on inlining

程序员才懂的乐趣:10亿行的挑战

Kubernetes 调度器 - 核心流程 (下篇)

Go调度器系列解读(一):什么是 GMP

Kubernetes 调度器 - 核心流程 (上篇)

图文讲透Golang标准库 net/http实现原理 -- 服务端

利用 ChatGPT 高效搜索Go问题:举一反三的思考方式,高效查找解决方案

Go语言中常见100问题-#96 Not knowing how to reduce allocations

从慢速到SIMG: 一个Go优化的故事

📒 后端相关

8种专坑同事的 SQL 写法,性能降低100倍,不来看看

批量执行Redis命令的四种方式!

阿里面试:设计一个大并发、大数据的系统架构,说说设计思路

码哥字节 124 篇优秀文章精选

Kafka性能篇:为何Kafka这么"快"

Redis 核心篇:唯快不破的秘密

链路追踪落地过程中的挑战与解决方案

美团面试:Sentinel底层滑动时间窗限流算法怎么实现的

字节二面:Spring Boot Redis 可重入分布式锁实现原理

纠正误区:这才是 SpringBoot Redis 分布式锁的正确实现方式

分库分表的 21 条法则,hold 住!

腾讯二面:epoll性能那么高,为什么

📒 前端相关

扩展你的前端知识库,毫无废话!

TypeScript 5.4 beta: NoInfer 类型、闭包类型分析优化、条件类型判断优化等

升级到 React 18 的经验和教训

· 7 min read
加菲猫

🌟 AI 相关

单卡3小时训练专属大模型Agent-基于LLaMA Factory实战

⭐️ Go & 云原生 & Rust 相关

#150 Go 并发模式介绍和创新创造【Go 夜读】

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

从 Context 看 Go 设计模式:接口、封装和并发控制

50 条争论的文章发生了啥:Go 标准库 encoding/json 真的慢吗

Kubernetes 控制器管理总结

使用cmux实现网络端口复用

毫巅之微---不同写法的性能差异 番外篇

2024年的Rust与Go

Go 1.22 rc2 刚刚发布,多个新特性等着大家 forloop,math/rand/v2,增强 http routing

Go 服务网络不通?net/http自带的这个工具帮你快速定位

golang pprof 监控系列(1) —— go trace 统计原理与使用

Go 定时器:Timer 和 Ticker

Go1.22 新特性:增强 http.ServerMux 路由能力,将有更强的表现力!

细节对线,让你写出更安全的 Dockerfile

Go 语言中高效切片拼接和 GO 1.22 提供的新方法

GO 中高效 int 转换 string 的方法与源码剖析

Go合集 | 上新 腾讯Go安全指南

《Go题库·16》读写锁底层是怎么实现的

《Go题库·15》go struct 能不能比较

Kubernetes GC 设计与实现

Go 夜读第 150 期 Go 并发模式介绍和创新创造

跟着老猫来搞GO-内建容器Map

这是我见过最酷的服务端日志收集方案!

Go语言中常见100问题-#95 Not understanding stack vs. heap

Go 语言实战:构建强大的延迟任务队列

为什么 Go1.22 for 循环要支持整数范围

📒 后端相关

万字详解微服务世纪难题:如何平滑拆分单体

没用过微服务?别慌,丐版架构图,让你轻松拿捏面试官

从4万行代码降到1.8万,腾讯视频竟然用DDD做架构重构

转转支付通道监控系统的搭建

微服务架构下网关的技术选型

Linux进程管理工具 Supervisor详解

SpringBoot + SpEL,轻松搞定复杂权限控制,非常优雅!

后端程序员必备:书写高质量SQL的30条建议

云音乐RPC稳定性建设与实践

临时抱佛脚必看|一个月速通高级系统架构设计师!

第一性原理:养猪还是读大学

第二遍读俞军的神作《产品方法论》,真香!

阿里面试:Sentinel熔断降级,是如何实现的

深度剖析:Redis分布式锁到底安全吗?看完这篇文章彻底懂了!

搞懂异地多活,看这篇就够了

一键部署 SpringCloud 微服务,yyds!

Redis、ZooKeeper、Etcd,谁有最好用的分布式锁

提炼设计框架,一文搞懂Redis/MySQL/Kafka为什么这样设计

腾讯一面:32 位 4GB 系统,访问 2GB 数据,虚拟内存会发生什么

1.5万字+30张图盘点索引常见的11个知识点

腾讯三面:一台服务器,最大支持的TCP连接数是多少

这些年背过的面试题——多线程篇

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

使用双异步后,如何保证数据一致性

📒 前端相关

虚实之间有一期播客讲「拼多多出海的 - TEMU 增长背后黄铮的创业哲学和中企出海之路」听下来讲得很有逻辑,聊到了全托管模式如何简化,拼多多的传统技能低价,以及如何实现的低价,包括中国企业出海的几个阶段,很通俗易懂,值得学习。

https://www.xiaoyuzhoufm.com/episode/657fc03f991e2ee608f54f98

当你想将 feature 分支上的多个 commit 合并到 release 分支,并且希望在 release 分支上只看到一个合并提交时,可以使用 git merge --squash 命令:

# 确保你在 release 分支上
$ git checkout release

# 进行 squash 合并
$ git merge feature --squash

# 在解决完所有冲突后,需要将已解决的文件添加到暂存区
$ git add .

# 提交合并结果为一个新的单个 commit(注意:这里没有自动提交,需要手动提交)
$ git commit -m "Squashed commit from feature-branch: Implemented XYZ feature"

注意,在 GitLab 提 Merge Request,可以在 Merge Request 页面中勾选 squash commit 选项

合并代码遇到冲突,想回退到合并前的状态:

$ git merge --abort

一个小技巧,which 命令可以用来查找可执行文件的路径:

$ which npm

/Users/bytedance/.nvm/versions/node/v18.16.0/bin/npm

框架中的类型编程: Hono 中的模板字符串类型编程

框架中的类型编程:tRPC & Prisma 中的泛型应用

React 19 即将推出的 4 个全新 Hooks,很实用!

我用埋点让老板安静 (埋点篇)

Rust性能很高?不,它完全顶不住我的代码

[]深度解析Webpack打包过程(2万字预警)

MDH Weekly 119 – 《周刊重启和博客》

· 5 min read
加菲猫

🌟 AI 相关

专补大模型短板的RAG有哪些新进展?这篇综述讲明白了

用检索增强生成让大模型更强大,这里有个手把手的Python实现

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

⭐️ Go & 云原生 & Rust 相关

慢聊Golang协程池Ants实现原理

Kubernetes Networking Model & CNI

for-range一个函数,还可以这么用

跟我一起编写 Buildpacks:Go 版本篇

探索Cloud Native Buildpacks的奇妙世界

哈啰云原生弹性伸缩控制器实现细节

使用 Rust 后,我写 Go 的方法都变了!

Go1.22 新特性:Slices 变更 Concat、Delete、Insert 等函数,对开发挺有帮助!

Go 简单设计和实现可扩展、高性能的泛型本地缓存

Kubernetes HPA 设计与实现

从零开始:使用Prometheus与Grafana搭建监控系统

十分钟教你在 k8s 中部署一个前后端应用

Go 夜读第 149 期:如何设计现代云原生网关: Easegress

Go Context 到底放第一个参数传,还是放结构体里

优雅判断 interface 是否为 nil

高效I/O并发处理:双缓冲和Exchanger

📒 后端相关

CPU中的高科技:流水线、超标量、SIMD

让你的代码运行更快:掌握零拷贝技术

电商库存系统的防超卖和高并发扣减方案 | 京东云技术团队

向上管理:让你主动汇报就这么难

RocketMQ 事务消息初体验

云音乐服务端可视化编排平台 TangoFlow 设计与实现

八分钟了解一致性算法 -- Raft算法

代码之外:工程师的成长进阶秘籍

复盘总结,不要错失最大财富

为了让小白也能看懂这个死锁case,我请来了小黑

阿里二面:要保证消息不丢失,又不重复,消息队列怎么选型

SpringCloud 远程调用为啥要采用HTTP,而不是RPC

业务型团队开发生存指南

DDD领域驱动工程落地实战

支付宝:多线程事务怎么回滚?说用 @Transactional 可以回去等通知了!

DDD 四层微服务架构,开箱即用!

2 万字 + 20张图| 细说 Redis 九种数据类型和应用场景

Redis 除了缓存,还支持哪些场景

Spring Boot + 规则引擎 URule,太强了!

单租户时代:SaaS范式转移

系统的可观察性是指什么

你管这破玩意儿叫高可用

如何判断业务做不做,什么是UE模型

并发编程的12条规范

性能优化2.0,新增缓存后,程序的秒开率不升反降

📒 前端相关

前端性能优化手册 - RoadMap

React 代码如何跑在小程序上

Taro编译mini-runner包的作用

穿越时空:2023年前端技术盘点与2024年技术展望

Monorepo 项目实现共享 Tailwind 配置

前端食堂技术周刊第 111 期:JS Rising Stars、2024 年如何写 CSS、两个 React、npm 年度回顾

+ + \ No newline at end of file diff --git a/2024/page/2/index.html b/2024/page/2/index.html index d2af937263..f3f6d95481 100644 --- a/2024/page/2/index.html +++ b/2024/page/2/index.html @@ -11,13 +11,13 @@ - - + +
-

· 10 min read
加菲猫

🌟 AI 相关

GPT-4 Technical Report

Today's top trending papers in Computer Science

⭐️ Go & 云原生 & Rust 相关

小红书可观测 Metrics 架构演进,如何实现数十倍性能提升

Java与Go到底差别在哪,谁要被时代抛弃

既然问题是 GC 占用的 CPU 过高,首先我们分析一下 CPU 热点,进一步确认一下问题。

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/profile

这个命令用于进行 30s 的 CPU 性能分析,在完成之后会进入 profile 的交互工具:

Alt text

这里直接输入 top 10 可以输出 flat 占比最高的 10 个函数,可以看到 runtime.mallocgc 的 cum 占比已经达到了 15%,占用了快到 3s CPU 时间。

Flat vs Cum:

  • Flat 占比是指这个函数自身的代码使用了多少 CPU,不计算子函数的耗时。
  • 而 Cum 则代表这个函数实际执行消耗了多少 CPU,也就是包括了所有的子函数(和子函数的子函数...)的耗时。

交互工具这里输入 web 就会自动生成调用图(callgraph)并在浏览器里打开 ,限于文档空间这里只展示重要的部分 :

Alt text

先分析一下主流程,这里业务逻辑一共占用了 54% 左右的 CPU(最上面的 endpoint.handler 方法),再往下看,其中 33% 是 RPC 调用(左下角的 client.Invoke),12% 是结果输出(右边的 endpoint.httpOutput,包括写出 HTTP Response,日志上报,监控)。剩下 9% 左右就是实际的各种业务逻辑了,因为非常分散且没有集中的点,所以图上没有显示出来。

纵观这个图可以看出,除了 HTTP/RPC 网络调用占用了大部分 CPU 外,并没有其他很明显的 CPU 热点,这就让最后一个热点凸显了出来:

Alt text

GC 占用的 CPU 在这次 Profiling 过程中占了 15%,比业务逻辑还高!到这里基本确认,GC 一定存在某些问题。

我们可以用另一个 pprof 工具 allocs 来确认猜测是否成立,这个工具会记录堆上的对象创建和内存分配,只需要把上面的 HTTP Path 最后的 profile 换成 allocs 即可:

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/allocs

和 CPU Profile 不一样,Allocs 的 Profile 会记录四个不同的信息,可以输入 o 查看 sample_index 的可选值:

Alt text

  • alloc_object:新建对象数量记录;
  • alloc_space:分配空间大小记录;
  • inuse_object:常驻内存对象数量记录;
  • inuse_space:常驻内存空间大小记录。

一般来说,inuse 相关的记录可以用于排查内存泄漏,OOM 等问题。这里我们是 GC 的问题,主要和内存申请和释放有关,所以先看下 alloc_space:

输入命令,sample_index=alloc_space,然后再 top 10 看下:

Alt text

可以发现,这 30s 一共申请了 1300M 的内存,其中绝大多数都是框架和框架组件,比如 RPC 的网络读取(consumeBytes, ReadFrame),pb 的解析和序列化(marshal),名字服务的选址(Select),日志输出(log),监控上报(ReportAttr)。也没有明显的可疑对象。

我们进行一些简单计算:进行 profiling 的线上节点是 2C2G 配置,看监控单节点大约是 800 QPS 的流量,所以 30s 就是 2w4 的请求,申请了 1300M 的空间,平均一个请求就是大约 50KB 左右。

这个量也比较合理,毕竟一次请求我们需要储存 HTTP 包内容,解析成结构体,还需要调用两次 RPC 接口,最后做日志写出和监控上报,最后再给出返回值,50KB 的资源使用并不算大。而且绝大多数都是框架使用,即使用对象池把业务上的一些小对象复用,对这个内存申请也影响不大。

虽然这个步骤没有排查到想查的问题,但是却发现了一些其他的代码中的小问题,这里也顺便记录下。

首先,上面的 top 10 看不出任何问题,但是为了保险起见,看了一下 top 20:

Alt text

这里有三个我们业务代码里的函数,flat 都很少,占比加起来也不到 4.5%,不过既然发现了他们 ,就深入看一下函数里各行的分配情况,看看有没有什么问题。

只改一个参数让Golang GC耗时暴降到1/30!

字节跳动云原生成本治理落地实践

Go 的 DDD 工程化项目实践

Rust 的所有权、借用和生命周期

Kubernetes Deployment 滚动更新实现原理

[go 面试] 分布式事务框架选择与实践

我是如何实现Go性能5倍提升的

完善 Golang Gin 框架的静态中间件:Gin-Static

Kubernetes 为什么需要 Ingress

Uber Go 出了个静态分析工具 NilAway,还挺实用!

Go语言中常见100问题-#93 Not taking into account instruction-level

Rust使用gRPC

这些流行的K8S工具,你都用上了吗

Go测试的20个实用建议

『每周译Go』Go 的抢占式调度(文末有彩蛋)

了解go在协程调度上的改进

Go 语言为什么不支持并发读写 map

第一篇 旧话重提:获取和利用 goroutine id, machine id 和 process id

📒 后端相关

HBase深度历险 | 京东物流技术团队

项目中遇到一个问题,需要记住弹窗频控,一般来说跟着设备走,也就是在前端缓存。如果需要以用户维度,需要怎么设计,可以用 Redis Bitmap 实现。

Redis Bitmap:实现千万级用户签到的秘密武器

这些年在阿里学到的方法论

架构面试:全链路压测,你是怎么设计的

阿里面试:如何保证RocketMQ消息有序?如何解决RocketMQ消息积压

网易面试:亿级用户,如何做微服务底层架构

美团面试:亿级数据 在线统计,如何实现

美团面试:ES+Redis+MySQL高可用,如何试实现

字节面试:DDD架构,如何落地

微服务下必须了解的4种部署策略!

自从用了这款链路追踪系统,睡觉真香!!

逆风时刻,管理动作或成噪音

这些年背过的面试题——架构设计篇

还得是腾讯,捞了我一把!

文末福利丨2023哔哩哔哩技术精选技术干货

能ping通,TCP就一定能连通吗

微服务全做错了!谷歌提出新方法,成本直接降9倍!

备考两年,关于软考的经验都在这了

我在阿里做开发的高效打工技巧总结

一文讲透消息队列RocketMQ实现消费幂等

订单场景-基于Redisson实现订单号生成

📒 前端相关

【第3162期】前端APM指标采集大冒险

2023年最火的前端项目出炉,竟然是它

你的网站或许不需要前端构建(二)

2023 年 Node.js 性能状态

【第3157期】解锁前端新潜能:如何使用 Rust 锈化前端工具链

前端食堂技术周刊第 110 期:Vue3.4、新版 Vue DevTools 开源、AI 2023 年度总结合集

- - +
Skip to main content

· 7 min read
加菲猫

🌟 AI 相关

中信建投 | AI前沿系列(一):混合专家模型技术(MoE)

《开源大模型食用指南》发布,7个小时,一杯奶茶速通大模型!

Stable Diffusion XL Turbo 文生图和图生图实践

在 Nvidia Docker 容器编译构建显存优化加速组件 xFormers

Amazing OpenAI API:把非 OpenAI 模型都按 OpenAI API 调用

节省时间:AI 模型靠谱下载方案汇总

修复 OpenCV 依赖错误的小工具:OpenCV Fixer

⭐️ Go & 云原生 & Rust 相关

Linux 6.8 网络优化, 大量并发连接的TCP性能提高40%左右

深入探索 Rust 中的 Panic 机制

探究 Go 源码中 panic & recover 有哪些坑

从《100 Go Mistakes》我总结了什么

3.深入TiDB:执行优化讲解

亲测体验Go语言模糊测试

Go 发布了一个非安全补丁的 Go 1.21.6

Go1.22 新特性:新的 math/rand/v2 库,更快更标准!

每秒百万数据点 Go 应用监控系统演进

别再用GDB了,一文掌握Go最好用的调试器Delve

Kubernetes CronJob 设计与实现

[go 面试] 实现服务高可用的策略和实践

我是如何实现Go性能5倍提升的

深入理解Go标准库-ServeMux的使用与模式匹配

深入理解Go标准库-http server的启动

使用 Grafana 和 Loki 监控传说中的武当纵云梯

Grafana 教程 - 构建你的第一个仪表盘

成本更低、更可控,云原生可观测新计费模式正式上线

Kubernetes Job 设计与实现

依赖Kafka的Go单元测试例解

Go1.22 新特性:for 循环不再共享循环变量,且支持整数范围

Go运行时的并发原语

Go语言中常见100问题-#94 Not being aware of data alignment

Go 语言中 defer 使用时有哪些陷阱

Go语言之父的反思:我们做对了什么,做错了什么

学习C++20, 为Go的atomic类型插上一双翅膀

📒 后端相关

一张图总结架构设计的40个黄金法则

这些年背过的面试题 — 架构设计篇

这些年背过的面试题——Spring篇

mysql 的 binlog、redolog、undolog 是啥:

  • Binlog(二进制日志):
    • 用于复制:在主从复制中,从数据库会重放主数据库中存储的 binlog,以实现主从同步。
    • 数据库恢复:binlog 可以用于数据库的按时间点还原。
  • Redo log(重做日志):
    • 确保事务的持久性:在事务提交前,redo log 会将事务的修改操作记录下来,以确保在系统崩溃或重启时,可以重新执行这些操作。
    • 防止脏页写入:在系统崩溃时,redo log 可以防止脏页(未提交的数据页)被写入磁盘。
  • Undo log(撤销日志):
    • 用于事务的回滚:在事务执行过程中,undo log 记录了事务修改前的数据版本,以便在事务回滚时恢复数据。
    • 多版本并发控制(MVCC):undo log 支持数据库的多版本并发控制机制,允许事务在不加锁的情况下读取一致的数据。

这些日志文件在 MySQL 中扮演着不同的角色,确保了数据库的一致性、持久性和并发控制。

使用懒加载 + 零拷贝后,程序的秒开率提升至99.99%

万字+20张图探秘Nacos注册中心核心实现原理

7000字+30张图看懂分布式追踪系统原理

拒绝用复杂度自慰:下云高可用的秘诀

公司为什么要使用OKR,目的是什么

阿里面试:说说Rocketmq推模式、拉模式

分布式事务概述与项目实战

分布式锁最终解决方案是RedLock吗?为什么

刷了四百道算法题,我在项目里用过几道呢

烂大街的缓存穿透、缓存击穿和缓存雪崩,你真的懂了

抖音提前批二面:为啥不推荐使用外键

增加索引 + 异步 + 不落地后,从 12h 优化到 15 min

📒 前端相关

有了它 Antd 样式覆盖不要太爽

一文带你从0到1做性能优化——国际化业务中台性能优化实践(上)

Bun 如何设置 npm registry,有时会用到 bunx 命令,会自动下载 npm 包,因此需要配置 npm registry:

# 在根目录建一个 `.bunfig.toml` 配置文件
$ vi $HOME/.bunfig.toml

写入如下内容:

[install]
# set default registry as a string
registry = "https://registry.npmjs.org"

参考:https://bun.sh/docs/install/registries

两个 React

2024 年前端预测

业务中后台用户体验优化方法论总结(体验篇)

分享4 个你可能感兴趣的 TikTok 前端面试题

Chrome 三方 Cookie 禁用已正式开始!

使用 Taro 开发鸿蒙原生应用 —— 快速上手,鸿蒙应用开发指南

· 10 min read
加菲猫

🌟 AI 相关

GPT-4 Technical Report

Today's top trending papers in Computer Science

⭐️ Go & 云原生 & Rust 相关

小红书可观测 Metrics 架构演进,如何实现数十倍性能提升

Java与Go到底差别在哪,谁要被时代抛弃

既然问题是 GC 占用的 CPU 过高,首先我们分析一下 CPU 热点,进一步确认一下问题。

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/profile

这个命令用于进行 30s 的 CPU 性能分析,在完成之后会进入 profile 的交互工具:

Alt text

这里直接输入 top 10 可以输出 flat 占比最高的 10 个函数,可以看到 runtime.mallocgc 的 cum 占比已经达到了 15%,占用了快到 3s CPU 时间。

Flat vs Cum:

  • Flat 占比是指这个函数自身的代码使用了多少 CPU,不计算子函数的耗时。
  • 而 Cum 则代表这个函数实际执行消耗了多少 CPU,也就是包括了所有的子函数(和子函数的子函数...)的耗时。

交互工具这里输入 web 就会自动生成调用图(callgraph)并在浏览器里打开 ,限于文档空间这里只展示重要的部分 :

Alt text

先分析一下主流程,这里业务逻辑一共占用了 54% 左右的 CPU(最上面的 endpoint.handler 方法),再往下看,其中 33% 是 RPC 调用(左下角的 client.Invoke),12% 是结果输出(右边的 endpoint.httpOutput,包括写出 HTTP Response,日志上报,监控)。剩下 9% 左右就是实际的各种业务逻辑了,因为非常分散且没有集中的点,所以图上没有显示出来。

纵观这个图可以看出,除了 HTTP/RPC 网络调用占用了大部分 CPU 外,并没有其他很明显的 CPU 热点,这就让最后一个热点凸显了出来:

Alt text

GC 占用的 CPU 在这次 Profiling 过程中占了 15%,比业务逻辑还高!到这里基本确认,GC 一定存在某些问题。

我们可以用另一个 pprof 工具 allocs 来确认猜测是否成立,这个工具会记录堆上的对象创建和内存分配,只需要把上面的 HTTP Path 最后的 profile 换成 allocs 即可:

$ go tool pprof -seconds 30 https://<测试域名>/debug/pprof/allocs

和 CPU Profile 不一样,Allocs 的 Profile 会记录四个不同的信息,可以输入 o 查看 sample_index 的可选值:

Alt text

  • alloc_object:新建对象数量记录;
  • alloc_space:分配空间大小记录;
  • inuse_object:常驻内存对象数量记录;
  • inuse_space:常驻内存空间大小记录。

一般来说,inuse 相关的记录可以用于排查内存泄漏,OOM 等问题。这里我们是 GC 的问题,主要和内存申请和释放有关,所以先看下 alloc_space:

输入命令,sample_index=alloc_space,然后再 top 10 看下:

Alt text

可以发现,这 30s 一共申请了 1300M 的内存,其中绝大多数都是框架和框架组件,比如 RPC 的网络读取(consumeBytes, ReadFrame),pb 的解析和序列化(marshal),名字服务的选址(Select),日志输出(log),监控上报(ReportAttr)。也没有明显的可疑对象。

我们进行一些简单计算:进行 profiling 的线上节点是 2C2G 配置,看监控单节点大约是 800 QPS 的流量,所以 30s 就是 2w4 的请求,申请了 1300M 的空间,平均一个请求就是大约 50KB 左右。

这个量也比较合理,毕竟一次请求我们需要储存 HTTP 包内容,解析成结构体,还需要调用两次 RPC 接口,最后做日志写出和监控上报,最后再给出返回值,50KB 的资源使用并不算大。而且绝大多数都是框架使用,即使用对象池把业务上的一些小对象复用,对这个内存申请也影响不大。

虽然这个步骤没有排查到想查的问题,但是却发现了一些其他的代码中的小问题,这里也顺便记录下。

首先,上面的 top 10 看不出任何问题,但是为了保险起见,看了一下 top 20:

Alt text

这里有三个我们业务代码里的函数,flat 都很少,占比加起来也不到 4.5%,不过既然发现了他们 ,就深入看一下函数里各行的分配情况,看看有没有什么问题。

只改一个参数让Golang GC耗时暴降到1/30!

字节跳动云原生成本治理落地实践

Go 的 DDD 工程化项目实践

Rust 的所有权、借用和生命周期

Kubernetes Deployment 滚动更新实现原理

[go 面试] 分布式事务框架选择与实践

我是如何实现Go性能5倍提升的

完善 Golang Gin 框架的静态中间件:Gin-Static

Kubernetes 为什么需要 Ingress

Uber Go 出了个静态分析工具 NilAway,还挺实用!

Go语言中常见100问题-#93 Not taking into account instruction-level

Rust使用gRPC

这些流行的K8S工具,你都用上了吗

Go测试的20个实用建议

『每周译Go』Go 的抢占式调度(文末有彩蛋)

了解go在协程调度上的改进

Go 语言为什么不支持并发读写 map

第一篇 旧话重提:获取和利用 goroutine id, machine id 和 process id

📒 后端相关

HBase深度历险 | 京东物流技术团队

项目中遇到一个问题,需要记住弹窗频控,一般来说跟着设备走,也就是在前端缓存。如果需要以用户维度,需要怎么设计,可以用 Redis Bitmap 实现。

Redis Bitmap:实现千万级用户签到的秘密武器

这些年在阿里学到的方法论

架构面试:全链路压测,你是怎么设计的

阿里面试:如何保证RocketMQ消息有序?如何解决RocketMQ消息积压

网易面试:亿级用户,如何做微服务底层架构

美团面试:亿级数据 在线统计,如何实现

美团面试:ES+Redis+MySQL高可用,如何试实现

字节面试:DDD架构,如何落地

微服务下必须了解的4种部署策略!

自从用了这款链路追踪系统,睡觉真香!!

逆风时刻,管理动作或成噪音

这些年背过的面试题——架构设计篇

还得是腾讯,捞了我一把!

文末福利丨2023哔哩哔哩技术精选技术干货

能ping通,TCP就一定能连通吗

微服务全做错了!谷歌提出新方法,成本直接降9倍!

备考两年,关于软考的经验都在这了

我在阿里做开发的高效打工技巧总结

一文讲透消息队列RocketMQ实现消费幂等

订单场景-基于Redisson实现订单号生成

📒 前端相关

【第3162期】前端APM指标采集大冒险

2023年最火的前端项目出炉,竟然是它

你的网站或许不需要前端构建(二)

2023 年 Node.js 性能状态

【第3157期】解锁前端新潜能:如何使用 Rust 锈化前端工具链

前端食堂技术周刊第 110 期:Vue3.4、新版 Vue DevTools 开源、AI 2023 年度总结合集

+ + \ No newline at end of file diff --git a/2024/rss.xml b/2024/rss.xml index 3d1c85bb67..a5ce27b894 100644 --- a/2024/rss.xml +++ b/2024/rss.xml @@ -28,6 +28,14 @@ Java Golang + + <![CDATA[3月17日内容汇总]]> + https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/frontend-weekly/2024/3月17日内容汇总 + https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/frontend-weekly/2024/3月17日内容汇总 + Sun, 17 Mar 2024 00:00:00 GMT + + 🌟 AI 相关

《南洋理工发布多模态金融交易Agent,平均利润提高36%!》。本文介绍了南洋理工大学发布的多模态金融交易Agent,通过融合大语言模型(LLMs)和多模态数据处理,提高了金融交易的效益。传统基于规则的交易系统在适应市场波动方面存在不足,而基于强化学习的系统虽然适应性更好,但在处理多模态数据和可解释性方面仍面临挑战。该文中提出的FinAgent是一种先进的多模态基础代理,能够综合分析多种形式的金融数据,提供精确的市场趋势分析和决策支持。实验证明,使用FinAgent进行金融交易可以平均提高36%的利润。论文链接:https://arxiv.org/pdf/2402.18485.pdf

《大模型推理:A100/H100 太贵,何不用 4090?》。本文介绍了大模型推理时,为什么可以考虑使用4090显卡。相比于A100和H100显卡,4090在性价比上更高,尤其在极致优化的情况下,甚至可以达到H100的2倍性能。文章指出,A100、H100和4090在算力方面的差距并不大,最大的区别在通信和内存方面。由于大模型训练使用高性能的通信,4090通信效率相对较低,因此在大模型训练中并不适用。然而,在推理(inference/serving)方面,4090在性价比上有优势,尤其是相对于H100显卡而言。文章还提到了GPU的训练性能和成本对比,以及大模型训练所需的算力和GPU数量等问题。详细内容可参考文章链接。

《精度提升!南加大等 | 提出分治Prompt策略,提升LLM分辨力》。本文介绍了一种基于分治算法的Prompt策略,旨在提高大语言模型(LLM)的分辨力。现有的提示策略在处理涉及重复子任务和含有欺骗性内容的任务时存在一定限制。为了解决这个问题,研究人员提出了一种基于分治算法的提示策略,利用分治程序来引导LLM的求解过程。该策略将任务划分为子问题并分别求解,然后合并子问题的答案。通过实验证明,这种分治策略能够提升模型在大整数乘法、幻觉检测和新闻验证等任务中的性能,相比传统提示策略具有更好的准确率和性能指标。论文地址:https://arxiv.org/pdf/2402.05359.pdf

《开源版“Devin”AI程序员炸场:自己分析股票、做报表、建模型》。这篇文章介绍了一个基于MetaGPT的开源项目Data Interpreter,该项目旨在处理数据实时变化、任务之间的复杂依赖关系、流程优化需求以及执行结果反馈的逻辑一致性等挑战。通过演示,展示了Data Interpreter在分析股票、预测葡萄酒质量、自动抠图、预测疾病进展和预测机器运行状态等方面的能力。该项目由MetaGPT团队与多所高校合作推出,提供了一种自主进行数据分析和建模的开源工具。

《【原创】一文读懂RAG的来源、发展和前沿》。本文介绍了检索增强生成(RAG)技术,该技术结合了检索和生成过程,旨在提高机器生成文本的相关性、准确性和多样性。文章详细解释了幻觉问题的存在以及解决幻觉问题的几种常见方法。RAG利用外部数据源进行信息检索,将检索到的信息作为上下文输入到生成模型中,从而帮助生成正确的响应。讨论了RAG的核心部件,如向量数据库、查询检索和重新排序。同时介绍了RAG在知识图谱和树结构方面的拓展。

《万字长文解析:大模型需要怎样的硬件算力》。这篇文章探讨了大模型在算力、存储、通信等多个方面上硬件资源的挑战和瓶颈。文章分析了以Transformer结构为核心的大模型在算力瓶颈、显存瓶颈和通信瓶颈方面的困境,以及当前所采取的硬件资源优化技术。此外,文章还提供了对大模型参数量和算力需求的量化估算,为选择合适的硬件设备和评估资源需求提供了指导。

《什么是好的大模型训练数据?》。本文基于Lilian Weng的博客,讨论了大模型如LLM在训练过程中对高质量数据的需求。认为高质量数据来源于“高质量人类”产生的标注数据,并强调了数据处理的重要性,提到了数据标注、质量控制和错误修正的重要步骤。文章还讨论了用于评估数据质量的多种方法,如Influence Functions和Noisy Cross-Validation,并提出了专注于“搭建高质量的数据标注pipeline”的企业方向。最后指出,在AI时代大量产出的数据中维护数据质量,是一个值得关注的挑战。

《读过的最白话讲清楚RAG原理的文章》。这篇文章直观地阐释了检索增强生成(RAG)的概念和工作原理,它是一种结合检索和生成的问答系统。该系统首先通过检索步骤找到与用户问题最相关的知识库内容,然后将这些内容与问题共同输入大型语言模型(例如ChatGPT)以生成答案。文章详细介绍了如何利用嵌入模型对知识库文本进行索引,以便协助语言模型进行精确的检索。此外,它还探讨了语义搜索背后的核心原则和技术细节点,如何通过嵌入找到与用户输入最匹配的知识,以及如何格式化文档以供语言模型使用,以便获得更高效的回答。

《LLM推理算法简述》。本文介绍了用于提高大型语言模型(LLM)推理性能的关键技术与策略。内容涵盖显存优化方法,如KV Cache减少显存浪费、MQA和GQA减少KV-Cache数量、Page Attention进行显存管理,以及提高推理速度的FlashAttention改进。文章还探讨了算子融合技术,比如FasterTransformer和DeepSpeed Inference的应用,以及调度优化策略如Async Serving和Dynamic Batch,最后介绍了用于处理大模型的分布式并行技术。这些优化手段能显著提高LLM推理过程中的性能与效率。

《数学推理增强!微软 | 提出数据合成框架:KPDDS,微调Mistral-7B性能超34B模型!》。微软的研究团队为提升大型语言模型(Large Language Models, LLMs)在数学推理任务的性能,提出了关键点驱动的数据合成(KPDDS)框架。KPDDS利用真实数据源中的关键点和示例对生成高质量问答对来训练语言模型。研究者基于此框架创建了KPMath数据集,进一步结合推理密集型数据形成KPMath-Plus数据集。在MATH测试集上,微调后的Mistral-7B模型达到了39.3%的零样本通过率,超越了数量更多的34B模型,证明了KPDDS的有效性与创新性。这一成果标志着LLMs在数学推理方面的性能得到显著提升。

《首个AI软件工程师上线!已通过公司面试抢程序员饭碗,华人创始团队手握10块IOI金牌》。在这篇文章中介绍了由华人创立的Cognition AI公司开发出来的首个人工智能软件工程师Devin。与现有GPT-4等模型不同,Devin能够独立完成复杂的编程任务,并已成功通过人工智能公司的面试和在自由职业平台Upwork上接单。得益于Cognition AI在长期推理和规划方面的进步,Devin在做决策和执行任务时,能回想相关上下文、随时间学习并修复错误。这标志着人工智能在理解真实世界软件工程问题方面取得了突破,为AI领域迈向更高层级的自动化及监督性工作开辟道路。

《向数字世界AGI迈进!智能体已经从头开玩「荒野大镖客 2」了》。这篇文章展示了如何使用Cradle这一通用计算机控制智能体框架进行AI的研究与应用,在无需内部API支持下控制键盘和鼠标以及与各类软件交互。文章来源于北京智源人工智能研究院、新加坡南洋理工大学和北京大学的联合研究。Cradle由六大模块组成,包括信息收集、自我反思、任务推断、技能管理、行动计划和记忆模块。这些模块让智能体能够自主进行决策和任务执行。研究团队通过将Cradle部署于《荒野大镖客 2》这一复杂的3A游戏中证明其通用性,Cradle能够自主完成游戏主线和探索开放世界。智能体的这种通用能力标志着智能体研究向通用人工智能(AGI)迈进的重要一步。

《深入浅出 LangChain 与智能 Agent:构建下一代 AI 助手》。文章深入讲解了LangChain工具箱及其如何赋能智能Agent,以构建更加智能的AI助手。LangChain利用大型语言模型如GPT-4,提供了一个开源软件框架,可助力开发者搭建基于语言模型的应用。它提供了六大类组件,如模型、提示模板、索引、文档加载器、文本分割器和向量存储,让GPT-4等模型不仅能处理语言,还能与外部API互动、管理用户上下文。文章以构建人脸技术问题排查助手为例,展示如何运用LangChain来协助问题诊断与智能交互,朝向自主、高效的智能应用发展。

《使用零一万物 200K 模型和 Dify 快速搭建模型应用》。本文详细介绍了如何使用零一万物的200K模型和Dify(LLM IDE)快速构建模型应用程序。作者首先对一个机器学习电子书进行翻译,并分享了源代码,然后引导读者如何申请和配置零一万物模型API。随后,作者说明了如何使用Dify IDE快速搭建和调试模型应用程序,以及如何使用Golang和AI模型自动化电子书的翻译过程。最后,作者总结了自动翻译程序的构建过程并展示了批量翻译内容的方法。整篇文章不仅是使用Dify的实操指南,还提供了一种效率化、自动化处理文本内容的示例,适合那些在寻找快速开发和集成大语言模型到应用中的开发者参考。

《一文看完多模态:从视觉表征到多模态大模型》。本文为读者系统梳理了图文多模态与多模态大模型领域的发展,尤其聚焦在视觉表征和视觉与文本融合方法上。文章从卷积神经网络(CNN)及其预训练方法开始讲起,从图像处理的视角介绍了多模态融合的初期方法,如LXMERT、VL-BERT和UNITER等。进一步,文章论述了Vision Transformer(ViT)及其预训练方案如MAE和BEIT,以及基于ViT的多模态对齐与预训练技术,如CLIP和VILT等。作者通过丰富的示例和对比,使读者能够理解这些模型在结构和功能上的不同与联系,为进一步研究提供了宝贵的资源和视角。

《浙大&中科院让Agent学会自我进化,玩德州扑克心机尽显》。Wenqi Zhang等研究者介绍了名为Agent-Pro的AI智能体,它使用大模型(GPT-4)为基础,配合自我优化的策略,能够运用虚张声势、主动放弃等复杂策略玩转德州扑克和21点等非完美信息博弈游戏。Agent-Pro的设计使其能够自我进化,适应复杂和动态的游戏环境,并通过策略层面的反思和世界模型的优化来提高自己的表现。该研究展示了AI在博弈领域的进步,同时为解决多agent现实世界问题提供了新策略。

《面向工业级推荐!“小”LLM也能做好推荐系统》。本文由蚂蚁集团AI创新研发部门NextEvo撰写,介绍了他们的论文《Can Small Language Models be Good Reasoners for Sequential Recommendation?》获得WWW 2024 (Oral)录用。文章针对大语言模型(LLM)在推荐系统应用时代价高昂的问题,提出了一种名为SLIM的基于蒸馏的大模型推荐框架。SLIM通过知识蒸馏技术,将大模型的知识和推理能力迁移到较小的模型上,从而达到用更少参数实现高效推荐的效果。论文强调SLIM在处理长尾物品和新用户推荐的优势,改进了传统基于交互数据的推荐系统偏差问题,并在保持推荐准确度和可解释性的同时降低资源消耗。

《AIOps 智能运维:有没有比专家经验更优雅的错/慢调用分析工具?》。本文介绍了阿里云应用实时监控服务 ARMS 最新推出的错/慢 Trace 分析功能。此功能不依赖专家经验,能对比分析错/慢 Trace 和正常 Trace 的每个维度,从而快速定位问题根源。针对生产环境下调用时延和错误调用的多种因素(如流量不均、单机故障等),ARMS 通过对错/慢 Trace 和正常 Trace 的对比,帮助用户发现异常的共同特征,从而定位到具体问题。这个工具提供了一种优于传统专家经验的快速、有效诊断系统问题的方法,并且附有最佳实践案例。文章最后提供了免登录的 demo 体验链接,引导用户了解和使用该功能。

《CUDA编程优化方法——Memory coalescing》。这篇文章对CUDA编程中的内存合并技术—— Memory coalescing进行了详细介绍。文章首先解释了全局内存的特点以及为何访问速度慢,并阐述了Memory coalescing的目的是通过合并内存访问操作来有效地利用带宽。通过对多维数组的存储方式及访问模式的解析,文章进一步讲解了Memory coalescing的具体实现细节,如何在多维数组访问和矩阵乘法中实现内存访问的合并。最后,文章提供了优化策略,以改进计算的内存访问模式,并提高CUDA内存传输的效率。

《扩散模型如何构建新一代决策智能体?超越自回归,同时生成长序列规划轨迹》。本篇文章介绍了扩散模型在强化学习中的多种应用场景,探讨了如何超越传统的自回归方法,同时生成长序列规划轨迹来模仿人类的决策过程。上海交通大学的团队所作的综述梳理了扩散模型在强化学习中的运用如轨迹规划、策略表征、数据合成,及其解决长序列规划误差累积、策略表达能力受限和数据稀缺等问题的巨大潜力。最终,文章对扩散模型未来的发展方向进行了展望,提出了生成式仿真环境、加入安全约束、检索增强生成及组合多种技能等多个研究方向。

《动手做一个最小RAG——TinyRAG》。本文由不要葱姜蒜指导读者如何一步步实现基于检索增强生成技术(RAG)的简化模型——TinyRAG。TinyRAG仅包含RAG核心功能,即Retrieval(检索)和Generation(生成)两个模块。文章详细介绍了RAG的基本结构,包括向量化模块、文档加载与切分模块、数据库和检索模块,以及如何根据检索内容生成回答。此外,还提供了对应的开源项目代码,助力理解语言模型与RAG的原理,并能够在实践中加以应用和拓展。

《聊一聊Transformer中的FFN》。这篇文章探讨了为什么Transformer的前馈神经网络(FFN)部分长期以来几乎没有大的改动。文章通过比较不同的激活函数,如ReLU、GeLU和Swish等,分析它们在Transformer中的应用效果和局限性。同时探讨了线性投影的必要性、参数量及其对模型容量和记忆力的影响。此外,文章还涉及了混合专家模型(Mixture-of-Experts,MoE)以提升Transformer的效率,并讨论了构建通用人工智能(AGI)所需要的结构特性,特别是放缩定律(Scaling Law)、上下文学习(In-Context Learning)、效率提升(Better Efficiency)和终生学习(Life-long learning)的重要性,最后对未来结构创新给出透彻见解。

⭐️ Go & 云原生 & Rust 相关

《More powerful Go execution traces》。Go的runtime/trace包提供了用于理解和排查Go程序的强大工具,允许对goroutine的执行进行跟踪。新版本Go大幅度降低了执行跟踪的运行时开销,从多数应用中的10-20% CPU下降到1-2%。文章介绍了如何通过将trace分割,从而使得trace可以扩展且保持低开销,还实现了飞行记录功能,使得即使在事件发生后也能从trace中获取信息。Go也提供了一个实验性的trace读取API,使程序性的跟踪分析成为可能。

《Rust: 实现比特币的交易模型》。本文详细介绍了比特币的交易模型中的UTXO(未花费交易输出)模型,并使用 Rust 语言来实现和展示其运作过程。UTXO 模型与传统的账户余额模型不同,将用户的余额分散存储在多个UTXO中。每个UTXO代表比特币网络上一笔可用于未来交易的输出。文章解释了UTXO模型的工作原理、优势以及交易处理流程,包括选择输入、生成输出、签名交易和广播交易。接着,文章提供了一个 Rust 实现的简化示例,展示了如何定义交易结构体、输入、输出以及UTXO集合,并介绍了基本的操作方法。如果你对比特币交易模型和 Rust 编程感兴趣,可以阅读该文章了解更多细节。

《深入理解 Go Modules: 高效管理你的 Golang 项目依赖》。本文详细介绍了 Go Modules 在 Golang 项目中的使用方法和原理。文章首先回顾了 Go 依赖管理的历史,从 GOPATH、Go Vendor 到 Go Module 的演进过程。然后讲解了模块、包和版本的概念,包括模块路径、包路径以及版本的格式和语义。接着,文章介绍了 Go Modules 的环境配置,包括 go env 环境变量和依赖管理文件(go.mod 和 go.sum)的作用和使用方法。最后,文章提供了一些实用技巧和常见问题的解答,帮助读者更好地理解和应用 Go Modules。如果你对 Golang 项目的依赖管理感兴趣,可以阅读该文章了解更多详情。

《Kubernetes集群节点处于Not Ready问题排查》。当Kubernetes集群中的节点显示为"Not Ready"状态时,这篇文章提供了一系列的排查步骤。首先,通过运行特定的kubectl命令来确认节点的状态并获取节点详细信息,检查可能的错误消息或者警告。接着,进入节点系统查看各种系统日志,并使用相关命令如grep、cat或tail来辅助分析。文章还建议检查kubelet服务状态和配置文件,确认系统资源是否充足,试图解决可能存在的磁盘空间和网络问题。最后,通过使用诸如ping、traceroute等诊断工具确保节点能够与主节点通信,并检查重要的网络端口是否开放。确保Kubelet能正确连接到Kubernetes API,并使用Kubernetes的诊断工具如kubectl get componentstatus检查组件状态。通过这些步骤,可以系统地排查并解决"Not Ready"的问题,保持集群健康。

《Go 错误处理: 用 select-case 来解决这个历史难题?》。煎鱼在这篇文章中介绍了一个新的Go语言错误处理提案,这个提案尝试用select-case结构作为错误检查的替代。这个新语法允许在select关键字之后声明一个变量为“陷阱”,赋值给该变量时触发case检查,以减少传统的if err != nil检查的繁琐性。新提案保持了Go1代码的兼容性,尝试提供一个更简洁、向后兼容的错误处理方式,尽管目前社区内对此仍未达成共识。

《K8s蓝绿部署:优雅应对应用程序更新挑战》。本文详细探讨了使用Kubernetes(K8s)进行蓝绿部署的方法,以达到无缝更新应用程序并最小化宕机时间。蓝绿部署是一个运行两个相同生产环境的模式,能够在更新时切换流量,确认无误后便去除旧环境。文章指导了从创建命名空间、创建和应用部署、服务及其路由规则、执行蓝绿切换,到最后的验证和回滚过程。这一过程不仅优化了应用版本的滚动更新,也为开发者提供了快速回滚的方案,以应对可能出现的问题。

《Go 中的高速数据包处理:从 net.Dial 到 AF_XDP》。文章介绍了使用 Go 语言进行高速数据包处理的多种方法,包括 net.Dial、原始套接字、系统调用、pcap 和 AF_PACKET,直至最新的 AF_XDP 方式。作者详细对比了每种方法的性能,从简单的 net.Dial 模式演进到 AF_XDP,逐步提高数据包每秒处理数量,同时指出各方法的使用场合和限制。通过基准测试,发现使用 AF_XDP 可实现最高性能,处理速度是使用 net.Dial 方法的4倍多。这些技术探讨对于需要大量网络数据包处理的场景,如网络监控、性能评估等都是非常重要的。

《数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)》。文章探讨了在云原生时代下,有状态服务(如生产环境的数据库)是否适用于容器化并由Kubernetes进行管理的问题。以B站Elasticsearch和Clickhouse的容器化和Kubernetes编排实践为例,文章详细介绍了在容器环境中部署这些有状态服务的挑战和解决方案,包括控制器的选择、持久化存储、磁盘调度、调度器、容器网络、服务发现以及如何保证集群和数据的高可用性。作者分享了通过Operator管理有状态服务应用、使用本地盘PV提升性能、LVM技术的动态扩缩容方案以及通过macvlan进行容器间高效通信的技术细节。

《一文带您探索 Kubernetes 中的容器类型》。文章介绍了在 Kubernetes 系统中常见的四种容器类型:初始化容器(Init Container)、边车容器(Sidecar Container)、临时容器(Ephemeral Container)和多容器(Multi Container)。初始化容器用于运行 Pod 中主容器启动前的准备工作,而边车容器则与主应用容器并行运行,为其提供支持服务。临时容器主要用于故障排除,而多容器 Pods 允许并行运行多个容器,共享资源和数据。文章提供了每种容器的详细使用案例、配置方法和命令,并强调了各自的特点与应用场景。

《4 秒处理 10 亿行数据! Go 语言的 9 大代码方案,一个比一个快》。软件工程师Ben Hoyt挑战使用Go语言处理10亿行数据,并提出了9种解决方案,其中最快在4秒内完成。这些方案只使用Go标准库,包括简单但优化的map处理、并行化处理等。Ben的方案虽未最快,但展现了独立思考的价值。他的测试表明,彻底地数据处理和算法优化可显著提高性能,减少计算成本。

《Go arena 民间库来了,可以手动管理内存!》。文中作者煎鱼介绍了Go语言的一个新的第三方库ortuman/nuke,这个库允许开发者手动管理内存。文章首先回顾了Go官方对于arena手动内存管理提案的停滞现状,然后重点介绍了如何使用ortuman/nuke库进行内存管理,包括库的安装、使用案例以及如何在并发场景下保持线程安全。文章详细讲解了arena内存管理的优点,例如高效率和一次性释放,并对库的实际用法,如通过context在HTTP请求周期中管理内存,进行了展示。最后,基于性能考虑,文章还提供了并发与非并发业务场景下的基准测试结果以及性能差异。

Go 语言中如何大小端字节序?int 转 byte 是如何进行的

Go 中如何实现三元运算符?Rust 和 Python 是怎么做的

Go语言中 enum 实现方式有哪些?一定要绝对类型安全吗

Go 中如何打印结构体? 代码调试效率提升

《快看! Go 1.22 对for循环进行了两个大更新》。文章讨论了Go语言在 1.22 版本中针对for循环作出的两项主要更新:1. 每次迭代的for循环都将定义一个新的变量,不再共用同一个变量;2. 引入了对整数范围的循环迭代支持。这些更新解决了闭包在并发执行时共享变量带来的问题,同时也简化了循环结构,提高了编写对整数范围进行迭代代码的方便性。文中提供了详细的代码示例来展示新旧版本之间的差异,并说明了如何利用新特性来编写更高效的Go代码。

《从慢速到SIMD》聊Go边界检查消除》。本文讨论了Go语言中边界检查消除(BCE)的相关技巧和最佳实践。文章首先回答了为何在Go代码中优化时选择使用a[i:i+4:i+4]而不是a[i:i+4]的问题,指出前者能减少编译器工作量从而提高性能。然后,介绍了Go101提出的BCE技术详解与应用实例,以及如何使用编译命令来检测边界检查的存在。文中还全面梳理了Go BCE技术的发展历程,以及在不同场景下消除冗余边界检查的方法,包括利用循环变量、常量索引等策略来提高代码执行效率。最后,提供了多种编程技巧以及相关讨论和参考资料,针对遇到的编程问题提出解决方案。

📒 后端相关

《分库分表已成为过去式,使用分布式数据库才是未来》。本文讨论了随着Mysql数据库性能下降,分库分表的局限性及其所引发的问题,如性能、事务、数据迁移等,并提出使用分布式数据库作为解决方案。文章详细介绍了TiDB这款分布式数据库的架构、特性和优势,包括其金融级的高可用性、水平扩容能力、兼容性以及云原生设计。文章强调TiDB在处理大规模数据时的效率和可维护性,终结分库分表的做法,并通过性能测试展示了TiDB与MySQL在不同场景下的性能表现。最终总结,对于数据量大的应用场景,采用TiDB来适应未来数据存储的需求是一个更优的策略。

《手把手带你精简代码-京东零售后端实践》。本文分享了京东零售后端在面临代码库日渐庞大和腐化的问题时,采用的代码精简方法。文章分为背景介绍、代码精简步骤和实施方法三部分,着重介绍了使用IntelliJ IDEA自带工具和PMD插件进行静态代码检查的步骤、配置和优缺点,以及如何借助京东jacoco流水线进行动态代码检查。本文旨在降低代码维护成本、提升可理解性,并详细阐述了代码精简的实践过程和预期结果。

《跟着iLogtail学习无锁化编程》。文章探讨了在多线程情况下,如何通过无锁化编程优化软件性能。详细讲述了iLogtail在实现无锁高效日志采集时采取的策略,比如自旋锁的使用、原子操作、内存顺序、内存屏障等概念。还分析了不同类型的锁的适用场景与特点,包括互斥锁、递归互斥锁和读写锁等。此外,文章还描述了如何将大的锁细分为多个小锁,通过降低锁粒度提升并发性能,以及在iLogtail中如何通过双Buffer机制来读写分离,减少锁的争用。最终,通过无锁化编程提高了iLogtail的日志采集性能,实现了低资源消耗和高性能。

《MYSQL 是如何保证binlog 和redo log同时提交的?》。文章讨论了如何确保在MYSQL中binlog(备份和主从同步用的日志)与redo log(InnoDB引擎层的日志,用于崩溃恢复)同步提交,以及为什么这一点对于防止主从数据不一致至关重要。文中解释了事务处理中的两个关键参数:innodb_flush_log_at_trx_commitsync_binlog,这两个值设置为1时可以确保两种日志的同步提交。该文还介绍了MYSQL的两阶段提交机制如何工作,并提出了业务开发中两阶段提交逻辑的思考,指出在有依赖关系的服务操作中,通过预锁定资源、请求成功后递减资源来保持数据的最终一致性。

《这些年背过的面试题——分布式篇》。本文从分布式系统的基础概念、发展历程及核心问题出发,详细介绍了分布式系统设计中的关键技术点。文章涵盖了负载均衡、服务的拆分与集群、分布式事务、数据一致性问题以及分区容错性等话题,并探讨了CAP理论与BASE理论在实际应用中的权衡。同时,文中还详细解读了常见的一致性算法如2PC、3PC、Paxos、Raft的机制和用例。此外,作者针对如何实现分布式Session、如何确保分布式事务的一致性等常见面试题目提供了详尽的解答,适合做为面试备考资料。

《RocketMQ为什么这么快?我从源码中扒出了10大原因!》。这篇文章详细分析了RocketMQ高性能的10个关键因素:批量发送消息降低通信次数,消息压缩减少带宽和存储压力,基于Netty的高效网络通信模型,零拷贝技术优化磁盘读写性能,顺序写提高数据写入速度,高效数据存储结构,异步机制包括异步刷盘和异步主从复制提升存储效率,批量处理减少网络通信次数和资源消耗,锁优化以及线程池隔离提升并发处理能力。作者通过深入分析源码给出了RocketMQ快速处理和拉取消息的内在原因,并深入讨论了每种技术的优势和实现。

《领导叫我接手一个新业务系统,我是这样熟悉项目的!》。本文作者小许分享了接手新业务系统的熟悉流程和实践方法。包括与产品经理交流了解业务现状,绘制用例图、ER图以明确业务与数据模型,梳理后端模型和核心流程,并运用状态机流转图和时序图深度解析复杂逻辑。最后,还提到了绘制类图以理解代码结构。文章提供了一套系统性的工具和方法,目的是帮助新成员或负责新项目的开发人员快速掌握业务逻辑,有效推进项目进度。

📒 前端相关

《Tango 低代码引擎沙箱实现解析》。本文介绍了Tango低代码引擎的沙箱实现。Tango是一个用于快速构建低代码平台的低代码设计器框架,通过对源代码进行执行和渲染前端视图,实现了低代码可视化搭建能力。借助Tango构建的低代码工具或平台可以实现源码进出的效果,并与企业内部现有的研发体系进行无缝集成。Tango的设计器引擎部分已经开源,并提供了相应的开源代码库、文档和社区讨论组。欢迎加入社区参与到Tango低代码引擎的开源建设中。更多相关文章可以在文中提供的链接中找到。

《未来只需要 2% 的程序员?》。DHH在这篇文章中提出一个激进的观点,预测未来程序员的需求可能会大幅度减少。他比较了农业从97%的人口需求降至2%的变迁,暗示软件开发也可能面临着类似缩减。尽管这个行业曾经经历招聘热潮,但现在许多程序员面临职业前景不稳定。文章讨论了人工智能的发展给程序员职业带来的压力,同时也指出职业变革的不确定性。DHH认为,未来大多数程序员可能无需手动编程,但同时指出科技行业将更加融合进社会,并提高了它的价值。他鼓励程序员接受这一变化,并享受行业的黄金时代。

《前端智能化,扣子(coze.cn)能做什么?》。这篇文章探讨了扣子(coze.cn)平台如何通过提供一个简单的交互式界面来创建聊天机器人(Chatbot)。用户通过与扣子的对话,可以快速设置一个Chatbot,如自动化微信订阅号内容发布等。文章强调了平台的易用性和界面友好性,同时指出了一些潜在缺点,包括无法解决深度问题和偶尔遇到的技术故障。另外,通过知识库和数据库的集成,可进一步提升Bot的功能。作者对扣子的机器人创建过程、优势、建议和改进进行了详细介绍,并通过实操案例展示了前端智能化机器人的搭建过程。

]]>
+
<![CDATA[3月10日内容汇总]]> https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/frontend-weekly/2024/3月10日内容汇总 diff --git a/2024/tags/golang/index.html b/2024/tags/golang/index.html index 4c750b424d..0d96895182 100644 --- a/2024/tags/golang/index.html +++ b/2024/tags/golang/index.html @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git a/2024/tags/index.html b/2024/tags/index.html index 08f1623039..a11d44fca3 100644 --- a/2024/tags/index.html +++ b/2024/tags/index.html @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git a/2024/tags/java/index.html b/2024/tags/java/index.html index ba8ac1da3b..0eff0b69be 100644 --- a/2024/tags/java/index.html +++ b/2024/tags/java/index.html @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git a/2024/tags/type-script/index.html b/2024/tags/type-script/index.html index 9f56f4fb2a..6be647fcca 100644 --- a/2024/tags/type-script/index.html +++ b/2024/tags/type-script/index.html @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git a/2024/tags/webpack/index.html b/2024/tags/webpack/index.html index 64ad7017ec..eaea921400 100644 --- a/2024/tags/webpack/index.html +++ b/2024/tags/webpack/index.html @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\344\270\232\345\212\241\346\210\220\351\225\277/index.html" "b/2024/tags/\344\270\232\345\212\241\346\210\220\351\225\277/index.html" index 32b106352a..be1d4d7967 100644 --- "a/2024/tags/\344\270\232\345\212\241\346\210\220\351\225\277/index.html" +++ "b/2024/tags/\344\270\232\345\212\241\346\210\220\351\225\277/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\345\211\215\347\253\257\346\241\206\346\236\266/index.html" "b/2024/tags/\345\211\215\347\253\257\346\241\206\346\236\266/index.html" index 118a6a3059..fc78837662 100644 --- "a/2024/tags/\345\211\215\347\253\257\346\241\206\346\236\266/index.html" +++ "b/2024/tags/\345\211\215\347\253\257\346\241\206\346\236\266/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\346\200\247\350\203\275\344\274\230\345\214\226/index.html" "b/2024/tags/\346\200\247\350\203\275\344\274\230\345\214\226/index.html" index 0c03d4ab4d..2aeea896d0 100644 --- "a/2024/tags/\346\200\247\350\203\275\344\274\230\345\214\226/index.html" +++ "b/2024/tags/\346\200\247\350\203\275\344\274\230\345\214\226/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\346\234\272\345\231\250\345\255\246\344\271\240/index.html" "b/2024/tags/\346\234\272\345\231\250\345\255\246\344\271\240/index.html" index c2f818a862..1667fafa72 100644 --- "a/2024/tags/\346\234\272\345\231\250\345\255\246\344\271\240/index.html" +++ "b/2024/tags/\346\234\272\345\231\250\345\255\246\344\271\240/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\346\272\220\347\240\201\347\263\273\345\210\227/index.html" "b/2024/tags/\346\272\220\347\240\201\347\263\273\345\210\227/index.html" index e7dab8e1fa..7014f77da5 100644 --- "a/2024/tags/\346\272\220\347\240\201\347\263\273\345\210\227/index.html" +++ "b/2024/tags/\346\272\220\347\240\201\347\263\273\345\210\227/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\347\273\204\344\273\266\345\272\223\345\256\236\346\210\230/index.html" "b/2024/tags/\347\273\204\344\273\266\345\272\223\345\256\236\346\210\230/index.html" index ff1474c721..5010a13e92 100644 --- "a/2024/tags/\347\273\204\344\273\266\345\272\223\345\256\236\346\210\230/index.html" +++ "b/2024/tags/\347\273\204\344\273\266\345\272\223\345\256\236\346\210\230/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git "a/2024/tags/\347\275\221\347\273\234\347\233\270\345\205\263/index.html" "b/2024/tags/\347\275\221\347\273\234\347\233\270\345\205\263/index.html" index 8522c5b2f6..4efbc69626 100644 --- "a/2024/tags/\347\275\221\347\273\234\347\233\270\345\205\263/index.html" +++ "b/2024/tags/\347\275\221\347\273\234\347\233\270\345\205\263/index.html" @@ -11,13 +11,13 @@ - - + + - - + + + \ No newline at end of file diff --git a/2024/welcome/index.html b/2024/welcome/index.html index 2988763b15..262d5acced 100644 --- a/2024/welcome/index.html +++ b/2024/welcome/index.html @@ -11,14 +11,14 @@ - - + +
-

置顶内容

· 145 min read
加菲猫

⭐️ 每周更新优质技术文章,欢迎点赞关注!

TypeScript 工程化方案

TS 高级技巧

TS && 框架

前端框架

编程范式

技术方案

业务成长 && 软技能

Git 相关

源码系列

Webpack 系列

Vite 系列

PNPM && Monorepo

Rollup 系列

微前端 && 模块联邦

VS Code 插件

前端工程化

软件架构 && 设计模式

持续集成

服务端相关

前端性能优化

前端组件库实战

Node.js 系列

前端编译

网络相关

操作系统

机器学习

LLM 技术调研

Java 相关

MySQL 学习

Golang 学习

Rust 学习

网站推荐

文档相关

开源推荐

在线 Plyaground

编程风格指南

技术社区

工具相关

学习资源

面试相关

📒 掘金大佬汇总

📒 待学习内容

📒 小目标

📒 推荐阅读

- - +

置顶内容

· 145 min read
加菲猫

⭐️ 每周更新优质技术文章,欢迎点赞关注!

TypeScript 工程化方案

TS 高级技巧

TS && 框架

前端框架

编程范式

技术方案

业务成长 && 软技能

Git 相关

源码系列

Webpack 系列

Vite 系列

PNPM && Monorepo

Rollup 系列

微前端 && 模块联邦

VS Code 插件

前端工程化

软件架构 && 设计模式

持续集成

服务端相关

前端性能优化

前端组件库实战

Node.js 系列

前端编译

网络相关

操作系统

机器学习

LLM 技术调研

Java 相关

MySQL 学习

Golang 学习

Rust 学习

网站推荐

文档相关

开源推荐

在线 Plyaground

编程风格指南

技术社区

工具相关

学习资源

面试相关

📒 掘金大佬汇总

📒 待学习内容

📒 小目标

📒 推荐阅读

+ + \ No newline at end of file diff --git a/404.html b/404.html index 2e42090190..d1bd0ade57 100644 --- a/404.html +++ b/404.html @@ -11,13 +11,13 @@ - - + +

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/assets/js/212c4d36.8ee62fb4.js b/assets/js/212c4d36.d41a866e.js similarity index 99% rename from assets/js/212c4d36.8ee62fb4.js rename to assets/js/212c4d36.d41a866e.js index 29705da8ba..f0c8f576be 100644 --- a/assets/js/212c4d36.8ee62fb4.js +++ b/assets/js/212c4d36.d41a866e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[5439],{49613:(e,t,a)=>{a.d(t,{Zo:()=>k,kt:()=>u});var i=a(59496);function p(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function l(e){for(var t=1;t=0||(p[a]=e[a]);return p}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(p[a]=e[a])}return p}var m=i.createContext({}),s=function(e){var t=i.useContext(m),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},k=function(e){var t=s(e.components);return i.createElement(m.Provider,{value:t},e.children)},h="mdxType",o={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},N=i.forwardRef((function(e,t){var a=e.components,p=e.mdxType,n=e.originalType,m=e.parentName,k=r(e,["components","mdxType","originalType","parentName"]),h=s(a),N=p,u=h["".concat(m,".").concat(N)]||h[N]||o[N]||n;return a?i.createElement(u,l(l({ref:t},k),{},{components:a})):i.createElement(u,l({ref:t},k))}));function u(e,t){var a=arguments,p=t&&t.mdxType;if("string"==typeof e||p){var n=a.length,l=new Array(n);l[0]=N;var r={};for(var m in t)hasOwnProperty.call(t,m)&&(r[m]=t[m]);r.originalType=e,r[h]="string"==typeof e?e:p,l[1]=r;for(var s=2;s{a.r(t),a.d(t,{assets:()=>A,contentTitle:()=>y,default:()=>T,frontMatter:()=>v,metadata:()=>S,toc:()=>R});var i=a(64778),p=a(59496),n=a(49613),l=a(45924),r=a(28238),m=a(83442),s=a(37795),k=a(77619),h=a(74242);function o(e){return function(e){return p.Children.map(e,(e=>{if((0,p.isValidElement)(e)&&"value"in e.props)return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))}(e).map((e=>{let{props:{value:t,label:a,attributes:i,default:p}}=e;return{value:t,label:a,attributes:i,default:p}}))}function N(e){const{values:t,children:a}=e;return(0,p.useMemo)((()=>{const e=t??o(a);return function(e){const t=(0,k.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function u(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function c(e){let{queryString:t=!1,groupId:a}=e;const i=(0,m.k6)(),n=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,s._X)(n),(0,p.useCallback)((e=>{if(!n)return;const t=new URLSearchParams(i.location.search);t.set(n,e),i.replace({...i.location,search:t.toString()})}),[n,i])]}function f(e){const{defaultValue:t,queryString:a=!1,groupId:i}=e,n=N(e),[l,r]=(0,p.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!u({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const i=a.find((e=>e.default))??a[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:t,tabValues:n}))),[m,s]=c({queryString:a,groupId:i}),[k,o]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[i,n]=(0,h.Nk)(a);return[i,(0,p.useCallback)((e=>{a&&n.set(e)}),[a,n])]}({groupId:i}),f=(()=>{const e=m??k;return u({value:e,tabValues:n})?e:null})();(0,p.useLayoutEffect)((()=>{f&&r(f)}),[f]);return{selectedValue:l,selectValue:(0,p.useCallback)((e=>{if(!u({value:e,tabValues:n}))throw new Error(`Can't select invalid tab value=${e}`);r(e),s(e),o(e)}),[s,o,n]),tabValues:n}}var q=a(72400);const w={tabList:"tabList_oPPN",tabItem:"tabItem_VDVc"};function j(e){let{className:t,block:a,selectedValue:n,selectValue:m,tabValues:s}=e;const k=[],{blockElementScrollPositionUntilNextRender:h}=(0,r.o5)(),o=e=>{const t=e.currentTarget,a=k.indexOf(t),i=s[a].value;i!==n&&(h(t),m(i))},N=e=>{let t=null;switch(e.key){case"Enter":o(e);break;case"ArrowRight":{const a=k.indexOf(e.currentTarget)+1;t=k[a]??k[0];break}case"ArrowLeft":{const a=k.indexOf(e.currentTarget)-1;t=k[a]??k[k.length-1];break}}t?.focus()};return p.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":a},t)},s.map((e=>{let{value:t,label:a,attributes:r}=e;return p.createElement("li",(0,i.Z)({role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,key:t,ref:e=>k.push(e),onKeyDown:N,onClick:o},r,{className:(0,l.Z)("tabs__item",w.tabItem,r?.className,{"tabs__item--active":n===t})}),a??t)})))}function g(e){let{lazy:t,children:a,selectedValue:i}=e;if(a=Array.isArray(a)?a:[a],t){const e=a.find((e=>e.props.value===i));return e?(0,p.cloneElement)(e,{className:"margin-top--md"}):null}return p.createElement("div",{className:"margin-top--md"},a.map(((e,t)=>(0,p.cloneElement)(e,{key:t,hidden:e.props.value!==i}))))}function x(e){const t=f(e);return p.createElement("div",{className:(0,l.Z)("tabs-container",w.tabList)},p.createElement(j,(0,i.Z)({},e,t)),p.createElement(g,(0,i.Z)({},e,t)))}function d(e){const t=(0,q.Z)();return p.createElement(x,(0,i.Z)({key:String(t)},e))}const b={tabItem:"tabItem_xe4B"};function G(e){let{children:t,hidden:a,className:i}=e;return p.createElement("div",{role:"tabpanel",className:(0,l.Z)(b.tabItem,i),hidden:a},t)}const v={slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},y=void 0,S={permalink:"/frontend-weekly/2024/welcome",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-12-12-welcome/index.md",source:"@site/blogs/2024/2024-12-12-welcome/index.md",title:"\u7f6e\u9876\u5185\u5bb9",description:"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01",date:"2024-12-12T00:00:00.000Z",formattedDate:"December 12, 2024",tags:[{label:"TypeScript",permalink:"/frontend-weekly/2024/tags/type-script"},{label:"\u524d\u7aef\u6846\u67b6",permalink:"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6"},{label:"Webpack",permalink:"/frontend-weekly/2024/tags/webpack"},{label:"\u6e90\u7801\u7cfb\u5217",permalink:"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217"},{label:"\u4e1a\u52a1\u6210\u957f",permalink:"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f"},{label:"\u6027\u80fd\u4f18\u5316",permalink:"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316"},{label:"\u7ec4\u4ef6\u5e93\u5b9e\u6218",permalink:"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218"},{label:"\u7f51\u7edc\u76f8\u5173",permalink:"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173"},{label:"\u673a\u5668\u5b66\u4e60",permalink:"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60"},{label:"Java",permalink:"/frontend-weekly/2024/tags/java"},{label:"Golang",permalink:"/frontend-weekly/2024/tags/golang"}],readingTime:144.44,hasTruncateMarker:!0,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},nextItem:{title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"}},A={authorsImageUrls:[void 0]},R=[{value:"TypeScript \u5de5\u7a0b\u5316\u65b9\u6848",id:"typescript-\u5de5\u7a0b\u5316\u65b9\u6848",level:2},{value:"TS \u9ad8\u7ea7\u6280\u5de7",id:"ts-\u9ad8\u7ea7\u6280\u5de7",level:2},{value:"TS && \u6846\u67b6",id:"ts--\u6846\u67b6",level:2},{value:"\u524d\u7aef\u6846\u67b6",id:"\u524d\u7aef\u6846\u67b6",level:2},{value:"\u7f16\u7a0b\u8303\u5f0f",id:"\u7f16\u7a0b\u8303\u5f0f",level:2},{value:"\u6280\u672f\u65b9\u6848",id:"\u6280\u672f\u65b9\u6848",level:2},{value:"\u4e1a\u52a1\u6210\u957f && \u8f6f\u6280\u80fd",id:"\u4e1a\u52a1\u6210\u957f--\u8f6f\u6280\u80fd",level:2},{value:"Git \u76f8\u5173",id:"git-\u76f8\u5173",level:2},{value:"\u6e90\u7801\u7cfb\u5217",id:"\u6e90\u7801\u7cfb\u5217",level:2},{value:"Webpack \u7cfb\u5217",id:"webpack-\u7cfb\u5217",level:2},{value:"Vite \u7cfb\u5217",id:"vite-\u7cfb\u5217",level:2},{value:"PNPM && Monorepo",id:"pnpm--monorepo",level:2},{value:"Rollup \u7cfb\u5217",id:"rollup-\u7cfb\u5217",level:2},{value:"\u5fae\u524d\u7aef && \u6a21\u5757\u8054\u90a6",id:"\u5fae\u524d\u7aef--\u6a21\u5757\u8054\u90a6",level:2},{value:"VS Code \u63d2\u4ef6",id:"vs-code-\u63d2\u4ef6",level:2},{value:"\u524d\u7aef\u5de5\u7a0b\u5316",id:"\u524d\u7aef\u5de5\u7a0b\u5316",level:2},{value:"\u8f6f\u4ef6\u67b6\u6784 && \u8bbe\u8ba1\u6a21\u5f0f",id:"\u8f6f\u4ef6\u67b6\u6784--\u8bbe\u8ba1\u6a21\u5f0f",level:2},{value:"\u6301\u7eed\u96c6\u6210",id:"\u6301\u7eed\u96c6\u6210",level:2},{value:"\u670d\u52a1\u7aef\u76f8\u5173",id:"\u670d\u52a1\u7aef\u76f8\u5173",level:2},{value:"\u524d\u7aef\u6027\u80fd\u4f18\u5316",id:"\u524d\u7aef\u6027\u80fd\u4f18\u5316",level:2},{value:"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218",id:"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218",level:2},{value:"Node.js \u7cfb\u5217",id:"nodejs-\u7cfb\u5217",level:2},{value:"\u524d\u7aef\u7f16\u8bd1",id:"\u524d\u7aef\u7f16\u8bd1",level:2},{value:"\u7f51\u7edc\u76f8\u5173",id:"\u7f51\u7edc\u76f8\u5173",level:2},{value:"\u64cd\u4f5c\u7cfb\u7edf",id:"\u64cd\u4f5c\u7cfb\u7edf",level:2},{value:"\u673a\u5668\u5b66\u4e60",id:"\u673a\u5668\u5b66\u4e60",level:2},{value:"LLM \u6280\u672f\u8c03\u7814",id:"llm-\u6280\u672f\u8c03\u7814",level:2},{value:"Java \u76f8\u5173",id:"java-\u76f8\u5173",level:2},{value:"MySQL \u5b66\u4e60",id:"mysql-\u5b66\u4e60",level:2},{value:"Golang \u5b66\u4e60",id:"golang-\u5b66\u4e60",level:2},{value:"Rust \u5b66\u4e60",id:"rust-\u5b66\u4e60",level:2},{value:"\u7f51\u7ad9\u63a8\u8350",id:"\u7f51\u7ad9\u63a8\u8350",level:2},{value:"\u5b66\u4e60\u8d44\u6e90",id:"\u5b66\u4e60\u8d44\u6e90",level:2},{value:"\u9762\u8bd5\u76f8\u5173",id:"\u9762\u8bd5\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u6398\u91d1\u5927\u4f6c\u6c47\u603b",id:"-\u6398\u91d1\u5927\u4f6c\u6c47\u603b",level:2},{value:"\ud83d\udcd2 \u5f85\u5b66\u4e60\u5185\u5bb9",id:"-\u5f85\u5b66\u4e60\u5185\u5bb9",level:2},{value:"\ud83d\udcd2 \u5c0f\u76ee\u6807",id:"-\u5c0f\u76ee\u6807",level:2},{value:"\ud83d\udcd2 \u63a8\u8350\u9605\u8bfb",id:"-\u63a8\u8350\u9605\u8bfb",level:2}],M={toc:R},Q="wrapper";function T(e){let{components:t,...a}=e;return(0,n.kt)(Q,(0,i.Z)({},M,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01"),(0,n.kt)("h2",{id:"typescript-\u5de5\u7a0b\u5316\u65b9\u6848"},"TypeScript \u5de5\u7a0b\u5316\u65b9\u6848"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/403970666"},"2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7087811040591675428"},"\u90fd 2022 \u5e74\u4e86\uff0c\u624b\u52a8\u642d\u5efa React \u5f00\u53d1\u73af\u5883\u5f88\u96be\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7039583726375796749#heading-22"},"\u4f1a\u5199 TypeScript \u4f46\u4f60\u771f\u7684\u4f1a TS \u7f16\u8bd1\u914d\u7f6e\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904102355271694"},"\u3010\u5f00\u6e90\u3011\u4e00\u4e2a React + TS \u9879\u76ee\u6a21\u677f"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4e00\u79cd\u662f\u4f7f\u7528 ts-loader + babel-loader + fork-ts-checker-webpack-plugin \u901a\u8fc7 typescript \u8fdb\u884c\u7f16\u8bd1\u548c\u7c7b\u578b\u68c0\u67e5"),(0,n.kt)("li",{parentName:"ul"},"\u53e6\u4e00\u79cd\u662f babel-loader + @babel/preset-typescript \u4f7f\u7528 babel \u8fdb\u884c\u7f16\u8bd1\uff0ctypescript \u53ea\u8d1f\u8d23\u7c7b\u578b\u68c0\u67e5\uff08babel 7 \u4ee5\u4e0a\uff09"))),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6999807899149008910"},"2021\u5e74\u4ece\u96f6\u5f00\u53d1\u524d\u7aef\u9879\u76ee\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904052094926855"},"Webpack \u8f6c\u8bd1 Typescript \u73b0\u6709\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000015315545"},"\u4f7f\u7528ESLint+Prettier\u6765\u7edf\u4e00\u524d\u7aef\u4ee3\u7801\u98ce\u683c")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000009546913"},"\u7528 husky \u548c lint-staged \u6784\u5efa\u8d85\u6e9c\u7684\u4ee3\u7801\u68c0\u67e5\u5de5\u4f5c\u6d41"))),(0,n.kt)("h2",{id:"ts-\u9ad8\u7ea7\u6280\u5de7"},"TS \u9ad8\u7ea7\u6280\u5de7"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/usDh1-Wzxrf4BftfWhwduA"},"\u4f60\u9700\u8981\u77e5\u9053\u7684TypeScript\u9ad8\u7ea7\u7c7b\u578b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WsldmkW2ovp-okxSY3le9g"},"Typescript \u7c7b\u578b\u7f16\u7a0b\uff0c\u4ece\u5165\u95e8\u5230\u901a\u8fbe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7089809919251054628"},"\u5982\u4f55\u8fdb\u9636TypeScript\u529f\u5e95\uff1f\u4e00\u6587\u5e26\u4f60\u7406\u89e3TS\u4e2d\u5404\u79cd\u9ad8\u7ea7\u8bed\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6998785406619615269"},"TypeScript\u4ece\u5e73\u51e1\u5230\u4e0d\u51e1\uff08\u57fa\u7840\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7150668738990178312"},"\u63a8\u835012\u4e2a\u503c\u5f97\u5b66\u4e60\u7684TypeScript\u5b9d\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TUv8Cu6_ftQQ6lEWAwIa4w"},"TypeScript \u7c7b\u578b\u7cfb\u7edf\uff1a\u5206\u5e03\u5f0f\u6761\u4ef6\u7c7b\u578b\u5168\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7061556434692997156"},"\u63a5\u8fd1\u5929\u82b1\u677f\u7684TS\u7c7b\u578b\u4f53\u64cd\uff0c\u770b\u61c2\u4f60\u5c31\u80fd\u73a9\u8f6cTS\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-x8iVK-hlQd3-OZDC04A5A"},"TypeScript \u7c7b\u578b\u7f16\u7a0b: \u4ece\u57fa\u7840\u5230\u7f16\u8bd1\u5668\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7050099282317148174"},"\u77e5\u5176\u7136\uff0c\u77e5\u5176\u6240\u4ee5\u7136\uff1aTypeScript \u4e2d\u7684\u534f\u53d8\u4e0e\u9006\u53d8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007251289721536543"},"TypeScript\u662f\u5982\u4f55\u5de5\u4f5c\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6964692485415108645"},"TypeScript \u9ad8\u7ea7\u7528\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/owtE_7PVLyz5XqwGofaTZg"},"\u629b\u7816\u5f15\u7389\uff1aTypeScript \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6871752423577223176"},"\u7ec6\u6570\u8fd9\u4e9b\u5e74\u88ab\u56f0\u6270\u8fc7\u7684 TS \u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904055039344654"},"TS \u5e38\u89c1\u95ee\u9898\u6574\u7406\uff0860\u591a\u4e2a\uff0c\u6301\u7eed\u66f4\u65b0ing\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6994102811218673700"},"Ts\u9ad8\u624b\u7bc7\uff1a22\u4e2a\u793a\u4f8b\u6df1\u5165\u8bb2\u89e3Ts\u6700\u6666\u6da9\u96be\u61c2\u7684\u9ad8\u7ea7\u7c7b\u578b\u5de5\u5177"))),(0,n.kt)("h2",{id:"ts--\u6846\u67b6"},"TS && \u6846\u67b6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://react-typescript-cheatsheet.netlify.app/"},"\u4e00\u4efd\u5f88\u5168\u9762\u7684 React TypeScript \u5907\u5fd8\u5f55")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6952696734078369828"},"React + TypeScript\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071066976830881823"},"\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069555976717729805"},"\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7058868160706904078"},"\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6DAyXFHIMW95FS0f3GyHpA"},"TypeScript \u7ec8\u6781\u521d\u5b66\u8005\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021674818621669389"},"\u5982\u4f55\u4f18\u96c5\u5730\u5728 React \u4e2d\u4f7f\u7528TypeScript\uff0c\u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904122550845448"},"\u7cbe\u8bfb\u300a@types react \u503c\u5f97\u6ce8\u610f\u7684 TS \u6280\u5de7\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7068081327857205261"},"\u300c1.9W\u5b57\u603b\u7ed3\u300d\u4e00\u4efd\u901a\u4fd7\u6613\u61c2\u7684 TS \u6559\u7a0b\uff0c\u5165\u95e8 + \u5b9e\u6218\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903865255477261"},"Vue3.0 \u524d\u7684 TypeScript \u6700\u4f73\u5165\u95e8\u5b9e\u8df5"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u867d\u7136\u4e0d\u662f Vue3 \u4f46\u662f\u4e5f\u63a8\u8350\u770b\u4e0b")))),(0,n.kt)("h2",{id:"\u524d\u7aef\u6846\u67b6"},"\u524d\u7aef\u6846\u67b6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047705995534925832"},"\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e Vue \u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047690546417565733"},"\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e React \u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047153016771706916"},"\u76d8\u70b9\u6398\u91d1 2021 \u70b9\u8d5e\u9ad8\u8fbe 6000\uff0c\u6536\u85cf\u8fc7\u4e07\u7684\u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q"},"\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903913410314247"},"Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/66sos7nML5rA0ZZGJ5qFIQ"},"[","\u79d1\u666e\u6587","]"," Vue3 \u5230\u5e95\u66f4\u65b0\u4e86\u4ec0\u4e48\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6922641008106668045"},"\u63ed\u79d8 Vue.js \u4e5d\u4e2a\u6027\u80fd\u4f18\u5316\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7005880217684148231"},"\u6211\u5728\u9879\u76ee\u4e2d\u7528\u5b9e\u9645\u7528\u5230\u768422\u4e2aVue\u4f18\u5316\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904165500518414"},"React Hooks \u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046358484610187277"},"React Hooks \u4f7f\u7528\u8bef\u533a\uff0c\u9a73\u5b98\u65b9\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043772161596588046"},"\u5b9d\u554a\uff5e\u6765\u804a\u804a 9 \u79cd React Hook")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6933018383961194509"},"\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684\u6d41\u5f0f React Hooks\uff08\u5173\u4e8e\u7ec4\u7ec7\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7025524870842679310#heading-58"},"\u4ece 16 \u4e2a\u65b9\u5411\u9010\u6b65\u642d\u5efa\u57fa\u4e8e vue3 \u7684\u524d\u7aef\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6874007172578033677"},"34\u6761\u6211\u80fd\u544a\u8bc9\u4f60\u7684Vue\u4e4b\u5b9e\u64cd\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/461844358"},"React \u4f53\u7cfb\u4e0b\u5173\u4e8e Mobx \u4e0e Redux \u7684\u4e00\u4e9b\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aOapwk4_qi8tNM7vaa7jGA"},"\u4f7f\u7528 React&Mobx \u7684\u51e0\u4e2a\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6995834232350179336"},"\u5f53\u8bbe\u8ba1\u6a21\u5f0f\u9047\u4e0a Hooks")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903985338400782"},"React Hooks \u8be6\u89e3 \u3010\u8fd1 1W \u5b57\u3011+ \u9879\u76ee\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6989022564043456543"},"\u300cReact\u8fdb\u9636\u300d\u53ea\u7528\u4e24\u4e2a\u81ea\u5b9a\u4e49 Hooks \u5c31\u80fd\u66ff\u4ee3 React-Redux ?")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6950063294270930980"},"\u300cReact\u8fdb\u9636\u300d React\u5168\u90e8api\u89e3\u8bfb+\u57fa\u7840\u5b9e\u8df5\u5927\u5168(\u592f\u5b9e\u57fa\u78402\u4e07\u5b57\u603b\u7ed3)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6963053793613185031"},"\u300cReact\u8fdb\u9636\u300d\u63a2\u6848\u63ed\u79d8\u516d\u79cdReact\u2018\u7075\u5f02\u2019\u73b0\u8c61")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944863057000529933"},"\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406"))),(0,n.kt)("h2",{id:"\u7f16\u7a0b\u8303\u5f0f"},"\u7f16\u7a0b\u8303\u5f0f"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/shfshanyue/fp-jargon-zh"},"\u51fd\u6570\u5f0f\u7f16\u7a0b\u672f\u8bed")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7065093131233919006"},"\u51fd\u6570\u5f0f\u7f16\u7a0b\uff08FP\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6974377246140301342"},"coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6892886272377880583"},"\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903936378273799"},"\u7b80\u660e JavaScript \u51fd\u6570\u5f0f\u7f16\u7a0b\u2014\u2014\u5165\u95e8\u7bc7"))),(0,n.kt)("h2",{id:"\u6280\u672f\u65b9\u6848"},"\u6280\u672f\u65b9\u6848"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7144881028661723167"},"\u5982\u4f55\u53bb\u641e\u524d\u7aef\u57fa\u5efa")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7129298214959710244"},"\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085679511290773534"},"\u817e\u8baf\u4e8c\u9762\uff1a\u73b0\u5728\u8981\u4f60\u5b9e\u73b0\u4e00\u4e2a\u57cb\u70b9\u76d1\u63a7SDK\uff0c\u4f60\u4f1a\u600e\u4e48\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA"},"\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7087206796351242248"},"\u817e\u8baf\u4e09\u9762\uff1aCookie\u7684SameSite\u4e86\u89e3\u5427\uff0c\u90a3SameParty\u5462")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7081539471585312805"},"\u817e\u8baf\u4e00\u9762\uff1aCORS\u4e3a\u4ec0\u4e48\u80fd\u4fdd\u969c\u5b89\u5168\uff1f\u4e3a\u4ec0\u4e48\u53ea\u5bf9\u590d\u6742\u8bf7\u6c42\u505a\u9884\u68c0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3hXLSOQC-B5JGmkOaYjgqw"},"\u4e0d\u4f7f\u7528\u7b2c\u4e09\u65b9\u5e93\u600e\u4e48\u5b9e\u73b0\u3010\u524d\u7aef\u5f15\u5bfc\u9875\u3011\u529f\u80fd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124573626161954823"},"\u524d\u7aef\u67b6\u6784\u5e26\u4f60 \u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u7ec8\u8eab\u53d7\u76ca\u300c\u7f8e\u56e2\u540e\u7aef\u8fde\u8fde\u70b9\u8d5e\u300d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d5M_-8XqFGYnpif7GQNmLA"},"\u3010\u7b2c2759\u671f\u3011\u5f02\u6b65\u5206\u7247\u8ba1\u7b97\u5728\u817e\u8baf\u6587\u6863\u7684\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FZUTFvOutS5NvURjj9jOFA"},"\u5b57\u8282\u524d\u7aef\u76d1\u63a7 SDK \u4f53\u79ef\u4e0e\u6027\u80fd\u4f18\u5316\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8cguocg_1DtZkHLfAGLyXg"},"\u4f7f\u7528 Vite \u63d2\u4ef6\u81ea\u52a8\u5316\u5b9e\u73b0\u9aa8\u67b6\u5c4f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l7SA04BJovmJTUDIuobYiw"},"\u76d8\u70b912\u4e2ayyds\u7684\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5f00\u6e90\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1HyQLZcnZN6I27p_hbfUPg"},"\u3010\u7b2c2628\u671f\u3011\u57fa\u4e8e\u8bbe\u8ba1\u7a3f\u8bc6\u522b\u7684\u53ef\u89c6\u5316\u4f4e\u4ee3\u7801\u7cfb\u7edf\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ba-3fMQXNXqIzVTjVUrWtQ"},"\u6d45\u8c08\u6587\u6863\u7684\u5b9e\u65f6\u534f\u540c\u7f16\u8f91")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-WHafu5z-Ap4tjrbWesnmA"},"\u81ea\u52a8\u5316\u751f\u6210\u9aa8\u67b6\u5c4f\u7684\u6280\u672f\u65b9\u6848\u8bbe\u8ba1\u4e0e\u843d\u5730")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7148254347401363463"},"\u8c08\u8c08JS\u4e8c\u8fdb\u5236\uff1aFile\u3001Blob\u3001FileReader\u3001ArrayBuffer\u3001Base64")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904046436843527"},"\u5b57\u8282\u8df3\u52a8\u9762\u8bd5\u5b98\uff1a\u8bf7\u4f60\u5b9e\u73b0\u4e00\u4e2a\u5927\u6587\u4ef6\u4e0a\u4f20\u548c\u65ad\u70b9\u7eed\u4f20")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6990283221170651149"},"\u4ece\u96f6\u5f00\u59cb\u624b\u5199\u4e00\u4e2a\u300c\u5f00\u7bb1\u5373\u7528\u7684\u5927\u6587\u4ef6\u5206\u7247\u4e0a\u4f20\u5e93\u300d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6992007156320960542"},"5000\u5b57\u5e26\u4f60\u5168\u9762\u6df1\u5165\u7406\u89e3JS\u4e2d\u7684Stream API\uff5c8\u6708\u66f4\u6587\u6311\u6218"))),(0,n.kt)("h2",{id:"\u4e1a\u52a1\u6210\u957f--\u8f6f\u6280\u80fd"},"\u4e1a\u52a1\u6210\u957f && \u8f6f\u6280\u80fd"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u7ba1\u7406\u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/neSFlzQMh2P7ROwJxhVNkg"},"\u7ba1\u7406\u5c0f\u518c\u3001\u4e00\u7ebf\u540c\u5b66\u63a8\u8350\u3001\u4e00\u7ebfLeader\u63a8\u8350\u3001\u603b\u76d1\u7ea7\u63a8\u8350")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FDK0a4HeO60fKyr6ioRYcw"},"\u8c01\u80fd\u6210\u4e3aLeader\uff0c\u5927Leader\u8be5\u505a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dTXg9a4kXwVZi2N7mP71mg"},"\u5c11\u5e74\uff0c\u77e5\u9053\u4ec0\u4e48\u662f\u4fe1\u606f\u5dee\u521b\u9020\u4ef7\u503c\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/oodAZtxzHCZVGIGS9rBzIA"},"\u4ec0\u4e48\u662f\u5411\u4e0a\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/B3qgLTvSHzE33d6O-k7bAQ"},"\u4f60\u662f\u5982\u4f55\u505a\u6c47\u62a5\u7684")))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7073001183123603470"},"\u5e73\u65f6\u7684\u5de5\u4f5c\u5982\u4f55\u4f53\u73b0\u4e00\u4e2a\u4eba\u7684\u6280\u672f\u6df1\u5ea6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U6jAFVrgrKIm9--amZV5rA"},"\u5982\u4f55\u6210\u4e3a\u4f18\u79c0\u5de5\u7a0b\u5e08\u4e4b\u8f6f\u6280\u80fd\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MOWQ3rBFaITHSD2hvSelcw"},"\u5e72\u8d27\uff016\u4e2a\u65b9\u9762\uff0c32\u6761\u603b\u7ed3\u6559\u4f60\u63d0\u5347\u804c\u573a\u7ecf\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kozXWY95HXiQPGou1sfttg"},"\u804a\u804a\u5982\u4f55\u5b66\u4e60")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/K36xQbYgGVme8v_p9_dhkQ"},"\u4ee5\u524d\u7aef\u67b6\u6784\u5e08\u8eab\u4efd\uff0c\u4ece\u96f6\u5f00\u59cb\u641e\u4e8b\u641e\u4e8b\u641e\u4e8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7115634967945674765"},"Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7185376363808260152"},"\u4e00\u56fe\u80dc\u5343\u8a00\u7cfb\u5217\u2014\u2014\u6cf3\u9053\u56fe\u548c\u6570\u636e\u6d41\u56fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153432342919397383"},"\u600e\u4e48\u505a\u5230\u4e00\u56fe\u80dc\u5343\u8a00")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/URJC9ERPrcniiFinUsIJkg"},"\u3010\u56fe\u4e66\u3011\u7a0b\u5e8f\u5458\u7684\u5e95\u5c42\u601d\u7ef4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iTFj1Sn5vPTgkAT2Q9YC0w"},"\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u5b98\uff0c\u539f\u6765\u8fd9\u79cd\u5b66\u751f\u6700\u5403\u9999\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rJN14WFRTKjhoy8oWPulWw"},"\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\uff01YYDS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cbKpWKWrhyJwKQhlyYhQ_w"},"\u5982\u4f55\u5728\u9879\u76ee\u5f00\u53d1\u4e2d\u9010\u6b65\u6210\u957f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7114967732805697543"},"\u51b4\u7fbd\u7b54\u8bfb\u8005\u95ee\uff1a\u5982\u4f55\u5728\u5de5\u4f5c\u4e2d\u6253\u9020\u5f71\u54cd\u529b\uff0c\u5e26\u52a8\u540c\u4e8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1BdXL5dQfP6DnK7iJs6zGQ"},"\u5165\u804cApifox\u7814\u53d1\u7ec4\u534a\u5e74\uff0c\u6211\u6240\u63d0\u5347\u7684\u8f6f\u6280\u80fd\uff5c\u6587\u672b\u62bd\u4e66")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G8SVu9CWrKwbT5jfXaBmtw"},"\u6709\u54ea\u4e9b\u503c\u5f97\u8ba1\u7b97\u673a\u4e13\u4e1a\u5b66\u751f\u52a0\u5165\u7684\u56fd\u4f01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ"},"\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1QMPfODUcH1p4pGaoO1owA"},"\u5982\u4f55\u5199\u597d\u4e00\u4efd\u664b\u5347PPT\uff08\u9644PPT\u6a21\u677f\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hXFWU6uuil1aC1lEYO_KhQ"},"\u5982\u4f55\u753b\u51fa\u4e00\u5f20\u4f18\u79c0\u7684\u67b6\u6784\u56fe\uff08\u8001\u9e1f\u5fc5\u5907\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6965675185890394119"},"\u7cbe\u8bfb\u300a\u524d\u7aef\u804c\u4e1a\u89c4\u5212 - 2021 \u5e74\u300b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7034419410706104356"},"2022\u5e74\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u5927\u524d\u7aefLeader\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n4Pa0Bao1ISS68IOPWGI_Q"},"\u6280\u672f\u4eba\u7684\u4e03\u5927\u5fc5\u5907\u7279\u8d28")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6906468062943182862#heading-8"},"\u521d\u7ea7\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u6210\u957f\u548c\u5bfb\u6c42\u7a81\u7834")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NRqhJax8e6K8LMCNZSSozA"},"\u5e74\u5e95\u4e86\uff0c\u4f60\u662f\u5982\u4f55\u505a\u5de5\u4f5c\u6c47\u62a5\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904103504527374"},"\u5199\u7ed9\u521d\u4e2d\u7ea7\u524d\u7aef\u7684\u9ad8\u7ea7\u8fdb\u9636\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7041713124210114567"},"\u5728\u653f\u91c7\u4e91\u5982\u4f55\u5199\u524d\u7aef\u6280\u672f\u65b9\u6848\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017643726944108558"},"\u5982\u4f55\u7f16\u5199\u524d\u7aef\u8bbe\u8ba1\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6901845776880795662#heading-0"},"\u7406\u6e05\u601d\u8def\uff0c\u524d\u7aef\u6280\u672f\u8c03\u7814\u5230\u5e95\u5e94\u8be5\u600e\u4e48\u505a\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6869548364640288781"},"\u4ece\u5b9e\u4e60\u5230\u5165\u804c\uff1a\u4e0e\u4f60\u5206\u4eab\u6211\u5728\u653f\u91c7\u4e91\u7684\u5de5\u4f5c\u548c\u6210\u957f"))),(0,n.kt)("h2",{id:"git-\u76f8\u5173"},"Git \u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/250493093"},"\u8840\u6cea\u6559\u8bad\u4e4b\u8bf7\u4e0d\u8981\u518d\u8f7b\u89c6Git \u2014\u2014 \u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 Git \u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aTr6xf4BEuF-yxL340TnLg"},"GitHub \u641c\u7d22\u6280\u5de7\uff1a\u5982\u4f55\u66f4\u6709\u6548\u5730\u641c\u7d22 issue\u3001repo \u548c\u66f4\u591a\u4fe1\u606f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046720828901163016"},"\u5982\u679c\u4f60\u8fd8\u4e0d\u4f1a\u7528git\u56de\u6eda\u4ee3\u7801\uff0c\u90a3\u4f60\u4e00\u5b9a\u8981\u6765\u770b\u770b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071780876501123085"},"Git\u4e0d\u8981\u53ea\u4f1apull\u548cpush\uff0c\u8bd5\u8bd5\u8fd95\u6761\u63d0\u9ad8\u6548\u7387\u7684\u547d\u4ee4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046409685561245733"},"\u5229\u7528\u597d git bisect \u8fd9\u628a\u5229\u5668\uff0c\u5e2e\u52a9\u4f60\u5feb\u901f\u5b9a\u4f4d\u7591\u96be bug")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7024043015794589727"},"\u524d\u7aef\u67b6\u6784\u5e08\u7684 git \u529f\u529b\uff0c\u4f60\u6709\u51e0\u6210\u706b\u5019\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000040712052"},"\u4e24\u6761\u547d\u4ee4\u8ba9\u4f60\u7684git\u81ea\u52a8\u53d8\u57fa")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904191203213326"},"\u591a\u5e74 Git \u4f7f\u7528\u5fc3\u5f97 & \u5e38\u89c1\u95ee\u9898\u6574\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6974184935804534815"},"\u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 git \u7684")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7000186205224566791"},"\u4e3a\u4ec0\u4e48 husky \u653e\u5f03\u4e86\u4f20\u7edf\u7684 JS \u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904036068491278"},"\u4f60\u53ef\u80fd\u5df2\u7ecf\u5ffd\u7565\u7684git commit\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://gitmoji.dev/"},"gitmoji: An emoji guide for your commit messages"))),(0,n.kt)("h2",{id:"\u6e90\u7801\u7cfb\u5217"},"\u6e90\u7801\u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982004709145968677"},"[\u5efa\u8bae\u6536\u85cf] \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7048970987500470279"},"\u516d\u5343\u5b57\u8be6\u89e3\uff01vue3 \u54cd\u5e94\u5f0f\u662f\u5982\u4f55\u5b9e\u73b0\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7019185205336342542"},"Redux\u901a\u5173\u7b80\u6d01\u653b\u7565 -- \u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6978654109893132318"},"\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7010539227284766751"},"React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6990974525273800712"},"\u5e26\u4f60\u5feb\u901f\u624b\u5199\u4e00\u4e2a\u7b80\u6613\u7248vue\u4e86\u89e3vue\u54cd\u5e94\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7072321805792313357"},"Vue3.2 vDOM diff\u6d41\u7a0b\u5206\u6790\u4e4b\u4e00\uff1adiff\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6977363265965785102"},"2021\u5e74\uff0c\u8ba9\u6211\u4eec\u624b\u5199\u4e00\u4e2amini\u7248\u672c\u7684vue2.x\u548cvue3.x\u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6846687602679119885"},"Vue(v2.6.11)\u4e07\u884c\u6e90\u7801\u751f\u5543\uff0c\u5c31\u786c\u521a\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6992018709439053837"},"\u5c24\u96e8\u6eaa\u56fd\u5916\u6559\u7a0b\uff1a\u4eb2\u624b\u5e26\u4f60\u5199\u4e2a\u7b80\u6613\u7248\u7684Vue\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://codepen.io/collection/DkxpbE?cursor=ZD0wJm89MCZwPTEmdj00"},"Vue 3 Workshop Code Samples")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997965021401579556"},"diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997943192851054606"},"Vue 3.2 \u53d1\u5e03\u4e86\uff0c\u90a3\u5c24\u96e8\u6eaa\u662f\u600e\u4e48\u53d1\u5e03 Vue.js \u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6994976281053888519"},"\u521d\u5b66\u8005\u4e5f\u80fd\u770b\u61c2\u7684 Vue3 \u6e90\u7801\u4e2d\u90a3\u4e9b\u5b9e\u7528\u7684\u57fa\u7840\u5de5\u5177\u51fd\u6570"))),(0,n.kt)("h2",{id:"webpack-\u7cfb\u5217"},"Webpack \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6937125495439900685"},"Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u901a\u8fc7\u7f16\u5199\u4e00\u4e2a plugin\uff0c\u5728\u9884\u5904\u7406\u9636\u6bb5\u901a\u8fc7\u63d2\u4ef6 apply \u51fd\u6570\u52a8\u6001\u4fee\u6539 webpack \u914d\u7f6e\uff0c\u6ce8\u5165 vue-loader \u4e13\u7528\u7684 rules"))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047777251949019173"},"\u8d85\u786c\u6838\uff5c\u5e26\u4f60\u7545\u6e38\u5728 Webpack \u63d2\u4ef6\u5f00\u53d1\u8005\u7684\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7170852747749621791"},"\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7164175171358556173"},"\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g"},"Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/32831172"},"\u4f60\u7684Tree-Shaking\u5e76\u6ca1\u4ec0\u4e48\u5375\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903939289120782"},"\u624b\u6478\u624b Webpack \u591a\u5165\u53e3\u914d\u7f6e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031546400034947108"},"Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023242274876162084"},"\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021729340945596424"},"Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gwHwVxA4zh59SBvq-onM-g"},"Webpack5 \u5b9e\u8df5 - \u6784\u5efa\u6548\u7387\u500d\u901f\u63d0\u5347\uff01")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mpF6W-4dElu0UPed03oJQw"},"Webpack \u6027\u80fd\u7cfb\u5217\u4e00: \u4f7f\u7528 Cache \u63d0\u5347\u6784\u5efa\u6027\u80fd")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6910893471339708429"},"\u6211\u662f\u5982\u4f55\u5c06\u7f51\u9875\u6027\u80fd\u63d0\u53475\u500d\u7684 \u2014 \u6784\u5efa\u4f18\u5316\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6858905382861946894"},"Webpack\u914d\u7f6e\u5168\u89e3\u6790\uff08\u4f18\u5316\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7144934998884220958"},"\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0a\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145025071432597541"},"\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0b\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6996816316875161637"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6991774994552324133"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u5b9e\u8df5\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6991630925792542750"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u57fa\u7840\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903912588181511"},"\u624b\u628a\u624b\u5e26\u4f60\u5165\u95e8 Webpack4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6949040393165996040"},"[","\u4e07\u5b57\u603b\u7ed3","]"," \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406"))),(0,n.kt)("h2",{id:"vite-\u7cfb\u5217"},"Vite \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124112069355372581"},"\u5b66\u4f1a\u8fd9 20 \u4e2a\u5e93\uff0c\u8ba9\u4f60\u5feb\u901f\u770b\u61c2 vue3 \u548c vite3 \u6e90\u7801 \ud83d\ude80")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094984070999834655"},"\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6986533364438138894"},"\u524d\u7aef\u5386\u53f2\u9879\u76ee\u7684 Vite \u8fc1\u79fb\u5b9e\u8df5\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6979932627465666568"},"\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite 2.x \u6e90\u7801\u7ea7\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6956564266812571656"},"\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite \u26a1\ufe0f\u539f\u7406\u5206\u6790"))),(0,n.kt)("h2",{id:"pnpm--monorepo"},"PNPM && Monorepo"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/beLkwHan2C8BuSArs53cIA"},"\u8bfe\u4ee3\u8868\uff1aTurborepo \u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7015566240991150117"},"lerna + dumi + eslint\u591a\u5305\u7ba1\u7406\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/z-tKxgRPmdyR0zwc78Khgw"},"\u7ec4\u4ef6\u5e93Monmrepo\u67b6\u6784\u4e0e\u5f00\u53d1\u8c03\u8bd5\u73af\u5883\u6784\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7177585131861835837"},"React Native\u5de5\u7a0bMonorepo\u6539\u9020\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JWks8VyuXoB5zaeYdyJPxw"},"\u3010\u7b2c2714\u671f\u3011\u4eceMultirepo\u5230Monorepo \u888b\u9f20\u4e91\u6570\u6808\u524d\u7aef\u7814\u53d1\u6548\u7387\u63d0\u5347\u63a2\u7d22\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N0CZABDD0TKTmdljH3y74A"},"Monorepo\uff0c\u5927\u578b\u524d\u7aef\u9879\u76ee\u7ba1\u7406\u6a21\u5f0f\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094984070999834655"},"\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6peafvVjmcF65PFSggSLYQ"},"\u590d\u6d3b\u4e86\uff01 Lerna V6 \u5e26\u6765\u4e86\u54ea\u4e9b\u65b0\u4e1c\u897f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7098609682519949325"},"pnpm + workspace + changesets \u6784\u5efa\u4f60\u7684 monorepo \u5de5\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7161063570594070559"},"Element Plus \u7ec4\u4ef6\u5e93\u6838\u5fc3\u6280\u672f\u63ed\u79d8\uff1a5. \u4ece\u7ec8\u7aef\u547d\u4ee4\u89e3\u6790\u5668\u8bf4\u8d77\u8c08\u8c08 npm \u5305\u7ba1\u7406\u5de5\u5177\u7684\u8fd0\u884c\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157743898939359262"},"Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a4. ESLint \u6280\u672f\u539f\u7406\u4e0e\u5b9e\u6218\u53ca\u4ee3\u7801\u89c4\u8303\u81ea\u52a8\u5316\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146183222425518093"},"Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7129267782515949575"},"\ud83d\ude80Turborepo\uff1a\u53d1\u5e03\u5f53\u6708\u5c31\u6fc0\u589e 3.8k Star\uff0c\u8fd9\u6b3e\u8d85\u795e\u7684\u65b0\u5174 Monorepo \u65b9\u6848\uff0c\u4f60\u4e0d\u6253\u7b97\u5c1d\u8bd5\u4e0b\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7136925215388499998"},"\u6700\u8be6\u7ec6\u7684 lerna \u4e2d\u6587\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://turborepo.org/docs/handbook/what-is-a-monorepo"},"Monorepo Handbook \u65b0\u9c9c\u51fa\u7089")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/99nozy-vtFMGcBTxYvumWA"},"\u73b0\u4ee3 Monorepo \u5de5\u7a0b\u6280\u672f\u9009\u578b\uff0c\u804a\u804a\u6211\u7684\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7092766235380678687"},"\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/455809528"},"\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA"},"pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw"},"\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083414641610588168"},"\u524d\u7aef\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u8fdb\u5316\u53f2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7053340250210795557"},"\u90fd2022\u5e74\u4e86\uff0cpnpm\u5feb\u5230\u7897\u91cc\u6765\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6932046455733485575"},"\u5173\u4e8e\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u6df1\u5ea6\u601d\u8003\u2014\u2014\u4e3a\u4ec0\u4e48\u73b0\u5728\u6211\u66f4\u63a8\u8350 pnpm \u800c\u4e0d\u662f npm/yarn?")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7051929587852247077"},"\u5e74\u7ec8\u76d8\u70b9\uff1a2022\u57fa\u4e8eMonorepo\u7684\u9996\u4e2a\u5927\u8d8b\u52bf-TurboRepo")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7030207667457130527"},"\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043998041786810398"},"One For All\uff1a\u57fa\u4e8epnpm + lerna + typescript\u7684\u6700\u4f73\u9879\u76ee\u5b9e\u8df5 - \u7406\u8bba\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029262501833359368"},"\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6972139870231724045"},"Monorepo \u7684\u8fd9\u4e9b\u5751\uff0c\u6211\u4eec\u5e2e\u4f60\u8e29\u8fc7\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6950082433647640612"},"\u5f00\u6e90\u9879\u76ee\u90fd\u5728\u7528 monorepo\uff0c\u4f46\u662f\u4f60\u77e5\u9053\u5c45\u7136\u6709\u90a3\u4e48\u591a\u5751\u4e48\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6924854598268108807"},"All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5"))),(0,n.kt)("h2",{id:"rollup-\u7cfb\u5217"},"Rollup \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145090564801691684"},"\u3010\u5b9e\u6218\u7bc7\u3011\u6700\u8be6\u7ec6\u7684Rollup\u6253\u5305\u9879\u76ee\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7144365208646418462"},"\u4ece0\u52301\u5f00\u53d1\u4e00\u4e2aReact\u7ec4\u4ef6\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xjY0d8eNTmAuCZKxKQeu7g"},"\u57fa\u4e8estorybook\u7ec4\u4ef6\u5e93\u7684\u6280\u672f\u9009\u578b\u8be5\u600e\u4e48\u9009")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7151653067593613320"},"\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126394898445500423"},"\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mL1pv2kPKvtaHalr7PXKow"},"\u524d\u7aef\u5de5\u7a0b\u5316\u57fa\u5efa\u63a2\u7d22\uff1a\u4ece\u5185\u90e8\u673a\u5236\u548c\u6838\u5fc3\u539f\u7406\u4e86\u89e3npm")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069555431303020580"},"\u4e00\u6587\u5165\u95e8rollup\ud83e\ude80\uff0113\u7ec4demo\u5e26\u4f60\u8f7b\u677e\u9a7e\u9a6d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7051236803344334862"},"\u8bf4\u4e0d\u6e05rollup\u80fd\u8f93\u51fa\u54ea6\u79cd\u683c\u5f0f\ud83d\ude25\u5dee\u70b9\u88ab\u9119\u89c6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7052307032971411463"},"\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903970469576718"},"\u524d\u7aef\u7ec4\u4ef6/\u5e93\u6253\u5305\u5229\u5668rollup\u4f7f\u7528\u4e0e\u914d\u7f6e\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6869551115420041229"},"\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup"))),(0,n.kt)("h2",{id:"\u5fae\u524d\u7aef--\u6a21\u5757\u8054\u90a6"},"\u5fae\u524d\u7aef && \u6a21\u5757\u8054\u90a6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pT_tugg_EvE5pnMCaUqliw"},"Module Federation\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WXeUuUdgF_3djqBhh1siQA"},"\u6a21\u5757\u8054\u90a6\u5728\u5fae\u524d\u7aef\u67b6\u6784\u4e2d\u7684\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/u5oAcIYiGrl1qOujOYjzqw"},"\u57fa\u4e8e MF \u7684\u7ec4\u4ef6\u5316\u5171\u4eab\u5de5\u4f5c\u6d41")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l_KKNRUyJANN6wkoC2TlVQ"},"\u804a\u4e00\u804a\u5173\u4e8e\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121244973558661150"},"\u8d85\u5927\u4f53\u91cf\u9879\u76ee\uff0c\u5fae\u524d\u7aef\u843d\u5730\u65b9\u6848\uff0c\u770b\u5b8c\u540e\u6094\u6765\u627e\u6211")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA"},"\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iS-prT1xZPV6cpH7MHRRdQ"},"\u3010\u7b2c1912\u671f\u3011\u63a2\u7d22 webpack5 \u65b0\u7279\u6027Module federation\u5728\u817e\u8baf\u6587\u6863\u7684\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PFKxQgZPER_XHUSbk_SQJA"},"\u3010\u7b2c1901\u671f\u3011Webpack 5 Module Federation: JavaScript \u67b6\u6784\u7684\u53d8\u9769\u8005")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vy84FY3P6KPeWzDaNl6Ntg"},"\u5168\u9762\u654f\u6377\u6a21\u5f0f\u4e0b\u7684\u5fae\u524d\u7aef\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mvdOU8uVG9NjGPzInpPxJA"},"\u5fae\u524d\u7aef\u573a\u666f\u4e0b\u7684\u4ee3\u7801\u5171\u4eab")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg"},"\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ylkY9HWTQKPlbDb2M33YWQ"},"\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g"},"\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101457212085633054"},"\u6a21\u5757\u8054\u90a6\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g"},"\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww"},"\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation"))),(0,n.kt)("h2",{id:"vs-code-\u63d2\u4ef6"},"VS Code \u63d2\u4ef6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4MmBSD-d-9T5-kFhcWNlTA"},"vscode\u63d2\u4ef6\u539f\u7406\u6d45\u6790\u4e0e\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/microsoft/vscode-extension-samples"},"vscode-extension-samples")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/e2gfSnBrR6rn7x37ZGLplg"},"\u5f00\u53d1\u4e00\u6b3e\u4e13\u5c5e\u7684 VSCode \u4ee3\u7801\u63d0\u793a\u63d2\u4ef6"))),(0,n.kt)("h2",{id:"\u524d\u7aef\u5de5\u7a0b\u5316"},"\u524d\u7aef\u5de5\u7a0b\u5316"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7062617190981173278"},"\u6765\u81ea\u672a\u6765\uff0c2022 \u5e74\u7684\u524d\u7aef\u4eba\u90fd\u5728\u505a\u4ec0\u4e48?")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7056612950412361741"},"\u4e3a\u4ec0\u4e48\u8bf4 WebAssembly \u662f Web \u7684\u672a\u6765\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7057114641507287048"},"easy-serverless \u529f\u80fd\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ckskF06PD43KHpKAGaYmRA"},"2022 \u5e74 JavaScript \u5f00\u53d1\u5de5\u5177\u7684\u751f\u6001")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JZbsIqsqNeJmc__QFKpo1Q"},"\u8d85\u5168\u9762\u7684\u524d\u7aef\u65b0\u4e00\u4ee3\u6784\u5efa\u5de5\u5177\u5bf9\u6bd4: esbuild\u3001Snowpack\u3001Vite\u3001wmr")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3aVYGfahv5rZJbWBhaI3BA"},"esno\uff0c\u57fa\u4e8e Esbuild \u7684\u795e\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qnA1tFKMXr7hwsEKFXKOZg"},"Deno \u7b80\u4ecb\uff1a\u5b83\u6bd4 Node.js \u66f4\u597d\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046204235226021901"},"\u57fa\u4e8e Next.js \u7684 SSR/SSG \u65b9\u6848\u4e86\u89e3\u4e00\u4e0b\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085257325165936648"},"\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029512357428592648"},"\u524d\u7aef\u67b6\u6784\u5e08\u795e\u6280\uff0c\u4e09\u62db\u7edf\u4e00\u56e2\u961f\u4ee3\u7801\u98ce\u683c")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904110601273357"},"\u624b\u628a\u624b\u6559\u4f60\u642d\u5efa\u4e00\u4e2a\u7070\u5ea6\u53d1\u5e03\u73af\u5883")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7049696761858195486"},"ES6 \u4ee5\u4e0a\u7248\u672c\u4ee3\u7801\u8981\u4e0d\u8981\u8f6c\u7801\u6210 ES5 ?")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3TKcUeoyzXvH3MGVI6Dj9A"},"ESM \u4e0e CJS \u7684 Interop \u6765\u4e16\u4eca\u751f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/493891614/answer/2269197391"},"2022 \u524d\u7aef\u6280\u672f\u9886\u57df\u4f1a\u6709\u54ea\u4e9b\u65b0\u7684\u53d8\u5316\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000040496020"},"\u524d\u7aef\u6784\u5efa\u8fd9\u5341\u5e74"))),(0,n.kt)("h2",{id:"\u8f6f\u4ef6\u67b6\u6784--\u8bbe\u8ba1\u6a21\u5f0f"},"\u8f6f\u4ef6\u67b6\u6784 && \u8bbe\u8ba1\u6a21\u5f0f"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f Software Engineering at Google",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u5728\u7ebf\u9605\u8bfb\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://abseil.io/blog/04222021-swe-book"},"https://abseil.io/blog/04222021-swe-book")),(0,n.kt)("li",{parentName:"ul"},"PDF \u4e0b\u8f7d\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://github.com/garfield-dev-team/Frontend-Training-Program/blob/main/OReilly.Software.Engineering.at.Google.2020.3.pdf"},"https://github.com/garfield-dev-team/Frontend-Training-Program/blob/main/OReilly.Software.Engineering.at.Google.2020.3.pdf")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/wiseai/the-ultimate-guide-to-software-engineering-545e"},"The Ultimate Guide To Software Engineering")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145014659584622629"},"\u8bed\u96c0\u684c\u9762\u7aef\u6280\u672f\u67b6\u6784\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg"},"\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kFjfzwTOdaKA2ym63VR3DQ"},"\u63a2\u79d8\u5fae\u4fe1\u4e1a\u52a1\u4f18\u5316\uff1aDDD\u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/12BS4V6fvXkeb84XDpPnHw"},"\u4e86\u89e3\u5fae\u524d\u7aef\uff0c\u6df1\u5165\u524d\u7aef\u67b6\u6784\u7684\u524d\u4e16\u4eca\u751f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg"},"\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ocPx6Sw09ioDyz_IOWK69Q"},"\u5de5\u4f5c\u4e2d\u5e38\u89c1\u7684 6 \u79cd\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f60\u7528\u8fc7\u51e0\u79cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3MwRLM0jDmwv5l6gamFjcw"},"\u3010\u7b2c2757\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u768423\u4e2a\u57fa\u672c\u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iB23DV4hovPDdf5_4TCaOA"},"\u3010\u7b2c2677\u671f\u3011\u5982\u4f55\u5728React\u4e2d\u5e94\u7528SOLID\u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1h6yqCWyzYLM8WPGlGdtVA"},"\u3010\u7b2c2703\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw"},"\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ"},"\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/surfacew/fe/qg0uev"},"\u6df1\u5165\u6d45\u51fa\u524d\u7aef\u505a\u63a7\u5236\u53cd\u8f6c\u4e0e\u4f9d\u8d56\u6ce8\u5165")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw"},"javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iZ9BX6cCCp_TB-SC3knuew"},"\u5b9e\u6218\uff01\u5982\u4f55\u4ece\u96f6\u642d\u5efa10\u4e07\u7ea7 QPS \u5927\u6d41\u91cf\u3001\u9ad8\u5e76\u53d1\u4f18\u60e0\u5238\u7cfb\u7edf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg"},"\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SMAycMJPWr018sU04kbfbQ"},"\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1\u56db\u8bba")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BIYp9DNd_9sw5O2daiHmlA"},"\u4e07\u5b57\u957f\u6587\u52a9\u4f60\u4e0a\u624b\u8f6f\u4ef6\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1 DDD")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QCIlheiEgmU4Qi-4b_XoqQ"},"\u7528DDD(\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1)\u548cADT(\u4ee3\u6570\u6570\u636e\u7c7b\u578b)\u63d0\u5347\u4ee3\u7801\u8d28\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hsH7LMBEDGe_df9UbfOvbQ"},"\u540e\u53f0\u670d\u52a1\u67b6\u6784\u9ad8\u6027\u80fd\u8bbe\u8ba1\u4e4b\u9053")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://coolshell.cn/articles/21672.html"},"\u6211\u505a\u7cfb\u7edf\u67b6\u6784\u7684\u4e00\u4e9b\u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/m1Dv-YG60AKArGu-URr88w"},"\u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\u4e2d\u5982\u4f55\u505a\u597d\u6280\u672f\u51b3\u7b56\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4bB_B5JTOrev8mqfG7K2cw"},"\u524d\u7aef\u9886\u57df\u7684 \u201c\u5e72\u51c0\u67b6\u6784\u201d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/g9F05SRnQBTzzfx_2CKqhg"},"\u53ea\u4f1a\u7528\u4f20\u7edf\u5f00\u53d1\u6a21\u5f0f\uff1f10\u5206\u949f\u6559\u4f60\u73a9\u8f6c\u654f\u6377\uff01"))),(0,n.kt)("h2",{id:"\u6301\u7eed\u96c6\u6210"},"\u6301\u7eed\u96c6\u6210"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg"},"\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/445217118"},"\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064906701941506061"},"GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=fqMOX6JJhGo"},"Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"},"Best practices for writing Dockerfiles")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://docs.docker.com/engine/reference/builder/"},"Dockerfile reference")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903793348329486"},"\u5982\u4f55\u4f7f\u7528 docker \u90e8\u7f72\u524d\u7aef\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://shanyue.tech/op/docker.html"},"docker \u7b80\u6613\u5165\u95e8 - shanyue")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4aFJ7t37IwEMyq-u09Wf1g"},"\u5c0f\u9cb8\u9c7c\u7684\u524d\u4e16\u4eca\u751f--Docker")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/6844733746462064654/section/6844733746504007693"},"\u5f00\u53d1\u8005\u5fc5\u5907\u7684 Docker \u5b9e\u8df5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U-zK6JEMpmK2Il68-ijcaw"},"\u8c01\u8bf4\u524d\u7aef\u4e0d\u9700\u8981\u5b66\u4e60docker\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7028222480326066213"},"\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6951684431597797389"},"\u524d\u7aef\u5f00\u53d1\u8005\u5e94\u8be5\u77e5\u9053\u7684 Centos/Docker/Nginx/Node/Jenkins \u64cd\u4f5c(\ud83c\udf61 \u957f\u6587)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7049920990351982628"},"\u4fdd\u59c6\u7ea7\u6307\u5357\uff1ajekins+docker\u6784\u5efa\u90e8\u7f72react\u9879\u76ee\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6993951401952935972"},"\u4f60\u7684\u7b2c\u4e00\u4e2a Docker + React + Express \u5168\u6808\u5e94\u7528"))),(0,n.kt)("h2",{id:"\u670d\u52a1\u7aef\u76f8\u5173"},"\u670d\u52a1\u7aef\u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u63a8\u8350\u7b97\u6cd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GetU-ULhfvY8ri47Ht28GQ"},"\u56fe\u6587\u89e3\u8bfb\uff1a\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7cbe\u6392\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wXb5uQJBCzSEq6IITP7VCQ"},"\u8d85\u5f3a\u6307\u5357\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u91cd\u6392")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1wOnG4dtNSI-x2x15-AjTQ"},"\u8be6\u7ec6\u89e3\u8bfb\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u53ec\u56de")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YsK_8yyBNL5z269qT5CrIw"},"\u56fe\u6587\u5e76\u8302\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7c97\u6392")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153878508035391502"},"\u8be6\u89e3\u95f2\u9c7c\u63a8\u8350\u7cfb\u7edf\uff08\u957f\u6587\u6536\u85cf\uff09")))),(0,n.kt)("li",{parentName:"ul"},"Redis \u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/469102289"},"Redis\u8be6\u7ec6\u5165\u95e8\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fnOvw4JfwszNGVBMW0N2hw"},"Redis \u53ea\u4f1a\u7528\u7f13\u5b58\uff1f16\u79cd\u5999\u7528\u8ba9\u540c\u4e8b\u76f4\u547c\u725bX")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ThVtw8TVuhxIyYxJy6sOWw"},"\u6df1\u5165\u6d45\u51fa\u5e26\u4f60\u8d70\u8fdbRedis\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U87wrGsx0Eop3CbF9mlTwQ"},"\u4e07\u5b57\u56fe\u6587\u8bb2\u900f\u6570\u636e\u5e93\u7f13\u5b58\u4e00\u81f4\u6027\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vwx99ER-9qiH9nfwtFW1zQ"},"Redis \u4e8b\u52a1\u9047\u4e0a @Transactional \u6709\u5927\u5751\uff01\uff01\u8bb0\u4e00\u6b21 Redis \u751f\u4ea7\u4e8b\u6545")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw"},"Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw"},"\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147602740405862407"},"Redis \u6301\u4e45\u5316\u7b56\u7565\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dCZm7e0aSEirhEqiCBvAyQ"},"\u56fe\u6587\u7ed3\u5408\uff01Redis\u5ef6\u8fdf\u961f\u5217golang\u9ad8\u6548\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/frOhO8rj2Xvdix6tnjTOrw"},"\u7528 Redis \u90fd\u80fd\u5b9e\u73b0\u54ea\u4e9b\u529f\u80fd\uff1f\u8fd92\u4e07\u5b57+20\u5f20\u56fe\u7ed9\u5206\u6790\u5168\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mO819q_r9qLVuRBE8cjx1Q"},"\u5982\u4f55\u4fdd\u8bc1\u6570\u636e\u5e93\u548c\u7f13\u5b58\u53cc\u5199\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Cq-CF1BC4PWwGnlRp4HrnQ"},"\u4e3a\u4e86\u62ff\u634f Redis \u6570\u636e\u7ed3\u6784\uff0c\u6211\u753b\u4e86 40 \u5f20\u56fe\uff08\u5b8c\u6574\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124572920403197965"},"Redis 5 \u79cd\u57fa\u672c\u6570\u636e\u7ed3\u6784\uff08String\u3001List\u3001Hash\u3001Set\u3001Sorted Set\uff09\u8be6\u89e3 | JavaGuide")))),(0,n.kt)("li",{parentName:"ul"},"Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2Rwy19C0eUshTWc_JfTPig"},"Redis\u5206\u5e03\u5f0f\u9501\u768410\u4e2a\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/p2rlkCRRj7h7-aojTidQbg"},"\u6df1\u5165\u7406\u89e3 go singleflight")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ESdfA5sJa6bmL-HvuWpoJA"},"\u9762\u8bd5\u5b98\uff1a\u5982\u4f55\u7528 Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RS1kKvF_Ly576GV52bHQPg"},"\u5982\u4f55\u7528Redis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lrSQBK-Kihkj6994kQFpUQ"},"Go\uff1a\u5206\u5e03\u5f0f\u9501\u5b9e\u73b0\u539f\u7406\u4e0e\u6700\u4f73\u5b9e\u8df5")))),(0,n.kt)("li",{parentName:"ul"},"Web Server",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085519712901136392"},"\u8d85\u8d8a Nginx\uff01\u53f7\u79f0\u4e0b\u4e00\u4ee3 Web \u670d\u52a1\u5668\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")))),(0,n.kt)("li",{parentName:"ul"},"IO\u591a\u8def\u590d\u7528",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j1KjR5bRQV6oGrU5tsyHgg"},"\u4eceLinux\u96f6\u62f7\u8d1d\u6df1\u5165\u4e86\u89e3Linux-I/O")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5xj42JPKG8o5T7hjXIKywg"},"\u6df1\u5165\u5b66\u4e60IO\u591a\u8def\u590d\u7528 select/poll/epoll \u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg"},"\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3")))),(0,n.kt)("li",{parentName:"ul"},"\u7cfb\u7edf\u8bbe\u8ba1",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FJi3ko9wjTBNWS79RVQf5A"},"\u6280\u672f\u603b\u76d1\u5206\u4eab\u7684\u7cfb\u7edf\u8bbe\u8ba1\u6280\u5de7\uff0c\u4e07\u80fd\u901a\u7528\uff0c\u7a33\u7684\u4e00\u6279\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PPA8Iw6K2M2xVnGE-Tf6zw"},"\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1\u768415\u4e2a\u9526\u56ca")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5Jj-IClPhInXz7xsfUZEnQ"},"\u652f\u4ed8\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qhsVURhXm0Ot-jWq0khfEg"},"\u8682\u8681\u91d1\u670d\u4e00\u9762\uff1a\u5341\u9053\u7ecf\u5178\u9762\u8bd5\u9898\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ebh5iVsx0iExb5Wxq3tQFQ"},"\u516c\u53f8\u65b0\u6765\u4e00\u4e2a\u540c\u4e8b\uff0c\u628a\u4f18\u60e0\u5238\u7cfb\u7edf\u8bbe\u8ba1\u7684\u7089\u706b\u7eaf\u9752\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8GXe6sKPKk7Flbd_kNAp2Q"},"\u7f51\u5173\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/crzfBEGn78nUZ5H3MF8UZw"},"\u9ad8\u5e76\u53d1\u4e0b\uff0c\u5e42\u7b49\u6027\u5982\u4f55\u4fdd\u8bc1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw"},"Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Z0xVHgw-ZzZV-jOOOSsMUw"},"\u5982\u4f55\u8bbe\u8ba1\u4e00\u4e2a\u77ed\u94fe\u670d\u52a1")))),(0,n.kt)("li",{parentName:"ul"},"\u6d88\u606f\u961f\u5217",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/D8ptc4SCqWtaWe-ZBhwXfA"},"\u804a\u804aRocketMQ\u5b58\u50a8\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mNpXpSVVVBuI59LI6vVvQA"},"\u9762\u6e23\u9006\u88ad\uff1aRocketMQ\u4e8c\u5341\u4e09\u95ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GeXtCJgo42u92FSS5V6oMQ"},"\u5228\u6839\u95ee\u5e95 Kafka\uff0c\u6838\u5fc3\u77e5\u8bc6\u70b9\u5927\u8d2f\u901a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J0zKPTNoJgiFvNT4M9BVcg"},"\u6d88\u606f\u961f\u5217\u539f\u7406\u548c\u9009\u578b\uff1aKafka\u3001RocketMQ \u3001RabbitMQ \u548c ActiveMQ")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i_bwyEb8QqfVLxY-R9odag"},"\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u513f\u53eb MQ")))),(0,n.kt)("li",{parentName:"ul"},"Elasticsearch \u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7155662252584992805"},"MyBatis-Plus\u540c\u6b3eElasticsearch ORM\u6846\u67b6\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904117580595214"},"Elasticsearch\u5feb\u901f\u5165\u95e8\uff0c\u638c\u63e1\u8fd9\u4e9b\u521a\u521a\u597d\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GG_zrQlaiP2nfPOxzx_j9w"},"Elasticsearch \u57fa\u7840\u5165\u95e8\u8be6\u6587")))),(0,n.kt)("li",{parentName:"ul"},"\u5927\u6570\u636e\u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vua2g0_t1Y8KW4cNHSQdNw"},"\u4e00\u6587\u4e86\u89e3-\u4e91\u539f\u751f\u5927\u6570\u636e\u77e5\u8bc6\u5730\u56fe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7149487706991493156"},"\u3010\u4e91\u539f\u751f\u3011Hive on k8s \u73af\u5883\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7087484692718420005"},"\u5927\u6570\u636eHadoop\u4e4b\u2014\u2014\u6570\u636e\u4ed3\u5e93Hive")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7136214451678052389"},"\u3010\u4e91\u539f\u751f\u3011Kubernetes\uff08k8s\uff09\u6700\u5b8c\u6574\u7248\u73af\u5883\u90e8\u7f72+master\u9ad8\u53ef\u7528\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7141215211586863140"},"Flink \u6d41\u6279\u4e00\u4f53\u5728\u5b57\u8282\u8df3\u52a8\u7684\u63a2\u7d22\u4e0e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G66BCDUMzYE30p250JO0hg"},"\u5927\u6570\u636e\u67b6\u6784\u7cfb\u5217\uff1a\u5982\u4f55\u7406\u89e3\u6e56\u4ed3\u4e00\u4f53")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yQavfvBayYbMEc7c9ObMxg"},"23\u5f20\u56fe\uff0c\u5e26\u4f60\u5165\u95e8\u63a8\u8350\u7cfb\u7edf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gAhoIwPoFDlKbBmWzrHu8w"},"\u4e00\u6587\u770b\u61c2\u5927\u6570\u636e\u751f\u6001\u5708\u5b8c\u6574\u77e5\u8bc6\u4f53\u7cfb\uff08\u6587\u672b\u9001\u4e66\uff09")))),(0,n.kt)("li",{parentName:"ul"},"\u4e91\u539f\u751f\u76d1\u63a7",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/72UbwZTxo36eJVqGq8HBgw"},"\u81ea\u4ece\u9879\u76ee\u4e0a\u4e86SkyWalking\uff0c\u7761\u89c9\u771f\u9999\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/D1JoTzdQnzUgX_yqT3N1BQ"},"\u81ea\u4ece\u7ebf\u4e0a\u9879\u76ee\u7528\u4e86\u8fd9\u4e2a\u76d1\u63a7\u7cfb\u7edf\uff0c\u7761\u89c9\u771f\u9999\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bSw_QP4-xMKnBTmqAjkUGA"},"\u8fd8\u5728\u670d\u52a1\u5668\u4e0a\u635e\u65e5\u5fd7\uff1f\u5feb\u642d\u5efa\u4e00\u4e2aELK\u65e5\u5fd7\u7cfb\u7edf\u5427\uff0c\u771f\u5fc3\u5f3a\u5927\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg"},"\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01")))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hJHMlbQpANwMjx9BetwkUg"},"\u4e00\u81f4\u6027\u54c8\u5e0c\u7b97\u6cd5\u89e3\u51b3\u7684\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/482549860"},"\u4e00\u81f4\u6027Hash\u7b97\u6cd5\u539f\u7406\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA"},"100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l3l9d9sLiWoUM381E9o-3Q"},"\u89e3\u51b3\u4e86 Redis \u5927 key \u95ee\u9898\uff0c\u540c\u4e8b\u4eec\u90fd\u8bf4\u725b\u76ae\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l_YdpyHht5Ayvrc7LFZNIA"},"\u56fe\u89e3|Linux\u5185\u5b58\u80cc\u540e\u7684\u90a3\u4e9b\u795e\u79d8\u5f80\u4e8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064952956201730062"},"\u56fe\u89e3|\u4ec0\u4e48\u662f\u5185\u5bb9\u5206\u53d1\u7f51\u7edc(cdn)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7070683049049980941"},"\u4e00\u952e\u90e8\u7f72 K8S \u73af\u5883\uff0c10\u5206\u949f\u73a9\u8f6c\uff0c\u8fd9\u6b3e\u5f00\u6e90\u795e\u5668\u5b9e\u5728\u592a\u9999\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KIcn2TAwY58JGoWiz82Q2g"},"\u989c\u503c\u7206\u8868\uff01Redis \u5b98\u65b9\u53ef\u89c6\u5316\u5de5\u5177\u6765\u5566\uff0c\u529f\u80fd\u771f\u5fc3\u5f3a\u5927\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904017286561799"},"Nginx\u7684\u8fd9\u4e9b\u5999\u7528\uff0c\u4f60\u80af\u5b9a\u6709\u4e0d\u77e5\u9053\u7684\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064378702779891749"},"\u524d\u7aef\u5230\u5e95\u7528nginx\u6765\u505a\u5565")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7048952689601806366"},"\u4e00\u4efd\u7b80\u5355\u591f\u7528\u7684 Nginx Location \u914d\u7f6e\u8bb2\u89e3"))),(0,n.kt)("h2",{id:"\u524d\u7aef\u6027\u80fd\u4f18\u5316"},"\u524d\u7aef\u6027\u80fd\u4f18\u5316"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6981673766178783262"},"\u5199\u7ed9\u4e2d\u9ad8\u7ea7\u524d\u7aef\u5173\u4e8e\u6027\u80fd\u4f18\u5316\u76849\u5927\u7b56\u7565\u548c6\u5927\u6307\u6807 | \u7f51\u6613\u56db\u5e74\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Au_NNeamEoFEtlNvvVjpLw"},"\u524d\u7aef\u76d1\u63a7\u7cfb\u52173 \uff5c \u5982\u4f55\u8861\u91cf\u4e00\u4e2a\u7ad9\u70b9\u7684\u6027\u80fd\u597d\u574f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7052918009555320839"},"\u6700\u5168\u7684\u524d\u7aef\u6027\u80fd\u5b9a\u4f4d\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wJxj5QbOHwH9cKmqU5eSQw"},"Web\u9875\u9762\u5168\u94fe\u8def\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7016900744695513125"},"\u5b57\u8282\u8df3\u52a8\u662f\u5982\u4f55\u843d\u5730\u5fae\u524d\u7aef\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7048260643589193765"},"2022 \u5e74\u7684 CSS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7054931603323093022"},"\u5982\u4f55\u7f16\u5199\u9632\u5fa1\u5f0f\u7684 CSS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/396010993"},"\u524d\u7aef Code Review \u4e0d\u5b8c\u5168\u6307\u5317(\u4e07\u5b57\u957f\u6587\uff0c50+case)")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7020212914020302856"},"\u5199\u5728 2021 \u7684\u524d\u7aef\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7000728875676205086"},"\u6df1\u5165\u6d45\u51fa Performance \u5de5\u5177 & API")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6904582930174705677"},"\u4f7f\u7528 Performance \u770b\u770b\u6d4f\u89c8\u5668\u5728\u505a\u4ec0\u4e48"))),(0,n.kt)("h2",{id:"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218"},"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7120893568553582622"},"\u5feb\u4e0a\u8f66\uff01\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117886038126624805"},"\u4f7f\u7528Vite\u548cTypeScript\u5e26\u4f60\u4ece\u96f6\u6253\u9020\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684Vue3\u7ec4\u4ef6\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069772395610898462"},"\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904197863964685"},"\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021528826798669854"},"\u5c24\u5927\u90fd\u63a8\u8350\u7684\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u5f00\u53d1\u51fa\u6765\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6983854006124675108"},"\u6bcf\u4e2a\u524d\u7aef\u90fd\u503c\u5f97\u62e5\u6709\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff0c\u5c31\u50cf\u6bcf\u4e2a\u590f\u5929\u90fd\u62e5\u6709\u897f\u74dc\ud83c\udf49")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6930879590554402830"},"Vue3\u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218 --Element3"))),(0,n.kt)("h2",{id:"nodejs-\u7cfb\u5217"},"Node.js \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/koala-coding/goodBlog"},"\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/B051n14JbNHqJtQb68HBFA"},"Node.js \u6982\u8ff0\uff1a\u67b6\u6784\u3001API\u3001\u4e8b\u4ef6\u5faa\u73af\u3001\u5e76\u53d1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sSfj4BOjHNyzdjGc90yU8g"},"\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0a\u3011")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9SJL2UttCedNjF6CKyk3wg"},"\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0b\u3011")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6887961766170066951"},"\u5927\u5382\u662f\u5982\u4f55\u7528DevCloud\u6d41\u6c34\u7ebf\u5b9e\u73b0\u81ea\u52a8\u5316\u90e8\u7f72Web\u5e94\u7528\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6902659492161421325"},"\u624b\u628a\u624b\u6559\u4f60\u4f7f\u7528Rollup\u6253\u5305 \ud83d\udce6 \u5e76\u53d1\u5e03\u81ea\u5df1\u7684\u5de5\u5177\u5e93 \ud83d\udd27")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/461945753"},"Node \u6848\u53d1\u73b0\u573a\u63ed\u79d8 \u2014\u2014 \u672a\u5b9a\u4e49 \u201cwindow\u201d \u5bf9\u8c61\u5f15\u53d1\u7684 SSR \u5185\u5b58\u6cc4\u9732")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://cnodejs.org/topic/58eb5d378cda07442731569f"},"\u8f7b\u677e\u6392\u67e5\u7ebf\u4e0aNode\u5185\u5b58\u6cc4\u6f0f\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/36728655"},"Node.js \u6d41\uff08stream\uff09\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1DIDUvGoQcckRq757R9Ohw"},"\u6700\u5168\u9762\u7684 Node.js \u8d44\u6e90\u6c47\u603b\u63a8\u8350")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yKm_U9Veh_1twIoXzM8Prw"},"Nest.js\u8fdb\u9636\u7cfb\u5217\u56db\uff1aNode.js\u4e2d\u4f7f\u7528Redis\u539f\u6765\u8fd9\u4e48\u7b80\u5355\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TmCtsbhjexZNCdvUSXdNCw"},"Redis\u5b66\u4e60-\u5165\u95e8\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2CBGgtja04NnOerpKfk0Ug"},"Node.js \u5b89\u5168\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PhuFfNAhvXAqW4eSbUqpKQ"},"2022\u5e74\u503c\u5f97\u4f7f\u7528\u7684 Node.js \u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7095354780079357966"},"NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/502951532"},"Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/415361629"},"\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/unjs"},"unjs: Unified JavaScript Tools")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/vercel/pkg"},"pkg - \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/oclif/oclif"},"Oclif v2.5\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6961790494514872333"},"JavaScript Debugger \u539f\u7406\u63ed\u79d8")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xCoTeyJDifi4Ymk0VsI2Ig"},"\u6d45\u8c08 Node.js \u70ed\u66f4\u65b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7044344538969669663"},"NodeJS\u52a0\u89e3\u5bc6\u4e4bCrypto")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/google/zx"},"zx - \u8c37\u6b4c\u5f00\u53d1\u7684\u547d\u4ee4\u884c\u811a\u672c\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/node-fetch/node-fetch"},"node-fetch - node \u73af\u5883\u4e0b\u8fdb\u884c\u7f51\u7edc\u8bf7\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6971770846872338439"},"\u6d45\u6790 NodeJS \u591a\u8fdb\u7a0b\u548c\u96c6\u7fa4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/privatenumber/tasuku"},"Tasuku - \u9762\u5411 Node \u7684\u6700\u5c0f\u4efb\u52a1\u8fd0\u884c\u5668")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7008504029277847565"},"Node.js\u7684\u5e95\u5c42\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Gcx6E4cYo6WPB8PLI72NWg"},"\u8ba4\u771f\u5199\u4e86\u4e2a\u5feb\u901f\u521b\u5efa Node \u670d\u52a1\u7684CLI\uff0c\u770b\u770b\u5bf9\u5c0f\u4f19\u4f34\u4eec\u6709\u5e2e\u5fd9\u5417\uff1f"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u9879\u76ee\u5730\u5740\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://github.com/koala-coding/create-bff-service-cli"},"https://github.com/koala-coding/create-bff-service-cli"))))),(0,n.kt)(d,{mdxType:"Tabs"},(0,n.kt)(G,{value:"\u5f00\u6e90\u9879\u76ee",label:"\u5f00\u6e90\u9879\u76ee",default:!0,mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/antfu/taze"},"taze - \u66f4\u65b0\u4f9d\u8d56\u7248\u672c\u7684 CLI \u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/egoist/haya"},"haya - Vite \u7684\u66ff\u4ee3\u65b9\u6848\uff0c\u63d0\u4f9b\u57fa\u4e8e esbuild \u7684 devServer \u548c bundler")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/unjs/unbuild"},"unbuild - \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/egoist/tsup"},"tsup - \u96f6\u914d\u7f6e\u7684 TS \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/Rich-Harris/degit"},"degit - \u7b80\u5355\u7684\u9879\u76ee\u811a\u624b\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/streamich/react-use"},"react-use - \u4e00\u4e2a React Hooks \u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/tannerlinsley/react-query"},"react-query - \u7528\u4e8e\u83b7\u53d6\u6570\u636e\u3001\u7f13\u5b58\u3001\u5f02\u6b65\u66f4\u65b0\u72b6\u6001\u7684 hook")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/luin/ioredis"},"ioredis - \u4e13\u6ce8\u4e8e\u6027\u80fd\u7684\u5168\u529f\u80fd Redis \u5ba2\u6237\u7aef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/prisma/prisma"},"prisma - \u4e0b\u4e00\u4ee3 Nodejs ORM \u5de5\u5177\uff0c\u652f\u6301\u5404\u79cd\u6570\u636e\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/withastro/astro"},"astro - \u9759\u6001\u7ad9\u70b9\u6784\u5efa\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/pmndrs/zustand"},"zustand - \u5c0f\u578b\u3001\u5feb\u901f\u53ef\u6269\u5c55\u7684\u72b6\u6001\u7ba1\u7406\u89e3\u51b3\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/tauri-apps/tauri"},"tauri - \u5c06\u524d\u7aef\u9879\u76ee\u6253\u5305\u4e3a\u684c\u9762\u5e94\u7528\uff0c\u7528\u4e8e\u66ff\u4ee3 electron")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/trpc/trpc"},"tRPC - \u65b9\u4fbf\u5feb\u901f\u7684\u751f\u6210\u7aef\u5bf9\u7aef\u7c7b\u578b\u5b89\u5168\u7684 API \u5b9a\u4e49")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/MaxLeiter/Drift"},"Drift - \u4e00\u4e2a\u53ef\u4ee5\u81ea\u5df1\u90e8\u7f72\u7684\u4ee3\u7801\u7247\u6bb5\u670d\u52a1\uff0c\u57fa\u4e8e Next.js 13 \u6784\u5efa")))),(0,n.kt)(G,{value:"React \u751f\u6001",label:"React \u751f\u6001",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/bytedance/bytemd"},"bytemd - \u5b57\u8282\u51fa\u54c1\u7684 markdown \u7f16\u8f91\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/bytedance/guide"},"guide - \u5b57\u8282\u51fa\u54c1\u7684 React \u65b0\u624b\u5f15\u5bfc\u7ec4\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/rpearce/react-medium-image-zoom"},"react-medium-image-zoom - \u53d7 Medium.com \u542f\u53d1\u7684\u56fe\u7247\u9884\u89c8\u7ec4\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/pacocoursey/cmdk"},"cmdk - \u4e00\u4e2a\u57fa\u4e8e React \u7684\u5feb\u901f\u3001\u53ef\u7ec4\u5408\u3001\u65e0\u98ce\u683c\u7684\u547d\u4ee4\u9762\u677f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/eBay/nice-modal-react"},"nice-modal-react\uff1a\u6765\u81ea eBay \u7684\u6a21\u6001\u6846\u72b6\u6001\u7ba1\u7406")))),(0,n.kt)(G,{value:"\u6d4f\u89c8\u5668\u73af\u5883",label:"\u6d4f\u89c8\u5668\u73af\u5883",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/date-fns/date-fns"},"date-fns - \u73b0\u4ee3\u5316\u7684 JavaScript \u65e5\u671f\u7c7b\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/ai/nanoid"},"nanoid - \u7528\u4e8e\u66ff\u4ee3 uuid \u7684\u968f\u673a id \u751f\u6210\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"dayjs"),"\uff1a\u4e0e ",(0,n.kt)("inlineCode",{parentName:"li"},"moment")," \u7684 API \u8bbe\u8ba1\u4fdd\u6301\u4e00\u6837\uff0c\u4f46\u4f53\u79ef\u4ec5\u6709 2KB\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"qs"),"\uff1a\u89e3\u6790 URL query \u53c2\u6570\u7684\u5e93\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"js-cookie"),"\uff1a\u7b80\u5355\u3001\u8f7b\u91cf\u7684\u5904\u7406 cookie \u7684\u5e93\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"flv.js"),"\uff1abilibili \u5f00\u6e90\u7684 HTML5 flash \u64ad\u653e\u5668\uff0c\u4f7f\u6d4f\u89c8\u5668\u5728\u4e0d\u501f\u52a9 flash \u63d2\u4ef6\u7684\u60c5\u51b5\u4e0b\u53ef\u4ee5\u64ad\u653e flv\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"vConsole"),"\uff1a\u4e00\u4e2a\u8f7b\u91cf\u3001\u53ef\u62d3\u5c55\u3001\u9488\u5bf9\u624b\u673a\u7f51\u9875\u7684\u524d\u7aef\u5f00\u53d1\u8005\u8c03\u8bd5\u9762\u677f\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"animate.css"),"\uff1a\u4e00\u4e2a\u8de8\u6d4f\u89c8\u5668\u7684 css3 \u52a8\u753b\u5e93\uff0c\u5185\u7f6e\u4e86\u5f88\u591a\u5178\u578b\u7684 css3 \u52a8\u753b\uff0c\u517c\u5bb9\u6027\u597d\uff0c\u4f7f\u7528\u65b9\u4fbf\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"lodash"),"\uff1a\u4e00\u4e2a\u4e00\u81f4\u6027\u3001\u6a21\u5757\u5316\u3001\u9ad8\u6027\u80fd\u7684 JavaScript \u5b9e\u7528\u5de5\u5177\u5e93\uff1b"))),(0,n.kt)(G,{value:"\u5b9e\u7528\u5de5\u5177",label:"\u5b9e\u7528\u5de5\u5177",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/paulmillr/chokidar"},"chokidar - \u8de8\u5e73\u53f0\u76d1\u542c\u6587\u4ef6\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/jprichardson/node-fs-extra"},"fs-extra - Node \u539f\u751f fs \u6a21\u5757\u7684\u6269\u5c55")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"yargs"),"\uff1a\u901a\u8fc7\u4f7f\u7528 Node.js \u6784\u5efa\u529f\u80fd\u5168\u9762\u7684\u547d\u4ee4\u884c\u5e94\u7528"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"Ajv"),"\uff1a\u4e00\u4e2a\u9002\u7528\u4e8e Node.js \u548c\u6d4f\u89c8\u5668\u7684\u6700\u5feb JSON \u9a8c\u8bc1\u5668"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"yallist"),"\uff1a\u4e00\u4e2a\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"rimraf"),"\uff1aNode.js \u7684 rm -rf \u5b9e\u7528\u7a0b\u5e8f"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"consola"),"\uff1aNuxt.js \u51fa\u54c1\u7684\u7ec8\u7aef\u65e5\u5fd7\u5de5\u5177"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"webpackbar"),"\uff1aNuxt.js \u51fa\u54c1\u7684 webpack \u7f16\u8bd1\u8fdb\u5ea6\u6761"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"pkg"),": \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"concurrently"),"\uff1a\u66f4\u4f18\u96c5\u5730\u5e76\u53d1\u6267\u884c\u547d\u4ee4"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"better-logging"),"\uff1aNode \u9ed8\u8ba4\u65e5\u5fd7\u8bb0\u5f55\u65b9\u6cd5\u7684\u66ff\u4ee3\u54c1"))),(0,n.kt)(G,{value:"CLI \u5de5\u5177",label:"CLI \u5de5\u5177",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"chalk/kolorist")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"inquirer/prompts")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"ora")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"semver")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"pkg-install")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"ncp"),"\uff1a\u8de8\u5e73\u53f0\u9012\u5f52\u62f7\u8d1d\u6587\u4ef6"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"commander/yargs")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"execa"),"\uff08\u4e2a\u4eba\u89c9\u5f97 Node \u539f\u751f ",(0,n.kt)("inlineCode",{parentName:"li"},"child_process")," \u7684 ",(0,n.kt)("inlineCode",{parentName:"li"},"exec")," \u5c31\u591f\u7528\u4e86\uff09"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"minimist")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"oclif"),"\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6")))),(0,n.kt)("h2",{id:"\u524d\u7aef\u7f16\u8bd1"},"\u524d\u7aef\u7f16\u8bd1"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JMl8LOsNYlttxO-KyVK-Vw"},"\u3010\u7b2c2597\u671f\u3011\u5982\u4f55\u7528JavaScript\u5b9e\u73b0\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 - AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7041021350114230285"},"V8 \u7f16\u8bd1\u6d45\u8c08")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7057354419888717855"},"\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e8c\uff09\u2014\u2014 Antlr \u53ca\u5176\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6989509925844041742"},"\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e00\uff09\u2014\u2014 \u7f16\u8bd1\u539f\u7406\u57fa\u7840")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/6946117847848321055"},"Babel \u63d2\u4ef6\u901a\u5173\u79d8\u7c4d")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.zoo.team/article/the-process-of-executing-js-in-v8"},"v8 \u6267\u884c js \u7684\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://laocuicode.cn/daydream/2022/04/01/202241-%E7%A1%AC%E6%A0%B8%E5%86%B7%E7%9F%A5%E8%AF%86%EF%BC%9AWebAssembly/"},"\u786c\u6838\u51b7\u77e5\u8bc6\uff1aV8\u4e0eWebAssembly\u4e0d\u5f97\u4e0d\u8bf4\u7684\u79d8\u5bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7018563244679757855"},"import \u65b9\u5f0f\u968f\u610f\u4e92\u8f6c\uff0c\u611f\u53d7 babel \u63d2\u4ef6\u7684\u5a01\u529b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pNossFUtJrDHshXbWLb4vA"},"\u4ece\u96f6\u5230\u4e00\uff0c\u6211\u4eec\u6765\u4e00\u8d77\u9020\u4e2a JS \u7684\u7f16\u8bd1\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047329886502912030"},"\u6d45\u6790TypeScript Compiler \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6962861837800964133"},"\u300a\u4ece 0 \u5230 1 \u624b\u5199 babel\u300b\u601d\u8def\u5206\u4eab")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6953963506693570573"},"\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357"))),(0,n.kt)("h2",{id:"\u7f51\u7edc\u76f8\u5173"},"\u7f51\u7edc\u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/"},"HTTP/3 From A To Z: Core Concepts")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7155280646112280613"},"502\u95ee\u9898\u600e\u4e48\u6392\u67e5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153255870447484936"},"\u521a\u63d2\u4e0a\u7f51\u7ebf\uff0c\u7535\u8111\u600e\u4e48\u77e5\u9053\u81ea\u5df1\u7684IP\u662f\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147243567075819557"},"\u52a8\u56fe\u56fe\u89e3 | UDP\u5c31\u4e00\u5b9a\u6bd4TCP\u5feb\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126710506936598558"},"\u7528\u4e86TCP\u534f\u8bae\uff0c\u5c31\u4e00\u5b9a\u4e0d\u4f1a\u4e22\u5305\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nS1bMy2TejmGwEfCHPXy5A"},"HTTPS \u5c31\u4e00\u5b9a\u5b89\u5168\uff1f\u6211\u4e0d\u4fe1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fb2uUWz5ZjPEfYv_l6e4Zg"},"\u80fdping\u901a\uff0cTCP\u5c31\u4e00\u5b9a\u80fd\u8fde\u901a\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RJp9s_shNckkHBqHsJThuA"},"Linux \u662f\u5982\u4f55\u6536\u53d1\u7f51\u7edc\u5305\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7P_1VkBeoArKuuEqGcR9ig"},"\u5b57\u8282\u4e09\u9762\uff0c\u7b54\u7684\u4e0d\u6ee1\u610f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8CPWh_Ly61m8rkHvPT5n2g"},"\u4f53\u9a8c http3: \u57fa\u4e8e nginx quic \u5206\u652f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nRHlwYsr0MaadmaFWEIblQ"},"HTTP/3\u53d1\u5e03\u4e86\uff0c\u6211\u4eec\u6765\u8c08\u8c08HTTP/3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qmnfmUCdekEt1xG0hp_4MQ"},"\u65e2\u7136\u6709 HTTP \u534f\u8bae\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u6709 RPC")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3fMZN_LidCi5fiD16nNWWA"},"\u5b57\u8282\u4e00\u9762\uff1aTCP \u548c UDP \u53ef\u4ee5\u4f7f\u7528\u540c\u4e00\u4e2a\u7aef\u53e3\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg"},"\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hX75YxVOMtsnB6Sm_yjm0g"},"\u5b57\u8282\u4e00\u9762\uff1a\u5982\u4f55\u7528 UDP \u5b9e\u73b0\u53ef\u9760\u4f20\u8f93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw"},"TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904070889603085"},"(\u5efa\u8bae\u6536\u85cf)TCP\u534f\u8bae\u7075\u9b42\u4e4b\u95ee\uff0c\u5de9\u56fa\u4f60\u7684\u7f51\u8def\u5e95\u5c42\u57fa\u7840")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g"},"TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u63a8\u8350\u770b\u770b QUIC 101 \u89c6\u9891\u4ee5\u53ca ",(0,n.kt)("a",{parentName:"li",href:"https://courses.cs.washington.edu/courses/cse550/20au/papers/CSE550.quic.pdf"},"The QUIC transport protocol: design and Internet-scale deployment")," \u8bba\u6587"),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000024523772"},"\u4e00\u6587\u5f7b\u5e95\u641e\u61c2\u52a0\u5bc6\u3001\u6570\u5b57\u7b7e\u540d\u548c\u6570\u5b57\u8bc1\u4e66\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944420222757503006"},"\u4e00\u4e2aResponse Header\u5f15\u53d1\u7684\u8840\u6848(\u5305\u542bCDN\u7684\u76f8\u5173\u6982\u5ff5)"))),(0,n.kt)("h2",{id:"\u64cd\u4f5c\u7cfb\u7edf"},"\u64cd\u4f5c\u7cfb\u7edf"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/jlevy/the-art-of-command-line"},"The Art of Command Line")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA"},"\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/94F4v1E9sB82lOr2DeSK0A"},"Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ev8hnv-coGLobrbezMK1og"},"Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZralWEfG2WJfZ-G-x9biow"},"\u770b\u5b8c\u8fd9\u7bc7\u4f60\u4e00\u5b9a\u80fd\u638c\u63e1Linux")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6938385978004340744"},"2\u4e07\u5b57\u7cfb\u7edf\u603b\u7ed3\uff0c\u5e26\u4f60\u5b9e\u73b0 Linux \u547d\u4ee4\u81ea\u7531")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6917096816118857736"},"6w\u5b57\u641e\u5b9aLinux\u57fa\u672c\u64cd\u4f5c\uff0c\u5efa\u8bae\u6536\u85cf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904080972709901"},"\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6875323565479034894"},"\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5"))),(0,n.kt)("h2",{id:"\u673a\u5668\u5b66\u4e60"},"\u673a\u5668\u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u672c\u5730\u8fd0\u884c Stable Diffusion \u9884\u8bad\u7ec3\u6a21\u578b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nDnQuZn3hVgrwqWVada2cw"},"AI\u6570\u5b57\u7ed8\u753b stable-diffusion \u4fdd\u59c6\u7ea7\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://lexica.art/?q=fc98f231-c95f-4a68-8727-899c73dbc486"},"https://lexica.art/?q=fc98f231-c95f-4a68-8727-899c73dbc486")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://huggingface.co/CompVis/stable-diffusion-v1-4"},"https://huggingface.co/CompVis/stable-diffusion-v1-4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/CompVis/stable-diffusion"},"https://github.com/CompVis/stable-diffusion")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://huggingface.co/blog/stable_diffusion"},"https://huggingface.co/blog/stable_diffusion")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146575333721341966"},"\u4e0d\u4f1a\u7b97\u6cd5\u4e5f\u80fd\u5fae\u8c03\u4e00\u4e2a NLP \u9884\u8bad\u7ec3\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BcXl8YQVNQA6auilbxW0kQ"},"\u4eba\u5de5\u795e\u7ecf\u7f51\u7edc\u7b97\u6cd5\u5165\u95e8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gaOzwCypQMFAJ4X50aUOcg"},"\u6d45\u6790\u795e\u7ecf\u7f51\u7edc Neural Networks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7075518863814869005"},"\u524d\u7aef\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u4f7f\u7528\u4e00\u4e2aNLP\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u6df1\u5165\u7406\u89e3 Transformer\uff1a",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1P4411F77q"},"https://www.bilibili.com/video/BV1P4411F77q")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Mt411J734"},"https://www.bilibili.com/video/BV1Mt411J734")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1cD4y1D7uR"},"\u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b- bilibili")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1mb4y1d7K7"},"\u300a\u8ba1\u7b97\u673a\u7f51\u7edc\u81ea\u9876\u5411\u4e0b\u65b9\u6cd5\u300b- bilibili"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u8fd9\u672c\u4e66\u91cd\u70b9\u7ae0\u8282\u662f\u7b2c2\u30013\u30014\u30015\u30016\u7ae0\uff0c\u5176\u4ed6\u7ae0\u8282\u53ef\u4ee5\u8df3\u8fc7"))),(0,n.kt)("li",{parentName:"ul"},"\u5b66\u4e60\u8d44\u6e90",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ossu/computer-science"},"https://github.com/ossu/computer-science")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/Snailclimb/JavaGuide"},"https://github.com/Snailclimb/JavaGuide")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/QSCTech/zju-icicles"},"https://github.com/QSCTech/zju-icicles")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Vt411z7wy"},"\u4e00\u5929\u5b66\u4f1a MySQL \u6570\u636e\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1FT4y1E74V"},"\u5434\u6069\u8fbe\u300a\u6df1\u5ea6\u5b66\u4e60\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1qK4y1479r"},"\u63a8\u8350\u7cfb\u7edf\u7b97\u6cd5\u57fa\u7840+\u7efc\u5408\u9879\u76ee\u5b9e\u6218"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u518d\u5c31\u662f\u4e00\u4e9b\u6211\u8ba4\u4e3a\u5f88\u4f18\u79c0\u7684\u5f00\u6e90\u9879\u76ee\uff1a"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/zhongqiangwu960812/AI-RecommenderSystem"},"https://github.com/zhongqiangwu960812/AI-RecommenderSystem")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ZiyaoGeng/Recommender-System-with-TF2.0"},"https://github.com/ZiyaoGeng/Recommender-System-with-TF2.0")))),(0,n.kt)("li",{parentName:"ul"},"\u53c2\u8003\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YbwQAPIEkihO7XzVvrlDCg"},"\u4e07\u5b57\u5165\u95e8\u63a8\u8350\u7cfb\u7edf\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7013674501116264484"},"\u8bf4\u4e00\u8bf4Web\u7aef\u4fa7AI")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6964335363787620383"},"\u673a\u5668\u5b66\u4e60\u521d\u63a2-\u7ebf\u6027\u56de\u5f52")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6951340421658181646"},"\u673a\u5668\u5b66\u4e60\u8fdb\u9636 - \u6df1\u5165\u601d\u8003\u903b\u8f91\u56de\u5f52"))),(0,n.kt)("h2",{id:"llm-\u6280\u672f\u8c03\u7814"},"LLM \u6280\u672f\u8c03\u7814"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Fo26NbtK8wFiHEGP0nhzuQ"},"\u4f7f\u7528 Transformers \u91cf\u5316 Meta AI LLaMA2 \u4e2d\u6587\u7248\u5927\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9cTNa_oya2Zj9YdDYodCvw"},"\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u4e2d\u6587\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NJ1JXkAK9LTSuor0mxtz1A"},"\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u5b98\u65b9\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iKtNOWkycm0FcMwnwq2M-A"},"AI \u52a0\u6301\u7684\u4ee3\u7801\u7f16\u5199\u5b9e\u6218\uff1a\u5feb\u901f\u5b9e\u73b0 Nginx \u914d\u7f6e\u683c\u5f0f\u5316\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/o-6Xg1f7SMX-BUFgXgwb8w"},"\u8ba9 OpenAI \u66f4 Open\uff0c\u5728 ChatGPT \u91cc\u81ea\u7531\u63a5\u5165\u6570\u636e\u6e90")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Qo1--bFCzdNHAdesshrUuQ"},"\u516b\u5341\u884c\u4ee3\u7801\u5b9e\u73b0\u5f00\u6e90\u7684 Midjourney\u3001Stable Diffusion \u201c\u5492\u8bed\u201d\u4f5c\u56fe\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vH5zkdQ9esiMeg3L9TYgvw"},"\u6a21\u578b\u6742\u8c08\uff1a1.5G \u663e\u5b58\u5c31\u80fd\u8fd0\u884c\u7684 RNN 14B \u7684\u5f00\u6e90\u6a21\u578b\uff08ChatRWKV\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cVR9yYP8zDiVBPEo91dSSA"},"\u4f7f\u7528 Docker \u548c Alpaca LoRA \u5bf9 LLaMA 65B \u5927\u6a21\u578b\u8fdb\u884c Fine-Tune")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6Ae6SgEws5gndQwmZqkcUg"},"\u57fa\u4e8e Docker \u7684\u6df1\u5ea6\u5b66\u4e60\u73af\u5883\uff1a\u5165\u95e8\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6oKORqZWX7IlQFI5zbLKCw"},"\u6a21\u578b\u6742\u8c08\uff1a\u4f7f\u7528 IN8 \u91cf\u5316\u63a8\u7406\u8fd0\u884c Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vc4t7sm-BhAYtE7_J8DekQ"},"\u6a21\u578b\u6742\u8c08\uff1a\u5feb\u901f\u4e0a\u624b\u5143\u5b87\u5b99\u5927\u5382 Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YKzWBa9kGbzwUpy2iuPjNA"},"RSS Can\uff1a\u501f\u52a9 V8 \u8ba9 Golang \u5e94\u7528\u5177\u5907\u52a8\u6001\u5316\u80fd\u529b\uff08\u4e8c\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UO6_L_oVe3-ocOyt6R_YTA"},"\u5728\u642d\u8f7d M1 \u53ca M2 \u82af\u7247 MacBook\u8bbe\u5907\u4e0a\u73a9 Stable Diffusion \u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_1AZ5U27JOkEaCUkAuZADQ"},"Linux \u8f6f\u4ef6\u5305\u4e0b\u8f7d\u52a0\u901f\u5de5\u5177\uff1aAPT Proxy")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/e0x7BR2PwkTk9JWdr2hg-w"},"\u8f7b\u91cf\u9ad8\u53ef\u7528\u7684 K8s \u96c6\u7fa4\u642d\u5efa\u65b9\u6848\uff1aMicroK8s")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8MppGs90WWP5sMlHFX2EUQ"},"\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f7f\u7528 Docker \u548c Milvus \u5feb\u901f\u6784\u5efa\u672c\u5730\u8f7b\u91cf\u56fe\u7247\u641c\u7d22\u5f15\u64ce")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pVYPpYRPjq7BUCahParVvw"},"\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u5165\u95e8\u5411\u91cf\u6570\u636e\u5e93 Milvus \u7684 Docker \u5de5\u5177\u955c\u50cf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/F0YgDChHceNoOPFstnBv3Q"},"\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f20\u7edf\u6587\u672c\u68c0\u7d22\u65b9\u5f0f\u7684\u964d\u7ef4\u6253\u51fb\uff0c\u4f7f\u7528 Faiss \u5b9e\u73b0\u5411\u91cf\u8bed\u4e49\u68c0\u7d22"))),(0,n.kt)("h2",{id:"java-\u76f8\u5173"},"Java \u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA"},"100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1Xe16FaHWfihYjqMVWidQg"},"\u539f\u521b\u7cbe\u9009\u835f\u8403\uff082022.05.11\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j1U4L06y2-8z2fSJypGG7w"},"\u652f\u4ed8\u5b9d\u4e00\u9762\uff1a\u5982\u4f55\u57fa\u4e8eRedis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/va75wKPBtpp2ceL25SkIVA"},"Jenkins+Docker \u5b9e\u73b0\u4e00\u952e\u81ea\u52a8\u5316\u90e8\u7f72\u9879\u76ee\uff01\u6b65\u9aa4\u9f50\u5168\uff0c\u5c11\u8d70\u5751\u8def\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/njeXqkHiIsXneBholN72OQ"},"\u4e24\u4e07\u5b57\u8be6\u89e3\uff01Netty\u7ecf\u517832\u8fde\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/409QGKe5H7tCP1qpCiY_KA"},"\u4e24\u4e07\u5b57\u76d8\u70b9\u8bbe\u8ba1\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J0C9TJF7nVVi2cMiDBqepA"},"\u5b9e\u6218\uff0c\u5b9e\u73b0\u5e42\u7b49\u76848\u79cd\u65b9\u6848\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Jct2rnz_0ahozWNZYfZ4Qg"},"\u5199\u4f18\u96c5\u4ee3\u7801\u768445\u4e2a\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PzZ31ju32-5epXpQeTZsNA"},"\u809d\u4e86\u4e00\u5468\u603b\u7ed3\u7684SpringBoot\u5e38\u7528\u6ce8\u89e3\u5927\u5168\uff0c\u770b\u5b8c\u5c31\u7089\u706b\u7eaf\u9752\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rSYOAuJeIXaonHvuR5O47Q"},"\u77a7\u77a7\u4eba\u5bb6\u5199\u7684API\u63a5\u53e3\u4ee3\u7801\uff0c\u90a3\u53eb\u4e00\u4e2a\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P017RfO8TDL5LxGzBoTLSA"},"SpringBoot \u5b9e\u73b0 Excel \u5bfc\u5165\u5bfc\u51fa\uff0c\u6027\u80fd\u7206\u8868\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SG9sNmMu9acB1xTODkG00Q"},"\u8fd8\u5728\u7528HttpUtil\uff1fSpringBoot 3.0\u5168\u65b0HTTP\u5ba2\u6237\u7aef\u5de5\u5177\u6765\u4e86\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ezLN8AzVhBaeMdNMK-TS-g"},"\u5999\u7528Java 8\u4e2d\u7684 Function\u63a5\u53e3\uff0c\u6d88\u706dif...else\uff08\u975e\u5e38\u65b0\u9896\u7684\u5199\u6cd5\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/20LjD3_nJYvZrTNo4tqjvA"},"\u522b\u518d\u7528 if \u6821\u9a8c\u53c2\u6570\u4e86\uff0c\u592aLow\uff01\u8fd9\u624d\u662f\u4e13\u4e1a\u7684 SpringBoot \u53c2\u6570\u6821\u9a8c\u65b9\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg"},"\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA"},"\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg"},"\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FX2umO7XCCmj8Bke7uKDZw"},"11\u79cd\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Va4eoL5xizJasnSUbvvccw"},"\u8fd9\u4e9b\u5e76\u53d1\u7f16\u7a0b\u77e5\u8bc6\uff0c\u4e00\u5b9a\u8981\u77e5\u9053")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EVgd689xdOX732hdOxPqcw"},"\u8fd910\u79cd\u795e\u7ea7\u6027\u80fd\u4f18\u5316\u624b\u6bb5\uff0c\u4f60\u7528\u8fc7\u51e0\u4e2a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VStQWv_ehN8RFDxpoAnKmg"},"\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ"},"MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/29xlEK2N_Wptl4TBMg1ZPQ"},"\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\u4e4b Spring IOC")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/T1toQ7NeHQKqof9A0o-99g"},"76 \u5f20\u56fe\uff0c\u5256\u6790 Spring AOP \u6e90\u7801\uff0c\u5c0f\u767d\u5c45\u7136\u4e5f\u80fd\u770b\u61c2\uff0c\u5927\u795e\uff0c\u8bf7\u6536\u4e0b\u6211\u7684\u819d\u76d6\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n8iw_33Wwr9i0mWEXMG6-A"},"\u4f7f\u7528 lambda \u5b9e\u73b0\u8d85\u5f3a\u7684\u6392\u5e8f\u529f\u80fd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/e_uJhaGj4HO1iTS_zCoCXw"},"\u4e07\u5b57\u957f\u6587\uff0cSpringSecurity\u5b9e\u73b0\u6743\u9650\u7cfb\u7edf\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J_11wYusexAjwa1cuckyfw"},"1.2w+\u5b57\uff01Java IO \u57fa\u7840\u77e5\u8bc6\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7js2uDZNv2Pb55ihKPc1xg"},"\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/djVu6SJjfYj4y_LNW-SKyw"},"\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\uff0cSpring \u5982\u4f55\u89e3\u51b3\u5faa\u73af\u4f9d\u8d56")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hhjwiMx-ypEbxwHJ9rJoBw"},"\u9ebb\u4e86\uff0c\u4ee3\u7801\u6539\u6210\u591a\u7ebf\u7a0b\uff0c\u7adf\u67099\u5927\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ioDYZjdSii3WUvL9xqc_Sg"},"\u522b\u518d\u4e71\u6253\u65e5\u5fd7\u4e86\uff0c\u8fd9\u4efd Java \u65e5\u5fd7\u89c4\u8303\uff0c\u5e94\u6709\u5c3d\u6709\uff0c\u5efa\u8bae\u6536\u85cf\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zn4TDT4Vl_MobqNkW1m-jw"},"\u804a\u804aSpringBoot\u5355\u5143\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4Sxal7N-uZ8gvphC8XWo8A"},"\u603b\u76d1\u53c8\u6765\u4e86\uff0c\u4eba\u72e0\u8bdd\u4e0d\u591a\uff0c\u8fd9\u7bc7 gRPC\uff0c\u5c0f\u5f1f\u4f69\u670d\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vqKKoPB5FQkCWXFWBLbkZg"},"\u817e\u8baf\u4e00\u9762\uff1aThread\u3001Runnable\u3001Callable\u3001Future\u3001FutureTask\uff0c\u8c08\u8c08\u4ed6\u4eec\u7684\u5173\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rlfRjCb8EOrpt3xnF7isBw"},"\u62dc\u6258\uff01\u9762\u8bd5\u8bf7\u4e0d\u8981\u518d\u95ee\u6211 @Transactional")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YcyC1Jm4H7uGvSg3rCkDig"},"7 \u6bb5\u5c0f\u4ee3\u7801\uff0c\u73a9\u8f6cJava\u7a0b\u5e8f\u5e38\u89c1\u7684\u5d29\u6e83\u573a\u666f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ua03qsLcrVURtxhSnuU_6w"},"\u5355\u4f8b\u6a21\u5f0f 4 \u79cd\u7ecf\u5178\u5b9e\u73b0\u65b9\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/mu_wind/article/details/118423362"},"ElasticSearch\u8fdb\u9636\uff1a\u4e00\u6587\u5168\u89c8\u5404\u79cdES\u67e5\u8be2\u5728Java\u4e2d\u7684\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031047868806873096"},"\u4f7f\u7528 @Transactional \u65f6\u5e38\u72af\u7684N\u79cd\u9519\u8bef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6984974277573836830"},"Spring Boot 2.x\u57fa\u7840\u6559\u7a0b\uff1a\u4f7f\u7528@Scheduled\u5b9e\u73b0\u5b9a\u65f6\u4efb\u52a1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007642025264676871"},"Spring Boot\u4e2d\u4f7f\u7528@Async\u5b9e\u73b0\u5f02\u6b65\u8c03\u7528\uff0c\u52a0\u901f\u4efb\u52a1\u7684\u6267\u884c\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/CodingDocs/awesome-idea"},"IDEA \u9ad8\u6548\u4f7f\u7528\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fuzhengwei/CodeGuide"},"CodeGuide | \u7a0b\u5e8f\u5458\u7f16\u7801\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fuzhengwei/small-spring"},"\ud83c\udf31 Spring \u624b\u64b8\u4e13\u680f - \u6613\u5b66\u3001\u597d\u5199\u3001\u80fd\u61c2\uff01"))),(0,n.kt)("h2",{id:"mysql-\u5b66\u4e60"},"MySQL \u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"MySQL \u4e13\u680f",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G8fWBvZPy6yxAyggwwx1NA"},"\u7530\u87ba\u54e5\u7684MySQL\u4e13\u680f\uff0125\u7bc7\uff0c\u771f\u9999\uff01")))),(0,n.kt)("li",{parentName:"ul"},"\u8868\u7ed3\u6784\u8bbe\u8ba1",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3yHSh7djpeeYZkajkTGFKg"},"\u63a8\u8350\u4e00\u6b3eSQL\u81ea\u52a8\u68c0\u67e5\u795e\u5668\uff0c\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3SQL\u51fa\u9519\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sSsZ-w6WzjA_DLZfnsxD2w"},"21\u4e2aMySQL\u8868\u8bbe\u8ba1\u7684\u7ecf\u9a8c\u51c6\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7136126923851169823"},"\u804a\u804a\u6570\u636e\u5e93\u5efa\u8868\u768415\u4e2a\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904142733836301"},"\u6211\u7528\u8d77\u6765\u987a\u624b\u7684\u6570\u636e\u5e93\u8bbe\u8ba1\u5de5\u5177\uff0c\u8fd9\u6b21\u63a8\u8350\u7ed9\u5927\u5bb6\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7108525565157589005"},"\u6570\u636e\u5e93\u8868\u7ed3\u6784\u8bbe\u8ba1\u4e00\u70b9\u5fc3\u5f97\u548c\u7ecf\u9a8c")))),(0,n.kt)("li",{parentName:"ul"},"\u6162 SQL \u4f18\u5316",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SBKlxcTK_kZf0s5CRtIEBA"},"SQL\u4f18\u531613\u8fde\u95ee\uff0c\u6536\u85cf\u597d\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Pi_SLqs3lwA7vWcT6lVv5g"},"\u7f8e\u56e2\u9762\u8bd5\uff1a\u8fd9\u4e2a SQL \u8bed\u53e5\u52a0\u4e86\u54ea\u4e9b\u9501")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8X-MuPgS-o53XZywqi_dmA"},"\u4e13\u5751\u540c\u4e8b\u7684SQL \u5c31\u8fd9\u4e48\u5199\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0_Arz-KO3UqJij1s4DjLNw"},"\u5b8c\u720690%\u7684\u6027\u80fd\u6bdb\u75c5\uff0c\u6570\u636e\u5e93\u4f18\u5316\u516b\u5927\u901a\u7528\u7edd\u62db\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3H9SD1dnAH0RoN-RoPXxgQ"},"\u516c\u53f8\u65b0\u6765\u4e2a\u540c\u4e8b\uff0cMyBatis\u6279\u91cf\u63d2\u516510w\u6761\u6570\u636e\u4ec5\u75282\u79d2\uff0c\u62cd\u6848\u53eb\u7edd\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OBjRKdGzwFM4PNrbMd7kIA"},"\u4e00\u6b21\u663e\u8457\u7684\u5927\u8868\u67e5\u8be2\u4f18\u5316\uff0c\u4ece20s\u4f18\u5316\u5230500ms\uff0c\u67e5\u8be2\u5206\u79bbYYDS\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UxZRGO58kTiX5wUnuzMJ9Q"},"MySQL\u8868\u592a\u5927\uff0ccount(*)\u90fd\u80fd 502\uff0c\u600e\u4e48\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/exPgSB0MNUnu0wMkThET1w"},"\u8fd915\u4e2aSQL\u4f18\u5316\u53e3\u8bc0\uff0c\u5de5\u4f5c\u9762\u8bd5\u90fd\u591f\u7528\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KegqAAvI4KxDffforTQqKA"},"\u4fdd\u59c6\u7ea7\u6559\u7a0b\uff012 \u4e07\u5b57 + 30 \u5f20\u56fe\u641e\u61c2 MySQL \u662f\u600e\u4e48\u52a0\u884c\u7ea7\u9501\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DZbAq9fpPxElhfJCkY53GA"},"\u4e24\u4e07\u5b57\u8be6\u89e3\uff01InnoDB\u9501\u4e13\u9898\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BbrLQWGYlkXiy6t4YANj0Q"},"SQL\u4f18\u5316\u601d\u8def+\u7ecf\u5178\u6848\u4f8b\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N3te_fVBeqhjIpl25N6kpA"},"MySQL \u5355\u8868\u4e0d\u8981\u8d85\u8fc7 2000W \u884c\uff0c\u9760\u8c31\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l3jJHIcqMzCcezbpboqyvQ"},"explain | \u7d22\u5f15\u4f18\u5316\u7684\u8fd9\u628a\u7edd\u4e16\u597d\u5251\uff0c\u4f60\u771f\u7684\u4f1a\u7528\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EVzU7KW9d5_254Kg4LZYQQ"},"MySQL \u4f18\u5316\uff1aExplain \u6267\u884c\u8ba1\u5212\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3jrf1GKBBbVzcvJxqYnx9Q"},"\u8fd911\u6761\u63a5\u53e3\u6027\u80fd\u4f18\u5316\u6280\u5de7\uff0c\u5229\u597d\u6bcf\u65e5\u7761\u7720")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Y1Mh-99cgQWuCQ53wAxkUQ"},"\u987a\u4e30\u5feb\u9012\uff1a\u8bf7\u7b7e\u6536MySQL\u7075\u9b42\u5341\u8fde")))),(0,n.kt)("li",{parentName:"ul"},"MySQL \u4e8b\u52a1",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pkJb_9mddmdYaJZ8azHSsg"},"\u56fe\u89e3MySQL\u4e8b\u52a1\u5e95\u5c42\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KEbuoasD_DOHRJiSqUgzzA"},"MySQL\u4e8b\u52a1\u768412\u8fde\u95ee\uff0c\u4f60\u9876\u5f97\u4e86\u561b")))),(0,n.kt)("li",{parentName:"ul"},"MySQL \u7d22\u5f15",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d3iC_Iokrjdn392I0Y53Og"},"MySQL\u7d22\u5f1515\u8fde\u95ee\uff0c\u6297\u4f4f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sqW51yqeAXcDs9r84UFP7A"},"\u8ddf\u5927\u5bb6\u804a\u804a MySQL \u4e00\u884c\u8bb0\u5f55\u662f\u600e\u4e48\u5b58\u50a8\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yvgB1a2o-m3_EBLePZM8cw"},"\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u53ebB+\u6811")))),(0,n.kt)("li",{parentName:"ul"},"MySQL \u65e5\u5fd7",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Tfbd-KiBgsZtkiuVc70BFA"},"\u804a\u804a MySQL \u65e5\u5fd7\uff0c\u597d\u725b\u7684\u8bbe\u8ba1\uff01")))),(0,n.kt)("li",{parentName:"ul"},"\u5206\u5e93\u5206\u8868",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cZ7mUsCvBxmo1dzsPA3WjQ"},"\u5206\u5e93\u5206\u8868\u7ecf\u517815\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AjVl-0u3plmL9U77h0VVJw"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u5206\u5e93\u5206\u8868\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wYXs7gsID8a9ahJKsWXJ6w"},"\u518d\u6709\u4eba\u95ee\u4f60\u4ec0\u4e48\u662f\u5206\u5e93\u5206\u8868\uff0c\u76f4\u63a5\u628a\u8fd9\u7bc7\u6587\u7ae0\u53d1\u7ed9\u4ed6")))),(0,n.kt)("li",{parentName:"ul"},"\u810f\u8bfb\u3001\u4e0d\u53ef\u91cd\u590d\u8bfb\u3001\u5e7b\u8bfb",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VWEKgnOWVnufz5pfvRjUWw"},"\u7f8e\u56e2\u4e09\u9762\uff1a\u4e00\u76f4\u8ffd\u95ee\u6211\uff0c MySQL \u5e7b\u8bfb\u88ab\u5f7b\u5e95\u89e3\u51b3\u4e86\u5417")))),(0,n.kt)("li",{parentName:"ul"},"\u6570\u636e\u4e00\u81f4\u6027",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VEU5p85aTvyBKf2XP5QTSg"},"\u6570\u636e\u5e93\u9501\u768412\u8fde\u95ee\uff0c\u6297\u4f4f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/shogIDEgXTtPVPFgsS8crw"},"\u804a\u804aselect for update\u5230\u5e95\u52a0\u4e86\u4ec0\u4e48\u9501")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw"},"\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lyqvv-nA_PMUc-eBuCsNTA"},"\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg"},"\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7104507830522085383"},"\u804a\u804a\u5206\u5e03\u5f0f\u9501")))),(0,n.kt)("li",{parentName:"ul"},"ORM \u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R2yqW3kfesK-T5oZR2Vl2w"},"MyBatis \u8fde\u73af 20 \u95ee\uff0c\u4f60\u80fd\u7b54\u5bf9\u51e0\u4e2a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ"},"MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6850037271233331208"},"MySQL \u4e09\u4e07\u5b57\u7cbe\u534e\u603b\u7ed3 + \u9762\u8bd5100 \u95ee\uff0c\u548c\u9762\u8bd5\u5b98\u626f\u76ae\u7ef0\u7ef0\u6709\u4f59\uff08\u6536\u85cf\u7cfb\u5217\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vRI-bFB4_IEaoCCQcMqZjw"},"\u660e\u660e\u52a0\u4e86\u552f\u4e00\u7d22\u5f15\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u662f\u4ea7\u751f\u91cd\u590d\u6570\u636e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/O6sgYSpXBPwAA4Qcstj-BA"},"\u4e92\u8054\u7f51\u516c\u53f8\u90fd\u600e\u4e48\u5b9e\u73b0\u5206\u9875\u7684\uff0c\u62ff MySQL \u4f7f\u52b2Limit")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cdc1NCSkvAU4Urk2wVFDMw"},"MySQL\u593a\u547d66\u95ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/L9qseWiHGfu1oAuKIhcUhw"},"\u4e00\u6b21 MySQL \u8bef\u64cd\u4f5c\u5bfc\u81f4\u7684\u4e8b\u6545\uff0c\u300c\u9ad8\u53ef\u7528\u300d\u90fd\u9876\u4e0d\u4f4f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Inocu3vjMG4ivE19HrxR3g"},"\u867e\u76ae\u4e8c\u9762\uff1aMySQL \u4e2d\u6709\u54ea\u4e9b\u9501\uff1f\u8868\u7ea7\u9501\u548c\u884c\u7ea7\u9501\u6709\u4ec0\u4e48\u533a\u522b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Jhh-_5ynu58EKPMignk5fA"},"\u9762\u9738\u7bc7\uff1aMySQL\u516d\u5341\u516d\u95ee\uff0c\u4e24\u4e07\u5b57+\u4e94\u5341\u56fe\u8be6\u89e3\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101581835527782414"},"\u6162SQL\u5206\u6790\u4e0e\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r91hINCgCYJDNHLMeaba8Q"},"Mysql\u6570\u636e\u5e93\u67e5\u8be2\u597d\u6162\uff0c\u9664\u4e86\u7d22\u5f15\uff0c\u8fd8\u80fd\u56e0\u4e3a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8OOSyFB9pzoBMH73ey7YmQ"},"MySQL \u4e3b\u4ece\uff0c6 \u5206\u949f\u5e26\u4f60\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N08tFkGyXtmBSN0nS6S6UA"},"\u5927\u5382\u9762\u8bd5\u9898\uff1a\u65e5\u5e38\u5de5\u4f5c\u5982\u4f55\u505aMySQL\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i8SHizPrBMQ2GIhQP7ozRw"},"Mysql\u5b8c\u7ed3\u6c47\u603b\u7bc7\uff0818W\u5b57\u9001\u7ed9\u5927\u5bb6\uff09\uff0c\u5b8c\u7ed3\u6492\u82b1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7081456994413969445"},"\u9762\u8bd5\u5b98\uff1a\u4ec0\u4e48\u662fMySQL \u4e8b\u52a1\u4e0e MVCC \u539f\u7406\uff1f"))),(0,n.kt)("h2",{id:"golang-\u5b66\u4e60"},"Golang \u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Golang \u5b66\u4e60\u8def\u7ebf",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/xiaobaiTech/golangFamily/blob/main/README.md"},"Go\u540e\u7aef\u5f00\u53d1\u6210\u957f\u8def\u7ebf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7119123646471208968"},"\u300aGo\u5b66\u4e60\u8def\u7ebf\u56fe\u300b\u5e26\u4f60\u5c11\u8d70\u5f2f\u8def\uff0cLet's Go \uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7176518080674136121"},"\u6700\u5168\u7684Go\u8d44\u6599\u6c47\u603b\u548c\u6700\u8d70\u5fc3\u7684\u5b66Go\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147939014870302756"},"\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7035966042857799687"},"\u6211\u809d\u4e86\u4e09\u4e2a\u6708\uff0c\u4e3a\u4f60\u5199\u51fa\u4e86GO\u6838\u5fc3\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7061980386640789540"},"Go \u5b66\u4e60\u8def\u7ebf\uff082022\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV16E411H7og"},"Golang\u5b66\u4e60\u624b\u518c\u4e4b\uff1a\u5e26\u4f6021\u5468\u641e\u5b9aGo\u8bed\u8a00")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=YS4e4q9oBaU"},"Learn Go Programming - Golang Tutorial for Beginners")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u8fdb\u9636",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/danielfurman/presentations/blob/master/lets-go-generic/README.md"},"Golang \u6cdb\u578b\u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1ry4y1y7V2"},"GopherCon UK 2018- Florin Patan - Production Ready Go Service in 30 Minutes")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r4IWY6bzKph2QvxrKZszPA"},"\u4f5c\u4e3aGopher\uff0c\u4f60\u77e5\u9053Go\u7684\u6ce8\u91ca\u5373\u6587\u6863\u5e94\u8be5\u600e\u4e48\u5199\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ne0uir1hpMokBUItntkfvw"},"31\u4e2a\uff01Golang\u5e38\u7528\u5de5\u5177\u6765\u5566\uff08\u5efa\u8bae\u6536\u85cf\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Mj-EqwYWZBMr8XNIHxUqDA"},"Golang\u4f9d\u8d56\u6ce8\u5165\u63d0\u5347\u5f00\u53d1\u6548\u7387\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VFS4TWi3OpeAegScZ4cJRw"},"Go\u8bed\u8a00\u4ece0\u52301\u5b9e\u73b0\u6700\u7b80\u5355\u7684\u6570\u636e\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/--ciEa-Oj0NEUxlp1Af_aQ"},"\u5fc5\u64b8\u7cfb\u5217\uff01Go\u53e6\u5916\u51e0\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7\u6c47\u603b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8HNZQrQ2oqMB2fAYbmH2Ow"},"\u6765\u4e86\uff01Go\u76842\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Zb5zGOy_mdalUQ_Qy0HngQ"},"3\u79cd\u65b9\u5f0f\uff01Go Error\u5904\u7406\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OCpVRwtiphFRZgu9zdae5g"},"Go\u7ec4\u4ef6\uff1acontext\u5b66\u4e60\u7b14\u8bb0\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NkSyv7iDSZsLhMUgAi-r4w"},"\u4e0d\u5f97\u4e0d\u77e5\u9053\u7684Golang\u4e4bsync.Map\u89e3\u8bfb\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XHbfPtUzkUTGF06Ao4jQYA"},"\u8d85\u5168\u907f\u5751\u6307\u5357: \u76d8\u70b9 Go \u7684\u5e38\u89c1\u5178\u578b\u9519\u8bef")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/56tth8PSquB1eR5-1XaDWA"},"\u9e45\u5382\u540e\u53f0\u5927\u4f6c\u6559\u4f60Go\u5185\u5b58\u7ba1\u7406\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QBZ1dp0XIqMo24vVFYf1fA"},"\u5168\u9762\u89e3\u8bfb\uff01Golang\u4e2d\u6cdb\u578b\u7684\u4f7f\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/niLk_n9Yp-iyl_RIie3Umw"},"\u8d85\u5e72\u8d27\uff01\u5f7b\u5e95\u641e\u61c2Golang\u5185\u5b58\u7ba1\u7406\u548c\u5783\u573e\u56de\u6536")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BPcRI0BHBLmuYfzvP10Wvw"},"\u5173\u4e8eGo\u5e76\u53d1\u7f16\u7a0b\uff0c\u4f60\u4e0d\u5f97\u4e0d\u77e5\u7684\u201c\u5de6\u8180\u53f3\u81c2\u201d\u2014\u2014\u5e76\u53d1\u4e0e\u901a\u9053\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aoR_69JMBN5ZM10DKqRCyQ"},"\u5b83\u6765\u4e86\uff0c\u5173\u4e8eGolang\u5e76\u53d1\u7f16\u7a0b\u7684\u8d85\u8be6\u7ec6\u6559\u7a0b\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/POZGQXsYu5aWXvu29vSM8g"},"\u901a\u4fd7\u6613\u61c2\uff01\u56fe\u89e3Go\u534f\u7a0b\u539f\u7406\u53ca\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DpCFUAYpvMzd6138Yp_JUA"},"\u62d2\u7edd\u5343\u7bc7\u4e00\u5f8b\uff0c\u8fd9\u5957Go\u9519\u8bef\u5904\u7406\u7684\u5b8c\u6574\u89e3\u51b3\u65b9\u6848\u503c\u5f97\u4e00\u770b\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_VGaV8ef65h9goxxfWejtQ"},"go\u8bed\u8a00\u6700\u5168\u4f18\u5316\u6280\u5de7\u603b\u7ed3\uff0c\u503c\u5f97\u6536\u85cf\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fXKSr8GXaYxG1WCrLIgneg"},"\u518d\u4e0dGo\u5c31\u6765\u4e0d\u53ca\u4e86\uff01Go\u9ad8\u6027\u80fd\u7f16\u7a0b\u6280\u6cd5\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XrJVpErmP8wIjd_byCCmhA"},"\u817e\u8baf 13 \u5e74\uff0c\u6211\u6240\u603b\u7ed3\u7684Code Review\u7ec8\u6781\u5927\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AMv5IVBPU2lAY_qUwskk4g"},"Go\u4e0eC\u7684\u6865\u6881\uff1aCGO\u5165\u95e8\u5256\u6790\u4e0e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tN27osC6K0NM-Laj9MbtsA"},"Golang \u6c47\u7f16\u5165\u95e8\u77e5\u8bc6\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VMzhyySny60zABnxlzlVjQ"},"Golang\u9ad8\u6027\u80fd\u7f16\u7a0b\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GwXQwJUdBi1UHdh2Q8FBMw"},"\u6572\u9ed1\u677f\uff01\u9e45\u5382\u7a0b\u5e8f\u5458\u9762\u8bd5\u4e5f\u8003\u4e86\u8fd9\u4e9b\u7b97\u6cd5\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JkpzM06IWNb11wUaJWJn8Q"},"Java\u4e0eGo\u5230\u5e95\u5dee\u522b\u5728\u54ea\uff0c\u8c01\u8981\u88ab\u65f6\u4ee3\u629b\u5f03")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/T4tk-sckA1oNcWIvp27MMA"},"\u770b\u4e86\u8fd9\u7bc7\u4f60\u4f1a\u53d1\u73b0\uff0c\u4f60\u662f\u61c2Go\u5185\u5b58\u5206\u914d\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SLouDICt3HABv_wh-sSqKw"},"Go \u5b9e\u6218\u6280\u5de7\uff1a\u907f\u514d\u5185\u5b58\u5206\u914d\u7684\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aIuta8Lr0govruPTgglw2w"},"\u901a\u8fc7\u4e00\u4e2a\u4f8b\u5b50\u8ba9\u4f60\u5f7b\u5e95\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_duDs0oHc_z_p--3OoIfVw"},"Go\u7684\u65b9\u6cd5\u63a5\u6536\u8005\uff1a\u503c\u63a5\u6536\u8005\u4e0e\u6307\u9488\u63a5\u6536\u8005")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157594175846744071"},"\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/94thx36Ao2PYQ-8Cbto-wQ"},"\u7a0b\u5e8f\u5458\u5e94\u8be5\u9075\u5b88\u7684\u7f16\u7a0b\u539f\u5219(\u4e0d\u6b62Gopher\u54e6)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ"},"\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UqjSA2i3s1VoLFACt_EL2A"},"Go 1.18\u65b0\u7279\u6027\u524d\u77bb\uff1a\u539f\u751f\u652f\u6301Fuzzing\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PBTP4vnwEXtrtsHdq0oL0g"},"\u5982\u4f55\u5e94\u5bf9\u4e0d\u65ad\u81a8\u80c0\u7684\u63a5\u53e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pCcNtUykXAwb-BN_prPGpA"},"\u6bcf\u4e2a gopher \u90fd\u9700\u8981\u4e86\u89e3\u7684 Go AST")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xzNqpRbIvoJygSWeQJFjTw"},"\u4e00\u6587\u641e\u61c2Go\u6807\u51c6\u5e93context\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/E4lT4SuWKIlCZd60i7vigQ"},"\u4f7f\u7528\u53cd\u5c04\u64cd\u4f5cchannel")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/z75HDSlX0PLCnvL5kAcSDw"},"Go 1.20\u65b0\u7279\u6027\u524d\u77bb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg"},"Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MRBEJHZBMS9s0w7UhseQWA"},"2022\u5e74Go\u8bed\u8a00\u76d8\u70b9\uff1a\u6cdb\u578b\u843d\u5730\uff0c\u65e0\u8da3\u5f88\u597d\uff0c\u7a33\u5b9a\u4e3a\u738b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HbFVODpDEzEZ047kv-LYbg"},"Go1.20 \u65b0\u7279\u6027\uff1acontext\u652f\u6301\u81ea\u5b9a\u4e49\u53d6\u6d88\u539f\u56e0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NtBzM8l54HRVSpapKR_0sg"},"\u804a\u804aGo\u4e0eTLS 1.3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CFwiFw00ah0rfdZyv_ppxw"},"\u5c06Roaring Bitmap\u5e8f\u5217\u5316\u4e3aJSON")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Y-JxePxv9XlaX_UASlWSvQ"},"\u4e07\u5b57\u957f\u6587\u544a\u8bc9\u4f60Go 1.20\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6_ygmyd64LP7rlkrOh-kRQ"},"\u4e00\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u5224\u65adGo\u63a5\u53e3\u53d8\u91cf\u662f\u5426\u76f8\u7b49")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WDw-Y8Rp4VxAa2iPKRnKKg"},"\u5c0f\u5382\u5185\u90e8\u79c1\u6709Go module\u62c9\u53d6\u65b9\u68483")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r5gIVtyBWtD7UQncK_JPNQ"},"Go\u662f\u4e00\u95e8\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8bed\u8a00\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5zoNwCWnNNunrDtu6cokqg"},"\u4e00\u6587\u641e\u61c2Go subtest")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ypK-2wGHGj9_n4o8y-clXg"},"\u804a\u804agodoc\u3001go doc\u4e0epkgsite")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MI9x4YOAhbtS-xQtOS-K_A"},"\u804a\u804aGo\u8bed\u8a00\u7684\u5168\u5c40\u53d8\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8yLt0Sh18VF5ApTcuxV-Sg"},"Go\u5f00\u53d1\u547d\u4ee4\u884c\u7a0b\u5e8f\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RKshV1hu61wabq4am906PA"},"\u4f7f\u7528go test\u6846\u67b6\u9a71\u52a8\u7684\u81ea\u52a8\u5316\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0TnAPFib82KC-BIL-uhMWw"},"\u4e00\u6587\u544a\u8bc9\u4f60\u54ea\u4e9bmap element\u7c7b\u578b\u652f\u6301\u5c31\u5730\u66f4\u65b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EHSR-GFPJy5RzVDgcvoTog"},"\u7406\u89e3unsafe-assume-no-moving-gc\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PwSJQM7WmJeLnDDbCr78hg"},"Go 1.21\u65b0\u7279\u6027\u524d\u77bb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FcuXy0Vqp6aczKpNpQeFrA"},"Go\uff1a\u503c\u4e0e\u6307\u9488")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IEsgLu5PFwcKppUWABA6-Q"},"Go\u9879\u76ee\u7ec4\u7ec7\uff1a\u5728\u5355\u4e00repo\u4e2d\u7ba1\u7406\u591a\u4e2aGo module\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/D_CVrPzjP3O81EpFqLoynQ"},"\u4e00\u6587\u641e\u61c2Go\u9519\u8bef\u94fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/18SbYmKnUbNR59gFlKEULQ"},"Go\u4e0e\u795e\u7ecf\u7f51\u7edc\uff1a\u5f20\u91cf\u8fd0\u7b97")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2P9_nyrdZ3JqlKRIR8--7g"},"\u804a\u804aGo\u8bed\u8a00\u7684\u63a7\u5236\u8bed\u53e5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J3hIbUaAp55l8QDuJYUQOg"},"Go\u8bed\u8a00\u53cd\u5c04\u7f16\u7a0b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-EAH8jjj4uy1LCr_9C1ghg"},"The State Of Go 2023")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_xA6bhKTm543i3QV8EZMSg"},"Go\u8bed\u8a00\u5305\u8bbe\u8ba1\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dyQ3WBMPF2DyaI8Dlgy8Gw"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u7c7b\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JWg8yW_lDiZQCk6bKZ5TeA"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u5185\u5b58\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WgeTzhP4T0AAjFssHz36UA"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Lxxfeqn70rfmnrGvgrxevA"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u64cd\u4f5c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xBpA36wpmbO85LIHlaTXBg"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6269\u5c55compute\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LppX2mvbkgsLKkqqudehQA"},"\u4f7f\u7528testify\u5305\u8f85\u52a9Go\u6d4b\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PcNpQJcKuWpZgYrKmVvRLQ"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u8bfb\u5199Parquet\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4UI6gTx7ZWRPhGbm4YGGCQ"},"Gopher Daily\u6539\u7248\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZaDNxyewtrSuiLRF62ipYg"},"Go\u9879\u76ee\u521d\u59cb\u5316\u4e0d\u518d\u56f0\u6270\u4f60\uff1agonew\u5168\u65b9\u4f4d\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3bfD9LPBB5zA9VxAv920Cw"},"Go 1.21\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/snVLySXv4E5xMlbD153FcQ"},"\u7f16\u8bd1Go\u5e94\u7528\u7684\u9ed1\u76d2\u6311\u6218\uff1a\u65e0\u6e90\u7801\u53ea\u6709.a\u6587\u4ef6\uff0c\u4f60\u80fd\u641e\u5b9a\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4HN0-m8AlzSmDCuF9hYU4Q"},"slog\u6b63\u5f0f\u7248\u6765\u4e86\uff1aGo\u65e5\u5fd7\u8bb0\u5f55\u65b0\u9009\u62e9\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7jS6E6d578QQIxvWKSux1Q"},"slog\u5b9e\u6218\uff1a\u6587\u4ef6\u65e5\u5fd7\u3001\u8f6e\u8f6c\u4e0ekafka\u96c6\u6210")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NzUXgDd7qPMK4LxIopcFLA"},"\u804a\u804aGo\u8bed\u8a00\u7684\u5411\u524d\u517c\u5bb9\u6027\u548ctoolchain\u89c4\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vY76-34hm-ujgaGTS_lDaQ"},"\u4f7f\u7528Go\u548cWebRTC data channel\u5b9e\u73b0\u7aef\u5230\u7aef\u5b9e\u65f6\u901a\u4fe1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2ibzE46UVnO_YNtugikpPQ"},"\u4e86\u89e3go\u5728\u534f\u7a0b\u8c03\u5ea6\u4e0a\u7684\u6539\u8fdb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J3Sfo9u63aTG6IndFP-BnQ"},"\u4e00\u7ad9\u5f0fGolang\u5185\u5b58\u6d17\u9ad3\u7ecf","[","Go\u4e09\u5173\u5178\u85cf\u7248","]")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9MfIdUdBZmfqbUYT_xrB8A"},"\u6df1\u5165\u7406\u89e3Golang\u534f\u7a0b\u8c03\u5ea6GPM","[","Go\u4e09\u5173\u5178\u85cf\u7248","]")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/up1MHqYW_v_C4P6AY-sW3w"},"Golang\u4e09\u8272\u6807\u8bb0\u6df7\u5408\u5199\u5c4f\u969cGC\u6a21\u5f0f\u5168\u5206\u6790","[","Go\u4e09\u5173\u5178\u85cf\u7248","]")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/veu5W0BFmLIZ-yvs39NdUw"},"\u4e3a\u4ec0\u4e48\u6cdb\u578b\u4f7f\u4f60\u7684\u7a0b\u5e8f\u53d8\u6162")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XojOIIZfKm_wXul9eSU1tQ"},"Go error \u5904\u7406\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mrAwE-go0vNSwrJ4g4L9Cg"},"\u5f00\u901a\u4e2a\u4eba\u535a\u5ba2\u5566\uff01\u9644\u5e26\u5168\u90e8 Hexo + Nginx + Git \u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gMjQmNvEi1o_iOFt2z7flg"},"\u975e\u5e7f\u544a| DDD \u5230\u5e95\u662f\u94f6\u5f39\u8fd8\u662f\u5783\u573e")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yEbqNo9UfPTCxL5-RDvlPw"},"\u7ed9\u9762\u8bd5\u5b98\u4e00\u70b9\u5c0f\u5c0f\u7684 gpt \u9707\u64bc")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AaHk-yg8D4atbO-zVAvhKQ"},"Go \u8bed\u8a00 GC \u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XR1KAeCW930i-Qxv6N2kaA"},"\u52a8\u6001\u8c03\u6574 GOGC \u4f18\u5316 Go \u7684 GC \u6807\u8bb0 CPU \u5360\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/T7IBCimzmWI07dHD8NA-Qw"},"\u804a\u804a rust trait")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/A4m1xlFwh9pD0qy3p7ItSA"},"Gopher \u9700\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7ed3\u6784\u4f53\u9a9a\u64cd\u4f5c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sYQ0vqKiIWaUCha740Dxtw"},"Go \u670d\u52a1\u7aef\u5f00\u53d1\uff0c\u8bf7\u7262\u8bb0\u8fd9\u51e0\u6761")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8xTtSoLvAcE1u_jWw9I-Eg"},"\u503c\u5f97\u6536\u85cf\u8c03\u5ea6\u5668\u7cfb\u5217\uff1a\u5077\u5929\u6362\u65e5 \u2014 g0 \u6808\u548c\u7528\u6237\u6808\u5982\u4f55\u5b8c\u6210\u5207\u6362\uff1f\uff08\u56db\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5E5V56wazp5gs9lrLvtopA"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff081\uff09\u2014\u2014\u8c03\u5ea6\u7684\u672c\u8d28")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WWfm7Ui7g_gGlb8XkIZigg"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff082\uff09\u2014\u2014 \u8ff7\u60d1\u7684 goroutine \u6267\u884c\u987a\u5e8f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2Y3qPkysRLaWDcIyLOerZg"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff083\uff09\u2014\u2014 \u5982\u4f55\u7528\u6c47\u7f16\u6253\u540c\u4e8b\u7684\u8138")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8R9ZLa0Xlscw6qhl-5g2Cg"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0810\uff09\u2014\u2014 \u5982\u4f55\u7ed9 Go \u63d0\u6027\u80fd\u4f18\u5316\u7684 pr")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SGv5vuh9aU2mqViC4Kj0YQ"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0811\uff09\u2014\u2014 \u4ece map \u7684 extra \u5b57\u6bb5\u8c08\u8d77")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RmEtL869Sd-FjB_73tFSaw"},"\u300e\u66f9\u5927\u5e26\u6211\u5b66 Go \u300f\u7cfb\u5217\u6587\u7ae0\u6c47\u603b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IEunJaXMfrOfPmounloYig"},"Go map \u7adf\u7136\u4e5f\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ujWkFUqJiY3DCWeKZeS8uw"},"\u5185\u8054\u51fd\u6570\u548c\u7f16\u8bd1\u5668\u5bf9Go\u4ee3\u7801\u7684\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VnF7YrXTaK5MASacXgzRhw"},"\u6df1\u5ea6\u9605\u8bfb\u4e4b\u300a100 Go Mistakes and How to Avoid Them\u300b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U5Okkf9FzLxxSYcsUI2DZg"},"kafka producer \u5728 aws \u53c8\u6302\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Bl3UrbgiMMsP3gxm6vnDtA"},"\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e00)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j59HejHj5hzKovfsGdrIdg"},"\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e8c)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UIeIBtC9MZJh3w-EphWHiA"},"Gopher \u5e94\u8be5\u8bb0\u4f4f\u8fd9 10 \u4e2a\u547d\u4ee4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HPzoclfCB3UxLScXm4J83w"},"\u6709\u8da3\u7684 Go HttpClient \u8d85\u65f6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2V3VSsAJH5haWqdvVJ9e8g"},"\u6211\u5982\u4f55\u7528\u4e24\u884c\u4ee3\u7801\u8282\u7701\u4e8630%\u7684CPU")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YzkPHkBCdqv-Z3APSPaDrQ"},"Go 1.19 \u4e2datomic\u5305\u7684\u65b0\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EIuM073G7VV1rIsnTXWyEw"},"\u7b49\u7b49\uff0c \u600e\u4e48\u4f7f\u7528 SetMemoryLimit")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sSwXgrHvQcjSuiy9bA8d_g"},"\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/S4FDRve0YPtRUixY4kPqAQ"},"\u554a\u54c8\uff0c\u4e00\u9053\u6709\u8da3\u7684Go\u5e76\u53d1\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VtDR2uJ8SQ2jiIS2o2uyfA"},"\u8fd8\u548b\u4f18\u5316\uff1f\u6211\u662f\u8bf4Go\u7a0b\u5e8f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/chPDWyBibBlvcEKKENFYGg"},"\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e00\u7bc7\uff1a\u7efc\u8ff0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hXfZImBUYTBe2JvhBD-OmA"},"\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e8c\u7bc7\uff1aGo\u8bed\u8a00\u4e2d\u7684\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EAk_LdlfYGwaiDDj9CgqHA"},"\u4e00\u4e9b\u5173\u4e8e\u65f6\u95f4\u548c\u5b9a\u65f6\u4efb\u52a1\u7684\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kSZieI3zE9RgvfAqEQEhbw"},"\u6ca1\u7528\u5fae\u670d\u52a1\uff0cShopify\u7684\u5355\u4f53\u7a0b\u5e8f\u5c45\u7136\u652f\u6491\u4e86127\u4e07/\u79d2\u7684\u8bf7\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8omJxT10c5UX6Neua9dLjA"},"\u673a\u667a\uff01\u751f\u62a0\u5185\u5efamap\u7684\u54c8\u5e0c\u51fd\u6570")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KTmMWyULYMS0LFsg69zwZg"},"\u50cf\u95ea\u7535\u4e00\u6837\u5feb\u901f\u626b\u63cf\u5168\u7f51\u7684IP\u5730\u5740")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KzMmzd2ZfAJwtHt4s-V0zQ"},"\u6bcf\u79d2\u767e\u4e07\u7ea7\u522b\u7684\u5305\u4f20\u8f93\uff0c\u6211\u662f\u8bf4CPU\u4f7f\u7528\u7387\u51e0\u4e4e\u4e3a\u96f6\u90a3\u79cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sVLOFBdL6a_1pOBFP8pSfw"},"\u4f7f\u7528\u5e95\u5c42\u7684syscall.Socket\u5b9e\u73b0\u7f51\u7edc\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uwdL6QjLIG6SbMKeb2HOAw"},"\u4f7f\u7528Go\u8bed\u8a00\u5b9e\u73b0ping\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1Nv5_b2jM9uiG0tEu1Pr1A"},"\u51e0\u79cd\u4f7f\u7528Go\u53d1\u9001IP\u5305\u7684\u65b9\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/C2AmKZjg9CyiIDxyU0-b1Q"},"\u600e\u4e48\u963b\u6b62\u4e00\u4e2aGo\u7a0b\u5e8f\u9000\u51fa")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SFXe1bdBu0bLuHoGEFTz8g"},"Go 1.21\u4e2d sync.Once\u7684\u65b0\u6269\u5c55")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mKraN_3xUfy6Bm-SswHEbw"},"\u6539\u9020! \u8ba9 sync.Map \u652f\u6301\u6cdb\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/26PlfCFLc9Giuv_7nmgxjg"},"\u4e00\u4e2a\u6cdb\u578b\u7684\u6709\u5e8fGo Map\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aC7omLYJ6Anm9f-8b4qYAg"},"MPTCP: \u4e00\u4e2a\u5728 Go 1.21\u4e2d\u7684\u88ab\u5ffd\u7565\u7684\u65b0\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Sv-SXDYxea_K_TtiI_CjTw"},"Go\u53ef\u4ee5\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f46\u7edd\u4e0d\u662f\u300a\u8bbe\u8ba1\u6a21\u5f0f\u300b\u4e2d\u7684\u90a3\u6837")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/325iHPhAQicbSN6-pb05rw"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5de5\u5382\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jXaCLkagT-cKbVHConcadg"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5efa\u9020\u8005\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NQOmlQfFpM-asN9I9CeVkw"},"\u5355\u4f8b\u6a21\u5f0f\u548c\u60f0\u6027\u521d\u59cb\u5316\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R1bPyZBMWizcfuwQv0-t8Q"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u539f\u578b\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/p5lv_yTUbxsNYDmZiIpGTw"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5bf9\u8c61\u6c60\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zVVl_R0WbP6AUcav5ys6tQ"},"\u539f\u578b\u6a21\u5f0f\u8865\u9057 - Go\u8bed\u8a00\u4e2d\u7684\u6df1\u5ea6\u62f7\u8d1d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KYlY-WFNpYirvcRiyaeVXw"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u9002\u914d\u5668\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MiACdPNOhnXRoysRX2VBVA"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u8d44\u6e90\u83b7\u53d6\u5373\u521d\u59cb\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hgFvoopT7DZoGUqHiurTeQ"},"Go 1.21 \u4e2d\u7684\u6cdb\u578b\u63a8\u65ad")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1cIcrObMP5xG_UsMUatETw"},"mping: \u4f7f\u7528\u65b0\u7684icmp\u5e93\u5b9e\u73b0\u63a2\u6d4b\u548c\u538b\u6d4b\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SSkt6YYGcqgH9kbIQH-tNg"},"PGO: \u4e3a\u4f60\u7684Go\u7a0b\u5e8f\u63d0\u65485%")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/M0WFAQtoCd1aEZHjxTyjMw"},"\u6df1\u5165\u7406\u89e3 PromQL")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5XMmVqdcji8jpRnC2p0F3w"},"\u4ec0\u4e48\u662f Go runtime.KeepAlive")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gc34RYqmzeMndEJ1-7sOwg"},"\u6027\u80fd\u4f18\u5316 | Go Ballast \u8ba9\u5185\u5b58\u63a7\u5236\u66f4\u52a0\u4e1d\u6ed1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lE83EZ7eztjEWd_NU796YQ"},"gin \u6e90\u7801\u9605\u8bfb(5) - \u7075\u6d3b\u7684\u8fd4\u56de\u503c\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2OI9vh_LGPxtGkhF-AnWDA"},"gin \u6e90\u7801\u9605\u8bfb(4) - \u53cb\u597d\u7684\u8bf7\u6c42\u53c2\u6570\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PldVh8Wk6oxCFIcWVx3hrQ"},"gin \u6e90\u7801\u9605\u8bfb(3) - gin \u8def\u7531\u7684\u5b9e\u73b0\u5256\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d9kP77eKRm2MSW_9ySlVGA"},"\u89c1\u5fae\u77e5\u8457| \u5e26\u4f60\u900f\u8fc7\u5185\u5b58\u770b Slice \u548c Array\u7684\u5f02\u540c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mrCQyw_dR5VYzf8ejyvHfA"},"Goland \u8fd9\u4e9b\u5b9e\u64cd\u6280\u5de7\uff0c\u4f60\u53ef\u80fd\u8fd8\u4e0d\u4f1a\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gmKi3bE99K6bXVGcMFz53w"},"\u8fd9\u4e9b Goland \u6280\u5de7\uff0c\u5b66\u4f1a\u5f00\u53d1\u6548\u7387\u7ffb\u500d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lMvU80jhkabMvqXeTFiDnw"},"Go interface \u539f\u7406\u5256\u6790--\u7c7b\u578b\u8f6c\u6362")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MQWZOkaAc4Bw-PmYHyd9SA"},"\u5feb\u6536\u85cf\uff01\u6700\u5168Go\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NrUWfpyfzX4sag22qF-Y-Q"},"\u5feb\u6536\u85cf\uff01\u6700\u5168GO\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\u3010\u4e0b\u3011")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i1N9bmVSW1lGfOezvhcD7g"},"\u6df1\u5165\u7406\u89e3 golang \u7684\u4e92\u65a5\u9501")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rETmci7xvzf5X9_liS0Hmg"},"Go 1.20\u65b0\u53d8\u5316\uff01\u7b2c\u4e00\u90e8\u5206\uff1a\u8bed\u8a00\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UQwOJVqm5gnQPMgSE3MW9w"},"[","\u8bd1","]","Uber \u7684 Go\u8bed\u8a00\u5f00\u53d1\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w"},"\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uWhmvBk_MN23RjmfjkxqeQ"},"\u4ece\u9e45\u5382\u5b9e\u4f8b\u51fa\u53d1\uff01\u5206\u6790Go Channel\u5e95\u5c42\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vB9ElJCfgZeQHtB596XHpA"},"Go \u670d\u52a1\u81ea\u52a8\u6536\u96c6\u7ebf\u4e0a\u95ee\u9898\u73b0\u573a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gLbAZShFnkPcI937pk-wpg"},"\u7528\u89c4\u5219\u5f15\u64ce\u8ba9\u4f60\u4e00\u5929\u4e0a\u7ebf\u5341\u4e2a\u9700\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gGs0tOJqBvJKCzPuUWsPiA"},"\u8ba1\u7b97\u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u59cb\u672b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nSlfsoIo0cMYUdgIEuHWEg"},"IO \u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u8bb0\u5f55")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YM9UP-esSDNZywMneKcVYw"},"Golang GC \u4ece\u7406\u8bba\u5230\u9488\u5bf9\u670d\u52a1\u7684\u5b9a\u5236\u5316\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QQjOyYkDfuxIxHl6k6qkRA"},"\u4e00\u6587\u5f7b\u5e95\u7406\u89e3Go\u8bed\u8a00\u6808\u5185\u5b58/\u5806\u5185\u5b58")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Oz0Zn8Y43UfHIOPL6rZ5Ig"},"\u5b57\u8282\u5927\u89c4\u6a21\u5fae\u670d\u52a1 Go \u8bed\u8a00\u53d1\u5c55\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2FVYnKHXFoj18W62pob_jw"},"\u901a\u8fc7\u5206\u6790gin\u3001beego\u6e90\u7801\uff0c\u8bfb\u61c2web\u6846\u67b6\u5bf9http\u8bf7\u6c42\u5904\u7406\u6d41\u7a0b\u7684\u672c\u8d28")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aLiqEuD9T8sERVrfGDSxvw"},"\u4e00\u6587\u8bfb\u61c2 Go Http Server \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0JbLDkJboDDihy-7N4MMPw"},"Golang slog \u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Immr4DD-XA-noOEkZ6flKg"},"Golang \u5e93: golang slog \u600e\u4e48\u8bbe\u7f6e\u65e5\u5fd7 Debug \u7b49\u7ea7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PKtrqHFTYWyAVSolKVOoBQ"},"Golang \u5e93: \u4e3a\u4ec0\u4e48 Golang slog \u5e93\u4e0d\u652f\u6301 Fatal")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G8mEAKRYbaae_rFBVJqdeg"},"\u53d1\u73b0conc\u5e76\u53d1\u5e93\u4e00\u4e2a\u6709\u8da3\u7684\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg"},"Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/irp0uBR-nJ87tZ_elMWPnA"},"\u300cGo\u8bed\u8a00\u8fdb\u9636\u300d\u5e76\u53d1\u7f16\u7a0b\u8be6\u89e3 | \u6587\u672b\u62bd\u5956")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7194334949011357755"},"\u4e00\u6587\u5165\u95e8Go\u4e91\u539f\u751f\u5fae\u670d\u52a1\u300c\u7206\u809d6\u5343\u5b57\u300d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jsdGV31yT5AR07BzRovWVw"},"\u4e3a\u4ec0\u4e48 Go \u4e0d\u652f\u6301 ","[","]","T \u8f6c\u6362\u4e3a ","[","]","interface")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uTJ1En-BXiLvH45xx0eFsA"},"go-zero \u662f\u5982\u4f55\u505a\u8def\u7531\u7ba1\u7406\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RyVc_JZJi_pTT_51mEHYiw"},"Go \u8bed\u8a00\u4e2d\u6392\u5e8f\u7684 3 \u79cd\u65b9\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ExfVdEM7_YWlQF6GhFn74A"},"\u4e00\u6587\u5403\u900f Go \u5185\u7f6e RPC \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ea7LfF2jOoHOSozX-qUZLA"},"Go \u6700\u7ec6\u8282\u7bc7\uff5c\u5185\u5b58\u56de\u6536\u53c8\u8e29\u5751\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BwqHMhc2WtAY_R-UffNQ4w"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cGo \u7684 nil \u503c\u5224\u65ad\uff0c\u5343\u65b9\u767e\u8ba1\uff0c\u8fd8\u662f\u8e29\u5751!")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-3X0c4P0WdZdjtkTsX16Rw"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cpprof \u7edf\u8ba1\u7684\u5185\u5b58\u603b\u662f\u504f\u5c0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZgTCSj-PZMTiMCR4FtBeyA"},"Go \u6700\u7ec6\u8282\u7bc7\uff5c\u89e3\u5bc6 defer \u539f\u7406\uff0c\u7a76\u7adf\u80cc\u7740\u7a0b\u5e8f\u733f\u505a\u4e86\u591a\u5c11\u4e8b\u60c5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Atj8Ngvg3Uzw4gMDwf5rag"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang \u5e76\u53d1\u7f16\u7a0b\u6838\u5fc3\u7bc7 \u2014\u2014 \u5185\u5b58\u53ef\u89c1\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2u2qRUbgcOwvU9wcHpC0SA"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang\u6700\u7ec6\u8282\u7bc7\u2014 struct{} \u7a7a\u7ed3\u6784\u4f53\u7a76\u7adf\u662f\u5565")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ylsTVohPo7x8QKAUj1uoTA"},"Go Slice \u6269\u5bb9\u7684\u8fd9\u4e9b\u5751\u4f60\u8e29\u8fc7\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ixTP1qythuJyhf3b9kIRaA"},"Go \u8bed\u8a00\u5b9e\u73b0\u521b\u5efa\u578b\u8bbe\u8ba1\u6a21\u5f0f - \u5355\u4f8b\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qTYlHqozkWHkhF9OKfaAMQ"},"Go \u8bed\u8a00\u81ea\u5e26\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SYQTlvbLvbsSwFi2Q_kI1Q"},"\u5982\u4f55\u505a\u597d\u8868\u7ed3\u6784\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xiUPLOTkDCX2i2jTOSNgCQ"},"Go \u9519\u8bef\u5904\u7406\uff1a100+ \u63d0\u6848\u5168\u90e8\u88ab\u62d2\u7edd\uff0c\u4e3a\u4f55\u73b0\u9636\u6bb5\u4ecd\u7528 if err != nil")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/431YMKwRjaStanqA6juePA"},"Go \u8bed\u8a00\u5e76\u53d1\u6a21\u5f0f\u4ee3\u7801\u6a21\u677f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/elsHIqDQ0yABUZXNVpjwMg"},"\u57fa\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4f18\u5316\u9884\u89c8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/soaxFUjo6hEe2KSnle_LkQ"},"\u300c\u9ad8\u9891\u5fc5\u8003\u300dGo\u5e76\u53d1\u7f16\u7a0b\u9762\u8bd5\u9898\u548c\u7b54\u6848")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/k0zwlJNFssMRh1NHA6rGcA"},"\u6e90\u7801\u9605\u8bfb - \u5207\u7247\u6269\u5bb9\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PzfiMXiYjfGQFHW_0hTS4A"},"Golang\u53cd\u5c04\u5b66\u4e60\uff1a\u624b\u5199\u4e00\u4e2aRPC")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mAo2K8lZNeJHTtShBHlUsQ"},"\u6df1\u5165\u89e3\u6790\u975e\u963b\u585eGolang IO\u6846\u67b6nbio")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aP9bT4UL1MK5EDx18WfvmQ"},"Go \u8bed\u8a00\u6807\u51c6\u5e93 bufio \u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Yi0eGTzrT7mtkpebmLXqVA"},"CPU \u7f13\u5b58\u4f53\u7cfb\u5bf9 Go \u7a0b\u5e8f\u7684\u5f71\u54cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2iOkW5h7x-1wdYe51vMemw"},"\u300c\u5237\u8d77\u6765\u300dGo\u5fc5\u770b\u7684\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NJuOB8k86Z7Hv-xITL1Vqg"},"Go \u6027\u80fd\u52a0\u901f\u5668\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684 5 \u4e2a\u8bc0\u7a8d\u548c\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tgBqY3xYbk5IBzViL9eaiA"},"\u6df1\u5165\u5256\u6790 Golang \u7a0b\u5e8f\u542f\u52a8\u539f\u7406 - \u4ece ELF \u5165\u53e3\u70b9\u5230GMP\u521d\u59cb\u5316\u5230\u6267\u884c main\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7254384497649844280"},"\u4ece\u7f16\u8bd1\u539f\u7406\u5230 Go \u542f\u52a8\u65f6\u7684\u6d41\u7a0b\uff0cGo\u7a0b\u5e8f\u662f\u600e\u6837\u8dd1\u8d77\u6765\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/V5wAZcTbunU3HdS1xaWavQ"},"\u4ece.go\u6587\u672c\u6587\u4ef6\u5230\u53ef\u6267\u884c\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/eWM9AvG1qXnMWF4qIwhnVQ"},"Go \u7f16\u8bd1\u5668\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7210005376653377597"},"\u5b66\u4f1a Go select \u8bed\u53e5\uff0c\u8f7b\u677e\u5b9e\u73b0\u9ad8\u6548\u5e76\u53d1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7215188852851097656"},"Go Mutex\uff1a\u4fdd\u62a4\u5e76\u53d1\u8bbf\u95ee\u5171\u4eab\u8d44\u6e90\u7684\u5229\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7218554163051413561"},"Go RWMutex\uff1a\u9ad8\u5e76\u53d1\u8bfb\u591a\u5199\u5c11\u573a\u666f\u4e0b\u7684\u6027\u80fd\u4f18\u5316\u5229\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7223035239072333861"},"Go \u8bed\u8a00\u4e2d\u6ca1\u6709\u679a\u4e3e\u7c7b\u578b\uff0c\u4f46\u662f\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u505a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7224147971834691639"},"Go \u65b9\u6cd5\u63a5\u6536\u5668\uff1a\u9009\u62e9\u503c\u63a5\u6536\u5668\u8fd8\u662f\u6307\u9488\u63a5\u6536\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7233981178101186619"},"\u4e00\u6587\u638c\u63e1 Go \u5e76\u53d1\u6a21\u5f0f Context \u4e0a\u4e0b\u6587")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rD3pnjWF5_Zz-r6GB0LrrA"},"Go \u7a7a\u7ed3\u6784\u4f53\uff1a\u96f6\u5185\u5b58\u7684\u9b54\u529b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7241938328839618597"},"Go \u51fd\u6570\u9009\u9879\u6a21\u5f0f\uff08Functional Options Pattern\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7246777406387306553"},"Go \u9879\u76ee\u5206\u5c42\u4e0b\u7684\u6700\u4f73 error \u5904\u7406\u65b9\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xjkY6hJnUq5btDyJuSOZrg"},"Go \u8bed\u8a00 iota \u7684\u795e\u5947\u529b\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sJeXoxTSh7M9azpsbsr1rQ"},"\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\uff1a\u63a2\u7d22Go\u8bed\u8a00\u4e2d\u7684\u51fd\u6570\u4e00\u7b49\u516c\u6c11")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_enXW8Pk4okosAgDo_aYSw"},"[","Go\u5f00\u6e90\u5de5\u5177","]"," go-optioner\uff1a\u8f7b\u677e\u751f\u6210\u51fd\u6570\u9009\u9879\u6a21\u5f0f\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/biTRyEu2h8AzQaQf7Ik8nA"},"\u6df1\u5165\u63a2\u7d22 Go 1.21.0 \u4e2d\u7684 maps \u5de5\u5177\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_a9d67L8l7G6EDJom1kixw"},"Go Gin \u6846\u67b6\u7cfb\u5217 - \u5165\u95e8\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gC4D9CqeYAd-jPotKgIV4g"},"Go \u9879\u76ee\u5fc5\u5907\uff1a\u6df1\u5165\u6d45\u51fa Wire \u4f9d\u8d56\u6ce8\u5165\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7226187111330611255"},"\u5feb\u901f\u4e0a\u624b Go CGO\uff0c\u638c\u63e1\u5728 Go \u91cc\u5199 C\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1NuBnk8_lxmTi9N0biLa2g"},"Go1.21 \u901f\u89c8\uff1a\u8fc7\u4e86\u4e00\u5e74\u534a\uff0cslices\u3001maps \u6cdb\u578b\u5e93\u7ec8\u4e8e\u8981\u52a0\u5165\u6807\u51c6\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N7_-WNBsTpTc4X8qTQw-Nw"},"Go1.22 \u53ef\u80fd\u4f1a\u89e3\u51b3\u5faa\u73af\u53d8\u91cf\u7684\u5751\uff0c\u771f\u597d\uff01\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xgJ8lPS-O84Ttne5heRa3g"},"Go1.21 \u901f\u89c8\uff1a\u9a9a\u64cd\u4f5c panic(nil) \u5c06\u6210\u4e3a\u5386\u53f2\uff01\u4ee5\u540e\u522b\u8fd9\u4e48\u5e72\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rxxQhrVk3_4ZvTjsIJbstw"},"Go1.21.0 \u65b0\u7279\u6027\uff1a\u4e0d\u9700\u8981\u5faa\u73af delete map \u5143\u7d20\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MorBUrzpKFhssiZWLt4o6g"},"Go1.21 \u901f\u89c8\uff1a\u65b0\u5185\u7f6e\u51fd\u6570 clear\u3001min\u3001max \u548c\u65b0\u6807\u51c6\u5e93\u5305 cmp\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/s13EBwOExsVz_vwNEm0fvQ"},"Go1.21 \u901f\u89c8\uff1ago.mod \u7684 Go \u7248\u672c\u53f7\u5c06\u4f1a\u7ea6\u675f Go \u7a0b\u5e8f\u6784\u5efa\uff0c\u8981\u7279\u522b\u6ce8\u610f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/b_TYBRIZ3-EORFYq1xRjyQ"},"Go \u5c06\u5f15\u5165\u6807\u51c6\u5e93 v2 \u7248\u672c\uff0c\u9996\u4e2a\u52a8\u624b\u7684\u662f\uff1amath/rand/v2\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7249913673216966714"},"Go1.21 \u901f\u89c8\uff1aContext \u53ef\u4ee5\u8bbe\u7f6e\u53d6\u6d88\u539f\u56e0\u548c\u56de\u8c03\u51fd\u6570\u4e86\uff0c\u7b49\u7684\u53ef\u592a\u4e45\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VO0VlfGbuvZst9yD73-VDQ"},"Go \u56e2\u961f\u5c06\u4fee\u6539 for \u5faa\u73af\u53d8\u91cf\u7684\u8bed\u4e49\uff0cGo1.21 \u65b0\u7248\u672c\u5373\u53ef\u4f53\u9a8c\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Z8kMDwuv9ZlmqvdrOu5SEQ"},"Google \u5de5\u4f5c 10+ \u5e74\u7684\u611f\u609f\uff0c\u6709\u770b\u5230 Go \u6838\u5fc3\u56e2\u961f\u7684\u5f71\u5b50\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4vpgxwTEn-xjdmXF5Hj7Kw"},"Go defer \u53bb\u6389\u95ed\u5305\u51fd\u6570\uff0c\u9760\u8c31\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xjjnE5hcspbNRGHP-I869A"},"\u53e6\u4e00\u79cd\u89c6\u89d2\uff1a\u6211\u4e3a\u4ec0\u4e48\u653e\u5f03 Go \u8bed\u8a00")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4pPpHRWflkkvqrf-FlXztg"},"Go \u9762\u8bd5\u9898\uff1astring \u662f\u7ebf\u7a0b\u5b89\u5168\u7684\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BfW8Ra3tsv7Dv3nu3MeI0g"},"Go \u6539\u7248\u672c\u53f7\u89c4\u5219\uff0c\u4e3b\u7248\u672c\u53f7\u7ec8\u4e8e\u652f\u6301\u7b2c\u4e09\u4f4d\u6570\u5b57 0 \u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Nuj_cYFvBesaBbSSz5PuBg"},"Go1.21 \u90a3\u4e9b\u4e8b\uff1a\u6cdb\u578b\u5e93\u3001for \u8bed\u4e49\u53d8\u66f4\u3001\u7edf\u4e00 log/slog\u3001WASI \u7b49\u65b0\u7279\u6027\uff0c\u4f60\u77e5\u9053\u591a\u5c11")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jk7k5v9uvaNy_2fUsDjq0Q"},"\u53c8\u6709\u65b0\u529f\u80fd\uff01Go \u5c06\u6709\u751f\u6210\u65b0\u6a21\u677f\u7684 gonew \u5de5\u5177\u94fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/o1iKbXJEikJn8BLwetvF5g"},"Go \u5c06\u589e\u52a0\u5185\u7f6e\u7684\u96f6\u503c\u6807\u8bc6\u7b26 zero\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/M6b4Q7rwKSt4KNKJN7_j4g"},"Go \u96f6\u503c\u548c\u7a7a\u503c\u7684\u5224\u65ad\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5kNyYJhrzigujLq1YSVjHw"},"Go \u8d1f\u8d23\u4eba\u8bf4\u4ee5\u540e\u4e0d\u4f1a\u6709 Go2 \u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TlJFr25XNgGA7uyRtLMOlw"},"Go \u5e38\u91cf\u4e3a\u4ec0\u4e48\u53ea\u652f\u6301\u57fa\u672c\u6570\u636e\u7c7b\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xO_w3FvNN8OeiuEYFarwGQ"},"Go \u5b98\u65b9\u65b0\u73a9\u5177\uff1a\u6f0f\u6d1e\u7ba1\u7406\u548c\u626b\u63cf\uff0c\u770b\u770b\u81ea\u5df1\u9879\u76ee\u6709\u6ca1\u6709\u5751")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4yfVZCaJ1489ddpYD5vDQA"},"\u5feb\u901f\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/C_KpYoul8ko5yrVLMe_uQg"},"\u300c\u5fc5\u77e5\u5fc5\u4f1a\u300d Nacos \u7684\u9762\u8bd5\u9898\u548c\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8XdbLrlzHhofiC089AMb1Q"},"zookeeper\u5230nacos\u7684\u8fc1\u79fb\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YGhndR5zR-Ebf8IaKbFZiQ"},"\u4e0a\u7bc7\uff1a\u5e26\u4f60\u624b\u5de5\u4f53\u9a8c\u4ece\u5199\u4ee3\u7801\u3001\u7f16\u8bd1\u3001\u6253\u5305\u955c\u50cf\u3001\u90e8\u7f72\u5230K8S\u7684\u5168\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yJ6rkYrwn8RAMLt5uCF9mw"},"\u4e0b\u7bc7\uff1a\u4f7f\u7528jenkins\u53d1\u5e03go\u9879\u76ee\u5230k8s\uff0c\u63a5\u4e0a\u7bc7\u7684\u624b\u5de5\u4f53\u9a8c\u6539\u9020\u4e3a\u81ea\u52a8\u5316\u53d1\u5e03")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pW0vxt8k1pDk0OEz5asWGQ"},"\u503c\u5f97\u6536\u85cf\uff1aK8S\u7684kubectl\u5e38\u7528\u547d\u4ee4\u5df2\u7ecf\u6309\u573a\u666f\u5206\u597d\u7c7b\uff0c\u8bf7\u60a8\u67e5\u9605")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lYg-GdheztmkTo9mwqHGsg"},"\u907f\u5751\uff1aGo\u5e76\u53d1\u7f16\u7a0b\u65f6\uff0c\u5982\u4f55\u907f\u514d\u53d1\u751f\u7ade\u6001\u6761\u4ef6\u548c\u6570\u636e\u7ade\u4e89")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bwkK3Yw02w4szwub2B2-ig"},"Go\u63a5\u53e3\uff1a\u8fd0\u7ef4\u5f00\u53d1\u573a\u666f\u4e2d\uff0cgo\u7684\u63a5\u53e3\u5230\u5e95\u600e\u4e48\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bqZ6gAsOZoVEMSCeOuLbiQ"},"Go\uff1a4\u4e2a\u573a\u666f\u5c31\u53ef\u4ee5\u8ba9\u4f60\u77e5\u9053Goroutine\u548c\u901a\u9053\u662f\u600e\u4e48\u7528\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7210747150828798008"},"\u4e0d\u80cc\u9505\u8fd0\u7ef4\uff1aGo\u8bed\u8a00\u5207\u7247\u5185\u5b58\u4f18\u5316\u6280\u5de7\u548c\u5b9e\u6218\u6848\u4f8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rxPAcU5zhWCtRQLbh9uxKw"},"Go\u5b9e\u6218\uff1a\u5f00\u53d1\u4e00\u4e2a\u7b80\u5355\u7684gRPC Demo")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/im8JZV3bL9WVOn7VgArmhw"},"Go\uff1a\u4f7f\u7528Cobra\u6253\u9020\u5f3a\u5927\u547d\u4ee4\u884c\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4VfTjWQwNO-tlxYbUOrWZw"},"Go\u7684\u8fd9\u4e2a\u5e93\uff0c\u8ba9\u4f60\u7684\u547d\u4ee4\u884c\u8f93\u51fa\u53d8\u5f97\u4e13\u4e1a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nbouC5ynfZShaTMTYiCJFA"},"\u300cGo\u5f00\u6e90\u5305\u300dasynq\uff1a\u4e00\u4e2a\u57fa\u4e8eredis\u7684\uff0c\u7b80\u5355\u3001\u53ef\u9760\u3001\u9ad8\u6548\u7684\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HBLwocMA2vQE2uFlJ0D8Iw"},"\u62bd\u4e1d\u5265\u8327\uff0c\u8bb0\u4e00\u6b21 Go \u7a0b\u5e8f\u6027\u80fd\u4f18\u5316\u4e4b\u65c5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1Y_A6WVslDthVjtbP9Ibvg"},"Go\uff1a\u8bb0\u4e00\u6b21\u63d0\u534718\u500d\u7684\u6027\u80fd\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/js3m_Fe6k4ys4aBSFDJhLQ"},"Go\u8bed\u8a00\u4e2dJSON\u5904\u7406\u6280\u5de7\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ueNuYA23F3bQTwIKU-PZ2Q"},"\u63a2\u7a76\uff5cGo JSON \u4e09\u65b9\u5305\u54ea\u5bb6\u5f3a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IAHEQu-N5OO-X_q-47GCsQ"},"Sonic: Go\u8bed\u8a00\u7684\u8d85\u7ea7JSON\u5e93\uff0c\u89e3\u6790\u4e0e\u7f16\u7801\u901f\u5ea6\u72c2\u98d9")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cjQyDdIgcdzj7LOeZf21bQ"},"\u6536\u85cf\uff01\uff01\uff01\u4e00\u56fe\u638c\u63e1 Go \u4e2d IO \u5305\u7684\u5173\u7cfb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7207058392287346747"},"\u901a\u8fc7\u6e90\u7801\u5256\u6790Go\u7684map\u6269\u5bb9\u5e95\u5c42\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cK2KMpN4vUrlDXEkTm7Mig"},"\u300c\u6709\u95ee\u5fc5\u7b54\u300dGopher\u5982\u4f55\u4f18\u96c5\u7684\u5bf9\u65f6\u95f4\u8fdb\u884c\u683c\u5f0f\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7qutgFgPDGyjKhxb6YVB3Q"},"Go \u6cdb\u578b\u7684\u4e8c\u5341\u4e00\u4e2a\u9677\u9631")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248388270723039290"},"\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff1a\u6df1\u5165\u63a2\u7d22Golang\u4e2d\u7684SM4\u52a0\u5bc6\u89e3\u5bc6\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248791708334899258"},"\u7cbe\u90098\u9053ES\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\uff0c\u540e\u6094\u6ca1\u65e9\u70b9\u770b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248995705291866169"},"\u7cbe\u9009Go\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\u6c47\u603b\uff0c\u9605\u8bfb\u7834\u4e07\uff0c\u6536\u85cf230+")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ldn5APfp0UooWbh4cmcM4A"},"Go\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3 | \u6587\u672b\u9001\u4e66")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GXAvaFvXR3HYI7qU4lL4lA"},"Go\u4e2d\u8fd9\u4e48\u591a\u521b\u5efaerror\u7684\u65b9\u5f0f\uff0c\u4f60\u771f\u7684\u4e86\u89e3\u5b83\u4eec\u5404\u81ea\u7684\u5e94\u7528\u573a\u666f\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6aicpVC3qjRpf1ILI4V4lA"},"\u57fa\u4e8eRedis\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u56fa\u5b9a\u7a97\u53e3\u9650\u6d41\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CUQaiZp4BrulnXvLd9ogZQ"},"go channel\u5e94\u7528\u7cfb\u5217\u4e4b\u63a7\u5236\u534f\u7a0b\u6570\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YJp2jxuBwwbPBaMWlDZG9g"},"\u914d\u56fe\u6e05\u65b0\u7684Protobuf \u7f16\u7801&\u907f\u5751\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iptZLaGFLd1rDedclQUMFg"},"\u5199\u7ed9\u5f00\u53d1\u8005\u7684gRPC\u6559\u7a0b-\u670d\u52a1\u53d1\u73b0\u4e0e\u8d1f\u8f7d\u5747\u8861")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/oettru3CV_Cjqv5GEOmcMw"},"\u7b54\u7f51\u53cb\u95ee\uff1agolang\u4e2d\u7684slice\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\u662f\u503c\u4f20\u9012\u8fd8\u662f\u5f15\u7528\u4f20\u9012")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OXopl6FpwtE6P-k0GEP9qA"},"Go\u53ef\u7528\u6027(\u4e03) \u603b\u7ed3: \u4e00\u5f20\u56fe\u4e32\u8054\u53ef\u7528\u6027\u77e5\u8bc6\u70b9")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MSwUlVGPDRBjdR-xh5cNfA"},"Go \u5de5\u7a0b\u5316(\u5341) \u5982\u4f55\u5728\u6574\u6d01\u67b6\u6784\u4e2d\u4f7f\u7528\u4e8b\u52a1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pb0P_y34N3uOhMu0SDqC2A"},"Go \u5de5\u7a0b\u5316(\u5341\u4e00) \u5982\u4f55\u4f18\u96c5\u7684\u5199\u51fa repo \u5c42\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2wYRmG_AiiHYjLDEXg94Ag"},"\u4f7f\u7528 Go \u8bed\u8a00\u5b9e\u73b0\u4e8c\u53c9\u641c\u7d22\u6811")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7hU0iSDBg0z1nYZnB-61gQ"},"Opentelemetry \u5b9e\u8df5\u5206\u4eab - Golang\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xavjsa4NzRiVRxyMhifCDg"},"Golang\u5b9e\u73b0\u5355\u673a\u767e\u4e07\u957f\u8fde\u63a5\u670d\u52a1 - \u7f8e\u56fe\u7684\u4e09\u5e74\u4f18\u5316\u7ecf\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IpvR28soReYC3nNkAisteA"},"\u4f7f\u7528go-zero\u5feb\u901f\u6784\u5efa\u5fae\u670d\u52a1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yHD5XKsk6emuXjcnU2JxDw"},"\u5927\u578b Go \u4ee3\u7801\u5e93\u7684 3 \u79cd\u6700\u4f73\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n199y8JEyjuGFwUEyH2XVg"},"Asynq: \u57fa\u4e8eRedis\u5b9e\u73b0\u7684Go\u751f\u6001\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u548c\u5f02\u6b65\u5904\u7406\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/C2kZGElYQmHz3OCb7LuYoA"},"\u300cGo\u9762\u7ecf\u300d\u7b97\u6cd5 \u5e76\u53d1\u6a21\u578b \u7f13\u5b58\u843d\u76d8 etcd actor\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2tFBe6LH84dZnOcfkgX32w"},"\u63a2\u7d22 Go1.21 \u4e2d\u7684 slices \u5305\uff1a\u539f\u7406\uff0c\u7279\u70b9\u548c\u793a\u4f8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7nK4whfh0Owwhmq_67_eYg"},"\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_mXRLJ-h7Iqkrt1jq_sZXg"},"Go \u8bed\u8a00\u4e3a\u4ec0\u4e48\u9002\u5408\u5f00\u53d1\u7f51\u7edc\u670d\u52a1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iamOjb0k3M2k_FVG9W7z0A"},"\u7528 Go \u7f16\u5199\u7b80\u6d01\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7vDklpTsbRdRDvB0-yvB5g"},"Golang channel \u4e09\u5927\u5751\uff0c\u4f60\u8e29\u8fc7\u4e86\u561b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j9Obe6Na25388AzeSL1dRA"},"\u4f7f\u7528Singleflight\u4f18\u5316Go\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gVjq59qnLjy-gwibt7Q3yw"},"\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G3FGOUo-F-stOp5eZjq4QQ"},"\u5b9a\u4e86\uff1aGo 1.22\u5c06\u4fee\u590dfor\u5faa\u73af\u53d8\u91cf\u9519\u8bef")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R_2pwdv2V1jj3zMjuUTNHw"},"Go\u5b57\u7b26\u4e32\u64cd\u4f5c\u4e0d\u662f\u4f60\u60f3\u7684\u90a3\u4e48\u7b80\u5355\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QlzH18i72pWPm012t7d42Q"},"Golang\u77e5\u8bc6\u70b9(defer): \u9762\u8bd5\u7ecf\u5e38\u53d8\u91cf\u5728 defer \u4e2d\u7684\u503c\uff0c \u5176\u5b9e\u5728\u95ee\u53d8\u91cf\u7684\u4f5c\u7528\u57df")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VjP9Bv46x7NP6uQ7cbsqmg"},"Go BIO/NIO\u63a2\u8ba8(1)\uff1aGin\u6846\u67b6\u4e2d\u5982\u4f55\u5904\u7406HTTP\u8bf7\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/x5qUJ-htS6ML1Cc8uYIDVQ"},"Go BIO/NIO\u63a2\u8ba8(2)\uff1anet\u5e93\u5bf9socket/bind/listen/accept\u7684\u5c01\u88c5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WoXZ_i7lJeXny8lIJ_Aj4g"},"Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/76xvAvnFAcDUAa6fgoZRfg"},"\u3010\u8865\u5145\u4ee3\u7801\u3011Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AvtIiC349sDqOe9labc3-A"},"Go BIO/NIO\u63a2\u8ba8(4)\uff1anet/http \u5728 tcp conn \u4e0a\u7684\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MO5XV40D3MI6NpEEpJiCMA"},"Go BIO/NIO\u63a2\u8ba8(5)\uff1anet\u5e93\u7684\u975e\u963b\u585e\u652f\u6301")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/t_4uTGN9DFCjqDw4LZT-0w"},"Go BIO/NIO\u63a2\u8ba8(6)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bselect")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Zsh92yqK4e6mxNBLgY0Umw"},"Go BIO/NIO\u63a2\u8ba8(7)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bepoll")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3_eToHvOw25JrC8-xePe_w"},"Go BIO/NIO\u63a2\u8ba8(8)\uff1aGo netpoll \u7684\u5de5\u4f5c\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-qms3hEl2mNMkDN1S4ZQoQ"},"Go\u534f\u7a0b\u6c60(1): \u7ebf\u7a0bvs\u534f\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ktMff61A9vvqeRGkGwQnwg"},"Go\u534f\u7a0b\u6c60(2): \u5982\u4f55\u5b9e\u73b0\u534f\u7a0b\u6c60")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cIgfuumVCL4rxtNYGcQH4A"},"\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1(1): \u5982\u4f55\u5b9e\u73b0\u6296\u97f3\u5173\u6ce8/\u7c89\u4e1d\u5217\u8868")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ydFRhjV70QC64N8r2zEtVA"},"SIMD\u80fd\u529b\u521d\u4f53\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/q-keuybJ2d-QMXWoPpSbPA"},"[","\u4ee3\u7801\u9644\u5f55","]"," SIMD\u80fd\u529b\u521d\u4f53\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1kuLtd8rxC1xP628FgAwqw"},"\u670d\u52a1\u67b6\u6784\u7b80\u4ecb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ane5iRMqYrtQMnC3TWlrwA"},"\u670d\u52a1\u67b6\u6784\uff1a\u5927\u6570\u636e\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dOw25R2xihr0M3T27fYUSA"},"\u670d\u52a1\u67b6\u6784\uff1a\u5fae\u670d\u52a1\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CUCHUQa6lYuPhvEALdIQQg"},"\u670d\u52a1\u67b6\u6784\uff1a\u5206\u5c42\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P1j0vg2FYqt1zvwPQsdtww"},"\u670d\u52a1\u67b6\u6784\uff1aWeb-Queue-Worker\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YkOoLbH2P2HheQxomGsbNQ"},"\u5f02\u6b65\u8bf7\u6c42-\u54cd\u5e94\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Q-YvkWhFC2uK1z5AKEKSnw"},"Sidecar\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157594175846744071"},"\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1CY3E5daJ5U42orVwzCpaw"},"Go Scheduler \u7684 GMP \u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7116817920209977351"},"Golang \u6cdb\u578b\u521d\u8bc6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yHB9BzEGIki1fyjYojdpYQ"},"Go \u8bed\u8a00\u5b98\u65b9\u4f9d\u8d56\u6ce8\u5165\u5de5\u5177 Wire \u4f7f\u7528\u6307\u5317")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043587400131411976"},"Go \u670d\u52a1\u7aef\u5f00\u53d1\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://eddycjy.com/go-categories/"},"Go \u8bed\u8a00\u5165\u95e8\u7cfb\u5217\uff1a\u521d\u63a2 Go \u9879\u76ee\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://golang2.eddycjy.com/"},"Go \u8bed\u8a00\u7f16\u7a0b\u4e4b\u65c5\uff1a\u6df1\u5165\u7528 Go \u505a\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://golang3.eddycjy.com/"},"Go \u8bed\u8a00\u8bbe\u8ba1\u54f2\u5b66\uff1a\u4e86\u89e3 Go \u7684\u4e3a\u4ec0\u4e48\u548c\u8bbe\u8ba1\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://golang1.eddycjy.com/"},"Go \u8bed\u8a00\u8fdb\u9636\u4e4b\u65c5\uff1a\u8fdb\u4e00\u6b65\u6df1\u5165 Go \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1383459655464337409&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011HTTP \u7cfb\u5217\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1323498303014780929&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00 Web \u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1325302744319737858&scene=21&from_msgid=2247484375&from_itemidx=1&count=3&nolastread=1#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5e76\u53d1\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/homepage?__biz=MzkyNzI1NzM5NQ==&hid=2&sn=4d298cf2d9ad21260321275cf6c75194&scene=1&devicetype=iOS14.0&version=18000733&lang=zh_CN&nettype=3G+&ascene=7&session_us=gh_169729c17b9c&fontScale=100"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"http://mp.weixin.qq.com/mp/homepage?__biz=MzkyMzIyNjIxMQ==&hid=1&sn=631fe1ce375f2cd672449d0bd01963d2&scene=18#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go\u6e90\u7801\u4e0e\u5e95\u5c42")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1394839706508148737&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Kubernetes \u5b66\u4e60\u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1488826194207752195&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011\u5fae\u670d\u52a1\u8bbe\u8ba1\u548c\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1809543596702777345&scene=21&from_msgid=2247492061&from_itemidx=1&count=3&nolastread=1#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u5fae\u670d\u52a1\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1326949382503219201&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5b9e\u6218\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1751854579329056768&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u9762\u8bd5\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/doc/effective_go"},"Golang \u8fdb\u9636 - Effective Go")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/doc/faq"},"Golang \u8fdb\u9636 - Go FAQ")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/blog/all"},"Golang \u8fdb\u9636 - blog\u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/talks/"},"Golang \u8fdb\u9636 - \u5404\u4e2atalk\u8d44\u6599")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://tonybai.com/2019/10/12/uber-go-style-guide/"},"Golang \u8fdb\u9636 - Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://tonybai.com/google-go-style/"},"Golang \u8fdb\u9636 - Google Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki/CodeReviewComments"},"Golang \u8fdb\u9636 - CodeReviewComments")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki/SliceTricks"},"Golang \u8fdb\u9636 - SliceTricks")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki/CompilerOptimizations#optimized-memclr"},"Golang \u8fdb\u9636 - CompilerOptimizations")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki#learning-more-about-go"},"Golang \u8fdb\u9636 - learning-more-about-go")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/luk4z7/go-concurrency-guide"},"Golang \u8fdb\u9636 - go-concurrency-guide")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u6587\u7ae0\u5206\u4eab",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/kevinyan815/gocookbook"},"Golang\u5f00\u53d1\u624b\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg"},"\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw"},"\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rOtR8FfMpfBZrIkyRrNsfQ"},"Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6307\u5357\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RCBUlu0gRuVFSQ2m8Uyycg"},"Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6982\u8ff0\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vP2IDCK4cjyIGiutCoA7Pw"},"\u4e07\u5b57\u957f\u6587\uff0c\u6559\u4f60\u7528go\u5f00\u53d1\u533a\u5757\u94fe\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8_pJiuOzoQt6xyoLUX0CIw"},"Go \u670d\u52a1\u7f51\u7edc\u4e0d\u901a\uff1fnet/http\u81ea\u5e26\u7684\u8fd9\u4e2a\u5de5\u5177\u5e2e\u4f60\u5feb\u901f\u5b9a\u4f4d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RnsM-bWSRBiDS4v1JcRzdg"},"\u98a0\u8986\u5fae\u670d\u52a1\u67b6\u6784\uff1f\u8c37\u6b4c\u6700\u65b0\u5f00\u6e90service weaver\u521d\u4f53\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i1loQpQufni3v4Ho2J6Pgw"},"\u4e00\u4e2a Go \u7a0b\u5e8f\u7684 Benchmark \u57fa\u51c6\u5206\u6790\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RLqjkV_1geeVkXeG9TLHFw"},"\u4f60\u8bf4 Go \u7684\u5207\u7247\u539f\u751f\u652f\u6301\u5e76\u53d1\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gNQETEVBMOH0US42M0uODg"},"\u7535\u8111\u7528GoLand\u592a\u5361\uff0c\u8bb0\u5f55\u4e0b\u81ea\u5df1\u628aVsCode\u5b9a\u5236\u6210Go IDE\u7684\u6b65\u9aa4\u548c\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iRgaOlFs52O2TMScu8wDzg"},"\u7528\u4e86Go\u533f\u540d\u7ed3\u6784\u4f53\uff0c\u642c\u7816\u6548\u7387\u66f4\u9ad8\uff0c\u4ea7\u91cf\u66f4\u8db3\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KaesgBLyTz7xi9eXvSTMmQ"},"\u5408\u8ba2\u672c\uff5c\u7528Go\u8bed\u8a00\u5b9e\u73b023\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u53ca\u5b66\u4e60\u91cd\u70b9")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/91-XUm5Gn9oQLd_F4dLb3A"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u4e2d\u4ecb\u8005\uff0c\u6700\u540e\u7684\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8v0UZWygCvkbye4Y0P-3sQ"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u89e3\u91ca\u5668\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n1R1fnRZuDwlaQqsDh5y3g"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u547d\u4ee4\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RikZAeI2Pic4vYwVNh4HnA"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u5907\u5fd8\u5f55\u6a21\u5f0f\uff0c\u5e26\u6682\u5b58\u7684\u4e1a\u52a1\u529f\u80fd\u53ef\u4ee5\u53c2\u8003\u5b83\u6765\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qsw89qI8DOXyb4C1XI5QtA"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u8bbf\u5ba2\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sABibBRsC2kknbAH18oatA"},"Go\u8bbe\u8ba1\u6a21\u5f0f-\u8fed\u4ee3\u5668\u5230\u5e95\u662f\u4e0d\u662f\u4e00\u4e2a\u591a\u6b64\u4e00\u4e3e\u7684\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/O8shSU46TcgFPx3h7NGFAA"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u6865\u63a5\u6a21\u5f0f\uff0c\u8ba9\u4ee3\u7801\u65e2\u80fd\u591a\u7ef4\u5ea6\u6269\u5c55\u53c8\u4e0d\u4f1a\u81c3\u80bf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AZHO7R6IXFG8MguDpUNdbw"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u4eab\u5143\u6a21\u5f0f\uff0c\u8282\u7701\u5185\u5b58\u7684\u597d\u5e2e\u624b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X9dKNO6sd-OY2VfsZpaElA"},"Go\u8bbe\u8ba1\u6a21\u5f0f\u5b9e\u6218--\u7528\u72b6\u6001\u6a21\u5f0f\u5b9e\u73b0\u7cfb\u7edf\u5de5\u4f5c\u6d41\u548c\u72b6\u6001\u673a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tC9xfZFJvcNEbTXHQYvT6w"},"\u5916\u89c2\u6a21\u5f0f\uff0c\u4e00\u4e2a\u6bcf\u5929\u90fd\u5728\u7528\uff0c\u5374\u88ab\u591a\u6570\u4eba\u5728\u9762\u8bd5\u4e2d\u5ffd\u89c6\u7684\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r8975amH-DcJkWQKytIeJQ"},"Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u9879\u76ee\u4f9d\u8d56\u8026\u5408\u5ea6\u592a\u9ad8\uff1f\u53ef\u4ee5\u7528\u9002\u914d\u5668\u505a\u4e0b\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JKWbyr4Yt7A6l1nFsANUcQ"},"Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u7ec4\u5408\uff0c\u4e00\u4e2a\u5bf9\u6570\u636e\u7ed3\u6784\u7b97\u6cd5\u548c\u804c\u573a\u90fd\u6709\u63d0\u5347\u7684\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_e9Qa97gZvgv9n-pFB4lFw"},"Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u88c5\u9970\u5668\u548c\u804c\u8d23\u94fe\uff0c\u54ea\u4e2a\u6a21\u5f0f\u5b9e\u73b0\u4e2d\u95f4\u4ef6\u66f4\u79d1\u5b66")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/59cxPFHWcdnUxKyRyo8SKw"},"sourcegraph \u51fa\u54c1\u7684\u5e76\u53d1\u5e93 conc \u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AUSse5z1YES9wtKCiMdyWA"},"Go\u8bed\u8a00\u5b9e\u73b0\u7684\u53ef\u8bfb\u6027\u66f4\u9ad8\u7684\u5e76\u53d1\u795e\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LW8Woq5Rg4x31DbtD-_jeA"},"\u4e24\u79cd Option \u7f16\u7a0b\u6a21\u5f0f\u7684\u5b9e\u73b0\uff0cUber\u63a8\u8350\u8fd9\u4e00\u79cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SFbSAGwQgQBVWpySYF-rkw"},"Go\u7248\u672c\u5927\u4e8e1.13\uff0c\u7a0b\u5e8f\u91cc\u8fd9\u6837\u505a\u9519\u8bef\u5904\u7406\u624d\u5730\u9053")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IelVDnMzGtT5y7hGSb_OxA"},"\u9762\u8bd5\u5b98\uff1anet/http\u5e93\u77e5\u9053\u5417\uff1f\u80fd\u8bf4\u8bf4\u4f18\u7f3a\u70b9\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3uWozu4VIUJHyIGut3_0Bg"},"Go \u6a21\u7cca\u6d4b\u8bd5fuzzing\u7684\u539f\u7406\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FTXkgxkUzsHMIspCK60G4w"},"Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u6015\u628a\u6838\u5fc3\u4ee3\u7801\u6539\u4e71\uff0c\u8bb0\u5f97\u7528\u4ee3\u7406\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zCh12E10JM24EGTyFS7hPQ"},"\u4f60\u4e5f\u662f\u4e1a\u52a1\u5f00\u53d1\uff1f\u63d0\u524d\u7528\u8fd9\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u9884\u9632\u4ea7\u54c1\u52a0\u9700\u6c42\u5427")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IQsojcdwLZ1g0TgVQDoqVw"},"Go \u7a0b\u5e8f\u91cc if else \u5206\u652f\u592a\u591a\uff1f\u8bd5\u7740\u7528\u7b56\u7565\u6a21\u5f0f\u6cbb\u7406\u4e00\u4e0b\u5427")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-Ysho1jI9MfrAIrplzj7UQ"},"\u7528Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f-\u63d0\u70bc\u6d41\u7a0b\uff0c\u51cf\u5c11\u91cd\u590d\u5f00\u53d1\u5c31\u9760\u5b83\u4e86!")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cAwc6ZhdUwxkI5VT8LY9Hg"},"Go Gin\u6846\u67b6\u8bf7\u6c42\u81ea\u52a8\u9a8c\u8bc1\u548c\u6570\u636e\u7ed1\u5b9a\uff0c\u770b\u5b8c\u8fd9\u7bc7\u5c31\u4f1a\u7528\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Uu3EAWpRO9pSbg1F1DLa_w"},"Go\u5f00\u6e90\u5e93\u3001\u5927\u9879\u76ee\u7684\u516c\u5171\u5305\uff0c\u662f\u8fd9\u4e48\u7528\u5efa\u9020\u8005\u6a21\u5f0f\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/y1qHsQNR7EWeDU5g60Loqg"},"Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u539f\u578b\u6a21\u5f0f\u7684\u8003\u67e5\u70b9\u548c\u4f7f\u7528\u63a8\u8350")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MlC6-TDf06LGpF8hxcSV_w"},"\u5de5\u5382\u6a21\u5f0f\u6709\u4e09\u4e2aLevel\uff0c\u4f60\u80fd\u7528Go\u5199\u5230\u7b2c\u51e0\u5c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1ZuhUA9Lt2uLFlamIY6fLQ"},"\u6700\u7b80\u5355\u7684\u5355\u4f8b\u6a21\u5f0f\uff0cGo\u7248\u672c\u7684\u5b9e\u73b0\u4f60\u5199\u5bf9\u4e86\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OKUeAdicn0Bvkz8dYx1epQ"},"\u62d2\u7edd Go \u4ee3\u7801\u81c3\u80bf\uff0c\u5176\u5b9e\u5728\u8fd9\u51e0\u5757\u53ef\u4ee5\u7528\u4e0b\u89c2\u5bdf\u8005\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SpVTl64W1Exy8fuN15-kmA"},"Go\u6307\u9488\u7684\u4f7f\u7528\u9650\u5236\u548c\u7a81\u7834\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TtN6NZ8hQ2AIf0C8wVzkjA"},"Go\u8bed\u8a00\u7684IO\u5e93\u90a3\u4e48\u591a\uff0c\u6211\u8be5\u600e\u4e48\u9009")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gYWhjh1BburgeAU72mn_aw"},"Go \u773c\u4e2d\u7684\u6587\u4ef6\u7cfb\u7edf\u662f\u4ec0\u4e48\uff1f io.FS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zJXPGYwNXIUyEOI0Kc15rg"},"\u51e0\u4e2a\u63d0\u5347Go\u8bed\u8a00\u5f00\u53d1\u6548\u7387\u7684\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg"},"\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Elq7SWRpH08KmhX7auboOA"},"Gophers\u5982\u4f55\u51c6\u5907\u9762\u8bd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FEPXDMFfvKgmtsymVTWzHw"},"Go Modules\u77e5\u8bc6\u70b9\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147939014870302756"},"\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7131717990558466062"},"GO\u9762\u8bd5\u5fc5\u77e5\u5fc5\u4f1a\u9762\u8bd5\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kyGNVNDby5uq5JGfQt4Yrg"},"\u8fd9\u4e9b\u6700\u5e38\u7528\u7684 Go CLI \u547d\u4ee4\uff0c\u65b0\u624b Gopher \u5e94\u8be5\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7uobN6DmpIYqG34pOpvvlA"},"PGO \u662f\u5565\uff0c\u548b\u5c31\u8ba9 Go \u66f4\u5feb\u66f4\u731b\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Pcp2FjcXk7Q7sV0Z-bEUNw"},"Go for \u5faa\u73af\u6709\u65f6\u5019\u771f\u7684\u5f88\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6KxJRG3lKUDY734t4EzAaA"},"\u6df1\u5ea6\u89e3\u5bc6Go\u8bed\u8a00\u4e4b\u5173\u4e8e interface \u7684 10 \u4e2a\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qyEiEACuUd8SsyqCDLUjXA"},"\u624b\u64b8\u6e90\u7801\u7cfb\u5217 - cache2go")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nc4s289ULpQkGlQuaFbZlQ"},"Go\u5e38\u89c1\u9519\u8bef\u96c6\u9526\u4e4b\u51fd\u6570\u5f0f\u9009\u9879\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/THMhcM9TXydW8K5-Vvqvxg"},"\u8be6\u89e3\u5e76\u53d1\u7f16\u7a0b\u57fa\u7840\u4e4b\u539f\u5b50\u64cd\u4f5c(atomic\u5305)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/E2XwSIXw1Si1EVSO1tMW7Q"},"\u5b66\u4e60channel\u8bbe\u8ba1\uff1a\u4ece\u5165\u95e8\u5230\u653e\u5f03")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lJxjlDg5SkQyNLZBpOPP5A"},"context\u4f7f\u7528\u4e0d\u5f53\u5f15\u53d1\u7684\u4e00\u4e2abug")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/S_EzyWZmFzzbBbxoSNe6Hw"},"Go\u8bed\u8a00\u5982\u4f55\u5b9e\u73b0\u53ef\u91cd\u5165\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zlqZ-4EdzMNt3iubMknKLA"},"\u5982\u4f55\u5728\u6d4b\u8bd5\u4e2d\u53d1\u73b0goroutine\u6cc4\u6f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JC14dWffHub0nfPlPipsHQ"},"\u8bf7\u52ff\u6ee5\u7528goroutine")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bhze_LcFHk7Y-QB4nEQKnA"},"\u9762\u8bd5\u5b98\uff1a\u54e5\u4eecGo\u8bed\u8a00\u4e92\u65a5\u9501\u4e86\u89e3\u5230\u4ec0\u4e48\u7a0b\u5ea6\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/E45dNnEURe87P709Ovu-Qw"},"Go\u5de5\u5177\u4e4bgenerate")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dN9G4Tnt9HgVqlNh73HNUQ"},"\u63a2\u7a76 Go \u6e90\u7801\u4e2d panic & recover \u6709\u54ea\u4e9b\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Wdh2O4cnez95x0RBpMiDvQ"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#41 substrings and memory leaks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/39S-WWKt1rYNF9OUfFSCbw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#38 Misusing trim functions")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/m0WyJyd2JwQfX1SP2H-jrA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#37 Inaccurate string iteration")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P6rEyeLvl8gxT_4RJf235Q"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#36 Not understanding the concept of a rune")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ls1_qaEnuc8MSZoDyTwa1Q"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#35 Using defer inside a loop")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XRQq1O9VROBxItSP4kC8zA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#34 Ignoring how the break statement works")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gwsWE-NTBOs0NnsdNG4WBw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#33 Making wrong assumptions during map iterations")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/58EVYGZ02xPfGYrprk7dRw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#32 Ignoring the impact of using pointer ...")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cuJAYXGOleUt0FG5brX8ng"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#31 Ignoring how arguments are evaluated in ...")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/71wpR1kz5PgzVNBgpN855g"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#30 Ignoring the fact that elements are copied")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fpHMk37QGLQCXrPAdxXC_w"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#29 Comparing values incorrectly")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/s5-Pl5u6yoZCPWwoeINs9g"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#28 maps and memory leaks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9pfznxXKHCv-QEZBqHw1YQ"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#27 Inefficient map initialization")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TYxqo1BniI-wfKVHQsrjjw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#26 slices and memory leaks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lAIB0l666R6Zh9NAdV809g"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#25 Unexpected side effects using slice append")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vZBePdCuKe12OMQOj6Rz4A"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#24 Not making slice copies correctly")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WsFGv9tcdRLP9K-NQSqimA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#23 Not properly checking if a slice is empty")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uHmCU0v0xJ2RYlmq_lQAiQ"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#22 Being confused about nil vs. empty slices")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-Kt2QJdzEUDJx8MFvrUo7Q"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#20 Not understanding slice length and capacity")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/epK_0yn_EPIWJjz9xmddcA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#12 Project misorganization")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/teivah/100-go-mistakes"},"100 Go Mistakes and How to Avoid Them")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aj_hULmeqy3whILr2ytECQ"},"Go \u4e2d\u57fa\u4e8e IP \u5730\u5740\u7684 HTTP \u8bf7\u6c42\u9650\u6d41")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pe0CQa3tdrUmC86OSRBNeg"},"\u9879\u76ee\u5b9e\u6218\uff1a\u7528 Go \u521b\u5efa\u4e00\u4e2a\u7b80\u6613\u8d1f\u8f7d\u5747\u8861\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tloEYzrnKNrrAo1YKdeyrw"},"\u4f60\u77e5\u9053\u51e0\u79cdGo\u5e76\u53d1\u63a7\u5236\u65b9\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/H5HDrwhxZ_4v6Vf5xXUsIg"},"\u6d45\u8c08Golang\u4e24\u79cd\u7ebf\u7a0b\u5b89\u5168\u7684map")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YYvoeDfPMm8Y2kFu9uesGw"},"Go\u7cbe\u5999\u7684\u4e92\u65a5\u9501\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CEIQUa7H43FR7M1ghkDSGg"},"Go\u66f4\u7ec6\u7c92\u5ea6\u7684\u8bfb\u5199\u9501\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Mro5XC8dS5ZAMvEVbJZsCw"},"Go \u7684 TryLock \u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/oA6UJ-0R2OucFl-fbgrvWA"},"Go1.18 \u65b0\u7279\u6027\uff1aTryLock \u662f\u4ec0\u4e48\uff1f\u9700\u8981\u5b83\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/V2x0Nw3Y8lZxHYJh_yQ0dQ"},"Go\u4e2d\u770b\u4f3c\u7b80\u5355\u7684WaitGroup\u6e90\u7801\u8bbe\u8ba1\uff0c\u7adf\u7136\u6697\u542b\u8fd9\u4e48\u591a\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Lsm-BMdKCKNQjRndNCLwLw"},"Go \u6807\u51c6\u5e93\u6e90\u7801\u5b66\u4e60\uff08\u4e00\uff09\u8be6\u89e3\u77ed\u5c0f\u7cbe\u608d\u7684 Once")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3VkcIg7NhCCiIwVRjuwR0A"},"Go \u4e2d\u4e3a\u4ec0\u4e48\u5efa\u8bae\u4f7f\u7528 NewXxx \u8fd9\u6837\u7684\u6784\u9020\u51fd\u6570")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nA26g46tM_hu-khaGYniAQ"},"Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KHzdEE_w_ev9p4v6MR7M8Q"},"\u600e\u4e48\u9009\u62e9 Go \u6587\u4ef6\u8bfb\u53d6\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EeOxPkTe8WkOide49yIfEg"},"\u5982\u4f55\u6709\u6548\u63a7\u5236 Go \u7ebf\u7a0b\u6570")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OIqgqjXEvVmDUmnRqq4PGw"},"\u52a0\u5927\u529b\u5ea6\uff01Go \u5c06\u4f1a\u589e\u5f3a Go1 \u5411\u540e\u517c\u5bb9\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ucqqg4h9uRo7RVd8XCz80w"},"Go \u7684\u96f6\u503c\u6709\u4ec0\u4e48\u7528\uff1f\u770b\u770b\u8fd9 4 \u4e2a\u573a\u666f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/L_Sy4_6BURL4XWDK6bpEwg"},"Go \u53ea\u4f1a if err != nil\uff1f\u8fd9\u662f\u4e0d\u5bf9\u7684\uff0c\u5206\u4eab\u8fd9\u4e9b\u4f18\u96c5\u7684\u5904\u7406\u59ff\u52bf\u7ed9\u4f60\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cJON1H68eBFeuBpWhFbXXw"},"10+ \u6761 Go \u5b98\u65b9\u8c1a\u8bed\uff0c\u4f60\u77e5\u9053\u51e0\u6761\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xDXwsVjOfU2j3gisiHTZTQ"},"Go \u9002\u5408 IO \u5bc6\u96c6\u578b\uff1f\u5e76\u4e0d\u51c6\u786e\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fzmN6zFVioQGedTdSDmyqQ"},"\u5982\u4f55\u8ba9 Go \u53cd\u5c04\u53d8\u5feb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/y60q0-RMh8isd4u4PuLfUg"},"\u6df1\u5165\u7406\u89e3StatefulSet\uff0c\u7528Kubernetes\u7f16\u6392\u6709\u72b6\u6001\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903433846145038"},"Go Modules \u7ec8\u6781\u5165\u95e8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7075098594151235597"},"\u975e\u5e38\u9002\u5408PHP\u540c\u5b66\u4f7f\u7528\u7684GO\u6846\u67b6\uff1aGoFrame")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EGN7G8ku-zkaZuzfBwx9Qw"},"\u770b Go \u4e2d\u7684 struct \u5982\u4f55\u88ab\u4f18\u5316\uff0c\u8fd8\u6709\u5c0f\u63d2\u66f2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Qlqt1pP_Li-PxOICrz7bAw"},"\u5728 Go \u91cc\u7528 CGO\uff1f\u8fd9 7 \u4e2a\u95ee\u9898\u4f60\u8981\u5173\u6ce8\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Am0ORd08GsMc4xSdLG9kgg"},"Go \u63a2\u8ba8\u4e86 13 \u5e74\uff0c\u600e\u4e48\u89e3\u51b3\u518d\u8d4b\u503c\u7684\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7134497015576133669"},"Go\u5982\u4f55\u4f18\u96c5\u7684\u8bb0\u5f55\u64cd\u4f5c\u65e5\u5fd7 | \u51b2\u523a\u6398\u91d1\u4e00\u5468")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0c7emt54ayCrm1K16lk2SQ"},"\u5982\u4f55\u66f4\u76f4\u89c2\u5730\u7406\u89e3 Go \u8c03\u5ea6\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FviFOLkIHuEjZdTg_qCoNQ"},"Go1.19 \u90a3\u4e9b\u4f60\u4e0d\u77e5\u9053\u7684\u65b0\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SrqJdng9cNUEVAS7nFaqAA"},"Go \u4e2d\u53ef\u522b\u7528\u590d\u5236\u9501\uff0c\u4f1a\u6709\u8fd9\u4e9b\u5927\u95ee\u9898\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zyvO_hhUo1TRm6kMPcaFFQ"},"\u4f19\u8ba1\uff0cGo\u9879\u76ee\u600e\u4e48\u4f7f\u7528\u679a\u4e3e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XPPwHd7eDUjvzsnuFwgbyw"},"Go ORM \u5355\u5143\u6d4b\u8bd5\u5168\u6d41\u7a0b\u8bb2\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r30z2i_sSuRfEnM_23wFlg"},"\u8d85\u5168\u603b\u7ed3\uff1aGo\u8bed\u8a00\u5982\u4f55\u64cd\u4f5c\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HaF9qieEJWNUoyY9qTvnKw"},"Go \u7684\u65f6\u95f4\u8f6c\u6362\u548c\u65f6\u533a\u6821\u5bf9\u603b\u8bb0\u4e0d\u4f4f\uff1f\u7ed9\u4f60\u4e00\u4efd\u5907\u5fd8\u5355")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ptJK7CDHCr6P4JCdsUXKdg"},"\u641e\u6e05\u695a Go Mod\u7684\u7248\u672c\u548c\u4f2a\u7248\u672c\uff0c\u4e0b\u6b21\u522b\u4e71\u7528\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7jLmwtP3xk-wbCFKqPLK2g"},"\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u5982\u4f55\u53d1\u5e03\u5230Go Module\u4e0a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Dn2oM89mHEgoz8yVQnNEoQ"},"\u8fd9\u4e0d\u4f1a\u53c8\u662f\u4e00\u4e2aGo\u7684BUG\u5427")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YojNHW7kkjmmdjqBXCuQYA"},"\u8fd9\u4e09\u4e2a Go \u6c34\u5e73\u81ea\u6d4b\u9898\uff0c\u624b\u5199\u4e0d\u51fa\u6765\u8fd8\u662f\u5148\u8001\u5b9e\u4e0a\u73ed\u5427")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pR_XHTnhft2Hi_mY7JuEJg"},"\u4e0d\u60f3Go \u9519\u8bef\u5904\u7406\u592a\u81c3\u80bf\uff0c\u53ef\u4ee5\u53c2\u8003\u8fd9\u4e2a\u4ee3\u7801\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HuZn9hnHUBx3J4bAGYBYpw"},"\u5173\u4e8eGo\u7a0b\u5e8f\u9519\u8bef\u5904\u7406\u7684\u4e00\u4e9b\u5efa\u8bae")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u90e8\u7f72",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4f7f\u7528 Docker Desktop \u642d\u5efa k8s \u96c6\u7fa4"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MFd1R5VeEW0eLk-A4BqSQQ"},"\u5929\u5450\uff01\u6211\u7528 go \u4ece\u96f6\u5f00\u59cb\u5199\u4e86\u4e00\u4e2a k8s \u5e94\u7528\u7ba1\u7406\u5de5\u5177\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u548c\u5f00\u53d1\u8fc7\u7a0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg"},"Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i3n0hoHRaYoDMWcC5DSQ3w"},"\u638c\u63e1\u4e86\u8fd9\u7bc7 Dockerfile \u4e2d\u7684 ARG \u4f5c\u7528\u57df\uff0c \u5c31\u7b97 Build \u955c\u50cf CI \u5165\u95e8\u4e86 \u3010\u6587\u672b\u62bd\u5956\u3011")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pen6G2aFsPfSqhKjgocVjQ"},"\u9762\u8bd5\u95ee Dockerfile \u7684\u4f18\u5316\uff0c \u5343\u4e07\u4e0d\u8981\u53ea\u4f1a\u8bf4\u51cf\u5c11\u5c42\u6570")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/10Ll8ipVGWg4HU4hjwILsQ"},"\u6ca1\u60f3\u5230\u5728 Docker \u5bb9\u5668\u4e2d\u8bbe\u7f6e\u65f6\u533a\u8fd9\u4e48\u7b80\u5355")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5NTgcdhn6CiZ2tg44_T-FQ"},"\u5feb\u6536\u85cf\uff01\u8d85\u5f3a\u56fe\u89e3Docker\u5e38\u89c1\u547d\u4ee4\u4e0e\u5b9e\u6218\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rDSKItZ8hvgjvpp4f4VzCQ"},"\u5b9e\u65f6\u53ef\u89c6\u5316Go Runtime\u6307\u6807\uff0c\u8fd9\u4e2aGo\u5e93\u8d85\u8d5e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg"},"\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DEZPCzQul7wnZKqm1Ue6rg"},"\u4eceGo\u7a0b\u5e8f\u7b2c\u4e00\u884c\u4ee3\u7801\uff0c\u5230\u5728 K8s \u4e0a\u8fd0\u884c\uff0c\u8981\u7ecf\u5386\u591a\u5c11\u6b65")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZU61NIMxh_UOo-chNvkPXA"},"\u5728K8S\u4e0a\u7684Web\u670d\u52a1\u8be5\u600e\u4e48\u505a\u57df\u540d\u89e3\u6790\u5462")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/"},"https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uruu3qbpSLbTRJJRcWTYqg"},"Kubernetes\u5165\u95e8\u5b9e\u8df5--\u90e8\u7f72\u8fd0\u884cGo\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hoJgL-sP2OtMEFAhYNCItA"},"\u7ebf\u4e0aGo\u9879\u76ee\u7684Docker\u955c\u50cf\u5e94\u8be5\u600e\u4e48\u6784\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.opskumu.com/docker.html"},"Docker \u5b66\u4e60\u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ze096f0Utcl84c6gBwrCYw"},"\u7a0b\u5e8f\u89e3Bug\u6700\u5e38\u7528\u7684K8s\u547d\u4ee4\uff0c\u5916\u52a0\u4f7f\u7528\u7a8d\u95e8")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u5f00\u6e90\u5e93\u63a8\u8350",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J6ziP7VOitGk-lz8NGdDrA"},"HTTP \u6846\u67b6 Hertz \u5b9e\u8df5\u5165\u95e8\uff1a\u6027\u80fd\u6d4b\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124337913352945672"},"\u5b57\u8282\u5f00\u6e90WEB\u6846\u67b6Hertz\u592a\u9999\u5566\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153889167385526308"},"\u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/cloudwego/hertz"},"https://github.com/cloudwego/hertz")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.cloudwego.io/blog/2021/10/09/bytedance-practices-on-go-network-library/"},"ByteDance Practices on Go Network Library")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.cloudwego.io/docs/hertz/getting-started/"},"https://www.cloudwego.io/docs/hertz/getting-started/")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/025-MLMAbdT38kWI--AoYg"},"Go \u8bed\u8a00\u7ec8\u6781\u641c\u7d22\u63d2\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ie7LqXZQOUX0Bfn4QhHzLA"},"\u300cGo\u5f00\u6e90\u5305\u300dsnappy\uff1agoogle\u5f00\u6e90\u7684\u5feb\u901f\u3001\u65e0\u635f\u538b\u7f29\u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Vkx8zzm1SjIl4IXLib3xkQ"},"\u300cGo\u5f00\u6e90\u5305\u300dxxhash\uff1a\u6bd4\u6807\u51c6\u5e93\u66f4\u5feb\uff0c\u57fa\u4e8exxHash\u7b97\u6cd5\u5b9e\u73b0\u768464\u4f4d\u7684\u6574\u578bhash\u503c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xt0v6snX6y5jaOy1IniwVw"},"\u300cGo\u5f00\u6e90\u5305\u300denv\uff1a\u4e00\u4e2a\u5c06\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u89e3\u6790\u5230\u7ed3\u6784\u4f53\u7684\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rGPsEt-XDOayDWwLGxvcsw"},"\u300cGo\u5f00\u6e90\u5305\u300dchromedp\uff1a\u4e00\u4e2a\u57fa\u4e8eChrome DevTools\u534f\u8bae\u7684\u5e93\uff0c\u652f\u6301\u6570\u636e\u91c7\u96c6\u3001\u622a\u53d6\u7f51\u9875\u957f\u56fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248951438742339639"},"\u300cGo\u5f00\u6e90\u5305\u300dnunu\uff1a\u4e00\u4e2a\u5feb\u901f\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u811a\u624b\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_TBmfaVwvX5VDRe8kLReXA"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Shopify \u51fa\u54c1\u7684\u5b8c\u6574\u5ea6\u6700\u5b8c\u5584\u7684 Kafka \u5ba2\u6237\u7aef_sarama")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iHIxsEZf3w06GbO2sHSuRA"},"\u300cGoCN\u9177Go\u63a8\u8350\u300dGolang\u7684Ealstic\u94fe\u63a5\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wGqwfX8lEifeD_VGcITmHw"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u534f\u7a0b\u6c60ants\u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2cERDCRKlmfHKv8gY324Hg"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528 cmux \u5b9e\u73b0\u670d\u52a1\u7aef\u8fde\u63a5\u591a\u8def\u590d\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dkbpIvy1o5aLnklt0ddIDA"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528GO\u8bed\u8a00\u542f\u52a8docker Container")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uLpmEV8mI4JpfNVfSK8cRQ"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u62bd\u8c61\u8bed\u6cd5\u6811go/ast\u5e93\u4f7f\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/weT4KUTTLWdQaC6q7VrPPg"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4e07\u80fd\u7684\u5bf9\u8c61\u62f7\u8d1d\u5de5\u5177\u2014\u2014Copier")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/q3wRIvoXpnPLPJsDAPTdeA"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u6f0f\u6876\u9650\u6d41\u5e93 \u2014 uber-go/ratelimit")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/emNifkcdn9oRjVHRcQmK9w"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u65f6\u95f4\u8f6e\u7b97\u6cd5\u5b9a\u65f6\u5668antlabs/timer\u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3iPqxiK2mf9Fl5CSZ9U7RQ"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Goroutine \u6cc4\u6f0f\u9632\u6cbb\u795e\u5668 goleak")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SWyMIE1rtVDVUPEFno4xsQ"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011\u5f02\u6b65\u4efb\u52a1\u961f\u5217Asynq")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X6Fo_6pEZTIZJ-1MJNrg6A"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011protobuf\u751f\u6210Go\u4ee3\u7801\u63d2\u4ef6gogo/protobuf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZoVr9ubPgcvjX9ERiQoLyA"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Golang\u5b98\u65b9\u8ba4\u53ef\u7684websocket\u5e93-gorilla/websocket")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JrEQwQZQRwf4SymprwKUmw"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Html\u89e3\u6790\u5229\u5668-goquery\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zRmAjQ0o9n8FE1R0WcnUtQ"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u9ad8\u6027\u80fd\u4e2d\u6587\u5206\u8bcd\u5e93 gojieba")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8YRqypiW1dQQVlZkmCd1mQ"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u89e3\u6790http\u4e2d\u7684user-agent\uff0c\u5c31\u7528\u8fd9\u4e2a\u5305\uff1auser_agent")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/92O1SHs4tw1FMcDeQoSfkA"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u63a8\u8350\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u3001\u8bed\u4e49\u5316\u7684\u65f6\u95f4\u5904\u7406\u5e93\uff1acarbon")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n-kU6nwhOH6ouhufrP_1kQ"},"Go\u6bcf\u65e5\u4e00\u5e93\u4e4bCSRF\u5e93\u7684\u4f7f\u7528\u65b9\u5f0f\u548c\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/f4FAt-RgraOFXSfZmWjeoQ"},"Go \u6bcf\u65e5\u4e00\u5e93\u4e4b go-cache \u7f13\u5b58")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KCj-mCkZpcEu3GXkuRLTuA"},"\u300cGo\u5de5\u5177\u7bb1\u300dredis\u5b98\u7f51\u63a8\u8350\u7684go\u7248\u672c\u7684\u5206\u5e03\u5f0f\u9501\uff1aredsync")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/samber/lo"},"https://github.com/samber/lo")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/nikoksr/notify"},"https://github.com/nikoksr/notify")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-chi/chi"},"https://github.com/go-chi/chi")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/gin-gonic/examples"},"https://github.com/gin-gonic/examples")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zLNwq32UKaCsaAXn2BaZkw"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u91cd\u78c5\u63a8\u8350\uff1a\u4e00\u4e2a\u56fd\u4ea7\u7684\uff0cstar\u9ad8\u8fbe12k+\u7684\u64cd\u4f5cexcel\u7684\u5305\uff1aExcelize")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Y3NGQH3hrT85O7aN7IrCIQ"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u4e00\u4e2a\u8ba9\u7ec8\u7aef\u5185\u5bb9\u5f69\u8272\u5316\u7684\u5de5\u5177\uff1aColor")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u76f8\u5173\u8d44\u6e90",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://research.swtch.com/"},"Russ Cox \u7684\u4e2a\u4eba\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://tonybai.com/articles/"},"Tony Bai \u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://gopherdaily.tonybai.com/"},"Gopher Daily")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://xargin.com/"},"ChatGPT \u4e0e\u6211\u5408\u529b\u5f00\u53d1 xargin blog archive \u63d2\u4ef6\uff1a\u66f9\u5927\u535a\u5ba2\u7684\u65b0\u5947\u63a2\u9669")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://qcrao.com/"},"qcrao \u7684\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang-design/go-questions"},"Go \u7a0b\u5e8f\u5458\u9762\u8bd5\u7b14\u8bd5\u5b9d\u5178")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/gopl-zh/"},"Go\u8bed\u8a00\u5723\u7ecf\uff08\u4e2d\u6587\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"http://books.studygolang.com/The-Golang-Standard-Library-by-Example/"},"Go\u8bed\u8a00\u6807\u51c6\u5e93\u4e66\u7c4d")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.topgoer.cn/"},"\u5730\u9f20\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.topgoer.cn/docs/golang/golang-1ccjbpfstsfi1"},"go\u8bed\u8a00\u4e2d\u6587\u6587\u6863 - \u5730\u9f20\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://go-proverbs.github.io/"},"Go \u5b98\u65b9\u8c1a\u8bed Go Proverbs")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cidtQEAfuFWuYveKFbFvKQ"},"GoLand 2023.2 \u53d1\u5e03\uff1a\u6709 AI \u52a9\u624b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SVMj-PvI1l-oSlxI4zaNcw"},"GoLand 2023.1 \u6b63\u5f0f\u53d1\u5e03\uff0c\u770b\u6709\u54ea\u4e9b\u65b0\u529f\u80fd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IvL24_7iuuRp9Y3dljHaHQ"},"GoLand \u8fce\u6765\u4e94\u5468\u5e74\uff0c\u540c\u65f6\u53d1\u5e03 2022.3\uff1a\u6709\u5f69\u86cb")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w"},"\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw"},"\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/Alikhll/golang-developer-roadmap"},"golang-developer-roadmap: 2020 \u5e74\u6210\u4e3a Go \u5f00\u53d1\u8005\u7684\u8def\u7ebf\u56fe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-admin-team/go-admin"},"go-admin: \u57fa\u4e8e Gin + Vue + Element UI \u7684\u72ec\u7acb\u524d\u540e\u7aef\u6743\u9650\u7ba1\u7406\u7cfb\u7edf\u7684\u811a\u624b\u67b6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/avelino/awesome-go"},"awesome-go: \u7cbe\u9009\u7684 Go \u6846\u67b6\u3001\u5e93\u548c\u8f6f\u4ef6\u7684\u5217\u8868")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wKxg6IVZCNK3NG2Os9_3jg"},"Go 13 \u5468\u5e74\u5566\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ"},"\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://golangbyexample.com/"},"Golang By Example")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://golangbyexample.com/golang-comprehensive-tutorial/"},"Golang Advanced Tutorial")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://golangbyexample.com/all-design-patterns-golang/"},"All Design Patterns in Go (Golang)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://techbyexample.com/system-design-questions/"},"System Design Questions")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.gokit.info/post/go-solid-design/"},"SOLID Go Design - Go\u8bed\u8a00\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/mohuishou/go-design-pattern"},"go design pattern")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XIwfj_AdZqX_vHM4VIq9EA"},"\u4e07\u5b57\u8be6\u6587\u9610\u91ca\u7a0b\u5e8f\u5458\u4fee\u70bc\u4e4b\u9053")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/c3RApB8a98tWahgC9mahJg"},"\u4e07\u5b57\u8be6\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u505a Code Review")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/talkgo/read"},"Go \u5b66\u4e60\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ipbUy3GBRMFat9jUSssMMw"},"1024\uff0c\u6211\u4eec\u7684\u8282\u65e5\uff0cGopher \u8be5\u5e72\u70b9\u5565"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/qyuhen/go"},"Go \u8bed\u8a00\u5b66\u4e60\u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/GoExpertProgramming/"},"GO\u4e13\u5bb6\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://go101.org/article/101.html"},"Go \u8bed\u8a00 101")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://go101.org/optimizations/101.html"},"Go Optimizations 101")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/"},"\u5f00\u6e90\u56fe\u4e66\u5728\u7ebf\u9605\u8bfb - Go\u8bed\u8a00\u4e2d\u6587\u7f51")))),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/go-interview/set/xq5788"},"Go Interview")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/halfrost/LeetCode-Go"},"LeetCode Cookbook")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.halfrost.com/leetcode/"},"LeetCode Cookbook\uff08\u5728\u7ebf\u9605\u8bfb\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-compile-intro/"},"Go \u8bed\u8a00\u8bbe\u8ba1\u4e0e\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/advanced-go-programming-book/"},"Go\u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b(Advanced Go Programming)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/geektutu/high-performance-go"},"Go \u8bed\u8a00\u9ad8\u6027\u80fd\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang-design/under-the-hood"},"Go \u8bed\u8a00\u539f\u672c")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://golang.design/under-the-hood/"},"Go \u8bed\u8a00\u539f\u672c\uff08\u5728\u7ebf\u9605\u8bfb\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://time.geekbang.org/column/intro/100093501"},"Tony Bai \xb7 Go \u8bed\u8a00\u7b2c\u4e00\u8bfe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://time.geekbang.org/column/intro/100061801"},"Go \u5e76\u53d1\u7f16\u7a0b\u5b9e\u6218\u8bfe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://time.geekbang.org/column/article/408409"},"Rust \u7f16\u7a0b\u7b2c\u4e00\u8bfe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://quickref.me/go"},"Go cheatsheet")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/miguelmota/golang-for-nodejs-developers"},"Golang for Node.js Developers")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://studygolang.gitbook.io/learn-go-with-tests"},"Learn Go with tests")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://makeoptim.com/golang/standards/project-layout"},"golang \u7f16\u7a0b\u89c4\u8303 - \u9879\u76ee\u76ee\u5f55\u7ed3\u6784")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/talkgo/night"},"Go \u591c\u8bfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VKPSqS50Un29x30KIgB0tA"},"\u5df2\u5165\u5b57\u8282\u7684\u5927\u4f6c\u5404\u5382\u4e09\u5e74Go\u9762\u7ecf")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u7b97\u6cd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fangbinwei/algorithm-practice"},"https://github.com/fangbinwei/algorithm-practice")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u9879\u76ee\u53c2\u8003",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/wangzhongyang007/goframe-shop-v2"},"https://github.com/wangzhongyang007/goframe-shop-v2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fangbinwei/aliyun-oss-website-action"},"https://github.com/fangbinwei/aliyun-oss-website-action")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u6559\u7a0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.w3cschool.cn/go/"},"https://www.w3cschool.cn/go/")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u6807\u51c6\u5e93\u6587\u6863",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://pkg.go.dev/std"},"https://pkg.go.dev/std")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u5355\u5143\u6d4b\u8bd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/ALEX_CYL/article/details/121793330"},"Golang-\u5355\u5143\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/377834750"},"\u624b\u628a\u624b\u6559\u4f60\u5982\u4f55\u8fdb\u884c Golang \u5355\u5143\u6d4b\u8bd5")))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/471317280"},"Go \u8bed\u8a00\u4e0e\u5e76\u53d1\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Xzlt_WcdcfLWhofafY3c6g"},"Golang \u7b80\u6d01\u67b6\u6784\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7065197280223035422"},"\u5982\u4f55\u4f7f\u7528\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\u63d0\u5347\u4ee3\u7801\u7684\u7b80\u6d01\u6027")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/36CqC1U54LUd4-izt4iZ1g"},"\u6df1\u5165\u7406\u89e3Go Json.Unmarshal\u7cbe\u5ea6\u4e22\u5931\u4e4b\u8c1c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EvkMQCPwg-B0fZonpwXodg"},"Go Error \u5904\u7406\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000013739000"},"Golang \u65b0\u624b\u53ef\u80fd\u4f1a\u8e29\u7684 50 \u4e2a\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/437626980"},"Golang\u8bbe\u8ba1\u6a21\u5f0f\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/267341653"},"Golang \u5355\u5143\u6d4b\u8bd5\u6307\u5f15")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7041846339189080101"},"\u4f7f\u7528Golang\u3001Gin\u548cReact\u3001esbuild\u5f00\u53d1\u7684Blog")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-gorm/gorm"},"gorm - Golang \u7684\u51fa\u8272 ORM \u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/gofiber/fiber"},"fiber\uff1a\u53d7\u5230 Express \u542f\u53d1\u7684 Web \u5e94\u7528\u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://go.dev/"},"Golang \u5b98\u65b9\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/426368274"},"Golang \u7f16\u7a0b\u601d\u7ef4\u548c\u5de5\u7a0b\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://gobyexample.com/"},"Go by example"))),(0,n.kt)("h2",{id:"rust-\u5b66\u4e60"},"Rust \u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf"},"PDF\uff1a\u4ece JavaScript \u5230 Rust\uff1a\u65b0\u4e66\u514d\u8d39\u53d1\u5e03")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/google/comprehensive-rust"},"Google \u51fa\u54c1\u7684 Rust \u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://course.rs/about-book.html"},"Rust\u8bed\u8a00\u5723\u7ecf(Rust Course)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HKkt9cNZsUFdCR4nAlHeBA"},"\u63ed\u79d8\u524d\u7aef\u773c\u4e2d\u7684Rust\uff01")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/book/"},"Rust \u5b98\u65b9\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/std/"},"Rust \u6807\u51c6\u5e93\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/stable/rust-by-example/"},"Rust by Example")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7143822279992934436"},"\u9009\u62e9 Go \u8fd8\u662f Rust\uff1fCloudWeGo-Volo \u57fa\u4e8e Rust \u8bed\u8a00\u7684\u63a2\u7d22\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/417534662"},"\u7528Rust\u9508\u5316Vue Compiler")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/TheAlgorithms/Rust"},"\u7528 Rust \u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5408\u8f91"))),(0,n.kt)("h2",{id:"\u7f51\u7ad9\u63a8\u8350"},"\u7f51\u7ad9\u63a8\u8350"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u6587\u6863\u76f8\u5173")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/search?q=&type="},"GitHub \u641c\u7d22\u9875\u9762")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/zh-CN/"},"MDN \u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://caniuse.com/"},"caniuse\uff1a\u67e5\u8be2 API \u517c\u5bb9\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://snyk.io/advisor/"},"snyk\uff1a\u67e5\u8be2 NPM\u3001Go\u3001Docker \u5b89\u5168\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://bundlephobia.com/"},"bundlephobia\uff1a\u67e5\u8be2 NPM \u5305\u4f53\u79ef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://oscarotero.com/deno/"},"Deno cheat sheet")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://beta.reactjs.org/learn"},"React Docs Beta")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://overreacted.io/"},"Overreacted")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://tailwindcss.com/docs/configuration"},"tailwindcss \u6837\u5f0f\u53c2\u8003")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://explainshell.com/"},"Explain Shell")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://es6.ruanyifeng.com/"},"\u300a\u962e\u4e00\u5cf0 ES6 \u6559\u7a0b\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/yeasy/docker_practice"},"Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/koala-coding/goodBlog"},"\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fblog.poetries.top%2Fbrowser-working-principle%2F"},"\u300a\u6d4f\u89c8\u5668\u5de5\u4f5c\u539f\u7406\u4e0e\u5b9e\u8df5\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fwebpack.wuhaolin.cn%2F"},"\u300a\u6df1\u5165\u6d45\u51fa webpack\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fprogrammercarl.com%2F"},"\u300a\u4ee3\u7801\u968f\u60f3\u5f55\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fyuchengkai.cn%2F"},"\u300a\u524d\u7aef\u8fdb\u9636\u4e4b\u9053\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Freact.iamkasong.com%2F"},"\u300aReact \u6280\u672f\u63ed\u79d8\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/7kms/react-illustration-series"},"\u300a\u56fe\u89e3 React \u6e90\u7801\u7cfb\u5217\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fustbhuangyi.github.io%2Fvue-analysis%2Fv2%2Fprepare%2F"},"\u300aVue \u6280\u672f\u63ed\u79d8\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"http://caibaojian.com/vue-design/"},"\u300aVue\u6280\u672f\u5185\u5e55\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://i5ting.github.io/How-to-learn-node-correctly/"},"\u72fc\u53d4\uff1a\u5982\u4f55\u6b63\u786e\u7684\u5b66\u4e60Node.js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://q.shanyue.tech/engineering/"},"\u5927\u5382\u9762\u8bd5\u9898\u6bcf\u65e5\u4e00\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://shanyue.tech/op/#%E9%A2%84%E8%A7%88"},"\u524d\u7aef\u5de5\u7a0b\u5316\u3001\u4e2a\u4eba\u670d\u52a1\u5668\u8fd0\u7ef4\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://xiaoflyfish.cn/"},"MySQL\u3001Linux\u3001\u670d\u52a1\u7aef\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://xcoder.in/"},"Khaidi Chu \u7684\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/chenyuntc/pytorch-book"},"\u300a\u6df1\u5ea6\u5b66\u4e60\u6846\u67b6PyTorch\uff1a\u5165\u95e8\u4e0e\u5b9e\u8df5\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/datawhalechina/pumpkin-book"},"\u300a\u673a\u5668\u5b66\u4e60\u300b\uff08\u897f\u74dc\u4e66\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Mh411e7VU"},"\u300a\u673a\u5668\u5b66\u4e60\u300b\u914d\u5957\u89c6\u9891\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://abseil.io/blog/04222021-swe-book"},"Software Engineering at Google")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/dair-ai/ML-YouTube-Courses"},"ML YouTube Courses")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/vasanthk/how-web-works"},"How Web Works"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u5f00\u6e90\u63a8\u8350")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://nextjs.org/docs/getting-started"},"Next.js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://tailwindcss.com/docs/configuration"},"tailwindcss \u6837\u5f0f\u53c2\u8003")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://pnpm.io/installation"},"PNPM")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.typescriptlang.org/docs/"},"TypeScript")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://vitejs.dev/"},"Vite")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://storybook.js.org/"},"Storybook"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u5728\u7ebf Plyaground")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://godbolt.org/"},"\u751f\u6210\u5404\u4e2a\u8bed\u8a00\u7684\u6c47\u7f16\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://sfc.vuejs.org/"},"Vue SFC Playground")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fcodesandbox.io%2Fdashboard%2Fhome"},"CodeSandBox")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://codepen.io/"},"CodePen")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.astexplorer.net/"},"AST explorer\uff1a\u53ef\u89c6\u5316 AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fjex.im%2Fregulex"},"\u6b63\u5219\u8868\u8fbe\u5f0f\u53ef\u89c6\u5316"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u7f16\u7a0b\u98ce\u683c\u6307\u5357")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/typescript-eslint/typescript-eslint"},"typescript-eslint")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/AlloyTeam/eslint-config-alloy"},"eslint-config-alloy")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/airbnb/javascript"},"Airbnb JavaScript Style Guide")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/ryanmcdermott/clean-code-javascript"},"clean-code-javascript"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u6280\u672f\u793e\u533a")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/"},"https://dev.to/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://medium.com/"},"https://medium.com/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://linuxhandbook.com/"},"https://linuxhandbook.com/"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u5de5\u5177\u76f8\u5173")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://plantuml.com/"},"plantuml\uff1a\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\u3001\u7528\u4f8b\u56fe\u3001\u7c7b\u56fe\u3001\u601d\u7ef4\u5bfc\u56fe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.npmjs.com/package/njt"},"njt\uff1a\u5feb\u901f\u5bfc\u822a\u81f3 npm \u5305\u8d44\u6e90")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.skypack.dev/"},"skypack\uff1a\u65e0\u9700\u6784\u5efa\u5de5\u5177\u4f7f\u7528\u5404\u79cd\u7ecf\u8fc7\u4f18\u5316\u7684 npm \u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fcarbon.now.sh%2F"},"carbon\uff1a\u751f\u6210\u4ee3\u7801\u7247")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://unbug.github.io/codelf/"},"codelf \u53d8\u91cf\u547d\u540d\u795e\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://openbase.com/"},"openbase\uff1a\u67e5\u8be2\u5404\u79cd\u7b2c\u4e09\u65b9\u5e93"))),(0,n.kt)("h2",{id:"\u5b66\u4e60\u8d44\u6e90"},"\u5b66\u4e60\u8d44\u6e90"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u300aLinux Shell \u811a\u672c\u653b\u7565\uff08\u7b2c2\u7248\uff09\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300a\u63a8\u8350\u7cfb\u7edf\u2014\u2014\u6280\u672f\u3001\u8bc4\u4f30\u53ca\u9ad8\u6548\u7b97\u6cd5\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aGo \u8bed\u8a00\u7f16\u7a0b\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aGo \u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300a\u64cd\u4f5c\u7cfb\u7edf\u5bfc\u8bba\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aMySQL\u6280\u672f\u5185\u5e55\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aRedis\u8bbe\u8ba1\u4e0e\u5b9e\u73b0\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA"},"\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1EW411u7th"},"\u3010\u8ba1\u7b97\u673a\u79d1\u5b66\u901f\u6210\u8bfe\u3011","[","40\u96c6\u5168/\u7cbe\u6821","]"," - Crash Course Computer Science")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1iW411d7hd"},"\u3010\u7cbe\u6821\u4e2d\u82f1\u5b57\u5e55\u30112015 CMU 15-213 CSAPP \u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf \u8bfe\u7a0b\u89c6\u9891"))),(0,n.kt)("h2",{id:"\u9762\u8bd5\u76f8\u5173"},"\u9762\u8bd5\u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ConardLi/awesome-coding-js"},"JS \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 - awesome-coding-js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/trekhleb/javascript-algorithms"},"JavaScript Algorithms and Data Structures")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023208826472005668"},"JavaScript\u7b97\u6cd5\u57fa\u7840\u53ca\u9762\u8bd5\u603b\u7ed3\uff081w1\u5b57\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903929705136141"},"\u5982\u4f55\u5199\u51fa\u4e00\u4e2a\u60ca\u8273\u9762\u8bd5\u5b98\u7684\u6df1\u62f7\u8d1d?")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904118704668685"},"\u9762\u4e86\u51e0\u4e2a\u8bf4\u81ea\u5df1\u7cbe\u901a Vue \u7684\u540c\u5b66")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/xgangzai/article/details/120375992"},"\u9ad8\u9891react\u9762\u8bd5\u989820\u9053\uff08\u9644\u8be6\u89e3\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903885488783374"},"\u30101 \u6708\u6700\u65b0\u3011\u524d\u7aef 100 \u95ee\uff1a\u80fd\u641e\u61c2 80% \u7684\u8bf7\u628a\u7b80\u5386\u7ed9\u6211"))),(0,n.kt)("h2",{id:"-\u6398\u91d1\u5927\u4f6c\u6c47\u603b"},"\ud83d\udcd2 \u6398\u91d1\u5927\u4f6c\u6c47\u603b"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Vue \u6e90\u7801\u3001\u54cd\u5e94\u5f0f\u673a\u5236\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2330620350708823/posts"},"ssh")," \u3001",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2137106333044861/posts"},"\u9ec4\u8f76")),(0,n.kt)("li",{parentName:"ul"},"React \u8fdb\u9636\u7cfb\u5217\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2418581313687390/posts"},"\u6211\u4e0d\u662f\u5916\u661f\u4eba")),(0,n.kt)("li",{parentName:"ul"},"Webpack \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/1820446985555544/posts"},"Tecvan")),(0,n.kt)("li",{parentName:"ul"},"\u8bbe\u8ba1\u6a21\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/3544481219495806/posts"},"DYBOY")),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199\u6e90\u7801\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2295436011645655/posts"},"\u848b\u9e4f\u98de")," \u3001",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/1204720476893064/posts"},"\u524d\u7aef\u9633\u5149")),(0,n.kt)("li",{parentName:"ul"},"Webpack5\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/4300945218607197"},"\u6e05\u6c64\u997a\u5b50")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/703340610597064/posts"},"\u5bd2\u8349")),(0,n.kt)("li",{parentName:"ul"},"\u603b\u7ed3\u5927\u5e08\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2330620350432110/posts"},"JowayYoung")),(0,n.kt)("li",{parentName:"ul"},"\u6e90\u7801\u5206\u6790\uff1a\u82e5\u5ddd"),(0,n.kt)("li",{parentName:"ul"},"\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/1556564164489389/posts"},"shanyue")),(0,n.kt)("li",{parentName:"ul"},"CSS \u5404\u79cd\u7279\u6548\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2330620350437678/posts"},"chokcoco")),(0,n.kt)("li",{parentName:"ul"},"Nodejs \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/people/liuyong25/posts"},"\u5929\u732a")),(0,n.kt)("li",{parentName:"ul"},"Umi \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/mdh/weekly/rhiudh"},"MDH \u524d\u7aef\u5468\u520a")),(0,n.kt)("li",{parentName:"ul"},"Antd\u3001Umi\u3001Node.js\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/antfe/featured/ys58hy"},"\u652f\u4ed8\u5b9d\u4f53\u9a8c\u79d1\u6280\u7cbe\u9009")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u3001\u5168\u6808\u6280\u672f\u4e13\u520a\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/column/ali-nanjing"},"\u963f\u91cc CCO \u4f53\u9a8c\u6280\u672f\u4e13\u520a")),(0,n.kt)("li",{parentName:"ul"},"Golang \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/340814811"},"\u817e\u8baf\u6280\u672f\u5de5\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u88c5\u903c\u6280\u5de7108\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/u/king_hcj"},"\u72ec\u9493\u5bd2\u6c5f\u96ea")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u4e5d\u6761 bug \u5206\u4eab\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/u/lulu_up"},"lulu_up")),(0,n.kt)("li",{parentName:"ul"},"Vue3 \u6e90\u7801\u5171\u8bfb\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1bS4y1T7ng"},"\u524d\u7aef\u6768\u6751\u957f")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u5de5\u7a0b\u5316\u3001\u5b66\u4e60 Golang\uff1a\u6d1b\u7af9"),(0,n.kt)("li",{parentName:"ul"},"Node.js \u76f8\u5173\uff1a\u4e94\u6708\u541b")),(0,n.kt)("h2",{id:"-\u5f85\u5b66\u4e60\u5185\u5bb9"},"\ud83d\udcd2 \u5f85\u5b66\u4e60\u5185\u5bb9"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017360824939315207"},"babel\u6e90\u7801\u8be6\u89e3-v1.7.8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904094079926286"},"\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904116913700877"},"\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6889247428797530126"},"\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903783005175815"},"\u5982\u4f55\u5229\u7528lerna\u7ba1\u7406\u6a21\u5757")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6969544464113074189"},"\u57fa\u4e8e lerna \u7684\u591a\u5305 JavaScript \u9879\u76ee\u642d\u5efa\u7ef4\u62a4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903896767283207#heading-5"},"React\u6027\u80fd\u4f18\u5316\u5c0f\u8d34\u58eb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903929726107655"},"\u795e\u5947\u7684lambda\u8868\u8fbe\u5f0f\u2014\u2014\u51fd\u6570\u5f0f\u7f16\u7a0b\u5fc5\u5b66")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903954002739213"},"npm\u8fdb\u9636\u2014\u2014\u5982\u4f55\u62e5\u6709\u81ea\u5df1\u7684\u5305\u548c\u6d41\u7a0b\u81ea\u52a8\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904162124103693"},"React Hooks\u7684\u82b1\u6837\u73a9\u6cd5"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"useDark\uff0cuseClickOutside\uff0c\u5168\u5c40\u72b6\u6001\u7ba1\u7406"))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903845227659271"},"\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u8981\u80cc")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903825145511950"},"\u6211\u4eec\u6216\u8bb8\u4e0d\u9700\u8981 classnames \u8fd9\u4e2a\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7014431215302213668"},"\u56fd\u5e86\u7206\u809d\uff0c\u7528vite+vue3+ts\u5b9e\u73b0\u4e00\u4e2a\u7f51\u9875\u7248\u7684typora\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982192362583752741"},"\u624b\u6478\u624b\u6559\u4f60\u4f7f\u7528\u6700\u65b0\u7248husky(v7.0.1)\u8ba9\u4ee3\u7801\u66f4\u4f18\u96c5\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7015476516196712462"},"\u5feb\u901f\u5165\u624bElectron\uff0c\u62e5\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u684c\u9762\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6945236994247098381"},"\u5728\u5927\u5382\u662f\u5982\u4f55\u9ad8\u6548\u7ec4\u7ec7 npm script \u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6940042028243746823"},"\u524d\u7aef\u5f00\u53d1\u8005\u5468\u520a\u7b2c\u4e09\u671f\uff1a\u5404\u5927\u5382 webpack5 \u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6937176680251424775#heading-7"},"\u3010\u8bd1\u3011\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 ViteJS \u4e2d\u82f1\u53cc\u8bed\u5b57\u5e55 \uff5c \u6280\u672f\u70b9\u8bc4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6924258563862822919"},"Webpack5 \u65b0\u7279\u6027\u4e1a\u52a1\u843d\u5730\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://webpack.docschina.org/guides/development/#choosing-a-development-tool"},"Webpack \u5b98\u65b9\u5f00\u53d1\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P3foOrcu4StJDGdX9xavng"},"\u6784\u5efa\u6548\u7387\u5927\u5e45\u63d0\u5347\uff0cwebpack5 \u5728\u4f01\u9e45\u8f85\u5bfc\u7684\u5347\u7ea7\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZP2IigNVSIZKGuYxNYOYgw"},"\u5982\u4f55\u5229\u7528 monorepo \u7b56\u7565\u7ba1\u7406\u4ee3\u7801\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6924854598268108807"},"All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007252464726458399"},"\u4e00\u987f\u64cd\u4f5c\uff0c\u6211\u628a Table \u7ec4\u4ef6\u6027\u80fd\u63d0\u5347\u4e86\u5341\u500d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7005019784429469704"},"MySQL \u4ece\u5165\u95e8\u5230\u5b9e\u8df5\uff0c\u4e07\u5b57\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904080972709901"},"\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903919995322382"},"\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5"))),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg"},"\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026119446162997261"},"\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7077365102743126052"},"\u56db\u4e2a\u771f\u79c0React\u7528\u6cd5\uff0c\u4f60\u503c\u5f97\u62e5\u6709")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw"},"\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA"},"pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/455809528"},"\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7152898360498716702"},"Vue\u7ec4\u4ef6\u5e93\u6587\u6863\u7ad9\u70b9\u7684\u642d\u5efa\u601d\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7151653067593613320#heading-18"},"\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7148746931802472485#heading-8"},"React-router\u4ece0\u52301")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118937685653192735#heading-7"},"\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7131222991681093639"},"768. \u6700\u591a\u80fd\u5b8c\u6210\u6392\u5e8f\u7684\u5757 II : \u5e38\u89c4\u8d2a\u5fc3\u6784\u9020\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7128597557634138148"},"\ud83e\udd8a\u3010\u524d\u7aef\u5de5\u7a0b\u5316\u3011\u4e3a\u4ec0\u4e48\u5927\u5382\u90fd\u8981\u5f00\u53d1\u81ea\u5df1\u7684\u811a\u624b\u67b6\uff1f\ud83e\udd84\ufe0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7120893568553582622"},"\u5feb\u4e0a\u8f66\uff01\u4ece\u96f6\u5f00\u59cb\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6938201650012094495"},"\u5199\u7ed9\u524d\u7aef\u7684\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u57fa\u7840\u5165\u95e8\uff08\u4e00\uff09\u8fd4\u749e\u5f52\u771f\uff1a\u4ece\u5f15\u7528\u7c7b\u578b\u5230\u88f8\u6307\u9488")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101457212085633054#heading-1"},"\u6a21\u5757\u8054\u90a6\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw"},"\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/go-interview/set/xq5788"},"Go Interview")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://books.halfrost.com/leetcode/ChapterFour/0200~0299/0287.Find-the-Duplicate-Number/"},"LeetCode Cookbook")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s?__biz=MzUxMDI4MDc1NA==&mid=2247483807&idx=1&sn=9c7aede4f675f2de49ddc08ab1a95a71&chksm=f90414c2ce739dd4b8711c0043286fba9744b8d9c86c75c7ac7750d28cd2fed43f749eb5de99&scene=178&cur_album_id=1383459655464337409#rd"},"Go Gin \u7cfb\u5217\u4e8c\uff1a\u521d\u59cb\u5316\u9879\u76ee\u53ca\u516c\u5171\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://orizens.com/blog/500ms-to-1-7ms-in-react-a-journey-and-a%20checklist/"},"500ms to 1.7ms In React: A Journey And A Checklist")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157902763534319624"},"\u6f2b\u8c08\u6784\u5efa\u5de5\u5177(\u5341):\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7170852747749621791"},"\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085257325165936648"},"\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684\uff1f\ud83c\udf89\ud83c\udf89\ud83c\udf89")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg"},"Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/aurelievache/learning-go-by-examples-part-7-create-a-cross-platform-gui-desktop-app-in-go-44j1"},"Learning Go by examples: part 7 - Create a cross-platform GUI/Desktop app in Go")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/aurelievache/understanding-docker-part-37-content-trust-18n3"},"Understanding Docker: part 37 \u2013 Content Trust")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/aurelievache/understanding-kubernetes-part-47-kubernetes-126-changelog-2404"},"Understanding Kubernetes: part 47 \u2013 Kubernetes 1.26 Changelog")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7115634967945674765"},"Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7116141318853623839"},"\u4e3a\u4ec0\u4e48 React \u7684 Diff \u7b97\u6cd5\u4e0d\u91c7\u7528 Vue \u7684\u53cc\u7aef\u5bf9\u6bd4\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121378029682556958"},"\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406"))),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094984070999834655"},"\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147939014870302756"},"\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117512204059934733"},"react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118937685653192735"},"\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944863057000529933"},"\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406"))),(0,n.kt)("h2",{id:"-\u5c0f\u76ee\u6807"},"\ud83d\udcd2 \u5c0f\u76ee\u6807"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Vue 3.x \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"Vuex 4.x \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"Vue-Router \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u642d\u5efa\u811a\u624b\u67b6\u5de5\u5177\uff08Webpack5 \u65b0\u7279\u6027\u5b9e\u8df5\uff09\uff1b"),(0,n.kt)("li",{parentName:"ul"},"VS Code extension \uff1b"),(0,n.kt)("li",{parentName:"ul"},"cocos \u6e38\u620f\u5f00\u53d1\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199 redux \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199 redux-thunk \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199 Promise/A+ \uff1b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904116913700877"},"\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6945319439772434469"},"\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7055202073511460895"},"V8 Promise\u6e90\u7801\u5168\u9762\u89e3\u8bfb\uff0c\u5176\u5b9e\u4f60\u5bf9Promise\u4e00\u65e0\u6240\u77e5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904094079926286"},"\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043758954496655397"},"\u624b\u628a\u624b\u4e00\u884c\u4e00\u884c\u4ee3\u7801\u6559\u4f60\u201c\u624b\u5199Promise\u201c\uff0c\u5b8c\u7f8e\u901a\u8fc7 Promises/A+ \u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b")))),(0,n.kt)("li",{parentName:"ul"},"\u6392\u5e8f\u7b97\u6cd5\uff0c\u6876\u6392\u5e8f\u3001\u8ba1\u6570\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6 O(n) \uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u6bcf\u65e5\u7b97\u6cd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://labuladong.gitee.io/algo/"},"https://labuladong.gitee.io/algo/"),"\uff08\u56fd\u5185\u901f\u5ea6\u5feb\uff0c\u4f53\u9a8c\u597d\uff0c\u63a8\u8350\uff09"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://labuladong.github.io/algo/"},"https://labuladong.github.io/algo/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AzQzw-pC8A-0kS0NJn2eWw"},"\u624b\u628a\u624b\u5237\u4e8c\u53c9\u6811\u7cfb\u5217\u5b8c\u7ed3\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hGrTUmM1zusPZZ0nA9aaNw"},"\u524d\u7f00\u6811\u7b97\u6cd5\u6a21\u677f\u79d2\u6740 5 \u9053\u7b97\u6cd5\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5GO2ZITncVArdm4KITBd9g"},"\u96c6\u5408\u5212\u5206\u95ee\u9898\uff1a\u6392\u5217\u7ec4\u5408\u4e2d\u7684\u56de\u6eaf\u601d\u60f3\uff08\u4fee\u8ba2\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8ZTMhvHJK_He48PpSt_AmQ"},"\u5feb\u901f\u6392\u5e8f\u7684\u6b63\u786e\u7406\u89e3\u65b9\u5f0f\u53ca\u8fd0\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A"},"\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/njl6nuid0aalZdH5tuDpqQ"},"\u4e00\u6587\u79d2\u6740 5 \u9053\u6700\u8fd1\u516c\u5171\u7956\u5148\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OQAzopRncZe5cb9_of4mCQ"},"\u7b97\u6cd5\u65f6\u7a7a\u590d\u6742\u5ea6\u5206\u6790\u5b9e\u7528\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zhaurXhrAiHsfgGAOfAuMw"},"\u52a8\u6001\u89c4\u5212\u7b54\u7591\u7bc7\uff08\u4fee\u8ba2\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6vwNBr48D36n6E3EawFUqg"},"\u8bba\u52a8\u6001\u89c4\u5212\u7a77\u4e3e\u7684\u4e24\u79cd\u89c6\u89d2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iL7tCl6pqw0fTatGSemY-g"},"\u9ad8\u9891\u9762\u8bd5\u7cfb\u5217\uff1a\u5355\u8bcd\u62c6\u5206\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HiEft8sW5QzHcM5mb5_V6g"},"\u522b\u7528 KMP \u4e86\uff0c Rabin-Karp \u7b97\u6cd5\u4e86\u89e3\u4e0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XXsWwDml_zHiTEFPZtbe3g"},"\u5fae\u8f6f\u9762\u8bd5\u9898\u89e3\u6790\uff1a\u4e11\u6570\u7cfb\u5217\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vxQDGfshcSVjs9EYmV8q3Q"},"\u8bf4\u900f\u6e38\u620f\u4e2d\u5e38\u7528\u7684\u4e24\u79cd\u968f\u673a\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kI0HUTFVr4YEBpLRZWLEDg"},"\u6211\u7528\u6d88\u606f\u961f\u5217\u505a\u4e86\u4e00\u6b3e\u8054\u673a\u5c0f\u6e38\u620f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mFLCL_Dyz5-CtZMZJmOXKw"},"Union Find \u5e76\u67e5\u96c6\u7b97\u6cd5\u539f\u7406\u53ca\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4vHfaNnn1OpWQJcsssWWdQ"},"\u5fc5\u77e5\u5fc5\u4f1a\u4f4d\u8fd0\u7b97\u6280\u5de7\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7152708637817831432"},"\u3010\u9762\u8bd5\u9ad8\u9891\u9898\u3011\u96be\u5ea6 1.5/5\uff0c\u591a\u89e3\u6cd5\u7ecf\u5178\u9762\u8bd5\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9Q4JAuSATq3WgN7krdGTWg"},"DFS/\u56de\u6eaf/\u52a8\u6001\u89c4\u5212\u7b97\u6cd5\u7684\u878d\u4f1a\u8d2f\u901a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ir1Hk06HcT8W_qz0MtyONA"},"2021 \u516c\u4f17\u53f7\u7cbe\u9009\u6587\u7ae0\u76ee\u5f55")))),(0,n.kt)("li",{parentName:"ul"},"\u770b\u4e0b\u9762\u7684\u6587\u7ae0\uff0c\u624b\u5199\u4e00\u4e2a Webpack",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6930877602840182791"},"\u624b\u5199\u4e00\u4e2awebpack\uff0c\u770b\u770bAST\u600e\u4e48\u7528\uff5c\u725b\u6c14\u51b2\u5929\u65b0\u5e74\u5f81\u6587")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6987036612035084296"},"\u4eca\u5929\uff0c\u6211\u4eec\u6765\u5b9e\u73b0\u4e00\u4e2a\u57fa\u7840\u7248\u7684webpack")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6854573217336541192"},"\u624b\u5199webpack\u6838\u5fc3\u539f\u7406\uff0c\u518d\u4e5f\u4e0d\u6015\u9762\u8bd5\u5b98\u95ee\u6211webpack\u539f\u7406")))),(0,n.kt)("li",{parentName:"ul"},"Webapck \u7f16\u8bd1\u6d41\u7a0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7115598540721618944"},"Webpack5 \u6838\u5fc3\u539f\u7406\u4e0e\u5e94\u7528\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031546400034947108"},"Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026658230365323301"},"\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6859538537830858759"},"\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7077484559893266439"},"100\u884c\u4ee3\u7801\u5b9e\u73b0\u4e00\u4e2a\u7ec4\u4ef6\u5f15\u7528\u6b21\u6570\u7edf\u8ba1\u63d2\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ronami/minipack"},"https://github.com/ronami/minipack")))),(0,n.kt)("li",{parentName:"ul"},"\u624b\u628a\u624b\u5b9e\u73b0\u4e00\u4e2a babel \u63d2\u4ef6",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"Babel \u63d2\u4ef6\u5e38\u7528 API\u3001\u914d\u5408 TS \u5f00\u53d1\u3001\u5982\u4f55\u6d4b\u8bd5\u63d2\u4ef6\u7b49\u7b49",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7143921535445631012"},"Babel \u63d2\u4ef6\uff1a30\u5206\u949f\u4ece\u5165\u95e8\u5230\u5b9e\u6218")))),(0,n.kt)("li",{parentName:"ul"},"\u8fd9\u7bc7\u505a\u7684 demo \u662f\u4e00\u4e2a\u7b80\u5355\u7684 babel-plugin-import",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903746804137991"},"\u6df1\u5165Babel\uff0c\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86")))),(0,n.kt)("li",{parentName:"ul"},"\u8fd9\u7bc7\u505a\u7684 demo \u7c7b\u4f3c Java \u4e2d\u7684 lambok",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7012424646247055390"},"\u4fdd\u59c6\u7ea7\u6559\u5b66\uff01\u8fd9\u6b21\u4e00\u5b9a\u5b66\u4f1ababel\u63d2\u4ef6\u5f00\u53d1\uff01")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md"},"babel-handbook - \u5404\u79cd ast \u64cd\u4f5c\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R6Xr8SoJicZB8-P4H2SSPA"},"\u4f60\u8fd8\u5728\u624b\u52a8\u90e8\u7f72\u57cb\u70b9\u5417\uff1f\u4ece0\u52301\u5f00\u53d1Babel\u57cb\u70b9\u81ea\u52a8\u690d\u5165\u63d2\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7061808830274863118"},"\u64cd\u4f5c JavaScript \u7684 AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6953963506693570573"},"\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026671646555504676"},"\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136")))),(0,n.kt)("li",{parentName:"ul"},"diff \u7b97\u6cd5\u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/snabbdom/snabbdom"},"https://github.com/snabbdom/snabbdom")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/snabbdom/snabbdom/blob/master/src/init.ts"},"https://github.com/snabbdom/snabbdom/blob/master/src/init.ts")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8M-pJdKjF6bx5ijtSFKIcw"},"\u56fe\u89e3Diff\u7b97\u6cd5\u2014\u2014Vue\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7067693810918096903"},"\u6d45\u6790 Snabbdom \u4e2d vnode \u548c diff \u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7161063643105198093"},"\u4e00\u6587\u5403\u900f React \u548c Vue \u7684\u591a\u8282\u70b9 diff \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997965021401579556"},"diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7000266544181674014"},"DIff\u7b97\u6cd5\u770b\u4e0d\u61c2\u5c31\u4e00\u8d77\u6765\u780d\u6211(\u5e26\u56fe)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966215704634720287"},"\u5173\u4e8eVirtual DOM\u7406\u89e3\u548cSnabbdom\u6e90\u7801\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/shfshanyue/mini-code/blob/master/code/vdom/index.js"},"shanyue mini-code vdom")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6976232466059100197"},"Virtual DOM\u5230\u5e95\u6709\u4ec0\u4e48\u8ff7\u4eba\u4e4b\u5904\uff1f\u5982\u4f55\u642d\u5efa\u4e00\u6b3e\u8ff7\u4f60\u7248Virtual DOM\u5e93\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6919376064833667080"},"React\u3001Vue2\u3001Vue3\u7684\u4e09\u79cdDiff\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/31809713/answer/53544875"},"\u7f51\u4e0a\u90fd\u8bf4\u64cd\u4f5c\u771f\u5b9e DOM \u6162\uff0c\u4f46\u6d4b\u8bd5\u7ed3\u679c\u5374\u6bd4 React \u66f4\u5feb\uff0c\u4e3a\u4ec0\u4e48\uff1f- \u77e5\u4e4e")))),(0,n.kt)("li",{parentName:"ul"},"webpack \u70ed\u6a21\u5757\u66ff\u6362\u770b\u4e0b\u6e90\u7801",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7049608872553611301"},"webpack\u6a21\u5757\u70ed\u66f4\u65b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021729340945596424"},"Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031546400034947108"},"Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790")))),(0,n.kt)("li",{parentName:"ul"},"Docker \u76f8\u5173\u603b\u7ed3\u4e00\u4e0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064906701941506061"},"GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5LLX__x-yamgR83e0NKAtA"},"\u5199\u7ed9\u524d\u7aef\u7684 Docker \u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0Il5o9CRgZI3LbuR0LjAtQ"},"\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069609959985512484"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083009375387779085"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7113712658850775048"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u5bb9\u5668\u7f16\u6392")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/f581rfvKWE3KGgWfZDJ2cA"},"\u4e91\u8ba1\u7b97\u65f6\u4ee3\uff0c\u4f60\u8fd8\u4e0d\u4f1a Docker \uff1f \u4e00\u4e07\u5b57\u603b\u7ed3\uff08\u5efa\u8bae\u6536\u85cf\uff09")))),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u6846\u67b6\u6e90\u7801",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/6945998773818490884"},"React \u8fdb\u9636\u5b9e\u8df5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117512204059934733"},"react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7122617883837857806"},"\u300cReact\u8fdb\u9636\u300dReact\u4e2d\u6ca1\u6709keepalive\uff1f\u6ca1\u4e8b\uff01\u624b\u628a\u624b\u6559\u4f60\u4ece\u96f6\u5230\u4e00\u8bbe\u8ba1\u5e76\u5b9e\u73b0\u4e00\u4e2a\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118937685653192735"},"\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069555976717729805"},"\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944863057000529933"},"\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085542534943883301"},"2022 \u5e74\u7684 React \u751f\u6001")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7010539227284766751"},"React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://overreacted.io/before-you-memo/"},"Before You memo()")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://7kms.github.io/react-illustration-series/main/fibertree-update/#bailout%E9%80%BB%E8%BE%91-bailout"},"\u56fe\u89e3 React - bailout\u903b\u8f91")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/434791954/answer/2453356416"},"React \u7684 Concurrent Mode \u662f\u5426\u6709\u8fc7\u5ea6\u8bbe\u8ba1\u7684\u6210\u5206")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Yr4y1J7oc"},"\u300c\u4e0a\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1j44y1g74m"},"\u300c\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://pomb.us/build-your-own-react/"},"Build your own React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903913410314247"},"Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121378029682556958"},"\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7154175507280429070"},"React \u6e32\u67d3\u7684\u672a\u6765")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/METf8Ng6Qnsu1uWGTzan8g"},"React \u4e2d\u5e38\u89c1\u7684 8 \u4e2a\u9519\u8bef\uff0c\u5982\u4f55\u907f\u514d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7104460511869141006"},"20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094424941541457933"},"React\u5b98\u65b9\u56e2\u961f\u51fa\u624b\uff0c\u8865\u9f50\u539f\u751fHook\u77ed\u677f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7075701341997236261"},"React Hooks \u7684\u539f\u7406\uff0c\u6709\u7684\u7b80\u5355\u6709\u7684\u4e0d\u7b80\u5355")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904193044512782"},"\u4ecereact hooks\u201c\u95ed\u5305\u9677\u9631\u201d\u5207\u5165\uff0c\u6d45\u8c08react hooks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7LXeQomcHK4zcuRqB32JDg"},"React+Ts\uff0c\u8fd9\u6837\u5b66\u8d77\u6765\u786e\u5b9e\u7b80\u5355\uff01\uff01\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/byD6xm3O6MzX8kksjBmqpA"},"React 18 \u8d85\u5168\u5347\u7ea7\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7077545184807878692"},"\u963f\u91cc\u4e09\u9762\uff1a\u7075\u9b42\u62f7\u95ee\u2014\u2014\u6709react fiber\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u9700\u8981vue fiber\u5462")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982004709145968677"},"[","\u5efa\u8bae\u6536\u85cf","]"," \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6978654109893132318"},"\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904197008130062"},"\u624b\u5199React\u7684Fiber\u67b6\u6784\uff0c\u6df1\u5165\u7406\u89e3\u5176\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6859528127010471949"},"React Fiber \u6e90\u7801\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6943896410987659277"},"\u8d70\u8fdbReact Fiber\u7684\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6911681589558640654"},"\u524d\u7aef\u5de5\u7a0b\u5e08\u7684\u81ea\u6211\u4fee\u517b\uff1aReact Fiber \u662f\u5982\u4f55\u5b9e\u73b0\u66f4\u65b0\u8fc7\u7a0b\u53ef\u63a7\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6984949525928476703"},"React Fiber\u5f88\u96be\uff1f\u516d\u4e2a\u95ee\u9898\u52a9\u4f60\u7406\u89e3 React Fiber")))),(0,n.kt)("li",{parentName:"ul"},"Vite \u6e90\u7801",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7050063811973218341"},"\u6df1\u5165\u6d45\u51fa Vite")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UD0-7rWtOAxMuDpOR77gug"},"\u8be6\u89e3 Vite \u4f9d\u8d56\u9884\u6784\u5efa\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bf11t1rH6NllKDA0IKR9Lw"},"\u6388\u4eba\u4e88\u6e14\uff0cVSCode \u5982\u4f55\u8c03\u8bd5 Vite \u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3dfbu7lZJLd6cJSp9XLcVQ"},"\u6572\u4e0b vite \u547d\u4ee4\u540e\uff0cserver \u505a\u4e86\u54ea\u4e9b\u4e8b")))),(0,n.kt)("li",{parentName:"ul"},"\u5305\u7ba1\u7406\u65b9\u6848\u3001PNPM"),(0,n.kt)("li",{parentName:"ul"},"Arch Linux",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://linuxhandbook.com/grep-command-examples/"},"10 Practical Grep Command Examples for Developers")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.freecodecamp.org/news/the-linux-commands-handbook/#the-linux-grep-command"},"The Linux Command Handbook \u2013 Learn Linux Commands for Beginners")))),(0,n.kt)("li",{parentName:"ul"},"\u5982\u4f55\u642d\u5efa\u4e2a\u4eba\u535a\u5ba2",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4f7f\u7528 Next.js\uff0c\u5f00\u7bb1\u5373\u7528\u6587\u4ef6\u7cfb\u7edf\u8def\u7531\u3001\u9759\u6001\u7ad9\u70b9\u751f\u6210\uff08SSG\uff09"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://nextjs.org/learn/basics/create-nextjs-app"},"https://nextjs.org/learn/basics/create-nextjs-app")))),(0,n.kt)("li",{parentName:"ul"},"\u5de5\u7a0b\u5316\u65b9\u6848\u603b\u7ed3\u4e0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/403970666"},"2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017710911443959839"},"2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023242274876162084"},"\ud83d\udd25\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts"},"Next.js webpack \u914d\u7f6e")))),(0,n.kt)("li",{parentName:"ul"},"\u9759\u6001\u9875\u9762\u90e8\u7f72\u65b9\u6848",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4e0a\u4f20\u963f\u91cc\u4e91 OSS\n",(0,n.kt)("a",{parentName:"li",href:"https://github.com/Menci/upload-to-oss"},"https://github.com/Menci/upload-to-oss")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6992172458748936222"},"\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u5f00\u53d1\u6a21\u5f0f - \u5199\u4e8e2021\u5e74")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6990538424545443854"},"\u4ece\u96f6\u642d\u5efaWebpack5-react\u811a\u624b\u67b6(\u9644\u6e90\u7801)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/JinJieTan/Peter-"},"\u624b\u5199\u5404\u79cd\u6e90\u7801"))),(0,n.kt)("h2",{id:"-\u63a8\u8350\u9605\u8bfb"},"\ud83d\udcd2 \u63a8\u8350\u9605\u8bfb"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/403970666"},"2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6996816316875161637#heading-15"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/webpack/webpack-dev-middleware"},"https://github.com/webpack/webpack-dev-middleware")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000011761306"},"webpack-dev-middleware \u63d2\u4ef6\u7684\u4f7f\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904099985489927"},"webpack-dev-middleware \u6e90\u7801\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6949040393165996040#heading-2"},"[","\u4e07\u5b57\u603b\u7ed3","]"," \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7020678344219820068"},"\u8ddf\u6751\u957f\u8001\u5e08\u505a\u3010Vue DevUI \u5f00\u6e90\u6307\u5357\u3011\u76f4\u64ad\u4e00\u4e2a\u6708\u7684\u611f\u53d7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021167384484380709"},"\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 008: webpack HMR \u5b9e\u73b0\u7684\u6838\u5fc3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7030207667457130527"},"\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6959115798841393160"},"\u624b\u6478\u624b\u6559\u4f60\u7528Vue3+Typescript+Rollup+Tailwinds\u6253\u9020\u63d2\u62d4\u5f0f\u7684\u4e1a\u52a1\u7ec4\u4ef6\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6869551115420041229"},"\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029525775321661470"},"\u624b\u6478\u624b\u5b66\u4f1a\u642d\u5efa\u4e00\u4e2a TS+Rollup \u7684\u521d\u59cb\u5f00\u53d1\u73af\u5883")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029292539479867429"},"\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1a\u5982\u4f55\u5b9e\u73b0\u7ec4\u4ef6\u7684\u6309\u9700\u6253\u5305\ud83d\udce6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029262501833359368"},"\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6974377246140301342"},"coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6892886272377880583"},"\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7028222480326066213"},"\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904093434019853"},"\u5982\u4f55\u63a8\u52a8\u524d\u7aef\u56e2\u961f\u7684\u57fa\u7840\u8bbe\u65bd\u5efa\u8bbe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966491047257964575"},"Element UI\u6e90\u7801\u4e2d\u5b66\u5230\u7684\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026658230365323301"},"\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6859538537830858759"},"\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026671646555504676"},"\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6920044884594425864"},"\u4ece\u96f6\u64b8\u4e00\u4e2aCLI\u547d\u4ee4\u884c\u811a\u624b\u67b6\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904197863964685"},"\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6943430853972852750"},"\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6946008649026240519"},"\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026274816734789663"},"git hooks \u7684\u5e93 husky \u6e90\u7801\u8fd9\u4e48\u7b80\u5355\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4e00\u4e2a\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026210002042011655"},"\u300cReact18\u65b0\u7279\u6027\u300d\u6df1\u5ea6\u89e3\u8bfb\u4e4buseMutableSource")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6953452438300917790"},"\u3010V8\u6e90\u7801\u8865\u5145\u7bc7\u3011\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966422095274180639"},"[","\u63a2\u7d22","]","Webpack DevServer\u548cHMR\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023242274876162084"},"\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903881390964744"},"\u4ece\u5934\u5f00\u59cb\uff0c\u5f7b\u5e95\u7406\u89e3\u670d\u52a1\u7aef\u6e32\u67d3\u539f\u7406(8\u5343\u5b57\u6c47\u603b\u957f\u6587)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982157120594509837"},"\u5256\u6790 Webpack SplitChunksPlugin \u6e90\u7801: \u5b66\u5b8c\u4f60\u4e5f\u80fd\u5199\u4e00\u4e2a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7025164660751990798"},"\u4e00\u70b9\u5173\u4e8e\u670d\u52a1\u7aef\u6e32\u67d3\u7684\u5206\u4eab")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966119324478079007"},"\u4ece 0 \u6784\u5efa\u81ea\u5df1\u7684\u811a\u624b\u67b6/CLI\u77e5\u8bc6\u4f53\u7cfb\uff08\u4e07\u5b57\uff09 \ud83d\udee0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6984939221681176607"},"\u624b\u5199\u4e00\u4e2a\u865a\u62dfDOM\u5e93\uff0c\u5f7b\u5e95\u8ba9\u4f60\u7406\u89e3diff\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6854573215969181703"},"10\u4e2a\u7b80\u5355\u7684\u6280\u5de7\u8ba9\u4f60\u7684 vue.js \u4ee3\u7801\u66f4\u4f18\u96c5\ud83c\udf4a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026119446162997261"},"\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/384048633/answer/1134746899"},"\u505a\u4e86\u4e24\u5e74\u524d\u7aef\u5f00\u53d1\uff0c\u5e73\u65f6\u5c31\u662f\u62ff Vue \u5199\u5199\u9875\u9762\u548c\u7ec4\u4ef6\uff0c\u7b80\u5386\u7684\u9879\u76ee\u7ecf\u5386\u5e94\u8be5\u600e\u4e48\u5199\u5f97\u597d\u770b\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017710911443959839"},"2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7016534471734198279"},"\u5206\u4eab\u4e00\u5e74\u4ee5\u6765\u7684Electron\u5f00\u53d1\u7ecf\u9a8c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903938894872589"},"\u300c\u524d\u7aef\u8fdb\u9636\u300d\u9ad8\u6027\u80fd\u6e32\u67d3\u5341\u4e07\u6761\u6570\u636e(\u65f6\u95f4\u5206\u7247)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6978654109893132318"},"\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6973155726302642206"},"\u624b\u5199\u7cfb\u5217-\u8fd9\u4e00\u6b21\uff0c\u5f7b\u5e95\u641e\u61c2 Promise")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7005375860509245471"},"50\u884c\u4ee3\u7801\u4e32\u884cPromise\uff0ckoa\u6d0b\u8471\u6a21\u578b\u539f\u6765\u662f\u8fd9\u4e48\u5b9e\u73b0\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6882290865763680264"},"\u73a9\u8f6c node \u5b50\u8fdb\u7a0b \u2014 child_process")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903895467032589"},"\u6df1\u5165\u5256\u6790\uff1aVue\u6838\u5fc3\u4e4b\u865a\u62dfDOM")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904055618158600"},"\u4ece\u96f6\u5f00\u59cb\u914d\u7f6e react + typescript\uff08\u4e00\uff09\uff1adotfiles")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6937125495439900685"},"Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7025213391618703367"},"TypeScript \u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6965320374451961886"},"\u7528ts\u7c7b\u578b\u7cfb\u7edf\u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7059400669916037133"},"\u521d\u6b65\u5c1d\u8bd5 tauri\uff0c\u5e76\u4e14\u4e0e electron.js \u5bf9\u6bd4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7057178581897740319"},"\u548c\u5927\u591a\u6570\u7684\u524d\u7aef\u5f00\u53d1\u8005\u76f8\u6bd4\uff0c\u6211\u5e76\u6ca1\u6709\u9009\u62e9node.js\u505acli\u800c\u6295\u9760\u4e86golang")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/acdlite/react-fiber-architecture"},"React Fiber Architecture")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.cnblogs.com/ginvip/p/6367939.html"},"linux\u547d\u4ee4\u603b\u7ed3\u4e4blsof\u547d\u4ee4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.smashingmagazine.com/2019/09/machine-learning-front-end-developers-tensorflowjs/"},"Machine Learning For Front-End Developers With Tensorflow.js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw"},"javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/476712416"},"\u6211\u7684\u7b2c\u4e00\u6b21webpack\u4f18\u5316\uff0c\u9996\u5c4f\u6e32\u67d3\u4ece9s\u52301s")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071518211392405541"},"\u5728\u9879\u76ee\u4e2d\u7528ts\u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u6574\u4e2a\u56e2\u961f\u53d7\u76ca\ud83d\ude01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ"},"\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ"},"\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A"},"\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aMYJODhtWsBt9CTJxySQEQ"},"\u817e\u8baf\u4e91\u540e\u7aef15\u8fde\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0kUf1ujPUuieyOSMsBIzaw"},"\u5b57\u8282\u56fd\u9645\u652f\u4ed8\u5341\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7080032725477883917"},"\u5982\u4f55\u6210\u4e3a\u4e00\u4e2a\u4f18\u79c0\u7684\u590d\u5236\u7c98\u8d34\u5de5\u7a0b\u5e08")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/zhydream77/article/details/81909706"},"docker\u6587\u4ef6\u5939\u6620\u5c04\u7684\u4e24\u79cd\u65b9\u5f0f---\u4e3b\u673a\u5377\u6620\u5c04\u548c\u5171\u4eab\u6587\u4ef6\u5939\u6620\u5c04")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://studygolang.com/articles/25997?fr=sidebar"},"\u4e3a\u4ec0\u4e48golang\u6ca1\u6709min/max\u4ee5\u53ca\u4e09\u5143\u64cd\u4f5c\u7b26")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7084882650233569317"},"\u7f16\u8bd1 ts \u4ee3\u7801\u7528 tsc \u8fd8\u662f babel")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031122959637217310"},"\u5982\u679c\u6ca1\u6709 package-lock.json\uff0c\u90a3\u5c06\u5982\u4f55")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7030084290989948935"},"\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 023\uff1anode_modules \u7248\u672c\u91cd\u590d\u7684\u56f0\u5883")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083468345579667493"},"\u3010\u6df7\u6dc6\u7cfb\u5217\u3011\u4e09\u95ee\uff1anpx\u3001npm\u3001cnpm\u3001pnpm\u533a\u522b\u4f60\u641e\u6e05\u695a\u4e86\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7082738107237433375"},"Webpack\u7ec4\u4ef6\u5e93\u6253\u5305\u8d85\u8be6\u7ec6\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XWZsKQECcsHAlE9cyqi9Eg"},"\u5199\u597d JavaScript \u5f02\u6b65\u4ee3\u7801\u7684\u51e0\u4e2a\u63a8\u8350\u505a\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WisEGFz2yn_ZeekViofMnA"},"Node.js \u8fdb\u9636 - \u591a\u6587\u4ef6 Stream \u5408\u5e76\uff0c\u4e32\u884c\u548c\u5e76\u53d1\u4e24\u79cd\u6a21\u5f0f\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046898330000949285"},"\u670d\u52a1\u7aef\u6e32\u67d3SSR\u53ca\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lyff2svfHh4rdsWRL4H5uA"},"\u624b\u6478\u624b\u670d\u52a1\u7aef\u6e32\u67d3-react")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7058868160706904078"},"\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kGMsNmIXlT25NfRrifjnTQ"},"\u9009\u62e9\u7b2c\u4e09\u65b9 NPM \u5305\u65f6\u7684 5 \u6761\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071066976830881823"},"\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/t3dYc3Md1dpiv1vaFa5plA"},"React 18 \u5168\u89c8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fgT7Kxs_0feRx4TkBe6G5Q"},"React 18 \u5bf9 Hooks \u7684\u5f71\u54cd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GatHpP3BRLV_I48MfpzR4A"},"React \u7684\u5fc3\u667a\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qyr6MnPtvnELDSbPJ2VtIw"},"\u4f60\u4e0d\u77e5\u9053\u7684 React v18 \u7684\u4efb\u52a1\u8c03\u5ea6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000041683300"},"\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0a)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000041683421"},"\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0b)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/502951532"},"Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/415361629"},"\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tWbeOTx0JpiZOD0YaC1P2A"},"\u524d\u7aef\u7b97\u6cd5\u7cfb\u7edf\u7ec3\u4e60: \u6808\u548c\u961f\u5217\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MYLi4mSgoi5KXj4-_OgT3A"},"\u3010\u7b2c2602\u671f\u3011\u8bbe\u7f6e NPM Registry \u7684 4 \u79cd\u59ff\u52bf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903919995322382"},"\u300c\u624b\u6478\u624b\u8bbe\u8ba1\u6a21\u5f0f\u7cfb\u5217\u300d \u4eab\u5143\u6a21\u5f0f\u4e0e\u8d44\u6e90\u6c60")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6889247428797530126"},"\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904165500518414"},"React Hooks \u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3xhNcfI4pTm0n-naSsOBwg"},"\u624b\u5199 CSS-modules \u6765\u6df1\u5165\u7406\u89e3\u5b83\u7684\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1j44y1g74m"},"\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-B5M7pjIWZzFNvq-hyr1Mw"},"Umi 4 \u7279\u6027\u5408\u96c6\uff0c\u6bd4 Vite \u8fd8\u8981\u5feb\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094296981001994277"},"\u4f60\u53ef\u80fd\u5e76\u6ca1\u6709\u7406\u89e3\u7684 babel \u914d\u7f6e\u7684\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7052307032971411463"},"\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069609959985512484"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083009375387779085"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww"},"\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7095354780079357966"},"NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g"},"Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FPupefVg4zphOfIERZOvHQ"},"\u5982\u4f55\u8bbe\u8ba1\u66f4\u4f18\u96c5\u7684 React \u7ec4\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/01sTK6w4BFUzoRc2NKCs1w"},"React \u5e76\u53d1\u6e32\u67d3\u7684\u524d\u4e16\u4eca\u751f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.freecodecamp.org/news/how-to-build-your-own-blog-with-next-js-and-mdx/"},"\u4f7f\u7528 Next.js \u548c MDX \u6784\u5efa\u4f60\u81ea\u5df1\u7684\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw"},"TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g"},"TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g"},"\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7099402445989609479"},"\u524d\u7aef\u5fc5\u5b66\u7684\u52a8\u753b\u5b9e\u73b0\u601d\u8def\uff0c\u9ad8\u903c\u683c\u7684\u6548\u679c\u8001\u677f\u770b\u4e86\u90fd\u4f1a\u5927\u58f0\u79f0\u8d5e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LSlgpazCwtceQWjHsMPCAg"},"\u3010\u7b2c2617\u671f\u3011React \u7ec4\u4ef6\u5e93 CSS \u6837\u5f0f\u65b9\u6848\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X4ni2i9bvolHGfCdf3SzIA"},"\u3010\u7b2c2616\u671f\u3011\u89e3\u91caJavaScript\u7684\u5185\u5b58\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OrekHmMrn8UlisTrvt3MNA"},"\u4ece Turborepo \u770b Monorepo \u5de5\u5177\u7684\u4efb\u52a1\u7f16\u6392\u80fd\u529b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GryL1QVARtMB8-WIzd7xQQ"},"\u89e3\u51b3\u524d\u7aef\u5e38\u89c1\u95ee\u9898\uff1a\u7ade\u6001\u6761\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3v54arsDRRw6agyr3MtPRg"},"Google \u6700\u65b0\u7684\u6027\u80fd\u4f18\u5316\u65b9\u6848\uff0cLCP \u63d0\u534730%\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-6bQKIjH6WPcfuiCFtsjng"},"React useEvent\uff1a\u7816\u5bb6\u8bf4\u7684\u6ca1\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7102328973820067877"},"\u88abdiss\u6027\u80fd\u5dee\uff0cDan\u8fde\u591c\u4f18\u5316React\u65b0\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7102233142567632933"},"Node.js \u8c03\u8bd5\u4e00\u8def\u8d70\u6765\u7ecf\u5386\u4e86\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/g1fr1fnGspi7SETyP9B6rA"},"\u63a8\u8350\u4e00\u4e2a\u524d\u7aef\u6280\u672f\u9009\u578b\u795e\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2OXIGB5qQFc2isIxhm33bg"},"\u6700\u9ad8\u6027\u80fd\u7684\u5305\u7ba1\u7406\u5668-pnpm")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3yy9V5HMDWPFwEf1cyL-lw"},"\u5e76\u53d1\u6e32\u67d3\u4f18\u5316\uff1a\u8ba9\u6587\u4ef6\u6811\u7684\u6e32\u67d3\u53c8\u5feb\u53c8\u7a33")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7092766235380678687"},"\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg"},"\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KwmNzTdjMB-ljQ0ysEGalg"},"\u6df1\u5165\u7406\u89e3 Linux CPU \u4e0a\u4e0b\u6587\u5207\u6362")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg"},"\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ashok-khanna/react-snippets/blob/main/Router.js"},"100 \u884c\u4ee3\u7801\u5b9e\u73b0 React \u8def\u7531")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7100736564979826695"},"\u7cbe\u8bfb\u300areact-snippets - Router \u6e90\u7801\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QWwb8PXtdJJUKyicHRmBkw"},"\u5e72\u8d27 | \u643a\u7a0b\u673a\u7968\u524d\u7aefSvelte\u751f\u4ea7\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069772395610898462"},"\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101457212085633054"},"\u6a21\u5757\u8054\u90a6\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g"},"\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ULY-_Vq-Jgb8aCbhyfqYHw"},"\u3010\u96f6\u57fa\u7840\u3011\u5145\u5206\u7406\u89e3WebGL\uff08\u4e09\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ROwTG6AC2pK5UN1dzY5x8w"},"Web3.0\u5f00\u53d1\u5165\u95e8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg"},"\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l19wbHNIrhjyD0HwJwuvmQ"},"\u5256\u6790React\u6838\u5fc3\u8bbe\u8ba1\u539f\u7406\u2014Virtual Dom")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/b15cyyg53lVKQ_TtR8hugQ"},"\u3010\u7b2c2630\u671f\u3011javascript\u4e2d\u7684\u4f9d\u8d56\u6ce8\u5165")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sEvP3nLUOBwbSHP9mmT__A"},"\u3010\u524d\u7aef\u90e8\u7f72\u9644\u5f55\u4e00\u3011\u5199\u7ed9\u524d\u7aef\u7684 docker \u4f7f\u7528\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/f8mYoozpLrnSfWcRHTMa7A"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6838\u5fc3service\u7c7b\u521d\u59cb\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/y-6Uf1hNBF19MabHEtqnJA"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u63d2\u4ef6\u5316\u67b6\u6784\u6838\u5fc3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4cZ3rJz4P5bSRSeXDbFoMQ"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u8fd0\u884c\u65f6\u63d2\u4ef6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2MsgPh9AZtUoJpsLLdOynQ"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6784\u5efa\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Sz8u6lzkL1nnpRxGrdbYJg"},"\u5982\u4f55\u534e\u4e3d\u7684\u5b9e\u73b0\u4e00\u5957\u811a\u624b\u67b6 - \u4ee5umicli\u548c\u8f6c\u8f6czzcli\u4e3a\u4f8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/antfe/featured/uf1bok"},"Umi 4 \u7279\u6027 05\uff1a\u7a33\u5b9a\u767d\u76d2\u6027\u80fd\u597d\u7684 ESLint")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZTI-8RI0l314Ki9oBxqRWw"},"\u6df1\u5165\u6d45\u51fa npm & yarn & pnpm \u5305\u7ba1\u7406\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg"},"\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=VozPNrt-LfE"},"\u4e00\u4e2a\u4e09\u5c0f\u65f6\u7684 React Native \u901f\u6210\u8bfe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7098211898990002207"},"\u524d\u7aef\u914d\u7f6e\u5316\u771f\u9999\uff5e\u4e0a\u73ed\u53c8\u591a\u4e8660%\u7684\u6478\ud83d\udc1f\u65f6\u95f4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7104460511869141006"},"20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7116296421816418311"},"Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u5982\u4f55\u5c06 template \u7f16\u8bd1\u6210 AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117085295798911012"},"Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6a21\u578b\u6811\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121504219588198413"},"Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6700\u540e\u4e00\u66f2\uff0crender code \u751f\u6210")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124890499478978597"},"\u521d\u63a2 Vue3 \u7f16\u8bd1\u4e4b\u7f8e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126712173014810661"},"Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u62bd\u8c61\u8bed\u6cd5\u6811\u7684\u751f\u6210")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7127074001897127943"},"Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u7a7a\u767d\u5b57\u7b26\u7684\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q"},"\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://turborepo.org/docs/handbook/what-is-a-monorepo"},"Monorepo Handbook \u65b0\u9c9c\u51fa\u7089")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7152045316294836260"},"Vue3\u7ec4\u4ef6\u5e93\u6253\u5305\u6307\u5357\uff0c\u4e00\u6b21\u751f\u6210esm\u3001esm-bundle\u3001commonjs\u3001umd\u56db\u79cd\u683c\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904039608500237"},"Koa\u7684\u6d0b\u8471\u4e2d\u95f4\u4ef6\uff0cRedux\u7684\u4e2d\u95f4\u4ef6\uff0cAxios\u7684\u62e6\u622a\u5668\u8ba9\u4f60\u8ff7\u60d1\u5417\uff1f\u5b9e\u73b0\u4e00\u4e2a\u7cbe\u7b80\u7248\u7684\u5c31\u5f7b\u5e95\u641e\u61c2\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/khS0wkBzQe4Lxn7jHK_0vA"},"\u5b66\u4e60 Babel \u63d2\u4ef6\uff0c\u628a Vue2 \u8bed\u6cd5\u81ea\u52a8\u8f6c\u6210 Vue3\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QgOslh1TwpU2cJubnNxYNw"},"\u5982\u4f55\u7f16\u5199\u795e\u5947\u7684\u300c\u63d2\u4ef6\u673a\u5236\u300d\uff0c\u4f18\u5316\u57fa\u4e8e Antd Table \u5c01\u88c5\u8868\u683c\u7684\u6df7\u4e71\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121378029682556958"},"\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7123969545387114509"},"\u803d\u8bef\u4f60\u5341\u5206\u949f\uff01\ud83c\udf83\u4f60\u53ef\u80fd\u7528\u5f97\u4e0a\u8fd9\u4e9bwebpack5\u65b0\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118782372220567566"},"\u5206\u5305\u738b\uff01\ud83e\udde8\u4f18\u5316\u9879\u76ee\u4f53\u79ef\u51cf\u5c1120%\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7148969678642102286"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u6a21\u578b\u5149\u6e90\u7ed3\u5408\u751f\u6210\u660e\u6697\u53d8\u5316\u7684\u521b\u610f\u9875\u9762-\u5149\u4e0e\u5f71\u4e4b\u8bd7 \ud83d\udca1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146383940931026958"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145064095178293285"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/the-cost-of-javascript"},"\u26a1\ufe0f The Cost Of JavaScript (2017 - 2023)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/fontend-target"},"\ud83d\uddc2 \u524d\u7aef\u7248\u672c\u517c\u5bb9\u95ee\u9898\u7684\u63a2\u7d22")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/web-dev-blog"},"\ud83d\uddc2 \u5bf9 web.dev \u6240\u6709 blog \u7684\u6574\u7406\u4e0e\u5f52\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/react-native-tweet"},"\ud83e\udd2f \u6ca1 2 \u5e74 React Native \u5f00\u53d1\u7ecf\u9a8c\uff0c\u4f60\u90fd\u9047\u4e0d\u5230\u8fd9\u4e9b\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146183222425518093"},"Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146973901166215176"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u57fa\u7840\u77e5\u8bc6\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146975493278367752"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u7b97\u6cd5\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146976516692410376"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u5de5\u7a0b\u5316\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146996646394462239"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u524d\u7aef\u6846\u67b6+\u6d4f\u89c8\u5668\u539f\u7406\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7158730050718662687"},"20\u4e2a\u5e38\u89c1\u7684\u524d\u7aef\u7b97\u6cd5\u9898\uff0c\u4f60\u5168\u90fd\u4f1a\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7151653067593613320"},"\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126394898445500423"},"\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157902763534319624"},"\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg"},"\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA"},"\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7172001951784108040"},"\u50bb\u74dc\u65b9\u5f0f\u5206\u6790\u524d\u7aef\u5e94\u7528\u7684\u4f53\u79ef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7050063811973218341/section/7070419010021490702"},"\u624b\u5199 Bundler: \u5b9e\u73b0\u4ee3\u7801\u6253\u5305\u3001 Tree Shaking")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7050063811973218341/section/7066614663533821983"},"\u624b\u5199 Bundler: \u5b9e\u73b0 JavaScript AST \u89e3\u6790\u5668\u2014\u2014\u8bcd\u6cd5\u5206\u6790\u3001\u8bed\u4e49\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1xY0hfcwJci1hr4TKUZMqg"},"\u3010\u7b2c2795\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u4e09\u7aef\u540c\u6784\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7WU1DDoMYQzXnlstz16QJA"},"\u3010\u7b2c2785\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u8de8\u7aef\u5bb9\u5668\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/19Ai1rbRoQxOBA5SXSNCAQ"},"Vite \u7279\u6027\u548c\u90e8\u5206\u6e90\u7801\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021115814870810660"},"Rollup\u6e90\u7801\uff1a\u6a21\u5757\u6253\u5305\u4e0eTree-Shaking")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7169004126469914654"},"Rollup \u4e0e Webpack \u7684 Tree-shaking")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157902763534319624"},"\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7160467329334607908"},"\u3010Webpack Plugin\u3011\u5199\u4e86\u4e2a\u63d2\u4ef6\u8ddf\u559c\u6b22\u7684\u5973\u751f\u8868\u767d\uff0c\u7ed3\u679c......\ud83d\ude2d\ud83d\ude2d\ud83d\ude2d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000012081469"},"\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0a\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000012099163"},"\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0b\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7164175171358556173"},"\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7170852747749621791"},"\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7176963906844246074"},"Webpack\u6df1\u5ea6\u8fdb\u9636\uff1a\u4e24\u5f20\u56fe\u5f7b\u5e95\u8bb2\u660e\u767d\u70ed\u66f4\u65b0\u539f\u7406\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_MJq-88MNFyvDTxUw_lFiA"},"Webpack4\u7684\u538b\u7f29\u9636\u6bb5\u7684\u6027\u80fd\u4f18\u5316\u548c\u8e29\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7093880734246502414"},"Vue3\u751f\u547d\u5468\u671fHooks\u7684\u539f\u7406\u53ca\u5176\u4e0e\u8c03\u5ea6\u5668(Scheduler)\u7684\u5173\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064740689178787871"},"\u3010\ud83d\udc2f\u521d/\u4e2d\u7ea7\u524d\u7aef\u9762\u7ecf\u3011\u4e2d\u5c0f\u578b\u516c\u53f8\u9762\u8bd5\u65f6\u90fd\u4f1a\u95ee\u4e9b\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7177216308843380797"},"\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0a\uff09\uff1a\u4e3a\u4ec0\u4e48\u662f Zustand")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7182462103297458236"},"\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0b\uff09\uff1a\u57fa\u4e8e Zustand \u7684\u6e10\u8fdb\u5f0f\u72b6\u6001\u7ba1\u7406\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg"},"\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pDXhIMFkyMuiVHB0l9gphw"},"\u5982\u4f55\u4f7f\u7528jenkins\u642d\u5efa\u4e00\u4e2a\u4e2d\u5c0f\u4f01\u4e1a\u524d\u7aef\u9879\u76ee\u90e8\u7f72\u73af\u5883")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7129298214959710244"},"\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6991640600533532679"},"\u8ddf\u7740\u6765\uff0c\u4f60\u4e5f\u53ef\u4ee5\u624b\u5199VueRouter")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997968693414084644"},"\u300c\u786c\u6838JS\u300d\u56fe\u89e3Promise\u8ff7\u60d1\u884c\u4e3a\uff5c\u8fd0\u884c\u673a\u5236\u8865\u5145")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007946894605287432"},"\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7012774158371127326"},"\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aLQVpglTRA0bJGyCpXOD8Q"},"\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684 async\u3001await \u7ec6\u8282")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7200039970575941693"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u7269\u7406\u6548\u679c-\u78b0\u649e\u548c\u58f0\u97f3 \ud83d\udca5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7191415427350659129"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u65b0\u6625\u7279\u5178-Rabbit craft go \ud83d\udc07")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7212235580104917053"},"\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300d\u81ea\u5df1\u52a8\u624b\u5b9e\u73b0\u4e00\u4e2aJSX\u8f6c\u6362")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7212603037667786813"},"\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dFiber\u67b6\u6784\u7684\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7213362704781852730"},"\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dReconciler\u67b6\u6784\u7684\u53cc\u7f13\u5b58\u6811\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QcQlOscF9R0aF2x3Oe6doQ"},"\u3010webpack\u6838\u5fc3\u5e93\u3011\u8017\u65f67\u4e2a\u5c0f\u65f6\uff0c\u7528\u8fd150\u5f20\u56fe\u6765\u5b66\u4e60enhance-resolve\u4e2d\u7684\u6570\u636e\u6d41\u52a8\u548c\u63d2\u4ef6\u8c03\u5ea6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7199832444836593725"},"\u804a\u804a Ant Design V5 \u7684\u4e3b\u9898\uff08\u4e0a\uff09\uff1aCSSinJS \u52a8\u6001\u4e3b\u9898\u7684\u82b1\u6d3b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sTBFnSLS-WBjMWDokH2o9A"},"\u5199\u7ed9\u5f00\u53d1\u540c\u5b66AI\u5f3a\u5316\u5b66\u4e60\u5165\u95e8\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d0zbdhTctR7L_62SaY_VJA"},"\u4e00\u8d77\u6765\u770b\u770b\u4e00\u4e2a\u4f53\u7cfb\u5b8c\u5584\u7684\u524d\u7aefReact\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u642d\u5efa\u51fa\u6765\u7684\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/z4GhUr5eA-4WbxVye4hmAQ"},"\u5e72\u8d27 | \u8017\u65f6\u7f29\u77ed2/3\uff0cTaro\u7f16\u8bd1\u6253\u5305\u4f18\u5316\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/g1XhCtfIL6yy-37Y_grtEw"},"\u5e72\u8d27 | 30+\u6761\u4e1a\u52a1\u7ebf\uff0c\u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u534f\u540c\u5f00\u53d1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PT4y8OMWTpIto50qnT8gmg"},"\u5e72\u8d27 | \u79d2\u5f00\u738770%+\uff0c\u643a\u7a0b\u91d1\u878dSSR\u5e94\u7528\u6027\u80fd\u76d1\u6d4b\u4e0e\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/293Lbr81oUWHeJ3TGfPRdw"},"\u5e72\u8d27 | \u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u8fdb\u884cSize\u6cbb\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iT05ZXPVYFuCQgZZF9Zu5w"},"\u5e72\u8d27 | \u643a\u7a0b\u5c0f\u7a0b\u5e8f\u751f\u6001\u4e4bTaro\u8de8\u7aef\u89e3\u51b3\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rpHb5ZhUTOTfbVPEZJFklg"},"\u5e72\u8d27 | \u7626\u8eab50%-70%\uff0c\u643a\u7a0b Taro \u5c0f\u7a0b\u5e8f\u6837\u5f0f Size \u7f29\u51cf\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HUJTU5Du6318LJ7RfQNN2g"},"\u5e72\u8d27 | \u643a\u7a0b\u5546\u65c5\u5927\u524d\u7aef React Streaming \u7684\u63a2\u7d22\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JiJhA6AfNiGXl7p0uQ8mGA"},"\u5e72\u8d27 | \u643a\u7a0b\u5ea6\u5047\u57fa\u4e8e RPC \u548c TypeScript \u7684 BFF \u8bbe\u8ba1\u4e0e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OHbzuqUl3tL1YlpLOgEkvA"},"INP \u5373\u5c06\u4ee3\u66ff FID \u6210\u4e3a\u65b0\u7684\u6838\u5fc3 Web \u6307\u6807")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2Dy5RsviZlo7SPA648Mj3g"},"\u3010\u7b2c2973\u671f\u3011\u643a\u7a0bWeb\u7ec4\u4ef6\u5728\u8de8\u7aef\u573a\u666f\u7684\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yPRPakU1UM5iVY-1bwiHJQ"},"\u8fd9\u4e9b\u5e74\u5728\u963f\u91cc\u5b66\u5230\u7684\u65b9\u6cd5\u8bba")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ganW_F5GhQV-8s9N2y7jaw"},"/[\u901a\u660e\u5883 \xb7 React\u67b6\u6784/]\u901a\u4fd7\u5730\u8bb2React\uff0c\u4f18\u96c5\u5730\u7406\u89e3React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/daHYuCfstHYqAtscn5T4WQ"},"React-Router 6.10+KeepAlive\u7684\u7ea6\u5b9a\u5f0f\u8def\u7531\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MWf07S5avWzK7vdzhpFsoA"},"\u5e72\u8d27\uff01\u6211\u662f\u5982\u4f55\u5728\u4e00\u7ebf\u5927\u5382\u5b9e\u8df5webpack\u4f18\u5316\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WV3oztPYZyGiv4hW0--Jkw"},"\u6d45\u8c08\u9886\u57df\u9a71\u52a8\u5728\u524d\u7aef\u7684\u5e94\u2f64")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Z-8lsdLeTqCeFZ4w2oNBjg"},"Chrome 117 \u53d1\u5e03\uff1a\u65b0 Web \u5f00\u53d1\u8c03\u8bd5\u6280\u5de7\u90fd\u5728\u8fd9\u4e86\uff01"))))}T.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[5439],{49613:(e,t,a)=>{a.d(t,{Zo:()=>k,kt:()=>u});var i=a(59496);function p(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function n(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,i)}return a}function l(e){for(var t=1;t=0||(p[a]=e[a]);return p}(e,t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(p[a]=e[a])}return p}var m=i.createContext({}),s=function(e){var t=i.useContext(m),a=t;return e&&(a="function"==typeof e?e(t):l(l({},t),e)),a},k=function(e){var t=s(e.components);return i.createElement(m.Provider,{value:t},e.children)},h="mdxType",o={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},N=i.forwardRef((function(e,t){var a=e.components,p=e.mdxType,n=e.originalType,m=e.parentName,k=r(e,["components","mdxType","originalType","parentName"]),h=s(a),N=p,u=h["".concat(m,".").concat(N)]||h[N]||o[N]||n;return a?i.createElement(u,l(l({ref:t},k),{},{components:a})):i.createElement(u,l({ref:t},k))}));function u(e,t){var a=arguments,p=t&&t.mdxType;if("string"==typeof e||p){var n=a.length,l=new Array(n);l[0]=N;var r={};for(var m in t)hasOwnProperty.call(t,m)&&(r[m]=t[m]);r.originalType=e,r[h]="string"==typeof e?e:p,l[1]=r;for(var s=2;s{a.r(t),a.d(t,{assets:()=>A,contentTitle:()=>y,default:()=>T,frontMatter:()=>v,metadata:()=>S,toc:()=>R});var i=a(64778),p=a(59496),n=a(49613),l=a(45924),r=a(28238),m=a(83442),s=a(37795),k=a(77619),h=a(74242);function o(e){return function(e){return p.Children.map(e,(e=>{if((0,p.isValidElement)(e)&&"value"in e.props)return e;throw new Error(`Docusaurus error: Bad child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the component should be , and every should have a unique "value" prop.`)}))}(e).map((e=>{let{props:{value:t,label:a,attributes:i,default:p}}=e;return{value:t,label:a,attributes:i,default:p}}))}function N(e){const{values:t,children:a}=e;return(0,p.useMemo)((()=>{const e=t??o(a);return function(e){const t=(0,k.l)(e,((e,t)=>e.value===t.value));if(t.length>0)throw new Error(`Docusaurus error: Duplicate values "${t.map((e=>e.value)).join(", ")}" found in . Every value needs to be unique.`)}(e),e}),[t,a])}function u(e){let{value:t,tabValues:a}=e;return a.some((e=>e.value===t))}function c(e){let{queryString:t=!1,groupId:a}=e;const i=(0,m.k6)(),n=function(e){let{queryString:t=!1,groupId:a}=e;if("string"==typeof t)return t;if(!1===t)return null;if(!0===t&&!a)throw new Error('Docusaurus error: The component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return a??null}({queryString:t,groupId:a});return[(0,s._X)(n),(0,p.useCallback)((e=>{if(!n)return;const t=new URLSearchParams(i.location.search);t.set(n,e),i.replace({...i.location,search:t.toString()})}),[n,i])]}function f(e){const{defaultValue:t,queryString:a=!1,groupId:i}=e,n=N(e),[l,r]=(0,p.useState)((()=>function(e){let{defaultValue:t,tabValues:a}=e;if(0===a.length)throw new Error("Docusaurus error: the component requires at least one children component");if(t){if(!u({value:t,tabValues:a}))throw new Error(`Docusaurus error: The has a defaultValue "${t}" but none of its children has the corresponding value. Available values are: ${a.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return t}const i=a.find((e=>e.default))??a[0];if(!i)throw new Error("Unexpected error: 0 tabValues");return i.value}({defaultValue:t,tabValues:n}))),[m,s]=c({queryString:a,groupId:i}),[k,o]=function(e){let{groupId:t}=e;const a=function(e){return e?`docusaurus.tab.${e}`:null}(t),[i,n]=(0,h.Nk)(a);return[i,(0,p.useCallback)((e=>{a&&n.set(e)}),[a,n])]}({groupId:i}),f=(()=>{const e=m??k;return u({value:e,tabValues:n})?e:null})();(0,p.useLayoutEffect)((()=>{f&&r(f)}),[f]);return{selectedValue:l,selectValue:(0,p.useCallback)((e=>{if(!u({value:e,tabValues:n}))throw new Error(`Can't select invalid tab value=${e}`);r(e),s(e),o(e)}),[s,o,n]),tabValues:n}}var q=a(72400);const w={tabList:"tabList_oPPN",tabItem:"tabItem_VDVc"};function j(e){let{className:t,block:a,selectedValue:n,selectValue:m,tabValues:s}=e;const k=[],{blockElementScrollPositionUntilNextRender:h}=(0,r.o5)(),o=e=>{const t=e.currentTarget,a=k.indexOf(t),i=s[a].value;i!==n&&(h(t),m(i))},N=e=>{let t=null;switch(e.key){case"Enter":o(e);break;case"ArrowRight":{const a=k.indexOf(e.currentTarget)+1;t=k[a]??k[0];break}case"ArrowLeft":{const a=k.indexOf(e.currentTarget)-1;t=k[a]??k[k.length-1];break}}t?.focus()};return p.createElement("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,l.Z)("tabs",{"tabs--block":a},t)},s.map((e=>{let{value:t,label:a,attributes:r}=e;return p.createElement("li",(0,i.Z)({role:"tab",tabIndex:n===t?0:-1,"aria-selected":n===t,key:t,ref:e=>k.push(e),onKeyDown:N,onClick:o},r,{className:(0,l.Z)("tabs__item",w.tabItem,r?.className,{"tabs__item--active":n===t})}),a??t)})))}function g(e){let{lazy:t,children:a,selectedValue:i}=e;if(a=Array.isArray(a)?a:[a],t){const e=a.find((e=>e.props.value===i));return e?(0,p.cloneElement)(e,{className:"margin-top--md"}):null}return p.createElement("div",{className:"margin-top--md"},a.map(((e,t)=>(0,p.cloneElement)(e,{key:t,hidden:e.props.value!==i}))))}function x(e){const t=f(e);return p.createElement("div",{className:(0,l.Z)("tabs-container",w.tabList)},p.createElement(j,(0,i.Z)({},e,t)),p.createElement(g,(0,i.Z)({},e,t)))}function d(e){const t=(0,q.Z)();return p.createElement(x,(0,i.Z)({key:String(t)},e))}const b={tabItem:"tabItem_xe4B"};function G(e){let{children:t,hidden:a,className:i}=e;return p.createElement("div",{role:"tabpanel",className:(0,l.Z)(b.tabItem,i),hidden:a},t)}const v={slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},y=void 0,S={permalink:"/frontend-weekly/2024/welcome",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-12-12-welcome/index.md",source:"@site/blogs/2024/2024-12-12-welcome/index.md",title:"\u7f6e\u9876\u5185\u5bb9",description:"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01",date:"2024-12-12T00:00:00.000Z",formattedDate:"December 12, 2024",tags:[{label:"TypeScript",permalink:"/frontend-weekly/2024/tags/type-script"},{label:"\u524d\u7aef\u6846\u67b6",permalink:"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6"},{label:"Webpack",permalink:"/frontend-weekly/2024/tags/webpack"},{label:"\u6e90\u7801\u7cfb\u5217",permalink:"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217"},{label:"\u4e1a\u52a1\u6210\u957f",permalink:"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f"},{label:"\u6027\u80fd\u4f18\u5316",permalink:"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316"},{label:"\u7ec4\u4ef6\u5e93\u5b9e\u6218",permalink:"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218"},{label:"\u7f51\u7edc\u76f8\u5173",permalink:"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173"},{label:"\u673a\u5668\u5b66\u4e60",permalink:"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60"},{label:"Java",permalink:"/frontend-weekly/2024/tags/java"},{label:"Golang",permalink:"/frontend-weekly/2024/tags/golang"}],readingTime:144.44,hasTruncateMarker:!0,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},nextItem:{title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"}},A={authorsImageUrls:[void 0]},R=[{value:"TypeScript \u5de5\u7a0b\u5316\u65b9\u6848",id:"typescript-\u5de5\u7a0b\u5316\u65b9\u6848",level:2},{value:"TS \u9ad8\u7ea7\u6280\u5de7",id:"ts-\u9ad8\u7ea7\u6280\u5de7",level:2},{value:"TS && \u6846\u67b6",id:"ts--\u6846\u67b6",level:2},{value:"\u524d\u7aef\u6846\u67b6",id:"\u524d\u7aef\u6846\u67b6",level:2},{value:"\u7f16\u7a0b\u8303\u5f0f",id:"\u7f16\u7a0b\u8303\u5f0f",level:2},{value:"\u6280\u672f\u65b9\u6848",id:"\u6280\u672f\u65b9\u6848",level:2},{value:"\u4e1a\u52a1\u6210\u957f && \u8f6f\u6280\u80fd",id:"\u4e1a\u52a1\u6210\u957f--\u8f6f\u6280\u80fd",level:2},{value:"Git \u76f8\u5173",id:"git-\u76f8\u5173",level:2},{value:"\u6e90\u7801\u7cfb\u5217",id:"\u6e90\u7801\u7cfb\u5217",level:2},{value:"Webpack \u7cfb\u5217",id:"webpack-\u7cfb\u5217",level:2},{value:"Vite \u7cfb\u5217",id:"vite-\u7cfb\u5217",level:2},{value:"PNPM && Monorepo",id:"pnpm--monorepo",level:2},{value:"Rollup \u7cfb\u5217",id:"rollup-\u7cfb\u5217",level:2},{value:"\u5fae\u524d\u7aef && \u6a21\u5757\u8054\u90a6",id:"\u5fae\u524d\u7aef--\u6a21\u5757\u8054\u90a6",level:2},{value:"VS Code \u63d2\u4ef6",id:"vs-code-\u63d2\u4ef6",level:2},{value:"\u524d\u7aef\u5de5\u7a0b\u5316",id:"\u524d\u7aef\u5de5\u7a0b\u5316",level:2},{value:"\u8f6f\u4ef6\u67b6\u6784 && \u8bbe\u8ba1\u6a21\u5f0f",id:"\u8f6f\u4ef6\u67b6\u6784--\u8bbe\u8ba1\u6a21\u5f0f",level:2},{value:"\u6301\u7eed\u96c6\u6210",id:"\u6301\u7eed\u96c6\u6210",level:2},{value:"\u670d\u52a1\u7aef\u76f8\u5173",id:"\u670d\u52a1\u7aef\u76f8\u5173",level:2},{value:"\u524d\u7aef\u6027\u80fd\u4f18\u5316",id:"\u524d\u7aef\u6027\u80fd\u4f18\u5316",level:2},{value:"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218",id:"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218",level:2},{value:"Node.js \u7cfb\u5217",id:"nodejs-\u7cfb\u5217",level:2},{value:"\u524d\u7aef\u7f16\u8bd1",id:"\u524d\u7aef\u7f16\u8bd1",level:2},{value:"\u7f51\u7edc\u76f8\u5173",id:"\u7f51\u7edc\u76f8\u5173",level:2},{value:"\u64cd\u4f5c\u7cfb\u7edf",id:"\u64cd\u4f5c\u7cfb\u7edf",level:2},{value:"\u673a\u5668\u5b66\u4e60",id:"\u673a\u5668\u5b66\u4e60",level:2},{value:"LLM \u6280\u672f\u8c03\u7814",id:"llm-\u6280\u672f\u8c03\u7814",level:2},{value:"Java \u76f8\u5173",id:"java-\u76f8\u5173",level:2},{value:"MySQL \u5b66\u4e60",id:"mysql-\u5b66\u4e60",level:2},{value:"Golang \u5b66\u4e60",id:"golang-\u5b66\u4e60",level:2},{value:"Rust \u5b66\u4e60",id:"rust-\u5b66\u4e60",level:2},{value:"\u7f51\u7ad9\u63a8\u8350",id:"\u7f51\u7ad9\u63a8\u8350",level:2},{value:"\u5b66\u4e60\u8d44\u6e90",id:"\u5b66\u4e60\u8d44\u6e90",level:2},{value:"\u9762\u8bd5\u76f8\u5173",id:"\u9762\u8bd5\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u6398\u91d1\u5927\u4f6c\u6c47\u603b",id:"-\u6398\u91d1\u5927\u4f6c\u6c47\u603b",level:2},{value:"\ud83d\udcd2 \u5f85\u5b66\u4e60\u5185\u5bb9",id:"-\u5f85\u5b66\u4e60\u5185\u5bb9",level:2},{value:"\ud83d\udcd2 \u5c0f\u76ee\u6807",id:"-\u5c0f\u76ee\u6807",level:2},{value:"\ud83d\udcd2 \u63a8\u8350\u9605\u8bfb",id:"-\u63a8\u8350\u9605\u8bfb",level:2}],M={toc:R},Q="wrapper";function T(e){let{components:t,...a}=e;return(0,n.kt)(Q,(0,i.Z)({},M,a,{components:t,mdxType:"MDXLayout"}),(0,n.kt)("p",null,"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01"),(0,n.kt)("h2",{id:"typescript-\u5de5\u7a0b\u5316\u65b9\u6848"},"TypeScript \u5de5\u7a0b\u5316\u65b9\u6848"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/403970666"},"2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7087811040591675428"},"\u90fd 2022 \u5e74\u4e86\uff0c\u624b\u52a8\u642d\u5efa React \u5f00\u53d1\u73af\u5883\u5f88\u96be\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7039583726375796749#heading-22"},"\u4f1a\u5199 TypeScript \u4f46\u4f60\u771f\u7684\u4f1a TS \u7f16\u8bd1\u914d\u7f6e\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904102355271694"},"\u3010\u5f00\u6e90\u3011\u4e00\u4e2a React + TS \u9879\u76ee\u6a21\u677f"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4e00\u79cd\u662f\u4f7f\u7528 ts-loader + babel-loader + fork-ts-checker-webpack-plugin \u901a\u8fc7 typescript \u8fdb\u884c\u7f16\u8bd1\u548c\u7c7b\u578b\u68c0\u67e5"),(0,n.kt)("li",{parentName:"ul"},"\u53e6\u4e00\u79cd\u662f babel-loader + @babel/preset-typescript \u4f7f\u7528 babel \u8fdb\u884c\u7f16\u8bd1\uff0ctypescript \u53ea\u8d1f\u8d23\u7c7b\u578b\u68c0\u67e5\uff08babel 7 \u4ee5\u4e0a\uff09"))),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6999807899149008910"},"2021\u5e74\u4ece\u96f6\u5f00\u53d1\u524d\u7aef\u9879\u76ee\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904052094926855"},"Webpack \u8f6c\u8bd1 Typescript \u73b0\u6709\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000015315545"},"\u4f7f\u7528ESLint+Prettier\u6765\u7edf\u4e00\u524d\u7aef\u4ee3\u7801\u98ce\u683c")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000009546913"},"\u7528 husky \u548c lint-staged \u6784\u5efa\u8d85\u6e9c\u7684\u4ee3\u7801\u68c0\u67e5\u5de5\u4f5c\u6d41"))),(0,n.kt)("h2",{id:"ts-\u9ad8\u7ea7\u6280\u5de7"},"TS \u9ad8\u7ea7\u6280\u5de7"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/usDh1-Wzxrf4BftfWhwduA"},"\u4f60\u9700\u8981\u77e5\u9053\u7684TypeScript\u9ad8\u7ea7\u7c7b\u578b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WsldmkW2ovp-okxSY3le9g"},"Typescript \u7c7b\u578b\u7f16\u7a0b\uff0c\u4ece\u5165\u95e8\u5230\u901a\u8fbe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7089809919251054628"},"\u5982\u4f55\u8fdb\u9636TypeScript\u529f\u5e95\uff1f\u4e00\u6587\u5e26\u4f60\u7406\u89e3TS\u4e2d\u5404\u79cd\u9ad8\u7ea7\u8bed\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6998785406619615269"},"TypeScript\u4ece\u5e73\u51e1\u5230\u4e0d\u51e1\uff08\u57fa\u7840\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7150668738990178312"},"\u63a8\u835012\u4e2a\u503c\u5f97\u5b66\u4e60\u7684TypeScript\u5b9d\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TUv8Cu6_ftQQ6lEWAwIa4w"},"TypeScript \u7c7b\u578b\u7cfb\u7edf\uff1a\u5206\u5e03\u5f0f\u6761\u4ef6\u7c7b\u578b\u5168\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7061556434692997156"},"\u63a5\u8fd1\u5929\u82b1\u677f\u7684TS\u7c7b\u578b\u4f53\u64cd\uff0c\u770b\u61c2\u4f60\u5c31\u80fd\u73a9\u8f6cTS\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-x8iVK-hlQd3-OZDC04A5A"},"TypeScript \u7c7b\u578b\u7f16\u7a0b: \u4ece\u57fa\u7840\u5230\u7f16\u8bd1\u5668\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7050099282317148174"},"\u77e5\u5176\u7136\uff0c\u77e5\u5176\u6240\u4ee5\u7136\uff1aTypeScript \u4e2d\u7684\u534f\u53d8\u4e0e\u9006\u53d8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007251289721536543"},"TypeScript\u662f\u5982\u4f55\u5de5\u4f5c\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6964692485415108645"},"TypeScript \u9ad8\u7ea7\u7528\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/owtE_7PVLyz5XqwGofaTZg"},"\u629b\u7816\u5f15\u7389\uff1aTypeScript \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6871752423577223176"},"\u7ec6\u6570\u8fd9\u4e9b\u5e74\u88ab\u56f0\u6270\u8fc7\u7684 TS \u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904055039344654"},"TS \u5e38\u89c1\u95ee\u9898\u6574\u7406\uff0860\u591a\u4e2a\uff0c\u6301\u7eed\u66f4\u65b0ing\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6994102811218673700"},"Ts\u9ad8\u624b\u7bc7\uff1a22\u4e2a\u793a\u4f8b\u6df1\u5165\u8bb2\u89e3Ts\u6700\u6666\u6da9\u96be\u61c2\u7684\u9ad8\u7ea7\u7c7b\u578b\u5de5\u5177"))),(0,n.kt)("h2",{id:"ts--\u6846\u67b6"},"TS && \u6846\u67b6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://react-typescript-cheatsheet.netlify.app/"},"\u4e00\u4efd\u5f88\u5168\u9762\u7684 React TypeScript \u5907\u5fd8\u5f55")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6952696734078369828"},"React + TypeScript\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071066976830881823"},"\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069555976717729805"},"\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7058868160706904078"},"\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6DAyXFHIMW95FS0f3GyHpA"},"TypeScript \u7ec8\u6781\u521d\u5b66\u8005\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021674818621669389"},"\u5982\u4f55\u4f18\u96c5\u5730\u5728 React \u4e2d\u4f7f\u7528TypeScript\uff0c\u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904122550845448"},"\u7cbe\u8bfb\u300a@types react \u503c\u5f97\u6ce8\u610f\u7684 TS \u6280\u5de7\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7068081327857205261"},"\u300c1.9W\u5b57\u603b\u7ed3\u300d\u4e00\u4efd\u901a\u4fd7\u6613\u61c2\u7684 TS \u6559\u7a0b\uff0c\u5165\u95e8 + \u5b9e\u6218\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903865255477261"},"Vue3.0 \u524d\u7684 TypeScript \u6700\u4f73\u5165\u95e8\u5b9e\u8df5"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u867d\u7136\u4e0d\u662f Vue3 \u4f46\u662f\u4e5f\u63a8\u8350\u770b\u4e0b")))),(0,n.kt)("h2",{id:"\u524d\u7aef\u6846\u67b6"},"\u524d\u7aef\u6846\u67b6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047705995534925832"},"\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e Vue \u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047690546417565733"},"\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e React \u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047153016771706916"},"\u76d8\u70b9\u6398\u91d1 2021 \u70b9\u8d5e\u9ad8\u8fbe 6000\uff0c\u6536\u85cf\u8fc7\u4e07\u7684\u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q"},"\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903913410314247"},"Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/66sos7nML5rA0ZZGJ5qFIQ"},"[","\u79d1\u666e\u6587","]"," Vue3 \u5230\u5e95\u66f4\u65b0\u4e86\u4ec0\u4e48\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6922641008106668045"},"\u63ed\u79d8 Vue.js \u4e5d\u4e2a\u6027\u80fd\u4f18\u5316\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7005880217684148231"},"\u6211\u5728\u9879\u76ee\u4e2d\u7528\u5b9e\u9645\u7528\u5230\u768422\u4e2aVue\u4f18\u5316\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904165500518414"},"React Hooks \u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046358484610187277"},"React Hooks \u4f7f\u7528\u8bef\u533a\uff0c\u9a73\u5b98\u65b9\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043772161596588046"},"\u5b9d\u554a\uff5e\u6765\u804a\u804a 9 \u79cd React Hook")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6933018383961194509"},"\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684\u6d41\u5f0f React Hooks\uff08\u5173\u4e8e\u7ec4\u7ec7\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7025524870842679310#heading-58"},"\u4ece 16 \u4e2a\u65b9\u5411\u9010\u6b65\u642d\u5efa\u57fa\u4e8e vue3 \u7684\u524d\u7aef\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6874007172578033677"},"34\u6761\u6211\u80fd\u544a\u8bc9\u4f60\u7684Vue\u4e4b\u5b9e\u64cd\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/461844358"},"React \u4f53\u7cfb\u4e0b\u5173\u4e8e Mobx \u4e0e Redux \u7684\u4e00\u4e9b\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aOapwk4_qi8tNM7vaa7jGA"},"\u4f7f\u7528 React&Mobx \u7684\u51e0\u4e2a\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6995834232350179336"},"\u5f53\u8bbe\u8ba1\u6a21\u5f0f\u9047\u4e0a Hooks")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903985338400782"},"React Hooks \u8be6\u89e3 \u3010\u8fd1 1W \u5b57\u3011+ \u9879\u76ee\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6989022564043456543"},"\u300cReact\u8fdb\u9636\u300d\u53ea\u7528\u4e24\u4e2a\u81ea\u5b9a\u4e49 Hooks \u5c31\u80fd\u66ff\u4ee3 React-Redux ?")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6950063294270930980"},"\u300cReact\u8fdb\u9636\u300d React\u5168\u90e8api\u89e3\u8bfb+\u57fa\u7840\u5b9e\u8df5\u5927\u5168(\u592f\u5b9e\u57fa\u78402\u4e07\u5b57\u603b\u7ed3)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6963053793613185031"},"\u300cReact\u8fdb\u9636\u300d\u63a2\u6848\u63ed\u79d8\u516d\u79cdReact\u2018\u7075\u5f02\u2019\u73b0\u8c61")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944863057000529933"},"\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406"))),(0,n.kt)("h2",{id:"\u7f16\u7a0b\u8303\u5f0f"},"\u7f16\u7a0b\u8303\u5f0f"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/shfshanyue/fp-jargon-zh"},"\u51fd\u6570\u5f0f\u7f16\u7a0b\u672f\u8bed")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7065093131233919006"},"\u51fd\u6570\u5f0f\u7f16\u7a0b\uff08FP\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6974377246140301342"},"coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6892886272377880583"},"\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903936378273799"},"\u7b80\u660e JavaScript \u51fd\u6570\u5f0f\u7f16\u7a0b\u2014\u2014\u5165\u95e8\u7bc7"))),(0,n.kt)("h2",{id:"\u6280\u672f\u65b9\u6848"},"\u6280\u672f\u65b9\u6848"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7144881028661723167"},"\u5982\u4f55\u53bb\u641e\u524d\u7aef\u57fa\u5efa")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7129298214959710244"},"\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085679511290773534"},"\u817e\u8baf\u4e8c\u9762\uff1a\u73b0\u5728\u8981\u4f60\u5b9e\u73b0\u4e00\u4e2a\u57cb\u70b9\u76d1\u63a7SDK\uff0c\u4f60\u4f1a\u600e\u4e48\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA"},"\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7087206796351242248"},"\u817e\u8baf\u4e09\u9762\uff1aCookie\u7684SameSite\u4e86\u89e3\u5427\uff0c\u90a3SameParty\u5462")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7081539471585312805"},"\u817e\u8baf\u4e00\u9762\uff1aCORS\u4e3a\u4ec0\u4e48\u80fd\u4fdd\u969c\u5b89\u5168\uff1f\u4e3a\u4ec0\u4e48\u53ea\u5bf9\u590d\u6742\u8bf7\u6c42\u505a\u9884\u68c0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3hXLSOQC-B5JGmkOaYjgqw"},"\u4e0d\u4f7f\u7528\u7b2c\u4e09\u65b9\u5e93\u600e\u4e48\u5b9e\u73b0\u3010\u524d\u7aef\u5f15\u5bfc\u9875\u3011\u529f\u80fd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124573626161954823"},"\u524d\u7aef\u67b6\u6784\u5e26\u4f60 \u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u7ec8\u8eab\u53d7\u76ca\u300c\u7f8e\u56e2\u540e\u7aef\u8fde\u8fde\u70b9\u8d5e\u300d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d5M_-8XqFGYnpif7GQNmLA"},"\u3010\u7b2c2759\u671f\u3011\u5f02\u6b65\u5206\u7247\u8ba1\u7b97\u5728\u817e\u8baf\u6587\u6863\u7684\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FZUTFvOutS5NvURjj9jOFA"},"\u5b57\u8282\u524d\u7aef\u76d1\u63a7 SDK \u4f53\u79ef\u4e0e\u6027\u80fd\u4f18\u5316\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8cguocg_1DtZkHLfAGLyXg"},"\u4f7f\u7528 Vite \u63d2\u4ef6\u81ea\u52a8\u5316\u5b9e\u73b0\u9aa8\u67b6\u5c4f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l7SA04BJovmJTUDIuobYiw"},"\u76d8\u70b912\u4e2ayyds\u7684\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5f00\u6e90\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1HyQLZcnZN6I27p_hbfUPg"},"\u3010\u7b2c2628\u671f\u3011\u57fa\u4e8e\u8bbe\u8ba1\u7a3f\u8bc6\u522b\u7684\u53ef\u89c6\u5316\u4f4e\u4ee3\u7801\u7cfb\u7edf\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ba-3fMQXNXqIzVTjVUrWtQ"},"\u6d45\u8c08\u6587\u6863\u7684\u5b9e\u65f6\u534f\u540c\u7f16\u8f91")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-WHafu5z-Ap4tjrbWesnmA"},"\u81ea\u52a8\u5316\u751f\u6210\u9aa8\u67b6\u5c4f\u7684\u6280\u672f\u65b9\u6848\u8bbe\u8ba1\u4e0e\u843d\u5730")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7148254347401363463"},"\u8c08\u8c08JS\u4e8c\u8fdb\u5236\uff1aFile\u3001Blob\u3001FileReader\u3001ArrayBuffer\u3001Base64")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904046436843527"},"\u5b57\u8282\u8df3\u52a8\u9762\u8bd5\u5b98\uff1a\u8bf7\u4f60\u5b9e\u73b0\u4e00\u4e2a\u5927\u6587\u4ef6\u4e0a\u4f20\u548c\u65ad\u70b9\u7eed\u4f20")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6990283221170651149"},"\u4ece\u96f6\u5f00\u59cb\u624b\u5199\u4e00\u4e2a\u300c\u5f00\u7bb1\u5373\u7528\u7684\u5927\u6587\u4ef6\u5206\u7247\u4e0a\u4f20\u5e93\u300d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6992007156320960542"},"5000\u5b57\u5e26\u4f60\u5168\u9762\u6df1\u5165\u7406\u89e3JS\u4e2d\u7684Stream API\uff5c8\u6708\u66f4\u6587\u6311\u6218"))),(0,n.kt)("h2",{id:"\u4e1a\u52a1\u6210\u957f--\u8f6f\u6280\u80fd"},"\u4e1a\u52a1\u6210\u957f && \u8f6f\u6280\u80fd"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u7ba1\u7406\u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/neSFlzQMh2P7ROwJxhVNkg"},"\u7ba1\u7406\u5c0f\u518c\u3001\u4e00\u7ebf\u540c\u5b66\u63a8\u8350\u3001\u4e00\u7ebfLeader\u63a8\u8350\u3001\u603b\u76d1\u7ea7\u63a8\u8350")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FDK0a4HeO60fKyr6ioRYcw"},"\u8c01\u80fd\u6210\u4e3aLeader\uff0c\u5927Leader\u8be5\u505a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dTXg9a4kXwVZi2N7mP71mg"},"\u5c11\u5e74\uff0c\u77e5\u9053\u4ec0\u4e48\u662f\u4fe1\u606f\u5dee\u521b\u9020\u4ef7\u503c\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/oodAZtxzHCZVGIGS9rBzIA"},"\u4ec0\u4e48\u662f\u5411\u4e0a\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/B3qgLTvSHzE33d6O-k7bAQ"},"\u4f60\u662f\u5982\u4f55\u505a\u6c47\u62a5\u7684")))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7073001183123603470"},"\u5e73\u65f6\u7684\u5de5\u4f5c\u5982\u4f55\u4f53\u73b0\u4e00\u4e2a\u4eba\u7684\u6280\u672f\u6df1\u5ea6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U6jAFVrgrKIm9--amZV5rA"},"\u5982\u4f55\u6210\u4e3a\u4f18\u79c0\u5de5\u7a0b\u5e08\u4e4b\u8f6f\u6280\u80fd\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MOWQ3rBFaITHSD2hvSelcw"},"\u5e72\u8d27\uff016\u4e2a\u65b9\u9762\uff0c32\u6761\u603b\u7ed3\u6559\u4f60\u63d0\u5347\u804c\u573a\u7ecf\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kozXWY95HXiQPGou1sfttg"},"\u804a\u804a\u5982\u4f55\u5b66\u4e60")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/K36xQbYgGVme8v_p9_dhkQ"},"\u4ee5\u524d\u7aef\u67b6\u6784\u5e08\u8eab\u4efd\uff0c\u4ece\u96f6\u5f00\u59cb\u641e\u4e8b\u641e\u4e8b\u641e\u4e8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7115634967945674765"},"Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7185376363808260152"},"\u4e00\u56fe\u80dc\u5343\u8a00\u7cfb\u5217\u2014\u2014\u6cf3\u9053\u56fe\u548c\u6570\u636e\u6d41\u56fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153432342919397383"},"\u600e\u4e48\u505a\u5230\u4e00\u56fe\u80dc\u5343\u8a00")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/URJC9ERPrcniiFinUsIJkg"},"\u3010\u56fe\u4e66\u3011\u7a0b\u5e8f\u5458\u7684\u5e95\u5c42\u601d\u7ef4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iTFj1Sn5vPTgkAT2Q9YC0w"},"\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u5b98\uff0c\u539f\u6765\u8fd9\u79cd\u5b66\u751f\u6700\u5403\u9999\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rJN14WFRTKjhoy8oWPulWw"},"\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\uff01YYDS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cbKpWKWrhyJwKQhlyYhQ_w"},"\u5982\u4f55\u5728\u9879\u76ee\u5f00\u53d1\u4e2d\u9010\u6b65\u6210\u957f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7114967732805697543"},"\u51b4\u7fbd\u7b54\u8bfb\u8005\u95ee\uff1a\u5982\u4f55\u5728\u5de5\u4f5c\u4e2d\u6253\u9020\u5f71\u54cd\u529b\uff0c\u5e26\u52a8\u540c\u4e8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1BdXL5dQfP6DnK7iJs6zGQ"},"\u5165\u804cApifox\u7814\u53d1\u7ec4\u534a\u5e74\uff0c\u6211\u6240\u63d0\u5347\u7684\u8f6f\u6280\u80fd\uff5c\u6587\u672b\u62bd\u4e66")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G8SVu9CWrKwbT5jfXaBmtw"},"\u6709\u54ea\u4e9b\u503c\u5f97\u8ba1\u7b97\u673a\u4e13\u4e1a\u5b66\u751f\u52a0\u5165\u7684\u56fd\u4f01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ"},"\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1QMPfODUcH1p4pGaoO1owA"},"\u5982\u4f55\u5199\u597d\u4e00\u4efd\u664b\u5347PPT\uff08\u9644PPT\u6a21\u677f\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hXFWU6uuil1aC1lEYO_KhQ"},"\u5982\u4f55\u753b\u51fa\u4e00\u5f20\u4f18\u79c0\u7684\u67b6\u6784\u56fe\uff08\u8001\u9e1f\u5fc5\u5907\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6965675185890394119"},"\u7cbe\u8bfb\u300a\u524d\u7aef\u804c\u4e1a\u89c4\u5212 - 2021 \u5e74\u300b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7034419410706104356"},"2022\u5e74\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u5927\u524d\u7aefLeader\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n4Pa0Bao1ISS68IOPWGI_Q"},"\u6280\u672f\u4eba\u7684\u4e03\u5927\u5fc5\u5907\u7279\u8d28")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6906468062943182862#heading-8"},"\u521d\u7ea7\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u6210\u957f\u548c\u5bfb\u6c42\u7a81\u7834")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NRqhJax8e6K8LMCNZSSozA"},"\u5e74\u5e95\u4e86\uff0c\u4f60\u662f\u5982\u4f55\u505a\u5de5\u4f5c\u6c47\u62a5\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904103504527374"},"\u5199\u7ed9\u521d\u4e2d\u7ea7\u524d\u7aef\u7684\u9ad8\u7ea7\u8fdb\u9636\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7041713124210114567"},"\u5728\u653f\u91c7\u4e91\u5982\u4f55\u5199\u524d\u7aef\u6280\u672f\u65b9\u6848\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017643726944108558"},"\u5982\u4f55\u7f16\u5199\u524d\u7aef\u8bbe\u8ba1\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6901845776880795662#heading-0"},"\u7406\u6e05\u601d\u8def\uff0c\u524d\u7aef\u6280\u672f\u8c03\u7814\u5230\u5e95\u5e94\u8be5\u600e\u4e48\u505a\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6869548364640288781"},"\u4ece\u5b9e\u4e60\u5230\u5165\u804c\uff1a\u4e0e\u4f60\u5206\u4eab\u6211\u5728\u653f\u91c7\u4e91\u7684\u5de5\u4f5c\u548c\u6210\u957f"))),(0,n.kt)("h2",{id:"git-\u76f8\u5173"},"Git \u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/250493093"},"\u8840\u6cea\u6559\u8bad\u4e4b\u8bf7\u4e0d\u8981\u518d\u8f7b\u89c6Git \u2014\u2014 \u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 Git \u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aTr6xf4BEuF-yxL340TnLg"},"GitHub \u641c\u7d22\u6280\u5de7\uff1a\u5982\u4f55\u66f4\u6709\u6548\u5730\u641c\u7d22 issue\u3001repo \u548c\u66f4\u591a\u4fe1\u606f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046720828901163016"},"\u5982\u679c\u4f60\u8fd8\u4e0d\u4f1a\u7528git\u56de\u6eda\u4ee3\u7801\uff0c\u90a3\u4f60\u4e00\u5b9a\u8981\u6765\u770b\u770b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071780876501123085"},"Git\u4e0d\u8981\u53ea\u4f1apull\u548cpush\uff0c\u8bd5\u8bd5\u8fd95\u6761\u63d0\u9ad8\u6548\u7387\u7684\u547d\u4ee4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046409685561245733"},"\u5229\u7528\u597d git bisect \u8fd9\u628a\u5229\u5668\uff0c\u5e2e\u52a9\u4f60\u5feb\u901f\u5b9a\u4f4d\u7591\u96be bug")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7024043015794589727"},"\u524d\u7aef\u67b6\u6784\u5e08\u7684 git \u529f\u529b\uff0c\u4f60\u6709\u51e0\u6210\u706b\u5019\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000040712052"},"\u4e24\u6761\u547d\u4ee4\u8ba9\u4f60\u7684git\u81ea\u52a8\u53d8\u57fa")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904191203213326"},"\u591a\u5e74 Git \u4f7f\u7528\u5fc3\u5f97 & \u5e38\u89c1\u95ee\u9898\u6574\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6974184935804534815"},"\u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 git \u7684")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7000186205224566791"},"\u4e3a\u4ec0\u4e48 husky \u653e\u5f03\u4e86\u4f20\u7edf\u7684 JS \u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904036068491278"},"\u4f60\u53ef\u80fd\u5df2\u7ecf\u5ffd\u7565\u7684git commit\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://gitmoji.dev/"},"gitmoji: An emoji guide for your commit messages"))),(0,n.kt)("h2",{id:"\u6e90\u7801\u7cfb\u5217"},"\u6e90\u7801\u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982004709145968677"},"[\u5efa\u8bae\u6536\u85cf] \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7048970987500470279"},"\u516d\u5343\u5b57\u8be6\u89e3\uff01vue3 \u54cd\u5e94\u5f0f\u662f\u5982\u4f55\u5b9e\u73b0\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7019185205336342542"},"Redux\u901a\u5173\u7b80\u6d01\u653b\u7565 -- \u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6978654109893132318"},"\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7010539227284766751"},"React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6990974525273800712"},"\u5e26\u4f60\u5feb\u901f\u624b\u5199\u4e00\u4e2a\u7b80\u6613\u7248vue\u4e86\u89e3vue\u54cd\u5e94\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7072321805792313357"},"Vue3.2 vDOM diff\u6d41\u7a0b\u5206\u6790\u4e4b\u4e00\uff1adiff\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6977363265965785102"},"2021\u5e74\uff0c\u8ba9\u6211\u4eec\u624b\u5199\u4e00\u4e2amini\u7248\u672c\u7684vue2.x\u548cvue3.x\u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6846687602679119885"},"Vue(v2.6.11)\u4e07\u884c\u6e90\u7801\u751f\u5543\uff0c\u5c31\u786c\u521a\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6992018709439053837"},"\u5c24\u96e8\u6eaa\u56fd\u5916\u6559\u7a0b\uff1a\u4eb2\u624b\u5e26\u4f60\u5199\u4e2a\u7b80\u6613\u7248\u7684Vue\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://codepen.io/collection/DkxpbE?cursor=ZD0wJm89MCZwPTEmdj00"},"Vue 3 Workshop Code Samples")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997965021401579556"},"diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997943192851054606"},"Vue 3.2 \u53d1\u5e03\u4e86\uff0c\u90a3\u5c24\u96e8\u6eaa\u662f\u600e\u4e48\u53d1\u5e03 Vue.js \u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6994976281053888519"},"\u521d\u5b66\u8005\u4e5f\u80fd\u770b\u61c2\u7684 Vue3 \u6e90\u7801\u4e2d\u90a3\u4e9b\u5b9e\u7528\u7684\u57fa\u7840\u5de5\u5177\u51fd\u6570"))),(0,n.kt)("h2",{id:"webpack-\u7cfb\u5217"},"Webpack \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6937125495439900685"},"Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u901a\u8fc7\u7f16\u5199\u4e00\u4e2a plugin\uff0c\u5728\u9884\u5904\u7406\u9636\u6bb5\u901a\u8fc7\u63d2\u4ef6 apply \u51fd\u6570\u52a8\u6001\u4fee\u6539 webpack \u914d\u7f6e\uff0c\u6ce8\u5165 vue-loader \u4e13\u7528\u7684 rules"))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047777251949019173"},"\u8d85\u786c\u6838\uff5c\u5e26\u4f60\u7545\u6e38\u5728 Webpack \u63d2\u4ef6\u5f00\u53d1\u8005\u7684\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7170852747749621791"},"\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7164175171358556173"},"\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g"},"Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/32831172"},"\u4f60\u7684Tree-Shaking\u5e76\u6ca1\u4ec0\u4e48\u5375\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903939289120782"},"\u624b\u6478\u624b Webpack \u591a\u5165\u53e3\u914d\u7f6e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031546400034947108"},"Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023242274876162084"},"\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021729340945596424"},"Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gwHwVxA4zh59SBvq-onM-g"},"Webpack5 \u5b9e\u8df5 - \u6784\u5efa\u6548\u7387\u500d\u901f\u63d0\u5347\uff01")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mpF6W-4dElu0UPed03oJQw"},"Webpack \u6027\u80fd\u7cfb\u5217\u4e00: \u4f7f\u7528 Cache \u63d0\u5347\u6784\u5efa\u6027\u80fd")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6910893471339708429"},"\u6211\u662f\u5982\u4f55\u5c06\u7f51\u9875\u6027\u80fd\u63d0\u53475\u500d\u7684 \u2014 \u6784\u5efa\u4f18\u5316\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6858905382861946894"},"Webpack\u914d\u7f6e\u5168\u89e3\u6790\uff08\u4f18\u5316\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7144934998884220958"},"\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0a\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145025071432597541"},"\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0b\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6996816316875161637"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6991774994552324133"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u5b9e\u8df5\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6991630925792542750"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u57fa\u7840\u7bc7\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903912588181511"},"\u624b\u628a\u624b\u5e26\u4f60\u5165\u95e8 Webpack4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6949040393165996040"},"[","\u4e07\u5b57\u603b\u7ed3","]"," \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406"))),(0,n.kt)("h2",{id:"vite-\u7cfb\u5217"},"Vite \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124112069355372581"},"\u5b66\u4f1a\u8fd9 20 \u4e2a\u5e93\uff0c\u8ba9\u4f60\u5feb\u901f\u770b\u61c2 vue3 \u548c vite3 \u6e90\u7801 \ud83d\ude80")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094984070999834655"},"\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6986533364438138894"},"\u524d\u7aef\u5386\u53f2\u9879\u76ee\u7684 Vite \u8fc1\u79fb\u5b9e\u8df5\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6979932627465666568"},"\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite 2.x \u6e90\u7801\u7ea7\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6956564266812571656"},"\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite \u26a1\ufe0f\u539f\u7406\u5206\u6790"))),(0,n.kt)("h2",{id:"pnpm--monorepo"},"PNPM && Monorepo"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/beLkwHan2C8BuSArs53cIA"},"\u8bfe\u4ee3\u8868\uff1aTurborepo \u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7015566240991150117"},"lerna + dumi + eslint\u591a\u5305\u7ba1\u7406\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/z-tKxgRPmdyR0zwc78Khgw"},"\u7ec4\u4ef6\u5e93Monmrepo\u67b6\u6784\u4e0e\u5f00\u53d1\u8c03\u8bd5\u73af\u5883\u6784\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7177585131861835837"},"React Native\u5de5\u7a0bMonorepo\u6539\u9020\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JWks8VyuXoB5zaeYdyJPxw"},"\u3010\u7b2c2714\u671f\u3011\u4eceMultirepo\u5230Monorepo \u888b\u9f20\u4e91\u6570\u6808\u524d\u7aef\u7814\u53d1\u6548\u7387\u63d0\u5347\u63a2\u7d22\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N0CZABDD0TKTmdljH3y74A"},"Monorepo\uff0c\u5927\u578b\u524d\u7aef\u9879\u76ee\u7ba1\u7406\u6a21\u5f0f\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094984070999834655"},"\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6peafvVjmcF65PFSggSLYQ"},"\u590d\u6d3b\u4e86\uff01 Lerna V6 \u5e26\u6765\u4e86\u54ea\u4e9b\u65b0\u4e1c\u897f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7098609682519949325"},"pnpm + workspace + changesets \u6784\u5efa\u4f60\u7684 monorepo \u5de5\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7161063570594070559"},"Element Plus \u7ec4\u4ef6\u5e93\u6838\u5fc3\u6280\u672f\u63ed\u79d8\uff1a5. \u4ece\u7ec8\u7aef\u547d\u4ee4\u89e3\u6790\u5668\u8bf4\u8d77\u8c08\u8c08 npm \u5305\u7ba1\u7406\u5de5\u5177\u7684\u8fd0\u884c\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157743898939359262"},"Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a4. ESLint \u6280\u672f\u539f\u7406\u4e0e\u5b9e\u6218\u53ca\u4ee3\u7801\u89c4\u8303\u81ea\u52a8\u5316\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146183222425518093"},"Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7129267782515949575"},"\ud83d\ude80Turborepo\uff1a\u53d1\u5e03\u5f53\u6708\u5c31\u6fc0\u589e 3.8k Star\uff0c\u8fd9\u6b3e\u8d85\u795e\u7684\u65b0\u5174 Monorepo \u65b9\u6848\uff0c\u4f60\u4e0d\u6253\u7b97\u5c1d\u8bd5\u4e0b\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7136925215388499998"},"\u6700\u8be6\u7ec6\u7684 lerna \u4e2d\u6587\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://turborepo.org/docs/handbook/what-is-a-monorepo"},"Monorepo Handbook \u65b0\u9c9c\u51fa\u7089")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/99nozy-vtFMGcBTxYvumWA"},"\u73b0\u4ee3 Monorepo \u5de5\u7a0b\u6280\u672f\u9009\u578b\uff0c\u804a\u804a\u6211\u7684\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7092766235380678687"},"\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/455809528"},"\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA"},"pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw"},"\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083414641610588168"},"\u524d\u7aef\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u8fdb\u5316\u53f2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7053340250210795557"},"\u90fd2022\u5e74\u4e86\uff0cpnpm\u5feb\u5230\u7897\u91cc\u6765\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6932046455733485575"},"\u5173\u4e8e\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u6df1\u5ea6\u601d\u8003\u2014\u2014\u4e3a\u4ec0\u4e48\u73b0\u5728\u6211\u66f4\u63a8\u8350 pnpm \u800c\u4e0d\u662f npm/yarn?")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7051929587852247077"},"\u5e74\u7ec8\u76d8\u70b9\uff1a2022\u57fa\u4e8eMonorepo\u7684\u9996\u4e2a\u5927\u8d8b\u52bf-TurboRepo")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7030207667457130527"},"\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043998041786810398"},"One For All\uff1a\u57fa\u4e8epnpm + lerna + typescript\u7684\u6700\u4f73\u9879\u76ee\u5b9e\u8df5 - \u7406\u8bba\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029262501833359368"},"\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6972139870231724045"},"Monorepo \u7684\u8fd9\u4e9b\u5751\uff0c\u6211\u4eec\u5e2e\u4f60\u8e29\u8fc7\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6950082433647640612"},"\u5f00\u6e90\u9879\u76ee\u90fd\u5728\u7528 monorepo\uff0c\u4f46\u662f\u4f60\u77e5\u9053\u5c45\u7136\u6709\u90a3\u4e48\u591a\u5751\u4e48\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6924854598268108807"},"All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5"))),(0,n.kt)("h2",{id:"rollup-\u7cfb\u5217"},"Rollup \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145090564801691684"},"\u3010\u5b9e\u6218\u7bc7\u3011\u6700\u8be6\u7ec6\u7684Rollup\u6253\u5305\u9879\u76ee\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7144365208646418462"},"\u4ece0\u52301\u5f00\u53d1\u4e00\u4e2aReact\u7ec4\u4ef6\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xjY0d8eNTmAuCZKxKQeu7g"},"\u57fa\u4e8estorybook\u7ec4\u4ef6\u5e93\u7684\u6280\u672f\u9009\u578b\u8be5\u600e\u4e48\u9009")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7151653067593613320"},"\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126394898445500423"},"\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mL1pv2kPKvtaHalr7PXKow"},"\u524d\u7aef\u5de5\u7a0b\u5316\u57fa\u5efa\u63a2\u7d22\uff1a\u4ece\u5185\u90e8\u673a\u5236\u548c\u6838\u5fc3\u539f\u7406\u4e86\u89e3npm")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069555431303020580"},"\u4e00\u6587\u5165\u95e8rollup\ud83e\ude80\uff0113\u7ec4demo\u5e26\u4f60\u8f7b\u677e\u9a7e\u9a6d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7051236803344334862"},"\u8bf4\u4e0d\u6e05rollup\u80fd\u8f93\u51fa\u54ea6\u79cd\u683c\u5f0f\ud83d\ude25\u5dee\u70b9\u88ab\u9119\u89c6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7052307032971411463"},"\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903970469576718"},"\u524d\u7aef\u7ec4\u4ef6/\u5e93\u6253\u5305\u5229\u5668rollup\u4f7f\u7528\u4e0e\u914d\u7f6e\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6869551115420041229"},"\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup"))),(0,n.kt)("h2",{id:"\u5fae\u524d\u7aef--\u6a21\u5757\u8054\u90a6"},"\u5fae\u524d\u7aef && \u6a21\u5757\u8054\u90a6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pT_tugg_EvE5pnMCaUqliw"},"Module Federation\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WXeUuUdgF_3djqBhh1siQA"},"\u6a21\u5757\u8054\u90a6\u5728\u5fae\u524d\u7aef\u67b6\u6784\u4e2d\u7684\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/u5oAcIYiGrl1qOujOYjzqw"},"\u57fa\u4e8e MF \u7684\u7ec4\u4ef6\u5316\u5171\u4eab\u5de5\u4f5c\u6d41")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l_KKNRUyJANN6wkoC2TlVQ"},"\u804a\u4e00\u804a\u5173\u4e8e\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121244973558661150"},"\u8d85\u5927\u4f53\u91cf\u9879\u76ee\uff0c\u5fae\u524d\u7aef\u843d\u5730\u65b9\u6848\uff0c\u770b\u5b8c\u540e\u6094\u6765\u627e\u6211")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA"},"\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iS-prT1xZPV6cpH7MHRRdQ"},"\u3010\u7b2c1912\u671f\u3011\u63a2\u7d22 webpack5 \u65b0\u7279\u6027Module federation\u5728\u817e\u8baf\u6587\u6863\u7684\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PFKxQgZPER_XHUSbk_SQJA"},"\u3010\u7b2c1901\u671f\u3011Webpack 5 Module Federation: JavaScript \u67b6\u6784\u7684\u53d8\u9769\u8005")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vy84FY3P6KPeWzDaNl6Ntg"},"\u5168\u9762\u654f\u6377\u6a21\u5f0f\u4e0b\u7684\u5fae\u524d\u7aef\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mvdOU8uVG9NjGPzInpPxJA"},"\u5fae\u524d\u7aef\u573a\u666f\u4e0b\u7684\u4ee3\u7801\u5171\u4eab")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg"},"\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ylkY9HWTQKPlbDb2M33YWQ"},"\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g"},"\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101457212085633054"},"\u6a21\u5757\u8054\u90a6\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g"},"\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww"},"\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation"))),(0,n.kt)("h2",{id:"vs-code-\u63d2\u4ef6"},"VS Code \u63d2\u4ef6"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4MmBSD-d-9T5-kFhcWNlTA"},"vscode\u63d2\u4ef6\u539f\u7406\u6d45\u6790\u4e0e\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/microsoft/vscode-extension-samples"},"vscode-extension-samples")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/e2gfSnBrR6rn7x37ZGLplg"},"\u5f00\u53d1\u4e00\u6b3e\u4e13\u5c5e\u7684 VSCode \u4ee3\u7801\u63d0\u793a\u63d2\u4ef6"))),(0,n.kt)("h2",{id:"\u524d\u7aef\u5de5\u7a0b\u5316"},"\u524d\u7aef\u5de5\u7a0b\u5316"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7062617190981173278"},"\u6765\u81ea\u672a\u6765\uff0c2022 \u5e74\u7684\u524d\u7aef\u4eba\u90fd\u5728\u505a\u4ec0\u4e48?")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7056612950412361741"},"\u4e3a\u4ec0\u4e48\u8bf4 WebAssembly \u662f Web \u7684\u672a\u6765\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7057114641507287048"},"easy-serverless \u529f\u80fd\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ckskF06PD43KHpKAGaYmRA"},"2022 \u5e74 JavaScript \u5f00\u53d1\u5de5\u5177\u7684\u751f\u6001")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JZbsIqsqNeJmc__QFKpo1Q"},"\u8d85\u5168\u9762\u7684\u524d\u7aef\u65b0\u4e00\u4ee3\u6784\u5efa\u5de5\u5177\u5bf9\u6bd4: esbuild\u3001Snowpack\u3001Vite\u3001wmr")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3aVYGfahv5rZJbWBhaI3BA"},"esno\uff0c\u57fa\u4e8e Esbuild \u7684\u795e\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qnA1tFKMXr7hwsEKFXKOZg"},"Deno \u7b80\u4ecb\uff1a\u5b83\u6bd4 Node.js \u66f4\u597d\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046204235226021901"},"\u57fa\u4e8e Next.js \u7684 SSR/SSG \u65b9\u6848\u4e86\u89e3\u4e00\u4e0b\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085257325165936648"},"\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029512357428592648"},"\u524d\u7aef\u67b6\u6784\u5e08\u795e\u6280\uff0c\u4e09\u62db\u7edf\u4e00\u56e2\u961f\u4ee3\u7801\u98ce\u683c")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904110601273357"},"\u624b\u628a\u624b\u6559\u4f60\u642d\u5efa\u4e00\u4e2a\u7070\u5ea6\u53d1\u5e03\u73af\u5883")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7049696761858195486"},"ES6 \u4ee5\u4e0a\u7248\u672c\u4ee3\u7801\u8981\u4e0d\u8981\u8f6c\u7801\u6210 ES5 ?")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3TKcUeoyzXvH3MGVI6Dj9A"},"ESM \u4e0e CJS \u7684 Interop \u6765\u4e16\u4eca\u751f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/493891614/answer/2269197391"},"2022 \u524d\u7aef\u6280\u672f\u9886\u57df\u4f1a\u6709\u54ea\u4e9b\u65b0\u7684\u53d8\u5316\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000040496020"},"\u524d\u7aef\u6784\u5efa\u8fd9\u5341\u5e74"))),(0,n.kt)("h2",{id:"\u8f6f\u4ef6\u67b6\u6784--\u8bbe\u8ba1\u6a21\u5f0f"},"\u8f6f\u4ef6\u67b6\u6784 && \u8bbe\u8ba1\u6a21\u5f0f"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f Software Engineering at Google",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u5728\u7ebf\u9605\u8bfb\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://abseil.io/blog/04222021-swe-book"},"https://abseil.io/blog/04222021-swe-book")),(0,n.kt)("li",{parentName:"ul"},"PDF \u4e0b\u8f7d\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://github.com/garfield-dev-team/Frontend-Training-Program/blob/main/OReilly.Software.Engineering.at.Google.2020.3.pdf"},"https://github.com/garfield-dev-team/Frontend-Training-Program/blob/main/OReilly.Software.Engineering.at.Google.2020.3.pdf")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/wiseai/the-ultimate-guide-to-software-engineering-545e"},"The Ultimate Guide To Software Engineering")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145014659584622629"},"\u8bed\u96c0\u684c\u9762\u7aef\u6280\u672f\u67b6\u6784\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg"},"\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kFjfzwTOdaKA2ym63VR3DQ"},"\u63a2\u79d8\u5fae\u4fe1\u4e1a\u52a1\u4f18\u5316\uff1aDDD\u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/12BS4V6fvXkeb84XDpPnHw"},"\u4e86\u89e3\u5fae\u524d\u7aef\uff0c\u6df1\u5165\u524d\u7aef\u67b6\u6784\u7684\u524d\u4e16\u4eca\u751f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg"},"\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ocPx6Sw09ioDyz_IOWK69Q"},"\u5de5\u4f5c\u4e2d\u5e38\u89c1\u7684 6 \u79cd\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f60\u7528\u8fc7\u51e0\u79cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3MwRLM0jDmwv5l6gamFjcw"},"\u3010\u7b2c2757\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u768423\u4e2a\u57fa\u672c\u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iB23DV4hovPDdf5_4TCaOA"},"\u3010\u7b2c2677\u671f\u3011\u5982\u4f55\u5728React\u4e2d\u5e94\u7528SOLID\u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1h6yqCWyzYLM8WPGlGdtVA"},"\u3010\u7b2c2703\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw"},"\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ"},"\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/surfacew/fe/qg0uev"},"\u6df1\u5165\u6d45\u51fa\u524d\u7aef\u505a\u63a7\u5236\u53cd\u8f6c\u4e0e\u4f9d\u8d56\u6ce8\u5165")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw"},"javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iZ9BX6cCCp_TB-SC3knuew"},"\u5b9e\u6218\uff01\u5982\u4f55\u4ece\u96f6\u642d\u5efa10\u4e07\u7ea7 QPS \u5927\u6d41\u91cf\u3001\u9ad8\u5e76\u53d1\u4f18\u60e0\u5238\u7cfb\u7edf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg"},"\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SMAycMJPWr018sU04kbfbQ"},"\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1\u56db\u8bba")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BIYp9DNd_9sw5O2daiHmlA"},"\u4e07\u5b57\u957f\u6587\u52a9\u4f60\u4e0a\u624b\u8f6f\u4ef6\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1 DDD")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QCIlheiEgmU4Qi-4b_XoqQ"},"\u7528DDD(\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1)\u548cADT(\u4ee3\u6570\u6570\u636e\u7c7b\u578b)\u63d0\u5347\u4ee3\u7801\u8d28\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hsH7LMBEDGe_df9UbfOvbQ"},"\u540e\u53f0\u670d\u52a1\u67b6\u6784\u9ad8\u6027\u80fd\u8bbe\u8ba1\u4e4b\u9053")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://coolshell.cn/articles/21672.html"},"\u6211\u505a\u7cfb\u7edf\u67b6\u6784\u7684\u4e00\u4e9b\u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/m1Dv-YG60AKArGu-URr88w"},"\u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\u4e2d\u5982\u4f55\u505a\u597d\u6280\u672f\u51b3\u7b56\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4bB_B5JTOrev8mqfG7K2cw"},"\u524d\u7aef\u9886\u57df\u7684 \u201c\u5e72\u51c0\u67b6\u6784\u201d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/g9F05SRnQBTzzfx_2CKqhg"},"\u53ea\u4f1a\u7528\u4f20\u7edf\u5f00\u53d1\u6a21\u5f0f\uff1f10\u5206\u949f\u6559\u4f60\u73a9\u8f6c\u654f\u6377\uff01"))),(0,n.kt)("h2",{id:"\u6301\u7eed\u96c6\u6210"},"\u6301\u7eed\u96c6\u6210"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg"},"\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/445217118"},"\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064906701941506061"},"GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=fqMOX6JJhGo"},"Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"},"Best practices for writing Dockerfiles")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://docs.docker.com/engine/reference/builder/"},"Dockerfile reference")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903793348329486"},"\u5982\u4f55\u4f7f\u7528 docker \u90e8\u7f72\u524d\u7aef\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://shanyue.tech/op/docker.html"},"docker \u7b80\u6613\u5165\u95e8 - shanyue")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4aFJ7t37IwEMyq-u09Wf1g"},"\u5c0f\u9cb8\u9c7c\u7684\u524d\u4e16\u4eca\u751f--Docker")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/6844733746462064654/section/6844733746504007693"},"\u5f00\u53d1\u8005\u5fc5\u5907\u7684 Docker \u5b9e\u8df5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U-zK6JEMpmK2Il68-ijcaw"},"\u8c01\u8bf4\u524d\u7aef\u4e0d\u9700\u8981\u5b66\u4e60docker\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7028222480326066213"},"\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6951684431597797389"},"\u524d\u7aef\u5f00\u53d1\u8005\u5e94\u8be5\u77e5\u9053\u7684 Centos/Docker/Nginx/Node/Jenkins \u64cd\u4f5c(\ud83c\udf61 \u957f\u6587)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7049920990351982628"},"\u4fdd\u59c6\u7ea7\u6307\u5357\uff1ajekins+docker\u6784\u5efa\u90e8\u7f72react\u9879\u76ee\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6993951401952935972"},"\u4f60\u7684\u7b2c\u4e00\u4e2a Docker + React + Express \u5168\u6808\u5e94\u7528"))),(0,n.kt)("h2",{id:"\u670d\u52a1\u7aef\u76f8\u5173"},"\u670d\u52a1\u7aef\u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u63a8\u8350\u7b97\u6cd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GetU-ULhfvY8ri47Ht28GQ"},"\u56fe\u6587\u89e3\u8bfb\uff1a\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7cbe\u6392\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wXb5uQJBCzSEq6IITP7VCQ"},"\u8d85\u5f3a\u6307\u5357\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u91cd\u6392")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1wOnG4dtNSI-x2x15-AjTQ"},"\u8be6\u7ec6\u89e3\u8bfb\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u53ec\u56de")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YsK_8yyBNL5z269qT5CrIw"},"\u56fe\u6587\u5e76\u8302\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7c97\u6392")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153878508035391502"},"\u8be6\u89e3\u95f2\u9c7c\u63a8\u8350\u7cfb\u7edf\uff08\u957f\u6587\u6536\u85cf\uff09")))),(0,n.kt)("li",{parentName:"ul"},"Redis \u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/469102289"},"Redis\u8be6\u7ec6\u5165\u95e8\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fnOvw4JfwszNGVBMW0N2hw"},"Redis \u53ea\u4f1a\u7528\u7f13\u5b58\uff1f16\u79cd\u5999\u7528\u8ba9\u540c\u4e8b\u76f4\u547c\u725bX")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ThVtw8TVuhxIyYxJy6sOWw"},"\u6df1\u5165\u6d45\u51fa\u5e26\u4f60\u8d70\u8fdbRedis\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U87wrGsx0Eop3CbF9mlTwQ"},"\u4e07\u5b57\u56fe\u6587\u8bb2\u900f\u6570\u636e\u5e93\u7f13\u5b58\u4e00\u81f4\u6027\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vwx99ER-9qiH9nfwtFW1zQ"},"Redis \u4e8b\u52a1\u9047\u4e0a @Transactional \u6709\u5927\u5751\uff01\uff01\u8bb0\u4e00\u6b21 Redis \u751f\u4ea7\u4e8b\u6545")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw"},"Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw"},"\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147602740405862407"},"Redis \u6301\u4e45\u5316\u7b56\u7565\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dCZm7e0aSEirhEqiCBvAyQ"},"\u56fe\u6587\u7ed3\u5408\uff01Redis\u5ef6\u8fdf\u961f\u5217golang\u9ad8\u6548\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/frOhO8rj2Xvdix6tnjTOrw"},"\u7528 Redis \u90fd\u80fd\u5b9e\u73b0\u54ea\u4e9b\u529f\u80fd\uff1f\u8fd92\u4e07\u5b57+20\u5f20\u56fe\u7ed9\u5206\u6790\u5168\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mO819q_r9qLVuRBE8cjx1Q"},"\u5982\u4f55\u4fdd\u8bc1\u6570\u636e\u5e93\u548c\u7f13\u5b58\u53cc\u5199\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Cq-CF1BC4PWwGnlRp4HrnQ"},"\u4e3a\u4e86\u62ff\u634f Redis \u6570\u636e\u7ed3\u6784\uff0c\u6211\u753b\u4e86 40 \u5f20\u56fe\uff08\u5b8c\u6574\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124572920403197965"},"Redis 5 \u79cd\u57fa\u672c\u6570\u636e\u7ed3\u6784\uff08String\u3001List\u3001Hash\u3001Set\u3001Sorted Set\uff09\u8be6\u89e3 | JavaGuide")))),(0,n.kt)("li",{parentName:"ul"},"Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2Rwy19C0eUshTWc_JfTPig"},"Redis\u5206\u5e03\u5f0f\u9501\u768410\u4e2a\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/p2rlkCRRj7h7-aojTidQbg"},"\u6df1\u5165\u7406\u89e3 go singleflight")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ESdfA5sJa6bmL-HvuWpoJA"},"\u9762\u8bd5\u5b98\uff1a\u5982\u4f55\u7528 Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RS1kKvF_Ly576GV52bHQPg"},"\u5982\u4f55\u7528Redis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lrSQBK-Kihkj6994kQFpUQ"},"Go\uff1a\u5206\u5e03\u5f0f\u9501\u5b9e\u73b0\u539f\u7406\u4e0e\u6700\u4f73\u5b9e\u8df5")))),(0,n.kt)("li",{parentName:"ul"},"Web Server",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085519712901136392"},"\u8d85\u8d8a Nginx\uff01\u53f7\u79f0\u4e0b\u4e00\u4ee3 Web \u670d\u52a1\u5668\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")))),(0,n.kt)("li",{parentName:"ul"},"IO\u591a\u8def\u590d\u7528",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j1KjR5bRQV6oGrU5tsyHgg"},"\u4eceLinux\u96f6\u62f7\u8d1d\u6df1\u5165\u4e86\u89e3Linux-I/O")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5xj42JPKG8o5T7hjXIKywg"},"\u6df1\u5165\u5b66\u4e60IO\u591a\u8def\u590d\u7528 select/poll/epoll \u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg"},"\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3")))),(0,n.kt)("li",{parentName:"ul"},"\u7cfb\u7edf\u8bbe\u8ba1",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FJi3ko9wjTBNWS79RVQf5A"},"\u6280\u672f\u603b\u76d1\u5206\u4eab\u7684\u7cfb\u7edf\u8bbe\u8ba1\u6280\u5de7\uff0c\u4e07\u80fd\u901a\u7528\uff0c\u7a33\u7684\u4e00\u6279\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PPA8Iw6K2M2xVnGE-Tf6zw"},"\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1\u768415\u4e2a\u9526\u56ca")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5Jj-IClPhInXz7xsfUZEnQ"},"\u652f\u4ed8\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qhsVURhXm0Ot-jWq0khfEg"},"\u8682\u8681\u91d1\u670d\u4e00\u9762\uff1a\u5341\u9053\u7ecf\u5178\u9762\u8bd5\u9898\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ebh5iVsx0iExb5Wxq3tQFQ"},"\u516c\u53f8\u65b0\u6765\u4e00\u4e2a\u540c\u4e8b\uff0c\u628a\u4f18\u60e0\u5238\u7cfb\u7edf\u8bbe\u8ba1\u7684\u7089\u706b\u7eaf\u9752\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8GXe6sKPKk7Flbd_kNAp2Q"},"\u7f51\u5173\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/crzfBEGn78nUZ5H3MF8UZw"},"\u9ad8\u5e76\u53d1\u4e0b\uff0c\u5e42\u7b49\u6027\u5982\u4f55\u4fdd\u8bc1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw"},"Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Z0xVHgw-ZzZV-jOOOSsMUw"},"\u5982\u4f55\u8bbe\u8ba1\u4e00\u4e2a\u77ed\u94fe\u670d\u52a1")))),(0,n.kt)("li",{parentName:"ul"},"\u6d88\u606f\u961f\u5217",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/D8ptc4SCqWtaWe-ZBhwXfA"},"\u804a\u804aRocketMQ\u5b58\u50a8\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mNpXpSVVVBuI59LI6vVvQA"},"\u9762\u6e23\u9006\u88ad\uff1aRocketMQ\u4e8c\u5341\u4e09\u95ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GeXtCJgo42u92FSS5V6oMQ"},"\u5228\u6839\u95ee\u5e95 Kafka\uff0c\u6838\u5fc3\u77e5\u8bc6\u70b9\u5927\u8d2f\u901a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J0zKPTNoJgiFvNT4M9BVcg"},"\u6d88\u606f\u961f\u5217\u539f\u7406\u548c\u9009\u578b\uff1aKafka\u3001RocketMQ \u3001RabbitMQ \u548c ActiveMQ")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i_bwyEb8QqfVLxY-R9odag"},"\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u513f\u53eb MQ")))),(0,n.kt)("li",{parentName:"ul"},"Elasticsearch \u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7155662252584992805"},"MyBatis-Plus\u540c\u6b3eElasticsearch ORM\u6846\u67b6\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904117580595214"},"Elasticsearch\u5feb\u901f\u5165\u95e8\uff0c\u638c\u63e1\u8fd9\u4e9b\u521a\u521a\u597d\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GG_zrQlaiP2nfPOxzx_j9w"},"Elasticsearch \u57fa\u7840\u5165\u95e8\u8be6\u6587")))),(0,n.kt)("li",{parentName:"ul"},"\u5927\u6570\u636e\u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vua2g0_t1Y8KW4cNHSQdNw"},"\u4e00\u6587\u4e86\u89e3-\u4e91\u539f\u751f\u5927\u6570\u636e\u77e5\u8bc6\u5730\u56fe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7149487706991493156"},"\u3010\u4e91\u539f\u751f\u3011Hive on k8s \u73af\u5883\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7087484692718420005"},"\u5927\u6570\u636eHadoop\u4e4b\u2014\u2014\u6570\u636e\u4ed3\u5e93Hive")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7136214451678052389"},"\u3010\u4e91\u539f\u751f\u3011Kubernetes\uff08k8s\uff09\u6700\u5b8c\u6574\u7248\u73af\u5883\u90e8\u7f72+master\u9ad8\u53ef\u7528\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7141215211586863140"},"Flink \u6d41\u6279\u4e00\u4f53\u5728\u5b57\u8282\u8df3\u52a8\u7684\u63a2\u7d22\u4e0e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G66BCDUMzYE30p250JO0hg"},"\u5927\u6570\u636e\u67b6\u6784\u7cfb\u5217\uff1a\u5982\u4f55\u7406\u89e3\u6e56\u4ed3\u4e00\u4f53")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yQavfvBayYbMEc7c9ObMxg"},"23\u5f20\u56fe\uff0c\u5e26\u4f60\u5165\u95e8\u63a8\u8350\u7cfb\u7edf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gAhoIwPoFDlKbBmWzrHu8w"},"\u4e00\u6587\u770b\u61c2\u5927\u6570\u636e\u751f\u6001\u5708\u5b8c\u6574\u77e5\u8bc6\u4f53\u7cfb\uff08\u6587\u672b\u9001\u4e66\uff09")))),(0,n.kt)("li",{parentName:"ul"},"\u4e91\u539f\u751f\u76d1\u63a7",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/72UbwZTxo36eJVqGq8HBgw"},"\u81ea\u4ece\u9879\u76ee\u4e0a\u4e86SkyWalking\uff0c\u7761\u89c9\u771f\u9999\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/D1JoTzdQnzUgX_yqT3N1BQ"},"\u81ea\u4ece\u7ebf\u4e0a\u9879\u76ee\u7528\u4e86\u8fd9\u4e2a\u76d1\u63a7\u7cfb\u7edf\uff0c\u7761\u89c9\u771f\u9999\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bSw_QP4-xMKnBTmqAjkUGA"},"\u8fd8\u5728\u670d\u52a1\u5668\u4e0a\u635e\u65e5\u5fd7\uff1f\u5feb\u642d\u5efa\u4e00\u4e2aELK\u65e5\u5fd7\u7cfb\u7edf\u5427\uff0c\u771f\u5fc3\u5f3a\u5927\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg"},"\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01")))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hJHMlbQpANwMjx9BetwkUg"},"\u4e00\u81f4\u6027\u54c8\u5e0c\u7b97\u6cd5\u89e3\u51b3\u7684\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/482549860"},"\u4e00\u81f4\u6027Hash\u7b97\u6cd5\u539f\u7406\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA"},"100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l3l9d9sLiWoUM381E9o-3Q"},"\u89e3\u51b3\u4e86 Redis \u5927 key \u95ee\u9898\uff0c\u540c\u4e8b\u4eec\u90fd\u8bf4\u725b\u76ae\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l_YdpyHht5Ayvrc7LFZNIA"},"\u56fe\u89e3|Linux\u5185\u5b58\u80cc\u540e\u7684\u90a3\u4e9b\u795e\u79d8\u5f80\u4e8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064952956201730062"},"\u56fe\u89e3|\u4ec0\u4e48\u662f\u5185\u5bb9\u5206\u53d1\u7f51\u7edc(cdn)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7070683049049980941"},"\u4e00\u952e\u90e8\u7f72 K8S \u73af\u5883\uff0c10\u5206\u949f\u73a9\u8f6c\uff0c\u8fd9\u6b3e\u5f00\u6e90\u795e\u5668\u5b9e\u5728\u592a\u9999\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KIcn2TAwY58JGoWiz82Q2g"},"\u989c\u503c\u7206\u8868\uff01Redis \u5b98\u65b9\u53ef\u89c6\u5316\u5de5\u5177\u6765\u5566\uff0c\u529f\u80fd\u771f\u5fc3\u5f3a\u5927\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904017286561799"},"Nginx\u7684\u8fd9\u4e9b\u5999\u7528\uff0c\u4f60\u80af\u5b9a\u6709\u4e0d\u77e5\u9053\u7684\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064378702779891749"},"\u524d\u7aef\u5230\u5e95\u7528nginx\u6765\u505a\u5565")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7048952689601806366"},"\u4e00\u4efd\u7b80\u5355\u591f\u7528\u7684 Nginx Location \u914d\u7f6e\u8bb2\u89e3"))),(0,n.kt)("h2",{id:"\u524d\u7aef\u6027\u80fd\u4f18\u5316"},"\u524d\u7aef\u6027\u80fd\u4f18\u5316"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6981673766178783262"},"\u5199\u7ed9\u4e2d\u9ad8\u7ea7\u524d\u7aef\u5173\u4e8e\u6027\u80fd\u4f18\u5316\u76849\u5927\u7b56\u7565\u548c6\u5927\u6307\u6807 | \u7f51\u6613\u56db\u5e74\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Au_NNeamEoFEtlNvvVjpLw"},"\u524d\u7aef\u76d1\u63a7\u7cfb\u52173 \uff5c \u5982\u4f55\u8861\u91cf\u4e00\u4e2a\u7ad9\u70b9\u7684\u6027\u80fd\u597d\u574f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7052918009555320839"},"\u6700\u5168\u7684\u524d\u7aef\u6027\u80fd\u5b9a\u4f4d\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wJxj5QbOHwH9cKmqU5eSQw"},"Web\u9875\u9762\u5168\u94fe\u8def\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7016900744695513125"},"\u5b57\u8282\u8df3\u52a8\u662f\u5982\u4f55\u843d\u5730\u5fae\u524d\u7aef\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7048260643589193765"},"2022 \u5e74\u7684 CSS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7054931603323093022"},"\u5982\u4f55\u7f16\u5199\u9632\u5fa1\u5f0f\u7684 CSS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/396010993"},"\u524d\u7aef Code Review \u4e0d\u5b8c\u5168\u6307\u5317(\u4e07\u5b57\u957f\u6587\uff0c50+case)")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7020212914020302856"},"\u5199\u5728 2021 \u7684\u524d\u7aef\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7000728875676205086"},"\u6df1\u5165\u6d45\u51fa Performance \u5de5\u5177 & API")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6904582930174705677"},"\u4f7f\u7528 Performance \u770b\u770b\u6d4f\u89c8\u5668\u5728\u505a\u4ec0\u4e48"))),(0,n.kt)("h2",{id:"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218"},"\u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7120893568553582622"},"\u5feb\u4e0a\u8f66\uff01\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117886038126624805"},"\u4f7f\u7528Vite\u548cTypeScript\u5e26\u4f60\u4ece\u96f6\u6253\u9020\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684Vue3\u7ec4\u4ef6\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069772395610898462"},"\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904197863964685"},"\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021528826798669854"},"\u5c24\u5927\u90fd\u63a8\u8350\u7684\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u5f00\u53d1\u51fa\u6765\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6983854006124675108"},"\u6bcf\u4e2a\u524d\u7aef\u90fd\u503c\u5f97\u62e5\u6709\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff0c\u5c31\u50cf\u6bcf\u4e2a\u590f\u5929\u90fd\u62e5\u6709\u897f\u74dc\ud83c\udf49")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6930879590554402830"},"Vue3\u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218 --Element3"))),(0,n.kt)("h2",{id:"nodejs-\u7cfb\u5217"},"Node.js \u7cfb\u5217"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/koala-coding/goodBlog"},"\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/B051n14JbNHqJtQb68HBFA"},"Node.js \u6982\u8ff0\uff1a\u67b6\u6784\u3001API\u3001\u4e8b\u4ef6\u5faa\u73af\u3001\u5e76\u53d1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sSfj4BOjHNyzdjGc90yU8g"},"\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0a\u3011")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9SJL2UttCedNjF6CKyk3wg"},"\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0b\u3011")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6887961766170066951"},"\u5927\u5382\u662f\u5982\u4f55\u7528DevCloud\u6d41\u6c34\u7ebf\u5b9e\u73b0\u81ea\u52a8\u5316\u90e8\u7f72Web\u5e94\u7528\u7684\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6902659492161421325"},"\u624b\u628a\u624b\u6559\u4f60\u4f7f\u7528Rollup\u6253\u5305 \ud83d\udce6 \u5e76\u53d1\u5e03\u81ea\u5df1\u7684\u5de5\u5177\u5e93 \ud83d\udd27")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/461945753"},"Node \u6848\u53d1\u73b0\u573a\u63ed\u79d8 \u2014\u2014 \u672a\u5b9a\u4e49 \u201cwindow\u201d \u5bf9\u8c61\u5f15\u53d1\u7684 SSR \u5185\u5b58\u6cc4\u9732")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://cnodejs.org/topic/58eb5d378cda07442731569f"},"\u8f7b\u677e\u6392\u67e5\u7ebf\u4e0aNode\u5185\u5b58\u6cc4\u6f0f\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/36728655"},"Node.js \u6d41\uff08stream\uff09\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1DIDUvGoQcckRq757R9Ohw"},"\u6700\u5168\u9762\u7684 Node.js \u8d44\u6e90\u6c47\u603b\u63a8\u8350")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yKm_U9Veh_1twIoXzM8Prw"},"Nest.js\u8fdb\u9636\u7cfb\u5217\u56db\uff1aNode.js\u4e2d\u4f7f\u7528Redis\u539f\u6765\u8fd9\u4e48\u7b80\u5355\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TmCtsbhjexZNCdvUSXdNCw"},"Redis\u5b66\u4e60-\u5165\u95e8\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2CBGgtja04NnOerpKfk0Ug"},"Node.js \u5b89\u5168\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PhuFfNAhvXAqW4eSbUqpKQ"},"2022\u5e74\u503c\u5f97\u4f7f\u7528\u7684 Node.js \u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7095354780079357966"},"NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/502951532"},"Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/415361629"},"\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/unjs"},"unjs: Unified JavaScript Tools")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/vercel/pkg"},"pkg - \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/oclif/oclif"},"Oclif v2.5\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6961790494514872333"},"JavaScript Debugger \u539f\u7406\u63ed\u79d8")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xCoTeyJDifi4Ymk0VsI2Ig"},"\u6d45\u8c08 Node.js \u70ed\u66f4\u65b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7044344538969669663"},"NodeJS\u52a0\u89e3\u5bc6\u4e4bCrypto")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/google/zx"},"zx - \u8c37\u6b4c\u5f00\u53d1\u7684\u547d\u4ee4\u884c\u811a\u672c\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/node-fetch/node-fetch"},"node-fetch - node \u73af\u5883\u4e0b\u8fdb\u884c\u7f51\u7edc\u8bf7\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6971770846872338439"},"\u6d45\u6790 NodeJS \u591a\u8fdb\u7a0b\u548c\u96c6\u7fa4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/privatenumber/tasuku"},"Tasuku - \u9762\u5411 Node \u7684\u6700\u5c0f\u4efb\u52a1\u8fd0\u884c\u5668")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7008504029277847565"},"Node.js\u7684\u5e95\u5c42\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Gcx6E4cYo6WPB8PLI72NWg"},"\u8ba4\u771f\u5199\u4e86\u4e2a\u5feb\u901f\u521b\u5efa Node \u670d\u52a1\u7684CLI\uff0c\u770b\u770b\u5bf9\u5c0f\u4f19\u4f34\u4eec\u6709\u5e2e\u5fd9\u5417\uff1f"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u9879\u76ee\u5730\u5740\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://github.com/koala-coding/create-bff-service-cli"},"https://github.com/koala-coding/create-bff-service-cli"))))),(0,n.kt)(d,{mdxType:"Tabs"},(0,n.kt)(G,{value:"\u5f00\u6e90\u9879\u76ee",label:"\u5f00\u6e90\u9879\u76ee",default:!0,mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/antfu/taze"},"taze - \u66f4\u65b0\u4f9d\u8d56\u7248\u672c\u7684 CLI \u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/egoist/haya"},"haya - Vite \u7684\u66ff\u4ee3\u65b9\u6848\uff0c\u63d0\u4f9b\u57fa\u4e8e esbuild \u7684 devServer \u548c bundler")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/unjs/unbuild"},"unbuild - \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/egoist/tsup"},"tsup - \u96f6\u914d\u7f6e\u7684 TS \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/Rich-Harris/degit"},"degit - \u7b80\u5355\u7684\u9879\u76ee\u811a\u624b\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/streamich/react-use"},"react-use - \u4e00\u4e2a React Hooks \u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/tannerlinsley/react-query"},"react-query - \u7528\u4e8e\u83b7\u53d6\u6570\u636e\u3001\u7f13\u5b58\u3001\u5f02\u6b65\u66f4\u65b0\u72b6\u6001\u7684 hook")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/luin/ioredis"},"ioredis - \u4e13\u6ce8\u4e8e\u6027\u80fd\u7684\u5168\u529f\u80fd Redis \u5ba2\u6237\u7aef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/prisma/prisma"},"prisma - \u4e0b\u4e00\u4ee3 Nodejs ORM \u5de5\u5177\uff0c\u652f\u6301\u5404\u79cd\u6570\u636e\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/withastro/astro"},"astro - \u9759\u6001\u7ad9\u70b9\u6784\u5efa\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/pmndrs/zustand"},"zustand - \u5c0f\u578b\u3001\u5feb\u901f\u53ef\u6269\u5c55\u7684\u72b6\u6001\u7ba1\u7406\u89e3\u51b3\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/tauri-apps/tauri"},"tauri - \u5c06\u524d\u7aef\u9879\u76ee\u6253\u5305\u4e3a\u684c\u9762\u5e94\u7528\uff0c\u7528\u4e8e\u66ff\u4ee3 electron")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/trpc/trpc"},"tRPC - \u65b9\u4fbf\u5feb\u901f\u7684\u751f\u6210\u7aef\u5bf9\u7aef\u7c7b\u578b\u5b89\u5168\u7684 API \u5b9a\u4e49")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/MaxLeiter/Drift"},"Drift - \u4e00\u4e2a\u53ef\u4ee5\u81ea\u5df1\u90e8\u7f72\u7684\u4ee3\u7801\u7247\u6bb5\u670d\u52a1\uff0c\u57fa\u4e8e Next.js 13 \u6784\u5efa")))),(0,n.kt)(G,{value:"React \u751f\u6001",label:"React \u751f\u6001",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/bytedance/bytemd"},"bytemd - \u5b57\u8282\u51fa\u54c1\u7684 markdown \u7f16\u8f91\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/bytedance/guide"},"guide - \u5b57\u8282\u51fa\u54c1\u7684 React \u65b0\u624b\u5f15\u5bfc\u7ec4\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/rpearce/react-medium-image-zoom"},"react-medium-image-zoom - \u53d7 Medium.com \u542f\u53d1\u7684\u56fe\u7247\u9884\u89c8\u7ec4\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/pacocoursey/cmdk"},"cmdk - \u4e00\u4e2a\u57fa\u4e8e React \u7684\u5feb\u901f\u3001\u53ef\u7ec4\u5408\u3001\u65e0\u98ce\u683c\u7684\u547d\u4ee4\u9762\u677f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/eBay/nice-modal-react"},"nice-modal-react\uff1a\u6765\u81ea eBay \u7684\u6a21\u6001\u6846\u72b6\u6001\u7ba1\u7406")))),(0,n.kt)(G,{value:"\u6d4f\u89c8\u5668\u73af\u5883",label:"\u6d4f\u89c8\u5668\u73af\u5883",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/date-fns/date-fns"},"date-fns - \u73b0\u4ee3\u5316\u7684 JavaScript \u65e5\u671f\u7c7b\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/ai/nanoid"},"nanoid - \u7528\u4e8e\u66ff\u4ee3 uuid \u7684\u968f\u673a id \u751f\u6210\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"dayjs"),"\uff1a\u4e0e ",(0,n.kt)("inlineCode",{parentName:"li"},"moment")," \u7684 API \u8bbe\u8ba1\u4fdd\u6301\u4e00\u6837\uff0c\u4f46\u4f53\u79ef\u4ec5\u6709 2KB\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"qs"),"\uff1a\u89e3\u6790 URL query \u53c2\u6570\u7684\u5e93\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"js-cookie"),"\uff1a\u7b80\u5355\u3001\u8f7b\u91cf\u7684\u5904\u7406 cookie \u7684\u5e93\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"flv.js"),"\uff1abilibili \u5f00\u6e90\u7684 HTML5 flash \u64ad\u653e\u5668\uff0c\u4f7f\u6d4f\u89c8\u5668\u5728\u4e0d\u501f\u52a9 flash \u63d2\u4ef6\u7684\u60c5\u51b5\u4e0b\u53ef\u4ee5\u64ad\u653e flv\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"vConsole"),"\uff1a\u4e00\u4e2a\u8f7b\u91cf\u3001\u53ef\u62d3\u5c55\u3001\u9488\u5bf9\u624b\u673a\u7f51\u9875\u7684\u524d\u7aef\u5f00\u53d1\u8005\u8c03\u8bd5\u9762\u677f\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"animate.css"),"\uff1a\u4e00\u4e2a\u8de8\u6d4f\u89c8\u5668\u7684 css3 \u52a8\u753b\u5e93\uff0c\u5185\u7f6e\u4e86\u5f88\u591a\u5178\u578b\u7684 css3 \u52a8\u753b\uff0c\u517c\u5bb9\u6027\u597d\uff0c\u4f7f\u7528\u65b9\u4fbf\uff1b"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"lodash"),"\uff1a\u4e00\u4e2a\u4e00\u81f4\u6027\u3001\u6a21\u5757\u5316\u3001\u9ad8\u6027\u80fd\u7684 JavaScript \u5b9e\u7528\u5de5\u5177\u5e93\uff1b"))),(0,n.kt)(G,{value:"\u5b9e\u7528\u5de5\u5177",label:"\u5b9e\u7528\u5de5\u5177",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/paulmillr/chokidar"},"chokidar - \u8de8\u5e73\u53f0\u76d1\u542c\u6587\u4ef6\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/jprichardson/node-fs-extra"},"fs-extra - Node \u539f\u751f fs \u6a21\u5757\u7684\u6269\u5c55")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"yargs"),"\uff1a\u901a\u8fc7\u4f7f\u7528 Node.js \u6784\u5efa\u529f\u80fd\u5168\u9762\u7684\u547d\u4ee4\u884c\u5e94\u7528"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"Ajv"),"\uff1a\u4e00\u4e2a\u9002\u7528\u4e8e Node.js \u548c\u6d4f\u89c8\u5668\u7684\u6700\u5feb JSON \u9a8c\u8bc1\u5668"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"yallist"),"\uff1a\u4e00\u4e2a\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"rimraf"),"\uff1aNode.js \u7684 rm -rf \u5b9e\u7528\u7a0b\u5e8f"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"consola"),"\uff1aNuxt.js \u51fa\u54c1\u7684\u7ec8\u7aef\u65e5\u5fd7\u5de5\u5177"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"webpackbar"),"\uff1aNuxt.js \u51fa\u54c1\u7684 webpack \u7f16\u8bd1\u8fdb\u5ea6\u6761"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"pkg"),": \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"concurrently"),"\uff1a\u66f4\u4f18\u96c5\u5730\u5e76\u53d1\u6267\u884c\u547d\u4ee4"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"better-logging"),"\uff1aNode \u9ed8\u8ba4\u65e5\u5fd7\u8bb0\u5f55\u65b9\u6cd5\u7684\u66ff\u4ee3\u54c1"))),(0,n.kt)(G,{value:"CLI \u5de5\u5177",label:"CLI \u5de5\u5177",mdxType:"TabItem"},(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"chalk/kolorist")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"inquirer/prompts")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"ora")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"semver")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"pkg-install")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"ncp"),"\uff1a\u8de8\u5e73\u53f0\u9012\u5f52\u62f7\u8d1d\u6587\u4ef6"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"commander/yargs")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"execa"),"\uff08\u4e2a\u4eba\u89c9\u5f97 Node \u539f\u751f ",(0,n.kt)("inlineCode",{parentName:"li"},"child_process")," \u7684 ",(0,n.kt)("inlineCode",{parentName:"li"},"exec")," \u5c31\u591f\u7528\u4e86\uff09"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"minimist")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("inlineCode",{parentName:"li"},"oclif"),"\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6")))),(0,n.kt)("h2",{id:"\u524d\u7aef\u7f16\u8bd1"},"\u524d\u7aef\u7f16\u8bd1"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JMl8LOsNYlttxO-KyVK-Vw"},"\u3010\u7b2c2597\u671f\u3011\u5982\u4f55\u7528JavaScript\u5b9e\u73b0\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 - AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7041021350114230285"},"V8 \u7f16\u8bd1\u6d45\u8c08")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7057354419888717855"},"\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e8c\uff09\u2014\u2014 Antlr \u53ca\u5176\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6989509925844041742"},"\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e00\uff09\u2014\u2014 \u7f16\u8bd1\u539f\u7406\u57fa\u7840")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/6946117847848321055"},"Babel \u63d2\u4ef6\u901a\u5173\u79d8\u7c4d")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.zoo.team/article/the-process-of-executing-js-in-v8"},"v8 \u6267\u884c js \u7684\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://laocuicode.cn/daydream/2022/04/01/202241-%E7%A1%AC%E6%A0%B8%E5%86%B7%E7%9F%A5%E8%AF%86%EF%BC%9AWebAssembly/"},"\u786c\u6838\u51b7\u77e5\u8bc6\uff1aV8\u4e0eWebAssembly\u4e0d\u5f97\u4e0d\u8bf4\u7684\u79d8\u5bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7018563244679757855"},"import \u65b9\u5f0f\u968f\u610f\u4e92\u8f6c\uff0c\u611f\u53d7 babel \u63d2\u4ef6\u7684\u5a01\u529b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pNossFUtJrDHshXbWLb4vA"},"\u4ece\u96f6\u5230\u4e00\uff0c\u6211\u4eec\u6765\u4e00\u8d77\u9020\u4e2a JS \u7684\u7f16\u8bd1\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7047329886502912030"},"\u6d45\u6790TypeScript Compiler \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6962861837800964133"},"\u300a\u4ece 0 \u5230 1 \u624b\u5199 babel\u300b\u601d\u8def\u5206\u4eab")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6953963506693570573"},"\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357"))),(0,n.kt)("h2",{id:"\u7f51\u7edc\u76f8\u5173"},"\u7f51\u7edc\u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/"},"HTTP/3 From A To Z: Core Concepts")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7155280646112280613"},"502\u95ee\u9898\u600e\u4e48\u6392\u67e5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153255870447484936"},"\u521a\u63d2\u4e0a\u7f51\u7ebf\uff0c\u7535\u8111\u600e\u4e48\u77e5\u9053\u81ea\u5df1\u7684IP\u662f\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147243567075819557"},"\u52a8\u56fe\u56fe\u89e3 | UDP\u5c31\u4e00\u5b9a\u6bd4TCP\u5feb\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126710506936598558"},"\u7528\u4e86TCP\u534f\u8bae\uff0c\u5c31\u4e00\u5b9a\u4e0d\u4f1a\u4e22\u5305\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nS1bMy2TejmGwEfCHPXy5A"},"HTTPS \u5c31\u4e00\u5b9a\u5b89\u5168\uff1f\u6211\u4e0d\u4fe1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fb2uUWz5ZjPEfYv_l6e4Zg"},"\u80fdping\u901a\uff0cTCP\u5c31\u4e00\u5b9a\u80fd\u8fde\u901a\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RJp9s_shNckkHBqHsJThuA"},"Linux \u662f\u5982\u4f55\u6536\u53d1\u7f51\u7edc\u5305\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7P_1VkBeoArKuuEqGcR9ig"},"\u5b57\u8282\u4e09\u9762\uff0c\u7b54\u7684\u4e0d\u6ee1\u610f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8CPWh_Ly61m8rkHvPT5n2g"},"\u4f53\u9a8c http3: \u57fa\u4e8e nginx quic \u5206\u652f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nRHlwYsr0MaadmaFWEIblQ"},"HTTP/3\u53d1\u5e03\u4e86\uff0c\u6211\u4eec\u6765\u8c08\u8c08HTTP/3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qmnfmUCdekEt1xG0hp_4MQ"},"\u65e2\u7136\u6709 HTTP \u534f\u8bae\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u6709 RPC")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3fMZN_LidCi5fiD16nNWWA"},"\u5b57\u8282\u4e00\u9762\uff1aTCP \u548c UDP \u53ef\u4ee5\u4f7f\u7528\u540c\u4e00\u4e2a\u7aef\u53e3\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg"},"\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hX75YxVOMtsnB6Sm_yjm0g"},"\u5b57\u8282\u4e00\u9762\uff1a\u5982\u4f55\u7528 UDP \u5b9e\u73b0\u53ef\u9760\u4f20\u8f93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw"},"TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904070889603085"},"(\u5efa\u8bae\u6536\u85cf)TCP\u534f\u8bae\u7075\u9b42\u4e4b\u95ee\uff0c\u5de9\u56fa\u4f60\u7684\u7f51\u8def\u5e95\u5c42\u57fa\u7840")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g"},"TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},"\u63a8\u8350\u770b\u770b QUIC 101 \u89c6\u9891\u4ee5\u53ca ",(0,n.kt)("a",{parentName:"li",href:"https://courses.cs.washington.edu/courses/cse550/20au/papers/CSE550.quic.pdf"},"The QUIC transport protocol: design and Internet-scale deployment")," \u8bba\u6587"),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000024523772"},"\u4e00\u6587\u5f7b\u5e95\u641e\u61c2\u52a0\u5bc6\u3001\u6570\u5b57\u7b7e\u540d\u548c\u6570\u5b57\u8bc1\u4e66\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944420222757503006"},"\u4e00\u4e2aResponse Header\u5f15\u53d1\u7684\u8840\u6848(\u5305\u542bCDN\u7684\u76f8\u5173\u6982\u5ff5)"))),(0,n.kt)("h2",{id:"\u64cd\u4f5c\u7cfb\u7edf"},"\u64cd\u4f5c\u7cfb\u7edf"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/jlevy/the-art-of-command-line"},"The Art of Command Line")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA"},"\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/94F4v1E9sB82lOr2DeSK0A"},"Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ev8hnv-coGLobrbezMK1og"},"Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZralWEfG2WJfZ-G-x9biow"},"\u770b\u5b8c\u8fd9\u7bc7\u4f60\u4e00\u5b9a\u80fd\u638c\u63e1Linux")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6938385978004340744"},"2\u4e07\u5b57\u7cfb\u7edf\u603b\u7ed3\uff0c\u5e26\u4f60\u5b9e\u73b0 Linux \u547d\u4ee4\u81ea\u7531")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6917096816118857736"},"6w\u5b57\u641e\u5b9aLinux\u57fa\u672c\u64cd\u4f5c\uff0c\u5efa\u8bae\u6536\u85cf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904080972709901"},"\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6875323565479034894"},"\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5"))),(0,n.kt)("h2",{id:"\u673a\u5668\u5b66\u4e60"},"\u673a\u5668\u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u672c\u5730\u8fd0\u884c Stable Diffusion \u9884\u8bad\u7ec3\u6a21\u578b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nDnQuZn3hVgrwqWVada2cw"},"AI\u6570\u5b57\u7ed8\u753b stable-diffusion \u4fdd\u59c6\u7ea7\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://lexica.art/?q=fc98f231-c95f-4a68-8727-899c73dbc486"},"https://lexica.art/?q=fc98f231-c95f-4a68-8727-899c73dbc486")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://huggingface.co/CompVis/stable-diffusion-v1-4"},"https://huggingface.co/CompVis/stable-diffusion-v1-4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/CompVis/stable-diffusion"},"https://github.com/CompVis/stable-diffusion")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://huggingface.co/blog/stable_diffusion"},"https://huggingface.co/blog/stable_diffusion")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146575333721341966"},"\u4e0d\u4f1a\u7b97\u6cd5\u4e5f\u80fd\u5fae\u8c03\u4e00\u4e2a NLP \u9884\u8bad\u7ec3\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BcXl8YQVNQA6auilbxW0kQ"},"\u4eba\u5de5\u795e\u7ecf\u7f51\u7edc\u7b97\u6cd5\u5165\u95e8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gaOzwCypQMFAJ4X50aUOcg"},"\u6d45\u6790\u795e\u7ecf\u7f51\u7edc Neural Networks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7075518863814869005"},"\u524d\u7aef\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u4f7f\u7528\u4e00\u4e2aNLP\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u6df1\u5165\u7406\u89e3 Transformer\uff1a",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1P4411F77q"},"https://www.bilibili.com/video/BV1P4411F77q")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Mt411J734"},"https://www.bilibili.com/video/BV1Mt411J734")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1cD4y1D7uR"},"\u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b- bilibili")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1mb4y1d7K7"},"\u300a\u8ba1\u7b97\u673a\u7f51\u7edc\u81ea\u9876\u5411\u4e0b\u65b9\u6cd5\u300b- bilibili"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u8fd9\u672c\u4e66\u91cd\u70b9\u7ae0\u8282\u662f\u7b2c2\u30013\u30014\u30015\u30016\u7ae0\uff0c\u5176\u4ed6\u7ae0\u8282\u53ef\u4ee5\u8df3\u8fc7"))),(0,n.kt)("li",{parentName:"ul"},"\u5b66\u4e60\u8d44\u6e90",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ossu/computer-science"},"https://github.com/ossu/computer-science")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/Snailclimb/JavaGuide"},"https://github.com/Snailclimb/JavaGuide")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/QSCTech/zju-icicles"},"https://github.com/QSCTech/zju-icicles")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Vt411z7wy"},"\u4e00\u5929\u5b66\u4f1a MySQL \u6570\u636e\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1FT4y1E74V"},"\u5434\u6069\u8fbe\u300a\u6df1\u5ea6\u5b66\u4e60\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1qK4y1479r"},"\u63a8\u8350\u7cfb\u7edf\u7b97\u6cd5\u57fa\u7840+\u7efc\u5408\u9879\u76ee\u5b9e\u6218"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u518d\u5c31\u662f\u4e00\u4e9b\u6211\u8ba4\u4e3a\u5f88\u4f18\u79c0\u7684\u5f00\u6e90\u9879\u76ee\uff1a"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/zhongqiangwu960812/AI-RecommenderSystem"},"https://github.com/zhongqiangwu960812/AI-RecommenderSystem")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ZiyaoGeng/Recommender-System-with-TF2.0"},"https://github.com/ZiyaoGeng/Recommender-System-with-TF2.0")))),(0,n.kt)("li",{parentName:"ul"},"\u53c2\u8003\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YbwQAPIEkihO7XzVvrlDCg"},"\u4e07\u5b57\u5165\u95e8\u63a8\u8350\u7cfb\u7edf\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7013674501116264484"},"\u8bf4\u4e00\u8bf4Web\u7aef\u4fa7AI")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6964335363787620383"},"\u673a\u5668\u5b66\u4e60\u521d\u63a2-\u7ebf\u6027\u56de\u5f52")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6951340421658181646"},"\u673a\u5668\u5b66\u4e60\u8fdb\u9636 - \u6df1\u5165\u601d\u8003\u903b\u8f91\u56de\u5f52"))),(0,n.kt)("h2",{id:"llm-\u6280\u672f\u8c03\u7814"},"LLM \u6280\u672f\u8c03\u7814"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Fo26NbtK8wFiHEGP0nhzuQ"},"\u4f7f\u7528 Transformers \u91cf\u5316 Meta AI LLaMA2 \u4e2d\u6587\u7248\u5927\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9cTNa_oya2Zj9YdDYodCvw"},"\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u4e2d\u6587\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NJ1JXkAK9LTSuor0mxtz1A"},"\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u5b98\u65b9\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iKtNOWkycm0FcMwnwq2M-A"},"AI \u52a0\u6301\u7684\u4ee3\u7801\u7f16\u5199\u5b9e\u6218\uff1a\u5feb\u901f\u5b9e\u73b0 Nginx \u914d\u7f6e\u683c\u5f0f\u5316\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/o-6Xg1f7SMX-BUFgXgwb8w"},"\u8ba9 OpenAI \u66f4 Open\uff0c\u5728 ChatGPT \u91cc\u81ea\u7531\u63a5\u5165\u6570\u636e\u6e90")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Qo1--bFCzdNHAdesshrUuQ"},"\u516b\u5341\u884c\u4ee3\u7801\u5b9e\u73b0\u5f00\u6e90\u7684 Midjourney\u3001Stable Diffusion \u201c\u5492\u8bed\u201d\u4f5c\u56fe\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vH5zkdQ9esiMeg3L9TYgvw"},"\u6a21\u578b\u6742\u8c08\uff1a1.5G \u663e\u5b58\u5c31\u80fd\u8fd0\u884c\u7684 RNN 14B \u7684\u5f00\u6e90\u6a21\u578b\uff08ChatRWKV\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cVR9yYP8zDiVBPEo91dSSA"},"\u4f7f\u7528 Docker \u548c Alpaca LoRA \u5bf9 LLaMA 65B \u5927\u6a21\u578b\u8fdb\u884c Fine-Tune")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6Ae6SgEws5gndQwmZqkcUg"},"\u57fa\u4e8e Docker \u7684\u6df1\u5ea6\u5b66\u4e60\u73af\u5883\uff1a\u5165\u95e8\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6oKORqZWX7IlQFI5zbLKCw"},"\u6a21\u578b\u6742\u8c08\uff1a\u4f7f\u7528 IN8 \u91cf\u5316\u63a8\u7406\u8fd0\u884c Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vc4t7sm-BhAYtE7_J8DekQ"},"\u6a21\u578b\u6742\u8c08\uff1a\u5feb\u901f\u4e0a\u624b\u5143\u5b87\u5b99\u5927\u5382 Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YKzWBa9kGbzwUpy2iuPjNA"},"RSS Can\uff1a\u501f\u52a9 V8 \u8ba9 Golang \u5e94\u7528\u5177\u5907\u52a8\u6001\u5316\u80fd\u529b\uff08\u4e8c\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UO6_L_oVe3-ocOyt6R_YTA"},"\u5728\u642d\u8f7d M1 \u53ca M2 \u82af\u7247 MacBook\u8bbe\u5907\u4e0a\u73a9 Stable Diffusion \u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_1AZ5U27JOkEaCUkAuZADQ"},"Linux \u8f6f\u4ef6\u5305\u4e0b\u8f7d\u52a0\u901f\u5de5\u5177\uff1aAPT Proxy")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/e0x7BR2PwkTk9JWdr2hg-w"},"\u8f7b\u91cf\u9ad8\u53ef\u7528\u7684 K8s \u96c6\u7fa4\u642d\u5efa\u65b9\u6848\uff1aMicroK8s")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8MppGs90WWP5sMlHFX2EUQ"},"\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f7f\u7528 Docker \u548c Milvus \u5feb\u901f\u6784\u5efa\u672c\u5730\u8f7b\u91cf\u56fe\u7247\u641c\u7d22\u5f15\u64ce")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pVYPpYRPjq7BUCahParVvw"},"\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u5165\u95e8\u5411\u91cf\u6570\u636e\u5e93 Milvus \u7684 Docker \u5de5\u5177\u955c\u50cf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/F0YgDChHceNoOPFstnBv3Q"},"\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f20\u7edf\u6587\u672c\u68c0\u7d22\u65b9\u5f0f\u7684\u964d\u7ef4\u6253\u51fb\uff0c\u4f7f\u7528 Faiss \u5b9e\u73b0\u5411\u91cf\u8bed\u4e49\u68c0\u7d22"))),(0,n.kt)("h2",{id:"java-\u76f8\u5173"},"Java \u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA"},"100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1Xe16FaHWfihYjqMVWidQg"},"\u539f\u521b\u7cbe\u9009\u835f\u8403\uff082022.05.11\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j1U4L06y2-8z2fSJypGG7w"},"\u652f\u4ed8\u5b9d\u4e00\u9762\uff1a\u5982\u4f55\u57fa\u4e8eRedis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/va75wKPBtpp2ceL25SkIVA"},"Jenkins+Docker \u5b9e\u73b0\u4e00\u952e\u81ea\u52a8\u5316\u90e8\u7f72\u9879\u76ee\uff01\u6b65\u9aa4\u9f50\u5168\uff0c\u5c11\u8d70\u5751\u8def\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/njeXqkHiIsXneBholN72OQ"},"\u4e24\u4e07\u5b57\u8be6\u89e3\uff01Netty\u7ecf\u517832\u8fde\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/409QGKe5H7tCP1qpCiY_KA"},"\u4e24\u4e07\u5b57\u76d8\u70b9\u8bbe\u8ba1\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J0C9TJF7nVVi2cMiDBqepA"},"\u5b9e\u6218\uff0c\u5b9e\u73b0\u5e42\u7b49\u76848\u79cd\u65b9\u6848\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Jct2rnz_0ahozWNZYfZ4Qg"},"\u5199\u4f18\u96c5\u4ee3\u7801\u768445\u4e2a\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PzZ31ju32-5epXpQeTZsNA"},"\u809d\u4e86\u4e00\u5468\u603b\u7ed3\u7684SpringBoot\u5e38\u7528\u6ce8\u89e3\u5927\u5168\uff0c\u770b\u5b8c\u5c31\u7089\u706b\u7eaf\u9752\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rSYOAuJeIXaonHvuR5O47Q"},"\u77a7\u77a7\u4eba\u5bb6\u5199\u7684API\u63a5\u53e3\u4ee3\u7801\uff0c\u90a3\u53eb\u4e00\u4e2a\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P017RfO8TDL5LxGzBoTLSA"},"SpringBoot \u5b9e\u73b0 Excel \u5bfc\u5165\u5bfc\u51fa\uff0c\u6027\u80fd\u7206\u8868\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SG9sNmMu9acB1xTODkG00Q"},"\u8fd8\u5728\u7528HttpUtil\uff1fSpringBoot 3.0\u5168\u65b0HTTP\u5ba2\u6237\u7aef\u5de5\u5177\u6765\u4e86\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ezLN8AzVhBaeMdNMK-TS-g"},"\u5999\u7528Java 8\u4e2d\u7684 Function\u63a5\u53e3\uff0c\u6d88\u706dif...else\uff08\u975e\u5e38\u65b0\u9896\u7684\u5199\u6cd5\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/20LjD3_nJYvZrTNo4tqjvA"},"\u522b\u518d\u7528 if \u6821\u9a8c\u53c2\u6570\u4e86\uff0c\u592aLow\uff01\u8fd9\u624d\u662f\u4e13\u4e1a\u7684 SpringBoot \u53c2\u6570\u6821\u9a8c\u65b9\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg"},"\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA"},"\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg"},"\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FX2umO7XCCmj8Bke7uKDZw"},"11\u79cd\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Va4eoL5xizJasnSUbvvccw"},"\u8fd9\u4e9b\u5e76\u53d1\u7f16\u7a0b\u77e5\u8bc6\uff0c\u4e00\u5b9a\u8981\u77e5\u9053")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EVgd689xdOX732hdOxPqcw"},"\u8fd910\u79cd\u795e\u7ea7\u6027\u80fd\u4f18\u5316\u624b\u6bb5\uff0c\u4f60\u7528\u8fc7\u51e0\u4e2a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VStQWv_ehN8RFDxpoAnKmg"},"\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ"},"MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/29xlEK2N_Wptl4TBMg1ZPQ"},"\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\u4e4b Spring IOC")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/T1toQ7NeHQKqof9A0o-99g"},"76 \u5f20\u56fe\uff0c\u5256\u6790 Spring AOP \u6e90\u7801\uff0c\u5c0f\u767d\u5c45\u7136\u4e5f\u80fd\u770b\u61c2\uff0c\u5927\u795e\uff0c\u8bf7\u6536\u4e0b\u6211\u7684\u819d\u76d6\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n8iw_33Wwr9i0mWEXMG6-A"},"\u4f7f\u7528 lambda \u5b9e\u73b0\u8d85\u5f3a\u7684\u6392\u5e8f\u529f\u80fd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/e_uJhaGj4HO1iTS_zCoCXw"},"\u4e07\u5b57\u957f\u6587\uff0cSpringSecurity\u5b9e\u73b0\u6743\u9650\u7cfb\u7edf\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J_11wYusexAjwa1cuckyfw"},"1.2w+\u5b57\uff01Java IO \u57fa\u7840\u77e5\u8bc6\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7js2uDZNv2Pb55ihKPc1xg"},"\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/djVu6SJjfYj4y_LNW-SKyw"},"\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\uff0cSpring \u5982\u4f55\u89e3\u51b3\u5faa\u73af\u4f9d\u8d56")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hhjwiMx-ypEbxwHJ9rJoBw"},"\u9ebb\u4e86\uff0c\u4ee3\u7801\u6539\u6210\u591a\u7ebf\u7a0b\uff0c\u7adf\u67099\u5927\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ioDYZjdSii3WUvL9xqc_Sg"},"\u522b\u518d\u4e71\u6253\u65e5\u5fd7\u4e86\uff0c\u8fd9\u4efd Java \u65e5\u5fd7\u89c4\u8303\uff0c\u5e94\u6709\u5c3d\u6709\uff0c\u5efa\u8bae\u6536\u85cf\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zn4TDT4Vl_MobqNkW1m-jw"},"\u804a\u804aSpringBoot\u5355\u5143\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4Sxal7N-uZ8gvphC8XWo8A"},"\u603b\u76d1\u53c8\u6765\u4e86\uff0c\u4eba\u72e0\u8bdd\u4e0d\u591a\uff0c\u8fd9\u7bc7 gRPC\uff0c\u5c0f\u5f1f\u4f69\u670d\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vqKKoPB5FQkCWXFWBLbkZg"},"\u817e\u8baf\u4e00\u9762\uff1aThread\u3001Runnable\u3001Callable\u3001Future\u3001FutureTask\uff0c\u8c08\u8c08\u4ed6\u4eec\u7684\u5173\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rlfRjCb8EOrpt3xnF7isBw"},"\u62dc\u6258\uff01\u9762\u8bd5\u8bf7\u4e0d\u8981\u518d\u95ee\u6211 @Transactional")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YcyC1Jm4H7uGvSg3rCkDig"},"7 \u6bb5\u5c0f\u4ee3\u7801\uff0c\u73a9\u8f6cJava\u7a0b\u5e8f\u5e38\u89c1\u7684\u5d29\u6e83\u573a\u666f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ua03qsLcrVURtxhSnuU_6w"},"\u5355\u4f8b\u6a21\u5f0f 4 \u79cd\u7ecf\u5178\u5b9e\u73b0\u65b9\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/mu_wind/article/details/118423362"},"ElasticSearch\u8fdb\u9636\uff1a\u4e00\u6587\u5168\u89c8\u5404\u79cdES\u67e5\u8be2\u5728Java\u4e2d\u7684\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031047868806873096"},"\u4f7f\u7528 @Transactional \u65f6\u5e38\u72af\u7684N\u79cd\u9519\u8bef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6984974277573836830"},"Spring Boot 2.x\u57fa\u7840\u6559\u7a0b\uff1a\u4f7f\u7528@Scheduled\u5b9e\u73b0\u5b9a\u65f6\u4efb\u52a1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007642025264676871"},"Spring Boot\u4e2d\u4f7f\u7528@Async\u5b9e\u73b0\u5f02\u6b65\u8c03\u7528\uff0c\u52a0\u901f\u4efb\u52a1\u7684\u6267\u884c\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/CodingDocs/awesome-idea"},"IDEA \u9ad8\u6548\u4f7f\u7528\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fuzhengwei/CodeGuide"},"CodeGuide | \u7a0b\u5e8f\u5458\u7f16\u7801\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fuzhengwei/small-spring"},"\ud83c\udf31 Spring \u624b\u64b8\u4e13\u680f - \u6613\u5b66\u3001\u597d\u5199\u3001\u80fd\u61c2\uff01"))),(0,n.kt)("h2",{id:"mysql-\u5b66\u4e60"},"MySQL \u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"MySQL \u4e13\u680f",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G8fWBvZPy6yxAyggwwx1NA"},"\u7530\u87ba\u54e5\u7684MySQL\u4e13\u680f\uff0125\u7bc7\uff0c\u771f\u9999\uff01")))),(0,n.kt)("li",{parentName:"ul"},"\u8868\u7ed3\u6784\u8bbe\u8ba1",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3yHSh7djpeeYZkajkTGFKg"},"\u63a8\u8350\u4e00\u6b3eSQL\u81ea\u52a8\u68c0\u67e5\u795e\u5668\uff0c\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3SQL\u51fa\u9519\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sSsZ-w6WzjA_DLZfnsxD2w"},"21\u4e2aMySQL\u8868\u8bbe\u8ba1\u7684\u7ecf\u9a8c\u51c6\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7136126923851169823"},"\u804a\u804a\u6570\u636e\u5e93\u5efa\u8868\u768415\u4e2a\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904142733836301"},"\u6211\u7528\u8d77\u6765\u987a\u624b\u7684\u6570\u636e\u5e93\u8bbe\u8ba1\u5de5\u5177\uff0c\u8fd9\u6b21\u63a8\u8350\u7ed9\u5927\u5bb6\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7108525565157589005"},"\u6570\u636e\u5e93\u8868\u7ed3\u6784\u8bbe\u8ba1\u4e00\u70b9\u5fc3\u5f97\u548c\u7ecf\u9a8c")))),(0,n.kt)("li",{parentName:"ul"},"\u6162 SQL \u4f18\u5316",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SBKlxcTK_kZf0s5CRtIEBA"},"SQL\u4f18\u531613\u8fde\u95ee\uff0c\u6536\u85cf\u597d\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Pi_SLqs3lwA7vWcT6lVv5g"},"\u7f8e\u56e2\u9762\u8bd5\uff1a\u8fd9\u4e2a SQL \u8bed\u53e5\u52a0\u4e86\u54ea\u4e9b\u9501")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8X-MuPgS-o53XZywqi_dmA"},"\u4e13\u5751\u540c\u4e8b\u7684SQL \u5c31\u8fd9\u4e48\u5199\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0_Arz-KO3UqJij1s4DjLNw"},"\u5b8c\u720690%\u7684\u6027\u80fd\u6bdb\u75c5\uff0c\u6570\u636e\u5e93\u4f18\u5316\u516b\u5927\u901a\u7528\u7edd\u62db\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3H9SD1dnAH0RoN-RoPXxgQ"},"\u516c\u53f8\u65b0\u6765\u4e2a\u540c\u4e8b\uff0cMyBatis\u6279\u91cf\u63d2\u516510w\u6761\u6570\u636e\u4ec5\u75282\u79d2\uff0c\u62cd\u6848\u53eb\u7edd\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OBjRKdGzwFM4PNrbMd7kIA"},"\u4e00\u6b21\u663e\u8457\u7684\u5927\u8868\u67e5\u8be2\u4f18\u5316\uff0c\u4ece20s\u4f18\u5316\u5230500ms\uff0c\u67e5\u8be2\u5206\u79bbYYDS\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UxZRGO58kTiX5wUnuzMJ9Q"},"MySQL\u8868\u592a\u5927\uff0ccount(*)\u90fd\u80fd 502\uff0c\u600e\u4e48\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/exPgSB0MNUnu0wMkThET1w"},"\u8fd915\u4e2aSQL\u4f18\u5316\u53e3\u8bc0\uff0c\u5de5\u4f5c\u9762\u8bd5\u90fd\u591f\u7528\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KegqAAvI4KxDffforTQqKA"},"\u4fdd\u59c6\u7ea7\u6559\u7a0b\uff012 \u4e07\u5b57 + 30 \u5f20\u56fe\u641e\u61c2 MySQL \u662f\u600e\u4e48\u52a0\u884c\u7ea7\u9501\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DZbAq9fpPxElhfJCkY53GA"},"\u4e24\u4e07\u5b57\u8be6\u89e3\uff01InnoDB\u9501\u4e13\u9898\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BbrLQWGYlkXiy6t4YANj0Q"},"SQL\u4f18\u5316\u601d\u8def+\u7ecf\u5178\u6848\u4f8b\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N3te_fVBeqhjIpl25N6kpA"},"MySQL \u5355\u8868\u4e0d\u8981\u8d85\u8fc7 2000W \u884c\uff0c\u9760\u8c31\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l3jJHIcqMzCcezbpboqyvQ"},"explain | \u7d22\u5f15\u4f18\u5316\u7684\u8fd9\u628a\u7edd\u4e16\u597d\u5251\uff0c\u4f60\u771f\u7684\u4f1a\u7528\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EVzU7KW9d5_254Kg4LZYQQ"},"MySQL \u4f18\u5316\uff1aExplain \u6267\u884c\u8ba1\u5212\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3jrf1GKBBbVzcvJxqYnx9Q"},"\u8fd911\u6761\u63a5\u53e3\u6027\u80fd\u4f18\u5316\u6280\u5de7\uff0c\u5229\u597d\u6bcf\u65e5\u7761\u7720")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Y1Mh-99cgQWuCQ53wAxkUQ"},"\u987a\u4e30\u5feb\u9012\uff1a\u8bf7\u7b7e\u6536MySQL\u7075\u9b42\u5341\u8fde")))),(0,n.kt)("li",{parentName:"ul"},"MySQL \u4e8b\u52a1",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pkJb_9mddmdYaJZ8azHSsg"},"\u56fe\u89e3MySQL\u4e8b\u52a1\u5e95\u5c42\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KEbuoasD_DOHRJiSqUgzzA"},"MySQL\u4e8b\u52a1\u768412\u8fde\u95ee\uff0c\u4f60\u9876\u5f97\u4e86\u561b")))),(0,n.kt)("li",{parentName:"ul"},"MySQL \u7d22\u5f15",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d3iC_Iokrjdn392I0Y53Og"},"MySQL\u7d22\u5f1515\u8fde\u95ee\uff0c\u6297\u4f4f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sqW51yqeAXcDs9r84UFP7A"},"\u8ddf\u5927\u5bb6\u804a\u804a MySQL \u4e00\u884c\u8bb0\u5f55\u662f\u600e\u4e48\u5b58\u50a8\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yvgB1a2o-m3_EBLePZM8cw"},"\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u53ebB+\u6811")))),(0,n.kt)("li",{parentName:"ul"},"MySQL \u65e5\u5fd7",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Tfbd-KiBgsZtkiuVc70BFA"},"\u804a\u804a MySQL \u65e5\u5fd7\uff0c\u597d\u725b\u7684\u8bbe\u8ba1\uff01")))),(0,n.kt)("li",{parentName:"ul"},"\u5206\u5e93\u5206\u8868",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cZ7mUsCvBxmo1dzsPA3WjQ"},"\u5206\u5e93\u5206\u8868\u7ecf\u517815\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AjVl-0u3plmL9U77h0VVJw"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u5206\u5e93\u5206\u8868\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wYXs7gsID8a9ahJKsWXJ6w"},"\u518d\u6709\u4eba\u95ee\u4f60\u4ec0\u4e48\u662f\u5206\u5e93\u5206\u8868\uff0c\u76f4\u63a5\u628a\u8fd9\u7bc7\u6587\u7ae0\u53d1\u7ed9\u4ed6")))),(0,n.kt)("li",{parentName:"ul"},"\u810f\u8bfb\u3001\u4e0d\u53ef\u91cd\u590d\u8bfb\u3001\u5e7b\u8bfb",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VWEKgnOWVnufz5pfvRjUWw"},"\u7f8e\u56e2\u4e09\u9762\uff1a\u4e00\u76f4\u8ffd\u95ee\u6211\uff0c MySQL \u5e7b\u8bfb\u88ab\u5f7b\u5e95\u89e3\u51b3\u4e86\u5417")))),(0,n.kt)("li",{parentName:"ul"},"\u6570\u636e\u4e00\u81f4\u6027",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VEU5p85aTvyBKf2XP5QTSg"},"\u6570\u636e\u5e93\u9501\u768412\u8fde\u95ee\uff0c\u6297\u4f4f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/shogIDEgXTtPVPFgsS8crw"},"\u804a\u804aselect for update\u5230\u5e95\u52a0\u4e86\u4ec0\u4e48\u9501")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw"},"\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lyqvv-nA_PMUc-eBuCsNTA"},"\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg"},"\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7104507830522085383"},"\u804a\u804a\u5206\u5e03\u5f0f\u9501")))),(0,n.kt)("li",{parentName:"ul"},"ORM \u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R2yqW3kfesK-T5oZR2Vl2w"},"MyBatis \u8fde\u73af 20 \u95ee\uff0c\u4f60\u80fd\u7b54\u5bf9\u51e0\u4e2a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ"},"MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6850037271233331208"},"MySQL \u4e09\u4e07\u5b57\u7cbe\u534e\u603b\u7ed3 + \u9762\u8bd5100 \u95ee\uff0c\u548c\u9762\u8bd5\u5b98\u626f\u76ae\u7ef0\u7ef0\u6709\u4f59\uff08\u6536\u85cf\u7cfb\u5217\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vRI-bFB4_IEaoCCQcMqZjw"},"\u660e\u660e\u52a0\u4e86\u552f\u4e00\u7d22\u5f15\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u662f\u4ea7\u751f\u91cd\u590d\u6570\u636e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/O6sgYSpXBPwAA4Qcstj-BA"},"\u4e92\u8054\u7f51\u516c\u53f8\u90fd\u600e\u4e48\u5b9e\u73b0\u5206\u9875\u7684\uff0c\u62ff MySQL \u4f7f\u52b2Limit")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cdc1NCSkvAU4Urk2wVFDMw"},"MySQL\u593a\u547d66\u95ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/L9qseWiHGfu1oAuKIhcUhw"},"\u4e00\u6b21 MySQL \u8bef\u64cd\u4f5c\u5bfc\u81f4\u7684\u4e8b\u6545\uff0c\u300c\u9ad8\u53ef\u7528\u300d\u90fd\u9876\u4e0d\u4f4f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Inocu3vjMG4ivE19HrxR3g"},"\u867e\u76ae\u4e8c\u9762\uff1aMySQL \u4e2d\u6709\u54ea\u4e9b\u9501\uff1f\u8868\u7ea7\u9501\u548c\u884c\u7ea7\u9501\u6709\u4ec0\u4e48\u533a\u522b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Jhh-_5ynu58EKPMignk5fA"},"\u9762\u9738\u7bc7\uff1aMySQL\u516d\u5341\u516d\u95ee\uff0c\u4e24\u4e07\u5b57+\u4e94\u5341\u56fe\u8be6\u89e3\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101581835527782414"},"\u6162SQL\u5206\u6790\u4e0e\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r91hINCgCYJDNHLMeaba8Q"},"Mysql\u6570\u636e\u5e93\u67e5\u8be2\u597d\u6162\uff0c\u9664\u4e86\u7d22\u5f15\uff0c\u8fd8\u80fd\u56e0\u4e3a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8OOSyFB9pzoBMH73ey7YmQ"},"MySQL \u4e3b\u4ece\uff0c6 \u5206\u949f\u5e26\u4f60\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N08tFkGyXtmBSN0nS6S6UA"},"\u5927\u5382\u9762\u8bd5\u9898\uff1a\u65e5\u5e38\u5de5\u4f5c\u5982\u4f55\u505aMySQL\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i8SHizPrBMQ2GIhQP7ozRw"},"Mysql\u5b8c\u7ed3\u6c47\u603b\u7bc7\uff0818W\u5b57\u9001\u7ed9\u5927\u5bb6\uff09\uff0c\u5b8c\u7ed3\u6492\u82b1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7081456994413969445"},"\u9762\u8bd5\u5b98\uff1a\u4ec0\u4e48\u662fMySQL \u4e8b\u52a1\u4e0e MVCC \u539f\u7406\uff1f"))),(0,n.kt)("h2",{id:"golang-\u5b66\u4e60"},"Golang \u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Golang \u5b66\u4e60\u8def\u7ebf",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/xiaobaiTech/golangFamily/blob/main/README.md"},"Go\u540e\u7aef\u5f00\u53d1\u6210\u957f\u8def\u7ebf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7119123646471208968"},"\u300aGo\u5b66\u4e60\u8def\u7ebf\u56fe\u300b\u5e26\u4f60\u5c11\u8d70\u5f2f\u8def\uff0cLet's Go \uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7176518080674136121"},"\u6700\u5168\u7684Go\u8d44\u6599\u6c47\u603b\u548c\u6700\u8d70\u5fc3\u7684\u5b66Go\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147939014870302756"},"\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7035966042857799687"},"\u6211\u809d\u4e86\u4e09\u4e2a\u6708\uff0c\u4e3a\u4f60\u5199\u51fa\u4e86GO\u6838\u5fc3\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7061980386640789540"},"Go \u5b66\u4e60\u8def\u7ebf\uff082022\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV16E411H7og"},"Golang\u5b66\u4e60\u624b\u518c\u4e4b\uff1a\u5e26\u4f6021\u5468\u641e\u5b9aGo\u8bed\u8a00")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=YS4e4q9oBaU"},"Learn Go Programming - Golang Tutorial for Beginners")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u8fdb\u9636",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/danielfurman/presentations/blob/master/lets-go-generic/README.md"},"Golang \u6cdb\u578b\u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1ry4y1y7V2"},"GopherCon UK 2018- Florin Patan - Production Ready Go Service in 30 Minutes")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r4IWY6bzKph2QvxrKZszPA"},"\u4f5c\u4e3aGopher\uff0c\u4f60\u77e5\u9053Go\u7684\u6ce8\u91ca\u5373\u6587\u6863\u5e94\u8be5\u600e\u4e48\u5199\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ne0uir1hpMokBUItntkfvw"},"31\u4e2a\uff01Golang\u5e38\u7528\u5de5\u5177\u6765\u5566\uff08\u5efa\u8bae\u6536\u85cf\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Mj-EqwYWZBMr8XNIHxUqDA"},"Golang\u4f9d\u8d56\u6ce8\u5165\u63d0\u5347\u5f00\u53d1\u6548\u7387\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VFS4TWi3OpeAegScZ4cJRw"},"Go\u8bed\u8a00\u4ece0\u52301\u5b9e\u73b0\u6700\u7b80\u5355\u7684\u6570\u636e\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/--ciEa-Oj0NEUxlp1Af_aQ"},"\u5fc5\u64b8\u7cfb\u5217\uff01Go\u53e6\u5916\u51e0\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7\u6c47\u603b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8HNZQrQ2oqMB2fAYbmH2Ow"},"\u6765\u4e86\uff01Go\u76842\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Zb5zGOy_mdalUQ_Qy0HngQ"},"3\u79cd\u65b9\u5f0f\uff01Go Error\u5904\u7406\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OCpVRwtiphFRZgu9zdae5g"},"Go\u7ec4\u4ef6\uff1acontext\u5b66\u4e60\u7b14\u8bb0\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NkSyv7iDSZsLhMUgAi-r4w"},"\u4e0d\u5f97\u4e0d\u77e5\u9053\u7684Golang\u4e4bsync.Map\u89e3\u8bfb\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XHbfPtUzkUTGF06Ao4jQYA"},"\u8d85\u5168\u907f\u5751\u6307\u5357: \u76d8\u70b9 Go \u7684\u5e38\u89c1\u5178\u578b\u9519\u8bef")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/56tth8PSquB1eR5-1XaDWA"},"\u9e45\u5382\u540e\u53f0\u5927\u4f6c\u6559\u4f60Go\u5185\u5b58\u7ba1\u7406\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QBZ1dp0XIqMo24vVFYf1fA"},"\u5168\u9762\u89e3\u8bfb\uff01Golang\u4e2d\u6cdb\u578b\u7684\u4f7f\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/niLk_n9Yp-iyl_RIie3Umw"},"\u8d85\u5e72\u8d27\uff01\u5f7b\u5e95\u641e\u61c2Golang\u5185\u5b58\u7ba1\u7406\u548c\u5783\u573e\u56de\u6536")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BPcRI0BHBLmuYfzvP10Wvw"},"\u5173\u4e8eGo\u5e76\u53d1\u7f16\u7a0b\uff0c\u4f60\u4e0d\u5f97\u4e0d\u77e5\u7684\u201c\u5de6\u8180\u53f3\u81c2\u201d\u2014\u2014\u5e76\u53d1\u4e0e\u901a\u9053\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aoR_69JMBN5ZM10DKqRCyQ"},"\u5b83\u6765\u4e86\uff0c\u5173\u4e8eGolang\u5e76\u53d1\u7f16\u7a0b\u7684\u8d85\u8be6\u7ec6\u6559\u7a0b\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/POZGQXsYu5aWXvu29vSM8g"},"\u901a\u4fd7\u6613\u61c2\uff01\u56fe\u89e3Go\u534f\u7a0b\u539f\u7406\u53ca\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DpCFUAYpvMzd6138Yp_JUA"},"\u62d2\u7edd\u5343\u7bc7\u4e00\u5f8b\uff0c\u8fd9\u5957Go\u9519\u8bef\u5904\u7406\u7684\u5b8c\u6574\u89e3\u51b3\u65b9\u6848\u503c\u5f97\u4e00\u770b\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_VGaV8ef65h9goxxfWejtQ"},"go\u8bed\u8a00\u6700\u5168\u4f18\u5316\u6280\u5de7\u603b\u7ed3\uff0c\u503c\u5f97\u6536\u85cf\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fXKSr8GXaYxG1WCrLIgneg"},"\u518d\u4e0dGo\u5c31\u6765\u4e0d\u53ca\u4e86\uff01Go\u9ad8\u6027\u80fd\u7f16\u7a0b\u6280\u6cd5\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XrJVpErmP8wIjd_byCCmhA"},"\u817e\u8baf 13 \u5e74\uff0c\u6211\u6240\u603b\u7ed3\u7684Code Review\u7ec8\u6781\u5927\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AMv5IVBPU2lAY_qUwskk4g"},"Go\u4e0eC\u7684\u6865\u6881\uff1aCGO\u5165\u95e8\u5256\u6790\u4e0e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tN27osC6K0NM-Laj9MbtsA"},"Golang \u6c47\u7f16\u5165\u95e8\u77e5\u8bc6\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VMzhyySny60zABnxlzlVjQ"},"Golang\u9ad8\u6027\u80fd\u7f16\u7a0b\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GwXQwJUdBi1UHdh2Q8FBMw"},"\u6572\u9ed1\u677f\uff01\u9e45\u5382\u7a0b\u5e8f\u5458\u9762\u8bd5\u4e5f\u8003\u4e86\u8fd9\u4e9b\u7b97\u6cd5\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JkpzM06IWNb11wUaJWJn8Q"},"Java\u4e0eGo\u5230\u5e95\u5dee\u522b\u5728\u54ea\uff0c\u8c01\u8981\u88ab\u65f6\u4ee3\u629b\u5f03")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/T4tk-sckA1oNcWIvp27MMA"},"\u770b\u4e86\u8fd9\u7bc7\u4f60\u4f1a\u53d1\u73b0\uff0c\u4f60\u662f\u61c2Go\u5185\u5b58\u5206\u914d\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SLouDICt3HABv_wh-sSqKw"},"Go \u5b9e\u6218\u6280\u5de7\uff1a\u907f\u514d\u5185\u5b58\u5206\u914d\u7684\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aIuta8Lr0govruPTgglw2w"},"\u901a\u8fc7\u4e00\u4e2a\u4f8b\u5b50\u8ba9\u4f60\u5f7b\u5e95\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_duDs0oHc_z_p--3OoIfVw"},"Go\u7684\u65b9\u6cd5\u63a5\u6536\u8005\uff1a\u503c\u63a5\u6536\u8005\u4e0e\u6307\u9488\u63a5\u6536\u8005")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157594175846744071"},"\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/94thx36Ao2PYQ-8Cbto-wQ"},"\u7a0b\u5e8f\u5458\u5e94\u8be5\u9075\u5b88\u7684\u7f16\u7a0b\u539f\u5219(\u4e0d\u6b62Gopher\u54e6)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ"},"\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UqjSA2i3s1VoLFACt_EL2A"},"Go 1.18\u65b0\u7279\u6027\u524d\u77bb\uff1a\u539f\u751f\u652f\u6301Fuzzing\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PBTP4vnwEXtrtsHdq0oL0g"},"\u5982\u4f55\u5e94\u5bf9\u4e0d\u65ad\u81a8\u80c0\u7684\u63a5\u53e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pCcNtUykXAwb-BN_prPGpA"},"\u6bcf\u4e2a gopher \u90fd\u9700\u8981\u4e86\u89e3\u7684 Go AST")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xzNqpRbIvoJygSWeQJFjTw"},"\u4e00\u6587\u641e\u61c2Go\u6807\u51c6\u5e93context\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/E4lT4SuWKIlCZd60i7vigQ"},"\u4f7f\u7528\u53cd\u5c04\u64cd\u4f5cchannel")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/z75HDSlX0PLCnvL5kAcSDw"},"Go 1.20\u65b0\u7279\u6027\u524d\u77bb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg"},"Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MRBEJHZBMS9s0w7UhseQWA"},"2022\u5e74Go\u8bed\u8a00\u76d8\u70b9\uff1a\u6cdb\u578b\u843d\u5730\uff0c\u65e0\u8da3\u5f88\u597d\uff0c\u7a33\u5b9a\u4e3a\u738b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HbFVODpDEzEZ047kv-LYbg"},"Go1.20 \u65b0\u7279\u6027\uff1acontext\u652f\u6301\u81ea\u5b9a\u4e49\u53d6\u6d88\u539f\u56e0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NtBzM8l54HRVSpapKR_0sg"},"\u804a\u804aGo\u4e0eTLS 1.3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CFwiFw00ah0rfdZyv_ppxw"},"\u5c06Roaring Bitmap\u5e8f\u5217\u5316\u4e3aJSON")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Y-JxePxv9XlaX_UASlWSvQ"},"\u4e07\u5b57\u957f\u6587\u544a\u8bc9\u4f60Go 1.20\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6_ygmyd64LP7rlkrOh-kRQ"},"\u4e00\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u5224\u65adGo\u63a5\u53e3\u53d8\u91cf\u662f\u5426\u76f8\u7b49")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WDw-Y8Rp4VxAa2iPKRnKKg"},"\u5c0f\u5382\u5185\u90e8\u79c1\u6709Go module\u62c9\u53d6\u65b9\u68483")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r5gIVtyBWtD7UQncK_JPNQ"},"Go\u662f\u4e00\u95e8\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8bed\u8a00\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5zoNwCWnNNunrDtu6cokqg"},"\u4e00\u6587\u641e\u61c2Go subtest")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ypK-2wGHGj9_n4o8y-clXg"},"\u804a\u804agodoc\u3001go doc\u4e0epkgsite")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MI9x4YOAhbtS-xQtOS-K_A"},"\u804a\u804aGo\u8bed\u8a00\u7684\u5168\u5c40\u53d8\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8yLt0Sh18VF5ApTcuxV-Sg"},"Go\u5f00\u53d1\u547d\u4ee4\u884c\u7a0b\u5e8f\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RKshV1hu61wabq4am906PA"},"\u4f7f\u7528go test\u6846\u67b6\u9a71\u52a8\u7684\u81ea\u52a8\u5316\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0TnAPFib82KC-BIL-uhMWw"},"\u4e00\u6587\u544a\u8bc9\u4f60\u54ea\u4e9bmap element\u7c7b\u578b\u652f\u6301\u5c31\u5730\u66f4\u65b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EHSR-GFPJy5RzVDgcvoTog"},"\u7406\u89e3unsafe-assume-no-moving-gc\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PwSJQM7WmJeLnDDbCr78hg"},"Go 1.21\u65b0\u7279\u6027\u524d\u77bb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FcuXy0Vqp6aczKpNpQeFrA"},"Go\uff1a\u503c\u4e0e\u6307\u9488")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IEsgLu5PFwcKppUWABA6-Q"},"Go\u9879\u76ee\u7ec4\u7ec7\uff1a\u5728\u5355\u4e00repo\u4e2d\u7ba1\u7406\u591a\u4e2aGo module\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/D_CVrPzjP3O81EpFqLoynQ"},"\u4e00\u6587\u641e\u61c2Go\u9519\u8bef\u94fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/18SbYmKnUbNR59gFlKEULQ"},"Go\u4e0e\u795e\u7ecf\u7f51\u7edc\uff1a\u5f20\u91cf\u8fd0\u7b97")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2P9_nyrdZ3JqlKRIR8--7g"},"\u804a\u804aGo\u8bed\u8a00\u7684\u63a7\u5236\u8bed\u53e5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J3hIbUaAp55l8QDuJYUQOg"},"Go\u8bed\u8a00\u53cd\u5c04\u7f16\u7a0b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-EAH8jjj4uy1LCr_9C1ghg"},"The State Of Go 2023")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_xA6bhKTm543i3QV8EZMSg"},"Go\u8bed\u8a00\u5305\u8bbe\u8ba1\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dyQ3WBMPF2DyaI8Dlgy8Gw"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u7c7b\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JWg8yW_lDiZQCk6bKZ5TeA"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u5185\u5b58\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WgeTzhP4T0AAjFssHz36UA"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Lxxfeqn70rfmnrGvgrxevA"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u64cd\u4f5c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xBpA36wpmbO85LIHlaTXBg"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6269\u5c55compute\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LppX2mvbkgsLKkqqudehQA"},"\u4f7f\u7528testify\u5305\u8f85\u52a9Go\u6d4b\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PcNpQJcKuWpZgYrKmVvRLQ"},"Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u8bfb\u5199Parquet\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4UI6gTx7ZWRPhGbm4YGGCQ"},"Gopher Daily\u6539\u7248\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZaDNxyewtrSuiLRF62ipYg"},"Go\u9879\u76ee\u521d\u59cb\u5316\u4e0d\u518d\u56f0\u6270\u4f60\uff1agonew\u5168\u65b9\u4f4d\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3bfD9LPBB5zA9VxAv920Cw"},"Go 1.21\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/snVLySXv4E5xMlbD153FcQ"},"\u7f16\u8bd1Go\u5e94\u7528\u7684\u9ed1\u76d2\u6311\u6218\uff1a\u65e0\u6e90\u7801\u53ea\u6709.a\u6587\u4ef6\uff0c\u4f60\u80fd\u641e\u5b9a\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4HN0-m8AlzSmDCuF9hYU4Q"},"slog\u6b63\u5f0f\u7248\u6765\u4e86\uff1aGo\u65e5\u5fd7\u8bb0\u5f55\u65b0\u9009\u62e9\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7jS6E6d578QQIxvWKSux1Q"},"slog\u5b9e\u6218\uff1a\u6587\u4ef6\u65e5\u5fd7\u3001\u8f6e\u8f6c\u4e0ekafka\u96c6\u6210")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NzUXgDd7qPMK4LxIopcFLA"},"\u804a\u804aGo\u8bed\u8a00\u7684\u5411\u524d\u517c\u5bb9\u6027\u548ctoolchain\u89c4\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vY76-34hm-ujgaGTS_lDaQ"},"\u4f7f\u7528Go\u548cWebRTC data channel\u5b9e\u73b0\u7aef\u5230\u7aef\u5b9e\u65f6\u901a\u4fe1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2ibzE46UVnO_YNtugikpPQ"},"\u4e86\u89e3go\u5728\u534f\u7a0b\u8c03\u5ea6\u4e0a\u7684\u6539\u8fdb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J3Sfo9u63aTG6IndFP-BnQ"},"\u4e00\u7ad9\u5f0fGolang\u5185\u5b58\u6d17\u9ad3\u7ecf","[","Go\u4e09\u5173\u5178\u85cf\u7248","]")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9MfIdUdBZmfqbUYT_xrB8A"},"\u6df1\u5165\u7406\u89e3Golang\u534f\u7a0b\u8c03\u5ea6GPM","[","Go\u4e09\u5173\u5178\u85cf\u7248","]")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/up1MHqYW_v_C4P6AY-sW3w"},"Golang\u4e09\u8272\u6807\u8bb0\u6df7\u5408\u5199\u5c4f\u969cGC\u6a21\u5f0f\u5168\u5206\u6790","[","Go\u4e09\u5173\u5178\u85cf\u7248","]")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/veu5W0BFmLIZ-yvs39NdUw"},"\u4e3a\u4ec0\u4e48\u6cdb\u578b\u4f7f\u4f60\u7684\u7a0b\u5e8f\u53d8\u6162")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XojOIIZfKm_wXul9eSU1tQ"},"Go error \u5904\u7406\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mrAwE-go0vNSwrJ4g4L9Cg"},"\u5f00\u901a\u4e2a\u4eba\u535a\u5ba2\u5566\uff01\u9644\u5e26\u5168\u90e8 Hexo + Nginx + Git \u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gMjQmNvEi1o_iOFt2z7flg"},"\u975e\u5e7f\u544a| DDD \u5230\u5e95\u662f\u94f6\u5f39\u8fd8\u662f\u5783\u573e")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yEbqNo9UfPTCxL5-RDvlPw"},"\u7ed9\u9762\u8bd5\u5b98\u4e00\u70b9\u5c0f\u5c0f\u7684 gpt \u9707\u64bc")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AaHk-yg8D4atbO-zVAvhKQ"},"Go \u8bed\u8a00 GC \u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XR1KAeCW930i-Qxv6N2kaA"},"\u52a8\u6001\u8c03\u6574 GOGC \u4f18\u5316 Go \u7684 GC \u6807\u8bb0 CPU \u5360\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/T7IBCimzmWI07dHD8NA-Qw"},"\u804a\u804a rust trait")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/A4m1xlFwh9pD0qy3p7ItSA"},"Gopher \u9700\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7ed3\u6784\u4f53\u9a9a\u64cd\u4f5c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sYQ0vqKiIWaUCha740Dxtw"},"Go \u670d\u52a1\u7aef\u5f00\u53d1\uff0c\u8bf7\u7262\u8bb0\u8fd9\u51e0\u6761")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8xTtSoLvAcE1u_jWw9I-Eg"},"\u503c\u5f97\u6536\u85cf\u8c03\u5ea6\u5668\u7cfb\u5217\uff1a\u5077\u5929\u6362\u65e5 \u2014 g0 \u6808\u548c\u7528\u6237\u6808\u5982\u4f55\u5b8c\u6210\u5207\u6362\uff1f\uff08\u56db\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5E5V56wazp5gs9lrLvtopA"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff081\uff09\u2014\u2014\u8c03\u5ea6\u7684\u672c\u8d28")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WWfm7Ui7g_gGlb8XkIZigg"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff082\uff09\u2014\u2014 \u8ff7\u60d1\u7684 goroutine \u6267\u884c\u987a\u5e8f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2Y3qPkysRLaWDcIyLOerZg"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff083\uff09\u2014\u2014 \u5982\u4f55\u7528\u6c47\u7f16\u6253\u540c\u4e8b\u7684\u8138")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8R9ZLa0Xlscw6qhl-5g2Cg"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0810\uff09\u2014\u2014 \u5982\u4f55\u7ed9 Go \u63d0\u6027\u80fd\u4f18\u5316\u7684 pr")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SGv5vuh9aU2mqViC4Kj0YQ"},"\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0811\uff09\u2014\u2014 \u4ece map \u7684 extra \u5b57\u6bb5\u8c08\u8d77")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RmEtL869Sd-FjB_73tFSaw"},"\u300e\u66f9\u5927\u5e26\u6211\u5b66 Go \u300f\u7cfb\u5217\u6587\u7ae0\u6c47\u603b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IEunJaXMfrOfPmounloYig"},"Go map \u7adf\u7136\u4e5f\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ujWkFUqJiY3DCWeKZeS8uw"},"\u5185\u8054\u51fd\u6570\u548c\u7f16\u8bd1\u5668\u5bf9Go\u4ee3\u7801\u7684\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VnF7YrXTaK5MASacXgzRhw"},"\u6df1\u5ea6\u9605\u8bfb\u4e4b\u300a100 Go Mistakes and How to Avoid Them\u300b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/U5Okkf9FzLxxSYcsUI2DZg"},"kafka producer \u5728 aws \u53c8\u6302\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Bl3UrbgiMMsP3gxm6vnDtA"},"\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e00)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j59HejHj5hzKovfsGdrIdg"},"\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e8c)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UIeIBtC9MZJh3w-EphWHiA"},"Gopher \u5e94\u8be5\u8bb0\u4f4f\u8fd9 10 \u4e2a\u547d\u4ee4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HPzoclfCB3UxLScXm4J83w"},"\u6709\u8da3\u7684 Go HttpClient \u8d85\u65f6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2V3VSsAJH5haWqdvVJ9e8g"},"\u6211\u5982\u4f55\u7528\u4e24\u884c\u4ee3\u7801\u8282\u7701\u4e8630%\u7684CPU")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YzkPHkBCdqv-Z3APSPaDrQ"},"Go 1.19 \u4e2datomic\u5305\u7684\u65b0\u53d8\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EIuM073G7VV1rIsnTXWyEw"},"\u7b49\u7b49\uff0c \u600e\u4e48\u4f7f\u7528 SetMemoryLimit")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sSwXgrHvQcjSuiy9bA8d_g"},"\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/S4FDRve0YPtRUixY4kPqAQ"},"\u554a\u54c8\uff0c\u4e00\u9053\u6709\u8da3\u7684Go\u5e76\u53d1\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VtDR2uJ8SQ2jiIS2o2uyfA"},"\u8fd8\u548b\u4f18\u5316\uff1f\u6211\u662f\u8bf4Go\u7a0b\u5e8f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/chPDWyBibBlvcEKKENFYGg"},"\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e00\u7bc7\uff1a\u7efc\u8ff0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hXfZImBUYTBe2JvhBD-OmA"},"\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e8c\u7bc7\uff1aGo\u8bed\u8a00\u4e2d\u7684\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EAk_LdlfYGwaiDDj9CgqHA"},"\u4e00\u4e9b\u5173\u4e8e\u65f6\u95f4\u548c\u5b9a\u65f6\u4efb\u52a1\u7684\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kSZieI3zE9RgvfAqEQEhbw"},"\u6ca1\u7528\u5fae\u670d\u52a1\uff0cShopify\u7684\u5355\u4f53\u7a0b\u5e8f\u5c45\u7136\u652f\u6491\u4e86127\u4e07/\u79d2\u7684\u8bf7\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8omJxT10c5UX6Neua9dLjA"},"\u673a\u667a\uff01\u751f\u62a0\u5185\u5efamap\u7684\u54c8\u5e0c\u51fd\u6570")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KTmMWyULYMS0LFsg69zwZg"},"\u50cf\u95ea\u7535\u4e00\u6837\u5feb\u901f\u626b\u63cf\u5168\u7f51\u7684IP\u5730\u5740")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KzMmzd2ZfAJwtHt4s-V0zQ"},"\u6bcf\u79d2\u767e\u4e07\u7ea7\u522b\u7684\u5305\u4f20\u8f93\uff0c\u6211\u662f\u8bf4CPU\u4f7f\u7528\u7387\u51e0\u4e4e\u4e3a\u96f6\u90a3\u79cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sVLOFBdL6a_1pOBFP8pSfw"},"\u4f7f\u7528\u5e95\u5c42\u7684syscall.Socket\u5b9e\u73b0\u7f51\u7edc\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uwdL6QjLIG6SbMKeb2HOAw"},"\u4f7f\u7528Go\u8bed\u8a00\u5b9e\u73b0ping\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1Nv5_b2jM9uiG0tEu1Pr1A"},"\u51e0\u79cd\u4f7f\u7528Go\u53d1\u9001IP\u5305\u7684\u65b9\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/C2AmKZjg9CyiIDxyU0-b1Q"},"\u600e\u4e48\u963b\u6b62\u4e00\u4e2aGo\u7a0b\u5e8f\u9000\u51fa")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SFXe1bdBu0bLuHoGEFTz8g"},"Go 1.21\u4e2d sync.Once\u7684\u65b0\u6269\u5c55")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mKraN_3xUfy6Bm-SswHEbw"},"\u6539\u9020! \u8ba9 sync.Map \u652f\u6301\u6cdb\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/26PlfCFLc9Giuv_7nmgxjg"},"\u4e00\u4e2a\u6cdb\u578b\u7684\u6709\u5e8fGo Map\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aC7omLYJ6Anm9f-8b4qYAg"},"MPTCP: \u4e00\u4e2a\u5728 Go 1.21\u4e2d\u7684\u88ab\u5ffd\u7565\u7684\u65b0\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Sv-SXDYxea_K_TtiI_CjTw"},"Go\u53ef\u4ee5\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f46\u7edd\u4e0d\u662f\u300a\u8bbe\u8ba1\u6a21\u5f0f\u300b\u4e2d\u7684\u90a3\u6837")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/325iHPhAQicbSN6-pb05rw"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5de5\u5382\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jXaCLkagT-cKbVHConcadg"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5efa\u9020\u8005\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NQOmlQfFpM-asN9I9CeVkw"},"\u5355\u4f8b\u6a21\u5f0f\u548c\u60f0\u6027\u521d\u59cb\u5316\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R1bPyZBMWizcfuwQv0-t8Q"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u539f\u578b\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/p5lv_yTUbxsNYDmZiIpGTw"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5bf9\u8c61\u6c60\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zVVl_R0WbP6AUcav5ys6tQ"},"\u539f\u578b\u6a21\u5f0f\u8865\u9057 - Go\u8bed\u8a00\u4e2d\u7684\u6df1\u5ea6\u62f7\u8d1d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KYlY-WFNpYirvcRiyaeVXw"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u9002\u914d\u5668\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MiACdPNOhnXRoysRX2VBVA"},"\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u8d44\u6e90\u83b7\u53d6\u5373\u521d\u59cb\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hgFvoopT7DZoGUqHiurTeQ"},"Go 1.21 \u4e2d\u7684\u6cdb\u578b\u63a8\u65ad")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1cIcrObMP5xG_UsMUatETw"},"mping: \u4f7f\u7528\u65b0\u7684icmp\u5e93\u5b9e\u73b0\u63a2\u6d4b\u548c\u538b\u6d4b\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SSkt6YYGcqgH9kbIQH-tNg"},"PGO: \u4e3a\u4f60\u7684Go\u7a0b\u5e8f\u63d0\u65485%")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/M0WFAQtoCd1aEZHjxTyjMw"},"\u6df1\u5165\u7406\u89e3 PromQL")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5XMmVqdcji8jpRnC2p0F3w"},"\u4ec0\u4e48\u662f Go runtime.KeepAlive")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gc34RYqmzeMndEJ1-7sOwg"},"\u6027\u80fd\u4f18\u5316 | Go Ballast \u8ba9\u5185\u5b58\u63a7\u5236\u66f4\u52a0\u4e1d\u6ed1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lE83EZ7eztjEWd_NU796YQ"},"gin \u6e90\u7801\u9605\u8bfb(5) - \u7075\u6d3b\u7684\u8fd4\u56de\u503c\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2OI9vh_LGPxtGkhF-AnWDA"},"gin \u6e90\u7801\u9605\u8bfb(4) - \u53cb\u597d\u7684\u8bf7\u6c42\u53c2\u6570\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PldVh8Wk6oxCFIcWVx3hrQ"},"gin \u6e90\u7801\u9605\u8bfb(3) - gin \u8def\u7531\u7684\u5b9e\u73b0\u5256\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d9kP77eKRm2MSW_9ySlVGA"},"\u89c1\u5fae\u77e5\u8457| \u5e26\u4f60\u900f\u8fc7\u5185\u5b58\u770b Slice \u548c Array\u7684\u5f02\u540c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mrCQyw_dR5VYzf8ejyvHfA"},"Goland \u8fd9\u4e9b\u5b9e\u64cd\u6280\u5de7\uff0c\u4f60\u53ef\u80fd\u8fd8\u4e0d\u4f1a\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gmKi3bE99K6bXVGcMFz53w"},"\u8fd9\u4e9b Goland \u6280\u5de7\uff0c\u5b66\u4f1a\u5f00\u53d1\u6548\u7387\u7ffb\u500d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lMvU80jhkabMvqXeTFiDnw"},"Go interface \u539f\u7406\u5256\u6790--\u7c7b\u578b\u8f6c\u6362")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MQWZOkaAc4Bw-PmYHyd9SA"},"\u5feb\u6536\u85cf\uff01\u6700\u5168Go\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NrUWfpyfzX4sag22qF-Y-Q"},"\u5feb\u6536\u85cf\uff01\u6700\u5168GO\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\u3010\u4e0b\u3011")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i1N9bmVSW1lGfOezvhcD7g"},"\u6df1\u5165\u7406\u89e3 golang \u7684\u4e92\u65a5\u9501")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rETmci7xvzf5X9_liS0Hmg"},"Go 1.20\u65b0\u53d8\u5316\uff01\u7b2c\u4e00\u90e8\u5206\uff1a\u8bed\u8a00\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UQwOJVqm5gnQPMgSE3MW9w"},"[","\u8bd1","]","Uber \u7684 Go\u8bed\u8a00\u5f00\u53d1\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w"},"\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uWhmvBk_MN23RjmfjkxqeQ"},"\u4ece\u9e45\u5382\u5b9e\u4f8b\u51fa\u53d1\uff01\u5206\u6790Go Channel\u5e95\u5c42\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vB9ElJCfgZeQHtB596XHpA"},"Go \u670d\u52a1\u81ea\u52a8\u6536\u96c6\u7ebf\u4e0a\u95ee\u9898\u73b0\u573a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gLbAZShFnkPcI937pk-wpg"},"\u7528\u89c4\u5219\u5f15\u64ce\u8ba9\u4f60\u4e00\u5929\u4e0a\u7ebf\u5341\u4e2a\u9700\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gGs0tOJqBvJKCzPuUWsPiA"},"\u8ba1\u7b97\u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u59cb\u672b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nSlfsoIo0cMYUdgIEuHWEg"},"IO \u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u8bb0\u5f55")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YM9UP-esSDNZywMneKcVYw"},"Golang GC \u4ece\u7406\u8bba\u5230\u9488\u5bf9\u670d\u52a1\u7684\u5b9a\u5236\u5316\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QQjOyYkDfuxIxHl6k6qkRA"},"\u4e00\u6587\u5f7b\u5e95\u7406\u89e3Go\u8bed\u8a00\u6808\u5185\u5b58/\u5806\u5185\u5b58")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Oz0Zn8Y43UfHIOPL6rZ5Ig"},"\u5b57\u8282\u5927\u89c4\u6a21\u5fae\u670d\u52a1 Go \u8bed\u8a00\u53d1\u5c55\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2FVYnKHXFoj18W62pob_jw"},"\u901a\u8fc7\u5206\u6790gin\u3001beego\u6e90\u7801\uff0c\u8bfb\u61c2web\u6846\u67b6\u5bf9http\u8bf7\u6c42\u5904\u7406\u6d41\u7a0b\u7684\u672c\u8d28")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aLiqEuD9T8sERVrfGDSxvw"},"\u4e00\u6587\u8bfb\u61c2 Go Http Server \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0JbLDkJboDDihy-7N4MMPw"},"Golang slog \u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Immr4DD-XA-noOEkZ6flKg"},"Golang \u5e93: golang slog \u600e\u4e48\u8bbe\u7f6e\u65e5\u5fd7 Debug \u7b49\u7ea7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PKtrqHFTYWyAVSolKVOoBQ"},"Golang \u5e93: \u4e3a\u4ec0\u4e48 Golang slog \u5e93\u4e0d\u652f\u6301 Fatal")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G8mEAKRYbaae_rFBVJqdeg"},"\u53d1\u73b0conc\u5e76\u53d1\u5e93\u4e00\u4e2a\u6709\u8da3\u7684\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg"},"Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/irp0uBR-nJ87tZ_elMWPnA"},"\u300cGo\u8bed\u8a00\u8fdb\u9636\u300d\u5e76\u53d1\u7f16\u7a0b\u8be6\u89e3 | \u6587\u672b\u62bd\u5956")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7194334949011357755"},"\u4e00\u6587\u5165\u95e8Go\u4e91\u539f\u751f\u5fae\u670d\u52a1\u300c\u7206\u809d6\u5343\u5b57\u300d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jsdGV31yT5AR07BzRovWVw"},"\u4e3a\u4ec0\u4e48 Go \u4e0d\u652f\u6301 ","[","]","T \u8f6c\u6362\u4e3a ","[","]","interface")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uTJ1En-BXiLvH45xx0eFsA"},"go-zero \u662f\u5982\u4f55\u505a\u8def\u7531\u7ba1\u7406\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RyVc_JZJi_pTT_51mEHYiw"},"Go \u8bed\u8a00\u4e2d\u6392\u5e8f\u7684 3 \u79cd\u65b9\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ExfVdEM7_YWlQF6GhFn74A"},"\u4e00\u6587\u5403\u900f Go \u5185\u7f6e RPC \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ea7LfF2jOoHOSozX-qUZLA"},"Go \u6700\u7ec6\u8282\u7bc7\uff5c\u5185\u5b58\u56de\u6536\u53c8\u8e29\u5751\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BwqHMhc2WtAY_R-UffNQ4w"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cGo \u7684 nil \u503c\u5224\u65ad\uff0c\u5343\u65b9\u767e\u8ba1\uff0c\u8fd8\u662f\u8e29\u5751!")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-3X0c4P0WdZdjtkTsX16Rw"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cpprof \u7edf\u8ba1\u7684\u5185\u5b58\u603b\u662f\u504f\u5c0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZgTCSj-PZMTiMCR4FtBeyA"},"Go \u6700\u7ec6\u8282\u7bc7\uff5c\u89e3\u5bc6 defer \u539f\u7406\uff0c\u7a76\u7adf\u80cc\u7740\u7a0b\u5e8f\u733f\u505a\u4e86\u591a\u5c11\u4e8b\u60c5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Atj8Ngvg3Uzw4gMDwf5rag"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang \u5e76\u53d1\u7f16\u7a0b\u6838\u5fc3\u7bc7 \u2014\u2014 \u5185\u5b58\u53ef\u89c1\u6027")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2u2qRUbgcOwvU9wcHpC0SA"},"Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang\u6700\u7ec6\u8282\u7bc7\u2014 struct{} \u7a7a\u7ed3\u6784\u4f53\u7a76\u7adf\u662f\u5565")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ylsTVohPo7x8QKAUj1uoTA"},"Go Slice \u6269\u5bb9\u7684\u8fd9\u4e9b\u5751\u4f60\u8e29\u8fc7\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ixTP1qythuJyhf3b9kIRaA"},"Go \u8bed\u8a00\u5b9e\u73b0\u521b\u5efa\u578b\u8bbe\u8ba1\u6a21\u5f0f - \u5355\u4f8b\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qTYlHqozkWHkhF9OKfaAMQ"},"Go \u8bed\u8a00\u81ea\u5e26\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SYQTlvbLvbsSwFi2Q_kI1Q"},"\u5982\u4f55\u505a\u597d\u8868\u7ed3\u6784\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xiUPLOTkDCX2i2jTOSNgCQ"},"Go \u9519\u8bef\u5904\u7406\uff1a100+ \u63d0\u6848\u5168\u90e8\u88ab\u62d2\u7edd\uff0c\u4e3a\u4f55\u73b0\u9636\u6bb5\u4ecd\u7528 if err != nil")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/431YMKwRjaStanqA6juePA"},"Go \u8bed\u8a00\u5e76\u53d1\u6a21\u5f0f\u4ee3\u7801\u6a21\u677f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/elsHIqDQ0yABUZXNVpjwMg"},"\u57fa\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4f18\u5316\u9884\u89c8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/soaxFUjo6hEe2KSnle_LkQ"},"\u300c\u9ad8\u9891\u5fc5\u8003\u300dGo\u5e76\u53d1\u7f16\u7a0b\u9762\u8bd5\u9898\u548c\u7b54\u6848")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/k0zwlJNFssMRh1NHA6rGcA"},"\u6e90\u7801\u9605\u8bfb - \u5207\u7247\u6269\u5bb9\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PzfiMXiYjfGQFHW_0hTS4A"},"Golang\u53cd\u5c04\u5b66\u4e60\uff1a\u624b\u5199\u4e00\u4e2aRPC")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mAo2K8lZNeJHTtShBHlUsQ"},"\u6df1\u5165\u89e3\u6790\u975e\u963b\u585eGolang IO\u6846\u67b6nbio")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aP9bT4UL1MK5EDx18WfvmQ"},"Go \u8bed\u8a00\u6807\u51c6\u5e93 bufio \u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Yi0eGTzrT7mtkpebmLXqVA"},"CPU \u7f13\u5b58\u4f53\u7cfb\u5bf9 Go \u7a0b\u5e8f\u7684\u5f71\u54cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2iOkW5h7x-1wdYe51vMemw"},"\u300c\u5237\u8d77\u6765\u300dGo\u5fc5\u770b\u7684\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/NJuOB8k86Z7Hv-xITL1Vqg"},"Go \u6027\u80fd\u52a0\u901f\u5668\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684 5 \u4e2a\u8bc0\u7a8d\u548c\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tgBqY3xYbk5IBzViL9eaiA"},"\u6df1\u5165\u5256\u6790 Golang \u7a0b\u5e8f\u542f\u52a8\u539f\u7406 - \u4ece ELF \u5165\u53e3\u70b9\u5230GMP\u521d\u59cb\u5316\u5230\u6267\u884c main\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7254384497649844280"},"\u4ece\u7f16\u8bd1\u539f\u7406\u5230 Go \u542f\u52a8\u65f6\u7684\u6d41\u7a0b\uff0cGo\u7a0b\u5e8f\u662f\u600e\u6837\u8dd1\u8d77\u6765\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/V5wAZcTbunU3HdS1xaWavQ"},"\u4ece.go\u6587\u672c\u6587\u4ef6\u5230\u53ef\u6267\u884c\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/eWM9AvG1qXnMWF4qIwhnVQ"},"Go \u7f16\u8bd1\u5668\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7210005376653377597"},"\u5b66\u4f1a Go select \u8bed\u53e5\uff0c\u8f7b\u677e\u5b9e\u73b0\u9ad8\u6548\u5e76\u53d1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7215188852851097656"},"Go Mutex\uff1a\u4fdd\u62a4\u5e76\u53d1\u8bbf\u95ee\u5171\u4eab\u8d44\u6e90\u7684\u5229\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7218554163051413561"},"Go RWMutex\uff1a\u9ad8\u5e76\u53d1\u8bfb\u591a\u5199\u5c11\u573a\u666f\u4e0b\u7684\u6027\u80fd\u4f18\u5316\u5229\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7223035239072333861"},"Go \u8bed\u8a00\u4e2d\u6ca1\u6709\u679a\u4e3e\u7c7b\u578b\uff0c\u4f46\u662f\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u505a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7224147971834691639"},"Go \u65b9\u6cd5\u63a5\u6536\u5668\uff1a\u9009\u62e9\u503c\u63a5\u6536\u5668\u8fd8\u662f\u6307\u9488\u63a5\u6536\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7233981178101186619"},"\u4e00\u6587\u638c\u63e1 Go \u5e76\u53d1\u6a21\u5f0f Context \u4e0a\u4e0b\u6587")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rD3pnjWF5_Zz-r6GB0LrrA"},"Go \u7a7a\u7ed3\u6784\u4f53\uff1a\u96f6\u5185\u5b58\u7684\u9b54\u529b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7241938328839618597"},"Go \u51fd\u6570\u9009\u9879\u6a21\u5f0f\uff08Functional Options Pattern\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7246777406387306553"},"Go \u9879\u76ee\u5206\u5c42\u4e0b\u7684\u6700\u4f73 error \u5904\u7406\u65b9\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xjkY6hJnUq5btDyJuSOZrg"},"Go \u8bed\u8a00 iota \u7684\u795e\u5947\u529b\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sJeXoxTSh7M9azpsbsr1rQ"},"\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\uff1a\u63a2\u7d22Go\u8bed\u8a00\u4e2d\u7684\u51fd\u6570\u4e00\u7b49\u516c\u6c11")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_enXW8Pk4okosAgDo_aYSw"},"[","Go\u5f00\u6e90\u5de5\u5177","]"," go-optioner\uff1a\u8f7b\u677e\u751f\u6210\u51fd\u6570\u9009\u9879\u6a21\u5f0f\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/biTRyEu2h8AzQaQf7Ik8nA"},"\u6df1\u5165\u63a2\u7d22 Go 1.21.0 \u4e2d\u7684 maps \u5de5\u5177\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_a9d67L8l7G6EDJom1kixw"},"Go Gin \u6846\u67b6\u7cfb\u5217 - \u5165\u95e8\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gC4D9CqeYAd-jPotKgIV4g"},"Go \u9879\u76ee\u5fc5\u5907\uff1a\u6df1\u5165\u6d45\u51fa Wire \u4f9d\u8d56\u6ce8\u5165\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7226187111330611255"},"\u5feb\u901f\u4e0a\u624b Go CGO\uff0c\u638c\u63e1\u5728 Go \u91cc\u5199 C\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1NuBnk8_lxmTi9N0biLa2g"},"Go1.21 \u901f\u89c8\uff1a\u8fc7\u4e86\u4e00\u5e74\u534a\uff0cslices\u3001maps \u6cdb\u578b\u5e93\u7ec8\u4e8e\u8981\u52a0\u5165\u6807\u51c6\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/N7_-WNBsTpTc4X8qTQw-Nw"},"Go1.22 \u53ef\u80fd\u4f1a\u89e3\u51b3\u5faa\u73af\u53d8\u91cf\u7684\u5751\uff0c\u771f\u597d\uff01\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xgJ8lPS-O84Ttne5heRa3g"},"Go1.21 \u901f\u89c8\uff1a\u9a9a\u64cd\u4f5c panic(nil) \u5c06\u6210\u4e3a\u5386\u53f2\uff01\u4ee5\u540e\u522b\u8fd9\u4e48\u5e72\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rxxQhrVk3_4ZvTjsIJbstw"},"Go1.21.0 \u65b0\u7279\u6027\uff1a\u4e0d\u9700\u8981\u5faa\u73af delete map \u5143\u7d20\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MorBUrzpKFhssiZWLt4o6g"},"Go1.21 \u901f\u89c8\uff1a\u65b0\u5185\u7f6e\u51fd\u6570 clear\u3001min\u3001max \u548c\u65b0\u6807\u51c6\u5e93\u5305 cmp\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/s13EBwOExsVz_vwNEm0fvQ"},"Go1.21 \u901f\u89c8\uff1ago.mod \u7684 Go \u7248\u672c\u53f7\u5c06\u4f1a\u7ea6\u675f Go \u7a0b\u5e8f\u6784\u5efa\uff0c\u8981\u7279\u522b\u6ce8\u610f\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/b_TYBRIZ3-EORFYq1xRjyQ"},"Go \u5c06\u5f15\u5165\u6807\u51c6\u5e93 v2 \u7248\u672c\uff0c\u9996\u4e2a\u52a8\u624b\u7684\u662f\uff1amath/rand/v2\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7249913673216966714"},"Go1.21 \u901f\u89c8\uff1aContext \u53ef\u4ee5\u8bbe\u7f6e\u53d6\u6d88\u539f\u56e0\u548c\u56de\u8c03\u51fd\u6570\u4e86\uff0c\u7b49\u7684\u53ef\u592a\u4e45\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VO0VlfGbuvZst9yD73-VDQ"},"Go \u56e2\u961f\u5c06\u4fee\u6539 for \u5faa\u73af\u53d8\u91cf\u7684\u8bed\u4e49\uff0cGo1.21 \u65b0\u7248\u672c\u5373\u53ef\u4f53\u9a8c\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Z8kMDwuv9ZlmqvdrOu5SEQ"},"Google \u5de5\u4f5c 10+ \u5e74\u7684\u611f\u609f\uff0c\u6709\u770b\u5230 Go \u6838\u5fc3\u56e2\u961f\u7684\u5f71\u5b50\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4vpgxwTEn-xjdmXF5Hj7Kw"},"Go defer \u53bb\u6389\u95ed\u5305\u51fd\u6570\uff0c\u9760\u8c31\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xjjnE5hcspbNRGHP-I869A"},"\u53e6\u4e00\u79cd\u89c6\u89d2\uff1a\u6211\u4e3a\u4ec0\u4e48\u653e\u5f03 Go \u8bed\u8a00")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4pPpHRWflkkvqrf-FlXztg"},"Go \u9762\u8bd5\u9898\uff1astring \u662f\u7ebf\u7a0b\u5b89\u5168\u7684\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/BfW8Ra3tsv7Dv3nu3MeI0g"},"Go \u6539\u7248\u672c\u53f7\u89c4\u5219\uff0c\u4e3b\u7248\u672c\u53f7\u7ec8\u4e8e\u652f\u6301\u7b2c\u4e09\u4f4d\u6570\u5b57 0 \u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Nuj_cYFvBesaBbSSz5PuBg"},"Go1.21 \u90a3\u4e9b\u4e8b\uff1a\u6cdb\u578b\u5e93\u3001for \u8bed\u4e49\u53d8\u66f4\u3001\u7edf\u4e00 log/slog\u3001WASI \u7b49\u65b0\u7279\u6027\uff0c\u4f60\u77e5\u9053\u591a\u5c11")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jk7k5v9uvaNy_2fUsDjq0Q"},"\u53c8\u6709\u65b0\u529f\u80fd\uff01Go \u5c06\u6709\u751f\u6210\u65b0\u6a21\u677f\u7684 gonew \u5de5\u5177\u94fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/o1iKbXJEikJn8BLwetvF5g"},"Go \u5c06\u589e\u52a0\u5185\u7f6e\u7684\u96f6\u503c\u6807\u8bc6\u7b26 zero\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/M6b4Q7rwKSt4KNKJN7_j4g"},"Go \u96f6\u503c\u548c\u7a7a\u503c\u7684\u5224\u65ad\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5kNyYJhrzigujLq1YSVjHw"},"Go \u8d1f\u8d23\u4eba\u8bf4\u4ee5\u540e\u4e0d\u4f1a\u6709 Go2 \u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TlJFr25XNgGA7uyRtLMOlw"},"Go \u5e38\u91cf\u4e3a\u4ec0\u4e48\u53ea\u652f\u6301\u57fa\u672c\u6570\u636e\u7c7b\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xO_w3FvNN8OeiuEYFarwGQ"},"Go \u5b98\u65b9\u65b0\u73a9\u5177\uff1a\u6f0f\u6d1e\u7ba1\u7406\u548c\u626b\u63cf\uff0c\u770b\u770b\u81ea\u5df1\u9879\u76ee\u6709\u6ca1\u6709\u5751")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4yfVZCaJ1489ddpYD5vDQA"},"\u5feb\u901f\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/C_KpYoul8ko5yrVLMe_uQg"},"\u300c\u5fc5\u77e5\u5fc5\u4f1a\u300d Nacos \u7684\u9762\u8bd5\u9898\u548c\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8XdbLrlzHhofiC089AMb1Q"},"zookeeper\u5230nacos\u7684\u8fc1\u79fb\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YGhndR5zR-Ebf8IaKbFZiQ"},"\u4e0a\u7bc7\uff1a\u5e26\u4f60\u624b\u5de5\u4f53\u9a8c\u4ece\u5199\u4ee3\u7801\u3001\u7f16\u8bd1\u3001\u6253\u5305\u955c\u50cf\u3001\u90e8\u7f72\u5230K8S\u7684\u5168\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yJ6rkYrwn8RAMLt5uCF9mw"},"\u4e0b\u7bc7\uff1a\u4f7f\u7528jenkins\u53d1\u5e03go\u9879\u76ee\u5230k8s\uff0c\u63a5\u4e0a\u7bc7\u7684\u624b\u5de5\u4f53\u9a8c\u6539\u9020\u4e3a\u81ea\u52a8\u5316\u53d1\u5e03")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pW0vxt8k1pDk0OEz5asWGQ"},"\u503c\u5f97\u6536\u85cf\uff1aK8S\u7684kubectl\u5e38\u7528\u547d\u4ee4\u5df2\u7ecf\u6309\u573a\u666f\u5206\u597d\u7c7b\uff0c\u8bf7\u60a8\u67e5\u9605")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lYg-GdheztmkTo9mwqHGsg"},"\u907f\u5751\uff1aGo\u5e76\u53d1\u7f16\u7a0b\u65f6\uff0c\u5982\u4f55\u907f\u514d\u53d1\u751f\u7ade\u6001\u6761\u4ef6\u548c\u6570\u636e\u7ade\u4e89")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bwkK3Yw02w4szwub2B2-ig"},"Go\u63a5\u53e3\uff1a\u8fd0\u7ef4\u5f00\u53d1\u573a\u666f\u4e2d\uff0cgo\u7684\u63a5\u53e3\u5230\u5e95\u600e\u4e48\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bqZ6gAsOZoVEMSCeOuLbiQ"},"Go\uff1a4\u4e2a\u573a\u666f\u5c31\u53ef\u4ee5\u8ba9\u4f60\u77e5\u9053Goroutine\u548c\u901a\u9053\u662f\u600e\u4e48\u7528\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7210747150828798008"},"\u4e0d\u80cc\u9505\u8fd0\u7ef4\uff1aGo\u8bed\u8a00\u5207\u7247\u5185\u5b58\u4f18\u5316\u6280\u5de7\u548c\u5b9e\u6218\u6848\u4f8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rxPAcU5zhWCtRQLbh9uxKw"},"Go\u5b9e\u6218\uff1a\u5f00\u53d1\u4e00\u4e2a\u7b80\u5355\u7684gRPC Demo")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/im8JZV3bL9WVOn7VgArmhw"},"Go\uff1a\u4f7f\u7528Cobra\u6253\u9020\u5f3a\u5927\u547d\u4ee4\u884c\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4VfTjWQwNO-tlxYbUOrWZw"},"Go\u7684\u8fd9\u4e2a\u5e93\uff0c\u8ba9\u4f60\u7684\u547d\u4ee4\u884c\u8f93\u51fa\u53d8\u5f97\u4e13\u4e1a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nbouC5ynfZShaTMTYiCJFA"},"\u300cGo\u5f00\u6e90\u5305\u300dasynq\uff1a\u4e00\u4e2a\u57fa\u4e8eredis\u7684\uff0c\u7b80\u5355\u3001\u53ef\u9760\u3001\u9ad8\u6548\u7684\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u5305")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HBLwocMA2vQE2uFlJ0D8Iw"},"\u62bd\u4e1d\u5265\u8327\uff0c\u8bb0\u4e00\u6b21 Go \u7a0b\u5e8f\u6027\u80fd\u4f18\u5316\u4e4b\u65c5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1Y_A6WVslDthVjtbP9Ibvg"},"Go\uff1a\u8bb0\u4e00\u6b21\u63d0\u534718\u500d\u7684\u6027\u80fd\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/js3m_Fe6k4ys4aBSFDJhLQ"},"Go\u8bed\u8a00\u4e2dJSON\u5904\u7406\u6280\u5de7\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ueNuYA23F3bQTwIKU-PZ2Q"},"\u63a2\u7a76\uff5cGo JSON \u4e09\u65b9\u5305\u54ea\u5bb6\u5f3a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IAHEQu-N5OO-X_q-47GCsQ"},"Sonic: Go\u8bed\u8a00\u7684\u8d85\u7ea7JSON\u5e93\uff0c\u89e3\u6790\u4e0e\u7f16\u7801\u901f\u5ea6\u72c2\u98d9")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cjQyDdIgcdzj7LOeZf21bQ"},"\u6536\u85cf\uff01\uff01\uff01\u4e00\u56fe\u638c\u63e1 Go \u4e2d IO \u5305\u7684\u5173\u7cfb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7207058392287346747"},"\u901a\u8fc7\u6e90\u7801\u5256\u6790Go\u7684map\u6269\u5bb9\u5e95\u5c42\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cK2KMpN4vUrlDXEkTm7Mig"},"\u300c\u6709\u95ee\u5fc5\u7b54\u300dGopher\u5982\u4f55\u4f18\u96c5\u7684\u5bf9\u65f6\u95f4\u8fdb\u884c\u683c\u5f0f\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7qutgFgPDGyjKhxb6YVB3Q"},"Go \u6cdb\u578b\u7684\u4e8c\u5341\u4e00\u4e2a\u9677\u9631")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248388270723039290"},"\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff1a\u6df1\u5165\u63a2\u7d22Golang\u4e2d\u7684SM4\u52a0\u5bc6\u89e3\u5bc6\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248791708334899258"},"\u7cbe\u90098\u9053ES\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\uff0c\u540e\u6094\u6ca1\u65e9\u70b9\u770b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248995705291866169"},"\u7cbe\u9009Go\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\u6c47\u603b\uff0c\u9605\u8bfb\u7834\u4e07\uff0c\u6536\u85cf230+")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ldn5APfp0UooWbh4cmcM4A"},"Go\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3 | \u6587\u672b\u9001\u4e66")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GXAvaFvXR3HYI7qU4lL4lA"},"Go\u4e2d\u8fd9\u4e48\u591a\u521b\u5efaerror\u7684\u65b9\u5f0f\uff0c\u4f60\u771f\u7684\u4e86\u89e3\u5b83\u4eec\u5404\u81ea\u7684\u5e94\u7528\u573a\u666f\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6aicpVC3qjRpf1ILI4V4lA"},"\u57fa\u4e8eRedis\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u56fa\u5b9a\u7a97\u53e3\u9650\u6d41\u5668")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CUQaiZp4BrulnXvLd9ogZQ"},"go channel\u5e94\u7528\u7cfb\u5217\u4e4b\u63a7\u5236\u534f\u7a0b\u6570\u91cf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YJp2jxuBwwbPBaMWlDZG9g"},"\u914d\u56fe\u6e05\u65b0\u7684Protobuf \u7f16\u7801&\u907f\u5751\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iptZLaGFLd1rDedclQUMFg"},"\u5199\u7ed9\u5f00\u53d1\u8005\u7684gRPC\u6559\u7a0b-\u670d\u52a1\u53d1\u73b0\u4e0e\u8d1f\u8f7d\u5747\u8861")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/oettru3CV_Cjqv5GEOmcMw"},"\u7b54\u7f51\u53cb\u95ee\uff1agolang\u4e2d\u7684slice\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\u662f\u503c\u4f20\u9012\u8fd8\u662f\u5f15\u7528\u4f20\u9012")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OXopl6FpwtE6P-k0GEP9qA"},"Go\u53ef\u7528\u6027(\u4e03) \u603b\u7ed3: \u4e00\u5f20\u56fe\u4e32\u8054\u53ef\u7528\u6027\u77e5\u8bc6\u70b9")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MSwUlVGPDRBjdR-xh5cNfA"},"Go \u5de5\u7a0b\u5316(\u5341) \u5982\u4f55\u5728\u6574\u6d01\u67b6\u6784\u4e2d\u4f7f\u7528\u4e8b\u52a1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pb0P_y34N3uOhMu0SDqC2A"},"Go \u5de5\u7a0b\u5316(\u5341\u4e00) \u5982\u4f55\u4f18\u96c5\u7684\u5199\u51fa repo \u5c42\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2wYRmG_AiiHYjLDEXg94Ag"},"\u4f7f\u7528 Go \u8bed\u8a00\u5b9e\u73b0\u4e8c\u53c9\u641c\u7d22\u6811")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7hU0iSDBg0z1nYZnB-61gQ"},"Opentelemetry \u5b9e\u8df5\u5206\u4eab - Golang\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xavjsa4NzRiVRxyMhifCDg"},"Golang\u5b9e\u73b0\u5355\u673a\u767e\u4e07\u957f\u8fde\u63a5\u670d\u52a1 - \u7f8e\u56fe\u7684\u4e09\u5e74\u4f18\u5316\u7ecf\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IpvR28soReYC3nNkAisteA"},"\u4f7f\u7528go-zero\u5feb\u901f\u6784\u5efa\u5fae\u670d\u52a1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yHD5XKsk6emuXjcnU2JxDw"},"\u5927\u578b Go \u4ee3\u7801\u5e93\u7684 3 \u79cd\u6700\u4f73\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n199y8JEyjuGFwUEyH2XVg"},"Asynq: \u57fa\u4e8eRedis\u5b9e\u73b0\u7684Go\u751f\u6001\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u548c\u5f02\u6b65\u5904\u7406\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/C2kZGElYQmHz3OCb7LuYoA"},"\u300cGo\u9762\u7ecf\u300d\u7b97\u6cd5 \u5e76\u53d1\u6a21\u578b \u7f13\u5b58\u843d\u76d8 etcd actor\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2tFBe6LH84dZnOcfkgX32w"},"\u63a2\u7d22 Go1.21 \u4e2d\u7684 slices \u5305\uff1a\u539f\u7406\uff0c\u7279\u70b9\u548c\u793a\u4f8b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7nK4whfh0Owwhmq_67_eYg"},"\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_mXRLJ-h7Iqkrt1jq_sZXg"},"Go \u8bed\u8a00\u4e3a\u4ec0\u4e48\u9002\u5408\u5f00\u53d1\u7f51\u7edc\u670d\u52a1")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iamOjb0k3M2k_FVG9W7z0A"},"\u7528 Go \u7f16\u5199\u7b80\u6d01\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7vDklpTsbRdRDvB0-yvB5g"},"Golang channel \u4e09\u5927\u5751\uff0c\u4f60\u8e29\u8fc7\u4e86\u561b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/j9Obe6Na25388AzeSL1dRA"},"\u4f7f\u7528Singleflight\u4f18\u5316Go\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gVjq59qnLjy-gwibt7Q3yw"},"\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/G3FGOUo-F-stOp5eZjq4QQ"},"\u5b9a\u4e86\uff1aGo 1.22\u5c06\u4fee\u590dfor\u5faa\u73af\u53d8\u91cf\u9519\u8bef")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R_2pwdv2V1jj3zMjuUTNHw"},"Go\u5b57\u7b26\u4e32\u64cd\u4f5c\u4e0d\u662f\u4f60\u60f3\u7684\u90a3\u4e48\u7b80\u5355\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QlzH18i72pWPm012t7d42Q"},"Golang\u77e5\u8bc6\u70b9(defer): \u9762\u8bd5\u7ecf\u5e38\u53d8\u91cf\u5728 defer \u4e2d\u7684\u503c\uff0c \u5176\u5b9e\u5728\u95ee\u53d8\u91cf\u7684\u4f5c\u7528\u57df")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VjP9Bv46x7NP6uQ7cbsqmg"},"Go BIO/NIO\u63a2\u8ba8(1)\uff1aGin\u6846\u67b6\u4e2d\u5982\u4f55\u5904\u7406HTTP\u8bf7\u6c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/x5qUJ-htS6ML1Cc8uYIDVQ"},"Go BIO/NIO\u63a2\u8ba8(2)\uff1anet\u5e93\u5bf9socket/bind/listen/accept\u7684\u5c01\u88c5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WoXZ_i7lJeXny8lIJ_Aj4g"},"Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/76xvAvnFAcDUAa6fgoZRfg"},"\u3010\u8865\u5145\u4ee3\u7801\u3011Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AvtIiC349sDqOe9labc3-A"},"Go BIO/NIO\u63a2\u8ba8(4)\uff1anet/http \u5728 tcp conn \u4e0a\u7684\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MO5XV40D3MI6NpEEpJiCMA"},"Go BIO/NIO\u63a2\u8ba8(5)\uff1anet\u5e93\u7684\u975e\u963b\u585e\u652f\u6301")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/t_4uTGN9DFCjqDw4LZT-0w"},"Go BIO/NIO\u63a2\u8ba8(6)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bselect")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Zsh92yqK4e6mxNBLgY0Umw"},"Go BIO/NIO\u63a2\u8ba8(7)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bepoll")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3_eToHvOw25JrC8-xePe_w"},"Go BIO/NIO\u63a2\u8ba8(8)\uff1aGo netpoll \u7684\u5de5\u4f5c\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-qms3hEl2mNMkDN1S4ZQoQ"},"Go\u534f\u7a0b\u6c60(1): \u7ebf\u7a0bvs\u534f\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ktMff61A9vvqeRGkGwQnwg"},"Go\u534f\u7a0b\u6c60(2): \u5982\u4f55\u5b9e\u73b0\u534f\u7a0b\u6c60")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cIgfuumVCL4rxtNYGcQH4A"},"\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1(1): \u5982\u4f55\u5b9e\u73b0\u6296\u97f3\u5173\u6ce8/\u7c89\u4e1d\u5217\u8868")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ydFRhjV70QC64N8r2zEtVA"},"SIMD\u80fd\u529b\u521d\u4f53\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/q-keuybJ2d-QMXWoPpSbPA"},"[","\u4ee3\u7801\u9644\u5f55","]"," SIMD\u80fd\u529b\u521d\u4f53\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1kuLtd8rxC1xP628FgAwqw"},"\u670d\u52a1\u67b6\u6784\u7b80\u4ecb")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ane5iRMqYrtQMnC3TWlrwA"},"\u670d\u52a1\u67b6\u6784\uff1a\u5927\u6570\u636e\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dOw25R2xihr0M3T27fYUSA"},"\u670d\u52a1\u67b6\u6784\uff1a\u5fae\u670d\u52a1\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CUCHUQa6lYuPhvEALdIQQg"},"\u670d\u52a1\u67b6\u6784\uff1a\u5206\u5c42\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P1j0vg2FYqt1zvwPQsdtww"},"\u670d\u52a1\u67b6\u6784\uff1aWeb-Queue-Worker\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YkOoLbH2P2HheQxomGsbNQ"},"\u5f02\u6b65\u8bf7\u6c42-\u54cd\u5e94\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Q-YvkWhFC2uK1z5AKEKSnw"},"Sidecar\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157594175846744071"},"\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1CY3E5daJ5U42orVwzCpaw"},"Go Scheduler \u7684 GMP \u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7116817920209977351"},"Golang \u6cdb\u578b\u521d\u8bc6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yHB9BzEGIki1fyjYojdpYQ"},"Go \u8bed\u8a00\u5b98\u65b9\u4f9d\u8d56\u6ce8\u5165\u5de5\u5177 Wire \u4f7f\u7528\u6307\u5317")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043587400131411976"},"Go \u670d\u52a1\u7aef\u5f00\u53d1\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://eddycjy.com/go-categories/"},"Go \u8bed\u8a00\u5165\u95e8\u7cfb\u5217\uff1a\u521d\u63a2 Go \u9879\u76ee\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://golang2.eddycjy.com/"},"Go \u8bed\u8a00\u7f16\u7a0b\u4e4b\u65c5\uff1a\u6df1\u5165\u7528 Go \u505a\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://golang3.eddycjy.com/"},"Go \u8bed\u8a00\u8bbe\u8ba1\u54f2\u5b66\uff1a\u4e86\u89e3 Go \u7684\u4e3a\u4ec0\u4e48\u548c\u8bbe\u8ba1\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://golang1.eddycjy.com/"},"Go \u8bed\u8a00\u8fdb\u9636\u4e4b\u65c5\uff1a\u8fdb\u4e00\u6b65\u6df1\u5165 Go \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1383459655464337409&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011HTTP \u7cfb\u5217\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1323498303014780929&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00 Web \u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1325302744319737858&scene=21&from_msgid=2247484375&from_itemidx=1&count=3&nolastread=1#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5e76\u53d1\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/homepage?__biz=MzkyNzI1NzM5NQ==&hid=2&sn=4d298cf2d9ad21260321275cf6c75194&scene=1&devicetype=iOS14.0&version=18000733&lang=zh_CN&nettype=3G+&ascene=7&session_us=gh_169729c17b9c&fontScale=100"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"http://mp.weixin.qq.com/mp/homepage?__biz=MzkyMzIyNjIxMQ==&hid=1&sn=631fe1ce375f2cd672449d0bd01963d2&scene=18#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go\u6e90\u7801\u4e0e\u5e95\u5c42")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1394839706508148737&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Kubernetes \u5b66\u4e60\u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1488826194207752195&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011\u5fae\u670d\u52a1\u8bbe\u8ba1\u548c\u601d\u8003")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1809543596702777345&scene=21&from_msgid=2247492061&from_itemidx=1&count=3&nolastread=1#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u5fae\u670d\u52a1\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1326949382503219201&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5b9e\u6218\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1751854579329056768&count=3#wechat_redirect"},"\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u9762\u8bd5\u9898")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/doc/effective_go"},"Golang \u8fdb\u9636 - Effective Go")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/doc/faq"},"Golang \u8fdb\u9636 - Go FAQ")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/blog/all"},"Golang \u8fdb\u9636 - blog\u6587\u7ae0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://go.dev/talks/"},"Golang \u8fdb\u9636 - \u5404\u4e2atalk\u8d44\u6599")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://tonybai.com/2019/10/12/uber-go-style-guide/"},"Golang \u8fdb\u9636 - Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://tonybai.com/google-go-style/"},"Golang \u8fdb\u9636 - Google Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki/CodeReviewComments"},"Golang \u8fdb\u9636 - CodeReviewComments")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki/SliceTricks"},"Golang \u8fdb\u9636 - SliceTricks")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki/CompilerOptimizations#optimized-memclr"},"Golang \u8fdb\u9636 - CompilerOptimizations")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang/go/wiki#learning-more-about-go"},"Golang \u8fdb\u9636 - learning-more-about-go")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/luk4z7/go-concurrency-guide"},"Golang \u8fdb\u9636 - go-concurrency-guide")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u6587\u7ae0\u5206\u4eab",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/kevinyan815/gocookbook"},"Golang\u5f00\u53d1\u624b\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg"},"\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw"},"\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rOtR8FfMpfBZrIkyRrNsfQ"},"Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6307\u5357\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RCBUlu0gRuVFSQ2m8Uyycg"},"Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6982\u8ff0\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vP2IDCK4cjyIGiutCoA7Pw"},"\u4e07\u5b57\u957f\u6587\uff0c\u6559\u4f60\u7528go\u5f00\u53d1\u533a\u5757\u94fe\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8_pJiuOzoQt6xyoLUX0CIw"},"Go \u670d\u52a1\u7f51\u7edc\u4e0d\u901a\uff1fnet/http\u81ea\u5e26\u7684\u8fd9\u4e2a\u5de5\u5177\u5e2e\u4f60\u5feb\u901f\u5b9a\u4f4d")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RnsM-bWSRBiDS4v1JcRzdg"},"\u98a0\u8986\u5fae\u670d\u52a1\u67b6\u6784\uff1f\u8c37\u6b4c\u6700\u65b0\u5f00\u6e90service weaver\u521d\u4f53\u9a8c")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i1loQpQufni3v4Ho2J6Pgw"},"\u4e00\u4e2a Go \u7a0b\u5e8f\u7684 Benchmark \u57fa\u51c6\u5206\u6790\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RLqjkV_1geeVkXeG9TLHFw"},"\u4f60\u8bf4 Go \u7684\u5207\u7247\u539f\u751f\u652f\u6301\u5e76\u53d1\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gNQETEVBMOH0US42M0uODg"},"\u7535\u8111\u7528GoLand\u592a\u5361\uff0c\u8bb0\u5f55\u4e0b\u81ea\u5df1\u628aVsCode\u5b9a\u5236\u6210Go IDE\u7684\u6b65\u9aa4\u548c\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iRgaOlFs52O2TMScu8wDzg"},"\u7528\u4e86Go\u533f\u540d\u7ed3\u6784\u4f53\uff0c\u642c\u7816\u6548\u7387\u66f4\u9ad8\uff0c\u4ea7\u91cf\u66f4\u8db3\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KaesgBLyTz7xi9eXvSTMmQ"},"\u5408\u8ba2\u672c\uff5c\u7528Go\u8bed\u8a00\u5b9e\u73b023\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u53ca\u5b66\u4e60\u91cd\u70b9")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/91-XUm5Gn9oQLd_F4dLb3A"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u4e2d\u4ecb\u8005\uff0c\u6700\u540e\u7684\u6a21\u5f0f\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8v0UZWygCvkbye4Y0P-3sQ"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u89e3\u91ca\u5668\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n1R1fnRZuDwlaQqsDh5y3g"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u547d\u4ee4\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/RikZAeI2Pic4vYwVNh4HnA"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u5907\u5fd8\u5f55\u6a21\u5f0f\uff0c\u5e26\u6682\u5b58\u7684\u4e1a\u52a1\u529f\u80fd\u53ef\u4ee5\u53c2\u8003\u5b83\u6765\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qsw89qI8DOXyb4C1XI5QtA"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u8bbf\u5ba2\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sABibBRsC2kknbAH18oatA"},"Go\u8bbe\u8ba1\u6a21\u5f0f-\u8fed\u4ee3\u5668\u5230\u5e95\u662f\u4e0d\u662f\u4e00\u4e2a\u591a\u6b64\u4e00\u4e3e\u7684\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/O8shSU46TcgFPx3h7NGFAA"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u6865\u63a5\u6a21\u5f0f\uff0c\u8ba9\u4ee3\u7801\u65e2\u80fd\u591a\u7ef4\u5ea6\u6269\u5c55\u53c8\u4e0d\u4f1a\u81c3\u80bf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AZHO7R6IXFG8MguDpUNdbw"},"Go\u8bbe\u8ba1\u6a21\u5f0f--\u4eab\u5143\u6a21\u5f0f\uff0c\u8282\u7701\u5185\u5b58\u7684\u597d\u5e2e\u624b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X9dKNO6sd-OY2VfsZpaElA"},"Go\u8bbe\u8ba1\u6a21\u5f0f\u5b9e\u6218--\u7528\u72b6\u6001\u6a21\u5f0f\u5b9e\u73b0\u7cfb\u7edf\u5de5\u4f5c\u6d41\u548c\u72b6\u6001\u673a")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tC9xfZFJvcNEbTXHQYvT6w"},"\u5916\u89c2\u6a21\u5f0f\uff0c\u4e00\u4e2a\u6bcf\u5929\u90fd\u5728\u7528\uff0c\u5374\u88ab\u591a\u6570\u4eba\u5728\u9762\u8bd5\u4e2d\u5ffd\u89c6\u7684\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r8975amH-DcJkWQKytIeJQ"},"Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u9879\u76ee\u4f9d\u8d56\u8026\u5408\u5ea6\u592a\u9ad8\uff1f\u53ef\u4ee5\u7528\u9002\u914d\u5668\u505a\u4e0b\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JKWbyr4Yt7A6l1nFsANUcQ"},"Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u7ec4\u5408\uff0c\u4e00\u4e2a\u5bf9\u6570\u636e\u7ed3\u6784\u7b97\u6cd5\u548c\u804c\u573a\u90fd\u6709\u63d0\u5347\u7684\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_e9Qa97gZvgv9n-pFB4lFw"},"Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u88c5\u9970\u5668\u548c\u804c\u8d23\u94fe\uff0c\u54ea\u4e2a\u6a21\u5f0f\u5b9e\u73b0\u4e2d\u95f4\u4ef6\u66f4\u79d1\u5b66")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/59cxPFHWcdnUxKyRyo8SKw"},"sourcegraph \u51fa\u54c1\u7684\u5e76\u53d1\u5e93 conc \u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AUSse5z1YES9wtKCiMdyWA"},"Go\u8bed\u8a00\u5b9e\u73b0\u7684\u53ef\u8bfb\u6027\u66f4\u9ad8\u7684\u5e76\u53d1\u795e\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LW8Woq5Rg4x31DbtD-_jeA"},"\u4e24\u79cd Option \u7f16\u7a0b\u6a21\u5f0f\u7684\u5b9e\u73b0\uff0cUber\u63a8\u8350\u8fd9\u4e00\u79cd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SFbSAGwQgQBVWpySYF-rkw"},"Go\u7248\u672c\u5927\u4e8e1.13\uff0c\u7a0b\u5e8f\u91cc\u8fd9\u6837\u505a\u9519\u8bef\u5904\u7406\u624d\u5730\u9053")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IelVDnMzGtT5y7hGSb_OxA"},"\u9762\u8bd5\u5b98\uff1anet/http\u5e93\u77e5\u9053\u5417\uff1f\u80fd\u8bf4\u8bf4\u4f18\u7f3a\u70b9\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3uWozu4VIUJHyIGut3_0Bg"},"Go \u6a21\u7cca\u6d4b\u8bd5fuzzing\u7684\u539f\u7406\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FTXkgxkUzsHMIspCK60G4w"},"Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u6015\u628a\u6838\u5fc3\u4ee3\u7801\u6539\u4e71\uff0c\u8bb0\u5f97\u7528\u4ee3\u7406\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zCh12E10JM24EGTyFS7hPQ"},"\u4f60\u4e5f\u662f\u4e1a\u52a1\u5f00\u53d1\uff1f\u63d0\u524d\u7528\u8fd9\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u9884\u9632\u4ea7\u54c1\u52a0\u9700\u6c42\u5427")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IQsojcdwLZ1g0TgVQDoqVw"},"Go \u7a0b\u5e8f\u91cc if else \u5206\u652f\u592a\u591a\uff1f\u8bd5\u7740\u7528\u7b56\u7565\u6a21\u5f0f\u6cbb\u7406\u4e00\u4e0b\u5427")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-Ysho1jI9MfrAIrplzj7UQ"},"\u7528Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f-\u63d0\u70bc\u6d41\u7a0b\uff0c\u51cf\u5c11\u91cd\u590d\u5f00\u53d1\u5c31\u9760\u5b83\u4e86!")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cAwc6ZhdUwxkI5VT8LY9Hg"},"Go Gin\u6846\u67b6\u8bf7\u6c42\u81ea\u52a8\u9a8c\u8bc1\u548c\u6570\u636e\u7ed1\u5b9a\uff0c\u770b\u5b8c\u8fd9\u7bc7\u5c31\u4f1a\u7528\u4e86")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Uu3EAWpRO9pSbg1F1DLa_w"},"Go\u5f00\u6e90\u5e93\u3001\u5927\u9879\u76ee\u7684\u516c\u5171\u5305\uff0c\u662f\u8fd9\u4e48\u7528\u5efa\u9020\u8005\u6a21\u5f0f\u7684")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/y1qHsQNR7EWeDU5g60Loqg"},"Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u539f\u578b\u6a21\u5f0f\u7684\u8003\u67e5\u70b9\u548c\u4f7f\u7528\u63a8\u8350")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MlC6-TDf06LGpF8hxcSV_w"},"\u5de5\u5382\u6a21\u5f0f\u6709\u4e09\u4e2aLevel\uff0c\u4f60\u80fd\u7528Go\u5199\u5230\u7b2c\u51e0\u5c42")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1ZuhUA9Lt2uLFlamIY6fLQ"},"\u6700\u7b80\u5355\u7684\u5355\u4f8b\u6a21\u5f0f\uff0cGo\u7248\u672c\u7684\u5b9e\u73b0\u4f60\u5199\u5bf9\u4e86\u5417")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OKUeAdicn0Bvkz8dYx1epQ"},"\u62d2\u7edd Go \u4ee3\u7801\u81c3\u80bf\uff0c\u5176\u5b9e\u5728\u8fd9\u51e0\u5757\u53ef\u4ee5\u7528\u4e0b\u89c2\u5bdf\u8005\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SpVTl64W1Exy8fuN15-kmA"},"Go\u6307\u9488\u7684\u4f7f\u7528\u9650\u5236\u548c\u7a81\u7834\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TtN6NZ8hQ2AIf0C8wVzkjA"},"Go\u8bed\u8a00\u7684IO\u5e93\u90a3\u4e48\u591a\uff0c\u6211\u8be5\u600e\u4e48\u9009")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gYWhjh1BburgeAU72mn_aw"},"Go \u773c\u4e2d\u7684\u6587\u4ef6\u7cfb\u7edf\u662f\u4ec0\u4e48\uff1f io.FS")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zJXPGYwNXIUyEOI0Kc15rg"},"\u51e0\u4e2a\u63d0\u5347Go\u8bed\u8a00\u5f00\u53d1\u6548\u7387\u7684\u5c0f\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg"},"\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Elq7SWRpH08KmhX7auboOA"},"Gophers\u5982\u4f55\u51c6\u5907\u9762\u8bd5")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FEPXDMFfvKgmtsymVTWzHw"},"Go Modules\u77e5\u8bc6\u70b9\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147939014870302756"},"\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7131717990558466062"},"GO\u9762\u8bd5\u5fc5\u77e5\u5fc5\u4f1a\u9762\u8bd5\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kyGNVNDby5uq5JGfQt4Yrg"},"\u8fd9\u4e9b\u6700\u5e38\u7528\u7684 Go CLI \u547d\u4ee4\uff0c\u65b0\u624b Gopher \u5e94\u8be5\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7uobN6DmpIYqG34pOpvvlA"},"PGO \u662f\u5565\uff0c\u548b\u5c31\u8ba9 Go \u66f4\u5feb\u66f4\u731b\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Pcp2FjcXk7Q7sV0Z-bEUNw"},"Go for \u5faa\u73af\u6709\u65f6\u5019\u771f\u7684\u5f88\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6KxJRG3lKUDY734t4EzAaA"},"\u6df1\u5ea6\u89e3\u5bc6Go\u8bed\u8a00\u4e4b\u5173\u4e8e interface \u7684 10 \u4e2a\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qyEiEACuUd8SsyqCDLUjXA"},"\u624b\u64b8\u6e90\u7801\u7cfb\u5217 - cache2go")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nc4s289ULpQkGlQuaFbZlQ"},"Go\u5e38\u89c1\u9519\u8bef\u96c6\u9526\u4e4b\u51fd\u6570\u5f0f\u9009\u9879\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/THMhcM9TXydW8K5-Vvqvxg"},"\u8be6\u89e3\u5e76\u53d1\u7f16\u7a0b\u57fa\u7840\u4e4b\u539f\u5b50\u64cd\u4f5c(atomic\u5305)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/E2XwSIXw1Si1EVSO1tMW7Q"},"\u5b66\u4e60channel\u8bbe\u8ba1\uff1a\u4ece\u5165\u95e8\u5230\u653e\u5f03")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lJxjlDg5SkQyNLZBpOPP5A"},"context\u4f7f\u7528\u4e0d\u5f53\u5f15\u53d1\u7684\u4e00\u4e2abug")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/S_EzyWZmFzzbBbxoSNe6Hw"},"Go\u8bed\u8a00\u5982\u4f55\u5b9e\u73b0\u53ef\u91cd\u5165\u9501")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zlqZ-4EdzMNt3iubMknKLA"},"\u5982\u4f55\u5728\u6d4b\u8bd5\u4e2d\u53d1\u73b0goroutine\u6cc4\u6f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JC14dWffHub0nfPlPipsHQ"},"\u8bf7\u52ff\u6ee5\u7528goroutine")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bhze_LcFHk7Y-QB4nEQKnA"},"\u9762\u8bd5\u5b98\uff1a\u54e5\u4eecGo\u8bed\u8a00\u4e92\u65a5\u9501\u4e86\u89e3\u5230\u4ec0\u4e48\u7a0b\u5ea6\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/E45dNnEURe87P709Ovu-Qw"},"Go\u5de5\u5177\u4e4bgenerate")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dN9G4Tnt9HgVqlNh73HNUQ"},"\u63a2\u7a76 Go \u6e90\u7801\u4e2d panic & recover \u6709\u54ea\u4e9b\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Wdh2O4cnez95x0RBpMiDvQ"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#41 substrings and memory leaks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/39S-WWKt1rYNF9OUfFSCbw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#38 Misusing trim functions")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/m0WyJyd2JwQfX1SP2H-jrA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#37 Inaccurate string iteration")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P6rEyeLvl8gxT_4RJf235Q"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#36 Not understanding the concept of a rune")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ls1_qaEnuc8MSZoDyTwa1Q"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#35 Using defer inside a loop")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XRQq1O9VROBxItSP4kC8zA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#34 Ignoring how the break statement works")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/gwsWE-NTBOs0NnsdNG4WBw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#33 Making wrong assumptions during map iterations")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/58EVYGZ02xPfGYrprk7dRw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#32 Ignoring the impact of using pointer ...")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cuJAYXGOleUt0FG5brX8ng"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#31 Ignoring how arguments are evaluated in ...")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/71wpR1kz5PgzVNBgpN855g"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#30 Ignoring the fact that elements are copied")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fpHMk37QGLQCXrPAdxXC_w"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#29 Comparing values incorrectly")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/s5-Pl5u6yoZCPWwoeINs9g"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#28 maps and memory leaks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9pfznxXKHCv-QEZBqHw1YQ"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#27 Inefficient map initialization")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/TYxqo1BniI-wfKVHQsrjjw"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#26 slices and memory leaks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lAIB0l666R6Zh9NAdV809g"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#25 Unexpected side effects using slice append")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vZBePdCuKe12OMQOj6Rz4A"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#24 Not making slice copies correctly")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WsFGv9tcdRLP9K-NQSqimA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#23 Not properly checking if a slice is empty")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uHmCU0v0xJ2RYlmq_lQAiQ"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#22 Being confused about nil vs. empty slices")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-Kt2QJdzEUDJx8MFvrUo7Q"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#20 Not understanding slice length and capacity")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/epK_0yn_EPIWJjz9xmddcA"},"Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#12 Project misorganization")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/teivah/100-go-mistakes"},"100 Go Mistakes and How to Avoid Them")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aj_hULmeqy3whILr2ytECQ"},"Go \u4e2d\u57fa\u4e8e IP \u5730\u5740\u7684 HTTP \u8bf7\u6c42\u9650\u6d41")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pe0CQa3tdrUmC86OSRBNeg"},"\u9879\u76ee\u5b9e\u6218\uff1a\u7528 Go \u521b\u5efa\u4e00\u4e2a\u7b80\u6613\u8d1f\u8f7d\u5747\u8861\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tloEYzrnKNrrAo1YKdeyrw"},"\u4f60\u77e5\u9053\u51e0\u79cdGo\u5e76\u53d1\u63a7\u5236\u65b9\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/H5HDrwhxZ_4v6Vf5xXUsIg"},"\u6d45\u8c08Golang\u4e24\u79cd\u7ebf\u7a0b\u5b89\u5168\u7684map")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YYvoeDfPMm8Y2kFu9uesGw"},"Go\u7cbe\u5999\u7684\u4e92\u65a5\u9501\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/CEIQUa7H43FR7M1ghkDSGg"},"Go\u66f4\u7ec6\u7c92\u5ea6\u7684\u8bfb\u5199\u9501\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Mro5XC8dS5ZAMvEVbJZsCw"},"Go \u7684 TryLock \u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/oA6UJ-0R2OucFl-fbgrvWA"},"Go1.18 \u65b0\u7279\u6027\uff1aTryLock \u662f\u4ec0\u4e48\uff1f\u9700\u8981\u5b83\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/V2x0Nw3Y8lZxHYJh_yQ0dQ"},"Go\u4e2d\u770b\u4f3c\u7b80\u5355\u7684WaitGroup\u6e90\u7801\u8bbe\u8ba1\uff0c\u7adf\u7136\u6697\u542b\u8fd9\u4e48\u591a\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Lsm-BMdKCKNQjRndNCLwLw"},"Go \u6807\u51c6\u5e93\u6e90\u7801\u5b66\u4e60\uff08\u4e00\uff09\u8be6\u89e3\u77ed\u5c0f\u7cbe\u608d\u7684 Once")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3VkcIg7NhCCiIwVRjuwR0A"},"Go \u4e2d\u4e3a\u4ec0\u4e48\u5efa\u8bae\u4f7f\u7528 NewXxx \u8fd9\u6837\u7684\u6784\u9020\u51fd\u6570")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/nA26g46tM_hu-khaGYniAQ"},"Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KHzdEE_w_ev9p4v6MR7M8Q"},"\u600e\u4e48\u9009\u62e9 Go \u6587\u4ef6\u8bfb\u53d6\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EeOxPkTe8WkOide49yIfEg"},"\u5982\u4f55\u6709\u6548\u63a7\u5236 Go \u7ebf\u7a0b\u6570")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OIqgqjXEvVmDUmnRqq4PGw"},"\u52a0\u5927\u529b\u5ea6\uff01Go \u5c06\u4f1a\u589e\u5f3a Go1 \u5411\u540e\u517c\u5bb9\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ucqqg4h9uRo7RVd8XCz80w"},"Go \u7684\u96f6\u503c\u6709\u4ec0\u4e48\u7528\uff1f\u770b\u770b\u8fd9 4 \u4e2a\u573a\u666f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/L_Sy4_6BURL4XWDK6bpEwg"},"Go \u53ea\u4f1a if err != nil\uff1f\u8fd9\u662f\u4e0d\u5bf9\u7684\uff0c\u5206\u4eab\u8fd9\u4e9b\u4f18\u96c5\u7684\u5904\u7406\u59ff\u52bf\u7ed9\u4f60\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cJON1H68eBFeuBpWhFbXXw"},"10+ \u6761 Go \u5b98\u65b9\u8c1a\u8bed\uff0c\u4f60\u77e5\u9053\u51e0\u6761\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xDXwsVjOfU2j3gisiHTZTQ"},"Go \u9002\u5408 IO \u5bc6\u96c6\u578b\uff1f\u5e76\u4e0d\u51c6\u786e\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fzmN6zFVioQGedTdSDmyqQ"},"\u5982\u4f55\u8ba9 Go \u53cd\u5c04\u53d8\u5feb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/y60q0-RMh8isd4u4PuLfUg"},"\u6df1\u5165\u7406\u89e3StatefulSet\uff0c\u7528Kubernetes\u7f16\u6392\u6709\u72b6\u6001\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903433846145038"},"Go Modules \u7ec8\u6781\u5165\u95e8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7075098594151235597"},"\u975e\u5e38\u9002\u5408PHP\u540c\u5b66\u4f7f\u7528\u7684GO\u6846\u67b6\uff1aGoFrame")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EGN7G8ku-zkaZuzfBwx9Qw"},"\u770b Go \u4e2d\u7684 struct \u5982\u4f55\u88ab\u4f18\u5316\uff0c\u8fd8\u6709\u5c0f\u63d2\u66f2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Qlqt1pP_Li-PxOICrz7bAw"},"\u5728 Go \u91cc\u7528 CGO\uff1f\u8fd9 7 \u4e2a\u95ee\u9898\u4f60\u8981\u5173\u6ce8\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Am0ORd08GsMc4xSdLG9kgg"},"Go \u63a2\u8ba8\u4e86 13 \u5e74\uff0c\u600e\u4e48\u89e3\u51b3\u518d\u8d4b\u503c\u7684\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7134497015576133669"},"Go\u5982\u4f55\u4f18\u96c5\u7684\u8bb0\u5f55\u64cd\u4f5c\u65e5\u5fd7 | \u51b2\u523a\u6398\u91d1\u4e00\u5468")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0c7emt54ayCrm1K16lk2SQ"},"\u5982\u4f55\u66f4\u76f4\u89c2\u5730\u7406\u89e3 Go \u8c03\u5ea6\u8fc7\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FviFOLkIHuEjZdTg_qCoNQ"},"Go1.19 \u90a3\u4e9b\u4f60\u4e0d\u77e5\u9053\u7684\u65b0\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SrqJdng9cNUEVAS7nFaqAA"},"Go \u4e2d\u53ef\u522b\u7528\u590d\u5236\u9501\uff0c\u4f1a\u6709\u8fd9\u4e9b\u5927\u95ee\u9898\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zyvO_hhUo1TRm6kMPcaFFQ"},"\u4f19\u8ba1\uff0cGo\u9879\u76ee\u600e\u4e48\u4f7f\u7528\u679a\u4e3e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XPPwHd7eDUjvzsnuFwgbyw"},"Go ORM \u5355\u5143\u6d4b\u8bd5\u5168\u6d41\u7a0b\u8bb2\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/r30z2i_sSuRfEnM_23wFlg"},"\u8d85\u5168\u603b\u7ed3\uff1aGo\u8bed\u8a00\u5982\u4f55\u64cd\u4f5c\u6587\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HaF9qieEJWNUoyY9qTvnKw"},"Go \u7684\u65f6\u95f4\u8f6c\u6362\u548c\u65f6\u533a\u6821\u5bf9\u603b\u8bb0\u4e0d\u4f4f\uff1f\u7ed9\u4f60\u4e00\u4efd\u5907\u5fd8\u5355")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ptJK7CDHCr6P4JCdsUXKdg"},"\u641e\u6e05\u695a Go Mod\u7684\u7248\u672c\u548c\u4f2a\u7248\u672c\uff0c\u4e0b\u6b21\u522b\u4e71\u7528\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7jLmwtP3xk-wbCFKqPLK2g"},"\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u5982\u4f55\u53d1\u5e03\u5230Go Module\u4e0a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Dn2oM89mHEgoz8yVQnNEoQ"},"\u8fd9\u4e0d\u4f1a\u53c8\u662f\u4e00\u4e2aGo\u7684BUG\u5427")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/YojNHW7kkjmmdjqBXCuQYA"},"\u8fd9\u4e09\u4e2a Go \u6c34\u5e73\u81ea\u6d4b\u9898\uff0c\u624b\u5199\u4e0d\u51fa\u6765\u8fd8\u662f\u5148\u8001\u5b9e\u4e0a\u73ed\u5427")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pR_XHTnhft2Hi_mY7JuEJg"},"\u4e0d\u60f3Go \u9519\u8bef\u5904\u7406\u592a\u81c3\u80bf\uff0c\u53ef\u4ee5\u53c2\u8003\u8fd9\u4e2a\u4ee3\u7801\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HuZn9hnHUBx3J4bAGYBYpw"},"\u5173\u4e8eGo\u7a0b\u5e8f\u9519\u8bef\u5904\u7406\u7684\u4e00\u4e9b\u5efa\u8bae")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u90e8\u7f72",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4f7f\u7528 Docker Desktop \u642d\u5efa k8s \u96c6\u7fa4"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MFd1R5VeEW0eLk-A4BqSQQ"},"\u5929\u5450\uff01\u6211\u7528 go \u4ece\u96f6\u5f00\u59cb\u5199\u4e86\u4e00\u4e2a k8s \u5e94\u7528\u7ba1\u7406\u5de5\u5177\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u548c\u5f00\u53d1\u8fc7\u7a0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg"},"Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/i3n0hoHRaYoDMWcC5DSQ3w"},"\u638c\u63e1\u4e86\u8fd9\u7bc7 Dockerfile \u4e2d\u7684 ARG \u4f5c\u7528\u57df\uff0c \u5c31\u7b97 Build \u955c\u50cf CI \u5165\u95e8\u4e86 \u3010\u6587\u672b\u62bd\u5956\u3011")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pen6G2aFsPfSqhKjgocVjQ"},"\u9762\u8bd5\u95ee Dockerfile \u7684\u4f18\u5316\uff0c \u5343\u4e07\u4e0d\u8981\u53ea\u4f1a\u8bf4\u51cf\u5c11\u5c42\u6570")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/10Ll8ipVGWg4HU4hjwILsQ"},"\u6ca1\u60f3\u5230\u5728 Docker \u5bb9\u5668\u4e2d\u8bbe\u7f6e\u65f6\u533a\u8fd9\u4e48\u7b80\u5355")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5NTgcdhn6CiZ2tg44_T-FQ"},"\u5feb\u6536\u85cf\uff01\u8d85\u5f3a\u56fe\u89e3Docker\u5e38\u89c1\u547d\u4ee4\u4e0e\u5b9e\u6218\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rDSKItZ8hvgjvpp4f4VzCQ"},"\u5b9e\u65f6\u53ef\u89c6\u5316Go Runtime\u6307\u6807\uff0c\u8fd9\u4e2aGo\u5e93\u8d85\u8d5e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg"},"\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DEZPCzQul7wnZKqm1Ue6rg"},"\u4eceGo\u7a0b\u5e8f\u7b2c\u4e00\u884c\u4ee3\u7801\uff0c\u5230\u5728 K8s \u4e0a\u8fd0\u884c\uff0c\u8981\u7ecf\u5386\u591a\u5c11\u6b65")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZU61NIMxh_UOo-chNvkPXA"},"\u5728K8S\u4e0a\u7684Web\u670d\u52a1\u8be5\u600e\u4e48\u505a\u57df\u540d\u89e3\u6790\u5462")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/"},"https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uruu3qbpSLbTRJJRcWTYqg"},"Kubernetes\u5165\u95e8\u5b9e\u8df5--\u90e8\u7f72\u8fd0\u884cGo\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hoJgL-sP2OtMEFAhYNCItA"},"\u7ebf\u4e0aGo\u9879\u76ee\u7684Docker\u955c\u50cf\u5e94\u8be5\u600e\u4e48\u6784\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.opskumu.com/docker.html"},"Docker \u5b66\u4e60\u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Ze096f0Utcl84c6gBwrCYw"},"\u7a0b\u5e8f\u89e3Bug\u6700\u5e38\u7528\u7684K8s\u547d\u4ee4\uff0c\u5916\u52a0\u4f7f\u7528\u7a8d\u95e8")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u5f00\u6e90\u5e93\u63a8\u8350",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/J6ziP7VOitGk-lz8NGdDrA"},"HTTP \u6846\u67b6 Hertz \u5b9e\u8df5\u5165\u95e8\uff1a\u6027\u80fd\u6d4b\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124337913352945672"},"\u5b57\u8282\u5f00\u6e90WEB\u6846\u67b6Hertz\u592a\u9999\u5566\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7153889167385526308"},"\u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/cloudwego/hertz"},"https://github.com/cloudwego/hertz")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.cloudwego.io/blog/2021/10/09/bytedance-practices-on-go-network-library/"},"ByteDance Practices on Go Network Library")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.cloudwego.io/docs/hertz/getting-started/"},"https://www.cloudwego.io/docs/hertz/getting-started/")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/025-MLMAbdT38kWI--AoYg"},"Go \u8bed\u8a00\u7ec8\u6781\u641c\u7d22\u63d2\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ie7LqXZQOUX0Bfn4QhHzLA"},"\u300cGo\u5f00\u6e90\u5305\u300dsnappy\uff1agoogle\u5f00\u6e90\u7684\u5feb\u901f\u3001\u65e0\u635f\u538b\u7f29\u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Vkx8zzm1SjIl4IXLib3xkQ"},"\u300cGo\u5f00\u6e90\u5305\u300dxxhash\uff1a\u6bd4\u6807\u51c6\u5e93\u66f4\u5feb\uff0c\u57fa\u4e8exxHash\u7b97\u6cd5\u5b9e\u73b0\u768464\u4f4d\u7684\u6574\u578bhash\u503c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xt0v6snX6y5jaOy1IniwVw"},"\u300cGo\u5f00\u6e90\u5305\u300denv\uff1a\u4e00\u4e2a\u5c06\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u89e3\u6790\u5230\u7ed3\u6784\u4f53\u7684\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rGPsEt-XDOayDWwLGxvcsw"},"\u300cGo\u5f00\u6e90\u5305\u300dchromedp\uff1a\u4e00\u4e2a\u57fa\u4e8eChrome DevTools\u534f\u8bae\u7684\u5e93\uff0c\u652f\u6301\u6570\u636e\u91c7\u96c6\u3001\u622a\u53d6\u7f51\u9875\u957f\u56fe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7248951438742339639"},"\u300cGo\u5f00\u6e90\u5305\u300dnunu\uff1a\u4e00\u4e2a\u5feb\u901f\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u811a\u624b\u67b6")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_TBmfaVwvX5VDRe8kLReXA"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Shopify \u51fa\u54c1\u7684\u5b8c\u6574\u5ea6\u6700\u5b8c\u5584\u7684 Kafka \u5ba2\u6237\u7aef_sarama")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iHIxsEZf3w06GbO2sHSuRA"},"\u300cGoCN\u9177Go\u63a8\u8350\u300dGolang\u7684Ealstic\u94fe\u63a5\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wGqwfX8lEifeD_VGcITmHw"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u534f\u7a0b\u6c60ants\u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2cERDCRKlmfHKv8gY324Hg"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528 cmux \u5b9e\u73b0\u670d\u52a1\u7aef\u8fde\u63a5\u591a\u8def\u590d\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dkbpIvy1o5aLnklt0ddIDA"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528GO\u8bed\u8a00\u542f\u52a8docker Container")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/uLpmEV8mI4JpfNVfSK8cRQ"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u62bd\u8c61\u8bed\u6cd5\u6811go/ast\u5e93\u4f7f\u7528")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/weT4KUTTLWdQaC6q7VrPPg"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4e07\u80fd\u7684\u5bf9\u8c61\u62f7\u8d1d\u5de5\u5177\u2014\u2014Copier")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/q3wRIvoXpnPLPJsDAPTdeA"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u6f0f\u6876\u9650\u6d41\u5e93 \u2014 uber-go/ratelimit")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/emNifkcdn9oRjVHRcQmK9w"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u65f6\u95f4\u8f6e\u7b97\u6cd5\u5b9a\u65f6\u5668antlabs/timer\u4ecb\u7ecd")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3iPqxiK2mf9Fl5CSZ9U7RQ"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Goroutine \u6cc4\u6f0f\u9632\u6cbb\u795e\u5668 goleak")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SWyMIE1rtVDVUPEFno4xsQ"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011\u5f02\u6b65\u4efb\u52a1\u961f\u5217Asynq")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X6Fo_6pEZTIZJ-1MJNrg6A"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011protobuf\u751f\u6210Go\u4ee3\u7801\u63d2\u4ef6gogo/protobuf")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZoVr9ubPgcvjX9ERiQoLyA"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Golang\u5b98\u65b9\u8ba4\u53ef\u7684websocket\u5e93-gorilla/websocket")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JrEQwQZQRwf4SymprwKUmw"},"\u3010GoCN\u9177Go\u63a8\u8350\u3011Html\u89e3\u6790\u5229\u5668-goquery\u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zRmAjQ0o9n8FE1R0WcnUtQ"},"\u300cGoCN\u9177Go\u63a8\u8350\u300d\u9ad8\u6027\u80fd\u4e2d\u6587\u5206\u8bcd\u5e93 gojieba")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8YRqypiW1dQQVlZkmCd1mQ"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u89e3\u6790http\u4e2d\u7684user-agent\uff0c\u5c31\u7528\u8fd9\u4e2a\u5305\uff1auser_agent")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/92O1SHs4tw1FMcDeQoSfkA"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u63a8\u8350\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u3001\u8bed\u4e49\u5316\u7684\u65f6\u95f4\u5904\u7406\u5e93\uff1acarbon")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/n-kU6nwhOH6ouhufrP_1kQ"},"Go\u6bcf\u65e5\u4e00\u5e93\u4e4bCSRF\u5e93\u7684\u4f7f\u7528\u65b9\u5f0f\u548c\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/f4FAt-RgraOFXSfZmWjeoQ"},"Go \u6bcf\u65e5\u4e00\u5e93\u4e4b go-cache \u7f13\u5b58")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KCj-mCkZpcEu3GXkuRLTuA"},"\u300cGo\u5de5\u5177\u7bb1\u300dredis\u5b98\u7f51\u63a8\u8350\u7684go\u7248\u672c\u7684\u5206\u5e03\u5f0f\u9501\uff1aredsync")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/samber/lo"},"https://github.com/samber/lo")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/nikoksr/notify"},"https://github.com/nikoksr/notify")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-chi/chi"},"https://github.com/go-chi/chi")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/gin-gonic/examples"},"https://github.com/gin-gonic/examples")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zLNwq32UKaCsaAXn2BaZkw"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u91cd\u78c5\u63a8\u8350\uff1a\u4e00\u4e2a\u56fd\u4ea7\u7684\uff0cstar\u9ad8\u8fbe12k+\u7684\u64cd\u4f5cexcel\u7684\u5305\uff1aExcelize")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Y3NGQH3hrT85O7aN7IrCIQ"},"\u300cGo\u5de5\u5177\u7bb1\u300d\u4e00\u4e2a\u8ba9\u7ec8\u7aef\u5185\u5bb9\u5f69\u8272\u5316\u7684\u5de5\u5177\uff1aColor")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u76f8\u5173\u8d44\u6e90",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://research.swtch.com/"},"Russ Cox \u7684\u4e2a\u4eba\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://tonybai.com/articles/"},"Tony Bai \u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://gopherdaily.tonybai.com/"},"Gopher Daily")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://xargin.com/"},"ChatGPT \u4e0e\u6211\u5408\u529b\u5f00\u53d1 xargin blog archive \u63d2\u4ef6\uff1a\u66f9\u5927\u535a\u5ba2\u7684\u65b0\u5947\u63a2\u9669")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://qcrao.com/"},"qcrao \u7684\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang-design/go-questions"},"Go \u7a0b\u5e8f\u5458\u9762\u8bd5\u7b14\u8bd5\u5b9d\u5178")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/gopl-zh/"},"Go\u8bed\u8a00\u5723\u7ecf\uff08\u4e2d\u6587\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"http://books.studygolang.com/The-Golang-Standard-Library-by-Example/"},"Go\u8bed\u8a00\u6807\u51c6\u5e93\u4e66\u7c4d")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.topgoer.cn/"},"\u5730\u9f20\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.topgoer.cn/docs/golang/golang-1ccjbpfstsfi1"},"go\u8bed\u8a00\u4e2d\u6587\u6587\u6863 - \u5730\u9f20\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://go-proverbs.github.io/"},"Go \u5b98\u65b9\u8c1a\u8bed Go Proverbs")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/cidtQEAfuFWuYveKFbFvKQ"},"GoLand 2023.2 \u53d1\u5e03\uff1a\u6709 AI \u52a9\u624b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/SVMj-PvI1l-oSlxI4zaNcw"},"GoLand 2023.1 \u6b63\u5f0f\u53d1\u5e03\uff0c\u770b\u6709\u54ea\u4e9b\u65b0\u529f\u80fd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/IvL24_7iuuRp9Y3dljHaHQ"},"GoLand \u8fce\u6765\u4e94\u5468\u5e74\uff0c\u540c\u65f6\u53d1\u5e03 2022.3\uff1a\u6709\u5f69\u86cb")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w"},"\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw"},"\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/Alikhll/golang-developer-roadmap"},"golang-developer-roadmap: 2020 \u5e74\u6210\u4e3a Go \u5f00\u53d1\u8005\u7684\u8def\u7ebf\u56fe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-admin-team/go-admin"},"go-admin: \u57fa\u4e8e Gin + Vue + Element UI \u7684\u72ec\u7acb\u524d\u540e\u7aef\u6743\u9650\u7ba1\u7406\u7cfb\u7edf\u7684\u811a\u624b\u67b6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/avelino/awesome-go"},"awesome-go: \u7cbe\u9009\u7684 Go \u6846\u67b6\u3001\u5e93\u548c\u8f6f\u4ef6\u7684\u5217\u8868")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/wKxg6IVZCNK3NG2Os9_3jg"},"Go 13 \u5468\u5e74\u5566\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ"},"\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://golangbyexample.com/"},"Golang By Example")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://golangbyexample.com/golang-comprehensive-tutorial/"},"Golang Advanced Tutorial")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://golangbyexample.com/all-design-patterns-golang/"},"All Design Patterns in Go (Golang)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://techbyexample.com/system-design-questions/"},"System Design Questions")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.gokit.info/post/go-solid-design/"},"SOLID Go Design - Go\u8bed\u8a00\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/mohuishou/go-design-pattern"},"go design pattern")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XIwfj_AdZqX_vHM4VIq9EA"},"\u4e07\u5b57\u8be6\u6587\u9610\u91ca\u7a0b\u5e8f\u5458\u4fee\u70bc\u4e4b\u9053")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/c3RApB8a98tWahgC9mahJg"},"\u4e07\u5b57\u8be6\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u505a Code Review")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/talkgo/read"},"Go \u5b66\u4e60\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ipbUy3GBRMFat9jUSssMMw"},"1024\uff0c\u6211\u4eec\u7684\u8282\u65e5\uff0cGopher \u8be5\u5e72\u70b9\u5565"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/qyuhen/go"},"Go \u8bed\u8a00\u5b66\u4e60\u7b14\u8bb0")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/GoExpertProgramming/"},"GO\u4e13\u5bb6\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://go101.org/article/101.html"},"Go \u8bed\u8a00 101")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://go101.org/optimizations/101.html"},"Go Optimizations 101")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/"},"\u5f00\u6e90\u56fe\u4e66\u5728\u7ebf\u9605\u8bfb - Go\u8bed\u8a00\u4e2d\u6587\u7f51")))),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/go-interview/set/xq5788"},"Go Interview")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/halfrost/LeetCode-Go"},"LeetCode Cookbook")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.halfrost.com/leetcode/"},"LeetCode Cookbook\uff08\u5728\u7ebf\u9605\u8bfb\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-compile-intro/"},"Go \u8bed\u8a00\u8bbe\u8ba1\u4e0e\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://books.studygolang.com/advanced-go-programming-book/"},"Go\u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b(Advanced Go Programming)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/geektutu/high-performance-go"},"Go \u8bed\u8a00\u9ad8\u6027\u80fd\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/golang-design/under-the-hood"},"Go \u8bed\u8a00\u539f\u672c")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://golang.design/under-the-hood/"},"Go \u8bed\u8a00\u539f\u672c\uff08\u5728\u7ebf\u9605\u8bfb\uff09")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://time.geekbang.org/column/intro/100093501"},"Tony Bai \xb7 Go \u8bed\u8a00\u7b2c\u4e00\u8bfe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://time.geekbang.org/column/intro/100061801"},"Go \u5e76\u53d1\u7f16\u7a0b\u5b9e\u6218\u8bfe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://time.geekbang.org/column/article/408409"},"Rust \u7f16\u7a0b\u7b2c\u4e00\u8bfe")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://quickref.me/go"},"Go cheatsheet")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/miguelmota/golang-for-nodejs-developers"},"Golang for Node.js Developers")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://studygolang.gitbook.io/learn-go-with-tests"},"Learn Go with tests")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1f ",(0,n.kt)("a",{parentName:"li",href:"https://makeoptim.com/golang/standards/project-layout"},"golang \u7f16\u7a0b\u89c4\u8303 - \u9879\u76ee\u76ee\u5f55\u7ed3\u6784")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/talkgo/night"},"Go \u591c\u8bfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/VKPSqS50Un29x30KIgB0tA"},"\u5df2\u5165\u5b57\u8282\u7684\u5927\u4f6c\u5404\u5382\u4e09\u5e74Go\u9762\u7ecf")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u7b97\u6cd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fangbinwei/algorithm-practice"},"https://github.com/fangbinwei/algorithm-practice")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u9879\u76ee\u53c2\u8003",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/wangzhongyang007/goframe-shop-v2"},"https://github.com/wangzhongyang007/goframe-shop-v2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/fangbinwei/aliyun-oss-website-action"},"https://github.com/fangbinwei/aliyun-oss-website-action")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u6559\u7a0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.w3cschool.cn/go/"},"https://www.w3cschool.cn/go/")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u6807\u51c6\u5e93\u6587\u6863",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://pkg.go.dev/std"},"https://pkg.go.dev/std")))),(0,n.kt)("li",{parentName:"ul"},"Golang \u5355\u5143\u6d4b\u8bd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/ALEX_CYL/article/details/121793330"},"Golang-\u5355\u5143\u6d4b\u8bd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/377834750"},"\u624b\u628a\u624b\u6559\u4f60\u5982\u4f55\u8fdb\u884c Golang \u5355\u5143\u6d4b\u8bd5")))),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/471317280"},"Go \u8bed\u8a00\u4e0e\u5e76\u53d1\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Xzlt_WcdcfLWhofafY3c6g"},"Golang \u7b80\u6d01\u67b6\u6784\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7065197280223035422"},"\u5982\u4f55\u4f7f\u7528\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\u63d0\u5347\u4ee3\u7801\u7684\u7b80\u6d01\u6027")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/36CqC1U54LUd4-izt4iZ1g"},"\u6df1\u5165\u7406\u89e3Go Json.Unmarshal\u7cbe\u5ea6\u4e22\u5931\u4e4b\u8c1c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/EvkMQCPwg-B0fZonpwXodg"},"Go Error \u5904\u7406\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000013739000"},"Golang \u65b0\u624b\u53ef\u80fd\u4f1a\u8e29\u7684 50 \u4e2a\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/437626980"},"Golang\u8bbe\u8ba1\u6a21\u5f0f\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/267341653"},"Golang \u5355\u5143\u6d4b\u8bd5\u6307\u5f15")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7041846339189080101"},"\u4f7f\u7528Golang\u3001Gin\u548cReact\u3001esbuild\u5f00\u53d1\u7684Blog")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/go-gorm/gorm"},"gorm - Golang \u7684\u51fa\u8272 ORM \u5e93")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/gofiber/fiber"},"fiber\uff1a\u53d7\u5230 Express \u542f\u53d1\u7684 Web \u5e94\u7528\u6846\u67b6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://go.dev/"},"Golang \u5b98\u65b9\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/426368274"},"Golang \u7f16\u7a0b\u601d\u7ef4\u548c\u5de5\u7a0b\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://gobyexample.com/"},"Go by example"))),(0,n.kt)("h2",{id:"rust-\u5b66\u4e60"},"Rust \u5b66\u4e60"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf"},"PDF\uff1a\u4ece JavaScript \u5230 Rust\uff1a\u65b0\u4e66\u514d\u8d39\u53d1\u5e03")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/google/comprehensive-rust"},"Google \u51fa\u54c1\u7684 Rust \u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://course.rs/about-book.html"},"Rust\u8bed\u8a00\u5723\u7ecf(Rust Course)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HKkt9cNZsUFdCR4nAlHeBA"},"\u63ed\u79d8\u524d\u7aef\u773c\u4e2d\u7684Rust\uff01")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/book/"},"Rust \u5b98\u65b9\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/std/"},"Rust \u6807\u51c6\u5e93\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://doc.rust-lang.org/stable/rust-by-example/"},"Rust by Example")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7143822279992934436"},"\u9009\u62e9 Go \u8fd8\u662f Rust\uff1fCloudWeGo-Volo \u57fa\u4e8e Rust \u8bed\u8a00\u7684\u63a2\u7d22\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/417534662"},"\u7528Rust\u9508\u5316Vue Compiler")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/TheAlgorithms/Rust"},"\u7528 Rust \u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5408\u8f91"))),(0,n.kt)("h2",{id:"\u7f51\u7ad9\u63a8\u8350"},"\u7f51\u7ad9\u63a8\u8350"),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u6587\u6863\u76f8\u5173")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/search?q=&type="},"GitHub \u641c\u7d22\u9875\u9762")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://developer.mozilla.org/zh-CN/"},"MDN \u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://caniuse.com/"},"caniuse\uff1a\u67e5\u8be2 API \u517c\u5bb9\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://snyk.io/advisor/"},"snyk\uff1a\u67e5\u8be2 NPM\u3001Go\u3001Docker \u5b89\u5168\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://bundlephobia.com/"},"bundlephobia\uff1a\u67e5\u8be2 NPM \u5305\u4f53\u79ef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://oscarotero.com/deno/"},"Deno cheat sheet")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://beta.reactjs.org/learn"},"React Docs Beta")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://overreacted.io/"},"Overreacted")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://tailwindcss.com/docs/configuration"},"tailwindcss \u6837\u5f0f\u53c2\u8003")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://explainshell.com/"},"Explain Shell")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://es6.ruanyifeng.com/"},"\u300a\u962e\u4e00\u5cf0 ES6 \u6559\u7a0b\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/yeasy/docker_practice"},"Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/koala-coding/goodBlog"},"\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fblog.poetries.top%2Fbrowser-working-principle%2F"},"\u300a\u6d4f\u89c8\u5668\u5de5\u4f5c\u539f\u7406\u4e0e\u5b9e\u8df5\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fwebpack.wuhaolin.cn%2F"},"\u300a\u6df1\u5165\u6d45\u51fa webpack\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fprogrammercarl.com%2F"},"\u300a\u4ee3\u7801\u968f\u60f3\u5f55\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fyuchengkai.cn%2F"},"\u300a\u524d\u7aef\u8fdb\u9636\u4e4b\u9053\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Freact.iamkasong.com%2F"},"\u300aReact \u6280\u672f\u63ed\u79d8\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/7kms/react-illustration-series"},"\u300a\u56fe\u89e3 React \u6e90\u7801\u7cfb\u5217\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fustbhuangyi.github.io%2Fvue-analysis%2Fv2%2Fprepare%2F"},"\u300aVue \u6280\u672f\u63ed\u79d8\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"http://caibaojian.com/vue-design/"},"\u300aVue\u6280\u672f\u5185\u5e55\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://i5ting.github.io/How-to-learn-node-correctly/"},"\u72fc\u53d4\uff1a\u5982\u4f55\u6b63\u786e\u7684\u5b66\u4e60Node.js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://q.shanyue.tech/engineering/"},"\u5927\u5382\u9762\u8bd5\u9898\u6bcf\u65e5\u4e00\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://shanyue.tech/op/#%E9%A2%84%E8%A7%88"},"\u524d\u7aef\u5de5\u7a0b\u5316\u3001\u4e2a\u4eba\u670d\u52a1\u5668\u8fd0\u7ef4\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://xiaoflyfish.cn/"},"MySQL\u3001Linux\u3001\u670d\u52a1\u7aef\u67b6\u6784")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://xcoder.in/"},"Khaidi Chu \u7684\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/chenyuntc/pytorch-book"},"\u300a\u6df1\u5ea6\u5b66\u4e60\u6846\u67b6PyTorch\uff1a\u5165\u95e8\u4e0e\u5b9e\u8df5\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/datawhalechina/pumpkin-book"},"\u300a\u673a\u5668\u5b66\u4e60\u300b\uff08\u897f\u74dc\u4e66\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Mh411e7VU"},"\u300a\u673a\u5668\u5b66\u4e60\u300b\u914d\u5957\u89c6\u9891\u6559\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://abseil.io/blog/04222021-swe-book"},"Software Engineering at Google")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/dair-ai/ML-YouTube-Courses"},"ML YouTube Courses")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/vasanthk/how-web-works"},"How Web Works"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u5f00\u6e90\u63a8\u8350")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://nextjs.org/docs/getting-started"},"Next.js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://tailwindcss.com/docs/configuration"},"tailwindcss \u6837\u5f0f\u53c2\u8003")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://pnpm.io/installation"},"PNPM")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.typescriptlang.org/docs/"},"TypeScript")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://vitejs.dev/"},"Vite")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://storybook.js.org/"},"Storybook"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u5728\u7ebf Plyaground")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://godbolt.org/"},"\u751f\u6210\u5404\u4e2a\u8bed\u8a00\u7684\u6c47\u7f16\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://sfc.vuejs.org/"},"Vue SFC Playground")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fcodesandbox.io%2Fdashboard%2Fhome"},"CodeSandBox")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://codepen.io/"},"CodePen")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.astexplorer.net/"},"AST explorer\uff1a\u53ef\u89c6\u5316 AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fjex.im%2Fregulex"},"\u6b63\u5219\u8868\u8fbe\u5f0f\u53ef\u89c6\u5316"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u7f16\u7a0b\u98ce\u683c\u6307\u5357")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/typescript-eslint/typescript-eslint"},"typescript-eslint")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/AlloyTeam/eslint-config-alloy"},"eslint-config-alloy")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/airbnb/javascript"},"Airbnb JavaScript Style Guide")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://github.com/ryanmcdermott/clean-code-javascript"},"clean-code-javascript"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u6280\u672f\u793e\u533a")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/"},"https://dev.to/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://medium.com/"},"https://medium.com/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://linuxhandbook.com/"},"https://linuxhandbook.com/"))),(0,n.kt)("p",null,(0,n.kt)("strong",{parentName:"p"},"\u5de5\u5177\u76f8\u5173")),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://plantuml.com/"},"plantuml\uff1a\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\u3001\u7528\u4f8b\u56fe\u3001\u7c7b\u56fe\u3001\u601d\u7ef4\u5bfc\u56fe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.npmjs.com/package/njt"},"njt\uff1a\u5feb\u901f\u5bfc\u822a\u81f3 npm \u5305\u8d44\u6e90")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.skypack.dev/"},"skypack\uff1a\u65e0\u9700\u6784\u5efa\u5de5\u5177\u4f7f\u7528\u5404\u79cd\u7ecf\u8fc7\u4f18\u5316\u7684 npm \u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://link.juejin.cn/?target=https%3A%2F%2Fcarbon.now.sh%2F"},"carbon\uff1a\u751f\u6210\u4ee3\u7801\u7247")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://unbug.github.io/codelf/"},"codelf \u53d8\u91cf\u547d\u540d\u795e\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://openbase.com/"},"openbase\uff1a\u67e5\u8be2\u5404\u79cd\u7b2c\u4e09\u65b9\u5e93"))),(0,n.kt)("h2",{id:"\u5b66\u4e60\u8d44\u6e90"},"\u5b66\u4e60\u8d44\u6e90"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"\u300aLinux Shell \u811a\u672c\u653b\u7565\uff08\u7b2c2\u7248\uff09\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300a\u63a8\u8350\u7cfb\u7edf\u2014\u2014\u6280\u672f\u3001\u8bc4\u4f30\u53ca\u9ad8\u6548\u7b97\u6cd5\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aGo \u8bed\u8a00\u7f16\u7a0b\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aGo \u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300a\u64cd\u4f5c\u7cfb\u7edf\u5bfc\u8bba\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aMySQL\u6280\u672f\u5185\u5e55\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u300aRedis\u8bbe\u8ba1\u4e0e\u5b9e\u73b0\u300b"),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA"},"\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1EW411u7th"},"\u3010\u8ba1\u7b97\u673a\u79d1\u5b66\u901f\u6210\u8bfe\u3011","[","40\u96c6\u5168/\u7cbe\u6821","]"," - Crash Course Computer Science")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1iW411d7hd"},"\u3010\u7cbe\u6821\u4e2d\u82f1\u5b57\u5e55\u30112015 CMU 15-213 CSAPP \u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf \u8bfe\u7a0b\u89c6\u9891"))),(0,n.kt)("h2",{id:"\u9762\u8bd5\u76f8\u5173"},"\u9762\u8bd5\u76f8\u5173"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ConardLi/awesome-coding-js"},"JS \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 - awesome-coding-js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/trekhleb/javascript-algorithms"},"JavaScript Algorithms and Data Structures")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023208826472005668"},"JavaScript\u7b97\u6cd5\u57fa\u7840\u53ca\u9762\u8bd5\u603b\u7ed3\uff081w1\u5b57\uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903929705136141"},"\u5982\u4f55\u5199\u51fa\u4e00\u4e2a\u60ca\u8273\u9762\u8bd5\u5b98\u7684\u6df1\u62f7\u8d1d?")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904118704668685"},"\u9762\u4e86\u51e0\u4e2a\u8bf4\u81ea\u5df1\u7cbe\u901a Vue \u7684\u540c\u5b66")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/xgangzai/article/details/120375992"},"\u9ad8\u9891react\u9762\u8bd5\u989820\u9053\uff08\u9644\u8be6\u89e3\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903885488783374"},"\u30101 \u6708\u6700\u65b0\u3011\u524d\u7aef 100 \u95ee\uff1a\u80fd\u641e\u61c2 80% \u7684\u8bf7\u628a\u7b80\u5386\u7ed9\u6211"))),(0,n.kt)("h2",{id:"-\u6398\u91d1\u5927\u4f6c\u6c47\u603b"},"\ud83d\udcd2 \u6398\u91d1\u5927\u4f6c\u6c47\u603b"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Vue \u6e90\u7801\u3001\u54cd\u5e94\u5f0f\u673a\u5236\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2330620350708823/posts"},"ssh")," \u3001",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2137106333044861/posts"},"\u9ec4\u8f76")),(0,n.kt)("li",{parentName:"ul"},"React \u8fdb\u9636\u7cfb\u5217\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2418581313687390/posts"},"\u6211\u4e0d\u662f\u5916\u661f\u4eba")),(0,n.kt)("li",{parentName:"ul"},"Webpack \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/1820446985555544/posts"},"Tecvan")),(0,n.kt)("li",{parentName:"ul"},"\u8bbe\u8ba1\u6a21\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/3544481219495806/posts"},"DYBOY")),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199\u6e90\u7801\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2295436011645655/posts"},"\u848b\u9e4f\u98de")," \u3001",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/1204720476893064/posts"},"\u524d\u7aef\u9633\u5149")),(0,n.kt)("li",{parentName:"ul"},"Webpack5\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/4300945218607197"},"\u6e05\u6c64\u997a\u5b50")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/703340610597064/posts"},"\u5bd2\u8349")),(0,n.kt)("li",{parentName:"ul"},"\u603b\u7ed3\u5927\u5e08\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2330620350432110/posts"},"JowayYoung")),(0,n.kt)("li",{parentName:"ul"},"\u6e90\u7801\u5206\u6790\uff1a\u82e5\u5ddd"),(0,n.kt)("li",{parentName:"ul"},"\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/1556564164489389/posts"},"shanyue")),(0,n.kt)("li",{parentName:"ul"},"CSS \u5404\u79cd\u7279\u6548\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/user/2330620350437678/posts"},"chokcoco")),(0,n.kt)("li",{parentName:"ul"},"Nodejs \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/people/liuyong25/posts"},"\u5929\u732a")),(0,n.kt)("li",{parentName:"ul"},"Umi \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/mdh/weekly/rhiudh"},"MDH \u524d\u7aef\u5468\u520a")),(0,n.kt)("li",{parentName:"ul"},"Antd\u3001Umi\u3001Node.js\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/antfe/featured/ys58hy"},"\u652f\u4ed8\u5b9d\u4f53\u9a8c\u79d1\u6280\u7cbe\u9009")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u3001\u5168\u6808\u6280\u672f\u4e13\u520a\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/column/ali-nanjing"},"\u963f\u91cc CCO \u4f53\u9a8c\u6280\u672f\u4e13\u520a")),(0,n.kt)("li",{parentName:"ul"},"Golang \u76f8\u5173\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/340814811"},"\u817e\u8baf\u6280\u672f\u5de5\u7a0b")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u88c5\u903c\u6280\u5de7108\u5f0f\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/u/king_hcj"},"\u72ec\u9493\u5bd2\u6c5f\u96ea")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u4e5d\u6761 bug \u5206\u4eab\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/u/lulu_up"},"lulu_up")),(0,n.kt)("li",{parentName:"ul"},"Vue3 \u6e90\u7801\u5171\u8bfb\uff1a",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1bS4y1T7ng"},"\u524d\u7aef\u6768\u6751\u957f")),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u5de5\u7a0b\u5316\u3001\u5b66\u4e60 Golang\uff1a\u6d1b\u7af9"),(0,n.kt)("li",{parentName:"ul"},"Node.js \u76f8\u5173\uff1a\u4e94\u6708\u541b")),(0,n.kt)("h2",{id:"-\u5f85\u5b66\u4e60\u5185\u5bb9"},"\ud83d\udcd2 \u5f85\u5b66\u4e60\u5185\u5bb9"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017360824939315207"},"babel\u6e90\u7801\u8be6\u89e3-v1.7.8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904094079926286"},"\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904116913700877"},"\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6889247428797530126"},"\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903783005175815"},"\u5982\u4f55\u5229\u7528lerna\u7ba1\u7406\u6a21\u5757")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6969544464113074189"},"\u57fa\u4e8e lerna \u7684\u591a\u5305 JavaScript \u9879\u76ee\u642d\u5efa\u7ef4\u62a4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903896767283207#heading-5"},"React\u6027\u80fd\u4f18\u5316\u5c0f\u8d34\u58eb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903929726107655"},"\u795e\u5947\u7684lambda\u8868\u8fbe\u5f0f\u2014\u2014\u51fd\u6570\u5f0f\u7f16\u7a0b\u5fc5\u5b66")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903954002739213"},"npm\u8fdb\u9636\u2014\u2014\u5982\u4f55\u62e5\u6709\u81ea\u5df1\u7684\u5305\u548c\u6d41\u7a0b\u81ea\u52a8\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904162124103693"},"React Hooks\u7684\u82b1\u6837\u73a9\u6cd5"),(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"useDark\uff0cuseClickOutside\uff0c\u5168\u5c40\u72b6\u6001\u7ba1\u7406"))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903845227659271"},"\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u8981\u80cc")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903825145511950"},"\u6211\u4eec\u6216\u8bb8\u4e0d\u9700\u8981 classnames \u8fd9\u4e2a\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7014431215302213668"},"\u56fd\u5e86\u7206\u809d\uff0c\u7528vite+vue3+ts\u5b9e\u73b0\u4e00\u4e2a\u7f51\u9875\u7248\u7684typora\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982192362583752741"},"\u624b\u6478\u624b\u6559\u4f60\u4f7f\u7528\u6700\u65b0\u7248husky(v7.0.1)\u8ba9\u4ee3\u7801\u66f4\u4f18\u96c5\u89c4\u8303")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7015476516196712462"},"\u5feb\u901f\u5165\u624bElectron\uff0c\u62e5\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u684c\u9762\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6945236994247098381"},"\u5728\u5927\u5382\u662f\u5982\u4f55\u9ad8\u6548\u7ec4\u7ec7 npm script \u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6940042028243746823"},"\u524d\u7aef\u5f00\u53d1\u8005\u5468\u520a\u7b2c\u4e09\u671f\uff1a\u5404\u5927\u5382 webpack5 \u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6937176680251424775#heading-7"},"\u3010\u8bd1\u3011\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 ViteJS \u4e2d\u82f1\u53cc\u8bed\u5b57\u5e55 \uff5c \u6280\u672f\u70b9\u8bc4")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6924258563862822919"},"Webpack5 \u65b0\u7279\u6027\u4e1a\u52a1\u843d\u5730\u5b9e\u6218")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://webpack.docschina.org/guides/development/#choosing-a-development-tool"},"Webpack \u5b98\u65b9\u5f00\u53d1\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P3foOrcu4StJDGdX9xavng"},"\u6784\u5efa\u6548\u7387\u5927\u5e45\u63d0\u5347\uff0cwebpack5 \u5728\u4f01\u9e45\u8f85\u5bfc\u7684\u5347\u7ea7\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZP2IigNVSIZKGuYxNYOYgw"},"\u5982\u4f55\u5229\u7528 monorepo \u7b56\u7565\u7ba1\u7406\u4ee3\u7801\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6924854598268108807"},"All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007252464726458399"},"\u4e00\u987f\u64cd\u4f5c\uff0c\u6211\u628a Table \u7ec4\u4ef6\u6027\u80fd\u63d0\u5347\u4e86\u5341\u500d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7005019784429469704"},"MySQL \u4ece\u5165\u95e8\u5230\u5b9e\u8df5\uff0c\u4e07\u5b57\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904080972709901"},"\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903919995322382"},"\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5"))),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg"},"\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026119446162997261"},"\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7077365102743126052"},"\u56db\u4e2a\u771f\u79c0React\u7528\u6cd5\uff0c\u4f60\u503c\u5f97\u62e5\u6709")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw"},"\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA"},"pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/455809528"},"\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7152898360498716702"},"Vue\u7ec4\u4ef6\u5e93\u6587\u6863\u7ad9\u70b9\u7684\u642d\u5efa\u601d\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7151653067593613320#heading-18"},"\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7148746931802472485#heading-8"},"React-router\u4ece0\u52301")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118937685653192735#heading-7"},"\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7131222991681093639"},"768. \u6700\u591a\u80fd\u5b8c\u6210\u6392\u5e8f\u7684\u5757 II : \u5e38\u89c4\u8d2a\u5fc3\u6784\u9020\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7128597557634138148"},"\ud83e\udd8a\u3010\u524d\u7aef\u5de5\u7a0b\u5316\u3011\u4e3a\u4ec0\u4e48\u5927\u5382\u90fd\u8981\u5f00\u53d1\u81ea\u5df1\u7684\u811a\u624b\u67b6\uff1f\ud83e\udd84\ufe0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7120893568553582622"},"\u5feb\u4e0a\u8f66\uff01\u4ece\u96f6\u5f00\u59cb\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6938201650012094495"},"\u5199\u7ed9\u524d\u7aef\u7684\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u57fa\u7840\u5165\u95e8\uff08\u4e00\uff09\u8fd4\u749e\u5f52\u771f\uff1a\u4ece\u5f15\u7528\u7c7b\u578b\u5230\u88f8\u6307\u9488")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101457212085633054#heading-1"},"\u6a21\u5757\u8054\u90a6\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw"},"\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/go-interview/set/xq5788"},"Go Interview")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://books.halfrost.com/leetcode/ChapterFour/0200~0299/0287.Find-the-Duplicate-Number/"},"LeetCode Cookbook")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s?__biz=MzUxMDI4MDc1NA==&mid=2247483807&idx=1&sn=9c7aede4f675f2de49ddc08ab1a95a71&chksm=f90414c2ce739dd4b8711c0043286fba9744b8d9c86c75c7ac7750d28cd2fed43f749eb5de99&scene=178&cur_album_id=1383459655464337409#rd"},"Go Gin \u7cfb\u5217\u4e8c\uff1a\u521d\u59cb\u5316\u9879\u76ee\u53ca\u516c\u5171\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://orizens.com/blog/500ms-to-1-7ms-in-react-a-journey-and-a%20checklist/"},"500ms to 1.7ms In React: A Journey And A Checklist")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157902763534319624"},"\u6f2b\u8c08\u6784\u5efa\u5de5\u5177(\u5341):\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7170852747749621791"},"\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085257325165936648"},"\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684\uff1f\ud83c\udf89\ud83c\udf89\ud83c\udf89")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg"},"Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/aurelievache/learning-go-by-examples-part-7-create-a-cross-platform-gui-desktop-app-in-go-44j1"},"Learning Go by examples: part 7 - Create a cross-platform GUI/Desktop app in Go")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/aurelievache/understanding-docker-part-37-content-trust-18n3"},"Understanding Docker: part 37 \u2013 Content Trust")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://dev.to/aurelievache/understanding-kubernetes-part-47-kubernetes-126-changelog-2404"},"Understanding Kubernetes: part 47 \u2013 Kubernetes 1.26 Changelog")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7115634967945674765"},"Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7116141318853623839"},"\u4e3a\u4ec0\u4e48 React \u7684 Diff \u7b97\u6cd5\u4e0d\u91c7\u7528 Vue \u7684\u53cc\u7aef\u5bf9\u6bd4\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121378029682556958"},"\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406"))),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094984070999834655"},"\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7147939014870302756"},"\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117512204059934733"},"react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118937685653192735"},"\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944863057000529933"},"\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406"))),(0,n.kt)("h2",{id:"-\u5c0f\u76ee\u6807"},"\ud83d\udcd2 \u5c0f\u76ee\u6807"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},"Vue 3.x \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"Vuex 4.x \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"Vue-Router \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u642d\u5efa\u811a\u624b\u67b6\u5de5\u5177\uff08Webpack5 \u65b0\u7279\u6027\u5b9e\u8df5\uff09\uff1b"),(0,n.kt)("li",{parentName:"ul"},"VS Code extension \uff1b"),(0,n.kt)("li",{parentName:"ul"},"cocos \u6e38\u620f\u5f00\u53d1\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199 redux \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199 redux-thunk \u6e90\u7801\uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u624b\u5199 Promise/A+ \uff1b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904116913700877"},"\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6945319439772434469"},"\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7055202073511460895"},"V8 Promise\u6e90\u7801\u5168\u9762\u89e3\u8bfb\uff0c\u5176\u5b9e\u4f60\u5bf9Promise\u4e00\u65e0\u6240\u77e5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904094079926286"},"\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7043758954496655397"},"\u624b\u628a\u624b\u4e00\u884c\u4e00\u884c\u4ee3\u7801\u6559\u4f60\u201c\u624b\u5199Promise\u201c\uff0c\u5b8c\u7f8e\u901a\u8fc7 Promises/A+ \u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b")))),(0,n.kt)("li",{parentName:"ul"},"\u6392\u5e8f\u7b97\u6cd5\uff0c\u6876\u6392\u5e8f\u3001\u8ba1\u6570\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6 O(n) \uff1b"),(0,n.kt)("li",{parentName:"ul"},"\u6bcf\u65e5\u7b97\u6cd5",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://labuladong.gitee.io/algo/"},"https://labuladong.gitee.io/algo/"),"\uff08\u56fd\u5185\u901f\u5ea6\u5feb\uff0c\u4f53\u9a8c\u597d\uff0c\u63a8\u8350\uff09"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://labuladong.github.io/algo/"},"https://labuladong.github.io/algo/")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/AzQzw-pC8A-0kS0NJn2eWw"},"\u624b\u628a\u624b\u5237\u4e8c\u53c9\u6811\u7cfb\u5217\u5b8c\u7ed3\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hGrTUmM1zusPZZ0nA9aaNw"},"\u524d\u7f00\u6811\u7b97\u6cd5\u6a21\u677f\u79d2\u6740 5 \u9053\u7b97\u6cd5\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5GO2ZITncVArdm4KITBd9g"},"\u96c6\u5408\u5212\u5206\u95ee\u9898\uff1a\u6392\u5217\u7ec4\u5408\u4e2d\u7684\u56de\u6eaf\u601d\u60f3\uff08\u4fee\u8ba2\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8ZTMhvHJK_He48PpSt_AmQ"},"\u5feb\u901f\u6392\u5e8f\u7684\u6b63\u786e\u7406\u89e3\u65b9\u5f0f\u53ca\u8fd0\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A"},"\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/njl6nuid0aalZdH5tuDpqQ"},"\u4e00\u6587\u79d2\u6740 5 \u9053\u6700\u8fd1\u516c\u5171\u7956\u5148\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OQAzopRncZe5cb9_of4mCQ"},"\u7b97\u6cd5\u65f6\u7a7a\u590d\u6742\u5ea6\u5206\u6790\u5b9e\u7528\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zhaurXhrAiHsfgGAOfAuMw"},"\u52a8\u6001\u89c4\u5212\u7b54\u7591\u7bc7\uff08\u4fee\u8ba2\u7248\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/6vwNBr48D36n6E3EawFUqg"},"\u8bba\u52a8\u6001\u89c4\u5212\u7a77\u4e3e\u7684\u4e24\u79cd\u89c6\u89d2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iL7tCl6pqw0fTatGSemY-g"},"\u9ad8\u9891\u9762\u8bd5\u7cfb\u5217\uff1a\u5355\u8bcd\u62c6\u5206\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HiEft8sW5QzHcM5mb5_V6g"},"\u522b\u7528 KMP \u4e86\uff0c Rabin-Karp \u7b97\u6cd5\u4e86\u89e3\u4e0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XXsWwDml_zHiTEFPZtbe3g"},"\u5fae\u8f6f\u9762\u8bd5\u9898\u89e3\u6790\uff1a\u4e11\u6570\u7cfb\u5217\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/vxQDGfshcSVjs9EYmV8q3Q"},"\u8bf4\u900f\u6e38\u620f\u4e2d\u5e38\u7528\u7684\u4e24\u79cd\u968f\u673a\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kI0HUTFVr4YEBpLRZWLEDg"},"\u6211\u7528\u6d88\u606f\u961f\u5217\u505a\u4e86\u4e00\u6b3e\u8054\u673a\u5c0f\u6e38\u620f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mFLCL_Dyz5-CtZMZJmOXKw"},"Union Find \u5e76\u67e5\u96c6\u7b97\u6cd5\u539f\u7406\u53ca\u5e94\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4vHfaNnn1OpWQJcsssWWdQ"},"\u5fc5\u77e5\u5fc5\u4f1a\u4f4d\u8fd0\u7b97\u6280\u5de7\u624b\u518c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7152708637817831432"},"\u3010\u9762\u8bd5\u9ad8\u9891\u9898\u3011\u96be\u5ea6 1.5/5\uff0c\u591a\u89e3\u6cd5\u7ecf\u5178\u9762\u8bd5\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9Q4JAuSATq3WgN7krdGTWg"},"DFS/\u56de\u6eaf/\u52a8\u6001\u89c4\u5212\u7b97\u6cd5\u7684\u878d\u4f1a\u8d2f\u901a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ir1Hk06HcT8W_qz0MtyONA"},"2021 \u516c\u4f17\u53f7\u7cbe\u9009\u6587\u7ae0\u76ee\u5f55")))),(0,n.kt)("li",{parentName:"ul"},"\u770b\u4e0b\u9762\u7684\u6587\u7ae0\uff0c\u624b\u5199\u4e00\u4e2a Webpack",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6930877602840182791"},"\u624b\u5199\u4e00\u4e2awebpack\uff0c\u770b\u770bAST\u600e\u4e48\u7528\uff5c\u725b\u6c14\u51b2\u5929\u65b0\u5e74\u5f81\u6587")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6987036612035084296"},"\u4eca\u5929\uff0c\u6211\u4eec\u6765\u5b9e\u73b0\u4e00\u4e2a\u57fa\u7840\u7248\u7684webpack")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6854573217336541192"},"\u624b\u5199webpack\u6838\u5fc3\u539f\u7406\uff0c\u518d\u4e5f\u4e0d\u6015\u9762\u8bd5\u5b98\u95ee\u6211webpack\u539f\u7406")))),(0,n.kt)("li",{parentName:"ul"},"Webapck \u7f16\u8bd1\u6d41\u7a0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7115598540721618944"},"Webpack5 \u6838\u5fc3\u539f\u7406\u4e0e\u5e94\u7528\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031546400034947108"},"Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026658230365323301"},"\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6859538537830858759"},"\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7077484559893266439"},"100\u884c\u4ee3\u7801\u5b9e\u73b0\u4e00\u4e2a\u7ec4\u4ef6\u5f15\u7528\u6b21\u6570\u7edf\u8ba1\u63d2\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ronami/minipack"},"https://github.com/ronami/minipack")))),(0,n.kt)("li",{parentName:"ul"},"\u624b\u628a\u624b\u5b9e\u73b0\u4e00\u4e2a babel \u63d2\u4ef6",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"Babel \u63d2\u4ef6\u5e38\u7528 API\u3001\u914d\u5408 TS \u5f00\u53d1\u3001\u5982\u4f55\u6d4b\u8bd5\u63d2\u4ef6\u7b49\u7b49",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7143921535445631012"},"Babel \u63d2\u4ef6\uff1a30\u5206\u949f\u4ece\u5165\u95e8\u5230\u5b9e\u6218")))),(0,n.kt)("li",{parentName:"ul"},"\u8fd9\u7bc7\u505a\u7684 demo \u662f\u4e00\u4e2a\u7b80\u5355\u7684 babel-plugin-import",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903746804137991"},"\u6df1\u5165Babel\uff0c\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86")))),(0,n.kt)("li",{parentName:"ul"},"\u8fd9\u7bc7\u505a\u7684 demo \u7c7b\u4f3c Java \u4e2d\u7684 lambok",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7012424646247055390"},"\u4fdd\u59c6\u7ea7\u6559\u5b66\uff01\u8fd9\u6b21\u4e00\u5b9a\u5b66\u4f1ababel\u63d2\u4ef6\u5f00\u53d1\uff01")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md"},"babel-handbook - \u5404\u79cd ast \u64cd\u4f5c\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/R6Xr8SoJicZB8-P4H2SSPA"},"\u4f60\u8fd8\u5728\u624b\u52a8\u90e8\u7f72\u57cb\u70b9\u5417\uff1f\u4ece0\u52301\u5f00\u53d1Babel\u57cb\u70b9\u81ea\u52a8\u690d\u5165\u63d2\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7061808830274863118"},"\u64cd\u4f5c JavaScript \u7684 AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6953963506693570573"},"\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026671646555504676"},"\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136")))),(0,n.kt)("li",{parentName:"ul"},"diff \u7b97\u6cd5\u76f8\u5173",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/snabbdom/snabbdom"},"https://github.com/snabbdom/snabbdom")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/snabbdom/snabbdom/blob/master/src/init.ts"},"https://github.com/snabbdom/snabbdom/blob/master/src/init.ts")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/8M-pJdKjF6bx5ijtSFKIcw"},"\u56fe\u89e3Diff\u7b97\u6cd5\u2014\u2014Vue\u7bc7")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7067693810918096903"},"\u6d45\u6790 Snabbdom \u4e2d vnode \u548c diff \u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7161063643105198093"},"\u4e00\u6587\u5403\u900f React \u548c Vue \u7684\u591a\u8282\u70b9 diff \u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997965021401579556"},"diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7000266544181674014"},"DIff\u7b97\u6cd5\u770b\u4e0d\u61c2\u5c31\u4e00\u8d77\u6765\u780d\u6211(\u5e26\u56fe)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966215704634720287"},"\u5173\u4e8eVirtual DOM\u7406\u89e3\u548cSnabbdom\u6e90\u7801\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/shfshanyue/mini-code/blob/master/code/vdom/index.js"},"shanyue mini-code vdom")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6976232466059100197"},"Virtual DOM\u5230\u5e95\u6709\u4ec0\u4e48\u8ff7\u4eba\u4e4b\u5904\uff1f\u5982\u4f55\u642d\u5efa\u4e00\u6b3e\u8ff7\u4f60\u7248Virtual DOM\u5e93\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6919376064833667080"},"React\u3001Vue2\u3001Vue3\u7684\u4e09\u79cdDiff\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/31809713/answer/53544875"},"\u7f51\u4e0a\u90fd\u8bf4\u64cd\u4f5c\u771f\u5b9e DOM \u6162\uff0c\u4f46\u6d4b\u8bd5\u7ed3\u679c\u5374\u6bd4 React \u66f4\u5feb\uff0c\u4e3a\u4ec0\u4e48\uff1f- \u77e5\u4e4e")))),(0,n.kt)("li",{parentName:"ul"},"webpack \u70ed\u6a21\u5757\u66ff\u6362\u770b\u4e0b\u6e90\u7801",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7049608872553611301"},"webpack\u6a21\u5757\u70ed\u66f4\u65b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021729340945596424"},"Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031546400034947108"},"Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790")))),(0,n.kt)("li",{parentName:"ul"},"Docker \u76f8\u5173\u603b\u7ed3\u4e00\u4e0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064906701941506061"},"GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5LLX__x-yamgR83e0NKAtA"},"\u5199\u7ed9\u524d\u7aef\u7684 Docker \u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0Il5o9CRgZI3LbuR0LjAtQ"},"\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069609959985512484"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083009375387779085"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7113712658850775048"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u5bb9\u5668\u7f16\u6392")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/f581rfvKWE3KGgWfZDJ2cA"},"\u4e91\u8ba1\u7b97\u65f6\u4ee3\uff0c\u4f60\u8fd8\u4e0d\u4f1a Docker \uff1f \u4e00\u4e07\u5b57\u603b\u7ed3\uff08\u5efa\u8bae\u6536\u85cf\uff09")))),(0,n.kt)("li",{parentName:"ul"},"\u524d\u7aef\u6846\u67b6\u6e90\u7801",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f \u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/6945998773818490884"},"React \u8fdb\u9636\u5b9e\u8df5\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117512204059934733"},"react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7122617883837857806"},"\u300cReact\u8fdb\u9636\u300dReact\u4e2d\u6ca1\u6709keepalive\uff1f\u6ca1\u4e8b\uff01\u624b\u628a\u624b\u6559\u4f60\u4ece\u96f6\u5230\u4e00\u8bbe\u8ba1\u5e76\u5b9e\u73b0\u4e00\u4e2a\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118937685653192735"},"\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069555976717729805"},"\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6944863057000529933"},"\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7085542534943883301"},"2022 \u5e74\u7684 React \u751f\u6001")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7010539227284766751"},"React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://overreacted.io/before-you-memo/"},"Before You memo()")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://7kms.github.io/react-illustration-series/main/fibertree-update/#bailout%E9%80%BB%E8%BE%91-bailout"},"\u56fe\u89e3 React - bailout\u903b\u8f91")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/434791954/answer/2453356416"},"React \u7684 Concurrent Mode \u662f\u5426\u6709\u8fc7\u5ea6\u8bbe\u8ba1\u7684\u6210\u5206")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1Yr4y1J7oc"},"\u300c\u4e0a\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1j44y1g74m"},"\u300c\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://pomb.us/build-your-own-react/"},"Build your own React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903913410314247"},"Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121378029682556958"},"\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7154175507280429070"},"React \u6e32\u67d3\u7684\u672a\u6765")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/METf8Ng6Qnsu1uWGTzan8g"},"React \u4e2d\u5e38\u89c1\u7684 8 \u4e2a\u9519\u8bef\uff0c\u5982\u4f55\u907f\u514d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7104460511869141006"},"20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094424941541457933"},"React\u5b98\u65b9\u56e2\u961f\u51fa\u624b\uff0c\u8865\u9f50\u539f\u751fHook\u77ed\u677f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7075701341997236261"},"React Hooks \u7684\u539f\u7406\uff0c\u6709\u7684\u7b80\u5355\u6709\u7684\u4e0d\u7b80\u5355")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904193044512782"},"\u4ecereact hooks\u201c\u95ed\u5305\u9677\u9631\u201d\u5207\u5165\uff0c\u6d45\u8c08react hooks")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7LXeQomcHK4zcuRqB32JDg"},"React+Ts\uff0c\u8fd9\u6837\u5b66\u8d77\u6765\u786e\u5b9e\u7b80\u5355\uff01\uff01\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/byD6xm3O6MzX8kksjBmqpA"},"React 18 \u8d85\u5168\u5347\u7ea7\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7077545184807878692"},"\u963f\u91cc\u4e09\u9762\uff1a\u7075\u9b42\u62f7\u95ee\u2014\u2014\u6709react fiber\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u9700\u8981vue fiber\u5462")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982004709145968677"},"[","\u5efa\u8bae\u6536\u85cf","]"," \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6978654109893132318"},"\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904197008130062"},"\u624b\u5199React\u7684Fiber\u67b6\u6784\uff0c\u6df1\u5165\u7406\u89e3\u5176\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6859528127010471949"},"React Fiber \u6e90\u7801\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6943896410987659277"},"\u8d70\u8fdbReact Fiber\u7684\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6911681589558640654"},"\u524d\u7aef\u5de5\u7a0b\u5e08\u7684\u81ea\u6211\u4fee\u517b\uff1aReact Fiber \u662f\u5982\u4f55\u5b9e\u73b0\u66f4\u65b0\u8fc7\u7a0b\u53ef\u63a7\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6984949525928476703"},"React Fiber\u5f88\u96be\uff1f\u516d\u4e2a\u95ee\u9898\u52a9\u4f60\u7406\u89e3 React Fiber")))),(0,n.kt)("li",{parentName:"ul"},"Vite \u6e90\u7801",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7050063811973218341"},"\u6df1\u5165\u6d45\u51fa Vite")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/UD0-7rWtOAxMuDpOR77gug"},"\u8be6\u89e3 Vite \u4f9d\u8d56\u9884\u6784\u5efa\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bf11t1rH6NllKDA0IKR9Lw"},"\u6388\u4eba\u4e88\u6e14\uff0cVSCode \u5982\u4f55\u8c03\u8bd5 Vite \u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3dfbu7lZJLd6cJSp9XLcVQ"},"\u6572\u4e0b vite \u547d\u4ee4\u540e\uff0cserver \u505a\u4e86\u54ea\u4e9b\u4e8b")))),(0,n.kt)("li",{parentName:"ul"},"\u5305\u7ba1\u7406\u65b9\u6848\u3001PNPM"),(0,n.kt)("li",{parentName:"ul"},"Arch Linux",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://linuxhandbook.com/grep-command-examples/"},"10 Practical Grep Command Examples for Developers")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.freecodecamp.org/news/the-linux-commands-handbook/#the-linux-grep-command"},"The Linux Command Handbook \u2013 Learn Linux Commands for Beginners")))),(0,n.kt)("li",{parentName:"ul"},"\u5982\u4f55\u642d\u5efa\u4e2a\u4eba\u535a\u5ba2",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4f7f\u7528 Next.js\uff0c\u5f00\u7bb1\u5373\u7528\u6587\u4ef6\u7cfb\u7edf\u8def\u7531\u3001\u9759\u6001\u7ad9\u70b9\u751f\u6210\uff08SSG\uff09"),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://nextjs.org/learn/basics/create-nextjs-app"},"https://nextjs.org/learn/basics/create-nextjs-app")))),(0,n.kt)("li",{parentName:"ul"},"\u5de5\u7a0b\u5316\u65b9\u6848\u603b\u7ed3\u4e0b",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/403970666"},"2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017710911443959839"},"2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023242274876162084"},"\ud83d\udd25\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts"},"Next.js webpack \u914d\u7f6e")))),(0,n.kt)("li",{parentName:"ul"},"\u9759\u6001\u9875\u9762\u90e8\u7f72\u65b9\u6848",(0,n.kt)("ul",{parentName:"li"},(0,n.kt)("li",{parentName:"ul"},"\u4e0a\u4f20\u963f\u91cc\u4e91 OSS\n",(0,n.kt)("a",{parentName:"li",href:"https://github.com/Menci/upload-to-oss"},"https://github.com/Menci/upload-to-oss")))),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6992172458748936222"},"\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u5f00\u53d1\u6a21\u5f0f - \u5199\u4e8e2021\u5e74")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6990538424545443854"},"\u4ece\u96f6\u642d\u5efaWebpack5-react\u811a\u624b\u67b6(\u9644\u6e90\u7801)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/JinJieTan/Peter-"},"\u624b\u5199\u5404\u79cd\u6e90\u7801"))),(0,n.kt)("h2",{id:"-\u63a8\u8350\u9605\u8bfb"},"\ud83d\udcd2 \u63a8\u8350\u9605\u8bfb"),(0,n.kt)("ul",null,(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/403970666"},"2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6996816316875161637#heading-15"},"\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/webpack/webpack-dev-middleware"},"https://github.com/webpack/webpack-dev-middleware")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000011761306"},"webpack-dev-middleware \u63d2\u4ef6\u7684\u4f7f\u7528")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904099985489927"},"webpack-dev-middleware \u6e90\u7801\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6949040393165996040#heading-2"},"[","\u4e07\u5b57\u603b\u7ed3","]"," \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7020678344219820068"},"\u8ddf\u6751\u957f\u8001\u5e08\u505a\u3010Vue DevUI \u5f00\u6e90\u6307\u5357\u3011\u76f4\u64ad\u4e00\u4e2a\u6708\u7684\u611f\u53d7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021167384484380709"},"\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 008: webpack HMR \u5b9e\u73b0\u7684\u6838\u5fc3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7030207667457130527"},"\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6959115798841393160"},"\u624b\u6478\u624b\u6559\u4f60\u7528Vue3+Typescript+Rollup+Tailwinds\u6253\u9020\u63d2\u62d4\u5f0f\u7684\u4e1a\u52a1\u7ec4\u4ef6\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6869551115420041229"},"\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029525775321661470"},"\u624b\u6478\u624b\u5b66\u4f1a\u642d\u5efa\u4e00\u4e2a TS+Rollup \u7684\u521d\u59cb\u5f00\u53d1\u73af\u5883")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029292539479867429"},"\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1a\u5982\u4f55\u5b9e\u73b0\u7ec4\u4ef6\u7684\u6309\u9700\u6253\u5305\ud83d\udce6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7029262501833359368"},"\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6974377246140301342"},"coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6892886272377880583"},"\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48")),(0,n.kt)("li",{parentName:"ul"},"\ud83c\udf1b ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7028222480326066213"},"\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904093434019853"},"\u5982\u4f55\u63a8\u52a8\u524d\u7aef\u56e2\u961f\u7684\u57fa\u7840\u8bbe\u65bd\u5efa\u8bbe")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966491047257964575"},"Element UI\u6e90\u7801\u4e2d\u5b66\u5230\u7684\u6280\u5de7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026658230365323301"},"\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6859538537830858759"},"\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026671646555504676"},"\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6920044884594425864"},"\u4ece\u96f6\u64b8\u4e00\u4e2aCLI\u547d\u4ee4\u884c\u811a\u624b\u67b6\u5de5\u5177")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904197863964685"},"\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6943430853972852750"},"\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6946008649026240519"},"\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026274816734789663"},"git hooks \u7684\u5e93 husky \u6e90\u7801\u8fd9\u4e48\u7b80\u5355\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4e00\u4e2a\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026210002042011655"},"\u300cReact18\u65b0\u7279\u6027\u300d\u6df1\u5ea6\u89e3\u8bfb\u4e4buseMutableSource")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6953452438300917790"},"\u3010V8\u6e90\u7801\u8865\u5145\u7bc7\u3011\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966422095274180639"},"[","\u63a2\u7d22","]","Webpack DevServer\u548cHMR\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7023242274876162084"},"\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903881390964744"},"\u4ece\u5934\u5f00\u59cb\uff0c\u5f7b\u5e95\u7406\u89e3\u670d\u52a1\u7aef\u6e32\u67d3\u539f\u7406(8\u5343\u5b57\u6c47\u603b\u957f\u6587)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6982157120594509837"},"\u5256\u6790 Webpack SplitChunksPlugin \u6e90\u7801: \u5b66\u5b8c\u4f60\u4e5f\u80fd\u5199\u4e00\u4e2a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7025164660751990798"},"\u4e00\u70b9\u5173\u4e8e\u670d\u52a1\u7aef\u6e32\u67d3\u7684\u5206\u4eab")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6966119324478079007"},"\u4ece 0 \u6784\u5efa\u81ea\u5df1\u7684\u811a\u624b\u67b6/CLI\u77e5\u8bc6\u4f53\u7cfb\uff08\u4e07\u5b57\uff09 \ud83d\udee0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6984939221681176607"},"\u624b\u5199\u4e00\u4e2a\u865a\u62dfDOM\u5e93\uff0c\u5f7b\u5e95\u8ba9\u4f60\u7406\u89e3diff\u7b97\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6854573215969181703"},"10\u4e2a\u7b80\u5355\u7684\u6280\u5de7\u8ba9\u4f60\u7684 vue.js \u4ee3\u7801\u66f4\u4f18\u96c5\ud83c\udf4a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7026119446162997261"},"\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.zhihu.com/question/384048633/answer/1134746899"},"\u505a\u4e86\u4e24\u5e74\u524d\u7aef\u5f00\u53d1\uff0c\u5e73\u65f6\u5c31\u662f\u62ff Vue \u5199\u5199\u9875\u9762\u548c\u7ec4\u4ef6\uff0c\u7b80\u5386\u7684\u9879\u76ee\u7ecf\u5386\u5e94\u8be5\u600e\u4e48\u5199\u5f97\u597d\u770b\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7017710911443959839"},"2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7016534471734198279"},"\u5206\u4eab\u4e00\u5e74\u4ee5\u6765\u7684Electron\u5f00\u53d1\u7ecf\u9a8c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903938894872589"},"\u300c\u524d\u7aef\u8fdb\u9636\u300d\u9ad8\u6027\u80fd\u6e32\u67d3\u5341\u4e07\u6761\u6570\u636e(\u65f6\u95f4\u5206\u7247)")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6978654109893132318"},"\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6973155726302642206"},"\u624b\u5199\u7cfb\u5217-\u8fd9\u4e00\u6b21\uff0c\u5f7b\u5e95\u641e\u61c2 Promise")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7005375860509245471"},"50\u884c\u4ee3\u7801\u4e32\u884cPromise\uff0ckoa\u6d0b\u8471\u6a21\u578b\u539f\u6765\u662f\u8fd9\u4e48\u5b9e\u73b0\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6882290865763680264"},"\u73a9\u8f6c node \u5b50\u8fdb\u7a0b \u2014 child_process")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903895467032589"},"\u6df1\u5165\u5256\u6790\uff1aVue\u6838\u5fc3\u4e4b\u865a\u62dfDOM")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904055618158600"},"\u4ece\u96f6\u5f00\u59cb\u914d\u7f6e react + typescript\uff08\u4e00\uff09\uff1adotfiles")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6937125495439900685"},"Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7025213391618703367"},"TypeScript \u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6965320374451961886"},"\u7528ts\u7c7b\u578b\u7cfb\u7edf\u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7059400669916037133"},"\u521d\u6b65\u5c1d\u8bd5 tauri\uff0c\u5e76\u4e14\u4e0e electron.js \u5bf9\u6bd4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7057178581897740319"},"\u548c\u5927\u591a\u6570\u7684\u524d\u7aef\u5f00\u53d1\u8005\u76f8\u6bd4\uff0c\u6211\u5e76\u6ca1\u6709\u9009\u62e9node.js\u505acli\u800c\u6295\u9760\u4e86golang")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/acdlite/react-fiber-architecture"},"React Fiber Architecture")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.cnblogs.com/ginvip/p/6367939.html"},"linux\u547d\u4ee4\u603b\u7ed3\u4e4blsof\u547d\u4ee4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.smashingmagazine.com/2019/09/machine-learning-front-end-developers-tensorflowjs/"},"Machine Learning For Front-End Developers With Tensorflow.js")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw"},"javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/476712416"},"\u6211\u7684\u7b2c\u4e00\u6b21webpack\u4f18\u5316\uff0c\u9996\u5c4f\u6e32\u67d3\u4ece9s\u52301s")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071518211392405541"},"\u5728\u9879\u76ee\u4e2d\u7528ts\u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u6574\u4e2a\u56e2\u961f\u53d7\u76ca\ud83d\ude01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ"},"\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ"},"\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A"},"\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aMYJODhtWsBt9CTJxySQEQ"},"\u817e\u8baf\u4e91\u540e\u7aef15\u8fde\u95ee\uff01")),(0,n.kt)("li",{parentName:"ul"},"\u2b50\ufe0f ",(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/0kUf1ujPUuieyOSMsBIzaw"},"\u5b57\u8282\u56fd\u9645\u652f\u4ed8\u5341\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7080032725477883917"},"\u5982\u4f55\u6210\u4e3a\u4e00\u4e2a\u4f18\u79c0\u7684\u590d\u5236\u7c98\u8d34\u5de5\u7a0b\u5e08")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://blog.csdn.net/zhydream77/article/details/81909706"},"docker\u6587\u4ef6\u5939\u6620\u5c04\u7684\u4e24\u79cd\u65b9\u5f0f---\u4e3b\u673a\u5377\u6620\u5c04\u548c\u5171\u4eab\u6587\u4ef6\u5939\u6620\u5c04")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://studygolang.com/articles/25997?fr=sidebar"},"\u4e3a\u4ec0\u4e48golang\u6ca1\u6709min/max\u4ee5\u53ca\u4e09\u5143\u64cd\u4f5c\u7b26")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7084882650233569317"},"\u7f16\u8bd1 ts \u4ee3\u7801\u7528 tsc \u8fd8\u662f babel")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7031122959637217310"},"\u5982\u679c\u6ca1\u6709 package-lock.json\uff0c\u90a3\u5c06\u5982\u4f55")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7030084290989948935"},"\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 023\uff1anode_modules \u7248\u672c\u91cd\u590d\u7684\u56f0\u5883")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083468345579667493"},"\u3010\u6df7\u6dc6\u7cfb\u5217\u3011\u4e09\u95ee\uff1anpx\u3001npm\u3001cnpm\u3001pnpm\u533a\u522b\u4f60\u641e\u6e05\u695a\u4e86\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7082738107237433375"},"Webpack\u7ec4\u4ef6\u5e93\u6253\u5305\u8d85\u8be6\u7ec6\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/XWZsKQECcsHAlE9cyqi9Eg"},"\u5199\u597d JavaScript \u5f02\u6b65\u4ee3\u7801\u7684\u51e0\u4e2a\u63a8\u8350\u505a\u6cd5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WisEGFz2yn_ZeekViofMnA"},"Node.js \u8fdb\u9636 - \u591a\u6587\u4ef6 Stream \u5408\u5e76\uff0c\u4e32\u884c\u548c\u5e76\u53d1\u4e24\u79cd\u6a21\u5f0f\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7046898330000949285"},"\u670d\u52a1\u7aef\u6e32\u67d3SSR\u53ca\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/lyff2svfHh4rdsWRL4H5uA"},"\u624b\u6478\u624b\u670d\u52a1\u7aef\u6e32\u67d3-react")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7058868160706904078"},"\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/kGMsNmIXlT25NfRrifjnTQ"},"\u9009\u62e9\u7b2c\u4e09\u65b9 NPM \u5305\u65f6\u7684 5 \u6761\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7071066976830881823"},"\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/t3dYc3Md1dpiv1vaFa5plA"},"React 18 \u5168\u89c8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/fgT7Kxs_0feRx4TkBe6G5Q"},"React 18 \u5bf9 Hooks \u7684\u5f71\u54cd")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GatHpP3BRLV_I48MfpzR4A"},"React \u7684\u5fc3\u667a\u6a21\u578b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qyr6MnPtvnELDSbPJ2VtIw"},"\u4f60\u4e0d\u77e5\u9053\u7684 React v18 \u7684\u4efb\u52a1\u8c03\u5ea6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000041683300"},"\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0a)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000041683421"},"\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0b)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/502951532"},"Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://zhuanlan.zhihu.com/p/415361629"},"\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/tWbeOTx0JpiZOD0YaC1P2A"},"\u524d\u7aef\u7b97\u6cd5\u7cfb\u7edf\u7ec3\u4e60: \u6808\u548c\u961f\u5217\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MYLi4mSgoi5KXj4-_OgT3A"},"\u3010\u7b2c2602\u671f\u3011\u8bbe\u7f6e NPM Registry \u7684 4 \u79cd\u59ff\u52bf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844903919995322382"},"\u300c\u624b\u6478\u624b\u8bbe\u8ba1\u6a21\u5f0f\u7cfb\u5217\u300d \u4eab\u5143\u6a21\u5f0f\u4e0e\u8d44\u6e90\u6c60")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6889247428797530126"},"\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904165500518414"},"React Hooks \u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3xhNcfI4pTm0n-naSsOBwg"},"\u624b\u5199 CSS-modules \u6765\u6df1\u5165\u7406\u89e3\u5b83\u7684\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.bilibili.com/video/BV1j44y1g74m"},"\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-B5M7pjIWZzFNvq-hyr1Mw"},"Umi 4 \u7279\u6027\u5408\u96c6\uff0c\u6bd4 Vite \u8fd8\u8981\u5feb\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7094296981001994277"},"\u4f60\u53ef\u80fd\u5e76\u6ca1\u6709\u7406\u89e3\u7684 babel \u914d\u7f6e\u7684\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7052307032971411463"},"\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069609959985512484"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7083009375387779085"},"\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww"},"\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7095354780079357966"},"NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g"},"Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/FPupefVg4zphOfIERZOvHQ"},"\u5982\u4f55\u8bbe\u8ba1\u66f4\u4f18\u96c5\u7684 React \u7ec4\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/01sTK6w4BFUzoRc2NKCs1w"},"React \u5e76\u53d1\u6e32\u67d3\u7684\u524d\u4e16\u4eca\u751f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.freecodecamp.org/news/how-to-build-your-own-blog-with-next-js-and-mdx/"},"\u4f7f\u7528 Next.js \u548c MDX \u6784\u5efa\u4f60\u81ea\u5df1\u7684\u535a\u5ba2")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw"},"TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g"},"TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g"},"\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7099402445989609479"},"\u524d\u7aef\u5fc5\u5b66\u7684\u52a8\u753b\u5b9e\u73b0\u601d\u8def\uff0c\u9ad8\u903c\u683c\u7684\u6548\u679c\u8001\u677f\u770b\u4e86\u90fd\u4f1a\u5927\u58f0\u79f0\u8d5e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LSlgpazCwtceQWjHsMPCAg"},"\u3010\u7b2c2617\u671f\u3011React \u7ec4\u4ef6\u5e93 CSS \u6837\u5f0f\u65b9\u6848\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/X4ni2i9bvolHGfCdf3SzIA"},"\u3010\u7b2c2616\u671f\u3011\u89e3\u91caJavaScript\u7684\u5185\u5b58\u7ba1\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OrekHmMrn8UlisTrvt3MNA"},"\u4ece Turborepo \u770b Monorepo \u5de5\u5177\u7684\u4efb\u52a1\u7f16\u6392\u80fd\u529b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/GryL1QVARtMB8-WIzd7xQQ"},"\u89e3\u51b3\u524d\u7aef\u5e38\u89c1\u95ee\u9898\uff1a\u7ade\u6001\u6761\u4ef6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3v54arsDRRw6agyr3MtPRg"},"Google \u6700\u65b0\u7684\u6027\u80fd\u4f18\u5316\u65b9\u6848\uff0cLCP \u63d0\u534730%\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/-6bQKIjH6WPcfuiCFtsjng"},"React useEvent\uff1a\u7816\u5bb6\u8bf4\u7684\u6ca1\u95ee\u9898")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7102328973820067877"},"\u88abdiss\u6027\u80fd\u5dee\uff0cDan\u8fde\u591c\u4f18\u5316React\u65b0\u6587\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7102233142567632933"},"Node.js \u8c03\u8bd5\u4e00\u8def\u8d70\u6765\u7ecf\u5386\u4e86\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/g1fr1fnGspi7SETyP9B6rA"},"\u63a8\u8350\u4e00\u4e2a\u524d\u7aef\u6280\u672f\u9009\u578b\u795e\u5668")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2OXIGB5qQFc2isIxhm33bg"},"\u6700\u9ad8\u6027\u80fd\u7684\u5305\u7ba1\u7406\u5668-pnpm")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/3yy9V5HMDWPFwEf1cyL-lw"},"\u5e76\u53d1\u6e32\u67d3\u4f18\u5316\uff1a\u8ba9\u6587\u4ef6\u6811\u7684\u6e32\u67d3\u53c8\u5feb\u53c8\u7a33")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7092766235380678687"},"\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg"},"\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/KwmNzTdjMB-ljQ0ysEGalg"},"\u6df1\u5165\u7406\u89e3 Linux CPU \u4e0a\u4e0b\u6587\u5207\u6362")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg"},"\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://github.com/ashok-khanna/react-snippets/blob/main/Router.js"},"100 \u884c\u4ee3\u7801\u5b9e\u73b0 React \u8def\u7531")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7100736564979826695"},"\u7cbe\u8bfb\u300areact-snippets - Router \u6e90\u7801\u300b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QWwb8PXtdJJUKyicHRmBkw"},"\u5e72\u8d27 | \u643a\u7a0b\u673a\u7968\u524d\u7aefSvelte\u751f\u4ea7\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7069772395610898462"},"\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7101457212085633054"},"\u6a21\u5757\u8054\u90a6\u6d45\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g"},"\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ULY-_Vq-Jgb8aCbhyfqYHw"},"\u3010\u96f6\u57fa\u7840\u3011\u5145\u5206\u7406\u89e3WebGL\uff08\u4e09\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ROwTG6AC2pK5UN1dzY5x8w"},"Web3.0\u5f00\u53d1\u5165\u95e8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg"},"\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/l19wbHNIrhjyD0HwJwuvmQ"},"\u5256\u6790React\u6838\u5fc3\u8bbe\u8ba1\u539f\u7406\u2014Virtual Dom")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/b15cyyg53lVKQ_TtR8hugQ"},"\u3010\u7b2c2630\u671f\u3011javascript\u4e2d\u7684\u4f9d\u8d56\u6ce8\u5165")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sEvP3nLUOBwbSHP9mmT__A"},"\u3010\u524d\u7aef\u90e8\u7f72\u9644\u5f55\u4e00\u3011\u5199\u7ed9\u524d\u7aef\u7684 docker \u4f7f\u7528\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/f8mYoozpLrnSfWcRHTMa7A"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6838\u5fc3service\u7c7b\u521d\u59cb\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/y-6Uf1hNBF19MabHEtqnJA"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u63d2\u4ef6\u5316\u67b6\u6784\u6838\u5fc3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/4cZ3rJz4P5bSRSeXDbFoMQ"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u8fd0\u884c\u65f6\u63d2\u4ef6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2MsgPh9AZtUoJpsLLdOynQ"},"UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6784\u5efa\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Sz8u6lzkL1nnpRxGrdbYJg"},"\u5982\u4f55\u534e\u4e3d\u7684\u5b9e\u73b0\u4e00\u5957\u811a\u624b\u67b6 - \u4ee5umicli\u548c\u8f6c\u8f6czzcli\u4e3a\u4f8b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.yuque.com/antfe/featured/uf1bok"},"Umi 4 \u7279\u6027 05\uff1a\u7a33\u5b9a\u767d\u76d2\u6027\u80fd\u597d\u7684 ESLint")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ZTI-8RI0l314Ki9oBxqRWw"},"\u6df1\u5165\u6d45\u51fa npm & yarn & pnpm \u5305\u7ba1\u7406\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg"},"\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=VozPNrt-LfE"},"\u4e00\u4e2a\u4e09\u5c0f\u65f6\u7684 React Native \u901f\u6210\u8bfe")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7098211898990002207"},"\u524d\u7aef\u914d\u7f6e\u5316\u771f\u9999\uff5e\u4e0a\u73ed\u53c8\u591a\u4e8660%\u7684\u6478\ud83d\udc1f\u65f6\u95f4")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7104460511869141006"},"20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7116296421816418311"},"Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u5982\u4f55\u5c06 template \u7f16\u8bd1\u6210 AST")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7117085295798911012"},"Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6a21\u578b\u6811\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121504219588198413"},"Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6700\u540e\u4e00\u66f2\uff0crender code \u751f\u6210")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7124890499478978597"},"\u521d\u63a2 Vue3 \u7f16\u8bd1\u4e4b\u7f8e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126712173014810661"},"Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u62bd\u8c61\u8bed\u6cd5\u6811\u7684\u751f\u6210")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7127074001897127943"},"Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u7a7a\u767d\u5b57\u7b26\u7684\u5904\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q"},"\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://turborepo.org/docs/handbook/what-is-a-monorepo"},"Monorepo Handbook \u65b0\u9c9c\u51fa\u7089")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7152045316294836260"},"Vue3\u7ec4\u4ef6\u5e93\u6253\u5305\u6307\u5357\uff0c\u4e00\u6b21\u751f\u6210esm\u3001esm-bundle\u3001commonjs\u3001umd\u56db\u79cd\u683c\u5f0f")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6844904039608500237"},"Koa\u7684\u6d0b\u8471\u4e2d\u95f4\u4ef6\uff0cRedux\u7684\u4e2d\u95f4\u4ef6\uff0cAxios\u7684\u62e6\u622a\u5668\u8ba9\u4f60\u8ff7\u60d1\u5417\uff1f\u5b9e\u73b0\u4e00\u4e2a\u7cbe\u7b80\u7248\u7684\u5c31\u5f7b\u5e95\u641e\u61c2\u4e86")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/khS0wkBzQe4Lxn7jHK_0vA"},"\u5b66\u4e60 Babel \u63d2\u4ef6\uff0c\u628a Vue2 \u8bed\u6cd5\u81ea\u52a8\u8f6c\u6210 Vue3\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QgOslh1TwpU2cJubnNxYNw"},"\u5982\u4f55\u7f16\u5199\u795e\u5947\u7684\u300c\u63d2\u4ef6\u673a\u5236\u300d\uff0c\u4f18\u5316\u57fa\u4e8e Antd Table \u5c01\u88c5\u8868\u683c\u7684\u6df7\u4e71\u4ee3\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7121378029682556958"},"\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7123969545387114509"},"\u803d\u8bef\u4f60\u5341\u5206\u949f\uff01\ud83c\udf83\u4f60\u53ef\u80fd\u7528\u5f97\u4e0a\u8fd9\u4e9bwebpack5\u65b0\u7279\u6027")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7118782372220567566"},"\u5206\u5305\u738b\uff01\ud83e\udde8\u4f18\u5316\u9879\u76ee\u4f53\u79ef\u51cf\u5c1120%\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7148969678642102286"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u6a21\u578b\u5149\u6e90\u7ed3\u5408\u751f\u6210\u660e\u6697\u53d8\u5316\u7684\u521b\u610f\u9875\u9762-\u5149\u4e0e\u5f71\u4e4b\u8bd7 \ud83d\udca1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146383940931026958"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7145064095178293285"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/the-cost-of-javascript"},"\u26a1\ufe0f The Cost Of JavaScript (2017 - 2023)")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/fontend-target"},"\ud83d\uddc2 \u524d\u7aef\u7248\u672c\u517c\u5bb9\u95ee\u9898\u7684\u63a2\u7d22")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/web-dev-blog"},"\ud83d\uddc2 \u5bf9 web.dev \u6240\u6709 blog \u7684\u6574\u7406\u4e0e\u5f52\u6863")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://supercodepower.com/react-native-tweet"},"\ud83e\udd2f \u6ca1 2 \u5e74 React Native \u5f00\u53d1\u7ecf\u9a8c\uff0c\u4f60\u90fd\u9047\u4e0d\u5230\u8fd9\u4e9b\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146183222425518093"},"Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146973901166215176"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u57fa\u7840\u77e5\u8bc6\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146975493278367752"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u7b97\u6cd5\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146976516692410376"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u5de5\u7a0b\u5316\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7146996646394462239"},"\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u524d\u7aef\u6846\u67b6+\u6d4f\u89c8\u5668\u539f\u7406\u7bc7\uff09\ud83d\udd25")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7158730050718662687"},"20\u4e2a\u5e38\u89c1\u7684\u524d\u7aef\u7b97\u6cd5\u9898\uff0c\u4f60\u5168\u90fd\u4f1a\u5417")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7151653067593613320"},"\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7126394898445500423"},"\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157902763534319624"},"\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg"},"\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g"},"\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA"},"\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7172001951784108040"},"\u50bb\u74dc\u65b9\u5f0f\u5206\u6790\u524d\u7aef\u5e94\u7528\u7684\u4f53\u79ef")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7050063811973218341/section/7070419010021490702"},"\u624b\u5199 Bundler: \u5b9e\u73b0\u4ee3\u7801\u6253\u5305\u3001 Tree Shaking")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/book/7050063811973218341/section/7066614663533821983"},"\u624b\u5199 Bundler: \u5b9e\u73b0 JavaScript AST \u89e3\u6790\u5668\u2014\u2014\u8bcd\u6cd5\u5206\u6790\u3001\u8bed\u4e49\u5206\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/1xY0hfcwJci1hr4TKUZMqg"},"\u3010\u7b2c2795\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u4e09\u7aef\u540c\u6784\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/7WU1DDoMYQzXnlstz16QJA"},"\u3010\u7b2c2785\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u8de8\u7aef\u5bb9\u5668\u7bc7")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/19Ai1rbRoQxOBA5SXSNCAQ"},"Vite \u7279\u6027\u548c\u90e8\u5206\u6e90\u7801\u89e3\u6790")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7021115814870810660"},"Rollup\u6e90\u7801\uff1a\u6a21\u5757\u6253\u5305\u4e0eTree-Shaking")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7169004126469914654"},"Rollup \u4e0e Webpack \u7684 Tree-shaking")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7157902763534319624"},"\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7160467329334607908"},"\u3010Webpack Plugin\u3011\u5199\u4e86\u4e2a\u63d2\u4ef6\u8ddf\u559c\u6b22\u7684\u5973\u751f\u8868\u767d\uff0c\u7ed3\u679c......\ud83d\ude2d\ud83d\ude2d\ud83d\ude2d")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000012081469"},"\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0a\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://segmentfault.com/a/1190000012099163"},"\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0b\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7164175171358556173"},"\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7170852747749621791"},"\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7176963906844246074"},"Webpack\u6df1\u5ea6\u8fdb\u9636\uff1a\u4e24\u5f20\u56fe\u5f7b\u5e95\u8bb2\u660e\u767d\u70ed\u66f4\u65b0\u539f\u7406\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/_MJq-88MNFyvDTxUw_lFiA"},"Webpack4\u7684\u538b\u7f29\u9636\u6bb5\u7684\u6027\u80fd\u4f18\u5316\u548c\u8e29\u5751")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7093880734246502414"},"Vue3\u751f\u547d\u5468\u671fHooks\u7684\u539f\u7406\u53ca\u5176\u4e0e\u8c03\u5ea6\u5668(Scheduler)\u7684\u5173\u7cfb")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7064740689178787871"},"\u3010\ud83d\udc2f\u521d/\u4e2d\u7ea7\u524d\u7aef\u9762\u7ecf\u3011\u4e2d\u5c0f\u578b\u516c\u53f8\u9762\u8bd5\u65f6\u90fd\u4f1a\u95ee\u4e9b\u4ec0\u4e48")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7177216308843380797"},"\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0a\uff09\uff1a\u4e3a\u4ec0\u4e48\u662f Zustand")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7182462103297458236"},"\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0b\uff09\uff1a\u57fa\u4e8e Zustand \u7684\u6e10\u8fdb\u5f0f\u72b6\u6001\u7ba1\u7406\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg"},"\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/pDXhIMFkyMuiVHB0l9gphw"},"\u5982\u4f55\u4f7f\u7528jenkins\u642d\u5efa\u4e00\u4e2a\u4e2d\u5c0f\u4f01\u4e1a\u524d\u7aef\u9879\u76ee\u90e8\u7f72\u73af\u5883")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7129298214959710244"},"\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6991640600533532679"},"\u8ddf\u7740\u6765\uff0c\u4f60\u4e5f\u53ef\u4ee5\u624b\u5199VueRouter")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/6997968693414084644"},"\u300c\u786c\u6838JS\u300d\u56fe\u89e3Promise\u8ff7\u60d1\u884c\u4e3a\uff5c\u8fd0\u884c\u673a\u5236\u8865\u5145")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7007946894605287432"},"\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0a\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7012774158371127326"},"\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0b\uff09")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/aLQVpglTRA0bJGyCpXOD8Q"},"\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684 async\u3001await \u7ec6\u8282")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7200039970575941693"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u7269\u7406\u6548\u679c-\u78b0\u649e\u548c\u58f0\u97f3 \ud83d\udca5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7191415427350659129"},"Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u65b0\u6625\u7279\u5178-Rabbit craft go \ud83d\udc07")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7212235580104917053"},"\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300d\u81ea\u5df1\u52a8\u624b\u5b9e\u73b0\u4e00\u4e2aJSX\u8f6c\u6362")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7212603037667786813"},"\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dFiber\u67b6\u6784\u7684\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7213362704781852730"},"\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dReconciler\u67b6\u6784\u7684\u53cc\u7f13\u5b58\u6811\u5b9e\u73b0\u539f\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/QcQlOscF9R0aF2x3Oe6doQ"},"\u3010webpack\u6838\u5fc3\u5e93\u3011\u8017\u65f67\u4e2a\u5c0f\u65f6\uff0c\u7528\u8fd150\u5f20\u56fe\u6765\u5b66\u4e60enhance-resolve\u4e2d\u7684\u6570\u636e\u6d41\u52a8\u548c\u63d2\u4ef6\u8c03\u5ea6\u673a\u5236")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://juejin.cn/post/7199832444836593725"},"\u804a\u804a Ant Design V5 \u7684\u4e3b\u9898\uff08\u4e0a\uff09\uff1aCSSinJS \u52a8\u6001\u4e3b\u9898\u7684\u82b1\u6d3b")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/sTBFnSLS-WBjMWDokH2o9A"},"\u5199\u7ed9\u5f00\u53d1\u540c\u5b66AI\u5f3a\u5316\u5b66\u4e60\u5165\u95e8\u6307\u5357")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/d0zbdhTctR7L_62SaY_VJA"},"\u4e00\u8d77\u6765\u770b\u770b\u4e00\u4e2a\u4f53\u7cfb\u5b8c\u5584\u7684\u524d\u7aefReact\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u642d\u5efa\u51fa\u6765\u7684\uff01")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/z4GhUr5eA-4WbxVye4hmAQ"},"\u5e72\u8d27 | \u8017\u65f6\u7f29\u77ed2/3\uff0cTaro\u7f16\u8bd1\u6253\u5305\u4f18\u5316\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/g1XhCtfIL6yy-37Y_grtEw"},"\u5e72\u8d27 | 30+\u6761\u4e1a\u52a1\u7ebf\uff0c\u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u534f\u540c\u5f00\u53d1")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/PT4y8OMWTpIto50qnT8gmg"},"\u5e72\u8d27 | \u79d2\u5f00\u738770%+\uff0c\u643a\u7a0b\u91d1\u878dSSR\u5e94\u7528\u6027\u80fd\u76d1\u6d4b\u4e0e\u4f18\u5316")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/293Lbr81oUWHeJ3TGfPRdw"},"\u5e72\u8d27 | \u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u8fdb\u884cSize\u6cbb\u7406")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/iT05ZXPVYFuCQgZZF9Zu5w"},"\u5e72\u8d27 | \u643a\u7a0b\u5c0f\u7a0b\u5e8f\u751f\u6001\u4e4bTaro\u8de8\u7aef\u89e3\u51b3\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/rpHb5ZhUTOTfbVPEZJFklg"},"\u5e72\u8d27 | \u7626\u8eab50%-70%\uff0c\u643a\u7a0b Taro \u5c0f\u7a0b\u5e8f\u6837\u5f0f Size \u7f29\u51cf\u65b9\u6848")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/HUJTU5Du6318LJ7RfQNN2g"},"\u5e72\u8d27 | \u643a\u7a0b\u5546\u65c5\u5927\u524d\u7aef React Streaming \u7684\u63a2\u7d22\u4e4b\u8def")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/JiJhA6AfNiGXl7p0uQ8mGA"},"\u5e72\u8d27 | \u643a\u7a0b\u5ea6\u5047\u57fa\u4e8e RPC \u548c TypeScript \u7684 BFF \u8bbe\u8ba1\u4e0e\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/OHbzuqUl3tL1YlpLOgEkvA"},"INP \u5373\u5c06\u4ee3\u66ff FID \u6210\u4e3a\u65b0\u7684\u6838\u5fc3 Web \u6307\u6807")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/2Dy5RsviZlo7SPA648Mj3g"},"\u3010\u7b2c2973\u671f\u3011\u643a\u7a0bWeb\u7ec4\u4ef6\u5728\u8de8\u7aef\u573a\u666f\u7684\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/yPRPakU1UM5iVY-1bwiHJQ"},"\u8fd9\u4e9b\u5e74\u5728\u963f\u91cc\u5b66\u5230\u7684\u65b9\u6cd5\u8bba")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/ganW_F5GhQV-8s9N2y7jaw"},"/[\u901a\u660e\u5883 \xb7 React\u67b6\u6784/]\u901a\u4fd7\u5730\u8bb2React\uff0c\u4f18\u96c5\u5730\u7406\u89e3React")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/daHYuCfstHYqAtscn5T4WQ"},"React-Router 6.10+KeepAlive\u7684\u7ea6\u5b9a\u5f0f\u8def\u7531\u6700\u4f73\u5b9e\u8df5")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/MWf07S5avWzK7vdzhpFsoA"},"\u5e72\u8d27\uff01\u6211\u662f\u5982\u4f55\u5728\u4e00\u7ebf\u5927\u5382\u5b9e\u8df5webpack\u4f18\u5316\u7684")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/WV3oztPYZyGiv4hW0--Jkw"},"\u6d45\u8c08\u9886\u57df\u9a71\u52a8\u5728\u524d\u7aef\u7684\u5e94\u2f64")),(0,n.kt)("li",{parentName:"ul"},(0,n.kt)("a",{parentName:"li",href:"https://mp.weixin.qq.com/s/Z-8lsdLeTqCeFZ4w2oNBjg"},"Chrome 117 \u53d1\u5e03\uff1a\u65b0 Web \u5f00\u53d1\u8c03\u8bd5\u6280\u5de7\u90fd\u5728\u8fd9\u4e86\uff01"))))}T.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/59c08185.185e672d.js b/assets/js/59c08185.185e672d.js deleted file mode 100644 index b336eeaf64..0000000000 --- a/assets/js/59c08185.185e672d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[9699],{49613:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var p=n(59496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);t&&(p=p.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,p)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(p=0;p=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=p.createContext({}),s=function(e){var t=p.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return p.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return p.createElement(p.Fragment,{},t)}},h=p.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=s(n),h=a,k=c["".concat(l,".").concat(h)]||c[h]||u[h]||r;return n?p.createElement(k,i(i({ref:t},m),{},{components:n})):p.createElement(k,i({ref:t},m))}));function k(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>s});var p=n(64778),a=(n(59496),n(49613));const r={slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},i=void 0,o={permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-10/index.md",source:"@site/blogs/2024/2024-03-10/index.md",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",description:"alt text",date:"2024-03-10T00:00:00.000Z",formattedDate:"March 10, 2024",tags:[],readingTime:34.7,hasTruncateMarker:!1,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},prevItem:{title:"\u7f6e\u9876\u5185\u5bb9",permalink:"/frontend-weekly/2024/welcome"},nextItem:{title:"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"}},l={authorsImageUrls:[void 0]},s=[{value:"\ud83c\udf1f AI \u76f8\u5173",id:"-ai-\u76f8\u5173",level:2},{value:"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173",id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173",id:"-\u540e\u7aef\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173",id:"-\u524d\u7aef\u76f8\u5173",level:2}],m={toc:s},c="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(c,(0,p.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"alt text",src:n(7662).Z,width:"1280",height:"720"})),(0,a.kt)("p",null,"\u5c01\u9762\u56fe\uff1aUnderstanding the Go runtime - Jesus Espino"),(0,a.kt)("h2",{id:"-ai-\u76f8\u5173"},"\ud83c\udf1f AI \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://arxiv.org/abs/2401.11624"},"\u300aIn-context Learning with Retrieved Demonstrations for Language Models: A Survey\u300b"),'\u3002\u8fd9\u7bc7\u9898\u4e3a "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" \u7684\u6587\u7ae0\uff0c\u4e3b\u8981\u8ba8\u8bba\u4e86\u8bed\u8a00\u6a21\u578b\uff0c\u5c24\u5176\u662f\u5927\u578b\u9884\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u5982\u4f55\u901a\u8fc7\u83b7\u53d6\u7684\u6f14\u793a\u8fdb\u884c\u5c11\u91cf\u60c5\u666f\u5b66\u4e60\u3002\u8fd9\u9879\u6280\u672f\u80fd\u6709\u6548\u5730\u6539\u8fdb\u5b66\u4e60\u8fc7\u7a0b\u7684\u6548\u7387\u548c\u53ef\u6269\u5c55\u6027\uff0c\u5e76\u964d\u4f4e\u624b\u52a8\u9009\u62e9\u6837\u4f8b\u65f6\u7684\u56fa\u6709\u504f\u89c1\u3002\u6587\u7ae0\u5bf9\u6b64\u9886\u57df\u8fdb\u884c\u4e86\u5e7f\u6cdb\u7684\u7814\u7a76\u56de\u987e\uff0c\u5bf9\u68c0\u7d22\u6a21\u578b\u3001\u68c0\u7d22\u8bad\u7ec3\u8fc7\u7a0b\u548c\u63a8\u7406\u7b97\u6cd5\u7684\u4e0d\u540c\u8bbe\u8ba1\u9009\u62e9\u8fdb\u884c\u4e86\u8ba8\u8bba\u548c\u6bd4\u8f83\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NUhEy0YLTjtzY3BGVXhfrw"},"\u300a\u78be\u538bLoRA\uff01Meta & CMU | \u63d0\u51fa\u9ad8\u6548\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\uff1aGaLore\uff0c\u5185\u5b58\u53ef\u51cf\u5c1163.3%\u300b"),"\u3002Meta\u548cCMU\u5408\u4f5c\u63d0\u51fa\u4e86\u4e00\u79cd\u65b0\u7684\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\u2014\u2014Gradient Low-Rank Projection\uff08GaLore\uff09\u3002GaLore\u901a\u8fc7\u68af\u5ea6\u7684\u4f4e\u79e9\u6295\u5f71\u4ee3\u66ff\u6743\u91cd\u7684\u4f4e\u79e9\u9002\u914d\uff0c\u4e0d\u4ec5\u652f\u6301\u5168\u53c2\u6570\u5b66\u4e60\uff0c\u800c\u4e14\u663e\u8457\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\uff0c\u51cf\u5c11\u4e8663.3%\u7684\u5185\u5b58\u9700\u6c42\u3002\u4e0d\u540c\u4e8eLoRA\u7684\u4f4e\u79e9\u6743\u91cd\u66f4\u65b0\uff0cGaLore\u5229\u7528\u6743\u91cd\u68af\u5ea6\u7684\u4f4e\u79e9\u7279\u6027\uff0c\u7ed3\u5408\u9010\u5c42\u6743\u91cd\u66f4\u65b0\u548c8\u4f4d\u4f18\u5316\u5668\uff0c\u6709\u6548\u5730\u4f18\u5316\u4e86\u5185\u5b58\u6548\u7387\u3002\u6b64\u5916\uff0cGaLore\u8fd8\u5f15\u5165\u4e86\u53ef\u8c03\u6574\u7684\u8d85\u53c2\u6570\uff0c\u63d0\u9ad8\u4e86\u5176\u9002\u5e94\u6027\u3002\u7ecf\u5b9e\u9a8c\u9a8c\u8bc1\uff0cGaLore\u7684\u8868\u73b0\u4f18\u4e8eLoRA\uff0c\u5c24\u5176\u662f\u5728\u9884\u8bad\u7ec3\u6a21\u578b\u5fae\u8c03\u4e0a\u8868\u73b0\u66f4\u4f73\uff0c\u4e3a\u5927\u6a21\u578b\u8bad\u7ec3\u63d0\u4f9b\u4e86\u65b0\u7684\u89e3\u51b3\u7b56\u7565\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7316592794109198387"},"\u4f7f\u7528 GPT4V+AI Agent \u505a\u81ea\u52a8 UI \u6d4b\u8bd5\u7684\u63a2\u7d22 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZSDCNDRu-tCkOlC9jz2j4w"},"Gemini\u4feebug\u795e\u4e86\uff01\u5f55\u7f51\u9875\u89c6\u9891\u628a\u4ee3\u7801\u5e93\u7529\u7ed9\u5b83\u5c31\u884c\uff0c\u7f51\u53cb\u5750\u4e0d\u4f4f\u4e86\uff1a\u60f3\u8981\u8bbf\u95ee\u6743\u9650")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GXwftkv-UpDQSjiTMn9TFA"},"\u4e00\u952e\u5f00\u542f GPU \u95f2\u7f6e\u6a21\u5f0f\uff0c\u57fa\u4e8e\u51fd\u6570\u8ba1\u7b97\u4f4e\u6210\u672c\u90e8\u7f72 Google Gemma \u6a21\u578b\u670d\u52a1")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/YDwL3dV-Fq5zcEyrL__NGw"},"\u300aYi\u6280\u672f\u62a5\u544a\u7ec6\u8282\u5206\u4eab\u300b"),"\u3002\u8be5\u6587\u7ae0\u5206\u4eab\u4e86Yi\u6a21\u578b\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u548c\u601d\u8def\uff0c\u5f3a\u8c03\u4e86\u6a21\u578b\u8bbe\u8ba1\u56f4\u7ed5\u6a21\u578b\u89c4\u6a21\u3001\u6570\u636e\u89c4\u6a21\u548c\u6570\u636e\u8d28\u91cf\u3002Yi\u6a21\u578b\u7684\u9884\u8bad\u7ec3\u9636\u6bb5\u6570\u636e\u5904\u7406\u6d41\u7a0b\u5305\u62ec\u542f\u53d1\u5f0f\u8fc7\u6ee4\u3001\u5b66\u4e60\u5f0f\u8fc7\u6ee4\u3001\u805a\u7c7b\u8fc7\u6ee4\u4ee5\u53ca\u53bb\u91cd\u7b49\u6b65\u9aa4\uff0c\u4ee5\u63d0\u9ad8\u6570\u636e\u8d28\u91cf\u3002\u5fae\u8c03\u9636\u6bb5\uff0cYi\u6a21\u578b\u4ec5\u91c7\u7528\u4e8610K\u6570\u636e\u8fdb\u884c\u6a21\u578b\u5fae\u8c03\uff0c\u5f3a\u8c03\u6570\u636e\u8d28\u91cf\u80dc\u8fc7\u6570\u91cf\u3002\u5728\u5206\u8bcd\u5668\u3001\u6a21\u578b\u7ed3\u6784\u53ca\u5fae\u8c03\u53c2\u6570\u65b9\u9762\uff0cYi\u6a21\u578b\u91c7\u7528\u4e86\u4e00\u7cfb\u5217\u4f18\u5316\u63aa\u65bd\uff0c\u5305\u62ecTransformer-Decoder\u7ed3\u6784\u3001Grouped-Query Attention\u7b49\u3002\u603b\u7684\u6765\u8bf4\uff0cYi\u6a21\u578b\u901a\u8fc7\u4f18\u5316\u6570\u636e\u5904\u7406\u6d41\u7a0b\u3001\u5fae\u8c03\u7b56\u7565\u3001\u8c03\u6574\u6a21\u578b\u7ed3\u6784\u548c\u53c2\u6570\u7b49\u591a\u65b9\u9762\u5b9e\u73b0\u4e86\u9ad8\u6548\u7684\u6280\u672f\u5b9e\u73b0\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lBXwSVvRHB2Yn0fYoOkDeQ"},"\u91cd\u65b0\u5b9a\u4e49\u5927\u6a21\u578b\u63a8\u7406\uff01Google | \u63d0\u51faSELF-DISCOVER\u6846\u67b6\uff0c\u5927\u6a21\u578b\u53ef\u81ea\u5199\u63a8\u7406\u7ed3\u6784\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/cB5tgMUPqg8fsXjNrzQpbg"},"\u300a\u65af\u5766\u798f && \u5fae\u8f6f | \u53d1\u5e03\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u52a9\u529b\u524d\u7aef\u81ea\u52a8\u5316\uff01\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u5b83\u53ef\u4ee5\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u7684\u6311\u6218\u6027\u548c\u73b0\u6709\u65b9\u6cd5\u7684\u5c40\u9650\u6027\uff0c\u7136\u540e\u63d0\u51fa\u4e86Design2Code\u57fa\u51c6\u548c\u591a\u6a21\u6001\u63d0\u793a\u65b9\u6cd5\uff0c\u4ee5\u6fc0\u53d1\u591a\u6a21\u6001\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u5982GPT-4V\u548cGemini\uff09\u7684\u6f5c\u529b\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5f00\u6e90\u768418B\u5fae\u8c03\u6a21\u578bDesign2Code-18B\uff0c\u5b83\u57fa\u4e8eCogAgent-18B\uff0c\u5728\u591a\u79cd\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u4e86\u9884\u8bad\u7ec3\uff0c\u5e76\u4f7f\u7528\u4e86Huggingface\u53d1\u5e03\u7684WebSight\u6570\u636e\u96c6\u8fdb\u884c\u5fae\u8c03\u3002\u6700\u540e\uff0c\u6587\u7ae0\u5c55\u793a\u4e86Design2Code-18B\u5728Design2Code\u57fa\u51c6\u4e0a\u7684\u4f18\u8d8a\u6027\u80fd\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u4e9b\u672a\u6765\u7814\u7a76\u65b9\u5411\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Pdp6_z_rxBl-kph41Lb8Ww"},"\u53ef\u63a7\u6587\u672c\u751f\u6210\u65b0\u65b9\u6cd5\uff0c\u4eba\u5927&&\u5357\u5f00 | \u63d0\u51faDATG\u67b6\u6784\uff0c\u51c6\u786e\u6027\u63d0\u534719.29%\uff0c\u6548\u7387\u63d0\u53471\u500d")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/53jEDw58dkZlJAVzr31G8A"},"\u300aAuto-Prompt | \u5927\u6a21\u578b\u63d0\u793a(Prompt)\u4f18\u5316\u65b0\u65b9\u6cd5IPC\uff1a\u53ef\u6839\u636e\u7528\u6237\u610f\u56fe\u8fdb\u884c\u5b9a\u5411\u4f18\u5316\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3a Intent-based Prompt Calibration\uff08IPC\uff09\u7684\u7cfb\u7edf\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u901a\u8fc7\u4f7f\u7528\u5408\u6210\u6848\u4f8b\u6837\u672c\u6765\u4f18\u5316\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u63d0\u793a\u5de5\u7a0b\u3002\u5b83\u57fa\u4e8e\u6a21\u578b\u751f\u6210\u7684\u6570\u636e\u96c6\u8fdb\u884c\u63d0\u793a\u4f18\u5316\uff0c\u4ee5\u89e3\u51b3\u5927\u8bed\u8a00\u6a21\u578b\u5bf9\u7ed9\u5b9a\u63d0\u793a\u7684\u654f\u611f\u6027\u7b49\u95ee\u9898\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u6838\u5fc3\u601d\u60f3\u662f\u6839\u636e\u7528\u6237\u610f\u56fe\u8fed\u4ee3\u7ec6\u5316\u63d0\u793a\u3002\u540c\u65f6\uff0c\u6587\u7ae0\u8fd8\u5bf9 IPC \u7cfb\u7edf\u7684\u6574\u4f53\u67b6\u6784\u548c\u5b9e\u73b0\u6d41\u7a0b\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u5c55\u793a\u4e86\u4e00\u4e9b\u5b9e\u9a8c\u7ed3\u679c\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u300a\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u51e0\u79cd\u65b0\u578b\u7684\u667a\u80fd Agent \u8bbe\u8ba1\u65b9\u6cd5\uff0c\u5305\u62ec Plan-and-Execute Agents\u3001ReWOO Agent \u548c LLMCompiler\u3002Plan-and-Execute Agent \u8bbe\u8ba1\u6cd5\u901a\u8fc7\u660e\u786e\u89c4\u5212\u6765\u4f18\u5316\u667a\u80fd Agent \u529f\u80fd\u3002ReWOO Agent \u8bbe\u8ba1\u6cd5\u51ed\u501f\u53d8\u91cf\u5206\u914d\u529f\u80fd\u4f7f\u5f97\u4e0d\u5fc5\u5bf9\u6bcf\u4e2a\u4efb\u52a1\u90fd\u4f7f\u7528 LLM\u3002LLMCompiler \u5219\u901a\u8fc7\u4efb\u52a1\u683c\u5f0f\u5316\u4e3a DAG \u6765\u63d0\u9ad8\u5de5\u5177\u8c03\u7528\u7684\u6548\u7387\u3002\u8fd9\u4e9b\u65b0\u578b\u8bbe\u8ba1\u90fd\u5728\u4e0d\u540c\u7a0b\u5ea6\u4e0a\u4f18\u5316\u4e86\u667a\u80fd Agent \u7684\u5de5\u4f5c\u6d41\u7a0b\uff0c\u63d0\u9ad8\u4e86\u5de5\u4f5c\u6548\u7387\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/F2s3pKycoNDT7Z-6piRHWg"},"\u300aOpenAI Function Calling \u4e0e LangChain Agent \u5de5\u4f5c\u539f\u7406\u53ca\u533a\u522b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86OpenAI Function Calling \u4e0e LangChain Agent\u7684\u5de5\u4f5c\u539f\u7406\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6587\u7ae0\u9996\u5148\u5217\u4e3e\u4e86\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u9650\u5236\uff0c\u5e76\u89e3\u91ca\u4e86\u4e3a\u4f55\u9700\u8981Agent\u3002\u7136\u540e\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86React Agent\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u901a\u8fc7\u201cReason Only\u201d\uff08\u5411\u5185\u6c42\u7d22\uff09\u3001\u201cAct Only\u201d\uff08\u5411\u5916\u63a2\u7d22\uff09\u548c\u201cReAct\u201d\uff08\u5185\u5916\u517c\u4fee\uff09\u4e09\u79cd\u6a21\u5f0f\u4f18\u5316\u6a21\u578b\u7684\u529f\u80fd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u4ee5\u4e00\u4e2a\u7b80\u5355\u7684\u5b9e\u4f8b\uff0c\u89e3\u91ca\u4e86\u5982\u4f55\u5229\u7528ReAct Agent\u6765\u89e3\u7b54\u4e00\u4e2a\u5305\u542b\u641c\u7d22\u548c\u8ba1\u7b97\u4e24\u4e2a\u6b65\u9aa4\u7684\u95ee\u9898\uff0c\u5c55\u793a\u4e86\u5176\u5b9e\u9645\u5e94\u7528\u7684\u6d41\u7a0b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iM45toKEHr3_rJxuwbgp4w"},"\u300aReAct Agent \u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u7684\u590d\u6742\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u201cReAct Agent \u7528\u4e8e\u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u590d\u6742\u95ee\u9898\u7684\u65b9\u5f0f\u201d\u3002\u968f\u7740\u8f93\u5165\u95ee\u9898\u7684\u590d\u6742\u5ea6\u5347\u9ad8\uff0c\u4f7f\u7528\u4f20\u7edf\u7684\u804a\u5929\u673a\u5668\u4eba\u5df2\u4e0d\u80fd\u8db3\u591f\u6709\u6548\u3002\u4e8e\u662f\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u5229\u7528 ReAct Agent\uff0c\u901a\u8fc7\u81ea\u7136\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u9010\u6b65\u89c4\u5212\u5e76\u6267\u884c\u5904\u7406\u95ee\u9898\u7684\u6b65\u9aa4\uff0c\u5e76\u5b9a\u4e49\u529f\u80fd\u6027\u5de5\u5177\uff08\u5982\u65f6\u95f4\u8ba1\u7b97\u3001\u6587\u672c\u641c\u7d22\u3001\u5217\u8868\u957f\u5ea6\u8ba1\u7b97\u3001\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\u7b49\uff09\u4ee5\u8f85\u52a9\u4efb\u52a1\u5b8c\u6210\u3002\u8fd9\u79cd\u65b9\u6cd5\u80fd\u591f\u66f4\u597d\u5730\u5e72\u9884\u548c\u63a7\u5236\u95ee\u9898\u7684\u89e3\u51b3\u8fc7\u7a0b\uff0c\u4ece\u800c\u63d0\u9ad8\u4efb\u52a1\u7684\u5b8c\u6210\u8d28\u91cf\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KF7joY-MkK4BZ8Rf8bLArw"},"ChatGPT\u4e5f\u80fd\u753b\u56fe\uff1f\u6559\u4f60\u4e00\u952e\u751f\u6210\u65f6\u5e8f\u56fe\u3001\u7c7b\u56fe\u3001\u6d41\u7a0b\u56fe\u3001\u72b6\u6001\u56fe\u4ee5\u53ca\u7528\u4f8b\u56fe")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/E2xwi9SNYQ7sdzhYlaDQFg"},"\u4e09\u4e2a\u88ab\u5ffd\u89c6\u7684\u5927\u6a21\u578b\u63d0\u793a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/u2LCRgBhKKcGZhY29PjIng"},"\u5173\u4e8eSora\u548cStable Diffusion 3\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/z6IFIuHawVZI6ZOfgvgKuA"},"\u6d88\u8d39\u7ea7\u663e\u5361\u53ef\u7528\uff01\u674e\u5f00\u590d\u96f6\u4e00\u4e07\u7269\u53d1\u5e03\u5e76\u5f00\u6e9090\u4ebf\u53c2\u6570Yi\u6a21\u578b\uff0c\u4ee3\u7801\u6570\u5b66\u80fd\u529b\u53f2\u4e0a\u6700\u5f3a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IBh3ytd3gtizAQd5PI2uig"},"\u8be6\u89e3\u5927\u6a21\u578b\u5fae\u8c03\u5168\u6d41\u7a0b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/UzC3J_TOzJPEx_86-lRwuw"},"\u5357\u5927\u4fde\u626c\u6559\u6388\uff1a\u4ec0\u4e48\u662fworld models/\u4e16\u754c\u6a21\u578b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Gi6pzD7wAMyzlCBSSWkVLA"},"\u6df1\u5165\u6d45\u51faLangChain\u4e0e\u667a\u80fdAgent\uff1a\u6784\u5efa\u4e0b\u4e00\u4ee3AI\u52a9\u624b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/T9YRVRGMgkwRSTl7Movadg"},"\u5c24\u6d0b\u6559\u6388\uff1a\u5f00\u6e90\u5b8c\u6574\u7684Sora\u590d\u73b0\u65b9\u6848\u6765\u4e86\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/8WYWrHyE4oryCgO9AemImA"},"\u300aT-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"T-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86T-RAG\u6280\u672f\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06RAG\u67b6\u6784\u4e0e\u5fae\u8c03\u8bed\u8a00\u6a21\u578b\u548c\u5b9e\u4f53\u6811\u5411\u91cf\u6570\u636e\u5e93\u76f8\u7ed3\u5408\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u652f\u6301\u8bed\u5883\u68c0\u7d22\u3002\u5b83\u6982\u8ff0\u4e86\u5728\u654f\u611f\u6587\u6863\u7684\u80cc\u666f\u4e0b\u5982\u4f55\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u6709\u9650\u7684\u8ba1\u7b97\u8d44\u6e90\u548c\u57fa\u4e8e\u73b0\u6709\u6587\u6863\u5efa\u7acb\u7684\u5c0f\u578b\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u4fdd\u8bc1\u7528\u6237\u63d0\u95ee\u7684\u51c6\u786e\u56de\u7b54\u3002\u6587\u4e2d\u8fd8\u7740\u91cd\u4ecb\u7ecd\u4e86T-RAG\u7684\u5de5\u4f5c\u6d41\u7a0b\u548c\u5b9e\u4f53\u6811\u7684\u4f5c\u7528\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u51fa\u4e86\u4e00\u4e2a\u65b0\u7684\u8bc4\u4f30\u6307\u6807\u201cCorrect-Verbose\u201d\uff0c\u7528\u4ee5\u8bc4\u4ef7\u751f\u6210\u56de\u590d\u7684\u8d28\u91cf\u3002\u6b64\u7814\u7a76\u4e0d\u4ec5\u662f\u7406\u8bba\u7814\u7a76\uff0c\u4e5f\u662f\u5b9e\u8df5\u4e2dLLM\u5e94\u7528\u7684\u7ecf\u9a8c\u603b\u7ed3\uff0c\u5177\u6709\u5b9e\u9645\u7684\u6307\u5bfc\u610f\u4e49\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/de3UxM9WTrHNjnOKSny0aw"},"\u300a\u9ad8\u7ea7 RAG\uff08Self-Reflective RAG\uff09\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u9ad8\u7ea7 RAG(Self-Reflective RAG)"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86Self-Reflective RAG\u7684\u7406\u5ff5\u548c\u5de5\u4f5c\u6d41\u7a0b\u3002\u5728\u57fa\u672c\u7684RAG pipeline\u4e2d\uff0c\u6211\u4eec\u7684\u8fc7\u7a0b\u5f80\u5f80\u53d7\u9650\u4e8e\u88ab\u52a8\u7684\u68c0\u7d22\u548c\u751f\u6210\uff0c\u800c\u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u751f\u6210\u7684\u7ed3\u679c\u8fdb\u884c\u4f18\u5316\uff0c\u5982\u6539\u53d8\u95ee\u9898\u6216\u7b5b\u9009\u548c\u6392\u5217\u5185\u5bb9\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u81ea\u6211\u4fee\u6b63\u6846\u67b6\uff0c\u5305\u62ecCorrective RAG(CRAG)\u548cSelf-Reflective RAG\u3002\u8fd9\u4e24\u79cdRAG\u90fd\u56f4\u7ed5\u7740\u5bf9\u68c0\u7d22\u548c\u751f\u6210\u5185\u5bb9\u7684\u8bc4\u4f30\u548c\u53cd\u9988\u8fdb\u884c\u81ea\u6211\u4fee\u6b63\uff0c\u5e76\u901a\u8fc7\u7279\u5b9a\u6807\u8bc6\u8fdb\u884c\u8c03\u63a7\u3002\u5728\u4e00\u5b9a\u6761\u4ef6\u4e0b\uff0c\u8fdb\u4e00\u6b65\u6539\u8fdb\u4e86RAG\uff0c\u4f7f\u5176\u4ea7\u751f\u66f4\u597d\u7684\u68c0\u7d22\u548c\u751f\u6210\u6548\u679c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WuJEubctUDsAmdhHcDItAg"},"RAG\u4e0d\u591f\u806a\u660e\uff1f\u6253\u9020\u66f4\u5f3a\u5927\u7684\u667a\u80fd\u4f53")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/b_eWGauwi6v0w4CoSOnU5w"},"Anthropic\u53d1\u5e03Claude3\uff0c\u6548\u679c\u5df2\u8d85\u8d8aGPT4")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/nMWTuKBnQVjgAM7Du6oOFQ"},"\u4ece0\u5f00\u59cb\u9884\u8bad\u7ec31.4b\u4e2d\u6587\u5927\u6a21\u578b\u5b9e\u8df5")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/W5W582CqxvRhF3wnKwIdiQ"},"\u300a\u5206\u7c7b\u7b97\u6cd5\u5165\u95e8:\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\uff0c\u5168\u9762\u800c\u8be6\u7ec6\u5730\u9610\u8ff0\u4e86\u673a\u5668\u5b66\u4e60\u4e2d\u7684\u5206\u7c7b\u7b97\u6cd5\u57fa\u7840\u77e5\u8bc6\u3002\u9996\u5148\u4ecb\u7ecd\u4e86\u4eba\u5de5\u667a\u80fd\u3001\u673a\u5668\u5b66\u4e60\u548c\u6df1\u5ea6\u5b66\u4e60\u7684\u57fa\u672c\u6982\u5ff5\uff0c\u8bb2\u89e3\u4e86\u673a\u5668\u5b66\u4e60\u5404\u79cd\u5206\u7c7b\u65b9\u6cd5\u7684\u7406\u8bba\u80cc\u666f\u3002\u968f\u540e\u901a\u8fc7\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528 Python \u5de5\u5177\uff08\u5305\u62ec pandas\u3001sklearn\u3001matplotlib \u548c seaborn\uff09\u8fdb\u884c\u6570\u636e\u5904\u7406\u3001\u5206\u6790\u548c\u53ef\u89c6\u5316\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u8ff0\u4e86\u51b3\u7b56\u6811\u3001\u903b\u8f91\u56de\u5f52\u3001\u652f\u6301\u5411\u91cf\u673a\u3001K\u8fd1\u90bb\u7b49\u7ecf\u5178\u7684\u5206\u7c7b\u7b97\u6cd5\uff0c\u5e76\u7528\u56fe\u5f62\u5316\u7684\u65b9\u5f0f\u5c55\u793a\u4e86\u5206\u7c7b\u6548\u679c\u3002\u6700\u540e\uff0c\u8bfb\u8005\u53ef\u4ee5\u901a\u8fc7\u672c\u6587\u6240\u63d0\u4f9b\u7684\u4e30\u5bcc\u5b66\u4e60\u8d44\u6599\u6765\u6df1\u5316\u5bf9\u673a\u5668\u5b66\u4e60\u5206\u7c7b\u4efb\u52a1\u7684\u7406\u89e3\u548c\u5e94\u7528\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fkRG7n4tOQKwU85xiEx0Eg"},"\u300a\u4e07\u5b57\u8be6\u89e3LLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u5199\u5728\u8de8\u5e74\u4e4b\u524d\uff1a\u804a\u804aLLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765"\uff0c\u4e3b\u8981\u6d89\u53ca\u5230LLM Agents\u7684\u5f53\u524d\u72b6\u6001\uff0c\u9762\u4e34\u7684\u95ee\u9898\u548c\u672a\u6765\u7684\u53ef\u80fd\u53d1\u5c55\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5305\u62ec\u5168\u53c2\u5fae\u8c03\u3001Prompt Tuning\u3001LoRA\u3001P-Tuning\u7b49\u5728\u5185\u7684SFT(Selective Fine Tuning)\u8303\u7574\u7684\u5404\u79cd\u6280\u672f\u3002\u5176\u4e2d\u5c24\u5176\u5f3a\u8c03\u4e86\u5bf9\u4e8e{prompt\uff0cresponse}\u7684\u5355\u8f6e\u95ee\u7b54\u5bf9\u7684\u5fae\u8c03\u662f\u6700\u7b80\u5355\u7684SFT\u5b9e\u73b0\u65b9\u5f0f\u3002\u5177\u4f53\u7684\u5185\u5bb9\u7ec6\u8282\u5927\u6982\u9700\u8981\u9605\u8bfb\u539f\u6587\u624d\u80fd\u83b7\u5f97\u66f4\u6df1\u5165\u7684\u7406\u89e3\u3002'),(0,a.kt)("h2",{id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173"},"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/generic-slice-functions"},"\u300aRobust generic functions on slices\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Robust generic functions on slices"\uff0c\u4e3b\u8981\u63a2\u8ba8\u4e86Go\u7684slices\u5305\u5982\u4f55\u63d0\u4f9b\u5bf9\u5207\u7247\u8fdb\u884c\u64cd\u4f5c\u7684\u901a\u7528\u51fd\u6570\u3002\u8be5\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u7c7b\u578b\u53c2\u6570\uff0c\u4e00\u6b21\u6027\u4e3a\u6240\u6709\u7c7b\u578b\u7684\u5207\u7247\u7f16\u5199\u7c7b\u4f3cslices.Index\u7b49\u51fd\u6570\uff0c\u800c\u65e0\u9700\u9488\u5bf9\u6bcf\u79cd\u4e0d\u540c\u7684\u5143\u7d20\u7c7b\u578b\u91cd\u65b0\u5b9e\u73b0\u3002\u968f\u540e\uff0c\u6587\u7ae0\u6df1\u5165\u8bb2\u8ff0\u4e86\u65b0\u7684\u51fd\u6570\uff08\u5982Insert, Replace\uff0cDelete\u7b49\uff09\u5982\u4f55\u4fee\u6539\u5207\u7247\uff0c\u5e76\u901a\u8fc7\u8be6\u8ff0\u5207\u7247\u5728\u5185\u5b58\u4e2d\u7684\u8868\u73b0\u5f62\u5f0f\u53ca\u5176\u5bf9\u5783\u573e\u56de\u6536\u5668\u7684\u5f71\u54cd\uff0c\u6765\u5e2e\u52a9\u8bfb\u8005\u7406\u89e3\u8fd9\u4e9b\u51fd\u6570\u7684\u5de5\u4f5c\u65b9\u5f0f\u548c\u6b63\u786e\u4f7f\u7528\u5b83\u4eec\u3002\u6587\u7ae0\u7279\u522b\u6307\u51fa\uff0c\u65b0\u7684Delete\u51fd\u6570\u63d0\u4f9b\u4e86\u66f4\u6e05\u6670\u5730\u8868\u8fbe\u7a0b\u5e8f\u5458\u610f\u56fe\u7684\u65b9\u5f0f\uff0c\u800c\u4e14\u5b83\u4e0d\u9700\u8981\u5206\u914d\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u6e05\u9664\u65e0\u7528\u7684\u5143\u7d20\uff0c\u5e2e\u52a9\u5783\u573e\u56de\u6536\u3002\u6587\u7ae0\u5f3a\u8c03\uff0c\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c\u5fc5\u987b\u8ba4\u4e3a\u539f\u59cb\u5207\u7247\u5df2\u65e0\u6548\uff0c\u56e0\u4e3a\u5e95\u5c42\u6570\u7ec4\u5df2\u88ab\u4fee\u6539\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u5728\u5904\u7406\u5185\u5b58\u6cc4\u6f0f\u548c\u5143\u7d20\u96f6\u503c\u8bbe\u7f6e\u7b49\u95ee\u9898\u65f6\u7684\u7b56\u7565\u548c\u9009\u9879\uff0c\u5b83\u4eec\u5728\u65b0\u7248\u672cGo\u7ed9\u51fa\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u6539\u53d8\u53ef\u80fd\u5bfc\u81f4\u7684\u4e00\u4e9b\u6d4b\u8bd5\u95ee\u9898\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9f13\u52b1\u5f00\u53d1\u4eba\u5458\u6b63\u786e\u4f7f\u7528\u65b0\u529f\u80fd\uff0c\u5e76\u5c3d\u91cf\u907f\u514d\u4e0a\u8ff0\u5217\u4e3e\u7684\u9677\u9631\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/routing-enhancements"},"\u300aRouting Enhancements for Go 1.22\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Routing Enhancements for Go 1.22"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86 Go 1.22 \u7248\u672c\u4e2d net/http \u5305\u7684\u8def\u7531\u5668\u63d0\u4f9b\u7684\u65b0\u7279\u6027\uff1a\u65b9\u6cd5\u5339\u914d\u548c\u901a\u914d\u7b26\u3002\u8fd9\u4e9b\u65b0\u7279\u6027\u8ba9\u4f60\u53ef\u4ee5\u4f7f\u7528\u6a21\u5f0f\uff0c\u800c\u975e Go \u4ee3\u7801\uff0c\u6765\u8868\u8fbe\u5e38\u89c1\u7684\u8def\u7531\u3002\u8fd9\u79cd\u65b0\u529f\u80fd\uff0c\u5c3d\u7ba1\u7b80\u5355\u6613\u61c2\uff0c\u4f46\u8981\u9009\u62e9\u51fa\u591a\u4e2a\u5339\u914d\u8bf7\u6c42\u7684\u6700\u4f73\u6a21\u5f0f\u5374\u662f\u4e00\u9879\u6311\u6218\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u9610\u91ca\u4e86\u5982\u4f55\u5728\u65b0\u7248 Go \u4e2d\u4f7f\u7528\u8fd9\u4e9b\u65b0\u7279\u6027\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u5f15\u5165\u7684\u53d8\u5316\u5982\u4f55\u5f71\u54cd\u4e86 ServeMux \u65b9\u6cd5 handle \u548c handleFunc \u3002\u6b64\u5916\uff0c\u8fd8\u63cf\u8ff0\u4e86\u65b0\u6a21\u5f0f\u5982\u4f55\u66f4\u5177\u4f18\u5148\u7ea7\uff0c\u5e76\u89e3\u91ca\u4e86\u5176\u80cc\u540e\u7684\u539f\u7406\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u65b0\u65e7\u7248\u672c\u7684\u517c\u5bb9\u6027\uff0c\u4f5c\u8005\u4eec\u4e5f\u52aa\u529b\u4f7f\u65b0\u7684\u6a21\u5f0f\u8bed\u6cd5\u80fd\u8986\u76d6\u65e7\u7684\uff0c\u5e76\u4f7f\u65b0\u7684\u4f18\u5148\u7ea7\u89c4\u5219\u80fd\u6cdb\u5316\u65e7\u7684\u89c4\u5219\u3002\u603b\u4f53\u4e0a\uff0c\u8fd9\u4e9b\u6539\u53d8\u662f Go \u8bed\u8a00\u56e2\u961f\u4e0d\u65ad\u52aa\u529b\u4f7f Go \u6210\u4e3a\u6784\u5efa\u751f\u4ea7\u7cfb\u7edf\u7684\u4f18\u79c0\u8bed\u8a00\u7684\u4e00\u4e2a\u6301\u7eed\u8fc7\u7a0b\u7684\u4e00\u90e8\u5206\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IH1FGDpClrsnlfjg7OF3lg"},"\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(6)")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/JCU3dwkwpMP3qMKqg9ed6g"},"\u4f7f\u7528Apache Kafka\u7684Golang\u5b9e\u8df5\u6307\u5357")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/RFsHfFByarSRAA-f1Rs13g"},"\u300aGo \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570\u300b"),'\u3002\u8fd9\u7bc7\u7531\u714e\u9c7c\u64b0\u5199\u7684\u6587\u7ae0\uff0c\u9898\u4e3a "Go \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570?"\uff0c\u5bf9\u4e8e\u8fd9\u4e2a\u8bdd\u9898\u8fdb\u884c\u4e86\u6df1\u5ea6\u89e3\u6790\u3002\u5176\u9996\u5148\u63d0\u5230\uff0c\u867d\u7136Go\u7684\u89c4\u8303\u5e76\u6ca1\u6709\u660e\u786e\u7981\u6b62\u4ecemain\u5305\u4e2d\u5bfc\u5165\u51fd\u6570\uff0c\u4f46\u6211\u4eec\u5728\u5b9e\u9645\u8fd0\u884c\u4e2d\u4f1a\u88ab\u62d2\u7edd\uff0c\u63d0\u793amain\u5305\u662f\u4e00\u4e2a\u7a0b\u5e8f\u800c\u975e\u53ef\u4ee5\u5bfc\u5165\u7684\u5305\u3002\u8fd9\u4e00\u73b0\u8c61\u7684\u539f\u56e0\u6765\u81ea\u4e8e\u7ecf\u8fc7\u591a\u6b21\u53d8\u52a8\u7684\u89c4\u5b9a\uff0c\u59822011\u5e74\u79fb\u9664\u4e86 "\u7a0b\u5e8f\u4e2d\u7684\u5176\u4ed6\u5305\u90fd\u4e0d\u80fd\u547d\u540d\u4e3a main" \u7684\u8981\u6c42\uff0c\u7136\u540e\u57282015\u5e74\u53c8\u65b0\u589e\u4e86\u9650\u5236\u3002\u8fd9\u6837\u7684\u53d8\u5316\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u589e\u52a0\u590d\u6742\u5ea6\u548c\u4e0d\u5b89\u5168\u6027\u3002\u6bd4\u5982\uff0c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u505a\u51fa\u81ea\u5df1\u62e5\u6709\u5b8c\u5168\u63a7\u5236\u6743\u7684\u5047\u8bbe\uff0c\u6240\u4ee5\u5982\u679c\u5f15\u5165\u591a\u4e2amain\u5305\u4e2d\u7684\u51fd\u6570\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u5728\u521d\u59cb\u5316\u987a\u5e8f\u3001\u5168\u5c40\u53d8\u91cf\u7684\u6ce8\u518c\u7b49\u65b9\u9762\u7684\u51b2\u7a81\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba4\u4e3aGo\u5b98\u65b9\u7684\u505a\u6cd5\u5728\u7406\u8bba\u4e0a\u53ef\u4ee5\u89e3\u51b3\u590d\u6742\u5ea6\u548c\u5b89\u5168\u6027\u95ee\u9898\uff0c\u4f46\u5bf9\u4e8e\u6709\u5386\u53f2\u503a\u52a1\u7684\u9879\u76ee\uff0c\u5bf9\u4e8e\u9700\u8981\u7ef4\u62a4\u591a\u4e2aGo\u9879\u76ee\u5de5\u7a0b\uff0c\u76f8\u5f53\u4e8e\u78e8\u706d\u4e86\u4e00\u6761\u9053\u8def\uff0c\u5176\u5b9e\u6bd4\u8f83\u5c34\u5c2c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/zxLO4IhLqQmIaUDzwwjU1w"},"\u300afasthttp\u662f\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8bb2\u89e3\u4e86fasthttp\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u539f\u7406\u3002fasthttp\u76f8\u6bd4\u4e8enet/http\u5728\u5904\u7406\u6d41\u7a0b\u4e0a\u6709\u6240\u5dee\u5f02\uff0cnet/http\u662f\u4e00\u4e2a\u8fde\u63a5\u65b0\u5efa\u4e00\u4e2agoroutine\uff0c\u5f53\u8fde\u63a5\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\u4f1a\u7ed9\u7cfb\u7edf\u5e26\u6765\u4e00\u5b9a\u7684\u538b\u529b\u3002\u800cfasthttp\u5219\u662f\u5efa\u7acb\u4e86workerPool\uff0c\u6bcf\u4e2aworkerChan\u5728\u540e\u53f0\u90fd\u4f1a\u6709\u4e00\u4e2aGoroutine\u6765\u5904\u7406\u5176\u4e2d\u7684\u8fde\u63a5\u3002\u6b64\u5916\uff0cfasthttp\u7684\u5feb\u901f\u4e5f\u5f97\u76ca\u4e8e\u51e0\u4e2a\u65b9\u9762\u7684\u4f18\u5316\uff1a\u8fde\u63a5\u590d\u7528\uff0c\u5927\u91cf\u4f7f\u7528\u4e86sync.Pool\u8fdb\u884c\u5185\u5b58\u590d\u7528\u4ee5\u53ca\u901a\u8fc7unsafe.Pointer\u6307\u9488\u8fdb\u884c","[","]","byte\u548cstring\u8f6c\u6362\u6765\u907f\u514d\u5185\u5b58\u5206\u914d\u548c\u62f7\u8d1d\u7684\u6d88\u8017\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fx-FTVpM3CXIPUwTC_juDQ"},"\u300a\u4e07\u5b57\u957f\u6587\u8bb2\u89e3Golang pprof \u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86Golang\u7684pprof\u5de5\u5177\u7684\u4f7f\u7528\u3002pprof\u5de5\u5177\u662fGolang\u4e2d\u7528\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4e00\u4e2a\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u5206\u6790\u51facpu\u4f7f\u7528\u60c5\u51b5\u3001\u5185\u5b58\u5360\u7528\u3001\u963b\u585e\u60c5\u51b5\u3001\u7ebf\u7a0b\u548c\u534f\u7a0b\u7b49\u4fe1\u606f\u3002\u6587\u7ae0\u4e2d\u8be6\u7ec6\u9610\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528\u6b64\u5de5\u5177\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u901a\u8fc7http\u63a5\u53e3\u7684\u65b9\u5f0f\u66b4\u9732\u51fapprof\u7684\u91c7\u96c6\u63a7\u5236\u754c\u9762\uff0c\u53e6\u4e00\u79cd\u662f\u5728\u7a0b\u5e8f\u4e2d\u901a\u8fc7\u4ee3\u7801\u6765\u542f\u52a8\u76f8\u5e94\u6307\u6807\u7684\u91c7\u96c6\u793a\u4f8b\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u89e3\u6790\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u5f0f\u83b7\u53d6\u7684\u8f93\u51fa\u4fe1\u606f\u3002\u672c\u6587\u7684\u4e3b\u8981\u76ee\u7684\u662f\u5c06pprof\u5de5\u5177\u7684\u4f7f\u7528\u65b9\u5f0f\u7528\u601d\u7ef4\u5bfc\u56fe\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765\uff0c\u8fd9\u6837\u53ef\u4ee5\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u4f7f\u7528pprof\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/xYvMI0JieO6RxHIdWf1ujQ"},"\u300a\u4e00\u7bc7\u5b9e\u7528\u7684\u5173\u4e8e\u4e91\u4e0aK8s\u5e94\u7528\u5206\u8d26\u5b9e\u8df5\u300b"),"\u3002\u672c\u6587\u8bb2\u8ff0\u4e91\u4e0aKubernetes\uff08K8s\uff09\u5e94\u7528\u7684\u6210\u672c\u5206\u644a\u5b9e\u8df5\uff0c\u6db5\u76d6\u4e86\u6210\u672c\u5206\u644a\u7684\u6838\u5fc3\u6982\u5ff5\u53ca\u963f\u91cc\u4e91ACK FinOps\u5957\u4ef6\u7684\u5e94\u7528\u3002\u6587\u4e2d\u9996\u5148\u4ee5\u524d\u671f\u9884\u7b97\u4e3a\u96c6\u7fa4\u89c4\u5212\u7684\u4f9d\u636e\uff0c\u5e76\u8ba8\u8bba\u4e86\u968f\u7740\u4e1a\u52a1\u53d1\u5c55\u5bf9\u6210\u672c\u5206\u644a\u7cbe\u51c6\u5ea6\u7684\u63d0\u5347\u9700\u6c42\u3002\u4ecb\u7ecd\u4e86\u5982\u4f55\u6839\u636ePod\u7684\u6838/\u65f6\u6210\u672c\uff0c\u901a\u8fc7ACK\u96c6\u7fa4\u3001\u8ba1\u7b97\u8282\u70b9\u3001\u547d\u540d\u7a7a\u95f4\u548c\u5e94\u7528Pod\u8fd9\u56db\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u8d39\u7528\u5206\u644a\u3002\u6587\u7ae0\u8fd8\u5206\u6790\u4e86\u5355\u8d44\u6e90\u548c\u6df7\u5408\u8d44\u6e90\u5206\u644a\u6a21\u578b\uff0c\u5e76\u8ba8\u8bba\u4e86\u5982\u4f55\u8bbe\u7f6eRequest\u548cLimit\u6765\u4f18\u5316\u8d44\u6e90\u5229\u7528\u3002\u5bf9\u4e8e\u591a\u4e91\u548c\u6df7\u5408\u4e91\u573a\u666f\uff0c\u5206\u4eab\u4e86\u5982\u4f55\u901a\u8fc7ACK One\u5b9e\u73b0\u7edf\u4e00\u7ba1\u7406\u548c\u6210\u672c\u5206\u6790\u3002\u9488\u5bf9\u590d\u6742\u4e1a\u52a1\u573a\u666f\uff0c\u8bb2\u8ff0\u4e86\u81ea\u5b9a\u4e49\u5b9a\u4ef7\u6a21\u7248\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u5141\u8bb8\u901a\u8fc7\u914d\u7f6e\u5b9e\u73b0\u6210\u672c\u5b9a\u5236\u9700\u6c42\u3002\u5bf9\u4e8e\u8ffd\u6c42\u7ec6\u8282\u7ba1\u7406\u548c\u7cbe\u7ec6\u5316\u8fd0\u8425\u7684\u56e2\u961f\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u6307\u5bfc\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/6xx3-qow8A5Hdp_72jswow"},'\u300a\u5982\u4f55\u4f7f\u7528 K8s \u4e24\u5927\u5229\u5668"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u5e2e\u4f60\u6446\u8131\u8fd0\u7ef4\u56f0\u5883\u300b'),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528 Kubernetes\uff08K8s\uff09\u7684"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u529f\u80fd\u6765\u5e2e\u52a9\u8fdb\u884c\u65e5\u5e38\u96c6\u7fa4\u8fd0\u7ef4\u5de5\u4f5c\u3002\u6587\u7ae0\u9996\u5148\u6307\u51fa\u4e86\u8fd0\u7ef4\u5de5\u4f5c\u4e2d\u53ef\u80fd\u51fa\u73b0\u7684\u4e00\u4e9b\u95ee\u9898\uff0c\u4f8b\u5982\u5e94\u7528\u88ab\u5220\u9664\u3001Apiserver\u8d1f\u8f7d\u7a81\u53d8\u3001\u96c6\u7fa4\u8282\u70b9\u51fa\u73b0\u95ee\u9898\u3001\u8282\u70b9\u81ea\u52a8\u6269\u5bb9\u7b49\u3002\u968f\u540e\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u89e3\u91ca\u4e86 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\u662f\u5982\u4f55\u8fd0\u4f5c\u7684\uff0c\u5f3a\u8c03\u4e86\u5584\u7528\u8fd9\u4e24\u79cd\u5de5\u5177\u53ef\u4ee5\u63d0\u9ad8\u96c6\u7fa4\u7684\u53ef\u89c2\u5bdf\u6027\uff0c\u4e3a\u8fd0\u7ef4\u5de5\u4f5c\u5e26\u6765\u6781\u5927\u7684\u4fbf\u5229\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u901a\u8fc7\u4f7f\u7528 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u66f4\u597d\u5730\u7ba1\u7406\u548c\u76d1\u6d4b\u96c6\u7fa4\u7684\u72b6\u6001\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lxEAFe2Ewmc8YvTqn8UcLQ"},"\u3010Go \u5de5\u5177\u3011\u7ade\u6001\u6761\u4ef6\u68c0\u6d4b\u795e\u5668 Race Detector")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Y67J4_D1yyMa-eb7XmgTcA"},"\u4f7f\u7528Redis\u5165\u95e8Golang")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/qDFM-nVo-jeh9VdcBfMreA"},"\u4e00\u9053\u9762\u8bd5\u9898: Top K \u95ee\u9898")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/sTd3SVh0swGTnaGugsw1SA"},"\u300a\u7406\u89e3 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u89e3\u6790\u4e86 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u3002\u9996\u5148\uff0c\u4f5c\u8005\u6982\u8ff0\u4e86\u7528\u6237\u540d\u3001\u7ec4\u540d\u3001\u7528\u6237ID\uff08UID\uff09\u548c\u7ec4ID\uff08GID\uff09\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e0e\u4e3b\u673a\u7cfb\u7edf\u4e4b\u95f4\u7684\u6620\u5c04\u5bf9\u4e8e\u6784\u5efa\u5b89\u5168\u7cfb\u7edf\u7684\u91cd\u8981\u6027\u3002\u968f\u540e\uff0c\u6587\u7ae0\u5206\u6790\u4e86uid/gid\u5728Linux\u7cfb\u7edf\u7684\u5b89\u5168\u6027\uff0c\u5f3a\u8c03\u4e86\u5355\u4e00\u5185\u6838\u6982\u5ff5\u4ee5\u53cauid/gid\u7684\u5206\u914d\u65b9\u5f0f\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u8fd0\u7528\u5b9e\u4f8b\u89e3\u91ca\u4e86Docker\u8fd0\u884c\u7684\u8fc7\u7a0b\u4ee5\u53ca\u5982\u4f55\u901a\u8fc7Dockerfile\u5b9a\u4e49\u548c\u542f\u52a8\u4e0d\u540c\u7528\u6237\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8bb2\u8ff0\u4e86\u5982\u4f55\u638c\u63a7\u548c\u63a7\u5236\u5bb9\u5668\u7684\u8bbf\u95ee\u6743\u9650\u3002\u5728\u9610\u8ff0\u4ee5\u4e0a\u5185\u5bb9\u7684\u540c\u65f6\uff0c\u6587\u7ae0\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u9645\u793a\u4f8b\u6765\u8bf4\u660e\u8fd9\u4e9b\u89c2\u70b9\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yUuo1IjeXY78_5u4QpkuTA"},"\u300a\u5982\u4f55\u57fa\u4e8eDocker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u5c06Docker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u3002\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5229\u7528\u5f00\u6e90\u5de5\u5177Dedockify\u7684\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u5de5\u4f5c\u539f\u7406\u3002\u8be5\u5de5\u5177\u901a\u8fc7Python\u811a\u672c\uff0c\u5229\u7528\u5b58\u50a8\u5728\u6bcf\u4e2a\u955c\u50cf\u5c42\u65c1\u8fb9\u7684\u5143\u6570\u636e\uff0c\u9010\u6b65\u904d\u5386\u5c42\u7ea7\u6811\uff0c\u6536\u96c6\u4e0e\u6bcf\u4e2a\u5c42\u76f8\u5173\u8054\u7684\u547d\u4ee4\uff0c\u91cd\u5efa\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\u547d\u4ee4\u5e8f\u5217\uff0c\u4ece\u800c\u5f97\u5230\u8fd1\u4f3c\u7684Dockerfile\u3002\u4e0d\u8fc7\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bbf\u95ee\u6267\u884c\u539f\u59cbdocker build\u547d\u4ee4\u65f6\u5b58\u5728\u7684\u6784\u5efa\u4e0a\u4e0b\u6587\uff0c\u5982\u679c\u4f7f\u7528\u4e86COPY\u6216ADD\u6307\u4ee4\uff0c\u751f\u6210\u7684\u8f93\u51fa\u53ef\u80fd\u4e0d\u5b8c\u5168\u5339\u914d\u539f\u59cb\u7684Dockerfile\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KkRWQyljuo86-XbBxEnGPA"},"\u300a\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u3002\u9996\u5148\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a\u901a\u7528\u7684Dockerfile\uff0c\u5e76\u6307\u51fa\u5176\u751f\u6210\u7684\u955c\u50cf\u5927\u5c0f\u8d85\u8fc7300MB\uff0c\u4e3b\u8981\u56e0\u4e3a\u5305\u542b\u4e86\u6240\u6709\u7684Golang\u5de5\u5177\u3002\u7136\u540e\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u591a\u9636\u6bb5\u6784\u5efa\u7684\u65b9\u6cd5\uff0c\u5b83\u80fd\u4ece\u4e0d\u540c\u7684\u57fa\u7840\u955c\u50cf\u6784\u5efa\uff0c\u6709\u9009\u62e9\u5730\u5c06\u6587\u4ef6\u4ece\u4e00\u4e2a\u9636\u6bb5\u4f20\u9012\u5230\u4e0b\u4e00\u4e2a\u9636\u6bb5\uff0c\u4ece\u800c\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u901a\u8fc7\u4e8c\u7ea7\u6784\u5efa\uff0c\u955c\u50cf\u5927\u5c0f\u5df2\u964d\u81f311.7MB\u3002\u6700\u540e\uff0c\u8fd8\u63a2\u8ba8\u4e86\u4f7f\u7528\u540d\u4e3ascratch\u7684\u7a7a\u767d\u955c\u50cf\u8fdb\u4e00\u6b65\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u7684\u53ef\u80fd\u6027\uff0c\u4f7f\u5f97\u955c\u50cf\u6700\u540e\u964d\u81f36.34MB\uff0c\u4f46\u4f5c\u8005\u5f3a\u8c03\u8fd9\u9700\u8981\u614e\u91cd\u8003\u8651\uff0c\u56e0\u4e3a\u6700\u540e\u751f\u6210\u7684\u955c\u50cf\u5c06\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dckA1ezcABndN5WSg1BOBA"},"\u300ak8s \u5230\u5e95\u662f\u4ec0\u4e48\uff0c\u67b6\u6784\u662f\u600e\u4e48\u6837\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86 Kubernetes\uff08K8s\uff09\u7684\u57fa\u672c\u6982\u5ff5\u3001\u67b6\u6784\u548c\u5de5\u4f5c\u539f\u7406\u3002Kubernetes\uff0c\u56e0\u5355\u8bcd\u8fc7\u957f\uff0c\u6211\u4eec\u901a\u5e38\u7b80\u5316\u4e3ak8s\u3002k8s \u662f\u4e00\u79cd\u5bb9\u5668\u7684\u534f\u8c03\u5de5\u5177\uff0c\u4f4d\u4e8e\u5e94\u7528\u670d\u52a1\u548c\u670d\u52a1\u5668\u4e4b\u95f4\uff0c\u80fd\u4ee5\u7b56\u7565\u7684\u65b9\u5f0f\u534f\u8c03\u548c\u7ba1\u7406\u591a\u4e2a\u5e94\u7528\u670d\u52a1\u3002\u901a\u8fc7\u4e00\u4e2a yaml \u6587\u4ef6\u7684\u914d\u7f6e\uff0c\u53ef\u4ee5\u5b9a\u4e49\u5e94\u7528\u7684\u90e8\u7f72\u987a\u5e8f\u7b49\u4fe1\u606f\uff0c\u81ea\u52a8\u90e8\u7f72\u5e94\u7528\u5230\u5404\u4e2a\u670d\u52a1\u5668\u4e0a\uff0c\u8fd8\u80fd\u8ba9\u5b83\u4eec\u5d29\u6e83\u540e\u81ea\u52a8\u91cd\u542f\uff0c\u53ef\u4ee5\u81ea\u52a8\u6269\u5bb9\u548c\u7f29\u5bb9\u3002Kubernetes \u7684\u670d\u52a1\u5668\u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u63a7\u5236\u5e73\u9762\u548c\u5de5\u4f5c\u8282\u70b9\uff0c\u524d\u8005\u8d1f\u8d23\u63a7\u5236\u548c\u7ba1\u7406\u5404\u4e2a\u8282\u70b9\uff0c\u540e\u8005\u5219\u8d1f\u8d23\u5b9e\u9645\u8fd0\u884c\u5404\u4e2a\u5e94\u7528\u670d\u52a1\u3002k8s \u7684\u547d\u4ee4\u884c\u5de5\u5177\u4e3a kubectl\uff0c\u7528\u4e8e\u6267\u884c\u5404\u7c7b\u64cd\u4f5c\u547d\u4ee4\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/vjmntyGwzURz_elg27vpXg"},"\u300aGo \u6cdb\u578b\u6709\u6ca1\u6709\u53ef\u80fd\u5728\u540e\u671f\u6539\u4e3a ",(0,a.kt)("inlineCode",{parentName:"a"},"<>")," \u5c16\u62ec\u53f7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728\u5904\u7406\u6cdb\u578b\u65f6\uff0c\u4e3a\u4f55\u5e76\u6ca1\u6709\u91c7\u7528\u7c7b\u4f3cJava\u548cC++\u7684 ",(0,a.kt)("inlineCode",{parentName:"p"},"<>")," \u5c16\u62ec\u53f7\u8868\u793a\u6cd5\uff0c\u800c\u662f\u9009\u62e9\u4e86\u4e2d\u62ec\u53f7 ",(0,a.kt)("inlineCode",{parentName:"p"},"[]"),". \u9996\u5148\uff0c\u4f7f\u7528\u5c16\u62ec\u53f7\u53ef\u80fd\u5bfc\u81f4\u8bed\u4e49\u6df7\u6dc6\uff0c\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"a, b := w < x, y > (z)")," \u6b64\u53e5\uff0c\u5982\u679c\u4f7f\u7528\u5c16\u62ec\u53f7\uff0c\u7a0b\u5e8f\u53ef\u80fd\u5728\u7f16\u8bd1\u9636\u6bb5\u65e0\u6cd5\u786e\u5b9a\u8be5\u884c\u8868\u8fbe\u5f0f\u7684\u5177\u4f53\u542b\u4e49\u3002\u5176\u6b21\uff0c\u4f7f\u7528\u5706\u62ec\u53f7\u4e5f\u4f1a\u5bfc\u81f4\u540c\u6837\u7684\u95ee\u9898\uff0c\u6bd4\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"func F(T any)(v T)(r1, r2 T)"),", \u65e0\u6cd5\u5feb\u901f\u51c6\u786e\u5224\u65ad\u51fa\u53c2\u6570\u548c\u8fd4\u56de\u503c\u90e8\u5206\u3002\u6b64\u5916\uff0cGo\u5b98\u65b9\u4e5f\u4e0d\u5e0c\u671b\u4f7f\u7528\u975eASCII\u7684\u5b57\u7b26\u3002\u4f5c\u8005\u8fd8\u63d0\u5230\u793e\u533a\u4e2d\u5bf9Go\u7684\u5904\u7406\u65b9\u5f0f\u5b58\u5728\u4e00\u4e9b\u4e89\u8bae\uff0c\u90e8\u5206\u793e\u533a\u6210\u5458\u8ba4\u4e3a\u5982\u679c\u4f7f\u5f97\u7f16\u8bd1\u5668\u89e3\u91ca\u5c16\u62ec\u53f7\u4e0d\u518d\u56f0\u96be\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u8fd9\u79cd\u7b26\u53f7\u3002\u7136\u800c\uff0c\u603b\u7684\u6765\u8bf4\uff0c\u57fa\u4e8e\u5df2\u6709\u7684\u5b9e\u8df5\u548c\u89c4\u8303\uff0cGo\u8bed\u8a00\u5728\u672a\u6765\u53ef\u80fd\u4e5f\u4e0d\u4f1a\u6539\u53d8\u5176\u6cdb\u578b\u7684\u8868\u793a\u65b9\u5f0f\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/arI9sip-5JH9YSu45XJ83w"},"\u300aRust\u4e2dchannel\u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86Rust\u7f16\u7a0b\u8bed\u8a00\u4e2dChannel\u7684\u7528\u6cd5\u3002\u5176\u4e2d\uff0cChannel\u662fRust\u4e2d\u7528\u4e8e\u5728\u4e0d\u540c\u7ebf\u7a0b\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u901a\u4fe1\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u7ebf\u7a0b\u95f4\u7684\u6d88\u606f\u4f20\u9012\u3002\u6bcf\u4e2aChannel\u7531\u53d1\u9001\u7aef\u548c\u63a5\u6536\u7aef\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5176\u8bbe\u8ba1\u7406\u5ff5\u662f\u201c\u901a\u8fc7\u901a\u4fe1\u6765\u5171\u4eab\u5185\u5b58\uff0c\u800c\u975e\u901a\u8fc7\u5171\u4eab\u5185\u5b58\u6765\u901a\u4fe1\u201d\uff0c\u4ee5\u6b64\u907f\u514d\u4e86\u6570\u636e\u7ade\u4e89\u548c\u5171\u4eab\u5185\u5b58\u7684\u590d\u6742\u6027\u3002\u8be5\u6587\u7ae0\u8fdb\u4e00\u6b65\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5728Rust\u4e2d\u521b\u5efa\u548c\u4f7f\u7528Channel\uff0c\u5e76\u7ed9\u51fa\u4e86\u76f8\u5173\u4ee3\u7801\u793a\u4f8b\u3002\u6700\u540e\uff0c\u6587\u7ae0\u9610\u8ff0\u4e86\u591a\u79cdChannel\u6a21\u578b\uff0c\u5305\u62ecRust\u6807\u51c6\u5e93\u4e2d\u6240\u4f7f\u7528\u7684MPSC\uff08\u591a\u751f\u4ea7\u8005\uff0c\u5355\u6d88\u8d39\u8005\uff09\u6a21\u578b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7272006755266002959"},"K8s\u90e8\u7f72\u65b9\u5f0f\u5927\u5168\uff1a\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1\u6240\u6709\u6280\u5de7")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7301584578342289423"},"k8s\u4ece\u5165\u95e8\u5230\u7cbe\u901a -- \u66f4\u9002\u5408\u4e2d\u56fd\u5b9d\u5b9d\u4f53\u8d28")),(0,a.kt)("h2",{id:"-\u540e\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NABg5tGizHsmdXgUO6NeVw"},"\u300a\u4e07\u5b57+33\u5f20\u56fe\u63a2\u79d8OpenFeign\u6838\u5fc3\u67b6\u6784\u539f\u7406\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u6df1\u5165\u63a2\u8ba8\u4e86SpringCloud\u6838\u5fc3\u7ec4\u4ef6OpenFeign\u7684\u6838\u5fc3\u67b6\u6784\u539f\u7406\u3002\u6587\u7ae0\u5206\u4e3a\u56db\u4e2a\u90e8\u5206\uff0c\u9996\u5148\u89e3\u91ca\u539f\u59cbFeign\u7684\u4f7f\u7528\u548c\u57fa\u4e8eSpringCloud\u7684\u8fdb\u5316\u8fc7\u5386\u7a0b\uff1b\u7136\u540e\u8be6\u7ec6\u8bb2\u89e3\u4e86Feign\u5e95\u5c42\u5de5\u4f5c\u539f\u7406\uff0c\u4f9d\u8d56\u4e8eJDK\u52a8\u6001\u4ee3\u7406\u548c\u6838\u5fc3\u7ec4\u4ef6\u5982Contract\u3001Encoder\u3001Decoder\u7b49\uff1b\u63a5\u4e0b\u6765\u5206\u6790\u4e86SpringCloud\u662f\u5982\u4f55\u6574\u5408Feign\u7684\uff0c\u5e76\u4e14\u8ba8\u8bba\u4e86OpenFeign\u7684\u591a\u79cd\u914d\u7f6e\u65b9\u5f0f\u53ca\u5176\u4f18\u5148\u7ea7\uff1b\u6700\u540e\uff0c\u6587\u7ae0\u901a\u8fc7\u4e30\u5bcc\u7684\u56fe\u793a\u548c\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u53ef\u4ee5\u66f4\u597d\u5730\u7406\u89e3\u5e76\u8fd0\u7528\u8fd9\u4e00\u5de5\u5177\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4e8e\u7406\u89e3\u548c\u8fd0\u7528OpenFeign\u975e\u5e38\u6709\u5e2e\u52a9\uff0c\u65e0\u8bba\u662f\u5bf9\u4e8e\u521d\u5b66\u8005\u8fd8\u662f\u6709\u7ecf\u9a8c\u7684\u5f00\u53d1\u8005\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1Qe29y3nrbi39Kpaspme7Q"},"\u300a\u4e09\u4e07\u5b57\u957f\u6587\uff1a\u5982\u4f55\u53bb\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4efd\u8be6\u5c3d\u7684\u6307\u5bfc\uff0c\u8bb2\u8ff0\u4e86\u5982\u4f55\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u3002\u6587\u4e2d\u9996\u5148\u5b9a\u4f4d\u4e86\u6280\u672f\u95ee\u9898\u7684\u8303\u56f4\uff0c\u786e\u5b9a\u9002\u7528\u4e8eJDK8\u81f3JDK11\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u7cfb\u7edf\u5316\u7684\u6392\u67e5\u539f\u5219\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u6b65\u6b65\u7684\u8bca\u65ad\u6d41\u7a0b\uff0c\u4ece\u57fa\u672c\u4fe1\u606f\u6536\u96c6\u3001\u5224\u65ad\u5185\u5b58\u589e\u957f\u539f\u56e0\uff0c\u5230\u5177\u4f53\u5206\u6790\u5185\u5b58\u95ee\u9898\u7684\u53ef\u80fd\u6765\u6e90\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u4e0d\u540c\u7684\u547d\u4ee4\u548c\u5de5\u5177\uff08\u5982jmap\u3001jstat\u3001Arthas\u7b49\uff09\u8fdb\u884c\u8be6\u7ec6\u7684\u5206\u6790\uff0c\u5e76\u6839\u636e\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff0c\u5411\u8bfb\u8005\u5c55\u793a\u4e86\u5982\u4f55\u786e\u5b9a\u662f\u5806\u5185\u5b58\u95ee\u9898\u8fd8\u662f\u5806\u5916\u5185\u5b58\u95ee\u9898\u3002\u603b\u4e4b\uff0c\u6587\u7ae0\u4e3a\u90a3\u4e9b\u9700\u8981\u6df1\u5165\u7406\u89e3\u548c\u5904\u7406JVM\u5185\u5b58\u95ee\u9898\u7684\u5f00\u53d1\u8005\u548c\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u77e5\u8bc6\u548c\u6280\u5de7\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WLPo8s_M3AzxwB3o3ehY3w"},"\u300a\u5982\u4f55\u907f\u514dMYSQL\u4e3b\u4ece\u5ef6\u8fdf\u5e26\u6765\u7684\u8bfb\u5199\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u5904\u7406\u5728MySQL\u4e3b\u4ece\u90e8\u7f72\u67b6\u6784\u4e2d\u666e\u904d\u5b58\u5728\u7684\u4e3b\u4ece\u540c\u6b65\u5ef6\u8fdf\u95ee\u9898\uff0c\u4ee5\u4fdd\u6301\u8bfb\u5199\u64cd\u4f5c\u7684\u4e00\u81f4\u6027\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u4e3b\u4ece\u5ef6\u8fdf\u4ea7\u751f\u7684\u573a\u666f\u53ca\u5176\u5bf9\u8bfb\u5199\u5206\u79bb\u539f\u5219\u7684\u5f71\u54cd\u3002\u7136\u540e\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e86\u4e3b\u4ece\u590d\u5236\u7684\u539f\u7406\uff0c\u5e76\u63d0\u51fa\u4e86\u4e24\u79cd\u907f\u514d\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u6280\u672f\u65b9\u6848\uff1a\u4e00\u662f\u4f7f\u7528select master_pos_wait\u51fd\u6570\u6765\u7b49\u5f85\u4ece\u5e93\u540c\u6b65\u81f3\u7279\u5b9a\u7684binlog\u4f4d\u7f6e\u70b9\uff1b\u4e8c\u662f\u5728\u5f00\u542fGTID\u6a21\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7select wait_for_executed_gtid_set\u51fd\u6570\u68c0\u67e5GTID\u96c6\u5408\u662f\u5426\u5df2\u540c\u6b65\u3002\u8fd9\u4e24\u79cd\u65b9\u6cd5\u5747\u65e8\u5728\u786e\u4fdd\u4ece\u5e93\u6570\u636e\u7684\u51c6\u786e\u6027\uff0c\u4ece\u800c\u6574\u4f53\u4e0a\u51cf\u8f7b\u4e3b\u5e93\u7684\u538b\u529b\u3002\u603b\u4f53\u4e0a\uff0c\u6587\u7ae0\u4e3aMySQL\u6570\u636e\u5e93\u7ba1\u7406\u5458\u63d0\u4f9b\u4e86\u7f13\u89e3\u4e3b\u4ece\u5ef6\u8fdf\u5bfc\u81f4\u7684\u8bfb\u5199\u95ee\u9898\u7684\u5177\u4f53\u5b9e\u65bd\u65b9\u6848\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dt_14etV_2ynAmyMa_uyug"},"\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014ES\u7bc7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u7bc7\u9488\u5bf9Elasticsearch(ES)\u7684\u9762\u8bd5\u6307\u5357\uff0c\u5b83\u6db5\u76d6ES\u57fa\u7840\u77e5\u8bc6\u70b9\u548c\u9762\u8bd5\u8fc7\u7a0b\u4e2d\u5e38\u89c1\u95ee\u9898\u3002\u5185\u5bb9\u5305\u62ecES\u7684\u529f\u80fd\u7279\u6027\u4ecb\u7ecd\uff08\u5982\u5206\u5e03\u5f0f\u67b6\u6784\u3001\u5168\u6587\u641c\u7d22\u3001\u6570\u636e\u5206\u6790\u7b49\uff09\u3001\u4e3b\u8981\u7684\u4f7f\u7528\u573a\u666f\u63cf\u8ff0\u3001\u4e0e\u5176\u4ed6\u641c\u7d22\u5f15\u64ce\u7684\u5bf9\u6bd4\uff08Lucene\u548cSolr\uff09\u3001\u4ee5\u53caES\u7684\u57fa\u672c\u6982\u5ff5\u89e3\u91ca\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u63a2\u8ba8\u4e86ES\u7684\u9ad8\u7ea7\u7279\u6027\uff0c\u5982\u6620\u5c04\u3001DSL\u67e5\u8be2\u3001\u805a\u5408\u5206\u6790\u548c\u667a\u80fd\u641c\u7d22\u5efa\u8bae\u5668\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u8fd8\u5206\u4eab\u4e86\u5173\u4e8e\u6570\u636e\u7d22\u5f15\u4f18\u5316\u7684\u5b9e\u6218\u6280\u5de7\u548c\u7b56\u7565\uff0c\u63d0\u4f9b\u4e86\u5199\u4f18\u5316\u3001\u8bfb\u4f18\u5316\u548c\u7d22\u5f15\u91cd\u5efa\u7684\u65b9\u6848\uff0c\u8fd9\u4e9b\u65b9\u6848\u5bf9ES\u6570\u636e\u5b58\u50a8\u548c\u67e5\u8be2\u7684\u6027\u80fd\u6709\u663e\u8457\u5f71\u54cd\uff0c\u6700\u540e\u8fd8\u5bf9Deep Paging\u6027\u80fd\u95ee\u9898\u63d0\u4f9b\u4e86\u89e3\u51b3\u65b9\u6cd5\u3002\u5bf9\u6b63\u5728\u51c6\u5907\u9762\u8bd5\u6216\u8005\u5e0c\u671b\u5de9\u56faES\u77e5\u8bc6\u7684\u8bfb\u8005\u800c\u8a00\uff0c\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4e2a\u5b9d\u8d35\u7684\u8d44\u6e90\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/gAJFm3q5510PfRBe4F11PQ"},"\u300a\u4ec0\u4e48\u662fMySQL\u9501\uff1f\u6709\u54ea\u4e9b\u9501\u7c7b\u578b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5730\u4ecb\u7ecd\u4e86MySQL\u4e2d\u7684\u9501\u5b9a\u673a\u5236\u53ca\u5176\u7c7b\u578b\u3002\u8d77\u521d\u6982\u8ff0\u4e86\u9501\u7684\u4f5c\u7528\uff0c\u5373\u534f\u8c03\u591a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u8d44\u6e90\u7684\u5e76\u53d1\u8bbf\u95ee\uff0c\u5728\u6570\u636e\u5e93\u73af\u5883\u4e0b\uff0c\u9501\u5bf9\u4e8e\u4fdd\u6301\u4e8b\u52a1\u7684\u6b63\u786e\u6027\u4e0e\u4e00\u81f4\u6027\u81f3\u5173\u91cd\u8981\u3002\u4f5c\u8005\u660e\u786e\u533a\u5206\u4e86MySQL\u4e2d\u9501\u7684\u7ea7\u522b\uff0c\u4ece\u5168\u5c40\u9501\u3001\u8868\u9501\uff08\u8bfb\u9501\u3001\u5199\u9501\uff09\u5230\u5143\u6570\u636e\u9501\u3001\u610f\u5411\u9501\uff0c\u76f4\u5230\u884c\u9501\u7684\u591a\u79cd\u5f62\u5f0f\uff08\u8bb0\u5f55\u9501\u3001\u95f4\u9699\u9501\u548c\u4e34\u952e\u9501\uff09\u3002\u6587\u4e2d\u8fd8\u63a2\u8ba8\u4e86AUTO-INC\u9501\u7684\u4f5c\u7528\u548c\u76f8\u5173\u4f18\u5316\uff0c\u4e3e\u4f8b\u8bf4\u660e\u4e86\u5176\u5728INSERT\u64cd\u4f5c\u4e2d\u7684\u5e94\u7528\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u4e5f\u6d89\u53ca\u4e86\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u60c5\u51b5\u4f18\u5316\u9501\u7684\u4f7f\u7528\u4ee5\u53ca\u5982\u4f55\u907f\u514d\u7531\u9501\u4ea7\u751f\u7684\u6027\u80fd\u74f6\u9888\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u7406\u89e3MySQL\u7684\u5404\u79cd\u9501\u7c7b\u578b\u548c\u9501\u673a\u5236\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u4fe1\u606f\uff0c\u7279\u522b\u5bf9\u4e8e\u6570\u636e\u5e93\u7ba1\u7406\u5458\u548c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5e76\u53d1\u6570\u636e\u8bbf\u95ee\u95ee\u9898\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u5b9e\u7528\u4ef7\u503c\u3002"),(0,a.kt)("h2",{id:"-\u524d\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/m-Ae6dbFuW22u2xSDWcciw"},"Vue \u56e2\u961f\u6b63\u5f0f\u5f00\u6e90 Rolldown\uff1a\u57fa\u4e8e Rust \u7684\u8d85\u5feb JavaScrip \u6253\u5305\u5de5\u5177\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/MVR5rV2LkH8_GHCtP6SHug"},"\u6253\u9020\u8212\u9002\u7684vscode\u5f00\u53d1\u73af\u5883")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/pY4-RqqamTmPXnRPfw0hRA"},"\u76f8\u6bd4\u4e8e Node.js\uff0cDeno \u548c Bun \u5230\u5e95\u80fd\u5e26\u6765\u4ec0\u4e48")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yBTK4Rds28aJ88mVgkoYJA"},"MDH Weekly 122 - \u300a\u62db\u4eba\u300b")))}u.isMDXComponent=!0},7662:(e,t,n)=>{n.d(t,{Z:()=>p});const p=n.p+"assets/images/maxresdefault-5b23cca3601cf7ebe54f3cb5023d859a.jpg"}}]); \ No newline at end of file diff --git a/assets/js/59c08185.959fce08.js b/assets/js/59c08185.959fce08.js new file mode 100644 index 0000000000..c2e458b9e0 --- /dev/null +++ b/assets/js/59c08185.959fce08.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[9699],{49613:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var p=n(59496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);t&&(p=p.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,p)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(p=0;p=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=p.createContext({}),s=function(e){var t=p.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return p.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return p.createElement(p.Fragment,{},t)}},h=p.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=s(n),h=a,k=c["".concat(l,".").concat(h)]||c[h]||u[h]||r;return n?p.createElement(k,i(i({ref:t},m),{},{components:n})):p.createElement(k,i({ref:t},m))}));function k(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>s});var p=n(64778),a=(n(59496),n(49613));const r={slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},i=void 0,o={permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-10/index.md",source:"@site/blogs/2024/2024-03-10/index.md",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",description:"alt text",date:"2024-03-10T00:00:00.000Z",formattedDate:"March 10, 2024",tags:[],readingTime:34.7,hasTruncateMarker:!1,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},prevItem:{title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"},nextItem:{title:"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"}},l={authorsImageUrls:[void 0]},s=[{value:"\ud83c\udf1f AI \u76f8\u5173",id:"-ai-\u76f8\u5173",level:2},{value:"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173",id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173",id:"-\u540e\u7aef\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173",id:"-\u524d\u7aef\u76f8\u5173",level:2}],m={toc:s},c="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(c,(0,p.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"alt text",src:n(7662).Z,width:"1280",height:"720"})),(0,a.kt)("p",null,"\u5c01\u9762\u56fe\uff1aUnderstanding the Go runtime - Jesus Espino"),(0,a.kt)("h2",{id:"-ai-\u76f8\u5173"},"\ud83c\udf1f AI \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://arxiv.org/abs/2401.11624"},"\u300aIn-context Learning with Retrieved Demonstrations for Language Models: A Survey\u300b"),'\u3002\u8fd9\u7bc7\u9898\u4e3a "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" \u7684\u6587\u7ae0\uff0c\u4e3b\u8981\u8ba8\u8bba\u4e86\u8bed\u8a00\u6a21\u578b\uff0c\u5c24\u5176\u662f\u5927\u578b\u9884\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u5982\u4f55\u901a\u8fc7\u83b7\u53d6\u7684\u6f14\u793a\u8fdb\u884c\u5c11\u91cf\u60c5\u666f\u5b66\u4e60\u3002\u8fd9\u9879\u6280\u672f\u80fd\u6709\u6548\u5730\u6539\u8fdb\u5b66\u4e60\u8fc7\u7a0b\u7684\u6548\u7387\u548c\u53ef\u6269\u5c55\u6027\uff0c\u5e76\u964d\u4f4e\u624b\u52a8\u9009\u62e9\u6837\u4f8b\u65f6\u7684\u56fa\u6709\u504f\u89c1\u3002\u6587\u7ae0\u5bf9\u6b64\u9886\u57df\u8fdb\u884c\u4e86\u5e7f\u6cdb\u7684\u7814\u7a76\u56de\u987e\uff0c\u5bf9\u68c0\u7d22\u6a21\u578b\u3001\u68c0\u7d22\u8bad\u7ec3\u8fc7\u7a0b\u548c\u63a8\u7406\u7b97\u6cd5\u7684\u4e0d\u540c\u8bbe\u8ba1\u9009\u62e9\u8fdb\u884c\u4e86\u8ba8\u8bba\u548c\u6bd4\u8f83\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NUhEy0YLTjtzY3BGVXhfrw"},"\u300a\u78be\u538bLoRA\uff01Meta & CMU | \u63d0\u51fa\u9ad8\u6548\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\uff1aGaLore\uff0c\u5185\u5b58\u53ef\u51cf\u5c1163.3%\u300b"),"\u3002Meta\u548cCMU\u5408\u4f5c\u63d0\u51fa\u4e86\u4e00\u79cd\u65b0\u7684\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\u2014\u2014Gradient Low-Rank Projection\uff08GaLore\uff09\u3002GaLore\u901a\u8fc7\u68af\u5ea6\u7684\u4f4e\u79e9\u6295\u5f71\u4ee3\u66ff\u6743\u91cd\u7684\u4f4e\u79e9\u9002\u914d\uff0c\u4e0d\u4ec5\u652f\u6301\u5168\u53c2\u6570\u5b66\u4e60\uff0c\u800c\u4e14\u663e\u8457\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\uff0c\u51cf\u5c11\u4e8663.3%\u7684\u5185\u5b58\u9700\u6c42\u3002\u4e0d\u540c\u4e8eLoRA\u7684\u4f4e\u79e9\u6743\u91cd\u66f4\u65b0\uff0cGaLore\u5229\u7528\u6743\u91cd\u68af\u5ea6\u7684\u4f4e\u79e9\u7279\u6027\uff0c\u7ed3\u5408\u9010\u5c42\u6743\u91cd\u66f4\u65b0\u548c8\u4f4d\u4f18\u5316\u5668\uff0c\u6709\u6548\u5730\u4f18\u5316\u4e86\u5185\u5b58\u6548\u7387\u3002\u6b64\u5916\uff0cGaLore\u8fd8\u5f15\u5165\u4e86\u53ef\u8c03\u6574\u7684\u8d85\u53c2\u6570\uff0c\u63d0\u9ad8\u4e86\u5176\u9002\u5e94\u6027\u3002\u7ecf\u5b9e\u9a8c\u9a8c\u8bc1\uff0cGaLore\u7684\u8868\u73b0\u4f18\u4e8eLoRA\uff0c\u5c24\u5176\u662f\u5728\u9884\u8bad\u7ec3\u6a21\u578b\u5fae\u8c03\u4e0a\u8868\u73b0\u66f4\u4f73\uff0c\u4e3a\u5927\u6a21\u578b\u8bad\u7ec3\u63d0\u4f9b\u4e86\u65b0\u7684\u89e3\u51b3\u7b56\u7565\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7316592794109198387"},"\u4f7f\u7528 GPT4V+AI Agent \u505a\u81ea\u52a8 UI \u6d4b\u8bd5\u7684\u63a2\u7d22 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZSDCNDRu-tCkOlC9jz2j4w"},"Gemini\u4feebug\u795e\u4e86\uff01\u5f55\u7f51\u9875\u89c6\u9891\u628a\u4ee3\u7801\u5e93\u7529\u7ed9\u5b83\u5c31\u884c\uff0c\u7f51\u53cb\u5750\u4e0d\u4f4f\u4e86\uff1a\u60f3\u8981\u8bbf\u95ee\u6743\u9650")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GXwftkv-UpDQSjiTMn9TFA"},"\u4e00\u952e\u5f00\u542f GPU \u95f2\u7f6e\u6a21\u5f0f\uff0c\u57fa\u4e8e\u51fd\u6570\u8ba1\u7b97\u4f4e\u6210\u672c\u90e8\u7f72 Google Gemma \u6a21\u578b\u670d\u52a1")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/YDwL3dV-Fq5zcEyrL__NGw"},"\u300aYi\u6280\u672f\u62a5\u544a\u7ec6\u8282\u5206\u4eab\u300b"),"\u3002\u8be5\u6587\u7ae0\u5206\u4eab\u4e86Yi\u6a21\u578b\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u548c\u601d\u8def\uff0c\u5f3a\u8c03\u4e86\u6a21\u578b\u8bbe\u8ba1\u56f4\u7ed5\u6a21\u578b\u89c4\u6a21\u3001\u6570\u636e\u89c4\u6a21\u548c\u6570\u636e\u8d28\u91cf\u3002Yi\u6a21\u578b\u7684\u9884\u8bad\u7ec3\u9636\u6bb5\u6570\u636e\u5904\u7406\u6d41\u7a0b\u5305\u62ec\u542f\u53d1\u5f0f\u8fc7\u6ee4\u3001\u5b66\u4e60\u5f0f\u8fc7\u6ee4\u3001\u805a\u7c7b\u8fc7\u6ee4\u4ee5\u53ca\u53bb\u91cd\u7b49\u6b65\u9aa4\uff0c\u4ee5\u63d0\u9ad8\u6570\u636e\u8d28\u91cf\u3002\u5fae\u8c03\u9636\u6bb5\uff0cYi\u6a21\u578b\u4ec5\u91c7\u7528\u4e8610K\u6570\u636e\u8fdb\u884c\u6a21\u578b\u5fae\u8c03\uff0c\u5f3a\u8c03\u6570\u636e\u8d28\u91cf\u80dc\u8fc7\u6570\u91cf\u3002\u5728\u5206\u8bcd\u5668\u3001\u6a21\u578b\u7ed3\u6784\u53ca\u5fae\u8c03\u53c2\u6570\u65b9\u9762\uff0cYi\u6a21\u578b\u91c7\u7528\u4e86\u4e00\u7cfb\u5217\u4f18\u5316\u63aa\u65bd\uff0c\u5305\u62ecTransformer-Decoder\u7ed3\u6784\u3001Grouped-Query Attention\u7b49\u3002\u603b\u7684\u6765\u8bf4\uff0cYi\u6a21\u578b\u901a\u8fc7\u4f18\u5316\u6570\u636e\u5904\u7406\u6d41\u7a0b\u3001\u5fae\u8c03\u7b56\u7565\u3001\u8c03\u6574\u6a21\u578b\u7ed3\u6784\u548c\u53c2\u6570\u7b49\u591a\u65b9\u9762\u5b9e\u73b0\u4e86\u9ad8\u6548\u7684\u6280\u672f\u5b9e\u73b0\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lBXwSVvRHB2Yn0fYoOkDeQ"},"\u91cd\u65b0\u5b9a\u4e49\u5927\u6a21\u578b\u63a8\u7406\uff01Google | \u63d0\u51faSELF-DISCOVER\u6846\u67b6\uff0c\u5927\u6a21\u578b\u53ef\u81ea\u5199\u63a8\u7406\u7ed3\u6784\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/cB5tgMUPqg8fsXjNrzQpbg"},"\u300a\u65af\u5766\u798f && \u5fae\u8f6f | \u53d1\u5e03\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u52a9\u529b\u524d\u7aef\u81ea\u52a8\u5316\uff01\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u5b83\u53ef\u4ee5\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u7684\u6311\u6218\u6027\u548c\u73b0\u6709\u65b9\u6cd5\u7684\u5c40\u9650\u6027\uff0c\u7136\u540e\u63d0\u51fa\u4e86Design2Code\u57fa\u51c6\u548c\u591a\u6a21\u6001\u63d0\u793a\u65b9\u6cd5\uff0c\u4ee5\u6fc0\u53d1\u591a\u6a21\u6001\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u5982GPT-4V\u548cGemini\uff09\u7684\u6f5c\u529b\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5f00\u6e90\u768418B\u5fae\u8c03\u6a21\u578bDesign2Code-18B\uff0c\u5b83\u57fa\u4e8eCogAgent-18B\uff0c\u5728\u591a\u79cd\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u4e86\u9884\u8bad\u7ec3\uff0c\u5e76\u4f7f\u7528\u4e86Huggingface\u53d1\u5e03\u7684WebSight\u6570\u636e\u96c6\u8fdb\u884c\u5fae\u8c03\u3002\u6700\u540e\uff0c\u6587\u7ae0\u5c55\u793a\u4e86Design2Code-18B\u5728Design2Code\u57fa\u51c6\u4e0a\u7684\u4f18\u8d8a\u6027\u80fd\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u4e9b\u672a\u6765\u7814\u7a76\u65b9\u5411\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Pdp6_z_rxBl-kph41Lb8Ww"},"\u53ef\u63a7\u6587\u672c\u751f\u6210\u65b0\u65b9\u6cd5\uff0c\u4eba\u5927&&\u5357\u5f00 | \u63d0\u51faDATG\u67b6\u6784\uff0c\u51c6\u786e\u6027\u63d0\u534719.29%\uff0c\u6548\u7387\u63d0\u53471\u500d")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/53jEDw58dkZlJAVzr31G8A"},"\u300aAuto-Prompt | \u5927\u6a21\u578b\u63d0\u793a(Prompt)\u4f18\u5316\u65b0\u65b9\u6cd5IPC\uff1a\u53ef\u6839\u636e\u7528\u6237\u610f\u56fe\u8fdb\u884c\u5b9a\u5411\u4f18\u5316\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3a Intent-based Prompt Calibration\uff08IPC\uff09\u7684\u7cfb\u7edf\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u901a\u8fc7\u4f7f\u7528\u5408\u6210\u6848\u4f8b\u6837\u672c\u6765\u4f18\u5316\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u63d0\u793a\u5de5\u7a0b\u3002\u5b83\u57fa\u4e8e\u6a21\u578b\u751f\u6210\u7684\u6570\u636e\u96c6\u8fdb\u884c\u63d0\u793a\u4f18\u5316\uff0c\u4ee5\u89e3\u51b3\u5927\u8bed\u8a00\u6a21\u578b\u5bf9\u7ed9\u5b9a\u63d0\u793a\u7684\u654f\u611f\u6027\u7b49\u95ee\u9898\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u6838\u5fc3\u601d\u60f3\u662f\u6839\u636e\u7528\u6237\u610f\u56fe\u8fed\u4ee3\u7ec6\u5316\u63d0\u793a\u3002\u540c\u65f6\uff0c\u6587\u7ae0\u8fd8\u5bf9 IPC \u7cfb\u7edf\u7684\u6574\u4f53\u67b6\u6784\u548c\u5b9e\u73b0\u6d41\u7a0b\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u5c55\u793a\u4e86\u4e00\u4e9b\u5b9e\u9a8c\u7ed3\u679c\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u300a\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u51e0\u79cd\u65b0\u578b\u7684\u667a\u80fd Agent \u8bbe\u8ba1\u65b9\u6cd5\uff0c\u5305\u62ec Plan-and-Execute Agents\u3001ReWOO Agent \u548c LLMCompiler\u3002Plan-and-Execute Agent \u8bbe\u8ba1\u6cd5\u901a\u8fc7\u660e\u786e\u89c4\u5212\u6765\u4f18\u5316\u667a\u80fd Agent \u529f\u80fd\u3002ReWOO Agent \u8bbe\u8ba1\u6cd5\u51ed\u501f\u53d8\u91cf\u5206\u914d\u529f\u80fd\u4f7f\u5f97\u4e0d\u5fc5\u5bf9\u6bcf\u4e2a\u4efb\u52a1\u90fd\u4f7f\u7528 LLM\u3002LLMCompiler \u5219\u901a\u8fc7\u4efb\u52a1\u683c\u5f0f\u5316\u4e3a DAG \u6765\u63d0\u9ad8\u5de5\u5177\u8c03\u7528\u7684\u6548\u7387\u3002\u8fd9\u4e9b\u65b0\u578b\u8bbe\u8ba1\u90fd\u5728\u4e0d\u540c\u7a0b\u5ea6\u4e0a\u4f18\u5316\u4e86\u667a\u80fd Agent \u7684\u5de5\u4f5c\u6d41\u7a0b\uff0c\u63d0\u9ad8\u4e86\u5de5\u4f5c\u6548\u7387\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/F2s3pKycoNDT7Z-6piRHWg"},"\u300aOpenAI Function Calling \u4e0e LangChain Agent \u5de5\u4f5c\u539f\u7406\u53ca\u533a\u522b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86OpenAI Function Calling \u4e0e LangChain Agent\u7684\u5de5\u4f5c\u539f\u7406\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6587\u7ae0\u9996\u5148\u5217\u4e3e\u4e86\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u9650\u5236\uff0c\u5e76\u89e3\u91ca\u4e86\u4e3a\u4f55\u9700\u8981Agent\u3002\u7136\u540e\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86React Agent\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u901a\u8fc7\u201cReason Only\u201d\uff08\u5411\u5185\u6c42\u7d22\uff09\u3001\u201cAct Only\u201d\uff08\u5411\u5916\u63a2\u7d22\uff09\u548c\u201cReAct\u201d\uff08\u5185\u5916\u517c\u4fee\uff09\u4e09\u79cd\u6a21\u5f0f\u4f18\u5316\u6a21\u578b\u7684\u529f\u80fd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u4ee5\u4e00\u4e2a\u7b80\u5355\u7684\u5b9e\u4f8b\uff0c\u89e3\u91ca\u4e86\u5982\u4f55\u5229\u7528ReAct Agent\u6765\u89e3\u7b54\u4e00\u4e2a\u5305\u542b\u641c\u7d22\u548c\u8ba1\u7b97\u4e24\u4e2a\u6b65\u9aa4\u7684\u95ee\u9898\uff0c\u5c55\u793a\u4e86\u5176\u5b9e\u9645\u5e94\u7528\u7684\u6d41\u7a0b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iM45toKEHr3_rJxuwbgp4w"},"\u300aReAct Agent \u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u7684\u590d\u6742\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u201cReAct Agent \u7528\u4e8e\u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u590d\u6742\u95ee\u9898\u7684\u65b9\u5f0f\u201d\u3002\u968f\u7740\u8f93\u5165\u95ee\u9898\u7684\u590d\u6742\u5ea6\u5347\u9ad8\uff0c\u4f7f\u7528\u4f20\u7edf\u7684\u804a\u5929\u673a\u5668\u4eba\u5df2\u4e0d\u80fd\u8db3\u591f\u6709\u6548\u3002\u4e8e\u662f\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u5229\u7528 ReAct Agent\uff0c\u901a\u8fc7\u81ea\u7136\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u9010\u6b65\u89c4\u5212\u5e76\u6267\u884c\u5904\u7406\u95ee\u9898\u7684\u6b65\u9aa4\uff0c\u5e76\u5b9a\u4e49\u529f\u80fd\u6027\u5de5\u5177\uff08\u5982\u65f6\u95f4\u8ba1\u7b97\u3001\u6587\u672c\u641c\u7d22\u3001\u5217\u8868\u957f\u5ea6\u8ba1\u7b97\u3001\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\u7b49\uff09\u4ee5\u8f85\u52a9\u4efb\u52a1\u5b8c\u6210\u3002\u8fd9\u79cd\u65b9\u6cd5\u80fd\u591f\u66f4\u597d\u5730\u5e72\u9884\u548c\u63a7\u5236\u95ee\u9898\u7684\u89e3\u51b3\u8fc7\u7a0b\uff0c\u4ece\u800c\u63d0\u9ad8\u4efb\u52a1\u7684\u5b8c\u6210\u8d28\u91cf\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KF7joY-MkK4BZ8Rf8bLArw"},"ChatGPT\u4e5f\u80fd\u753b\u56fe\uff1f\u6559\u4f60\u4e00\u952e\u751f\u6210\u65f6\u5e8f\u56fe\u3001\u7c7b\u56fe\u3001\u6d41\u7a0b\u56fe\u3001\u72b6\u6001\u56fe\u4ee5\u53ca\u7528\u4f8b\u56fe")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/E2xwi9SNYQ7sdzhYlaDQFg"},"\u4e09\u4e2a\u88ab\u5ffd\u89c6\u7684\u5927\u6a21\u578b\u63d0\u793a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/u2LCRgBhKKcGZhY29PjIng"},"\u5173\u4e8eSora\u548cStable Diffusion 3\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/z6IFIuHawVZI6ZOfgvgKuA"},"\u6d88\u8d39\u7ea7\u663e\u5361\u53ef\u7528\uff01\u674e\u5f00\u590d\u96f6\u4e00\u4e07\u7269\u53d1\u5e03\u5e76\u5f00\u6e9090\u4ebf\u53c2\u6570Yi\u6a21\u578b\uff0c\u4ee3\u7801\u6570\u5b66\u80fd\u529b\u53f2\u4e0a\u6700\u5f3a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IBh3ytd3gtizAQd5PI2uig"},"\u8be6\u89e3\u5927\u6a21\u578b\u5fae\u8c03\u5168\u6d41\u7a0b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/UzC3J_TOzJPEx_86-lRwuw"},"\u5357\u5927\u4fde\u626c\u6559\u6388\uff1a\u4ec0\u4e48\u662fworld models/\u4e16\u754c\u6a21\u578b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Gi6pzD7wAMyzlCBSSWkVLA"},"\u6df1\u5165\u6d45\u51faLangChain\u4e0e\u667a\u80fdAgent\uff1a\u6784\u5efa\u4e0b\u4e00\u4ee3AI\u52a9\u624b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/T9YRVRGMgkwRSTl7Movadg"},"\u5c24\u6d0b\u6559\u6388\uff1a\u5f00\u6e90\u5b8c\u6574\u7684Sora\u590d\u73b0\u65b9\u6848\u6765\u4e86\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/8WYWrHyE4oryCgO9AemImA"},"\u300aT-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"T-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86T-RAG\u6280\u672f\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06RAG\u67b6\u6784\u4e0e\u5fae\u8c03\u8bed\u8a00\u6a21\u578b\u548c\u5b9e\u4f53\u6811\u5411\u91cf\u6570\u636e\u5e93\u76f8\u7ed3\u5408\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u652f\u6301\u8bed\u5883\u68c0\u7d22\u3002\u5b83\u6982\u8ff0\u4e86\u5728\u654f\u611f\u6587\u6863\u7684\u80cc\u666f\u4e0b\u5982\u4f55\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u6709\u9650\u7684\u8ba1\u7b97\u8d44\u6e90\u548c\u57fa\u4e8e\u73b0\u6709\u6587\u6863\u5efa\u7acb\u7684\u5c0f\u578b\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u4fdd\u8bc1\u7528\u6237\u63d0\u95ee\u7684\u51c6\u786e\u56de\u7b54\u3002\u6587\u4e2d\u8fd8\u7740\u91cd\u4ecb\u7ecd\u4e86T-RAG\u7684\u5de5\u4f5c\u6d41\u7a0b\u548c\u5b9e\u4f53\u6811\u7684\u4f5c\u7528\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u51fa\u4e86\u4e00\u4e2a\u65b0\u7684\u8bc4\u4f30\u6307\u6807\u201cCorrect-Verbose\u201d\uff0c\u7528\u4ee5\u8bc4\u4ef7\u751f\u6210\u56de\u590d\u7684\u8d28\u91cf\u3002\u6b64\u7814\u7a76\u4e0d\u4ec5\u662f\u7406\u8bba\u7814\u7a76\uff0c\u4e5f\u662f\u5b9e\u8df5\u4e2dLLM\u5e94\u7528\u7684\u7ecf\u9a8c\u603b\u7ed3\uff0c\u5177\u6709\u5b9e\u9645\u7684\u6307\u5bfc\u610f\u4e49\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/de3UxM9WTrHNjnOKSny0aw"},"\u300a\u9ad8\u7ea7 RAG\uff08Self-Reflective RAG\uff09\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u9ad8\u7ea7 RAG(Self-Reflective RAG)"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86Self-Reflective RAG\u7684\u7406\u5ff5\u548c\u5de5\u4f5c\u6d41\u7a0b\u3002\u5728\u57fa\u672c\u7684RAG pipeline\u4e2d\uff0c\u6211\u4eec\u7684\u8fc7\u7a0b\u5f80\u5f80\u53d7\u9650\u4e8e\u88ab\u52a8\u7684\u68c0\u7d22\u548c\u751f\u6210\uff0c\u800c\u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u751f\u6210\u7684\u7ed3\u679c\u8fdb\u884c\u4f18\u5316\uff0c\u5982\u6539\u53d8\u95ee\u9898\u6216\u7b5b\u9009\u548c\u6392\u5217\u5185\u5bb9\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u81ea\u6211\u4fee\u6b63\u6846\u67b6\uff0c\u5305\u62ecCorrective RAG(CRAG)\u548cSelf-Reflective RAG\u3002\u8fd9\u4e24\u79cdRAG\u90fd\u56f4\u7ed5\u7740\u5bf9\u68c0\u7d22\u548c\u751f\u6210\u5185\u5bb9\u7684\u8bc4\u4f30\u548c\u53cd\u9988\u8fdb\u884c\u81ea\u6211\u4fee\u6b63\uff0c\u5e76\u901a\u8fc7\u7279\u5b9a\u6807\u8bc6\u8fdb\u884c\u8c03\u63a7\u3002\u5728\u4e00\u5b9a\u6761\u4ef6\u4e0b\uff0c\u8fdb\u4e00\u6b65\u6539\u8fdb\u4e86RAG\uff0c\u4f7f\u5176\u4ea7\u751f\u66f4\u597d\u7684\u68c0\u7d22\u548c\u751f\u6210\u6548\u679c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WuJEubctUDsAmdhHcDItAg"},"RAG\u4e0d\u591f\u806a\u660e\uff1f\u6253\u9020\u66f4\u5f3a\u5927\u7684\u667a\u80fd\u4f53")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/b_eWGauwi6v0w4CoSOnU5w"},"Anthropic\u53d1\u5e03Claude3\uff0c\u6548\u679c\u5df2\u8d85\u8d8aGPT4")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/nMWTuKBnQVjgAM7Du6oOFQ"},"\u4ece0\u5f00\u59cb\u9884\u8bad\u7ec31.4b\u4e2d\u6587\u5927\u6a21\u578b\u5b9e\u8df5")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/W5W582CqxvRhF3wnKwIdiQ"},"\u300a\u5206\u7c7b\u7b97\u6cd5\u5165\u95e8:\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\uff0c\u5168\u9762\u800c\u8be6\u7ec6\u5730\u9610\u8ff0\u4e86\u673a\u5668\u5b66\u4e60\u4e2d\u7684\u5206\u7c7b\u7b97\u6cd5\u57fa\u7840\u77e5\u8bc6\u3002\u9996\u5148\u4ecb\u7ecd\u4e86\u4eba\u5de5\u667a\u80fd\u3001\u673a\u5668\u5b66\u4e60\u548c\u6df1\u5ea6\u5b66\u4e60\u7684\u57fa\u672c\u6982\u5ff5\uff0c\u8bb2\u89e3\u4e86\u673a\u5668\u5b66\u4e60\u5404\u79cd\u5206\u7c7b\u65b9\u6cd5\u7684\u7406\u8bba\u80cc\u666f\u3002\u968f\u540e\u901a\u8fc7\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528 Python \u5de5\u5177\uff08\u5305\u62ec pandas\u3001sklearn\u3001matplotlib \u548c seaborn\uff09\u8fdb\u884c\u6570\u636e\u5904\u7406\u3001\u5206\u6790\u548c\u53ef\u89c6\u5316\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u8ff0\u4e86\u51b3\u7b56\u6811\u3001\u903b\u8f91\u56de\u5f52\u3001\u652f\u6301\u5411\u91cf\u673a\u3001K\u8fd1\u90bb\u7b49\u7ecf\u5178\u7684\u5206\u7c7b\u7b97\u6cd5\uff0c\u5e76\u7528\u56fe\u5f62\u5316\u7684\u65b9\u5f0f\u5c55\u793a\u4e86\u5206\u7c7b\u6548\u679c\u3002\u6700\u540e\uff0c\u8bfb\u8005\u53ef\u4ee5\u901a\u8fc7\u672c\u6587\u6240\u63d0\u4f9b\u7684\u4e30\u5bcc\u5b66\u4e60\u8d44\u6599\u6765\u6df1\u5316\u5bf9\u673a\u5668\u5b66\u4e60\u5206\u7c7b\u4efb\u52a1\u7684\u7406\u89e3\u548c\u5e94\u7528\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fkRG7n4tOQKwU85xiEx0Eg"},"\u300a\u4e07\u5b57\u8be6\u89e3LLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u5199\u5728\u8de8\u5e74\u4e4b\u524d\uff1a\u804a\u804aLLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765"\uff0c\u4e3b\u8981\u6d89\u53ca\u5230LLM Agents\u7684\u5f53\u524d\u72b6\u6001\uff0c\u9762\u4e34\u7684\u95ee\u9898\u548c\u672a\u6765\u7684\u53ef\u80fd\u53d1\u5c55\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5305\u62ec\u5168\u53c2\u5fae\u8c03\u3001Prompt Tuning\u3001LoRA\u3001P-Tuning\u7b49\u5728\u5185\u7684SFT(Selective Fine Tuning)\u8303\u7574\u7684\u5404\u79cd\u6280\u672f\u3002\u5176\u4e2d\u5c24\u5176\u5f3a\u8c03\u4e86\u5bf9\u4e8e{prompt\uff0cresponse}\u7684\u5355\u8f6e\u95ee\u7b54\u5bf9\u7684\u5fae\u8c03\u662f\u6700\u7b80\u5355\u7684SFT\u5b9e\u73b0\u65b9\u5f0f\u3002\u5177\u4f53\u7684\u5185\u5bb9\u7ec6\u8282\u5927\u6982\u9700\u8981\u9605\u8bfb\u539f\u6587\u624d\u80fd\u83b7\u5f97\u66f4\u6df1\u5165\u7684\u7406\u89e3\u3002'),(0,a.kt)("h2",{id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173"},"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/generic-slice-functions"},"\u300aRobust generic functions on slices\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Robust generic functions on slices"\uff0c\u4e3b\u8981\u63a2\u8ba8\u4e86Go\u7684slices\u5305\u5982\u4f55\u63d0\u4f9b\u5bf9\u5207\u7247\u8fdb\u884c\u64cd\u4f5c\u7684\u901a\u7528\u51fd\u6570\u3002\u8be5\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u7c7b\u578b\u53c2\u6570\uff0c\u4e00\u6b21\u6027\u4e3a\u6240\u6709\u7c7b\u578b\u7684\u5207\u7247\u7f16\u5199\u7c7b\u4f3cslices.Index\u7b49\u51fd\u6570\uff0c\u800c\u65e0\u9700\u9488\u5bf9\u6bcf\u79cd\u4e0d\u540c\u7684\u5143\u7d20\u7c7b\u578b\u91cd\u65b0\u5b9e\u73b0\u3002\u968f\u540e\uff0c\u6587\u7ae0\u6df1\u5165\u8bb2\u8ff0\u4e86\u65b0\u7684\u51fd\u6570\uff08\u5982Insert, Replace\uff0cDelete\u7b49\uff09\u5982\u4f55\u4fee\u6539\u5207\u7247\uff0c\u5e76\u901a\u8fc7\u8be6\u8ff0\u5207\u7247\u5728\u5185\u5b58\u4e2d\u7684\u8868\u73b0\u5f62\u5f0f\u53ca\u5176\u5bf9\u5783\u573e\u56de\u6536\u5668\u7684\u5f71\u54cd\uff0c\u6765\u5e2e\u52a9\u8bfb\u8005\u7406\u89e3\u8fd9\u4e9b\u51fd\u6570\u7684\u5de5\u4f5c\u65b9\u5f0f\u548c\u6b63\u786e\u4f7f\u7528\u5b83\u4eec\u3002\u6587\u7ae0\u7279\u522b\u6307\u51fa\uff0c\u65b0\u7684Delete\u51fd\u6570\u63d0\u4f9b\u4e86\u66f4\u6e05\u6670\u5730\u8868\u8fbe\u7a0b\u5e8f\u5458\u610f\u56fe\u7684\u65b9\u5f0f\uff0c\u800c\u4e14\u5b83\u4e0d\u9700\u8981\u5206\u914d\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u6e05\u9664\u65e0\u7528\u7684\u5143\u7d20\uff0c\u5e2e\u52a9\u5783\u573e\u56de\u6536\u3002\u6587\u7ae0\u5f3a\u8c03\uff0c\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c\u5fc5\u987b\u8ba4\u4e3a\u539f\u59cb\u5207\u7247\u5df2\u65e0\u6548\uff0c\u56e0\u4e3a\u5e95\u5c42\u6570\u7ec4\u5df2\u88ab\u4fee\u6539\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u5728\u5904\u7406\u5185\u5b58\u6cc4\u6f0f\u548c\u5143\u7d20\u96f6\u503c\u8bbe\u7f6e\u7b49\u95ee\u9898\u65f6\u7684\u7b56\u7565\u548c\u9009\u9879\uff0c\u5b83\u4eec\u5728\u65b0\u7248\u672cGo\u7ed9\u51fa\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u6539\u53d8\u53ef\u80fd\u5bfc\u81f4\u7684\u4e00\u4e9b\u6d4b\u8bd5\u95ee\u9898\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9f13\u52b1\u5f00\u53d1\u4eba\u5458\u6b63\u786e\u4f7f\u7528\u65b0\u529f\u80fd\uff0c\u5e76\u5c3d\u91cf\u907f\u514d\u4e0a\u8ff0\u5217\u4e3e\u7684\u9677\u9631\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/routing-enhancements"},"\u300aRouting Enhancements for Go 1.22\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Routing Enhancements for Go 1.22"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86 Go 1.22 \u7248\u672c\u4e2d net/http \u5305\u7684\u8def\u7531\u5668\u63d0\u4f9b\u7684\u65b0\u7279\u6027\uff1a\u65b9\u6cd5\u5339\u914d\u548c\u901a\u914d\u7b26\u3002\u8fd9\u4e9b\u65b0\u7279\u6027\u8ba9\u4f60\u53ef\u4ee5\u4f7f\u7528\u6a21\u5f0f\uff0c\u800c\u975e Go \u4ee3\u7801\uff0c\u6765\u8868\u8fbe\u5e38\u89c1\u7684\u8def\u7531\u3002\u8fd9\u79cd\u65b0\u529f\u80fd\uff0c\u5c3d\u7ba1\u7b80\u5355\u6613\u61c2\uff0c\u4f46\u8981\u9009\u62e9\u51fa\u591a\u4e2a\u5339\u914d\u8bf7\u6c42\u7684\u6700\u4f73\u6a21\u5f0f\u5374\u662f\u4e00\u9879\u6311\u6218\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u9610\u91ca\u4e86\u5982\u4f55\u5728\u65b0\u7248 Go \u4e2d\u4f7f\u7528\u8fd9\u4e9b\u65b0\u7279\u6027\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u5f15\u5165\u7684\u53d8\u5316\u5982\u4f55\u5f71\u54cd\u4e86 ServeMux \u65b9\u6cd5 handle \u548c handleFunc \u3002\u6b64\u5916\uff0c\u8fd8\u63cf\u8ff0\u4e86\u65b0\u6a21\u5f0f\u5982\u4f55\u66f4\u5177\u4f18\u5148\u7ea7\uff0c\u5e76\u89e3\u91ca\u4e86\u5176\u80cc\u540e\u7684\u539f\u7406\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u65b0\u65e7\u7248\u672c\u7684\u517c\u5bb9\u6027\uff0c\u4f5c\u8005\u4eec\u4e5f\u52aa\u529b\u4f7f\u65b0\u7684\u6a21\u5f0f\u8bed\u6cd5\u80fd\u8986\u76d6\u65e7\u7684\uff0c\u5e76\u4f7f\u65b0\u7684\u4f18\u5148\u7ea7\u89c4\u5219\u80fd\u6cdb\u5316\u65e7\u7684\u89c4\u5219\u3002\u603b\u4f53\u4e0a\uff0c\u8fd9\u4e9b\u6539\u53d8\u662f Go \u8bed\u8a00\u56e2\u961f\u4e0d\u65ad\u52aa\u529b\u4f7f Go \u6210\u4e3a\u6784\u5efa\u751f\u4ea7\u7cfb\u7edf\u7684\u4f18\u79c0\u8bed\u8a00\u7684\u4e00\u4e2a\u6301\u7eed\u8fc7\u7a0b\u7684\u4e00\u90e8\u5206\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IH1FGDpClrsnlfjg7OF3lg"},"\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(6)")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/JCU3dwkwpMP3qMKqg9ed6g"},"\u4f7f\u7528Apache Kafka\u7684Golang\u5b9e\u8df5\u6307\u5357")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/RFsHfFByarSRAA-f1Rs13g"},"\u300aGo \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570\u300b"),'\u3002\u8fd9\u7bc7\u7531\u714e\u9c7c\u64b0\u5199\u7684\u6587\u7ae0\uff0c\u9898\u4e3a "Go \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570?"\uff0c\u5bf9\u4e8e\u8fd9\u4e2a\u8bdd\u9898\u8fdb\u884c\u4e86\u6df1\u5ea6\u89e3\u6790\u3002\u5176\u9996\u5148\u63d0\u5230\uff0c\u867d\u7136Go\u7684\u89c4\u8303\u5e76\u6ca1\u6709\u660e\u786e\u7981\u6b62\u4ecemain\u5305\u4e2d\u5bfc\u5165\u51fd\u6570\uff0c\u4f46\u6211\u4eec\u5728\u5b9e\u9645\u8fd0\u884c\u4e2d\u4f1a\u88ab\u62d2\u7edd\uff0c\u63d0\u793amain\u5305\u662f\u4e00\u4e2a\u7a0b\u5e8f\u800c\u975e\u53ef\u4ee5\u5bfc\u5165\u7684\u5305\u3002\u8fd9\u4e00\u73b0\u8c61\u7684\u539f\u56e0\u6765\u81ea\u4e8e\u7ecf\u8fc7\u591a\u6b21\u53d8\u52a8\u7684\u89c4\u5b9a\uff0c\u59822011\u5e74\u79fb\u9664\u4e86 "\u7a0b\u5e8f\u4e2d\u7684\u5176\u4ed6\u5305\u90fd\u4e0d\u80fd\u547d\u540d\u4e3a main" \u7684\u8981\u6c42\uff0c\u7136\u540e\u57282015\u5e74\u53c8\u65b0\u589e\u4e86\u9650\u5236\u3002\u8fd9\u6837\u7684\u53d8\u5316\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u589e\u52a0\u590d\u6742\u5ea6\u548c\u4e0d\u5b89\u5168\u6027\u3002\u6bd4\u5982\uff0c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u505a\u51fa\u81ea\u5df1\u62e5\u6709\u5b8c\u5168\u63a7\u5236\u6743\u7684\u5047\u8bbe\uff0c\u6240\u4ee5\u5982\u679c\u5f15\u5165\u591a\u4e2amain\u5305\u4e2d\u7684\u51fd\u6570\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u5728\u521d\u59cb\u5316\u987a\u5e8f\u3001\u5168\u5c40\u53d8\u91cf\u7684\u6ce8\u518c\u7b49\u65b9\u9762\u7684\u51b2\u7a81\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba4\u4e3aGo\u5b98\u65b9\u7684\u505a\u6cd5\u5728\u7406\u8bba\u4e0a\u53ef\u4ee5\u89e3\u51b3\u590d\u6742\u5ea6\u548c\u5b89\u5168\u6027\u95ee\u9898\uff0c\u4f46\u5bf9\u4e8e\u6709\u5386\u53f2\u503a\u52a1\u7684\u9879\u76ee\uff0c\u5bf9\u4e8e\u9700\u8981\u7ef4\u62a4\u591a\u4e2aGo\u9879\u76ee\u5de5\u7a0b\uff0c\u76f8\u5f53\u4e8e\u78e8\u706d\u4e86\u4e00\u6761\u9053\u8def\uff0c\u5176\u5b9e\u6bd4\u8f83\u5c34\u5c2c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/zxLO4IhLqQmIaUDzwwjU1w"},"\u300afasthttp\u662f\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8bb2\u89e3\u4e86fasthttp\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u539f\u7406\u3002fasthttp\u76f8\u6bd4\u4e8enet/http\u5728\u5904\u7406\u6d41\u7a0b\u4e0a\u6709\u6240\u5dee\u5f02\uff0cnet/http\u662f\u4e00\u4e2a\u8fde\u63a5\u65b0\u5efa\u4e00\u4e2agoroutine\uff0c\u5f53\u8fde\u63a5\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\u4f1a\u7ed9\u7cfb\u7edf\u5e26\u6765\u4e00\u5b9a\u7684\u538b\u529b\u3002\u800cfasthttp\u5219\u662f\u5efa\u7acb\u4e86workerPool\uff0c\u6bcf\u4e2aworkerChan\u5728\u540e\u53f0\u90fd\u4f1a\u6709\u4e00\u4e2aGoroutine\u6765\u5904\u7406\u5176\u4e2d\u7684\u8fde\u63a5\u3002\u6b64\u5916\uff0cfasthttp\u7684\u5feb\u901f\u4e5f\u5f97\u76ca\u4e8e\u51e0\u4e2a\u65b9\u9762\u7684\u4f18\u5316\uff1a\u8fde\u63a5\u590d\u7528\uff0c\u5927\u91cf\u4f7f\u7528\u4e86sync.Pool\u8fdb\u884c\u5185\u5b58\u590d\u7528\u4ee5\u53ca\u901a\u8fc7unsafe.Pointer\u6307\u9488\u8fdb\u884c","[","]","byte\u548cstring\u8f6c\u6362\u6765\u907f\u514d\u5185\u5b58\u5206\u914d\u548c\u62f7\u8d1d\u7684\u6d88\u8017\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fx-FTVpM3CXIPUwTC_juDQ"},"\u300a\u4e07\u5b57\u957f\u6587\u8bb2\u89e3Golang pprof \u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86Golang\u7684pprof\u5de5\u5177\u7684\u4f7f\u7528\u3002pprof\u5de5\u5177\u662fGolang\u4e2d\u7528\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4e00\u4e2a\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u5206\u6790\u51facpu\u4f7f\u7528\u60c5\u51b5\u3001\u5185\u5b58\u5360\u7528\u3001\u963b\u585e\u60c5\u51b5\u3001\u7ebf\u7a0b\u548c\u534f\u7a0b\u7b49\u4fe1\u606f\u3002\u6587\u7ae0\u4e2d\u8be6\u7ec6\u9610\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528\u6b64\u5de5\u5177\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u901a\u8fc7http\u63a5\u53e3\u7684\u65b9\u5f0f\u66b4\u9732\u51fapprof\u7684\u91c7\u96c6\u63a7\u5236\u754c\u9762\uff0c\u53e6\u4e00\u79cd\u662f\u5728\u7a0b\u5e8f\u4e2d\u901a\u8fc7\u4ee3\u7801\u6765\u542f\u52a8\u76f8\u5e94\u6307\u6807\u7684\u91c7\u96c6\u793a\u4f8b\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u89e3\u6790\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u5f0f\u83b7\u53d6\u7684\u8f93\u51fa\u4fe1\u606f\u3002\u672c\u6587\u7684\u4e3b\u8981\u76ee\u7684\u662f\u5c06pprof\u5de5\u5177\u7684\u4f7f\u7528\u65b9\u5f0f\u7528\u601d\u7ef4\u5bfc\u56fe\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765\uff0c\u8fd9\u6837\u53ef\u4ee5\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u4f7f\u7528pprof\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/xYvMI0JieO6RxHIdWf1ujQ"},"\u300a\u4e00\u7bc7\u5b9e\u7528\u7684\u5173\u4e8e\u4e91\u4e0aK8s\u5e94\u7528\u5206\u8d26\u5b9e\u8df5\u300b"),"\u3002\u672c\u6587\u8bb2\u8ff0\u4e91\u4e0aKubernetes\uff08K8s\uff09\u5e94\u7528\u7684\u6210\u672c\u5206\u644a\u5b9e\u8df5\uff0c\u6db5\u76d6\u4e86\u6210\u672c\u5206\u644a\u7684\u6838\u5fc3\u6982\u5ff5\u53ca\u963f\u91cc\u4e91ACK FinOps\u5957\u4ef6\u7684\u5e94\u7528\u3002\u6587\u4e2d\u9996\u5148\u4ee5\u524d\u671f\u9884\u7b97\u4e3a\u96c6\u7fa4\u89c4\u5212\u7684\u4f9d\u636e\uff0c\u5e76\u8ba8\u8bba\u4e86\u968f\u7740\u4e1a\u52a1\u53d1\u5c55\u5bf9\u6210\u672c\u5206\u644a\u7cbe\u51c6\u5ea6\u7684\u63d0\u5347\u9700\u6c42\u3002\u4ecb\u7ecd\u4e86\u5982\u4f55\u6839\u636ePod\u7684\u6838/\u65f6\u6210\u672c\uff0c\u901a\u8fc7ACK\u96c6\u7fa4\u3001\u8ba1\u7b97\u8282\u70b9\u3001\u547d\u540d\u7a7a\u95f4\u548c\u5e94\u7528Pod\u8fd9\u56db\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u8d39\u7528\u5206\u644a\u3002\u6587\u7ae0\u8fd8\u5206\u6790\u4e86\u5355\u8d44\u6e90\u548c\u6df7\u5408\u8d44\u6e90\u5206\u644a\u6a21\u578b\uff0c\u5e76\u8ba8\u8bba\u4e86\u5982\u4f55\u8bbe\u7f6eRequest\u548cLimit\u6765\u4f18\u5316\u8d44\u6e90\u5229\u7528\u3002\u5bf9\u4e8e\u591a\u4e91\u548c\u6df7\u5408\u4e91\u573a\u666f\uff0c\u5206\u4eab\u4e86\u5982\u4f55\u901a\u8fc7ACK One\u5b9e\u73b0\u7edf\u4e00\u7ba1\u7406\u548c\u6210\u672c\u5206\u6790\u3002\u9488\u5bf9\u590d\u6742\u4e1a\u52a1\u573a\u666f\uff0c\u8bb2\u8ff0\u4e86\u81ea\u5b9a\u4e49\u5b9a\u4ef7\u6a21\u7248\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u5141\u8bb8\u901a\u8fc7\u914d\u7f6e\u5b9e\u73b0\u6210\u672c\u5b9a\u5236\u9700\u6c42\u3002\u5bf9\u4e8e\u8ffd\u6c42\u7ec6\u8282\u7ba1\u7406\u548c\u7cbe\u7ec6\u5316\u8fd0\u8425\u7684\u56e2\u961f\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u6307\u5bfc\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/6xx3-qow8A5Hdp_72jswow"},'\u300a\u5982\u4f55\u4f7f\u7528 K8s \u4e24\u5927\u5229\u5668"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u5e2e\u4f60\u6446\u8131\u8fd0\u7ef4\u56f0\u5883\u300b'),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528 Kubernetes\uff08K8s\uff09\u7684"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u529f\u80fd\u6765\u5e2e\u52a9\u8fdb\u884c\u65e5\u5e38\u96c6\u7fa4\u8fd0\u7ef4\u5de5\u4f5c\u3002\u6587\u7ae0\u9996\u5148\u6307\u51fa\u4e86\u8fd0\u7ef4\u5de5\u4f5c\u4e2d\u53ef\u80fd\u51fa\u73b0\u7684\u4e00\u4e9b\u95ee\u9898\uff0c\u4f8b\u5982\u5e94\u7528\u88ab\u5220\u9664\u3001Apiserver\u8d1f\u8f7d\u7a81\u53d8\u3001\u96c6\u7fa4\u8282\u70b9\u51fa\u73b0\u95ee\u9898\u3001\u8282\u70b9\u81ea\u52a8\u6269\u5bb9\u7b49\u3002\u968f\u540e\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u89e3\u91ca\u4e86 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\u662f\u5982\u4f55\u8fd0\u4f5c\u7684\uff0c\u5f3a\u8c03\u4e86\u5584\u7528\u8fd9\u4e24\u79cd\u5de5\u5177\u53ef\u4ee5\u63d0\u9ad8\u96c6\u7fa4\u7684\u53ef\u89c2\u5bdf\u6027\uff0c\u4e3a\u8fd0\u7ef4\u5de5\u4f5c\u5e26\u6765\u6781\u5927\u7684\u4fbf\u5229\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u901a\u8fc7\u4f7f\u7528 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u66f4\u597d\u5730\u7ba1\u7406\u548c\u76d1\u6d4b\u96c6\u7fa4\u7684\u72b6\u6001\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lxEAFe2Ewmc8YvTqn8UcLQ"},"\u3010Go \u5de5\u5177\u3011\u7ade\u6001\u6761\u4ef6\u68c0\u6d4b\u795e\u5668 Race Detector")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Y67J4_D1yyMa-eb7XmgTcA"},"\u4f7f\u7528Redis\u5165\u95e8Golang")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/qDFM-nVo-jeh9VdcBfMreA"},"\u4e00\u9053\u9762\u8bd5\u9898: Top K \u95ee\u9898")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/sTd3SVh0swGTnaGugsw1SA"},"\u300a\u7406\u89e3 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u89e3\u6790\u4e86 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u3002\u9996\u5148\uff0c\u4f5c\u8005\u6982\u8ff0\u4e86\u7528\u6237\u540d\u3001\u7ec4\u540d\u3001\u7528\u6237ID\uff08UID\uff09\u548c\u7ec4ID\uff08GID\uff09\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e0e\u4e3b\u673a\u7cfb\u7edf\u4e4b\u95f4\u7684\u6620\u5c04\u5bf9\u4e8e\u6784\u5efa\u5b89\u5168\u7cfb\u7edf\u7684\u91cd\u8981\u6027\u3002\u968f\u540e\uff0c\u6587\u7ae0\u5206\u6790\u4e86uid/gid\u5728Linux\u7cfb\u7edf\u7684\u5b89\u5168\u6027\uff0c\u5f3a\u8c03\u4e86\u5355\u4e00\u5185\u6838\u6982\u5ff5\u4ee5\u53cauid/gid\u7684\u5206\u914d\u65b9\u5f0f\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u8fd0\u7528\u5b9e\u4f8b\u89e3\u91ca\u4e86Docker\u8fd0\u884c\u7684\u8fc7\u7a0b\u4ee5\u53ca\u5982\u4f55\u901a\u8fc7Dockerfile\u5b9a\u4e49\u548c\u542f\u52a8\u4e0d\u540c\u7528\u6237\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8bb2\u8ff0\u4e86\u5982\u4f55\u638c\u63a7\u548c\u63a7\u5236\u5bb9\u5668\u7684\u8bbf\u95ee\u6743\u9650\u3002\u5728\u9610\u8ff0\u4ee5\u4e0a\u5185\u5bb9\u7684\u540c\u65f6\uff0c\u6587\u7ae0\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u9645\u793a\u4f8b\u6765\u8bf4\u660e\u8fd9\u4e9b\u89c2\u70b9\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yUuo1IjeXY78_5u4QpkuTA"},"\u300a\u5982\u4f55\u57fa\u4e8eDocker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u5c06Docker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u3002\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5229\u7528\u5f00\u6e90\u5de5\u5177Dedockify\u7684\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u5de5\u4f5c\u539f\u7406\u3002\u8be5\u5de5\u5177\u901a\u8fc7Python\u811a\u672c\uff0c\u5229\u7528\u5b58\u50a8\u5728\u6bcf\u4e2a\u955c\u50cf\u5c42\u65c1\u8fb9\u7684\u5143\u6570\u636e\uff0c\u9010\u6b65\u904d\u5386\u5c42\u7ea7\u6811\uff0c\u6536\u96c6\u4e0e\u6bcf\u4e2a\u5c42\u76f8\u5173\u8054\u7684\u547d\u4ee4\uff0c\u91cd\u5efa\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\u547d\u4ee4\u5e8f\u5217\uff0c\u4ece\u800c\u5f97\u5230\u8fd1\u4f3c\u7684Dockerfile\u3002\u4e0d\u8fc7\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bbf\u95ee\u6267\u884c\u539f\u59cbdocker build\u547d\u4ee4\u65f6\u5b58\u5728\u7684\u6784\u5efa\u4e0a\u4e0b\u6587\uff0c\u5982\u679c\u4f7f\u7528\u4e86COPY\u6216ADD\u6307\u4ee4\uff0c\u751f\u6210\u7684\u8f93\u51fa\u53ef\u80fd\u4e0d\u5b8c\u5168\u5339\u914d\u539f\u59cb\u7684Dockerfile\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KkRWQyljuo86-XbBxEnGPA"},"\u300a\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u3002\u9996\u5148\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a\u901a\u7528\u7684Dockerfile\uff0c\u5e76\u6307\u51fa\u5176\u751f\u6210\u7684\u955c\u50cf\u5927\u5c0f\u8d85\u8fc7300MB\uff0c\u4e3b\u8981\u56e0\u4e3a\u5305\u542b\u4e86\u6240\u6709\u7684Golang\u5de5\u5177\u3002\u7136\u540e\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u591a\u9636\u6bb5\u6784\u5efa\u7684\u65b9\u6cd5\uff0c\u5b83\u80fd\u4ece\u4e0d\u540c\u7684\u57fa\u7840\u955c\u50cf\u6784\u5efa\uff0c\u6709\u9009\u62e9\u5730\u5c06\u6587\u4ef6\u4ece\u4e00\u4e2a\u9636\u6bb5\u4f20\u9012\u5230\u4e0b\u4e00\u4e2a\u9636\u6bb5\uff0c\u4ece\u800c\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u901a\u8fc7\u4e8c\u7ea7\u6784\u5efa\uff0c\u955c\u50cf\u5927\u5c0f\u5df2\u964d\u81f311.7MB\u3002\u6700\u540e\uff0c\u8fd8\u63a2\u8ba8\u4e86\u4f7f\u7528\u540d\u4e3ascratch\u7684\u7a7a\u767d\u955c\u50cf\u8fdb\u4e00\u6b65\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u7684\u53ef\u80fd\u6027\uff0c\u4f7f\u5f97\u955c\u50cf\u6700\u540e\u964d\u81f36.34MB\uff0c\u4f46\u4f5c\u8005\u5f3a\u8c03\u8fd9\u9700\u8981\u614e\u91cd\u8003\u8651\uff0c\u56e0\u4e3a\u6700\u540e\u751f\u6210\u7684\u955c\u50cf\u5c06\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dckA1ezcABndN5WSg1BOBA"},"\u300ak8s \u5230\u5e95\u662f\u4ec0\u4e48\uff0c\u67b6\u6784\u662f\u600e\u4e48\u6837\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86 Kubernetes\uff08K8s\uff09\u7684\u57fa\u672c\u6982\u5ff5\u3001\u67b6\u6784\u548c\u5de5\u4f5c\u539f\u7406\u3002Kubernetes\uff0c\u56e0\u5355\u8bcd\u8fc7\u957f\uff0c\u6211\u4eec\u901a\u5e38\u7b80\u5316\u4e3ak8s\u3002k8s \u662f\u4e00\u79cd\u5bb9\u5668\u7684\u534f\u8c03\u5de5\u5177\uff0c\u4f4d\u4e8e\u5e94\u7528\u670d\u52a1\u548c\u670d\u52a1\u5668\u4e4b\u95f4\uff0c\u80fd\u4ee5\u7b56\u7565\u7684\u65b9\u5f0f\u534f\u8c03\u548c\u7ba1\u7406\u591a\u4e2a\u5e94\u7528\u670d\u52a1\u3002\u901a\u8fc7\u4e00\u4e2a yaml \u6587\u4ef6\u7684\u914d\u7f6e\uff0c\u53ef\u4ee5\u5b9a\u4e49\u5e94\u7528\u7684\u90e8\u7f72\u987a\u5e8f\u7b49\u4fe1\u606f\uff0c\u81ea\u52a8\u90e8\u7f72\u5e94\u7528\u5230\u5404\u4e2a\u670d\u52a1\u5668\u4e0a\uff0c\u8fd8\u80fd\u8ba9\u5b83\u4eec\u5d29\u6e83\u540e\u81ea\u52a8\u91cd\u542f\uff0c\u53ef\u4ee5\u81ea\u52a8\u6269\u5bb9\u548c\u7f29\u5bb9\u3002Kubernetes \u7684\u670d\u52a1\u5668\u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u63a7\u5236\u5e73\u9762\u548c\u5de5\u4f5c\u8282\u70b9\uff0c\u524d\u8005\u8d1f\u8d23\u63a7\u5236\u548c\u7ba1\u7406\u5404\u4e2a\u8282\u70b9\uff0c\u540e\u8005\u5219\u8d1f\u8d23\u5b9e\u9645\u8fd0\u884c\u5404\u4e2a\u5e94\u7528\u670d\u52a1\u3002k8s \u7684\u547d\u4ee4\u884c\u5de5\u5177\u4e3a kubectl\uff0c\u7528\u4e8e\u6267\u884c\u5404\u7c7b\u64cd\u4f5c\u547d\u4ee4\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/vjmntyGwzURz_elg27vpXg"},"\u300aGo \u6cdb\u578b\u6709\u6ca1\u6709\u53ef\u80fd\u5728\u540e\u671f\u6539\u4e3a ",(0,a.kt)("inlineCode",{parentName:"a"},"<>")," \u5c16\u62ec\u53f7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728\u5904\u7406\u6cdb\u578b\u65f6\uff0c\u4e3a\u4f55\u5e76\u6ca1\u6709\u91c7\u7528\u7c7b\u4f3cJava\u548cC++\u7684 ",(0,a.kt)("inlineCode",{parentName:"p"},"<>")," \u5c16\u62ec\u53f7\u8868\u793a\u6cd5\uff0c\u800c\u662f\u9009\u62e9\u4e86\u4e2d\u62ec\u53f7 ",(0,a.kt)("inlineCode",{parentName:"p"},"[]"),". \u9996\u5148\uff0c\u4f7f\u7528\u5c16\u62ec\u53f7\u53ef\u80fd\u5bfc\u81f4\u8bed\u4e49\u6df7\u6dc6\uff0c\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"a, b := w < x, y > (z)")," \u6b64\u53e5\uff0c\u5982\u679c\u4f7f\u7528\u5c16\u62ec\u53f7\uff0c\u7a0b\u5e8f\u53ef\u80fd\u5728\u7f16\u8bd1\u9636\u6bb5\u65e0\u6cd5\u786e\u5b9a\u8be5\u884c\u8868\u8fbe\u5f0f\u7684\u5177\u4f53\u542b\u4e49\u3002\u5176\u6b21\uff0c\u4f7f\u7528\u5706\u62ec\u53f7\u4e5f\u4f1a\u5bfc\u81f4\u540c\u6837\u7684\u95ee\u9898\uff0c\u6bd4\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"func F(T any)(v T)(r1, r2 T)"),", \u65e0\u6cd5\u5feb\u901f\u51c6\u786e\u5224\u65ad\u51fa\u53c2\u6570\u548c\u8fd4\u56de\u503c\u90e8\u5206\u3002\u6b64\u5916\uff0cGo\u5b98\u65b9\u4e5f\u4e0d\u5e0c\u671b\u4f7f\u7528\u975eASCII\u7684\u5b57\u7b26\u3002\u4f5c\u8005\u8fd8\u63d0\u5230\u793e\u533a\u4e2d\u5bf9Go\u7684\u5904\u7406\u65b9\u5f0f\u5b58\u5728\u4e00\u4e9b\u4e89\u8bae\uff0c\u90e8\u5206\u793e\u533a\u6210\u5458\u8ba4\u4e3a\u5982\u679c\u4f7f\u5f97\u7f16\u8bd1\u5668\u89e3\u91ca\u5c16\u62ec\u53f7\u4e0d\u518d\u56f0\u96be\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u8fd9\u79cd\u7b26\u53f7\u3002\u7136\u800c\uff0c\u603b\u7684\u6765\u8bf4\uff0c\u57fa\u4e8e\u5df2\u6709\u7684\u5b9e\u8df5\u548c\u89c4\u8303\uff0cGo\u8bed\u8a00\u5728\u672a\u6765\u53ef\u80fd\u4e5f\u4e0d\u4f1a\u6539\u53d8\u5176\u6cdb\u578b\u7684\u8868\u793a\u65b9\u5f0f\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/arI9sip-5JH9YSu45XJ83w"},"\u300aRust\u4e2dchannel\u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86Rust\u7f16\u7a0b\u8bed\u8a00\u4e2dChannel\u7684\u7528\u6cd5\u3002\u5176\u4e2d\uff0cChannel\u662fRust\u4e2d\u7528\u4e8e\u5728\u4e0d\u540c\u7ebf\u7a0b\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u901a\u4fe1\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u7ebf\u7a0b\u95f4\u7684\u6d88\u606f\u4f20\u9012\u3002\u6bcf\u4e2aChannel\u7531\u53d1\u9001\u7aef\u548c\u63a5\u6536\u7aef\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5176\u8bbe\u8ba1\u7406\u5ff5\u662f\u201c\u901a\u8fc7\u901a\u4fe1\u6765\u5171\u4eab\u5185\u5b58\uff0c\u800c\u975e\u901a\u8fc7\u5171\u4eab\u5185\u5b58\u6765\u901a\u4fe1\u201d\uff0c\u4ee5\u6b64\u907f\u514d\u4e86\u6570\u636e\u7ade\u4e89\u548c\u5171\u4eab\u5185\u5b58\u7684\u590d\u6742\u6027\u3002\u8be5\u6587\u7ae0\u8fdb\u4e00\u6b65\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5728Rust\u4e2d\u521b\u5efa\u548c\u4f7f\u7528Channel\uff0c\u5e76\u7ed9\u51fa\u4e86\u76f8\u5173\u4ee3\u7801\u793a\u4f8b\u3002\u6700\u540e\uff0c\u6587\u7ae0\u9610\u8ff0\u4e86\u591a\u79cdChannel\u6a21\u578b\uff0c\u5305\u62ecRust\u6807\u51c6\u5e93\u4e2d\u6240\u4f7f\u7528\u7684MPSC\uff08\u591a\u751f\u4ea7\u8005\uff0c\u5355\u6d88\u8d39\u8005\uff09\u6a21\u578b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7272006755266002959"},"K8s\u90e8\u7f72\u65b9\u5f0f\u5927\u5168\uff1a\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1\u6240\u6709\u6280\u5de7")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7301584578342289423"},"k8s\u4ece\u5165\u95e8\u5230\u7cbe\u901a -- \u66f4\u9002\u5408\u4e2d\u56fd\u5b9d\u5b9d\u4f53\u8d28")),(0,a.kt)("h2",{id:"-\u540e\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NABg5tGizHsmdXgUO6NeVw"},"\u300a\u4e07\u5b57+33\u5f20\u56fe\u63a2\u79d8OpenFeign\u6838\u5fc3\u67b6\u6784\u539f\u7406\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u6df1\u5165\u63a2\u8ba8\u4e86SpringCloud\u6838\u5fc3\u7ec4\u4ef6OpenFeign\u7684\u6838\u5fc3\u67b6\u6784\u539f\u7406\u3002\u6587\u7ae0\u5206\u4e3a\u56db\u4e2a\u90e8\u5206\uff0c\u9996\u5148\u89e3\u91ca\u539f\u59cbFeign\u7684\u4f7f\u7528\u548c\u57fa\u4e8eSpringCloud\u7684\u8fdb\u5316\u8fc7\u5386\u7a0b\uff1b\u7136\u540e\u8be6\u7ec6\u8bb2\u89e3\u4e86Feign\u5e95\u5c42\u5de5\u4f5c\u539f\u7406\uff0c\u4f9d\u8d56\u4e8eJDK\u52a8\u6001\u4ee3\u7406\u548c\u6838\u5fc3\u7ec4\u4ef6\u5982Contract\u3001Encoder\u3001Decoder\u7b49\uff1b\u63a5\u4e0b\u6765\u5206\u6790\u4e86SpringCloud\u662f\u5982\u4f55\u6574\u5408Feign\u7684\uff0c\u5e76\u4e14\u8ba8\u8bba\u4e86OpenFeign\u7684\u591a\u79cd\u914d\u7f6e\u65b9\u5f0f\u53ca\u5176\u4f18\u5148\u7ea7\uff1b\u6700\u540e\uff0c\u6587\u7ae0\u901a\u8fc7\u4e30\u5bcc\u7684\u56fe\u793a\u548c\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u53ef\u4ee5\u66f4\u597d\u5730\u7406\u89e3\u5e76\u8fd0\u7528\u8fd9\u4e00\u5de5\u5177\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4e8e\u7406\u89e3\u548c\u8fd0\u7528OpenFeign\u975e\u5e38\u6709\u5e2e\u52a9\uff0c\u65e0\u8bba\u662f\u5bf9\u4e8e\u521d\u5b66\u8005\u8fd8\u662f\u6709\u7ecf\u9a8c\u7684\u5f00\u53d1\u8005\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1Qe29y3nrbi39Kpaspme7Q"},"\u300a\u4e09\u4e07\u5b57\u957f\u6587\uff1a\u5982\u4f55\u53bb\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4efd\u8be6\u5c3d\u7684\u6307\u5bfc\uff0c\u8bb2\u8ff0\u4e86\u5982\u4f55\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u3002\u6587\u4e2d\u9996\u5148\u5b9a\u4f4d\u4e86\u6280\u672f\u95ee\u9898\u7684\u8303\u56f4\uff0c\u786e\u5b9a\u9002\u7528\u4e8eJDK8\u81f3JDK11\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u7cfb\u7edf\u5316\u7684\u6392\u67e5\u539f\u5219\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u6b65\u6b65\u7684\u8bca\u65ad\u6d41\u7a0b\uff0c\u4ece\u57fa\u672c\u4fe1\u606f\u6536\u96c6\u3001\u5224\u65ad\u5185\u5b58\u589e\u957f\u539f\u56e0\uff0c\u5230\u5177\u4f53\u5206\u6790\u5185\u5b58\u95ee\u9898\u7684\u53ef\u80fd\u6765\u6e90\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u4e0d\u540c\u7684\u547d\u4ee4\u548c\u5de5\u5177\uff08\u5982jmap\u3001jstat\u3001Arthas\u7b49\uff09\u8fdb\u884c\u8be6\u7ec6\u7684\u5206\u6790\uff0c\u5e76\u6839\u636e\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff0c\u5411\u8bfb\u8005\u5c55\u793a\u4e86\u5982\u4f55\u786e\u5b9a\u662f\u5806\u5185\u5b58\u95ee\u9898\u8fd8\u662f\u5806\u5916\u5185\u5b58\u95ee\u9898\u3002\u603b\u4e4b\uff0c\u6587\u7ae0\u4e3a\u90a3\u4e9b\u9700\u8981\u6df1\u5165\u7406\u89e3\u548c\u5904\u7406JVM\u5185\u5b58\u95ee\u9898\u7684\u5f00\u53d1\u8005\u548c\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u77e5\u8bc6\u548c\u6280\u5de7\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WLPo8s_M3AzxwB3o3ehY3w"},"\u300a\u5982\u4f55\u907f\u514dMYSQL\u4e3b\u4ece\u5ef6\u8fdf\u5e26\u6765\u7684\u8bfb\u5199\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u5904\u7406\u5728MySQL\u4e3b\u4ece\u90e8\u7f72\u67b6\u6784\u4e2d\u666e\u904d\u5b58\u5728\u7684\u4e3b\u4ece\u540c\u6b65\u5ef6\u8fdf\u95ee\u9898\uff0c\u4ee5\u4fdd\u6301\u8bfb\u5199\u64cd\u4f5c\u7684\u4e00\u81f4\u6027\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u4e3b\u4ece\u5ef6\u8fdf\u4ea7\u751f\u7684\u573a\u666f\u53ca\u5176\u5bf9\u8bfb\u5199\u5206\u79bb\u539f\u5219\u7684\u5f71\u54cd\u3002\u7136\u540e\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e86\u4e3b\u4ece\u590d\u5236\u7684\u539f\u7406\uff0c\u5e76\u63d0\u51fa\u4e86\u4e24\u79cd\u907f\u514d\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u6280\u672f\u65b9\u6848\uff1a\u4e00\u662f\u4f7f\u7528select master_pos_wait\u51fd\u6570\u6765\u7b49\u5f85\u4ece\u5e93\u540c\u6b65\u81f3\u7279\u5b9a\u7684binlog\u4f4d\u7f6e\u70b9\uff1b\u4e8c\u662f\u5728\u5f00\u542fGTID\u6a21\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7select wait_for_executed_gtid_set\u51fd\u6570\u68c0\u67e5GTID\u96c6\u5408\u662f\u5426\u5df2\u540c\u6b65\u3002\u8fd9\u4e24\u79cd\u65b9\u6cd5\u5747\u65e8\u5728\u786e\u4fdd\u4ece\u5e93\u6570\u636e\u7684\u51c6\u786e\u6027\uff0c\u4ece\u800c\u6574\u4f53\u4e0a\u51cf\u8f7b\u4e3b\u5e93\u7684\u538b\u529b\u3002\u603b\u4f53\u4e0a\uff0c\u6587\u7ae0\u4e3aMySQL\u6570\u636e\u5e93\u7ba1\u7406\u5458\u63d0\u4f9b\u4e86\u7f13\u89e3\u4e3b\u4ece\u5ef6\u8fdf\u5bfc\u81f4\u7684\u8bfb\u5199\u95ee\u9898\u7684\u5177\u4f53\u5b9e\u65bd\u65b9\u6848\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dt_14etV_2ynAmyMa_uyug"},"\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014ES\u7bc7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u7bc7\u9488\u5bf9Elasticsearch(ES)\u7684\u9762\u8bd5\u6307\u5357\uff0c\u5b83\u6db5\u76d6ES\u57fa\u7840\u77e5\u8bc6\u70b9\u548c\u9762\u8bd5\u8fc7\u7a0b\u4e2d\u5e38\u89c1\u95ee\u9898\u3002\u5185\u5bb9\u5305\u62ecES\u7684\u529f\u80fd\u7279\u6027\u4ecb\u7ecd\uff08\u5982\u5206\u5e03\u5f0f\u67b6\u6784\u3001\u5168\u6587\u641c\u7d22\u3001\u6570\u636e\u5206\u6790\u7b49\uff09\u3001\u4e3b\u8981\u7684\u4f7f\u7528\u573a\u666f\u63cf\u8ff0\u3001\u4e0e\u5176\u4ed6\u641c\u7d22\u5f15\u64ce\u7684\u5bf9\u6bd4\uff08Lucene\u548cSolr\uff09\u3001\u4ee5\u53caES\u7684\u57fa\u672c\u6982\u5ff5\u89e3\u91ca\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u63a2\u8ba8\u4e86ES\u7684\u9ad8\u7ea7\u7279\u6027\uff0c\u5982\u6620\u5c04\u3001DSL\u67e5\u8be2\u3001\u805a\u5408\u5206\u6790\u548c\u667a\u80fd\u641c\u7d22\u5efa\u8bae\u5668\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u8fd8\u5206\u4eab\u4e86\u5173\u4e8e\u6570\u636e\u7d22\u5f15\u4f18\u5316\u7684\u5b9e\u6218\u6280\u5de7\u548c\u7b56\u7565\uff0c\u63d0\u4f9b\u4e86\u5199\u4f18\u5316\u3001\u8bfb\u4f18\u5316\u548c\u7d22\u5f15\u91cd\u5efa\u7684\u65b9\u6848\uff0c\u8fd9\u4e9b\u65b9\u6848\u5bf9ES\u6570\u636e\u5b58\u50a8\u548c\u67e5\u8be2\u7684\u6027\u80fd\u6709\u663e\u8457\u5f71\u54cd\uff0c\u6700\u540e\u8fd8\u5bf9Deep Paging\u6027\u80fd\u95ee\u9898\u63d0\u4f9b\u4e86\u89e3\u51b3\u65b9\u6cd5\u3002\u5bf9\u6b63\u5728\u51c6\u5907\u9762\u8bd5\u6216\u8005\u5e0c\u671b\u5de9\u56faES\u77e5\u8bc6\u7684\u8bfb\u8005\u800c\u8a00\uff0c\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4e2a\u5b9d\u8d35\u7684\u8d44\u6e90\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/gAJFm3q5510PfRBe4F11PQ"},"\u300a\u4ec0\u4e48\u662fMySQL\u9501\uff1f\u6709\u54ea\u4e9b\u9501\u7c7b\u578b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5730\u4ecb\u7ecd\u4e86MySQL\u4e2d\u7684\u9501\u5b9a\u673a\u5236\u53ca\u5176\u7c7b\u578b\u3002\u8d77\u521d\u6982\u8ff0\u4e86\u9501\u7684\u4f5c\u7528\uff0c\u5373\u534f\u8c03\u591a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u8d44\u6e90\u7684\u5e76\u53d1\u8bbf\u95ee\uff0c\u5728\u6570\u636e\u5e93\u73af\u5883\u4e0b\uff0c\u9501\u5bf9\u4e8e\u4fdd\u6301\u4e8b\u52a1\u7684\u6b63\u786e\u6027\u4e0e\u4e00\u81f4\u6027\u81f3\u5173\u91cd\u8981\u3002\u4f5c\u8005\u660e\u786e\u533a\u5206\u4e86MySQL\u4e2d\u9501\u7684\u7ea7\u522b\uff0c\u4ece\u5168\u5c40\u9501\u3001\u8868\u9501\uff08\u8bfb\u9501\u3001\u5199\u9501\uff09\u5230\u5143\u6570\u636e\u9501\u3001\u610f\u5411\u9501\uff0c\u76f4\u5230\u884c\u9501\u7684\u591a\u79cd\u5f62\u5f0f\uff08\u8bb0\u5f55\u9501\u3001\u95f4\u9699\u9501\u548c\u4e34\u952e\u9501\uff09\u3002\u6587\u4e2d\u8fd8\u63a2\u8ba8\u4e86AUTO-INC\u9501\u7684\u4f5c\u7528\u548c\u76f8\u5173\u4f18\u5316\uff0c\u4e3e\u4f8b\u8bf4\u660e\u4e86\u5176\u5728INSERT\u64cd\u4f5c\u4e2d\u7684\u5e94\u7528\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u4e5f\u6d89\u53ca\u4e86\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u60c5\u51b5\u4f18\u5316\u9501\u7684\u4f7f\u7528\u4ee5\u53ca\u5982\u4f55\u907f\u514d\u7531\u9501\u4ea7\u751f\u7684\u6027\u80fd\u74f6\u9888\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u7406\u89e3MySQL\u7684\u5404\u79cd\u9501\u7c7b\u578b\u548c\u9501\u673a\u5236\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u4fe1\u606f\uff0c\u7279\u522b\u5bf9\u4e8e\u6570\u636e\u5e93\u7ba1\u7406\u5458\u548c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5e76\u53d1\u6570\u636e\u8bbf\u95ee\u95ee\u9898\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u5b9e\u7528\u4ef7\u503c\u3002"),(0,a.kt)("h2",{id:"-\u524d\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/m-Ae6dbFuW22u2xSDWcciw"},"Vue \u56e2\u961f\u6b63\u5f0f\u5f00\u6e90 Rolldown\uff1a\u57fa\u4e8e Rust \u7684\u8d85\u5feb JavaScrip \u6253\u5305\u5de5\u5177\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/MVR5rV2LkH8_GHCtP6SHug"},"\u6253\u9020\u8212\u9002\u7684vscode\u5f00\u53d1\u73af\u5883")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/pY4-RqqamTmPXnRPfw0hRA"},"\u76f8\u6bd4\u4e8e Node.js\uff0cDeno \u548c Bun \u5230\u5e95\u80fd\u5e26\u6765\u4ec0\u4e48")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yBTK4Rds28aJ88mVgkoYJA"},"MDH Weekly 122 - \u300a\u62db\u4eba\u300b")))}u.isMDXComponent=!0},7662:(e,t,n)=>{n.d(t,{Z:()=>p});const p=n.p+"assets/images/maxresdefault-5b23cca3601cf7ebe54f3cb5023d859a.jpg"}}]); \ No newline at end of file diff --git a/assets/js/5e7acaa9.540967e8.js b/assets/js/5e7acaa9.3c001628.js similarity index 80% rename from assets/js/5e7acaa9.540967e8.js rename to assets/js/5e7acaa9.3c001628.js index 77926336d5..b691ec755f 100644 --- a/assets/js/5e7acaa9.540967e8.js +++ b/assets/js/5e7acaa9.3c001628.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[6831],{73664:e=>{e.exports=JSON.parse('{"permalink":"/frontend-weekly/2024/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":11,"previousPage":"/frontend-weekly/2024","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[6831],{73664:e=>{e.exports=JSON.parse('{"permalink":"/frontend-weekly/2024/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":12,"previousPage":"/frontend-weekly/2024","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/76cc166b.6f9972d1.js b/assets/js/76cc166b.6f9972d1.js new file mode 100644 index 0000000000..9bcc89261f --- /dev/null +++ b/assets/js/76cc166b.6f9972d1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[7403],{49613:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var p=n(59496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);t&&(p=p.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,p)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(p=0;p=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=p.createContext({}),s=function(e){var t=p.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return p.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return p.createElement(p.Fragment,{},t)}},h=p.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=s(n),h=a,k=c["".concat(l,".").concat(h)]||c[h]||u[h]||r;return n?p.createElement(k,i(i({ref:t},m),{},{components:n})):p.createElement(k,i({ref:t},m))}));function k(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>s});var p=n(64778),a=(n(59496),n(49613));const r={slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},i=void 0,o={permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-10/index.md",source:"@site/blogs/2024/2024-03-10/index.md",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",description:"alt text",date:"2024-03-10T00:00:00.000Z",formattedDate:"March 10, 2024",tags:[],readingTime:34.7,hasTruncateMarker:!1,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},prevItem:{title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"},nextItem:{title:"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"}},l={authorsImageUrls:[void 0]},s=[{value:"\ud83c\udf1f AI \u76f8\u5173",id:"-ai-\u76f8\u5173",level:2},{value:"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173",id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173",id:"-\u540e\u7aef\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173",id:"-\u524d\u7aef\u76f8\u5173",level:2}],m={toc:s},c="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(c,(0,p.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"alt text",src:n(7662).Z,width:"1280",height:"720"})),(0,a.kt)("p",null,"\u5c01\u9762\u56fe\uff1aUnderstanding the Go runtime - Jesus Espino"),(0,a.kt)("h2",{id:"-ai-\u76f8\u5173"},"\ud83c\udf1f AI \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://arxiv.org/abs/2401.11624"},"\u300aIn-context Learning with Retrieved Demonstrations for Language Models: A Survey\u300b"),'\u3002\u8fd9\u7bc7\u9898\u4e3a "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" \u7684\u6587\u7ae0\uff0c\u4e3b\u8981\u8ba8\u8bba\u4e86\u8bed\u8a00\u6a21\u578b\uff0c\u5c24\u5176\u662f\u5927\u578b\u9884\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u5982\u4f55\u901a\u8fc7\u83b7\u53d6\u7684\u6f14\u793a\u8fdb\u884c\u5c11\u91cf\u60c5\u666f\u5b66\u4e60\u3002\u8fd9\u9879\u6280\u672f\u80fd\u6709\u6548\u5730\u6539\u8fdb\u5b66\u4e60\u8fc7\u7a0b\u7684\u6548\u7387\u548c\u53ef\u6269\u5c55\u6027\uff0c\u5e76\u964d\u4f4e\u624b\u52a8\u9009\u62e9\u6837\u4f8b\u65f6\u7684\u56fa\u6709\u504f\u89c1\u3002\u6587\u7ae0\u5bf9\u6b64\u9886\u57df\u8fdb\u884c\u4e86\u5e7f\u6cdb\u7684\u7814\u7a76\u56de\u987e\uff0c\u5bf9\u68c0\u7d22\u6a21\u578b\u3001\u68c0\u7d22\u8bad\u7ec3\u8fc7\u7a0b\u548c\u63a8\u7406\u7b97\u6cd5\u7684\u4e0d\u540c\u8bbe\u8ba1\u9009\u62e9\u8fdb\u884c\u4e86\u8ba8\u8bba\u548c\u6bd4\u8f83\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NUhEy0YLTjtzY3BGVXhfrw"},"\u300a\u78be\u538bLoRA\uff01Meta & CMU | \u63d0\u51fa\u9ad8\u6548\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\uff1aGaLore\uff0c\u5185\u5b58\u53ef\u51cf\u5c1163.3%\u300b"),"\u3002Meta\u548cCMU\u5408\u4f5c\u63d0\u51fa\u4e86\u4e00\u79cd\u65b0\u7684\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\u2014\u2014Gradient Low-Rank Projection\uff08GaLore\uff09\u3002GaLore\u901a\u8fc7\u68af\u5ea6\u7684\u4f4e\u79e9\u6295\u5f71\u4ee3\u66ff\u6743\u91cd\u7684\u4f4e\u79e9\u9002\u914d\uff0c\u4e0d\u4ec5\u652f\u6301\u5168\u53c2\u6570\u5b66\u4e60\uff0c\u800c\u4e14\u663e\u8457\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\uff0c\u51cf\u5c11\u4e8663.3%\u7684\u5185\u5b58\u9700\u6c42\u3002\u4e0d\u540c\u4e8eLoRA\u7684\u4f4e\u79e9\u6743\u91cd\u66f4\u65b0\uff0cGaLore\u5229\u7528\u6743\u91cd\u68af\u5ea6\u7684\u4f4e\u79e9\u7279\u6027\uff0c\u7ed3\u5408\u9010\u5c42\u6743\u91cd\u66f4\u65b0\u548c8\u4f4d\u4f18\u5316\u5668\uff0c\u6709\u6548\u5730\u4f18\u5316\u4e86\u5185\u5b58\u6548\u7387\u3002\u6b64\u5916\uff0cGaLore\u8fd8\u5f15\u5165\u4e86\u53ef\u8c03\u6574\u7684\u8d85\u53c2\u6570\uff0c\u63d0\u9ad8\u4e86\u5176\u9002\u5e94\u6027\u3002\u7ecf\u5b9e\u9a8c\u9a8c\u8bc1\uff0cGaLore\u7684\u8868\u73b0\u4f18\u4e8eLoRA\uff0c\u5c24\u5176\u662f\u5728\u9884\u8bad\u7ec3\u6a21\u578b\u5fae\u8c03\u4e0a\u8868\u73b0\u66f4\u4f73\uff0c\u4e3a\u5927\u6a21\u578b\u8bad\u7ec3\u63d0\u4f9b\u4e86\u65b0\u7684\u89e3\u51b3\u7b56\u7565\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7316592794109198387"},"\u4f7f\u7528 GPT4V+AI Agent \u505a\u81ea\u52a8 UI \u6d4b\u8bd5\u7684\u63a2\u7d22 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZSDCNDRu-tCkOlC9jz2j4w"},"Gemini\u4feebug\u795e\u4e86\uff01\u5f55\u7f51\u9875\u89c6\u9891\u628a\u4ee3\u7801\u5e93\u7529\u7ed9\u5b83\u5c31\u884c\uff0c\u7f51\u53cb\u5750\u4e0d\u4f4f\u4e86\uff1a\u60f3\u8981\u8bbf\u95ee\u6743\u9650")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GXwftkv-UpDQSjiTMn9TFA"},"\u4e00\u952e\u5f00\u542f GPU \u95f2\u7f6e\u6a21\u5f0f\uff0c\u57fa\u4e8e\u51fd\u6570\u8ba1\u7b97\u4f4e\u6210\u672c\u90e8\u7f72 Google Gemma \u6a21\u578b\u670d\u52a1")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/YDwL3dV-Fq5zcEyrL__NGw"},"\u300aYi\u6280\u672f\u62a5\u544a\u7ec6\u8282\u5206\u4eab\u300b"),"\u3002\u8be5\u6587\u7ae0\u5206\u4eab\u4e86Yi\u6a21\u578b\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u548c\u601d\u8def\uff0c\u5f3a\u8c03\u4e86\u6a21\u578b\u8bbe\u8ba1\u56f4\u7ed5\u6a21\u578b\u89c4\u6a21\u3001\u6570\u636e\u89c4\u6a21\u548c\u6570\u636e\u8d28\u91cf\u3002Yi\u6a21\u578b\u7684\u9884\u8bad\u7ec3\u9636\u6bb5\u6570\u636e\u5904\u7406\u6d41\u7a0b\u5305\u62ec\u542f\u53d1\u5f0f\u8fc7\u6ee4\u3001\u5b66\u4e60\u5f0f\u8fc7\u6ee4\u3001\u805a\u7c7b\u8fc7\u6ee4\u4ee5\u53ca\u53bb\u91cd\u7b49\u6b65\u9aa4\uff0c\u4ee5\u63d0\u9ad8\u6570\u636e\u8d28\u91cf\u3002\u5fae\u8c03\u9636\u6bb5\uff0cYi\u6a21\u578b\u4ec5\u91c7\u7528\u4e8610K\u6570\u636e\u8fdb\u884c\u6a21\u578b\u5fae\u8c03\uff0c\u5f3a\u8c03\u6570\u636e\u8d28\u91cf\u80dc\u8fc7\u6570\u91cf\u3002\u5728\u5206\u8bcd\u5668\u3001\u6a21\u578b\u7ed3\u6784\u53ca\u5fae\u8c03\u53c2\u6570\u65b9\u9762\uff0cYi\u6a21\u578b\u91c7\u7528\u4e86\u4e00\u7cfb\u5217\u4f18\u5316\u63aa\u65bd\uff0c\u5305\u62ecTransformer-Decoder\u7ed3\u6784\u3001Grouped-Query Attention\u7b49\u3002\u603b\u7684\u6765\u8bf4\uff0cYi\u6a21\u578b\u901a\u8fc7\u4f18\u5316\u6570\u636e\u5904\u7406\u6d41\u7a0b\u3001\u5fae\u8c03\u7b56\u7565\u3001\u8c03\u6574\u6a21\u578b\u7ed3\u6784\u548c\u53c2\u6570\u7b49\u591a\u65b9\u9762\u5b9e\u73b0\u4e86\u9ad8\u6548\u7684\u6280\u672f\u5b9e\u73b0\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lBXwSVvRHB2Yn0fYoOkDeQ"},"\u91cd\u65b0\u5b9a\u4e49\u5927\u6a21\u578b\u63a8\u7406\uff01Google | \u63d0\u51faSELF-DISCOVER\u6846\u67b6\uff0c\u5927\u6a21\u578b\u53ef\u81ea\u5199\u63a8\u7406\u7ed3\u6784\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/cB5tgMUPqg8fsXjNrzQpbg"},"\u300a\u65af\u5766\u798f && \u5fae\u8f6f | \u53d1\u5e03\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u52a9\u529b\u524d\u7aef\u81ea\u52a8\u5316\uff01\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u5b83\u53ef\u4ee5\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u7684\u6311\u6218\u6027\u548c\u73b0\u6709\u65b9\u6cd5\u7684\u5c40\u9650\u6027\uff0c\u7136\u540e\u63d0\u51fa\u4e86Design2Code\u57fa\u51c6\u548c\u591a\u6a21\u6001\u63d0\u793a\u65b9\u6cd5\uff0c\u4ee5\u6fc0\u53d1\u591a\u6a21\u6001\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u5982GPT-4V\u548cGemini\uff09\u7684\u6f5c\u529b\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5f00\u6e90\u768418B\u5fae\u8c03\u6a21\u578bDesign2Code-18B\uff0c\u5b83\u57fa\u4e8eCogAgent-18B\uff0c\u5728\u591a\u79cd\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u4e86\u9884\u8bad\u7ec3\uff0c\u5e76\u4f7f\u7528\u4e86Huggingface\u53d1\u5e03\u7684WebSight\u6570\u636e\u96c6\u8fdb\u884c\u5fae\u8c03\u3002\u6700\u540e\uff0c\u6587\u7ae0\u5c55\u793a\u4e86Design2Code-18B\u5728Design2Code\u57fa\u51c6\u4e0a\u7684\u4f18\u8d8a\u6027\u80fd\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u4e9b\u672a\u6765\u7814\u7a76\u65b9\u5411\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Pdp6_z_rxBl-kph41Lb8Ww"},"\u53ef\u63a7\u6587\u672c\u751f\u6210\u65b0\u65b9\u6cd5\uff0c\u4eba\u5927&&\u5357\u5f00 | \u63d0\u51faDATG\u67b6\u6784\uff0c\u51c6\u786e\u6027\u63d0\u534719.29%\uff0c\u6548\u7387\u63d0\u53471\u500d")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/53jEDw58dkZlJAVzr31G8A"},"\u300aAuto-Prompt | \u5927\u6a21\u578b\u63d0\u793a(Prompt)\u4f18\u5316\u65b0\u65b9\u6cd5IPC\uff1a\u53ef\u6839\u636e\u7528\u6237\u610f\u56fe\u8fdb\u884c\u5b9a\u5411\u4f18\u5316\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3a Intent-based Prompt Calibration\uff08IPC\uff09\u7684\u7cfb\u7edf\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u901a\u8fc7\u4f7f\u7528\u5408\u6210\u6848\u4f8b\u6837\u672c\u6765\u4f18\u5316\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u63d0\u793a\u5de5\u7a0b\u3002\u5b83\u57fa\u4e8e\u6a21\u578b\u751f\u6210\u7684\u6570\u636e\u96c6\u8fdb\u884c\u63d0\u793a\u4f18\u5316\uff0c\u4ee5\u89e3\u51b3\u5927\u8bed\u8a00\u6a21\u578b\u5bf9\u7ed9\u5b9a\u63d0\u793a\u7684\u654f\u611f\u6027\u7b49\u95ee\u9898\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u6838\u5fc3\u601d\u60f3\u662f\u6839\u636e\u7528\u6237\u610f\u56fe\u8fed\u4ee3\u7ec6\u5316\u63d0\u793a\u3002\u540c\u65f6\uff0c\u6587\u7ae0\u8fd8\u5bf9 IPC \u7cfb\u7edf\u7684\u6574\u4f53\u67b6\u6784\u548c\u5b9e\u73b0\u6d41\u7a0b\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u5c55\u793a\u4e86\u4e00\u4e9b\u5b9e\u9a8c\u7ed3\u679c\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u300a\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u51e0\u79cd\u65b0\u578b\u7684\u667a\u80fd Agent \u8bbe\u8ba1\u65b9\u6cd5\uff0c\u5305\u62ec Plan-and-Execute Agents\u3001ReWOO Agent \u548c LLMCompiler\u3002Plan-and-Execute Agent \u8bbe\u8ba1\u6cd5\u901a\u8fc7\u660e\u786e\u89c4\u5212\u6765\u4f18\u5316\u667a\u80fd Agent \u529f\u80fd\u3002ReWOO Agent \u8bbe\u8ba1\u6cd5\u51ed\u501f\u53d8\u91cf\u5206\u914d\u529f\u80fd\u4f7f\u5f97\u4e0d\u5fc5\u5bf9\u6bcf\u4e2a\u4efb\u52a1\u90fd\u4f7f\u7528 LLM\u3002LLMCompiler \u5219\u901a\u8fc7\u4efb\u52a1\u683c\u5f0f\u5316\u4e3a DAG \u6765\u63d0\u9ad8\u5de5\u5177\u8c03\u7528\u7684\u6548\u7387\u3002\u8fd9\u4e9b\u65b0\u578b\u8bbe\u8ba1\u90fd\u5728\u4e0d\u540c\u7a0b\u5ea6\u4e0a\u4f18\u5316\u4e86\u667a\u80fd Agent \u7684\u5de5\u4f5c\u6d41\u7a0b\uff0c\u63d0\u9ad8\u4e86\u5de5\u4f5c\u6548\u7387\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/F2s3pKycoNDT7Z-6piRHWg"},"\u300aOpenAI Function Calling \u4e0e LangChain Agent \u5de5\u4f5c\u539f\u7406\u53ca\u533a\u522b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86OpenAI Function Calling \u4e0e LangChain Agent\u7684\u5de5\u4f5c\u539f\u7406\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6587\u7ae0\u9996\u5148\u5217\u4e3e\u4e86\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u9650\u5236\uff0c\u5e76\u89e3\u91ca\u4e86\u4e3a\u4f55\u9700\u8981Agent\u3002\u7136\u540e\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86React Agent\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u901a\u8fc7\u201cReason Only\u201d\uff08\u5411\u5185\u6c42\u7d22\uff09\u3001\u201cAct Only\u201d\uff08\u5411\u5916\u63a2\u7d22\uff09\u548c\u201cReAct\u201d\uff08\u5185\u5916\u517c\u4fee\uff09\u4e09\u79cd\u6a21\u5f0f\u4f18\u5316\u6a21\u578b\u7684\u529f\u80fd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u4ee5\u4e00\u4e2a\u7b80\u5355\u7684\u5b9e\u4f8b\uff0c\u89e3\u91ca\u4e86\u5982\u4f55\u5229\u7528ReAct Agent\u6765\u89e3\u7b54\u4e00\u4e2a\u5305\u542b\u641c\u7d22\u548c\u8ba1\u7b97\u4e24\u4e2a\u6b65\u9aa4\u7684\u95ee\u9898\uff0c\u5c55\u793a\u4e86\u5176\u5b9e\u9645\u5e94\u7528\u7684\u6d41\u7a0b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iM45toKEHr3_rJxuwbgp4w"},"\u300aReAct Agent \u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u7684\u590d\u6742\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u201cReAct Agent \u7528\u4e8e\u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u590d\u6742\u95ee\u9898\u7684\u65b9\u5f0f\u201d\u3002\u968f\u7740\u8f93\u5165\u95ee\u9898\u7684\u590d\u6742\u5ea6\u5347\u9ad8\uff0c\u4f7f\u7528\u4f20\u7edf\u7684\u804a\u5929\u673a\u5668\u4eba\u5df2\u4e0d\u80fd\u8db3\u591f\u6709\u6548\u3002\u4e8e\u662f\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u5229\u7528 ReAct Agent\uff0c\u901a\u8fc7\u81ea\u7136\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u9010\u6b65\u89c4\u5212\u5e76\u6267\u884c\u5904\u7406\u95ee\u9898\u7684\u6b65\u9aa4\uff0c\u5e76\u5b9a\u4e49\u529f\u80fd\u6027\u5de5\u5177\uff08\u5982\u65f6\u95f4\u8ba1\u7b97\u3001\u6587\u672c\u641c\u7d22\u3001\u5217\u8868\u957f\u5ea6\u8ba1\u7b97\u3001\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\u7b49\uff09\u4ee5\u8f85\u52a9\u4efb\u52a1\u5b8c\u6210\u3002\u8fd9\u79cd\u65b9\u6cd5\u80fd\u591f\u66f4\u597d\u5730\u5e72\u9884\u548c\u63a7\u5236\u95ee\u9898\u7684\u89e3\u51b3\u8fc7\u7a0b\uff0c\u4ece\u800c\u63d0\u9ad8\u4efb\u52a1\u7684\u5b8c\u6210\u8d28\u91cf\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KF7joY-MkK4BZ8Rf8bLArw"},"ChatGPT\u4e5f\u80fd\u753b\u56fe\uff1f\u6559\u4f60\u4e00\u952e\u751f\u6210\u65f6\u5e8f\u56fe\u3001\u7c7b\u56fe\u3001\u6d41\u7a0b\u56fe\u3001\u72b6\u6001\u56fe\u4ee5\u53ca\u7528\u4f8b\u56fe")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/E2xwi9SNYQ7sdzhYlaDQFg"},"\u4e09\u4e2a\u88ab\u5ffd\u89c6\u7684\u5927\u6a21\u578b\u63d0\u793a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/u2LCRgBhKKcGZhY29PjIng"},"\u5173\u4e8eSora\u548cStable Diffusion 3\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/z6IFIuHawVZI6ZOfgvgKuA"},"\u6d88\u8d39\u7ea7\u663e\u5361\u53ef\u7528\uff01\u674e\u5f00\u590d\u96f6\u4e00\u4e07\u7269\u53d1\u5e03\u5e76\u5f00\u6e9090\u4ebf\u53c2\u6570Yi\u6a21\u578b\uff0c\u4ee3\u7801\u6570\u5b66\u80fd\u529b\u53f2\u4e0a\u6700\u5f3a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IBh3ytd3gtizAQd5PI2uig"},"\u8be6\u89e3\u5927\u6a21\u578b\u5fae\u8c03\u5168\u6d41\u7a0b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/UzC3J_TOzJPEx_86-lRwuw"},"\u5357\u5927\u4fde\u626c\u6559\u6388\uff1a\u4ec0\u4e48\u662fworld models/\u4e16\u754c\u6a21\u578b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Gi6pzD7wAMyzlCBSSWkVLA"},"\u6df1\u5165\u6d45\u51faLangChain\u4e0e\u667a\u80fdAgent\uff1a\u6784\u5efa\u4e0b\u4e00\u4ee3AI\u52a9\u624b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/T9YRVRGMgkwRSTl7Movadg"},"\u5c24\u6d0b\u6559\u6388\uff1a\u5f00\u6e90\u5b8c\u6574\u7684Sora\u590d\u73b0\u65b9\u6848\u6765\u4e86\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/8WYWrHyE4oryCgO9AemImA"},"\u300aT-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"T-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86T-RAG\u6280\u672f\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06RAG\u67b6\u6784\u4e0e\u5fae\u8c03\u8bed\u8a00\u6a21\u578b\u548c\u5b9e\u4f53\u6811\u5411\u91cf\u6570\u636e\u5e93\u76f8\u7ed3\u5408\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u652f\u6301\u8bed\u5883\u68c0\u7d22\u3002\u5b83\u6982\u8ff0\u4e86\u5728\u654f\u611f\u6587\u6863\u7684\u80cc\u666f\u4e0b\u5982\u4f55\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u6709\u9650\u7684\u8ba1\u7b97\u8d44\u6e90\u548c\u57fa\u4e8e\u73b0\u6709\u6587\u6863\u5efa\u7acb\u7684\u5c0f\u578b\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u4fdd\u8bc1\u7528\u6237\u63d0\u95ee\u7684\u51c6\u786e\u56de\u7b54\u3002\u6587\u4e2d\u8fd8\u7740\u91cd\u4ecb\u7ecd\u4e86T-RAG\u7684\u5de5\u4f5c\u6d41\u7a0b\u548c\u5b9e\u4f53\u6811\u7684\u4f5c\u7528\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u51fa\u4e86\u4e00\u4e2a\u65b0\u7684\u8bc4\u4f30\u6307\u6807\u201cCorrect-Verbose\u201d\uff0c\u7528\u4ee5\u8bc4\u4ef7\u751f\u6210\u56de\u590d\u7684\u8d28\u91cf\u3002\u6b64\u7814\u7a76\u4e0d\u4ec5\u662f\u7406\u8bba\u7814\u7a76\uff0c\u4e5f\u662f\u5b9e\u8df5\u4e2dLLM\u5e94\u7528\u7684\u7ecf\u9a8c\u603b\u7ed3\uff0c\u5177\u6709\u5b9e\u9645\u7684\u6307\u5bfc\u610f\u4e49\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/de3UxM9WTrHNjnOKSny0aw"},"\u300a\u9ad8\u7ea7 RAG\uff08Self-Reflective RAG\uff09\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u9ad8\u7ea7 RAG(Self-Reflective RAG)"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86Self-Reflective RAG\u7684\u7406\u5ff5\u548c\u5de5\u4f5c\u6d41\u7a0b\u3002\u5728\u57fa\u672c\u7684RAG pipeline\u4e2d\uff0c\u6211\u4eec\u7684\u8fc7\u7a0b\u5f80\u5f80\u53d7\u9650\u4e8e\u88ab\u52a8\u7684\u68c0\u7d22\u548c\u751f\u6210\uff0c\u800c\u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u751f\u6210\u7684\u7ed3\u679c\u8fdb\u884c\u4f18\u5316\uff0c\u5982\u6539\u53d8\u95ee\u9898\u6216\u7b5b\u9009\u548c\u6392\u5217\u5185\u5bb9\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u81ea\u6211\u4fee\u6b63\u6846\u67b6\uff0c\u5305\u62ecCorrective RAG(CRAG)\u548cSelf-Reflective RAG\u3002\u8fd9\u4e24\u79cdRAG\u90fd\u56f4\u7ed5\u7740\u5bf9\u68c0\u7d22\u548c\u751f\u6210\u5185\u5bb9\u7684\u8bc4\u4f30\u548c\u53cd\u9988\u8fdb\u884c\u81ea\u6211\u4fee\u6b63\uff0c\u5e76\u901a\u8fc7\u7279\u5b9a\u6807\u8bc6\u8fdb\u884c\u8c03\u63a7\u3002\u5728\u4e00\u5b9a\u6761\u4ef6\u4e0b\uff0c\u8fdb\u4e00\u6b65\u6539\u8fdb\u4e86RAG\uff0c\u4f7f\u5176\u4ea7\u751f\u66f4\u597d\u7684\u68c0\u7d22\u548c\u751f\u6210\u6548\u679c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WuJEubctUDsAmdhHcDItAg"},"RAG\u4e0d\u591f\u806a\u660e\uff1f\u6253\u9020\u66f4\u5f3a\u5927\u7684\u667a\u80fd\u4f53")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/b_eWGauwi6v0w4CoSOnU5w"},"Anthropic\u53d1\u5e03Claude3\uff0c\u6548\u679c\u5df2\u8d85\u8d8aGPT4")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/nMWTuKBnQVjgAM7Du6oOFQ"},"\u4ece0\u5f00\u59cb\u9884\u8bad\u7ec31.4b\u4e2d\u6587\u5927\u6a21\u578b\u5b9e\u8df5")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/W5W582CqxvRhF3wnKwIdiQ"},"\u300a\u5206\u7c7b\u7b97\u6cd5\u5165\u95e8:\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\uff0c\u5168\u9762\u800c\u8be6\u7ec6\u5730\u9610\u8ff0\u4e86\u673a\u5668\u5b66\u4e60\u4e2d\u7684\u5206\u7c7b\u7b97\u6cd5\u57fa\u7840\u77e5\u8bc6\u3002\u9996\u5148\u4ecb\u7ecd\u4e86\u4eba\u5de5\u667a\u80fd\u3001\u673a\u5668\u5b66\u4e60\u548c\u6df1\u5ea6\u5b66\u4e60\u7684\u57fa\u672c\u6982\u5ff5\uff0c\u8bb2\u89e3\u4e86\u673a\u5668\u5b66\u4e60\u5404\u79cd\u5206\u7c7b\u65b9\u6cd5\u7684\u7406\u8bba\u80cc\u666f\u3002\u968f\u540e\u901a\u8fc7\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528 Python \u5de5\u5177\uff08\u5305\u62ec pandas\u3001sklearn\u3001matplotlib \u548c seaborn\uff09\u8fdb\u884c\u6570\u636e\u5904\u7406\u3001\u5206\u6790\u548c\u53ef\u89c6\u5316\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u8ff0\u4e86\u51b3\u7b56\u6811\u3001\u903b\u8f91\u56de\u5f52\u3001\u652f\u6301\u5411\u91cf\u673a\u3001K\u8fd1\u90bb\u7b49\u7ecf\u5178\u7684\u5206\u7c7b\u7b97\u6cd5\uff0c\u5e76\u7528\u56fe\u5f62\u5316\u7684\u65b9\u5f0f\u5c55\u793a\u4e86\u5206\u7c7b\u6548\u679c\u3002\u6700\u540e\uff0c\u8bfb\u8005\u53ef\u4ee5\u901a\u8fc7\u672c\u6587\u6240\u63d0\u4f9b\u7684\u4e30\u5bcc\u5b66\u4e60\u8d44\u6599\u6765\u6df1\u5316\u5bf9\u673a\u5668\u5b66\u4e60\u5206\u7c7b\u4efb\u52a1\u7684\u7406\u89e3\u548c\u5e94\u7528\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fkRG7n4tOQKwU85xiEx0Eg"},"\u300a\u4e07\u5b57\u8be6\u89e3LLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u5199\u5728\u8de8\u5e74\u4e4b\u524d\uff1a\u804a\u804aLLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765"\uff0c\u4e3b\u8981\u6d89\u53ca\u5230LLM Agents\u7684\u5f53\u524d\u72b6\u6001\uff0c\u9762\u4e34\u7684\u95ee\u9898\u548c\u672a\u6765\u7684\u53ef\u80fd\u53d1\u5c55\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5305\u62ec\u5168\u53c2\u5fae\u8c03\u3001Prompt Tuning\u3001LoRA\u3001P-Tuning\u7b49\u5728\u5185\u7684SFT(Selective Fine Tuning)\u8303\u7574\u7684\u5404\u79cd\u6280\u672f\u3002\u5176\u4e2d\u5c24\u5176\u5f3a\u8c03\u4e86\u5bf9\u4e8e{prompt\uff0cresponse}\u7684\u5355\u8f6e\u95ee\u7b54\u5bf9\u7684\u5fae\u8c03\u662f\u6700\u7b80\u5355\u7684SFT\u5b9e\u73b0\u65b9\u5f0f\u3002\u5177\u4f53\u7684\u5185\u5bb9\u7ec6\u8282\u5927\u6982\u9700\u8981\u9605\u8bfb\u539f\u6587\u624d\u80fd\u83b7\u5f97\u66f4\u6df1\u5165\u7684\u7406\u89e3\u3002'),(0,a.kt)("h2",{id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173"},"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/generic-slice-functions"},"\u300aRobust generic functions on slices\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Robust generic functions on slices"\uff0c\u4e3b\u8981\u63a2\u8ba8\u4e86Go\u7684slices\u5305\u5982\u4f55\u63d0\u4f9b\u5bf9\u5207\u7247\u8fdb\u884c\u64cd\u4f5c\u7684\u901a\u7528\u51fd\u6570\u3002\u8be5\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u7c7b\u578b\u53c2\u6570\uff0c\u4e00\u6b21\u6027\u4e3a\u6240\u6709\u7c7b\u578b\u7684\u5207\u7247\u7f16\u5199\u7c7b\u4f3cslices.Index\u7b49\u51fd\u6570\uff0c\u800c\u65e0\u9700\u9488\u5bf9\u6bcf\u79cd\u4e0d\u540c\u7684\u5143\u7d20\u7c7b\u578b\u91cd\u65b0\u5b9e\u73b0\u3002\u968f\u540e\uff0c\u6587\u7ae0\u6df1\u5165\u8bb2\u8ff0\u4e86\u65b0\u7684\u51fd\u6570\uff08\u5982Insert, Replace\uff0cDelete\u7b49\uff09\u5982\u4f55\u4fee\u6539\u5207\u7247\uff0c\u5e76\u901a\u8fc7\u8be6\u8ff0\u5207\u7247\u5728\u5185\u5b58\u4e2d\u7684\u8868\u73b0\u5f62\u5f0f\u53ca\u5176\u5bf9\u5783\u573e\u56de\u6536\u5668\u7684\u5f71\u54cd\uff0c\u6765\u5e2e\u52a9\u8bfb\u8005\u7406\u89e3\u8fd9\u4e9b\u51fd\u6570\u7684\u5de5\u4f5c\u65b9\u5f0f\u548c\u6b63\u786e\u4f7f\u7528\u5b83\u4eec\u3002\u6587\u7ae0\u7279\u522b\u6307\u51fa\uff0c\u65b0\u7684Delete\u51fd\u6570\u63d0\u4f9b\u4e86\u66f4\u6e05\u6670\u5730\u8868\u8fbe\u7a0b\u5e8f\u5458\u610f\u56fe\u7684\u65b9\u5f0f\uff0c\u800c\u4e14\u5b83\u4e0d\u9700\u8981\u5206\u914d\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u6e05\u9664\u65e0\u7528\u7684\u5143\u7d20\uff0c\u5e2e\u52a9\u5783\u573e\u56de\u6536\u3002\u6587\u7ae0\u5f3a\u8c03\uff0c\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c\u5fc5\u987b\u8ba4\u4e3a\u539f\u59cb\u5207\u7247\u5df2\u65e0\u6548\uff0c\u56e0\u4e3a\u5e95\u5c42\u6570\u7ec4\u5df2\u88ab\u4fee\u6539\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u5728\u5904\u7406\u5185\u5b58\u6cc4\u6f0f\u548c\u5143\u7d20\u96f6\u503c\u8bbe\u7f6e\u7b49\u95ee\u9898\u65f6\u7684\u7b56\u7565\u548c\u9009\u9879\uff0c\u5b83\u4eec\u5728\u65b0\u7248\u672cGo\u7ed9\u51fa\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u6539\u53d8\u53ef\u80fd\u5bfc\u81f4\u7684\u4e00\u4e9b\u6d4b\u8bd5\u95ee\u9898\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9f13\u52b1\u5f00\u53d1\u4eba\u5458\u6b63\u786e\u4f7f\u7528\u65b0\u529f\u80fd\uff0c\u5e76\u5c3d\u91cf\u907f\u514d\u4e0a\u8ff0\u5217\u4e3e\u7684\u9677\u9631\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/routing-enhancements"},"\u300aRouting Enhancements for Go 1.22\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Routing Enhancements for Go 1.22"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86 Go 1.22 \u7248\u672c\u4e2d net/http \u5305\u7684\u8def\u7531\u5668\u63d0\u4f9b\u7684\u65b0\u7279\u6027\uff1a\u65b9\u6cd5\u5339\u914d\u548c\u901a\u914d\u7b26\u3002\u8fd9\u4e9b\u65b0\u7279\u6027\u8ba9\u4f60\u53ef\u4ee5\u4f7f\u7528\u6a21\u5f0f\uff0c\u800c\u975e Go \u4ee3\u7801\uff0c\u6765\u8868\u8fbe\u5e38\u89c1\u7684\u8def\u7531\u3002\u8fd9\u79cd\u65b0\u529f\u80fd\uff0c\u5c3d\u7ba1\u7b80\u5355\u6613\u61c2\uff0c\u4f46\u8981\u9009\u62e9\u51fa\u591a\u4e2a\u5339\u914d\u8bf7\u6c42\u7684\u6700\u4f73\u6a21\u5f0f\u5374\u662f\u4e00\u9879\u6311\u6218\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u9610\u91ca\u4e86\u5982\u4f55\u5728\u65b0\u7248 Go \u4e2d\u4f7f\u7528\u8fd9\u4e9b\u65b0\u7279\u6027\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u5f15\u5165\u7684\u53d8\u5316\u5982\u4f55\u5f71\u54cd\u4e86 ServeMux \u65b9\u6cd5 handle \u548c handleFunc \u3002\u6b64\u5916\uff0c\u8fd8\u63cf\u8ff0\u4e86\u65b0\u6a21\u5f0f\u5982\u4f55\u66f4\u5177\u4f18\u5148\u7ea7\uff0c\u5e76\u89e3\u91ca\u4e86\u5176\u80cc\u540e\u7684\u539f\u7406\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u65b0\u65e7\u7248\u672c\u7684\u517c\u5bb9\u6027\uff0c\u4f5c\u8005\u4eec\u4e5f\u52aa\u529b\u4f7f\u65b0\u7684\u6a21\u5f0f\u8bed\u6cd5\u80fd\u8986\u76d6\u65e7\u7684\uff0c\u5e76\u4f7f\u65b0\u7684\u4f18\u5148\u7ea7\u89c4\u5219\u80fd\u6cdb\u5316\u65e7\u7684\u89c4\u5219\u3002\u603b\u4f53\u4e0a\uff0c\u8fd9\u4e9b\u6539\u53d8\u662f Go \u8bed\u8a00\u56e2\u961f\u4e0d\u65ad\u52aa\u529b\u4f7f Go \u6210\u4e3a\u6784\u5efa\u751f\u4ea7\u7cfb\u7edf\u7684\u4f18\u79c0\u8bed\u8a00\u7684\u4e00\u4e2a\u6301\u7eed\u8fc7\u7a0b\u7684\u4e00\u90e8\u5206\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IH1FGDpClrsnlfjg7OF3lg"},"\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(6)")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/JCU3dwkwpMP3qMKqg9ed6g"},"\u4f7f\u7528Apache Kafka\u7684Golang\u5b9e\u8df5\u6307\u5357")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/RFsHfFByarSRAA-f1Rs13g"},"\u300aGo \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570\u300b"),'\u3002\u8fd9\u7bc7\u7531\u714e\u9c7c\u64b0\u5199\u7684\u6587\u7ae0\uff0c\u9898\u4e3a "Go \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570?"\uff0c\u5bf9\u4e8e\u8fd9\u4e2a\u8bdd\u9898\u8fdb\u884c\u4e86\u6df1\u5ea6\u89e3\u6790\u3002\u5176\u9996\u5148\u63d0\u5230\uff0c\u867d\u7136Go\u7684\u89c4\u8303\u5e76\u6ca1\u6709\u660e\u786e\u7981\u6b62\u4ecemain\u5305\u4e2d\u5bfc\u5165\u51fd\u6570\uff0c\u4f46\u6211\u4eec\u5728\u5b9e\u9645\u8fd0\u884c\u4e2d\u4f1a\u88ab\u62d2\u7edd\uff0c\u63d0\u793amain\u5305\u662f\u4e00\u4e2a\u7a0b\u5e8f\u800c\u975e\u53ef\u4ee5\u5bfc\u5165\u7684\u5305\u3002\u8fd9\u4e00\u73b0\u8c61\u7684\u539f\u56e0\u6765\u81ea\u4e8e\u7ecf\u8fc7\u591a\u6b21\u53d8\u52a8\u7684\u89c4\u5b9a\uff0c\u59822011\u5e74\u79fb\u9664\u4e86 "\u7a0b\u5e8f\u4e2d\u7684\u5176\u4ed6\u5305\u90fd\u4e0d\u80fd\u547d\u540d\u4e3a main" \u7684\u8981\u6c42\uff0c\u7136\u540e\u57282015\u5e74\u53c8\u65b0\u589e\u4e86\u9650\u5236\u3002\u8fd9\u6837\u7684\u53d8\u5316\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u589e\u52a0\u590d\u6742\u5ea6\u548c\u4e0d\u5b89\u5168\u6027\u3002\u6bd4\u5982\uff0c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u505a\u51fa\u81ea\u5df1\u62e5\u6709\u5b8c\u5168\u63a7\u5236\u6743\u7684\u5047\u8bbe\uff0c\u6240\u4ee5\u5982\u679c\u5f15\u5165\u591a\u4e2amain\u5305\u4e2d\u7684\u51fd\u6570\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u5728\u521d\u59cb\u5316\u987a\u5e8f\u3001\u5168\u5c40\u53d8\u91cf\u7684\u6ce8\u518c\u7b49\u65b9\u9762\u7684\u51b2\u7a81\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba4\u4e3aGo\u5b98\u65b9\u7684\u505a\u6cd5\u5728\u7406\u8bba\u4e0a\u53ef\u4ee5\u89e3\u51b3\u590d\u6742\u5ea6\u548c\u5b89\u5168\u6027\u95ee\u9898\uff0c\u4f46\u5bf9\u4e8e\u6709\u5386\u53f2\u503a\u52a1\u7684\u9879\u76ee\uff0c\u5bf9\u4e8e\u9700\u8981\u7ef4\u62a4\u591a\u4e2aGo\u9879\u76ee\u5de5\u7a0b\uff0c\u76f8\u5f53\u4e8e\u78e8\u706d\u4e86\u4e00\u6761\u9053\u8def\uff0c\u5176\u5b9e\u6bd4\u8f83\u5c34\u5c2c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/zxLO4IhLqQmIaUDzwwjU1w"},"\u300afasthttp\u662f\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8bb2\u89e3\u4e86fasthttp\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u539f\u7406\u3002fasthttp\u76f8\u6bd4\u4e8enet/http\u5728\u5904\u7406\u6d41\u7a0b\u4e0a\u6709\u6240\u5dee\u5f02\uff0cnet/http\u662f\u4e00\u4e2a\u8fde\u63a5\u65b0\u5efa\u4e00\u4e2agoroutine\uff0c\u5f53\u8fde\u63a5\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\u4f1a\u7ed9\u7cfb\u7edf\u5e26\u6765\u4e00\u5b9a\u7684\u538b\u529b\u3002\u800cfasthttp\u5219\u662f\u5efa\u7acb\u4e86workerPool\uff0c\u6bcf\u4e2aworkerChan\u5728\u540e\u53f0\u90fd\u4f1a\u6709\u4e00\u4e2aGoroutine\u6765\u5904\u7406\u5176\u4e2d\u7684\u8fde\u63a5\u3002\u6b64\u5916\uff0cfasthttp\u7684\u5feb\u901f\u4e5f\u5f97\u76ca\u4e8e\u51e0\u4e2a\u65b9\u9762\u7684\u4f18\u5316\uff1a\u8fde\u63a5\u590d\u7528\uff0c\u5927\u91cf\u4f7f\u7528\u4e86sync.Pool\u8fdb\u884c\u5185\u5b58\u590d\u7528\u4ee5\u53ca\u901a\u8fc7unsafe.Pointer\u6307\u9488\u8fdb\u884c","[","]","byte\u548cstring\u8f6c\u6362\u6765\u907f\u514d\u5185\u5b58\u5206\u914d\u548c\u62f7\u8d1d\u7684\u6d88\u8017\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fx-FTVpM3CXIPUwTC_juDQ"},"\u300a\u4e07\u5b57\u957f\u6587\u8bb2\u89e3Golang pprof \u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86Golang\u7684pprof\u5de5\u5177\u7684\u4f7f\u7528\u3002pprof\u5de5\u5177\u662fGolang\u4e2d\u7528\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4e00\u4e2a\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u5206\u6790\u51facpu\u4f7f\u7528\u60c5\u51b5\u3001\u5185\u5b58\u5360\u7528\u3001\u963b\u585e\u60c5\u51b5\u3001\u7ebf\u7a0b\u548c\u534f\u7a0b\u7b49\u4fe1\u606f\u3002\u6587\u7ae0\u4e2d\u8be6\u7ec6\u9610\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528\u6b64\u5de5\u5177\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u901a\u8fc7http\u63a5\u53e3\u7684\u65b9\u5f0f\u66b4\u9732\u51fapprof\u7684\u91c7\u96c6\u63a7\u5236\u754c\u9762\uff0c\u53e6\u4e00\u79cd\u662f\u5728\u7a0b\u5e8f\u4e2d\u901a\u8fc7\u4ee3\u7801\u6765\u542f\u52a8\u76f8\u5e94\u6307\u6807\u7684\u91c7\u96c6\u793a\u4f8b\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u89e3\u6790\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u5f0f\u83b7\u53d6\u7684\u8f93\u51fa\u4fe1\u606f\u3002\u672c\u6587\u7684\u4e3b\u8981\u76ee\u7684\u662f\u5c06pprof\u5de5\u5177\u7684\u4f7f\u7528\u65b9\u5f0f\u7528\u601d\u7ef4\u5bfc\u56fe\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765\uff0c\u8fd9\u6837\u53ef\u4ee5\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u4f7f\u7528pprof\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/xYvMI0JieO6RxHIdWf1ujQ"},"\u300a\u4e00\u7bc7\u5b9e\u7528\u7684\u5173\u4e8e\u4e91\u4e0aK8s\u5e94\u7528\u5206\u8d26\u5b9e\u8df5\u300b"),"\u3002\u672c\u6587\u8bb2\u8ff0\u4e91\u4e0aKubernetes\uff08K8s\uff09\u5e94\u7528\u7684\u6210\u672c\u5206\u644a\u5b9e\u8df5\uff0c\u6db5\u76d6\u4e86\u6210\u672c\u5206\u644a\u7684\u6838\u5fc3\u6982\u5ff5\u53ca\u963f\u91cc\u4e91ACK FinOps\u5957\u4ef6\u7684\u5e94\u7528\u3002\u6587\u4e2d\u9996\u5148\u4ee5\u524d\u671f\u9884\u7b97\u4e3a\u96c6\u7fa4\u89c4\u5212\u7684\u4f9d\u636e\uff0c\u5e76\u8ba8\u8bba\u4e86\u968f\u7740\u4e1a\u52a1\u53d1\u5c55\u5bf9\u6210\u672c\u5206\u644a\u7cbe\u51c6\u5ea6\u7684\u63d0\u5347\u9700\u6c42\u3002\u4ecb\u7ecd\u4e86\u5982\u4f55\u6839\u636ePod\u7684\u6838/\u65f6\u6210\u672c\uff0c\u901a\u8fc7ACK\u96c6\u7fa4\u3001\u8ba1\u7b97\u8282\u70b9\u3001\u547d\u540d\u7a7a\u95f4\u548c\u5e94\u7528Pod\u8fd9\u56db\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u8d39\u7528\u5206\u644a\u3002\u6587\u7ae0\u8fd8\u5206\u6790\u4e86\u5355\u8d44\u6e90\u548c\u6df7\u5408\u8d44\u6e90\u5206\u644a\u6a21\u578b\uff0c\u5e76\u8ba8\u8bba\u4e86\u5982\u4f55\u8bbe\u7f6eRequest\u548cLimit\u6765\u4f18\u5316\u8d44\u6e90\u5229\u7528\u3002\u5bf9\u4e8e\u591a\u4e91\u548c\u6df7\u5408\u4e91\u573a\u666f\uff0c\u5206\u4eab\u4e86\u5982\u4f55\u901a\u8fc7ACK One\u5b9e\u73b0\u7edf\u4e00\u7ba1\u7406\u548c\u6210\u672c\u5206\u6790\u3002\u9488\u5bf9\u590d\u6742\u4e1a\u52a1\u573a\u666f\uff0c\u8bb2\u8ff0\u4e86\u81ea\u5b9a\u4e49\u5b9a\u4ef7\u6a21\u7248\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u5141\u8bb8\u901a\u8fc7\u914d\u7f6e\u5b9e\u73b0\u6210\u672c\u5b9a\u5236\u9700\u6c42\u3002\u5bf9\u4e8e\u8ffd\u6c42\u7ec6\u8282\u7ba1\u7406\u548c\u7cbe\u7ec6\u5316\u8fd0\u8425\u7684\u56e2\u961f\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u6307\u5bfc\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/6xx3-qow8A5Hdp_72jswow"},'\u300a\u5982\u4f55\u4f7f\u7528 K8s \u4e24\u5927\u5229\u5668"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u5e2e\u4f60\u6446\u8131\u8fd0\u7ef4\u56f0\u5883\u300b'),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528 Kubernetes\uff08K8s\uff09\u7684"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u529f\u80fd\u6765\u5e2e\u52a9\u8fdb\u884c\u65e5\u5e38\u96c6\u7fa4\u8fd0\u7ef4\u5de5\u4f5c\u3002\u6587\u7ae0\u9996\u5148\u6307\u51fa\u4e86\u8fd0\u7ef4\u5de5\u4f5c\u4e2d\u53ef\u80fd\u51fa\u73b0\u7684\u4e00\u4e9b\u95ee\u9898\uff0c\u4f8b\u5982\u5e94\u7528\u88ab\u5220\u9664\u3001Apiserver\u8d1f\u8f7d\u7a81\u53d8\u3001\u96c6\u7fa4\u8282\u70b9\u51fa\u73b0\u95ee\u9898\u3001\u8282\u70b9\u81ea\u52a8\u6269\u5bb9\u7b49\u3002\u968f\u540e\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u89e3\u91ca\u4e86 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\u662f\u5982\u4f55\u8fd0\u4f5c\u7684\uff0c\u5f3a\u8c03\u4e86\u5584\u7528\u8fd9\u4e24\u79cd\u5de5\u5177\u53ef\u4ee5\u63d0\u9ad8\u96c6\u7fa4\u7684\u53ef\u89c2\u5bdf\u6027\uff0c\u4e3a\u8fd0\u7ef4\u5de5\u4f5c\u5e26\u6765\u6781\u5927\u7684\u4fbf\u5229\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u901a\u8fc7\u4f7f\u7528 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u66f4\u597d\u5730\u7ba1\u7406\u548c\u76d1\u6d4b\u96c6\u7fa4\u7684\u72b6\u6001\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lxEAFe2Ewmc8YvTqn8UcLQ"},"\u3010Go \u5de5\u5177\u3011\u7ade\u6001\u6761\u4ef6\u68c0\u6d4b\u795e\u5668 Race Detector")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Y67J4_D1yyMa-eb7XmgTcA"},"\u4f7f\u7528Redis\u5165\u95e8Golang")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/qDFM-nVo-jeh9VdcBfMreA"},"\u4e00\u9053\u9762\u8bd5\u9898: Top K \u95ee\u9898")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/sTd3SVh0swGTnaGugsw1SA"},"\u300a\u7406\u89e3 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u89e3\u6790\u4e86 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u3002\u9996\u5148\uff0c\u4f5c\u8005\u6982\u8ff0\u4e86\u7528\u6237\u540d\u3001\u7ec4\u540d\u3001\u7528\u6237ID\uff08UID\uff09\u548c\u7ec4ID\uff08GID\uff09\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e0e\u4e3b\u673a\u7cfb\u7edf\u4e4b\u95f4\u7684\u6620\u5c04\u5bf9\u4e8e\u6784\u5efa\u5b89\u5168\u7cfb\u7edf\u7684\u91cd\u8981\u6027\u3002\u968f\u540e\uff0c\u6587\u7ae0\u5206\u6790\u4e86uid/gid\u5728Linux\u7cfb\u7edf\u7684\u5b89\u5168\u6027\uff0c\u5f3a\u8c03\u4e86\u5355\u4e00\u5185\u6838\u6982\u5ff5\u4ee5\u53cauid/gid\u7684\u5206\u914d\u65b9\u5f0f\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u8fd0\u7528\u5b9e\u4f8b\u89e3\u91ca\u4e86Docker\u8fd0\u884c\u7684\u8fc7\u7a0b\u4ee5\u53ca\u5982\u4f55\u901a\u8fc7Dockerfile\u5b9a\u4e49\u548c\u542f\u52a8\u4e0d\u540c\u7528\u6237\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8bb2\u8ff0\u4e86\u5982\u4f55\u638c\u63a7\u548c\u63a7\u5236\u5bb9\u5668\u7684\u8bbf\u95ee\u6743\u9650\u3002\u5728\u9610\u8ff0\u4ee5\u4e0a\u5185\u5bb9\u7684\u540c\u65f6\uff0c\u6587\u7ae0\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u9645\u793a\u4f8b\u6765\u8bf4\u660e\u8fd9\u4e9b\u89c2\u70b9\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yUuo1IjeXY78_5u4QpkuTA"},"\u300a\u5982\u4f55\u57fa\u4e8eDocker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u5c06Docker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u3002\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5229\u7528\u5f00\u6e90\u5de5\u5177Dedockify\u7684\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u5de5\u4f5c\u539f\u7406\u3002\u8be5\u5de5\u5177\u901a\u8fc7Python\u811a\u672c\uff0c\u5229\u7528\u5b58\u50a8\u5728\u6bcf\u4e2a\u955c\u50cf\u5c42\u65c1\u8fb9\u7684\u5143\u6570\u636e\uff0c\u9010\u6b65\u904d\u5386\u5c42\u7ea7\u6811\uff0c\u6536\u96c6\u4e0e\u6bcf\u4e2a\u5c42\u76f8\u5173\u8054\u7684\u547d\u4ee4\uff0c\u91cd\u5efa\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\u547d\u4ee4\u5e8f\u5217\uff0c\u4ece\u800c\u5f97\u5230\u8fd1\u4f3c\u7684Dockerfile\u3002\u4e0d\u8fc7\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bbf\u95ee\u6267\u884c\u539f\u59cbdocker build\u547d\u4ee4\u65f6\u5b58\u5728\u7684\u6784\u5efa\u4e0a\u4e0b\u6587\uff0c\u5982\u679c\u4f7f\u7528\u4e86COPY\u6216ADD\u6307\u4ee4\uff0c\u751f\u6210\u7684\u8f93\u51fa\u53ef\u80fd\u4e0d\u5b8c\u5168\u5339\u914d\u539f\u59cb\u7684Dockerfile\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KkRWQyljuo86-XbBxEnGPA"},"\u300a\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u3002\u9996\u5148\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a\u901a\u7528\u7684Dockerfile\uff0c\u5e76\u6307\u51fa\u5176\u751f\u6210\u7684\u955c\u50cf\u5927\u5c0f\u8d85\u8fc7300MB\uff0c\u4e3b\u8981\u56e0\u4e3a\u5305\u542b\u4e86\u6240\u6709\u7684Golang\u5de5\u5177\u3002\u7136\u540e\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u591a\u9636\u6bb5\u6784\u5efa\u7684\u65b9\u6cd5\uff0c\u5b83\u80fd\u4ece\u4e0d\u540c\u7684\u57fa\u7840\u955c\u50cf\u6784\u5efa\uff0c\u6709\u9009\u62e9\u5730\u5c06\u6587\u4ef6\u4ece\u4e00\u4e2a\u9636\u6bb5\u4f20\u9012\u5230\u4e0b\u4e00\u4e2a\u9636\u6bb5\uff0c\u4ece\u800c\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u901a\u8fc7\u4e8c\u7ea7\u6784\u5efa\uff0c\u955c\u50cf\u5927\u5c0f\u5df2\u964d\u81f311.7MB\u3002\u6700\u540e\uff0c\u8fd8\u63a2\u8ba8\u4e86\u4f7f\u7528\u540d\u4e3ascratch\u7684\u7a7a\u767d\u955c\u50cf\u8fdb\u4e00\u6b65\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u7684\u53ef\u80fd\u6027\uff0c\u4f7f\u5f97\u955c\u50cf\u6700\u540e\u964d\u81f36.34MB\uff0c\u4f46\u4f5c\u8005\u5f3a\u8c03\u8fd9\u9700\u8981\u614e\u91cd\u8003\u8651\uff0c\u56e0\u4e3a\u6700\u540e\u751f\u6210\u7684\u955c\u50cf\u5c06\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dckA1ezcABndN5WSg1BOBA"},"\u300ak8s \u5230\u5e95\u662f\u4ec0\u4e48\uff0c\u67b6\u6784\u662f\u600e\u4e48\u6837\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86 Kubernetes\uff08K8s\uff09\u7684\u57fa\u672c\u6982\u5ff5\u3001\u67b6\u6784\u548c\u5de5\u4f5c\u539f\u7406\u3002Kubernetes\uff0c\u56e0\u5355\u8bcd\u8fc7\u957f\uff0c\u6211\u4eec\u901a\u5e38\u7b80\u5316\u4e3ak8s\u3002k8s \u662f\u4e00\u79cd\u5bb9\u5668\u7684\u534f\u8c03\u5de5\u5177\uff0c\u4f4d\u4e8e\u5e94\u7528\u670d\u52a1\u548c\u670d\u52a1\u5668\u4e4b\u95f4\uff0c\u80fd\u4ee5\u7b56\u7565\u7684\u65b9\u5f0f\u534f\u8c03\u548c\u7ba1\u7406\u591a\u4e2a\u5e94\u7528\u670d\u52a1\u3002\u901a\u8fc7\u4e00\u4e2a yaml \u6587\u4ef6\u7684\u914d\u7f6e\uff0c\u53ef\u4ee5\u5b9a\u4e49\u5e94\u7528\u7684\u90e8\u7f72\u987a\u5e8f\u7b49\u4fe1\u606f\uff0c\u81ea\u52a8\u90e8\u7f72\u5e94\u7528\u5230\u5404\u4e2a\u670d\u52a1\u5668\u4e0a\uff0c\u8fd8\u80fd\u8ba9\u5b83\u4eec\u5d29\u6e83\u540e\u81ea\u52a8\u91cd\u542f\uff0c\u53ef\u4ee5\u81ea\u52a8\u6269\u5bb9\u548c\u7f29\u5bb9\u3002Kubernetes \u7684\u670d\u52a1\u5668\u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u63a7\u5236\u5e73\u9762\u548c\u5de5\u4f5c\u8282\u70b9\uff0c\u524d\u8005\u8d1f\u8d23\u63a7\u5236\u548c\u7ba1\u7406\u5404\u4e2a\u8282\u70b9\uff0c\u540e\u8005\u5219\u8d1f\u8d23\u5b9e\u9645\u8fd0\u884c\u5404\u4e2a\u5e94\u7528\u670d\u52a1\u3002k8s \u7684\u547d\u4ee4\u884c\u5de5\u5177\u4e3a kubectl\uff0c\u7528\u4e8e\u6267\u884c\u5404\u7c7b\u64cd\u4f5c\u547d\u4ee4\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/vjmntyGwzURz_elg27vpXg"},"\u300aGo \u6cdb\u578b\u6709\u6ca1\u6709\u53ef\u80fd\u5728\u540e\u671f\u6539\u4e3a ",(0,a.kt)("inlineCode",{parentName:"a"},"<>")," \u5c16\u62ec\u53f7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728\u5904\u7406\u6cdb\u578b\u65f6\uff0c\u4e3a\u4f55\u5e76\u6ca1\u6709\u91c7\u7528\u7c7b\u4f3cJava\u548cC++\u7684 ",(0,a.kt)("inlineCode",{parentName:"p"},"<>")," \u5c16\u62ec\u53f7\u8868\u793a\u6cd5\uff0c\u800c\u662f\u9009\u62e9\u4e86\u4e2d\u62ec\u53f7 ",(0,a.kt)("inlineCode",{parentName:"p"},"[]"),". \u9996\u5148\uff0c\u4f7f\u7528\u5c16\u62ec\u53f7\u53ef\u80fd\u5bfc\u81f4\u8bed\u4e49\u6df7\u6dc6\uff0c\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"a, b := w < x, y > (z)")," \u6b64\u53e5\uff0c\u5982\u679c\u4f7f\u7528\u5c16\u62ec\u53f7\uff0c\u7a0b\u5e8f\u53ef\u80fd\u5728\u7f16\u8bd1\u9636\u6bb5\u65e0\u6cd5\u786e\u5b9a\u8be5\u884c\u8868\u8fbe\u5f0f\u7684\u5177\u4f53\u542b\u4e49\u3002\u5176\u6b21\uff0c\u4f7f\u7528\u5706\u62ec\u53f7\u4e5f\u4f1a\u5bfc\u81f4\u540c\u6837\u7684\u95ee\u9898\uff0c\u6bd4\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"func F(T any)(v T)(r1, r2 T)"),", \u65e0\u6cd5\u5feb\u901f\u51c6\u786e\u5224\u65ad\u51fa\u53c2\u6570\u548c\u8fd4\u56de\u503c\u90e8\u5206\u3002\u6b64\u5916\uff0cGo\u5b98\u65b9\u4e5f\u4e0d\u5e0c\u671b\u4f7f\u7528\u975eASCII\u7684\u5b57\u7b26\u3002\u4f5c\u8005\u8fd8\u63d0\u5230\u793e\u533a\u4e2d\u5bf9Go\u7684\u5904\u7406\u65b9\u5f0f\u5b58\u5728\u4e00\u4e9b\u4e89\u8bae\uff0c\u90e8\u5206\u793e\u533a\u6210\u5458\u8ba4\u4e3a\u5982\u679c\u4f7f\u5f97\u7f16\u8bd1\u5668\u89e3\u91ca\u5c16\u62ec\u53f7\u4e0d\u518d\u56f0\u96be\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u8fd9\u79cd\u7b26\u53f7\u3002\u7136\u800c\uff0c\u603b\u7684\u6765\u8bf4\uff0c\u57fa\u4e8e\u5df2\u6709\u7684\u5b9e\u8df5\u548c\u89c4\u8303\uff0cGo\u8bed\u8a00\u5728\u672a\u6765\u53ef\u80fd\u4e5f\u4e0d\u4f1a\u6539\u53d8\u5176\u6cdb\u578b\u7684\u8868\u793a\u65b9\u5f0f\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/arI9sip-5JH9YSu45XJ83w"},"\u300aRust\u4e2dchannel\u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86Rust\u7f16\u7a0b\u8bed\u8a00\u4e2dChannel\u7684\u7528\u6cd5\u3002\u5176\u4e2d\uff0cChannel\u662fRust\u4e2d\u7528\u4e8e\u5728\u4e0d\u540c\u7ebf\u7a0b\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u901a\u4fe1\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u7ebf\u7a0b\u95f4\u7684\u6d88\u606f\u4f20\u9012\u3002\u6bcf\u4e2aChannel\u7531\u53d1\u9001\u7aef\u548c\u63a5\u6536\u7aef\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5176\u8bbe\u8ba1\u7406\u5ff5\u662f\u201c\u901a\u8fc7\u901a\u4fe1\u6765\u5171\u4eab\u5185\u5b58\uff0c\u800c\u975e\u901a\u8fc7\u5171\u4eab\u5185\u5b58\u6765\u901a\u4fe1\u201d\uff0c\u4ee5\u6b64\u907f\u514d\u4e86\u6570\u636e\u7ade\u4e89\u548c\u5171\u4eab\u5185\u5b58\u7684\u590d\u6742\u6027\u3002\u8be5\u6587\u7ae0\u8fdb\u4e00\u6b65\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5728Rust\u4e2d\u521b\u5efa\u548c\u4f7f\u7528Channel\uff0c\u5e76\u7ed9\u51fa\u4e86\u76f8\u5173\u4ee3\u7801\u793a\u4f8b\u3002\u6700\u540e\uff0c\u6587\u7ae0\u9610\u8ff0\u4e86\u591a\u79cdChannel\u6a21\u578b\uff0c\u5305\u62ecRust\u6807\u51c6\u5e93\u4e2d\u6240\u4f7f\u7528\u7684MPSC\uff08\u591a\u751f\u4ea7\u8005\uff0c\u5355\u6d88\u8d39\u8005\uff09\u6a21\u578b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7272006755266002959"},"K8s\u90e8\u7f72\u65b9\u5f0f\u5927\u5168\uff1a\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1\u6240\u6709\u6280\u5de7")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7301584578342289423"},"k8s\u4ece\u5165\u95e8\u5230\u7cbe\u901a -- \u66f4\u9002\u5408\u4e2d\u56fd\u5b9d\u5b9d\u4f53\u8d28")),(0,a.kt)("h2",{id:"-\u540e\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NABg5tGizHsmdXgUO6NeVw"},"\u300a\u4e07\u5b57+33\u5f20\u56fe\u63a2\u79d8OpenFeign\u6838\u5fc3\u67b6\u6784\u539f\u7406\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u6df1\u5165\u63a2\u8ba8\u4e86SpringCloud\u6838\u5fc3\u7ec4\u4ef6OpenFeign\u7684\u6838\u5fc3\u67b6\u6784\u539f\u7406\u3002\u6587\u7ae0\u5206\u4e3a\u56db\u4e2a\u90e8\u5206\uff0c\u9996\u5148\u89e3\u91ca\u539f\u59cbFeign\u7684\u4f7f\u7528\u548c\u57fa\u4e8eSpringCloud\u7684\u8fdb\u5316\u8fc7\u5386\u7a0b\uff1b\u7136\u540e\u8be6\u7ec6\u8bb2\u89e3\u4e86Feign\u5e95\u5c42\u5de5\u4f5c\u539f\u7406\uff0c\u4f9d\u8d56\u4e8eJDK\u52a8\u6001\u4ee3\u7406\u548c\u6838\u5fc3\u7ec4\u4ef6\u5982Contract\u3001Encoder\u3001Decoder\u7b49\uff1b\u63a5\u4e0b\u6765\u5206\u6790\u4e86SpringCloud\u662f\u5982\u4f55\u6574\u5408Feign\u7684\uff0c\u5e76\u4e14\u8ba8\u8bba\u4e86OpenFeign\u7684\u591a\u79cd\u914d\u7f6e\u65b9\u5f0f\u53ca\u5176\u4f18\u5148\u7ea7\uff1b\u6700\u540e\uff0c\u6587\u7ae0\u901a\u8fc7\u4e30\u5bcc\u7684\u56fe\u793a\u548c\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u53ef\u4ee5\u66f4\u597d\u5730\u7406\u89e3\u5e76\u8fd0\u7528\u8fd9\u4e00\u5de5\u5177\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4e8e\u7406\u89e3\u548c\u8fd0\u7528OpenFeign\u975e\u5e38\u6709\u5e2e\u52a9\uff0c\u65e0\u8bba\u662f\u5bf9\u4e8e\u521d\u5b66\u8005\u8fd8\u662f\u6709\u7ecf\u9a8c\u7684\u5f00\u53d1\u8005\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1Qe29y3nrbi39Kpaspme7Q"},"\u300a\u4e09\u4e07\u5b57\u957f\u6587\uff1a\u5982\u4f55\u53bb\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4efd\u8be6\u5c3d\u7684\u6307\u5bfc\uff0c\u8bb2\u8ff0\u4e86\u5982\u4f55\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u3002\u6587\u4e2d\u9996\u5148\u5b9a\u4f4d\u4e86\u6280\u672f\u95ee\u9898\u7684\u8303\u56f4\uff0c\u786e\u5b9a\u9002\u7528\u4e8eJDK8\u81f3JDK11\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u7cfb\u7edf\u5316\u7684\u6392\u67e5\u539f\u5219\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u6b65\u6b65\u7684\u8bca\u65ad\u6d41\u7a0b\uff0c\u4ece\u57fa\u672c\u4fe1\u606f\u6536\u96c6\u3001\u5224\u65ad\u5185\u5b58\u589e\u957f\u539f\u56e0\uff0c\u5230\u5177\u4f53\u5206\u6790\u5185\u5b58\u95ee\u9898\u7684\u53ef\u80fd\u6765\u6e90\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u4e0d\u540c\u7684\u547d\u4ee4\u548c\u5de5\u5177\uff08\u5982jmap\u3001jstat\u3001Arthas\u7b49\uff09\u8fdb\u884c\u8be6\u7ec6\u7684\u5206\u6790\uff0c\u5e76\u6839\u636e\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff0c\u5411\u8bfb\u8005\u5c55\u793a\u4e86\u5982\u4f55\u786e\u5b9a\u662f\u5806\u5185\u5b58\u95ee\u9898\u8fd8\u662f\u5806\u5916\u5185\u5b58\u95ee\u9898\u3002\u603b\u4e4b\uff0c\u6587\u7ae0\u4e3a\u90a3\u4e9b\u9700\u8981\u6df1\u5165\u7406\u89e3\u548c\u5904\u7406JVM\u5185\u5b58\u95ee\u9898\u7684\u5f00\u53d1\u8005\u548c\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u77e5\u8bc6\u548c\u6280\u5de7\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WLPo8s_M3AzxwB3o3ehY3w"},"\u300a\u5982\u4f55\u907f\u514dMYSQL\u4e3b\u4ece\u5ef6\u8fdf\u5e26\u6765\u7684\u8bfb\u5199\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u5904\u7406\u5728MySQL\u4e3b\u4ece\u90e8\u7f72\u67b6\u6784\u4e2d\u666e\u904d\u5b58\u5728\u7684\u4e3b\u4ece\u540c\u6b65\u5ef6\u8fdf\u95ee\u9898\uff0c\u4ee5\u4fdd\u6301\u8bfb\u5199\u64cd\u4f5c\u7684\u4e00\u81f4\u6027\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u4e3b\u4ece\u5ef6\u8fdf\u4ea7\u751f\u7684\u573a\u666f\u53ca\u5176\u5bf9\u8bfb\u5199\u5206\u79bb\u539f\u5219\u7684\u5f71\u54cd\u3002\u7136\u540e\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e86\u4e3b\u4ece\u590d\u5236\u7684\u539f\u7406\uff0c\u5e76\u63d0\u51fa\u4e86\u4e24\u79cd\u907f\u514d\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u6280\u672f\u65b9\u6848\uff1a\u4e00\u662f\u4f7f\u7528select master_pos_wait\u51fd\u6570\u6765\u7b49\u5f85\u4ece\u5e93\u540c\u6b65\u81f3\u7279\u5b9a\u7684binlog\u4f4d\u7f6e\u70b9\uff1b\u4e8c\u662f\u5728\u5f00\u542fGTID\u6a21\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7select wait_for_executed_gtid_set\u51fd\u6570\u68c0\u67e5GTID\u96c6\u5408\u662f\u5426\u5df2\u540c\u6b65\u3002\u8fd9\u4e24\u79cd\u65b9\u6cd5\u5747\u65e8\u5728\u786e\u4fdd\u4ece\u5e93\u6570\u636e\u7684\u51c6\u786e\u6027\uff0c\u4ece\u800c\u6574\u4f53\u4e0a\u51cf\u8f7b\u4e3b\u5e93\u7684\u538b\u529b\u3002\u603b\u4f53\u4e0a\uff0c\u6587\u7ae0\u4e3aMySQL\u6570\u636e\u5e93\u7ba1\u7406\u5458\u63d0\u4f9b\u4e86\u7f13\u89e3\u4e3b\u4ece\u5ef6\u8fdf\u5bfc\u81f4\u7684\u8bfb\u5199\u95ee\u9898\u7684\u5177\u4f53\u5b9e\u65bd\u65b9\u6848\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dt_14etV_2ynAmyMa_uyug"},"\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014ES\u7bc7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u7bc7\u9488\u5bf9Elasticsearch(ES)\u7684\u9762\u8bd5\u6307\u5357\uff0c\u5b83\u6db5\u76d6ES\u57fa\u7840\u77e5\u8bc6\u70b9\u548c\u9762\u8bd5\u8fc7\u7a0b\u4e2d\u5e38\u89c1\u95ee\u9898\u3002\u5185\u5bb9\u5305\u62ecES\u7684\u529f\u80fd\u7279\u6027\u4ecb\u7ecd\uff08\u5982\u5206\u5e03\u5f0f\u67b6\u6784\u3001\u5168\u6587\u641c\u7d22\u3001\u6570\u636e\u5206\u6790\u7b49\uff09\u3001\u4e3b\u8981\u7684\u4f7f\u7528\u573a\u666f\u63cf\u8ff0\u3001\u4e0e\u5176\u4ed6\u641c\u7d22\u5f15\u64ce\u7684\u5bf9\u6bd4\uff08Lucene\u548cSolr\uff09\u3001\u4ee5\u53caES\u7684\u57fa\u672c\u6982\u5ff5\u89e3\u91ca\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u63a2\u8ba8\u4e86ES\u7684\u9ad8\u7ea7\u7279\u6027\uff0c\u5982\u6620\u5c04\u3001DSL\u67e5\u8be2\u3001\u805a\u5408\u5206\u6790\u548c\u667a\u80fd\u641c\u7d22\u5efa\u8bae\u5668\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u8fd8\u5206\u4eab\u4e86\u5173\u4e8e\u6570\u636e\u7d22\u5f15\u4f18\u5316\u7684\u5b9e\u6218\u6280\u5de7\u548c\u7b56\u7565\uff0c\u63d0\u4f9b\u4e86\u5199\u4f18\u5316\u3001\u8bfb\u4f18\u5316\u548c\u7d22\u5f15\u91cd\u5efa\u7684\u65b9\u6848\uff0c\u8fd9\u4e9b\u65b9\u6848\u5bf9ES\u6570\u636e\u5b58\u50a8\u548c\u67e5\u8be2\u7684\u6027\u80fd\u6709\u663e\u8457\u5f71\u54cd\uff0c\u6700\u540e\u8fd8\u5bf9Deep Paging\u6027\u80fd\u95ee\u9898\u63d0\u4f9b\u4e86\u89e3\u51b3\u65b9\u6cd5\u3002\u5bf9\u6b63\u5728\u51c6\u5907\u9762\u8bd5\u6216\u8005\u5e0c\u671b\u5de9\u56faES\u77e5\u8bc6\u7684\u8bfb\u8005\u800c\u8a00\uff0c\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4e2a\u5b9d\u8d35\u7684\u8d44\u6e90\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/gAJFm3q5510PfRBe4F11PQ"},"\u300a\u4ec0\u4e48\u662fMySQL\u9501\uff1f\u6709\u54ea\u4e9b\u9501\u7c7b\u578b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5730\u4ecb\u7ecd\u4e86MySQL\u4e2d\u7684\u9501\u5b9a\u673a\u5236\u53ca\u5176\u7c7b\u578b\u3002\u8d77\u521d\u6982\u8ff0\u4e86\u9501\u7684\u4f5c\u7528\uff0c\u5373\u534f\u8c03\u591a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u8d44\u6e90\u7684\u5e76\u53d1\u8bbf\u95ee\uff0c\u5728\u6570\u636e\u5e93\u73af\u5883\u4e0b\uff0c\u9501\u5bf9\u4e8e\u4fdd\u6301\u4e8b\u52a1\u7684\u6b63\u786e\u6027\u4e0e\u4e00\u81f4\u6027\u81f3\u5173\u91cd\u8981\u3002\u4f5c\u8005\u660e\u786e\u533a\u5206\u4e86MySQL\u4e2d\u9501\u7684\u7ea7\u522b\uff0c\u4ece\u5168\u5c40\u9501\u3001\u8868\u9501\uff08\u8bfb\u9501\u3001\u5199\u9501\uff09\u5230\u5143\u6570\u636e\u9501\u3001\u610f\u5411\u9501\uff0c\u76f4\u5230\u884c\u9501\u7684\u591a\u79cd\u5f62\u5f0f\uff08\u8bb0\u5f55\u9501\u3001\u95f4\u9699\u9501\u548c\u4e34\u952e\u9501\uff09\u3002\u6587\u4e2d\u8fd8\u63a2\u8ba8\u4e86AUTO-INC\u9501\u7684\u4f5c\u7528\u548c\u76f8\u5173\u4f18\u5316\uff0c\u4e3e\u4f8b\u8bf4\u660e\u4e86\u5176\u5728INSERT\u64cd\u4f5c\u4e2d\u7684\u5e94\u7528\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u4e5f\u6d89\u53ca\u4e86\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u60c5\u51b5\u4f18\u5316\u9501\u7684\u4f7f\u7528\u4ee5\u53ca\u5982\u4f55\u907f\u514d\u7531\u9501\u4ea7\u751f\u7684\u6027\u80fd\u74f6\u9888\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u7406\u89e3MySQL\u7684\u5404\u79cd\u9501\u7c7b\u578b\u548c\u9501\u673a\u5236\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u4fe1\u606f\uff0c\u7279\u522b\u5bf9\u4e8e\u6570\u636e\u5e93\u7ba1\u7406\u5458\u548c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5e76\u53d1\u6570\u636e\u8bbf\u95ee\u95ee\u9898\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u5b9e\u7528\u4ef7\u503c\u3002"),(0,a.kt)("h2",{id:"-\u524d\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/m-Ae6dbFuW22u2xSDWcciw"},"Vue \u56e2\u961f\u6b63\u5f0f\u5f00\u6e90 Rolldown\uff1a\u57fa\u4e8e Rust \u7684\u8d85\u5feb JavaScrip \u6253\u5305\u5de5\u5177\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/MVR5rV2LkH8_GHCtP6SHug"},"\u6253\u9020\u8212\u9002\u7684vscode\u5f00\u53d1\u73af\u5883")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/pY4-RqqamTmPXnRPfw0hRA"},"\u76f8\u6bd4\u4e8e Node.js\uff0cDeno \u548c Bun \u5230\u5e95\u80fd\u5e26\u6765\u4ec0\u4e48")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yBTK4Rds28aJ88mVgkoYJA"},"MDH Weekly 122 - \u300a\u62db\u4eba\u300b")))}u.isMDXComponent=!0},7662:(e,t,n)=>{n.d(t,{Z:()=>p});const p=n.p+"assets/images/maxresdefault-5b23cca3601cf7ebe54f3cb5023d859a.jpg"}}]); \ No newline at end of file diff --git a/assets/js/76cc166b.759427f0.js b/assets/js/76cc166b.759427f0.js deleted file mode 100644 index 62c18ce3c6..0000000000 --- a/assets/js/76cc166b.759427f0.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[7403],{49613:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var p=n(59496);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);t&&(p=p.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,p)}return n}function i(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(p=0;p=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=p.createContext({}),s=function(e){var t=p.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},m=function(e){var t=s(e.components);return p.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return p.createElement(p.Fragment,{},t)}},h=p.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),c=s(n),h=a,k=c["".concat(l,".").concat(h)]||c[h]||u[h]||r;return n?p.createElement(k,i(i({ref:t},m),{},{components:n})):p.createElement(k,i({ref:t},m))}));function k(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=h;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[c]="string"==typeof e?e:a,i[1]=o;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>u,frontMatter:()=>r,metadata:()=>o,toc:()=>s});var p=n(64778),a=(n(59496),n(49613));const r={slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},i=void 0,o={permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-10/index.md",source:"@site/blogs/2024/2024-03-10/index.md",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",description:"alt text",date:"2024-03-10T00:00:00.000Z",formattedDate:"March 10, 2024",tags:[],readingTime:34.7,hasTruncateMarker:!1,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},prevItem:{title:"\u7f6e\u9876\u5185\u5bb9",permalink:"/frontend-weekly/2024/welcome"},nextItem:{title:"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"}},l={authorsImageUrls:[void 0]},s=[{value:"\ud83c\udf1f AI \u76f8\u5173",id:"-ai-\u76f8\u5173",level:2},{value:"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173",id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173",id:"-\u540e\u7aef\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173",id:"-\u524d\u7aef\u76f8\u5173",level:2}],m={toc:s},c="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(c,(0,p.Z)({},m,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,(0,a.kt)("img",{alt:"alt text",src:n(7662).Z,width:"1280",height:"720"})),(0,a.kt)("p",null,"\u5c01\u9762\u56fe\uff1aUnderstanding the Go runtime - Jesus Espino"),(0,a.kt)("h2",{id:"-ai-\u76f8\u5173"},"\ud83c\udf1f AI \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://arxiv.org/abs/2401.11624"},"\u300aIn-context Learning with Retrieved Demonstrations for Language Models: A Survey\u300b"),'\u3002\u8fd9\u7bc7\u9898\u4e3a "In-context Learning with Retrieved Demonstrations for Language Models: A Survey" \u7684\u6587\u7ae0\uff0c\u4e3b\u8981\u8ba8\u8bba\u4e86\u8bed\u8a00\u6a21\u578b\uff0c\u5c24\u5176\u662f\u5927\u578b\u9884\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u5982\u4f55\u901a\u8fc7\u83b7\u53d6\u7684\u6f14\u793a\u8fdb\u884c\u5c11\u91cf\u60c5\u666f\u5b66\u4e60\u3002\u8fd9\u9879\u6280\u672f\u80fd\u6709\u6548\u5730\u6539\u8fdb\u5b66\u4e60\u8fc7\u7a0b\u7684\u6548\u7387\u548c\u53ef\u6269\u5c55\u6027\uff0c\u5e76\u964d\u4f4e\u624b\u52a8\u9009\u62e9\u6837\u4f8b\u65f6\u7684\u56fa\u6709\u504f\u89c1\u3002\u6587\u7ae0\u5bf9\u6b64\u9886\u57df\u8fdb\u884c\u4e86\u5e7f\u6cdb\u7684\u7814\u7a76\u56de\u987e\uff0c\u5bf9\u68c0\u7d22\u6a21\u578b\u3001\u68c0\u7d22\u8bad\u7ec3\u8fc7\u7a0b\u548c\u63a8\u7406\u7b97\u6cd5\u7684\u4e0d\u540c\u8bbe\u8ba1\u9009\u62e9\u8fdb\u884c\u4e86\u8ba8\u8bba\u548c\u6bd4\u8f83\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NUhEy0YLTjtzY3BGVXhfrw"},"\u300a\u78be\u538bLoRA\uff01Meta & CMU | \u63d0\u51fa\u9ad8\u6548\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\uff1aGaLore\uff0c\u5185\u5b58\u53ef\u51cf\u5c1163.3%\u300b"),"\u3002Meta\u548cCMU\u5408\u4f5c\u63d0\u51fa\u4e86\u4e00\u79cd\u65b0\u7684\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\u2014\u2014Gradient Low-Rank Projection\uff08GaLore\uff09\u3002GaLore\u901a\u8fc7\u68af\u5ea6\u7684\u4f4e\u79e9\u6295\u5f71\u4ee3\u66ff\u6743\u91cd\u7684\u4f4e\u79e9\u9002\u914d\uff0c\u4e0d\u4ec5\u652f\u6301\u5168\u53c2\u6570\u5b66\u4e60\uff0c\u800c\u4e14\u663e\u8457\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\uff0c\u51cf\u5c11\u4e8663.3%\u7684\u5185\u5b58\u9700\u6c42\u3002\u4e0d\u540c\u4e8eLoRA\u7684\u4f4e\u79e9\u6743\u91cd\u66f4\u65b0\uff0cGaLore\u5229\u7528\u6743\u91cd\u68af\u5ea6\u7684\u4f4e\u79e9\u7279\u6027\uff0c\u7ed3\u5408\u9010\u5c42\u6743\u91cd\u66f4\u65b0\u548c8\u4f4d\u4f18\u5316\u5668\uff0c\u6709\u6548\u5730\u4f18\u5316\u4e86\u5185\u5b58\u6548\u7387\u3002\u6b64\u5916\uff0cGaLore\u8fd8\u5f15\u5165\u4e86\u53ef\u8c03\u6574\u7684\u8d85\u53c2\u6570\uff0c\u63d0\u9ad8\u4e86\u5176\u9002\u5e94\u6027\u3002\u7ecf\u5b9e\u9a8c\u9a8c\u8bc1\uff0cGaLore\u7684\u8868\u73b0\u4f18\u4e8eLoRA\uff0c\u5c24\u5176\u662f\u5728\u9884\u8bad\u7ec3\u6a21\u578b\u5fae\u8c03\u4e0a\u8868\u73b0\u66f4\u4f73\uff0c\u4e3a\u5927\u6a21\u578b\u8bad\u7ec3\u63d0\u4f9b\u4e86\u65b0\u7684\u89e3\u51b3\u7b56\u7565\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7316592794109198387"},"\u4f7f\u7528 GPT4V+AI Agent \u505a\u81ea\u52a8 UI \u6d4b\u8bd5\u7684\u63a2\u7d22 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZSDCNDRu-tCkOlC9jz2j4w"},"Gemini\u4feebug\u795e\u4e86\uff01\u5f55\u7f51\u9875\u89c6\u9891\u628a\u4ee3\u7801\u5e93\u7529\u7ed9\u5b83\u5c31\u884c\uff0c\u7f51\u53cb\u5750\u4e0d\u4f4f\u4e86\uff1a\u60f3\u8981\u8bbf\u95ee\u6743\u9650")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GXwftkv-UpDQSjiTMn9TFA"},"\u4e00\u952e\u5f00\u542f GPU \u95f2\u7f6e\u6a21\u5f0f\uff0c\u57fa\u4e8e\u51fd\u6570\u8ba1\u7b97\u4f4e\u6210\u672c\u90e8\u7f72 Google Gemma \u6a21\u578b\u670d\u52a1")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/YDwL3dV-Fq5zcEyrL__NGw"},"\u300aYi\u6280\u672f\u62a5\u544a\u7ec6\u8282\u5206\u4eab\u300b"),"\u3002\u8be5\u6587\u7ae0\u5206\u4eab\u4e86Yi\u6a21\u578b\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u548c\u601d\u8def\uff0c\u5f3a\u8c03\u4e86\u6a21\u578b\u8bbe\u8ba1\u56f4\u7ed5\u6a21\u578b\u89c4\u6a21\u3001\u6570\u636e\u89c4\u6a21\u548c\u6570\u636e\u8d28\u91cf\u3002Yi\u6a21\u578b\u7684\u9884\u8bad\u7ec3\u9636\u6bb5\u6570\u636e\u5904\u7406\u6d41\u7a0b\u5305\u62ec\u542f\u53d1\u5f0f\u8fc7\u6ee4\u3001\u5b66\u4e60\u5f0f\u8fc7\u6ee4\u3001\u805a\u7c7b\u8fc7\u6ee4\u4ee5\u53ca\u53bb\u91cd\u7b49\u6b65\u9aa4\uff0c\u4ee5\u63d0\u9ad8\u6570\u636e\u8d28\u91cf\u3002\u5fae\u8c03\u9636\u6bb5\uff0cYi\u6a21\u578b\u4ec5\u91c7\u7528\u4e8610K\u6570\u636e\u8fdb\u884c\u6a21\u578b\u5fae\u8c03\uff0c\u5f3a\u8c03\u6570\u636e\u8d28\u91cf\u80dc\u8fc7\u6570\u91cf\u3002\u5728\u5206\u8bcd\u5668\u3001\u6a21\u578b\u7ed3\u6784\u53ca\u5fae\u8c03\u53c2\u6570\u65b9\u9762\uff0cYi\u6a21\u578b\u91c7\u7528\u4e86\u4e00\u7cfb\u5217\u4f18\u5316\u63aa\u65bd\uff0c\u5305\u62ecTransformer-Decoder\u7ed3\u6784\u3001Grouped-Query Attention\u7b49\u3002\u603b\u7684\u6765\u8bf4\uff0cYi\u6a21\u578b\u901a\u8fc7\u4f18\u5316\u6570\u636e\u5904\u7406\u6d41\u7a0b\u3001\u5fae\u8c03\u7b56\u7565\u3001\u8c03\u6574\u6a21\u578b\u7ed3\u6784\u548c\u53c2\u6570\u7b49\u591a\u65b9\u9762\u5b9e\u73b0\u4e86\u9ad8\u6548\u7684\u6280\u672f\u5b9e\u73b0\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lBXwSVvRHB2Yn0fYoOkDeQ"},"\u91cd\u65b0\u5b9a\u4e49\u5927\u6a21\u578b\u63a8\u7406\uff01Google | \u63d0\u51faSELF-DISCOVER\u6846\u67b6\uff0c\u5927\u6a21\u578b\u53ef\u81ea\u5199\u63a8\u7406\u7ed3\u6784\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/cB5tgMUPqg8fsXjNrzQpbg"},"\u300a\u65af\u5766\u798f && \u5fae\u8f6f | \u53d1\u5e03\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u52a9\u529b\u524d\u7aef\u81ea\u52a8\u5316\uff01\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u5b83\u53ef\u4ee5\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u7684\u6311\u6218\u6027\u548c\u73b0\u6709\u65b9\u6cd5\u7684\u5c40\u9650\u6027\uff0c\u7136\u540e\u63d0\u51fa\u4e86Design2Code\u57fa\u51c6\u548c\u591a\u6a21\u6001\u63d0\u793a\u65b9\u6cd5\uff0c\u4ee5\u6fc0\u53d1\u591a\u6a21\u6001\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u5982GPT-4V\u548cGemini\uff09\u7684\u6f5c\u529b\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5f00\u6e90\u768418B\u5fae\u8c03\u6a21\u578bDesign2Code-18B\uff0c\u5b83\u57fa\u4e8eCogAgent-18B\uff0c\u5728\u591a\u79cd\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u4e86\u9884\u8bad\u7ec3\uff0c\u5e76\u4f7f\u7528\u4e86Huggingface\u53d1\u5e03\u7684WebSight\u6570\u636e\u96c6\u8fdb\u884c\u5fae\u8c03\u3002\u6700\u540e\uff0c\u6587\u7ae0\u5c55\u793a\u4e86Design2Code-18B\u5728Design2Code\u57fa\u51c6\u4e0a\u7684\u4f18\u8d8a\u6027\u80fd\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u4e9b\u672a\u6765\u7814\u7a76\u65b9\u5411\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Pdp6_z_rxBl-kph41Lb8Ww"},"\u53ef\u63a7\u6587\u672c\u751f\u6210\u65b0\u65b9\u6cd5\uff0c\u4eba\u5927&&\u5357\u5f00 | \u63d0\u51faDATG\u67b6\u6784\uff0c\u51c6\u786e\u6027\u63d0\u534719.29%\uff0c\u6548\u7387\u63d0\u53471\u500d")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/53jEDw58dkZlJAVzr31G8A"},"\u300aAuto-Prompt | \u5927\u6a21\u578b\u63d0\u793a(Prompt)\u4f18\u5316\u65b0\u65b9\u6cd5IPC\uff1a\u53ef\u6839\u636e\u7528\u6237\u610f\u56fe\u8fdb\u884c\u5b9a\u5411\u4f18\u5316\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3a Intent-based Prompt Calibration\uff08IPC\uff09\u7684\u7cfb\u7edf\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u901a\u8fc7\u4f7f\u7528\u5408\u6210\u6848\u4f8b\u6837\u672c\u6765\u4f18\u5316\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u63d0\u793a\u5de5\u7a0b\u3002\u5b83\u57fa\u4e8e\u6a21\u578b\u751f\u6210\u7684\u6570\u636e\u96c6\u8fdb\u884c\u63d0\u793a\u4f18\u5316\uff0c\u4ee5\u89e3\u51b3\u5927\u8bed\u8a00\u6a21\u578b\u5bf9\u7ed9\u5b9a\u63d0\u793a\u7684\u654f\u611f\u6027\u7b49\u95ee\u9898\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u6838\u5fc3\u601d\u60f3\u662f\u6839\u636e\u7528\u6237\u610f\u56fe\u8fed\u4ee3\u7ec6\u5316\u63d0\u793a\u3002\u540c\u65f6\uff0c\u6587\u7ae0\u8fd8\u5bf9 IPC \u7cfb\u7edf\u7684\u6574\u4f53\u67b6\u6784\u548c\u5b9e\u73b0\u6d41\u7a0b\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u5c55\u793a\u4e86\u4e00\u4e9b\u5b9e\u9a8c\u7ed3\u679c\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u300a\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u51e0\u79cd\u65b0\u578b\u7684\u667a\u80fd Agent \u8bbe\u8ba1\u65b9\u6cd5\uff0c\u5305\u62ec Plan-and-Execute Agents\u3001ReWOO Agent \u548c LLMCompiler\u3002Plan-and-Execute Agent \u8bbe\u8ba1\u6cd5\u901a\u8fc7\u660e\u786e\u89c4\u5212\u6765\u4f18\u5316\u667a\u80fd Agent \u529f\u80fd\u3002ReWOO Agent \u8bbe\u8ba1\u6cd5\u51ed\u501f\u53d8\u91cf\u5206\u914d\u529f\u80fd\u4f7f\u5f97\u4e0d\u5fc5\u5bf9\u6bcf\u4e2a\u4efb\u52a1\u90fd\u4f7f\u7528 LLM\u3002LLMCompiler \u5219\u901a\u8fc7\u4efb\u52a1\u683c\u5f0f\u5316\u4e3a DAG \u6765\u63d0\u9ad8\u5de5\u5177\u8c03\u7528\u7684\u6548\u7387\u3002\u8fd9\u4e9b\u65b0\u578b\u8bbe\u8ba1\u90fd\u5728\u4e0d\u540c\u7a0b\u5ea6\u4e0a\u4f18\u5316\u4e86\u667a\u80fd Agent \u7684\u5de5\u4f5c\u6d41\u7a0b\uff0c\u63d0\u9ad8\u4e86\u5de5\u4f5c\u6548\u7387\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/F2s3pKycoNDT7Z-6piRHWg"},"\u300aOpenAI Function Calling \u4e0e LangChain Agent \u5de5\u4f5c\u539f\u7406\u53ca\u533a\u522b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86OpenAI Function Calling \u4e0e LangChain Agent\u7684\u5de5\u4f5c\u539f\u7406\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6587\u7ae0\u9996\u5148\u5217\u4e3e\u4e86\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u9650\u5236\uff0c\u5e76\u89e3\u91ca\u4e86\u4e3a\u4f55\u9700\u8981Agent\u3002\u7136\u540e\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86React Agent\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u901a\u8fc7\u201cReason Only\u201d\uff08\u5411\u5185\u6c42\u7d22\uff09\u3001\u201cAct Only\u201d\uff08\u5411\u5916\u63a2\u7d22\uff09\u548c\u201cReAct\u201d\uff08\u5185\u5916\u517c\u4fee\uff09\u4e09\u79cd\u6a21\u5f0f\u4f18\u5316\u6a21\u578b\u7684\u529f\u80fd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u4ee5\u4e00\u4e2a\u7b80\u5355\u7684\u5b9e\u4f8b\uff0c\u89e3\u91ca\u4e86\u5982\u4f55\u5229\u7528ReAct Agent\u6765\u89e3\u7b54\u4e00\u4e2a\u5305\u542b\u641c\u7d22\u548c\u8ba1\u7b97\u4e24\u4e2a\u6b65\u9aa4\u7684\u95ee\u9898\uff0c\u5c55\u793a\u4e86\u5176\u5b9e\u9645\u5e94\u7528\u7684\u6d41\u7a0b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iM45toKEHr3_rJxuwbgp4w"},"\u300aReAct Agent \u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u7684\u590d\u6742\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u201cReAct Agent \u7528\u4e8e\u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u590d\u6742\u95ee\u9898\u7684\u65b9\u5f0f\u201d\u3002\u968f\u7740\u8f93\u5165\u95ee\u9898\u7684\u590d\u6742\u5ea6\u5347\u9ad8\uff0c\u4f7f\u7528\u4f20\u7edf\u7684\u804a\u5929\u673a\u5668\u4eba\u5df2\u4e0d\u80fd\u8db3\u591f\u6709\u6548\u3002\u4e8e\u662f\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u5229\u7528 ReAct Agent\uff0c\u901a\u8fc7\u81ea\u7136\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u9010\u6b65\u89c4\u5212\u5e76\u6267\u884c\u5904\u7406\u95ee\u9898\u7684\u6b65\u9aa4\uff0c\u5e76\u5b9a\u4e49\u529f\u80fd\u6027\u5de5\u5177\uff08\u5982\u65f6\u95f4\u8ba1\u7b97\u3001\u6587\u672c\u641c\u7d22\u3001\u5217\u8868\u957f\u5ea6\u8ba1\u7b97\u3001\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\u7b49\uff09\u4ee5\u8f85\u52a9\u4efb\u52a1\u5b8c\u6210\u3002\u8fd9\u79cd\u65b9\u6cd5\u80fd\u591f\u66f4\u597d\u5730\u5e72\u9884\u548c\u63a7\u5236\u95ee\u9898\u7684\u89e3\u51b3\u8fc7\u7a0b\uff0c\u4ece\u800c\u63d0\u9ad8\u4efb\u52a1\u7684\u5b8c\u6210\u8d28\u91cf\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA"},"\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KF7joY-MkK4BZ8Rf8bLArw"},"ChatGPT\u4e5f\u80fd\u753b\u56fe\uff1f\u6559\u4f60\u4e00\u952e\u751f\u6210\u65f6\u5e8f\u56fe\u3001\u7c7b\u56fe\u3001\u6d41\u7a0b\u56fe\u3001\u72b6\u6001\u56fe\u4ee5\u53ca\u7528\u4f8b\u56fe")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/E2xwi9SNYQ7sdzhYlaDQFg"},"\u4e09\u4e2a\u88ab\u5ffd\u89c6\u7684\u5927\u6a21\u578b\u63d0\u793a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/u2LCRgBhKKcGZhY29PjIng"},"\u5173\u4e8eSora\u548cStable Diffusion 3\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/z6IFIuHawVZI6ZOfgvgKuA"},"\u6d88\u8d39\u7ea7\u663e\u5361\u53ef\u7528\uff01\u674e\u5f00\u590d\u96f6\u4e00\u4e07\u7269\u53d1\u5e03\u5e76\u5f00\u6e9090\u4ebf\u53c2\u6570Yi\u6a21\u578b\uff0c\u4ee3\u7801\u6570\u5b66\u80fd\u529b\u53f2\u4e0a\u6700\u5f3a")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IBh3ytd3gtizAQd5PI2uig"},"\u8be6\u89e3\u5927\u6a21\u578b\u5fae\u8c03\u5168\u6d41\u7a0b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/UzC3J_TOzJPEx_86-lRwuw"},"\u5357\u5927\u4fde\u626c\u6559\u6388\uff1a\u4ec0\u4e48\u662fworld models/\u4e16\u754c\u6a21\u578b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Gi6pzD7wAMyzlCBSSWkVLA"},"\u6df1\u5165\u6d45\u51faLangChain\u4e0e\u667a\u80fdAgent\uff1a\u6784\u5efa\u4e0b\u4e00\u4ee3AI\u52a9\u624b")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/T9YRVRGMgkwRSTl7Movadg"},"\u5c24\u6d0b\u6559\u6388\uff1a\u5f00\u6e90\u5b8c\u6574\u7684Sora\u590d\u73b0\u65b9\u6848\u6765\u4e86\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/8WYWrHyE4oryCgO9AemImA"},"\u300aT-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"T-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86T-RAG\u6280\u672f\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06RAG\u67b6\u6784\u4e0e\u5fae\u8c03\u8bed\u8a00\u6a21\u578b\u548c\u5b9e\u4f53\u6811\u5411\u91cf\u6570\u636e\u5e93\u76f8\u7ed3\u5408\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u652f\u6301\u8bed\u5883\u68c0\u7d22\u3002\u5b83\u6982\u8ff0\u4e86\u5728\u654f\u611f\u6587\u6863\u7684\u80cc\u666f\u4e0b\u5982\u4f55\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u6709\u9650\u7684\u8ba1\u7b97\u8d44\u6e90\u548c\u57fa\u4e8e\u73b0\u6709\u6587\u6863\u5efa\u7acb\u7684\u5c0f\u578b\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u4fdd\u8bc1\u7528\u6237\u63d0\u95ee\u7684\u51c6\u786e\u56de\u7b54\u3002\u6587\u4e2d\u8fd8\u7740\u91cd\u4ecb\u7ecd\u4e86T-RAG\u7684\u5de5\u4f5c\u6d41\u7a0b\u548c\u5b9e\u4f53\u6811\u7684\u4f5c\u7528\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u51fa\u4e86\u4e00\u4e2a\u65b0\u7684\u8bc4\u4f30\u6307\u6807\u201cCorrect-Verbose\u201d\uff0c\u7528\u4ee5\u8bc4\u4ef7\u751f\u6210\u56de\u590d\u7684\u8d28\u91cf\u3002\u6b64\u7814\u7a76\u4e0d\u4ec5\u662f\u7406\u8bba\u7814\u7a76\uff0c\u4e5f\u662f\u5b9e\u8df5\u4e2dLLM\u5e94\u7528\u7684\u7ecf\u9a8c\u603b\u7ed3\uff0c\u5177\u6709\u5b9e\u9645\u7684\u6307\u5bfc\u610f\u4e49\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/de3UxM9WTrHNjnOKSny0aw"},"\u300a\u9ad8\u7ea7 RAG\uff08Self-Reflective RAG\uff09\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u9ad8\u7ea7 RAG(Self-Reflective RAG)"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86Self-Reflective RAG\u7684\u7406\u5ff5\u548c\u5de5\u4f5c\u6d41\u7a0b\u3002\u5728\u57fa\u672c\u7684RAG pipeline\u4e2d\uff0c\u6211\u4eec\u7684\u8fc7\u7a0b\u5f80\u5f80\u53d7\u9650\u4e8e\u88ab\u52a8\u7684\u68c0\u7d22\u548c\u751f\u6210\uff0c\u800c\u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u751f\u6210\u7684\u7ed3\u679c\u8fdb\u884c\u4f18\u5316\uff0c\u5982\u6539\u53d8\u95ee\u9898\u6216\u7b5b\u9009\u548c\u6392\u5217\u5185\u5bb9\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u81ea\u6211\u4fee\u6b63\u6846\u67b6\uff0c\u5305\u62ecCorrective RAG(CRAG)\u548cSelf-Reflective RAG\u3002\u8fd9\u4e24\u79cdRAG\u90fd\u56f4\u7ed5\u7740\u5bf9\u68c0\u7d22\u548c\u751f\u6210\u5185\u5bb9\u7684\u8bc4\u4f30\u548c\u53cd\u9988\u8fdb\u884c\u81ea\u6211\u4fee\u6b63\uff0c\u5e76\u901a\u8fc7\u7279\u5b9a\u6807\u8bc6\u8fdb\u884c\u8c03\u63a7\u3002\u5728\u4e00\u5b9a\u6761\u4ef6\u4e0b\uff0c\u8fdb\u4e00\u6b65\u6539\u8fdb\u4e86RAG\uff0c\u4f7f\u5176\u4ea7\u751f\u66f4\u597d\u7684\u68c0\u7d22\u548c\u751f\u6210\u6548\u679c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WuJEubctUDsAmdhHcDItAg"},"RAG\u4e0d\u591f\u806a\u660e\uff1f\u6253\u9020\u66f4\u5f3a\u5927\u7684\u667a\u80fd\u4f53")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/b_eWGauwi6v0w4CoSOnU5w"},"Anthropic\u53d1\u5e03Claude3\uff0c\u6548\u679c\u5df2\u8d85\u8d8aGPT4")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/nMWTuKBnQVjgAM7Du6oOFQ"},"\u4ece0\u5f00\u59cb\u9884\u8bad\u7ec31.4b\u4e2d\u6587\u5927\u6a21\u578b\u5b9e\u8df5")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/W5W582CqxvRhF3wnKwIdiQ"},"\u300a\u5206\u7c7b\u7b97\u6cd5\u5165\u95e8:\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\uff0c\u5168\u9762\u800c\u8be6\u7ec6\u5730\u9610\u8ff0\u4e86\u673a\u5668\u5b66\u4e60\u4e2d\u7684\u5206\u7c7b\u7b97\u6cd5\u57fa\u7840\u77e5\u8bc6\u3002\u9996\u5148\u4ecb\u7ecd\u4e86\u4eba\u5de5\u667a\u80fd\u3001\u673a\u5668\u5b66\u4e60\u548c\u6df1\u5ea6\u5b66\u4e60\u7684\u57fa\u672c\u6982\u5ff5\uff0c\u8bb2\u89e3\u4e86\u673a\u5668\u5b66\u4e60\u5404\u79cd\u5206\u7c7b\u65b9\u6cd5\u7684\u7406\u8bba\u80cc\u666f\u3002\u968f\u540e\u901a\u8fc7\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528 Python \u5de5\u5177\uff08\u5305\u62ec pandas\u3001sklearn\u3001matplotlib \u548c seaborn\uff09\u8fdb\u884c\u6570\u636e\u5904\u7406\u3001\u5206\u6790\u548c\u53ef\u89c6\u5316\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u8ff0\u4e86\u51b3\u7b56\u6811\u3001\u903b\u8f91\u56de\u5f52\u3001\u652f\u6301\u5411\u91cf\u673a\u3001K\u8fd1\u90bb\u7b49\u7ecf\u5178\u7684\u5206\u7c7b\u7b97\u6cd5\uff0c\u5e76\u7528\u56fe\u5f62\u5316\u7684\u65b9\u5f0f\u5c55\u793a\u4e86\u5206\u7c7b\u6548\u679c\u3002\u6700\u540e\uff0c\u8bfb\u8005\u53ef\u4ee5\u901a\u8fc7\u672c\u6587\u6240\u63d0\u4f9b\u7684\u4e30\u5bcc\u5b66\u4e60\u8d44\u6599\u6765\u6df1\u5316\u5bf9\u673a\u5668\u5b66\u4e60\u5206\u7c7b\u4efb\u52a1\u7684\u7406\u89e3\u548c\u5e94\u7528\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fkRG7n4tOQKwU85xiEx0Eg"},"\u300a\u4e07\u5b57\u8be6\u89e3LLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"\u5199\u5728\u8de8\u5e74\u4e4b\u524d\uff1a\u804a\u804aLLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765"\uff0c\u4e3b\u8981\u6d89\u53ca\u5230LLM Agents\u7684\u5f53\u524d\u72b6\u6001\uff0c\u9762\u4e34\u7684\u95ee\u9898\u548c\u672a\u6765\u7684\u53ef\u80fd\u53d1\u5c55\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5305\u62ec\u5168\u53c2\u5fae\u8c03\u3001Prompt Tuning\u3001LoRA\u3001P-Tuning\u7b49\u5728\u5185\u7684SFT(Selective Fine Tuning)\u8303\u7574\u7684\u5404\u79cd\u6280\u672f\u3002\u5176\u4e2d\u5c24\u5176\u5f3a\u8c03\u4e86\u5bf9\u4e8e{prompt\uff0cresponse}\u7684\u5355\u8f6e\u95ee\u7b54\u5bf9\u7684\u5fae\u8c03\u662f\u6700\u7b80\u5355\u7684SFT\u5b9e\u73b0\u65b9\u5f0f\u3002\u5177\u4f53\u7684\u5185\u5bb9\u7ec6\u8282\u5927\u6982\u9700\u8981\u9605\u8bfb\u539f\u6587\u624d\u80fd\u83b7\u5f97\u66f4\u6df1\u5165\u7684\u7406\u89e3\u3002'),(0,a.kt)("h2",{id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173"},"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/generic-slice-functions"},"\u300aRobust generic functions on slices\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Robust generic functions on slices"\uff0c\u4e3b\u8981\u63a2\u8ba8\u4e86Go\u7684slices\u5305\u5982\u4f55\u63d0\u4f9b\u5bf9\u5207\u7247\u8fdb\u884c\u64cd\u4f5c\u7684\u901a\u7528\u51fd\u6570\u3002\u8be5\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u7c7b\u578b\u53c2\u6570\uff0c\u4e00\u6b21\u6027\u4e3a\u6240\u6709\u7c7b\u578b\u7684\u5207\u7247\u7f16\u5199\u7c7b\u4f3cslices.Index\u7b49\u51fd\u6570\uff0c\u800c\u65e0\u9700\u9488\u5bf9\u6bcf\u79cd\u4e0d\u540c\u7684\u5143\u7d20\u7c7b\u578b\u91cd\u65b0\u5b9e\u73b0\u3002\u968f\u540e\uff0c\u6587\u7ae0\u6df1\u5165\u8bb2\u8ff0\u4e86\u65b0\u7684\u51fd\u6570\uff08\u5982Insert, Replace\uff0cDelete\u7b49\uff09\u5982\u4f55\u4fee\u6539\u5207\u7247\uff0c\u5e76\u901a\u8fc7\u8be6\u8ff0\u5207\u7247\u5728\u5185\u5b58\u4e2d\u7684\u8868\u73b0\u5f62\u5f0f\u53ca\u5176\u5bf9\u5783\u573e\u56de\u6536\u5668\u7684\u5f71\u54cd\uff0c\u6765\u5e2e\u52a9\u8bfb\u8005\u7406\u89e3\u8fd9\u4e9b\u51fd\u6570\u7684\u5de5\u4f5c\u65b9\u5f0f\u548c\u6b63\u786e\u4f7f\u7528\u5b83\u4eec\u3002\u6587\u7ae0\u7279\u522b\u6307\u51fa\uff0c\u65b0\u7684Delete\u51fd\u6570\u63d0\u4f9b\u4e86\u66f4\u6e05\u6670\u5730\u8868\u8fbe\u7a0b\u5e8f\u5458\u610f\u56fe\u7684\u65b9\u5f0f\uff0c\u800c\u4e14\u5b83\u4e0d\u9700\u8981\u5206\u914d\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u6e05\u9664\u65e0\u7528\u7684\u5143\u7d20\uff0c\u5e2e\u52a9\u5783\u573e\u56de\u6536\u3002\u6587\u7ae0\u5f3a\u8c03\uff0c\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c\u5fc5\u987b\u8ba4\u4e3a\u539f\u59cb\u5207\u7247\u5df2\u65e0\u6548\uff0c\u56e0\u4e3a\u5e95\u5c42\u6570\u7ec4\u5df2\u88ab\u4fee\u6539\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u5728\u5904\u7406\u5185\u5b58\u6cc4\u6f0f\u548c\u5143\u7d20\u96f6\u503c\u8bbe\u7f6e\u7b49\u95ee\u9898\u65f6\u7684\u7b56\u7565\u548c\u9009\u9879\uff0c\u5b83\u4eec\u5728\u65b0\u7248\u672cGo\u7ed9\u51fa\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u6539\u53d8\u53ef\u80fd\u5bfc\u81f4\u7684\u4e00\u4e9b\u6d4b\u8bd5\u95ee\u9898\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9f13\u52b1\u5f00\u53d1\u4eba\u5458\u6b63\u786e\u4f7f\u7528\u65b0\u529f\u80fd\uff0c\u5e76\u5c3d\u91cf\u907f\u514d\u4e0a\u8ff0\u5217\u4e3e\u7684\u9677\u9631\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://go.dev/blog/routing-enhancements"},"\u300aRouting Enhancements for Go 1.22\u300b"),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a"Routing Enhancements for Go 1.22"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86 Go 1.22 \u7248\u672c\u4e2d net/http \u5305\u7684\u8def\u7531\u5668\u63d0\u4f9b\u7684\u65b0\u7279\u6027\uff1a\u65b9\u6cd5\u5339\u914d\u548c\u901a\u914d\u7b26\u3002\u8fd9\u4e9b\u65b0\u7279\u6027\u8ba9\u4f60\u53ef\u4ee5\u4f7f\u7528\u6a21\u5f0f\uff0c\u800c\u975e Go \u4ee3\u7801\uff0c\u6765\u8868\u8fbe\u5e38\u89c1\u7684\u8def\u7531\u3002\u8fd9\u79cd\u65b0\u529f\u80fd\uff0c\u5c3d\u7ba1\u7b80\u5355\u6613\u61c2\uff0c\u4f46\u8981\u9009\u62e9\u51fa\u591a\u4e2a\u5339\u914d\u8bf7\u6c42\u7684\u6700\u4f73\u6a21\u5f0f\u5374\u662f\u4e00\u9879\u6311\u6218\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u9610\u91ca\u4e86\u5982\u4f55\u5728\u65b0\u7248 Go \u4e2d\u4f7f\u7528\u8fd9\u4e9b\u65b0\u7279\u6027\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u5f15\u5165\u7684\u53d8\u5316\u5982\u4f55\u5f71\u54cd\u4e86 ServeMux \u65b9\u6cd5 handle \u548c handleFunc \u3002\u6b64\u5916\uff0c\u8fd8\u63cf\u8ff0\u4e86\u65b0\u6a21\u5f0f\u5982\u4f55\u66f4\u5177\u4f18\u5148\u7ea7\uff0c\u5e76\u89e3\u91ca\u4e86\u5176\u80cc\u540e\u7684\u539f\u7406\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u65b0\u65e7\u7248\u672c\u7684\u517c\u5bb9\u6027\uff0c\u4f5c\u8005\u4eec\u4e5f\u52aa\u529b\u4f7f\u65b0\u7684\u6a21\u5f0f\u8bed\u6cd5\u80fd\u8986\u76d6\u65e7\u7684\uff0c\u5e76\u4f7f\u65b0\u7684\u4f18\u5148\u7ea7\u89c4\u5219\u80fd\u6cdb\u5316\u65e7\u7684\u89c4\u5219\u3002\u603b\u4f53\u4e0a\uff0c\u8fd9\u4e9b\u6539\u53d8\u662f Go \u8bed\u8a00\u56e2\u961f\u4e0d\u65ad\u52aa\u529b\u4f7f Go \u6210\u4e3a\u6784\u5efa\u751f\u4ea7\u7cfb\u7edf\u7684\u4f18\u79c0\u8bed\u8a00\u7684\u4e00\u4e2a\u6301\u7eed\u8fc7\u7a0b\u7684\u4e00\u90e8\u5206\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/IH1FGDpClrsnlfjg7OF3lg"},"\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(6)")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/JCU3dwkwpMP3qMKqg9ed6g"},"\u4f7f\u7528Apache Kafka\u7684Golang\u5b9e\u8df5\u6307\u5357")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/RFsHfFByarSRAA-f1Rs13g"},"\u300aGo \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570\u300b"),'\u3002\u8fd9\u7bc7\u7531\u714e\u9c7c\u64b0\u5199\u7684\u6587\u7ae0\uff0c\u9898\u4e3a "Go \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570?"\uff0c\u5bf9\u4e8e\u8fd9\u4e2a\u8bdd\u9898\u8fdb\u884c\u4e86\u6df1\u5ea6\u89e3\u6790\u3002\u5176\u9996\u5148\u63d0\u5230\uff0c\u867d\u7136Go\u7684\u89c4\u8303\u5e76\u6ca1\u6709\u660e\u786e\u7981\u6b62\u4ecemain\u5305\u4e2d\u5bfc\u5165\u51fd\u6570\uff0c\u4f46\u6211\u4eec\u5728\u5b9e\u9645\u8fd0\u884c\u4e2d\u4f1a\u88ab\u62d2\u7edd\uff0c\u63d0\u793amain\u5305\u662f\u4e00\u4e2a\u7a0b\u5e8f\u800c\u975e\u53ef\u4ee5\u5bfc\u5165\u7684\u5305\u3002\u8fd9\u4e00\u73b0\u8c61\u7684\u539f\u56e0\u6765\u81ea\u4e8e\u7ecf\u8fc7\u591a\u6b21\u53d8\u52a8\u7684\u89c4\u5b9a\uff0c\u59822011\u5e74\u79fb\u9664\u4e86 "\u7a0b\u5e8f\u4e2d\u7684\u5176\u4ed6\u5305\u90fd\u4e0d\u80fd\u547d\u540d\u4e3a main" \u7684\u8981\u6c42\uff0c\u7136\u540e\u57282015\u5e74\u53c8\u65b0\u589e\u4e86\u9650\u5236\u3002\u8fd9\u6837\u7684\u53d8\u5316\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u589e\u52a0\u590d\u6742\u5ea6\u548c\u4e0d\u5b89\u5168\u6027\u3002\u6bd4\u5982\uff0c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u505a\u51fa\u81ea\u5df1\u62e5\u6709\u5b8c\u5168\u63a7\u5236\u6743\u7684\u5047\u8bbe\uff0c\u6240\u4ee5\u5982\u679c\u5f15\u5165\u591a\u4e2amain\u5305\u4e2d\u7684\u51fd\u6570\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u5728\u521d\u59cb\u5316\u987a\u5e8f\u3001\u5168\u5c40\u53d8\u91cf\u7684\u6ce8\u518c\u7b49\u65b9\u9762\u7684\u51b2\u7a81\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba4\u4e3aGo\u5b98\u65b9\u7684\u505a\u6cd5\u5728\u7406\u8bba\u4e0a\u53ef\u4ee5\u89e3\u51b3\u590d\u6742\u5ea6\u548c\u5b89\u5168\u6027\u95ee\u9898\uff0c\u4f46\u5bf9\u4e8e\u6709\u5386\u53f2\u503a\u52a1\u7684\u9879\u76ee\uff0c\u5bf9\u4e8e\u9700\u8981\u7ef4\u62a4\u591a\u4e2aGo\u9879\u76ee\u5de5\u7a0b\uff0c\u76f8\u5f53\u4e8e\u78e8\u706d\u4e86\u4e00\u6761\u9053\u8def\uff0c\u5176\u5b9e\u6bd4\u8f83\u5c34\u5c2c\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/zxLO4IhLqQmIaUDzwwjU1w"},"\u300afasthttp\u662f\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8bb2\u89e3\u4e86fasthttp\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u539f\u7406\u3002fasthttp\u76f8\u6bd4\u4e8enet/http\u5728\u5904\u7406\u6d41\u7a0b\u4e0a\u6709\u6240\u5dee\u5f02\uff0cnet/http\u662f\u4e00\u4e2a\u8fde\u63a5\u65b0\u5efa\u4e00\u4e2agoroutine\uff0c\u5f53\u8fde\u63a5\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\u4f1a\u7ed9\u7cfb\u7edf\u5e26\u6765\u4e00\u5b9a\u7684\u538b\u529b\u3002\u800cfasthttp\u5219\u662f\u5efa\u7acb\u4e86workerPool\uff0c\u6bcf\u4e2aworkerChan\u5728\u540e\u53f0\u90fd\u4f1a\u6709\u4e00\u4e2aGoroutine\u6765\u5904\u7406\u5176\u4e2d\u7684\u8fde\u63a5\u3002\u6b64\u5916\uff0cfasthttp\u7684\u5feb\u901f\u4e5f\u5f97\u76ca\u4e8e\u51e0\u4e2a\u65b9\u9762\u7684\u4f18\u5316\uff1a\u8fde\u63a5\u590d\u7528\uff0c\u5927\u91cf\u4f7f\u7528\u4e86sync.Pool\u8fdb\u884c\u5185\u5b58\u590d\u7528\u4ee5\u53ca\u901a\u8fc7unsafe.Pointer\u6307\u9488\u8fdb\u884c","[","]","byte\u548cstring\u8f6c\u6362\u6765\u907f\u514d\u5185\u5b58\u5206\u914d\u548c\u62f7\u8d1d\u7684\u6d88\u8017\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/fx-FTVpM3CXIPUwTC_juDQ"},"\u300a\u4e07\u5b57\u957f\u6587\u8bb2\u89e3Golang pprof \u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86Golang\u7684pprof\u5de5\u5177\u7684\u4f7f\u7528\u3002pprof\u5de5\u5177\u662fGolang\u4e2d\u7528\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4e00\u4e2a\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u5206\u6790\u51facpu\u4f7f\u7528\u60c5\u51b5\u3001\u5185\u5b58\u5360\u7528\u3001\u963b\u585e\u60c5\u51b5\u3001\u7ebf\u7a0b\u548c\u534f\u7a0b\u7b49\u4fe1\u606f\u3002\u6587\u7ae0\u4e2d\u8be6\u7ec6\u9610\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528\u6b64\u5de5\u5177\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u901a\u8fc7http\u63a5\u53e3\u7684\u65b9\u5f0f\u66b4\u9732\u51fapprof\u7684\u91c7\u96c6\u63a7\u5236\u754c\u9762\uff0c\u53e6\u4e00\u79cd\u662f\u5728\u7a0b\u5e8f\u4e2d\u901a\u8fc7\u4ee3\u7801\u6765\u542f\u52a8\u76f8\u5e94\u6307\u6807\u7684\u91c7\u96c6\u793a\u4f8b\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u89e3\u6790\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u5f0f\u83b7\u53d6\u7684\u8f93\u51fa\u4fe1\u606f\u3002\u672c\u6587\u7684\u4e3b\u8981\u76ee\u7684\u662f\u5c06pprof\u5de5\u5177\u7684\u4f7f\u7528\u65b9\u5f0f\u7528\u601d\u7ef4\u5bfc\u56fe\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765\uff0c\u8fd9\u6837\u53ef\u4ee5\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u4f7f\u7528pprof\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/xYvMI0JieO6RxHIdWf1ujQ"},"\u300a\u4e00\u7bc7\u5b9e\u7528\u7684\u5173\u4e8e\u4e91\u4e0aK8s\u5e94\u7528\u5206\u8d26\u5b9e\u8df5\u300b"),"\u3002\u672c\u6587\u8bb2\u8ff0\u4e91\u4e0aKubernetes\uff08K8s\uff09\u5e94\u7528\u7684\u6210\u672c\u5206\u644a\u5b9e\u8df5\uff0c\u6db5\u76d6\u4e86\u6210\u672c\u5206\u644a\u7684\u6838\u5fc3\u6982\u5ff5\u53ca\u963f\u91cc\u4e91ACK FinOps\u5957\u4ef6\u7684\u5e94\u7528\u3002\u6587\u4e2d\u9996\u5148\u4ee5\u524d\u671f\u9884\u7b97\u4e3a\u96c6\u7fa4\u89c4\u5212\u7684\u4f9d\u636e\uff0c\u5e76\u8ba8\u8bba\u4e86\u968f\u7740\u4e1a\u52a1\u53d1\u5c55\u5bf9\u6210\u672c\u5206\u644a\u7cbe\u51c6\u5ea6\u7684\u63d0\u5347\u9700\u6c42\u3002\u4ecb\u7ecd\u4e86\u5982\u4f55\u6839\u636ePod\u7684\u6838/\u65f6\u6210\u672c\uff0c\u901a\u8fc7ACK\u96c6\u7fa4\u3001\u8ba1\u7b97\u8282\u70b9\u3001\u547d\u540d\u7a7a\u95f4\u548c\u5e94\u7528Pod\u8fd9\u56db\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u8d39\u7528\u5206\u644a\u3002\u6587\u7ae0\u8fd8\u5206\u6790\u4e86\u5355\u8d44\u6e90\u548c\u6df7\u5408\u8d44\u6e90\u5206\u644a\u6a21\u578b\uff0c\u5e76\u8ba8\u8bba\u4e86\u5982\u4f55\u8bbe\u7f6eRequest\u548cLimit\u6765\u4f18\u5316\u8d44\u6e90\u5229\u7528\u3002\u5bf9\u4e8e\u591a\u4e91\u548c\u6df7\u5408\u4e91\u573a\u666f\uff0c\u5206\u4eab\u4e86\u5982\u4f55\u901a\u8fc7ACK One\u5b9e\u73b0\u7edf\u4e00\u7ba1\u7406\u548c\u6210\u672c\u5206\u6790\u3002\u9488\u5bf9\u590d\u6742\u4e1a\u52a1\u573a\u666f\uff0c\u8bb2\u8ff0\u4e86\u81ea\u5b9a\u4e49\u5b9a\u4ef7\u6a21\u7248\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u5141\u8bb8\u901a\u8fc7\u914d\u7f6e\u5b9e\u73b0\u6210\u672c\u5b9a\u5236\u9700\u6c42\u3002\u5bf9\u4e8e\u8ffd\u6c42\u7ec6\u8282\u7ba1\u7406\u548c\u7cbe\u7ec6\u5316\u8fd0\u8425\u7684\u56e2\u961f\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u6307\u5bfc\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/6xx3-qow8A5Hdp_72jswow"},'\u300a\u5982\u4f55\u4f7f\u7528 K8s \u4e24\u5927\u5229\u5668"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u5e2e\u4f60\u6446\u8131\u8fd0\u7ef4\u56f0\u5883\u300b'),'\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528 Kubernetes\uff08K8s\uff09\u7684"\u5ba1\u8ba1"\u548c"\u4e8b\u4ef6"\u529f\u80fd\u6765\u5e2e\u52a9\u8fdb\u884c\u65e5\u5e38\u96c6\u7fa4\u8fd0\u7ef4\u5de5\u4f5c\u3002\u6587\u7ae0\u9996\u5148\u6307\u51fa\u4e86\u8fd0\u7ef4\u5de5\u4f5c\u4e2d\u53ef\u80fd\u51fa\u73b0\u7684\u4e00\u4e9b\u95ee\u9898\uff0c\u4f8b\u5982\u5e94\u7528\u88ab\u5220\u9664\u3001Apiserver\u8d1f\u8f7d\u7a81\u53d8\u3001\u96c6\u7fa4\u8282\u70b9\u51fa\u73b0\u95ee\u9898\u3001\u8282\u70b9\u81ea\u52a8\u6269\u5bb9\u7b49\u3002\u968f\u540e\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u89e3\u91ca\u4e86 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\u662f\u5982\u4f55\u8fd0\u4f5c\u7684\uff0c\u5f3a\u8c03\u4e86\u5584\u7528\u8fd9\u4e24\u79cd\u5de5\u5177\u53ef\u4ee5\u63d0\u9ad8\u96c6\u7fa4\u7684\u53ef\u89c2\u5bdf\u6027\uff0c\u4e3a\u8fd0\u7ef4\u5de5\u4f5c\u5e26\u6765\u6781\u5927\u7684\u4fbf\u5229\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u901a\u8fc7\u4f7f\u7528 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u66f4\u597d\u5730\u7ba1\u7406\u548c\u76d1\u6d4b\u96c6\u7fa4\u7684\u72b6\u6001\u3002'),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lxEAFe2Ewmc8YvTqn8UcLQ"},"\u3010Go \u5de5\u5177\u3011\u7ade\u6001\u6761\u4ef6\u68c0\u6d4b\u795e\u5668 Race Detector")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Y67J4_D1yyMa-eb7XmgTcA"},"\u4f7f\u7528Redis\u5165\u95e8Golang")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/qDFM-nVo-jeh9VdcBfMreA"},"\u4e00\u9053\u9762\u8bd5\u9898: Top K \u95ee\u9898")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/sTd3SVh0swGTnaGugsw1SA"},"\u300a\u7406\u89e3 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u89e3\u6790\u4e86 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u3002\u9996\u5148\uff0c\u4f5c\u8005\u6982\u8ff0\u4e86\u7528\u6237\u540d\u3001\u7ec4\u540d\u3001\u7528\u6237ID\uff08UID\uff09\u548c\u7ec4ID\uff08GID\uff09\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e0e\u4e3b\u673a\u7cfb\u7edf\u4e4b\u95f4\u7684\u6620\u5c04\u5bf9\u4e8e\u6784\u5efa\u5b89\u5168\u7cfb\u7edf\u7684\u91cd\u8981\u6027\u3002\u968f\u540e\uff0c\u6587\u7ae0\u5206\u6790\u4e86uid/gid\u5728Linux\u7cfb\u7edf\u7684\u5b89\u5168\u6027\uff0c\u5f3a\u8c03\u4e86\u5355\u4e00\u5185\u6838\u6982\u5ff5\u4ee5\u53cauid/gid\u7684\u5206\u914d\u65b9\u5f0f\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u8fd0\u7528\u5b9e\u4f8b\u89e3\u91ca\u4e86Docker\u8fd0\u884c\u7684\u8fc7\u7a0b\u4ee5\u53ca\u5982\u4f55\u901a\u8fc7Dockerfile\u5b9a\u4e49\u548c\u542f\u52a8\u4e0d\u540c\u7528\u6237\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8bb2\u8ff0\u4e86\u5982\u4f55\u638c\u63a7\u548c\u63a7\u5236\u5bb9\u5668\u7684\u8bbf\u95ee\u6743\u9650\u3002\u5728\u9610\u8ff0\u4ee5\u4e0a\u5185\u5bb9\u7684\u540c\u65f6\uff0c\u6587\u7ae0\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u9645\u793a\u4f8b\u6765\u8bf4\u660e\u8fd9\u4e9b\u89c2\u70b9\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yUuo1IjeXY78_5u4QpkuTA"},"\u300a\u5982\u4f55\u57fa\u4e8eDocker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u5c06Docker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u3002\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5229\u7528\u5f00\u6e90\u5de5\u5177Dedockify\u7684\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u5de5\u4f5c\u539f\u7406\u3002\u8be5\u5de5\u5177\u901a\u8fc7Python\u811a\u672c\uff0c\u5229\u7528\u5b58\u50a8\u5728\u6bcf\u4e2a\u955c\u50cf\u5c42\u65c1\u8fb9\u7684\u5143\u6570\u636e\uff0c\u9010\u6b65\u904d\u5386\u5c42\u7ea7\u6811\uff0c\u6536\u96c6\u4e0e\u6bcf\u4e2a\u5c42\u76f8\u5173\u8054\u7684\u547d\u4ee4\uff0c\u91cd\u5efa\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\u547d\u4ee4\u5e8f\u5217\uff0c\u4ece\u800c\u5f97\u5230\u8fd1\u4f3c\u7684Dockerfile\u3002\u4e0d\u8fc7\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bbf\u95ee\u6267\u884c\u539f\u59cbdocker build\u547d\u4ee4\u65f6\u5b58\u5728\u7684\u6784\u5efa\u4e0a\u4e0b\u6587\uff0c\u5982\u679c\u4f7f\u7528\u4e86COPY\u6216ADD\u6307\u4ee4\uff0c\u751f\u6210\u7684\u8f93\u51fa\u53ef\u80fd\u4e0d\u5b8c\u5168\u5339\u914d\u539f\u59cb\u7684Dockerfile\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/KkRWQyljuo86-XbBxEnGPA"},"\u300a\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u3002\u9996\u5148\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a\u901a\u7528\u7684Dockerfile\uff0c\u5e76\u6307\u51fa\u5176\u751f\u6210\u7684\u955c\u50cf\u5927\u5c0f\u8d85\u8fc7300MB\uff0c\u4e3b\u8981\u56e0\u4e3a\u5305\u542b\u4e86\u6240\u6709\u7684Golang\u5de5\u5177\u3002\u7136\u540e\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u591a\u9636\u6bb5\u6784\u5efa\u7684\u65b9\u6cd5\uff0c\u5b83\u80fd\u4ece\u4e0d\u540c\u7684\u57fa\u7840\u955c\u50cf\u6784\u5efa\uff0c\u6709\u9009\u62e9\u5730\u5c06\u6587\u4ef6\u4ece\u4e00\u4e2a\u9636\u6bb5\u4f20\u9012\u5230\u4e0b\u4e00\u4e2a\u9636\u6bb5\uff0c\u4ece\u800c\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u901a\u8fc7\u4e8c\u7ea7\u6784\u5efa\uff0c\u955c\u50cf\u5927\u5c0f\u5df2\u964d\u81f311.7MB\u3002\u6700\u540e\uff0c\u8fd8\u63a2\u8ba8\u4e86\u4f7f\u7528\u540d\u4e3ascratch\u7684\u7a7a\u767d\u955c\u50cf\u8fdb\u4e00\u6b65\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u7684\u53ef\u80fd\u6027\uff0c\u4f7f\u5f97\u955c\u50cf\u6700\u540e\u964d\u81f36.34MB\uff0c\u4f46\u4f5c\u8005\u5f3a\u8c03\u8fd9\u9700\u8981\u614e\u91cd\u8003\u8651\uff0c\u56e0\u4e3a\u6700\u540e\u751f\u6210\u7684\u955c\u50cf\u5c06\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u5de5\u5177\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dckA1ezcABndN5WSg1BOBA"},"\u300ak8s \u5230\u5e95\u662f\u4ec0\u4e48\uff0c\u67b6\u6784\u662f\u600e\u4e48\u6837\u7684\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86 Kubernetes\uff08K8s\uff09\u7684\u57fa\u672c\u6982\u5ff5\u3001\u67b6\u6784\u548c\u5de5\u4f5c\u539f\u7406\u3002Kubernetes\uff0c\u56e0\u5355\u8bcd\u8fc7\u957f\uff0c\u6211\u4eec\u901a\u5e38\u7b80\u5316\u4e3ak8s\u3002k8s \u662f\u4e00\u79cd\u5bb9\u5668\u7684\u534f\u8c03\u5de5\u5177\uff0c\u4f4d\u4e8e\u5e94\u7528\u670d\u52a1\u548c\u670d\u52a1\u5668\u4e4b\u95f4\uff0c\u80fd\u4ee5\u7b56\u7565\u7684\u65b9\u5f0f\u534f\u8c03\u548c\u7ba1\u7406\u591a\u4e2a\u5e94\u7528\u670d\u52a1\u3002\u901a\u8fc7\u4e00\u4e2a yaml \u6587\u4ef6\u7684\u914d\u7f6e\uff0c\u53ef\u4ee5\u5b9a\u4e49\u5e94\u7528\u7684\u90e8\u7f72\u987a\u5e8f\u7b49\u4fe1\u606f\uff0c\u81ea\u52a8\u90e8\u7f72\u5e94\u7528\u5230\u5404\u4e2a\u670d\u52a1\u5668\u4e0a\uff0c\u8fd8\u80fd\u8ba9\u5b83\u4eec\u5d29\u6e83\u540e\u81ea\u52a8\u91cd\u542f\uff0c\u53ef\u4ee5\u81ea\u52a8\u6269\u5bb9\u548c\u7f29\u5bb9\u3002Kubernetes \u7684\u670d\u52a1\u5668\u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u63a7\u5236\u5e73\u9762\u548c\u5de5\u4f5c\u8282\u70b9\uff0c\u524d\u8005\u8d1f\u8d23\u63a7\u5236\u548c\u7ba1\u7406\u5404\u4e2a\u8282\u70b9\uff0c\u540e\u8005\u5219\u8d1f\u8d23\u5b9e\u9645\u8fd0\u884c\u5404\u4e2a\u5e94\u7528\u670d\u52a1\u3002k8s \u7684\u547d\u4ee4\u884c\u5de5\u5177\u4e3a kubectl\uff0c\u7528\u4e8e\u6267\u884c\u5404\u7c7b\u64cd\u4f5c\u547d\u4ee4\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/vjmntyGwzURz_elg27vpXg"},"\u300aGo \u6cdb\u578b\u6709\u6ca1\u6709\u53ef\u80fd\u5728\u540e\u671f\u6539\u4e3a ",(0,a.kt)("inlineCode",{parentName:"a"},"<>")," \u5c16\u62ec\u53f7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728\u5904\u7406\u6cdb\u578b\u65f6\uff0c\u4e3a\u4f55\u5e76\u6ca1\u6709\u91c7\u7528\u7c7b\u4f3cJava\u548cC++\u7684 ",(0,a.kt)("inlineCode",{parentName:"p"},"<>")," \u5c16\u62ec\u53f7\u8868\u793a\u6cd5\uff0c\u800c\u662f\u9009\u62e9\u4e86\u4e2d\u62ec\u53f7 ",(0,a.kt)("inlineCode",{parentName:"p"},"[]"),". \u9996\u5148\uff0c\u4f7f\u7528\u5c16\u62ec\u53f7\u53ef\u80fd\u5bfc\u81f4\u8bed\u4e49\u6df7\u6dc6\uff0c\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"a, b := w < x, y > (z)")," \u6b64\u53e5\uff0c\u5982\u679c\u4f7f\u7528\u5c16\u62ec\u53f7\uff0c\u7a0b\u5e8f\u53ef\u80fd\u5728\u7f16\u8bd1\u9636\u6bb5\u65e0\u6cd5\u786e\u5b9a\u8be5\u884c\u8868\u8fbe\u5f0f\u7684\u5177\u4f53\u542b\u4e49\u3002\u5176\u6b21\uff0c\u4f7f\u7528\u5706\u62ec\u53f7\u4e5f\u4f1a\u5bfc\u81f4\u540c\u6837\u7684\u95ee\u9898\uff0c\u6bd4\u5982 ",(0,a.kt)("inlineCode",{parentName:"p"},"func F(T any)(v T)(r1, r2 T)"),", \u65e0\u6cd5\u5feb\u901f\u51c6\u786e\u5224\u65ad\u51fa\u53c2\u6570\u548c\u8fd4\u56de\u503c\u90e8\u5206\u3002\u6b64\u5916\uff0cGo\u5b98\u65b9\u4e5f\u4e0d\u5e0c\u671b\u4f7f\u7528\u975eASCII\u7684\u5b57\u7b26\u3002\u4f5c\u8005\u8fd8\u63d0\u5230\u793e\u533a\u4e2d\u5bf9Go\u7684\u5904\u7406\u65b9\u5f0f\u5b58\u5728\u4e00\u4e9b\u4e89\u8bae\uff0c\u90e8\u5206\u793e\u533a\u6210\u5458\u8ba4\u4e3a\u5982\u679c\u4f7f\u5f97\u7f16\u8bd1\u5668\u89e3\u91ca\u5c16\u62ec\u53f7\u4e0d\u518d\u56f0\u96be\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u8fd9\u79cd\u7b26\u53f7\u3002\u7136\u800c\uff0c\u603b\u7684\u6765\u8bf4\uff0c\u57fa\u4e8e\u5df2\u6709\u7684\u5b9e\u8df5\u548c\u89c4\u8303\uff0cGo\u8bed\u8a00\u5728\u672a\u6765\u53ef\u80fd\u4e5f\u4e0d\u4f1a\u6539\u53d8\u5176\u6cdb\u578b\u7684\u8868\u793a\u65b9\u5f0f\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/arI9sip-5JH9YSu45XJ83w"},"\u300aRust\u4e2dchannel\u7684\u4f7f\u7528\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86Rust\u7f16\u7a0b\u8bed\u8a00\u4e2dChannel\u7684\u7528\u6cd5\u3002\u5176\u4e2d\uff0cChannel\u662fRust\u4e2d\u7528\u4e8e\u5728\u4e0d\u540c\u7ebf\u7a0b\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u901a\u4fe1\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u7ebf\u7a0b\u95f4\u7684\u6d88\u606f\u4f20\u9012\u3002\u6bcf\u4e2aChannel\u7531\u53d1\u9001\u7aef\u548c\u63a5\u6536\u7aef\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5176\u8bbe\u8ba1\u7406\u5ff5\u662f\u201c\u901a\u8fc7\u901a\u4fe1\u6765\u5171\u4eab\u5185\u5b58\uff0c\u800c\u975e\u901a\u8fc7\u5171\u4eab\u5185\u5b58\u6765\u901a\u4fe1\u201d\uff0c\u4ee5\u6b64\u907f\u514d\u4e86\u6570\u636e\u7ade\u4e89\u548c\u5171\u4eab\u5185\u5b58\u7684\u590d\u6742\u6027\u3002\u8be5\u6587\u7ae0\u8fdb\u4e00\u6b65\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5728Rust\u4e2d\u521b\u5efa\u548c\u4f7f\u7528Channel\uff0c\u5e76\u7ed9\u51fa\u4e86\u76f8\u5173\u4ee3\u7801\u793a\u4f8b\u3002\u6700\u540e\uff0c\u6587\u7ae0\u9610\u8ff0\u4e86\u591a\u79cdChannel\u6a21\u578b\uff0c\u5305\u62ecRust\u6807\u51c6\u5e93\u4e2d\u6240\u4f7f\u7528\u7684MPSC\uff08\u591a\u751f\u4ea7\u8005\uff0c\u5355\u6d88\u8d39\u8005\uff09\u6a21\u578b\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7272006755266002959"},"K8s\u90e8\u7f72\u65b9\u5f0f\u5927\u5168\uff1a\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1\u6240\u6709\u6280\u5de7")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7301584578342289423"},"k8s\u4ece\u5165\u95e8\u5230\u7cbe\u901a -- \u66f4\u9002\u5408\u4e2d\u56fd\u5b9d\u5b9d\u4f53\u8d28")),(0,a.kt)("h2",{id:"-\u540e\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NABg5tGizHsmdXgUO6NeVw"},"\u300a\u4e07\u5b57+33\u5f20\u56fe\u63a2\u79d8OpenFeign\u6838\u5fc3\u67b6\u6784\u539f\u7406\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u6df1\u5165\u63a2\u8ba8\u4e86SpringCloud\u6838\u5fc3\u7ec4\u4ef6OpenFeign\u7684\u6838\u5fc3\u67b6\u6784\u539f\u7406\u3002\u6587\u7ae0\u5206\u4e3a\u56db\u4e2a\u90e8\u5206\uff0c\u9996\u5148\u89e3\u91ca\u539f\u59cbFeign\u7684\u4f7f\u7528\u548c\u57fa\u4e8eSpringCloud\u7684\u8fdb\u5316\u8fc7\u5386\u7a0b\uff1b\u7136\u540e\u8be6\u7ec6\u8bb2\u89e3\u4e86Feign\u5e95\u5c42\u5de5\u4f5c\u539f\u7406\uff0c\u4f9d\u8d56\u4e8eJDK\u52a8\u6001\u4ee3\u7406\u548c\u6838\u5fc3\u7ec4\u4ef6\u5982Contract\u3001Encoder\u3001Decoder\u7b49\uff1b\u63a5\u4e0b\u6765\u5206\u6790\u4e86SpringCloud\u662f\u5982\u4f55\u6574\u5408Feign\u7684\uff0c\u5e76\u4e14\u8ba8\u8bba\u4e86OpenFeign\u7684\u591a\u79cd\u914d\u7f6e\u65b9\u5f0f\u53ca\u5176\u4f18\u5148\u7ea7\uff1b\u6700\u540e\uff0c\u6587\u7ae0\u901a\u8fc7\u4e30\u5bcc\u7684\u56fe\u793a\u548c\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u53ef\u4ee5\u66f4\u597d\u5730\u7406\u89e3\u5e76\u8fd0\u7528\u8fd9\u4e00\u5de5\u5177\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4e8e\u7406\u89e3\u548c\u8fd0\u7528OpenFeign\u975e\u5e38\u6709\u5e2e\u52a9\uff0c\u65e0\u8bba\u662f\u5bf9\u4e8e\u521d\u5b66\u8005\u8fd8\u662f\u6709\u7ecf\u9a8c\u7684\u5f00\u53d1\u8005\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1Qe29y3nrbi39Kpaspme7Q"},"\u300a\u4e09\u4e07\u5b57\u957f\u6587\uff1a\u5982\u4f55\u53bb\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4efd\u8be6\u5c3d\u7684\u6307\u5bfc\uff0c\u8bb2\u8ff0\u4e86\u5982\u4f55\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u3002\u6587\u4e2d\u9996\u5148\u5b9a\u4f4d\u4e86\u6280\u672f\u95ee\u9898\u7684\u8303\u56f4\uff0c\u786e\u5b9a\u9002\u7528\u4e8eJDK8\u81f3JDK11\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u7cfb\u7edf\u5316\u7684\u6392\u67e5\u539f\u5219\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u6b65\u6b65\u7684\u8bca\u65ad\u6d41\u7a0b\uff0c\u4ece\u57fa\u672c\u4fe1\u606f\u6536\u96c6\u3001\u5224\u65ad\u5185\u5b58\u589e\u957f\u539f\u56e0\uff0c\u5230\u5177\u4f53\u5206\u6790\u5185\u5b58\u95ee\u9898\u7684\u53ef\u80fd\u6765\u6e90\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u4e0d\u540c\u7684\u547d\u4ee4\u548c\u5de5\u5177\uff08\u5982jmap\u3001jstat\u3001Arthas\u7b49\uff09\u8fdb\u884c\u8be6\u7ec6\u7684\u5206\u6790\uff0c\u5e76\u6839\u636e\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff0c\u5411\u8bfb\u8005\u5c55\u793a\u4e86\u5982\u4f55\u786e\u5b9a\u662f\u5806\u5185\u5b58\u95ee\u9898\u8fd8\u662f\u5806\u5916\u5185\u5b58\u95ee\u9898\u3002\u603b\u4e4b\uff0c\u6587\u7ae0\u4e3a\u90a3\u4e9b\u9700\u8981\u6df1\u5165\u7406\u89e3\u548c\u5904\u7406JVM\u5185\u5b58\u95ee\u9898\u7684\u5f00\u53d1\u8005\u548c\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u77e5\u8bc6\u548c\u6280\u5de7\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/WLPo8s_M3AzxwB3o3ehY3w"},"\u300a\u5982\u4f55\u907f\u514dMYSQL\u4e3b\u4ece\u5ef6\u8fdf\u5e26\u6765\u7684\u8bfb\u5199\u95ee\u9898\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u5904\u7406\u5728MySQL\u4e3b\u4ece\u90e8\u7f72\u67b6\u6784\u4e2d\u666e\u904d\u5b58\u5728\u7684\u4e3b\u4ece\u540c\u6b65\u5ef6\u8fdf\u95ee\u9898\uff0c\u4ee5\u4fdd\u6301\u8bfb\u5199\u64cd\u4f5c\u7684\u4e00\u81f4\u6027\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u4e3b\u4ece\u5ef6\u8fdf\u4ea7\u751f\u7684\u573a\u666f\u53ca\u5176\u5bf9\u8bfb\u5199\u5206\u79bb\u539f\u5219\u7684\u5f71\u54cd\u3002\u7136\u540e\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e86\u4e3b\u4ece\u590d\u5236\u7684\u539f\u7406\uff0c\u5e76\u63d0\u51fa\u4e86\u4e24\u79cd\u907f\u514d\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u6280\u672f\u65b9\u6848\uff1a\u4e00\u662f\u4f7f\u7528select master_pos_wait\u51fd\u6570\u6765\u7b49\u5f85\u4ece\u5e93\u540c\u6b65\u81f3\u7279\u5b9a\u7684binlog\u4f4d\u7f6e\u70b9\uff1b\u4e8c\u662f\u5728\u5f00\u542fGTID\u6a21\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7select wait_for_executed_gtid_set\u51fd\u6570\u68c0\u67e5GTID\u96c6\u5408\u662f\u5426\u5df2\u540c\u6b65\u3002\u8fd9\u4e24\u79cd\u65b9\u6cd5\u5747\u65e8\u5728\u786e\u4fdd\u4ece\u5e93\u6570\u636e\u7684\u51c6\u786e\u6027\uff0c\u4ece\u800c\u6574\u4f53\u4e0a\u51cf\u8f7b\u4e3b\u5e93\u7684\u538b\u529b\u3002\u603b\u4f53\u4e0a\uff0c\u6587\u7ae0\u4e3aMySQL\u6570\u636e\u5e93\u7ba1\u7406\u5458\u63d0\u4f9b\u4e86\u7f13\u89e3\u4e3b\u4ece\u5ef6\u8fdf\u5bfc\u81f4\u7684\u8bfb\u5199\u95ee\u9898\u7684\u5177\u4f53\u5b9e\u65bd\u65b9\u6848\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dt_14etV_2ynAmyMa_uyug"},"\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014ES\u7bc7\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u7bc7\u9488\u5bf9Elasticsearch(ES)\u7684\u9762\u8bd5\u6307\u5357\uff0c\u5b83\u6db5\u76d6ES\u57fa\u7840\u77e5\u8bc6\u70b9\u548c\u9762\u8bd5\u8fc7\u7a0b\u4e2d\u5e38\u89c1\u95ee\u9898\u3002\u5185\u5bb9\u5305\u62ecES\u7684\u529f\u80fd\u7279\u6027\u4ecb\u7ecd\uff08\u5982\u5206\u5e03\u5f0f\u67b6\u6784\u3001\u5168\u6587\u641c\u7d22\u3001\u6570\u636e\u5206\u6790\u7b49\uff09\u3001\u4e3b\u8981\u7684\u4f7f\u7528\u573a\u666f\u63cf\u8ff0\u3001\u4e0e\u5176\u4ed6\u641c\u7d22\u5f15\u64ce\u7684\u5bf9\u6bd4\uff08Lucene\u548cSolr\uff09\u3001\u4ee5\u53caES\u7684\u57fa\u672c\u6982\u5ff5\u89e3\u91ca\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u63a2\u8ba8\u4e86ES\u7684\u9ad8\u7ea7\u7279\u6027\uff0c\u5982\u6620\u5c04\u3001DSL\u67e5\u8be2\u3001\u805a\u5408\u5206\u6790\u548c\u667a\u80fd\u641c\u7d22\u5efa\u8bae\u5668\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u8fd8\u5206\u4eab\u4e86\u5173\u4e8e\u6570\u636e\u7d22\u5f15\u4f18\u5316\u7684\u5b9e\u6218\u6280\u5de7\u548c\u7b56\u7565\uff0c\u63d0\u4f9b\u4e86\u5199\u4f18\u5316\u3001\u8bfb\u4f18\u5316\u548c\u7d22\u5f15\u91cd\u5efa\u7684\u65b9\u6848\uff0c\u8fd9\u4e9b\u65b9\u6848\u5bf9ES\u6570\u636e\u5b58\u50a8\u548c\u67e5\u8be2\u7684\u6027\u80fd\u6709\u663e\u8457\u5f71\u54cd\uff0c\u6700\u540e\u8fd8\u5bf9Deep Paging\u6027\u80fd\u95ee\u9898\u63d0\u4f9b\u4e86\u89e3\u51b3\u65b9\u6cd5\u3002\u5bf9\u6b63\u5728\u51c6\u5907\u9762\u8bd5\u6216\u8005\u5e0c\u671b\u5de9\u56faES\u77e5\u8bc6\u7684\u8bfb\u8005\u800c\u8a00\uff0c\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4e2a\u5b9d\u8d35\u7684\u8d44\u6e90\u3002"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/gAJFm3q5510PfRBe4F11PQ"},"\u300a\u4ec0\u4e48\u662fMySQL\u9501\uff1f\u6709\u54ea\u4e9b\u9501\u7c7b\u578b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5730\u4ecb\u7ecd\u4e86MySQL\u4e2d\u7684\u9501\u5b9a\u673a\u5236\u53ca\u5176\u7c7b\u578b\u3002\u8d77\u521d\u6982\u8ff0\u4e86\u9501\u7684\u4f5c\u7528\uff0c\u5373\u534f\u8c03\u591a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u8d44\u6e90\u7684\u5e76\u53d1\u8bbf\u95ee\uff0c\u5728\u6570\u636e\u5e93\u73af\u5883\u4e0b\uff0c\u9501\u5bf9\u4e8e\u4fdd\u6301\u4e8b\u52a1\u7684\u6b63\u786e\u6027\u4e0e\u4e00\u81f4\u6027\u81f3\u5173\u91cd\u8981\u3002\u4f5c\u8005\u660e\u786e\u533a\u5206\u4e86MySQL\u4e2d\u9501\u7684\u7ea7\u522b\uff0c\u4ece\u5168\u5c40\u9501\u3001\u8868\u9501\uff08\u8bfb\u9501\u3001\u5199\u9501\uff09\u5230\u5143\u6570\u636e\u9501\u3001\u610f\u5411\u9501\uff0c\u76f4\u5230\u884c\u9501\u7684\u591a\u79cd\u5f62\u5f0f\uff08\u8bb0\u5f55\u9501\u3001\u95f4\u9699\u9501\u548c\u4e34\u952e\u9501\uff09\u3002\u6587\u4e2d\u8fd8\u63a2\u8ba8\u4e86AUTO-INC\u9501\u7684\u4f5c\u7528\u548c\u76f8\u5173\u4f18\u5316\uff0c\u4e3e\u4f8b\u8bf4\u660e\u4e86\u5176\u5728INSERT\u64cd\u4f5c\u4e2d\u7684\u5e94\u7528\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u4e5f\u6d89\u53ca\u4e86\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u60c5\u51b5\u4f18\u5316\u9501\u7684\u4f7f\u7528\u4ee5\u53ca\u5982\u4f55\u907f\u514d\u7531\u9501\u4ea7\u751f\u7684\u6027\u80fd\u74f6\u9888\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u7406\u89e3MySQL\u7684\u5404\u79cd\u9501\u7c7b\u578b\u548c\u9501\u673a\u5236\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u4fe1\u606f\uff0c\u7279\u522b\u5bf9\u4e8e\u6570\u636e\u5e93\u7ba1\u7406\u5458\u548c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5e76\u53d1\u6570\u636e\u8bbf\u95ee\u95ee\u9898\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u5b9e\u7528\u4ef7\u503c\u3002"),(0,a.kt)("h2",{id:"-\u524d\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173"),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/m-Ae6dbFuW22u2xSDWcciw"},"Vue \u56e2\u961f\u6b63\u5f0f\u5f00\u6e90 Rolldown\uff1a\u57fa\u4e8e Rust \u7684\u8d85\u5feb JavaScrip \u6253\u5305\u5de5\u5177\uff01")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/MVR5rV2LkH8_GHCtP6SHug"},"\u6253\u9020\u8212\u9002\u7684vscode\u5f00\u53d1\u73af\u5883")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/pY4-RqqamTmPXnRPfw0hRA"},"\u76f8\u6bd4\u4e8e Node.js\uff0cDeno \u548c Bun \u5230\u5e95\u80fd\u5e26\u6765\u4ec0\u4e48")),(0,a.kt)("p",null,(0,a.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/yBTK4Rds28aJ88mVgkoYJA"},"MDH Weekly 122 - \u300a\u62db\u4eba\u300b")))}u.isMDXComponent=!0},7662:(e,t,n)=>{n.d(t,{Z:()=>p});const p=n.p+"assets/images/maxresdefault-5b23cca3601cf7ebe54f3cb5023d859a.jpg"}}]); \ No newline at end of file diff --git a/assets/js/7811d1e5.86244e40.js b/assets/js/7811d1e5.86244e40.js new file mode 100644 index 0000000000..da1b156d08 --- /dev/null +++ b/assets/js/7811d1e5.86244e40.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[7110],{49613:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var a=n(59496);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},m=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,p=e.originalType,l=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),c=s(n),h=r,k=c["".concat(l,".").concat(h)]||c[h]||u[h]||p;return n?a.createElement(k,o(o({ref:t},m),{},{components:n})):a.createElement(k,o({ref:t},m))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var p=n.length,o=new Array(p);o[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:r,o[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>i,toc:()=>s});var a=n(64778),r=(n(59496),n(49613));const p={slug:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},o=void 0,i={permalink:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-17/index.md",source:"@site/blogs/2024/2024-03-17/index.md",title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",description:"\ud83c\udf1f AI \u76f8\u5173",date:"2024-03-17T00:00:00.000Z",formattedDate:"March 17, 2024",tags:[],readingTime:45.52,hasTruncateMarker:!1,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},prevItem:{title:"\u7f6e\u9876\u5185\u5bb9",permalink:"/frontend-weekly/2024/welcome"},nextItem:{title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"}},l={authorsImageUrls:[void 0]},s=[{value:"\ud83c\udf1f AI \u76f8\u5173",id:"-ai-\u76f8\u5173",level:2},{value:"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173",id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173",id:"-\u540e\u7aef\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173",id:"-\u524d\u7aef\u76f8\u5173",level:2}],m={toc:s},c="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(c,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"-ai-\u76f8\u5173"},"\ud83c\udf1f AI \u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/QBORpQmZrumppLl81aWAxA"},"\u300a\u5357\u6d0b\u7406\u5de5\u53d1\u5e03\u591a\u6a21\u6001\u91d1\u878d\u4ea4\u6613Agent\uff0c\u5e73\u5747\u5229\u6da6\u63d0\u9ad836%\uff01\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u5357\u6d0b\u7406\u5de5\u5927\u5b66\u53d1\u5e03\u7684\u591a\u6a21\u6001\u91d1\u878d\u4ea4\u6613Agent\uff0c\u901a\u8fc7\u878d\u5408\u5927\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u548c\u591a\u6a21\u6001\u6570\u636e\u5904\u7406\uff0c\u63d0\u9ad8\u4e86\u91d1\u878d\u4ea4\u6613\u7684\u6548\u76ca\u3002\u4f20\u7edf\u57fa\u4e8e\u89c4\u5219\u7684\u4ea4\u6613\u7cfb\u7edf\u5728\u9002\u5e94\u5e02\u573a\u6ce2\u52a8\u65b9\u9762\u5b58\u5728\u4e0d\u8db3\uff0c\u800c\u57fa\u4e8e\u5f3a\u5316\u5b66\u4e60\u7684\u7cfb\u7edf\u867d\u7136\u9002\u5e94\u6027\u66f4\u597d\uff0c\u4f46\u5728\u5904\u7406\u591a\u6a21\u6001\u6570\u636e\u548c\u53ef\u89e3\u91ca\u6027\u65b9\u9762\u4ecd\u9762\u4e34\u6311\u6218\u3002\u8be5\u6587\u4e2d\u63d0\u51fa\u7684FinAgent\u662f\u4e00\u79cd\u5148\u8fdb\u7684\u591a\u6a21\u6001\u57fa\u7840\u4ee3\u7406\uff0c\u80fd\u591f\u7efc\u5408\u5206\u6790\u591a\u79cd\u5f62\u5f0f\u7684\u91d1\u878d\u6570\u636e\uff0c\u63d0\u4f9b\u7cbe\u786e\u7684\u5e02\u573a\u8d8b\u52bf\u5206\u6790\u548c\u51b3\u7b56\u652f\u6301\u3002\u5b9e\u9a8c\u8bc1\u660e\uff0c\u4f7f\u7528FinAgent\u8fdb\u884c\u91d1\u878d\u4ea4\u6613\u53ef\u4ee5\u5e73\u5747\u63d0\u9ad836%\u7684\u5229\u6da6\u3002\u8bba\u6587\u94fe\u63a5\uff1a",(0,r.kt)("a",{parentName:"p",href:"https://arxiv.org/pdf/2402.18485.pdf"},"https://arxiv.org/pdf/2402.18485.pdf")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/kek5xGP96UOJ3Rpfw3V-FQ"},"\u300a\u5927\u6a21\u578b\u63a8\u7406:A100/H100 \u592a\u8d35\uff0c\u4f55\u4e0d\u7528 4090?\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u5927\u6a21\u578b\u63a8\u7406\u65f6\uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u8003\u8651\u4f7f\u75284090\u663e\u5361\u3002\u76f8\u6bd4\u4e8eA100\u548cH100\u663e\u5361\uff0c4090\u5728\u6027\u4ef7\u6bd4\u4e0a\u66f4\u9ad8\uff0c\u5c24\u5176\u5728\u6781\u81f4\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u53ef\u4ee5\u8fbe\u5230H100\u76842\u500d\u6027\u80fd\u3002\u6587\u7ae0\u6307\u51fa\uff0cA100\u3001H100\u548c4090\u5728\u7b97\u529b\u65b9\u9762\u7684\u5dee\u8ddd\u5e76\u4e0d\u5927\uff0c\u6700\u5927\u7684\u533a\u522b\u5728\u901a\u4fe1\u548c\u5185\u5b58\u65b9\u9762\u3002\u7531\u4e8e\u5927\u6a21\u578b\u8bad\u7ec3\u4f7f\u7528\u9ad8\u6027\u80fd\u7684\u901a\u4fe1\uff0c4090\u901a\u4fe1\u6548\u7387\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u6b64\u5728\u5927\u6a21\u578b\u8bad\u7ec3\u4e2d\u5e76\u4e0d\u9002\u7528\u3002\u7136\u800c\uff0c\u5728\u63a8\u7406\uff08inference/serving\uff09\u65b9\u9762\uff0c4090\u5728\u6027\u4ef7\u6bd4\u4e0a\u6709\u4f18\u52bf\uff0c\u5c24\u5176\u662f\u76f8\u5bf9\u4e8eH100\u663e\u5361\u800c\u8a00\u3002\u6587\u7ae0\u8fd8\u63d0\u5230\u4e86GPU\u7684\u8bad\u7ec3\u6027\u80fd\u548c\u6210\u672c\u5bf9\u6bd4\uff0c\u4ee5\u53ca\u5927\u6a21\u578b\u8bad\u7ec3\u6240\u9700\u7684\u7b97\u529b\u548cGPU\u6570\u91cf\u7b49\u95ee\u9898\u3002\u8be6\u7ec6\u5185\u5bb9\u53ef\u53c2\u8003\u6587\u7ae0\u94fe\u63a5\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/tKVHsoR_opgBqtCMDHbv6Q"},"\u300a\u7cbe\u5ea6\u63d0\u5347!\u5357\u52a0\u5927\u7b49 | \u63d0\u51fa\u5206\u6cbbPrompt\u7b56\u7565\uff0c\u63d0\u5347LLM\u5206\u8fa8\u529b\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b97\u6cd5\u7684Prompt\u7b56\u7565\uff0c\u65e8\u5728\u63d0\u9ad8\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u7684\u5206\u8fa8\u529b\u3002\u73b0\u6709\u7684\u63d0\u793a\u7b56\u7565\u5728\u5904\u7406\u6d89\u53ca\u91cd\u590d\u5b50\u4efb\u52a1\u548c\u542b\u6709\u6b3a\u9a97\u6027\u5185\u5bb9\u7684\u4efb\u52a1\u65f6\u5b58\u5728\u4e00\u5b9a\u9650\u5236\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u7814\u7a76\u4eba\u5458\u63d0\u51fa\u4e86\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b97\u6cd5\u7684\u63d0\u793a\u7b56\u7565\uff0c\u5229\u7528\u5206\u6cbb\u7a0b\u5e8f\u6765\u5f15\u5bfcLLM\u7684\u6c42\u89e3\u8fc7\u7a0b\u3002\u8be5\u7b56\u7565\u5c06\u4efb\u52a1\u5212\u5206\u4e3a\u5b50\u95ee\u9898\u5e76\u5206\u522b\u6c42\u89e3\uff0c\u7136\u540e\u5408\u5e76\u5b50\u95ee\u9898\u7684\u7b54\u6848\u3002\u901a\u8fc7\u5b9e\u9a8c\u8bc1\u660e\uff0c\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u63d0\u5347\u6a21\u578b\u5728\u5927\u6574\u6570\u4e58\u6cd5\u3001\u5e7b\u89c9\u68c0\u6d4b\u548c\u65b0\u95fb\u9a8c\u8bc1\u7b49\u4efb\u52a1\u4e2d\u7684\u6027\u80fd\uff0c\u76f8\u6bd4\u4f20\u7edf\u63d0\u793a\u7b56\u7565\u5177\u6709\u66f4\u597d\u7684\u51c6\u786e\u7387\u548c\u6027\u80fd\u6307\u6807\u3002\u8bba\u6587\u5730\u5740\uff1a",(0,r.kt)("a",{parentName:"p",href:"https://arxiv.org/pdf/2402.05359.pdf"},"https://arxiv.org/pdf/2402.05359.pdf")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/sxgfJf4vxvaxhO5L7-Npwg"},"\u300a\u5f00\u6e90\u7248\u201cDevin\u201dAI\u7a0b\u5e8f\u5458\u70b8\u573a:\u81ea\u5df1\u5206\u6790\u80a1\u7968\u3001\u505a\u62a5\u8868\u3001\u5efa\u6a21\u578b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u4e2a\u57fa\u4e8eMetaGPT\u7684\u5f00\u6e90\u9879\u76eeData Interpreter\uff0c\u8be5\u9879\u76ee\u65e8\u5728\u5904\u7406\u6570\u636e\u5b9e\u65f6\u53d8\u5316\u3001\u4efb\u52a1\u4e4b\u95f4\u7684\u590d\u6742\u4f9d\u8d56\u5173\u7cfb\u3001\u6d41\u7a0b\u4f18\u5316\u9700\u6c42\u4ee5\u53ca\u6267\u884c\u7ed3\u679c\u53cd\u9988\u7684\u903b\u8f91\u4e00\u81f4\u6027\u7b49\u6311\u6218\u3002\u901a\u8fc7\u6f14\u793a\uff0c\u5c55\u793a\u4e86Data Interpreter\u5728\u5206\u6790\u80a1\u7968\u3001\u9884\u6d4b\u8461\u8404\u9152\u8d28\u91cf\u3001\u81ea\u52a8\u62a0\u56fe\u3001\u9884\u6d4b\u75be\u75c5\u8fdb\u5c55\u548c\u9884\u6d4b\u673a\u5668\u8fd0\u884c\u72b6\u6001\u7b49\u65b9\u9762\u7684\u80fd\u529b\u3002\u8be5\u9879\u76ee\u7531MetaGPT\u56e2\u961f\u4e0e\u591a\u6240\u9ad8\u6821\u5408\u4f5c\u63a8\u51fa\uff0c\u63d0\u4f9b\u4e86\u4e00\u79cd\u81ea\u4e3b\u8fdb\u884c\u6570\u636e\u5206\u6790\u548c\u5efa\u6a21\u7684\u5f00\u6e90\u5de5\u5177\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/n98IZHs7LTXMzzS3KmHvrA"},"\u300a\u3010\u539f\u521b\u3011\u4e00\u6587\u8bfb\u61c2RAG\u7684\u6765\u6e90\u3001\u53d1\u5c55\u548c\u524d\u6cbf\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u6280\u672f\uff0c\u8be5\u6280\u672f\u7ed3\u5408\u4e86\u68c0\u7d22\u548c\u751f\u6210\u8fc7\u7a0b\uff0c\u65e8\u5728\u63d0\u9ad8\u673a\u5668\u751f\u6210\u6587\u672c\u7684\u76f8\u5173\u6027\u3001\u51c6\u786e\u6027\u548c\u591a\u6837\u6027\u3002\u6587\u7ae0\u8be6\u7ec6\u89e3\u91ca\u4e86\u5e7b\u89c9\u95ee\u9898\u7684\u5b58\u5728\u4ee5\u53ca\u89e3\u51b3\u5e7b\u89c9\u95ee\u9898\u7684\u51e0\u79cd\u5e38\u89c1\u65b9\u6cd5\u3002RAG\u5229\u7528\u5916\u90e8\u6570\u636e\u6e90\u8fdb\u884c\u4fe1\u606f\u68c0\u7d22\uff0c\u5c06\u68c0\u7d22\u5230\u7684\u4fe1\u606f\u4f5c\u4e3a\u4e0a\u4e0b\u6587\u8f93\u5165\u5230\u751f\u6210\u6a21\u578b\u4e2d\uff0c\u4ece\u800c\u5e2e\u52a9\u751f\u6210\u6b63\u786e\u7684\u54cd\u5e94\u3002\u8ba8\u8bba\u4e86RAG\u7684\u6838\u5fc3\u90e8\u4ef6\uff0c\u5982\u5411\u91cf\u6570\u636e\u5e93\u3001\u67e5\u8be2\u68c0\u7d22\u548c\u91cd\u65b0\u6392\u5e8f\u3002\u540c\u65f6\u4ecb\u7ecd\u4e86RAG\u5728\u77e5\u8bc6\u56fe\u8c31\u548c\u6811\u7ed3\u6784\u65b9\u9762\u7684\u62d3\u5c55\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NoREsyLXNVk1aABtSkhBDA"},"\u300a\u4e07\u5b57\u957f\u6587\u89e3\u6790:\u5927\u6a21\u578b\u9700\u8981\u600e\u6837\u7684\u786c\u4ef6\u7b97\u529b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u5927\u6a21\u578b\u5728\u7b97\u529b\u3001\u5b58\u50a8\u3001\u901a\u4fe1\u7b49\u591a\u4e2a\u65b9\u9762\u4e0a\u786c\u4ef6\u8d44\u6e90\u7684\u6311\u6218\u548c\u74f6\u9888\u3002\u6587\u7ae0\u5206\u6790\u4e86\u4ee5Transformer\u7ed3\u6784\u4e3a\u6838\u5fc3\u7684\u5927\u6a21\u578b\u5728\u7b97\u529b\u74f6\u9888\u3001\u663e\u5b58\u74f6\u9888\u548c\u901a\u4fe1\u74f6\u9888\u65b9\u9762\u7684\u56f0\u5883\uff0c\u4ee5\u53ca\u5f53\u524d\u6240\u91c7\u53d6\u7684\u786c\u4ef6\u8d44\u6e90\u4f18\u5316\u6280\u672f\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u63d0\u4f9b\u4e86\u5bf9\u5927\u6a21\u578b\u53c2\u6570\u91cf\u548c\u7b97\u529b\u9700\u6c42\u7684\u91cf\u5316\u4f30\u7b97\uff0c\u4e3a\u9009\u62e9\u5408\u9002\u7684\u786c\u4ef6\u8bbe\u5907\u548c\u8bc4\u4f30\u8d44\u6e90\u9700\u6c42\u63d0\u4f9b\u4e86\u6307\u5bfc\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lbLOqiW-DoHq_S9qpYcbCQ"},"\u300a\u4ec0\u4e48\u662f\u597d\u7684\u5927\u6a21\u578b\u8bad\u7ec3\u6570\u636e?\u300b"),"\u3002\u672c\u6587\u57fa\u4e8eLilian Weng\u7684\u535a\u5ba2\uff0c\u8ba8\u8bba\u4e86\u5927\u6a21\u578b\u5982LLM\u5728\u8bad\u7ec3\u8fc7\u7a0b\u4e2d\u5bf9\u9ad8\u8d28\u91cf\u6570\u636e\u7684\u9700\u6c42\u3002\u8ba4\u4e3a\u9ad8\u8d28\u91cf\u6570\u636e\u6765\u6e90\u4e8e\u201c\u9ad8\u8d28\u91cf\u4eba\u7c7b\u201d\u4ea7\u751f\u7684\u6807\u6ce8\u6570\u636e\uff0c\u5e76\u5f3a\u8c03\u4e86\u6570\u636e\u5904\u7406\u7684\u91cd\u8981\u6027\uff0c\u63d0\u5230\u4e86\u6570\u636e\u6807\u6ce8\u3001\u8d28\u91cf\u63a7\u5236\u548c\u9519\u8bef\u4fee\u6b63\u7684\u91cd\u8981\u6b65\u9aa4\u3002\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u7528\u4e8e\u8bc4\u4f30\u6570\u636e\u8d28\u91cf\u7684\u591a\u79cd\u65b9\u6cd5\uff0c\u5982Influence Functions\u548cNoisy Cross-Validation\uff0c\u5e76\u63d0\u51fa\u4e86\u4e13\u6ce8\u4e8e\u201c\u642d\u5efa\u9ad8\u8d28\u91cf\u7684\u6570\u636e\u6807\u6ce8pipeline\u201d\u7684\u4f01\u4e1a\u65b9\u5411\u3002\u6700\u540e\u6307\u51fa\uff0c\u5728AI\u65f6\u4ee3\u5927\u91cf\u4ea7\u51fa\u7684\u6570\u636e\u4e2d\u7ef4\u62a4\u6570\u636e\u8d28\u91cf\uff0c\u662f\u4e00\u4e2a\u503c\u5f97\u5173\u6ce8\u7684\u6311\u6218\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dA757HASxJPYuAbRZ7KvUQ"},"\u300a\u8bfb\u8fc7\u7684\u6700\u767d\u8bdd\u8bb2\u6e05\u695aRAG\u539f\u7406\u7684\u6587\u7ae0\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u76f4\u89c2\u5730\u9610\u91ca\u4e86\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u7684\u6982\u5ff5\u548c\u5de5\u4f5c\u539f\u7406\uff0c\u5b83\u662f\u4e00\u79cd\u7ed3\u5408\u68c0\u7d22\u548c\u751f\u6210\u7684\u95ee\u7b54\u7cfb\u7edf\u3002\u8be5\u7cfb\u7edf\u9996\u5148\u901a\u8fc7\u68c0\u7d22\u6b65\u9aa4\u627e\u5230\u4e0e\u7528\u6237\u95ee\u9898\u6700\u76f8\u5173\u7684\u77e5\u8bc6\u5e93\u5185\u5bb9\uff0c\u7136\u540e\u5c06\u8fd9\u4e9b\u5185\u5bb9\u4e0e\u95ee\u9898\u5171\u540c\u8f93\u5165\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u4f8b\u5982ChatGPT\uff09\u4ee5\u751f\u6210\u7b54\u6848\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u5d4c\u5165\u6a21\u578b\u5bf9\u77e5\u8bc6\u5e93\u6587\u672c\u8fdb\u884c\u7d22\u5f15\uff0c\u4ee5\u4fbf\u534f\u52a9\u8bed\u8a00\u6a21\u578b\u8fdb\u884c\u7cbe\u786e\u7684\u68c0\u7d22\u3002\u6b64\u5916\uff0c\u5b83\u8fd8\u63a2\u8ba8\u4e86\u8bed\u4e49\u641c\u7d22\u80cc\u540e\u7684\u6838\u5fc3\u539f\u5219\u548c\u6280\u672f\u7ec6\u8282\u70b9\uff0c\u5982\u4f55\u901a\u8fc7\u5d4c\u5165\u627e\u5230\u4e0e\u7528\u6237\u8f93\u5165\u6700\u5339\u914d\u7684\u77e5\u8bc6\uff0c\u4ee5\u53ca\u5982\u4f55\u683c\u5f0f\u5316\u6587\u6863\u4ee5\u4f9b\u8bed\u8a00\u6a21\u578b\u4f7f\u7528\uff0c\u4ee5\u4fbf\u83b7\u5f97\u66f4\u9ad8\u6548\u7684\u56de\u7b54\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://zhuanlan.zhihu.com/p/685794495"},"\u300aLLM\u63a8\u7406\u7b97\u6cd5\u7b80\u8ff0\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u7528\u4e8e\u63d0\u9ad8\u5927\u578b\u8bed\u8a00\u6a21\u578b(LLM)\u63a8\u7406\u6027\u80fd\u7684\u5173\u952e\u6280\u672f\u4e0e\u7b56\u7565\u3002\u5185\u5bb9\u6db5\u76d6\u663e\u5b58\u4f18\u5316\u65b9\u6cd5\uff0c\u5982KV Cache\u51cf\u5c11\u663e\u5b58\u6d6a\u8d39\u3001MQA\u548cGQA\u51cf\u5c11KV-Cache\u6570\u91cf\u3001Page Attention\u8fdb\u884c\u663e\u5b58\u7ba1\u7406\uff0c\u4ee5\u53ca\u63d0\u9ad8\u63a8\u7406\u901f\u5ea6\u7684FlashAttention\u6539\u8fdb\u3002\u6587\u7ae0\u8fd8\u63a2\u8ba8\u4e86\u7b97\u5b50\u878d\u5408\u6280\u672f\uff0c\u6bd4\u5982FasterTransformer\u548cDeepSpeed Inference\u7684\u5e94\u7528\uff0c\u4ee5\u53ca\u8c03\u5ea6\u4f18\u5316\u7b56\u7565\u5982Async Serving\u548cDynamic Batch\uff0c\u6700\u540e\u4ecb\u7ecd\u4e86\u7528\u4e8e\u5904\u7406\u5927\u6a21\u578b\u7684\u5206\u5e03\u5f0f\u5e76\u884c\u6280\u672f\u3002\u8fd9\u4e9b\u4f18\u5316\u624b\u6bb5\u80fd\u663e\u8457\u63d0\u9ad8LLM\u63a8\u7406\u8fc7\u7a0b\u4e2d\u7684\u6027\u80fd\u4e0e\u6548\u7387\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/V8Tz5X81FlOva9B6bCprqg"},"\u300a\u6570\u5b66\u63a8\u7406\u589e\u5f3a!\u5fae\u8f6f | \u63d0\u51fa\u6570\u636e\u5408\u6210\u6846\u67b6:KPDDS\uff0c\u5fae\u8c03Mistral-7B\u6027\u80fd\u8d8534B\u6a21\u578b!\u300b"),"\u3002\u5fae\u8f6f\u7684\u7814\u7a76\u56e2\u961f\u4e3a\u63d0\u5347\u5927\u578b\u8bed\u8a00\u6a21\u578b(Large Language Models, LLMs)\u5728\u6570\u5b66\u63a8\u7406\u4efb\u52a1\u7684\u6027\u80fd\uff0c\u63d0\u51fa\u4e86\u5173\u952e\u70b9\u9a71\u52a8\u7684\u6570\u636e\u5408\u6210(KPDDS)\u6846\u67b6\u3002KPDDS\u5229\u7528\u771f\u5b9e\u6570\u636e\u6e90\u4e2d\u7684\u5173\u952e\u70b9\u548c\u793a\u4f8b\u5bf9\u751f\u6210\u9ad8\u8d28\u91cf\u95ee\u7b54\u5bf9\u6765\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u3002\u7814\u7a76\u8005\u57fa\u4e8e\u6b64\u6846\u67b6\u521b\u5efa\u4e86KPMath\u6570\u636e\u96c6\uff0c\u8fdb\u4e00\u6b65\u7ed3\u5408\u63a8\u7406\u5bc6\u96c6\u578b\u6570\u636e\u5f62\u6210KPMath-Plus\u6570\u636e\u96c6\u3002\u5728MATH\u6d4b\u8bd5\u96c6\u4e0a\uff0c\u5fae\u8c03\u540e\u7684Mistral-7B\u6a21\u578b\u8fbe\u5230\u4e8639.3%\u7684\u96f6\u6837\u672c\u901a\u8fc7\u7387\uff0c\u8d85\u8d8a\u4e86\u6570\u91cf\u66f4\u591a\u768434B\u6a21\u578b\uff0c\u8bc1\u660e\u4e86KPDDS\u7684\u6709\u6548\u6027\u4e0e\u521b\u65b0\u6027\u3002\u8fd9\u4e00\u6210\u679c\u6807\u5fd7\u7740LLMs\u5728\u6570\u5b66\u63a8\u7406\u65b9\u9762\u7684\u6027\u80fd\u5f97\u5230\u663e\u8457\u63d0\u5347\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/QkkYAilf4_XZyBRqSIEL2Q"},"\u300a\u9996\u4e2aAI\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u4e0a\u7ebf!\u5df2\u901a\u8fc7\u516c\u53f8\u9762\u8bd5\u62a2\u7a0b\u5e8f\u5458\u996d\u7897\uff0c\u534e\u4eba\u521b\u59cb\u56e2\u961f\u624b\u63e110\u5757IOI\u91d1\u724c\u300b"),"\u3002\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u4e86\u7531\u534e\u4eba\u521b\u7acb\u7684Cognition AI\u516c\u53f8\u5f00\u53d1\u51fa\u6765\u7684\u9996\u4e2a\u4eba\u5de5\u667a\u80fd\u8f6f\u4ef6\u5de5\u7a0b\u5e08Devin\u3002\u4e0e\u73b0\u6709GPT-4\u7b49\u6a21\u578b\u4e0d\u540c\uff0cDevin\u80fd\u591f\u72ec\u7acb\u5b8c\u6210\u590d\u6742\u7684\u7f16\u7a0b\u4efb\u52a1\uff0c\u5e76\u5df2\u6210\u529f\u901a\u8fc7\u4eba\u5de5\u667a\u80fd\u516c\u53f8\u7684\u9762\u8bd5\u548c\u5728\u81ea\u7531\u804c\u4e1a\u5e73\u53f0Upwork\u4e0a\u63a5\u5355\u3002\u5f97\u76ca\u4e8eCognition AI\u5728\u957f\u671f\u63a8\u7406\u548c\u89c4\u5212\u65b9\u9762\u7684\u8fdb\u6b65\uff0cDevin\u5728\u505a\u51b3\u7b56\u548c\u6267\u884c\u4efb\u52a1\u65f6\uff0c\u80fd\u56de\u60f3\u76f8\u5173\u4e0a\u4e0b\u6587\u3001\u968f\u65f6\u95f4\u5b66\u4e60\u5e76\u4fee\u590d\u9519\u8bef\u3002\u8fd9\u6807\u5fd7\u7740\u4eba\u5de5\u667a\u80fd\u5728\u7406\u89e3\u771f\u5b9e\u4e16\u754c\u8f6f\u4ef6\u5de5\u7a0b\u95ee\u9898\u65b9\u9762\u53d6\u5f97\u4e86\u7a81\u7834\uff0c\u4e3aAI\u9886\u57df\u8fc8\u5411\u66f4\u9ad8\u5c42\u7ea7\u7684\u81ea\u52a8\u5316\u53ca\u76d1\u7763\u6027\u5de5\u4f5c\u5f00\u8f9f\u9053\u8def\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/q_lgeiXFzTU4WEt9wpUG3w"},"\u300a\u5411\u6570\u5b57\u4e16\u754cAGI\u8fc8\u8fdb!\u667a\u80fd\u4f53\u5df2\u7ecf\u4ece\u5934\u5f00\u73a9\u300c\u8352\u91ce\u5927\u9556\u5ba2 2\u300d\u4e86\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528Cradle\u8fd9\u4e00\u901a\u7528\u8ba1\u7b97\u673a\u63a7\u5236\u667a\u80fd\u4f53\u6846\u67b6\u8fdb\u884cAI\u7684\u7814\u7a76\u4e0e\u5e94\u7528\uff0c\u5728\u65e0\u9700\u5185\u90e8API\u652f\u6301\u4e0b\u63a7\u5236\u952e\u76d8\u548c\u9f20\u6807\u4ee5\u53ca\u4e0e\u5404\u7c7b\u8f6f\u4ef6\u4ea4\u4e92\u3002\u6587\u7ae0\u6765\u6e90\u4e8e\u5317\u4eac\u667a\u6e90\u4eba\u5de5\u667a\u80fd\u7814\u7a76\u9662\u3001\u65b0\u52a0\u5761\u5357\u6d0b\u7406\u5de5\u5927\u5b66\u548c\u5317\u4eac\u5927\u5b66\u7684\u8054\u5408\u7814\u7a76\u3002Cradle\u7531\u516d\u5927\u6a21\u5757\u7ec4\u6210\uff0c\u5305\u62ec\u4fe1\u606f\u6536\u96c6\u3001\u81ea\u6211\u53cd\u601d\u3001\u4efb\u52a1\u63a8\u65ad\u3001\u6280\u80fd\u7ba1\u7406\u3001\u884c\u52a8\u8ba1\u5212\u548c\u8bb0\u5fc6\u6a21\u5757\u3002\u8fd9\u4e9b\u6a21\u5757\u8ba9\u667a\u80fd\u4f53\u80fd\u591f\u81ea\u4e3b\u8fdb\u884c\u51b3\u7b56\u548c\u4efb\u52a1\u6267\u884c\u3002\u7814\u7a76\u56e2\u961f\u901a\u8fc7\u5c06Cradle\u90e8\u7f72\u4e8e\u300a\u8352\u91ce\u5927\u9556\u5ba2 2\u300b\u8fd9\u4e00\u590d\u6742\u76843A\u6e38\u620f\u4e2d\u8bc1\u660e\u5176\u901a\u7528\u6027\uff0cCradle\u80fd\u591f\u81ea\u4e3b\u5b8c\u6210\u6e38\u620f\u4e3b\u7ebf\u548c\u63a2\u7d22\u5f00\u653e\u4e16\u754c\u3002\u667a\u80fd\u4f53\u7684\u8fd9\u79cd\u901a\u7528\u80fd\u529b\u6807\u5fd7\u7740\u667a\u80fd\u4f53\u7814\u7a76\u5411\u901a\u7528\u4eba\u5de5\u667a\u80fd\uff08AGI\uff09\u8fc8\u8fdb\u7684\u91cd\u8981\u4e00\u6b65\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/U2472bnEvCE9lMPP-z0ysw"},"\u300a\u6df1\u5165\u6d45\u51fa LangChain \u4e0e\u667a\u80fd Agent:\u6784\u5efa\u4e0b\u4e00\u4ee3 AI \u52a9\u624b\u300b"),"\u3002\u6587\u7ae0\u6df1\u5165\u8bb2\u89e3\u4e86LangChain\u5de5\u5177\u7bb1\u53ca\u5176\u5982\u4f55\u8d4b\u80fd\u667a\u80fdAgent\uff0c\u4ee5\u6784\u5efa\u66f4\u52a0\u667a\u80fd\u7684AI\u52a9\u624b\u3002LangChain\u5229\u7528\u5927\u578b\u8bed\u8a00\u6a21\u578b\u5982GPT-4\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f00\u6e90\u8f6f\u4ef6\u6846\u67b6\uff0c\u53ef\u52a9\u529b\u5f00\u53d1\u8005\u642d\u5efa\u57fa\u4e8e\u8bed\u8a00\u6a21\u578b\u7684\u5e94\u7528\u3002\u5b83\u63d0\u4f9b\u4e86\u516d\u5927\u7c7b\u7ec4\u4ef6\uff0c\u5982\u6a21\u578b\u3001\u63d0\u793a\u6a21\u677f\u3001\u7d22\u5f15\u3001\u6587\u6863\u52a0\u8f7d\u5668\u3001\u6587\u672c\u5206\u5272\u5668\u548c\u5411\u91cf\u5b58\u50a8\uff0c\u8ba9GPT-4\u7b49\u6a21\u578b\u4e0d\u4ec5\u80fd\u5904\u7406\u8bed\u8a00\uff0c\u8fd8\u80fd\u4e0e\u5916\u90e8API\u4e92\u52a8\u3001\u7ba1\u7406\u7528\u6237\u4e0a\u4e0b\u6587\u3002\u6587\u7ae0\u4ee5\u6784\u5efa\u4eba\u8138\u6280\u672f\u95ee\u9898\u6392\u67e5\u52a9\u624b\u4e3a\u4f8b\uff0c\u5c55\u793a\u5982\u4f55\u8fd0\u7528LangChain\u6765\u534f\u52a9\u95ee\u9898\u8bca\u65ad\u4e0e\u667a\u80fd\u4ea4\u4e92\uff0c\u671d\u5411\u81ea\u4e3b\u3001\u9ad8\u6548\u7684\u667a\u80fd\u5e94\u7528\u53d1\u5c55\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/AAkITPRodLzvl61oALEI2Q"},"\u300a\u4f7f\u7528\u96f6\u4e00\u4e07\u7269 200K \u6a21\u578b\u548c Dify \u5feb\u901f\u642d\u5efa\u6a21\u578b\u5e94\u7528\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u4f7f\u7528\u96f6\u4e00\u4e07\u7269\u7684200K\u6a21\u578b\u548cDify\uff08LLM IDE\uff09\u5feb\u901f\u6784\u5efa\u6a21\u578b\u5e94\u7528\u7a0b\u5e8f\u3002\u4f5c\u8005\u9996\u5148\u5bf9\u4e00\u4e2a\u673a\u5668\u5b66\u4e60\u7535\u5b50\u4e66\u8fdb\u884c\u7ffb\u8bd1\uff0c\u5e76\u5206\u4eab\u4e86\u6e90\u4ee3\u7801\uff0c\u7136\u540e\u5f15\u5bfc\u8bfb\u8005\u5982\u4f55\u7533\u8bf7\u548c\u914d\u7f6e\u96f6\u4e00\u4e07\u7269\u6a21\u578bAPI\u3002\u968f\u540e\uff0c\u4f5c\u8005\u8bf4\u660e\u4e86\u5982\u4f55\u4f7f\u7528Dify IDE\u5feb\u901f\u642d\u5efa\u548c\u8c03\u8bd5\u6a21\u578b\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528Golang\u548cAI\u6a21\u578b\u81ea\u52a8\u5316\u7535\u5b50\u4e66\u7684\u7ffb\u8bd1\u8fc7\u7a0b\u3002\u6700\u540e\uff0c\u4f5c\u8005\u603b\u7ed3\u4e86\u81ea\u52a8\u7ffb\u8bd1\u7a0b\u5e8f\u7684\u6784\u5efa\u8fc7\u7a0b\u5e76\u5c55\u793a\u4e86\u6279\u91cf\u7ffb\u8bd1\u5185\u5bb9\u7684\u65b9\u6cd5\u3002\u6574\u7bc7\u6587\u7ae0\u4e0d\u4ec5\u662f\u4f7f\u7528Dify\u7684\u5b9e\u64cd\u6307\u5357\uff0c\u8fd8\u63d0\u4f9b\u4e86\u4e00\u79cd\u6548\u7387\u5316\u3001\u81ea\u52a8\u5316\u5904\u7406\u6587\u672c\u5185\u5bb9\u7684\u793a\u4f8b\uff0c\u9002\u5408\u90a3\u4e9b\u5728\u5bfb\u627e\u5feb\u901f\u5f00\u53d1\u548c\u96c6\u6210\u5927\u8bed\u8a00\u6a21\u578b\u5230\u5e94\u7528\u4e2d\u7684\u5f00\u53d1\u8005\u53c2\u8003\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/-9H0mLnvebzaLMaI6EKB6g"},"\u300a\u4e00\u6587\u770b\u5b8c\u591a\u6a21\u6001:\u4ece\u89c6\u89c9\u8868\u5f81\u5230\u591a\u6a21\u6001\u5927\u6a21\u578b\u300b"),"\u3002\u672c\u6587\u4e3a\u8bfb\u8005\u7cfb\u7edf\u68b3\u7406\u4e86\u56fe\u6587\u591a\u6a21\u6001\u4e0e\u591a\u6a21\u6001\u5927\u6a21\u578b\u9886\u57df\u7684\u53d1\u5c55\uff0c\u5c24\u5176\u805a\u7126\u5728\u89c6\u89c9\u8868\u5f81\u548c\u89c6\u89c9\u4e0e\u6587\u672c\u878d\u5408\u65b9\u6cd5\u4e0a\u3002\u6587\u7ae0\u4ece\u5377\u79ef\u795e\u7ecf\u7f51\u7edc\uff08CNN\uff09\u53ca\u5176\u9884\u8bad\u7ec3\u65b9\u6cd5\u5f00\u59cb\u8bb2\u8d77\uff0c\u4ece\u56fe\u50cf\u5904\u7406\u7684\u89c6\u89d2\u4ecb\u7ecd\u4e86\u591a\u6a21\u6001\u878d\u5408\u7684\u521d\u671f\u65b9\u6cd5\uff0c\u5982LXMERT\u3001VL-BERT\u548cUNITER\u7b49\u3002\u8fdb\u4e00\u6b65\uff0c\u6587\u7ae0\u8bba\u8ff0\u4e86Vision Transformer\uff08ViT\uff09\u53ca\u5176\u9884\u8bad\u7ec3\u65b9\u6848\u5982MAE\u548cBEIT\uff0c\u4ee5\u53ca\u57fa\u4e8eViT\u7684\u591a\u6a21\u6001\u5bf9\u9f50\u4e0e\u9884\u8bad\u7ec3\u6280\u672f\uff0c\u5982CLIP\u548cVILT\u7b49\u3002\u4f5c\u8005\u901a\u8fc7\u4e30\u5bcc\u7684\u793a\u4f8b\u548c\u5bf9\u6bd4\uff0c\u4f7f\u8bfb\u8005\u80fd\u591f\u7406\u89e3\u8fd9\u4e9b\u6a21\u578b\u5728\u7ed3\u6784\u548c\u529f\u80fd\u4e0a\u7684\u4e0d\u540c\u4e0e\u8054\u7cfb\uff0c\u4e3a\u8fdb\u4e00\u6b65\u7814\u7a76\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u8d44\u6e90\u548c\u89c6\u89d2\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/k7b55PKdLA622G6Qb5Q0hA"},"\u300a\u6d59\u5927&\u4e2d\u79d1\u9662\u8ba9Agent\u5b66\u4f1a\u81ea\u6211\u8fdb\u5316\uff0c\u73a9\u5fb7\u5dde\u6251\u514b\u5fc3\u673a\u5c3d\u663e\u300b"),"\u3002Wenqi Zhang\u7b49\u7814\u7a76\u8005\u4ecb\u7ecd\u4e86\u540d\u4e3aAgent-Pro\u7684AI\u667a\u80fd\u4f53\uff0c\u5b83\u4f7f\u7528\u5927\u6a21\u578b(GPT-4)\u4e3a\u57fa\u7840\uff0c\u914d\u5408\u81ea\u6211\u4f18\u5316\u7684\u7b56\u7565\uff0c\u80fd\u591f\u8fd0\u7528\u865a\u5f20\u58f0\u52bf\u3001\u4e3b\u52a8\u653e\u5f03\u7b49\u590d\u6742\u7b56\u7565\u73a9\u8f6c\u5fb7\u5dde\u6251\u514b\u548c21\u70b9\u7b49\u975e\u5b8c\u7f8e\u4fe1\u606f\u535a\u5f08\u6e38\u620f\u3002Agent-Pro\u7684\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u81ea\u6211\u8fdb\u5316\uff0c\u9002\u5e94\u590d\u6742\u548c\u52a8\u6001\u7684\u6e38\u620f\u73af\u5883\uff0c\u5e76\u901a\u8fc7\u7b56\u7565\u5c42\u9762\u7684\u53cd\u601d\u548c\u4e16\u754c\u6a21\u578b\u7684\u4f18\u5316\u6765\u63d0\u9ad8\u81ea\u5df1\u7684\u8868\u73b0\u3002\u8be5\u7814\u7a76\u5c55\u793a\u4e86AI\u5728\u535a\u5f08\u9886\u57df\u7684\u8fdb\u6b65\uff0c\u540c\u65f6\u4e3a\u89e3\u51b3\u591aagent\u73b0\u5b9e\u4e16\u754c\u95ee\u9898\u63d0\u4f9b\u4e86\u65b0\u7b56\u7565\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZG3CuhZisI26taz4FQrdPg"},"\u300a\u9762\u5411\u5de5\u4e1a\u7ea7\u63a8\u8350!\u201c\u5c0f\u201dLLM\u4e5f\u80fd\u505a\u597d\u63a8\u8350\u7cfb\u7edf\u300b"),"\u3002\u672c\u6587\u7531\u8682\u8681\u96c6\u56e2AI\u521b\u65b0\u7814\u53d1\u90e8\u95e8NextEvo\u64b0\u5199\uff0c\u4ecb\u7ecd\u4e86\u4ed6\u4eec\u7684\u8bba\u6587\u300aCan Small Language Models be Good Reasoners for Sequential Recommendation?\u300b\u83b7\u5f97WWW 2024 (Oral)\u5f55\u7528\u3002\u6587\u7ae0\u9488\u5bf9\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u5728\u63a8\u8350\u7cfb\u7edf\u5e94\u7528\u65f6\u4ee3\u4ef7\u9ad8\u6602\u7684\u95ee\u9898\uff0c\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3aSLIM\u7684\u57fa\u4e8e\u84b8\u998f\u7684\u5927\u6a21\u578b\u63a8\u8350\u6846\u67b6\u3002SLIM\u901a\u8fc7\u77e5\u8bc6\u84b8\u998f\u6280\u672f\uff0c\u5c06\u5927\u6a21\u578b\u7684\u77e5\u8bc6\u548c\u63a8\u7406\u80fd\u529b\u8fc1\u79fb\u5230\u8f83\u5c0f\u7684\u6a21\u578b\u4e0a\uff0c\u4ece\u800c\u8fbe\u5230\u7528\u66f4\u5c11\u53c2\u6570\u5b9e\u73b0\u9ad8\u6548\u63a8\u8350\u7684\u6548\u679c\u3002\u8bba\u6587\u5f3a\u8c03SLIM\u5728\u5904\u7406\u957f\u5c3e\u7269\u54c1\u548c\u65b0\u7528\u6237\u63a8\u8350\u7684\u4f18\u52bf\uff0c\u6539\u8fdb\u4e86\u4f20\u7edf\u57fa\u4e8e\u4ea4\u4e92\u6570\u636e\u7684\u63a8\u8350\u7cfb\u7edf\u504f\u5dee\u95ee\u9898\uff0c\u5e76\u5728\u4fdd\u6301\u63a8\u8350\u51c6\u786e\u5ea6\u548c\u53ef\u89e3\u91ca\u6027\u7684\u540c\u65f6\u964d\u4f4e\u8d44\u6e90\u6d88\u8017\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/P7gOETO-EG3Ha7WjGs6Szg"},"\u300aAIOps \u667a\u80fd\u8fd0\u7ef4:\u6709\u6ca1\u6709\u6bd4\u4e13\u5bb6\u7ecf\u9a8c\u66f4\u4f18\u96c5\u7684\u9519/\u6162\u8c03\u7528\u5206\u6790\u5de5\u5177?\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u963f\u91cc\u4e91\u5e94\u7528\u5b9e\u65f6\u76d1\u63a7\u670d\u52a1 ARMS \u6700\u65b0\u63a8\u51fa\u7684\u9519/\u6162 Trace \u5206\u6790\u529f\u80fd\u3002\u6b64\u529f\u80fd\u4e0d\u4f9d\u8d56\u4e13\u5bb6\u7ecf\u9a8c\uff0c\u80fd\u5bf9\u6bd4\u5206\u6790\u9519/\u6162 Trace \u548c\u6b63\u5e38 Trace \u7684\u6bcf\u4e2a\u7ef4\u5ea6\uff0c\u4ece\u800c\u5feb\u901f\u5b9a\u4f4d\u95ee\u9898\u6839\u6e90\u3002\u9488\u5bf9\u751f\u4ea7\u73af\u5883\u4e0b\u8c03\u7528\u65f6\u5ef6\u548c\u9519\u8bef\u8c03\u7528\u7684\u591a\u79cd\u56e0\u7d20\uff08\u5982\u6d41\u91cf\u4e0d\u5747\u3001\u5355\u673a\u6545\u969c\u7b49\uff09\uff0cARMS \u901a\u8fc7\u5bf9\u9519/\u6162 Trace \u548c\u6b63\u5e38 Trace \u7684\u5bf9\u6bd4\uff0c\u5e2e\u52a9\u7528\u6237\u53d1\u73b0\u5f02\u5e38\u7684\u5171\u540c\u7279\u5f81\uff0c\u4ece\u800c\u5b9a\u4f4d\u5230\u5177\u4f53\u95ee\u9898\u3002\u8fd9\u4e2a\u5de5\u5177\u63d0\u4f9b\u4e86\u4e00\u79cd\u4f18\u4e8e\u4f20\u7edf\u4e13\u5bb6\u7ecf\u9a8c\u7684\u5feb\u901f\u3001\u6709\u6548\u8bca\u65ad\u7cfb\u7edf\u95ee\u9898\u7684\u65b9\u6cd5\uff0c\u5e76\u4e14\u9644\u6709\u6700\u4f73\u5b9e\u8df5\u6848\u4f8b\u3002\u6587\u7ae0\u6700\u540e\u63d0\u4f9b\u4e86\u514d\u767b\u5f55\u7684 demo \u4f53\u9a8c\u94fe\u63a5\uff0c\u5f15\u5bfc\u7528\u6237\u4e86\u89e3\u548c\u4f7f\u7528\u8be5\u529f\u80fd\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/9RaOOrroywQKnOhanBApsA"},"\u300aCUDA\u7f16\u7a0b\u4f18\u5316\u65b9\u6cd5\u2014\u2014Memory coalescing\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9CUDA\u7f16\u7a0b\u4e2d\u7684\u5185\u5b58\u5408\u5e76\u6280\u672f\u2014\u2014 Memory coalescing\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\u3002\u6587\u7ae0\u9996\u5148\u89e3\u91ca\u4e86\u5168\u5c40\u5185\u5b58\u7684\u7279\u70b9\u4ee5\u53ca\u4e3a\u4f55\u8bbf\u95ee\u901f\u5ea6\u6162\uff0c\u5e76\u9610\u8ff0\u4e86Memory coalescing\u7684\u76ee\u7684\u662f\u901a\u8fc7\u5408\u5e76\u5185\u5b58\u8bbf\u95ee\u64cd\u4f5c\u6765\u6709\u6548\u5730\u5229\u7528\u5e26\u5bbd\u3002\u901a\u8fc7\u5bf9\u591a\u7ef4\u6570\u7ec4\u7684\u5b58\u50a8\u65b9\u5f0f\u53ca\u8bbf\u95ee\u6a21\u5f0f\u7684\u89e3\u6790\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u8bb2\u89e3\u4e86Memory coalescing\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\uff0c\u5982\u4f55\u5728\u591a\u7ef4\u6570\u7ec4\u8bbf\u95ee\u548c\u77e9\u9635\u4e58\u6cd5\u4e2d\u5b9e\u73b0\u5185\u5b58\u8bbf\u95ee\u7684\u5408\u5e76\u3002\u6700\u540e\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4f18\u5316\u7b56\u7565\uff0c\u4ee5\u6539\u8fdb\u8ba1\u7b97\u7684\u5185\u5b58\u8bbf\u95ee\u6a21\u5f0f\uff0c\u5e76\u63d0\u9ad8CUDA\u5185\u5b58\u4f20\u8f93\u7684\u6548\u7387\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/b6D-vipDxKtlyocbxTObVQ"},"\u300a\u6269\u6563\u6a21\u578b\u5982\u4f55\u6784\u5efa\u65b0\u4e00\u4ee3\u51b3\u7b56\u667a\u80fd\u4f53?\u8d85\u8d8a\u81ea\u56de\u5f52\uff0c\u540c\u65f6\u751f\u6210\u957f\u5e8f\u5217\u89c4\u5212\u8f68\u8ff9\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u6269\u6563\u6a21\u578b\u5728\u5f3a\u5316\u5b66\u4e60\u4e2d\u7684\u591a\u79cd\u5e94\u7528\u573a\u666f\uff0c\u63a2\u8ba8\u4e86\u5982\u4f55\u8d85\u8d8a\u4f20\u7edf\u7684\u81ea\u56de\u5f52\u65b9\u6cd5\uff0c\u540c\u65f6\u751f\u6210\u957f\u5e8f\u5217\u89c4\u5212\u8f68\u8ff9\u6765\u6a21\u4eff\u4eba\u7c7b\u7684\u51b3\u7b56\u8fc7\u7a0b\u3002\u4e0a\u6d77\u4ea4\u901a\u5927\u5b66\u7684\u56e2\u961f\u6240\u4f5c\u7684\u7efc\u8ff0\u68b3\u7406\u4e86\u6269\u6563\u6a21\u578b\u5728\u5f3a\u5316\u5b66\u4e60\u4e2d\u7684\u8fd0\u7528\u5982\u8f68\u8ff9\u89c4\u5212\u3001\u7b56\u7565\u8868\u5f81\u3001\u6570\u636e\u5408\u6210\uff0c\u53ca\u5176\u89e3\u51b3\u957f\u5e8f\u5217\u89c4\u5212\u8bef\u5dee\u7d2f\u79ef\u3001\u7b56\u7565\u8868\u8fbe\u80fd\u529b\u53d7\u9650\u548c\u6570\u636e\u7a00\u7f3a\u7b49\u95ee\u9898\u7684\u5de8\u5927\u6f5c\u529b\u3002\u6700\u7ec8\uff0c\u6587\u7ae0\u5bf9\u6269\u6563\u6a21\u578b\u672a\u6765\u7684\u53d1\u5c55\u65b9\u5411\u8fdb\u884c\u4e86\u5c55\u671b\uff0c\u63d0\u51fa\u4e86\u751f\u6210\u5f0f\u4eff\u771f\u73af\u5883\u3001\u52a0\u5165\u5b89\u5168\u7ea6\u675f\u3001\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u53ca\u7ec4\u5408\u591a\u79cd\u6280\u80fd\u7b49\u591a\u4e2a\u7814\u7a76\u65b9\u5411\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GII5CwvB4FuxkT7yzyf_4Q"},"\u300a\u52a8\u624b\u505a\u4e00\u4e2a\u6700\u5c0fRAG\u2014\u2014TinyRAG\u300b"),"\u3002\u672c\u6587\u7531\u4e0d\u8981\u8471\u59dc\u849c\u6307\u5bfc\u8bfb\u8005\u5982\u4f55\u4e00\u6b65\u6b65\u5b9e\u73b0\u57fa\u4e8e\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u6280\u672f\uff08RAG\uff09\u7684\u7b80\u5316\u6a21\u578b\u2014\u2014TinyRAG\u3002TinyRAG\u4ec5\u5305\u542bRAG\u6838\u5fc3\u529f\u80fd\uff0c\u5373Retrieval\uff08\u68c0\u7d22\uff09\u548cGeneration\uff08\u751f\u6210\uff09\u4e24\u4e2a\u6a21\u5757\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86RAG\u7684\u57fa\u672c\u7ed3\u6784\uff0c\u5305\u62ec\u5411\u91cf\u5316\u6a21\u5757\u3001\u6587\u6863\u52a0\u8f7d\u4e0e\u5207\u5206\u6a21\u5757\u3001\u6570\u636e\u5e93\u548c\u68c0\u7d22\u6a21\u5757\uff0c\u4ee5\u53ca\u5982\u4f55\u6839\u636e\u68c0\u7d22\u5185\u5bb9\u751f\u6210\u56de\u7b54\u3002\u6b64\u5916\uff0c\u8fd8\u63d0\u4f9b\u4e86\u5bf9\u5e94\u7684\u5f00\u6e90\u9879\u76ee",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KMnO4-zx/TinyRAG"},"\u4ee3\u7801"),"\uff0c\u52a9\u529b\u7406\u89e3\u8bed\u8a00\u6a21\u578b\u4e0eRAG\u7684\u539f\u7406\uff0c\u5e76\u80fd\u591f\u5728\u5b9e\u8df5\u4e2d\u52a0\u4ee5\u5e94\u7528\u548c\u62d3\u5c55\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1jTw_5_re4GWWLqgKnkSww"},"\u300a\u804a\u4e00\u804aTransformer\u4e2d\u7684FFN\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u4e3a\u4ec0\u4e48Transformer\u7684\u524d\u9988\u795e\u7ecf\u7f51\u7edc\uff08FFN\uff09\u90e8\u5206\u957f\u671f\u4ee5\u6765\u51e0\u4e4e\u6ca1\u6709\u5927\u7684\u6539\u52a8\u3002\u6587\u7ae0\u901a\u8fc7\u6bd4\u8f83\u4e0d\u540c\u7684\u6fc0\u6d3b\u51fd\u6570\uff0c\u5982ReLU\u3001GeLU\u548cSwish\u7b49\uff0c\u5206\u6790\u5b83\u4eec\u5728Transformer\u4e2d\u7684\u5e94\u7528\u6548\u679c\u548c\u5c40\u9650\u6027\u3002\u540c\u65f6\u63a2\u8ba8\u4e86\u7ebf\u6027\u6295\u5f71\u7684\u5fc5\u8981\u6027\u3001\u53c2\u6570\u91cf\u53ca\u5176\u5bf9\u6a21\u578b\u5bb9\u91cf\u548c\u8bb0\u5fc6\u529b\u7684\u5f71\u54cd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u6d89\u53ca\u4e86\u6df7\u5408\u4e13\u5bb6\u6a21\u578b\uff08Mixture-of-Experts\uff0cMoE\uff09\u4ee5\u63d0\u5347Transformer\u7684\u6548\u7387\uff0c\u5e76\u8ba8\u8bba\u4e86\u6784\u5efa\u901a\u7528\u4eba\u5de5\u667a\u80fd\uff08AGI\uff09\u6240\u9700\u8981\u7684\u7ed3\u6784\u7279\u6027\uff0c\u7279\u522b\u662f\u653e\u7f29\u5b9a\u5f8b\uff08Scaling Law\uff09\u3001\u4e0a\u4e0b\u6587\u5b66\u4e60\uff08In-Context Learning\uff09\u3001\u6548\u7387\u63d0\u5347\uff08Better Efficiency\uff09\u548c\u7ec8\u751f\u5b66\u4e60\uff08Life-long learning\uff09\u7684\u91cd\u8981\u6027\uff0c\u6700\u540e\u5bf9\u672a\u6765\u7ed3\u6784\u521b\u65b0\u7ed9\u51fa\u900f\u5f7b\u89c1\u89e3\u3002"),(0,r.kt)("h2",{id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173"},"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://go.dev/blog/execution-traces-2024"},"\u300aMore powerful Go execution traces\u300b"),"\u3002Go\u7684runtime/trace\u5305\u63d0\u4f9b\u4e86\u7528\u4e8e\u7406\u89e3\u548c\u6392\u67e5Go\u7a0b\u5e8f\u7684\u5f3a\u5927\u5de5\u5177\uff0c\u5141\u8bb8\u5bf9goroutine\u7684\u6267\u884c\u8fdb\u884c\u8ddf\u8e2a\u3002\u65b0\u7248\u672cGo\u5927\u5e45\u5ea6\u964d\u4f4e\u4e86\u6267\u884c\u8ddf\u8e2a\u7684\u8fd0\u884c\u65f6\u5f00\u9500\uff0c\u4ece\u591a\u6570\u5e94\u7528\u4e2d\u768410-20% CPU\u4e0b\u964d\u52301-2%\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u5c06trace\u5206\u5272\uff0c\u4ece\u800c\u4f7f\u5f97trace\u53ef\u4ee5\u6269\u5c55\u4e14\u4fdd\u6301\u4f4e\u5f00\u9500\uff0c\u8fd8\u5b9e\u73b0\u4e86\u98de\u884c\u8bb0\u5f55\u529f\u80fd\uff0c\u4f7f\u5f97\u5373\u4f7f\u5728\u4e8b\u4ef6\u53d1\u751f\u540e\u4e5f\u80fd\u4ecetrace\u4e2d\u83b7\u53d6\u4fe1\u606f\u3002Go\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5b9e\u9a8c\u6027\u7684trace\u8bfb\u53d6API\uff0c\u4f7f\u7a0b\u5e8f\u6027\u7684\u8ddf\u8e2a\u5206\u6790\u6210\u4e3a\u53ef\u80fd\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7346394191264710666"},"\u300aRust: \u5b9e\u73b0\u6bd4\u7279\u5e01\u7684\u4ea4\u6613\u6a21\u578b\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u6bd4\u7279\u5e01\u7684\u4ea4\u6613\u6a21\u578b\u4e2d\u7684UTXO\uff08\u672a\u82b1\u8d39\u4ea4\u6613\u8f93\u51fa\uff09\u6a21\u578b\uff0c\u5e76\u4f7f\u7528 Rust \u8bed\u8a00\u6765\u5b9e\u73b0\u548c\u5c55\u793a\u5176\u8fd0\u4f5c\u8fc7\u7a0b\u3002UTXO \u6a21\u578b\u4e0e\u4f20\u7edf\u7684\u8d26\u6237\u4f59\u989d\u6a21\u578b\u4e0d\u540c\uff0c\u5c06\u7528\u6237\u7684\u4f59\u989d\u5206\u6563\u5b58\u50a8\u5728\u591a\u4e2aUTXO\u4e2d\u3002\u6bcf\u4e2aUTXO\u4ee3\u8868\u6bd4\u7279\u5e01\u7f51\u7edc\u4e0a\u4e00\u7b14\u53ef\u7528\u4e8e\u672a\u6765\u4ea4\u6613\u7684\u8f93\u51fa\u3002\u6587\u7ae0\u89e3\u91ca\u4e86UTXO\u6a21\u578b\u7684\u5de5\u4f5c\u539f\u7406\u3001\u4f18\u52bf\u4ee5\u53ca\u4ea4\u6613\u5904\u7406\u6d41\u7a0b\uff0c\u5305\u62ec\u9009\u62e9\u8f93\u5165\u3001\u751f\u6210\u8f93\u51fa\u3001\u7b7e\u540d\u4ea4\u6613\u548c\u5e7f\u64ad\u4ea4\u6613\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u4e2a Rust \u5b9e\u73b0\u7684\u7b80\u5316\u793a\u4f8b\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u5b9a\u4e49\u4ea4\u6613\u7ed3\u6784\u4f53\u3001\u8f93\u5165\u3001\u8f93\u51fa\u4ee5\u53caUTXO\u96c6\u5408\uff0c\u5e76\u4ecb\u7ecd\u4e86\u57fa\u672c\u7684\u64cd\u4f5c\u65b9\u6cd5\u3002\u5982\u679c\u4f60\u5bf9\u6bd4\u7279\u5e01\u4ea4\u6613\u6a21\u578b\u548c Rust \u7f16\u7a0b\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u9605\u8bfb\u8be5\u6587\u7ae0\u4e86\u89e3\u66f4\u591a\u7ec6\u8282\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7309692103055507491"},"\u300a\u6df1\u5165\u7406\u89e3 Go Modules: \u9ad8\u6548\u7ba1\u7406\u4f60\u7684 Golang \u9879\u76ee\u4f9d\u8d56\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86 Go Modules \u5728 Golang \u9879\u76ee\u4e2d\u7684\u4f7f\u7528\u65b9\u6cd5\u548c\u539f\u7406\u3002\u6587\u7ae0\u9996\u5148\u56de\u987e\u4e86 Go \u4f9d\u8d56\u7ba1\u7406\u7684\u5386\u53f2\uff0c\u4ece GOPATH\u3001Go Vendor \u5230 Go Module \u7684\u6f14\u8fdb\u8fc7\u7a0b\u3002\u7136\u540e\u8bb2\u89e3\u4e86\u6a21\u5757\u3001\u5305\u548c\u7248\u672c\u7684\u6982\u5ff5\uff0c\u5305\u62ec\u6a21\u5757\u8def\u5f84\u3001\u5305\u8def\u5f84\u4ee5\u53ca\u7248\u672c\u7684\u683c\u5f0f\u548c\u8bed\u4e49\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86 Go Modules \u7684\u73af\u5883\u914d\u7f6e\uff0c\u5305\u62ec go env \u73af\u5883\u53d8\u91cf\u548c\u4f9d\u8d56\u7ba1\u7406\u6587\u4ef6\uff08go.mod \u548c go.sum\uff09\u7684\u4f5c\u7528\u548c\u4f7f\u7528\u65b9\u6cd5\u3002\u6700\u540e\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u7528\u6280\u5de7\u548c\u5e38\u89c1\u95ee\u9898\u7684\u89e3\u7b54\uff0c\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u5e94\u7528 Go Modules\u3002\u5982\u679c\u4f60\u5bf9 Golang \u9879\u76ee\u7684\u4f9d\u8d56\u7ba1\u7406\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u9605\u8bfb\u8be5\u6587\u7ae0\u4e86\u89e3\u66f4\u591a\u8be6\u60c5\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GxTtiqMpcrDWK9toaK5CMw"},"\u300aKubernetes\u96c6\u7fa4\u8282\u70b9\u5904\u4e8eNot Ready\u95ee\u9898\u6392\u67e5\u300b"),'\u3002\u5f53Kubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u663e\u793a\u4e3a"Not Ready"\u72b6\u6001\u65f6\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u7cfb\u5217\u7684\u6392\u67e5\u6b65\u9aa4\u3002\u9996\u5148\uff0c\u901a\u8fc7\u8fd0\u884c\u7279\u5b9a\u7684kubectl\u547d\u4ee4\u6765\u786e\u8ba4\u8282\u70b9\u7684\u72b6\u6001\u5e76\u83b7\u53d6\u8282\u70b9\u8be6\u7ec6\u4fe1\u606f\uff0c\u68c0\u67e5\u53ef\u80fd\u7684\u9519\u8bef\u6d88\u606f\u6216\u8005\u8b66\u544a\u3002\u63a5\u7740\uff0c\u8fdb\u5165\u8282\u70b9\u7cfb\u7edf\u67e5\u770b\u5404\u79cd\u7cfb\u7edf\u65e5\u5fd7\uff0c\u5e76\u4f7f\u7528\u76f8\u5173\u547d\u4ee4\u5982grep\u3001cat\u6216tail\u6765\u8f85\u52a9\u5206\u6790\u3002\u6587\u7ae0\u8fd8\u5efa\u8bae\u68c0\u67e5kubelet\u670d\u52a1\u72b6\u6001\u548c\u914d\u7f6e\u6587\u4ef6\uff0c\u786e\u8ba4\u7cfb\u7edf\u8d44\u6e90\u662f\u5426\u5145\u8db3\uff0c\u8bd5\u56fe\u89e3\u51b3\u53ef\u80fd\u5b58\u5728\u7684\u78c1\u76d8\u7a7a\u95f4\u548c\u7f51\u7edc\u95ee\u9898\u3002\u6700\u540e\uff0c\u901a\u8fc7\u4f7f\u7528\u8bf8\u5982ping\u3001traceroute\u7b49\u8bca\u65ad\u5de5\u5177\u786e\u4fdd\u8282\u70b9\u80fd\u591f\u4e0e\u4e3b\u8282\u70b9\u901a\u4fe1\uff0c\u5e76\u68c0\u67e5\u91cd\u8981\u7684\u7f51\u7edc\u7aef\u53e3\u662f\u5426\u5f00\u653e\u3002\u786e\u4fddKubelet\u80fd\u6b63\u786e\u8fde\u63a5\u5230Kubernetes API\uff0c\u5e76\u4f7f\u7528Kubernetes\u7684\u8bca\u65ad\u5de5\u5177\u5982kubectl get componentstatus\u68c0\u67e5\u7ec4\u4ef6\u72b6\u6001\u3002\u901a\u8fc7\u8fd9\u4e9b\u6b65\u9aa4\uff0c\u53ef\u4ee5\u7cfb\u7edf\u5730\u6392\u67e5\u5e76\u89e3\u51b3"Not Ready"\u7684\u95ee\u9898\uff0c\u4fdd\u6301\u96c6\u7fa4\u5065\u5eb7\u3002'),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iuzDw7_w20jtjJUlynv9NA"},"\u300aGo \u9519\u8bef\u5904\u7406: \u7528 select-case \u6765\u89e3\u51b3\u8fd9\u4e2a\u5386\u53f2\u96be\u9898?\u300b"),"\u3002\u714e\u9c7c\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u4e86\u4e00\u4e2a\u65b0\u7684Go\u8bed\u8a00\u9519\u8bef\u5904\u7406\u63d0\u6848\uff0c\u8fd9\u4e2a\u63d0\u6848\u5c1d\u8bd5\u7528",(0,r.kt)("inlineCode",{parentName:"p"},"select-case"),"\u7ed3\u6784\u4f5c\u4e3a\u9519\u8bef\u68c0\u67e5\u7684\u66ff\u4ee3\u3002\u8fd9\u4e2a\u65b0\u8bed\u6cd5\u5141\u8bb8\u5728",(0,r.kt)("inlineCode",{parentName:"p"},"select"),"\u5173\u952e\u5b57\u4e4b\u540e\u58f0\u660e\u4e00\u4e2a\u53d8\u91cf\u4e3a\u201c\u9677\u9631\u201d\uff0c\u8d4b\u503c\u7ed9\u8be5\u53d8\u91cf\u65f6\u89e6\u53d1",(0,r.kt)("inlineCode",{parentName:"p"},"case"),"\u68c0\u67e5\uff0c\u4ee5\u51cf\u5c11\u4f20\u7edf\u7684",(0,r.kt)("inlineCode",{parentName:"p"},"if err != nil"),"\u68c0\u67e5\u7684\u7e41\u7410\u6027\u3002\u65b0\u63d0\u6848\u4fdd\u6301\u4e86Go1\u4ee3\u7801\u7684\u517c\u5bb9\u6027\uff0c\u5c1d\u8bd5\u63d0\u4f9b\u4e00\u4e2a\u66f4\u7b80\u6d01\u3001\u5411\u540e\u517c\u5bb9\u7684\u9519\u8bef\u5904\u7406\u65b9\u5f0f\uff0c\u5c3d\u7ba1\u76ee\u524d\u793e\u533a\u5185\u5bf9\u6b64\u4ecd\u672a\u8fbe\u6210\u5171\u8bc6\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Dc5wOBAE_jSiTKqPc6M4Dg"},"\u300aK8s\u84dd\u7eff\u90e8\u7f72:\u4f18\u96c5\u5e94\u5bf9\u5e94\u7528\u7a0b\u5e8f\u66f4\u65b0\u6311\u6218\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u63a2\u8ba8\u4e86\u4f7f\u7528Kubernetes\uff08K8s\uff09\u8fdb\u884c\u84dd\u7eff\u90e8\u7f72\u7684\u65b9\u6cd5\uff0c\u4ee5\u8fbe\u5230\u65e0\u7f1d\u66f4\u65b0\u5e94\u7528\u7a0b\u5e8f\u5e76\u6700\u5c0f\u5316\u5b95\u673a\u65f6\u95f4\u3002\u84dd\u7eff\u90e8\u7f72\u662f\u4e00\u4e2a\u8fd0\u884c\u4e24\u4e2a\u76f8\u540c\u751f\u4ea7\u73af\u5883\u7684\u6a21\u5f0f\uff0c\u80fd\u591f\u5728\u66f4\u65b0\u65f6\u5207\u6362\u6d41\u91cf\uff0c\u786e\u8ba4\u65e0\u8bef\u540e\u4fbf\u53bb\u9664\u65e7\u73af\u5883\u3002\u6587\u7ae0\u6307\u5bfc\u4e86\u4ece\u521b\u5efa\u547d\u540d\u7a7a\u95f4\u3001\u521b\u5efa\u548c\u5e94\u7528\u90e8\u7f72\u3001\u670d\u52a1\u53ca\u5176\u8def\u7531\u89c4\u5219\u3001\u6267\u884c\u84dd\u7eff\u5207\u6362\uff0c\u5230\u6700\u540e\u7684\u9a8c\u8bc1\u548c\u56de\u6eda\u8fc7\u7a0b\u3002\u8fd9\u4e00\u8fc7\u7a0b\u4e0d\u4ec5\u4f18\u5316\u4e86\u5e94\u7528\u7248\u672c\u7684\u6eda\u52a8\u66f4\u65b0\uff0c\u4e5f\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u5feb\u901f\u56de\u6eda\u7684\u65b9\u6848\uff0c\u4ee5\u5e94\u5bf9\u53ef\u80fd\u51fa\u73b0\u7684\u95ee\u9898\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/RzglzZ0xY9NmsgujdHa-Tw"},"\u300aGo \u4e2d\u7684\u9ad8\u901f\u6570\u636e\u5305\u5904\u7406:\u4ece net.Dial \u5230 AF_XDP\u300b"),"\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4f7f\u7528 Go \u8bed\u8a00\u8fdb\u884c\u9ad8\u901f\u6570\u636e\u5305\u5904\u7406\u7684\u591a\u79cd\u65b9\u6cd5\uff0c\u5305\u62ec net.Dial\u3001\u539f\u59cb\u5957\u63a5\u5b57\u3001\u7cfb\u7edf\u8c03\u7528\u3001pcap \u548c AF_PACKET\uff0c\u76f4\u81f3\u6700\u65b0\u7684 AF_XDP \u65b9\u5f0f\u3002\u4f5c\u8005\u8be6\u7ec6\u5bf9\u6bd4\u4e86\u6bcf\u79cd\u65b9\u6cd5\u7684\u6027\u80fd\uff0c\u4ece\u7b80\u5355\u7684 net.Dial \u6a21\u5f0f\u6f14\u8fdb\u5230 AF_XDP\uff0c\u9010\u6b65\u63d0\u9ad8\u6570\u636e\u5305\u6bcf\u79d2\u5904\u7406\u6570\u91cf\uff0c\u540c\u65f6\u6307\u51fa\u5404\u65b9\u6cd5\u7684\u4f7f\u7528\u573a\u5408\u548c\u9650\u5236\u3002\u901a\u8fc7\u57fa\u51c6\u6d4b\u8bd5\uff0c\u53d1\u73b0\u4f7f\u7528 AF_XDP \u53ef\u5b9e\u73b0\u6700\u9ad8\u6027\u80fd\uff0c\u5904\u7406\u901f\u5ea6\u662f\u4f7f\u7528 net.Dial \u65b9\u6cd5\u76844\u500d\u591a\u3002\u8fd9\u4e9b\u6280\u672f\u63a2\u8ba8\u5bf9\u4e8e\u9700\u8981\u5927\u91cf\u7f51\u7edc\u6570\u636e\u5305\u5904\u7406\u7684\u573a\u666f\uff0c\u5982\u7f51\u7edc\u76d1\u63a7\u3001\u6027\u80fd\u8bc4\u4f30\u7b49\u90fd\u662f\u975e\u5e38\u91cd\u8981\u7684\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dCQPOx2n2w36Q3P3hCKe8A"},"\u300a\u6570\u636e\u5e93\u4e0d\u5e94\u653e\u5728\u5bb9\u5668\u4e2d?- B\u7ad9Kubernetes\u6709\u72b6\u6001\u670d\u52a1\u5b9e\u8df5(Elasticsearch/Clickhouse)\u300b"),"\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5728\u4e91\u539f\u751f\u65f6\u4ee3\u4e0b\uff0c\u6709\u72b6\u6001\u670d\u52a1\uff08\u5982\u751f\u4ea7\u73af\u5883\u7684\u6570\u636e\u5e93\uff09\u662f\u5426\u9002\u7528\u4e8e\u5bb9\u5668\u5316\u5e76\u7531Kubernetes\u8fdb\u884c\u7ba1\u7406\u7684\u95ee\u9898\u3002\u4ee5B\u7ad9Elasticsearch\u548cClickhouse\u7684\u5bb9\u5668\u5316\u548cKubernetes\u7f16\u6392\u5b9e\u8df5\u4e3a\u4f8b\uff0c\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5728\u5bb9\u5668\u73af\u5883\u4e2d\u90e8\u7f72\u8fd9\u4e9b\u6709\u72b6\u6001\u670d\u52a1\u7684\u6311\u6218\u548c\u89e3\u51b3\u65b9\u6848\uff0c\u5305\u62ec\u63a7\u5236\u5668\u7684\u9009\u62e9\u3001\u6301\u4e45\u5316\u5b58\u50a8\u3001\u78c1\u76d8\u8c03\u5ea6\u3001\u8c03\u5ea6\u5668\u3001\u5bb9\u5668\u7f51\u7edc\u3001\u670d\u52a1\u53d1\u73b0\u4ee5\u53ca\u5982\u4f55\u4fdd\u8bc1\u96c6\u7fa4\u548c\u6570\u636e\u7684\u9ad8\u53ef\u7528\u6027\u3002\u4f5c\u8005\u5206\u4eab\u4e86\u901a\u8fc7Operator\u7ba1\u7406\u6709\u72b6\u6001\u670d\u52a1\u5e94\u7528\u3001\u4f7f\u7528\u672c\u5730\u76d8PV\u63d0\u5347\u6027\u80fd\u3001LVM\u6280\u672f\u7684\u52a8\u6001\u6269\u7f29\u5bb9\u65b9\u6848\u4ee5\u53ca\u901a\u8fc7macvlan\u8fdb\u884c\u5bb9\u5668\u95f4\u9ad8\u6548\u901a\u4fe1\u7684\u6280\u672f\u7ec6\u8282\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/-TXbvQiR-tpB0RgQ5d-QDw"},"\u300a\u4e00\u6587\u5e26\u60a8\u63a2\u7d22 Kubernetes \u4e2d\u7684\u5bb9\u5668\u7c7b\u578b\u300b"),"\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5728 Kubernetes \u7cfb\u7edf\u4e2d\u5e38\u89c1\u7684\u56db\u79cd\u5bb9\u5668\u7c7b\u578b\uff1a\u521d\u59cb\u5316\u5bb9\u5668(Init Container)\u3001\u8fb9\u8f66\u5bb9\u5668(Sidecar Container)\u3001\u4e34\u65f6\u5bb9\u5668(Ephemeral Container)\u548c\u591a\u5bb9\u5668(Multi Container)\u3002\u521d\u59cb\u5316\u5bb9\u5668\u7528\u4e8e\u8fd0\u884c Pod \u4e2d\u4e3b\u5bb9\u5668\u542f\u52a8\u524d\u7684\u51c6\u5907\u5de5\u4f5c\uff0c\u800c\u8fb9\u8f66\u5bb9\u5668\u5219\u4e0e\u4e3b\u5e94\u7528\u5bb9\u5668\u5e76\u884c\u8fd0\u884c\uff0c\u4e3a\u5176\u63d0\u4f9b\u652f\u6301\u670d\u52a1\u3002\u4e34\u65f6\u5bb9\u5668\u4e3b\u8981\u7528\u4e8e\u6545\u969c\u6392\u9664\uff0c\u800c\u591a\u5bb9\u5668 Pods \u5141\u8bb8\u5e76\u884c\u8fd0\u884c\u591a\u4e2a\u5bb9\u5668\uff0c\u5171\u4eab\u8d44\u6e90\u548c\u6570\u636e\u3002\u6587\u7ae0\u63d0\u4f9b\u4e86\u6bcf\u79cd\u5bb9\u5668\u7684\u8be6\u7ec6\u4f7f\u7528\u6848\u4f8b\u3001\u914d\u7f6e\u65b9\u6cd5\u548c\u547d\u4ee4\uff0c\u5e76\u5f3a\u8c03\u4e86\u5404\u81ea\u7684\u7279\u70b9\u4e0e\u5e94\u7528\u573a\u666f\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iylZAKZfxLL6SYruww_8zA"},"\u300a4 \u79d2\u5904\u7406 10 \u4ebf\u884c\u6570\u636e! Go \u8bed\u8a00\u7684 9 \u5927\u4ee3\u7801\u65b9\u6848\uff0c\u4e00\u4e2a\u6bd4\u4e00\u4e2a\u5feb\u300b"),"\u3002\u8f6f\u4ef6\u5de5\u7a0b\u5e08Ben Hoyt\u6311\u6218\u4f7f\u7528Go\u8bed\u8a00\u5904\u740610\u4ebf\u884c\u6570\u636e\uff0c\u5e76\u63d0\u51fa\u4e869\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u5176\u4e2d\u6700\u5feb\u57284\u79d2\u5185\u5b8c\u6210\u3002\u8fd9\u4e9b\u65b9\u6848\u53ea\u4f7f\u7528Go\u6807\u51c6\u5e93\uff0c\u5305\u62ec\u7b80\u5355\u4f46\u4f18\u5316\u7684map\u5904\u7406\u3001\u5e76\u884c\u5316\u5904\u7406\u7b49\u3002Ben\u7684\u65b9\u6848\u867d\u672a\u6700\u5feb\uff0c\u4f46\u5c55\u73b0\u4e86\u72ec\u7acb\u601d\u8003\u7684\u4ef7\u503c\u3002\u4ed6\u7684\u6d4b\u8bd5\u8868\u660e\uff0c\u5f7b\u5e95\u5730\u6570\u636e\u5904\u7406\u548c\u7b97\u6cd5\u4f18\u5316\u53ef\u663e\u8457\u63d0\u9ad8\u6027\u80fd\uff0c\u51cf\u5c11\u8ba1\u7b97\u6210\u672c\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/aS-azhReZL5epoG_3n0hyg"},"\u300aGo arena \u6c11\u95f4\u5e93\u6765\u4e86\uff0c\u53ef\u4ee5\u624b\u52a8\u7ba1\u7406\u5185\u5b58!\u300b"),"\u3002\u6587\u4e2d\u4f5c\u8005\u714e\u9c7c\u4ecb\u7ecd\u4e86Go\u8bed\u8a00\u7684\u4e00\u4e2a\u65b0\u7684\u7b2c\u4e09\u65b9\u5e93ortuman/nuke\uff0c\u8fd9\u4e2a\u5e93\u5141\u8bb8\u5f00\u53d1\u8005\u624b\u52a8\u7ba1\u7406\u5185\u5b58\u3002\u6587\u7ae0\u9996\u5148\u56de\u987e\u4e86Go\u5b98\u65b9\u5bf9\u4e8earena\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u63d0\u6848\u7684\u505c\u6ede\u73b0\u72b6\uff0c\u7136\u540e\u91cd\u70b9\u4ecb\u7ecd\u4e86\u5982\u4f55\u4f7f\u7528ortuman/nuke\u5e93\u8fdb\u884c\u5185\u5b58\u7ba1\u7406\uff0c\u5305\u62ec\u5e93\u7684\u5b89\u88c5\u3001\u4f7f\u7528\u6848\u4f8b\u4ee5\u53ca\u5982\u4f55\u5728\u5e76\u53d1\u573a\u666f\u4e0b\u4fdd\u6301\u7ebf\u7a0b\u5b89\u5168\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u89e3\u4e86arena\u5185\u5b58\u7ba1\u7406\u7684\u4f18\u70b9\uff0c\u4f8b\u5982\u9ad8\u6548\u7387\u548c\u4e00\u6b21\u6027\u91ca\u653e\uff0c\u5e76\u5bf9\u5e93\u7684\u5b9e\u9645\u7528\u6cd5\uff0c\u5982\u901a\u8fc7context\u5728HTTP\u8bf7\u6c42\u5468\u671f\u4e2d\u7ba1\u7406\u5185\u5b58\uff0c\u8fdb\u884c\u4e86\u5c55\u793a\u3002\u6700\u540e\uff0c\u57fa\u4e8e\u6027\u80fd\u8003\u8651\uff0c\u6587\u7ae0\u8fd8\u63d0\u4f9b\u4e86\u5e76\u53d1\u4e0e\u975e\u5e76\u53d1\u4e1a\u52a1\u573a\u666f\u4e0b\u7684\u57fa\u51c6\u6d4b\u8bd5\u7ed3\u679c\u4ee5\u53ca\u6027\u80fd\u5dee\u5f02\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/xRxRe6DkWJVcGKXOt1oGlQ"},"Go \u8bed\u8a00\u4e2d\u5982\u4f55\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\uff1fint \u8f6c byte \u662f\u5982\u4f55\u8fdb\u884c\u7684")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/USKjmlyTtexSQtToOg481g"},"Go \u4e2d\u5982\u4f55\u5b9e\u73b0\u4e09\u5143\u8fd0\u7b97\u7b26\uff1fRust \u548c Python \u662f\u600e\u4e48\u505a\u7684")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/mFZewdDxlK4O_wUWR6mVjg"},"Go\u8bed\u8a00\u4e2d enum \u5b9e\u73b0\u65b9\u5f0f\u6709\u54ea\u4e9b\uff1f\u4e00\u5b9a\u8981\u7edd\u5bf9\u7c7b\u578b\u5b89\u5168\u5417")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/obOG_Kior34ktLek3_-GZg"},"Go \u4e2d\u5982\u4f55\u6253\u5370\u7ed3\u6784\u4f53\uff1f \u4ee3\u7801\u8c03\u8bd5\u6548\u7387\u63d0\u5347")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/9ARiVYpYRy4FCuSJ5IKuGw"},"\u300a\u5feb\u770b! Go 1.22 \u5bf9for\u5faa\u73af\u8fdb\u884c\u4e86\u4e24\u4e2a\u5927\u66f4\u65b0\u300b"),"\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728 1.22 \u7248\u672c\u4e2d\u9488\u5bf9for\u5faa\u73af\u4f5c\u51fa\u7684\u4e24\u9879\u4e3b\u8981\u66f4\u65b0\uff1a1. \u6bcf\u6b21\u8fed\u4ee3\u7684for\u5faa\u73af\u90fd\u5c06\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u53d8\u91cf\uff0c\u4e0d\u518d\u5171\u7528\u540c\u4e00\u4e2a\u53d8\u91cf\uff1b2. \u5f15\u5165\u4e86\u5bf9\u6574\u6570\u8303\u56f4\u7684\u5faa\u73af\u8fed\u4ee3\u652f\u6301\u3002\u8fd9\u4e9b\u66f4\u65b0\u89e3\u51b3\u4e86\u95ed\u5305\u5728\u5e76\u53d1\u6267\u884c\u65f6\u5171\u4eab\u53d8\u91cf\u5e26\u6765\u7684\u95ee\u9898\uff0c\u540c\u65f6\u4e5f\u7b80\u5316\u4e86\u5faa\u73af\u7ed3\u6784\uff0c\u63d0\u9ad8\u4e86\u7f16\u5199\u5bf9\u6574\u6570\u8303\u56f4\u8fdb\u884c\u8fed\u4ee3\u4ee3\u7801\u7684\u65b9\u4fbf\u6027\u3002\u6587\u4e2d\u63d0\u4f9b\u4e86\u8be6\u7ec6\u7684\u4ee3\u7801\u793a\u4f8b\u6765\u5c55\u793a\u65b0\u65e7\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\uff0c\u5e76\u8bf4\u660e\u4e86\u5982\u4f55\u5229\u7528\u65b0\u7279\u6027\u6765\u7f16\u5199\u66f4\u9ad8\u6548\u7684Go\u4ee3\u7801\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lxp9OqiVAHtoX75UoaHipw"},"\u300a\u4ece\u6162\u901f\u5230SIMD\u300b\u804aGo\u8fb9\u754c\u68c0\u67e5\u6d88\u9664\u300b"),"\u3002\u672c\u6587\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u4e2d\u8fb9\u754c\u68c0\u67e5\u6d88\u9664\uff08BCE\uff09\u7684\u76f8\u5173\u6280\u5de7\u548c\u6700\u4f73\u5b9e\u8df5\u3002\u6587\u7ae0\u9996\u5148\u56de\u7b54\u4e86\u4e3a\u4f55\u5728Go\u4ee3\u7801\u4e2d\u4f18\u5316\u65f6\u9009\u62e9\u4f7f\u7528",(0,r.kt)("inlineCode",{parentName:"p"},"a[i:i+4:i+4]"),"\u800c\u4e0d\u662f",(0,r.kt)("inlineCode",{parentName:"p"},"a[i:i+4]"),"\u7684\u95ee\u9898\uff0c\u6307\u51fa\u524d\u8005\u80fd\u51cf\u5c11\u7f16\u8bd1\u5668\u5de5\u4f5c\u91cf\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u7136\u540e\uff0c\u4ecb\u7ecd\u4e86Go101\u63d0\u51fa\u7684BCE\u6280\u672f\u8be6\u89e3\u4e0e\u5e94\u7528\u5b9e\u4f8b\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528\u7f16\u8bd1\u547d\u4ee4\u6765\u68c0\u6d4b\u8fb9\u754c\u68c0\u67e5\u7684\u5b58\u5728\u3002\u6587\u4e2d\u8fd8\u5168\u9762\u68b3\u7406\u4e86Go BCE\u6280\u672f\u7684\u53d1\u5c55\u5386\u7a0b\uff0c\u4ee5\u53ca\u5728\u4e0d\u540c\u573a\u666f\u4e0b\u6d88\u9664\u5197\u4f59\u8fb9\u754c\u68c0\u67e5\u7684\u65b9\u6cd5\uff0c\u5305\u62ec\u5229\u7528\u5faa\u73af\u53d8\u91cf\u3001\u5e38\u91cf\u7d22\u5f15\u7b49\u7b56\u7565\u6765\u63d0\u9ad8\u4ee3\u7801\u6267\u884c\u6548\u7387\u3002\u6700\u540e\uff0c\u63d0\u4f9b\u4e86\u591a\u79cd\u7f16\u7a0b\u6280\u5de7\u4ee5\u53ca\u76f8\u5173\u8ba8\u8bba\u548c\u53c2\u8003\u8d44\u6599\uff0c\u9488\u5bf9\u9047\u5230\u7684\u7f16\u7a0b\u95ee\u9898\u63d0\u51fa\u89e3\u51b3\u65b9\u6848\u3002"),(0,r.kt)("h2",{id:"-\u540e\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7329413905028579340"},"\u300a\u5206\u5e93\u5206\u8868\u5df2\u6210\u4e3a\u8fc7\u53bb\u5f0f\uff0c\u4f7f\u7528\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u624d\u662f\u672a\u6765\u300b"),"\u3002\u672c\u6587\u8ba8\u8bba\u4e86\u968f\u7740Mysql\u6570\u636e\u5e93\u6027\u80fd\u4e0b\u964d\uff0c\u5206\u5e93\u5206\u8868\u7684\u5c40\u9650\u6027\u53ca\u5176\u6240\u5f15\u53d1\u7684\u95ee\u9898\uff0c\u5982\u6027\u80fd\u3001\u4e8b\u52a1\u3001\u6570\u636e\u8fc1\u79fb\u7b49\uff0c\u5e76\u63d0\u51fa\u4f7f\u7528\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u4f5c\u4e3a\u89e3\u51b3\u65b9\u6848\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86TiDB\u8fd9\u6b3e\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u7684\u67b6\u6784\u3001\u7279\u6027\u548c\u4f18\u52bf\uff0c\u5305\u62ec\u5176\u91d1\u878d\u7ea7\u7684\u9ad8\u53ef\u7528\u6027\u3001\u6c34\u5e73\u6269\u5bb9\u80fd\u529b\u3001\u517c\u5bb9\u6027\u4ee5\u53ca\u4e91\u539f\u751f\u8bbe\u8ba1\u3002\u6587\u7ae0\u5f3a\u8c03TiDB\u5728\u5904\u7406\u5927\u89c4\u6a21\u6570\u636e\u65f6\u7684\u6548\u7387\u548c\u53ef\u7ef4\u62a4\u6027\uff0c\u7ec8\u7ed3\u5206\u5e93\u5206\u8868\u7684\u505a\u6cd5\uff0c\u5e76\u901a\u8fc7\u6027\u80fd\u6d4b\u8bd5\u5c55\u793a\u4e86TiDB\u4e0eMySQL\u5728\u4e0d\u540c\u573a\u666f\u4e0b\u7684\u6027\u80fd\u8868\u73b0\u3002\u6700\u7ec8\u603b\u7ed3\uff0c\u5bf9\u4e8e\u6570\u636e\u91cf\u5927\u7684\u5e94\u7528\u573a\u666f\uff0c\u91c7\u7528TiDB\u6765\u9002\u5e94\u672a\u6765\u6570\u636e\u5b58\u50a8\u7684\u9700\u6c42\u662f\u4e00\u4e2a\u66f4\u4f18\u7684\u7b56\u7565\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7337247324681093129"},"\u300a\u624b\u628a\u624b\u5e26\u4f60\u7cbe\u7b80\u4ee3\u7801-\u4eac\u4e1c\u96f6\u552e\u540e\u7aef\u5b9e\u8df5\u300b"),"\u3002\u672c\u6587\u5206\u4eab\u4e86\u4eac\u4e1c\u96f6\u552e\u540e\u7aef\u5728\u9762\u4e34\u4ee3\u7801\u5e93\u65e5\u6e10\u5e9e\u5927\u548c\u8150\u5316\u7684\u95ee\u9898\u65f6\uff0c\u91c7\u7528\u7684\u4ee3\u7801\u7cbe\u7b80\u65b9\u6cd5\u3002\u6587\u7ae0\u5206\u4e3a\u80cc\u666f\u4ecb\u7ecd\u3001\u4ee3\u7801\u7cbe\u7b80\u6b65\u9aa4\u548c\u5b9e\u65bd\u65b9\u6cd5\u4e09\u90e8\u5206\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u4f7f\u7528IntelliJ IDEA\u81ea\u5e26\u5de5\u5177\u548cPMD\u63d2\u4ef6\u8fdb\u884c\u9759\u6001\u4ee3\u7801\u68c0\u67e5\u7684\u6b65\u9aa4\u3001\u914d\u7f6e\u548c\u4f18\u7f3a\u70b9\uff0c\u4ee5\u53ca\u5982\u4f55\u501f\u52a9\u4eac\u4e1cjacoco\u6d41\u6c34\u7ebf\u8fdb\u884c\u52a8\u6001\u4ee3\u7801\u68c0\u67e5\u3002\u672c\u6587\u65e8\u5728\u964d\u4f4e\u4ee3\u7801\u7ef4\u62a4\u6210\u672c\u3001\u63d0\u5347\u53ef\u7406\u89e3\u6027\uff0c\u5e76\u8be6\u7ec6\u9610\u8ff0\u4e86\u4ee3\u7801\u7cbe\u7b80\u7684\u5b9e\u8df5\u8fc7\u7a0b\u548c\u9884\u671f\u7ed3\u679c\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZSXAPM8oFiCGztqbs1kksQ"},"\u300a\u8ddf\u7740iLogtail\u5b66\u4e60\u65e0\u9501\u5316\u7f16\u7a0b\u300b"),"\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5728\u591a\u7ebf\u7a0b\u60c5\u51b5\u4e0b\uff0c\u5982\u4f55\u901a\u8fc7\u65e0\u9501\u5316\u7f16\u7a0b\u4f18\u5316\u8f6f\u4ef6\u6027\u80fd\u3002\u8be6\u7ec6\u8bb2\u8ff0\u4e86iLogtail\u5728\u5b9e\u73b0\u65e0\u9501\u9ad8\u6548\u65e5\u5fd7\u91c7\u96c6\u65f6\u91c7\u53d6\u7684\u7b56\u7565\uff0c\u6bd4\u5982\u81ea\u65cb\u9501\u7684\u4f7f\u7528\u3001\u539f\u5b50\u64cd\u4f5c\u3001\u5185\u5b58\u987a\u5e8f\u3001\u5185\u5b58\u5c4f\u969c\u7b49\u6982\u5ff5\u3002\u8fd8\u5206\u6790\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u9501\u7684\u9002\u7528\u573a\u666f\u4e0e\u7279\u70b9\uff0c\u5305\u62ec\u4e92\u65a5\u9501\u3001\u9012\u5f52\u4e92\u65a5\u9501\u548c\u8bfb\u5199\u9501\u7b49\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u63cf\u8ff0\u4e86\u5982\u4f55\u5c06\u5927\u7684\u9501\u7ec6\u5206\u4e3a\u591a\u4e2a\u5c0f\u9501\uff0c\u901a\u8fc7\u964d\u4f4e\u9501\u7c92\u5ea6\u63d0\u5347\u5e76\u53d1\u6027\u80fd\uff0c\u4ee5\u53ca\u5728iLogtail\u4e2d\u5982\u4f55\u901a\u8fc7\u53ccBuffer\u673a\u5236\u6765\u8bfb\u5199\u5206\u79bb\uff0c\u51cf\u5c11\u9501\u7684\u4e89\u7528\u3002\u6700\u7ec8\uff0c\u901a\u8fc7\u65e0\u9501\u5316\u7f16\u7a0b\u63d0\u9ad8\u4e86iLogtail\u7684\u65e5\u5fd7\u91c7\u96c6\u6027\u80fd\uff0c\u5b9e\u73b0\u4e86\u4f4e\u8d44\u6e90\u6d88\u8017\u548c\u9ad8\u6027\u80fd\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GtU4xBKzfK3q3IsPuQV6pQ"},"\u300aMYSQL \u662f\u5982\u4f55\u4fdd\u8bc1binlog \u548credo log\u540c\u65f6\u63d0\u4ea4\u7684?\u300b"),"\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u786e\u4fdd\u5728MYSQL\u4e2dbinlog\uff08\u5907\u4efd\u548c\u4e3b\u4ece\u540c\u6b65\u7528\u7684\u65e5\u5fd7\uff09\u4e0eredo log\uff08InnoDB\u5f15\u64ce\u5c42\u7684\u65e5\u5fd7\uff0c\u7528\u4e8e\u5d29\u6e83\u6062\u590d\uff09\u540c\u6b65\u63d0\u4ea4\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u8fd9\u4e00\u70b9\u5bf9\u4e8e\u9632\u6b62\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u81f3\u5173\u91cd\u8981\u3002\u6587\u4e2d\u89e3\u91ca\u4e86\u4e8b\u52a1\u5904\u7406\u4e2d\u7684\u4e24\u4e2a\u5173\u952e\u53c2\u6570\uff1a",(0,r.kt)("inlineCode",{parentName:"p"},"innodb_flush_log_at_trx_commit"),"\u548c",(0,r.kt)("inlineCode",{parentName:"p"},"sync_binlog"),"\uff0c\u8fd9\u4e24\u4e2a\u503c\u8bbe\u7f6e\u4e3a1\u65f6\u53ef\u4ee5\u786e\u4fdd\u4e24\u79cd\u65e5\u5fd7\u7684\u540c\u6b65\u63d0\u4ea4\u3002\u8be5\u6587\u8fd8\u4ecb\u7ecd\u4e86MYSQL\u7684\u4e24\u9636\u6bb5\u63d0\u4ea4\u673a\u5236\u5982\u4f55\u5de5\u4f5c\uff0c\u5e76\u63d0\u51fa\u4e86\u4e1a\u52a1\u5f00\u53d1\u4e2d\u4e24\u9636\u6bb5\u63d0\u4ea4\u903b\u8f91\u7684\u601d\u8003\uff0c\u6307\u51fa\u5728\u6709\u4f9d\u8d56\u5173\u7cfb\u7684\u670d\u52a1\u64cd\u4f5c\u4e2d\uff0c\u901a\u8fc7\u9884\u9501\u5b9a\u8d44\u6e90\u3001\u8bf7\u6c42\u6210\u529f\u540e\u9012\u51cf\u8d44\u6e90\u6765\u4fdd\u6301\u6570\u636e\u7684\u6700\u7ec8\u4e00\u81f4\u6027\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/jVKgmbvha6Q-iNxvVzg3nw"},"\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u5206\u5e03\u5f0f\u7bc7\u300b"),"\u3002\u672c\u6587\u4ece\u5206\u5e03\u5f0f\u7cfb\u7edf\u7684\u57fa\u7840\u6982\u5ff5\u3001\u53d1\u5c55\u5386\u7a0b\u53ca\u6838\u5fc3\u95ee\u9898\u51fa\u53d1\uff0c\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u4e2d\u7684\u5173\u952e\u6280\u672f\u70b9\u3002\u6587\u7ae0\u6db5\u76d6\u4e86\u8d1f\u8f7d\u5747\u8861\u3001\u670d\u52a1\u7684\u62c6\u5206\u4e0e\u96c6\u7fa4\u3001\u5206\u5e03\u5f0f\u4e8b\u52a1\u3001\u6570\u636e\u4e00\u81f4\u6027\u95ee\u9898\u4ee5\u53ca\u5206\u533a\u5bb9\u9519\u6027\u7b49\u8bdd\u9898\uff0c\u5e76\u63a2\u8ba8\u4e86CAP\u7406\u8bba\u4e0eBASE\u7406\u8bba\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u6743\u8861\u3002\u540c\u65f6\uff0c\u6587\u4e2d\u8fd8\u8be6\u7ec6\u89e3\u8bfb\u4e86\u5e38\u89c1\u7684\u4e00\u81f4\u6027\u7b97\u6cd5\u59822PC\u30013PC\u3001Paxos\u3001Raft\u7684\u673a\u5236\u548c\u7528\u4f8b\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9488\u5bf9\u5982\u4f55\u5b9e\u73b0\u5206\u5e03\u5f0fSession\u3001\u5982\u4f55\u786e\u4fdd\u5206\u5e03\u5f0f\u4e8b\u52a1\u7684\u4e00\u81f4\u6027\u7b49\u5e38\u89c1\u9762\u8bd5\u9898\u76ee\u63d0\u4f9b\u4e86\u8be6\u5c3d\u7684\u89e3\u7b54\uff0c\u9002\u5408\u505a\u4e3a\u9762\u8bd5\u5907\u8003\u8d44\u6599\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/y1-A-SHAkGdg9IOTeUtPxg"},"\u300aRocketMQ\u4e3a\u4ec0\u4e48\u8fd9\u4e48\u5feb?\u6211\u4ece\u6e90\u7801\u4e2d\u6252\u51fa\u4e8610\u5927\u539f\u56e0!\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5206\u6790\u4e86RocketMQ\u9ad8\u6027\u80fd\u768410\u4e2a\u5173\u952e\u56e0\u7d20\uff1a\u6279\u91cf\u53d1\u9001\u6d88\u606f\u964d\u4f4e\u901a\u4fe1\u6b21\u6570\uff0c\u6d88\u606f\u538b\u7f29\u51cf\u5c11\u5e26\u5bbd\u548c\u5b58\u50a8\u538b\u529b\uff0c\u57fa\u4e8eNetty\u7684\u9ad8\u6548\u7f51\u7edc\u901a\u4fe1\u6a21\u578b\uff0c\u96f6\u62f7\u8d1d\u6280\u672f\u4f18\u5316\u78c1\u76d8\u8bfb\u5199\u6027\u80fd\uff0c\u987a\u5e8f\u5199\u63d0\u9ad8\u6570\u636e\u5199\u5165\u901f\u5ea6\uff0c\u9ad8\u6548\u6570\u636e\u5b58\u50a8\u7ed3\u6784\uff0c\u5f02\u6b65\u673a\u5236\u5305\u62ec\u5f02\u6b65\u5237\u76d8\u548c\u5f02\u6b65\u4e3b\u4ece\u590d\u5236\u63d0\u5347\u5b58\u50a8\u6548\u7387\uff0c\u6279\u91cf\u5904\u7406\u51cf\u5c11\u7f51\u7edc\u901a\u4fe1\u6b21\u6570\u548c\u8d44\u6e90\u6d88\u8017\uff0c\u9501\u4f18\u5316\u4ee5\u53ca\u7ebf\u7a0b\u6c60\u9694\u79bb\u63d0\u5347\u5e76\u53d1\u5904\u7406\u80fd\u529b\u3002\u4f5c\u8005\u901a\u8fc7\u6df1\u5165\u5206\u6790\u6e90\u7801\u7ed9\u51fa\u4e86RocketMQ\u5feb\u901f\u5904\u7406\u548c\u62c9\u53d6\u6d88\u606f\u7684\u5185\u5728\u539f\u56e0\uff0c\u5e76\u6df1\u5165\u8ba8\u8bba\u4e86\u6bcf\u79cd\u6280\u672f\u7684\u4f18\u52bf\u548c\u5b9e\u73b0\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/39t_G3InMtHg9ETj_xYR7Q"},"\u300a\u9886\u5bfc\u53eb\u6211\u63a5\u624b\u4e00\u4e2a\u65b0\u4e1a\u52a1\u7cfb\u7edf\uff0c\u6211\u662f\u8fd9\u6837\u719f\u6089\u9879\u76ee\u7684!\u300b"),"\u3002\u672c\u6587\u4f5c\u8005\u5c0f\u8bb8\u5206\u4eab\u4e86\u63a5\u624b\u65b0\u4e1a\u52a1\u7cfb\u7edf\u7684\u719f\u6089\u6d41\u7a0b\u548c\u5b9e\u8df5\u65b9\u6cd5\u3002\u5305\u62ec\u4e0e\u4ea7\u54c1\u7ecf\u7406\u4ea4\u6d41\u4e86\u89e3\u4e1a\u52a1\u73b0\u72b6\uff0c\u7ed8\u5236\u7528\u4f8b\u56fe\u3001ER\u56fe\u4ee5\u660e\u786e\u4e1a\u52a1\u4e0e\u6570\u636e\u6a21\u578b\uff0c\u68b3\u7406\u540e\u7aef\u6a21\u578b\u548c\u6838\u5fc3\u6d41\u7a0b\uff0c\u5e76\u8fd0\u7528\u72b6\u6001\u673a\u6d41\u8f6c\u56fe\u548c\u65f6\u5e8f\u56fe\u6df1\u5ea6\u89e3\u6790\u590d\u6742\u903b\u8f91\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u5230\u4e86\u7ed8\u5236\u7c7b\u56fe\u4ee5\u7406\u89e3\u4ee3\u7801\u7ed3\u6784\u3002\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u5957\u7cfb\u7edf\u6027\u7684\u5de5\u5177\u548c\u65b9\u6cd5\uff0c\u76ee\u7684\u662f\u5e2e\u52a9\u65b0\u6210\u5458\u6216\u8d1f\u8d23\u65b0\u9879\u76ee\u7684\u5f00\u53d1\u4eba\u5458\u5feb\u901f\u638c\u63e1\u4e1a\u52a1\u903b\u8f91\uff0c\u6709\u6548\u63a8\u8fdb\u9879\u76ee\u8fdb\u5ea6\u3002"),(0,r.kt)("h2",{id:"-\u524d\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GqSoZR3bSeuLWiULHt8Zvg"},"\u300aTango \u4f4e\u4ee3\u7801\u5f15\u64ce\u6c99\u7bb1\u5b9e\u73b0\u89e3\u6790\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86Tango\u4f4e\u4ee3\u7801\u5f15\u64ce\u7684\u6c99\u7bb1\u5b9e\u73b0\u3002Tango\u662f\u4e00\u4e2a\u7528\u4e8e\u5feb\u901f\u6784\u5efa\u4f4e\u4ee3\u7801\u5e73\u53f0\u7684\u4f4e\u4ee3\u7801\u8bbe\u8ba1\u5668\u6846\u67b6\uff0c\u901a\u8fc7\u5bf9\u6e90\u4ee3\u7801\u8fdb\u884c\u6267\u884c\u548c\u6e32\u67d3\u524d\u7aef\u89c6\u56fe\uff0c\u5b9e\u73b0\u4e86\u4f4e\u4ee3\u7801\u53ef\u89c6\u5316\u642d\u5efa\u80fd\u529b\u3002\u501f\u52a9Tango\u6784\u5efa\u7684\u4f4e\u4ee3\u7801\u5de5\u5177\u6216\u5e73\u53f0\u53ef\u4ee5\u5b9e\u73b0\u6e90\u7801\u8fdb\u51fa\u7684\u6548\u679c\uff0c\u5e76\u4e0e\u4f01\u4e1a\u5185\u90e8\u73b0\u6709\u7684\u7814\u53d1\u4f53\u7cfb\u8fdb\u884c\u65e0\u7f1d\u96c6\u6210\u3002Tango\u7684\u8bbe\u8ba1\u5668\u5f15\u64ce\u90e8\u5206\u5df2\u7ecf\u5f00\u6e90\uff0c\u5e76\u63d0\u4f9b\u4e86\u76f8\u5e94\u7684\u5f00\u6e90\u4ee3\u7801\u5e93\u3001\u6587\u6863\u548c\u793e\u533a\u8ba8\u8bba\u7ec4\u3002\u6b22\u8fce\u52a0\u5165\u793e\u533a\u53c2\u4e0e\u5230Tango\u4f4e\u4ee3\u7801\u5f15\u64ce\u7684\u5f00\u6e90\u5efa\u8bbe\u4e2d\u3002\u66f4\u591a\u76f8\u5173\u6587\u7ae0\u53ef\u4ee5\u5728\u6587\u4e2d\u63d0\u4f9b\u7684\u94fe\u63a5\u4e2d\u627e\u5230\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/U6ZQwLiW5sfkknz_bayosg"},"\u300a\u672a\u6765\u53ea\u9700\u8981 2% \u7684\u7a0b\u5e8f\u5458?\u300b"),"\u3002DHH\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u63d0\u51fa\u4e00\u4e2a\u6fc0\u8fdb\u7684\u89c2\u70b9\uff0c\u9884\u6d4b\u672a\u6765\u7a0b\u5e8f\u5458\u7684\u9700\u6c42\u53ef\u80fd\u4f1a\u5927\u5e45\u5ea6\u51cf\u5c11\u3002\u4ed6\u6bd4\u8f83\u4e86\u519c\u4e1a\u4ece97%\u7684\u4eba\u53e3\u9700\u6c42\u964d\u81f32%\u7684\u53d8\u8fc1\uff0c\u6697\u793a\u8f6f\u4ef6\u5f00\u53d1\u4e5f\u53ef\u80fd\u9762\u4e34\u7740\u7c7b\u4f3c\u7f29\u51cf\u3002\u5c3d\u7ba1\u8fd9\u4e2a\u884c\u4e1a\u66fe\u7ecf\u7ecf\u5386\u62db\u8058\u70ed\u6f6e\uff0c\u4f46\u73b0\u5728\u8bb8\u591a\u7a0b\u5e8f\u5458\u9762\u4e34\u804c\u4e1a\u524d\u666f\u4e0d\u7a33\u5b9a\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86\u4eba\u5de5\u667a\u80fd\u7684\u53d1\u5c55\u7ed9\u7a0b\u5e8f\u5458\u804c\u4e1a\u5e26\u6765\u7684\u538b\u529b\uff0c\u540c\u65f6\u4e5f\u6307\u51fa\u804c\u4e1a\u53d8\u9769\u7684\u4e0d\u786e\u5b9a\u6027\u3002DHH\u8ba4\u4e3a\uff0c\u672a\u6765\u5927\u591a\u6570\u7a0b\u5e8f\u5458\u53ef\u80fd\u65e0\u9700\u624b\u52a8\u7f16\u7a0b\uff0c\u4f46\u540c\u65f6\u6307\u51fa\u79d1\u6280\u884c\u4e1a\u5c06\u66f4\u52a0\u878d\u5408\u8fdb\u793e\u4f1a\uff0c\u5e76\u63d0\u9ad8\u4e86\u5b83\u7684\u4ef7\u503c\u3002\u4ed6\u9f13\u52b1\u7a0b\u5e8f\u5458\u63a5\u53d7\u8fd9\u4e00\u53d8\u5316\uff0c\u5e76\u4eab\u53d7\u884c\u4e1a\u7684\u9ec4\u91d1\u65f6\u4ee3\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/tiolzTwPKPZF4b8zZbvYpA"},"\u300a\u524d\u7aef\u667a\u80fd\u5316\uff0c\u6263\u5b50(coze.cn)\u80fd\u505a\u4ec0\u4e48?\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u6263\u5b50\uff08coze.cn\uff09\u5e73\u53f0\u5982\u4f55\u901a\u8fc7\u63d0\u4f9b\u4e00\u4e2a\u7b80\u5355\u7684\u4ea4\u4e92\u5f0f\u754c\u9762\u6765\u521b\u5efa\u804a\u5929\u673a\u5668\u4eba\uff08Chatbot\uff09\u3002\u7528\u6237\u901a\u8fc7\u4e0e\u6263\u5b50\u7684\u5bf9\u8bdd\uff0c\u53ef\u4ee5\u5feb\u901f\u8bbe\u7f6e\u4e00\u4e2aChatbot\uff0c\u5982\u81ea\u52a8\u5316\u5fae\u4fe1\u8ba2\u9605\u53f7\u5185\u5bb9\u53d1\u5e03\u7b49\u3002\u6587\u7ae0\u5f3a\u8c03\u4e86\u5e73\u53f0\u7684\u6613\u7528\u6027\u548c\u754c\u9762\u53cb\u597d\u6027\uff0c\u540c\u65f6\u6307\u51fa\u4e86\u4e00\u4e9b\u6f5c\u5728\u7f3a\u70b9\uff0c\u5305\u62ec\u65e0\u6cd5\u89e3\u51b3\u6df1\u5ea6\u95ee\u9898\u548c\u5076\u5c14\u9047\u5230\u7684\u6280\u672f\u6545\u969c\u3002\u53e6\u5916\uff0c\u901a\u8fc7\u77e5\u8bc6\u5e93\u548c\u6570\u636e\u5e93\u7684\u96c6\u6210\uff0c\u53ef\u8fdb\u4e00\u6b65\u63d0\u5347Bot\u7684\u529f\u80fd\u3002\u4f5c\u8005\u5bf9\u6263\u5b50\u7684\u673a\u5668\u4eba\u521b\u5efa\u8fc7\u7a0b\u3001\u4f18\u52bf\u3001\u5efa\u8bae\u548c\u6539\u8fdb\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u901a\u8fc7\u5b9e\u64cd\u6848\u4f8b\u5c55\u793a\u4e86\u524d\u7aef\u667a\u80fd\u5316\u673a\u5668\u4eba\u7684\u642d\u5efa\u8fc7\u7a0b\u3002"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8e0fd697.91d6ac12.js b/assets/js/8e0fd697.eba8e2bf.js similarity index 92% rename from assets/js/8e0fd697.91d6ac12.js rename to assets/js/8e0fd697.eba8e2bf.js index 4edbfce303..05afb2d3f0 100644 --- a/assets/js/8e0fd697.91d6ac12.js +++ b/assets/js/8e0fd697.eba8e2bf.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[8874],{46280:e=>{e.exports=JSON.parse('{"title":"All posts in 2024","items":[{"title":"\u7f6e\u9876\u5185\u5bb9","permalink":"/frontend-weekly/2024/welcome"},{"title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[8874],{46280:e=>{e.exports=JSON.parse('{"title":"All posts in 2024","items":[{"title":"\u7f6e\u9876\u5185\u5bb9","permalink":"/frontend-weekly/2024/welcome"},{"title":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b"},{"title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b"}]}')}}]); \ No newline at end of file diff --git a/assets/js/a02a2c89.d92da2a4.js b/assets/js/a02a2c89.d92da2a4.js new file mode 100644 index 0000000000..55f5af91b8 --- /dev/null +++ b/assets/js/a02a2c89.d92da2a4.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[8520],{49613:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>k});var a=n(59496);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function p(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function o(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var p=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var l=a.createContext({}),s=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},m=function(e){var t=s(e.components);return a.createElement(l.Provider,{value:t},e.children)},c="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},h=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,p=e.originalType,l=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),c=s(n),h=r,k=c["".concat(l,".").concat(h)]||c[h]||u[h]||p;return n?a.createElement(k,o(o({ref:t},m),{},{components:n})):a.createElement(k,o({ref:t},m))}));function k(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var p=n.length,o=new Array(p);o[0]=h;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[c]="string"==typeof e?e:r,o[1]=i;for(var s=2;s{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>o,default:()=>u,frontMatter:()=>p,metadata:()=>i,toc:()=>s});var a=n(64778),r=(n(59496),n(49613));const p={slug:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},o=void 0,i={permalink:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-17/index.md",source:"@site/blogs/2024/2024-03-17/index.md",title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",description:"\ud83c\udf1f AI \u76f8\u5173",date:"2024-03-17T00:00:00.000Z",formattedDate:"March 17, 2024",tags:[],readingTime:45.52,hasTruncateMarker:!1,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",authors:["garfield"],tags:[]},prevItem:{title:"\u7f6e\u9876\u5185\u5bb9",permalink:"/frontend-weekly/2024/welcome"},nextItem:{title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"}},l={authorsImageUrls:[void 0]},s=[{value:"\ud83c\udf1f AI \u76f8\u5173",id:"-ai-\u76f8\u5173",level:2},{value:"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173",id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173",id:"-\u540e\u7aef\u76f8\u5173",level:2},{value:"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173",id:"-\u524d\u7aef\u76f8\u5173",level:2}],m={toc:s},c="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(c,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h2",{id:"-ai-\u76f8\u5173"},"\ud83c\udf1f AI \u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/QBORpQmZrumppLl81aWAxA"},"\u300a\u5357\u6d0b\u7406\u5de5\u53d1\u5e03\u591a\u6a21\u6001\u91d1\u878d\u4ea4\u6613Agent\uff0c\u5e73\u5747\u5229\u6da6\u63d0\u9ad836%\uff01\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u5357\u6d0b\u7406\u5de5\u5927\u5b66\u53d1\u5e03\u7684\u591a\u6a21\u6001\u91d1\u878d\u4ea4\u6613Agent\uff0c\u901a\u8fc7\u878d\u5408\u5927\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u548c\u591a\u6a21\u6001\u6570\u636e\u5904\u7406\uff0c\u63d0\u9ad8\u4e86\u91d1\u878d\u4ea4\u6613\u7684\u6548\u76ca\u3002\u4f20\u7edf\u57fa\u4e8e\u89c4\u5219\u7684\u4ea4\u6613\u7cfb\u7edf\u5728\u9002\u5e94\u5e02\u573a\u6ce2\u52a8\u65b9\u9762\u5b58\u5728\u4e0d\u8db3\uff0c\u800c\u57fa\u4e8e\u5f3a\u5316\u5b66\u4e60\u7684\u7cfb\u7edf\u867d\u7136\u9002\u5e94\u6027\u66f4\u597d\uff0c\u4f46\u5728\u5904\u7406\u591a\u6a21\u6001\u6570\u636e\u548c\u53ef\u89e3\u91ca\u6027\u65b9\u9762\u4ecd\u9762\u4e34\u6311\u6218\u3002\u8be5\u6587\u4e2d\u63d0\u51fa\u7684FinAgent\u662f\u4e00\u79cd\u5148\u8fdb\u7684\u591a\u6a21\u6001\u57fa\u7840\u4ee3\u7406\uff0c\u80fd\u591f\u7efc\u5408\u5206\u6790\u591a\u79cd\u5f62\u5f0f\u7684\u91d1\u878d\u6570\u636e\uff0c\u63d0\u4f9b\u7cbe\u786e\u7684\u5e02\u573a\u8d8b\u52bf\u5206\u6790\u548c\u51b3\u7b56\u652f\u6301\u3002\u5b9e\u9a8c\u8bc1\u660e\uff0c\u4f7f\u7528FinAgent\u8fdb\u884c\u91d1\u878d\u4ea4\u6613\u53ef\u4ee5\u5e73\u5747\u63d0\u9ad836%\u7684\u5229\u6da6\u3002\u8bba\u6587\u94fe\u63a5\uff1a",(0,r.kt)("a",{parentName:"p",href:"https://arxiv.org/pdf/2402.18485.pdf"},"https://arxiv.org/pdf/2402.18485.pdf")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/kek5xGP96UOJ3Rpfw3V-FQ"},"\u300a\u5927\u6a21\u578b\u63a8\u7406:A100/H100 \u592a\u8d35\uff0c\u4f55\u4e0d\u7528 4090?\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u5927\u6a21\u578b\u63a8\u7406\u65f6\uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u8003\u8651\u4f7f\u75284090\u663e\u5361\u3002\u76f8\u6bd4\u4e8eA100\u548cH100\u663e\u5361\uff0c4090\u5728\u6027\u4ef7\u6bd4\u4e0a\u66f4\u9ad8\uff0c\u5c24\u5176\u5728\u6781\u81f4\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u53ef\u4ee5\u8fbe\u5230H100\u76842\u500d\u6027\u80fd\u3002\u6587\u7ae0\u6307\u51fa\uff0cA100\u3001H100\u548c4090\u5728\u7b97\u529b\u65b9\u9762\u7684\u5dee\u8ddd\u5e76\u4e0d\u5927\uff0c\u6700\u5927\u7684\u533a\u522b\u5728\u901a\u4fe1\u548c\u5185\u5b58\u65b9\u9762\u3002\u7531\u4e8e\u5927\u6a21\u578b\u8bad\u7ec3\u4f7f\u7528\u9ad8\u6027\u80fd\u7684\u901a\u4fe1\uff0c4090\u901a\u4fe1\u6548\u7387\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u6b64\u5728\u5927\u6a21\u578b\u8bad\u7ec3\u4e2d\u5e76\u4e0d\u9002\u7528\u3002\u7136\u800c\uff0c\u5728\u63a8\u7406\uff08inference/serving\uff09\u65b9\u9762\uff0c4090\u5728\u6027\u4ef7\u6bd4\u4e0a\u6709\u4f18\u52bf\uff0c\u5c24\u5176\u662f\u76f8\u5bf9\u4e8eH100\u663e\u5361\u800c\u8a00\u3002\u6587\u7ae0\u8fd8\u63d0\u5230\u4e86GPU\u7684\u8bad\u7ec3\u6027\u80fd\u548c\u6210\u672c\u5bf9\u6bd4\uff0c\u4ee5\u53ca\u5927\u6a21\u578b\u8bad\u7ec3\u6240\u9700\u7684\u7b97\u529b\u548cGPU\u6570\u91cf\u7b49\u95ee\u9898\u3002\u8be6\u7ec6\u5185\u5bb9\u53ef\u53c2\u8003\u6587\u7ae0\u94fe\u63a5\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/tKVHsoR_opgBqtCMDHbv6Q"},"\u300a\u7cbe\u5ea6\u63d0\u5347!\u5357\u52a0\u5927\u7b49 | \u63d0\u51fa\u5206\u6cbbPrompt\u7b56\u7565\uff0c\u63d0\u5347LLM\u5206\u8fa8\u529b\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b97\u6cd5\u7684Prompt\u7b56\u7565\uff0c\u65e8\u5728\u63d0\u9ad8\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u7684\u5206\u8fa8\u529b\u3002\u73b0\u6709\u7684\u63d0\u793a\u7b56\u7565\u5728\u5904\u7406\u6d89\u53ca\u91cd\u590d\u5b50\u4efb\u52a1\u548c\u542b\u6709\u6b3a\u9a97\u6027\u5185\u5bb9\u7684\u4efb\u52a1\u65f6\u5b58\u5728\u4e00\u5b9a\u9650\u5236\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u7814\u7a76\u4eba\u5458\u63d0\u51fa\u4e86\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b97\u6cd5\u7684\u63d0\u793a\u7b56\u7565\uff0c\u5229\u7528\u5206\u6cbb\u7a0b\u5e8f\u6765\u5f15\u5bfcLLM\u7684\u6c42\u89e3\u8fc7\u7a0b\u3002\u8be5\u7b56\u7565\u5c06\u4efb\u52a1\u5212\u5206\u4e3a\u5b50\u95ee\u9898\u5e76\u5206\u522b\u6c42\u89e3\uff0c\u7136\u540e\u5408\u5e76\u5b50\u95ee\u9898\u7684\u7b54\u6848\u3002\u901a\u8fc7\u5b9e\u9a8c\u8bc1\u660e\uff0c\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u63d0\u5347\u6a21\u578b\u5728\u5927\u6574\u6570\u4e58\u6cd5\u3001\u5e7b\u89c9\u68c0\u6d4b\u548c\u65b0\u95fb\u9a8c\u8bc1\u7b49\u4efb\u52a1\u4e2d\u7684\u6027\u80fd\uff0c\u76f8\u6bd4\u4f20\u7edf\u63d0\u793a\u7b56\u7565\u5177\u6709\u66f4\u597d\u7684\u51c6\u786e\u7387\u548c\u6027\u80fd\u6307\u6807\u3002\u8bba\u6587\u5730\u5740\uff1a",(0,r.kt)("a",{parentName:"p",href:"https://arxiv.org/pdf/2402.05359.pdf"},"https://arxiv.org/pdf/2402.05359.pdf")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/sxgfJf4vxvaxhO5L7-Npwg"},"\u300a\u5f00\u6e90\u7248\u201cDevin\u201dAI\u7a0b\u5e8f\u5458\u70b8\u573a:\u81ea\u5df1\u5206\u6790\u80a1\u7968\u3001\u505a\u62a5\u8868\u3001\u5efa\u6a21\u578b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u4e2a\u57fa\u4e8eMetaGPT\u7684\u5f00\u6e90\u9879\u76eeData Interpreter\uff0c\u8be5\u9879\u76ee\u65e8\u5728\u5904\u7406\u6570\u636e\u5b9e\u65f6\u53d8\u5316\u3001\u4efb\u52a1\u4e4b\u95f4\u7684\u590d\u6742\u4f9d\u8d56\u5173\u7cfb\u3001\u6d41\u7a0b\u4f18\u5316\u9700\u6c42\u4ee5\u53ca\u6267\u884c\u7ed3\u679c\u53cd\u9988\u7684\u903b\u8f91\u4e00\u81f4\u6027\u7b49\u6311\u6218\u3002\u901a\u8fc7\u6f14\u793a\uff0c\u5c55\u793a\u4e86Data Interpreter\u5728\u5206\u6790\u80a1\u7968\u3001\u9884\u6d4b\u8461\u8404\u9152\u8d28\u91cf\u3001\u81ea\u52a8\u62a0\u56fe\u3001\u9884\u6d4b\u75be\u75c5\u8fdb\u5c55\u548c\u9884\u6d4b\u673a\u5668\u8fd0\u884c\u72b6\u6001\u7b49\u65b9\u9762\u7684\u80fd\u529b\u3002\u8be5\u9879\u76ee\u7531MetaGPT\u56e2\u961f\u4e0e\u591a\u6240\u9ad8\u6821\u5408\u4f5c\u63a8\u51fa\uff0c\u63d0\u4f9b\u4e86\u4e00\u79cd\u81ea\u4e3b\u8fdb\u884c\u6570\u636e\u5206\u6790\u548c\u5efa\u6a21\u7684\u5f00\u6e90\u5de5\u5177\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/n98IZHs7LTXMzzS3KmHvrA"},"\u300a\u3010\u539f\u521b\u3011\u4e00\u6587\u8bfb\u61c2RAG\u7684\u6765\u6e90\u3001\u53d1\u5c55\u548c\u524d\u6cbf\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u6280\u672f\uff0c\u8be5\u6280\u672f\u7ed3\u5408\u4e86\u68c0\u7d22\u548c\u751f\u6210\u8fc7\u7a0b\uff0c\u65e8\u5728\u63d0\u9ad8\u673a\u5668\u751f\u6210\u6587\u672c\u7684\u76f8\u5173\u6027\u3001\u51c6\u786e\u6027\u548c\u591a\u6837\u6027\u3002\u6587\u7ae0\u8be6\u7ec6\u89e3\u91ca\u4e86\u5e7b\u89c9\u95ee\u9898\u7684\u5b58\u5728\u4ee5\u53ca\u89e3\u51b3\u5e7b\u89c9\u95ee\u9898\u7684\u51e0\u79cd\u5e38\u89c1\u65b9\u6cd5\u3002RAG\u5229\u7528\u5916\u90e8\u6570\u636e\u6e90\u8fdb\u884c\u4fe1\u606f\u68c0\u7d22\uff0c\u5c06\u68c0\u7d22\u5230\u7684\u4fe1\u606f\u4f5c\u4e3a\u4e0a\u4e0b\u6587\u8f93\u5165\u5230\u751f\u6210\u6a21\u578b\u4e2d\uff0c\u4ece\u800c\u5e2e\u52a9\u751f\u6210\u6b63\u786e\u7684\u54cd\u5e94\u3002\u8ba8\u8bba\u4e86RAG\u7684\u6838\u5fc3\u90e8\u4ef6\uff0c\u5982\u5411\u91cf\u6570\u636e\u5e93\u3001\u67e5\u8be2\u68c0\u7d22\u548c\u91cd\u65b0\u6392\u5e8f\u3002\u540c\u65f6\u4ecb\u7ecd\u4e86RAG\u5728\u77e5\u8bc6\u56fe\u8c31\u548c\u6811\u7ed3\u6784\u65b9\u9762\u7684\u62d3\u5c55\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/NoREsyLXNVk1aABtSkhBDA"},"\u300a\u4e07\u5b57\u957f\u6587\u89e3\u6790:\u5927\u6a21\u578b\u9700\u8981\u600e\u6837\u7684\u786c\u4ef6\u7b97\u529b\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u5927\u6a21\u578b\u5728\u7b97\u529b\u3001\u5b58\u50a8\u3001\u901a\u4fe1\u7b49\u591a\u4e2a\u65b9\u9762\u4e0a\u786c\u4ef6\u8d44\u6e90\u7684\u6311\u6218\u548c\u74f6\u9888\u3002\u6587\u7ae0\u5206\u6790\u4e86\u4ee5Transformer\u7ed3\u6784\u4e3a\u6838\u5fc3\u7684\u5927\u6a21\u578b\u5728\u7b97\u529b\u74f6\u9888\u3001\u663e\u5b58\u74f6\u9888\u548c\u901a\u4fe1\u74f6\u9888\u65b9\u9762\u7684\u56f0\u5883\uff0c\u4ee5\u53ca\u5f53\u524d\u6240\u91c7\u53d6\u7684\u786c\u4ef6\u8d44\u6e90\u4f18\u5316\u6280\u672f\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u63d0\u4f9b\u4e86\u5bf9\u5927\u6a21\u578b\u53c2\u6570\u91cf\u548c\u7b97\u529b\u9700\u6c42\u7684\u91cf\u5316\u4f30\u7b97\uff0c\u4e3a\u9009\u62e9\u5408\u9002\u7684\u786c\u4ef6\u8bbe\u5907\u548c\u8bc4\u4f30\u8d44\u6e90\u9700\u6c42\u63d0\u4f9b\u4e86\u6307\u5bfc\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lbLOqiW-DoHq_S9qpYcbCQ"},"\u300a\u4ec0\u4e48\u662f\u597d\u7684\u5927\u6a21\u578b\u8bad\u7ec3\u6570\u636e?\u300b"),"\u3002\u672c\u6587\u57fa\u4e8eLilian Weng\u7684\u535a\u5ba2\uff0c\u8ba8\u8bba\u4e86\u5927\u6a21\u578b\u5982LLM\u5728\u8bad\u7ec3\u8fc7\u7a0b\u4e2d\u5bf9\u9ad8\u8d28\u91cf\u6570\u636e\u7684\u9700\u6c42\u3002\u8ba4\u4e3a\u9ad8\u8d28\u91cf\u6570\u636e\u6765\u6e90\u4e8e\u201c\u9ad8\u8d28\u91cf\u4eba\u7c7b\u201d\u4ea7\u751f\u7684\u6807\u6ce8\u6570\u636e\uff0c\u5e76\u5f3a\u8c03\u4e86\u6570\u636e\u5904\u7406\u7684\u91cd\u8981\u6027\uff0c\u63d0\u5230\u4e86\u6570\u636e\u6807\u6ce8\u3001\u8d28\u91cf\u63a7\u5236\u548c\u9519\u8bef\u4fee\u6b63\u7684\u91cd\u8981\u6b65\u9aa4\u3002\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u7528\u4e8e\u8bc4\u4f30\u6570\u636e\u8d28\u91cf\u7684\u591a\u79cd\u65b9\u6cd5\uff0c\u5982Influence Functions\u548cNoisy Cross-Validation\uff0c\u5e76\u63d0\u51fa\u4e86\u4e13\u6ce8\u4e8e\u201c\u642d\u5efa\u9ad8\u8d28\u91cf\u7684\u6570\u636e\u6807\u6ce8pipeline\u201d\u7684\u4f01\u4e1a\u65b9\u5411\u3002\u6700\u540e\u6307\u51fa\uff0c\u5728AI\u65f6\u4ee3\u5927\u91cf\u4ea7\u51fa\u7684\u6570\u636e\u4e2d\u7ef4\u62a4\u6570\u636e\u8d28\u91cf\uff0c\u662f\u4e00\u4e2a\u503c\u5f97\u5173\u6ce8\u7684\u6311\u6218\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dA757HASxJPYuAbRZ7KvUQ"},"\u300a\u8bfb\u8fc7\u7684\u6700\u767d\u8bdd\u8bb2\u6e05\u695aRAG\u539f\u7406\u7684\u6587\u7ae0\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u76f4\u89c2\u5730\u9610\u91ca\u4e86\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u7684\u6982\u5ff5\u548c\u5de5\u4f5c\u539f\u7406\uff0c\u5b83\u662f\u4e00\u79cd\u7ed3\u5408\u68c0\u7d22\u548c\u751f\u6210\u7684\u95ee\u7b54\u7cfb\u7edf\u3002\u8be5\u7cfb\u7edf\u9996\u5148\u901a\u8fc7\u68c0\u7d22\u6b65\u9aa4\u627e\u5230\u4e0e\u7528\u6237\u95ee\u9898\u6700\u76f8\u5173\u7684\u77e5\u8bc6\u5e93\u5185\u5bb9\uff0c\u7136\u540e\u5c06\u8fd9\u4e9b\u5185\u5bb9\u4e0e\u95ee\u9898\u5171\u540c\u8f93\u5165\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u4f8b\u5982ChatGPT\uff09\u4ee5\u751f\u6210\u7b54\u6848\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u5d4c\u5165\u6a21\u578b\u5bf9\u77e5\u8bc6\u5e93\u6587\u672c\u8fdb\u884c\u7d22\u5f15\uff0c\u4ee5\u4fbf\u534f\u52a9\u8bed\u8a00\u6a21\u578b\u8fdb\u884c\u7cbe\u786e\u7684\u68c0\u7d22\u3002\u6b64\u5916\uff0c\u5b83\u8fd8\u63a2\u8ba8\u4e86\u8bed\u4e49\u641c\u7d22\u80cc\u540e\u7684\u6838\u5fc3\u539f\u5219\u548c\u6280\u672f\u7ec6\u8282\u70b9\uff0c\u5982\u4f55\u901a\u8fc7\u5d4c\u5165\u627e\u5230\u4e0e\u7528\u6237\u8f93\u5165\u6700\u5339\u914d\u7684\u77e5\u8bc6\uff0c\u4ee5\u53ca\u5982\u4f55\u683c\u5f0f\u5316\u6587\u6863\u4ee5\u4f9b\u8bed\u8a00\u6a21\u578b\u4f7f\u7528\uff0c\u4ee5\u4fbf\u83b7\u5f97\u66f4\u9ad8\u6548\u7684\u56de\u7b54\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://zhuanlan.zhihu.com/p/685794495"},"\u300aLLM\u63a8\u7406\u7b97\u6cd5\u7b80\u8ff0\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u7528\u4e8e\u63d0\u9ad8\u5927\u578b\u8bed\u8a00\u6a21\u578b(LLM)\u63a8\u7406\u6027\u80fd\u7684\u5173\u952e\u6280\u672f\u4e0e\u7b56\u7565\u3002\u5185\u5bb9\u6db5\u76d6\u663e\u5b58\u4f18\u5316\u65b9\u6cd5\uff0c\u5982KV Cache\u51cf\u5c11\u663e\u5b58\u6d6a\u8d39\u3001MQA\u548cGQA\u51cf\u5c11KV-Cache\u6570\u91cf\u3001Page Attention\u8fdb\u884c\u663e\u5b58\u7ba1\u7406\uff0c\u4ee5\u53ca\u63d0\u9ad8\u63a8\u7406\u901f\u5ea6\u7684FlashAttention\u6539\u8fdb\u3002\u6587\u7ae0\u8fd8\u63a2\u8ba8\u4e86\u7b97\u5b50\u878d\u5408\u6280\u672f\uff0c\u6bd4\u5982FasterTransformer\u548cDeepSpeed Inference\u7684\u5e94\u7528\uff0c\u4ee5\u53ca\u8c03\u5ea6\u4f18\u5316\u7b56\u7565\u5982Async Serving\u548cDynamic Batch\uff0c\u6700\u540e\u4ecb\u7ecd\u4e86\u7528\u4e8e\u5904\u7406\u5927\u6a21\u578b\u7684\u5206\u5e03\u5f0f\u5e76\u884c\u6280\u672f\u3002\u8fd9\u4e9b\u4f18\u5316\u624b\u6bb5\u80fd\u663e\u8457\u63d0\u9ad8LLM\u63a8\u7406\u8fc7\u7a0b\u4e2d\u7684\u6027\u80fd\u4e0e\u6548\u7387\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/V8Tz5X81FlOva9B6bCprqg"},"\u300a\u6570\u5b66\u63a8\u7406\u589e\u5f3a!\u5fae\u8f6f | \u63d0\u51fa\u6570\u636e\u5408\u6210\u6846\u67b6:KPDDS\uff0c\u5fae\u8c03Mistral-7B\u6027\u80fd\u8d8534B\u6a21\u578b!\u300b"),"\u3002\u5fae\u8f6f\u7684\u7814\u7a76\u56e2\u961f\u4e3a\u63d0\u5347\u5927\u578b\u8bed\u8a00\u6a21\u578b(Large Language Models, LLMs)\u5728\u6570\u5b66\u63a8\u7406\u4efb\u52a1\u7684\u6027\u80fd\uff0c\u63d0\u51fa\u4e86\u5173\u952e\u70b9\u9a71\u52a8\u7684\u6570\u636e\u5408\u6210(KPDDS)\u6846\u67b6\u3002KPDDS\u5229\u7528\u771f\u5b9e\u6570\u636e\u6e90\u4e2d\u7684\u5173\u952e\u70b9\u548c\u793a\u4f8b\u5bf9\u751f\u6210\u9ad8\u8d28\u91cf\u95ee\u7b54\u5bf9\u6765\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u3002\u7814\u7a76\u8005\u57fa\u4e8e\u6b64\u6846\u67b6\u521b\u5efa\u4e86KPMath\u6570\u636e\u96c6\uff0c\u8fdb\u4e00\u6b65\u7ed3\u5408\u63a8\u7406\u5bc6\u96c6\u578b\u6570\u636e\u5f62\u6210KPMath-Plus\u6570\u636e\u96c6\u3002\u5728MATH\u6d4b\u8bd5\u96c6\u4e0a\uff0c\u5fae\u8c03\u540e\u7684Mistral-7B\u6a21\u578b\u8fbe\u5230\u4e8639.3%\u7684\u96f6\u6837\u672c\u901a\u8fc7\u7387\uff0c\u8d85\u8d8a\u4e86\u6570\u91cf\u66f4\u591a\u768434B\u6a21\u578b\uff0c\u8bc1\u660e\u4e86KPDDS\u7684\u6709\u6548\u6027\u4e0e\u521b\u65b0\u6027\u3002\u8fd9\u4e00\u6210\u679c\u6807\u5fd7\u7740LLMs\u5728\u6570\u5b66\u63a8\u7406\u65b9\u9762\u7684\u6027\u80fd\u5f97\u5230\u663e\u8457\u63d0\u5347\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/QkkYAilf4_XZyBRqSIEL2Q"},"\u300a\u9996\u4e2aAI\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u4e0a\u7ebf!\u5df2\u901a\u8fc7\u516c\u53f8\u9762\u8bd5\u62a2\u7a0b\u5e8f\u5458\u996d\u7897\uff0c\u534e\u4eba\u521b\u59cb\u56e2\u961f\u624b\u63e110\u5757IOI\u91d1\u724c\u300b"),"\u3002\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u4e86\u7531\u534e\u4eba\u521b\u7acb\u7684Cognition AI\u516c\u53f8\u5f00\u53d1\u51fa\u6765\u7684\u9996\u4e2a\u4eba\u5de5\u667a\u80fd\u8f6f\u4ef6\u5de5\u7a0b\u5e08Devin\u3002\u4e0e\u73b0\u6709GPT-4\u7b49\u6a21\u578b\u4e0d\u540c\uff0cDevin\u80fd\u591f\u72ec\u7acb\u5b8c\u6210\u590d\u6742\u7684\u7f16\u7a0b\u4efb\u52a1\uff0c\u5e76\u5df2\u6210\u529f\u901a\u8fc7\u4eba\u5de5\u667a\u80fd\u516c\u53f8\u7684\u9762\u8bd5\u548c\u5728\u81ea\u7531\u804c\u4e1a\u5e73\u53f0Upwork\u4e0a\u63a5\u5355\u3002\u5f97\u76ca\u4e8eCognition AI\u5728\u957f\u671f\u63a8\u7406\u548c\u89c4\u5212\u65b9\u9762\u7684\u8fdb\u6b65\uff0cDevin\u5728\u505a\u51b3\u7b56\u548c\u6267\u884c\u4efb\u52a1\u65f6\uff0c\u80fd\u56de\u60f3\u76f8\u5173\u4e0a\u4e0b\u6587\u3001\u968f\u65f6\u95f4\u5b66\u4e60\u5e76\u4fee\u590d\u9519\u8bef\u3002\u8fd9\u6807\u5fd7\u7740\u4eba\u5de5\u667a\u80fd\u5728\u7406\u89e3\u771f\u5b9e\u4e16\u754c\u8f6f\u4ef6\u5de5\u7a0b\u95ee\u9898\u65b9\u9762\u53d6\u5f97\u4e86\u7a81\u7834\uff0c\u4e3aAI\u9886\u57df\u8fc8\u5411\u66f4\u9ad8\u5c42\u7ea7\u7684\u81ea\u52a8\u5316\u53ca\u76d1\u7763\u6027\u5de5\u4f5c\u5f00\u8f9f\u9053\u8def\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/q_lgeiXFzTU4WEt9wpUG3w"},"\u300a\u5411\u6570\u5b57\u4e16\u754cAGI\u8fc8\u8fdb!\u667a\u80fd\u4f53\u5df2\u7ecf\u4ece\u5934\u5f00\u73a9\u300c\u8352\u91ce\u5927\u9556\u5ba2 2\u300d\u4e86\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528Cradle\u8fd9\u4e00\u901a\u7528\u8ba1\u7b97\u673a\u63a7\u5236\u667a\u80fd\u4f53\u6846\u67b6\u8fdb\u884cAI\u7684\u7814\u7a76\u4e0e\u5e94\u7528\uff0c\u5728\u65e0\u9700\u5185\u90e8API\u652f\u6301\u4e0b\u63a7\u5236\u952e\u76d8\u548c\u9f20\u6807\u4ee5\u53ca\u4e0e\u5404\u7c7b\u8f6f\u4ef6\u4ea4\u4e92\u3002\u6587\u7ae0\u6765\u6e90\u4e8e\u5317\u4eac\u667a\u6e90\u4eba\u5de5\u667a\u80fd\u7814\u7a76\u9662\u3001\u65b0\u52a0\u5761\u5357\u6d0b\u7406\u5de5\u5927\u5b66\u548c\u5317\u4eac\u5927\u5b66\u7684\u8054\u5408\u7814\u7a76\u3002Cradle\u7531\u516d\u5927\u6a21\u5757\u7ec4\u6210\uff0c\u5305\u62ec\u4fe1\u606f\u6536\u96c6\u3001\u81ea\u6211\u53cd\u601d\u3001\u4efb\u52a1\u63a8\u65ad\u3001\u6280\u80fd\u7ba1\u7406\u3001\u884c\u52a8\u8ba1\u5212\u548c\u8bb0\u5fc6\u6a21\u5757\u3002\u8fd9\u4e9b\u6a21\u5757\u8ba9\u667a\u80fd\u4f53\u80fd\u591f\u81ea\u4e3b\u8fdb\u884c\u51b3\u7b56\u548c\u4efb\u52a1\u6267\u884c\u3002\u7814\u7a76\u56e2\u961f\u901a\u8fc7\u5c06Cradle\u90e8\u7f72\u4e8e\u300a\u8352\u91ce\u5927\u9556\u5ba2 2\u300b\u8fd9\u4e00\u590d\u6742\u76843A\u6e38\u620f\u4e2d\u8bc1\u660e\u5176\u901a\u7528\u6027\uff0cCradle\u80fd\u591f\u81ea\u4e3b\u5b8c\u6210\u6e38\u620f\u4e3b\u7ebf\u548c\u63a2\u7d22\u5f00\u653e\u4e16\u754c\u3002\u667a\u80fd\u4f53\u7684\u8fd9\u79cd\u901a\u7528\u80fd\u529b\u6807\u5fd7\u7740\u667a\u80fd\u4f53\u7814\u7a76\u5411\u901a\u7528\u4eba\u5de5\u667a\u80fd\uff08AGI\uff09\u8fc8\u8fdb\u7684\u91cd\u8981\u4e00\u6b65\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/U2472bnEvCE9lMPP-z0ysw"},"\u300a\u6df1\u5165\u6d45\u51fa LangChain \u4e0e\u667a\u80fd Agent:\u6784\u5efa\u4e0b\u4e00\u4ee3 AI \u52a9\u624b\u300b"),"\u3002\u6587\u7ae0\u6df1\u5165\u8bb2\u89e3\u4e86LangChain\u5de5\u5177\u7bb1\u53ca\u5176\u5982\u4f55\u8d4b\u80fd\u667a\u80fdAgent\uff0c\u4ee5\u6784\u5efa\u66f4\u52a0\u667a\u80fd\u7684AI\u52a9\u624b\u3002LangChain\u5229\u7528\u5927\u578b\u8bed\u8a00\u6a21\u578b\u5982GPT-4\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f00\u6e90\u8f6f\u4ef6\u6846\u67b6\uff0c\u53ef\u52a9\u529b\u5f00\u53d1\u8005\u642d\u5efa\u57fa\u4e8e\u8bed\u8a00\u6a21\u578b\u7684\u5e94\u7528\u3002\u5b83\u63d0\u4f9b\u4e86\u516d\u5927\u7c7b\u7ec4\u4ef6\uff0c\u5982\u6a21\u578b\u3001\u63d0\u793a\u6a21\u677f\u3001\u7d22\u5f15\u3001\u6587\u6863\u52a0\u8f7d\u5668\u3001\u6587\u672c\u5206\u5272\u5668\u548c\u5411\u91cf\u5b58\u50a8\uff0c\u8ba9GPT-4\u7b49\u6a21\u578b\u4e0d\u4ec5\u80fd\u5904\u7406\u8bed\u8a00\uff0c\u8fd8\u80fd\u4e0e\u5916\u90e8API\u4e92\u52a8\u3001\u7ba1\u7406\u7528\u6237\u4e0a\u4e0b\u6587\u3002\u6587\u7ae0\u4ee5\u6784\u5efa\u4eba\u8138\u6280\u672f\u95ee\u9898\u6392\u67e5\u52a9\u624b\u4e3a\u4f8b\uff0c\u5c55\u793a\u5982\u4f55\u8fd0\u7528LangChain\u6765\u534f\u52a9\u95ee\u9898\u8bca\u65ad\u4e0e\u667a\u80fd\u4ea4\u4e92\uff0c\u671d\u5411\u81ea\u4e3b\u3001\u9ad8\u6548\u7684\u667a\u80fd\u5e94\u7528\u53d1\u5c55\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/AAkITPRodLzvl61oALEI2Q"},"\u300a\u4f7f\u7528\u96f6\u4e00\u4e07\u7269 200K \u6a21\u578b\u548c Dify \u5feb\u901f\u642d\u5efa\u6a21\u578b\u5e94\u7528\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u4f7f\u7528\u96f6\u4e00\u4e07\u7269\u7684200K\u6a21\u578b\u548cDify\uff08LLM IDE\uff09\u5feb\u901f\u6784\u5efa\u6a21\u578b\u5e94\u7528\u7a0b\u5e8f\u3002\u4f5c\u8005\u9996\u5148\u5bf9\u4e00\u4e2a\u673a\u5668\u5b66\u4e60\u7535\u5b50\u4e66\u8fdb\u884c\u7ffb\u8bd1\uff0c\u5e76\u5206\u4eab\u4e86\u6e90\u4ee3\u7801\uff0c\u7136\u540e\u5f15\u5bfc\u8bfb\u8005\u5982\u4f55\u7533\u8bf7\u548c\u914d\u7f6e\u96f6\u4e00\u4e07\u7269\u6a21\u578bAPI\u3002\u968f\u540e\uff0c\u4f5c\u8005\u8bf4\u660e\u4e86\u5982\u4f55\u4f7f\u7528Dify IDE\u5feb\u901f\u642d\u5efa\u548c\u8c03\u8bd5\u6a21\u578b\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528Golang\u548cAI\u6a21\u578b\u81ea\u52a8\u5316\u7535\u5b50\u4e66\u7684\u7ffb\u8bd1\u8fc7\u7a0b\u3002\u6700\u540e\uff0c\u4f5c\u8005\u603b\u7ed3\u4e86\u81ea\u52a8\u7ffb\u8bd1\u7a0b\u5e8f\u7684\u6784\u5efa\u8fc7\u7a0b\u5e76\u5c55\u793a\u4e86\u6279\u91cf\u7ffb\u8bd1\u5185\u5bb9\u7684\u65b9\u6cd5\u3002\u6574\u7bc7\u6587\u7ae0\u4e0d\u4ec5\u662f\u4f7f\u7528Dify\u7684\u5b9e\u64cd\u6307\u5357\uff0c\u8fd8\u63d0\u4f9b\u4e86\u4e00\u79cd\u6548\u7387\u5316\u3001\u81ea\u52a8\u5316\u5904\u7406\u6587\u672c\u5185\u5bb9\u7684\u793a\u4f8b\uff0c\u9002\u5408\u90a3\u4e9b\u5728\u5bfb\u627e\u5feb\u901f\u5f00\u53d1\u548c\u96c6\u6210\u5927\u8bed\u8a00\u6a21\u578b\u5230\u5e94\u7528\u4e2d\u7684\u5f00\u53d1\u8005\u53c2\u8003\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/-9H0mLnvebzaLMaI6EKB6g"},"\u300a\u4e00\u6587\u770b\u5b8c\u591a\u6a21\u6001:\u4ece\u89c6\u89c9\u8868\u5f81\u5230\u591a\u6a21\u6001\u5927\u6a21\u578b\u300b"),"\u3002\u672c\u6587\u4e3a\u8bfb\u8005\u7cfb\u7edf\u68b3\u7406\u4e86\u56fe\u6587\u591a\u6a21\u6001\u4e0e\u591a\u6a21\u6001\u5927\u6a21\u578b\u9886\u57df\u7684\u53d1\u5c55\uff0c\u5c24\u5176\u805a\u7126\u5728\u89c6\u89c9\u8868\u5f81\u548c\u89c6\u89c9\u4e0e\u6587\u672c\u878d\u5408\u65b9\u6cd5\u4e0a\u3002\u6587\u7ae0\u4ece\u5377\u79ef\u795e\u7ecf\u7f51\u7edc\uff08CNN\uff09\u53ca\u5176\u9884\u8bad\u7ec3\u65b9\u6cd5\u5f00\u59cb\u8bb2\u8d77\uff0c\u4ece\u56fe\u50cf\u5904\u7406\u7684\u89c6\u89d2\u4ecb\u7ecd\u4e86\u591a\u6a21\u6001\u878d\u5408\u7684\u521d\u671f\u65b9\u6cd5\uff0c\u5982LXMERT\u3001VL-BERT\u548cUNITER\u7b49\u3002\u8fdb\u4e00\u6b65\uff0c\u6587\u7ae0\u8bba\u8ff0\u4e86Vision Transformer\uff08ViT\uff09\u53ca\u5176\u9884\u8bad\u7ec3\u65b9\u6848\u5982MAE\u548cBEIT\uff0c\u4ee5\u53ca\u57fa\u4e8eViT\u7684\u591a\u6a21\u6001\u5bf9\u9f50\u4e0e\u9884\u8bad\u7ec3\u6280\u672f\uff0c\u5982CLIP\u548cVILT\u7b49\u3002\u4f5c\u8005\u901a\u8fc7\u4e30\u5bcc\u7684\u793a\u4f8b\u548c\u5bf9\u6bd4\uff0c\u4f7f\u8bfb\u8005\u80fd\u591f\u7406\u89e3\u8fd9\u4e9b\u6a21\u578b\u5728\u7ed3\u6784\u548c\u529f\u80fd\u4e0a\u7684\u4e0d\u540c\u4e0e\u8054\u7cfb\uff0c\u4e3a\u8fdb\u4e00\u6b65\u7814\u7a76\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u8d44\u6e90\u548c\u89c6\u89d2\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/k7b55PKdLA622G6Qb5Q0hA"},"\u300a\u6d59\u5927&\u4e2d\u79d1\u9662\u8ba9Agent\u5b66\u4f1a\u81ea\u6211\u8fdb\u5316\uff0c\u73a9\u5fb7\u5dde\u6251\u514b\u5fc3\u673a\u5c3d\u663e\u300b"),"\u3002Wenqi Zhang\u7b49\u7814\u7a76\u8005\u4ecb\u7ecd\u4e86\u540d\u4e3aAgent-Pro\u7684AI\u667a\u80fd\u4f53\uff0c\u5b83\u4f7f\u7528\u5927\u6a21\u578b(GPT-4)\u4e3a\u57fa\u7840\uff0c\u914d\u5408\u81ea\u6211\u4f18\u5316\u7684\u7b56\u7565\uff0c\u80fd\u591f\u8fd0\u7528\u865a\u5f20\u58f0\u52bf\u3001\u4e3b\u52a8\u653e\u5f03\u7b49\u590d\u6742\u7b56\u7565\u73a9\u8f6c\u5fb7\u5dde\u6251\u514b\u548c21\u70b9\u7b49\u975e\u5b8c\u7f8e\u4fe1\u606f\u535a\u5f08\u6e38\u620f\u3002Agent-Pro\u7684\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u81ea\u6211\u8fdb\u5316\uff0c\u9002\u5e94\u590d\u6742\u548c\u52a8\u6001\u7684\u6e38\u620f\u73af\u5883\uff0c\u5e76\u901a\u8fc7\u7b56\u7565\u5c42\u9762\u7684\u53cd\u601d\u548c\u4e16\u754c\u6a21\u578b\u7684\u4f18\u5316\u6765\u63d0\u9ad8\u81ea\u5df1\u7684\u8868\u73b0\u3002\u8be5\u7814\u7a76\u5c55\u793a\u4e86AI\u5728\u535a\u5f08\u9886\u57df\u7684\u8fdb\u6b65\uff0c\u540c\u65f6\u4e3a\u89e3\u51b3\u591aagent\u73b0\u5b9e\u4e16\u754c\u95ee\u9898\u63d0\u4f9b\u4e86\u65b0\u7b56\u7565\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZG3CuhZisI26taz4FQrdPg"},"\u300a\u9762\u5411\u5de5\u4e1a\u7ea7\u63a8\u8350!\u201c\u5c0f\u201dLLM\u4e5f\u80fd\u505a\u597d\u63a8\u8350\u7cfb\u7edf\u300b"),"\u3002\u672c\u6587\u7531\u8682\u8681\u96c6\u56e2AI\u521b\u65b0\u7814\u53d1\u90e8\u95e8NextEvo\u64b0\u5199\uff0c\u4ecb\u7ecd\u4e86\u4ed6\u4eec\u7684\u8bba\u6587\u300aCan Small Language Models be Good Reasoners for Sequential Recommendation?\u300b\u83b7\u5f97WWW 2024 (Oral)\u5f55\u7528\u3002\u6587\u7ae0\u9488\u5bf9\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u5728\u63a8\u8350\u7cfb\u7edf\u5e94\u7528\u65f6\u4ee3\u4ef7\u9ad8\u6602\u7684\u95ee\u9898\uff0c\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3aSLIM\u7684\u57fa\u4e8e\u84b8\u998f\u7684\u5927\u6a21\u578b\u63a8\u8350\u6846\u67b6\u3002SLIM\u901a\u8fc7\u77e5\u8bc6\u84b8\u998f\u6280\u672f\uff0c\u5c06\u5927\u6a21\u578b\u7684\u77e5\u8bc6\u548c\u63a8\u7406\u80fd\u529b\u8fc1\u79fb\u5230\u8f83\u5c0f\u7684\u6a21\u578b\u4e0a\uff0c\u4ece\u800c\u8fbe\u5230\u7528\u66f4\u5c11\u53c2\u6570\u5b9e\u73b0\u9ad8\u6548\u63a8\u8350\u7684\u6548\u679c\u3002\u8bba\u6587\u5f3a\u8c03SLIM\u5728\u5904\u7406\u957f\u5c3e\u7269\u54c1\u548c\u65b0\u7528\u6237\u63a8\u8350\u7684\u4f18\u52bf\uff0c\u6539\u8fdb\u4e86\u4f20\u7edf\u57fa\u4e8e\u4ea4\u4e92\u6570\u636e\u7684\u63a8\u8350\u7cfb\u7edf\u504f\u5dee\u95ee\u9898\uff0c\u5e76\u5728\u4fdd\u6301\u63a8\u8350\u51c6\u786e\u5ea6\u548c\u53ef\u89e3\u91ca\u6027\u7684\u540c\u65f6\u964d\u4f4e\u8d44\u6e90\u6d88\u8017\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/P7gOETO-EG3Ha7WjGs6Szg"},"\u300aAIOps \u667a\u80fd\u8fd0\u7ef4:\u6709\u6ca1\u6709\u6bd4\u4e13\u5bb6\u7ecf\u9a8c\u66f4\u4f18\u96c5\u7684\u9519/\u6162\u8c03\u7528\u5206\u6790\u5de5\u5177?\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u963f\u91cc\u4e91\u5e94\u7528\u5b9e\u65f6\u76d1\u63a7\u670d\u52a1 ARMS \u6700\u65b0\u63a8\u51fa\u7684\u9519/\u6162 Trace \u5206\u6790\u529f\u80fd\u3002\u6b64\u529f\u80fd\u4e0d\u4f9d\u8d56\u4e13\u5bb6\u7ecf\u9a8c\uff0c\u80fd\u5bf9\u6bd4\u5206\u6790\u9519/\u6162 Trace \u548c\u6b63\u5e38 Trace \u7684\u6bcf\u4e2a\u7ef4\u5ea6\uff0c\u4ece\u800c\u5feb\u901f\u5b9a\u4f4d\u95ee\u9898\u6839\u6e90\u3002\u9488\u5bf9\u751f\u4ea7\u73af\u5883\u4e0b\u8c03\u7528\u65f6\u5ef6\u548c\u9519\u8bef\u8c03\u7528\u7684\u591a\u79cd\u56e0\u7d20\uff08\u5982\u6d41\u91cf\u4e0d\u5747\u3001\u5355\u673a\u6545\u969c\u7b49\uff09\uff0cARMS \u901a\u8fc7\u5bf9\u9519/\u6162 Trace \u548c\u6b63\u5e38 Trace \u7684\u5bf9\u6bd4\uff0c\u5e2e\u52a9\u7528\u6237\u53d1\u73b0\u5f02\u5e38\u7684\u5171\u540c\u7279\u5f81\uff0c\u4ece\u800c\u5b9a\u4f4d\u5230\u5177\u4f53\u95ee\u9898\u3002\u8fd9\u4e2a\u5de5\u5177\u63d0\u4f9b\u4e86\u4e00\u79cd\u4f18\u4e8e\u4f20\u7edf\u4e13\u5bb6\u7ecf\u9a8c\u7684\u5feb\u901f\u3001\u6709\u6548\u8bca\u65ad\u7cfb\u7edf\u95ee\u9898\u7684\u65b9\u6cd5\uff0c\u5e76\u4e14\u9644\u6709\u6700\u4f73\u5b9e\u8df5\u6848\u4f8b\u3002\u6587\u7ae0\u6700\u540e\u63d0\u4f9b\u4e86\u514d\u767b\u5f55\u7684 demo \u4f53\u9a8c\u94fe\u63a5\uff0c\u5f15\u5bfc\u7528\u6237\u4e86\u89e3\u548c\u4f7f\u7528\u8be5\u529f\u80fd\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/9RaOOrroywQKnOhanBApsA"},"\u300aCUDA\u7f16\u7a0b\u4f18\u5316\u65b9\u6cd5\u2014\u2014Memory coalescing\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9CUDA\u7f16\u7a0b\u4e2d\u7684\u5185\u5b58\u5408\u5e76\u6280\u672f\u2014\u2014 Memory coalescing\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\u3002\u6587\u7ae0\u9996\u5148\u89e3\u91ca\u4e86\u5168\u5c40\u5185\u5b58\u7684\u7279\u70b9\u4ee5\u53ca\u4e3a\u4f55\u8bbf\u95ee\u901f\u5ea6\u6162\uff0c\u5e76\u9610\u8ff0\u4e86Memory coalescing\u7684\u76ee\u7684\u662f\u901a\u8fc7\u5408\u5e76\u5185\u5b58\u8bbf\u95ee\u64cd\u4f5c\u6765\u6709\u6548\u5730\u5229\u7528\u5e26\u5bbd\u3002\u901a\u8fc7\u5bf9\u591a\u7ef4\u6570\u7ec4\u7684\u5b58\u50a8\u65b9\u5f0f\u53ca\u8bbf\u95ee\u6a21\u5f0f\u7684\u89e3\u6790\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u8bb2\u89e3\u4e86Memory coalescing\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\uff0c\u5982\u4f55\u5728\u591a\u7ef4\u6570\u7ec4\u8bbf\u95ee\u548c\u77e9\u9635\u4e58\u6cd5\u4e2d\u5b9e\u73b0\u5185\u5b58\u8bbf\u95ee\u7684\u5408\u5e76\u3002\u6700\u540e\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4f18\u5316\u7b56\u7565\uff0c\u4ee5\u6539\u8fdb\u8ba1\u7b97\u7684\u5185\u5b58\u8bbf\u95ee\u6a21\u5f0f\uff0c\u5e76\u63d0\u9ad8CUDA\u5185\u5b58\u4f20\u8f93\u7684\u6548\u7387\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/b6D-vipDxKtlyocbxTObVQ"},"\u300a\u6269\u6563\u6a21\u578b\u5982\u4f55\u6784\u5efa\u65b0\u4e00\u4ee3\u51b3\u7b56\u667a\u80fd\u4f53?\u8d85\u8d8a\u81ea\u56de\u5f52\uff0c\u540c\u65f6\u751f\u6210\u957f\u5e8f\u5217\u89c4\u5212\u8f68\u8ff9\u300b"),"\u3002\u672c\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u6269\u6563\u6a21\u578b\u5728\u5f3a\u5316\u5b66\u4e60\u4e2d\u7684\u591a\u79cd\u5e94\u7528\u573a\u666f\uff0c\u63a2\u8ba8\u4e86\u5982\u4f55\u8d85\u8d8a\u4f20\u7edf\u7684\u81ea\u56de\u5f52\u65b9\u6cd5\uff0c\u540c\u65f6\u751f\u6210\u957f\u5e8f\u5217\u89c4\u5212\u8f68\u8ff9\u6765\u6a21\u4eff\u4eba\u7c7b\u7684\u51b3\u7b56\u8fc7\u7a0b\u3002\u4e0a\u6d77\u4ea4\u901a\u5927\u5b66\u7684\u56e2\u961f\u6240\u4f5c\u7684\u7efc\u8ff0\u68b3\u7406\u4e86\u6269\u6563\u6a21\u578b\u5728\u5f3a\u5316\u5b66\u4e60\u4e2d\u7684\u8fd0\u7528\u5982\u8f68\u8ff9\u89c4\u5212\u3001\u7b56\u7565\u8868\u5f81\u3001\u6570\u636e\u5408\u6210\uff0c\u53ca\u5176\u89e3\u51b3\u957f\u5e8f\u5217\u89c4\u5212\u8bef\u5dee\u7d2f\u79ef\u3001\u7b56\u7565\u8868\u8fbe\u80fd\u529b\u53d7\u9650\u548c\u6570\u636e\u7a00\u7f3a\u7b49\u95ee\u9898\u7684\u5de8\u5927\u6f5c\u529b\u3002\u6700\u7ec8\uff0c\u6587\u7ae0\u5bf9\u6269\u6563\u6a21\u578b\u672a\u6765\u7684\u53d1\u5c55\u65b9\u5411\u8fdb\u884c\u4e86\u5c55\u671b\uff0c\u63d0\u51fa\u4e86\u751f\u6210\u5f0f\u4eff\u771f\u73af\u5883\u3001\u52a0\u5165\u5b89\u5168\u7ea6\u675f\u3001\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u53ca\u7ec4\u5408\u591a\u79cd\u6280\u80fd\u7b49\u591a\u4e2a\u7814\u7a76\u65b9\u5411\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GII5CwvB4FuxkT7yzyf_4Q"},"\u300a\u52a8\u624b\u505a\u4e00\u4e2a\u6700\u5c0fRAG\u2014\u2014TinyRAG\u300b"),"\u3002\u672c\u6587\u7531\u4e0d\u8981\u8471\u59dc\u849c\u6307\u5bfc\u8bfb\u8005\u5982\u4f55\u4e00\u6b65\u6b65\u5b9e\u73b0\u57fa\u4e8e\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u6280\u672f\uff08RAG\uff09\u7684\u7b80\u5316\u6a21\u578b\u2014\u2014TinyRAG\u3002TinyRAG\u4ec5\u5305\u542bRAG\u6838\u5fc3\u529f\u80fd\uff0c\u5373Retrieval\uff08\u68c0\u7d22\uff09\u548cGeneration\uff08\u751f\u6210\uff09\u4e24\u4e2a\u6a21\u5757\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86RAG\u7684\u57fa\u672c\u7ed3\u6784\uff0c\u5305\u62ec\u5411\u91cf\u5316\u6a21\u5757\u3001\u6587\u6863\u52a0\u8f7d\u4e0e\u5207\u5206\u6a21\u5757\u3001\u6570\u636e\u5e93\u548c\u68c0\u7d22\u6a21\u5757\uff0c\u4ee5\u53ca\u5982\u4f55\u6839\u636e\u68c0\u7d22\u5185\u5bb9\u751f\u6210\u56de\u7b54\u3002\u6b64\u5916\uff0c\u8fd8\u63d0\u4f9b\u4e86\u5bf9\u5e94\u7684\u5f00\u6e90\u9879\u76ee",(0,r.kt)("a",{parentName:"p",href:"https://github.com/KMnO4-zx/TinyRAG"},"\u4ee3\u7801"),"\uff0c\u52a9\u529b\u7406\u89e3\u8bed\u8a00\u6a21\u578b\u4e0eRAG\u7684\u539f\u7406\uff0c\u5e76\u80fd\u591f\u5728\u5b9e\u8df5\u4e2d\u52a0\u4ee5\u5e94\u7528\u548c\u62d3\u5c55\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/1jTw_5_re4GWWLqgKnkSww"},"\u300a\u804a\u4e00\u804aTransformer\u4e2d\u7684FFN\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u4e3a\u4ec0\u4e48Transformer\u7684\u524d\u9988\u795e\u7ecf\u7f51\u7edc\uff08FFN\uff09\u90e8\u5206\u957f\u671f\u4ee5\u6765\u51e0\u4e4e\u6ca1\u6709\u5927\u7684\u6539\u52a8\u3002\u6587\u7ae0\u901a\u8fc7\u6bd4\u8f83\u4e0d\u540c\u7684\u6fc0\u6d3b\u51fd\u6570\uff0c\u5982ReLU\u3001GeLU\u548cSwish\u7b49\uff0c\u5206\u6790\u5b83\u4eec\u5728Transformer\u4e2d\u7684\u5e94\u7528\u6548\u679c\u548c\u5c40\u9650\u6027\u3002\u540c\u65f6\u63a2\u8ba8\u4e86\u7ebf\u6027\u6295\u5f71\u7684\u5fc5\u8981\u6027\u3001\u53c2\u6570\u91cf\u53ca\u5176\u5bf9\u6a21\u578b\u5bb9\u91cf\u548c\u8bb0\u5fc6\u529b\u7684\u5f71\u54cd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u6d89\u53ca\u4e86\u6df7\u5408\u4e13\u5bb6\u6a21\u578b\uff08Mixture-of-Experts\uff0cMoE\uff09\u4ee5\u63d0\u5347Transformer\u7684\u6548\u7387\uff0c\u5e76\u8ba8\u8bba\u4e86\u6784\u5efa\u901a\u7528\u4eba\u5de5\u667a\u80fd\uff08AGI\uff09\u6240\u9700\u8981\u7684\u7ed3\u6784\u7279\u6027\uff0c\u7279\u522b\u662f\u653e\u7f29\u5b9a\u5f8b\uff08Scaling Law\uff09\u3001\u4e0a\u4e0b\u6587\u5b66\u4e60\uff08In-Context Learning\uff09\u3001\u6548\u7387\u63d0\u5347\uff08Better Efficiency\uff09\u548c\u7ec8\u751f\u5b66\u4e60\uff08Life-long learning\uff09\u7684\u91cd\u8981\u6027\uff0c\u6700\u540e\u5bf9\u672a\u6765\u7ed3\u6784\u521b\u65b0\u7ed9\u51fa\u900f\u5f7b\u89c1\u89e3\u3002"),(0,r.kt)("h2",{id:"\ufe0f-go--\u4e91\u539f\u751f--rust-\u76f8\u5173"},"\u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://go.dev/blog/execution-traces-2024"},"\u300aMore powerful Go execution traces\u300b"),"\u3002Go\u7684runtime/trace\u5305\u63d0\u4f9b\u4e86\u7528\u4e8e\u7406\u89e3\u548c\u6392\u67e5Go\u7a0b\u5e8f\u7684\u5f3a\u5927\u5de5\u5177\uff0c\u5141\u8bb8\u5bf9goroutine\u7684\u6267\u884c\u8fdb\u884c\u8ddf\u8e2a\u3002\u65b0\u7248\u672cGo\u5927\u5e45\u5ea6\u964d\u4f4e\u4e86\u6267\u884c\u8ddf\u8e2a\u7684\u8fd0\u884c\u65f6\u5f00\u9500\uff0c\u4ece\u591a\u6570\u5e94\u7528\u4e2d\u768410-20% CPU\u4e0b\u964d\u52301-2%\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u5c06trace\u5206\u5272\uff0c\u4ece\u800c\u4f7f\u5f97trace\u53ef\u4ee5\u6269\u5c55\u4e14\u4fdd\u6301\u4f4e\u5f00\u9500\uff0c\u8fd8\u5b9e\u73b0\u4e86\u98de\u884c\u8bb0\u5f55\u529f\u80fd\uff0c\u4f7f\u5f97\u5373\u4f7f\u5728\u4e8b\u4ef6\u53d1\u751f\u540e\u4e5f\u80fd\u4ecetrace\u4e2d\u83b7\u53d6\u4fe1\u606f\u3002Go\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5b9e\u9a8c\u6027\u7684trace\u8bfb\u53d6API\uff0c\u4f7f\u7a0b\u5e8f\u6027\u7684\u8ddf\u8e2a\u5206\u6790\u6210\u4e3a\u53ef\u80fd\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7346394191264710666"},"\u300aRust: \u5b9e\u73b0\u6bd4\u7279\u5e01\u7684\u4ea4\u6613\u6a21\u578b\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u6bd4\u7279\u5e01\u7684\u4ea4\u6613\u6a21\u578b\u4e2d\u7684UTXO\uff08\u672a\u82b1\u8d39\u4ea4\u6613\u8f93\u51fa\uff09\u6a21\u578b\uff0c\u5e76\u4f7f\u7528 Rust \u8bed\u8a00\u6765\u5b9e\u73b0\u548c\u5c55\u793a\u5176\u8fd0\u4f5c\u8fc7\u7a0b\u3002UTXO \u6a21\u578b\u4e0e\u4f20\u7edf\u7684\u8d26\u6237\u4f59\u989d\u6a21\u578b\u4e0d\u540c\uff0c\u5c06\u7528\u6237\u7684\u4f59\u989d\u5206\u6563\u5b58\u50a8\u5728\u591a\u4e2aUTXO\u4e2d\u3002\u6bcf\u4e2aUTXO\u4ee3\u8868\u6bd4\u7279\u5e01\u7f51\u7edc\u4e0a\u4e00\u7b14\u53ef\u7528\u4e8e\u672a\u6765\u4ea4\u6613\u7684\u8f93\u51fa\u3002\u6587\u7ae0\u89e3\u91ca\u4e86UTXO\u6a21\u578b\u7684\u5de5\u4f5c\u539f\u7406\u3001\u4f18\u52bf\u4ee5\u53ca\u4ea4\u6613\u5904\u7406\u6d41\u7a0b\uff0c\u5305\u62ec\u9009\u62e9\u8f93\u5165\u3001\u751f\u6210\u8f93\u51fa\u3001\u7b7e\u540d\u4ea4\u6613\u548c\u5e7f\u64ad\u4ea4\u6613\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u4e2a Rust \u5b9e\u73b0\u7684\u7b80\u5316\u793a\u4f8b\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u5b9a\u4e49\u4ea4\u6613\u7ed3\u6784\u4f53\u3001\u8f93\u5165\u3001\u8f93\u51fa\u4ee5\u53caUTXO\u96c6\u5408\uff0c\u5e76\u4ecb\u7ecd\u4e86\u57fa\u672c\u7684\u64cd\u4f5c\u65b9\u6cd5\u3002\u5982\u679c\u4f60\u5bf9\u6bd4\u7279\u5e01\u4ea4\u6613\u6a21\u578b\u548c Rust \u7f16\u7a0b\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u9605\u8bfb\u8be5\u6587\u7ae0\u4e86\u89e3\u66f4\u591a\u7ec6\u8282\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7309692103055507491"},"\u300a\u6df1\u5165\u7406\u89e3 Go Modules: \u9ad8\u6548\u7ba1\u7406\u4f60\u7684 Golang \u9879\u76ee\u4f9d\u8d56\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86 Go Modules \u5728 Golang \u9879\u76ee\u4e2d\u7684\u4f7f\u7528\u65b9\u6cd5\u548c\u539f\u7406\u3002\u6587\u7ae0\u9996\u5148\u56de\u987e\u4e86 Go \u4f9d\u8d56\u7ba1\u7406\u7684\u5386\u53f2\uff0c\u4ece GOPATH\u3001Go Vendor \u5230 Go Module \u7684\u6f14\u8fdb\u8fc7\u7a0b\u3002\u7136\u540e\u8bb2\u89e3\u4e86\u6a21\u5757\u3001\u5305\u548c\u7248\u672c\u7684\u6982\u5ff5\uff0c\u5305\u62ec\u6a21\u5757\u8def\u5f84\u3001\u5305\u8def\u5f84\u4ee5\u53ca\u7248\u672c\u7684\u683c\u5f0f\u548c\u8bed\u4e49\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86 Go Modules \u7684\u73af\u5883\u914d\u7f6e\uff0c\u5305\u62ec go env \u73af\u5883\u53d8\u91cf\u548c\u4f9d\u8d56\u7ba1\u7406\u6587\u4ef6\uff08go.mod \u548c go.sum\uff09\u7684\u4f5c\u7528\u548c\u4f7f\u7528\u65b9\u6cd5\u3002\u6700\u540e\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u7528\u6280\u5de7\u548c\u5e38\u89c1\u95ee\u9898\u7684\u89e3\u7b54\uff0c\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u5e94\u7528 Go Modules\u3002\u5982\u679c\u4f60\u5bf9 Golang \u9879\u76ee\u7684\u4f9d\u8d56\u7ba1\u7406\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u9605\u8bfb\u8be5\u6587\u7ae0\u4e86\u89e3\u66f4\u591a\u8be6\u60c5\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GxTtiqMpcrDWK9toaK5CMw"},"\u300aKubernetes\u96c6\u7fa4\u8282\u70b9\u5904\u4e8eNot Ready\u95ee\u9898\u6392\u67e5\u300b"),'\u3002\u5f53Kubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u663e\u793a\u4e3a"Not Ready"\u72b6\u6001\u65f6\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u7cfb\u5217\u7684\u6392\u67e5\u6b65\u9aa4\u3002\u9996\u5148\uff0c\u901a\u8fc7\u8fd0\u884c\u7279\u5b9a\u7684kubectl\u547d\u4ee4\u6765\u786e\u8ba4\u8282\u70b9\u7684\u72b6\u6001\u5e76\u83b7\u53d6\u8282\u70b9\u8be6\u7ec6\u4fe1\u606f\uff0c\u68c0\u67e5\u53ef\u80fd\u7684\u9519\u8bef\u6d88\u606f\u6216\u8005\u8b66\u544a\u3002\u63a5\u7740\uff0c\u8fdb\u5165\u8282\u70b9\u7cfb\u7edf\u67e5\u770b\u5404\u79cd\u7cfb\u7edf\u65e5\u5fd7\uff0c\u5e76\u4f7f\u7528\u76f8\u5173\u547d\u4ee4\u5982grep\u3001cat\u6216tail\u6765\u8f85\u52a9\u5206\u6790\u3002\u6587\u7ae0\u8fd8\u5efa\u8bae\u68c0\u67e5kubelet\u670d\u52a1\u72b6\u6001\u548c\u914d\u7f6e\u6587\u4ef6\uff0c\u786e\u8ba4\u7cfb\u7edf\u8d44\u6e90\u662f\u5426\u5145\u8db3\uff0c\u8bd5\u56fe\u89e3\u51b3\u53ef\u80fd\u5b58\u5728\u7684\u78c1\u76d8\u7a7a\u95f4\u548c\u7f51\u7edc\u95ee\u9898\u3002\u6700\u540e\uff0c\u901a\u8fc7\u4f7f\u7528\u8bf8\u5982ping\u3001traceroute\u7b49\u8bca\u65ad\u5de5\u5177\u786e\u4fdd\u8282\u70b9\u80fd\u591f\u4e0e\u4e3b\u8282\u70b9\u901a\u4fe1\uff0c\u5e76\u68c0\u67e5\u91cd\u8981\u7684\u7f51\u7edc\u7aef\u53e3\u662f\u5426\u5f00\u653e\u3002\u786e\u4fddKubelet\u80fd\u6b63\u786e\u8fde\u63a5\u5230Kubernetes API\uff0c\u5e76\u4f7f\u7528Kubernetes\u7684\u8bca\u65ad\u5de5\u5177\u5982kubectl get componentstatus\u68c0\u67e5\u7ec4\u4ef6\u72b6\u6001\u3002\u901a\u8fc7\u8fd9\u4e9b\u6b65\u9aa4\uff0c\u53ef\u4ee5\u7cfb\u7edf\u5730\u6392\u67e5\u5e76\u89e3\u51b3"Not Ready"\u7684\u95ee\u9898\uff0c\u4fdd\u6301\u96c6\u7fa4\u5065\u5eb7\u3002'),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iuzDw7_w20jtjJUlynv9NA"},"\u300aGo \u9519\u8bef\u5904\u7406: \u7528 select-case \u6765\u89e3\u51b3\u8fd9\u4e2a\u5386\u53f2\u96be\u9898?\u300b"),"\u3002\u714e\u9c7c\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u4e86\u4e00\u4e2a\u65b0\u7684Go\u8bed\u8a00\u9519\u8bef\u5904\u7406\u63d0\u6848\uff0c\u8fd9\u4e2a\u63d0\u6848\u5c1d\u8bd5\u7528",(0,r.kt)("inlineCode",{parentName:"p"},"select-case"),"\u7ed3\u6784\u4f5c\u4e3a\u9519\u8bef\u68c0\u67e5\u7684\u66ff\u4ee3\u3002\u8fd9\u4e2a\u65b0\u8bed\u6cd5\u5141\u8bb8\u5728",(0,r.kt)("inlineCode",{parentName:"p"},"select"),"\u5173\u952e\u5b57\u4e4b\u540e\u58f0\u660e\u4e00\u4e2a\u53d8\u91cf\u4e3a\u201c\u9677\u9631\u201d\uff0c\u8d4b\u503c\u7ed9\u8be5\u53d8\u91cf\u65f6\u89e6\u53d1",(0,r.kt)("inlineCode",{parentName:"p"},"case"),"\u68c0\u67e5\uff0c\u4ee5\u51cf\u5c11\u4f20\u7edf\u7684",(0,r.kt)("inlineCode",{parentName:"p"},"if err != nil"),"\u68c0\u67e5\u7684\u7e41\u7410\u6027\u3002\u65b0\u63d0\u6848\u4fdd\u6301\u4e86Go1\u4ee3\u7801\u7684\u517c\u5bb9\u6027\uff0c\u5c1d\u8bd5\u63d0\u4f9b\u4e00\u4e2a\u66f4\u7b80\u6d01\u3001\u5411\u540e\u517c\u5bb9\u7684\u9519\u8bef\u5904\u7406\u65b9\u5f0f\uff0c\u5c3d\u7ba1\u76ee\u524d\u793e\u533a\u5185\u5bf9\u6b64\u4ecd\u672a\u8fbe\u6210\u5171\u8bc6\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/Dc5wOBAE_jSiTKqPc6M4Dg"},"\u300aK8s\u84dd\u7eff\u90e8\u7f72:\u4f18\u96c5\u5e94\u5bf9\u5e94\u7528\u7a0b\u5e8f\u66f4\u65b0\u6311\u6218\u300b"),"\u3002\u672c\u6587\u8be6\u7ec6\u63a2\u8ba8\u4e86\u4f7f\u7528Kubernetes\uff08K8s\uff09\u8fdb\u884c\u84dd\u7eff\u90e8\u7f72\u7684\u65b9\u6cd5\uff0c\u4ee5\u8fbe\u5230\u65e0\u7f1d\u66f4\u65b0\u5e94\u7528\u7a0b\u5e8f\u5e76\u6700\u5c0f\u5316\u5b95\u673a\u65f6\u95f4\u3002\u84dd\u7eff\u90e8\u7f72\u662f\u4e00\u4e2a\u8fd0\u884c\u4e24\u4e2a\u76f8\u540c\u751f\u4ea7\u73af\u5883\u7684\u6a21\u5f0f\uff0c\u80fd\u591f\u5728\u66f4\u65b0\u65f6\u5207\u6362\u6d41\u91cf\uff0c\u786e\u8ba4\u65e0\u8bef\u540e\u4fbf\u53bb\u9664\u65e7\u73af\u5883\u3002\u6587\u7ae0\u6307\u5bfc\u4e86\u4ece\u521b\u5efa\u547d\u540d\u7a7a\u95f4\u3001\u521b\u5efa\u548c\u5e94\u7528\u90e8\u7f72\u3001\u670d\u52a1\u53ca\u5176\u8def\u7531\u89c4\u5219\u3001\u6267\u884c\u84dd\u7eff\u5207\u6362\uff0c\u5230\u6700\u540e\u7684\u9a8c\u8bc1\u548c\u56de\u6eda\u8fc7\u7a0b\u3002\u8fd9\u4e00\u8fc7\u7a0b\u4e0d\u4ec5\u4f18\u5316\u4e86\u5e94\u7528\u7248\u672c\u7684\u6eda\u52a8\u66f4\u65b0\uff0c\u4e5f\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u5feb\u901f\u56de\u6eda\u7684\u65b9\u6848\uff0c\u4ee5\u5e94\u5bf9\u53ef\u80fd\u51fa\u73b0\u7684\u95ee\u9898\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/RzglzZ0xY9NmsgujdHa-Tw"},"\u300aGo \u4e2d\u7684\u9ad8\u901f\u6570\u636e\u5305\u5904\u7406:\u4ece net.Dial \u5230 AF_XDP\u300b"),"\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4f7f\u7528 Go \u8bed\u8a00\u8fdb\u884c\u9ad8\u901f\u6570\u636e\u5305\u5904\u7406\u7684\u591a\u79cd\u65b9\u6cd5\uff0c\u5305\u62ec net.Dial\u3001\u539f\u59cb\u5957\u63a5\u5b57\u3001\u7cfb\u7edf\u8c03\u7528\u3001pcap \u548c AF_PACKET\uff0c\u76f4\u81f3\u6700\u65b0\u7684 AF_XDP \u65b9\u5f0f\u3002\u4f5c\u8005\u8be6\u7ec6\u5bf9\u6bd4\u4e86\u6bcf\u79cd\u65b9\u6cd5\u7684\u6027\u80fd\uff0c\u4ece\u7b80\u5355\u7684 net.Dial \u6a21\u5f0f\u6f14\u8fdb\u5230 AF_XDP\uff0c\u9010\u6b65\u63d0\u9ad8\u6570\u636e\u5305\u6bcf\u79d2\u5904\u7406\u6570\u91cf\uff0c\u540c\u65f6\u6307\u51fa\u5404\u65b9\u6cd5\u7684\u4f7f\u7528\u573a\u5408\u548c\u9650\u5236\u3002\u901a\u8fc7\u57fa\u51c6\u6d4b\u8bd5\uff0c\u53d1\u73b0\u4f7f\u7528 AF_XDP \u53ef\u5b9e\u73b0\u6700\u9ad8\u6027\u80fd\uff0c\u5904\u7406\u901f\u5ea6\u662f\u4f7f\u7528 net.Dial \u65b9\u6cd5\u76844\u500d\u591a\u3002\u8fd9\u4e9b\u6280\u672f\u63a2\u8ba8\u5bf9\u4e8e\u9700\u8981\u5927\u91cf\u7f51\u7edc\u6570\u636e\u5305\u5904\u7406\u7684\u573a\u666f\uff0c\u5982\u7f51\u7edc\u76d1\u63a7\u3001\u6027\u80fd\u8bc4\u4f30\u7b49\u90fd\u662f\u975e\u5e38\u91cd\u8981\u7684\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/dCQPOx2n2w36Q3P3hCKe8A"},"\u300a\u6570\u636e\u5e93\u4e0d\u5e94\u653e\u5728\u5bb9\u5668\u4e2d?- B\u7ad9Kubernetes\u6709\u72b6\u6001\u670d\u52a1\u5b9e\u8df5(Elasticsearch/Clickhouse)\u300b"),"\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5728\u4e91\u539f\u751f\u65f6\u4ee3\u4e0b\uff0c\u6709\u72b6\u6001\u670d\u52a1\uff08\u5982\u751f\u4ea7\u73af\u5883\u7684\u6570\u636e\u5e93\uff09\u662f\u5426\u9002\u7528\u4e8e\u5bb9\u5668\u5316\u5e76\u7531Kubernetes\u8fdb\u884c\u7ba1\u7406\u7684\u95ee\u9898\u3002\u4ee5B\u7ad9Elasticsearch\u548cClickhouse\u7684\u5bb9\u5668\u5316\u548cKubernetes\u7f16\u6392\u5b9e\u8df5\u4e3a\u4f8b\uff0c\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5728\u5bb9\u5668\u73af\u5883\u4e2d\u90e8\u7f72\u8fd9\u4e9b\u6709\u72b6\u6001\u670d\u52a1\u7684\u6311\u6218\u548c\u89e3\u51b3\u65b9\u6848\uff0c\u5305\u62ec\u63a7\u5236\u5668\u7684\u9009\u62e9\u3001\u6301\u4e45\u5316\u5b58\u50a8\u3001\u78c1\u76d8\u8c03\u5ea6\u3001\u8c03\u5ea6\u5668\u3001\u5bb9\u5668\u7f51\u7edc\u3001\u670d\u52a1\u53d1\u73b0\u4ee5\u53ca\u5982\u4f55\u4fdd\u8bc1\u96c6\u7fa4\u548c\u6570\u636e\u7684\u9ad8\u53ef\u7528\u6027\u3002\u4f5c\u8005\u5206\u4eab\u4e86\u901a\u8fc7Operator\u7ba1\u7406\u6709\u72b6\u6001\u670d\u52a1\u5e94\u7528\u3001\u4f7f\u7528\u672c\u5730\u76d8PV\u63d0\u5347\u6027\u80fd\u3001LVM\u6280\u672f\u7684\u52a8\u6001\u6269\u7f29\u5bb9\u65b9\u6848\u4ee5\u53ca\u901a\u8fc7macvlan\u8fdb\u884c\u5bb9\u5668\u95f4\u9ad8\u6548\u901a\u4fe1\u7684\u6280\u672f\u7ec6\u8282\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/-TXbvQiR-tpB0RgQ5d-QDw"},"\u300a\u4e00\u6587\u5e26\u60a8\u63a2\u7d22 Kubernetes \u4e2d\u7684\u5bb9\u5668\u7c7b\u578b\u300b"),"\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5728 Kubernetes \u7cfb\u7edf\u4e2d\u5e38\u89c1\u7684\u56db\u79cd\u5bb9\u5668\u7c7b\u578b\uff1a\u521d\u59cb\u5316\u5bb9\u5668(Init Container)\u3001\u8fb9\u8f66\u5bb9\u5668(Sidecar Container)\u3001\u4e34\u65f6\u5bb9\u5668(Ephemeral Container)\u548c\u591a\u5bb9\u5668(Multi Container)\u3002\u521d\u59cb\u5316\u5bb9\u5668\u7528\u4e8e\u8fd0\u884c Pod \u4e2d\u4e3b\u5bb9\u5668\u542f\u52a8\u524d\u7684\u51c6\u5907\u5de5\u4f5c\uff0c\u800c\u8fb9\u8f66\u5bb9\u5668\u5219\u4e0e\u4e3b\u5e94\u7528\u5bb9\u5668\u5e76\u884c\u8fd0\u884c\uff0c\u4e3a\u5176\u63d0\u4f9b\u652f\u6301\u670d\u52a1\u3002\u4e34\u65f6\u5bb9\u5668\u4e3b\u8981\u7528\u4e8e\u6545\u969c\u6392\u9664\uff0c\u800c\u591a\u5bb9\u5668 Pods \u5141\u8bb8\u5e76\u884c\u8fd0\u884c\u591a\u4e2a\u5bb9\u5668\uff0c\u5171\u4eab\u8d44\u6e90\u548c\u6570\u636e\u3002\u6587\u7ae0\u63d0\u4f9b\u4e86\u6bcf\u79cd\u5bb9\u5668\u7684\u8be6\u7ec6\u4f7f\u7528\u6848\u4f8b\u3001\u914d\u7f6e\u65b9\u6cd5\u548c\u547d\u4ee4\uff0c\u5e76\u5f3a\u8c03\u4e86\u5404\u81ea\u7684\u7279\u70b9\u4e0e\u5e94\u7528\u573a\u666f\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/iylZAKZfxLL6SYruww_8zA"},"\u300a4 \u79d2\u5904\u7406 10 \u4ebf\u884c\u6570\u636e! Go \u8bed\u8a00\u7684 9 \u5927\u4ee3\u7801\u65b9\u6848\uff0c\u4e00\u4e2a\u6bd4\u4e00\u4e2a\u5feb\u300b"),"\u3002\u8f6f\u4ef6\u5de5\u7a0b\u5e08Ben Hoyt\u6311\u6218\u4f7f\u7528Go\u8bed\u8a00\u5904\u740610\u4ebf\u884c\u6570\u636e\uff0c\u5e76\u63d0\u51fa\u4e869\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u5176\u4e2d\u6700\u5feb\u57284\u79d2\u5185\u5b8c\u6210\u3002\u8fd9\u4e9b\u65b9\u6848\u53ea\u4f7f\u7528Go\u6807\u51c6\u5e93\uff0c\u5305\u62ec\u7b80\u5355\u4f46\u4f18\u5316\u7684map\u5904\u7406\u3001\u5e76\u884c\u5316\u5904\u7406\u7b49\u3002Ben\u7684\u65b9\u6848\u867d\u672a\u6700\u5feb\uff0c\u4f46\u5c55\u73b0\u4e86\u72ec\u7acb\u601d\u8003\u7684\u4ef7\u503c\u3002\u4ed6\u7684\u6d4b\u8bd5\u8868\u660e\uff0c\u5f7b\u5e95\u5730\u6570\u636e\u5904\u7406\u548c\u7b97\u6cd5\u4f18\u5316\u53ef\u663e\u8457\u63d0\u9ad8\u6027\u80fd\uff0c\u51cf\u5c11\u8ba1\u7b97\u6210\u672c\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/aS-azhReZL5epoG_3n0hyg"},"\u300aGo arena \u6c11\u95f4\u5e93\u6765\u4e86\uff0c\u53ef\u4ee5\u624b\u52a8\u7ba1\u7406\u5185\u5b58!\u300b"),"\u3002\u6587\u4e2d\u4f5c\u8005\u714e\u9c7c\u4ecb\u7ecd\u4e86Go\u8bed\u8a00\u7684\u4e00\u4e2a\u65b0\u7684\u7b2c\u4e09\u65b9\u5e93ortuman/nuke\uff0c\u8fd9\u4e2a\u5e93\u5141\u8bb8\u5f00\u53d1\u8005\u624b\u52a8\u7ba1\u7406\u5185\u5b58\u3002\u6587\u7ae0\u9996\u5148\u56de\u987e\u4e86Go\u5b98\u65b9\u5bf9\u4e8earena\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u63d0\u6848\u7684\u505c\u6ede\u73b0\u72b6\uff0c\u7136\u540e\u91cd\u70b9\u4ecb\u7ecd\u4e86\u5982\u4f55\u4f7f\u7528ortuman/nuke\u5e93\u8fdb\u884c\u5185\u5b58\u7ba1\u7406\uff0c\u5305\u62ec\u5e93\u7684\u5b89\u88c5\u3001\u4f7f\u7528\u6848\u4f8b\u4ee5\u53ca\u5982\u4f55\u5728\u5e76\u53d1\u573a\u666f\u4e0b\u4fdd\u6301\u7ebf\u7a0b\u5b89\u5168\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u89e3\u4e86arena\u5185\u5b58\u7ba1\u7406\u7684\u4f18\u70b9\uff0c\u4f8b\u5982\u9ad8\u6548\u7387\u548c\u4e00\u6b21\u6027\u91ca\u653e\uff0c\u5e76\u5bf9\u5e93\u7684\u5b9e\u9645\u7528\u6cd5\uff0c\u5982\u901a\u8fc7context\u5728HTTP\u8bf7\u6c42\u5468\u671f\u4e2d\u7ba1\u7406\u5185\u5b58\uff0c\u8fdb\u884c\u4e86\u5c55\u793a\u3002\u6700\u540e\uff0c\u57fa\u4e8e\u6027\u80fd\u8003\u8651\uff0c\u6587\u7ae0\u8fd8\u63d0\u4f9b\u4e86\u5e76\u53d1\u4e0e\u975e\u5e76\u53d1\u4e1a\u52a1\u573a\u666f\u4e0b\u7684\u57fa\u51c6\u6d4b\u8bd5\u7ed3\u679c\u4ee5\u53ca\u6027\u80fd\u5dee\u5f02\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/xRxRe6DkWJVcGKXOt1oGlQ"},"Go \u8bed\u8a00\u4e2d\u5982\u4f55\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\uff1fint \u8f6c byte \u662f\u5982\u4f55\u8fdb\u884c\u7684")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/USKjmlyTtexSQtToOg481g"},"Go \u4e2d\u5982\u4f55\u5b9e\u73b0\u4e09\u5143\u8fd0\u7b97\u7b26\uff1fRust \u548c Python \u662f\u600e\u4e48\u505a\u7684")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/mFZewdDxlK4O_wUWR6mVjg"},"Go\u8bed\u8a00\u4e2d enum \u5b9e\u73b0\u65b9\u5f0f\u6709\u54ea\u4e9b\uff1f\u4e00\u5b9a\u8981\u7edd\u5bf9\u7c7b\u578b\u5b89\u5168\u5417")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/obOG_Kior34ktLek3_-GZg"},"Go \u4e2d\u5982\u4f55\u6253\u5370\u7ed3\u6784\u4f53\uff1f \u4ee3\u7801\u8c03\u8bd5\u6548\u7387\u63d0\u5347")),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/9ARiVYpYRy4FCuSJ5IKuGw"},"\u300a\u5feb\u770b! Go 1.22 \u5bf9for\u5faa\u73af\u8fdb\u884c\u4e86\u4e24\u4e2a\u5927\u66f4\u65b0\u300b"),"\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728 1.22 \u7248\u672c\u4e2d\u9488\u5bf9for\u5faa\u73af\u4f5c\u51fa\u7684\u4e24\u9879\u4e3b\u8981\u66f4\u65b0\uff1a1. \u6bcf\u6b21\u8fed\u4ee3\u7684for\u5faa\u73af\u90fd\u5c06\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u53d8\u91cf\uff0c\u4e0d\u518d\u5171\u7528\u540c\u4e00\u4e2a\u53d8\u91cf\uff1b2. \u5f15\u5165\u4e86\u5bf9\u6574\u6570\u8303\u56f4\u7684\u5faa\u73af\u8fed\u4ee3\u652f\u6301\u3002\u8fd9\u4e9b\u66f4\u65b0\u89e3\u51b3\u4e86\u95ed\u5305\u5728\u5e76\u53d1\u6267\u884c\u65f6\u5171\u4eab\u53d8\u91cf\u5e26\u6765\u7684\u95ee\u9898\uff0c\u540c\u65f6\u4e5f\u7b80\u5316\u4e86\u5faa\u73af\u7ed3\u6784\uff0c\u63d0\u9ad8\u4e86\u7f16\u5199\u5bf9\u6574\u6570\u8303\u56f4\u8fdb\u884c\u8fed\u4ee3\u4ee3\u7801\u7684\u65b9\u4fbf\u6027\u3002\u6587\u4e2d\u63d0\u4f9b\u4e86\u8be6\u7ec6\u7684\u4ee3\u7801\u793a\u4f8b\u6765\u5c55\u793a\u65b0\u65e7\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\uff0c\u5e76\u8bf4\u660e\u4e86\u5982\u4f55\u5229\u7528\u65b0\u7279\u6027\u6765\u7f16\u5199\u66f4\u9ad8\u6548\u7684Go\u4ee3\u7801\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/lxp9OqiVAHtoX75UoaHipw"},"\u300a\u4ece\u6162\u901f\u5230SIMD\u300b\u804aGo\u8fb9\u754c\u68c0\u67e5\u6d88\u9664\u300b"),"\u3002\u672c\u6587\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u4e2d\u8fb9\u754c\u68c0\u67e5\u6d88\u9664\uff08BCE\uff09\u7684\u76f8\u5173\u6280\u5de7\u548c\u6700\u4f73\u5b9e\u8df5\u3002\u6587\u7ae0\u9996\u5148\u56de\u7b54\u4e86\u4e3a\u4f55\u5728Go\u4ee3\u7801\u4e2d\u4f18\u5316\u65f6\u9009\u62e9\u4f7f\u7528",(0,r.kt)("inlineCode",{parentName:"p"},"a[i:i+4:i+4]"),"\u800c\u4e0d\u662f",(0,r.kt)("inlineCode",{parentName:"p"},"a[i:i+4]"),"\u7684\u95ee\u9898\uff0c\u6307\u51fa\u524d\u8005\u80fd\u51cf\u5c11\u7f16\u8bd1\u5668\u5de5\u4f5c\u91cf\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u7136\u540e\uff0c\u4ecb\u7ecd\u4e86Go101\u63d0\u51fa\u7684BCE\u6280\u672f\u8be6\u89e3\u4e0e\u5e94\u7528\u5b9e\u4f8b\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528\u7f16\u8bd1\u547d\u4ee4\u6765\u68c0\u6d4b\u8fb9\u754c\u68c0\u67e5\u7684\u5b58\u5728\u3002\u6587\u4e2d\u8fd8\u5168\u9762\u68b3\u7406\u4e86Go BCE\u6280\u672f\u7684\u53d1\u5c55\u5386\u7a0b\uff0c\u4ee5\u53ca\u5728\u4e0d\u540c\u573a\u666f\u4e0b\u6d88\u9664\u5197\u4f59\u8fb9\u754c\u68c0\u67e5\u7684\u65b9\u6cd5\uff0c\u5305\u62ec\u5229\u7528\u5faa\u73af\u53d8\u91cf\u3001\u5e38\u91cf\u7d22\u5f15\u7b49\u7b56\u7565\u6765\u63d0\u9ad8\u4ee3\u7801\u6267\u884c\u6548\u7387\u3002\u6700\u540e\uff0c\u63d0\u4f9b\u4e86\u591a\u79cd\u7f16\u7a0b\u6280\u5de7\u4ee5\u53ca\u76f8\u5173\u8ba8\u8bba\u548c\u53c2\u8003\u8d44\u6599\uff0c\u9488\u5bf9\u9047\u5230\u7684\u7f16\u7a0b\u95ee\u9898\u63d0\u51fa\u89e3\u51b3\u65b9\u6848\u3002"),(0,r.kt)("h2",{id:"-\u540e\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u540e\u7aef\u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7329413905028579340"},"\u300a\u5206\u5e93\u5206\u8868\u5df2\u6210\u4e3a\u8fc7\u53bb\u5f0f\uff0c\u4f7f\u7528\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u624d\u662f\u672a\u6765\u300b"),"\u3002\u672c\u6587\u8ba8\u8bba\u4e86\u968f\u7740Mysql\u6570\u636e\u5e93\u6027\u80fd\u4e0b\u964d\uff0c\u5206\u5e93\u5206\u8868\u7684\u5c40\u9650\u6027\u53ca\u5176\u6240\u5f15\u53d1\u7684\u95ee\u9898\uff0c\u5982\u6027\u80fd\u3001\u4e8b\u52a1\u3001\u6570\u636e\u8fc1\u79fb\u7b49\uff0c\u5e76\u63d0\u51fa\u4f7f\u7528\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u4f5c\u4e3a\u89e3\u51b3\u65b9\u6848\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86TiDB\u8fd9\u6b3e\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u7684\u67b6\u6784\u3001\u7279\u6027\u548c\u4f18\u52bf\uff0c\u5305\u62ec\u5176\u91d1\u878d\u7ea7\u7684\u9ad8\u53ef\u7528\u6027\u3001\u6c34\u5e73\u6269\u5bb9\u80fd\u529b\u3001\u517c\u5bb9\u6027\u4ee5\u53ca\u4e91\u539f\u751f\u8bbe\u8ba1\u3002\u6587\u7ae0\u5f3a\u8c03TiDB\u5728\u5904\u7406\u5927\u89c4\u6a21\u6570\u636e\u65f6\u7684\u6548\u7387\u548c\u53ef\u7ef4\u62a4\u6027\uff0c\u7ec8\u7ed3\u5206\u5e93\u5206\u8868\u7684\u505a\u6cd5\uff0c\u5e76\u901a\u8fc7\u6027\u80fd\u6d4b\u8bd5\u5c55\u793a\u4e86TiDB\u4e0eMySQL\u5728\u4e0d\u540c\u573a\u666f\u4e0b\u7684\u6027\u80fd\u8868\u73b0\u3002\u6700\u7ec8\u603b\u7ed3\uff0c\u5bf9\u4e8e\u6570\u636e\u91cf\u5927\u7684\u5e94\u7528\u573a\u666f\uff0c\u91c7\u7528TiDB\u6765\u9002\u5e94\u672a\u6765\u6570\u636e\u5b58\u50a8\u7684\u9700\u6c42\u662f\u4e00\u4e2a\u66f4\u4f18\u7684\u7b56\u7565\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://juejin.cn/post/7337247324681093129"},"\u300a\u624b\u628a\u624b\u5e26\u4f60\u7cbe\u7b80\u4ee3\u7801-\u4eac\u4e1c\u96f6\u552e\u540e\u7aef\u5b9e\u8df5\u300b"),"\u3002\u672c\u6587\u5206\u4eab\u4e86\u4eac\u4e1c\u96f6\u552e\u540e\u7aef\u5728\u9762\u4e34\u4ee3\u7801\u5e93\u65e5\u6e10\u5e9e\u5927\u548c\u8150\u5316\u7684\u95ee\u9898\u65f6\uff0c\u91c7\u7528\u7684\u4ee3\u7801\u7cbe\u7b80\u65b9\u6cd5\u3002\u6587\u7ae0\u5206\u4e3a\u80cc\u666f\u4ecb\u7ecd\u3001\u4ee3\u7801\u7cbe\u7b80\u6b65\u9aa4\u548c\u5b9e\u65bd\u65b9\u6cd5\u4e09\u90e8\u5206\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u4f7f\u7528IntelliJ IDEA\u81ea\u5e26\u5de5\u5177\u548cPMD\u63d2\u4ef6\u8fdb\u884c\u9759\u6001\u4ee3\u7801\u68c0\u67e5\u7684\u6b65\u9aa4\u3001\u914d\u7f6e\u548c\u4f18\u7f3a\u70b9\uff0c\u4ee5\u53ca\u5982\u4f55\u501f\u52a9\u4eac\u4e1cjacoco\u6d41\u6c34\u7ebf\u8fdb\u884c\u52a8\u6001\u4ee3\u7801\u68c0\u67e5\u3002\u672c\u6587\u65e8\u5728\u964d\u4f4e\u4ee3\u7801\u7ef4\u62a4\u6210\u672c\u3001\u63d0\u5347\u53ef\u7406\u89e3\u6027\uff0c\u5e76\u8be6\u7ec6\u9610\u8ff0\u4e86\u4ee3\u7801\u7cbe\u7b80\u7684\u5b9e\u8df5\u8fc7\u7a0b\u548c\u9884\u671f\u7ed3\u679c\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/ZSXAPM8oFiCGztqbs1kksQ"},"\u300a\u8ddf\u7740iLogtail\u5b66\u4e60\u65e0\u9501\u5316\u7f16\u7a0b\u300b"),"\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5728\u591a\u7ebf\u7a0b\u60c5\u51b5\u4e0b\uff0c\u5982\u4f55\u901a\u8fc7\u65e0\u9501\u5316\u7f16\u7a0b\u4f18\u5316\u8f6f\u4ef6\u6027\u80fd\u3002\u8be6\u7ec6\u8bb2\u8ff0\u4e86iLogtail\u5728\u5b9e\u73b0\u65e0\u9501\u9ad8\u6548\u65e5\u5fd7\u91c7\u96c6\u65f6\u91c7\u53d6\u7684\u7b56\u7565\uff0c\u6bd4\u5982\u81ea\u65cb\u9501\u7684\u4f7f\u7528\u3001\u539f\u5b50\u64cd\u4f5c\u3001\u5185\u5b58\u987a\u5e8f\u3001\u5185\u5b58\u5c4f\u969c\u7b49\u6982\u5ff5\u3002\u8fd8\u5206\u6790\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u9501\u7684\u9002\u7528\u573a\u666f\u4e0e\u7279\u70b9\uff0c\u5305\u62ec\u4e92\u65a5\u9501\u3001\u9012\u5f52\u4e92\u65a5\u9501\u548c\u8bfb\u5199\u9501\u7b49\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u63cf\u8ff0\u4e86\u5982\u4f55\u5c06\u5927\u7684\u9501\u7ec6\u5206\u4e3a\u591a\u4e2a\u5c0f\u9501\uff0c\u901a\u8fc7\u964d\u4f4e\u9501\u7c92\u5ea6\u63d0\u5347\u5e76\u53d1\u6027\u80fd\uff0c\u4ee5\u53ca\u5728iLogtail\u4e2d\u5982\u4f55\u901a\u8fc7\u53ccBuffer\u673a\u5236\u6765\u8bfb\u5199\u5206\u79bb\uff0c\u51cf\u5c11\u9501\u7684\u4e89\u7528\u3002\u6700\u7ec8\uff0c\u901a\u8fc7\u65e0\u9501\u5316\u7f16\u7a0b\u63d0\u9ad8\u4e86iLogtail\u7684\u65e5\u5fd7\u91c7\u96c6\u6027\u80fd\uff0c\u5b9e\u73b0\u4e86\u4f4e\u8d44\u6e90\u6d88\u8017\u548c\u9ad8\u6027\u80fd\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GtU4xBKzfK3q3IsPuQV6pQ"},"\u300aMYSQL \u662f\u5982\u4f55\u4fdd\u8bc1binlog \u548credo log\u540c\u65f6\u63d0\u4ea4\u7684?\u300b"),"\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u786e\u4fdd\u5728MYSQL\u4e2dbinlog\uff08\u5907\u4efd\u548c\u4e3b\u4ece\u540c\u6b65\u7528\u7684\u65e5\u5fd7\uff09\u4e0eredo log\uff08InnoDB\u5f15\u64ce\u5c42\u7684\u65e5\u5fd7\uff0c\u7528\u4e8e\u5d29\u6e83\u6062\u590d\uff09\u540c\u6b65\u63d0\u4ea4\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u8fd9\u4e00\u70b9\u5bf9\u4e8e\u9632\u6b62\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u81f3\u5173\u91cd\u8981\u3002\u6587\u4e2d\u89e3\u91ca\u4e86\u4e8b\u52a1\u5904\u7406\u4e2d\u7684\u4e24\u4e2a\u5173\u952e\u53c2\u6570\uff1a",(0,r.kt)("inlineCode",{parentName:"p"},"innodb_flush_log_at_trx_commit"),"\u548c",(0,r.kt)("inlineCode",{parentName:"p"},"sync_binlog"),"\uff0c\u8fd9\u4e24\u4e2a\u503c\u8bbe\u7f6e\u4e3a1\u65f6\u53ef\u4ee5\u786e\u4fdd\u4e24\u79cd\u65e5\u5fd7\u7684\u540c\u6b65\u63d0\u4ea4\u3002\u8be5\u6587\u8fd8\u4ecb\u7ecd\u4e86MYSQL\u7684\u4e24\u9636\u6bb5\u63d0\u4ea4\u673a\u5236\u5982\u4f55\u5de5\u4f5c\uff0c\u5e76\u63d0\u51fa\u4e86\u4e1a\u52a1\u5f00\u53d1\u4e2d\u4e24\u9636\u6bb5\u63d0\u4ea4\u903b\u8f91\u7684\u601d\u8003\uff0c\u6307\u51fa\u5728\u6709\u4f9d\u8d56\u5173\u7cfb\u7684\u670d\u52a1\u64cd\u4f5c\u4e2d\uff0c\u901a\u8fc7\u9884\u9501\u5b9a\u8d44\u6e90\u3001\u8bf7\u6c42\u6210\u529f\u540e\u9012\u51cf\u8d44\u6e90\u6765\u4fdd\u6301\u6570\u636e\u7684\u6700\u7ec8\u4e00\u81f4\u6027\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/jVKgmbvha6Q-iNxvVzg3nw"},"\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u5206\u5e03\u5f0f\u7bc7\u300b"),"\u3002\u672c\u6587\u4ece\u5206\u5e03\u5f0f\u7cfb\u7edf\u7684\u57fa\u7840\u6982\u5ff5\u3001\u53d1\u5c55\u5386\u7a0b\u53ca\u6838\u5fc3\u95ee\u9898\u51fa\u53d1\uff0c\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u4e2d\u7684\u5173\u952e\u6280\u672f\u70b9\u3002\u6587\u7ae0\u6db5\u76d6\u4e86\u8d1f\u8f7d\u5747\u8861\u3001\u670d\u52a1\u7684\u62c6\u5206\u4e0e\u96c6\u7fa4\u3001\u5206\u5e03\u5f0f\u4e8b\u52a1\u3001\u6570\u636e\u4e00\u81f4\u6027\u95ee\u9898\u4ee5\u53ca\u5206\u533a\u5bb9\u9519\u6027\u7b49\u8bdd\u9898\uff0c\u5e76\u63a2\u8ba8\u4e86CAP\u7406\u8bba\u4e0eBASE\u7406\u8bba\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u6743\u8861\u3002\u540c\u65f6\uff0c\u6587\u4e2d\u8fd8\u8be6\u7ec6\u89e3\u8bfb\u4e86\u5e38\u89c1\u7684\u4e00\u81f4\u6027\u7b97\u6cd5\u59822PC\u30013PC\u3001Paxos\u3001Raft\u7684\u673a\u5236\u548c\u7528\u4f8b\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9488\u5bf9\u5982\u4f55\u5b9e\u73b0\u5206\u5e03\u5f0fSession\u3001\u5982\u4f55\u786e\u4fdd\u5206\u5e03\u5f0f\u4e8b\u52a1\u7684\u4e00\u81f4\u6027\u7b49\u5e38\u89c1\u9762\u8bd5\u9898\u76ee\u63d0\u4f9b\u4e86\u8be6\u5c3d\u7684\u89e3\u7b54\uff0c\u9002\u5408\u505a\u4e3a\u9762\u8bd5\u5907\u8003\u8d44\u6599\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/y1-A-SHAkGdg9IOTeUtPxg"},"\u300aRocketMQ\u4e3a\u4ec0\u4e48\u8fd9\u4e48\u5feb?\u6211\u4ece\u6e90\u7801\u4e2d\u6252\u51fa\u4e8610\u5927\u539f\u56e0!\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5206\u6790\u4e86RocketMQ\u9ad8\u6027\u80fd\u768410\u4e2a\u5173\u952e\u56e0\u7d20\uff1a\u6279\u91cf\u53d1\u9001\u6d88\u606f\u964d\u4f4e\u901a\u4fe1\u6b21\u6570\uff0c\u6d88\u606f\u538b\u7f29\u51cf\u5c11\u5e26\u5bbd\u548c\u5b58\u50a8\u538b\u529b\uff0c\u57fa\u4e8eNetty\u7684\u9ad8\u6548\u7f51\u7edc\u901a\u4fe1\u6a21\u578b\uff0c\u96f6\u62f7\u8d1d\u6280\u672f\u4f18\u5316\u78c1\u76d8\u8bfb\u5199\u6027\u80fd\uff0c\u987a\u5e8f\u5199\u63d0\u9ad8\u6570\u636e\u5199\u5165\u901f\u5ea6\uff0c\u9ad8\u6548\u6570\u636e\u5b58\u50a8\u7ed3\u6784\uff0c\u5f02\u6b65\u673a\u5236\u5305\u62ec\u5f02\u6b65\u5237\u76d8\u548c\u5f02\u6b65\u4e3b\u4ece\u590d\u5236\u63d0\u5347\u5b58\u50a8\u6548\u7387\uff0c\u6279\u91cf\u5904\u7406\u51cf\u5c11\u7f51\u7edc\u901a\u4fe1\u6b21\u6570\u548c\u8d44\u6e90\u6d88\u8017\uff0c\u9501\u4f18\u5316\u4ee5\u53ca\u7ebf\u7a0b\u6c60\u9694\u79bb\u63d0\u5347\u5e76\u53d1\u5904\u7406\u80fd\u529b\u3002\u4f5c\u8005\u901a\u8fc7\u6df1\u5165\u5206\u6790\u6e90\u7801\u7ed9\u51fa\u4e86RocketMQ\u5feb\u901f\u5904\u7406\u548c\u62c9\u53d6\u6d88\u606f\u7684\u5185\u5728\u539f\u56e0\uff0c\u5e76\u6df1\u5165\u8ba8\u8bba\u4e86\u6bcf\u79cd\u6280\u672f\u7684\u4f18\u52bf\u548c\u5b9e\u73b0\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/39t_G3InMtHg9ETj_xYR7Q"},"\u300a\u9886\u5bfc\u53eb\u6211\u63a5\u624b\u4e00\u4e2a\u65b0\u4e1a\u52a1\u7cfb\u7edf\uff0c\u6211\u662f\u8fd9\u6837\u719f\u6089\u9879\u76ee\u7684!\u300b"),"\u3002\u672c\u6587\u4f5c\u8005\u5c0f\u8bb8\u5206\u4eab\u4e86\u63a5\u624b\u65b0\u4e1a\u52a1\u7cfb\u7edf\u7684\u719f\u6089\u6d41\u7a0b\u548c\u5b9e\u8df5\u65b9\u6cd5\u3002\u5305\u62ec\u4e0e\u4ea7\u54c1\u7ecf\u7406\u4ea4\u6d41\u4e86\u89e3\u4e1a\u52a1\u73b0\u72b6\uff0c\u7ed8\u5236\u7528\u4f8b\u56fe\u3001ER\u56fe\u4ee5\u660e\u786e\u4e1a\u52a1\u4e0e\u6570\u636e\u6a21\u578b\uff0c\u68b3\u7406\u540e\u7aef\u6a21\u578b\u548c\u6838\u5fc3\u6d41\u7a0b\uff0c\u5e76\u8fd0\u7528\u72b6\u6001\u673a\u6d41\u8f6c\u56fe\u548c\u65f6\u5e8f\u56fe\u6df1\u5ea6\u89e3\u6790\u590d\u6742\u903b\u8f91\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u5230\u4e86\u7ed8\u5236\u7c7b\u56fe\u4ee5\u7406\u89e3\u4ee3\u7801\u7ed3\u6784\u3002\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u5957\u7cfb\u7edf\u6027\u7684\u5de5\u5177\u548c\u65b9\u6cd5\uff0c\u76ee\u7684\u662f\u5e2e\u52a9\u65b0\u6210\u5458\u6216\u8d1f\u8d23\u65b0\u9879\u76ee\u7684\u5f00\u53d1\u4eba\u5458\u5feb\u901f\u638c\u63e1\u4e1a\u52a1\u903b\u8f91\uff0c\u6709\u6548\u63a8\u8fdb\u9879\u76ee\u8fdb\u5ea6\u3002"),(0,r.kt)("h2",{id:"-\u524d\u7aef\u76f8\u5173"},"\ud83d\udcd2 \u524d\u7aef\u76f8\u5173"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/GqSoZR3bSeuLWiULHt8Zvg"},"\u300aTango \u4f4e\u4ee3\u7801\u5f15\u64ce\u6c99\u7bb1\u5b9e\u73b0\u89e3\u6790\u300b"),"\u3002\u672c\u6587\u4ecb\u7ecd\u4e86Tango\u4f4e\u4ee3\u7801\u5f15\u64ce\u7684\u6c99\u7bb1\u5b9e\u73b0\u3002Tango\u662f\u4e00\u4e2a\u7528\u4e8e\u5feb\u901f\u6784\u5efa\u4f4e\u4ee3\u7801\u5e73\u53f0\u7684\u4f4e\u4ee3\u7801\u8bbe\u8ba1\u5668\u6846\u67b6\uff0c\u901a\u8fc7\u5bf9\u6e90\u4ee3\u7801\u8fdb\u884c\u6267\u884c\u548c\u6e32\u67d3\u524d\u7aef\u89c6\u56fe\uff0c\u5b9e\u73b0\u4e86\u4f4e\u4ee3\u7801\u53ef\u89c6\u5316\u642d\u5efa\u80fd\u529b\u3002\u501f\u52a9Tango\u6784\u5efa\u7684\u4f4e\u4ee3\u7801\u5de5\u5177\u6216\u5e73\u53f0\u53ef\u4ee5\u5b9e\u73b0\u6e90\u7801\u8fdb\u51fa\u7684\u6548\u679c\uff0c\u5e76\u4e0e\u4f01\u4e1a\u5185\u90e8\u73b0\u6709\u7684\u7814\u53d1\u4f53\u7cfb\u8fdb\u884c\u65e0\u7f1d\u96c6\u6210\u3002Tango\u7684\u8bbe\u8ba1\u5668\u5f15\u64ce\u90e8\u5206\u5df2\u7ecf\u5f00\u6e90\uff0c\u5e76\u63d0\u4f9b\u4e86\u76f8\u5e94\u7684\u5f00\u6e90\u4ee3\u7801\u5e93\u3001\u6587\u6863\u548c\u793e\u533a\u8ba8\u8bba\u7ec4\u3002\u6b22\u8fce\u52a0\u5165\u793e\u533a\u53c2\u4e0e\u5230Tango\u4f4e\u4ee3\u7801\u5f15\u64ce\u7684\u5f00\u6e90\u5efa\u8bbe\u4e2d\u3002\u66f4\u591a\u76f8\u5173\u6587\u7ae0\u53ef\u4ee5\u5728\u6587\u4e2d\u63d0\u4f9b\u7684\u94fe\u63a5\u4e2d\u627e\u5230\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/U6ZQwLiW5sfkknz_bayosg"},"\u300a\u672a\u6765\u53ea\u9700\u8981 2% \u7684\u7a0b\u5e8f\u5458?\u300b"),"\u3002DHH\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u63d0\u51fa\u4e00\u4e2a\u6fc0\u8fdb\u7684\u89c2\u70b9\uff0c\u9884\u6d4b\u672a\u6765\u7a0b\u5e8f\u5458\u7684\u9700\u6c42\u53ef\u80fd\u4f1a\u5927\u5e45\u5ea6\u51cf\u5c11\u3002\u4ed6\u6bd4\u8f83\u4e86\u519c\u4e1a\u4ece97%\u7684\u4eba\u53e3\u9700\u6c42\u964d\u81f32%\u7684\u53d8\u8fc1\uff0c\u6697\u793a\u8f6f\u4ef6\u5f00\u53d1\u4e5f\u53ef\u80fd\u9762\u4e34\u7740\u7c7b\u4f3c\u7f29\u51cf\u3002\u5c3d\u7ba1\u8fd9\u4e2a\u884c\u4e1a\u66fe\u7ecf\u7ecf\u5386\u62db\u8058\u70ed\u6f6e\uff0c\u4f46\u73b0\u5728\u8bb8\u591a\u7a0b\u5e8f\u5458\u9762\u4e34\u804c\u4e1a\u524d\u666f\u4e0d\u7a33\u5b9a\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86\u4eba\u5de5\u667a\u80fd\u7684\u53d1\u5c55\u7ed9\u7a0b\u5e8f\u5458\u804c\u4e1a\u5e26\u6765\u7684\u538b\u529b\uff0c\u540c\u65f6\u4e5f\u6307\u51fa\u804c\u4e1a\u53d8\u9769\u7684\u4e0d\u786e\u5b9a\u6027\u3002DHH\u8ba4\u4e3a\uff0c\u672a\u6765\u5927\u591a\u6570\u7a0b\u5e8f\u5458\u53ef\u80fd\u65e0\u9700\u624b\u52a8\u7f16\u7a0b\uff0c\u4f46\u540c\u65f6\u6307\u51fa\u79d1\u6280\u884c\u4e1a\u5c06\u66f4\u52a0\u878d\u5408\u8fdb\u793e\u4f1a\uff0c\u5e76\u63d0\u9ad8\u4e86\u5b83\u7684\u4ef7\u503c\u3002\u4ed6\u9f13\u52b1\u7a0b\u5e8f\u5458\u63a5\u53d7\u8fd9\u4e00\u53d8\u5316\uff0c\u5e76\u4eab\u53d7\u884c\u4e1a\u7684\u9ec4\u91d1\u65f6\u4ee3\u3002"),(0,r.kt)("p",null,(0,r.kt)("a",{parentName:"p",href:"https://mp.weixin.qq.com/s/tiolzTwPKPZF4b8zZbvYpA"},"\u300a\u524d\u7aef\u667a\u80fd\u5316\uff0c\u6263\u5b50(coze.cn)\u80fd\u505a\u4ec0\u4e48?\u300b"),"\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u6263\u5b50\uff08coze.cn\uff09\u5e73\u53f0\u5982\u4f55\u901a\u8fc7\u63d0\u4f9b\u4e00\u4e2a\u7b80\u5355\u7684\u4ea4\u4e92\u5f0f\u754c\u9762\u6765\u521b\u5efa\u804a\u5929\u673a\u5668\u4eba\uff08Chatbot\uff09\u3002\u7528\u6237\u901a\u8fc7\u4e0e\u6263\u5b50\u7684\u5bf9\u8bdd\uff0c\u53ef\u4ee5\u5feb\u901f\u8bbe\u7f6e\u4e00\u4e2aChatbot\uff0c\u5982\u81ea\u52a8\u5316\u5fae\u4fe1\u8ba2\u9605\u53f7\u5185\u5bb9\u53d1\u5e03\u7b49\u3002\u6587\u7ae0\u5f3a\u8c03\u4e86\u5e73\u53f0\u7684\u6613\u7528\u6027\u548c\u754c\u9762\u53cb\u597d\u6027\uff0c\u540c\u65f6\u6307\u51fa\u4e86\u4e00\u4e9b\u6f5c\u5728\u7f3a\u70b9\uff0c\u5305\u62ec\u65e0\u6cd5\u89e3\u51b3\u6df1\u5ea6\u95ee\u9898\u548c\u5076\u5c14\u9047\u5230\u7684\u6280\u672f\u6545\u969c\u3002\u53e6\u5916\uff0c\u901a\u8fc7\u77e5\u8bc6\u5e93\u548c\u6570\u636e\u5e93\u7684\u96c6\u6210\uff0c\u53ef\u8fdb\u4e00\u6b65\u63d0\u5347Bot\u7684\u529f\u80fd\u3002\u4f5c\u8005\u5bf9\u6263\u5b50\u7684\u673a\u5668\u4eba\u521b\u5efa\u8fc7\u7a0b\u3001\u4f18\u52bf\u3001\u5efa\u8bae\u548c\u6539\u8fdb\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u901a\u8fc7\u5b9e\u64cd\u6848\u4f8b\u5c55\u793a\u4e86\u524d\u7aef\u667a\u80fd\u5316\u673a\u5668\u4eba\u7684\u642d\u5efa\u8fc7\u7a0b\u3002"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/cb01c7d8.a34fd5b2.js b/assets/js/cb01c7d8.2c68cf60.js similarity index 97% rename from assets/js/cb01c7d8.a34fd5b2.js rename to assets/js/cb01c7d8.2c68cf60.js index 65c5ec2a95..2ee6710b5c 100644 --- a/assets/js/cb01c7d8.a34fd5b2.js +++ b/assets/js/cb01c7d8.2c68cf60.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[1653],{49613:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>y});var n=r(59496);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),f=p(r),m=a,y=f["".concat(c,".").concat(m)]||f[m]||u[m]||l;return r?n.createElement(y,o(o({ref:t},s),{},{components:r})):n.createElement(y,o({ref:t},s))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[f]="string"==typeof e?e:a,o[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var n=r(64778),a=(r(59496),r(49613));const l={slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},o=void 0,i={permalink:"/frontend-weekly/2024/welcome",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-12-12-welcome/index.md",source:"@site/blogs/2024/2024-12-12-welcome/index.md",title:"\u7f6e\u9876\u5185\u5bb9",description:"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01",date:"2024-12-12T00:00:00.000Z",formattedDate:"December 12, 2024",tags:[{label:"TypeScript",permalink:"/frontend-weekly/2024/tags/type-script"},{label:"\u524d\u7aef\u6846\u67b6",permalink:"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6"},{label:"Webpack",permalink:"/frontend-weekly/2024/tags/webpack"},{label:"\u6e90\u7801\u7cfb\u5217",permalink:"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217"},{label:"\u4e1a\u52a1\u6210\u957f",permalink:"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f"},{label:"\u6027\u80fd\u4f18\u5316",permalink:"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316"},{label:"\u7ec4\u4ef6\u5e93\u5b9e\u6218",permalink:"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218"},{label:"\u7f51\u7edc\u76f8\u5173",permalink:"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173"},{label:"\u673a\u5668\u5b66\u4e60",permalink:"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60"},{label:"Java",permalink:"/frontend-weekly/2024/tags/java"},{label:"Golang",permalink:"/frontend-weekly/2024/tags/golang"}],readingTime:144.44,hasTruncateMarker:!0,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},nextItem:{title:"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"}},c={authorsImageUrls:[void 0]},p=[],s={toc:p},f="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(f,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01"))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[1653],{49613:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>y});var n=r(59496);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function l(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function o(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var l=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var c=n.createContext({}),p=function(e){var t=n.useContext(c),r=t;return e&&(r="function"==typeof e?e(t):o(o({},t),e)),r},s=function(e){var t=p(e.components);return n.createElement(c.Provider,{value:t},e.children)},f="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,l=e.originalType,c=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),f=p(r),m=a,y=f["".concat(c,".").concat(m)]||f[m]||u[m]||l;return r?n.createElement(y,o(o({ref:t},s),{},{components:r})):n.createElement(y,o({ref:t},s))}));function y(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var l=r.length,o=new Array(l);o[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[f]="string"==typeof e?e:a,o[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>u,frontMatter:()=>l,metadata:()=>i,toc:()=>p});var n=r(64778),a=(r(59496),r(49613));const l={slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},o=void 0,i={permalink:"/frontend-weekly/2024/welcome",editUrl:"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-12-12-welcome/index.md",source:"@site/blogs/2024/2024-12-12-welcome/index.md",title:"\u7f6e\u9876\u5185\u5bb9",description:"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01",date:"2024-12-12T00:00:00.000Z",formattedDate:"December 12, 2024",tags:[{label:"TypeScript",permalink:"/frontend-weekly/2024/tags/type-script"},{label:"\u524d\u7aef\u6846\u67b6",permalink:"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6"},{label:"Webpack",permalink:"/frontend-weekly/2024/tags/webpack"},{label:"\u6e90\u7801\u7cfb\u5217",permalink:"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217"},{label:"\u4e1a\u52a1\u6210\u957f",permalink:"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f"},{label:"\u6027\u80fd\u4f18\u5316",permalink:"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316"},{label:"\u7ec4\u4ef6\u5e93\u5b9e\u6218",permalink:"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218"},{label:"\u7f51\u7edc\u76f8\u5173",permalink:"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173"},{label:"\u673a\u5668\u5b66\u4e60",permalink:"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60"},{label:"Java",permalink:"/frontend-weekly/2024/tags/java"},{label:"Golang",permalink:"/frontend-weekly/2024/tags/golang"}],readingTime:144.44,hasTruncateMarker:!0,authors:[{name:"\u52a0\u83f2\u732b",title:"\u524d\u7aef\u5f00\u53d1 @NETEASE",url:"https://github.com/Jiacheng787",imageURL:"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG",key:"garfield"}],frontMatter:{slug:"welcome",title:"\u7f6e\u9876\u5185\u5bb9",authors:["garfield"],tags:["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},nextItem:{title:"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",permalink:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"}},c={authorsImageUrls:[void 0]},p=[],s={toc:p},f="wrapper";function u(e){let{components:t,...r}=e;return(0,a.kt)(f,(0,n.Z)({},s,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("p",null,"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01"))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ce5f8616.827be279.js b/assets/js/ce5f8616.7ae6b609.js similarity index 79% rename from assets/js/ce5f8616.827be279.js rename to assets/js/ce5f8616.7ae6b609.js index 75238ec2dd..d867a4b29c 100644 --- a/assets/js/ce5f8616.827be279.js +++ b/assets/js/ce5f8616.7ae6b609.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[3865],{20638:e=>{e.exports=JSON.parse('{"permalink":"/frontend-weekly/2024","page":1,"postsPerPage":10,"totalPages":2,"totalCount":11,"nextPage":"/frontend-weekly/2024/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[3865],{20638:e=>{e.exports=JSON.parse('{"permalink":"/frontend-weekly/2024","page":1,"postsPerPage":10,"totalPages":2,"totalCount":12,"nextPage":"/frontend-weekly/2024/page/2","blogDescription":"Blog","blogTitle":"Blog"}')}}]); \ No newline at end of file diff --git a/assets/js/fbf1db8d.eda2dc73.js b/assets/js/fbf1db8d.e483494e.js similarity index 56% rename from assets/js/fbf1db8d.eda2dc73.js rename to assets/js/fbf1db8d.e483494e.js index 19bfd39235..3f7ba0efa8 100644 --- a/assets/js/fbf1db8d.eda2dc73.js +++ b/assets/js/fbf1db8d.e483494e.js @@ -1 +1 @@ -"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[8621],{54197:n=>{n.exports=JSON.parse('{"blogPosts":[{"id":"welcome","metadata":{"permalink":"/frontend-weekly/2024/welcome","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-12-12-welcome/index.md","source":"@site/blogs/2024/2024-12-12-welcome/index.md","title":"\u7f6e\u9876\u5185\u5bb9","description":"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01","date":"2024-12-12T00:00:00.000Z","formattedDate":"December 12, 2024","tags":[{"label":"TypeScript","permalink":"/frontend-weekly/2024/tags/type-script"},{"label":"\u524d\u7aef\u6846\u67b6","permalink":"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6"},{"label":"Webpack","permalink":"/frontend-weekly/2024/tags/webpack"},{"label":"\u6e90\u7801\u7cfb\u5217","permalink":"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217"},{"label":"\u4e1a\u52a1\u6210\u957f","permalink":"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f"},{"label":"\u6027\u80fd\u4f18\u5316","permalink":"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316"},{"label":"\u7ec4\u4ef6\u5e93\u5b9e\u6218","permalink":"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218"},{"label":"\u7f51\u7edc\u76f8\u5173","permalink":"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173"},{"label":"\u673a\u5668\u5b66\u4e60","permalink":"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60"},{"label":"Java","permalink":"/frontend-weekly/2024/tags/java"},{"label":"Golang","permalink":"/frontend-weekly/2024/tags/golang"}],"readingTime":144.44,"hasTruncateMarker":true,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"welcome","title":"\u7f6e\u9876\u5185\u5bb9","authors":["garfield"],"tags":["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},"nextItem":{"title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01\\n\\n\x3c!--truncate--\x3e\\n\\n## TypeScript \u5de5\u7a0b\u5316\u65b9\u6848\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357](https://zhuanlan.zhihu.com/p/403970666)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u90fd 2022 \u5e74\u4e86\uff0c\u624b\u52a8\u642d\u5efa React \u5f00\u53d1\u73af\u5883\u5f88\u96be\u5417](https://juejin.cn/post/7087811040591675428)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4f1a\u5199 TypeScript \u4f46\u4f60\u771f\u7684\u4f1a TS \u7f16\u8bd1\u914d\u7f6e\u5417\uff1f](https://juejin.cn/post/7039583726375796749#heading-22)\\n- \ud83c\udf1b [\u3010\u5f00\u6e90\u3011\u4e00\u4e2a React + TS \u9879\u76ee\u6a21\u677f](https://juejin.cn/post/6844904102355271694)\\n - \u4e00\u79cd\u662f\u4f7f\u7528 ts-loader + babel-loader + fork-ts-checker-webpack-plugin \u901a\u8fc7 typescript \u8fdb\u884c\u7f16\u8bd1\u548c\u7c7b\u578b\u68c0\u67e5\\n - \u53e6\u4e00\u79cd\u662f babel-loader + @babel/preset-typescript \u4f7f\u7528 babel \u8fdb\u884c\u7f16\u8bd1\uff0ctypescript \u53ea\u8d1f\u8d23\u7c7b\u578b\u68c0\u67e5\uff08babel 7 \u4ee5\u4e0a\uff09\\n- \ud83c\udf1b [2021\u5e74\u4ece\u96f6\u5f00\u53d1\u524d\u7aef\u9879\u76ee\u6307\u5357](https://juejin.cn/post/6999807899149008910)\\n- [Webpack \u8f6c\u8bd1 Typescript \u73b0\u6709\u65b9\u6848](https://juejin.cn/post/6844904052094926855)\\n- \ud83c\udf1b [\u4f7f\u7528ESLint+Prettier\u6765\u7edf\u4e00\u524d\u7aef\u4ee3\u7801\u98ce\u683c](https://segmentfault.com/a/1190000015315545)\\n- \ud83c\udf1b [\u7528 husky \u548c lint-staged \u6784\u5efa\u8d85\u6e9c\u7684\u4ee3\u7801\u68c0\u67e5\u5de5\u4f5c\u6d41](https://segmentfault.com/a/1190000009546913)\\n\\n## TS \u9ad8\u7ea7\u6280\u5de7\\n\\n- \u2b50\ufe0f [\u4f60\u9700\u8981\u77e5\u9053\u7684TypeScript\u9ad8\u7ea7\u7c7b\u578b](https://mp.weixin.qq.com/s/usDh1-Wzxrf4BftfWhwduA)\\n- \ud83c\udf1b [Typescript \u7c7b\u578b\u7f16\u7a0b\uff0c\u4ece\u5165\u95e8\u5230\u901a\u8fbe](https://mp.weixin.qq.com/s/WsldmkW2ovp-okxSY3le9g)\\n- \ud83c\udf1b [\u5982\u4f55\u8fdb\u9636TypeScript\u529f\u5e95\uff1f\u4e00\u6587\u5e26\u4f60\u7406\u89e3TS\u4e2d\u5404\u79cd\u9ad8\u7ea7\u8bed\u6cd5](https://juejin.cn/post/7089809919251054628)\\n- \ud83c\udf1b [TypeScript\u4ece\u5e73\u51e1\u5230\u4e0d\u51e1\uff08\u57fa\u7840\u7bc7\uff09](https://juejin.cn/post/6998785406619615269)\\n- \ud83c\udf1b [\u63a8\u835012\u4e2a\u503c\u5f97\u5b66\u4e60\u7684TypeScript\u5b9d\u5e93\uff01](https://juejin.cn/post/7150668738990178312)\\n- \ud83c\udf1b [TypeScript \u7c7b\u578b\u7cfb\u7edf\uff1a\u5206\u5e03\u5f0f\u6761\u4ef6\u7c7b\u578b\u5168\u89e3](https://mp.weixin.qq.com/s/TUv8Cu6_ftQQ6lEWAwIa4w)\\n- \ud83c\udf1b [\u63a5\u8fd1\u5929\u82b1\u677f\u7684TS\u7c7b\u578b\u4f53\u64cd\uff0c\u770b\u61c2\u4f60\u5c31\u80fd\u73a9\u8f6cTS\u4e86](https://juejin.cn/post/7061556434692997156)\\n- \ud83c\udf1b [TypeScript \u7c7b\u578b\u7f16\u7a0b: \u4ece\u57fa\u7840\u5230\u7f16\u8bd1\u5668\u5b9e\u6218](https://mp.weixin.qq.com/s/-x8iVK-hlQd3-OZDC04A5A)\\n- \ud83c\udf1b [\u77e5\u5176\u7136\uff0c\u77e5\u5176\u6240\u4ee5\u7136\uff1aTypeScript \u4e2d\u7684\u534f\u53d8\u4e0e\u9006\u53d8](https://juejin.cn/post/7050099282317148174)\\n- \u2b50\ufe0f [TypeScript\u662f\u5982\u4f55\u5de5\u4f5c\u7684](https://juejin.cn/post/7007251289721536543)\\n- \u2b50\ufe0f [TypeScript \u9ad8\u7ea7\u7528\u6cd5](https://juejin.cn/post/6964692485415108645)\\n- \u2b50\ufe0f [\u629b\u7816\u5f15\u7389\uff1aTypeScript \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://mp.weixin.qq.com/s/owtE_7PVLyz5XqwGofaTZg)\\n- \u2b50\ufe0f [\u7ec6\u6570\u8fd9\u4e9b\u5e74\u88ab\u56f0\u6270\u8fc7\u7684 TS \u95ee\u9898](https://juejin.cn/post/6871752423577223176)\\n- [TS \u5e38\u89c1\u95ee\u9898\u6574\u7406\uff0860\u591a\u4e2a\uff0c\u6301\u7eed\u66f4\u65b0ing\uff09](https://juejin.cn/post/6844904055039344654)\\n- [Ts\u9ad8\u624b\u7bc7\uff1a22\u4e2a\u793a\u4f8b\u6df1\u5165\u8bb2\u89e3Ts\u6700\u6666\u6da9\u96be\u61c2\u7684\u9ad8\u7ea7\u7c7b\u578b\u5de5\u5177](https://juejin.cn/post/6994102811218673700)\\n\\n## TS && \u6846\u67b6\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4e00\u4efd\u5f88\u5168\u9762\u7684 React TypeScript \u5907\u5fd8\u5f55](https://react-typescript-cheatsheet.netlify.app/)\\n\x3c!-- - \u2b50\ufe0f \u2b50\ufe0f [\u4f7f\u7528 TypeScript \u7f16\u5199 React \u7684\u6700\u4f73\u5b9e\u8df5\uff01](https://mp.weixin.qq.com/s/o_cXCroRSK5HAKG0wjC29Q) --\x3e\\n- \u2b50\ufe0f \u2b50\ufe0f [React + TypeScript\u5b9e\u8df5](https://juejin.cn/post/6952696734078369828)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86](https://juejin.cn/post/7071066976830881823)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357](https://juejin.cn/post/7069555976717729805)\\n- [\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript](https://juejin.cn/post/7058868160706904078)\\n- [TypeScript \u7ec8\u6781\u521d\u5b66\u8005\u6307\u5357](https://mp.weixin.qq.com/s/6DAyXFHIMW95FS0f3GyHpA)\\n- [\u5982\u4f55\u4f18\u96c5\u5730\u5728 React \u4e2d\u4f7f\u7528TypeScript\uff0c\u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01](https://juejin.cn/post/7021674818621669389)\\n- [\u7cbe\u8bfb\u300a@types react \u503c\u5f97\u6ce8\u610f\u7684 TS \u6280\u5de7\u300b](https://juejin.cn/post/6844904122550845448)\\n- [\u300c1.9W\u5b57\u603b\u7ed3\u300d\u4e00\u4efd\u901a\u4fd7\u6613\u61c2\u7684 TS \u6559\u7a0b\uff0c\u5165\u95e8 + \u5b9e\u6218\uff01](https://juejin.cn/post/7068081327857205261)\\n- \u2b50\ufe0f [Vue3.0 \u524d\u7684 TypeScript \u6700\u4f73\u5165\u95e8\u5b9e\u8df5](https://juejin.cn/post/6844903865255477261)\\n - \u867d\u7136\u4e0d\u662f Vue3 \u4f46\u662f\u4e5f\u63a8\u8350\u770b\u4e0b\\n\\n## \u524d\u7aef\u6846\u67b6\\n\\n- [\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e Vue \u6587\u7ae0](https://juejin.cn/post/7047705995534925832)\\n- [\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e React \u6587\u7ae0](https://juejin.cn/post/7047690546417565733)\\n- [\u76d8\u70b9\u6398\u91d1 2021 \u70b9\u8d5e\u9ad8\u8fbe 6000\uff0c\u6536\u85cf\u8fc7\u4e07\u7684\u6587\u7ae0](https://juejin.cn/post/7047153016771706916)\\n- \u2b50\ufe0f [\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a](https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q)\\n- \u2b50\ufe0f [Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09](https://juejin.cn/post/6844903913410314247)\\n- \u2b50\ufe0f [\\\\[\u79d1\u666e\u6587\\\\] Vue3 \u5230\u5e95\u66f4\u65b0\u4e86\u4ec0\u4e48\uff1f](https://mp.weixin.qq.com/s/66sos7nML5rA0ZZGJ5qFIQ)\\n- \u2b50\ufe0f [\u63ed\u79d8 Vue.js \u4e5d\u4e2a\u6027\u80fd\u4f18\u5316\u6280\u5de7](https://juejin.cn/post/6922641008106668045)\\n- \ud83c\udf1b [\u6211\u5728\u9879\u76ee\u4e2d\u7528\u5b9e\u9645\u7528\u5230\u768422\u4e2aVue\u4f18\u5316\u6280\u5de7](https://juejin.cn/post/7005880217684148231)\\n- \ud83c\udf1b [React Hooks \u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6844904165500518414)\\n- \ud83c\udf1b [React Hooks \u4f7f\u7528\u8bef\u533a\uff0c\u9a73\u5b98\u65b9\u6587\u6863](https://juejin.cn/post/7046358484610187277)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b9d\u554a\uff5e\u6765\u804a\u804a 9 \u79cd React Hook](https://juejin.cn/post/7043772161596588046)\\n- \u2b50\ufe0f [\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684\u6d41\u5f0f React Hooks\uff08\u5173\u4e8e\u7ec4\u7ec7\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5\uff09](https://juejin.cn/post/6933018383961194509)\\n- \u2b50\ufe0f [\u4ece 16 \u4e2a\u65b9\u5411\u9010\u6b65\u642d\u5efa\u57fa\u4e8e vue3 \u7684\u524d\u7aef\u67b6\u6784](https://juejin.cn/post/7025524870842679310#heading-58)\\n- \u2b50\ufe0f [34\u6761\u6211\u80fd\u544a\u8bc9\u4f60\u7684Vue\u4e4b\u5b9e\u64cd\u7bc7](https://juejin.cn/post/6874007172578033677)\\n- \ud83c\udf1b [React \u4f53\u7cfb\u4e0b\u5173\u4e8e Mobx \u4e0e Redux \u7684\u4e00\u4e9b\u601d\u8003](https://zhuanlan.zhihu.com/p/461844358)\\n- \ud83c\udf1b [\u4f7f\u7528 React&Mobx \u7684\u51e0\u4e2a\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/aOapwk4_qi8tNM7vaa7jGA)\\n- \u2b50\ufe0f [\u5f53\u8bbe\u8ba1\u6a21\u5f0f\u9047\u4e0a Hooks](https://juejin.cn/post/6995834232350179336)\\n- \u2b50\ufe0f \u2b50\ufe0f [React Hooks \u8be6\u89e3 \u3010\u8fd1 1W \u5b57\u3011+ \u9879\u76ee\u5b9e\u6218](https://juejin.cn/post/6844903985338400782)\\n- [\u300cReact\u8fdb\u9636\u300d\u53ea\u7528\u4e24\u4e2a\u81ea\u5b9a\u4e49 Hooks \u5c31\u80fd\u66ff\u4ee3 React-Redux ?](https://juejin.cn/post/6989022564043456543)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300d React\u5168\u90e8api\u89e3\u8bfb+\u57fa\u7840\u5b9e\u8df5\u5927\u5168(\u592f\u5b9e\u57fa\u78402\u4e07\u5b57\u603b\u7ed3)](https://juejin.cn/post/6950063294270930980)\\n- [\u300cReact\u8fdb\u9636\u300d\u63a2\u6848\u63ed\u79d8\u516d\u79cdReact\u2018\u7075\u5f02\u2019\u73b0\u8c61](https://juejin.cn/post/6963053793613185031)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406](https://juejin.cn/post/6944863057000529933)\\n\\n## \u7f16\u7a0b\u8303\u5f0f\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [\u51fd\u6570\u5f0f\u7f16\u7a0b\u672f\u8bed](https://github.com/shfshanyue/fp-jargon-zh)\\n- [\u51fd\u6570\u5f0f\u7f16\u7a0b\uff08FP\uff09](https://juejin.cn/post/7065093131233919006)\\n- [coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b](https://juejin.cn/post/6974377246140301342)\\n- [\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48](https://juejin.cn/post/6892886272377880583)\\n- [\u7b80\u660e JavaScript \u51fd\u6570\u5f0f\u7f16\u7a0b\u2014\u2014\u5165\u95e8\u7bc7](https://juejin.cn/post/6844903936378273799)\\n\\n## \u6280\u672f\u65b9\u6848\\n\\n- \u2b50\ufe0f [\u5982\u4f55\u53bb\u641e\u524d\u7aef\u57fa\u5efa](https://juejin.cn/post/7144881028661723167)\\n- \u2b50\ufe0f [\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8](https://juejin.cn/post/7129298214959710244)\\n- \u2b50\ufe0f [\u817e\u8baf\u4e8c\u9762\uff1a\u73b0\u5728\u8981\u4f60\u5b9e\u73b0\u4e00\u4e2a\u57cb\u70b9\u76d1\u63a7SDK\uff0c\u4f60\u4f1a\u600e\u4e48\u8bbe\u8ba1](https://juejin.cn/post/7085679511290773534)\\n- \u2b50\ufe0f [\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22](https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA)\\n- [\u817e\u8baf\u4e09\u9762\uff1aCookie\u7684SameSite\u4e86\u89e3\u5427\uff0c\u90a3SameParty\u5462](https://juejin.cn/post/7087206796351242248)\\n- [\u817e\u8baf\u4e00\u9762\uff1aCORS\u4e3a\u4ec0\u4e48\u80fd\u4fdd\u969c\u5b89\u5168\uff1f\u4e3a\u4ec0\u4e48\u53ea\u5bf9\u590d\u6742\u8bf7\u6c42\u505a\u9884\u68c0](https://juejin.cn/post/7081539471585312805)\\n- [\u4e0d\u4f7f\u7528\u7b2c\u4e09\u65b9\u5e93\u600e\u4e48\u5b9e\u73b0\u3010\u524d\u7aef\u5f15\u5bfc\u9875\u3011\u529f\u80fd](https://mp.weixin.qq.com/s/3hXLSOQC-B5JGmkOaYjgqw)\\n- [\u524d\u7aef\u67b6\u6784\u5e26\u4f60 \u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u7ec8\u8eab\u53d7\u76ca\u300c\u7f8e\u56e2\u540e\u7aef\u8fde\u8fde\u70b9\u8d5e\u300d](https://juejin.cn/post/7124573626161954823)\\n- [\u3010\u7b2c2759\u671f\u3011\u5f02\u6b65\u5206\u7247\u8ba1\u7b97\u5728\u817e\u8baf\u6587\u6863\u7684\u5b9e\u8df5](https://mp.weixin.qq.com/s/d5M_-8XqFGYnpif7GQNmLA)\\n- [\u5b57\u8282\u524d\u7aef\u76d1\u63a7 SDK \u4f53\u79ef\u4e0e\u6027\u80fd\u4f18\u5316\u5b9e\u8df5](https://mp.weixin.qq.com/s/FZUTFvOutS5NvURjj9jOFA)\\n- [\u4f7f\u7528 Vite \u63d2\u4ef6\u81ea\u52a8\u5316\u5b9e\u73b0\u9aa8\u67b6\u5c4f](https://mp.weixin.qq.com/s/8cguocg_1DtZkHLfAGLyXg)\\n- [\u76d8\u70b912\u4e2ayyds\u7684\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/l7SA04BJovmJTUDIuobYiw)\\n- [\u3010\u7b2c2628\u671f\u3011\u57fa\u4e8e\u8bbe\u8ba1\u7a3f\u8bc6\u522b\u7684\u53ef\u89c6\u5316\u4f4e\u4ee3\u7801\u7cfb\u7edf\u5b9e\u8df5](https://mp.weixin.qq.com/s/1HyQLZcnZN6I27p_hbfUPg)\\n- [\u6d45\u8c08\u6587\u6863\u7684\u5b9e\u65f6\u534f\u540c\u7f16\u8f91](https://mp.weixin.qq.com/s/Ba-3fMQXNXqIzVTjVUrWtQ)\\n- [\u81ea\u52a8\u5316\u751f\u6210\u9aa8\u67b6\u5c4f\u7684\u6280\u672f\u65b9\u6848\u8bbe\u8ba1\u4e0e\u843d\u5730](https://mp.weixin.qq.com/s/-WHafu5z-Ap4tjrbWesnmA)\\n- \u2b50\ufe0f [\u8c08\u8c08JS\u4e8c\u8fdb\u5236\uff1aFile\u3001Blob\u3001FileReader\u3001ArrayBuffer\u3001Base64](https://juejin.cn/post/7148254347401363463)\\n- \u2b50\ufe0f [\u5b57\u8282\u8df3\u52a8\u9762\u8bd5\u5b98\uff1a\u8bf7\u4f60\u5b9e\u73b0\u4e00\u4e2a\u5927\u6587\u4ef6\u4e0a\u4f20\u548c\u65ad\u70b9\u7eed\u4f20](https://juejin.cn/post/6844904046436843527)\\n- \u2b50\ufe0f [\u4ece\u96f6\u5f00\u59cb\u624b\u5199\u4e00\u4e2a\u300c\u5f00\u7bb1\u5373\u7528\u7684\u5927\u6587\u4ef6\u5206\u7247\u4e0a\u4f20\u5e93\u300d](https://juejin.cn/post/6990283221170651149)\\n- [5000\u5b57\u5e26\u4f60\u5168\u9762\u6df1\u5165\u7406\u89e3JS\u4e2d\u7684Stream API\uff5c8\u6708\u66f4\u6587\u6311\u6218](https://juejin.cn/post/6992007156320960542)\\n\\n## \u4e1a\u52a1\u6210\u957f && \u8f6f\u6280\u80fd\\n\\n- \u7ba1\u7406\u76f8\u5173\\n - \u2b50\ufe0f \u2b50\ufe0f [\u7ba1\u7406\u5c0f\u518c\u3001\u4e00\u7ebf\u540c\u5b66\u63a8\u8350\u3001\u4e00\u7ebfLeader\u63a8\u8350\u3001\u603b\u76d1\u7ea7\u63a8\u8350](https://mp.weixin.qq.com/s/neSFlzQMh2P7ROwJxhVNkg)\\n - \u2b50\ufe0f [\u8c01\u80fd\u6210\u4e3aLeader\uff0c\u5927Leader\u8be5\u505a\u4ec0\u4e48](https://mp.weixin.qq.com/s/FDK0a4HeO60fKyr6ioRYcw)\\n - \u2b50\ufe0f [\u5c11\u5e74\uff0c\u77e5\u9053\u4ec0\u4e48\u662f\u4fe1\u606f\u5dee\u521b\u9020\u4ef7\u503c\u5417](https://mp.weixin.qq.com/s/dTXg9a4kXwVZi2N7mP71mg)\\n - \u2b50\ufe0f [\u4ec0\u4e48\u662f\u5411\u4e0a\u7ba1\u7406](https://mp.weixin.qq.com/s/oodAZtxzHCZVGIGS9rBzIA)\\n - \u2b50\ufe0f [\u4f60\u662f\u5982\u4f55\u505a\u6c47\u62a5\u7684](https://mp.weixin.qq.com/s/B3qgLTvSHzE33d6O-k7bAQ)\\n- \u2b50\ufe0f [\u5e73\u65f6\u7684\u5de5\u4f5c\u5982\u4f55\u4f53\u73b0\u4e00\u4e2a\u4eba\u7684\u6280\u672f\u6df1\u5ea6](https://juejin.cn/post/7073001183123603470)\\n- \u2b50\ufe0f [\u5982\u4f55\u6210\u4e3a\u4f18\u79c0\u5de5\u7a0b\u5e08\u4e4b\u8f6f\u6280\u80fd\u7bc7](https://mp.weixin.qq.com/s/U6jAFVrgrKIm9--amZV5rA)\\n- \u2b50\ufe0f [\u5e72\u8d27\uff016\u4e2a\u65b9\u9762\uff0c32\u6761\u603b\u7ed3\u6559\u4f60\u63d0\u5347\u804c\u573a\u7ecf\u9a8c](https://mp.weixin.qq.com/s/MOWQ3rBFaITHSD2hvSelcw)\\n- \u2b50\ufe0f [\u804a\u804a\u5982\u4f55\u5b66\u4e60](https://mp.weixin.qq.com/s/kozXWY95HXiQPGou1sfttg)\\n- \u2b50\ufe0f [\u4ee5\u524d\u7aef\u67b6\u6784\u5e08\u8eab\u4efd\uff0c\u4ece\u96f6\u5f00\u59cb\u641e\u4e8b\u641e\u4e8b\u641e\u4e8b](https://mp.weixin.qq.com/s/K36xQbYgGVme8v_p9_dhkQ)\\n- \u2b50\ufe0f [Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3](https://juejin.cn/post/7115634967945674765)\\n- \u2b50\ufe0f [\u4e00\u56fe\u80dc\u5343\u8a00\u7cfb\u5217\u2014\u2014\u6cf3\u9053\u56fe\u548c\u6570\u636e\u6d41\u56fe](https://juejin.cn/post/7185376363808260152)\\n- \u2b50\ufe0f [\u600e\u4e48\u505a\u5230\u4e00\u56fe\u80dc\u5343\u8a00](https://juejin.cn/post/7153432342919397383)\\n- \u2b50\ufe0f [\u3010\u56fe\u4e66\u3011\u7a0b\u5e8f\u5458\u7684\u5e95\u5c42\u601d\u7ef4](https://mp.weixin.qq.com/s/URJC9ERPrcniiFinUsIJkg)\\n- \u2b50\ufe0f [\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u5b98\uff0c\u539f\u6765\u8fd9\u79cd\u5b66\u751f\u6700\u5403\u9999\uff01](https://mp.weixin.qq.com/s/iTFj1Sn5vPTgkAT2Q9YC0w)\\n- \u2b50\ufe0f [\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\uff01YYDS](https://mp.weixin.qq.com/s/rJN14WFRTKjhoy8oWPulWw)\\n- \u2b50\ufe0f [\u5982\u4f55\u5728\u9879\u76ee\u5f00\u53d1\u4e2d\u9010\u6b65\u6210\u957f](https://mp.weixin.qq.com/s/cbKpWKWrhyJwKQhlyYhQ_w)\\n- \u2b50\ufe0f [\u51b4\u7fbd\u7b54\u8bfb\u8005\u95ee\uff1a\u5982\u4f55\u5728\u5de5\u4f5c\u4e2d\u6253\u9020\u5f71\u54cd\u529b\uff0c\u5e26\u52a8\u540c\u4e8b](https://juejin.cn/post/7114967732805697543)\\n- \u2b50\ufe0f [\u5165\u804cApifox\u7814\u53d1\u7ec4\u534a\u5e74\uff0c\u6211\u6240\u63d0\u5347\u7684\u8f6f\u6280\u80fd\uff5c\u6587\u672b\u62bd\u4e66](https://mp.weixin.qq.com/s/1BdXL5dQfP6DnK7iJs6zGQ)\\n- \u2b50\ufe0f [\u6709\u54ea\u4e9b\u503c\u5f97\u8ba1\u7b97\u673a\u4e13\u4e1a\u5b66\u751f\u52a0\u5165\u7684\u56fd\u4f01](https://mp.weixin.qq.com/s/G8SVu9CWrKwbT5jfXaBmtw)\\n- \u2b50\ufe0f [\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09](https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ)\\n- [\u5982\u4f55\u5199\u597d\u4e00\u4efd\u664b\u5347PPT\uff08\u9644PPT\u6a21\u677f\uff09](https://mp.weixin.qq.com/s/1QMPfODUcH1p4pGaoO1owA)\\n- [\u5982\u4f55\u753b\u51fa\u4e00\u5f20\u4f18\u79c0\u7684\u67b6\u6784\u56fe\uff08\u8001\u9e1f\u5fc5\u5907\uff09](https://mp.weixin.qq.com/s/hXFWU6uuil1aC1lEYO_KhQ)\\n- \u2b50\ufe0f [\u7cbe\u8bfb\u300a\u524d\u7aef\u804c\u4e1a\u89c4\u5212 - 2021 \u5e74\u300b](https://juejin.cn/post/6965675185890394119)\\n- \u2b50\ufe0f [2022\u5e74\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u5927\u524d\u7aefLeader\uff1f](https://juejin.cn/post/7034419410706104356)\\n- \u2b50\ufe0f [\u6280\u672f\u4eba\u7684\u4e03\u5927\u5fc5\u5907\u7279\u8d28](https://mp.weixin.qq.com/s/n4Pa0Bao1ISS68IOPWGI_Q)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u521d\u7ea7\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u6210\u957f\u548c\u5bfb\u6c42\u7a81\u7834](https://juejin.cn/post/6906468062943182862#heading-8)\\n- [\u5e74\u5e95\u4e86\uff0c\u4f60\u662f\u5982\u4f55\u505a\u5de5\u4f5c\u6c47\u62a5\u7684\uff1f](https://mp.weixin.qq.com/s/NRqhJax8e6K8LMCNZSSozA)\\n- \u2b50\ufe0f [\u5199\u7ed9\u521d\u4e2d\u7ea7\u524d\u7aef\u7684\u9ad8\u7ea7\u8fdb\u9636\u6307\u5357](https://juejin.cn/post/6844904103504527374)\\n- [\u5728\u653f\u91c7\u4e91\u5982\u4f55\u5199\u524d\u7aef\u6280\u672f\u65b9\u6848\u6587\u6863](https://juejin.cn/post/7041713124210114567)\\n- [\u5982\u4f55\u7f16\u5199\u524d\u7aef\u8bbe\u8ba1\u6587\u6863](https://juejin.cn/post/7017643726944108558)\\n- \u2b50\ufe0f [\u7406\u6e05\u601d\u8def\uff0c\u524d\u7aef\u6280\u672f\u8c03\u7814\u5230\u5e95\u5e94\u8be5\u600e\u4e48\u505a\uff1f](https://juejin.cn/post/6901845776880795662#heading-0)\\n- [\u4ece\u5b9e\u4e60\u5230\u5165\u804c\uff1a\u4e0e\u4f60\u5206\u4eab\u6211\u5728\u653f\u91c7\u4e91\u7684\u5de5\u4f5c\u548c\u6210\u957f](https://juejin.cn/post/6869548364640288781)\\n\\n## Git \u76f8\u5173\\n\\n- \u2b50\ufe0f [\u8840\u6cea\u6559\u8bad\u4e4b\u8bf7\u4e0d\u8981\u518d\u8f7b\u89c6Git \u2014\u2014 \u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 Git \u7684](https://zhuanlan.zhihu.com/p/250493093)\\n- \u2b50\ufe0f [GitHub \u641c\u7d22\u6280\u5de7\uff1a\u5982\u4f55\u66f4\u6709\u6548\u5730\u641c\u7d22 issue\u3001repo \u548c\u66f4\u591a\u4fe1\u606f](https://mp.weixin.qq.com/s/aTr6xf4BEuF-yxL340TnLg)\\n- \u2b50\ufe0f [\u5982\u679c\u4f60\u8fd8\u4e0d\u4f1a\u7528git\u56de\u6eda\u4ee3\u7801\uff0c\u90a3\u4f60\u4e00\u5b9a\u8981\u6765\u770b\u770b](https://juejin.cn/post/7046720828901163016)\\n- \u2b50\ufe0f [Git\u4e0d\u8981\u53ea\u4f1apull\u548cpush\uff0c\u8bd5\u8bd5\u8fd95\u6761\u63d0\u9ad8\u6548\u7387\u7684\u547d\u4ee4](https://juejin.cn/post/7071780876501123085)\\n- [\u5229\u7528\u597d git bisect \u8fd9\u628a\u5229\u5668\uff0c\u5e2e\u52a9\u4f60\u5feb\u901f\u5b9a\u4f4d\u7591\u96be bug](https://juejin.cn/post/7046409685561245733)\\n- \u2b50\ufe0f [\u524d\u7aef\u67b6\u6784\u5e08\u7684 git \u529f\u529b\uff0c\u4f60\u6709\u51e0\u6210\u706b\u5019\uff1f](https://juejin.cn/post/7024043015794589727)\\n- \u2b50\ufe0f [\u4e24\u6761\u547d\u4ee4\u8ba9\u4f60\u7684git\u81ea\u52a8\u53d8\u57fa](https://segmentfault.com/a/1190000040712052)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u591a\u5e74 Git \u4f7f\u7528\u5fc3\u5f97 & \u5e38\u89c1\u95ee\u9898\u6574\u7406](https://juejin.cn/post/6844904191203213326)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 git \u7684](https://juejin.cn/post/6974184935804534815)\\n- \ud83c\udf1b [\u4e3a\u4ec0\u4e48 husky \u653e\u5f03\u4e86\u4f20\u7edf\u7684 JS \u914d\u7f6e](https://juejin.cn/post/7000186205224566791)\\n- \u2b50\ufe0f [\u4f60\u53ef\u80fd\u5df2\u7ecf\u5ffd\u7565\u7684git commit\u89c4\u8303](https://juejin.cn/post/6844904036068491278)\\n- [gitmoji: An emoji guide for your commit messages](https://gitmoji.dev/)\\n\\n## \u6e90\u7801\u7cfb\u5217\\n\\n- \u2b50\ufe0f [[\u5efa\u8bae\u6536\u85cf] \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709](https://juejin.cn/post/6982004709145968677)\\n- \u2b50\ufe0f [\u516d\u5343\u5b57\u8be6\u89e3\uff01vue3 \u54cd\u5e94\u5f0f\u662f\u5982\u4f55\u5b9e\u73b0\u7684\uff1f](https://juejin.cn/post/7048970987500470279)\\n- \u2b50\ufe0f \u2b50\ufe0f [Redux\u901a\u5173\u7b80\u6d01\u653b\u7565 -- \u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01](https://juejin.cn/post/7019185205336342542)\\n- \u2b50\ufe0f [\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React](https://juejin.cn/post/6978654109893132318)\\n- \u2b50\ufe0f [React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb](https://juejin.cn/post/7010539227284766751)\\n- \u2b50\ufe0f [\u5e26\u4f60\u5feb\u901f\u624b\u5199\u4e00\u4e2a\u7b80\u6613\u7248vue\u4e86\u89e3vue\u54cd\u5e94\u5f0f](https://juejin.cn/post/6990974525273800712)\\n- [Vue3.2 vDOM diff\u6d41\u7a0b\u5206\u6790\u4e4b\u4e00\uff1adiff\u7b97\u6cd5](https://juejin.cn/post/7072321805792313357)\\n- [2021\u5e74\uff0c\u8ba9\u6211\u4eec\u624b\u5199\u4e00\u4e2amini\u7248\u672c\u7684vue2.x\u548cvue3.x\u6846\u67b6](https://juejin.cn/post/6977363265965785102)\\n- [Vue(v2.6.11)\u4e07\u884c\u6e90\u7801\u751f\u5543\uff0c\u5c31\u786c\u521a\uff01](https://juejin.cn/post/6846687602679119885)\\n- [\u5c24\u96e8\u6eaa\u56fd\u5916\u6559\u7a0b\uff1a\u4eb2\u624b\u5e26\u4f60\u5199\u4e2a\u7b80\u6613\u7248\u7684Vue\uff01](https://juejin.cn/post/6992018709439053837)\\n- [Vue 3 Workshop Code Samples](https://codepen.io/collection/DkxpbE?cursor=ZD0wJm89MCZwPTEmdj00)\\n- \u2b50\ufe0f [diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f](https://juejin.cn/post/6997965021401579556)\\n- \u2b50\ufe0f [Vue 3.2 \u53d1\u5e03\u4e86\uff0c\u90a3\u5c24\u96e8\u6eaa\u662f\u600e\u4e48\u53d1\u5e03 Vue.js \u7684\uff1f](https://juejin.cn/post/6997943192851054606)\\n- \u2b50\ufe0f [\u521d\u5b66\u8005\u4e5f\u80fd\u770b\u61c2\u7684 Vue3 \u6e90\u7801\u4e2d\u90a3\u4e9b\u5b9e\u7528\u7684\u57fa\u7840\u5de5\u5177\u51fd\u6570](https://juejin.cn/post/6994976281053888519)\\n\\n## Webpack \u7cfb\u5217\\n\\n- [Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790](https://juejin.cn/post/6937125495439900685)\\n - \u901a\u8fc7\u7f16\u5199\u4e00\u4e2a plugin\uff0c\u5728\u9884\u5904\u7406\u9636\u6bb5\u901a\u8fc7\u63d2\u4ef6 apply \u51fd\u6570\u52a8\u6001\u4fee\u6539 webpack \u914d\u7f6e\uff0c\u6ce8\u5165 vue-loader \u4e13\u7528\u7684 rules\\n- \u2b50\ufe0f [\u8d85\u786c\u6838\uff5c\u5e26\u4f60\u7545\u6e38\u5728 Webpack \u63d2\u4ef6\u5f00\u53d1\u8005\u7684\u4e16\u754c](https://juejin.cn/post/7047777251949019173)\\n- \u2b50\ufe0f [\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684](https://juejin.cn/post/7170852747749621791)\\n- \u2b50\ufe0f [\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801](https://juejin.cn/post/7164175171358556173)\\n- [Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566](https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g)\\n- [\u4f60\u7684Tree-Shaking\u5e76\u6ca1\u4ec0\u4e48\u5375\u7528](https://zhuanlan.zhihu.com/p/32831172)\\n- [\u624b\u6478\u624b Webpack \u591a\u5165\u53e3\u914d\u7f6e\u5b9e\u8df5](https://juejin.cn/post/6844903939289120782)\\n- \u2b50\ufe0f [Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790](https://juejin.cn/post/7031546400034947108)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb](https://juejin.cn/post/7023242274876162084)\\n- \u2b50\ufe0f [Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790](https://juejin.cn/post/7021729340945596424)\\n- [Webpack5 \u5b9e\u8df5 - \u6784\u5efa\u6548\u7387\u500d\u901f\u63d0\u5347\uff01](https://mp.weixin.qq.com/s/gwHwVxA4zh59SBvq-onM-g)\\n- \ud83c\udf1b [Webpack \u6027\u80fd\u7cfb\u5217\u4e00: \u4f7f\u7528 Cache \u63d0\u5347\u6784\u5efa\u6027\u80fd](https://mp.weixin.qq.com/s/mpF6W-4dElu0UPed03oJQw)\\n- \ud83c\udf1b [\u6211\u662f\u5982\u4f55\u5c06\u7f51\u9875\u6027\u80fd\u63d0\u53475\u500d\u7684 \u2014 \u6784\u5efa\u4f18\u5316\u7bc7](https://juejin.cn/post/6910893471339708429)\\n- \u2b50\ufe0f [Webpack\u914d\u7f6e\u5168\u89e3\u6790\uff08\u4f18\u5316\u7bc7\uff09](https://juejin.cn/post/6858905382861946894)\\n- \u2b50\ufe0f [\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0a\u7bc7](https://juejin.cn/post/7144934998884220958)\\n- \u2b50\ufe0f [\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0b\u7bc7](https://juejin.cn/post/7145025071432597541)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57](https://juejin.cn/post/6996816316875161637)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u5b9e\u8df5\u7bc7\uff09](https://juejin.cn/post/6991774994552324133)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u57fa\u7840\u7bc7\uff09](https://juejin.cn/post/6991630925792542750)\\n- \u2b50\ufe0f [\u624b\u628a\u624b\u5e26\u4f60\u5165\u95e8 Webpack4](https://juejin.cn/post/6844903912588181511)\\n- \u2b50\ufe0f \u2b50\ufe0f [\\\\[\u4e07\u5b57\u603b\u7ed3\\\\] \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406](https://juejin.cn/post/6949040393165996040)\\n\\n## Vite \u7cfb\u5217\\n\\n- [\u5b66\u4f1a\u8fd9 20 \u4e2a\u5e93\uff0c\u8ba9\u4f60\u5feb\u901f\u770b\u61c2 vue3 \u548c vite3 \u6e90\u7801 \ud83d\ude80](https://juejin.cn/post/7124112069355372581)\\n- [\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417](https://juejin.cn/post/7094984070999834655)\\n- [\u524d\u7aef\u5386\u53f2\u9879\u76ee\u7684 Vite \u8fc1\u79fb\u5b9e\u8df5\u603b\u7ed3](https://juejin.cn/post/6986533364438138894)\\n- [\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite 2.x \u6e90\u7801\u7ea7\u5206\u6790](https://juejin.cn/post/6979932627465666568)\\n- [\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite \u26a1\ufe0f\u539f\u7406\u5206\u6790](https://juejin.cn/post/6956564266812571656)\\n\\n## PNPM && Monorepo\\n\\n- \u2b50\ufe0f [\u8bfe\u4ee3\u8868\uff1aTurborepo \u7b14\u8bb0](https://mp.weixin.qq.com/s/beLkwHan2C8BuSArs53cIA)\\n- \u2b50\ufe0f [lerna + dumi + eslint\u591a\u5305\u7ba1\u7406\u5b9e\u8df5](https://juejin.cn/post/7015566240991150117)\\n- \u2b50\ufe0f [\u7ec4\u4ef6\u5e93Monmrepo\u67b6\u6784\u4e0e\u5f00\u53d1\u8c03\u8bd5\u73af\u5883\u6784\u5efa](https://mp.weixin.qq.com/s/z-tKxgRPmdyR0zwc78Khgw)\\n- [React Native\u5de5\u7a0bMonorepo\u6539\u9020\u5b9e\u8df5](https://juejin.cn/post/7177585131861835837)\\n- [\u3010\u7b2c2714\u671f\u3011\u4eceMultirepo\u5230Monorepo \u888b\u9f20\u4e91\u6570\u6808\u524d\u7aef\u7814\u53d1\u6548\u7387\u63d0\u5347\u63a2\u7d22\u4e4b\u8def](https://mp.weixin.qq.com/s/JWks8VyuXoB5zaeYdyJPxw)\\n- [Monorepo\uff0c\u5927\u578b\u524d\u7aef\u9879\u76ee\u7ba1\u7406\u6a21\u5f0f\u5b9e\u8df5](https://mp.weixin.qq.com/s/N0CZABDD0TKTmdljH3y74A)\\n- [\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417](https://juejin.cn/post/7094984070999834655)\\n- [\u590d\u6d3b\u4e86\uff01 Lerna V6 \u5e26\u6765\u4e86\u54ea\u4e9b\u65b0\u4e1c\u897f](https://mp.weixin.qq.com/s/6peafvVjmcF65PFSggSLYQ)\\n- [pnpm + workspace + changesets \u6784\u5efa\u4f60\u7684 monorepo \u5de5\u7a0b](https://juejin.cn/post/7098609682519949325)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u6838\u5fc3\u6280\u672f\u63ed\u79d8\uff1a5. \u4ece\u7ec8\u7aef\u547d\u4ee4\u89e3\u6790\u5668\u8bf4\u8d77\u8c08\u8c08 npm \u5305\u7ba1\u7406\u5de5\u5177\u7684\u8fd0\u884c\u539f\u7406](https://juejin.cn/post/7161063570594070559)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a4. ESLint \u6280\u672f\u539f\u7406\u4e0e\u5b9e\u6218\u53ca\u4ee3\u7801\u89c4\u8303\u81ea\u52a8\u5316\u8be6\u89e3](https://juejin.cn/post/7157743898939359262)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa](https://juejin.cn/post/7146183222425518093)\\n- [\ud83d\ude80Turborepo\uff1a\u53d1\u5e03\u5f53\u6708\u5c31\u6fc0\u589e 3.8k Star\uff0c\u8fd9\u6b3e\u8d85\u795e\u7684\u65b0\u5174 Monorepo \u65b9\u6848\uff0c\u4f60\u4e0d\u6253\u7b97\u5c1d\u8bd5\u4e0b\u5417](https://juejin.cn/post/7129267782515949575)\\n- [\u6700\u8be6\u7ec6\u7684 lerna \u4e2d\u6587\u624b\u518c](https://juejin.cn/post/7136925215388499998)\\n- [Monorepo Handbook \u65b0\u9c9c\u51fa\u7089](https://turborepo.org/docs/handbook/what-is-a-monorepo)\\n- [\u73b0\u4ee3 Monorepo \u5de5\u7a0b\u6280\u672f\u9009\u578b\uff0c\u804a\u804a\u6211\u7684\u601d\u8003](https://mp.weixin.qq.com/s/99nozy-vtFMGcBTxYvumWA)\\n- [\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf](https://juejin.cn/post/7092766235380678687)\\n- [\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2](https://zhuanlan.zhihu.com/p/455809528)\\n- [pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA)\\n- [\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09](https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw)\\n- [\u524d\u7aef\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u8fdb\u5316\u53f2](https://juejin.cn/post/7083414641610588168)\\n- [\u90fd2022\u5e74\u4e86\uff0cpnpm\u5feb\u5230\u7897\u91cc\u6765\uff01](https://juejin.cn/post/7053340250210795557)\\n- [\u5173\u4e8e\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u6df1\u5ea6\u601d\u8003\u2014\u2014\u4e3a\u4ec0\u4e48\u73b0\u5728\u6211\u66f4\u63a8\u8350 pnpm \u800c\u4e0d\u662f npm/yarn?](https://juejin.cn/post/6932046455733485575)\\n- [\u5e74\u7ec8\u76d8\u70b9\uff1a2022\u57fa\u4e8eMonorepo\u7684\u9996\u4e2a\u5927\u8d8b\u52bf-TurboRepo](https://juejin.cn/post/7051929587852247077)\\n- [\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406](https://juejin.cn/post/7030207667457130527)\\n- [One For All\uff1a\u57fa\u4e8epnpm + lerna + typescript\u7684\u6700\u4f73\u9879\u76ee\u5b9e\u8df5 - \u7406\u8bba\u7bc7](https://juejin.cn/post/7043998041786810398)\\n- [\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020](https://juejin.cn/post/7029262501833359368)\\n- [Monorepo \u7684\u8fd9\u4e9b\u5751\uff0c\u6211\u4eec\u5e2e\u4f60\u8e29\u8fc7\u4e86\uff01](https://juejin.cn/post/6972139870231724045)\\n- [\u5f00\u6e90\u9879\u76ee\u90fd\u5728\u7528 monorepo\uff0c\u4f46\u662f\u4f60\u77e5\u9053\u5c45\u7136\u6709\u90a3\u4e48\u591a\u5751\u4e48\uff1f](https://juejin.cn/post/6950082433647640612)\\n- [All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6924854598268108807)\\n\\n## Rollup \u7cfb\u5217\\n\\n- \u2b50\ufe0f [\u3010\u5b9e\u6218\u7bc7\u3011\u6700\u8be6\u7ec6\u7684Rollup\u6253\u5305\u9879\u76ee\u6559\u7a0b](https://juejin.cn/post/7145090564801691684)\\n- \u2b50\ufe0f [\u4ece0\u52301\u5f00\u53d1\u4e00\u4e2aReact\u7ec4\u4ef6\u5e93](https://juejin.cn/post/7144365208646418462)\\n- \u2b50\ufe0f [\u57fa\u4e8estorybook\u7ec4\u4ef6\u5e93\u7684\u6280\u672f\u9009\u578b\u8be5\u600e\u4e48\u9009](https://mp.weixin.qq.com/s/xjY0d8eNTmAuCZKxKQeu7g)\\n- \u2b50\ufe0f [\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e](https://juejin.cn/post/7151653067593613320)\\n- \u2b50\ufe0f [\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305](https://juejin.cn/post/7126394898445500423)\\n- \u2b50\ufe0f [\u524d\u7aef\u5de5\u7a0b\u5316\u57fa\u5efa\u63a2\u7d22\uff1a\u4ece\u5185\u90e8\u673a\u5236\u548c\u6838\u5fc3\u539f\u7406\u4e86\u89e3npm](https://mp.weixin.qq.com/s/mL1pv2kPKvtaHalr7PXKow)\\n- [\u4e00\u6587\u5165\u95e8rollup\ud83e\ude80\uff0113\u7ec4demo\u5e26\u4f60\u8f7b\u677e\u9a7e\u9a6d](https://juejin.cn/post/7069555431303020580)\\n- [\u8bf4\u4e0d\u6e05rollup\u80fd\u8f93\u51fa\u54ea6\u79cd\u683c\u5f0f\ud83d\ude25\u5dee\u70b9\u88ab\u9119\u89c6](https://juejin.cn/post/7051236803344334862)\\n- [\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305](https://juejin.cn/post/7052307032971411463)\\n- [\u524d\u7aef\u7ec4\u4ef6/\u5e93\u6253\u5305\u5229\u5668rollup\u4f7f\u7528\u4e0e\u914d\u7f6e\u5b9e\u6218](https://juejin.cn/post/6844903970469576718)\\n- [\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup](https://juejin.cn/post/6869551115420041229)\\n\\n## \u5fae\u524d\u7aef && \u6a21\u5757\u8054\u90a6\\n\\n- \ud83c\udf1f [Module Federation\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/pT_tugg_EvE5pnMCaUqliw)\\n- \ud83c\udf1f [\u6a21\u5757\u8054\u90a6\u5728\u5fae\u524d\u7aef\u67b6\u6784\u4e2d\u7684\u5b9e\u8df5](https://mp.weixin.qq.com/s/WXeUuUdgF_3djqBhh1siQA)\\n- \ud83c\udf1f [\u57fa\u4e8e MF \u7684\u7ec4\u4ef6\u5316\u5171\u4eab\u5de5\u4f5c\u6d41](https://mp.weixin.qq.com/s/u5oAcIYiGrl1qOujOYjzqw)\\n- \u2b50\ufe0f [\u804a\u4e00\u804a\u5173\u4e8e\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b](https://mp.weixin.qq.com/s/l_KKNRUyJANN6wkoC2TlVQ)\\n- \u2b50\ufe0f [\u8d85\u5927\u4f53\u91cf\u9879\u76ee\uff0c\u5fae\u524d\u7aef\u843d\u5730\u65b9\u6848\uff0c\u770b\u5b8c\u540e\u6094\u6765\u627e\u6211](https://juejin.cn/post/7121244973558661150)\\n- \u2b50\ufe0f [\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22](https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA)\\n- \u2b50\ufe0f [\u3010\u7b2c1912\u671f\u3011\u63a2\u7d22 webpack5 \u65b0\u7279\u6027Module federation\u5728\u817e\u8baf\u6587\u6863\u7684\u5e94\u7528](https://mp.weixin.qq.com/s/iS-prT1xZPV6cpH7MHRRdQ)\\n- \u2b50\ufe0f [\u3010\u7b2c1901\u671f\u3011Webpack 5 Module Federation: JavaScript \u67b6\u6784\u7684\u53d8\u9769\u8005](https://mp.weixin.qq.com/s/PFKxQgZPER_XHUSbk_SQJA)\\n- [\u5168\u9762\u654f\u6377\u6a21\u5f0f\u4e0b\u7684\u5fae\u524d\u7aef\u65b9\u6848](https://mp.weixin.qq.com/s/vy84FY3P6KPeWzDaNl6Ntg)\\n- [\u5fae\u524d\u7aef\u573a\u666f\u4e0b\u7684\u4ee3\u7801\u5171\u4eab](https://mp.weixin.qq.com/s/mvdOU8uVG9NjGPzInpPxJA)\\n- [\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c](https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg)\\n- [\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b](https://mp.weixin.qq.com/s/ylkY9HWTQKPlbDb2M33YWQ)\\n- [\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684](https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g)\\n- [\u6a21\u5757\u8054\u90a6\u6d45\u6790](https://juejin.cn/post/7101457212085633054)\\n- [\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb](https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g)\\n- [\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation](https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww)\\n\\n## VS Code \u63d2\u4ef6\\n\\n- [vscode\u63d2\u4ef6\u539f\u7406\u6d45\u6790\u4e0e\u5b9e\u6218](https://mp.weixin.qq.com/s/4MmBSD-d-9T5-kFhcWNlTA)\\n- [vscode-extension-samples](https://github.com/microsoft/vscode-extension-samples)\\n- [\u5f00\u53d1\u4e00\u6b3e\u4e13\u5c5e\u7684 VSCode \u4ee3\u7801\u63d0\u793a\u63d2\u4ef6](https://mp.weixin.qq.com/s/e2gfSnBrR6rn7x37ZGLplg)\\n\\n## \u524d\u7aef\u5de5\u7a0b\u5316\\n\\n- \u2b50\ufe0f [\u6765\u81ea\u672a\u6765\uff0c2022 \u5e74\u7684\u524d\u7aef\u4eba\u90fd\u5728\u505a\u4ec0\u4e48?](https://juejin.cn/post/7062617190981173278)\\n- [\u4e3a\u4ec0\u4e48\u8bf4 WebAssembly \u662f Web \u7684\u672a\u6765\uff1f](https://juejin.cn/post/7056612950412361741)\\n- [easy-serverless \u529f\u80fd\u5206\u6790](https://juejin.cn/post/7057114641507287048)\\n- [2022 \u5e74 JavaScript \u5f00\u53d1\u5de5\u5177\u7684\u751f\u6001](https://mp.weixin.qq.com/s/ckskF06PD43KHpKAGaYmRA)\\n- [\u8d85\u5168\u9762\u7684\u524d\u7aef\u65b0\u4e00\u4ee3\u6784\u5efa\u5de5\u5177\u5bf9\u6bd4: esbuild\u3001Snowpack\u3001Vite\u3001wmr](https://mp.weixin.qq.com/s/JZbsIqsqNeJmc__QFKpo1Q)\\n- [esno\uff0c\u57fa\u4e8e Esbuild \u7684\u795e\u5668](https://mp.weixin.qq.com/s/3aVYGfahv5rZJbWBhaI3BA)\\n- \u2b50\ufe0f [Deno \u7b80\u4ecb\uff1a\u5b83\u6bd4 Node.js \u66f4\u597d\u5417\uff1f](https://mp.weixin.qq.com/s/qnA1tFKMXr7hwsEKFXKOZg)\\n- \u2b50\ufe0f [\u57fa\u4e8e Next.js \u7684 SSR/SSG \u65b9\u6848\u4e86\u89e3\u4e00\u4e0b\uff1f](https://juejin.cn/post/7046204235226021901)\\n- \ud83c\udf1b [\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684](https://juejin.cn/post/7085257325165936648)\\n- \ud83c\udf1b [\u524d\u7aef\u67b6\u6784\u5e08\u795e\u6280\uff0c\u4e09\u62db\u7edf\u4e00\u56e2\u961f\u4ee3\u7801\u98ce\u683c](https://juejin.cn/post/7029512357428592648)\\n- \ud83c\udf1b [\u624b\u628a\u624b\u6559\u4f60\u642d\u5efa\u4e00\u4e2a\u7070\u5ea6\u53d1\u5e03\u73af\u5883](https://juejin.cn/post/6844904110601273357)\\n- \u2b50\ufe0f [ES6 \u4ee5\u4e0a\u7248\u672c\u4ee3\u7801\u8981\u4e0d\u8981\u8f6c\u7801\u6210 ES5 ?](https://juejin.cn/post/7049696761858195486)\\n- \u2b50\ufe0f [ESM \u4e0e CJS \u7684 Interop \u6765\u4e16\u4eca\u751f](https://mp.weixin.qq.com/s/3TKcUeoyzXvH3MGVI6Dj9A)\\n- \u2b50\ufe0f [2022 \u524d\u7aef\u6280\u672f\u9886\u57df\u4f1a\u6709\u54ea\u4e9b\u65b0\u7684\u53d8\u5316\uff1f](https://www.zhihu.com/question/493891614/answer/2269197391)\\n- \ud83c\udf1b [\u524d\u7aef\u6784\u5efa\u8fd9\u5341\u5e74](https://segmentfault.com/a/1190000040496020)\\n\\n## \u8f6f\u4ef6\u67b6\u6784 && \u8bbe\u8ba1\u6a21\u5f0f\\n\\n- \u2b50\ufe0f Software Engineering at Google\\n - \u5728\u7ebf\u9605\u8bfb\uff1ahttps://abseil.io/blog/04222021-swe-book\\n - PDF \u4e0b\u8f7d\uff1ahttps://github.com/garfield-dev-team/Frontend-Training-Program/blob/main/OReilly.Software.Engineering.at.Google.2020.3.pdf\\n- [The Ultimate Guide To Software Engineering](https://dev.to/wiseai/the-ultimate-guide-to-software-engineering-545e)\\n- \u2b50\ufe0f [\u8bed\u96c0\u684c\u9762\u7aef\u6280\u672f\u67b6\u6784\u5b9e\u8df5](https://juejin.cn/post/7145014659584622629)\\n- \u2b50\ufe0f [\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01](https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg)\\n- [\u63a2\u79d8\u5fae\u4fe1\u4e1a\u52a1\u4f18\u5316\uff1aDDD\u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://mp.weixin.qq.com/s/kFjfzwTOdaKA2ym63VR3DQ)\\n- [\u4e86\u89e3\u5fae\u524d\u7aef\uff0c\u6df1\u5165\u524d\u7aef\u67b6\u6784\u7684\u524d\u4e16\u4eca\u751f](https://mp.weixin.qq.com/s/12BS4V6fvXkeb84XDpPnHw)\\n- \u2b50\ufe0f [\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg)\\n- \u2b50\ufe0f [\u5de5\u4f5c\u4e2d\u5e38\u89c1\u7684 6 \u79cd\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f60\u7528\u8fc7\u51e0\u79cd](https://mp.weixin.qq.com/s/ocPx6Sw09ioDyz_IOWK69Q)\\n- \u2b50\ufe0f [\u3010\u7b2c2757\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u768423\u4e2a\u57fa\u672c\u539f\u5219](https://mp.weixin.qq.com/s/3MwRLM0jDmwv5l6gamFjcw)\\n- \u2b50\ufe0f [\u3010\u7b2c2677\u671f\u3011\u5982\u4f55\u5728React\u4e2d\u5e94\u7528SOLID\u539f\u5219](https://mp.weixin.qq.com/s/iB23DV4hovPDdf5_4TCaOA)\\n- [\u3010\u7b2c2703\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u624b\u518c](https://mp.weixin.qq.com/s/1h6yqCWyzYLM8WPGlGdtVA)\\n- [\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw)\\n- [\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ)\\n- [\u6df1\u5165\u6d45\u51fa\u524d\u7aef\u505a\u63a7\u5236\u53cd\u8f6c\u4e0e\u4f9d\u8d56\u6ce8\u5165](https://www.yuque.com/surfacew/fe/qg0uev)\\n- [javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw)\\n- [\u5b9e\u6218\uff01\u5982\u4f55\u4ece\u96f6\u642d\u5efa10\u4e07\u7ea7 QPS \u5927\u6d41\u91cf\u3001\u9ad8\u5e76\u53d1\u4f18\u60e0\u5238\u7cfb\u7edf](https://mp.weixin.qq.com/s/iZ9BX6cCCp_TB-SC3knuew)\\n- \u2b50\ufe0f [\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1](https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg)\\n- \u2b50\ufe0f [\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1\u56db\u8bba](https://mp.weixin.qq.com/s/SMAycMJPWr018sU04kbfbQ)\\n- \u2b50\ufe0f [\u4e07\u5b57\u957f\u6587\u52a9\u4f60\u4e0a\u624b\u8f6f\u4ef6\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1 DDD](https://mp.weixin.qq.com/s/BIYp9DNd_9sw5O2daiHmlA)\\n- \ud83c\udf1b [\u7528DDD(\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1)\u548cADT(\u4ee3\u6570\u6570\u636e\u7c7b\u578b)\u63d0\u5347\u4ee3\u7801\u8d28\u91cf](https://mp.weixin.qq.com/s/QCIlheiEgmU4Qi-4b_XoqQ)\\n- \ud83c\udf1b [\u540e\u53f0\u670d\u52a1\u67b6\u6784\u9ad8\u6027\u80fd\u8bbe\u8ba1\u4e4b\u9053](https://mp.weixin.qq.com/s/hsH7LMBEDGe_df9UbfOvbQ)\\n- [\u6211\u505a\u7cfb\u7edf\u67b6\u6784\u7684\u4e00\u4e9b\u539f\u5219](https://coolshell.cn/articles/21672.html)\\n- [\u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\u4e2d\u5982\u4f55\u505a\u597d\u6280\u672f\u51b3\u7b56\uff1f](https://mp.weixin.qq.com/s/m1Dv-YG60AKArGu-URr88w)\\n- [\u524d\u7aef\u9886\u57df\u7684 \u201c\u5e72\u51c0\u67b6\u6784\u201d](https://mp.weixin.qq.com/s/4bB_B5JTOrev8mqfG7K2cw)\\n- [\u53ea\u4f1a\u7528\u4f20\u7edf\u5f00\u53d1\u6a21\u5f0f\uff1f10\u5206\u949f\u6559\u4f60\u73a9\u8f6c\u654f\u6377\uff01](https://mp.weixin.qq.com/s/g9F05SRnQBTzzfx_2CKqhg)\\n\\n## \u6301\u7eed\u96c6\u6210\\n\\n- \u2b50\ufe0f [\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg)\\n- [\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357](https://zhuanlan.zhihu.com/p/445217118)\\n- [GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/7064906701941506061)\\n- [Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers](https://www.youtube.com/watch?v=fqMOX6JJhGo)\\n- \u2b50\ufe0f [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)\\n- \u2b50\ufe0f [Dockerfile reference](https://docs.docker.com/engine/reference/builder/)\\n- [\u5982\u4f55\u4f7f\u7528 docker \u90e8\u7f72\u524d\u7aef\u5e94\u7528](https://juejin.cn/post/6844903793348329486)\\n- [docker \u7b80\u6613\u5165\u95e8 - shanyue](https://shanyue.tech/op/docker.html)\\n- [\u5c0f\u9cb8\u9c7c\u7684\u524d\u4e16\u4eca\u751f--Docker](https://mp.weixin.qq.com/s/4aFJ7t37IwEMyq-u09Wf1g)\\n- [\u5f00\u53d1\u8005\u5fc5\u5907\u7684 Docker \u5b9e\u8df5\u6307\u5357](https://juejin.cn/book/6844733746462064654/section/6844733746504007693)\\n- [\u8c01\u8bf4\u524d\u7aef\u4e0d\u9700\u8981\u5b66\u4e60docker\uff1f](https://mp.weixin.qq.com/s/U-zK6JEMpmK2Il68-ijcaw)\\n- [\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a](https://juejin.cn/post/7028222480326066213)\\n- [\u524d\u7aef\u5f00\u53d1\u8005\u5e94\u8be5\u77e5\u9053\u7684 Centos/Docker/Nginx/Node/Jenkins \u64cd\u4f5c(\ud83c\udf61 \u957f\u6587)](https://juejin.cn/post/6951684431597797389)\\n- [\u4fdd\u59c6\u7ea7\u6307\u5357\uff1ajekins+docker\u6784\u5efa\u90e8\u7f72react\u9879\u76ee\u5b9e\u6218](https://juejin.cn/post/7049920990351982628)\\n- [\u4f60\u7684\u7b2c\u4e00\u4e2a Docker + React + Express \u5168\u6808\u5e94\u7528](https://juejin.cn/post/6993951401952935972)\\n\\n## \u670d\u52a1\u7aef\u76f8\u5173\\n\\n- \u63a8\u8350\u7b97\u6cd5\\n - [\u56fe\u6587\u89e3\u8bfb\uff1a\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7cbe\u6392\uff01](https://mp.weixin.qq.com/s/GetU-ULhfvY8ri47Ht28GQ)\\n - [\u8d85\u5f3a\u6307\u5357\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u91cd\u6392](https://mp.weixin.qq.com/s/wXb5uQJBCzSEq6IITP7VCQ)\\n - [\u8be6\u7ec6\u89e3\u8bfb\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u53ec\u56de](https://mp.weixin.qq.com/s/1wOnG4dtNSI-x2x15-AjTQ)\\n - [\u56fe\u6587\u5e76\u8302\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7c97\u6392](https://mp.weixin.qq.com/s/YsK_8yyBNL5z269qT5CrIw)\\n - [\u8be6\u89e3\u95f2\u9c7c\u63a8\u8350\u7cfb\u7edf\uff08\u957f\u6587\u6536\u85cf\uff09](https://juejin.cn/post/7153878508035391502)\\n- Redis \u76f8\u5173\\n - \u2b50\ufe0f \u2b50\ufe0f [Redis\u8be6\u7ec6\u5165\u95e8\u6559\u7a0b](https://zhuanlan.zhihu.com/p/469102289)\\n - \u2b50\ufe0f [Redis \u53ea\u4f1a\u7528\u7f13\u5b58\uff1f16\u79cd\u5999\u7528\u8ba9\u540c\u4e8b\u76f4\u547c\u725bX](https://mp.weixin.qq.com/s/fnOvw4JfwszNGVBMW0N2hw)\\n - \u2b50\ufe0f [\u6df1\u5165\u6d45\u51fa\u5e26\u4f60\u8d70\u8fdbRedis\uff01](https://mp.weixin.qq.com/s/ThVtw8TVuhxIyYxJy6sOWw)\\n - \u2b50\ufe0f [\u4e07\u5b57\u56fe\u6587\u8bb2\u900f\u6570\u636e\u5e93\u7f13\u5b58\u4e00\u81f4\u6027\u95ee\u9898](https://mp.weixin.qq.com/s/U87wrGsx0Eop3CbF9mlTwQ)\\n - \u2b50\ufe0f [Redis \u4e8b\u52a1\u9047\u4e0a @Transactional \u6709\u5927\u5751\uff01\uff01\u8bb0\u4e00\u6b21 Redis \u751f\u4ea7\u4e8b\u6545](https://mp.weixin.qq.com/s/vwx99ER-9qiH9nfwtFW1zQ)\\n - \u2b50\ufe0f [Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848](https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw)\\n - \ud83c\udf1b [Redis \u6301\u4e45\u5316\u7b56\u7565\u6d45\u6790](https://juejin.cn/post/7147602740405862407)\\n - \ud83c\udf1b [\u56fe\u6587\u7ed3\u5408\uff01Redis\u5ef6\u8fdf\u961f\u5217golang\u9ad8\u6548\u5b9e\u8df5](https://mp.weixin.qq.com/s/dCZm7e0aSEirhEqiCBvAyQ)\\n - \u2b50\ufe0f [\u7528 Redis \u90fd\u80fd\u5b9e\u73b0\u54ea\u4e9b\u529f\u80fd\uff1f\u8fd92\u4e07\u5b57+20\u5f20\u56fe\u7ed9\u5206\u6790\u5168\u4e86](https://mp.weixin.qq.com/s/frOhO8rj2Xvdix6tnjTOrw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u8bc1\u6570\u636e\u5e93\u548c\u7f13\u5b58\u53cc\u5199\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/mO819q_r9qLVuRBE8cjx1Q)\\n - \u2b50\ufe0f [\u4e3a\u4e86\u62ff\u634f Redis \u6570\u636e\u7ed3\u6784\uff0c\u6211\u753b\u4e86 40 \u5f20\u56fe\uff08\u5b8c\u6574\u7248\uff09](https://mp.weixin.qq.com/s/Cq-CF1BC4PWwGnlRp4HrnQ)\\n - \u2b50\ufe0f [Redis 5 \u79cd\u57fa\u672c\u6570\u636e\u7ed3\u6784\uff08String\u3001List\u3001Hash\u3001Set\u3001Sorted Set\uff09\u8be6\u89e3 | JavaGuide](https://juejin.cn/post/7124572920403197965)\\n- Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\\n - [Redis\u5206\u5e03\u5f0f\u9501\u768410\u4e2a\u5751](https://mp.weixin.qq.com/s/2Rwy19C0eUshTWc_JfTPig)\\n - [\u6df1\u5165\u7406\u89e3 go singleflight](https://mp.weixin.qq.com/s/p2rlkCRRj7h7-aojTidQbg)\\n - [\u9762\u8bd5\u5b98\uff1a\u5982\u4f55\u7528 Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/ESdfA5sJa6bmL-HvuWpoJA)\\n - [\u5982\u4f55\u7528Redis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/RS1kKvF_Ly576GV52bHQPg)\\n - [Go\uff1a\u5206\u5e03\u5f0f\u9501\u5b9e\u73b0\u539f\u7406\u4e0e\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/lrSQBK-Kihkj6994kQFpUQ)\\n- Web Server\\n - \u2b50\ufe0f [\u8d85\u8d8a Nginx\uff01\u53f7\u79f0\u4e0b\u4e00\u4ee3 Web \u670d\u52a1\u5668\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://juejin.cn/post/7085519712901136392)\\n- IO\u591a\u8def\u590d\u7528\\n - \u2b50\ufe0f [\u4eceLinux\u96f6\u62f7\u8d1d\u6df1\u5165\u4e86\u89e3Linux-I/O](https://mp.weixin.qq.com/s/j1KjR5bRQV6oGrU5tsyHgg)\\n - \u2b50\ufe0f [\u6df1\u5165\u5b66\u4e60IO\u591a\u8def\u590d\u7528 select/poll/epoll \u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/5xj42JPKG8o5T7hjXIKywg)\\n - \u2b50\ufe0f [\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3](https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg)\\n - \u2b50\ufe0f [\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3](https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g)\\n- \u7cfb\u7edf\u8bbe\u8ba1\\n - \u2b50\ufe0f [\u6280\u672f\u603b\u76d1\u5206\u4eab\u7684\u7cfb\u7edf\u8bbe\u8ba1\u6280\u5de7\uff0c\u4e07\u80fd\u901a\u7528\uff0c\u7a33\u7684\u4e00\u6279\uff01](https://mp.weixin.qq.com/s/FJi3ko9wjTBNWS79RVQf5A)\\n - \u2b50\ufe0f [\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1\u768415\u4e2a\u9526\u56ca](https://mp.weixin.qq.com/s/PPA8Iw6K2M2xVnGE-Tf6zw)\\n - \u2b50\ufe0f [\u652f\u4ed8\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01](https://mp.weixin.qq.com/s/5Jj-IClPhInXz7xsfUZEnQ)\\n - \u2b50\ufe0f [\u8682\u8681\u91d1\u670d\u4e00\u9762\uff1a\u5341\u9053\u7ecf\u5178\u9762\u8bd5\u9898\u89e3\u6790](https://mp.weixin.qq.com/s/qhsVURhXm0Ot-jWq0khfEg)\\n - \u2b50\ufe0f [\u516c\u53f8\u65b0\u6765\u4e00\u4e2a\u540c\u4e8b\uff0c\u628a\u4f18\u60e0\u5238\u7cfb\u7edf\u8bbe\u8ba1\u7684\u7089\u706b\u7eaf\u9752\uff01](https://mp.weixin.qq.com/s/Ebh5iVsx0iExb5Wxq3tQFQ)\\n - \u2b50\ufe0f [\u7f51\u5173\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01](https://mp.weixin.qq.com/s/8GXe6sKPKk7Flbd_kNAp2Q)\\n - \u2b50\ufe0f [\u9ad8\u5e76\u53d1\u4e0b\uff0c\u5e42\u7b49\u6027\u5982\u4f55\u4fdd\u8bc1](https://mp.weixin.qq.com/s/crzfBEGn78nUZ5H3MF8UZw)\\n - \u2b50\ufe0f [Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848](https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw)\\n - [\u5982\u4f55\u8bbe\u8ba1\u4e00\u4e2a\u77ed\u94fe\u670d\u52a1](https://mp.weixin.qq.com/s/Z0xVHgw-ZzZV-jOOOSsMUw)\\n- \u6d88\u606f\u961f\u5217\\n - \u2b50\ufe0f [\u804a\u804aRocketMQ\u5b58\u50a8\u6a21\u578b](https://mp.weixin.qq.com/s/D8ptc4SCqWtaWe-ZBhwXfA)\\n - \u2b50\ufe0f [\u9762\u6e23\u9006\u88ad\uff1aRocketMQ\u4e8c\u5341\u4e09\u95ee](https://mp.weixin.qq.com/s/mNpXpSVVVBuI59LI6vVvQA)\\n - \u2b50\ufe0f [\u5228\u6839\u95ee\u5e95 Kafka\uff0c\u6838\u5fc3\u77e5\u8bc6\u70b9\u5927\u8d2f\u901a](https://mp.weixin.qq.com/s/GeXtCJgo42u92FSS5V6oMQ)\\n - \u2b50\ufe0f [\u6d88\u606f\u961f\u5217\u539f\u7406\u548c\u9009\u578b\uff1aKafka\u3001RocketMQ \u3001RabbitMQ \u548c ActiveMQ](https://mp.weixin.qq.com/s/J0zKPTNoJgiFvNT4M9BVcg)\\n - [\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u513f\u53eb MQ](https://mp.weixin.qq.com/s/i_bwyEb8QqfVLxY-R9odag)\\n- Elasticsearch \u76f8\u5173\\n - \u2b50\ufe0f [MyBatis-Plus\u540c\u6b3eElasticsearch ORM\u6846\u67b6\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://juejin.cn/post/7155662252584992805)\\n - \u2b50\ufe0f [Elasticsearch\u5feb\u901f\u5165\u95e8\uff0c\u638c\u63e1\u8fd9\u4e9b\u521a\u521a\u597d\uff01](https://juejin.cn/post/6844904117580595214)\\n - \u2b50\ufe0f [Elasticsearch \u57fa\u7840\u5165\u95e8\u8be6\u6587](https://mp.weixin.qq.com/s/GG_zrQlaiP2nfPOxzx_j9w)\\n- \u5927\u6570\u636e\u76f8\u5173\\n - [\u4e00\u6587\u4e86\u89e3-\u4e91\u539f\u751f\u5927\u6570\u636e\u77e5\u8bc6\u5730\u56fe](https://mp.weixin.qq.com/s/vua2g0_t1Y8KW4cNHSQdNw)\\n - [\u3010\u4e91\u539f\u751f\u3011Hive on k8s \u73af\u5883\u90e8\u7f72](https://juejin.cn/post/7149487706991493156)\\n - [\u5927\u6570\u636eHadoop\u4e4b\u2014\u2014\u6570\u636e\u4ed3\u5e93Hive](https://juejin.cn/post/7087484692718420005)\\n - [\u3010\u4e91\u539f\u751f\u3011Kubernetes\uff08k8s\uff09\u6700\u5b8c\u6574\u7248\u73af\u5883\u90e8\u7f72+master\u9ad8\u53ef\u7528\u5b9e\u73b0](https://juejin.cn/post/7136214451678052389)\\n - [Flink \u6d41\u6279\u4e00\u4f53\u5728\u5b57\u8282\u8df3\u52a8\u7684\u63a2\u7d22\u4e0e\u5b9e\u8df5](https://juejin.cn/post/7141215211586863140)\\n - [\u5927\u6570\u636e\u67b6\u6784\u7cfb\u5217\uff1a\u5982\u4f55\u7406\u89e3\u6e56\u4ed3\u4e00\u4f53](https://mp.weixin.qq.com/s/G66BCDUMzYE30p250JO0hg)\\n - [23\u5f20\u56fe\uff0c\u5e26\u4f60\u5165\u95e8\u63a8\u8350\u7cfb\u7edf](https://mp.weixin.qq.com/s/yQavfvBayYbMEc7c9ObMxg)\\n - [\u4e00\u6587\u770b\u61c2\u5927\u6570\u636e\u751f\u6001\u5708\u5b8c\u6574\u77e5\u8bc6\u4f53\u7cfb\uff08\u6587\u672b\u9001\u4e66\uff09](https://mp.weixin.qq.com/s/gAhoIwPoFDlKbBmWzrHu8w)\\n- \u4e91\u539f\u751f\u76d1\u63a7\\n - \u2b50\ufe0f [\u81ea\u4ece\u9879\u76ee\u4e0a\u4e86SkyWalking\uff0c\u7761\u89c9\u771f\u9999\uff01](https://mp.weixin.qq.com/s/72UbwZTxo36eJVqGq8HBgw)\\n - \u2b50\ufe0f [\u81ea\u4ece\u7ebf\u4e0a\u9879\u76ee\u7528\u4e86\u8fd9\u4e2a\u76d1\u63a7\u7cfb\u7edf\uff0c\u7761\u89c9\u771f\u9999\uff01](https://mp.weixin.qq.com/s/D1JoTzdQnzUgX_yqT3N1BQ)\\n - \u2b50\ufe0f [\u8fd8\u5728\u670d\u52a1\u5668\u4e0a\u635e\u65e5\u5fd7\uff1f\u5feb\u642d\u5efa\u4e00\u4e2aELK\u65e5\u5fd7\u7cfb\u7edf\u5427\uff0c\u771f\u5fc3\u5f3a\u5927\uff01](https://mp.weixin.qq.com/s/bSw_QP4-xMKnBTmqAjkUGA)\\n - \u2b50\ufe0f [\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01](https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg)\\n- \u2b50\ufe0f [\u4e00\u81f4\u6027\u54c8\u5e0c\u7b97\u6cd5\u89e3\u51b3\u7684\u95ee\u9898](https://mp.weixin.qq.com/s/hJHMlbQpANwMjx9BetwkUg)\\n- \u2b50\ufe0f [\u4e00\u81f4\u6027Hash\u7b97\u6cd5\u539f\u7406\u603b\u7ed3](https://zhuanlan.zhihu.com/p/482549860)\\n- \u2b50\ufe0f \u2b50\ufe0f [100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01](https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA)\\n- [\u89e3\u51b3\u4e86 Redis \u5927 key \u95ee\u9898\uff0c\u540c\u4e8b\u4eec\u90fd\u8bf4\u725b\u76ae\uff01](https://mp.weixin.qq.com/s/l3l9d9sLiWoUM381E9o-3Q)\\n- [\u56fe\u89e3|Linux\u5185\u5b58\u80cc\u540e\u7684\u90a3\u4e9b\u795e\u79d8\u5f80\u4e8b](https://mp.weixin.qq.com/s/l_YdpyHht5Ayvrc7LFZNIA)\\n- [\u56fe\u89e3|\u4ec0\u4e48\u662f\u5185\u5bb9\u5206\u53d1\u7f51\u7edc(cdn)](https://juejin.cn/post/7064952956201730062)\\n- [\u4e00\u952e\u90e8\u7f72 K8S \u73af\u5883\uff0c10\u5206\u949f\u73a9\u8f6c\uff0c\u8fd9\u6b3e\u5f00\u6e90\u795e\u5668\u5b9e\u5728\u592a\u9999\u4e86\uff01](https://juejin.cn/post/7070683049049980941)\\n- [\u989c\u503c\u7206\u8868\uff01Redis \u5b98\u65b9\u53ef\u89c6\u5316\u5de5\u5177\u6765\u5566\uff0c\u529f\u80fd\u771f\u5fc3\u5f3a\u5927\uff01](https://mp.weixin.qq.com/s/KIcn2TAwY58JGoWiz82Q2g)\\n- [Nginx\u7684\u8fd9\u4e9b\u5999\u7528\uff0c\u4f60\u80af\u5b9a\u6709\u4e0d\u77e5\u9053\u7684\uff01](https://juejin.cn/post/6844904017286561799)\\n- [\u524d\u7aef\u5230\u5e95\u7528nginx\u6765\u505a\u5565](https://juejin.cn/post/7064378702779891749)\\n- [\u4e00\u4efd\u7b80\u5355\u591f\u7528\u7684 Nginx Location \u914d\u7f6e\u8bb2\u89e3](https://juejin.cn/post/7048952689601806366)\\n\\n## \u524d\u7aef\u6027\u80fd\u4f18\u5316\\n\\n- \u2b50\ufe0f [\u5199\u7ed9\u4e2d\u9ad8\u7ea7\u524d\u7aef\u5173\u4e8e\u6027\u80fd\u4f18\u5316\u76849\u5927\u7b56\u7565\u548c6\u5927\u6307\u6807 | \u7f51\u6613\u56db\u5e74\u5b9e\u8df5](https://juejin.cn/post/6981673766178783262)\\n- \u2b50\ufe0f [\u524d\u7aef\u76d1\u63a7\u7cfb\u52173 \uff5c \u5982\u4f55\u8861\u91cf\u4e00\u4e2a\u7ad9\u70b9\u7684\u6027\u80fd\u597d\u574f](https://mp.weixin.qq.com/s/Au_NNeamEoFEtlNvvVjpLw)\\n- \u2b50\ufe0f [\u6700\u5168\u7684\u524d\u7aef\u6027\u80fd\u5b9a\u4f4d\u603b\u7ed3](https://juejin.cn/post/7052918009555320839)\\n- \u2b50\ufe0f [Web\u9875\u9762\u5168\u94fe\u8def\u6027\u80fd\u4f18\u5316\u6307\u5357](https://mp.weixin.qq.com/s/wJxj5QbOHwH9cKmqU5eSQw)\\n- \u2b50\ufe0f [\u5b57\u8282\u8df3\u52a8\u662f\u5982\u4f55\u843d\u5730\u5fae\u524d\u7aef\u7684](https://juejin.cn/post/7016900744695513125)\\n- \u2b50\ufe0f [2022 \u5e74\u7684 CSS](https://juejin.cn/post/7048260643589193765)\\n- \u2b50\ufe0f [\u5982\u4f55\u7f16\u5199\u9632\u5fa1\u5f0f\u7684 CSS](https://juejin.cn/post/7054931603323093022)\\n- \u2b50\ufe0f [\u524d\u7aef Code Review \u4e0d\u5b8c\u5168\u6307\u5317(\u4e07\u5b57\u957f\u6587\uff0c50+case)](https://zhuanlan.zhihu.com/p/396010993)\\n- \ud83c\udf1b [\u5199\u5728 2021 \u7684\u524d\u7aef\u6027\u80fd\u4f18\u5316\u6307\u5357](https://juejin.cn/post/7020212914020302856)\\n- [\u6df1\u5165\u6d45\u51fa Performance \u5de5\u5177 & API](https://juejin.cn/post/7000728875676205086)\\n- [\u4f7f\u7528 Performance \u770b\u770b\u6d4f\u89c8\u5668\u5728\u505a\u4ec0\u4e48](https://juejin.cn/post/6904582930174705677)\\n\\n## \u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218\\n\\n- \u2b50\ufe0f [\u5feb\u4e0a\u8f66\uff01\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01](https://juejin.cn/post/7120893568553582622)\\n- \u2b50\ufe0f [\u4f7f\u7528Vite\u548cTypeScript\u5e26\u4f60\u4ece\u96f6\u6253\u9020\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684Vue3\u7ec4\u4ef6\u5e93](https://juejin.cn/post/7117886038126624805)\\n- \u2b50\ufe0f [\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6](https://juejin.cn/post/7069772395610898462)\\n- \u2b50\ufe0f [\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1](https://juejin.cn/post/6844904197863964685)\\n- \u2b50\ufe0f [\u5c24\u5927\u90fd\u63a8\u8350\u7684\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u5f00\u53d1\u51fa\u6765\u7684\uff1f](https://juejin.cn/post/7021528826798669854)\\n- [\u6bcf\u4e2a\u524d\u7aef\u90fd\u503c\u5f97\u62e5\u6709\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff0c\u5c31\u50cf\u6bcf\u4e2a\u590f\u5929\u90fd\u62e5\u6709\u897f\u74dc\ud83c\udf49](https://juejin.cn/post/6983854006124675108)\\n- [Vue3\u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218 --Element3](https://juejin.cn/post/6930879590554402830)\\n\\n## Node.js \u7cfb\u5217\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217](https://github.com/koala-coding/goodBlog)\\n- \u2b50\ufe0f \u2b50\ufe0f [Node.js \u6982\u8ff0\uff1a\u67b6\u6784\u3001API\u3001\u4e8b\u4ef6\u5faa\u73af\u3001\u5e76\u53d1](https://mp.weixin.qq.com/s/B051n14JbNHqJtQb68HBFA)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0a\u3011](https://mp.weixin.qq.com/s/sSfj4BOjHNyzdjGc90yU8g)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0b\u3011](https://mp.weixin.qq.com/s/9SJL2UttCedNjF6CKyk3wg)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5927\u5382\u662f\u5982\u4f55\u7528DevCloud\u6d41\u6c34\u7ebf\u5b9e\u73b0\u81ea\u52a8\u5316\u90e8\u7f72Web\u5e94\u7528\u7684\uff1f](https://juejin.cn/post/6887961766170066951)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u624b\u628a\u624b\u6559\u4f60\u4f7f\u7528Rollup\u6253\u5305 \ud83d\udce6 \u5e76\u53d1\u5e03\u81ea\u5df1\u7684\u5de5\u5177\u5e93 \ud83d\udd27](https://juejin.cn/post/6902659492161421325)\\n- \ud83c\udf1b [Node \u6848\u53d1\u73b0\u573a\u63ed\u79d8 \u2014\u2014 \u672a\u5b9a\u4e49 \u201cwindow\u201d \u5bf9\u8c61\u5f15\u53d1\u7684 SSR \u5185\u5b58\u6cc4\u9732](https://zhuanlan.zhihu.com/p/461945753)\\n- \ud83c\udf1b [\u8f7b\u677e\u6392\u67e5\u7ebf\u4e0aNode\u5185\u5b58\u6cc4\u6f0f\u95ee\u9898](https://cnodejs.org/topic/58eb5d378cda07442731569f)\\n- \u2b50\ufe0f [Node.js \u6d41\uff08stream\uff09\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://zhuanlan.zhihu.com/p/36728655)\\n- \ud83c\udf1b [\u6700\u5168\u9762\u7684 Node.js \u8d44\u6e90\u6c47\u603b\u63a8\u8350](https://mp.weixin.qq.com/s/1DIDUvGoQcckRq757R9Ohw)\\n- \u2b50\ufe0f [Nest.js\u8fdb\u9636\u7cfb\u5217\u56db\uff1aNode.js\u4e2d\u4f7f\u7528Redis\u539f\u6765\u8fd9\u4e48\u7b80\u5355\uff01](https://mp.weixin.qq.com/s/yKm_U9Veh_1twIoXzM8Prw)\\n- \u2b50\ufe0f [Redis\u5b66\u4e60-\u5165\u95e8\u7bc7](https://mp.weixin.qq.com/s/TmCtsbhjexZNCdvUSXdNCw)\\n- \u2b50\ufe0f [Node.js \u5b89\u5168\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/2CBGgtja04NnOerpKfk0Ug)\\n- \u2b50\ufe0f [2022\u5e74\u503c\u5f97\u4f7f\u7528\u7684 Node.js \u6846\u67b6](https://mp.weixin.qq.com/s/PhuFfNAhvXAqW4eSbUqpKQ)\\n- \ud83c\udf1b [NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357](https://juejin.cn/post/7095354780079357966)\\n- \u2b50\ufe0f [Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb](https://zhuanlan.zhihu.com/p/502951532)\\n- \ud83c\udf1b [\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93](https://zhuanlan.zhihu.com/p/415361629)\\n- \ud83c\udf1b [unjs: Unified JavaScript Tools](https://github.com/unjs)\\n- \ud83c\udf1b [pkg - \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6](https://github.com/vercel/pkg)\\n- \u2b50\ufe0f [Oclif v2.5\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6](https://github.com/oclif/oclif)\\n- \ud83c\udf1b [JavaScript Debugger \u539f\u7406\u63ed\u79d8](https://juejin.cn/post/6961790494514872333)\\n- \ud83c\udf1b [\u6d45\u8c08 Node.js \u70ed\u66f4\u65b0](https://mp.weixin.qq.com/s/xCoTeyJDifi4Ymk0VsI2Ig)\\n- \u2b50\ufe0f [NodeJS\u52a0\u89e3\u5bc6\u4e4bCrypto](https://juejin.cn/post/7044344538969669663)\\n- \ud83c\udf1b [zx - \u8c37\u6b4c\u5f00\u53d1\u7684\u547d\u4ee4\u884c\u811a\u672c\u5de5\u5177](https://github.com/google/zx)\\n- \ud83c\udf1b [node-fetch - node \u73af\u5883\u4e0b\u8fdb\u884c\u7f51\u7edc\u8bf7\u6c42](https://github.com/node-fetch/node-fetch)\\n- \u2b50\ufe0f [\u6d45\u6790 NodeJS \u591a\u8fdb\u7a0b\u548c\u96c6\u7fa4](https://juejin.cn/post/6971770846872338439)\\n- \u2b50\ufe0f [Tasuku - \u9762\u5411 Node \u7684\u6700\u5c0f\u4efb\u52a1\u8fd0\u884c\u5668](https://github.com/privatenumber/tasuku)\\n- \ud83c\udf1b [Node.js\u7684\u5e95\u5c42\u539f\u7406](https://juejin.cn/post/7008504029277847565)\\n- \u2b50\ufe0f [\u8ba4\u771f\u5199\u4e86\u4e2a\u5feb\u901f\u521b\u5efa Node \u670d\u52a1\u7684CLI\uff0c\u770b\u770b\u5bf9\u5c0f\u4f19\u4f34\u4eec\u6709\u5e2e\u5fd9\u5417\uff1f](https://mp.weixin.qq.com/s/Gcx6E4cYo6WPB8PLI72NWg)\\n - \u9879\u76ee\u5730\u5740\uff1ahttps://github.com/koala-coding/create-bff-service-cli\\n\\nimport Tabs from \'@theme/Tabs\';\\nimport TabItem from \'@theme/TabItem\';\\n\\n\\n\\n\\n- \u2b50\ufe0f [taze - \u66f4\u65b0\u4f9d\u8d56\u7248\u672c\u7684 CLI \u5de5\u5177](https://github.com/antfu/taze)\\n- \u2b50\ufe0f [haya - Vite \u7684\u66ff\u4ee3\u65b9\u6848\uff0c\u63d0\u4f9b\u57fa\u4e8e esbuild \u7684 devServer \u548c bundler](https://github.com/egoist/haya)\\n- \u2b50\ufe0f [unbuild - \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177](https://github.com/unjs/unbuild)\\n- \u2b50\ufe0f [tsup - \u96f6\u914d\u7f6e\u7684 TS \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177](https://github.com/egoist/tsup)\\n- \u2b50\ufe0f [degit - \u7b80\u5355\u7684\u9879\u76ee\u811a\u624b\u67b6](https://github.com/Rich-Harris/degit)\\n- \u2b50\ufe0f [react-use - \u4e00\u4e2a React Hooks \u5e93](https://github.com/streamich/react-use)\\n- [react-query - \u7528\u4e8e\u83b7\u53d6\u6570\u636e\u3001\u7f13\u5b58\u3001\u5f02\u6b65\u66f4\u65b0\u72b6\u6001\u7684 hook](https://github.com/tannerlinsley/react-query)\\n- [ioredis - \u4e13\u6ce8\u4e8e\u6027\u80fd\u7684\u5168\u529f\u80fd Redis \u5ba2\u6237\u7aef](https://github.com/luin/ioredis)\\n- [prisma - \u4e0b\u4e00\u4ee3 Nodejs ORM \u5de5\u5177\uff0c\u652f\u6301\u5404\u79cd\u6570\u636e\u5e93](https://github.com/prisma/prisma)\\n- [astro - \u9759\u6001\u7ad9\u70b9\u6784\u5efa\u5de5\u5177](https://github.com/withastro/astro)\\n- [zustand - \u5c0f\u578b\u3001\u5feb\u901f\u53ef\u6269\u5c55\u7684\u72b6\u6001\u7ba1\u7406\u89e3\u51b3\u65b9\u6848](https://github.com/pmndrs/zustand)\\n- [tauri - \u5c06\u524d\u7aef\u9879\u76ee\u6253\u5305\u4e3a\u684c\u9762\u5e94\u7528\uff0c\u7528\u4e8e\u66ff\u4ee3 electron](https://github.com/tauri-apps/tauri)\\n- [tRPC - \u65b9\u4fbf\u5feb\u901f\u7684\u751f\u6210\u7aef\u5bf9\u7aef\u7c7b\u578b\u5b89\u5168\u7684 API \u5b9a\u4e49](https://github.com/trpc/trpc)\\n- [Drift - \u4e00\u4e2a\u53ef\u4ee5\u81ea\u5df1\u90e8\u7f72\u7684\u4ee3\u7801\u7247\u6bb5\u670d\u52a1\uff0c\u57fa\u4e8e Next.js 13 \u6784\u5efa](https://github.com/MaxLeiter/Drift)\\n\\n\\n\\n\\n- \u2b50\ufe0f [bytemd - \u5b57\u8282\u51fa\u54c1\u7684 markdown \u7f16\u8f91\u5668](https://github.com/bytedance/bytemd)\\n- \u2b50\ufe0f [guide - \u5b57\u8282\u51fa\u54c1\u7684 React \u65b0\u624b\u5f15\u5bfc\u7ec4\u4ef6](https://github.com/bytedance/guide)\\n- \u2b50\ufe0f [react-medium-image-zoom - \u53d7 Medium.com \u542f\u53d1\u7684\u56fe\u7247\u9884\u89c8\u7ec4\u4ef6](https://github.com/rpearce/react-medium-image-zoom)\\n- \u2b50\ufe0f [cmdk - \u4e00\u4e2a\u57fa\u4e8e React \u7684\u5feb\u901f\u3001\u53ef\u7ec4\u5408\u3001\u65e0\u98ce\u683c\u7684\u547d\u4ee4\u9762\u677f](https://github.com/pacocoursey/cmdk)\\n- \u2b50\ufe0f [nice-modal-react\uff1a\u6765\u81ea eBay \u7684\u6a21\u6001\u6846\u72b6\u6001\u7ba1\u7406](https://github.com/eBay/nice-modal-react)\\n\\n\\n\\n\\n- \u2b50\ufe0f [date-fns - \u73b0\u4ee3\u5316\u7684 JavaScript \u65e5\u671f\u7c7b\u5e93](https://github.com/date-fns/date-fns)\\n- \u2b50\ufe0f [nanoid - \u7528\u4e8e\u66ff\u4ee3 uuid \u7684\u968f\u673a id \u751f\u6210\u5e93](https://github.com/ai/nanoid)\\n- `dayjs`\uff1a\u4e0e `moment` \u7684 API \u8bbe\u8ba1\u4fdd\u6301\u4e00\u6837\uff0c\u4f46\u4f53\u79ef\u4ec5\u6709 2KB\uff1b\\n- `qs`\uff1a\u89e3\u6790 URL query \u53c2\u6570\u7684\u5e93\uff1b\\n- `js-cookie`\uff1a\u7b80\u5355\u3001\u8f7b\u91cf\u7684\u5904\u7406 cookie \u7684\u5e93\uff1b\\n- `flv.js`\uff1abilibili \u5f00\u6e90\u7684 HTML5 flash \u64ad\u653e\u5668\uff0c\u4f7f\u6d4f\u89c8\u5668\u5728\u4e0d\u501f\u52a9 flash \u63d2\u4ef6\u7684\u60c5\u51b5\u4e0b\u53ef\u4ee5\u64ad\u653e flv\uff1b\\n- `vConsole`\uff1a\u4e00\u4e2a\u8f7b\u91cf\u3001\u53ef\u62d3\u5c55\u3001\u9488\u5bf9\u624b\u673a\u7f51\u9875\u7684\u524d\u7aef\u5f00\u53d1\u8005\u8c03\u8bd5\u9762\u677f\uff1b\\n- `animate.css`\uff1a\u4e00\u4e2a\u8de8\u6d4f\u89c8\u5668\u7684 css3 \u52a8\u753b\u5e93\uff0c\u5185\u7f6e\u4e86\u5f88\u591a\u5178\u578b\u7684 css3 \u52a8\u753b\uff0c\u517c\u5bb9\u6027\u597d\uff0c\u4f7f\u7528\u65b9\u4fbf\uff1b\\n- `lodash`\uff1a\u4e00\u4e2a\u4e00\u81f4\u6027\u3001\u6a21\u5757\u5316\u3001\u9ad8\u6027\u80fd\u7684 JavaScript \u5b9e\u7528\u5de5\u5177\u5e93\uff1b\\n\\n\\n\\n\\n- \u2b50\ufe0f [chokidar - \u8de8\u5e73\u53f0\u76d1\u542c\u6587\u4ef6\u53d8\u5316](https://github.com/paulmillr/chokidar)\\n- \u2b50\ufe0f [fs-extra - Node \u539f\u751f fs \u6a21\u5757\u7684\u6269\u5c55](https://github.com/jprichardson/node-fs-extra)\\n- `yargs`\uff1a\u901a\u8fc7\u4f7f\u7528 Node.js \u6784\u5efa\u529f\u80fd\u5168\u9762\u7684\u547d\u4ee4\u884c\u5e94\u7528\\n- `Ajv`\uff1a\u4e00\u4e2a\u9002\u7528\u4e8e Node.js \u548c\u6d4f\u89c8\u5668\u7684\u6700\u5feb JSON \u9a8c\u8bc1\u5668\\n- `yallist`\uff1a\u4e00\u4e2a\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0\\n- `rimraf`\uff1aNode.js \u7684 rm -rf \u5b9e\u7528\u7a0b\u5e8f\\n- `consola`\uff1aNuxt.js \u51fa\u54c1\u7684\u7ec8\u7aef\u65e5\u5fd7\u5de5\u5177\\n- `webpackbar`\uff1aNuxt.js \u51fa\u54c1\u7684 webpack \u7f16\u8bd1\u8fdb\u5ea6\u6761\\n- `pkg`: \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6\\n- `concurrently`\uff1a\u66f4\u4f18\u96c5\u5730\u5e76\u53d1\u6267\u884c\u547d\u4ee4\\n- `better-logging`\uff1aNode \u9ed8\u8ba4\u65e5\u5fd7\u8bb0\u5f55\u65b9\u6cd5\u7684\u66ff\u4ee3\u54c1\\n\\n\\n\\n\\n- `chalk/kolorist`\\n- `inquirer/prompts`\\n- `ora`\\n- `semver`\\n- `pkg-install`\\n- `ncp`\uff1a\u8de8\u5e73\u53f0\u9012\u5f52\u62f7\u8d1d\u6587\u4ef6\\n- `commander/yargs`\\n- `execa`\uff08\u4e2a\u4eba\u89c9\u5f97 Node \u539f\u751f `child_process` \u7684 `exec` \u5c31\u591f\u7528\u4e86\uff09\\n- `minimist`\\n- `oclif`\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6\\n\\n\\n\\n\\n## \u524d\u7aef\u7f16\u8bd1\\n\\n- [\u3010\u7b2c2597\u671f\u3011\u5982\u4f55\u7528JavaScript\u5b9e\u73b0\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 - AST](https://mp.weixin.qq.com/s/JMl8LOsNYlttxO-KyVK-Vw)\\n- [V8 \u7f16\u8bd1\u6d45\u8c08](https://juejin.cn/post/7041021350114230285)\\n- \u2b50\ufe0f [\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e8c\uff09\u2014\u2014 Antlr \u53ca\u5176\u5e94\u7528](https://juejin.cn/post/7057354419888717855)\\n- \u2b50\ufe0f [\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e00\uff09\u2014\u2014 \u7f16\u8bd1\u539f\u7406\u57fa\u7840](https://juejin.cn/post/6989509925844041742)\\n- \u2b50\ufe0f [Babel \u63d2\u4ef6\u901a\u5173\u79d8\u7c4d](https://juejin.cn/book/6946117847848321055)\\n- \ud83c\udf1b [v8 \u6267\u884c js \u7684\u8fc7\u7a0b](https://www.zoo.team/article/the-process-of-executing-js-in-v8)\\n- \ud83c\udf1b [\u786c\u6838\u51b7\u77e5\u8bc6\uff1aV8\u4e0eWebAssembly\u4e0d\u5f97\u4e0d\u8bf4\u7684\u79d8\u5bc6](https://laocuicode.cn/daydream/2022/04/01/202241-%E7%A1%AC%E6%A0%B8%E5%86%B7%E7%9F%A5%E8%AF%86%EF%BC%9AWebAssembly/)\\n- [import \u65b9\u5f0f\u968f\u610f\u4e92\u8f6c\uff0c\u611f\u53d7 babel \u63d2\u4ef6\u7684\u5a01\u529b](https://juejin.cn/post/7018563244679757855)\\n- [\u4ece\u96f6\u5230\u4e00\uff0c\u6211\u4eec\u6765\u4e00\u8d77\u9020\u4e2a JS \u7684\u7f16\u8bd1\u5668](https://mp.weixin.qq.com/s/pNossFUtJrDHshXbWLb4vA)\\n- [\u6d45\u6790TypeScript Compiler \u539f\u7406](https://juejin.cn/post/7047329886502912030)\\n- \u2b50\ufe0f [\u300a\u4ece 0 \u5230 1 \u624b\u5199 babel\u300b\u601d\u8def\u5206\u4eab](https://juejin.cn/post/6962861837800964133)\\n- [\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357](https://juejin.cn/post/6953963506693570573)\\n\\n## \u7f51\u7edc\u76f8\u5173\\n\\n- [HTTP/3 From A To Z: Core Concepts](https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/)\\n- [502\u95ee\u9898\u600e\u4e48\u6392\u67e5](https://juejin.cn/post/7155280646112280613)\\n- [\u521a\u63d2\u4e0a\u7f51\u7ebf\uff0c\u7535\u8111\u600e\u4e48\u77e5\u9053\u81ea\u5df1\u7684IP\u662f\u4ec0\u4e48](https://juejin.cn/post/7153255870447484936)\\n- [\u52a8\u56fe\u56fe\u89e3 | UDP\u5c31\u4e00\u5b9a\u6bd4TCP\u5feb\u5417](https://juejin.cn/post/7147243567075819557)\\n- [\u7528\u4e86TCP\u534f\u8bae\uff0c\u5c31\u4e00\u5b9a\u4e0d\u4f1a\u4e22\u5305\u5417](https://juejin.cn/post/7126710506936598558)\\n- \u2b50\ufe0f [HTTPS \u5c31\u4e00\u5b9a\u5b89\u5168\uff1f\u6211\u4e0d\u4fe1](https://mp.weixin.qq.com/s/nS1bMy2TejmGwEfCHPXy5A)\\n- \u2b50\ufe0f [\u80fdping\u901a\uff0cTCP\u5c31\u4e00\u5b9a\u80fd\u8fde\u901a\u5417](https://mp.weixin.qq.com/s/fb2uUWz5ZjPEfYv_l6e4Zg)\\n- [Linux \u662f\u5982\u4f55\u6536\u53d1\u7f51\u7edc\u5305\u7684](https://mp.weixin.qq.com/s/RJp9s_shNckkHBqHsJThuA)\\n- [\u5b57\u8282\u4e09\u9762\uff0c\u7b54\u7684\u4e0d\u6ee1\u610f](https://mp.weixin.qq.com/s/7P_1VkBeoArKuuEqGcR9ig)\\n- [\u4f53\u9a8c http3: \u57fa\u4e8e nginx quic \u5206\u652f](https://mp.weixin.qq.com/s/8CPWh_Ly61m8rkHvPT5n2g)\\n- [HTTP/3\u53d1\u5e03\u4e86\uff0c\u6211\u4eec\u6765\u8c08\u8c08HTTP/3](https://mp.weixin.qq.com/s/nRHlwYsr0MaadmaFWEIblQ)\\n- [\u65e2\u7136\u6709 HTTP \u534f\u8bae\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u6709 RPC](https://mp.weixin.qq.com/s/qmnfmUCdekEt1xG0hp_4MQ)\\n- [\u5b57\u8282\u4e00\u9762\uff1aTCP \u548c UDP \u53ef\u4ee5\u4f7f\u7528\u540c\u4e00\u4e2a\u7aef\u53e3\u5417](https://mp.weixin.qq.com/s/3fMZN_LidCi5fiD16nNWWA)\\n- \u2b50\ufe0f [\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee](https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg)\\n- \u2b50\ufe0f [\u5b57\u8282\u4e00\u9762\uff1a\u5982\u4f55\u7528 UDP \u5b9e\u73b0\u53ef\u9760\u4f20\u8f93](https://mp.weixin.qq.com/s/hX75YxVOMtsnB6Sm_yjm0g)\\n- \u2b50\ufe0f [TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86](https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw)\\n- \u2b50\ufe0f [(\u5efa\u8bae\u6536\u85cf)TCP\u534f\u8bae\u7075\u9b42\u4e4b\u95ee\uff0c\u5de9\u56fa\u4f60\u7684\u7f51\u8def\u5e95\u5c42\u57fa\u7840](https://juejin.cn/post/6844904070889603085)\\n- \u2b50\ufe0f [TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f](https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g)\\n- \u63a8\u8350\u770b\u770b QUIC 101 \u89c6\u9891\u4ee5\u53ca [The QUIC transport protocol: design and Internet-scale deployment](https://courses.cs.washington.edu/courses/cse550/20au/papers/CSE550.quic.pdf) \u8bba\u6587\\n- \u2b50\ufe0f [\u4e00\u6587\u5f7b\u5e95\u641e\u61c2\u52a0\u5bc6\u3001\u6570\u5b57\u7b7e\u540d\u548c\u6570\u5b57\u8bc1\u4e66\uff01](https://segmentfault.com/a/1190000024523772)\\n- \u2b50\ufe0f [\u4e00\u4e2aResponse Header\u5f15\u53d1\u7684\u8840\u6848(\u5305\u542bCDN\u7684\u76f8\u5173\u6982\u5ff5)](https://juejin.cn/post/6944420222757503006)\\n\\n## \u64cd\u4f5c\u7cfb\u7edf\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [The Art of Command Line](https://github.com/jlevy/the-art-of-command-line)\\n- \u2b50\ufe0f [\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01](https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA)\\n- \u2b50\ufe0f [Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0a\uff09](https://mp.weixin.qq.com/s/94F4v1E9sB82lOr2DeSK0A)\\n- \u2b50\ufe0f [Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0b\uff09](https://mp.weixin.qq.com/s/ev8hnv-coGLobrbezMK1og)\\n- \u2b50\ufe0f [\u770b\u5b8c\u8fd9\u7bc7\u4f60\u4e00\u5b9a\u80fd\u638c\u63e1Linux](https://mp.weixin.qq.com/s/ZralWEfG2WJfZ-G-x9biow)\\n- \u2b50\ufe0f [2\u4e07\u5b57\u7cfb\u7edf\u603b\u7ed3\uff0c\u5e26\u4f60\u5b9e\u73b0 Linux \u547d\u4ee4\u81ea\u7531](https://juejin.cn/post/6938385978004340744)\\n- [6w\u5b57\u641e\u5b9aLinux\u57fa\u672c\u64cd\u4f5c\uff0c\u5efa\u8bae\u6536\u85cf](https://juejin.cn/post/6917096816118857736)\\n- [\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6](https://juejin.cn/post/6844904080972709901)\\n- [\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/6875323565479034894)\\n\\n## \u673a\u5668\u5b66\u4e60\\n\\n- \u672c\u5730\u8fd0\u884c Stable Diffusion \u9884\u8bad\u7ec3\u6a21\u578b\\n - [AI\u6570\u5b57\u7ed8\u753b stable-diffusion \u4fdd\u59c6\u7ea7\u6559\u7a0b](https://mp.weixin.qq.com/s/nDnQuZn3hVgrwqWVada2cw)\\n - https://lexica.art/?q=fc98f231-c95f-4a68-8727-899c73dbc486\\n - https://huggingface.co/CompVis/stable-diffusion-v1-4\\n - https://github.com/CompVis/stable-diffusion\\n - https://huggingface.co/blog/stable_diffusion\\n- [\u4e0d\u4f1a\u7b97\u6cd5\u4e5f\u80fd\u5fae\u8c03\u4e00\u4e2a NLP \u9884\u8bad\u7ec3\u6a21\u578b](https://juejin.cn/post/7146575333721341966)\\n- [\u4eba\u5de5\u795e\u7ecf\u7f51\u7edc\u7b97\u6cd5\u5165\u95e8](https://mp.weixin.qq.com/s/BcXl8YQVNQA6auilbxW0kQ)\\n- [\u6d45\u6790\u795e\u7ecf\u7f51\u7edc Neural Networks](https://mp.weixin.qq.com/s/gaOzwCypQMFAJ4X50aUOcg)\\n- [\u524d\u7aef\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u4f7f\u7528\u4e00\u4e2aNLP\u6a21\u578b](https://juejin.cn/post/7075518863814869005)\\n- \u6df1\u5165\u7406\u89e3 Transformer\uff1a\\n - https://www.bilibili.com/video/BV1P4411F77q\\n - https://www.bilibili.com/video/BV1Mt411J734\\n- [\u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b- bilibili](https://www.bilibili.com/video/BV1cD4y1D7uR)\\n- [\u300a\u8ba1\u7b97\u673a\u7f51\u7edc\u81ea\u9876\u5411\u4e0b\u65b9\u6cd5\u300b- bilibili](https://www.bilibili.com/video/BV1mb4y1d7K7)\\n - \u8fd9\u672c\u4e66\u91cd\u70b9\u7ae0\u8282\u662f\u7b2c2\u30013\u30014\u30015\u30016\u7ae0\uff0c\u5176\u4ed6\u7ae0\u8282\u53ef\u4ee5\u8df3\u8fc7\\n- \u5b66\u4e60\u8d44\u6e90\\n - https://github.com/ossu/computer-science\\n - https://github.com/Snailclimb/JavaGuide\\n - https://github.com/QSCTech/zju-icicles\\n- [\u4e00\u5929\u5b66\u4f1a MySQL \u6570\u636e\u5e93](https://www.bilibili.com/video/BV1Vt411z7wy)\\n- [\u5434\u6069\u8fbe\u300a\u6df1\u5ea6\u5b66\u4e60\u300b](https://www.bilibili.com/video/BV1FT4y1E74V)\\n- [\u63a8\u8350\u7cfb\u7edf\u7b97\u6cd5\u57fa\u7840+\u7efc\u5408\u9879\u76ee\u5b9e\u6218](https://www.bilibili.com/video/BV1qK4y1479r)\\n - \u518d\u5c31\u662f\u4e00\u4e9b\u6211\u8ba4\u4e3a\u5f88\u4f18\u79c0\u7684\u5f00\u6e90\u9879\u76ee\uff1a\\n - https://github.com/zhongqiangwu960812/AI-RecommenderSystem\\n - https://github.com/ZiyaoGeng/Recommender-System-with-TF2.0\\n- \u53c2\u8003\uff1a[\u4e07\u5b57\u5165\u95e8\u63a8\u8350\u7cfb\u7edf\uff01](https://mp.weixin.qq.com/s/YbwQAPIEkihO7XzVvrlDCg)\\n- [\u8bf4\u4e00\u8bf4Web\u7aef\u4fa7AI](https://juejin.cn/post/7013674501116264484)\\n- [\u673a\u5668\u5b66\u4e60\u521d\u63a2-\u7ebf\u6027\u56de\u5f52](https://juejin.cn/post/6964335363787620383)\\n- [\u673a\u5668\u5b66\u4e60\u8fdb\u9636 - \u6df1\u5165\u601d\u8003\u903b\u8f91\u56de\u5f52](https://juejin.cn/post/6951340421658181646)\\n\\n## LLM \u6280\u672f\u8c03\u7814\\n\\n- [\u4f7f\u7528 Transformers \u91cf\u5316 Meta AI LLaMA2 \u4e2d\u6587\u7248\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/Fo26NbtK8wFiHEGP0nhzuQ)\\n- [\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u4e2d\u6587\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/9cTNa_oya2Zj9YdDYodCvw)\\n- [\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u5b98\u65b9\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/NJ1JXkAK9LTSuor0mxtz1A)\\n- [AI \u52a0\u6301\u7684\u4ee3\u7801\u7f16\u5199\u5b9e\u6218\uff1a\u5feb\u901f\u5b9e\u73b0 Nginx \u914d\u7f6e\u683c\u5f0f\u5316\u5de5\u5177](https://mp.weixin.qq.com/s/iKtNOWkycm0FcMwnwq2M-A)\\n- [\u8ba9 OpenAI \u66f4 Open\uff0c\u5728 ChatGPT \u91cc\u81ea\u7531\u63a5\u5165\u6570\u636e\u6e90](https://mp.weixin.qq.com/s/o-6Xg1f7SMX-BUFgXgwb8w)\\n- [\u516b\u5341\u884c\u4ee3\u7801\u5b9e\u73b0\u5f00\u6e90\u7684 Midjourney\u3001Stable Diffusion \u201c\u5492\u8bed\u201d\u4f5c\u56fe\u5de5\u5177](https://mp.weixin.qq.com/s/Qo1--bFCzdNHAdesshrUuQ)\\n- [\u6a21\u578b\u6742\u8c08\uff1a1.5G \u663e\u5b58\u5c31\u80fd\u8fd0\u884c\u7684 RNN 14B \u7684\u5f00\u6e90\u6a21\u578b\uff08ChatRWKV\uff09](https://mp.weixin.qq.com/s/vH5zkdQ9esiMeg3L9TYgvw)\\n- [\u4f7f\u7528 Docker \u548c Alpaca LoRA \u5bf9 LLaMA 65B \u5927\u6a21\u578b\u8fdb\u884c Fine-Tune](https://mp.weixin.qq.com/s/cVR9yYP8zDiVBPEo91dSSA)\\n- [\u57fa\u4e8e Docker \u7684\u6df1\u5ea6\u5b66\u4e60\u73af\u5883\uff1a\u5165\u95e8\u7bc7](https://mp.weixin.qq.com/s/6Ae6SgEws5gndQwmZqkcUg)\\n- [\u6a21\u578b\u6742\u8c08\uff1a\u4f7f\u7528 IN8 \u91cf\u5316\u63a8\u7406\u8fd0\u884c Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09](https://mp.weixin.qq.com/s/6oKORqZWX7IlQFI5zbLKCw)\\n- [\u6a21\u578b\u6742\u8c08\uff1a\u5feb\u901f\u4e0a\u624b\u5143\u5b87\u5b99\u5927\u5382 Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09](https://mp.weixin.qq.com/s/vc4t7sm-BhAYtE7_J8DekQ)\\n- [RSS Can\uff1a\u501f\u52a9 V8 \u8ba9 Golang \u5e94\u7528\u5177\u5907\u52a8\u6001\u5316\u80fd\u529b\uff08\u4e8c\uff09](https://mp.weixin.qq.com/s/YKzWBa9kGbzwUpy2iuPjNA)\\n- [\u5728\u642d\u8f7d M1 \u53ca M2 \u82af\u7247 MacBook\u8bbe\u5907\u4e0a\u73a9 Stable Diffusion \u6a21\u578b](https://mp.weixin.qq.com/s/UO6_L_oVe3-ocOyt6R_YTA)\\n- [Linux \u8f6f\u4ef6\u5305\u4e0b\u8f7d\u52a0\u901f\u5de5\u5177\uff1aAPT Proxy](https://mp.weixin.qq.com/s/_1AZ5U27JOkEaCUkAuZADQ)\\n- [\u8f7b\u91cf\u9ad8\u53ef\u7528\u7684 K8s \u96c6\u7fa4\u642d\u5efa\u65b9\u6848\uff1aMicroK8s](https://mp.weixin.qq.com/s/e0x7BR2PwkTk9JWdr2hg-w)\\n- [\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f7f\u7528 Docker \u548c Milvus \u5feb\u901f\u6784\u5efa\u672c\u5730\u8f7b\u91cf\u56fe\u7247\u641c\u7d22\u5f15\u64ce](https://mp.weixin.qq.com/s/8MppGs90WWP5sMlHFX2EUQ)\\n- [\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u5165\u95e8\u5411\u91cf\u6570\u636e\u5e93 Milvus \u7684 Docker \u5de5\u5177\u955c\u50cf](https://mp.weixin.qq.com/s/pVYPpYRPjq7BUCahParVvw)\\n- [\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f20\u7edf\u6587\u672c\u68c0\u7d22\u65b9\u5f0f\u7684\u964d\u7ef4\u6253\u51fb\uff0c\u4f7f\u7528 Faiss \u5b9e\u73b0\u5411\u91cf\u8bed\u4e49\u68c0\u7d22](https://mp.weixin.qq.com/s/F0YgDChHceNoOPFstnBv3Q)\\n\\n## Java \u76f8\u5173\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01](https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u539f\u521b\u7cbe\u9009\u835f\u8403\uff082022.05.11\uff09](https://mp.weixin.qq.com/s/1Xe16FaHWfihYjqMVWidQg)\\n- [\u652f\u4ed8\u5b9d\u4e00\u9762\uff1a\u5982\u4f55\u57fa\u4e8eRedis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/j1U4L06y2-8z2fSJypGG7w)\\n- [Jenkins+Docker \u5b9e\u73b0\u4e00\u952e\u81ea\u52a8\u5316\u90e8\u7f72\u9879\u76ee\uff01\u6b65\u9aa4\u9f50\u5168\uff0c\u5c11\u8d70\u5751\u8def\uff01](https://mp.weixin.qq.com/s/va75wKPBtpp2ceL25SkIVA)\\n- [\u4e24\u4e07\u5b57\u8be6\u89e3\uff01Netty\u7ecf\u517832\u8fde\u95ee\uff01](https://mp.weixin.qq.com/s/njeXqkHiIsXneBholN72OQ)\\n- [\u4e24\u4e07\u5b57\u76d8\u70b9\u8bbe\u8ba1\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/409QGKe5H7tCP1qpCiY_KA)\\n- [\u5b9e\u6218\uff0c\u5b9e\u73b0\u5e42\u7b49\u76848\u79cd\u65b9\u6848\uff01](https://mp.weixin.qq.com/s/J0C9TJF7nVVi2cMiDBqepA)\\n- [\u5199\u4f18\u96c5\u4ee3\u7801\u768445\u4e2a\u5c0f\u6280\u5de7](https://mp.weixin.qq.com/s/Jct2rnz_0ahozWNZYfZ4Qg)\\n- [\u809d\u4e86\u4e00\u5468\u603b\u7ed3\u7684SpringBoot\u5e38\u7528\u6ce8\u89e3\u5927\u5168\uff0c\u770b\u5b8c\u5c31\u7089\u706b\u7eaf\u9752\u4e86\uff01](https://mp.weixin.qq.com/s/PzZ31ju32-5epXpQeTZsNA)\\n- [\u77a7\u77a7\u4eba\u5bb6\u5199\u7684API\u63a5\u53e3\u4ee3\u7801\uff0c\u90a3\u53eb\u4e00\u4e2a\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/rSYOAuJeIXaonHvuR5O47Q)\\n- [SpringBoot \u5b9e\u73b0 Excel \u5bfc\u5165\u5bfc\u51fa\uff0c\u6027\u80fd\u7206\u8868\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/P017RfO8TDL5LxGzBoTLSA)\\n- [\u8fd8\u5728\u7528HttpUtil\uff1fSpringBoot 3.0\u5168\u65b0HTTP\u5ba2\u6237\u7aef\u5de5\u5177\u6765\u4e86\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/SG9sNmMu9acB1xTODkG00Q)\\n- [\u5999\u7528Java 8\u4e2d\u7684 Function\u63a5\u53e3\uff0c\u6d88\u706dif...else\uff08\u975e\u5e38\u65b0\u9896\u7684\u5199\u6cd5\uff09](https://mp.weixin.qq.com/s/ezLN8AzVhBaeMdNMK-TS-g)\\n- [\u522b\u518d\u7528 if \u6821\u9a8c\u53c2\u6570\u4e86\uff0c\u592aLow\uff01\u8fd9\u624d\u662f\u4e13\u4e1a\u7684 SpringBoot \u53c2\u6570\u6821\u9a8c\u65b9\u5f0f\uff01](https://mp.weixin.qq.com/s/20LjD3_nJYvZrTNo4tqjvA)\\n- [\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3](https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg)\\n- [\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3](https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g)\\n- [\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3](https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA)\\n- [\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg)\\n- [11\u79cd\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/FX2umO7XCCmj8Bke7uKDZw)\\n- [\u8fd9\u4e9b\u5e76\u53d1\u7f16\u7a0b\u77e5\u8bc6\uff0c\u4e00\u5b9a\u8981\u77e5\u9053](https://mp.weixin.qq.com/s/Va4eoL5xizJasnSUbvvccw)\\n- [\u8fd910\u79cd\u795e\u7ea7\u6027\u80fd\u4f18\u5316\u624b\u6bb5\uff0c\u4f60\u7528\u8fc7\u51e0\u4e2a](https://mp.weixin.qq.com/s/EVgd689xdOX732hdOxPqcw)\\n- [\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01](https://mp.weixin.qq.com/s/VStQWv_ehN8RFDxpoAnKmg)\\n- [MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01](https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ)\\n- \u2b50\ufe0f [\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\u4e4b Spring IOC](https://mp.weixin.qq.com/s/29xlEK2N_Wptl4TBMg1ZPQ)\\n- [76 \u5f20\u56fe\uff0c\u5256\u6790 Spring AOP \u6e90\u7801\uff0c\u5c0f\u767d\u5c45\u7136\u4e5f\u80fd\u770b\u61c2\uff0c\u5927\u795e\uff0c\u8bf7\u6536\u4e0b\u6211\u7684\u819d\u76d6\uff01](https://mp.weixin.qq.com/s/T1toQ7NeHQKqof9A0o-99g)\\n- [\u4f7f\u7528 lambda \u5b9e\u73b0\u8d85\u5f3a\u7684\u6392\u5e8f\u529f\u80fd](https://mp.weixin.qq.com/s/n8iw_33Wwr9i0mWEXMG6-A)\\n- [\u4e07\u5b57\u957f\u6587\uff0cSpringSecurity\u5b9e\u73b0\u6743\u9650\u7cfb\u7edf\u8bbe\u8ba1](https://mp.weixin.qq.com/s/e_uJhaGj4HO1iTS_zCoCXw)\\n- [1.2w+\u5b57\uff01Java IO \u57fa\u7840\u77e5\u8bc6\u603b\u7ed3](https://mp.weixin.qq.com/s/J_11wYusexAjwa1cuckyfw)\\n- [\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01](https://mp.weixin.qq.com/s/7js2uDZNv2Pb55ihKPc1xg)\\n- [\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\uff0cSpring \u5982\u4f55\u89e3\u51b3\u5faa\u73af\u4f9d\u8d56](https://mp.weixin.qq.com/s/djVu6SJjfYj4y_LNW-SKyw)\\n- [\u9ebb\u4e86\uff0c\u4ee3\u7801\u6539\u6210\u591a\u7ebf\u7a0b\uff0c\u7adf\u67099\u5927\u95ee\u9898](https://mp.weixin.qq.com/s/hhjwiMx-ypEbxwHJ9rJoBw)\\n- [\u522b\u518d\u4e71\u6253\u65e5\u5fd7\u4e86\uff0c\u8fd9\u4efd Java \u65e5\u5fd7\u89c4\u8303\uff0c\u5e94\u6709\u5c3d\u6709\uff0c\u5efa\u8bae\u6536\u85cf\uff01](https://mp.weixin.qq.com/s/ioDYZjdSii3WUvL9xqc_Sg)\\n- [\u804a\u804aSpringBoot\u5355\u5143\u6d4b\u8bd5](https://mp.weixin.qq.com/s/zn4TDT4Vl_MobqNkW1m-jw)\\n- [\u603b\u76d1\u53c8\u6765\u4e86\uff0c\u4eba\u72e0\u8bdd\u4e0d\u591a\uff0c\u8fd9\u7bc7 gRPC\uff0c\u5c0f\u5f1f\u4f69\u670d\uff01](https://mp.weixin.qq.com/s/4Sxal7N-uZ8gvphC8XWo8A)\\n\x3c!-- - [Java\u6d41\u884c\u6846\u67b6\u6e90\u7801\u5206\u6790\uff1aSpring\u6e90\u7801\u3001SpringBoot\u6e90\u7801\u3001SpringAOP\u6e90\u7801\u3001SpringSecurity\u6e90\u7801\u3001SpringSecurity OAuth2\u6e90\u7801\u3001JDK\u6e90\u7801\u3001Netty\u6e90\u7801](https://github.com/coderbruis/JavaSourceCodeLearning) --\x3e\\n- [\u817e\u8baf\u4e00\u9762\uff1aThread\u3001Runnable\u3001Callable\u3001Future\u3001FutureTask\uff0c\u8c08\u8c08\u4ed6\u4eec\u7684\u5173\u7cfb](https://mp.weixin.qq.com/s/vqKKoPB5FQkCWXFWBLbkZg)\\n- [\u62dc\u6258\uff01\u9762\u8bd5\u8bf7\u4e0d\u8981\u518d\u95ee\u6211 @Transactional](https://mp.weixin.qq.com/s/rlfRjCb8EOrpt3xnF7isBw)\\n- [7 \u6bb5\u5c0f\u4ee3\u7801\uff0c\u73a9\u8f6cJava\u7a0b\u5e8f\u5e38\u89c1\u7684\u5d29\u6e83\u573a\u666f](https://mp.weixin.qq.com/s/YcyC1Jm4H7uGvSg3rCkDig)\\n- [\u5355\u4f8b\u6a21\u5f0f 4 \u79cd\u7ecf\u5178\u5b9e\u73b0\u65b9\u6cd5](https://mp.weixin.qq.com/s/Ua03qsLcrVURtxhSnuU_6w)\\n- [ElasticSearch\u8fdb\u9636\uff1a\u4e00\u6587\u5168\u89c8\u5404\u79cdES\u67e5\u8be2\u5728Java\u4e2d\u7684\u5b9e\u73b0](https://blog.csdn.net/mu_wind/article/details/118423362)\\n- [\u4f7f\u7528 @Transactional \u65f6\u5e38\u72af\u7684N\u79cd\u9519\u8bef](https://juejin.cn/post/7031047868806873096)\\n- [Spring Boot 2.x\u57fa\u7840\u6559\u7a0b\uff1a\u4f7f\u7528@Scheduled\u5b9e\u73b0\u5b9a\u65f6\u4efb\u52a1](https://juejin.cn/post/6984974277573836830)\\n- [Spring Boot\u4e2d\u4f7f\u7528@Async\u5b9e\u73b0\u5f02\u6b65\u8c03\u7528\uff0c\u52a0\u901f\u4efb\u52a1\u7684\u6267\u884c\uff01](https://juejin.cn/post/7007642025264676871)\\n- [IDEA \u9ad8\u6548\u4f7f\u7528\u6307\u5357](https://github.com/CodingDocs/awesome-idea)\\n- [CodeGuide | \u7a0b\u5e8f\u5458\u7f16\u7801\u6307\u5357](https://github.com/fuzhengwei/CodeGuide)\\n- [\ud83c\udf31 Spring \u624b\u64b8\u4e13\u680f - \u6613\u5b66\u3001\u597d\u5199\u3001\u80fd\u61c2\uff01](https://github.com/fuzhengwei/small-spring)\\n\\n## MySQL \u5b66\u4e60\\n\\n- MySQL \u4e13\u680f\\n - \u2b50\ufe0f \u2b50\ufe0f [\u7530\u87ba\u54e5\u7684MySQL\u4e13\u680f\uff0125\u7bc7\uff0c\u771f\u9999\uff01](https://mp.weixin.qq.com/s/G8fWBvZPy6yxAyggwwx1NA)\\n- \u8868\u7ed3\u6784\u8bbe\u8ba1\\n - \u2b50\ufe0f [\u63a8\u8350\u4e00\u6b3eSQL\u81ea\u52a8\u68c0\u67e5\u795e\u5668\uff0c\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3SQL\u51fa\u9519\u4e86\uff01](https://mp.weixin.qq.com/s/3yHSh7djpeeYZkajkTGFKg)\\n - \u2b50\ufe0f [21\u4e2aMySQL\u8868\u8bbe\u8ba1\u7684\u7ecf\u9a8c\u51c6\u5219](https://mp.weixin.qq.com/s/sSsZ-w6WzjA_DLZfnsxD2w)\\n - \u2b50\ufe0f [\u804a\u804a\u6570\u636e\u5e93\u5efa\u8868\u768415\u4e2a\u5c0f\u6280\u5de7](https://juejin.cn/post/7136126923851169823)\\n - \u2b50\ufe0f [\u6211\u7528\u8d77\u6765\u987a\u624b\u7684\u6570\u636e\u5e93\u8bbe\u8ba1\u5de5\u5177\uff0c\u8fd9\u6b21\u63a8\u8350\u7ed9\u5927\u5bb6\uff01](https://juejin.cn/post/6844904142733836301)\\n - \u2b50\ufe0f [\u6570\u636e\u5e93\u8868\u7ed3\u6784\u8bbe\u8ba1\u4e00\u70b9\u5fc3\u5f97\u548c\u7ecf\u9a8c](https://juejin.cn/post/7108525565157589005)\\n- \u6162 SQL \u4f18\u5316\\n - \u2b50\ufe0f [SQL\u4f18\u531613\u8fde\u95ee\uff0c\u6536\u85cf\u597d\uff01](https://mp.weixin.qq.com/s/SBKlxcTK_kZf0s5CRtIEBA)\\n - \u2b50\ufe0f [\u7f8e\u56e2\u9762\u8bd5\uff1a\u8fd9\u4e2a SQL \u8bed\u53e5\u52a0\u4e86\u54ea\u4e9b\u9501](https://mp.weixin.qq.com/s/Pi_SLqs3lwA7vWcT6lVv5g)\\n - \u2b50\ufe0f [\u4e13\u5751\u540c\u4e8b\u7684SQL \u5c31\u8fd9\u4e48\u5199\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b](https://mp.weixin.qq.com/s/8X-MuPgS-o53XZywqi_dmA)\\n - \u2b50\ufe0f [\u5b8c\u720690%\u7684\u6027\u80fd\u6bdb\u75c5\uff0c\u6570\u636e\u5e93\u4f18\u5316\u516b\u5927\u901a\u7528\u7edd\u62db\uff01](https://mp.weixin.qq.com/s/0_Arz-KO3UqJij1s4DjLNw)\\n - \u2b50\ufe0f [\u516c\u53f8\u65b0\u6765\u4e2a\u540c\u4e8b\uff0cMyBatis\u6279\u91cf\u63d2\u516510w\u6761\u6570\u636e\u4ec5\u75282\u79d2\uff0c\u62cd\u6848\u53eb\u7edd\uff01](https://mp.weixin.qq.com/s/3H9SD1dnAH0RoN-RoPXxgQ)\\n - \u2b50\ufe0f [\u4e00\u6b21\u663e\u8457\u7684\u5927\u8868\u67e5\u8be2\u4f18\u5316\uff0c\u4ece20s\u4f18\u5316\u5230500ms\uff0c\u67e5\u8be2\u5206\u79bbYYDS\uff01](https://mp.weixin.qq.com/s/OBjRKdGzwFM4PNrbMd7kIA)\\n - \u2b50\ufe0f [MySQL\u8868\u592a\u5927\uff0ccount(*)\u90fd\u80fd 502\uff0c\u600e\u4e48\u4f18\u5316](https://mp.weixin.qq.com/s/UxZRGO58kTiX5wUnuzMJ9Q)\\n - \u2b50\ufe0f [\u8fd915\u4e2aSQL\u4f18\u5316\u53e3\u8bc0\uff0c\u5de5\u4f5c\u9762\u8bd5\u90fd\u591f\u7528\u4e86](https://mp.weixin.qq.com/s/exPgSB0MNUnu0wMkThET1w)\\n - \u2b50\ufe0f [\u4fdd\u59c6\u7ea7\u6559\u7a0b\uff012 \u4e07\u5b57 + 30 \u5f20\u56fe\u641e\u61c2 MySQL \u662f\u600e\u4e48\u52a0\u884c\u7ea7\u9501\u7684](https://mp.weixin.qq.com/s/KegqAAvI4KxDffforTQqKA)\\n - \u2b50\ufe0f [\u4e24\u4e07\u5b57\u8be6\u89e3\uff01InnoDB\u9501\u4e13\u9898\uff01](https://mp.weixin.qq.com/s/DZbAq9fpPxElhfJCkY53GA)\\n - \u2b50\ufe0f [SQL\u4f18\u5316\u601d\u8def+\u7ecf\u5178\u6848\u4f8b\u5206\u6790](https://mp.weixin.qq.com/s/BbrLQWGYlkXiy6t4YANj0Q)\\n - [MySQL \u5355\u8868\u4e0d\u8981\u8d85\u8fc7 2000W \u884c\uff0c\u9760\u8c31\u5417](https://mp.weixin.qq.com/s/N3te_fVBeqhjIpl25N6kpA)\\n - \u2b50\ufe0f [explain | \u7d22\u5f15\u4f18\u5316\u7684\u8fd9\u628a\u7edd\u4e16\u597d\u5251\uff0c\u4f60\u771f\u7684\u4f1a\u7528\u5417](https://mp.weixin.qq.com/s/l3jJHIcqMzCcezbpboqyvQ)\\n - [MySQL \u4f18\u5316\uff1aExplain \u6267\u884c\u8ba1\u5212\u8be6\u89e3](https://mp.weixin.qq.com/s/EVzU7KW9d5_254Kg4LZYQQ)\\n - \u2b50\ufe0f [\u8fd911\u6761\u63a5\u53e3\u6027\u80fd\u4f18\u5316\u6280\u5de7\uff0c\u5229\u597d\u6bcf\u65e5\u7761\u7720](https://mp.weixin.qq.com/s/3jrf1GKBBbVzcvJxqYnx9Q)\\n - \u2b50\ufe0f [\u987a\u4e30\u5feb\u9012\uff1a\u8bf7\u7b7e\u6536MySQL\u7075\u9b42\u5341\u8fde](https://mp.weixin.qq.com/s/Y1Mh-99cgQWuCQ53wAxkUQ)\\n- MySQL \u4e8b\u52a1\\n - \u2b50\ufe0f [\u56fe\u89e3MySQL\u4e8b\u52a1\u5e95\u5c42\u539f\u7406](https://mp.weixin.qq.com/s/pkJb_9mddmdYaJZ8azHSsg)\\n - \u2b50\ufe0f [MySQL\u4e8b\u52a1\u768412\u8fde\u95ee\uff0c\u4f60\u9876\u5f97\u4e86\u561b](https://mp.weixin.qq.com/s/KEbuoasD_DOHRJiSqUgzzA)\\n- MySQL \u7d22\u5f15\\n - \u2b50\ufe0f [MySQL\u7d22\u5f1515\u8fde\u95ee\uff0c\u6297\u4f4f\uff01](https://mp.weixin.qq.com/s/d3iC_Iokrjdn392I0Y53Og)\\n - \u2b50\ufe0f [\u8ddf\u5927\u5bb6\u804a\u804a MySQL \u4e00\u884c\u8bb0\u5f55\u662f\u600e\u4e48\u5b58\u50a8\u7684](https://mp.weixin.qq.com/s/sqW51yqeAXcDs9r84UFP7A)\\n - \u2b50\ufe0f [\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u53ebB+\u6811](https://mp.weixin.qq.com/s/yvgB1a2o-m3_EBLePZM8cw)\\n- MySQL \u65e5\u5fd7\\n - \u2b50\ufe0f [\u804a\u804a MySQL \u65e5\u5fd7\uff0c\u597d\u725b\u7684\u8bbe\u8ba1\uff01](https://mp.weixin.qq.com/s/Tfbd-KiBgsZtkiuVc70BFA)\\n- \u5206\u5e93\u5206\u8868\\n - \u2b50\ufe0f [\u5206\u5e93\u5206\u8868\u7ecf\u517815\u8fde\u95ee](https://mp.weixin.qq.com/s/cZ7mUsCvBxmo1dzsPA3WjQ)\\n - \u2b50\ufe0f [\u9762\u8bd5\u5fc5\u5907\uff1a\u5206\u5e93\u5206\u8868\uff01](https://mp.weixin.qq.com/s/AjVl-0u3plmL9U77h0VVJw)\\n - \u2b50\ufe0f [\u518d\u6709\u4eba\u95ee\u4f60\u4ec0\u4e48\u662f\u5206\u5e93\u5206\u8868\uff0c\u76f4\u63a5\u628a\u8fd9\u7bc7\u6587\u7ae0\u53d1\u7ed9\u4ed6](https://mp.weixin.qq.com/s/wYXs7gsID8a9ahJKsWXJ6w)\\n- \u810f\u8bfb\u3001\u4e0d\u53ef\u91cd\u590d\u8bfb\u3001\u5e7b\u8bfb\\n - \u2b50\ufe0f [\u7f8e\u56e2\u4e09\u9762\uff1a\u4e00\u76f4\u8ffd\u95ee\u6211\uff0c MySQL \u5e7b\u8bfb\u88ab\u5f7b\u5e95\u89e3\u51b3\u4e86\u5417](https://mp.weixin.qq.com/s/VWEKgnOWVnufz5pfvRjUWw)\\n- \u6570\u636e\u4e00\u81f4\u6027\\n - \u2b50\ufe0f [\u6570\u636e\u5e93\u9501\u768412\u8fde\u95ee\uff0c\u6297\u4f4f\uff01](https://mp.weixin.qq.com/s/VEU5p85aTvyBKf2XP5QTSg)\\n - \u2b50\ufe0f [\u804a\u804aselect for update\u5230\u5e95\u52a0\u4e86\u4ec0\u4e48\u9501](https://mp.weixin.qq.com/s/shogIDEgXTtPVPFgsS8crw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/lyqvv-nA_PMUc-eBuCsNTA)\\n - \u2b50\ufe0f [\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01](https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg)\\n - \u2b50\ufe0f [\u804a\u804a\u5206\u5e03\u5f0f\u9501](https://juejin.cn/post/7104507830522085383)\\n- ORM \u76f8\u5173\\n - \u2b50\ufe0f [MyBatis \u8fde\u73af 20 \u95ee\uff0c\u4f60\u80fd\u7b54\u5bf9\u51e0\u4e2a](https://mp.weixin.qq.com/s/R2yqW3kfesK-T5oZR2Vl2w)\\n - \u2b50\ufe0f [MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01](https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ)\\n- [MySQL \u4e09\u4e07\u5b57\u7cbe\u534e\u603b\u7ed3 + \u9762\u8bd5100 \u95ee\uff0c\u548c\u9762\u8bd5\u5b98\u626f\u76ae\u7ef0\u7ef0\u6709\u4f59\uff08\u6536\u85cf\u7cfb\u5217\uff09](https://juejin.cn/post/6850037271233331208)\\n- [\u660e\u660e\u52a0\u4e86\u552f\u4e00\u7d22\u5f15\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u662f\u4ea7\u751f\u91cd\u590d\u6570\u636e](https://mp.weixin.qq.com/s/vRI-bFB4_IEaoCCQcMqZjw)\\n- [\u4e92\u8054\u7f51\u516c\u53f8\u90fd\u600e\u4e48\u5b9e\u73b0\u5206\u9875\u7684\uff0c\u62ff MySQL \u4f7f\u52b2Limit](https://mp.weixin.qq.com/s/O6sgYSpXBPwAA4Qcstj-BA)\\n- [MySQL\u593a\u547d66\u95ee](https://mp.weixin.qq.com/s/cdc1NCSkvAU4Urk2wVFDMw)\\n- [\u4e00\u6b21 MySQL \u8bef\u64cd\u4f5c\u5bfc\u81f4\u7684\u4e8b\u6545\uff0c\u300c\u9ad8\u53ef\u7528\u300d\u90fd\u9876\u4e0d\u4f4f\u4e86\uff01](https://mp.weixin.qq.com/s/L9qseWiHGfu1oAuKIhcUhw)\\n- [\u867e\u76ae\u4e8c\u9762\uff1aMySQL \u4e2d\u6709\u54ea\u4e9b\u9501\uff1f\u8868\u7ea7\u9501\u548c\u884c\u7ea7\u9501\u6709\u4ec0\u4e48\u533a\u522b](https://mp.weixin.qq.com/s/Inocu3vjMG4ivE19HrxR3g)\\n- [\u9762\u9738\u7bc7\uff1aMySQL\u516d\u5341\u516d\u95ee\uff0c\u4e24\u4e07\u5b57+\u4e94\u5341\u56fe\u8be6\u89e3\uff01](https://mp.weixin.qq.com/s/Jhh-_5ynu58EKPMignk5fA)\\n- [\u6162SQL\u5206\u6790\u4e0e\u4f18\u5316](https://juejin.cn/post/7101581835527782414)\\n- [Mysql\u6570\u636e\u5e93\u67e5\u8be2\u597d\u6162\uff0c\u9664\u4e86\u7d22\u5f15\uff0c\u8fd8\u80fd\u56e0\u4e3a\u4ec0\u4e48](https://mp.weixin.qq.com/s/r91hINCgCYJDNHLMeaba8Q)\\n- [MySQL \u4e3b\u4ece\uff0c6 \u5206\u949f\u5e26\u4f60\u638c\u63e1](https://mp.weixin.qq.com/s/8OOSyFB9pzoBMH73ey7YmQ)\\n- [\u5927\u5382\u9762\u8bd5\u9898\uff1a\u65e5\u5e38\u5de5\u4f5c\u5982\u4f55\u505aMySQL\u4f18\u5316](https://mp.weixin.qq.com/s/N08tFkGyXtmBSN0nS6S6UA)\\n- [Mysql\u5b8c\u7ed3\u6c47\u603b\u7bc7\uff0818W\u5b57\u9001\u7ed9\u5927\u5bb6\uff09\uff0c\u5b8c\u7ed3\u6492\u82b1](https://mp.weixin.qq.com/s/i8SHizPrBMQ2GIhQP7ozRw)\\n- [\u9762\u8bd5\u5b98\uff1a\u4ec0\u4e48\u662fMySQL \u4e8b\u52a1\u4e0e MVCC \u539f\u7406\uff1f](https://juejin.cn/post/7081456994413969445)\\n\\n## Golang \u5b66\u4e60\\n\\n- Golang \u5b66\u4e60\u8def\u7ebf\\n - \u2b50\ufe0f [Go\u540e\u7aef\u5f00\u53d1\u6210\u957f\u8def\u7ebf](https://github.com/xiaobaiTech/golangFamily/blob/main/README.md)\\n - \u2b50\ufe0f [\u300aGo\u5b66\u4e60\u8def\u7ebf\u56fe\u300b\u5e26\u4f60\u5c11\u8d70\u5f2f\u8def\uff0cLet\'s Go \uff01](https://juejin.cn/post/7119123646471208968)\\n - \u2b50\ufe0f [\u6700\u5168\u7684Go\u8d44\u6599\u6c47\u603b\u548c\u6700\u8d70\u5fc3\u7684\u5b66Go\u5efa\u8bae](https://juejin.cn/post/7176518080674136121)\\n - \u2b50\ufe0f [\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae](https://juejin.cn/post/7147939014870302756)\\n - [\u6211\u809d\u4e86\u4e09\u4e2a\u6708\uff0c\u4e3a\u4f60\u5199\u51fa\u4e86GO\u6838\u5fc3\u624b\u518c](https://juejin.cn/post/7035966042857799687)\\n - [Go \u5b66\u4e60\u8def\u7ebf\uff082022\uff09](https://juejin.cn/post/7061980386640789540)\\n - [Golang\u5b66\u4e60\u624b\u518c\u4e4b\uff1a\u5e26\u4f6021\u5468\u641e\u5b9aGo\u8bed\u8a00](https://www.bilibili.com/video/BV16E411H7og)\\n - [Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU)\\n- Golang \u8fdb\u9636\\n - \u2b50\ufe0f [Golang \u6cdb\u578b\u4ecb\u7ecd](https://github.com/danielfurman/presentations/blob/master/lets-go-generic/README.md)\\n - \u2b50\ufe0f [GopherCon UK 2018- Florin Patan - Production Ready Go Service in 30 Minutes](https://www.bilibili.com/video/BV1ry4y1y7V2)\\n - \u2b50\ufe0f [\u4f5c\u4e3aGopher\uff0c\u4f60\u77e5\u9053Go\u7684\u6ce8\u91ca\u5373\u6587\u6863\u5e94\u8be5\u600e\u4e48\u5199\u5417](https://mp.weixin.qq.com/s/r4IWY6bzKph2QvxrKZszPA)\\n - \u2b50\ufe0f [31\u4e2a\uff01Golang\u5e38\u7528\u5de5\u5177\u6765\u5566\uff08\u5efa\u8bae\u6536\u85cf\uff09](https://mp.weixin.qq.com/s/Ne0uir1hpMokBUItntkfvw)\\n - \u2b50\ufe0f [Golang\u4f9d\u8d56\u6ce8\u5165\u63d0\u5347\u5f00\u53d1\u6548\u7387\uff01](https://mp.weixin.qq.com/s/Mj-EqwYWZBMr8XNIHxUqDA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u4ece0\u52301\u5b9e\u73b0\u6700\u7b80\u5355\u7684\u6570\u636e\u5e93\uff01](https://mp.weixin.qq.com/s/VFS4TWi3OpeAegScZ4cJRw)\\n - \u2b50\ufe0f [\u5fc5\u64b8\u7cfb\u5217\uff01Go\u53e6\u5916\u51e0\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7\u6c47\u603b](https://mp.weixin.qq.com/s/--ciEa-Oj0NEUxlp1Af_aQ)\\n - \u2b50\ufe0f [\u6765\u4e86\uff01Go\u76842\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7](https://mp.weixin.qq.com/s/8HNZQrQ2oqMB2fAYbmH2Ow)\\n - \u2b50\ufe0f [3\u79cd\u65b9\u5f0f\uff01Go Error\u5904\u7406\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/Zb5zGOy_mdalUQ_Qy0HngQ)\\n - \u2b50\ufe0f [Go\u7ec4\u4ef6\uff1acontext\u5b66\u4e60\u7b14\u8bb0\uff01](https://mp.weixin.qq.com/s/OCpVRwtiphFRZgu9zdae5g)\\n - \u2b50\ufe0f [\u4e0d\u5f97\u4e0d\u77e5\u9053\u7684Golang\u4e4bsync.Map\u89e3\u8bfb\uff01](https://mp.weixin.qq.com/s/NkSyv7iDSZsLhMUgAi-r4w)\\n - \u2b50\ufe0f [\u8d85\u5168\u907f\u5751\u6307\u5357: \u76d8\u70b9 Go \u7684\u5e38\u89c1\u5178\u578b\u9519\u8bef](https://mp.weixin.qq.com/s/XHbfPtUzkUTGF06Ao4jQYA)\\n - \u2b50\ufe0f [\u9e45\u5382\u540e\u53f0\u5927\u4f6c\u6559\u4f60Go\u5185\u5b58\u7ba1\u7406\uff01](https://mp.weixin.qq.com/s/56tth8PSquB1eR5-1XaDWA)\\n - \u2b50\ufe0f [\u5168\u9762\u89e3\u8bfb\uff01Golang\u4e2d\u6cdb\u578b\u7684\u4f7f\u7528](https://mp.weixin.qq.com/s/QBZ1dp0XIqMo24vVFYf1fA)\\n - \u2b50\ufe0f [\u8d85\u5e72\u8d27\uff01\u5f7b\u5e95\u641e\u61c2Golang\u5185\u5b58\u7ba1\u7406\u548c\u5783\u573e\u56de\u6536](https://mp.weixin.qq.com/s/niLk_n9Yp-iyl_RIie3Umw)\\n - \u2b50\ufe0f [\u5173\u4e8eGo\u5e76\u53d1\u7f16\u7a0b\uff0c\u4f60\u4e0d\u5f97\u4e0d\u77e5\u7684\u201c\u5de6\u8180\u53f3\u81c2\u201d\u2014\u2014\u5e76\u53d1\u4e0e\u901a\u9053\uff01](https://mp.weixin.qq.com/s/BPcRI0BHBLmuYfzvP10Wvw)\\n - \u2b50\ufe0f [\u5b83\u6765\u4e86\uff0c\u5173\u4e8eGolang\u5e76\u53d1\u7f16\u7a0b\u7684\u8d85\u8be6\u7ec6\u6559\u7a0b\uff01](https://mp.weixin.qq.com/s/aoR_69JMBN5ZM10DKqRCyQ)\\n - \u2b50\ufe0f [\u901a\u4fd7\u6613\u61c2\uff01\u56fe\u89e3Go\u534f\u7a0b\u539f\u7406\u53ca\u5b9e\u6218](https://mp.weixin.qq.com/s/POZGQXsYu5aWXvu29vSM8g)\\n - \u2b50\ufe0f [\u62d2\u7edd\u5343\u7bc7\u4e00\u5f8b\uff0c\u8fd9\u5957Go\u9519\u8bef\u5904\u7406\u7684\u5b8c\u6574\u89e3\u51b3\u65b9\u6848\u503c\u5f97\u4e00\u770b\uff01](https://mp.weixin.qq.com/s/DpCFUAYpvMzd6138Yp_JUA)\\n - \u2b50\ufe0f [go\u8bed\u8a00\u6700\u5168\u4f18\u5316\u6280\u5de7\u603b\u7ed3\uff0c\u503c\u5f97\u6536\u85cf\uff01](https://mp.weixin.qq.com/s/_VGaV8ef65h9goxxfWejtQ)\\n - \u2b50\ufe0f [\u518d\u4e0dGo\u5c31\u6765\u4e0d\u53ca\u4e86\uff01Go\u9ad8\u6027\u80fd\u7f16\u7a0b\u6280\u6cd5\u89e3\u8bfb](https://mp.weixin.qq.com/s/fXKSr8GXaYxG1WCrLIgneg)\\n - \u2b50\ufe0f [\u817e\u8baf 13 \u5e74\uff0c\u6211\u6240\u603b\u7ed3\u7684Code Review\u7ec8\u6781\u5927\u6cd5](https://mp.weixin.qq.com/s/XrJVpErmP8wIjd_byCCmhA)\\n - \u2b50\ufe0f [Go\u4e0eC\u7684\u6865\u6881\uff1aCGO\u5165\u95e8\u5256\u6790\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/AMv5IVBPU2lAY_qUwskk4g)\\n - \u2b50\ufe0f [Golang \u6c47\u7f16\u5165\u95e8\u77e5\u8bc6\u603b\u7ed3](https://mp.weixin.qq.com/s/tN27osC6K0NM-Laj9MbtsA)\\n - \u2b50\ufe0f [Golang\u9ad8\u6027\u80fd\u7f16\u7a0b\u5b9e\u8df5](https://mp.weixin.qq.com/s/VMzhyySny60zABnxlzlVjQ)\\n - \u2b50\ufe0f [\u6572\u9ed1\u677f\uff01\u9e45\u5382\u7a0b\u5e8f\u5458\u9762\u8bd5\u4e5f\u8003\u4e86\u8fd9\u4e9b\u7b97\u6cd5\u77e5\u8bc6](https://mp.weixin.qq.com/s/GwXQwJUdBi1UHdh2Q8FBMw)\\n - \u2b50\ufe0f [Java\u4e0eGo\u5230\u5e95\u5dee\u522b\u5728\u54ea\uff0c\u8c01\u8981\u88ab\u65f6\u4ee3\u629b\u5f03](https://mp.weixin.qq.com/s/JkpzM06IWNb11wUaJWJn8Q)\\n - \u2b50\ufe0f [\u770b\u4e86\u8fd9\u7bc7\u4f60\u4f1a\u53d1\u73b0\uff0c\u4f60\u662f\u61c2Go\u5185\u5b58\u5206\u914d\u7684](https://mp.weixin.qq.com/s/T4tk-sckA1oNcWIvp27MMA)\\n - \u2b50\ufe0f [Go \u5b9e\u6218\u6280\u5de7\uff1a\u907f\u514d\u5185\u5b58\u5206\u914d\u7684\u5c0f\u6280\u5de7](https://mp.weixin.qq.com/s/SLouDICt3HABv_wh-sSqKw)\\n - \u2b50\ufe0f [\u901a\u8fc7\u4e00\u4e2a\u4f8b\u5b50\u8ba9\u4f60\u5f7b\u5e95\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f](https://mp.weixin.qq.com/s/aIuta8Lr0govruPTgglw2w)\\n - \u2b50\ufe0f [Go\u7684\u65b9\u6cd5\u63a5\u6536\u8005\uff1a\u503c\u63a5\u6536\u8005\u4e0e\u6307\u9488\u63a5\u6536\u8005](https://mp.weixin.qq.com/s/_duDs0oHc_z_p--3OoIfVw)\\n - \u2b50\ufe0f [\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303](https://juejin.cn/post/7157594175846744071)\\n - \u2b50\ufe0f [\u7a0b\u5e8f\u5458\u5e94\u8be5\u9075\u5b88\u7684\u7f16\u7a0b\u539f\u5219(\u4e0d\u6b62Gopher\u54e6)](https://mp.weixin.qq.com/s/94thx36Ao2PYQ-8Cbto-wQ)\\n - \u2b50\ufe0f [\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566](https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ)\\n - \u2b50\ufe0f [Go 1.18\u65b0\u7279\u6027\u524d\u77bb\uff1a\u539f\u751f\u652f\u6301Fuzzing\u6d4b\u8bd5](https://mp.weixin.qq.com/s/UqjSA2i3s1VoLFACt_EL2A)\\n - \u2b50\ufe0f [\u5982\u4f55\u5e94\u5bf9\u4e0d\u65ad\u81a8\u80c0\u7684\u63a5\u53e3](https://mp.weixin.qq.com/s/PBTP4vnwEXtrtsHdq0oL0g)\\n - \u2b50\ufe0f [\u6bcf\u4e2a gopher \u90fd\u9700\u8981\u4e86\u89e3\u7684 Go AST](https://mp.weixin.qq.com/s/pCcNtUykXAwb-BN_prPGpA)\\n - \u2b50\ufe0f [\u4e00\u6587\u641e\u61c2Go\u6807\u51c6\u5e93context\u5305](https://mp.weixin.qq.com/s/xzNqpRbIvoJygSWeQJFjTw)\\n - \u2b50\ufe0f [\u4f7f\u7528\u53cd\u5c04\u64cd\u4f5cchannel](https://mp.weixin.qq.com/s/E4lT4SuWKIlCZd60i7vigQ)\\n - \u2b50\ufe0f [Go 1.20\u65b0\u7279\u6027\u524d\u77bb](https://mp.weixin.qq.com/s/z75HDSlX0PLCnvL5kAcSDw)\\n - \u2b50\ufe0f [Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c](https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg)\\n - \u2b50\ufe0f [2022\u5e74Go\u8bed\u8a00\u76d8\u70b9\uff1a\u6cdb\u578b\u843d\u5730\uff0c\u65e0\u8da3\u5f88\u597d\uff0c\u7a33\u5b9a\u4e3a\u738b](https://mp.weixin.qq.com/s/MRBEJHZBMS9s0w7UhseQWA)\\n - \u2b50\ufe0f [Go1.20 \u65b0\u7279\u6027\uff1acontext\u652f\u6301\u81ea\u5b9a\u4e49\u53d6\u6d88\u539f\u56e0](https://mp.weixin.qq.com/s/HbFVODpDEzEZ047kv-LYbg)\\n - \u2b50\ufe0f [\u804a\u804aGo\u4e0eTLS 1.3](https://mp.weixin.qq.com/s/NtBzM8l54HRVSpapKR_0sg)\\n - \u2b50\ufe0f [\u5c06Roaring Bitmap\u5e8f\u5217\u5316\u4e3aJSON](https://mp.weixin.qq.com/s/CFwiFw00ah0rfdZyv_ppxw)\\n - \u2b50\ufe0f [\u4e07\u5b57\u957f\u6587\u544a\u8bc9\u4f60Go 1.20\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316](https://mp.weixin.qq.com/s/Y-JxePxv9XlaX_UASlWSvQ)\\n - \u2b50\ufe0f [\u4e00\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u5224\u65adGo\u63a5\u53e3\u53d8\u91cf\u662f\u5426\u76f8\u7b49](https://mp.weixin.qq.com/s/6_ygmyd64LP7rlkrOh-kRQ)\\n - \u2b50\ufe0f [\u5c0f\u5382\u5185\u90e8\u79c1\u6709Go module\u62c9\u53d6\u65b9\u68483](https://mp.weixin.qq.com/s/WDw-Y8Rp4VxAa2iPKRnKKg)\\n - \u2b50\ufe0f [Go\u662f\u4e00\u95e8\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8bed\u8a00\u5417](https://mp.weixin.qq.com/s/r5gIVtyBWtD7UQncK_JPNQ)\\n - \u2b50\ufe0f [\u4e00\u6587\u641e\u61c2Go subtest](https://mp.weixin.qq.com/s/5zoNwCWnNNunrDtu6cokqg)\\n - \u2b50\ufe0f [\u804a\u804agodoc\u3001go doc\u4e0epkgsite](https://mp.weixin.qq.com/s/ypK-2wGHGj9_n4o8y-clXg)\\n - \u2b50\ufe0f [\u804a\u804aGo\u8bed\u8a00\u7684\u5168\u5c40\u53d8\u91cf](https://mp.weixin.qq.com/s/MI9x4YOAhbtS-xQtOS-K_A)\\n - \u2b50\ufe0f [Go\u5f00\u53d1\u547d\u4ee4\u884c\u7a0b\u5e8f\u6307\u5357](https://mp.weixin.qq.com/s/8yLt0Sh18VF5ApTcuxV-Sg)\\n - \u2b50\ufe0f [\u4f7f\u7528go test\u6846\u67b6\u9a71\u52a8\u7684\u81ea\u52a8\u5316\u6d4b\u8bd5](https://mp.weixin.qq.com/s/RKshV1hu61wabq4am906PA)\\n - \u2b50\ufe0f [\u4e00\u6587\u544a\u8bc9\u4f60\u54ea\u4e9bmap element\u7c7b\u578b\u652f\u6301\u5c31\u5730\u66f4\u65b0](https://mp.weixin.qq.com/s/0TnAPFib82KC-BIL-uhMWw)\\n - \u2b50\ufe0f [\u7406\u89e3unsafe-assume-no-moving-gc\u5305](https://mp.weixin.qq.com/s/EHSR-GFPJy5RzVDgcvoTog)\\n - \u2b50\ufe0f [Go 1.21\u65b0\u7279\u6027\u524d\u77bb](https://mp.weixin.qq.com/s/PwSJQM7WmJeLnDDbCr78hg)\\n - \u2b50\ufe0f [Go\uff1a\u503c\u4e0e\u6307\u9488](https://mp.weixin.qq.com/s/FcuXy0Vqp6aczKpNpQeFrA)\\n - \u2b50\ufe0f [Go\u9879\u76ee\u7ec4\u7ec7\uff1a\u5728\u5355\u4e00repo\u4e2d\u7ba1\u7406\u591a\u4e2aGo module\u6307\u5357](https://mp.weixin.qq.com/s/IEsgLu5PFwcKppUWABA6-Q)\\n - \u2b50\ufe0f [\u4e00\u6587\u641e\u61c2Go\u9519\u8bef\u94fe](https://mp.weixin.qq.com/s/D_CVrPzjP3O81EpFqLoynQ)\\n - \u2b50\ufe0f [Go\u4e0e\u795e\u7ecf\u7f51\u7edc\uff1a\u5f20\u91cf\u8fd0\u7b97](https://mp.weixin.qq.com/s/18SbYmKnUbNR59gFlKEULQ)\\n - \u2b50\ufe0f [\u804a\u804aGo\u8bed\u8a00\u7684\u63a7\u5236\u8bed\u53e5](https://mp.weixin.qq.com/s/2P9_nyrdZ3JqlKRIR8--7g)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u53cd\u5c04\u7f16\u7a0b\u6307\u5357](https://mp.weixin.qq.com/s/J3hIbUaAp55l8QDuJYUQOg)\\n - \u2b50\ufe0f [The State Of Go 2023](https://mp.weixin.qq.com/s/-EAH8jjj4uy1LCr_9C1ghg)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5305\u8bbe\u8ba1\u6307\u5357](https://mp.weixin.qq.com/s/_xA6bhKTm543i3QV8EZMSg)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u7c7b\u578b](https://mp.weixin.qq.com/s/dyQ3WBMPF2DyaI8Dlgy8Gw)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u5185\u5b58\u7ba1\u7406](https://mp.weixin.qq.com/s/JWg8yW_lDiZQCk6bKZ5TeA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784](https://mp.weixin.qq.com/s/WgeTzhP4T0AAjFssHz36UA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u64cd\u4f5c](https://mp.weixin.qq.com/s/Lxxfeqn70rfmnrGvgrxevA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6269\u5c55compute\u5305](https://mp.weixin.qq.com/s/xBpA36wpmbO85LIHlaTXBg)\\n - \u2b50\ufe0f [\u4f7f\u7528testify\u5305\u8f85\u52a9Go\u6d4b\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/LppX2mvbkgsLKkqqudehQA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u8bfb\u5199Parquet\u6587\u4ef6](https://mp.weixin.qq.com/s/PcNpQJcKuWpZgYrKmVvRLQ)\\n - \u2b50\ufe0f [Gopher Daily\u6539\u7248\u4e86](https://mp.weixin.qq.com/s/4UI6gTx7ZWRPhGbm4YGGCQ)\\n - \u2b50\ufe0f [Go\u9879\u76ee\u521d\u59cb\u5316\u4e0d\u518d\u56f0\u6270\u4f60\uff1agonew\u5168\u65b9\u4f4d\u89e3\u6790](https://mp.weixin.qq.com/s/ZaDNxyewtrSuiLRF62ipYg)\\n - \u2b50\ufe0f [Go 1.21\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316](https://mp.weixin.qq.com/s/3bfD9LPBB5zA9VxAv920Cw)\\n - \u2b50\ufe0f [\u7f16\u8bd1Go\u5e94\u7528\u7684\u9ed1\u76d2\u6311\u6218\uff1a\u65e0\u6e90\u7801\u53ea\u6709.a\u6587\u4ef6\uff0c\u4f60\u80fd\u641e\u5b9a\u5417](https://mp.weixin.qq.com/s/snVLySXv4E5xMlbD153FcQ)\\n - \u2b50\ufe0f [slog\u6b63\u5f0f\u7248\u6765\u4e86\uff1aGo\u65e5\u5fd7\u8bb0\u5f55\u65b0\u9009\u62e9\uff01](https://mp.weixin.qq.com/s/4HN0-m8AlzSmDCuF9hYU4Q)\\n - \u2b50\ufe0f [slog\u5b9e\u6218\uff1a\u6587\u4ef6\u65e5\u5fd7\u3001\u8f6e\u8f6c\u4e0ekafka\u96c6\u6210](https://mp.weixin.qq.com/s/7jS6E6d578QQIxvWKSux1Q)\\n - \u2b50\ufe0f [\u804a\u804aGo\u8bed\u8a00\u7684\u5411\u524d\u517c\u5bb9\u6027\u548ctoolchain\u89c4\u5219](https://mp.weixin.qq.com/s/NzUXgDd7qPMK4LxIopcFLA)\\n - \u2b50\ufe0f [\u4f7f\u7528Go\u548cWebRTC data channel\u5b9e\u73b0\u7aef\u5230\u7aef\u5b9e\u65f6\u901a\u4fe1](https://mp.weixin.qq.com/s/vY76-34hm-ujgaGTS_lDaQ)\\n - \u2b50\ufe0f [\u4e86\u89e3go\u5728\u534f\u7a0b\u8c03\u5ea6\u4e0a\u7684\u6539\u8fdb](https://mp.weixin.qq.com/s/2ibzE46UVnO_YNtugikpPQ)\\n - \u2b50\ufe0f [\u4e00\u7ad9\u5f0fGolang\u5185\u5b58\u6d17\u9ad3\u7ecf\\\\[Go\u4e09\u5173\u5178\u85cf\u7248\\\\]](https://mp.weixin.qq.com/s/J3Sfo9u63aTG6IndFP-BnQ)\\n - \u2b50\ufe0f [\u6df1\u5165\u7406\u89e3Golang\u534f\u7a0b\u8c03\u5ea6GPM\\\\[Go\u4e09\u5173\u5178\u85cf\u7248\\\\]](https://mp.weixin.qq.com/s/9MfIdUdBZmfqbUYT_xrB8A)\\n - \u2b50\ufe0f [Golang\u4e09\u8272\u6807\u8bb0\u6df7\u5408\u5199\u5c4f\u969cGC\u6a21\u5f0f\u5168\u5206\u6790\\\\[Go\u4e09\u5173\u5178\u85cf\u7248\\\\]](https://mp.weixin.qq.com/s/up1MHqYW_v_C4P6AY-sW3w)\\n - \u2b50\ufe0f [\u4e3a\u4ec0\u4e48\u6cdb\u578b\u4f7f\u4f60\u7684\u7a0b\u5e8f\u53d8\u6162](https://mp.weixin.qq.com/s/veu5W0BFmLIZ-yvs39NdUw)\\n - \u2b50\ufe0f [Go error \u5904\u7406\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/XojOIIZfKm_wXul9eSU1tQ)\\n - \u2b50\ufe0f [\u5f00\u901a\u4e2a\u4eba\u535a\u5ba2\u5566\uff01\u9644\u5e26\u5168\u90e8 Hexo + Nginx + Git \u6559\u7a0b](https://mp.weixin.qq.com/s/mrAwE-go0vNSwrJ4g4L9Cg)\\n - \u2b50\ufe0f [\u975e\u5e7f\u544a| DDD \u5230\u5e95\u662f\u94f6\u5f39\u8fd8\u662f\u5783\u573e](https://mp.weixin.qq.com/s/gMjQmNvEi1o_iOFt2z7flg)\\n - \u2b50\ufe0f [\u7ed9\u9762\u8bd5\u5b98\u4e00\u70b9\u5c0f\u5c0f\u7684 gpt \u9707\u64bc](https://mp.weixin.qq.com/s/yEbqNo9UfPTCxL5-RDvlPw)\\n - \u2b50\ufe0f [Go \u8bed\u8a00 GC \u5206\u6790](https://mp.weixin.qq.com/s/AaHk-yg8D4atbO-zVAvhKQ)\\n - \u2b50\ufe0f [\u52a8\u6001\u8c03\u6574 GOGC \u4f18\u5316 Go \u7684 GC \u6807\u8bb0 CPU \u5360\u7528](https://mp.weixin.qq.com/s/XR1KAeCW930i-Qxv6N2kaA)\\n - \u2b50\ufe0f [\u804a\u804a rust trait](https://mp.weixin.qq.com/s/T7IBCimzmWI07dHD8NA-Qw)\\n - \u2b50\ufe0f [Gopher \u9700\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7ed3\u6784\u4f53\u9a9a\u64cd\u4f5c](https://mp.weixin.qq.com/s/A4m1xlFwh9pD0qy3p7ItSA)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u7aef\u5f00\u53d1\uff0c\u8bf7\u7262\u8bb0\u8fd9\u51e0\u6761](https://mp.weixin.qq.com/s/sYQ0vqKiIWaUCha740Dxtw)\\n - \u2b50\ufe0f [\u503c\u5f97\u6536\u85cf\u8c03\u5ea6\u5668\u7cfb\u5217\uff1a\u5077\u5929\u6362\u65e5 \u2014 g0 \u6808\u548c\u7528\u6237\u6808\u5982\u4f55\u5b8c\u6210\u5207\u6362\uff1f\uff08\u56db\uff09](https://mp.weixin.qq.com/s/8xTtSoLvAcE1u_jWw9I-Eg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff081\uff09\u2014\u2014\u8c03\u5ea6\u7684\u672c\u8d28](https://mp.weixin.qq.com/s/5E5V56wazp5gs9lrLvtopA)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff082\uff09\u2014\u2014 \u8ff7\u60d1\u7684 goroutine \u6267\u884c\u987a\u5e8f](https://mp.weixin.qq.com/s/WWfm7Ui7g_gGlb8XkIZigg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff083\uff09\u2014\u2014 \u5982\u4f55\u7528\u6c47\u7f16\u6253\u540c\u4e8b\u7684\u8138](https://mp.weixin.qq.com/s/2Y3qPkysRLaWDcIyLOerZg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0810\uff09\u2014\u2014 \u5982\u4f55\u7ed9 Go \u63d0\u6027\u80fd\u4f18\u5316\u7684 pr](https://mp.weixin.qq.com/s/8R9ZLa0Xlscw6qhl-5g2Cg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0811\uff09\u2014\u2014 \u4ece map \u7684 extra \u5b57\u6bb5\u8c08\u8d77](https://mp.weixin.qq.com/s/SGv5vuh9aU2mqViC4Kj0YQ)\\n - \u2b50\ufe0f [\u300e\u66f9\u5927\u5e26\u6211\u5b66 Go \u300f\u7cfb\u5217\u6587\u7ae0\u6c47\u603b](https://mp.weixin.qq.com/s/RmEtL869Sd-FjB_73tFSaw)\\n - \u2b50\ufe0f [Go map \u7adf\u7136\u4e5f\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f](https://mp.weixin.qq.com/s/IEunJaXMfrOfPmounloYig)\\n - \u2b50\ufe0f [\u5185\u8054\u51fd\u6570\u548c\u7f16\u8bd1\u5668\u5bf9Go\u4ee3\u7801\u7684\u4f18\u5316](https://mp.weixin.qq.com/s/ujWkFUqJiY3DCWeKZeS8uw)\\n - \u2b50\ufe0f [\u6df1\u5ea6\u9605\u8bfb\u4e4b\u300a100 Go Mistakes and How to Avoid Them\u300b](https://mp.weixin.qq.com/s/VnF7YrXTaK5MASacXgzRhw)\\n - \u2b50\ufe0f [kafka producer \u5728 aws \u53c8\u6302\u4e86](https://mp.weixin.qq.com/s/U5Okkf9FzLxxSYcsUI2DZg)\\n - \u2b50\ufe0f [\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e00)](https://mp.weixin.qq.com/s/Bl3UrbgiMMsP3gxm6vnDtA)\\n - \u2b50\ufe0f [\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e8c)](https://mp.weixin.qq.com/s/j59HejHj5hzKovfsGdrIdg)\\n - \u2b50\ufe0f [Gopher \u5e94\u8be5\u8bb0\u4f4f\u8fd9 10 \u4e2a\u547d\u4ee4](https://mp.weixin.qq.com/s/UIeIBtC9MZJh3w-EphWHiA)\\n - \u2b50\ufe0f [\u6709\u8da3\u7684 Go HttpClient \u8d85\u65f6\u673a\u5236](https://mp.weixin.qq.com/s/HPzoclfCB3UxLScXm4J83w)\\n - \u2b50\ufe0f [\u6211\u5982\u4f55\u7528\u4e24\u884c\u4ee3\u7801\u8282\u7701\u4e8630%\u7684CPU](https://mp.weixin.qq.com/s/2V3VSsAJH5haWqdvVJ9e8g)\\n - \u2b50\ufe0f [Go 1.19 \u4e2datomic\u5305\u7684\u65b0\u53d8\u5316](https://mp.weixin.qq.com/s/YzkPHkBCdqv-Z3APSPaDrQ)\\n - \u2b50\ufe0f [\u7b49\u7b49\uff0c \u600e\u4e48\u4f7f\u7528 SetMemoryLimit](https://mp.weixin.qq.com/s/EIuM073G7VV1rIsnTXWyEw)\\n - \u2b50\ufe0f [\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/sSwXgrHvQcjSuiy9bA8d_g)\\n - \u2b50\ufe0f [\u554a\u54c8\uff0c\u4e00\u9053\u6709\u8da3\u7684Go\u5e76\u53d1\u9898](https://mp.weixin.qq.com/s/S4FDRve0YPtRUixY4kPqAQ)\\n - \u2b50\ufe0f [\u8fd8\u548b\u4f18\u5316\uff1f\u6211\u662f\u8bf4Go\u7a0b\u5e8f](https://mp.weixin.qq.com/s/VtDR2uJ8SQ2jiIS2o2uyfA)\\n - \u2b50\ufe0f [\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e00\u7bc7\uff1a\u7efc\u8ff0](https://mp.weixin.qq.com/s/chPDWyBibBlvcEKKENFYGg)\\n - \u2b50\ufe0f [\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e8c\u7bc7\uff1aGo\u8bed\u8a00\u4e2d\u7684\u5e94\u7528](https://mp.weixin.qq.com/s/hXfZImBUYTBe2JvhBD-OmA)\\n - \u2b50\ufe0f [\u4e00\u4e9b\u5173\u4e8e\u65f6\u95f4\u548c\u5b9a\u65f6\u4efb\u52a1\u7684\u5e93](https://mp.weixin.qq.com/s/EAk_LdlfYGwaiDDj9CgqHA)\\n - \u2b50\ufe0f [\u6ca1\u7528\u5fae\u670d\u52a1\uff0cShopify\u7684\u5355\u4f53\u7a0b\u5e8f\u5c45\u7136\u652f\u6491\u4e86127\u4e07/\u79d2\u7684\u8bf7\u6c42](https://mp.weixin.qq.com/s/kSZieI3zE9RgvfAqEQEhbw)\\n - \u2b50\ufe0f [\u673a\u667a\uff01\u751f\u62a0\u5185\u5efamap\u7684\u54c8\u5e0c\u51fd\u6570](https://mp.weixin.qq.com/s/8omJxT10c5UX6Neua9dLjA)\\n - \u2b50\ufe0f [\u50cf\u95ea\u7535\u4e00\u6837\u5feb\u901f\u626b\u63cf\u5168\u7f51\u7684IP\u5730\u5740](https://mp.weixin.qq.com/s/KTmMWyULYMS0LFsg69zwZg)\\n - \u2b50\ufe0f [\u6bcf\u79d2\u767e\u4e07\u7ea7\u522b\u7684\u5305\u4f20\u8f93\uff0c\u6211\u662f\u8bf4CPU\u4f7f\u7528\u7387\u51e0\u4e4e\u4e3a\u96f6\u90a3\u79cd](https://mp.weixin.qq.com/s/KzMmzd2ZfAJwtHt4s-V0zQ)\\n - \u2b50\ufe0f [\u4f7f\u7528\u5e95\u5c42\u7684syscall.Socket\u5b9e\u73b0\u7f51\u7edc\u7f16\u7a0b](https://mp.weixin.qq.com/s/sVLOFBdL6a_1pOBFP8pSfw)\\n - \u2b50\ufe0f [\u4f7f\u7528Go\u8bed\u8a00\u5b9e\u73b0ping\u5de5\u5177](https://mp.weixin.qq.com/s/uwdL6QjLIG6SbMKeb2HOAw)\\n - \u2b50\ufe0f [\u51e0\u79cd\u4f7f\u7528Go\u53d1\u9001IP\u5305\u7684\u65b9\u6cd5](https://mp.weixin.qq.com/s/1Nv5_b2jM9uiG0tEu1Pr1A)\\n - \u2b50\ufe0f [\u600e\u4e48\u963b\u6b62\u4e00\u4e2aGo\u7a0b\u5e8f\u9000\u51fa](https://mp.weixin.qq.com/s/C2AmKZjg9CyiIDxyU0-b1Q)\\n - \u2b50\ufe0f [Go 1.21\u4e2d sync.Once\u7684\u65b0\u6269\u5c55](https://mp.weixin.qq.com/s/SFXe1bdBu0bLuHoGEFTz8g)\\n - \u2b50\ufe0f [\u6539\u9020! \u8ba9 sync.Map \u652f\u6301\u6cdb\u578b](https://mp.weixin.qq.com/s/mKraN_3xUfy6Bm-SswHEbw)\\n - \u2b50\ufe0f [\u4e00\u4e2a\u6cdb\u578b\u7684\u6709\u5e8fGo Map\u5b9e\u73b0](https://mp.weixin.qq.com/s/26PlfCFLc9Giuv_7nmgxjg)\\n - \u2b50\ufe0f [MPTCP: \u4e00\u4e2a\u5728 Go 1.21\u4e2d\u7684\u88ab\u5ffd\u7565\u7684\u65b0\u7279\u6027](https://mp.weixin.qq.com/s/aC7omLYJ6Anm9f-8b4qYAg)\\n - \u2b50\ufe0f [Go\u53ef\u4ee5\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f46\u7edd\u4e0d\u662f\u300a\u8bbe\u8ba1\u6a21\u5f0f\u300b\u4e2d\u7684\u90a3\u6837](https://mp.weixin.qq.com/s/Sv-SXDYxea_K_TtiI_CjTw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5de5\u5382\u6a21\u5f0f](https://mp.weixin.qq.com/s/325iHPhAQicbSN6-pb05rw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5efa\u9020\u8005\u6a21\u5f0f](https://mp.weixin.qq.com/s/jXaCLkagT-cKbVHConcadg)\\n - \u2b50\ufe0f [\u5355\u4f8b\u6a21\u5f0f\u548c\u60f0\u6027\u521d\u59cb\u5316\u6a21\u5f0f](https://mp.weixin.qq.com/s/NQOmlQfFpM-asN9I9CeVkw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u539f\u578b\u6a21\u5f0f](https://mp.weixin.qq.com/s/R1bPyZBMWizcfuwQv0-t8Q)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5bf9\u8c61\u6c60\u6a21\u5f0f](https://mp.weixin.qq.com/s/p5lv_yTUbxsNYDmZiIpGTw)\\n - \u2b50\ufe0f [\u539f\u578b\u6a21\u5f0f\u8865\u9057 - Go\u8bed\u8a00\u4e2d\u7684\u6df1\u5ea6\u62f7\u8d1d](https://mp.weixin.qq.com/s/zVVl_R0WbP6AUcav5ys6tQ)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u9002\u914d\u5668\u6a21\u5f0f](https://mp.weixin.qq.com/s/KYlY-WFNpYirvcRiyaeVXw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u8d44\u6e90\u83b7\u53d6\u5373\u521d\u59cb\u5316](https://mp.weixin.qq.com/s/MiACdPNOhnXRoysRX2VBVA)\\n - \u2b50\ufe0f [Go 1.21 \u4e2d\u7684\u6cdb\u578b\u63a8\u65ad](https://mp.weixin.qq.com/s/hgFvoopT7DZoGUqHiurTeQ)\\n - \u2b50\ufe0f [mping: \u4f7f\u7528\u65b0\u7684icmp\u5e93\u5b9e\u73b0\u63a2\u6d4b\u548c\u538b\u6d4b\u5de5\u5177](https://mp.weixin.qq.com/s/1cIcrObMP5xG_UsMUatETw)\\n - \u2b50\ufe0f [PGO: \u4e3a\u4f60\u7684Go\u7a0b\u5e8f\u63d0\u65485%](https://mp.weixin.qq.com/s/SSkt6YYGcqgH9kbIQH-tNg)\\n - \u2b50\ufe0f [\u6df1\u5165\u7406\u89e3 PromQL](https://mp.weixin.qq.com/s/M0WFAQtoCd1aEZHjxTyjMw)\\n - \u2b50\ufe0f [\u4ec0\u4e48\u662f Go runtime.KeepAlive](https://mp.weixin.qq.com/s/5XMmVqdcji8jpRnC2p0F3w)\\n - \u2b50\ufe0f [\u6027\u80fd\u4f18\u5316 | Go Ballast \u8ba9\u5185\u5b58\u63a7\u5236\u66f4\u52a0\u4e1d\u6ed1](https://mp.weixin.qq.com/s/gc34RYqmzeMndEJ1-7sOwg)\\n - \u2b50\ufe0f [gin \u6e90\u7801\u9605\u8bfb(5) - \u7075\u6d3b\u7684\u8fd4\u56de\u503c\u5904\u7406](https://mp.weixin.qq.com/s/lE83EZ7eztjEWd_NU796YQ)\\n - \u2b50\ufe0f [gin \u6e90\u7801\u9605\u8bfb(4) - \u53cb\u597d\u7684\u8bf7\u6c42\u53c2\u6570\u5904\u7406](https://mp.weixin.qq.com/s/2OI9vh_LGPxtGkhF-AnWDA)\\n - \u2b50\ufe0f [gin \u6e90\u7801\u9605\u8bfb(3) - gin \u8def\u7531\u7684\u5b9e\u73b0\u5256\u6790](https://mp.weixin.qq.com/s/PldVh8Wk6oxCFIcWVx3hrQ)\\n - \u2b50\ufe0f [\u89c1\u5fae\u77e5\u8457| \u5e26\u4f60\u900f\u8fc7\u5185\u5b58\u770b Slice \u548c Array\u7684\u5f02\u540c](https://mp.weixin.qq.com/s/d9kP77eKRm2MSW_9ySlVGA)\\n - \u2b50\ufe0f [Goland \u8fd9\u4e9b\u5b9e\u64cd\u6280\u5de7\uff0c\u4f60\u53ef\u80fd\u8fd8\u4e0d\u4f1a\uff01](https://mp.weixin.qq.com/s/mrCQyw_dR5VYzf8ejyvHfA)\\n - \u2b50\ufe0f [\u8fd9\u4e9b Goland \u6280\u5de7\uff0c\u5b66\u4f1a\u5f00\u53d1\u6548\u7387\u7ffb\u500d](https://mp.weixin.qq.com/s/gmKi3bE99K6bXVGcMFz53w)\\n - \u2b50\ufe0f [Go interface \u539f\u7406\u5256\u6790--\u7c7b\u578b\u8f6c\u6362](https://mp.weixin.qq.com/s/lMvU80jhkabMvqXeTFiDnw)\\n - \u2b50\ufe0f [\u5feb\u6536\u85cf\uff01\u6700\u5168Go\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\uff08\u4e0a\uff09](https://mp.weixin.qq.com/s/MQWZOkaAc4Bw-PmYHyd9SA)\\n - \u2b50\ufe0f [\u5feb\u6536\u85cf\uff01\u6700\u5168GO\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\u3010\u4e0b\u3011](https://mp.weixin.qq.com/s/NrUWfpyfzX4sag22qF-Y-Q)\\n - \u2b50\ufe0f [\u6df1\u5165\u7406\u89e3 golang \u7684\u4e92\u65a5\u9501](https://mp.weixin.qq.com/s/i1N9bmVSW1lGfOezvhcD7g)\\n - \u2b50\ufe0f [Go 1.20\u65b0\u53d8\u5316\uff01\u7b2c\u4e00\u90e8\u5206\uff1a\u8bed\u8a00\u7279\u6027](https://mp.weixin.qq.com/s/rETmci7xvzf5X9_liS0Hmg)\\n - \u2b50\ufe0f [\\\\[\u8bd1\\\\]Uber \u7684 Go\u8bed\u8a00\u5f00\u53d1\u89c4\u8303](https://mp.weixin.qq.com/s/UQwOJVqm5gnQPMgSE3MW9w)\\n - \u2b50\ufe0f [\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01](https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w)\\n - \u2b50\ufe0f [\u4ece\u9e45\u5382\u5b9e\u4f8b\u51fa\u53d1\uff01\u5206\u6790Go Channel\u5e95\u5c42\u539f\u7406](https://mp.weixin.qq.com/s/uWhmvBk_MN23RjmfjkxqeQ)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u81ea\u52a8\u6536\u96c6\u7ebf\u4e0a\u95ee\u9898\u73b0\u573a](https://mp.weixin.qq.com/s/vB9ElJCfgZeQHtB596XHpA)\\n - \u2b50\ufe0f [\u7528\u89c4\u5219\u5f15\u64ce\u8ba9\u4f60\u4e00\u5929\u4e0a\u7ebf\u5341\u4e2a\u9700\u6c42](https://mp.weixin.qq.com/s/gLbAZShFnkPcI937pk-wpg)\\n - \u2b50\ufe0f [\u8ba1\u7b97\u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u59cb\u672b](https://mp.weixin.qq.com/s/gGs0tOJqBvJKCzPuUWsPiA)\\n - \u2b50\ufe0f [IO \u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u8bb0\u5f55](https://mp.weixin.qq.com/s/nSlfsoIo0cMYUdgIEuHWEg)\\n - \u2b50\ufe0f [Golang GC \u4ece\u7406\u8bba\u5230\u9488\u5bf9\u670d\u52a1\u7684\u5b9a\u5236\u5316\u5e94\u7528](https://mp.weixin.qq.com/s/YM9UP-esSDNZywMneKcVYw)\\n - \u2b50\ufe0f [\u4e00\u6587\u5f7b\u5e95\u7406\u89e3Go\u8bed\u8a00\u6808\u5185\u5b58/\u5806\u5185\u5b58](https://mp.weixin.qq.com/s/QQjOyYkDfuxIxHl6k6qkRA)\\n - \u2b50\ufe0f [\u5b57\u8282\u5927\u89c4\u6a21\u5fae\u670d\u52a1 Go \u8bed\u8a00\u53d1\u5c55\u4e4b\u8def](https://mp.weixin.qq.com/s/Oz0Zn8Y43UfHIOPL6rZ5Ig)\\n - \u2b50\ufe0f [\u901a\u8fc7\u5206\u6790gin\u3001beego\u6e90\u7801\uff0c\u8bfb\u61c2web\u6846\u67b6\u5bf9http\u8bf7\u6c42\u5904\u7406\u6d41\u7a0b\u7684\u672c\u8d28](https://mp.weixin.qq.com/s/2FVYnKHXFoj18W62pob_jw)\\n - \u2b50\ufe0f [\u4e00\u6587\u8bfb\u61c2 Go Http Server \u539f\u7406](https://mp.weixin.qq.com/s/aLiqEuD9T8sERVrfGDSxvw)\\n - \u2b50\ufe0f [Golang slog \u4ecb\u7ecd](https://mp.weixin.qq.com/s/0JbLDkJboDDihy-7N4MMPw)\\n - \u2b50\ufe0f [Golang \u5e93: golang slog \u600e\u4e48\u8bbe\u7f6e\u65e5\u5fd7 Debug \u7b49\u7ea7](https://mp.weixin.qq.com/s/Immr4DD-XA-noOEkZ6flKg)\\n - \u2b50\ufe0f [Golang \u5e93: \u4e3a\u4ec0\u4e48 Golang slog \u5e93\u4e0d\u652f\u6301 Fatal](https://mp.weixin.qq.com/s/PKtrqHFTYWyAVSolKVOoBQ)\\n - \u2b50\ufe0f [\u53d1\u73b0conc\u5e76\u53d1\u5e93\u4e00\u4e2a\u6709\u8da3\u7684\u95ee\u9898](https://mp.weixin.qq.com/s/G8mEAKRYbaae_rFBVJqdeg)\\n - \u2b50\ufe0f [Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72](https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg)\\n - \u2b50\ufe0f [\u300cGo\u8bed\u8a00\u8fdb\u9636\u300d\u5e76\u53d1\u7f16\u7a0b\u8be6\u89e3 | \u6587\u672b\u62bd\u5956](https://mp.weixin.qq.com/s/irp0uBR-nJ87tZ_elMWPnA)\\n - \u2b50\ufe0f [\u4e00\u6587\u5165\u95e8Go\u4e91\u539f\u751f\u5fae\u670d\u52a1\u300c\u7206\u809d6\u5343\u5b57\u300d](https://juejin.cn/post/7194334949011357755)\\n - \u2b50\ufe0f [\u4e3a\u4ec0\u4e48 Go \u4e0d\u652f\u6301 \\\\[\\\\]T \u8f6c\u6362\u4e3a \\\\[\\\\]interface](https://mp.weixin.qq.com/s/jsdGV31yT5AR07BzRovWVw)\\n - \u2b50\ufe0f [go-zero \u662f\u5982\u4f55\u505a\u8def\u7531\u7ba1\u7406\u7684](https://mp.weixin.qq.com/s/uTJ1En-BXiLvH45xx0eFsA)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4e2d\u6392\u5e8f\u7684 3 \u79cd\u65b9\u6cd5](https://mp.weixin.qq.com/s/RyVc_JZJi_pTT_51mEHYiw)\\n - \u2b50\ufe0f [\u4e00\u6587\u5403\u900f Go \u5185\u7f6e RPC \u539f\u7406](https://mp.weixin.qq.com/s/ExfVdEM7_YWlQF6GhFn74A)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5c\u5185\u5b58\u56de\u6536\u53c8\u8e29\u5751\u4e86](https://mp.weixin.qq.com/s/ea7LfF2jOoHOSozX-qUZLA)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cGo \u7684 nil \u503c\u5224\u65ad\uff0c\u5343\u65b9\u767e\u8ba1\uff0c\u8fd8\u662f\u8e29\u5751!](https://mp.weixin.qq.com/s/BwqHMhc2WtAY_R-UffNQ4w)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cpprof \u7edf\u8ba1\u7684\u5185\u5b58\u603b\u662f\u504f\u5c0f](https://mp.weixin.qq.com/s/-3X0c4P0WdZdjtkTsX16Rw)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5c\u89e3\u5bc6 defer \u539f\u7406\uff0c\u7a76\u7adf\u80cc\u7740\u7a0b\u5e8f\u733f\u505a\u4e86\u591a\u5c11\u4e8b\u60c5](https://mp.weixin.qq.com/s/ZgTCSj-PZMTiMCR4FtBeyA)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang \u5e76\u53d1\u7f16\u7a0b\u6838\u5fc3\u7bc7 \u2014\u2014 \u5185\u5b58\u53ef\u89c1\u6027](https://mp.weixin.qq.com/s/Atj8Ngvg3Uzw4gMDwf5rag)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang\u6700\u7ec6\u8282\u7bc7\u2014 struct{} \u7a7a\u7ed3\u6784\u4f53\u7a76\u7adf\u662f\u5565](https://mp.weixin.qq.com/s/2u2qRUbgcOwvU9wcHpC0SA)\\n - \u2b50\ufe0f [Go Slice \u6269\u5bb9\u7684\u8fd9\u4e9b\u5751\u4f60\u8e29\u8fc7\u5417](https://mp.weixin.qq.com/s/ylsTVohPo7x8QKAUj1uoTA)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u5b9e\u73b0\u521b\u5efa\u578b\u8bbe\u8ba1\u6a21\u5f0f - \u5355\u4f8b\u6a21\u5f0f](https://mp.weixin.qq.com/s/ixTP1qythuJyhf3b9kIRaA)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u81ea\u5e26\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/qTYlHqozkWHkhF9OKfaAMQ)\\n - \u2b50\ufe0f [\u5982\u4f55\u505a\u597d\u8868\u7ed3\u6784\u8bbe\u8ba1](https://mp.weixin.qq.com/s/SYQTlvbLvbsSwFi2Q_kI1Q)\\n - \u2b50\ufe0f [Go \u9519\u8bef\u5904\u7406\uff1a100+ \u63d0\u6848\u5168\u90e8\u88ab\u62d2\u7edd\uff0c\u4e3a\u4f55\u73b0\u9636\u6bb5\u4ecd\u7528 if err != nil](https://mp.weixin.qq.com/s/xiUPLOTkDCX2i2jTOSNgCQ)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u5e76\u53d1\u6a21\u5f0f\u4ee3\u7801\u6a21\u677f](https://mp.weixin.qq.com/s/431YMKwRjaStanqA6juePA)\\n - \u2b50\ufe0f [\u57fa\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4f18\u5316\u9884\u89c8](https://mp.weixin.qq.com/s/elsHIqDQ0yABUZXNVpjwMg)\\n - \u2b50\ufe0f [\u300c\u9ad8\u9891\u5fc5\u8003\u300dGo\u5e76\u53d1\u7f16\u7a0b\u9762\u8bd5\u9898\u548c\u7b54\u6848](https://mp.weixin.qq.com/s/soaxFUjo6hEe2KSnle_LkQ)\\n - \u2b50\ufe0f [\u6e90\u7801\u9605\u8bfb - \u5207\u7247\u6269\u5bb9\u8fc7\u7a0b](https://mp.weixin.qq.com/s/k0zwlJNFssMRh1NHA6rGcA)\\n - \u2b50\ufe0f [Golang\u53cd\u5c04\u5b66\u4e60\uff1a\u624b\u5199\u4e00\u4e2aRPC](https://mp.weixin.qq.com/s/PzfiMXiYjfGQFHW_0hTS4A)\\n - \u2b50\ufe0f [\u6df1\u5165\u89e3\u6790\u975e\u963b\u585eGolang IO\u6846\u67b6nbio](https://mp.weixin.qq.com/s/mAo2K8lZNeJHTtShBHlUsQ)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u6807\u51c6\u5e93 bufio \u8be6\u89e3](https://mp.weixin.qq.com/s/aP9bT4UL1MK5EDx18WfvmQ)\\n - \u2b50\ufe0f [CPU \u7f13\u5b58\u4f53\u7cfb\u5bf9 Go \u7a0b\u5e8f\u7684\u5f71\u54cd](https://mp.weixin.qq.com/s/Yi0eGTzrT7mtkpebmLXqVA)\\n - \u2b50\ufe0f [\u300c\u5237\u8d77\u6765\u300dGo\u5fc5\u770b\u7684\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3](https://mp.weixin.qq.com/s/2iOkW5h7x-1wdYe51vMemw)\\n - \u2b50\ufe0f [Go \u6027\u80fd\u52a0\u901f\u5668\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684 5 \u4e2a\u8bc0\u7a8d\u548c\u6280\u5de7](https://mp.weixin.qq.com/s/NJuOB8k86Z7Hv-xITL1Vqg)\\n - \u2b50\ufe0f [\u6df1\u5165\u5256\u6790 Golang \u7a0b\u5e8f\u542f\u52a8\u539f\u7406 - \u4ece ELF \u5165\u53e3\u70b9\u5230GMP\u521d\u59cb\u5316\u5230\u6267\u884c main\uff01](https://mp.weixin.qq.com/s/tgBqY3xYbk5IBzViL9eaiA)\\n - \u2b50\ufe0f [\u4ece\u7f16\u8bd1\u539f\u7406\u5230 Go \u542f\u52a8\u65f6\u7684\u6d41\u7a0b\uff0cGo\u7a0b\u5e8f\u662f\u600e\u6837\u8dd1\u8d77\u6765\u7684](https://juejin.cn/post/7254384497649844280)\\n - \u2b50\ufe0f [\u4ece.go\u6587\u672c\u6587\u4ef6\u5230\u53ef\u6267\u884c\u6587\u4ef6](https://mp.weixin.qq.com/s/V5wAZcTbunU3HdS1xaWavQ)\\n - \u2b50\ufe0f [Go \u7f16\u8bd1\u5668\u4f18\u5316](https://mp.weixin.qq.com/s/eWM9AvG1qXnMWF4qIwhnVQ)\\n - \u2b50\ufe0f [\u5b66\u4f1a Go select \u8bed\u53e5\uff0c\u8f7b\u677e\u5b9e\u73b0\u9ad8\u6548\u5e76\u53d1](https://juejin.cn/post/7210005376653377597)\\n - \u2b50\ufe0f [Go Mutex\uff1a\u4fdd\u62a4\u5e76\u53d1\u8bbf\u95ee\u5171\u4eab\u8d44\u6e90\u7684\u5229\u5668](https://juejin.cn/post/7215188852851097656)\\n - \u2b50\ufe0f [Go RWMutex\uff1a\u9ad8\u5e76\u53d1\u8bfb\u591a\u5199\u5c11\u573a\u666f\u4e0b\u7684\u6027\u80fd\u4f18\u5316\u5229\u5668](https://juejin.cn/post/7218554163051413561)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4e2d\u6ca1\u6709\u679a\u4e3e\u7c7b\u578b\uff0c\u4f46\u662f\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u505a](https://juejin.cn/post/7223035239072333861)\\n - \u2b50\ufe0f [Go \u65b9\u6cd5\u63a5\u6536\u5668\uff1a\u9009\u62e9\u503c\u63a5\u6536\u5668\u8fd8\u662f\u6307\u9488\u63a5\u6536\u5668](https://juejin.cn/post/7224147971834691639)\\n - \u2b50\ufe0f [\u4e00\u6587\u638c\u63e1 Go \u5e76\u53d1\u6a21\u5f0f Context \u4e0a\u4e0b\u6587](https://juejin.cn/post/7233981178101186619)\\n - \u2b50\ufe0f [Go \u7a7a\u7ed3\u6784\u4f53\uff1a\u96f6\u5185\u5b58\u7684\u9b54\u529b](https://mp.weixin.qq.com/s/rD3pnjWF5_Zz-r6GB0LrrA)\\n - \u2b50\ufe0f [Go \u51fd\u6570\u9009\u9879\u6a21\u5f0f\uff08Functional Options Pattern\uff09](https://juejin.cn/post/7241938328839618597)\\n - \u2b50\ufe0f [Go \u9879\u76ee\u5206\u5c42\u4e0b\u7684\u6700\u4f73 error \u5904\u7406\u65b9\u5f0f](https://juejin.cn/post/7246777406387306553)\\n - \u2b50\ufe0f [Go \u8bed\u8a00 iota \u7684\u795e\u5947\u529b\u91cf](https://mp.weixin.qq.com/s/xjkY6hJnUq5btDyJuSOZrg)\\n - \u2b50\ufe0f [\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\uff1a\u63a2\u7d22Go\u8bed\u8a00\u4e2d\u7684\u51fd\u6570\u4e00\u7b49\u516c\u6c11](https://mp.weixin.qq.com/s/sJeXoxTSh7M9azpsbsr1rQ)\\n - \u2b50\ufe0f [\\\\[Go\u5f00\u6e90\u5de5\u5177\\\\] go-optioner\uff1a\u8f7b\u677e\u751f\u6210\u51fd\u6570\u9009\u9879\u6a21\u5f0f\u4ee3\u7801](https://mp.weixin.qq.com/s/_enXW8Pk4okosAgDo_aYSw)\\n - \u2b50\ufe0f [\u6df1\u5165\u63a2\u7d22 Go 1.21.0 \u4e2d\u7684 maps \u5de5\u5177\u5e93](https://mp.weixin.qq.com/s/biTRyEu2h8AzQaQf7Ik8nA)\\n - \u2b50\ufe0f [Go Gin \u6846\u67b6\u7cfb\u5217 - \u5165\u95e8\u7bc7](https://mp.weixin.qq.com/s/_a9d67L8l7G6EDJom1kixw)\\n - \u2b50\ufe0f [Go \u9879\u76ee\u5fc5\u5907\uff1a\u6df1\u5165\u6d45\u51fa Wire \u4f9d\u8d56\u6ce8\u5165\u5de5\u5177](https://mp.weixin.qq.com/s/gC4D9CqeYAd-jPotKgIV4g)\\n - \u2b50\ufe0f [\u5feb\u901f\u4e0a\u624b Go CGO\uff0c\u638c\u63e1\u5728 Go \u91cc\u5199 C\uff01](https://juejin.cn/post/7226187111330611255)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1a\u8fc7\u4e86\u4e00\u5e74\u534a\uff0cslices\u3001maps \u6cdb\u578b\u5e93\u7ec8\u4e8e\u8981\u52a0\u5165\u6807\u51c6\u5e93](https://mp.weixin.qq.com/s/1NuBnk8_lxmTi9N0biLa2g)\\n - \u2b50\ufe0f [Go1.22 \u53ef\u80fd\u4f1a\u89e3\u51b3\u5faa\u73af\u53d8\u91cf\u7684\u5751\uff0c\u771f\u597d\uff01\uff01](https://mp.weixin.qq.com/s/N7_-WNBsTpTc4X8qTQw-Nw)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1a\u9a9a\u64cd\u4f5c panic(nil) \u5c06\u6210\u4e3a\u5386\u53f2\uff01\u4ee5\u540e\u522b\u8fd9\u4e48\u5e72\u4e86](https://mp.weixin.qq.com/s/xgJ8lPS-O84Ttne5heRa3g)\\n - \u2b50\ufe0f [Go1.21.0 \u65b0\u7279\u6027\uff1a\u4e0d\u9700\u8981\u5faa\u73af delete map \u5143\u7d20\u4e86](https://mp.weixin.qq.com/s/rxxQhrVk3_4ZvTjsIJbstw)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1a\u65b0\u5185\u7f6e\u51fd\u6570 clear\u3001min\u3001max \u548c\u65b0\u6807\u51c6\u5e93\u5305 cmp\uff01](https://mp.weixin.qq.com/s/MorBUrzpKFhssiZWLt4o6g)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1ago.mod \u7684 Go \u7248\u672c\u53f7\u5c06\u4f1a\u7ea6\u675f Go \u7a0b\u5e8f\u6784\u5efa\uff0c\u8981\u7279\u522b\u6ce8\u610f\u4e86\uff01](https://mp.weixin.qq.com/s/s13EBwOExsVz_vwNEm0fvQ)\\n - \u2b50\ufe0f [Go \u5c06\u5f15\u5165\u6807\u51c6\u5e93 v2 \u7248\u672c\uff0c\u9996\u4e2a\u52a8\u624b\u7684\u662f\uff1amath/rand/v2\uff01](https://mp.weixin.qq.com/s/b_TYBRIZ3-EORFYq1xRjyQ)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1aContext \u53ef\u4ee5\u8bbe\u7f6e\u53d6\u6d88\u539f\u56e0\u548c\u56de\u8c03\u51fd\u6570\u4e86\uff0c\u7b49\u7684\u53ef\u592a\u4e45\u4e86\uff01](https://juejin.cn/post/7249913673216966714)\\n - \u2b50\ufe0f [Go \u56e2\u961f\u5c06\u4fee\u6539 for \u5faa\u73af\u53d8\u91cf\u7684\u8bed\u4e49\uff0cGo1.21 \u65b0\u7248\u672c\u5373\u53ef\u4f53\u9a8c\uff01](https://mp.weixin.qq.com/s/VO0VlfGbuvZst9yD73-VDQ)\\n - \u2b50\ufe0f [Google \u5de5\u4f5c 10+ \u5e74\u7684\u611f\u609f\uff0c\u6709\u770b\u5230 Go \u6838\u5fc3\u56e2\u961f\u7684\u5f71\u5b50\u5417](https://mp.weixin.qq.com/s/Z8kMDwuv9ZlmqvdrOu5SEQ)\\n - \u2b50\ufe0f [Go defer \u53bb\u6389\u95ed\u5305\u51fd\u6570\uff0c\u9760\u8c31\u5417](https://mp.weixin.qq.com/s/4vpgxwTEn-xjdmXF5Hj7Kw)\\n - \u2b50\ufe0f [\u53e6\u4e00\u79cd\u89c6\u89d2\uff1a\u6211\u4e3a\u4ec0\u4e48\u653e\u5f03 Go \u8bed\u8a00](https://mp.weixin.qq.com/s/xjjnE5hcspbNRGHP-I869A)\\n - \u2b50\ufe0f [Go \u9762\u8bd5\u9898\uff1astring \u662f\u7ebf\u7a0b\u5b89\u5168\u7684\u5417](https://mp.weixin.qq.com/s/4pPpHRWflkkvqrf-FlXztg)\\n - \u2b50\ufe0f [Go \u6539\u7248\u672c\u53f7\u89c4\u5219\uff0c\u4e3b\u7248\u672c\u53f7\u7ec8\u4e8e\u652f\u6301\u7b2c\u4e09\u4f4d\u6570\u5b57 0 \u4e86](https://mp.weixin.qq.com/s/BfW8Ra3tsv7Dv3nu3MeI0g)\\n - \u2b50\ufe0f [Go1.21 \u90a3\u4e9b\u4e8b\uff1a\u6cdb\u578b\u5e93\u3001for \u8bed\u4e49\u53d8\u66f4\u3001\u7edf\u4e00 log/slog\u3001WASI \u7b49\u65b0\u7279\u6027\uff0c\u4f60\u77e5\u9053\u591a\u5c11](https://mp.weixin.qq.com/s/Nuj_cYFvBesaBbSSz5PuBg)\\n - \u2b50\ufe0f [\u53c8\u6709\u65b0\u529f\u80fd\uff01Go \u5c06\u6709\u751f\u6210\u65b0\u6a21\u677f\u7684 gonew \u5de5\u5177\u94fe](https://mp.weixin.qq.com/s/jk7k5v9uvaNy_2fUsDjq0Q)\\n - \u2b50\ufe0f [Go \u5c06\u589e\u52a0\u5185\u7f6e\u7684\u96f6\u503c\u6807\u8bc6\u7b26 zero\uff01](https://mp.weixin.qq.com/s/o1iKbXJEikJn8BLwetvF5g)\\n - \u2b50\ufe0f [Go \u96f6\u503c\u548c\u7a7a\u503c\u7684\u5224\u65ad\u95ee\u9898](https://mp.weixin.qq.com/s/M6b4Q7rwKSt4KNKJN7_j4g)\\n - \u2b50\ufe0f [Go \u8d1f\u8d23\u4eba\u8bf4\u4ee5\u540e\u4e0d\u4f1a\u6709 Go2 \u4e86](https://mp.weixin.qq.com/s/5kNyYJhrzigujLq1YSVjHw)\\n - \u2b50\ufe0f [Go \u5e38\u91cf\u4e3a\u4ec0\u4e48\u53ea\u652f\u6301\u57fa\u672c\u6570\u636e\u7c7b\u578b](https://mp.weixin.qq.com/s/TlJFr25XNgGA7uyRtLMOlw)\\n - \u2b50\ufe0f [Go \u5b98\u65b9\u65b0\u73a9\u5177\uff1a\u6f0f\u6d1e\u7ba1\u7406\u548c\u626b\u63cf\uff0c\u770b\u770b\u81ea\u5df1\u9879\u76ee\u6709\u6ca1\u6709\u5751](https://mp.weixin.qq.com/s/xO_w3FvNN8OeiuEYFarwGQ)\\n - \u2b50\ufe0f [\u5feb\u901f\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f](https://mp.weixin.qq.com/s/4yfVZCaJ1489ddpYD5vDQA)\\n - \u2b50\ufe0f [\u300c\u5fc5\u77e5\u5fc5\u4f1a\u300d Nacos \u7684\u9762\u8bd5\u9898\u548c\u8be6\u89e3](https://mp.weixin.qq.com/s/C_KpYoul8ko5yrVLMe_uQg)\\n - \u2b50\ufe0f [zookeeper\u5230nacos\u7684\u8fc1\u79fb\u5b9e\u8df5](https://mp.weixin.qq.com/s/8XdbLrlzHhofiC089AMb1Q)\\n - \u2b50\ufe0f [\u4e0a\u7bc7\uff1a\u5e26\u4f60\u624b\u5de5\u4f53\u9a8c\u4ece\u5199\u4ee3\u7801\u3001\u7f16\u8bd1\u3001\u6253\u5305\u955c\u50cf\u3001\u90e8\u7f72\u5230K8S\u7684\u5168\u8fc7\u7a0b](https://mp.weixin.qq.com/s/YGhndR5zR-Ebf8IaKbFZiQ)\\n - \u2b50\ufe0f [\u4e0b\u7bc7\uff1a\u4f7f\u7528jenkins\u53d1\u5e03go\u9879\u76ee\u5230k8s\uff0c\u63a5\u4e0a\u7bc7\u7684\u624b\u5de5\u4f53\u9a8c\u6539\u9020\u4e3a\u81ea\u52a8\u5316\u53d1\u5e03](https://mp.weixin.qq.com/s/yJ6rkYrwn8RAMLt5uCF9mw)\\n - \u2b50\ufe0f [\u503c\u5f97\u6536\u85cf\uff1aK8S\u7684kubectl\u5e38\u7528\u547d\u4ee4\u5df2\u7ecf\u6309\u573a\u666f\u5206\u597d\u7c7b\uff0c\u8bf7\u60a8\u67e5\u9605](https://mp.weixin.qq.com/s/pW0vxt8k1pDk0OEz5asWGQ)\\n - \u2b50\ufe0f [\u907f\u5751\uff1aGo\u5e76\u53d1\u7f16\u7a0b\u65f6\uff0c\u5982\u4f55\u907f\u514d\u53d1\u751f\u7ade\u6001\u6761\u4ef6\u548c\u6570\u636e\u7ade\u4e89](https://mp.weixin.qq.com/s/lYg-GdheztmkTo9mwqHGsg)\\n - \u2b50\ufe0f [Go\u63a5\u53e3\uff1a\u8fd0\u7ef4\u5f00\u53d1\u573a\u666f\u4e2d\uff0cgo\u7684\u63a5\u53e3\u5230\u5e95\u600e\u4e48\u7528](https://mp.weixin.qq.com/s/bwkK3Yw02w4szwub2B2-ig)\\n - \u2b50\ufe0f [Go\uff1a4\u4e2a\u573a\u666f\u5c31\u53ef\u4ee5\u8ba9\u4f60\u77e5\u9053Goroutine\u548c\u901a\u9053\u662f\u600e\u4e48\u7528\u7684](https://mp.weixin.qq.com/s/bqZ6gAsOZoVEMSCeOuLbiQ)\\n - \u2b50\ufe0f [\u4e0d\u80cc\u9505\u8fd0\u7ef4\uff1aGo\u8bed\u8a00\u5207\u7247\u5185\u5b58\u4f18\u5316\u6280\u5de7\u548c\u5b9e\u6218\u6848\u4f8b](https://juejin.cn/post/7210747150828798008)\\n - \u2b50\ufe0f [Go\u5b9e\u6218\uff1a\u5f00\u53d1\u4e00\u4e2a\u7b80\u5355\u7684gRPC Demo](https://mp.weixin.qq.com/s/rxPAcU5zhWCtRQLbh9uxKw)\\n - \u2b50\ufe0f [Go\uff1a\u4f7f\u7528Cobra\u6253\u9020\u5f3a\u5927\u547d\u4ee4\u884c\u5e94\u7528](https://mp.weixin.qq.com/s/im8JZV3bL9WVOn7VgArmhw)\\n - \u2b50\ufe0f [Go\u7684\u8fd9\u4e2a\u5e93\uff0c\u8ba9\u4f60\u7684\u547d\u4ee4\u884c\u8f93\u51fa\u53d8\u5f97\u4e13\u4e1a](https://mp.weixin.qq.com/s/4VfTjWQwNO-tlxYbUOrWZw)\\n - \u2b50\ufe0f [\u300cGo\u5f00\u6e90\u5305\u300dasynq\uff1a\u4e00\u4e2a\u57fa\u4e8eredis\u7684\uff0c\u7b80\u5355\u3001\u53ef\u9760\u3001\u9ad8\u6548\u7684\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u5305](https://mp.weixin.qq.com/s/nbouC5ynfZShaTMTYiCJFA)\\n - \u2b50\ufe0f [\u62bd\u4e1d\u5265\u8327\uff0c\u8bb0\u4e00\u6b21 Go \u7a0b\u5e8f\u6027\u80fd\u4f18\u5316\u4e4b\u65c5](https://mp.weixin.qq.com/s/HBLwocMA2vQE2uFlJ0D8Iw)\\n - \u2b50\ufe0f [Go\uff1a\u8bb0\u4e00\u6b21\u63d0\u534718\u500d\u7684\u6027\u80fd\u4f18\u5316](https://mp.weixin.qq.com/s/1Y_A6WVslDthVjtbP9Ibvg)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u4e2dJSON\u5904\u7406\u6280\u5de7\u603b\u7ed3](https://mp.weixin.qq.com/s/js3m_Fe6k4ys4aBSFDJhLQ)\\n - \u2b50\ufe0f [\u63a2\u7a76\uff5cGo JSON \u4e09\u65b9\u5305\u54ea\u5bb6\u5f3a](https://mp.weixin.qq.com/s/ueNuYA23F3bQTwIKU-PZ2Q)\\n - \u2b50\ufe0f [Sonic: Go\u8bed\u8a00\u7684\u8d85\u7ea7JSON\u5e93\uff0c\u89e3\u6790\u4e0e\u7f16\u7801\u901f\u5ea6\u72c2\u98d9](https://mp.weixin.qq.com/s/IAHEQu-N5OO-X_q-47GCsQ)\\n - \u2b50\ufe0f [\u6536\u85cf\uff01\uff01\uff01\u4e00\u56fe\u638c\u63e1 Go \u4e2d IO \u5305\u7684\u5173\u7cfb](https://mp.weixin.qq.com/s/cjQyDdIgcdzj7LOeZf21bQ)\\n - \u2b50\ufe0f [\u901a\u8fc7\u6e90\u7801\u5256\u6790Go\u7684map\u6269\u5bb9\u5e95\u5c42\u5b9e\u73b0](https://juejin.cn/post/7207058392287346747)\\n - \u2b50\ufe0f [\u300c\u6709\u95ee\u5fc5\u7b54\u300dGopher\u5982\u4f55\u4f18\u96c5\u7684\u5bf9\u65f6\u95f4\u8fdb\u884c\u683c\u5f0f\u5316](https://mp.weixin.qq.com/s/cK2KMpN4vUrlDXEkTm7Mig)\\n - \u2b50\ufe0f [Go \u6cdb\u578b\u7684\u4e8c\u5341\u4e00\u4e2a\u9677\u9631](https://mp.weixin.qq.com/s/7qutgFgPDGyjKhxb6YVB3Q)\\n - \u2b50\ufe0f [\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff1a\u6df1\u5165\u63a2\u7d22Golang\u4e2d\u7684SM4\u52a0\u5bc6\u89e3\u5bc6\u7b97\u6cd5](https://juejin.cn/post/7248388270723039290)\\n - \u2b50\ufe0f [\u7cbe\u90098\u9053ES\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\uff0c\u540e\u6094\u6ca1\u65e9\u70b9\u770b](https://juejin.cn/post/7248791708334899258)\\n - \u2b50\ufe0f [\u7cbe\u9009Go\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\u6c47\u603b\uff0c\u9605\u8bfb\u7834\u4e07\uff0c\u6536\u85cf230+](https://juejin.cn/post/7248995705291866169)\\n - \u2b50\ufe0f [Go\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3 | \u6587\u672b\u9001\u4e66](https://mp.weixin.qq.com/s/ldn5APfp0UooWbh4cmcM4A)\\n - \u2b50\ufe0f [Go\u4e2d\u8fd9\u4e48\u591a\u521b\u5efaerror\u7684\u65b9\u5f0f\uff0c\u4f60\u771f\u7684\u4e86\u89e3\u5b83\u4eec\u5404\u81ea\u7684\u5e94\u7528\u573a\u666f\u5417](https://mp.weixin.qq.com/s/GXAvaFvXR3HYI7qU4lL4lA)\\n - \u2b50\ufe0f [\u57fa\u4e8eRedis\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u56fa\u5b9a\u7a97\u53e3\u9650\u6d41\u5668](https://mp.weixin.qq.com/s/6aicpVC3qjRpf1ILI4V4lA)\\n - \u2b50\ufe0f [go channel\u5e94\u7528\u7cfb\u5217\u4e4b\u63a7\u5236\u534f\u7a0b\u6570\u91cf](https://mp.weixin.qq.com/s/CUQaiZp4BrulnXvLd9ogZQ)\\n - \u2b50\ufe0f [\u914d\u56fe\u6e05\u65b0\u7684Protobuf \u7f16\u7801&\u907f\u5751\u6307\u5357](https://mp.weixin.qq.com/s/YJp2jxuBwwbPBaMWlDZG9g)\\n - \u2b50\ufe0f [\u5199\u7ed9\u5f00\u53d1\u8005\u7684gRPC\u6559\u7a0b-\u670d\u52a1\u53d1\u73b0\u4e0e\u8d1f\u8f7d\u5747\u8861](https://mp.weixin.qq.com/s/iptZLaGFLd1rDedclQUMFg)\\n - \u2b50\ufe0f [\u7b54\u7f51\u53cb\u95ee\uff1agolang\u4e2d\u7684slice\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\u662f\u503c\u4f20\u9012\u8fd8\u662f\u5f15\u7528\u4f20\u9012](https://mp.weixin.qq.com/s/oettru3CV_Cjqv5GEOmcMw)\\n - \u2b50\ufe0f [Go\u53ef\u7528\u6027(\u4e03) \u603b\u7ed3: \u4e00\u5f20\u56fe\u4e32\u8054\u53ef\u7528\u6027\u77e5\u8bc6\u70b9](https://mp.weixin.qq.com/s/OXopl6FpwtE6P-k0GEP9qA)\\n - \u2b50\ufe0f [Go \u5de5\u7a0b\u5316(\u5341) \u5982\u4f55\u5728\u6574\u6d01\u67b6\u6784\u4e2d\u4f7f\u7528\u4e8b\u52a1](https://mp.weixin.qq.com/s/MSwUlVGPDRBjdR-xh5cNfA)\\n - \u2b50\ufe0f [Go \u5de5\u7a0b\u5316(\u5341\u4e00) \u5982\u4f55\u4f18\u96c5\u7684\u5199\u51fa repo \u5c42\u4ee3\u7801](https://mp.weixin.qq.com/s/pb0P_y34N3uOhMu0SDqC2A)\\n - \u2b50\ufe0f [\u4f7f\u7528 Go \u8bed\u8a00\u5b9e\u73b0\u4e8c\u53c9\u641c\u7d22\u6811](https://mp.weixin.qq.com/s/2wYRmG_AiiHYjLDEXg94Ag)\\n - \u2b50\ufe0f [Opentelemetry \u5b9e\u8df5\u5206\u4eab - Golang\u7bc7](https://mp.weixin.qq.com/s/7hU0iSDBg0z1nYZnB-61gQ)\\n - \u2b50\ufe0f [Golang\u5b9e\u73b0\u5355\u673a\u767e\u4e07\u957f\u8fde\u63a5\u670d\u52a1 - \u7f8e\u56fe\u7684\u4e09\u5e74\u4f18\u5316\u7ecf\u9a8c](https://mp.weixin.qq.com/s/xavjsa4NzRiVRxyMhifCDg)\\n - \u2b50\ufe0f [\u4f7f\u7528go-zero\u5feb\u901f\u6784\u5efa\u5fae\u670d\u52a1](https://mp.weixin.qq.com/s/IpvR28soReYC3nNkAisteA)\\n - \u2b50\ufe0f [\u5927\u578b Go \u4ee3\u7801\u5e93\u7684 3 \u79cd\u6700\u4f73\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/yHD5XKsk6emuXjcnU2JxDw)\\n - \u2b50\ufe0f [Asynq: \u57fa\u4e8eRedis\u5b9e\u73b0\u7684Go\u751f\u6001\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u548c\u5f02\u6b65\u5904\u7406\u5e93](https://mp.weixin.qq.com/s/n199y8JEyjuGFwUEyH2XVg)\\n - \u2b50\ufe0f [\u300cGo\u9762\u7ecf\u300d\u7b97\u6cd5 \u5e76\u53d1\u6a21\u578b \u7f13\u5b58\u843d\u76d8 etcd actor\u6a21\u578b](https://mp.weixin.qq.com/s/C2kZGElYQmHz3OCb7LuYoA)\\n - \u2b50\ufe0f [\u63a2\u7d22 Go1.21 \u4e2d\u7684 slices \u5305\uff1a\u539f\u7406\uff0c\u7279\u70b9\u548c\u793a\u4f8b](https://mp.weixin.qq.com/s/2tFBe6LH84dZnOcfkgX32w)\\n - \u2b50\ufe0f [\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a](https://mp.weixin.qq.com/s/7nK4whfh0Owwhmq_67_eYg)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4e3a\u4ec0\u4e48\u9002\u5408\u5f00\u53d1\u7f51\u7edc\u670d\u52a1](https://mp.weixin.qq.com/s/_mXRLJ-h7Iqkrt1jq_sZXg)\\n - \u2b50\ufe0f [\u7528 Go \u7f16\u5199\u7b80\u6d01\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/iamOjb0k3M2k_FVG9W7z0A)\\n - \u2b50\ufe0f [Golang channel \u4e09\u5927\u5751\uff0c\u4f60\u8e29\u8fc7\u4e86\u561b](https://mp.weixin.qq.com/s/7vDklpTsbRdRDvB0-yvB5g)\\n - \u2b50\ufe0f [\u4f7f\u7528Singleflight\u4f18\u5316Go\u4ee3\u7801](https://mp.weixin.qq.com/s/j9Obe6Na25388AzeSL1dRA)\\n - \u2b50\ufe0f [\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a](https://mp.weixin.qq.com/s/gVjq59qnLjy-gwibt7Q3yw)\\n - \u2b50\ufe0f [\u5b9a\u4e86\uff1aGo 1.22\u5c06\u4fee\u590dfor\u5faa\u73af\u53d8\u91cf\u9519\u8bef](https://mp.weixin.qq.com/s/G3FGOUo-F-stOp5eZjq4QQ)\\n - \u2b50\ufe0f [Go\u5b57\u7b26\u4e32\u64cd\u4f5c\u4e0d\u662f\u4f60\u60f3\u7684\u90a3\u4e48\u7b80\u5355\uff01](https://mp.weixin.qq.com/s/R_2pwdv2V1jj3zMjuUTNHw)\\n - \u2b50\ufe0f [Golang\u77e5\u8bc6\u70b9(defer): \u9762\u8bd5\u7ecf\u5e38\u53d8\u91cf\u5728 defer \u4e2d\u7684\u503c\uff0c \u5176\u5b9e\u5728\u95ee\u53d8\u91cf\u7684\u4f5c\u7528\u57df](https://mp.weixin.qq.com/s/QlzH18i72pWPm012t7d42Q)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(1)\uff1aGin\u6846\u67b6\u4e2d\u5982\u4f55\u5904\u7406HTTP\u8bf7\u6c42](https://mp.weixin.qq.com/s/VjP9Bv46x7NP6uQ7cbsqmg)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(2)\uff1anet\u5e93\u5bf9socket/bind/listen/accept\u7684\u5c01\u88c5](https://mp.weixin.qq.com/s/x5qUJ-htS6ML1Cc8uYIDVQ)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server](https://mp.weixin.qq.com/s/WoXZ_i7lJeXny8lIJ_Aj4g)\\n - \u2b50\ufe0f [\u3010\u8865\u5145\u4ee3\u7801\u3011Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server](https://mp.weixin.qq.com/s/76xvAvnFAcDUAa6fgoZRfg)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(4)\uff1anet/http \u5728 tcp conn \u4e0a\u7684\u5904\u7406](https://mp.weixin.qq.com/s/AvtIiC349sDqOe9labc3-A)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(5)\uff1anet\u5e93\u7684\u975e\u963b\u585e\u652f\u6301](https://mp.weixin.qq.com/s/MO5XV40D3MI6NpEEpJiCMA)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(6)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bselect](https://mp.weixin.qq.com/s/t_4uTGN9DFCjqDw4LZT-0w)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(7)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bepoll](https://mp.weixin.qq.com/s/Zsh92yqK4e6mxNBLgY0Umw)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(8)\uff1aGo netpoll \u7684\u5de5\u4f5c\u673a\u5236](https://mp.weixin.qq.com/s/3_eToHvOw25JrC8-xePe_w)\\n - \u2b50\ufe0f [Go\u534f\u7a0b\u6c60(1): \u7ebf\u7a0bvs\u534f\u7a0b](https://mp.weixin.qq.com/s/-qms3hEl2mNMkDN1S4ZQoQ)\\n - \u2b50\ufe0f [Go\u534f\u7a0b\u6c60(2): \u5982\u4f55\u5b9e\u73b0\u534f\u7a0b\u6c60](https://mp.weixin.qq.com/s/ktMff61A9vvqeRGkGwQnwg)\\n - \u2b50\ufe0f [\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1(1): \u5982\u4f55\u5b9e\u73b0\u6296\u97f3\u5173\u6ce8/\u7c89\u4e1d\u5217\u8868](https://mp.weixin.qq.com/s/cIgfuumVCL4rxtNYGcQH4A)\\n - \u2b50\ufe0f [SIMD\u80fd\u529b\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/ydFRhjV70QC64N8r2zEtVA)\\n - \u2b50\ufe0f [\\\\[\u4ee3\u7801\u9644\u5f55\\\\] SIMD\u80fd\u529b\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/q-keuybJ2d-QMXWoPpSbPA)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\u7b80\u4ecb](https://mp.weixin.qq.com/s/1kuLtd8rxC1xP628FgAwqw)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1a\u5927\u6570\u636e\u67b6\u6784](https://mp.weixin.qq.com/s/Ane5iRMqYrtQMnC3TWlrwA)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1a\u5fae\u670d\u52a1\u67b6\u6784](https://mp.weixin.qq.com/s/dOw25R2xihr0M3T27fYUSA)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1a\u5206\u5c42\u67b6\u6784](https://mp.weixin.qq.com/s/CUCHUQa6lYuPhvEALdIQQg)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1aWeb-Queue-Worker\u67b6\u6784](https://mp.weixin.qq.com/s/P1j0vg2FYqt1zvwPQsdtww)\\n - \u2b50\ufe0f [\u5f02\u6b65\u8bf7\u6c42-\u54cd\u5e94\u6a21\u5f0f](https://mp.weixin.qq.com/s/YkOoLbH2P2HheQxomGsbNQ)\\n - \u2b50\ufe0f [Sidecar\u6a21\u5f0f](https://mp.weixin.qq.com/s/Q-YvkWhFC2uK1z5AKEKSnw)\\n - \u2b50\ufe0f [\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303](https://juejin.cn/post/7157594175846744071)\\n - \u2b50\ufe0f [Go Scheduler \u7684 GMP \u6a21\u578b](https://mp.weixin.qq.com/s/1CY3E5daJ5U42orVwzCpaw)\\n - \u2b50\ufe0f [Golang \u6cdb\u578b\u521d\u8bc6](https://juejin.cn/post/7116817920209977351)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u5b98\u65b9\u4f9d\u8d56\u6ce8\u5165\u5de5\u5177 Wire \u4f7f\u7528\u6307\u5317](https://mp.weixin.qq.com/s/yHB9BzEGIki1fyjYojdpYQ)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u7aef\u5f00\u53d1\u603b\u7ed3](https://juejin.cn/post/7043587400131411976)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u5165\u95e8\u7cfb\u5217\uff1a\u521d\u63a2 Go \u9879\u76ee\u5b9e\u6218](https://eddycjy.com/go-categories/)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u7f16\u7a0b\u4e4b\u65c5\uff1a\u6df1\u5165\u7528 Go \u505a\u9879\u76ee](https://golang2.eddycjy.com/)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u8bbe\u8ba1\u54f2\u5b66\uff1a\u4e86\u89e3 Go \u7684\u4e3a\u4ec0\u4e48\u548c\u8bbe\u8ba1\u601d\u8003](https://golang3.eddycjy.com/)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u8fdb\u9636\u4e4b\u65c5\uff1a\u8fdb\u4e00\u6b65\u6df1\u5165 Go \u6e90\u7801](https://golang1.eddycjy.com/)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011HTTP \u7cfb\u5217\u6559\u7a0b](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1383459655464337409&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00 Web \u7f16\u7a0b](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1323498303014780929&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5e76\u53d1\u7f16\u7a0b](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1325302744319737858&scene=21&from_msgid=2247484375&from_itemidx=1&count=3&nolastread=1#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u6e90\u7801](https://mp.weixin.qq.com/mp/homepage?__biz=MzkyNzI1NzM5NQ==&hid=2&sn=4d298cf2d9ad21260321275cf6c75194&scene=1&devicetype=iOS14.0&version=18000733&lang=zh_CN&nettype=3G+&ascene=7&session_us=gh_169729c17b9c&fontScale=100)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go\u6e90\u7801\u4e0e\u5e95\u5c42](http://mp.weixin.qq.com/mp/homepage?__biz=MzkyMzIyNjIxMQ==&hid=1&sn=631fe1ce375f2cd672449d0bd01963d2&scene=18#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Kubernetes \u5b66\u4e60\u7b14\u8bb0](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1394839706508148737&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011\u5fae\u670d\u52a1\u8bbe\u8ba1\u548c\u601d\u8003](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1488826194207752195&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u5fae\u670d\u52a1\u5b9e\u6218](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1809543596702777345&scene=21&from_msgid=2247492061&from_itemidx=1&count=3&nolastread=1#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5b9e\u6218\u6280\u5de7](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1326949382503219201&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u9762\u8bd5\u9898](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1751854579329056768&count=3#wechat_redirect)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Effective Go](https://go.dev/doc/effective_go)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Go FAQ](https://go.dev/doc/faq)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - blog\u6587\u7ae0](https://go.dev/blog/all)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - \u5404\u4e2atalk\u8d44\u6599](https://go.dev/talks/)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303](https://tonybai.com/2019/10/12/uber-go-style-guide/)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Google Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303](https://tonybai.com/google-go-style/)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - SliceTricks](https://github.com/golang/go/wiki/SliceTricks)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - CompilerOptimizations](https://github.com/golang/go/wiki/CompilerOptimizations#optimized-memclr)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - learning-more-about-go](https://github.com/golang/go/wiki#learning-more-about-go)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - go-concurrency-guide](https://github.com/luk4z7/go-concurrency-guide)\\n- Golang \u6587\u7ae0\u5206\u4eab\\n - \u2b50\ufe0f [Golang\u5f00\u53d1\u624b\u8bb0](https://github.com/kevinyan815/gocookbook)\\n - \u2b50\ufe0f [\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8](https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg)\\n - \u2b50\ufe0f [\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6307\u5357\u7bc7](https://mp.weixin.qq.com/s/rOtR8FfMpfBZrIkyRrNsfQ)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6982\u8ff0\u7bc7](https://mp.weixin.qq.com/s/RCBUlu0gRuVFSQ2m8Uyycg)\\n - \u2b50\ufe0f [\u4e07\u5b57\u957f\u6587\uff0c\u6559\u4f60\u7528go\u5f00\u53d1\u533a\u5757\u94fe\u5e94\u7528](https://mp.weixin.qq.com/s/vP2IDCK4cjyIGiutCoA7Pw)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u7f51\u7edc\u4e0d\u901a\uff1fnet/http\u81ea\u5e26\u7684\u8fd9\u4e2a\u5de5\u5177\u5e2e\u4f60\u5feb\u901f\u5b9a\u4f4d](https://mp.weixin.qq.com/s/8_pJiuOzoQt6xyoLUX0CIw)\\n - \u2b50\ufe0f [\u98a0\u8986\u5fae\u670d\u52a1\u67b6\u6784\uff1f\u8c37\u6b4c\u6700\u65b0\u5f00\u6e90service weaver\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/RnsM-bWSRBiDS4v1JcRzdg)\\n - \u2b50\ufe0f [\u4e00\u4e2a Go \u7a0b\u5e8f\u7684 Benchmark \u57fa\u51c6\u5206\u6790\u5de5\u5177](https://mp.weixin.qq.com/s/i1loQpQufni3v4Ho2J6Pgw)\\n - \u2b50\ufe0f [\u4f60\u8bf4 Go \u7684\u5207\u7247\u539f\u751f\u652f\u6301\u5e76\u53d1\u5417](https://mp.weixin.qq.com/s/RLqjkV_1geeVkXeG9TLHFw)\\n - \u2b50\ufe0f [\u7535\u8111\u7528GoLand\u592a\u5361\uff0c\u8bb0\u5f55\u4e0b\u81ea\u5df1\u628aVsCode\u5b9a\u5236\u6210Go IDE\u7684\u6b65\u9aa4\u548c\u8fc7\u7a0b](https://mp.weixin.qq.com/s/gNQETEVBMOH0US42M0uODg)\\n - \u2b50\ufe0f [\u7528\u4e86Go\u533f\u540d\u7ed3\u6784\u4f53\uff0c\u642c\u7816\u6548\u7387\u66f4\u9ad8\uff0c\u4ea7\u91cf\u66f4\u8db3\u4e86](https://mp.weixin.qq.com/s/iRgaOlFs52O2TMScu8wDzg)\\n - \u2b50\ufe0f [\u5408\u8ba2\u672c\uff5c\u7528Go\u8bed\u8a00\u5b9e\u73b023\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u53ca\u5b66\u4e60\u91cd\u70b9](https://mp.weixin.qq.com/s/KaesgBLyTz7xi9eXvSTMmQ)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u4e2d\u4ecb\u8005\uff0c\u6700\u540e\u7684\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/91-XUm5Gn9oQLd_F4dLb3A)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u89e3\u91ca\u5668\u6a21\u5f0f](https://mp.weixin.qq.com/s/8v0UZWygCvkbye4Y0P-3sQ)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u547d\u4ee4\u6a21\u5f0f](https://mp.weixin.qq.com/s/n1R1fnRZuDwlaQqsDh5y3g)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u5907\u5fd8\u5f55\u6a21\u5f0f\uff0c\u5e26\u6682\u5b58\u7684\u4e1a\u52a1\u529f\u80fd\u53ef\u4ee5\u53c2\u8003\u5b83\u6765\u5b9e\u73b0](https://mp.weixin.qq.com/s/RikZAeI2Pic4vYwVNh4HnA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u8bbf\u5ba2\u6a21\u5f0f](https://mp.weixin.qq.com/s/qsw89qI8DOXyb4C1XI5QtA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f-\u8fed\u4ee3\u5668\u5230\u5e95\u662f\u4e0d\u662f\u4e00\u4e2a\u591a\u6b64\u4e00\u4e3e\u7684\u6a21\u5f0f](https://mp.weixin.qq.com/s/sABibBRsC2kknbAH18oatA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u6865\u63a5\u6a21\u5f0f\uff0c\u8ba9\u4ee3\u7801\u65e2\u80fd\u591a\u7ef4\u5ea6\u6269\u5c55\u53c8\u4e0d\u4f1a\u81c3\u80bf](https://mp.weixin.qq.com/s/O8shSU46TcgFPx3h7NGFAA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u4eab\u5143\u6a21\u5f0f\uff0c\u8282\u7701\u5185\u5b58\u7684\u597d\u5e2e\u624b](https://mp.weixin.qq.com/s/AZHO7R6IXFG8MguDpUNdbw)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f\u5b9e\u6218--\u7528\u72b6\u6001\u6a21\u5f0f\u5b9e\u73b0\u7cfb\u7edf\u5de5\u4f5c\u6d41\u548c\u72b6\u6001\u673a](https://mp.weixin.qq.com/s/X9dKNO6sd-OY2VfsZpaElA)\\n - \u2b50\ufe0f [\u5916\u89c2\u6a21\u5f0f\uff0c\u4e00\u4e2a\u6bcf\u5929\u90fd\u5728\u7528\uff0c\u5374\u88ab\u591a\u6570\u4eba\u5728\u9762\u8bd5\u4e2d\u5ffd\u89c6\u7684\u6a21\u5f0f](https://mp.weixin.qq.com/s/tC9xfZFJvcNEbTXHQYvT6w)\\n - \u2b50\ufe0f [Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u9879\u76ee\u4f9d\u8d56\u8026\u5408\u5ea6\u592a\u9ad8\uff1f\u53ef\u4ee5\u7528\u9002\u914d\u5668\u505a\u4e0b\u4f18\u5316](https://mp.weixin.qq.com/s/r8975amH-DcJkWQKytIeJQ)\\n - \u2b50\ufe0f [Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u7ec4\u5408\uff0c\u4e00\u4e2a\u5bf9\u6570\u636e\u7ed3\u6784\u7b97\u6cd5\u548c\u804c\u573a\u90fd\u6709\u63d0\u5347\u7684\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/JKWbyr4Yt7A6l1nFsANUcQ)\\n - \u2b50\ufe0f [Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u88c5\u9970\u5668\u548c\u804c\u8d23\u94fe\uff0c\u54ea\u4e2a\u6a21\u5f0f\u5b9e\u73b0\u4e2d\u95f4\u4ef6\u66f4\u79d1\u5b66](https://mp.weixin.qq.com/s/_e9Qa97gZvgv9n-pFB4lFw)\\n - \u2b50\ufe0f [sourcegraph \u51fa\u54c1\u7684\u5e76\u53d1\u5e93 conc \u8be6\u89e3](https://mp.weixin.qq.com/s/59cxPFHWcdnUxKyRyo8SKw)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5b9e\u73b0\u7684\u53ef\u8bfb\u6027\u66f4\u9ad8\u7684\u5e76\u53d1\u795e\u5e93](https://mp.weixin.qq.com/s/AUSse5z1YES9wtKCiMdyWA)\\n - \u2b50\ufe0f [\u4e24\u79cd Option \u7f16\u7a0b\u6a21\u5f0f\u7684\u5b9e\u73b0\uff0cUber\u63a8\u8350\u8fd9\u4e00\u79cd](https://mp.weixin.qq.com/s/LW8Woq5Rg4x31DbtD-_jeA)\\n - \u2b50\ufe0f [Go\u7248\u672c\u5927\u4e8e1.13\uff0c\u7a0b\u5e8f\u91cc\u8fd9\u6837\u505a\u9519\u8bef\u5904\u7406\u624d\u5730\u9053](https://mp.weixin.qq.com/s/SFbSAGwQgQBVWpySYF-rkw)\\n - \u2b50\ufe0f [\u9762\u8bd5\u5b98\uff1anet/http\u5e93\u77e5\u9053\u5417\uff1f\u80fd\u8bf4\u8bf4\u4f18\u7f3a\u70b9\u5417](https://mp.weixin.qq.com/s/IelVDnMzGtT5y7hGSb_OxA)\\n - \u2b50\ufe0f [Go \u6a21\u7cca\u6d4b\u8bd5fuzzing\u7684\u539f\u7406\u5206\u6790](https://mp.weixin.qq.com/s/3uWozu4VIUJHyIGut3_0Bg)\\n - \u2b50\ufe0f [Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u6015\u628a\u6838\u5fc3\u4ee3\u7801\u6539\u4e71\uff0c\u8bb0\u5f97\u7528\u4ee3\u7406\u6a21\u5f0f](https://mp.weixin.qq.com/s/FTXkgxkUzsHMIspCK60G4w)\\n - \u2b50\ufe0f [\u4f60\u4e5f\u662f\u4e1a\u52a1\u5f00\u53d1\uff1f\u63d0\u524d\u7528\u8fd9\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u9884\u9632\u4ea7\u54c1\u52a0\u9700\u6c42\u5427](https://mp.weixin.qq.com/s/zCh12E10JM24EGTyFS7hPQ)\\n - \u2b50\ufe0f [Go \u7a0b\u5e8f\u91cc if else \u5206\u652f\u592a\u591a\uff1f\u8bd5\u7740\u7528\u7b56\u7565\u6a21\u5f0f\u6cbb\u7406\u4e00\u4e0b\u5427](https://mp.weixin.qq.com/s/IQsojcdwLZ1g0TgVQDoqVw)\\n - \u2b50\ufe0f [\u7528Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f-\u63d0\u70bc\u6d41\u7a0b\uff0c\u51cf\u5c11\u91cd\u590d\u5f00\u53d1\u5c31\u9760\u5b83\u4e86!](https://mp.weixin.qq.com/s/-Ysho1jI9MfrAIrplzj7UQ)\\n - \u2b50\ufe0f [Go Gin\u6846\u67b6\u8bf7\u6c42\u81ea\u52a8\u9a8c\u8bc1\u548c\u6570\u636e\u7ed1\u5b9a\uff0c\u770b\u5b8c\u8fd9\u7bc7\u5c31\u4f1a\u7528\u4e86](https://mp.weixin.qq.com/s/cAwc6ZhdUwxkI5VT8LY9Hg)\\n - \u2b50\ufe0f [Go\u5f00\u6e90\u5e93\u3001\u5927\u9879\u76ee\u7684\u516c\u5171\u5305\uff0c\u662f\u8fd9\u4e48\u7528\u5efa\u9020\u8005\u6a21\u5f0f\u7684](https://mp.weixin.qq.com/s/Uu3EAWpRO9pSbg1F1DLa_w)\\n - \u2b50\ufe0f [Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u539f\u578b\u6a21\u5f0f\u7684\u8003\u67e5\u70b9\u548c\u4f7f\u7528\u63a8\u8350](https://mp.weixin.qq.com/s/y1qHsQNR7EWeDU5g60Loqg)\\n - \u2b50\ufe0f [\u5de5\u5382\u6a21\u5f0f\u6709\u4e09\u4e2aLevel\uff0c\u4f60\u80fd\u7528Go\u5199\u5230\u7b2c\u51e0\u5c42](https://mp.weixin.qq.com/s/MlC6-TDf06LGpF8hxcSV_w)\\n - \u2b50\ufe0f [\u6700\u7b80\u5355\u7684\u5355\u4f8b\u6a21\u5f0f\uff0cGo\u7248\u672c\u7684\u5b9e\u73b0\u4f60\u5199\u5bf9\u4e86\u5417](https://mp.weixin.qq.com/s/1ZuhUA9Lt2uLFlamIY6fLQ)\\n - \u2b50\ufe0f [\u62d2\u7edd Go \u4ee3\u7801\u81c3\u80bf\uff0c\u5176\u5b9e\u5728\u8fd9\u51e0\u5757\u53ef\u4ee5\u7528\u4e0b\u89c2\u5bdf\u8005\u6a21\u5f0f](https://mp.weixin.qq.com/s/OKUeAdicn0Bvkz8dYx1epQ)\\n - \u2b50\ufe0f [Go\u6307\u9488\u7684\u4f7f\u7528\u9650\u5236\u548c\u7a81\u7834\u4e4b\u8def](https://mp.weixin.qq.com/s/SpVTl64W1Exy8fuN15-kmA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u7684IO\u5e93\u90a3\u4e48\u591a\uff0c\u6211\u8be5\u600e\u4e48\u9009](https://mp.weixin.qq.com/s/TtN6NZ8hQ2AIf0C8wVzkjA)\\n - \u2b50\ufe0f [Go \u773c\u4e2d\u7684\u6587\u4ef6\u7cfb\u7edf\u662f\u4ec0\u4e48\uff1f io.FS](https://mp.weixin.qq.com/s/gYWhjh1BburgeAU72mn_aw)\\n - \u2b50\ufe0f [\u51e0\u4e2a\u63d0\u5347Go\u8bed\u8a00\u5f00\u53d1\u6548\u7387\u7684\u5c0f\u6280\u5de7](https://mp.weixin.qq.com/s/zJXPGYwNXIUyEOI0Kc15rg)\\n - \u2b50\ufe0f [\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8](https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg)\\n - \u2b50\ufe0f [Gophers\u5982\u4f55\u51c6\u5907\u9762\u8bd5](https://mp.weixin.qq.com/s/Elq7SWRpH08KmhX7auboOA)\\n - \u2b50\ufe0f [Go Modules\u77e5\u8bc6\u70b9\u603b\u7ed3](https://mp.weixin.qq.com/s/FEPXDMFfvKgmtsymVTWzHw)\\n - \ud83c\udf1b [\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae](https://juejin.cn/post/7147939014870302756)\\n - \ud83c\udf1b [GO\u9762\u8bd5\u5fc5\u77e5\u5fc5\u4f1a\u9762\u8bd5\u9898](https://juejin.cn/post/7131717990558466062)\\n - [\u8fd9\u4e9b\u6700\u5e38\u7528\u7684 Go CLI \u547d\u4ee4\uff0c\u65b0\u624b Gopher \u5e94\u8be5\u638c\u63e1](https://mp.weixin.qq.com/s/kyGNVNDby5uq5JGfQt4Yrg)\\n - [PGO \u662f\u5565\uff0c\u548b\u5c31\u8ba9 Go \u66f4\u5feb\u66f4\u731b\u4e86](https://mp.weixin.qq.com/s/7uobN6DmpIYqG34pOpvvlA)\\n - [Go for \u5faa\u73af\u6709\u65f6\u5019\u771f\u7684\u5f88\u5751](https://mp.weixin.qq.com/s/Pcp2FjcXk7Q7sV0Z-bEUNw)\\n - [\u6df1\u5ea6\u89e3\u5bc6Go\u8bed\u8a00\u4e4b\u5173\u4e8e interface \u7684 10 \u4e2a\u95ee\u9898](https://mp.weixin.qq.com/s/6KxJRG3lKUDY734t4EzAaA)\\n - [\u624b\u64b8\u6e90\u7801\u7cfb\u5217 - cache2go](https://mp.weixin.qq.com/s/qyEiEACuUd8SsyqCDLUjXA)\\n - [Go\u5e38\u89c1\u9519\u8bef\u96c6\u9526\u4e4b\u51fd\u6570\u5f0f\u9009\u9879\u6a21\u5f0f](https://mp.weixin.qq.com/s/nc4s289ULpQkGlQuaFbZlQ)\\n - [\u8be6\u89e3\u5e76\u53d1\u7f16\u7a0b\u57fa\u7840\u4e4b\u539f\u5b50\u64cd\u4f5c(atomic\u5305)](https://mp.weixin.qq.com/s/THMhcM9TXydW8K5-Vvqvxg)\\n - [\u5b66\u4e60channel\u8bbe\u8ba1\uff1a\u4ece\u5165\u95e8\u5230\u653e\u5f03](https://mp.weixin.qq.com/s/E2XwSIXw1Si1EVSO1tMW7Q)\\n - [context\u4f7f\u7528\u4e0d\u5f53\u5f15\u53d1\u7684\u4e00\u4e2abug](https://mp.weixin.qq.com/s/lJxjlDg5SkQyNLZBpOPP5A)\\n - [Go\u8bed\u8a00\u5982\u4f55\u5b9e\u73b0\u53ef\u91cd\u5165\u9501](https://mp.weixin.qq.com/s/S_EzyWZmFzzbBbxoSNe6Hw)\\n - [\u5982\u4f55\u5728\u6d4b\u8bd5\u4e2d\u53d1\u73b0goroutine\u6cc4\u6f0f](https://mp.weixin.qq.com/s/zlqZ-4EdzMNt3iubMknKLA)\\n - [\u8bf7\u52ff\u6ee5\u7528goroutine](https://mp.weixin.qq.com/s/JC14dWffHub0nfPlPipsHQ)\\n - [\u9762\u8bd5\u5b98\uff1a\u54e5\u4eecGo\u8bed\u8a00\u4e92\u65a5\u9501\u4e86\u89e3\u5230\u4ec0\u4e48\u7a0b\u5ea6\u4e86](https://mp.weixin.qq.com/s/bhze_LcFHk7Y-QB4nEQKnA)\\n - [Go\u5de5\u5177\u4e4bgenerate](https://mp.weixin.qq.com/s/E45dNnEURe87P709Ovu-Qw)\\n - [\u63a2\u7a76 Go \u6e90\u7801\u4e2d panic & recover \u6709\u54ea\u4e9b\u5751](https://mp.weixin.qq.com/s/dN9G4Tnt9HgVqlNh73HNUQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#41 substrings and memory leaks](https://mp.weixin.qq.com/s/Wdh2O4cnez95x0RBpMiDvQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#38 Misusing trim functions](https://mp.weixin.qq.com/s/39S-WWKt1rYNF9OUfFSCbw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#37 Inaccurate string iteration](https://mp.weixin.qq.com/s/m0WyJyd2JwQfX1SP2H-jrA)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#36 Not understanding the concept of a rune](https://mp.weixin.qq.com/s/P6rEyeLvl8gxT_4RJf235Q)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#35 Using defer inside a loop](https://mp.weixin.qq.com/s/Ls1_qaEnuc8MSZoDyTwa1Q)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#34 Ignoring how the break statement works](https://mp.weixin.qq.com/s/XRQq1O9VROBxItSP4kC8zA)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#33 Making wrong assumptions during map iterations](https://mp.weixin.qq.com/s/gwsWE-NTBOs0NnsdNG4WBw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#32 Ignoring the impact of using pointer ...](https://mp.weixin.qq.com/s/58EVYGZ02xPfGYrprk7dRw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#31 Ignoring how arguments are evaluated in ...](https://mp.weixin.qq.com/s/cuJAYXGOleUt0FG5brX8ng)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#30 Ignoring the fact that elements are copied](https://mp.weixin.qq.com/s/71wpR1kz5PgzVNBgpN855g)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#29 Comparing values incorrectly](https://mp.weixin.qq.com/s/fpHMk37QGLQCXrPAdxXC_w)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#28 maps and memory leaks](https://mp.weixin.qq.com/s/s5-Pl5u6yoZCPWwoeINs9g)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#27 Inefficient map initialization](https://mp.weixin.qq.com/s/9pfznxXKHCv-QEZBqHw1YQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#26 slices and memory leaks](https://mp.weixin.qq.com/s/TYxqo1BniI-wfKVHQsrjjw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#25 Unexpected side effects using slice append](https://mp.weixin.qq.com/s/lAIB0l666R6Zh9NAdV809g)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#24 Not making slice copies correctly](https://mp.weixin.qq.com/s/vZBePdCuKe12OMQOj6Rz4A)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#23 Not properly checking if a slice is empty](https://mp.weixin.qq.com/s/WsFGv9tcdRLP9K-NQSqimA)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#22 Being confused about nil vs. empty slices](https://mp.weixin.qq.com/s/uHmCU0v0xJ2RYlmq_lQAiQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#20 Not understanding slice length and capacity](https://mp.weixin.qq.com/s/-Kt2QJdzEUDJx8MFvrUo7Q)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#12 Project misorganization](https://mp.weixin.qq.com/s/epK_0yn_EPIWJjz9xmddcA)\\n - [100 Go Mistakes and How to Avoid Them](https://github.com/teivah/100-go-mistakes)\\n - [Go \u4e2d\u57fa\u4e8e IP \u5730\u5740\u7684 HTTP \u8bf7\u6c42\u9650\u6d41](https://mp.weixin.qq.com/s/aj_hULmeqy3whILr2ytECQ)\\n - [\u9879\u76ee\u5b9e\u6218\uff1a\u7528 Go \u521b\u5efa\u4e00\u4e2a\u7b80\u6613\u8d1f\u8f7d\u5747\u8861\u5668](https://mp.weixin.qq.com/s/pe0CQa3tdrUmC86OSRBNeg)\\n - [\u4f60\u77e5\u9053\u51e0\u79cdGo\u5e76\u53d1\u63a7\u5236\u65b9\u5f0f](https://mp.weixin.qq.com/s/tloEYzrnKNrrAo1YKdeyrw)\\n - [\u6d45\u8c08Golang\u4e24\u79cd\u7ebf\u7a0b\u5b89\u5168\u7684map](https://mp.weixin.qq.com/s/H5HDrwhxZ_4v6Vf5xXUsIg)\\n - [Go\u7cbe\u5999\u7684\u4e92\u65a5\u9501\u8bbe\u8ba1](https://mp.weixin.qq.com/s/YYvoeDfPMm8Y2kFu9uesGw)\\n - [Go\u66f4\u7ec6\u7c92\u5ea6\u7684\u8bfb\u5199\u9501\u8bbe\u8ba1](https://mp.weixin.qq.com/s/CEIQUa7H43FR7M1ghkDSGg)\\n - [Go \u7684 TryLock \u5b9e\u73b0](https://mp.weixin.qq.com/s/Mro5XC8dS5ZAMvEVbJZsCw)\\n - [Go1.18 \u65b0\u7279\u6027\uff1aTryLock \u662f\u4ec0\u4e48\uff1f\u9700\u8981\u5b83\u5417](https://mp.weixin.qq.com/s/oA6UJ-0R2OucFl-fbgrvWA)\\n - [Go\u4e2d\u770b\u4f3c\u7b80\u5355\u7684WaitGroup\u6e90\u7801\u8bbe\u8ba1\uff0c\u7adf\u7136\u6697\u542b\u8fd9\u4e48\u591a\u77e5\u8bc6](https://mp.weixin.qq.com/s/V2x0Nw3Y8lZxHYJh_yQ0dQ)\\n - [Go \u6807\u51c6\u5e93\u6e90\u7801\u5b66\u4e60\uff08\u4e00\uff09\u8be6\u89e3\u77ed\u5c0f\u7cbe\u608d\u7684 Once](https://mp.weixin.qq.com/s/Lsm-BMdKCKNQjRndNCLwLw)\\n - [Go \u4e2d\u4e3a\u4ec0\u4e48\u5efa\u8bae\u4f7f\u7528 NewXxx \u8fd9\u6837\u7684\u6784\u9020\u51fd\u6570](https://mp.weixin.qq.com/s/3VkcIg7NhCCiIwVRjuwR0A)\\n - [Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303](https://mp.weixin.qq.com/s/nA26g46tM_hu-khaGYniAQ)\\n - [\u600e\u4e48\u9009\u62e9 Go \u6587\u4ef6\u8bfb\u53d6\u65b9\u6848](https://mp.weixin.qq.com/s/KHzdEE_w_ev9p4v6MR7M8Q)\\n - [\u5982\u4f55\u6709\u6548\u63a7\u5236 Go \u7ebf\u7a0b\u6570](https://mp.weixin.qq.com/s/EeOxPkTe8WkOide49yIfEg)\\n - [\u52a0\u5927\u529b\u5ea6\uff01Go \u5c06\u4f1a\u589e\u5f3a Go1 \u5411\u540e\u517c\u5bb9\u6027](https://mp.weixin.qq.com/s/OIqgqjXEvVmDUmnRqq4PGw)\\n - [Go \u7684\u96f6\u503c\u6709\u4ec0\u4e48\u7528\uff1f\u770b\u770b\u8fd9 4 \u4e2a\u573a\u666f](https://mp.weixin.qq.com/s/Ucqqg4h9uRo7RVd8XCz80w)\\n - [Go \u53ea\u4f1a if err != nil\uff1f\u8fd9\u662f\u4e0d\u5bf9\u7684\uff0c\u5206\u4eab\u8fd9\u4e9b\u4f18\u96c5\u7684\u5904\u7406\u59ff\u52bf\u7ed9\u4f60\uff01](https://mp.weixin.qq.com/s/L_Sy4_6BURL4XWDK6bpEwg)\\n - [10+ \u6761 Go \u5b98\u65b9\u8c1a\u8bed\uff0c\u4f60\u77e5\u9053\u51e0\u6761\uff1f](https://mp.weixin.qq.com/s/cJON1H68eBFeuBpWhFbXXw)\\n - [Go \u9002\u5408 IO \u5bc6\u96c6\u578b\uff1f\u5e76\u4e0d\u51c6\u786e\uff01](https://mp.weixin.qq.com/s/xDXwsVjOfU2j3gisiHTZTQ)\\n - [\u5982\u4f55\u8ba9 Go \u53cd\u5c04\u53d8\u5feb](https://mp.weixin.qq.com/s/fzmN6zFVioQGedTdSDmyqQ)\\n - [\u6df1\u5165\u7406\u89e3StatefulSet\uff0c\u7528Kubernetes\u7f16\u6392\u6709\u72b6\u6001\u5e94\u7528](https://mp.weixin.qq.com/s/y60q0-RMh8isd4u4PuLfUg)\\n - [Go Modules \u7ec8\u6781\u5165\u95e8](https://juejin.cn/post/6844903433846145038)\\n - [\u975e\u5e38\u9002\u5408PHP\u540c\u5b66\u4f7f\u7528\u7684GO\u6846\u67b6\uff1aGoFrame](https://juejin.cn/post/7075098594151235597)\\n - [\u770b Go \u4e2d\u7684 struct \u5982\u4f55\u88ab\u4f18\u5316\uff0c\u8fd8\u6709\u5c0f\u63d2\u66f2](https://mp.weixin.qq.com/s/EGN7G8ku-zkaZuzfBwx9Qw)\\n - [\u5728 Go \u91cc\u7528 CGO\uff1f\u8fd9 7 \u4e2a\u95ee\u9898\u4f60\u8981\u5173\u6ce8\uff01](https://mp.weixin.qq.com/s/Qlqt1pP_Li-PxOICrz7bAw)\\n - [Go \u63a2\u8ba8\u4e86 13 \u5e74\uff0c\u600e\u4e48\u89e3\u51b3\u518d\u8d4b\u503c\u7684\u5751](https://mp.weixin.qq.com/s/Am0ORd08GsMc4xSdLG9kgg)\\n - [Go\u5982\u4f55\u4f18\u96c5\u7684\u8bb0\u5f55\u64cd\u4f5c\u65e5\u5fd7 | \u51b2\u523a\u6398\u91d1\u4e00\u5468](https://juejin.cn/post/7134497015576133669)\\n - [\u5982\u4f55\u66f4\u76f4\u89c2\u5730\u7406\u89e3 Go \u8c03\u5ea6\u8fc7\u7a0b](https://mp.weixin.qq.com/s/0c7emt54ayCrm1K16lk2SQ)\\n - [Go1.19 \u90a3\u4e9b\u4f60\u4e0d\u77e5\u9053\u7684\u65b0\u7279\u6027](https://mp.weixin.qq.com/s/FviFOLkIHuEjZdTg_qCoNQ)\\n - [Go \u4e2d\u53ef\u522b\u7528\u590d\u5236\u9501\uff0c\u4f1a\u6709\u8fd9\u4e9b\u5927\u95ee\u9898\uff01](https://mp.weixin.qq.com/s/SrqJdng9cNUEVAS7nFaqAA)\\n - [\u4f19\u8ba1\uff0cGo\u9879\u76ee\u600e\u4e48\u4f7f\u7528\u679a\u4e3e](https://mp.weixin.qq.com/s/zyvO_hhUo1TRm6kMPcaFFQ)\\n - [Go ORM \u5355\u5143\u6d4b\u8bd5\u5168\u6d41\u7a0b\u8bb2\u89e3](https://mp.weixin.qq.com/s/XPPwHd7eDUjvzsnuFwgbyw)\\n - [\u8d85\u5168\u603b\u7ed3\uff1aGo\u8bed\u8a00\u5982\u4f55\u64cd\u4f5c\u6587\u4ef6](https://mp.weixin.qq.com/s/r30z2i_sSuRfEnM_23wFlg)\\n - [Go \u7684\u65f6\u95f4\u8f6c\u6362\u548c\u65f6\u533a\u6821\u5bf9\u603b\u8bb0\u4e0d\u4f4f\uff1f\u7ed9\u4f60\u4e00\u4efd\u5907\u5fd8\u5355](https://mp.weixin.qq.com/s/HaF9qieEJWNUoyY9qTvnKw)\\n - [\u641e\u6e05\u695a Go Mod\u7684\u7248\u672c\u548c\u4f2a\u7248\u672c\uff0c\u4e0b\u6b21\u522b\u4e71\u7528\u4e86](https://mp.weixin.qq.com/s/ptJK7CDHCr6P4JCdsUXKdg)\\n - [\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u5982\u4f55\u53d1\u5e03\u5230Go Module\u4e0a](https://mp.weixin.qq.com/s/7jLmwtP3xk-wbCFKqPLK2g)\\n - [\u8fd9\u4e0d\u4f1a\u53c8\u662f\u4e00\u4e2aGo\u7684BUG\u5427](https://mp.weixin.qq.com/s/Dn2oM89mHEgoz8yVQnNEoQ)\\n - [\u8fd9\u4e09\u4e2a Go \u6c34\u5e73\u81ea\u6d4b\u9898\uff0c\u624b\u5199\u4e0d\u51fa\u6765\u8fd8\u662f\u5148\u8001\u5b9e\u4e0a\u73ed\u5427](https://mp.weixin.qq.com/s/YojNHW7kkjmmdjqBXCuQYA)\\n - [\u4e0d\u60f3Go \u9519\u8bef\u5904\u7406\u592a\u81c3\u80bf\uff0c\u53ef\u4ee5\u53c2\u8003\u8fd9\u4e2a\u4ee3\u7801\u8bbe\u8ba1](https://mp.weixin.qq.com/s/pR_XHTnhft2Hi_mY7JuEJg)\\n - [\u5173\u4e8eGo\u7a0b\u5e8f\u9519\u8bef\u5904\u7406\u7684\u4e00\u4e9b\u5efa\u8bae](https://mp.weixin.qq.com/s/HuZn9hnHUBx3J4bAGYBYpw)\\n- Golang \u90e8\u7f72\\n - \u4f7f\u7528 Docker Desktop \u642d\u5efa k8s \u96c6\u7fa4\\n - [\u5929\u5450\uff01\u6211\u7528 go \u4ece\u96f6\u5f00\u59cb\u5199\u4e86\u4e00\u4e2a k8s \u5e94\u7528\u7ba1\u7406\u5de5\u5177\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u548c\u5f00\u53d1\u8fc7\u7a0b\uff09](https://mp.weixin.qq.com/s/MFd1R5VeEW0eLk-A4BqSQQ)\\n - [Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72](https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg)\\n - [\u638c\u63e1\u4e86\u8fd9\u7bc7 Dockerfile \u4e2d\u7684 ARG \u4f5c\u7528\u57df\uff0c \u5c31\u7b97 Build \u955c\u50cf CI \u5165\u95e8\u4e86 \u3010\u6587\u672b\u62bd\u5956\u3011](https://mp.weixin.qq.com/s/i3n0hoHRaYoDMWcC5DSQ3w)\\n - [\u9762\u8bd5\u95ee Dockerfile \u7684\u4f18\u5316\uff0c \u5343\u4e07\u4e0d\u8981\u53ea\u4f1a\u8bf4\u51cf\u5c11\u5c42\u6570](https://mp.weixin.qq.com/s/pen6G2aFsPfSqhKjgocVjQ)\\n - [\u6ca1\u60f3\u5230\u5728 Docker \u5bb9\u5668\u4e2d\u8bbe\u7f6e\u65f6\u533a\u8fd9\u4e48\u7b80\u5355](https://mp.weixin.qq.com/s/10Ll8ipVGWg4HU4hjwILsQ)\\n - [\u5feb\u6536\u85cf\uff01\u8d85\u5f3a\u56fe\u89e3Docker\u5e38\u89c1\u547d\u4ee4\u4e0e\u5b9e\u6218\uff01](https://mp.weixin.qq.com/s/5NTgcdhn6CiZ2tg44_T-FQ)\\n - [\u5b9e\u65f6\u53ef\u89c6\u5316Go Runtime\u6307\u6807\uff0c\u8fd9\u4e2aGo\u5e93\u8d85\u8d5e](https://mp.weixin.qq.com/s/rDSKItZ8hvgjvpp4f4VzCQ)\\n - [\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01](https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg)\\n - [\u4eceGo\u7a0b\u5e8f\u7b2c\u4e00\u884c\u4ee3\u7801\uff0c\u5230\u5728 K8s \u4e0a\u8fd0\u884c\uff0c\u8981\u7ecf\u5386\u591a\u5c11\u6b65](https://mp.weixin.qq.com/s/DEZPCzQul7wnZKqm1Ue6rg)\\n - [\u5728K8S\u4e0a\u7684Web\u670d\u52a1\u8be5\u600e\u4e48\u505a\u57df\u540d\u89e3\u6790\u5462](https://mp.weixin.qq.com/s/ZU61NIMxh_UOo-chNvkPXA)\\n - https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/\\n - [Kubernetes\u5165\u95e8\u5b9e\u8df5--\u90e8\u7f72\u8fd0\u884cGo\u9879\u76ee](https://mp.weixin.qq.com/s/uruu3qbpSLbTRJJRcWTYqg)\\n - [\u7ebf\u4e0aGo\u9879\u76ee\u7684Docker\u955c\u50cf\u5e94\u8be5\u600e\u4e48\u6784\u5efa](https://mp.weixin.qq.com/s/hoJgL-sP2OtMEFAhYNCItA)\\n - [Docker \u5b66\u4e60\u7b14\u8bb0](https://blog.opskumu.com/docker.html)\\n - [\u7a0b\u5e8f\u89e3Bug\u6700\u5e38\u7528\u7684K8s\u547d\u4ee4\uff0c\u5916\u52a0\u4f7f\u7528\u7a8d\u95e8](https://mp.weixin.qq.com/s/Ze096f0Utcl84c6gBwrCYw)\\n- Golang \u5f00\u6e90\u5e93\u63a8\u8350\\n - \u2b50\ufe0f \u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5\\n - [HTTP \u6846\u67b6 Hertz \u5b9e\u8df5\u5165\u95e8\uff1a\u6027\u80fd\u6d4b\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/J6ziP7VOitGk-lz8NGdDrA)\\n - [\u5b57\u8282\u5f00\u6e90WEB\u6846\u67b6Hertz\u592a\u9999\u5566\uff01](https://juejin.cn/post/7124337913352945672)\\n - [\u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5](https://juejin.cn/post/7153889167385526308)\\n - https://github.com/cloudwego/hertz\\n - [ByteDance Practices on Go Network Library](https://www.cloudwego.io/blog/2021/10/09/bytedance-practices-on-go-network-library/)\\n - https://www.cloudwego.io/docs/hertz/getting-started/\\n - [Go \u8bed\u8a00\u7ec8\u6781\u641c\u7d22\u63d2\u4ef6](https://mp.weixin.qq.com/s/025-MLMAbdT38kWI--AoYg)\\n - [\u300cGo\u5f00\u6e90\u5305\u300dsnappy\uff1agoogle\u5f00\u6e90\u7684\u5feb\u901f\u3001\u65e0\u635f\u538b\u7f29\u5305](https://mp.weixin.qq.com/s/ie7LqXZQOUX0Bfn4QhHzLA)\\n - [\u300cGo\u5f00\u6e90\u5305\u300dxxhash\uff1a\u6bd4\u6807\u51c6\u5e93\u66f4\u5feb\uff0c\u57fa\u4e8exxHash\u7b97\u6cd5\u5b9e\u73b0\u768464\u4f4d\u7684\u6574\u578bhash\u503c](https://mp.weixin.qq.com/s/Vkx8zzm1SjIl4IXLib3xkQ)\\n - [\u300cGo\u5f00\u6e90\u5305\u300denv\uff1a\u4e00\u4e2a\u5c06\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u89e3\u6790\u5230\u7ed3\u6784\u4f53\u7684\u5e93](https://mp.weixin.qq.com/s/xt0v6snX6y5jaOy1IniwVw)\\n - \u2b50\ufe0f [\u300cGo\u5f00\u6e90\u5305\u300dchromedp\uff1a\u4e00\u4e2a\u57fa\u4e8eChrome DevTools\u534f\u8bae\u7684\u5e93\uff0c\u652f\u6301\u6570\u636e\u91c7\u96c6\u3001\u622a\u53d6\u7f51\u9875\u957f\u56fe](https://mp.weixin.qq.com/s/rGPsEt-XDOayDWwLGxvcsw)\\n - \u2b50\ufe0f [\u300cGo\u5f00\u6e90\u5305\u300dnunu\uff1a\u4e00\u4e2a\u5feb\u901f\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u811a\u624b\u67b6](https://juejin.cn/post/7248951438742339639)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Shopify \u51fa\u54c1\u7684\u5b8c\u6574\u5ea6\u6700\u5b8c\u5584\u7684 Kafka \u5ba2\u6237\u7aef_sarama](https://mp.weixin.qq.com/s/_TBmfaVwvX5VDRe8kLReXA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300dGolang\u7684Ealstic\u94fe\u63a5\u5e93](https://mp.weixin.qq.com/s/iHIxsEZf3w06GbO2sHSuRA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u534f\u7a0b\u6c60ants\u4ecb\u7ecd](https://mp.weixin.qq.com/s/wGqwfX8lEifeD_VGcITmHw)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528 cmux \u5b9e\u73b0\u670d\u52a1\u7aef\u8fde\u63a5\u591a\u8def\u590d\u7528](https://mp.weixin.qq.com/s/2cERDCRKlmfHKv8gY324Hg)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528GO\u8bed\u8a00\u542f\u52a8docker Container](https://mp.weixin.qq.com/s/dkbpIvy1o5aLnklt0ddIDA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u62bd\u8c61\u8bed\u6cd5\u6811go/ast\u5e93\u4f7f\u7528](https://mp.weixin.qq.com/s/uLpmEV8mI4JpfNVfSK8cRQ)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4e07\u80fd\u7684\u5bf9\u8c61\u62f7\u8d1d\u5de5\u5177\u2014\u2014Copier](https://mp.weixin.qq.com/s/weT4KUTTLWdQaC6q7VrPPg)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u6f0f\u6876\u9650\u6d41\u5e93 \u2014 uber-go/ratelimit](https://mp.weixin.qq.com/s/q3wRIvoXpnPLPJsDAPTdeA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u65f6\u95f4\u8f6e\u7b97\u6cd5\u5b9a\u65f6\u5668antlabs/timer\u4ecb\u7ecd](https://mp.weixin.qq.com/s/emNifkcdn9oRjVHRcQmK9w)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Goroutine \u6cc4\u6f0f\u9632\u6cbb\u795e\u5668 goleak](https://mp.weixin.qq.com/s/3iPqxiK2mf9Fl5CSZ9U7RQ)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011\u5f02\u6b65\u4efb\u52a1\u961f\u5217Asynq](https://mp.weixin.qq.com/s/SWyMIE1rtVDVUPEFno4xsQ)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011protobuf\u751f\u6210Go\u4ee3\u7801\u63d2\u4ef6gogo/protobuf](https://mp.weixin.qq.com/s/X6Fo_6pEZTIZJ-1MJNrg6A)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Golang\u5b98\u65b9\u8ba4\u53ef\u7684websocket\u5e93-gorilla/websocket](https://mp.weixin.qq.com/s/ZoVr9ubPgcvjX9ERiQoLyA)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Html\u89e3\u6790\u5229\u5668-goquery\u5e93](https://mp.weixin.qq.com/s/JrEQwQZQRwf4SymprwKUmw)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u9ad8\u6027\u80fd\u4e2d\u6587\u5206\u8bcd\u5e93 gojieba](https://mp.weixin.qq.com/s/zRmAjQ0o9n8FE1R0WcnUtQ)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u89e3\u6790http\u4e2d\u7684user-agent\uff0c\u5c31\u7528\u8fd9\u4e2a\u5305\uff1auser_agent](https://mp.weixin.qq.com/s/8YRqypiW1dQQVlZkmCd1mQ)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u63a8\u8350\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u3001\u8bed\u4e49\u5316\u7684\u65f6\u95f4\u5904\u7406\u5e93\uff1acarbon](https://mp.weixin.qq.com/s/92O1SHs4tw1FMcDeQoSfkA)\\n - [Go\u6bcf\u65e5\u4e00\u5e93\u4e4bCSRF\u5e93\u7684\u4f7f\u7528\u65b9\u5f0f\u548c\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/n-kU6nwhOH6ouhufrP_1kQ)\\n - [Go \u6bcf\u65e5\u4e00\u5e93\u4e4b go-cache \u7f13\u5b58](https://mp.weixin.qq.com/s/f4FAt-RgraOFXSfZmWjeoQ)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300dredis\u5b98\u7f51\u63a8\u8350\u7684go\u7248\u672c\u7684\u5206\u5e03\u5f0f\u9501\uff1aredsync](https://mp.weixin.qq.com/s/KCj-mCkZpcEu3GXkuRLTuA)\\n - https://github.com/samber/lo\\n - https://github.com/nikoksr/notify\\n - https://github.com/go-chi/chi\\n - https://github.com/gin-gonic/examples\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u91cd\u78c5\u63a8\u8350\uff1a\u4e00\u4e2a\u56fd\u4ea7\u7684\uff0cstar\u9ad8\u8fbe12k+\u7684\u64cd\u4f5cexcel\u7684\u5305\uff1aExcelize](https://mp.weixin.qq.com/s/zLNwq32UKaCsaAXn2BaZkw)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u4e00\u4e2a\u8ba9\u7ec8\u7aef\u5185\u5bb9\u5f69\u8272\u5316\u7684\u5de5\u5177\uff1aColor](https://mp.weixin.qq.com/s/Y3NGQH3hrT85O7aN7IrCIQ)\\n- Golang \u76f8\u5173\u8d44\u6e90\\n - \ud83c\udf1f [Russ Cox \u7684\u4e2a\u4eba\u535a\u5ba2](https://research.swtch.com/)\\n - \ud83c\udf1f [Tony Bai \u535a\u5ba2](https://tonybai.com/articles/)\\n - \ud83c\udf1f [Gopher Daily](https://gopherdaily.tonybai.com/)\\n - \ud83c\udf1f [ChatGPT \u4e0e\u6211\u5408\u529b\u5f00\u53d1 xargin blog archive \u63d2\u4ef6\uff1a\u66f9\u5927\u535a\u5ba2\u7684\u65b0\u5947\u63a2\u9669](https://xargin.com/)\\n - \ud83c\udf1f [qcrao \u7684\u535a\u5ba2](https://qcrao.com/)\\n - \ud83c\udf1f [Go \u7a0b\u5e8f\u5458\u9762\u8bd5\u7b14\u8bd5\u5b9d\u5178](https://github.com/golang-design/go-questions)\\n - \ud83c\udf1f [Go\u8bed\u8a00\u5723\u7ecf\uff08\u4e2d\u6587\u7248\uff09](https://books.studygolang.com/gopl-zh/)\\n - \ud83c\udf1f [Go\u8bed\u8a00\u6807\u51c6\u5e93\u4e66\u7c4d](http://books.studygolang.com/The-Golang-Standard-Library-by-Example/)\\n - \ud83c\udf1f [\u5730\u9f20\u6587\u6863](https://www.topgoer.cn/)\\n - \ud83c\udf1f [go\u8bed\u8a00\u4e2d\u6587\u6587\u6863 - \u5730\u9f20\u6587\u6863](https://www.topgoer.cn/docs/golang/golang-1ccjbpfstsfi1)\\n - \ud83c\udf1f [Go \u5b98\u65b9\u8c1a\u8bed Go Proverbs](https://go-proverbs.github.io/)\\n - [GoLand 2023.2 \u53d1\u5e03\uff1a\u6709 AI \u52a9\u624b](https://mp.weixin.qq.com/s/cidtQEAfuFWuYveKFbFvKQ)\\n - [GoLand 2023.1 \u6b63\u5f0f\u53d1\u5e03\uff0c\u770b\u6709\u54ea\u4e9b\u65b0\u529f\u80fd](https://mp.weixin.qq.com/s/SVMj-PvI1l-oSlxI4zaNcw)\\n - [GoLand \u8fce\u6765\u4e94\u5468\u5e74\uff0c\u540c\u65f6\u53d1\u5e03 2022.3\uff1a\u6709\u5f69\u86cb](https://mp.weixin.qq.com/s/IvL24_7iuuRp9Y3dljHaHQ)\\n - \ud83c\udf1f [\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01](https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w)\\n - [\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw)\\n - [golang-developer-roadmap: 2020 \u5e74\u6210\u4e3a Go \u5f00\u53d1\u8005\u7684\u8def\u7ebf\u56fe](https://github.com/Alikhll/golang-developer-roadmap)\\n - [go-admin: \u57fa\u4e8e Gin + Vue + Element UI \u7684\u72ec\u7acb\u524d\u540e\u7aef\u6743\u9650\u7ba1\u7406\u7cfb\u7edf\u7684\u811a\u624b\u67b6](https://github.com/go-admin-team/go-admin)\\n - [awesome-go: \u7cbe\u9009\u7684 Go \u6846\u67b6\u3001\u5e93\u548c\u8f6f\u4ef6\u7684\u5217\u8868](https://github.com/avelino/awesome-go)\\n - [Go 13 \u5468\u5e74\u5566\uff01](https://mp.weixin.qq.com/s/wKxg6IVZCNK3NG2Os9_3jg)\\n - [\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566](https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ)\\n - \ud83c\udf1f [Golang By Example](https://golangbyexample.com/)\\n - [Golang Advanced Tutorial](https://golangbyexample.com/golang-comprehensive-tutorial/)\\n - [All Design Patterns in Go (Golang)](https://golangbyexample.com/all-design-patterns-golang/)\\n - [System Design Questions](https://techbyexample.com/system-design-questions/)\\n - [SOLID Go Design - Go\u8bed\u8a00\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1](https://blog.gokit.info/post/go-solid-design/)\\n - [go design pattern](https://github.com/mohuishou/go-design-pattern)\\n - [\u4e07\u5b57\u8be6\u6587\u9610\u91ca\u7a0b\u5e8f\u5458\u4fee\u70bc\u4e4b\u9053](https://mp.weixin.qq.com/s/XIwfj_AdZqX_vHM4VIq9EA)\\n - [\u4e07\u5b57\u8be6\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u505a Code Review](https://mp.weixin.qq.com/s/c3RApB8a98tWahgC9mahJg)\\n - [Go \u5b66\u4e60\u4e4b\u8def](https://github.com/talkgo/read)\\n - [1024\uff0c\u6211\u4eec\u7684\u8282\u65e5\uff0cGopher \u8be5\u5e72\u70b9\u5565](https://mp.weixin.qq.com/s/ipbUy3GBRMFat9jUSssMMw)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u5b66\u4e60\u7b14\u8bb0](https://www.yuque.com/qyuhen/go)\\n - \ud83c\udf1f [GO\u4e13\u5bb6\u7f16\u7a0b](https://books.studygolang.com/GoExpertProgramming/)\\n - \ud83c\udf1f [Go \u8bed\u8a00 101](https://go101.org/article/101.html)\\n - \ud83c\udf1f [Go Optimizations 101](https://go101.org/optimizations/101.html)\\n - [\u5f00\u6e90\u56fe\u4e66\u5728\u7ebf\u9605\u8bfb - Go\u8bed\u8a00\u4e2d\u6587\u7f51](https://books.studygolang.com/)\\n - \ud83c\udf1f [Go Interview](https://www.yuque.com/go-interview/set/xq5788)\\n - \ud83c\udf1f [LeetCode Cookbook](https://github.com/halfrost/LeetCode-Go)\\n - \ud83c\udf1f [LeetCode Cookbook\uff08\u5728\u7ebf\u9605\u8bfb\uff09](https://books.halfrost.com/leetcode/)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-compile-intro/)\\n - \ud83c\udf1f [Go\u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b(Advanced Go Programming)](https://books.studygolang.com/advanced-go-programming-book/)\\n - [Go \u8bed\u8a00\u9ad8\u6027\u80fd\u7f16\u7a0b](https://github.com/geektutu/high-performance-go)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u539f\u672c](https://github.com/golang-design/under-the-hood)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u539f\u672c\uff08\u5728\u7ebf\u9605\u8bfb\uff09](https://golang.design/under-the-hood/)\\n - \ud83c\udf1f [Tony Bai \xb7 Go \u8bed\u8a00\u7b2c\u4e00\u8bfe](https://time.geekbang.org/column/intro/100093501)\\n - \ud83c\udf1f [Go \u5e76\u53d1\u7f16\u7a0b\u5b9e\u6218\u8bfe](https://time.geekbang.org/column/intro/100061801)\\n - \ud83c\udf1f [Rust \u7f16\u7a0b\u7b2c\u4e00\u8bfe](https://time.geekbang.org/column/article/408409)\\n - \ud83c\udf1f [Go cheatsheet](https://quickref.me/go)\\n - \ud83c\udf1f [Golang for Node.js Developers](https://github.com/miguelmota/golang-for-nodejs-developers)\\n - \ud83c\udf1f [Learn Go with tests](https://studygolang.gitbook.io/learn-go-with-tests)\\n - \ud83c\udf1f [golang \u7f16\u7a0b\u89c4\u8303 - \u9879\u76ee\u76ee\u5f55\u7ed3\u6784](https://makeoptim.com/golang/standards/project-layout)\\n - [Go \u591c\u8bfb](https://github.com/talkgo/night)\\n - [\u5df2\u5165\u5b57\u8282\u7684\u5927\u4f6c\u5404\u5382\u4e09\u5e74Go\u9762\u7ecf](https://mp.weixin.qq.com/s/VKPSqS50Un29x30KIgB0tA)\\n- Golang \u7b97\u6cd5\\n - https://github.com/fangbinwei/algorithm-practice\\n- Golang \u9879\u76ee\u53c2\u8003\\n - https://github.com/wangzhongyang007/goframe-shop-v2\\n - https://github.com/fangbinwei/aliyun-oss-website-action\\n- Golang \u6559\u7a0b\\n - https://www.w3cschool.cn/go/\\n- Golang \u6807\u51c6\u5e93\u6587\u6863\\n - https://pkg.go.dev/std\\n- Golang \u5355\u5143\u6d4b\u8bd5\\n - [Golang-\u5355\u5143\u6d4b\u8bd5](https://blog.csdn.net/ALEX_CYL/article/details/121793330)\\n - [\u624b\u628a\u624b\u6559\u4f60\u5982\u4f55\u8fdb\u884c Golang \u5355\u5143\u6d4b\u8bd5](https://zhuanlan.zhihu.com/p/377834750)\\n- \u2b50\ufe0f [Go \u8bed\u8a00\u4e0e\u5e76\u53d1\u7f16\u7a0b](https://zhuanlan.zhihu.com/p/471317280)\\n- \u2b50\ufe0f [Golang \u7b80\u6d01\u67b6\u6784\u5b9e\u6218](https://mp.weixin.qq.com/s/Xzlt_WcdcfLWhofafY3c6g)\\n- \u2b50\ufe0f [\u5982\u4f55\u4f7f\u7528\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\u63d0\u5347\u4ee3\u7801\u7684\u7b80\u6d01\u6027](https://juejin.cn/post/7065197280223035422)\\n- \ud83c\udf1b [\u6df1\u5165\u7406\u89e3Go Json.Unmarshal\u7cbe\u5ea6\u4e22\u5931\u4e4b\u8c1c](https://mp.weixin.qq.com/s/36CqC1U54LUd4-izt4iZ1g)\\n- [Go Error \u5904\u7406\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/EvkMQCPwg-B0fZonpwXodg)\\n- [Golang \u65b0\u624b\u53ef\u80fd\u4f1a\u8e29\u7684 50 \u4e2a\u5751](https://segmentfault.com/a/1190000013739000)\\n- [Golang\u8bbe\u8ba1\u6a21\u5f0f\u603b\u7ed3](https://zhuanlan.zhihu.com/p/437626980)\\n- [Golang \u5355\u5143\u6d4b\u8bd5\u6307\u5f15](https://zhuanlan.zhihu.com/p/267341653)\\n- \u2b50\ufe0f [\u4f7f\u7528Golang\u3001Gin\u548cReact\u3001esbuild\u5f00\u53d1\u7684Blog](https://juejin.cn/post/7041846339189080101)\\n- \u2b50\ufe0f [gorm - Golang \u7684\u51fa\u8272 ORM \u5e93](https://github.com/go-gorm/gorm)\\n- \u2b50\ufe0f [fiber\uff1a\u53d7\u5230 Express \u542f\u53d1\u7684 Web \u5e94\u7528\u6846\u67b6](https://github.com/gofiber/fiber)\\n- [Golang \u5b98\u65b9\u6587\u6863](https://go.dev/)\\n- [Golang \u7f16\u7a0b\u601d\u7ef4\u548c\u5de5\u7a0b\u5b9e\u6218](https://zhuanlan.zhihu.com/p/426368274)\\n- \u2b50\ufe0f [Go by example](https://gobyexample.com/)\\n\\n## Rust \u5b66\u4e60\\n\\n- \u2b50\ufe0f [PDF\uff1a\u4ece JavaScript \u5230 Rust\uff1a\u65b0\u4e66\u514d\u8d39\u53d1\u5e03](https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf)\\n- \u2b50\ufe0f [Google \u51fa\u54c1\u7684 Rust \u6559\u7a0b](https://github.com/google/comprehensive-rust)\\n- \u2b50\ufe0f [Rust\u8bed\u8a00\u5723\u7ecf(Rust Course)](https://course.rs/about-book.html)\\n- \u2b50\ufe0f [\u63ed\u79d8\u524d\u7aef\u773c\u4e2d\u7684Rust\uff01](https://mp.weixin.qq.com/s/HKkt9cNZsUFdCR4nAlHeBA)\\n- \ud83c\udf1b [Rust \u5b98\u65b9\u6587\u6863](https://doc.rust-lang.org/book/)\\n- \ud83c\udf1b [Rust \u6807\u51c6\u5e93\u6587\u6863](https://doc.rust-lang.org/std/)\\n- \ud83c\udf1b [Rust by Example](https://doc.rust-lang.org/stable/rust-by-example/)\\n- \ud83c\udf1b [\u9009\u62e9 Go \u8fd8\u662f Rust\uff1fCloudWeGo-Volo \u57fa\u4e8e Rust \u8bed\u8a00\u7684\u63a2\u7d22\u5b9e\u8df5](https://juejin.cn/post/7143822279992934436)\\n- \ud83c\udf1b [\u7528Rust\u9508\u5316Vue Compiler](https://zhuanlan.zhihu.com/p/417534662)\\n- \ud83c\udf1b [\u7528 Rust \u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5408\u8f91](https://github.com/TheAlgorithms/Rust)\\n\\n## \u7f51\u7ad9\u63a8\u8350\\n\\n**\u6587\u6863\u76f8\u5173**\\n\\n- [GitHub \u641c\u7d22\u9875\u9762](https://github.com/search?q=&type=)\\n- [MDN \u6587\u6863](https://developer.mozilla.org/zh-CN/)\\n- [caniuse\uff1a\u67e5\u8be2 API \u517c\u5bb9\u6027](https://caniuse.com/)\\n- [snyk\uff1a\u67e5\u8be2 NPM\u3001Go\u3001Docker \u5b89\u5168\u6027](https://snyk.io/advisor/)\\n- [bundlephobia\uff1a\u67e5\u8be2 NPM \u5305\u4f53\u79ef](https://bundlephobia.com/)\\n- [Deno cheat sheet](https://oscarotero.com/deno/)\\n- [React Docs Beta](https://beta.reactjs.org/learn)\\n- [Overreacted](https://overreacted.io/)\\n- [tailwindcss \u6837\u5f0f\u53c2\u8003](https://tailwindcss.com/docs/configuration)\\n- [Explain Shell](https://explainshell.com/)\\n- [\u300a\u962e\u4e00\u5cf0 ES6 \u6559\u7a0b\u300b](https://es6.ruanyifeng.com/)\\n- [Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://github.com/yeasy/docker_practice)\\n- [\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217](https://github.com/koala-coding/goodBlog)\\n- [\u300a\u6d4f\u89c8\u5668\u5de5\u4f5c\u539f\u7406\u4e0e\u5b9e\u8df5\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fblog.poetries.top%2Fbrowser-working-principle%2F)\\n- [\u300a\u6df1\u5165\u6d45\u51fa webpack\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fwebpack.wuhaolin.cn%2F)\\n- [\u300a\u4ee3\u7801\u968f\u60f3\u5f55\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fprogrammercarl.com%2F)\\n- [\u300a\u524d\u7aef\u8fdb\u9636\u4e4b\u9053\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fyuchengkai.cn%2F)\\n- [\u300aReact \u6280\u672f\u63ed\u79d8\u300b](https://link.juejin.cn/?target=https%3A%2F%2Freact.iamkasong.com%2F)\\n- [\u300a\u56fe\u89e3 React \u6e90\u7801\u7cfb\u5217\u300b](https://github.com/7kms/react-illustration-series)\\n- [\u300aVue \u6280\u672f\u63ed\u79d8\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fustbhuangyi.github.io%2Fvue-analysis%2Fv2%2Fprepare%2F)\\n- [\u300aVue\u6280\u672f\u5185\u5e55\u300b](http://caibaojian.com/vue-design/)\\n- [\u72fc\u53d4\uff1a\u5982\u4f55\u6b63\u786e\u7684\u5b66\u4e60Node.js](https://i5ting.github.io/How-to-learn-node-correctly/)\\n- [\u5927\u5382\u9762\u8bd5\u9898\u6bcf\u65e5\u4e00\u9898](https://q.shanyue.tech/engineering/)\\n- [\u524d\u7aef\u5de5\u7a0b\u5316\u3001\u4e2a\u4eba\u670d\u52a1\u5668\u8fd0\u7ef4\u6307\u5357](https://shanyue.tech/op/#%E9%A2%84%E8%A7%88)\\n- [MySQL\u3001Linux\u3001\u670d\u52a1\u7aef\u67b6\u6784](https://xiaoflyfish.cn/)\\n- [Khaidi Chu \u7684\u535a\u5ba2](https://xcoder.in/)\\n\x3c!-- - [NLP-Beginner\uff1a\u81ea\u7136\u8bed\u8a00\u5904\u7406\u5165\u95e8\u7ec3\u4e60](https://github.com/FudanNLP/nlp-beginner) --\x3e\\n- [\u300a\u6df1\u5ea6\u5b66\u4e60\u6846\u67b6PyTorch\uff1a\u5165\u95e8\u4e0e\u5b9e\u8df5\u300b](https://github.com/chenyuntc/pytorch-book)\\n- [\u300a\u673a\u5668\u5b66\u4e60\u300b\uff08\u897f\u74dc\u4e66\uff09](https://github.com/datawhalechina/pumpkin-book)\\n- [\u300a\u673a\u5668\u5b66\u4e60\u300b\u914d\u5957\u89c6\u9891\u6559\u7a0b](https://www.bilibili.com/video/BV1Mh411e7VU)\\n- \u2b50\ufe0f [Software Engineering at Google](https://abseil.io/blog/04222021-swe-book)\\n- \u2b50\ufe0f [ML YouTube Courses](https://github.com/dair-ai/ML-YouTube-Courses)\\n- \u2b50\ufe0f [How Web Works](https://github.com/vasanthk/how-web-works)\\n\\n**\u5f00\u6e90\u63a8\u8350**\\n\\n- [Next.js](https://nextjs.org/docs/getting-started)\\n- [tailwindcss \u6837\u5f0f\u53c2\u8003](https://tailwindcss.com/docs/configuration)\\n- [PNPM](https://pnpm.io/installation)\\n- [TypeScript](https://www.typescriptlang.org/docs/)\\n- [Vite](https://vitejs.dev/)\\n- [Storybook](https://storybook.js.org/)\\n\\n**\u5728\u7ebf Plyaground**\\n\\n- [\u751f\u6210\u5404\u4e2a\u8bed\u8a00\u7684\u6c47\u7f16\u4ee3\u7801](https://godbolt.org/)\\n- [Vue SFC Playground](https://sfc.vuejs.org/)\\n- [CodeSandBox](https://link.juejin.cn/?target=https%3A%2F%2Fcodesandbox.io%2Fdashboard%2Fhome)\\n- [CodePen](https://codepen.io/)\\n- [AST explorer\uff1a\u53ef\u89c6\u5316 AST](https://www.astexplorer.net/)\\n- [\u6b63\u5219\u8868\u8fbe\u5f0f\u53ef\u89c6\u5316](https://link.juejin.cn/?target=https%3A%2F%2Fjex.im%2Fregulex)\\n\\n**\u7f16\u7a0b\u98ce\u683c\u6307\u5357**\\n\\n- \u2b50\ufe0f [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint)\\n- \u2b50\ufe0f [eslint-config-alloy](https://github.com/AlloyTeam/eslint-config-alloy)\\n- \u2b50\ufe0f [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)\\n- \u2b50\ufe0f [clean-code-javascript](https://github.com/ryanmcdermott/clean-code-javascript)\\n\\n**\u6280\u672f\u793e\u533a**\\n\\n- https://dev.to/\\n- https://medium.com/\\n- https://linuxhandbook.com/\\n\\n**\u5de5\u5177\u76f8\u5173**\\n\\n- [plantuml\uff1a\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\u3001\u7528\u4f8b\u56fe\u3001\u7c7b\u56fe\u3001\u601d\u7ef4\u5bfc\u56fe](https://plantuml.com/)\\n- [njt\uff1a\u5feb\u901f\u5bfc\u822a\u81f3 npm \u5305\u8d44\u6e90](https://www.npmjs.com/package/njt)\\n- [skypack\uff1a\u65e0\u9700\u6784\u5efa\u5de5\u5177\u4f7f\u7528\u5404\u79cd\u7ecf\u8fc7\u4f18\u5316\u7684 npm \u5305](https://www.skypack.dev/)\\n- [carbon\uff1a\u751f\u6210\u4ee3\u7801\u7247](https://link.juejin.cn/?target=https%3A%2F%2Fcarbon.now.sh%2F)\\n- [codelf \u53d8\u91cf\u547d\u540d\u795e\u5668](https://unbug.github.io/codelf/)\\n- [openbase\uff1a\u67e5\u8be2\u5404\u79cd\u7b2c\u4e09\u65b9\u5e93](https://openbase.com/)\\n\\n## \u5b66\u4e60\u8d44\u6e90\\n\\n- \u300aLinux Shell \u811a\u672c\u653b\u7565\uff08\u7b2c2\u7248\uff09\u300b\\n- \u300a\u63a8\u8350\u7cfb\u7edf\u2014\u2014\u6280\u672f\u3001\u8bc4\u4f30\u53ca\u9ad8\u6548\u7b97\u6cd5\u300b\\n- \u300aGo \u8bed\u8a00\u7f16\u7a0b\u300b\\n- \u300aGo \u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b\u300b\\n- \u300a\u64cd\u4f5c\u7cfb\u7edf\u5bfc\u8bba\u300b\\n- \u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b\\n- \u300aMySQL\u6280\u672f\u5185\u5e55\u300b\\n- \u300aRedis\u8bbe\u8ba1\u4e0e\u5b9e\u73b0\u300b\\n- \u2b50\ufe0f [\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01](https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA)\\n- \u2b50\ufe0f [\u3010\u8ba1\u7b97\u673a\u79d1\u5b66\u901f\u6210\u8bfe\u3011\\\\[40\u96c6\u5168/\u7cbe\u6821\\\\] - Crash Course Computer Science](https://www.bilibili.com/video/BV1EW411u7th)\\n- \u2b50\ufe0f [\u3010\u7cbe\u6821\u4e2d\u82f1\u5b57\u5e55\u30112015 CMU 15-213 CSAPP \u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf \u8bfe\u7a0b\u89c6\u9891](https://www.bilibili.com/video/BV1iW411d7hd)\\n\\n## \u9762\u8bd5\u76f8\u5173\\n\\n- [JS \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 - awesome-coding-js](https://github.com/ConardLi/awesome-coding-js)\\n- [JavaScript Algorithms and Data Structures](https://github.com/trekhleb/javascript-algorithms)\\n- [JavaScript\u7b97\u6cd5\u57fa\u7840\u53ca\u9762\u8bd5\u603b\u7ed3\uff081w1\u5b57\uff09](https://juejin.cn/post/7023208826472005668)\\n- \u2b50\ufe0f [\u5982\u4f55\u5199\u51fa\u4e00\u4e2a\u60ca\u8273\u9762\u8bd5\u5b98\u7684\u6df1\u62f7\u8d1d?](https://juejin.cn/post/6844903929705136141)\\n- \u2b50\ufe0f [\u9762\u4e86\u51e0\u4e2a\u8bf4\u81ea\u5df1\u7cbe\u901a Vue \u7684\u540c\u5b66](https://juejin.cn/post/6844904118704668685)\\n- [\u9ad8\u9891react\u9762\u8bd5\u989820\u9053\uff08\u9644\u8be6\u89e3\uff09](https://blog.csdn.net/xgangzai/article/details/120375992)\\n- [\u30101 \u6708\u6700\u65b0\u3011\u524d\u7aef 100 \u95ee\uff1a\u80fd\u641e\u61c2 80% \u7684\u8bf7\u628a\u7b80\u5386\u7ed9\u6211](https://juejin.cn/post/6844903885488783374)\\n\\n\x3c!--\\n\\n## \u524d\u7aef\u6d4b\u8bd5\\n\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0a\uff09](https://juejin.cn/post/6943430853972852750)\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0b\uff09](https://juejin.cn/post/6946008649026240519)\\n- [\u524d\u7aef\u6d4b\u8bd5\u96c6\u9526\u2014\u2014\u5982\u4f55\u5199\u597d\u524d\u7aef\u6d4b\u8bd5\u4fdd\u8bc1\u4ee3\u7801\u8d28\u91cf\uff1f](https://juejin.cn/post/6999445868550029319)\\n\\n## \u5f00\u53d1\u73af\u5883\u76f8\u5173\\n\\n- [\u3010\u624b\u628a\u624b\u3011\u5b66\u4f1aVS Code\\"\u4efb\u52a1\\"\u795e\u6280\uff0c\u6210\u4e3a\u9879\u76ee\u7ec4\u6700\u9753\u7684\u5d3d\uff01](https://juejin.cn/post/7035448197883363359)\\n- [\u804a\u804a\u5f00\u53d1\u65e5\u5e38\u7684\u6548\u7387\u63d0\u5347\u5de5\u5177\uff08\u5168\uff09](https://juejin.cn/post/7019183422320934948)\\n- [\u6253\u9020\u8212\u9002\u642c\u7816\u73af\u5883\uff0c\u8fd9\u4e9b\u662f\u6211\u6700\u60f3\u63a8\u4ecb\u7684\u684c\u9762\u597d\u7269](https://juejin.cn/post/6844904193828880391)\\n- [\u5e72\u8d27\u6ee1\u6ee1\uff01\u63a8\u4ecb\u51e0\u6b3e Mac \u4e0b\u975e\u5e38\u597d\u7528\u7684\u8f6f\u4ef6\uff08\u7b2c\u4e00\u5f39\uff09](https://juejin.cn/post/6844904012920127495)\\n- [\u5e72\u8d27\u6ee1\u6ee1\uff01\u63a8\u4ecb\u51e0\u6b3e Mac \u4e0b\u975e\u5e38\u597d\u7528\u7684\u8f6f\u4ef6\uff08\u7b2c\u4e8c\u5f39\uff09](https://juejin.cn/post/6844904031685443592)\\n\\n--\x3e\\n\\n## \ud83d\udcd2 \u6398\u91d1\u5927\u4f6c\u6c47\u603b\\n\\n- Vue \u6e90\u7801\u3001\u54cd\u5e94\u5f0f\u673a\u5236\uff1a[ssh](https://juejin.cn/user/2330620350708823/posts) \u3001[\u9ec4\u8f76](https://juejin.cn/user/2137106333044861/posts)\\n- React \u8fdb\u9636\u7cfb\u5217\uff1a[\u6211\u4e0d\u662f\u5916\u661f\u4eba](https://juejin.cn/user/2418581313687390/posts)\\n- Webpack \u76f8\u5173\uff1a[Tecvan](https://juejin.cn/user/1820446985555544/posts)\\n- \u8bbe\u8ba1\u6a21\u5f0f\uff1a[DYBOY](https://juejin.cn/user/3544481219495806/posts)\\n- \u624b\u5199\u6e90\u7801\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a[\u848b\u9e4f\u98de](https://juejin.cn/user/2295436011645655/posts) \u3001[\u524d\u7aef\u9633\u5149](https://juejin.cn/user/1204720476893064/posts)\\n- Webpack5\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a[\u6e05\u6c64\u997a\u5b50](https://juejin.cn/user/4300945218607197)\\n- \u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\uff1a[\u5bd2\u8349](https://juejin.cn/user/703340610597064/posts)\\n- \u603b\u7ed3\u5927\u5e08\uff1a[JowayYoung](https://juejin.cn/user/2330620350432110/posts)\\n- \u6e90\u7801\u5206\u6790\uff1a\u82e5\u5ddd\\n- \u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247\uff1a[shanyue](https://juejin.cn/user/1556564164489389/posts)\\n- CSS \u5404\u79cd\u7279\u6548\uff1a[chokcoco](https://juejin.cn/user/2330620350437678/posts)\\n- Nodejs \u76f8\u5173\uff1a[\u5929\u732a](https://www.zhihu.com/people/liuyong25/posts)\\n- Umi \u76f8\u5173\uff1a[MDH \u524d\u7aef\u5468\u520a](https://www.yuque.com/mdh/weekly/rhiudh)\\n- Antd\u3001Umi\u3001Node.js\uff1a[\u652f\u4ed8\u5b9d\u4f53\u9a8c\u79d1\u6280\u7cbe\u9009](https://www.yuque.com/antfe/featured/ys58hy)\\n- \u524d\u7aef\u3001\u5168\u6808\u6280\u672f\u4e13\u520a\uff1a[\u963f\u91cc CCO \u4f53\u9a8c\u6280\u672f\u4e13\u520a](https://www.zhihu.com/column/ali-nanjing)\\n- Golang \u76f8\u5173\uff1a[\u817e\u8baf\u6280\u672f\u5de5\u7a0b](https://zhuanlan.zhihu.com/p/340814811)\\n- \u524d\u7aef\u88c5\u903c\u6280\u5de7108\u5f0f\uff1a[\u72ec\u9493\u5bd2\u6c5f\u96ea](https://segmentfault.com/u/king_hcj)\\n- \u524d\u7aef\u4e5d\u6761 bug \u5206\u4eab\uff1a[lulu_up](https://segmentfault.com/u/lulu_up)\\n- Vue3 \u6e90\u7801\u5171\u8bfb\uff1a[\u524d\u7aef\u6768\u6751\u957f](https://www.bilibili.com/video/BV1bS4y1T7ng)\\n- \u524d\u7aef\u5de5\u7a0b\u5316\u3001\u5b66\u4e60 Golang\uff1a\u6d1b\u7af9\\n- Node.js \u76f8\u5173\uff1a\u4e94\u6708\u541b\\n\\n## \ud83d\udcd2 \u5f85\u5b66\u4e60\u5185\u5bb9\\n\\n- [babel\u6e90\u7801\u8be6\u89e3-v1.7.8](https://juejin.cn/post/7017360824939315207)\\n- [\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09](https://juejin.cn/post/6844904094079926286)\\n- [\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b](https://juejin.cn/post/6844904116913700877)\\n- [\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7](https://juejin.cn/post/6889247428797530126)\\n- [\u5982\u4f55\u5229\u7528lerna\u7ba1\u7406\u6a21\u5757](https://juejin.cn/post/6844903783005175815)\\n- [\u57fa\u4e8e lerna \u7684\u591a\u5305 JavaScript \u9879\u76ee\u642d\u5efa\u7ef4\u62a4](https://juejin.cn/post/6969544464113074189)\\n- [React\u6027\u80fd\u4f18\u5316\u5c0f\u8d34\u58eb](https://juejin.cn/post/6844903896767283207#heading-5)\\n- [\u795e\u5947\u7684lambda\u8868\u8fbe\u5f0f\u2014\u2014\u51fd\u6570\u5f0f\u7f16\u7a0b\u5fc5\u5b66](https://juejin.cn/post/6844903929726107655)\\n- [npm\u8fdb\u9636\u2014\u2014\u5982\u4f55\u62e5\u6709\u81ea\u5df1\u7684\u5305\u548c\u6d41\u7a0b\u81ea\u52a8\u5316](https://juejin.cn/post/6844903954002739213)\\n- [React Hooks\u7684\u82b1\u6837\u73a9\u6cd5](https://juejin.cn/post/6844904162124103693)\\n - useDark\uff0cuseClickOutside\uff0c\u5168\u5c40\u72b6\u6001\u7ba1\u7406\\n- [\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u8981\u80cc](https://juejin.cn/post/6844903845227659271)\\n- [\u6211\u4eec\u6216\u8bb8\u4e0d\u9700\u8981 classnames \u8fd9\u4e2a\u5e93](https://juejin.cn/post/6844903825145511950)\\n- [\u56fd\u5e86\u7206\u809d\uff0c\u7528vite+vue3+ts\u5b9e\u73b0\u4e00\u4e2a\u7f51\u9875\u7248\u7684typora\uff01](https://juejin.cn/post/7014431215302213668)\\n- [\u624b\u6478\u624b\u6559\u4f60\u4f7f\u7528\u6700\u65b0\u7248husky(v7.0.1)\u8ba9\u4ee3\u7801\u66f4\u4f18\u96c5\u89c4\u8303](https://juejin.cn/post/6982192362583752741)\\n- [\u5feb\u901f\u5165\u624bElectron\uff0c\u62e5\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u684c\u9762\u5e94\u7528](https://juejin.cn/post/7015476516196712462)\\n- [\u5728\u5927\u5382\u662f\u5982\u4f55\u9ad8\u6548\u7ec4\u7ec7 npm script \u7684](https://juejin.cn/post/6945236994247098381)\\n- [\u524d\u7aef\u5f00\u53d1\u8005\u5468\u520a\u7b2c\u4e09\u671f\uff1a\u5404\u5927\u5382 webpack5 \u5b9e\u8df5](https://juejin.cn/post/6940042028243746823)\\n- [\u3010\u8bd1\u3011\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 ViteJS \u4e2d\u82f1\u53cc\u8bed\u5b57\u5e55 \uff5c \u6280\u672f\u70b9\u8bc4](https://juejin.cn/post/6937176680251424775#heading-7)\\n- \u2b50\ufe0f [Webpack5 \u65b0\u7279\u6027\u4e1a\u52a1\u843d\u5730\u5b9e\u6218](https://juejin.cn/post/6924258563862822919)\\n- \u2b50\ufe0f [Webpack \u5b98\u65b9\u5f00\u53d1\u6307\u5357](https://webpack.docschina.org/guides/development/#choosing-a-development-tool)\\n- [\u6784\u5efa\u6548\u7387\u5927\u5e45\u63d0\u5347\uff0cwebpack5 \u5728\u4f01\u9e45\u8f85\u5bfc\u7684\u5347\u7ea7\u5b9e\u8df5](https://mp.weixin.qq.com/s/P3foOrcu4StJDGdX9xavng)\\n- [\u5982\u4f55\u5229\u7528 monorepo \u7b56\u7565\u7ba1\u7406\u4ee3\u7801\uff1f](https://mp.weixin.qq.com/s/ZP2IigNVSIZKGuYxNYOYgw)\\n- [All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6924854598268108807)\\n- [\u4e00\u987f\u64cd\u4f5c\uff0c\u6211\u628a Table \u7ec4\u4ef6\u6027\u80fd\u63d0\u5347\u4e86\u5341\u500d](https://juejin.cn/post/7007252464726458399)\\n- [MySQL \u4ece\u5165\u95e8\u5230\u5b9e\u8df5\uff0c\u4e07\u5b57\u8be6\u89e3](https://juejin.cn/post/7005019784429469704)\\n- [\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6](https://juejin.cn/post/6844904080972709901)\\n- [\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/6844903919995322382)\\n\\n\x3c!-- --\x3e\\n\\n- [\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357](https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg)\\n- [\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key](https://juejin.cn/post/7026119446162997261)\\n- [\u56db\u4e2a\u771f\u79c0React\u7528\u6cd5\uff0c\u4f60\u503c\u5f97\u62e5\u6709](https://juejin.cn/post/7077365102743126052)\\n- [\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09](https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw)\\n- [pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA)\\n- [\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2](https://zhuanlan.zhihu.com/p/455809528)\\n- [Vue\u7ec4\u4ef6\u5e93\u6587\u6863\u7ad9\u70b9\u7684\u642d\u5efa\u601d\u8def](https://juejin.cn/post/7152898360498716702)\\n- [\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e](https://juejin.cn/post/7151653067593613320#heading-18)\\n- [React-router\u4ece0\u52301](https://juejin.cn/post/7148746931802472485#heading-8)\\n- [\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09](https://juejin.cn/post/7118937685653192735#heading-7)\\n- [768. \u6700\u591a\u80fd\u5b8c\u6210\u6392\u5e8f\u7684\u5757 II : \u5e38\u89c4\u8d2a\u5fc3\u6784\u9020\u9898](https://juejin.cn/post/7131222991681093639)\\n- [\ud83e\udd8a\u3010\u524d\u7aef\u5de5\u7a0b\u5316\u3011\u4e3a\u4ec0\u4e48\u5927\u5382\u90fd\u8981\u5f00\u53d1\u81ea\u5df1\u7684\u811a\u624b\u67b6\uff1f\ud83e\udd84\ufe0f](https://juejin.cn/post/7128597557634138148)\\n- [\u5feb\u4e0a\u8f66\uff01\u4ece\u96f6\u5f00\u59cb\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01](https://juejin.cn/post/7120893568553582622)\\n- [\u5199\u7ed9\u524d\u7aef\u7684\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u57fa\u7840\u5165\u95e8\uff08\u4e00\uff09\u8fd4\u749e\u5f52\u771f\uff1a\u4ece\u5f15\u7528\u7c7b\u578b\u5230\u88f8\u6307\u9488](https://juejin.cn/post/6938201650012094495)\\n- [\u6a21\u5757\u8054\u90a6\u6d45\u6790](https://juejin.cn/post/7101457212085633054#heading-1)\\n- [\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw)\\n- [Go Interview](https://www.yuque.com/go-interview/set/xq5788)\\n- [LeetCode Cookbook](https://books.halfrost.com/leetcode/ChapterFour/0200~0299/0287.Find-the-Duplicate-Number/)\\n- [Go Gin \u7cfb\u5217\u4e8c\uff1a\u521d\u59cb\u5316\u9879\u76ee\u53ca\u516c\u5171\u5e93](https://mp.weixin.qq.com/s?__biz=MzUxMDI4MDc1NA==&mid=2247483807&idx=1&sn=9c7aede4f675f2de49ddc08ab1a95a71&chksm=f90414c2ce739dd4b8711c0043286fba9744b8d9c86c75c7ac7750d28cd2fed43f749eb5de99&scene=178&cur_album_id=1383459655464337409#rd)\\n- [500ms to 1.7ms In React: A Journey And A Checklist](https://orizens.com/blog/500ms-to-1-7ms-in-react-a-journey-and-a%20checklist/)\\n- [\u6f2b\u8c08\u6784\u5efa\u5de5\u5177(\u5341):\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def](https://juejin.cn/post/7157902763534319624)\\n- [\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684](https://juejin.cn/post/7170852747749621791)\\n- [\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684\uff1f\ud83c\udf89\ud83c\udf89\ud83c\udf89](https://juejin.cn/post/7085257325165936648)\\n- [Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c](https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg)\\n- [Learning Go by examples: part 7 - Create a cross-platform GUI/Desktop app in Go](https://dev.to/aurelievache/learning-go-by-examples-part-7-create-a-cross-platform-gui-desktop-app-in-go-44j1)\\n- [Understanding Docker: part 37 \u2013 Content Trust](https://dev.to/aurelievache/understanding-docker-part-37-content-trust-18n3)\\n- [Understanding Kubernetes: part 47 \u2013 Kubernetes 1.26 Changelog](https://dev.to/aurelievache/understanding-kubernetes-part-47-kubernetes-126-changelog-2404)\\n- [Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3](https://juejin.cn/post/7115634967945674765)\\n- [\u4e3a\u4ec0\u4e48 React \u7684 Diff \u7b97\u6cd5\u4e0d\u91c7\u7528 Vue \u7684\u53cc\u7aef\u5bf9\u6bd4\u7b97\u6cd5](https://juejin.cn/post/7116141318853623839)\\n- [\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406](https://juejin.cn/post/7121378029682556958)\\n\\n\x3c!-- --\x3e\\n\\n- [\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417](https://juejin.cn/post/7094984070999834655)\\n- [\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae](https://juejin.cn/post/7147939014870302756)\\n- [react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3](https://juejin.cn/post/7117512204059934733)\\n- [\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09](https://juejin.cn/post/7118937685653192735)\\n- [\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406](https://juejin.cn/post/6944863057000529933)\\n\\n## \ud83d\udcd2 \u5c0f\u76ee\u6807\\n\\n- Vue 3.x \u6e90\u7801\uff1b\\n- Vuex 4.x \u6e90\u7801\uff1b\\n- Vue-Router \u6e90\u7801\uff1b\\n- \u642d\u5efa\u811a\u624b\u67b6\u5de5\u5177\uff08Webpack5 \u65b0\u7279\u6027\u5b9e\u8df5\uff09\uff1b\\n- VS Code extension \uff1b\\n- cocos \u6e38\u620f\u5f00\u53d1\uff1b\\n- \u624b\u5199 redux \u6e90\u7801\uff1b\\n- \u624b\u5199 redux-thunk \u6e90\u7801\uff1b\\n- \u624b\u5199 Promise/A+ \uff1b\\n - [\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b](https://juejin.cn/post/6844904116913700877)\\n - [\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282](https://juejin.cn/post/6945319439772434469)\\n - [V8 Promise\u6e90\u7801\u5168\u9762\u89e3\u8bfb\uff0c\u5176\u5b9e\u4f60\u5bf9Promise\u4e00\u65e0\u6240\u77e5](https://juejin.cn/post/7055202073511460895)\\n - [\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09](https://juejin.cn/post/6844904094079926286)\\n - [\u624b\u628a\u624b\u4e00\u884c\u4e00\u884c\u4ee3\u7801\u6559\u4f60\u201c\u624b\u5199Promise\u201c\uff0c\u5b8c\u7f8e\u901a\u8fc7 Promises/A+ \u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b](https://juejin.cn/post/7043758954496655397)\\n- \u6392\u5e8f\u7b97\u6cd5\uff0c\u6876\u6392\u5e8f\u3001\u8ba1\u6570\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6 O(n) \uff1b\\n- \u6bcf\u65e5\u7b97\u6cd5\\n - [https://labuladong.gitee.io/algo/](https://labuladong.gitee.io/algo/)\uff08\u56fd\u5185\u901f\u5ea6\u5feb\uff0c\u4f53\u9a8c\u597d\uff0c\u63a8\u8350\uff09\\n - https://labuladong.github.io/algo/\\n - [\u624b\u628a\u624b\u5237\u4e8c\u53c9\u6811\u7cfb\u5217\u5b8c\u7ed3\u7bc7](https://mp.weixin.qq.com/s/AzQzw-pC8A-0kS0NJn2eWw)\\n - [\u524d\u7f00\u6811\u7b97\u6cd5\u6a21\u677f\u79d2\u6740 5 \u9053\u7b97\u6cd5\u9898](https://mp.weixin.qq.com/s/hGrTUmM1zusPZZ0nA9aaNw)\\n - [\u96c6\u5408\u5212\u5206\u95ee\u9898\uff1a\u6392\u5217\u7ec4\u5408\u4e2d\u7684\u56de\u6eaf\u601d\u60f3\uff08\u4fee\u8ba2\u7248\uff09](https://mp.weixin.qq.com/s/5GO2ZITncVArdm4KITBd9g)\\n - [\u5feb\u901f\u6392\u5e8f\u7684\u6b63\u786e\u7406\u89e3\u65b9\u5f0f\u53ca\u8fd0\u7528](https://mp.weixin.qq.com/s/8ZTMhvHJK_He48PpSt_AmQ)\\n - [\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01](https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A)\\n - [\u4e00\u6587\u79d2\u6740 5 \u9053\u6700\u8fd1\u516c\u5171\u7956\u5148\u95ee\u9898](https://mp.weixin.qq.com/s/njl6nuid0aalZdH5tuDpqQ)\\n - [\u7b97\u6cd5\u65f6\u7a7a\u590d\u6742\u5ea6\u5206\u6790\u5b9e\u7528\u6307\u5357](https://mp.weixin.qq.com/s/OQAzopRncZe5cb9_of4mCQ)\\n - [\u52a8\u6001\u89c4\u5212\u7b54\u7591\u7bc7\uff08\u4fee\u8ba2\u7248\uff09](https://mp.weixin.qq.com/s/zhaurXhrAiHsfgGAOfAuMw)\\n - [\u8bba\u52a8\u6001\u89c4\u5212\u7a77\u4e3e\u7684\u4e24\u79cd\u89c6\u89d2](https://mp.weixin.qq.com/s/6vwNBr48D36n6E3EawFUqg)\\n - [\u9ad8\u9891\u9762\u8bd5\u7cfb\u5217\uff1a\u5355\u8bcd\u62c6\u5206\u95ee\u9898](https://mp.weixin.qq.com/s/iL7tCl6pqw0fTatGSemY-g)\\n - [\u522b\u7528 KMP \u4e86\uff0c Rabin-Karp \u7b97\u6cd5\u4e86\u89e3\u4e0b](https://mp.weixin.qq.com/s/HiEft8sW5QzHcM5mb5_V6g)\\n - [\u5fae\u8f6f\u9762\u8bd5\u9898\u89e3\u6790\uff1a\u4e11\u6570\u7cfb\u5217\u7b97\u6cd5](https://mp.weixin.qq.com/s/XXsWwDml_zHiTEFPZtbe3g)\\n - [\u8bf4\u900f\u6e38\u620f\u4e2d\u5e38\u7528\u7684\u4e24\u79cd\u968f\u673a\u7b97\u6cd5](https://mp.weixin.qq.com/s/vxQDGfshcSVjs9EYmV8q3Q)\\n - [\u6211\u7528\u6d88\u606f\u961f\u5217\u505a\u4e86\u4e00\u6b3e\u8054\u673a\u5c0f\u6e38\u620f](https://mp.weixin.qq.com/s/kI0HUTFVr4YEBpLRZWLEDg)\\n - [Union Find \u5e76\u67e5\u96c6\u7b97\u6cd5\u539f\u7406\u53ca\u5e94\u7528](https://mp.weixin.qq.com/s/mFLCL_Dyz5-CtZMZJmOXKw)\\n - [\u5fc5\u77e5\u5fc5\u4f1a\u4f4d\u8fd0\u7b97\u6280\u5de7\u624b\u518c](https://mp.weixin.qq.com/s/4vHfaNnn1OpWQJcsssWWdQ)\\n - [\u3010\u9762\u8bd5\u9ad8\u9891\u9898\u3011\u96be\u5ea6 1.5/5\uff0c\u591a\u89e3\u6cd5\u7ecf\u5178\u9762\u8bd5\u9898](https://juejin.cn/post/7152708637817831432)\\n - [DFS/\u56de\u6eaf/\u52a8\u6001\u89c4\u5212\u7b97\u6cd5\u7684\u878d\u4f1a\u8d2f\u901a](https://mp.weixin.qq.com/s/9Q4JAuSATq3WgN7krdGTWg)\\n - [2021 \u516c\u4f17\u53f7\u7cbe\u9009\u6587\u7ae0\u76ee\u5f55](https://mp.weixin.qq.com/s/ir1Hk06HcT8W_qz0MtyONA)\\n- \u770b\u4e0b\u9762\u7684\u6587\u7ae0\uff0c\u624b\u5199\u4e00\u4e2a Webpack\\n\\t- [\u624b\u5199\u4e00\u4e2awebpack\uff0c\u770b\u770bAST\u600e\u4e48\u7528\uff5c\u725b\u6c14\u51b2\u5929\u65b0\u5e74\u5f81\u6587](https://juejin.cn/post/6930877602840182791)\\n - [\u4eca\u5929\uff0c\u6211\u4eec\u6765\u5b9e\u73b0\u4e00\u4e2a\u57fa\u7840\u7248\u7684webpack](https://juejin.cn/post/6987036612035084296)\\n\\t- [\u624b\u5199webpack\u6838\u5fc3\u539f\u7406\uff0c\u518d\u4e5f\u4e0d\u6015\u9762\u8bd5\u5b98\u95ee\u6211webpack\u539f\u7406](https://juejin.cn/post/6854573217336541192)\\n- Webapck \u7f16\u8bd1\u6d41\u7a0b\\n - \u2b50\ufe0f [Webpack5 \u6838\u5fc3\u539f\u7406\u4e0e\u5e94\u7528\u5b9e\u8df5](https://juejin.cn/book/7115598540721618944)\\n - [Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790](https://juejin.cn/post/7031546400034947108)\\n - [\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b](https://juejin.cn/post/7026658230365323301)\\n - [\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f](https://juejin.cn/post/6859538537830858759)\\n - [100\u884c\u4ee3\u7801\u5b9e\u73b0\u4e00\u4e2a\u7ec4\u4ef6\u5f15\u7528\u6b21\u6570\u7edf\u8ba1\u63d2\u4ef6](https://juejin.cn/post/7077484559893266439)\\n - https://github.com/ronami/minipack\\n- \u624b\u628a\u624b\u5b9e\u73b0\u4e00\u4e2a babel \u63d2\u4ef6\\n - Babel \u63d2\u4ef6\u5e38\u7528 API\u3001\u914d\u5408 TS \u5f00\u53d1\u3001\u5982\u4f55\u6d4b\u8bd5\u63d2\u4ef6\u7b49\u7b49\\n - \u2b50\ufe0f [Babel \u63d2\u4ef6\uff1a30\u5206\u949f\u4ece\u5165\u95e8\u5230\u5b9e\u6218](https://juejin.cn/post/7143921535445631012)\\n - \u8fd9\u7bc7\u505a\u7684 demo \u662f\u4e00\u4e2a\u7b80\u5355\u7684 babel-plugin-import\\n - [\u6df1\u5165Babel\uff0c\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86](https://juejin.cn/post/6844903746804137991)\\n - \u8fd9\u7bc7\u505a\u7684 demo \u7c7b\u4f3c Java \u4e2d\u7684 lambok\\n - [\u4fdd\u59c6\u7ea7\u6559\u5b66\uff01\u8fd9\u6b21\u4e00\u5b9a\u5b66\u4f1ababel\u63d2\u4ef6\u5f00\u53d1\uff01](https://juejin.cn/post/7012424646247055390)\\n - [babel-handbook - \u5404\u79cd ast \u64cd\u4f5c\u6307\u5357](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md)\\n - [\u4f60\u8fd8\u5728\u624b\u52a8\u90e8\u7f72\u57cb\u70b9\u5417\uff1f\u4ece0\u52301\u5f00\u53d1Babel\u57cb\u70b9\u81ea\u52a8\u690d\u5165\u63d2\u4ef6](https://mp.weixin.qq.com/s/R6Xr8SoJicZB8-P4H2SSPA)\\n - [\u64cd\u4f5c JavaScript \u7684 AST](https://juejin.cn/post/7061808830274863118)\\n - [\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357](https://juejin.cn/post/6953963506693570573)\\n - [\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136](https://juejin.cn/post/7026671646555504676)\\n- diff \u7b97\u6cd5\u76f8\u5173\\n - https://github.com/snabbdom/snabbdom\\n - https://github.com/snabbdom/snabbdom/blob/master/src/init.ts\\n - \u2b50\ufe0f [\u56fe\u89e3Diff\u7b97\u6cd5\u2014\u2014Vue\u7bc7](https://mp.weixin.qq.com/s/8M-pJdKjF6bx5ijtSFKIcw)\\n - \u2b50\ufe0f [\u6d45\u6790 Snabbdom \u4e2d vnode \u548c diff \u7b97\u6cd5](https://juejin.cn/post/7067693810918096903)\\n - [\u4e00\u6587\u5403\u900f React \u548c Vue \u7684\u591a\u8282\u70b9 diff \u539f\u7406](https://juejin.cn/post/7161063643105198093)\\n - [diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f](https://juejin.cn/post/6997965021401579556)\\n - [DIff\u7b97\u6cd5\u770b\u4e0d\u61c2\u5c31\u4e00\u8d77\u6765\u780d\u6211(\u5e26\u56fe)](https://juejin.cn/post/7000266544181674014)\\n - [\u5173\u4e8eVirtual DOM\u7406\u89e3\u548cSnabbdom\u6e90\u7801\u6d45\u6790](https://juejin.cn/post/6966215704634720287)\\n - [shanyue mini-code vdom](https://github.com/shfshanyue/mini-code/blob/master/code/vdom/index.js)\\n - [Virtual DOM\u5230\u5e95\u6709\u4ec0\u4e48\u8ff7\u4eba\u4e4b\u5904\uff1f\u5982\u4f55\u642d\u5efa\u4e00\u6b3e\u8ff7\u4f60\u7248Virtual DOM\u5e93\uff1f](https://juejin.cn/post/6976232466059100197)\\n - [React\u3001Vue2\u3001Vue3\u7684\u4e09\u79cdDiff\u7b97\u6cd5](https://juejin.cn/post/6919376064833667080)\\n - [\u7f51\u4e0a\u90fd\u8bf4\u64cd\u4f5c\u771f\u5b9e DOM \u6162\uff0c\u4f46\u6d4b\u8bd5\u7ed3\u679c\u5374\u6bd4 React \u66f4\u5feb\uff0c\u4e3a\u4ec0\u4e48\uff1f- \u77e5\u4e4e](https://www.zhihu.com/question/31809713/answer/53544875)\\n- webpack \u70ed\u6a21\u5757\u66ff\u6362\u770b\u4e0b\u6e90\u7801\\n - [webpack\u6a21\u5757\u70ed\u66f4\u65b0\u539f\u7406](https://juejin.cn/post/7049608872553611301)\\n - [Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790](https://juejin.cn/post/7021729340945596424)\\n - [Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790](https://juejin.cn/post/7031546400034947108)\\n- Docker \u76f8\u5173\u603b\u7ed3\u4e00\u4e0b\\n - [GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/7064906701941506061)\\n - [\u5199\u7ed9\u524d\u7aef\u7684 Docker \u4e0a\u624b\u6307\u5357](https://mp.weixin.qq.com/s/5LLX__x-yamgR83e0NKAtA)\\n - [\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357](https://mp.weixin.qq.com/s/0Il5o9CRgZI3LbuR0LjAtQ)\\n - [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72](https://juejin.cn/post/7069609959985512484)\\n - [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72](https://juejin.cn/post/7083009375387779085)\\n - [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u5bb9\u5668\u7f16\u6392](https://juejin.cn/post/7113712658850775048)\\n - [\u4e91\u8ba1\u7b97\u65f6\u4ee3\uff0c\u4f60\u8fd8\u4e0d\u4f1a Docker \uff1f \u4e00\u4e07\u5b57\u603b\u7ed3\uff08\u5efa\u8bae\u6536\u85cf\uff09](https://mp.weixin.qq.com/s/f581rfvKWE3KGgWfZDJ2cA)\\n- \u524d\u7aef\u6846\u67b6\u6e90\u7801\\n - \u2b50\ufe0f \u2b50\ufe0f [React \u8fdb\u9636\u5b9e\u8df5\u6307\u5357](https://juejin.cn/book/6945998773818490884)\\n - \u2b50\ufe0f [react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3](https://juejin.cn/post/7117512204059934733)\\n - \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300dReact\u4e2d\u6ca1\u6709keepalive\uff1f\u6ca1\u4e8b\uff01\u624b\u628a\u624b\u6559\u4f60\u4ece\u96f6\u5230\u4e00\u8bbe\u8ba1\u5e76\u5b9e\u73b0\u4e00\u4e2a\uff01](https://juejin.cn/post/7122617883837857806)\\n - \u2b50\ufe0f [\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09](https://juejin.cn/post/7118937685653192735)\\n - \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357](https://juejin.cn/post/7069555976717729805)\\n - \u2b50\ufe0f [\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406](https://juejin.cn/post/6944863057000529933)\\n - \u2b50\ufe0f [2022 \u5e74\u7684 React \u751f\u6001](https://juejin.cn/post/7085542534943883301)\\n - \u2b50\ufe0f [React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb](https://juejin.cn/post/7010539227284766751)\\n - \ud83c\udf1b [Before You memo()](https://overreacted.io/before-you-memo/)\\n - \ud83c\udf1b [\u56fe\u89e3 React - bailout\u903b\u8f91](https://7kms.github.io/react-illustration-series/main/fibertree-update/#bailout%E9%80%BB%E8%BE%91-bailout)\\n - \ud83c\udf1b [React \u7684 Concurrent Mode \u662f\u5426\u6709\u8fc7\u5ea6\u8bbe\u8ba1\u7684\u6210\u5206](https://www.zhihu.com/question/434791954/answer/2453356416)\\n - \ud83c\udf1b [\u300c\u4e0a\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://www.bilibili.com/video/BV1Yr4y1J7oc)\\n - \ud83c\udf1b [\u300c\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://www.bilibili.com/video/BV1j44y1g74m)\\n - \ud83c\udf1b [Build your own React](https://pomb.us/build-your-own-react/)\\n - [Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09](https://juejin.cn/post/6844903913410314247)\\n - [\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406](https://juejin.cn/post/7121378029682556958)\\n - [React \u6e32\u67d3\u7684\u672a\u6765](https://juejin.cn/post/7154175507280429070)\\n - [React \u4e2d\u5e38\u89c1\u7684 8 \u4e2a\u9519\u8bef\uff0c\u5982\u4f55\u907f\u514d](https://mp.weixin.qq.com/s/METf8Ng6Qnsu1uWGTzan8g)\\n - [20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08](https://juejin.cn/post/7104460511869141006)\\n - [React\u5b98\u65b9\u56e2\u961f\u51fa\u624b\uff0c\u8865\u9f50\u539f\u751fHook\u77ed\u677f](https://juejin.cn/post/7094424941541457933)\\n - [React Hooks \u7684\u539f\u7406\uff0c\u6709\u7684\u7b80\u5355\u6709\u7684\u4e0d\u7b80\u5355](https://juejin.cn/post/7075701341997236261)\\n - [\u4ecereact hooks\u201c\u95ed\u5305\u9677\u9631\u201d\u5207\u5165\uff0c\u6d45\u8c08react hooks](https://juejin.cn/post/6844904193044512782)\\n - [React+Ts\uff0c\u8fd9\u6837\u5b66\u8d77\u6765\u786e\u5b9e\u7b80\u5355\uff01\uff01\uff01](https://mp.weixin.qq.com/s/7LXeQomcHK4zcuRqB32JDg)\\n - [React 18 \u8d85\u5168\u5347\u7ea7\u6307\u5357](https://mp.weixin.qq.com/s/byD6xm3O6MzX8kksjBmqpA)\\n - [\u963f\u91cc\u4e09\u9762\uff1a\u7075\u9b42\u62f7\u95ee\u2014\u2014\u6709react fiber\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u9700\u8981vue fiber\u5462](https://juejin.cn/post/7077545184807878692)\\n - [\\\\[\u5efa\u8bae\u6536\u85cf\\\\] \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709](https://juejin.cn/post/6982004709145968677)\\n - [\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React](https://juejin.cn/post/6978654109893132318)\\n - [\u624b\u5199React\u7684Fiber\u67b6\u6784\uff0c\u6df1\u5165\u7406\u89e3\u5176\u539f\u7406](https://juejin.cn/post/6844904197008130062)\\n - [React Fiber \u6e90\u7801\u89e3\u6790](https://juejin.cn/post/6859528127010471949)\\n - [\u8d70\u8fdbReact Fiber\u7684\u4e16\u754c](https://juejin.cn/post/6943896410987659277)\\n - [\u524d\u7aef\u5de5\u7a0b\u5e08\u7684\u81ea\u6211\u4fee\u517b\uff1aReact Fiber \u662f\u5982\u4f55\u5b9e\u73b0\u66f4\u65b0\u8fc7\u7a0b\u53ef\u63a7\u7684](https://juejin.cn/post/6911681589558640654)\\n - [React Fiber\u5f88\u96be\uff1f\u516d\u4e2a\u95ee\u9898\u52a9\u4f60\u7406\u89e3 React Fiber](https://juejin.cn/post/6984949525928476703)\\n- Vite \u6e90\u7801\\n - \u2b50\ufe0f [\u6df1\u5165\u6d45\u51fa Vite](https://juejin.cn/book/7050063811973218341)\\n - [\u8be6\u89e3 Vite \u4f9d\u8d56\u9884\u6784\u5efa\u6d41\u7a0b](https://mp.weixin.qq.com/s/UD0-7rWtOAxMuDpOR77gug)\\n - [\u6388\u4eba\u4e88\u6e14\uff0cVSCode \u5982\u4f55\u8c03\u8bd5 Vite \u4ee3\u7801](https://mp.weixin.qq.com/s/bf11t1rH6NllKDA0IKR9Lw)\\n - [\u6572\u4e0b vite \u547d\u4ee4\u540e\uff0cserver \u505a\u4e86\u54ea\u4e9b\u4e8b](https://mp.weixin.qq.com/s/3dfbu7lZJLd6cJSp9XLcVQ)\\n- \u5305\u7ba1\u7406\u65b9\u6848\u3001PNPM\\n- Arch Linux\\n - [10 Practical Grep Command Examples for Developers](https://linuxhandbook.com/grep-command-examples/)\\n - [The Linux Command Handbook \u2013 Learn Linux Commands for Beginners](https://www.freecodecamp.org/news/the-linux-commands-handbook/#the-linux-grep-command)\\n- \u5982\u4f55\u642d\u5efa\u4e2a\u4eba\u535a\u5ba2\\n - \u4f7f\u7528 Next.js\uff0c\u5f00\u7bb1\u5373\u7528\u6587\u4ef6\u7cfb\u7edf\u8def\u7531\u3001\u9759\u6001\u7ad9\u70b9\u751f\u6210\uff08SSG\uff09\\n - https://nextjs.org/learn/basics/create-nextjs-app\\n- \u5de5\u7a0b\u5316\u65b9\u6848\u603b\u7ed3\u4e0b\\n - [2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357](https://zhuanlan.zhihu.com/p/403970666)\\n - [2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48](https://juejin.cn/post/7017710911443959839)\\n - [\ud83d\udd25\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb](https://juejin.cn/post/7023242274876162084)\\n - [Next.js webpack \u914d\u7f6e](https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts)\\n- \u9759\u6001\u9875\u9762\u90e8\u7f72\u65b9\u6848\\n - \u4e0a\u4f20\u963f\u91cc\u4e91 OSS\\n https://github.com/Menci/upload-to-oss\\n- [\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u5f00\u53d1\u6a21\u5f0f - \u5199\u4e8e2021\u5e74](https://juejin.cn/post/6992172458748936222)\\n- [\u4ece\u96f6\u642d\u5efaWebpack5-react\u811a\u624b\u67b6(\u9644\u6e90\u7801)](https://juejin.cn/post/6990538424545443854)\\n- [\u624b\u5199\u5404\u79cd\u6e90\u7801](https://github.com/JinJieTan/Peter-)\\n\\n## \ud83d\udcd2 \u63a8\u8350\u9605\u8bfb\\n\\n- [2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357](https://zhuanlan.zhihu.com/p/403970666)\\n- [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57](https://juejin.cn/post/6996816316875161637#heading-15)\\n- https://github.com/webpack/webpack-dev-middleware\\n- [webpack-dev-middleware \u63d2\u4ef6\u7684\u4f7f\u7528](https://segmentfault.com/a/1190000011761306)\\n- [webpack-dev-middleware \u6e90\u7801\u89e3\u8bfb](https://juejin.cn/post/6844904099985489927)\\n- [\\\\[\u4e07\u5b57\u603b\u7ed3\\\\] \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406](https://juejin.cn/post/6949040393165996040#heading-2)\\n- [\u8ddf\u6751\u957f\u8001\u5e08\u505a\u3010Vue DevUI \u5f00\u6e90\u6307\u5357\u3011\u76f4\u64ad\u4e00\u4e2a\u6708\u7684\u611f\u53d7](https://juejin.cn/post/7020678344219820068)\\n- [\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 008: webpack HMR \u5b9e\u73b0\u7684\u6838\u5fc3\u539f\u7406](https://juejin.cn/post/7021167384484380709)\\n- [\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406](https://juejin.cn/post/7030207667457130527)\\n- [\u624b\u6478\u624b\u6559\u4f60\u7528Vue3+Typescript+Rollup+Tailwinds\u6253\u9020\u63d2\u62d4\u5f0f\u7684\u4e1a\u52a1\u7ec4\u4ef6\u5e93](https://juejin.cn/post/6959115798841393160)\\n- [\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup](https://juejin.cn/post/6869551115420041229)\\n- \ud83c\udf1b [\u624b\u6478\u624b\u5b66\u4f1a\u642d\u5efa\u4e00\u4e2a TS+Rollup \u7684\u521d\u59cb\u5f00\u53d1\u73af\u5883](https://juejin.cn/post/7029525775321661470)\\n- [\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1a\u5982\u4f55\u5b9e\u73b0\u7ec4\u4ef6\u7684\u6309\u9700\u6253\u5305\ud83d\udce6](https://juejin.cn/post/7029292539479867429)\\n- [\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020](https://juejin.cn/post/7029262501833359368)\\n- [coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b](https://juejin.cn/post/6974377246140301342)\\n- [\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48](https://juejin.cn/post/6892886272377880583)\\n- \ud83c\udf1b [\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a](https://juejin.cn/post/7028222480326066213)\\n- [\u5982\u4f55\u63a8\u52a8\u524d\u7aef\u56e2\u961f\u7684\u57fa\u7840\u8bbe\u65bd\u5efa\u8bbe](https://juejin.cn/post/6844904093434019853)\\n- \u2b50\ufe0f [Element UI\u6e90\u7801\u4e2d\u5b66\u5230\u7684\u6280\u5de7](https://juejin.cn/post/6966491047257964575)\\n- [\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b](https://juejin.cn/post/7026658230365323301)\\n- [\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f](https://juejin.cn/post/6859538537830858759)\\n- [\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136](https://juejin.cn/post/7026671646555504676)\\n- [\u4ece\u96f6\u64b8\u4e00\u4e2aCLI\u547d\u4ee4\u884c\u811a\u624b\u67b6\u5de5\u5177](https://juejin.cn/post/6920044884594425864)\\n- [\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1](https://juejin.cn/post/6844904197863964685)\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0a\uff09](https://juejin.cn/post/6943430853972852750)\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0b\uff09](https://juejin.cn/post/6946008649026240519)\\n- [git hooks \u7684\u5e93 husky \u6e90\u7801\u8fd9\u4e48\u7b80\u5355\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4e00\u4e2a\uff01](https://juejin.cn/post/7026274816734789663)\\n- [\u300cReact18\u65b0\u7279\u6027\u300d\u6df1\u5ea6\u89e3\u8bfb\u4e4buseMutableSource](https://juejin.cn/post/7026210002042011655)\\n- [\u3010V8\u6e90\u7801\u8865\u5145\u7bc7\u3011\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282](https://juejin.cn/post/6953452438300917790)\\n- [\\\\[\u63a2\u7d22\\\\]Webpack DevServer\u548cHMR\u539f\u7406](https://juejin.cn/post/6966422095274180639)\\n- [\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb](https://juejin.cn/post/7023242274876162084)\\n- [\u4ece\u5934\u5f00\u59cb\uff0c\u5f7b\u5e95\u7406\u89e3\u670d\u52a1\u7aef\u6e32\u67d3\u539f\u7406(8\u5343\u5b57\u6c47\u603b\u957f\u6587)](https://juejin.cn/post/6844903881390964744)\\n- [\u5256\u6790 Webpack SplitChunksPlugin \u6e90\u7801: \u5b66\u5b8c\u4f60\u4e5f\u80fd\u5199\u4e00\u4e2a](https://juejin.cn/post/6982157120594509837)\\n- [\u4e00\u70b9\u5173\u4e8e\u670d\u52a1\u7aef\u6e32\u67d3\u7684\u5206\u4eab](https://juejin.cn/post/7025164660751990798)\\n- [\u4ece 0 \u6784\u5efa\u81ea\u5df1\u7684\u811a\u624b\u67b6/CLI\u77e5\u8bc6\u4f53\u7cfb\uff08\u4e07\u5b57\uff09 \ud83d\udee0](https://juejin.cn/post/6966119324478079007)\\n- [\u624b\u5199\u4e00\u4e2a\u865a\u62dfDOM\u5e93\uff0c\u5f7b\u5e95\u8ba9\u4f60\u7406\u89e3diff\u7b97\u6cd5](https://juejin.cn/post/6984939221681176607)\\n- [10\u4e2a\u7b80\u5355\u7684\u6280\u5de7\u8ba9\u4f60\u7684 vue.js \u4ee3\u7801\u66f4\u4f18\u96c5\ud83c\udf4a](https://juejin.cn/post/6854573215969181703)\\n- [\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key](https://juejin.cn/post/7026119446162997261)\\n- [\u505a\u4e86\u4e24\u5e74\u524d\u7aef\u5f00\u53d1\uff0c\u5e73\u65f6\u5c31\u662f\u62ff Vue \u5199\u5199\u9875\u9762\u548c\u7ec4\u4ef6\uff0c\u7b80\u5386\u7684\u9879\u76ee\u7ecf\u5386\u5e94\u8be5\u600e\u4e48\u5199\u5f97\u597d\u770b\uff1f](https://www.zhihu.com/question/384048633/answer/1134746899)\\n- [2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48](https://juejin.cn/post/7017710911443959839)\\n- [\u5206\u4eab\u4e00\u5e74\u4ee5\u6765\u7684Electron\u5f00\u53d1\u7ecf\u9a8c](https://juejin.cn/post/7016534471734198279)\\n- [\u300c\u524d\u7aef\u8fdb\u9636\u300d\u9ad8\u6027\u80fd\u6e32\u67d3\u5341\u4e07\u6761\u6570\u636e(\u65f6\u95f4\u5206\u7247)](https://juejin.cn/post/6844903938894872589)\\n- \u2b50\ufe0f [\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React](https://juejin.cn/post/6978654109893132318)\\n- [\u624b\u5199\u7cfb\u5217-\u8fd9\u4e00\u6b21\uff0c\u5f7b\u5e95\u641e\u61c2 Promise](https://juejin.cn/post/6973155726302642206)\\n- [50\u884c\u4ee3\u7801\u4e32\u884cPromise\uff0ckoa\u6d0b\u8471\u6a21\u578b\u539f\u6765\u662f\u8fd9\u4e48\u5b9e\u73b0\uff1f](https://juejin.cn/post/7005375860509245471)\\n- [\u73a9\u8f6c node \u5b50\u8fdb\u7a0b \u2014 child_process](https://juejin.cn/post/6882290865763680264)\\n- [\u6df1\u5165\u5256\u6790\uff1aVue\u6838\u5fc3\u4e4b\u865a\u62dfDOM](https://juejin.cn/post/6844903895467032589)\\n- \u2b50\ufe0f [\u4ece\u96f6\u5f00\u59cb\u914d\u7f6e react + typescript\uff08\u4e00\uff09\uff1adotfiles](https://juejin.cn/post/6844904055618158600)\\n- [Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790](https://juejin.cn/post/6937125495439900685)\\n- [TypeScript \u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217](https://juejin.cn/post/7025213391618703367)\\n- [\u7528ts\u7c7b\u578b\u7cfb\u7edf\u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217](https://juejin.cn/post/6965320374451961886)\\n- [\u521d\u6b65\u5c1d\u8bd5 tauri\uff0c\u5e76\u4e14\u4e0e electron.js \u5bf9\u6bd4](https://juejin.cn/post/7059400669916037133)\\n- [\u548c\u5927\u591a\u6570\u7684\u524d\u7aef\u5f00\u53d1\u8005\u76f8\u6bd4\uff0c\u6211\u5e76\u6ca1\u6709\u9009\u62e9node.js\u505acli\u800c\u6295\u9760\u4e86golang](https://juejin.cn/post/7057178581897740319)\\n- [React Fiber Architecture](https://github.com/acdlite/react-fiber-architecture)\\n- [linux\u547d\u4ee4\u603b\u7ed3\u4e4blsof\u547d\u4ee4](https://www.cnblogs.com/ginvip/p/6367939.html)\\n- [Machine Learning For Front-End Developers With Tensorflow.js](https://www.smashingmagazine.com/2019/09/machine-learning-front-end-developers-tensorflowjs/)\\n- [javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw)\\n- [\u6211\u7684\u7b2c\u4e00\u6b21webpack\u4f18\u5316\uff0c\u9996\u5c4f\u6e32\u67d3\u4ece9s\u52301s](https://zhuanlan.zhihu.com/p/476712416)\\n- [\u5728\u9879\u76ee\u4e2d\u7528ts\u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u6574\u4e2a\u56e2\u961f\u53d7\u76ca\ud83d\ude01](https://juejin.cn/post/7071518211392405541)\\n- [\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09](https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ)\\n- [\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ)\\n- \u2b50\ufe0f [\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01](https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A)\\n- \u2b50\ufe0f [\u817e\u8baf\u4e91\u540e\u7aef15\u8fde\u95ee\uff01](https://mp.weixin.qq.com/s/aMYJODhtWsBt9CTJxySQEQ)\\n- \u2b50\ufe0f [\u5b57\u8282\u56fd\u9645\u652f\u4ed8\u5341\u8fde\u95ee](https://mp.weixin.qq.com/s/0kUf1ujPUuieyOSMsBIzaw)\\n- [\u5982\u4f55\u6210\u4e3a\u4e00\u4e2a\u4f18\u79c0\u7684\u590d\u5236\u7c98\u8d34\u5de5\u7a0b\u5e08](https://juejin.cn/post/7080032725477883917)\\n- [docker\u6587\u4ef6\u5939\u6620\u5c04\u7684\u4e24\u79cd\u65b9\u5f0f---\u4e3b\u673a\u5377\u6620\u5c04\u548c\u5171\u4eab\u6587\u4ef6\u5939\u6620\u5c04](https://blog.csdn.net/zhydream77/article/details/81909706)\\n- [\u4e3a\u4ec0\u4e48golang\u6ca1\u6709min/max\u4ee5\u53ca\u4e09\u5143\u64cd\u4f5c\u7b26](https://studygolang.com/articles/25997?fr=sidebar)\\n- [\u7f16\u8bd1 ts \u4ee3\u7801\u7528 tsc \u8fd8\u662f babel](https://juejin.cn/post/7084882650233569317)\\n- [\u5982\u679c\u6ca1\u6709 package-lock.json\uff0c\u90a3\u5c06\u5982\u4f55](https://juejin.cn/post/7031122959637217310)\\n- [\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 023\uff1anode_modules \u7248\u672c\u91cd\u590d\u7684\u56f0\u5883](https://juejin.cn/post/7030084290989948935)\\n- [\u3010\u6df7\u6dc6\u7cfb\u5217\u3011\u4e09\u95ee\uff1anpx\u3001npm\u3001cnpm\u3001pnpm\u533a\u522b\u4f60\u641e\u6e05\u695a\u4e86\u5417\uff1f](https://juejin.cn/post/7083468345579667493)\\n- [Webpack\u7ec4\u4ef6\u5e93\u6253\u5305\u8d85\u8be6\u7ec6\u6307\u5357](https://juejin.cn/post/7082738107237433375)\\n- [\u5199\u597d JavaScript \u5f02\u6b65\u4ee3\u7801\u7684\u51e0\u4e2a\u63a8\u8350\u505a\u6cd5](https://mp.weixin.qq.com/s/XWZsKQECcsHAlE9cyqi9Eg)\\n- [Node.js \u8fdb\u9636 - \u591a\u6587\u4ef6 Stream \u5408\u5e76\uff0c\u4e32\u884c\u548c\u5e76\u53d1\u4e24\u79cd\u6a21\u5f0f\u5b9e\u73b0](https://mp.weixin.qq.com/s/WisEGFz2yn_ZeekViofMnA)\\n- [\u670d\u52a1\u7aef\u6e32\u67d3SSR\u53ca\u5b9e\u73b0\u539f\u7406](https://juejin.cn/post/7046898330000949285)\\n- [\u624b\u6478\u624b\u670d\u52a1\u7aef\u6e32\u67d3-react](https://mp.weixin.qq.com/s/lyff2svfHh4rdsWRL4H5uA)\\n- [\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript](https://juejin.cn/post/7058868160706904078)\\n- [\u9009\u62e9\u7b2c\u4e09\u65b9 NPM \u5305\u65f6\u7684 5 \u6761\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/kGMsNmIXlT25NfRrifjnTQ)\\n- [\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86](https://juejin.cn/post/7071066976830881823)\\n- [React 18 \u5168\u89c8](https://mp.weixin.qq.com/s/t3dYc3Md1dpiv1vaFa5plA)\\n- [React 18 \u5bf9 Hooks \u7684\u5f71\u54cd](https://mp.weixin.qq.com/s/fgT7Kxs_0feRx4TkBe6G5Q)\\n- [React \u7684\u5fc3\u667a\u6a21\u578b](https://mp.weixin.qq.com/s/GatHpP3BRLV_I48MfpzR4A)\\n- [\u4f60\u4e0d\u77e5\u9053\u7684 React v18 \u7684\u4efb\u52a1\u8c03\u5ea6\u673a\u5236](https://mp.weixin.qq.com/s/qyr6MnPtvnELDSbPJ2VtIw)\\n- [\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0a)](https://segmentfault.com/a/1190000041683300)\\n- [\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0b)](https://segmentfault.com/a/1190000041683421)\\n- [Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb](https://zhuanlan.zhihu.com/p/502951532)\\n- [\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93](https://zhuanlan.zhihu.com/p/415361629)\\n- [\u524d\u7aef\u7b97\u6cd5\u7cfb\u7edf\u7ec3\u4e60: \u6808\u548c\u961f\u5217\u7bc7](https://mp.weixin.qq.com/s/tWbeOTx0JpiZOD0YaC1P2A)\\n- [\u3010\u7b2c2602\u671f\u3011\u8bbe\u7f6e NPM Registry \u7684 4 \u79cd\u59ff\u52bf](https://mp.weixin.qq.com/s/MYLi4mSgoi5KXj4-_OgT3A)\\n- [\u300c\u624b\u6478\u624b\u8bbe\u8ba1\u6a21\u5f0f\u7cfb\u5217\u300d \u4eab\u5143\u6a21\u5f0f\u4e0e\u8d44\u6e90\u6c60](https://juejin.cn/post/6844903919995322382)\\n- [\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7](https://juejin.cn/post/6889247428797530126)\\n- [React Hooks \u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6844904165500518414)\\n- [\u624b\u5199 CSS-modules \u6765\u6df1\u5165\u7406\u89e3\u5b83\u7684\u539f\u7406](https://mp.weixin.qq.com/s/3xhNcfI4pTm0n-naSsOBwg)\\n- [\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://www.bilibili.com/video/BV1j44y1g74m)\\n- [Umi 4 \u7279\u6027\u5408\u96c6\uff0c\u6bd4 Vite \u8fd8\u8981\u5feb\uff1f](https://mp.weixin.qq.com/s/-B5M7pjIWZzFNvq-hyr1Mw)\\n- [\u4f60\u53ef\u80fd\u5e76\u6ca1\u6709\u7406\u89e3\u7684 babel \u914d\u7f6e\u7684\u539f\u7406](https://juejin.cn/post/7094296981001994277)\\n- [\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305](https://juejin.cn/post/7052307032971411463)\\n- [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72](https://juejin.cn/post/7069609959985512484)\\n- [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72](https://juejin.cn/post/7083009375387779085)\\n- [\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation](https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww)\\n- [NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357](https://juejin.cn/post/7095354780079357966)\\n- [Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566](https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g)\\n- [\u5982\u4f55\u8bbe\u8ba1\u66f4\u4f18\u96c5\u7684 React \u7ec4\u4ef6](https://mp.weixin.qq.com/s/FPupefVg4zphOfIERZOvHQ)\\n- [React \u5e76\u53d1\u6e32\u67d3\u7684\u524d\u4e16\u4eca\u751f](https://mp.weixin.qq.com/s/01sTK6w4BFUzoRc2NKCs1w)\\n- [\u4f7f\u7528 Next.js \u548c MDX \u6784\u5efa\u4f60\u81ea\u5df1\u7684\u535a\u5ba2](https://www.freecodecamp.org/news/how-to-build-your-own-blog-with-next-js-and-mdx/)\\n- [TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86](https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw)\\n- [TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f](https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g)\\n- [\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb](https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g)\\n- [\u524d\u7aef\u5fc5\u5b66\u7684\u52a8\u753b\u5b9e\u73b0\u601d\u8def\uff0c\u9ad8\u903c\u683c\u7684\u6548\u679c\u8001\u677f\u770b\u4e86\u90fd\u4f1a\u5927\u58f0\u79f0\u8d5e](https://juejin.cn/post/7099402445989609479)\\n- [\u3010\u7b2c2617\u671f\u3011React \u7ec4\u4ef6\u5e93 CSS \u6837\u5f0f\u65b9\u6848\u5206\u6790](https://mp.weixin.qq.com/s/LSlgpazCwtceQWjHsMPCAg)\\n- [\u3010\u7b2c2616\u671f\u3011\u89e3\u91caJavaScript\u7684\u5185\u5b58\u7ba1\u7406](https://mp.weixin.qq.com/s/X4ni2i9bvolHGfCdf3SzIA)\\n- [\u4ece Turborepo \u770b Monorepo \u5de5\u5177\u7684\u4efb\u52a1\u7f16\u6392\u80fd\u529b](https://mp.weixin.qq.com/s/OrekHmMrn8UlisTrvt3MNA)\\n- [\u89e3\u51b3\u524d\u7aef\u5e38\u89c1\u95ee\u9898\uff1a\u7ade\u6001\u6761\u4ef6](https://mp.weixin.qq.com/s/GryL1QVARtMB8-WIzd7xQQ)\\n- [Google \u6700\u65b0\u7684\u6027\u80fd\u4f18\u5316\u65b9\u6848\uff0cLCP \u63d0\u534730%\uff01](https://mp.weixin.qq.com/s/3v54arsDRRw6agyr3MtPRg)\\n- [React useEvent\uff1a\u7816\u5bb6\u8bf4\u7684\u6ca1\u95ee\u9898](https://mp.weixin.qq.com/s/-6bQKIjH6WPcfuiCFtsjng)\\n- [\u88abdiss\u6027\u80fd\u5dee\uff0cDan\u8fde\u591c\u4f18\u5316React\u65b0\u6587\u6863](https://juejin.cn/post/7102328973820067877)\\n- [Node.js \u8c03\u8bd5\u4e00\u8def\u8d70\u6765\u7ecf\u5386\u4e86\u4ec0\u4e48](https://juejin.cn/post/7102233142567632933)\\n- [\u63a8\u8350\u4e00\u4e2a\u524d\u7aef\u6280\u672f\u9009\u578b\u795e\u5668](https://mp.weixin.qq.com/s/g1fr1fnGspi7SETyP9B6rA)\\n- [\u6700\u9ad8\u6027\u80fd\u7684\u5305\u7ba1\u7406\u5668-pnpm](https://mp.weixin.qq.com/s/2OXIGB5qQFc2isIxhm33bg)\\n- [\u5e76\u53d1\u6e32\u67d3\u4f18\u5316\uff1a\u8ba9\u6587\u4ef6\u6811\u7684\u6e32\u67d3\u53c8\u5feb\u53c8\u7a33](https://mp.weixin.qq.com/s/3yy9V5HMDWPFwEf1cyL-lw)\\n- [\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf](https://juejin.cn/post/7092766235380678687)\\n- [\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1](https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg)\\n- [\u6df1\u5165\u7406\u89e3 Linux CPU \u4e0a\u4e0b\u6587\u5207\u6362](https://mp.weixin.qq.com/s/KwmNzTdjMB-ljQ0ysEGalg)\\n- [\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee](https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg)\\n- [100 \u884c\u4ee3\u7801\u5b9e\u73b0 React \u8def\u7531](https://github.com/ashok-khanna/react-snippets/blob/main/Router.js)\\n- [\u7cbe\u8bfb\u300areact-snippets - Router \u6e90\u7801\u300b](https://juejin.cn/post/7100736564979826695)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u673a\u7968\u524d\u7aefSvelte\u751f\u4ea7\u5b9e\u8df5](https://mp.weixin.qq.com/s/QWwb8PXtdJJUKyicHRmBkw)\\n- [\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6](https://juejin.cn/post/7069772395610898462)\\n- [\u6a21\u5757\u8054\u90a6\u6d45\u6790](https://juejin.cn/post/7101457212085633054)\\n- [\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684](https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g)\\n- [\u3010\u96f6\u57fa\u7840\u3011\u5145\u5206\u7406\u89e3WebGL\uff08\u4e09\uff09](https://mp.weixin.qq.com/s/ULY-_Vq-Jgb8aCbhyfqYHw)\\n- [Web3.0\u5f00\u53d1\u5165\u95e8](https://mp.weixin.qq.com/s/ROwTG6AC2pK5UN1dzY5x8w)\\n- [\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357](https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg)\\n- [\u5256\u6790React\u6838\u5fc3\u8bbe\u8ba1\u539f\u7406\u2014Virtual Dom](https://mp.weixin.qq.com/s/l19wbHNIrhjyD0HwJwuvmQ)\\n- [\u3010\u7b2c2630\u671f\u3011javascript\u4e2d\u7684\u4f9d\u8d56\u6ce8\u5165](https://mp.weixin.qq.com/s/b15cyyg53lVKQ_TtR8hugQ)\\n- [\u3010\u524d\u7aef\u90e8\u7f72\u9644\u5f55\u4e00\u3011\u5199\u7ed9\u524d\u7aef\u7684 docker \u4f7f\u7528\u6307\u5357](https://mp.weixin.qq.com/s/sEvP3nLUOBwbSHP9mmT__A)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6838\u5fc3service\u7c7b\u521d\u59cb\u5316](https://mp.weixin.qq.com/s/f8mYoozpLrnSfWcRHTMa7A)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u63d2\u4ef6\u5316\u67b6\u6784\u6838\u5fc3](https://mp.weixin.qq.com/s/y-6Uf1hNBF19MabHEtqnJA)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u8fd0\u884c\u65f6\u63d2\u4ef6\u673a\u5236](https://mp.weixin.qq.com/s/4cZ3rJz4P5bSRSeXDbFoMQ)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6784\u5efa\u539f\u7406](https://mp.weixin.qq.com/s/2MsgPh9AZtUoJpsLLdOynQ)\\n- [\u5982\u4f55\u534e\u4e3d\u7684\u5b9e\u73b0\u4e00\u5957\u811a\u624b\u67b6 - \u4ee5umicli\u548c\u8f6c\u8f6czzcli\u4e3a\u4f8b](https://mp.weixin.qq.com/s/Sz8u6lzkL1nnpRxGrdbYJg)\\n- [Umi 4 \u7279\u6027 05\uff1a\u7a33\u5b9a\u767d\u76d2\u6027\u80fd\u597d\u7684 ESLint](https://www.yuque.com/antfe/featured/uf1bok)\\n- [\u6df1\u5165\u6d45\u51fa npm & yarn & pnpm \u5305\u7ba1\u7406\u673a\u5236](https://mp.weixin.qq.com/s/ZTI-8RI0l314Ki9oBxqRWw)\\n- [\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c](https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg)\\n- [\u4e00\u4e2a\u4e09\u5c0f\u65f6\u7684 React Native \u901f\u6210\u8bfe](https://www.youtube.com/watch?v=VozPNrt-LfE)\\n- [\u524d\u7aef\u914d\u7f6e\u5316\u771f\u9999\uff5e\u4e0a\u73ed\u53c8\u591a\u4e8660%\u7684\u6478\ud83d\udc1f\u65f6\u95f4](https://juejin.cn/post/7098211898990002207)\\n- [20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08](https://juejin.cn/post/7104460511869141006)\\n- [Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u5982\u4f55\u5c06 template \u7f16\u8bd1\u6210 AST](https://juejin.cn/post/7116296421816418311)\\n- [Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6a21\u578b\u6811\u4f18\u5316](https://juejin.cn/post/7117085295798911012)\\n- [Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6700\u540e\u4e00\u66f2\uff0crender code \u751f\u6210](https://juejin.cn/post/7121504219588198413)\\n- [\u521d\u63a2 Vue3 \u7f16\u8bd1\u4e4b\u7f8e](https://juejin.cn/post/7124890499478978597)\\n- [Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u62bd\u8c61\u8bed\u6cd5\u6811\u7684\u751f\u6210](https://juejin.cn/post/7126712173014810661)\\n- [Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u7a7a\u767d\u5b57\u7b26\u7684\u5904\u7406](https://juejin.cn/post/7127074001897127943)\\n- [\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a](https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q)\\n- [Monorepo Handbook \u65b0\u9c9c\u51fa\u7089](https://turborepo.org/docs/handbook/what-is-a-monorepo)\\n- [Vue3\u7ec4\u4ef6\u5e93\u6253\u5305\u6307\u5357\uff0c\u4e00\u6b21\u751f\u6210esm\u3001esm-bundle\u3001commonjs\u3001umd\u56db\u79cd\u683c\u5f0f](https://juejin.cn/post/7152045316294836260)\\n- [Koa\u7684\u6d0b\u8471\u4e2d\u95f4\u4ef6\uff0cRedux\u7684\u4e2d\u95f4\u4ef6\uff0cAxios\u7684\u62e6\u622a\u5668\u8ba9\u4f60\u8ff7\u60d1\u5417\uff1f\u5b9e\u73b0\u4e00\u4e2a\u7cbe\u7b80\u7248\u7684\u5c31\u5f7b\u5e95\u641e\u61c2\u4e86](https://juejin.cn/post/6844904039608500237)\\n- [\u5b66\u4e60 Babel \u63d2\u4ef6\uff0c\u628a Vue2 \u8bed\u6cd5\u81ea\u52a8\u8f6c\u6210 Vue3\uff01](https://mp.weixin.qq.com/s/khS0wkBzQe4Lxn7jHK_0vA)\\n- [\u5982\u4f55\u7f16\u5199\u795e\u5947\u7684\u300c\u63d2\u4ef6\u673a\u5236\u300d\uff0c\u4f18\u5316\u57fa\u4e8e Antd Table \u5c01\u88c5\u8868\u683c\u7684\u6df7\u4e71\u4ee3\u7801](https://mp.weixin.qq.com/s/QgOslh1TwpU2cJubnNxYNw)\\n- [\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406](https://juejin.cn/post/7121378029682556958)\\n- [\u803d\u8bef\u4f60\u5341\u5206\u949f\uff01\ud83c\udf83\u4f60\u53ef\u80fd\u7528\u5f97\u4e0a\u8fd9\u4e9bwebpack5\u65b0\u7279\u6027](https://juejin.cn/post/7123969545387114509)\\n- [\u5206\u5305\u738b\uff01\ud83e\udde8\u4f18\u5316\u9879\u76ee\u4f53\u79ef\u51cf\u5c1120%\uff01](https://juejin.cn/post/7118782372220567566)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u6a21\u578b\u5149\u6e90\u7ed3\u5408\u751f\u6210\u660e\u6697\u53d8\u5316\u7684\u521b\u610f\u9875\u9762-\u5149\u4e0e\u5f71\u4e4b\u8bd7 \ud83d\udca1](https://juejin.cn/post/7148969678642102286)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0b\uff09](https://juejin.cn/post/7146383940931026958)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0a\uff09](https://juejin.cn/post/7145064095178293285)\\n- [\u26a1\ufe0f The Cost Of JavaScript (2017 - 2023)](https://supercodepower.com/the-cost-of-javascript)\\n- [\ud83d\uddc2 \u524d\u7aef\u7248\u672c\u517c\u5bb9\u95ee\u9898\u7684\u63a2\u7d22](https://supercodepower.com/fontend-target)\\n- [\ud83d\uddc2 \u5bf9 web.dev \u6240\u6709 blog \u7684\u6574\u7406\u4e0e\u5f52\u6863](https://supercodepower.com/web-dev-blog)\\n- [\ud83e\udd2f \u6ca1 2 \u5e74 React Native \u5f00\u53d1\u7ecf\u9a8c\uff0c\u4f60\u90fd\u9047\u4e0d\u5230\u8fd9\u4e9b\u5751](https://supercodepower.com/react-native-tweet)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa](https://juejin.cn/post/7146183222425518093)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u57fa\u7840\u77e5\u8bc6\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146973901166215176)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u7b97\u6cd5\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146975493278367752)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u5de5\u7a0b\u5316\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146976516692410376)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u524d\u7aef\u6846\u67b6+\u6d4f\u89c8\u5668\u539f\u7406\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146996646394462239)\\n- [20\u4e2a\u5e38\u89c1\u7684\u524d\u7aef\u7b97\u6cd5\u9898\uff0c\u4f60\u5168\u90fd\u4f1a\u5417](https://juejin.cn/post/7158730050718662687)\\n- [\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e](https://juejin.cn/post/7151653067593613320)\\n- [\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305](https://juejin.cn/post/7126394898445500423)\\n- [\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def](https://juejin.cn/post/7157902763534319624)\\n- [\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3](https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg)\\n- [\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3](https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g)\\n- [\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3](https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA)\\n- [\u50bb\u74dc\u65b9\u5f0f\u5206\u6790\u524d\u7aef\u5e94\u7528\u7684\u4f53\u79ef](https://juejin.cn/post/7172001951784108040)\\n- [\u624b\u5199 Bundler: \u5b9e\u73b0\u4ee3\u7801\u6253\u5305\u3001 Tree Shaking](https://juejin.cn/book/7050063811973218341/section/7070419010021490702)\\n- [\u624b\u5199 Bundler: \u5b9e\u73b0 JavaScript AST \u89e3\u6790\u5668\u2014\u2014\u8bcd\u6cd5\u5206\u6790\u3001\u8bed\u4e49\u5206\u6790](https://juejin.cn/book/7050063811973218341/section/7066614663533821983)\\n- [\u3010\u7b2c2795\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u4e09\u7aef\u540c\u6784\u7bc7](https://mp.weixin.qq.com/s/1xY0hfcwJci1hr4TKUZMqg)\\n- [\u3010\u7b2c2785\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u8de8\u7aef\u5bb9\u5668\u7bc7](https://mp.weixin.qq.com/s/7WU1DDoMYQzXnlstz16QJA)\\n- [Vite \u7279\u6027\u548c\u90e8\u5206\u6e90\u7801\u89e3\u6790](https://mp.weixin.qq.com/s/19Ai1rbRoQxOBA5SXSNCAQ)\\n- [Rollup\u6e90\u7801\uff1a\u6a21\u5757\u6253\u5305\u4e0eTree-Shaking](https://juejin.cn/post/7021115814870810660)\\n- [Rollup \u4e0e Webpack \u7684 Tree-shaking](https://juejin.cn/post/7169004126469914654)\\n- [\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def](https://juejin.cn/post/7157902763534319624)\\n- [\u3010Webpack Plugin\u3011\u5199\u4e86\u4e2a\u63d2\u4ef6\u8ddf\u559c\u6b22\u7684\u5973\u751f\u8868\u767d\uff0c\u7ed3\u679c......\ud83d\ude2d\ud83d\ude2d\ud83d\ude2d](https://juejin.cn/post/7160467329334607908)\\n- [\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0a\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b](https://segmentfault.com/a/1190000012081469)\\n- [\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0b\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b](https://segmentfault.com/a/1190000012099163)\\n- [\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801](https://juejin.cn/post/7164175171358556173)\\n- [\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684](https://juejin.cn/post/7170852747749621791)\\n- [Webpack\u6df1\u5ea6\u8fdb\u9636\uff1a\u4e24\u5f20\u56fe\u5f7b\u5e95\u8bb2\u660e\u767d\u70ed\u66f4\u65b0\u539f\u7406\uff01](https://juejin.cn/post/7176963906844246074)\\n- [Webpack4\u7684\u538b\u7f29\u9636\u6bb5\u7684\u6027\u80fd\u4f18\u5316\u548c\u8e29\u5751](https://mp.weixin.qq.com/s/_MJq-88MNFyvDTxUw_lFiA)\\n- [Vue3\u751f\u547d\u5468\u671fHooks\u7684\u539f\u7406\u53ca\u5176\u4e0e\u8c03\u5ea6\u5668(Scheduler)\u7684\u5173\u7cfb](https://juejin.cn/post/7093880734246502414)\\n- [\u3010\ud83d\udc2f\u521d/\u4e2d\u7ea7\u524d\u7aef\u9762\u7ecf\u3011\u4e2d\u5c0f\u578b\u516c\u53f8\u9762\u8bd5\u65f6\u90fd\u4f1a\u95ee\u4e9b\u4ec0\u4e48](https://juejin.cn/post/7064740689178787871)\\n- [\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0a\uff09\uff1a\u4e3a\u4ec0\u4e48\u662f Zustand](https://juejin.cn/post/7177216308843380797)\\n- [\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0b\uff09\uff1a\u57fa\u4e8e Zustand \u7684\u6e10\u8fdb\u5f0f\u72b6\u6001\u7ba1\u7406\u5b9e\u8df5](https://juejin.cn/post/7182462103297458236)\\n- [\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg)\\n- [\u5982\u4f55\u4f7f\u7528jenkins\u642d\u5efa\u4e00\u4e2a\u4e2d\u5c0f\u4f01\u4e1a\u524d\u7aef\u9879\u76ee\u90e8\u7f72\u73af\u5883](https://mp.weixin.qq.com/s/pDXhIMFkyMuiVHB0l9gphw)\\n- [\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8](https://juejin.cn/post/7129298214959710244)\\n- [\u8ddf\u7740\u6765\uff0c\u4f60\u4e5f\u53ef\u4ee5\u624b\u5199VueRouter](https://juejin.cn/post/6991640600533532679)\\n- [\u300c\u786c\u6838JS\u300d\u56fe\u89e3Promise\u8ff7\u60d1\u884c\u4e3a\uff5c\u8fd0\u884c\u673a\u5236\u8865\u5145](https://juejin.cn/post/6997968693414084644)\\n- [\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0a\uff09](https://juejin.cn/post/7007946894605287432)\\n- [\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0b\uff09](https://juejin.cn/post/7012774158371127326)\\n- [\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684 async\u3001await \u7ec6\u8282](https://mp.weixin.qq.com/s/aLQVpglTRA0bJGyCpXOD8Q)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u7269\u7406\u6548\u679c-\u78b0\u649e\u548c\u58f0\u97f3 \ud83d\udca5](https://juejin.cn/post/7200039970575941693)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u65b0\u6625\u7279\u5178-Rabbit craft go \ud83d\udc07](https://juejin.cn/post/7191415427350659129)\\n- [\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300d\u81ea\u5df1\u52a8\u624b\u5b9e\u73b0\u4e00\u4e2aJSX\u8f6c\u6362](https://juejin.cn/post/7212235580104917053)\\n- [\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dFiber\u67b6\u6784\u7684\u5b9e\u73b0\u539f\u7406](https://juejin.cn/post/7212603037667786813)\\n- [\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dReconciler\u67b6\u6784\u7684\u53cc\u7f13\u5b58\u6811\u5b9e\u73b0\u539f\u7406](https://juejin.cn/post/7213362704781852730)\\n- [\u3010webpack\u6838\u5fc3\u5e93\u3011\u8017\u65f67\u4e2a\u5c0f\u65f6\uff0c\u7528\u8fd150\u5f20\u56fe\u6765\u5b66\u4e60enhance-resolve\u4e2d\u7684\u6570\u636e\u6d41\u52a8\u548c\u63d2\u4ef6\u8c03\u5ea6\u673a\u5236](https://mp.weixin.qq.com/s/QcQlOscF9R0aF2x3Oe6doQ)\\n- [\u804a\u804a Ant Design V5 \u7684\u4e3b\u9898\uff08\u4e0a\uff09\uff1aCSSinJS \u52a8\u6001\u4e3b\u9898\u7684\u82b1\u6d3b](https://juejin.cn/post/7199832444836593725)\\n- [\u5199\u7ed9\u5f00\u53d1\u540c\u5b66AI\u5f3a\u5316\u5b66\u4e60\u5165\u95e8\u6307\u5357](https://mp.weixin.qq.com/s/sTBFnSLS-WBjMWDokH2o9A)\\n- [\u4e00\u8d77\u6765\u770b\u770b\u4e00\u4e2a\u4f53\u7cfb\u5b8c\u5584\u7684\u524d\u7aefReact\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u642d\u5efa\u51fa\u6765\u7684\uff01](https://mp.weixin.qq.com/s/d0zbdhTctR7L_62SaY_VJA)\\n- [\u5e72\u8d27 | \u8017\u65f6\u7f29\u77ed2/3\uff0cTaro\u7f16\u8bd1\u6253\u5305\u4f18\u5316\u5b9e\u8df5](https://mp.weixin.qq.com/s/z4GhUr5eA-4WbxVye4hmAQ)\\n- [\u5e72\u8d27 | 30+\u6761\u4e1a\u52a1\u7ebf\uff0c\u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u534f\u540c\u5f00\u53d1](https://mp.weixin.qq.com/s/g1XhCtfIL6yy-37Y_grtEw)\\n- [\u5e72\u8d27 | \u79d2\u5f00\u738770%+\uff0c\u643a\u7a0b\u91d1\u878dSSR\u5e94\u7528\u6027\u80fd\u76d1\u6d4b\u4e0e\u4f18\u5316](https://mp.weixin.qq.com/s/PT4y8OMWTpIto50qnT8gmg)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u8fdb\u884cSize\u6cbb\u7406](https://mp.weixin.qq.com/s/293Lbr81oUWHeJ3TGfPRdw)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5c0f\u7a0b\u5e8f\u751f\u6001\u4e4bTaro\u8de8\u7aef\u89e3\u51b3\u65b9\u6848](https://mp.weixin.qq.com/s/iT05ZXPVYFuCQgZZF9Zu5w)\\n- [\u5e72\u8d27 | \u7626\u8eab50%-70%\uff0c\u643a\u7a0b Taro \u5c0f\u7a0b\u5e8f\u6837\u5f0f Size \u7f29\u51cf\u65b9\u6848](https://mp.weixin.qq.com/s/rpHb5ZhUTOTfbVPEZJFklg)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5546\u65c5\u5927\u524d\u7aef React Streaming \u7684\u63a2\u7d22\u4e4b\u8def](https://mp.weixin.qq.com/s/HUJTU5Du6318LJ7RfQNN2g)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5ea6\u5047\u57fa\u4e8e RPC \u548c TypeScript \u7684 BFF \u8bbe\u8ba1\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/JiJhA6AfNiGXl7p0uQ8mGA)\\n- [INP \u5373\u5c06\u4ee3\u66ff FID \u6210\u4e3a\u65b0\u7684\u6838\u5fc3 Web \u6307\u6807](https://mp.weixin.qq.com/s/OHbzuqUl3tL1YlpLOgEkvA)\\n- [\u3010\u7b2c2973\u671f\u3011\u643a\u7a0bWeb\u7ec4\u4ef6\u5728\u8de8\u7aef\u573a\u666f\u7684\u5b9e\u8df5](https://mp.weixin.qq.com/s/2Dy5RsviZlo7SPA648Mj3g)\\n- [\u8fd9\u4e9b\u5e74\u5728\u963f\u91cc\u5b66\u5230\u7684\u65b9\u6cd5\u8bba](https://mp.weixin.qq.com/s/yPRPakU1UM5iVY-1bwiHJQ)\\n- [/[\u901a\u660e\u5883 \xb7 React\u67b6\u6784/]\u901a\u4fd7\u5730\u8bb2React\uff0c\u4f18\u96c5\u5730\u7406\u89e3React](https://mp.weixin.qq.com/s/ganW_F5GhQV-8s9N2y7jaw)\\n- [React-Router 6.10+KeepAlive\u7684\u7ea6\u5b9a\u5f0f\u8def\u7531\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/daHYuCfstHYqAtscn5T4WQ)\\n- [\u5e72\u8d27\uff01\u6211\u662f\u5982\u4f55\u5728\u4e00\u7ebf\u5927\u5382\u5b9e\u8df5webpack\u4f18\u5316\u7684](https://mp.weixin.qq.com/s/MWf07S5avWzK7vdzhpFsoA)\\n- [\u6d45\u8c08\u9886\u57df\u9a71\u52a8\u5728\u524d\u7aef\u7684\u5e94\u2f64](https://mp.weixin.qq.com/s/WV3oztPYZyGiv4hW0--Jkw)\\n- [Chrome 117 \u53d1\u5e03\uff1a\u65b0 Web \u5f00\u53d1\u8c03\u8bd5\u6280\u5de7\u90fd\u5728\u8fd9\u4e86\uff01](https://mp.weixin.qq.com/s/Z-8lsdLeTqCeFZ4w2oNBjg)"},{"id":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-10/index.md","source":"@site/blogs/2024/2024-03-10/index.md","title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-03-10T00:00:00.000Z","formattedDate":"March 10, 2024","tags":[],"readingTime":34.7,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"\u7f6e\u9876\u5185\u5bb9","permalink":"/frontend-weekly/2024/welcome"},"nextItem":{"title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](maxresdefault.jpg)\\n\\n\u5c01\u9762\u56fe\uff1aUnderstanding the Go runtime - Jesus Espino\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u300aIn-context Learning with Retrieved Demonstrations for Language Models: A Survey\u300b](https://arxiv.org/abs/2401.11624)\u3002\u8fd9\u7bc7\u9898\u4e3a \\"In-context Learning with Retrieved Demonstrations for Language Models: A Survey\\" \u7684\u6587\u7ae0\uff0c\u4e3b\u8981\u8ba8\u8bba\u4e86\u8bed\u8a00\u6a21\u578b\uff0c\u5c24\u5176\u662f\u5927\u578b\u9884\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u5982\u4f55\u901a\u8fc7\u83b7\u53d6\u7684\u6f14\u793a\u8fdb\u884c\u5c11\u91cf\u60c5\u666f\u5b66\u4e60\u3002\u8fd9\u9879\u6280\u672f\u80fd\u6709\u6548\u5730\u6539\u8fdb\u5b66\u4e60\u8fc7\u7a0b\u7684\u6548\u7387\u548c\u53ef\u6269\u5c55\u6027\uff0c\u5e76\u964d\u4f4e\u624b\u52a8\u9009\u62e9\u6837\u4f8b\u65f6\u7684\u56fa\u6709\u504f\u89c1\u3002\u6587\u7ae0\u5bf9\u6b64\u9886\u57df\u8fdb\u884c\u4e86\u5e7f\u6cdb\u7684\u7814\u7a76\u56de\u987e\uff0c\u5bf9\u68c0\u7d22\u6a21\u578b\u3001\u68c0\u7d22\u8bad\u7ec3\u8fc7\u7a0b\u548c\u63a8\u7406\u7b97\u6cd5\u7684\u4e0d\u540c\u8bbe\u8ba1\u9009\u62e9\u8fdb\u884c\u4e86\u8ba8\u8bba\u548c\u6bd4\u8f83\u3002\\n\\n[\u300a\u78be\u538bLoRA\uff01Meta & CMU | \u63d0\u51fa\u9ad8\u6548\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\uff1aGaLore\uff0c\u5185\u5b58\u53ef\u51cf\u5c1163.3%\u300b](https://mp.weixin.qq.com/s/NUhEy0YLTjtzY3BGVXhfrw)\u3002Meta\u548cCMU\u5408\u4f5c\u63d0\u51fa\u4e86\u4e00\u79cd\u65b0\u7684\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\u2014\u2014Gradient Low-Rank Projection\uff08GaLore\uff09\u3002GaLore\u901a\u8fc7\u68af\u5ea6\u7684\u4f4e\u79e9\u6295\u5f71\u4ee3\u66ff\u6743\u91cd\u7684\u4f4e\u79e9\u9002\u914d\uff0c\u4e0d\u4ec5\u652f\u6301\u5168\u53c2\u6570\u5b66\u4e60\uff0c\u800c\u4e14\u663e\u8457\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\uff0c\u51cf\u5c11\u4e8663.3%\u7684\u5185\u5b58\u9700\u6c42\u3002\u4e0d\u540c\u4e8eLoRA\u7684\u4f4e\u79e9\u6743\u91cd\u66f4\u65b0\uff0cGaLore\u5229\u7528\u6743\u91cd\u68af\u5ea6\u7684\u4f4e\u79e9\u7279\u6027\uff0c\u7ed3\u5408\u9010\u5c42\u6743\u91cd\u66f4\u65b0\u548c8\u4f4d\u4f18\u5316\u5668\uff0c\u6709\u6548\u5730\u4f18\u5316\u4e86\u5185\u5b58\u6548\u7387\u3002\u6b64\u5916\uff0cGaLore\u8fd8\u5f15\u5165\u4e86\u53ef\u8c03\u6574\u7684\u8d85\u53c2\u6570\uff0c\u63d0\u9ad8\u4e86\u5176\u9002\u5e94\u6027\u3002\u7ecf\u5b9e\u9a8c\u9a8c\u8bc1\uff0cGaLore\u7684\u8868\u73b0\u4f18\u4e8eLoRA\uff0c\u5c24\u5176\u662f\u5728\u9884\u8bad\u7ec3\u6a21\u578b\u5fae\u8c03\u4e0a\u8868\u73b0\u66f4\u4f73\uff0c\u4e3a\u5927\u6a21\u578b\u8bad\u7ec3\u63d0\u4f9b\u4e86\u65b0\u7684\u89e3\u51b3\u7b56\u7565\u3002\\n\\n[\u4f7f\u7528 GPT4V+AI Agent \u505a\u81ea\u52a8 UI \u6d4b\u8bd5\u7684\u63a2\u7d22 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7316592794109198387)\\n\\n[Gemini\u4feebug\u795e\u4e86\uff01\u5f55\u7f51\u9875\u89c6\u9891\u628a\u4ee3\u7801\u5e93\u7529\u7ed9\u5b83\u5c31\u884c\uff0c\u7f51\u53cb\u5750\u4e0d\u4f4f\u4e86\uff1a\u60f3\u8981\u8bbf\u95ee\u6743\u9650](https://mp.weixin.qq.com/s/ZSDCNDRu-tCkOlC9jz2j4w)\\n\\n[\u4e00\u952e\u5f00\u542f GPU \u95f2\u7f6e\u6a21\u5f0f\uff0c\u57fa\u4e8e\u51fd\u6570\u8ba1\u7b97\u4f4e\u6210\u672c\u90e8\u7f72 Google Gemma \u6a21\u578b\u670d\u52a1](https://mp.weixin.qq.com/s/GXwftkv-UpDQSjiTMn9TFA)\\n\\n[\u300aYi\u6280\u672f\u62a5\u544a\u7ec6\u8282\u5206\u4eab\u300b](https://mp.weixin.qq.com/s/YDwL3dV-Fq5zcEyrL__NGw)\u3002\u8be5\u6587\u7ae0\u5206\u4eab\u4e86Yi\u6a21\u578b\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u548c\u601d\u8def\uff0c\u5f3a\u8c03\u4e86\u6a21\u578b\u8bbe\u8ba1\u56f4\u7ed5\u6a21\u578b\u89c4\u6a21\u3001\u6570\u636e\u89c4\u6a21\u548c\u6570\u636e\u8d28\u91cf\u3002Yi\u6a21\u578b\u7684\u9884\u8bad\u7ec3\u9636\u6bb5\u6570\u636e\u5904\u7406\u6d41\u7a0b\u5305\u62ec\u542f\u53d1\u5f0f\u8fc7\u6ee4\u3001\u5b66\u4e60\u5f0f\u8fc7\u6ee4\u3001\u805a\u7c7b\u8fc7\u6ee4\u4ee5\u53ca\u53bb\u91cd\u7b49\u6b65\u9aa4\uff0c\u4ee5\u63d0\u9ad8\u6570\u636e\u8d28\u91cf\u3002\u5fae\u8c03\u9636\u6bb5\uff0cYi\u6a21\u578b\u4ec5\u91c7\u7528\u4e8610K\u6570\u636e\u8fdb\u884c\u6a21\u578b\u5fae\u8c03\uff0c\u5f3a\u8c03\u6570\u636e\u8d28\u91cf\u80dc\u8fc7\u6570\u91cf\u3002\u5728\u5206\u8bcd\u5668\u3001\u6a21\u578b\u7ed3\u6784\u53ca\u5fae\u8c03\u53c2\u6570\u65b9\u9762\uff0cYi\u6a21\u578b\u91c7\u7528\u4e86\u4e00\u7cfb\u5217\u4f18\u5316\u63aa\u65bd\uff0c\u5305\u62ecTransformer-Decoder\u7ed3\u6784\u3001Grouped-Query Attention\u7b49\u3002\u603b\u7684\u6765\u8bf4\uff0cYi\u6a21\u578b\u901a\u8fc7\u4f18\u5316\u6570\u636e\u5904\u7406\u6d41\u7a0b\u3001\u5fae\u8c03\u7b56\u7565\u3001\u8c03\u6574\u6a21\u578b\u7ed3\u6784\u548c\u53c2\u6570\u7b49\u591a\u65b9\u9762\u5b9e\u73b0\u4e86\u9ad8\u6548\u7684\u6280\u672f\u5b9e\u73b0\u3002\\n\\n[\u91cd\u65b0\u5b9a\u4e49\u5927\u6a21\u578b\u63a8\u7406\uff01Google | \u63d0\u51faSELF-DISCOVER\u6846\u67b6\uff0c\u5927\u6a21\u578b\u53ef\u81ea\u5199\u63a8\u7406\u7ed3\u6784\uff01](https://mp.weixin.qq.com/s/lBXwSVvRHB2Yn0fYoOkDeQ)\\n\\n[\u300a\u65af\u5766\u798f && \u5fae\u8f6f | \u53d1\u5e03\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u52a9\u529b\u524d\u7aef\u81ea\u52a8\u5316\uff01\u300b](https://mp.weixin.qq.com/s/cB5tgMUPqg8fsXjNrzQpbg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u5b83\u53ef\u4ee5\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u7684\u6311\u6218\u6027\u548c\u73b0\u6709\u65b9\u6cd5\u7684\u5c40\u9650\u6027\uff0c\u7136\u540e\u63d0\u51fa\u4e86Design2Code\u57fa\u51c6\u548c\u591a\u6a21\u6001\u63d0\u793a\u65b9\u6cd5\uff0c\u4ee5\u6fc0\u53d1\u591a\u6a21\u6001\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u5982GPT-4V\u548cGemini\uff09\u7684\u6f5c\u529b\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5f00\u6e90\u768418B\u5fae\u8c03\u6a21\u578bDesign2Code-18B\uff0c\u5b83\u57fa\u4e8eCogAgent-18B\uff0c\u5728\u591a\u79cd\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u4e86\u9884\u8bad\u7ec3\uff0c\u5e76\u4f7f\u7528\u4e86Huggingface\u53d1\u5e03\u7684WebSight\u6570\u636e\u96c6\u8fdb\u884c\u5fae\u8c03\u3002\u6700\u540e\uff0c\u6587\u7ae0\u5c55\u793a\u4e86Design2Code-18B\u5728Design2Code\u57fa\u51c6\u4e0a\u7684\u4f18\u8d8a\u6027\u80fd\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u4e9b\u672a\u6765\u7814\u7a76\u65b9\u5411\u3002\\n\\n[\u53ef\u63a7\u6587\u672c\u751f\u6210\u65b0\u65b9\u6cd5\uff0c\u4eba\u5927&&\u5357\u5f00 | \u63d0\u51faDATG\u67b6\u6784\uff0c\u51c6\u786e\u6027\u63d0\u534719.29%\uff0c\u6548\u7387\u63d0\u53471\u500d](https://mp.weixin.qq.com/s/Pdp6_z_rxBl-kph41Lb8Ww)\\n\\n[\u300aAuto-Prompt | \u5927\u6a21\u578b\u63d0\u793a(Prompt)\u4f18\u5316\u65b0\u65b9\u6cd5IPC\uff1a\u53ef\u6839\u636e\u7528\u6237\u610f\u56fe\u8fdb\u884c\u5b9a\u5411\u4f18\u5316\u300b](https://mp.weixin.qq.com/s/53jEDw58dkZlJAVzr31G8A)\u3002\u8fd9\u7bc7\u6587\u7ae0\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3a Intent-based Prompt Calibration\uff08IPC\uff09\u7684\u7cfb\u7edf\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u901a\u8fc7\u4f7f\u7528\u5408\u6210\u6848\u4f8b\u6837\u672c\u6765\u4f18\u5316\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u63d0\u793a\u5de5\u7a0b\u3002\u5b83\u57fa\u4e8e\u6a21\u578b\u751f\u6210\u7684\u6570\u636e\u96c6\u8fdb\u884c\u63d0\u793a\u4f18\u5316\uff0c\u4ee5\u89e3\u51b3\u5927\u8bed\u8a00\u6a21\u578b\u5bf9\u7ed9\u5b9a\u63d0\u793a\u7684\u654f\u611f\u6027\u7b49\u95ee\u9898\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u6838\u5fc3\u601d\u60f3\u662f\u6839\u636e\u7528\u6237\u610f\u56fe\u8fed\u4ee3\u7ec6\u5316\u63d0\u793a\u3002\u540c\u65f6\uff0c\u6587\u7ae0\u8fd8\u5bf9 IPC \u7cfb\u7edf\u7684\u6574\u4f53\u67b6\u6784\u548c\u5b9e\u73b0\u6d41\u7a0b\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u5c55\u793a\u4e86\u4e00\u4e9b\u5b9e\u9a8c\u7ed3\u679c\u3002\\n\\n[\u300a\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c\u300b](https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u51e0\u79cd\u65b0\u578b\u7684\u667a\u80fd Agent \u8bbe\u8ba1\u65b9\u6cd5\uff0c\u5305\u62ec Plan-and-Execute Agents\u3001ReWOO Agent \u548c LLMCompiler\u3002Plan-and-Execute Agent \u8bbe\u8ba1\u6cd5\u901a\u8fc7\u660e\u786e\u89c4\u5212\u6765\u4f18\u5316\u667a\u80fd Agent \u529f\u80fd\u3002ReWOO Agent \u8bbe\u8ba1\u6cd5\u51ed\u501f\u53d8\u91cf\u5206\u914d\u529f\u80fd\u4f7f\u5f97\u4e0d\u5fc5\u5bf9\u6bcf\u4e2a\u4efb\u52a1\u90fd\u4f7f\u7528 LLM\u3002LLMCompiler \u5219\u901a\u8fc7\u4efb\u52a1\u683c\u5f0f\u5316\u4e3a DAG \u6765\u63d0\u9ad8\u5de5\u5177\u8c03\u7528\u7684\u6548\u7387\u3002\u8fd9\u4e9b\u65b0\u578b\u8bbe\u8ba1\u90fd\u5728\u4e0d\u540c\u7a0b\u5ea6\u4e0a\u4f18\u5316\u4e86\u667a\u80fd Agent \u7684\u5de5\u4f5c\u6d41\u7a0b\uff0c\u63d0\u9ad8\u4e86\u5de5\u4f5c\u6548\u7387\u3002\\n\\n[\u300aOpenAI Function Calling \u4e0e LangChain Agent \u5de5\u4f5c\u539f\u7406\u53ca\u533a\u522b\u300b](https://mp.weixin.qq.com/s/F2s3pKycoNDT7Z-6piRHWg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86OpenAI Function Calling \u4e0e LangChain Agent\u7684\u5de5\u4f5c\u539f\u7406\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6587\u7ae0\u9996\u5148\u5217\u4e3e\u4e86\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u9650\u5236\uff0c\u5e76\u89e3\u91ca\u4e86\u4e3a\u4f55\u9700\u8981Agent\u3002\u7136\u540e\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86React Agent\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u901a\u8fc7\u201cReason Only\u201d\uff08\u5411\u5185\u6c42\u7d22\uff09\u3001\u201cAct Only\u201d\uff08\u5411\u5916\u63a2\u7d22\uff09\u548c\u201cReAct\u201d\uff08\u5185\u5916\u517c\u4fee\uff09\u4e09\u79cd\u6a21\u5f0f\u4f18\u5316\u6a21\u578b\u7684\u529f\u80fd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u4ee5\u4e00\u4e2a\u7b80\u5355\u7684\u5b9e\u4f8b\uff0c\u89e3\u91ca\u4e86\u5982\u4f55\u5229\u7528ReAct Agent\u6765\u89e3\u7b54\u4e00\u4e2a\u5305\u542b\u641c\u7d22\u548c\u8ba1\u7b97\u4e24\u4e2a\u6b65\u9aa4\u7684\u95ee\u9898\uff0c\u5c55\u793a\u4e86\u5176\u5b9e\u9645\u5e94\u7528\u7684\u6d41\u7a0b\u3002\\n\\n[\u300aReAct Agent \u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u7684\u590d\u6742\u95ee\u9898\u300b](https://mp.weixin.qq.com/s/iM45toKEHr3_rJxuwbgp4w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u201cReAct Agent \u7528\u4e8e\u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u590d\u6742\u95ee\u9898\u7684\u65b9\u5f0f\u201d\u3002\u968f\u7740\u8f93\u5165\u95ee\u9898\u7684\u590d\u6742\u5ea6\u5347\u9ad8\uff0c\u4f7f\u7528\u4f20\u7edf\u7684\u804a\u5929\u673a\u5668\u4eba\u5df2\u4e0d\u80fd\u8db3\u591f\u6709\u6548\u3002\u4e8e\u662f\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u5229\u7528 ReAct Agent\uff0c\u901a\u8fc7\u81ea\u7136\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u9010\u6b65\u89c4\u5212\u5e76\u6267\u884c\u5904\u7406\u95ee\u9898\u7684\u6b65\u9aa4\uff0c\u5e76\u5b9a\u4e49\u529f\u80fd\u6027\u5de5\u5177\uff08\u5982\u65f6\u95f4\u8ba1\u7b97\u3001\u6587\u672c\u641c\u7d22\u3001\u5217\u8868\u957f\u5ea6\u8ba1\u7b97\u3001\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\u7b49\uff09\u4ee5\u8f85\u52a9\u4efb\u52a1\u5b8c\u6210\u3002\u8fd9\u79cd\u65b9\u6cd5\u80fd\u591f\u66f4\u597d\u5730\u5e72\u9884\u548c\u63a7\u5236\u95ee\u9898\u7684\u89e3\u51b3\u8fc7\u7a0b\uff0c\u4ece\u800c\u63d0\u9ad8\u4efb\u52a1\u7684\u5b8c\u6210\u8d28\u91cf\u3002\\n\\n[\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c](https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA)\\n\\n[ChatGPT\u4e5f\u80fd\u753b\u56fe\uff1f\u6559\u4f60\u4e00\u952e\u751f\u6210\u65f6\u5e8f\u56fe\u3001\u7c7b\u56fe\u3001\u6d41\u7a0b\u56fe\u3001\u72b6\u6001\u56fe\u4ee5\u53ca\u7528\u4f8b\u56fe](https://mp.weixin.qq.com/s/KF7joY-MkK4BZ8Rf8bLArw)\\n\\n[\u4e09\u4e2a\u88ab\u5ffd\u89c6\u7684\u5927\u6a21\u578b\u63d0\u793a](https://mp.weixin.qq.com/s/E2xwi9SNYQ7sdzhYlaDQFg)\\n\\n[\u5173\u4e8eSora\u548cStable Diffusion 3\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://mp.weixin.qq.com/s/u2LCRgBhKKcGZhY29PjIng)\\n\\n[\u6d88\u8d39\u7ea7\u663e\u5361\u53ef\u7528\uff01\u674e\u5f00\u590d\u96f6\u4e00\u4e07\u7269\u53d1\u5e03\u5e76\u5f00\u6e9090\u4ebf\u53c2\u6570Yi\u6a21\u578b\uff0c\u4ee3\u7801\u6570\u5b66\u80fd\u529b\u53f2\u4e0a\u6700\u5f3a](https://mp.weixin.qq.com/s/z6IFIuHawVZI6ZOfgvgKuA)\\n\\n[\u8be6\u89e3\u5927\u6a21\u578b\u5fae\u8c03\u5168\u6d41\u7a0b](https://mp.weixin.qq.com/s/IBh3ytd3gtizAQd5PI2uig)\\n\\n[\u5357\u5927\u4fde\u626c\u6559\u6388\uff1a\u4ec0\u4e48\u662fworld models/\u4e16\u754c\u6a21\u578b](https://mp.weixin.qq.com/s/UzC3J_TOzJPEx_86-lRwuw)\\n\\n[\u6df1\u5165\u6d45\u51faLangChain\u4e0e\u667a\u80fdAgent\uff1a\u6784\u5efa\u4e0b\u4e00\u4ee3AI\u52a9\u624b](https://mp.weixin.qq.com/s/Gi6pzD7wAMyzlCBSSWkVLA)\\n\\n[\u5c24\u6d0b\u6559\u6388\uff1a\u5f00\u6e90\u5b8c\u6574\u7684Sora\u590d\u73b0\u65b9\u6848\u6765\u4e86\uff01](https://mp.weixin.qq.com/s/T9YRVRGMgkwRSTl7Movadg)\\n\\n[\u300aT-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\u300b](https://mp.weixin.qq.com/s/8WYWrHyE4oryCgO9AemImA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"T-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\\"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86T-RAG\u6280\u672f\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06RAG\u67b6\u6784\u4e0e\u5fae\u8c03\u8bed\u8a00\u6a21\u578b\u548c\u5b9e\u4f53\u6811\u5411\u91cf\u6570\u636e\u5e93\u76f8\u7ed3\u5408\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u652f\u6301\u8bed\u5883\u68c0\u7d22\u3002\u5b83\u6982\u8ff0\u4e86\u5728\u654f\u611f\u6587\u6863\u7684\u80cc\u666f\u4e0b\u5982\u4f55\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u6709\u9650\u7684\u8ba1\u7b97\u8d44\u6e90\u548c\u57fa\u4e8e\u73b0\u6709\u6587\u6863\u5efa\u7acb\u7684\u5c0f\u578b\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u4fdd\u8bc1\u7528\u6237\u63d0\u95ee\u7684\u51c6\u786e\u56de\u7b54\u3002\u6587\u4e2d\u8fd8\u7740\u91cd\u4ecb\u7ecd\u4e86T-RAG\u7684\u5de5\u4f5c\u6d41\u7a0b\u548c\u5b9e\u4f53\u6811\u7684\u4f5c\u7528\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u51fa\u4e86\u4e00\u4e2a\u65b0\u7684\u8bc4\u4f30\u6307\u6807\u201cCorrect-Verbose\u201d\uff0c\u7528\u4ee5\u8bc4\u4ef7\u751f\u6210\u56de\u590d\u7684\u8d28\u91cf\u3002\u6b64\u7814\u7a76\u4e0d\u4ec5\u662f\u7406\u8bba\u7814\u7a76\uff0c\u4e5f\u662f\u5b9e\u8df5\u4e2dLLM\u5e94\u7528\u7684\u7ecf\u9a8c\u603b\u7ed3\uff0c\u5177\u6709\u5b9e\u9645\u7684\u6307\u5bfc\u610f\u4e49\u3002\\n\\n[\u300a\u9ad8\u7ea7 RAG\uff08Self-Reflective RAG\uff09\u300b](https://mp.weixin.qq.com/s/de3UxM9WTrHNjnOKSny0aw)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"\u9ad8\u7ea7 RAG(Self-Reflective RAG)\\"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86Self-Reflective RAG\u7684\u7406\u5ff5\u548c\u5de5\u4f5c\u6d41\u7a0b\u3002\u5728\u57fa\u672c\u7684RAG pipeline\u4e2d\uff0c\u6211\u4eec\u7684\u8fc7\u7a0b\u5f80\u5f80\u53d7\u9650\u4e8e\u88ab\u52a8\u7684\u68c0\u7d22\u548c\u751f\u6210\uff0c\u800c\u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u751f\u6210\u7684\u7ed3\u679c\u8fdb\u884c\u4f18\u5316\uff0c\u5982\u6539\u53d8\u95ee\u9898\u6216\u7b5b\u9009\u548c\u6392\u5217\u5185\u5bb9\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u81ea\u6211\u4fee\u6b63\u6846\u67b6\uff0c\u5305\u62ecCorrective RAG(CRAG)\u548cSelf-Reflective RAG\u3002\u8fd9\u4e24\u79cdRAG\u90fd\u56f4\u7ed5\u7740\u5bf9\u68c0\u7d22\u548c\u751f\u6210\u5185\u5bb9\u7684\u8bc4\u4f30\u548c\u53cd\u9988\u8fdb\u884c\u81ea\u6211\u4fee\u6b63\uff0c\u5e76\u901a\u8fc7\u7279\u5b9a\u6807\u8bc6\u8fdb\u884c\u8c03\u63a7\u3002\u5728\u4e00\u5b9a\u6761\u4ef6\u4e0b\uff0c\u8fdb\u4e00\u6b65\u6539\u8fdb\u4e86RAG\uff0c\u4f7f\u5176\u4ea7\u751f\u66f4\u597d\u7684\u68c0\u7d22\u548c\u751f\u6210\u6548\u679c\u3002\\n\\n[RAG\u4e0d\u591f\u806a\u660e\uff1f\u6253\u9020\u66f4\u5f3a\u5927\u7684\u667a\u80fd\u4f53](https://mp.weixin.qq.com/s/WuJEubctUDsAmdhHcDItAg)\\n\\n[Anthropic\u53d1\u5e03Claude3\uff0c\u6548\u679c\u5df2\u8d85\u8d8aGPT4](https://mp.weixin.qq.com/s/b_eWGauwi6v0w4CoSOnU5w)\\n\\n[\u4ece0\u5f00\u59cb\u9884\u8bad\u7ec31.4b\u4e2d\u6587\u5927\u6a21\u578b\u5b9e\u8df5](https://mp.weixin.qq.com/s/nMWTuKBnQVjgAM7Du6oOFQ)\\n\\n[\u300a\u5206\u7c7b\u7b97\u6cd5\u5165\u95e8:\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\u300b](https://mp.weixin.qq.com/s/W5W582CqxvRhF3wnKwIdiQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\uff0c\u5168\u9762\u800c\u8be6\u7ec6\u5730\u9610\u8ff0\u4e86\u673a\u5668\u5b66\u4e60\u4e2d\u7684\u5206\u7c7b\u7b97\u6cd5\u57fa\u7840\u77e5\u8bc6\u3002\u9996\u5148\u4ecb\u7ecd\u4e86\u4eba\u5de5\u667a\u80fd\u3001\u673a\u5668\u5b66\u4e60\u548c\u6df1\u5ea6\u5b66\u4e60\u7684\u57fa\u672c\u6982\u5ff5\uff0c\u8bb2\u89e3\u4e86\u673a\u5668\u5b66\u4e60\u5404\u79cd\u5206\u7c7b\u65b9\u6cd5\u7684\u7406\u8bba\u80cc\u666f\u3002\u968f\u540e\u901a\u8fc7\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528 Python \u5de5\u5177\uff08\u5305\u62ec pandas\u3001sklearn\u3001matplotlib \u548c seaborn\uff09\u8fdb\u884c\u6570\u636e\u5904\u7406\u3001\u5206\u6790\u548c\u53ef\u89c6\u5316\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u8ff0\u4e86\u51b3\u7b56\u6811\u3001\u903b\u8f91\u56de\u5f52\u3001\u652f\u6301\u5411\u91cf\u673a\u3001K\u8fd1\u90bb\u7b49\u7ecf\u5178\u7684\u5206\u7c7b\u7b97\u6cd5\uff0c\u5e76\u7528\u56fe\u5f62\u5316\u7684\u65b9\u5f0f\u5c55\u793a\u4e86\u5206\u7c7b\u6548\u679c\u3002\u6700\u540e\uff0c\u8bfb\u8005\u53ef\u4ee5\u901a\u8fc7\u672c\u6587\u6240\u63d0\u4f9b\u7684\u4e30\u5bcc\u5b66\u4e60\u8d44\u6599\u6765\u6df1\u5316\u5bf9\u673a\u5668\u5b66\u4e60\u5206\u7c7b\u4efb\u52a1\u7684\u7406\u89e3\u548c\u5e94\u7528\u3002\\n\\n[\u300a\u4e07\u5b57\u8be6\u89e3LLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\u300b](https://mp.weixin.qq.com/s/fkRG7n4tOQKwU85xiEx0Eg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"\u5199\u5728\u8de8\u5e74\u4e4b\u524d\uff1a\u804a\u804aLLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\\"\uff0c\u4e3b\u8981\u6d89\u53ca\u5230LLM Agents\u7684\u5f53\u524d\u72b6\u6001\uff0c\u9762\u4e34\u7684\u95ee\u9898\u548c\u672a\u6765\u7684\u53ef\u80fd\u53d1\u5c55\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5305\u62ec\u5168\u53c2\u5fae\u8c03\u3001Prompt Tuning\u3001LoRA\u3001P-Tuning\u7b49\u5728\u5185\u7684SFT(Selective Fine Tuning)\u8303\u7574\u7684\u5404\u79cd\u6280\u672f\u3002\u5176\u4e2d\u5c24\u5176\u5f3a\u8c03\u4e86\u5bf9\u4e8e{prompt\uff0cresponse}\u7684\u5355\u8f6e\u95ee\u7b54\u5bf9\u7684\u5fae\u8c03\u662f\u6700\u7b80\u5355\u7684SFT\u5b9e\u73b0\u65b9\u5f0f\u3002\u5177\u4f53\u7684\u5185\u5bb9\u7ec6\u8282\u5927\u6982\u9700\u8981\u9605\u8bfb\u539f\u6587\u624d\u80fd\u83b7\u5f97\u66f4\u6df1\u5165\u7684\u7406\u89e3\u3002\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u300aRobust generic functions on slices\u300b](https://go.dev/blog/generic-slice-functions)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"Robust generic functions on slices\\"\uff0c\u4e3b\u8981\u63a2\u8ba8\u4e86Go\u7684slices\u5305\u5982\u4f55\u63d0\u4f9b\u5bf9\u5207\u7247\u8fdb\u884c\u64cd\u4f5c\u7684\u901a\u7528\u51fd\u6570\u3002\u8be5\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u7c7b\u578b\u53c2\u6570\uff0c\u4e00\u6b21\u6027\u4e3a\u6240\u6709\u7c7b\u578b\u7684\u5207\u7247\u7f16\u5199\u7c7b\u4f3cslices.Index\u7b49\u51fd\u6570\uff0c\u800c\u65e0\u9700\u9488\u5bf9\u6bcf\u79cd\u4e0d\u540c\u7684\u5143\u7d20\u7c7b\u578b\u91cd\u65b0\u5b9e\u73b0\u3002\u968f\u540e\uff0c\u6587\u7ae0\u6df1\u5165\u8bb2\u8ff0\u4e86\u65b0\u7684\u51fd\u6570\uff08\u5982Insert, Replace\uff0cDelete\u7b49\uff09\u5982\u4f55\u4fee\u6539\u5207\u7247\uff0c\u5e76\u901a\u8fc7\u8be6\u8ff0\u5207\u7247\u5728\u5185\u5b58\u4e2d\u7684\u8868\u73b0\u5f62\u5f0f\u53ca\u5176\u5bf9\u5783\u573e\u56de\u6536\u5668\u7684\u5f71\u54cd\uff0c\u6765\u5e2e\u52a9\u8bfb\u8005\u7406\u89e3\u8fd9\u4e9b\u51fd\u6570\u7684\u5de5\u4f5c\u65b9\u5f0f\u548c\u6b63\u786e\u4f7f\u7528\u5b83\u4eec\u3002\u6587\u7ae0\u7279\u522b\u6307\u51fa\uff0c\u65b0\u7684Delete\u51fd\u6570\u63d0\u4f9b\u4e86\u66f4\u6e05\u6670\u5730\u8868\u8fbe\u7a0b\u5e8f\u5458\u610f\u56fe\u7684\u65b9\u5f0f\uff0c\u800c\u4e14\u5b83\u4e0d\u9700\u8981\u5206\u914d\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u6e05\u9664\u65e0\u7528\u7684\u5143\u7d20\uff0c\u5e2e\u52a9\u5783\u573e\u56de\u6536\u3002\u6587\u7ae0\u5f3a\u8c03\uff0c\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c\u5fc5\u987b\u8ba4\u4e3a\u539f\u59cb\u5207\u7247\u5df2\u65e0\u6548\uff0c\u56e0\u4e3a\u5e95\u5c42\u6570\u7ec4\u5df2\u88ab\u4fee\u6539\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u5728\u5904\u7406\u5185\u5b58\u6cc4\u6f0f\u548c\u5143\u7d20\u96f6\u503c\u8bbe\u7f6e\u7b49\u95ee\u9898\u65f6\u7684\u7b56\u7565\u548c\u9009\u9879\uff0c\u5b83\u4eec\u5728\u65b0\u7248\u672cGo\u7ed9\u51fa\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u6539\u53d8\u53ef\u80fd\u5bfc\u81f4\u7684\u4e00\u4e9b\u6d4b\u8bd5\u95ee\u9898\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9f13\u52b1\u5f00\u53d1\u4eba\u5458\u6b63\u786e\u4f7f\u7528\u65b0\u529f\u80fd\uff0c\u5e76\u5c3d\u91cf\u907f\u514d\u4e0a\u8ff0\u5217\u4e3e\u7684\u9677\u9631\u3002\\n\\n[\u300aRouting Enhancements for Go 1.22\u300b](https://go.dev/blog/routing-enhancements)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"Routing Enhancements for Go 1.22\\"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86 Go 1.22 \u7248\u672c\u4e2d net/http \u5305\u7684\u8def\u7531\u5668\u63d0\u4f9b\u7684\u65b0\u7279\u6027\uff1a\u65b9\u6cd5\u5339\u914d\u548c\u901a\u914d\u7b26\u3002\u8fd9\u4e9b\u65b0\u7279\u6027\u8ba9\u4f60\u53ef\u4ee5\u4f7f\u7528\u6a21\u5f0f\uff0c\u800c\u975e Go \u4ee3\u7801\uff0c\u6765\u8868\u8fbe\u5e38\u89c1\u7684\u8def\u7531\u3002\u8fd9\u79cd\u65b0\u529f\u80fd\uff0c\u5c3d\u7ba1\u7b80\u5355\u6613\u61c2\uff0c\u4f46\u8981\u9009\u62e9\u51fa\u591a\u4e2a\u5339\u914d\u8bf7\u6c42\u7684\u6700\u4f73\u6a21\u5f0f\u5374\u662f\u4e00\u9879\u6311\u6218\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u9610\u91ca\u4e86\u5982\u4f55\u5728\u65b0\u7248 Go \u4e2d\u4f7f\u7528\u8fd9\u4e9b\u65b0\u7279\u6027\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u5f15\u5165\u7684\u53d8\u5316\u5982\u4f55\u5f71\u54cd\u4e86 ServeMux \u65b9\u6cd5 handle \u548c handleFunc \u3002\u6b64\u5916\uff0c\u8fd8\u63cf\u8ff0\u4e86\u65b0\u6a21\u5f0f\u5982\u4f55\u66f4\u5177\u4f18\u5148\u7ea7\uff0c\u5e76\u89e3\u91ca\u4e86\u5176\u80cc\u540e\u7684\u539f\u7406\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u65b0\u65e7\u7248\u672c\u7684\u517c\u5bb9\u6027\uff0c\u4f5c\u8005\u4eec\u4e5f\u52aa\u529b\u4f7f\u65b0\u7684\u6a21\u5f0f\u8bed\u6cd5\u80fd\u8986\u76d6\u65e7\u7684\uff0c\u5e76\u4f7f\u65b0\u7684\u4f18\u5148\u7ea7\u89c4\u5219\u80fd\u6cdb\u5316\u65e7\u7684\u89c4\u5219\u3002\u603b\u4f53\u4e0a\uff0c\u8fd9\u4e9b\u6539\u53d8\u662f Go \u8bed\u8a00\u56e2\u961f\u4e0d\u65ad\u52aa\u529b\u4f7f Go \u6210\u4e3a\u6784\u5efa\u751f\u4ea7\u7cfb\u7edf\u7684\u4f18\u79c0\u8bed\u8a00\u7684\u4e00\u4e2a\u6301\u7eed\u8fc7\u7a0b\u7684\u4e00\u90e8\u5206\u3002\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(6)](https://mp.weixin.qq.com/s/IH1FGDpClrsnlfjg7OF3lg)\\n\\n[\u4f7f\u7528Apache Kafka\u7684Golang\u5b9e\u8df5\u6307\u5357](https://mp.weixin.qq.com/s/JCU3dwkwpMP3qMKqg9ed6g)\\n\\n[\u300aGo \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570\u300b](https://mp.weixin.qq.com/s/RFsHfFByarSRAA-f1Rs13g)\u3002\u8fd9\u7bc7\u7531\u714e\u9c7c\u64b0\u5199\u7684\u6587\u7ae0\uff0c\u9898\u4e3a \\"Go \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570?\\"\uff0c\u5bf9\u4e8e\u8fd9\u4e2a\u8bdd\u9898\u8fdb\u884c\u4e86\u6df1\u5ea6\u89e3\u6790\u3002\u5176\u9996\u5148\u63d0\u5230\uff0c\u867d\u7136Go\u7684\u89c4\u8303\u5e76\u6ca1\u6709\u660e\u786e\u7981\u6b62\u4ecemain\u5305\u4e2d\u5bfc\u5165\u51fd\u6570\uff0c\u4f46\u6211\u4eec\u5728\u5b9e\u9645\u8fd0\u884c\u4e2d\u4f1a\u88ab\u62d2\u7edd\uff0c\u63d0\u793amain\u5305\u662f\u4e00\u4e2a\u7a0b\u5e8f\u800c\u975e\u53ef\u4ee5\u5bfc\u5165\u7684\u5305\u3002\u8fd9\u4e00\u73b0\u8c61\u7684\u539f\u56e0\u6765\u81ea\u4e8e\u7ecf\u8fc7\u591a\u6b21\u53d8\u52a8\u7684\u89c4\u5b9a\uff0c\u59822011\u5e74\u79fb\u9664\u4e86 \\"\u7a0b\u5e8f\u4e2d\u7684\u5176\u4ed6\u5305\u90fd\u4e0d\u80fd\u547d\u540d\u4e3a main\\" \u7684\u8981\u6c42\uff0c\u7136\u540e\u57282015\u5e74\u53c8\u65b0\u589e\u4e86\u9650\u5236\u3002\u8fd9\u6837\u7684\u53d8\u5316\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u589e\u52a0\u590d\u6742\u5ea6\u548c\u4e0d\u5b89\u5168\u6027\u3002\u6bd4\u5982\uff0c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u505a\u51fa\u81ea\u5df1\u62e5\u6709\u5b8c\u5168\u63a7\u5236\u6743\u7684\u5047\u8bbe\uff0c\u6240\u4ee5\u5982\u679c\u5f15\u5165\u591a\u4e2amain\u5305\u4e2d\u7684\u51fd\u6570\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u5728\u521d\u59cb\u5316\u987a\u5e8f\u3001\u5168\u5c40\u53d8\u91cf\u7684\u6ce8\u518c\u7b49\u65b9\u9762\u7684\u51b2\u7a81\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba4\u4e3aGo\u5b98\u65b9\u7684\u505a\u6cd5\u5728\u7406\u8bba\u4e0a\u53ef\u4ee5\u89e3\u51b3\u590d\u6742\u5ea6\u548c\u5b89\u5168\u6027\u95ee\u9898\uff0c\u4f46\u5bf9\u4e8e\u6709\u5386\u53f2\u503a\u52a1\u7684\u9879\u76ee\uff0c\u5bf9\u4e8e\u9700\u8981\u7ef4\u62a4\u591a\u4e2aGo\u9879\u76ee\u5de5\u7a0b\uff0c\u76f8\u5f53\u4e8e\u78e8\u706d\u4e86\u4e00\u6761\u9053\u8def\uff0c\u5176\u5b9e\u6bd4\u8f83\u5c34\u5c2c\u3002\\n\\n[\u300afasthttp\u662f\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u300b](https://mp.weixin.qq.com/s/zxLO4IhLqQmIaUDzwwjU1w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8bb2\u89e3\u4e86fasthttp\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u539f\u7406\u3002fasthttp\u76f8\u6bd4\u4e8enet/http\u5728\u5904\u7406\u6d41\u7a0b\u4e0a\u6709\u6240\u5dee\u5f02\uff0cnet/http\u662f\u4e00\u4e2a\u8fde\u63a5\u65b0\u5efa\u4e00\u4e2agoroutine\uff0c\u5f53\u8fde\u63a5\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\u4f1a\u7ed9\u7cfb\u7edf\u5e26\u6765\u4e00\u5b9a\u7684\u538b\u529b\u3002\u800cfasthttp\u5219\u662f\u5efa\u7acb\u4e86workerPool\uff0c\u6bcf\u4e2aworkerChan\u5728\u540e\u53f0\u90fd\u4f1a\u6709\u4e00\u4e2aGoroutine\u6765\u5904\u7406\u5176\u4e2d\u7684\u8fde\u63a5\u3002\u6b64\u5916\uff0cfasthttp\u7684\u5feb\u901f\u4e5f\u5f97\u76ca\u4e8e\u51e0\u4e2a\u65b9\u9762\u7684\u4f18\u5316\uff1a\u8fde\u63a5\u590d\u7528\uff0c\u5927\u91cf\u4f7f\u7528\u4e86sync.Pool\u8fdb\u884c\u5185\u5b58\u590d\u7528\u4ee5\u53ca\u901a\u8fc7unsafe.Pointer\u6307\u9488\u8fdb\u884c\\\\[\\\\]byte\u548cstring\u8f6c\u6362\u6765\u907f\u514d\u5185\u5b58\u5206\u914d\u548c\u62f7\u8d1d\u7684\u6d88\u8017\u3002\\n\\n[\u300a\u4e07\u5b57\u957f\u6587\u8bb2\u89e3Golang pprof \u7684\u4f7f\u7528\u300b](https://mp.weixin.qq.com/s/fx-FTVpM3CXIPUwTC_juDQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86Golang\u7684pprof\u5de5\u5177\u7684\u4f7f\u7528\u3002pprof\u5de5\u5177\u662fGolang\u4e2d\u7528\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4e00\u4e2a\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u5206\u6790\u51facpu\u4f7f\u7528\u60c5\u51b5\u3001\u5185\u5b58\u5360\u7528\u3001\u963b\u585e\u60c5\u51b5\u3001\u7ebf\u7a0b\u548c\u534f\u7a0b\u7b49\u4fe1\u606f\u3002\u6587\u7ae0\u4e2d\u8be6\u7ec6\u9610\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528\u6b64\u5de5\u5177\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u901a\u8fc7http\u63a5\u53e3\u7684\u65b9\u5f0f\u66b4\u9732\u51fapprof\u7684\u91c7\u96c6\u63a7\u5236\u754c\u9762\uff0c\u53e6\u4e00\u79cd\u662f\u5728\u7a0b\u5e8f\u4e2d\u901a\u8fc7\u4ee3\u7801\u6765\u542f\u52a8\u76f8\u5e94\u6307\u6807\u7684\u91c7\u96c6\u793a\u4f8b\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u89e3\u6790\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u5f0f\u83b7\u53d6\u7684\u8f93\u51fa\u4fe1\u606f\u3002\u672c\u6587\u7684\u4e3b\u8981\u76ee\u7684\u662f\u5c06pprof\u5de5\u5177\u7684\u4f7f\u7528\u65b9\u5f0f\u7528\u601d\u7ef4\u5bfc\u56fe\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765\uff0c\u8fd9\u6837\u53ef\u4ee5\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u4f7f\u7528pprof\u5de5\u5177\u3002\\n\\n[\u300a\u4e00\u7bc7\u5b9e\u7528\u7684\u5173\u4e8e\u4e91\u4e0aK8s\u5e94\u7528\u5206\u8d26\u5b9e\u8df5\u300b](https://mp.weixin.qq.com/s/xYvMI0JieO6RxHIdWf1ujQ)\u3002\u672c\u6587\u8bb2\u8ff0\u4e91\u4e0aKubernetes\uff08K8s\uff09\u5e94\u7528\u7684\u6210\u672c\u5206\u644a\u5b9e\u8df5\uff0c\u6db5\u76d6\u4e86\u6210\u672c\u5206\u644a\u7684\u6838\u5fc3\u6982\u5ff5\u53ca\u963f\u91cc\u4e91ACK FinOps\u5957\u4ef6\u7684\u5e94\u7528\u3002\u6587\u4e2d\u9996\u5148\u4ee5\u524d\u671f\u9884\u7b97\u4e3a\u96c6\u7fa4\u89c4\u5212\u7684\u4f9d\u636e\uff0c\u5e76\u8ba8\u8bba\u4e86\u968f\u7740\u4e1a\u52a1\u53d1\u5c55\u5bf9\u6210\u672c\u5206\u644a\u7cbe\u51c6\u5ea6\u7684\u63d0\u5347\u9700\u6c42\u3002\u4ecb\u7ecd\u4e86\u5982\u4f55\u6839\u636ePod\u7684\u6838/\u65f6\u6210\u672c\uff0c\u901a\u8fc7ACK\u96c6\u7fa4\u3001\u8ba1\u7b97\u8282\u70b9\u3001\u547d\u540d\u7a7a\u95f4\u548c\u5e94\u7528Pod\u8fd9\u56db\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u8d39\u7528\u5206\u644a\u3002\u6587\u7ae0\u8fd8\u5206\u6790\u4e86\u5355\u8d44\u6e90\u548c\u6df7\u5408\u8d44\u6e90\u5206\u644a\u6a21\u578b\uff0c\u5e76\u8ba8\u8bba\u4e86\u5982\u4f55\u8bbe\u7f6eRequest\u548cLimit\u6765\u4f18\u5316\u8d44\u6e90\u5229\u7528\u3002\u5bf9\u4e8e\u591a\u4e91\u548c\u6df7\u5408\u4e91\u573a\u666f\uff0c\u5206\u4eab\u4e86\u5982\u4f55\u901a\u8fc7ACK One\u5b9e\u73b0\u7edf\u4e00\u7ba1\u7406\u548c\u6210\u672c\u5206\u6790\u3002\u9488\u5bf9\u590d\u6742\u4e1a\u52a1\u573a\u666f\uff0c\u8bb2\u8ff0\u4e86\u81ea\u5b9a\u4e49\u5b9a\u4ef7\u6a21\u7248\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u5141\u8bb8\u901a\u8fc7\u914d\u7f6e\u5b9e\u73b0\u6210\u672c\u5b9a\u5236\u9700\u6c42\u3002\u5bf9\u4e8e\u8ffd\u6c42\u7ec6\u8282\u7ba1\u7406\u548c\u7cbe\u7ec6\u5316\u8fd0\u8425\u7684\u56e2\u961f\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u6307\u5bfc\u3002\\n\\n[\u300a\u5982\u4f55\u4f7f\u7528 K8s \u4e24\u5927\u5229\u5668\\"\u5ba1\u8ba1\\"\u548c\\"\u4e8b\u4ef6\\"\u5e2e\u4f60\u6446\u8131\u8fd0\u7ef4\u56f0\u5883\u300b](https://mp.weixin.qq.com/s/6xx3-qow8A5Hdp_72jswow)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528 Kubernetes\uff08K8s\uff09\u7684\\"\u5ba1\u8ba1\\"\u548c\\"\u4e8b\u4ef6\\"\u529f\u80fd\u6765\u5e2e\u52a9\u8fdb\u884c\u65e5\u5e38\u96c6\u7fa4\u8fd0\u7ef4\u5de5\u4f5c\u3002\u6587\u7ae0\u9996\u5148\u6307\u51fa\u4e86\u8fd0\u7ef4\u5de5\u4f5c\u4e2d\u53ef\u80fd\u51fa\u73b0\u7684\u4e00\u4e9b\u95ee\u9898\uff0c\u4f8b\u5982\u5e94\u7528\u88ab\u5220\u9664\u3001Apiserver\u8d1f\u8f7d\u7a81\u53d8\u3001\u96c6\u7fa4\u8282\u70b9\u51fa\u73b0\u95ee\u9898\u3001\u8282\u70b9\u81ea\u52a8\u6269\u5bb9\u7b49\u3002\u968f\u540e\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u89e3\u91ca\u4e86 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\u662f\u5982\u4f55\u8fd0\u4f5c\u7684\uff0c\u5f3a\u8c03\u4e86\u5584\u7528\u8fd9\u4e24\u79cd\u5de5\u5177\u53ef\u4ee5\u63d0\u9ad8\u96c6\u7fa4\u7684\u53ef\u89c2\u5bdf\u6027\uff0c\u4e3a\u8fd0\u7ef4\u5de5\u4f5c\u5e26\u6765\u6781\u5927\u7684\u4fbf\u5229\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u901a\u8fc7\u4f7f\u7528 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u66f4\u597d\u5730\u7ba1\u7406\u548c\u76d1\u6d4b\u96c6\u7fa4\u7684\u72b6\u6001\u3002\\n\\n[\u3010Go \u5de5\u5177\u3011\u7ade\u6001\u6761\u4ef6\u68c0\u6d4b\u795e\u5668 Race Detector](https://mp.weixin.qq.com/s/lxEAFe2Ewmc8YvTqn8UcLQ)\\n\\n[\u4f7f\u7528Redis\u5165\u95e8Golang](https://mp.weixin.qq.com/s/Y67J4_D1yyMa-eb7XmgTcA)\\n\\n[\u4e00\u9053\u9762\u8bd5\u9898: Top K \u95ee\u9898](https://mp.weixin.qq.com/s/qDFM-nVo-jeh9VdcBfMreA)\\n\\n[\u300a\u7406\u89e3 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u300b](https://mp.weixin.qq.com/s/sTd3SVh0swGTnaGugsw1SA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u89e3\u6790\u4e86 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u3002\u9996\u5148\uff0c\u4f5c\u8005\u6982\u8ff0\u4e86\u7528\u6237\u540d\u3001\u7ec4\u540d\u3001\u7528\u6237ID\uff08UID\uff09\u548c\u7ec4ID\uff08GID\uff09\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e0e\u4e3b\u673a\u7cfb\u7edf\u4e4b\u95f4\u7684\u6620\u5c04\u5bf9\u4e8e\u6784\u5efa\u5b89\u5168\u7cfb\u7edf\u7684\u91cd\u8981\u6027\u3002\u968f\u540e\uff0c\u6587\u7ae0\u5206\u6790\u4e86uid/gid\u5728Linux\u7cfb\u7edf\u7684\u5b89\u5168\u6027\uff0c\u5f3a\u8c03\u4e86\u5355\u4e00\u5185\u6838\u6982\u5ff5\u4ee5\u53cauid/gid\u7684\u5206\u914d\u65b9\u5f0f\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u8fd0\u7528\u5b9e\u4f8b\u89e3\u91ca\u4e86Docker\u8fd0\u884c\u7684\u8fc7\u7a0b\u4ee5\u53ca\u5982\u4f55\u901a\u8fc7Dockerfile\u5b9a\u4e49\u548c\u542f\u52a8\u4e0d\u540c\u7528\u6237\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8bb2\u8ff0\u4e86\u5982\u4f55\u638c\u63a7\u548c\u63a7\u5236\u5bb9\u5668\u7684\u8bbf\u95ee\u6743\u9650\u3002\u5728\u9610\u8ff0\u4ee5\u4e0a\u5185\u5bb9\u7684\u540c\u65f6\uff0c\u6587\u7ae0\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u9645\u793a\u4f8b\u6765\u8bf4\u660e\u8fd9\u4e9b\u89c2\u70b9\u3002\\n\\n[\u300a\u5982\u4f55\u57fa\u4e8eDocker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u300b](https://mp.weixin.qq.com/s/yUuo1IjeXY78_5u4QpkuTA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u5c06Docker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u3002\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5229\u7528\u5f00\u6e90\u5de5\u5177Dedockify\u7684\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u5de5\u4f5c\u539f\u7406\u3002\u8be5\u5de5\u5177\u901a\u8fc7Python\u811a\u672c\uff0c\u5229\u7528\u5b58\u50a8\u5728\u6bcf\u4e2a\u955c\u50cf\u5c42\u65c1\u8fb9\u7684\u5143\u6570\u636e\uff0c\u9010\u6b65\u904d\u5386\u5c42\u7ea7\u6811\uff0c\u6536\u96c6\u4e0e\u6bcf\u4e2a\u5c42\u76f8\u5173\u8054\u7684\u547d\u4ee4\uff0c\u91cd\u5efa\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\u547d\u4ee4\u5e8f\u5217\uff0c\u4ece\u800c\u5f97\u5230\u8fd1\u4f3c\u7684Dockerfile\u3002\u4e0d\u8fc7\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bbf\u95ee\u6267\u884c\u539f\u59cbdocker build\u547d\u4ee4\u65f6\u5b58\u5728\u7684\u6784\u5efa\u4e0a\u4e0b\u6587\uff0c\u5982\u679c\u4f7f\u7528\u4e86COPY\u6216ADD\u6307\u4ee4\uff0c\u751f\u6210\u7684\u8f93\u51fa\u53ef\u80fd\u4e0d\u5b8c\u5168\u5339\u914d\u539f\u59cb\u7684Dockerfile\u3002\\n\\n[\u300a\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u300b](https://mp.weixin.qq.com/s/KkRWQyljuo86-XbBxEnGPA)\u3002\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u3002\u9996\u5148\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a\u901a\u7528\u7684Dockerfile\uff0c\u5e76\u6307\u51fa\u5176\u751f\u6210\u7684\u955c\u50cf\u5927\u5c0f\u8d85\u8fc7300MB\uff0c\u4e3b\u8981\u56e0\u4e3a\u5305\u542b\u4e86\u6240\u6709\u7684Golang\u5de5\u5177\u3002\u7136\u540e\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u591a\u9636\u6bb5\u6784\u5efa\u7684\u65b9\u6cd5\uff0c\u5b83\u80fd\u4ece\u4e0d\u540c\u7684\u57fa\u7840\u955c\u50cf\u6784\u5efa\uff0c\u6709\u9009\u62e9\u5730\u5c06\u6587\u4ef6\u4ece\u4e00\u4e2a\u9636\u6bb5\u4f20\u9012\u5230\u4e0b\u4e00\u4e2a\u9636\u6bb5\uff0c\u4ece\u800c\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u901a\u8fc7\u4e8c\u7ea7\u6784\u5efa\uff0c\u955c\u50cf\u5927\u5c0f\u5df2\u964d\u81f311.7MB\u3002\u6700\u540e\uff0c\u8fd8\u63a2\u8ba8\u4e86\u4f7f\u7528\u540d\u4e3ascratch\u7684\u7a7a\u767d\u955c\u50cf\u8fdb\u4e00\u6b65\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u7684\u53ef\u80fd\u6027\uff0c\u4f7f\u5f97\u955c\u50cf\u6700\u540e\u964d\u81f36.34MB\uff0c\u4f46\u4f5c\u8005\u5f3a\u8c03\u8fd9\u9700\u8981\u614e\u91cd\u8003\u8651\uff0c\u56e0\u4e3a\u6700\u540e\u751f\u6210\u7684\u955c\u50cf\u5c06\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u5de5\u5177\u3002\\n\\n[\u300ak8s \u5230\u5e95\u662f\u4ec0\u4e48\uff0c\u67b6\u6784\u662f\u600e\u4e48\u6837\u7684\u300b](https://mp.weixin.qq.com/s/dckA1ezcABndN5WSg1BOBA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86 Kubernetes\uff08K8s\uff09\u7684\u57fa\u672c\u6982\u5ff5\u3001\u67b6\u6784\u548c\u5de5\u4f5c\u539f\u7406\u3002Kubernetes\uff0c\u56e0\u5355\u8bcd\u8fc7\u957f\uff0c\u6211\u4eec\u901a\u5e38\u7b80\u5316\u4e3ak8s\u3002k8s \u662f\u4e00\u79cd\u5bb9\u5668\u7684\u534f\u8c03\u5de5\u5177\uff0c\u4f4d\u4e8e\u5e94\u7528\u670d\u52a1\u548c\u670d\u52a1\u5668\u4e4b\u95f4\uff0c\u80fd\u4ee5\u7b56\u7565\u7684\u65b9\u5f0f\u534f\u8c03\u548c\u7ba1\u7406\u591a\u4e2a\u5e94\u7528\u670d\u52a1\u3002\u901a\u8fc7\u4e00\u4e2a yaml \u6587\u4ef6\u7684\u914d\u7f6e\uff0c\u53ef\u4ee5\u5b9a\u4e49\u5e94\u7528\u7684\u90e8\u7f72\u987a\u5e8f\u7b49\u4fe1\u606f\uff0c\u81ea\u52a8\u90e8\u7f72\u5e94\u7528\u5230\u5404\u4e2a\u670d\u52a1\u5668\u4e0a\uff0c\u8fd8\u80fd\u8ba9\u5b83\u4eec\u5d29\u6e83\u540e\u81ea\u52a8\u91cd\u542f\uff0c\u53ef\u4ee5\u81ea\u52a8\u6269\u5bb9\u548c\u7f29\u5bb9\u3002Kubernetes \u7684\u670d\u52a1\u5668\u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u63a7\u5236\u5e73\u9762\u548c\u5de5\u4f5c\u8282\u70b9\uff0c\u524d\u8005\u8d1f\u8d23\u63a7\u5236\u548c\u7ba1\u7406\u5404\u4e2a\u8282\u70b9\uff0c\u540e\u8005\u5219\u8d1f\u8d23\u5b9e\u9645\u8fd0\u884c\u5404\u4e2a\u5e94\u7528\u670d\u52a1\u3002k8s \u7684\u547d\u4ee4\u884c\u5de5\u5177\u4e3a kubectl\uff0c\u7528\u4e8e\u6267\u884c\u5404\u7c7b\u64cd\u4f5c\u547d\u4ee4\u3002\\n\\n[\u300aGo \u6cdb\u578b\u6709\u6ca1\u6709\u53ef\u80fd\u5728\u540e\u671f\u6539\u4e3a `<>` \u5c16\u62ec\u53f7\u300b](https://mp.weixin.qq.com/s/vjmntyGwzURz_elg27vpXg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728\u5904\u7406\u6cdb\u578b\u65f6\uff0c\u4e3a\u4f55\u5e76\u6ca1\u6709\u91c7\u7528\u7c7b\u4f3cJava\u548cC++\u7684 `<>` \u5c16\u62ec\u53f7\u8868\u793a\u6cd5\uff0c\u800c\u662f\u9009\u62e9\u4e86\u4e2d\u62ec\u53f7 `[]`. \u9996\u5148\uff0c\u4f7f\u7528\u5c16\u62ec\u53f7\u53ef\u80fd\u5bfc\u81f4\u8bed\u4e49\u6df7\u6dc6\uff0c\u5982 `a, b := w < x, y > (z)` \u6b64\u53e5\uff0c\u5982\u679c\u4f7f\u7528\u5c16\u62ec\u53f7\uff0c\u7a0b\u5e8f\u53ef\u80fd\u5728\u7f16\u8bd1\u9636\u6bb5\u65e0\u6cd5\u786e\u5b9a\u8be5\u884c\u8868\u8fbe\u5f0f\u7684\u5177\u4f53\u542b\u4e49\u3002\u5176\u6b21\uff0c\u4f7f\u7528\u5706\u62ec\u53f7\u4e5f\u4f1a\u5bfc\u81f4\u540c\u6837\u7684\u95ee\u9898\uff0c\u6bd4\u5982 `func F(T any)(v T)(r1, r2 T)`, \u65e0\u6cd5\u5feb\u901f\u51c6\u786e\u5224\u65ad\u51fa\u53c2\u6570\u548c\u8fd4\u56de\u503c\u90e8\u5206\u3002\u6b64\u5916\uff0cGo\u5b98\u65b9\u4e5f\u4e0d\u5e0c\u671b\u4f7f\u7528\u975eASCII\u7684\u5b57\u7b26\u3002\u4f5c\u8005\u8fd8\u63d0\u5230\u793e\u533a\u4e2d\u5bf9Go\u7684\u5904\u7406\u65b9\u5f0f\u5b58\u5728\u4e00\u4e9b\u4e89\u8bae\uff0c\u90e8\u5206\u793e\u533a\u6210\u5458\u8ba4\u4e3a\u5982\u679c\u4f7f\u5f97\u7f16\u8bd1\u5668\u89e3\u91ca\u5c16\u62ec\u53f7\u4e0d\u518d\u56f0\u96be\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u8fd9\u79cd\u7b26\u53f7\u3002\u7136\u800c\uff0c\u603b\u7684\u6765\u8bf4\uff0c\u57fa\u4e8e\u5df2\u6709\u7684\u5b9e\u8df5\u548c\u89c4\u8303\uff0cGo\u8bed\u8a00\u5728\u672a\u6765\u53ef\u80fd\u4e5f\u4e0d\u4f1a\u6539\u53d8\u5176\u6cdb\u578b\u7684\u8868\u793a\u65b9\u5f0f\u3002\\n\\n[\u300aRust\u4e2dchannel\u7684\u4f7f\u7528\u300b](https://mp.weixin.qq.com/s/arI9sip-5JH9YSu45XJ83w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86Rust\u7f16\u7a0b\u8bed\u8a00\u4e2dChannel\u7684\u7528\u6cd5\u3002\u5176\u4e2d\uff0cChannel\u662fRust\u4e2d\u7528\u4e8e\u5728\u4e0d\u540c\u7ebf\u7a0b\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u901a\u4fe1\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u7ebf\u7a0b\u95f4\u7684\u6d88\u606f\u4f20\u9012\u3002\u6bcf\u4e2aChannel\u7531\u53d1\u9001\u7aef\u548c\u63a5\u6536\u7aef\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5176\u8bbe\u8ba1\u7406\u5ff5\u662f\u201c\u901a\u8fc7\u901a\u4fe1\u6765\u5171\u4eab\u5185\u5b58\uff0c\u800c\u975e\u901a\u8fc7\u5171\u4eab\u5185\u5b58\u6765\u901a\u4fe1\u201d\uff0c\u4ee5\u6b64\u907f\u514d\u4e86\u6570\u636e\u7ade\u4e89\u548c\u5171\u4eab\u5185\u5b58\u7684\u590d\u6742\u6027\u3002\u8be5\u6587\u7ae0\u8fdb\u4e00\u6b65\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5728Rust\u4e2d\u521b\u5efa\u548c\u4f7f\u7528Channel\uff0c\u5e76\u7ed9\u51fa\u4e86\u76f8\u5173\u4ee3\u7801\u793a\u4f8b\u3002\u6700\u540e\uff0c\u6587\u7ae0\u9610\u8ff0\u4e86\u591a\u79cdChannel\u6a21\u578b\uff0c\u5305\u62ecRust\u6807\u51c6\u5e93\u4e2d\u6240\u4f7f\u7528\u7684MPSC\uff08\u591a\u751f\u4ea7\u8005\uff0c\u5355\u6d88\u8d39\u8005\uff09\u6a21\u578b\u3002\\n\\n[K8s\u90e8\u7f72\u65b9\u5f0f\u5927\u5168\uff1a\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1\u6240\u6709\u6280\u5de7](https://juejin.cn/post/7272006755266002959)\\n\\n[k8s\u4ece\u5165\u95e8\u5230\u7cbe\u901a -- \u66f4\u9002\u5408\u4e2d\u56fd\u5b9d\u5b9d\u4f53\u8d28](https://juejin.cn/post/7301584578342289423)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u300a\u4e07\u5b57+33\u5f20\u56fe\u63a2\u79d8OpenFeign\u6838\u5fc3\u67b6\u6784\u539f\u7406\u300b](https://mp.weixin.qq.com/s/NABg5tGizHsmdXgUO6NeVw)\u3002\u672c\u7bc7\u6587\u7ae0\u6df1\u5165\u63a2\u8ba8\u4e86SpringCloud\u6838\u5fc3\u7ec4\u4ef6OpenFeign\u7684\u6838\u5fc3\u67b6\u6784\u539f\u7406\u3002\u6587\u7ae0\u5206\u4e3a\u56db\u4e2a\u90e8\u5206\uff0c\u9996\u5148\u89e3\u91ca\u539f\u59cbFeign\u7684\u4f7f\u7528\u548c\u57fa\u4e8eSpringCloud\u7684\u8fdb\u5316\u8fc7\u5386\u7a0b\uff1b\u7136\u540e\u8be6\u7ec6\u8bb2\u89e3\u4e86Feign\u5e95\u5c42\u5de5\u4f5c\u539f\u7406\uff0c\u4f9d\u8d56\u4e8eJDK\u52a8\u6001\u4ee3\u7406\u548c\u6838\u5fc3\u7ec4\u4ef6\u5982Contract\u3001Encoder\u3001Decoder\u7b49\uff1b\u63a5\u4e0b\u6765\u5206\u6790\u4e86SpringCloud\u662f\u5982\u4f55\u6574\u5408Feign\u7684\uff0c\u5e76\u4e14\u8ba8\u8bba\u4e86OpenFeign\u7684\u591a\u79cd\u914d\u7f6e\u65b9\u5f0f\u53ca\u5176\u4f18\u5148\u7ea7\uff1b\u6700\u540e\uff0c\u6587\u7ae0\u901a\u8fc7\u4e30\u5bcc\u7684\u56fe\u793a\u548c\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u53ef\u4ee5\u66f4\u597d\u5730\u7406\u89e3\u5e76\u8fd0\u7528\u8fd9\u4e00\u5de5\u5177\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4e8e\u7406\u89e3\u548c\u8fd0\u7528OpenFeign\u975e\u5e38\u6709\u5e2e\u52a9\uff0c\u65e0\u8bba\u662f\u5bf9\u4e8e\u521d\u5b66\u8005\u8fd8\u662f\u6709\u7ecf\u9a8c\u7684\u5f00\u53d1\u8005\u3002\\n\\n[\u300a\u4e09\u4e07\u5b57\u957f\u6587\uff1a\u5982\u4f55\u53bb\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u300b](https://mp.weixin.qq.com/s/1Qe29y3nrbi39Kpaspme7Q)\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4efd\u8be6\u5c3d\u7684\u6307\u5bfc\uff0c\u8bb2\u8ff0\u4e86\u5982\u4f55\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u3002\u6587\u4e2d\u9996\u5148\u5b9a\u4f4d\u4e86\u6280\u672f\u95ee\u9898\u7684\u8303\u56f4\uff0c\u786e\u5b9a\u9002\u7528\u4e8eJDK8\u81f3JDK11\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u7cfb\u7edf\u5316\u7684\u6392\u67e5\u539f\u5219\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u6b65\u6b65\u7684\u8bca\u65ad\u6d41\u7a0b\uff0c\u4ece\u57fa\u672c\u4fe1\u606f\u6536\u96c6\u3001\u5224\u65ad\u5185\u5b58\u589e\u957f\u539f\u56e0\uff0c\u5230\u5177\u4f53\u5206\u6790\u5185\u5b58\u95ee\u9898\u7684\u53ef\u80fd\u6765\u6e90\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u4e0d\u540c\u7684\u547d\u4ee4\u548c\u5de5\u5177\uff08\u5982jmap\u3001jstat\u3001Arthas\u7b49\uff09\u8fdb\u884c\u8be6\u7ec6\u7684\u5206\u6790\uff0c\u5e76\u6839\u636e\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff0c\u5411\u8bfb\u8005\u5c55\u793a\u4e86\u5982\u4f55\u786e\u5b9a\u662f\u5806\u5185\u5b58\u95ee\u9898\u8fd8\u662f\u5806\u5916\u5185\u5b58\u95ee\u9898\u3002\u603b\u4e4b\uff0c\u6587\u7ae0\u4e3a\u90a3\u4e9b\u9700\u8981\u6df1\u5165\u7406\u89e3\u548c\u5904\u7406JVM\u5185\u5b58\u95ee\u9898\u7684\u5f00\u53d1\u8005\u548c\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u77e5\u8bc6\u548c\u6280\u5de7\u3002\\n\\n[\u300a\u5982\u4f55\u907f\u514dMYSQL\u4e3b\u4ece\u5ef6\u8fdf\u5e26\u6765\u7684\u8bfb\u5199\u95ee\u9898\u300b](https://mp.weixin.qq.com/s/WLPo8s_M3AzxwB3o3ehY3w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u5904\u7406\u5728MySQL\u4e3b\u4ece\u90e8\u7f72\u67b6\u6784\u4e2d\u666e\u904d\u5b58\u5728\u7684\u4e3b\u4ece\u540c\u6b65\u5ef6\u8fdf\u95ee\u9898\uff0c\u4ee5\u4fdd\u6301\u8bfb\u5199\u64cd\u4f5c\u7684\u4e00\u81f4\u6027\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u4e3b\u4ece\u5ef6\u8fdf\u4ea7\u751f\u7684\u573a\u666f\u53ca\u5176\u5bf9\u8bfb\u5199\u5206\u79bb\u539f\u5219\u7684\u5f71\u54cd\u3002\u7136\u540e\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e86\u4e3b\u4ece\u590d\u5236\u7684\u539f\u7406\uff0c\u5e76\u63d0\u51fa\u4e86\u4e24\u79cd\u907f\u514d\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u6280\u672f\u65b9\u6848\uff1a\u4e00\u662f\u4f7f\u7528select master_pos_wait\u51fd\u6570\u6765\u7b49\u5f85\u4ece\u5e93\u540c\u6b65\u81f3\u7279\u5b9a\u7684binlog\u4f4d\u7f6e\u70b9\uff1b\u4e8c\u662f\u5728\u5f00\u542fGTID\u6a21\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7select wait_for_executed_gtid_set\u51fd\u6570\u68c0\u67e5GTID\u96c6\u5408\u662f\u5426\u5df2\u540c\u6b65\u3002\u8fd9\u4e24\u79cd\u65b9\u6cd5\u5747\u65e8\u5728\u786e\u4fdd\u4ece\u5e93\u6570\u636e\u7684\u51c6\u786e\u6027\uff0c\u4ece\u800c\u6574\u4f53\u4e0a\u51cf\u8f7b\u4e3b\u5e93\u7684\u538b\u529b\u3002\u603b\u4f53\u4e0a\uff0c\u6587\u7ae0\u4e3aMySQL\u6570\u636e\u5e93\u7ba1\u7406\u5458\u63d0\u4f9b\u4e86\u7f13\u89e3\u4e3b\u4ece\u5ef6\u8fdf\u5bfc\u81f4\u7684\u8bfb\u5199\u95ee\u9898\u7684\u5177\u4f53\u5b9e\u65bd\u65b9\u6848\u3002\\n\\n[\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014ES\u7bc7\u300b](https://mp.weixin.qq.com/s/dt_14etV_2ynAmyMa_uyug)\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u7bc7\u9488\u5bf9Elasticsearch(ES)\u7684\u9762\u8bd5\u6307\u5357\uff0c\u5b83\u6db5\u76d6ES\u57fa\u7840\u77e5\u8bc6\u70b9\u548c\u9762\u8bd5\u8fc7\u7a0b\u4e2d\u5e38\u89c1\u95ee\u9898\u3002\u5185\u5bb9\u5305\u62ecES\u7684\u529f\u80fd\u7279\u6027\u4ecb\u7ecd\uff08\u5982\u5206\u5e03\u5f0f\u67b6\u6784\u3001\u5168\u6587\u641c\u7d22\u3001\u6570\u636e\u5206\u6790\u7b49\uff09\u3001\u4e3b\u8981\u7684\u4f7f\u7528\u573a\u666f\u63cf\u8ff0\u3001\u4e0e\u5176\u4ed6\u641c\u7d22\u5f15\u64ce\u7684\u5bf9\u6bd4\uff08Lucene\u548cSolr\uff09\u3001\u4ee5\u53caES\u7684\u57fa\u672c\u6982\u5ff5\u89e3\u91ca\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u63a2\u8ba8\u4e86ES\u7684\u9ad8\u7ea7\u7279\u6027\uff0c\u5982\u6620\u5c04\u3001DSL\u67e5\u8be2\u3001\u805a\u5408\u5206\u6790\u548c\u667a\u80fd\u641c\u7d22\u5efa\u8bae\u5668\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u8fd8\u5206\u4eab\u4e86\u5173\u4e8e\u6570\u636e\u7d22\u5f15\u4f18\u5316\u7684\u5b9e\u6218\u6280\u5de7\u548c\u7b56\u7565\uff0c\u63d0\u4f9b\u4e86\u5199\u4f18\u5316\u3001\u8bfb\u4f18\u5316\u548c\u7d22\u5f15\u91cd\u5efa\u7684\u65b9\u6848\uff0c\u8fd9\u4e9b\u65b9\u6848\u5bf9ES\u6570\u636e\u5b58\u50a8\u548c\u67e5\u8be2\u7684\u6027\u80fd\u6709\u663e\u8457\u5f71\u54cd\uff0c\u6700\u540e\u8fd8\u5bf9Deep Paging\u6027\u80fd\u95ee\u9898\u63d0\u4f9b\u4e86\u89e3\u51b3\u65b9\u6cd5\u3002\u5bf9\u6b63\u5728\u51c6\u5907\u9762\u8bd5\u6216\u8005\u5e0c\u671b\u5de9\u56faES\u77e5\u8bc6\u7684\u8bfb\u8005\u800c\u8a00\uff0c\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4e2a\u5b9d\u8d35\u7684\u8d44\u6e90\u3002\\n\\n[\u300a\u4ec0\u4e48\u662fMySQL\u9501\uff1f\u6709\u54ea\u4e9b\u9501\u7c7b\u578b\u300b](https://mp.weixin.qq.com/s/gAJFm3q5510PfRBe4F11PQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5730\u4ecb\u7ecd\u4e86MySQL\u4e2d\u7684\u9501\u5b9a\u673a\u5236\u53ca\u5176\u7c7b\u578b\u3002\u8d77\u521d\u6982\u8ff0\u4e86\u9501\u7684\u4f5c\u7528\uff0c\u5373\u534f\u8c03\u591a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u8d44\u6e90\u7684\u5e76\u53d1\u8bbf\u95ee\uff0c\u5728\u6570\u636e\u5e93\u73af\u5883\u4e0b\uff0c\u9501\u5bf9\u4e8e\u4fdd\u6301\u4e8b\u52a1\u7684\u6b63\u786e\u6027\u4e0e\u4e00\u81f4\u6027\u81f3\u5173\u91cd\u8981\u3002\u4f5c\u8005\u660e\u786e\u533a\u5206\u4e86MySQL\u4e2d\u9501\u7684\u7ea7\u522b\uff0c\u4ece\u5168\u5c40\u9501\u3001\u8868\u9501\uff08\u8bfb\u9501\u3001\u5199\u9501\uff09\u5230\u5143\u6570\u636e\u9501\u3001\u610f\u5411\u9501\uff0c\u76f4\u5230\u884c\u9501\u7684\u591a\u79cd\u5f62\u5f0f\uff08\u8bb0\u5f55\u9501\u3001\u95f4\u9699\u9501\u548c\u4e34\u952e\u9501\uff09\u3002\u6587\u4e2d\u8fd8\u63a2\u8ba8\u4e86AUTO-INC\u9501\u7684\u4f5c\u7528\u548c\u76f8\u5173\u4f18\u5316\uff0c\u4e3e\u4f8b\u8bf4\u660e\u4e86\u5176\u5728INSERT\u64cd\u4f5c\u4e2d\u7684\u5e94\u7528\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u4e5f\u6d89\u53ca\u4e86\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u60c5\u51b5\u4f18\u5316\u9501\u7684\u4f7f\u7528\u4ee5\u53ca\u5982\u4f55\u907f\u514d\u7531\u9501\u4ea7\u751f\u7684\u6027\u80fd\u74f6\u9888\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u7406\u89e3MySQL\u7684\u5404\u79cd\u9501\u7c7b\u578b\u548c\u9501\u673a\u5236\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u4fe1\u606f\uff0c\u7279\u522b\u5bf9\u4e8e\u6570\u636e\u5e93\u7ba1\u7406\u5458\u548c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5e76\u53d1\u6570\u636e\u8bbf\u95ee\u95ee\u9898\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u5b9e\u7528\u4ef7\u503c\u3002\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[Vue \u56e2\u961f\u6b63\u5f0f\u5f00\u6e90 Rolldown\uff1a\u57fa\u4e8e Rust \u7684\u8d85\u5feb JavaScrip \u6253\u5305\u5de5\u5177\uff01](https://mp.weixin.qq.com/s/m-Ae6dbFuW22u2xSDWcciw)\\n\\n[\u6253\u9020\u8212\u9002\u7684vscode\u5f00\u53d1\u73af\u5883](https://mp.weixin.qq.com/s/MVR5rV2LkH8_GHCtP6SHug)\\n\\n[\u76f8\u6bd4\u4e8e Node.js\uff0cDeno \u548c Bun \u5230\u5e95\u80fd\u5e26\u6765\u4ec0\u4e48](https://mp.weixin.qq.com/s/pY4-RqqamTmPXnRPfw0hRA)\\n\\n[MDH Weekly 122 - \u300a\u62db\u4eba\u300b](https://mp.weixin.qq.com/s/yBTK4Rds28aJ88mVgkoYJA)"},{"id":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-03/index.md","source":"@site/blogs/2024/2024-03-03/index.md","title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-03-03T00:00:00.000Z","formattedDate":"March 3, 2024","tags":[],"readingTime":3.63,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1a\u7528 switch-case \u6765\u89e3\u51b3 Go \u9519\u8bef\u5904\u7406\u7684\u96be\u9898\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[LangChain \u5b9e\u6218\uff1aAgent\u601d\u7ef4](https://mp.weixin.qq.com/s/II_6lb9KjKOmz-DIgnaz7g)\\n\\n[\u8be6\u89e3\u5927\u6a21\u578bRLHF\u8fc7\u7a0b\uff08\u914d\u4ee3\u7801\u89e3\u8bfb\uff09](https://mp.weixin.qq.com/s/tl32MrTPMi0i7BN53ELb2w)\\n\\n[PromptFlow\u9ad8\u8d28\u91cfAI\u5e94\u7528 - \u57fa\u4e8eLLM\u7684\u6587\u6863QA\u673a\u5668\u4eba](https://mp.weixin.qq.com/s/J8yEbS-XTJY0aFyJAl1ypA)\\n\\n[\u56fe\u89e3\u5927\u6a21\u578b\u8ba1\u7b97\u52a0\u901f\u7cfb\u5217\uff1aFlash Attention V1\uff0c\u4ece\u786c\u4ef6\u5230\u8ba1\u7b97\u903b\u8f91](https://mp.weixin.qq.com/s/gPVwXysJsV2S2FgP3c6Qpw)\\n\\n[\u4f7f\u7528\u642d\u8f7d\u9a81\u9f99 8 Gen 3 \u7684\u5b89\u5353\u624b\u673a\u8fd0\u884c AI \u5927\u6a21\u578b](https://mp.weixin.qq.com/s/yfou0pEkbbUZxe2NS1jnag)\\n\\n[\u751f\u6210\u5f0f AI \u7684\u53d1\u5c55\u65b9\u5411\uff0c\u662f Chat \u8fd8\u662f Agent](https://mp.weixin.qq.com/s/ws3U1NBouPivqatUb_ldQA)\\n\\n[\u804a\u804a\u5927\u6a21\u578bAgent\u6280\u672f\uff0c\u53ca\u548c\u5177\u8eab\u667a\u80fd\u53c8\u6709\u4ec0\u4e48\u5f02\u540c](https://mp.weixin.qq.com/s/U1IqQElxkfHfQoxygMnSOg)\\n\\n[\u590d\u65e6NLP\u56e2\u961f\u53d1\u5e0380\u9875\u5927\u6a21\u578bAgent\u7efc\u8ff0\uff0c\u4e00\u6587\u7eb5\u89c8AI\u667a\u80fd\u4f53\u7684\u73b0\u72b6\u4e0e\u672a\u6765](https://mp.weixin.qq.com/s/eWlms4IxTd4wzka4V7Gu6w)\\n\\n[\u77e5\u8bc6\u95ee\u7b54\u7cfb\u7edf\u7684\u4f18\u5316\u5b9e\u8df5\uff1aLLM\u4e0eRAG\u7684\u7ed3\u5408\u827a\u672f](https://mp.weixin.qq.com/s/cZB90npCcz88IJ6W00LnMA)\\n\\n[\u4e00\u6587\u89e3\u6784\u5927\u6a21\u578bRAG\u95ee\u7b54\u5173\u952e\u73af\u8282\u53ca\u4e0eLLM\u5fae\u8c03\u5bf9\u6bd4\u603b\u7ed3](https://mp.weixin.qq.com/s/xxFcMRMl--HPcGAkAYaW7w)\\n\\n[Mistral AI\u53d1\u5e03Mistral Large\u6a21\u578b](https://mp.weixin.qq.com/s/K0yFNjpcBk5OL-1DRHSeGA)\\n\\n[Mistral AI\u65b0\u6a21\u578b\u5bf9\u6807GPT-4\uff0c\u4e0d\u5f00\u6e90\u4e14\u4e0e\u5fae\u8f6f\u5408\u4f5c\uff0c\u7f51\u53cb\uff1a\u5fd8\u4e86\u521d\u5fc3](https://mp.weixin.qq.com/s/rvIJLIEvvzQ5n8v7ZF6pWw)\\n\\n[\u5927\u6a21\u578b\u5fae\u8c03\u65b0\u8303\u5f0f\uff1a\u5f53LoRA\u9047\u89c1MoE](https://mp.weixin.qq.com/s/gTFVNbWRsxONnoE_fq2S3A)\\n\\n[Mistral Large\uff0cLe Chat\u6765\u4e86\uff01Mistral AI\u8fde\u653e\u4e24\u4e2a\u5927\u62db\uff01](https://mp.weixin.qq.com/s/P5XktjiRgY2Q6V1pLyqYAw)\\n\\n[\u63a2\u7d222024\u5e741\u6708\u7684AI\u7814\u7a76\u524d\u6cbf\uff1a\u6a21\u578b\u5408\u5e76\u3001\u4e13\u5bb6\u6df7\u5408\u4e0e\u5c0f\u578bLLM\u7684\u5d1b\u8d77](https://mp.weixin.qq.com/s/1zc4klUCCsgeFDaA5K2Rgg)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[Cargo\u7684\u81ea\u5b9a\u4e49\u547d\u4ee4\u6269\u5c55\u529f\u80fd](https://mp.weixin.qq.com/s/PCFDz_fVsk_6M144VpBAww)\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(2)](https://mp.weixin.qq.com/s/CXnLIoYhI1k3SNP3IWz8dQ)\\n\\n[\u5143\u8001\u4e0e\u65b0\u79c0\uff1aGo sort.Search()\u548csort.Find()](https://mp.weixin.qq.com/s/vg8MfMBEs8I-FQl3Nuay6Q)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(6)-Connector](https://mp.weixin.qq.com/s/oM8JS_eMQjeU2tJzfO7f5w)\\n\\n[\u8df3\u69fd\u5fc5\u770b\u306eMySQL\u7d22\u5f15\uff1aB+\u6811\u539f\u7406\u63ed\u79d8\u4e0e\u7d22\u5f15\u4f18\u7f3a\u70b9\u5206\u6790](https://mp.weixin.qq.com/s/1DuY0WXZ_GsG87Ahuk_9rw)\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(1)](https://mp.weixin.qq.com/s/QfE-dnHlIv49ae205RrJ_Q)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(5)](https://mp.weixin.qq.com/s/xVBT-E3IiYsiOtHF2V22Xw)\\n\\n[\u7528 switch-case \u6765\u89e3\u51b3 Go \u9519\u8bef\u5904\u7406\u7684\u96be\u9898](https://mp.weixin.qq.com/s/MkWxrN_kQFNn9rMeJXs3PA)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(4)](https://mp.weixin.qq.com/s/7C7Jxe7XEN-vQKiY2MJMtw)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(3)](https://mp.weixin.qq.com/s/SHLh2ofDUteQCafXZo8mmw)\\n\\n[\u56fe\u6587\u8bb2\u900fGolang\u6807\u51c6\u5e93 net/http\u5b9e\u73b0\u539f\u7406 -- \u5ba2\u6237\u7aef](https://mp.weixin.qq.com/s/WoUYmpvYH6ixYSDwFga59g)\\n\\n[\u4f7f\u7528docker init\u7f16\u5199Dockerfile\u548cdocker-compose\u914d\u7f6e](https://mp.weixin.qq.com/s/TqAQ9kP4HlFN9UdLq0tavQ)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#\u5b8c\u7ed3\u6492\u82b1](https://mp.weixin.qq.com/s/tqAcoskLYd2UV6B_6AeIjw)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(2)](https://mp.weixin.qq.com/s/9Pg8blMjqECaCY_W9MbYHg)\\n\\n[golang \u9ad8\u6027\u80fd\u65e0 GC \u7684\u7f13\u5b58\u5e93 bigcache \u662f\u600e\u4e48\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/4ufuA3n9aaFcQ9zDItUHaQ)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u4ece0\u52301\u6784\u5efa\u4e00\u4e2a\u7a33\u5b9a\u3001\u9ad8\u6027\u80fdRedis\u96c6\u7fa4](https://mp.weixin.qq.com/s/5BwWCekb_wIu6LrCdmoGCQ)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014SpringCloud\u7bc7](https://mp.weixin.qq.com/s/KetCuZNb9jR0HSY7Jqh0NA)\\n\\n[\u5982\u4f55\u8bbe\u8ba1\u8ba2\u5355\u8d85\u65f6\u81ea\u52a8\u53d6\u6d88](https://mp.weixin.qq.com/s/hCZanLARApXcW2_6r3g-5A)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[2024 AI & \u524d\u7aef\uff1a\u56de\u9996\u5c55\u671b\uff0c\u5149\u8292\u672a\u81f3\uff0c\u7834\u6653\u4e4b\u524d\uff01](https://mp.weixin.qq.com/s/H9_kt3L6l6fj0aBP9UonhA)\\n\\n[\u770b\u5b8czustand\u6e90\u7801\u540e\uff0c\u6211\u7684TypeScript\u6c34\u5e73\u7a81\u98de\u731b\u8fdb](https://mp.weixin.qq.com/s/kZOpaaIfogWzeB7KwdTkRw)\\n\\n[ElTable \u4e8c\u6b21\u5c01\u88c5\uff1a\u6211\u7528 Vue3.3 \u65b0\u7279\u6027\u5b8c\u7f8e\u89e3\u51b3\u4e86\u5217\u63d2\u69fd\u6570\u636e\u65e0\u7c7b\u578b\u63d0\u793a\u95ee\u9898\uff01\uff01\uff01](https://mp.weixin.qq.com/s/Q1vvgM_A7QEtO-0a3GLUsw)\\n\\n[ECharts \u8fce\u6765\u91cd\u5927\u66f4\u65b0\uff0c\u8fd0\u884c\u65f6\u5305\u4f53\u79ef\u53ef\u51cf\u5c11 98%\uff01](https://mp.weixin.qq.com/s/WgtUG0vp3fk0_388svrGXg)\\n\\n[FFmpeg\u524d\u7aef\u89c6\u9891\u5408\u6210\u5b9e\u8df5](https://mp.weixin.qq.com/s/1XmH55nqs7wavsWJNT-tSw)\\n\\n[2024 \u4f7f\u7528 TS \u642d\u5efa Node.js \u670d\u52a1\u5668 - \u5feb\u901f\u6559\u7a0b](https://mp.weixin.qq.com/s/8D6yD3A5-KPod85zsxRPZQ)\\n\\n[\u524d\u7aef\u98df\u5802\u6280\u672f\u5468\u520a\u7b2c 113 \u671f\uff1aNode \u5e74\u7ec8\u603b\u7ed3\u3001Node \u65b0\u5409\u7965\u7269\u3001Qwik 2.0\u3001React Labs \u5de5\u4f5c\u8fdb\u5c55](https://mp.weixin.qq.com/s/udt61U0aaoFJqnzFKhGTjw)"},{"id":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-25/index.md","source":"@site/blogs/2024/2024-02-25/index.md","title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-02-25T00:00:00.000Z","formattedDate":"February 25, 2024","tags":[],"readingTime":5.4,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[Large Language Models for Data Annotation: A Survey](https://arxiv.org/pdf/2402.13446)\\n\\n[ACTIVERAG: Revealing the Treasures of Knowledge via Active Learning](https://arxiv.org/pdf/2402.13547.pdf)\\n\\n[\u5173\u4e8eGenerative-Diffusion-Model\u7684\u5168\u9762\u7efc\u8ff0\uff0c\u53ef\u4ee5\u4f5c\u4e3a\u4e86\u89e3sora\u7684\u57fa\u7840\u77e5\u8bc6](https://arxiv.org/pdf/2209.02646.pdf\uff0chttps://github.com/chq1155/A-Survey-on-Generative-Diffusion-Model?tab=readme-ov-file)\\n\\n[\u4e91\u97f3\u4e50 CMS \u5e73\u53f0 AIGC \u5b9e\u8df5\u4e0e\u65b0\u7279\u6027\u5b9e\u73b0\u603b\u7ed3](https://mp.weixin.qq.com/s/f2A6r5dVSBwDO_h27dlj6A)\\n\\n[\u4e91\u97f3\u4e50D2C\u8bbe\u8ba1\u7a3f\u8f6c\u4ee3\u7801\u5efa\u8bbe\u5b9e\u8df5](https://mp.weixin.qq.com/s/Oc1f3thZYIONsF4OWWEcSw)\\n\\n[\u4e91\u97f3\u4e50 AI Agent \u63a2\u7d22\u5b9e\u8df5](https://mp.weixin.qq.com/s/2O5z9rAvLxU3ZsU7k4xdhA)\\n\\n[\u4e91\u97f3\u4e50\u4f4e\u4ee3\u7801 + ChatGPT \u5b9e\u8df5\u65b9\u6848\u4e0e\u601d\u8003](https://mp.weixin.qq.com/s/jaIiVI636uJBOOKsXuHCpw)\\n\\n[\ud83e\udd9c\ud83d\udd78\ufe0f LangGraph\uff1aPlan-Execute Agents \u5b9e\u6218](https://www.bilibili.com/video/BV1vJ4m1s7Zn)\\n\\n[Pinecone\u603b\u7ed3\u4e00\uff1a\u5927\u6a21\u578b\u89d2\u5ea6](https://mp.weixin.qq.com/s/G1DYQiAjUL9zphJ8ajrrtg)\\n\\n[\u4f7f\u7528 Hugging Face \u5fae\u8c03 Gemma \u6a21\u578b](https://mp.weixin.qq.com/s/N6RI456ouuczWjyqXOSPNQ)\\n\\n[\u5f00\u6e90\u5927\u8bed\u8a00\u6a21\u578b\u4f5c\u4e3a LangChain \u667a\u80fd\u4f53](https://mp.weixin.qq.com/s/fsvgtS3stS1cfrIT78XBCA)\\n\\n[200\u4e07\u4e0a\u4e0b\u6587\u7a97\u53e3\u521b\u98deGemini 1.5\uff01\u5fae\u8f6f\u6765\u7838\u8c37\u6b4c\u573a\u5b50\u4e86\uff08doge\uff09](https://mp.weixin.qq.com/s/tJj0ZCX8fRS2Xcr0v85C8g)\\n\\n[\u5982\u4f55\u5229\u7528\u5927\u6a21\u578b\u8fdb\u884c\u6570\u636e\u6807\u6ce8\u4e0e\u77e5\u8bc6\u84b8\u998f\uff1a\u517c\u770bActiveRAG\u4e0a\u4e0b\u6587\u53bb\u566a\u7684\u5927\u6a21\u578bRAG\u95ee\u7b54\u8303\u5f0f](https://mp.weixin.qq.com/s/idr60a1a66gdGFSZrOnC0w)\\n\\n[\u6811\u5f62\u7ed3\u6784\u4e0eRAG\u7684\u5b8c\u7f8e\u7ed3\u5408\uff1aT-RAG\u65b9\u6cd5\u5728\u7ec4\u7ec7\u5185\u90e8\u4fe1\u606f\u67e5\u8be2\u4e2d\u7684\u7a81\u7834](https://mp.weixin.qq.com/s/NNkVs_TnaStvjWdmfrM88Q)\\n\\n[\u9886\u514899%\u5c0f\u767d\u7684Sora\u5173\u952e\u4fe1\u606f\uff01](https://mp.weixin.qq.com/s/MsaCUnTsJYxJFgnNGT6DTA)\\n\\n[AI, Machine Learning\u548c Deep Learning\u6709\u4ec0\u4e48\u5dee\u5f02](https://mp.weixin.qq.com/s/Js9YAibVSeVwfy4-xESDRg)\\n\\n[\u6a21\u578b\u878d\u5408\u3001\u6df7\u5408\u4e13\u5bb6\u3001\u66f4\u5c0f\u7684LLM\uff0c\u51e0\u7bc7\u8bba\u6587\u770b\u61c22024\u5e74LLM\u53d1\u5c55\u65b9\u5411](https://mp.weixin.qq.com/s/qImKOQXLoZqLTW-SVISKHA)\\n\\n[\u5f00\u6e90\u5927\u6a21\u578b\u738b\u5ea7\u6613\u4e3b\uff01\u8c37\u6b4cGemma\u6740\u5165\u573a\uff0c\u7b14\u8bb0\u672c\u53ef\u8dd1\uff0c\u53ef\u5546\u7528](https://mp.weixin.qq.com/s/_iCYfqmXA3enKn3Hm-DwSA)\\n\\n[\u5173\u4e8eGoogle\u5f00\u6e90Gemma\u7684\u4e00\u4e9b\u60f3\u6cd5](https://mp.weixin.qq.com/s/H2ie4vuhLqr4UKtgvZZtEQ)\\n\\n[LangChain\u539f\u7406\u5b66\u4e60\u7b14\u8bb0](https://mp.weixin.qq.com/s/0xzCAqiXOsscBItpN9R0lA)\\n\\n[\u5de5\u5177\u589e\u5f3a\u578b\u5927\u6a21\u578b\uff1a\u5f15\u9886\u667a\u80fd\u65b0\u65f6\u4ee3](https://mp.weixin.qq.com/s/gHyMnVxh-QVe58TvZMvl8Q)\\n\\n[AI \u5b9e\u6218\uff1a\u624b\u628a\u624b\u6559\u4f60\u4f7f\u7528\u300c\u6263\u5b50/coze\u300d\u6765\u642d\u5efa\u4e2a\u4ebablog\u77e5\u8bc6\u5e93](https://mp.weixin.qq.com/s/YAGfwy5fUHbTW5f3bUSYVg)\\n\\n[\u5927\u6a21\u578b\u63a8\u7406\u4f18\u5316\u5b9e\u8df5\uff1aKV cache\u590d\u7528\u4e0e\u6295\u673a\u91c7\u6837](https://mp.weixin.qq.com/s/W9iVW7niyi_HvEWxOcnwuA)\\n\\n[NLP\u7814\u7a76\u5728\u5927\u6a21\u578b\u65f6\u4ee3\u7684\u521b\u65b0\u98de\u8dc3](https://mp.weixin.qq.com/s/06w7_lb8Hc4Ee2GG9I4wLg)\\n\\n[\u4e0b\u4e00\u4ee3RAG\u8303\u5f0f\uff1aRAG-Fusion](https://mp.weixin.qq.com/s/delaJc2KDxLWfUUtGo-V-A)\\n\\n[\u56fe\u89e3\u5927\u6a21\u578b\u8ba1\u7b97\u52a0\u901f\u7cfb\u5217\uff1aFlash Attention V2\uff0c\u4ece\u539f\u7406\u5230\u5e76\u884c\u8ba1\u7b97](https://mp.weixin.qq.com/s/5K6yNj23NmNLcAQofHcT4Q)\\n\\n[\u5982\u4f55\u5728\u5c0f\u516c\u53f8\u505a\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/yr_VAbEIresEH352Iyehjg)\\n\\n[\u673a\u5668\u5b66\u4e60\u7b80\u4ecb: \u5bfb\u627e\u51fd\u6570\u7684\u827a\u672f](https://mp.weixin.qq.com/s/j52XdHyD5w_Ug-hpWlPIgQ)\\n\\n[OpenAl \u89c6\u9891\u751f\u6210\u6a21\u578b \u2014\u2014 Sora\u6280\u672f\u62a5\u544a\u89e3\u8bfb](https://mp.weixin.qq.com/s/3reFjJNHuL8J24EyLmsSPA)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[etcd\u5b58\u50a8\u5f15\u64ce\u4e4b\u4e3b\u5e72\u6846\u67b6](https://mp.weixin.qq.com/s/oL_G8H_ROSF3TjtzBOGCow)\\n\\n[Rust \u9ad8\u6027\u80fd\u7f16\u7a0b\u6307\u5357](https://mp.weixin.qq.com/s/5PovYOUzHFcCU2JjDLEnnA)\\n\\n[Go map \u52a0\u6709\u5e8f\u6392\u5e8f\u7684\u4e00\u4e9b\u6323\u624e](https://mp.weixin.qq.com/s/n0v8Xtz1q9XRvZuI4tPoXg)\\n\\n[\u4e91\u97f3\u4e50 GitOps \u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/uYmSCyTZtbSpiIL6Qet5_A)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(1)](https://mp.weixin.qq.com/s/UNr11UvRX9kzKefKttX4wg)\\n\\n[\u76f8\u540c\u578b\u53f7\u7269\u7406\u673a\uff0c\u5bb9\u5668\u6027\u80fd\u4e0d\u5982\u865a\u62df\u673a](https://mp.weixin.qq.com/s/-oQITzwDo51TkUyzUs0BQQ)\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--library/portable-simd](https://mp.weixin.qq.com/s/-zgXvXuUlqywbEPUygmv7w)\\n\\n[Go deadcode\uff1a\u67e5\u627e\u6ca1\u610f\u4e49\u7684\u6b7b\u4ee3\u7801\uff0c\u5bf9\u4e8e\u7ef4\u62a4\u9879\u76ee\u633a\u6709\u7528\uff01](https://mp.weixin.qq.com/s/r-HbSxbvrpIltUdCXCEzSw)\\n\\n[\u901a\u4fd7\u6613\u61c2\u5256\u6790Go Channel\uff1a\u7406\u89e3\u5e76\u53d1\u901a\u4fe1\u7684\u6838\u5fc3\u673a\u5236](https://mp.weixin.qq.com/s/Be6VYGlSa-AXcDkuhCQ1HA)\\n\\n[\u7adf\u7136\u662f\\"\u4f60\\"\u5077\u8d70\u4e86\u90a30.001\u7684\u670d\u52a1\u53ef\u7528\u6027](https://mp.weixin.qq.com/s/-C-wIjkKM7N1M7fcCd7HSQ)\\n\\n[\u7cbe\u5fc3\u8bbe\u8ba1\u7684 DNS Failover \u7b56\u7565\u5728 Go \u4e2d\u7adf\u7136\u5e26\u6765\u4e86\u53cd\u6548\u679c\uff0c\u53d1\u751f\u4e86\u4ec0\u4e48](https://mp.weixin.qq.com/s/BqNLR9rsWSPtTJpzOX1uOw)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#100 Not understanding the impacts of running Go](https://mp.weixin.qq.com/s/Sx2Bo_KUVh2w6twwb_XBVA)\\n\\n[\u300a\u4ece\u6162\u901f\u5230SIMD\u300b\u804aGo \u8fb9\u754c\u68c0\u67e5\u6d88\u9664](https://mp.weixin.qq.com/s/2AWWhbkEhwTJcgCjL-9pcQ)\\n\\n[Go\u9879\u76ee\u4e2d\u7684Labels](https://mp.weixin.qq.com/s/fmlzQfwmIwMgP38op0Ebmg)\\n\\n[Go \u66f4\u5f3a\u7684\u4ee3\u7801\u6d01\u7656\uff0c\u53ef\u4ee5\u628a gofmt \u7ed9\u6362\u4e86\uff01](https://mp.weixin.qq.com/s/dnF3bxT0H_OfAsml9m976w)\\n\\n[Go \u7ec8\u4e8e\u628a\u8fd9\u4e2a\u50bb\u7f3a\u7279\u6027\u53bb\u6389\u4e86\uff0c\u591a\u5c11\u9648\u5e74\u8001BUG\u90fd\u662f\u56e0\u4e3a\u5b83\uff01](https://mp.weixin.qq.com/s/b1cLEth3cgQsTmMCgw9Bog)\\n\\n[Go 1.22 slices \u5e93\u7684\u66f4\u65b0\uff1a\u9ad8\u6548\u62fc\u63a5\u3001\u96f6\u5316\u5904\u7406\u548c\u8d8a\u754c\u63d2\u5165\u4f18\u5316](https://mp.weixin.qq.com/s/10cPBDKOuSuyW1XTUxuqiw)\\n\\n[Go 1.22\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316](https://mp.weixin.qq.com/s/KUiTxRBQcywcyHsHmOFvEQ)\\n\\n[Go\u4e2d\u6700\u5e38\u7528\u7684\u6570\u636e\u6821\u9a8c\u5e93](https://mp.weixin.qq.com/s/Gp4yLILc2rWQonn2Bg-FTg)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1a\u8bf4\u8bf4OOM\u4e09\u5927\u573a\u666f\u548c\u89e3\u51b3\u65b9\u6848\uff1f \uff08\u7edd\u5bf9\u53f2\u4e0a\u6700\u5168\uff09](https://mp.weixin.qq.com/s/8DT0tNYbuPjXkKwMMUABYg)\\n\\n[(\u4e5d)\u6df1\u5165\u5e76\u53d1\u7f16\u7a0b\u4e4b\u5e76\u53d1\u5bb9\u5668\uff1a\u963b\u585e\u961f\u5217\u3001\u5199\u65f6\u590d\u5236\u5bb9\u5668\u3001\u9501\u5206\u6bb5\u5bb9\u5668\u539f\u7406\u8be6\u8c08](https://mp.weixin.qq.com/s/5RehBI0KwDFzkY5ssuivEQ)\\n\\n[(\u516b)\u6df1\u5165\u5e76\u53d1\u4e4bRunnable\u3001Callable\u3001FutureTask\u53caCompletableFuture\u539f\u7406\u5206\u6790](https://mp.weixin.qq.com/s/BJ9ju3Ov6ZwgpbjoM2SDqA)\\n\\n[\u56db\u5341\u4e94\u56fe\uff0c\u4e00\u4e07\u4e94\u5343\u5b57\uff01\u4e00\u6587\u8ba9\u4f60\u8d70\u51fa\u8ff7\u96fe\u73a9\u8f6cMaven\uff01](https://mp.weixin.qq.com/s/n4OGEkfJ_ql-gifHVaN7ZA)\\n\\n[\u8e29\u4e86\u4e00\u5806\u5751\uff0c\u7ec8\u4e8e\u628a\u5fae\u670d\u52a1\u7cfb\u7edf\u5168\u9762\u5347\u7ea7 JDK17 \u548c SpringBoot3 \u4e86](https://mp.weixin.qq.com/s/iKz_iABnlibNb1fRM3RXmA)\\n\\n[\u5947\u601d\u5999\u60f3\u7684SQL\uff5c\u517c\u987e\u6027\u80fd\u7684\u6570\u636e\u503e\u659c\u5904\u7406\u65b0\u59ff\u52bf](https://mp.weixin.qq.com/s/VGgT1faRKGnUuQ-HHQ3Q5g)\\n\\n[\u5982\u4f55\u6210\u4e3a\u4e00\u7ebf Leader](https://mp.weixin.qq.com/s/3xi9uu5OXVRS0dX1PxW9UA)\\n\\n[ForkJoinPool\uff1a\u5927\u4efb\u52a1\u62c6\u5206\uff0c\u8ba9\u5e76\u884c\u55e8\u8d77\u6765\uff01](https://mp.weixin.qq.com/s/f3yorGDYOFVeLydwkAPvFw)\\n\\n[\u5199\u4e86\u8fd9\u4e48\u591a\u5e74DateUtils\uff0c\u6b8a\u4e0d\u77e5\u4f60\u8fd8\u6709\u8fd9\u4e48\u591a\u5f2f\u5f2f\u7ed5\uff01](https://mp.weixin.qq.com/s/h6Bhgcu7QqV0nMUvOUThsg)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014Kafka\u7bc7](https://mp.weixin.qq.com/s/8UNtMIllJ03ULZwE9WtVdg)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\ud83e\udd2f \\\\[\u6027\u80fd\u4f18\u5316\\\\] \u6d4f\u89c8\u5668\u8de8\u57df\u5e26\u6765\u7684\u4e00\u4e9b\u6027\u80fd\u95ee\u9898](https://mp.weixin.qq.com/s/UXZa0lJfQznseNfRnld1_g)\\n\\n[\ud83e\uddd0 \\\\[\u8de8\u7aef\u5f00\u53d1\\\\] \u5982\u4f55\u5b9a\u4f4d Hybrid Web \u9875\u9762\u4e2d Native \u6ce8\u5165\u7684 JS \u4ee3\u7801](https://mp.weixin.qq.com/s/uIupFpxXkbrKiEkCl_1ZYg)\\n\\n[413 - \u300a\u8bfb\u4e66\u7b14\u8bb0\uff1aA Philosophy of Software Design\u300b](https://sorrycc.com/book-a-philosophy-of-software-design)\\n\\n[\u5982\u4f55\u5728\u6cdb\u578b\u7ec4\u4ef6\u4e2d\u4f7f\u7528 forwardRef](https://www.totaltypescript.com/forwardref-with-generic-components)\\n\\n[\u8bd1\uff1aHot Module Replacement \u539f\u7406](https://sorrycc.com/hot-module-replacement-is-easy)\\n\\n[MDH Weekly 121 - \u300a\u5f00\u5de5\u5927\u5409\u300b](https://mp.weixin.qq.com/s/ga5-g5sOTccc7z1ZCQ29jg)"},{"id":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-18/index.md","source":"@site/blogs/2024/2024-02-18/index.md","title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-02-18T00:00:00.000Z","formattedDate":"February 18, 2024","tags":[],"readingTime":6.41,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1a\u725b\u903c\u4e86\uff012\u6708\u7f16\u7a0b\u8bed\u8a00\u699c\u5355\uff1aGo\u9996\u6b21\u8fdb\u5165\u524d\u5341\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[How to Cut RAG Costs by 80% Using Prompt Compression](https://towardsdatascience.com/how-to-cut-rag-costs-by-80-using-prompt-compression-877a07c6bedb)\\n\\n[RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture](https://arxiv.org/abs/2401.08406)\\n\\n[RAG vs Finetuning \u2014 Which Is the Best Tool to Boost Your LLM Application](https://towardsdatascience.com/rag-vs-finetuning-which-is-the-best-tool-to-boost-your-llm-application-94654b1eaba7)\\n\\n[\u5927\u8bed\u8a00\u6a21\u578b\u4e4bLlaMA\u7cfb\u5217- LlaMA 2\u53caLLaMA2_chat(\u4e0a)](https://mp.weixin.qq.com/s/Nyu46KN0Hj2-r93vXVcbiQ)\\n\\n[RAG\u8fd8\u662f\u5fae\u8c03\uff1f\u5fae\u8f6f\u51fa\u4e86\u4e00\u4efd\u7279\u5b9a\u9886\u57df\u5927\u6a21\u578b\u5e94\u7528\u5efa\u8bbe\u6d41\u7a0b\u6307\u5357](https://mp.weixin.qq.com/s/G8nKz4H3QSKBibSMYAzRvA)\\n\\n[\u8c37\u6b4c\u5168\u65b0\u5927\u6a21\u578b\u7a81\u7136\u53d1\u5e03\uff01100\u4e07token\u5b8c\u7206GPT-4\uff0c\u4ec5\u9760\u63d0\u793a\u8bcd\u5c31\u80fd\u5b66\u4f1a\u65b0\u8bed\u8a00](https://mp.weixin.qq.com/s/FKC7Y-05L9VfukI-3EMvZw)\\n\\n[\u6269\u5c55\u8bf4\u660e: \u6307\u4ee4\u5fae\u8c03 Llama 2](https://mp.weixin.qq.com/s/iIIM3N1-1cE2SxBRdZ-ILg)\\n\\n[\u793e\u533a\u4f9b\u7a3f | \u56fe\u89e3\u5927\u6a21\u578b\u63a8\u7406\u4f18\u5316\u4e4b KV Cache](https://mp.weixin.qq.com/s/6q2LmwoFG2LcN0iHoZjjqw)\\n\\n[\u5927\u6a21\u578b\u6027\u80fd\u4f18\u5316\u4e4bPrompt\u5de5\u7a0b\u5168\u9762\u68b3\u7406\uff1a\u4ecezero shot\u5230chain of thought\u518d\u5230\u82b1\u5f0fXOT](https://mp.weixin.qq.com/s/va1Ua3koedNWKkln4v6Vvg)\\n\\n[\u5927\u6a21\u578bRAG\u95ee\u7b54\u884c\u4e1a\u6700\u4f73\u6848\u4f8b\u53ca\u5fae\u8c03\u3001\u63a8\u7406\u53cc\u9636\u6bb5\u5b9e\u73b0\u6a21\u5f0f\uff1a\u57fa\u4e8e\u6a21\u5757\u5316(Modular)RAG\u81ea\u5b9a\u4e49RAG Flow](https://mp.weixin.qq.com/s/bJRFayNByx4D3ujGcEb47A)\\n\\n[\u503c\u5f97\u4e00\u770b\u7684\u5927\u6a21\u578bRAG\u95ee\u7b54\u603b\u62ec\u6027\u68b3\u7406\uff1a\u6a21\u5757\u5316(Modular)RAG\u8303\u5f0f\u7684\u5b9a\u4e49\u3001\u6784\u6210\u53ca\u673a\u9047](https://mp.weixin.qq.com/s/j07PkTCoxBzAhkyON1puPg)\\n\\n[\u3010\u6709\u8154\u8c03\u7684RAG\u301101 \u534a\u7ed3\u6784\u5316\u6570\u636e\u4e0a\u7684RAG](https://www.bilibili.com/video/BV1tN4y1m78N)\\n\\n[\u7701\u94b1\uff01\u5fae\u8f6f\u5f00\u6e90\u6846\u67b6LLMLingua + LlamaIndex\u5b9e\u73b0\u63d0\u793a\u8bcd\u538b\u7f29](https://www.bilibili.com/video/BV16w411J7sW)\\n\\n[Ollama Python\u5f00\u53d1\u5305\u5b9e\u4f8b | \u57fa\u4e8e\u672c\u5730\u90e8\u7f72\u5f00\u6e90\u5927\u6a21\u578b\u7684Streamlit\u804a\u5929\u5e94\u7528](https://www.bilibili.com/video/BV1GK4y1q718)\\n\\n[\u3010\u9690\u79c1\u4f18\u5148\u3011Llama 2 + GPT4All + Chroma\u5b9e\u73b0100%\u672c\u5730\u5316RAG](https://www.bilibili.com/video/BV1yH4y117oV)\\n\\n[\u5927\u6a21\u578b\u65f6\u4ee3\u8fd8\u4e0d\u7406\u89e3\u81ea\u6ce8\u610f\u529b\uff1f\u8fd9\u7bc7\u6587\u7ae0\u6559\u4f60\u4ece\u5934\u5199\u4ee3\u7801\u5b9e\u73b0](https://mp.weixin.qq.com/s/XZDG8ZaB4QqD5cgIDJT6vQ)\\n\\n[\u9648\u4e39\u7426\u56e2\u961f\u65b0\u4f5c\uff1a\u6570\u636e\u91cf\u780d95%\uff0c\u5927\u6a21\u578b\u6027\u80fd\u66f4\u5f3a\u4e86\uff01Less is More](https://mp.weixin.qq.com/s/4ZnL0_uMLBgbVCNVjPWGKg)\\n\\n[\u3010AI \u521d\u4f53\u9a8c\u3011 llama2\u4e0eLangChain \u7684 SQLDatabaseChain](https://juejin.cn/post/7298997940019314742)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u4ece\u7269\u7406\u673a\u5230K8S\uff1a\u5e94\u7528\u7cfb\u7edf\u90e8\u7f72\u65b9\u5f0f\u7684\u6f14\u8fdb\u53ca\u5176\u5f71\u54cd](https://juejin.cn/post/7306806944047415332)\\n\\n[Leetcode \u7b97\u6cd5\u9898\u89e3\u7cbe\u9009](https://mp.weixin.qq.com/s/ujs3PT_g7yFHVW-klzTJNQ)\\n\\n[\u725b\u903c\u4e86\uff012\u6708\u7f16\u7a0b\u8bed\u8a00\u699c\u5355\uff1aGo\u9996\u6b21\u8fdb\u5165\u524d\u5341](https://mp.weixin.qq.com/s/HaVmckBGakEwu-EJ5JkONg)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#99 Not understanding how the GC works](https://mp.weixin.qq.com/s/fQensm55bnzPKagMEVs8Ag)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#98 Not using Go diagnostics tooling](https://mp.weixin.qq.com/s/GwOvZYfT6Y7euZuum9868Q)\\n\\n[\u4e00\u6587\u641e\u61c2Go GC\u6f14\u8fdb\u53f2\uff0c\u8bb2\u7684\u592a\u7ec6\u81f4\u4e86\uff01](https://juejin.cn/post/7317462907302461475)\\n\\n[Rust \u4e2d\u7684\u5e76\u53d1\u6a21\u578b\u548c\u6240\u6709\u6743\u7cfb\u7edf](https://juejin.cn/post/7307244392564408358)\\n\\n[Kitex\uff1a\u5fae\u670d\u52a1\u67b6\u6784\u4e0b\u7684\u9ad8\u6027\u80fd\u4f18\u5316\u5b9e\u8df5](https://juejin.cn/post/7270326047342182419)\\n\\n[\u63a2\u7a76 Go \u7684\u9ad8\u7ea7\u7279\u6027\u4e4b \u3010\u5904\u74061\u5206\u949f\u767e\u4e07\u8bf7\u6c42\u3011](https://juejin.cn/post/7245919919223636023)\\n\\n[\u63a2\u7a76 Go \u7684\u9ad8\u7ea7\u7279\u6027\u4e4b \u3010\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1\u4e2d\u7bc7\u3011](https://juejin.cn/post/7247428110165016613)\\n\\n[\u7528 Go \u8bed\u8a00\u5b9e\u73b0\u5218\u8c26 2024 \u6625\u665a\u9b54\u672f\uff0c\u8fd8\u539f\u5c3c\u683c\u4e70\u63d0\u6c57\u6d41\u6d43\u80cc\u7684\u5c34\u5c2c\u77ac\u95f4!](https://juejin.cn/post/7333027152139567113)\\n\\n[\u8fd8\u4e0d\u6562\u5199\u591a\u7ebf\u7a0b\u7a0b\u5e8f\uff1f\u770b\u770bGo\u5982\u4f55\u8ba9\u5e76\u53d1\u63a7\u5236\u7b80\u5355\u6709\u8da3](https://juejin.cn/post/7323087699479724042)\\n\\n[\u4ece fatal \u9519\u8bef\u5230 sync.Map\uff1aGo\u4e2d Map \u7684\u5e76\u53d1\u7b56\u7565](https://juejin.cn/post/7325733245166026793)\\n\\n[16. Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e09\uff09\uff1aGMP \u6a21\u578b\u8c03\u5ea6\u65f6\u673a](https://juejin.cn/post/7330052230472663055)\\n\\n[15. Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e8c\uff09\uff1aGo \u7a0b\u5e8f\u542f\u52a8\u90fd\u5e72\u4e86\u4e9b\u4ec0\u4e48](https://juejin.cn/post/7327138554756857908)\\n\\n[14. Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e00\uff09\uff1a\u4ec0\u4e48\u662f GMP](https://juejin.cn/post/7324931501926875170)\\n\\n[13. \u5165\u95e8 go \u8bed\u8a00\u6c47\u7f16\uff0c\u770b\u61c2 GMP \u6e90\u7801](https://juejin.cn/post/7319484272531701812)\\n\\n[8. \u770b Go \u6e90\u7801\uff0c\u4f60\u9700\u8981\u4e86\u89e3 unsafe.Pointer](https://juejin.cn/post/7298645450554605568)\\n\\n[5. golang map \u6e90\u7801\u7684\u9010\u53e5\u89e3\u8bfb](https://juejin.cn/post/7293820517375164416)\\n\\n[\u4e00\u6587\u641e\u61c2Kubernetes \u90e8\u7f72\u7b56\u7565](https://juejin.cn/post/7319418651069743167)\\n\\n[\u6eda\u52a8\u66f4\u65b0\u548c\u56de\u6eda\u90e8\u7f72\u5728 Kubernetes \u4e2d\u7684\u5de5\u4f5c\u539f\u7406](https://juejin.cn/post/7303075105390477323)\\n\\n[Go \u9879\u76ee\u6807\u51c6\u5e03\u5c40\uff1fGo \u5b98\u65b9\u51fa\u6307\u5357\u4e86](https://juejin.cn/post/7291853227245764658)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u963f\u91cc\u7ec8\u9762\uff1aNetty \u5982\u4f55\u505a\u5230\u5355\u673a\u767e\u4e07\u5e76\u53d1](https://mp.weixin.qq.com/s/j_cslpQDjVIUm1CGjk9CQQ)\\n\\n[8\u79cd\u4e13\u5751\u540c\u4e8b SQL\u5199\u6cd5\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b](https://mp.weixin.qq.com/s/9jKS_vW7lN3f-RwEDS7avw)\\n\\n[\u4ebf\u7ea7\u63a8\u9001\uff0c\u5f97\u7269\u662f\u600e\u4e48\u67b6\u6784\u7684](https://mp.weixin.qq.com/s/GGvBCVWSLce7Gs0Z0B8Jvg)\\n\\n[\u8be6\u89e3Redis\u4e09\u5927\u96c6\u7fa4\u6a21\u5f0f\uff0c\u8f7b\u677e\u5b9e\u73b0\u9ad8\u53ef\u7528\uff01](https://mp.weixin.qq.com/s/cvuz0619FadtkzmjD47llg)\\n\\n[\u963f\u91ccJava\u9762\u8bd5\u5b98\uff1aCopyOnWriteArrayList\u5e95\u5c42\u662f\u600e\u4e48\u4fdd\u8bc1\u7ebf\u7a0b\u5b89\u5168\u7684](https://mp.weixin.qq.com/s/AMkub_c3bTk8O0NzsdW35Q)\\n\\n[\u8fd8\u641e\u4e0d\u61c2ConcurrentHashMap\u5e95\u5c42\u6e90\u7801\uff0c\u770b\u8fd9\u7bc7\u5c31\u591f\u4e86](https://mp.weixin.qq.com/s/PlizO3EnFRmqn4Cl6nqiGA)\\n\\n[\u53ea\u9700\u4e03\u6b65\uff0c\u6559\u4f60\u8f7b\u677e\u89e3\u51b3Redis\u70ed\u70b9Key\u95ee\u9898](https://mp.weixin.qq.com/s/gb9nqVfqrClZ5o4-B4Eadg)\\n\\n[\u4e00\u6587\u8be6\u89e3Redis\u4e2dBigKey\u3001HotKey\u7684\u53d1\u73b0\u4e0e\u5904\u7406](https://mp.weixin.qq.com/s/FPYE1B839_8Yk1-YSiW-1Q)\\n\\n[Java \u5341\u4ebf\u884c\u6570\u636e\u8ba1\u7b97\uff0c\u6700\u5feb6\u79d2\u51fa\u7ed3\u679c\uff0c\u4f60\u80fd\u5417](https://mp.weixin.qq.com/s/dpXMqMSq_ZrXOeEInxlC_Q)\\n\\n[\u4eceKafka\u4e2d\u5b66\u4e60\u9ad8\u6027\u80fd\u7cfb\u7edf\u5982\u4f55\u8bbe\u8ba1 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7249380394457694263)\\n\\n[\u7531\u6d45\u5165\u6df1\u7684\u4ecb\u7ecd\u6263\u51cf\u4e1a\u52a1\u4e2d\u7684\u4e00\u4e9b\u9ad8\u5e76\u53d1\u6784\u5efa\u65b9\u6848\uff08\u4e0a\uff09](https://juejin.cn/post/7256104538230571067)\\n\\n[\u5982\u4f55\u5728\u5fae\u670d\u52a1\u4e0b\u4fdd\u8bc1\u4e8b\u52a1\u7684\u4e00\u81f4\u6027 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7226525442176778277)\\n\\n[\u3010Redis\u9ad8\u53ef\u7528\u7cfb\u5217\u3011\u4e3b\u4ece\u590d\u5236\u539f\u7406\u548c\u590d\u5236\u65b9\u5f0f\u5206\u6790](https://juejin.cn/post/7309373606272761895)\\n\\n[Redis\u5220\u9664\u6570\u636e\u540e\uff0c\u4e3a\u4ec0\u4e48\u5185\u5b58\u5360\u7528\u7387\u8fd8\u662f\u5f88\u9ad8](https://juejin.cn/post/7300809038246608948)\\n\\n[\u611f\u89c9Redis\u53d8\u6162\u4e86\uff0c\u8fd9\u4e9b\u53ef\u80fd\u7684\u539f\u56e0\u4f60\u67e5\u4e86\u6ca1 (\u4e0a)](https://juejin.cn/post/7290725204266287158)\\n\\n[\u611f\u89c9Redis\u53d8\u6162\u4e86\uff0c\u8fd9\u4e9b\u53ef\u80fd\u7684\u539f\u56e0\u4f60\u67e5\u4e86\u6ca1 (\u4e0b)](https://juejin.cn/post/7292975471448113192)\\n\\n[\u4f4d\u56fe(bitmap)\u539f\u7406\u4ee5\u53ca\u5b9e\u73b0](https://juejin.cn/post/7280435879541637176)\\n\\n[\u4ebf\u4e07\u7528\u6237\u5728\u7ebf\uff0c\u4e00\u5f20bitmap\u7edf\u8ba1\u5168\u89e3\u5bc6](https://juejin.cn/post/7329694104118362139)\\n\\n[\u5982\u4f55\u4f7f\u7528Redis\u6570\u636e\u7c7b\u578b\u8fdb\u884c\u4ebf\u7ea7\u522b\u7edf\u8ba1\u6570\u636e](https://juejin.cn/post/7282666872218107915)\\n\\n[MySQL\u4e8b\u52a1\u672a\u63d0\u4ea4redolog\u80fd\u6301\u4e45\u5316\u5230\u78c1\u76d8\u5417](https://juejin.cn/post/7319273137765449763)\\n\\n[\u7ed3\u5408MySQL\u66f4\u65b0\u6d41\u7a0b\u770b undolog\u3001redolog\u3001binlog](https://juejin.cn/post/7269296778226597927)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u81f4\u6240\u6709\u6e34\u671b\u5b66\u4e60Rust\u7684\u4eba\u7684\u4fe1](https://juejin.cn/post/7275978708644511802)\\n\\n[\u524d\u7aef\u9879\u76ee\u91cc\u90fd\u6709\u5565](https://juejin.cn/post/7327867132037611539)\\n\\n[\u767d\u5ad6ChatGPT4.0 (\u7b2c\u4e8c\u5f39)](https://juejin.cn/post/7302310196310294580)\\n\\n[\u5b57\u8282\u8df3\u52a8\u6700\u70ed\u95e8\u7684 15 \u4e2a\u524d\u7aef\u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/XuigLACJa95rJ9iJQhIDDg)\\n\\n[\u5218\u8c26\u6625\u665a\u9b54\u672f\u63ed\u79d8\uff1a\u7ea6\u745f\u592b\u73af\u7684\u6570\u5b66\u9b45\u529b\uff0cJS\u5b9e\u73b0\u4e0b\uff01](https://mp.weixin.qq.com/s/PUywO7JtYuO9H0fnLGsz-w)\\n\\n[\u6211\u5199\u4e86\u4e00\u4e2a\u6839\u636e\u9879\u76ee\u81ea\u52a8\u5207\u6362node\u7248\u672c\u7684\u63d2\u4ef6\uff0c\u518d\u4e5f\u4e0d\u7528\u624b\u52a8\u4f7f\u7528\u547d\u4ee4\u5207\u6362\u4e86](https://mp.weixin.qq.com/s/tk_E1NP6ra0yxuSVumH6UA)"},{"id":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-11/index.md","source":"@site/blogs/2024/2024-02-11/index.md","title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-02-11T00:00:00.000Z","formattedDate":"February 11, 2024","tags":[],"readingTime":3.79,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1aGo1.22 \u6b63\u5f0f\u53d1\u5e03\uff01\u5305\u542b\u8bed\u8a00\u53d8\u5316\u3001\u6027\u80fd\u63d0\u9ad8\u3001\u6807\u51c6\u5e93\u53d8\u52a8\u7b49\u91cd\u8981\u7279\u6027\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[MultiHop-RAG: Benchmarking Retrieval-Augmented Generation for Multi-Hop Queries](https://arxiv.org/pdf/2401.15391.pdf)\\n\\n[\u624b\u628a\u624b\u6559\u4f60\uff0c\u4ece\u96f6\u5f00\u59cb\u5b9e\u73b0\u4e00\u4e2a\u7a00\u758f\u6df7\u5408\u4e13\u5bb6\u67b6\u6784\u8bed\u8a00\u6a21\u578b\uff08MoE\uff09](https://mp.weixin.qq.com/s/fV-dnbT5g8j_B3RXgRsuZQ)\\n\\n[\u82f9\u679c\u4e3a\u81ea\u5bb6\u82af\u7247\u6253\u9020\u5f00\u6e90\u6846\u67b6MLX\uff0c\u5b9e\u73b0Llama 7B\u5e76\u5728M2 Ultra\u4e0a\u8fd0\u884c](https://mp.weixin.qq.com/s/jtpXKlABXwzlN8QjzT-sPA)\\n\\n[\u5982\u4f55\u7528LLM\u548c\u81ea\u6709\u77e5\u8bc6\u5e93\u642d\u5efa\u667a\u80fdAgent](https://mp.weixin.qq.com/s/dSleYYKtE41RQ9AUf5ruMw)\\n\\n[\u4e07\u5b57\u8be6\u89e3\u4e13\u5bb6\u6df7\u5408\uff1aMoE\u6a21\u578b](https://mp.weixin.qq.com/s/MY7sWGct2IxvDYvthY6A0g)\\n\\n[Prompt Engineering\uff1a\u5927\u6a21\u578b PUA \u6307\u5357\uff01](https://mp.weixin.qq.com/s/JloI284hBrKyV0d2s7V3ug)\\n\\n[Mixtral-8x7B \u6a21\u578b\u6316\u5751](https://mp.weixin.qq.com/s/IxQy6UMXaFn2odVFLhEXHw)\\n\\n[\u7cbe\u5f69\u624b\u7ed8\u5168\u89e3\uff1aRAG\u6280\u672f\uff0c\u4ece\u5165\u95e8\u5230\u7cbe\u901a](https://mp.weixin.qq.com/s/BITRn0NkpaVP0niiqevUaQ)\\n\\n[\u5355\u53613\u5c0f\u65f6\u8bad\u7ec3\u4e13\u5c5e\u5927\u6a21\u578bAgent-\u57fa\u4e8eLLaMA Factory\u5b9e\u6218](https://mp.weixin.qq.com/s/qeWEEmWlomjtFP5wQxUAcg)\\n\\n[\u767d\u8bddEmbedding\uff1a\u666e\u901a\u4eba\u90fd\u80fd\u61c2\u7684\u79d1\u666e\u6587](https://mp.weixin.qq.com/s/DGeey6v3ntGhIorOd_eB3w)\\n\\n[Mixtral 8x7B: \u8d85\u8d8aGPT-3.5\u4e0eLlama 2 70B\u7684\u7a00\u758f\u6df7\u5408\u4e13\u5bb6\u67b6\u6784\u65b0\u7bc7\u7ae0](https://mp.weixin.qq.com/s/GGY-hvcNphj4fvPxJPLLrQ)\\n\\n[3B\u6a21\u578b\u4e0d\u8f937B LLaVA\uff01\u5317\u5927\u591a\u6a21\u6001MoE\u6a21\u578b\u767bGitHub\u70ed\u699c](https://mp.weixin.qq.com/s/NSfAdIBXNzG9WNrz9jP1eA)\\n\\n[GPT-4\u63a8\u7406\u80fd\u529b\u66b4\u6da832%\uff0c\u8c37\u6b4c\u65b0\u578b\u601d\u7ef4\u94fe\u6548\u679c\u8d85CoT\uff0c\u8ba1\u7b97\u6210\u672c\u53ef\u964d\u81f31/40](https://mp.weixin.qq.com/s/HUW8MX2GhsdE3qFBvb1-Hg)\\n\\n[\u963f\u91cc\u5927\u6a21\u578b\u6625\u8282\u793c\u5305\u6765\u4e86\uff1a\u4ee3\u7801\u53ef\u6267\u884c\u7387\u8d85GPT-4\uff0c1.5\u7248\u672c\u5168\u7cfb\u5217\u5f00\u6e90](https://mp.weixin.qq.com/s/Ddn-8zI7SF5VfoQPcoYuPg)\\n\\n[\u521a\u521a\uff0c\u8c37\u6b4c\u5f03Bard\u53d1\u5e03\u8d85\u5927\u676fGemini\uff0c\u5168\u9762\u5bf9\u6807GPT-4\uff0c\u524d2\u4e2a\u6708\u514d\u8d39\uff01](https://mp.weixin.qq.com/s/V3abZ1R-NYG7nMRngheYbA)\\n\\n[\u65e0\u9700RLHF\u663e\u8457\u63d0\u5347GPT-4/Llama2\u6027\u80fd\uff0c\u5317\u5927\u56e2\u961f\u63d0\u51faAligner\u5bf9\u9f50\u65b0\u8303\u5f0f](https://mp.weixin.qq.com/s/O9PP4Oc_Ee3R_HxKyd31Qg)\\n\\n[\u624b\u6495LangChain\u4ee3\u7801\uff0c\u65b0\u624b\u8bf7\u8fdb](https://mp.weixin.qq.com/s/mPO13cCbTgIkWZBfKSjFvA)\\n\\n[MoE \u5377\u8d77\u6765\u5566\uff01\u53c8\u4e00\u5fae\u8c03\u7248 Mixtral-8x7B \u53d1\u5e03\uff0c\u8bd5\u8bd5\u6548\u679c\u600e\u4e48\u6837](https://mp.weixin.qq.com/s/Ks6X9RSCuNnTU2ZlQiGpqA)\\n\\n[\u4e0d\u662f GPT4 \u7528\u4e0d\u8d77\uff0c\u800c\u662f\u672c\u5730\u8fd0\u884c Mixtral-8x7B \u66f4\u6709\u6027\u4ef7\u6bd4](https://mp.weixin.qq.com/s/lGcatebmosW9BerZyVRlBQ)\\n\\n[\u5728 Mac \u8fd0\u884c OpenChat 3.5 \u5927\u6a21\u578b\uff0cAI\u63a8\u7406APP\u4ec52MB \u5b8c\u5168\u53ef\u79fb\u690d](https://mp.weixin.qq.com/s/mmG8NQbG6fnmc4lHL1zHWQ)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u4ee3\u7801\u9a8c\u8bc1\u65af\u7279\u6797\u516c\u5f0f\u7684\u51c6\u786e\u6027](https://mp.weixin.qq.com/s/4bd77FfQubPqdhcNJPFrsQ)\\n\\n[\u4e00\u4e9b\u7b14\u8bb0\u5de5\u5177\u5de5\u5177\u4ee5\u53camemos\u4ecb\u7ecd](https://mp.weixin.qq.com/s/-8IcAjN6T6LeE29p0nkqcQ)\\n\\n[Go 1.22.0 \u53ef\u79f0\u4e4b\u4e3a\u4e00\u6b21\u53f2\u8bd7\u7ea7\u66f4\u65b0](https://mp.weixin.qq.com/s/vr_-5HD0hFZYHmnnisByiA)\\n\\n[Go1.22 \u6b63\u5f0f\u53d1\u5e03\uff01\u5305\u542b\u8bed\u8a00\u53d8\u5316\u3001\u6027\u80fd\u63d0\u9ad8\u3001\u6807\u51c6\u5e93\u53d8\u52a8\u7b49\u91cd\u8981\u7279\u6027](https://mp.weixin.qq.com/s/SFMKam051BIZI4gwz8nrKg)\\n\\n[\u5b9e\u73b0\u57fa\u4e8e Grafana Loki \u7684\u65e5\u5fd7\u62a5\u8b66](https://mp.weixin.qq.com/s/8JAQxUQSfIggAIArokeL9g)\\n\\n[\u9f50\u6d3b\u4e86\uff0cGrafana \u53d1\u5e03\u5927\u89c4\u6a21\u6301\u7eed\u6027\u80fd\u5206\u6790\u5f00\u6e90\u6570\u636e\u5e93 - Phlare](https://mp.weixin.qq.com/s/P8E52qK6qeigwTMPWECBsw)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[DDD\u843d\u5730\uff1a\u4ece\u643a\u7a0b\u8ba2\u5355\u7cfb\u7edf\u91cd\u6784\uff0c\u770bDDD\u7684\u5de8\u5927\u4ef7\u503c](https://mp.weixin.qq.com/s/IsEDEu33HqHffFdv-A7WBw)\\n\\n[\u4e00\u6b21\u7531\u4e8e\u516b\u80a1\u6587\u5f15\u8d77\u7684\u5185\u5b58\u6cc4\u6f0f](https://mp.weixin.qq.com/s/QGmOz8jUjNo-3xKqVcWGmg)\\n\\n[\u7f51\u6613\u9762\u8bd5\uff1a\u8bf7\u8bbe\u8ba1\u4e00\u4e2a\u9ad8\u53ef\u7528\u6027\u7684\u8f6f\u4ef6\u67b6\u6784\uff0c\u8bf4\u660e\u8bbe\u8ba1\u601d\u8def](https://mp.weixin.qq.com/s/tNOhR16aC-cr5EqKiwbAOQ)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014MySQL\u7bc7](https://mp.weixin.qq.com/s/L26rI11OV8hrfJVy5Yu78g)\\n\\n[\u5929\u5929\u5199\u4e1a\u52a1\u4ee3\u7801\uff0c\u5982\u4f55\u7834\u5c40\u4e1a\u52a1\u5f00\u53d1\u7684\u672c\u8d28](https://mp.weixin.qq.com/s/2I3gFQZY03OKhdJa1AVhmw)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u7011\u5e03\u6d41\u4f18\u5316\uff1a\u6211\u628a\u5c0f\u7ea2\u4e66\u7684\u7011\u5e03\u6d41\u865a\u62df\u5217\u8868\u6495\u51fa\u6765\u4e86](https://mp.weixin.qq.com/s/z5zzBWel6DooAS0bzY702g)\\n\\n[\u5fc3\u9047APP\u7ad9\u5185\u73a9\u6cd5H5\u4f53\u9a8c\u4f18\u5316\u5b9e\u8df5](https://mp.weixin.qq.com/s/GYtd3k0JXns1GZQyZzvHaQ)\\n\\n[\u8bd1\uff1a\u5982\u4f55\u907f\u514d SSR \u6e32\u67d3\u672c\u5730\u65e5\u671f\u65f6\u7684 FOUC \u95ee\u9898](https://sorrycc.com/ssr-local-dates-without-fouc)\\n\\n[\u8bd1\uff1a\u5371\u9669\u7684\u6ce8\u6c34](https://sorrycc.com/danger-rehydration)\\n\\n[\u8bd1\uff1aReact 19 \u8ba1\u5212\u63a8\u51fa\u7684\u65b0 Hook](https://sorrycc.com/react-19-new-hooks)\\n\\n[\u8bd1\uff1a\u4f7f\u7528 Promise.withResolvers \u5ef6\u8fdf Promise](https://sorrycc.com/promise-with-resolvers)\\n\\n[2024 \u5e74\u4f60\u9700\u8981\u77e5\u9053\u7684 5 \u4e2a CSS \u4ee3\u7801\u7247\u6bb5](https://web.dev/articles/5-css-snippets-every-front-end-developer-should-know-in-2024)\\n\\n[Partial Prerendering \u7684 What\u3001Why \u548c How](https://www.youtube.com/watch?v=MTcPrTIBkpA)\\n\\n[2024 \u5e74\u5982\u4f55\u542f\u52a8 React \u9879\u76ee](https://www.robinwieruch.de/react-starter/)\\n\\n[MDH Weekly 120 - \u300a\u5c0f\u518c\u300b](https://mp.weixin.qq.com/s/fY-wz2LzkiZrvpblpSWlVw)"},{"id":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-04/index.md","source":"@site/blogs/2024/2024-02-04/index.md","title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-02-04T00:00:00.000Z","formattedDate":"February 4, 2024","tags":[],"readingTime":4.22,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1a\u56fe\u6587\u5403\u900fGolang net/http \u6807\u51c6\u5e93--\u670d\u52a1\u7aef\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[Large Language Models for Mathematical Reasoning: Progresses and Challenges](https://arxiv.org/abs/2402.00157)\\n\\n[A Comprehensive Survey of Compression Algorithms for Language Models](https://arxiv.org/abs/2401.15347)\\n\\n[The Power of Noise: Redefining Retrieval for RAG Systems](https://arxiv.org/abs/2401.14887)\\n\\n[Corrective Retrieval Augmented Generation](https://arxiv.org/abs/2401.15884)\\n\\n[\u4ece\u96f6\u6784\u5efa\u73b0\u4ee3\u6df1\u5ea6\u5b66\u4e60\u6846\u67b6(TinyDL-0.01)](https://mp.weixin.qq.com/s/tFl0RQd3ex98_SAOIIfM_Q)\\n\\n[\u672c\u5730\u8fd0\u884c\u9762\u58c1\u667a\u80fd\u7684\u201c\u8d3a\u5c81\u6a21\u578b\u201d\uff1aMiniCPM 2B](https://mp.weixin.qq.com/s/Z0iZR6iGSBe298eK1Er1Ow)\\n\\n[\u300c\u6211\u5728\u6dd8\u5929\u505a\u6280\u672f\u300d2024\u5e74\u770bAIGC\u662f\u5982\u4f55\u8ba91688\u4e3b\u56fe\u7115\u53d1\u65b0\u6625\u7684](https://mp.weixin.qq.com/s/Ni_vVDlxBaoUcgoVORw31A)\\n\\n[\u5927\u6a21\u578b\u63a8\u7406\u6846\u67b6RTP-LLM\u5bf9LoRA\u7684\u652f\u6301](https://mp.weixin.qq.com/s/em-mnps_Oqe1PLLpJ9hB-A)\\n\\n[LLM\u4e4bLangChain\uff08\u4e94\uff09| \u4f7f\u7528LangChain Agent\u5206\u6790\u975e\u7ed3\u6784\u5316\u6570\u636e](https://mp.weixin.qq.com/s/chxksL3zqbwyqHev1x43kw)\\n\\n[LLM\u4e4bRAG\u7406\u8bba\uff08\u516d\uff09| \u9ad8\u7ea7RAG\u6307\u5357\u548c\u6280\u5de7](https://mp.weixin.qq.com/s/a5uKQAxwfsREnXd0XPhu1A)\\n\\n[\u4ece\u96f6\u624b\u6413MoE\u5927\u6a21\u578b\uff0c\u5927\u795e\u7ea7\u6559\u7a0b\u6765\u4e86](https://mp.weixin.qq.com/s/gDtzzSRunUrKjoIUGSHCvA)\\n\\n[RAG\u8fdb\u9636 \u591a\u7528\u6237\u591a\u6587\u6863](https://juejin.cn/post/7325993514702258230)\\n\\n[RAG \u8fdb\u9636 LlamaIndex\u591a\u6587\u6863](https://juejin.cn/post/7325831147563958308)\\n\\n[RAG \u8fdb\u9636 \u591a\u6a21\u6001\u56fe\u7247\u68c0\u7d22](https://juejin.cn/post/7325724706139996201)\\n\\n[RAG \u8fdb\u9636 \u534a\u7ed3\u6784\u5316\u6570\u636e](https://juejin.cn/post/7325800661232140327)\\n\\n[LlamIndex\u4e8c RAG\u5e94\u7528\u5f00\u53d1](https://juejin.cn/post/7310347016982069288)\\n\\n[LlamaIndex \u4e00 \u7b80\u5355\u6587\u6863\u67e5\u8be2](https://juejin.cn/post/7310786591940165641)\\n\\n[\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u4e2d\u6587\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/9cTNa_oya2Zj9YdDYodCvw)\\n\\n[\u90e8\u7f72\u5fc5\u5907\u2014triton-inference-server\u7684backend\uff08\u4e00\uff09\u2014\u2014\u5173\u4e8e\u63a8\u7406\u6846\u67b6\u7684\u4e00\u4e9b\u8ba8\u8bba](https://mp.weixin.qq.com/s/_WStiyaAk7G-w2j6SVe4CA)\\n\\n[TensorRT-LLM\u521d\u63a2\uff08\u4e00\uff09\u8fd0\u884cllama\uff0c\u4ee5\u53catriton tensorrt llm backend\u670d\u52a1\u5316](https://mp.weixin.qq.com/s/J1EdNtAx3B0yeQ7zeSDLQg)\\n\\n[H100\u63a8\u7406\u98d9\u53478\u500d\uff01\u82f1\u4f1f\u8fbe\u5b98\u5ba3\u5f00\u6e90TensorRT-LLM\uff0c\u652f\u630110+\u6a21\u578b](https://mp.weixin.qq.com/s/xcNQBG69XkS6mOstzqROAw)\\n\\n[\u5927\u8bed\u8a00\u6a21\u578b\u63a8\u7406\u63d0\u901f\uff1aTensorRT-LLM \u9ad8\u6027\u80fd\u63a8\u7406\u5b9e\u8df5](https://mp.weixin.qq.com/s/jnQs5XhWeAqoitahmDhziQ)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1a\u6027\u80fd\u63d0\u9ad8\u3001Trace \u5927\u4fee\u3001\u5de5\u4f5c\u533a\u652f\u6301 vendor \u7b49](https://mp.weixin.qq.com/s/_RHDJ1VGfqolE_Uzorosbw)\\n\\n[json.Marshal\u4e3a\u4ec0\u4e48\u4f1a\u5bf9[]byte\u7c7b\u578b\u8fdb\u884cbase64\u7f16\u7801\u5904\u7406](https://mp.weixin.qq.com/s/h8SNvIVN1bFy8gBUB63_NA)\\n\\n[Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e8c\uff09\uff1aGo \u7a0b\u5e8f\u542f\u52a8\u90fd\u5e72\u4e86\u4e9b\u4ec0\u4e48](https://mp.weixin.qq.com/s/PvdZ_Ay9xgrY_SrDt-Sddw)\\n\\n[Go\u8bed\u8a00\u4e2d\u7684Pinner.Pin](https://mp.weixin.qq.com/s/MNuk0poC3s2tTx_DjyJAQA)\\n\\n[Kubernetes \u8c03\u5ea6\u5668\u961f\u5217 - \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/wQqMu41e8pnLpnAZo0GLow)\\n\\n[Go\u8bed\u8a00\u901a\u77e5\u534f\u7a0b\u9000\u51fa(\u53d6\u6d88)\u7684\u51e0\u79cd\u65b9\u5f0f](https://mp.weixin.qq.com/s/CNTlXMWSmQ4dNbbCQpbjYg)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#97 Not relying on inlining](https://mp.weixin.qq.com/s/SC1tg6XxDi_y1bjj6lkw6w)\\n\\n[\u7a0b\u5e8f\u5458\u624d\u61c2\u7684\u4e50\u8da3\uff1a10\u4ebf\u884c\u7684\u6311\u6218](https://mp.weixin.qq.com/s/_z801oBwANP27C-BXbHNZA)\\n\\n[Kubernetes \u8c03\u5ea6\u5668 - \u6838\u5fc3\u6d41\u7a0b (\u4e0b\u7bc7)](https://mp.weixin.qq.com/s/vHr56wXPVAl-b4tbnvhS5w)\\n\\n[Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e00\uff09\uff1a\u4ec0\u4e48\u662f GMP](https://mp.weixin.qq.com/s/g4NdoFWrcGmSMeQt8q1XtA)\\n\\n[Kubernetes \u8c03\u5ea6\u5668 - \u6838\u5fc3\u6d41\u7a0b (\u4e0a\u7bc7)](https://mp.weixin.qq.com/s/4hZ6laeQc5P2o2n1yKD_8w)\\n\\n[\u56fe\u6587\u8bb2\u900fGolang\u6807\u51c6\u5e93 net/http\u5b9e\u73b0\u539f\u7406 -- \u670d\u52a1\u7aef](https://mp.weixin.qq.com/s/e7Z_kZrayTFx7y0hlzoTdg)\\n\\n[\u5229\u7528 ChatGPT \u9ad8\u6548\u641c\u7d22Go\u95ee\u9898\uff1a\u4e3e\u4e00\u53cd\u4e09\u7684\u601d\u8003\u65b9\u5f0f\uff0c\u9ad8\u6548\u67e5\u627e\u89e3\u51b3\u65b9\u6848](https://mp.weixin.qq.com/s/b7dHVIVYsL-19gyzUujktA)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#96 Not knowing how to reduce allocations](https://mp.weixin.qq.com/s/d5nczMvDpELt8R5ZB08Yow)\\n\\n[\u4ece\u6162\u901f\u5230SIMG: \u4e00\u4e2aGo\u4f18\u5316\u7684\u6545\u4e8b](https://mp.weixin.qq.com/s/l6Tq_bVDmMpwZg_rPfi1DQ)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[8\u79cd\u4e13\u5751\u540c\u4e8b\u7684 SQL \u5199\u6cd5\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b](https://mp.weixin.qq.com/s/jwAawzeKq_vTTYw58rvgVA)\\n\\n[\u6279\u91cf\u6267\u884cRedis\u547d\u4ee4\u7684\u56db\u79cd\u65b9\u5f0f\uff01](https://mp.weixin.qq.com/s/YF5D3RRvmVXNJ_Njsa1Txw)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1a\u8bbe\u8ba1\u4e00\u4e2a\u5927\u5e76\u53d1\u3001\u5927\u6570\u636e\u7684\u7cfb\u7edf\u67b6\u6784\uff0c\u8bf4\u8bf4\u8bbe\u8ba1\u601d\u8def](https://mp.weixin.qq.com/s/hmO2BKuMMU8ZPxW0lj9ZHw)\\n\\n[\u7801\u54e5\u5b57\u8282 124 \u7bc7\u4f18\u79c0\u6587\u7ae0\u7cbe\u9009](https://mp.weixin.qq.com/s/mspeViqHosmh4kUI8S8ajA)\\n\\n[Kafka\u6027\u80fd\u7bc7\uff1a\u4e3a\u4f55Kafka\u8fd9\u4e48\\"\u5feb\\"](https://mp.weixin.qq.com/s/vzbLWE4JteqjkOFJwcgRhg)\\n\\n[Redis \u6838\u5fc3\u7bc7\uff1a\u552f\u5feb\u4e0d\u7834\u7684\u79d8\u5bc6](https://mp.weixin.qq.com/s/z4VjDaDDbspFz1rIBwazIA)\\n\\n[\u94fe\u8def\u8ffd\u8e2a\u843d\u5730\u8fc7\u7a0b\u4e2d\u7684\u6311\u6218\u4e0e\u89e3\u51b3\u65b9\u6848](https://mp.weixin.qq.com/s/NU-W6rpwH-6_RQnSgbfZqQ)\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1aSentinel\u5e95\u5c42\u6ed1\u52a8\u65f6\u95f4\u7a97\u9650\u6d41\u7b97\u6cd5\u600e\u4e48\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/TbxisH1zzE58u7YoRi04yA)\\n\\n[\u5b57\u8282\u4e8c\u9762\uff1aSpring Boot Redis \u53ef\u91cd\u5165\u5206\u5e03\u5f0f\u9501\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/sMeLfLachYpUq261usr4tQ)\\n\\n[\u7ea0\u6b63\u8bef\u533a\uff1a\u8fd9\u624d\u662f SpringBoot Redis \u5206\u5e03\u5f0f\u9501\u7684\u6b63\u786e\u5b9e\u73b0\u65b9\u5f0f](https://mp.weixin.qq.com/s/nJeRvz7jb4i2eXzc4vpdvw)\\n\\n[\u5206\u5e93\u5206\u8868\u7684 21 \u6761\u6cd5\u5219\uff0chold \u4f4f\uff01](https://mp.weixin.qq.com/s/W5vbjWMG86zEca3CPvAadg)\\n\\n[\u817e\u8baf\u4e8c\u9762\uff1aepoll\u6027\u80fd\u90a3\u4e48\u9ad8\uff0c\u4e3a\u4ec0\u4e48](https://mp.weixin.qq.com/s/DLmXspbokYhQ-j5tLnUMgw)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u6269\u5c55\u4f60\u7684\u524d\u7aef\u77e5\u8bc6\u5e93\uff0c\u6beb\u65e0\u5e9f\u8bdd\uff01](https://mp.weixin.qq.com/s/ZkMc3-T0swxjJ4yujp1R1w)\\n\\n[TypeScript 5.4 beta: NoInfer \u7c7b\u578b\u3001\u95ed\u5305\u7c7b\u578b\u5206\u6790\u4f18\u5316\u3001\u6761\u4ef6\u7c7b\u578b\u5224\u65ad\u4f18\u5316\u7b49](https://mp.weixin.qq.com/s/lRzS_ZoJhzHmuOx0HCDTnw)\\n\\n[\u5347\u7ea7\u5230 React 18 \u7684\u7ecf\u9a8c\u548c\u6559\u8bad](https://mp.weixin.qq.com/s/48cn-JU3uCZkpsi30cloiQ)"},{"id":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-28/index.md","source":"@site/blogs/2024/2024-01-28/index.md","title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-28T00:00:00.000Z","formattedDate":"January 28, 2024","tags":[],"readingTime":6.64,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u5355\u53613\u5c0f\u65f6\u8bad\u7ec3\u4e13\u5c5e\u5927\u6a21\u578bAgent-\u57fa\u4e8eLLaMA Factory\u5b9e\u6218](https://mp.weixin.qq.com/s/DPTDaPkYdhY4KjR3hahKNA)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[#150 Go \u5e76\u53d1\u6a21\u5f0f\u4ecb\u7ecd\u548c\u521b\u65b0\u521b\u9020\u3010Go \u591c\u8bfb\u3011](https://www.bilibili.com/video/BV1Fw41177tk)\\n\\n[\u4e3a\u4ec0\u4e48 Golang Fasthttp \u9009\u62e9\u4f7f\u7528 slice \u800c\u975e map \u5b58\u50a8\u8bf7\u6c42\u6570\u636e](https://mp.weixin.qq.com/s/68Pj0mEJF2Ks9X2pVFk87g)\\n\\n[\u4ece Context \u770b Go \u8bbe\u8ba1\u6a21\u5f0f\uff1a\u63a5\u53e3\u3001\u5c01\u88c5\u548c\u5e76\u53d1\u63a7\u5236](https://mp.weixin.qq.com/s/e03KFBKXUXwzvw3dVPOH-Q)\\n\\n[50 \u6761\u4e89\u8bba\u7684\u6587\u7ae0\u53d1\u751f\u4e86\u5565\uff1aGo \u6807\u51c6\u5e93 encoding/json \u771f\u7684\u6162\u5417](https://mp.weixin.qq.com/s/s63mY3j4oBwpQmB4r4SeWw)\\n\\n[Kubernetes \u63a7\u5236\u5668\u7ba1\u7406\u603b\u7ed3](https://mp.weixin.qq.com/s/uyN2iHJPEjaYlQYpxTJ6bA)\\n\\n[\u4f7f\u7528cmux\u5b9e\u73b0\u7f51\u7edc\u7aef\u53e3\u590d\u7528](https://mp.weixin.qq.com/s/_BQjJT8zqvWrXXdO_YR8lA)\\n\\n[\u6beb\u5dc5\u4e4b\u5fae---\u4e0d\u540c\u5199\u6cd5\u7684\u6027\u80fd\u5dee\u5f02 \u756a\u5916\u7bc7](https://mp.weixin.qq.com/s/LIdlk0p32iW2KDjGHGflMQ)\\n\\n[2024\u5e74\u7684Rust\u4e0eGo](https://mp.weixin.qq.com/s/EWq7-LYcq586U0PXaJeQHw)\\n\\n[Go 1.22 rc2 \u521a\u521a\u53d1\u5e03\uff0c\u591a\u4e2a\u65b0\u7279\u6027\u7b49\u7740\u5927\u5bb6 forloop,math/rand/v2,\u589e\u5f3a http routing](https://mp.weixin.qq.com/s/-mLxdZ5LXYoFKH_RinNqqw)\\n\\n[Go \u670d\u52a1\u7f51\u7edc\u4e0d\u901a\uff1fnet/http\u81ea\u5e26\u7684\u8fd9\u4e2a\u5de5\u5177\u5e2e\u4f60\u5feb\u901f\u5b9a\u4f4d](https://mp.weixin.qq.com/s/8_pJiuOzoQt6xyoLUX0CIw)\\n\\n[golang pprof \u76d1\u63a7\u7cfb\u5217(1) \u2014\u2014 go trace \u7edf\u8ba1\u539f\u7406\u4e0e\u4f7f\u7528](https://mp.weixin.qq.com/s/2BY_93w8iAJOGpsCdgbGtA)\\n\\n[Go \u5b9a\u65f6\u5668\uff1aTimer \u548c Ticker](https://mp.weixin.qq.com/s/IgXFofLEwhYYYUtIZ4_rTA)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1a\u589e\u5f3a http.ServerMux \u8def\u7531\u80fd\u529b\uff0c\u5c06\u6709\u66f4\u5f3a\u7684\u8868\u73b0\u529b\uff01](https://mp.weixin.qq.com/s/gGr1aM1ijBmaejfwW2qqeA)\\n\\n[\u7ec6\u8282\u5bf9\u7ebf\uff0c\u8ba9\u4f60\u5199\u51fa\u66f4\u5b89\u5168\u7684 Dockerfile](https://mp.weixin.qq.com/s/8ZSuq-vYbB62B1TRFF-MGA)\\n\\n[Go \u8bed\u8a00\u4e2d\u9ad8\u6548\u5207\u7247\u62fc\u63a5\u548c GO 1.22 \u63d0\u4f9b\u7684\u65b0\u65b9\u6cd5](https://mp.weixin.qq.com/s/A99rzi-SZ6QvAv8Sia5nGg)\\n\\n[GO \u4e2d\u9ad8\u6548 int \u8f6c\u6362 string \u7684\u65b9\u6cd5\u4e0e\u6e90\u7801\u5256\u6790](https://mp.weixin.qq.com/s/xwNZsIp3qMK532R9CVI31A)\\n\\n[Go\u5408\u96c6 | \u4e0a\u65b0 \u817e\u8bafGo\u5b89\u5168\u6307\u5357](https://mp.weixin.qq.com/s/gFR9WCMeZG9KxUBq11EGXw)\\n\\n[\u300aGo\u9898\u5e93\xb716\u300b\u8bfb\u5199\u9501\u5e95\u5c42\u662f\u600e\u4e48\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/CARzBDS3PSeH-EVrADvozA)\\n\\n[\u300aGo\u9898\u5e93\xb715\u300bgo struct \u80fd\u4e0d\u80fd\u6bd4\u8f83](https://mp.weixin.qq.com/s/wzqKqHhWhJKA0T6V-6SAig)\\n\\n[Kubernetes GC \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/wlS5IYD11HJnS-NqD-BvWA)\\n\\n[Go \u591c\u8bfb\u7b2c 150 \u671f Go \u5e76\u53d1\u6a21\u5f0f\u4ecb\u7ecd\u548c\u521b\u65b0\u521b\u9020](https://mp.weixin.qq.com/s/Ks1BDSw3mSxcxLp3VHObaw)\\n\\n[\u8ddf\u7740\u8001\u732b\u6765\u641eGO-\u5185\u5efa\u5bb9\u5668Map](https://mp.weixin.qq.com/s/KB8BM9jNI5AS6QCG_6fHYw)\\n\\n[\u8fd9\u662f\u6211\u89c1\u8fc7\u6700\u9177\u7684\u670d\u52a1\u7aef\u65e5\u5fd7\u6536\u96c6\u65b9\u6848\uff01](https://mp.weixin.qq.com/s/bBefDLI2psURnUm3LhiAkA)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#95 Not understanding stack vs. heap](https://mp.weixin.qq.com/s/KqjvbhO4zN5oB-lmq0cNkg)\\n\\n[Go \u8bed\u8a00\u5b9e\u6218\uff1a\u6784\u5efa\u5f3a\u5927\u7684\u5ef6\u8fdf\u4efb\u52a1\u961f\u5217](https://mp.weixin.qq.com/s/OkBqiMEnha3SyCxBA0MkRQ)\\n\\n[\u4e3a\u4ec0\u4e48 Go1.22 for \u5faa\u73af\u8981\u652f\u6301\u6574\u6570\u8303\u56f4](https://mp.weixin.qq.com/s/cw7p2EuUTIj1TAcfCdfbew)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u4e07\u5b57\u8be6\u89e3\u5fae\u670d\u52a1\u4e16\u7eaa\u96be\u9898\uff1a\u5982\u4f55\u5e73\u6ed1\u62c6\u5206\u5355\u4f53](https://mp.weixin.qq.com/s/WaD8Go8twTF3CyoZm1ZICQ)\\n\\n[\u6ca1\u7528\u8fc7\u5fae\u670d\u52a1\uff1f\u522b\u614c\uff0c\u4e10\u7248\u67b6\u6784\u56fe\uff0c\u8ba9\u4f60\u8f7b\u677e\u62ff\u634f\u9762\u8bd5\u5b98](https://mp.weixin.qq.com/s/R-w5_FCVBmesVpLNFxWNhw)\\n\\n[\u4ece4\u4e07\u884c\u4ee3\u7801\u964d\u52301.8\u4e07\uff0c\u817e\u8baf\u89c6\u9891\u7adf\u7136\u7528DDD\u505a\u67b6\u6784\u91cd\u6784](https://mp.weixin.qq.com/s/DK3YM3umDfuEIvX77DHdHA)\\n\\n[\u8f6c\u8f6c\u652f\u4ed8\u901a\u9053\u76d1\u63a7\u7cfb\u7edf\u7684\u642d\u5efa](https://mp.weixin.qq.com/s/GVZWeBay7xKniiCHjc0yeg)\\n\\n[\u5fae\u670d\u52a1\u67b6\u6784\u4e0b\u7f51\u5173\u7684\u6280\u672f\u9009\u578b](https://mp.weixin.qq.com/s/27sPoF_p2cjgg_5Kq2hYCA)\\n\\n[Linux\u8fdb\u7a0b\u7ba1\u7406\u5de5\u5177 Supervisor\u8be6\u89e3](https://zhuanlan.zhihu.com/p/147305277)\\n\\n[SpringBoot + SpEL\uff0c\u8f7b\u677e\u641e\u5b9a\u590d\u6742\u6743\u9650\u63a7\u5236\uff0c\u975e\u5e38\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/DA3HoEvCTXPDKvM5EvbXrg)\\n\\n[\u540e\u7aef\u7a0b\u5e8f\u5458\u5fc5\u5907\uff1a\u4e66\u5199\u9ad8\u8d28\u91cfSQL\u768430\u6761\u5efa\u8bae](https://mp.weixin.qq.com/s/IPUAlBmGgsQTGqodLGECLg)\\n\\n[\u4e91\u97f3\u4e50RPC\u7a33\u5b9a\u6027\u5efa\u8bbe\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/8blLwTDT5lGqD2BYqaNlmg)\\n\\n[\u4e34\u65f6\u62b1\u4f5b\u811a\u5fc5\u770b\uff5c\u4e00\u4e2a\u6708\u901f\u901a\u9ad8\u7ea7\u7cfb\u7edf\u67b6\u6784\u8bbe\u8ba1\u5e08\uff01](https://mp.weixin.qq.com/s/l0FJsocKibWWxxW4Uk_mxQ)\\n\\n[\u7b2c\u4e00\u6027\u539f\u7406\uff1a\u517b\u732a\u8fd8\u662f\u8bfb\u5927\u5b66](https://mp.weixin.qq.com/s/azDbatL-bYqoNo08kQbVpQ)\\n\\n[\u7b2c\u4e8c\u904d\u8bfb\u4fde\u519b\u7684\u795e\u4f5c\u300a\u4ea7\u54c1\u65b9\u6cd5\u8bba\u300b\uff0c\u771f\u9999\uff01](https://mp.weixin.qq.com/s/8vVU-UjbA5BFJJRBOSHgeQ)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1aSentinel\u7194\u65ad\u964d\u7ea7\uff0c\u662f\u5982\u4f55\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/DWwkAax0tPj2mqikffJDfg)\\n\\n[\u6df1\u5ea6\u5256\u6790\uff1aRedis\u5206\u5e03\u5f0f\u9501\u5230\u5e95\u5b89\u5168\u5417\uff1f\u770b\u5b8c\u8fd9\u7bc7\u6587\u7ae0\u5f7b\u5e95\u61c2\u4e86\uff01](https://mp.weixin.qq.com/s/s8xjm1ZCKIoTGT3DCVA4aw)\\n\\n[\u641e\u61c2\u5f02\u5730\u591a\u6d3b\uff0c\u770b\u8fd9\u7bc7\u5c31\u591f\u4e86](https://mp.weixin.qq.com/s/T6mMDdtTfBuIiEowCpqu6Q)\\n\\n[\u4e00\u952e\u90e8\u7f72 SpringCloud \u5fae\u670d\u52a1\uff0cyyds\uff01](https://mp.weixin.qq.com/s/HXj5YvANMIpceaspBWjmgg)\\n\\n[Redis\u3001ZooKeeper\u3001Etcd\uff0c\u8c01\u6709\u6700\u597d\u7528\u7684\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/yZC6VJGxt1ANZkn0SljZBg)\\n\\n[\u63d0\u70bc\u8bbe\u8ba1\u6846\u67b6\uff0c\u4e00\u6587\u641e\u61c2Redis/MySQL/Kafka\u4e3a\u4ec0\u4e48\u8fd9\u6837\u8bbe\u8ba1](https://juejin.cn/post/7317926149119721507)\\n\\n[\u817e\u8baf\u4e00\u9762\uff1a32 \u4f4d 4GB \u7cfb\u7edf\uff0c\u8bbf\u95ee 2GB \u6570\u636e\uff0c\u865a\u62df\u5185\u5b58\u4f1a\u53d1\u751f\u4ec0\u4e48](https://mp.weixin.qq.com/s/IfLCzKsqTx_xUQkC4DB9KA)\\n\\n[1.5\u4e07\u5b57+30\u5f20\u56fe\u76d8\u70b9\u7d22\u5f15\u5e38\u89c1\u768411\u4e2a\u77e5\u8bc6\u70b9](https://mp.weixin.qq.com/s/FHt1IehO-XrpojJKsY7tkQ)\\n\\n[\u817e\u8baf\u4e09\u9762\uff1a\u4e00\u53f0\u670d\u52a1\u5668\uff0c\u6700\u5927\u652f\u6301\u7684TCP\u8fde\u63a5\u6570\u662f\u591a\u5c11](https://mp.weixin.qq.com/s/JSnmeL68oOwCZzuLxZrb5Q)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u591a\u7ebf\u7a0b\u7bc7](https://mp.weixin.qq.com/s/IVgGXQKU1QiT1ToN2wXHJg)\\n\\n[\u963f\u91cc\u4e8c\u9762\uff1a\u8981\u4fdd\u8bc1\u6d88\u606f\u4e0d\u4e22\u5931\uff0c\u53c8\u4e0d\u91cd\u590d\uff0c\u6d88\u606f\u961f\u5217\u600e\u4e48\u9009\u578b](https://mp.weixin.qq.com/s/g-vG2d9QaYn_-f3gCa1Jqg)\\n\\n[\u4f7f\u7528\u53cc\u5f02\u6b65\u540e\uff0c\u5982\u4f55\u4fdd\u8bc1\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/2-V0Yf7sHxneKp0PJbYxBg)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n\u865a\u5b9e\u4e4b\u95f4\u6709\u4e00\u671f\u64ad\u5ba2\u8bb2\u300c\u62fc\u591a\u591a\u51fa\u6d77\u7684 - TEMU \u589e\u957f\u80cc\u540e\u9ec4\u94ee\u7684\u521b\u4e1a\u54f2\u5b66\u548c\u4e2d\u4f01\u51fa\u6d77\u4e4b\u8def\u300d\u542c\u4e0b\u6765\u8bb2\u5f97\u5f88\u6709\u903b\u8f91\uff0c\u804a\u5230\u4e86\u5168\u6258\u7ba1\u6a21\u5f0f\u5982\u4f55\u7b80\u5316\uff0c\u62fc\u591a\u591a\u7684\u4f20\u7edf\u6280\u80fd\u4f4e\u4ef7\uff0c\u4ee5\u53ca\u5982\u4f55\u5b9e\u73b0\u7684\u4f4e\u4ef7\uff0c\u5305\u62ec\u4e2d\u56fd\u4f01\u4e1a\u51fa\u6d77\u7684\u51e0\u4e2a\u9636\u6bb5\uff0c\u5f88\u901a\u4fd7\u6613\u61c2\uff0c\u503c\u5f97\u5b66\u4e60\u3002\\n\\nhttps://www.xiaoyuzhoufm.com/episode/657fc03f991e2ee608f54f98\\n\\n\u5f53\u4f60\u60f3\u5c06 feature \u5206\u652f\u4e0a\u7684\u591a\u4e2a commit \u5408\u5e76\u5230 release \u5206\u652f\uff0c\u5e76\u4e14\u5e0c\u671b\u5728 release \u5206\u652f\u4e0a\u53ea\u770b\u5230\u4e00\u4e2a\u5408\u5e76\u63d0\u4ea4\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528 `git merge --squash` \u547d\u4ee4\uff1a\\n\\n```bash\\n# \u786e\u4fdd\u4f60\u5728 release \u5206\u652f\u4e0a\\n$ git checkout release\\n\\n# \u8fdb\u884c squash \u5408\u5e76\\n$ git merge feature --squash\\n\\n# \u5728\u89e3\u51b3\u5b8c\u6240\u6709\u51b2\u7a81\u540e\uff0c\u9700\u8981\u5c06\u5df2\u89e3\u51b3\u7684\u6587\u4ef6\u6dfb\u52a0\u5230\u6682\u5b58\u533a\\n$ git add .\\n\\n# \u63d0\u4ea4\u5408\u5e76\u7ed3\u679c\u4e3a\u4e00\u4e2a\u65b0\u7684\u5355\u4e2a commit\uff08\u6ce8\u610f\uff1a\u8fd9\u91cc\u6ca1\u6709\u81ea\u52a8\u63d0\u4ea4\uff0c\u9700\u8981\u624b\u52a8\u63d0\u4ea4\uff09\\n$ git commit -m \\"Squashed commit from feature-branch: Implemented XYZ feature\\"\\n```\\n\\n> \u6ce8\u610f\uff0c\u5728 GitLab \u63d0 Merge Request\uff0c\u53ef\u4ee5\u5728 Merge Request \u9875\u9762\u4e2d\u52fe\u9009 squash commit \u9009\u9879\\n\\n\u5408\u5e76\u4ee3\u7801\u9047\u5230\u51b2\u7a81\uff0c\u60f3\u56de\u9000\u5230\u5408\u5e76\u524d\u7684\u72b6\u6001\uff1a\\n\\n```bash\\n$ git merge --abort\\n```\\n\\n\u4e00\u4e2a\u5c0f\u6280\u5de7\uff0c`which` \u547d\u4ee4\u53ef\u4ee5\u7528\u6765\u67e5\u627e\u53ef\u6267\u884c\u6587\u4ef6\u7684\u8def\u5f84\uff1a\\n\\n```bash\\n$ which npm\\n\\n/Users/bytedance/.nvm/versions/node/v18.16.0/bin/npm\\n```\\n\\n[\u6846\u67b6\u4e2d\u7684\u7c7b\u578b\u7f16\u7a0b\uff1a Hono \u4e2d\u7684\u6a21\u677f\u5b57\u7b26\u4e32\u7c7b\u578b\u7f16\u7a0b](https://juejin.cn/post/7328564786596544523)\\n\\n[\u6846\u67b6\u4e2d\u7684\u7c7b\u578b\u7f16\u7a0b\uff1atRPC & Prisma \u4e2d\u7684\u6cdb\u578b\u5e94\u7528](https://juejin.cn/post/7328564786596528139)\\n\\n[React 19 \u5373\u5c06\u63a8\u51fa\u7684 4 \u4e2a\u5168\u65b0 Hooks\uff0c\u5f88\u5b9e\u7528\uff01](https://mp.weixin.qq.com/s/KFUikcgNvNw15wqM2wPHJw)\\n\\n[\u6211\u7528\u57cb\u70b9\u8ba9\u8001\u677f\u5b89\u9759 \uff08\u57cb\u70b9\u7bc7\uff09](https://mp.weixin.qq.com/s/1L75-L5eFFjuc4w0qBkXoQ)\\n\\n[Rust\u6027\u80fd\u5f88\u9ad8\uff1f\u4e0d\uff0c\u5b83\u5b8c\u5168\u9876\u4e0d\u4f4f\u6211\u7684\u4ee3\u7801](https://juejin.cn/post/7325993514701635638)\\n\\n[\\\\[\u8bd1\\\\]\u6df1\u5ea6\u89e3\u6790Webpack\u6253\u5305\u8fc7\u7a0b\uff082\u4e07\u5b57\u9884\u8b66\uff09](https://juejin.cn/post/7313423853223985167)\\n\\n[MDH Weekly 119 \u2013 \u300a\u5468\u520a\u91cd\u542f\u548c\u535a\u5ba2\u300b](https://mp.weixin.qq.com/s/3azGXsDFYoqaf0cWYlzDSw)"},{"id":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-21/index.md","source":"@site/blogs/2024/2024-01-21/index.md","title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-21T00:00:00.000Z","formattedDate":"January 21, 2024","tags":[],"readingTime":4.07,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u4e13\u8865\u5927\u6a21\u578b\u77ed\u677f\u7684RAG\u6709\u54ea\u4e9b\u65b0\u8fdb\u5c55\uff1f\u8fd9\u7bc7\u7efc\u8ff0\u8bb2\u660e\u767d\u4e86](https://mp.weixin.qq.com/s/yZo-HcGuWFQE8B63hZkqVQ)\\n\\n[\u7528\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u8ba9\u5927\u6a21\u578b\u66f4\u5f3a\u5927\uff0c\u8fd9\u91cc\u6709\u4e2a\u624b\u628a\u624b\u7684Python\u5b9e\u73b0](https://mp.weixin.qq.com/s/RUdZjQMSlVOfHfhErSNXnA)\\n\\n[Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks](https://ar5iv.labs.arxiv.org/html/2005.11401)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u6162\u804aGolang\u534f\u7a0b\u6c60Ants\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/fZpPkG-C0wZ5Z45H2aUxAA)\\n\\n[Kubernetes Networking Model & CNI](https://mp.weixin.qq.com/s/zCJIZ8lkOmFCe_we2W7fow)\\n\\n[for-range\u4e00\u4e2a\u51fd\u6570\uff0c\u8fd8\u53ef\u4ee5\u8fd9\u4e48\u7528](https://mp.weixin.qq.com/s/NCoM7M1xSx_9gjhfPJhlYw)\\n\\n[\u8ddf\u6211\u4e00\u8d77\u7f16\u5199 Buildpacks\uff1aGo \u7248\u672c\u7bc7](https://mp.weixin.qq.com/s/u4nPO0oohpNlhxDLY92Qiw)\\n\\n[\u63a2\u7d22Cloud Native Buildpacks\u7684\u5947\u5999\u4e16\u754c](https://mp.weixin.qq.com/s/4E1tD-Gzsi196Q8ZxrioJA)\\n\\n[\u54c8\u5570\u4e91\u539f\u751f\u5f39\u6027\u4f38\u7f29\u63a7\u5236\u5668\u5b9e\u73b0\u7ec6\u8282](https://mp.weixin.qq.com/s/UnpVbcGFiVv3xM7K8wQUxA)\\n\\n[\u4f7f\u7528 Rust \u540e\uff0c\u6211\u5199 Go \u7684\u65b9\u6cd5\u90fd\u53d8\u4e86\uff01](https://mp.weixin.qq.com/s/YiCBaFZB5PlPvg8Z9E-tVg)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1aSlices \u53d8\u66f4 Concat\u3001Delete\u3001Insert \u7b49\u51fd\u6570\uff0c\u5bf9\u5f00\u53d1\u633a\u6709\u5e2e\u52a9\uff01](https://mp.weixin.qq.com/s/z886NFcGeKkNm97YhBhc7w)\\n\\n[Go \u7b80\u5355\u8bbe\u8ba1\u548c\u5b9e\u73b0\u53ef\u6269\u5c55\u3001\u9ad8\u6027\u80fd\u7684\u6cdb\u578b\u672c\u5730\u7f13\u5b58](https://mp.weixin.qq.com/s/XApYnOB2H1OhojLbWk_YAA)\\n\\n[Kubernetes HPA \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/vx8i-fPI8g1fT7GGSK41oQ)\\n\\n[\u4ece\u96f6\u5f00\u59cb\uff1a\u4f7f\u7528Prometheus\u4e0eGrafana\u642d\u5efa\u76d1\u63a7\u7cfb\u7edf](https://mp.weixin.qq.com/s/OROQH9DzwFLnfWKmKmrxsA)\\n\\n[\u5341\u5206\u949f\u6559\u4f60\u5728 k8s \u4e2d\u90e8\u7f72\u4e00\u4e2a\u524d\u540e\u7aef\u5e94\u7528](https://mp.weixin.qq.com/s/0JHQE0Ivm1qTopSkwsFs7g)\\n\\n[Go \u591c\u8bfb\u7b2c 149 \u671f\uff1a\u5982\u4f55\u8bbe\u8ba1\u73b0\u4ee3\u4e91\u539f\u751f\u7f51\u5173\uff1a Easegress](https://mp.weixin.qq.com/s/gUh6u8wSYcWPgvyquoqyaA)\\n\\n[Go Context \u5230\u5e95\u653e\u7b2c\u4e00\u4e2a\u53c2\u6570\u4f20\uff0c\u8fd8\u662f\u653e\u7ed3\u6784\u4f53\u91cc](https://mp.weixin.qq.com/s/2PLBKpPuRa5zMY7bJLJXqg)\\n\\n[\u4f18\u96c5\u5224\u65ad interface \u662f\u5426\u4e3a nil](https://mp.weixin.qq.com/s/g04NwXJrxNfHrHJTPKBrXw)\\n\\n[\u9ad8\u6548I/O\u5e76\u53d1\u5904\u7406\uff1a\u53cc\u7f13\u51b2\u548cExchanger](https://mp.weixin.qq.com/s/OrFw2yJuN-Syngpi6rLMzg)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[CPU\u4e2d\u7684\u9ad8\u79d1\u6280\uff1a\u6d41\u6c34\u7ebf\u3001\u8d85\u6807\u91cf\u3001SIMD](https://juejin.cn/post/7293122294788243467)\\n\\n[\u8ba9\u4f60\u7684\u4ee3\u7801\u8fd0\u884c\u66f4\u5feb\uff1a\u638c\u63e1\u96f6\u62f7\u8d1d\u6280\u672f](https://juejin.cn/post/7307146455537238043)\\n\\n[\u7535\u5546\u5e93\u5b58\u7cfb\u7edf\u7684\u9632\u8d85\u5356\u548c\u9ad8\u5e76\u53d1\u6263\u51cf\u65b9\u6848 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7263124928663683132)\\n\\n[\u5411\u4e0a\u7ba1\u7406\uff1a\u8ba9\u4f60\u4e3b\u52a8\u6c47\u62a5\u5c31\u8fd9\u4e48\u96be](https://mp.weixin.qq.com/s/FZ3oN-SARKV-BiCcuu4SLw)\\n\\n[RocketMQ \u4e8b\u52a1\u6d88\u606f\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/H4Lf3ldi6ES5013WDjWtRg)\\n\\n[\u4e91\u97f3\u4e50\u670d\u52a1\u7aef\u53ef\u89c6\u5316\u7f16\u6392\u5e73\u53f0 TangoFlow \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/5vBKKCf_ZHPuHpWtC5Twjw)\\n\\n[\u516b\u5206\u949f\u4e86\u89e3\u4e00\u81f4\u6027\u7b97\u6cd5 -- Raft\u7b97\u6cd5](https://mp.weixin.qq.com/s/iZLKntKlG9847fglMt2A7w)\\n\\n[\u4ee3\u7801\u4e4b\u5916\uff1a\u5de5\u7a0b\u5e08\u7684\u6210\u957f\u8fdb\u9636\u79d8\u7c4d](https://mp.weixin.qq.com/s/FHCq-4yJOm8bT7yTiIkrow)\\n\\n[\u590d\u76d8\u603b\u7ed3\uff0c\u4e0d\u8981\u9519\u5931\u6700\u5927\u8d22\u5bcc](https://mp.weixin.qq.com/s/YU8PVqfoe-1-upazosJFhw)\\n\\n[\u4e3a\u4e86\u8ba9\u5c0f\u767d\u4e5f\u80fd\u770b\u61c2\u8fd9\u4e2a\u6b7b\u9501case\uff0c\u6211\u8bf7\u6765\u4e86\u5c0f\u9ed1](https://mp.weixin.qq.com/s/LqVlSVR6lG6-jGRdEvYixw)\\n\\n[\u963f\u91cc\u4e8c\u9762\uff1a\u8981\u4fdd\u8bc1\u6d88\u606f\u4e0d\u4e22\u5931\uff0c\u53c8\u4e0d\u91cd\u590d\uff0c\u6d88\u606f\u961f\u5217\u600e\u4e48\u9009\u578b](https://mp.weixin.qq.com/s/fvBfKDtZLxNdMWWSLJm_bQ)\\n\\n[SpringCloud \u8fdc\u7a0b\u8c03\u7528\u4e3a\u5565\u8981\u91c7\u7528HTTP\uff0c\u800c\u4e0d\u662fRPC](https://mp.weixin.qq.com/s/Yhn04560RVhYTPKEFDAbIw)\\n\\n[\u4e1a\u52a1\u578b\u56e2\u961f\u5f00\u53d1\u751f\u5b58\u6307\u5357](https://mp.weixin.qq.com/s/tMW3bneEd90ZcoP9VX0VBg)\\n\\n[DDD\u9886\u57df\u9a71\u52a8\u5de5\u7a0b\u843d\u5730\u5b9e\u6218](https://mp.weixin.qq.com/s/g6Zn9oFclF-3Py_VI9AUgQ)\\n\\n[\u652f\u4ed8\u5b9d\uff1a\u591a\u7ebf\u7a0b\u4e8b\u52a1\u600e\u4e48\u56de\u6eda\uff1f\u8bf4\u7528 @Transactional \u53ef\u4ee5\u56de\u53bb\u7b49\u901a\u77e5\u4e86\uff01](https://mp.weixin.qq.com/s/gSxZtSCdSYTHYQwOO9EaKQ)\\n\\n[DDD \u56db\u5c42\u5fae\u670d\u52a1\u67b6\u6784\uff0c\u5f00\u7bb1\u5373\u7528\uff01](https://mp.weixin.qq.com/s/GZRFyAy43AmMJlZiFXH48w)\\n\\n[2 \u4e07\u5b57 + 20\u5f20\u56fe\uff5c \u7ec6\u8bf4 Redis \u4e5d\u79cd\u6570\u636e\u7c7b\u578b\u548c\u5e94\u7528\u573a\u666f](https://mp.weixin.qq.com/s/r9_0xpRsp2ubgyvpiyMfuw)\\n\\n[Redis \u9664\u4e86\u7f13\u5b58\uff0c\u8fd8\u652f\u6301\u54ea\u4e9b\u573a\u666f](https://mp.weixin.qq.com/s/HaGsi29Qxflw0OAOi2dE7g)\\n\\n[Spring Boot + \u89c4\u5219\u5f15\u64ce URule\uff0c\u592a\u5f3a\u4e86\uff01](https://mp.weixin.qq.com/s/r_YJpPvjoz1xBeQQdiVEZw)\\n\\n[\u5355\u79df\u6237\u65f6\u4ee3\uff1aSaaS\u8303\u5f0f\u8f6c\u79fb](https://mp.weixin.qq.com/s/jKv9l_ro6rWei4QnXck-zw)\\n\\n[\u7cfb\u7edf\u7684\u53ef\u89c2\u5bdf\u6027\u662f\u6307\u4ec0\u4e48](https://mp.weixin.qq.com/s/ocxZ1BDiLpR5CT_JKABFNA)\\n\\n[\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u513f\u53eb\u9ad8\u53ef\u7528](https://mp.weixin.qq.com/s/yy31QEaDNkhXcC4T9blxJA)\\n\\n[\u5982\u4f55\u5224\u65ad\u4e1a\u52a1\u505a\u4e0d\u505a\uff0c\u4ec0\u4e48\u662fUE\u6a21\u578b](https://mp.weixin.qq.com/s/aFI60g2nMn_u9kTZk6hjAA)\\n\\n[\u5e76\u53d1\u7f16\u7a0b\u768412\u6761\u89c4\u8303](https://mp.weixin.qq.com/s/crWQn2bT3AqtfmnK9PUKMQ)\\n\\n[\u6027\u80fd\u4f18\u53162.0\uff0c\u65b0\u589e\u7f13\u5b58\u540e\uff0c\u7a0b\u5e8f\u7684\u79d2\u5f00\u7387\u4e0d\u5347\u53cd\u964d](https://mp.weixin.qq.com/s/u_B0AjIi4y73_Yv-m6bNWA)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u524d\u7aef\u6027\u80fd\u4f18\u5316\u624b\u518c - RoadMap](https://mp.weixin.qq.com/s/sLT9Kot_LN4LQFV3STixAw)\\n\\n[React \u4ee3\u7801\u5982\u4f55\u8dd1\u5728\u5c0f\u7a0b\u5e8f\u4e0a](https://mp.weixin.qq.com/s/134VAXPJczElvdYzNFcHhA)\\n\\n[Taro\u7f16\u8bd1mini-runner\u5305\u7684\u4f5c\u7528](https://mp.weixin.qq.com/s/dqhKJQ_bMVfSj6RN0wOtCQ)\\n\\n[\u7a7f\u8d8a\u65f6\u7a7a\uff1a2023\u5e74\u524d\u7aef\u6280\u672f\u76d8\u70b9\u4e0e2024\u5e74\u6280\u672f\u5c55\u671b](https://mp.weixin.qq.com/s/LiygBJqMN8U_vSpAjxMibQ)\\n\\n[Monorepo \u9879\u76ee\u5b9e\u73b0\u5171\u4eab Tailwind \u914d\u7f6e](https://mp.weixin.qq.com/s/ChAhLD9pHfaGo2JIDfczqA)\\n\\n[\u524d\u7aef\u98df\u5802\u6280\u672f\u5468\u520a\u7b2c 111 \u671f\uff1aJS Rising Stars\u30012024 \u5e74\u5982\u4f55\u5199 CSS\u3001\u4e24\u4e2a React\u3001npm \u5e74\u5ea6\u56de\u987e](https://mp.weixin.qq.com/s/-AP9CJe8BRqHKfKUFR5QuA)"},{"id":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-14/index.md","source":"@site/blogs/2024/2024-01-14/index.md","title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-14T00:00:00.000Z","formattedDate":"January 14, 2024","tags":[],"readingTime":6.495,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u4e2d\u4fe1\u5efa\u6295 | AI\u524d\u6cbf\u7cfb\u5217\uff08\u4e00\uff09\uff1a\u6df7\u5408\u4e13\u5bb6\u6a21\u578b\u6280\u672f\uff08MoE\uff09](https://mp.weixin.qq.com/s/KpRT1MCq7ewJw_Heb5-ZrA)\\n\\n[\u300a\u5f00\u6e90\u5927\u6a21\u578b\u98df\u7528\u6307\u5357\u300b\u53d1\u5e03\uff0c7\u4e2a\u5c0f\u65f6\uff0c\u4e00\u676f\u5976\u8336\u901f\u901a\u5927\u6a21\u578b\uff01](https://mp.weixin.qq.com/s/78mSLefUmZOagwZ5dMUyTg)\\n\\n[Stable Diffusion XL Turbo \u6587\u751f\u56fe\u548c\u56fe\u751f\u56fe\u5b9e\u8df5](https://mp.weixin.qq.com/s/0rS1qX37M-4FQT-d2DIsPw)\\n\\n[\u5728 Nvidia Docker \u5bb9\u5668\u7f16\u8bd1\u6784\u5efa\u663e\u5b58\u4f18\u5316\u52a0\u901f\u7ec4\u4ef6 xFormers](https://mp.weixin.qq.com/s/3TgTDsUHCs8tcNLcabqukg)\\n\\n[Amazing OpenAI API\uff1a\u628a\u975e OpenAI \u6a21\u578b\u90fd\u6309 OpenAI API \u8c03\u7528](https://mp.weixin.qq.com/s/Tw8Yr_illbY6MQO4sAMO7g)\\n\\n[\u8282\u7701\u65f6\u95f4\uff1aAI \u6a21\u578b\u9760\u8c31\u4e0b\u8f7d\u65b9\u6848\u6c47\u603b](https://mp.weixin.qq.com/s/5wiz-IaGhGFlbHmRdf1TUA)\\n\\n[\u4fee\u590d OpenCV \u4f9d\u8d56\u9519\u8bef\u7684\u5c0f\u5de5\u5177\uff1aOpenCV Fixer](https://mp.weixin.qq.com/s/PEHW4XJv0D2IN0W92CAi3A)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[Linux 6.8 \u7f51\u7edc\u4f18\u5316, \u5927\u91cf\u5e76\u53d1\u8fde\u63a5\u7684TCP\u6027\u80fd\u63d0\u9ad840%\u5de6\u53f3](https://mp.weixin.qq.com/s/Idp0blvp5WvKRkTw2nD1Xg)\\n\\n[\u6df1\u5165\u63a2\u7d22 Rust \u4e2d\u7684 Panic \u673a\u5236](https://juejin.cn/post/7314144983018782761)\\n\\n[\u63a2\u7a76 Go \u6e90\u7801\u4e2d panic & recover \u6709\u54ea\u4e9b\u5751](https://mp.weixin.qq.com/s/362o7pgILLEWL5NYVwz9Hw)\\n\\n[\u4ece\u300a100 Go Mistakes\u300b\u6211\u603b\u7ed3\u4e86\u4ec0\u4e48](https://mp.weixin.qq.com/s/wXq3Sy1L_ElfTmhLYJiiQw)\\n\\n[3.\u6df1\u5165TiDB\uff1a\u6267\u884c\u4f18\u5316\u8bb2\u89e3](https://mp.weixin.qq.com/s/IRk2lA9aGAa0KAdBY4oXjA)\\n\\n[\u4eb2\u6d4b\u4f53\u9a8cGo\u8bed\u8a00\u6a21\u7cca\u6d4b\u8bd5](https://mp.weixin.qq.com/s/C1YptWtsDw6YGepRpxFAQg)\\n\\n[Go \u53d1\u5e03\u4e86\u4e00\u4e2a\u975e\u5b89\u5168\u8865\u4e01\u7684 Go 1.21.6](https://mp.weixin.qq.com/s/qeEO2zK7mz9JUYocHetBHA)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1a\u65b0\u7684 math/rand/v2 \u5e93\uff0c\u66f4\u5feb\u66f4\u6807\u51c6\uff01](https://mp.weixin.qq.com/s/BsZeSDxHwwSzjLjfjUIgIA)\\n\\n[\u6bcf\u79d2\u767e\u4e07\u6570\u636e\u70b9 Go \u5e94\u7528\u76d1\u63a7\u7cfb\u7edf\u6f14\u8fdb](https://mp.weixin.qq.com/s/ezG3VQLgE2e0AWSxsoBHRg)\\n\\n[\u522b\u518d\u7528GDB\u4e86\uff0c\u4e00\u6587\u638c\u63e1Go\u6700\u597d\u7528\u7684\u8c03\u8bd5\u5668Delve](https://mp.weixin.qq.com/s/Ed39t5I0k0ynfPch-ex7Ag)\\n\\n[Kubernetes CronJob \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/ZNojELz-zTGybcpGgCtfng)\\n\\n[\\\\[go \u9762\u8bd5\\\\] \u5b9e\u73b0\u670d\u52a1\u9ad8\u53ef\u7528\u7684\u7b56\u7565\u548c\u5b9e\u8df5](https://mp.weixin.qq.com/s/-JBLJhU47kocCKXvBe-4uA)\\n\\n[\u6211\u662f\u5982\u4f55\u5b9e\u73b0Go\u6027\u80fd5\u500d\u63d0\u5347\u7684](https://mp.weixin.qq.com/s/HZCqoRgBcT3ZNAlnlChS-Q)\\n\\n[\u6df1\u5165\u7406\u89e3Go\u6807\u51c6\u5e93-ServeMux\u7684\u4f7f\u7528\u4e0e\u6a21\u5f0f\u5339\u914d](https://mp.weixin.qq.com/s/TU9FL2SVe5TW7Uq5I0o_Sg)\\n\\n[\u6df1\u5165\u7406\u89e3Go\u6807\u51c6\u5e93-http server\u7684\u542f\u52a8](https://mp.weixin.qq.com/s/s3BWg6iiCcDZRFh7oZJj5Q)\\n\\n[\u4f7f\u7528 Grafana \u548c Loki \u76d1\u63a7\u4f20\u8bf4\u4e2d\u7684\u6b66\u5f53\u7eb5\u4e91\u68af](https://mp.weixin.qq.com/s/fKFSOA0ZoFLN4dedlRp-HA)\\n\\n[Grafana \u6559\u7a0b - \u6784\u5efa\u4f60\u7684\u7b2c\u4e00\u4e2a\u4eea\u8868\u76d8](https://mp.weixin.qq.com/s/ivK0UmZjvtrJ_WyonwxN2w)\\n\\n[\u6210\u672c\u66f4\u4f4e\u3001\u66f4\u53ef\u63a7\uff0c\u4e91\u539f\u751f\u53ef\u89c2\u6d4b\u65b0\u8ba1\u8d39\u6a21\u5f0f\u6b63\u5f0f\u4e0a\u7ebf](https://mp.weixin.qq.com/s/AbggxNJXCMSAfmuIQ59E8A)\\n\\n[Kubernetes Job \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/FTf4VK1CV-hgf_LgB0T8fA)\\n\\n[\u4f9d\u8d56Kafka\u7684Go\u5355\u5143\u6d4b\u8bd5\u4f8b\u89e3](https://mp.weixin.qq.com/s/M_lV7FaIMxZGd6pZ9dDaAw)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1afor \u5faa\u73af\u4e0d\u518d\u5171\u4eab\u5faa\u73af\u53d8\u91cf\uff0c\u4e14\u652f\u6301\u6574\u6570\u8303\u56f4](https://mp.weixin.qq.com/s/OnvniPEvDz6k5LLKGH1MFA)\\n\\n[Go\u8fd0\u884c\u65f6\u7684\u5e76\u53d1\u539f\u8bed](https://mp.weixin.qq.com/s/Lhw_VFL8UHD9edfbKt_QjQ)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#94 Not being aware of data alignment](https://mp.weixin.qq.com/s/yHWzh89g6Naz0xRmo5FdGw)\\n\\n[Go \u8bed\u8a00\u4e2d defer \u4f7f\u7528\u65f6\u6709\u54ea\u4e9b\u9677\u9631](https://mp.weixin.qq.com/s/g6ohhBBQd0u4PzD1KhnKCA)\\n\\n[Go\u8bed\u8a00\u4e4b\u7236\u7684\u53cd\u601d\uff1a\u6211\u4eec\u505a\u5bf9\u4e86\u4ec0\u4e48\uff0c\u505a\u9519\u4e86\u4ec0\u4e48](https://mp.weixin.qq.com/s/1BTdUMMPIMDobh1ZJ_gXAQ)\\n\\n[\u5b66\u4e60C++20, \u4e3aGo\u7684atomic\u7c7b\u578b\u63d2\u4e0a\u4e00\u53cc\u7fc5\u8180](https://mp.weixin.qq.com/s/Nbc_V5v5QruZsd1PVsDQnA)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u4e00\u5f20\u56fe\u603b\u7ed3\u67b6\u6784\u8bbe\u8ba1\u768440\u4e2a\u9ec4\u91d1\u6cd5\u5219](https://mp.weixin.qq.com/s/eDEjSdf93HE35ndVPpH13A)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898 \u2014 \u67b6\u6784\u8bbe\u8ba1\u7bc7](https://mp.weixin.qq.com/s/Qwj4S4r9Mayy5_HG3ubw7w)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014Spring\u7bc7](https://mp.weixin.qq.com/s/faEtlyaNHW9AWE6LMTs4Ng)\\n\\nmysql \u7684 binlog\u3001redolog\u3001undolog \u662f\u5565\uff1a\\n\\n- Binlog\uff08\u4e8c\u8fdb\u5236\u65e5\u5fd7\uff09\uff1a\\n - \u7528\u4e8e\u590d\u5236\uff1a\u5728\u4e3b\u4ece\u590d\u5236\u4e2d\uff0c\u4ece\u6570\u636e\u5e93\u4f1a\u91cd\u653e\u4e3b\u6570\u636e\u5e93\u4e2d\u5b58\u50a8\u7684 binlog\uff0c\u4ee5\u5b9e\u73b0\u4e3b\u4ece\u540c\u6b65\u3002\\n - \u6570\u636e\u5e93\u6062\u590d\uff1abinlog \u53ef\u4ee5\u7528\u4e8e\u6570\u636e\u5e93\u7684\u6309\u65f6\u95f4\u70b9\u8fd8\u539f\u3002\\n- Redo log\uff08\u91cd\u505a\u65e5\u5fd7\uff09\uff1a\\n - \u786e\u4fdd\u4e8b\u52a1\u7684\u6301\u4e45\u6027\uff1a\u5728\u4e8b\u52a1\u63d0\u4ea4\u524d\uff0credo log \u4f1a\u5c06\u4e8b\u52a1\u7684\u4fee\u6539\u64cd\u4f5c\u8bb0\u5f55\u4e0b\u6765\uff0c\u4ee5\u786e\u4fdd\u5728\u7cfb\u7edf\u5d29\u6e83\u6216\u91cd\u542f\u65f6\uff0c\u53ef\u4ee5\u91cd\u65b0\u6267\u884c\u8fd9\u4e9b\u64cd\u4f5c\u3002\\n - \u9632\u6b62\u810f\u9875\u5199\u5165\uff1a\u5728\u7cfb\u7edf\u5d29\u6e83\u65f6\uff0credo log \u53ef\u4ee5\u9632\u6b62\u810f\u9875\uff08\u672a\u63d0\u4ea4\u7684\u6570\u636e\u9875\uff09\u88ab\u5199\u5165\u78c1\u76d8\u3002\\n- Undo log\uff08\u64a4\u9500\u65e5\u5fd7\uff09\uff1a\\n - \u7528\u4e8e\u4e8b\u52a1\u7684\u56de\u6eda\uff1a\u5728\u4e8b\u52a1\u6267\u884c\u8fc7\u7a0b\u4e2d\uff0cundo log \u8bb0\u5f55\u4e86\u4e8b\u52a1\u4fee\u6539\u524d\u7684\u6570\u636e\u7248\u672c\uff0c\u4ee5\u4fbf\u5728\u4e8b\u52a1\u56de\u6eda\u65f6\u6062\u590d\u6570\u636e\u3002\\n - \u591a\u7248\u672c\u5e76\u53d1\u63a7\u5236\uff08MVCC\uff09\uff1aundo log \u652f\u6301\u6570\u636e\u5e93\u7684\u591a\u7248\u672c\u5e76\u53d1\u63a7\u5236\u673a\u5236\uff0c\u5141\u8bb8\u4e8b\u52a1\u5728\u4e0d\u52a0\u9501\u7684\u60c5\u51b5\u4e0b\u8bfb\u53d6\u4e00\u81f4\u7684\u6570\u636e\u3002\\n\\n\u8fd9\u4e9b\u65e5\u5fd7\u6587\u4ef6\u5728 MySQL \u4e2d\u626e\u6f14\u7740\u4e0d\u540c\u7684\u89d2\u8272\uff0c\u786e\u4fdd\u4e86\u6570\u636e\u5e93\u7684\u4e00\u81f4\u6027\u3001\u6301\u4e45\u6027\u548c\u5e76\u53d1\u63a7\u5236\u3002\\n\\n[\u4f7f\u7528\u61d2\u52a0\u8f7d + \u96f6\u62f7\u8d1d\u540e\uff0c\u7a0b\u5e8f\u7684\u79d2\u5f00\u7387\u63d0\u5347\u81f399.99%](https://mp.weixin.qq.com/s/kaogMK5qz5vkfs9-BYu0Mg)\\n\\n[\u4e07\u5b57+20\u5f20\u56fe\u63a2\u79d8Nacos\u6ce8\u518c\u4e2d\u5fc3\u6838\u5fc3\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/NYH6jgDOp1MwnAUyUHM5yg)\\n\\n[7000\u5b57+30\u5f20\u56fe\u770b\u61c2\u5206\u5e03\u5f0f\u8ffd\u8e2a\u7cfb\u7edf\u539f\u7406](https://mp.weixin.qq.com/s/8CYXOML5LvRlFRpNFOQCjw)\\n\\n[\u62d2\u7edd\u7528\u590d\u6742\u5ea6\u81ea\u6170\uff1a\u4e0b\u4e91\u9ad8\u53ef\u7528\u7684\u79d8\u8bc0](https://mp.weixin.qq.com/s/yIVal-9U6_TXX-dZpVtjBg)\\n\\n[\u516c\u53f8\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528OKR\uff0c\u76ee\u7684\u662f\u4ec0\u4e48](https://mp.weixin.qq.com/s/L-pb5GgWSVJsJa_nnWMVQQ)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1a\u8bf4\u8bf4Rocketmq\u63a8\u6a21\u5f0f\u3001\u62c9\u6a21\u5f0f](https://mp.weixin.qq.com/s/gnRiDUhAvTgjXaQiROB66A)\\n\\n[\u5206\u5e03\u5f0f\u4e8b\u52a1\u6982\u8ff0\u4e0e\u9879\u76ee\u5b9e\u6218](https://mp.weixin.qq.com/s/0Io-X0S9AY-s0HeRb_jbag)\\n\\n[\u5206\u5e03\u5f0f\u9501\u6700\u7ec8\u89e3\u51b3\u65b9\u6848\u662fRedLock\u5417\uff1f\u4e3a\u4ec0\u4e48](https://mp.weixin.qq.com/s/lbSJAv8zJ7NG4G3beNExUA)\\n\\n[\u5237\u4e86\u56db\u767e\u9053\u7b97\u6cd5\u9898\uff0c\u6211\u5728\u9879\u76ee\u91cc\u7528\u8fc7\u51e0\u9053\u5462](https://mp.weixin.qq.com/s/Xna4EDDPvg3vmMUgmsNewQ)\\n\\n[\u70c2\u5927\u8857\u7684\u7f13\u5b58\u7a7f\u900f\u3001\u7f13\u5b58\u51fb\u7a7f\u548c\u7f13\u5b58\u96ea\u5d29\uff0c\u4f60\u771f\u7684\u61c2\u4e86](https://mp.weixin.qq.com/s/MsU0eNt4k7WqpBOQ8CAotA)\\n\\n[\u6296\u97f3\u63d0\u524d\u6279\u4e8c\u9762\uff1a\u4e3a\u5565\u4e0d\u63a8\u8350\u4f7f\u7528\u5916\u952e](https://mp.weixin.qq.com/s/4Q7FzxgkqYCb5fGOARhvDg)\\n\\n[\u589e\u52a0\u7d22\u5f15 + \u5f02\u6b65 + \u4e0d\u843d\u5730\u540e\uff0c\u4ece 12h \u4f18\u5316\u5230 15 min](https://mp.weixin.qq.com/s/V2p_p-KoDowlZxLN2by2Sg)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u6709\u4e86\u5b83 Antd \u6837\u5f0f\u8986\u76d6\u4e0d\u8981\u592a\u723d](https://mp.weixin.qq.com/s/0Tr3tNwl2wwZ3mVqB97mQg)\\n\\n[\u4e00\u6587\u5e26\u4f60\u4ece0\u52301\u505a\u6027\u80fd\u4f18\u5316\u2014\u2014\u56fd\u9645\u5316\u4e1a\u52a1\u4e2d\u53f0\u6027\u80fd\u4f18\u5316\u5b9e\u8df5\uff08\u4e0a\uff09](https://mp.weixin.qq.com/s/SZ-PHb5Mi3KnaEo3yNjR7g)\\n\\nBun \u5982\u4f55\u8bbe\u7f6e npm registry\uff0c\u6709\u65f6\u4f1a\u7528\u5230 bunx \u547d\u4ee4\uff0c\u4f1a\u81ea\u52a8\u4e0b\u8f7d npm \u5305\uff0c\u56e0\u6b64\u9700\u8981\u914d\u7f6e npm registry\uff1a\\n\\n```bash\\n# \u5728\u6839\u76ee\u5f55\u5efa\u4e00\u4e2a `.bunfig.toml` \u914d\u7f6e\u6587\u4ef6\\n$ vi $HOME/.bunfig.toml\\n```\\n\\n\u5199\u5165\u5982\u4e0b\u5185\u5bb9\uff1a\\n\\n```toml\\n[install]\\n# set default registry as a string\\nregistry = \\"https://registry.npmjs.org\\"\\n```\\n\\n> \u53c2\u8003\uff1ahttps://bun.sh/docs/install/registries\\n\\n[\u4e24\u4e2a React](https://mp.weixin.qq.com/s/AKdqtR6DWxB-c4CCmz594g)\\n\\n[2024 \u5e74\u524d\u7aef\u9884\u6d4b](https://mp.weixin.qq.com/s/BO29XPm7c9VKcQT_v9lOGw)\\n\\n[\u4e1a\u52a1\u4e2d\u540e\u53f0\u7528\u6237\u4f53\u9a8c\u4f18\u5316\u65b9\u6cd5\u8bba\u603b\u7ed3\uff08\u4f53\u9a8c\u7bc7\uff09](https://mp.weixin.qq.com/s/vXQR_eTKAYI3_ylXxQJTLA)\\n\\n[\u5206\u4eab4 \u4e2a\u4f60\u53ef\u80fd\u611f\u5174\u8da3\u7684 TikTok \u524d\u7aef\u9762\u8bd5\u9898](https://mp.weixin.qq.com/s/0bzsHVqxoyl9uth3iymp0A)\\n\\n[Chrome \u4e09\u65b9 Cookie \u7981\u7528\u5df2\u6b63\u5f0f\u5f00\u59cb\uff01](https://mp.weixin.qq.com/s/9O7D5mugTmnUuMinQmaEOw)\\n\\n[\u4f7f\u7528 Taro \u5f00\u53d1\u9e3f\u8499\u539f\u751f\u5e94\u7528 \u2014\u2014 \u5feb\u901f\u4e0a\u624b\uff0c\u9e3f\u8499\u5e94\u7528\u5f00\u53d1\u6307\u5357](https://mp.weixin.qq.com/s/FcQocQdxeaQijAA6oUjAZg)"},{"id":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-07/index.md","source":"@site/blogs/2024/2024-01-07/index.md","title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-07T00:00:00.000Z","formattedDate":"January 7, 2024","tags":[],"readingTime":9.405,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[GPT-4 Technical Report](https://ar5iv.labs.arxiv.org/html/2303.08774)\\n\\n[Today\'s top trending papers in Computer Science](https://trendingpapers.com/papers?o=pagerank_growth&pd=Since%20beginning&cc=Cited%20and%20uncited%20papers&c=All%20categories)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u5c0f\u7ea2\u4e66\u53ef\u89c2\u6d4b Metrics \u67b6\u6784\u6f14\u8fdb\uff0c\u5982\u4f55\u5b9e\u73b0\u6570\u5341\u500d\u6027\u80fd\u63d0\u5347](https://mp.weixin.qq.com/s/uJ1t0B8WBBryzvbLWDfl5A)\\n\\n[Java\u4e0eGo\u5230\u5e95\u5dee\u522b\u5728\u54ea\uff0c\u8c01\u8981\u88ab\u65f6\u4ee3\u629b\u5f03](https://mp.weixin.qq.com/s/JkpzM06IWNb11wUaJWJn8Q)\\n\\n\u65e2\u7136\u95ee\u9898\u662f GC \u5360\u7528\u7684 CPU \u8fc7\u9ad8\uff0c\u9996\u5148\u6211\u4eec\u5206\u6790\u4e00\u4e0b CPU \u70ed\u70b9\uff0c\u8fdb\u4e00\u6b65\u786e\u8ba4\u4e00\u4e0b\u95ee\u9898\u3002\\n\\n```bash\\n$ go tool pprof -seconds 30 https://<\u6d4b\u8bd5\u57df\u540d>/debug/pprof/profile\\n```\\n\\n\u8fd9\u4e2a\u547d\u4ee4\u7528\u4e8e\u8fdb\u884c 30s \u7684 CPU \u6027\u80fd\u5206\u6790\uff0c\u5728\u5b8c\u6210\u4e4b\u540e\u4f1a\u8fdb\u5165 profile \u7684\u4ea4\u4e92\u5de5\u5177\uff1a\\n\\n![Alt text](image.png)\\n\\n\u8fd9\u91cc\u76f4\u63a5\u8f93\u5165 top 10 \u53ef\u4ee5\u8f93\u51fa flat \u5360\u6bd4\u6700\u9ad8\u7684 10 \u4e2a\u51fd\u6570\uff0c\u53ef\u4ee5\u770b\u5230 runtime.mallocgc \u7684 cum \u5360\u6bd4\u5df2\u7ecf\u8fbe\u5230\u4e86 15%\uff0c\u5360\u7528\u4e86\u5feb\u5230 3s CPU \u65f6\u95f4\u3002\\n\\nFlat vs Cum\uff1a\\n- Flat \u5360\u6bd4\u662f\u6307\u8fd9\u4e2a\u51fd\u6570\u81ea\u8eab\u7684\u4ee3\u7801\u4f7f\u7528\u4e86\u591a\u5c11 CPU\uff0c\u4e0d\u8ba1\u7b97\u5b50\u51fd\u6570\u7684\u8017\u65f6\u3002\\n- \u800c Cum \u5219\u4ee3\u8868\u8fd9\u4e2a\u51fd\u6570\u5b9e\u9645\u6267\u884c\u6d88\u8017\u4e86\u591a\u5c11 CPU\uff0c\u4e5f\u5c31\u662f\u5305\u62ec\u4e86\u6240\u6709\u7684\u5b50\u51fd\u6570\uff08\u548c\u5b50\u51fd\u6570\u7684\u5b50\u51fd\u6570...\uff09\u7684\u8017\u65f6\u3002\\n\\n\u4ea4\u4e92\u5de5\u5177\u8fd9\u91cc\u8f93\u5165 web \u5c31\u4f1a\u81ea\u52a8\u751f\u6210\u8c03\u7528\u56fe\uff08callgraph\uff09\u5e76\u5728\u6d4f\u89c8\u5668\u91cc\u6253\u5f00 \uff0c\u9650\u4e8e\u6587\u6863\u7a7a\u95f4\u8fd9\u91cc\u53ea\u5c55\u793a\u91cd\u8981\u7684\u90e8\u5206 \uff1a\\n\\n![Alt text](image-1.png)\\n\\n\u5148\u5206\u6790\u4e00\u4e0b\u4e3b\u6d41\u7a0b\uff0c\u8fd9\u91cc\u4e1a\u52a1\u903b\u8f91\u4e00\u5171\u5360\u7528\u4e86 54% \u5de6\u53f3\u7684 CPU\uff08\u6700\u4e0a\u9762\u7684 endpoint.handler \u65b9\u6cd5\uff09\uff0c\u518d\u5f80\u4e0b\u770b\uff0c\u5176\u4e2d 33% \u662f RPC \u8c03\u7528\uff08\u5de6\u4e0b\u89d2\u7684 client.Invoke\uff09\uff0c12% \u662f\u7ed3\u679c\u8f93\u51fa\uff08\u53f3\u8fb9\u7684 endpoint.httpOutput\uff0c\u5305\u62ec\u5199\u51fa HTTP Response\uff0c\u65e5\u5fd7\u4e0a\u62a5\uff0c\u76d1\u63a7\uff09\u3002\u5269\u4e0b 9% \u5de6\u53f3\u5c31\u662f\u5b9e\u9645\u7684\u5404\u79cd\u4e1a\u52a1\u903b\u8f91\u4e86\uff0c\u56e0\u4e3a\u975e\u5e38\u5206\u6563\u4e14\u6ca1\u6709\u96c6\u4e2d\u7684\u70b9\uff0c\u6240\u4ee5\u56fe\u4e0a\u6ca1\u6709\u663e\u793a\u51fa\u6765\u3002\\n\\n\u7eb5\u89c2\u8fd9\u4e2a\u56fe\u53ef\u4ee5\u770b\u51fa\uff0c\u9664\u4e86 HTTP/RPC \u7f51\u7edc\u8c03\u7528\u5360\u7528\u4e86\u5927\u90e8\u5206 CPU \u5916\uff0c\u5e76\u6ca1\u6709\u5176\u4ed6\u5f88\u660e\u663e\u7684 CPU \u70ed\u70b9\uff0c\u8fd9\u5c31\u8ba9\u6700\u540e\u4e00\u4e2a\u70ed\u70b9\u51f8\u663e\u4e86\u51fa\u6765\uff1a\\n\\n![Alt text](image-2.png)\\n\\nGC \u5360\u7528\u7684 CPU \u5728\u8fd9\u6b21 Profiling \u8fc7\u7a0b\u4e2d\u5360\u4e86 15%\uff0c\u6bd4\u4e1a\u52a1\u903b\u8f91\u8fd8\u9ad8\uff01\u5230\u8fd9\u91cc\u57fa\u672c\u786e\u8ba4\uff0cGC \u4e00\u5b9a\u5b58\u5728\u67d0\u4e9b\u95ee\u9898\u3002\\n\\n\u6211\u4eec\u53ef\u4ee5\u7528\u53e6\u4e00\u4e2a pprof \u5de5\u5177 allocs \u6765\u786e\u8ba4\u731c\u6d4b\u662f\u5426\u6210\u7acb\uff0c\u8fd9\u4e2a\u5de5\u5177\u4f1a\u8bb0\u5f55\u5806\u4e0a\u7684\u5bf9\u8c61\u521b\u5efa\u548c\u5185\u5b58\u5206\u914d\uff0c\u53ea\u9700\u8981\u628a\u4e0a\u9762\u7684 HTTP Path \u6700\u540e\u7684 profile \u6362\u6210 allocs \u5373\u53ef\uff1a\\n\\n```bash\\n$ go tool pprof -seconds 30 https://<\u6d4b\u8bd5\u57df\u540d>/debug/pprof/allocs\\n```\\n\\n\u548c CPU Profile \u4e0d\u4e00\u6837\uff0cAllocs \u7684 Profile \u4f1a\u8bb0\u5f55\u56db\u4e2a\u4e0d\u540c\u7684\u4fe1\u606f\uff0c\u53ef\u4ee5\u8f93\u5165 o \u67e5\u770b sample_index \u7684\u53ef\u9009\u503c\uff1a\\n\\n![Alt text](image-3.png)\\n\\n- alloc_object\uff1a\u65b0\u5efa\u5bf9\u8c61\u6570\u91cf\u8bb0\u5f55\uff1b\\n- alloc_space\uff1a\u5206\u914d\u7a7a\u95f4\u5927\u5c0f\u8bb0\u5f55\uff1b\\n- inuse_object\uff1a\u5e38\u9a7b\u5185\u5b58\u5bf9\u8c61\u6570\u91cf\u8bb0\u5f55\uff1b\\n- inuse_space\uff1a\u5e38\u9a7b\u5185\u5b58\u7a7a\u95f4\u5927\u5c0f\u8bb0\u5f55\u3002\\n\\n\u4e00\u822c\u6765\u8bf4\uff0cinuse \u76f8\u5173\u7684\u8bb0\u5f55\u53ef\u4ee5\u7528\u4e8e\u6392\u67e5\u5185\u5b58\u6cc4\u6f0f\uff0cOOM \u7b49\u95ee\u9898\u3002\u8fd9\u91cc\u6211\u4eec\u662f GC \u7684\u95ee\u9898\uff0c\u4e3b\u8981\u548c\u5185\u5b58\u7533\u8bf7\u548c\u91ca\u653e\u6709\u5173\uff0c\u6240\u4ee5\u5148\u770b\u4e0b alloc_space\uff1a\\n\\n\u8f93\u5165\u547d\u4ee4\uff0csample_index=alloc_space\uff0c\u7136\u540e\u518d top 10 \u770b\u4e0b\uff1a\\n\\n![Alt text](image-4.png)\\n\\n\u53ef\u4ee5\u53d1\u73b0\uff0c\u8fd9 30s \u4e00\u5171\u7533\u8bf7\u4e86 1300M \u7684\u5185\u5b58\uff0c\u5176\u4e2d\u7edd\u5927\u591a\u6570\u90fd\u662f\u6846\u67b6\u548c\u6846\u67b6\u7ec4\u4ef6\uff0c\u6bd4\u5982 RPC \u7684\u7f51\u7edc\u8bfb\u53d6\uff08consumeBytes, ReadFrame\uff09\uff0cpb \u7684\u89e3\u6790\u548c\u5e8f\u5217\u5316\uff08marshal\uff09\uff0c\u540d\u5b57\u670d\u52a1\u7684\u9009\u5740\uff08Select\uff09\uff0c\u65e5\u5fd7\u8f93\u51fa\uff08log\uff09\uff0c\u76d1\u63a7\u4e0a\u62a5\uff08ReportAttr\uff09\u3002\u4e5f\u6ca1\u6709\u660e\u663e\u7684\u53ef\u7591\u5bf9\u8c61\u3002\\n\\n\u6211\u4eec\u8fdb\u884c\u4e00\u4e9b\u7b80\u5355\u8ba1\u7b97\uff1a\u8fdb\u884c profiling \u7684\u7ebf\u4e0a\u8282\u70b9\u662f 2C2G \u914d\u7f6e\uff0c\u770b\u76d1\u63a7\u5355\u8282\u70b9\u5927\u7ea6\u662f 800 QPS \u7684\u6d41\u91cf\uff0c\u6240\u4ee5 30s \u5c31\u662f 2w4 \u7684\u8bf7\u6c42\uff0c\u7533\u8bf7\u4e86 1300M \u7684\u7a7a\u95f4\uff0c\u5e73\u5747\u4e00\u4e2a\u8bf7\u6c42\u5c31\u662f\u5927\u7ea6 50KB \u5de6\u53f3\u3002\\n\\n\u8fd9\u4e2a\u91cf\u4e5f\u6bd4\u8f83\u5408\u7406\uff0c\u6bd5\u7adf\u4e00\u6b21\u8bf7\u6c42\u6211\u4eec\u9700\u8981\u50a8\u5b58 HTTP \u5305\u5185\u5bb9\uff0c\u89e3\u6790\u6210\u7ed3\u6784\u4f53\uff0c\u8fd8\u9700\u8981\u8c03\u7528\u4e24\u6b21 RPC \u63a5\u53e3\uff0c\u6700\u540e\u505a\u65e5\u5fd7\u5199\u51fa\u548c\u76d1\u63a7\u4e0a\u62a5\uff0c\u6700\u540e\u518d\u7ed9\u51fa\u8fd4\u56de\u503c\uff0c50KB \u7684\u8d44\u6e90\u4f7f\u7528\u5e76\u4e0d\u7b97\u5927\u3002\u800c\u4e14\u7edd\u5927\u591a\u6570\u90fd\u662f\u6846\u67b6\u4f7f\u7528\uff0c\u5373\u4f7f\u7528\u5bf9\u8c61\u6c60\u628a\u4e1a\u52a1\u4e0a\u7684\u4e00\u4e9b\u5c0f\u5bf9\u8c61\u590d\u7528\uff0c\u5bf9\u8fd9\u4e2a\u5185\u5b58\u7533\u8bf7\u4e5f\u5f71\u54cd\u4e0d\u5927\u3002\\n\\n\u867d\u7136\u8fd9\u4e2a\u6b65\u9aa4\u6ca1\u6709\u6392\u67e5\u5230\u60f3\u67e5\u7684\u95ee\u9898\uff0c\u4f46\u662f\u5374\u53d1\u73b0\u4e86\u4e00\u4e9b\u5176\u4ed6\u7684\u4ee3\u7801\u4e2d\u7684\u5c0f\u95ee\u9898\uff0c\u8fd9\u91cc\u4e5f\u987a\u4fbf\u8bb0\u5f55\u4e0b\u3002\\n\\n\u9996\u5148\uff0c\u4e0a\u9762\u7684 top 10 \u770b\u4e0d\u51fa\u4efb\u4f55\u95ee\u9898\uff0c\u4f46\u662f\u4e3a\u4e86\u4fdd\u9669\u8d77\u89c1\uff0c\u770b\u4e86\u4e00\u4e0b top 20\uff1a\\n\\n![Alt text](image-5.png)\\n\\n\u8fd9\u91cc\u6709\u4e09\u4e2a\u6211\u4eec\u4e1a\u52a1\u4ee3\u7801\u91cc\u7684\u51fd\u6570\uff0cflat \u90fd\u5f88\u5c11\uff0c\u5360\u6bd4\u52a0\u8d77\u6765\u4e5f\u4e0d\u5230 4.5%\uff0c\u4e0d\u8fc7\u65e2\u7136\u53d1\u73b0\u4e86\u4ed6\u4eec \uff0c\u5c31\u6df1\u5165\u770b\u4e00\u4e0b\u51fd\u6570\u91cc\u5404\u884c\u7684\u5206\u914d\u60c5\u51b5\uff0c\u770b\u770b\u6709\u6ca1\u6709\u4ec0\u4e48\u95ee\u9898\u3002\\n\\n[\u53ea\u6539\u4e00\u4e2a\u53c2\u6570\u8ba9Golang GC\u8017\u65f6\u66b4\u964d\u52301/30\uff01](https://mp.weixin.qq.com/s/EEDNuhEr0G4SbTzDhVBjbg)\\n\\n[\u5b57\u8282\u8df3\u52a8\u4e91\u539f\u751f\u6210\u672c\u6cbb\u7406\u843d\u5730\u5b9e\u8df5](https://mp.weixin.qq.com/s/GFYudlHBuIr_bDe6IX4mlw)\\n\\n[Go \u7684 DDD \u5de5\u7a0b\u5316\u9879\u76ee\u5b9e\u8df5](https://juejin.cn/post/7298160530292703244)\\n\\n[Rust \u7684\u6240\u6709\u6743\u3001\u501f\u7528\u548c\u751f\u547d\u5468\u671f](https://juejin.cn/post/7279313746450235403)\\n\\n[Kubernetes Deployment \u6eda\u52a8\u66f4\u65b0\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/c4LWdwACitC2gH2tDu3E8g)\\n\\n[\\\\[go \u9762\u8bd5\\\\] \u5206\u5e03\u5f0f\u4e8b\u52a1\u6846\u67b6\u9009\u62e9\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/vQz2-KhRenuimU7jvHtkkQ)\\n\\n[\u6211\u662f\u5982\u4f55\u5b9e\u73b0Go\u6027\u80fd5\u500d\u63d0\u5347\u7684](https://mp.weixin.qq.com/s/SlPdSoMs1po1l19uaNMrIQ)\\n\\n[\u5b8c\u5584 Golang Gin \u6846\u67b6\u7684\u9759\u6001\u4e2d\u95f4\u4ef6\uff1aGin-Static](https://mp.weixin.qq.com/s/4ZT1Pu_lR56LmIQjFmy9Kg)\\n\\n[Kubernetes \u4e3a\u4ec0\u4e48\u9700\u8981 Ingress](https://mp.weixin.qq.com/s/uuB97dnIHe0hxsoBrk6THg)\\n\\n[Uber Go \u51fa\u4e86\u4e2a\u9759\u6001\u5206\u6790\u5de5\u5177 NilAway\uff0c\u8fd8\u633a\u5b9e\u7528\uff01](https://mp.weixin.qq.com/s/vDmSnZZXg1EnyeFMuj6orw)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#93 Not taking into account instruction-level](https://mp.weixin.qq.com/s/oVSJz7MIUR7HNhU-hKnCJg)\\n\\n[Rust\u4f7f\u7528gRPC](https://mp.weixin.qq.com/s/a_v6_F6nqGlDcBUKyEQF2w)\\n\\n[\u8fd9\u4e9b\u6d41\u884c\u7684K8S\u5de5\u5177\uff0c\u4f60\u90fd\u7528\u4e0a\u4e86\u5417](https://mp.weixin.qq.com/s/6bgFUadhbCqDAwNgGsXgGg)\\n\\n[Go\u6d4b\u8bd5\u768420\u4e2a\u5b9e\u7528\u5efa\u8bae](https://mp.weixin.qq.com/s/yJqwcYqYmV1wWuo147fX4Q)\\n\\n[\u300e\u6bcf\u5468\u8bd1Go\u300fGo \u7684\u62a2\u5360\u5f0f\u8c03\u5ea6\uff08\u6587\u672b\u6709\u5f69\u86cb\uff09](https://mp.weixin.qq.com/s/d7FdGBc0S0V3S4aRL4EByA)\\n\\n[\u4e86\u89e3go\u5728\u534f\u7a0b\u8c03\u5ea6\u4e0a\u7684\u6539\u8fdb](https://mp.weixin.qq.com/s/YXxFVBrwlwf3YpIUhXFmTQ)\\n\\n[Go \u8bed\u8a00\u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u5e76\u53d1\u8bfb\u5199 map](https://mp.weixin.qq.com/s/n6K6tbDRdS5c0hMtmHxdFg)\\n\\n[\u7b2c\u4e00\u7bc7 \u65e7\u8bdd\u91cd\u63d0\uff1a\u83b7\u53d6\u548c\u5229\u7528 goroutine id, machine id \u548c process id](https://mp.weixin.qq.com/s/dePs661VzQf_yi2aHsydIA)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[HBase\u6df1\u5ea6\u5386\u9669 | \u4eac\u4e1c\u7269\u6d41\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7315959676886450211)\\n\\n\u9879\u76ee\u4e2d\u9047\u5230\u4e00\u4e2a\u95ee\u9898\uff0c\u9700\u8981\u8bb0\u4f4f\u5f39\u7a97\u9891\u63a7\uff0c\u4e00\u822c\u6765\u8bf4\u8ddf\u7740\u8bbe\u5907\u8d70\uff0c\u4e5f\u5c31\u662f\u5728\u524d\u7aef\u7f13\u5b58\u3002\u5982\u679c\u9700\u8981\u4ee5\u7528\u6237\u7ef4\u5ea6\uff0c\u9700\u8981\u600e\u4e48\u8bbe\u8ba1\uff0c\u53ef\u4ee5\u7528 Redis Bitmap \u5b9e\u73b0\u3002\\n\\n[Redis Bitmap\uff1a\u5b9e\u73b0\u5343\u4e07\u7ea7\u7528\u6237\u7b7e\u5230\u7684\u79d8\u5bc6\u6b66\u5668](https://juejin.cn/post/7273025562155466764)\\n\\n[\u8fd9\u4e9b\u5e74\u5728\u963f\u91cc\u5b66\u5230\u7684\u65b9\u6cd5\u8bba](https://mp.weixin.qq.com/s/yPRPakU1UM5iVY-1bwiHJQ)\\n\\n[\u67b6\u6784\u9762\u8bd5\uff1a\u5168\u94fe\u8def\u538b\u6d4b\uff0c\u4f60\u662f\u600e\u4e48\u8bbe\u8ba1\u7684](https://mp.weixin.qq.com/s/MyK6QrNt3xtms_IBAb6sSQ)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1a\u5982\u4f55\u4fdd\u8bc1RocketMQ\u6d88\u606f\u6709\u5e8f\uff1f\u5982\u4f55\u89e3\u51b3RocketMQ\u6d88\u606f\u79ef\u538b](https://mp.weixin.qq.com/s/ofaQwaOobZ_5xqcor6ObhA)\\n\\n[\u7f51\u6613\u9762\u8bd5\uff1a\u4ebf\u7ea7\u7528\u6237\uff0c\u5982\u4f55\u505a\u5fae\u670d\u52a1\u5e95\u5c42\u67b6\u6784](https://mp.weixin.qq.com/s/3w5Ld8zgc8DeTmoo7T31qw)\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1a\u4ebf\u7ea7\u6570\u636e \u5728\u7ebf\u7edf\u8ba1\uff0c\u5982\u4f55\u5b9e\u73b0](https://mp.weixin.qq.com/s/PRouD97LKd726m_aW5DWFw)\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1aES+Redis+MySQL\u9ad8\u53ef\u7528\uff0c\u5982\u4f55\u8bd5\u5b9e\u73b0](https://mp.weixin.qq.com/s/SXsQ3T5SFK0SKg054m-7Mg)\\n\\n[\u5b57\u8282\u9762\u8bd5\uff1aDDD\u67b6\u6784\uff0c\u5982\u4f55\u843d\u5730](https://mp.weixin.qq.com/s/_NAHYDIvmT7EbffXkIpqYw)\\n\\n[\u5fae\u670d\u52a1\u4e0b\u5fc5\u987b\u4e86\u89e3\u76844\u79cd\u90e8\u7f72\u7b56\u7565\uff01](https://mp.weixin.qq.com/s/c9sioXo95QQmZ7AyQxFBtw)\\n\\n[\u81ea\u4ece\u7528\u4e86\u8fd9\u6b3e\u94fe\u8def\u8ffd\u8e2a\u7cfb\u7edf\uff0c\u7761\u89c9\u771f\u9999\uff01\uff01](https://mp.weixin.qq.com/s/QzG3MupskxyV8eaGt2YOXw)\\n\\n[\u9006\u98ce\u65f6\u523b\uff0c\u7ba1\u7406\u52a8\u4f5c\u6216\u6210\u566a\u97f3](https://mp.weixin.qq.com/s/EtPcGw3dYsKbd411FbZ0bA)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u67b6\u6784\u8bbe\u8ba1\u7bc7](https://mp.weixin.qq.com/s/w7xUHPCZZuCX_Is1eT5uZQ)\\n\\n[\u8fd8\u5f97\u662f\u817e\u8baf\uff0c\u635e\u4e86\u6211\u4e00\u628a\uff01](https://mp.weixin.qq.com/s/Qwc0xsrOVD4ZTHohAb01yw)\\n\\n[\u6587\u672b\u798f\u5229\u4e282023\u54d4\u54e9\u54d4\u54e9\u6280\u672f\u7cbe\u9009\u6280\u672f\u5e72\u8d27](https://mp.weixin.qq.com/s/zgymXmxo5kiKPG7QRs6Uiw)\\n\\n[\u80fdping\u901a\uff0cTCP\u5c31\u4e00\u5b9a\u80fd\u8fde\u901a\u5417](https://mp.weixin.qq.com/s/gLrRgfwmzMvk9T6MIY4cWg)\\n\\n[\u5fae\u670d\u52a1\u5168\u505a\u9519\u4e86\uff01\u8c37\u6b4c\u63d0\u51fa\u65b0\u65b9\u6cd5\uff0c\u6210\u672c\u76f4\u63a5\u964d9\u500d\uff01](https://mp.weixin.qq.com/s/rezUShZLEK_3f3Cfl2b_fw)\\n\\n[\u5907\u8003\u4e24\u5e74\uff0c\u5173\u4e8e\u8f6f\u8003\u7684\u7ecf\u9a8c\u90fd\u5728\u8fd9\u4e86](https://mp.weixin.qq.com/s/Ijh0taMzh7MUnuysjCB4gQ)\\n\\n[\u6211\u5728\u963f\u91cc\u505a\u5f00\u53d1\u7684\u9ad8\u6548\u6253\u5de5\u6280\u5de7\u603b\u7ed3](https://mp.weixin.qq.com/s/EwdKRsu_U39bTJf4hbjIeA)\\n\\n[\u4e00\u6587\u8bb2\u900f\u6d88\u606f\u961f\u5217RocketMQ\u5b9e\u73b0\u6d88\u8d39\u5e42\u7b49](https://juejin.cn/post/7313242116771627034)\\n\\n[\u8ba2\u5355\u573a\u666f-\u57fa\u4e8eRedisson\u5b9e\u73b0\u8ba2\u5355\u53f7\u751f\u6210](https://juejin.cn/post/7307467803975843891)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u3010\u7b2c3162\u671f\u3011\u524d\u7aefAPM\u6307\u6807\u91c7\u96c6\u5927\u5192\u9669](https://mp.weixin.qq.com/s/u78Dr9DfLyCMAH8aTil5Lg)\\n\\n[2023\u5e74\u6700\u706b\u7684\u524d\u7aef\u9879\u76ee\u51fa\u7089\uff0c\u7adf\u7136\u662f\u5b83](https://mp.weixin.qq.com/s/ENkssTfPQmS5_PjdIcXpBA)\\n\\n[\u4f60\u7684\u7f51\u7ad9\u6216\u8bb8\u4e0d\u9700\u8981\u524d\u7aef\u6784\u5efa\uff08\u4e8c\uff09](https://mp.weixin.qq.com/s/2Cm7iBMTZk-YqX7G0WfwRQ)\\n\\n[2023 \u5e74 Node.js \u6027\u80fd\u72b6\u6001](https://mp.weixin.qq.com/s/hEYGSa__fKr67nVjR1DFWA)\\n\\n[\u3010\u7b2c3157\u671f\u3011\u89e3\u9501\u524d\u7aef\u65b0\u6f5c\u80fd\uff1a\u5982\u4f55\u4f7f\u7528 Rust \u9508\u5316\u524d\u7aef\u5de5\u5177\u94fe](https://mp.weixin.qq.com/s/Zlc-G6oD63mpSUVBiOs6FA)\\n\\n[\u524d\u7aef\u98df\u5802\u6280\u672f\u5468\u520a\u7b2c 110 \u671f\uff1aVue3.4\u3001\u65b0\u7248 Vue DevTools \u5f00\u6e90\u3001AI 2023 \u5e74\u5ea6\u603b\u7ed3\u5408\u96c6](https://mp.weixin.qq.com/s/yre8fxml3Sgykr4iG8_BSw)"}]}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[8621],{54197:n=>{n.exports=JSON.parse('{"blogPosts":[{"id":"welcome","metadata":{"permalink":"/frontend-weekly/2024/welcome","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-12-12-welcome/index.md","source":"@site/blogs/2024/2024-12-12-welcome/index.md","title":"\u7f6e\u9876\u5185\u5bb9","description":"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01","date":"2024-12-12T00:00:00.000Z","formattedDate":"December 12, 2024","tags":[{"label":"TypeScript","permalink":"/frontend-weekly/2024/tags/type-script"},{"label":"\u524d\u7aef\u6846\u67b6","permalink":"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6"},{"label":"Webpack","permalink":"/frontend-weekly/2024/tags/webpack"},{"label":"\u6e90\u7801\u7cfb\u5217","permalink":"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217"},{"label":"\u4e1a\u52a1\u6210\u957f","permalink":"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f"},{"label":"\u6027\u80fd\u4f18\u5316","permalink":"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316"},{"label":"\u7ec4\u4ef6\u5e93\u5b9e\u6218","permalink":"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218"},{"label":"\u7f51\u7edc\u76f8\u5173","permalink":"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173"},{"label":"\u673a\u5668\u5b66\u4e60","permalink":"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60"},{"label":"Java","permalink":"/frontend-weekly/2024/tags/java"},{"label":"Golang","permalink":"/frontend-weekly/2024/tags/golang"}],"readingTime":144.44,"hasTruncateMarker":true,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"welcome","title":"\u7f6e\u9876\u5185\u5bb9","authors":["garfield"],"tags":["TypeScript","\u524d\u7aef\u6846\u67b6","Webpack","\u6e90\u7801\u7cfb\u5217","\u4e1a\u52a1\u6210\u957f","\u6027\u80fd\u4f18\u5316","\u7ec4\u4ef6\u5e93\u5b9e\u6218","\u7f51\u7edc\u76f8\u5173","\u673a\u5668\u5b66\u4e60","Java","Golang"]},"nextItem":{"title":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"\u2b50\ufe0f \u6bcf\u5468\u66f4\u65b0\u4f18\u8d28\u6280\u672f\u6587\u7ae0\uff0c\u6b22\u8fce\u70b9\u8d5e\u5173\u6ce8\uff01\\n\\n\x3c!--truncate--\x3e\\n\\n## TypeScript \u5de5\u7a0b\u5316\u65b9\u6848\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357](https://zhuanlan.zhihu.com/p/403970666)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u90fd 2022 \u5e74\u4e86\uff0c\u624b\u52a8\u642d\u5efa React \u5f00\u53d1\u73af\u5883\u5f88\u96be\u5417](https://juejin.cn/post/7087811040591675428)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4f1a\u5199 TypeScript \u4f46\u4f60\u771f\u7684\u4f1a TS \u7f16\u8bd1\u914d\u7f6e\u5417\uff1f](https://juejin.cn/post/7039583726375796749#heading-22)\\n- \ud83c\udf1b [\u3010\u5f00\u6e90\u3011\u4e00\u4e2a React + TS \u9879\u76ee\u6a21\u677f](https://juejin.cn/post/6844904102355271694)\\n - \u4e00\u79cd\u662f\u4f7f\u7528 ts-loader + babel-loader + fork-ts-checker-webpack-plugin \u901a\u8fc7 typescript \u8fdb\u884c\u7f16\u8bd1\u548c\u7c7b\u578b\u68c0\u67e5\\n - \u53e6\u4e00\u79cd\u662f babel-loader + @babel/preset-typescript \u4f7f\u7528 babel \u8fdb\u884c\u7f16\u8bd1\uff0ctypescript \u53ea\u8d1f\u8d23\u7c7b\u578b\u68c0\u67e5\uff08babel 7 \u4ee5\u4e0a\uff09\\n- \ud83c\udf1b [2021\u5e74\u4ece\u96f6\u5f00\u53d1\u524d\u7aef\u9879\u76ee\u6307\u5357](https://juejin.cn/post/6999807899149008910)\\n- [Webpack \u8f6c\u8bd1 Typescript \u73b0\u6709\u65b9\u6848](https://juejin.cn/post/6844904052094926855)\\n- \ud83c\udf1b [\u4f7f\u7528ESLint+Prettier\u6765\u7edf\u4e00\u524d\u7aef\u4ee3\u7801\u98ce\u683c](https://segmentfault.com/a/1190000015315545)\\n- \ud83c\udf1b [\u7528 husky \u548c lint-staged \u6784\u5efa\u8d85\u6e9c\u7684\u4ee3\u7801\u68c0\u67e5\u5de5\u4f5c\u6d41](https://segmentfault.com/a/1190000009546913)\\n\\n## TS \u9ad8\u7ea7\u6280\u5de7\\n\\n- \u2b50\ufe0f [\u4f60\u9700\u8981\u77e5\u9053\u7684TypeScript\u9ad8\u7ea7\u7c7b\u578b](https://mp.weixin.qq.com/s/usDh1-Wzxrf4BftfWhwduA)\\n- \ud83c\udf1b [Typescript \u7c7b\u578b\u7f16\u7a0b\uff0c\u4ece\u5165\u95e8\u5230\u901a\u8fbe](https://mp.weixin.qq.com/s/WsldmkW2ovp-okxSY3le9g)\\n- \ud83c\udf1b [\u5982\u4f55\u8fdb\u9636TypeScript\u529f\u5e95\uff1f\u4e00\u6587\u5e26\u4f60\u7406\u89e3TS\u4e2d\u5404\u79cd\u9ad8\u7ea7\u8bed\u6cd5](https://juejin.cn/post/7089809919251054628)\\n- \ud83c\udf1b [TypeScript\u4ece\u5e73\u51e1\u5230\u4e0d\u51e1\uff08\u57fa\u7840\u7bc7\uff09](https://juejin.cn/post/6998785406619615269)\\n- \ud83c\udf1b [\u63a8\u835012\u4e2a\u503c\u5f97\u5b66\u4e60\u7684TypeScript\u5b9d\u5e93\uff01](https://juejin.cn/post/7150668738990178312)\\n- \ud83c\udf1b [TypeScript \u7c7b\u578b\u7cfb\u7edf\uff1a\u5206\u5e03\u5f0f\u6761\u4ef6\u7c7b\u578b\u5168\u89e3](https://mp.weixin.qq.com/s/TUv8Cu6_ftQQ6lEWAwIa4w)\\n- \ud83c\udf1b [\u63a5\u8fd1\u5929\u82b1\u677f\u7684TS\u7c7b\u578b\u4f53\u64cd\uff0c\u770b\u61c2\u4f60\u5c31\u80fd\u73a9\u8f6cTS\u4e86](https://juejin.cn/post/7061556434692997156)\\n- \ud83c\udf1b [TypeScript \u7c7b\u578b\u7f16\u7a0b: \u4ece\u57fa\u7840\u5230\u7f16\u8bd1\u5668\u5b9e\u6218](https://mp.weixin.qq.com/s/-x8iVK-hlQd3-OZDC04A5A)\\n- \ud83c\udf1b [\u77e5\u5176\u7136\uff0c\u77e5\u5176\u6240\u4ee5\u7136\uff1aTypeScript \u4e2d\u7684\u534f\u53d8\u4e0e\u9006\u53d8](https://juejin.cn/post/7050099282317148174)\\n- \u2b50\ufe0f [TypeScript\u662f\u5982\u4f55\u5de5\u4f5c\u7684](https://juejin.cn/post/7007251289721536543)\\n- \u2b50\ufe0f [TypeScript \u9ad8\u7ea7\u7528\u6cd5](https://juejin.cn/post/6964692485415108645)\\n- \u2b50\ufe0f [\u629b\u7816\u5f15\u7389\uff1aTypeScript \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://mp.weixin.qq.com/s/owtE_7PVLyz5XqwGofaTZg)\\n- \u2b50\ufe0f [\u7ec6\u6570\u8fd9\u4e9b\u5e74\u88ab\u56f0\u6270\u8fc7\u7684 TS \u95ee\u9898](https://juejin.cn/post/6871752423577223176)\\n- [TS \u5e38\u89c1\u95ee\u9898\u6574\u7406\uff0860\u591a\u4e2a\uff0c\u6301\u7eed\u66f4\u65b0ing\uff09](https://juejin.cn/post/6844904055039344654)\\n- [Ts\u9ad8\u624b\u7bc7\uff1a22\u4e2a\u793a\u4f8b\u6df1\u5165\u8bb2\u89e3Ts\u6700\u6666\u6da9\u96be\u61c2\u7684\u9ad8\u7ea7\u7c7b\u578b\u5de5\u5177](https://juejin.cn/post/6994102811218673700)\\n\\n## TS && \u6846\u67b6\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4e00\u4efd\u5f88\u5168\u9762\u7684 React TypeScript \u5907\u5fd8\u5f55](https://react-typescript-cheatsheet.netlify.app/)\\n\x3c!-- - \u2b50\ufe0f \u2b50\ufe0f [\u4f7f\u7528 TypeScript \u7f16\u5199 React \u7684\u6700\u4f73\u5b9e\u8df5\uff01](https://mp.weixin.qq.com/s/o_cXCroRSK5HAKG0wjC29Q) --\x3e\\n- \u2b50\ufe0f \u2b50\ufe0f [React + TypeScript\u5b9e\u8df5](https://juejin.cn/post/6952696734078369828)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86](https://juejin.cn/post/7071066976830881823)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357](https://juejin.cn/post/7069555976717729805)\\n- [\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript](https://juejin.cn/post/7058868160706904078)\\n- [TypeScript \u7ec8\u6781\u521d\u5b66\u8005\u6307\u5357](https://mp.weixin.qq.com/s/6DAyXFHIMW95FS0f3GyHpA)\\n- [\u5982\u4f55\u4f18\u96c5\u5730\u5728 React \u4e2d\u4f7f\u7528TypeScript\uff0c\u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01](https://juejin.cn/post/7021674818621669389)\\n- [\u7cbe\u8bfb\u300a@types react \u503c\u5f97\u6ce8\u610f\u7684 TS \u6280\u5de7\u300b](https://juejin.cn/post/6844904122550845448)\\n- [\u300c1.9W\u5b57\u603b\u7ed3\u300d\u4e00\u4efd\u901a\u4fd7\u6613\u61c2\u7684 TS \u6559\u7a0b\uff0c\u5165\u95e8 + \u5b9e\u6218\uff01](https://juejin.cn/post/7068081327857205261)\\n- \u2b50\ufe0f [Vue3.0 \u524d\u7684 TypeScript \u6700\u4f73\u5165\u95e8\u5b9e\u8df5](https://juejin.cn/post/6844903865255477261)\\n - \u867d\u7136\u4e0d\u662f Vue3 \u4f46\u662f\u4e5f\u63a8\u8350\u770b\u4e0b\\n\\n## \u524d\u7aef\u6846\u67b6\\n\\n- [\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e Vue \u6587\u7ae0](https://juejin.cn/post/7047705995534925832)\\n- [\u76d8\u70b9\u6398\u91d1 2021 \u9ad8\u8d5e React \u6587\u7ae0](https://juejin.cn/post/7047690546417565733)\\n- [\u76d8\u70b9\u6398\u91d1 2021 \u70b9\u8d5e\u9ad8\u8fbe 6000\uff0c\u6536\u85cf\u8fc7\u4e07\u7684\u6587\u7ae0](https://juejin.cn/post/7047153016771706916)\\n- \u2b50\ufe0f [\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a](https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q)\\n- \u2b50\ufe0f [Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09](https://juejin.cn/post/6844903913410314247)\\n- \u2b50\ufe0f [\\\\[\u79d1\u666e\u6587\\\\] Vue3 \u5230\u5e95\u66f4\u65b0\u4e86\u4ec0\u4e48\uff1f](https://mp.weixin.qq.com/s/66sos7nML5rA0ZZGJ5qFIQ)\\n- \u2b50\ufe0f [\u63ed\u79d8 Vue.js \u4e5d\u4e2a\u6027\u80fd\u4f18\u5316\u6280\u5de7](https://juejin.cn/post/6922641008106668045)\\n- \ud83c\udf1b [\u6211\u5728\u9879\u76ee\u4e2d\u7528\u5b9e\u9645\u7528\u5230\u768422\u4e2aVue\u4f18\u5316\u6280\u5de7](https://juejin.cn/post/7005880217684148231)\\n- \ud83c\udf1b [React Hooks \u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6844904165500518414)\\n- \ud83c\udf1b [React Hooks \u4f7f\u7528\u8bef\u533a\uff0c\u9a73\u5b98\u65b9\u6587\u6863](https://juejin.cn/post/7046358484610187277)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b9d\u554a\uff5e\u6765\u804a\u804a 9 \u79cd React Hook](https://juejin.cn/post/7043772161596588046)\\n- \u2b50\ufe0f [\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684\u6d41\u5f0f React Hooks\uff08\u5173\u4e8e\u7ec4\u7ec7\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5\uff09](https://juejin.cn/post/6933018383961194509)\\n- \u2b50\ufe0f [\u4ece 16 \u4e2a\u65b9\u5411\u9010\u6b65\u642d\u5efa\u57fa\u4e8e vue3 \u7684\u524d\u7aef\u67b6\u6784](https://juejin.cn/post/7025524870842679310#heading-58)\\n- \u2b50\ufe0f [34\u6761\u6211\u80fd\u544a\u8bc9\u4f60\u7684Vue\u4e4b\u5b9e\u64cd\u7bc7](https://juejin.cn/post/6874007172578033677)\\n- \ud83c\udf1b [React \u4f53\u7cfb\u4e0b\u5173\u4e8e Mobx \u4e0e Redux \u7684\u4e00\u4e9b\u601d\u8003](https://zhuanlan.zhihu.com/p/461844358)\\n- \ud83c\udf1b [\u4f7f\u7528 React&Mobx \u7684\u51e0\u4e2a\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/aOapwk4_qi8tNM7vaa7jGA)\\n- \u2b50\ufe0f [\u5f53\u8bbe\u8ba1\u6a21\u5f0f\u9047\u4e0a Hooks](https://juejin.cn/post/6995834232350179336)\\n- \u2b50\ufe0f \u2b50\ufe0f [React Hooks \u8be6\u89e3 \u3010\u8fd1 1W \u5b57\u3011+ \u9879\u76ee\u5b9e\u6218](https://juejin.cn/post/6844903985338400782)\\n- [\u300cReact\u8fdb\u9636\u300d\u53ea\u7528\u4e24\u4e2a\u81ea\u5b9a\u4e49 Hooks \u5c31\u80fd\u66ff\u4ee3 React-Redux ?](https://juejin.cn/post/6989022564043456543)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300d React\u5168\u90e8api\u89e3\u8bfb+\u57fa\u7840\u5b9e\u8df5\u5927\u5168(\u592f\u5b9e\u57fa\u78402\u4e07\u5b57\u603b\u7ed3)](https://juejin.cn/post/6950063294270930980)\\n- [\u300cReact\u8fdb\u9636\u300d\u63a2\u6848\u63ed\u79d8\u516d\u79cdReact\u2018\u7075\u5f02\u2019\u73b0\u8c61](https://juejin.cn/post/6963053793613185031)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406](https://juejin.cn/post/6944863057000529933)\\n\\n## \u7f16\u7a0b\u8303\u5f0f\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [\u51fd\u6570\u5f0f\u7f16\u7a0b\u672f\u8bed](https://github.com/shfshanyue/fp-jargon-zh)\\n- [\u51fd\u6570\u5f0f\u7f16\u7a0b\uff08FP\uff09](https://juejin.cn/post/7065093131233919006)\\n- [coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b](https://juejin.cn/post/6974377246140301342)\\n- [\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48](https://juejin.cn/post/6892886272377880583)\\n- [\u7b80\u660e JavaScript \u51fd\u6570\u5f0f\u7f16\u7a0b\u2014\u2014\u5165\u95e8\u7bc7](https://juejin.cn/post/6844903936378273799)\\n\\n## \u6280\u672f\u65b9\u6848\\n\\n- \u2b50\ufe0f [\u5982\u4f55\u53bb\u641e\u524d\u7aef\u57fa\u5efa](https://juejin.cn/post/7144881028661723167)\\n- \u2b50\ufe0f [\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8](https://juejin.cn/post/7129298214959710244)\\n- \u2b50\ufe0f [\u817e\u8baf\u4e8c\u9762\uff1a\u73b0\u5728\u8981\u4f60\u5b9e\u73b0\u4e00\u4e2a\u57cb\u70b9\u76d1\u63a7SDK\uff0c\u4f60\u4f1a\u600e\u4e48\u8bbe\u8ba1](https://juejin.cn/post/7085679511290773534)\\n- \u2b50\ufe0f [\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22](https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA)\\n- [\u817e\u8baf\u4e09\u9762\uff1aCookie\u7684SameSite\u4e86\u89e3\u5427\uff0c\u90a3SameParty\u5462](https://juejin.cn/post/7087206796351242248)\\n- [\u817e\u8baf\u4e00\u9762\uff1aCORS\u4e3a\u4ec0\u4e48\u80fd\u4fdd\u969c\u5b89\u5168\uff1f\u4e3a\u4ec0\u4e48\u53ea\u5bf9\u590d\u6742\u8bf7\u6c42\u505a\u9884\u68c0](https://juejin.cn/post/7081539471585312805)\\n- [\u4e0d\u4f7f\u7528\u7b2c\u4e09\u65b9\u5e93\u600e\u4e48\u5b9e\u73b0\u3010\u524d\u7aef\u5f15\u5bfc\u9875\u3011\u529f\u80fd](https://mp.weixin.qq.com/s/3hXLSOQC-B5JGmkOaYjgqw)\\n- [\u524d\u7aef\u67b6\u6784\u5e26\u4f60 \u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u7ec8\u8eab\u53d7\u76ca\u300c\u7f8e\u56e2\u540e\u7aef\u8fde\u8fde\u70b9\u8d5e\u300d](https://juejin.cn/post/7124573626161954823)\\n- [\u3010\u7b2c2759\u671f\u3011\u5f02\u6b65\u5206\u7247\u8ba1\u7b97\u5728\u817e\u8baf\u6587\u6863\u7684\u5b9e\u8df5](https://mp.weixin.qq.com/s/d5M_-8XqFGYnpif7GQNmLA)\\n- [\u5b57\u8282\u524d\u7aef\u76d1\u63a7 SDK \u4f53\u79ef\u4e0e\u6027\u80fd\u4f18\u5316\u5b9e\u8df5](https://mp.weixin.qq.com/s/FZUTFvOutS5NvURjj9jOFA)\\n- [\u4f7f\u7528 Vite \u63d2\u4ef6\u81ea\u52a8\u5316\u5b9e\u73b0\u9aa8\u67b6\u5c4f](https://mp.weixin.qq.com/s/8cguocg_1DtZkHLfAGLyXg)\\n- [\u76d8\u70b912\u4e2ayyds\u7684\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/l7SA04BJovmJTUDIuobYiw)\\n- [\u3010\u7b2c2628\u671f\u3011\u57fa\u4e8e\u8bbe\u8ba1\u7a3f\u8bc6\u522b\u7684\u53ef\u89c6\u5316\u4f4e\u4ee3\u7801\u7cfb\u7edf\u5b9e\u8df5](https://mp.weixin.qq.com/s/1HyQLZcnZN6I27p_hbfUPg)\\n- [\u6d45\u8c08\u6587\u6863\u7684\u5b9e\u65f6\u534f\u540c\u7f16\u8f91](https://mp.weixin.qq.com/s/Ba-3fMQXNXqIzVTjVUrWtQ)\\n- [\u81ea\u52a8\u5316\u751f\u6210\u9aa8\u67b6\u5c4f\u7684\u6280\u672f\u65b9\u6848\u8bbe\u8ba1\u4e0e\u843d\u5730](https://mp.weixin.qq.com/s/-WHafu5z-Ap4tjrbWesnmA)\\n- \u2b50\ufe0f [\u8c08\u8c08JS\u4e8c\u8fdb\u5236\uff1aFile\u3001Blob\u3001FileReader\u3001ArrayBuffer\u3001Base64](https://juejin.cn/post/7148254347401363463)\\n- \u2b50\ufe0f [\u5b57\u8282\u8df3\u52a8\u9762\u8bd5\u5b98\uff1a\u8bf7\u4f60\u5b9e\u73b0\u4e00\u4e2a\u5927\u6587\u4ef6\u4e0a\u4f20\u548c\u65ad\u70b9\u7eed\u4f20](https://juejin.cn/post/6844904046436843527)\\n- \u2b50\ufe0f [\u4ece\u96f6\u5f00\u59cb\u624b\u5199\u4e00\u4e2a\u300c\u5f00\u7bb1\u5373\u7528\u7684\u5927\u6587\u4ef6\u5206\u7247\u4e0a\u4f20\u5e93\u300d](https://juejin.cn/post/6990283221170651149)\\n- [5000\u5b57\u5e26\u4f60\u5168\u9762\u6df1\u5165\u7406\u89e3JS\u4e2d\u7684Stream API\uff5c8\u6708\u66f4\u6587\u6311\u6218](https://juejin.cn/post/6992007156320960542)\\n\\n## \u4e1a\u52a1\u6210\u957f && \u8f6f\u6280\u80fd\\n\\n- \u7ba1\u7406\u76f8\u5173\\n - \u2b50\ufe0f \u2b50\ufe0f [\u7ba1\u7406\u5c0f\u518c\u3001\u4e00\u7ebf\u540c\u5b66\u63a8\u8350\u3001\u4e00\u7ebfLeader\u63a8\u8350\u3001\u603b\u76d1\u7ea7\u63a8\u8350](https://mp.weixin.qq.com/s/neSFlzQMh2P7ROwJxhVNkg)\\n - \u2b50\ufe0f [\u8c01\u80fd\u6210\u4e3aLeader\uff0c\u5927Leader\u8be5\u505a\u4ec0\u4e48](https://mp.weixin.qq.com/s/FDK0a4HeO60fKyr6ioRYcw)\\n - \u2b50\ufe0f [\u5c11\u5e74\uff0c\u77e5\u9053\u4ec0\u4e48\u662f\u4fe1\u606f\u5dee\u521b\u9020\u4ef7\u503c\u5417](https://mp.weixin.qq.com/s/dTXg9a4kXwVZi2N7mP71mg)\\n - \u2b50\ufe0f [\u4ec0\u4e48\u662f\u5411\u4e0a\u7ba1\u7406](https://mp.weixin.qq.com/s/oodAZtxzHCZVGIGS9rBzIA)\\n - \u2b50\ufe0f [\u4f60\u662f\u5982\u4f55\u505a\u6c47\u62a5\u7684](https://mp.weixin.qq.com/s/B3qgLTvSHzE33d6O-k7bAQ)\\n- \u2b50\ufe0f [\u5e73\u65f6\u7684\u5de5\u4f5c\u5982\u4f55\u4f53\u73b0\u4e00\u4e2a\u4eba\u7684\u6280\u672f\u6df1\u5ea6](https://juejin.cn/post/7073001183123603470)\\n- \u2b50\ufe0f [\u5982\u4f55\u6210\u4e3a\u4f18\u79c0\u5de5\u7a0b\u5e08\u4e4b\u8f6f\u6280\u80fd\u7bc7](https://mp.weixin.qq.com/s/U6jAFVrgrKIm9--amZV5rA)\\n- \u2b50\ufe0f [\u5e72\u8d27\uff016\u4e2a\u65b9\u9762\uff0c32\u6761\u603b\u7ed3\u6559\u4f60\u63d0\u5347\u804c\u573a\u7ecf\u9a8c](https://mp.weixin.qq.com/s/MOWQ3rBFaITHSD2hvSelcw)\\n- \u2b50\ufe0f [\u804a\u804a\u5982\u4f55\u5b66\u4e60](https://mp.weixin.qq.com/s/kozXWY95HXiQPGou1sfttg)\\n- \u2b50\ufe0f [\u4ee5\u524d\u7aef\u67b6\u6784\u5e08\u8eab\u4efd\uff0c\u4ece\u96f6\u5f00\u59cb\u641e\u4e8b\u641e\u4e8b\u641e\u4e8b](https://mp.weixin.qq.com/s/K36xQbYgGVme8v_p9_dhkQ)\\n- \u2b50\ufe0f [Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3](https://juejin.cn/post/7115634967945674765)\\n- \u2b50\ufe0f [\u4e00\u56fe\u80dc\u5343\u8a00\u7cfb\u5217\u2014\u2014\u6cf3\u9053\u56fe\u548c\u6570\u636e\u6d41\u56fe](https://juejin.cn/post/7185376363808260152)\\n- \u2b50\ufe0f [\u600e\u4e48\u505a\u5230\u4e00\u56fe\u80dc\u5343\u8a00](https://juejin.cn/post/7153432342919397383)\\n- \u2b50\ufe0f [\u3010\u56fe\u4e66\u3011\u7a0b\u5e8f\u5458\u7684\u5e95\u5c42\u601d\u7ef4](https://mp.weixin.qq.com/s/URJC9ERPrcniiFinUsIJkg)\\n- \u2b50\ufe0f [\u4f5c\u4e3a\u5927\u5382\u9762\u8bd5\u5b98\uff0c\u539f\u6765\u8fd9\u79cd\u5b66\u751f\u6700\u5403\u9999\uff01](https://mp.weixin.qq.com/s/iTFj1Sn5vPTgkAT2Q9YC0w)\\n- \u2b50\ufe0f [\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\uff01YYDS](https://mp.weixin.qq.com/s/rJN14WFRTKjhoy8oWPulWw)\\n- \u2b50\ufe0f [\u5982\u4f55\u5728\u9879\u76ee\u5f00\u53d1\u4e2d\u9010\u6b65\u6210\u957f](https://mp.weixin.qq.com/s/cbKpWKWrhyJwKQhlyYhQ_w)\\n- \u2b50\ufe0f [\u51b4\u7fbd\u7b54\u8bfb\u8005\u95ee\uff1a\u5982\u4f55\u5728\u5de5\u4f5c\u4e2d\u6253\u9020\u5f71\u54cd\u529b\uff0c\u5e26\u52a8\u540c\u4e8b](https://juejin.cn/post/7114967732805697543)\\n- \u2b50\ufe0f [\u5165\u804cApifox\u7814\u53d1\u7ec4\u534a\u5e74\uff0c\u6211\u6240\u63d0\u5347\u7684\u8f6f\u6280\u80fd\uff5c\u6587\u672b\u62bd\u4e66](https://mp.weixin.qq.com/s/1BdXL5dQfP6DnK7iJs6zGQ)\\n- \u2b50\ufe0f [\u6709\u54ea\u4e9b\u503c\u5f97\u8ba1\u7b97\u673a\u4e13\u4e1a\u5b66\u751f\u52a0\u5165\u7684\u56fd\u4f01](https://mp.weixin.qq.com/s/G8SVu9CWrKwbT5jfXaBmtw)\\n- \u2b50\ufe0f [\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09](https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ)\\n- [\u5982\u4f55\u5199\u597d\u4e00\u4efd\u664b\u5347PPT\uff08\u9644PPT\u6a21\u677f\uff09](https://mp.weixin.qq.com/s/1QMPfODUcH1p4pGaoO1owA)\\n- [\u5982\u4f55\u753b\u51fa\u4e00\u5f20\u4f18\u79c0\u7684\u67b6\u6784\u56fe\uff08\u8001\u9e1f\u5fc5\u5907\uff09](https://mp.weixin.qq.com/s/hXFWU6uuil1aC1lEYO_KhQ)\\n- \u2b50\ufe0f [\u7cbe\u8bfb\u300a\u524d\u7aef\u804c\u4e1a\u89c4\u5212 - 2021 \u5e74\u300b](https://juejin.cn/post/6965675185890394119)\\n- \u2b50\ufe0f [2022\u5e74\u5982\u4f55\u6210\u4e3a\u4e00\u540d\u4f18\u79c0\u7684\u5927\u524d\u7aefLeader\uff1f](https://juejin.cn/post/7034419410706104356)\\n- \u2b50\ufe0f [\u6280\u672f\u4eba\u7684\u4e03\u5927\u5fc5\u5907\u7279\u8d28](https://mp.weixin.qq.com/s/n4Pa0Bao1ISS68IOPWGI_Q)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u521d\u7ea7\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u6210\u957f\u548c\u5bfb\u6c42\u7a81\u7834](https://juejin.cn/post/6906468062943182862#heading-8)\\n- [\u5e74\u5e95\u4e86\uff0c\u4f60\u662f\u5982\u4f55\u505a\u5de5\u4f5c\u6c47\u62a5\u7684\uff1f](https://mp.weixin.qq.com/s/NRqhJax8e6K8LMCNZSSozA)\\n- \u2b50\ufe0f [\u5199\u7ed9\u521d\u4e2d\u7ea7\u524d\u7aef\u7684\u9ad8\u7ea7\u8fdb\u9636\u6307\u5357](https://juejin.cn/post/6844904103504527374)\\n- [\u5728\u653f\u91c7\u4e91\u5982\u4f55\u5199\u524d\u7aef\u6280\u672f\u65b9\u6848\u6587\u6863](https://juejin.cn/post/7041713124210114567)\\n- [\u5982\u4f55\u7f16\u5199\u524d\u7aef\u8bbe\u8ba1\u6587\u6863](https://juejin.cn/post/7017643726944108558)\\n- \u2b50\ufe0f [\u7406\u6e05\u601d\u8def\uff0c\u524d\u7aef\u6280\u672f\u8c03\u7814\u5230\u5e95\u5e94\u8be5\u600e\u4e48\u505a\uff1f](https://juejin.cn/post/6901845776880795662#heading-0)\\n- [\u4ece\u5b9e\u4e60\u5230\u5165\u804c\uff1a\u4e0e\u4f60\u5206\u4eab\u6211\u5728\u653f\u91c7\u4e91\u7684\u5de5\u4f5c\u548c\u6210\u957f](https://juejin.cn/post/6869548364640288781)\\n\\n## Git \u76f8\u5173\\n\\n- \u2b50\ufe0f [\u8840\u6cea\u6559\u8bad\u4e4b\u8bf7\u4e0d\u8981\u518d\u8f7b\u89c6Git \u2014\u2014 \u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 Git \u7684](https://zhuanlan.zhihu.com/p/250493093)\\n- \u2b50\ufe0f [GitHub \u641c\u7d22\u6280\u5de7\uff1a\u5982\u4f55\u66f4\u6709\u6548\u5730\u641c\u7d22 issue\u3001repo \u548c\u66f4\u591a\u4fe1\u606f](https://mp.weixin.qq.com/s/aTr6xf4BEuF-yxL340TnLg)\\n- \u2b50\ufe0f [\u5982\u679c\u4f60\u8fd8\u4e0d\u4f1a\u7528git\u56de\u6eda\u4ee3\u7801\uff0c\u90a3\u4f60\u4e00\u5b9a\u8981\u6765\u770b\u770b](https://juejin.cn/post/7046720828901163016)\\n- \u2b50\ufe0f [Git\u4e0d\u8981\u53ea\u4f1apull\u548cpush\uff0c\u8bd5\u8bd5\u8fd95\u6761\u63d0\u9ad8\u6548\u7387\u7684\u547d\u4ee4](https://juejin.cn/post/7071780876501123085)\\n- [\u5229\u7528\u597d git bisect \u8fd9\u628a\u5229\u5668\uff0c\u5e2e\u52a9\u4f60\u5feb\u901f\u5b9a\u4f4d\u7591\u96be bug](https://juejin.cn/post/7046409685561245733)\\n- \u2b50\ufe0f [\u524d\u7aef\u67b6\u6784\u5e08\u7684 git \u529f\u529b\uff0c\u4f60\u6709\u51e0\u6210\u706b\u5019\uff1f](https://juejin.cn/post/7024043015794589727)\\n- \u2b50\ufe0f [\u4e24\u6761\u547d\u4ee4\u8ba9\u4f60\u7684git\u81ea\u52a8\u53d8\u57fa](https://segmentfault.com/a/1190000040712052)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u591a\u5e74 Git \u4f7f\u7528\u5fc3\u5f97 & \u5e38\u89c1\u95ee\u9898\u6574\u7406](https://juejin.cn/post/6844904191203213326)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u6211\u5728\u5de5\u4f5c\u4e2d\u662f\u5982\u4f55\u4f7f\u7528 git \u7684](https://juejin.cn/post/6974184935804534815)\\n- \ud83c\udf1b [\u4e3a\u4ec0\u4e48 husky \u653e\u5f03\u4e86\u4f20\u7edf\u7684 JS \u914d\u7f6e](https://juejin.cn/post/7000186205224566791)\\n- \u2b50\ufe0f [\u4f60\u53ef\u80fd\u5df2\u7ecf\u5ffd\u7565\u7684git commit\u89c4\u8303](https://juejin.cn/post/6844904036068491278)\\n- [gitmoji: An emoji guide for your commit messages](https://gitmoji.dev/)\\n\\n## \u6e90\u7801\u7cfb\u5217\\n\\n- \u2b50\ufe0f [[\u5efa\u8bae\u6536\u85cf] \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709](https://juejin.cn/post/6982004709145968677)\\n- \u2b50\ufe0f [\u516d\u5343\u5b57\u8be6\u89e3\uff01vue3 \u54cd\u5e94\u5f0f\u662f\u5982\u4f55\u5b9e\u73b0\u7684\uff1f](https://juejin.cn/post/7048970987500470279)\\n- \u2b50\ufe0f \u2b50\ufe0f [Redux\u901a\u5173\u7b80\u6d01\u653b\u7565 -- \u770b\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86\uff01](https://juejin.cn/post/7019185205336342542)\\n- \u2b50\ufe0f [\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React](https://juejin.cn/post/6978654109893132318)\\n- \u2b50\ufe0f [React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb](https://juejin.cn/post/7010539227284766751)\\n- \u2b50\ufe0f [\u5e26\u4f60\u5feb\u901f\u624b\u5199\u4e00\u4e2a\u7b80\u6613\u7248vue\u4e86\u89e3vue\u54cd\u5e94\u5f0f](https://juejin.cn/post/6990974525273800712)\\n- [Vue3.2 vDOM diff\u6d41\u7a0b\u5206\u6790\u4e4b\u4e00\uff1adiff\u7b97\u6cd5](https://juejin.cn/post/7072321805792313357)\\n- [2021\u5e74\uff0c\u8ba9\u6211\u4eec\u624b\u5199\u4e00\u4e2amini\u7248\u672c\u7684vue2.x\u548cvue3.x\u6846\u67b6](https://juejin.cn/post/6977363265965785102)\\n- [Vue(v2.6.11)\u4e07\u884c\u6e90\u7801\u751f\u5543\uff0c\u5c31\u786c\u521a\uff01](https://juejin.cn/post/6846687602679119885)\\n- [\u5c24\u96e8\u6eaa\u56fd\u5916\u6559\u7a0b\uff1a\u4eb2\u624b\u5e26\u4f60\u5199\u4e2a\u7b80\u6613\u7248\u7684Vue\uff01](https://juejin.cn/post/6992018709439053837)\\n- [Vue 3 Workshop Code Samples](https://codepen.io/collection/DkxpbE?cursor=ZD0wJm89MCZwPTEmdj00)\\n- \u2b50\ufe0f [diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f](https://juejin.cn/post/6997965021401579556)\\n- \u2b50\ufe0f [Vue 3.2 \u53d1\u5e03\u4e86\uff0c\u90a3\u5c24\u96e8\u6eaa\u662f\u600e\u4e48\u53d1\u5e03 Vue.js \u7684\uff1f](https://juejin.cn/post/6997943192851054606)\\n- \u2b50\ufe0f [\u521d\u5b66\u8005\u4e5f\u80fd\u770b\u61c2\u7684 Vue3 \u6e90\u7801\u4e2d\u90a3\u4e9b\u5b9e\u7528\u7684\u57fa\u7840\u5de5\u5177\u51fd\u6570](https://juejin.cn/post/6994976281053888519)\\n\\n## Webpack \u7cfb\u5217\\n\\n- [Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790](https://juejin.cn/post/6937125495439900685)\\n - \u901a\u8fc7\u7f16\u5199\u4e00\u4e2a plugin\uff0c\u5728\u9884\u5904\u7406\u9636\u6bb5\u901a\u8fc7\u63d2\u4ef6 apply \u51fd\u6570\u52a8\u6001\u4fee\u6539 webpack \u914d\u7f6e\uff0c\u6ce8\u5165 vue-loader \u4e13\u7528\u7684 rules\\n- \u2b50\ufe0f [\u8d85\u786c\u6838\uff5c\u5e26\u4f60\u7545\u6e38\u5728 Webpack \u63d2\u4ef6\u5f00\u53d1\u8005\u7684\u4e16\u754c](https://juejin.cn/post/7047777251949019173)\\n- \u2b50\ufe0f [\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684](https://juejin.cn/post/7170852747749621791)\\n- \u2b50\ufe0f [\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801](https://juejin.cn/post/7164175171358556173)\\n- [Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566](https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g)\\n- [\u4f60\u7684Tree-Shaking\u5e76\u6ca1\u4ec0\u4e48\u5375\u7528](https://zhuanlan.zhihu.com/p/32831172)\\n- [\u624b\u6478\u624b Webpack \u591a\u5165\u53e3\u914d\u7f6e\u5b9e\u8df5](https://juejin.cn/post/6844903939289120782)\\n- \u2b50\ufe0f [Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790](https://juejin.cn/post/7031546400034947108)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb](https://juejin.cn/post/7023242274876162084)\\n- \u2b50\ufe0f [Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790](https://juejin.cn/post/7021729340945596424)\\n- [Webpack5 \u5b9e\u8df5 - \u6784\u5efa\u6548\u7387\u500d\u901f\u63d0\u5347\uff01](https://mp.weixin.qq.com/s/gwHwVxA4zh59SBvq-onM-g)\\n- \ud83c\udf1b [Webpack \u6027\u80fd\u7cfb\u5217\u4e00: \u4f7f\u7528 Cache \u63d0\u5347\u6784\u5efa\u6027\u80fd](https://mp.weixin.qq.com/s/mpF6W-4dElu0UPed03oJQw)\\n- \ud83c\udf1b [\u6211\u662f\u5982\u4f55\u5c06\u7f51\u9875\u6027\u80fd\u63d0\u53475\u500d\u7684 \u2014 \u6784\u5efa\u4f18\u5316\u7bc7](https://juejin.cn/post/6910893471339708429)\\n- \u2b50\ufe0f [Webpack\u914d\u7f6e\u5168\u89e3\u6790\uff08\u4f18\u5316\u7bc7\uff09](https://juejin.cn/post/6858905382861946894)\\n- \u2b50\ufe0f [\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0a\u7bc7](https://juejin.cn/post/7144934998884220958)\\n- \u2b50\ufe0f [\u5982\u4f55\u5feb\u901f\u6210\u4e3a\u4e00\u540d\u719f\u7ec3\u7684 Webpack \u914d\u7f6e\u5de5\u7a0b\u5e08 - \u4e0b\u7bc7](https://juejin.cn/post/7145025071432597541)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57](https://juejin.cn/post/6996816316875161637)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u5b9e\u8df5\u7bc7\uff09](https://juejin.cn/post/6991774994552324133)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u57fa\u7840\u7bc7\uff09](https://juejin.cn/post/6991630925792542750)\\n- \u2b50\ufe0f [\u624b\u628a\u624b\u5e26\u4f60\u5165\u95e8 Webpack4](https://juejin.cn/post/6844903912588181511)\\n- \u2b50\ufe0f \u2b50\ufe0f [\\\\[\u4e07\u5b57\u603b\u7ed3\\\\] \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406](https://juejin.cn/post/6949040393165996040)\\n\\n## Vite \u7cfb\u5217\\n\\n- [\u5b66\u4f1a\u8fd9 20 \u4e2a\u5e93\uff0c\u8ba9\u4f60\u5feb\u901f\u770b\u61c2 vue3 \u548c vite3 \u6e90\u7801 \ud83d\ude80](https://juejin.cn/post/7124112069355372581)\\n- [\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417](https://juejin.cn/post/7094984070999834655)\\n- [\u524d\u7aef\u5386\u53f2\u9879\u76ee\u7684 Vite \u8fc1\u79fb\u5b9e\u8df5\u603b\u7ed3](https://juejin.cn/post/6986533364438138894)\\n- [\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite 2.x \u6e90\u7801\u7ea7\u5206\u6790](https://juejin.cn/post/6979932627465666568)\\n- [\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u6784\u5efa\u5de5\u5177 - Vite \u26a1\ufe0f\u539f\u7406\u5206\u6790](https://juejin.cn/post/6956564266812571656)\\n\\n## PNPM && Monorepo\\n\\n- \u2b50\ufe0f [\u8bfe\u4ee3\u8868\uff1aTurborepo \u7b14\u8bb0](https://mp.weixin.qq.com/s/beLkwHan2C8BuSArs53cIA)\\n- \u2b50\ufe0f [lerna + dumi + eslint\u591a\u5305\u7ba1\u7406\u5b9e\u8df5](https://juejin.cn/post/7015566240991150117)\\n- \u2b50\ufe0f [\u7ec4\u4ef6\u5e93Monmrepo\u67b6\u6784\u4e0e\u5f00\u53d1\u8c03\u8bd5\u73af\u5883\u6784\u5efa](https://mp.weixin.qq.com/s/z-tKxgRPmdyR0zwc78Khgw)\\n- [React Native\u5de5\u7a0bMonorepo\u6539\u9020\u5b9e\u8df5](https://juejin.cn/post/7177585131861835837)\\n- [\u3010\u7b2c2714\u671f\u3011\u4eceMultirepo\u5230Monorepo \u888b\u9f20\u4e91\u6570\u6808\u524d\u7aef\u7814\u53d1\u6548\u7387\u63d0\u5347\u63a2\u7d22\u4e4b\u8def](https://mp.weixin.qq.com/s/JWks8VyuXoB5zaeYdyJPxw)\\n- [Monorepo\uff0c\u5927\u578b\u524d\u7aef\u9879\u76ee\u7ba1\u7406\u6a21\u5f0f\u5b9e\u8df5](https://mp.weixin.qq.com/s/N0CZABDD0TKTmdljH3y74A)\\n- [\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417](https://juejin.cn/post/7094984070999834655)\\n- [\u590d\u6d3b\u4e86\uff01 Lerna V6 \u5e26\u6765\u4e86\u54ea\u4e9b\u65b0\u4e1c\u897f](https://mp.weixin.qq.com/s/6peafvVjmcF65PFSggSLYQ)\\n- [pnpm + workspace + changesets \u6784\u5efa\u4f60\u7684 monorepo \u5de5\u7a0b](https://juejin.cn/post/7098609682519949325)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u6838\u5fc3\u6280\u672f\u63ed\u79d8\uff1a5. \u4ece\u7ec8\u7aef\u547d\u4ee4\u89e3\u6790\u5668\u8bf4\u8d77\u8c08\u8c08 npm \u5305\u7ba1\u7406\u5de5\u5177\u7684\u8fd0\u884c\u539f\u7406](https://juejin.cn/post/7161063570594070559)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a4. ESLint \u6280\u672f\u539f\u7406\u4e0e\u5b9e\u6218\u53ca\u4ee3\u7801\u89c4\u8303\u81ea\u52a8\u5316\u8be6\u89e3](https://juejin.cn/post/7157743898939359262)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa](https://juejin.cn/post/7146183222425518093)\\n- [\ud83d\ude80Turborepo\uff1a\u53d1\u5e03\u5f53\u6708\u5c31\u6fc0\u589e 3.8k Star\uff0c\u8fd9\u6b3e\u8d85\u795e\u7684\u65b0\u5174 Monorepo \u65b9\u6848\uff0c\u4f60\u4e0d\u6253\u7b97\u5c1d\u8bd5\u4e0b\u5417](https://juejin.cn/post/7129267782515949575)\\n- [\u6700\u8be6\u7ec6\u7684 lerna \u4e2d\u6587\u624b\u518c](https://juejin.cn/post/7136925215388499998)\\n- [Monorepo Handbook \u65b0\u9c9c\u51fa\u7089](https://turborepo.org/docs/handbook/what-is-a-monorepo)\\n- [\u73b0\u4ee3 Monorepo \u5de5\u7a0b\u6280\u672f\u9009\u578b\uff0c\u804a\u804a\u6211\u7684\u601d\u8003](https://mp.weixin.qq.com/s/99nozy-vtFMGcBTxYvumWA)\\n- [\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf](https://juejin.cn/post/7092766235380678687)\\n- [\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2](https://zhuanlan.zhihu.com/p/455809528)\\n- [pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA)\\n- [\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09](https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw)\\n- [\u524d\u7aef\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u8fdb\u5316\u53f2](https://juejin.cn/post/7083414641610588168)\\n- [\u90fd2022\u5e74\u4e86\uff0cpnpm\u5feb\u5230\u7897\u91cc\u6765\uff01](https://juejin.cn/post/7053340250210795557)\\n- [\u5173\u4e8e\u73b0\u4ee3\u5305\u7ba1\u7406\u5668\u7684\u6df1\u5ea6\u601d\u8003\u2014\u2014\u4e3a\u4ec0\u4e48\u73b0\u5728\u6211\u66f4\u63a8\u8350 pnpm \u800c\u4e0d\u662f npm/yarn?](https://juejin.cn/post/6932046455733485575)\\n- [\u5e74\u7ec8\u76d8\u70b9\uff1a2022\u57fa\u4e8eMonorepo\u7684\u9996\u4e2a\u5927\u8d8b\u52bf-TurboRepo](https://juejin.cn/post/7051929587852247077)\\n- [\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406](https://juejin.cn/post/7030207667457130527)\\n- [One For All\uff1a\u57fa\u4e8epnpm + lerna + typescript\u7684\u6700\u4f73\u9879\u76ee\u5b9e\u8df5 - \u7406\u8bba\u7bc7](https://juejin.cn/post/7043998041786810398)\\n- [\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020](https://juejin.cn/post/7029262501833359368)\\n- [Monorepo \u7684\u8fd9\u4e9b\u5751\uff0c\u6211\u4eec\u5e2e\u4f60\u8e29\u8fc7\u4e86\uff01](https://juejin.cn/post/6972139870231724045)\\n- [\u5f00\u6e90\u9879\u76ee\u90fd\u5728\u7528 monorepo\uff0c\u4f46\u662f\u4f60\u77e5\u9053\u5c45\u7136\u6709\u90a3\u4e48\u591a\u5751\u4e48\uff1f](https://juejin.cn/post/6950082433647640612)\\n- [All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6924854598268108807)\\n\\n## Rollup \u7cfb\u5217\\n\\n- \u2b50\ufe0f [\u3010\u5b9e\u6218\u7bc7\u3011\u6700\u8be6\u7ec6\u7684Rollup\u6253\u5305\u9879\u76ee\u6559\u7a0b](https://juejin.cn/post/7145090564801691684)\\n- \u2b50\ufe0f [\u4ece0\u52301\u5f00\u53d1\u4e00\u4e2aReact\u7ec4\u4ef6\u5e93](https://juejin.cn/post/7144365208646418462)\\n- \u2b50\ufe0f [\u57fa\u4e8estorybook\u7ec4\u4ef6\u5e93\u7684\u6280\u672f\u9009\u578b\u8be5\u600e\u4e48\u9009](https://mp.weixin.qq.com/s/xjY0d8eNTmAuCZKxKQeu7g)\\n- \u2b50\ufe0f [\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e](https://juejin.cn/post/7151653067593613320)\\n- \u2b50\ufe0f [\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305](https://juejin.cn/post/7126394898445500423)\\n- \u2b50\ufe0f [\u524d\u7aef\u5de5\u7a0b\u5316\u57fa\u5efa\u63a2\u7d22\uff1a\u4ece\u5185\u90e8\u673a\u5236\u548c\u6838\u5fc3\u539f\u7406\u4e86\u89e3npm](https://mp.weixin.qq.com/s/mL1pv2kPKvtaHalr7PXKow)\\n- [\u4e00\u6587\u5165\u95e8rollup\ud83e\ude80\uff0113\u7ec4demo\u5e26\u4f60\u8f7b\u677e\u9a7e\u9a6d](https://juejin.cn/post/7069555431303020580)\\n- [\u8bf4\u4e0d\u6e05rollup\u80fd\u8f93\u51fa\u54ea6\u79cd\u683c\u5f0f\ud83d\ude25\u5dee\u70b9\u88ab\u9119\u89c6](https://juejin.cn/post/7051236803344334862)\\n- [\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305](https://juejin.cn/post/7052307032971411463)\\n- [\u524d\u7aef\u7ec4\u4ef6/\u5e93\u6253\u5305\u5229\u5668rollup\u4f7f\u7528\u4e0e\u914d\u7f6e\u5b9e\u6218](https://juejin.cn/post/6844903970469576718)\\n- [\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup](https://juejin.cn/post/6869551115420041229)\\n\\n## \u5fae\u524d\u7aef && \u6a21\u5757\u8054\u90a6\\n\\n- \ud83c\udf1f [Module Federation\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/pT_tugg_EvE5pnMCaUqliw)\\n- \ud83c\udf1f [\u6a21\u5757\u8054\u90a6\u5728\u5fae\u524d\u7aef\u67b6\u6784\u4e2d\u7684\u5b9e\u8df5](https://mp.weixin.qq.com/s/WXeUuUdgF_3djqBhh1siQA)\\n- \ud83c\udf1f [\u57fa\u4e8e MF \u7684\u7ec4\u4ef6\u5316\u5171\u4eab\u5de5\u4f5c\u6d41](https://mp.weixin.qq.com/s/u5oAcIYiGrl1qOujOYjzqw)\\n- \u2b50\ufe0f [\u804a\u4e00\u804a\u5173\u4e8e\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b](https://mp.weixin.qq.com/s/l_KKNRUyJANN6wkoC2TlVQ)\\n- \u2b50\ufe0f [\u8d85\u5927\u4f53\u91cf\u9879\u76ee\uff0c\u5fae\u524d\u7aef\u843d\u5730\u65b9\u6848\uff0c\u770b\u5b8c\u540e\u6094\u6765\u627e\u6211](https://juejin.cn/post/7121244973558661150)\\n- \u2b50\ufe0f [\u3010\u7b2c2774\u671f\u3011\u57fa\u4e8e Module Federation \u7684\u6a21\u5757\u5316\u8de8\u6808\u65b9\u6848\u63a2\u7d22](https://mp.weixin.qq.com/s/Fqy_pkgKvZrdZZc3t5xgdA)\\n- \u2b50\ufe0f [\u3010\u7b2c1912\u671f\u3011\u63a2\u7d22 webpack5 \u65b0\u7279\u6027Module federation\u5728\u817e\u8baf\u6587\u6863\u7684\u5e94\u7528](https://mp.weixin.qq.com/s/iS-prT1xZPV6cpH7MHRRdQ)\\n- \u2b50\ufe0f [\u3010\u7b2c1901\u671f\u3011Webpack 5 Module Federation: JavaScript \u67b6\u6784\u7684\u53d8\u9769\u8005](https://mp.weixin.qq.com/s/PFKxQgZPER_XHUSbk_SQJA)\\n- [\u5168\u9762\u654f\u6377\u6a21\u5f0f\u4e0b\u7684\u5fae\u524d\u7aef\u65b9\u6848](https://mp.weixin.qq.com/s/vy84FY3P6KPeWzDaNl6Ntg)\\n- [\u5fae\u524d\u7aef\u573a\u666f\u4e0b\u7684\u4ee3\u7801\u5171\u4eab](https://mp.weixin.qq.com/s/mvdOU8uVG9NjGPzInpPxJA)\\n- [\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c](https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg)\\n- [\u5fae\u524d\u7aef\u67b6\u6784\u7684\u51e0\u79cd\u6280\u672f\u9009\u578b](https://mp.weixin.qq.com/s/ylkY9HWTQKPlbDb2M33YWQ)\\n- [\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684](https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g)\\n- [\u6a21\u5757\u8054\u90a6\u6d45\u6790](https://juejin.cn/post/7101457212085633054)\\n- [\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb](https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g)\\n- [\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation](https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww)\\n\\n## VS Code \u63d2\u4ef6\\n\\n- [vscode\u63d2\u4ef6\u539f\u7406\u6d45\u6790\u4e0e\u5b9e\u6218](https://mp.weixin.qq.com/s/4MmBSD-d-9T5-kFhcWNlTA)\\n- [vscode-extension-samples](https://github.com/microsoft/vscode-extension-samples)\\n- [\u5f00\u53d1\u4e00\u6b3e\u4e13\u5c5e\u7684 VSCode \u4ee3\u7801\u63d0\u793a\u63d2\u4ef6](https://mp.weixin.qq.com/s/e2gfSnBrR6rn7x37ZGLplg)\\n\\n## \u524d\u7aef\u5de5\u7a0b\u5316\\n\\n- \u2b50\ufe0f [\u6765\u81ea\u672a\u6765\uff0c2022 \u5e74\u7684\u524d\u7aef\u4eba\u90fd\u5728\u505a\u4ec0\u4e48?](https://juejin.cn/post/7062617190981173278)\\n- [\u4e3a\u4ec0\u4e48\u8bf4 WebAssembly \u662f Web \u7684\u672a\u6765\uff1f](https://juejin.cn/post/7056612950412361741)\\n- [easy-serverless \u529f\u80fd\u5206\u6790](https://juejin.cn/post/7057114641507287048)\\n- [2022 \u5e74 JavaScript \u5f00\u53d1\u5de5\u5177\u7684\u751f\u6001](https://mp.weixin.qq.com/s/ckskF06PD43KHpKAGaYmRA)\\n- [\u8d85\u5168\u9762\u7684\u524d\u7aef\u65b0\u4e00\u4ee3\u6784\u5efa\u5de5\u5177\u5bf9\u6bd4: esbuild\u3001Snowpack\u3001Vite\u3001wmr](https://mp.weixin.qq.com/s/JZbsIqsqNeJmc__QFKpo1Q)\\n- [esno\uff0c\u57fa\u4e8e Esbuild \u7684\u795e\u5668](https://mp.weixin.qq.com/s/3aVYGfahv5rZJbWBhaI3BA)\\n- \u2b50\ufe0f [Deno \u7b80\u4ecb\uff1a\u5b83\u6bd4 Node.js \u66f4\u597d\u5417\uff1f](https://mp.weixin.qq.com/s/qnA1tFKMXr7hwsEKFXKOZg)\\n- \u2b50\ufe0f [\u57fa\u4e8e Next.js \u7684 SSR/SSG \u65b9\u6848\u4e86\u89e3\u4e00\u4e0b\uff1f](https://juejin.cn/post/7046204235226021901)\\n- \ud83c\udf1b [\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684](https://juejin.cn/post/7085257325165936648)\\n- \ud83c\udf1b [\u524d\u7aef\u67b6\u6784\u5e08\u795e\u6280\uff0c\u4e09\u62db\u7edf\u4e00\u56e2\u961f\u4ee3\u7801\u98ce\u683c](https://juejin.cn/post/7029512357428592648)\\n- \ud83c\udf1b [\u624b\u628a\u624b\u6559\u4f60\u642d\u5efa\u4e00\u4e2a\u7070\u5ea6\u53d1\u5e03\u73af\u5883](https://juejin.cn/post/6844904110601273357)\\n- \u2b50\ufe0f [ES6 \u4ee5\u4e0a\u7248\u672c\u4ee3\u7801\u8981\u4e0d\u8981\u8f6c\u7801\u6210 ES5 ?](https://juejin.cn/post/7049696761858195486)\\n- \u2b50\ufe0f [ESM \u4e0e CJS \u7684 Interop \u6765\u4e16\u4eca\u751f](https://mp.weixin.qq.com/s/3TKcUeoyzXvH3MGVI6Dj9A)\\n- \u2b50\ufe0f [2022 \u524d\u7aef\u6280\u672f\u9886\u57df\u4f1a\u6709\u54ea\u4e9b\u65b0\u7684\u53d8\u5316\uff1f](https://www.zhihu.com/question/493891614/answer/2269197391)\\n- \ud83c\udf1b [\u524d\u7aef\u6784\u5efa\u8fd9\u5341\u5e74](https://segmentfault.com/a/1190000040496020)\\n\\n## \u8f6f\u4ef6\u67b6\u6784 && \u8bbe\u8ba1\u6a21\u5f0f\\n\\n- \u2b50\ufe0f Software Engineering at Google\\n - \u5728\u7ebf\u9605\u8bfb\uff1ahttps://abseil.io/blog/04222021-swe-book\\n - PDF \u4e0b\u8f7d\uff1ahttps://github.com/garfield-dev-team/Frontend-Training-Program/blob/main/OReilly.Software.Engineering.at.Google.2020.3.pdf\\n- [The Ultimate Guide To Software Engineering](https://dev.to/wiseai/the-ultimate-guide-to-software-engineering-545e)\\n- \u2b50\ufe0f [\u8bed\u96c0\u684c\u9762\u7aef\u6280\u672f\u67b6\u6784\u5b9e\u8df5](https://juejin.cn/post/7145014659584622629)\\n- \u2b50\ufe0f [\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01](https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg)\\n- [\u63a2\u79d8\u5fae\u4fe1\u4e1a\u52a1\u4f18\u5316\uff1aDDD\u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://mp.weixin.qq.com/s/kFjfzwTOdaKA2ym63VR3DQ)\\n- [\u4e86\u89e3\u5fae\u524d\u7aef\uff0c\u6df1\u5165\u524d\u7aef\u67b6\u6784\u7684\u524d\u4e16\u4eca\u751f](https://mp.weixin.qq.com/s/12BS4V6fvXkeb84XDpPnHw)\\n- \u2b50\ufe0f [\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg)\\n- \u2b50\ufe0f [\u5de5\u4f5c\u4e2d\u5e38\u89c1\u7684 6 \u79cd\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f60\u7528\u8fc7\u51e0\u79cd](https://mp.weixin.qq.com/s/ocPx6Sw09ioDyz_IOWK69Q)\\n- \u2b50\ufe0f [\u3010\u7b2c2757\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u768423\u4e2a\u57fa\u672c\u539f\u5219](https://mp.weixin.qq.com/s/3MwRLM0jDmwv5l6gamFjcw)\\n- \u2b50\ufe0f [\u3010\u7b2c2677\u671f\u3011\u5982\u4f55\u5728React\u4e2d\u5e94\u7528SOLID\u539f\u5219](https://mp.weixin.qq.com/s/iB23DV4hovPDdf5_4TCaOA)\\n- [\u3010\u7b2c2703\u671f\u3011\u8f6f\u4ef6\u67b6\u6784\u624b\u518c](https://mp.weixin.qq.com/s/1h6yqCWyzYLM8WPGlGdtVA)\\n- [\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw)\\n- [\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ)\\n- [\u6df1\u5165\u6d45\u51fa\u524d\u7aef\u505a\u63a7\u5236\u53cd\u8f6c\u4e0e\u4f9d\u8d56\u6ce8\u5165](https://www.yuque.com/surfacew/fe/qg0uev)\\n- [javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw)\\n- [\u5b9e\u6218\uff01\u5982\u4f55\u4ece\u96f6\u642d\u5efa10\u4e07\u7ea7 QPS \u5927\u6d41\u91cf\u3001\u9ad8\u5e76\u53d1\u4f18\u60e0\u5238\u7cfb\u7edf](https://mp.weixin.qq.com/s/iZ9BX6cCCp_TB-SC3knuew)\\n- \u2b50\ufe0f [\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1](https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg)\\n- \u2b50\ufe0f [\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1\u56db\u8bba](https://mp.weixin.qq.com/s/SMAycMJPWr018sU04kbfbQ)\\n- \u2b50\ufe0f [\u4e07\u5b57\u957f\u6587\u52a9\u4f60\u4e0a\u624b\u8f6f\u4ef6\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1 DDD](https://mp.weixin.qq.com/s/BIYp9DNd_9sw5O2daiHmlA)\\n- \ud83c\udf1b [\u7528DDD(\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1)\u548cADT(\u4ee3\u6570\u6570\u636e\u7c7b\u578b)\u63d0\u5347\u4ee3\u7801\u8d28\u91cf](https://mp.weixin.qq.com/s/QCIlheiEgmU4Qi-4b_XoqQ)\\n- \ud83c\udf1b [\u540e\u53f0\u670d\u52a1\u67b6\u6784\u9ad8\u6027\u80fd\u8bbe\u8ba1\u4e4b\u9053](https://mp.weixin.qq.com/s/hsH7LMBEDGe_df9UbfOvbQ)\\n- [\u6211\u505a\u7cfb\u7edf\u67b6\u6784\u7684\u4e00\u4e9b\u539f\u5219](https://coolshell.cn/articles/21672.html)\\n- [\u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\u4e2d\u5982\u4f55\u505a\u597d\u6280\u672f\u51b3\u7b56\uff1f](https://mp.weixin.qq.com/s/m1Dv-YG60AKArGu-URr88w)\\n- [\u524d\u7aef\u9886\u57df\u7684 \u201c\u5e72\u51c0\u67b6\u6784\u201d](https://mp.weixin.qq.com/s/4bB_B5JTOrev8mqfG7K2cw)\\n- [\u53ea\u4f1a\u7528\u4f20\u7edf\u5f00\u53d1\u6a21\u5f0f\uff1f10\u5206\u949f\u6559\u4f60\u73a9\u8f6c\u654f\u6377\uff01](https://mp.weixin.qq.com/s/g9F05SRnQBTzzfx_2CKqhg)\\n\\n## \u6301\u7eed\u96c6\u6210\\n\\n- \u2b50\ufe0f [\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg)\\n- [\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357](https://zhuanlan.zhihu.com/p/445217118)\\n- [GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/7064906701941506061)\\n- [Docker Tutorial for Beginners - A Full DevOps Course on How to Run Applications in Containers](https://www.youtube.com/watch?v=fqMOX6JJhGo)\\n- \u2b50\ufe0f [Best practices for writing Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/)\\n- \u2b50\ufe0f [Dockerfile reference](https://docs.docker.com/engine/reference/builder/)\\n- [\u5982\u4f55\u4f7f\u7528 docker \u90e8\u7f72\u524d\u7aef\u5e94\u7528](https://juejin.cn/post/6844903793348329486)\\n- [docker \u7b80\u6613\u5165\u95e8 - shanyue](https://shanyue.tech/op/docker.html)\\n- [\u5c0f\u9cb8\u9c7c\u7684\u524d\u4e16\u4eca\u751f--Docker](https://mp.weixin.qq.com/s/4aFJ7t37IwEMyq-u09Wf1g)\\n- [\u5f00\u53d1\u8005\u5fc5\u5907\u7684 Docker \u5b9e\u8df5\u6307\u5357](https://juejin.cn/book/6844733746462064654/section/6844733746504007693)\\n- [\u8c01\u8bf4\u524d\u7aef\u4e0d\u9700\u8981\u5b66\u4e60docker\uff1f](https://mp.weixin.qq.com/s/U-zK6JEMpmK2Il68-ijcaw)\\n- [\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a](https://juejin.cn/post/7028222480326066213)\\n- [\u524d\u7aef\u5f00\u53d1\u8005\u5e94\u8be5\u77e5\u9053\u7684 Centos/Docker/Nginx/Node/Jenkins \u64cd\u4f5c(\ud83c\udf61 \u957f\u6587)](https://juejin.cn/post/6951684431597797389)\\n- [\u4fdd\u59c6\u7ea7\u6307\u5357\uff1ajekins+docker\u6784\u5efa\u90e8\u7f72react\u9879\u76ee\u5b9e\u6218](https://juejin.cn/post/7049920990351982628)\\n- [\u4f60\u7684\u7b2c\u4e00\u4e2a Docker + React + Express \u5168\u6808\u5e94\u7528](https://juejin.cn/post/6993951401952935972)\\n\\n## \u670d\u52a1\u7aef\u76f8\u5173\\n\\n- \u63a8\u8350\u7b97\u6cd5\\n - [\u56fe\u6587\u89e3\u8bfb\uff1a\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7cbe\u6392\uff01](https://mp.weixin.qq.com/s/GetU-ULhfvY8ri47Ht28GQ)\\n - [\u8d85\u5f3a\u6307\u5357\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u91cd\u6392](https://mp.weixin.qq.com/s/wXb5uQJBCzSEq6IITP7VCQ)\\n - [\u8be6\u7ec6\u89e3\u8bfb\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u53ec\u56de](https://mp.weixin.qq.com/s/1wOnG4dtNSI-x2x15-AjTQ)\\n - [\u56fe\u6587\u5e76\u8302\uff01\u63a8\u8350\u7b97\u6cd5\u67b6\u6784\u2014\u2014\u7c97\u6392](https://mp.weixin.qq.com/s/YsK_8yyBNL5z269qT5CrIw)\\n - [\u8be6\u89e3\u95f2\u9c7c\u63a8\u8350\u7cfb\u7edf\uff08\u957f\u6587\u6536\u85cf\uff09](https://juejin.cn/post/7153878508035391502)\\n- Redis \u76f8\u5173\\n - \u2b50\ufe0f \u2b50\ufe0f [Redis\u8be6\u7ec6\u5165\u95e8\u6559\u7a0b](https://zhuanlan.zhihu.com/p/469102289)\\n - \u2b50\ufe0f [Redis \u53ea\u4f1a\u7528\u7f13\u5b58\uff1f16\u79cd\u5999\u7528\u8ba9\u540c\u4e8b\u76f4\u547c\u725bX](https://mp.weixin.qq.com/s/fnOvw4JfwszNGVBMW0N2hw)\\n - \u2b50\ufe0f [\u6df1\u5165\u6d45\u51fa\u5e26\u4f60\u8d70\u8fdbRedis\uff01](https://mp.weixin.qq.com/s/ThVtw8TVuhxIyYxJy6sOWw)\\n - \u2b50\ufe0f [\u4e07\u5b57\u56fe\u6587\u8bb2\u900f\u6570\u636e\u5e93\u7f13\u5b58\u4e00\u81f4\u6027\u95ee\u9898](https://mp.weixin.qq.com/s/U87wrGsx0Eop3CbF9mlTwQ)\\n - \u2b50\ufe0f [Redis \u4e8b\u52a1\u9047\u4e0a @Transactional \u6709\u5927\u5751\uff01\uff01\u8bb0\u4e00\u6b21 Redis \u751f\u4ea7\u4e8b\u6545](https://mp.weixin.qq.com/s/vwx99ER-9qiH9nfwtFW1zQ)\\n - \u2b50\ufe0f [Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848](https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw)\\n - \ud83c\udf1b [Redis \u6301\u4e45\u5316\u7b56\u7565\u6d45\u6790](https://juejin.cn/post/7147602740405862407)\\n - \ud83c\udf1b [\u56fe\u6587\u7ed3\u5408\uff01Redis\u5ef6\u8fdf\u961f\u5217golang\u9ad8\u6548\u5b9e\u8df5](https://mp.weixin.qq.com/s/dCZm7e0aSEirhEqiCBvAyQ)\\n - \u2b50\ufe0f [\u7528 Redis \u90fd\u80fd\u5b9e\u73b0\u54ea\u4e9b\u529f\u80fd\uff1f\u8fd92\u4e07\u5b57+20\u5f20\u56fe\u7ed9\u5206\u6790\u5168\u4e86](https://mp.weixin.qq.com/s/frOhO8rj2Xvdix6tnjTOrw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u8bc1\u6570\u636e\u5e93\u548c\u7f13\u5b58\u53cc\u5199\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/mO819q_r9qLVuRBE8cjx1Q)\\n - \u2b50\ufe0f [\u4e3a\u4e86\u62ff\u634f Redis \u6570\u636e\u7ed3\u6784\uff0c\u6211\u753b\u4e86 40 \u5f20\u56fe\uff08\u5b8c\u6574\u7248\uff09](https://mp.weixin.qq.com/s/Cq-CF1BC4PWwGnlRp4HrnQ)\\n - \u2b50\ufe0f [Redis 5 \u79cd\u57fa\u672c\u6570\u636e\u7ed3\u6784\uff08String\u3001List\u3001Hash\u3001Set\u3001Sorted Set\uff09\u8be6\u89e3 | JavaGuide](https://juejin.cn/post/7124572920403197965)\\n- Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\\n - [Redis\u5206\u5e03\u5f0f\u9501\u768410\u4e2a\u5751](https://mp.weixin.qq.com/s/2Rwy19C0eUshTWc_JfTPig)\\n - [\u6df1\u5165\u7406\u89e3 go singleflight](https://mp.weixin.qq.com/s/p2rlkCRRj7h7-aojTidQbg)\\n - [\u9762\u8bd5\u5b98\uff1a\u5982\u4f55\u7528 Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/ESdfA5sJa6bmL-HvuWpoJA)\\n - [\u5982\u4f55\u7528Redis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/RS1kKvF_Ly576GV52bHQPg)\\n - [Go\uff1a\u5206\u5e03\u5f0f\u9501\u5b9e\u73b0\u539f\u7406\u4e0e\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/lrSQBK-Kihkj6994kQFpUQ)\\n- Web Server\\n - \u2b50\ufe0f [\u8d85\u8d8a Nginx\uff01\u53f7\u79f0\u4e0b\u4e00\u4ee3 Web \u670d\u52a1\u5668\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://juejin.cn/post/7085519712901136392)\\n- IO\u591a\u8def\u590d\u7528\\n - \u2b50\ufe0f [\u4eceLinux\u96f6\u62f7\u8d1d\u6df1\u5165\u4e86\u89e3Linux-I/O](https://mp.weixin.qq.com/s/j1KjR5bRQV6oGrU5tsyHgg)\\n - \u2b50\ufe0f [\u6df1\u5165\u5b66\u4e60IO\u591a\u8def\u590d\u7528 select/poll/epoll \u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/5xj42JPKG8o5T7hjXIKywg)\\n - \u2b50\ufe0f [\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3](https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg)\\n - \u2b50\ufe0f [\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3](https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g)\\n- \u7cfb\u7edf\u8bbe\u8ba1\\n - \u2b50\ufe0f [\u6280\u672f\u603b\u76d1\u5206\u4eab\u7684\u7cfb\u7edf\u8bbe\u8ba1\u6280\u5de7\uff0c\u4e07\u80fd\u901a\u7528\uff0c\u7a33\u7684\u4e00\u6279\uff01](https://mp.weixin.qq.com/s/FJi3ko9wjTBNWS79RVQf5A)\\n - \u2b50\ufe0f [\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1\u768415\u4e2a\u9526\u56ca](https://mp.weixin.qq.com/s/PPA8Iw6K2M2xVnGE-Tf6zw)\\n - \u2b50\ufe0f [\u652f\u4ed8\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01](https://mp.weixin.qq.com/s/5Jj-IClPhInXz7xsfUZEnQ)\\n - \u2b50\ufe0f [\u8682\u8681\u91d1\u670d\u4e00\u9762\uff1a\u5341\u9053\u7ecf\u5178\u9762\u8bd5\u9898\u89e3\u6790](https://mp.weixin.qq.com/s/qhsVURhXm0Ot-jWq0khfEg)\\n - \u2b50\ufe0f [\u516c\u53f8\u65b0\u6765\u4e00\u4e2a\u540c\u4e8b\uff0c\u628a\u4f18\u60e0\u5238\u7cfb\u7edf\u8bbe\u8ba1\u7684\u7089\u706b\u7eaf\u9752\uff01](https://mp.weixin.qq.com/s/Ebh5iVsx0iExb5Wxq3tQFQ)\\n - \u2b50\ufe0f [\u7f51\u5173\u7cfb\u7edf\u5c31\u8be5\u8fd9\u4e48\u8bbe\u8ba1\uff08\u4e07\u80fd\u901a\u7528\uff09\uff0c\u7a33\u7684\u4e00\u6279\uff01](https://mp.weixin.qq.com/s/8GXe6sKPKk7Flbd_kNAp2Q)\\n - \u2b50\ufe0f [\u9ad8\u5e76\u53d1\u4e0b\uff0c\u5e42\u7b49\u6027\u5982\u4f55\u4fdd\u8bc1](https://mp.weixin.qq.com/s/crzfBEGn78nUZ5H3MF8UZw)\\n - \u2b50\ufe0f [Redis \u5b9e\u73b0\u5206\u5e03\u5f0f\u9501\u7684 7 \u79cd\u65b9\u6848](https://mp.weixin.qq.com/s/n6IEF2OinYN3slJXqc_xgw)\\n - [\u5982\u4f55\u8bbe\u8ba1\u4e00\u4e2a\u77ed\u94fe\u670d\u52a1](https://mp.weixin.qq.com/s/Z0xVHgw-ZzZV-jOOOSsMUw)\\n- \u6d88\u606f\u961f\u5217\\n - \u2b50\ufe0f [\u804a\u804aRocketMQ\u5b58\u50a8\u6a21\u578b](https://mp.weixin.qq.com/s/D8ptc4SCqWtaWe-ZBhwXfA)\\n - \u2b50\ufe0f [\u9762\u6e23\u9006\u88ad\uff1aRocketMQ\u4e8c\u5341\u4e09\u95ee](https://mp.weixin.qq.com/s/mNpXpSVVVBuI59LI6vVvQA)\\n - \u2b50\ufe0f [\u5228\u6839\u95ee\u5e95 Kafka\uff0c\u6838\u5fc3\u77e5\u8bc6\u70b9\u5927\u8d2f\u901a](https://mp.weixin.qq.com/s/GeXtCJgo42u92FSS5V6oMQ)\\n - \u2b50\ufe0f [\u6d88\u606f\u961f\u5217\u539f\u7406\u548c\u9009\u578b\uff1aKafka\u3001RocketMQ \u3001RabbitMQ \u548c ActiveMQ](https://mp.weixin.qq.com/s/J0zKPTNoJgiFvNT4M9BVcg)\\n - [\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u513f\u53eb MQ](https://mp.weixin.qq.com/s/i_bwyEb8QqfVLxY-R9odag)\\n- Elasticsearch \u76f8\u5173\\n - \u2b50\ufe0f [MyBatis-Plus\u540c\u6b3eElasticsearch ORM\u6846\u67b6\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://juejin.cn/post/7155662252584992805)\\n - \u2b50\ufe0f [Elasticsearch\u5feb\u901f\u5165\u95e8\uff0c\u638c\u63e1\u8fd9\u4e9b\u521a\u521a\u597d\uff01](https://juejin.cn/post/6844904117580595214)\\n - \u2b50\ufe0f [Elasticsearch \u57fa\u7840\u5165\u95e8\u8be6\u6587](https://mp.weixin.qq.com/s/GG_zrQlaiP2nfPOxzx_j9w)\\n- \u5927\u6570\u636e\u76f8\u5173\\n - [\u4e00\u6587\u4e86\u89e3-\u4e91\u539f\u751f\u5927\u6570\u636e\u77e5\u8bc6\u5730\u56fe](https://mp.weixin.qq.com/s/vua2g0_t1Y8KW4cNHSQdNw)\\n - [\u3010\u4e91\u539f\u751f\u3011Hive on k8s \u73af\u5883\u90e8\u7f72](https://juejin.cn/post/7149487706991493156)\\n - [\u5927\u6570\u636eHadoop\u4e4b\u2014\u2014\u6570\u636e\u4ed3\u5e93Hive](https://juejin.cn/post/7087484692718420005)\\n - [\u3010\u4e91\u539f\u751f\u3011Kubernetes\uff08k8s\uff09\u6700\u5b8c\u6574\u7248\u73af\u5883\u90e8\u7f72+master\u9ad8\u53ef\u7528\u5b9e\u73b0](https://juejin.cn/post/7136214451678052389)\\n - [Flink \u6d41\u6279\u4e00\u4f53\u5728\u5b57\u8282\u8df3\u52a8\u7684\u63a2\u7d22\u4e0e\u5b9e\u8df5](https://juejin.cn/post/7141215211586863140)\\n - [\u5927\u6570\u636e\u67b6\u6784\u7cfb\u5217\uff1a\u5982\u4f55\u7406\u89e3\u6e56\u4ed3\u4e00\u4f53](https://mp.weixin.qq.com/s/G66BCDUMzYE30p250JO0hg)\\n - [23\u5f20\u56fe\uff0c\u5e26\u4f60\u5165\u95e8\u63a8\u8350\u7cfb\u7edf](https://mp.weixin.qq.com/s/yQavfvBayYbMEc7c9ObMxg)\\n - [\u4e00\u6587\u770b\u61c2\u5927\u6570\u636e\u751f\u6001\u5708\u5b8c\u6574\u77e5\u8bc6\u4f53\u7cfb\uff08\u6587\u672b\u9001\u4e66\uff09](https://mp.weixin.qq.com/s/gAhoIwPoFDlKbBmWzrHu8w)\\n- \u4e91\u539f\u751f\u76d1\u63a7\\n - \u2b50\ufe0f [\u81ea\u4ece\u9879\u76ee\u4e0a\u4e86SkyWalking\uff0c\u7761\u89c9\u771f\u9999\uff01](https://mp.weixin.qq.com/s/72UbwZTxo36eJVqGq8HBgw)\\n - \u2b50\ufe0f [\u81ea\u4ece\u7ebf\u4e0a\u9879\u76ee\u7528\u4e86\u8fd9\u4e2a\u76d1\u63a7\u7cfb\u7edf\uff0c\u7761\u89c9\u771f\u9999\uff01](https://mp.weixin.qq.com/s/D1JoTzdQnzUgX_yqT3N1BQ)\\n - \u2b50\ufe0f [\u8fd8\u5728\u670d\u52a1\u5668\u4e0a\u635e\u65e5\u5fd7\uff1f\u5feb\u642d\u5efa\u4e00\u4e2aELK\u65e5\u5fd7\u7cfb\u7edf\u5427\uff0c\u771f\u5fc3\u5f3a\u5927\uff01](https://mp.weixin.qq.com/s/bSw_QP4-xMKnBTmqAjkUGA)\\n - \u2b50\ufe0f [\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01](https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg)\\n- \u2b50\ufe0f [\u4e00\u81f4\u6027\u54c8\u5e0c\u7b97\u6cd5\u89e3\u51b3\u7684\u95ee\u9898](https://mp.weixin.qq.com/s/hJHMlbQpANwMjx9BetwkUg)\\n- \u2b50\ufe0f [\u4e00\u81f4\u6027Hash\u7b97\u6cd5\u539f\u7406\u603b\u7ed3](https://zhuanlan.zhihu.com/p/482549860)\\n- \u2b50\ufe0f \u2b50\ufe0f [100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01](https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA)\\n- [\u89e3\u51b3\u4e86 Redis \u5927 key \u95ee\u9898\uff0c\u540c\u4e8b\u4eec\u90fd\u8bf4\u725b\u76ae\uff01](https://mp.weixin.qq.com/s/l3l9d9sLiWoUM381E9o-3Q)\\n- [\u56fe\u89e3|Linux\u5185\u5b58\u80cc\u540e\u7684\u90a3\u4e9b\u795e\u79d8\u5f80\u4e8b](https://mp.weixin.qq.com/s/l_YdpyHht5Ayvrc7LFZNIA)\\n- [\u56fe\u89e3|\u4ec0\u4e48\u662f\u5185\u5bb9\u5206\u53d1\u7f51\u7edc(cdn)](https://juejin.cn/post/7064952956201730062)\\n- [\u4e00\u952e\u90e8\u7f72 K8S \u73af\u5883\uff0c10\u5206\u949f\u73a9\u8f6c\uff0c\u8fd9\u6b3e\u5f00\u6e90\u795e\u5668\u5b9e\u5728\u592a\u9999\u4e86\uff01](https://juejin.cn/post/7070683049049980941)\\n- [\u989c\u503c\u7206\u8868\uff01Redis \u5b98\u65b9\u53ef\u89c6\u5316\u5de5\u5177\u6765\u5566\uff0c\u529f\u80fd\u771f\u5fc3\u5f3a\u5927\uff01](https://mp.weixin.qq.com/s/KIcn2TAwY58JGoWiz82Q2g)\\n- [Nginx\u7684\u8fd9\u4e9b\u5999\u7528\uff0c\u4f60\u80af\u5b9a\u6709\u4e0d\u77e5\u9053\u7684\uff01](https://juejin.cn/post/6844904017286561799)\\n- [\u524d\u7aef\u5230\u5e95\u7528nginx\u6765\u505a\u5565](https://juejin.cn/post/7064378702779891749)\\n- [\u4e00\u4efd\u7b80\u5355\u591f\u7528\u7684 Nginx Location \u914d\u7f6e\u8bb2\u89e3](https://juejin.cn/post/7048952689601806366)\\n\\n## \u524d\u7aef\u6027\u80fd\u4f18\u5316\\n\\n- \u2b50\ufe0f [\u5199\u7ed9\u4e2d\u9ad8\u7ea7\u524d\u7aef\u5173\u4e8e\u6027\u80fd\u4f18\u5316\u76849\u5927\u7b56\u7565\u548c6\u5927\u6307\u6807 | \u7f51\u6613\u56db\u5e74\u5b9e\u8df5](https://juejin.cn/post/6981673766178783262)\\n- \u2b50\ufe0f [\u524d\u7aef\u76d1\u63a7\u7cfb\u52173 \uff5c \u5982\u4f55\u8861\u91cf\u4e00\u4e2a\u7ad9\u70b9\u7684\u6027\u80fd\u597d\u574f](https://mp.weixin.qq.com/s/Au_NNeamEoFEtlNvvVjpLw)\\n- \u2b50\ufe0f [\u6700\u5168\u7684\u524d\u7aef\u6027\u80fd\u5b9a\u4f4d\u603b\u7ed3](https://juejin.cn/post/7052918009555320839)\\n- \u2b50\ufe0f [Web\u9875\u9762\u5168\u94fe\u8def\u6027\u80fd\u4f18\u5316\u6307\u5357](https://mp.weixin.qq.com/s/wJxj5QbOHwH9cKmqU5eSQw)\\n- \u2b50\ufe0f [\u5b57\u8282\u8df3\u52a8\u662f\u5982\u4f55\u843d\u5730\u5fae\u524d\u7aef\u7684](https://juejin.cn/post/7016900744695513125)\\n- \u2b50\ufe0f [2022 \u5e74\u7684 CSS](https://juejin.cn/post/7048260643589193765)\\n- \u2b50\ufe0f [\u5982\u4f55\u7f16\u5199\u9632\u5fa1\u5f0f\u7684 CSS](https://juejin.cn/post/7054931603323093022)\\n- \u2b50\ufe0f [\u524d\u7aef Code Review \u4e0d\u5b8c\u5168\u6307\u5317(\u4e07\u5b57\u957f\u6587\uff0c50+case)](https://zhuanlan.zhihu.com/p/396010993)\\n- \ud83c\udf1b [\u5199\u5728 2021 \u7684\u524d\u7aef\u6027\u80fd\u4f18\u5316\u6307\u5357](https://juejin.cn/post/7020212914020302856)\\n- [\u6df1\u5165\u6d45\u51fa Performance \u5de5\u5177 & API](https://juejin.cn/post/7000728875676205086)\\n- [\u4f7f\u7528 Performance \u770b\u770b\u6d4f\u89c8\u5668\u5728\u505a\u4ec0\u4e48](https://juejin.cn/post/6904582930174705677)\\n\\n## \u524d\u7aef\u7ec4\u4ef6\u5e93\u5b9e\u6218\\n\\n- \u2b50\ufe0f [\u5feb\u4e0a\u8f66\uff01\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01](https://juejin.cn/post/7120893568553582622)\\n- \u2b50\ufe0f [\u4f7f\u7528Vite\u548cTypeScript\u5e26\u4f60\u4ece\u96f6\u6253\u9020\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684Vue3\u7ec4\u4ef6\u5e93](https://juejin.cn/post/7117886038126624805)\\n- \u2b50\ufe0f [\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6](https://juejin.cn/post/7069772395610898462)\\n- \u2b50\ufe0f [\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1](https://juejin.cn/post/6844904197863964685)\\n- \u2b50\ufe0f [\u5c24\u5927\u90fd\u63a8\u8350\u7684\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u5f00\u53d1\u51fa\u6765\u7684\uff1f](https://juejin.cn/post/7021528826798669854)\\n- [\u6bcf\u4e2a\u524d\u7aef\u90fd\u503c\u5f97\u62e5\u6709\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff0c\u5c31\u50cf\u6bcf\u4e2a\u590f\u5929\u90fd\u62e5\u6709\u897f\u74dc\ud83c\udf49](https://juejin.cn/post/6983854006124675108)\\n- [Vue3\u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218 --Element3](https://juejin.cn/post/6930879590554402830)\\n\\n## Node.js \u7cfb\u5217\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217](https://github.com/koala-coding/goodBlog)\\n- \u2b50\ufe0f \u2b50\ufe0f [Node.js \u6982\u8ff0\uff1a\u67b6\u6784\u3001API\u3001\u4e8b\u4ef6\u5faa\u73af\u3001\u5e76\u53d1](https://mp.weixin.qq.com/s/B051n14JbNHqJtQb68HBFA)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0a\u3011](https://mp.weixin.qq.com/s/sSfj4BOjHNyzdjGc90yU8g)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u4e00\u7bc7\u6587\u7ae0\u6784\u5efa\u4f60\u7684 NodeJS \u77e5\u8bc6\u4f53\u7cfb\u3010\u4e0b\u3011](https://mp.weixin.qq.com/s/9SJL2UttCedNjF6CKyk3wg)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u5927\u5382\u662f\u5982\u4f55\u7528DevCloud\u6d41\u6c34\u7ebf\u5b9e\u73b0\u81ea\u52a8\u5316\u90e8\u7f72Web\u5e94\u7528\u7684\uff1f](https://juejin.cn/post/6887961766170066951)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u624b\u628a\u624b\u6559\u4f60\u4f7f\u7528Rollup\u6253\u5305 \ud83d\udce6 \u5e76\u53d1\u5e03\u81ea\u5df1\u7684\u5de5\u5177\u5e93 \ud83d\udd27](https://juejin.cn/post/6902659492161421325)\\n- \ud83c\udf1b [Node \u6848\u53d1\u73b0\u573a\u63ed\u79d8 \u2014\u2014 \u672a\u5b9a\u4e49 \u201cwindow\u201d \u5bf9\u8c61\u5f15\u53d1\u7684 SSR \u5185\u5b58\u6cc4\u9732](https://zhuanlan.zhihu.com/p/461945753)\\n- \ud83c\udf1b [\u8f7b\u677e\u6392\u67e5\u7ebf\u4e0aNode\u5185\u5b58\u6cc4\u6f0f\u95ee\u9898](https://cnodejs.org/topic/58eb5d378cda07442731569f)\\n- \u2b50\ufe0f [Node.js \u6d41\uff08stream\uff09\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://zhuanlan.zhihu.com/p/36728655)\\n- \ud83c\udf1b [\u6700\u5168\u9762\u7684 Node.js \u8d44\u6e90\u6c47\u603b\u63a8\u8350](https://mp.weixin.qq.com/s/1DIDUvGoQcckRq757R9Ohw)\\n- \u2b50\ufe0f [Nest.js\u8fdb\u9636\u7cfb\u5217\u56db\uff1aNode.js\u4e2d\u4f7f\u7528Redis\u539f\u6765\u8fd9\u4e48\u7b80\u5355\uff01](https://mp.weixin.qq.com/s/yKm_U9Veh_1twIoXzM8Prw)\\n- \u2b50\ufe0f [Redis\u5b66\u4e60-\u5165\u95e8\u7bc7](https://mp.weixin.qq.com/s/TmCtsbhjexZNCdvUSXdNCw)\\n- \u2b50\ufe0f [Node.js \u5b89\u5168\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/2CBGgtja04NnOerpKfk0Ug)\\n- \u2b50\ufe0f [2022\u5e74\u503c\u5f97\u4f7f\u7528\u7684 Node.js \u6846\u67b6](https://mp.weixin.qq.com/s/PhuFfNAhvXAqW4eSbUqpKQ)\\n- \ud83c\udf1b [NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357](https://juejin.cn/post/7095354780079357966)\\n- \u2b50\ufe0f [Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb](https://zhuanlan.zhihu.com/p/502951532)\\n- \ud83c\udf1b [\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93](https://zhuanlan.zhihu.com/p/415361629)\\n- \ud83c\udf1b [unjs: Unified JavaScript Tools](https://github.com/unjs)\\n- \ud83c\udf1b [pkg - \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6](https://github.com/vercel/pkg)\\n- \u2b50\ufe0f [Oclif v2.5\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6](https://github.com/oclif/oclif)\\n- \ud83c\udf1b [JavaScript Debugger \u539f\u7406\u63ed\u79d8](https://juejin.cn/post/6961790494514872333)\\n- \ud83c\udf1b [\u6d45\u8c08 Node.js \u70ed\u66f4\u65b0](https://mp.weixin.qq.com/s/xCoTeyJDifi4Ymk0VsI2Ig)\\n- \u2b50\ufe0f [NodeJS\u52a0\u89e3\u5bc6\u4e4bCrypto](https://juejin.cn/post/7044344538969669663)\\n- \ud83c\udf1b [zx - \u8c37\u6b4c\u5f00\u53d1\u7684\u547d\u4ee4\u884c\u811a\u672c\u5de5\u5177](https://github.com/google/zx)\\n- \ud83c\udf1b [node-fetch - node \u73af\u5883\u4e0b\u8fdb\u884c\u7f51\u7edc\u8bf7\u6c42](https://github.com/node-fetch/node-fetch)\\n- \u2b50\ufe0f [\u6d45\u6790 NodeJS \u591a\u8fdb\u7a0b\u548c\u96c6\u7fa4](https://juejin.cn/post/6971770846872338439)\\n- \u2b50\ufe0f [Tasuku - \u9762\u5411 Node \u7684\u6700\u5c0f\u4efb\u52a1\u8fd0\u884c\u5668](https://github.com/privatenumber/tasuku)\\n- \ud83c\udf1b [Node.js\u7684\u5e95\u5c42\u539f\u7406](https://juejin.cn/post/7008504029277847565)\\n- \u2b50\ufe0f [\u8ba4\u771f\u5199\u4e86\u4e2a\u5feb\u901f\u521b\u5efa Node \u670d\u52a1\u7684CLI\uff0c\u770b\u770b\u5bf9\u5c0f\u4f19\u4f34\u4eec\u6709\u5e2e\u5fd9\u5417\uff1f](https://mp.weixin.qq.com/s/Gcx6E4cYo6WPB8PLI72NWg)\\n - \u9879\u76ee\u5730\u5740\uff1ahttps://github.com/koala-coding/create-bff-service-cli\\n\\nimport Tabs from \'@theme/Tabs\';\\nimport TabItem from \'@theme/TabItem\';\\n\\n\\n\\n\\n- \u2b50\ufe0f [taze - \u66f4\u65b0\u4f9d\u8d56\u7248\u672c\u7684 CLI \u5de5\u5177](https://github.com/antfu/taze)\\n- \u2b50\ufe0f [haya - Vite \u7684\u66ff\u4ee3\u65b9\u6848\uff0c\u63d0\u4f9b\u57fa\u4e8e esbuild \u7684 devServer \u548c bundler](https://github.com/egoist/haya)\\n- \u2b50\ufe0f [unbuild - \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177](https://github.com/unjs/unbuild)\\n- \u2b50\ufe0f [tsup - \u96f6\u914d\u7f6e\u7684 TS \u7b2c\u4e09\u65b9\u5e93\u6253\u5305\u5de5\u5177](https://github.com/egoist/tsup)\\n- \u2b50\ufe0f [degit - \u7b80\u5355\u7684\u9879\u76ee\u811a\u624b\u67b6](https://github.com/Rich-Harris/degit)\\n- \u2b50\ufe0f [react-use - \u4e00\u4e2a React Hooks \u5e93](https://github.com/streamich/react-use)\\n- [react-query - \u7528\u4e8e\u83b7\u53d6\u6570\u636e\u3001\u7f13\u5b58\u3001\u5f02\u6b65\u66f4\u65b0\u72b6\u6001\u7684 hook](https://github.com/tannerlinsley/react-query)\\n- [ioredis - \u4e13\u6ce8\u4e8e\u6027\u80fd\u7684\u5168\u529f\u80fd Redis \u5ba2\u6237\u7aef](https://github.com/luin/ioredis)\\n- [prisma - \u4e0b\u4e00\u4ee3 Nodejs ORM \u5de5\u5177\uff0c\u652f\u6301\u5404\u79cd\u6570\u636e\u5e93](https://github.com/prisma/prisma)\\n- [astro - \u9759\u6001\u7ad9\u70b9\u6784\u5efa\u5de5\u5177](https://github.com/withastro/astro)\\n- [zustand - \u5c0f\u578b\u3001\u5feb\u901f\u53ef\u6269\u5c55\u7684\u72b6\u6001\u7ba1\u7406\u89e3\u51b3\u65b9\u6848](https://github.com/pmndrs/zustand)\\n- [tauri - \u5c06\u524d\u7aef\u9879\u76ee\u6253\u5305\u4e3a\u684c\u9762\u5e94\u7528\uff0c\u7528\u4e8e\u66ff\u4ee3 electron](https://github.com/tauri-apps/tauri)\\n- [tRPC - \u65b9\u4fbf\u5feb\u901f\u7684\u751f\u6210\u7aef\u5bf9\u7aef\u7c7b\u578b\u5b89\u5168\u7684 API \u5b9a\u4e49](https://github.com/trpc/trpc)\\n- [Drift - \u4e00\u4e2a\u53ef\u4ee5\u81ea\u5df1\u90e8\u7f72\u7684\u4ee3\u7801\u7247\u6bb5\u670d\u52a1\uff0c\u57fa\u4e8e Next.js 13 \u6784\u5efa](https://github.com/MaxLeiter/Drift)\\n\\n\\n\\n\\n- \u2b50\ufe0f [bytemd - \u5b57\u8282\u51fa\u54c1\u7684 markdown \u7f16\u8f91\u5668](https://github.com/bytedance/bytemd)\\n- \u2b50\ufe0f [guide - \u5b57\u8282\u51fa\u54c1\u7684 React \u65b0\u624b\u5f15\u5bfc\u7ec4\u4ef6](https://github.com/bytedance/guide)\\n- \u2b50\ufe0f [react-medium-image-zoom - \u53d7 Medium.com \u542f\u53d1\u7684\u56fe\u7247\u9884\u89c8\u7ec4\u4ef6](https://github.com/rpearce/react-medium-image-zoom)\\n- \u2b50\ufe0f [cmdk - \u4e00\u4e2a\u57fa\u4e8e React \u7684\u5feb\u901f\u3001\u53ef\u7ec4\u5408\u3001\u65e0\u98ce\u683c\u7684\u547d\u4ee4\u9762\u677f](https://github.com/pacocoursey/cmdk)\\n- \u2b50\ufe0f [nice-modal-react\uff1a\u6765\u81ea eBay \u7684\u6a21\u6001\u6846\u72b6\u6001\u7ba1\u7406](https://github.com/eBay/nice-modal-react)\\n\\n\\n\\n\\n- \u2b50\ufe0f [date-fns - \u73b0\u4ee3\u5316\u7684 JavaScript \u65e5\u671f\u7c7b\u5e93](https://github.com/date-fns/date-fns)\\n- \u2b50\ufe0f [nanoid - \u7528\u4e8e\u66ff\u4ee3 uuid \u7684\u968f\u673a id \u751f\u6210\u5e93](https://github.com/ai/nanoid)\\n- `dayjs`\uff1a\u4e0e `moment` \u7684 API \u8bbe\u8ba1\u4fdd\u6301\u4e00\u6837\uff0c\u4f46\u4f53\u79ef\u4ec5\u6709 2KB\uff1b\\n- `qs`\uff1a\u89e3\u6790 URL query \u53c2\u6570\u7684\u5e93\uff1b\\n- `js-cookie`\uff1a\u7b80\u5355\u3001\u8f7b\u91cf\u7684\u5904\u7406 cookie \u7684\u5e93\uff1b\\n- `flv.js`\uff1abilibili \u5f00\u6e90\u7684 HTML5 flash \u64ad\u653e\u5668\uff0c\u4f7f\u6d4f\u89c8\u5668\u5728\u4e0d\u501f\u52a9 flash \u63d2\u4ef6\u7684\u60c5\u51b5\u4e0b\u53ef\u4ee5\u64ad\u653e flv\uff1b\\n- `vConsole`\uff1a\u4e00\u4e2a\u8f7b\u91cf\u3001\u53ef\u62d3\u5c55\u3001\u9488\u5bf9\u624b\u673a\u7f51\u9875\u7684\u524d\u7aef\u5f00\u53d1\u8005\u8c03\u8bd5\u9762\u677f\uff1b\\n- `animate.css`\uff1a\u4e00\u4e2a\u8de8\u6d4f\u89c8\u5668\u7684 css3 \u52a8\u753b\u5e93\uff0c\u5185\u7f6e\u4e86\u5f88\u591a\u5178\u578b\u7684 css3 \u52a8\u753b\uff0c\u517c\u5bb9\u6027\u597d\uff0c\u4f7f\u7528\u65b9\u4fbf\uff1b\\n- `lodash`\uff1a\u4e00\u4e2a\u4e00\u81f4\u6027\u3001\u6a21\u5757\u5316\u3001\u9ad8\u6027\u80fd\u7684 JavaScript \u5b9e\u7528\u5de5\u5177\u5e93\uff1b\\n\\n\\n\\n\\n- \u2b50\ufe0f [chokidar - \u8de8\u5e73\u53f0\u76d1\u542c\u6587\u4ef6\u53d8\u5316](https://github.com/paulmillr/chokidar)\\n- \u2b50\ufe0f [fs-extra - Node \u539f\u751f fs \u6a21\u5757\u7684\u6269\u5c55](https://github.com/jprichardson/node-fs-extra)\\n- `yargs`\uff1a\u901a\u8fc7\u4f7f\u7528 Node.js \u6784\u5efa\u529f\u80fd\u5168\u9762\u7684\u547d\u4ee4\u884c\u5e94\u7528\\n- `Ajv`\uff1a\u4e00\u4e2a\u9002\u7528\u4e8e Node.js \u548c\u6d4f\u89c8\u5668\u7684\u6700\u5feb JSON \u9a8c\u8bc1\u5668\\n- `yallist`\uff1a\u4e00\u4e2a\u53cc\u5411\u94fe\u8868\u7684\u5b9e\u73b0\\n- `rimraf`\uff1aNode.js \u7684 rm -rf \u5b9e\u7528\u7a0b\u5e8f\\n- `consola`\uff1aNuxt.js \u51fa\u54c1\u7684\u7ec8\u7aef\u65e5\u5fd7\u5de5\u5177\\n- `webpackbar`\uff1aNuxt.js \u51fa\u54c1\u7684 webpack \u7f16\u8bd1\u8fdb\u5ea6\u6761\\n- `pkg`: \u628a Node.js \u9879\u76ee\u6253\u5305\u4e3a\u53ef\u6267\u884c\u6587\u4ef6\\n- `concurrently`\uff1a\u66f4\u4f18\u96c5\u5730\u5e76\u53d1\u6267\u884c\u547d\u4ee4\\n- `better-logging`\uff1aNode \u9ed8\u8ba4\u65e5\u5fd7\u8bb0\u5f55\u65b9\u6cd5\u7684\u66ff\u4ee3\u54c1\\n\\n\\n\\n\\n- `chalk/kolorist`\\n- `inquirer/prompts`\\n- `ora`\\n- `semver`\\n- `pkg-install`\\n- `ncp`\uff1a\u8de8\u5e73\u53f0\u9012\u5f52\u62f7\u8d1d\u6587\u4ef6\\n- `commander/yargs`\\n- `execa`\uff08\u4e2a\u4eba\u89c9\u5f97 Node \u539f\u751f `child_process` \u7684 `exec` \u5c31\u591f\u7528\u4e86\uff09\\n- `minimist`\\n- `oclif`\uff1aHeroku \u5f00\u6e90\u7684 CLI \u6846\u67b6\\n\\n\\n\\n\\n## \u524d\u7aef\u7f16\u8bd1\\n\\n- [\u3010\u7b2c2597\u671f\u3011\u5982\u4f55\u7528JavaScript\u5b9e\u73b0\u4e00\u95e8\u7f16\u7a0b\u8bed\u8a00 - AST](https://mp.weixin.qq.com/s/JMl8LOsNYlttxO-KyVK-Vw)\\n- [V8 \u7f16\u8bd1\u6d45\u8c08](https://juejin.cn/post/7041021350114230285)\\n- \u2b50\ufe0f [\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e8c\uff09\u2014\u2014 Antlr \u53ca\u5176\u5e94\u7528](https://juejin.cn/post/7057354419888717855)\\n- \u2b50\ufe0f [\u7f16\u8bd1\u6280\u672f\u5728\u524d\u7aef\u7684\u5b9e\u8df5\uff08\u4e00\uff09\u2014\u2014 \u7f16\u8bd1\u539f\u7406\u57fa\u7840](https://juejin.cn/post/6989509925844041742)\\n- \u2b50\ufe0f [Babel \u63d2\u4ef6\u901a\u5173\u79d8\u7c4d](https://juejin.cn/book/6946117847848321055)\\n- \ud83c\udf1b [v8 \u6267\u884c js \u7684\u8fc7\u7a0b](https://www.zoo.team/article/the-process-of-executing-js-in-v8)\\n- \ud83c\udf1b [\u786c\u6838\u51b7\u77e5\u8bc6\uff1aV8\u4e0eWebAssembly\u4e0d\u5f97\u4e0d\u8bf4\u7684\u79d8\u5bc6](https://laocuicode.cn/daydream/2022/04/01/202241-%E7%A1%AC%E6%A0%B8%E5%86%B7%E7%9F%A5%E8%AF%86%EF%BC%9AWebAssembly/)\\n- [import \u65b9\u5f0f\u968f\u610f\u4e92\u8f6c\uff0c\u611f\u53d7 babel \u63d2\u4ef6\u7684\u5a01\u529b](https://juejin.cn/post/7018563244679757855)\\n- [\u4ece\u96f6\u5230\u4e00\uff0c\u6211\u4eec\u6765\u4e00\u8d77\u9020\u4e2a JS \u7684\u7f16\u8bd1\u5668](https://mp.weixin.qq.com/s/pNossFUtJrDHshXbWLb4vA)\\n- [\u6d45\u6790TypeScript Compiler \u539f\u7406](https://juejin.cn/post/7047329886502912030)\\n- \u2b50\ufe0f [\u300a\u4ece 0 \u5230 1 \u624b\u5199 babel\u300b\u601d\u8def\u5206\u4eab](https://juejin.cn/post/6962861837800964133)\\n- [\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357](https://juejin.cn/post/6953963506693570573)\\n\\n## \u7f51\u7edc\u76f8\u5173\\n\\n- [HTTP/3 From A To Z: Core Concepts](https://www.smashingmagazine.com/2021/08/http3-core-concepts-part1/)\\n- [502\u95ee\u9898\u600e\u4e48\u6392\u67e5](https://juejin.cn/post/7155280646112280613)\\n- [\u521a\u63d2\u4e0a\u7f51\u7ebf\uff0c\u7535\u8111\u600e\u4e48\u77e5\u9053\u81ea\u5df1\u7684IP\u662f\u4ec0\u4e48](https://juejin.cn/post/7153255870447484936)\\n- [\u52a8\u56fe\u56fe\u89e3 | UDP\u5c31\u4e00\u5b9a\u6bd4TCP\u5feb\u5417](https://juejin.cn/post/7147243567075819557)\\n- [\u7528\u4e86TCP\u534f\u8bae\uff0c\u5c31\u4e00\u5b9a\u4e0d\u4f1a\u4e22\u5305\u5417](https://juejin.cn/post/7126710506936598558)\\n- \u2b50\ufe0f [HTTPS \u5c31\u4e00\u5b9a\u5b89\u5168\uff1f\u6211\u4e0d\u4fe1](https://mp.weixin.qq.com/s/nS1bMy2TejmGwEfCHPXy5A)\\n- \u2b50\ufe0f [\u80fdping\u901a\uff0cTCP\u5c31\u4e00\u5b9a\u80fd\u8fde\u901a\u5417](https://mp.weixin.qq.com/s/fb2uUWz5ZjPEfYv_l6e4Zg)\\n- [Linux \u662f\u5982\u4f55\u6536\u53d1\u7f51\u7edc\u5305\u7684](https://mp.weixin.qq.com/s/RJp9s_shNckkHBqHsJThuA)\\n- [\u5b57\u8282\u4e09\u9762\uff0c\u7b54\u7684\u4e0d\u6ee1\u610f](https://mp.weixin.qq.com/s/7P_1VkBeoArKuuEqGcR9ig)\\n- [\u4f53\u9a8c http3: \u57fa\u4e8e nginx quic \u5206\u652f](https://mp.weixin.qq.com/s/8CPWh_Ly61m8rkHvPT5n2g)\\n- [HTTP/3\u53d1\u5e03\u4e86\uff0c\u6211\u4eec\u6765\u8c08\u8c08HTTP/3](https://mp.weixin.qq.com/s/nRHlwYsr0MaadmaFWEIblQ)\\n- [\u65e2\u7136\u6709 HTTP \u534f\u8bae\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u8981\u6709 RPC](https://mp.weixin.qq.com/s/qmnfmUCdekEt1xG0hp_4MQ)\\n- [\u5b57\u8282\u4e00\u9762\uff1aTCP \u548c UDP \u53ef\u4ee5\u4f7f\u7528\u540c\u4e00\u4e2a\u7aef\u53e3\u5417](https://mp.weixin.qq.com/s/3fMZN_LidCi5fiD16nNWWA)\\n- \u2b50\ufe0f [\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee](https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg)\\n- \u2b50\ufe0f [\u5b57\u8282\u4e00\u9762\uff1a\u5982\u4f55\u7528 UDP \u5b9e\u73b0\u53ef\u9760\u4f20\u8f93](https://mp.weixin.qq.com/s/hX75YxVOMtsnB6Sm_yjm0g)\\n- \u2b50\ufe0f [TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86](https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw)\\n- \u2b50\ufe0f [(\u5efa\u8bae\u6536\u85cf)TCP\u534f\u8bae\u7075\u9b42\u4e4b\u95ee\uff0c\u5de9\u56fa\u4f60\u7684\u7f51\u8def\u5e95\u5c42\u57fa\u7840](https://juejin.cn/post/6844904070889603085)\\n- \u2b50\ufe0f [TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f](https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g)\\n- \u63a8\u8350\u770b\u770b QUIC 101 \u89c6\u9891\u4ee5\u53ca [The QUIC transport protocol: design and Internet-scale deployment](https://courses.cs.washington.edu/courses/cse550/20au/papers/CSE550.quic.pdf) \u8bba\u6587\\n- \u2b50\ufe0f [\u4e00\u6587\u5f7b\u5e95\u641e\u61c2\u52a0\u5bc6\u3001\u6570\u5b57\u7b7e\u540d\u548c\u6570\u5b57\u8bc1\u4e66\uff01](https://segmentfault.com/a/1190000024523772)\\n- \u2b50\ufe0f [\u4e00\u4e2aResponse Header\u5f15\u53d1\u7684\u8840\u6848(\u5305\u542bCDN\u7684\u76f8\u5173\u6982\u5ff5)](https://juejin.cn/post/6944420222757503006)\\n\\n## \u64cd\u4f5c\u7cfb\u7edf\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [The Art of Command Line](https://github.com/jlevy/the-art-of-command-line)\\n- \u2b50\ufe0f [\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01](https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA)\\n- \u2b50\ufe0f [Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0a\uff09](https://mp.weixin.qq.com/s/94F4v1E9sB82lOr2DeSK0A)\\n- \u2b50\ufe0f [Arch Linux \u5b8c\u5168\u624b\u518c\uff08\u4e0b\uff09](https://mp.weixin.qq.com/s/ev8hnv-coGLobrbezMK1og)\\n- \u2b50\ufe0f [\u770b\u5b8c\u8fd9\u7bc7\u4f60\u4e00\u5b9a\u80fd\u638c\u63e1Linux](https://mp.weixin.qq.com/s/ZralWEfG2WJfZ-G-x9biow)\\n- \u2b50\ufe0f [2\u4e07\u5b57\u7cfb\u7edf\u603b\u7ed3\uff0c\u5e26\u4f60\u5b9e\u73b0 Linux \u547d\u4ee4\u81ea\u7531](https://juejin.cn/post/6938385978004340744)\\n- [6w\u5b57\u641e\u5b9aLinux\u57fa\u672c\u64cd\u4f5c\uff0c\u5efa\u8bae\u6536\u85cf](https://juejin.cn/post/6917096816118857736)\\n- [\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6](https://juejin.cn/post/6844904080972709901)\\n- [\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/6875323565479034894)\\n\\n## \u673a\u5668\u5b66\u4e60\\n\\n- \u672c\u5730\u8fd0\u884c Stable Diffusion \u9884\u8bad\u7ec3\u6a21\u578b\\n - [AI\u6570\u5b57\u7ed8\u753b stable-diffusion \u4fdd\u59c6\u7ea7\u6559\u7a0b](https://mp.weixin.qq.com/s/nDnQuZn3hVgrwqWVada2cw)\\n - https://lexica.art/?q=fc98f231-c95f-4a68-8727-899c73dbc486\\n - https://huggingface.co/CompVis/stable-diffusion-v1-4\\n - https://github.com/CompVis/stable-diffusion\\n - https://huggingface.co/blog/stable_diffusion\\n- [\u4e0d\u4f1a\u7b97\u6cd5\u4e5f\u80fd\u5fae\u8c03\u4e00\u4e2a NLP \u9884\u8bad\u7ec3\u6a21\u578b](https://juejin.cn/post/7146575333721341966)\\n- [\u4eba\u5de5\u795e\u7ecf\u7f51\u7edc\u7b97\u6cd5\u5165\u95e8](https://mp.weixin.qq.com/s/BcXl8YQVNQA6auilbxW0kQ)\\n- [\u6d45\u6790\u795e\u7ecf\u7f51\u7edc Neural Networks](https://mp.weixin.qq.com/s/gaOzwCypQMFAJ4X50aUOcg)\\n- [\u524d\u7aef\u5de5\u7a0b\u5e08\u5982\u4f55\u5feb\u901f\u4f7f\u7528\u4e00\u4e2aNLP\u6a21\u578b](https://juejin.cn/post/7075518863814869005)\\n- \u6df1\u5165\u7406\u89e3 Transformer\uff1a\\n - https://www.bilibili.com/video/BV1P4411F77q\\n - https://www.bilibili.com/video/BV1Mt411J734\\n- [\u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b- bilibili](https://www.bilibili.com/video/BV1cD4y1D7uR)\\n- [\u300a\u8ba1\u7b97\u673a\u7f51\u7edc\u81ea\u9876\u5411\u4e0b\u65b9\u6cd5\u300b- bilibili](https://www.bilibili.com/video/BV1mb4y1d7K7)\\n - \u8fd9\u672c\u4e66\u91cd\u70b9\u7ae0\u8282\u662f\u7b2c2\u30013\u30014\u30015\u30016\u7ae0\uff0c\u5176\u4ed6\u7ae0\u8282\u53ef\u4ee5\u8df3\u8fc7\\n- \u5b66\u4e60\u8d44\u6e90\\n - https://github.com/ossu/computer-science\\n - https://github.com/Snailclimb/JavaGuide\\n - https://github.com/QSCTech/zju-icicles\\n- [\u4e00\u5929\u5b66\u4f1a MySQL \u6570\u636e\u5e93](https://www.bilibili.com/video/BV1Vt411z7wy)\\n- [\u5434\u6069\u8fbe\u300a\u6df1\u5ea6\u5b66\u4e60\u300b](https://www.bilibili.com/video/BV1FT4y1E74V)\\n- [\u63a8\u8350\u7cfb\u7edf\u7b97\u6cd5\u57fa\u7840+\u7efc\u5408\u9879\u76ee\u5b9e\u6218](https://www.bilibili.com/video/BV1qK4y1479r)\\n - \u518d\u5c31\u662f\u4e00\u4e9b\u6211\u8ba4\u4e3a\u5f88\u4f18\u79c0\u7684\u5f00\u6e90\u9879\u76ee\uff1a\\n - https://github.com/zhongqiangwu960812/AI-RecommenderSystem\\n - https://github.com/ZiyaoGeng/Recommender-System-with-TF2.0\\n- \u53c2\u8003\uff1a[\u4e07\u5b57\u5165\u95e8\u63a8\u8350\u7cfb\u7edf\uff01](https://mp.weixin.qq.com/s/YbwQAPIEkihO7XzVvrlDCg)\\n- [\u8bf4\u4e00\u8bf4Web\u7aef\u4fa7AI](https://juejin.cn/post/7013674501116264484)\\n- [\u673a\u5668\u5b66\u4e60\u521d\u63a2-\u7ebf\u6027\u56de\u5f52](https://juejin.cn/post/6964335363787620383)\\n- [\u673a\u5668\u5b66\u4e60\u8fdb\u9636 - \u6df1\u5165\u601d\u8003\u903b\u8f91\u56de\u5f52](https://juejin.cn/post/6951340421658181646)\\n\\n## LLM \u6280\u672f\u8c03\u7814\\n\\n- [\u4f7f\u7528 Transformers \u91cf\u5316 Meta AI LLaMA2 \u4e2d\u6587\u7248\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/Fo26NbtK8wFiHEGP0nhzuQ)\\n- [\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u4e2d\u6587\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/9cTNa_oya2Zj9YdDYodCvw)\\n- [\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u5b98\u65b9\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/NJ1JXkAK9LTSuor0mxtz1A)\\n- [AI \u52a0\u6301\u7684\u4ee3\u7801\u7f16\u5199\u5b9e\u6218\uff1a\u5feb\u901f\u5b9e\u73b0 Nginx \u914d\u7f6e\u683c\u5f0f\u5316\u5de5\u5177](https://mp.weixin.qq.com/s/iKtNOWkycm0FcMwnwq2M-A)\\n- [\u8ba9 OpenAI \u66f4 Open\uff0c\u5728 ChatGPT \u91cc\u81ea\u7531\u63a5\u5165\u6570\u636e\u6e90](https://mp.weixin.qq.com/s/o-6Xg1f7SMX-BUFgXgwb8w)\\n- [\u516b\u5341\u884c\u4ee3\u7801\u5b9e\u73b0\u5f00\u6e90\u7684 Midjourney\u3001Stable Diffusion \u201c\u5492\u8bed\u201d\u4f5c\u56fe\u5de5\u5177](https://mp.weixin.qq.com/s/Qo1--bFCzdNHAdesshrUuQ)\\n- [\u6a21\u578b\u6742\u8c08\uff1a1.5G \u663e\u5b58\u5c31\u80fd\u8fd0\u884c\u7684 RNN 14B \u7684\u5f00\u6e90\u6a21\u578b\uff08ChatRWKV\uff09](https://mp.weixin.qq.com/s/vH5zkdQ9esiMeg3L9TYgvw)\\n- [\u4f7f\u7528 Docker \u548c Alpaca LoRA \u5bf9 LLaMA 65B \u5927\u6a21\u578b\u8fdb\u884c Fine-Tune](https://mp.weixin.qq.com/s/cVR9yYP8zDiVBPEo91dSSA)\\n- [\u57fa\u4e8e Docker \u7684\u6df1\u5ea6\u5b66\u4e60\u73af\u5883\uff1a\u5165\u95e8\u7bc7](https://mp.weixin.qq.com/s/6Ae6SgEws5gndQwmZqkcUg)\\n- [\u6a21\u578b\u6742\u8c08\uff1a\u4f7f\u7528 IN8 \u91cf\u5316\u63a8\u7406\u8fd0\u884c Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09](https://mp.weixin.qq.com/s/6oKORqZWX7IlQFI5zbLKCw)\\n- [\u6a21\u578b\u6742\u8c08\uff1a\u5feb\u901f\u4e0a\u624b\u5143\u5b87\u5b99\u5927\u5382 Meta \u201c\u5f00\u6e90\u6cc4\u9732\u201d\u7684\u5927\u6a21\u578b\uff08LLaMA\uff09](https://mp.weixin.qq.com/s/vc4t7sm-BhAYtE7_J8DekQ)\\n- [RSS Can\uff1a\u501f\u52a9 V8 \u8ba9 Golang \u5e94\u7528\u5177\u5907\u52a8\u6001\u5316\u80fd\u529b\uff08\u4e8c\uff09](https://mp.weixin.qq.com/s/YKzWBa9kGbzwUpy2iuPjNA)\\n- [\u5728\u642d\u8f7d M1 \u53ca M2 \u82af\u7247 MacBook\u8bbe\u5907\u4e0a\u73a9 Stable Diffusion \u6a21\u578b](https://mp.weixin.qq.com/s/UO6_L_oVe3-ocOyt6R_YTA)\\n- [Linux \u8f6f\u4ef6\u5305\u4e0b\u8f7d\u52a0\u901f\u5de5\u5177\uff1aAPT Proxy](https://mp.weixin.qq.com/s/_1AZ5U27JOkEaCUkAuZADQ)\\n- [\u8f7b\u91cf\u9ad8\u53ef\u7528\u7684 K8s \u96c6\u7fa4\u642d\u5efa\u65b9\u6848\uff1aMicroK8s](https://mp.weixin.qq.com/s/e0x7BR2PwkTk9JWdr2hg-w)\\n- [\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f7f\u7528 Docker \u548c Milvus \u5feb\u901f\u6784\u5efa\u672c\u5730\u8f7b\u91cf\u56fe\u7247\u641c\u7d22\u5f15\u64ce](https://mp.weixin.qq.com/s/8MppGs90WWP5sMlHFX2EUQ)\\n- [\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u5165\u95e8\u5411\u91cf\u6570\u636e\u5e93 Milvus \u7684 Docker \u5de5\u5177\u955c\u50cf](https://mp.weixin.qq.com/s/pVYPpYRPjq7BUCahParVvw)\\n- [\u5411\u91cf\u6570\u636e\u5e93\u5165\u5751\uff1a\u4f20\u7edf\u6587\u672c\u68c0\u7d22\u65b9\u5f0f\u7684\u964d\u7ef4\u6253\u51fb\uff0c\u4f7f\u7528 Faiss \u5b9e\u73b0\u5411\u91cf\u8bed\u4e49\u68c0\u7d22](https://mp.weixin.qq.com/s/F0YgDChHceNoOPFstnBv3Q)\\n\\n## Java \u76f8\u5173\\n\\n- \u2b50\ufe0f \u2b50\ufe0f [100+\u7bc7\u539f\u521b\uff011900+\u8f6c\u8f7d\uff01\u5927\u5bb6\u4e00\u8d77\u52a0\u6cb9\uff01](https://mp.weixin.qq.com/s/AGaxg4ymPvSnpt3dZuO9SA)\\n- \u2b50\ufe0f \u2b50\ufe0f [\u539f\u521b\u7cbe\u9009\u835f\u8403\uff082022.05.11\uff09](https://mp.weixin.qq.com/s/1Xe16FaHWfihYjqMVWidQg)\\n- [\u652f\u4ed8\u5b9d\u4e00\u9762\uff1a\u5982\u4f55\u57fa\u4e8eRedis\u5b9e\u73b0\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/j1U4L06y2-8z2fSJypGG7w)\\n- [Jenkins+Docker \u5b9e\u73b0\u4e00\u952e\u81ea\u52a8\u5316\u90e8\u7f72\u9879\u76ee\uff01\u6b65\u9aa4\u9f50\u5168\uff0c\u5c11\u8d70\u5751\u8def\uff01](https://mp.weixin.qq.com/s/va75wKPBtpp2ceL25SkIVA)\\n- [\u4e24\u4e07\u5b57\u8be6\u89e3\uff01Netty\u7ecf\u517832\u8fde\u95ee\uff01](https://mp.weixin.qq.com/s/njeXqkHiIsXneBholN72OQ)\\n- [\u4e24\u4e07\u5b57\u76d8\u70b9\u8bbe\u8ba1\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/409QGKe5H7tCP1qpCiY_KA)\\n- [\u5b9e\u6218\uff0c\u5b9e\u73b0\u5e42\u7b49\u76848\u79cd\u65b9\u6848\uff01](https://mp.weixin.qq.com/s/J0C9TJF7nVVi2cMiDBqepA)\\n- [\u5199\u4f18\u96c5\u4ee3\u7801\u768445\u4e2a\u5c0f\u6280\u5de7](https://mp.weixin.qq.com/s/Jct2rnz_0ahozWNZYfZ4Qg)\\n- [\u809d\u4e86\u4e00\u5468\u603b\u7ed3\u7684SpringBoot\u5e38\u7528\u6ce8\u89e3\u5927\u5168\uff0c\u770b\u5b8c\u5c31\u7089\u706b\u7eaf\u9752\u4e86\uff01](https://mp.weixin.qq.com/s/PzZ31ju32-5epXpQeTZsNA)\\n- [\u77a7\u77a7\u4eba\u5bb6\u5199\u7684API\u63a5\u53e3\u4ee3\u7801\uff0c\u90a3\u53eb\u4e00\u4e2a\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/rSYOAuJeIXaonHvuR5O47Q)\\n- [SpringBoot \u5b9e\u73b0 Excel \u5bfc\u5165\u5bfc\u51fa\uff0c\u6027\u80fd\u7206\u8868\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/P017RfO8TDL5LxGzBoTLSA)\\n- [\u8fd8\u5728\u7528HttpUtil\uff1fSpringBoot 3.0\u5168\u65b0HTTP\u5ba2\u6237\u7aef\u5de5\u5177\u6765\u4e86\uff0c\u7528\u8d77\u6765\u591f\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/SG9sNmMu9acB1xTODkG00Q)\\n- [\u5999\u7528Java 8\u4e2d\u7684 Function\u63a5\u53e3\uff0c\u6d88\u706dif...else\uff08\u975e\u5e38\u65b0\u9896\u7684\u5199\u6cd5\uff09](https://mp.weixin.qq.com/s/ezLN8AzVhBaeMdNMK-TS-g)\\n- [\u522b\u518d\u7528 if \u6821\u9a8c\u53c2\u6570\u4e86\uff0c\u592aLow\uff01\u8fd9\u624d\u662f\u4e13\u4e1a\u7684 SpringBoot \u53c2\u6570\u6821\u9a8c\u65b9\u5f0f\uff01](https://mp.weixin.qq.com/s/20LjD3_nJYvZrTNo4tqjvA)\\n- [\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3](https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg)\\n- [\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3](https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g)\\n- [\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3](https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA)\\n- [\u5fd8\u4e86\u53c8\u770b\uff0c\u770b\u4e86\u53c8\u5fd8\uff1f\u4fdd\u59c6\u7ea7\u6559\u5b66\uff0c\u4e00\u53e3\u6c14\u6559\u4f60\u73a9\u8f6c 3 \u79cd\u9ad8\u9891\u8bbe\u8ba1\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/yyoaDbKsvhdZbAL8T2V-zg)\\n- [11\u79cd\u5e38\u7528\u7684\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/FX2umO7XCCmj8Bke7uKDZw)\\n- [\u8fd9\u4e9b\u5e76\u53d1\u7f16\u7a0b\u77e5\u8bc6\uff0c\u4e00\u5b9a\u8981\u77e5\u9053](https://mp.weixin.qq.com/s/Va4eoL5xizJasnSUbvvccw)\\n- [\u8fd910\u79cd\u795e\u7ea7\u6027\u80fd\u4f18\u5316\u624b\u6bb5\uff0c\u4f60\u7528\u8fc7\u51e0\u4e2a](https://mp.weixin.qq.com/s/EVgd689xdOX732hdOxPqcw)\\n- [\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01](https://mp.weixin.qq.com/s/VStQWv_ehN8RFDxpoAnKmg)\\n- [MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01](https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ)\\n- \u2b50\ufe0f [\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\u4e4b Spring IOC](https://mp.weixin.qq.com/s/29xlEK2N_Wptl4TBMg1ZPQ)\\n- [76 \u5f20\u56fe\uff0c\u5256\u6790 Spring AOP \u6e90\u7801\uff0c\u5c0f\u767d\u5c45\u7136\u4e5f\u80fd\u770b\u61c2\uff0c\u5927\u795e\uff0c\u8bf7\u6536\u4e0b\u6211\u7684\u819d\u76d6\uff01](https://mp.weixin.qq.com/s/T1toQ7NeHQKqof9A0o-99g)\\n- [\u4f7f\u7528 lambda \u5b9e\u73b0\u8d85\u5f3a\u7684\u6392\u5e8f\u529f\u80fd](https://mp.weixin.qq.com/s/n8iw_33Wwr9i0mWEXMG6-A)\\n- [\u4e07\u5b57\u957f\u6587\uff0cSpringSecurity\u5b9e\u73b0\u6743\u9650\u7cfb\u7edf\u8bbe\u8ba1](https://mp.weixin.qq.com/s/e_uJhaGj4HO1iTS_zCoCXw)\\n- [1.2w+\u5b57\uff01Java IO \u57fa\u7840\u77e5\u8bc6\u603b\u7ed3](https://mp.weixin.qq.com/s/J_11wYusexAjwa1cuckyfw)\\n- [\u4e24\u4e07\u5b57\uff01\u591a\u7ebf\u7a0b\u786c\u683850\u95ee\uff01](https://mp.weixin.qq.com/s/7js2uDZNv2Pb55ihKPc1xg)\\n- [\u6e90\u7801\u6df1\u5ea6\u89e3\u6790\uff0cSpring \u5982\u4f55\u89e3\u51b3\u5faa\u73af\u4f9d\u8d56](https://mp.weixin.qq.com/s/djVu6SJjfYj4y_LNW-SKyw)\\n- [\u9ebb\u4e86\uff0c\u4ee3\u7801\u6539\u6210\u591a\u7ebf\u7a0b\uff0c\u7adf\u67099\u5927\u95ee\u9898](https://mp.weixin.qq.com/s/hhjwiMx-ypEbxwHJ9rJoBw)\\n- [\u522b\u518d\u4e71\u6253\u65e5\u5fd7\u4e86\uff0c\u8fd9\u4efd Java \u65e5\u5fd7\u89c4\u8303\uff0c\u5e94\u6709\u5c3d\u6709\uff0c\u5efa\u8bae\u6536\u85cf\uff01](https://mp.weixin.qq.com/s/ioDYZjdSii3WUvL9xqc_Sg)\\n- [\u804a\u804aSpringBoot\u5355\u5143\u6d4b\u8bd5](https://mp.weixin.qq.com/s/zn4TDT4Vl_MobqNkW1m-jw)\\n- [\u603b\u76d1\u53c8\u6765\u4e86\uff0c\u4eba\u72e0\u8bdd\u4e0d\u591a\uff0c\u8fd9\u7bc7 gRPC\uff0c\u5c0f\u5f1f\u4f69\u670d\uff01](https://mp.weixin.qq.com/s/4Sxal7N-uZ8gvphC8XWo8A)\\n\x3c!-- - [Java\u6d41\u884c\u6846\u67b6\u6e90\u7801\u5206\u6790\uff1aSpring\u6e90\u7801\u3001SpringBoot\u6e90\u7801\u3001SpringAOP\u6e90\u7801\u3001SpringSecurity\u6e90\u7801\u3001SpringSecurity OAuth2\u6e90\u7801\u3001JDK\u6e90\u7801\u3001Netty\u6e90\u7801](https://github.com/coderbruis/JavaSourceCodeLearning) --\x3e\\n- [\u817e\u8baf\u4e00\u9762\uff1aThread\u3001Runnable\u3001Callable\u3001Future\u3001FutureTask\uff0c\u8c08\u8c08\u4ed6\u4eec\u7684\u5173\u7cfb](https://mp.weixin.qq.com/s/vqKKoPB5FQkCWXFWBLbkZg)\\n- [\u62dc\u6258\uff01\u9762\u8bd5\u8bf7\u4e0d\u8981\u518d\u95ee\u6211 @Transactional](https://mp.weixin.qq.com/s/rlfRjCb8EOrpt3xnF7isBw)\\n- [7 \u6bb5\u5c0f\u4ee3\u7801\uff0c\u73a9\u8f6cJava\u7a0b\u5e8f\u5e38\u89c1\u7684\u5d29\u6e83\u573a\u666f](https://mp.weixin.qq.com/s/YcyC1Jm4H7uGvSg3rCkDig)\\n- [\u5355\u4f8b\u6a21\u5f0f 4 \u79cd\u7ecf\u5178\u5b9e\u73b0\u65b9\u6cd5](https://mp.weixin.qq.com/s/Ua03qsLcrVURtxhSnuU_6w)\\n- [ElasticSearch\u8fdb\u9636\uff1a\u4e00\u6587\u5168\u89c8\u5404\u79cdES\u67e5\u8be2\u5728Java\u4e2d\u7684\u5b9e\u73b0](https://blog.csdn.net/mu_wind/article/details/118423362)\\n- [\u4f7f\u7528 @Transactional \u65f6\u5e38\u72af\u7684N\u79cd\u9519\u8bef](https://juejin.cn/post/7031047868806873096)\\n- [Spring Boot 2.x\u57fa\u7840\u6559\u7a0b\uff1a\u4f7f\u7528@Scheduled\u5b9e\u73b0\u5b9a\u65f6\u4efb\u52a1](https://juejin.cn/post/6984974277573836830)\\n- [Spring Boot\u4e2d\u4f7f\u7528@Async\u5b9e\u73b0\u5f02\u6b65\u8c03\u7528\uff0c\u52a0\u901f\u4efb\u52a1\u7684\u6267\u884c\uff01](https://juejin.cn/post/7007642025264676871)\\n- [IDEA \u9ad8\u6548\u4f7f\u7528\u6307\u5357](https://github.com/CodingDocs/awesome-idea)\\n- [CodeGuide | \u7a0b\u5e8f\u5458\u7f16\u7801\u6307\u5357](https://github.com/fuzhengwei/CodeGuide)\\n- [\ud83c\udf31 Spring \u624b\u64b8\u4e13\u680f - \u6613\u5b66\u3001\u597d\u5199\u3001\u80fd\u61c2\uff01](https://github.com/fuzhengwei/small-spring)\\n\\n## MySQL \u5b66\u4e60\\n\\n- MySQL \u4e13\u680f\\n - \u2b50\ufe0f \u2b50\ufe0f [\u7530\u87ba\u54e5\u7684MySQL\u4e13\u680f\uff0125\u7bc7\uff0c\u771f\u9999\uff01](https://mp.weixin.qq.com/s/G8fWBvZPy6yxAyggwwx1NA)\\n- \u8868\u7ed3\u6784\u8bbe\u8ba1\\n - \u2b50\ufe0f [\u63a8\u8350\u4e00\u6b3eSQL\u81ea\u52a8\u68c0\u67e5\u795e\u5668\uff0c\u518d\u4e5f\u4e0d\u7528\u62c5\u5fc3SQL\u51fa\u9519\u4e86\uff01](https://mp.weixin.qq.com/s/3yHSh7djpeeYZkajkTGFKg)\\n - \u2b50\ufe0f [21\u4e2aMySQL\u8868\u8bbe\u8ba1\u7684\u7ecf\u9a8c\u51c6\u5219](https://mp.weixin.qq.com/s/sSsZ-w6WzjA_DLZfnsxD2w)\\n - \u2b50\ufe0f [\u804a\u804a\u6570\u636e\u5e93\u5efa\u8868\u768415\u4e2a\u5c0f\u6280\u5de7](https://juejin.cn/post/7136126923851169823)\\n - \u2b50\ufe0f [\u6211\u7528\u8d77\u6765\u987a\u624b\u7684\u6570\u636e\u5e93\u8bbe\u8ba1\u5de5\u5177\uff0c\u8fd9\u6b21\u63a8\u8350\u7ed9\u5927\u5bb6\uff01](https://juejin.cn/post/6844904142733836301)\\n - \u2b50\ufe0f [\u6570\u636e\u5e93\u8868\u7ed3\u6784\u8bbe\u8ba1\u4e00\u70b9\u5fc3\u5f97\u548c\u7ecf\u9a8c](https://juejin.cn/post/7108525565157589005)\\n- \u6162 SQL \u4f18\u5316\\n - \u2b50\ufe0f [SQL\u4f18\u531613\u8fde\u95ee\uff0c\u6536\u85cf\u597d\uff01](https://mp.weixin.qq.com/s/SBKlxcTK_kZf0s5CRtIEBA)\\n - \u2b50\ufe0f [\u7f8e\u56e2\u9762\u8bd5\uff1a\u8fd9\u4e2a SQL \u8bed\u53e5\u52a0\u4e86\u54ea\u4e9b\u9501](https://mp.weixin.qq.com/s/Pi_SLqs3lwA7vWcT6lVv5g)\\n - \u2b50\ufe0f [\u4e13\u5751\u540c\u4e8b\u7684SQL \u5c31\u8fd9\u4e48\u5199\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b](https://mp.weixin.qq.com/s/8X-MuPgS-o53XZywqi_dmA)\\n - \u2b50\ufe0f [\u5b8c\u720690%\u7684\u6027\u80fd\u6bdb\u75c5\uff0c\u6570\u636e\u5e93\u4f18\u5316\u516b\u5927\u901a\u7528\u7edd\u62db\uff01](https://mp.weixin.qq.com/s/0_Arz-KO3UqJij1s4DjLNw)\\n - \u2b50\ufe0f [\u516c\u53f8\u65b0\u6765\u4e2a\u540c\u4e8b\uff0cMyBatis\u6279\u91cf\u63d2\u516510w\u6761\u6570\u636e\u4ec5\u75282\u79d2\uff0c\u62cd\u6848\u53eb\u7edd\uff01](https://mp.weixin.qq.com/s/3H9SD1dnAH0RoN-RoPXxgQ)\\n - \u2b50\ufe0f [\u4e00\u6b21\u663e\u8457\u7684\u5927\u8868\u67e5\u8be2\u4f18\u5316\uff0c\u4ece20s\u4f18\u5316\u5230500ms\uff0c\u67e5\u8be2\u5206\u79bbYYDS\uff01](https://mp.weixin.qq.com/s/OBjRKdGzwFM4PNrbMd7kIA)\\n - \u2b50\ufe0f [MySQL\u8868\u592a\u5927\uff0ccount(*)\u90fd\u80fd 502\uff0c\u600e\u4e48\u4f18\u5316](https://mp.weixin.qq.com/s/UxZRGO58kTiX5wUnuzMJ9Q)\\n - \u2b50\ufe0f [\u8fd915\u4e2aSQL\u4f18\u5316\u53e3\u8bc0\uff0c\u5de5\u4f5c\u9762\u8bd5\u90fd\u591f\u7528\u4e86](https://mp.weixin.qq.com/s/exPgSB0MNUnu0wMkThET1w)\\n - \u2b50\ufe0f [\u4fdd\u59c6\u7ea7\u6559\u7a0b\uff012 \u4e07\u5b57 + 30 \u5f20\u56fe\u641e\u61c2 MySQL \u662f\u600e\u4e48\u52a0\u884c\u7ea7\u9501\u7684](https://mp.weixin.qq.com/s/KegqAAvI4KxDffforTQqKA)\\n - \u2b50\ufe0f [\u4e24\u4e07\u5b57\u8be6\u89e3\uff01InnoDB\u9501\u4e13\u9898\uff01](https://mp.weixin.qq.com/s/DZbAq9fpPxElhfJCkY53GA)\\n - \u2b50\ufe0f [SQL\u4f18\u5316\u601d\u8def+\u7ecf\u5178\u6848\u4f8b\u5206\u6790](https://mp.weixin.qq.com/s/BbrLQWGYlkXiy6t4YANj0Q)\\n - [MySQL \u5355\u8868\u4e0d\u8981\u8d85\u8fc7 2000W \u884c\uff0c\u9760\u8c31\u5417](https://mp.weixin.qq.com/s/N3te_fVBeqhjIpl25N6kpA)\\n - \u2b50\ufe0f [explain | \u7d22\u5f15\u4f18\u5316\u7684\u8fd9\u628a\u7edd\u4e16\u597d\u5251\uff0c\u4f60\u771f\u7684\u4f1a\u7528\u5417](https://mp.weixin.qq.com/s/l3jJHIcqMzCcezbpboqyvQ)\\n - [MySQL \u4f18\u5316\uff1aExplain \u6267\u884c\u8ba1\u5212\u8be6\u89e3](https://mp.weixin.qq.com/s/EVzU7KW9d5_254Kg4LZYQQ)\\n - \u2b50\ufe0f [\u8fd911\u6761\u63a5\u53e3\u6027\u80fd\u4f18\u5316\u6280\u5de7\uff0c\u5229\u597d\u6bcf\u65e5\u7761\u7720](https://mp.weixin.qq.com/s/3jrf1GKBBbVzcvJxqYnx9Q)\\n - \u2b50\ufe0f [\u987a\u4e30\u5feb\u9012\uff1a\u8bf7\u7b7e\u6536MySQL\u7075\u9b42\u5341\u8fde](https://mp.weixin.qq.com/s/Y1Mh-99cgQWuCQ53wAxkUQ)\\n- MySQL \u4e8b\u52a1\\n - \u2b50\ufe0f [\u56fe\u89e3MySQL\u4e8b\u52a1\u5e95\u5c42\u539f\u7406](https://mp.weixin.qq.com/s/pkJb_9mddmdYaJZ8azHSsg)\\n - \u2b50\ufe0f [MySQL\u4e8b\u52a1\u768412\u8fde\u95ee\uff0c\u4f60\u9876\u5f97\u4e86\u561b](https://mp.weixin.qq.com/s/KEbuoasD_DOHRJiSqUgzzA)\\n- MySQL \u7d22\u5f15\\n - \u2b50\ufe0f [MySQL\u7d22\u5f1515\u8fde\u95ee\uff0c\u6297\u4f4f\uff01](https://mp.weixin.qq.com/s/d3iC_Iokrjdn392I0Y53Og)\\n - \u2b50\ufe0f [\u8ddf\u5927\u5bb6\u804a\u804a MySQL \u4e00\u884c\u8bb0\u5f55\u662f\u600e\u4e48\u5b58\u50a8\u7684](https://mp.weixin.qq.com/s/sqW51yqeAXcDs9r84UFP7A)\\n - \u2b50\ufe0f [\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u53ebB+\u6811](https://mp.weixin.qq.com/s/yvgB1a2o-m3_EBLePZM8cw)\\n- MySQL \u65e5\u5fd7\\n - \u2b50\ufe0f [\u804a\u804a MySQL \u65e5\u5fd7\uff0c\u597d\u725b\u7684\u8bbe\u8ba1\uff01](https://mp.weixin.qq.com/s/Tfbd-KiBgsZtkiuVc70BFA)\\n- \u5206\u5e93\u5206\u8868\\n - \u2b50\ufe0f [\u5206\u5e93\u5206\u8868\u7ecf\u517815\u8fde\u95ee](https://mp.weixin.qq.com/s/cZ7mUsCvBxmo1dzsPA3WjQ)\\n - \u2b50\ufe0f [\u9762\u8bd5\u5fc5\u5907\uff1a\u5206\u5e93\u5206\u8868\uff01](https://mp.weixin.qq.com/s/AjVl-0u3plmL9U77h0VVJw)\\n - \u2b50\ufe0f [\u518d\u6709\u4eba\u95ee\u4f60\u4ec0\u4e48\u662f\u5206\u5e93\u5206\u8868\uff0c\u76f4\u63a5\u628a\u8fd9\u7bc7\u6587\u7ae0\u53d1\u7ed9\u4ed6](https://mp.weixin.qq.com/s/wYXs7gsID8a9ahJKsWXJ6w)\\n- \u810f\u8bfb\u3001\u4e0d\u53ef\u91cd\u590d\u8bfb\u3001\u5e7b\u8bfb\\n - \u2b50\ufe0f [\u7f8e\u56e2\u4e09\u9762\uff1a\u4e00\u76f4\u8ffd\u95ee\u6211\uff0c MySQL \u5e7b\u8bfb\u88ab\u5f7b\u5e95\u89e3\u51b3\u4e86\u5417](https://mp.weixin.qq.com/s/VWEKgnOWVnufz5pfvRjUWw)\\n- \u6570\u636e\u4e00\u81f4\u6027\\n - \u2b50\ufe0f [\u6570\u636e\u5e93\u9501\u768412\u8fde\u95ee\uff0c\u6297\u4f4f\uff01](https://mp.weixin.qq.com/s/VEU5p85aTvyBKf2XP5QTSg)\\n - \u2b50\ufe0f [\u804a\u804aselect for update\u5230\u5e95\u52a0\u4e86\u4ec0\u4e48\u9501](https://mp.weixin.qq.com/s/shogIDEgXTtPVPFgsS8crw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/WzAVtmFmEMhY-MiNEgQ0fw)\\n - \u2b50\ufe0f [\u5982\u4f55\u4fdd\u969c MySQL \u548c Redis \u7684\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/lyqvv-nA_PMUc-eBuCsNTA)\\n - \u2b50\ufe0f [\u804a\u804a\u5206\u5e03\u5f0f\u4e00\u81f4\u6027\uff01](https://mp.weixin.qq.com/s/kkSQu7zdr6x_CZRE5uW-lg)\\n - \u2b50\ufe0f [\u804a\u804a\u5206\u5e03\u5f0f\u9501](https://juejin.cn/post/7104507830522085383)\\n- ORM \u76f8\u5173\\n - \u2b50\ufe0f [MyBatis \u8fde\u73af 20 \u95ee\uff0c\u4f60\u80fd\u7b54\u5bf9\u51e0\u4e2a](https://mp.weixin.qq.com/s/R2yqW3kfesK-T5oZR2Vl2w)\\n - \u2b50\ufe0f [MyBatis\u8fd9\u6837\u7528\uff0c\u540c\u4e8b\u76f4\u547c\u54c7\u585e\uff0c\u582a\u79f0\u6700\u4f73\u5b9e\u8df5\uff01](https://mp.weixin.qq.com/s/X11OCZSEh2k5K6uYG768yQ)\\n- [MySQL \u4e09\u4e07\u5b57\u7cbe\u534e\u603b\u7ed3 + \u9762\u8bd5100 \u95ee\uff0c\u548c\u9762\u8bd5\u5b98\u626f\u76ae\u7ef0\u7ef0\u6709\u4f59\uff08\u6536\u85cf\u7cfb\u5217\uff09](https://juejin.cn/post/6850037271233331208)\\n- [\u660e\u660e\u52a0\u4e86\u552f\u4e00\u7d22\u5f15\uff0c\u4e3a\u4ec0\u4e48\u8fd8\u662f\u4ea7\u751f\u91cd\u590d\u6570\u636e](https://mp.weixin.qq.com/s/vRI-bFB4_IEaoCCQcMqZjw)\\n- [\u4e92\u8054\u7f51\u516c\u53f8\u90fd\u600e\u4e48\u5b9e\u73b0\u5206\u9875\u7684\uff0c\u62ff MySQL \u4f7f\u52b2Limit](https://mp.weixin.qq.com/s/O6sgYSpXBPwAA4Qcstj-BA)\\n- [MySQL\u593a\u547d66\u95ee](https://mp.weixin.qq.com/s/cdc1NCSkvAU4Urk2wVFDMw)\\n- [\u4e00\u6b21 MySQL \u8bef\u64cd\u4f5c\u5bfc\u81f4\u7684\u4e8b\u6545\uff0c\u300c\u9ad8\u53ef\u7528\u300d\u90fd\u9876\u4e0d\u4f4f\u4e86\uff01](https://mp.weixin.qq.com/s/L9qseWiHGfu1oAuKIhcUhw)\\n- [\u867e\u76ae\u4e8c\u9762\uff1aMySQL \u4e2d\u6709\u54ea\u4e9b\u9501\uff1f\u8868\u7ea7\u9501\u548c\u884c\u7ea7\u9501\u6709\u4ec0\u4e48\u533a\u522b](https://mp.weixin.qq.com/s/Inocu3vjMG4ivE19HrxR3g)\\n- [\u9762\u9738\u7bc7\uff1aMySQL\u516d\u5341\u516d\u95ee\uff0c\u4e24\u4e07\u5b57+\u4e94\u5341\u56fe\u8be6\u89e3\uff01](https://mp.weixin.qq.com/s/Jhh-_5ynu58EKPMignk5fA)\\n- [\u6162SQL\u5206\u6790\u4e0e\u4f18\u5316](https://juejin.cn/post/7101581835527782414)\\n- [Mysql\u6570\u636e\u5e93\u67e5\u8be2\u597d\u6162\uff0c\u9664\u4e86\u7d22\u5f15\uff0c\u8fd8\u80fd\u56e0\u4e3a\u4ec0\u4e48](https://mp.weixin.qq.com/s/r91hINCgCYJDNHLMeaba8Q)\\n- [MySQL \u4e3b\u4ece\uff0c6 \u5206\u949f\u5e26\u4f60\u638c\u63e1](https://mp.weixin.qq.com/s/8OOSyFB9pzoBMH73ey7YmQ)\\n- [\u5927\u5382\u9762\u8bd5\u9898\uff1a\u65e5\u5e38\u5de5\u4f5c\u5982\u4f55\u505aMySQL\u4f18\u5316](https://mp.weixin.qq.com/s/N08tFkGyXtmBSN0nS6S6UA)\\n- [Mysql\u5b8c\u7ed3\u6c47\u603b\u7bc7\uff0818W\u5b57\u9001\u7ed9\u5927\u5bb6\uff09\uff0c\u5b8c\u7ed3\u6492\u82b1](https://mp.weixin.qq.com/s/i8SHizPrBMQ2GIhQP7ozRw)\\n- [\u9762\u8bd5\u5b98\uff1a\u4ec0\u4e48\u662fMySQL \u4e8b\u52a1\u4e0e MVCC \u539f\u7406\uff1f](https://juejin.cn/post/7081456994413969445)\\n\\n## Golang \u5b66\u4e60\\n\\n- Golang \u5b66\u4e60\u8def\u7ebf\\n - \u2b50\ufe0f [Go\u540e\u7aef\u5f00\u53d1\u6210\u957f\u8def\u7ebf](https://github.com/xiaobaiTech/golangFamily/blob/main/README.md)\\n - \u2b50\ufe0f [\u300aGo\u5b66\u4e60\u8def\u7ebf\u56fe\u300b\u5e26\u4f60\u5c11\u8d70\u5f2f\u8def\uff0cLet\'s Go \uff01](https://juejin.cn/post/7119123646471208968)\\n - \u2b50\ufe0f [\u6700\u5168\u7684Go\u8d44\u6599\u6c47\u603b\u548c\u6700\u8d70\u5fc3\u7684\u5b66Go\u5efa\u8bae](https://juejin.cn/post/7176518080674136121)\\n - \u2b50\ufe0f [\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae](https://juejin.cn/post/7147939014870302756)\\n - [\u6211\u809d\u4e86\u4e09\u4e2a\u6708\uff0c\u4e3a\u4f60\u5199\u51fa\u4e86GO\u6838\u5fc3\u624b\u518c](https://juejin.cn/post/7035966042857799687)\\n - [Go \u5b66\u4e60\u8def\u7ebf\uff082022\uff09](https://juejin.cn/post/7061980386640789540)\\n - [Golang\u5b66\u4e60\u624b\u518c\u4e4b\uff1a\u5e26\u4f6021\u5468\u641e\u5b9aGo\u8bed\u8a00](https://www.bilibili.com/video/BV16E411H7og)\\n - [Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU)\\n- Golang \u8fdb\u9636\\n - \u2b50\ufe0f [Golang \u6cdb\u578b\u4ecb\u7ecd](https://github.com/danielfurman/presentations/blob/master/lets-go-generic/README.md)\\n - \u2b50\ufe0f [GopherCon UK 2018- Florin Patan - Production Ready Go Service in 30 Minutes](https://www.bilibili.com/video/BV1ry4y1y7V2)\\n - \u2b50\ufe0f [\u4f5c\u4e3aGopher\uff0c\u4f60\u77e5\u9053Go\u7684\u6ce8\u91ca\u5373\u6587\u6863\u5e94\u8be5\u600e\u4e48\u5199\u5417](https://mp.weixin.qq.com/s/r4IWY6bzKph2QvxrKZszPA)\\n - \u2b50\ufe0f [31\u4e2a\uff01Golang\u5e38\u7528\u5de5\u5177\u6765\u5566\uff08\u5efa\u8bae\u6536\u85cf\uff09](https://mp.weixin.qq.com/s/Ne0uir1hpMokBUItntkfvw)\\n - \u2b50\ufe0f [Golang\u4f9d\u8d56\u6ce8\u5165\u63d0\u5347\u5f00\u53d1\u6548\u7387\uff01](https://mp.weixin.qq.com/s/Mj-EqwYWZBMr8XNIHxUqDA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u4ece0\u52301\u5b9e\u73b0\u6700\u7b80\u5355\u7684\u6570\u636e\u5e93\uff01](https://mp.weixin.qq.com/s/VFS4TWi3OpeAegScZ4cJRw)\\n - \u2b50\ufe0f [\u5fc5\u64b8\u7cfb\u5217\uff01Go\u53e6\u5916\u51e0\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7\u6c47\u603b](https://mp.weixin.qq.com/s/--ciEa-Oj0NEUxlp1Af_aQ)\\n - \u2b50\ufe0f [\u6765\u4e86\uff01Go\u76842\u4e2a\u9ed1\u9b54\u6cd5\u6280\u5de7](https://mp.weixin.qq.com/s/8HNZQrQ2oqMB2fAYbmH2Ow)\\n - \u2b50\ufe0f [3\u79cd\u65b9\u5f0f\uff01Go Error\u5904\u7406\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/Zb5zGOy_mdalUQ_Qy0HngQ)\\n - \u2b50\ufe0f [Go\u7ec4\u4ef6\uff1acontext\u5b66\u4e60\u7b14\u8bb0\uff01](https://mp.weixin.qq.com/s/OCpVRwtiphFRZgu9zdae5g)\\n - \u2b50\ufe0f [\u4e0d\u5f97\u4e0d\u77e5\u9053\u7684Golang\u4e4bsync.Map\u89e3\u8bfb\uff01](https://mp.weixin.qq.com/s/NkSyv7iDSZsLhMUgAi-r4w)\\n - \u2b50\ufe0f [\u8d85\u5168\u907f\u5751\u6307\u5357: \u76d8\u70b9 Go \u7684\u5e38\u89c1\u5178\u578b\u9519\u8bef](https://mp.weixin.qq.com/s/XHbfPtUzkUTGF06Ao4jQYA)\\n - \u2b50\ufe0f [\u9e45\u5382\u540e\u53f0\u5927\u4f6c\u6559\u4f60Go\u5185\u5b58\u7ba1\u7406\uff01](https://mp.weixin.qq.com/s/56tth8PSquB1eR5-1XaDWA)\\n - \u2b50\ufe0f [\u5168\u9762\u89e3\u8bfb\uff01Golang\u4e2d\u6cdb\u578b\u7684\u4f7f\u7528](https://mp.weixin.qq.com/s/QBZ1dp0XIqMo24vVFYf1fA)\\n - \u2b50\ufe0f [\u8d85\u5e72\u8d27\uff01\u5f7b\u5e95\u641e\u61c2Golang\u5185\u5b58\u7ba1\u7406\u548c\u5783\u573e\u56de\u6536](https://mp.weixin.qq.com/s/niLk_n9Yp-iyl_RIie3Umw)\\n - \u2b50\ufe0f [\u5173\u4e8eGo\u5e76\u53d1\u7f16\u7a0b\uff0c\u4f60\u4e0d\u5f97\u4e0d\u77e5\u7684\u201c\u5de6\u8180\u53f3\u81c2\u201d\u2014\u2014\u5e76\u53d1\u4e0e\u901a\u9053\uff01](https://mp.weixin.qq.com/s/BPcRI0BHBLmuYfzvP10Wvw)\\n - \u2b50\ufe0f [\u5b83\u6765\u4e86\uff0c\u5173\u4e8eGolang\u5e76\u53d1\u7f16\u7a0b\u7684\u8d85\u8be6\u7ec6\u6559\u7a0b\uff01](https://mp.weixin.qq.com/s/aoR_69JMBN5ZM10DKqRCyQ)\\n - \u2b50\ufe0f [\u901a\u4fd7\u6613\u61c2\uff01\u56fe\u89e3Go\u534f\u7a0b\u539f\u7406\u53ca\u5b9e\u6218](https://mp.weixin.qq.com/s/POZGQXsYu5aWXvu29vSM8g)\\n - \u2b50\ufe0f [\u62d2\u7edd\u5343\u7bc7\u4e00\u5f8b\uff0c\u8fd9\u5957Go\u9519\u8bef\u5904\u7406\u7684\u5b8c\u6574\u89e3\u51b3\u65b9\u6848\u503c\u5f97\u4e00\u770b\uff01](https://mp.weixin.qq.com/s/DpCFUAYpvMzd6138Yp_JUA)\\n - \u2b50\ufe0f [go\u8bed\u8a00\u6700\u5168\u4f18\u5316\u6280\u5de7\u603b\u7ed3\uff0c\u503c\u5f97\u6536\u85cf\uff01](https://mp.weixin.qq.com/s/_VGaV8ef65h9goxxfWejtQ)\\n - \u2b50\ufe0f [\u518d\u4e0dGo\u5c31\u6765\u4e0d\u53ca\u4e86\uff01Go\u9ad8\u6027\u80fd\u7f16\u7a0b\u6280\u6cd5\u89e3\u8bfb](https://mp.weixin.qq.com/s/fXKSr8GXaYxG1WCrLIgneg)\\n - \u2b50\ufe0f [\u817e\u8baf 13 \u5e74\uff0c\u6211\u6240\u603b\u7ed3\u7684Code Review\u7ec8\u6781\u5927\u6cd5](https://mp.weixin.qq.com/s/XrJVpErmP8wIjd_byCCmhA)\\n - \u2b50\ufe0f [Go\u4e0eC\u7684\u6865\u6881\uff1aCGO\u5165\u95e8\u5256\u6790\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/AMv5IVBPU2lAY_qUwskk4g)\\n - \u2b50\ufe0f [Golang \u6c47\u7f16\u5165\u95e8\u77e5\u8bc6\u603b\u7ed3](https://mp.weixin.qq.com/s/tN27osC6K0NM-Laj9MbtsA)\\n - \u2b50\ufe0f [Golang\u9ad8\u6027\u80fd\u7f16\u7a0b\u5b9e\u8df5](https://mp.weixin.qq.com/s/VMzhyySny60zABnxlzlVjQ)\\n - \u2b50\ufe0f [\u6572\u9ed1\u677f\uff01\u9e45\u5382\u7a0b\u5e8f\u5458\u9762\u8bd5\u4e5f\u8003\u4e86\u8fd9\u4e9b\u7b97\u6cd5\u77e5\u8bc6](https://mp.weixin.qq.com/s/GwXQwJUdBi1UHdh2Q8FBMw)\\n - \u2b50\ufe0f [Java\u4e0eGo\u5230\u5e95\u5dee\u522b\u5728\u54ea\uff0c\u8c01\u8981\u88ab\u65f6\u4ee3\u629b\u5f03](https://mp.weixin.qq.com/s/JkpzM06IWNb11wUaJWJn8Q)\\n - \u2b50\ufe0f [\u770b\u4e86\u8fd9\u7bc7\u4f60\u4f1a\u53d1\u73b0\uff0c\u4f60\u662f\u61c2Go\u5185\u5b58\u5206\u914d\u7684](https://mp.weixin.qq.com/s/T4tk-sckA1oNcWIvp27MMA)\\n - \u2b50\ufe0f [Go \u5b9e\u6218\u6280\u5de7\uff1a\u907f\u514d\u5185\u5b58\u5206\u914d\u7684\u5c0f\u6280\u5de7](https://mp.weixin.qq.com/s/SLouDICt3HABv_wh-sSqKw)\\n - \u2b50\ufe0f [\u901a\u8fc7\u4e00\u4e2a\u4f8b\u5b50\u8ba9\u4f60\u5f7b\u5e95\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f](https://mp.weixin.qq.com/s/aIuta8Lr0govruPTgglw2w)\\n - \u2b50\ufe0f [Go\u7684\u65b9\u6cd5\u63a5\u6536\u8005\uff1a\u503c\u63a5\u6536\u8005\u4e0e\u6307\u9488\u63a5\u6536\u8005](https://mp.weixin.qq.com/s/_duDs0oHc_z_p--3OoIfVw)\\n - \u2b50\ufe0f [\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303](https://juejin.cn/post/7157594175846744071)\\n - \u2b50\ufe0f [\u7a0b\u5e8f\u5458\u5e94\u8be5\u9075\u5b88\u7684\u7f16\u7a0b\u539f\u5219(\u4e0d\u6b62Gopher\u54e6)](https://mp.weixin.qq.com/s/94thx36Ao2PYQ-8Cbto-wQ)\\n - \u2b50\ufe0f [\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566](https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ)\\n - \u2b50\ufe0f [Go 1.18\u65b0\u7279\u6027\u524d\u77bb\uff1a\u539f\u751f\u652f\u6301Fuzzing\u6d4b\u8bd5](https://mp.weixin.qq.com/s/UqjSA2i3s1VoLFACt_EL2A)\\n - \u2b50\ufe0f [\u5982\u4f55\u5e94\u5bf9\u4e0d\u65ad\u81a8\u80c0\u7684\u63a5\u53e3](https://mp.weixin.qq.com/s/PBTP4vnwEXtrtsHdq0oL0g)\\n - \u2b50\ufe0f [\u6bcf\u4e2a gopher \u90fd\u9700\u8981\u4e86\u89e3\u7684 Go AST](https://mp.weixin.qq.com/s/pCcNtUykXAwb-BN_prPGpA)\\n - \u2b50\ufe0f [\u4e00\u6587\u641e\u61c2Go\u6807\u51c6\u5e93context\u5305](https://mp.weixin.qq.com/s/xzNqpRbIvoJygSWeQJFjTw)\\n - \u2b50\ufe0f [\u4f7f\u7528\u53cd\u5c04\u64cd\u4f5cchannel](https://mp.weixin.qq.com/s/E4lT4SuWKIlCZd60i7vigQ)\\n - \u2b50\ufe0f [Go 1.20\u65b0\u7279\u6027\u524d\u77bb](https://mp.weixin.qq.com/s/z75HDSlX0PLCnvL5kAcSDw)\\n - \u2b50\ufe0f [Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c](https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg)\\n - \u2b50\ufe0f [2022\u5e74Go\u8bed\u8a00\u76d8\u70b9\uff1a\u6cdb\u578b\u843d\u5730\uff0c\u65e0\u8da3\u5f88\u597d\uff0c\u7a33\u5b9a\u4e3a\u738b](https://mp.weixin.qq.com/s/MRBEJHZBMS9s0w7UhseQWA)\\n - \u2b50\ufe0f [Go1.20 \u65b0\u7279\u6027\uff1acontext\u652f\u6301\u81ea\u5b9a\u4e49\u53d6\u6d88\u539f\u56e0](https://mp.weixin.qq.com/s/HbFVODpDEzEZ047kv-LYbg)\\n - \u2b50\ufe0f [\u804a\u804aGo\u4e0eTLS 1.3](https://mp.weixin.qq.com/s/NtBzM8l54HRVSpapKR_0sg)\\n - \u2b50\ufe0f [\u5c06Roaring Bitmap\u5e8f\u5217\u5316\u4e3aJSON](https://mp.weixin.qq.com/s/CFwiFw00ah0rfdZyv_ppxw)\\n - \u2b50\ufe0f [\u4e07\u5b57\u957f\u6587\u544a\u8bc9\u4f60Go 1.20\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316](https://mp.weixin.qq.com/s/Y-JxePxv9XlaX_UASlWSvQ)\\n - \u2b50\ufe0f [\u4e00\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u5224\u65adGo\u63a5\u53e3\u53d8\u91cf\u662f\u5426\u76f8\u7b49](https://mp.weixin.qq.com/s/6_ygmyd64LP7rlkrOh-kRQ)\\n - \u2b50\ufe0f [\u5c0f\u5382\u5185\u90e8\u79c1\u6709Go module\u62c9\u53d6\u65b9\u68483](https://mp.weixin.qq.com/s/WDw-Y8Rp4VxAa2iPKRnKKg)\\n - \u2b50\ufe0f [Go\u662f\u4e00\u95e8\u9762\u5411\u5bf9\u8c61\u7f16\u7a0b\u8bed\u8a00\u5417](https://mp.weixin.qq.com/s/r5gIVtyBWtD7UQncK_JPNQ)\\n - \u2b50\ufe0f [\u4e00\u6587\u641e\u61c2Go subtest](https://mp.weixin.qq.com/s/5zoNwCWnNNunrDtu6cokqg)\\n - \u2b50\ufe0f [\u804a\u804agodoc\u3001go doc\u4e0epkgsite](https://mp.weixin.qq.com/s/ypK-2wGHGj9_n4o8y-clXg)\\n - \u2b50\ufe0f [\u804a\u804aGo\u8bed\u8a00\u7684\u5168\u5c40\u53d8\u91cf](https://mp.weixin.qq.com/s/MI9x4YOAhbtS-xQtOS-K_A)\\n - \u2b50\ufe0f [Go\u5f00\u53d1\u547d\u4ee4\u884c\u7a0b\u5e8f\u6307\u5357](https://mp.weixin.qq.com/s/8yLt0Sh18VF5ApTcuxV-Sg)\\n - \u2b50\ufe0f [\u4f7f\u7528go test\u6846\u67b6\u9a71\u52a8\u7684\u81ea\u52a8\u5316\u6d4b\u8bd5](https://mp.weixin.qq.com/s/RKshV1hu61wabq4am906PA)\\n - \u2b50\ufe0f [\u4e00\u6587\u544a\u8bc9\u4f60\u54ea\u4e9bmap element\u7c7b\u578b\u652f\u6301\u5c31\u5730\u66f4\u65b0](https://mp.weixin.qq.com/s/0TnAPFib82KC-BIL-uhMWw)\\n - \u2b50\ufe0f [\u7406\u89e3unsafe-assume-no-moving-gc\u5305](https://mp.weixin.qq.com/s/EHSR-GFPJy5RzVDgcvoTog)\\n - \u2b50\ufe0f [Go 1.21\u65b0\u7279\u6027\u524d\u77bb](https://mp.weixin.qq.com/s/PwSJQM7WmJeLnDDbCr78hg)\\n - \u2b50\ufe0f [Go\uff1a\u503c\u4e0e\u6307\u9488](https://mp.weixin.qq.com/s/FcuXy0Vqp6aczKpNpQeFrA)\\n - \u2b50\ufe0f [Go\u9879\u76ee\u7ec4\u7ec7\uff1a\u5728\u5355\u4e00repo\u4e2d\u7ba1\u7406\u591a\u4e2aGo module\u6307\u5357](https://mp.weixin.qq.com/s/IEsgLu5PFwcKppUWABA6-Q)\\n - \u2b50\ufe0f [\u4e00\u6587\u641e\u61c2Go\u9519\u8bef\u94fe](https://mp.weixin.qq.com/s/D_CVrPzjP3O81EpFqLoynQ)\\n - \u2b50\ufe0f [Go\u4e0e\u795e\u7ecf\u7f51\u7edc\uff1a\u5f20\u91cf\u8fd0\u7b97](https://mp.weixin.qq.com/s/18SbYmKnUbNR59gFlKEULQ)\\n - \u2b50\ufe0f [\u804a\u804aGo\u8bed\u8a00\u7684\u63a7\u5236\u8bed\u53e5](https://mp.weixin.qq.com/s/2P9_nyrdZ3JqlKRIR8--7g)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u53cd\u5c04\u7f16\u7a0b\u6307\u5357](https://mp.weixin.qq.com/s/J3hIbUaAp55l8QDuJYUQOg)\\n - \u2b50\ufe0f [The State Of Go 2023](https://mp.weixin.qq.com/s/-EAH8jjj4uy1LCr_9C1ghg)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5305\u8bbe\u8ba1\u6307\u5357](https://mp.weixin.qq.com/s/_xA6bhKTm543i3QV8EZMSg)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u7c7b\u578b](https://mp.weixin.qq.com/s/dyQ3WBMPF2DyaI8Dlgy8Gw)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u5185\u5b58\u7ba1\u7406](https://mp.weixin.qq.com/s/JWg8yW_lDiZQCk6bKZ5TeA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u9ad8\u7ea7\u6570\u636e\u7ed3\u6784](https://mp.weixin.qq.com/s/WgeTzhP4T0AAjFssHz36UA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6570\u636e\u64cd\u4f5c](https://mp.weixin.qq.com/s/Lxxfeqn70rfmnrGvgrxevA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u6269\u5c55compute\u5305](https://mp.weixin.qq.com/s/xBpA36wpmbO85LIHlaTXBg)\\n - \u2b50\ufe0f [\u4f7f\u7528testify\u5305\u8f85\u52a9Go\u6d4b\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/LppX2mvbkgsLKkqqudehQA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5f00\u53d1\u8005\u7684Apache Arrow\u4f7f\u7528\u6307\u5357\uff1a\u8bfb\u5199Parquet\u6587\u4ef6](https://mp.weixin.qq.com/s/PcNpQJcKuWpZgYrKmVvRLQ)\\n - \u2b50\ufe0f [Gopher Daily\u6539\u7248\u4e86](https://mp.weixin.qq.com/s/4UI6gTx7ZWRPhGbm4YGGCQ)\\n - \u2b50\ufe0f [Go\u9879\u76ee\u521d\u59cb\u5316\u4e0d\u518d\u56f0\u6270\u4f60\uff1agonew\u5168\u65b9\u4f4d\u89e3\u6790](https://mp.weixin.qq.com/s/ZaDNxyewtrSuiLRF62ipYg)\\n - \u2b50\ufe0f [Go 1.21\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316](https://mp.weixin.qq.com/s/3bfD9LPBB5zA9VxAv920Cw)\\n - \u2b50\ufe0f [\u7f16\u8bd1Go\u5e94\u7528\u7684\u9ed1\u76d2\u6311\u6218\uff1a\u65e0\u6e90\u7801\u53ea\u6709.a\u6587\u4ef6\uff0c\u4f60\u80fd\u641e\u5b9a\u5417](https://mp.weixin.qq.com/s/snVLySXv4E5xMlbD153FcQ)\\n - \u2b50\ufe0f [slog\u6b63\u5f0f\u7248\u6765\u4e86\uff1aGo\u65e5\u5fd7\u8bb0\u5f55\u65b0\u9009\u62e9\uff01](https://mp.weixin.qq.com/s/4HN0-m8AlzSmDCuF9hYU4Q)\\n - \u2b50\ufe0f [slog\u5b9e\u6218\uff1a\u6587\u4ef6\u65e5\u5fd7\u3001\u8f6e\u8f6c\u4e0ekafka\u96c6\u6210](https://mp.weixin.qq.com/s/7jS6E6d578QQIxvWKSux1Q)\\n - \u2b50\ufe0f [\u804a\u804aGo\u8bed\u8a00\u7684\u5411\u524d\u517c\u5bb9\u6027\u548ctoolchain\u89c4\u5219](https://mp.weixin.qq.com/s/NzUXgDd7qPMK4LxIopcFLA)\\n - \u2b50\ufe0f [\u4f7f\u7528Go\u548cWebRTC data channel\u5b9e\u73b0\u7aef\u5230\u7aef\u5b9e\u65f6\u901a\u4fe1](https://mp.weixin.qq.com/s/vY76-34hm-ujgaGTS_lDaQ)\\n - \u2b50\ufe0f [\u4e86\u89e3go\u5728\u534f\u7a0b\u8c03\u5ea6\u4e0a\u7684\u6539\u8fdb](https://mp.weixin.qq.com/s/2ibzE46UVnO_YNtugikpPQ)\\n - \u2b50\ufe0f [\u4e00\u7ad9\u5f0fGolang\u5185\u5b58\u6d17\u9ad3\u7ecf\\\\[Go\u4e09\u5173\u5178\u85cf\u7248\\\\]](https://mp.weixin.qq.com/s/J3Sfo9u63aTG6IndFP-BnQ)\\n - \u2b50\ufe0f [\u6df1\u5165\u7406\u89e3Golang\u534f\u7a0b\u8c03\u5ea6GPM\\\\[Go\u4e09\u5173\u5178\u85cf\u7248\\\\]](https://mp.weixin.qq.com/s/9MfIdUdBZmfqbUYT_xrB8A)\\n - \u2b50\ufe0f [Golang\u4e09\u8272\u6807\u8bb0\u6df7\u5408\u5199\u5c4f\u969cGC\u6a21\u5f0f\u5168\u5206\u6790\\\\[Go\u4e09\u5173\u5178\u85cf\u7248\\\\]](https://mp.weixin.qq.com/s/up1MHqYW_v_C4P6AY-sW3w)\\n - \u2b50\ufe0f [\u4e3a\u4ec0\u4e48\u6cdb\u578b\u4f7f\u4f60\u7684\u7a0b\u5e8f\u53d8\u6162](https://mp.weixin.qq.com/s/veu5W0BFmLIZ-yvs39NdUw)\\n - \u2b50\ufe0f [Go error \u5904\u7406\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/XojOIIZfKm_wXul9eSU1tQ)\\n - \u2b50\ufe0f [\u5f00\u901a\u4e2a\u4eba\u535a\u5ba2\u5566\uff01\u9644\u5e26\u5168\u90e8 Hexo + Nginx + Git \u6559\u7a0b](https://mp.weixin.qq.com/s/mrAwE-go0vNSwrJ4g4L9Cg)\\n - \u2b50\ufe0f [\u975e\u5e7f\u544a| DDD \u5230\u5e95\u662f\u94f6\u5f39\u8fd8\u662f\u5783\u573e](https://mp.weixin.qq.com/s/gMjQmNvEi1o_iOFt2z7flg)\\n - \u2b50\ufe0f [\u7ed9\u9762\u8bd5\u5b98\u4e00\u70b9\u5c0f\u5c0f\u7684 gpt \u9707\u64bc](https://mp.weixin.qq.com/s/yEbqNo9UfPTCxL5-RDvlPw)\\n - \u2b50\ufe0f [Go \u8bed\u8a00 GC \u5206\u6790](https://mp.weixin.qq.com/s/AaHk-yg8D4atbO-zVAvhKQ)\\n - \u2b50\ufe0f [\u52a8\u6001\u8c03\u6574 GOGC \u4f18\u5316 Go \u7684 GC \u6807\u8bb0 CPU \u5360\u7528](https://mp.weixin.qq.com/s/XR1KAeCW930i-Qxv6N2kaA)\\n - \u2b50\ufe0f [\u804a\u804a rust trait](https://mp.weixin.qq.com/s/T7IBCimzmWI07dHD8NA-Qw)\\n - \u2b50\ufe0f [Gopher \u9700\u8981\u77e5\u9053\u7684\u51e0\u4e2a\u7ed3\u6784\u4f53\u9a9a\u64cd\u4f5c](https://mp.weixin.qq.com/s/A4m1xlFwh9pD0qy3p7ItSA)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u7aef\u5f00\u53d1\uff0c\u8bf7\u7262\u8bb0\u8fd9\u51e0\u6761](https://mp.weixin.qq.com/s/sYQ0vqKiIWaUCha740Dxtw)\\n - \u2b50\ufe0f [\u503c\u5f97\u6536\u85cf\u8c03\u5ea6\u5668\u7cfb\u5217\uff1a\u5077\u5929\u6362\u65e5 \u2014 g0 \u6808\u548c\u7528\u6237\u6808\u5982\u4f55\u5b8c\u6210\u5207\u6362\uff1f\uff08\u56db\uff09](https://mp.weixin.qq.com/s/8xTtSoLvAcE1u_jWw9I-Eg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff081\uff09\u2014\u2014\u8c03\u5ea6\u7684\u672c\u8d28](https://mp.weixin.qq.com/s/5E5V56wazp5gs9lrLvtopA)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff082\uff09\u2014\u2014 \u8ff7\u60d1\u7684 goroutine \u6267\u884c\u987a\u5e8f](https://mp.weixin.qq.com/s/WWfm7Ui7g_gGlb8XkIZigg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff083\uff09\u2014\u2014 \u5982\u4f55\u7528\u6c47\u7f16\u6253\u540c\u4e8b\u7684\u8138](https://mp.weixin.qq.com/s/2Y3qPkysRLaWDcIyLOerZg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0810\uff09\u2014\u2014 \u5982\u4f55\u7ed9 Go \u63d0\u6027\u80fd\u4f18\u5316\u7684 pr](https://mp.weixin.qq.com/s/8R9ZLa0Xlscw6qhl-5g2Cg)\\n - \u2b50\ufe0f [\u66f9\u5927\u5e26\u6211\u5b66 Go\uff0811\uff09\u2014\u2014 \u4ece map \u7684 extra \u5b57\u6bb5\u8c08\u8d77](https://mp.weixin.qq.com/s/SGv5vuh9aU2mqViC4Kj0YQ)\\n - \u2b50\ufe0f [\u300e\u66f9\u5927\u5e26\u6211\u5b66 Go \u300f\u7cfb\u5217\u6587\u7ae0\u6c47\u603b](https://mp.weixin.qq.com/s/RmEtL869Sd-FjB_73tFSaw)\\n - \u2b50\ufe0f [Go map \u7adf\u7136\u4e5f\u4f1a\u53d1\u751f\u5185\u5b58\u6cc4\u6f0f](https://mp.weixin.qq.com/s/IEunJaXMfrOfPmounloYig)\\n - \u2b50\ufe0f [\u5185\u8054\u51fd\u6570\u548c\u7f16\u8bd1\u5668\u5bf9Go\u4ee3\u7801\u7684\u4f18\u5316](https://mp.weixin.qq.com/s/ujWkFUqJiY3DCWeKZeS8uw)\\n - \u2b50\ufe0f [\u6df1\u5ea6\u9605\u8bfb\u4e4b\u300a100 Go Mistakes and How to Avoid Them\u300b](https://mp.weixin.qq.com/s/VnF7YrXTaK5MASacXgzRhw)\\n - \u2b50\ufe0f [kafka producer \u5728 aws \u53c8\u6302\u4e86](https://mp.weixin.qq.com/s/U5Okkf9FzLxxSYcsUI2DZg)\\n - \u2b50\ufe0f [\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e00)](https://mp.weixin.qq.com/s/Bl3UrbgiMMsP3gxm6vnDtA)\\n - \u2b50\ufe0f [\u300a\u8c37\u6b4c\u7684\u8f6f\u4ef6\u5de5\u7a0b\u300b\u7b14\u8bb0(\u4e8c)](https://mp.weixin.qq.com/s/j59HejHj5hzKovfsGdrIdg)\\n - \u2b50\ufe0f [Gopher \u5e94\u8be5\u8bb0\u4f4f\u8fd9 10 \u4e2a\u547d\u4ee4](https://mp.weixin.qq.com/s/UIeIBtC9MZJh3w-EphWHiA)\\n - \u2b50\ufe0f [\u6709\u8da3\u7684 Go HttpClient \u8d85\u65f6\u673a\u5236](https://mp.weixin.qq.com/s/HPzoclfCB3UxLScXm4J83w)\\n - \u2b50\ufe0f [\u6211\u5982\u4f55\u7528\u4e24\u884c\u4ee3\u7801\u8282\u7701\u4e8630%\u7684CPU](https://mp.weixin.qq.com/s/2V3VSsAJH5haWqdvVJ9e8g)\\n - \u2b50\ufe0f [Go 1.19 \u4e2datomic\u5305\u7684\u65b0\u53d8\u5316](https://mp.weixin.qq.com/s/YzkPHkBCdqv-Z3APSPaDrQ)\\n - \u2b50\ufe0f [\u7b49\u7b49\uff0c \u600e\u4e48\u4f7f\u7528 SetMemoryLimit](https://mp.weixin.qq.com/s/EIuM073G7VV1rIsnTXWyEw)\\n - \u2b50\ufe0f [\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/sSwXgrHvQcjSuiy9bA8d_g)\\n - \u2b50\ufe0f [\u554a\u54c8\uff0c\u4e00\u9053\u6709\u8da3\u7684Go\u5e76\u53d1\u9898](https://mp.weixin.qq.com/s/S4FDRve0YPtRUixY4kPqAQ)\\n - \u2b50\ufe0f [\u8fd8\u548b\u4f18\u5316\uff1f\u6211\u662f\u8bf4Go\u7a0b\u5e8f](https://mp.weixin.qq.com/s/VtDR2uJ8SQ2jiIS2o2uyfA)\\n - \u2b50\ufe0f [\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e00\u7bc7\uff1a\u7efc\u8ff0](https://mp.weixin.qq.com/s/chPDWyBibBlvcEKKENFYGg)\\n - \u2b50\ufe0f [\u96f6\u62f7\u8d1d\u6280\u672f\u7b2c\u4e8c\u7bc7\uff1aGo\u8bed\u8a00\u4e2d\u7684\u5e94\u7528](https://mp.weixin.qq.com/s/hXfZImBUYTBe2JvhBD-OmA)\\n - \u2b50\ufe0f [\u4e00\u4e9b\u5173\u4e8e\u65f6\u95f4\u548c\u5b9a\u65f6\u4efb\u52a1\u7684\u5e93](https://mp.weixin.qq.com/s/EAk_LdlfYGwaiDDj9CgqHA)\\n - \u2b50\ufe0f [\u6ca1\u7528\u5fae\u670d\u52a1\uff0cShopify\u7684\u5355\u4f53\u7a0b\u5e8f\u5c45\u7136\u652f\u6491\u4e86127\u4e07/\u79d2\u7684\u8bf7\u6c42](https://mp.weixin.qq.com/s/kSZieI3zE9RgvfAqEQEhbw)\\n - \u2b50\ufe0f [\u673a\u667a\uff01\u751f\u62a0\u5185\u5efamap\u7684\u54c8\u5e0c\u51fd\u6570](https://mp.weixin.qq.com/s/8omJxT10c5UX6Neua9dLjA)\\n - \u2b50\ufe0f [\u50cf\u95ea\u7535\u4e00\u6837\u5feb\u901f\u626b\u63cf\u5168\u7f51\u7684IP\u5730\u5740](https://mp.weixin.qq.com/s/KTmMWyULYMS0LFsg69zwZg)\\n - \u2b50\ufe0f [\u6bcf\u79d2\u767e\u4e07\u7ea7\u522b\u7684\u5305\u4f20\u8f93\uff0c\u6211\u662f\u8bf4CPU\u4f7f\u7528\u7387\u51e0\u4e4e\u4e3a\u96f6\u90a3\u79cd](https://mp.weixin.qq.com/s/KzMmzd2ZfAJwtHt4s-V0zQ)\\n - \u2b50\ufe0f [\u4f7f\u7528\u5e95\u5c42\u7684syscall.Socket\u5b9e\u73b0\u7f51\u7edc\u7f16\u7a0b](https://mp.weixin.qq.com/s/sVLOFBdL6a_1pOBFP8pSfw)\\n - \u2b50\ufe0f [\u4f7f\u7528Go\u8bed\u8a00\u5b9e\u73b0ping\u5de5\u5177](https://mp.weixin.qq.com/s/uwdL6QjLIG6SbMKeb2HOAw)\\n - \u2b50\ufe0f [\u51e0\u79cd\u4f7f\u7528Go\u53d1\u9001IP\u5305\u7684\u65b9\u6cd5](https://mp.weixin.qq.com/s/1Nv5_b2jM9uiG0tEu1Pr1A)\\n - \u2b50\ufe0f [\u600e\u4e48\u963b\u6b62\u4e00\u4e2aGo\u7a0b\u5e8f\u9000\u51fa](https://mp.weixin.qq.com/s/C2AmKZjg9CyiIDxyU0-b1Q)\\n - \u2b50\ufe0f [Go 1.21\u4e2d sync.Once\u7684\u65b0\u6269\u5c55](https://mp.weixin.qq.com/s/SFXe1bdBu0bLuHoGEFTz8g)\\n - \u2b50\ufe0f [\u6539\u9020! \u8ba9 sync.Map \u652f\u6301\u6cdb\u578b](https://mp.weixin.qq.com/s/mKraN_3xUfy6Bm-SswHEbw)\\n - \u2b50\ufe0f [\u4e00\u4e2a\u6cdb\u578b\u7684\u6709\u5e8fGo Map\u5b9e\u73b0](https://mp.weixin.qq.com/s/26PlfCFLc9Giuv_7nmgxjg)\\n - \u2b50\ufe0f [MPTCP: \u4e00\u4e2a\u5728 Go 1.21\u4e2d\u7684\u88ab\u5ffd\u7565\u7684\u65b0\u7279\u6027](https://mp.weixin.qq.com/s/aC7omLYJ6Anm9f-8b4qYAg)\\n - \u2b50\ufe0f [Go\u53ef\u4ee5\u4f7f\u7528\u8bbe\u8ba1\u6a21\u5f0f\uff0c\u4f46\u7edd\u4e0d\u662f\u300a\u8bbe\u8ba1\u6a21\u5f0f\u300b\u4e2d\u7684\u90a3\u6837](https://mp.weixin.qq.com/s/Sv-SXDYxea_K_TtiI_CjTw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5de5\u5382\u6a21\u5f0f](https://mp.weixin.qq.com/s/325iHPhAQicbSN6-pb05rw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5efa\u9020\u8005\u6a21\u5f0f](https://mp.weixin.qq.com/s/jXaCLkagT-cKbVHConcadg)\\n - \u2b50\ufe0f [\u5355\u4f8b\u6a21\u5f0f\u548c\u60f0\u6027\u521d\u59cb\u5316\u6a21\u5f0f](https://mp.weixin.qq.com/s/NQOmlQfFpM-asN9I9CeVkw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u539f\u578b\u6a21\u5f0f](https://mp.weixin.qq.com/s/R1bPyZBMWizcfuwQv0-t8Q)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u5bf9\u8c61\u6c60\u6a21\u5f0f](https://mp.weixin.qq.com/s/p5lv_yTUbxsNYDmZiIpGTw)\\n - \u2b50\ufe0f [\u539f\u578b\u6a21\u5f0f\u8865\u9057 - Go\u8bed\u8a00\u4e2d\u7684\u6df1\u5ea6\u62f7\u8d1d](https://mp.weixin.qq.com/s/zVVl_R0WbP6AUcav5ys6tQ)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u9002\u914d\u5668\u6a21\u5f0f](https://mp.weixin.qq.com/s/KYlY-WFNpYirvcRiyaeVXw)\\n - \u2b50\ufe0f [\u771f\u5b9e\u4e16\u754c\u7684Go\u8bbe\u8ba1\u6a21\u5f0f - \u8d44\u6e90\u83b7\u53d6\u5373\u521d\u59cb\u5316](https://mp.weixin.qq.com/s/MiACdPNOhnXRoysRX2VBVA)\\n - \u2b50\ufe0f [Go 1.21 \u4e2d\u7684\u6cdb\u578b\u63a8\u65ad](https://mp.weixin.qq.com/s/hgFvoopT7DZoGUqHiurTeQ)\\n - \u2b50\ufe0f [mping: \u4f7f\u7528\u65b0\u7684icmp\u5e93\u5b9e\u73b0\u63a2\u6d4b\u548c\u538b\u6d4b\u5de5\u5177](https://mp.weixin.qq.com/s/1cIcrObMP5xG_UsMUatETw)\\n - \u2b50\ufe0f [PGO: \u4e3a\u4f60\u7684Go\u7a0b\u5e8f\u63d0\u65485%](https://mp.weixin.qq.com/s/SSkt6YYGcqgH9kbIQH-tNg)\\n - \u2b50\ufe0f [\u6df1\u5165\u7406\u89e3 PromQL](https://mp.weixin.qq.com/s/M0WFAQtoCd1aEZHjxTyjMw)\\n - \u2b50\ufe0f [\u4ec0\u4e48\u662f Go runtime.KeepAlive](https://mp.weixin.qq.com/s/5XMmVqdcji8jpRnC2p0F3w)\\n - \u2b50\ufe0f [\u6027\u80fd\u4f18\u5316 | Go Ballast \u8ba9\u5185\u5b58\u63a7\u5236\u66f4\u52a0\u4e1d\u6ed1](https://mp.weixin.qq.com/s/gc34RYqmzeMndEJ1-7sOwg)\\n - \u2b50\ufe0f [gin \u6e90\u7801\u9605\u8bfb(5) - \u7075\u6d3b\u7684\u8fd4\u56de\u503c\u5904\u7406](https://mp.weixin.qq.com/s/lE83EZ7eztjEWd_NU796YQ)\\n - \u2b50\ufe0f [gin \u6e90\u7801\u9605\u8bfb(4) - \u53cb\u597d\u7684\u8bf7\u6c42\u53c2\u6570\u5904\u7406](https://mp.weixin.qq.com/s/2OI9vh_LGPxtGkhF-AnWDA)\\n - \u2b50\ufe0f [gin \u6e90\u7801\u9605\u8bfb(3) - gin \u8def\u7531\u7684\u5b9e\u73b0\u5256\u6790](https://mp.weixin.qq.com/s/PldVh8Wk6oxCFIcWVx3hrQ)\\n - \u2b50\ufe0f [\u89c1\u5fae\u77e5\u8457| \u5e26\u4f60\u900f\u8fc7\u5185\u5b58\u770b Slice \u548c Array\u7684\u5f02\u540c](https://mp.weixin.qq.com/s/d9kP77eKRm2MSW_9ySlVGA)\\n - \u2b50\ufe0f [Goland \u8fd9\u4e9b\u5b9e\u64cd\u6280\u5de7\uff0c\u4f60\u53ef\u80fd\u8fd8\u4e0d\u4f1a\uff01](https://mp.weixin.qq.com/s/mrCQyw_dR5VYzf8ejyvHfA)\\n - \u2b50\ufe0f [\u8fd9\u4e9b Goland \u6280\u5de7\uff0c\u5b66\u4f1a\u5f00\u53d1\u6548\u7387\u7ffb\u500d](https://mp.weixin.qq.com/s/gmKi3bE99K6bXVGcMFz53w)\\n - \u2b50\ufe0f [Go interface \u539f\u7406\u5256\u6790--\u7c7b\u578b\u8f6c\u6362](https://mp.weixin.qq.com/s/lMvU80jhkabMvqXeTFiDnw)\\n - \u2b50\ufe0f [\u5feb\u6536\u85cf\uff01\u6700\u5168Go\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\uff08\u4e0a\uff09](https://mp.weixin.qq.com/s/MQWZOkaAc4Bw-PmYHyd9SA)\\n - \u2b50\ufe0f [\u5feb\u6536\u85cf\uff01\u6700\u5168GO\u8bed\u8a00\u5b9e\u73b0\u8bbe\u8ba1\u6a21\u5f0f\u3010\u4e0b\u3011](https://mp.weixin.qq.com/s/NrUWfpyfzX4sag22qF-Y-Q)\\n - \u2b50\ufe0f [\u6df1\u5165\u7406\u89e3 golang \u7684\u4e92\u65a5\u9501](https://mp.weixin.qq.com/s/i1N9bmVSW1lGfOezvhcD7g)\\n - \u2b50\ufe0f [Go 1.20\u65b0\u53d8\u5316\uff01\u7b2c\u4e00\u90e8\u5206\uff1a\u8bed\u8a00\u7279\u6027](https://mp.weixin.qq.com/s/rETmci7xvzf5X9_liS0Hmg)\\n - \u2b50\ufe0f [\\\\[\u8bd1\\\\]Uber \u7684 Go\u8bed\u8a00\u5f00\u53d1\u89c4\u8303](https://mp.weixin.qq.com/s/UQwOJVqm5gnQPMgSE3MW9w)\\n - \u2b50\ufe0f [\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01](https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w)\\n - \u2b50\ufe0f [\u4ece\u9e45\u5382\u5b9e\u4f8b\u51fa\u53d1\uff01\u5206\u6790Go Channel\u5e95\u5c42\u539f\u7406](https://mp.weixin.qq.com/s/uWhmvBk_MN23RjmfjkxqeQ)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u81ea\u52a8\u6536\u96c6\u7ebf\u4e0a\u95ee\u9898\u73b0\u573a](https://mp.weixin.qq.com/s/vB9ElJCfgZeQHtB596XHpA)\\n - \u2b50\ufe0f [\u7528\u89c4\u5219\u5f15\u64ce\u8ba9\u4f60\u4e00\u5929\u4e0a\u7ebf\u5341\u4e2a\u9700\u6c42](https://mp.weixin.qq.com/s/gLbAZShFnkPcI937pk-wpg)\\n - \u2b50\ufe0f [\u8ba1\u7b97\u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u59cb\u672b](https://mp.weixin.qq.com/s/gGs0tOJqBvJKCzPuUWsPiA)\\n - \u2b50\ufe0f [IO \u5bc6\u96c6\u578b\u670d\u52a1 \u6027\u80fd\u4f18\u5316\u5b9e\u6218\u8bb0\u5f55](https://mp.weixin.qq.com/s/nSlfsoIo0cMYUdgIEuHWEg)\\n - \u2b50\ufe0f [Golang GC \u4ece\u7406\u8bba\u5230\u9488\u5bf9\u670d\u52a1\u7684\u5b9a\u5236\u5316\u5e94\u7528](https://mp.weixin.qq.com/s/YM9UP-esSDNZywMneKcVYw)\\n - \u2b50\ufe0f [\u4e00\u6587\u5f7b\u5e95\u7406\u89e3Go\u8bed\u8a00\u6808\u5185\u5b58/\u5806\u5185\u5b58](https://mp.weixin.qq.com/s/QQjOyYkDfuxIxHl6k6qkRA)\\n - \u2b50\ufe0f [\u5b57\u8282\u5927\u89c4\u6a21\u5fae\u670d\u52a1 Go \u8bed\u8a00\u53d1\u5c55\u4e4b\u8def](https://mp.weixin.qq.com/s/Oz0Zn8Y43UfHIOPL6rZ5Ig)\\n - \u2b50\ufe0f [\u901a\u8fc7\u5206\u6790gin\u3001beego\u6e90\u7801\uff0c\u8bfb\u61c2web\u6846\u67b6\u5bf9http\u8bf7\u6c42\u5904\u7406\u6d41\u7a0b\u7684\u672c\u8d28](https://mp.weixin.qq.com/s/2FVYnKHXFoj18W62pob_jw)\\n - \u2b50\ufe0f [\u4e00\u6587\u8bfb\u61c2 Go Http Server \u539f\u7406](https://mp.weixin.qq.com/s/aLiqEuD9T8sERVrfGDSxvw)\\n - \u2b50\ufe0f [Golang slog \u4ecb\u7ecd](https://mp.weixin.qq.com/s/0JbLDkJboDDihy-7N4MMPw)\\n - \u2b50\ufe0f [Golang \u5e93: golang slog \u600e\u4e48\u8bbe\u7f6e\u65e5\u5fd7 Debug \u7b49\u7ea7](https://mp.weixin.qq.com/s/Immr4DD-XA-noOEkZ6flKg)\\n - \u2b50\ufe0f [Golang \u5e93: \u4e3a\u4ec0\u4e48 Golang slog \u5e93\u4e0d\u652f\u6301 Fatal](https://mp.weixin.qq.com/s/PKtrqHFTYWyAVSolKVOoBQ)\\n - \u2b50\ufe0f [\u53d1\u73b0conc\u5e76\u53d1\u5e93\u4e00\u4e2a\u6709\u8da3\u7684\u95ee\u9898](https://mp.weixin.qq.com/s/G8mEAKRYbaae_rFBVJqdeg)\\n - \u2b50\ufe0f [Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72](https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg)\\n - \u2b50\ufe0f [\u300cGo\u8bed\u8a00\u8fdb\u9636\u300d\u5e76\u53d1\u7f16\u7a0b\u8be6\u89e3 | \u6587\u672b\u62bd\u5956](https://mp.weixin.qq.com/s/irp0uBR-nJ87tZ_elMWPnA)\\n - \u2b50\ufe0f [\u4e00\u6587\u5165\u95e8Go\u4e91\u539f\u751f\u5fae\u670d\u52a1\u300c\u7206\u809d6\u5343\u5b57\u300d](https://juejin.cn/post/7194334949011357755)\\n - \u2b50\ufe0f [\u4e3a\u4ec0\u4e48 Go \u4e0d\u652f\u6301 \\\\[\\\\]T \u8f6c\u6362\u4e3a \\\\[\\\\]interface](https://mp.weixin.qq.com/s/jsdGV31yT5AR07BzRovWVw)\\n - \u2b50\ufe0f [go-zero \u662f\u5982\u4f55\u505a\u8def\u7531\u7ba1\u7406\u7684](https://mp.weixin.qq.com/s/uTJ1En-BXiLvH45xx0eFsA)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4e2d\u6392\u5e8f\u7684 3 \u79cd\u65b9\u6cd5](https://mp.weixin.qq.com/s/RyVc_JZJi_pTT_51mEHYiw)\\n - \u2b50\ufe0f [\u4e00\u6587\u5403\u900f Go \u5185\u7f6e RPC \u539f\u7406](https://mp.weixin.qq.com/s/ExfVdEM7_YWlQF6GhFn74A)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5c\u5185\u5b58\u56de\u6536\u53c8\u8e29\u5751\u4e86](https://mp.weixin.qq.com/s/ea7LfF2jOoHOSozX-qUZLA)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cGo \u7684 nil \u503c\u5224\u65ad\uff0c\u5343\u65b9\u767e\u8ba1\uff0c\u8fd8\u662f\u8e29\u5751!](https://mp.weixin.qq.com/s/BwqHMhc2WtAY_R-UffNQ4w)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cpprof \u7edf\u8ba1\u7684\u5185\u5b58\u603b\u662f\u504f\u5c0f](https://mp.weixin.qq.com/s/-3X0c4P0WdZdjtkTsX16Rw)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5c\u89e3\u5bc6 defer \u539f\u7406\uff0c\u7a76\u7adf\u80cc\u7740\u7a0b\u5e8f\u733f\u505a\u4e86\u591a\u5c11\u4e8b\u60c5](https://mp.weixin.qq.com/s/ZgTCSj-PZMTiMCR4FtBeyA)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang \u5e76\u53d1\u7f16\u7a0b\u6838\u5fc3\u7bc7 \u2014\u2014 \u5185\u5b58\u53ef\u89c1\u6027](https://mp.weixin.qq.com/s/Atj8Ngvg3Uzw4gMDwf5rag)\\n - \u2b50\ufe0f [Go \u6700\u7ec6\u8282\u7bc7\uff5cGolang\u6700\u7ec6\u8282\u7bc7\u2014 struct{} \u7a7a\u7ed3\u6784\u4f53\u7a76\u7adf\u662f\u5565](https://mp.weixin.qq.com/s/2u2qRUbgcOwvU9wcHpC0SA)\\n - \u2b50\ufe0f [Go Slice \u6269\u5bb9\u7684\u8fd9\u4e9b\u5751\u4f60\u8e29\u8fc7\u5417](https://mp.weixin.qq.com/s/ylsTVohPo7x8QKAUj1uoTA)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u5b9e\u73b0\u521b\u5efa\u578b\u8bbe\u8ba1\u6a21\u5f0f - \u5355\u4f8b\u6a21\u5f0f](https://mp.weixin.qq.com/s/ixTP1qythuJyhf3b9kIRaA)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u81ea\u5e26\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/qTYlHqozkWHkhF9OKfaAMQ)\\n - \u2b50\ufe0f [\u5982\u4f55\u505a\u597d\u8868\u7ed3\u6784\u8bbe\u8ba1](https://mp.weixin.qq.com/s/SYQTlvbLvbsSwFi2Q_kI1Q)\\n - \u2b50\ufe0f [Go \u9519\u8bef\u5904\u7406\uff1a100+ \u63d0\u6848\u5168\u90e8\u88ab\u62d2\u7edd\uff0c\u4e3a\u4f55\u73b0\u9636\u6bb5\u4ecd\u7528 if err != nil](https://mp.weixin.qq.com/s/xiUPLOTkDCX2i2jTOSNgCQ)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u5e76\u53d1\u6a21\u5f0f\u4ee3\u7801\u6a21\u677f](https://mp.weixin.qq.com/s/431YMKwRjaStanqA6juePA)\\n - \u2b50\ufe0f [\u57fa\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4f18\u5316\u9884\u89c8](https://mp.weixin.qq.com/s/elsHIqDQ0yABUZXNVpjwMg)\\n - \u2b50\ufe0f [\u300c\u9ad8\u9891\u5fc5\u8003\u300dGo\u5e76\u53d1\u7f16\u7a0b\u9762\u8bd5\u9898\u548c\u7b54\u6848](https://mp.weixin.qq.com/s/soaxFUjo6hEe2KSnle_LkQ)\\n - \u2b50\ufe0f [\u6e90\u7801\u9605\u8bfb - \u5207\u7247\u6269\u5bb9\u8fc7\u7a0b](https://mp.weixin.qq.com/s/k0zwlJNFssMRh1NHA6rGcA)\\n - \u2b50\ufe0f [Golang\u53cd\u5c04\u5b66\u4e60\uff1a\u624b\u5199\u4e00\u4e2aRPC](https://mp.weixin.qq.com/s/PzfiMXiYjfGQFHW_0hTS4A)\\n - \u2b50\ufe0f [\u6df1\u5165\u89e3\u6790\u975e\u963b\u585eGolang IO\u6846\u67b6nbio](https://mp.weixin.qq.com/s/mAo2K8lZNeJHTtShBHlUsQ)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u6807\u51c6\u5e93 bufio \u8be6\u89e3](https://mp.weixin.qq.com/s/aP9bT4UL1MK5EDx18WfvmQ)\\n - \u2b50\ufe0f [CPU \u7f13\u5b58\u4f53\u7cfb\u5bf9 Go \u7a0b\u5e8f\u7684\u5f71\u54cd](https://mp.weixin.qq.com/s/Yi0eGTzrT7mtkpebmLXqVA)\\n - \u2b50\ufe0f [\u300c\u5237\u8d77\u6765\u300dGo\u5fc5\u770b\u7684\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3](https://mp.weixin.qq.com/s/2iOkW5h7x-1wdYe51vMemw)\\n - \u2b50\ufe0f [Go \u6027\u80fd\u52a0\u901f\u5668\uff1a\u4f60\u9700\u8981\u77e5\u9053\u7684 5 \u4e2a\u8bc0\u7a8d\u548c\u6280\u5de7](https://mp.weixin.qq.com/s/NJuOB8k86Z7Hv-xITL1Vqg)\\n - \u2b50\ufe0f [\u6df1\u5165\u5256\u6790 Golang \u7a0b\u5e8f\u542f\u52a8\u539f\u7406 - \u4ece ELF \u5165\u53e3\u70b9\u5230GMP\u521d\u59cb\u5316\u5230\u6267\u884c main\uff01](https://mp.weixin.qq.com/s/tgBqY3xYbk5IBzViL9eaiA)\\n - \u2b50\ufe0f [\u4ece\u7f16\u8bd1\u539f\u7406\u5230 Go \u542f\u52a8\u65f6\u7684\u6d41\u7a0b\uff0cGo\u7a0b\u5e8f\u662f\u600e\u6837\u8dd1\u8d77\u6765\u7684](https://juejin.cn/post/7254384497649844280)\\n - \u2b50\ufe0f [\u4ece.go\u6587\u672c\u6587\u4ef6\u5230\u53ef\u6267\u884c\u6587\u4ef6](https://mp.weixin.qq.com/s/V5wAZcTbunU3HdS1xaWavQ)\\n - \u2b50\ufe0f [Go \u7f16\u8bd1\u5668\u4f18\u5316](https://mp.weixin.qq.com/s/eWM9AvG1qXnMWF4qIwhnVQ)\\n - \u2b50\ufe0f [\u5b66\u4f1a Go select \u8bed\u53e5\uff0c\u8f7b\u677e\u5b9e\u73b0\u9ad8\u6548\u5e76\u53d1](https://juejin.cn/post/7210005376653377597)\\n - \u2b50\ufe0f [Go Mutex\uff1a\u4fdd\u62a4\u5e76\u53d1\u8bbf\u95ee\u5171\u4eab\u8d44\u6e90\u7684\u5229\u5668](https://juejin.cn/post/7215188852851097656)\\n - \u2b50\ufe0f [Go RWMutex\uff1a\u9ad8\u5e76\u53d1\u8bfb\u591a\u5199\u5c11\u573a\u666f\u4e0b\u7684\u6027\u80fd\u4f18\u5316\u5229\u5668](https://juejin.cn/post/7218554163051413561)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4e2d\u6ca1\u6709\u679a\u4e3e\u7c7b\u578b\uff0c\u4f46\u662f\u6211\u4eec\u53ef\u4ee5\u8fd9\u6837\u505a](https://juejin.cn/post/7223035239072333861)\\n - \u2b50\ufe0f [Go \u65b9\u6cd5\u63a5\u6536\u5668\uff1a\u9009\u62e9\u503c\u63a5\u6536\u5668\u8fd8\u662f\u6307\u9488\u63a5\u6536\u5668](https://juejin.cn/post/7224147971834691639)\\n - \u2b50\ufe0f [\u4e00\u6587\u638c\u63e1 Go \u5e76\u53d1\u6a21\u5f0f Context \u4e0a\u4e0b\u6587](https://juejin.cn/post/7233981178101186619)\\n - \u2b50\ufe0f [Go \u7a7a\u7ed3\u6784\u4f53\uff1a\u96f6\u5185\u5b58\u7684\u9b54\u529b](https://mp.weixin.qq.com/s/rD3pnjWF5_Zz-r6GB0LrrA)\\n - \u2b50\ufe0f [Go \u51fd\u6570\u9009\u9879\u6a21\u5f0f\uff08Functional Options Pattern\uff09](https://juejin.cn/post/7241938328839618597)\\n - \u2b50\ufe0f [Go \u9879\u76ee\u5206\u5c42\u4e0b\u7684\u6700\u4f73 error \u5904\u7406\u65b9\u5f0f](https://juejin.cn/post/7246777406387306553)\\n - \u2b50\ufe0f [Go \u8bed\u8a00 iota \u7684\u795e\u5947\u529b\u91cf](https://mp.weixin.qq.com/s/xjkY6hJnUq5btDyJuSOZrg)\\n - \u2b50\ufe0f [\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\uff1a\u63a2\u7d22Go\u8bed\u8a00\u4e2d\u7684\u51fd\u6570\u4e00\u7b49\u516c\u6c11](https://mp.weixin.qq.com/s/sJeXoxTSh7M9azpsbsr1rQ)\\n - \u2b50\ufe0f [\\\\[Go\u5f00\u6e90\u5de5\u5177\\\\] go-optioner\uff1a\u8f7b\u677e\u751f\u6210\u51fd\u6570\u9009\u9879\u6a21\u5f0f\u4ee3\u7801](https://mp.weixin.qq.com/s/_enXW8Pk4okosAgDo_aYSw)\\n - \u2b50\ufe0f [\u6df1\u5165\u63a2\u7d22 Go 1.21.0 \u4e2d\u7684 maps \u5de5\u5177\u5e93](https://mp.weixin.qq.com/s/biTRyEu2h8AzQaQf7Ik8nA)\\n - \u2b50\ufe0f [Go Gin \u6846\u67b6\u7cfb\u5217 - \u5165\u95e8\u7bc7](https://mp.weixin.qq.com/s/_a9d67L8l7G6EDJom1kixw)\\n - \u2b50\ufe0f [Go \u9879\u76ee\u5fc5\u5907\uff1a\u6df1\u5165\u6d45\u51fa Wire \u4f9d\u8d56\u6ce8\u5165\u5de5\u5177](https://mp.weixin.qq.com/s/gC4D9CqeYAd-jPotKgIV4g)\\n - \u2b50\ufe0f [\u5feb\u901f\u4e0a\u624b Go CGO\uff0c\u638c\u63e1\u5728 Go \u91cc\u5199 C\uff01](https://juejin.cn/post/7226187111330611255)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1a\u8fc7\u4e86\u4e00\u5e74\u534a\uff0cslices\u3001maps \u6cdb\u578b\u5e93\u7ec8\u4e8e\u8981\u52a0\u5165\u6807\u51c6\u5e93](https://mp.weixin.qq.com/s/1NuBnk8_lxmTi9N0biLa2g)\\n - \u2b50\ufe0f [Go1.22 \u53ef\u80fd\u4f1a\u89e3\u51b3\u5faa\u73af\u53d8\u91cf\u7684\u5751\uff0c\u771f\u597d\uff01\uff01](https://mp.weixin.qq.com/s/N7_-WNBsTpTc4X8qTQw-Nw)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1a\u9a9a\u64cd\u4f5c panic(nil) \u5c06\u6210\u4e3a\u5386\u53f2\uff01\u4ee5\u540e\u522b\u8fd9\u4e48\u5e72\u4e86](https://mp.weixin.qq.com/s/xgJ8lPS-O84Ttne5heRa3g)\\n - \u2b50\ufe0f [Go1.21.0 \u65b0\u7279\u6027\uff1a\u4e0d\u9700\u8981\u5faa\u73af delete map \u5143\u7d20\u4e86](https://mp.weixin.qq.com/s/rxxQhrVk3_4ZvTjsIJbstw)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1a\u65b0\u5185\u7f6e\u51fd\u6570 clear\u3001min\u3001max \u548c\u65b0\u6807\u51c6\u5e93\u5305 cmp\uff01](https://mp.weixin.qq.com/s/MorBUrzpKFhssiZWLt4o6g)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1ago.mod \u7684 Go \u7248\u672c\u53f7\u5c06\u4f1a\u7ea6\u675f Go \u7a0b\u5e8f\u6784\u5efa\uff0c\u8981\u7279\u522b\u6ce8\u610f\u4e86\uff01](https://mp.weixin.qq.com/s/s13EBwOExsVz_vwNEm0fvQ)\\n - \u2b50\ufe0f [Go \u5c06\u5f15\u5165\u6807\u51c6\u5e93 v2 \u7248\u672c\uff0c\u9996\u4e2a\u52a8\u624b\u7684\u662f\uff1amath/rand/v2\uff01](https://mp.weixin.qq.com/s/b_TYBRIZ3-EORFYq1xRjyQ)\\n - \u2b50\ufe0f [Go1.21 \u901f\u89c8\uff1aContext \u53ef\u4ee5\u8bbe\u7f6e\u53d6\u6d88\u539f\u56e0\u548c\u56de\u8c03\u51fd\u6570\u4e86\uff0c\u7b49\u7684\u53ef\u592a\u4e45\u4e86\uff01](https://juejin.cn/post/7249913673216966714)\\n - \u2b50\ufe0f [Go \u56e2\u961f\u5c06\u4fee\u6539 for \u5faa\u73af\u53d8\u91cf\u7684\u8bed\u4e49\uff0cGo1.21 \u65b0\u7248\u672c\u5373\u53ef\u4f53\u9a8c\uff01](https://mp.weixin.qq.com/s/VO0VlfGbuvZst9yD73-VDQ)\\n - \u2b50\ufe0f [Google \u5de5\u4f5c 10+ \u5e74\u7684\u611f\u609f\uff0c\u6709\u770b\u5230 Go \u6838\u5fc3\u56e2\u961f\u7684\u5f71\u5b50\u5417](https://mp.weixin.qq.com/s/Z8kMDwuv9ZlmqvdrOu5SEQ)\\n - \u2b50\ufe0f [Go defer \u53bb\u6389\u95ed\u5305\u51fd\u6570\uff0c\u9760\u8c31\u5417](https://mp.weixin.qq.com/s/4vpgxwTEn-xjdmXF5Hj7Kw)\\n - \u2b50\ufe0f [\u53e6\u4e00\u79cd\u89c6\u89d2\uff1a\u6211\u4e3a\u4ec0\u4e48\u653e\u5f03 Go \u8bed\u8a00](https://mp.weixin.qq.com/s/xjjnE5hcspbNRGHP-I869A)\\n - \u2b50\ufe0f [Go \u9762\u8bd5\u9898\uff1astring \u662f\u7ebf\u7a0b\u5b89\u5168\u7684\u5417](https://mp.weixin.qq.com/s/4pPpHRWflkkvqrf-FlXztg)\\n - \u2b50\ufe0f [Go \u6539\u7248\u672c\u53f7\u89c4\u5219\uff0c\u4e3b\u7248\u672c\u53f7\u7ec8\u4e8e\u652f\u6301\u7b2c\u4e09\u4f4d\u6570\u5b57 0 \u4e86](https://mp.weixin.qq.com/s/BfW8Ra3tsv7Dv3nu3MeI0g)\\n - \u2b50\ufe0f [Go1.21 \u90a3\u4e9b\u4e8b\uff1a\u6cdb\u578b\u5e93\u3001for \u8bed\u4e49\u53d8\u66f4\u3001\u7edf\u4e00 log/slog\u3001WASI \u7b49\u65b0\u7279\u6027\uff0c\u4f60\u77e5\u9053\u591a\u5c11](https://mp.weixin.qq.com/s/Nuj_cYFvBesaBbSSz5PuBg)\\n - \u2b50\ufe0f [\u53c8\u6709\u65b0\u529f\u80fd\uff01Go \u5c06\u6709\u751f\u6210\u65b0\u6a21\u677f\u7684 gonew \u5de5\u5177\u94fe](https://mp.weixin.qq.com/s/jk7k5v9uvaNy_2fUsDjq0Q)\\n - \u2b50\ufe0f [Go \u5c06\u589e\u52a0\u5185\u7f6e\u7684\u96f6\u503c\u6807\u8bc6\u7b26 zero\uff01](https://mp.weixin.qq.com/s/o1iKbXJEikJn8BLwetvF5g)\\n - \u2b50\ufe0f [Go \u96f6\u503c\u548c\u7a7a\u503c\u7684\u5224\u65ad\u95ee\u9898](https://mp.weixin.qq.com/s/M6b4Q7rwKSt4KNKJN7_j4g)\\n - \u2b50\ufe0f [Go \u8d1f\u8d23\u4eba\u8bf4\u4ee5\u540e\u4e0d\u4f1a\u6709 Go2 \u4e86](https://mp.weixin.qq.com/s/5kNyYJhrzigujLq1YSVjHw)\\n - \u2b50\ufe0f [Go \u5e38\u91cf\u4e3a\u4ec0\u4e48\u53ea\u652f\u6301\u57fa\u672c\u6570\u636e\u7c7b\u578b](https://mp.weixin.qq.com/s/TlJFr25XNgGA7uyRtLMOlw)\\n - \u2b50\ufe0f [Go \u5b98\u65b9\u65b0\u73a9\u5177\uff1a\u6f0f\u6d1e\u7ba1\u7406\u548c\u626b\u63cf\uff0c\u770b\u770b\u81ea\u5df1\u9879\u76ee\u6709\u6ca1\u6709\u5751](https://mp.weixin.qq.com/s/xO_w3FvNN8OeiuEYFarwGQ)\\n - \u2b50\ufe0f [\u5feb\u901f\u638c\u63e1 Go \u5de5\u4f5c\u533a\u6a21\u5f0f](https://mp.weixin.qq.com/s/4yfVZCaJ1489ddpYD5vDQA)\\n - \u2b50\ufe0f [\u300c\u5fc5\u77e5\u5fc5\u4f1a\u300d Nacos \u7684\u9762\u8bd5\u9898\u548c\u8be6\u89e3](https://mp.weixin.qq.com/s/C_KpYoul8ko5yrVLMe_uQg)\\n - \u2b50\ufe0f [zookeeper\u5230nacos\u7684\u8fc1\u79fb\u5b9e\u8df5](https://mp.weixin.qq.com/s/8XdbLrlzHhofiC089AMb1Q)\\n - \u2b50\ufe0f [\u4e0a\u7bc7\uff1a\u5e26\u4f60\u624b\u5de5\u4f53\u9a8c\u4ece\u5199\u4ee3\u7801\u3001\u7f16\u8bd1\u3001\u6253\u5305\u955c\u50cf\u3001\u90e8\u7f72\u5230K8S\u7684\u5168\u8fc7\u7a0b](https://mp.weixin.qq.com/s/YGhndR5zR-Ebf8IaKbFZiQ)\\n - \u2b50\ufe0f [\u4e0b\u7bc7\uff1a\u4f7f\u7528jenkins\u53d1\u5e03go\u9879\u76ee\u5230k8s\uff0c\u63a5\u4e0a\u7bc7\u7684\u624b\u5de5\u4f53\u9a8c\u6539\u9020\u4e3a\u81ea\u52a8\u5316\u53d1\u5e03](https://mp.weixin.qq.com/s/yJ6rkYrwn8RAMLt5uCF9mw)\\n - \u2b50\ufe0f [\u503c\u5f97\u6536\u85cf\uff1aK8S\u7684kubectl\u5e38\u7528\u547d\u4ee4\u5df2\u7ecf\u6309\u573a\u666f\u5206\u597d\u7c7b\uff0c\u8bf7\u60a8\u67e5\u9605](https://mp.weixin.qq.com/s/pW0vxt8k1pDk0OEz5asWGQ)\\n - \u2b50\ufe0f [\u907f\u5751\uff1aGo\u5e76\u53d1\u7f16\u7a0b\u65f6\uff0c\u5982\u4f55\u907f\u514d\u53d1\u751f\u7ade\u6001\u6761\u4ef6\u548c\u6570\u636e\u7ade\u4e89](https://mp.weixin.qq.com/s/lYg-GdheztmkTo9mwqHGsg)\\n - \u2b50\ufe0f [Go\u63a5\u53e3\uff1a\u8fd0\u7ef4\u5f00\u53d1\u573a\u666f\u4e2d\uff0cgo\u7684\u63a5\u53e3\u5230\u5e95\u600e\u4e48\u7528](https://mp.weixin.qq.com/s/bwkK3Yw02w4szwub2B2-ig)\\n - \u2b50\ufe0f [Go\uff1a4\u4e2a\u573a\u666f\u5c31\u53ef\u4ee5\u8ba9\u4f60\u77e5\u9053Goroutine\u548c\u901a\u9053\u662f\u600e\u4e48\u7528\u7684](https://mp.weixin.qq.com/s/bqZ6gAsOZoVEMSCeOuLbiQ)\\n - \u2b50\ufe0f [\u4e0d\u80cc\u9505\u8fd0\u7ef4\uff1aGo\u8bed\u8a00\u5207\u7247\u5185\u5b58\u4f18\u5316\u6280\u5de7\u548c\u5b9e\u6218\u6848\u4f8b](https://juejin.cn/post/7210747150828798008)\\n - \u2b50\ufe0f [Go\u5b9e\u6218\uff1a\u5f00\u53d1\u4e00\u4e2a\u7b80\u5355\u7684gRPC Demo](https://mp.weixin.qq.com/s/rxPAcU5zhWCtRQLbh9uxKw)\\n - \u2b50\ufe0f [Go\uff1a\u4f7f\u7528Cobra\u6253\u9020\u5f3a\u5927\u547d\u4ee4\u884c\u5e94\u7528](https://mp.weixin.qq.com/s/im8JZV3bL9WVOn7VgArmhw)\\n - \u2b50\ufe0f [Go\u7684\u8fd9\u4e2a\u5e93\uff0c\u8ba9\u4f60\u7684\u547d\u4ee4\u884c\u8f93\u51fa\u53d8\u5f97\u4e13\u4e1a](https://mp.weixin.qq.com/s/4VfTjWQwNO-tlxYbUOrWZw)\\n - \u2b50\ufe0f [\u300cGo\u5f00\u6e90\u5305\u300dasynq\uff1a\u4e00\u4e2a\u57fa\u4e8eredis\u7684\uff0c\u7b80\u5355\u3001\u53ef\u9760\u3001\u9ad8\u6548\u7684\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u5305](https://mp.weixin.qq.com/s/nbouC5ynfZShaTMTYiCJFA)\\n - \u2b50\ufe0f [\u62bd\u4e1d\u5265\u8327\uff0c\u8bb0\u4e00\u6b21 Go \u7a0b\u5e8f\u6027\u80fd\u4f18\u5316\u4e4b\u65c5](https://mp.weixin.qq.com/s/HBLwocMA2vQE2uFlJ0D8Iw)\\n - \u2b50\ufe0f [Go\uff1a\u8bb0\u4e00\u6b21\u63d0\u534718\u500d\u7684\u6027\u80fd\u4f18\u5316](https://mp.weixin.qq.com/s/1Y_A6WVslDthVjtbP9Ibvg)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u4e2dJSON\u5904\u7406\u6280\u5de7\u603b\u7ed3](https://mp.weixin.qq.com/s/js3m_Fe6k4ys4aBSFDJhLQ)\\n - \u2b50\ufe0f [\u63a2\u7a76\uff5cGo JSON \u4e09\u65b9\u5305\u54ea\u5bb6\u5f3a](https://mp.weixin.qq.com/s/ueNuYA23F3bQTwIKU-PZ2Q)\\n - \u2b50\ufe0f [Sonic: Go\u8bed\u8a00\u7684\u8d85\u7ea7JSON\u5e93\uff0c\u89e3\u6790\u4e0e\u7f16\u7801\u901f\u5ea6\u72c2\u98d9](https://mp.weixin.qq.com/s/IAHEQu-N5OO-X_q-47GCsQ)\\n - \u2b50\ufe0f [\u6536\u85cf\uff01\uff01\uff01\u4e00\u56fe\u638c\u63e1 Go \u4e2d IO \u5305\u7684\u5173\u7cfb](https://mp.weixin.qq.com/s/cjQyDdIgcdzj7LOeZf21bQ)\\n - \u2b50\ufe0f [\u901a\u8fc7\u6e90\u7801\u5256\u6790Go\u7684map\u6269\u5bb9\u5e95\u5c42\u5b9e\u73b0](https://juejin.cn/post/7207058392287346747)\\n - \u2b50\ufe0f [\u300c\u6709\u95ee\u5fc5\u7b54\u300dGopher\u5982\u4f55\u4f18\u96c5\u7684\u5bf9\u65f6\u95f4\u8fdb\u884c\u683c\u5f0f\u5316](https://mp.weixin.qq.com/s/cK2KMpN4vUrlDXEkTm7Mig)\\n - \u2b50\ufe0f [Go \u6cdb\u578b\u7684\u4e8c\u5341\u4e00\u4e2a\u9677\u9631](https://mp.weixin.qq.com/s/7qutgFgPDGyjKhxb6YVB3Q)\\n - \u2b50\ufe0f [\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff1a\u6df1\u5165\u63a2\u7d22Golang\u4e2d\u7684SM4\u52a0\u5bc6\u89e3\u5bc6\u7b97\u6cd5](https://juejin.cn/post/7248388270723039290)\\n - \u2b50\ufe0f [\u7cbe\u90098\u9053ES\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\uff0c\u540e\u6094\u6ca1\u65e9\u70b9\u770b](https://juejin.cn/post/7248791708334899258)\\n - \u2b50\ufe0f [\u7cbe\u9009Go\u9ad8\u9891\u9762\u8bd5\u9898\u548c\u7b54\u6848\u6c47\u603b\uff0c\u9605\u8bfb\u7834\u4e07\uff0c\u6536\u85cf230+](https://juejin.cn/post/7248995705291866169)\\n - \u2b50\ufe0f [Go\u8fdb\u9636\u9762\u8bd5\u9898\u8be6\u89e3 | \u6587\u672b\u9001\u4e66](https://mp.weixin.qq.com/s/ldn5APfp0UooWbh4cmcM4A)\\n - \u2b50\ufe0f [Go\u4e2d\u8fd9\u4e48\u591a\u521b\u5efaerror\u7684\u65b9\u5f0f\uff0c\u4f60\u771f\u7684\u4e86\u89e3\u5b83\u4eec\u5404\u81ea\u7684\u5e94\u7528\u573a\u666f\u5417](https://mp.weixin.qq.com/s/GXAvaFvXR3HYI7qU4lL4lA)\\n - \u2b50\ufe0f [\u57fa\u4e8eRedis\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u56fa\u5b9a\u7a97\u53e3\u9650\u6d41\u5668](https://mp.weixin.qq.com/s/6aicpVC3qjRpf1ILI4V4lA)\\n - \u2b50\ufe0f [go channel\u5e94\u7528\u7cfb\u5217\u4e4b\u63a7\u5236\u534f\u7a0b\u6570\u91cf](https://mp.weixin.qq.com/s/CUQaiZp4BrulnXvLd9ogZQ)\\n - \u2b50\ufe0f [\u914d\u56fe\u6e05\u65b0\u7684Protobuf \u7f16\u7801&\u907f\u5751\u6307\u5357](https://mp.weixin.qq.com/s/YJp2jxuBwwbPBaMWlDZG9g)\\n - \u2b50\ufe0f [\u5199\u7ed9\u5f00\u53d1\u8005\u7684gRPC\u6559\u7a0b-\u670d\u52a1\u53d1\u73b0\u4e0e\u8d1f\u8f7d\u5747\u8861](https://mp.weixin.qq.com/s/iptZLaGFLd1rDedclQUMFg)\\n - \u2b50\ufe0f [\u7b54\u7f51\u53cb\u95ee\uff1agolang\u4e2d\u7684slice\u4f5c\u4e3a\u51fd\u6570\u53c2\u6570\u65f6\u662f\u503c\u4f20\u9012\u8fd8\u662f\u5f15\u7528\u4f20\u9012](https://mp.weixin.qq.com/s/oettru3CV_Cjqv5GEOmcMw)\\n - \u2b50\ufe0f [Go\u53ef\u7528\u6027(\u4e03) \u603b\u7ed3: \u4e00\u5f20\u56fe\u4e32\u8054\u53ef\u7528\u6027\u77e5\u8bc6\u70b9](https://mp.weixin.qq.com/s/OXopl6FpwtE6P-k0GEP9qA)\\n - \u2b50\ufe0f [Go \u5de5\u7a0b\u5316(\u5341) \u5982\u4f55\u5728\u6574\u6d01\u67b6\u6784\u4e2d\u4f7f\u7528\u4e8b\u52a1](https://mp.weixin.qq.com/s/MSwUlVGPDRBjdR-xh5cNfA)\\n - \u2b50\ufe0f [Go \u5de5\u7a0b\u5316(\u5341\u4e00) \u5982\u4f55\u4f18\u96c5\u7684\u5199\u51fa repo \u5c42\u4ee3\u7801](https://mp.weixin.qq.com/s/pb0P_y34N3uOhMu0SDqC2A)\\n - \u2b50\ufe0f [\u4f7f\u7528 Go \u8bed\u8a00\u5b9e\u73b0\u4e8c\u53c9\u641c\u7d22\u6811](https://mp.weixin.qq.com/s/2wYRmG_AiiHYjLDEXg94Ag)\\n - \u2b50\ufe0f [Opentelemetry \u5b9e\u8df5\u5206\u4eab - Golang\u7bc7](https://mp.weixin.qq.com/s/7hU0iSDBg0z1nYZnB-61gQ)\\n - \u2b50\ufe0f [Golang\u5b9e\u73b0\u5355\u673a\u767e\u4e07\u957f\u8fde\u63a5\u670d\u52a1 - \u7f8e\u56fe\u7684\u4e09\u5e74\u4f18\u5316\u7ecf\u9a8c](https://mp.weixin.qq.com/s/xavjsa4NzRiVRxyMhifCDg)\\n - \u2b50\ufe0f [\u4f7f\u7528go-zero\u5feb\u901f\u6784\u5efa\u5fae\u670d\u52a1](https://mp.weixin.qq.com/s/IpvR28soReYC3nNkAisteA)\\n - \u2b50\ufe0f [\u5927\u578b Go \u4ee3\u7801\u5e93\u7684 3 \u79cd\u6700\u4f73\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/yHD5XKsk6emuXjcnU2JxDw)\\n - \u2b50\ufe0f [Asynq: \u57fa\u4e8eRedis\u5b9e\u73b0\u7684Go\u751f\u6001\u5206\u5e03\u5f0f\u4efb\u52a1\u961f\u5217\u548c\u5f02\u6b65\u5904\u7406\u5e93](https://mp.weixin.qq.com/s/n199y8JEyjuGFwUEyH2XVg)\\n - \u2b50\ufe0f [\u300cGo\u9762\u7ecf\u300d\u7b97\u6cd5 \u5e76\u53d1\u6a21\u578b \u7f13\u5b58\u843d\u76d8 etcd actor\u6a21\u578b](https://mp.weixin.qq.com/s/C2kZGElYQmHz3OCb7LuYoA)\\n - \u2b50\ufe0f [\u63a2\u7d22 Go1.21 \u4e2d\u7684 slices \u5305\uff1a\u539f\u7406\uff0c\u7279\u70b9\u548c\u793a\u4f8b](https://mp.weixin.qq.com/s/2tFBe6LH84dZnOcfkgX32w)\\n - \u2b50\ufe0f [\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a](https://mp.weixin.qq.com/s/7nK4whfh0Owwhmq_67_eYg)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4e3a\u4ec0\u4e48\u9002\u5408\u5f00\u53d1\u7f51\u7edc\u670d\u52a1](https://mp.weixin.qq.com/s/_mXRLJ-h7Iqkrt1jq_sZXg)\\n - \u2b50\ufe0f [\u7528 Go \u7f16\u5199\u7b80\u6d01\u4ee3\u7801\u7684\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/iamOjb0k3M2k_FVG9W7z0A)\\n - \u2b50\ufe0f [Golang channel \u4e09\u5927\u5751\uff0c\u4f60\u8e29\u8fc7\u4e86\u561b](https://mp.weixin.qq.com/s/7vDklpTsbRdRDvB0-yvB5g)\\n - \u2b50\ufe0f [\u4f7f\u7528Singleflight\u4f18\u5316Go\u4ee3\u7801](https://mp.weixin.qq.com/s/j9Obe6Na25388AzeSL1dRA)\\n - \u2b50\ufe0f [\u76d8\u70b9 Go \u8bed\u8a00\u7684\u90a3\u4e9b\u65e5\u5fd7\u5e93\uff1a\u4f60\u7528\u4e86\u54ea\u4e2a](https://mp.weixin.qq.com/s/gVjq59qnLjy-gwibt7Q3yw)\\n - \u2b50\ufe0f [\u5b9a\u4e86\uff1aGo 1.22\u5c06\u4fee\u590dfor\u5faa\u73af\u53d8\u91cf\u9519\u8bef](https://mp.weixin.qq.com/s/G3FGOUo-F-stOp5eZjq4QQ)\\n - \u2b50\ufe0f [Go\u5b57\u7b26\u4e32\u64cd\u4f5c\u4e0d\u662f\u4f60\u60f3\u7684\u90a3\u4e48\u7b80\u5355\uff01](https://mp.weixin.qq.com/s/R_2pwdv2V1jj3zMjuUTNHw)\\n - \u2b50\ufe0f [Golang\u77e5\u8bc6\u70b9(defer): \u9762\u8bd5\u7ecf\u5e38\u53d8\u91cf\u5728 defer \u4e2d\u7684\u503c\uff0c \u5176\u5b9e\u5728\u95ee\u53d8\u91cf\u7684\u4f5c\u7528\u57df](https://mp.weixin.qq.com/s/QlzH18i72pWPm012t7d42Q)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(1)\uff1aGin\u6846\u67b6\u4e2d\u5982\u4f55\u5904\u7406HTTP\u8bf7\u6c42](https://mp.weixin.qq.com/s/VjP9Bv46x7NP6uQ7cbsqmg)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(2)\uff1anet\u5e93\u5bf9socket/bind/listen/accept\u7684\u5c01\u88c5](https://mp.weixin.qq.com/s/x5qUJ-htS6ML1Cc8uYIDVQ)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server](https://mp.weixin.qq.com/s/WoXZ_i7lJeXny8lIJ_Aj4g)\\n - \u2b50\ufe0f [\u3010\u8865\u5145\u4ee3\u7801\u3011Go BIO/NIO\u63a2\u8ba8(3): \u57fa\u4e8e\u7cfb\u7edf\u8c03\u7528\u5b9e\u73b0tcp echo server](https://mp.weixin.qq.com/s/76xvAvnFAcDUAa6fgoZRfg)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(4)\uff1anet/http \u5728 tcp conn \u4e0a\u7684\u5904\u7406](https://mp.weixin.qq.com/s/AvtIiC349sDqOe9labc3-A)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(5)\uff1anet\u5e93\u7684\u975e\u963b\u585e\u652f\u6301](https://mp.weixin.qq.com/s/MO5XV40D3MI6NpEEpJiCMA)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(6)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bselect](https://mp.weixin.qq.com/s/t_4uTGN9DFCjqDw4LZT-0w)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(7)\uff1aIO\u591a\u8def\u590d\u7528\u4e4bepoll](https://mp.weixin.qq.com/s/Zsh92yqK4e6mxNBLgY0Umw)\\n - \u2b50\ufe0f [Go BIO/NIO\u63a2\u8ba8(8)\uff1aGo netpoll \u7684\u5de5\u4f5c\u673a\u5236](https://mp.weixin.qq.com/s/3_eToHvOw25JrC8-xePe_w)\\n - \u2b50\ufe0f [Go\u534f\u7a0b\u6c60(1): \u7ebf\u7a0bvs\u534f\u7a0b](https://mp.weixin.qq.com/s/-qms3hEl2mNMkDN1S4ZQoQ)\\n - \u2b50\ufe0f [Go\u534f\u7a0b\u6c60(2): \u5982\u4f55\u5b9e\u73b0\u534f\u7a0b\u6c60](https://mp.weixin.qq.com/s/ktMff61A9vvqeRGkGwQnwg)\\n - \u2b50\ufe0f [\u9ad8\u5e76\u53d1\u7cfb\u7edf\u8bbe\u8ba1(1): \u5982\u4f55\u5b9e\u73b0\u6296\u97f3\u5173\u6ce8/\u7c89\u4e1d\u5217\u8868](https://mp.weixin.qq.com/s/cIgfuumVCL4rxtNYGcQH4A)\\n - \u2b50\ufe0f [SIMD\u80fd\u529b\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/ydFRhjV70QC64N8r2zEtVA)\\n - \u2b50\ufe0f [\\\\[\u4ee3\u7801\u9644\u5f55\\\\] SIMD\u80fd\u529b\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/q-keuybJ2d-QMXWoPpSbPA)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\u7b80\u4ecb](https://mp.weixin.qq.com/s/1kuLtd8rxC1xP628FgAwqw)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1a\u5927\u6570\u636e\u67b6\u6784](https://mp.weixin.qq.com/s/Ane5iRMqYrtQMnC3TWlrwA)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1a\u5fae\u670d\u52a1\u67b6\u6784](https://mp.weixin.qq.com/s/dOw25R2xihr0M3T27fYUSA)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1a\u5206\u5c42\u67b6\u6784](https://mp.weixin.qq.com/s/CUCHUQa6lYuPhvEALdIQQg)\\n - \u2b50\ufe0f [\u670d\u52a1\u67b6\u6784\uff1aWeb-Queue-Worker\u67b6\u6784](https://mp.weixin.qq.com/s/P1j0vg2FYqt1zvwPQsdtww)\\n - \u2b50\ufe0f [\u5f02\u6b65\u8bf7\u6c42-\u54cd\u5e94\u6a21\u5f0f](https://mp.weixin.qq.com/s/YkOoLbH2P2HheQxomGsbNQ)\\n - \u2b50\ufe0f [Sidecar\u6a21\u5f0f](https://mp.weixin.qq.com/s/Q-YvkWhFC2uK1z5AKEKSnw)\\n - \u2b50\ufe0f [\u9002\u5408\u56e2\u961f\u548c\u4e2a\u4eba\u9879\u76ee\u7684 Golang \u7f16\u7801\u89c4\u8303](https://juejin.cn/post/7157594175846744071)\\n - \u2b50\ufe0f [Go Scheduler \u7684 GMP \u6a21\u578b](https://mp.weixin.qq.com/s/1CY3E5daJ5U42orVwzCpaw)\\n - \u2b50\ufe0f [Golang \u6cdb\u578b\u521d\u8bc6](https://juejin.cn/post/7116817920209977351)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u5b98\u65b9\u4f9d\u8d56\u6ce8\u5165\u5de5\u5177 Wire \u4f7f\u7528\u6307\u5317](https://mp.weixin.qq.com/s/yHB9BzEGIki1fyjYojdpYQ)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u7aef\u5f00\u53d1\u603b\u7ed3](https://juejin.cn/post/7043587400131411976)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u5165\u95e8\u7cfb\u5217\uff1a\u521d\u63a2 Go \u9879\u76ee\u5b9e\u6218](https://eddycjy.com/go-categories/)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u7f16\u7a0b\u4e4b\u65c5\uff1a\u6df1\u5165\u7528 Go \u505a\u9879\u76ee](https://golang2.eddycjy.com/)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u8bbe\u8ba1\u54f2\u5b66\uff1a\u4e86\u89e3 Go \u7684\u4e3a\u4ec0\u4e48\u548c\u8bbe\u8ba1\u601d\u8003](https://golang3.eddycjy.com/)\\n - \ud83c\udf1b [Go \u8bed\u8a00\u8fdb\u9636\u4e4b\u65c5\uff1a\u8fdb\u4e00\u6b65\u6df1\u5165 Go \u6e90\u7801](https://golang1.eddycjy.com/)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011HTTP \u7cfb\u5217\u6559\u7a0b](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1383459655464337409&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00 Web \u7f16\u7a0b](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1323498303014780929&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5e76\u53d1\u7f16\u7a0b](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1325302744319737858&scene=21&from_msgid=2247484375&from_itemidx=1&count=3&nolastread=1#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u6e90\u7801](https://mp.weixin.qq.com/mp/homepage?__biz=MzkyNzI1NzM5NQ==&hid=2&sn=4d298cf2d9ad21260321275cf6c75194&scene=1&devicetype=iOS14.0&version=18000733&lang=zh_CN&nettype=3G+&ascene=7&session_us=gh_169729c17b9c&fontScale=100)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go\u6e90\u7801\u4e0e\u5e95\u5c42](http://mp.weixin.qq.com/mp/homepage?__biz=MzkyMzIyNjIxMQ==&hid=1&sn=631fe1ce375f2cd672449d0bd01963d2&scene=18#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Kubernetes \u5b66\u4e60\u7b14\u8bb0](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1394839706508148737&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011\u5fae\u670d\u52a1\u8bbe\u8ba1\u548c\u601d\u8003](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1488826194207752195&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u5fae\u670d\u52a1\u5b9e\u6218](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUzNTY5MzU2MA==&action=getalbum&album_id=1809543596702777345&scene=21&from_msgid=2247492061&from_itemidx=1&count=3&nolastread=1#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u8bed\u8a00\u5b9e\u6218\u6280\u5de7](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUzNTY5MzU2MA==&scene=1&album_id=1326949382503219201&count=3#wechat_redirect)\\n - \ud83c\udf1b [\u3010\u7cfb\u5217\u6587\u7ae0\u3011Go \u9762\u8bd5\u9898](https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxMDI4MDc1NA==&scene=1&album_id=1751854579329056768&count=3#wechat_redirect)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Effective Go](https://go.dev/doc/effective_go)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Go FAQ](https://go.dev/doc/faq)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - blog\u6587\u7ae0](https://go.dev/blog/all)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - \u5404\u4e2atalk\u8d44\u6599](https://go.dev/talks/)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303](https://tonybai.com/2019/10/12/uber-go-style-guide/)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - Google Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303](https://tonybai.com/google-go-style/)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - CodeReviewComments](https://github.com/golang/go/wiki/CodeReviewComments)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - SliceTricks](https://github.com/golang/go/wiki/SliceTricks)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - CompilerOptimizations](https://github.com/golang/go/wiki/CompilerOptimizations#optimized-memclr)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - learning-more-about-go](https://github.com/golang/go/wiki#learning-more-about-go)\\n - \u2b50\ufe0f [Golang \u8fdb\u9636 - go-concurrency-guide](https://github.com/luk4z7/go-concurrency-guide)\\n- Golang \u6587\u7ae0\u5206\u4eab\\n - \u2b50\ufe0f [Golang\u5f00\u53d1\u624b\u8bb0](https://github.com/kevinyan815/gocookbook)\\n - \u2b50\ufe0f [\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8](https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg)\\n - \u2b50\ufe0f [\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6307\u5357\u7bc7](https://mp.weixin.qq.com/s/rOtR8FfMpfBZrIkyRrNsfQ)\\n - \u2b50\ufe0f [Go \u8bed\u8a00\u4ee3\u7801\u98ce\u683c\u89c4\u8303-\u6982\u8ff0\u7bc7](https://mp.weixin.qq.com/s/RCBUlu0gRuVFSQ2m8Uyycg)\\n - \u2b50\ufe0f [\u4e07\u5b57\u957f\u6587\uff0c\u6559\u4f60\u7528go\u5f00\u53d1\u533a\u5757\u94fe\u5e94\u7528](https://mp.weixin.qq.com/s/vP2IDCK4cjyIGiutCoA7Pw)\\n - \u2b50\ufe0f [Go \u670d\u52a1\u7f51\u7edc\u4e0d\u901a\uff1fnet/http\u81ea\u5e26\u7684\u8fd9\u4e2a\u5de5\u5177\u5e2e\u4f60\u5feb\u901f\u5b9a\u4f4d](https://mp.weixin.qq.com/s/8_pJiuOzoQt6xyoLUX0CIw)\\n - \u2b50\ufe0f [\u98a0\u8986\u5fae\u670d\u52a1\u67b6\u6784\uff1f\u8c37\u6b4c\u6700\u65b0\u5f00\u6e90service weaver\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/RnsM-bWSRBiDS4v1JcRzdg)\\n - \u2b50\ufe0f [\u4e00\u4e2a Go \u7a0b\u5e8f\u7684 Benchmark \u57fa\u51c6\u5206\u6790\u5de5\u5177](https://mp.weixin.qq.com/s/i1loQpQufni3v4Ho2J6Pgw)\\n - \u2b50\ufe0f [\u4f60\u8bf4 Go \u7684\u5207\u7247\u539f\u751f\u652f\u6301\u5e76\u53d1\u5417](https://mp.weixin.qq.com/s/RLqjkV_1geeVkXeG9TLHFw)\\n - \u2b50\ufe0f [\u7535\u8111\u7528GoLand\u592a\u5361\uff0c\u8bb0\u5f55\u4e0b\u81ea\u5df1\u628aVsCode\u5b9a\u5236\u6210Go IDE\u7684\u6b65\u9aa4\u548c\u8fc7\u7a0b](https://mp.weixin.qq.com/s/gNQETEVBMOH0US42M0uODg)\\n - \u2b50\ufe0f [\u7528\u4e86Go\u533f\u540d\u7ed3\u6784\u4f53\uff0c\u642c\u7816\u6548\u7387\u66f4\u9ad8\uff0c\u4ea7\u91cf\u66f4\u8db3\u4e86](https://mp.weixin.qq.com/s/iRgaOlFs52O2TMScu8wDzg)\\n - \u2b50\ufe0f [\u5408\u8ba2\u672c\uff5c\u7528Go\u8bed\u8a00\u5b9e\u73b023\u79cd\u8bbe\u8ba1\u6a21\u5f0f\u53ca\u5b66\u4e60\u91cd\u70b9](https://mp.weixin.qq.com/s/KaesgBLyTz7xi9eXvSTMmQ)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u4e2d\u4ecb\u8005\uff0c\u6700\u540e\u7684\u6a21\u5f0f\uff01](https://mp.weixin.qq.com/s/91-XUm5Gn9oQLd_F4dLb3A)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u89e3\u91ca\u5668\u6a21\u5f0f](https://mp.weixin.qq.com/s/8v0UZWygCvkbye4Y0P-3sQ)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u547d\u4ee4\u6a21\u5f0f](https://mp.weixin.qq.com/s/n1R1fnRZuDwlaQqsDh5y3g)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u5907\u5fd8\u5f55\u6a21\u5f0f\uff0c\u5e26\u6682\u5b58\u7684\u4e1a\u52a1\u529f\u80fd\u53ef\u4ee5\u53c2\u8003\u5b83\u6765\u5b9e\u73b0](https://mp.weixin.qq.com/s/RikZAeI2Pic4vYwVNh4HnA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u8bbf\u5ba2\u6a21\u5f0f](https://mp.weixin.qq.com/s/qsw89qI8DOXyb4C1XI5QtA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f-\u8fed\u4ee3\u5668\u5230\u5e95\u662f\u4e0d\u662f\u4e00\u4e2a\u591a\u6b64\u4e00\u4e3e\u7684\u6a21\u5f0f](https://mp.weixin.qq.com/s/sABibBRsC2kknbAH18oatA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u6865\u63a5\u6a21\u5f0f\uff0c\u8ba9\u4ee3\u7801\u65e2\u80fd\u591a\u7ef4\u5ea6\u6269\u5c55\u53c8\u4e0d\u4f1a\u81c3\u80bf](https://mp.weixin.qq.com/s/O8shSU46TcgFPx3h7NGFAA)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f--\u4eab\u5143\u6a21\u5f0f\uff0c\u8282\u7701\u5185\u5b58\u7684\u597d\u5e2e\u624b](https://mp.weixin.qq.com/s/AZHO7R6IXFG8MguDpUNdbw)\\n - \u2b50\ufe0f [Go\u8bbe\u8ba1\u6a21\u5f0f\u5b9e\u6218--\u7528\u72b6\u6001\u6a21\u5f0f\u5b9e\u73b0\u7cfb\u7edf\u5de5\u4f5c\u6d41\u548c\u72b6\u6001\u673a](https://mp.weixin.qq.com/s/X9dKNO6sd-OY2VfsZpaElA)\\n - \u2b50\ufe0f [\u5916\u89c2\u6a21\u5f0f\uff0c\u4e00\u4e2a\u6bcf\u5929\u90fd\u5728\u7528\uff0c\u5374\u88ab\u591a\u6570\u4eba\u5728\u9762\u8bd5\u4e2d\u5ffd\u89c6\u7684\u6a21\u5f0f](https://mp.weixin.qq.com/s/tC9xfZFJvcNEbTXHQYvT6w)\\n - \u2b50\ufe0f [Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u9879\u76ee\u4f9d\u8d56\u8026\u5408\u5ea6\u592a\u9ad8\uff1f\u53ef\u4ee5\u7528\u9002\u914d\u5668\u505a\u4e0b\u4f18\u5316](https://mp.weixin.qq.com/s/r8975amH-DcJkWQKytIeJQ)\\n - \u2b50\ufe0f [Go \u8bbe\u8ba1\u6a21\u5f0f\uff5c\u7ec4\u5408\uff0c\u4e00\u4e2a\u5bf9\u6570\u636e\u7ed3\u6784\u7b97\u6cd5\u548c\u804c\u573a\u90fd\u6709\u63d0\u5347\u7684\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/JKWbyr4Yt7A6l1nFsANUcQ)\\n - \u2b50\ufe0f [Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u88c5\u9970\u5668\u548c\u804c\u8d23\u94fe\uff0c\u54ea\u4e2a\u6a21\u5f0f\u5b9e\u73b0\u4e2d\u95f4\u4ef6\u66f4\u79d1\u5b66](https://mp.weixin.qq.com/s/_e9Qa97gZvgv9n-pFB4lFw)\\n - \u2b50\ufe0f [sourcegraph \u51fa\u54c1\u7684\u5e76\u53d1\u5e93 conc \u8be6\u89e3](https://mp.weixin.qq.com/s/59cxPFHWcdnUxKyRyo8SKw)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u5b9e\u73b0\u7684\u53ef\u8bfb\u6027\u66f4\u9ad8\u7684\u5e76\u53d1\u795e\u5e93](https://mp.weixin.qq.com/s/AUSse5z1YES9wtKCiMdyWA)\\n - \u2b50\ufe0f [\u4e24\u79cd Option \u7f16\u7a0b\u6a21\u5f0f\u7684\u5b9e\u73b0\uff0cUber\u63a8\u8350\u8fd9\u4e00\u79cd](https://mp.weixin.qq.com/s/LW8Woq5Rg4x31DbtD-_jeA)\\n - \u2b50\ufe0f [Go\u7248\u672c\u5927\u4e8e1.13\uff0c\u7a0b\u5e8f\u91cc\u8fd9\u6837\u505a\u9519\u8bef\u5904\u7406\u624d\u5730\u9053](https://mp.weixin.qq.com/s/SFbSAGwQgQBVWpySYF-rkw)\\n - \u2b50\ufe0f [\u9762\u8bd5\u5b98\uff1anet/http\u5e93\u77e5\u9053\u5417\uff1f\u80fd\u8bf4\u8bf4\u4f18\u7f3a\u70b9\u5417](https://mp.weixin.qq.com/s/IelVDnMzGtT5y7hGSb_OxA)\\n - \u2b50\ufe0f [Go \u6a21\u7cca\u6d4b\u8bd5fuzzing\u7684\u539f\u7406\u5206\u6790](https://mp.weixin.qq.com/s/3uWozu4VIUJHyIGut3_0Bg)\\n - \u2b50\ufe0f [Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u6015\u628a\u6838\u5fc3\u4ee3\u7801\u6539\u4e71\uff0c\u8bb0\u5f97\u7528\u4ee3\u7406\u6a21\u5f0f](https://mp.weixin.qq.com/s/FTXkgxkUzsHMIspCK60G4w)\\n - \u2b50\ufe0f [\u4f60\u4e5f\u662f\u4e1a\u52a1\u5f00\u53d1\uff1f\u63d0\u524d\u7528\u8fd9\u4e2a\u8bbe\u8ba1\u6a21\u5f0f\u9884\u9632\u4ea7\u54c1\u52a0\u9700\u6c42\u5427](https://mp.weixin.qq.com/s/zCh12E10JM24EGTyFS7hPQ)\\n - \u2b50\ufe0f [Go \u7a0b\u5e8f\u91cc if else \u5206\u652f\u592a\u591a\uff1f\u8bd5\u7740\u7528\u7b56\u7565\u6a21\u5f0f\u6cbb\u7406\u4e00\u4e0b\u5427](https://mp.weixin.qq.com/s/IQsojcdwLZ1g0TgVQDoqVw)\\n - \u2b50\ufe0f [\u7528Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f-\u63d0\u70bc\u6d41\u7a0b\uff0c\u51cf\u5c11\u91cd\u590d\u5f00\u53d1\u5c31\u9760\u5b83\u4e86!](https://mp.weixin.qq.com/s/-Ysho1jI9MfrAIrplzj7UQ)\\n - \u2b50\ufe0f [Go Gin\u6846\u67b6\u8bf7\u6c42\u81ea\u52a8\u9a8c\u8bc1\u548c\u6570\u636e\u7ed1\u5b9a\uff0c\u770b\u5b8c\u8fd9\u7bc7\u5c31\u4f1a\u7528\u4e86](https://mp.weixin.qq.com/s/cAwc6ZhdUwxkI5VT8LY9Hg)\\n - \u2b50\ufe0f [Go\u5f00\u6e90\u5e93\u3001\u5927\u9879\u76ee\u7684\u516c\u5171\u5305\uff0c\u662f\u8fd9\u4e48\u7528\u5efa\u9020\u8005\u6a21\u5f0f\u7684](https://mp.weixin.qq.com/s/Uu3EAWpRO9pSbg1F1DLa_w)\\n - \u2b50\ufe0f [Go\u5b66\u8bbe\u8ba1\u6a21\u5f0f--\u539f\u578b\u6a21\u5f0f\u7684\u8003\u67e5\u70b9\u548c\u4f7f\u7528\u63a8\u8350](https://mp.weixin.qq.com/s/y1qHsQNR7EWeDU5g60Loqg)\\n - \u2b50\ufe0f [\u5de5\u5382\u6a21\u5f0f\u6709\u4e09\u4e2aLevel\uff0c\u4f60\u80fd\u7528Go\u5199\u5230\u7b2c\u51e0\u5c42](https://mp.weixin.qq.com/s/MlC6-TDf06LGpF8hxcSV_w)\\n - \u2b50\ufe0f [\u6700\u7b80\u5355\u7684\u5355\u4f8b\u6a21\u5f0f\uff0cGo\u7248\u672c\u7684\u5b9e\u73b0\u4f60\u5199\u5bf9\u4e86\u5417](https://mp.weixin.qq.com/s/1ZuhUA9Lt2uLFlamIY6fLQ)\\n - \u2b50\ufe0f [\u62d2\u7edd Go \u4ee3\u7801\u81c3\u80bf\uff0c\u5176\u5b9e\u5728\u8fd9\u51e0\u5757\u53ef\u4ee5\u7528\u4e0b\u89c2\u5bdf\u8005\u6a21\u5f0f](https://mp.weixin.qq.com/s/OKUeAdicn0Bvkz8dYx1epQ)\\n - \u2b50\ufe0f [Go\u6307\u9488\u7684\u4f7f\u7528\u9650\u5236\u548c\u7a81\u7834\u4e4b\u8def](https://mp.weixin.qq.com/s/SpVTl64W1Exy8fuN15-kmA)\\n - \u2b50\ufe0f [Go\u8bed\u8a00\u7684IO\u5e93\u90a3\u4e48\u591a\uff0c\u6211\u8be5\u600e\u4e48\u9009](https://mp.weixin.qq.com/s/TtN6NZ8hQ2AIf0C8wVzkjA)\\n - \u2b50\ufe0f [Go \u773c\u4e2d\u7684\u6587\u4ef6\u7cfb\u7edf\u662f\u4ec0\u4e48\uff1f io.FS](https://mp.weixin.qq.com/s/gYWhjh1BburgeAU72mn_aw)\\n - \u2b50\ufe0f [\u51e0\u4e2a\u63d0\u5347Go\u8bed\u8a00\u5f00\u53d1\u6548\u7387\u7684\u5c0f\u6280\u5de7](https://mp.weixin.qq.com/s/zJXPGYwNXIUyEOI0Kc15rg)\\n - \u2b50\ufe0f [\u5206\u4eab\u4e09\u4e2a\u9605\u8bfb Go \u6e90\u7801\u7684\u7a8d\u95e8](https://mp.weixin.qq.com/s/ZVLaykgYaOACbT2r-K0qBg)\\n - \u2b50\ufe0f [Gophers\u5982\u4f55\u51c6\u5907\u9762\u8bd5](https://mp.weixin.qq.com/s/Elq7SWRpH08KmhX7auboOA)\\n - \u2b50\ufe0f [Go Modules\u77e5\u8bc6\u70b9\u603b\u7ed3](https://mp.weixin.qq.com/s/FEPXDMFfvKgmtsymVTWzHw)\\n - \ud83c\udf1b [\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae](https://juejin.cn/post/7147939014870302756)\\n - \ud83c\udf1b [GO\u9762\u8bd5\u5fc5\u77e5\u5fc5\u4f1a\u9762\u8bd5\u9898](https://juejin.cn/post/7131717990558466062)\\n - [\u8fd9\u4e9b\u6700\u5e38\u7528\u7684 Go CLI \u547d\u4ee4\uff0c\u65b0\u624b Gopher \u5e94\u8be5\u638c\u63e1](https://mp.weixin.qq.com/s/kyGNVNDby5uq5JGfQt4Yrg)\\n - [PGO \u662f\u5565\uff0c\u548b\u5c31\u8ba9 Go \u66f4\u5feb\u66f4\u731b\u4e86](https://mp.weixin.qq.com/s/7uobN6DmpIYqG34pOpvvlA)\\n - [Go for \u5faa\u73af\u6709\u65f6\u5019\u771f\u7684\u5f88\u5751](https://mp.weixin.qq.com/s/Pcp2FjcXk7Q7sV0Z-bEUNw)\\n - [\u6df1\u5ea6\u89e3\u5bc6Go\u8bed\u8a00\u4e4b\u5173\u4e8e interface \u7684 10 \u4e2a\u95ee\u9898](https://mp.weixin.qq.com/s/6KxJRG3lKUDY734t4EzAaA)\\n - [\u624b\u64b8\u6e90\u7801\u7cfb\u5217 - cache2go](https://mp.weixin.qq.com/s/qyEiEACuUd8SsyqCDLUjXA)\\n - [Go\u5e38\u89c1\u9519\u8bef\u96c6\u9526\u4e4b\u51fd\u6570\u5f0f\u9009\u9879\u6a21\u5f0f](https://mp.weixin.qq.com/s/nc4s289ULpQkGlQuaFbZlQ)\\n - [\u8be6\u89e3\u5e76\u53d1\u7f16\u7a0b\u57fa\u7840\u4e4b\u539f\u5b50\u64cd\u4f5c(atomic\u5305)](https://mp.weixin.qq.com/s/THMhcM9TXydW8K5-Vvqvxg)\\n - [\u5b66\u4e60channel\u8bbe\u8ba1\uff1a\u4ece\u5165\u95e8\u5230\u653e\u5f03](https://mp.weixin.qq.com/s/E2XwSIXw1Si1EVSO1tMW7Q)\\n - [context\u4f7f\u7528\u4e0d\u5f53\u5f15\u53d1\u7684\u4e00\u4e2abug](https://mp.weixin.qq.com/s/lJxjlDg5SkQyNLZBpOPP5A)\\n - [Go\u8bed\u8a00\u5982\u4f55\u5b9e\u73b0\u53ef\u91cd\u5165\u9501](https://mp.weixin.qq.com/s/S_EzyWZmFzzbBbxoSNe6Hw)\\n - [\u5982\u4f55\u5728\u6d4b\u8bd5\u4e2d\u53d1\u73b0goroutine\u6cc4\u6f0f](https://mp.weixin.qq.com/s/zlqZ-4EdzMNt3iubMknKLA)\\n - [\u8bf7\u52ff\u6ee5\u7528goroutine](https://mp.weixin.qq.com/s/JC14dWffHub0nfPlPipsHQ)\\n - [\u9762\u8bd5\u5b98\uff1a\u54e5\u4eecGo\u8bed\u8a00\u4e92\u65a5\u9501\u4e86\u89e3\u5230\u4ec0\u4e48\u7a0b\u5ea6\u4e86](https://mp.weixin.qq.com/s/bhze_LcFHk7Y-QB4nEQKnA)\\n - [Go\u5de5\u5177\u4e4bgenerate](https://mp.weixin.qq.com/s/E45dNnEURe87P709Ovu-Qw)\\n - [\u63a2\u7a76 Go \u6e90\u7801\u4e2d panic & recover \u6709\u54ea\u4e9b\u5751](https://mp.weixin.qq.com/s/dN9G4Tnt9HgVqlNh73HNUQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#41 substrings and memory leaks](https://mp.weixin.qq.com/s/Wdh2O4cnez95x0RBpMiDvQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#38 Misusing trim functions](https://mp.weixin.qq.com/s/39S-WWKt1rYNF9OUfFSCbw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#37 Inaccurate string iteration](https://mp.weixin.qq.com/s/m0WyJyd2JwQfX1SP2H-jrA)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#36 Not understanding the concept of a rune](https://mp.weixin.qq.com/s/P6rEyeLvl8gxT_4RJf235Q)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#35 Using defer inside a loop](https://mp.weixin.qq.com/s/Ls1_qaEnuc8MSZoDyTwa1Q)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#34 Ignoring how the break statement works](https://mp.weixin.qq.com/s/XRQq1O9VROBxItSP4kC8zA)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#33 Making wrong assumptions during map iterations](https://mp.weixin.qq.com/s/gwsWE-NTBOs0NnsdNG4WBw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#32 Ignoring the impact of using pointer ...](https://mp.weixin.qq.com/s/58EVYGZ02xPfGYrprk7dRw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#31 Ignoring how arguments are evaluated in ...](https://mp.weixin.qq.com/s/cuJAYXGOleUt0FG5brX8ng)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#30 Ignoring the fact that elements are copied](https://mp.weixin.qq.com/s/71wpR1kz5PgzVNBgpN855g)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#29 Comparing values incorrectly](https://mp.weixin.qq.com/s/fpHMk37QGLQCXrPAdxXC_w)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#28 maps and memory leaks](https://mp.weixin.qq.com/s/s5-Pl5u6yoZCPWwoeINs9g)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#27 Inefficient map initialization](https://mp.weixin.qq.com/s/9pfznxXKHCv-QEZBqHw1YQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#26 slices and memory leaks](https://mp.weixin.qq.com/s/TYxqo1BniI-wfKVHQsrjjw)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#25 Unexpected side effects using slice append](https://mp.weixin.qq.com/s/lAIB0l666R6Zh9NAdV809g)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#24 Not making slice copies correctly](https://mp.weixin.qq.com/s/vZBePdCuKe12OMQOj6Rz4A)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#23 Not properly checking if a slice is empty](https://mp.weixin.qq.com/s/WsFGv9tcdRLP9K-NQSqimA)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#22 Being confused about nil vs. empty slices](https://mp.weixin.qq.com/s/uHmCU0v0xJ2RYlmq_lQAiQ)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#20 Not understanding slice length and capacity](https://mp.weixin.qq.com/s/-Kt2QJdzEUDJx8MFvrUo7Q)\\n - [Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#12 Project misorganization](https://mp.weixin.qq.com/s/epK_0yn_EPIWJjz9xmddcA)\\n - [100 Go Mistakes and How to Avoid Them](https://github.com/teivah/100-go-mistakes)\\n - [Go \u4e2d\u57fa\u4e8e IP \u5730\u5740\u7684 HTTP \u8bf7\u6c42\u9650\u6d41](https://mp.weixin.qq.com/s/aj_hULmeqy3whILr2ytECQ)\\n - [\u9879\u76ee\u5b9e\u6218\uff1a\u7528 Go \u521b\u5efa\u4e00\u4e2a\u7b80\u6613\u8d1f\u8f7d\u5747\u8861\u5668](https://mp.weixin.qq.com/s/pe0CQa3tdrUmC86OSRBNeg)\\n - [\u4f60\u77e5\u9053\u51e0\u79cdGo\u5e76\u53d1\u63a7\u5236\u65b9\u5f0f](https://mp.weixin.qq.com/s/tloEYzrnKNrrAo1YKdeyrw)\\n - [\u6d45\u8c08Golang\u4e24\u79cd\u7ebf\u7a0b\u5b89\u5168\u7684map](https://mp.weixin.qq.com/s/H5HDrwhxZ_4v6Vf5xXUsIg)\\n - [Go\u7cbe\u5999\u7684\u4e92\u65a5\u9501\u8bbe\u8ba1](https://mp.weixin.qq.com/s/YYvoeDfPMm8Y2kFu9uesGw)\\n - [Go\u66f4\u7ec6\u7c92\u5ea6\u7684\u8bfb\u5199\u9501\u8bbe\u8ba1](https://mp.weixin.qq.com/s/CEIQUa7H43FR7M1ghkDSGg)\\n - [Go \u7684 TryLock \u5b9e\u73b0](https://mp.weixin.qq.com/s/Mro5XC8dS5ZAMvEVbJZsCw)\\n - [Go1.18 \u65b0\u7279\u6027\uff1aTryLock \u662f\u4ec0\u4e48\uff1f\u9700\u8981\u5b83\u5417](https://mp.weixin.qq.com/s/oA6UJ-0R2OucFl-fbgrvWA)\\n - [Go\u4e2d\u770b\u4f3c\u7b80\u5355\u7684WaitGroup\u6e90\u7801\u8bbe\u8ba1\uff0c\u7adf\u7136\u6697\u542b\u8fd9\u4e48\u591a\u77e5\u8bc6](https://mp.weixin.qq.com/s/V2x0Nw3Y8lZxHYJh_yQ0dQ)\\n - [Go \u6807\u51c6\u5e93\u6e90\u7801\u5b66\u4e60\uff08\u4e00\uff09\u8be6\u89e3\u77ed\u5c0f\u7cbe\u608d\u7684 Once](https://mp.weixin.qq.com/s/Lsm-BMdKCKNQjRndNCLwLw)\\n - [Go \u4e2d\u4e3a\u4ec0\u4e48\u5efa\u8bae\u4f7f\u7528 NewXxx \u8fd9\u6837\u7684\u6784\u9020\u51fd\u6570](https://mp.weixin.qq.com/s/3VkcIg7NhCCiIwVRjuwR0A)\\n - [Uber Go\u8bed\u8a00\u7f16\u7801\u89c4\u8303](https://mp.weixin.qq.com/s/nA26g46tM_hu-khaGYniAQ)\\n - [\u600e\u4e48\u9009\u62e9 Go \u6587\u4ef6\u8bfb\u53d6\u65b9\u6848](https://mp.weixin.qq.com/s/KHzdEE_w_ev9p4v6MR7M8Q)\\n - [\u5982\u4f55\u6709\u6548\u63a7\u5236 Go \u7ebf\u7a0b\u6570](https://mp.weixin.qq.com/s/EeOxPkTe8WkOide49yIfEg)\\n - [\u52a0\u5927\u529b\u5ea6\uff01Go \u5c06\u4f1a\u589e\u5f3a Go1 \u5411\u540e\u517c\u5bb9\u6027](https://mp.weixin.qq.com/s/OIqgqjXEvVmDUmnRqq4PGw)\\n - [Go \u7684\u96f6\u503c\u6709\u4ec0\u4e48\u7528\uff1f\u770b\u770b\u8fd9 4 \u4e2a\u573a\u666f](https://mp.weixin.qq.com/s/Ucqqg4h9uRo7RVd8XCz80w)\\n - [Go \u53ea\u4f1a if err != nil\uff1f\u8fd9\u662f\u4e0d\u5bf9\u7684\uff0c\u5206\u4eab\u8fd9\u4e9b\u4f18\u96c5\u7684\u5904\u7406\u59ff\u52bf\u7ed9\u4f60\uff01](https://mp.weixin.qq.com/s/L_Sy4_6BURL4XWDK6bpEwg)\\n - [10+ \u6761 Go \u5b98\u65b9\u8c1a\u8bed\uff0c\u4f60\u77e5\u9053\u51e0\u6761\uff1f](https://mp.weixin.qq.com/s/cJON1H68eBFeuBpWhFbXXw)\\n - [Go \u9002\u5408 IO \u5bc6\u96c6\u578b\uff1f\u5e76\u4e0d\u51c6\u786e\uff01](https://mp.weixin.qq.com/s/xDXwsVjOfU2j3gisiHTZTQ)\\n - [\u5982\u4f55\u8ba9 Go \u53cd\u5c04\u53d8\u5feb](https://mp.weixin.qq.com/s/fzmN6zFVioQGedTdSDmyqQ)\\n - [\u6df1\u5165\u7406\u89e3StatefulSet\uff0c\u7528Kubernetes\u7f16\u6392\u6709\u72b6\u6001\u5e94\u7528](https://mp.weixin.qq.com/s/y60q0-RMh8isd4u4PuLfUg)\\n - [Go Modules \u7ec8\u6781\u5165\u95e8](https://juejin.cn/post/6844903433846145038)\\n - [\u975e\u5e38\u9002\u5408PHP\u540c\u5b66\u4f7f\u7528\u7684GO\u6846\u67b6\uff1aGoFrame](https://juejin.cn/post/7075098594151235597)\\n - [\u770b Go \u4e2d\u7684 struct \u5982\u4f55\u88ab\u4f18\u5316\uff0c\u8fd8\u6709\u5c0f\u63d2\u66f2](https://mp.weixin.qq.com/s/EGN7G8ku-zkaZuzfBwx9Qw)\\n - [\u5728 Go \u91cc\u7528 CGO\uff1f\u8fd9 7 \u4e2a\u95ee\u9898\u4f60\u8981\u5173\u6ce8\uff01](https://mp.weixin.qq.com/s/Qlqt1pP_Li-PxOICrz7bAw)\\n - [Go \u63a2\u8ba8\u4e86 13 \u5e74\uff0c\u600e\u4e48\u89e3\u51b3\u518d\u8d4b\u503c\u7684\u5751](https://mp.weixin.qq.com/s/Am0ORd08GsMc4xSdLG9kgg)\\n - [Go\u5982\u4f55\u4f18\u96c5\u7684\u8bb0\u5f55\u64cd\u4f5c\u65e5\u5fd7 | \u51b2\u523a\u6398\u91d1\u4e00\u5468](https://juejin.cn/post/7134497015576133669)\\n - [\u5982\u4f55\u66f4\u76f4\u89c2\u5730\u7406\u89e3 Go \u8c03\u5ea6\u8fc7\u7a0b](https://mp.weixin.qq.com/s/0c7emt54ayCrm1K16lk2SQ)\\n - [Go1.19 \u90a3\u4e9b\u4f60\u4e0d\u77e5\u9053\u7684\u65b0\u7279\u6027](https://mp.weixin.qq.com/s/FviFOLkIHuEjZdTg_qCoNQ)\\n - [Go \u4e2d\u53ef\u522b\u7528\u590d\u5236\u9501\uff0c\u4f1a\u6709\u8fd9\u4e9b\u5927\u95ee\u9898\uff01](https://mp.weixin.qq.com/s/SrqJdng9cNUEVAS7nFaqAA)\\n - [\u4f19\u8ba1\uff0cGo\u9879\u76ee\u600e\u4e48\u4f7f\u7528\u679a\u4e3e](https://mp.weixin.qq.com/s/zyvO_hhUo1TRm6kMPcaFFQ)\\n - [Go ORM \u5355\u5143\u6d4b\u8bd5\u5168\u6d41\u7a0b\u8bb2\u89e3](https://mp.weixin.qq.com/s/XPPwHd7eDUjvzsnuFwgbyw)\\n - [\u8d85\u5168\u603b\u7ed3\uff1aGo\u8bed\u8a00\u5982\u4f55\u64cd\u4f5c\u6587\u4ef6](https://mp.weixin.qq.com/s/r30z2i_sSuRfEnM_23wFlg)\\n - [Go \u7684\u65f6\u95f4\u8f6c\u6362\u548c\u65f6\u533a\u6821\u5bf9\u603b\u8bb0\u4e0d\u4f4f\uff1f\u7ed9\u4f60\u4e00\u4efd\u5907\u5fd8\u5355](https://mp.weixin.qq.com/s/HaF9qieEJWNUoyY9qTvnKw)\\n - [\u641e\u6e05\u695a Go Mod\u7684\u7248\u672c\u548c\u4f2a\u7248\u672c\uff0c\u4e0b\u6b21\u522b\u4e71\u7528\u4e86](https://mp.weixin.qq.com/s/ptJK7CDHCr6P4JCdsUXKdg)\\n - [\u81ea\u5df1\u7684\u9879\u76ee\uff0c\u5982\u4f55\u53d1\u5e03\u5230Go Module\u4e0a](https://mp.weixin.qq.com/s/7jLmwtP3xk-wbCFKqPLK2g)\\n - [\u8fd9\u4e0d\u4f1a\u53c8\u662f\u4e00\u4e2aGo\u7684BUG\u5427](https://mp.weixin.qq.com/s/Dn2oM89mHEgoz8yVQnNEoQ)\\n - [\u8fd9\u4e09\u4e2a Go \u6c34\u5e73\u81ea\u6d4b\u9898\uff0c\u624b\u5199\u4e0d\u51fa\u6765\u8fd8\u662f\u5148\u8001\u5b9e\u4e0a\u73ed\u5427](https://mp.weixin.qq.com/s/YojNHW7kkjmmdjqBXCuQYA)\\n - [\u4e0d\u60f3Go \u9519\u8bef\u5904\u7406\u592a\u81c3\u80bf\uff0c\u53ef\u4ee5\u53c2\u8003\u8fd9\u4e2a\u4ee3\u7801\u8bbe\u8ba1](https://mp.weixin.qq.com/s/pR_XHTnhft2Hi_mY7JuEJg)\\n - [\u5173\u4e8eGo\u7a0b\u5e8f\u9519\u8bef\u5904\u7406\u7684\u4e00\u4e9b\u5efa\u8bae](https://mp.weixin.qq.com/s/HuZn9hnHUBx3J4bAGYBYpw)\\n- Golang \u90e8\u7f72\\n - \u4f7f\u7528 Docker Desktop \u642d\u5efa k8s \u96c6\u7fa4\\n - [\u5929\u5450\uff01\u6211\u7528 go \u4ece\u96f6\u5f00\u59cb\u5199\u4e86\u4e00\u4e2a k8s \u5e94\u7528\u7ba1\u7406\u5de5\u5177\uff08\u9644\u5b8c\u6574\u4ee3\u7801\u548c\u5f00\u53d1\u8fc7\u7a0b\uff09](https://mp.weixin.qq.com/s/MFd1R5VeEW0eLk-A4BqSQQ)\\n - [Go \u8bed\u8a00 Web \u5e94\u7528\u600e\u4e48\u4f7f\u7528 Nginx \u90e8\u7f72](https://mp.weixin.qq.com/s/Rrz-UEx2SwYmyWC5rKh4Wg)\\n - [\u638c\u63e1\u4e86\u8fd9\u7bc7 Dockerfile \u4e2d\u7684 ARG \u4f5c\u7528\u57df\uff0c \u5c31\u7b97 Build \u955c\u50cf CI \u5165\u95e8\u4e86 \u3010\u6587\u672b\u62bd\u5956\u3011](https://mp.weixin.qq.com/s/i3n0hoHRaYoDMWcC5DSQ3w)\\n - [\u9762\u8bd5\u95ee Dockerfile \u7684\u4f18\u5316\uff0c \u5343\u4e07\u4e0d\u8981\u53ea\u4f1a\u8bf4\u51cf\u5c11\u5c42\u6570](https://mp.weixin.qq.com/s/pen6G2aFsPfSqhKjgocVjQ)\\n - [\u6ca1\u60f3\u5230\u5728 Docker \u5bb9\u5668\u4e2d\u8bbe\u7f6e\u65f6\u533a\u8fd9\u4e48\u7b80\u5355](https://mp.weixin.qq.com/s/10Ll8ipVGWg4HU4hjwILsQ)\\n - [\u5feb\u6536\u85cf\uff01\u8d85\u5f3a\u56fe\u89e3Docker\u5e38\u89c1\u547d\u4ee4\u4e0e\u5b9e\u6218\uff01](https://mp.weixin.qq.com/s/5NTgcdhn6CiZ2tg44_T-FQ)\\n - [\u5b9e\u65f6\u53ef\u89c6\u5316Go Runtime\u6307\u6807\uff0c\u8fd9\u4e2aGo\u5e93\u8d85\u8d5e](https://mp.weixin.qq.com/s/rDSKItZ8hvgjvpp4f4VzCQ)\\n - [\u4e3b\u6d41\u76d1\u63a7\u7cfb\u7edf\u6280\u672f\u9009\u578b\uff0cyyds\uff01](https://mp.weixin.qq.com/s/GfJqTG9XYx58eh5kImyeWg)\\n - [\u4eceGo\u7a0b\u5e8f\u7b2c\u4e00\u884c\u4ee3\u7801\uff0c\u5230\u5728 K8s \u4e0a\u8fd0\u884c\uff0c\u8981\u7ecf\u5386\u591a\u5c11\u6b65](https://mp.weixin.qq.com/s/DEZPCzQul7wnZKqm1Ue6rg)\\n - [\u5728K8S\u4e0a\u7684Web\u670d\u52a1\u8be5\u600e\u4e48\u505a\u57df\u540d\u89e3\u6790\u5462](https://mp.weixin.qq.com/s/ZU61NIMxh_UOo-chNvkPXA)\\n - https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/\\n - [Kubernetes\u5165\u95e8\u5b9e\u8df5--\u90e8\u7f72\u8fd0\u884cGo\u9879\u76ee](https://mp.weixin.qq.com/s/uruu3qbpSLbTRJJRcWTYqg)\\n - [\u7ebf\u4e0aGo\u9879\u76ee\u7684Docker\u955c\u50cf\u5e94\u8be5\u600e\u4e48\u6784\u5efa](https://mp.weixin.qq.com/s/hoJgL-sP2OtMEFAhYNCItA)\\n - [Docker \u5b66\u4e60\u7b14\u8bb0](https://blog.opskumu.com/docker.html)\\n - [\u7a0b\u5e8f\u89e3Bug\u6700\u5e38\u7528\u7684K8s\u547d\u4ee4\uff0c\u5916\u52a0\u4f7f\u7528\u7a8d\u95e8](https://mp.weixin.qq.com/s/Ze096f0Utcl84c6gBwrCYw)\\n- Golang \u5f00\u6e90\u5e93\u63a8\u8350\\n - \u2b50\ufe0f \u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5\\n - [HTTP \u6846\u67b6 Hertz \u5b9e\u8df5\u5165\u95e8\uff1a\u6027\u80fd\u6d4b\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/J6ziP7VOitGk-lz8NGdDrA)\\n - [\u5b57\u8282\u5f00\u6e90WEB\u6846\u67b6Hertz\u592a\u9999\u5566\uff01](https://juejin.cn/post/7124337913352945672)\\n - [\u5b57\u8282\u8df3\u52a8\u5927\u89c4\u6a21\u4f01\u4e1a\u7ea7 HTTP \u6846\u67b6 Hertz \u8bbe\u8ba1\u5b9e\u8df5](https://juejin.cn/post/7153889167385526308)\\n - https://github.com/cloudwego/hertz\\n - [ByteDance Practices on Go Network Library](https://www.cloudwego.io/blog/2021/10/09/bytedance-practices-on-go-network-library/)\\n - https://www.cloudwego.io/docs/hertz/getting-started/\\n - [Go \u8bed\u8a00\u7ec8\u6781\u641c\u7d22\u63d2\u4ef6](https://mp.weixin.qq.com/s/025-MLMAbdT38kWI--AoYg)\\n - [\u300cGo\u5f00\u6e90\u5305\u300dsnappy\uff1agoogle\u5f00\u6e90\u7684\u5feb\u901f\u3001\u65e0\u635f\u538b\u7f29\u5305](https://mp.weixin.qq.com/s/ie7LqXZQOUX0Bfn4QhHzLA)\\n - [\u300cGo\u5f00\u6e90\u5305\u300dxxhash\uff1a\u6bd4\u6807\u51c6\u5e93\u66f4\u5feb\uff0c\u57fa\u4e8exxHash\u7b97\u6cd5\u5b9e\u73b0\u768464\u4f4d\u7684\u6574\u578bhash\u503c](https://mp.weixin.qq.com/s/Vkx8zzm1SjIl4IXLib3xkQ)\\n - [\u300cGo\u5f00\u6e90\u5305\u300denv\uff1a\u4e00\u4e2a\u5c06\u7cfb\u7edf\u73af\u5883\u53d8\u91cf\u89e3\u6790\u5230\u7ed3\u6784\u4f53\u7684\u5e93](https://mp.weixin.qq.com/s/xt0v6snX6y5jaOy1IniwVw)\\n - \u2b50\ufe0f [\u300cGo\u5f00\u6e90\u5305\u300dchromedp\uff1a\u4e00\u4e2a\u57fa\u4e8eChrome DevTools\u534f\u8bae\u7684\u5e93\uff0c\u652f\u6301\u6570\u636e\u91c7\u96c6\u3001\u622a\u53d6\u7f51\u9875\u957f\u56fe](https://mp.weixin.qq.com/s/rGPsEt-XDOayDWwLGxvcsw)\\n - \u2b50\ufe0f [\u300cGo\u5f00\u6e90\u5305\u300dnunu\uff1a\u4e00\u4e2a\u5feb\u901f\u6784\u5efa\u5e94\u7528\u7a0b\u5e8f\u7684\u811a\u624b\u67b6](https://juejin.cn/post/7248951438742339639)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Shopify \u51fa\u54c1\u7684\u5b8c\u6574\u5ea6\u6700\u5b8c\u5584\u7684 Kafka \u5ba2\u6237\u7aef_sarama](https://mp.weixin.qq.com/s/_TBmfaVwvX5VDRe8kLReXA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300dGolang\u7684Ealstic\u94fe\u63a5\u5e93](https://mp.weixin.qq.com/s/iHIxsEZf3w06GbO2sHSuRA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u534f\u7a0b\u6c60ants\u4ecb\u7ecd](https://mp.weixin.qq.com/s/wGqwfX8lEifeD_VGcITmHw)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528 cmux \u5b9e\u73b0\u670d\u52a1\u7aef\u8fde\u63a5\u591a\u8def\u590d\u7528](https://mp.weixin.qq.com/s/2cERDCRKlmfHKv8gY324Hg)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4f7f\u7528GO\u8bed\u8a00\u542f\u52a8docker Container](https://mp.weixin.qq.com/s/dkbpIvy1o5aLnklt0ddIDA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u62bd\u8c61\u8bed\u6cd5\u6811go/ast\u5e93\u4f7f\u7528](https://mp.weixin.qq.com/s/uLpmEV8mI4JpfNVfSK8cRQ)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u4e07\u80fd\u7684\u5bf9\u8c61\u62f7\u8d1d\u5de5\u5177\u2014\u2014Copier](https://mp.weixin.qq.com/s/weT4KUTTLWdQaC6q7VrPPg)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u6f0f\u6876\u9650\u6d41\u5e93 \u2014 uber-go/ratelimit](https://mp.weixin.qq.com/s/q3wRIvoXpnPLPJsDAPTdeA)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u65f6\u95f4\u8f6e\u7b97\u6cd5\u5b9a\u65f6\u5668antlabs/timer\u4ecb\u7ecd](https://mp.weixin.qq.com/s/emNifkcdn9oRjVHRcQmK9w)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Goroutine \u6cc4\u6f0f\u9632\u6cbb\u795e\u5668 goleak](https://mp.weixin.qq.com/s/3iPqxiK2mf9Fl5CSZ9U7RQ)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011\u5f02\u6b65\u4efb\u52a1\u961f\u5217Asynq](https://mp.weixin.qq.com/s/SWyMIE1rtVDVUPEFno4xsQ)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011protobuf\u751f\u6210Go\u4ee3\u7801\u63d2\u4ef6gogo/protobuf](https://mp.weixin.qq.com/s/X6Fo_6pEZTIZJ-1MJNrg6A)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Golang\u5b98\u65b9\u8ba4\u53ef\u7684websocket\u5e93-gorilla/websocket](https://mp.weixin.qq.com/s/ZoVr9ubPgcvjX9ERiQoLyA)\\n - \u2b50\ufe0f [\u3010GoCN\u9177Go\u63a8\u8350\u3011Html\u89e3\u6790\u5229\u5668-goquery\u5e93](https://mp.weixin.qq.com/s/JrEQwQZQRwf4SymprwKUmw)\\n - \u2b50\ufe0f [\u300cGoCN\u9177Go\u63a8\u8350\u300d\u9ad8\u6027\u80fd\u4e2d\u6587\u5206\u8bcd\u5e93 gojieba](https://mp.weixin.qq.com/s/zRmAjQ0o9n8FE1R0WcnUtQ)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u89e3\u6790http\u4e2d\u7684user-agent\uff0c\u5c31\u7528\u8fd9\u4e2a\u5305\uff1auser_agent](https://mp.weixin.qq.com/s/8YRqypiW1dQQVlZkmCd1mQ)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u63a8\u8350\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u3001\u8bed\u4e49\u5316\u7684\u65f6\u95f4\u5904\u7406\u5e93\uff1acarbon](https://mp.weixin.qq.com/s/92O1SHs4tw1FMcDeQoSfkA)\\n - [Go\u6bcf\u65e5\u4e00\u5e93\u4e4bCSRF\u5e93\u7684\u4f7f\u7528\u65b9\u5f0f\u548c\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/n-kU6nwhOH6ouhufrP_1kQ)\\n - [Go \u6bcf\u65e5\u4e00\u5e93\u4e4b go-cache \u7f13\u5b58](https://mp.weixin.qq.com/s/f4FAt-RgraOFXSfZmWjeoQ)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300dredis\u5b98\u7f51\u63a8\u8350\u7684go\u7248\u672c\u7684\u5206\u5e03\u5f0f\u9501\uff1aredsync](https://mp.weixin.qq.com/s/KCj-mCkZpcEu3GXkuRLTuA)\\n - https://github.com/samber/lo\\n - https://github.com/nikoksr/notify\\n - https://github.com/go-chi/chi\\n - https://github.com/gin-gonic/examples\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u91cd\u78c5\u63a8\u8350\uff1a\u4e00\u4e2a\u56fd\u4ea7\u7684\uff0cstar\u9ad8\u8fbe12k+\u7684\u64cd\u4f5cexcel\u7684\u5305\uff1aExcelize](https://mp.weixin.qq.com/s/zLNwq32UKaCsaAXn2BaZkw)\\n - [\u300cGo\u5de5\u5177\u7bb1\u300d\u4e00\u4e2a\u8ba9\u7ec8\u7aef\u5185\u5bb9\u5f69\u8272\u5316\u7684\u5de5\u5177\uff1aColor](https://mp.weixin.qq.com/s/Y3NGQH3hrT85O7aN7IrCIQ)\\n- Golang \u76f8\u5173\u8d44\u6e90\\n - \ud83c\udf1f [Russ Cox \u7684\u4e2a\u4eba\u535a\u5ba2](https://research.swtch.com/)\\n - \ud83c\udf1f [Tony Bai \u535a\u5ba2](https://tonybai.com/articles/)\\n - \ud83c\udf1f [Gopher Daily](https://gopherdaily.tonybai.com/)\\n - \ud83c\udf1f [ChatGPT \u4e0e\u6211\u5408\u529b\u5f00\u53d1 xargin blog archive \u63d2\u4ef6\uff1a\u66f9\u5927\u535a\u5ba2\u7684\u65b0\u5947\u63a2\u9669](https://xargin.com/)\\n - \ud83c\udf1f [qcrao \u7684\u535a\u5ba2](https://qcrao.com/)\\n - \ud83c\udf1f [Go \u7a0b\u5e8f\u5458\u9762\u8bd5\u7b14\u8bd5\u5b9d\u5178](https://github.com/golang-design/go-questions)\\n - \ud83c\udf1f [Go\u8bed\u8a00\u5723\u7ecf\uff08\u4e2d\u6587\u7248\uff09](https://books.studygolang.com/gopl-zh/)\\n - \ud83c\udf1f [Go\u8bed\u8a00\u6807\u51c6\u5e93\u4e66\u7c4d](http://books.studygolang.com/The-Golang-Standard-Library-by-Example/)\\n - \ud83c\udf1f [\u5730\u9f20\u6587\u6863](https://www.topgoer.cn/)\\n - \ud83c\udf1f [go\u8bed\u8a00\u4e2d\u6587\u6587\u6863 - \u5730\u9f20\u6587\u6863](https://www.topgoer.cn/docs/golang/golang-1ccjbpfstsfi1)\\n - \ud83c\udf1f [Go \u5b98\u65b9\u8c1a\u8bed Go Proverbs](https://go-proverbs.github.io/)\\n - [GoLand 2023.2 \u53d1\u5e03\uff1a\u6709 AI \u52a9\u624b](https://mp.weixin.qq.com/s/cidtQEAfuFWuYveKFbFvKQ)\\n - [GoLand 2023.1 \u6b63\u5f0f\u53d1\u5e03\uff0c\u770b\u6709\u54ea\u4e9b\u65b0\u529f\u80fd](https://mp.weixin.qq.com/s/SVMj-PvI1l-oSlxI4zaNcw)\\n - [GoLand \u8fce\u6765\u4e94\u5468\u5e74\uff0c\u540c\u65f6\u53d1\u5e03 2022.3\uff1a\u6709\u5f69\u86cb](https://mp.weixin.qq.com/s/IvL24_7iuuRp9Y3dljHaHQ)\\n - \ud83c\udf1f [\u8fd9\u53ef\u80fd\u662f\u6700\u6743\u5a01\u3001\u6700\u5168\u9762\u7684Go\u8bed\u8a00\u7f16\u7801\u98ce\u683c\u89c4\u8303\u4e86\uff01](https://mp.weixin.qq.com/s/jrua9iSa1Huk3UvMluVe7w)\\n - [\u6210\u4e3a Go \u9ad8\u624b\u7684 8 \u4e2a GitHub \u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/2qPeqi3qdk4sqtpqo-3_Uw)\\n - [golang-developer-roadmap: 2020 \u5e74\u6210\u4e3a Go \u5f00\u53d1\u8005\u7684\u8def\u7ebf\u56fe](https://github.com/Alikhll/golang-developer-roadmap)\\n - [go-admin: \u57fa\u4e8e Gin + Vue + Element UI \u7684\u72ec\u7acb\u524d\u540e\u7aef\u6743\u9650\u7ba1\u7406\u7cfb\u7edf\u7684\u811a\u624b\u67b6](https://github.com/go-admin-team/go-admin)\\n - [awesome-go: \u7cbe\u9009\u7684 Go \u6846\u67b6\u3001\u5e93\u548c\u8f6f\u4ef6\u7684\u5217\u8868](https://github.com/avelino/awesome-go)\\n - [Go 13 \u5468\u5e74\u5566\uff01](https://mp.weixin.qq.com/s/wKxg6IVZCNK3NG2Os9_3jg)\\n - [\u7ed9\uff0c\u4f60\u8981\u7684Go\u5b66\u4e60\u8def\u7ebf\u56fe\u6765\u5566](https://mp.weixin.qq.com/s/rPKO23mHDGofeyzeCIHJxQ)\\n - \ud83c\udf1f [Golang By Example](https://golangbyexample.com/)\\n - [Golang Advanced Tutorial](https://golangbyexample.com/golang-comprehensive-tutorial/)\\n - [All Design Patterns in Go (Golang)](https://golangbyexample.com/all-design-patterns-golang/)\\n - [System Design Questions](https://techbyexample.com/system-design-questions/)\\n - [SOLID Go Design - Go\u8bed\u8a00\u9762\u5411\u5bf9\u8c61\u8bbe\u8ba1](https://blog.gokit.info/post/go-solid-design/)\\n - [go design pattern](https://github.com/mohuishou/go-design-pattern)\\n - [\u4e07\u5b57\u8be6\u6587\u9610\u91ca\u7a0b\u5e8f\u5458\u4fee\u70bc\u4e4b\u9053](https://mp.weixin.qq.com/s/XIwfj_AdZqX_vHM4VIq9EA)\\n - [\u4e07\u5b57\u8be6\u6587\u544a\u8bc9\u4f60\u5982\u4f55\u505a Code Review](https://mp.weixin.qq.com/s/c3RApB8a98tWahgC9mahJg)\\n - [Go \u5b66\u4e60\u4e4b\u8def](https://github.com/talkgo/read)\\n - [1024\uff0c\u6211\u4eec\u7684\u8282\u65e5\uff0cGopher \u8be5\u5e72\u70b9\u5565](https://mp.weixin.qq.com/s/ipbUy3GBRMFat9jUSssMMw)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u5b66\u4e60\u7b14\u8bb0](https://www.yuque.com/qyuhen/go)\\n - \ud83c\udf1f [GO\u4e13\u5bb6\u7f16\u7a0b](https://books.studygolang.com/GoExpertProgramming/)\\n - \ud83c\udf1f [Go \u8bed\u8a00 101](https://go101.org/article/101.html)\\n - \ud83c\udf1f [Go Optimizations 101](https://go101.org/optimizations/101.html)\\n - [\u5f00\u6e90\u56fe\u4e66\u5728\u7ebf\u9605\u8bfb - Go\u8bed\u8a00\u4e2d\u6587\u7f51](https://books.studygolang.com/)\\n - \ud83c\udf1f [Go Interview](https://www.yuque.com/go-interview/set/xq5788)\\n - \ud83c\udf1f [LeetCode Cookbook](https://github.com/halfrost/LeetCode-Go)\\n - \ud83c\udf1f [LeetCode Cookbook\uff08\u5728\u7ebf\u9605\u8bfb\uff09](https://books.halfrost.com/leetcode/)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://draveness.me/golang/docs/part1-prerequisite/ch02-compile/golang-compile-intro/)\\n - \ud83c\udf1f [Go\u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b(Advanced Go Programming)](https://books.studygolang.com/advanced-go-programming-book/)\\n - [Go \u8bed\u8a00\u9ad8\u6027\u80fd\u7f16\u7a0b](https://github.com/geektutu/high-performance-go)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u539f\u672c](https://github.com/golang-design/under-the-hood)\\n - \ud83c\udf1f [Go \u8bed\u8a00\u539f\u672c\uff08\u5728\u7ebf\u9605\u8bfb\uff09](https://golang.design/under-the-hood/)\\n - \ud83c\udf1f [Tony Bai \xb7 Go \u8bed\u8a00\u7b2c\u4e00\u8bfe](https://time.geekbang.org/column/intro/100093501)\\n - \ud83c\udf1f [Go \u5e76\u53d1\u7f16\u7a0b\u5b9e\u6218\u8bfe](https://time.geekbang.org/column/intro/100061801)\\n - \ud83c\udf1f [Rust \u7f16\u7a0b\u7b2c\u4e00\u8bfe](https://time.geekbang.org/column/article/408409)\\n - \ud83c\udf1f [Go cheatsheet](https://quickref.me/go)\\n - \ud83c\udf1f [Golang for Node.js Developers](https://github.com/miguelmota/golang-for-nodejs-developers)\\n - \ud83c\udf1f [Learn Go with tests](https://studygolang.gitbook.io/learn-go-with-tests)\\n - \ud83c\udf1f [golang \u7f16\u7a0b\u89c4\u8303 - \u9879\u76ee\u76ee\u5f55\u7ed3\u6784](https://makeoptim.com/golang/standards/project-layout)\\n - [Go \u591c\u8bfb](https://github.com/talkgo/night)\\n - [\u5df2\u5165\u5b57\u8282\u7684\u5927\u4f6c\u5404\u5382\u4e09\u5e74Go\u9762\u7ecf](https://mp.weixin.qq.com/s/VKPSqS50Un29x30KIgB0tA)\\n- Golang \u7b97\u6cd5\\n - https://github.com/fangbinwei/algorithm-practice\\n- Golang \u9879\u76ee\u53c2\u8003\\n - https://github.com/wangzhongyang007/goframe-shop-v2\\n - https://github.com/fangbinwei/aliyun-oss-website-action\\n- Golang \u6559\u7a0b\\n - https://www.w3cschool.cn/go/\\n- Golang \u6807\u51c6\u5e93\u6587\u6863\\n - https://pkg.go.dev/std\\n- Golang \u5355\u5143\u6d4b\u8bd5\\n - [Golang-\u5355\u5143\u6d4b\u8bd5](https://blog.csdn.net/ALEX_CYL/article/details/121793330)\\n - [\u624b\u628a\u624b\u6559\u4f60\u5982\u4f55\u8fdb\u884c Golang \u5355\u5143\u6d4b\u8bd5](https://zhuanlan.zhihu.com/p/377834750)\\n- \u2b50\ufe0f [Go \u8bed\u8a00\u4e0e\u5e76\u53d1\u7f16\u7a0b](https://zhuanlan.zhihu.com/p/471317280)\\n- \u2b50\ufe0f [Golang \u7b80\u6d01\u67b6\u6784\u5b9e\u6218](https://mp.weixin.qq.com/s/Xzlt_WcdcfLWhofafY3c6g)\\n- \u2b50\ufe0f [\u5982\u4f55\u4f7f\u7528\u9ad8\u9636\u51fd\u6570\u7f16\u7a0b\u63d0\u5347\u4ee3\u7801\u7684\u7b80\u6d01\u6027](https://juejin.cn/post/7065197280223035422)\\n- \ud83c\udf1b [\u6df1\u5165\u7406\u89e3Go Json.Unmarshal\u7cbe\u5ea6\u4e22\u5931\u4e4b\u8c1c](https://mp.weixin.qq.com/s/36CqC1U54LUd4-izt4iZ1g)\\n- [Go Error \u5904\u7406\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/EvkMQCPwg-B0fZonpwXodg)\\n- [Golang \u65b0\u624b\u53ef\u80fd\u4f1a\u8e29\u7684 50 \u4e2a\u5751](https://segmentfault.com/a/1190000013739000)\\n- [Golang\u8bbe\u8ba1\u6a21\u5f0f\u603b\u7ed3](https://zhuanlan.zhihu.com/p/437626980)\\n- [Golang \u5355\u5143\u6d4b\u8bd5\u6307\u5f15](https://zhuanlan.zhihu.com/p/267341653)\\n- \u2b50\ufe0f [\u4f7f\u7528Golang\u3001Gin\u548cReact\u3001esbuild\u5f00\u53d1\u7684Blog](https://juejin.cn/post/7041846339189080101)\\n- \u2b50\ufe0f [gorm - Golang \u7684\u51fa\u8272 ORM \u5e93](https://github.com/go-gorm/gorm)\\n- \u2b50\ufe0f [fiber\uff1a\u53d7\u5230 Express \u542f\u53d1\u7684 Web \u5e94\u7528\u6846\u67b6](https://github.com/gofiber/fiber)\\n- [Golang \u5b98\u65b9\u6587\u6863](https://go.dev/)\\n- [Golang \u7f16\u7a0b\u601d\u7ef4\u548c\u5de5\u7a0b\u5b9e\u6218](https://zhuanlan.zhihu.com/p/426368274)\\n- \u2b50\ufe0f [Go by example](https://gobyexample.com/)\\n\\n## Rust \u5b66\u4e60\\n\\n- \u2b50\ufe0f [PDF\uff1a\u4ece JavaScript \u5230 Rust\uff1a\u65b0\u4e66\u514d\u8d39\u53d1\u5e03](https://github.com/vinodotdev/node-to-rust/releases/download/v1/from-javascript-to-rust.pdf)\\n- \u2b50\ufe0f [Google \u51fa\u54c1\u7684 Rust \u6559\u7a0b](https://github.com/google/comprehensive-rust)\\n- \u2b50\ufe0f [Rust\u8bed\u8a00\u5723\u7ecf(Rust Course)](https://course.rs/about-book.html)\\n- \u2b50\ufe0f [\u63ed\u79d8\u524d\u7aef\u773c\u4e2d\u7684Rust\uff01](https://mp.weixin.qq.com/s/HKkt9cNZsUFdCR4nAlHeBA)\\n- \ud83c\udf1b [Rust \u5b98\u65b9\u6587\u6863](https://doc.rust-lang.org/book/)\\n- \ud83c\udf1b [Rust \u6807\u51c6\u5e93\u6587\u6863](https://doc.rust-lang.org/std/)\\n- \ud83c\udf1b [Rust by Example](https://doc.rust-lang.org/stable/rust-by-example/)\\n- \ud83c\udf1b [\u9009\u62e9 Go \u8fd8\u662f Rust\uff1fCloudWeGo-Volo \u57fa\u4e8e Rust \u8bed\u8a00\u7684\u63a2\u7d22\u5b9e\u8df5](https://juejin.cn/post/7143822279992934436)\\n- \ud83c\udf1b [\u7528Rust\u9508\u5316Vue Compiler](https://zhuanlan.zhihu.com/p/417534662)\\n- \ud83c\udf1b [\u7528 Rust \u5b9e\u73b0\u7684\u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5\u5408\u8f91](https://github.com/TheAlgorithms/Rust)\\n\\n## \u7f51\u7ad9\u63a8\u8350\\n\\n**\u6587\u6863\u76f8\u5173**\\n\\n- [GitHub \u641c\u7d22\u9875\u9762](https://github.com/search?q=&type=)\\n- [MDN \u6587\u6863](https://developer.mozilla.org/zh-CN/)\\n- [caniuse\uff1a\u67e5\u8be2 API \u517c\u5bb9\u6027](https://caniuse.com/)\\n- [snyk\uff1a\u67e5\u8be2 NPM\u3001Go\u3001Docker \u5b89\u5168\u6027](https://snyk.io/advisor/)\\n- [bundlephobia\uff1a\u67e5\u8be2 NPM \u5305\u4f53\u79ef](https://bundlephobia.com/)\\n- [Deno cheat sheet](https://oscarotero.com/deno/)\\n- [React Docs Beta](https://beta.reactjs.org/learn)\\n- [Overreacted](https://overreacted.io/)\\n- [tailwindcss \u6837\u5f0f\u53c2\u8003](https://tailwindcss.com/docs/configuration)\\n- [Explain Shell](https://explainshell.com/)\\n- [\u300a\u962e\u4e00\u5cf0 ES6 \u6559\u7a0b\u300b](https://es6.ruanyifeng.com/)\\n- [Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://github.com/yeasy/docker_practice)\\n- [\u3010\u7a0b\u5e8f\u5458\u6210\u957f\u6307\u5317\u3011node \u5fc5\u77e5\u5fc5\u4f1a\u7cfb\u5217](https://github.com/koala-coding/goodBlog)\\n- [\u300a\u6d4f\u89c8\u5668\u5de5\u4f5c\u539f\u7406\u4e0e\u5b9e\u8df5\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fblog.poetries.top%2Fbrowser-working-principle%2F)\\n- [\u300a\u6df1\u5165\u6d45\u51fa webpack\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fwebpack.wuhaolin.cn%2F)\\n- [\u300a\u4ee3\u7801\u968f\u60f3\u5f55\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fprogrammercarl.com%2F)\\n- [\u300a\u524d\u7aef\u8fdb\u9636\u4e4b\u9053\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fyuchengkai.cn%2F)\\n- [\u300aReact \u6280\u672f\u63ed\u79d8\u300b](https://link.juejin.cn/?target=https%3A%2F%2Freact.iamkasong.com%2F)\\n- [\u300a\u56fe\u89e3 React \u6e90\u7801\u7cfb\u5217\u300b](https://github.com/7kms/react-illustration-series)\\n- [\u300aVue \u6280\u672f\u63ed\u79d8\u300b](https://link.juejin.cn/?target=https%3A%2F%2Fustbhuangyi.github.io%2Fvue-analysis%2Fv2%2Fprepare%2F)\\n- [\u300aVue\u6280\u672f\u5185\u5e55\u300b](http://caibaojian.com/vue-design/)\\n- [\u72fc\u53d4\uff1a\u5982\u4f55\u6b63\u786e\u7684\u5b66\u4e60Node.js](https://i5ting.github.io/How-to-learn-node-correctly/)\\n- [\u5927\u5382\u9762\u8bd5\u9898\u6bcf\u65e5\u4e00\u9898](https://q.shanyue.tech/engineering/)\\n- [\u524d\u7aef\u5de5\u7a0b\u5316\u3001\u4e2a\u4eba\u670d\u52a1\u5668\u8fd0\u7ef4\u6307\u5357](https://shanyue.tech/op/#%E9%A2%84%E8%A7%88)\\n- [MySQL\u3001Linux\u3001\u670d\u52a1\u7aef\u67b6\u6784](https://xiaoflyfish.cn/)\\n- [Khaidi Chu \u7684\u535a\u5ba2](https://xcoder.in/)\\n\x3c!-- - [NLP-Beginner\uff1a\u81ea\u7136\u8bed\u8a00\u5904\u7406\u5165\u95e8\u7ec3\u4e60](https://github.com/FudanNLP/nlp-beginner) --\x3e\\n- [\u300a\u6df1\u5ea6\u5b66\u4e60\u6846\u67b6PyTorch\uff1a\u5165\u95e8\u4e0e\u5b9e\u8df5\u300b](https://github.com/chenyuntc/pytorch-book)\\n- [\u300a\u673a\u5668\u5b66\u4e60\u300b\uff08\u897f\u74dc\u4e66\uff09](https://github.com/datawhalechina/pumpkin-book)\\n- [\u300a\u673a\u5668\u5b66\u4e60\u300b\u914d\u5957\u89c6\u9891\u6559\u7a0b](https://www.bilibili.com/video/BV1Mh411e7VU)\\n- \u2b50\ufe0f [Software Engineering at Google](https://abseil.io/blog/04222021-swe-book)\\n- \u2b50\ufe0f [ML YouTube Courses](https://github.com/dair-ai/ML-YouTube-Courses)\\n- \u2b50\ufe0f [How Web Works](https://github.com/vasanthk/how-web-works)\\n\\n**\u5f00\u6e90\u63a8\u8350**\\n\\n- [Next.js](https://nextjs.org/docs/getting-started)\\n- [tailwindcss \u6837\u5f0f\u53c2\u8003](https://tailwindcss.com/docs/configuration)\\n- [PNPM](https://pnpm.io/installation)\\n- [TypeScript](https://www.typescriptlang.org/docs/)\\n- [Vite](https://vitejs.dev/)\\n- [Storybook](https://storybook.js.org/)\\n\\n**\u5728\u7ebf Plyaground**\\n\\n- [\u751f\u6210\u5404\u4e2a\u8bed\u8a00\u7684\u6c47\u7f16\u4ee3\u7801](https://godbolt.org/)\\n- [Vue SFC Playground](https://sfc.vuejs.org/)\\n- [CodeSandBox](https://link.juejin.cn/?target=https%3A%2F%2Fcodesandbox.io%2Fdashboard%2Fhome)\\n- [CodePen](https://codepen.io/)\\n- [AST explorer\uff1a\u53ef\u89c6\u5316 AST](https://www.astexplorer.net/)\\n- [\u6b63\u5219\u8868\u8fbe\u5f0f\u53ef\u89c6\u5316](https://link.juejin.cn/?target=https%3A%2F%2Fjex.im%2Fregulex)\\n\\n**\u7f16\u7a0b\u98ce\u683c\u6307\u5357**\\n\\n- \u2b50\ufe0f [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint)\\n- \u2b50\ufe0f [eslint-config-alloy](https://github.com/AlloyTeam/eslint-config-alloy)\\n- \u2b50\ufe0f [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript)\\n- \u2b50\ufe0f [clean-code-javascript](https://github.com/ryanmcdermott/clean-code-javascript)\\n\\n**\u6280\u672f\u793e\u533a**\\n\\n- https://dev.to/\\n- https://medium.com/\\n- https://linuxhandbook.com/\\n\\n**\u5de5\u5177\u76f8\u5173**\\n\\n- [plantuml\uff1a\u7528\u4ee3\u7801\u753b\u65f6\u5e8f\u56fe\u3001\u7528\u4f8b\u56fe\u3001\u7c7b\u56fe\u3001\u601d\u7ef4\u5bfc\u56fe](https://plantuml.com/)\\n- [njt\uff1a\u5feb\u901f\u5bfc\u822a\u81f3 npm \u5305\u8d44\u6e90](https://www.npmjs.com/package/njt)\\n- [skypack\uff1a\u65e0\u9700\u6784\u5efa\u5de5\u5177\u4f7f\u7528\u5404\u79cd\u7ecf\u8fc7\u4f18\u5316\u7684 npm \u5305](https://www.skypack.dev/)\\n- [carbon\uff1a\u751f\u6210\u4ee3\u7801\u7247](https://link.juejin.cn/?target=https%3A%2F%2Fcarbon.now.sh%2F)\\n- [codelf \u53d8\u91cf\u547d\u540d\u795e\u5668](https://unbug.github.io/codelf/)\\n- [openbase\uff1a\u67e5\u8be2\u5404\u79cd\u7b2c\u4e09\u65b9\u5e93](https://openbase.com/)\\n\\n## \u5b66\u4e60\u8d44\u6e90\\n\\n- \u300aLinux Shell \u811a\u672c\u653b\u7565\uff08\u7b2c2\u7248\uff09\u300b\\n- \u300a\u63a8\u8350\u7cfb\u7edf\u2014\u2014\u6280\u672f\u3001\u8bc4\u4f30\u53ca\u9ad8\u6548\u7b97\u6cd5\u300b\\n- \u300aGo \u8bed\u8a00\u7f16\u7a0b\u300b\\n- \u300aGo \u8bed\u8a00\u9ad8\u7ea7\u7f16\u7a0b\u300b\\n- \u300a\u64cd\u4f5c\u7cfb\u7edf\u5bfc\u8bba\u300b\\n- \u300a\u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf\u300b\\n- \u300aMySQL\u6280\u672f\u5185\u5e55\u300b\\n- \u300aRedis\u8bbe\u8ba1\u4e0e\u5b9e\u73b0\u300b\\n- \u2b50\ufe0f [\u64cd\u4f5c\u7cfb\u7edf\u5e38\u7528\u77e5\u8bc6\u603b\u7ed3\uff01](https://mp.weixin.qq.com/s/xRnG204OW67mKMnbfFHBoA)\\n- \u2b50\ufe0f [\u3010\u8ba1\u7b97\u673a\u79d1\u5b66\u901f\u6210\u8bfe\u3011\\\\[40\u96c6\u5168/\u7cbe\u6821\\\\] - Crash Course Computer Science](https://www.bilibili.com/video/BV1EW411u7th)\\n- \u2b50\ufe0f [\u3010\u7cbe\u6821\u4e2d\u82f1\u5b57\u5e55\u30112015 CMU 15-213 CSAPP \u6df1\u5165\u7406\u89e3\u8ba1\u7b97\u673a\u7cfb\u7edf \u8bfe\u7a0b\u89c6\u9891](https://www.bilibili.com/video/BV1iW411d7hd)\\n\\n## \u9762\u8bd5\u76f8\u5173\\n\\n- [JS \u6570\u636e\u7ed3\u6784\u4e0e\u7b97\u6cd5 - awesome-coding-js](https://github.com/ConardLi/awesome-coding-js)\\n- [JavaScript Algorithms and Data Structures](https://github.com/trekhleb/javascript-algorithms)\\n- [JavaScript\u7b97\u6cd5\u57fa\u7840\u53ca\u9762\u8bd5\u603b\u7ed3\uff081w1\u5b57\uff09](https://juejin.cn/post/7023208826472005668)\\n- \u2b50\ufe0f [\u5982\u4f55\u5199\u51fa\u4e00\u4e2a\u60ca\u8273\u9762\u8bd5\u5b98\u7684\u6df1\u62f7\u8d1d?](https://juejin.cn/post/6844903929705136141)\\n- \u2b50\ufe0f [\u9762\u4e86\u51e0\u4e2a\u8bf4\u81ea\u5df1\u7cbe\u901a Vue \u7684\u540c\u5b66](https://juejin.cn/post/6844904118704668685)\\n- [\u9ad8\u9891react\u9762\u8bd5\u989820\u9053\uff08\u9644\u8be6\u89e3\uff09](https://blog.csdn.net/xgangzai/article/details/120375992)\\n- [\u30101 \u6708\u6700\u65b0\u3011\u524d\u7aef 100 \u95ee\uff1a\u80fd\u641e\u61c2 80% \u7684\u8bf7\u628a\u7b80\u5386\u7ed9\u6211](https://juejin.cn/post/6844903885488783374)\\n\\n\x3c!--\\n\\n## \u524d\u7aef\u6d4b\u8bd5\\n\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0a\uff09](https://juejin.cn/post/6943430853972852750)\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0b\uff09](https://juejin.cn/post/6946008649026240519)\\n- [\u524d\u7aef\u6d4b\u8bd5\u96c6\u9526\u2014\u2014\u5982\u4f55\u5199\u597d\u524d\u7aef\u6d4b\u8bd5\u4fdd\u8bc1\u4ee3\u7801\u8d28\u91cf\uff1f](https://juejin.cn/post/6999445868550029319)\\n\\n## \u5f00\u53d1\u73af\u5883\u76f8\u5173\\n\\n- [\u3010\u624b\u628a\u624b\u3011\u5b66\u4f1aVS Code\\"\u4efb\u52a1\\"\u795e\u6280\uff0c\u6210\u4e3a\u9879\u76ee\u7ec4\u6700\u9753\u7684\u5d3d\uff01](https://juejin.cn/post/7035448197883363359)\\n- [\u804a\u804a\u5f00\u53d1\u65e5\u5e38\u7684\u6548\u7387\u63d0\u5347\u5de5\u5177\uff08\u5168\uff09](https://juejin.cn/post/7019183422320934948)\\n- [\u6253\u9020\u8212\u9002\u642c\u7816\u73af\u5883\uff0c\u8fd9\u4e9b\u662f\u6211\u6700\u60f3\u63a8\u4ecb\u7684\u684c\u9762\u597d\u7269](https://juejin.cn/post/6844904193828880391)\\n- [\u5e72\u8d27\u6ee1\u6ee1\uff01\u63a8\u4ecb\u51e0\u6b3e Mac \u4e0b\u975e\u5e38\u597d\u7528\u7684\u8f6f\u4ef6\uff08\u7b2c\u4e00\u5f39\uff09](https://juejin.cn/post/6844904012920127495)\\n- [\u5e72\u8d27\u6ee1\u6ee1\uff01\u63a8\u4ecb\u51e0\u6b3e Mac \u4e0b\u975e\u5e38\u597d\u7528\u7684\u8f6f\u4ef6\uff08\u7b2c\u4e8c\u5f39\uff09](https://juejin.cn/post/6844904031685443592)\\n\\n--\x3e\\n\\n## \ud83d\udcd2 \u6398\u91d1\u5927\u4f6c\u6c47\u603b\\n\\n- Vue \u6e90\u7801\u3001\u54cd\u5e94\u5f0f\u673a\u5236\uff1a[ssh](https://juejin.cn/user/2330620350708823/posts) \u3001[\u9ec4\u8f76](https://juejin.cn/user/2137106333044861/posts)\\n- React \u8fdb\u9636\u7cfb\u5217\uff1a[\u6211\u4e0d\u662f\u5916\u661f\u4eba](https://juejin.cn/user/2418581313687390/posts)\\n- Webpack \u76f8\u5173\uff1a[Tecvan](https://juejin.cn/user/1820446985555544/posts)\\n- \u8bbe\u8ba1\u6a21\u5f0f\uff1a[DYBOY](https://juejin.cn/user/3544481219495806/posts)\\n- \u624b\u5199\u6e90\u7801\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a[\u848b\u9e4f\u98de](https://juejin.cn/user/2295436011645655/posts) \u3001[\u524d\u7aef\u9633\u5149](https://juejin.cn/user/1204720476893064/posts)\\n- Webpack5\u3001\u8bbe\u8ba1\u6a21\u5f0f\uff1a[\u6e05\u6c64\u997a\u5b50](https://juejin.cn/user/4300945218607197)\\n- \u524d\u7aef\u67b6\u6784\u8bbe\u8ba1\uff1a[\u5bd2\u8349](https://juejin.cn/user/703340610597064/posts)\\n- \u603b\u7ed3\u5927\u5e08\uff1a[JowayYoung](https://juejin.cn/user/2330620350432110/posts)\\n- \u6e90\u7801\u5206\u6790\uff1a\u82e5\u5ddd\\n- \u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247\uff1a[shanyue](https://juejin.cn/user/1556564164489389/posts)\\n- CSS \u5404\u79cd\u7279\u6548\uff1a[chokcoco](https://juejin.cn/user/2330620350437678/posts)\\n- Nodejs \u76f8\u5173\uff1a[\u5929\u732a](https://www.zhihu.com/people/liuyong25/posts)\\n- Umi \u76f8\u5173\uff1a[MDH \u524d\u7aef\u5468\u520a](https://www.yuque.com/mdh/weekly/rhiudh)\\n- Antd\u3001Umi\u3001Node.js\uff1a[\u652f\u4ed8\u5b9d\u4f53\u9a8c\u79d1\u6280\u7cbe\u9009](https://www.yuque.com/antfe/featured/ys58hy)\\n- \u524d\u7aef\u3001\u5168\u6808\u6280\u672f\u4e13\u520a\uff1a[\u963f\u91cc CCO \u4f53\u9a8c\u6280\u672f\u4e13\u520a](https://www.zhihu.com/column/ali-nanjing)\\n- Golang \u76f8\u5173\uff1a[\u817e\u8baf\u6280\u672f\u5de5\u7a0b](https://zhuanlan.zhihu.com/p/340814811)\\n- \u524d\u7aef\u88c5\u903c\u6280\u5de7108\u5f0f\uff1a[\u72ec\u9493\u5bd2\u6c5f\u96ea](https://segmentfault.com/u/king_hcj)\\n- \u524d\u7aef\u4e5d\u6761 bug \u5206\u4eab\uff1a[lulu_up](https://segmentfault.com/u/lulu_up)\\n- Vue3 \u6e90\u7801\u5171\u8bfb\uff1a[\u524d\u7aef\u6768\u6751\u957f](https://www.bilibili.com/video/BV1bS4y1T7ng)\\n- \u524d\u7aef\u5de5\u7a0b\u5316\u3001\u5b66\u4e60 Golang\uff1a\u6d1b\u7af9\\n- Node.js \u76f8\u5173\uff1a\u4e94\u6708\u541b\\n\\n## \ud83d\udcd2 \u5f85\u5b66\u4e60\u5185\u5bb9\\n\\n- [babel\u6e90\u7801\u8be6\u89e3-v1.7.8](https://juejin.cn/post/7017360824939315207)\\n- [\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09](https://juejin.cn/post/6844904094079926286)\\n- [\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b](https://juejin.cn/post/6844904116913700877)\\n- [\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7](https://juejin.cn/post/6889247428797530126)\\n- [\u5982\u4f55\u5229\u7528lerna\u7ba1\u7406\u6a21\u5757](https://juejin.cn/post/6844903783005175815)\\n- [\u57fa\u4e8e lerna \u7684\u591a\u5305 JavaScript \u9879\u76ee\u642d\u5efa\u7ef4\u62a4](https://juejin.cn/post/6969544464113074189)\\n- [React\u6027\u80fd\u4f18\u5316\u5c0f\u8d34\u58eb](https://juejin.cn/post/6844903896767283207#heading-5)\\n- [\u795e\u5947\u7684lambda\u8868\u8fbe\u5f0f\u2014\u2014\u51fd\u6570\u5f0f\u7f16\u7a0b\u5fc5\u5b66](https://juejin.cn/post/6844903929726107655)\\n- [npm\u8fdb\u9636\u2014\u2014\u5982\u4f55\u62e5\u6709\u81ea\u5df1\u7684\u5305\u548c\u6d41\u7a0b\u81ea\u52a8\u5316](https://juejin.cn/post/6844903954002739213)\\n- [React Hooks\u7684\u82b1\u6837\u73a9\u6cd5](https://juejin.cn/post/6844904162124103693)\\n - useDark\uff0cuseClickOutside\uff0c\u5168\u5c40\u72b6\u6001\u7ba1\u7406\\n- [\u6b63\u5219\u8868\u8fbe\u5f0f\u4e0d\u8981\u80cc](https://juejin.cn/post/6844903845227659271)\\n- [\u6211\u4eec\u6216\u8bb8\u4e0d\u9700\u8981 classnames \u8fd9\u4e2a\u5e93](https://juejin.cn/post/6844903825145511950)\\n- [\u56fd\u5e86\u7206\u809d\uff0c\u7528vite+vue3+ts\u5b9e\u73b0\u4e00\u4e2a\u7f51\u9875\u7248\u7684typora\uff01](https://juejin.cn/post/7014431215302213668)\\n- [\u624b\u6478\u624b\u6559\u4f60\u4f7f\u7528\u6700\u65b0\u7248husky(v7.0.1)\u8ba9\u4ee3\u7801\u66f4\u4f18\u96c5\u89c4\u8303](https://juejin.cn/post/6982192362583752741)\\n- [\u5feb\u901f\u5165\u624bElectron\uff0c\u62e5\u6709\u4e00\u4e2a\u81ea\u5df1\u7684\u684c\u9762\u5e94\u7528](https://juejin.cn/post/7015476516196712462)\\n- [\u5728\u5927\u5382\u662f\u5982\u4f55\u9ad8\u6548\u7ec4\u7ec7 npm script \u7684](https://juejin.cn/post/6945236994247098381)\\n- [\u524d\u7aef\u5f00\u53d1\u8005\u5468\u520a\u7b2c\u4e09\u671f\uff1a\u5404\u5927\u5382 webpack5 \u5b9e\u8df5](https://juejin.cn/post/6940042028243746823)\\n- [\u3010\u8bd1\u3011\u4e0b\u4e00\u4ee3\u524d\u7aef\u6784\u5efa\u5de5\u5177 ViteJS \u4e2d\u82f1\u53cc\u8bed\u5b57\u5e55 \uff5c \u6280\u672f\u70b9\u8bc4](https://juejin.cn/post/6937176680251424775#heading-7)\\n- \u2b50\ufe0f [Webpack5 \u65b0\u7279\u6027\u4e1a\u52a1\u843d\u5730\u5b9e\u6218](https://juejin.cn/post/6924258563862822919)\\n- \u2b50\ufe0f [Webpack \u5b98\u65b9\u5f00\u53d1\u6307\u5357](https://webpack.docschina.org/guides/development/#choosing-a-development-tool)\\n- [\u6784\u5efa\u6548\u7387\u5927\u5e45\u63d0\u5347\uff0cwebpack5 \u5728\u4f01\u9e45\u8f85\u5bfc\u7684\u5347\u7ea7\u5b9e\u8df5](https://mp.weixin.qq.com/s/P3foOrcu4StJDGdX9xavng)\\n- [\u5982\u4f55\u5229\u7528 monorepo \u7b56\u7565\u7ba1\u7406\u4ee3\u7801\uff1f](https://mp.weixin.qq.com/s/ZP2IigNVSIZKGuYxNYOYgw)\\n- [All in one\uff1a\u9879\u76ee\u7ea7 monorepo \u7b56\u7565\u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6924854598268108807)\\n- [\u4e00\u987f\u64cd\u4f5c\uff0c\u6211\u628a Table \u7ec4\u4ef6\u6027\u80fd\u63d0\u5347\u4e86\u5341\u500d](https://juejin.cn/post/7007252464726458399)\\n- [MySQL \u4ece\u5165\u95e8\u5230\u5b9e\u8df5\uff0c\u4e07\u5b57\u8be6\u89e3](https://juejin.cn/post/7005019784429469704)\\n- [\u534a\u5c0f\u65f6\u641e\u4f1a CentOS \u5165\u95e8\u5fc5\u5907\u57fa\u7840\u77e5\u8bc6](https://juejin.cn/post/6844904080972709901)\\n- [\u624b\u6478\u624b\u5e26\u4f60 Docker \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/6844903919995322382)\\n\\n\x3c!-- --\x3e\\n\\n- [\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357](https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg)\\n- [\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key](https://juejin.cn/post/7026119446162997261)\\n- [\u56db\u4e2a\u771f\u79c0React\u7528\u6cd5\uff0c\u4f60\u503c\u5f97\u62e5\u6709](https://juejin.cn/post/7077365102743126052)\\n- [\u3010\u7b2c2506\u671f\u3011JavaScript \u5305\u7ba1\u7406\u5668\u7b80\u53f2\uff08npm/yarn/pnpm\uff09](https://mp.weixin.qq.com/s/0Nx093GdMcYo5Mr5VRFDjw)\\n- [pnpm \u6e90\u7801\u7ed3\u6784\u53ca\u8c03\u8bd5\u6307\u5357](https://mp.weixin.qq.com/s/grb2OlBYiwU3TOkEtNZReA)\\n- [\u6df1\u5165\u6d45\u51fa tnpm rapid \u6a21\u5f0f - \u5982\u4f55\u6bd4 pnpm \u5feb 10 \u79d2](https://zhuanlan.zhihu.com/p/455809528)\\n- [Vue\u7ec4\u4ef6\u5e93\u6587\u6863\u7ad9\u70b9\u7684\u642d\u5efa\u601d\u8def](https://juejin.cn/post/7152898360498716702)\\n- [\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e](https://juejin.cn/post/7151653067593613320#heading-18)\\n- [React-router\u4ece0\u52301](https://juejin.cn/post/7148746931802472485#heading-8)\\n- [\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09](https://juejin.cn/post/7118937685653192735#heading-7)\\n- [768. \u6700\u591a\u80fd\u5b8c\u6210\u6392\u5e8f\u7684\u5757 II : \u5e38\u89c4\u8d2a\u5fc3\u6784\u9020\u9898](https://juejin.cn/post/7131222991681093639)\\n- [\ud83e\udd8a\u3010\u524d\u7aef\u5de5\u7a0b\u5316\u3011\u4e3a\u4ec0\u4e48\u5927\u5382\u90fd\u8981\u5f00\u53d1\u81ea\u5df1\u7684\u811a\u624b\u67b6\uff1f\ud83e\udd84\ufe0f](https://juejin.cn/post/7128597557634138148)\\n- [\u5feb\u4e0a\u8f66\uff01\u4ece\u96f6\u5f00\u59cb\u642d\u5efa\u4e00\u4e2a\u5c5e\u4e8e\u81ea\u5df1\u7684\u7ec4\u4ef6\u5e93\uff01](https://juejin.cn/post/7120893568553582622)\\n- [\u5199\u7ed9\u524d\u7aef\u7684\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u57fa\u7840\u5165\u95e8\uff08\u4e00\uff09\u8fd4\u749e\u5f52\u771f\uff1a\u4ece\u5f15\u7528\u7c7b\u578b\u5230\u88f8\u6307\u9488](https://juejin.cn/post/6938201650012094495)\\n- [\u6a21\u5757\u8054\u90a6\u6d45\u6790](https://juejin.cn/post/7101457212085633054#heading-1)\\n- [\u3010\u7b2c2126\u671f\u3011\u6bcf\u4e2a\u5f00\u53d1\u8005\u90fd\u5e94\u8be5\u77e5\u9053\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/KHeo5bdY4cjPfA5I1mjXWw)\\n- [Go Interview](https://www.yuque.com/go-interview/set/xq5788)\\n- [LeetCode Cookbook](https://books.halfrost.com/leetcode/ChapterFour/0200~0299/0287.Find-the-Duplicate-Number/)\\n- [Go Gin \u7cfb\u5217\u4e8c\uff1a\u521d\u59cb\u5316\u9879\u76ee\u53ca\u516c\u5171\u5e93](https://mp.weixin.qq.com/s?__biz=MzUxMDI4MDc1NA==&mid=2247483807&idx=1&sn=9c7aede4f675f2de49ddc08ab1a95a71&chksm=f90414c2ce739dd4b8711c0043286fba9744b8d9c86c75c7ac7750d28cd2fed43f749eb5de99&scene=178&cur_album_id=1383459655464337409#rd)\\n- [500ms to 1.7ms In React: A Journey And A Checklist](https://orizens.com/blog/500ms-to-1-7ms-in-react-a-journey-and-a%20checklist/)\\n- [\u6f2b\u8c08\u6784\u5efa\u5de5\u5177(\u5341):\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def](https://juejin.cn/post/7157902763534319624)\\n- [\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684](https://juejin.cn/post/7170852747749621791)\\n- [\u6211\u662f\u5982\u4f55\u5e26\u9886\u56e2\u961f\u4ece\u96f6\u5230\u4e00\u5efa\u7acb\u524d\u7aef\u89c4\u8303\u7684\uff1f\ud83c\udf89\ud83c\udf89\ud83c\udf89](https://juejin.cn/post/7085257325165936648)\\n- [Go\u7c7b\u578b\u7cfb\u7edf\uff1a\u6709\u4f55\u4e0e\u4f17\u4e0d\u540c](https://mp.weixin.qq.com/s/H3iygMqDTRWv6h2VcgVeUg)\\n- [Learning Go by examples: part 7 - Create a cross-platform GUI/Desktop app in Go](https://dev.to/aurelievache/learning-go-by-examples-part-7-create-a-cross-platform-gui-desktop-app-in-go-44j1)\\n- [Understanding Docker: part 37 \u2013 Content Trust](https://dev.to/aurelievache/understanding-docker-part-37-content-trust-18n3)\\n- [Understanding Kubernetes: part 47 \u2013 Kubernetes 1.26 Changelog](https://dev.to/aurelievache/understanding-kubernetes-part-47-kubernetes-126-changelog-2404)\\n- [Umi Core Maintainers\uff0c\u6708\u699c\u4f5c\u8005\uff0c\u664b\u5347 P8\uff0c\u6765\u542c\u6211\u788e\u788e\u5ff5\u5982\u4f55\uff5c2022 \u5e74\u4e2d\u603b\u7ed3](https://juejin.cn/post/7115634967945674765)\\n- [\u4e3a\u4ec0\u4e48 React \u7684 Diff \u7b97\u6cd5\u4e0d\u91c7\u7528 Vue \u7684\u53cc\u7aef\u5bf9\u6bd4\u7b97\u6cd5](https://juejin.cn/post/7116141318853623839)\\n- [\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406](https://juejin.cn/post/7121378029682556958)\\n\\n\x3c!-- --\x3e\\n\\n- [\u9762\u8bd5\u5b98\uff1a\u4f60\u4f1a\u770b Vite \u6e90\u7801\u5417](https://juejin.cn/post/7094984070999834655)\\n- [\u7ed9\u60f3\u8f6cGo\u6216\u8005Go\u8fdb\u9636\u540c\u5b66\u7684\u4e00\u4e9b\u5efa\u8bae](https://juejin.cn/post/7147939014870302756)\\n- [react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3](https://juejin.cn/post/7117512204059934733)\\n- [\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09](https://juejin.cn/post/7118937685653192735)\\n- [\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406](https://juejin.cn/post/6944863057000529933)\\n\\n## \ud83d\udcd2 \u5c0f\u76ee\u6807\\n\\n- Vue 3.x \u6e90\u7801\uff1b\\n- Vuex 4.x \u6e90\u7801\uff1b\\n- Vue-Router \u6e90\u7801\uff1b\\n- \u642d\u5efa\u811a\u624b\u67b6\u5de5\u5177\uff08Webpack5 \u65b0\u7279\u6027\u5b9e\u8df5\uff09\uff1b\\n- VS Code extension \uff1b\\n- cocos \u6e38\u620f\u5f00\u53d1\uff1b\\n- \u624b\u5199 redux \u6e90\u7801\uff1b\\n- \u624b\u5199 redux-thunk \u6e90\u7801\uff1b\\n- \u624b\u5199 Promise/A+ \uff1b\\n - [\u624b\u5199\u4e00\u4e2aPromise/A+,\u5b8c\u7f8e\u901a\u8fc7\u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b](https://juejin.cn/post/6844904116913700877)\\n - [\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282](https://juejin.cn/post/6945319439772434469)\\n - [V8 Promise\u6e90\u7801\u5168\u9762\u89e3\u8bfb\uff0c\u5176\u5b9e\u4f60\u5bf9Promise\u4e00\u65e0\u6240\u77e5](https://juejin.cn/post/7055202073511460895)\\n - [\u6700\u7b80\u5b9e\u73b0Promise\uff0c\u652f\u6301\u5f02\u6b65\u94fe\u5f0f\u8c03\u7528\uff0820\u884c\uff09](https://juejin.cn/post/6844904094079926286)\\n - [\u624b\u628a\u624b\u4e00\u884c\u4e00\u884c\u4ee3\u7801\u6559\u4f60\u201c\u624b\u5199Promise\u201c\uff0c\u5b8c\u7f8e\u901a\u8fc7 Promises/A+ \u5b98\u65b9872\u4e2a\u6d4b\u8bd5\u7528\u4f8b](https://juejin.cn/post/7043758954496655397)\\n- \u6392\u5e8f\u7b97\u6cd5\uff0c\u6876\u6392\u5e8f\u3001\u8ba1\u6570\u6392\u5e8f\uff0c\u65f6\u95f4\u590d\u6742\u5ea6 O(n) \uff1b\\n- \u6bcf\u65e5\u7b97\u6cd5\\n - [https://labuladong.gitee.io/algo/](https://labuladong.gitee.io/algo/)\uff08\u56fd\u5185\u901f\u5ea6\u5feb\uff0c\u4f53\u9a8c\u597d\uff0c\u63a8\u8350\uff09\\n - https://labuladong.github.io/algo/\\n - [\u624b\u628a\u624b\u5237\u4e8c\u53c9\u6811\u7cfb\u5217\u5b8c\u7ed3\u7bc7](https://mp.weixin.qq.com/s/AzQzw-pC8A-0kS0NJn2eWw)\\n - [\u524d\u7f00\u6811\u7b97\u6cd5\u6a21\u677f\u79d2\u6740 5 \u9053\u7b97\u6cd5\u9898](https://mp.weixin.qq.com/s/hGrTUmM1zusPZZ0nA9aaNw)\\n - [\u96c6\u5408\u5212\u5206\u95ee\u9898\uff1a\u6392\u5217\u7ec4\u5408\u4e2d\u7684\u56de\u6eaf\u601d\u60f3\uff08\u4fee\u8ba2\u7248\uff09](https://mp.weixin.qq.com/s/5GO2ZITncVArdm4KITBd9g)\\n - [\u5feb\u901f\u6392\u5e8f\u7684\u6b63\u786e\u7406\u89e3\u65b9\u5f0f\u53ca\u8fd0\u7528](https://mp.weixin.qq.com/s/8ZTMhvHJK_He48PpSt_AmQ)\\n - [\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01](https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A)\\n - [\u4e00\u6587\u79d2\u6740 5 \u9053\u6700\u8fd1\u516c\u5171\u7956\u5148\u95ee\u9898](https://mp.weixin.qq.com/s/njl6nuid0aalZdH5tuDpqQ)\\n - [\u7b97\u6cd5\u65f6\u7a7a\u590d\u6742\u5ea6\u5206\u6790\u5b9e\u7528\u6307\u5357](https://mp.weixin.qq.com/s/OQAzopRncZe5cb9_of4mCQ)\\n - [\u52a8\u6001\u89c4\u5212\u7b54\u7591\u7bc7\uff08\u4fee\u8ba2\u7248\uff09](https://mp.weixin.qq.com/s/zhaurXhrAiHsfgGAOfAuMw)\\n - [\u8bba\u52a8\u6001\u89c4\u5212\u7a77\u4e3e\u7684\u4e24\u79cd\u89c6\u89d2](https://mp.weixin.qq.com/s/6vwNBr48D36n6E3EawFUqg)\\n - [\u9ad8\u9891\u9762\u8bd5\u7cfb\u5217\uff1a\u5355\u8bcd\u62c6\u5206\u95ee\u9898](https://mp.weixin.qq.com/s/iL7tCl6pqw0fTatGSemY-g)\\n - [\u522b\u7528 KMP \u4e86\uff0c Rabin-Karp \u7b97\u6cd5\u4e86\u89e3\u4e0b](https://mp.weixin.qq.com/s/HiEft8sW5QzHcM5mb5_V6g)\\n - [\u5fae\u8f6f\u9762\u8bd5\u9898\u89e3\u6790\uff1a\u4e11\u6570\u7cfb\u5217\u7b97\u6cd5](https://mp.weixin.qq.com/s/XXsWwDml_zHiTEFPZtbe3g)\\n - [\u8bf4\u900f\u6e38\u620f\u4e2d\u5e38\u7528\u7684\u4e24\u79cd\u968f\u673a\u7b97\u6cd5](https://mp.weixin.qq.com/s/vxQDGfshcSVjs9EYmV8q3Q)\\n - [\u6211\u7528\u6d88\u606f\u961f\u5217\u505a\u4e86\u4e00\u6b3e\u8054\u673a\u5c0f\u6e38\u620f](https://mp.weixin.qq.com/s/kI0HUTFVr4YEBpLRZWLEDg)\\n - [Union Find \u5e76\u67e5\u96c6\u7b97\u6cd5\u539f\u7406\u53ca\u5e94\u7528](https://mp.weixin.qq.com/s/mFLCL_Dyz5-CtZMZJmOXKw)\\n - [\u5fc5\u77e5\u5fc5\u4f1a\u4f4d\u8fd0\u7b97\u6280\u5de7\u624b\u518c](https://mp.weixin.qq.com/s/4vHfaNnn1OpWQJcsssWWdQ)\\n - [\u3010\u9762\u8bd5\u9ad8\u9891\u9898\u3011\u96be\u5ea6 1.5/5\uff0c\u591a\u89e3\u6cd5\u7ecf\u5178\u9762\u8bd5\u9898](https://juejin.cn/post/7152708637817831432)\\n - [DFS/\u56de\u6eaf/\u52a8\u6001\u89c4\u5212\u7b97\u6cd5\u7684\u878d\u4f1a\u8d2f\u901a](https://mp.weixin.qq.com/s/9Q4JAuSATq3WgN7krdGTWg)\\n - [2021 \u516c\u4f17\u53f7\u7cbe\u9009\u6587\u7ae0\u76ee\u5f55](https://mp.weixin.qq.com/s/ir1Hk06HcT8W_qz0MtyONA)\\n- \u770b\u4e0b\u9762\u7684\u6587\u7ae0\uff0c\u624b\u5199\u4e00\u4e2a Webpack\\n\\t- [\u624b\u5199\u4e00\u4e2awebpack\uff0c\u770b\u770bAST\u600e\u4e48\u7528\uff5c\u725b\u6c14\u51b2\u5929\u65b0\u5e74\u5f81\u6587](https://juejin.cn/post/6930877602840182791)\\n - [\u4eca\u5929\uff0c\u6211\u4eec\u6765\u5b9e\u73b0\u4e00\u4e2a\u57fa\u7840\u7248\u7684webpack](https://juejin.cn/post/6987036612035084296)\\n\\t- [\u624b\u5199webpack\u6838\u5fc3\u539f\u7406\uff0c\u518d\u4e5f\u4e0d\u6015\u9762\u8bd5\u5b98\u95ee\u6211webpack\u539f\u7406](https://juejin.cn/post/6854573217336541192)\\n- Webapck \u7f16\u8bd1\u6d41\u7a0b\\n - \u2b50\ufe0f [Webpack5 \u6838\u5fc3\u539f\u7406\u4e0e\u5e94\u7528\u5b9e\u8df5](https://juejin.cn/book/7115598540721618944)\\n - [Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790](https://juejin.cn/post/7031546400034947108)\\n - [\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b](https://juejin.cn/post/7026658230365323301)\\n - [\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f](https://juejin.cn/post/6859538537830858759)\\n - [100\u884c\u4ee3\u7801\u5b9e\u73b0\u4e00\u4e2a\u7ec4\u4ef6\u5f15\u7528\u6b21\u6570\u7edf\u8ba1\u63d2\u4ef6](https://juejin.cn/post/7077484559893266439)\\n - https://github.com/ronami/minipack\\n- \u624b\u628a\u624b\u5b9e\u73b0\u4e00\u4e2a babel \u63d2\u4ef6\\n - Babel \u63d2\u4ef6\u5e38\u7528 API\u3001\u914d\u5408 TS \u5f00\u53d1\u3001\u5982\u4f55\u6d4b\u8bd5\u63d2\u4ef6\u7b49\u7b49\\n - \u2b50\ufe0f [Babel \u63d2\u4ef6\uff1a30\u5206\u949f\u4ece\u5165\u95e8\u5230\u5b9e\u6218](https://juejin.cn/post/7143921535445631012)\\n - \u8fd9\u7bc7\u505a\u7684 demo \u662f\u4e00\u4e2a\u7b80\u5355\u7684 babel-plugin-import\\n - [\u6df1\u5165Babel\uff0c\u8fd9\u4e00\u7bc7\u5c31\u591f\u4e86](https://juejin.cn/post/6844903746804137991)\\n - \u8fd9\u7bc7\u505a\u7684 demo \u7c7b\u4f3c Java \u4e2d\u7684 lambok\\n - [\u4fdd\u59c6\u7ea7\u6559\u5b66\uff01\u8fd9\u6b21\u4e00\u5b9a\u5b66\u4f1ababel\u63d2\u4ef6\u5f00\u53d1\uff01](https://juejin.cn/post/7012424646247055390)\\n - [babel-handbook - \u5404\u79cd ast \u64cd\u4f5c\u6307\u5357](https://github.com/jamiebuilds/babel-handbook/blob/master/translations/en/plugin-handbook.md)\\n - [\u4f60\u8fd8\u5728\u624b\u52a8\u90e8\u7f72\u57cb\u70b9\u5417\uff1f\u4ece0\u52301\u5f00\u53d1Babel\u57cb\u70b9\u81ea\u52a8\u690d\u5165\u63d2\u4ef6](https://mp.weixin.qq.com/s/R6Xr8SoJicZB8-P4H2SSPA)\\n - [\u64cd\u4f5c JavaScript \u7684 AST](https://juejin.cn/post/7061808830274863118)\\n - [\u524d\u7aef\u4e5f\u8981\u61c2\u7f16\u8bd1\uff1aAST \u4ece\u5165\u95e8\u5230\u4e0a\u624b\u6307\u5357](https://juejin.cn/post/6953963506693570573)\\n - [\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136](https://juejin.cn/post/7026671646555504676)\\n- diff \u7b97\u6cd5\u76f8\u5173\\n - https://github.com/snabbdom/snabbdom\\n - https://github.com/snabbdom/snabbdom/blob/master/src/init.ts\\n - \u2b50\ufe0f [\u56fe\u89e3Diff\u7b97\u6cd5\u2014\u2014Vue\u7bc7](https://mp.weixin.qq.com/s/8M-pJdKjF6bx5ijtSFKIcw)\\n - \u2b50\ufe0f [\u6d45\u6790 Snabbdom \u4e2d vnode \u548c diff \u7b97\u6cd5](https://juejin.cn/post/7067693810918096903)\\n - [\u4e00\u6587\u5403\u900f React \u548c Vue \u7684\u591a\u8282\u70b9 diff \u539f\u7406](https://juejin.cn/post/7161063643105198093)\\n - [diff \u7b97\u6cd5\u6df1\u5165\u4e00\u4e0b\uff1f](https://juejin.cn/post/6997965021401579556)\\n - [DIff\u7b97\u6cd5\u770b\u4e0d\u61c2\u5c31\u4e00\u8d77\u6765\u780d\u6211(\u5e26\u56fe)](https://juejin.cn/post/7000266544181674014)\\n - [\u5173\u4e8eVirtual DOM\u7406\u89e3\u548cSnabbdom\u6e90\u7801\u6d45\u6790](https://juejin.cn/post/6966215704634720287)\\n - [shanyue mini-code vdom](https://github.com/shfshanyue/mini-code/blob/master/code/vdom/index.js)\\n - [Virtual DOM\u5230\u5e95\u6709\u4ec0\u4e48\u8ff7\u4eba\u4e4b\u5904\uff1f\u5982\u4f55\u642d\u5efa\u4e00\u6b3e\u8ff7\u4f60\u7248Virtual DOM\u5e93\uff1f](https://juejin.cn/post/6976232466059100197)\\n - [React\u3001Vue2\u3001Vue3\u7684\u4e09\u79cdDiff\u7b97\u6cd5](https://juejin.cn/post/6919376064833667080)\\n - [\u7f51\u4e0a\u90fd\u8bf4\u64cd\u4f5c\u771f\u5b9e DOM \u6162\uff0c\u4f46\u6d4b\u8bd5\u7ed3\u679c\u5374\u6bd4 React \u66f4\u5feb\uff0c\u4e3a\u4ec0\u4e48\uff1f- \u77e5\u4e4e](https://www.zhihu.com/question/31809713/answer/53544875)\\n- webpack \u70ed\u6a21\u5757\u66ff\u6362\u770b\u4e0b\u6e90\u7801\\n - [webpack\u6a21\u5757\u70ed\u66f4\u65b0\u539f\u7406](https://juejin.cn/post/7049608872553611301)\\n - [Webpack \u539f\u7406\u7cfb\u5217\u5341\uff1aHMR \u539f\u7406\u5168\u89e3\u6790](https://juejin.cn/post/7021729340945596424)\\n - [Webapck5\u6838\u5fc3\u6253\u5305\u539f\u7406\u5168\u6d41\u7a0b\u89e3\u6790](https://juejin.cn/post/7031546400034947108)\\n- Docker \u76f8\u5173\u603b\u7ed3\u4e00\u4e0b\\n - [GitLab CI \u4ece\u5165\u95e8\u5230\u5b9e\u8df5](https://juejin.cn/post/7064906701941506061)\\n - [\u5199\u7ed9\u524d\u7aef\u7684 Docker \u4e0a\u624b\u6307\u5357](https://mp.weixin.qq.com/s/5LLX__x-yamgR83e0NKAtA)\\n - [\u5199\u7ed9\u524d\u7aef\u7684 K8S \u4e0a\u624b\u6307\u5357](https://mp.weixin.qq.com/s/0Il5o9CRgZI3LbuR0LjAtQ)\\n - [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72](https://juejin.cn/post/7069609959985512484)\\n - [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72](https://juejin.cn/post/7083009375387779085)\\n - [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u5bb9\u5668\u7f16\u6392](https://juejin.cn/post/7113712658850775048)\\n - [\u4e91\u8ba1\u7b97\u65f6\u4ee3\uff0c\u4f60\u8fd8\u4e0d\u4f1a Docker \uff1f \u4e00\u4e07\u5b57\u603b\u7ed3\uff08\u5efa\u8bae\u6536\u85cf\uff09](https://mp.weixin.qq.com/s/f581rfvKWE3KGgWfZDJ2cA)\\n- \u524d\u7aef\u6846\u67b6\u6e90\u7801\\n - \u2b50\ufe0f \u2b50\ufe0f [React \u8fdb\u9636\u5b9e\u8df5\u6307\u5357](https://juejin.cn/book/6945998773818490884)\\n - \u2b50\ufe0f [react18\u65b0\u7279\u6027\u53ca\u5b9e\u8df5\u603b\u7ed3](https://juejin.cn/post/7117512204059934733)\\n - \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300dReact\u4e2d\u6ca1\u6709keepalive\uff1f\u6ca1\u4e8b\uff01\u624b\u628a\u624b\u6559\u4f60\u4ece\u96f6\u5230\u4e00\u8bbe\u8ba1\u5e76\u5b9e\u73b0\u4e00\u4e2a\uff01](https://juejin.cn/post/7122617883837857806)\\n - \u2b50\ufe0f [\u300cReact \u8fdb\u9636\u300d React \u5168\u90e8 Hooks \u4f7f\u7528\u5927\u5168 \uff08\u5305\u542b React v18 \u7248\u672c \uff09](https://juejin.cn/post/7118937685653192735)\\n - \u2b50\ufe0f [\u300cReact\u8fdb\u9636\u300dreact-router v6 \u901a\u5173\u6307\u5357](https://juejin.cn/post/7069555976717729805)\\n - \u2b50\ufe0f [\u300creact\u8fdb\u9636\u300d\u4e00\u6587\u5403\u900freact-hooks\u539f\u7406](https://juejin.cn/post/6944863057000529933)\\n - \u2b50\ufe0f [2022 \u5e74\u7684 React \u751f\u6001](https://juejin.cn/post/7085542534943883301)\\n - \u2b50\ufe0f [React \u8fd0\u884c\u65f6\u4f18\u5316\u65b9\u6848\u7684\u6f14\u8fdb](https://juejin.cn/post/7010539227284766751)\\n - \ud83c\udf1b [Before You memo()](https://overreacted.io/before-you-memo/)\\n - \ud83c\udf1b [\u56fe\u89e3 React - bailout\u903b\u8f91](https://7kms.github.io/react-illustration-series/main/fibertree-update/#bailout%E9%80%BB%E8%BE%91-bailout)\\n - \ud83c\udf1b [React \u7684 Concurrent Mode \u662f\u5426\u6709\u8fc7\u5ea6\u8bbe\u8ba1\u7684\u6210\u5206](https://www.zhihu.com/question/434791954/answer/2453356416)\\n - \ud83c\udf1b [\u300c\u4e0a\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://www.bilibili.com/video/BV1Yr4y1J7oc)\\n - \ud83c\udf1b [\u300c\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://www.bilibili.com/video/BV1j44y1g74m)\\n - \ud83c\udf1b [Build your own React](https://pomb.us/build-your-own-react/)\\n - [Vue \u9879\u76ee\u6027\u80fd\u4f18\u5316 \u2014 \u5b9e\u8df5\u6307\u5357\uff08\u7f51\u4e0a\u6700\u5168 / \u8be6\u7ec6\uff09](https://juejin.cn/post/6844903913410314247)\\n - [\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406](https://juejin.cn/post/7121378029682556958)\\n - [React \u6e32\u67d3\u7684\u672a\u6765](https://juejin.cn/post/7154175507280429070)\\n - [React \u4e2d\u5e38\u89c1\u7684 8 \u4e2a\u9519\u8bef\uff0c\u5982\u4f55\u907f\u514d](https://mp.weixin.qq.com/s/METf8Ng6Qnsu1uWGTzan8g)\\n - [20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08](https://juejin.cn/post/7104460511869141006)\\n - [React\u5b98\u65b9\u56e2\u961f\u51fa\u624b\uff0c\u8865\u9f50\u539f\u751fHook\u77ed\u677f](https://juejin.cn/post/7094424941541457933)\\n - [React Hooks \u7684\u539f\u7406\uff0c\u6709\u7684\u7b80\u5355\u6709\u7684\u4e0d\u7b80\u5355](https://juejin.cn/post/7075701341997236261)\\n - [\u4ecereact hooks\u201c\u95ed\u5305\u9677\u9631\u201d\u5207\u5165\uff0c\u6d45\u8c08react hooks](https://juejin.cn/post/6844904193044512782)\\n - [React+Ts\uff0c\u8fd9\u6837\u5b66\u8d77\u6765\u786e\u5b9e\u7b80\u5355\uff01\uff01\uff01](https://mp.weixin.qq.com/s/7LXeQomcHK4zcuRqB32JDg)\\n - [React 18 \u8d85\u5168\u5347\u7ea7\u6307\u5357](https://mp.weixin.qq.com/s/byD6xm3O6MzX8kksjBmqpA)\\n - [\u963f\u91cc\u4e09\u9762\uff1a\u7075\u9b42\u62f7\u95ee\u2014\u2014\u6709react fiber\uff0c\u4e3a\u4ec0\u4e48\u4e0d\u9700\u8981vue fiber\u5462](https://juejin.cn/post/7077545184807878692)\\n - [\\\\[\u5efa\u8bae\u6536\u85cf\\\\] \u4f60\u60f3\u77e5\u9053\u7684Vue3\u6838\u5fc3\u6e90\u7801\u8fd9\u91cc\u90fd\u6709](https://juejin.cn/post/6982004709145968677)\\n - [\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React](https://juejin.cn/post/6978654109893132318)\\n - [\u624b\u5199React\u7684Fiber\u67b6\u6784\uff0c\u6df1\u5165\u7406\u89e3\u5176\u539f\u7406](https://juejin.cn/post/6844904197008130062)\\n - [React Fiber \u6e90\u7801\u89e3\u6790](https://juejin.cn/post/6859528127010471949)\\n - [\u8d70\u8fdbReact Fiber\u7684\u4e16\u754c](https://juejin.cn/post/6943896410987659277)\\n - [\u524d\u7aef\u5de5\u7a0b\u5e08\u7684\u81ea\u6211\u4fee\u517b\uff1aReact Fiber \u662f\u5982\u4f55\u5b9e\u73b0\u66f4\u65b0\u8fc7\u7a0b\u53ef\u63a7\u7684](https://juejin.cn/post/6911681589558640654)\\n - [React Fiber\u5f88\u96be\uff1f\u516d\u4e2a\u95ee\u9898\u52a9\u4f60\u7406\u89e3 React Fiber](https://juejin.cn/post/6984949525928476703)\\n- Vite \u6e90\u7801\\n - \u2b50\ufe0f [\u6df1\u5165\u6d45\u51fa Vite](https://juejin.cn/book/7050063811973218341)\\n - [\u8be6\u89e3 Vite \u4f9d\u8d56\u9884\u6784\u5efa\u6d41\u7a0b](https://mp.weixin.qq.com/s/UD0-7rWtOAxMuDpOR77gug)\\n - [\u6388\u4eba\u4e88\u6e14\uff0cVSCode \u5982\u4f55\u8c03\u8bd5 Vite \u4ee3\u7801](https://mp.weixin.qq.com/s/bf11t1rH6NllKDA0IKR9Lw)\\n - [\u6572\u4e0b vite \u547d\u4ee4\u540e\uff0cserver \u505a\u4e86\u54ea\u4e9b\u4e8b](https://mp.weixin.qq.com/s/3dfbu7lZJLd6cJSp9XLcVQ)\\n- \u5305\u7ba1\u7406\u65b9\u6848\u3001PNPM\\n- Arch Linux\\n - [10 Practical Grep Command Examples for Developers](https://linuxhandbook.com/grep-command-examples/)\\n - [The Linux Command Handbook \u2013 Learn Linux Commands for Beginners](https://www.freecodecamp.org/news/the-linux-commands-handbook/#the-linux-grep-command)\\n- \u5982\u4f55\u642d\u5efa\u4e2a\u4eba\u535a\u5ba2\\n - \u4f7f\u7528 Next.js\uff0c\u5f00\u7bb1\u5373\u7528\u6587\u4ef6\u7cfb\u7edf\u8def\u7531\u3001\u9759\u6001\u7ad9\u70b9\u751f\u6210\uff08SSG\uff09\\n - https://nextjs.org/learn/basics/create-nextjs-app\\n- \u5de5\u7a0b\u5316\u65b9\u6848\u603b\u7ed3\u4e0b\\n - [2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357](https://zhuanlan.zhihu.com/p/403970666)\\n - [2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48](https://juejin.cn/post/7017710911443959839)\\n - [\ud83d\udd25\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb](https://juejin.cn/post/7023242274876162084)\\n - [Next.js webpack \u914d\u7f6e](https://github.com/vercel/next.js/blob/canary/packages/next/build/webpack-config.ts)\\n- \u9759\u6001\u9875\u9762\u90e8\u7f72\u65b9\u6848\\n - \u4e0a\u4f20\u963f\u91cc\u4e91 OSS\\n https://github.com/Menci/upload-to-oss\\n- [\u9762\u5411\u672a\u6765\u7684\u524d\u7aef\u5f00\u53d1\u6a21\u5f0f - \u5199\u4e8e2021\u5e74](https://juejin.cn/post/6992172458748936222)\\n- [\u4ece\u96f6\u642d\u5efaWebpack5-react\u811a\u624b\u67b6(\u9644\u6e90\u7801)](https://juejin.cn/post/6990538424545443854)\\n- [\u624b\u5199\u5404\u79cd\u6e90\u7801](https://github.com/JinJieTan/Peter-)\\n\\n## \ud83d\udcd2 \u63a8\u8350\u9605\u8bfb\\n\\n- [2021 \u5e74 TypeScript + React \u5de5\u7a0b\u5316\u6307\u5357](https://zhuanlan.zhihu.com/p/403970666)\\n- [\u5b66\u4e60 Webpack5 \u4e4b\u8def\uff08\u4f18\u5316\u7bc7\uff09- \u8fd1 7k \u5b57](https://juejin.cn/post/6996816316875161637#heading-15)\\n- https://github.com/webpack/webpack-dev-middleware\\n- [webpack-dev-middleware \u63d2\u4ef6\u7684\u4f7f\u7528](https://segmentfault.com/a/1190000011761306)\\n- [webpack-dev-middleware \u6e90\u7801\u89e3\u8bfb](https://juejin.cn/post/6844904099985489927)\\n- [\\\\[\u4e07\u5b57\u603b\u7ed3\\\\] \u4e00\u6587\u5403\u900f Webpack \u6838\u5fc3\u539f\u7406](https://juejin.cn/post/6949040393165996040#heading-2)\\n- [\u8ddf\u6751\u957f\u8001\u5e08\u505a\u3010Vue DevUI \u5f00\u6e90\u6307\u5357\u3011\u76f4\u64ad\u4e00\u4e2a\u6708\u7684\u611f\u53d7](https://juejin.cn/post/7020678344219820068)\\n- [\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 008: webpack HMR \u5b9e\u73b0\u7684\u6838\u5fc3\u539f\u7406](https://juejin.cn/post/7021167384484380709)\\n- [\u57fa\u4e8e Lerna \u5b9e\u73b0 Monorepo \u9879\u76ee\u7ba1\u7406](https://juejin.cn/post/7030207667457130527)\\n- [\u624b\u6478\u624b\u6559\u4f60\u7528Vue3+Typescript+Rollup+Tailwinds\u6253\u9020\u63d2\u62d4\u5f0f\u7684\u4e1a\u52a1\u7ec4\u4ef6\u5e93](https://juejin.cn/post/6959115798841393160)\\n- [\u4e00\u6587\u5e26\u4f60\u5feb\u901f\u4e0a\u624bRollup](https://juejin.cn/post/6869551115420041229)\\n- \ud83c\udf1b [\u624b\u6478\u624b\u5b66\u4f1a\u642d\u5efa\u4e00\u4e2a TS+Rollup \u7684\u521d\u59cb\u5f00\u53d1\u73af\u5883](https://juejin.cn/post/7029525775321661470)\\n- [\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1a\u5982\u4f55\u5b9e\u73b0\u7ec4\u4ef6\u7684\u6309\u9700\u6253\u5305\ud83d\udce6](https://juejin.cn/post/7029292539479867429)\\n- [\u3010\u6211\u8981\u505a\u5f00\u6e90\u3011Vue DevUI\u5f00\u6e90\u6307\u535708\uff1aMonorepo\u6539\u9020](https://juejin.cn/post/7029262501833359368)\\n- [coding\u4f18\u96c5\u6307\u5357\uff1a\u51fd\u6570\u5f0f\u7f16\u7a0b](https://juejin.cn/post/6974377246140301342)\\n- [\u8fd9\u4e9b\u9ad8\u9636\u7684\u51fd\u6570\u6280\u672f\uff0c\u4f60\u638c\u63e1\u4e86\u4e48](https://juejin.cn/post/6892886272377880583)\\n- \ud83c\udf1b [\u4f7f\u7528Docker Compose\u3001Nginx\u3001SSH\u548cGithub Actions\u5b9e\u73b0\u524d\u7aef\u81ea\u52a8\u5316\u90e8\u7f72\u6d4b\u8bd5\u673a](https://juejin.cn/post/7028222480326066213)\\n- [\u5982\u4f55\u63a8\u52a8\u524d\u7aef\u56e2\u961f\u7684\u57fa\u7840\u8bbe\u65bd\u5efa\u8bbe](https://juejin.cn/post/6844904093434019853)\\n- \u2b50\ufe0f [Element UI\u6e90\u7801\u4e2d\u5b66\u5230\u7684\u6280\u5de7](https://juejin.cn/post/6966491047257964575)\\n- [\u8ddf\u7740\u6e90\u7801\u4e86\u89e3Webpack\u7f16\u8bd1\u6d41\u7a0b](https://juejin.cn/post/7026658230365323301)\\n- [\u9762\u8bd5\u5b98\uff1awebpack\u539f\u7406\u90fd\u4e0d\u4f1a\uff1f](https://juejin.cn/post/6859538537830858759)\\n- [\u8ba9 AST \u64cd\u4f5c\u50cf\u547c\u5438\u4e00\u6837\u81ea\u7136](https://juejin.cn/post/7026671646555504676)\\n- [\u4ece\u96f6\u64b8\u4e00\u4e2aCLI\u547d\u4ee4\u884c\u811a\u624b\u67b6\u5de5\u5177](https://juejin.cn/post/6920044884594425864)\\n- [\u4ece Element UI \u6e90\u7801\u7684\u6784\u5efa\u6d41\u7a0b\u6765\u770b\u524d\u7aef UI \u5e93\u8bbe\u8ba1](https://juejin.cn/post/6844904197863964685)\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0a\uff09](https://juejin.cn/post/6943430853972852750)\\n- [\u90a3\u4e9b\u5e74\u9519\u8fc7\u7684React\u7ec4\u4ef6\u5355\u5143\u6d4b\u8bd5\uff08\u4e0b\uff09](https://juejin.cn/post/6946008649026240519)\\n- [git hooks \u7684\u5e93 husky \u6e90\u7801\u8fd9\u4e48\u7b80\u5355\uff0c\u4f60\u4e5f\u53ef\u4ee5\u5b9e\u73b0\u4e00\u4e2a\uff01](https://juejin.cn/post/7026274816734789663)\\n- [\u300cReact18\u65b0\u7279\u6027\u300d\u6df1\u5ea6\u89e3\u8bfb\u4e4buseMutableSource](https://juejin.cn/post/7026210002042011655)\\n- [\u3010V8\u6e90\u7801\u8865\u5145\u7bc7\u3011\u4ece\u4e00\u9053\u8ba9\u6211\u5931\u7720\u7684 Promise \u9762\u8bd5\u9898\u5f00\u59cb\uff0c\u6df1\u5165\u5206\u6790 Promise \u5b9e\u73b0\u7ec6\u8282](https://juejin.cn/post/6953452438300917790)\\n- [\\\\[\u63a2\u7d22\\\\]Webpack DevServer\u548cHMR\u539f\u7406](https://juejin.cn/post/6966422095274180639)\\n- [\u3010\u4e07\u5b57\u3011\u900f\u8fc7\u5206\u6790 webpack \u9762\u8bd5\u9898\uff0c\u6784\u5efa webpack5.x \u77e5\u8bc6\u4f53\u7cfb](https://juejin.cn/post/7023242274876162084)\\n- [\u4ece\u5934\u5f00\u59cb\uff0c\u5f7b\u5e95\u7406\u89e3\u670d\u52a1\u7aef\u6e32\u67d3\u539f\u7406(8\u5343\u5b57\u6c47\u603b\u957f\u6587)](https://juejin.cn/post/6844903881390964744)\\n- [\u5256\u6790 Webpack SplitChunksPlugin \u6e90\u7801: \u5b66\u5b8c\u4f60\u4e5f\u80fd\u5199\u4e00\u4e2a](https://juejin.cn/post/6982157120594509837)\\n- [\u4e00\u70b9\u5173\u4e8e\u670d\u52a1\u7aef\u6e32\u67d3\u7684\u5206\u4eab](https://juejin.cn/post/7025164660751990798)\\n- [\u4ece 0 \u6784\u5efa\u81ea\u5df1\u7684\u811a\u624b\u67b6/CLI\u77e5\u8bc6\u4f53\u7cfb\uff08\u4e07\u5b57\uff09 \ud83d\udee0](https://juejin.cn/post/6966119324478079007)\\n- [\u624b\u5199\u4e00\u4e2a\u865a\u62dfDOM\u5e93\uff0c\u5f7b\u5e95\u8ba9\u4f60\u7406\u89e3diff\u7b97\u6cd5](https://juejin.cn/post/6984939221681176607)\\n- [10\u4e2a\u7b80\u5355\u7684\u6280\u5de7\u8ba9\u4f60\u7684 vue.js \u4ee3\u7801\u66f4\u4f18\u96c5\ud83c\udf4a](https://juejin.cn/post/6854573215969181703)\\n- [\u5728 Vue \u4e2d\u4e3a\u4ec0\u4e48\u4e0d\u63a8\u8350\u7528 index \u505a key](https://juejin.cn/post/7026119446162997261)\\n- [\u505a\u4e86\u4e24\u5e74\u524d\u7aef\u5f00\u53d1\uff0c\u5e73\u65f6\u5c31\u662f\u62ff Vue \u5199\u5199\u9875\u9762\u548c\u7ec4\u4ef6\uff0c\u7b80\u5386\u7684\u9879\u76ee\u7ecf\u5386\u5e94\u8be5\u600e\u4e48\u5199\u5f97\u597d\u770b\uff1f](https://www.zhihu.com/question/384048633/answer/1134746899)\\n- [2021 \u5e74\u5f53\u6211\u4eec\u804a\u524d\u7aef\u90e8\u7f72\u65f6\uff0c\u6211\u4eec\u5728\u804a\u4ec0\u4e48](https://juejin.cn/post/7017710911443959839)\\n- [\u5206\u4eab\u4e00\u5e74\u4ee5\u6765\u7684Electron\u5f00\u53d1\u7ecf\u9a8c](https://juejin.cn/post/7016534471734198279)\\n- [\u300c\u524d\u7aef\u8fdb\u9636\u300d\u9ad8\u6027\u80fd\u6e32\u67d3\u5341\u4e07\u6761\u6570\u636e(\u65f6\u95f4\u5206\u7247)](https://juejin.cn/post/6844903938894872589)\\n- \u2b50\ufe0f [\u624b\u5199\u7cfb\u5217-\u5b9e\u73b0\u4e00\u4e2a\u94c2\u91d1\u6bb5\u4f4d\u7684 React](https://juejin.cn/post/6978654109893132318)\\n- [\u624b\u5199\u7cfb\u5217-\u8fd9\u4e00\u6b21\uff0c\u5f7b\u5e95\u641e\u61c2 Promise](https://juejin.cn/post/6973155726302642206)\\n- [50\u884c\u4ee3\u7801\u4e32\u884cPromise\uff0ckoa\u6d0b\u8471\u6a21\u578b\u539f\u6765\u662f\u8fd9\u4e48\u5b9e\u73b0\uff1f](https://juejin.cn/post/7005375860509245471)\\n- [\u73a9\u8f6c node \u5b50\u8fdb\u7a0b \u2014 child_process](https://juejin.cn/post/6882290865763680264)\\n- [\u6df1\u5165\u5256\u6790\uff1aVue\u6838\u5fc3\u4e4b\u865a\u62dfDOM](https://juejin.cn/post/6844903895467032589)\\n- \u2b50\ufe0f [\u4ece\u96f6\u5f00\u59cb\u914d\u7f6e react + typescript\uff08\u4e00\uff09\uff1adotfiles](https://juejin.cn/post/6844904055618158600)\\n- [Webpack \u6848\u4f8b \u2014\u2014 vue-loader \u539f\u7406\u5206\u6790](https://juejin.cn/post/6937125495439900685)\\n- [TypeScript \u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217](https://juejin.cn/post/7025213391618703367)\\n- [\u7528ts\u7c7b\u578b\u7cfb\u7edf\u5b9e\u73b0\u6590\u6ce2\u90a3\u5951\u6570\u5217](https://juejin.cn/post/6965320374451961886)\\n- [\u521d\u6b65\u5c1d\u8bd5 tauri\uff0c\u5e76\u4e14\u4e0e electron.js \u5bf9\u6bd4](https://juejin.cn/post/7059400669916037133)\\n- [\u548c\u5927\u591a\u6570\u7684\u524d\u7aef\u5f00\u53d1\u8005\u76f8\u6bd4\uff0c\u6211\u5e76\u6ca1\u6709\u9009\u62e9node.js\u505acli\u800c\u6295\u9760\u4e86golang](https://juejin.cn/post/7057178581897740319)\\n- [React Fiber Architecture](https://github.com/acdlite/react-fiber-architecture)\\n- [linux\u547d\u4ee4\u603b\u7ed3\u4e4blsof\u547d\u4ee4](https://www.cnblogs.com/ginvip/p/6367939.html)\\n- [Machine Learning For Front-End Developers With Tensorflow.js](https://www.smashingmagazine.com/2019/09/machine-learning-front-end-developers-tensorflowjs/)\\n- [javascript\u768423\u79cd\u8bbe\u8ba1\u6a21\u5f0f](https://mp.weixin.qq.com/s/hP5YMgJTgaVIlaK-XJ3Bcw)\\n- [\u6211\u7684\u7b2c\u4e00\u6b21webpack\u4f18\u5316\uff0c\u9996\u5c4f\u6e32\u67d3\u4ece9s\u52301s](https://zhuanlan.zhihu.com/p/476712416)\\n- [\u5728\u9879\u76ee\u4e2d\u7528ts\u5c01\u88c5axios\uff0c\u4e00\u6b21\u5c01\u88c5\u6574\u4e2a\u56e2\u961f\u53d7\u76ca\ud83d\ude01](https://juejin.cn/post/7071518211392405541)\\n- [\u664b\u5347\uff0c\u5982\u4f55\u51cf\u5c11 50%+ \u7684\u7b54\u8fa9\u6750\u6599\u51c6\u5907\u65f6\u95f4\u3001\u8c03\u6574\u5fc3\u6001\uff08\u4e2a\u4eba\u7ecf\u9a8c\u603b\u7ed3\uff09](https://mp.weixin.qq.com/s/usMxG3cAowUtO3Lvn9VjsQ)\\n- [\u57fa\u4e8e TypeScript \u7406\u89e3\u7a0b\u5e8f\u8bbe\u8ba1\u7684 SOLID \u539f\u5219](https://mp.weixin.qq.com/s/mz5S1iiRWkk-KKJg5lOOJQ)\\n- \u2b50\ufe0f [\u5341\u9053\u817e\u8baf\u7b97\u6cd5\u771f\u9898\u89e3\u6790\uff01](https://mp.weixin.qq.com/s/dg4WI2eJzh6b3OAzHN0q3A)\\n- \u2b50\ufe0f [\u817e\u8baf\u4e91\u540e\u7aef15\u8fde\u95ee\uff01](https://mp.weixin.qq.com/s/aMYJODhtWsBt9CTJxySQEQ)\\n- \u2b50\ufe0f [\u5b57\u8282\u56fd\u9645\u652f\u4ed8\u5341\u8fde\u95ee](https://mp.weixin.qq.com/s/0kUf1ujPUuieyOSMsBIzaw)\\n- [\u5982\u4f55\u6210\u4e3a\u4e00\u4e2a\u4f18\u79c0\u7684\u590d\u5236\u7c98\u8d34\u5de5\u7a0b\u5e08](https://juejin.cn/post/7080032725477883917)\\n- [docker\u6587\u4ef6\u5939\u6620\u5c04\u7684\u4e24\u79cd\u65b9\u5f0f---\u4e3b\u673a\u5377\u6620\u5c04\u548c\u5171\u4eab\u6587\u4ef6\u5939\u6620\u5c04](https://blog.csdn.net/zhydream77/article/details/81909706)\\n- [\u4e3a\u4ec0\u4e48golang\u6ca1\u6709min/max\u4ee5\u53ca\u4e09\u5143\u64cd\u4f5c\u7b26](https://studygolang.com/articles/25997?fr=sidebar)\\n- [\u7f16\u8bd1 ts \u4ee3\u7801\u7528 tsc \u8fd8\u662f babel](https://juejin.cn/post/7084882650233569317)\\n- [\u5982\u679c\u6ca1\u6709 package-lock.json\uff0c\u90a3\u5c06\u5982\u4f55](https://juejin.cn/post/7031122959637217310)\\n- [\u5de5\u7a0b\u5316\u77e5\u8bc6\u5361\u7247 023\uff1anode_modules \u7248\u672c\u91cd\u590d\u7684\u56f0\u5883](https://juejin.cn/post/7030084290989948935)\\n- [\u3010\u6df7\u6dc6\u7cfb\u5217\u3011\u4e09\u95ee\uff1anpx\u3001npm\u3001cnpm\u3001pnpm\u533a\u522b\u4f60\u641e\u6e05\u695a\u4e86\u5417\uff1f](https://juejin.cn/post/7083468345579667493)\\n- [Webpack\u7ec4\u4ef6\u5e93\u6253\u5305\u8d85\u8be6\u7ec6\u6307\u5357](https://juejin.cn/post/7082738107237433375)\\n- [\u5199\u597d JavaScript \u5f02\u6b65\u4ee3\u7801\u7684\u51e0\u4e2a\u63a8\u8350\u505a\u6cd5](https://mp.weixin.qq.com/s/XWZsKQECcsHAlE9cyqi9Eg)\\n- [Node.js \u8fdb\u9636 - \u591a\u6587\u4ef6 Stream \u5408\u5e76\uff0c\u4e32\u884c\u548c\u5e76\u53d1\u4e24\u79cd\u6a21\u5f0f\u5b9e\u73b0](https://mp.weixin.qq.com/s/WisEGFz2yn_ZeekViofMnA)\\n- [\u670d\u52a1\u7aef\u6e32\u67d3SSR\u53ca\u5b9e\u73b0\u539f\u7406](https://juejin.cn/post/7046898330000949285)\\n- [\u624b\u6478\u624b\u670d\u52a1\u7aef\u6e32\u67d3-react](https://mp.weixin.qq.com/s/lyff2svfHh4rdsWRL4H5uA)\\n- [\u5982\u4f55\u5728\u9879\u76ee\u4e2d\u7528\u597d TypeScript](https://juejin.cn/post/7058868160706904078)\\n- [\u9009\u62e9\u7b2c\u4e09\u65b9 NPM \u5305\u65f6\u7684 5 \u6761\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/kGMsNmIXlT25NfRrifjnTQ)\\n- [\u7528 Redux \u505a\u72b6\u6001\u7ba1\u7406\uff0c\u771f\u7684\u5f88\u7b80\u5355\ud83e\udd86](https://juejin.cn/post/7071066976830881823)\\n- [React 18 \u5168\u89c8](https://mp.weixin.qq.com/s/t3dYc3Md1dpiv1vaFa5plA)\\n- [React 18 \u5bf9 Hooks \u7684\u5f71\u54cd](https://mp.weixin.qq.com/s/fgT7Kxs_0feRx4TkBe6G5Q)\\n- [React \u7684\u5fc3\u667a\u6a21\u578b](https://mp.weixin.qq.com/s/GatHpP3BRLV_I48MfpzR4A)\\n- [\u4f60\u4e0d\u77e5\u9053\u7684 React v18 \u7684\u4efb\u52a1\u8c03\u5ea6\u673a\u5236](https://mp.weixin.qq.com/s/qyr6MnPtvnELDSbPJ2VtIw)\\n- [\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0a)](https://segmentfault.com/a/1190000041683300)\\n- [\u4e00\u4e9b\u5173\u4e8ereact\u7684keep-alive\u529f\u80fd\u76f8\u5173\u77e5\u8bc6\u5728\u8fd9\u91cc(\u4e0b)](https://segmentfault.com/a/1190000041683421)\\n- [Node.js 18 \u65b0\u7279\u6027\u89e3\u8bfb](https://zhuanlan.zhihu.com/p/502951532)\\n- [\u90a3\u4e9b\u4f60\u5e94\u8be5\u8bf4\u518d\u89c1\u7684 npm \u7956\u4f20\u8001\u5e93](https://zhuanlan.zhihu.com/p/415361629)\\n- [\u524d\u7aef\u7b97\u6cd5\u7cfb\u7edf\u7ec3\u4e60: \u6808\u548c\u961f\u5217\u7bc7](https://mp.weixin.qq.com/s/tWbeOTx0JpiZOD0YaC1P2A)\\n- [\u3010\u7b2c2602\u671f\u3011\u8bbe\u7f6e NPM Registry \u7684 4 \u79cd\u59ff\u52bf](https://mp.weixin.qq.com/s/MYLi4mSgoi5KXj4-_OgT3A)\\n- [\u300c\u624b\u6478\u624b\u8bbe\u8ba1\u6a21\u5f0f\u7cfb\u5217\u300d \u4eab\u5143\u6a21\u5f0f\u4e0e\u8d44\u6e90\u6c60](https://juejin.cn/post/6844903919995322382)\\n- [\u6211\u5728\u5de5\u4f5c\u4e2d\u5199React\uff0c\u5b66\u5230\u4e86\u4ec0\u4e48\uff1f\u6027\u80fd\u4f18\u5316\u7bc7](https://juejin.cn/post/6889247428797530126)\\n- [React Hooks \u6700\u4f73\u5b9e\u8df5](https://juejin.cn/post/6844904165500518414)\\n- [\u624b\u5199 CSS-modules \u6765\u6df1\u5165\u7406\u89e3\u5b83\u7684\u539f\u7406](https://mp.weixin.qq.com/s/3xhNcfI4pTm0n-naSsOBwg)\\n- [\u4e0b\u96c6\u300dReact\u6027\u80fd\u4f18\u5316\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://www.bilibili.com/video/BV1j44y1g74m)\\n- [Umi 4 \u7279\u6027\u5408\u96c6\uff0c\u6bd4 Vite \u8fd8\u8981\u5feb\uff1f](https://mp.weixin.qq.com/s/-B5M7pjIWZzFNvq-hyr1Mw)\\n- [\u4f60\u53ef\u80fd\u5e76\u6ca1\u6709\u7406\u89e3\u7684 babel \u914d\u7f6e\u7684\u539f\u7406](https://juejin.cn/post/7094296981001994277)\\n- [\u4ece\u96f6\u5f00\u59cb\u53d1\u5e03\u81ea\u5df1\u7684NPM\u5305](https://juejin.cn/post/7052307032971411463)\\n- [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4b\u521d\u8bc6Docker\u5bb9\u5668\u5316\u90e8\u7f72](https://juejin.cn/post/7069609959985512484)\\n- [\u524d\u7aef\u62a2\u996d\u7897\u7cfb\u5217\u4e4bDocker\u8fdb\u9636\u90e8\u7f72](https://juejin.cn/post/7083009375387779085)\\n- [\u3010\u5de5\u7a0b\u5316\u3011\u63a2\u7d22webpack5\u4e2d\u7684Module Federation](https://mp.weixin.qq.com/s/zt7x2KjMT_cWvLVVa2-Hww)\\n- [NodeJs\u8fdb\u9636\u5f00\u53d1\u3001\u6027\u80fd\u4f18\u5316\u6307\u5357](https://juejin.cn/post/7095354780079357966)\\n- [Tree shaking\u95ee\u9898\u6392\u67e5\u6307\u5357\u6765\u5566](https://mp.weixin.qq.com/s/P3mzw_vmOR6K_Mj-963o3g)\\n- [\u5982\u4f55\u8bbe\u8ba1\u66f4\u4f18\u96c5\u7684 React \u7ec4\u4ef6](https://mp.weixin.qq.com/s/FPupefVg4zphOfIERZOvHQ)\\n- [React \u5e76\u53d1\u6e32\u67d3\u7684\u524d\u4e16\u4eca\u751f](https://mp.weixin.qq.com/s/01sTK6w4BFUzoRc2NKCs1w)\\n- [\u4f7f\u7528 Next.js \u548c MDX \u6784\u5efa\u4f60\u81ea\u5df1\u7684\u535a\u5ba2](https://www.freecodecamp.org/news/how-to-build-your-own-blog-with-next-js-and-mdx/)\\n- [TCP \u91cd\u4f20\u3001\u6ed1\u52a8\u7a97\u53e3\u3001\u6d41\u91cf\u63a7\u5236\u3001\u62e5\u585e\u63a7\u597d\u96be\uff1f\u770b\u5b8c\u56fe\u89e3\u5c31\u4e0d\u6101\u4e86](https://mp.weixin.qq.com/s/toQUgqJHeUbFZMtxfzFCxw)\\n- [TCP \u5c31\u6ca1\u4ec0\u4e48\u7f3a\u9677\u5417\uff1f](https://mp.weixin.qq.com/s/9kHoRk6QIYOFUR_PCmHY6g)\\n- [\u3010\u7b2c2618\u671f\u3011\u624b\u628a\u624b\u6559\u4f60\u5b9a\u5236\u4e00\u5957\u9002\u5408\u56e2\u961f\u7684\u5fae\u524d\u7aef\u4f53\u7cfb](https://mp.weixin.qq.com/s/ovwjufnPmCoYNLMkv5xv2g)\\n- [\u524d\u7aef\u5fc5\u5b66\u7684\u52a8\u753b\u5b9e\u73b0\u601d\u8def\uff0c\u9ad8\u903c\u683c\u7684\u6548\u679c\u8001\u677f\u770b\u4e86\u90fd\u4f1a\u5927\u58f0\u79f0\u8d5e](https://juejin.cn/post/7099402445989609479)\\n- [\u3010\u7b2c2617\u671f\u3011React \u7ec4\u4ef6\u5e93 CSS \u6837\u5f0f\u65b9\u6848\u5206\u6790](https://mp.weixin.qq.com/s/LSlgpazCwtceQWjHsMPCAg)\\n- [\u3010\u7b2c2616\u671f\u3011\u89e3\u91caJavaScript\u7684\u5185\u5b58\u7ba1\u7406](https://mp.weixin.qq.com/s/X4ni2i9bvolHGfCdf3SzIA)\\n- [\u4ece Turborepo \u770b Monorepo \u5de5\u5177\u7684\u4efb\u52a1\u7f16\u6392\u80fd\u529b](https://mp.weixin.qq.com/s/OrekHmMrn8UlisTrvt3MNA)\\n- [\u89e3\u51b3\u524d\u7aef\u5e38\u89c1\u95ee\u9898\uff1a\u7ade\u6001\u6761\u4ef6](https://mp.weixin.qq.com/s/GryL1QVARtMB8-WIzd7xQQ)\\n- [Google \u6700\u65b0\u7684\u6027\u80fd\u4f18\u5316\u65b9\u6848\uff0cLCP \u63d0\u534730%\uff01](https://mp.weixin.qq.com/s/3v54arsDRRw6agyr3MtPRg)\\n- [React useEvent\uff1a\u7816\u5bb6\u8bf4\u7684\u6ca1\u95ee\u9898](https://mp.weixin.qq.com/s/-6bQKIjH6WPcfuiCFtsjng)\\n- [\u88abdiss\u6027\u80fd\u5dee\uff0cDan\u8fde\u591c\u4f18\u5316React\u65b0\u6587\u6863](https://juejin.cn/post/7102328973820067877)\\n- [Node.js \u8c03\u8bd5\u4e00\u8def\u8d70\u6765\u7ecf\u5386\u4e86\u4ec0\u4e48](https://juejin.cn/post/7102233142567632933)\\n- [\u63a8\u8350\u4e00\u4e2a\u524d\u7aef\u6280\u672f\u9009\u578b\u795e\u5668](https://mp.weixin.qq.com/s/g1fr1fnGspi7SETyP9B6rA)\\n- [\u6700\u9ad8\u6027\u80fd\u7684\u5305\u7ba1\u7406\u5668-pnpm](https://mp.weixin.qq.com/s/2OXIGB5qQFc2isIxhm33bg)\\n- [\u5e76\u53d1\u6e32\u67d3\u4f18\u5316\uff1a\u8ba9\u6587\u4ef6\u6811\u7684\u6e32\u67d3\u53c8\u5feb\u53c8\u7a33](https://mp.weixin.qq.com/s/3yy9V5HMDWPFwEf1cyL-lw)\\n- [\u770b\u4e869\u4e2a\u5f00\u6e90\u7684 Vue3 \u7ec4\u4ef6\u5e93\uff0c\u53d1\u73b0\u4e86\u8fd9\u4e9b\u524d\u7aef\u7684\u6d41\u884c\u8d8b\u52bf](https://juejin.cn/post/7092766235380678687)\\n- [\u809d\u4e86\u4e00\u4e2a\u6708\u7684 DDD\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1](https://mp.weixin.qq.com/s/jU0awhez7QzN_nKrm4BNwg)\\n- [\u6df1\u5165\u7406\u89e3 Linux CPU \u4e0a\u4e0b\u6587\u5207\u6362](https://mp.weixin.qq.com/s/KwmNzTdjMB-ljQ0ysEGalg)\\n- [\u9762\u8bd5\u5fc5\u5907\uff01TCP\u534f\u8bae\u7ecf\u5178\u5341\u4e94\u8fde\u95ee](https://mp.weixin.qq.com/s/hVh5PIVaOeLyErZDPXx6mg)\\n- [100 \u884c\u4ee3\u7801\u5b9e\u73b0 React \u8def\u7531](https://github.com/ashok-khanna/react-snippets/blob/main/Router.js)\\n- [\u7cbe\u8bfb\u300areact-snippets - Router \u6e90\u7801\u300b](https://juejin.cn/post/7100736564979826695)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u673a\u7968\u524d\u7aefSvelte\u751f\u4ea7\u5b9e\u8df5](https://mp.weixin.qq.com/s/QWwb8PXtdJJUKyicHRmBkw)\\n- [\u4ecearco-design\u7684collapse\u7ec4\u4ef6\u5206\u6790\u5982\u4f55\u5438\u6536\u5f00\u6e90\u9879\u76ee\u7684\u77e5\u8bc6](https://juejin.cn/post/7069772395610898462)\\n- [\u6a21\u5757\u8054\u90a6\u6d45\u6790](https://juejin.cn/post/7101457212085633054)\\n- [\u6211\u4eec\u662f\u600e\u4e48\u5728\u9879\u76ee\u4e2d\u843d\u5730qiankun\u7684](https://mp.weixin.qq.com/s/yu1tKtwneoTI9eSGS4us-g)\\n- [\u3010\u96f6\u57fa\u7840\u3011\u5145\u5206\u7406\u89e3WebGL\uff08\u4e09\uff09](https://mp.weixin.qq.com/s/ULY-_Vq-Jgb8aCbhyfqYHw)\\n- [Web3.0\u5f00\u53d1\u5165\u95e8](https://mp.weixin.qq.com/s/ROwTG6AC2pK5UN1dzY5x8w)\\n- [\u4ece\u6e90\u7801\u4e2d\u6765\uff0c\u5230\u4e1a\u52a1\u4e2d\u53bb\uff0cReact\u6027\u80fd\u4f18\u5316\u7ec8\u6781\u6307\u5357](https://mp.weixin.qq.com/s/DswfPb6J1w2B_MWj1TjyOg)\\n- [\u5256\u6790React\u6838\u5fc3\u8bbe\u8ba1\u539f\u7406\u2014Virtual Dom](https://mp.weixin.qq.com/s/l19wbHNIrhjyD0HwJwuvmQ)\\n- [\u3010\u7b2c2630\u671f\u3011javascript\u4e2d\u7684\u4f9d\u8d56\u6ce8\u5165](https://mp.weixin.qq.com/s/b15cyyg53lVKQ_TtR8hugQ)\\n- [\u3010\u524d\u7aef\u90e8\u7f72\u9644\u5f55\u4e00\u3011\u5199\u7ed9\u524d\u7aef\u7684 docker \u4f7f\u7528\u6307\u5357](https://mp.weixin.qq.com/s/sEvP3nLUOBwbSHP9mmT__A)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6838\u5fc3service\u7c7b\u521d\u59cb\u5316](https://mp.weixin.qq.com/s/f8mYoozpLrnSfWcRHTMa7A)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u63d2\u4ef6\u5316\u67b6\u6784\u6838\u5fc3](https://mp.weixin.qq.com/s/y-6Uf1hNBF19MabHEtqnJA)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u8fd0\u884c\u65f6\u63d2\u4ef6\u673a\u5236](https://mp.weixin.qq.com/s/4cZ3rJz4P5bSRSeXDbFoMQ)\\n- [UMI3\u6e90\u7801\u89e3\u6790\u7cfb\u5217\u4e4b\u6784\u5efa\u539f\u7406](https://mp.weixin.qq.com/s/2MsgPh9AZtUoJpsLLdOynQ)\\n- [\u5982\u4f55\u534e\u4e3d\u7684\u5b9e\u73b0\u4e00\u5957\u811a\u624b\u67b6 - \u4ee5umicli\u548c\u8f6c\u8f6czzcli\u4e3a\u4f8b](https://mp.weixin.qq.com/s/Sz8u6lzkL1nnpRxGrdbYJg)\\n- [Umi 4 \u7279\u6027 05\uff1a\u7a33\u5b9a\u767d\u76d2\u6027\u80fd\u597d\u7684 ESLint](https://www.yuque.com/antfe/featured/uf1bok)\\n- [\u6df1\u5165\u6d45\u51fa npm & yarn & pnpm \u5305\u7ba1\u7406\u673a\u5236](https://mp.weixin.qq.com/s/ZTI-8RI0l314Ki9oBxqRWw)\\n- [\u4e00\u6587\u5e26\u4f60\u8fdb\u5165\u5fae\u524d\u7aef\u4e16\u754c](https://mp.weixin.qq.com/s/LL6VZj36PKftbwaybBFmXg)\\n- [\u4e00\u4e2a\u4e09\u5c0f\u65f6\u7684 React Native \u901f\u6210\u8bfe](https://www.youtube.com/watch?v=VozPNrt-LfE)\\n- [\u524d\u7aef\u914d\u7f6e\u5316\u771f\u9999\uff5e\u4e0a\u73ed\u53c8\u591a\u4e8660%\u7684\u6478\ud83d\udc1f\u65f6\u95f4](https://juejin.cn/post/7098211898990002207)\\n- [20\u4e2aGitHub\u4ed3\u5e93\u52a9\u4f60\u6210\u4e3aReact\u5927\u5e08](https://juejin.cn/post/7104460511869141006)\\n- [Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u5982\u4f55\u5c06 template \u7f16\u8bd1\u6210 AST](https://juejin.cn/post/7116296421816418311)\\n- [Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6a21\u578b\u6811\u4f18\u5316](https://juejin.cn/post/7117085295798911012)\\n- [Vue \u7f16\u8bd1\u4e09\u90e8\u66f2\uff1a\u6700\u540e\u4e00\u66f2\uff0crender code \u751f\u6210](https://juejin.cn/post/7121504219588198413)\\n- [\u521d\u63a2 Vue3 \u7f16\u8bd1\u4e4b\u7f8e](https://juejin.cn/post/7124890499478978597)\\n- [Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u62bd\u8c61\u8bed\u6cd5\u6811\u7684\u751f\u6210](https://juejin.cn/post/7126712173014810661)\\n- [Vue3 \u7f16\u8bd1\u4e4b\u7f8e\uff0c\u7a7a\u767d\u5b57\u7b26\u7684\u5904\u7406](https://juejin.cn/post/7127074001897127943)\\n- [\u5728\u64b8 Vue \u7684 \u2318+K \u5524\u8d77\u83dc\u5355\u5e93\u65f6\uff0c\u6211\u5b66\u5230\u4e86\u5f88\u591a](https://mp.weixin.qq.com/s/5AnRvwmA-U76T52FR47w8Q)\\n- [Monorepo Handbook \u65b0\u9c9c\u51fa\u7089](https://turborepo.org/docs/handbook/what-is-a-monorepo)\\n- [Vue3\u7ec4\u4ef6\u5e93\u6253\u5305\u6307\u5357\uff0c\u4e00\u6b21\u751f\u6210esm\u3001esm-bundle\u3001commonjs\u3001umd\u56db\u79cd\u683c\u5f0f](https://juejin.cn/post/7152045316294836260)\\n- [Koa\u7684\u6d0b\u8471\u4e2d\u95f4\u4ef6\uff0cRedux\u7684\u4e2d\u95f4\u4ef6\uff0cAxios\u7684\u62e6\u622a\u5668\u8ba9\u4f60\u8ff7\u60d1\u5417\uff1f\u5b9e\u73b0\u4e00\u4e2a\u7cbe\u7b80\u7248\u7684\u5c31\u5f7b\u5e95\u641e\u61c2\u4e86](https://juejin.cn/post/6844904039608500237)\\n- [\u5b66\u4e60 Babel \u63d2\u4ef6\uff0c\u628a Vue2 \u8bed\u6cd5\u81ea\u52a8\u8f6c\u6210 Vue3\uff01](https://mp.weixin.qq.com/s/khS0wkBzQe4Lxn7jHK_0vA)\\n- [\u5982\u4f55\u7f16\u5199\u795e\u5947\u7684\u300c\u63d2\u4ef6\u673a\u5236\u300d\uff0c\u4f18\u5316\u57fa\u4e8e Antd Table \u5c01\u88c5\u8868\u683c\u7684\u6df7\u4e71\u4ee3\u7801](https://mp.weixin.qq.com/s/QgOslh1TwpU2cJubnNxYNw)\\n- [\u300c\u4e07\u5b57\u603b\u7ed3\u300d\ud83c\udf52\u52a8\u753b + \u5927\u767d\u8bdd\u8bb2\u6e05\u695aReact\u6e32\u67d3\u539f\u7406](https://juejin.cn/post/7121378029682556958)\\n- [\u803d\u8bef\u4f60\u5341\u5206\u949f\uff01\ud83c\udf83\u4f60\u53ef\u80fd\u7528\u5f97\u4e0a\u8fd9\u4e9bwebpack5\u65b0\u7279\u6027](https://juejin.cn/post/7123969545387114509)\\n- [\u5206\u5305\u738b\uff01\ud83e\udde8\u4f18\u5316\u9879\u76ee\u4f53\u79ef\u51cf\u5c1120%\uff01](https://juejin.cn/post/7118782372220567566)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u6a21\u578b\u5149\u6e90\u7ed3\u5408\u751f\u6210\u660e\u6697\u53d8\u5316\u7684\u521b\u610f\u9875\u9762-\u5149\u4e0e\u5f71\u4e4b\u8bd7 \ud83d\udca1](https://juejin.cn/post/7148969678642102286)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0b\uff09](https://juejin.cn/post/7146383940931026958)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u57fa\u7840\u5165\u95e8\uff08\u4e0a\uff09](https://juejin.cn/post/7145064095178293285)\\n- [\u26a1\ufe0f The Cost Of JavaScript (2017 - 2023)](https://supercodepower.com/the-cost-of-javascript)\\n- [\ud83d\uddc2 \u524d\u7aef\u7248\u672c\u517c\u5bb9\u95ee\u9898\u7684\u63a2\u7d22](https://supercodepower.com/fontend-target)\\n- [\ud83d\uddc2 \u5bf9 web.dev \u6240\u6709 blog \u7684\u6574\u7406\u4e0e\u5f52\u6863](https://supercodepower.com/web-dev-blog)\\n- [\ud83e\udd2f \u6ca1 2 \u5e74 React Native \u5f00\u53d1\u7ecf\u9a8c\uff0c\u4f60\u90fd\u9047\u4e0d\u5230\u8fd9\u4e9b\u5751](https://supercodepower.com/react-native-tweet)\\n- [Element Plus \u7ec4\u4ef6\u5e93\u76f8\u5173\u6280\u672f\u63ed\u79d8\uff1a2. \u7ec4\u4ef6\u5e93\u5de5\u7a0b\u5316\u5b9e\u6218\u4e4b Monorepo \u67b6\u6784\u642d\u5efa](https://juejin.cn/post/7146183222425518093)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u57fa\u7840\u77e5\u8bc6\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146973901166215176)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u7b97\u6cd5\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146975493278367752)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u5de5\u7a0b\u5316\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146976516692410376)\\n- [\u300c\u5386\u65f68\u4e2a\u6708\u300d10\u4e07\u5b57\u524d\u7aef\u77e5\u8bc6\u4f53\u7cfb\u603b\u7ed3\uff08\u524d\u7aef\u6846\u67b6+\u6d4f\u89c8\u5668\u539f\u7406\u7bc7\uff09\ud83d\udd25](https://juejin.cn/post/7146996646394462239)\\n- [20\u4e2a\u5e38\u89c1\u7684\u524d\u7aef\u7b97\u6cd5\u9898\uff0c\u4f60\u5168\u90fd\u4f1a\u5417](https://juejin.cn/post/7158730050718662687)\\n- [\u4e00\u6587\u804a\u5b8c\u524d\u7aef\u9879\u76ee\u4e2d\u7684Babel\u914d\u7f6e](https://juejin.cn/post/7151653067593613320)\\n- [\u4ece package.json \u6765\u804a\u804a\u5982\u4f55\u7ba1\u7406\u4e00\u6b3e\u4f18\u79c0\u7684 Npm \u5305](https://juejin.cn/post/7126394898445500423)\\n- [\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def](https://juejin.cn/post/7157902763534319624)\\n- [\u770b\u4e00\u904d\u5c31\u7406\u89e3\uff1aIO\u6a21\u578b\u8be6\u89e3](https://mp.weixin.qq.com/s/bb7C6VNbq7REP9u8PsreSg)\\n- [\u9762\u8bd5\u5fc5\u5907\uff1a\u96f6\u62f7\u8d1d\u8be6\u89e3](https://mp.weixin.qq.com/s/qaUZ3AMA_dJkx2ZpyhJN2g)\\n- [\u5b9e\u6218\u603b\u7ed3\uff0118\u79cd\u63a5\u53e3\u4f18\u5316\u65b9\u6848\u7684\u603b\u7ed3](https://mp.weixin.qq.com/s/DGP1frbIlirZ_C8Vd0OmEA)\\n- [\u50bb\u74dc\u65b9\u5f0f\u5206\u6790\u524d\u7aef\u5e94\u7528\u7684\u4f53\u79ef](https://juejin.cn/post/7172001951784108040)\\n- [\u624b\u5199 Bundler: \u5b9e\u73b0\u4ee3\u7801\u6253\u5305\u3001 Tree Shaking](https://juejin.cn/book/7050063811973218341/section/7070419010021490702)\\n- [\u624b\u5199 Bundler: \u5b9e\u73b0 JavaScript AST \u89e3\u6790\u5668\u2014\u2014\u8bcd\u6cd5\u5206\u6790\u3001\u8bed\u4e49\u5206\u6790](https://juejin.cn/book/7050063811973218341/section/7066614663533821983)\\n- [\u3010\u7b2c2795\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u4e09\u7aef\u540c\u6784\u7bc7](https://mp.weixin.qq.com/s/1xY0hfcwJci1hr4TKUZMqg)\\n- [\u3010\u7b2c2785\u671f\u3011\u96ea\u7403\u8de8\u7aef\u67b6\u6784\u5efa\u8bbe\u4e4b\u8de8\u7aef\u5bb9\u5668\u7bc7](https://mp.weixin.qq.com/s/7WU1DDoMYQzXnlstz16QJA)\\n- [Vite \u7279\u6027\u548c\u90e8\u5206\u6e90\u7801\u89e3\u6790](https://mp.weixin.qq.com/s/19Ai1rbRoQxOBA5SXSNCAQ)\\n- [Rollup\u6e90\u7801\uff1a\u6a21\u5757\u6253\u5305\u4e0eTree-Shaking](https://juejin.cn/post/7021115814870810660)\\n- [Rollup \u4e0e Webpack \u7684 Tree-shaking](https://juejin.cn/post/7169004126469914654)\\n- [\u804a\u4e00\u804a\u5e38\u89c1\u7684\u6784\u5efa\u5de5\u5177\u5173\u4e8e\u63d2\u4ef6\u673a\u5236\u7684\u90a3\u4e9b\u901a\u7528\u5957\u8def](https://juejin.cn/post/7157902763534319624)\\n- [\u3010Webpack Plugin\u3011\u5199\u4e86\u4e2a\u63d2\u4ef6\u8ddf\u559c\u6b22\u7684\u5973\u751f\u8868\u767d\uff0c\u7ed3\u679c......\ud83d\ude2d\ud83d\ude2d\ud83d\ude2d](https://juejin.cn/post/7160467329334607908)\\n- [\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0a\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b](https://segmentfault.com/a/1190000012081469)\\n- [\u73a9\u8f6cwebpack\uff08\u4e00\uff09\u4e0b\u7bc7\uff1awebpack\u7684\u57fa\u672c\u67b6\u6784\u548c\u6784\u5efa\u6d41\u7a0b](https://segmentfault.com/a/1190000012099163)\\n- [\u3010\u4e2d\u7ea7/\u9ad8\u7ea7\u524d\u7aef\u3011\u4e3a\u4ec0\u4e48\u6211\u5efa\u8bae\u4f60\u4e00\u5b9a\u8981\u8bfb\u4e00\u8bfb Tapable \u6e90\u7801](https://juejin.cn/post/7164175171358556173)\\n- [\u4e8c\u5341\u5f20\u56fe\u7247\u5f7b\u5e95\u8bb2\u660e\u767dWebpack\u8bbe\u8ba1\u7406\u5ff5\uff0c\u4ee5\u770b\u61c2\u4e3a\u76ee\u7684](https://juejin.cn/post/7170852747749621791)\\n- [Webpack\u6df1\u5ea6\u8fdb\u9636\uff1a\u4e24\u5f20\u56fe\u5f7b\u5e95\u8bb2\u660e\u767d\u70ed\u66f4\u65b0\u539f\u7406\uff01](https://juejin.cn/post/7176963906844246074)\\n- [Webpack4\u7684\u538b\u7f29\u9636\u6bb5\u7684\u6027\u80fd\u4f18\u5316\u548c\u8e29\u5751](https://mp.weixin.qq.com/s/_MJq-88MNFyvDTxUw_lFiA)\\n- [Vue3\u751f\u547d\u5468\u671fHooks\u7684\u539f\u7406\u53ca\u5176\u4e0e\u8c03\u5ea6\u5668(Scheduler)\u7684\u5173\u7cfb](https://juejin.cn/post/7093880734246502414)\\n- [\u3010\ud83d\udc2f\u521d/\u4e2d\u7ea7\u524d\u7aef\u9762\u7ecf\u3011\u4e2d\u5c0f\u578b\u516c\u53f8\u9762\u8bd5\u65f6\u90fd\u4f1a\u95ee\u4e9b\u4ec0\u4e48](https://juejin.cn/post/7064740689178787871)\\n- [\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0a\uff09\uff1a\u4e3a\u4ec0\u4e48\u662f Zustand](https://juejin.cn/post/7177216308843380797)\\n- [\u8c08\u8c08\u590d\u6742\u5e94\u7528\u7684\u72b6\u6001\u7ba1\u7406\uff08\u4e0b\uff09\uff1a\u57fa\u4e8e Zustand \u7684\u6e10\u8fdb\u5f0f\u72b6\u6001\u7ba1\u7406\u5b9e\u8df5](https://juejin.cn/post/7182462103297458236)\\n- [\u3010\u597d\u6587\u5206\u4eab\u3011\u57fa\u4e8eJira\u7684\u8fd0\u7ef4\u53d1\u5e03\u5e73\u53f0\u7684\u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/Bf5JNQjki9xLVzioYPy5qg)\\n- [\u5982\u4f55\u4f7f\u7528jenkins\u642d\u5efa\u4e00\u4e2a\u4e2d\u5c0f\u4f01\u4e1a\u524d\u7aef\u9879\u76ee\u90e8\u7f72\u73af\u5883](https://mp.weixin.qq.com/s/pDXhIMFkyMuiVHB0l9gphw)\\n- [\u4e00\u6587\u6559\u4f60\u641e\u5b9a\u6240\u6709\u524d\u7aef\u9274\u6743\u4e0e\u540e\u7aef\u9274\u6743\u65b9\u6848\uff0c\u8ba9\u4f60\u4e0d\u518d\u8ff7\u60d8](https://juejin.cn/post/7129298214959710244)\\n- [\u8ddf\u7740\u6765\uff0c\u4f60\u4e5f\u53ef\u4ee5\u624b\u5199VueRouter](https://juejin.cn/post/6991640600533532679)\\n- [\u300c\u786c\u6838JS\u300d\u56fe\u89e3Promise\u8ff7\u60d1\u884c\u4e3a\uff5c\u8fd0\u884c\u673a\u5236\u8865\u5145](https://juejin.cn/post/6997968693414084644)\\n- [\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0a\uff09](https://juejin.cn/post/7007946894605287432)\\n- [\u300c\u524d\u7aef\u5de5\u7a0b\u56db\u90e8\u66f2\u300d\u6a21\u5757\u5316\u7684\u524d\u4e16\u4eca\u751f\uff08\u4e0b\uff09](https://juejin.cn/post/7012774158371127326)\\n- [\u4f60\u53ef\u80fd\u4e0d\u77e5\u9053\u7684 async\u3001await \u7ec6\u8282](https://mp.weixin.qq.com/s/aLQVpglTRA0bJGyCpXOD8Q)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u7269\u7406\u6548\u679c-\u78b0\u649e\u548c\u58f0\u97f3 \ud83d\udca5](https://juejin.cn/post/7200039970575941693)\\n- [Three.js \u8fdb\u9636\u4e4b\u65c5\uff1a\u65b0\u6625\u7279\u5178-Rabbit craft go \ud83d\udc07](https://juejin.cn/post/7191415427350659129)\\n- [\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300d\u81ea\u5df1\u52a8\u624b\u5b9e\u73b0\u4e00\u4e2aJSX\u8f6c\u6362](https://juejin.cn/post/7212235580104917053)\\n- [\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dFiber\u67b6\u6784\u7684\u5b9e\u73b0\u539f\u7406](https://juejin.cn/post/7212603037667786813)\\n- [\u300c\u4ece0\u5b9e\u73b0React18\u7cfb\u5217\u300dReconciler\u67b6\u6784\u7684\u53cc\u7f13\u5b58\u6811\u5b9e\u73b0\u539f\u7406](https://juejin.cn/post/7213362704781852730)\\n- [\u3010webpack\u6838\u5fc3\u5e93\u3011\u8017\u65f67\u4e2a\u5c0f\u65f6\uff0c\u7528\u8fd150\u5f20\u56fe\u6765\u5b66\u4e60enhance-resolve\u4e2d\u7684\u6570\u636e\u6d41\u52a8\u548c\u63d2\u4ef6\u8c03\u5ea6\u673a\u5236](https://mp.weixin.qq.com/s/QcQlOscF9R0aF2x3Oe6doQ)\\n- [\u804a\u804a Ant Design V5 \u7684\u4e3b\u9898\uff08\u4e0a\uff09\uff1aCSSinJS \u52a8\u6001\u4e3b\u9898\u7684\u82b1\u6d3b](https://juejin.cn/post/7199832444836593725)\\n- [\u5199\u7ed9\u5f00\u53d1\u540c\u5b66AI\u5f3a\u5316\u5b66\u4e60\u5165\u95e8\u6307\u5357](https://mp.weixin.qq.com/s/sTBFnSLS-WBjMWDokH2o9A)\\n- [\u4e00\u8d77\u6765\u770b\u770b\u4e00\u4e2a\u4f53\u7cfb\u5b8c\u5584\u7684\u524d\u7aefReact\u7ec4\u4ef6\u5e93\u662f\u5982\u4f55\u642d\u5efa\u51fa\u6765\u7684\uff01](https://mp.weixin.qq.com/s/d0zbdhTctR7L_62SaY_VJA)\\n- [\u5e72\u8d27 | \u8017\u65f6\u7f29\u77ed2/3\uff0cTaro\u7f16\u8bd1\u6253\u5305\u4f18\u5316\u5b9e\u8df5](https://mp.weixin.qq.com/s/z4GhUr5eA-4WbxVye4hmAQ)\\n- [\u5e72\u8d27 | 30+\u6761\u4e1a\u52a1\u7ebf\uff0c\u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u534f\u540c\u5f00\u53d1](https://mp.weixin.qq.com/s/g1XhCtfIL6yy-37Y_grtEw)\\n- [\u5e72\u8d27 | \u79d2\u5f00\u738770%+\uff0c\u643a\u7a0b\u91d1\u878dSSR\u5e94\u7528\u6027\u80fd\u76d1\u6d4b\u4e0e\u4f18\u5316](https://mp.weixin.qq.com/s/PT4y8OMWTpIto50qnT8gmg)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5fae\u4fe1\u5c0f\u7a0b\u5e8f\u5982\u4f55\u8fdb\u884cSize\u6cbb\u7406](https://mp.weixin.qq.com/s/293Lbr81oUWHeJ3TGfPRdw)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5c0f\u7a0b\u5e8f\u751f\u6001\u4e4bTaro\u8de8\u7aef\u89e3\u51b3\u65b9\u6848](https://mp.weixin.qq.com/s/iT05ZXPVYFuCQgZZF9Zu5w)\\n- [\u5e72\u8d27 | \u7626\u8eab50%-70%\uff0c\u643a\u7a0b Taro \u5c0f\u7a0b\u5e8f\u6837\u5f0f Size \u7f29\u51cf\u65b9\u6848](https://mp.weixin.qq.com/s/rpHb5ZhUTOTfbVPEZJFklg)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5546\u65c5\u5927\u524d\u7aef React Streaming \u7684\u63a2\u7d22\u4e4b\u8def](https://mp.weixin.qq.com/s/HUJTU5Du6318LJ7RfQNN2g)\\n- [\u5e72\u8d27 | \u643a\u7a0b\u5ea6\u5047\u57fa\u4e8e RPC \u548c TypeScript \u7684 BFF \u8bbe\u8ba1\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/JiJhA6AfNiGXl7p0uQ8mGA)\\n- [INP \u5373\u5c06\u4ee3\u66ff FID \u6210\u4e3a\u65b0\u7684\u6838\u5fc3 Web \u6307\u6807](https://mp.weixin.qq.com/s/OHbzuqUl3tL1YlpLOgEkvA)\\n- [\u3010\u7b2c2973\u671f\u3011\u643a\u7a0bWeb\u7ec4\u4ef6\u5728\u8de8\u7aef\u573a\u666f\u7684\u5b9e\u8df5](https://mp.weixin.qq.com/s/2Dy5RsviZlo7SPA648Mj3g)\\n- [\u8fd9\u4e9b\u5e74\u5728\u963f\u91cc\u5b66\u5230\u7684\u65b9\u6cd5\u8bba](https://mp.weixin.qq.com/s/yPRPakU1UM5iVY-1bwiHJQ)\\n- [/[\u901a\u660e\u5883 \xb7 React\u67b6\u6784/]\u901a\u4fd7\u5730\u8bb2React\uff0c\u4f18\u96c5\u5730\u7406\u89e3React](https://mp.weixin.qq.com/s/ganW_F5GhQV-8s9N2y7jaw)\\n- [React-Router 6.10+KeepAlive\u7684\u7ea6\u5b9a\u5f0f\u8def\u7531\u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/daHYuCfstHYqAtscn5T4WQ)\\n- [\u5e72\u8d27\uff01\u6211\u662f\u5982\u4f55\u5728\u4e00\u7ebf\u5927\u5382\u5b9e\u8df5webpack\u4f18\u5316\u7684](https://mp.weixin.qq.com/s/MWf07S5avWzK7vdzhpFsoA)\\n- [\u6d45\u8c08\u9886\u57df\u9a71\u52a8\u5728\u524d\u7aef\u7684\u5e94\u2f64](https://mp.weixin.qq.com/s/WV3oztPYZyGiv4hW0--Jkw)\\n- [Chrome 117 \u53d1\u5e03\uff1a\u65b0 Web \u5f00\u53d1\u8c03\u8bd5\u6280\u5de7\u90fd\u5728\u8fd9\u4e86\uff01](https://mp.weixin.qq.com/s/Z-8lsdLeTqCeFZ4w2oNBjg)"},{"id":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-17/index.md","source":"@site/blogs/2024/2024-03-17/index.md","title":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-03-17T00:00:00.000Z","formattedDate":"March 17, 2024","tags":[],"readingTime":45.52,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","title":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"\u7f6e\u9876\u5185\u5bb9","permalink":"/frontend-weekly/2024/welcome"},"nextItem":{"title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u300a\u5357\u6d0b\u7406\u5de5\u53d1\u5e03\u591a\u6a21\u6001\u91d1\u878d\u4ea4\u6613Agent\uff0c\u5e73\u5747\u5229\u6da6\u63d0\u9ad836%\uff01\u300b](https://mp.weixin.qq.com/s/QBORpQmZrumppLl81aWAxA)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u5357\u6d0b\u7406\u5de5\u5927\u5b66\u53d1\u5e03\u7684\u591a\u6a21\u6001\u91d1\u878d\u4ea4\u6613Agent\uff0c\u901a\u8fc7\u878d\u5408\u5927\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u548c\u591a\u6a21\u6001\u6570\u636e\u5904\u7406\uff0c\u63d0\u9ad8\u4e86\u91d1\u878d\u4ea4\u6613\u7684\u6548\u76ca\u3002\u4f20\u7edf\u57fa\u4e8e\u89c4\u5219\u7684\u4ea4\u6613\u7cfb\u7edf\u5728\u9002\u5e94\u5e02\u573a\u6ce2\u52a8\u65b9\u9762\u5b58\u5728\u4e0d\u8db3\uff0c\u800c\u57fa\u4e8e\u5f3a\u5316\u5b66\u4e60\u7684\u7cfb\u7edf\u867d\u7136\u9002\u5e94\u6027\u66f4\u597d\uff0c\u4f46\u5728\u5904\u7406\u591a\u6a21\u6001\u6570\u636e\u548c\u53ef\u89e3\u91ca\u6027\u65b9\u9762\u4ecd\u9762\u4e34\u6311\u6218\u3002\u8be5\u6587\u4e2d\u63d0\u51fa\u7684FinAgent\u662f\u4e00\u79cd\u5148\u8fdb\u7684\u591a\u6a21\u6001\u57fa\u7840\u4ee3\u7406\uff0c\u80fd\u591f\u7efc\u5408\u5206\u6790\u591a\u79cd\u5f62\u5f0f\u7684\u91d1\u878d\u6570\u636e\uff0c\u63d0\u4f9b\u7cbe\u786e\u7684\u5e02\u573a\u8d8b\u52bf\u5206\u6790\u548c\u51b3\u7b56\u652f\u6301\u3002\u5b9e\u9a8c\u8bc1\u660e\uff0c\u4f7f\u7528FinAgent\u8fdb\u884c\u91d1\u878d\u4ea4\u6613\u53ef\u4ee5\u5e73\u5747\u63d0\u9ad836%\u7684\u5229\u6da6\u3002\u8bba\u6587\u94fe\u63a5\uff1a[https://arxiv.org/pdf/2402.18485.pdf](https://arxiv.org/pdf/2402.18485.pdf)\\n\\n[\u300a\u5927\u6a21\u578b\u63a8\u7406:A100/H100 \u592a\u8d35\uff0c\u4f55\u4e0d\u7528 4090?\u300b](https://mp.weixin.qq.com/s/kek5xGP96UOJ3Rpfw3V-FQ)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u5927\u6a21\u578b\u63a8\u7406\u65f6\uff0c\u4e3a\u4ec0\u4e48\u53ef\u4ee5\u8003\u8651\u4f7f\u75284090\u663e\u5361\u3002\u76f8\u6bd4\u4e8eA100\u548cH100\u663e\u5361\uff0c4090\u5728\u6027\u4ef7\u6bd4\u4e0a\u66f4\u9ad8\uff0c\u5c24\u5176\u5728\u6781\u81f4\u4f18\u5316\u7684\u60c5\u51b5\u4e0b\uff0c\u751a\u81f3\u53ef\u4ee5\u8fbe\u5230H100\u76842\u500d\u6027\u80fd\u3002\u6587\u7ae0\u6307\u51fa\uff0cA100\u3001H100\u548c4090\u5728\u7b97\u529b\u65b9\u9762\u7684\u5dee\u8ddd\u5e76\u4e0d\u5927\uff0c\u6700\u5927\u7684\u533a\u522b\u5728\u901a\u4fe1\u548c\u5185\u5b58\u65b9\u9762\u3002\u7531\u4e8e\u5927\u6a21\u578b\u8bad\u7ec3\u4f7f\u7528\u9ad8\u6027\u80fd\u7684\u901a\u4fe1\uff0c4090\u901a\u4fe1\u6548\u7387\u76f8\u5bf9\u8f83\u4f4e\uff0c\u56e0\u6b64\u5728\u5927\u6a21\u578b\u8bad\u7ec3\u4e2d\u5e76\u4e0d\u9002\u7528\u3002\u7136\u800c\uff0c\u5728\u63a8\u7406\uff08inference/serving\uff09\u65b9\u9762\uff0c4090\u5728\u6027\u4ef7\u6bd4\u4e0a\u6709\u4f18\u52bf\uff0c\u5c24\u5176\u662f\u76f8\u5bf9\u4e8eH100\u663e\u5361\u800c\u8a00\u3002\u6587\u7ae0\u8fd8\u63d0\u5230\u4e86GPU\u7684\u8bad\u7ec3\u6027\u80fd\u548c\u6210\u672c\u5bf9\u6bd4\uff0c\u4ee5\u53ca\u5927\u6a21\u578b\u8bad\u7ec3\u6240\u9700\u7684\u7b97\u529b\u548cGPU\u6570\u91cf\u7b49\u95ee\u9898\u3002\u8be6\u7ec6\u5185\u5bb9\u53ef\u53c2\u8003\u6587\u7ae0\u94fe\u63a5\u3002\\n\\n[\u300a\u7cbe\u5ea6\u63d0\u5347!\u5357\u52a0\u5927\u7b49 | \u63d0\u51fa\u5206\u6cbbPrompt\u7b56\u7565\uff0c\u63d0\u5347LLM\u5206\u8fa8\u529b\u300b](https://mp.weixin.qq.com/s/tKVHsoR_opgBqtCMDHbv6Q)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b97\u6cd5\u7684Prompt\u7b56\u7565\uff0c\u65e8\u5728\u63d0\u9ad8\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u7684\u5206\u8fa8\u529b\u3002\u73b0\u6709\u7684\u63d0\u793a\u7b56\u7565\u5728\u5904\u7406\u6d89\u53ca\u91cd\u590d\u5b50\u4efb\u52a1\u548c\u542b\u6709\u6b3a\u9a97\u6027\u5185\u5bb9\u7684\u4efb\u52a1\u65f6\u5b58\u5728\u4e00\u5b9a\u9650\u5236\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u7814\u7a76\u4eba\u5458\u63d0\u51fa\u4e86\u4e00\u79cd\u57fa\u4e8e\u5206\u6cbb\u7b97\u6cd5\u7684\u63d0\u793a\u7b56\u7565\uff0c\u5229\u7528\u5206\u6cbb\u7a0b\u5e8f\u6765\u5f15\u5bfcLLM\u7684\u6c42\u89e3\u8fc7\u7a0b\u3002\u8be5\u7b56\u7565\u5c06\u4efb\u52a1\u5212\u5206\u4e3a\u5b50\u95ee\u9898\u5e76\u5206\u522b\u6c42\u89e3\uff0c\u7136\u540e\u5408\u5e76\u5b50\u95ee\u9898\u7684\u7b54\u6848\u3002\u901a\u8fc7\u5b9e\u9a8c\u8bc1\u660e\uff0c\u8fd9\u79cd\u5206\u6cbb\u7b56\u7565\u80fd\u591f\u63d0\u5347\u6a21\u578b\u5728\u5927\u6574\u6570\u4e58\u6cd5\u3001\u5e7b\u89c9\u68c0\u6d4b\u548c\u65b0\u95fb\u9a8c\u8bc1\u7b49\u4efb\u52a1\u4e2d\u7684\u6027\u80fd\uff0c\u76f8\u6bd4\u4f20\u7edf\u63d0\u793a\u7b56\u7565\u5177\u6709\u66f4\u597d\u7684\u51c6\u786e\u7387\u548c\u6027\u80fd\u6307\u6807\u3002\u8bba\u6587\u5730\u5740\uff1a[https://arxiv.org/pdf/2402.05359.pdf](https://arxiv.org/pdf/2402.05359.pdf)\\n\\n[\u300a\u5f00\u6e90\u7248\u201cDevin\u201dAI\u7a0b\u5e8f\u5458\u70b8\u573a:\u81ea\u5df1\u5206\u6790\u80a1\u7968\u3001\u505a\u62a5\u8868\u3001\u5efa\u6a21\u578b\u300b](https://mp.weixin.qq.com/s/sxgfJf4vxvaxhO5L7-Npwg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u4e2a\u57fa\u4e8eMetaGPT\u7684\u5f00\u6e90\u9879\u76eeData Interpreter\uff0c\u8be5\u9879\u76ee\u65e8\u5728\u5904\u7406\u6570\u636e\u5b9e\u65f6\u53d8\u5316\u3001\u4efb\u52a1\u4e4b\u95f4\u7684\u590d\u6742\u4f9d\u8d56\u5173\u7cfb\u3001\u6d41\u7a0b\u4f18\u5316\u9700\u6c42\u4ee5\u53ca\u6267\u884c\u7ed3\u679c\u53cd\u9988\u7684\u903b\u8f91\u4e00\u81f4\u6027\u7b49\u6311\u6218\u3002\u901a\u8fc7\u6f14\u793a\uff0c\u5c55\u793a\u4e86Data Interpreter\u5728\u5206\u6790\u80a1\u7968\u3001\u9884\u6d4b\u8461\u8404\u9152\u8d28\u91cf\u3001\u81ea\u52a8\u62a0\u56fe\u3001\u9884\u6d4b\u75be\u75c5\u8fdb\u5c55\u548c\u9884\u6d4b\u673a\u5668\u8fd0\u884c\u72b6\u6001\u7b49\u65b9\u9762\u7684\u80fd\u529b\u3002\u8be5\u9879\u76ee\u7531MetaGPT\u56e2\u961f\u4e0e\u591a\u6240\u9ad8\u6821\u5408\u4f5c\u63a8\u51fa\uff0c\u63d0\u4f9b\u4e86\u4e00\u79cd\u81ea\u4e3b\u8fdb\u884c\u6570\u636e\u5206\u6790\u548c\u5efa\u6a21\u7684\u5f00\u6e90\u5de5\u5177\u3002\\n\\n[\u300a\u3010\u539f\u521b\u3011\u4e00\u6587\u8bfb\u61c2RAG\u7684\u6765\u6e90\u3001\u53d1\u5c55\u548c\u524d\u6cbf\u300b](https://mp.weixin.qq.com/s/n98IZHs7LTXMzzS3KmHvrA)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u6280\u672f\uff0c\u8be5\u6280\u672f\u7ed3\u5408\u4e86\u68c0\u7d22\u548c\u751f\u6210\u8fc7\u7a0b\uff0c\u65e8\u5728\u63d0\u9ad8\u673a\u5668\u751f\u6210\u6587\u672c\u7684\u76f8\u5173\u6027\u3001\u51c6\u786e\u6027\u548c\u591a\u6837\u6027\u3002\u6587\u7ae0\u8be6\u7ec6\u89e3\u91ca\u4e86\u5e7b\u89c9\u95ee\u9898\u7684\u5b58\u5728\u4ee5\u53ca\u89e3\u51b3\u5e7b\u89c9\u95ee\u9898\u7684\u51e0\u79cd\u5e38\u89c1\u65b9\u6cd5\u3002RAG\u5229\u7528\u5916\u90e8\u6570\u636e\u6e90\u8fdb\u884c\u4fe1\u606f\u68c0\u7d22\uff0c\u5c06\u68c0\u7d22\u5230\u7684\u4fe1\u606f\u4f5c\u4e3a\u4e0a\u4e0b\u6587\u8f93\u5165\u5230\u751f\u6210\u6a21\u578b\u4e2d\uff0c\u4ece\u800c\u5e2e\u52a9\u751f\u6210\u6b63\u786e\u7684\u54cd\u5e94\u3002\u8ba8\u8bba\u4e86RAG\u7684\u6838\u5fc3\u90e8\u4ef6\uff0c\u5982\u5411\u91cf\u6570\u636e\u5e93\u3001\u67e5\u8be2\u68c0\u7d22\u548c\u91cd\u65b0\u6392\u5e8f\u3002\u540c\u65f6\u4ecb\u7ecd\u4e86RAG\u5728\u77e5\u8bc6\u56fe\u8c31\u548c\u6811\u7ed3\u6784\u65b9\u9762\u7684\u62d3\u5c55\u3002\\n\\n[\u300a\u4e07\u5b57\u957f\u6587\u89e3\u6790:\u5927\u6a21\u578b\u9700\u8981\u600e\u6837\u7684\u786c\u4ef6\u7b97\u529b\u300b](https://mp.weixin.qq.com/s/NoREsyLXNVk1aABtSkhBDA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u5927\u6a21\u578b\u5728\u7b97\u529b\u3001\u5b58\u50a8\u3001\u901a\u4fe1\u7b49\u591a\u4e2a\u65b9\u9762\u4e0a\u786c\u4ef6\u8d44\u6e90\u7684\u6311\u6218\u548c\u74f6\u9888\u3002\u6587\u7ae0\u5206\u6790\u4e86\u4ee5Transformer\u7ed3\u6784\u4e3a\u6838\u5fc3\u7684\u5927\u6a21\u578b\u5728\u7b97\u529b\u74f6\u9888\u3001\u663e\u5b58\u74f6\u9888\u548c\u901a\u4fe1\u74f6\u9888\u65b9\u9762\u7684\u56f0\u5883\uff0c\u4ee5\u53ca\u5f53\u524d\u6240\u91c7\u53d6\u7684\u786c\u4ef6\u8d44\u6e90\u4f18\u5316\u6280\u672f\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u63d0\u4f9b\u4e86\u5bf9\u5927\u6a21\u578b\u53c2\u6570\u91cf\u548c\u7b97\u529b\u9700\u6c42\u7684\u91cf\u5316\u4f30\u7b97\uff0c\u4e3a\u9009\u62e9\u5408\u9002\u7684\u786c\u4ef6\u8bbe\u5907\u548c\u8bc4\u4f30\u8d44\u6e90\u9700\u6c42\u63d0\u4f9b\u4e86\u6307\u5bfc\u3002\\n\\n[\u300a\u4ec0\u4e48\u662f\u597d\u7684\u5927\u6a21\u578b\u8bad\u7ec3\u6570\u636e?\u300b](https://mp.weixin.qq.com/s/lbLOqiW-DoHq_S9qpYcbCQ)\u3002\u672c\u6587\u57fa\u4e8eLilian Weng\u7684\u535a\u5ba2\uff0c\u8ba8\u8bba\u4e86\u5927\u6a21\u578b\u5982LLM\u5728\u8bad\u7ec3\u8fc7\u7a0b\u4e2d\u5bf9\u9ad8\u8d28\u91cf\u6570\u636e\u7684\u9700\u6c42\u3002\u8ba4\u4e3a\u9ad8\u8d28\u91cf\u6570\u636e\u6765\u6e90\u4e8e\u201c\u9ad8\u8d28\u91cf\u4eba\u7c7b\u201d\u4ea7\u751f\u7684\u6807\u6ce8\u6570\u636e\uff0c\u5e76\u5f3a\u8c03\u4e86\u6570\u636e\u5904\u7406\u7684\u91cd\u8981\u6027\uff0c\u63d0\u5230\u4e86\u6570\u636e\u6807\u6ce8\u3001\u8d28\u91cf\u63a7\u5236\u548c\u9519\u8bef\u4fee\u6b63\u7684\u91cd\u8981\u6b65\u9aa4\u3002\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u7528\u4e8e\u8bc4\u4f30\u6570\u636e\u8d28\u91cf\u7684\u591a\u79cd\u65b9\u6cd5\uff0c\u5982Influence Functions\u548cNoisy Cross-Validation\uff0c\u5e76\u63d0\u51fa\u4e86\u4e13\u6ce8\u4e8e\u201c\u642d\u5efa\u9ad8\u8d28\u91cf\u7684\u6570\u636e\u6807\u6ce8pipeline\u201d\u7684\u4f01\u4e1a\u65b9\u5411\u3002\u6700\u540e\u6307\u51fa\uff0c\u5728AI\u65f6\u4ee3\u5927\u91cf\u4ea7\u51fa\u7684\u6570\u636e\u4e2d\u7ef4\u62a4\u6570\u636e\u8d28\u91cf\uff0c\u662f\u4e00\u4e2a\u503c\u5f97\u5173\u6ce8\u7684\u6311\u6218\u3002\\n\\n[\u300a\u8bfb\u8fc7\u7684\u6700\u767d\u8bdd\u8bb2\u6e05\u695aRAG\u539f\u7406\u7684\u6587\u7ae0\u300b](https://mp.weixin.qq.com/s/dA757HASxJPYuAbRZ7KvUQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u76f4\u89c2\u5730\u9610\u91ca\u4e86\u68c0\u7d22\u589e\u5f3a\u751f\u6210\uff08RAG\uff09\u7684\u6982\u5ff5\u548c\u5de5\u4f5c\u539f\u7406\uff0c\u5b83\u662f\u4e00\u79cd\u7ed3\u5408\u68c0\u7d22\u548c\u751f\u6210\u7684\u95ee\u7b54\u7cfb\u7edf\u3002\u8be5\u7cfb\u7edf\u9996\u5148\u901a\u8fc7\u68c0\u7d22\u6b65\u9aa4\u627e\u5230\u4e0e\u7528\u6237\u95ee\u9898\u6700\u76f8\u5173\u7684\u77e5\u8bc6\u5e93\u5185\u5bb9\uff0c\u7136\u540e\u5c06\u8fd9\u4e9b\u5185\u5bb9\u4e0e\u95ee\u9898\u5171\u540c\u8f93\u5165\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u4f8b\u5982ChatGPT\uff09\u4ee5\u751f\u6210\u7b54\u6848\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u5d4c\u5165\u6a21\u578b\u5bf9\u77e5\u8bc6\u5e93\u6587\u672c\u8fdb\u884c\u7d22\u5f15\uff0c\u4ee5\u4fbf\u534f\u52a9\u8bed\u8a00\u6a21\u578b\u8fdb\u884c\u7cbe\u786e\u7684\u68c0\u7d22\u3002\u6b64\u5916\uff0c\u5b83\u8fd8\u63a2\u8ba8\u4e86\u8bed\u4e49\u641c\u7d22\u80cc\u540e\u7684\u6838\u5fc3\u539f\u5219\u548c\u6280\u672f\u7ec6\u8282\u70b9\uff0c\u5982\u4f55\u901a\u8fc7\u5d4c\u5165\u627e\u5230\u4e0e\u7528\u6237\u8f93\u5165\u6700\u5339\u914d\u7684\u77e5\u8bc6\uff0c\u4ee5\u53ca\u5982\u4f55\u683c\u5f0f\u5316\u6587\u6863\u4ee5\u4f9b\u8bed\u8a00\u6a21\u578b\u4f7f\u7528\uff0c\u4ee5\u4fbf\u83b7\u5f97\u66f4\u9ad8\u6548\u7684\u56de\u7b54\u3002\\n\\n[\u300aLLM\u63a8\u7406\u7b97\u6cd5\u7b80\u8ff0\u300b](https://zhuanlan.zhihu.com/p/685794495)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u7528\u4e8e\u63d0\u9ad8\u5927\u578b\u8bed\u8a00\u6a21\u578b(LLM)\u63a8\u7406\u6027\u80fd\u7684\u5173\u952e\u6280\u672f\u4e0e\u7b56\u7565\u3002\u5185\u5bb9\u6db5\u76d6\u663e\u5b58\u4f18\u5316\u65b9\u6cd5\uff0c\u5982KV Cache\u51cf\u5c11\u663e\u5b58\u6d6a\u8d39\u3001MQA\u548cGQA\u51cf\u5c11KV-Cache\u6570\u91cf\u3001Page Attention\u8fdb\u884c\u663e\u5b58\u7ba1\u7406\uff0c\u4ee5\u53ca\u63d0\u9ad8\u63a8\u7406\u901f\u5ea6\u7684FlashAttention\u6539\u8fdb\u3002\u6587\u7ae0\u8fd8\u63a2\u8ba8\u4e86\u7b97\u5b50\u878d\u5408\u6280\u672f\uff0c\u6bd4\u5982FasterTransformer\u548cDeepSpeed Inference\u7684\u5e94\u7528\uff0c\u4ee5\u53ca\u8c03\u5ea6\u4f18\u5316\u7b56\u7565\u5982Async Serving\u548cDynamic Batch\uff0c\u6700\u540e\u4ecb\u7ecd\u4e86\u7528\u4e8e\u5904\u7406\u5927\u6a21\u578b\u7684\u5206\u5e03\u5f0f\u5e76\u884c\u6280\u672f\u3002\u8fd9\u4e9b\u4f18\u5316\u624b\u6bb5\u80fd\u663e\u8457\u63d0\u9ad8LLM\u63a8\u7406\u8fc7\u7a0b\u4e2d\u7684\u6027\u80fd\u4e0e\u6548\u7387\u3002\\n\\n[\u300a\u6570\u5b66\u63a8\u7406\u589e\u5f3a!\u5fae\u8f6f | \u63d0\u51fa\u6570\u636e\u5408\u6210\u6846\u67b6:KPDDS\uff0c\u5fae\u8c03Mistral-7B\u6027\u80fd\u8d8534B\u6a21\u578b!\u300b](https://mp.weixin.qq.com/s/V8Tz5X81FlOva9B6bCprqg)\u3002\u5fae\u8f6f\u7684\u7814\u7a76\u56e2\u961f\u4e3a\u63d0\u5347\u5927\u578b\u8bed\u8a00\u6a21\u578b(Large Language Models, LLMs)\u5728\u6570\u5b66\u63a8\u7406\u4efb\u52a1\u7684\u6027\u80fd\uff0c\u63d0\u51fa\u4e86\u5173\u952e\u70b9\u9a71\u52a8\u7684\u6570\u636e\u5408\u6210(KPDDS)\u6846\u67b6\u3002KPDDS\u5229\u7528\u771f\u5b9e\u6570\u636e\u6e90\u4e2d\u7684\u5173\u952e\u70b9\u548c\u793a\u4f8b\u5bf9\u751f\u6210\u9ad8\u8d28\u91cf\u95ee\u7b54\u5bf9\u6765\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u3002\u7814\u7a76\u8005\u57fa\u4e8e\u6b64\u6846\u67b6\u521b\u5efa\u4e86KPMath\u6570\u636e\u96c6\uff0c\u8fdb\u4e00\u6b65\u7ed3\u5408\u63a8\u7406\u5bc6\u96c6\u578b\u6570\u636e\u5f62\u6210KPMath-Plus\u6570\u636e\u96c6\u3002\u5728MATH\u6d4b\u8bd5\u96c6\u4e0a\uff0c\u5fae\u8c03\u540e\u7684Mistral-7B\u6a21\u578b\u8fbe\u5230\u4e8639.3%\u7684\u96f6\u6837\u672c\u901a\u8fc7\u7387\uff0c\u8d85\u8d8a\u4e86\u6570\u91cf\u66f4\u591a\u768434B\u6a21\u578b\uff0c\u8bc1\u660e\u4e86KPDDS\u7684\u6709\u6548\u6027\u4e0e\u521b\u65b0\u6027\u3002\u8fd9\u4e00\u6210\u679c\u6807\u5fd7\u7740LLMs\u5728\u6570\u5b66\u63a8\u7406\u65b9\u9762\u7684\u6027\u80fd\u5f97\u5230\u663e\u8457\u63d0\u5347\u3002\\n\\n[\u300a\u9996\u4e2aAI\u8f6f\u4ef6\u5de5\u7a0b\u5e08\u4e0a\u7ebf!\u5df2\u901a\u8fc7\u516c\u53f8\u9762\u8bd5\u62a2\u7a0b\u5e8f\u5458\u996d\u7897\uff0c\u534e\u4eba\u521b\u59cb\u56e2\u961f\u624b\u63e110\u5757IOI\u91d1\u724c\u300b](https://mp.weixin.qq.com/s/QkkYAilf4_XZyBRqSIEL2Q)\u3002\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u4e86\u7531\u534e\u4eba\u521b\u7acb\u7684Cognition AI\u516c\u53f8\u5f00\u53d1\u51fa\u6765\u7684\u9996\u4e2a\u4eba\u5de5\u667a\u80fd\u8f6f\u4ef6\u5de5\u7a0b\u5e08Devin\u3002\u4e0e\u73b0\u6709GPT-4\u7b49\u6a21\u578b\u4e0d\u540c\uff0cDevin\u80fd\u591f\u72ec\u7acb\u5b8c\u6210\u590d\u6742\u7684\u7f16\u7a0b\u4efb\u52a1\uff0c\u5e76\u5df2\u6210\u529f\u901a\u8fc7\u4eba\u5de5\u667a\u80fd\u516c\u53f8\u7684\u9762\u8bd5\u548c\u5728\u81ea\u7531\u804c\u4e1a\u5e73\u53f0Upwork\u4e0a\u63a5\u5355\u3002\u5f97\u76ca\u4e8eCognition AI\u5728\u957f\u671f\u63a8\u7406\u548c\u89c4\u5212\u65b9\u9762\u7684\u8fdb\u6b65\uff0cDevin\u5728\u505a\u51b3\u7b56\u548c\u6267\u884c\u4efb\u52a1\u65f6\uff0c\u80fd\u56de\u60f3\u76f8\u5173\u4e0a\u4e0b\u6587\u3001\u968f\u65f6\u95f4\u5b66\u4e60\u5e76\u4fee\u590d\u9519\u8bef\u3002\u8fd9\u6807\u5fd7\u7740\u4eba\u5de5\u667a\u80fd\u5728\u7406\u89e3\u771f\u5b9e\u4e16\u754c\u8f6f\u4ef6\u5de5\u7a0b\u95ee\u9898\u65b9\u9762\u53d6\u5f97\u4e86\u7a81\u7834\uff0c\u4e3aAI\u9886\u57df\u8fc8\u5411\u66f4\u9ad8\u5c42\u7ea7\u7684\u81ea\u52a8\u5316\u53ca\u76d1\u7763\u6027\u5de5\u4f5c\u5f00\u8f9f\u9053\u8def\u3002\\n\\n[\u300a\u5411\u6570\u5b57\u4e16\u754cAGI\u8fc8\u8fdb!\u667a\u80fd\u4f53\u5df2\u7ecf\u4ece\u5934\u5f00\u73a9\u300c\u8352\u91ce\u5927\u9556\u5ba2 2\u300d\u4e86\u300b](https://mp.weixin.qq.com/s/q_lgeiXFzTU4WEt9wpUG3w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528Cradle\u8fd9\u4e00\u901a\u7528\u8ba1\u7b97\u673a\u63a7\u5236\u667a\u80fd\u4f53\u6846\u67b6\u8fdb\u884cAI\u7684\u7814\u7a76\u4e0e\u5e94\u7528\uff0c\u5728\u65e0\u9700\u5185\u90e8API\u652f\u6301\u4e0b\u63a7\u5236\u952e\u76d8\u548c\u9f20\u6807\u4ee5\u53ca\u4e0e\u5404\u7c7b\u8f6f\u4ef6\u4ea4\u4e92\u3002\u6587\u7ae0\u6765\u6e90\u4e8e\u5317\u4eac\u667a\u6e90\u4eba\u5de5\u667a\u80fd\u7814\u7a76\u9662\u3001\u65b0\u52a0\u5761\u5357\u6d0b\u7406\u5de5\u5927\u5b66\u548c\u5317\u4eac\u5927\u5b66\u7684\u8054\u5408\u7814\u7a76\u3002Cradle\u7531\u516d\u5927\u6a21\u5757\u7ec4\u6210\uff0c\u5305\u62ec\u4fe1\u606f\u6536\u96c6\u3001\u81ea\u6211\u53cd\u601d\u3001\u4efb\u52a1\u63a8\u65ad\u3001\u6280\u80fd\u7ba1\u7406\u3001\u884c\u52a8\u8ba1\u5212\u548c\u8bb0\u5fc6\u6a21\u5757\u3002\u8fd9\u4e9b\u6a21\u5757\u8ba9\u667a\u80fd\u4f53\u80fd\u591f\u81ea\u4e3b\u8fdb\u884c\u51b3\u7b56\u548c\u4efb\u52a1\u6267\u884c\u3002\u7814\u7a76\u56e2\u961f\u901a\u8fc7\u5c06Cradle\u90e8\u7f72\u4e8e\u300a\u8352\u91ce\u5927\u9556\u5ba2 2\u300b\u8fd9\u4e00\u590d\u6742\u76843A\u6e38\u620f\u4e2d\u8bc1\u660e\u5176\u901a\u7528\u6027\uff0cCradle\u80fd\u591f\u81ea\u4e3b\u5b8c\u6210\u6e38\u620f\u4e3b\u7ebf\u548c\u63a2\u7d22\u5f00\u653e\u4e16\u754c\u3002\u667a\u80fd\u4f53\u7684\u8fd9\u79cd\u901a\u7528\u80fd\u529b\u6807\u5fd7\u7740\u667a\u80fd\u4f53\u7814\u7a76\u5411\u901a\u7528\u4eba\u5de5\u667a\u80fd\uff08AGI\uff09\u8fc8\u8fdb\u7684\u91cd\u8981\u4e00\u6b65\u3002\\n\\n[\u300a\u6df1\u5165\u6d45\u51fa LangChain \u4e0e\u667a\u80fd Agent:\u6784\u5efa\u4e0b\u4e00\u4ee3 AI \u52a9\u624b\u300b](https://mp.weixin.qq.com/s/U2472bnEvCE9lMPP-z0ysw)\u3002\u6587\u7ae0\u6df1\u5165\u8bb2\u89e3\u4e86LangChain\u5de5\u5177\u7bb1\u53ca\u5176\u5982\u4f55\u8d4b\u80fd\u667a\u80fdAgent\uff0c\u4ee5\u6784\u5efa\u66f4\u52a0\u667a\u80fd\u7684AI\u52a9\u624b\u3002LangChain\u5229\u7528\u5927\u578b\u8bed\u8a00\u6a21\u578b\u5982GPT-4\uff0c\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5f00\u6e90\u8f6f\u4ef6\u6846\u67b6\uff0c\u53ef\u52a9\u529b\u5f00\u53d1\u8005\u642d\u5efa\u57fa\u4e8e\u8bed\u8a00\u6a21\u578b\u7684\u5e94\u7528\u3002\u5b83\u63d0\u4f9b\u4e86\u516d\u5927\u7c7b\u7ec4\u4ef6\uff0c\u5982\u6a21\u578b\u3001\u63d0\u793a\u6a21\u677f\u3001\u7d22\u5f15\u3001\u6587\u6863\u52a0\u8f7d\u5668\u3001\u6587\u672c\u5206\u5272\u5668\u548c\u5411\u91cf\u5b58\u50a8\uff0c\u8ba9GPT-4\u7b49\u6a21\u578b\u4e0d\u4ec5\u80fd\u5904\u7406\u8bed\u8a00\uff0c\u8fd8\u80fd\u4e0e\u5916\u90e8API\u4e92\u52a8\u3001\u7ba1\u7406\u7528\u6237\u4e0a\u4e0b\u6587\u3002\u6587\u7ae0\u4ee5\u6784\u5efa\u4eba\u8138\u6280\u672f\u95ee\u9898\u6392\u67e5\u52a9\u624b\u4e3a\u4f8b\uff0c\u5c55\u793a\u5982\u4f55\u8fd0\u7528LangChain\u6765\u534f\u52a9\u95ee\u9898\u8bca\u65ad\u4e0e\u667a\u80fd\u4ea4\u4e92\uff0c\u671d\u5411\u81ea\u4e3b\u3001\u9ad8\u6548\u7684\u667a\u80fd\u5e94\u7528\u53d1\u5c55\u3002\\n\\n[\u300a\u4f7f\u7528\u96f6\u4e00\u4e07\u7269 200K \u6a21\u578b\u548c Dify \u5feb\u901f\u642d\u5efa\u6a21\u578b\u5e94\u7528\u300b](https://mp.weixin.qq.com/s/AAkITPRodLzvl61oALEI2Q)\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u4f7f\u7528\u96f6\u4e00\u4e07\u7269\u7684200K\u6a21\u578b\u548cDify\uff08LLM IDE\uff09\u5feb\u901f\u6784\u5efa\u6a21\u578b\u5e94\u7528\u7a0b\u5e8f\u3002\u4f5c\u8005\u9996\u5148\u5bf9\u4e00\u4e2a\u673a\u5668\u5b66\u4e60\u7535\u5b50\u4e66\u8fdb\u884c\u7ffb\u8bd1\uff0c\u5e76\u5206\u4eab\u4e86\u6e90\u4ee3\u7801\uff0c\u7136\u540e\u5f15\u5bfc\u8bfb\u8005\u5982\u4f55\u7533\u8bf7\u548c\u914d\u7f6e\u96f6\u4e00\u4e07\u7269\u6a21\u578bAPI\u3002\u968f\u540e\uff0c\u4f5c\u8005\u8bf4\u660e\u4e86\u5982\u4f55\u4f7f\u7528Dify IDE\u5feb\u901f\u642d\u5efa\u548c\u8c03\u8bd5\u6a21\u578b\u5e94\u7528\u7a0b\u5e8f\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528Golang\u548cAI\u6a21\u578b\u81ea\u52a8\u5316\u7535\u5b50\u4e66\u7684\u7ffb\u8bd1\u8fc7\u7a0b\u3002\u6700\u540e\uff0c\u4f5c\u8005\u603b\u7ed3\u4e86\u81ea\u52a8\u7ffb\u8bd1\u7a0b\u5e8f\u7684\u6784\u5efa\u8fc7\u7a0b\u5e76\u5c55\u793a\u4e86\u6279\u91cf\u7ffb\u8bd1\u5185\u5bb9\u7684\u65b9\u6cd5\u3002\u6574\u7bc7\u6587\u7ae0\u4e0d\u4ec5\u662f\u4f7f\u7528Dify\u7684\u5b9e\u64cd\u6307\u5357\uff0c\u8fd8\u63d0\u4f9b\u4e86\u4e00\u79cd\u6548\u7387\u5316\u3001\u81ea\u52a8\u5316\u5904\u7406\u6587\u672c\u5185\u5bb9\u7684\u793a\u4f8b\uff0c\u9002\u5408\u90a3\u4e9b\u5728\u5bfb\u627e\u5feb\u901f\u5f00\u53d1\u548c\u96c6\u6210\u5927\u8bed\u8a00\u6a21\u578b\u5230\u5e94\u7528\u4e2d\u7684\u5f00\u53d1\u8005\u53c2\u8003\u3002\\n\\n[\u300a\u4e00\u6587\u770b\u5b8c\u591a\u6a21\u6001:\u4ece\u89c6\u89c9\u8868\u5f81\u5230\u591a\u6a21\u6001\u5927\u6a21\u578b\u300b](https://mp.weixin.qq.com/s/-9H0mLnvebzaLMaI6EKB6g)\u3002\u672c\u6587\u4e3a\u8bfb\u8005\u7cfb\u7edf\u68b3\u7406\u4e86\u56fe\u6587\u591a\u6a21\u6001\u4e0e\u591a\u6a21\u6001\u5927\u6a21\u578b\u9886\u57df\u7684\u53d1\u5c55\uff0c\u5c24\u5176\u805a\u7126\u5728\u89c6\u89c9\u8868\u5f81\u548c\u89c6\u89c9\u4e0e\u6587\u672c\u878d\u5408\u65b9\u6cd5\u4e0a\u3002\u6587\u7ae0\u4ece\u5377\u79ef\u795e\u7ecf\u7f51\u7edc\uff08CNN\uff09\u53ca\u5176\u9884\u8bad\u7ec3\u65b9\u6cd5\u5f00\u59cb\u8bb2\u8d77\uff0c\u4ece\u56fe\u50cf\u5904\u7406\u7684\u89c6\u89d2\u4ecb\u7ecd\u4e86\u591a\u6a21\u6001\u878d\u5408\u7684\u521d\u671f\u65b9\u6cd5\uff0c\u5982LXMERT\u3001VL-BERT\u548cUNITER\u7b49\u3002\u8fdb\u4e00\u6b65\uff0c\u6587\u7ae0\u8bba\u8ff0\u4e86Vision Transformer\uff08ViT\uff09\u53ca\u5176\u9884\u8bad\u7ec3\u65b9\u6848\u5982MAE\u548cBEIT\uff0c\u4ee5\u53ca\u57fa\u4e8eViT\u7684\u591a\u6a21\u6001\u5bf9\u9f50\u4e0e\u9884\u8bad\u7ec3\u6280\u672f\uff0c\u5982CLIP\u548cVILT\u7b49\u3002\u4f5c\u8005\u901a\u8fc7\u4e30\u5bcc\u7684\u793a\u4f8b\u548c\u5bf9\u6bd4\uff0c\u4f7f\u8bfb\u8005\u80fd\u591f\u7406\u89e3\u8fd9\u4e9b\u6a21\u578b\u5728\u7ed3\u6784\u548c\u529f\u80fd\u4e0a\u7684\u4e0d\u540c\u4e0e\u8054\u7cfb\uff0c\u4e3a\u8fdb\u4e00\u6b65\u7814\u7a76\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u8d44\u6e90\u548c\u89c6\u89d2\u3002\\n\\n[\u300a\u6d59\u5927&\u4e2d\u79d1\u9662\u8ba9Agent\u5b66\u4f1a\u81ea\u6211\u8fdb\u5316\uff0c\u73a9\u5fb7\u5dde\u6251\u514b\u5fc3\u673a\u5c3d\u663e\u300b](https://mp.weixin.qq.com/s/k7b55PKdLA622G6Qb5Q0hA)\u3002Wenqi Zhang\u7b49\u7814\u7a76\u8005\u4ecb\u7ecd\u4e86\u540d\u4e3aAgent-Pro\u7684AI\u667a\u80fd\u4f53\uff0c\u5b83\u4f7f\u7528\u5927\u6a21\u578b(GPT-4)\u4e3a\u57fa\u7840\uff0c\u914d\u5408\u81ea\u6211\u4f18\u5316\u7684\u7b56\u7565\uff0c\u80fd\u591f\u8fd0\u7528\u865a\u5f20\u58f0\u52bf\u3001\u4e3b\u52a8\u653e\u5f03\u7b49\u590d\u6742\u7b56\u7565\u73a9\u8f6c\u5fb7\u5dde\u6251\u514b\u548c21\u70b9\u7b49\u975e\u5b8c\u7f8e\u4fe1\u606f\u535a\u5f08\u6e38\u620f\u3002Agent-Pro\u7684\u8bbe\u8ba1\u4f7f\u5176\u80fd\u591f\u81ea\u6211\u8fdb\u5316\uff0c\u9002\u5e94\u590d\u6742\u548c\u52a8\u6001\u7684\u6e38\u620f\u73af\u5883\uff0c\u5e76\u901a\u8fc7\u7b56\u7565\u5c42\u9762\u7684\u53cd\u601d\u548c\u4e16\u754c\u6a21\u578b\u7684\u4f18\u5316\u6765\u63d0\u9ad8\u81ea\u5df1\u7684\u8868\u73b0\u3002\u8be5\u7814\u7a76\u5c55\u793a\u4e86AI\u5728\u535a\u5f08\u9886\u57df\u7684\u8fdb\u6b65\uff0c\u540c\u65f6\u4e3a\u89e3\u51b3\u591aagent\u73b0\u5b9e\u4e16\u754c\u95ee\u9898\u63d0\u4f9b\u4e86\u65b0\u7b56\u7565\u3002\\n\\n[\u300a\u9762\u5411\u5de5\u4e1a\u7ea7\u63a8\u8350!\u201c\u5c0f\u201dLLM\u4e5f\u80fd\u505a\u597d\u63a8\u8350\u7cfb\u7edf\u300b](https://mp.weixin.qq.com/s/ZG3CuhZisI26taz4FQrdPg)\u3002\u672c\u6587\u7531\u8682\u8681\u96c6\u56e2AI\u521b\u65b0\u7814\u53d1\u90e8\u95e8NextEvo\u64b0\u5199\uff0c\u4ecb\u7ecd\u4e86\u4ed6\u4eec\u7684\u8bba\u6587\u300aCan Small Language Models be Good Reasoners for Sequential Recommendation?\u300b\u83b7\u5f97WWW 2024 (Oral)\u5f55\u7528\u3002\u6587\u7ae0\u9488\u5bf9\u5927\u8bed\u8a00\u6a21\u578b\uff08LLM\uff09\u5728\u63a8\u8350\u7cfb\u7edf\u5e94\u7528\u65f6\u4ee3\u4ef7\u9ad8\u6602\u7684\u95ee\u9898\uff0c\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3aSLIM\u7684\u57fa\u4e8e\u84b8\u998f\u7684\u5927\u6a21\u578b\u63a8\u8350\u6846\u67b6\u3002SLIM\u901a\u8fc7\u77e5\u8bc6\u84b8\u998f\u6280\u672f\uff0c\u5c06\u5927\u6a21\u578b\u7684\u77e5\u8bc6\u548c\u63a8\u7406\u80fd\u529b\u8fc1\u79fb\u5230\u8f83\u5c0f\u7684\u6a21\u578b\u4e0a\uff0c\u4ece\u800c\u8fbe\u5230\u7528\u66f4\u5c11\u53c2\u6570\u5b9e\u73b0\u9ad8\u6548\u63a8\u8350\u7684\u6548\u679c\u3002\u8bba\u6587\u5f3a\u8c03SLIM\u5728\u5904\u7406\u957f\u5c3e\u7269\u54c1\u548c\u65b0\u7528\u6237\u63a8\u8350\u7684\u4f18\u52bf\uff0c\u6539\u8fdb\u4e86\u4f20\u7edf\u57fa\u4e8e\u4ea4\u4e92\u6570\u636e\u7684\u63a8\u8350\u7cfb\u7edf\u504f\u5dee\u95ee\u9898\uff0c\u5e76\u5728\u4fdd\u6301\u63a8\u8350\u51c6\u786e\u5ea6\u548c\u53ef\u89e3\u91ca\u6027\u7684\u540c\u65f6\u964d\u4f4e\u8d44\u6e90\u6d88\u8017\u3002\\n\\n[\u300aAIOps \u667a\u80fd\u8fd0\u7ef4:\u6709\u6ca1\u6709\u6bd4\u4e13\u5bb6\u7ecf\u9a8c\u66f4\u4f18\u96c5\u7684\u9519/\u6162\u8c03\u7528\u5206\u6790\u5de5\u5177?\u300b](https://mp.weixin.qq.com/s/P7gOETO-EG3Ha7WjGs6Szg)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86\u963f\u91cc\u4e91\u5e94\u7528\u5b9e\u65f6\u76d1\u63a7\u670d\u52a1 ARMS \u6700\u65b0\u63a8\u51fa\u7684\u9519/\u6162 Trace \u5206\u6790\u529f\u80fd\u3002\u6b64\u529f\u80fd\u4e0d\u4f9d\u8d56\u4e13\u5bb6\u7ecf\u9a8c\uff0c\u80fd\u5bf9\u6bd4\u5206\u6790\u9519/\u6162 Trace \u548c\u6b63\u5e38 Trace \u7684\u6bcf\u4e2a\u7ef4\u5ea6\uff0c\u4ece\u800c\u5feb\u901f\u5b9a\u4f4d\u95ee\u9898\u6839\u6e90\u3002\u9488\u5bf9\u751f\u4ea7\u73af\u5883\u4e0b\u8c03\u7528\u65f6\u5ef6\u548c\u9519\u8bef\u8c03\u7528\u7684\u591a\u79cd\u56e0\u7d20\uff08\u5982\u6d41\u91cf\u4e0d\u5747\u3001\u5355\u673a\u6545\u969c\u7b49\uff09\uff0cARMS \u901a\u8fc7\u5bf9\u9519/\u6162 Trace \u548c\u6b63\u5e38 Trace \u7684\u5bf9\u6bd4\uff0c\u5e2e\u52a9\u7528\u6237\u53d1\u73b0\u5f02\u5e38\u7684\u5171\u540c\u7279\u5f81\uff0c\u4ece\u800c\u5b9a\u4f4d\u5230\u5177\u4f53\u95ee\u9898\u3002\u8fd9\u4e2a\u5de5\u5177\u63d0\u4f9b\u4e86\u4e00\u79cd\u4f18\u4e8e\u4f20\u7edf\u4e13\u5bb6\u7ecf\u9a8c\u7684\u5feb\u901f\u3001\u6709\u6548\u8bca\u65ad\u7cfb\u7edf\u95ee\u9898\u7684\u65b9\u6cd5\uff0c\u5e76\u4e14\u9644\u6709\u6700\u4f73\u5b9e\u8df5\u6848\u4f8b\u3002\u6587\u7ae0\u6700\u540e\u63d0\u4f9b\u4e86\u514d\u767b\u5f55\u7684 demo \u4f53\u9a8c\u94fe\u63a5\uff0c\u5f15\u5bfc\u7528\u6237\u4e86\u89e3\u548c\u4f7f\u7528\u8be5\u529f\u80fd\u3002\\n\\n[\u300aCUDA\u7f16\u7a0b\u4f18\u5316\u65b9\u6cd5\u2014\u2014Memory coalescing\u300b](https://mp.weixin.qq.com/s/9RaOOrroywQKnOhanBApsA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9CUDA\u7f16\u7a0b\u4e2d\u7684\u5185\u5b58\u5408\u5e76\u6280\u672f\u2014\u2014 Memory coalescing\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\u3002\u6587\u7ae0\u9996\u5148\u89e3\u91ca\u4e86\u5168\u5c40\u5185\u5b58\u7684\u7279\u70b9\u4ee5\u53ca\u4e3a\u4f55\u8bbf\u95ee\u901f\u5ea6\u6162\uff0c\u5e76\u9610\u8ff0\u4e86Memory coalescing\u7684\u76ee\u7684\u662f\u901a\u8fc7\u5408\u5e76\u5185\u5b58\u8bbf\u95ee\u64cd\u4f5c\u6765\u6709\u6548\u5730\u5229\u7528\u5e26\u5bbd\u3002\u901a\u8fc7\u5bf9\u591a\u7ef4\u6570\u7ec4\u7684\u5b58\u50a8\u65b9\u5f0f\u53ca\u8bbf\u95ee\u6a21\u5f0f\u7684\u89e3\u6790\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u8bb2\u89e3\u4e86Memory coalescing\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\uff0c\u5982\u4f55\u5728\u591a\u7ef4\u6570\u7ec4\u8bbf\u95ee\u548c\u77e9\u9635\u4e58\u6cd5\u4e2d\u5b9e\u73b0\u5185\u5b58\u8bbf\u95ee\u7684\u5408\u5e76\u3002\u6700\u540e\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4f18\u5316\u7b56\u7565\uff0c\u4ee5\u6539\u8fdb\u8ba1\u7b97\u7684\u5185\u5b58\u8bbf\u95ee\u6a21\u5f0f\uff0c\u5e76\u63d0\u9ad8CUDA\u5185\u5b58\u4f20\u8f93\u7684\u6548\u7387\u3002\\n\\n[\u300a\u6269\u6563\u6a21\u578b\u5982\u4f55\u6784\u5efa\u65b0\u4e00\u4ee3\u51b3\u7b56\u667a\u80fd\u4f53?\u8d85\u8d8a\u81ea\u56de\u5f52\uff0c\u540c\u65f6\u751f\u6210\u957f\u5e8f\u5217\u89c4\u5212\u8f68\u8ff9\u300b](https://mp.weixin.qq.com/s/b6D-vipDxKtlyocbxTObVQ)\u3002\u672c\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u6269\u6563\u6a21\u578b\u5728\u5f3a\u5316\u5b66\u4e60\u4e2d\u7684\u591a\u79cd\u5e94\u7528\u573a\u666f\uff0c\u63a2\u8ba8\u4e86\u5982\u4f55\u8d85\u8d8a\u4f20\u7edf\u7684\u81ea\u56de\u5f52\u65b9\u6cd5\uff0c\u540c\u65f6\u751f\u6210\u957f\u5e8f\u5217\u89c4\u5212\u8f68\u8ff9\u6765\u6a21\u4eff\u4eba\u7c7b\u7684\u51b3\u7b56\u8fc7\u7a0b\u3002\u4e0a\u6d77\u4ea4\u901a\u5927\u5b66\u7684\u56e2\u961f\u6240\u4f5c\u7684\u7efc\u8ff0\u68b3\u7406\u4e86\u6269\u6563\u6a21\u578b\u5728\u5f3a\u5316\u5b66\u4e60\u4e2d\u7684\u8fd0\u7528\u5982\u8f68\u8ff9\u89c4\u5212\u3001\u7b56\u7565\u8868\u5f81\u3001\u6570\u636e\u5408\u6210\uff0c\u53ca\u5176\u89e3\u51b3\u957f\u5e8f\u5217\u89c4\u5212\u8bef\u5dee\u7d2f\u79ef\u3001\u7b56\u7565\u8868\u8fbe\u80fd\u529b\u53d7\u9650\u548c\u6570\u636e\u7a00\u7f3a\u7b49\u95ee\u9898\u7684\u5de8\u5927\u6f5c\u529b\u3002\u6700\u7ec8\uff0c\u6587\u7ae0\u5bf9\u6269\u6563\u6a21\u578b\u672a\u6765\u7684\u53d1\u5c55\u65b9\u5411\u8fdb\u884c\u4e86\u5c55\u671b\uff0c\u63d0\u51fa\u4e86\u751f\u6210\u5f0f\u4eff\u771f\u73af\u5883\u3001\u52a0\u5165\u5b89\u5168\u7ea6\u675f\u3001\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u53ca\u7ec4\u5408\u591a\u79cd\u6280\u80fd\u7b49\u591a\u4e2a\u7814\u7a76\u65b9\u5411\u3002\\n\\n[\u300a\u52a8\u624b\u505a\u4e00\u4e2a\u6700\u5c0fRAG\u2014\u2014TinyRAG\u300b](https://mp.weixin.qq.com/s/GII5CwvB4FuxkT7yzyf_4Q)\u3002\u672c\u6587\u7531\u4e0d\u8981\u8471\u59dc\u849c\u6307\u5bfc\u8bfb\u8005\u5982\u4f55\u4e00\u6b65\u6b65\u5b9e\u73b0\u57fa\u4e8e\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u6280\u672f\uff08RAG\uff09\u7684\u7b80\u5316\u6a21\u578b\u2014\u2014TinyRAG\u3002TinyRAG\u4ec5\u5305\u542bRAG\u6838\u5fc3\u529f\u80fd\uff0c\u5373Retrieval\uff08\u68c0\u7d22\uff09\u548cGeneration\uff08\u751f\u6210\uff09\u4e24\u4e2a\u6a21\u5757\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86RAG\u7684\u57fa\u672c\u7ed3\u6784\uff0c\u5305\u62ec\u5411\u91cf\u5316\u6a21\u5757\u3001\u6587\u6863\u52a0\u8f7d\u4e0e\u5207\u5206\u6a21\u5757\u3001\u6570\u636e\u5e93\u548c\u68c0\u7d22\u6a21\u5757\uff0c\u4ee5\u53ca\u5982\u4f55\u6839\u636e\u68c0\u7d22\u5185\u5bb9\u751f\u6210\u56de\u7b54\u3002\u6b64\u5916\uff0c\u8fd8\u63d0\u4f9b\u4e86\u5bf9\u5e94\u7684\u5f00\u6e90\u9879\u76ee[\u4ee3\u7801](https://github.com/KMnO4-zx/TinyRAG)\uff0c\u52a9\u529b\u7406\u89e3\u8bed\u8a00\u6a21\u578b\u4e0eRAG\u7684\u539f\u7406\uff0c\u5e76\u80fd\u591f\u5728\u5b9e\u8df5\u4e2d\u52a0\u4ee5\u5e94\u7528\u548c\u62d3\u5c55\u3002\\n\\n[\u300a\u804a\u4e00\u804aTransformer\u4e2d\u7684FFN\u300b](https://mp.weixin.qq.com/s/1jTw_5_re4GWWLqgKnkSww)\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u4e3a\u4ec0\u4e48Transformer\u7684\u524d\u9988\u795e\u7ecf\u7f51\u7edc\uff08FFN\uff09\u90e8\u5206\u957f\u671f\u4ee5\u6765\u51e0\u4e4e\u6ca1\u6709\u5927\u7684\u6539\u52a8\u3002\u6587\u7ae0\u901a\u8fc7\u6bd4\u8f83\u4e0d\u540c\u7684\u6fc0\u6d3b\u51fd\u6570\uff0c\u5982ReLU\u3001GeLU\u548cSwish\u7b49\uff0c\u5206\u6790\u5b83\u4eec\u5728Transformer\u4e2d\u7684\u5e94\u7528\u6548\u679c\u548c\u5c40\u9650\u6027\u3002\u540c\u65f6\u63a2\u8ba8\u4e86\u7ebf\u6027\u6295\u5f71\u7684\u5fc5\u8981\u6027\u3001\u53c2\u6570\u91cf\u53ca\u5176\u5bf9\u6a21\u578b\u5bb9\u91cf\u548c\u8bb0\u5fc6\u529b\u7684\u5f71\u54cd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u6d89\u53ca\u4e86\u6df7\u5408\u4e13\u5bb6\u6a21\u578b\uff08Mixture-of-Experts\uff0cMoE\uff09\u4ee5\u63d0\u5347Transformer\u7684\u6548\u7387\uff0c\u5e76\u8ba8\u8bba\u4e86\u6784\u5efa\u901a\u7528\u4eba\u5de5\u667a\u80fd\uff08AGI\uff09\u6240\u9700\u8981\u7684\u7ed3\u6784\u7279\u6027\uff0c\u7279\u522b\u662f\u653e\u7f29\u5b9a\u5f8b\uff08Scaling Law\uff09\u3001\u4e0a\u4e0b\u6587\u5b66\u4e60\uff08In-Context Learning\uff09\u3001\u6548\u7387\u63d0\u5347\uff08Better Efficiency\uff09\u548c\u7ec8\u751f\u5b66\u4e60\uff08Life-long learning\uff09\u7684\u91cd\u8981\u6027\uff0c\u6700\u540e\u5bf9\u672a\u6765\u7ed3\u6784\u521b\u65b0\u7ed9\u51fa\u900f\u5f7b\u89c1\u89e3\u3002\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u300aMore powerful Go execution traces\u300b](https://go.dev/blog/execution-traces-2024)\u3002Go\u7684runtime/trace\u5305\u63d0\u4f9b\u4e86\u7528\u4e8e\u7406\u89e3\u548c\u6392\u67e5Go\u7a0b\u5e8f\u7684\u5f3a\u5927\u5de5\u5177\uff0c\u5141\u8bb8\u5bf9goroutine\u7684\u6267\u884c\u8fdb\u884c\u8ddf\u8e2a\u3002\u65b0\u7248\u672cGo\u5927\u5e45\u5ea6\u964d\u4f4e\u4e86\u6267\u884c\u8ddf\u8e2a\u7684\u8fd0\u884c\u65f6\u5f00\u9500\uff0c\u4ece\u591a\u6570\u5e94\u7528\u4e2d\u768410-20% CPU\u4e0b\u964d\u52301-2%\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u5c06trace\u5206\u5272\uff0c\u4ece\u800c\u4f7f\u5f97trace\u53ef\u4ee5\u6269\u5c55\u4e14\u4fdd\u6301\u4f4e\u5f00\u9500\uff0c\u8fd8\u5b9e\u73b0\u4e86\u98de\u884c\u8bb0\u5f55\u529f\u80fd\uff0c\u4f7f\u5f97\u5373\u4f7f\u5728\u4e8b\u4ef6\u53d1\u751f\u540e\u4e5f\u80fd\u4ecetrace\u4e2d\u83b7\u53d6\u4fe1\u606f\u3002Go\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e2a\u5b9e\u9a8c\u6027\u7684trace\u8bfb\u53d6API\uff0c\u4f7f\u7a0b\u5e8f\u6027\u7684\u8ddf\u8e2a\u5206\u6790\u6210\u4e3a\u53ef\u80fd\u3002\\n\\n[\u300aRust: \u5b9e\u73b0\u6bd4\u7279\u5e01\u7684\u4ea4\u6613\u6a21\u578b\u300b](https://juejin.cn/post/7346394191264710666)\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u6bd4\u7279\u5e01\u7684\u4ea4\u6613\u6a21\u578b\u4e2d\u7684UTXO\uff08\u672a\u82b1\u8d39\u4ea4\u6613\u8f93\u51fa\uff09\u6a21\u578b\uff0c\u5e76\u4f7f\u7528 Rust \u8bed\u8a00\u6765\u5b9e\u73b0\u548c\u5c55\u793a\u5176\u8fd0\u4f5c\u8fc7\u7a0b\u3002UTXO \u6a21\u578b\u4e0e\u4f20\u7edf\u7684\u8d26\u6237\u4f59\u989d\u6a21\u578b\u4e0d\u540c\uff0c\u5c06\u7528\u6237\u7684\u4f59\u989d\u5206\u6563\u5b58\u50a8\u5728\u591a\u4e2aUTXO\u4e2d\u3002\u6bcf\u4e2aUTXO\u4ee3\u8868\u6bd4\u7279\u5e01\u7f51\u7edc\u4e0a\u4e00\u7b14\u53ef\u7528\u4e8e\u672a\u6765\u4ea4\u6613\u7684\u8f93\u51fa\u3002\u6587\u7ae0\u89e3\u91ca\u4e86UTXO\u6a21\u578b\u7684\u5de5\u4f5c\u539f\u7406\u3001\u4f18\u52bf\u4ee5\u53ca\u4ea4\u6613\u5904\u7406\u6d41\u7a0b\uff0c\u5305\u62ec\u9009\u62e9\u8f93\u5165\u3001\u751f\u6210\u8f93\u51fa\u3001\u7b7e\u540d\u4ea4\u6613\u548c\u5e7f\u64ad\u4ea4\u6613\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u4e2a Rust \u5b9e\u73b0\u7684\u7b80\u5316\u793a\u4f8b\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u5b9a\u4e49\u4ea4\u6613\u7ed3\u6784\u4f53\u3001\u8f93\u5165\u3001\u8f93\u51fa\u4ee5\u53caUTXO\u96c6\u5408\uff0c\u5e76\u4ecb\u7ecd\u4e86\u57fa\u672c\u7684\u64cd\u4f5c\u65b9\u6cd5\u3002\u5982\u679c\u4f60\u5bf9\u6bd4\u7279\u5e01\u4ea4\u6613\u6a21\u578b\u548c Rust \u7f16\u7a0b\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u9605\u8bfb\u8be5\u6587\u7ae0\u4e86\u89e3\u66f4\u591a\u7ec6\u8282\u3002\\n\\n[\u300a\u6df1\u5165\u7406\u89e3 Go Modules: \u9ad8\u6548\u7ba1\u7406\u4f60\u7684 Golang \u9879\u76ee\u4f9d\u8d56\u300b](https://juejin.cn/post/7309692103055507491)\u3002\u672c\u6587\u8be6\u7ec6\u4ecb\u7ecd\u4e86 Go Modules \u5728 Golang \u9879\u76ee\u4e2d\u7684\u4f7f\u7528\u65b9\u6cd5\u548c\u539f\u7406\u3002\u6587\u7ae0\u9996\u5148\u56de\u987e\u4e86 Go \u4f9d\u8d56\u7ba1\u7406\u7684\u5386\u53f2\uff0c\u4ece GOPATH\u3001Go Vendor \u5230 Go Module \u7684\u6f14\u8fdb\u8fc7\u7a0b\u3002\u7136\u540e\u8bb2\u89e3\u4e86\u6a21\u5757\u3001\u5305\u548c\u7248\u672c\u7684\u6982\u5ff5\uff0c\u5305\u62ec\u6a21\u5757\u8def\u5f84\u3001\u5305\u8def\u5f84\u4ee5\u53ca\u7248\u672c\u7684\u683c\u5f0f\u548c\u8bed\u4e49\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86 Go Modules \u7684\u73af\u5883\u914d\u7f6e\uff0c\u5305\u62ec go env \u73af\u5883\u53d8\u91cf\u548c\u4f9d\u8d56\u7ba1\u7406\u6587\u4ef6\uff08go.mod \u548c go.sum\uff09\u7684\u4f5c\u7528\u548c\u4f7f\u7528\u65b9\u6cd5\u3002\u6700\u540e\uff0c\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u7528\u6280\u5de7\u548c\u5e38\u89c1\u95ee\u9898\u7684\u89e3\u7b54\uff0c\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u5e94\u7528 Go Modules\u3002\u5982\u679c\u4f60\u5bf9 Golang \u9879\u76ee\u7684\u4f9d\u8d56\u7ba1\u7406\u611f\u5174\u8da3\uff0c\u53ef\u4ee5\u9605\u8bfb\u8be5\u6587\u7ae0\u4e86\u89e3\u66f4\u591a\u8be6\u60c5\u3002\\n\\n[\u300aKubernetes\u96c6\u7fa4\u8282\u70b9\u5904\u4e8eNot Ready\u95ee\u9898\u6392\u67e5\u300b](https://mp.weixin.qq.com/s/GxTtiqMpcrDWK9toaK5CMw)\u3002\u5f53Kubernetes\u96c6\u7fa4\u4e2d\u7684\u8282\u70b9\u663e\u793a\u4e3a\\"Not Ready\\"\u72b6\u6001\u65f6\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u7cfb\u5217\u7684\u6392\u67e5\u6b65\u9aa4\u3002\u9996\u5148\uff0c\u901a\u8fc7\u8fd0\u884c\u7279\u5b9a\u7684kubectl\u547d\u4ee4\u6765\u786e\u8ba4\u8282\u70b9\u7684\u72b6\u6001\u5e76\u83b7\u53d6\u8282\u70b9\u8be6\u7ec6\u4fe1\u606f\uff0c\u68c0\u67e5\u53ef\u80fd\u7684\u9519\u8bef\u6d88\u606f\u6216\u8005\u8b66\u544a\u3002\u63a5\u7740\uff0c\u8fdb\u5165\u8282\u70b9\u7cfb\u7edf\u67e5\u770b\u5404\u79cd\u7cfb\u7edf\u65e5\u5fd7\uff0c\u5e76\u4f7f\u7528\u76f8\u5173\u547d\u4ee4\u5982grep\u3001cat\u6216tail\u6765\u8f85\u52a9\u5206\u6790\u3002\u6587\u7ae0\u8fd8\u5efa\u8bae\u68c0\u67e5kubelet\u670d\u52a1\u72b6\u6001\u548c\u914d\u7f6e\u6587\u4ef6\uff0c\u786e\u8ba4\u7cfb\u7edf\u8d44\u6e90\u662f\u5426\u5145\u8db3\uff0c\u8bd5\u56fe\u89e3\u51b3\u53ef\u80fd\u5b58\u5728\u7684\u78c1\u76d8\u7a7a\u95f4\u548c\u7f51\u7edc\u95ee\u9898\u3002\u6700\u540e\uff0c\u901a\u8fc7\u4f7f\u7528\u8bf8\u5982ping\u3001traceroute\u7b49\u8bca\u65ad\u5de5\u5177\u786e\u4fdd\u8282\u70b9\u80fd\u591f\u4e0e\u4e3b\u8282\u70b9\u901a\u4fe1\uff0c\u5e76\u68c0\u67e5\u91cd\u8981\u7684\u7f51\u7edc\u7aef\u53e3\u662f\u5426\u5f00\u653e\u3002\u786e\u4fddKubelet\u80fd\u6b63\u786e\u8fde\u63a5\u5230Kubernetes API\uff0c\u5e76\u4f7f\u7528Kubernetes\u7684\u8bca\u65ad\u5de5\u5177\u5982kubectl get componentstatus\u68c0\u67e5\u7ec4\u4ef6\u72b6\u6001\u3002\u901a\u8fc7\u8fd9\u4e9b\u6b65\u9aa4\uff0c\u53ef\u4ee5\u7cfb\u7edf\u5730\u6392\u67e5\u5e76\u89e3\u51b3\\"Not Ready\\"\u7684\u95ee\u9898\uff0c\u4fdd\u6301\u96c6\u7fa4\u5065\u5eb7\u3002\\n\\n[\u300aGo \u9519\u8bef\u5904\u7406: \u7528 select-case \u6765\u89e3\u51b3\u8fd9\u4e2a\u5386\u53f2\u96be\u9898?\u300b](https://mp.weixin.qq.com/s/iuzDw7_w20jtjJUlynv9NA)\u3002\u714e\u9c7c\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u4ecb\u7ecd\u4e86\u4e00\u4e2a\u65b0\u7684Go\u8bed\u8a00\u9519\u8bef\u5904\u7406\u63d0\u6848\uff0c\u8fd9\u4e2a\u63d0\u6848\u5c1d\u8bd5\u7528`select-case`\u7ed3\u6784\u4f5c\u4e3a\u9519\u8bef\u68c0\u67e5\u7684\u66ff\u4ee3\u3002\u8fd9\u4e2a\u65b0\u8bed\u6cd5\u5141\u8bb8\u5728`select`\u5173\u952e\u5b57\u4e4b\u540e\u58f0\u660e\u4e00\u4e2a\u53d8\u91cf\u4e3a\u201c\u9677\u9631\u201d\uff0c\u8d4b\u503c\u7ed9\u8be5\u53d8\u91cf\u65f6\u89e6\u53d1`case`\u68c0\u67e5\uff0c\u4ee5\u51cf\u5c11\u4f20\u7edf\u7684`if err != nil`\u68c0\u67e5\u7684\u7e41\u7410\u6027\u3002\u65b0\u63d0\u6848\u4fdd\u6301\u4e86Go1\u4ee3\u7801\u7684\u517c\u5bb9\u6027\uff0c\u5c1d\u8bd5\u63d0\u4f9b\u4e00\u4e2a\u66f4\u7b80\u6d01\u3001\u5411\u540e\u517c\u5bb9\u7684\u9519\u8bef\u5904\u7406\u65b9\u5f0f\uff0c\u5c3d\u7ba1\u76ee\u524d\u793e\u533a\u5185\u5bf9\u6b64\u4ecd\u672a\u8fbe\u6210\u5171\u8bc6\u3002\\n\\n[\u300aK8s\u84dd\u7eff\u90e8\u7f72:\u4f18\u96c5\u5e94\u5bf9\u5e94\u7528\u7a0b\u5e8f\u66f4\u65b0\u6311\u6218\u300b](https://mp.weixin.qq.com/s/Dc5wOBAE_jSiTKqPc6M4Dg)\u3002\u672c\u6587\u8be6\u7ec6\u63a2\u8ba8\u4e86\u4f7f\u7528Kubernetes\uff08K8s\uff09\u8fdb\u884c\u84dd\u7eff\u90e8\u7f72\u7684\u65b9\u6cd5\uff0c\u4ee5\u8fbe\u5230\u65e0\u7f1d\u66f4\u65b0\u5e94\u7528\u7a0b\u5e8f\u5e76\u6700\u5c0f\u5316\u5b95\u673a\u65f6\u95f4\u3002\u84dd\u7eff\u90e8\u7f72\u662f\u4e00\u4e2a\u8fd0\u884c\u4e24\u4e2a\u76f8\u540c\u751f\u4ea7\u73af\u5883\u7684\u6a21\u5f0f\uff0c\u80fd\u591f\u5728\u66f4\u65b0\u65f6\u5207\u6362\u6d41\u91cf\uff0c\u786e\u8ba4\u65e0\u8bef\u540e\u4fbf\u53bb\u9664\u65e7\u73af\u5883\u3002\u6587\u7ae0\u6307\u5bfc\u4e86\u4ece\u521b\u5efa\u547d\u540d\u7a7a\u95f4\u3001\u521b\u5efa\u548c\u5e94\u7528\u90e8\u7f72\u3001\u670d\u52a1\u53ca\u5176\u8def\u7531\u89c4\u5219\u3001\u6267\u884c\u84dd\u7eff\u5207\u6362\uff0c\u5230\u6700\u540e\u7684\u9a8c\u8bc1\u548c\u56de\u6eda\u8fc7\u7a0b\u3002\u8fd9\u4e00\u8fc7\u7a0b\u4e0d\u4ec5\u4f18\u5316\u4e86\u5e94\u7528\u7248\u672c\u7684\u6eda\u52a8\u66f4\u65b0\uff0c\u4e5f\u4e3a\u5f00\u53d1\u8005\u63d0\u4f9b\u4e86\u5feb\u901f\u56de\u6eda\u7684\u65b9\u6848\uff0c\u4ee5\u5e94\u5bf9\u53ef\u80fd\u51fa\u73b0\u7684\u95ee\u9898\u3002\\n\\n[\u300aGo \u4e2d\u7684\u9ad8\u901f\u6570\u636e\u5305\u5904\u7406:\u4ece net.Dial \u5230 AF_XDP\u300b](https://mp.weixin.qq.com/s/RzglzZ0xY9NmsgujdHa-Tw)\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4f7f\u7528 Go \u8bed\u8a00\u8fdb\u884c\u9ad8\u901f\u6570\u636e\u5305\u5904\u7406\u7684\u591a\u79cd\u65b9\u6cd5\uff0c\u5305\u62ec net.Dial\u3001\u539f\u59cb\u5957\u63a5\u5b57\u3001\u7cfb\u7edf\u8c03\u7528\u3001pcap \u548c AF_PACKET\uff0c\u76f4\u81f3\u6700\u65b0\u7684 AF_XDP \u65b9\u5f0f\u3002\u4f5c\u8005\u8be6\u7ec6\u5bf9\u6bd4\u4e86\u6bcf\u79cd\u65b9\u6cd5\u7684\u6027\u80fd\uff0c\u4ece\u7b80\u5355\u7684 net.Dial \u6a21\u5f0f\u6f14\u8fdb\u5230 AF_XDP\uff0c\u9010\u6b65\u63d0\u9ad8\u6570\u636e\u5305\u6bcf\u79d2\u5904\u7406\u6570\u91cf\uff0c\u540c\u65f6\u6307\u51fa\u5404\u65b9\u6cd5\u7684\u4f7f\u7528\u573a\u5408\u548c\u9650\u5236\u3002\u901a\u8fc7\u57fa\u51c6\u6d4b\u8bd5\uff0c\u53d1\u73b0\u4f7f\u7528 AF_XDP \u53ef\u5b9e\u73b0\u6700\u9ad8\u6027\u80fd\uff0c\u5904\u7406\u901f\u5ea6\u662f\u4f7f\u7528 net.Dial \u65b9\u6cd5\u76844\u500d\u591a\u3002\u8fd9\u4e9b\u6280\u672f\u63a2\u8ba8\u5bf9\u4e8e\u9700\u8981\u5927\u91cf\u7f51\u7edc\u6570\u636e\u5305\u5904\u7406\u7684\u573a\u666f\uff0c\u5982\u7f51\u7edc\u76d1\u63a7\u3001\u6027\u80fd\u8bc4\u4f30\u7b49\u90fd\u662f\u975e\u5e38\u91cd\u8981\u7684\u3002\\n\\n[\u300a\u6570\u636e\u5e93\u4e0d\u5e94\u653e\u5728\u5bb9\u5668\u4e2d?- B\u7ad9Kubernetes\u6709\u72b6\u6001\u670d\u52a1\u5b9e\u8df5(Elasticsearch/Clickhouse)\u300b](https://mp.weixin.qq.com/s/dCQPOx2n2w36Q3P3hCKe8A)\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5728\u4e91\u539f\u751f\u65f6\u4ee3\u4e0b\uff0c\u6709\u72b6\u6001\u670d\u52a1\uff08\u5982\u751f\u4ea7\u73af\u5883\u7684\u6570\u636e\u5e93\uff09\u662f\u5426\u9002\u7528\u4e8e\u5bb9\u5668\u5316\u5e76\u7531Kubernetes\u8fdb\u884c\u7ba1\u7406\u7684\u95ee\u9898\u3002\u4ee5B\u7ad9Elasticsearch\u548cClickhouse\u7684\u5bb9\u5668\u5316\u548cKubernetes\u7f16\u6392\u5b9e\u8df5\u4e3a\u4f8b\uff0c\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5728\u5bb9\u5668\u73af\u5883\u4e2d\u90e8\u7f72\u8fd9\u4e9b\u6709\u72b6\u6001\u670d\u52a1\u7684\u6311\u6218\u548c\u89e3\u51b3\u65b9\u6848\uff0c\u5305\u62ec\u63a7\u5236\u5668\u7684\u9009\u62e9\u3001\u6301\u4e45\u5316\u5b58\u50a8\u3001\u78c1\u76d8\u8c03\u5ea6\u3001\u8c03\u5ea6\u5668\u3001\u5bb9\u5668\u7f51\u7edc\u3001\u670d\u52a1\u53d1\u73b0\u4ee5\u53ca\u5982\u4f55\u4fdd\u8bc1\u96c6\u7fa4\u548c\u6570\u636e\u7684\u9ad8\u53ef\u7528\u6027\u3002\u4f5c\u8005\u5206\u4eab\u4e86\u901a\u8fc7Operator\u7ba1\u7406\u6709\u72b6\u6001\u670d\u52a1\u5e94\u7528\u3001\u4f7f\u7528\u672c\u5730\u76d8PV\u63d0\u5347\u6027\u80fd\u3001LVM\u6280\u672f\u7684\u52a8\u6001\u6269\u7f29\u5bb9\u65b9\u6848\u4ee5\u53ca\u901a\u8fc7macvlan\u8fdb\u884c\u5bb9\u5668\u95f4\u9ad8\u6548\u901a\u4fe1\u7684\u6280\u672f\u7ec6\u8282\u3002\\n\\n[\u300a\u4e00\u6587\u5e26\u60a8\u63a2\u7d22 Kubernetes \u4e2d\u7684\u5bb9\u5668\u7c7b\u578b\u300b](https://mp.weixin.qq.com/s/-TXbvQiR-tpB0RgQ5d-QDw)\u3002\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5728 Kubernetes \u7cfb\u7edf\u4e2d\u5e38\u89c1\u7684\u56db\u79cd\u5bb9\u5668\u7c7b\u578b\uff1a\u521d\u59cb\u5316\u5bb9\u5668(Init Container)\u3001\u8fb9\u8f66\u5bb9\u5668(Sidecar Container)\u3001\u4e34\u65f6\u5bb9\u5668(Ephemeral Container)\u548c\u591a\u5bb9\u5668(Multi Container)\u3002\u521d\u59cb\u5316\u5bb9\u5668\u7528\u4e8e\u8fd0\u884c Pod \u4e2d\u4e3b\u5bb9\u5668\u542f\u52a8\u524d\u7684\u51c6\u5907\u5de5\u4f5c\uff0c\u800c\u8fb9\u8f66\u5bb9\u5668\u5219\u4e0e\u4e3b\u5e94\u7528\u5bb9\u5668\u5e76\u884c\u8fd0\u884c\uff0c\u4e3a\u5176\u63d0\u4f9b\u652f\u6301\u670d\u52a1\u3002\u4e34\u65f6\u5bb9\u5668\u4e3b\u8981\u7528\u4e8e\u6545\u969c\u6392\u9664\uff0c\u800c\u591a\u5bb9\u5668 Pods \u5141\u8bb8\u5e76\u884c\u8fd0\u884c\u591a\u4e2a\u5bb9\u5668\uff0c\u5171\u4eab\u8d44\u6e90\u548c\u6570\u636e\u3002\u6587\u7ae0\u63d0\u4f9b\u4e86\u6bcf\u79cd\u5bb9\u5668\u7684\u8be6\u7ec6\u4f7f\u7528\u6848\u4f8b\u3001\u914d\u7f6e\u65b9\u6cd5\u548c\u547d\u4ee4\uff0c\u5e76\u5f3a\u8c03\u4e86\u5404\u81ea\u7684\u7279\u70b9\u4e0e\u5e94\u7528\u573a\u666f\u3002\\n\\n[\u300a4 \u79d2\u5904\u7406 10 \u4ebf\u884c\u6570\u636e! Go \u8bed\u8a00\u7684 9 \u5927\u4ee3\u7801\u65b9\u6848\uff0c\u4e00\u4e2a\u6bd4\u4e00\u4e2a\u5feb\u300b](https://mp.weixin.qq.com/s/iylZAKZfxLL6SYruww_8zA)\u3002\u8f6f\u4ef6\u5de5\u7a0b\u5e08Ben Hoyt\u6311\u6218\u4f7f\u7528Go\u8bed\u8a00\u5904\u740610\u4ebf\u884c\u6570\u636e\uff0c\u5e76\u63d0\u51fa\u4e869\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u5176\u4e2d\u6700\u5feb\u57284\u79d2\u5185\u5b8c\u6210\u3002\u8fd9\u4e9b\u65b9\u6848\u53ea\u4f7f\u7528Go\u6807\u51c6\u5e93\uff0c\u5305\u62ec\u7b80\u5355\u4f46\u4f18\u5316\u7684map\u5904\u7406\u3001\u5e76\u884c\u5316\u5904\u7406\u7b49\u3002Ben\u7684\u65b9\u6848\u867d\u672a\u6700\u5feb\uff0c\u4f46\u5c55\u73b0\u4e86\u72ec\u7acb\u601d\u8003\u7684\u4ef7\u503c\u3002\u4ed6\u7684\u6d4b\u8bd5\u8868\u660e\uff0c\u5f7b\u5e95\u5730\u6570\u636e\u5904\u7406\u548c\u7b97\u6cd5\u4f18\u5316\u53ef\u663e\u8457\u63d0\u9ad8\u6027\u80fd\uff0c\u51cf\u5c11\u8ba1\u7b97\u6210\u672c\u3002\\n\\n[\u300aGo arena \u6c11\u95f4\u5e93\u6765\u4e86\uff0c\u53ef\u4ee5\u624b\u52a8\u7ba1\u7406\u5185\u5b58!\u300b](https://mp.weixin.qq.com/s/aS-azhReZL5epoG_3n0hyg)\u3002\u6587\u4e2d\u4f5c\u8005\u714e\u9c7c\u4ecb\u7ecd\u4e86Go\u8bed\u8a00\u7684\u4e00\u4e2a\u65b0\u7684\u7b2c\u4e09\u65b9\u5e93ortuman/nuke\uff0c\u8fd9\u4e2a\u5e93\u5141\u8bb8\u5f00\u53d1\u8005\u624b\u52a8\u7ba1\u7406\u5185\u5b58\u3002\u6587\u7ae0\u9996\u5148\u56de\u987e\u4e86Go\u5b98\u65b9\u5bf9\u4e8earena\u624b\u52a8\u5185\u5b58\u7ba1\u7406\u63d0\u6848\u7684\u505c\u6ede\u73b0\u72b6\uff0c\u7136\u540e\u91cd\u70b9\u4ecb\u7ecd\u4e86\u5982\u4f55\u4f7f\u7528ortuman/nuke\u5e93\u8fdb\u884c\u5185\u5b58\u7ba1\u7406\uff0c\u5305\u62ec\u5e93\u7684\u5b89\u88c5\u3001\u4f7f\u7528\u6848\u4f8b\u4ee5\u53ca\u5982\u4f55\u5728\u5e76\u53d1\u573a\u666f\u4e0b\u4fdd\u6301\u7ebf\u7a0b\u5b89\u5168\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u89e3\u4e86arena\u5185\u5b58\u7ba1\u7406\u7684\u4f18\u70b9\uff0c\u4f8b\u5982\u9ad8\u6548\u7387\u548c\u4e00\u6b21\u6027\u91ca\u653e\uff0c\u5e76\u5bf9\u5e93\u7684\u5b9e\u9645\u7528\u6cd5\uff0c\u5982\u901a\u8fc7context\u5728HTTP\u8bf7\u6c42\u5468\u671f\u4e2d\u7ba1\u7406\u5185\u5b58\uff0c\u8fdb\u884c\u4e86\u5c55\u793a\u3002\u6700\u540e\uff0c\u57fa\u4e8e\u6027\u80fd\u8003\u8651\uff0c\u6587\u7ae0\u8fd8\u63d0\u4f9b\u4e86\u5e76\u53d1\u4e0e\u975e\u5e76\u53d1\u4e1a\u52a1\u573a\u666f\u4e0b\u7684\u57fa\u51c6\u6d4b\u8bd5\u7ed3\u679c\u4ee5\u53ca\u6027\u80fd\u5dee\u5f02\u3002\\n\\n[Go \u8bed\u8a00\u4e2d\u5982\u4f55\u5927\u5c0f\u7aef\u5b57\u8282\u5e8f\uff1fint \u8f6c byte \u662f\u5982\u4f55\u8fdb\u884c\u7684](https://mp.weixin.qq.com/s/xRxRe6DkWJVcGKXOt1oGlQ)\\n\\n[Go \u4e2d\u5982\u4f55\u5b9e\u73b0\u4e09\u5143\u8fd0\u7b97\u7b26\uff1fRust \u548c Python \u662f\u600e\u4e48\u505a\u7684](https://mp.weixin.qq.com/s/USKjmlyTtexSQtToOg481g)\\n\\n[Go\u8bed\u8a00\u4e2d enum \u5b9e\u73b0\u65b9\u5f0f\u6709\u54ea\u4e9b\uff1f\u4e00\u5b9a\u8981\u7edd\u5bf9\u7c7b\u578b\u5b89\u5168\u5417](https://mp.weixin.qq.com/s/mFZewdDxlK4O_wUWR6mVjg)\\n\\n[Go \u4e2d\u5982\u4f55\u6253\u5370\u7ed3\u6784\u4f53\uff1f \u4ee3\u7801\u8c03\u8bd5\u6548\u7387\u63d0\u5347](https://mp.weixin.qq.com/s/obOG_Kior34ktLek3_-GZg)\\n\\n[\u300a\u5feb\u770b! Go 1.22 \u5bf9for\u5faa\u73af\u8fdb\u884c\u4e86\u4e24\u4e2a\u5927\u66f4\u65b0\u300b](https://mp.weixin.qq.com/s/9ARiVYpYRy4FCuSJ5IKuGw)\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728 1.22 \u7248\u672c\u4e2d\u9488\u5bf9for\u5faa\u73af\u4f5c\u51fa\u7684\u4e24\u9879\u4e3b\u8981\u66f4\u65b0\uff1a1. \u6bcf\u6b21\u8fed\u4ee3\u7684for\u5faa\u73af\u90fd\u5c06\u5b9a\u4e49\u4e00\u4e2a\u65b0\u7684\u53d8\u91cf\uff0c\u4e0d\u518d\u5171\u7528\u540c\u4e00\u4e2a\u53d8\u91cf\uff1b2. \u5f15\u5165\u4e86\u5bf9\u6574\u6570\u8303\u56f4\u7684\u5faa\u73af\u8fed\u4ee3\u652f\u6301\u3002\u8fd9\u4e9b\u66f4\u65b0\u89e3\u51b3\u4e86\u95ed\u5305\u5728\u5e76\u53d1\u6267\u884c\u65f6\u5171\u4eab\u53d8\u91cf\u5e26\u6765\u7684\u95ee\u9898\uff0c\u540c\u65f6\u4e5f\u7b80\u5316\u4e86\u5faa\u73af\u7ed3\u6784\uff0c\u63d0\u9ad8\u4e86\u7f16\u5199\u5bf9\u6574\u6570\u8303\u56f4\u8fdb\u884c\u8fed\u4ee3\u4ee3\u7801\u7684\u65b9\u4fbf\u6027\u3002\u6587\u4e2d\u63d0\u4f9b\u4e86\u8be6\u7ec6\u7684\u4ee3\u7801\u793a\u4f8b\u6765\u5c55\u793a\u65b0\u65e7\u7248\u672c\u4e4b\u95f4\u7684\u5dee\u5f02\uff0c\u5e76\u8bf4\u660e\u4e86\u5982\u4f55\u5229\u7528\u65b0\u7279\u6027\u6765\u7f16\u5199\u66f4\u9ad8\u6548\u7684Go\u4ee3\u7801\u3002\\n\\n[\u300a\u4ece\u6162\u901f\u5230SIMD\u300b\u804aGo\u8fb9\u754c\u68c0\u67e5\u6d88\u9664\u300b](https://mp.weixin.qq.com/s/lxp9OqiVAHtoX75UoaHipw)\u3002\u672c\u6587\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u4e2d\u8fb9\u754c\u68c0\u67e5\u6d88\u9664\uff08BCE\uff09\u7684\u76f8\u5173\u6280\u5de7\u548c\u6700\u4f73\u5b9e\u8df5\u3002\u6587\u7ae0\u9996\u5148\u56de\u7b54\u4e86\u4e3a\u4f55\u5728Go\u4ee3\u7801\u4e2d\u4f18\u5316\u65f6\u9009\u62e9\u4f7f\u7528`a[i:i+4:i+4]`\u800c\u4e0d\u662f`a[i:i+4]`\u7684\u95ee\u9898\uff0c\u6307\u51fa\u524d\u8005\u80fd\u51cf\u5c11\u7f16\u8bd1\u5668\u5de5\u4f5c\u91cf\u4ece\u800c\u63d0\u9ad8\u6027\u80fd\u3002\u7136\u540e\uff0c\u4ecb\u7ecd\u4e86Go101\u63d0\u51fa\u7684BCE\u6280\u672f\u8be6\u89e3\u4e0e\u5e94\u7528\u5b9e\u4f8b\uff0c\u4ee5\u53ca\u5982\u4f55\u4f7f\u7528\u7f16\u8bd1\u547d\u4ee4\u6765\u68c0\u6d4b\u8fb9\u754c\u68c0\u67e5\u7684\u5b58\u5728\u3002\u6587\u4e2d\u8fd8\u5168\u9762\u68b3\u7406\u4e86Go BCE\u6280\u672f\u7684\u53d1\u5c55\u5386\u7a0b\uff0c\u4ee5\u53ca\u5728\u4e0d\u540c\u573a\u666f\u4e0b\u6d88\u9664\u5197\u4f59\u8fb9\u754c\u68c0\u67e5\u7684\u65b9\u6cd5\uff0c\u5305\u62ec\u5229\u7528\u5faa\u73af\u53d8\u91cf\u3001\u5e38\u91cf\u7d22\u5f15\u7b49\u7b56\u7565\u6765\u63d0\u9ad8\u4ee3\u7801\u6267\u884c\u6548\u7387\u3002\u6700\u540e\uff0c\u63d0\u4f9b\u4e86\u591a\u79cd\u7f16\u7a0b\u6280\u5de7\u4ee5\u53ca\u76f8\u5173\u8ba8\u8bba\u548c\u53c2\u8003\u8d44\u6599\uff0c\u9488\u5bf9\u9047\u5230\u7684\u7f16\u7a0b\u95ee\u9898\u63d0\u51fa\u89e3\u51b3\u65b9\u6848\u3002\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u300a\u5206\u5e93\u5206\u8868\u5df2\u6210\u4e3a\u8fc7\u53bb\u5f0f\uff0c\u4f7f\u7528\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u624d\u662f\u672a\u6765\u300b](https://juejin.cn/post/7329413905028579340)\u3002\u672c\u6587\u8ba8\u8bba\u4e86\u968f\u7740Mysql\u6570\u636e\u5e93\u6027\u80fd\u4e0b\u964d\uff0c\u5206\u5e93\u5206\u8868\u7684\u5c40\u9650\u6027\u53ca\u5176\u6240\u5f15\u53d1\u7684\u95ee\u9898\uff0c\u5982\u6027\u80fd\u3001\u4e8b\u52a1\u3001\u6570\u636e\u8fc1\u79fb\u7b49\uff0c\u5e76\u63d0\u51fa\u4f7f\u7528\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u4f5c\u4e3a\u89e3\u51b3\u65b9\u6848\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86TiDB\u8fd9\u6b3e\u5206\u5e03\u5f0f\u6570\u636e\u5e93\u7684\u67b6\u6784\u3001\u7279\u6027\u548c\u4f18\u52bf\uff0c\u5305\u62ec\u5176\u91d1\u878d\u7ea7\u7684\u9ad8\u53ef\u7528\u6027\u3001\u6c34\u5e73\u6269\u5bb9\u80fd\u529b\u3001\u517c\u5bb9\u6027\u4ee5\u53ca\u4e91\u539f\u751f\u8bbe\u8ba1\u3002\u6587\u7ae0\u5f3a\u8c03TiDB\u5728\u5904\u7406\u5927\u89c4\u6a21\u6570\u636e\u65f6\u7684\u6548\u7387\u548c\u53ef\u7ef4\u62a4\u6027\uff0c\u7ec8\u7ed3\u5206\u5e93\u5206\u8868\u7684\u505a\u6cd5\uff0c\u5e76\u901a\u8fc7\u6027\u80fd\u6d4b\u8bd5\u5c55\u793a\u4e86TiDB\u4e0eMySQL\u5728\u4e0d\u540c\u573a\u666f\u4e0b\u7684\u6027\u80fd\u8868\u73b0\u3002\u6700\u7ec8\u603b\u7ed3\uff0c\u5bf9\u4e8e\u6570\u636e\u91cf\u5927\u7684\u5e94\u7528\u573a\u666f\uff0c\u91c7\u7528TiDB\u6765\u9002\u5e94\u672a\u6765\u6570\u636e\u5b58\u50a8\u7684\u9700\u6c42\u662f\u4e00\u4e2a\u66f4\u4f18\u7684\u7b56\u7565\u3002\\n\\n[\u300a\u624b\u628a\u624b\u5e26\u4f60\u7cbe\u7b80\u4ee3\u7801-\u4eac\u4e1c\u96f6\u552e\u540e\u7aef\u5b9e\u8df5\u300b](https://juejin.cn/post/7337247324681093129)\u3002\u672c\u6587\u5206\u4eab\u4e86\u4eac\u4e1c\u96f6\u552e\u540e\u7aef\u5728\u9762\u4e34\u4ee3\u7801\u5e93\u65e5\u6e10\u5e9e\u5927\u548c\u8150\u5316\u7684\u95ee\u9898\u65f6\uff0c\u91c7\u7528\u7684\u4ee3\u7801\u7cbe\u7b80\u65b9\u6cd5\u3002\u6587\u7ae0\u5206\u4e3a\u80cc\u666f\u4ecb\u7ecd\u3001\u4ee3\u7801\u7cbe\u7b80\u6b65\u9aa4\u548c\u5b9e\u65bd\u65b9\u6cd5\u4e09\u90e8\u5206\uff0c\u7740\u91cd\u4ecb\u7ecd\u4e86\u4f7f\u7528IntelliJ IDEA\u81ea\u5e26\u5de5\u5177\u548cPMD\u63d2\u4ef6\u8fdb\u884c\u9759\u6001\u4ee3\u7801\u68c0\u67e5\u7684\u6b65\u9aa4\u3001\u914d\u7f6e\u548c\u4f18\u7f3a\u70b9\uff0c\u4ee5\u53ca\u5982\u4f55\u501f\u52a9\u4eac\u4e1cjacoco\u6d41\u6c34\u7ebf\u8fdb\u884c\u52a8\u6001\u4ee3\u7801\u68c0\u67e5\u3002\u672c\u6587\u65e8\u5728\u964d\u4f4e\u4ee3\u7801\u7ef4\u62a4\u6210\u672c\u3001\u63d0\u5347\u53ef\u7406\u89e3\u6027\uff0c\u5e76\u8be6\u7ec6\u9610\u8ff0\u4e86\u4ee3\u7801\u7cbe\u7b80\u7684\u5b9e\u8df5\u8fc7\u7a0b\u548c\u9884\u671f\u7ed3\u679c\u3002\\n\\n[\u300a\u8ddf\u7740iLogtail\u5b66\u4e60\u65e0\u9501\u5316\u7f16\u7a0b\u300b](https://mp.weixin.qq.com/s/ZSXAPM8oFiCGztqbs1kksQ)\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5728\u591a\u7ebf\u7a0b\u60c5\u51b5\u4e0b\uff0c\u5982\u4f55\u901a\u8fc7\u65e0\u9501\u5316\u7f16\u7a0b\u4f18\u5316\u8f6f\u4ef6\u6027\u80fd\u3002\u8be6\u7ec6\u8bb2\u8ff0\u4e86iLogtail\u5728\u5b9e\u73b0\u65e0\u9501\u9ad8\u6548\u65e5\u5fd7\u91c7\u96c6\u65f6\u91c7\u53d6\u7684\u7b56\u7565\uff0c\u6bd4\u5982\u81ea\u65cb\u9501\u7684\u4f7f\u7528\u3001\u539f\u5b50\u64cd\u4f5c\u3001\u5185\u5b58\u987a\u5e8f\u3001\u5185\u5b58\u5c4f\u969c\u7b49\u6982\u5ff5\u3002\u8fd8\u5206\u6790\u4e86\u4e0d\u540c\u7c7b\u578b\u7684\u9501\u7684\u9002\u7528\u573a\u666f\u4e0e\u7279\u70b9\uff0c\u5305\u62ec\u4e92\u65a5\u9501\u3001\u9012\u5f52\u4e92\u65a5\u9501\u548c\u8bfb\u5199\u9501\u7b49\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u63cf\u8ff0\u4e86\u5982\u4f55\u5c06\u5927\u7684\u9501\u7ec6\u5206\u4e3a\u591a\u4e2a\u5c0f\u9501\uff0c\u901a\u8fc7\u964d\u4f4e\u9501\u7c92\u5ea6\u63d0\u5347\u5e76\u53d1\u6027\u80fd\uff0c\u4ee5\u53ca\u5728iLogtail\u4e2d\u5982\u4f55\u901a\u8fc7\u53ccBuffer\u673a\u5236\u6765\u8bfb\u5199\u5206\u79bb\uff0c\u51cf\u5c11\u9501\u7684\u4e89\u7528\u3002\u6700\u7ec8\uff0c\u901a\u8fc7\u65e0\u9501\u5316\u7f16\u7a0b\u63d0\u9ad8\u4e86iLogtail\u7684\u65e5\u5fd7\u91c7\u96c6\u6027\u80fd\uff0c\u5b9e\u73b0\u4e86\u4f4e\u8d44\u6e90\u6d88\u8017\u548c\u9ad8\u6027\u80fd\u3002\\n\\n[\u300aMYSQL \u662f\u5982\u4f55\u4fdd\u8bc1binlog \u548credo log\u540c\u65f6\u63d0\u4ea4\u7684?\u300b](https://mp.weixin.qq.com/s/GtU4xBKzfK3q3IsPuQV6pQ)\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u786e\u4fdd\u5728MYSQL\u4e2dbinlog\uff08\u5907\u4efd\u548c\u4e3b\u4ece\u540c\u6b65\u7528\u7684\u65e5\u5fd7\uff09\u4e0eredo log\uff08InnoDB\u5f15\u64ce\u5c42\u7684\u65e5\u5fd7\uff0c\u7528\u4e8e\u5d29\u6e83\u6062\u590d\uff09\u540c\u6b65\u63d0\u4ea4\uff0c\u4ee5\u53ca\u4e3a\u4ec0\u4e48\u8fd9\u4e00\u70b9\u5bf9\u4e8e\u9632\u6b62\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u81f3\u5173\u91cd\u8981\u3002\u6587\u4e2d\u89e3\u91ca\u4e86\u4e8b\u52a1\u5904\u7406\u4e2d\u7684\u4e24\u4e2a\u5173\u952e\u53c2\u6570\uff1a`innodb_flush_log_at_trx_commit`\u548c`sync_binlog`\uff0c\u8fd9\u4e24\u4e2a\u503c\u8bbe\u7f6e\u4e3a1\u65f6\u53ef\u4ee5\u786e\u4fdd\u4e24\u79cd\u65e5\u5fd7\u7684\u540c\u6b65\u63d0\u4ea4\u3002\u8be5\u6587\u8fd8\u4ecb\u7ecd\u4e86MYSQL\u7684\u4e24\u9636\u6bb5\u63d0\u4ea4\u673a\u5236\u5982\u4f55\u5de5\u4f5c\uff0c\u5e76\u63d0\u51fa\u4e86\u4e1a\u52a1\u5f00\u53d1\u4e2d\u4e24\u9636\u6bb5\u63d0\u4ea4\u903b\u8f91\u7684\u601d\u8003\uff0c\u6307\u51fa\u5728\u6709\u4f9d\u8d56\u5173\u7cfb\u7684\u670d\u52a1\u64cd\u4f5c\u4e2d\uff0c\u901a\u8fc7\u9884\u9501\u5b9a\u8d44\u6e90\u3001\u8bf7\u6c42\u6210\u529f\u540e\u9012\u51cf\u8d44\u6e90\u6765\u4fdd\u6301\u6570\u636e\u7684\u6700\u7ec8\u4e00\u81f4\u6027\u3002\\n\\n[\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u5206\u5e03\u5f0f\u7bc7\u300b](https://mp.weixin.qq.com/s/jVKgmbvha6Q-iNxvVzg3nw)\u3002\u672c\u6587\u4ece\u5206\u5e03\u5f0f\u7cfb\u7edf\u7684\u57fa\u7840\u6982\u5ff5\u3001\u53d1\u5c55\u5386\u7a0b\u53ca\u6838\u5fc3\u95ee\u9898\u51fa\u53d1\uff0c\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5206\u5e03\u5f0f\u7cfb\u7edf\u8bbe\u8ba1\u4e2d\u7684\u5173\u952e\u6280\u672f\u70b9\u3002\u6587\u7ae0\u6db5\u76d6\u4e86\u8d1f\u8f7d\u5747\u8861\u3001\u670d\u52a1\u7684\u62c6\u5206\u4e0e\u96c6\u7fa4\u3001\u5206\u5e03\u5f0f\u4e8b\u52a1\u3001\u6570\u636e\u4e00\u81f4\u6027\u95ee\u9898\u4ee5\u53ca\u5206\u533a\u5bb9\u9519\u6027\u7b49\u8bdd\u9898\uff0c\u5e76\u63a2\u8ba8\u4e86CAP\u7406\u8bba\u4e0eBASE\u7406\u8bba\u5728\u5b9e\u9645\u5e94\u7528\u4e2d\u7684\u6743\u8861\u3002\u540c\u65f6\uff0c\u6587\u4e2d\u8fd8\u8be6\u7ec6\u89e3\u8bfb\u4e86\u5e38\u89c1\u7684\u4e00\u81f4\u6027\u7b97\u6cd5\u59822PC\u30013PC\u3001Paxos\u3001Raft\u7684\u673a\u5236\u548c\u7528\u4f8b\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9488\u5bf9\u5982\u4f55\u5b9e\u73b0\u5206\u5e03\u5f0fSession\u3001\u5982\u4f55\u786e\u4fdd\u5206\u5e03\u5f0f\u4e8b\u52a1\u7684\u4e00\u81f4\u6027\u7b49\u5e38\u89c1\u9762\u8bd5\u9898\u76ee\u63d0\u4f9b\u4e86\u8be6\u5c3d\u7684\u89e3\u7b54\uff0c\u9002\u5408\u505a\u4e3a\u9762\u8bd5\u5907\u8003\u8d44\u6599\u3002\\n\\n[\u300aRocketMQ\u4e3a\u4ec0\u4e48\u8fd9\u4e48\u5feb?\u6211\u4ece\u6e90\u7801\u4e2d\u6252\u51fa\u4e8610\u5927\u539f\u56e0!\u300b](https://mp.weixin.qq.com/s/y1-A-SHAkGdg9IOTeUtPxg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5206\u6790\u4e86RocketMQ\u9ad8\u6027\u80fd\u768410\u4e2a\u5173\u952e\u56e0\u7d20\uff1a\u6279\u91cf\u53d1\u9001\u6d88\u606f\u964d\u4f4e\u901a\u4fe1\u6b21\u6570\uff0c\u6d88\u606f\u538b\u7f29\u51cf\u5c11\u5e26\u5bbd\u548c\u5b58\u50a8\u538b\u529b\uff0c\u57fa\u4e8eNetty\u7684\u9ad8\u6548\u7f51\u7edc\u901a\u4fe1\u6a21\u578b\uff0c\u96f6\u62f7\u8d1d\u6280\u672f\u4f18\u5316\u78c1\u76d8\u8bfb\u5199\u6027\u80fd\uff0c\u987a\u5e8f\u5199\u63d0\u9ad8\u6570\u636e\u5199\u5165\u901f\u5ea6\uff0c\u9ad8\u6548\u6570\u636e\u5b58\u50a8\u7ed3\u6784\uff0c\u5f02\u6b65\u673a\u5236\u5305\u62ec\u5f02\u6b65\u5237\u76d8\u548c\u5f02\u6b65\u4e3b\u4ece\u590d\u5236\u63d0\u5347\u5b58\u50a8\u6548\u7387\uff0c\u6279\u91cf\u5904\u7406\u51cf\u5c11\u7f51\u7edc\u901a\u4fe1\u6b21\u6570\u548c\u8d44\u6e90\u6d88\u8017\uff0c\u9501\u4f18\u5316\u4ee5\u53ca\u7ebf\u7a0b\u6c60\u9694\u79bb\u63d0\u5347\u5e76\u53d1\u5904\u7406\u80fd\u529b\u3002\u4f5c\u8005\u901a\u8fc7\u6df1\u5165\u5206\u6790\u6e90\u7801\u7ed9\u51fa\u4e86RocketMQ\u5feb\u901f\u5904\u7406\u548c\u62c9\u53d6\u6d88\u606f\u7684\u5185\u5728\u539f\u56e0\uff0c\u5e76\u6df1\u5165\u8ba8\u8bba\u4e86\u6bcf\u79cd\u6280\u672f\u7684\u4f18\u52bf\u548c\u5b9e\u73b0\u3002\\n\\n[\u300a\u9886\u5bfc\u53eb\u6211\u63a5\u624b\u4e00\u4e2a\u65b0\u4e1a\u52a1\u7cfb\u7edf\uff0c\u6211\u662f\u8fd9\u6837\u719f\u6089\u9879\u76ee\u7684!\u300b](https://mp.weixin.qq.com/s/39t_G3InMtHg9ETj_xYR7Q)\u3002\u672c\u6587\u4f5c\u8005\u5c0f\u8bb8\u5206\u4eab\u4e86\u63a5\u624b\u65b0\u4e1a\u52a1\u7cfb\u7edf\u7684\u719f\u6089\u6d41\u7a0b\u548c\u5b9e\u8df5\u65b9\u6cd5\u3002\u5305\u62ec\u4e0e\u4ea7\u54c1\u7ecf\u7406\u4ea4\u6d41\u4e86\u89e3\u4e1a\u52a1\u73b0\u72b6\uff0c\u7ed8\u5236\u7528\u4f8b\u56fe\u3001ER\u56fe\u4ee5\u660e\u786e\u4e1a\u52a1\u4e0e\u6570\u636e\u6a21\u578b\uff0c\u68b3\u7406\u540e\u7aef\u6a21\u578b\u548c\u6838\u5fc3\u6d41\u7a0b\uff0c\u5e76\u8fd0\u7528\u72b6\u6001\u673a\u6d41\u8f6c\u56fe\u548c\u65f6\u5e8f\u56fe\u6df1\u5ea6\u89e3\u6790\u590d\u6742\u903b\u8f91\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u5230\u4e86\u7ed8\u5236\u7c7b\u56fe\u4ee5\u7406\u89e3\u4ee3\u7801\u7ed3\u6784\u3002\u6587\u7ae0\u63d0\u4f9b\u4e86\u4e00\u5957\u7cfb\u7edf\u6027\u7684\u5de5\u5177\u548c\u65b9\u6cd5\uff0c\u76ee\u7684\u662f\u5e2e\u52a9\u65b0\u6210\u5458\u6216\u8d1f\u8d23\u65b0\u9879\u76ee\u7684\u5f00\u53d1\u4eba\u5458\u5feb\u901f\u638c\u63e1\u4e1a\u52a1\u903b\u8f91\uff0c\u6709\u6548\u63a8\u8fdb\u9879\u76ee\u8fdb\u5ea6\u3002\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u300aTango \u4f4e\u4ee3\u7801\u5f15\u64ce\u6c99\u7bb1\u5b9e\u73b0\u89e3\u6790\u300b](https://mp.weixin.qq.com/s/GqSoZR3bSeuLWiULHt8Zvg)\u3002\u672c\u6587\u4ecb\u7ecd\u4e86Tango\u4f4e\u4ee3\u7801\u5f15\u64ce\u7684\u6c99\u7bb1\u5b9e\u73b0\u3002Tango\u662f\u4e00\u4e2a\u7528\u4e8e\u5feb\u901f\u6784\u5efa\u4f4e\u4ee3\u7801\u5e73\u53f0\u7684\u4f4e\u4ee3\u7801\u8bbe\u8ba1\u5668\u6846\u67b6\uff0c\u901a\u8fc7\u5bf9\u6e90\u4ee3\u7801\u8fdb\u884c\u6267\u884c\u548c\u6e32\u67d3\u524d\u7aef\u89c6\u56fe\uff0c\u5b9e\u73b0\u4e86\u4f4e\u4ee3\u7801\u53ef\u89c6\u5316\u642d\u5efa\u80fd\u529b\u3002\u501f\u52a9Tango\u6784\u5efa\u7684\u4f4e\u4ee3\u7801\u5de5\u5177\u6216\u5e73\u53f0\u53ef\u4ee5\u5b9e\u73b0\u6e90\u7801\u8fdb\u51fa\u7684\u6548\u679c\uff0c\u5e76\u4e0e\u4f01\u4e1a\u5185\u90e8\u73b0\u6709\u7684\u7814\u53d1\u4f53\u7cfb\u8fdb\u884c\u65e0\u7f1d\u96c6\u6210\u3002Tango\u7684\u8bbe\u8ba1\u5668\u5f15\u64ce\u90e8\u5206\u5df2\u7ecf\u5f00\u6e90\uff0c\u5e76\u63d0\u4f9b\u4e86\u76f8\u5e94\u7684\u5f00\u6e90\u4ee3\u7801\u5e93\u3001\u6587\u6863\u548c\u793e\u533a\u8ba8\u8bba\u7ec4\u3002\u6b22\u8fce\u52a0\u5165\u793e\u533a\u53c2\u4e0e\u5230Tango\u4f4e\u4ee3\u7801\u5f15\u64ce\u7684\u5f00\u6e90\u5efa\u8bbe\u4e2d\u3002\u66f4\u591a\u76f8\u5173\u6587\u7ae0\u53ef\u4ee5\u5728\u6587\u4e2d\u63d0\u4f9b\u7684\u94fe\u63a5\u4e2d\u627e\u5230\u3002\\n\\n[\u300a\u672a\u6765\u53ea\u9700\u8981 2% \u7684\u7a0b\u5e8f\u5458?\u300b](https://mp.weixin.qq.com/s/U6ZQwLiW5sfkknz_bayosg)\u3002DHH\u5728\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u63d0\u51fa\u4e00\u4e2a\u6fc0\u8fdb\u7684\u89c2\u70b9\uff0c\u9884\u6d4b\u672a\u6765\u7a0b\u5e8f\u5458\u7684\u9700\u6c42\u53ef\u80fd\u4f1a\u5927\u5e45\u5ea6\u51cf\u5c11\u3002\u4ed6\u6bd4\u8f83\u4e86\u519c\u4e1a\u4ece97%\u7684\u4eba\u53e3\u9700\u6c42\u964d\u81f32%\u7684\u53d8\u8fc1\uff0c\u6697\u793a\u8f6f\u4ef6\u5f00\u53d1\u4e5f\u53ef\u80fd\u9762\u4e34\u7740\u7c7b\u4f3c\u7f29\u51cf\u3002\u5c3d\u7ba1\u8fd9\u4e2a\u884c\u4e1a\u66fe\u7ecf\u7ecf\u5386\u62db\u8058\u70ed\u6f6e\uff0c\u4f46\u73b0\u5728\u8bb8\u591a\u7a0b\u5e8f\u5458\u9762\u4e34\u804c\u4e1a\u524d\u666f\u4e0d\u7a33\u5b9a\u3002\u6587\u7ae0\u8ba8\u8bba\u4e86\u4eba\u5de5\u667a\u80fd\u7684\u53d1\u5c55\u7ed9\u7a0b\u5e8f\u5458\u804c\u4e1a\u5e26\u6765\u7684\u538b\u529b\uff0c\u540c\u65f6\u4e5f\u6307\u51fa\u804c\u4e1a\u53d8\u9769\u7684\u4e0d\u786e\u5b9a\u6027\u3002DHH\u8ba4\u4e3a\uff0c\u672a\u6765\u5927\u591a\u6570\u7a0b\u5e8f\u5458\u53ef\u80fd\u65e0\u9700\u624b\u52a8\u7f16\u7a0b\uff0c\u4f46\u540c\u65f6\u6307\u51fa\u79d1\u6280\u884c\u4e1a\u5c06\u66f4\u52a0\u878d\u5408\u8fdb\u793e\u4f1a\uff0c\u5e76\u63d0\u9ad8\u4e86\u5b83\u7684\u4ef7\u503c\u3002\u4ed6\u9f13\u52b1\u7a0b\u5e8f\u5458\u63a5\u53d7\u8fd9\u4e00\u53d8\u5316\uff0c\u5e76\u4eab\u53d7\u884c\u4e1a\u7684\u9ec4\u91d1\u65f6\u4ee3\u3002\\n\\n[\u300a\u524d\u7aef\u667a\u80fd\u5316\uff0c\u6263\u5b50(coze.cn)\u80fd\u505a\u4ec0\u4e48?\u300b](https://mp.weixin.qq.com/s/tiolzTwPKPZF4b8zZbvYpA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u63a2\u8ba8\u4e86\u6263\u5b50\uff08coze.cn\uff09\u5e73\u53f0\u5982\u4f55\u901a\u8fc7\u63d0\u4f9b\u4e00\u4e2a\u7b80\u5355\u7684\u4ea4\u4e92\u5f0f\u754c\u9762\u6765\u521b\u5efa\u804a\u5929\u673a\u5668\u4eba\uff08Chatbot\uff09\u3002\u7528\u6237\u901a\u8fc7\u4e0e\u6263\u5b50\u7684\u5bf9\u8bdd\uff0c\u53ef\u4ee5\u5feb\u901f\u8bbe\u7f6e\u4e00\u4e2aChatbot\uff0c\u5982\u81ea\u52a8\u5316\u5fae\u4fe1\u8ba2\u9605\u53f7\u5185\u5bb9\u53d1\u5e03\u7b49\u3002\u6587\u7ae0\u5f3a\u8c03\u4e86\u5e73\u53f0\u7684\u6613\u7528\u6027\u548c\u754c\u9762\u53cb\u597d\u6027\uff0c\u540c\u65f6\u6307\u51fa\u4e86\u4e00\u4e9b\u6f5c\u5728\u7f3a\u70b9\uff0c\u5305\u62ec\u65e0\u6cd5\u89e3\u51b3\u6df1\u5ea6\u95ee\u9898\u548c\u5076\u5c14\u9047\u5230\u7684\u6280\u672f\u6545\u969c\u3002\u53e6\u5916\uff0c\u901a\u8fc7\u77e5\u8bc6\u5e93\u548c\u6570\u636e\u5e93\u7684\u96c6\u6210\uff0c\u53ef\u8fdb\u4e00\u6b65\u63d0\u5347Bot\u7684\u529f\u80fd\u3002\u4f5c\u8005\u5bf9\u6263\u5b50\u7684\u673a\u5668\u4eba\u521b\u5efa\u8fc7\u7a0b\u3001\u4f18\u52bf\u3001\u5efa\u8bae\u548c\u6539\u8fdb\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u901a\u8fc7\u5b9e\u64cd\u6848\u4f8b\u5c55\u793a\u4e86\u524d\u7aef\u667a\u80fd\u5316\u673a\u5668\u4eba\u7684\u642d\u5efa\u8fc7\u7a0b\u3002"},{"id":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-10/index.md","source":"@site/blogs/2024/2024-03-10/index.md","title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-03-10T00:00:00.000Z","formattedDate":"March 10, 2024","tags":[],"readingTime":34.7,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](maxresdefault.jpg)\\n\\n\u5c01\u9762\u56fe\uff1aUnderstanding the Go runtime - Jesus Espino\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u300aIn-context Learning with Retrieved Demonstrations for Language Models: A Survey\u300b](https://arxiv.org/abs/2401.11624)\u3002\u8fd9\u7bc7\u9898\u4e3a \\"In-context Learning with Retrieved Demonstrations for Language Models: A Survey\\" \u7684\u6587\u7ae0\uff0c\u4e3b\u8981\u8ba8\u8bba\u4e86\u8bed\u8a00\u6a21\u578b\uff0c\u5c24\u5176\u662f\u5927\u578b\u9884\u8bad\u7ec3\u8bed\u8a00\u6a21\u578b\u5982\u4f55\u901a\u8fc7\u83b7\u53d6\u7684\u6f14\u793a\u8fdb\u884c\u5c11\u91cf\u60c5\u666f\u5b66\u4e60\u3002\u8fd9\u9879\u6280\u672f\u80fd\u6709\u6548\u5730\u6539\u8fdb\u5b66\u4e60\u8fc7\u7a0b\u7684\u6548\u7387\u548c\u53ef\u6269\u5c55\u6027\uff0c\u5e76\u964d\u4f4e\u624b\u52a8\u9009\u62e9\u6837\u4f8b\u65f6\u7684\u56fa\u6709\u504f\u89c1\u3002\u6587\u7ae0\u5bf9\u6b64\u9886\u57df\u8fdb\u884c\u4e86\u5e7f\u6cdb\u7684\u7814\u7a76\u56de\u987e\uff0c\u5bf9\u68c0\u7d22\u6a21\u578b\u3001\u68c0\u7d22\u8bad\u7ec3\u8fc7\u7a0b\u548c\u63a8\u7406\u7b97\u6cd5\u7684\u4e0d\u540c\u8bbe\u8ba1\u9009\u62e9\u8fdb\u884c\u4e86\u8ba8\u8bba\u548c\u6bd4\u8f83\u3002\\n\\n[\u300a\u78be\u538bLoRA\uff01Meta & CMU | \u63d0\u51fa\u9ad8\u6548\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\uff1aGaLore\uff0c\u5185\u5b58\u53ef\u51cf\u5c1163.3%\u300b](https://mp.weixin.qq.com/s/NUhEy0YLTjtzY3BGVXhfrw)\u3002Meta\u548cCMU\u5408\u4f5c\u63d0\u51fa\u4e86\u4e00\u79cd\u65b0\u7684\u5927\u6a21\u578b\u5fae\u8c03\u65b9\u6cd5\u2014\u2014Gradient Low-Rank Projection\uff08GaLore\uff09\u3002GaLore\u901a\u8fc7\u68af\u5ea6\u7684\u4f4e\u79e9\u6295\u5f71\u4ee3\u66ff\u6743\u91cd\u7684\u4f4e\u79e9\u9002\u914d\uff0c\u4e0d\u4ec5\u652f\u6301\u5168\u53c2\u6570\u5b66\u4e60\uff0c\u800c\u4e14\u663e\u8457\u964d\u4f4e\u4e86\u5185\u5b58\u5360\u7528\uff0c\u51cf\u5c11\u4e8663.3%\u7684\u5185\u5b58\u9700\u6c42\u3002\u4e0d\u540c\u4e8eLoRA\u7684\u4f4e\u79e9\u6743\u91cd\u66f4\u65b0\uff0cGaLore\u5229\u7528\u6743\u91cd\u68af\u5ea6\u7684\u4f4e\u79e9\u7279\u6027\uff0c\u7ed3\u5408\u9010\u5c42\u6743\u91cd\u66f4\u65b0\u548c8\u4f4d\u4f18\u5316\u5668\uff0c\u6709\u6548\u5730\u4f18\u5316\u4e86\u5185\u5b58\u6548\u7387\u3002\u6b64\u5916\uff0cGaLore\u8fd8\u5f15\u5165\u4e86\u53ef\u8c03\u6574\u7684\u8d85\u53c2\u6570\uff0c\u63d0\u9ad8\u4e86\u5176\u9002\u5e94\u6027\u3002\u7ecf\u5b9e\u9a8c\u9a8c\u8bc1\uff0cGaLore\u7684\u8868\u73b0\u4f18\u4e8eLoRA\uff0c\u5c24\u5176\u662f\u5728\u9884\u8bad\u7ec3\u6a21\u578b\u5fae\u8c03\u4e0a\u8868\u73b0\u66f4\u4f73\uff0c\u4e3a\u5927\u6a21\u578b\u8bad\u7ec3\u63d0\u4f9b\u4e86\u65b0\u7684\u89e3\u51b3\u7b56\u7565\u3002\\n\\n[\u4f7f\u7528 GPT4V+AI Agent \u505a\u81ea\u52a8 UI \u6d4b\u8bd5\u7684\u63a2\u7d22 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7316592794109198387)\\n\\n[Gemini\u4feebug\u795e\u4e86\uff01\u5f55\u7f51\u9875\u89c6\u9891\u628a\u4ee3\u7801\u5e93\u7529\u7ed9\u5b83\u5c31\u884c\uff0c\u7f51\u53cb\u5750\u4e0d\u4f4f\u4e86\uff1a\u60f3\u8981\u8bbf\u95ee\u6743\u9650](https://mp.weixin.qq.com/s/ZSDCNDRu-tCkOlC9jz2j4w)\\n\\n[\u4e00\u952e\u5f00\u542f GPU \u95f2\u7f6e\u6a21\u5f0f\uff0c\u57fa\u4e8e\u51fd\u6570\u8ba1\u7b97\u4f4e\u6210\u672c\u90e8\u7f72 Google Gemma \u6a21\u578b\u670d\u52a1](https://mp.weixin.qq.com/s/GXwftkv-UpDQSjiTMn9TFA)\\n\\n[\u300aYi\u6280\u672f\u62a5\u544a\u7ec6\u8282\u5206\u4eab\u300b](https://mp.weixin.qq.com/s/YDwL3dV-Fq5zcEyrL__NGw)\u3002\u8be5\u6587\u7ae0\u5206\u4eab\u4e86Yi\u6a21\u578b\u7684\u5177\u4f53\u5b9e\u73b0\u7ec6\u8282\u548c\u601d\u8def\uff0c\u5f3a\u8c03\u4e86\u6a21\u578b\u8bbe\u8ba1\u56f4\u7ed5\u6a21\u578b\u89c4\u6a21\u3001\u6570\u636e\u89c4\u6a21\u548c\u6570\u636e\u8d28\u91cf\u3002Yi\u6a21\u578b\u7684\u9884\u8bad\u7ec3\u9636\u6bb5\u6570\u636e\u5904\u7406\u6d41\u7a0b\u5305\u62ec\u542f\u53d1\u5f0f\u8fc7\u6ee4\u3001\u5b66\u4e60\u5f0f\u8fc7\u6ee4\u3001\u805a\u7c7b\u8fc7\u6ee4\u4ee5\u53ca\u53bb\u91cd\u7b49\u6b65\u9aa4\uff0c\u4ee5\u63d0\u9ad8\u6570\u636e\u8d28\u91cf\u3002\u5fae\u8c03\u9636\u6bb5\uff0cYi\u6a21\u578b\u4ec5\u91c7\u7528\u4e8610K\u6570\u636e\u8fdb\u884c\u6a21\u578b\u5fae\u8c03\uff0c\u5f3a\u8c03\u6570\u636e\u8d28\u91cf\u80dc\u8fc7\u6570\u91cf\u3002\u5728\u5206\u8bcd\u5668\u3001\u6a21\u578b\u7ed3\u6784\u53ca\u5fae\u8c03\u53c2\u6570\u65b9\u9762\uff0cYi\u6a21\u578b\u91c7\u7528\u4e86\u4e00\u7cfb\u5217\u4f18\u5316\u63aa\u65bd\uff0c\u5305\u62ecTransformer-Decoder\u7ed3\u6784\u3001Grouped-Query Attention\u7b49\u3002\u603b\u7684\u6765\u8bf4\uff0cYi\u6a21\u578b\u901a\u8fc7\u4f18\u5316\u6570\u636e\u5904\u7406\u6d41\u7a0b\u3001\u5fae\u8c03\u7b56\u7565\u3001\u8c03\u6574\u6a21\u578b\u7ed3\u6784\u548c\u53c2\u6570\u7b49\u591a\u65b9\u9762\u5b9e\u73b0\u4e86\u9ad8\u6548\u7684\u6280\u672f\u5b9e\u73b0\u3002\\n\\n[\u91cd\u65b0\u5b9a\u4e49\u5927\u6a21\u578b\u63a8\u7406\uff01Google | \u63d0\u51faSELF-DISCOVER\u6846\u67b6\uff0c\u5927\u6a21\u578b\u53ef\u81ea\u5199\u63a8\u7406\u7ed3\u6784\uff01](https://mp.weixin.qq.com/s/lBXwSVvRHB2Yn0fYoOkDeQ)\\n\\n[\u300a\u65af\u5766\u798f && \u5fae\u8f6f | \u53d1\u5e03\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u52a9\u529b\u524d\u7aef\u81ea\u52a8\u5316\uff01\u300b](https://mp.weixin.qq.com/s/cB5tgMUPqg8fsXjNrzQpbg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u524d\u7aef\u4ee3\u7801\u751f\u6210\u5927\u6a21\u578b\uff1aDesign2Code-18B\uff0c\u5b83\u53ef\u4ee5\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5c06\u7f51\u9875\u89c6\u89c9\u8bbe\u8ba1\u8f6c\u6362\u6210\u529f\u80fd\u6027\u4ee3\u7801\u7684\u6311\u6218\u6027\u548c\u73b0\u6709\u65b9\u6cd5\u7684\u5c40\u9650\u6027\uff0c\u7136\u540e\u63d0\u51fa\u4e86Design2Code\u57fa\u51c6\u548c\u591a\u6a21\u6001\u63d0\u793a\u65b9\u6cd5\uff0c\u4ee5\u6fc0\u53d1\u591a\u6a21\u6001\u5927\u578b\u8bed\u8a00\u6a21\u578b\uff08\u5982GPT-4V\u548cGemini\uff09\u7684\u6f5c\u529b\u3002\u63a5\u7740\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5f00\u6e90\u768418B\u5fae\u8c03\u6a21\u578bDesign2Code-18B\uff0c\u5b83\u57fa\u4e8eCogAgent-18B\uff0c\u5728\u591a\u79cd\u6570\u636e\u96c6\u4e0a\u8fdb\u884c\u4e86\u9884\u8bad\u7ec3\uff0c\u5e76\u4f7f\u7528\u4e86Huggingface\u53d1\u5e03\u7684WebSight\u6570\u636e\u96c6\u8fdb\u884c\u5fae\u8c03\u3002\u6700\u540e\uff0c\u6587\u7ae0\u5c55\u793a\u4e86Design2Code-18B\u5728Design2Code\u57fa\u51c6\u4e0a\u7684\u4f18\u8d8a\u6027\u80fd\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u4e9b\u672a\u6765\u7814\u7a76\u65b9\u5411\u3002\\n\\n[\u53ef\u63a7\u6587\u672c\u751f\u6210\u65b0\u65b9\u6cd5\uff0c\u4eba\u5927&&\u5357\u5f00 | \u63d0\u51faDATG\u67b6\u6784\uff0c\u51c6\u786e\u6027\u63d0\u534719.29%\uff0c\u6548\u7387\u63d0\u53471\u500d](https://mp.weixin.qq.com/s/Pdp6_z_rxBl-kph41Lb8Ww)\\n\\n[\u300aAuto-Prompt | \u5927\u6a21\u578b\u63d0\u793a(Prompt)\u4f18\u5316\u65b0\u65b9\u6cd5IPC\uff1a\u53ef\u6839\u636e\u7528\u6237\u610f\u56fe\u8fdb\u884c\u5b9a\u5411\u4f18\u5316\u300b](https://mp.weixin.qq.com/s/53jEDw58dkZlJAVzr31G8A)\u3002\u8fd9\u7bc7\u6587\u7ae0\u63d0\u51fa\u4e86\u4e00\u79cd\u540d\u4e3a Intent-based Prompt Calibration\uff08IPC\uff09\u7684\u7cfb\u7edf\uff0c\u4e3b\u8981\u76ee\u7684\u662f\u901a\u8fc7\u4f7f\u7528\u5408\u6210\u6848\u4f8b\u6837\u672c\u6765\u4f18\u5316\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u63d0\u793a\u5de5\u7a0b\u3002\u5b83\u57fa\u4e8e\u6a21\u578b\u751f\u6210\u7684\u6570\u636e\u96c6\u8fdb\u884c\u63d0\u793a\u4f18\u5316\uff0c\u4ee5\u89e3\u51b3\u5927\u8bed\u8a00\u6a21\u578b\u5bf9\u7ed9\u5b9a\u63d0\u793a\u7684\u654f\u611f\u6027\u7b49\u95ee\u9898\u3002\u8fd9\u79cd\u65b9\u6cd5\u7684\u6838\u5fc3\u601d\u60f3\u662f\u6839\u636e\u7528\u6237\u610f\u56fe\u8fed\u4ee3\u7ec6\u5316\u63d0\u793a\u3002\u540c\u65f6\uff0c\u6587\u7ae0\u8fd8\u5bf9 IPC \u7cfb\u7edf\u7684\u6574\u4f53\u67b6\u6784\u548c\u5b9e\u73b0\u6d41\u7a0b\u8fdb\u884c\u4e86\u8be6\u7ec6\u4ecb\u7ecd\uff0c\u5e76\u5c55\u793a\u4e86\u4e00\u4e9b\u5b9e\u9a8c\u7ed3\u679c\u3002\\n\\n[\u300a\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c\u300b](https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u51e0\u79cd\u65b0\u578b\u7684\u667a\u80fd Agent \u8bbe\u8ba1\u65b9\u6cd5\uff0c\u5305\u62ec Plan-and-Execute Agents\u3001ReWOO Agent \u548c LLMCompiler\u3002Plan-and-Execute Agent \u8bbe\u8ba1\u6cd5\u901a\u8fc7\u660e\u786e\u89c4\u5212\u6765\u4f18\u5316\u667a\u80fd Agent \u529f\u80fd\u3002ReWOO Agent \u8bbe\u8ba1\u6cd5\u51ed\u501f\u53d8\u91cf\u5206\u914d\u529f\u80fd\u4f7f\u5f97\u4e0d\u5fc5\u5bf9\u6bcf\u4e2a\u4efb\u52a1\u90fd\u4f7f\u7528 LLM\u3002LLMCompiler \u5219\u901a\u8fc7\u4efb\u52a1\u683c\u5f0f\u5316\u4e3a DAG \u6765\u63d0\u9ad8\u5de5\u5177\u8c03\u7528\u7684\u6548\u7387\u3002\u8fd9\u4e9b\u65b0\u578b\u8bbe\u8ba1\u90fd\u5728\u4e0d\u540c\u7a0b\u5ea6\u4e0a\u4f18\u5316\u4e86\u667a\u80fd Agent \u7684\u5de5\u4f5c\u6d41\u7a0b\uff0c\u63d0\u9ad8\u4e86\u5de5\u4f5c\u6548\u7387\u3002\\n\\n[\u300aOpenAI Function Calling \u4e0e LangChain Agent \u5de5\u4f5c\u539f\u7406\u53ca\u533a\u522b\u300b](https://mp.weixin.qq.com/s/F2s3pKycoNDT7Z-6piRHWg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86OpenAI Function Calling \u4e0e LangChain Agent\u7684\u5de5\u4f5c\u539f\u7406\u53ca\u5b83\u4eec\u4e4b\u95f4\u7684\u533a\u522b\u3002\u6587\u7ae0\u9996\u5148\u5217\u4e3e\u4e86\u5927\u578b\u8bed\u8a00\u6a21\u578b\u7684\u9650\u5236\uff0c\u5e76\u89e3\u91ca\u4e86\u4e3a\u4f55\u9700\u8981Agent\u3002\u7136\u540e\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86React Agent\u7684\u5de5\u4f5c\u65b9\u5f0f\uff0c\u901a\u8fc7\u201cReason Only\u201d\uff08\u5411\u5185\u6c42\u7d22\uff09\u3001\u201cAct Only\u201d\uff08\u5411\u5916\u63a2\u7d22\uff09\u548c\u201cReAct\u201d\uff08\u5185\u5916\u517c\u4fee\uff09\u4e09\u79cd\u6a21\u5f0f\u4f18\u5316\u6a21\u578b\u7684\u529f\u80fd\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u8fd8\u4ee5\u4e00\u4e2a\u7b80\u5355\u7684\u5b9e\u4f8b\uff0c\u89e3\u91ca\u4e86\u5982\u4f55\u5229\u7528ReAct Agent\u6765\u89e3\u7b54\u4e00\u4e2a\u5305\u542b\u641c\u7d22\u548c\u8ba1\u7b97\u4e24\u4e2a\u6b65\u9aa4\u7684\u95ee\u9898\uff0c\u5c55\u793a\u4e86\u5176\u5b9e\u9645\u5e94\u7528\u7684\u6d41\u7a0b\u3002\\n\\n[\u300aReAct Agent \u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u7684\u590d\u6742\u95ee\u9898\u300b](https://mp.weixin.qq.com/s/iM45toKEHr3_rJxuwbgp4w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u201cReAct Agent \u7528\u4e8e\u56de\u7b54 RAG \u7cfb\u7edf\u4e2d\u590d\u6742\u95ee\u9898\u7684\u65b9\u5f0f\u201d\u3002\u968f\u7740\u8f93\u5165\u95ee\u9898\u7684\u590d\u6742\u5ea6\u5347\u9ad8\uff0c\u4f7f\u7528\u4f20\u7edf\u7684\u804a\u5929\u673a\u5668\u4eba\u5df2\u4e0d\u80fd\u8db3\u591f\u6709\u6548\u3002\u4e8e\u662f\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u5229\u7528 ReAct Agent\uff0c\u901a\u8fc7\u81ea\u7136\u8bed\u8a00\u6a21\u578b\uff08LLMs\uff09\u9010\u6b65\u89c4\u5212\u5e76\u6267\u884c\u5904\u7406\u95ee\u9898\u7684\u6b65\u9aa4\uff0c\u5e76\u5b9a\u4e49\u529f\u80fd\u6027\u5de5\u5177\uff08\u5982\u65f6\u95f4\u8ba1\u7b97\u3001\u6587\u672c\u641c\u7d22\u3001\u5217\u8868\u957f\u5ea6\u8ba1\u7b97\u3001\u767e\u5206\u6bd4\u53d8\u5316\u8ba1\u7b97\u7b49\uff09\u4ee5\u8f85\u52a9\u4efb\u52a1\u5b8c\u6210\u3002\u8fd9\u79cd\u65b9\u6cd5\u80fd\u591f\u66f4\u597d\u5730\u5e72\u9884\u548c\u63a7\u5236\u95ee\u9898\u7684\u89e3\u51b3\u8fc7\u7a0b\uff0c\u4ece\u800c\u63d0\u9ad8\u4efb\u52a1\u7684\u5b8c\u6210\u8d28\u91cf\u3002\\n\\n[\u66f4\u667a\u80fd\u7684 Agent\uff0cPlan-and-Execute Agents \u8ba1\u5212\u548c\u6267\u884c](https://mp.weixin.qq.com/s/1d2_kHEQnug9iR0cU_0nAA)\\n\\n[ChatGPT\u4e5f\u80fd\u753b\u56fe\uff1f\u6559\u4f60\u4e00\u952e\u751f\u6210\u65f6\u5e8f\u56fe\u3001\u7c7b\u56fe\u3001\u6d41\u7a0b\u56fe\u3001\u72b6\u6001\u56fe\u4ee5\u53ca\u7528\u4f8b\u56fe](https://mp.weixin.qq.com/s/KF7joY-MkK4BZ8Rf8bLArw)\\n\\n[\u4e09\u4e2a\u88ab\u5ffd\u89c6\u7684\u5927\u6a21\u578b\u63d0\u793a](https://mp.weixin.qq.com/s/E2xwi9SNYQ7sdzhYlaDQFg)\\n\\n[\u5173\u4e8eSora\u548cStable Diffusion 3\uff0c\u4f60\u9700\u8981\u77e5\u9053\u7684\u4e00\u5207](https://mp.weixin.qq.com/s/u2LCRgBhKKcGZhY29PjIng)\\n\\n[\u6d88\u8d39\u7ea7\u663e\u5361\u53ef\u7528\uff01\u674e\u5f00\u590d\u96f6\u4e00\u4e07\u7269\u53d1\u5e03\u5e76\u5f00\u6e9090\u4ebf\u53c2\u6570Yi\u6a21\u578b\uff0c\u4ee3\u7801\u6570\u5b66\u80fd\u529b\u53f2\u4e0a\u6700\u5f3a](https://mp.weixin.qq.com/s/z6IFIuHawVZI6ZOfgvgKuA)\\n\\n[\u8be6\u89e3\u5927\u6a21\u578b\u5fae\u8c03\u5168\u6d41\u7a0b](https://mp.weixin.qq.com/s/IBh3ytd3gtizAQd5PI2uig)\\n\\n[\u5357\u5927\u4fde\u626c\u6559\u6388\uff1a\u4ec0\u4e48\u662fworld models/\u4e16\u754c\u6a21\u578b](https://mp.weixin.qq.com/s/UzC3J_TOzJPEx_86-lRwuw)\\n\\n[\u6df1\u5165\u6d45\u51faLangChain\u4e0e\u667a\u80fdAgent\uff1a\u6784\u5efa\u4e0b\u4e00\u4ee3AI\u52a9\u624b](https://mp.weixin.qq.com/s/Gi6pzD7wAMyzlCBSSWkVLA)\\n\\n[\u5c24\u6d0b\u6559\u6388\uff1a\u5f00\u6e90\u5b8c\u6574\u7684Sora\u590d\u73b0\u65b9\u6848\u6765\u4e86\uff01](https://mp.weixin.qq.com/s/T9YRVRGMgkwRSTl7Movadg)\\n\\n[\u300aT-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\u300b](https://mp.weixin.qq.com/s/8WYWrHyE4oryCgO9AemImA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"T-RAG=RAG+\u5fae\u8c03+\u5b9e\u4f53\u8bc6\u522b\\"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86T-RAG\u6280\u672f\uff0c\u8fd9\u662f\u4e00\u79cd\u5c06RAG\u67b6\u6784\u4e0e\u5fae\u8c03\u8bed\u8a00\u6a21\u578b\u548c\u5b9e\u4f53\u6811\u5411\u91cf\u6570\u636e\u5e93\u76f8\u7ed3\u5408\u7684\u65b9\u6cd5\uff0c\u7528\u4e8e\u652f\u6301\u8bed\u5883\u68c0\u7d22\u3002\u5b83\u6982\u8ff0\u4e86\u5728\u654f\u611f\u6587\u6863\u7684\u80cc\u666f\u4e0b\u5982\u4f55\u4fdd\u62a4\u6570\u636e\u9690\u79c1\uff0c\u4ee5\u53ca\u5982\u4f55\u5728\u6709\u9650\u7684\u8ba1\u7b97\u8d44\u6e90\u548c\u57fa\u4e8e\u73b0\u6709\u6587\u6863\u5efa\u7acb\u7684\u5c0f\u578b\u8bad\u7ec3\u6570\u636e\u96c6\u4e2d\u4fdd\u8bc1\u7528\u6237\u63d0\u95ee\u7684\u51c6\u786e\u56de\u7b54\u3002\u6587\u4e2d\u8fd8\u7740\u91cd\u4ecb\u7ecd\u4e86T-RAG\u7684\u5de5\u4f5c\u6d41\u7a0b\u548c\u5b9e\u4f53\u6811\u7684\u4f5c\u7528\u3002\u6700\u540e\uff0c\u8fd8\u63d0\u51fa\u4e86\u4e00\u4e2a\u65b0\u7684\u8bc4\u4f30\u6307\u6807\u201cCorrect-Verbose\u201d\uff0c\u7528\u4ee5\u8bc4\u4ef7\u751f\u6210\u56de\u590d\u7684\u8d28\u91cf\u3002\u6b64\u7814\u7a76\u4e0d\u4ec5\u662f\u7406\u8bba\u7814\u7a76\uff0c\u4e5f\u662f\u5b9e\u8df5\u4e2dLLM\u5e94\u7528\u7684\u7ecf\u9a8c\u603b\u7ed3\uff0c\u5177\u6709\u5b9e\u9645\u7684\u6307\u5bfc\u610f\u4e49\u3002\\n\\n[\u300a\u9ad8\u7ea7 RAG\uff08Self-Reflective RAG\uff09\u300b](https://mp.weixin.qq.com/s/de3UxM9WTrHNjnOKSny0aw)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"\u9ad8\u7ea7 RAG(Self-Reflective RAG)\\"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86Self-Reflective RAG\u7684\u7406\u5ff5\u548c\u5de5\u4f5c\u6d41\u7a0b\u3002\u5728\u57fa\u672c\u7684RAG pipeline\u4e2d\uff0c\u6211\u4eec\u7684\u8fc7\u7a0b\u5f80\u5f80\u53d7\u9650\u4e8e\u88ab\u52a8\u7684\u68c0\u7d22\u548c\u751f\u6210\uff0c\u800c\u5b9e\u9645\u64cd\u4f5c\u4e2d\uff0c\u6211\u4eec\u9700\u8981\u6839\u636e\u751f\u6210\u7684\u7ed3\u679c\u8fdb\u884c\u4f18\u5316\uff0c\u5982\u6539\u53d8\u95ee\u9898\u6216\u7b5b\u9009\u548c\u6392\u5217\u5185\u5bb9\u3002\u4e3a\u4e86\u89e3\u51b3\u8fd9\u4e2a\u95ee\u9898\uff0c\u6587\u7ae0\u4ecb\u7ecd\u4e86\u4e00\u79cd\u65b0\u7684\u81ea\u6211\u4fee\u6b63\u6846\u67b6\uff0c\u5305\u62ecCorrective RAG(CRAG)\u548cSelf-Reflective RAG\u3002\u8fd9\u4e24\u79cdRAG\u90fd\u56f4\u7ed5\u7740\u5bf9\u68c0\u7d22\u548c\u751f\u6210\u5185\u5bb9\u7684\u8bc4\u4f30\u548c\u53cd\u9988\u8fdb\u884c\u81ea\u6211\u4fee\u6b63\uff0c\u5e76\u901a\u8fc7\u7279\u5b9a\u6807\u8bc6\u8fdb\u884c\u8c03\u63a7\u3002\u5728\u4e00\u5b9a\u6761\u4ef6\u4e0b\uff0c\u8fdb\u4e00\u6b65\u6539\u8fdb\u4e86RAG\uff0c\u4f7f\u5176\u4ea7\u751f\u66f4\u597d\u7684\u68c0\u7d22\u548c\u751f\u6210\u6548\u679c\u3002\\n\\n[RAG\u4e0d\u591f\u806a\u660e\uff1f\u6253\u9020\u66f4\u5f3a\u5927\u7684\u667a\u80fd\u4f53](https://mp.weixin.qq.com/s/WuJEubctUDsAmdhHcDItAg)\\n\\n[Anthropic\u53d1\u5e03Claude3\uff0c\u6548\u679c\u5df2\u8d85\u8d8aGPT4](https://mp.weixin.qq.com/s/b_eWGauwi6v0w4CoSOnU5w)\\n\\n[\u4ece0\u5f00\u59cb\u9884\u8bad\u7ec31.4b\u4e2d\u6587\u5927\u6a21\u578b\u5b9e\u8df5](https://mp.weixin.qq.com/s/nMWTuKBnQVjgAM7Du6oOFQ)\\n\\n[\u300a\u5206\u7c7b\u7b97\u6cd5\u5165\u95e8:\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\u300b](https://mp.weixin.qq.com/s/W5W582CqxvRhF3wnKwIdiQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ee5\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\u4e3a\u4f8b\uff0c\u5168\u9762\u800c\u8be6\u7ec6\u5730\u9610\u8ff0\u4e86\u673a\u5668\u5b66\u4e60\u4e2d\u7684\u5206\u7c7b\u7b97\u6cd5\u57fa\u7840\u77e5\u8bc6\u3002\u9996\u5148\u4ecb\u7ecd\u4e86\u4eba\u5de5\u667a\u80fd\u3001\u673a\u5668\u5b66\u4e60\u548c\u6df1\u5ea6\u5b66\u4e60\u7684\u57fa\u672c\u6982\u5ff5\uff0c\u8bb2\u89e3\u4e86\u673a\u5668\u5b66\u4e60\u5404\u79cd\u5206\u7c7b\u65b9\u6cd5\u7684\u7406\u8bba\u80cc\u666f\u3002\u968f\u540e\u901a\u8fc7\u9e22\u5c3e\u82b1\u6570\u636e\u96c6\uff0c\u5c55\u793a\u4e86\u5982\u4f55\u4f7f\u7528 Python \u5de5\u5177\uff08\u5305\u62ec pandas\u3001sklearn\u3001matplotlib \u548c seaborn\uff09\u8fdb\u884c\u6570\u636e\u5904\u7406\u3001\u5206\u6790\u548c\u53ef\u89c6\u5316\u3002\u6587\u7ae0\u8be6\u7ec6\u8bb2\u8ff0\u4e86\u51b3\u7b56\u6811\u3001\u903b\u8f91\u56de\u5f52\u3001\u652f\u6301\u5411\u91cf\u673a\u3001K\u8fd1\u90bb\u7b49\u7ecf\u5178\u7684\u5206\u7c7b\u7b97\u6cd5\uff0c\u5e76\u7528\u56fe\u5f62\u5316\u7684\u65b9\u5f0f\u5c55\u793a\u4e86\u5206\u7c7b\u6548\u679c\u3002\u6700\u540e\uff0c\u8bfb\u8005\u53ef\u4ee5\u901a\u8fc7\u672c\u6587\u6240\u63d0\u4f9b\u7684\u4e30\u5bcc\u5b66\u4e60\u8d44\u6599\u6765\u6df1\u5316\u5bf9\u673a\u5668\u5b66\u4e60\u5206\u7c7b\u4efb\u52a1\u7684\u7406\u89e3\u548c\u5e94\u7528\u3002\\n\\n[\u300a\u4e07\u5b57\u8be6\u89e3LLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\u300b](https://mp.weixin.qq.com/s/fkRG7n4tOQKwU85xiEx0Eg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"\u5199\u5728\u8de8\u5e74\u4e4b\u524d\uff1a\u804a\u804aLLM Agents\u7684\u73b0\u72b6\uff0c\u95ee\u9898\u4e0e\u672a\u6765\\"\uff0c\u4e3b\u8981\u6d89\u53ca\u5230LLM Agents\u7684\u5f53\u524d\u72b6\u6001\uff0c\u9762\u4e34\u7684\u95ee\u9898\u548c\u672a\u6765\u7684\u53ef\u80fd\u53d1\u5c55\u3002\u6587\u7ae0\u63a2\u8ba8\u4e86\u5305\u62ec\u5168\u53c2\u5fae\u8c03\u3001Prompt Tuning\u3001LoRA\u3001P-Tuning\u7b49\u5728\u5185\u7684SFT(Selective Fine Tuning)\u8303\u7574\u7684\u5404\u79cd\u6280\u672f\u3002\u5176\u4e2d\u5c24\u5176\u5f3a\u8c03\u4e86\u5bf9\u4e8e{prompt\uff0cresponse}\u7684\u5355\u8f6e\u95ee\u7b54\u5bf9\u7684\u5fae\u8c03\u662f\u6700\u7b80\u5355\u7684SFT\u5b9e\u73b0\u65b9\u5f0f\u3002\u5177\u4f53\u7684\u5185\u5bb9\u7ec6\u8282\u5927\u6982\u9700\u8981\u9605\u8bfb\u539f\u6587\u624d\u80fd\u83b7\u5f97\u66f4\u6df1\u5165\u7684\u7406\u89e3\u3002\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u300aRobust generic functions on slices\u300b](https://go.dev/blog/generic-slice-functions)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"Robust generic functions on slices\\"\uff0c\u4e3b\u8981\u63a2\u8ba8\u4e86Go\u7684slices\u5305\u5982\u4f55\u63d0\u4f9b\u5bf9\u5207\u7247\u8fdb\u884c\u64cd\u4f5c\u7684\u901a\u7528\u51fd\u6570\u3002\u8be5\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u7c7b\u578b\u53c2\u6570\uff0c\u4e00\u6b21\u6027\u4e3a\u6240\u6709\u7c7b\u578b\u7684\u5207\u7247\u7f16\u5199\u7c7b\u4f3cslices.Index\u7b49\u51fd\u6570\uff0c\u800c\u65e0\u9700\u9488\u5bf9\u6bcf\u79cd\u4e0d\u540c\u7684\u5143\u7d20\u7c7b\u578b\u91cd\u65b0\u5b9e\u73b0\u3002\u968f\u540e\uff0c\u6587\u7ae0\u6df1\u5165\u8bb2\u8ff0\u4e86\u65b0\u7684\u51fd\u6570\uff08\u5982Insert, Replace\uff0cDelete\u7b49\uff09\u5982\u4f55\u4fee\u6539\u5207\u7247\uff0c\u5e76\u901a\u8fc7\u8be6\u8ff0\u5207\u7247\u5728\u5185\u5b58\u4e2d\u7684\u8868\u73b0\u5f62\u5f0f\u53ca\u5176\u5bf9\u5783\u573e\u56de\u6536\u5668\u7684\u5f71\u54cd\uff0c\u6765\u5e2e\u52a9\u8bfb\u8005\u7406\u89e3\u8fd9\u4e9b\u51fd\u6570\u7684\u5de5\u4f5c\u65b9\u5f0f\u548c\u6b63\u786e\u4f7f\u7528\u5b83\u4eec\u3002\u6587\u7ae0\u7279\u522b\u6307\u51fa\uff0c\u65b0\u7684Delete\u51fd\u6570\u63d0\u4f9b\u4e86\u66f4\u6e05\u6670\u5730\u8868\u8fbe\u7a0b\u5e8f\u5458\u610f\u56fe\u7684\u65b9\u5f0f\uff0c\u800c\u4e14\u5b83\u4e0d\u9700\u8981\u5206\u914d\u65b0\u7684\u6570\u7ec4\uff0c\u8fd9\u6837\u5c31\u53ef\u4ee5\u5728\u9002\u5f53\u65f6\u6e05\u9664\u65e0\u7528\u7684\u5143\u7d20\uff0c\u5e2e\u52a9\u5783\u573e\u56de\u6536\u3002\u6587\u7ae0\u5f3a\u8c03\uff0c\u8c03\u7528\u8fd9\u4e9b\u51fd\u6570\u540e\uff0c\u5fc5\u987b\u8ba4\u4e3a\u539f\u59cb\u5207\u7247\u5df2\u65e0\u6548\uff0c\u56e0\u4e3a\u5e95\u5c42\u6570\u7ec4\u5df2\u88ab\u4fee\u6539\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8fd8\u8ba8\u8bba\u4e86\u5728\u5904\u7406\u5185\u5b58\u6cc4\u6f0f\u548c\u5143\u7d20\u96f6\u503c\u8bbe\u7f6e\u7b49\u95ee\u9898\u65f6\u7684\u7b56\u7565\u548c\u9009\u9879\uff0c\u5b83\u4eec\u5728\u65b0\u7248\u672cGo\u7ed9\u51fa\u7684\u89e3\u51b3\u65b9\u6848\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u6539\u53d8\u53ef\u80fd\u5bfc\u81f4\u7684\u4e00\u4e9b\u6d4b\u8bd5\u95ee\u9898\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u9f13\u52b1\u5f00\u53d1\u4eba\u5458\u6b63\u786e\u4f7f\u7528\u65b0\u529f\u80fd\uff0c\u5e76\u5c3d\u91cf\u907f\u514d\u4e0a\u8ff0\u5217\u4e3e\u7684\u9677\u9631\u3002\\n\\n[\u300aRouting Enhancements for Go 1.22\u300b](https://go.dev/blog/routing-enhancements)\u3002\u8fd9\u7bc7\u6587\u7ae0\u540d\u4e3a\\"Routing Enhancements for Go 1.22\\"\uff0c\u4e3b\u8981\u4ecb\u7ecd\u4e86 Go 1.22 \u7248\u672c\u4e2d net/http \u5305\u7684\u8def\u7531\u5668\u63d0\u4f9b\u7684\u65b0\u7279\u6027\uff1a\u65b9\u6cd5\u5339\u914d\u548c\u901a\u914d\u7b26\u3002\u8fd9\u4e9b\u65b0\u7279\u6027\u8ba9\u4f60\u53ef\u4ee5\u4f7f\u7528\u6a21\u5f0f\uff0c\u800c\u975e Go \u4ee3\u7801\uff0c\u6765\u8868\u8fbe\u5e38\u89c1\u7684\u8def\u7531\u3002\u8fd9\u79cd\u65b0\u529f\u80fd\uff0c\u5c3d\u7ba1\u7b80\u5355\u6613\u61c2\uff0c\u4f46\u8981\u9009\u62e9\u51fa\u591a\u4e2a\u5339\u914d\u8bf7\u6c42\u7684\u6700\u4f73\u6a21\u5f0f\u5374\u662f\u4e00\u9879\u6311\u6218\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u9610\u91ca\u4e86\u5982\u4f55\u5728\u65b0\u7248 Go \u4e2d\u4f7f\u7528\u8fd9\u4e9b\u65b0\u7279\u6027\uff0c\u4ee5\u53ca\u8fd9\u4e9b\u5f15\u5165\u7684\u53d8\u5316\u5982\u4f55\u5f71\u54cd\u4e86 ServeMux \u65b9\u6cd5 handle \u548c handleFunc \u3002\u6b64\u5916\uff0c\u8fd8\u63cf\u8ff0\u4e86\u65b0\u6a21\u5f0f\u5982\u4f55\u66f4\u5177\u4f18\u5148\u7ea7\uff0c\u5e76\u89e3\u91ca\u4e86\u5176\u80cc\u540e\u7684\u539f\u7406\u3002\u540c\u65f6\uff0c\u4e3a\u4e86\u4fdd\u6301\u65b0\u65e7\u7248\u672c\u7684\u517c\u5bb9\u6027\uff0c\u4f5c\u8005\u4eec\u4e5f\u52aa\u529b\u4f7f\u65b0\u7684\u6a21\u5f0f\u8bed\u6cd5\u80fd\u8986\u76d6\u65e7\u7684\uff0c\u5e76\u4f7f\u65b0\u7684\u4f18\u5148\u7ea7\u89c4\u5219\u80fd\u6cdb\u5316\u65e7\u7684\u89c4\u5219\u3002\u603b\u4f53\u4e0a\uff0c\u8fd9\u4e9b\u6539\u53d8\u662f Go \u8bed\u8a00\u56e2\u961f\u4e0d\u65ad\u52aa\u529b\u4f7f Go \u6210\u4e3a\u6784\u5efa\u751f\u4ea7\u7cfb\u7edf\u7684\u4f18\u79c0\u8bed\u8a00\u7684\u4e00\u4e2a\u6301\u7eed\u8fc7\u7a0b\u7684\u4e00\u90e8\u5206\u3002\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(6)](https://mp.weixin.qq.com/s/IH1FGDpClrsnlfjg7OF3lg)\\n\\n[\u4f7f\u7528Apache Kafka\u7684Golang\u5b9e\u8df5\u6307\u5357](https://mp.weixin.qq.com/s/JCU3dwkwpMP3qMKqg9ed6g)\\n\\n[\u300aGo \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570\u300b](https://mp.weixin.qq.com/s/RFsHfFByarSRAA-f1Rs13g)\u3002\u8fd9\u7bc7\u7531\u714e\u9c7c\u64b0\u5199\u7684\u6587\u7ae0\uff0c\u9898\u4e3a \\"Go \u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u4ece main \u5305\u4e2d\u5bfc\u5165\u51fd\u6570?\\"\uff0c\u5bf9\u4e8e\u8fd9\u4e2a\u8bdd\u9898\u8fdb\u884c\u4e86\u6df1\u5ea6\u89e3\u6790\u3002\u5176\u9996\u5148\u63d0\u5230\uff0c\u867d\u7136Go\u7684\u89c4\u8303\u5e76\u6ca1\u6709\u660e\u786e\u7981\u6b62\u4ecemain\u5305\u4e2d\u5bfc\u5165\u51fd\u6570\uff0c\u4f46\u6211\u4eec\u5728\u5b9e\u9645\u8fd0\u884c\u4e2d\u4f1a\u88ab\u62d2\u7edd\uff0c\u63d0\u793amain\u5305\u662f\u4e00\u4e2a\u7a0b\u5e8f\u800c\u975e\u53ef\u4ee5\u5bfc\u5165\u7684\u5305\u3002\u8fd9\u4e00\u73b0\u8c61\u7684\u539f\u56e0\u6765\u81ea\u4e8e\u7ecf\u8fc7\u591a\u6b21\u53d8\u52a8\u7684\u89c4\u5b9a\uff0c\u59822011\u5e74\u79fb\u9664\u4e86 \\"\u7a0b\u5e8f\u4e2d\u7684\u5176\u4ed6\u5305\u90fd\u4e0d\u80fd\u547d\u540d\u4e3a main\\" \u7684\u8981\u6c42\uff0c\u7136\u540e\u57282015\u5e74\u53c8\u65b0\u589e\u4e86\u9650\u5236\u3002\u8fd9\u6837\u7684\u53d8\u5316\u4e3b\u8981\u662f\u4e3a\u4e86\u907f\u514d\u589e\u52a0\u590d\u6742\u5ea6\u548c\u4e0d\u5b89\u5168\u6027\u3002\u6bd4\u5982\uff0c\u4e00\u4e2a\u51fd\u6570\u53ef\u80fd\u4f1a\u505a\u51fa\u81ea\u5df1\u62e5\u6709\u5b8c\u5168\u63a7\u5236\u6743\u7684\u5047\u8bbe\uff0c\u6240\u4ee5\u5982\u679c\u5f15\u5165\u591a\u4e2amain\u5305\u4e2d\u7684\u51fd\u6570\uff0c\u53ef\u80fd\u4f1a\u4ea7\u751f\u5728\u521d\u59cb\u5316\u987a\u5e8f\u3001\u5168\u5c40\u53d8\u91cf\u7684\u6ce8\u518c\u7b49\u65b9\u9762\u7684\u51b2\u7a81\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba4\u4e3aGo\u5b98\u65b9\u7684\u505a\u6cd5\u5728\u7406\u8bba\u4e0a\u53ef\u4ee5\u89e3\u51b3\u590d\u6742\u5ea6\u548c\u5b89\u5168\u6027\u95ee\u9898\uff0c\u4f46\u5bf9\u4e8e\u6709\u5386\u53f2\u503a\u52a1\u7684\u9879\u76ee\uff0c\u5bf9\u4e8e\u9700\u8981\u7ef4\u62a4\u591a\u4e2aGo\u9879\u76ee\u5de5\u7a0b\uff0c\u76f8\u5f53\u4e8e\u78e8\u706d\u4e86\u4e00\u6761\u9053\u8def\uff0c\u5176\u5b9e\u6bd4\u8f83\u5c34\u5c2c\u3002\\n\\n[\u300afasthttp\u662f\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u300b](https://mp.weixin.qq.com/s/zxLO4IhLqQmIaUDzwwjU1w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8bb2\u89e3\u4e86fasthttp\u5982\u4f55\u505a\u5230\u6bd4net/http\u5feb\u5341\u500d\u7684\u539f\u7406\u3002fasthttp\u76f8\u6bd4\u4e8enet/http\u5728\u5904\u7406\u6d41\u7a0b\u4e0a\u6709\u6240\u5dee\u5f02\uff0cnet/http\u662f\u4e00\u4e2a\u8fde\u63a5\u65b0\u5efa\u4e00\u4e2agoroutine\uff0c\u5f53\u8fde\u63a5\u6570\u975e\u5e38\u591a\u7684\u65f6\u5019\u4f1a\u7ed9\u7cfb\u7edf\u5e26\u6765\u4e00\u5b9a\u7684\u538b\u529b\u3002\u800cfasthttp\u5219\u662f\u5efa\u7acb\u4e86workerPool\uff0c\u6bcf\u4e2aworkerChan\u5728\u540e\u53f0\u90fd\u4f1a\u6709\u4e00\u4e2aGoroutine\u6765\u5904\u7406\u5176\u4e2d\u7684\u8fde\u63a5\u3002\u6b64\u5916\uff0cfasthttp\u7684\u5feb\u901f\u4e5f\u5f97\u76ca\u4e8e\u51e0\u4e2a\u65b9\u9762\u7684\u4f18\u5316\uff1a\u8fde\u63a5\u590d\u7528\uff0c\u5927\u91cf\u4f7f\u7528\u4e86sync.Pool\u8fdb\u884c\u5185\u5b58\u590d\u7528\u4ee5\u53ca\u901a\u8fc7unsafe.Pointer\u6307\u9488\u8fdb\u884c\\\\[\\\\]byte\u548cstring\u8f6c\u6362\u6765\u907f\u514d\u5185\u5b58\u5206\u914d\u548c\u62f7\u8d1d\u7684\u6d88\u8017\u3002\\n\\n[\u300a\u4e07\u5b57\u957f\u6587\u8bb2\u89e3Golang pprof \u7684\u4f7f\u7528\u300b](https://mp.weixin.qq.com/s/fx-FTVpM3CXIPUwTC_juDQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86Golang\u7684pprof\u5de5\u5177\u7684\u4f7f\u7528\u3002pprof\u5de5\u5177\u662fGolang\u4e2d\u7528\u4e8e\u6027\u80fd\u5206\u6790\u7684\u4e00\u4e2a\u5de5\u5177\uff0c\u5b83\u53ef\u4ee5\u5206\u6790\u51facpu\u4f7f\u7528\u60c5\u51b5\u3001\u5185\u5b58\u5360\u7528\u3001\u963b\u585e\u60c5\u51b5\u3001\u7ebf\u7a0b\u548c\u534f\u7a0b\u7b49\u4fe1\u606f\u3002\u6587\u7ae0\u4e2d\u8be6\u7ec6\u9610\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528\u6b64\u5de5\u5177\uff0c\u4e3b\u8981\u6709\u4e24\u79cd\u65b9\u5f0f\uff0c\u4e00\u79cd\u662f\u901a\u8fc7http\u63a5\u53e3\u7684\u65b9\u5f0f\u66b4\u9732\u51fapprof\u7684\u91c7\u96c6\u63a7\u5236\u754c\u9762\uff0c\u53e6\u4e00\u79cd\u662f\u5728\u7a0b\u5e8f\u4e2d\u901a\u8fc7\u4ee3\u7801\u6765\u542f\u52a8\u76f8\u5e94\u6307\u6807\u7684\u91c7\u96c6\u793a\u4f8b\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u89e3\u6790\u901a\u8fc7\u8fd9\u4e24\u79cd\u65b9\u5f0f\u83b7\u53d6\u7684\u8f93\u51fa\u4fe1\u606f\u3002\u672c\u6587\u7684\u4e3b\u8981\u76ee\u7684\u662f\u5c06pprof\u5de5\u5177\u7684\u4f7f\u7528\u65b9\u5f0f\u7528\u601d\u7ef4\u5bfc\u56fe\u7684\u5f62\u5f0f\u5c55\u793a\u51fa\u6765\uff0c\u8fd9\u6837\u53ef\u4ee5\u5e2e\u52a9\u8bfb\u8005\u66f4\u597d\u5730\u7406\u89e3\u548c\u4f7f\u7528pprof\u5de5\u5177\u3002\\n\\n[\u300a\u4e00\u7bc7\u5b9e\u7528\u7684\u5173\u4e8e\u4e91\u4e0aK8s\u5e94\u7528\u5206\u8d26\u5b9e\u8df5\u300b](https://mp.weixin.qq.com/s/xYvMI0JieO6RxHIdWf1ujQ)\u3002\u672c\u6587\u8bb2\u8ff0\u4e91\u4e0aKubernetes\uff08K8s\uff09\u5e94\u7528\u7684\u6210\u672c\u5206\u644a\u5b9e\u8df5\uff0c\u6db5\u76d6\u4e86\u6210\u672c\u5206\u644a\u7684\u6838\u5fc3\u6982\u5ff5\u53ca\u963f\u91cc\u4e91ACK FinOps\u5957\u4ef6\u7684\u5e94\u7528\u3002\u6587\u4e2d\u9996\u5148\u4ee5\u524d\u671f\u9884\u7b97\u4e3a\u96c6\u7fa4\u89c4\u5212\u7684\u4f9d\u636e\uff0c\u5e76\u8ba8\u8bba\u4e86\u968f\u7740\u4e1a\u52a1\u53d1\u5c55\u5bf9\u6210\u672c\u5206\u644a\u7cbe\u51c6\u5ea6\u7684\u63d0\u5347\u9700\u6c42\u3002\u4ecb\u7ecd\u4e86\u5982\u4f55\u6839\u636ePod\u7684\u6838/\u65f6\u6210\u672c\uff0c\u901a\u8fc7ACK\u96c6\u7fa4\u3001\u8ba1\u7b97\u8282\u70b9\u3001\u547d\u540d\u7a7a\u95f4\u548c\u5e94\u7528Pod\u8fd9\u56db\u4e2a\u7ef4\u5ea6\u8fdb\u884c\u8d39\u7528\u5206\u644a\u3002\u6587\u7ae0\u8fd8\u5206\u6790\u4e86\u5355\u8d44\u6e90\u548c\u6df7\u5408\u8d44\u6e90\u5206\u644a\u6a21\u578b\uff0c\u5e76\u8ba8\u8bba\u4e86\u5982\u4f55\u8bbe\u7f6eRequest\u548cLimit\u6765\u4f18\u5316\u8d44\u6e90\u5229\u7528\u3002\u5bf9\u4e8e\u591a\u4e91\u548c\u6df7\u5408\u4e91\u573a\u666f\uff0c\u5206\u4eab\u4e86\u5982\u4f55\u901a\u8fc7ACK One\u5b9e\u73b0\u7edf\u4e00\u7ba1\u7406\u548c\u6210\u672c\u5206\u6790\u3002\u9488\u5bf9\u590d\u6742\u4e1a\u52a1\u573a\u666f\uff0c\u8bb2\u8ff0\u4e86\u81ea\u5b9a\u4e49\u5b9a\u4ef7\u6a21\u7248\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u5141\u8bb8\u901a\u8fc7\u914d\u7f6e\u5b9e\u73b0\u6210\u672c\u5b9a\u5236\u9700\u6c42\u3002\u5bf9\u4e8e\u8ffd\u6c42\u7ec6\u8282\u7ba1\u7406\u548c\u7cbe\u7ec6\u5316\u8fd0\u8425\u7684\u56e2\u961f\uff0c\u8fd9\u7bc7\u6587\u7ae0\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u6307\u5bfc\u3002\\n\\n[\u300a\u5982\u4f55\u4f7f\u7528 K8s \u4e24\u5927\u5229\u5668\\"\u5ba1\u8ba1\\"\u548c\\"\u4e8b\u4ef6\\"\u5e2e\u4f60\u6446\u8131\u8fd0\u7ef4\u56f0\u5883\u300b](https://mp.weixin.qq.com/s/6xx3-qow8A5Hdp_72jswow)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5982\u4f55\u4f7f\u7528 Kubernetes\uff08K8s\uff09\u7684\\"\u5ba1\u8ba1\\"\u548c\\"\u4e8b\u4ef6\\"\u529f\u80fd\u6765\u5e2e\u52a9\u8fdb\u884c\u65e5\u5e38\u96c6\u7fa4\u8fd0\u7ef4\u5de5\u4f5c\u3002\u6587\u7ae0\u9996\u5148\u6307\u51fa\u4e86\u8fd0\u7ef4\u5de5\u4f5c\u4e2d\u53ef\u80fd\u51fa\u73b0\u7684\u4e00\u4e9b\u95ee\u9898\uff0c\u4f8b\u5982\u5e94\u7528\u88ab\u5220\u9664\u3001Apiserver\u8d1f\u8f7d\u7a81\u53d8\u3001\u96c6\u7fa4\u8282\u70b9\u51fa\u73b0\u95ee\u9898\u3001\u8282\u70b9\u81ea\u52a8\u6269\u5bb9\u7b49\u3002\u968f\u540e\uff0c\u6587\u7ae0\u8fdb\u4e00\u6b65\u89e3\u91ca\u4e86 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\u662f\u5982\u4f55\u8fd0\u4f5c\u7684\uff0c\u5f3a\u8c03\u4e86\u5584\u7528\u8fd9\u4e24\u79cd\u5de5\u5177\u53ef\u4ee5\u63d0\u9ad8\u96c6\u7fa4\u7684\u53ef\u89c2\u5bdf\u6027\uff0c\u4e3a\u8fd0\u7ef4\u5de5\u4f5c\u5e26\u6765\u6781\u5927\u7684\u4fbf\u5229\u3002\u603b\u7684\u6765\u8bf4\uff0c\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u4e00\u79cd\u89e3\u51b3\u65b9\u6848\uff0c\u901a\u8fc7\u4f7f\u7528 Kubernetes\u7684\u5ba1\u8ba1\u548c\u4e8b\u4ef6\uff0c\u53ef\u4ee5\u66f4\u597d\u5730\u7ba1\u7406\u548c\u76d1\u6d4b\u96c6\u7fa4\u7684\u72b6\u6001\u3002\\n\\n[\u3010Go \u5de5\u5177\u3011\u7ade\u6001\u6761\u4ef6\u68c0\u6d4b\u795e\u5668 Race Detector](https://mp.weixin.qq.com/s/lxEAFe2Ewmc8YvTqn8UcLQ)\\n\\n[\u4f7f\u7528Redis\u5165\u95e8Golang](https://mp.weixin.qq.com/s/Y67J4_D1yyMa-eb7XmgTcA)\\n\\n[\u4e00\u9053\u9762\u8bd5\u9898: Top K \u95ee\u9898](https://mp.weixin.qq.com/s/qDFM-nVo-jeh9VdcBfMreA)\\n\\n[\u300a\u7406\u89e3 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u300b](https://mp.weixin.qq.com/s/sTd3SVh0swGTnaGugsw1SA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u89e3\u6790\u4e86 Docker \u5bb9\u5668\u4e2d UID \u548c GID \u7684\u5de5\u4f5c\u539f\u7406\u3002\u9996\u5148\uff0c\u4f5c\u8005\u6982\u8ff0\u4e86\u7528\u6237\u540d\u3001\u7ec4\u540d\u3001\u7528\u6237ID\uff08UID\uff09\u548c\u7ec4ID\uff08GID\uff09\u5728\u5bb9\u5668\u5185\u8fd0\u884c\u7684\u8fdb\u7a0b\u4e0e\u4e3b\u673a\u7cfb\u7edf\u4e4b\u95f4\u7684\u6620\u5c04\u5bf9\u4e8e\u6784\u5efa\u5b89\u5168\u7cfb\u7edf\u7684\u91cd\u8981\u6027\u3002\u968f\u540e\uff0c\u6587\u7ae0\u5206\u6790\u4e86uid/gid\u5728Linux\u7cfb\u7edf\u7684\u5b89\u5168\u6027\uff0c\u5f3a\u8c03\u4e86\u5355\u4e00\u5185\u6838\u6982\u5ff5\u4ee5\u53cauid/gid\u7684\u5206\u914d\u65b9\u5f0f\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u8fd0\u7528\u5b9e\u4f8b\u89e3\u91ca\u4e86Docker\u8fd0\u884c\u7684\u8fc7\u7a0b\u4ee5\u53ca\u5982\u4f55\u901a\u8fc7Dockerfile\u5b9a\u4e49\u548c\u542f\u52a8\u4e0d\u540c\u7528\u6237\u3002\u6700\u540e\uff0c\u6587\u7ae0\u8bb2\u8ff0\u4e86\u5982\u4f55\u638c\u63a7\u548c\u63a7\u5236\u5bb9\u5668\u7684\u8bbf\u95ee\u6743\u9650\u3002\u5728\u9610\u8ff0\u4ee5\u4e0a\u5185\u5bb9\u7684\u540c\u65f6\uff0c\u6587\u7ae0\u4e5f\u63d0\u4f9b\u4e86\u4e00\u4e9b\u5b9e\u9645\u793a\u4f8b\u6765\u8bf4\u660e\u8fd9\u4e9b\u89c2\u70b9\u3002\\n\\n[\u300a\u5982\u4f55\u57fa\u4e8eDocker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u300b](https://mp.weixin.qq.com/s/yUuo1IjeXY78_5u4QpkuTA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4ecb\u7ecd\u4e86\u5982\u4f55\u5c06Docker\u955c\u50cf\u9006\u5411\u751f\u6210Dockerfile\u3002\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86\u5229\u7528\u5f00\u6e90\u5de5\u5177Dedockify\u7684\u64cd\u4f5c\u65b9\u6cd5\u4e0e\u5de5\u4f5c\u539f\u7406\u3002\u8be5\u5de5\u5177\u901a\u8fc7Python\u811a\u672c\uff0c\u5229\u7528\u5b58\u50a8\u5728\u6bcf\u4e2a\u955c\u50cf\u5c42\u65c1\u8fb9\u7684\u5143\u6570\u636e\uff0c\u9010\u6b65\u904d\u5386\u5c42\u7ea7\u6811\uff0c\u6536\u96c6\u4e0e\u6bcf\u4e2a\u5c42\u76f8\u5173\u8054\u7684\u547d\u4ee4\uff0c\u91cd\u5efa\u955c\u50cf\u6784\u5efa\u8fc7\u7a0b\u4e2d\u6267\u884c\u7684\u547d\u4ee4\u5e8f\u5217\uff0c\u4ece\u800c\u5f97\u5230\u8fd1\u4f3c\u7684Dockerfile\u3002\u4e0d\u8fc7\uff0c\u56e0\u4e3a\u65e0\u6cd5\u8bbf\u95ee\u6267\u884c\u539f\u59cbdocker build\u547d\u4ee4\u65f6\u5b58\u5728\u7684\u6784\u5efa\u4e0a\u4e0b\u6587\uff0c\u5982\u679c\u4f7f\u7528\u4e86COPY\u6216ADD\u6307\u4ee4\uff0c\u751f\u6210\u7684\u8f93\u51fa\u53ef\u80fd\u4e0d\u5b8c\u5168\u5339\u914d\u539f\u59cb\u7684Dockerfile\u3002\\n\\n[\u300a\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u300b](https://mp.weixin.qq.com/s/KkRWQyljuo86-XbBxEnGPA)\u3002\u672c\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86\u5982\u4f55\u901a\u8fc7\u591a\u9636\u6bb5\u6784\u5efa\u51cf\u5c0fGolang\u955c\u50cf\u7684\u5927\u5c0f\u3002\u9996\u5148\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a\u901a\u7528\u7684Dockerfile\uff0c\u5e76\u6307\u51fa\u5176\u751f\u6210\u7684\u955c\u50cf\u5927\u5c0f\u8d85\u8fc7300MB\uff0c\u4e3b\u8981\u56e0\u4e3a\u5305\u542b\u4e86\u6240\u6709\u7684Golang\u5de5\u5177\u3002\u7136\u540e\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u591a\u9636\u6bb5\u6784\u5efa\u7684\u65b9\u6cd5\uff0c\u5b83\u80fd\u4ece\u4e0d\u540c\u7684\u57fa\u7840\u955c\u50cf\u6784\u5efa\uff0c\u6709\u9009\u62e9\u5730\u5c06\u6587\u4ef6\u4ece\u4e00\u4e2a\u9636\u6bb5\u4f20\u9012\u5230\u4e0b\u4e00\u4e2a\u9636\u6bb5\uff0c\u4ece\u800c\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u3002\u5728\u672c\u4f8b\u4e2d\uff0c\u901a\u8fc7\u4e8c\u7ea7\u6784\u5efa\uff0c\u955c\u50cf\u5927\u5c0f\u5df2\u964d\u81f311.7MB\u3002\u6700\u540e\uff0c\u8fd8\u63a2\u8ba8\u4e86\u4f7f\u7528\u540d\u4e3ascratch\u7684\u7a7a\u767d\u955c\u50cf\u8fdb\u4e00\u6b65\u51cf\u5c0f\u955c\u50cf\u5927\u5c0f\u7684\u53ef\u80fd\u6027\uff0c\u4f7f\u5f97\u955c\u50cf\u6700\u540e\u964d\u81f36.34MB\uff0c\u4f46\u4f5c\u8005\u5f3a\u8c03\u8fd9\u9700\u8981\u614e\u91cd\u8003\u8651\uff0c\u56e0\u4e3a\u6700\u540e\u751f\u6210\u7684\u955c\u50cf\u5c06\u5b8c\u5168\u6ca1\u6709\u4efb\u4f55\u5de5\u5177\u3002\\n\\n[\u300ak8s \u5230\u5e95\u662f\u4ec0\u4e48\uff0c\u67b6\u6784\u662f\u600e\u4e48\u6837\u7684\u300b](https://mp.weixin.qq.com/s/dckA1ezcABndN5WSg1BOBA)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8bb2\u8ff0\u4e86 Kubernetes\uff08K8s\uff09\u7684\u57fa\u672c\u6982\u5ff5\u3001\u67b6\u6784\u548c\u5de5\u4f5c\u539f\u7406\u3002Kubernetes\uff0c\u56e0\u5355\u8bcd\u8fc7\u957f\uff0c\u6211\u4eec\u901a\u5e38\u7b80\u5316\u4e3ak8s\u3002k8s \u662f\u4e00\u79cd\u5bb9\u5668\u7684\u534f\u8c03\u5de5\u5177\uff0c\u4f4d\u4e8e\u5e94\u7528\u670d\u52a1\u548c\u670d\u52a1\u5668\u4e4b\u95f4\uff0c\u80fd\u4ee5\u7b56\u7565\u7684\u65b9\u5f0f\u534f\u8c03\u548c\u7ba1\u7406\u591a\u4e2a\u5e94\u7528\u670d\u52a1\u3002\u901a\u8fc7\u4e00\u4e2a yaml \u6587\u4ef6\u7684\u914d\u7f6e\uff0c\u53ef\u4ee5\u5b9a\u4e49\u5e94\u7528\u7684\u90e8\u7f72\u987a\u5e8f\u7b49\u4fe1\u606f\uff0c\u81ea\u52a8\u90e8\u7f72\u5e94\u7528\u5230\u5404\u4e2a\u670d\u52a1\u5668\u4e0a\uff0c\u8fd8\u80fd\u8ba9\u5b83\u4eec\u5d29\u6e83\u540e\u81ea\u52a8\u91cd\u542f\uff0c\u53ef\u4ee5\u81ea\u52a8\u6269\u5bb9\u548c\u7f29\u5bb9\u3002Kubernetes \u7684\u670d\u52a1\u5668\u5206\u4e3a\u4e24\u90e8\u5206\uff1a\u63a7\u5236\u5e73\u9762\u548c\u5de5\u4f5c\u8282\u70b9\uff0c\u524d\u8005\u8d1f\u8d23\u63a7\u5236\u548c\u7ba1\u7406\u5404\u4e2a\u8282\u70b9\uff0c\u540e\u8005\u5219\u8d1f\u8d23\u5b9e\u9645\u8fd0\u884c\u5404\u4e2a\u5e94\u7528\u670d\u52a1\u3002k8s \u7684\u547d\u4ee4\u884c\u5de5\u5177\u4e3a kubectl\uff0c\u7528\u4e8e\u6267\u884c\u5404\u7c7b\u64cd\u4f5c\u547d\u4ee4\u3002\\n\\n[\u300aGo \u6cdb\u578b\u6709\u6ca1\u6709\u53ef\u80fd\u5728\u540e\u671f\u6539\u4e3a `<>` \u5c16\u62ec\u53f7\u300b](https://mp.weixin.qq.com/s/vjmntyGwzURz_elg27vpXg)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u8ba8\u8bba\u4e86Go\u8bed\u8a00\u5728\u5904\u7406\u6cdb\u578b\u65f6\uff0c\u4e3a\u4f55\u5e76\u6ca1\u6709\u91c7\u7528\u7c7b\u4f3cJava\u548cC++\u7684 `<>` \u5c16\u62ec\u53f7\u8868\u793a\u6cd5\uff0c\u800c\u662f\u9009\u62e9\u4e86\u4e2d\u62ec\u53f7 `[]`. \u9996\u5148\uff0c\u4f7f\u7528\u5c16\u62ec\u53f7\u53ef\u80fd\u5bfc\u81f4\u8bed\u4e49\u6df7\u6dc6\uff0c\u5982 `a, b := w < x, y > (z)` \u6b64\u53e5\uff0c\u5982\u679c\u4f7f\u7528\u5c16\u62ec\u53f7\uff0c\u7a0b\u5e8f\u53ef\u80fd\u5728\u7f16\u8bd1\u9636\u6bb5\u65e0\u6cd5\u786e\u5b9a\u8be5\u884c\u8868\u8fbe\u5f0f\u7684\u5177\u4f53\u542b\u4e49\u3002\u5176\u6b21\uff0c\u4f7f\u7528\u5706\u62ec\u53f7\u4e5f\u4f1a\u5bfc\u81f4\u540c\u6837\u7684\u95ee\u9898\uff0c\u6bd4\u5982 `func F(T any)(v T)(r1, r2 T)`, \u65e0\u6cd5\u5feb\u901f\u51c6\u786e\u5224\u65ad\u51fa\u53c2\u6570\u548c\u8fd4\u56de\u503c\u90e8\u5206\u3002\u6b64\u5916\uff0cGo\u5b98\u65b9\u4e5f\u4e0d\u5e0c\u671b\u4f7f\u7528\u975eASCII\u7684\u5b57\u7b26\u3002\u4f5c\u8005\u8fd8\u63d0\u5230\u793e\u533a\u4e2d\u5bf9Go\u7684\u5904\u7406\u65b9\u5f0f\u5b58\u5728\u4e00\u4e9b\u4e89\u8bae\uff0c\u90e8\u5206\u793e\u533a\u6210\u5458\u8ba4\u4e3a\u5982\u679c\u4f7f\u5f97\u7f16\u8bd1\u5668\u89e3\u91ca\u5c16\u62ec\u53f7\u4e0d\u518d\u56f0\u96be\uff0c\u5c31\u53ef\u4ee5\u91c7\u7528\u8fd9\u79cd\u7b26\u53f7\u3002\u7136\u800c\uff0c\u603b\u7684\u6765\u8bf4\uff0c\u57fa\u4e8e\u5df2\u6709\u7684\u5b9e\u8df5\u548c\u89c4\u8303\uff0cGo\u8bed\u8a00\u5728\u672a\u6765\u53ef\u80fd\u4e5f\u4e0d\u4f1a\u6539\u53d8\u5176\u6cdb\u578b\u7684\u8868\u793a\u65b9\u5f0f\u3002\\n\\n[\u300aRust\u4e2dchannel\u7684\u4f7f\u7528\u300b](https://mp.weixin.qq.com/s/arI9sip-5JH9YSu45XJ83w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3b\u8981\u4ecb\u7ecd\u4e86Rust\u7f16\u7a0b\u8bed\u8a00\u4e2dChannel\u7684\u7528\u6cd5\u3002\u5176\u4e2d\uff0cChannel\u662fRust\u4e2d\u7528\u4e8e\u5728\u4e0d\u540c\u7ebf\u7a0b\u95f4\u4f20\u9012\u4fe1\u606f\u7684\u901a\u4fe1\u673a\u5236\uff0c\u5b9e\u73b0\u4e86\u7ebf\u7a0b\u95f4\u7684\u6d88\u606f\u4f20\u9012\u3002\u6bcf\u4e2aChannel\u7531\u53d1\u9001\u7aef\u548c\u63a5\u6536\u7aef\u4e24\u90e8\u5206\u7ec4\u6210\uff0c\u5176\u8bbe\u8ba1\u7406\u5ff5\u662f\u201c\u901a\u8fc7\u901a\u4fe1\u6765\u5171\u4eab\u5185\u5b58\uff0c\u800c\u975e\u901a\u8fc7\u5171\u4eab\u5185\u5b58\u6765\u901a\u4fe1\u201d\uff0c\u4ee5\u6b64\u907f\u514d\u4e86\u6570\u636e\u7ade\u4e89\u548c\u5171\u4eab\u5185\u5b58\u7684\u590d\u6742\u6027\u3002\u8be5\u6587\u7ae0\u8fdb\u4e00\u6b65\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5728Rust\u4e2d\u521b\u5efa\u548c\u4f7f\u7528Channel\uff0c\u5e76\u7ed9\u51fa\u4e86\u76f8\u5173\u4ee3\u7801\u793a\u4f8b\u3002\u6700\u540e\uff0c\u6587\u7ae0\u9610\u8ff0\u4e86\u591a\u79cdChannel\u6a21\u578b\uff0c\u5305\u62ecRust\u6807\u51c6\u5e93\u4e2d\u6240\u4f7f\u7528\u7684MPSC\uff08\u591a\u751f\u4ea7\u8005\uff0c\u5355\u6d88\u8d39\u8005\uff09\u6a21\u578b\u3002\\n\\n[K8s\u90e8\u7f72\u65b9\u5f0f\u5927\u5168\uff1a\u4ece\u57fa\u7840\u5230\u8fdb\u9636\uff0c\u4e00\u6587\u5e26\u4f60\u638c\u63e1\u6240\u6709\u6280\u5de7](https://juejin.cn/post/7272006755266002959)\\n\\n[k8s\u4ece\u5165\u95e8\u5230\u7cbe\u901a -- \u66f4\u9002\u5408\u4e2d\u56fd\u5b9d\u5b9d\u4f53\u8d28](https://juejin.cn/post/7301584578342289423)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u300a\u4e07\u5b57+33\u5f20\u56fe\u63a2\u79d8OpenFeign\u6838\u5fc3\u67b6\u6784\u539f\u7406\u300b](https://mp.weixin.qq.com/s/NABg5tGizHsmdXgUO6NeVw)\u3002\u672c\u7bc7\u6587\u7ae0\u6df1\u5165\u63a2\u8ba8\u4e86SpringCloud\u6838\u5fc3\u7ec4\u4ef6OpenFeign\u7684\u6838\u5fc3\u67b6\u6784\u539f\u7406\u3002\u6587\u7ae0\u5206\u4e3a\u56db\u4e2a\u90e8\u5206\uff0c\u9996\u5148\u89e3\u91ca\u539f\u59cbFeign\u7684\u4f7f\u7528\u548c\u57fa\u4e8eSpringCloud\u7684\u8fdb\u5316\u8fc7\u5386\u7a0b\uff1b\u7136\u540e\u8be6\u7ec6\u8bb2\u89e3\u4e86Feign\u5e95\u5c42\u5de5\u4f5c\u539f\u7406\uff0c\u4f9d\u8d56\u4e8eJDK\u52a8\u6001\u4ee3\u7406\u548c\u6838\u5fc3\u7ec4\u4ef6\u5982Contract\u3001Encoder\u3001Decoder\u7b49\uff1b\u63a5\u4e0b\u6765\u5206\u6790\u4e86SpringCloud\u662f\u5982\u4f55\u6574\u5408Feign\u7684\uff0c\u5e76\u4e14\u8ba8\u8bba\u4e86OpenFeign\u7684\u591a\u79cd\u914d\u7f6e\u65b9\u5f0f\u53ca\u5176\u4f18\u5148\u7ea7\uff1b\u6700\u540e\uff0c\u6587\u7ae0\u901a\u8fc7\u4e30\u5bcc\u7684\u56fe\u793a\u548c\u4ee3\u7801\u793a\u4f8b\uff0c\u4f7f\u8bfb\u8005\u53ef\u4ee5\u66f4\u597d\u5730\u7406\u89e3\u5e76\u8fd0\u7528\u8fd9\u4e00\u5de5\u5177\u3002\u8fd9\u7bc7\u6587\u7ae0\u5bf9\u4e8e\u7406\u89e3\u548c\u8fd0\u7528OpenFeign\u975e\u5e38\u6709\u5e2e\u52a9\uff0c\u65e0\u8bba\u662f\u5bf9\u4e8e\u521d\u5b66\u8005\u8fd8\u662f\u6709\u7ecf\u9a8c\u7684\u5f00\u53d1\u8005\u3002\\n\\n[\u300a\u4e09\u4e07\u5b57\u957f\u6587\uff1a\u5982\u4f55\u53bb\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u300b](https://mp.weixin.qq.com/s/1Qe29y3nrbi39Kpaspme7Q)\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4efd\u8be6\u5c3d\u7684\u6307\u5bfc\uff0c\u8bb2\u8ff0\u4e86\u5982\u4f55\u6392\u67e5JVM\u5185\u5b58\u95ee\u9898\u3002\u6587\u4e2d\u9996\u5148\u5b9a\u4f4d\u4e86\u6280\u672f\u95ee\u9898\u7684\u8303\u56f4\uff0c\u786e\u5b9a\u9002\u7528\u4e8eJDK8\u81f3JDK11\u3002\u63a5\u7740\uff0c\u4f5c\u8005\u63d0\u51fa\u4e86\u7cfb\u7edf\u5316\u7684\u6392\u67e5\u539f\u5219\uff0c\u5e76\u63d0\u4f9b\u4e86\u4e00\u6b65\u6b65\u7684\u8bca\u65ad\u6d41\u7a0b\uff0c\u4ece\u57fa\u672c\u4fe1\u606f\u6536\u96c6\u3001\u5224\u65ad\u5185\u5b58\u589e\u957f\u539f\u56e0\uff0c\u5230\u5177\u4f53\u5206\u6790\u5185\u5b58\u95ee\u9898\u7684\u53ef\u80fd\u6765\u6e90\u3002\u6587\u7ae0\u8be6\u7ec6\u4ecb\u7ecd\u4e86\u5982\u4f55\u5229\u7528\u4e0d\u540c\u7684\u547d\u4ee4\u548c\u5de5\u5177\uff08\u5982jmap\u3001jstat\u3001Arthas\u7b49\uff09\u8fdb\u884c\u8be6\u7ec6\u7684\u5206\u6790\uff0c\u5e76\u6839\u636e\u5185\u5b58\u4f7f\u7528\u60c5\u51b5\uff0c\u5411\u8bfb\u8005\u5c55\u793a\u4e86\u5982\u4f55\u786e\u5b9a\u662f\u5806\u5185\u5b58\u95ee\u9898\u8fd8\u662f\u5806\u5916\u5185\u5b58\u95ee\u9898\u3002\u603b\u4e4b\uff0c\u6587\u7ae0\u4e3a\u90a3\u4e9b\u9700\u8981\u6df1\u5165\u7406\u89e3\u548c\u5904\u7406JVM\u5185\u5b58\u95ee\u9898\u7684\u5f00\u53d1\u8005\u548c\u8fd0\u7ef4\u4eba\u5458\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u77e5\u8bc6\u548c\u6280\u5de7\u3002\\n\\n[\u300a\u5982\u4f55\u907f\u514dMYSQL\u4e3b\u4ece\u5ef6\u8fdf\u5e26\u6765\u7684\u8bfb\u5199\u95ee\u9898\u300b](https://mp.weixin.qq.com/s/WLPo8s_M3AzxwB3o3ehY3w)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8ba8\u8bba\u4e86\u5982\u4f55\u5904\u7406\u5728MySQL\u4e3b\u4ece\u90e8\u7f72\u67b6\u6784\u4e2d\u666e\u904d\u5b58\u5728\u7684\u4e3b\u4ece\u540c\u6b65\u5ef6\u8fdf\u95ee\u9898\uff0c\u4ee5\u4fdd\u6301\u8bfb\u5199\u64cd\u4f5c\u7684\u4e00\u81f4\u6027\u3002\u6587\u7ae0\u9996\u5148\u4ecb\u7ecd\u4e86\u4e3b\u4ece\u5ef6\u8fdf\u4ea7\u751f\u7684\u573a\u666f\u53ca\u5176\u5bf9\u8bfb\u5199\u5206\u79bb\u539f\u5219\u7684\u5f71\u54cd\u3002\u7136\u540e\uff0c\u8be6\u7ec6\u89e3\u91ca\u4e86\u4e3b\u4ece\u590d\u5236\u7684\u539f\u7406\uff0c\u5e76\u63d0\u51fa\u4e86\u4e24\u79cd\u907f\u514d\u4e3b\u4ece\u6570\u636e\u4e0d\u4e00\u81f4\u7684\u6280\u672f\u65b9\u6848\uff1a\u4e00\u662f\u4f7f\u7528select master_pos_wait\u51fd\u6570\u6765\u7b49\u5f85\u4ece\u5e93\u540c\u6b65\u81f3\u7279\u5b9a\u7684binlog\u4f4d\u7f6e\u70b9\uff1b\u4e8c\u662f\u5728\u5f00\u542fGTID\u6a21\u5f0f\u7684\u60c5\u51b5\u4e0b\uff0c\u901a\u8fc7select wait_for_executed_gtid_set\u51fd\u6570\u68c0\u67e5GTID\u96c6\u5408\u662f\u5426\u5df2\u540c\u6b65\u3002\u8fd9\u4e24\u79cd\u65b9\u6cd5\u5747\u65e8\u5728\u786e\u4fdd\u4ece\u5e93\u6570\u636e\u7684\u51c6\u786e\u6027\uff0c\u4ece\u800c\u6574\u4f53\u4e0a\u51cf\u8f7b\u4e3b\u5e93\u7684\u538b\u529b\u3002\u603b\u4f53\u4e0a\uff0c\u6587\u7ae0\u4e3aMySQL\u6570\u636e\u5e93\u7ba1\u7406\u5458\u63d0\u4f9b\u4e86\u7f13\u89e3\u4e3b\u4ece\u5ef6\u8fdf\u5bfc\u81f4\u7684\u8bfb\u5199\u95ee\u9898\u7684\u5177\u4f53\u5b9e\u65bd\u65b9\u6848\u3002\\n\\n[\u300a\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014ES\u7bc7\u300b](https://mp.weixin.qq.com/s/dt_14etV_2ynAmyMa_uyug)\u3002\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u7bc7\u9488\u5bf9Elasticsearch(ES)\u7684\u9762\u8bd5\u6307\u5357\uff0c\u5b83\u6db5\u76d6ES\u57fa\u7840\u77e5\u8bc6\u70b9\u548c\u9762\u8bd5\u8fc7\u7a0b\u4e2d\u5e38\u89c1\u95ee\u9898\u3002\u5185\u5bb9\u5305\u62ecES\u7684\u529f\u80fd\u7279\u6027\u4ecb\u7ecd\uff08\u5982\u5206\u5e03\u5f0f\u67b6\u6784\u3001\u5168\u6587\u641c\u7d22\u3001\u6570\u636e\u5206\u6790\u7b49\uff09\u3001\u4e3b\u8981\u7684\u4f7f\u7528\u573a\u666f\u63cf\u8ff0\u3001\u4e0e\u5176\u4ed6\u641c\u7d22\u5f15\u64ce\u7684\u5bf9\u6bd4\uff08Lucene\u548cSolr\uff09\u3001\u4ee5\u53caES\u7684\u57fa\u672c\u6982\u5ff5\u89e3\u91ca\u3002\u6587\u7ae0\u8fd8\u8be6\u7ec6\u63a2\u8ba8\u4e86ES\u7684\u9ad8\u7ea7\u7279\u6027\uff0c\u5982\u6620\u5c04\u3001DSL\u67e5\u8be2\u3001\u805a\u5408\u5206\u6790\u548c\u667a\u80fd\u641c\u7d22\u5efa\u8bae\u5668\u3002\u6b64\u5916\uff0c\u4f5c\u8005\u8fd8\u5206\u4eab\u4e86\u5173\u4e8e\u6570\u636e\u7d22\u5f15\u4f18\u5316\u7684\u5b9e\u6218\u6280\u5de7\u548c\u7b56\u7565\uff0c\u63d0\u4f9b\u4e86\u5199\u4f18\u5316\u3001\u8bfb\u4f18\u5316\u548c\u7d22\u5f15\u91cd\u5efa\u7684\u65b9\u6848\uff0c\u8fd9\u4e9b\u65b9\u6848\u5bf9ES\u6570\u636e\u5b58\u50a8\u548c\u67e5\u8be2\u7684\u6027\u80fd\u6709\u663e\u8457\u5f71\u54cd\uff0c\u6700\u540e\u8fd8\u5bf9Deep Paging\u6027\u80fd\u95ee\u9898\u63d0\u4f9b\u4e86\u89e3\u51b3\u65b9\u6cd5\u3002\u5bf9\u6b63\u5728\u51c6\u5907\u9762\u8bd5\u6216\u8005\u5e0c\u671b\u5de9\u56faES\u77e5\u8bc6\u7684\u8bfb\u8005\u800c\u8a00\uff0c\u8fd9\u7bc7\u6587\u7ae0\u662f\u4e00\u4e2a\u5b9d\u8d35\u7684\u8d44\u6e90\u3002\\n\\n[\u300a\u4ec0\u4e48\u662fMySQL\u9501\uff1f\u6709\u54ea\u4e9b\u9501\u7c7b\u578b\u300b](https://mp.weixin.qq.com/s/gAJFm3q5510PfRBe4F11PQ)\u3002\u8fd9\u7bc7\u6587\u7ae0\u8be6\u7ec6\u5730\u4ecb\u7ecd\u4e86MySQL\u4e2d\u7684\u9501\u5b9a\u673a\u5236\u53ca\u5176\u7c7b\u578b\u3002\u8d77\u521d\u6982\u8ff0\u4e86\u9501\u7684\u4f5c\u7528\uff0c\u5373\u534f\u8c03\u591a\u8fdb\u7a0b\u6216\u7ebf\u7a0b\u5bf9\u8d44\u6e90\u7684\u5e76\u53d1\u8bbf\u95ee\uff0c\u5728\u6570\u636e\u5e93\u73af\u5883\u4e0b\uff0c\u9501\u5bf9\u4e8e\u4fdd\u6301\u4e8b\u52a1\u7684\u6b63\u786e\u6027\u4e0e\u4e00\u81f4\u6027\u81f3\u5173\u91cd\u8981\u3002\u4f5c\u8005\u660e\u786e\u533a\u5206\u4e86MySQL\u4e2d\u9501\u7684\u7ea7\u522b\uff0c\u4ece\u5168\u5c40\u9501\u3001\u8868\u9501\uff08\u8bfb\u9501\u3001\u5199\u9501\uff09\u5230\u5143\u6570\u636e\u9501\u3001\u610f\u5411\u9501\uff0c\u76f4\u5230\u884c\u9501\u7684\u591a\u79cd\u5f62\u5f0f\uff08\u8bb0\u5f55\u9501\u3001\u95f4\u9699\u9501\u548c\u4e34\u952e\u9501\uff09\u3002\u6587\u4e2d\u8fd8\u63a2\u8ba8\u4e86AUTO-INC\u9501\u7684\u4f5c\u7528\u548c\u76f8\u5173\u4f18\u5316\uff0c\u4e3e\u4f8b\u8bf4\u660e\u4e86\u5176\u5728INSERT\u64cd\u4f5c\u4e2d\u7684\u5e94\u7528\u3002\u6b64\u5916\uff0c\u6587\u7ae0\u4e5f\u6d89\u53ca\u4e86\u5982\u4f55\u6839\u636e\u4e0d\u540c\u7684\u60c5\u51b5\u4f18\u5316\u9501\u7684\u4f7f\u7528\u4ee5\u53ca\u5982\u4f55\u907f\u514d\u7531\u9501\u4ea7\u751f\u7684\u6027\u80fd\u74f6\u9888\u3002\u8fd9\u7bc7\u6587\u7ae0\u4e3a\u7406\u89e3MySQL\u7684\u5404\u79cd\u9501\u7c7b\u578b\u548c\u9501\u673a\u5236\u63d0\u4f9b\u4e86\u5b9d\u8d35\u7684\u4fe1\u606f\uff0c\u7279\u522b\u5bf9\u4e8e\u6570\u636e\u5e93\u7ba1\u7406\u5458\u548c\u90a3\u4e9b\u9700\u8981\u7ba1\u7406\u5e76\u53d1\u6570\u636e\u8bbf\u95ee\u95ee\u9898\u7684\u5f00\u53d1\u4eba\u5458\u6765\u8bf4\uff0c\u5177\u6709\u5f88\u9ad8\u7684\u5b9e\u7528\u4ef7\u503c\u3002\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[Vue \u56e2\u961f\u6b63\u5f0f\u5f00\u6e90 Rolldown\uff1a\u57fa\u4e8e Rust \u7684\u8d85\u5feb JavaScrip \u6253\u5305\u5de5\u5177\uff01](https://mp.weixin.qq.com/s/m-Ae6dbFuW22u2xSDWcciw)\\n\\n[\u6253\u9020\u8212\u9002\u7684vscode\u5f00\u53d1\u73af\u5883](https://mp.weixin.qq.com/s/MVR5rV2LkH8_GHCtP6SHug)\\n\\n[\u76f8\u6bd4\u4e8e Node.js\uff0cDeno \u548c Bun \u5230\u5e95\u80fd\u5e26\u6765\u4ec0\u4e48](https://mp.weixin.qq.com/s/pY4-RqqamTmPXnRPfw0hRA)\\n\\n[MDH Weekly 122 - \u300a\u62db\u4eba\u300b](https://mp.weixin.qq.com/s/yBTK4Rds28aJ88mVgkoYJA)"},{"id":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-03-03/index.md","source":"@site/blogs/2024/2024-03-03/index.md","title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-03-03T00:00:00.000Z","formattedDate":"March 3, 2024","tags":[],"readingTime":3.63,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1a\u7528 switch-case \u6765\u89e3\u51b3 Go \u9519\u8bef\u5904\u7406\u7684\u96be\u9898\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[LangChain \u5b9e\u6218\uff1aAgent\u601d\u7ef4](https://mp.weixin.qq.com/s/II_6lb9KjKOmz-DIgnaz7g)\\n\\n[\u8be6\u89e3\u5927\u6a21\u578bRLHF\u8fc7\u7a0b\uff08\u914d\u4ee3\u7801\u89e3\u8bfb\uff09](https://mp.weixin.qq.com/s/tl32MrTPMi0i7BN53ELb2w)\\n\\n[PromptFlow\u9ad8\u8d28\u91cfAI\u5e94\u7528 - \u57fa\u4e8eLLM\u7684\u6587\u6863QA\u673a\u5668\u4eba](https://mp.weixin.qq.com/s/J8yEbS-XTJY0aFyJAl1ypA)\\n\\n[\u56fe\u89e3\u5927\u6a21\u578b\u8ba1\u7b97\u52a0\u901f\u7cfb\u5217\uff1aFlash Attention V1\uff0c\u4ece\u786c\u4ef6\u5230\u8ba1\u7b97\u903b\u8f91](https://mp.weixin.qq.com/s/gPVwXysJsV2S2FgP3c6Qpw)\\n\\n[\u4f7f\u7528\u642d\u8f7d\u9a81\u9f99 8 Gen 3 \u7684\u5b89\u5353\u624b\u673a\u8fd0\u884c AI \u5927\u6a21\u578b](https://mp.weixin.qq.com/s/yfou0pEkbbUZxe2NS1jnag)\\n\\n[\u751f\u6210\u5f0f AI \u7684\u53d1\u5c55\u65b9\u5411\uff0c\u662f Chat \u8fd8\u662f Agent](https://mp.weixin.qq.com/s/ws3U1NBouPivqatUb_ldQA)\\n\\n[\u804a\u804a\u5927\u6a21\u578bAgent\u6280\u672f\uff0c\u53ca\u548c\u5177\u8eab\u667a\u80fd\u53c8\u6709\u4ec0\u4e48\u5f02\u540c](https://mp.weixin.qq.com/s/U1IqQElxkfHfQoxygMnSOg)\\n\\n[\u590d\u65e6NLP\u56e2\u961f\u53d1\u5e0380\u9875\u5927\u6a21\u578bAgent\u7efc\u8ff0\uff0c\u4e00\u6587\u7eb5\u89c8AI\u667a\u80fd\u4f53\u7684\u73b0\u72b6\u4e0e\u672a\u6765](https://mp.weixin.qq.com/s/eWlms4IxTd4wzka4V7Gu6w)\\n\\n[\u77e5\u8bc6\u95ee\u7b54\u7cfb\u7edf\u7684\u4f18\u5316\u5b9e\u8df5\uff1aLLM\u4e0eRAG\u7684\u7ed3\u5408\u827a\u672f](https://mp.weixin.qq.com/s/cZB90npCcz88IJ6W00LnMA)\\n\\n[\u4e00\u6587\u89e3\u6784\u5927\u6a21\u578bRAG\u95ee\u7b54\u5173\u952e\u73af\u8282\u53ca\u4e0eLLM\u5fae\u8c03\u5bf9\u6bd4\u603b\u7ed3](https://mp.weixin.qq.com/s/xxFcMRMl--HPcGAkAYaW7w)\\n\\n[Mistral AI\u53d1\u5e03Mistral Large\u6a21\u578b](https://mp.weixin.qq.com/s/K0yFNjpcBk5OL-1DRHSeGA)\\n\\n[Mistral AI\u65b0\u6a21\u578b\u5bf9\u6807GPT-4\uff0c\u4e0d\u5f00\u6e90\u4e14\u4e0e\u5fae\u8f6f\u5408\u4f5c\uff0c\u7f51\u53cb\uff1a\u5fd8\u4e86\u521d\u5fc3](https://mp.weixin.qq.com/s/rvIJLIEvvzQ5n8v7ZF6pWw)\\n\\n[\u5927\u6a21\u578b\u5fae\u8c03\u65b0\u8303\u5f0f\uff1a\u5f53LoRA\u9047\u89c1MoE](https://mp.weixin.qq.com/s/gTFVNbWRsxONnoE_fq2S3A)\\n\\n[Mistral Large\uff0cLe Chat\u6765\u4e86\uff01Mistral AI\u8fde\u653e\u4e24\u4e2a\u5927\u62db\uff01](https://mp.weixin.qq.com/s/P5XktjiRgY2Q6V1pLyqYAw)\\n\\n[\u63a2\u7d222024\u5e741\u6708\u7684AI\u7814\u7a76\u524d\u6cbf\uff1a\u6a21\u578b\u5408\u5e76\u3001\u4e13\u5bb6\u6df7\u5408\u4e0e\u5c0f\u578bLLM\u7684\u5d1b\u8d77](https://mp.weixin.qq.com/s/1zc4klUCCsgeFDaA5K2Rgg)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[Cargo\u7684\u81ea\u5b9a\u4e49\u547d\u4ee4\u6269\u5c55\u529f\u80fd](https://mp.weixin.qq.com/s/PCFDz_fVsk_6M144VpBAww)\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(2)](https://mp.weixin.qq.com/s/CXnLIoYhI1k3SNP3IWz8dQ)\\n\\n[\u5143\u8001\u4e0e\u65b0\u79c0\uff1aGo sort.Search()\u548csort.Find()](https://mp.weixin.qq.com/s/vg8MfMBEs8I-FQl3Nuay6Q)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(6)-Connector](https://mp.weixin.qq.com/s/oM8JS_eMQjeU2tJzfO7f5w)\\n\\n[\u8df3\u69fd\u5fc5\u770b\u306eMySQL\u7d22\u5f15\uff1aB+\u6811\u539f\u7406\u63ed\u79d8\u4e0e\u7d22\u5f15\u4f18\u7f3a\u70b9\u5206\u6790](https://mp.weixin.qq.com/s/1DuY0WXZ_GsG87Ahuk_9rw)\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--compiler(1)](https://mp.weixin.qq.com/s/QfE-dnHlIv49ae205RrJ_Q)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(5)](https://mp.weixin.qq.com/s/xVBT-E3IiYsiOtHF2V22Xw)\\n\\n[\u7528 switch-case \u6765\u89e3\u51b3 Go \u9519\u8bef\u5904\u7406\u7684\u96be\u9898](https://mp.weixin.qq.com/s/MkWxrN_kQFNn9rMeJXs3PA)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(4)](https://mp.weixin.qq.com/s/7C7Jxe7XEN-vQKiY2MJMtw)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(3)](https://mp.weixin.qq.com/s/SHLh2ofDUteQCafXZo8mmw)\\n\\n[\u56fe\u6587\u8bb2\u900fGolang\u6807\u51c6\u5e93 net/http\u5b9e\u73b0\u539f\u7406 -- \u5ba2\u6237\u7aef](https://mp.weixin.qq.com/s/WoUYmpvYH6ixYSDwFga59g)\\n\\n[\u4f7f\u7528docker init\u7f16\u5199Dockerfile\u548cdocker-compose\u914d\u7f6e](https://mp.weixin.qq.com/s/TqAQ9kP4HlFN9UdLq0tavQ)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#\u5b8c\u7ed3\u6492\u82b1](https://mp.weixin.qq.com/s/tqAcoskLYd2UV6B_6AeIjw)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(2)](https://mp.weixin.qq.com/s/9Pg8blMjqECaCY_W9MbYHg)\\n\\n[golang \u9ad8\u6027\u80fd\u65e0 GC \u7684\u7f13\u5b58\u5e93 bigcache \u662f\u600e\u4e48\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/4ufuA3n9aaFcQ9zDItUHaQ)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u4ece0\u52301\u6784\u5efa\u4e00\u4e2a\u7a33\u5b9a\u3001\u9ad8\u6027\u80fdRedis\u96c6\u7fa4](https://mp.weixin.qq.com/s/5BwWCekb_wIu6LrCdmoGCQ)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014SpringCloud\u7bc7](https://mp.weixin.qq.com/s/KetCuZNb9jR0HSY7Jqh0NA)\\n\\n[\u5982\u4f55\u8bbe\u8ba1\u8ba2\u5355\u8d85\u65f6\u81ea\u52a8\u53d6\u6d88](https://mp.weixin.qq.com/s/hCZanLARApXcW2_6r3g-5A)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[2024 AI & \u524d\u7aef\uff1a\u56de\u9996\u5c55\u671b\uff0c\u5149\u8292\u672a\u81f3\uff0c\u7834\u6653\u4e4b\u524d\uff01](https://mp.weixin.qq.com/s/H9_kt3L6l6fj0aBP9UonhA)\\n\\n[\u770b\u5b8czustand\u6e90\u7801\u540e\uff0c\u6211\u7684TypeScript\u6c34\u5e73\u7a81\u98de\u731b\u8fdb](https://mp.weixin.qq.com/s/kZOpaaIfogWzeB7KwdTkRw)\\n\\n[ElTable \u4e8c\u6b21\u5c01\u88c5\uff1a\u6211\u7528 Vue3.3 \u65b0\u7279\u6027\u5b8c\u7f8e\u89e3\u51b3\u4e86\u5217\u63d2\u69fd\u6570\u636e\u65e0\u7c7b\u578b\u63d0\u793a\u95ee\u9898\uff01\uff01\uff01](https://mp.weixin.qq.com/s/Q1vvgM_A7QEtO-0a3GLUsw)\\n\\n[ECharts \u8fce\u6765\u91cd\u5927\u66f4\u65b0\uff0c\u8fd0\u884c\u65f6\u5305\u4f53\u79ef\u53ef\u51cf\u5c11 98%\uff01](https://mp.weixin.qq.com/s/WgtUG0vp3fk0_388svrGXg)\\n\\n[FFmpeg\u524d\u7aef\u89c6\u9891\u5408\u6210\u5b9e\u8df5](https://mp.weixin.qq.com/s/1XmH55nqs7wavsWJNT-tSw)\\n\\n[2024 \u4f7f\u7528 TS \u642d\u5efa Node.js \u670d\u52a1\u5668 - \u5feb\u901f\u6559\u7a0b](https://mp.weixin.qq.com/s/8D6yD3A5-KPod85zsxRPZQ)\\n\\n[\u524d\u7aef\u98df\u5802\u6280\u672f\u5468\u520a\u7b2c 113 \u671f\uff1aNode \u5e74\u7ec8\u603b\u7ed3\u3001Node \u65b0\u5409\u7965\u7269\u3001Qwik 2.0\u3001React Labs \u5de5\u4f5c\u8fdb\u5c55](https://mp.weixin.qq.com/s/udt61U0aaoFJqnzFKhGTjw)"},{"id":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-25/index.md","source":"@site/blogs/2024/2024-02-25/index.md","title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-02-25T00:00:00.000Z","formattedDate":"February 25, 2024","tags":[],"readingTime":5.4,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[Large Language Models for Data Annotation: A Survey](https://arxiv.org/pdf/2402.13446)\\n\\n[ACTIVERAG: Revealing the Treasures of Knowledge via Active Learning](https://arxiv.org/pdf/2402.13547.pdf)\\n\\n[\u5173\u4e8eGenerative-Diffusion-Model\u7684\u5168\u9762\u7efc\u8ff0\uff0c\u53ef\u4ee5\u4f5c\u4e3a\u4e86\u89e3sora\u7684\u57fa\u7840\u77e5\u8bc6](https://arxiv.org/pdf/2209.02646.pdf\uff0chttps://github.com/chq1155/A-Survey-on-Generative-Diffusion-Model?tab=readme-ov-file)\\n\\n[\u4e91\u97f3\u4e50 CMS \u5e73\u53f0 AIGC \u5b9e\u8df5\u4e0e\u65b0\u7279\u6027\u5b9e\u73b0\u603b\u7ed3](https://mp.weixin.qq.com/s/f2A6r5dVSBwDO_h27dlj6A)\\n\\n[\u4e91\u97f3\u4e50D2C\u8bbe\u8ba1\u7a3f\u8f6c\u4ee3\u7801\u5efa\u8bbe\u5b9e\u8df5](https://mp.weixin.qq.com/s/Oc1f3thZYIONsF4OWWEcSw)\\n\\n[\u4e91\u97f3\u4e50 AI Agent \u63a2\u7d22\u5b9e\u8df5](https://mp.weixin.qq.com/s/2O5z9rAvLxU3ZsU7k4xdhA)\\n\\n[\u4e91\u97f3\u4e50\u4f4e\u4ee3\u7801 + ChatGPT \u5b9e\u8df5\u65b9\u6848\u4e0e\u601d\u8003](https://mp.weixin.qq.com/s/jaIiVI636uJBOOKsXuHCpw)\\n\\n[\ud83e\udd9c\ud83d\udd78\ufe0f LangGraph\uff1aPlan-Execute Agents \u5b9e\u6218](https://www.bilibili.com/video/BV1vJ4m1s7Zn)\\n\\n[Pinecone\u603b\u7ed3\u4e00\uff1a\u5927\u6a21\u578b\u89d2\u5ea6](https://mp.weixin.qq.com/s/G1DYQiAjUL9zphJ8ajrrtg)\\n\\n[\u4f7f\u7528 Hugging Face \u5fae\u8c03 Gemma \u6a21\u578b](https://mp.weixin.qq.com/s/N6RI456ouuczWjyqXOSPNQ)\\n\\n[\u5f00\u6e90\u5927\u8bed\u8a00\u6a21\u578b\u4f5c\u4e3a LangChain \u667a\u80fd\u4f53](https://mp.weixin.qq.com/s/fsvgtS3stS1cfrIT78XBCA)\\n\\n[200\u4e07\u4e0a\u4e0b\u6587\u7a97\u53e3\u521b\u98deGemini 1.5\uff01\u5fae\u8f6f\u6765\u7838\u8c37\u6b4c\u573a\u5b50\u4e86\uff08doge\uff09](https://mp.weixin.qq.com/s/tJj0ZCX8fRS2Xcr0v85C8g)\\n\\n[\u5982\u4f55\u5229\u7528\u5927\u6a21\u578b\u8fdb\u884c\u6570\u636e\u6807\u6ce8\u4e0e\u77e5\u8bc6\u84b8\u998f\uff1a\u517c\u770bActiveRAG\u4e0a\u4e0b\u6587\u53bb\u566a\u7684\u5927\u6a21\u578bRAG\u95ee\u7b54\u8303\u5f0f](https://mp.weixin.qq.com/s/idr60a1a66gdGFSZrOnC0w)\\n\\n[\u6811\u5f62\u7ed3\u6784\u4e0eRAG\u7684\u5b8c\u7f8e\u7ed3\u5408\uff1aT-RAG\u65b9\u6cd5\u5728\u7ec4\u7ec7\u5185\u90e8\u4fe1\u606f\u67e5\u8be2\u4e2d\u7684\u7a81\u7834](https://mp.weixin.qq.com/s/NNkVs_TnaStvjWdmfrM88Q)\\n\\n[\u9886\u514899%\u5c0f\u767d\u7684Sora\u5173\u952e\u4fe1\u606f\uff01](https://mp.weixin.qq.com/s/MsaCUnTsJYxJFgnNGT6DTA)\\n\\n[AI, Machine Learning\u548c Deep Learning\u6709\u4ec0\u4e48\u5dee\u5f02](https://mp.weixin.qq.com/s/Js9YAibVSeVwfy4-xESDRg)\\n\\n[\u6a21\u578b\u878d\u5408\u3001\u6df7\u5408\u4e13\u5bb6\u3001\u66f4\u5c0f\u7684LLM\uff0c\u51e0\u7bc7\u8bba\u6587\u770b\u61c22024\u5e74LLM\u53d1\u5c55\u65b9\u5411](https://mp.weixin.qq.com/s/qImKOQXLoZqLTW-SVISKHA)\\n\\n[\u5f00\u6e90\u5927\u6a21\u578b\u738b\u5ea7\u6613\u4e3b\uff01\u8c37\u6b4cGemma\u6740\u5165\u573a\uff0c\u7b14\u8bb0\u672c\u53ef\u8dd1\uff0c\u53ef\u5546\u7528](https://mp.weixin.qq.com/s/_iCYfqmXA3enKn3Hm-DwSA)\\n\\n[\u5173\u4e8eGoogle\u5f00\u6e90Gemma\u7684\u4e00\u4e9b\u60f3\u6cd5](https://mp.weixin.qq.com/s/H2ie4vuhLqr4UKtgvZZtEQ)\\n\\n[LangChain\u539f\u7406\u5b66\u4e60\u7b14\u8bb0](https://mp.weixin.qq.com/s/0xzCAqiXOsscBItpN9R0lA)\\n\\n[\u5de5\u5177\u589e\u5f3a\u578b\u5927\u6a21\u578b\uff1a\u5f15\u9886\u667a\u80fd\u65b0\u65f6\u4ee3](https://mp.weixin.qq.com/s/gHyMnVxh-QVe58TvZMvl8Q)\\n\\n[AI \u5b9e\u6218\uff1a\u624b\u628a\u624b\u6559\u4f60\u4f7f\u7528\u300c\u6263\u5b50/coze\u300d\u6765\u642d\u5efa\u4e2a\u4ebablog\u77e5\u8bc6\u5e93](https://mp.weixin.qq.com/s/YAGfwy5fUHbTW5f3bUSYVg)\\n\\n[\u5927\u6a21\u578b\u63a8\u7406\u4f18\u5316\u5b9e\u8df5\uff1aKV cache\u590d\u7528\u4e0e\u6295\u673a\u91c7\u6837](https://mp.weixin.qq.com/s/W9iVW7niyi_HvEWxOcnwuA)\\n\\n[NLP\u7814\u7a76\u5728\u5927\u6a21\u578b\u65f6\u4ee3\u7684\u521b\u65b0\u98de\u8dc3](https://mp.weixin.qq.com/s/06w7_lb8Hc4Ee2GG9I4wLg)\\n\\n[\u4e0b\u4e00\u4ee3RAG\u8303\u5f0f\uff1aRAG-Fusion](https://mp.weixin.qq.com/s/delaJc2KDxLWfUUtGo-V-A)\\n\\n[\u56fe\u89e3\u5927\u6a21\u578b\u8ba1\u7b97\u52a0\u901f\u7cfb\u5217\uff1aFlash Attention V2\uff0c\u4ece\u539f\u7406\u5230\u5e76\u884c\u8ba1\u7b97](https://mp.weixin.qq.com/s/5K6yNj23NmNLcAQofHcT4Q)\\n\\n[\u5982\u4f55\u5728\u5c0f\u516c\u53f8\u505a\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/yr_VAbEIresEH352Iyehjg)\\n\\n[\u673a\u5668\u5b66\u4e60\u7b80\u4ecb: \u5bfb\u627e\u51fd\u6570\u7684\u827a\u672f](https://mp.weixin.qq.com/s/j52XdHyD5w_Ug-hpWlPIgQ)\\n\\n[OpenAl \u89c6\u9891\u751f\u6210\u6a21\u578b \u2014\u2014 Sora\u6280\u672f\u62a5\u544a\u89e3\u8bfb](https://mp.weixin.qq.com/s/3reFjJNHuL8J24EyLmsSPA)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[etcd\u5b58\u50a8\u5f15\u64ce\u4e4b\u4e3b\u5e72\u6846\u67b6](https://mp.weixin.qq.com/s/oL_G8H_ROSF3TjtzBOGCow)\\n\\n[Rust \u9ad8\u6027\u80fd\u7f16\u7a0b\u6307\u5357](https://mp.weixin.qq.com/s/5PovYOUzHFcCU2JjDLEnnA)\\n\\n[Go map \u52a0\u6709\u5e8f\u6392\u5e8f\u7684\u4e00\u4e9b\u6323\u624e](https://mp.weixin.qq.com/s/n0v8Xtz1q9XRvZuI4tPoXg)\\n\\n[\u4e91\u97f3\u4e50 GitOps \u6700\u4f73\u5b9e\u8df5](https://mp.weixin.qq.com/s/uYmSCyTZtbSpiIL6Qet5_A)\\n\\n[KisFlow-\u57fa\u4e8eGolang\u7684\u6d41\u5f0f\u8ba1\u7b97\u6846\u67b6\u5b9e\u6218(1)](https://mp.weixin.qq.com/s/UNr11UvRX9kzKefKttX4wg)\\n\\n[\u76f8\u540c\u578b\u53f7\u7269\u7406\u673a\uff0c\u5bb9\u5668\u6027\u80fd\u4e0d\u5982\u865a\u62df\u673a](https://mp.weixin.qq.com/s/-oQITzwDo51TkUyzUs0BQQ)\\n\\n[\u542cGPT \u8bb2Rust\u6e90\u4ee3\u7801--library/portable-simd](https://mp.weixin.qq.com/s/-zgXvXuUlqywbEPUygmv7w)\\n\\n[Go deadcode\uff1a\u67e5\u627e\u6ca1\u610f\u4e49\u7684\u6b7b\u4ee3\u7801\uff0c\u5bf9\u4e8e\u7ef4\u62a4\u9879\u76ee\u633a\u6709\u7528\uff01](https://mp.weixin.qq.com/s/r-HbSxbvrpIltUdCXCEzSw)\\n\\n[\u901a\u4fd7\u6613\u61c2\u5256\u6790Go Channel\uff1a\u7406\u89e3\u5e76\u53d1\u901a\u4fe1\u7684\u6838\u5fc3\u673a\u5236](https://mp.weixin.qq.com/s/Be6VYGlSa-AXcDkuhCQ1HA)\\n\\n[\u7adf\u7136\u662f\\"\u4f60\\"\u5077\u8d70\u4e86\u90a30.001\u7684\u670d\u52a1\u53ef\u7528\u6027](https://mp.weixin.qq.com/s/-C-wIjkKM7N1M7fcCd7HSQ)\\n\\n[\u7cbe\u5fc3\u8bbe\u8ba1\u7684 DNS Failover \u7b56\u7565\u5728 Go \u4e2d\u7adf\u7136\u5e26\u6765\u4e86\u53cd\u6548\u679c\uff0c\u53d1\u751f\u4e86\u4ec0\u4e48](https://mp.weixin.qq.com/s/BqNLR9rsWSPtTJpzOX1uOw)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#100 Not understanding the impacts of running Go](https://mp.weixin.qq.com/s/Sx2Bo_KUVh2w6twwb_XBVA)\\n\\n[\u300a\u4ece\u6162\u901f\u5230SIMD\u300b\u804aGo \u8fb9\u754c\u68c0\u67e5\u6d88\u9664](https://mp.weixin.qq.com/s/2AWWhbkEhwTJcgCjL-9pcQ)\\n\\n[Go\u9879\u76ee\u4e2d\u7684Labels](https://mp.weixin.qq.com/s/fmlzQfwmIwMgP38op0Ebmg)\\n\\n[Go \u66f4\u5f3a\u7684\u4ee3\u7801\u6d01\u7656\uff0c\u53ef\u4ee5\u628a gofmt \u7ed9\u6362\u4e86\uff01](https://mp.weixin.qq.com/s/dnF3bxT0H_OfAsml9m976w)\\n\\n[Go \u7ec8\u4e8e\u628a\u8fd9\u4e2a\u50bb\u7f3a\u7279\u6027\u53bb\u6389\u4e86\uff0c\u591a\u5c11\u9648\u5e74\u8001BUG\u90fd\u662f\u56e0\u4e3a\u5b83\uff01](https://mp.weixin.qq.com/s/b1cLEth3cgQsTmMCgw9Bog)\\n\\n[Go 1.22 slices \u5e93\u7684\u66f4\u65b0\uff1a\u9ad8\u6548\u62fc\u63a5\u3001\u96f6\u5316\u5904\u7406\u548c\u8d8a\u754c\u63d2\u5165\u4f18\u5316](https://mp.weixin.qq.com/s/10cPBDKOuSuyW1XTUxuqiw)\\n\\n[Go 1.22\u4e2d\u503c\u5f97\u5173\u6ce8\u7684\u51e0\u4e2a\u53d8\u5316](https://mp.weixin.qq.com/s/KUiTxRBQcywcyHsHmOFvEQ)\\n\\n[Go\u4e2d\u6700\u5e38\u7528\u7684\u6570\u636e\u6821\u9a8c\u5e93](https://mp.weixin.qq.com/s/Gp4yLILc2rWQonn2Bg-FTg)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1a\u8bf4\u8bf4OOM\u4e09\u5927\u573a\u666f\u548c\u89e3\u51b3\u65b9\u6848\uff1f \uff08\u7edd\u5bf9\u53f2\u4e0a\u6700\u5168\uff09](https://mp.weixin.qq.com/s/8DT0tNYbuPjXkKwMMUABYg)\\n\\n[(\u4e5d)\u6df1\u5165\u5e76\u53d1\u7f16\u7a0b\u4e4b\u5e76\u53d1\u5bb9\u5668\uff1a\u963b\u585e\u961f\u5217\u3001\u5199\u65f6\u590d\u5236\u5bb9\u5668\u3001\u9501\u5206\u6bb5\u5bb9\u5668\u539f\u7406\u8be6\u8c08](https://mp.weixin.qq.com/s/5RehBI0KwDFzkY5ssuivEQ)\\n\\n[(\u516b)\u6df1\u5165\u5e76\u53d1\u4e4bRunnable\u3001Callable\u3001FutureTask\u53caCompletableFuture\u539f\u7406\u5206\u6790](https://mp.weixin.qq.com/s/BJ9ju3Ov6ZwgpbjoM2SDqA)\\n\\n[\u56db\u5341\u4e94\u56fe\uff0c\u4e00\u4e07\u4e94\u5343\u5b57\uff01\u4e00\u6587\u8ba9\u4f60\u8d70\u51fa\u8ff7\u96fe\u73a9\u8f6cMaven\uff01](https://mp.weixin.qq.com/s/n4OGEkfJ_ql-gifHVaN7ZA)\\n\\n[\u8e29\u4e86\u4e00\u5806\u5751\uff0c\u7ec8\u4e8e\u628a\u5fae\u670d\u52a1\u7cfb\u7edf\u5168\u9762\u5347\u7ea7 JDK17 \u548c SpringBoot3 \u4e86](https://mp.weixin.qq.com/s/iKz_iABnlibNb1fRM3RXmA)\\n\\n[\u5947\u601d\u5999\u60f3\u7684SQL\uff5c\u517c\u987e\u6027\u80fd\u7684\u6570\u636e\u503e\u659c\u5904\u7406\u65b0\u59ff\u52bf](https://mp.weixin.qq.com/s/VGgT1faRKGnUuQ-HHQ3Q5g)\\n\\n[\u5982\u4f55\u6210\u4e3a\u4e00\u7ebf Leader](https://mp.weixin.qq.com/s/3xi9uu5OXVRS0dX1PxW9UA)\\n\\n[ForkJoinPool\uff1a\u5927\u4efb\u52a1\u62c6\u5206\uff0c\u8ba9\u5e76\u884c\u55e8\u8d77\u6765\uff01](https://mp.weixin.qq.com/s/f3yorGDYOFVeLydwkAPvFw)\\n\\n[\u5199\u4e86\u8fd9\u4e48\u591a\u5e74DateUtils\uff0c\u6b8a\u4e0d\u77e5\u4f60\u8fd8\u6709\u8fd9\u4e48\u591a\u5f2f\u5f2f\u7ed5\uff01](https://mp.weixin.qq.com/s/h6Bhgcu7QqV0nMUvOUThsg)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014Kafka\u7bc7](https://mp.weixin.qq.com/s/8UNtMIllJ03ULZwE9WtVdg)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\ud83e\udd2f \\\\[\u6027\u80fd\u4f18\u5316\\\\] \u6d4f\u89c8\u5668\u8de8\u57df\u5e26\u6765\u7684\u4e00\u4e9b\u6027\u80fd\u95ee\u9898](https://mp.weixin.qq.com/s/UXZa0lJfQznseNfRnld1_g)\\n\\n[\ud83e\uddd0 \\\\[\u8de8\u7aef\u5f00\u53d1\\\\] \u5982\u4f55\u5b9a\u4f4d Hybrid Web \u9875\u9762\u4e2d Native \u6ce8\u5165\u7684 JS \u4ee3\u7801](https://mp.weixin.qq.com/s/uIupFpxXkbrKiEkCl_1ZYg)\\n\\n[413 - \u300a\u8bfb\u4e66\u7b14\u8bb0\uff1aA Philosophy of Software Design\u300b](https://sorrycc.com/book-a-philosophy-of-software-design)\\n\\n[\u5982\u4f55\u5728\u6cdb\u578b\u7ec4\u4ef6\u4e2d\u4f7f\u7528 forwardRef](https://www.totaltypescript.com/forwardref-with-generic-components)\\n\\n[\u8bd1\uff1aHot Module Replacement \u539f\u7406](https://sorrycc.com/hot-module-replacement-is-easy)\\n\\n[MDH Weekly 121 - \u300a\u5f00\u5de5\u5927\u5409\u300b](https://mp.weixin.qq.com/s/ga5-g5sOTccc7z1ZCQ29jg)"},{"id":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-18/index.md","source":"@site/blogs/2024/2024-02-18/index.md","title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-02-18T00:00:00.000Z","formattedDate":"February 18, 2024","tags":[],"readingTime":6.41,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1a\u725b\u903c\u4e86\uff012\u6708\u7f16\u7a0b\u8bed\u8a00\u699c\u5355\uff1aGo\u9996\u6b21\u8fdb\u5165\u524d\u5341\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[How to Cut RAG Costs by 80% Using Prompt Compression](https://towardsdatascience.com/how-to-cut-rag-costs-by-80-using-prompt-compression-877a07c6bedb)\\n\\n[RAG vs Fine-tuning: Pipelines, Tradeoffs, and a Case Study on Agriculture](https://arxiv.org/abs/2401.08406)\\n\\n[RAG vs Finetuning \u2014 Which Is the Best Tool to Boost Your LLM Application](https://towardsdatascience.com/rag-vs-finetuning-which-is-the-best-tool-to-boost-your-llm-application-94654b1eaba7)\\n\\n[\u5927\u8bed\u8a00\u6a21\u578b\u4e4bLlaMA\u7cfb\u5217- LlaMA 2\u53caLLaMA2_chat(\u4e0a)](https://mp.weixin.qq.com/s/Nyu46KN0Hj2-r93vXVcbiQ)\\n\\n[RAG\u8fd8\u662f\u5fae\u8c03\uff1f\u5fae\u8f6f\u51fa\u4e86\u4e00\u4efd\u7279\u5b9a\u9886\u57df\u5927\u6a21\u578b\u5e94\u7528\u5efa\u8bbe\u6d41\u7a0b\u6307\u5357](https://mp.weixin.qq.com/s/G8nKz4H3QSKBibSMYAzRvA)\\n\\n[\u8c37\u6b4c\u5168\u65b0\u5927\u6a21\u578b\u7a81\u7136\u53d1\u5e03\uff01100\u4e07token\u5b8c\u7206GPT-4\uff0c\u4ec5\u9760\u63d0\u793a\u8bcd\u5c31\u80fd\u5b66\u4f1a\u65b0\u8bed\u8a00](https://mp.weixin.qq.com/s/FKC7Y-05L9VfukI-3EMvZw)\\n\\n[\u6269\u5c55\u8bf4\u660e: \u6307\u4ee4\u5fae\u8c03 Llama 2](https://mp.weixin.qq.com/s/iIIM3N1-1cE2SxBRdZ-ILg)\\n\\n[\u793e\u533a\u4f9b\u7a3f | \u56fe\u89e3\u5927\u6a21\u578b\u63a8\u7406\u4f18\u5316\u4e4b KV Cache](https://mp.weixin.qq.com/s/6q2LmwoFG2LcN0iHoZjjqw)\\n\\n[\u5927\u6a21\u578b\u6027\u80fd\u4f18\u5316\u4e4bPrompt\u5de5\u7a0b\u5168\u9762\u68b3\u7406\uff1a\u4ecezero shot\u5230chain of thought\u518d\u5230\u82b1\u5f0fXOT](https://mp.weixin.qq.com/s/va1Ua3koedNWKkln4v6Vvg)\\n\\n[\u5927\u6a21\u578bRAG\u95ee\u7b54\u884c\u4e1a\u6700\u4f73\u6848\u4f8b\u53ca\u5fae\u8c03\u3001\u63a8\u7406\u53cc\u9636\u6bb5\u5b9e\u73b0\u6a21\u5f0f\uff1a\u57fa\u4e8e\u6a21\u5757\u5316(Modular)RAG\u81ea\u5b9a\u4e49RAG Flow](https://mp.weixin.qq.com/s/bJRFayNByx4D3ujGcEb47A)\\n\\n[\u503c\u5f97\u4e00\u770b\u7684\u5927\u6a21\u578bRAG\u95ee\u7b54\u603b\u62ec\u6027\u68b3\u7406\uff1a\u6a21\u5757\u5316(Modular)RAG\u8303\u5f0f\u7684\u5b9a\u4e49\u3001\u6784\u6210\u53ca\u673a\u9047](https://mp.weixin.qq.com/s/j07PkTCoxBzAhkyON1puPg)\\n\\n[\u3010\u6709\u8154\u8c03\u7684RAG\u301101 \u534a\u7ed3\u6784\u5316\u6570\u636e\u4e0a\u7684RAG](https://www.bilibili.com/video/BV1tN4y1m78N)\\n\\n[\u7701\u94b1\uff01\u5fae\u8f6f\u5f00\u6e90\u6846\u67b6LLMLingua + LlamaIndex\u5b9e\u73b0\u63d0\u793a\u8bcd\u538b\u7f29](https://www.bilibili.com/video/BV16w411J7sW)\\n\\n[Ollama Python\u5f00\u53d1\u5305\u5b9e\u4f8b | \u57fa\u4e8e\u672c\u5730\u90e8\u7f72\u5f00\u6e90\u5927\u6a21\u578b\u7684Streamlit\u804a\u5929\u5e94\u7528](https://www.bilibili.com/video/BV1GK4y1q718)\\n\\n[\u3010\u9690\u79c1\u4f18\u5148\u3011Llama 2 + GPT4All + Chroma\u5b9e\u73b0100%\u672c\u5730\u5316RAG](https://www.bilibili.com/video/BV1yH4y117oV)\\n\\n[\u5927\u6a21\u578b\u65f6\u4ee3\u8fd8\u4e0d\u7406\u89e3\u81ea\u6ce8\u610f\u529b\uff1f\u8fd9\u7bc7\u6587\u7ae0\u6559\u4f60\u4ece\u5934\u5199\u4ee3\u7801\u5b9e\u73b0](https://mp.weixin.qq.com/s/XZDG8ZaB4QqD5cgIDJT6vQ)\\n\\n[\u9648\u4e39\u7426\u56e2\u961f\u65b0\u4f5c\uff1a\u6570\u636e\u91cf\u780d95%\uff0c\u5927\u6a21\u578b\u6027\u80fd\u66f4\u5f3a\u4e86\uff01Less is More](https://mp.weixin.qq.com/s/4ZnL0_uMLBgbVCNVjPWGKg)\\n\\n[\u3010AI \u521d\u4f53\u9a8c\u3011 llama2\u4e0eLangChain \u7684 SQLDatabaseChain](https://juejin.cn/post/7298997940019314742)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u4ece\u7269\u7406\u673a\u5230K8S\uff1a\u5e94\u7528\u7cfb\u7edf\u90e8\u7f72\u65b9\u5f0f\u7684\u6f14\u8fdb\u53ca\u5176\u5f71\u54cd](https://juejin.cn/post/7306806944047415332)\\n\\n[Leetcode \u7b97\u6cd5\u9898\u89e3\u7cbe\u9009](https://mp.weixin.qq.com/s/ujs3PT_g7yFHVW-klzTJNQ)\\n\\n[\u725b\u903c\u4e86\uff012\u6708\u7f16\u7a0b\u8bed\u8a00\u699c\u5355\uff1aGo\u9996\u6b21\u8fdb\u5165\u524d\u5341](https://mp.weixin.qq.com/s/HaVmckBGakEwu-EJ5JkONg)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#99 Not understanding how the GC works](https://mp.weixin.qq.com/s/fQensm55bnzPKagMEVs8Ag)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#98 Not using Go diagnostics tooling](https://mp.weixin.qq.com/s/GwOvZYfT6Y7euZuum9868Q)\\n\\n[\u4e00\u6587\u641e\u61c2Go GC\u6f14\u8fdb\u53f2\uff0c\u8bb2\u7684\u592a\u7ec6\u81f4\u4e86\uff01](https://juejin.cn/post/7317462907302461475)\\n\\n[Rust \u4e2d\u7684\u5e76\u53d1\u6a21\u578b\u548c\u6240\u6709\u6743\u7cfb\u7edf](https://juejin.cn/post/7307244392564408358)\\n\\n[Kitex\uff1a\u5fae\u670d\u52a1\u67b6\u6784\u4e0b\u7684\u9ad8\u6027\u80fd\u4f18\u5316\u5b9e\u8df5](https://juejin.cn/post/7270326047342182419)\\n\\n[\u63a2\u7a76 Go \u7684\u9ad8\u7ea7\u7279\u6027\u4e4b \u3010\u5904\u74061\u5206\u949f\u767e\u4e07\u8bf7\u6c42\u3011](https://juejin.cn/post/7245919919223636023)\\n\\n[\u63a2\u7a76 Go \u7684\u9ad8\u7ea7\u7279\u6027\u4e4b \u3010\u9886\u57df\u9a71\u52a8\u8bbe\u8ba1\u4e2d\u7bc7\u3011](https://juejin.cn/post/7247428110165016613)\\n\\n[\u7528 Go \u8bed\u8a00\u5b9e\u73b0\u5218\u8c26 2024 \u6625\u665a\u9b54\u672f\uff0c\u8fd8\u539f\u5c3c\u683c\u4e70\u63d0\u6c57\u6d41\u6d43\u80cc\u7684\u5c34\u5c2c\u77ac\u95f4!](https://juejin.cn/post/7333027152139567113)\\n\\n[\u8fd8\u4e0d\u6562\u5199\u591a\u7ebf\u7a0b\u7a0b\u5e8f\uff1f\u770b\u770bGo\u5982\u4f55\u8ba9\u5e76\u53d1\u63a7\u5236\u7b80\u5355\u6709\u8da3](https://juejin.cn/post/7323087699479724042)\\n\\n[\u4ece fatal \u9519\u8bef\u5230 sync.Map\uff1aGo\u4e2d Map \u7684\u5e76\u53d1\u7b56\u7565](https://juejin.cn/post/7325733245166026793)\\n\\n[16. Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e09\uff09\uff1aGMP \u6a21\u578b\u8c03\u5ea6\u65f6\u673a](https://juejin.cn/post/7330052230472663055)\\n\\n[15. Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e8c\uff09\uff1aGo \u7a0b\u5e8f\u542f\u52a8\u90fd\u5e72\u4e86\u4e9b\u4ec0\u4e48](https://juejin.cn/post/7327138554756857908)\\n\\n[14. Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e00\uff09\uff1a\u4ec0\u4e48\u662f GMP](https://juejin.cn/post/7324931501926875170)\\n\\n[13. \u5165\u95e8 go \u8bed\u8a00\u6c47\u7f16\uff0c\u770b\u61c2 GMP \u6e90\u7801](https://juejin.cn/post/7319484272531701812)\\n\\n[8. \u770b Go \u6e90\u7801\uff0c\u4f60\u9700\u8981\u4e86\u89e3 unsafe.Pointer](https://juejin.cn/post/7298645450554605568)\\n\\n[5. golang map \u6e90\u7801\u7684\u9010\u53e5\u89e3\u8bfb](https://juejin.cn/post/7293820517375164416)\\n\\n[\u4e00\u6587\u641e\u61c2Kubernetes \u90e8\u7f72\u7b56\u7565](https://juejin.cn/post/7319418651069743167)\\n\\n[\u6eda\u52a8\u66f4\u65b0\u548c\u56de\u6eda\u90e8\u7f72\u5728 Kubernetes \u4e2d\u7684\u5de5\u4f5c\u539f\u7406](https://juejin.cn/post/7303075105390477323)\\n\\n[Go \u9879\u76ee\u6807\u51c6\u5e03\u5c40\uff1fGo \u5b98\u65b9\u51fa\u6307\u5357\u4e86](https://juejin.cn/post/7291853227245764658)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u963f\u91cc\u7ec8\u9762\uff1aNetty \u5982\u4f55\u505a\u5230\u5355\u673a\u767e\u4e07\u5e76\u53d1](https://mp.weixin.qq.com/s/j_cslpQDjVIUm1CGjk9CQQ)\\n\\n[8\u79cd\u4e13\u5751\u540c\u4e8b SQL\u5199\u6cd5\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b](https://mp.weixin.qq.com/s/9jKS_vW7lN3f-RwEDS7avw)\\n\\n[\u4ebf\u7ea7\u63a8\u9001\uff0c\u5f97\u7269\u662f\u600e\u4e48\u67b6\u6784\u7684](https://mp.weixin.qq.com/s/GGvBCVWSLce7Gs0Z0B8Jvg)\\n\\n[\u8be6\u89e3Redis\u4e09\u5927\u96c6\u7fa4\u6a21\u5f0f\uff0c\u8f7b\u677e\u5b9e\u73b0\u9ad8\u53ef\u7528\uff01](https://mp.weixin.qq.com/s/cvuz0619FadtkzmjD47llg)\\n\\n[\u963f\u91ccJava\u9762\u8bd5\u5b98\uff1aCopyOnWriteArrayList\u5e95\u5c42\u662f\u600e\u4e48\u4fdd\u8bc1\u7ebf\u7a0b\u5b89\u5168\u7684](https://mp.weixin.qq.com/s/AMkub_c3bTk8O0NzsdW35Q)\\n\\n[\u8fd8\u641e\u4e0d\u61c2ConcurrentHashMap\u5e95\u5c42\u6e90\u7801\uff0c\u770b\u8fd9\u7bc7\u5c31\u591f\u4e86](https://mp.weixin.qq.com/s/PlizO3EnFRmqn4Cl6nqiGA)\\n\\n[\u53ea\u9700\u4e03\u6b65\uff0c\u6559\u4f60\u8f7b\u677e\u89e3\u51b3Redis\u70ed\u70b9Key\u95ee\u9898](https://mp.weixin.qq.com/s/gb9nqVfqrClZ5o4-B4Eadg)\\n\\n[\u4e00\u6587\u8be6\u89e3Redis\u4e2dBigKey\u3001HotKey\u7684\u53d1\u73b0\u4e0e\u5904\u7406](https://mp.weixin.qq.com/s/FPYE1B839_8Yk1-YSiW-1Q)\\n\\n[Java \u5341\u4ebf\u884c\u6570\u636e\u8ba1\u7b97\uff0c\u6700\u5feb6\u79d2\u51fa\u7ed3\u679c\uff0c\u4f60\u80fd\u5417](https://mp.weixin.qq.com/s/dpXMqMSq_ZrXOeEInxlC_Q)\\n\\n[\u4eceKafka\u4e2d\u5b66\u4e60\u9ad8\u6027\u80fd\u7cfb\u7edf\u5982\u4f55\u8bbe\u8ba1 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7249380394457694263)\\n\\n[\u7531\u6d45\u5165\u6df1\u7684\u4ecb\u7ecd\u6263\u51cf\u4e1a\u52a1\u4e2d\u7684\u4e00\u4e9b\u9ad8\u5e76\u53d1\u6784\u5efa\u65b9\u6848\uff08\u4e0a\uff09](https://juejin.cn/post/7256104538230571067)\\n\\n[\u5982\u4f55\u5728\u5fae\u670d\u52a1\u4e0b\u4fdd\u8bc1\u4e8b\u52a1\u7684\u4e00\u81f4\u6027 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7226525442176778277)\\n\\n[\u3010Redis\u9ad8\u53ef\u7528\u7cfb\u5217\u3011\u4e3b\u4ece\u590d\u5236\u539f\u7406\u548c\u590d\u5236\u65b9\u5f0f\u5206\u6790](https://juejin.cn/post/7309373606272761895)\\n\\n[Redis\u5220\u9664\u6570\u636e\u540e\uff0c\u4e3a\u4ec0\u4e48\u5185\u5b58\u5360\u7528\u7387\u8fd8\u662f\u5f88\u9ad8](https://juejin.cn/post/7300809038246608948)\\n\\n[\u611f\u89c9Redis\u53d8\u6162\u4e86\uff0c\u8fd9\u4e9b\u53ef\u80fd\u7684\u539f\u56e0\u4f60\u67e5\u4e86\u6ca1 (\u4e0a)](https://juejin.cn/post/7290725204266287158)\\n\\n[\u611f\u89c9Redis\u53d8\u6162\u4e86\uff0c\u8fd9\u4e9b\u53ef\u80fd\u7684\u539f\u56e0\u4f60\u67e5\u4e86\u6ca1 (\u4e0b)](https://juejin.cn/post/7292975471448113192)\\n\\n[\u4f4d\u56fe(bitmap)\u539f\u7406\u4ee5\u53ca\u5b9e\u73b0](https://juejin.cn/post/7280435879541637176)\\n\\n[\u4ebf\u4e07\u7528\u6237\u5728\u7ebf\uff0c\u4e00\u5f20bitmap\u7edf\u8ba1\u5168\u89e3\u5bc6](https://juejin.cn/post/7329694104118362139)\\n\\n[\u5982\u4f55\u4f7f\u7528Redis\u6570\u636e\u7c7b\u578b\u8fdb\u884c\u4ebf\u7ea7\u522b\u7edf\u8ba1\u6570\u636e](https://juejin.cn/post/7282666872218107915)\\n\\n[MySQL\u4e8b\u52a1\u672a\u63d0\u4ea4redolog\u80fd\u6301\u4e45\u5316\u5230\u78c1\u76d8\u5417](https://juejin.cn/post/7319273137765449763)\\n\\n[\u7ed3\u5408MySQL\u66f4\u65b0\u6d41\u7a0b\u770b undolog\u3001redolog\u3001binlog](https://juejin.cn/post/7269296778226597927)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u81f4\u6240\u6709\u6e34\u671b\u5b66\u4e60Rust\u7684\u4eba\u7684\u4fe1](https://juejin.cn/post/7275978708644511802)\\n\\n[\u524d\u7aef\u9879\u76ee\u91cc\u90fd\u6709\u5565](https://juejin.cn/post/7327867132037611539)\\n\\n[\u767d\u5ad6ChatGPT4.0 (\u7b2c\u4e8c\u5f39)](https://juejin.cn/post/7302310196310294580)\\n\\n[\u5b57\u8282\u8df3\u52a8\u6700\u70ed\u95e8\u7684 15 \u4e2a\u524d\u7aef\u5f00\u6e90\u9879\u76ee](https://mp.weixin.qq.com/s/XuigLACJa95rJ9iJQhIDDg)\\n\\n[\u5218\u8c26\u6625\u665a\u9b54\u672f\u63ed\u79d8\uff1a\u7ea6\u745f\u592b\u73af\u7684\u6570\u5b66\u9b45\u529b\uff0cJS\u5b9e\u73b0\u4e0b\uff01](https://mp.weixin.qq.com/s/PUywO7JtYuO9H0fnLGsz-w)\\n\\n[\u6211\u5199\u4e86\u4e00\u4e2a\u6839\u636e\u9879\u76ee\u81ea\u52a8\u5207\u6362node\u7248\u672c\u7684\u63d2\u4ef6\uff0c\u518d\u4e5f\u4e0d\u7528\u624b\u52a8\u4f7f\u7528\u547d\u4ee4\u5207\u6362\u4e86](https://mp.weixin.qq.com/s/tk_E1NP6ra0yxuSVumH6UA)"},{"id":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-11/index.md","source":"@site/blogs/2024/2024-02-11/index.md","title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-02-11T00:00:00.000Z","formattedDate":"February 11, 2024","tags":[],"readingTime":3.79,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1aGo1.22 \u6b63\u5f0f\u53d1\u5e03\uff01\u5305\u542b\u8bed\u8a00\u53d8\u5316\u3001\u6027\u80fd\u63d0\u9ad8\u3001\u6807\u51c6\u5e93\u53d8\u52a8\u7b49\u91cd\u8981\u7279\u6027\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[MultiHop-RAG: Benchmarking Retrieval-Augmented Generation for Multi-Hop Queries](https://arxiv.org/pdf/2401.15391.pdf)\\n\\n[\u624b\u628a\u624b\u6559\u4f60\uff0c\u4ece\u96f6\u5f00\u59cb\u5b9e\u73b0\u4e00\u4e2a\u7a00\u758f\u6df7\u5408\u4e13\u5bb6\u67b6\u6784\u8bed\u8a00\u6a21\u578b\uff08MoE\uff09](https://mp.weixin.qq.com/s/fV-dnbT5g8j_B3RXgRsuZQ)\\n\\n[\u82f9\u679c\u4e3a\u81ea\u5bb6\u82af\u7247\u6253\u9020\u5f00\u6e90\u6846\u67b6MLX\uff0c\u5b9e\u73b0Llama 7B\u5e76\u5728M2 Ultra\u4e0a\u8fd0\u884c](https://mp.weixin.qq.com/s/jtpXKlABXwzlN8QjzT-sPA)\\n\\n[\u5982\u4f55\u7528LLM\u548c\u81ea\u6709\u77e5\u8bc6\u5e93\u642d\u5efa\u667a\u80fdAgent](https://mp.weixin.qq.com/s/dSleYYKtE41RQ9AUf5ruMw)\\n\\n[\u4e07\u5b57\u8be6\u89e3\u4e13\u5bb6\u6df7\u5408\uff1aMoE\u6a21\u578b](https://mp.weixin.qq.com/s/MY7sWGct2IxvDYvthY6A0g)\\n\\n[Prompt Engineering\uff1a\u5927\u6a21\u578b PUA \u6307\u5357\uff01](https://mp.weixin.qq.com/s/JloI284hBrKyV0d2s7V3ug)\\n\\n[Mixtral-8x7B \u6a21\u578b\u6316\u5751](https://mp.weixin.qq.com/s/IxQy6UMXaFn2odVFLhEXHw)\\n\\n[\u7cbe\u5f69\u624b\u7ed8\u5168\u89e3\uff1aRAG\u6280\u672f\uff0c\u4ece\u5165\u95e8\u5230\u7cbe\u901a](https://mp.weixin.qq.com/s/BITRn0NkpaVP0niiqevUaQ)\\n\\n[\u5355\u53613\u5c0f\u65f6\u8bad\u7ec3\u4e13\u5c5e\u5927\u6a21\u578bAgent-\u57fa\u4e8eLLaMA Factory\u5b9e\u6218](https://mp.weixin.qq.com/s/qeWEEmWlomjtFP5wQxUAcg)\\n\\n[\u767d\u8bddEmbedding\uff1a\u666e\u901a\u4eba\u90fd\u80fd\u61c2\u7684\u79d1\u666e\u6587](https://mp.weixin.qq.com/s/DGeey6v3ntGhIorOd_eB3w)\\n\\n[Mixtral 8x7B: \u8d85\u8d8aGPT-3.5\u4e0eLlama 2 70B\u7684\u7a00\u758f\u6df7\u5408\u4e13\u5bb6\u67b6\u6784\u65b0\u7bc7\u7ae0](https://mp.weixin.qq.com/s/GGY-hvcNphj4fvPxJPLLrQ)\\n\\n[3B\u6a21\u578b\u4e0d\u8f937B LLaVA\uff01\u5317\u5927\u591a\u6a21\u6001MoE\u6a21\u578b\u767bGitHub\u70ed\u699c](https://mp.weixin.qq.com/s/NSfAdIBXNzG9WNrz9jP1eA)\\n\\n[GPT-4\u63a8\u7406\u80fd\u529b\u66b4\u6da832%\uff0c\u8c37\u6b4c\u65b0\u578b\u601d\u7ef4\u94fe\u6548\u679c\u8d85CoT\uff0c\u8ba1\u7b97\u6210\u672c\u53ef\u964d\u81f31/40](https://mp.weixin.qq.com/s/HUW8MX2GhsdE3qFBvb1-Hg)\\n\\n[\u963f\u91cc\u5927\u6a21\u578b\u6625\u8282\u793c\u5305\u6765\u4e86\uff1a\u4ee3\u7801\u53ef\u6267\u884c\u7387\u8d85GPT-4\uff0c1.5\u7248\u672c\u5168\u7cfb\u5217\u5f00\u6e90](https://mp.weixin.qq.com/s/Ddn-8zI7SF5VfoQPcoYuPg)\\n\\n[\u521a\u521a\uff0c\u8c37\u6b4c\u5f03Bard\u53d1\u5e03\u8d85\u5927\u676fGemini\uff0c\u5168\u9762\u5bf9\u6807GPT-4\uff0c\u524d2\u4e2a\u6708\u514d\u8d39\uff01](https://mp.weixin.qq.com/s/V3abZ1R-NYG7nMRngheYbA)\\n\\n[\u65e0\u9700RLHF\u663e\u8457\u63d0\u5347GPT-4/Llama2\u6027\u80fd\uff0c\u5317\u5927\u56e2\u961f\u63d0\u51faAligner\u5bf9\u9f50\u65b0\u8303\u5f0f](https://mp.weixin.qq.com/s/O9PP4Oc_Ee3R_HxKyd31Qg)\\n\\n[\u624b\u6495LangChain\u4ee3\u7801\uff0c\u65b0\u624b\u8bf7\u8fdb](https://mp.weixin.qq.com/s/mPO13cCbTgIkWZBfKSjFvA)\\n\\n[MoE \u5377\u8d77\u6765\u5566\uff01\u53c8\u4e00\u5fae\u8c03\u7248 Mixtral-8x7B \u53d1\u5e03\uff0c\u8bd5\u8bd5\u6548\u679c\u600e\u4e48\u6837](https://mp.weixin.qq.com/s/Ks6X9RSCuNnTU2ZlQiGpqA)\\n\\n[\u4e0d\u662f GPT4 \u7528\u4e0d\u8d77\uff0c\u800c\u662f\u672c\u5730\u8fd0\u884c Mixtral-8x7B \u66f4\u6709\u6027\u4ef7\u6bd4](https://mp.weixin.qq.com/s/lGcatebmosW9BerZyVRlBQ)\\n\\n[\u5728 Mac \u8fd0\u884c OpenChat 3.5 \u5927\u6a21\u578b\uff0cAI\u63a8\u7406APP\u4ec52MB \u5b8c\u5168\u53ef\u79fb\u690d](https://mp.weixin.qq.com/s/mmG8NQbG6fnmc4lHL1zHWQ)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u4ee3\u7801\u9a8c\u8bc1\u65af\u7279\u6797\u516c\u5f0f\u7684\u51c6\u786e\u6027](https://mp.weixin.qq.com/s/4bd77FfQubPqdhcNJPFrsQ)\\n\\n[\u4e00\u4e9b\u7b14\u8bb0\u5de5\u5177\u5de5\u5177\u4ee5\u53camemos\u4ecb\u7ecd](https://mp.weixin.qq.com/s/-8IcAjN6T6LeE29p0nkqcQ)\\n\\n[Go 1.22.0 \u53ef\u79f0\u4e4b\u4e3a\u4e00\u6b21\u53f2\u8bd7\u7ea7\u66f4\u65b0](https://mp.weixin.qq.com/s/vr_-5HD0hFZYHmnnisByiA)\\n\\n[Go1.22 \u6b63\u5f0f\u53d1\u5e03\uff01\u5305\u542b\u8bed\u8a00\u53d8\u5316\u3001\u6027\u80fd\u63d0\u9ad8\u3001\u6807\u51c6\u5e93\u53d8\u52a8\u7b49\u91cd\u8981\u7279\u6027](https://mp.weixin.qq.com/s/SFMKam051BIZI4gwz8nrKg)\\n\\n[\u5b9e\u73b0\u57fa\u4e8e Grafana Loki \u7684\u65e5\u5fd7\u62a5\u8b66](https://mp.weixin.qq.com/s/8JAQxUQSfIggAIArokeL9g)\\n\\n[\u9f50\u6d3b\u4e86\uff0cGrafana \u53d1\u5e03\u5927\u89c4\u6a21\u6301\u7eed\u6027\u80fd\u5206\u6790\u5f00\u6e90\u6570\u636e\u5e93 - Phlare](https://mp.weixin.qq.com/s/P8E52qK6qeigwTMPWECBsw)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[DDD\u843d\u5730\uff1a\u4ece\u643a\u7a0b\u8ba2\u5355\u7cfb\u7edf\u91cd\u6784\uff0c\u770bDDD\u7684\u5de8\u5927\u4ef7\u503c](https://mp.weixin.qq.com/s/IsEDEu33HqHffFdv-A7WBw)\\n\\n[\u4e00\u6b21\u7531\u4e8e\u516b\u80a1\u6587\u5f15\u8d77\u7684\u5185\u5b58\u6cc4\u6f0f](https://mp.weixin.qq.com/s/QGmOz8jUjNo-3xKqVcWGmg)\\n\\n[\u7f51\u6613\u9762\u8bd5\uff1a\u8bf7\u8bbe\u8ba1\u4e00\u4e2a\u9ad8\u53ef\u7528\u6027\u7684\u8f6f\u4ef6\u67b6\u6784\uff0c\u8bf4\u660e\u8bbe\u8ba1\u601d\u8def](https://mp.weixin.qq.com/s/tNOhR16aC-cr5EqKiwbAOQ)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014MySQL\u7bc7](https://mp.weixin.qq.com/s/L26rI11OV8hrfJVy5Yu78g)\\n\\n[\u5929\u5929\u5199\u4e1a\u52a1\u4ee3\u7801\uff0c\u5982\u4f55\u7834\u5c40\u4e1a\u52a1\u5f00\u53d1\u7684\u672c\u8d28](https://mp.weixin.qq.com/s/2I3gFQZY03OKhdJa1AVhmw)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u7011\u5e03\u6d41\u4f18\u5316\uff1a\u6211\u628a\u5c0f\u7ea2\u4e66\u7684\u7011\u5e03\u6d41\u865a\u62df\u5217\u8868\u6495\u51fa\u6765\u4e86](https://mp.weixin.qq.com/s/z5zzBWel6DooAS0bzY702g)\\n\\n[\u5fc3\u9047APP\u7ad9\u5185\u73a9\u6cd5H5\u4f53\u9a8c\u4f18\u5316\u5b9e\u8df5](https://mp.weixin.qq.com/s/GYtd3k0JXns1GZQyZzvHaQ)\\n\\n[\u8bd1\uff1a\u5982\u4f55\u907f\u514d SSR \u6e32\u67d3\u672c\u5730\u65e5\u671f\u65f6\u7684 FOUC \u95ee\u9898](https://sorrycc.com/ssr-local-dates-without-fouc)\\n\\n[\u8bd1\uff1a\u5371\u9669\u7684\u6ce8\u6c34](https://sorrycc.com/danger-rehydration)\\n\\n[\u8bd1\uff1aReact 19 \u8ba1\u5212\u63a8\u51fa\u7684\u65b0 Hook](https://sorrycc.com/react-19-new-hooks)\\n\\n[\u8bd1\uff1a\u4f7f\u7528 Promise.withResolvers \u5ef6\u8fdf Promise](https://sorrycc.com/promise-with-resolvers)\\n\\n[2024 \u5e74\u4f60\u9700\u8981\u77e5\u9053\u7684 5 \u4e2a CSS \u4ee3\u7801\u7247\u6bb5](https://web.dev/articles/5-css-snippets-every-front-end-developer-should-know-in-2024)\\n\\n[Partial Prerendering \u7684 What\u3001Why \u548c How](https://www.youtube.com/watch?v=MTcPrTIBkpA)\\n\\n[2024 \u5e74\u5982\u4f55\u542f\u52a8 React \u9879\u76ee](https://www.robinwieruch.de/react-starter/)\\n\\n[MDH Weekly 120 - \u300a\u5c0f\u518c\u300b](https://mp.weixin.qq.com/s/fY-wz2LzkiZrvpblpSWlVw)"},{"id":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-02-04/index.md","source":"@site/blogs/2024/2024-02-04/index.md","title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","description":"alt text","date":"2024-02-04T00:00:00.000Z","formattedDate":"February 4, 2024","tags":[],"readingTime":4.22,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"![alt text](image.png)\\n\\n\u5c01\u9762\u56fe\uff1a\u56fe\u6587\u5403\u900fGolang net/http \u6807\u51c6\u5e93--\u670d\u52a1\u7aef\\n\\n## \ud83c\udf1f AI \u76f8\u5173\\n\\n[Large Language Models for Mathematical Reasoning: Progresses and Challenges](https://arxiv.org/abs/2402.00157)\\n\\n[A Comprehensive Survey of Compression Algorithms for Language Models](https://arxiv.org/abs/2401.15347)\\n\\n[The Power of Noise: Redefining Retrieval for RAG Systems](https://arxiv.org/abs/2401.14887)\\n\\n[Corrective Retrieval Augmented Generation](https://arxiv.org/abs/2401.15884)\\n\\n[\u4ece\u96f6\u6784\u5efa\u73b0\u4ee3\u6df1\u5ea6\u5b66\u4e60\u6846\u67b6(TinyDL-0.01)](https://mp.weixin.qq.com/s/tFl0RQd3ex98_SAOIIfM_Q)\\n\\n[\u672c\u5730\u8fd0\u884c\u9762\u58c1\u667a\u80fd\u7684\u201c\u8d3a\u5c81\u6a21\u578b\u201d\uff1aMiniCPM 2B](https://mp.weixin.qq.com/s/Z0iZR6iGSBe298eK1Er1Ow)\\n\\n[\u300c\u6211\u5728\u6dd8\u5929\u505a\u6280\u672f\u300d2024\u5e74\u770bAIGC\u662f\u5982\u4f55\u8ba91688\u4e3b\u56fe\u7115\u53d1\u65b0\u6625\u7684](https://mp.weixin.qq.com/s/Ni_vVDlxBaoUcgoVORw31A)\\n\\n[\u5927\u6a21\u578b\u63a8\u7406\u6846\u67b6RTP-LLM\u5bf9LoRA\u7684\u652f\u6301](https://mp.weixin.qq.com/s/em-mnps_Oqe1PLLpJ9hB-A)\\n\\n[LLM\u4e4bLangChain\uff08\u4e94\uff09| \u4f7f\u7528LangChain Agent\u5206\u6790\u975e\u7ed3\u6784\u5316\u6570\u636e](https://mp.weixin.qq.com/s/chxksL3zqbwyqHev1x43kw)\\n\\n[LLM\u4e4bRAG\u7406\u8bba\uff08\u516d\uff09| \u9ad8\u7ea7RAG\u6307\u5357\u548c\u6280\u5de7](https://mp.weixin.qq.com/s/a5uKQAxwfsREnXd0XPhu1A)\\n\\n[\u4ece\u96f6\u624b\u6413MoE\u5927\u6a21\u578b\uff0c\u5927\u795e\u7ea7\u6559\u7a0b\u6765\u4e86](https://mp.weixin.qq.com/s/gDtzzSRunUrKjoIUGSHCvA)\\n\\n[RAG\u8fdb\u9636 \u591a\u7528\u6237\u591a\u6587\u6863](https://juejin.cn/post/7325993514702258230)\\n\\n[RAG \u8fdb\u9636 LlamaIndex\u591a\u6587\u6863](https://juejin.cn/post/7325831147563958308)\\n\\n[RAG \u8fdb\u9636 \u591a\u6a21\u6001\u56fe\u7247\u68c0\u7d22](https://juejin.cn/post/7325724706139996201)\\n\\n[RAG \u8fdb\u9636 \u534a\u7ed3\u6784\u5316\u6570\u636e](https://juejin.cn/post/7325800661232140327)\\n\\n[LlamIndex\u4e8c RAG\u5e94\u7528\u5f00\u53d1](https://juejin.cn/post/7310347016982069288)\\n\\n[LlamaIndex \u4e00 \u7b80\u5355\u6587\u6863\u67e5\u8be2](https://juejin.cn/post/7310786591940165641)\\n\\n[\u4f7f\u7528 Docker \u5feb\u901f\u4e0a\u624b\u4e2d\u6587\u7248 LLaMA2 \u5f00\u6e90\u5927\u6a21\u578b](https://mp.weixin.qq.com/s/9cTNa_oya2Zj9YdDYodCvw)\\n\\n[\u90e8\u7f72\u5fc5\u5907\u2014triton-inference-server\u7684backend\uff08\u4e00\uff09\u2014\u2014\u5173\u4e8e\u63a8\u7406\u6846\u67b6\u7684\u4e00\u4e9b\u8ba8\u8bba](https://mp.weixin.qq.com/s/_WStiyaAk7G-w2j6SVe4CA)\\n\\n[TensorRT-LLM\u521d\u63a2\uff08\u4e00\uff09\u8fd0\u884cllama\uff0c\u4ee5\u53catriton tensorrt llm backend\u670d\u52a1\u5316](https://mp.weixin.qq.com/s/J1EdNtAx3B0yeQ7zeSDLQg)\\n\\n[H100\u63a8\u7406\u98d9\u53478\u500d\uff01\u82f1\u4f1f\u8fbe\u5b98\u5ba3\u5f00\u6e90TensorRT-LLM\uff0c\u652f\u630110+\u6a21\u578b](https://mp.weixin.qq.com/s/xcNQBG69XkS6mOstzqROAw)\\n\\n[\u5927\u8bed\u8a00\u6a21\u578b\u63a8\u7406\u63d0\u901f\uff1aTensorRT-LLM \u9ad8\u6027\u80fd\u63a8\u7406\u5b9e\u8df5](https://mp.weixin.qq.com/s/jnQs5XhWeAqoitahmDhziQ)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1a\u6027\u80fd\u63d0\u9ad8\u3001Trace \u5927\u4fee\u3001\u5de5\u4f5c\u533a\u652f\u6301 vendor \u7b49](https://mp.weixin.qq.com/s/_RHDJ1VGfqolE_Uzorosbw)\\n\\n[json.Marshal\u4e3a\u4ec0\u4e48\u4f1a\u5bf9[]byte\u7c7b\u578b\u8fdb\u884cbase64\u7f16\u7801\u5904\u7406](https://mp.weixin.qq.com/s/h8SNvIVN1bFy8gBUB63_NA)\\n\\n[Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e8c\uff09\uff1aGo \u7a0b\u5e8f\u542f\u52a8\u90fd\u5e72\u4e86\u4e9b\u4ec0\u4e48](https://mp.weixin.qq.com/s/PvdZ_Ay9xgrY_SrDt-Sddw)\\n\\n[Go\u8bed\u8a00\u4e2d\u7684Pinner.Pin](https://mp.weixin.qq.com/s/MNuk0poC3s2tTx_DjyJAQA)\\n\\n[Kubernetes \u8c03\u5ea6\u5668\u961f\u5217 - \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/wQqMu41e8pnLpnAZo0GLow)\\n\\n[Go\u8bed\u8a00\u901a\u77e5\u534f\u7a0b\u9000\u51fa(\u53d6\u6d88)\u7684\u51e0\u79cd\u65b9\u5f0f](https://mp.weixin.qq.com/s/CNTlXMWSmQ4dNbbCQpbjYg)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#97 Not relying on inlining](https://mp.weixin.qq.com/s/SC1tg6XxDi_y1bjj6lkw6w)\\n\\n[\u7a0b\u5e8f\u5458\u624d\u61c2\u7684\u4e50\u8da3\uff1a10\u4ebf\u884c\u7684\u6311\u6218](https://mp.weixin.qq.com/s/_z801oBwANP27C-BXbHNZA)\\n\\n[Kubernetes \u8c03\u5ea6\u5668 - \u6838\u5fc3\u6d41\u7a0b (\u4e0b\u7bc7)](https://mp.weixin.qq.com/s/vHr56wXPVAl-b4tbnvhS5w)\\n\\n[Go\u8c03\u5ea6\u5668\u7cfb\u5217\u89e3\u8bfb\uff08\u4e00\uff09\uff1a\u4ec0\u4e48\u662f GMP](https://mp.weixin.qq.com/s/g4NdoFWrcGmSMeQt8q1XtA)\\n\\n[Kubernetes \u8c03\u5ea6\u5668 - \u6838\u5fc3\u6d41\u7a0b (\u4e0a\u7bc7)](https://mp.weixin.qq.com/s/4hZ6laeQc5P2o2n1yKD_8w)\\n\\n[\u56fe\u6587\u8bb2\u900fGolang\u6807\u51c6\u5e93 net/http\u5b9e\u73b0\u539f\u7406 -- \u670d\u52a1\u7aef](https://mp.weixin.qq.com/s/e7Z_kZrayTFx7y0hlzoTdg)\\n\\n[\u5229\u7528 ChatGPT \u9ad8\u6548\u641c\u7d22Go\u95ee\u9898\uff1a\u4e3e\u4e00\u53cd\u4e09\u7684\u601d\u8003\u65b9\u5f0f\uff0c\u9ad8\u6548\u67e5\u627e\u89e3\u51b3\u65b9\u6848](https://mp.weixin.qq.com/s/b7dHVIVYsL-19gyzUujktA)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#96 Not knowing how to reduce allocations](https://mp.weixin.qq.com/s/d5nczMvDpELt8R5ZB08Yow)\\n\\n[\u4ece\u6162\u901f\u5230SIMG: \u4e00\u4e2aGo\u4f18\u5316\u7684\u6545\u4e8b](https://mp.weixin.qq.com/s/l6Tq_bVDmMpwZg_rPfi1DQ)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[8\u79cd\u4e13\u5751\u540c\u4e8b\u7684 SQL \u5199\u6cd5\uff0c\u6027\u80fd\u964d\u4f4e100\u500d\uff0c\u4e0d\u6765\u770b\u770b](https://mp.weixin.qq.com/s/jwAawzeKq_vTTYw58rvgVA)\\n\\n[\u6279\u91cf\u6267\u884cRedis\u547d\u4ee4\u7684\u56db\u79cd\u65b9\u5f0f\uff01](https://mp.weixin.qq.com/s/YF5D3RRvmVXNJ_Njsa1Txw)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1a\u8bbe\u8ba1\u4e00\u4e2a\u5927\u5e76\u53d1\u3001\u5927\u6570\u636e\u7684\u7cfb\u7edf\u67b6\u6784\uff0c\u8bf4\u8bf4\u8bbe\u8ba1\u601d\u8def](https://mp.weixin.qq.com/s/hmO2BKuMMU8ZPxW0lj9ZHw)\\n\\n[\u7801\u54e5\u5b57\u8282 124 \u7bc7\u4f18\u79c0\u6587\u7ae0\u7cbe\u9009](https://mp.weixin.qq.com/s/mspeViqHosmh4kUI8S8ajA)\\n\\n[Kafka\u6027\u80fd\u7bc7\uff1a\u4e3a\u4f55Kafka\u8fd9\u4e48\\"\u5feb\\"](https://mp.weixin.qq.com/s/vzbLWE4JteqjkOFJwcgRhg)\\n\\n[Redis \u6838\u5fc3\u7bc7\uff1a\u552f\u5feb\u4e0d\u7834\u7684\u79d8\u5bc6](https://mp.weixin.qq.com/s/z4VjDaDDbspFz1rIBwazIA)\\n\\n[\u94fe\u8def\u8ffd\u8e2a\u843d\u5730\u8fc7\u7a0b\u4e2d\u7684\u6311\u6218\u4e0e\u89e3\u51b3\u65b9\u6848](https://mp.weixin.qq.com/s/NU-W6rpwH-6_RQnSgbfZqQ)\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1aSentinel\u5e95\u5c42\u6ed1\u52a8\u65f6\u95f4\u7a97\u9650\u6d41\u7b97\u6cd5\u600e\u4e48\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/TbxisH1zzE58u7YoRi04yA)\\n\\n[\u5b57\u8282\u4e8c\u9762\uff1aSpring Boot Redis \u53ef\u91cd\u5165\u5206\u5e03\u5f0f\u9501\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/sMeLfLachYpUq261usr4tQ)\\n\\n[\u7ea0\u6b63\u8bef\u533a\uff1a\u8fd9\u624d\u662f SpringBoot Redis \u5206\u5e03\u5f0f\u9501\u7684\u6b63\u786e\u5b9e\u73b0\u65b9\u5f0f](https://mp.weixin.qq.com/s/nJeRvz7jb4i2eXzc4vpdvw)\\n\\n[\u5206\u5e93\u5206\u8868\u7684 21 \u6761\u6cd5\u5219\uff0chold \u4f4f\uff01](https://mp.weixin.qq.com/s/W5vbjWMG86zEca3CPvAadg)\\n\\n[\u817e\u8baf\u4e8c\u9762\uff1aepoll\u6027\u80fd\u90a3\u4e48\u9ad8\uff0c\u4e3a\u4ec0\u4e48](https://mp.weixin.qq.com/s/DLmXspbokYhQ-j5tLnUMgw)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u6269\u5c55\u4f60\u7684\u524d\u7aef\u77e5\u8bc6\u5e93\uff0c\u6beb\u65e0\u5e9f\u8bdd\uff01](https://mp.weixin.qq.com/s/ZkMc3-T0swxjJ4yujp1R1w)\\n\\n[TypeScript 5.4 beta: NoInfer \u7c7b\u578b\u3001\u95ed\u5305\u7c7b\u578b\u5206\u6790\u4f18\u5316\u3001\u6761\u4ef6\u7c7b\u578b\u5224\u65ad\u4f18\u5316\u7b49](https://mp.weixin.qq.com/s/lRzS_ZoJhzHmuOx0HCDTnw)\\n\\n[\u5347\u7ea7\u5230 React 18 \u7684\u7ecf\u9a8c\u548c\u6559\u8bad](https://mp.weixin.qq.com/s/48cn-JU3uCZkpsi30cloiQ)"},{"id":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-28/index.md","source":"@site/blogs/2024/2024-01-28/index.md","title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-28T00:00:00.000Z","formattedDate":"January 28, 2024","tags":[],"readingTime":6.64,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u5355\u53613\u5c0f\u65f6\u8bad\u7ec3\u4e13\u5c5e\u5927\u6a21\u578bAgent-\u57fa\u4e8eLLaMA Factory\u5b9e\u6218](https://mp.weixin.qq.com/s/DPTDaPkYdhY4KjR3hahKNA)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[#150 Go \u5e76\u53d1\u6a21\u5f0f\u4ecb\u7ecd\u548c\u521b\u65b0\u521b\u9020\u3010Go \u591c\u8bfb\u3011](https://www.bilibili.com/video/BV1Fw41177tk)\\n\\n[\u4e3a\u4ec0\u4e48 Golang Fasthttp \u9009\u62e9\u4f7f\u7528 slice \u800c\u975e map \u5b58\u50a8\u8bf7\u6c42\u6570\u636e](https://mp.weixin.qq.com/s/68Pj0mEJF2Ks9X2pVFk87g)\\n\\n[\u4ece Context \u770b Go \u8bbe\u8ba1\u6a21\u5f0f\uff1a\u63a5\u53e3\u3001\u5c01\u88c5\u548c\u5e76\u53d1\u63a7\u5236](https://mp.weixin.qq.com/s/e03KFBKXUXwzvw3dVPOH-Q)\\n\\n[50 \u6761\u4e89\u8bba\u7684\u6587\u7ae0\u53d1\u751f\u4e86\u5565\uff1aGo \u6807\u51c6\u5e93 encoding/json \u771f\u7684\u6162\u5417](https://mp.weixin.qq.com/s/s63mY3j4oBwpQmB4r4SeWw)\\n\\n[Kubernetes \u63a7\u5236\u5668\u7ba1\u7406\u603b\u7ed3](https://mp.weixin.qq.com/s/uyN2iHJPEjaYlQYpxTJ6bA)\\n\\n[\u4f7f\u7528cmux\u5b9e\u73b0\u7f51\u7edc\u7aef\u53e3\u590d\u7528](https://mp.weixin.qq.com/s/_BQjJT8zqvWrXXdO_YR8lA)\\n\\n[\u6beb\u5dc5\u4e4b\u5fae---\u4e0d\u540c\u5199\u6cd5\u7684\u6027\u80fd\u5dee\u5f02 \u756a\u5916\u7bc7](https://mp.weixin.qq.com/s/LIdlk0p32iW2KDjGHGflMQ)\\n\\n[2024\u5e74\u7684Rust\u4e0eGo](https://mp.weixin.qq.com/s/EWq7-LYcq586U0PXaJeQHw)\\n\\n[Go 1.22 rc2 \u521a\u521a\u53d1\u5e03\uff0c\u591a\u4e2a\u65b0\u7279\u6027\u7b49\u7740\u5927\u5bb6 forloop,math/rand/v2,\u589e\u5f3a http routing](https://mp.weixin.qq.com/s/-mLxdZ5LXYoFKH_RinNqqw)\\n\\n[Go \u670d\u52a1\u7f51\u7edc\u4e0d\u901a\uff1fnet/http\u81ea\u5e26\u7684\u8fd9\u4e2a\u5de5\u5177\u5e2e\u4f60\u5feb\u901f\u5b9a\u4f4d](https://mp.weixin.qq.com/s/8_pJiuOzoQt6xyoLUX0CIw)\\n\\n[golang pprof \u76d1\u63a7\u7cfb\u5217(1) \u2014\u2014 go trace \u7edf\u8ba1\u539f\u7406\u4e0e\u4f7f\u7528](https://mp.weixin.qq.com/s/2BY_93w8iAJOGpsCdgbGtA)\\n\\n[Go \u5b9a\u65f6\u5668\uff1aTimer \u548c Ticker](https://mp.weixin.qq.com/s/IgXFofLEwhYYYUtIZ4_rTA)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1a\u589e\u5f3a http.ServerMux \u8def\u7531\u80fd\u529b\uff0c\u5c06\u6709\u66f4\u5f3a\u7684\u8868\u73b0\u529b\uff01](https://mp.weixin.qq.com/s/gGr1aM1ijBmaejfwW2qqeA)\\n\\n[\u7ec6\u8282\u5bf9\u7ebf\uff0c\u8ba9\u4f60\u5199\u51fa\u66f4\u5b89\u5168\u7684 Dockerfile](https://mp.weixin.qq.com/s/8ZSuq-vYbB62B1TRFF-MGA)\\n\\n[Go \u8bed\u8a00\u4e2d\u9ad8\u6548\u5207\u7247\u62fc\u63a5\u548c GO 1.22 \u63d0\u4f9b\u7684\u65b0\u65b9\u6cd5](https://mp.weixin.qq.com/s/A99rzi-SZ6QvAv8Sia5nGg)\\n\\n[GO \u4e2d\u9ad8\u6548 int \u8f6c\u6362 string \u7684\u65b9\u6cd5\u4e0e\u6e90\u7801\u5256\u6790](https://mp.weixin.qq.com/s/xwNZsIp3qMK532R9CVI31A)\\n\\n[Go\u5408\u96c6 | \u4e0a\u65b0 \u817e\u8bafGo\u5b89\u5168\u6307\u5357](https://mp.weixin.qq.com/s/gFR9WCMeZG9KxUBq11EGXw)\\n\\n[\u300aGo\u9898\u5e93\xb716\u300b\u8bfb\u5199\u9501\u5e95\u5c42\u662f\u600e\u4e48\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/CARzBDS3PSeH-EVrADvozA)\\n\\n[\u300aGo\u9898\u5e93\xb715\u300bgo struct \u80fd\u4e0d\u80fd\u6bd4\u8f83](https://mp.weixin.qq.com/s/wzqKqHhWhJKA0T6V-6SAig)\\n\\n[Kubernetes GC \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/wlS5IYD11HJnS-NqD-BvWA)\\n\\n[Go \u591c\u8bfb\u7b2c 150 \u671f Go \u5e76\u53d1\u6a21\u5f0f\u4ecb\u7ecd\u548c\u521b\u65b0\u521b\u9020](https://mp.weixin.qq.com/s/Ks1BDSw3mSxcxLp3VHObaw)\\n\\n[\u8ddf\u7740\u8001\u732b\u6765\u641eGO-\u5185\u5efa\u5bb9\u5668Map](https://mp.weixin.qq.com/s/KB8BM9jNI5AS6QCG_6fHYw)\\n\\n[\u8fd9\u662f\u6211\u89c1\u8fc7\u6700\u9177\u7684\u670d\u52a1\u7aef\u65e5\u5fd7\u6536\u96c6\u65b9\u6848\uff01](https://mp.weixin.qq.com/s/bBefDLI2psURnUm3LhiAkA)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#95 Not understanding stack vs. heap](https://mp.weixin.qq.com/s/KqjvbhO4zN5oB-lmq0cNkg)\\n\\n[Go \u8bed\u8a00\u5b9e\u6218\uff1a\u6784\u5efa\u5f3a\u5927\u7684\u5ef6\u8fdf\u4efb\u52a1\u961f\u5217](https://mp.weixin.qq.com/s/OkBqiMEnha3SyCxBA0MkRQ)\\n\\n[\u4e3a\u4ec0\u4e48 Go1.22 for \u5faa\u73af\u8981\u652f\u6301\u6574\u6570\u8303\u56f4](https://mp.weixin.qq.com/s/cw7p2EuUTIj1TAcfCdfbew)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u4e07\u5b57\u8be6\u89e3\u5fae\u670d\u52a1\u4e16\u7eaa\u96be\u9898\uff1a\u5982\u4f55\u5e73\u6ed1\u62c6\u5206\u5355\u4f53](https://mp.weixin.qq.com/s/WaD8Go8twTF3CyoZm1ZICQ)\\n\\n[\u6ca1\u7528\u8fc7\u5fae\u670d\u52a1\uff1f\u522b\u614c\uff0c\u4e10\u7248\u67b6\u6784\u56fe\uff0c\u8ba9\u4f60\u8f7b\u677e\u62ff\u634f\u9762\u8bd5\u5b98](https://mp.weixin.qq.com/s/R-w5_FCVBmesVpLNFxWNhw)\\n\\n[\u4ece4\u4e07\u884c\u4ee3\u7801\u964d\u52301.8\u4e07\uff0c\u817e\u8baf\u89c6\u9891\u7adf\u7136\u7528DDD\u505a\u67b6\u6784\u91cd\u6784](https://mp.weixin.qq.com/s/DK3YM3umDfuEIvX77DHdHA)\\n\\n[\u8f6c\u8f6c\u652f\u4ed8\u901a\u9053\u76d1\u63a7\u7cfb\u7edf\u7684\u642d\u5efa](https://mp.weixin.qq.com/s/GVZWeBay7xKniiCHjc0yeg)\\n\\n[\u5fae\u670d\u52a1\u67b6\u6784\u4e0b\u7f51\u5173\u7684\u6280\u672f\u9009\u578b](https://mp.weixin.qq.com/s/27sPoF_p2cjgg_5Kq2hYCA)\\n\\n[Linux\u8fdb\u7a0b\u7ba1\u7406\u5de5\u5177 Supervisor\u8be6\u89e3](https://zhuanlan.zhihu.com/p/147305277)\\n\\n[SpringBoot + SpEL\uff0c\u8f7b\u677e\u641e\u5b9a\u590d\u6742\u6743\u9650\u63a7\u5236\uff0c\u975e\u5e38\u4f18\u96c5\uff01](https://mp.weixin.qq.com/s/DA3HoEvCTXPDKvM5EvbXrg)\\n\\n[\u540e\u7aef\u7a0b\u5e8f\u5458\u5fc5\u5907\uff1a\u4e66\u5199\u9ad8\u8d28\u91cfSQL\u768430\u6761\u5efa\u8bae](https://mp.weixin.qq.com/s/IPUAlBmGgsQTGqodLGECLg)\\n\\n[\u4e91\u97f3\u4e50RPC\u7a33\u5b9a\u6027\u5efa\u8bbe\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/8blLwTDT5lGqD2BYqaNlmg)\\n\\n[\u4e34\u65f6\u62b1\u4f5b\u811a\u5fc5\u770b\uff5c\u4e00\u4e2a\u6708\u901f\u901a\u9ad8\u7ea7\u7cfb\u7edf\u67b6\u6784\u8bbe\u8ba1\u5e08\uff01](https://mp.weixin.qq.com/s/l0FJsocKibWWxxW4Uk_mxQ)\\n\\n[\u7b2c\u4e00\u6027\u539f\u7406\uff1a\u517b\u732a\u8fd8\u662f\u8bfb\u5927\u5b66](https://mp.weixin.qq.com/s/azDbatL-bYqoNo08kQbVpQ)\\n\\n[\u7b2c\u4e8c\u904d\u8bfb\u4fde\u519b\u7684\u795e\u4f5c\u300a\u4ea7\u54c1\u65b9\u6cd5\u8bba\u300b\uff0c\u771f\u9999\uff01](https://mp.weixin.qq.com/s/8vVU-UjbA5BFJJRBOSHgeQ)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1aSentinel\u7194\u65ad\u964d\u7ea7\uff0c\u662f\u5982\u4f55\u5b9e\u73b0\u7684](https://mp.weixin.qq.com/s/DWwkAax0tPj2mqikffJDfg)\\n\\n[\u6df1\u5ea6\u5256\u6790\uff1aRedis\u5206\u5e03\u5f0f\u9501\u5230\u5e95\u5b89\u5168\u5417\uff1f\u770b\u5b8c\u8fd9\u7bc7\u6587\u7ae0\u5f7b\u5e95\u61c2\u4e86\uff01](https://mp.weixin.qq.com/s/s8xjm1ZCKIoTGT3DCVA4aw)\\n\\n[\u641e\u61c2\u5f02\u5730\u591a\u6d3b\uff0c\u770b\u8fd9\u7bc7\u5c31\u591f\u4e86](https://mp.weixin.qq.com/s/T6mMDdtTfBuIiEowCpqu6Q)\\n\\n[\u4e00\u952e\u90e8\u7f72 SpringCloud \u5fae\u670d\u52a1\uff0cyyds\uff01](https://mp.weixin.qq.com/s/HXj5YvANMIpceaspBWjmgg)\\n\\n[Redis\u3001ZooKeeper\u3001Etcd\uff0c\u8c01\u6709\u6700\u597d\u7528\u7684\u5206\u5e03\u5f0f\u9501](https://mp.weixin.qq.com/s/yZC6VJGxt1ANZkn0SljZBg)\\n\\n[\u63d0\u70bc\u8bbe\u8ba1\u6846\u67b6\uff0c\u4e00\u6587\u641e\u61c2Redis/MySQL/Kafka\u4e3a\u4ec0\u4e48\u8fd9\u6837\u8bbe\u8ba1](https://juejin.cn/post/7317926149119721507)\\n\\n[\u817e\u8baf\u4e00\u9762\uff1a32 \u4f4d 4GB \u7cfb\u7edf\uff0c\u8bbf\u95ee 2GB \u6570\u636e\uff0c\u865a\u62df\u5185\u5b58\u4f1a\u53d1\u751f\u4ec0\u4e48](https://mp.weixin.qq.com/s/IfLCzKsqTx_xUQkC4DB9KA)\\n\\n[1.5\u4e07\u5b57+30\u5f20\u56fe\u76d8\u70b9\u7d22\u5f15\u5e38\u89c1\u768411\u4e2a\u77e5\u8bc6\u70b9](https://mp.weixin.qq.com/s/FHt1IehO-XrpojJKsY7tkQ)\\n\\n[\u817e\u8baf\u4e09\u9762\uff1a\u4e00\u53f0\u670d\u52a1\u5668\uff0c\u6700\u5927\u652f\u6301\u7684TCP\u8fde\u63a5\u6570\u662f\u591a\u5c11](https://mp.weixin.qq.com/s/JSnmeL68oOwCZzuLxZrb5Q)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u591a\u7ebf\u7a0b\u7bc7](https://mp.weixin.qq.com/s/IVgGXQKU1QiT1ToN2wXHJg)\\n\\n[\u963f\u91cc\u4e8c\u9762\uff1a\u8981\u4fdd\u8bc1\u6d88\u606f\u4e0d\u4e22\u5931\uff0c\u53c8\u4e0d\u91cd\u590d\uff0c\u6d88\u606f\u961f\u5217\u600e\u4e48\u9009\u578b](https://mp.weixin.qq.com/s/g-vG2d9QaYn_-f3gCa1Jqg)\\n\\n[\u4f7f\u7528\u53cc\u5f02\u6b65\u540e\uff0c\u5982\u4f55\u4fdd\u8bc1\u6570\u636e\u4e00\u81f4\u6027](https://mp.weixin.qq.com/s/2-V0Yf7sHxneKp0PJbYxBg)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n\u865a\u5b9e\u4e4b\u95f4\u6709\u4e00\u671f\u64ad\u5ba2\u8bb2\u300c\u62fc\u591a\u591a\u51fa\u6d77\u7684 - TEMU \u589e\u957f\u80cc\u540e\u9ec4\u94ee\u7684\u521b\u4e1a\u54f2\u5b66\u548c\u4e2d\u4f01\u51fa\u6d77\u4e4b\u8def\u300d\u542c\u4e0b\u6765\u8bb2\u5f97\u5f88\u6709\u903b\u8f91\uff0c\u804a\u5230\u4e86\u5168\u6258\u7ba1\u6a21\u5f0f\u5982\u4f55\u7b80\u5316\uff0c\u62fc\u591a\u591a\u7684\u4f20\u7edf\u6280\u80fd\u4f4e\u4ef7\uff0c\u4ee5\u53ca\u5982\u4f55\u5b9e\u73b0\u7684\u4f4e\u4ef7\uff0c\u5305\u62ec\u4e2d\u56fd\u4f01\u4e1a\u51fa\u6d77\u7684\u51e0\u4e2a\u9636\u6bb5\uff0c\u5f88\u901a\u4fd7\u6613\u61c2\uff0c\u503c\u5f97\u5b66\u4e60\u3002\\n\\nhttps://www.xiaoyuzhoufm.com/episode/657fc03f991e2ee608f54f98\\n\\n\u5f53\u4f60\u60f3\u5c06 feature \u5206\u652f\u4e0a\u7684\u591a\u4e2a commit \u5408\u5e76\u5230 release \u5206\u652f\uff0c\u5e76\u4e14\u5e0c\u671b\u5728 release \u5206\u652f\u4e0a\u53ea\u770b\u5230\u4e00\u4e2a\u5408\u5e76\u63d0\u4ea4\u65f6\uff0c\u53ef\u4ee5\u4f7f\u7528 `git merge --squash` \u547d\u4ee4\uff1a\\n\\n```bash\\n# \u786e\u4fdd\u4f60\u5728 release \u5206\u652f\u4e0a\\n$ git checkout release\\n\\n# \u8fdb\u884c squash \u5408\u5e76\\n$ git merge feature --squash\\n\\n# \u5728\u89e3\u51b3\u5b8c\u6240\u6709\u51b2\u7a81\u540e\uff0c\u9700\u8981\u5c06\u5df2\u89e3\u51b3\u7684\u6587\u4ef6\u6dfb\u52a0\u5230\u6682\u5b58\u533a\\n$ git add .\\n\\n# \u63d0\u4ea4\u5408\u5e76\u7ed3\u679c\u4e3a\u4e00\u4e2a\u65b0\u7684\u5355\u4e2a commit\uff08\u6ce8\u610f\uff1a\u8fd9\u91cc\u6ca1\u6709\u81ea\u52a8\u63d0\u4ea4\uff0c\u9700\u8981\u624b\u52a8\u63d0\u4ea4\uff09\\n$ git commit -m \\"Squashed commit from feature-branch: Implemented XYZ feature\\"\\n```\\n\\n> \u6ce8\u610f\uff0c\u5728 GitLab \u63d0 Merge Request\uff0c\u53ef\u4ee5\u5728 Merge Request \u9875\u9762\u4e2d\u52fe\u9009 squash commit \u9009\u9879\\n\\n\u5408\u5e76\u4ee3\u7801\u9047\u5230\u51b2\u7a81\uff0c\u60f3\u56de\u9000\u5230\u5408\u5e76\u524d\u7684\u72b6\u6001\uff1a\\n\\n```bash\\n$ git merge --abort\\n```\\n\\n\u4e00\u4e2a\u5c0f\u6280\u5de7\uff0c`which` \u547d\u4ee4\u53ef\u4ee5\u7528\u6765\u67e5\u627e\u53ef\u6267\u884c\u6587\u4ef6\u7684\u8def\u5f84\uff1a\\n\\n```bash\\n$ which npm\\n\\n/Users/bytedance/.nvm/versions/node/v18.16.0/bin/npm\\n```\\n\\n[\u6846\u67b6\u4e2d\u7684\u7c7b\u578b\u7f16\u7a0b\uff1a Hono \u4e2d\u7684\u6a21\u677f\u5b57\u7b26\u4e32\u7c7b\u578b\u7f16\u7a0b](https://juejin.cn/post/7328564786596544523)\\n\\n[\u6846\u67b6\u4e2d\u7684\u7c7b\u578b\u7f16\u7a0b\uff1atRPC & Prisma \u4e2d\u7684\u6cdb\u578b\u5e94\u7528](https://juejin.cn/post/7328564786596528139)\\n\\n[React 19 \u5373\u5c06\u63a8\u51fa\u7684 4 \u4e2a\u5168\u65b0 Hooks\uff0c\u5f88\u5b9e\u7528\uff01](https://mp.weixin.qq.com/s/KFUikcgNvNw15wqM2wPHJw)\\n\\n[\u6211\u7528\u57cb\u70b9\u8ba9\u8001\u677f\u5b89\u9759 \uff08\u57cb\u70b9\u7bc7\uff09](https://mp.weixin.qq.com/s/1L75-L5eFFjuc4w0qBkXoQ)\\n\\n[Rust\u6027\u80fd\u5f88\u9ad8\uff1f\u4e0d\uff0c\u5b83\u5b8c\u5168\u9876\u4e0d\u4f4f\u6211\u7684\u4ee3\u7801](https://juejin.cn/post/7325993514701635638)\\n\\n[\\\\[\u8bd1\\\\]\u6df1\u5ea6\u89e3\u6790Webpack\u6253\u5305\u8fc7\u7a0b\uff082\u4e07\u5b57\u9884\u8b66\uff09](https://juejin.cn/post/7313423853223985167)\\n\\n[MDH Weekly 119 \u2013 \u300a\u5468\u520a\u91cd\u542f\u548c\u535a\u5ba2\u300b](https://mp.weixin.qq.com/s/3azGXsDFYoqaf0cWYlzDSw)"},{"id":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-21/index.md","source":"@site/blogs/2024/2024-01-21/index.md","title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-21T00:00:00.000Z","formattedDate":"January 21, 2024","tags":[],"readingTime":4.07,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u4e13\u8865\u5927\u6a21\u578b\u77ed\u677f\u7684RAG\u6709\u54ea\u4e9b\u65b0\u8fdb\u5c55\uff1f\u8fd9\u7bc7\u7efc\u8ff0\u8bb2\u660e\u767d\u4e86](https://mp.weixin.qq.com/s/yZo-HcGuWFQE8B63hZkqVQ)\\n\\n[\u7528\u68c0\u7d22\u589e\u5f3a\u751f\u6210\u8ba9\u5927\u6a21\u578b\u66f4\u5f3a\u5927\uff0c\u8fd9\u91cc\u6709\u4e2a\u624b\u628a\u624b\u7684Python\u5b9e\u73b0](https://mp.weixin.qq.com/s/RUdZjQMSlVOfHfhErSNXnA)\\n\\n[Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks](https://ar5iv.labs.arxiv.org/html/2005.11401)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u6162\u804aGolang\u534f\u7a0b\u6c60Ants\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/fZpPkG-C0wZ5Z45H2aUxAA)\\n\\n[Kubernetes Networking Model & CNI](https://mp.weixin.qq.com/s/zCJIZ8lkOmFCe_we2W7fow)\\n\\n[for-range\u4e00\u4e2a\u51fd\u6570\uff0c\u8fd8\u53ef\u4ee5\u8fd9\u4e48\u7528](https://mp.weixin.qq.com/s/NCoM7M1xSx_9gjhfPJhlYw)\\n\\n[\u8ddf\u6211\u4e00\u8d77\u7f16\u5199 Buildpacks\uff1aGo \u7248\u672c\u7bc7](https://mp.weixin.qq.com/s/u4nPO0oohpNlhxDLY92Qiw)\\n\\n[\u63a2\u7d22Cloud Native Buildpacks\u7684\u5947\u5999\u4e16\u754c](https://mp.weixin.qq.com/s/4E1tD-Gzsi196Q8ZxrioJA)\\n\\n[\u54c8\u5570\u4e91\u539f\u751f\u5f39\u6027\u4f38\u7f29\u63a7\u5236\u5668\u5b9e\u73b0\u7ec6\u8282](https://mp.weixin.qq.com/s/UnpVbcGFiVv3xM7K8wQUxA)\\n\\n[\u4f7f\u7528 Rust \u540e\uff0c\u6211\u5199 Go \u7684\u65b9\u6cd5\u90fd\u53d8\u4e86\uff01](https://mp.weixin.qq.com/s/YiCBaFZB5PlPvg8Z9E-tVg)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1aSlices \u53d8\u66f4 Concat\u3001Delete\u3001Insert \u7b49\u51fd\u6570\uff0c\u5bf9\u5f00\u53d1\u633a\u6709\u5e2e\u52a9\uff01](https://mp.weixin.qq.com/s/z886NFcGeKkNm97YhBhc7w)\\n\\n[Go \u7b80\u5355\u8bbe\u8ba1\u548c\u5b9e\u73b0\u53ef\u6269\u5c55\u3001\u9ad8\u6027\u80fd\u7684\u6cdb\u578b\u672c\u5730\u7f13\u5b58](https://mp.weixin.qq.com/s/XApYnOB2H1OhojLbWk_YAA)\\n\\n[Kubernetes HPA \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/vx8i-fPI8g1fT7GGSK41oQ)\\n\\n[\u4ece\u96f6\u5f00\u59cb\uff1a\u4f7f\u7528Prometheus\u4e0eGrafana\u642d\u5efa\u76d1\u63a7\u7cfb\u7edf](https://mp.weixin.qq.com/s/OROQH9DzwFLnfWKmKmrxsA)\\n\\n[\u5341\u5206\u949f\u6559\u4f60\u5728 k8s \u4e2d\u90e8\u7f72\u4e00\u4e2a\u524d\u540e\u7aef\u5e94\u7528](https://mp.weixin.qq.com/s/0JHQE0Ivm1qTopSkwsFs7g)\\n\\n[Go \u591c\u8bfb\u7b2c 149 \u671f\uff1a\u5982\u4f55\u8bbe\u8ba1\u73b0\u4ee3\u4e91\u539f\u751f\u7f51\u5173\uff1a Easegress](https://mp.weixin.qq.com/s/gUh6u8wSYcWPgvyquoqyaA)\\n\\n[Go Context \u5230\u5e95\u653e\u7b2c\u4e00\u4e2a\u53c2\u6570\u4f20\uff0c\u8fd8\u662f\u653e\u7ed3\u6784\u4f53\u91cc](https://mp.weixin.qq.com/s/2PLBKpPuRa5zMY7bJLJXqg)\\n\\n[\u4f18\u96c5\u5224\u65ad interface \u662f\u5426\u4e3a nil](https://mp.weixin.qq.com/s/g04NwXJrxNfHrHJTPKBrXw)\\n\\n[\u9ad8\u6548I/O\u5e76\u53d1\u5904\u7406\uff1a\u53cc\u7f13\u51b2\u548cExchanger](https://mp.weixin.qq.com/s/OrFw2yJuN-Syngpi6rLMzg)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[CPU\u4e2d\u7684\u9ad8\u79d1\u6280\uff1a\u6d41\u6c34\u7ebf\u3001\u8d85\u6807\u91cf\u3001SIMD](https://juejin.cn/post/7293122294788243467)\\n\\n[\u8ba9\u4f60\u7684\u4ee3\u7801\u8fd0\u884c\u66f4\u5feb\uff1a\u638c\u63e1\u96f6\u62f7\u8d1d\u6280\u672f](https://juejin.cn/post/7307146455537238043)\\n\\n[\u7535\u5546\u5e93\u5b58\u7cfb\u7edf\u7684\u9632\u8d85\u5356\u548c\u9ad8\u5e76\u53d1\u6263\u51cf\u65b9\u6848 | \u4eac\u4e1c\u4e91\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7263124928663683132)\\n\\n[\u5411\u4e0a\u7ba1\u7406\uff1a\u8ba9\u4f60\u4e3b\u52a8\u6c47\u62a5\u5c31\u8fd9\u4e48\u96be](https://mp.weixin.qq.com/s/FZ3oN-SARKV-BiCcuu4SLw)\\n\\n[RocketMQ \u4e8b\u52a1\u6d88\u606f\u521d\u4f53\u9a8c](https://mp.weixin.qq.com/s/H4Lf3ldi6ES5013WDjWtRg)\\n\\n[\u4e91\u97f3\u4e50\u670d\u52a1\u7aef\u53ef\u89c6\u5316\u7f16\u6392\u5e73\u53f0 TangoFlow \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/5vBKKCf_ZHPuHpWtC5Twjw)\\n\\n[\u516b\u5206\u949f\u4e86\u89e3\u4e00\u81f4\u6027\u7b97\u6cd5 -- Raft\u7b97\u6cd5](https://mp.weixin.qq.com/s/iZLKntKlG9847fglMt2A7w)\\n\\n[\u4ee3\u7801\u4e4b\u5916\uff1a\u5de5\u7a0b\u5e08\u7684\u6210\u957f\u8fdb\u9636\u79d8\u7c4d](https://mp.weixin.qq.com/s/FHCq-4yJOm8bT7yTiIkrow)\\n\\n[\u590d\u76d8\u603b\u7ed3\uff0c\u4e0d\u8981\u9519\u5931\u6700\u5927\u8d22\u5bcc](https://mp.weixin.qq.com/s/YU8PVqfoe-1-upazosJFhw)\\n\\n[\u4e3a\u4e86\u8ba9\u5c0f\u767d\u4e5f\u80fd\u770b\u61c2\u8fd9\u4e2a\u6b7b\u9501case\uff0c\u6211\u8bf7\u6765\u4e86\u5c0f\u9ed1](https://mp.weixin.qq.com/s/LqVlSVR6lG6-jGRdEvYixw)\\n\\n[\u963f\u91cc\u4e8c\u9762\uff1a\u8981\u4fdd\u8bc1\u6d88\u606f\u4e0d\u4e22\u5931\uff0c\u53c8\u4e0d\u91cd\u590d\uff0c\u6d88\u606f\u961f\u5217\u600e\u4e48\u9009\u578b](https://mp.weixin.qq.com/s/fvBfKDtZLxNdMWWSLJm_bQ)\\n\\n[SpringCloud \u8fdc\u7a0b\u8c03\u7528\u4e3a\u5565\u8981\u91c7\u7528HTTP\uff0c\u800c\u4e0d\u662fRPC](https://mp.weixin.qq.com/s/Yhn04560RVhYTPKEFDAbIw)\\n\\n[\u4e1a\u52a1\u578b\u56e2\u961f\u5f00\u53d1\u751f\u5b58\u6307\u5357](https://mp.weixin.qq.com/s/tMW3bneEd90ZcoP9VX0VBg)\\n\\n[DDD\u9886\u57df\u9a71\u52a8\u5de5\u7a0b\u843d\u5730\u5b9e\u6218](https://mp.weixin.qq.com/s/g6Zn9oFclF-3Py_VI9AUgQ)\\n\\n[\u652f\u4ed8\u5b9d\uff1a\u591a\u7ebf\u7a0b\u4e8b\u52a1\u600e\u4e48\u56de\u6eda\uff1f\u8bf4\u7528 @Transactional \u53ef\u4ee5\u56de\u53bb\u7b49\u901a\u77e5\u4e86\uff01](https://mp.weixin.qq.com/s/gSxZtSCdSYTHYQwOO9EaKQ)\\n\\n[DDD \u56db\u5c42\u5fae\u670d\u52a1\u67b6\u6784\uff0c\u5f00\u7bb1\u5373\u7528\uff01](https://mp.weixin.qq.com/s/GZRFyAy43AmMJlZiFXH48w)\\n\\n[2 \u4e07\u5b57 + 20\u5f20\u56fe\uff5c \u7ec6\u8bf4 Redis \u4e5d\u79cd\u6570\u636e\u7c7b\u578b\u548c\u5e94\u7528\u573a\u666f](https://mp.weixin.qq.com/s/r9_0xpRsp2ubgyvpiyMfuw)\\n\\n[Redis \u9664\u4e86\u7f13\u5b58\uff0c\u8fd8\u652f\u6301\u54ea\u4e9b\u573a\u666f](https://mp.weixin.qq.com/s/HaGsi29Qxflw0OAOi2dE7g)\\n\\n[Spring Boot + \u89c4\u5219\u5f15\u64ce URule\uff0c\u592a\u5f3a\u4e86\uff01](https://mp.weixin.qq.com/s/r_YJpPvjoz1xBeQQdiVEZw)\\n\\n[\u5355\u79df\u6237\u65f6\u4ee3\uff1aSaaS\u8303\u5f0f\u8f6c\u79fb](https://mp.weixin.qq.com/s/jKv9l_ro6rWei4QnXck-zw)\\n\\n[\u7cfb\u7edf\u7684\u53ef\u89c2\u5bdf\u6027\u662f\u6307\u4ec0\u4e48](https://mp.weixin.qq.com/s/ocxZ1BDiLpR5CT_JKABFNA)\\n\\n[\u4f60\u7ba1\u8fd9\u7834\u73a9\u610f\u513f\u53eb\u9ad8\u53ef\u7528](https://mp.weixin.qq.com/s/yy31QEaDNkhXcC4T9blxJA)\\n\\n[\u5982\u4f55\u5224\u65ad\u4e1a\u52a1\u505a\u4e0d\u505a\uff0c\u4ec0\u4e48\u662fUE\u6a21\u578b](https://mp.weixin.qq.com/s/aFI60g2nMn_u9kTZk6hjAA)\\n\\n[\u5e76\u53d1\u7f16\u7a0b\u768412\u6761\u89c4\u8303](https://mp.weixin.qq.com/s/crWQn2bT3AqtfmnK9PUKMQ)\\n\\n[\u6027\u80fd\u4f18\u53162.0\uff0c\u65b0\u589e\u7f13\u5b58\u540e\uff0c\u7a0b\u5e8f\u7684\u79d2\u5f00\u7387\u4e0d\u5347\u53cd\u964d](https://mp.weixin.qq.com/s/u_B0AjIi4y73_Yv-m6bNWA)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u524d\u7aef\u6027\u80fd\u4f18\u5316\u624b\u518c - RoadMap](https://mp.weixin.qq.com/s/sLT9Kot_LN4LQFV3STixAw)\\n\\n[React \u4ee3\u7801\u5982\u4f55\u8dd1\u5728\u5c0f\u7a0b\u5e8f\u4e0a](https://mp.weixin.qq.com/s/134VAXPJczElvdYzNFcHhA)\\n\\n[Taro\u7f16\u8bd1mini-runner\u5305\u7684\u4f5c\u7528](https://mp.weixin.qq.com/s/dqhKJQ_bMVfSj6RN0wOtCQ)\\n\\n[\u7a7f\u8d8a\u65f6\u7a7a\uff1a2023\u5e74\u524d\u7aef\u6280\u672f\u76d8\u70b9\u4e0e2024\u5e74\u6280\u672f\u5c55\u671b](https://mp.weixin.qq.com/s/LiygBJqMN8U_vSpAjxMibQ)\\n\\n[Monorepo \u9879\u76ee\u5b9e\u73b0\u5171\u4eab Tailwind \u914d\u7f6e](https://mp.weixin.qq.com/s/ChAhLD9pHfaGo2JIDfczqA)\\n\\n[\u524d\u7aef\u98df\u5802\u6280\u672f\u5468\u520a\u7b2c 111 \u671f\uff1aJS Rising Stars\u30012024 \u5e74\u5982\u4f55\u5199 CSS\u3001\u4e24\u4e2a React\u3001npm \u5e74\u5ea6\u56de\u987e](https://mp.weixin.qq.com/s/-AP9CJe8BRqHKfKUFR5QuA)"},{"id":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-14/index.md","source":"@site/blogs/2024/2024-01-14/index.md","title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-14T00:00:00.000Z","formattedDate":"January 14, 2024","tags":[],"readingTime":6.495,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b"},"nextItem":{"title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[\u4e2d\u4fe1\u5efa\u6295 | AI\u524d\u6cbf\u7cfb\u5217\uff08\u4e00\uff09\uff1a\u6df7\u5408\u4e13\u5bb6\u6a21\u578b\u6280\u672f\uff08MoE\uff09](https://mp.weixin.qq.com/s/KpRT1MCq7ewJw_Heb5-ZrA)\\n\\n[\u300a\u5f00\u6e90\u5927\u6a21\u578b\u98df\u7528\u6307\u5357\u300b\u53d1\u5e03\uff0c7\u4e2a\u5c0f\u65f6\uff0c\u4e00\u676f\u5976\u8336\u901f\u901a\u5927\u6a21\u578b\uff01](https://mp.weixin.qq.com/s/78mSLefUmZOagwZ5dMUyTg)\\n\\n[Stable Diffusion XL Turbo \u6587\u751f\u56fe\u548c\u56fe\u751f\u56fe\u5b9e\u8df5](https://mp.weixin.qq.com/s/0rS1qX37M-4FQT-d2DIsPw)\\n\\n[\u5728 Nvidia Docker \u5bb9\u5668\u7f16\u8bd1\u6784\u5efa\u663e\u5b58\u4f18\u5316\u52a0\u901f\u7ec4\u4ef6 xFormers](https://mp.weixin.qq.com/s/3TgTDsUHCs8tcNLcabqukg)\\n\\n[Amazing OpenAI API\uff1a\u628a\u975e OpenAI \u6a21\u578b\u90fd\u6309 OpenAI API \u8c03\u7528](https://mp.weixin.qq.com/s/Tw8Yr_illbY6MQO4sAMO7g)\\n\\n[\u8282\u7701\u65f6\u95f4\uff1aAI \u6a21\u578b\u9760\u8c31\u4e0b\u8f7d\u65b9\u6848\u6c47\u603b](https://mp.weixin.qq.com/s/5wiz-IaGhGFlbHmRdf1TUA)\\n\\n[\u4fee\u590d OpenCV \u4f9d\u8d56\u9519\u8bef\u7684\u5c0f\u5de5\u5177\uff1aOpenCV Fixer](https://mp.weixin.qq.com/s/PEHW4XJv0D2IN0W92CAi3A)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[Linux 6.8 \u7f51\u7edc\u4f18\u5316, \u5927\u91cf\u5e76\u53d1\u8fde\u63a5\u7684TCP\u6027\u80fd\u63d0\u9ad840%\u5de6\u53f3](https://mp.weixin.qq.com/s/Idp0blvp5WvKRkTw2nD1Xg)\\n\\n[\u6df1\u5165\u63a2\u7d22 Rust \u4e2d\u7684 Panic \u673a\u5236](https://juejin.cn/post/7314144983018782761)\\n\\n[\u63a2\u7a76 Go \u6e90\u7801\u4e2d panic & recover \u6709\u54ea\u4e9b\u5751](https://mp.weixin.qq.com/s/362o7pgILLEWL5NYVwz9Hw)\\n\\n[\u4ece\u300a100 Go Mistakes\u300b\u6211\u603b\u7ed3\u4e86\u4ec0\u4e48](https://mp.weixin.qq.com/s/wXq3Sy1L_ElfTmhLYJiiQw)\\n\\n[3.\u6df1\u5165TiDB\uff1a\u6267\u884c\u4f18\u5316\u8bb2\u89e3](https://mp.weixin.qq.com/s/IRk2lA9aGAa0KAdBY4oXjA)\\n\\n[\u4eb2\u6d4b\u4f53\u9a8cGo\u8bed\u8a00\u6a21\u7cca\u6d4b\u8bd5](https://mp.weixin.qq.com/s/C1YptWtsDw6YGepRpxFAQg)\\n\\n[Go \u53d1\u5e03\u4e86\u4e00\u4e2a\u975e\u5b89\u5168\u8865\u4e01\u7684 Go 1.21.6](https://mp.weixin.qq.com/s/qeEO2zK7mz9JUYocHetBHA)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1a\u65b0\u7684 math/rand/v2 \u5e93\uff0c\u66f4\u5feb\u66f4\u6807\u51c6\uff01](https://mp.weixin.qq.com/s/BsZeSDxHwwSzjLjfjUIgIA)\\n\\n[\u6bcf\u79d2\u767e\u4e07\u6570\u636e\u70b9 Go \u5e94\u7528\u76d1\u63a7\u7cfb\u7edf\u6f14\u8fdb](https://mp.weixin.qq.com/s/ezG3VQLgE2e0AWSxsoBHRg)\\n\\n[\u522b\u518d\u7528GDB\u4e86\uff0c\u4e00\u6587\u638c\u63e1Go\u6700\u597d\u7528\u7684\u8c03\u8bd5\u5668Delve](https://mp.weixin.qq.com/s/Ed39t5I0k0ynfPch-ex7Ag)\\n\\n[Kubernetes CronJob \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/ZNojELz-zTGybcpGgCtfng)\\n\\n[\\\\[go \u9762\u8bd5\\\\] \u5b9e\u73b0\u670d\u52a1\u9ad8\u53ef\u7528\u7684\u7b56\u7565\u548c\u5b9e\u8df5](https://mp.weixin.qq.com/s/-JBLJhU47kocCKXvBe-4uA)\\n\\n[\u6211\u662f\u5982\u4f55\u5b9e\u73b0Go\u6027\u80fd5\u500d\u63d0\u5347\u7684](https://mp.weixin.qq.com/s/HZCqoRgBcT3ZNAlnlChS-Q)\\n\\n[\u6df1\u5165\u7406\u89e3Go\u6807\u51c6\u5e93-ServeMux\u7684\u4f7f\u7528\u4e0e\u6a21\u5f0f\u5339\u914d](https://mp.weixin.qq.com/s/TU9FL2SVe5TW7Uq5I0o_Sg)\\n\\n[\u6df1\u5165\u7406\u89e3Go\u6807\u51c6\u5e93-http server\u7684\u542f\u52a8](https://mp.weixin.qq.com/s/s3BWg6iiCcDZRFh7oZJj5Q)\\n\\n[\u4f7f\u7528 Grafana \u548c Loki \u76d1\u63a7\u4f20\u8bf4\u4e2d\u7684\u6b66\u5f53\u7eb5\u4e91\u68af](https://mp.weixin.qq.com/s/fKFSOA0ZoFLN4dedlRp-HA)\\n\\n[Grafana \u6559\u7a0b - \u6784\u5efa\u4f60\u7684\u7b2c\u4e00\u4e2a\u4eea\u8868\u76d8](https://mp.weixin.qq.com/s/ivK0UmZjvtrJ_WyonwxN2w)\\n\\n[\u6210\u672c\u66f4\u4f4e\u3001\u66f4\u53ef\u63a7\uff0c\u4e91\u539f\u751f\u53ef\u89c2\u6d4b\u65b0\u8ba1\u8d39\u6a21\u5f0f\u6b63\u5f0f\u4e0a\u7ebf](https://mp.weixin.qq.com/s/AbggxNJXCMSAfmuIQ59E8A)\\n\\n[Kubernetes Job \u8bbe\u8ba1\u4e0e\u5b9e\u73b0](https://mp.weixin.qq.com/s/FTf4VK1CV-hgf_LgB0T8fA)\\n\\n[\u4f9d\u8d56Kafka\u7684Go\u5355\u5143\u6d4b\u8bd5\u4f8b\u89e3](https://mp.weixin.qq.com/s/M_lV7FaIMxZGd6pZ9dDaAw)\\n\\n[Go1.22 \u65b0\u7279\u6027\uff1afor \u5faa\u73af\u4e0d\u518d\u5171\u4eab\u5faa\u73af\u53d8\u91cf\uff0c\u4e14\u652f\u6301\u6574\u6570\u8303\u56f4](https://mp.weixin.qq.com/s/OnvniPEvDz6k5LLKGH1MFA)\\n\\n[Go\u8fd0\u884c\u65f6\u7684\u5e76\u53d1\u539f\u8bed](https://mp.weixin.qq.com/s/Lhw_VFL8UHD9edfbKt_QjQ)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#94 Not being aware of data alignment](https://mp.weixin.qq.com/s/yHWzh89g6Naz0xRmo5FdGw)\\n\\n[Go \u8bed\u8a00\u4e2d defer \u4f7f\u7528\u65f6\u6709\u54ea\u4e9b\u9677\u9631](https://mp.weixin.qq.com/s/g6ohhBBQd0u4PzD1KhnKCA)\\n\\n[Go\u8bed\u8a00\u4e4b\u7236\u7684\u53cd\u601d\uff1a\u6211\u4eec\u505a\u5bf9\u4e86\u4ec0\u4e48\uff0c\u505a\u9519\u4e86\u4ec0\u4e48](https://mp.weixin.qq.com/s/1BTdUMMPIMDobh1ZJ_gXAQ)\\n\\n[\u5b66\u4e60C++20, \u4e3aGo\u7684atomic\u7c7b\u578b\u63d2\u4e0a\u4e00\u53cc\u7fc5\u8180](https://mp.weixin.qq.com/s/Nbc_V5v5QruZsd1PVsDQnA)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[\u4e00\u5f20\u56fe\u603b\u7ed3\u67b6\u6784\u8bbe\u8ba1\u768440\u4e2a\u9ec4\u91d1\u6cd5\u5219](https://mp.weixin.qq.com/s/eDEjSdf93HE35ndVPpH13A)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898 \u2014 \u67b6\u6784\u8bbe\u8ba1\u7bc7](https://mp.weixin.qq.com/s/Qwj4S4r9Mayy5_HG3ubw7w)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014Spring\u7bc7](https://mp.weixin.qq.com/s/faEtlyaNHW9AWE6LMTs4Ng)\\n\\nmysql \u7684 binlog\u3001redolog\u3001undolog \u662f\u5565\uff1a\\n\\n- Binlog\uff08\u4e8c\u8fdb\u5236\u65e5\u5fd7\uff09\uff1a\\n - \u7528\u4e8e\u590d\u5236\uff1a\u5728\u4e3b\u4ece\u590d\u5236\u4e2d\uff0c\u4ece\u6570\u636e\u5e93\u4f1a\u91cd\u653e\u4e3b\u6570\u636e\u5e93\u4e2d\u5b58\u50a8\u7684 binlog\uff0c\u4ee5\u5b9e\u73b0\u4e3b\u4ece\u540c\u6b65\u3002\\n - \u6570\u636e\u5e93\u6062\u590d\uff1abinlog \u53ef\u4ee5\u7528\u4e8e\u6570\u636e\u5e93\u7684\u6309\u65f6\u95f4\u70b9\u8fd8\u539f\u3002\\n- Redo log\uff08\u91cd\u505a\u65e5\u5fd7\uff09\uff1a\\n - \u786e\u4fdd\u4e8b\u52a1\u7684\u6301\u4e45\u6027\uff1a\u5728\u4e8b\u52a1\u63d0\u4ea4\u524d\uff0credo log \u4f1a\u5c06\u4e8b\u52a1\u7684\u4fee\u6539\u64cd\u4f5c\u8bb0\u5f55\u4e0b\u6765\uff0c\u4ee5\u786e\u4fdd\u5728\u7cfb\u7edf\u5d29\u6e83\u6216\u91cd\u542f\u65f6\uff0c\u53ef\u4ee5\u91cd\u65b0\u6267\u884c\u8fd9\u4e9b\u64cd\u4f5c\u3002\\n - \u9632\u6b62\u810f\u9875\u5199\u5165\uff1a\u5728\u7cfb\u7edf\u5d29\u6e83\u65f6\uff0credo log \u53ef\u4ee5\u9632\u6b62\u810f\u9875\uff08\u672a\u63d0\u4ea4\u7684\u6570\u636e\u9875\uff09\u88ab\u5199\u5165\u78c1\u76d8\u3002\\n- Undo log\uff08\u64a4\u9500\u65e5\u5fd7\uff09\uff1a\\n - \u7528\u4e8e\u4e8b\u52a1\u7684\u56de\u6eda\uff1a\u5728\u4e8b\u52a1\u6267\u884c\u8fc7\u7a0b\u4e2d\uff0cundo log \u8bb0\u5f55\u4e86\u4e8b\u52a1\u4fee\u6539\u524d\u7684\u6570\u636e\u7248\u672c\uff0c\u4ee5\u4fbf\u5728\u4e8b\u52a1\u56de\u6eda\u65f6\u6062\u590d\u6570\u636e\u3002\\n - \u591a\u7248\u672c\u5e76\u53d1\u63a7\u5236\uff08MVCC\uff09\uff1aundo log \u652f\u6301\u6570\u636e\u5e93\u7684\u591a\u7248\u672c\u5e76\u53d1\u63a7\u5236\u673a\u5236\uff0c\u5141\u8bb8\u4e8b\u52a1\u5728\u4e0d\u52a0\u9501\u7684\u60c5\u51b5\u4e0b\u8bfb\u53d6\u4e00\u81f4\u7684\u6570\u636e\u3002\\n\\n\u8fd9\u4e9b\u65e5\u5fd7\u6587\u4ef6\u5728 MySQL \u4e2d\u626e\u6f14\u7740\u4e0d\u540c\u7684\u89d2\u8272\uff0c\u786e\u4fdd\u4e86\u6570\u636e\u5e93\u7684\u4e00\u81f4\u6027\u3001\u6301\u4e45\u6027\u548c\u5e76\u53d1\u63a7\u5236\u3002\\n\\n[\u4f7f\u7528\u61d2\u52a0\u8f7d + \u96f6\u62f7\u8d1d\u540e\uff0c\u7a0b\u5e8f\u7684\u79d2\u5f00\u7387\u63d0\u5347\u81f399.99%](https://mp.weixin.qq.com/s/kaogMK5qz5vkfs9-BYu0Mg)\\n\\n[\u4e07\u5b57+20\u5f20\u56fe\u63a2\u79d8Nacos\u6ce8\u518c\u4e2d\u5fc3\u6838\u5fc3\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/NYH6jgDOp1MwnAUyUHM5yg)\\n\\n[7000\u5b57+30\u5f20\u56fe\u770b\u61c2\u5206\u5e03\u5f0f\u8ffd\u8e2a\u7cfb\u7edf\u539f\u7406](https://mp.weixin.qq.com/s/8CYXOML5LvRlFRpNFOQCjw)\\n\\n[\u62d2\u7edd\u7528\u590d\u6742\u5ea6\u81ea\u6170\uff1a\u4e0b\u4e91\u9ad8\u53ef\u7528\u7684\u79d8\u8bc0](https://mp.weixin.qq.com/s/yIVal-9U6_TXX-dZpVtjBg)\\n\\n[\u516c\u53f8\u4e3a\u4ec0\u4e48\u8981\u4f7f\u7528OKR\uff0c\u76ee\u7684\u662f\u4ec0\u4e48](https://mp.weixin.qq.com/s/L-pb5GgWSVJsJa_nnWMVQQ)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1a\u8bf4\u8bf4Rocketmq\u63a8\u6a21\u5f0f\u3001\u62c9\u6a21\u5f0f](https://mp.weixin.qq.com/s/gnRiDUhAvTgjXaQiROB66A)\\n\\n[\u5206\u5e03\u5f0f\u4e8b\u52a1\u6982\u8ff0\u4e0e\u9879\u76ee\u5b9e\u6218](https://mp.weixin.qq.com/s/0Io-X0S9AY-s0HeRb_jbag)\\n\\n[\u5206\u5e03\u5f0f\u9501\u6700\u7ec8\u89e3\u51b3\u65b9\u6848\u662fRedLock\u5417\uff1f\u4e3a\u4ec0\u4e48](https://mp.weixin.qq.com/s/lbSJAv8zJ7NG4G3beNExUA)\\n\\n[\u5237\u4e86\u56db\u767e\u9053\u7b97\u6cd5\u9898\uff0c\u6211\u5728\u9879\u76ee\u91cc\u7528\u8fc7\u51e0\u9053\u5462](https://mp.weixin.qq.com/s/Xna4EDDPvg3vmMUgmsNewQ)\\n\\n[\u70c2\u5927\u8857\u7684\u7f13\u5b58\u7a7f\u900f\u3001\u7f13\u5b58\u51fb\u7a7f\u548c\u7f13\u5b58\u96ea\u5d29\uff0c\u4f60\u771f\u7684\u61c2\u4e86](https://mp.weixin.qq.com/s/MsU0eNt4k7WqpBOQ8CAotA)\\n\\n[\u6296\u97f3\u63d0\u524d\u6279\u4e8c\u9762\uff1a\u4e3a\u5565\u4e0d\u63a8\u8350\u4f7f\u7528\u5916\u952e](https://mp.weixin.qq.com/s/4Q7FzxgkqYCb5fGOARhvDg)\\n\\n[\u589e\u52a0\u7d22\u5f15 + \u5f02\u6b65 + \u4e0d\u843d\u5730\u540e\uff0c\u4ece 12h \u4f18\u5316\u5230 15 min](https://mp.weixin.qq.com/s/V2p_p-KoDowlZxLN2by2Sg)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u6709\u4e86\u5b83 Antd \u6837\u5f0f\u8986\u76d6\u4e0d\u8981\u592a\u723d](https://mp.weixin.qq.com/s/0Tr3tNwl2wwZ3mVqB97mQg)\\n\\n[\u4e00\u6587\u5e26\u4f60\u4ece0\u52301\u505a\u6027\u80fd\u4f18\u5316\u2014\u2014\u56fd\u9645\u5316\u4e1a\u52a1\u4e2d\u53f0\u6027\u80fd\u4f18\u5316\u5b9e\u8df5\uff08\u4e0a\uff09](https://mp.weixin.qq.com/s/SZ-PHb5Mi3KnaEo3yNjR7g)\\n\\nBun \u5982\u4f55\u8bbe\u7f6e npm registry\uff0c\u6709\u65f6\u4f1a\u7528\u5230 bunx \u547d\u4ee4\uff0c\u4f1a\u81ea\u52a8\u4e0b\u8f7d npm \u5305\uff0c\u56e0\u6b64\u9700\u8981\u914d\u7f6e npm registry\uff1a\\n\\n```bash\\n# \u5728\u6839\u76ee\u5f55\u5efa\u4e00\u4e2a `.bunfig.toml` \u914d\u7f6e\u6587\u4ef6\\n$ vi $HOME/.bunfig.toml\\n```\\n\\n\u5199\u5165\u5982\u4e0b\u5185\u5bb9\uff1a\\n\\n```toml\\n[install]\\n# set default registry as a string\\nregistry = \\"https://registry.npmjs.org\\"\\n```\\n\\n> \u53c2\u8003\uff1ahttps://bun.sh/docs/install/registries\\n\\n[\u4e24\u4e2a React](https://mp.weixin.qq.com/s/AKdqtR6DWxB-c4CCmz594g)\\n\\n[2024 \u5e74\u524d\u7aef\u9884\u6d4b](https://mp.weixin.qq.com/s/BO29XPm7c9VKcQT_v9lOGw)\\n\\n[\u4e1a\u52a1\u4e2d\u540e\u53f0\u7528\u6237\u4f53\u9a8c\u4f18\u5316\u65b9\u6cd5\u8bba\u603b\u7ed3\uff08\u4f53\u9a8c\u7bc7\uff09](https://mp.weixin.qq.com/s/vXQR_eTKAYI3_ylXxQJTLA)\\n\\n[\u5206\u4eab4 \u4e2a\u4f60\u53ef\u80fd\u611f\u5174\u8da3\u7684 TikTok \u524d\u7aef\u9762\u8bd5\u9898](https://mp.weixin.qq.com/s/0bzsHVqxoyl9uth3iymp0A)\\n\\n[Chrome \u4e09\u65b9 Cookie \u7981\u7528\u5df2\u6b63\u5f0f\u5f00\u59cb\uff01](https://mp.weixin.qq.com/s/9O7D5mugTmnUuMinQmaEOw)\\n\\n[\u4f7f\u7528 Taro \u5f00\u53d1\u9e3f\u8499\u539f\u751f\u5e94\u7528 \u2014\u2014 \u5feb\u901f\u4e0a\u624b\uff0c\u9e3f\u8499\u5e94\u7528\u5f00\u53d1\u6307\u5357](https://mp.weixin.qq.com/s/FcQocQdxeaQijAA6oUjAZg)"},{"id":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","metadata":{"permalink":"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","editUrl":"https://github.com/facebook/docusaurus/edit/main/website/blog/blogs/2024/2024-01-07/index.md","source":"@site/blogs/2024/2024-01-07/index.md","title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","description":"\ud83c\udf1f AI \u76f8\u5173","date":"2024-01-07T00:00:00.000Z","formattedDate":"January 7, 2024","tags":[],"readingTime":9.405,"hasTruncateMarker":false,"authors":[{"name":"\u52a0\u83f2\u732b","title":"\u524d\u7aef\u5f00\u53d1 @NETEASE","url":"https://github.com/Jiacheng787","imageURL":"https://frontend-weekly.oss-cn-hangzhou.aliyuncs.com/img/IMG_0687.JPG","key":"garfield"}],"frontMatter":{"slug":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","title":"1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","authors":["garfield"],"tags":[]},"prevItem":{"title":"1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","permalink":"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b"}},"content":"## \ud83c\udf1f AI \u76f8\u5173\\n\\n[GPT-4 Technical Report](https://ar5iv.labs.arxiv.org/html/2303.08774)\\n\\n[Today\'s top trending papers in Computer Science](https://trendingpapers.com/papers?o=pagerank_growth&pd=Since%20beginning&cc=Cited%20and%20uncited%20papers&c=All%20categories)\\n\\n## \u2b50\ufe0f Go & \u4e91\u539f\u751f & Rust \u76f8\u5173\\n\\n[\u5c0f\u7ea2\u4e66\u53ef\u89c2\u6d4b Metrics \u67b6\u6784\u6f14\u8fdb\uff0c\u5982\u4f55\u5b9e\u73b0\u6570\u5341\u500d\u6027\u80fd\u63d0\u5347](https://mp.weixin.qq.com/s/uJ1t0B8WBBryzvbLWDfl5A)\\n\\n[Java\u4e0eGo\u5230\u5e95\u5dee\u522b\u5728\u54ea\uff0c\u8c01\u8981\u88ab\u65f6\u4ee3\u629b\u5f03](https://mp.weixin.qq.com/s/JkpzM06IWNb11wUaJWJn8Q)\\n\\n\u65e2\u7136\u95ee\u9898\u662f GC \u5360\u7528\u7684 CPU \u8fc7\u9ad8\uff0c\u9996\u5148\u6211\u4eec\u5206\u6790\u4e00\u4e0b CPU \u70ed\u70b9\uff0c\u8fdb\u4e00\u6b65\u786e\u8ba4\u4e00\u4e0b\u95ee\u9898\u3002\\n\\n```bash\\n$ go tool pprof -seconds 30 https://<\u6d4b\u8bd5\u57df\u540d>/debug/pprof/profile\\n```\\n\\n\u8fd9\u4e2a\u547d\u4ee4\u7528\u4e8e\u8fdb\u884c 30s \u7684 CPU \u6027\u80fd\u5206\u6790\uff0c\u5728\u5b8c\u6210\u4e4b\u540e\u4f1a\u8fdb\u5165 profile \u7684\u4ea4\u4e92\u5de5\u5177\uff1a\\n\\n![Alt text](image.png)\\n\\n\u8fd9\u91cc\u76f4\u63a5\u8f93\u5165 top 10 \u53ef\u4ee5\u8f93\u51fa flat \u5360\u6bd4\u6700\u9ad8\u7684 10 \u4e2a\u51fd\u6570\uff0c\u53ef\u4ee5\u770b\u5230 runtime.mallocgc \u7684 cum \u5360\u6bd4\u5df2\u7ecf\u8fbe\u5230\u4e86 15%\uff0c\u5360\u7528\u4e86\u5feb\u5230 3s CPU \u65f6\u95f4\u3002\\n\\nFlat vs Cum\uff1a\\n- Flat \u5360\u6bd4\u662f\u6307\u8fd9\u4e2a\u51fd\u6570\u81ea\u8eab\u7684\u4ee3\u7801\u4f7f\u7528\u4e86\u591a\u5c11 CPU\uff0c\u4e0d\u8ba1\u7b97\u5b50\u51fd\u6570\u7684\u8017\u65f6\u3002\\n- \u800c Cum \u5219\u4ee3\u8868\u8fd9\u4e2a\u51fd\u6570\u5b9e\u9645\u6267\u884c\u6d88\u8017\u4e86\u591a\u5c11 CPU\uff0c\u4e5f\u5c31\u662f\u5305\u62ec\u4e86\u6240\u6709\u7684\u5b50\u51fd\u6570\uff08\u548c\u5b50\u51fd\u6570\u7684\u5b50\u51fd\u6570...\uff09\u7684\u8017\u65f6\u3002\\n\\n\u4ea4\u4e92\u5de5\u5177\u8fd9\u91cc\u8f93\u5165 web \u5c31\u4f1a\u81ea\u52a8\u751f\u6210\u8c03\u7528\u56fe\uff08callgraph\uff09\u5e76\u5728\u6d4f\u89c8\u5668\u91cc\u6253\u5f00 \uff0c\u9650\u4e8e\u6587\u6863\u7a7a\u95f4\u8fd9\u91cc\u53ea\u5c55\u793a\u91cd\u8981\u7684\u90e8\u5206 \uff1a\\n\\n![Alt text](image-1.png)\\n\\n\u5148\u5206\u6790\u4e00\u4e0b\u4e3b\u6d41\u7a0b\uff0c\u8fd9\u91cc\u4e1a\u52a1\u903b\u8f91\u4e00\u5171\u5360\u7528\u4e86 54% \u5de6\u53f3\u7684 CPU\uff08\u6700\u4e0a\u9762\u7684 endpoint.handler \u65b9\u6cd5\uff09\uff0c\u518d\u5f80\u4e0b\u770b\uff0c\u5176\u4e2d 33% \u662f RPC \u8c03\u7528\uff08\u5de6\u4e0b\u89d2\u7684 client.Invoke\uff09\uff0c12% \u662f\u7ed3\u679c\u8f93\u51fa\uff08\u53f3\u8fb9\u7684 endpoint.httpOutput\uff0c\u5305\u62ec\u5199\u51fa HTTP Response\uff0c\u65e5\u5fd7\u4e0a\u62a5\uff0c\u76d1\u63a7\uff09\u3002\u5269\u4e0b 9% \u5de6\u53f3\u5c31\u662f\u5b9e\u9645\u7684\u5404\u79cd\u4e1a\u52a1\u903b\u8f91\u4e86\uff0c\u56e0\u4e3a\u975e\u5e38\u5206\u6563\u4e14\u6ca1\u6709\u96c6\u4e2d\u7684\u70b9\uff0c\u6240\u4ee5\u56fe\u4e0a\u6ca1\u6709\u663e\u793a\u51fa\u6765\u3002\\n\\n\u7eb5\u89c2\u8fd9\u4e2a\u56fe\u53ef\u4ee5\u770b\u51fa\uff0c\u9664\u4e86 HTTP/RPC \u7f51\u7edc\u8c03\u7528\u5360\u7528\u4e86\u5927\u90e8\u5206 CPU \u5916\uff0c\u5e76\u6ca1\u6709\u5176\u4ed6\u5f88\u660e\u663e\u7684 CPU \u70ed\u70b9\uff0c\u8fd9\u5c31\u8ba9\u6700\u540e\u4e00\u4e2a\u70ed\u70b9\u51f8\u663e\u4e86\u51fa\u6765\uff1a\\n\\n![Alt text](image-2.png)\\n\\nGC \u5360\u7528\u7684 CPU \u5728\u8fd9\u6b21 Profiling \u8fc7\u7a0b\u4e2d\u5360\u4e86 15%\uff0c\u6bd4\u4e1a\u52a1\u903b\u8f91\u8fd8\u9ad8\uff01\u5230\u8fd9\u91cc\u57fa\u672c\u786e\u8ba4\uff0cGC \u4e00\u5b9a\u5b58\u5728\u67d0\u4e9b\u95ee\u9898\u3002\\n\\n\u6211\u4eec\u53ef\u4ee5\u7528\u53e6\u4e00\u4e2a pprof \u5de5\u5177 allocs \u6765\u786e\u8ba4\u731c\u6d4b\u662f\u5426\u6210\u7acb\uff0c\u8fd9\u4e2a\u5de5\u5177\u4f1a\u8bb0\u5f55\u5806\u4e0a\u7684\u5bf9\u8c61\u521b\u5efa\u548c\u5185\u5b58\u5206\u914d\uff0c\u53ea\u9700\u8981\u628a\u4e0a\u9762\u7684 HTTP Path \u6700\u540e\u7684 profile \u6362\u6210 allocs \u5373\u53ef\uff1a\\n\\n```bash\\n$ go tool pprof -seconds 30 https://<\u6d4b\u8bd5\u57df\u540d>/debug/pprof/allocs\\n```\\n\\n\u548c CPU Profile \u4e0d\u4e00\u6837\uff0cAllocs \u7684 Profile \u4f1a\u8bb0\u5f55\u56db\u4e2a\u4e0d\u540c\u7684\u4fe1\u606f\uff0c\u53ef\u4ee5\u8f93\u5165 o \u67e5\u770b sample_index \u7684\u53ef\u9009\u503c\uff1a\\n\\n![Alt text](image-3.png)\\n\\n- alloc_object\uff1a\u65b0\u5efa\u5bf9\u8c61\u6570\u91cf\u8bb0\u5f55\uff1b\\n- alloc_space\uff1a\u5206\u914d\u7a7a\u95f4\u5927\u5c0f\u8bb0\u5f55\uff1b\\n- inuse_object\uff1a\u5e38\u9a7b\u5185\u5b58\u5bf9\u8c61\u6570\u91cf\u8bb0\u5f55\uff1b\\n- inuse_space\uff1a\u5e38\u9a7b\u5185\u5b58\u7a7a\u95f4\u5927\u5c0f\u8bb0\u5f55\u3002\\n\\n\u4e00\u822c\u6765\u8bf4\uff0cinuse \u76f8\u5173\u7684\u8bb0\u5f55\u53ef\u4ee5\u7528\u4e8e\u6392\u67e5\u5185\u5b58\u6cc4\u6f0f\uff0cOOM \u7b49\u95ee\u9898\u3002\u8fd9\u91cc\u6211\u4eec\u662f GC \u7684\u95ee\u9898\uff0c\u4e3b\u8981\u548c\u5185\u5b58\u7533\u8bf7\u548c\u91ca\u653e\u6709\u5173\uff0c\u6240\u4ee5\u5148\u770b\u4e0b alloc_space\uff1a\\n\\n\u8f93\u5165\u547d\u4ee4\uff0csample_index=alloc_space\uff0c\u7136\u540e\u518d top 10 \u770b\u4e0b\uff1a\\n\\n![Alt text](image-4.png)\\n\\n\u53ef\u4ee5\u53d1\u73b0\uff0c\u8fd9 30s \u4e00\u5171\u7533\u8bf7\u4e86 1300M \u7684\u5185\u5b58\uff0c\u5176\u4e2d\u7edd\u5927\u591a\u6570\u90fd\u662f\u6846\u67b6\u548c\u6846\u67b6\u7ec4\u4ef6\uff0c\u6bd4\u5982 RPC \u7684\u7f51\u7edc\u8bfb\u53d6\uff08consumeBytes, ReadFrame\uff09\uff0cpb \u7684\u89e3\u6790\u548c\u5e8f\u5217\u5316\uff08marshal\uff09\uff0c\u540d\u5b57\u670d\u52a1\u7684\u9009\u5740\uff08Select\uff09\uff0c\u65e5\u5fd7\u8f93\u51fa\uff08log\uff09\uff0c\u76d1\u63a7\u4e0a\u62a5\uff08ReportAttr\uff09\u3002\u4e5f\u6ca1\u6709\u660e\u663e\u7684\u53ef\u7591\u5bf9\u8c61\u3002\\n\\n\u6211\u4eec\u8fdb\u884c\u4e00\u4e9b\u7b80\u5355\u8ba1\u7b97\uff1a\u8fdb\u884c profiling \u7684\u7ebf\u4e0a\u8282\u70b9\u662f 2C2G \u914d\u7f6e\uff0c\u770b\u76d1\u63a7\u5355\u8282\u70b9\u5927\u7ea6\u662f 800 QPS \u7684\u6d41\u91cf\uff0c\u6240\u4ee5 30s \u5c31\u662f 2w4 \u7684\u8bf7\u6c42\uff0c\u7533\u8bf7\u4e86 1300M \u7684\u7a7a\u95f4\uff0c\u5e73\u5747\u4e00\u4e2a\u8bf7\u6c42\u5c31\u662f\u5927\u7ea6 50KB \u5de6\u53f3\u3002\\n\\n\u8fd9\u4e2a\u91cf\u4e5f\u6bd4\u8f83\u5408\u7406\uff0c\u6bd5\u7adf\u4e00\u6b21\u8bf7\u6c42\u6211\u4eec\u9700\u8981\u50a8\u5b58 HTTP \u5305\u5185\u5bb9\uff0c\u89e3\u6790\u6210\u7ed3\u6784\u4f53\uff0c\u8fd8\u9700\u8981\u8c03\u7528\u4e24\u6b21 RPC \u63a5\u53e3\uff0c\u6700\u540e\u505a\u65e5\u5fd7\u5199\u51fa\u548c\u76d1\u63a7\u4e0a\u62a5\uff0c\u6700\u540e\u518d\u7ed9\u51fa\u8fd4\u56de\u503c\uff0c50KB \u7684\u8d44\u6e90\u4f7f\u7528\u5e76\u4e0d\u7b97\u5927\u3002\u800c\u4e14\u7edd\u5927\u591a\u6570\u90fd\u662f\u6846\u67b6\u4f7f\u7528\uff0c\u5373\u4f7f\u7528\u5bf9\u8c61\u6c60\u628a\u4e1a\u52a1\u4e0a\u7684\u4e00\u4e9b\u5c0f\u5bf9\u8c61\u590d\u7528\uff0c\u5bf9\u8fd9\u4e2a\u5185\u5b58\u7533\u8bf7\u4e5f\u5f71\u54cd\u4e0d\u5927\u3002\\n\\n\u867d\u7136\u8fd9\u4e2a\u6b65\u9aa4\u6ca1\u6709\u6392\u67e5\u5230\u60f3\u67e5\u7684\u95ee\u9898\uff0c\u4f46\u662f\u5374\u53d1\u73b0\u4e86\u4e00\u4e9b\u5176\u4ed6\u7684\u4ee3\u7801\u4e2d\u7684\u5c0f\u95ee\u9898\uff0c\u8fd9\u91cc\u4e5f\u987a\u4fbf\u8bb0\u5f55\u4e0b\u3002\\n\\n\u9996\u5148\uff0c\u4e0a\u9762\u7684 top 10 \u770b\u4e0d\u51fa\u4efb\u4f55\u95ee\u9898\uff0c\u4f46\u662f\u4e3a\u4e86\u4fdd\u9669\u8d77\u89c1\uff0c\u770b\u4e86\u4e00\u4e0b top 20\uff1a\\n\\n![Alt text](image-5.png)\\n\\n\u8fd9\u91cc\u6709\u4e09\u4e2a\u6211\u4eec\u4e1a\u52a1\u4ee3\u7801\u91cc\u7684\u51fd\u6570\uff0cflat \u90fd\u5f88\u5c11\uff0c\u5360\u6bd4\u52a0\u8d77\u6765\u4e5f\u4e0d\u5230 4.5%\uff0c\u4e0d\u8fc7\u65e2\u7136\u53d1\u73b0\u4e86\u4ed6\u4eec \uff0c\u5c31\u6df1\u5165\u770b\u4e00\u4e0b\u51fd\u6570\u91cc\u5404\u884c\u7684\u5206\u914d\u60c5\u51b5\uff0c\u770b\u770b\u6709\u6ca1\u6709\u4ec0\u4e48\u95ee\u9898\u3002\\n\\n[\u53ea\u6539\u4e00\u4e2a\u53c2\u6570\u8ba9Golang GC\u8017\u65f6\u66b4\u964d\u52301/30\uff01](https://mp.weixin.qq.com/s/EEDNuhEr0G4SbTzDhVBjbg)\\n\\n[\u5b57\u8282\u8df3\u52a8\u4e91\u539f\u751f\u6210\u672c\u6cbb\u7406\u843d\u5730\u5b9e\u8df5](https://mp.weixin.qq.com/s/GFYudlHBuIr_bDe6IX4mlw)\\n\\n[Go \u7684 DDD \u5de5\u7a0b\u5316\u9879\u76ee\u5b9e\u8df5](https://juejin.cn/post/7298160530292703244)\\n\\n[Rust \u7684\u6240\u6709\u6743\u3001\u501f\u7528\u548c\u751f\u547d\u5468\u671f](https://juejin.cn/post/7279313746450235403)\\n\\n[Kubernetes Deployment \u6eda\u52a8\u66f4\u65b0\u5b9e\u73b0\u539f\u7406](https://mp.weixin.qq.com/s/c4LWdwACitC2gH2tDu3E8g)\\n\\n[\\\\[go \u9762\u8bd5\\\\] \u5206\u5e03\u5f0f\u4e8b\u52a1\u6846\u67b6\u9009\u62e9\u4e0e\u5b9e\u8df5](https://mp.weixin.qq.com/s/vQz2-KhRenuimU7jvHtkkQ)\\n\\n[\u6211\u662f\u5982\u4f55\u5b9e\u73b0Go\u6027\u80fd5\u500d\u63d0\u5347\u7684](https://mp.weixin.qq.com/s/SlPdSoMs1po1l19uaNMrIQ)\\n\\n[\u5b8c\u5584 Golang Gin \u6846\u67b6\u7684\u9759\u6001\u4e2d\u95f4\u4ef6\uff1aGin-Static](https://mp.weixin.qq.com/s/4ZT1Pu_lR56LmIQjFmy9Kg)\\n\\n[Kubernetes \u4e3a\u4ec0\u4e48\u9700\u8981 Ingress](https://mp.weixin.qq.com/s/uuB97dnIHe0hxsoBrk6THg)\\n\\n[Uber Go \u51fa\u4e86\u4e2a\u9759\u6001\u5206\u6790\u5de5\u5177 NilAway\uff0c\u8fd8\u633a\u5b9e\u7528\uff01](https://mp.weixin.qq.com/s/vDmSnZZXg1EnyeFMuj6orw)\\n\\n[Go\u8bed\u8a00\u4e2d\u5e38\u89c1100\u95ee\u9898-#93 Not taking into account instruction-level](https://mp.weixin.qq.com/s/oVSJz7MIUR7HNhU-hKnCJg)\\n\\n[Rust\u4f7f\u7528gRPC](https://mp.weixin.qq.com/s/a_v6_F6nqGlDcBUKyEQF2w)\\n\\n[\u8fd9\u4e9b\u6d41\u884c\u7684K8S\u5de5\u5177\uff0c\u4f60\u90fd\u7528\u4e0a\u4e86\u5417](https://mp.weixin.qq.com/s/6bgFUadhbCqDAwNgGsXgGg)\\n\\n[Go\u6d4b\u8bd5\u768420\u4e2a\u5b9e\u7528\u5efa\u8bae](https://mp.weixin.qq.com/s/yJqwcYqYmV1wWuo147fX4Q)\\n\\n[\u300e\u6bcf\u5468\u8bd1Go\u300fGo \u7684\u62a2\u5360\u5f0f\u8c03\u5ea6\uff08\u6587\u672b\u6709\u5f69\u86cb\uff09](https://mp.weixin.qq.com/s/d7FdGBc0S0V3S4aRL4EByA)\\n\\n[\u4e86\u89e3go\u5728\u534f\u7a0b\u8c03\u5ea6\u4e0a\u7684\u6539\u8fdb](https://mp.weixin.qq.com/s/YXxFVBrwlwf3YpIUhXFmTQ)\\n\\n[Go \u8bed\u8a00\u4e3a\u4ec0\u4e48\u4e0d\u652f\u6301\u5e76\u53d1\u8bfb\u5199 map](https://mp.weixin.qq.com/s/n6K6tbDRdS5c0hMtmHxdFg)\\n\\n[\u7b2c\u4e00\u7bc7 \u65e7\u8bdd\u91cd\u63d0\uff1a\u83b7\u53d6\u548c\u5229\u7528 goroutine id, machine id \u548c process id](https://mp.weixin.qq.com/s/dePs661VzQf_yi2aHsydIA)\\n\\n## \ud83d\udcd2 \u540e\u7aef\u76f8\u5173\\n\\n[HBase\u6df1\u5ea6\u5386\u9669 | \u4eac\u4e1c\u7269\u6d41\u6280\u672f\u56e2\u961f](https://juejin.cn/post/7315959676886450211)\\n\\n\u9879\u76ee\u4e2d\u9047\u5230\u4e00\u4e2a\u95ee\u9898\uff0c\u9700\u8981\u8bb0\u4f4f\u5f39\u7a97\u9891\u63a7\uff0c\u4e00\u822c\u6765\u8bf4\u8ddf\u7740\u8bbe\u5907\u8d70\uff0c\u4e5f\u5c31\u662f\u5728\u524d\u7aef\u7f13\u5b58\u3002\u5982\u679c\u9700\u8981\u4ee5\u7528\u6237\u7ef4\u5ea6\uff0c\u9700\u8981\u600e\u4e48\u8bbe\u8ba1\uff0c\u53ef\u4ee5\u7528 Redis Bitmap \u5b9e\u73b0\u3002\\n\\n[Redis Bitmap\uff1a\u5b9e\u73b0\u5343\u4e07\u7ea7\u7528\u6237\u7b7e\u5230\u7684\u79d8\u5bc6\u6b66\u5668](https://juejin.cn/post/7273025562155466764)\\n\\n[\u8fd9\u4e9b\u5e74\u5728\u963f\u91cc\u5b66\u5230\u7684\u65b9\u6cd5\u8bba](https://mp.weixin.qq.com/s/yPRPakU1UM5iVY-1bwiHJQ)\\n\\n[\u67b6\u6784\u9762\u8bd5\uff1a\u5168\u94fe\u8def\u538b\u6d4b\uff0c\u4f60\u662f\u600e\u4e48\u8bbe\u8ba1\u7684](https://mp.weixin.qq.com/s/MyK6QrNt3xtms_IBAb6sSQ)\\n\\n[\u963f\u91cc\u9762\u8bd5\uff1a\u5982\u4f55\u4fdd\u8bc1RocketMQ\u6d88\u606f\u6709\u5e8f\uff1f\u5982\u4f55\u89e3\u51b3RocketMQ\u6d88\u606f\u79ef\u538b](https://mp.weixin.qq.com/s/ofaQwaOobZ_5xqcor6ObhA)\\n\\n[\u7f51\u6613\u9762\u8bd5\uff1a\u4ebf\u7ea7\u7528\u6237\uff0c\u5982\u4f55\u505a\u5fae\u670d\u52a1\u5e95\u5c42\u67b6\u6784](https://mp.weixin.qq.com/s/3w5Ld8zgc8DeTmoo7T31qw)\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1a\u4ebf\u7ea7\u6570\u636e \u5728\u7ebf\u7edf\u8ba1\uff0c\u5982\u4f55\u5b9e\u73b0](https://mp.weixin.qq.com/s/PRouD97LKd726m_aW5DWFw)\\n\\n[\u7f8e\u56e2\u9762\u8bd5\uff1aES+Redis+MySQL\u9ad8\u53ef\u7528\uff0c\u5982\u4f55\u8bd5\u5b9e\u73b0](https://mp.weixin.qq.com/s/SXsQ3T5SFK0SKg054m-7Mg)\\n\\n[\u5b57\u8282\u9762\u8bd5\uff1aDDD\u67b6\u6784\uff0c\u5982\u4f55\u843d\u5730](https://mp.weixin.qq.com/s/_NAHYDIvmT7EbffXkIpqYw)\\n\\n[\u5fae\u670d\u52a1\u4e0b\u5fc5\u987b\u4e86\u89e3\u76844\u79cd\u90e8\u7f72\u7b56\u7565\uff01](https://mp.weixin.qq.com/s/c9sioXo95QQmZ7AyQxFBtw)\\n\\n[\u81ea\u4ece\u7528\u4e86\u8fd9\u6b3e\u94fe\u8def\u8ffd\u8e2a\u7cfb\u7edf\uff0c\u7761\u89c9\u771f\u9999\uff01\uff01](https://mp.weixin.qq.com/s/QzG3MupskxyV8eaGt2YOXw)\\n\\n[\u9006\u98ce\u65f6\u523b\uff0c\u7ba1\u7406\u52a8\u4f5c\u6216\u6210\u566a\u97f3](https://mp.weixin.qq.com/s/EtPcGw3dYsKbd411FbZ0bA)\\n\\n[\u8fd9\u4e9b\u5e74\u80cc\u8fc7\u7684\u9762\u8bd5\u9898\u2014\u2014\u67b6\u6784\u8bbe\u8ba1\u7bc7](https://mp.weixin.qq.com/s/w7xUHPCZZuCX_Is1eT5uZQ)\\n\\n[\u8fd8\u5f97\u662f\u817e\u8baf\uff0c\u635e\u4e86\u6211\u4e00\u628a\uff01](https://mp.weixin.qq.com/s/Qwc0xsrOVD4ZTHohAb01yw)\\n\\n[\u6587\u672b\u798f\u5229\u4e282023\u54d4\u54e9\u54d4\u54e9\u6280\u672f\u7cbe\u9009\u6280\u672f\u5e72\u8d27](https://mp.weixin.qq.com/s/zgymXmxo5kiKPG7QRs6Uiw)\\n\\n[\u80fdping\u901a\uff0cTCP\u5c31\u4e00\u5b9a\u80fd\u8fde\u901a\u5417](https://mp.weixin.qq.com/s/gLrRgfwmzMvk9T6MIY4cWg)\\n\\n[\u5fae\u670d\u52a1\u5168\u505a\u9519\u4e86\uff01\u8c37\u6b4c\u63d0\u51fa\u65b0\u65b9\u6cd5\uff0c\u6210\u672c\u76f4\u63a5\u964d9\u500d\uff01](https://mp.weixin.qq.com/s/rezUShZLEK_3f3Cfl2b_fw)\\n\\n[\u5907\u8003\u4e24\u5e74\uff0c\u5173\u4e8e\u8f6f\u8003\u7684\u7ecf\u9a8c\u90fd\u5728\u8fd9\u4e86](https://mp.weixin.qq.com/s/Ijh0taMzh7MUnuysjCB4gQ)\\n\\n[\u6211\u5728\u963f\u91cc\u505a\u5f00\u53d1\u7684\u9ad8\u6548\u6253\u5de5\u6280\u5de7\u603b\u7ed3](https://mp.weixin.qq.com/s/EwdKRsu_U39bTJf4hbjIeA)\\n\\n[\u4e00\u6587\u8bb2\u900f\u6d88\u606f\u961f\u5217RocketMQ\u5b9e\u73b0\u6d88\u8d39\u5e42\u7b49](https://juejin.cn/post/7313242116771627034)\\n\\n[\u8ba2\u5355\u573a\u666f-\u57fa\u4e8eRedisson\u5b9e\u73b0\u8ba2\u5355\u53f7\u751f\u6210](https://juejin.cn/post/7307467803975843891)\\n\\n## \ud83d\udcd2 \u524d\u7aef\u76f8\u5173\\n\\n[\u3010\u7b2c3162\u671f\u3011\u524d\u7aefAPM\u6307\u6807\u91c7\u96c6\u5927\u5192\u9669](https://mp.weixin.qq.com/s/u78Dr9DfLyCMAH8aTil5Lg)\\n\\n[2023\u5e74\u6700\u706b\u7684\u524d\u7aef\u9879\u76ee\u51fa\u7089\uff0c\u7adf\u7136\u662f\u5b83](https://mp.weixin.qq.com/s/ENkssTfPQmS5_PjdIcXpBA)\\n\\n[\u4f60\u7684\u7f51\u7ad9\u6216\u8bb8\u4e0d\u9700\u8981\u524d\u7aef\u6784\u5efa\uff08\u4e8c\uff09](https://mp.weixin.qq.com/s/2Cm7iBMTZk-YqX7G0WfwRQ)\\n\\n[2023 \u5e74 Node.js \u6027\u80fd\u72b6\u6001](https://mp.weixin.qq.com/s/hEYGSa__fKr67nVjR1DFWA)\\n\\n[\u3010\u7b2c3157\u671f\u3011\u89e3\u9501\u524d\u7aef\u65b0\u6f5c\u80fd\uff1a\u5982\u4f55\u4f7f\u7528 Rust \u9508\u5316\u524d\u7aef\u5de5\u5177\u94fe](https://mp.weixin.qq.com/s/Zlc-G6oD63mpSUVBiOs6FA)\\n\\n[\u524d\u7aef\u98df\u5802\u6280\u672f\u5468\u520a\u7b2c 110 \u671f\uff1aVue3.4\u3001\u65b0\u7248 Vue DevTools \u5f00\u6e90\u3001AI 2023 \u5e74\u5ea6\u603b\u7ed3\u5408\u96c6](https://mp.weixin.qq.com/s/yre8fxml3Sgykr4iG8_BSw)"}]}')}}]); \ No newline at end of file diff --git a/assets/js/main.2ced05e0.js b/assets/js/main.2ced05e0.js new file mode 100644 index 0000000000..a37bcd3c4e --- /dev/null +++ b/assets/js/main.2ced05e0.js @@ -0,0 +1,2 @@ +/*! For license information please see main.2ced05e0.js.LICENSE.txt */ +(self.webpackChunkfrontend_weekly=self.webpackChunkfrontend_weekly||[]).push([[179],{55898:(e,t,n)=>{var r={"./prism-java":50955};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=55898},62409:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(59496),a=n(64778),o=n(16628),i=n.n(o),l=n(16887);const c={"002989b8":[()=>n.e(9265).then(n.bind(n,57198)),"@site/blogs/2024/2024-02-18/index.md?truncated=true",57198],"00d51549":[()=>n.e(4593).then(n.bind(n,87696)),"@site/blogs/2022/2022-11-06/index.md?truncated=true",87696],"00e755eb":[()=>n.e(7704).then(n.bind(n,35651)),"@site/blogs/2023/2023-01-08/index.md",35651],"011598a9":[()=>n.e(5391).then(n.t.bind(n,47530,19)),"~blog/2022/frontend-weekly-2022-tags-react-hooks-\u72b6\u6001\u7ba1\u7406-41b.json",47530],"0160f3ea":[()=>n.e(9557).then(n.bind(n,32162)),"@site/blogs/2021/2021-11-14/index.md?truncated=true",32162],"016b564c":[()=>n.e(2236).then(n.t.bind(n,76609,19)),"~blog/2022/frontend-weekly-2022-tags-\u9ed1\u6697\u6a21\u5f0f-b6c.json",76609],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,50210)),"@theme/BlogTagsListPage",50210],"02ec9bf2":[()=>n.e(8471).then(n.t.bind(n,73611,19)),"~blog/2022/frontend-weekly-2022-tags-\u61d2\u52a0\u8f7d-897.json",73611],"04687896":[()=>n.e(9652).then(n.bind(n,4672)),"@site/blogs/2023/2023-04-30/index.md?truncated=true",4672],"057ed7f3":[()=>n.e(1318).then(n.bind(n,86146)),"@site/blogs/2023/2023-03-26/index.md",86146],"061683b7":[()=>n.e(5481).then(n.bind(n,86014)),"@site/blogs/2022/2022-09-04/index.md?truncated=true",86014],"062c07af":[()=>n.e(7384).then(n.bind(n,96571)),"@site/blogs/2023/2023-03-19/index.md?truncated=true",96571],"083d70c6":[()=>n.e(37).then(n.bind(n,76373)),"@site/blogs/2024/2024-02-18/index.md",76373],"085715db":[()=>n.e(4134).then(n.bind(n,56286)),"@site/blogs/2022/2022-01-23/index.md",56286],"08d5ac9a":[()=>n.e(4806).then(n.bind(n,31130)),"@site/blogs/2022/2022-01-23/index.md?truncated=true",31130],"0a0d5910":[()=>n.e(5115).then(n.bind(n,38698)),"@site/blogs/2023/2023-11-12/index.md?truncated=true",38698],"0a4e147b":[()=>n.e(9359).then(n.bind(n,74794)),"@site/blogs/2022/2022-07-31/index.md",74794],"0a8187ba":[()=>n.e(591).then(n.t.bind(n,49860,19)),"~blog/2022/frontend-weekly-2022-tags-\u9ed1\u6697\u6a21\u5f0f-b6c-list.json",49860],"0aaab98c":[()=>n.e(3953).then(n.t.bind(n,59233,19)),"~blog/2022/frontend-weekly-2022-tags-webpack-loader-6f7.json",59233],"0b14ef1a":[()=>n.e(9451).then(n.bind(n,52966)),"@site/blogs/2022/2022-04-03/index.md",52966],"0b251a68":[()=>n.e(1347).then(n.bind(n,76377)),"@site/blogs/2023/2023-12-24/index.md",76377],"0b4570fe":[()=>n.e(4139).then(n.bind(n,42266)),"@site/blogs/2022/2022-11-27/index.md",42266],"0b5d8df8":[()=>n.e(5416).then(n.bind(n,62420)),"@site/blogs/2023/2023-12-31/index.md",62420],"0b74b0bf":[()=>n.e(327).then(n.bind(n,2251)),"@site/blogs/2023/2023-04-02/index.md?truncated=true",2251],"0c702a4c":[()=>n.e(1773).then(n.t.bind(n,70372,19)),"~blog/2022/frontend-weekly-2022-tags-es-next-e27.json",70372],"0d0acdf8":[()=>n.e(3240).then(n.t.bind(n,86395,19)),"~blog/2022/frontend-weekly-2022-tags-\u547d\u4ee4\u884c\u5de5\u5177-936.json",86395],"0d293ec3":[()=>n.e(7750).then(n.t.bind(n,18772,19)),"~blog/2021/frontend-weekly-2021-tags-vue-10b.json",18772],"0e85fec6":[()=>n.e(5623).then(n.bind(n,66984)),"@site/blogs/2023/2023-01-29/index.md?truncated=true",66984],"0ee40e73":[()=>n.e(3469).then(n.bind(n,30777)),"@site/blogs/2022/2022-03-06/index.md?truncated=true",30777],"0f3c0072":[()=>n.e(1867).then(n.t.bind(n,78849,19)),"~blog/2022/frontend-weekly-2022-tags-vue-3-690-list.json",78849],"0f6f20c8":[()=>n.e(0).then(n.bind(n,28139)),"@site/blogs/2023/2023-01-22/index.md?truncated=true",28139],"0f8e0732":[()=>n.e(7452).then(n.t.bind(n,1250,19)),"~blog/2021/frontend-weekly-2021-tags-\u6784\u5efa\u5de5\u5177-5aa.json",1250],"0fdcbc4d":[()=>n.e(2088).then(n.bind(n,1949)),"@site/blogs/2022/2022-09-11/index.md",1949],"10ff88c7":[()=>n.e(2611).then(n.bind(n,3478)),"@site/blogs/2023/2023-07-30/index.md",3478],"11437d96":[()=>n.e(1559).then(n.bind(n,35070)),"@site/blogs/2022/2022-10-30/index.md?truncated=true",35070],"128bfab2":[()=>n.e(5331).then(n.t.bind(n,23244,19)),"~blog/2021/frontend-weekly-2021-tags-git-\u5c0f\u6280\u5de7-368.json",23244],"1337aa16":[()=>n.e(8756).then(n.t.bind(n,37849,19)),"~blog/2022/frontend-weekly-2022-tags-quic-84d-list.json",37849],13873167:[()=>n.e(471).then(n.t.bind(n,3578,19)),"~blog/2021/frontend-weekly-2021-tags-\u7bad\u5934\u51fd\u6570-9f5.json",3578],"13f3758b":[()=>n.e(8165).then(n.t.bind(n,75295,19)),"~blog/2022/frontend-weekly-2022-tags-react-native-b4e-list.json",75295],"148a5620":[()=>n.e(88).then(n.bind(n,96980)),"@site/blogs/2023/2023-08-06/index.md?truncated=true",96980],"14c9e3ff":[()=>n.e(8895).then(n.bind(n,82878)),"@site/blogs/2023/2023-03-12/index.md?truncated=true",82878],"151bacfb":[()=>n.e(5751).then(n.bind(n,28926)),"@site/blogs/2023/2023-05-28/index.md?truncated=true",28926],"15224e9d":[()=>n.e(4147).then(n.bind(n,19454)),"@site/blogs/2023/2023-09-24/index.md",19454],"16a3faf9":[()=>n.e(3043).then(n.t.bind(n,67985,19)),"~blog/2021/frontend-weekly-2021-tags-\u6784\u5efa\u5de5\u5177-5aa-list.json",67985],"188722b8":[()=>n.e(979).then(n.bind(n,15003)),"@site/blogs/2023/2023-03-12/index.md",15003],"194a145f":[()=>n.e(9323).then(n.bind(n,64278)),"@site/blogs/2022/2022-05-22/index.md?truncated=true",64278],"19aadaf8":[()=>n.e(2481).then(n.bind(n,26623)),"@site/blogs/2022/2022-04-24/index.md",26623],"19c08f74":[()=>n.e(5266).then(n.bind(n,86676)),"@site/blogs/2023/2023-10-01/index.md?truncated=true",86676],"1a75bbad":[()=>n.e(5292).then(n.t.bind(n,16749,19)),"~blog/2022/frontend-weekly-2022-tags-git-page-2-5e2.json",16749],"1acd76b3":[()=>n.e(6510).then(n.bind(n,12462)),"@site/blogs/2023/2023-04-23/index.md?truncated=true",12462],"1bc8c260":[()=>n.e(39).then(n.bind(n,96517)),"@site/blogs/2021/2021-12-12/index.md",96517],"1cf3be1e":[()=>n.e(7472).then(n.bind(n,79889)),"@site/blogs/2022/2022-03-27/index.md",79889],"1d0ddbc9":[()=>n.e(5137).then(n.t.bind(n,10300,19)),"~blog/2022/frontend-weekly-2022-tags-css-063-list.json",10300],"1df93b7f":[()=>Promise.all([n.e(532),n.e(3237)]).then(n.bind(n,23880)),"@site/src/pages/index.tsx",23880],"1f0d2849":[()=>n.e(1472).then(n.t.bind(n,80942,19)),"~blog/2024/frontend-weekly-2024-tags-java-7fb.json",80942],"1f391b9e":[()=>Promise.all([n.e(532),n.e(176),n.e(3085)]).then(n.bind(n,91383)),"@theme/MDXPage",91383],"20e14003":[()=>n.e(7372).then(n.t.bind(n,2556,19)),"~blog/2022/frontend-weekly-2022-page-4-e21.json",2556],"212c4d36":[()=>Promise.all([n.e(532),n.e(5439)]).then(n.bind(n,81526)),"@site/blogs/2024/2024-12-12-welcome/index.md",81526],"2199b7b6":[()=>n.e(9421).then(n.t.bind(n,62831,19)),"~blog/2022/frontend-weekly-2022-tags-quic-84d.json",62831],"21f5b1e9":[()=>n.e(4406).then(n.bind(n,6641)),"@site/blogs/2023/2023-11-19/index.md",6641],22496556:[()=>n.e(6482).then(n.bind(n,32322)),"@site/blogs/2023/2023-04-16/index.md",32322],"22c1db88":[()=>n.e(3093).then(n.t.bind(n,40283,19)),"~blog/2021/frontend-weekly-2021-archive-63d.json",40283],"22d08400":[()=>n.e(9374).then(n.bind(n,26076)),"@site/blogs/2023/2023-05-14/index.md",26076],"22f7e1bd":[()=>n.e(8246).then(n.t.bind(n,24817,19)),"~blog/2021/frontend-weekly-2021-tags-\u7b2c\u4e09\u65b9\u5e93-lockfile-135-list.json",24817],"22fdc298":[()=>n.e(8630).then(n.bind(n,47633)),"@site/blogs/2023/2023-06-04/index.md?truncated=true",47633],"230bd4b8":[()=>n.e(2526).then(n.t.bind(n,43841,19)),"~blog/2022/frontend-weekly-2022-tags-diff-\u7b97\u6cd5-c87.json",43841],"23251bbe":[()=>n.e(9875).then(n.bind(n,32233)),"@site/blogs/2023/2023-07-30/index.md?truncated=true",32233],"23325a9b":[()=>n.e(6877).then(n.bind(n,30474)),"@site/blogs/2024/2024-01-14/index.md",30474],"24d2924d":[()=>n.e(8404).then(n.bind(n,5654)),"@site/blogs/2021/2021-11-21/index.md",5654],"24e163b7":[()=>n.e(2837).then(n.bind(n,86632)),"@site/blogs/2023/2023-09-10/index.md",86632],"2565997f":[()=>n.e(714).then(n.bind(n,32718)),"@site/blogs/2022/2022-04-17/index.md",32718],"25858c09":[()=>n.e(8114).then(n.bind(n,12465)),"@site/blogs/2024/2024-01-21/index.md?truncated=true",12465],"261ce045":[()=>n.e(7201).then(n.bind(n,29271)),"@site/blogs/2022/2022-04-03/index.md?truncated=true",29271],"272dd7a1":[()=>n.e(8632).then(n.bind(n,75611)),"@site/blogs/2023/2023-04-02/index.md",75611],"27c35a5f":[()=>n.e(1955).then(n.bind(n,84030)),"@site/blogs/2023/2023-02-19/index.md",84030],"294406ef":[()=>n.e(1464).then(n.bind(n,22910)),"@site/blogs/2023/2023-05-07/index.md",22910],"2b0b4be1":[()=>n.e(6623).then(n.bind(n,37465)),"@site/blogs/2023/2023-01-22/index.md",37465],"2b1f4d91":[()=>n.e(1890).then(n.t.bind(n,8213,19)),"~blog/2021/frontend-weekly-2021-tags-\u5f00\u53d1\u89c4\u8303-331-list.json",8213],"2b333ad7":[()=>n.e(5769).then(n.bind(n,53006)),"@site/blogs/2022/2022-02-06/index.md?truncated=true",53006],"2e5b1181":[()=>n.e(4569).then(n.t.bind(n,99855,19)),"~blog/2021/frontend-weekly-2021-tags-tags-ad8.json",99855],"2fc692c6":[()=>n.e(2997).then(n.bind(n,30022)),"@site/blogs/2022/2022-09-11/index.md?truncated=true",30022],"2fdd3b46":[()=>n.e(4759).then(n.t.bind(n,82798,19)),"~blog/2021/frontend-weekly-2021-tags-type-script-cb8.json",82798],"2fec89d2":[()=>n.e(6455).then(n.bind(n,86390)),"@site/blogs/2022/2022-10-02/index.md?truncated=true",86390],"3023e805":[()=>n.e(7949).then(n.bind(n,34930)),"@site/blogs/2021/2021-12-12/index.md?truncated=true",34930],"30a0cc05":[()=>n.e(5464).then(n.bind(n,37354)),"@site/blogs/2022/2022-05-01/index.md?truncated=true",37354],"30c81eb5":[()=>n.e(846).then(n.t.bind(n,67047,19)),"~blog/2021/frontend-weekly-2021-tags-type-script-cb8-list.json",67047],"30fa4192":[()=>n.e(219).then(n.t.bind(n,95744,19)),"~blog/2022/frontend-weekly-2022-tags-\u5f52\u5e76\u6392\u5e8f-a1c.json",95744],"3124026b":[()=>n.e(8882).then(n.t.bind(n,43647,19)),"~blog/2022/frontend-weekly-2022-tags-golang-831.json",43647],"3239346b":[()=>n.e(6642).then(n.t.bind(n,17114,19)),"~blog/2021/frontend-weekly-2021-tags-babel-\u63d2\u4ef6-356.json",17114],"32a4888c":[()=>n.e(273).then(n.t.bind(n,40357,19)),"~blog/2024/frontend-weekly-2024-tags-golang-2bc.json",40357],34950556:[()=>n.e(6318).then(n.t.bind(n,59836,19)),"~blog/2021/frontend-weekly-2021-tags-\u6587\u6863\u90e8\u7f72-7f9.json",59836],"36b98d1c":[()=>n.e(8871).then(n.bind(n,50114)),"@site/blogs/2022/2022-05-08/index.md",50114],"36f70ca6":[()=>n.e(7168).then(n.t.bind(n,93798,19)),"~blog/2022/frontend-weekly-2022-tags-cra-13e-list.json",93798],37088983:[()=>n.e(6803).then(n.t.bind(n,92543,19)),"~blog/2022/frontend-weekly-2022-tags-golang-page-2-40a-list.json",92543],"37a7b38e":[()=>n.e(6004).then(n.t.bind(n,14011,19)),"~blog/2022/frontend-weekly-2022-tags-vs-code-d0c-list.json",14011],"39014ceb":[()=>n.e(6649).then(n.bind(n,52482)),"@site/blogs/2022/2022-06-19/index.md?truncated=true",52482],"393be207":[()=>n.e(7414).then(n.bind(n,6886)),"@site/src/pages/markdown-page.md",6886],"39b171f9":[()=>n.e(5280).then(n.bind(n,57977)),"@site/blogs/2024/2024-02-04/index.md?truncated=true",57977],"3a362ac1":[()=>n.e(1556).then(n.t.bind(n,65396,19)),"~blog/2021/frontend-weekly-2021-tags-common-js-38b.json",65396],"3a6df9d8":[()=>n.e(5071).then(n.t.bind(n,517,19)),"~blog/2021/frontend-weekly-2021-tags-webpack-c6e-list.json",517],"3a899b59":[()=>n.e(1609).then(n.t.bind(n,55626,19)),"~blog/2024/frontend-weekly-2024-tags-type-script-139-list.json",55626],"3b3f30df":[()=>n.e(6327).then(n.t.bind(n,18874,19)),"~blog/2023/frontend-weekly-2023-page-4-c19.json",18874],"3c3cdec0":[()=>n.e(9513).then(n.bind(n,87978)),"@site/blogs/2021/2021-12-05/index.md",87978],"3c771fbf":[()=>n.e(3422).then(n.t.bind(n,36718,19)),"~blog/2022/frontend-weekly-2022-tags-vs-code-d0c.json",36718],"3d7fb8a6":[()=>n.e(6631).then(n.t.bind(n,60656,19)),"~blog/2022/frontend-weekly-2022-tags-git-768.json",60656],"3da482b0":[()=>n.e(6438).then(n.bind(n,62557)),"@site/blogs/2022/2022-12-11/index.md",62557],"3dd376e3":[()=>n.e(9981).then(n.t.bind(n,90822,19)),"~blog/2021/frontend-weekly-2021-tags-npm-\u53d1\u5305-106.json",90822],"3e027d21":[()=>n.e(4869).then(n.t.bind(n,74258,19)),"~blog/2022/frontend-weekly-2022-tags-next-js-f43.json",74258],"3e75dae4":[()=>n.e(7615).then(n.t.bind(n,1149,19)),"~blog/2022/frontend-weekly-2022-tags-\u547d\u4ee4\u884c\u5de5\u5177-936-list.json",1149],"3ef65211":[()=>n.e(4622).then(n.bind(n,41876)),"@site/blogs/2022/2022-08-21/index.md",41876],"3f61a362":[()=>n.e(980).then(n.bind(n,90865)),"@site/blogs/2021/2021-11-14/index.md",90865],"3fca080d":[()=>n.e(2256).then(n.t.bind(n,55392,19)),"~blog/2022/frontend-weekly-2022-tags-json-\u5e8f\u5217\u5316-c15-list.json",55392],"40d7045c":[()=>n.e(398).then(n.t.bind(n,23067,19)),"~blog/2021/frontend-weekly-2021-tags-\u56de\u6eaf\u7b97\u6cd5-497-list.json",23067],"41031f24":[()=>n.e(3768).then(n.bind(n,39987)),"@site/blogs/2024/2024-02-25/index.md",39987],"420604fa":[()=>n.e(2270).then(n.bind(n,98388)),"@site/blogs/2022/2022-01-16/index.md",98388],"4233d2da":[()=>n.e(662).then(n.t.bind(n,53431,19)),"~blog/2021/frontend-weekly-2021-tags-vue-3-6bd-list.json",53431],"426827d4":[()=>n.e(7588).then(n.bind(n,53191)),"@site/blogs/2023/2023-05-14/index.md?truncated=true",53191],"42a6a62e":[()=>n.e(4127).then(n.t.bind(n,21345,19)),"~blog/2021/frontend-weekly-2021-tags-vue-10b-list.json",21345],"4484b83c":[()=>n.e(144).then(n.bind(n,1043)),"@site/blogs/2023/2023-11-05/index.md",1043],"45a4f26b":[()=>n.e(1119).then(n.t.bind(n,70735,19)),"~blog/2023/frontend-weekly-2023-page-2-02d.json",70735],"45a601ff":[()=>n.e(3688).then(n.t.bind(n,62746,19)),"~blog/2021/frontend-weekly-2021-tags-react-docs-ea6-list.json",62746],"46d48290":[()=>n.e(9422).then(n.t.bind(n,65686,19)),"~blog/2021/frontend-weekly-2021-tags-\u4ee3\u7801\u89c4\u8303-fd6.json",65686],"4733621c":[()=>n.e(1888).then(n.t.bind(n,32044,19)),"~blog/2021/frontend-weekly-2021-tags-golang-626.json",32044],"4781e04d":[()=>n.e(5966).then(n.bind(n,76887)),"@site/blogs/2022/2022-12-25/index.md",76887],"4864417c":[()=>n.e(7963).then(n.t.bind(n,53800,19)),"/home/runner/work/frontend-weekly/frontend-weekly/.docusaurus/docusaurus-plugin-content-blog/2021/plugin-route-context-module-100.json",53800],"49522ea0":[()=>n.e(5917).then(n.bind(n,12529)),"@site/blogs/2023/2023-10-29/index.md",12529],"4953c8af":[()=>n.e(8008).then(n.bind(n,77516)),"@site/blogs/2022/2022-10-02/index.md",77516],"49c70eac":[()=>n.e(350).then(n.bind(n,82172)),"@site/blogs/2023/2023-05-07/index.md?truncated=true",82172],"49ed6318":[()=>n.e(5876).then(n.t.bind(n,94743,19)),"~blog/2023/frontend-weekly-2023-page-3-20b.json",94743],"4a08cf11":[()=>n.e(931).then(n.bind(n,28658)),"@site/blogs/2023/2023-01-29/index.md",28658],"4a0d16a7":[()=>n.e(1333).then(n.t.bind(n,42472,19)),"~blog/2024/frontend-weekly-2024-tags-\u6027\u80fd\u4f18\u5316-e74-list.json",42472],"4a79a12f":[()=>n.e(3920).then(n.bind(n,66325)),"@site/blogs/2022/2022-02-27/index.md",66325],"4ac614ae":[()=>n.e(9266).then(n.t.bind(n,98891,19)),"~blog/2022/frontend-weekly-2022-tags-monorepo-493.json",98891],"4b19a69b":[()=>n.e(2844).then(n.bind(n,28916)),"@site/blogs/2023/2023-02-19/index.md?truncated=true",28916],"4b311cb7":[()=>n.e(3758).then(n.t.bind(n,59779,19)),"~blog/2021/frontend-weekly-2021-tags-\u7b2c\u4e09\u65b9\u5e93-lockfile-135.json",59779],"4cab3bea":[()=>n.e(813).then(n.t.bind(n,99034,19)),"~blog/2024/frontend-weekly-2024-tags-tags-003.json",99034],"4cb2d6f8":[()=>n.e(4934).then(n.t.bind(n,62485,19)),"~blog/2022/frontend-weekly-2022-tags-yaml-400-list.json",62485],"4dd2793b":[()=>n.e(3021).then(n.bind(n,82279)),"@site/blogs/2021/2021-12-26/index.md",82279],"4dd92330":[()=>n.e(108).then(n.bind(n,75258)),"@site/blogs/2023/2023-05-21/index.md",75258],"4df537fa":[()=>n.e(5962).then(n.t.bind(n,79453,19)),"~blog/2021/frontend-weekly-2021-tags-npm-\u53d1\u5305-106-list.json",79453],"4e0171ea":[()=>n.e(7651).then(n.bind(n,59107)),"@site/blogs/2022/2022-01-30/index.md",59107],"4e53c30d":[()=>n.e(1304).then(n.t.bind(n,56408,19)),"~blog/2022/frontend-weekly-2022-tags-yaml-400.json",56408],"4ec32771":[()=>n.e(8252).then(n.t.bind(n,14690,19)),"~blog/2022/frontend-weekly-2022-tags-git-hub-\u5b9a\u65f6\u4efb\u52a1-283.json",14690],"4ee5a073":[()=>n.e(1162).then(n.bind(n,65578)),"@site/blogs/2022/2022-02-20/index.md?truncated=true",65578],"4f0454d0":[()=>n.e(1739).then(n.t.bind(n,89164,19)),"~blog/2021/frontend-weekly-2021-tags-browserslist-5a8.json",89164],"50b1c0f3":[()=>n.e(9650).then(n.bind(n,69077)),"@site/blogs/2023/2023-12-24/index.md?truncated=true",69077],51635236:[()=>n.e(6360).then(n.bind(n,9438)),"@site/blogs/2022/2022-01-16/index.md?truncated=true",9438],53009603:[()=>n.e(7861).then(n.bind(n,10833)),"@site/blogs/2023/2023-02-12/index.md",10833],"53dbfb56":[()=>n.e(4830).then(n.bind(n,9507)),"@site/blogs/2022/2022-08-07/index.md",9507],"546c6da5":[()=>n.e(3617).then(n.bind(n,6835)),"@site/blogs/2023/2023-08-27/index.md?truncated=true",6835],"54bf8b9f":[()=>n.e(6861).then(n.bind(n,9031)),"@site/blogs/2022/2022-10-23/index.md?truncated=true",9031],"54e64e6b":[()=>n.e(3380).then(n.bind(n,2400)),"@site/blogs/2023/2023-09-03/index.md",2400],"559c513c":[()=>n.e(5219).then(n.t.bind(n,23369,19)),"~blog/2021/frontend-weekly-2021-tags-common-js-38b-list.json",23369],"56b43681":[()=>n.e(3832).then(n.t.bind(n,16777,19)),"~blog/2022/frontend-weekly-2022-tags-prettier-4ce.json",16777],"56e0c3ac":[()=>n.e(4377).then(n.bind(n,92927)),"@site/blogs/2024/2024-01-07/index.md?truncated=true",92927],57244941:[()=>n.e(517).then(n.bind(n,7558)),"@site/blogs/2022/2022-10-16/index.md",7558],"576e3011":[()=>Promise.all([n.e(532),n.e(3555),n.e(3535)]).then(n.bind(n,85049)),"@site/blogs/2022/2022-01-09/index.md?truncated=true",85049],"57785e1d":[()=>n.e(7994).then(n.bind(n,69983)),"@site/blogs/2023/2023-02-26/index.md",69983],"582da741":[()=>n.e(7152).then(n.bind(n,51374)),"@site/blogs/2022/2022-07-31/index.md?truncated=true",51374],"59b8a2b1":[()=>n.e(3156).then(n.t.bind(n,39161,19)),"~blog/2021/frontend-weekly-2021-tags-react-280.json",39161],"59c08185":[()=>n.e(9699).then(n.bind(n,14244)),"@site/blogs/2024/2024-03-10/index.md",14244],"5ae68e2c":[()=>n.e(1877).then(n.t.bind(n,43701,19)),"~blog/2024/frontend-weekly-2024-tags-\u524d\u7aef\u6846\u67b6-f34.json",43701],"5b4da08b":[()=>n.e(5849).then(n.t.bind(n,77614,19)),"~blog/2024/frontend-weekly-2024-tags-webpack-c14.json",77614],"5bc15456":[()=>n.e(3222).then(n.t.bind(n,61937,19)),"~blog/2022/frontend-weekly-2022-tags-http-\u7f13\u5b58-99a.json",61937],"5c1a72a0":[()=>Promise.all([n.e(532),n.e(3555),n.e(3830)]).then(n.bind(n,95200)),"@site/blogs/2022/2022-01-02/index.md?truncated=true",95200],"5dbf6a39":[()=>n.e(7462).then(n.bind(n,40978)),"@site/blogs/2023/2023-06-25/index.md",40978],"5e0e8c84":[()=>n.e(1281).then(n.t.bind(n,10342,19)),"~blog/2024/frontend-weekly-2024-tags-\u4e1a\u52a1\u6210\u957f-787-list.json",10342],"5e504fc7":[()=>n.e(2322).then(n.t.bind(n,54154,19)),"~blog/2021/frontend-weekly-2021-tags-\u7bad\u5934\u51fd\u6570-9f5-list.json",54154],"5e7acaa9":[()=>n.e(6831).then(n.t.bind(n,73664,19)),"~blog/2024/frontend-weekly-2024-page-2-24c.json",73664],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"5eb3c5dc":[()=>n.e(3123).then(n.t.bind(n,70584,19)),"~blog/2024/frontend-weekly-2024-tags-type-script-139.json",70584],"5f876c65":[()=>n.e(5097).then(n.t.bind(n,5419,19)),"~blog/2024/frontend-weekly-2024-tags-\u7ec4\u4ef6\u5e93\u5b9e\u6218-fd1-list.json",5419],"5fd95b94":[()=>Promise.all([n.e(532),n.e(3555),n.e(1863)]).then(n.bind(n,89954)),"@site/blogs/2022/2022-01-02/index.md",89954],"5fdfbb02":[()=>n.e(5243).then(n.bind(n,64824)),"@site/blogs/2021/2021-11-21/index.md?truncated=true",64824],60542136:[()=>n.e(283).then(n.t.bind(n,65949,19)),"~blog/2022/frontend-weekly-2022-tags-\u5de5\u7a0b\u5316\u65b9\u6848-c20-list.json",65949],"60a25021":[()=>n.e(6347).then(n.t.bind(n,90676,19)),"~blog/2022/frontend-weekly-2022-tags-vue-ad7-list.json",90676],"619c22f7":[()=>n.e(9848).then(n.bind(n,10394)),"@site/blogs/2023/2023-04-16/index.md?truncated=true",10394],"61cb9fc1":[()=>n.e(577).then(n.bind(n,42142)),"@site/blogs/2022/2022-08-21/index.md?truncated=true",42142],"6201bab2":[()=>n.e(1262).then(n.t.bind(n,60749,19)),"~blog/2023/blog-post-list-prop-2023.json",60749],"62a376b5":[()=>n.e(6082).then(n.t.bind(n,41391,19)),"~blog/2022/frontend-weekly-2022-tags-post-css-5ad-list.json",41391],"63d7434d":[()=>n.e(2008).then(n.bind(n,17894)),"@site/blogs/2022/2022-03-13/index.md?truncated=true",17894],"64a6f719":[()=>n.e(6298).then(n.t.bind(n,50133,19)),"~blog/2022/frontend-weekly-2022-tags-code-review-5c7-list.json",50133],"6508c73f":[()=>n.e(2980).then(n.bind(n,12709)),"@site/blogs/2022/2022-06-05/index.md?truncated=true",12709],"66718fba":[()=>n.e(9023).then(n.bind(n,13020)),"@site/blogs/2022/2022-10-23/index.md",13020],"6714549f":[()=>n.e(9011).then(n.t.bind(n,63122,19)),"~blog/2022/frontend-weekly-2022-tags-type-script-923.json",63122],67680451:[()=>n.e(9613).then(n.t.bind(n,68166,19)),"~blog/2022/frontend-weekly-2022-tags-\u5e74\u5ea6\u9ad8\u8d5e\u6587\u7ae0-4a0.json",68166],"67e55bf3":[()=>n.e(7547).then(n.t.bind(n,28127,19)),"/home/runner/work/frontend-weekly/frontend-weekly/.docusaurus/docusaurus-plugin-content-blog/2024/plugin-route-context-module-100.json",28127],"6875c492":[()=>Promise.all([n.e(532),n.e(176),n.e(4332),n.e(8610)]).then(n.bind(n,18379)),"@theme/BlogTagsPostsPage",18379],"68a1f349":[()=>n.e(1226).then(n.t.bind(n,92541,19)),"~blog/2024/frontend-weekly-2024-tags-golang-2bc-list.json",92541],"68c3e8f0":[()=>n.e(9688).then(n.t.bind(n,69708,19)),"~blog/2022/frontend-weekly-2022-tags-\u524d\u7aef\u6280\u672f\u65b9\u5411-c55.json",69708],"6971714e":[()=>n.e(6026).then(n.bind(n,7677)),"@site/blogs/2023/2023-07-09/index.md",7677],"69b4722b":[()=>n.e(375).then(n.t.bind(n,49058,19)),"~blog/2022/frontend-weekly-2022-tags-react-9de-list.json",49058],"6a75f64b":[()=>n.e(1479).then(n.t.bind(n,38432,19)),"~blog/2024/frontend-weekly-2024-tags-\u524d\u7aef\u6846\u67b6-f34-list.json",38432],"6a9e7760":[()=>n.e(4630).then(n.t.bind(n,46548,19)),"~blog/2022/frontend-weekly-2022-tags-http-\u7f13\u5b58-99a-list.json",46548],"6aa15a4e":[()=>n.e(1864).then(n.t.bind(n,20454,19)),"~blog/2022/frontend-weekly-2022-tags-babel-02e-list.json",20454],"6b41cb32":[()=>n.e(3738).then(n.t.bind(n,97531,19)),"~blog/2022/frontend-weekly-2022-tags-\u61d2\u52a0\u8f7d-897-list.json",97531],"6bcf959d":[()=>n.e(1290).then(n.bind(n,87709)),"@site/blogs/2023/2023-01-01/index.md",87709],"6c0b118e":[()=>n.e(9568).then(n.t.bind(n,8717,19)),"~blog/2022/frontend-weekly-2022-tags-idea-99e-list.json",8717],"6c17f2f7":[()=>n.e(803).then(n.t.bind(n,24116,19)),"~blog/2022/frontend-weekly-2022-tags-leetcode-ab6.json",24116],"6cbe801a":[()=>n.e(9842).then(n.t.bind(n,49683,19)),"~blog/2022/frontend-weekly-2022-tags-\u5de5\u7a0b\u5316\u65b9\u6848-c20.json",49683],"6cbee5d2":[()=>Promise.all([n.e(532),n.e(3555),n.e(5499)]).then(n.bind(n,99856)),"@site/blogs/2022/2022-01-09/index.md",99856],"6d3ee4db":[()=>n.e(8536).then(n.bind(n,47225)),"@site/blogs/2022/2022-06-19/index.md",47225],"6f16508d":[()=>n.e(4131).then(n.bind(n,4859)),"@site/blogs/2023/2023-08-20/index.md",4859],"6f25190c":[()=>n.e(606).then(n.t.bind(n,65872,19)),"~blog/2022/frontend-weekly-2022-tags-es-lint-4b7-list.json",65872],"6f45c95e":[()=>n.e(9937).then(n.bind(n,4334)),"@site/blogs/2023/2023-02-26/index.md?truncated=true",4334],"6fa35ed7":[()=>n.e(7690).then(n.t.bind(n,92354,19)),"~blog/2024/frontend-weekly-2024-tags-\u7f51\u7edc\u76f8\u5173-48c.json",92354],"707bb5fe":[()=>n.e(899).then(n.bind(n,5313)),"@site/blogs/2023/2023-08-06/index.md",5313],"707c4168":[()=>n.e(5906).then(n.bind(n,82524)),"@site/blogs/2022/2022-07-24/index.md?truncated=true",82524],"70f68d2f":[()=>n.e(4930).then(n.bind(n,8033)),"@site/blogs/2023/2023-04-09/index.md",8033],"72bd454e":[()=>n.e(3502).then(n.bind(n,18977)),"@site/blogs/2022/2022-12-18/index.md?truncated=true",18977],"72c8e5bd":[()=>n.e(4405).then(n.bind(n,80950)),"@site/blogs/2024/2024-01-14/index.md?truncated=true",80950],73610610:[()=>n.e(6566).then(n.bind(n,1271)),"@site/blogs/2023/2023-06-11/index.md",1271],"749aaaad":[()=>n.e(6059).then(n.bind(n,40198)),"@site/blogs/2022/2022-07-10/index.md",40198],"74b7f1d3":[()=>n.e(2191).then(n.t.bind(n,452,19)),"~blog/2022/frontend-weekly-2022-tags-\u5e74\u5ea6\u9ad8\u8d5e\u6587\u7ae0-4a0-list.json",452],"7569bc28":[()=>n.e(5487).then(n.t.bind(n,98738,19)),"~blog/2022/frontend-weekly-2022-tags-\u9759\u6001\u9875\u9762\u90e8\u7f72-61a-list.json",98738],"75bfcd16":[()=>n.e(900).then(n.t.bind(n,48929,19)),"~blog/2022/frontend-weekly-2022-tags-react-hooks-\u72b6\u6001\u7ba1\u7406-41b-list.json",48929],"76cc166b":[()=>n.e(7403).then(n.bind(n,52317)),"@site/blogs/2024/2024-03-10/index.md?truncated=true",52317],"7811d1e5":[()=>n.e(7110).then(n.bind(n,27210)),"@site/blogs/2024/2024-03-17/index.md",27210],"78e126d2":[()=>n.e(7625).then(n.bind(n,2189)),"@site/blogs/2022/2022-07-24/index.md",2189],"798977f1":[()=>n.e(7265).then(n.t.bind(n,90254,19)),"~blog/2022/frontend-weekly-2022-tags-webpack-loader-6f7-list.json",90254],"7a281e25":[()=>n.e(4170).then(n.t.bind(n,98800,19)),"~blog/2022/frontend-weekly-2022-tags-node-js-e1f-list.json",98800],"7a4bdb0d":[()=>n.e(9711).then(n.bind(n,89413)),"@site/blogs/2022/2022-05-01/index.md",89413],"7a9a181f":[()=>n.e(4169).then(n.t.bind(n,83970,19)),"~blog/2021/frontend-weekly-2021-tags-\u8bed\u4e49\u5316\u7248\u672c-598-list.json",83970],"7ad18ae8":[()=>n.e(7574).then(n.bind(n,85403)),"@site/blogs/2023/2023-11-05/index.md?truncated=true",85403],"7b0f43d5":[()=>n.e(762).then(n.bind(n,26309)),"@site/blogs/2022/2022-11-13/index.md?truncated=true",26309],"7b6269e3":[()=>n.e(9329).then(n.t.bind(n,42320,19)),"~blog/2022/frontend-weekly-2022-tags-\u524d\u7aef\u6280\u672f\u65b9\u5411-c55-list.json",42320],"7b81ce2d":[()=>n.e(7e3).then(n.t.bind(n,10334,19)),"~blog/2021/frontend-weekly-2021-tags-\u56de\u6eaf\u7b97\u6cd5-497.json",10334],"7bf5dbab":[()=>n.e(3390).then(n.t.bind(n,13281,19)),"~blog/2022/frontend-weekly-2022-tags-yarn-2-470.json",13281],"7c173d83":[()=>n.e(408).then(n.bind(n,75071)),"@site/blogs/2023/2023-10-08/index.md?truncated=true",75071],"7c1d6a51":[()=>n.e(5686).then(n.bind(n,93545)),"@site/blogs/2023/2023-01-15/index.md?truncated=true",93545],"7c729b88":[()=>n.e(3491).then(n.t.bind(n,50621,19)),"~blog/2022/frontend-weekly-2022-tags-monorepo-493-list.json",50621],"7d590d1d":[()=>n.e(8093).then(n.bind(n,4282)),"@site/blogs/2024/2024-02-04/index.md",4282],"7d83e1d3":[()=>n.e(3482).then(n.bind(n,66169)),"@site/blogs/2022/2022-07-17/index.md?truncated=true",66169],"7ffd8a68":[()=>n.e(5364).then(n.t.bind(n,13630,19)),"~blog/2022/frontend-weekly-2022-page-3-a7c.json",13630],"8025eb17":[()=>n.e(2707).then(n.t.bind(n,48342,19)),"~blog/2022/frontend-weekly-2022-tags-post-css-5ad.json",48342],81339387:[()=>n.e(7445).then(n.t.bind(n,91875,19)),"~blog/2022/frontend-weekly-2022-tags-golang-831-list.json",91875],"816f873d":[()=>n.e(9788).then(n.t.bind(n,91352,19)),"~blog/2024/frontend-weekly-2024-tags-\u6e90\u7801\u7cfb\u5217-416.json",91352],"81aad93a":[()=>n.e(2155).then(n.t.bind(n,99124,19)),"~blog/2022/frontend-weekly-2022-archive-99d.json",99124],"81d5a07b":[()=>n.e(4275).then(n.bind(n,49348)),"@site/blogs/2022/2022-11-20/index.md?truncated=true",49348],"81ec0f73":[()=>n.e(2172).then(n.t.bind(n,82165,19)),"~blog/2024/frontend-weekly-2024-tags-\u6027\u80fd\u4f18\u5316-e74.json",82165],"8305f01e":[()=>n.e(7717).then(n.t.bind(n,76614,19)),"~blog/2021/blog-post-list-prop-2021.json",76614],"853795ed":[()=>n.e(8362).then(n.t.bind(n,63162,19)),"~blog/2021/frontend-weekly-2021-tags-npm-e02-list.json",63162],"85fa8aa7":[()=>n.e(3975).then(n.bind(n,59460)),"@site/blogs/2023/2023-10-15/index.md",59460],"8636baf8":[()=>n.e(8945).then(n.bind(n,94277)),"@site/blogs/2022/2022-03-13/index.md",94277],"86b3ff26":[()=>n.e(100).then(n.bind(n,47024)),"@site/blogs/2022/2022-03-20/index.md?truncated=true",47024],"870f7756":[()=>n.e(1041).then(n.bind(n,3766)),"@site/blogs/2023/2023-11-26/index.md?truncated=true",3766],"874d9227":[()=>n.e(4633).then(n.t.bind(n,88086,19)),"~blog/2022/frontend-weekly-2022-tags-prettier-4ce-list.json",88086],87637539:[()=>n.e(8844).then(n.t.bind(n,85074,19)),"~blog/2023/frontend-weekly-2023-4c4.json",85074],"878d443d":[()=>n.e(8473).then(n.t.bind(n,65945,19)),"~blog/2022/frontend-weekly-2022-tags-css-063.json",65945],"88d799cd":[()=>n.e(4729).then(n.t.bind(n,73501,19)),"~blog/2021/frontend-weekly-2021-tags-\u5f00\u53d1\u89c4\u8303-331.json",73501],"894c03f5":[()=>n.e(4626).then(n.t.bind(n,99813,19)),"~blog/2022/frontend-weekly-2022-page-5-7ba.json",99813],"89d8e4a5":[()=>n.e(4436).then(n.t.bind(n,1615,19)),"~blog/2022/frontend-weekly-2022-tags-code-review-5c7.json",1615],"8be4b43f":[()=>n.e(7875).then(n.bind(n,98123)),"@site/blogs/2023/2023-02-05/index.md?truncated=true",98123],"8c6ee49a":[()=>n.e(9547).then(n.bind(n,18547)),"@site/blogs/2022/2022-01-30/index.md?truncated=true",18547],"8c7fb54b":[()=>n.e(7300).then(n.bind(n,36033)),"@site/blogs/2022/2022-04-10/index.md",36033],"8e0fd697":[()=>n.e(8874).then(n.t.bind(n,46280,19)),"~blog/2024/blog-post-list-prop-2024.json",46280],"8e69adc5":[()=>n.e(8170).then(n.bind(n,48901)),"@site/blogs/2023/2023-09-17/index.md?truncated=true",48901],"8f5dc316":[()=>n.e(9357).then(n.bind(n,41562)),"@site/blogs/2024/2024-02-11/index.md?truncated=true",41562],"905269b8":[()=>n.e(9061).then(n.bind(n,74467)),"@site/blogs/2022/2022-06-26/index.md",74467],"90b56ec4":[()=>n.e(8479).then(n.bind(n,22273)),"@site/blogs/2021/2021-12-26/index.md?truncated=true",22273],"91c57bb5":[()=>n.e(9300).then(n.t.bind(n,47131,19)),"~blog/2021/frontend-weekly-2021-tags-react-docs-ea6.json",47131],"92c2ee84":[()=>n.e(7474).then(n.bind(n,26413)),"@site/blogs/2023/2023-06-25/index.md?truncated=true",26413],"9511e944":[()=>n.e(4150).then(n.t.bind(n,32411,19)),"~blog/2023/frontend-weekly-2023-archive-2a5.json",32411],95485761:[()=>n.e(7072).then(n.t.bind(n,42510,19)),"~blog/2022/frontend-weekly-2022-tags-rollup-979-list.json",42510],"9576b8f2":[()=>n.e(2655).then(n.bind(n,74662)),"@site/blogs/2022/2022-08-14/index.md",74662],"95bb9347":[()=>n.e(7967).then(n.t.bind(n,95240,19)),"/home/runner/work/frontend-weekly/frontend-weekly/.docusaurus/docusaurus-plugin-content-blog/2023/plugin-route-context-module-100.json",95240],"95f1a559":[()=>n.e(7045).then(n.t.bind(n,29018,19)),"~blog/2022/frontend-weekly-2022-tags-tags-43a.json",29018],"9679232f":[()=>n.e(3458).then(n.t.bind(n,18245,19)),"~blog/2021/frontend-weekly-2021-3cb.json",18245],"9682b0b2":[()=>n.e(9753).then(n.bind(n,19462)),"@site/blogs/2023/2023-04-23/index.md",19462],"97224efe":[()=>n.e(4781).then(n.bind(n,59963)),"@site/blogs/2022/2022-08-14/index.md?truncated=true",59963],"9902accf":[()=>n.e(1206).then(n.bind(n,46723)),"@site/blogs/2023/2023-06-11/index.md?truncated=true",46723],"9a7b715a":[()=>n.e(9052).then(n.bind(n,21194)),"@site/blogs/2022/2022-08-28/index.md?truncated=true",21194],"9ce370e2":[()=>n.e(9441).then(n.bind(n,97787)),"@site/blogs/2022/2022-02-27/index.md?truncated=true",97787],"9e0b726d":[()=>n.e(7803).then(n.bind(n,23614)),"@site/blogs/2024/2024-03-03/index.md?truncated=true",23614],"9e27b63a":[()=>n.e(5379).then(n.bind(n,84458)),"@site/blogs/2022/2022-10-16/index.md?truncated=true",84458],"9e4087bc":[()=>n.e(3608).then(n.bind(n,73293)),"@theme/BlogArchivePage",73293],"9ea486d7":[()=>n.e(919).then(n.t.bind(n,59900,19)),"~blog/2022/frontend-weekly-2022-tags-performance-975.json",59900],"9fa4a310":[()=>n.e(5217).then(n.t.bind(n,46986,19)),"~blog/2022/frontend-weekly-2022-tags-webpack-hmr-b5e.json",46986],a00bcecf:[()=>n.e(3003).then(n.bind(n,10272)),"@site/blogs/2023/2023-12-03/index.md?truncated=true",10272],a02a2c89:[()=>n.e(8520).then(n.bind(n,8944)),"@site/blogs/2024/2024-03-17/index.md?truncated=true",8944],a1b38fa6:[()=>n.e(1134).then(n.t.bind(n,8806,19)),"~blog/2022/frontend-weekly-2022-tags-yarn-2-470-list.json",8806],a26f269a:[()=>n.e(3931).then(n.t.bind(n,47256,19)),"~blog/2024/frontend-weekly-2024-tags-\u673a\u5668\u5b66\u4e60-381-list.json",47256],a2728c33:[()=>n.e(4281).then(n.bind(n,77220)),"@site/blogs/2022/2022-03-27/index.md?truncated=true",77220],a281978f:[()=>n.e(3683).then(n.t.bind(n,59565,19)),"~blog/2022/frontend-weekly-2022-tags-react-native-b4e.json",59565],a2a9ac51:[()=>n.e(3265).then(n.bind(n,34757)),"@site/blogs/2023/2023-12-03/index.md",34757],a2cf8ebe:[()=>n.e(9621).then(n.bind(n,36434)),"@site/blogs/2023/2023-07-23/index.md",36434],a300ea1a:[()=>n.e(5354).then(n.t.bind(n,30158,19)),"~blog/2021/frontend-weekly-2021-tags-npm-e02.json",30158],a36e47dd:[()=>n.e(1039).then(n.bind(n,14545)),"@site/blogs/2022/2022-12-04/index.md",14545],a4037bd4:[()=>n.e(4498).then(n.bind(n,46074)),"@site/blogs/2023/2023-12-31/index.md?truncated=true",46074],a4255d4c:[()=>n.e(3829).then(n.bind(n,7551)),"@site/blogs/2023/2023-08-13/index.md",7551],a43abca3:[()=>n.e(8906).then(n.t.bind(n,78954,19)),"~blog/2022/frontend-weekly-2022-tags-\u9759\u6001\u9875\u9762\u90e8\u7f72-61a.json",78954],a45fcefe:[()=>n.e(8537).then(n.t.bind(n,67944,19)),"~blog/2022/frontend-weekly-2022-tags-es-next-e27-list.json",67944],a6a5b324:[()=>n.e(3127).then(n.bind(n,67994)),"@site/blogs/2022/2022-02-20/index.md",67994],a6aa9e1f:[()=>Promise.all([n.e(532),n.e(176),n.e(4332),n.e(3089)]).then(n.bind(n,48377)),"@theme/BlogListPage",48377],a7097b38:[()=>n.e(3391).then(n.bind(n,42276)),"@site/blogs/2022/2022-05-08/index.md?truncated=true",42276],a8d8aad8:[()=>n.e(8439).then(n.bind(n,53765)),"@site/blogs/2024/2024-02-11/index.md",53765],a91a7faa:[()=>n.e(4736).then(n.t.bind(n,23922,19)),"~blog/2024/frontend-weekly-2024-tags-\u4e1a\u52a1\u6210\u957f-787.json",23922],a947616c:[()=>n.e(5389).then(n.t.bind(n,52947,19)),"~blog/2022/frontend-weekly-2022-tags-idea-99e.json",52947],a97d24b7:[()=>n.e(7073).then(n.t.bind(n,64744,19)),"~blog/2021/frontend-weekly-2021-tags-promise-305.json",64744],aaa38cf8:[()=>n.e(190).then(n.t.bind(n,67666,19)),"~blog/2022/frontend-weekly-2022-tags-\u5f52\u5e76\u6392\u5e8f-a1c-list.json",67666],ab73b4a2:[()=>n.e(5147).then(n.bind(n,46414)),"@site/blogs/2023/2023-09-24/index.md?truncated=true",46414],ac2e308b:[()=>n.e(3609).then(n.bind(n,38963)),"@site/blogs/2023/2023-10-22/index.md",38963],ac680ce7:[()=>n.e(6301).then(n.bind(n,84307)),"@site/blogs/2022/2022-02-13/index.md?truncated=true",84307],acad7bc8:[()=>n.e(9426).then(n.t.bind(n,98418,19)),"~blog/2023/frontend-weekly-2023-page-6-c32.json",98418],acd73f92:[()=>n.e(2769).then(n.t.bind(n,70736,19)),"~blog/2021/frontend-weekly-2021-tags-git-\u5c0f\u6280\u5de7-368-list.json",70736],acf36710:[()=>n.e(4610).then(n.t.bind(n,43686,19)),"~blog/2022/frontend-weekly-2022-tags-performance-975-list.json",43686],adbf9179:[()=>n.e(1922).then(n.t.bind(n,48236,19)),"~blog/2022/frontend-weekly-2022-tags-vue-3-690.json",48236],ae138786:[()=>n.e(973).then(n.t.bind(n,54970,19)),"~blog/2021/frontend-weekly-2021-tags-promise-305-list.json",54970],ae4c023f:[()=>n.e(3480).then(n.bind(n,29278)),"@site/blogs/2022/2022-06-26/index.md?truncated=true",29278],ae9c9e65:[()=>n.e(442).then(n.bind(n,39374)),"@site/blogs/2022/2022-07-17/index.md",39374],aeb4082c:[()=>n.e(4685).then(n.bind(n,17667)),"@site/blogs/2022/2022-12-18/index.md",17667],afb7b356:[()=>n.e(482).then(n.bind(n,384)),"@site/blogs/2022/2022-11-06/index.md",384],b09df939:[()=>n.e(8990).then(n.bind(n,99423)),"@site/blogs/2022/2022-12-11/index.md?truncated=true",99423],b100a8d4:[()=>n.e(7837).then(n.bind(n,31148)),"@site/blogs/2023/2023-10-29/index.md?truncated=true",31148],b10e825b:[()=>n.e(1409).then(n.t.bind(n,15859,19)),"/home/runner/work/frontend-weekly/frontend-weekly/.docusaurus/docusaurus-plugin-content-blog/2022/plugin-route-context-module-100.json",15859],b13a99d6:[()=>n.e(9154).then(n.t.bind(n,69058,19)),"~blog/2022/frontend-weekly-2022-tags-css-page-2-a75-list.json",69058],b1fa2ecf:[()=>n.e(3090).then(n.bind(n,23378)),"@site/blogs/2021/2021-12-05/index.md?truncated=true",23378],b2377777:[()=>n.e(880).then(n.bind(n,43282)),"@site/blogs/2022/2022-09-25/index.md",43282],b23e827a:[()=>n.e(1282).then(n.bind(n,50953)),"@site/blogs/2021/2021-12-19/index.md?truncated=true",50953],b23ea4ba:[()=>n.e(6325).then(n.bind(n,1151)),"@site/blogs/2022/2022-06-12/index.md?truncated=true",1151],b2684a9b:[()=>n.e(1387).then(n.bind(n,16079)),"@site/blogs/2022/2022-12-04/index.md?truncated=true",16079],b2a7027c:[()=>n.e(6926).then(n.bind(n,79054)),"@site/blogs/2023/2023-06-04/index.md",79054],b2c22a51:[()=>n.e(6417).then(n.t.bind(n,82677,19)),"~blog/2022/frontend-weekly-2022-tags-webpack-hmr-b5e-list.json",82677],b33e1212:[()=>n.e(5494).then(n.bind(n,51599)),"@site/blogs/2022/2022-07-03/index.md",51599],b3a6edc6:[()=>n.e(1878).then(n.bind(n,54998)),"@site/blogs/2023/2023-07-16/index.md",54998],b4148fec:[()=>n.e(1284).then(n.t.bind(n,7635,19)),"~blog/2022/frontend-weekly-2022-tags-type-script-923-list.json",7635],b659154d:[()=>n.e(2100).then(n.t.bind(n,157,19)),"~blog/2022/frontend-weekly-2022-tags-react-9de.json",157],b6c6ade3:[()=>n.e(1676).then(n.bind(n,83016)),"@site/blogs/2022/2022-05-15/index.md?truncated=true",83016],b796304a:[()=>n.e(2360).then(n.bind(n,39655)),"@site/blogs/2022/2022-09-18/index.md?truncated=true",39655],b7aa49d2:[()=>n.e(4468).then(n.bind(n,62407)),"@site/blogs/2022/2022-07-03/index.md?truncated=true",62407],b7ba6a3a:[()=>n.e(828).then(n.bind(n,69545)),"@site/blogs/2022/2022-06-12/index.md",69545],b802db3b:[()=>n.e(2488).then(n.t.bind(n,38628,19)),"~blog/2021/frontend-weekly-2021-tags-\u8bed\u4e49\u5316\u7248\u672c-598.json",38628],b9fd8968:[()=>n.e(2053).then(n.bind(n,83100)),"@site/blogs/2022/2022-11-13/index.md",83100],ba2a6679:[()=>n.e(4849).then(n.bind(n,24786)),"@site/blogs/2022/2022-05-22/index.md",24786],ba55b50d:[()=>n.e(8985).then(n.bind(n,51769)),"@site/blogs/2022/2022-09-25/index.md?truncated=true",51769],ba614adb:[()=>n.e(1246).then(n.bind(n,16059)),"@site/blogs/2023/2023-12-10/index.md?truncated=true",16059],ba74b990:[()=>n.e(6199).then(n.bind(n,95624)),"@site/blogs/2022/2022-12-25/index.md?truncated=true",95624],bb9f4062:[()=>n.e(4631).then(n.t.bind(n,71267,19)),"~blog/2022/frontend-weekly-2022-tags-json-\u5e8f\u5217\u5316-c15.json",71267],bc51e9f0:[()=>n.e(7601).then(n.bind(n,6066)),"@site/blogs/2023/2023-05-28/index.md",6066],bc6a5b4f:[()=>n.e(839).then(n.bind(n,61878)),"@site/blogs/2023/2023-07-16/index.md?truncated=true",61878],bcad7f02:[()=>n.e(4578).then(n.t.bind(n,31476,19)),"~blog/2021/frontend-weekly-2021-tags-babel-\u63d2\u4ef6-356-list.json",31476],be6df531:[()=>n.e(1194).then(n.bind(n,54534)),"@site/blogs/2022/2022-10-30/index.md",54534],bf14d1d7:[()=>n.e(5378).then(n.t.bind(n,76958,19)),"~blog/2022/frontend-weekly-2022-tags-babel-02e.json",76958],bf180038:[()=>n.e(9624).then(n.bind(n,32365)),"@site/blogs/2024/2024-01-21/index.md",32365],bf5e64bd:[()=>n.e(7246).then(n.t.bind(n,31805,19)),"~blog/2022/frontend-weekly-2022-tags-diff-\u7b97\u6cd5-c87-list.json",31805],bff93d80:[()=>n.e(2689).then(n.bind(n,99301)),"@site/blogs/2023/2023-01-01/index.md?truncated=true",99301],bffe9d32:[()=>n.e(2803).then(n.bind(n,4524)),"@site/blogs/2023/2023-05-21/index.md?truncated=true",4524],c1140de7:[()=>n.e(8271).then(n.bind(n,97518)),"@site/blogs/2022/2022-04-24/index.md?truncated=true",97518],c2006348:[()=>n.e(9516).then(n.bind(n,97599)),"@site/blogs/2022/2022-05-29/index.md",97599],c33e5259:[()=>n.e(3129).then(n.bind(n,23241)),"@site/blogs/2021/2021-11-28/index.md",23241],c3f61fc1:[()=>n.e(889).then(n.bind(n,21875)),"@site/blogs/2022/2022-05-15/index.md",21875],c49b7daa:[()=>n.e(9170).then(n.t.bind(n,6985,19)),"~blog/2022/frontend-weekly-2022-tags-cli-\u5de5\u5177-334.json",6985],c4dc42da:[()=>n.e(8585).then(n.bind(n,93389)),"@site/blogs/2023/2023-09-17/index.md",93389],c517bd8e:[()=>n.e(9086).then(n.bind(n,6506)),"@site/blogs/2022/2022-09-04/index.md",6506],c5aafa0a:[()=>n.e(5748).then(n.t.bind(n,16980,19)),"~blog/2022/frontend-weekly-2022-tags-leetcode-ab6-list.json",16980],c6194cd0:[()=>n.e(765).then(n.t.bind(n,55156,19)),"~blog/2022/frontend-weekly-2022-page-6-4e4.json",55156],c642636b:[()=>n.e(627).then(n.bind(n,15088)),"@site/blogs/2023/2023-07-02/index.md",15088],c6983b92:[()=>n.e(4323).then(n.t.bind(n,40937,19)),"~blog/2024/frontend-weekly-2024-tags-webpack-c14-list.json",40937],c7a399b8:[()=>n.e(1868).then(n.bind(n,7876)),"@site/blogs/2022/2022-04-17/index.md?truncated=true",7876],c99a9175:[()=>n.e(5094).then(n.t.bind(n,69057,19)),"~blog/2022/frontend-weekly-2022-page-2-591.json",69057],c9f5d8a0:[()=>n.e(9066).then(n.t.bind(n,96816,19)),"~blog/2022/frontend-weekly-2022-968.json",96816],cab2b773:[()=>n.e(9254).then(n.bind(n,51406)),"@site/blogs/2022/2022-02-13/index.md",51406],cb01c7d8:[()=>n.e(1653).then(n.bind(n,69492)),"@site/blogs/2024/2024-12-12-welcome/index.md?truncated=true",69492],cb46548a:[()=>n.e(2046).then(n.t.bind(n,48114,19)),"~blog/2022/blog-post-list-prop-2022.json",48114],cc3e77c2:[()=>n.e(6247).then(n.bind(n,19477)),"@site/blogs/2022/2022-09-18/index.md",19477],ccc49370:[()=>Promise.all([n.e(532),n.e(176),n.e(4332),n.e(6103)]).then(n.bind(n,95666)),"@theme/BlogPostPage",95666],cd02f729:[()=>n.e(9778).then(n.bind(n,29131)),"@site/blogs/2023/2023-08-27/index.md",29131],cd87da7a:[()=>n.e(396).then(n.bind(n,4729)),"@site/blogs/2023/2023-07-09/index.md?truncated=true",4729],ce5f8616:[()=>n.e(3865).then(n.t.bind(n,20638,19)),"~blog/2024/frontend-weekly-2024-023.json",20638],ce6146b9:[()=>n.e(2427).then(n.bind(n,83696)),"@site/blogs/2021/2021-12-19/index.md",83696],cece3433:[()=>n.e(1439).then(n.t.bind(n,78343,19)),"~blog/2022/frontend-weekly-2022-tags-vue-ad7.json",78343],cef333d8:[()=>n.e(3958).then(n.t.bind(n,35495,19)),"~blog/2021/frontend-weekly-2021-tags-chrome-634.json",35495],cf537146:[()=>n.e(2709).then(n.bind(n,95494)),"@site/blogs/2022/2022-04-10/index.md?truncated=true",95494],cf687b45:[()=>n.e(4879).then(n.t.bind(n,98148,19)),"~blog/2021/frontend-weekly-2021-tags-node-js-4d1.json",98148],cf84160d:[()=>n.e(5980).then(n.t.bind(n,59019,19)),"~blog/2024/frontend-weekly-2024-tags-\u673a\u5668\u5b66\u4e60-381.json",59019],d1932438:[()=>n.e(2489).then(n.bind(n,9487)),"@site/blogs/2023/2023-12-17/index.md?truncated=true",9487],d1c621c0:[()=>n.e(3847).then(n.bind(n,63310)),"@site/blogs/2022/2022-08-07/index.md?truncated=true",63310],d1ed239b:[()=>n.e(5812).then(n.bind(n,36746)),"@site/blogs/2023/2023-10-22/index.md?truncated=true",36746],d1fcdef7:[()=>n.e(3199).then(n.bind(n,60108)),"@site/blogs/2023/2023-08-20/index.md?truncated=true",60108],d2abdfb5:[()=>n.e(701).then(n.t.bind(n,45617,19)),"~blog/2022/frontend-weekly-2022-tags-rollup-979.json",45617],d36595dc:[()=>n.e(8936).then(n.t.bind(n,40143,19)),"~blog/2021/frontend-weekly-2021-tags-golang-626-list.json",40143],d3b5c9e1:[()=>n.e(2644).then(n.t.bind(n,1228,19)),"~blog/2021/frontend-weekly-2021-tags-chrome-634-list.json",1228],d446fd6a:[()=>n.e(7060).then(n.t.bind(n,87896,19)),"~blog/2022/frontend-weekly-2022-tags-es-lint-4b7.json",87896],d62b6412:[()=>n.e(756).then(n.bind(n,31027)),"@site/blogs/2023/2023-11-19/index.md?truncated=true",31027],d72d543c:[()=>n.e(6994).then(n.t.bind(n,53911,19)),"~blog/2022/frontend-weekly-2022-tags-golang-page-2-40a.json",53911],d7509b92:[()=>n.e(2615).then(n.bind(n,46478)),"@site/blogs/2023/2023-06-18/index.md",46478],d8389d4a:[()=>n.e(9565).then(n.bind(n,38633)),"@site/blogs/2023/2023-07-23/index.md?truncated=true",38633],d9668e89:[()=>n.e(9025).then(n.bind(n,75304)),"@site/blogs/2022/2022-10-09/index.md?truncated=true",75304],d9fd7198:[()=>n.e(3136).then(n.bind(n,45203)),"@site/blogs/2023/2023-01-08/index.md?truncated=true",45203],da8f78d6:[()=>n.e(6018).then(n.t.bind(n,69292,19)),"~blog/2021/frontend-weekly-2021-tags-webpack-c6e.json",69292],dafb24b9:[()=>n.e(768).then(n.bind(n,35709)),"@site/blogs/2022/2022-08-28/index.md",35709],db5d30ff:[()=>n.e(1960).then(n.bind(n,89806)),"@site/blogs/2023/2023-03-19/index.md",89806],dcfcec88:[()=>n.e(7220).then(n.t.bind(n,91418,19)),"~blog/2021/frontend-weekly-2021-tags-node-js-4d1-list.json",91418],dd563b81:[()=>n.e(6920).then(n.bind(n,26845)),"@site/blogs/2023/2023-11-26/index.md",26845],dda07e9c:[()=>n.e(8344).then(n.bind(n,55869)),"@site/blogs/2023/2023-11-12/index.md",55869],debb4adc:[()=>n.e(5035).then(n.bind(n,43163)),"@site/blogs/2022/2022-11-20/index.md",43163],df013fbd:[()=>n.e(7856).then(n.bind(n,5824)),"@site/blogs/2023/2023-04-30/index.md",5824],df79158e:[()=>n.e(6130).then(n.bind(n,35633)),"@site/blogs/2023/2023-10-15/index.md?truncated=true",35633],e0628d4c:[()=>n.e(3333).then(n.bind(n,12093)),"@site/blogs/2022/2022-10-09/index.md",12093],e2140242:[()=>n.e(2971).then(n.bind(n,60262)),"@site/blogs/2024/2024-01-28/index.md",60262],e32538a8:[()=>n.e(1536).then(n.t.bind(n,59675,19)),"~blog/2022/frontend-weekly-2022-tags-cli-\u5de5\u5177-334-list.json",59675],e4feeb8c:[()=>n.e(9098).then(n.bind(n,7505)),"@site/blogs/2022/2022-03-20/index.md",7505],e5220047:[()=>n.e(5993).then(n.bind(n,76005)),"@site/blogs/2021/2021-11-28/index.md?truncated=true",76005],e5a9b58d:[()=>n.e(1066).then(n.t.bind(n,21005,19)),"~blog/2022/frontend-weekly-2022-tags-git-page-2-5e2-list.json",21005],e5b8488c:[()=>n.e(1093).then(n.t.bind(n,71308,19)),"~blog/2022/frontend-weekly-2022-tags-\u9ed1\u6697\u6a21\u5f0f\u9002\u914d-c60.json",71308],e616d40e:[()=>n.e(4400).then(n.bind(n,67452)),"@site/blogs/2023/2023-12-17/index.md",67452],e6c2a3eb:[()=>n.e(7765).then(n.bind(n,31388)),"@site/blogs/2023/2023-01-15/index.md",31388],e6c381e0:[()=>n.e(5951).then(n.t.bind(n,70652,19)),"~blog/2022/frontend-weekly-2022-tags-css-page-2-a75.json",70652],e6ff846e:[()=>n.e(8841).then(n.bind(n,34252)),"@site/blogs/2022/2022-05-29/index.md?truncated=true",34252],e713937e:[()=>n.e(9968).then(n.bind(n,6794)),"@site/blogs/2024/2024-02-25/index.md?truncated=true",6794],e71e1009:[()=>n.e(710).then(n.t.bind(n,11492,19)),"~blog/2022/frontend-weekly-2022-tags-\u9ed1\u6697\u6a21\u5f0f\u9002\u914d-c60-list.json",11492],e799a75e:[()=>n.e(5911).then(n.bind(n,30897)),"@site/blogs/2023/2023-02-12/index.md?truncated=true",30897],e8392810:[()=>n.e(3243).then(n.t.bind(n,26922,19)),"~blog/2021/frontend-weekly-2021-tags-browserslist-5a8-list.json",26922],e8d7051f:[()=>n.e(5306).then(n.bind(n,77217)),"@site/blogs/2023/2023-08-13/index.md?truncated=true",77217],e970594d:[()=>n.e(6456).then(n.t.bind(n,11703,19)),"~blog/2022/frontend-weekly-2022-tags-diff-b02.json",11703],eaf266c2:[()=>n.e(1484).then(n.t.bind(n,96956,19)),"~blog/2021/frontend-weekly-2021-tags-\u6587\u6863\u90e8\u7f72-7f9-list.json",96956],eb9af83e:[()=>n.e(9164).then(n.t.bind(n,71136,19)),"~blog/2022/frontend-weekly-2022-tags-git-hub-\u5b9a\u65f6\u4efb\u52a1-283-list.json",71136],eca19b80:[()=>n.e(5030).then(n.bind(n,37214)),"@site/blogs/2023/2023-12-10/index.md",37214],ed0ed16d:[()=>n.e(7722).then(n.t.bind(n,80558,19)),"~blog/2021/frontend-weekly-2021-tags-vue-3-6bd.json",80558],ed195d62:[()=>n.e(7164).then(n.bind(n,64229)),"@site/blogs/2023/2023-02-05/index.md",64229],ed8fdd76:[()=>n.e(5393).then(n.t.bind(n,19147,19)),"~blog/2022/frontend-weekly-2022-tags-next-js-f43-list.json",19147],ee6586a4:[()=>n.e(6555).then(n.t.bind(n,46876,19)),"~blog/2024/frontend-weekly-2024-tags-\u7ec4\u4ef6\u5e93\u5b9e\u6218-fd1.json",46876],ee774ae6:[()=>n.e(8607).then(n.bind(n,83964)),"@site/blogs/2024/2024-01-07/index.md",83964],ef681f27:[()=>n.e(5856).then(n.bind(n,13732)),"@site/blogs/2023/2023-10-08/index.md",13732],ef9d0575:[()=>n.e(6204).then(n.t.bind(n,39032,19)),"~blog/2023/frontend-weekly-2023-page-5-b1d.json",39032],efad4974:[()=>n.e(1537).then(n.bind(n,23586)),"@site/blogs/2022/2022-07-10/index.md?truncated=true",23586],f02169d2:[()=>n.e(5438).then(n.bind(n,71511)),"@site/blogs/2022/2022-06-05/index.md",71511],f0838127:[()=>n.e(1403).then(n.t.bind(n,9556,19)),"~blog/2024/frontend-weekly-2024-tags-java-7fb-list.json",9556],f0a2c17a:[()=>n.e(8180).then(n.bind(n,9639)),"@site/blogs/2024/2024-01-28/index.md?truncated=true",9639],f0c653c9:[()=>n.e(2043).then(n.t.bind(n,41084,19)),"~blog/2024/frontend-weekly-2024-tags-\u7f51\u7edc\u76f8\u5173-48c-list.json",41084],f0e802fe:[()=>n.e(1269).then(n.bind(n,36006)),"@site/blogs/2022/2022-03-06/index.md",36006],f14809e7:[()=>n.e(7865).then(n.t.bind(n,55965,19)),"~blog/2022/frontend-weekly-2022-tags-cra-13e.json",55965],f1bf285a:[()=>n.e(3151).then(n.bind(n,4363)),"@site/blogs/2022/2022-11-27/index.md?truncated=true",4363],f2e5f5f4:[()=>n.e(9077).then(n.t.bind(n,308,19)),"~blog/2022/frontend-weekly-2022-tags-diff-b02-list.json",308],f34c4bf8:[()=>n.e(2056).then(n.bind(n,67405)),"@site/blogs/2022/2022-02-06/index.md",67405],f4198d46:[()=>n.e(4094).then(n.bind(n,59271)),"@site/blogs/2023/2023-06-18/index.md?truncated=true",59271],f4cee1a8:[()=>n.e(2947).then(n.t.bind(n,39024,19)),"~blog/2022/frontend-weekly-2022-tags-git-768-list.json",39024],f5960486:[()=>n.e(5450).then(n.bind(n,82641)),"@site/blogs/2023/2023-04-09/index.md?truncated=true",82641],f6ccc0cd:[()=>n.e(2034).then(n.t.bind(n,15745,19)),"/home/runner/work/frontend-weekly/frontend-weekly/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",15745],f7ddcab8:[()=>n.e(5865).then(n.bind(n,29123)),"@site/blogs/2023/2023-09-10/index.md?truncated=true",29123],f814745b:[()=>n.e(1606).then(n.t.bind(n,82090,19)),"~blog/2024/frontend-weekly-2024-tags-\u6e90\u7801\u7cfb\u5217-416-list.json",82090],f9329a04:[()=>n.e(8249).then(n.bind(n,27221)),"@site/blogs/2023/2023-07-02/index.md?truncated=true",27221],fa064f83:[()=>n.e(5399).then(n.bind(n,56802)),"@site/blogs/2023/2023-09-03/index.md?truncated=true",56802],fa9d8089:[()=>n.e(2081).then(n.t.bind(n,82208,19)),"~blog/2022/frontend-weekly-2022-tags-node-js-e1f.json",82208],fad14f54:[()=>n.e(2904).then(n.t.bind(n,49297,19)),"~blog/2021/frontend-weekly-2021-tags-css-in-js-03d.json",49297],fb3799e4:[()=>n.e(6792).then(n.bind(n,36845)),"@site/blogs/2023/2023-03-05/index.md?truncated=true",36845],fb716e4b:[()=>n.e(927).then(n.bind(n,13666)),"@site/blogs/2023/2023-03-26/index.md?truncated=true",13666],fbf1db8d:[()=>n.e(8621).then(n.t.bind(n,54197,19)),"~blog/2024/frontend-weekly-2024-archive-549.json",54197],fbf35eef:[()=>n.e(5829).then(n.t.bind(n,29866,19)),"~blog/2021/frontend-weekly-2021-tags-\u4ee3\u7801\u89c4\u8303-fd6-list.json",29866],fd03b527:[()=>n.e(2921).then(n.t.bind(n,17658,19)),"~blog/2021/frontend-weekly-2021-tags-react-280-list.json",17658],fdf06986:[()=>n.e(7153).then(n.t.bind(n,79260,19)),"~blog/2021/frontend-weekly-2021-tags-css-in-js-03d-list.json",79260],fe0767c3:[()=>n.e(1521).then(n.bind(n,13438)),"@site/blogs/2023/2023-10-01/index.md",13438],fe1eead7:[()=>n.e(138).then(n.bind(n,80295)),"@site/blogs/2023/2023-03-05/index.md",80295],ffa2e393:[()=>n.e(585).then(n.bind(n,76817)),"@site/blogs/2024/2024-03-03/index.md",76817]};function s(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var u=n(3981),d=n(95609);function f(e,t){if("*"===e)return i()({loading:s,loader:()=>n.e(718).then(n.bind(n,40718)),modules:["@theme/NotFound"],webpack:()=>[40718],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],f={},p=[],b=[],g=(0,u.Z)(o);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=c[n];r&&(f[t]=r[0],p.push(r[1]),b.push(r[2]))})),i().Map({loading:s,loader:f,modules:p,webpack:()=>b,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const c=i.__context;return delete i.__context,r.createElement(d.z,{value:c},r.createElement(l,(0,a.Z)({},i,n)))}})}const p=[{path:"/frontend-weekly/2021",component:f("/frontend-weekly/2021","c50"),exact:!0},{path:"/frontend-weekly/2021/11\u670814\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/11\u670814\u65e5\u5185\u5bb9\u6c47\u603b","f2f"),exact:!0},{path:"/frontend-weekly/2021/11\u670821\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/11\u670821\u65e5\u5185\u5bb9\u6c47\u603b","87b"),exact:!0},{path:"/frontend-weekly/2021/11\u670828\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/11\u670828\u65e5\u5185\u5bb9\u6c47\u603b","0d2"),exact:!0},{path:"/frontend-weekly/2021/12\u670812\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/12\u670812\u65e5\u5185\u5bb9\u6c47\u603b","7b1"),exact:!0},{path:"/frontend-weekly/2021/12\u670819\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/12\u670819\u65e5\u5185\u5bb9\u6c47\u603b","ff2"),exact:!0},{path:"/frontend-weekly/2021/12\u670826\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/12\u670826\u65e5\u5185\u5bb9\u6c47\u603b","259"),exact:!0},{path:"/frontend-weekly/2021/12\u67085\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2021/12\u67085\u65e5\u5185\u5bb9\u6c47\u603b","89c"),exact:!0},{path:"/frontend-weekly/2021/archive",component:f("/frontend-weekly/2021/archive","cb7"),exact:!0},{path:"/frontend-weekly/2021/tags",component:f("/frontend-weekly/2021/tags","c04"),exact:!0},{path:"/frontend-weekly/2021/tags/babel-\u63d2\u4ef6",component:f("/frontend-weekly/2021/tags/babel-\u63d2\u4ef6","d09"),exact:!0},{path:"/frontend-weekly/2021/tags/browserslist",component:f("/frontend-weekly/2021/tags/browserslist","767"),exact:!0},{path:"/frontend-weekly/2021/tags/chrome",component:f("/frontend-weekly/2021/tags/chrome","72f"),exact:!0},{path:"/frontend-weekly/2021/tags/common-js",component:f("/frontend-weekly/2021/tags/common-js","833"),exact:!0},{path:"/frontend-weekly/2021/tags/css-in-js",component:f("/frontend-weekly/2021/tags/css-in-js","d56"),exact:!0},{path:"/frontend-weekly/2021/tags/git-\u5c0f\u6280\u5de7",component:f("/frontend-weekly/2021/tags/git-\u5c0f\u6280\u5de7","fe6"),exact:!0},{path:"/frontend-weekly/2021/tags/golang",component:f("/frontend-weekly/2021/tags/golang","1fd"),exact:!0},{path:"/frontend-weekly/2021/tags/node-js",component:f("/frontend-weekly/2021/tags/node-js","e64"),exact:!0},{path:"/frontend-weekly/2021/tags/npm",component:f("/frontend-weekly/2021/tags/npm","a82"),exact:!0},{path:"/frontend-weekly/2021/tags/npm-\u53d1\u5305",component:f("/frontend-weekly/2021/tags/npm-\u53d1\u5305","3d0"),exact:!0},{path:"/frontend-weekly/2021/tags/promise",component:f("/frontend-weekly/2021/tags/promise","a62"),exact:!0},{path:"/frontend-weekly/2021/tags/react",component:f("/frontend-weekly/2021/tags/react","d24"),exact:!0},{path:"/frontend-weekly/2021/tags/react-docs",component:f("/frontend-weekly/2021/tags/react-docs","30a"),exact:!0},{path:"/frontend-weekly/2021/tags/type-script",component:f("/frontend-weekly/2021/tags/type-script","69e"),exact:!0},{path:"/frontend-weekly/2021/tags/vue",component:f("/frontend-weekly/2021/tags/vue","14a"),exact:!0},{path:"/frontend-weekly/2021/tags/vue-3",component:f("/frontend-weekly/2021/tags/vue-3","e21"),exact:!0},{path:"/frontend-weekly/2021/tags/webpack",component:f("/frontend-weekly/2021/tags/webpack","702"),exact:!0},{path:"/frontend-weekly/2021/tags/\u4ee3\u7801\u89c4\u8303",component:f("/frontend-weekly/2021/tags/\u4ee3\u7801\u89c4\u8303","e91"),exact:!0},{path:"/frontend-weekly/2021/tags/\u56de\u6eaf\u7b97\u6cd5",component:f("/frontend-weekly/2021/tags/\u56de\u6eaf\u7b97\u6cd5","e8f"),exact:!0},{path:"/frontend-weekly/2021/tags/\u5f00\u53d1\u89c4\u8303",component:f("/frontend-weekly/2021/tags/\u5f00\u53d1\u89c4\u8303","4a8"),exact:!0},{path:"/frontend-weekly/2021/tags/\u6587\u6863\u90e8\u7f72",component:f("/frontend-weekly/2021/tags/\u6587\u6863\u90e8\u7f72","324"),exact:!0},{path:"/frontend-weekly/2021/tags/\u6784\u5efa\u5de5\u5177",component:f("/frontend-weekly/2021/tags/\u6784\u5efa\u5de5\u5177","325"),exact:!0},{path:"/frontend-weekly/2021/tags/\u7b2c\u4e09\u65b9\u5e93-lockfile",component:f("/frontend-weekly/2021/tags/\u7b2c\u4e09\u65b9\u5e93-lockfile","445"),exact:!0},{path:"/frontend-weekly/2021/tags/\u7bad\u5934\u51fd\u6570",component:f("/frontend-weekly/2021/tags/\u7bad\u5934\u51fd\u6570","54a"),exact:!0},{path:"/frontend-weekly/2021/tags/\u8bed\u4e49\u5316\u7248\u672c",component:f("/frontend-weekly/2021/tags/\u8bed\u4e49\u5316\u7248\u672c","115"),exact:!0},{path:"/frontend-weekly/2022",component:f("/frontend-weekly/2022","0dd"),exact:!0},{path:"/frontend-weekly/2022/10\u670816\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/10\u670816\u65e5\u5185\u5bb9\u6c47\u603b","a8c"),exact:!0},{path:"/frontend-weekly/2022/10\u670823\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/10\u670823\u65e5\u5185\u5bb9\u6c47\u603b","0df"),exact:!0},{path:"/frontend-weekly/2022/10\u67082\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/10\u67082\u65e5\u5185\u5bb9\u6c47\u603b","51e"),exact:!0},{path:"/frontend-weekly/2022/10\u670830\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/10\u670830\u65e5\u5185\u5bb9\u6c47\u603b","3b2"),exact:!0},{path:"/frontend-weekly/2022/10\u67089\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/10\u67089\u65e5\u5185\u5bb9\u6c47\u603b","fc1"),exact:!0},{path:"/frontend-weekly/2022/11\u670813\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/11\u670813\u65e5\u5185\u5bb9\u6c47\u603b","db9"),exact:!0},{path:"/frontend-weekly/2022/11\u670820\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/11\u670820\u65e5\u5185\u5bb9\u6c47\u603b","f5c"),exact:!0},{path:"/frontend-weekly/2022/11\u670827\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/11\u670827\u65e5\u5185\u5bb9\u6c47\u603b","94e"),exact:!0},{path:"/frontend-weekly/2022/11\u67086\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/11\u67086\u65e5\u5185\u5bb9\u6c47\u603b","a20"),exact:!0},{path:"/frontend-weekly/2022/12\u670811\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/12\u670811\u65e5\u5185\u5bb9\u6c47\u603b","30f"),exact:!0},{path:"/frontend-weekly/2022/12\u670818\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/12\u670818\u65e5\u5185\u5bb9\u6c47\u603b","870"),exact:!0},{path:"/frontend-weekly/2022/12\u670825\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/12\u670825\u65e5\u5185\u5bb9\u6c47\u603b","4c6"),exact:!0},{path:"/frontend-weekly/2022/12\u67084\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/12\u67084\u65e5\u5185\u5bb9\u6c47\u603b","eff"),exact:!0},{path:"/frontend-weekly/2022/1\u670816\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/1\u670816\u65e5\u5185\u5bb9\u6c47\u603b","14d"),exact:!0},{path:"/frontend-weekly/2022/1\u670823\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/1\u670823\u65e5\u5185\u5bb9\u6c47\u603b","e30"),exact:!0},{path:"/frontend-weekly/2022/1\u67082\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/1\u67082\u65e5\u5185\u5bb9\u6c47\u603b","455"),exact:!0},{path:"/frontend-weekly/2022/1\u670830\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/1\u670830\u65e5\u5185\u5bb9\u6c47\u603b","cad"),exact:!0},{path:"/frontend-weekly/2022/1\u67089\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/1\u67089\u65e5\u5185\u5bb9\u6c47\u603b","de7"),exact:!0},{path:"/frontend-weekly/2022/2\u670813\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/2\u670813\u65e5\u5185\u5bb9\u6c47\u603b","768"),exact:!0},{path:"/frontend-weekly/2022/2\u670820\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/2\u670820\u65e5\u5185\u5bb9\u6c47\u603b","539"),exact:!0},{path:"/frontend-weekly/2022/2\u670827\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/2\u670827\u65e5\u5185\u5bb9\u6c47\u603b","ee2"),exact:!0},{path:"/frontend-weekly/2022/2\u67086\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/2\u67086\u65e5\u5185\u5bb9\u6c47\u603b","f6e"),exact:!0},{path:"/frontend-weekly/2022/3\u670813\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/3\u670813\u65e5\u5185\u5bb9\u6c47\u603b","2b1"),exact:!0},{path:"/frontend-weekly/2022/3\u670820\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/3\u670820\u65e5\u5185\u5bb9\u6c47\u603b","f2a"),exact:!0},{path:"/frontend-weekly/2022/3\u670827\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/3\u670827\u65e5\u5185\u5bb9\u6c47\u603b","3f4"),exact:!0},{path:"/frontend-weekly/2022/3\u67086\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/3\u67086\u65e5\u5185\u5bb9\u6c47\u603b","6f3"),exact:!0},{path:"/frontend-weekly/2022/4\u670810\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/4\u670810\u65e5\u5185\u5bb9\u6c47\u603b","b5b"),exact:!0},{path:"/frontend-weekly/2022/4\u670817\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/4\u670817\u65e5\u5185\u5bb9\u6c47\u603b","f89"),exact:!0},{path:"/frontend-weekly/2022/4\u670824\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/4\u670824\u65e5\u5185\u5bb9\u6c47\u603b","8a6"),exact:!0},{path:"/frontend-weekly/2022/4\u67083\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/4\u67083\u65e5\u5185\u5bb9\u6c47\u603b","7dc"),exact:!0},{path:"/frontend-weekly/2022/5\u670815\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/5\u670815\u65e5\u5185\u5bb9\u6c47\u603b","d4d"),exact:!0},{path:"/frontend-weekly/2022/5\u67081\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/5\u67081\u65e5\u5185\u5bb9\u6c47\u603b","0e3"),exact:!0},{path:"/frontend-weekly/2022/5\u670822\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/5\u670822\u65e5\u5185\u5bb9\u6c47\u603b","00a"),exact:!0},{path:"/frontend-weekly/2022/5\u670829\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/5\u670829\u65e5\u5185\u5bb9\u6c47\u603b","74a"),exact:!0},{path:"/frontend-weekly/2022/5\u67088\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/5\u67088\u65e5\u5185\u5bb9\u6c47\u603b","a54"),exact:!0},{path:"/frontend-weekly/2022/6\u670812\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/6\u670812\u65e5\u5185\u5bb9\u6c47\u603b","ac8"),exact:!0},{path:"/frontend-weekly/2022/6\u670819\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/6\u670819\u65e5\u5185\u5bb9\u6c47\u603b","404"),exact:!0},{path:"/frontend-weekly/2022/6\u670826\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/6\u670826\u65e5\u5185\u5bb9\u6c47\u603b","dc0"),exact:!0},{path:"/frontend-weekly/2022/6\u67085\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/6\u67085\u65e5\u5185\u5bb9\u6c47\u603b","86d"),exact:!0},{path:"/frontend-weekly/2022/7\u670810\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/7\u670810\u65e5\u5185\u5bb9\u6c47\u603b","f65"),exact:!0},{path:"/frontend-weekly/2022/7\u670817\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/7\u670817\u65e5\u5185\u5bb9\u6c47\u603b","727"),exact:!0},{path:"/frontend-weekly/2022/7\u670824\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/7\u670824\u65e5\u5185\u5bb9\u6c47\u603b","7e6"),exact:!0},{path:"/frontend-weekly/2022/7\u670831\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/7\u670831\u65e5\u5185\u5bb9\u6c47\u603b","8f5"),exact:!0},{path:"/frontend-weekly/2022/7\u67083\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/7\u67083\u65e5\u5185\u5bb9\u6c47\u603b","258"),exact:!0},{path:"/frontend-weekly/2022/8\u670814\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/8\u670814\u65e5\u5185\u5bb9\u6c47\u603b","b54"),exact:!0},{path:"/frontend-weekly/2022/8\u670821\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/8\u670821\u65e5\u5185\u5bb9\u6c47\u603b","740"),exact:!0},{path:"/frontend-weekly/2022/8\u670828\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/8\u670828\u65e5\u5185\u5bb9\u6c47\u603b","618"),exact:!0},{path:"/frontend-weekly/2022/8\u67087\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/8\u67087\u65e5\u5185\u5bb9\u6c47\u603b","d2b"),exact:!0},{path:"/frontend-weekly/2022/9\u670811\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/9\u670811\u65e5\u5185\u5bb9\u6c47\u603b","3ff"),exact:!0},{path:"/frontend-weekly/2022/9\u670818\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/9\u670818\u65e5\u5185\u5bb9\u6c47\u603b","a9c"),exact:!0},{path:"/frontend-weekly/2022/9\u670825\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/9\u670825\u65e5\u5185\u5bb9\u6c47\u603b","ad7"),exact:!0},{path:"/frontend-weekly/2022/9\u67084\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2022/9\u67084\u65e5\u5185\u5bb9\u6c47\u603b","335"),exact:!0},{path:"/frontend-weekly/2022/archive",component:f("/frontend-weekly/2022/archive","27f"),exact:!0},{path:"/frontend-weekly/2022/page/2",component:f("/frontend-weekly/2022/page/2","3b8"),exact:!0},{path:"/frontend-weekly/2022/page/3",component:f("/frontend-weekly/2022/page/3","df4"),exact:!0},{path:"/frontend-weekly/2022/page/4",component:f("/frontend-weekly/2022/page/4","0bf"),exact:!0},{path:"/frontend-weekly/2022/page/5",component:f("/frontend-weekly/2022/page/5","efe"),exact:!0},{path:"/frontend-weekly/2022/page/6",component:f("/frontend-weekly/2022/page/6","4d4"),exact:!0},{path:"/frontend-weekly/2022/tags",component:f("/frontend-weekly/2022/tags","b21"),exact:!0},{path:"/frontend-weekly/2022/tags/babel",component:f("/frontend-weekly/2022/tags/babel","945"),exact:!0},{path:"/frontend-weekly/2022/tags/cli-\u5de5\u5177",component:f("/frontend-weekly/2022/tags/cli-\u5de5\u5177","fe7"),exact:!0},{path:"/frontend-weekly/2022/tags/code-review",component:f("/frontend-weekly/2022/tags/code-review","c16"),exact:!0},{path:"/frontend-weekly/2022/tags/cra",component:f("/frontend-weekly/2022/tags/cra","e83"),exact:!0},{path:"/frontend-weekly/2022/tags/css",component:f("/frontend-weekly/2022/tags/css","f21"),exact:!0},{path:"/frontend-weekly/2022/tags/css/page/2",component:f("/frontend-weekly/2022/tags/css/page/2","599"),exact:!0},{path:"/frontend-weekly/2022/tags/diff",component:f("/frontend-weekly/2022/tags/diff","6ba"),exact:!0},{path:"/frontend-weekly/2022/tags/diff-\u7b97\u6cd5",component:f("/frontend-weekly/2022/tags/diff-\u7b97\u6cd5","f51"),exact:!0},{path:"/frontend-weekly/2022/tags/es-lint",component:f("/frontend-weekly/2022/tags/es-lint","868"),exact:!0},{path:"/frontend-weekly/2022/tags/es-next",component:f("/frontend-weekly/2022/tags/es-next","2bf"),exact:!0},{path:"/frontend-weekly/2022/tags/git",component:f("/frontend-weekly/2022/tags/git","e38"),exact:!0},{path:"/frontend-weekly/2022/tags/git-hub-\u5b9a\u65f6\u4efb\u52a1",component:f("/frontend-weekly/2022/tags/git-hub-\u5b9a\u65f6\u4efb\u52a1","07b"),exact:!0},{path:"/frontend-weekly/2022/tags/git/page/2",component:f("/frontend-weekly/2022/tags/git/page/2","7e3"),exact:!0},{path:"/frontend-weekly/2022/tags/golang",component:f("/frontend-weekly/2022/tags/golang","93f"),exact:!0},{path:"/frontend-weekly/2022/tags/golang/page/2",component:f("/frontend-weekly/2022/tags/golang/page/2","1f8"),exact:!0},{path:"/frontend-weekly/2022/tags/http-\u7f13\u5b58",component:f("/frontend-weekly/2022/tags/http-\u7f13\u5b58","254"),exact:!0},{path:"/frontend-weekly/2022/tags/idea",component:f("/frontend-weekly/2022/tags/idea","09b"),exact:!0},{path:"/frontend-weekly/2022/tags/json-\u5e8f\u5217\u5316",component:f("/frontend-weekly/2022/tags/json-\u5e8f\u5217\u5316","356"),exact:!0},{path:"/frontend-weekly/2022/tags/leetcode",component:f("/frontend-weekly/2022/tags/leetcode","c4d"),exact:!0},{path:"/frontend-weekly/2022/tags/monorepo",component:f("/frontend-weekly/2022/tags/monorepo","645"),exact:!0},{path:"/frontend-weekly/2022/tags/next-js",component:f("/frontend-weekly/2022/tags/next-js","cb3"),exact:!0},{path:"/frontend-weekly/2022/tags/node-js",component:f("/frontend-weekly/2022/tags/node-js","8f9"),exact:!0},{path:"/frontend-weekly/2022/tags/performance",component:f("/frontend-weekly/2022/tags/performance","bfc"),exact:!0},{path:"/frontend-weekly/2022/tags/post-css",component:f("/frontend-weekly/2022/tags/post-css","0f7"),exact:!0},{path:"/frontend-weekly/2022/tags/prettier",component:f("/frontend-weekly/2022/tags/prettier","e68"),exact:!0},{path:"/frontend-weekly/2022/tags/quic",component:f("/frontend-weekly/2022/tags/quic","388"),exact:!0},{path:"/frontend-weekly/2022/tags/react",component:f("/frontend-weekly/2022/tags/react","960"),exact:!0},{path:"/frontend-weekly/2022/tags/react-hooks-\u72b6\u6001\u7ba1\u7406",component:f("/frontend-weekly/2022/tags/react-hooks-\u72b6\u6001\u7ba1\u7406","09e"),exact:!0},{path:"/frontend-weekly/2022/tags/react-native",component:f("/frontend-weekly/2022/tags/react-native","ca9"),exact:!0},{path:"/frontend-weekly/2022/tags/rollup",component:f("/frontend-weekly/2022/tags/rollup","ad1"),exact:!0},{path:"/frontend-weekly/2022/tags/type-script",component:f("/frontend-weekly/2022/tags/type-script","aa4"),exact:!0},{path:"/frontend-weekly/2022/tags/vs-code",component:f("/frontend-weekly/2022/tags/vs-code","57d"),exact:!0},{path:"/frontend-weekly/2022/tags/vue",component:f("/frontend-weekly/2022/tags/vue","81c"),exact:!0},{path:"/frontend-weekly/2022/tags/vue-3",component:f("/frontend-weekly/2022/tags/vue-3","918"),exact:!0},{path:"/frontend-weekly/2022/tags/webpack-hmr",component:f("/frontend-weekly/2022/tags/webpack-hmr","cb4"),exact:!0},{path:"/frontend-weekly/2022/tags/webpack-loader",component:f("/frontend-weekly/2022/tags/webpack-loader","127"),exact:!0},{path:"/frontend-weekly/2022/tags/yaml",component:f("/frontend-weekly/2022/tags/yaml","be9"),exact:!0},{path:"/frontend-weekly/2022/tags/yarn-2",component:f("/frontend-weekly/2022/tags/yarn-2","f6d"),exact:!0},{path:"/frontend-weekly/2022/tags/\u524d\u7aef\u6280\u672f\u65b9\u5411",component:f("/frontend-weekly/2022/tags/\u524d\u7aef\u6280\u672f\u65b9\u5411","0d9"),exact:!0},{path:"/frontend-weekly/2022/tags/\u547d\u4ee4\u884c\u5de5\u5177",component:f("/frontend-weekly/2022/tags/\u547d\u4ee4\u884c\u5de5\u5177","e2c"),exact:!0},{path:"/frontend-weekly/2022/tags/\u5de5\u7a0b\u5316\u65b9\u6848",component:f("/frontend-weekly/2022/tags/\u5de5\u7a0b\u5316\u65b9\u6848","1ec"),exact:!0},{path:"/frontend-weekly/2022/tags/\u5e74\u5ea6\u9ad8\u8d5e\u6587\u7ae0",component:f("/frontend-weekly/2022/tags/\u5e74\u5ea6\u9ad8\u8d5e\u6587\u7ae0","9b6"),exact:!0},{path:"/frontend-weekly/2022/tags/\u5f52\u5e76\u6392\u5e8f",component:f("/frontend-weekly/2022/tags/\u5f52\u5e76\u6392\u5e8f","725"),exact:!0},{path:"/frontend-weekly/2022/tags/\u61d2\u52a0\u8f7d",component:f("/frontend-weekly/2022/tags/\u61d2\u52a0\u8f7d","e3d"),exact:!0},{path:"/frontend-weekly/2022/tags/\u9759\u6001\u9875\u9762\u90e8\u7f72",component:f("/frontend-weekly/2022/tags/\u9759\u6001\u9875\u9762\u90e8\u7f72","b89"),exact:!0},{path:"/frontend-weekly/2022/tags/\u9ed1\u6697\u6a21\u5f0f",component:f("/frontend-weekly/2022/tags/\u9ed1\u6697\u6a21\u5f0f","366"),exact:!0},{path:"/frontend-weekly/2022/tags/\u9ed1\u6697\u6a21\u5f0f\u9002\u914d",component:f("/frontend-weekly/2022/tags/\u9ed1\u6697\u6a21\u5f0f\u9002\u914d","43e"),exact:!0},{path:"/frontend-weekly/2023",component:f("/frontend-weekly/2023","81d"),exact:!0},{path:"/frontend-weekly/2023/10\u670815\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/10\u670815\u65e5\u5185\u5bb9\u6c47\u603b","deb"),exact:!0},{path:"/frontend-weekly/2023/10\u67081\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/10\u67081\u65e5\u5185\u5bb9\u6c47\u603b","066"),exact:!0},{path:"/frontend-weekly/2023/10\u670822\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/10\u670822\u65e5\u5185\u5bb9\u6c47\u603b","5b9"),exact:!0},{path:"/frontend-weekly/2023/10\u670829\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/10\u670829\u65e5\u5185\u5bb9\u6c47\u603b","21b"),exact:!0},{path:"/frontend-weekly/2023/10\u67088\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/10\u67088\u65e5\u5185\u5bb9\u6c47\u603b","923"),exact:!0},{path:"/frontend-weekly/2023/11\u670812\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/11\u670812\u65e5\u5185\u5bb9\u6c47\u603b","0b1"),exact:!0},{path:"/frontend-weekly/2023/11\u670819\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/11\u670819\u65e5\u5185\u5bb9\u6c47\u603b","715"),exact:!0},{path:"/frontend-weekly/2023/11\u670826\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/11\u670826\u65e5\u5185\u5bb9\u6c47\u603b","5be"),exact:!0},{path:"/frontend-weekly/2023/11\u67085\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/11\u67085\u65e5\u5185\u5bb9\u6c47\u603b","6b0"),exact:!0},{path:"/frontend-weekly/2023/12\u670810\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/12\u670810\u65e5\u5185\u5bb9\u6c47\u603b","1c3"),exact:!0},{path:"/frontend-weekly/2023/12\u670817\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/12\u670817\u65e5\u5185\u5bb9\u6c47\u603b","d77"),exact:!0},{path:"/frontend-weekly/2023/12\u670824\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/12\u670824\u65e5\u5185\u5bb9\u6c47\u603b","d96"),exact:!0},{path:"/frontend-weekly/2023/12\u670831\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/12\u670831\u65e5\u5185\u5bb9\u6c47\u603b","463"),exact:!0},{path:"/frontend-weekly/2023/12\u67083\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/12\u67083\u65e5\u5185\u5bb9\u6c47\u603b","6e9"),exact:!0},{path:"/frontend-weekly/2023/1\u670815\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/1\u670815\u65e5\u5185\u5bb9\u6c47\u603b","2e1"),exact:!0},{path:"/frontend-weekly/2023/1\u67081\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/1\u67081\u65e5\u5185\u5bb9\u6c47\u603b","c2d"),exact:!0},{path:"/frontend-weekly/2023/1\u670822\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/1\u670822\u65e5\u5185\u5bb9\u6c47\u603b","f47"),exact:!0},{path:"/frontend-weekly/2023/1\u670829\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/1\u670829\u65e5\u5185\u5bb9\u6c47\u603b","794"),exact:!0},{path:"/frontend-weekly/2023/1\u67088\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/1\u67088\u65e5\u5185\u5bb9\u6c47\u603b","73b"),exact:!0},{path:"/frontend-weekly/2023/2\u670812\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/2\u670812\u65e5\u5185\u5bb9\u6c47\u603b","380"),exact:!0},{path:"/frontend-weekly/2023/2\u670819\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/2\u670819\u65e5\u5185\u5bb9\u6c47\u603b","beb"),exact:!0},{path:"/frontend-weekly/2023/2\u670826\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/2\u670826\u65e5\u5185\u5bb9\u6c47\u603b","c6a"),exact:!0},{path:"/frontend-weekly/2023/2\u67085\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/2\u67085\u65e5\u5185\u5bb9\u6c47\u603b","b73"),exact:!0},{path:"/frontend-weekly/2023/3\u670812\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/3\u670812\u65e5\u5185\u5bb9\u6c47\u603b","59b"),exact:!0},{path:"/frontend-weekly/2023/3\u670819\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/3\u670819\u65e5\u5185\u5bb9\u6c47\u603b","3cb"),exact:!0},{path:"/frontend-weekly/2023/3\u670826\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/3\u670826\u65e5\u5185\u5bb9\u6c47\u603b","ccd"),exact:!0},{path:"/frontend-weekly/2023/3\u67085\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/3\u67085\u65e5\u5185\u5bb9\u6c47\u603b","969"),exact:!0},{path:"/frontend-weekly/2023/4\u670816\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/4\u670816\u65e5\u5185\u5bb9\u6c47\u603b","220"),exact:!0},{path:"/frontend-weekly/2023/4\u670823\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/4\u670823\u65e5\u5185\u5bb9\u6c47\u603b","429"),exact:!0},{path:"/frontend-weekly/2023/4\u67082\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/4\u67082\u65e5\u5185\u5bb9\u6c47\u603b","17e"),exact:!0},{path:"/frontend-weekly/2023/4\u670830\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/4\u670830\u65e5\u5185\u5bb9\u6c47\u603b","179"),exact:!0},{path:"/frontend-weekly/2023/4\u67089\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/4\u67089\u65e5\u5185\u5bb9\u6c47\u603b","6a0"),exact:!0},{path:"/frontend-weekly/2023/5\u670814\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/5\u670814\u65e5\u5185\u5bb9\u6c47\u603b","c48"),exact:!0},{path:"/frontend-weekly/2023/5\u670821\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/5\u670821\u65e5\u5185\u5bb9\u6c47\u603b","4ff"),exact:!0},{path:"/frontend-weekly/2023/5\u670828\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/5\u670828\u65e5\u5185\u5bb9\u6c47\u603b","1f5"),exact:!0},{path:"/frontend-weekly/2023/5\u67087\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/5\u67087\u65e5\u5185\u5bb9\u6c47\u603b","6b4"),exact:!0},{path:"/frontend-weekly/2023/6\u670811\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/6\u670811\u65e5\u5185\u5bb9\u6c47\u603b","9e5"),exact:!0},{path:"/frontend-weekly/2023/6\u670818\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/6\u670818\u65e5\u5185\u5bb9\u6c47\u603b","4b0"),exact:!0},{path:"/frontend-weekly/2023/6\u670825\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/6\u670825\u65e5\u5185\u5bb9\u6c47\u603b","194"),exact:!0},{path:"/frontend-weekly/2023/6\u67084\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/6\u67084\u65e5\u5185\u5bb9\u6c47\u603b","737"),exact:!0},{path:"/frontend-weekly/2023/7\u670816\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/7\u670816\u65e5\u5185\u5bb9\u6c47\u603b","650"),exact:!0},{path:"/frontend-weekly/2023/7\u670823\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/7\u670823\u65e5\u5185\u5bb9\u6c47\u603b","659"),exact:!0},{path:"/frontend-weekly/2023/7\u67082\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/7\u67082\u65e5\u5185\u5bb9\u6c47\u603b","840"),exact:!0},{path:"/frontend-weekly/2023/7\u670830\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/7\u670830\u65e5\u5185\u5bb9\u6c47\u603b","a49"),exact:!0},{path:"/frontend-weekly/2023/7\u67089\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/7\u67089\u65e5\u5185\u5bb9\u6c47\u603b","a38"),exact:!0},{path:"/frontend-weekly/2023/8\u670813\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/8\u670813\u65e5\u5185\u5bb9\u6c47\u603b","08a"),exact:!0},{path:"/frontend-weekly/2023/8\u670820\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/8\u670820\u65e5\u5185\u5bb9\u6c47\u603b","244"),exact:!0},{path:"/frontend-weekly/2023/8\u670827\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/8\u670827\u65e5\u5185\u5bb9\u6c47\u603b","256"),exact:!0},{path:"/frontend-weekly/2023/8\u67086\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/8\u67086\u65e5\u5185\u5bb9\u6c47\u603b","c5a"),exact:!0},{path:"/frontend-weekly/2023/9\u670810\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/9\u670810\u65e5\u5185\u5bb9\u6c47\u603b","aa2"),exact:!0},{path:"/frontend-weekly/2023/9\u670817\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/9\u670817\u65e5\u5185\u5bb9\u6c47\u603b","89b"),exact:!0},{path:"/frontend-weekly/2023/9\u670824\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/9\u670824\u65e5\u5185\u5bb9\u6c47\u603b","0d3"),exact:!0},{path:"/frontend-weekly/2023/9\u67083\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2023/9\u67083\u65e5\u5185\u5bb9\u6c47\u603b","6aa"),exact:!0},{path:"/frontend-weekly/2023/archive",component:f("/frontend-weekly/2023/archive","410"),exact:!0},{path:"/frontend-weekly/2023/page/2",component:f("/frontend-weekly/2023/page/2","c29"),exact:!0},{path:"/frontend-weekly/2023/page/3",component:f("/frontend-weekly/2023/page/3","017"),exact:!0},{path:"/frontend-weekly/2023/page/4",component:f("/frontend-weekly/2023/page/4","376"),exact:!0},{path:"/frontend-weekly/2023/page/5",component:f("/frontend-weekly/2023/page/5","2df"),exact:!0},{path:"/frontend-weekly/2023/page/6",component:f("/frontend-weekly/2023/page/6","c73"),exact:!0},{path:"/frontend-weekly/2024",component:f("/frontend-weekly/2024","860"),exact:!0},{path:"/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/1\u670814\u65e5\u5185\u5bb9\u6c47\u603b","5ea"),exact:!0},{path:"/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/1\u670821\u65e5\u5185\u5bb9\u6c47\u603b","f9e"),exact:!0},{path:"/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/1\u670828\u65e5\u5185\u5bb9\u6c47\u603b","313"),exact:!0},{path:"/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/1\u67087\u65e5\u5185\u5bb9\u6c47\u603b","52a"),exact:!0},{path:"/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/2\u670811\u65e5\u5185\u5bb9\u6c47\u603b","48f"),exact:!0},{path:"/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/2\u670818\u65e5\u5185\u5bb9\u6c47\u603b","1b9"),exact:!0},{path:"/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/2\u670825\u65e5\u5185\u5bb9\u6c47\u603b","b00"),exact:!0},{path:"/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/2\u67084\u65e5\u5185\u5bb9\u6c47\u603b","c9f"),exact:!0},{path:"/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/3\u670810\u65e5\u5185\u5bb9\u6c47\u603b","aa6"),exact:!0},{path:"/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/3\u670817\u65e5\u5185\u5bb9\u6c47\u603b","691"),exact:!0},{path:"/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b",component:f("/frontend-weekly/2024/3\u67083\u65e5\u5185\u5bb9\u6c47\u603b","c81"),exact:!0},{path:"/frontend-weekly/2024/archive",component:f("/frontend-weekly/2024/archive","714"),exact:!0},{path:"/frontend-weekly/2024/page/2",component:f("/frontend-weekly/2024/page/2","687"),exact:!0},{path:"/frontend-weekly/2024/tags",component:f("/frontend-weekly/2024/tags","d06"),exact:!0},{path:"/frontend-weekly/2024/tags/golang",component:f("/frontend-weekly/2024/tags/golang","9e4"),exact:!0},{path:"/frontend-weekly/2024/tags/java",component:f("/frontend-weekly/2024/tags/java","4df"),exact:!0},{path:"/frontend-weekly/2024/tags/type-script",component:f("/frontend-weekly/2024/tags/type-script","b3e"),exact:!0},{path:"/frontend-weekly/2024/tags/webpack",component:f("/frontend-weekly/2024/tags/webpack","1d8"),exact:!0},{path:"/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f",component:f("/frontend-weekly/2024/tags/\u4e1a\u52a1\u6210\u957f","449"),exact:!0},{path:"/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6",component:f("/frontend-weekly/2024/tags/\u524d\u7aef\u6846\u67b6","039"),exact:!0},{path:"/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316",component:f("/frontend-weekly/2024/tags/\u6027\u80fd\u4f18\u5316","c9b"),exact:!0},{path:"/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60",component:f("/frontend-weekly/2024/tags/\u673a\u5668\u5b66\u4e60","41c"),exact:!0},{path:"/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217",component:f("/frontend-weekly/2024/tags/\u6e90\u7801\u7cfb\u5217","dc7"),exact:!0},{path:"/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218",component:f("/frontend-weekly/2024/tags/\u7ec4\u4ef6\u5e93\u5b9e\u6218","0b4"),exact:!0},{path:"/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173",component:f("/frontend-weekly/2024/tags/\u7f51\u7edc\u76f8\u5173","557"),exact:!0},{path:"/frontend-weekly/2024/welcome",component:f("/frontend-weekly/2024/welcome","826"),exact:!0},{path:"/frontend-weekly/markdown-page",component:f("/frontend-weekly/markdown-page","3c9"),exact:!0},{path:"/frontend-weekly/",component:f("/frontend-weekly/","bbf"),exact:!0},{path:"*",component:f("*")}]},59100:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(59496);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},6569:(e,t,n)=>{"use strict";var r=n(59496),a=n(87995),o=n(78736),i=n(8663),l=n(80689);const c=[n(78708),n(32444),n(71630),n(14211)];var s=n(62409),u=n(83442),d=n(64778);function f(e,t,n){return void 0===n&&(n=[]),e.some((function(e){var r=e.path?(0,u.LX)(t,e):n.length?n[n.length-1].match:u.F0.computeRootMatch(t);return r&&(n.push({route:e,match:r}),e.routes&&f(e.routes,t,n)),r})),n}function p(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var b=n(23050),g=n(79375),m=n(58102),h=n(10018),y=n(60542),w=n(5572),v=n(59386);const k="default";var _=n(50284);function x(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,w.l)();return r.createElement(b.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function E(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),a=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,u.TH)();return e+(0,m.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(b.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function S(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,h.L)();return r.createElement(r.Fragment,null,r.createElement(b.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:v.h})),n&&r.createElement(y.d,{image:n}),r.createElement(E,null),r.createElement(x,null),r.createElement(_.Z,{tag:k,locale:e}),r.createElement(b.Z,null,t.map(((e,t)=>r.createElement("meta",(0,d.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if(f(s.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var A=n(59100),L=n(25162);function N(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r(t.default?.[e]??t[e])?.(...n)));return()=>a.forEach((e=>e?.()))}const P=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1));document.getElementById(e)?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),N("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function O(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>f(s.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{constructor(e){super(e),this.previousLocation=void 0,this.routeUpdateCleanupCb=void 0,this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?N("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=N("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),O(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(P,{previousLocation:this.previousLocation,location:t},r.createElement(u.AW,{location:t,render:()=>e}))}}const I=R,M="docusaurus-base-url-issue-banner-container",j="docusaurus-base-url-issue-banner",D="docusaurus-base-url-issue-banner-suggestion-container",F="__DOCUSAURUS_INSERT_BASEURL_BANNER";function B(e){return`\nwindow['${F}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${F}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${M}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[F]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(b.Z,null,r.createElement("script",null,B(e))),r.createElement("div",{id:M}))}function z(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,u.TH)();return t&&n===e?r.createElement($,null):null}function U(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,g.Z)(),i=(0,m.Z)(e),{htmlLang:l,direction:c}=o[a];return r.createElement(b.Z,null,r.createElement("html",{lang:l,dir:c}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var Z=n(95363);function H(){const e=function(e,t,n){return void 0===t&&(t={}),void 0===n&&(n={}),e?r.createElement(u.rs,n,e.map((function(e,n){return r.createElement(u.AW,{key:e.key||n,path:e.path,exact:e.exact,strict:e.strict,render:function(n){return e.render?e.render((0,d.Z)({},n,{},t,{route:e})):r.createElement(e.component,(0,d.Z)({},n,t,{route:e}))}})}))):null}(s.Z),t=(0,u.TH)();return r.createElement(Z.Z,null,r.createElement(L.M,null,r.createElement(A.t,null,r.createElement(p,null,r.createElement(U,null),r.createElement(S,null),r.createElement(z,null),r.createElement(I,{location:T(t)},e)))))}var V=n(16887);const G=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();(document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode)?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var W=n(3981);const q=new Set,Y=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!K()&&!Y.has(e)&&!q.has(e))(e))return!1;q.add(e);const t=f(s.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(V).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,W.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?G(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!Y.has(e))(e)&&(Y.add(e),O(e))},X=Object.freeze(Q);if(l.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;O(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},25162:(e,t,n)=>{"use strict";n.d(t,{_:()=>s,M:()=>u});var r=n(59496),a=n(36809);const o=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var i=n(57529);const l=JSON.parse('{"docusaurusVersion":"2.3.1","siteVersion":"0.0.0","pluginVersions":{"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.3.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.3.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.3.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.3.1"}}}'),c={siteConfig:a.default,siteMetadata:l,globalData:{},i18n:o,codeTranslations:i},s=r.createContext(c);function u(e){let{children:t}=e;return r.createElement(s.Provider,{value:c},t)}},95363:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(59496),a=n(80689),o=n(23050),i=n(68644);function l(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}function c(e){let{error:t,tryAgain:n}=e;return r.createElement(u,{fallback:()=>r.createElement(l,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(i.Z,null,r.createElement(l,{error:t,tryAgain:n})))}const s=e=>r.createElement(c,e);class u extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??s)(e)}return e??null}}},80689:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},23050:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(59496),a=n(8663);function o(e){return r.createElement(a.ql,e)}},87599:(e,t,n)=>{"use strict";n.d(t,{Z:()=>g});var r=n(64778),a=n(59496),o=n(78736),i=n(65),l=n(79375),c=n(80387),s=n(80689);const u=a.createContext({collectLink:()=>{}}),d=()=>(0,a.useContext)(u);var f=n(58102);const p=e=>e.startsWith("/");function b(e,t){let{isNavLink:n,to:u,href:b,activeClassName:g,isActive:m,"data-noBrokenLinkCheck":h,autoAddBaseUrl:y=!0,...w}=e;const{siteConfig:{trailingSlash:v,baseUrl:k}}=(0,l.Z)(),{withBaseUrl:_}=(0,f.C)(),x=d(),E=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>E.current));const S=u||b;const C=(0,c.Z)(S),T=S?.replace("pathname://","");let A=void 0!==T?(L=T,y&&p(L)?_(L):L):void 0;var L;A&&C&&(A=(0,i.applyTrailingSlash)(A,{trailingSlash:v,baseUrl:k}));const N=(0,a.useRef)(!1),P=n?o.OL:o.rU,O=s.Z.canUseIntersectionObserver,R=(0,a.useRef)(),I=()=>{N.current||null==A||(window.docusaurus.preload(A),N.current=!0)};(0,a.useEffect)((()=>(!O&&C&&null!=A&&window.docusaurus.prefetch(A),()=>{O&&R.current&&R.current.disconnect()})),[R,A,O,C]);const M=A?.startsWith("#")??!1,j=!A||!C||M;return j||h||x.collectLink(A),j?a.createElement("a",(0,r.Z)({ref:E,href:A},S&&!C&&{target:"_blank",rel:"noopener noreferrer"},w)):a.createElement(P,(0,r.Z)({},w,{onMouseEnter:I,onTouchStart:I,innerRef:e=>{E.current=e,O&&e&&C&&(R.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(R.current.unobserve(e),R.current.disconnect(),null!=A&&window.docusaurus.prefetch(A))}))})),R.current.observe(e))},to:A},n&&{isActive:m,activeClassName:g}))}const g=a.forwardRef(b)},75883:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},30159:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c,I:()=>l});var r=n(59496);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(57529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function c(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},80387:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},58102:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(59496),a=n(79375),o=n(80387);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},79375:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(59496),a=n(25162);function o(){return(0,r.useContext)(a._)}},72400:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(59496),a=n(59100);function o(){return(0,r.useContext)(a._)}},3981:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t=".",n={};return function e(a,o){Object.entries(a).forEach((a=>{let[i,l]=a;const c=o?`${o}${t}${i}`:i;r(l)?e(l,c):n[c]=l}))}(e),n}},95609:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(59496);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},16628:(e,t,n)=>{"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function a(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(){return i=Object.assign||function(e){for(var t=1;t{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(29981),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},32444:(e,t,n)=>{"use strict";n.r(t);var r=n(20999),a=n(36809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(55898)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},68644:(e,t,n)=>{"use strict";n.d(t,{Z:()=>It});var r=n(59496),a=n(45924),o=n(95363),i=n(60542),l=n(64778),c=n(83442),s=n(30159),u=n(48251);function d(e){const t=(0,c.TH)(),n=(0,u.D9)(t),a=(0,u.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&a({location:t,previousLocation:n})}),[a,t,n])}const f="docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function b(){const e=(0,r.useRef)(null),{action:t}=(0,c.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(f);t&&p(t)}),[]);return d((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const g=(0,s.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function m(e){const t=e.children??g,{containerRef:n,onClick:a}=b();return r.createElement("div",{ref:n,role:"region","aria-label":g},r.createElement("a",(0,l.Z)({},e,{href:`#${f}`,onClick:a}),t))}var h=n(77685),y=n(59386);const w={skipToContent:"skipToContent_Rzz1"};function v(){return r.createElement(m,{className:w.skipToContent})}var k=n(10018),_=n(72400),x=n(74242);const E=(0,x.WA)("docusaurus.announcement.dismiss"),S=(0,x.WA)("docusaurus.announcement.id"),C=()=>"true"===E.get(),T=e=>E.set(String(e)),A=r.createContext(null);function L(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...c}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},c),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const N={closeButton:"closeButton_b7KD"};function P(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,s.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",N.closeButton,e.className)}),r.createElement(L,{width:14,height:14,strokeWidth:3.1}))}const O={content:"content_nAGp"};function R(e){const{announcementBar:t}=(0,k.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(O.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const I={announcementBar:"announcementBar_tpxO",announcementBarPlaceholder:"announcementBarPlaceholder_qe10",announcementBarClose:"announcementBarClose_XzJw",announcementBarContent:"announcementBarContent_insu"};function M(){const{announcementBar:e}=(0,k.L)(),{isActive:t,close:n}=function(){const e=(0,r.useContext)(A);if(!e)throw new u.i6("AnnouncementBarProvider");return e}();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:I.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:I.announcementBarPlaceholder}),r.createElement(R,{className:I.announcementBarContent}),i&&r.createElement(P,{onClick:n,className:I.announcementBarClose}))}var j=n(4166),D=n(49361),F=n(37795);const B=r.createContext(void 0);function $(){const e=function(){const e=(0,j.HY)(),{items:t}=(0,k.L)().navbar;return 0===t.length&&!e.component}(),t=(0,D.i)(),n=!e&&"mobile"===t,[a,o]=(0,r.useState)(!1);(0,F.Rb)((()=>{if(a)return o(!1),!1}));const i=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&o(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:i,shown:a})),[e,n,i,a])}function z(e){let{children:t}=e;const n=$();return r.createElement(B.Provider,{value:n},t)}function U(){const e=r.useContext(B);if(void 0===e)throw new u.i6("NavbarMobileSidebarProvider");return e}var Z=n(28238);const H=r.createContext(null);function V(e){let{children:t}=e;const n=function(){const e=U(),t=(0,j.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,u.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(H.Provider,{value:n},t)}function G(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function W(){const e=(0,r.useContext)(H);if(!e)throw new u.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,j.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:G(o)})),[a,o,t])}function q(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=W();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var Y=n(67054);function K(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function Q(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const X={toggle:"toggle_HPIb",toggleButton:"toggleButton_yRlM",darkToggleIcon:"darkToggleIcon_lcNQ",lightToggleIcon:"lightToggleIcon_Vljy",toggleButtonDisabled:"toggleButtonDisabled_oHIz"};function J(e){let{className:t,value:n,onChange:o}=e;const i=(0,_.Z)(),l=(0,s.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===n?(0,s.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,s.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)(X.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",X.toggleButton,!i&&X.toggleButtonDisabled),type:"button",onClick:()=>o("dark"===n?"light":"dark"),disabled:!i,title:l,"aria-label":l,"aria-live":"polite"},r.createElement(K,{className:(0,a.Z)(X.toggleIcon,X.lightToggleIcon)}),r.createElement(Q,{className:(0,a.Z)(X.toggleIcon,X.darkToggleIcon)})))}const ee=r.memo(J);function te(e){let{className:t}=e;const n=(0,k.L)().colorMode.disableSwitch,{colorMode:a,setColorMode:o}=(0,Y.I)();return n?null:r.createElement(ee,{className:t,value:a,onChange:o})}var ne=n(87599),re=n(58102),ae=n(79375);const oe={themedImage:"themedImage_DeRy","themedImage--light":"themedImage--light_hbln","themedImage--dark":"themedImage--dark_qgR1"};function ie(e){const t=(0,_.Z)(),{colorMode:n}=(0,Y.I)(),{sources:o,className:i,alt:c,...s}=e,u=t?"dark"===n?["dark"]:["light"]:["light","dark"];return r.createElement(r.Fragment,null,u.map((e=>r.createElement("img",(0,l.Z)({key:e,src:o[e],alt:c,className:(0,a.Z)(oe.themedImage,oe[`themedImage--${e}`],i)},s)))))}function le(e){let{logo:t,alt:n,imageClassName:a}=e;const o={light:(0,re.Z)(t.src),dark:(0,re.Z)(t.srcDark||t.src)},i=r.createElement(ie,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return a?r.createElement("div",{className:a},i):i}function ce(e){const{siteConfig:{title:t}}=(0,ae.Z)(),{navbar:{title:n,logo:a}}=(0,k.L)(),{imageClassName:o,titleClassName:i,...c}=e,s=(0,re.Z)(a?.href||"/"),u=n?"":t,d=a?.alt??u;return r.createElement(ne.Z,(0,l.Z)({to:s},c,a?.target&&{target:a.target}),a&&r.createElement(le,{logo:a,alt:d,imageClassName:o}),null!=n&&r.createElement("b",{className:i},n))}function se(){return r.createElement(ce,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function ue(){const e=U();return r.createElement("button",{type:"button","aria-label":(0,s.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(L,{color:"var(--ifm-color-emphasis-600)"}))}function de(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(se,null),r.createElement(te,{className:"margin-right--md"}),r.createElement(ue,null))}var fe=n(80387);function pe(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}const be={iconExternalLink:"iconExternalLink_LBPb"};function ge(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:be.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}function me(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:c,isDropdownLink:s,prependBaseUrlToHref:u,...d}=e;const f=(0,re.Z)(a),p=(0,re.Z)(t),b=(0,re.Z)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,fe.Z)(o),m=c?{dangerouslySetInnerHTML:{__html:c}}:{children:r.createElement(r.Fragment,null,i,g&&r.createElement(ge,s&&{width:12,height:12}))};return o?r.createElement(ne.Z,(0,l.Z)({href:u?b:o},d,m)):r.createElement(ne.Z,(0,l.Z)({to:f,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?pe(n,t.pathname):t.pathname.startsWith(p)},d,m))}function he(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(me,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ye(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(me,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function we(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ye:he;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ve=n(25777);n(62409);function ke(e,t){return e.some((e=>function(e,t){return!!function(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}(e.to,t)||!!pe(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function _e(e){let{items:t,position:n,className:o,onClick:i,...c}=e;const s=(0,r.useRef)(null),[u,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{s.current&&!s.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[s]),r.createElement("div",{ref:s,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":u})},r.createElement(me,(0,l.Z)({"aria-haspopup":"true","aria-expanded":u,role:"button",href:c.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},c,{onClick:c.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!u))}}),c.children??c.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,n)=>r.createElement(Je,(0,l.Z)({isDropdownItem:!0,onKeyDown:e=>{if(n===t.length-1&&"Tab"===e.key){e.preventDefault(),d(!1);const t=s.current.nextElementSibling;if(t){(t instanceof HTMLAnchorElement?t:t.querySelector("a")).focus()}}},activeClassName:"dropdown__link--active"},e,{key:n}))))))}function xe(e){let{items:t,className:n,position:o,onClick:i,...s}=e;const u=function(){const{siteConfig:{baseUrl:e}}=(0,ae.Z)(),{pathname:t}=(0,c.TH)();return t.replace(e,"/")}(),d=ke(t,u),{collapsed:f,toggleCollapsed:p,setCollapsed:b}=(0,ve.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&b(!d)}),[u,d,b]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":f})},r.createElement(me,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},s,{onClick:e=>{e.preventDefault(),p()}}),s.children??s.label),r.createElement(ve.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:f},t.map(((e,t)=>r.createElement(Je,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function Ee(e){let{mobile:t=!1,...n}=e;const a=t?xe:_e;return r.createElement(a,n)}var Se=n(5572);function Ce(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const Te={iconLanguage:"iconLanguage_sh8s"};var Ae=n(75883);const Le={searchBox:"searchBox_mmj0"};function Ne(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,Le.searchBox)},t)}const Pe="default";function Oe(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,ae.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const Re=e=>e.versions.find((e=>e.isLast));function Ie(e,t){const n=function(e,t){const n=Re(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,c.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),r=n?.docs.find((e=>!!(0,c.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:r,alternateDocVersions:r?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(r.id):{}}}const Me={},je=()=>Oe("docusaurus-plugin-content-docs")??Me,De=e=>function(e,t,n){void 0===t&&(t=Pe),void 0===n&&(n={});const r=Oe(e)?.[t];if(!r&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return r}("docusaurus-plugin-content-docs",e,{failfast:!0});function Fe(e){const t=De(e),{pathname:n}=(0,c.TH)();return Ie(t,n)}const Be=e=>`docs-preferred-version-${e}`,$e={save:(e,t,n)=>{(0,x.WA)(Be(e),{persistence:t}).set(n)},read:(e,t)=>(0,x.WA)(Be(e),{persistence:t}).get(),clear:(e,t)=>{(0,x.WA)(Be(e),{persistence:t}).del()}},ze=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const Ue=r.createContext(null);function Ze(){const e=je(),t=(0,k.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,o]=(0,r.useState)((()=>ze(n)));(0,r.useEffect)((()=>{o(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=$e.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:($e.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){$e.save(e,t,n),o((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function He(e){let{children:t}=e;const n=Ze();return r.createElement(Ue.Provider,{value:n},t)}function Ve(){const e=(0,r.useContext)(Ue);if(!e)throw new u.i6("DocsPreferredVersionContextProvider");return e}function Ge(e){void 0===e&&(e=Pe);const t=De(e),[n,a]=Ve(),{preferredVersionName:o}=n[e];return{preferredVersion:t.versions.find((e=>e.name===o))??null,savePreferredVersionName:(0,r.useCallback)((t=>{a.savePreferredVersion(e,t)}),[a,e])}}var We=n(77619);const qe=!!je;function Ye(e){const{activeVersion:t}=Fe(e),{preferredVersion:n}=Ge(e),a=function(e){const t=De(e);return Re(t)}(e);return(0,r.useMemo)((()=>(0,We.j)([t,n,a].filter(Boolean))),[t,n,a])}const Ke=e=>e.docs.find((t=>t.id===e.mainDocId));const Qe=e=>e.docs.find((t=>t.id===e.mainDocId));const Xe={...{default:we,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:u,localeConfigs:d}}=(0,ae.Z)(),f=(0,Se.l)(),{search:p,hash:b}=(0,c.TH)(),g=[...n,...u.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${b}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],m=t?(0,s.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(Ee,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(Ce,{className:Te.iconLanguage}),m),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(Ne,{className:n},r.createElement(Ae.Z,null))},dropdown:Ee,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=Fe(a),c=function(e,t){const n=Ye(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`DocNavbarItem: couldn't find any doc with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,We.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}(t,a);return null===c?null:r.createElement(we,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===c.path||!!i?.sidebar&&i.sidebar===c.sidebar,label:n??c.id,to:c.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=Fe(a),c=function(e,t){const n=Ye(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\n Available sidebar ids are:\n - ${Object.keys(t).join("\n- ")}`);return r[1]}),[e,n])}(t,a).link;if(!c)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(we,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??c.label,to:c.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=Ye(a)[0],c=t??i.label,s=n??Ke(i).path;return r.createElement(we,(0,l.Z)({},o,{label:c,to:s}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...u}=e;const{search:d,hash:f}=(0,c.TH)(),p=Fe(n),b=De(n).versions,{savePreferredVersionName:g}=Ge(n),m=[...o,...b.map((e=>{const t=p.alternateDocVersions[e.name]??Qe(e);return{label:e.label,to:`${t.path}${d}${f}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...i],h=Ye(n)[0],y=t&&m.length>1?(0,s.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):h.label,w=t&&m.length>1?void 0:Qe(h).path;return m.length<=1?r.createElement(we,(0,l.Z)({},u,{mobile:t,label:y,to:w,isActive:a?()=>!1:void 0})):r.createElement(Ee,(0,l.Z)({},u,{mobile:t,label:y,to:w,items:m,isActive:a?()=>!1:void 0}))}},"custom-doc-version-navbar-item":e=>{let{mobile:t,items:n,...a}=e;const{pathname:o}=(0,c.TH)(),i=n.at(0),s=n.find((e=>o.includes(e.to)));return r.createElement(Ee,(0,l.Z)({},a,{mobile:t,label:`Blog of ${s?.label||i.label}`,to:s?.to||i.to,items:n}))}};function Je(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Xe[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function et(){const e=U(),t=(0,k.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(Je,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function tt(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(s.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function nt(){const e=0===(0,k.L)().navbar.items.length,t=W();return r.createElement(r.Fragment,null,!e&&r.createElement(tt,{onClick:()=>t.hide()}),t.content)}function rt(){const e=U();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(q,{header:r.createElement(de,null),primaryMenu:r.createElement(et,null),secondaryMenu:r.createElement(nt,null)}):null}const at={navbarHideable:"navbarHideable_hfek",navbarHidden:"navbarHidden_Fu3z"};function ot(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function it(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,k.L)(),i=U(),{navbarRef:l,isNavbarVisible:c}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,Z.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+s{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,s.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[at.navbarHideable,!c&&at.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(ot,{onClick:i.toggle}),r.createElement(rt,null))}const lt="right";function ct(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function st(){const{toggle:e,shown:t}=U();return r.createElement("button",{onClick:e,"aria-label":(0,s.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(ct,null))}const ut={colorModeToggle:"colorModeToggle_KItF"};function dt(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Je,(0,l.Z)({},e,{key:t})))))}function ft(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function pt(){const e=U(),t=(0,k.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??lt)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement(ft,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(st,null),r.createElement(se,null),r.createElement(dt,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(dt,{items:a}),r.createElement(te,{className:ut.colorModeToggle}),!o&&r.createElement(Ne,null,r.createElement(Ae.Z,null)))})}function bt(){return r.createElement(it,null,r.createElement(pt,null))}function gt(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...c}=t,s=(0,re.Z)(n),u=(0,re.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(ne.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?u:a}:{to:s},c),o,a&&!(0,fe.Z)(a)&&r.createElement(ge,null))}function mt(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(gt,{item:t}))}function ht(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(mt,{key:t,item:e})))))}function yt(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(ht,{key:t,column:e}))))}function wt(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function vt(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(gt,{item:t})}function kt(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(vt,{item:e}),t.length!==n+1&&r.createElement(wt,null))))))}function _t(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(yt,{columns:t}):r.createElement(kt,{links:t})}const xt={footerLogoLink:"footerLogoLink_aXGI"};function Et(e){let{logo:t}=e;const{withBaseUrl:n}=(0,re.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(ie,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function St(e){let{logo:t}=e;return t.href?r.createElement(ne.Z,{href:t.href,className:xt.footerLogoLink,target:t.target},r.createElement(Et,{logo:t})):r.createElement(Et,{logo:t})}function Ct(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function Tt(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function At(){const{footer:e}=(0,k.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(Tt,{style:o,links:n&&n.length>0&&r.createElement(_t,{links:n}),logo:a&&r.createElement(St,{logo:a}),copyright:t&&r.createElement(Ct,{copyright:t})})}const Lt=r.memo(At),Nt=(0,u.Qc)([Y.S,function(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,k.L)(),t=(0,_.Z)(),[n,a]=(0,r.useState)((()=>!!t&&C()));(0,r.useEffect)((()=>{a(C())}),[]);const o=(0,r.useCallback)((()=>{T(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=S.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;S.set(t),r&&T(!1),!r&&C()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:o})),[e,n,o])}();return r.createElement(A.Provider,{value:n},t)},Z.OC,function(e){let{children:t}=e;return qe?r.createElement(He,null,t):r.createElement(r.Fragment,null,t)},i.VC,function(e){let{children:t}=e;return r.createElement(j.n2,null,r.createElement(z,null,r.createElement(V,null,t)))}]);function Pt(e){let{children:t}=e;return r.createElement(Nt,null,t)}function Ot(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(s.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(s.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}const Rt={mainWrapper:"mainWrapper_NWrx"};function It(e){const{children:t,noFooter:n,wrapperClassName:l,title:c,description:s}=e;return(0,y.t)(),r.createElement(Pt,null,r.createElement(i.d,{title:c,description:s}),r.createElement(v,null),r.createElement(M,null),r.createElement(bt,null),r.createElement("div",{id:f,className:(0,a.Z)(h.k.wrapper.main,Rt.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(Ot,e)},t)),!n&&r.createElement(Lt,null))}},50284:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(59496),a=n(23050);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},25777:(e,t,n)=>{"use strict";n.d(t,{u:()=>l,z:()=>g});var r=n(64778),a=n(59496),o=n(80689);const i="ease-in-out";function l(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const c={display:"none",overflow:"hidden",height:"0px"},s={display:"block",overflow:"visible",height:"auto"};function u(e,t){const n=t?c:s;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function d(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??i}`,height:`${t}px`}}function l(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return u(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(l(),requestAnimationFrame((()=>{e.style.height=c.height,e.style.overflow=c.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{l()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function f(e){if(!o.Z.canUseDOM)return e?c:s}function p(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:c}=e;const s=(0,a.useRef)(null);return d({collapsibleRef:s,collapsed:n,animation:o}),a.createElement(t,{ref:s,style:c?void 0:f(n),onTransitionEnd:e=>{"height"===e.propertyName&&(u(s.current,n),i?.(n))},className:l},r)}function b(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,c]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&c(t)}),[o,t]),o?a.createElement(p,(0,r.Z)({},n,{collapsed:l})):null}function g(e){let{lazy:t,...n}=e;const r=t?b:p;return a.createElement(r,n)}},67054:(e,t,n)=>{"use strict";n.d(t,{I:()=>m,S:()=>g});var r=n(59496),a=n(80689),o=n(48251),i=n(74242),l=n(10018);const c=r.createContext(void 0),s="theme",u=(0,i.WA)(s),d={light:"light",dark:"dark"},f=e=>e===d.dark?d.dark:d.light,p=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),b=e=>{u.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(p(e));(0,r.useEffect)((()=>{t&&u.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&b(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),u.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==s)return;const t=u.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const c=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(c.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(c);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},4166:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>c,n2:()=>i});var r=n(59496),a=n(48251);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function c(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,c=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:c})}),[l,t,c]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},59386:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(59496);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},49361:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(59496),a=n(80689);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const c=!1;function s(){const[e,t]=(0,r.useState)((()=>c?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=c?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},77685:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},37795:(e,t,n)=>{"use strict";n.d(t,{Rb:()=>l,_X:()=>c});var r=n(59496),a=n(83442),o=n(74241),i=n(48251);function l(e){!function(e){const t=(0,a.k6)(),n=(0,i.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function c(e){return function(e){const t=(0,a.k6)();return(0,o.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},77619:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function a(e){return Array.from(new Set(e))}n.d(t,{j:()=>a,l:()=>r})},60542:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>u,VC:()=>p});var r=n(59496),a=n(45924),o=n(23050),i=n(95609);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var c=n(58102),s=n(79375);function u(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const u=function(e){const{siteConfig:t}=(0,s.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,c.C)(),f=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,u),t&&r.createElement("meta",{property:"og:title",content:u}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),l)}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function p(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(f,{className:(0,a.Z)(o,i)},t)}},48251:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>s,Ql:()=>c,i6:()=>l,zX:()=>o});var r=n(59496);const a=n(80689).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function c(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function s(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},28238:(e,t,n)=>{"use strict";n.d(t,{OC:()=>l,RF:()=>u,o5:()=>d});var r=n(59496),a=n(80689),o=(n(72400),n(48251));const i=r.createContext(void 0);function l(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(i.Provider,{value:n},t)}function c(){const e=(0,r.useContext)(i);if(null==e)throw new o.i6("ScrollControllerProvider");return e}const s=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function u(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=c(),a=(0,r.useRef)(s()),i=(0,o.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=s();i(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[i,n,...t])}function d(){const e=c(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),a=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,r.useLayoutEffect)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:a}}},74242:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>d,WA:()=>u});var r=n(59496),a=n(74241);const o="localStorage";function i(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function l(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,c||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),c=!0),null}var t}let c=!1;const s={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function u(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=l(t?.persistence);return null===n?s:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),i({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),i({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function d(e,t){const n=(0,r.useRef)((()=>null===e?s:u(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,a.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},5572:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(79375),a=n(83442);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),l=o===n?e:e.replace(`/${o}/`,"/"),c=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${c}`}}}},10018:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(79375);function a(){return(0,r.Z)().siteConfig.themeConfig}},31232:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},65:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="post-content";var a=n(31232);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}})},45924:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>v,q_:()=>C,ob:()=>p,PP:()=>A,Ep:()=>f});var r=n(64778);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!s)for(;d--;d)i.unshift("..");!s||""===i[0]||i[0]&&a(i[0])||i.unshift("");var b=i.join("/");return n&&"/"!==b.substr(-1)&&(b+="/"),b};var l=n(38624);function c(e){return"/"===e.charAt(0)?e:"/"+e}function s(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,g(),v.location);u.confirmTransitionTo(a,r,n,(function(e){e&&(v.entries[v.index]=a,d({action:r,location:a}))}))},go:w,goBack:function(){w(-1)},goForward:function(){w(1)},canGo:function(e){var t=v.index+e;return t>=0&&t{"use strict";var r=n(56237),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function c(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var s=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,b=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(b){var a=p(n);a&&a!==b&&e(t,a,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var l=c(t),g=c(n),m=0;m{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[n,r,a,o,i,l],u=0;(c=new Error(t.replace(/%s/g,(function(){return s[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},70901:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},78708:(e,t,n)=>{"use strict";n.r(t)},14211:(e,t,n)=>{"use strict";n.r(t)},29981:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),s=o.querySelector(r.barSelector),u=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(s,i(e,u,d)),1===e?(c(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){c(o,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),s=document.querySelector(r.parent);return c(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),s!=document.body&&u(s,"nprogress-custom-parent"),s.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function s(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=f(e),r=n+t;s(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);s(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},22767:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),c=1;c{var r=n(70901);e.exports=p,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",u=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var b=e[i],g=n[2],m=n[3],h=n[4],y=n[5],w=n[6],v=n[7];l&&(r.push(l),l="");var k=null!=g&&null!=b&&b!==g,_="+"===w||"*"===w,x="?"===w||"*"===w,E=n[2]||u,S=h||y;r.push({name:m||o++,prefix:g||"",delimiter:E,optional:x,repeat:_,partial:k,asterisk:!!v,pattern:S?s(S):v?".*":"[^"+c(E)+"]+?"})}}return i{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);x+=_.value.length,_=_.next){var E=_.value;if(t.length>e.length)return;if(!(E instanceof a)){var S,C=1;if(y){if(!(S=o(k,x,e,h))||S.index>=e.length)break;var T=S.index,A=S.index+S[0].length,L=x;for(L+=_.value.length;T>=L;)L+=(_=_.next).value.length;if(x=L-=_.value.length,_.value instanceof a)continue;for(var N=_;N!==t.tail&&(Ld.reach&&(d.reach=I);var M=_.prev;if(O&&(M=c(t,M,O),x+=O.length),s(t,M,C),_=c(t,M,new a(f,m?r.tokenize(P,m):P,w,P)),R&&c(t,_,R),C>1){var j={cause:f+","+b,reach:I};i(e,t,n,_.prev,x,j),d&&j.reach>d.reach&&(d.reach=j.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function c(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function s(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},c=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var c=n;c=0&&p(s,"variable-input")}}}}function u(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function c(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function s(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,c(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function u(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,u={},d=c(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return u[n]=a,n})).join(""),n,r),f=Object.keys(u);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var c=o.substring(0,l),d=s(u[a]),p=o.substring(l+a.length),b=[];if(c&&b.push(c),b.push(d),p){var g=[p];e(g),b.push.apply(b,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(b)),n+=b.length-1):r.content=b}}else{var m=r.content;Array.isArray(m)?e(m):e([m])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var c=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(c=i(t[r-1])+c,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",c,null,c)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var c=0;c=o.length);c++){var s=l[c];if("string"==typeof s||s.content&&"string"==typeof s.content){var u=o[a],d=n.tokenStack[u],f="string"==typeof s?s:s.content,p=t(r,u),b=f.indexOf(p);if(b>-1){++a;var g=f.substring(0,b),m=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),h=f.substring(b+p.length),y=[];g&&y.push.apply(y,i([g])),y.push(m),h&&y.push.apply(y,i([h])),"string"==typeof s?l.splice.apply(l,[c,1].concat(y)):s.content=y}}else s.content&&i(s.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},50955:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},74049:(e,t,n)=>{"use strict";var r=n(36257);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},40507:(e,t,n)=>{e.exports=n(74049)()},36257:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},17439:(e,t,n)=>{"use strict";var r=n(59496),a=n(22767),o=n(58051);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n