🐹 日常战报: 写 Go 代码 → 用
pprof
灭火 → 泡咖啡 → 循环🐍 日常战报: 写 Python 时:▇▇▇▇▇ 自动化脚本加载中… 🐞 捕获 BUG:TypeError ×3
💻 日常战报: 写 Shell 时:[[ $? -eq 0 ]] || 重启玄学调试模式
🌿 非技术时刻:骑行川藏线记录 | 胶片摄影暗房教程
💡 终极真理:echo “rm -rf /” > deploy.sh
pprof
灭火 → 泡咖啡 → 循环Vue3 的核心原理,ChatGPT 老师给出来的内容,记录下来对于理解 vue 很有帮助 我们来动手实现一个最小可运行的响应式系统,它能模拟 Vue 3 中 reactive、ref、effect、track 和 trigger 的核心逻辑。 🧩 目标功能 实现 reactive(obj) 和 ref(value)。 实现 effect(fn):收集依赖并在数据变更时重新运行。 实现 track:读取属性时记录依赖。 实现 trigger:写入属性时触发依赖。 ✅ 最简实现代码 // 用于记录当前正在执行的副作用函数 let activeEffect = null; // targetMap 用于存储依赖映射:target -> key -> effects const targetMap = new WeakMap(); // 收集依赖:在 get 时调用 function track(target, key) { if (!activeEffect) return; let depsMap = targetMap.get(target); if (!depsMap) { depsMap = new Map(); targetMap.set(target, depsMap); } let deps = depsMap.get(key); if (!deps) { deps = new Set(); depsMap.set(key, deps); } deps.add(activeEffect); } // 触发依赖:在 set 时调用 function trigger(target, key) { const depsMap = targetMap.get(target); if (!depsMap) return; const deps = depsMap.get(key); if (deps) { for (const effect of deps) { effect(); } } } // 注册副作用函数 function effect(fn) { activeEffect = fn; fn(); // 立即执行一次,触发 getter 从而 track activeEffect = null; } // 实现 reactive function reactive(obj) { return new Proxy(obj, { get(target, key, receiver) { track(target, key); return Reflect.get(target, key, receiver); }, set(target, key, value, receiver) { const result = Reflect.set(target, key, value, receiver); trigger(target, key); return result; }, }); } // 实现 ref function ref(value) { const obj = { get value() { track(obj, "value"); return value; }, set value(newVal) { value = newVal; trigger(obj, "value"); }, }; return obj; } 🚀 使用示例 const state = reactive({ count: 0 }); effect(() => { console.log("count changed to:", state.count); }); state.count++; // 会触发 effect 再次执行 const age = ref(18); effect(() => { console.log("age is:", age.value); }); age.value = 20; // 会触发 effect 再次执行 📌 总结 功能 简述 effect(fn) 注册副作用函数(依赖收集器) track() 读取数据时记录当前副作用函数依赖 trigger() 写入数据时触发依赖函数重新运行 reactive() 用 Proxy 包装对象以支持响应式 ref() 用 getter/setter 包装基本值 这个模型就是 Vue 3 响应性系统的基本结构,当然 Vue 3 实现里更复杂,支持嵌套对象、effect 的调度与清理、懒执行等等,但核心思想就是这里的 track -> trigger。 ...
下面是对 Tailwind CSS 类名前缀(开头简写)的一个系统总结,涵盖了常用的样式类别以及它们控制的样式类型,便于查阅与理解: 🧩 Tailwind CSS 类名前缀速查表 类名前缀 作用描述 影响的 CSS 属性 w- 宽度 width h- 高度 height min-w- 最小宽度 min-width min-h- 最小高度 min-height max-w- 最大宽度 max-width max-h- 最大高度 max-height p- 内边距 (padding) padding(所有) px- 水平内边距 padding-left、padding-right py- 垂直内边距 padding-top、padding-bottom pt- 上内边距 padding-top pr- 右内边距 padding-right pb- 下内边距 padding-bottom pl- 左内边距 padding-left m- 外边距 (margin) margin(所有) mx- 水平外边距 margin-left、margin-right my- 垂直外边距 margin-top、margin-bottom mt- 上外边距 margin-top mr- 右外边距 margin-right mb- 下外边距 margin-bottom ml- 左外边距 margin-left text- 文字样式 color, align, size, weight, transform font- 字体粗细、字体族 font-weight, font-family leading- 行高 line-height tracking- 字间距 letter-spacing bg- 背景样式 background-color, background-image, background-size 等 border- 边框样式 border-width, border-color 等 rounded- 圆角 border-radius shadow- 阴影 box-shadow flex、grid、inline- 布局模式 display items- 垂直方向对齐 align-items justify- 水平方向对齐 justify-content gap- 容器子元素间距 gap space-x- 横向子元素间距 margin-left space-y- 纵向子元素间距 margin-top z- 层级 z-index opacity- 透明度 opacity overflow- 溢出控制 overflow, overflow-x, overflow-y cursor- 鼠标样式 cursor transition、duration- 动画过渡 transition, transition-duration 等 ease- 缓动函数 transition-timing-function scale-、rotate-、translate- 变换 transform absolute、relative、fixed、sticky 定位模式 position top-、left-、right-、bottom- 定位偏移 top, left 等 hidden、block、inline-block 显示类型 display 📌 特殊响应式与状态前缀(组合使用) 前缀 说明 示例 sm: / md: / lg: / xl: / 2xl: 响应式断点 md:w-1/2(中等屏幕宽度为 50%) hover: 悬停状态 hover:bg-blue-500 focus: 聚焦状态 focus:ring disabled: 禁用状态 disabled:opacity-50 dark: 深色模式 dark:bg-gray-800 group-hover: 父元素悬停触发 group-hover:text-red-500
TypeScript 的三种特殊类型 any 表示任意类型,对 TypeScript 的类型检查器完全关闭检查。编译器不会对它进行任何类型检查,也不会自动补全类型信息。 let value: any; value = 42; value = "hello"; value = [1, 2, 3]; console.log(value.toFixed()); // 编译器不会报错,但运行时可能出错 兼容所有类型(可以赋值给任何类型,也可以接受任何类型赋值) 不安全,等于放弃了 TypeScript 的类型系统 unknown 也是可以接受任何类型的变量,但不能直接使用,除非先做类型检查或断言。安全的任意类型 let value: any; value = 42; value = "hello"; value = [1, 2, 3]; // console.log(value.toFixed()); // 报错 Object is of the 'unknown' if ( typeof value == "number" ) { console.log(value.toFixed()); // 先检查后使用 } 可以接受任何类型赋值(类似 any) 不能直接使用(需要类型缩小或断言) 更安全,更适合函数入参或外部数据 never (不可能的类型) 表示永远不会发生的值。 通用用于明确函数不会返回(抛错、死循环);类型保护不完整时,确保类型覆盖完整性。 // 抛出的异常函数 function throwError(msg: string): never { throw new Error(msg); } // 死循环函数 function loopForever(); never { while (true) {} } // 不可达的分支 function exhaustiveCheck(value: "a" | "b"): number { if ( value === "a") return 1; if ( value === "b") return 2; // value 的类型为 never, 如果执行到这里说明之前的类型判断不完整 const check: never = vlaue; return check; } 总结对比表 特性 any unknown never 可接受任何值 ✅ 是 ✅ 是 ❌ 否 可赋值给其他类型 ✅ 是 ❌ 否(需断言/缩小) ✅ 是 可被其他类型赋值 ✅ 是 ✅ 是 ❌ 否 编译器检查 ❌ 无类型检查 ✅ 有(使用前需检查) ✅ 编译器保证类型不可达 安全性 ❌ 不安全 ✅ 安全 ✅ 类型系统完整性保障 使用场景 快速开发、兼容旧代码 外部数据、泛型参数 永不返回函数、穷尽检查等
JavaScript 的不同文件后缀名的含义 后缀名 含义/用途 常见位置或用途说明 .js JavaScript 文件,可能是 CommonJS 或 ESModule 项目源代码或编译产物 .mjs JavaScript ES Module(明确标注为模块) Node.js 中使用 ESModule 时常见 .cjs JavaScript CommonJS 模块(明确标注) 当项目默认使用 ESModule,但某些文件需保留 CJS 语法 .ts TypeScript 源代码文件 支持类型系统和新语法特性,需编译为 .js 才能运行 .cts TypeScript 的 CommonJS 模块 .ts 的 CJS 对应,ESM 项目中显式指定 CJS 模块 .mts TypeScript 的 ES Module 模块 .ts 的 ESM 对应 .d.ts TypeScript 类型声明文件 只包含类型信息,无实现,用于类型补全或公共 API 描述 .jsx JavaScript + JSX(React) React 组件的源代码,支持 JSX 语法 .tsx TypeScript + JSX(React) 结合 TypeScript 类型检查与 React JSX .json JSON 文件 配置、数据、模块导入(Node.js / Vite / webpack 支持 import) .node 原生 Node.js 模块(二进制) C/C++ 编译生成的原生插件,Node.js 用于加载本地扩展 .wasm WebAssembly 模块 浏览器或 Node.js 中导入的高性能二进制模块 .map SourceMap 文件 用于调试编译后的代码(.js.map / .ts.map) .lock 锁定文件依赖版本(package-lock.json, pnpm-lock.yaml) 不是 JS 文件,但项目重要组成部分 ✅ 总结重点分类 代码类型:.js, .ts, .mjs, .cjs, .jsx, .tsx, .vue 类型声明:.d.ts 编译产物:.js, .map 配置文件:.js, .ts, .json, .yaml, .env 模块说明:.mjs, .cjs, .mts, .cts 框架扩展:.vue, .svelte, .astro, .ejs, .hbs
Lua 的基本内容 值和类型 8 中基本类型 类型 说明 nil nil类型只有一个值,通常表示不存在有用的值 boolean nil 和 false 为假,其余均为真值 number 整数和浮点数 string 不可变的字节序列 function userdata 用户数据值在 Lua 中无法创建或修改,只能通过 C API 进行创建或修改 thread 线程类型 table 关联数组 表、函数、线程和(完整的)用户数据值都是对象 :变量实际上并不包含这些值,而只是对它们的引用 。赋值、参数传递和函数返回始终操作的是对这些值的引用;这些操作不涉及任何形式的复制。 环境和全局变量 Lua 把你没定义过的变量,都当作是 _ENV 这个表里的成员。_ENV 就是一个普通的 Lua 表(table),它用来当“作用域环境”。默认这个 _ENV 就是 _G 也就是平时说的全局变量表。 -- _ENV 可以被改掉 local _ENV = {print = function() print("你被劫持了") end} -- 如果要加载一个 lua 脚本,不想让它访问全局变量,可以使用 load / loadfile local f = load("print(x)", nil, "t", { print = print, x = 123 }) f() -- 输出 123 -- 这个 { print = print, x = 123 } 就是传给这个脚本的 _ENV,它用来隔离变量作用域 错误处理 功能 用法说明 抛出错误 error(“错误了”) 捕获错误 pcall(function) 带堆栈处理器 xpcall(func, handler) 错误值 可以是字符串、table、数字……任意值 警告机制 只提示不影响程序运行,从 Lua 5.4 开始支持 -- 抛出错误 --error("发生了致命错误") -- pcall 捕获错误 local ok, result = pcall(function() error("boom") end) print(ok) print(result) -- 自定义处理错误 xpcall local function my_func() error("出问题了") end local function my_handler(err) return "捕获错误: " .. err .. "\n" .. debug.traceback() end local ok, msg = xpcall(my_func, my_handler) print(msg) 自定义错误处理 local function log_error(msg) io.stderr:write("[ERROR] " .. os.date() .. "\n" .. msg .. "\n") end function safe_call(fn, ...) local args = { ... } local function error_handler(err) local msg = tostring(err) local trace = debug.traceback("", 2) local full_msg = "【Lua错误】" .. msg .. "\n" .. trace log_error(full_msg) return full_msg end local function wrapped() return fn(table.unpack(args)) end local ok, result = xpcall(wrapped, error_handler) return ok, result end local function demo(a, b) return a / b end local ok, res = safe_call(demo, 10, 0) if not ok then print("执行失败: ") print(res) else print("执行成功,结果是: " .. res) end 元表和元方法 Lua 的 metatables 和 metamethods 允许自定义 lua 对象的行为。 ...
在 shell 脚本判断逻辑中的一些操作符 一、字符串测试 选项 含义 示例 说明 -z 字符串为空 [ -z "$str" ] 变量未定义或值为空时为真 -n 字符串非空 [ -n "$str" ] 变量已定义且值不为空时为真 重要提示:变量必须用双引号包裹,避免未定义变量导致语法错误: # 错误写法(未定义变量会报错) [ -n $var ] # 正确写法 [ -n "$var" ] 二、文件测试 文件存在性测试 选项 含义 示例 -e 文件/目录存在 [ -e "/path" ] -a 同 -e(已废弃) 不推荐使用 文件类型测试 选项 含义 示例 -f 常规文件 [ -f file.txt ] -d 目录 [ -d "/dir" ] -L 符号链接 [ -L link ] -h 同 -L [ -h link ] -b 块设备 [ -b /dev/sda ] -c 字符设备 [ -c /dev/tty ] -p 命名管道 [ -p pipe ] -S 套接字 [ -S socket ] 权限测试 选项 含义 示例 -r 可读 [ -r file ] -w 可写 [ -w file ] -x 可执行 [ -x script.sh ] -g 设置了 setgid [ -g file ] -u 设置了 setuid [ -u file ] -k 设置了 sticky bit [ -k /tmp ] 文件属性测试 选项 含义 示例 -s 文件非空 [ -s data.log ] -N 修改后未读取 [ -N file ] -O 当前用户拥有 [ -O file ] -G 当前用户组拥有 [ -G file ] 文件比较测试 选项 含义 示例 -nt 文件1比文件2新 [ file1 -nt file2 ] -ot 文件1比文件2旧 [ file1 -ot file2 ] -ef 相同设备/Inode [ file1 -ef file2 ] 三、数值比较 选项 含义 示例 等价算术符 -eq 等于 [ $a -eq 5 ] == -ne 不等于 [ $a -ne 5 ] != -gt 大于 [ $a -gt 5 ] > -ge 大于等于 [ $a -ge 5 ] >= -lt 小于 [ $a -lt 5 ] < -le 小于等于 [ $a -le 5 ] <= 四、组合逻辑 选项 含义 示例 ! 逻辑非 [ ! -f file ] -a 逻辑与 [ -f file -a -r file ] -o 逻辑或 [ -d dir -o -L dir ] 现代写法(推荐): ...
图片引用 https://mp.weixin.qq.com/s/GTAGMy2t0FIIUhq6CpFgWw 🧩 一、iptables 五表详解 优先级顺序 raw > mangle > nat > filter > security 表名 用途 作用时机 优先级 常用规则 raw 关闭连接跟踪(conntrack) 最早阶段 ⭐最高 NOTRACK mangle 修改数据包(TTL、TOS、MARK等) 早期、中期、晚期都可插入 高 MARK, TTL, TOS nat 实现源地址或目标地址转换(NAT) PREROUTING / POSTROUTING / OUTPUT 中 SNAT, DNAT, MASQUERADE filter 数据包过滤(放行/丢弃) 处理末期 ⭐最常用 ACCEPT, DROP security 与 SELinux、AppArmor 结合的强制访问控制 最后阶段 低 配合 SELinux 使用 🔗 二、五链详解(对应五个 hook 点) 链名 描述 属于哪些表 PREROUTING 入站包一进内核就处理(在路由前) raw, mangle, nat INPUT 进入本机的包 mangle, filter, security FORWARD 转发到别处的包 mangle, filter, security OUTPUT 本机发出的包 raw, mangle, nat, filter, security POSTROUTING 所有出站包(包括转发)在离开前 mangle, nat, security 🚚 三、收发包流程图说明(图下方) 你贴的图,和 Netfilter 的真实流程图是基本一致的。下面我对照图帮你拆解下: ...
📌 问题 在一些 Shell 脚本中,常常看到以下结构: #!/usr/bin/env bash { # this ensures the entire script is downloaded # # 脚本内容 some_function() { echo "Hello" } some_function } # this ensures the entire script is downloaded # 为什么要用 { ... } 把整个脚本包裹起来?这样做有什么好处? ✅ 答案 这是一个 Shell 脚本技巧,主要用于: 确保整个脚本在下载完成并被完全解析之后再执行 🧠 原因解释 在执行远程脚本时,例如: curl -s https://example.com/script.sh | bash 脚本是以流式方式传给 bash 的,会出现: 边下载边执行 如果下载中断,脚本会只执行了一部分 函数定义、变量赋值可能不完整,甚至执行危险命令 🛡 加上 { ... } 的作用 使用大括号包裹: { # 所有脚本内容 } 等于告诉 bash: ...
📡 MCP 协议简明说明文档 什么是 MCP 协议? MCP(Message Calling Protocol)是一种用于“大模型调用工具”的通信协议标准。 它的目标是解决这个问题: 🧠 “模型说要调用工具 A 干点事,那我们怎么告诉它工具叫啥、怎么传参、怎么返回结果呢?” MCP 协议规定了什么?(共 4 点) 1. 工具定义格式 使用 JSON Schema 定义工具的名称、描述和参数: { "name": "get_weather", "description": "获取城市天气", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "城市名" } }, "required": ["city"] } } 2. 调用请求格式 遵循 JSON-RPC 格式: { "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "get_weather", "arguments": { "city": "北京" } } } 3. 返回结果格式 { "jsonrpc": "2.0", "id": 1, "result": { "content": [ { "type": "text", "text": "北京今天晴,最高25度。" } ] } } 支持返回多种类型的数据(如文本、图片、文件等)。 4. 多轮交互 & 中间件机制 支持多轮对话中的函数调用 MCP Server 可实现日志、权限、缓存、调度等中间件机制 MCP 协议需要客户端和服务端做什么? 🖥️ 服务端(MCP Server)职责 功能 说明 接收 JSON-RPC 请求 支持 HTTP / WebSocket / stdio 等方式 查找并执行工具逻辑 按名称 name 执行对应函数或脚本 返回标准格式结果 输出 result.content,统一格式 返回示例: ...
展示下启动完成后的效果 依赖 docker 环境 .env 文件 GITLAB_HOST_IP=192.168.1.8 GITLAB_PORT=8929 GITLAB_ROOT=/Users/mako/gitlab GITLAB_WEB_URL=192.168.1.8:8929 GITLAB_SHELL_SSH_PORT=2224 使用 docker compose 进行安装 # yaml-language-server: $schema=https://cdn.jsdelivr.net/gh/compose-spec/compose-spec@master/schema/compose-spec.json services: web: image: gitlab/gitlab-ce:latest restart: always container_name: gitlab hostname: gitlab environment: GITLAB_OMNIBUS_CONFIG: | external_url 'http://${GITLAB_HOST_IP}:${GITLAB_PORT}' gitlab_rails['gitlab_shell_ssh_port'] = ${GITLAB_SHELL_SSH_PORT} ports: - ${GITLAB_PORT}:${GITLAB_PORT} - ${GITLAB_SHELL_SSH_PORT}:22 volumes: - ${GITLAB_ROOT}/config:/etc/gitlab - ${GITLAB_ROOT}/logs:/var/log/gitlab - ${GITLAB_ROOT}/data:/var/opt/gitlab shm_size: 256m runner: image: gitlab/gitlab-runner:latest container_name: gitlab-runner restart: always volumes: - ${GITLAB_ROOT}/runner/config:/etc/gitlab-runner - ${GITLAB_ROOT}/runner/docker.sock:/var/run/docker.sock 控制脚本 control.sh 进行自动更新 .env及启停 在不同网络下本机的 IP 地址变更,只需要 ./control.sh restart 即可,脚本中会自动重新配置 .env 内容 ...