XeLaTeX: Unicode 友好的 LaTeX 引擎

XeLaTeX 是 TeX Live 发行版中的一种 LaTeX 编译引擎,与 pdfLaTeX、LuaLaTeX 并列。处理中文、英文混排或需要调用系统 OpenType 字体时,XeLaTeX 是最常用的选择之一。若还不熟悉 LaTeX 本身,建议先读该文建立概念,再回来看引擎差异。 LaTeX 与引擎是什么关系 可以先这样理解: 概念 角色 LaTeX 排版语言与宏集;你写 .tex 源文件 引擎(pdfLaTeX、XeLaTeX、LuaLaTeX) 读取 .tex,输出 PDF TeX Live 引擎 + 海量宏包 + 字体的发行版 document.tex → xelatex → document.pdf Pandoc 生成 PDF 时,也是先写出 .tex,再调用你指定的 --pdf-engine(如 xelatex)完成最后一步。 为什么需要 XeLaTeX pdfLaTeX 的局限 传统的 pdfLaTeX 历史悠久,但: 字体接入方式偏旧(多为 T1 编码、内置字体) 中文等非拉丁文字支持麻烦,常要额外宏包和配置 直接调用系统里的 Noto、Inter 等 OpenType 字体不直观 XeLaTeX 的优势 XeLaTeX 原生支持 Unicode,并通过 fontspec 宏包直接加载系统字体: \usepackage{fontspec} \setmainfont{Inter} \setCJKmainfont{Noto Sans CJK SC} % via xeCJK 因此适合: ...

Created 22226-06-22 · Updated 22226-06-22 · 2 min · 283 words · -

Pandoc: 通用文档格式转换工具

Pandoc 是一个命令行文档转换器,号称能把一种标记格式转成几十种另一种格式。写 Markdown 的人最常拿它做两件事:导出 Word / HTML,以及配合 LaTeX 引擎生成 PDF。 它解决什么问题 很多内容用 Markdown(或 reStructuredText、Org-mode 等)写更舒服,但投递、打印、协作方往往要 PDF 或 DOCX。Pandoc 在不改动写作习惯的前提下,充当「格式编译器」: Markdown / HTML / docx / ... │ ▼ Pandoc │ ▼ PDF / HTML / docx / LaTeX / ... 同一份源文件,可以按需输出多种交付物。 支持哪些格式 Pandoc 3.x 支持大量输入、输出格式。日常最常用的一组: 方向 格式 读入 Markdown、HTML、docx、LaTeX、EPUB、JSON 等 写出 HTML、PDF、docx、LaTeX、EPUB、纯文本等 查看本机完整列表: pandoc --list-input-formats pandoc --list-output-formats 基本用法 最简单的转换——Markdown 转 HTML: pandoc input.md -o output.html Markdown 转 PDF(需要 LaTeX 引擎,见 XeLaTeX 介绍): ...

Created 22226-06-22 · Updated 22226-06-22 · 2 min · 251 words · -

Gradle, 目录

Gradle, 目录 Gradle 是以 Groovy / Kotlin DSL 为基础的 JVM 自动化构建工具,面向 Java 等语言项目。常见构建脚本为 build.gradle(Groovy)或 build.gradle.kts(Kotlin DSL)。 Gradle 与 Gradle Wrapper(gradlew) 很多人第一次 clone 项目时会疑惑:明明没装 Gradle,为什么 ./gradlew test 也能跑? 答案就在 Wrapper。 是什么关系 概念 说明 Gradle 安装在系统上的构建工具,命令是 gradle(例如 brew install gradle、SDKMAN) Gradle Wrapper 项目自带的一层「启动器」,命令是 ./gradlew(Windows 用 gradlew.bat) 关系 gradlew 不负责实现编译逻辑;它只负责下载并启动项目指定版本的 Gradle,再把 test、build 等任务交给真正的 Gradle 执行 一句话:Gradle 是引擎,gradlew 是带版本号的点火钥匙。 日常开发、CI 里应优先用 ./gradlew,而不是裸 gradle。这样所有人、每台机器用的是 gradle-wrapper.properties 里锁定的同一版本,避免「我这能编、你那报错」。 Wrapper 相关文件 这些文件应提交到 Git(官方建议): 路径 作用 gradlew Unix/macOS 启动脚本 gradlew.bat Windows 启动脚本 gradle/wrapper/gradle-wrapper.jar 小 bootstrap 程序,负责下载真正的 Gradle 发行包 gradle/wrapper/gradle-wrapper.properties 锁定 Gradle 版本,核心是 distributionUrl distributionUrl 示例: ...

Created 20206-12-20 · Updated 20206-06-20 · 3 min · 549 words · -

缓存一致性问题

概述 应用读多写少时,常在 PostgreSQL 与 Redis 之间加一层缓存:热数据放 Redis,持久化仍由 PostgreSQL 负责。难点不在「能不能缓存」,而在写路径与读路径如何协调——数据库已更新,缓存仍是旧值;或缓存已失效,并发读把脏数据又写回缓存。 下文以 Redis 作缓存、PostgreSQL 作权威数据源,梳理几种主流缓存模式、各自的一致性特征与适用场景。示例以伪代码和常见实践为主,便于对照落地。 模式总览 模式 谁加载缓存 谁写缓存 一致性 复杂度 典型场景 Cache-Aside 应用 应用 最终一致,需自行处理竞态 低 通用业务,最常用 Read-Through 缓存层 缓存层 同 Cache-Aside 中 统一缓存 SDK Write-Through 应用 缓存层同步写 DB 较强一致 中 读多、可接受写延迟 Write-Back 应用 缓存层异步刷盘 弱一致,有丢数据风险 高 写密集、可容忍短暂不一致 Binlog 同步 中间件 CDC 消费 binlog 更新缓存 最终一致,解耦业务 高 多服务共享缓存、不想侵入业务 分布式事务 应用 + 协调者 2PC / TCC / Saga 强一致或业务级一致 很高 资金、库存等强一致域 graph LR App[应用] Redis[(Redis)] PG[(PostgreSQL)] App -->|Cache-Aside / Read-Through / Write-Through| Redis App -->|直接写或经缓存层| PG Redis -->|miss 时回源| PG PG -->|Binlog / WAL| CDC[CDC 消费者] CDC -->|更新/失效| Redis Cache-Aside(旁路缓存) 也叫 Lazy Loading。应用自己管缓存:读先查 Redis,miss 再查 PostgreSQL 并回填;写先更新 PostgreSQL,再删除(推荐)或更新 Redis。 ...

Created 19196-06-19 · Updated 19196-06-19 · 6 min · 1080 words · -

React 入门

React 是由 Meta(前 Facebook)开发并开源的 JavaScript UI 库,专注于构建用户界面。它于 2013 年开源,目前已成为最流行的前端技术之一。 react 核心概念 组件(Component) React 的核心单元是组件(Component)。组件是一个返回 UI 描述的函数(或类),可以像拼积木一样组合成复杂的界面。 function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } 组件分为两类: 函数组件:现代 React 的主流写法,配合 Hooks 使用 类组件:早期写法,新项目不推荐使用 JSX JSX 是 JavaScript 的语法扩展,允许在 JS 文件中写类似 HTML 的结构。它不是 HTML,会被编译工具(如 Babel、SWC)编译为 React.createElement() 调用。 const element = <div className="container">Hello</div>; // 编译后等价于: const element = React.createElement("div", { className: "container" }, "Hello"); 详见:JSX 介绍 Props Props(属性)是组件的输入,由父组件传入,在子组件内部是只读的。 function Button({ label, onClick }) { return <button onClick={onClick}>{label}</button>; } // 使用 <Button label="提交" onClick={() => console.log("clicked")} /> State State(状态)是组件内部管理的可变数据。状态变化会触发组件重新渲染。 import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>当前计数:{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> </div> ); } 虚拟 DOM React 在内存中维护一棵虚拟 DOM 树。每次状态更新时,React 通过 Diffing 算法对比新旧虚拟 DOM,计算出最小变更集,再批量更新真实 DOM,从而提升性能。 ...

Created 17176-05-17 · Updated 16166-06-16 · 2 min · 353 words · -

Giscus:基于 GitHub Discussions 的评论系统

Giscus 是一个基于 GitHub Discussions 的评论系统,评论数据完全存储在 GitHub,无需额外的数据库或第三方平台。适合托管在 GitHub Pages、Cloudflare Pages 等静态站点。 工作原理 Giscus 把每篇页面的评论映射到 GitHub Discussions 中的一个 Discussion,通过在页面嵌入 <script> 标签加载评论组件。 页面与 Discussion 的映射方式: 映射方式 说明 pathname(推荐) 按页面 URL 路径匹配,最通用 title 按文章标题匹配 og:title 按 Open Graph 标题匹配 前置条件 GitHub 仓库需开启 Discussions 功能:仓库 Settings → Features → Discussions ✓ 安装 Giscus GitHub App:github.com/apps/giscus → Install → 选择目标仓库 获取配置参数 访问 giscus.app,填写仓库名和配置选项,页面底部会生成完整的 <script> 标签,从中获取: data-repo-id(格式 R_kgDO...):仓库 Node ID data-category-id(格式 DIC_kwDO...):Discussion 分类 ID Discussion 分类推荐选 Announcements:只有维护者能在 GitHub 网页直接新建 Discussion,普通用户只能通过 Giscus 组件留言,防止垃圾内容。 ...

Created 16166-06-16 · Updated 16166-06-16 · 1 min · 181 words · -

Spring Boot 关系型数据库持久层概览

概述 在 Spring Boot 里访问 MySQL、PostgreSQL、SQLite 等关系型数据库,常见有几条路线。它们最终都经过 JDBC 连到数据库,差别在于中间抽象层有多高、SQL 由谁写。 应用代码 │ ├── Spring Data JDBC ← Repository 风格,底层仍是 JDBC ├── Spring Data JPA ← 对象为主,框架生成 SQL │ └── JPA(标准)→ Hibernate(实现) ├── MyBatis (+ Plus) ← SQL 手写 + 映射 └── JdbcTemplate / JDBI / jOOQ ← SQL 路线(字符串或类型安全 DSL) 下面分别介绍 Spring Data JDBC、Spring Data JPA、MyBatis、JdbcTemplate、JDBI、jOOQ,并简要说明 JPA 本身是什么。 Spring Data JDBC Spring Data JDBC 是 Spring 官方提供的 轻量持久化方案,依赖 spring-boot-starter-data-jdbc。它提供与 Spring Data JPA 类似的 CrudRepository 接口风格,但 不是 ORM,底层仍通过 JdbcTemplate 访问数据库。 ...

Created 22226-05-22 · Updated 20206-05-20 · 5 min · 974 words · -

React 状态管理:Zustand、Jotai 与 Redux 对比

什么是状态管理,它解决什么问题 React 的数据流是单向的:数据通过 Props 从父组件流向子组件。这在小型应用中很好用,但随着应用规模扩大,会遇到两个典型痛点: Prop Drilling(属性透传) 同一份数据需要从顶层组件一层一层往下传,中间层组件本身并不使用这个数据,却不得不接收并转发它。组件层级越深,代码越难维护。 App(持有 user 状态) └─ Layout └─ Sidebar └─ UserAvatar(需要 user)← 要传三层 props 跨组件状态同步困难 当两个没有父子关系的组件需要访问同一份数据时,只能把状态提升到它们共同的祖先组件,然后再层层传下去。状态越分散,同步越容易出 bug。 状态管理库的解法 把共享状态提取到组件树之外的独立 Store,任何组件都可以直接订阅和修改,不需要层层传递 Props。 Store(独立于组件树) ↗ ↗ ComponentA ComponentB React 主流状态管理方案对比 库 定位 包大小 学习曲线 Zustand 轻量、直觉式 API ~1 KB 低 Jotai 原子化状态,细粒度订阅 ~3 KB 低 Redux Toolkit 功能完整,适合大型项目 ~20 KB 高 Zustand Zustand 是目前最流行的轻量状态管理库,API 极简,和 Vue 的 Pinia 非常相似。 创建 Store: ...

Created 18186-05-18 · Updated 18186-05-18 · 4 min · 685 words · -

React 函数组件与类组件

React 有两种组件写法:函数组件(Function Component) 和 类组件(Class Component)。现代 React 项目几乎全面使用函数组件,类组件属于历史遗留写法。 函数组件 函数组件就是一个普通的 JavaScript 函数,接收 Props,返回 JSX。 function Greeting({ name }) { return <h1>Hello, {name}!</h1>; } // 也可以用箭头函数 const Greeting = ({ name }) => <h1>Hello, {name}!</h1>; React 16.8 引入 Hooks 之后,函数组件可以使用状态和生命周期,成为主流写法。 类组件 类组件通过继承 React.Component 实现,必须定义 render() 方法返回 JSX。 import { Component } from "react"; class Greeting extends Component { render() { return <h1>Hello, {this.props.name}!</h1>; } } 有状态的类组件: class Counter extends Component { constructor(props) { super(props); this.state = { count: 0 }; } render() { return ( <div> <p>计数:{this.state.count}</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> +1 </button> </div> ); } } 同一功能的对比 以一个带状态的计数器为例,对比两种写法的差异: 类组件写法: class Counter extends Component { constructor(props) { super(props); this.state = { count: 0 }; this.handleClick = this.handleClick.bind(this); // 必须手动绑定 this } componentDidMount() { document.title = `计数:${this.state.count}`; } componentDidUpdate() { document.title = `计数:${this.state.count}`; } componentWillUnmount() { document.title = "App"; } handleClick() { this.setState({ count: this.state.count + 1 }); } render() { return ( <button onClick={this.handleClick}> 计数:{this.state.count} </button> ); } } 函数组件写法: ...

Created 17176-05-17 · Updated 17176-05-17 · 3 min · 481 words · -

React Hooks 详解

Hook 是 React 16.8 引入的一类特殊函数,命名以 use 开头。它让函数组件拥有了原本只有类组件才有的能力:状态管理、生命周期、跨组件共享逻辑。 为什么需要 Hook React 16.8 之前,函数组件只能做纯渲染,没有状态、没有生命周期。要用这些功能必须写类组件,但类组件存在几个痛点: this 绑定容易出错 生命周期方法(componentDidMount / componentDidUpdate)把不相关的逻辑强行塞在一起 状态逻辑难以在组件之间复用 Hook 彻底解决了这些问题,现代 React 项目基本全面使用函数组件 + Hook。 Hook 使用规则 这两条规则必须严格遵守,否则会导致 Bug。 只在函数组件或自定义 Hook 的顶层调用 Hook,不能在条件语句、循环、嵌套函数中调用 只在 React 函数中调用 Hook,不能在普通 JS 函数中调用 // ❌ 错误:在条件语句中调用 if (condition) { const [value, setValue] = useState(0); } // ✅ 正确:在顶层调用 const [value, setValue] = useState(0); if (condition) { setValue(1); } 内置 Hook useState 管理组件的局部状态。 const [state, setState] = useState(initialValue); state:当前状态值 setState:更新状态的函数,调用后触发重渲染 initialValue:初始值,也可以传入一个函数(懒初始化) import { useState } from "react"; function Counter() { const [count, setCount] = useState(0); return ( <div> <p>计数:{count}</p> <button onClick={() => setCount(count + 1)}>+1</button> <button onClick={() => setCount(prev => prev - 1)}>-1</button> </div> ); } 函数式更新:当新状态依赖上一个状态时,推荐传函数给 setState,避免闭包陷阱: ...

Created 17176-05-17 · Updated 17176-05-17 · 4 min · 675 words · -

JSX 是什么

JSX 解决了什么问题 在 JSX 出现之前,用 JavaScript 描述 UI 结构需要这样写: const el = React.createElement( 'div', { className: 'card' }, React.createElement('h2', null, title), React.createElement('p', null, content), React.createElement('button', { onClick: handleClick }, '确认') ); 嵌套稍深就几乎无法阅读。而人类天然擅长读 HTML 这种树形标签结构。 JSX 解决的核心问题是:让 UI 结构可视化,让开发者用熟悉的标签思维描述界面,同时保留 JavaScript 的全部表达能力。 // JSX 版本,结构一目了然 const el = ( <div className="card"> <h2>{title}</h2> <p>{content}</p> <button onClick={handleClick}>确认</button> </div> ); JSX 是什么 JSX(JavaScript XML)是一种 JavaScript 的语法扩展,允许在 JS 代码里直接写类似 HTML 的标签。 它既不是真正的 HTML,也不是模板引擎,而是 React.createElement() 的语法糖。浏览器不认识 JSX,需要由 Babel 等编译工具在构建阶段将其转换为普通 JavaScript。 // 你写的 JSX const element = <h1 className="title">Hello, {name}</h1>; // Babel 编译后(React 17 之前) const element = React.createElement( 'h1', { className: 'title' }, 'Hello, ', name ); // Babel 编译后(React 17+ 新 JSX Transform) import { jsx as _jsx } from 'react/jsx-runtime'; const element = _jsx('h1', { className: 'title', children: ['Hello, ', name] }); React 17 之后引入了新的 JSX Transform,编译器自动引入 react/jsx-runtime,不再需要在每个文件顶部写 import React from 'react'。 ...

Created 17176-05-17 · Updated 17176-05-17 · 3 min · 597 words · -

React 虚拟 DOM 与 Diff 算法

什么是虚拟 DOM 虚拟 DOM(Virtual DOM)是用 JavaScript 对象来描述真实 DOM 结构的一棵树,存在于内存中,是真实 DOM 的轻量级副本。 内存中的实际结构 React Element 虚拟 DOM 节点是一个普通的 JavaScript 对象(Plain Object),React 内部称它为 React Element,由 React.createElement() 创建。 // 你写的 JSX const el = <div className="box"><h1>Hello</h1></div> // Babel 编译后实际执行的 const el = React.createElement( 'div', { className: 'box' }, React.createElement('h1', null, 'Hello') ) // 返回的对象结构 { $$typeof: Symbol(react.element), // 防 XSS 的安全标记 type: 'div', key: null, ref: null, props: { className: 'box', children: { $$typeof: Symbol(react.element), type: 'h1', key: null, ref: null, props: { children: 'Hello' }, _owner: null, } }, _owner: null, } 树状结构靠 props.children 的引用嵌套形成,多个子节点时 children 是一个数组: div (React Element) └── props.children: [ h1 (React Element) └── props.children: "Hello" p (React Element) └── props.children: "World" ] React Element 只是"描述长什么样"的不可变快照,每次渲染都会重新创建,不会长期驻留内存。 ...

Created 17176-05-17 · Updated 17176-05-17 · 2 min · 401 words · -

基于原型的编程 (Prototype-based Programming)

注意:本文讲的是基于原型的编程范式,不是 GoF 设计模式中的 Prototype 模式。两者名字相同,但概念不同。 基于原型的编程是什么 基于原型的编程(Prototype-based programming)是面向对象编程的一种方式。与传统的基于类(class-based)的方式不同,它没有 class 的概念,对象直接从其他对象继承,又称为基于实例的编程(Instance-based programming)。 与基于类的编程的区别 基于类的编程(如 Java、C++): 先定义 class(类),class 描述对象的结构和行为 再通过 class 实例化出对象 对象的行为由其所属的 class 决定 基于原型的编程(如 JavaScript、Lua、Self): 没有 class,只有对象 对象直接从另一个对象(原型)继承属性和方法 可以在运行时动态修改对象,甚至修改原型 典型例子:JavaScript JavaScript 是最广为人知的基于原型的语言。每个对象都有一个内部指针指向它的原型对象,属性查找会沿着原型链向上查找。 const animal = { speak() { console.log("..."); } }; const dog = Object.create(animal); // dog 的原型是 animal dog.speak(); // 继承自 animal ES6 引入的 class 语法只是原型继承的语法糖,底层仍然是原型链。

Created 13136-11-13 · Updated 15156-05-15 · 1 min · 57 words · -

Builder 模式与 Factory Method 模式的对比

原文:http://www.cnblogs.com/shenfx318/archive/2007/01/28/632724.html 代码示例为 C#。 Builder 与 Factory Method 同属 GoF 创建型模式,初学者容易混淆。本文通过将 Builder 模式一步步演化为 Factory Method,探讨两者的本质关系。 注:本文讨论的 Factory 指工厂方法(Factory Method),不是抽象工厂(Abstract Factory)。 Builder 模式的标准结构 Builder 模式由四个角色构成:抽象 Builder、具体 Builder、Director(指导者)、Product。 public interface IBuilder { void BuildPart1(); void BuildPart2(); Product GetResult(); } public class BuilderA : IBuilder { private Product product; public void BuildPart1() { product = new Product(); product.Add("Part1 build by BuilderA"); } public void BuildPart2() { product.Add("Part2 build by BuilderA"); } public Product GetResult() { return product; } } // Director 封装构建顺序 public class Director { public void Construct(IBuilder builder) { builder.BuildPart1(); builder.BuildPart2(); } } 客户端调用: ...

Created 12126-10-12 · Updated 15156-05-15 · 2 min · 221 words · -

静态工厂方法 (Static Factory Method)

与 GoF 工厂方法的区别 静态工厂方法(Static Factory Method)不是 GoF 23 种设计模式之一,容易和 GoF 的"工厂方法模式(Factory Method Pattern)“混淆,两者本质不同: GoF 工厂方法模式 静态工厂方法 出处 GoF《设计模式》 Effective Java Item 1(Joshua Bloch) 本质 定义创建对象的接口,由子类决定实例化哪个类 用静态方法代替构造器来创建对象 是否 GoF 模式 ✅ 是 ❌ 不是,是编程惯用法(idiom) 静态工厂方法是 Joshua Bloch 在《Effective Java》Item 1 中推荐的编程惯例:用命名的静态方法代替构造函数。 基本概念 创建类的实例的最常见方式是用 new 调用构造方法。每执行一条 new 语句,都会在堆区产生一个新对象。假如类需要封装创建实例的细节、或控制实例数量,可以改用静态工厂方法。 典型例子:Class 实例由 JVM 在加载类时自动创建,程序无法用 new 创建 java.lang.Class 的实例(没有 public 构造方法)。为此,Class 提供了静态工厂方法: Class c = Class.forName("Sample"); // 返回代表 Sample 类的实例 相比构造方法的优势 1. 方法名可以携带语义 构造方法名必须与类名相同,所有重载版本名字一样,难以区分。静态工厂方法可以任意命名,提高可读性: ...

Created 26266-03-26 · Updated 15156-05-15 · 2 min · 276 words · -

Spring Boot + PostgreSQL 持久层框架

主流持久层框架 Spring Data JPA + Hibernate Spring Boot 默认推荐,依赖 spring-boot-starter-data-jpa ORM 框架,用注解映射对象和表 自动生成 SQL,支持 JPQL / Criteria API 适合领域模型复杂的场景 MyBatis / MyBatis-Plus 半自动 ORM,SQL 写在 XML 或注解中 对 SQL 控制力强,适合复杂查询 MyBatis-Plus 提供代码生成、分页等增强功能 JOOQ 类型安全的 SQL DSL,SQL 风格写法 编译期检查 SQL,适合喜欢写 SQL 的团队 商业数据库需付费版 Spring Data JDBC 比 JPA 更轻量,无懒加载、缓存等复杂特性 SQL 更透明,适合简单 CRUD R2DBC(响应式) 非阻塞响应式驱动,配合 WebFlux 使用 依赖 spring-boot-starter-data-r2dbc 选型建议 场景 推荐 快速开发,标准 CRUD Spring Data JPA 复杂 SQL,精细控制 MyBatis-Plus 强类型 SQL,重查询业务 JOOQ 响应式架构 R2DBC 连接池 Spring Boot 默认使用 HikariCP 作为连接池。 ...

Created 25256-04-25 · Updated 11116-05-11 · 3 min · 467 words · -

软件工程师的能力与素质

技术能力 扎实的基础:数据结构、算法、操作系统、网络、数据库原理 系统设计能力:能权衡取舍,设计可扩展、可维护的系统 调试与排障:能快速定位问题,善用工具(profiler、日志、监控) 阅读代码:能快速理解陌生代码库,而不只是写代码 持续学习:技术演进快,能主动跟进新技术而不盲目追新 工程素养 写可读代码:代码是写给人看的,命名清晰,逻辑直白 测试意识:主动写测试,而不是依赖 QA 兜底 版本控制规范:清晰的 commit message,合理的分支策略 文档意识:在合适的地方写合适的文档(不是每行都注释) 安全意识:代码层面的 OWASP 意识,不把安全留给"以后再说" 协作能力 沟通清晰:能向非技术人员解释技术问题,能在 code review 中表达具体意见 估时准确:能分解任务,给出相对可靠的工时估算 主动暴露问题:遇到 blocker 早说,而不是默默卡住 思维方式 系统思维:看到局部问题时,能思考对整体的影响 务实:不追求完美设计,在"够好"和"完美"之间找到正确点 ownership:对自己负责的东西有主人翁意识,上线后持续关注 简单优先:倾向于简单方案,而不是过度设计;代码越少越好 软技能 抗压与专注:在复杂问题面前不慌,能保持有效的思考 接受反馈:对 code review 意见开放,不把技术讨论变成自我防卫 好奇心 好奇心是一个底层驱动力(meta-driver),不是和其他素质并列的加分项,而是在它们之上的一层——其他很多素质都可以被好奇心解释: 为什么愿意深挖 bug?→ 对根因有好奇心 为什么写好测试?→ 对"这段代码真的对吗"有好奇心 为什么沟通顺畅?→ 对同事的想法和 enduser 的真实需求有好奇心 好奇心不只是对新技术的好奇,它覆盖技术、协作、产品三个维度: 好奇心的方向 驱动的行为 对新技术 主动学习,不等培训 对异常日志 追根溯源,不绕过问题 对业务逻辑 理解 why,不只是 how 对同事的想法 真正倾听,不是等自己开口 对 enduser 产品感,不只是功能完成度 没有好奇心的工程师可以把当前的工作做得"够用",但很难做到深入——他们写的代码能跑,但不理解为什么。 好奇心本身还不够,它需要配上自律和落地能力。有些人什么都好奇,但浅尝辄止,或者永远在学新东西却从不完成一件事——这是好奇心失控的版本。 更完整的表述是:有边界的好奇心——对核心领域深挖,对周边领域保持开放,但不被新鲜感分散焦点。 好奇心 vs 好胜心 很多工程师有强烈的好胜心——想赢、想证明自己——但好奇心不足。他们学新东西是为了"会",不是真的想搞懂。这两种人外表相似,但遇到真正难的问题时会分叉:好胜心驱动的人倾向于绕过难点或表演能力,好奇心驱动的人会停下来真正弄清楚。 ...

Created 9096-05-09 · Updated 9096-05-09 · 1 min · 117 words · -