[{"content":"大模型是什么？ 大模型是大语言模型（Large Language Model, LLM）的简称，基于海量数据和庞大参数规模得到的机器学习模型，能够理解和生成自然语言和代码等内容。\n大模型有什么核心特点？ 大模型的核心特点是参数规模大、通用性强、上下文理解。\n大模型的参数规模在十亿到万亿量级，比如GPT-4有1.8万亿。有些模型参数会带在名字里，比如Qwen-72B指的是千问通用大模型的720亿参数的版本。\n大模型的通用性在于任务无关性、小样本学习和多模态能力。大模型预训练学习广泛的知识，可以适用于多种任务，问答、翻译、编程等。大模型无需额外训练，仅通过示例就可以执行新任务。多模态大模型可以同时处理文本、图像、语音等输入。\n大模型支持长文本交互，能结合上下文生成连贯的回答。大模型能识别上下文代词的指代以及省略，维持主题避免重复或矛盾，提取分散在多段落中的关键信息。大模型的上下文理解能力得益于注意力机制和位置编码，但也有长程衰减的特点，注意力权重下降。上下文有窗口限制，比如GPT-4支持128K个token，超出会被丢弃。\n大模型的局限性体现在幻觉、数据偏见和算力要求高。幻觉是在上下文模糊的情况下产生的一种虚构内容的现象。训练数据中如果有偏见那么大模型也会产生偏见。目前训练和部署都需要大量的GPU资源。\n大模型有哪些应用场景呢？ 大模型凭借其强大的语义理解和生成能力，将会影响到各行各业的创新和协作，就目前看，主要是以下四个大类：\n自然语言处理：知识问答／智能客服、机器翻译、情感分析，可结合语音处理的技术提供更贴近生活的用户体验 代码生成和辅助：代码补全、文件编辑、代码生成、代码理解和转换、注释生成、测试用例生成、错误修复、设计建议，可通过代理调用其他服务扩展大模型的能力 内容创作：营销文案、广告创意、新闻快讯、剧本大纲、字幕生成、编辑校对、文字润色，可结合图像、语音、视频处理的技术生成多模态的内容 分析诊断：疾病辅助诊断、辅助数学证明、科研论文阅读、智能顾问、自适应学习、合规审查、风险分析 大模型有哪些核心能力呢？ GPT-5直接给出了16项能力（Capability），是DeepSeek给出的两倍，看上去也不太好说哪个就能包含或者推导出另一个，难以剔除，只能进行分层（Level）和分组（Group），GPT-5给出的结果基本没有太多可挑剔的，它直接对能力分了七层和六组，不过我还是觉得太多了，索性让它把六组做了分层，它给出了三个方案，我选择了大小适中的方案介绍。\n四个分层是\nL1: 表示与变换 L2: 推理与决策 L3: 编排与行动 L4: 治理与保障 四层中，前三层的关系是上一层是下一层的基础，而第四层需要贯穿整个三层。六个分组是\nG1: 语言与表示 G2: 语义变换 G3: 认知推理 G4: 交互控制 G5: 外界接入与行动 G6: 治理与保障 六个分组到四个层的归属关系是这样的：\nL1: G1, G2 L2: G3 L3: G4, G5 L4: G6 详细来看看16项能力的描述和示例。\nC1: 语言理解（NLU）- 读懂意图、上下文、指代、情感、语义相似度；意图识别、问答、分类、相似句召回 C2: 语言生成（NLG）- 连贯生成与风格控制、改写；邮件/文案撰写、语气转换、SEO内容 C3: 翻译与跨语言 - 多语互译、术语一致、语域迁移；技术文档本地化、多语客服 C4: 长上下文与记忆 - 超长文档处理与跨段一致性；长合同问答、项目历史跟进 C5: 多模态理解与生成 - 图像/音频/视频/表格理解与描述；图表解读、截图问答、图像说明 C6: 信息抽取与结构化 - 实体/关系抽取、要点表格化；合同要点提取、舆情三元组抽取 C7: 摘要与压缩 - 多粒度总结、对比摘要、主题归纳；会议纪要、论文速览、新闻汇编 C8: 推理与规划 - 常识/因果/数学推理，任务分解与计划；解题思路、行程规划、流程优化 C9: 数据分析与轻量可视化 - 描述统计、趋势洞察、异常解读；报表解读、A/B结果解释 C10: 指令跟随与对话管理 - 按自然语言步骤执行，保持多轮上下文；流程性任务执行、对话机器人 C11: 个性化与风格控制 - 角色设定、语气/长度/格式可控；法律/学术风格、对话式教程 C12: 检索与知识增强（RAG）- 结合外部文档检索提升事实性与时效；企业知识库问答、条文引用 C13: 工具使用（函数与插件调用）- 调用API/数据库/计算器/浏览器等；下单、查库存、运行SQL、网页查证 C14: 代码能力 - 生成、重构、补全、调试、解释；API示例、单测补全、错误定位 C15: 代理与自动化 - 拆解-执行-回顾的自主循环；竞品调研到成稿的一体化执行 C16: 安全与可控性 - 敏感识别、合规约束、审计可追踪；内容审核、PII识别、策略对齐 它给的示例中，大部分我还都知道是什么内容，像语域迁移、舆情三元组、PII识别的概念都是头次听说，它的知识储备的确让人类的个体望尘莫及啊。最后，16项能力到六个分组的归属关系是这样的：\nG1: C1, C2, C3, C4, C5 G2: C6, C7 G3: C8, C9 G4: C10, C11 G5: C12, C13, C14, C15 G6: C16 大模型能力的评价维度有哪些？ 大模型训练和推理过程中都需要指标去评价，从而帮人去认识大模型的能力和能力边界，以达成选择和优化的目的。不同的阶段和方法会涉及到非常多的指标，但一般能从六个维度来看：\n准确性：输出是否正确、与证据一致、逻辑自洽，比如语言理解和生成中分类或者选择的准确率、推理和数学问题解答的正确率、知识生成的幻觉率、代码测试用例的通过率等。 稳定性：在扰动、不同随机性、长链路下保持一致且不崩溃，比如度量决策稳定性的温度、扰动一致性评分、对抗测试输出相似度等。 时效性：对近期事实/变化的掌握与更新能力，比如近期实时回答的正确率、线上模型主题分布和训练分布漂移等。 成本与性能：服务成本与性能效率，比如首token的延时、平均token生成速率、单次推理成本、能耗比等。 安全与合规：有害内容、越权、隐私与法规风险，比如毒性内容触发率、个人身份信息泄漏率等。 用户体验：用户主观满意与交互效率，用户满意度、净推荐值、会话留存率、平均会话长度等。 大模型的局限与缓解方法？ 从大模型能力的四个分层上来看局限性和缓解策略：\n表示与转换：符号接地问题（Symbol Grounding Problem）是说抽象的概念与概念的符号如何能对接上真实的对象或者指代的符号。这个局限性一方面来自于多模态的表示不足，另一方面来自于大模型不具备真实世界的体验，而依赖于统计模式。从梅拉尼·米歇尔的观点看，人工智能还缺乏直觉知识，也就是人们普遍习以为常但并未被记录成文字的知识。表示不足容易造成幻觉，目前缓解的办法是通过内容对齐、检索增强、不可回答时拒答、结合知识图谱等。 推理与决策：因果推理薄弱，有长推理漂移与数学/逻辑错误。这个局限性来自于用统计的相关性代替因果逻辑。从梅拉尼·米歇尔的观点看，人工智能还缺乏抽象、类比、元认知。抽象是说通过抽取不同事物之间的共性特征而构建新的概念。类比是抽取共性的基础上进行预测。元认知是一种反思观察思维过程的过程与抽象。在大模型涌现出思维链能力后，这个局限性有所缓解，其他的缓解办法还有引入工具计算、分步验证、断言检查、规划-执行-回顾等。 外界接入与行动：物理执行缺失，感知外界变化滞后，实时交互延时。这个局限性来自于文本的符号世界与物理世界的割裂，传感器和执行器难以闭环。数据训练虽然成本高、周期长，但跟传感器和执行器的接入和演进速度来比，已经算是低成本和极快的迭代速度了。缓解办法是发展模型上下文协议（MCP）增强模型接入工具的能力。 安全保障：隐私泄漏、偏见与毒性输出、对抗攻击脆弱。这个局限性来自于安全目标的不可计算性。缓解办法是数据脱敏、价值观的统一、内容过滤、对抗性测试等。 大模型能力落地范式有哪些？ 大模型落地的范式有五种：\n纯生成 知识增强生成 工具与程序增强 编排与工作流 模型定制 纯生成，也就是通过提示词工程，提供少量样本参考，做结构化的生成。这种方式直接通过调用通用或者推理大模型的API，选择合适的初始化配置，结合着提示词优化就可以实现，成本较低。适合简单问答，不需要实时信息，没有特殊安全与隐私合规的需求。\n知识增强生成，也就是在用户和大模型之间，加入额外的系统对用户原始请求或者大模型的答案来增强知识，从而增加大模型回复的准确性。具有代表性的是检索增强生成（RAG），通过信息检索技术，在文档库中检索相关的文档片段，作为额外的知识，一起传给大模型，来降低幻觉，提升信息的时效性。这种方式适合专业领域知识并未公开但可以内部检索的需求，还有时效新闻来不及训练的需求。\n工具与程序增强，也就是让大模型具备使用外部工具和执行程序的能力，大模型作为代理人去使用工具完成任务或者补充精确计算结果。这种方式适合编程这种环境相对封闭的需求，还有简化企业内部工具使用的需求。\n编排与工作流，也就是让大模型作为多个代理人角色承担计划、执行、回顾等多种任务，自动完成完整的工作流。这种方式适合自动化运营和批量报表生产。\n模型定制，也就是通过指令对齐、模型微调让大模型能适应特定任务或者领域。这种方式需要额外训练，对数据规模和成本要求较高，适合法律、医疗、编程等专业领域。\n大模型的原理和核心技术？ 大模型的核心思想是通过海量数据+巨量参数+自监督学习实现通用智能，其原理和核心技术体现在算力、算法和数据三个方面。\n算力：\n张量核心与混合精度 稀疏计算技术 显存分层与内存优化 通信栈和互联硬件优化 并行分片技术 CUDA生态和编译优化 芯片液冷和动态频率调节 算法：\n缩放定律与涌现能力 深度学习理论 神经网络理论 Transformer架构 向量化表示 训练扩展技术 微调对齐技术 参数压缩技术 参数调节技巧 数据：\n数据规模与计算资源配比 相似文本检测去重 低质量文本过滤 文本解析与规范化 数据增强技术 打包和加载技术 数据采样与混合策略 数据治理与可观测技术 ","date":"2025-08-15T00:00:00Z","permalink":"/posts/%E5%A4%A7%E6%A8%A1%E5%9E%8B%E4%B8%80/","title":"大模型（一）"},{"content":"算术平均、几何平均和调和平均在实际生活中应用广泛，只要有度量、有统计、要比较的地方都需要它们，理解它们的差别才能更好地使用它们，不论是设计新指标还是读取报告中的指标，都要知道它指代的真实含义和局限性。\n定义\n算术平均是n个数的和除以n。 几何平均是n个数的积开n次方。 调和平均是n除以n个数的倒数和。 示例\n算术平均：班级中有20人，20个人都参加了数学考试，拿到了20个分数，班级的平均分就是所有人的分数求和除以20。 算术平均：一个地区有男性人数20万，每个人都有身高，基本落在150厘米到190厘米之间，平均身高就是所有身高求和除以人数。 几何平均：假设股票连续四天的收益率依次是+100%、-50%、+100%、-50%，平均收益率0，也就是(1+100%)乘以(1-50%)乘以(1+100%)乘以(1-50%)，然后开四次方，等于1，无收益。 几何平均：人口增长率连续几年下降，求这几年的平均增长率，也是相乘后开方。 调和平均：一艘船走同一段路程，顺流而下的速度是5米每秒，逆流而上的速度是4米每秒，平均速度是4.4米每秒。 调和平均：n个并联电路的电阻依次是R1, R2, \u0026hellip;, Rn，等价于用了一个n/(1/R1+1/R2+\u0026hellip;+1/Rn)的电阻。 动机\n当我们希望用一个数字去刻画相同性质的一组数字的特征的时候，就可能需要平均数。统计学里常常需要做这样的事情，实际生活中，刻画群体特征，也需要这样的一些指标。最近看大模型中F1指标，就是Precision和Recall的调和平均，又想到了这个问题。\n好处\n信息从许多个压缩到了一个，比较好呈现，也容易做比较。\n局限\n这是一种有损的不可逆的映射，对于极端的分布，这样的指标特征刻画不够完整，也容易误导。比如一个地区的平均工资会被少数的高收入群体拉得很高。\n大小\n三个平均数的大小关系是\n算数平均数 \u0026gt;= 几何平均数 \u0026gt;= 调和平均数\n当n个数完全相同的时候，取到等号。\n含义\n不管哪种平均都意味着均匀、均等，更对称，更靠近中心的意思。 算术平均刻画了可叠加的多个数，分布均匀的条件下，取得同样和的那个数值是几。 两个数值的算术平均从几何上看，一般有两个角度。第一，当两个数值是长方形的两条边长时，有同样周长的正方形的边长就是这个算术平均数。第二，当两个数值代表两条首尾相接共线的线段时，总线段一半的长度就是算数平均数。 算数平均到三维的几何含义，第一个角度可以说立方体的表面积，第二个角度可以说质心的坐标位置，更高维依然可以这样类比。第一个角度叫做和等效均衡，第二个角度是线性均衡，或者说空间中心趋势。 几何平均刻画了可叠乘的变量，分布均匀的条件下，取得同样积的那个数值是几。 两个数值的几何平均从几何上看，一般也有两个角度。第一，当两个数值代表长方形的两条边长时，得到同样面积的正方形的边长就是这个几何平均数。第二，当两个数值代表两条首尾相接共线的线段时，以总线段中点为圆心，总线段一半长为半径做圆，从相接点向圆做垂线，这段垂线段长度就是几何平均数。 几何平均到三维的几何含义，第一个角度可以说得到相同体积的立方体边长，是积等效均衡，第二个角度可以说三个数的比例均衡。 调和平均刻画了完成同样一件事情不同方法或者不同角度的效率的平均。 调和平均的几何意义是面积相同的n个长方形，若各自的底长度不变，得到总面积不变的一个大的长方形的高也就是原来n个高的调和平均。 用途\n可叠加的量求平均用算数平均，比如路程、时间、人数、分数、身高、体重、长度等等。 增长率一类叠乘的量求平均用几何平均，比如经济增长率、投资收益率、人口增长率、声音频率等等。 效率一类倒数可叠加的量求平均用调和平均，比如速度、折射率、电阻并联等等。 讨论\n三个平均数在很多时候，从计算的数值上看，差别并不大，似乎不用那么严格影响也不大。比如一个人90分，一个人80分，算数平均是85.00分，几何平均是84.85分，调和平均是84.71分，用哪个也都差不过一分。但一些特殊情况就不那么回事了，比如一个人10分，一个人90分，这个差别就大了，如果有一个0分，几何和调和就都得0分了，或者严格来说调和无意义，0不能取倒数。再比如前面举的收益率的例子，如果用了算数平均就会错误地判断四年的平均增长率是+25%，但实际上四年的平均增长率是零。因此，实际应用中，一定要注意量的实际含义，选择合适的平均数。\n","date":"2025-08-12T00:00:00Z","permalink":"/posts/%E4%B8%89%E7%A7%8D%E5%B9%B3%E5%9D%87%E6%95%B0/","title":"三种平均数"},{"content":"概述 什么是微服务？ 微服务是一种软件架构风格，相较于单体架构（整体式架构），应用被拆分为多个小型、独立服务，每个服务围绕特定业务功能构建，独立开发、部署、扩展和维护，服务间通过轻量级的通信机制协作，来组合完成完整应用。微服务和微服务架构是一个意思。每个微服务由各个小型独立团队负责。\n为什么需要微服务？ 微服务架构从单体架构（整体式架构）演进而来，经历了从单体架构到面向服务（SOA）架构，再到微服务架构的变化。微服务架构使应用程序更易于扩展和更快地开发，从而加速创新并缩短新功能的上市时间。\n微服务架构具有自治和专用的特点。自治加快了应用的发布速度，让开发变得敏捷、功能扩展更灵活、工具选择更自由、部署更轻松。专用降低了应用功能的耦合性，提高了代码模块的重用，也缩小了故障影响提升了可用性，让应用更具弹性和可伸缩性。\n微服务和云原生是什么关系？ 微服务架构是云原生架构的基石，除了微服务之外，云原生的关键技术还包括容器、Serverless和DevOps。微服务架构的核心目的是通过模块化来提升应用研发的效率，而云原生的核心目的是最大化地利用云平台的特性来实现高效的资源利用、快速迭代和自动化运维，两者相辅相成。\n构建微服务有哪些典型的服务组件？ 典型的微服务组件可以从七个角度来看：\n业务核心组件：服务实例、服务接口 通信组件：API网关、RPC通信（同步）、消息队列（异步）、定时任务（异步）、注册中心 数据管理组件：独立数据库、分布式缓存、时间流处理 运维监控组件：容器和编排、配置中心、日志与监控 安全组件：身份认证与授权、服务网格 弹性与容错组件：域名解析、负载均衡、限流器、熔断器、重试与降级 开发与交付组件：持续交付、基础设施即代码 参考阅读 什么是微服务？AWS 什么是微服务？阿里云 微服务是什么？阮一峰 什么是云原生？AWS 云原生架构 AWS 什么是云原生？阿里云 什么是云原生？Google Cloud ","date":"2025-06-09T00:00:00Z","permalink":"/posts/%E5%BE%AE%E6%9C%8D%E5%8A%A1%E4%B8%80/","title":"微服务（一）"},{"content":"虚拟化有哪些核心概念？ 服务器的虚拟化 虚拟化的核心就是虚拟机监视器（Virtual Machine Monitor, VMM/Hypervisor），它是一个虚拟化层，将硬件抽象成虚拟计算资源，分配给虚拟机使用。硬件是一台物理机，有些情况下也被称作宿主机（Host Machine）。虚拟机运行在VMM之上，也被称作客户机（Guest Machine）。在虚拟机上才会安装操作系统（OS），用以通过服务和应用供用户操作完成一些特定的任务。VMM直接运行在硬件上的也被称作裸金属型的。此外，还有一种运行在操作系统上的被称作宿主型的。\n服务器的虚拟化的抽象资源包括处理器（CPU或者GPU）、内存和I/O，CPU和内存用于通用计算，GPU用于图形计算、并行计算、智能计算，I/O用于扩展外部设备，包括存储和网络等。从功能上看，虚拟机监视器提供虚拟机的创建、资源的隔离和调度、虚拟化的设备管理等三项功能。此外，为保障虚拟资源的执行效率，降低虚拟化的损耗，VMM的很大一部分工作是性能优化，许多的架构设计方案都是为了达成这个目标。\nCPU的虚拟化 物理CPU虚拟化的产物是虚拟CPU，或者vCPU，物理CPU也被称作pCPU。CPU的核心功能是接受指令请求和处理指令，串行接受指令请求和处理指令的单元是线程。模拟出vCPU的主要工作就是构造出线程的部件和功能，包括控制器、运算器、寄存器和高速缓冲存储器等部件，取指令、翻译指令和执行指令等功能。vCPU的数量取决于三个因素，物理CPU的数量、一个物理CPU内的核心数、一个核心的超线程数。\n每个虚拟机可以被分配所有的vCPU，也可以分配部分，VMM负责vCPU的调度，也就是把vCPU上的指令转换为物理CPU上的指令。依据虚拟化方法的不同，有全虚拟化、硬件辅助虚拟化和半虚拟化。虚拟化方法需要VMM和虚拟机甚至是客户机的操作系统能够配合和兼容。全虚拟化也就是完全在软件层面模拟接受指令请求和处理指令的过程，这种情况下陷入内核执行的指令数量很多，因此性能较差。硬件辅助虚拟化是针对特权指令才陷入到特权级别执行，在CPU中实现了虚拟机的上下文切换和状态管理，提升了性能。半虚拟化需要修改操作系统来支持hypercall，使得客户机的操作系统也能运行在物理CPU的特权模式下。\n内存的虚拟化 内存虚拟化的产物是虚拟内存，但实际上虚拟内存在没提虚拟化的时候，就已经有了。虚拟内存是为了给每个进程分配逻辑一致的独立的地址空间，有别于物理内存。在内存的虚拟化中是为了给每个虚拟机分配逻辑一致的独立的地址空间，在进程地址空间之外又加了一层，这样算下来是四个地址：客户机的虚拟地址（GVA）、客户机的物理地址（GPA）、VMM的虚拟地址（HVA）、VMM的物理地址（HPA）。不管几层，虚拟化方法的核心功能都是类似的，都是地址映射，实现机制就是通过页表分页管理地址映射，提高效率的方法就是减少映射转换的次数。\n可被虚拟化的内存资源数量受到GPU支持能力、主板内存插槽数量、单条内存容量、内存类型等因素的限制。虚拟内存的容量受到物理内存容量和内存超分配技术的限制。\nI/O的虚拟化 除去CPU和内存外，其他的设备都算作I/O，I/O往往是通过接口外挂上去后，由设备控制器与CPU和内存进行控制权、状态和数据的交换的。控制是双向的，由设备发起的是中断请求，由CPU发起的是设备访问。中断请求和设备访问都会下发指令，使得另一方的状态发生变化，同时携带要传递的数据。为提高CPU的效率，对于大量的数据移动，会通过DMA完成。\n虚拟化的目的是为了分隔资源和利用资源，梳理来看这里面的资源有设备、接口、总线和中断处理器/RTC/DMA等四项。虚拟化设备需要单独拎出来看，不同的设备虚拟化的方法有所不同，共性是接入CPU和内存的方式，以及通信和控制的方式。接口用于接入设备，物理实体上是各种端口和插槽，从通信机制上看，一种是端口I/O，另一种是内存映射I/O。总线用于设备和CPU、内存间的通信，连接了设备和CPU、内存。接口和总线的虚拟化，就是接入配置和通信机制的虚拟化。通信机制的核心部分是中断处理器、RTC和DMA完成的，虚拟化通信机制的主要部分就是虚拟化它们。\n具体到虚拟化的解决方案所要讨论的，就是VMM中有没有必要实现某种资源的虚拟化，某种资源的虚拟化可否放在用户空间实现。\n虚拟I/O的设备数量受限于物理主机的I/O带宽（网络带宽、存储带宽等）、VMM的参数配置（资源类型、设备配置等）、物理设备虚拟化的支持情况、虚拟设备的类型和数量（虚拟网卡、虚拟控制器等）等因素。\nGPU的虚拟化 从硬件上看，GPU通常是显卡的一部分，显卡属于外部设备，需要跟CPU和内存配合工作。CUDA编程让GPU能够支持通用的并行计算（GPGPU），在CUDA编程之前GPU主要通过图形接口执行图形渲染任务。随着GPU被人工智能领域用来训练深度学习的神经网络，这样的计算也开始被称作智能计算。\n物理GPU虚拟化的产物是vGPU，将vGPU分配不同的虚拟机使用，为了保障性能，也有直通的资源独占的方式。由于显卡的外设属性，也需要考虑设备驱动，可GPU又不同于其他的外设，具备计算的能力，因此GPU的核心在处理计算任务的时候也被看作是服务器，而不仅仅是向CPU发起中断请求的客户端。在英伟达vCUDA核心的设计上，有三个模块客户端、服务端和管理端。客户端是安装在虚拟机上的显卡驱动程序，负责对CUDA应用程序API的拦截、解析、包装、代理请求和代理响应。服务端是位于一个特权虚拟机中，负责接受管理端的资源注册，以及为客户端的请求提供服务。管理端才是GPU的管理器，位于特权域VMM中，负责GPU的动态调度、负载均衡和故障恢复。\n物理GPU的数量受限于主板显卡的卡槽数量、显卡的类型、总线带宽和电源供应等因素。虚拟GPU的数量受限于物理显卡的数量、VMM的配置和调度策略、GPU和内存资源等因素。\n存储的虚拟化 存储虚拟化需要从两个角度来看，一个是用户的使用角度，另一个是物理设备的管理。\n从用户使用角度看，有直接挂载磁盘的块存储，也有直接挂载文件系统的文件存储，还有更扁平化的对象存储。\n块存储相当于一块空白的磁盘，支持创建、初始化、挂载、卸载等操作。创建的结果是一个虚拟磁盘，初始化的结果是要对虚拟磁盘进行分区或者格式化，并创建文件系统。在分布式环境中，创建和初始化的结果跨越了单机的限制，但实质上与本地磁盘管理要做的事情类似，都是元数据的管理。虚拟磁盘的挂载和卸载也是元数据的操作。除了元数据操作外，实际数据的读写需要遵从一些分布式的网络存储协议，并且要做好元数据中分区、块和实际物理存储之间的映射关系。操作系统使用的存储协议需要考虑网络环境，iSCSI（Internet Small Computer System Interface）是基于IP的存储协议，适用于局域网和广域网连接的块存储；Fibre Channel是专用于存储区域网络的高速传输协议；NVMe-oF是基于NVMe的网络协议。\n文件存储不再增加分区和块的概念，元数据中直接管理文件和文件夹。网络文件存储协议有NFS（Network File System）、CIFS/SMB（Common Internet File System/Server Message Block）和AFP（Apple Filing Protocol）。对象存储相比文件存储更加扁平化，元数据管理存储空间（Bucket）和对象。对象存储首先是亚马逊AWS的S3现实，也被称作S3协议。\n从物理设备管理的角度看，存储虚拟化分三个层次，最底层是存储资源的标准化接入，中间层是统一的数据管理，再上层是虚拟存储整合成资源池。存储的资源主要是磁盘，从介质上是两类，机械硬盘（Hard Drive Disk, HDD）和固态硬盘（Solid State Drive, SSD），此外，还有混合固态硬盘和磁带。存储资源接入主机可以是单块内置或外置，也可以是多块构成的存储阵列。机械硬盘接入主要通过SATA接口，也可以通过SAS（Serial Attached SCSI）扩展器，或者网络协议iSCSI和FC。固态硬盘接入主要通过PCIe槽位，利用NVMe访问和传输协议控制硬盘读写。同一块硬盘通过分区形成不同的存储盘，多块存储盘的物理分区通过逻辑卷组形成跨磁盘的逻辑卷（虚拟分区）。集中的块存储服务通过专门的网络结构和网络协议搭建形成SAN（Storage Area Network）存储。集中的文件存储服务通过瘦服务器将磁盘阵列管理起来形成NAS（Network Attached Storage）存储。通过主机服务器来访问存储的架构是以服务器为中心的架构，成为直连DAS（Directed Attached Storage）存储。虚拟主机也可以接入本地存储镜像。\n网络的虚拟化 网络由网络节点和传输介质组成，此外在节点之间传输信息需要协议进行控制数据传输。对网络进行虚拟化就是对网络节点、传输介质和传输协议进行设计和实现。虚拟化的网络称作Overlay网络，物理网络称作Underlay网络。\n网络节点按照功能分主要有五种客户终端、主机服务器、交换机、路由器、网关。对于网络实现来讲终端和服务器都能归结到网卡（NIC）上。传输介质有同轴电缆、双绞线、光纤、无线电波等。传输协议按照网络分层是底层在外层，上层在里层，一层包一层，封装和拆包的过程恰好相反。\n虚拟化后的网络节点也被称作网元，都通过软件定义实现。虚拟主机通过挂载虚拟网卡进行网络通信，两台虚拟机之间通过虚拟交换机通信，虚拟网卡和虚拟交换机之间通过虚拟链路通信。跨物理机的虚拟机之间的通信除了需要隧道封装技术外，还需要经过虚拟地址和物理地址的映射转换的NAT网关。Overlay的隧道封装技术主流的包括两种GRE（Generic Routing Encapsulation）和VxLAN（Virtual eXtensible LAN）。\n","date":"2025-05-31T00:00:00Z","permalink":"/posts/%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF%E4%BA%8C/","title":"虚拟化技术（二）"},{"content":"今早这个司机挺有趣，血气方刚，情绪高涨，因为我主动提醒，“小区里开慢点别错过出口，好多司机开太快，导航来不及反应”，开始滔滔不绝讲了一路。\n他的讲话里八成都在讲跟女乘客的恩怨情仇，核心是要给挡风玻璃中间挂着的运动摄像头正名，大概这个摄像头帮他赢得了很多场斗争的胜利。\n面对陌生人，刚开始起头，要讲社会问题，不能太琐碎，探探他的口风，找找他的兴趣点，看看他的态度。\n有人主动跟我讲话，我自然乐得听些故事，摘下耳机，随声应和，脑海中浮现出的是两个场景。一个是短视频里黄执中讲如何当捧哏让出租车司机讲得意犹未尽，还有一个是跟朋友打车去八大处爬山的路上他把司机引得很尽兴。\n从大同强奸案、婚姻法的调整到结婚率的下降，从网红游戏主播的夫妻不睦到“傅首尔”们的荒诞。基本论点是社会纵容女性到了不可理喻的地步，男性已经委屈到回家吃不上一口热饭的境地，不光钱被骗了去还得戴顶绿帽子。我想说说在工业社会细分工下，人的功能和价值的局限性，也想说说书本外的社会传统的惯性下，多数人头脑中对家庭结构和家庭成员的刻板印象，与建设独立人格和寻找精神寄托的割裂，可惜我插不上话，也不知道从哪儿讲起。 他讲了三段。第一段是坐在副驾驶座的女乘客控诉被他摸了，他讲了只是看到了女乘客掀起裙子后的内裤的颜色。他讲得绘声绘色。\n第二段是女乘客抱着猫上车，猫跳到后排座位弄得满车猫毛，乘客还要求他爱护猫，不要冲她大喊大叫。他讲得义愤填膺。\n第三段是帮两个女乘客放行李箱，一位提醒行李重表示要搭把手，另一位轻蔑他说“他就是干这个的”。他讲起来仍旧暴躁如雷，粗口不停。\n他的结论是除了干程序员的女性，大多数的女性太过情绪化，不讲理，面对纠缠半个钟头的投诉，他必须要用摄像头来捍卫自己的权益，证明自己的清白。\n我试图给他讲造成一些女性情绪化的原因，比如社会家庭的规训，他说他只能认同50%。其实我还想说，他其实是乐得跟女性发生纠缠的，即便只是个女乘客，这是他生活的乐趣，不过我还是默默选择不给自己惹麻烦，人们不喜欢被教育，让一个人看清了真相之后，他会变得茫然，变得抑郁。\n最后一段，他讲了个奇怪的男乘客，一路上不应答他的问话，下车开左边门，不听劝，他评价道这是个危险分子。以此来说明男乘客和女乘客的不尊重人有着显著的差别。他很自信自己看人的本领，他主动把自己的工作跟人力资源在贴近，七年的网约车职业生活，给他过得很精彩。\n熟人生活中，他不是我喜欢打交道的一类人，为了减少麻烦，我也需要给人贴上标签，但我无法否认我有点享受跟他共处这二三十分钟的时间，他的本性、他的善恶在他的语言和行为中尽情地释放，他增加了我的阅历，给我寂寞的生活增添了色彩。\n性是欲望的原动力，如洪水猛兽一般，有意无意地推动着大部分私人的往来，宗教、戒律、礼仪、法律都是外在的力量去约束它泛滥成灾，内在的力量需要精神信仰。是物质的充裕，造就了精神的解放，还是精神的解放，让物质变得充裕。我虽然算不上个马克思主义者，改造世界的内驱力没那么巨大，但我是坚信后者的。精神的解放到底解放了什么，是思想观念，是恋爱自由，是性别平等，还是欲望和恶行。\n","date":"2025-04-30T00:00:00Z","permalink":"/posts/%E6%91%84%E5%83%8F%E5%A4%B4%E6%AD%A3%E4%B9%89/","title":"摄像头正义"},{"content":"远离世俗生活的一类人，入世的方法只能通过做事情，不能通过拉关系。在做事中建立起关系，而不是去顺从世俗社会所定义的关系而去做事情。\n做事的立意很重要，是为了改善谁的生活，是为了谁的利益，要牺牲谁的利益，要放弃谁，必须要有所牺牲有所放弃，才能有所成就。谦恭退让不是立意含糊和立意不正的遮羞布。立意含糊的关系要避免，立意不正的关系要杜绝。\n以生存的欲望作为立意，这是生命的本能追求。以生存之外的欲望作为立意，这是生命的情趣所在。以断除欲望和情趣作为立意，这是生命的解脱之路。要安全，并忍受波涛汹涌的情海和没有穷尽的苦痛，还是要难以相信的解脱后的自由和宁静，这是生命的难题。\n","date":"2025-04-04T00:00:00Z","permalink":"/posts/%E7%94%9F%E5%91%BD%E7%9A%84%E9%9A%BE%E9%A2%98/","title":"生命的难题"},{"content":"为什么需要虚拟化？ 虚拟化可以对同一物理资源进行隔离处理，分给不同的用户使用，避免资源的闲置，提高资源的利用率。虚拟化是云计算的核心技术，云基础设施服务提供商对虚拟化的资源进行池化管理，通过资源的隔离和编排使得租用的用户能够在分钟级的时间内低成本获取到所需的资源，也提升了业务部署的灵活性。\n归纳起来有以下几点：1) 提升资源利用率，2) 降低成本，3) 屏蔽硬件差异，4) 提供资源隔离，5) 部署更灵活，6) 提升容灾能力。\n虚拟化技术为何得以持续发展？ 资源的标准化和规模化提升了资源的获取效率和资源的利用率，相较于非标准化和小规模的资源建设和使用来说有了利润。算力是大数据处理、信息服务、人工智能的要素之一，应用场景涉及的领域广阔。云基础设施服务提供商能专注在标准化和规模化算力和平台建设上，成为整个社会进入智能化的推动引擎，而各领域的消费者能够专注在业务开发上面而减轻设施的维护开销。\n什么是虚拟化？ 虚拟化是一种资源管理技术，它将单台物理计算资源抽象、转换后呈现，分割成多台虚拟机、操作系统或者容器。\n虚拟化的资源类型可以从多种层次来看，最为核心和基础的是计算（CPU/GPU/内存）、存储（磁盘）、网络、I/O。从云服务商的资产管理角度看，有服务器、数据中心。从消费者角度看，有应用、数据、桌面。\n多数时候人们所说的虚拟化就是指服务器的虚拟化，简单理解就是在一台物理机上运行多台虚拟机。\n虚拟化和容器化有什么区别？ 两者之所以值得比较，是因为虚拟化和容器化的结果都是一个可供应用运行的计算环境。从虚拟的层次来看，虚拟化通常是直接对物理资源的虚拟化，而容器化是操作系统级别的虚拟化，也有一种说法是应用级别的虚拟化。虚拟机上可以安装容器，但反之却不可以。\n容器化来自于操作系统的一个功能，内核允许存在多个隔离的用户空间的实例，这个实例被称作容器，或者分区，或者虚拟环境（VEs），又或者监狱（FreeBSD jails）。运行在操作系统中的程序可以看到计算机所有的资源，包括连接的设备、文件和文件夹、网络共享、CPU性能等，而运行在容器中的程序只能看到容器的内容和分配给容器的设备。从使用场景来看，容器化更轻量，更易扩展，更容易移植。容器化的代表是Docker。\n虚拟化和模拟、仿真有什么区别？ 虚拟化（Virtualization）、模拟（Simulation）和仿真（Emulation）都是为了构建一个运行环境，一般都是为了构建一个区别于物理实体的逻辑实体。不同之处在于构建的目的，虚拟化是为了提升硬件资源的利用率，通常是用于生产环境的，而模拟和仿真是为了测试和研究，性能往往较差。\n","date":"2025-04-04T00:00:00Z","permalink":"/posts/%E8%99%9A%E6%8B%9F%E5%8C%96%E6%8A%80%E6%9C%AF%E4%B8%80/","title":"虚拟化技术（一）"},{"content":"今天去机场的路上意外频发，直到飞机降落，悬着的心才算放下。\n刚出小区就听到汽车发出咔嗒咔嗒的响声，看着附近车堵得厉害，再想想早上看到了美国航空管控系统故障的新闻，内心有种不祥的预感。学了周易，我知道今天注定不顺，我得仔细应对，一路上竟然都没时间占一卦。好在我是做稳定性的，突发事件应急的方法论已经了然于胸。\n我跟司机抱怨了一下汽车的异响，请求他停车看一看。他把车停在小区出口的两条路中间，在后备箱敲了敲，我摇下车窗跟他说再试试吧。我明白这不是个解决问题的地方，后面跟了一排车，一会儿喇叭声该此起彼伏了。他上车解释说可能是轴承坏了，珠子可能掉出来。\n担心车坏在高速上，我难换车，就请求他结单。我这侧是公司做的一个网页客户端，无法结单。他可以结单，但他提前结单会按原始估算费用计费，我无法同意。看到可以修改目的地，让他停在了途中望京南地铁站附近。\n很快叫到了第二辆车，是位女司机，路上不停在跟家里人聊天，走到北皋路附近没上高速，结果往南绕回去了三公里，还是很堵的一段路。\n我慌了，开始跟她交涉绕行的问题，并强调我飞机的出发时间，希望她要确保三十分钟内抵达。\n我只能把绕行的责任推给路线规划，惹她不开心了，很可能给我误了飞机。她说她确实是按照导航走的，我难以再去追究是她的责任。她挂断了电话，不断变道插空，开始抱怨一些车留那么大车距。我安慰提醒她还是要安全第一。\n机场高速上走了一阵她提醒，还剩十一个红绿灯，感到有些奇怪。我赶快检查路线，发现我也犯了错，目的地没有选到航站楼的出发口，而是三号航站楼侧面的一个点，我赶忙更换。\n我比对了三个软件的路线，眼看着对齐了，结果司机说还是显示有八个红绿灯，规划路线中后一段没有第二高速，大概是公司软件为了节省五块钱高速费吧。我无法选择路线，只好作罢。\n临近T3航站楼时，导航又给出了跟路牌指示不一致的路线，好在司机及时提醒，我及时决策，要求她以路牌为准。她担心偏离航线我投诉她，我跟她讲还是要看路标。她要真给我误了，我可能真投诉她。\n两会期间机场人流大，不过机场应该增加了各方面资源，安检队伍长度跟往常差不多。赶到登机口，队伍已经排了起来，不一会儿就开始了检票，之后一切顺利。\n","date":"2025-03-09T00:00:00Z","permalink":"/posts/%E6%B3%A2%E6%8A%98%E7%9A%84%E5%B7%AE%E6%97%85/","title":"波折的差旅"},{"content":"在处理字段分组聚合时，如果需要多层次的聚合，有时还需要在新的层次进行该字段的合并，但SQL语言并没有提供直接的语法和简单的函数进行支持，经过MAP_UNION的去重操作，结合其他的一些数组转字典的操作，可以实现该功能。具体来说，已知表1中有两行数据\nc1 c2 c3 s1 d1 r1,r2 s1 d2 r1,r3 怎么得到表2\nc1 c2 c3 s1 d1,d2 r1,r2,r3 得到表2的数据，最直接的思路是通过GROUP BY进行分组聚合，c2列可以用过COLLECT_SET函数外加ARRAY_JOIN实现。对于c3列，需要先SPLIT成数组，然后再分组合并。查询MaxCompute SQL的函数手册，在数组方面并没有这样的功能。随后看到MAP_UNION的键可以去重，转而想到把数组转换成字典，合并字典的键后，再提取键转为数组，具体的代码可以参考：\nWITH test_table AS ( SELECT \u0026#39;s1\u0026#39; AS c1 ,\u0026#39;d1\u0026#39; AS c2 ,\u0026#39;r1,r2\u0026#39; AS c3 UNION SELECT \u0026#39;s1\u0026#39; AS c1 ,\u0026#39;d2\u0026#39; AS c2 ,\u0026#39;r1,r3\u0026#39; AS c3 ) SELECT c1 ,ARRAY_JOIN(COLLECT_SET(c2), \u0026#39;,\u0026#39;) ,ARRAY_JOIN(MAP_KEYS(MAP_UNION(MAP_FROM_ARRAYS(SPLIT(c3, \u0026#39;,\u0026#39;), ARRAY_REPEAT(1, SIZE(SPLIT(c3, \u0026#39;,\u0026#39;)))))), \u0026#39;,\u0026#39;) FROM test_table GROUP BY c1 ; 另外一种思路是设法让表1回到表3的状态，然后再对c3通过COLLECT_SET函数外加ARRAY_JOIN来实现。\nc1 c2 c3 s1 d1 r1 s1 d1 r2 s1 d2 r1 s1 d2 r3 在MaxCompute SQL中，可以用LATERAL VIEW语句结合EXPLODE函数来实现。具体的代码可以参考：\nWITH test_table AS ( SELECT \u0026#39;s1\u0026#39; AS c1 ,\u0026#39;d1\u0026#39; AS c2 ,\u0026#39;r1,r2\u0026#39; AS c3 UNION SELECT \u0026#39;s1\u0026#39; AS c1 ,\u0026#39;d2\u0026#39; AS c2 ,\u0026#39;r1,r3\u0026#39; AS c3 ) SELECT c1 ,ARRAY_JOIN(COLLECT_SET(c2),\u0026#39;,\u0026#39;) ,ARRAY_JOIN(COLLECT_SET(TRIM(t.c3_item)),\u0026#39;,\u0026#39;) FROM test_table LATERAL VIEW EXPLODE(SPLIT(c3,\u0026#39;,\u0026#39;)) t AS c3_item GROUP BY c1 ; ","date":"2025-02-09T00:00:00Z","permalink":"/posts/maxcompute-sql%E7%9A%84%E6%95%B0%E7%BB%84%E5%AD%97%E6%AE%B5%E7%9A%84%E5%90%88%E5%B9%B6/","title":"MaxCompute SQL的数组字段的合并"},{"content":" 2024年09月16日分享于pFinder邮件组，起因是教师节向贺老师的问候，写成时恰逢中秋节前夕。\n这次换工作参加了33场面试，历时八个月，拿到了两个口头录取，一个正式录取。尝试了五个技术方向，22个团队，九家公司。简历改了四轮，共十个版本。认识了三到四个还不错的猎头，一个职业顾问，两个靠谱的HR。整体来看，按团队算成功率13%，去掉前期的三个被介绍的机会，主动寻找的成功率只有5%，好在也还足够幸运，结果也算是得偿所愿。\n八个月间，心情起起伏伏，焦虑和自我怀疑，从未间断，轻松惬意的时间并不多。对自我的掌控感在增强，对生活的掌控感在减弱。面对困难的勇气和韧性在增强，对世间生活的期待在减弱。尽量随缘而行，不为难自己。\n换工作的因缘 这次换工作的内外条件都很充分，不便公开所有感知到的因素，就拣一些重要且能说的分享一下体悟和收获吧。\n推动换工作的主要因素是裁员，其次是职业成长的期待和未来生活的饭碗。\n裁员影响不到五十人，也没有在舆论上掀起什么风波。北美的技术总监亲自到北京宣布，会议大概持续了五分钟，本没有给提问的机会，我还是抓住话头鼓起勇气旁敲侧击地探寻决策的主要因素，但没得到任何答案。看得出来，他也有些错愕。\n大概也就只有我还在乎这个决策的主要因素吧，大家更在意接下来的安排，经济补偿、工作交接和求职机会。\n别人不说，我们就只能推测了，推测的结果缺乏直接的证据，但也同样能拿来对其他事情的决策做支撑，这就是信念了。从整体环境看，这个决策的政治因素占比应该比较高，经济因素应该是次要的，官方给出的时区差异造成的工作协同问题更是次要的。\n政治因素有宏观，有微观。宏观是俄乌战争都影响到了飞往西雅图的航线、班次和票价，中美的贸易对抗目前看上去，在中国土地上美国资本在不断撤退，中国的资本在不断外扩。亚马逊的上层领导不安的感受肯定要比我敏锐，信息渠道也更为直接和真实，毕竟政策和军事的影响，对他们来讲是实实在在的经济损失。微观是办公室政治，疫情和航班的管制对两地的面对面交流产生了很大影响，巩固信任和缓和矛盾缺乏了条件，也就自然走向了反面。\n北京团队参与购物平台的基础架构，属于零售业务的核心，在战略型的创新项目中，首席和高级别的工程师占比较其他业务要高出许多。我在一线领导团队中年纪轻，在技术上经验比较丰富，但在产品和管理上经验缺乏，只能在负责的一到两个业务问题领域中有一定的话语权。可我仍旧能深切地体察到北京团队在语言能力、技术能力和文化观念上难以融入到战略项目的核心决策上。除去日常会议的点滴感受，一个明显的外在表现是团队建设之初上层就没有同意在北京招一个首席工程师的请求，高级经理只能想办法培养。人与人之间的信任，创新想法的落地，是个鸡生蛋蛋生鸡的问题，生产和消费两方互为因果，要在频繁地试错和互动之中寻求壮大。现如今的结果不言自明。\n我在乎决策的主要因素，好奇和求真的心态或许有一些，但也许是本能的一种自利行为吧。我对安全感的需求多过自由，我大概是属于那种能在名教中找到快乐的人，所以更合适管束较多的土壤。可能是我能量不高的缘故，太过自由，我会感到不安，利他的行为也得在身心状态良好能力富余的情况下才能开展。\n全员当面宣布完，紧接着就是HR挨个面谈签协商解除劳动合同的协议。协议的关键点是补偿金额、几个关键的时间点以及要遵守的行为。外企给的经济补偿会比国内法律规定高些，大概因为在异国做生意，大方点可以免去很多麻烦。后来调研了解到在美国失业没有这么多的补偿。大多数人对补偿方案没有什么异议，我当下就签了。有异议的出在股票到期时间和落户影响等方面。比如，我们组有个同学，有落户名额，但北京市政策规定，要在一家企业工作满三年，他还差九个月，就在想寻求延长的解决方案。\n大的方案上分两类，一类给了去西雅图转岗的机会，且给了额外一段时间的项目交接的补偿，另一类只给了补偿和一定时间窗口内的带薪找工作时间。我在第一类中，于是就有了找贺老师参谋的事情。\n留在国内的决定 我在亚马逊呆了有八年多，都已经超过我学龄前在家的时间长度了。亚马逊带给了我很多，不错的收入、国际视野、职业成长的方法论、商业上做事的思维方法、良好的社会关系、说得过去的工作履历。可惜缘分到头，该走还是得走，我不再有信心跟着它获得职业的成长了。信心的丧失和家庭的牵绊让我选择留在国内。后来我虽然还有三次北京转岗的机会，但因为各种不合适，没有能够续上。\n许多人到外企工作的一个重要原因就是将其作为出国的踏板，然后长期在海外发展，寻求一片自由的天地，但我不仅没有过这方面计划，连意愿都说不上强烈。我在精神上向往自由，但我不觉得换个地方或者国家就能够得到自由。我的独立自主性也不够强大，依赖和跟随的心态一直很重，难以自己给自己安全感。我有好奇心和探索欲，但更多是向内的，而非向外的。我只能改变自己的想法和意志，重塑自己的意识形态。我不喜欢人因为种种被迫和无奈而做出某种选择，我喜欢人因为心悦诚服而做出选择。被迫的选择短期是看到了效果，但不可持续，我更在乎长期的影响。\n我的精神追求主导着我的情感倾向和价值取向，理性分析只能配合着帮我找到尽可能多的正面的支撑因素，弱化一些负面的瓦解因素。这样说显得我太过理想化、虚妄不实，毕竟我不是活在真空中，我是要穿衣吃饭的。实际的决策中，我理性地分析了我的内在需求以及外在因素，找十一个人咨询了该作何选择或者国外的工作和生活的体验如何，做了两次占卜。最终的决策结果，与我一开始的直觉并没有差别，只是多挖掘出几个因素，选择哪个因素在哪个场合怎么讲的问题了。\n我的内在需求，有八点：第一，与直属领导配合融洽；第二，一年回国一次减轻家庭的精神压力；第三，一次至少呆一个月；第四，在西雅图最多呆三年；第五，能力成长持平或好过当下；第六，薪资待遇相比北京高至少一倍；第七，工作强度不高于北京；第八，与平级和下级相处融洽。\n外在因素，有三点：第一，工作机会的自由度；第二，部门的工作目标和产品的市场走势和反馈；第三，地区的生活状况。\n咨询和访谈下来，到西雅图工作与留在北京工作，各点满足的情况如何，我就不展开细说了，列在这里给大家一个方向参考和对照。\n这里说说周易占卜的结果，如今回看，越看越有意思。到西雅图工作，我卜到了遁卦变同人卦。留在北京工作，我卜到了谦卦变巽卦。我是个解卦小白，但如今辅助工具很多，比如AI、名家的解卦意见。不看爻变，只看卦象就很能反映我的处境，跟我内心的感受很接近。\n遁卦是隐避、隐忍、退守的意思，同人卦是与人和同、上下和同的意思。我选择西雅图显然属于双向奔赴了，对方抛出了橄榄枝，我接住了，那就意味着志同道合，所谋一致。隐避和退守应该是基于国内来说的，我的社会关系都在国内，虽然西雅图也有不少认识的人，但远离主体环境的选择，是一种隐避和退守。遁卦一般提示人们处在环境恶劣的时候，要懂得韬光养晦。不过我对国内市场是抱有乐观态度的，虽然时下的就业环境严峻，企业成熟度相较美国还有不小差距。\n按傅佩荣教授的说法，遁卦和谦卦属十大好卦，爻辞不是吉就是利，尤其是谦卦。看到谦卦我很高兴，我的情况在国内市场应该还是有利的，虽然已经接近35周岁，但履历的稳定性好，并且2021年底幸运地得到了一次晋升，发展势头是向上的。当时不太懂巽卦的意思，以为是谦逊的意思。现在回看，巽卦象征风，飘忽不定，但风又意味着进入，所以意思是我会经历一段动荡不安的日子，然后进入新的环境。接下来就说说这个内心动荡不安的经历。\n面对失败的勇气 为什么内心是动荡不安的呢，因为花费的时间比预期长，失败次数也比预期多。\n除了最后的正式录取外，另外两个口头录取，都是借他人的势而得的，我的努力成分并不高。我想每一个追求自己喜好和理想的人，多少都是有受虐倾向的。\n第一个机会是美团应用平台做直播中台开发，第二个机会是AWS中国区做云服务市场的开发。这两个机会都是高级经理介绍的。第一个机会，借了亚马逊和美团直播处境的势。美团一直公开说在向亚马逊学习文化和管理经验。美团一些业务营收受抖音直播的正面冲击，所以也要建立直播的平台来应对。第二个机会，借了领导推荐和亚马逊职级评价体系的势。有这些外部的势做基础，对我的面试表现要求并不算太高。\n这两个机会都发生在去年11月我开始主动寻找机会之前。后面让我有点煎熬的，是前路坎坷不明，退路却还充满诱惑。\n内部Kindle和JP Tech都有意向考虑我，我都在被动回应着。大概就是人被追求时，不那么情愿，但又怕找不到更好选择，而不明确说拒绝的心态。这样的心态很不好，倒不是说对对方不好，而是对自己不好。一方面让自己向前的意志不够坚定，另一方面就是不断的情绪内耗和产生幻想。\n在抵挡诱惑方面，不断明确目标，理性分析逼着自己做判断、下结论是坚定意志的办法。找人倾诉和咨询、进行占卜是缓解内耗和寻找新思路的办法。\n在前路不明方面，要把求职当作完成一个项目，采用类似做产品和科研的方法论，即明确求职目标、调研市场中的职位需求、认清自己需求和能力、规划执行路径、快速试错并及时复盘总结、继续调整路径。成败的关键就在于执行力、洞察力、心态和运气。找工作，实则是换了个形式的工作，也就是没有报酬，自己为自己打工，放到市场中去进行自我检验的一个活动。\n做项目，无非人、钱、事三方面。\n从人的角度看，除了自己外，就是熟人和陌生人。探索新的机会，就是去结交陌生人的。要多去观察、尝试和总结经验。除了亲人，我基本不怎么去打扰其他熟人。这样做的好处，是我和对方都避免了情绪上的消耗，但坏处，是让我变得孤立无援，内心孤寂。因此就随缘去认识陌生人。找工作期间认识的陌生人，基本就是三种，猎头、职业顾问和HR。面试官没有立场去主动问候，除非你有勇气像罗永浩自荐一样，去主动问候俞敏洪。不过也有负责人直接在招聘软件上找人的，我没有遇到比较靠谱的。跟人打招呼方面，我从一开始的畏畏缩缩、有所顾忌，到后来的开门见山，他们的评价体系很功利也很明确，就是毕业学校、最后一家企业的职级和薪酬、要找的方向的经验积累和成绩。\n从钱的角度看，缩短战线就是在节省成本，要留够自己内心感到足够安全的现金，裁员补偿是一块，平日的储蓄也要留好。在社保和公积金方面，也要提前规划好，我的情况比较简单，不用有这方面的顾虑。不过为了医疗还能报销，自己通过网络申请了灵活就业缴纳的方式。如果平日有积累，有额外的小成本投入的“睡后收入”，可以适当加大比重，或者看情况选择多干干，但如果没有，那就还是专心把心思放在找工作这件事情上。如果找工作的事情都搞不定，自己做生意赚钱也基本没戏，找人去创业也大概率是失败。\n最后说事。找工作中，自己不仅要有技术，也要懂产品和管理。管理的对象就是人、钱、事，目标就是要在有限资源内把自己卖个好价钱。产品就是自己，要知道自己作为劳动商品的长处和短处，知道自己的市场价格，知道推销自己的方法，注重产品在市场上的需求点和质量。技术就是挖掘、分析、复盘、总结、写文本、讲故事的能力。\n我擅长技术，但一个人闷头调整简历、准备面试问题、挖掘项目亮点，挺艰难的。一方面不知道调整的方向是不是符合市场需要，另一方面在缺乏目标听众或者读者的情况下也会缺乏做事情的动力。这时候，一定要跟人互动起来，比如HR、猎头或者职业顾问，他们就是市场中最为重要的一线人员。就像我前面说的，把他们当作工作合作伙伴，进入平时的工作状态，就知道该怎么做了。既不能对他们抱太大期待，但也不能没有互动。期待总是要向内的，是对自己的要求。互动比自己闷头做带来了一些随机性，在陷入困境的时候，与人的互动往往能够给自己打开一个新局面。\n互动是深入认识自己，把自己和市场结合起来的关键。认识不够深刻，简历上的内容就不成体系，项目经历是一盘散沙或是同样能力的重复。认识如果一味只看向内，不注意市场上的需要，就只是自我满足，不会有太好的效果。看向内的功夫在平常，到这个时候，反复总结和挖掘项目亮点是面试前非常重要的动作。向外看的功夫就是做减法的功夫，你可能有三四项都还不错的能力，但能力不能凭空说，要落在过去的项目中，要落在招聘需求上，拣关键的写，挑关键的说，剩下的就留到工作中日后去表现。\n互动是给自己带来后续行动的动力来源。互动还是让他们对你留有印象的关键。别怕问他们要一些反馈，比如简历哪里写得不太好，能提供个更加优秀的例子吗等等。询问得体，他们可能会给你暴露更多信息。\n除了讲到这个微观层面的具体行动的方法，还要在宏观层面，对机会的数量和方向有所判断。我读了一些领域的白皮书和行业分析报告，不用花钱，公开的信息足够了解个大概。我最后找到的机会，就是《中国软件技术发展洞察和趋势预测研究报告2023》中提到的处在早期推广技术和准成熟度技术阶段的方向。看看这些行业分析报告和领域白皮书的参与单位，基本就说明这些公司会在这些领域中投入，软件行业的投入重要的就是人员方面的投入。虽然目前企业处于降本增效的阶段，没有了盲目的扩张，但总还有适合自己过去积累的新投入。有些热点投入，如果自己的积累不多，也跟自己无关，当新闻看看就好了。\n我得到上面的一些经验，也是走了一些弯路的，比如尝试竞争力不那么强的方向，技术支持、移动端应用，还有一些不那么靠谱的团队，不符合我职位预期的机会。目前是买方市场，应聘者多，机会少，雇主不仅要挑学历，挑稳定性，挑能力和意愿，还要挑细分领域的知识积累程度，这许多下来，匹配上就比较困难了。\n我最终入职的是阿里云的稳定性架构师，不属于企业中的产研部门，不产生利润，属横向部门，做故障、风险等系统不稳定因素的发现、应急、处理和巡检的。选择这个方向跟我的项目积累有关，我过去经历中50%以上的项目积累都在这块，这些不完全是由我决定的。很幸运阿里云在这块有扩大投入，不过他们是在财年初才审批下来岗位，所以等到4月底才得到这个比较适合的机会。\n如果对方真的在招人，你又很合适，面试的结果反馈往往是很快的，一般都是当天或者隔天通知。反之，如果不那么合适，三天如果没有反馈，就问一下HR，提前做好心理建设和多种结果的应对话语。面试后的每一次失败都是严重的心理打击，那几天情绪会很不好，根本没有心情去总结复盘。如果是这种状况，就要明白，自己需要在这方面有所成长。从根本上说，这是认知的问题，但却又很难在短时间内有所改变，即便短时间内一些道理通了，但还是做不到。办法就是直面情绪的来源，不断明确自己的目标来树立自信，不要把外界变化无常的因素作为评判自己的标准，把情绪当作一个内求改变和提升的信号。我到后期基本隔天就好了，恢复得很快，自己知道哪不合适就不会过度纠结，要承认自己的局限，也要允许别人的局限。社会就是一个巨大的草台班子，但却能满足形形色色人的需求。找对期待，总能看到出路。我意识到自己从小到大在学业和工作其实没有遭遇过太大的挫折，在运气的加持下，结果一直都没有差预期太多。这段经历相比从前遇到的还算个不小的挫折。\n最后还有一点要说，其实有时候没有结果，就是应该休息和放松，这是天赐的良机，千万不要逼自己，最后休息没休息好，拖垮了身体，目标目标没达成，丢掉了信心。说实话，我唯一觉得做得不好的，还是太过焦虑，没有真正放松下来去休息。我在拿到阿里云的口头录取后，有半个月等正式审批结果的时间，但自己还是没心思出去放松放松。\n未来的路 四十岁时是什么状态，我不太清楚，我能把握的是先把当前工作做好。国家也才做五年规划，企业做三年规划，自己没必要给未来放那么多一定要的东西。自己只能提一些愿景，在亚马逊叫做North Star，具体到三年规划要落实到Vision和Blueprint。这段期间，我把人生追求、人生信条和职业技术发展方向都梳理清楚了，算是最大的收获。这使得我能够收缩精力，去长时间专注在选定的特长领域中。\n职业上，我对程序语言设计兴趣浓厚，但国内研究和业界项目都很少，这是个投资成本极高，迭代速度很慢，却非常有趣的领域。这个随缘投入吧。眼下，软件故障诊断，业界在蓬勃发展，与医学的方法论很相似，是我认为国内外实践相对缺乏系统化，难以量化的领域，需求很多，可大可小，跟我的特长也比较贴合的方向。\n面对现实，生存是首要的，理想是次要的。我虽然走上了工商的道路，但商业的兴趣和知识都匮乏，在这个重商的时代，只能边积累边走着看。生存不只要食物做营养，也需要思想做营养，近些年对中国传统文化的兴趣越来越浓厚。\n一个人的精力是有限的，选定了方向，灵活应对就好。管理自己的预期和他人的预期很重要，预期管理实际上就是欲望的管理。少欲知足，无欲则刚，说说容易，做起来就是另一回事了。《金刚经》有说，“过去心不可得，现在心不可得，未来心不可得”。过去已经发生，无力改变，未来还未发生，也不能直接作用到，现在即生即灭，没有可以抓住的东西。人生如梦，活得洒脱点更好。\n","date":"2024-09-16T00:00:00Z","permalink":"/posts/%E6%8D%A2%E5%B7%A5%E4%BD%9C%E5%B0%8F%E8%AE%B0/","title":"换工作小记"},{"content":"临近春节，客流高峰，高铁站出租车乘车点一片乱象。又碰上大雪天，司机们不约而同地坐地起价，无节制拼车。三人挤满不够，一定要行李和乘客把空间都塞满，才作罢。一怒之下，我拉着行李下了车。看见长长的乘客队伍，立刻想起，追求公正是要付出代价的，我不得不花费更多的时间，去寻找代替方案。\n兜底的方案是联系亲戚朋友来接。除非绝境，我这种性格的人，惧怕与人有牵绊。\n剩下方案只有网约车和公交。\n徘徊在出租车和网约车乘车点之间，加一倍价格也没人接单，即刻意识到，这样的形势下，乘客毫无议价能力，除非价钱覆盖了拼四人的，否则网约车司机也觉得亏。一年到头，他们就指着这个形势，大赚一笔，断然没有松口的可能。宁愿候半个小时等下一班列车凑满人，也不愿意少一个人走。\n供不应求的形势下，市场的分配就是如此，能把人安全送到就行，乘客的体验是最不重要的。这种情况下，乘客还追求体验就是矫情。\n公交是唯一的选择了。虽然拥挤还没有座位，但气消了，来不及无奈，就要投入到下一场智斗中了。如何运用技巧从上车口冲破密集的行李和乘客顺利移动到下车口，如何在拥挤的车上找到一块不那么拥挤的地方，如何找到一个位置乘客最有可能提前下车。满是情绪的时候，动用理性是最能让人开心的事情。\n提前判断形势，做好心理预期，接受能接受的，拒绝不能接受的。人的选择，看起来随机，却也都是必然。\n","date":"2024-02-03T00:00:00Z","permalink":"/posts/%E4%B8%80%E6%80%92%E4%B9%8B%E4%B8%8B/","title":"一怒之下"},{"content":"又是一个不眠夜。想自己的爱好、专长和未来发展想了一宿。\n系统软件四大件里，我仍旧对编译器情有独钟。我是透过编译器的视角，来看待操作系统、数据库和网络协议栈的。\n我对此的情有独钟，不单单是因为过去已经花费了很多时间积累知识，有了沉没成本，而更是因为它当中的挑战，一直能引发我的兴趣，去不断地深入挖掘和学习。这条路子看似小众，但不可或缺，实际上也可以跨很多应用领域，而且上限极高。概率统计的方向现在很热，符号与规则的方向被压得快没有了声音，可在现实中却仍旧是主导人们认识和决策的主要体系，概率统计理论本身也是符号规则的。过去一年中，最大的认识改变就是，概率统计的思想与符号规则的思想是彼此相辅相成的，而不是对立的，不是一个更加基础，另一个更加上层的，而是事物的一体两面，否则人们何必要做统计推断呢，又何必要依据公式来算概率呢。新的一年里，我应该在此方向上多迈出些步子，多做些规划。\n职业追求上，以编译理论和实践为主，辅以佛学和传统文化来矫正身心失衡。过去工作中，周围能讨论编译问题的人太少，面试中讲挑战，大多数面试官也是没感觉。编译的理论太多，太抽象，我需要尽快找到实践的路径，取得一些阶段性的成绩，才能找到更多志同道合的人。\n快三十四岁才看清方向，虽然有些晚，但着实让人内心安定许多。经过嵌入式、信息检索、机器学习、网页应用、移动应用漫长十二年的实践学习后，终究还是知道哪些应该放弃，哪些应该选择与坚守，体系结构是让人着迷的，编译是很好的一个切入角度。做应用软件开发，实在不合我的气性，但以这个年龄去融入到一个新的圈子中，还是需要先让我的天份与价值能够被他人看到，而后自然而然地被接纳，而不是像如今一样，盲头苍蝇乱撞。\n实习生/低阶职位、研究生、开源项目是三个不同的路子，我想做开源项目应该更适合这个阶段的我。我已经迫不及待想进行一番规划与实践了。\n","date":"2024-01-01T00:00:00Z","permalink":"/posts/%E6%96%B0%E5%B9%B4%E9%87%8C%E7%9A%84%E9%81%93%E8%B7%AF/","title":"新年的道路"},{"content":" 1. 为什么需要项目总结模板呢？\n功利务实的目的，是为了节省以下两项工作的时间：\n准备每年的年终评审或者述职报告。 准备更换工作或者寻找新的机会。 非功利务虚的目的，为了反思自身在每个项目中的成长，能力的增长和知识的积累。\n2. 做项目总结应当注意什么呢？\n从内容上讲，注意优先级和客观性。优先级取决于项目的重要性，要考虑参与度、影响力、复杂度。客观性取决于可重复性和规模，要从业务、技术、人事角度将客体数量化。\n参与度是三个重要性因素中唯一一个与自身直接相关的，要说清楚自己的角色和成长。\n影响力可以从三方面来考虑：第一，在更大的项目中的位置与作用；第二，客户规模和作用纵深；第三，对项目中其他人的影响，对上级、对下级、对同级，特别是权威缺乏的时候对同级的影响。上级一般与自己共享利益，在同一条战船上，只要对齐目标，自己主动、卖力，一般问题不大。影响下级，需要在专业能力上走在他前面，能帮助他解决具体的问题。影响同级，需要在项目的价值与更大的项目中的作用上思考得更加全面与深入。\n复杂度可以从项目参与的人数、代码量、包的数量、项目时间等角度来考虑。\n从形式上讲，注意拼写、语法、语义、字符样式、空格、缩进等。\n1. 我在项目中的主要职责是什么？\n第一要落在动词上：主导、负责、带领、指导、评审，参与就可以不用写了，而提议、设计、编写、测试等是具体的工作，是展开时要说的。 第二要落在对象上，即人与事，要具体化和量化，人要有数字，事要有范围，说清楚边界与局限。\n2. 我在项目中取得了哪些关键成果？\n围绕攻克的难题与技术挑战，对项目上的事与人产生正面的效果，提升团队的工作效率。 从事上讲，是创新、创意，寻找全新视角、推动僵局。从人上讲，是获得客户的认可、上级的认可、成为团队的放大器。上级不要局限为自己的直属领导，也包括其他与自己合作的级别更高者，级别更高者往往有更高的能力与权力，即便都没有，也还有更多的信息获取渠道。\n描述方法一般遵循STAR法则，情形、任务、行动和结果。\n3. 我在项目中取得那些关键的成果有什么成功的经验可以分享？\n围绕能力，即专业能力与领导力，而不是知识性的结论。知识性的总结功夫应该落在平时，而非项目总结的时候。知识往往很容易在网络和书籍中获得，将个人知识结构化、体系化重点要放在对领域问题的认识上。对领域问题的认识更加深入往往是做项目的副产品，要以具体的例子来说明能力。\n专业能力比方说编码能力、设计能力、践行最佳实践的能力，可以讲方法论。要以专业能力好为论点，用具体的领域知识来举例说明。能力很抽象，需要具体的例子。 领导力就以亚马逊的领导力准则来说即可，比方说沟通能力可以在敢于谏言服从大局方面举例，分析能力和推断能力可以在刨根问底方面举例。\n4. 我在项目中有哪些做得不够好值得提升的方面？\n与前一个问题本质相同，一体两面，也要围绕能力，即专业能力与领导力。不同于前面一个问题，这个问题还可以谈谈打算采取怎样的计划与行动来提升。\n亚马逊领导力准则：\nCustomer Obsession Ownership Invent and Simplify Are Right, A Lot Learn and Be Curious Hire and Develop the Best Insist on the Highest Standards Think Big Bias for Action Frugality Earn Trust Dive Deep Have Backbone; Disagree and Commit Deliver Results 新增的最后两条Strive to be Earth’s Best Employer和Success and Scale Bring Broad Responsibility个人不是很认同值得与前十四条并列，它们不像前十四条一样属于行之有效的简单能力，而是复合能力，故而省去。\n","date":"2023-10-23T00:00:00Z","permalink":"/posts/%E9%A1%B9%E7%9B%AE%E6%80%BB%E7%BB%93%E6%A8%A1%E6%9D%BF/","title":"项目总结模板"},{"content":" 2018年01月02日分享于pFinder邮件组，作为《参加工作以来的成长（一）》的附件。\n高效快速地找到一个复杂系统中问题发生的根本原因，是每个工程师的必修课。当我们面对这样一些问题时，往往不知道复杂系统的全貌和所有细节，这种状况下应该怎么办？对于一个训练有素的工程师，肯定不是头脑发热，不知所措，或者到处去找人询问，而是从有限的问题本身出发，不断地反问自己，如果要找到问题的答案需要知道什么信息，层层地挖掘出更多的相关信息，从而找到问题的症结。这是一个结合深度搜索和广度搜索的技能，并且需要恰到好处的结合，想得太深可能会让自己陷入一个死胡同，关注的太广可能会让自己迷失在太多的细节当中，而忘记了来时的路，和最终要达成的目的。\n前段时间仅花了两天的时间就找到了一个手机应用偷跑流量的根本原因，着实兴奋了一整天。解决了问题是一方面，发现自己在高效地找到一个完全不熟悉的问题发生的根本原因方面有了长进是更重要的另一方面。一直思量着把这个过程记录下来，却不得空，今天总算可以静下心来写写了。\n我被委派的任务是调查一个手机应用偷跑流量的问题，具体来讲，测试人员测试发现公司的安卓手机应用在预装的定制机上，未启动的情况下就已经开始有流量消耗，并且测试人员反映发现偷跑流量时有跟个推（国内的一个推送服务）相关的日志。\n收到任务时，我的情况是，1) 对安卓只有一年的开发经验，而且是断断续续地利用业余时间学习；2) 对安卓的推送机制基本不了解，仅对推送的过程了解一些；3) 对如何预装应用完全不清楚；4) 对公司复杂的手机应用知道一些跟WebView相关的部分，估摸着看过的代码最多也就几千行，而整个应用仅核心两个包的代码就有十几万行，附属提供功能的依赖包至少有一百多个，整个依赖的包有近两千个，整个应用的代码量在百万行甚至上千万行的数量级上，整个应用的完整的构建需要两个多钟头（当然局部的修改不会进行完整的构建）。\n搞清楚问题和清楚自己所处的状况是解决问题的第一步，千万不要盲目。解决复杂系统中的问题，跟做书本上简化了条件的题目不同，但方法论大体还是一致的。从小做数学题时，老生常谈的就是审题，清楚题目的条件和限制。简单题目之所以简单，主要是解题的所有信息完全可以装在大脑中，只需要自己审清题，大多数情况下问题就迎刃而解了。复杂问题的信息是不可能全部装在脑子中的，需要去挖掘和搜索。搞清楚问题是要明确目标，并时刻铭记目标，防止自己走偏。清楚自己所处的状况更重要，这样可以帮助自己找出阶段性的目标，逐渐将原始问题的未知条件转化为已知。\n面对这个具体的任务时我首先问了自己以下的几个问题：\n在定制机上预装的手机应用未启动时，有流量消耗，那么对于非预装的应用呢？ 如果非预装应用没有这样的问题，那么预装的手机应用在未启动之前与非预装应用有什么差别呢？ 对于未启动前的阶段是安装阶段，这个是常识，那么安装阶段安卓平台做了哪些事情呢？ 如果非预装应用也有这样的问题，那么问题也一定出在安装阶段，同样也需要知道问题3的答案。 如果个推在偷跑流量，那么一定得有后台运行的服务被启动，否则谁去打印日志呢？进一步这个服务为什么会在安装阶段被启动？这两个疑问也都指向了问题3。 在清楚问题和我所处的状况下，有正常逻辑的人都不难问出以上的问题。将这些问题用纸（或者云笔记）记录下来极为重要，因为尝试着去回答每个问题时，你还会问出自己更多的问题，更多的问题增加了广度，让自己对问题了解得更多，但同时也很容易丢失目标，不要让自己大脑不停去重复想前面提出的5个问题，大脑会很累。写下来还有个好处是一天没有解决完的问题，第二天可以快速重新捡起来。\n说完写下来的重要性（重要的事情总要说三遍），接下来回头看下提出的5个问题的特点。第一，它们跟原始问题中的几个关键因素直接相关，比如预装、流量消耗、打印日志、个推服务。第二，它们是对原始问题的分解，彼此之间有很强的逻辑关系，这一方面可以让思考变得严密，另一方面也更加具体。第三，它们运用我有限的常识和对比的方法，引入了更多的我熟悉但还没有透彻掌握的因素，比如启动前的步骤只有安装，打印日志一定有后台服务运行。总结下来，提问的时候，首先要寻找原始问题中的关键词，然后结合自己的常识，运用逻辑和对比的方法，引入更多的因素，分解出更多的问题。\n除了将分解的5个问题写到一页纸上以外，还要另外新建5页纸，将5个问题分别作为5页纸的标题，为后续的问题分解、搜索和寻找答案做记录。\n做好准备工作后，可以暂时放下思考原始的问题，转而从第一个问题开始，各个击破。\n第一个问题中，整体是在问，非预装应用在相同的条件下，是否也有流量消耗。可是在解决这个问题前，还有几个问题令我充满困惑：\n如何复现原始的问题？ 提到复现，就需要知道怎么能做一个预装应用？ 预装应用被装在了设备的哪个目录下？ 非预装应用被装在了设备的哪个目录下？ 预装应用有哪些区别于非预装应用的特点？ 如何做非预装应用的对比测试？ 提出这些问题的动机和方法同提出前面5个问题的动机和方法类似，我进行了第二层的深度分解。这一层的问题进一步具体，同样需要用纸记录下来，逐个地回答。同一层级的问题之间有个特点，前面有提到，就是彼此之间有很强的逻辑关系。可能其中的某几个问题还比较抽象，但只要有一个问题足够具体，利用现有的认知做简单的搜索可以得到答案，那么就不必要进一步加深分解的层次，以免节外生枝，消耗不必要的脑力。\n拿上面分解的6个问题来看，问题1和6都比较抽象，剩下的很具体，尝试着回答了2到5，那么会把1和6更佳的具体化，至少在自己的大脑中是如此。相比于3到5，问题2也显得不够具体，所以先回答3到5是个不错的想法。\n回答未知的问题，以前的人们只能翻书，效率很低，现在有搜索引擎，虽然很快，但也需要能有效利用。这就要提到如何增强自己的搜索能力，如何综合利用多个搜索引擎的结果，如何快速定位自己关心问题的答案。回答这几个问题同样可以重复前面采用的方法，进行问题分解，为避免跑题，在此只列举一些我个人的经验。首先，用中文关键词在百度或者Bing中搜索，搜索出来的答案可以辅助拓展关键词，但不可以全用，大多数时候不准确，不全面。其次，准确地将关键词翻译成英文，在Bing或者Google上搜索，高质量的答案一般来自于官方文档、Stackoverflow、Google论坛，博客上面的答案可以用来辅助拓展关键词和充实答案。再有，学会关键词转换，转换关键词的过程其实是转换思考问题角度的过程，在很多山穷水尽的时候，转换思路或许能柳暗花明。还有，启用搜索引擎的高级搜索功能，只找某几个网站的搜索结果，或者要求关键词严格匹配，直接滤除掉低质量的结果，减少干扰。最后，浏览搜索结果，看相关度的时候，要始终想着要解决的问题，以免被带偏。问题越具体，越容易找到相关度高的结果。\n在百度中搜索以下两组关键词：\n安卓 预装应用 安装目录 安卓 应用 安装目录 在Bing上搜索以下三组关键词：\nAndroid preload application installation location Android application installation location Android application installation folder 百度中第一组搜索关键词的头五名：\n怎样知道安卓系统上安装的应用程序其所在文件夹\u0026hellip;_百度知道 安卓手机如何彻底删除预装应用_百度经验 教你怎么把安卓应用软件放到系统根目录system/app下 - 飞\u0026hellip;_博客园 安卓手机安装后的安装包文件怎么找_百度经验 Android应用程序的安装位置 - CSDN博客 百度中第二组搜素关键词的头五名：\n怎样知道安卓系统上安装的应用程序其所在文件夹\u0026hellip;_百度知道 android APK应用安装过程以及默认安装路径 - CSDN博客 Android开发出来的APP在手机的安装路径是? - CSDN博客 安卓软件安装目录在什么位置?-其他软件-ZOL问答堂 各种APP的安装路径在哪? - Sony Xperia Z3/Compact 安\u0026hellip;_机锋论坛 快速的浏览10篇帖子，有些提到/data/app，有些提到/data/data，有些提到/system/app，还有些提到/system/priv-app。各个帖子试图去解决的问题不同，可能不是对我关心问题的正面回答，但不妨碍我将它们作为候选答案和新的搜索关键词。在浏览帖子的过程中，我了解到有人问过安卓手机如何彻底删除预装应用_百度经验，我获得的认识是系统应用可能很难删除。在浏览帖子Android应用程序的安装位置 - CSDN博客时，我发现标题虽然相关，但内容在谈应用如何能放在外部空间，根据过去对存储分级的认识，我可以联想到默认的应用应该放在内部空间中，这时候勾起了我强烈的兴趣去了解安卓系统的存储结构。面对这种情况，如果时间充裕，不妨搜索一下，以满足自己的好奇心，如果时间不允许，最好就此打住，以免花太多的时间在拓展问题上。浏览的所有帖子中，android APK应用安装过程以及默认安装路径 - CSDN博客的质量最高，不妨把这个链接留下，写到自己创建的笔记中。\n综合中文的搜索结果其实已经基本得到了问题3和4的答案，在笔记中做下记录。问题3的答案是/system/app和/system/priv-app，问题4的答案是/data/app。如果觉得这两个问题太小，也可以合并成一个笔记。为进一步确认我们的判断，阅读下英文的搜索结果，发现有人正面回答这个问题，比如下面的几个帖子：\nWhere in the file system are applications installed? where is .apk location for apps that are installed on sdcard? Where does Android app package gets installed on phone 确认得出的结论正确后，还需要到设备上实际操作一下，得到最终的确认。帖子Where does Android app package gets installed on phone中的一个回答者提到了adb shell pm list packages -f这条命令，去执行一下，并且在笔记中做记录。\n问题5相比于问题3和4相对复杂些，复杂性在于要从两个本身就有些复杂的概念中寻找差异。类比地来想，问题3和4分别在问“中国人住在地球的哪里”、“美国人住在地球的哪里”，而问题5却要回答“中国人和美国人有什么差别”。第一类问题具体到了被考察对象（预装应用或者中国人）千百万个属性中的一个。第二类问题却没有框定哪些属性。对于复杂概念的属性，人们往往还会根据复杂概念本身跟外部的依赖关系、用途而对属性进行进一步抽象、分类，以便于容易认知和讨论。拿中国人和美国人来讲，可以讨论的属性没有穷尽，但可讨论的抽象出的类别相对有限，比如生物特征、生活方式、历史习俗、社会结构、思维方式等。实际上简单想想都会觉得，问题5的复杂度肯定比回答中国人和美国人的差别要低得多了，然而后者虽然客观来讲更困难，但在感情上却是容易的。思考它不仅可以辅助拓展问题5的搜索关键词还能够明确我所关心的差别方向。经过这一番类比，我能想到去限定问题5的类别对比范围，我更在乎启动前的差别，至于启动后，暂时可以不必了解，没差别最好。想到这里，我可以写下以下的几组搜索关键词\nDifference normal app preload app Android Difference normal app preload app installation Android Difference normal app system app Android Difference normal app system app before start Android 预装应用 非预装应用 差别 安卓 预装应用 非预装应用 差别 安装 安卓 预装应用 非预装应用 差别 启动前 安卓\n经过在Bing和百度中的搜索，我找到一些相关的答案，很多在谈权限的问题。不过搜索过程中，我同时还发现我的用词不够准确，大家很少叫normal app，而更多用的是user app；preload app也很少用，而更多用的system app。中文中大家更倾向于用普通应用和系统应用。看到系统，我又想起了我在前面找到问题3和4的答案，于是我改进自己的搜索关键词\nDifference user app system app Android Difference user app system app permission Android Difference /data/app /system/app Android 普通应用 系统应用 差别 安卓 普通应用 系统应用 启动前 差别 安卓 /system/app /data/app 差别 安卓\n多次重新搜索（re-search）后，终于找到看起来靠谱的两个答案。第一篇是StackExchange上面，有人问“What are the differences between a system app and user app?”，高票的答案解释清楚了主要是拥有系统权限的不同。这样的答案可以促进自己知识的结构化，却不对解决问题产生直接帮助，因为我还是不知道什么系统权限有差别。跟系统硬件相关的权限有很多，到底由哪个造成。从头到尾读安卓的系统权限相关的文档，或者是拿一个一个的系统权限常量串到代码库中去搜索都不太现实。在我即将准备进一步优化搜索关键词的时候，第二篇CSDN上的一篇博客“System APP 与普通 APP 简析”清晰地为我指明了方向。博客中的第二点不仅说了权限有差别，并且说了是广播的接收权限有差别，系统应用即便用户没有打开应用，也一样可以收到广播消息，而普通应用必须打开应用后才能收到广播消息。\n问题答案找到这里，我虽然只能回答第一个大问题的3个小问题，但是似乎已经距离找到答案很近了。我已经将可能出问题的范围缩小到了广播接收器和权限，外加一个条件就是个推，于是我兴奋地去个推包的AndroidManifest.xml中找所有的广播接收器和权限声明语句。看到以下几行可疑度比较高的语句。\n\u0026lt;uses-permission android:name=\u0026#34;android.permission.RECEIVE_BOOT_COMPLETED\u0026#34; /\u0026gt; \u0026lt;receiver android:name=\u0026#34;.PushReceiver\u0026#34; \u0026gt; \u0026lt;intent-filter\u0026gt; \u0026lt;action android:name=\u0026#34;android.intent.action.BOOT_COMPLETED\u0026#34; /\u0026gt; \u0026lt;action android:name=\u0026#34;android.net.conn.CONNECTIVITY_CHANGE\u0026#34; /\u0026gt; \u0026lt;action android:name=\u0026#34;android.intent.action.USER_PRESENT\u0026#34; /\u0026gt; \u0026lt;!-- 省略 --\u0026gt; \u0026lt;/intent-filter\u0026gt; \u0026lt;/receiver\u0026gt; 权限一行的声明在说，应用在请求启动完成时的某种权限。广播接收器的声明在说，接收器在匹配到以下的三种事件发生的广播情况下能执行一定的任务，包括android.intent.action.BOOT_COMPLETED、android.net.conn.CONNECTIVITY_CHANGE和android.intent.action.USER_PRESENT。这时候，我再去找官方文档阅读印证我的理解是否正确。阅读后发现这三个事件过滤器的确是只针对系统应用才能产生效果的。进一步确信后，我创建一个修复分支，删除这几行代码后，需要验证是否真的就是这几行代码起的作用。对于这个验证，我有两点预期断言（Assertion）：1) 在预装应用中不再出现偷跑流量的问题 2) 对于非预装应用的推送功能并没有因为这几行代码的删除而执行异常。第一个断言属于功能性测试，为了修复不满足需求的漏洞，第二个断言属于回归测试，为了避免修复引入新的问题。\n做功能性的测试我需要先搭建测试环境，如果测试环境搭建好了，我预期基本上问题1, 2, 6的答案也就都有了。在这个问题方面，因为测试，外组有专门的人员负责，对我而言也只是个临时的任务，于是我在尝试搭建测试环境失败后，将任务转给了他。由于他人在美国，我需要明确要他做的事情和预期，在转交任务前，我做的测试尝试包括：\n找问题2的答案， 做初步的回归测试。 回归测试的环境是现成的，我将带着修复的应用装到普通用户应用区域，完整地测试了推送功能和查看错误日志，并无异常发生，所以回归测试在我这里算是过了，后期还需要我们组专门的测试人员进行重复测试。\n找问题2的答案，相比问题5难度要小，不过执行操作比较多，而且存在着损坏硬件的风险。系统区是ROM区，只有ROOT权限才可以读写，并且启动加载的操作系统内核程序也存放在这个区域，因而操作风险较大。我尝试了两三次向一台ROOT过的机器强制覆盖应用都导致整个手机系统重启，并产生了系统崩溃的报告。为了尽快完成修复测试，我将带着修复的应用转给了外组的测试人员，他在五天之后给出了测试结果，平均每天的流量消耗是零。\n问题已解决，有闲暇的时间里，我将剩下的一些问题做了一些简单搜索、思考和整理，以增加我对系统局部模块的认识，就不在这里赘述。\n回顾整个问题解决的过程，积累结构性的知识和特定的领域细节固然重要，但反思和迭代自己解决问题的能力和方法更能让人感到一种成长的愉悦。如果特定领域的知识积累到一定程度，比如对安卓系统非常精通的人，大概看到这样问题的发生，就已经推测出可能出问题的方向，一点都不需要这个复杂的搜索、重新搜索的过程，而是直接去代码中找了。然而，现实中，所有的技术更新迭代的速度超乎我们的想象得快，做到对一切细节都能把握得很清楚是件不可能的事情，这个时候练就快速在大脑中索引和找到细节的能力就显得更加重要。学会反问自己恰当的问题和良好的记录习惯是快速掌握这个技能的核心要素。另外，我想这个技能应该也是精通某项技术不可或缺的能力，换句话说，如果很难以习得这样的能力，基本和精通无缘了。学科领域细分的今天，只有跨领域才能做出点东西，习得这样的能力也只是开始，与此同时，这个技能也是快速介入其它相关领域的好途径。\n","date":"2023-09-28T00:00:00Z","permalink":"/posts/%E8%B0%88%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98%E7%9A%84%E6%96%B9%E6%B3%95%E4%BB%8E%E5%81%B7%E8%B7%91%E6%B5%81%E9%87%8F%E8%B0%88%E8%B5%B7/","title":"谈解决问题的方法：从偷跑流量谈起"},{"content":" 编号 1 2 3 4 5 6 文档类型 提案 报告 手册 跟踪 笔记 模板 英文名称 Proposals Reports Manuals Trackers Notes Templates 编写目的 做决策，确定路线与方案，统一各方的意见，订立盟约。 解决技术难题，找到关键要素，找到大笔开销，清除阻碍，疏通项目各支流，确保工程质量。 辅助客户和开发者完成功能的集成或者开发、调试、测试和发布，保障产品销售，促进长期合作，提高应急响应效率，维护品牌与团队形象，积累领域知识。 避免项目延期，避免花费超出预算，保持团队士气，帮助成员成长，控制成员离职率。 辅助团队成员回忆行动细节，为完成前四类文档（提案、报告、手册、跟踪）与项目本身而服务。 加速前四类文档（提案、报告、手册、跟踪）的编写与自动化，方便多人合作完成一个文档。 常见用途 立项书、计划书（包括项目计划、产品路线、测试计划、变更计划、部署计划等）、合同、草案（包括财务预算、架构设计的草案、规格说明书的草案等）。 花费分析、可行性分析、调查报告、诊断报告、测试报告（或称质量报告）、用户分析、竞品分析、需求分析。 用户手册、标准作业程序（SOP）、开发环境搭建手册、测试用例与执行手册、运维操作手册、常见问题解答（FAQ）、客服渠道手册。 会议邀请日历、任务状态、会议纪要、项目进展通知、公告、调查问卷、周报、月报、业务回顾、职业发展跟踪表、花费记录、成员特长、成员技术偏好、晋升文档。 调研笔记、实验笔记、会议笔记、阅读笔记、测试笔记、访谈笔记、头脑风暴笔记、演示脚本。 所有文档都可以有模板。 文档结构 先阐述问题，再讲述愿景，然后给出提议（包括对蓝图进行描绘以及对提议与备选方案进行对比讨论）。 先描述问题，再说明分析方法（包括环境、参数、策略、工具），然后总结实验结果，最后讨论实验结果，根据得出的结论提出后续行动的有关建议。 先说明文档作用范围，包括目的、目标群体和使用场景，然后列举先决条件，最后是执行的详细步骤，此外还可以附加注意事项与常见问题解答。 表格形式要计划好表格的数量以及想清楚每张表格中的行与列的表头。邮件形式，如果是周期性的，要把收件人、密送、标题、正文做成模板，便于后续重用。至于邮件内容，相对灵活多变，但不变的原则是要想清楚邮件的目的与后续的跟进和回复。 笔记结构灵活，关键是记录的细节，为方便后续查看，适当分节组织和描述信息的来源与服务场景。 模板中通常是两类元素，一类是不变量的字符串，另一类是变量，变量要用特殊字体高亮或者说明需要替换。 亚马逊领导力[1] Invent and Simplify Think Big Have Backbone; Disagree and Commit Success and Scale Bring Broad Responsibility Are Right, A Lot Learn and Be Curious Dive Deep Customer Obsession Bias for Action Earn Trust Deliver Results Hire and Develop the Best Frugality Strive to be Earth’s Best Employer Insist on the Highest Standards Ownership 管理偏向 投资管理 难点管理 质量管理 产品管理 客户管理 流程管理 项目管理 人员管理 资金管理 内容管理 结构管理 偏向的项目阶段[2] 启动/倡议阶段 规划、执行、监控阶段 规划、执行、监控阶段 规划、执行 监控阶段 执行阶段 所有阶段 版本控制[3] 需要 需要 需要 不需要 不需要 需要 归档 需要 需要 需要 需要 看情况 需要 主导角色[4] SDM SDE/PMT SDE/PMT/TPM SDM/TPM 无 无 项目文档管理纲要 [1] 亚马逊领导利准则：https://amazon.jobs/content/en/our-workplace/leadership-principles [2]项目阶段：启动、计划、执行、监控、执行。https://www.atlassian.com/zh/work-management/project-management/phases [3] 版本控制：结构性的调整，修改大版本号。局部内容的变动，修改小版本号。[4] 主导角色：Software Development Manager (SDM), Software Development Engineer (SDE), Product Manager – Technical (PMT), Technical Program Manager (TPM)\n","date":"2023-09-28T00:00:00Z","permalink":"/posts/%E9%A1%B9%E7%9B%AE%E6%96%87%E6%A1%A3%E7%AE%A1%E7%90%86%E7%BA%B2%E8%A6%81/","title":"项目文档管理纲要"},{"content":" 2018年11月25日分享于pFinder邮件组。因迟浩师兄文章Comprehensive identification of peptides in tandem mass spectra using an efficient open search engine发表在Nature Biotechnology，祝贺之余分享了个人的成长。\n不好意思，作为晚辈，我来插个队。\n首先，一样的，先恭喜浩哥的工作成果登上了更大的舞台，有了更大的影响力，特别是未来的影响力。我亲历了这篇成果产生前的头三年，错过了后三年，虽然没有能对文章有些贡献，但作为旁观者，我还是有很多观察和要讲的话的。如果我没记错，这篇文章内容的萌芽，应该溯洄到2013年，浩哥毕业那年，浩哥从头设计pFind的索引结构开始。在我的印象中，毕业前的半年到一年里，浩哥每日会有非常长的时间，独自在15楼上（或是13楼？记忆真是靠不住）做设计、开发、写毕业论文，一天呆在所里的时间应该在12小时左右。后来，2014年pFind集中做新版本开发的时候，浩哥下来同组里的交流逐渐多起来了，特别是发现了杨皓这个好苗子后。软件设计、开发、集成是个浩大的工程，软件能够初步用起来，我想前前后后，应该有一年半时间吧。再后来就是超哥定量论文发表，贺老师读到一篇论文，萌生了用定量的方法去验证定性的准确性，开始在组里做些初步的探索，并且加深了同董老师处的合作。不仅是做湿实验的能同我们提需求、要分析结果，我们也要主动站的更高、看得更广，向他们提需求，用以改善引擎。在我走之前，pFind 3还处在，发现开放式搜索中N15数据意外修饰非数比例高，正分别对错误的鉴定分门别类，寻找原因的阶段。\n我阅读了发表文章的正文部分，短短的三页，信息浓度很高。文章最令我激动的部分，不是鉴定到的肽谱匹配数、肽段数、肽段序列远远地甩开了其它的7个引擎，而是文中清晰的评测方法和评测指标得到了反复地应用。我摘引了其中的四个最精彩的句子如下：\n“Given the design of this dataset, if a PSM identification is estimated to be correct for an unlabeled peptide, the corresponding precursor ions with 15N or 13C labeling should generally be observed in full mass scans and valid quantitation ratios should be obtained.\u0026quot; \u0026ldquo;Generally, a smaller percentage of NaN ratio results indicates higher precision, and precision can be estimated independently of the target-decoy approach via the percentage of NaN ratio results.\u0026rdquo; \u0026ldquo;…, indicating that the PSMs from the extended search space of Open-pFind were also highly credible. Notably, the metabolic labelling technique also helped to identify why spectra are misidentified.\u0026rdquo; \u0026ldquo;A total of 1,259,215 distinct peptides were retained, corresponding to 548,371 distinct peptide sequences, which was ~87.2% more than what was reported originally (~293,000). These indicate that ~10-20% of cysteines in all of the identified peptides were not modified by carbamindomethylation, as would usually be expected.\u0026rdquo; 第一个句子简短地给出了评测方法，第二个句子说明了评测指标该如何看。后面巧妙地将结果分为两步去应用评测方法，第一步是看无修饰和有四个基础修饰的情况，第二步是考虑所有修饰的情况。第三句更进一步，还说出了，对于这样的评测技术，不仅只在于给出鉴定结果的准确性，还能辅助分析为什么被错误鉴定。第四句是对整个引擎所带来价值的说明，另外也能够延伸出需要制定一些评测指标，让湿实验的质量和干实验的质量可以互相监督。\n之所以觉得这四个句子精彩，其实我想强调评测指标对系统演进的重要性，评测指标不应该是系统后期的工作，不应该是写文章时才想到的方面，而是在系统一开始设计的时候就要思考的。评测指标是对目标的清晰定义，目标决定了系统的迭代方向，目标是意义的具象化。还记得贺老师常提，我们做算法，无非就是速度和精度。这两个目标比较抽象，具体写文章和做研究时候，还是需要细分，落到不同的方面。比如我们做一个在线的服务，如果将软件质量对等到精度，软件工程里通常会细分为可用性（Availability）、健壮性（Robustness）、可扩展性（Extensibility）、可伸缩性（Scalability）、安全性（Security）等，速度细化为延迟（Latency）、吞吐能力（Throughput）。举例来讲，可用性，常用百分比来衡量。一般说几个九，比如两个九就是，有99%的时间里，服务都可用，这样一年只准有不到四天的不可用。如果是三个九，那么一年里只准有不到9小时的不可用。像AWS的很多服务的工业标准是四个九，我想城市里送电、送水也是一样的衡量指标吧。再举例来说健壮性和可扩展性，直接去定义不好定义，那么可以有很多辅助的指标，比如降低代码的复杂度，再比如，如今流行的Test Driven的开发，也就是常说的单元测试，有多少的代码行数被覆盖了，有多少的代码分支被覆盖了，还比如集成测试的外部依赖覆盖率，端到端的回归测试的测试用例覆盖率等等。做一个离线的数据分析系统，也要根据系统的功能，将评测的指标（Metric）具体化，并持续改进。\n除了前面提到的四个句子外，还有一句话不得不提，就是速度提升显著的原因：\n\u0026ldquo;It is worth noting that, in Open-pFind, the tag-index technique was essential to increasing the speed of the open search, and the database reduction strategy was essential to increasing the speed of the subsequent restricted search.\u0026rdquo;\n这是浩哥内功最深厚的部分，想必如今浩哥在索引方面的技艺已经炉火纯青了。如何索引和如何搜索的技术是海量的数据分析无法规避的问题，不论哪个领域的数据分析。数据分析一般有两个层次，一层是数据的过滤（Filtering）、分组（Grouping）和聚合（Aggregation），另一层是搜索、提炼（Refinement）和个例分析。第一层是从宏观上看，做些整体的分析；第二层是从微观上看，做些局部的特殊分析，将研究工作落到实处。总之，搜索对未来的重要性不言而喻。有幸头三年从浩哥的毕业论文中学到了索引技术中最为核心的内容，以连续的数组做键，尽可能压缩存储值的部分，当然怎么散列键值，就需要看数据的具体特性了。良好的索引设计总是空间和时间上达到了一个较好的均衡。计算机中加速的核心就是去除冗余计算、减少计算步骤，转换成常用的技术就是加缓存、散列索引、设计压缩表示等。前段时间了解了一些Linux内存管理中内存页管理，核心也是这些，但复杂度却还要高得多。\n以上只是对文章本身和我三年前记忆中的浩哥的一点点看法。站在如今，我也会不自禁产生，贺老师在多年前pLink发表Nature Methods后，杨兵师兄毕业答辩时问的一个问题类似的疑问：如果换一个人，这篇文章还能发表吗？我想这个问题是在问，需要哪些必要的因素，才能够作出一篇影响力足够大的文章。回答这样的问题，需要花费很多笔墨，越抽象的问题，越可以详细分解和论述，有不同的发挥，浩哥想必肯定也会思考类似这样的问题，并且或许也会因为这样的问题而感到压力。\n贺老师给出了这个问题一个必要因素：“念念不忘，必有回响”，这是在说信念。我觉得信念同决心、固执、不服输、持之以恒，都是同源而异流的表达，在《怎样解题》这本书中Polya也特别强调了决心在解题中的重要性。\n我想分享另一个显而易见的必要因素：“人心齐，泰山移”，这是在说愚公精神。团队只有向着一个共同的目标奋进的时候，才能达成显著的成绩。pFind 3有贺老师提出的用标记定量的结果去辅助验证定性的结果的新方法，浩哥强劲的搜索、鉴定能力，超哥pQuant标记定量的最新成果，小龙pParse+对共洗脱母离子高召回率的导出，文锋持续关注统计机器学习方法介绍的半监督学习方法，董老师、丁师兄实验室的标记数据等等。恕我只能就自己所知的方面列举了部分，如有不准确的部分，还请纠正。所有之前的积累和阶段的目标，都为这个大的目标做了铺垫，再想想，这个目标也必将会为下一个目标做铺垫。就我能想到的，找交联位点的问题，pFind 3显然能帮助pLink缩小搜索空间。\n当问到前面的问题后，想必还会继续问，“如何才能缩短创作的周期？”，“如何能做出小而巧的创新？”，“如何影响团队，才能形成良性循环？”。这些问题显得功利，却又是每个创作者所无法回避的想法，我倒不会功利地看待这些问题，思考这些问题，我想可以让人更加发挥自己的特长，节省自己的时间，更加信任他人，时刻考虑如何改善当下低效工作的运作机制，以求通过改善流程，促进运作机制的变革、克服畏难情绪和拖延心理。\n其实相比于技术的收获、方法论的收获，我更感兴趣的是浩哥这一路的心路历程。我总觉得，将头脑中一些不可说或者难以言说的想法和情绪尝试用语言表达出来是一个排解的好方法。语言是思想的一种载体，损耗和变质了多少，难以回答，但我深切地感受到了语言对思想的塑造能力。也许说损耗和变质是个错误的假设，因为损耗和变质是基于我们的思维固执地相信思想有中更加高级的载体和表示形式，而这种高级的载体根本就是虚幻。不过只要对因果律的信念还在，去想解决这样的问题又未尝不可呢。通信技术的下一场革命不知道什么时候会出现，会以什么形式萌生，会跟生物技术的进步有关吗，还是要死磕量子技术。\n我个人的近况 从世俗的角度看，我今年运气很背。工作上，今年做的其中两个项目测试都没赢，公司的股票从九月起也开始不停下滑，个人的收入也跟着受挫。家庭中，父亲突发心脏病去世，个人的精神一个多月来也有点恍恍惚惚。一直记挂着写点什么，却总提不起精神来，大概是因缘不到，悲痛还未彻底消散。\n从修炼心性来看，我变得更加自信、从容和淡定了。\n公司同事都惊讶于我的毅力，能从去年十月开始，每天中午蔬菜沙拉，晚上赛百味，除了偶尔必要的集体活动时跟着变化一下，但我觉得这样的饮食反倒是顺应了我的天性，一方面避免了每天吃饭时的选择困难症，另一方面迎合了内心的一点小信念，拿自己当个试验品，看看饮食结构对人的改变到底如何。\n父亲去世以来，母亲和我都在姐姐的告诫下，开始斋戒，以至四十九天后，都觉得吃素挺好。我本小时候就是被母亲逼着慢慢开始吃肉的，自己对吃并没有多大欲望，改变成素食，并不困难。只是没想到母亲也能完全适应，更没想到姐姐能有这样的告诫。姐姐在年初时说自己顿悟，入了藏传佛教，在家修行，我起初非常忧心。我的忧心无非是抱着唯物、世俗的心态，觉得念经只会占用提升生活技能的时间，也怕她哪天真的出家了。虽是忧心，但我也不会过多劝诫，我怕适得其反，人都总有点逆反心理，想着她自己厌烦了，大概也就停止了，但在经历了这半年多的事情后，我彻底改变了对她学佛的态度，而她也带我走进了一个不一样的世界。这个故事说起来太长，我只会在后面提到些佛学对我思想观念上带来的改变。\n去年随着我开始思考“How to Write Unit Tests”，我逐渐领悟到了如何提问、如何思考，如何顺藤摸瓜地去搜寻资料，快速解决问题。伴随着思考“什么是复杂”，先后阅读了《复杂》、《寻找希格斯粒子》、《混沌与秩序:生物系统的复杂结构》、《人类理解论》，我找到了大部分的工程研究和论文结构方法论的缘起，也就是西方人常说的还原论（Reductionism）。还原论的思想方法不仅对研究探索、解决工程问题有帮助，对理解思维和语言的关系也非常有帮助。我有点沉浸在这样的思想方法当中，开始认为头脑中所有一切的观念都能归结到空间、时间和意识三个方面上，因为所有的存在都依附于这三个方面。人们所拥有的最重要两项底层思考方式，比较和抽象，也都依附于这三个方面。拿“比较”来说，我们所有的感官都能建立起比较的观念，不论是通过视觉、听觉、触觉、味觉还是嗅觉。我们说大小，我想是空间中粒子的分布在视觉上作用的观念，只是伴随抽象观念的增多，大小的引申义也越来越广，比如说国家的大小、软件的大小。我们说光滑和粗糙，我想是空间中粒子分布通过触觉作用后产生的观念，只是我们关联上视觉后，引申到了更多的场景中，比如曲线的光滑和粗糙、平面的光滑和粗糙。能有大小、光滑和粗糙的观念正是建立在比较思维之上的，慢慢地，凭借着抽象思维，我们也有了比较的观念。不论语言中是借助词的变形（He is better）还是副词（他更好），都需要有比较思维才能建立起所有的观念。有了“比较”的观念，我们就能主动去运用比较的思维去分析更加抽象、更加复杂的观念，比如确定和不确定，偶然和必然，再比如东方文化和西方文化，Android系统和iOS系统等等。运用比较，我会思考，脑中产生观念的能力、自然语言的描述能力、数学语言的描述能力、编程语言的描述能力、科学和工程的范围彼此间的大小关系、相互作用等等。从小缺少语言天分的我，开始对词汇学、训诂学、语法学、语义学开始产生强烈的兴趣，走马观花，读了几本。\n从前觉得一些所谓的哲学问题只是文字游戏，但实际上，看到文字游戏只是看到了形式和表象，更进一步地是思想观念的转变，语言只是思想的承载形式。比如说，学习语言时，英语的语言符号、结构跟汉语，特别是古汉语差别巨大，但共性的部分正是体现观念形成最核心的部分。拿动词来说，动词描述了事物之间的关系，自然语言中的动词直接关联的事物最多三个，关联得太多，不只是靠线性的语言、声音的传播困难，短时间理解起来也困难。举例来讲，“他送给我一本书”（“He gave me a book”、“He gave a book to me”），“送”就关联了“他”、“我”、“书”三个事物。我很佩服乔姆斯基能抽取出语言中存在的共性，给编译原理提供理论基石。单就拿动词的这个特性，如果明白了动词在语言中所起的作用，那么我们也自然地在编程的过程中，知道如何给函数命名，不要过多地传递参数这个朴素的最佳实践。再比如说，有名的理发师悖论，“镇子上的一位理发师只给不给自己刮脸的人刮脸”，那么他就将自己放在了能刮脸和不能刮脸之外的一种状态。这是逻辑和语言的困境，我想老子和佛陀是早就明白这个道理的，说到底是理性思维的困境。总有些“道”和“名”，不只是不能道和不能名的，可能都是不能想和不能识的。\n从前学习大学哲学的时候，都是在批判“不是风动、幡动，而是心动“的观点，并且贴上唯心主义，利用人天生的分别心和情感心理来褒此薄彼。不过也恰恰是批判，让人记住了这个观点，在今后的生活体验中能再次体悟这样观点的可贵和完全不同的思想境界。刻意地消灭总是消灭不尽的，最好的办法是完全屏蔽，让其处于无的状态。简单做一个思想实验，如果世上没有人了，那么这个世界是存在的吗，这是个完全没法回答的问题，因为我们所有能回答的，都是要经过观察、感受和思考的。其实不需要学习不确定性原理，单从思考思维和语言的关系，就能想到所有的观念都需要人的感官和思考，而感官和思考的大前提，人们含糊地称其为意识。这样想来，空间和时间又归结到意识上。简单再做一个思想实验，倘若所有的人都是盲人，我们能靠触觉、听觉建立起来前、后、左、右的观念吗，或者说我们还能建立起三维空间的观念吗。我想是无法建立的，即便人们可以靠耳朵和嘴巴交流，身体去触碰。意识是运用逻辑和理性无法逾越的坎，因为逻辑和理性是思考一部分，而思考的前提是有意识，更不必说自然语言、数学语言、编程语言、科学和工程了。也许有人会觉得意识是个虚假的观念，只是物质的生命体复杂到一定程度后自然萌生出的一种状态。这样的想法是可以辩驳的，首先，观念哪有虚假之分，只有能用科学的方法证实和证伪的差别，科学方法本就是有局限性的，说虚，说假，又指的是什么呢；其次，所谓的自然萌生，这显然是不符合还原论的认知范围的，这里面有一加一大于二的论调；再次，还可以问复杂到一定程度到底是怎样的程度，复杂本就是无法定义的，又怎么说程度呢。\n从前以为证据堆积得越多就越可信、越真实，但可信和真实都是有主体的，对谁可信，对谁真实。只要存在谁，那么所谓的可信、真实就会被加工、处理。我曾恍惚间分不清历史和故事的区别，只要是大多数人信的就是历史吗，还是少数权威学者说的是历史呢。那么多的《圣经》故事，卷帙浩繁的佛经，汗牛充栋的史书，为何它们就比上古的神话更让人觉得可信呢，是因为它们更贴近现代人的思维方式、生活常识、社会伦理吗。\n所有的这些运用所谓的理性和逻辑的推演，最终都会引人想到庄周梦蝶的困惑，我们无法说明什么是真实，什么是存在。佛陀说，“一切有为法，如梦幻泡影，如露亦如电，应作如是观”。佛陀对探求类似“我是谁”这样的形而上学的问题不予理睬，只是叫人累生累世修行，直至脱离轮回，圆寂涅槃。\n能明白自己是个凡夫俗子，心中总不会过分苛求自己，也不会苛求别人。王国维将人的苦痛分为“积极的苦痛”和“消极的苦痛”，说“消极的苦痛”是空虚的苦痛，“积极的苦痛”是活动中的苦痛，诸如工作等。我想一些嗜酒、嗜烟的人也无非是拿“积极的苦痛”去换取“消极的苦痛”罢了，本质上同工作狂是一样的。\n能明白自己是个凡夫俗子，也就能更加从容的生活和工作，去思考解决一些自己感兴趣和力所能及的问题。\n祝愿大家能够从容生活和工作。\n","date":"2023-09-27T00:00:00Z","permalink":"/posts/%E7%A5%9D%E8%B4%BA%E8%BF%9F%E6%B5%A9%E5%B8%88%E5%85%84%E6%96%87%E7%AB%A0%E5%8F%91%E8%A1%A8nbt%E7%9A%84%E4%B8%AA%E4%BA%BA%E5%88%86%E4%BA%AB/","title":"参加工作以来的成长（二）"},{"content":" 2018年01月02日分享于pFinder邮件组。\n贺老师，新年好，\n离开研究所快满三年了，感慨时间流逝得越来越快，希望您一切安好。研究生阶段的教育对我的影响无疑是巨大的，尤其是在思维方式的训练方面。我曾不止一次地跟我的经理、同事说过，您是除了我父母、姐姐之外对我影响最大的人，在此对您表示感谢。新年来临之际，也想跟您分享一下我这两年多来的成长，希望您对此还感兴趣。\n我的变化 过去的2017年里我有三个大的变化：第一、我完成了一次职位晋升，第二、我的体重减脂训练下降了15斤，第三、不便公开。\n职位晋升 这次的职位晋升，物质上带来的好处是薪水上涨了55%，外加上前两年的薪水涨幅和公司蒸蒸日上的股票，我的薪水明年预计比入职的头一年翻了一倍。精神上带来的好处是我对自己的信心比研究生毕业的时候增强了更多。不过更重要的是这两年意识到了一种前所未有的感受，感受到年轻、精力充沛、思维活跃的美妙，更美妙的是我还处在其中。\n如果说研究生阶段是我在思维方式方面发生改变和习得的阶段，亚马逊无疑是个好的平台让我习得的思维方式得以实践和巩固。想来这个思维方式包括两个方面，一方面是批判性的独立思维，另一方面是探索性的工程思维。我不知道这两方面我是否掌握到了精髓，因为我相信好的思维方法会孕育出好的成果，而我暂时的成绩还不那么理想，但我能够持续地感受到这两种思维力量对我的塑造和做事方式上的指导和影响。\n批判性的独立思维 具有批判性的独立思维的人，会时常和自己对话，时常地反思自己的过去的行为方式以及思维方式。反思行为方式是在抽取一种行为模式，反思思维方式是在抽取一种快速准确的生成行为模式的模式，或者叫思维模式。反思活动中最为重要的方面是去明确目的和意义，这个目的和意义往往不是为了去迎合某个系统的某个部分或者部分人群，而是最大限度地去符合客观经验和事实。虽然客观经验和事实为什么如此，往往显得难以回答，但想到要去了解客观经验和事实，就会去辅助设计评价体系进行迭代和校准。\n举例来讲，在接受新工具的时候，我从前的行为模式是带着抵触情绪，被迫的从某一个细节开始，这样让我的情绪非常糟糕，虽然事后由于我的坚持和忍耐也往往能够掌握下来，甚至喜欢上新的工具，但这样的接受过程不能让人感到太多过程中的愉悦。当我抽取出我过去的行为模式是过早地将精力投入细节中的时候，我意识到细节很容易将人淹没，我开始尝试着用自顶向下的办法，问自己，为什么要用这个新工具？很多人可能觉得问这个问题这是多余的废话，我找来这个工具当然是为了解决某个问题，但其实很多人往往并没有想明白这个为什么。回答清为什么，其实是在进行问题分解，是在设计工具的接口，是在从用户的角度来考虑系统的功能需求和非功能需求。通过这个思维过程，我调整了自己使用新工具前的行为模式，首先明确自己要用这个工具的什么功能；其次如果我自己来设计这个功能我会怎么考虑，包括接口怎么设计（接口的设主要是确定输入、输出和行为），放在什么位置，等等；最后在我大概想明白后，我去亲自使用，来调整我对新工具的认识和对要解决问题所生成的已有解决方案的认识。这个例子中，我调整了一个具体的行为模式，并且在今后的很多行为活动中都去进行套用和实践，包括使用别人开发的代码库、阅读和尝试了解一个新的领域。\n对于思维方式的反思，我获得了一个生成其它行为模式的模式，也就是意识到了生成行为模式的重要性，而不是去生成一个一个的行为。除此之外，做研究的基本过程是一个很好的思维模式，从了解动机、调研现状，学习别人的工作成果，到抽取假设、提出表示和方法，再到设计流程、运行实例，最后验证、评价和得出结论。这个思维模式看起来呆板、老套，不过能将其运用起来去生成自己的行为模式，必须要有从头到尾走过一遍的经验，否则听再多也没有收获。\n还是拿我前面举的例子来说，我调整自己使用新工具的行为模式也是经历过了类似做研究的思维模式之后得出的结论，虽然没有正式研究那么严谨，但很多的环节起到了重要的作用。比如我开始去阅读一些方法论方面的书籍，譬如波利亚写的《怎样解题》。再比如我会去刻意的在使用一个工具的时候回想我总结出的模式并以此执行，最终的效果往往是可观的。\n我为什么会拿接受新工具来作为例子呢，除去以上的思考外，还因为对于接受新工具的态度和速度很容易将人群分类。一些人有着接受新工具的热情，但没有方法，最终可能无法精通整个工具；一些人抵触接受新工具，而且也没有方法，最终会极大地依赖于已经掌握了的工具，沦为工具的奴隶；还有一些人抵触接受新工具，但有着一定的方法，最终同样会为工具所累，因为切换工具的成本是抵触情绪产生的根本；另外一些人既有接受新工具的热情，又有通用的方法，这样的人才能真正的驾驭工具，并且做出一些成绩。\n我性格里的保守成分偏多，所以没有过第一类人的经历。参加工作以前，我大概属于第二类人，好在我的性格保守，母亲也培养了我良好的学习习惯，即便抵触，只要有用，我还会硬着头皮接受的。参加工作的头两年里，我大概属于第三类人，迫切地想快速地掌握工具，迫切地想迭代自己的行为方法，不过仍旧抵触新的工具。2017年之后，我感到我逐渐转换成了第四类人，可能还不彻底，但确实发生了转变。\n观察周围的同事，很多新人处在第一类和第二类里，一些工作久了的人，会处在第三类中，能升级到第四类的人，我工作的周围我只见过我现在的经理一人。他比我晚加入公司两周，之前同我一起汇报给我之前的经理，他接受掌握公司那些复杂工具的速度至少比我快一年，他最初每天的工作产出基本是我的两倍。从2016年秋天他平级转换成经理以来，组建起了一个二十人的团队，全年基本没休年假，终于感受到了极限，同他的经理商量，又找来一名新的经理协助一同管理。\n我拿接受新工具作为例子，还有一个原因是它总能使我想起前段时间听吴军在《谷歌方法论》节目中提到的做工程的方法。他将做工程的方法用工字型表示，底下的一条线代表工程师掌握的领域基础知识，他称之为基线，上面的线代表领域内科学研究回答的极限，工程师要做的是寻找基线和极限中间的攀爬的绳索，尽可能地接近极限。每个工程师要做的首要事情就是提高自己的基线和清楚极限，阅读书本和论文当然是行之有效的方法，但真正要落实到物理世界中，接受新工具，其实才是真正的提高了基线，特别是那些领域中顶尖的工具。掌握了工具，其实是掌握了工具背后要解决的问题的一种方法，永远不能迷失在工具里带入的花式细节当中，而始终应该记得背后解决的那个问题。实际上如果头脑中有分形的概念，利用类比的方法去看待工具中的花式细节的时候，每一个细节也一定由一个问题而引入，清楚问题往往能系统地知道一大片的细节。\n探索性的工程思维 具有探索性工程思维的人，往往有办法给大部分工程问题一个可行的解决方案。探索不是盲目尝试，而是运用一些思维方法，包括类比、逻辑推理、图形、检验等。令我收获最大的不是增强了某一个单独的思维方式，而是如何开始探索，切入问题，尽可能的在探索过程中运用这些思维方法，以求得到一个可行的解决方案。如何开始探索和切入问题，我总结到的主要是两个方面，一方面，在解决问题的各个阶段都不停反问自己为什么、是什么、怎么做；另一方面，在自顶向下的问题分解不清楚前，不要盲目地去试图找出一个自底向上的高效方法。这两个方面其实听起来不那么新鲜，但对我而言却是一个通用的行为模式。\n对于反问技巧的实践，我写过两篇小文章进行总结，一篇是《谈解决问题的方法：从偷跑流量谈起》，放在了邮件的结尾，因为其中提到一些跟公司相关的私密信息，虽然我尽可能地隐去了敏感信息，但是为保险起见，没有在博客中公开。如果您觉得还不错，可以分享给组里的师弟师妹们，希望对他们有所帮助。另一篇是上半年写的一篇How to Write Unit Tests，已经公开在博客中。这篇方法性差些，不过文章组织的方式比较契合由反问而产生的探索。\n对于自顶向下和自底向上方法的实践，我也有两篇小文章进行总结，都在博客中，一篇是《尾递归的启示》，另一篇是《求数组的子数组之和的最大值》。前一篇更多在谈收获，后一篇是在前一篇完成后的实践，我个人非常喜欢当时的思考过程。在此之前我没有独立想到过如何将O(n^2)的算法优化成O(n)，而且《编程之美》中的优化思路并没有显得像是做数学题一样一环扣一环，而我运用尾递归的方法做到了，对于我个人而言，想起来更容易了，不知道对其他人是不是如此。\n职位晋升的经过 谈了很多思想上的收获，具体回顾职位晋升的过程，也并非十分顺畅，大概用了半年多的时间。公司的技术职位有六个级别，从低到高依次是SDE (Software Development Engineer)、SDE II、SDE III、Principle Engineer、Senior Principle Engineer以及Distinguished Engineer。工程师的比例大致是SDE I和II占90%，SDE III占近10%，Principle和Senior Principle占0.5%，Distinguished似乎是个位数，目前我只知道Java之父是这个职位。SDE到SDE II的晋升一年两次，SDE II到SDE III的晋升一年四次，再往上大概就没有特定的流程了，也不需要，毕竟人很少。\n从2017年初公司的晋升流程做了一次改革，从直属经理驱动，变为了员工自己驱动。经理驱动的方式是由经理提名，然后由经理收集整理材料，在年初和年中的会议中所有的经理当面讨论打分投票，这个过程对员工不太透明，给经理带来的压力也不小。不透明往往会引来一些猜疑和怨气，公司的原则是晋升到下一个级别的条件是已经在按下一个级别的标准在行事，如何定义下一个级别的标准，公司虽然有相关的文档，但主动权还是掌握在经理的手中。\n我的前经理在2016年9月的时候，对我讲，原本预期2017年1月份会在会议上提名我，但后来他转组到了另外的部门，我选择留了下来。他临走前交代给我现在的经理这件事，这其实对我晋升挺不利的，因为我现在的经理也刚由工程师转换成经理的角色，在会议上的话语权预计不是很强。我自己对这个事情的态度，不算那么太努力，但也开始上心了。我在公司的内部网站中搜集所有关于晋升的资料，发现了人力资源部门计划在2017年1月份时候旧流程和新流程一起用，在9月份的时候只接受新流程。于是我学习了新流程后，跟经理大概过了一下，因为他也还不清楚。\n新的流程主要围绕一个文档，完整的过程很复杂，考虑到整个流程是公司机密，我不便细讲。总之，由于我先前的工作中并未留下太多的文档，我额外补写了很多。此外，考虑经理在旧流程中的不利因素，我自己倾向于用新流程。他也建议我用新的流程，理由是即便2017年一月份没通过，至少还能完成几个部分，在后面还可以用。这点也是新流程的另一个优势，员工的晋升，降低了经理变动带来的影响。我的文档是从2017年春节前开始写的，陆续改了18个版本，于7月中旬通过，10月1日生效。\n减脂训练 从参加工作以来，我每年会带母亲出去旅游一次，今年在省内，十一期间，从大同到五台山再到太原，把山西省的主要景点转了转。期间照相发现自己已经胖得不能看了，体重超出62公斤，最明显的是肚子和胸部脂肪很厚，于是痛下决心十一回去开始健身。其实还有很多因素促成我去健身，我想了想，除了前面的导火索以外，还有这些方面：第一，今年出差去西雅图，发现那边在街上跑步的人很多，从前在影视剧中也发现外国人似乎很重视运动和饮食；第二，我的一位好友，在他家附近找了个健身工作室，体重从80公斤减到了70公斤，他有177公分，九月份见了他一次，发现精神状态特别好，给我感觉像是又回到了刚上研究生见他的时候一般；第三，每天工作坐在电脑前的时间太久，时间长了对颈椎和视力都不好；第四，我希望给家里人做个榜样和学习一些经验，健身是一个终身要做的事情，需要年轻时候培养一个好的习惯。\n十一期间，我计划着一周拿出两到三次时间，每次两个小时。十一假期结束回北京后，我立刻找了一个家附近走路5分钟的健身工作室。在家附近的好处是工作日我可以选两个晚上，周末我可以选一天。我兴冲冲地立刻约了一次体验课。课上，教练给我做了身体成分分析、体态分析、关节灵活度评估、拍照存档、饮食建议、针对性的训练计划和休息建议。数据和照片证明我的身体很不好，全身体脂率平均达到26%，肌肉含量偏低，即便BMI指数正常，但照片不会骗人，体态很差，腹部的脂肪很厚、盆骨前倾、肩膀内旋。教练分析得很全面，不过当最后谈到买课的费用时候，我还是犹豫了。带我上体验课的教练是资深教练，每小时收费480。如果一次买30节，平均一次460；如果买50节课，平均一次440。普通教练，每小时380，如果一次买30节，平均一次360；如果买50节课，平均一次340。课是一定要买的，我犹豫的是选普通教练还是资深教练，是买30节，还是50节。最终想了一晚上，觉得这是一件培养习惯，终身受益的事情，买了资深教练的30节课。我不知道选择了普通教练，是否能达到现在的训练效果，不过整个过程我是很享受和满意的，至今也觉得物有所值。\n健身的关键是要自律，首先要保证周期性的饮食、训练和休息。私以为饮食贡献了七成，训练和休息贡献了三成。饮食是控制体重的主要因素，训练是帮助提高心肺功能，改善体态的。\n饮食方面，教练并未给出一个具体的清单说照着这个吃，而是强调少油、少盐、少碳水化合物、多喝水、蔬菜量大。实际上没有太多新鲜的东西。他建议早饭可以通过坚果来补充脂肪，其它的食物中，如果油脂多，需要过一遍清水。我嫌过水麻烦，中午基本吃711的蔬菜沙拉，不加沙拉酱，额外会加一个苹果或者梨，还有玉米。晚饭，基本都是赛百味，面包点全麦，开头一个多月，只吃火鸡胸和香烤牛肉，不加芝士，不加酱料。后来，每天都点特价，训练当天会加一份肉。早饭是我最爱吃的，通常很丰富，包括酸奶、两片烤面包、一把坚果还有一个鸡蛋。每天早上，我会先蒸上鸡蛋，然后开始洗漱。\n一位同事跟着我吃了一周赛百味后放弃了，觉得没有什么味道，但我却发现，我越来越喜欢蔬菜、肉原本的味道，而不是加过重的佐料。\n训练基本是周二晚上8点、周五晚上8点和周日上午11点。一个小时教练带着练习，另外半个小时自己做有氧运动，有爬坡、划船、蹬自行车、跳绳、踢毽球，剩下的半小时放松肌肉做拉伸和洗澡。\n休息教练建议十一点，不要超过十二点，我开头坚持了两个月，后来又推迟到了十二点半，来年在休息上还需要注意。\n实际上减脂到一个月的时候效果就已经非常明显了，同事也都很佩服我的坚持。不过我知道这个根本不是我的目标，并且这样的坚持只是我的另一项日行二十英里的实践，我希望的是能够养成一个独立健身的习惯，当不跟着教练训练的时候，我自己在健身房中也仍旧能够定时、定量，按照自己的能力练习。\n日行二十英里的一些实践 岔开话题到日行二十英里的实践上，其实毕业后我已经体会到了很多次，每天坚持固定时间做一件事情，几个月或者一年以后成效明显。我从前只是学习和工作，并没有感觉到自己明显的提升，但如今我却可以举出好多个例子来。\n我从毕业时候开始每天晚上练字一小时，一天只写两个字，每个字写一页三百次。起初的半年都是没有太多起色的，但一年之后，让我惊讶的是自己的字开始变得好看，并且写字运笔有了感觉。一次在签字的时候，一位陌生人就问我是不是练过字，我点了点头。实际上，照着字帖临，关注每一笔的长短、粗细、位置是一件很耗时间，但却很放松的事情，那段时间每次写字的时候我的心都异常的平静。我还是很疑惑，人对准确性的感知是怎么一步步地就被记忆在了肌肉中的，写好字的过程对我的做事方式和心态有很大的影响。\n再有一件事情是读诗。我特别喜欢《红楼梦》中林黛玉教香菱作诗的情节，黛玉让香菱先读王维，然后再读杜甫和李白，有这三个人的诗做底子，写诗是不会写歪的。于是我去买了王维的诗选，开始一篇篇的背，都说成年人的记忆力会差，不过我感觉我背诗比小时候可快多了。王维擅长五言，是从王维起古诗开始有了意境，他的诗语言不华丽，却画面感极强。不论边塞诗、送别诗、田园诗、隐逸诗，都有着身融自然和心系广川的天然流露。苏轼说他“诗中有画”一点都不假。我自己陆陆续续花了一年多的时间才把一百多首诗记过一遍，不过在我读了近二十首诗后，一段时间里竟每日想着作诗，自认为写得还不赖。目前在读杜甫，因为工作和常常需要额外充电的缘故，杜甫的诗只读了二十多首，诗的纪实成分偏多，跟王维完全是两种性格的人。古人称他们一个是“诗佛”，一个是“诗圣”，都很贴切。\n我还看了贺老师推荐的王鼎钧的《作文四书》也是每天看一点，花不了多少功夫就能读完。读这几本小书最大的感慨就是相见恨晚，书中不仅传达的是写作技巧，更多的是思维技巧。我将这套书推荐给了很多人。\n从十一月份中旬开始，我每天记日记和工作流水。小时候，我是有记日记习惯的，上大学以前基本没有停过，小学时候是我母亲的要求，初中高中时候是学校的要求。上大学开始，我的叙述能力、思辨能力、情感抒发都在增强，每次写起日记来，都很花时间，并且非常的啰嗦，因而也就逐渐从日记改成了周记甚至是月记，没有固定的频率。研究生时期，直接放弃了，更多的写了一些随笔。前段时间，我又重新审视了日记的价值，日记对自己来说不仅是一种成长的记录，还会成为日后做总结、写文章的素材，此外，最为重要的一项价值我会在第三个部分分享。\n审视日记的价值让我意识到日记应该短小而精悍，不应该是随笔式的中长篇。所以十一月份以来，我的日记会用小标题，事一、事二、事三等等来分隔，每一件事，要么是叙述当天发生的一个场景，要么是记述我的一段小的思想感悟，要么是记述我内心的一个想法和计划，都应在几百字内完成。后面附录中，我随意找了三篇作为示例。\n跟工作相关的事情，因为都比较琐碎，我也用相同的方式，在Evernote中，单独创建了一个笔记本，按日期一天一天记录。每天将要干几件事，或者干了几件事，每件事干到了什么程度都是一清二楚。\n用这样的方式记日记和工作流水，让我每天过得非常条理高效和充实。我一般是在上班刚到工位时候，开始做前一天的日记记录，拟定今天的工作流水。这两个习惯，对感受生活的乐趣和提高工作效率，起到了很好的作用。\n减脂训练的后续 回到减脂训练的事情上来，十五次课后，我又做了一次体侧，体脂率从26%降到了19%，体重下降了12斤，胸围从90.5下降到了87，腹围从88.5下降到了80，臀围从94.5下降到了89.5。最明显的变化是，我从前需要买170或者175的衣服，现在都要买165的衣服。测量数据显示我的上肢肌肉含量偏低，照片显示我的盆骨前倾还比较明显，核心和背部较弱。后面和教练商量了一下，又续了三十次课。我想完成这六十次课基本要半年，届时我应该已经系统的了解了训练的模式、技巧和常用动作，并且身体调节到了一个较好的状态。\n如今还没有做第二次体侧，不过我明显感受到体能变得更好了，我的静息心率下降了一些，没有了高血压，做半小时运动不会出虚汗，等等。\n不便公开 ……\n尾记 另外不得不提一下，今年4月份出差去了趟西雅图，约见京芬师姐的那天，她刚好有事情，就让庞斌师兄来跟我见面，中午吃饭聊了一会儿。她跟庞师兄都在亚马逊总部，她在仓储管理的部门，庞师兄在云计算部门。\n最后不得不提的是最近读到的一本好书，梅拉妮·米歇尔写的《复杂》，让我对长久以来一直盲目思考的秩序、随机和混沌的问题以及控制复杂的问题有了系统性的认识。作者将动力学中遇到的确定性的随机问题，热力学中遇到的熵增的问题进而引发信息和计算革命，以及计算机中尝试的自复制自动机的思想，还有目前人们在控制和寻找度量复杂性中做的尝试，做了条理清晰地阐释，阅读起来，爱不释手。复杂性是联系学科之间的纽带，目前所有领域都在面对这样的问题，所以去研究复杂性本身，可能对了解复杂性具有的性质、产生的机理，有更深入的了解，进而，能产生一些通用的方法，应用在各个领域中，改善控制系统中的复杂性。\n我对这方面的知识兴趣度，只增不减，目前还处在阅读大量科普读物的时候，等找到其中感兴趣的问题时候，或许，我会深入地做些研究。\n附录一：日记节选 2017年11月17日 事一\n下载阿里云手机客户端，续费虚拟主机两年，截至2020年1月。域名已续费到2019年12月。\n2017年12月06日 事一\n人都挺恐惧单方面无限期的付出。付出是一种自我驱动的行为，本是一件快乐充实的事情，由思想开始，也终止于思想，但思想闲暇时，感受不到反馈，抑或是感受到的反馈没有符合自我的预期，会让人恐慌和失落。\n收不到反馈，人不知道下一步的行动如何进行，如果永远都是盲目的试探，总觉得永远浮在事物的表面，而人天性中都有对事物深入了解的诉求。\n人们喜欢手机的原因大概是反馈即时可控，人们喜欢宠物的原因大概是反馈无法违逆自己的意愿。人们喜欢孩子，大概在于孩子信息的输入源一开始只有周围的亲人长辈这些小的样本，这些小样本的输入大部分都在家长的控制范围内，偶尔孩子基于本性结合上已知的输入源给家长带来的反馈会成为一种意外和惊喜，然而一旦基于本性结合上未知输入（跃出了家长控制的范围）给家长带来的反馈会成为青春期的叛逆，加剧了他们的恐慌和担忧，但这并不会影响成年人对孩子付出的热情，因为前面的反馈总大于后面的反馈，直到他们成年。\n和成年人相处，人开始变得谨慎起来，需要小心翼翼地试探清楚对方的价值集（价值观集合），计算清楚自己想象对方的价值集，企图让对方的真实价值集和自己想象中对方的价值集重叠的更大。然而，这个过程不一定产生反馈，因为对方的价值集和自己想象中对方的价值集都是站在自己的角度出发的，反馈来自于对方想象自己的价值集和自己想象对方价值集的重叠，这两个虚无的集合发生极大的重合的时候大概就是所谓的心灵感应吧。可悲的是，付出者，能得到对方的价值集、自己想象对方的价值集，却无法得到对方想象自己的价值集。反馈的主动权掌握在接收方手中。成人间的矛盾、冲突大概都来源于反馈的落空吧。\n2017年12月10日 事一\n上周末预约了今天下午一点到一点半的朝阳医院皮肤科专家号，按时赴约，整个流程走得很顺。\n进门，用社保卡在自助取号机上付款取号。专家号100元，医保卡报销40，个人出60。随后拿着号到9层皮肤科刷医院专用医疗卡排号。神奇的是排到的是两年前给我看腿上的那个医生。排队的门口人坐了不少，估计很多是普通门诊，我过去后，只等了一个人，大概也就5分钟的时间。看病差不多5分钟到10分钟。医生会打印出病历，上面包括病人自己的陈述、医生的诊断、以及所使用的药物。额外的单子是使用药物的单子，共四张，两张自己留底，另外两张用于取药。之所以是两张，是因为中药和西药是分开打印的。付费的环节，仍旧需要人工进行，需要给取药单和社保卡。付完钱，会返回取药单和社保卡，外加一张收据单子。收据单子上同时会将挂号的支付情况也一并打印。取药时候仍旧需要排号，这个时候排号主要是为了分配取药窗口。取号使用的是病历上的条形码。最后取药单和号码会被收走。整个看病的过程非常高效，能自动化的环节都已经引入了自动化。\n再来说看病的收获。进门后，直接陈述自己患病多年，偶尔发痒。医生说，掀起衣服看看。看一眼后，说是两种病，一种是X联锁鱼鳞病，另外一种是毛囊炎。前一种是遗传病，病征是褐色的斑点，后一种，就是俗称的青春痘。医生说跟你下巴部位的状况类似，她还额外询问了胸前是否有，看后，没有。此外，她提到人的脸部中线油脂分泌旺盛，可以适量的用香皂清洗。医生一共给开了四种药，一种中药，当归苦参丸，共三盒，早晚各一次，饭后服用。三种外敷的西药，一种尿素乳膏，用于涂抹在褐色处，一天一次，可以在晚上涂。一种夫西地酸乳膏，涂抹在红色处，一天早晨一次。一种维A酸乳膏，涂抹在红色处，一天晚上一次。医生还嘱咐说忌辛辣和油腻，想来这段时间辛辣和油腻跟我是无关了。\n附录二：大四期间的一些文字记录 深夜随笔（2011年05月01日） 突然之间意识到自己对过去的反思大大地超过了对未来的憧憬。我有时很羡慕那些整日里打游戏的人，因为他们至少过的充实，那种整日夜全身心投入对一个人的生活体验来讲是一件再美妙不过的事情了。然而我绝大多数的时间是无法专注于学习编写程序或者学习新的计算机知识；电影、电视剧虽然容易占有我的思维，但看多了也会觉得累，重要的是能找到可以产生共鸣的片子并不多；对于游戏现在早已从中找不到似小时候坐在小霸王前的那种中迷恋的感觉。因而在无他人陪伴的情况下，思考便成为了唯一的选择。然而正如我所忧虑得那样，我似乎不是命运的弄潮儿，没有让自己用那些时间去谋求自己的进财之道，没有去追寻未来的方向，没有去规划自己的人生蓝图；而是一味的在寻思什么原因致使了自己变得如此之平庸，什么原因让自己需要整日担忧更多别人无需伤神的问题。\n年轻的心比衰老的心更容易感到孤独，所以他才更需要找到同伴度过一生。这种对于驱除孤独的渴求占据着青春的多数时间。幸运的是那种看似符合自然规律的渴求可以正大光明的去寻找满足，然而那些备受众人鄙夷的关系却成为偷鸡摸狗的勾当。\n我无奈陷入了无法正当找到寄托而举步维艰的境地，压抑的情绪只好去寻找幻想中的种种美好的可能。\n所以我有些开始担心自己会没有未来，因为年轻的我感觉像是被提前判入了老年的行列中，不为自己的将来打算，而是一味的在思绪过去的种种。当然未来本身也许已经有了定数，但一定不是轻生的那一种。我不会鄙视那种行为，但在相当大的程度上我感到那是体现自己无能的行为。除非你的那种行为不是为了唤起别人的关注或者同情，抑或者是试图惩罚别人，而应该是彻彻底底的醒悟，像最虔诚的佛教徒万念皆抛后在恒河水中去寻找真正的解脱。对我而言大概是不会有这种觉悟的，因此我也只好苟活着，希望时机成熟的时候，让自己能够有喘息的机会。\n多数失眠的人喜欢抱怨失眠，然而所有失眠的人其实都清楚他们失眠的原因，他们也都不愿意告知别人他们失眠的真正原因，他们大概也都羡慕那些贴床就能睡着的人，正像我现在一样。夜静的时候比喧闹的环境更容易让人陷入忧虑与幻想，好在我还能够尽力控制自己的思绪，不过我更希望的是能在借未来可能的喘息机会中得到彻底的失眠的解脱。\n无限度的忍耐（2011年05月04日） 人们常说人的忍耐总是有限度的，但细想来这句话用到单个人的身上却不见得总是正确的，有些忍耐是永没有限度的，因为对于单个人而言他的极限无非也就是他的生命长度。奴隶社会的多数奴隶穷其一生都没有反抗，他们的忍耐达到了极限；封建时代的婚配制度让多数人对自己伴侣的忍耐达到了极限；时至今日这样的例子也不胜枚举，一个高官的妻子可以对她丈夫的拈花惹草睁一只眼闭一只眼，只要这种事情没有影响到她的社会地位，拿掉他的乌纱帽。\n当然对于这些可能会造成个人无极限的忍耐的事情也是因人而异的。有些人生性懦弱也就容易选择没有限度的限度。懦弱往往是以妥协终了，妥协方是自然是懦弱者本人，对于被妥协方在这些事情方面多数是社会中那些掌握着社会的评判标准和道德“真理”的人。无论什么样的懦弱妥协，妥协方总是自己痛苦的，被妥协方是欢快的。然而对待这样的事情，不同于一般的懦弱妥协，此时的妥协方自身不会像普通事情的懦弱妥协那样被被妥协方鄙夷为懦弱，而被认为是明哲保身。这时那些并不懦弱的人无法忍耐这种可能的无期限，便不会妥协，因此便会遭受被妥协方的压迫辱骂，被称之为社会的渣滓、时代的毒瘤。\n不过社会终究是进步的，当初那些被认为深明大义的人最终会被标识为懦夫，而那些当初被称作毒瘤的人也终究会被定义为革命者。随着时间的推移，更多的没有限度的忍耐在人群中越来越少，因为这是多数人追求的方向。不论是懦夫还是“渣滓”都在内心盼望着这没有限度忍耐的消失，人们的内心不愿做更多的忍耐，更不愿自己被称作懦夫。\n宿命（2011年05月09日） 最近这样一个想法常常在脑袋里徘徊，那就是我发现一个人的人生轨迹是一个线性结构。这个特性取决于时间的单向性和空间的唯一性（至少在目前的科学水平认知能力下是如此）。虫洞的制造变得没有可能，因此回到过去也就成为人们最为憧憬而又遗憾的梦想；并行空间的存在激起了人们心底美丽的幻想，这虽不似虫洞那般在挑战自然界的因果逻辑，但对连地震都无法准确预知的人们来说无疑实践起来要比制造时间机器困难的多。\n有了这些基本的认知，说人生是一个线性结构大概也就没有什么可辩驳的了。有趣的是这个线性结构在思想方面时时会产生分叉，但最终无疑又合并为一条路径。因此未知、各种可能的命运也就出现在了每一个人的头脑中。然而命运终究还是线性的，于是有人开始相信宿命，他们相信人生的轨迹是有定数的，当你的思想出现分叉的时候你就会选择某一条道路，而不是其它的。这是有人反驳说始终选择与命运结果始终不同的道路，但无奈你终究要做出选择。这个选择好比在玩石头、剪子、布时，在双方平局后你对对手的预判，他跟你玩的是预想一次应对还是预想两次还是三次。对个时候无论你的脑子多么灵活，如果对方不存在智力障碍，得到好的结果也只是运气，而非聪明才智或是先知。\n说到先知，很讽刺的事情是似乎所有的先知都没有起到他身为先知的真正作用，他永远都不会去阻止事物像坏的方面发展，不过在我看来先知本身的存在就是个矛盾体，因为同前面两种选择一样，它会让事情变为永无休止的死循环而无法向前发展，进而违背了时间的单向性，因此他们也只好出现在影视剧或者传说之中了。\n所有这些问题产生的本质原因就在于它的结果已预先知道只能唯一，所以我向来是相信宿命的。但人生中无数的抉择却又不同于在玩石头、剪子、布那样，靠的完全是运气。要取得一个满意的结果，它们需要你的才智、勤奋、胆识和谨慎，当然还需要那么一点运气。所以相信宿命，不等于自暴自弃，不同于狂妄自大，也不是一味的倾其家产购买彩票。\n我向来害怕做选择题，因为一旦遇到那种含糊不清、模棱两可的选项便令我痛苦不堪，远不如简答题来的爽快。因而在人生的抉择面前，我总是慌乱了手脚。我自诩为算得上是个勤奋的人，分外谨慎的人，才智也还勉勉强强说的过去的人，但稀缺的胆识却成为造成我慌乱不堪的重要原因，这也使得我在抉择时内心的煎熬比平常水平要长更多，我也往往归咎于我的优柔寡断。今后应该多多注意这个方面的不足，尽力去弥补。\n啰嗦了这么多，其实一句古谚就足以道明其中的真谛：谋事在人，成事在天。英语中或称，Man proposes, God disposes. 不知是中国人翻译外国人的，还是外国人引借中国人的，但我到更愿相信，他们彼此都未引借。对于有着高度文明的民族，一些认识不谋而合应该是件很正常的事吧。\n早晨与夜晚，忙碌与闲散（2011年05月18日） 一天中最爱的是早晨，无论是阳光明媚还是阴雨笼罩，心中总是无比的舒畅，整个人也是精神满满。看见枯萎的盆景在经历一个月的无人照看后奇迹般地抽出嫩绿的枝牙，心中充满着活力和希望。无论是坐在电脑前还是在图书馆阅览室里，总是期待着一天会有丰富的收获。当期盼的事情意外地发生时，激动的情绪会一时难以自抑。总之早晨能带来太多的美好。\n夜幕的降临容易带给人带来恐惧、孤寂和压抑。傍晚的夕阳斜射在脏乱的房间里令人感到烦躁。闷热多日后的一场晚间小雨反而让人焦躁万分。洗手时无意间瞥见盆景中那枯萎的果实，再联想到它曾经的嫩绿、鲜红，不由得担忧起多年后的自己和身边的人。拥有网络的夜晚除了坐在电脑前也再找不到更有乐趣的事情，好在熄灯后终于有借口得到无电脑的解脱。无奈躺下后却发现又是一个难以入眠的夜晚。\n忙于一些事情时总是期盼着片刻的休息，同时又总计划着闲散时要做的事。然而在真正闲散时，却喜欢胡思乱想，压抑、沉闷、烦躁和忧虑顿时都涌上心头。叹今生在世能有几多愁，恰似一江春水向东流。\n","date":"2023-09-27T00:00:00Z","permalink":"/posts/%E5%8F%82%E5%8A%A0%E5%B7%A5%E4%BD%9C%E4%BB%A5%E6%9D%A5%E7%9A%84%E6%88%90%E9%95%BF%E4%B8%80/","title":"参加工作以来的成长（一）"},{"content":" 2020年02月02日分享于pFinder邮件组。\n谢谢贺老师挂念，与人分享能帮我缓解愁绪，带来喜悦和能量。去年发生的事情很多，就拣年初时母亲出走的那次经历做个分享吧。\n去年上半年，我的人生中卷起了惊涛骇浪，直到今天还是余波未平。\n春节假期快要结束的一天，房子临近租期，我跟姐姐张罗着换个大点的房子，好让三个人住着不太拥挤。原本计划着跟妈妈一起，但她那天魂不守舍、乖张暴躁，总站在阳台呆呆地向外看，我们以为她只是脾气不好，还在为昨晚的事情恼怒，也就没太在意。上大学以来，我跟姐姐都已经习惯了漂泊在外、居无定所的感觉，也遵守和践行着现代人所崇尚的契约精神，并不觉得房东来家里商谈退租事宜时，拿个卷尺在家里量各处的尺寸是多大的事情，更不会在意与来家里修电路的电工多攀谈几句会招来什么灾祸，可妈妈对这样的行为却表现出了强烈的不满，她感受到了冒犯和不被理解，于是对我俩恶语训斥，这难免招致我俩升高语调、加快语速与她辩驳。不用说，读了多年书外加几年的涉世经历，德慧有没有增长不知道，对自己才智倒是足够自信，丝毫不愧疚于所逞口舌之快。\n我跟姐姐找了一上午也没找到合适的地方，中午回家时，沮丧之余还被妈妈反锁在了门外，敲了十多分钟才进了家门。问她不开门的原因，也不说。这时候其实已是一次征兆，但爱心被焦虑和自大遮蔽，感受不到这是一种异常信号。下午再次外出回家时，同样的征兆，又一次被忽视，从而酿成了之后的灾祸。妈妈开门后，迅速往楼下跑，我从小很黏她，下意识地跟着她下去，却被她骂了回来，心中想着她或许是想一个人去公园散步吧，因为在我和姐姐每日上班长达十个钟头里，她时常到公园散步排解烦闷，于是下意识地说服了自己。可等回过神来，感觉却是无来由的惶恐不安。事后想来这惶恐不安除了两次敲门时的反常信号，还有她出门的时间不似往常，已近黄昏，再有就是她对我跟随时的态度比任何时候都要暴怒。\n我迅速跑去公园、超市、水果摊，所有我带她去过的地方找了两三遍，毫无收获。接下来的四天格外煎熬，茶不思，饭不想，夜难寐，悲伤之余，还要竭尽理智，想一切办法。\n我们发觉妈妈没有带手机，也不清楚她出门时穿的衣服，只记得背了个包，身上应该有一千多的现金，身份证在包里。\n出走的当天夜里也不好惊动亲戚和朋友，只能自己东奔西跑，缓解焦虑。第二天开始到派出所报案，结果被告知无法立案。派出所立案需要证明丢失人要么低龄，要么有人身危险。派出所立案应该能够调动较多的警力和资源，但像我们遇到的情况很难立案。一般成年有自理能力的人，就是存档留个事件也在48小时以上。跟派出所的民警沟通前后其实也就是几句话，但只要站到他们的立场上，也很快能明白他们的难处。他们的工作方式跟普通上班族其实也没有太大区别，围绕的都是人（分队）、项目（案件）和技术，管理上是资源、授权和行动。案件和事件能调动的警力和资源不同。事件最多能根据身份证查查内部的网络系统，没有查询街道视频监控系统的权限；案件的话需要分队上报上级，排优先级，然后自上到下的调配资源（包括警力和特定的授权）。我如果是个民警，大概也不会觉得这个事件足够立案，毕竟事件的影响力微乎其微。立案的都属于刑事案件。\n民警是不会说出事件影响力这样的词汇的，这样的词汇只能在制定规则和学术系统中使用，在实际案件中，一则对事件家属心理上是种打击，另一则与民警的职责相悖。回到学理上，即便我没学过刑侦学，只要我有基础的理智和同理心，也能明白事件初期其实很难确定一个事件的影响力。\n我不知道其他人在想到这个层面的时候，之后会产生哪些想法。扩大事件的影响力，很显然的手段就是靠媒体，迅速扩散消息。可我会有两个顾及，其一，知道的人越多，对事情的解决未必越好，因为也担心有用心险恶的人；真正决定事件影响力的主要因素并不是知道这个事件的人数的多寡，而是民警所说的是否有人身危险。我还会想象出这时一些家属的可能行为，要么纠缠民警，哭闹；或者埋怨民警甚至引发仇恨，散布言论说民警不作为。这些想象出的行为在我的脑子里并不是简单的停留，而是确实觉察到，并且仔细思量，认为没有任何正面的价值，还可能造成事件的恶化。若让负面情绪控制了心智甚至是采取了行动的话，会实实在在的有损道德。结果大概率是真正的症结找不到，目标也达不成，还给自己带来更严重的负面情绪，甚至遮挡了自己对环境的真实感知力。\n派出所只是一天跑一次，跑多了也没价值。能做的不外乎，了解一些派出所内部规定，跟民警熟悉熟悉，留些个人信息和联系方式。\n回到家坐不住，电话联系老家表哥，托他到家乡车站看看她是不是坐着车回去了，也不敢随便惊动妈妈的兄弟姐妹，毕竟他们都上了年纪，告诉他们只能干着急，帮不了太多忙。除了打电话，另外能做的就是到附近她常到的地方去一遍遍检查，再有就是大观园、植物园，我带她去过的地方，指望着能够幸运地碰到。可一次一次的期望落空后，内心就更加清楚什么是人海茫茫，什么是缘分。用精确的语言说是对几公里还有几千万分之一有了更深切的体悟。人与人的相遇和陪伴可远低于这样概率。说到这里，插句题外话，我近几个月面试人，总爱问大数加法的问题，我问他们对大数应用的了解，知道的人很少。问周围人对于宇宙中粒子的总数量级的了解，包括量级本身和估计方法，知道的人数是零。人们对这些别的领域，但在我看来却是关乎一个人价值观建立的问题，不是太关心。\n老家也没什么消息，我还能做的就是挨个查看周围的视频监控，至少能增加些信息，知道她出走时穿的衣服和离开的方向。银行营业点和社区的视频监控都是受严格管控的，没有派出所的民警亲自到访，是不给查看的。街道的视频监控都不知道是什么单位在管理，我唯一能做的就是问周围民营商铺的私人监控。两天下来也就只看了两家，只有一家有收获。收获便是我后来在朋友圈和媒体上公开的那张照片。获得的信息仅仅是她出走时穿的衣着。至于她朝着哪个方向离开，有没有乘坐出租车或是地铁，一无所获。一个监控摄像头的覆盖范围非常有限。此外，我能想到的还有附近地铁站的视频监控，但也同样是无权查看，并且地铁站的入口众多，时间范围估计也只能缩小在两个小时，精确到十分钟，即便能看，也不是一个小的工作量。\n雨水期间的北京夜里很冷，警察没有查到妈妈的住宿记录，她在北京人生地不熟，并且她的信息获取能力很差，我不仅担忧她的安全，也很担忧她的温饱。我跟姐姐商量着要等到民警登记了再公开从朋友圈寻求帮助，想着至少一些片警能在巡逻的时候有所留意，以增加人身安全。恐惧心理让我无法去信任扩散信息后带来的是喜还是患。最终两天后，我们在各自的朋友圈发布了信息。为了方便大家转发，我把所有的文字和内容都放在了一张图中。之后，许多朋友都纷纷转发，很多热心的朋友私信我帮着出谋划策，虽然情绪低落，但也备受鼓舞。其中最令我感动的是一位素不相识的同事，经我经理介绍，因为住得离我较近，给了很多关怀和好的建议。她不仅帮着把消息转发到她们的社区微信群中，还主动提出愿意借车带我在夜里绕街扫视。我一方面因为陌生不愿接受她太多恩惠，另一方面自己那个时候的悲观情绪很重，并不认为这样的方法会很有效。可后来跟姐姐聊了这个提议后，我开始有些动摇，觉得至少要试试。她的分析是夜里能留人的地方除了宾馆、网吧，再有就是车站、肯德基和麦当劳。如果人是在街边，凌晨人少，也很容易看见。\n我联系了一个要好的朋友，请他帮忙。我们起初绕着非环路走，遇到一个营业的便利店就进门问一下。店员们都是些漂泊在外的年轻人，听了后大部分人很乐意转发到他们的工作群里，但也有有所顾及的，我也表示理解。从朝阳开到海淀，并没有让人看到希望，北京城街道众多，即便不重不漏地走一遍，走走停停，也不知道要几天，何况还可能恰好擦身而过。无法缩小她活动的范围，我们最后能做的也只是在北半城过了一遍肯德基和麦当劳。令人欢欣的是里面无家可归的人很多，妈妈可能在其中；可令人悲伤的是这些人大都衣衫不整，酣睡时气味刺鼻。他们迷茫和落魄于这人世间，没有太多人在意，更别说关怀，好在这些快餐店还能容得下他们。一晚上下来，我担忧朋友身体扛不住，觉得该看的都看到了之后，就嘱咐他回去了。\n如朋友所说消息在朋友圈中的二度转发率往往不高，可是消息在小城中的扩散速度却很快。妈妈的兄弟姐妹很快打来电话询问，甚至爸爸的兄弟姐妹、朋友和远方亲戚也都陆陆续续打电话来确认消息的真实性。不管是真正关心也好，看热闹也罢，我都尽力回复。二姨和小舅在家里坐不住，连夜坐火车跑来帮忙。他们的到来给我带来了更多的温暖，那时我的期待已经跌落至谷底，我甚至开始感到我丢掉了妈妈在身边的信号，这种信号不是物理上的信号，而是家人之间那种牵绊的信号，我感觉上天是故意把她藏了起来，在考验我。也是这时，我悟到了这个事情能有转机的四个关键要素：第一，我跟姐姐期待她回来的愿力；第二，妈妈还想回来的愿力；第三，公安系统的责任心；第四，社交媒体的爱心。这四个要素中，前两个至关重要，三四是辅助的。这几个要素虽然听起来显而易见，但人在慌乱的情绪中，很容易丢掉。我无法知道要素二如何，我更是相信没有人能控制要素三和四，我唯一能做的只有坚定信念，保有我的愿力，期待妈妈还能保有一丝感应，信任公安系统和社交媒体。个人的肢体力量和智力在庞大的系统和广袤的复杂面前都不值一提，可人的信念和愿力虽无法度量，却可以集中和坚定。事情的发展自有内在的规律，我们能做的只有努力促成事情发展的因缘，任何人都无法控制事情发展本身。\n伴随着一年多来的成长经历，我对姐姐寻求佛学院的师兄们帮忙诵经回向的态度也渐渐改变了态度。从起初的不认同的沉默慢慢转变为了中立的沉默，到今天我大概是认同了。我想起初的不认同，源自于从小所受的教育和社会中的负面信息。其实只需要简单动一动心智就能感受到这是件出发点没有坏处的事情，出发点没有坏处很重要。\n事情的转机发生在第四天上午，我接到了家附近民警的电话，说天安门附近的片警找到了她。那几天恰逢两会期间，天安门地下通道的戒备加强，进入人群要检查身份证。公安系统里，妈妈的身份证在存档时候被监控了起来。听到消息后，喜悦的心情溢于言表，我镇定下来，联系上姐姐后，一起赶往天安门附近的派出所。民警在简单问询和登记后，引我们见到了妈妈。见到她时，她披散着头发，手中只提了个塑料袋，里面装了一瓶矿泉水，脖子上的佛像不见了，肩上挎的包也不见了，谢天谢地，身份证还在身上。那天她不愿跟我们走，民警只问她我们是不是她的子女，她回答是，民警便帮着劝阻。我跟姐姐没有太多过问她这几日是在哪里度过的，即便我后来问她时，她也不愿多说，只说她开始在车站呆着，包和佛像都被人拿走了。她是梦里梦到姐姐说让她到天安门，才过来的。\n那天下午，单独感谢了私信我的人后，第二天我在朋友圈写下“妈妈昨天上午10点多被民警在天安门附近发现，人现在很好。一家人遭受这次劫难，多亏民警、媒体还有各位亲朋好友的鼎力相助，才得以平安度过，浴火重生。祝愿各位能始终保有真情、真爱，单有理不足以让人生起实信，有实信才能稳住生的希望，保有乐观的态度。”\n到今日，回望那几日的经历，我自认为这段经历后的收获总结是到位的。\n听完我的故事，最后来分享个读书方法吧。孔子“十有五而志于学，三十而立”，我今年要满三十岁了，我感到我已逐渐找到了做人该有的立场。\n近几个月来，我开始找来六本不同注解的《论语》（包括英文的），每天读三则，自乐于孔门师徒待人接物的态度以及后人在其之上的发挥。这个读书方法我是从樊登那里学来的，很有趣，推荐给大家。曾经我感受到的教育观念是革命式的，不推倒旧的就没法建立新的，于是信现代医学就要把传统医学踩在脚下，信科学要把神话、宗教信仰视作愚昧，信民主和自由就要批判儒家伦理作落后的封建思想，否则怎么做时代的先锋和弄潮儿。可“旧的”真的被推倒了吗，“新的”就真的新吗。当真正放下傲慢，正心正信去读经典的时候，却发现经典从来都不曾被推倒，被推倒的只是在邪心与邪信下滋生的邪念与邪见，在傲慢与自大下蔓延的恶语与暴力，在懒惰与自弃下引诱出的欺凌与压迫。革命饱含着激情和热血，却也满是伤口和剧痛。纵有历史千万年，也仍旧可以一叶障目，结果是好了伤疤忘了痛。\n望共勉！\n","date":"2023-09-27T00:00:00Z","permalink":"/posts/%E5%A6%88%E5%A6%88%E7%9A%84%E5%87%BA%E8%B5%B0/","title":"妈妈的出走"},{"content":" 2022年10月23日分享于pFinder邮件组。pFind团队成立20周年之际，读了贺老师的分享，有感而发。\n祝贺pFind团队成立20周年，创立以来国内外影响力稳步上升，祝愿今后能发展更好，取得更好的突破。\n人一生的20年，大约一个手掰指头能数得过来，读了贺老师的回顾与展望，钦佩之余，也颇多感慨，感慨创业之艰、发展之难，也感慨健康不易、人生短促。\n最近一年来表达欲很低，也许是刺激表达欲的某种神经递质在工作中都耗尽了，也许是疫情独居三年满足于观察自己杂乱的念头，再也许是逐渐接受了人命天定多说无益之类的说法。不过该说话的时候还是得说。\n情比理重，求名求利之上，是为了中国人民的健康，甚至未来人类的健康。这样的大话日常不能宣之于口，大概只适合政治场合，可若没有这样的想法，眼界不会开阔，研究动力会不足，但空有这样的想法，没有根基，一腔热血，抛洒无益。根基的深浅把人从梦幻拽回现实，于是还是要自私一些，要先顾好自己的健康，稳固自己的根基，自己的健康是人民健康和人类健康的一份，而稳固的根基可为健康护航。\n健康的目标是幸福，是自由，是从痛苦中解脱。幸福于每一个人是具体的，或求没有疾病、家人身体健康，或求亲密关系稳固、知心话儿有人听，或求社会关系和谐、不缺财富、不缺声望。幸福于一个群体却是抽象的。不管怎样的政治理念、心理模型都是固化的，能构建一个时代一群人的幸福观，却无法顾及每一个人的幸福感，无法阻挡事物自然发展中的腐败与衰变，即便有灵活的理念与模型，却不能载于文字，载于机器，人能弘道，非道弘人。抽象与具体之间的鸿沟是人，是人的精神，是人的实践。\n幸福于一个群体还是矛盾的。于福，有人幸，有人不幸，人人皆幸，必会有别的群体不幸，天道如此，不仅道家如此说，古希腊先哲也这样看。身处幸福的人，反感说教，可脱缰的欲望却侵害他人的幸福。人们厌恶独裁与寡头，可偏执的自由却葬送他人的幸福。他人今天的不幸，昭示着我们明天的不幸吗？求权弃经，逻辑推理，自然是毫无关系。\n福可以计量吗？调查访谈，抽样统计，可以做得很科学，但于个体和群体增强幸福感有益吗，或许对于治理群体幸福的寡淡与不均是有益的吧，可对个体呢。政府救助，精准赐福？充分调动起个体寻找幸福的动力同时还要培养能力？可福是求来的吗？福是一种庆幸的遭遇。福总是短暂易变的，依托形势与机会生灭，所以称之为幸。福求不得，需要养，要遵从事情发展的自然规律，人心的变化规律。为他人造得福之势，即是在为自己造得福之势。《论语》在讲这个道理，说“己所不欲，勿施于人”，又说“己欲立而立人，己欲达而达人”。《诗经》讲这个道理讲得朴素直观，说“投我以木桃，报之以琼瑶，匪报也，永以为好也”。《金刚经》也讲布施的道理，讲得更细更深，说以满恒河沙等的宝石与身命布施不及法布施。\n福祸相依，这样的幸福是相对的幸福。人们所求的健康与自由，也都是相对的。死不知何期，丧不知何地，不知因何而亡，不知亡后何去。人是无知的。人因无知而可以求得知识，但却得不到绝对的幸福，得不到绝对的健康与自由。若我们对生命的认识是建立在别的生命的痛苦之上，我难以相信这样的认识下获得的知识是真理，能够让人得到绝对的幸福。\n精神的健康是首要的，没有精神健康的人，只是一具行尸走肉，一架行走的机器，还可能是混迹人群的妖魔鬼怪。\n精神的健康是向善的，并且首先是善待自己，减轻自己的痛苦。自己痛苦不减轻，传递带给他人的也只会是痛苦，往往首先承受的是家人，其次是朋友、同事与合作伙伴。自己的痛苦减轻后，推己及人，才可能帮助别人减轻痛苦。\n内观，察觉自己的痛苦，向自己坦诚，如实地描述自己的焦虑、抑郁、恐慌与不安。不管苦是一种电信号还是化学信号，抑或是魔鬼缠身，它至少都是一种征兆，可解读成为一种保护信号，让我们改变自己的行为，调整自己的观念，完善我们的意识形态，甚至颠覆我们的信仰。\n求诸己，查找和描述自己痛苦的原因，自己的痛苦莫怪他人与教条，莫怪情势不如意。和平年代的人不用太过忧心杀戮、流离失所与食不果腹。绝大多数的痛苦，都是求不得的痛苦，追求一种虚妄，根基不实的状态。看不清眼前的情势，是自己的德行问题，看清形势却无能为力，是自己的能力问题。\n德行是柔软的，普遍的，一尘不染、无所不在、却不可计量的。《易经》讲厚德载物是大地的品格，不偏私，对于污垢与垃圾也默默承载。人天然的是一个垃圾源，精神的垃圾和物质的垃圾每天都在不停排放，对自己排放的垃圾，多少还是要有些羞耻心与责任心。有身体系统与社会系统帮我们承担了物质垃圾的清理，才留得下我们需要的营养、整洁与秩序。精神垃圾的清理却是他人爱莫能助的，须得自己亲力亲为。少对别人道德审判，道德是用来审判自己的，观察自己的恶念、恶语和恶行，及时止恶。\n要认清能力，认清能力与道德的关系，能力不足，强迫要求德道，只会造成伪善与伪君子。诚也是对己的，不是做给人看的。守该守的戒，守不住的戒，就不要抱有侥幸心理，该承担后果的时候逃不掉。德行可以滋生能力，而能力可以保护德行。\n要认清能力，能力是坚硬的，分类型的，抗侵染、有边界、可测量的。首先要认清自己不是无所不能的，即便有点天分，也要知道能力本身就是分类型有边界的。强迫自己，轻则是焦虑、抑郁，重则是轻蔑、妒忌、傲慢。《易经》讲自强不息是天的品格，昼夜交替，永不停歇。天是不懈怠的，但天也是有节制的。即便太阳，为地上的万物提供源源不断的光与热，也都有燃料耗尽的一天。电能带给现代人存储后的光与热，但不会因此就蕴含出人所从没有过的能力，反而助人释放了更多欲望，让人德行受损。能力虽然抗侵染，但尘垢却可以裹挟能力，让其无法发挥作用，俗话说，就是精神内耗，精神的垃圾都在这个范畴内。\n认清能力的类型和边界，可以助自己更好开发自己的能力，欣赏别人的能力，特别是欣赏周围人的能力。工作中聚在一起的人，能力的类型虽然接近，但有量级的差异，也有偏向一隅的差异。师长与上级可能各方面能力全面强于己，那说明自己太不努力，要精进。搜集信息能力不足，理解信息能力不足，全丢给别人，摆弱者心态，并不会有助于问题的解决，既不增长能力也不增长德行，多数时候会滋生精神的垃圾。与上级或者同级之间更多时候是能力的互补。行动能力强的人可能描述能力不足。分类能力强的人可能推理能力不足。观察能力强的人可能决策能力不足。要保持好奇心，培养自己喜爱且擅长的能力，同时也要虚心，遇事积极听取别人的观点和建议，弥补自己因能力不足而造成的疏漏。\n知道痛苦的原因，还要知道痛苦的止息，知道止息痛苦的路径。贪嗔痴是毒，看不清自己的贪嗔是痴，总说不知道也是痴。痛苦的止息要清毒，止息痛苦的路径是八正道。\n人能培养的根基不过是自己的能力与德行，至于事情的成败、对他人的影响，都是不可控的，不是自己的根基部分，此外，自己的身体、家庭、学历、成就、工作单位也都只是幻象，变化不定，终有消逝的一天。圆满的人生稀有，找到合理的期望，着眼脚下。\n祝愿大家健康工作，生活幸福。\n","date":"2023-09-27T00:00:00Z","permalink":"/posts/%E5%A6%82%E4%BD%95%E8%BF%BD%E6%B1%82%E5%B9%B8%E7%A6%8F/","title":"如何追求幸福"},{"content":"提案是以做决策为目的的，以书面叙述的形式呈现，应当尽量简短、观点鲜明、考虑周详、论证合理、详略得当。提案的发起人常常也是提案的作者，其读者往往是能做决策的利益相关方，最终决策人要么是提案发起人，要么是项目投资人，也即利益方中其他最终承担风险的人。\n提案必然是被拿来讨论的，讨论后一定要做出决策，以确定方向，将团队资源聚焦到一条道路上。作为提案的发起人与作者，不论是否是最终的决策人，都要做好讨论会前的准备、会中的记录和会后的总结。\n参与讨论，与人打交道，关键在于做好期望管理，对于可能偏离期望的部分，做好应对策略。会前要充分考虑参与讨论的各利益方的诉求和底线，从而使得提案能尽量不超出参与者的预期。对于不熟悉的利益方，要做好调研，先判别清楚敌友。友方共享利益，敌方争夺利益。初步研判后，仍旧需要一些场外联络和互动或者前哨工作，兵法所谓知己知彼。能够化敌为友自然是上上策，若不能，要团结更多的利益方，消除友方的疑虑与困惑，减轻友方的摇摆，让敌方打退堂鼓。\n会中是正面战场，发起人有着指挥与主持的天然优势，不仅能调动友方发言，还能适时地禁言敌方。会议即便有专门的主持，发起人也不能把责任全部丢出去，给主持人施加压力。理论上讲，主持的角色在会议的把控能力上可以稍有不足，但至少应当在德行上秉持公允，不畏惧强势一方的气场与发言，而为弱势一方鼓气，从而维持和谐的氛围与秩序。可现实往往是能力充分者可能没有德行或者因争夺利益而丢掉德行，而能力不足者必然德行不足，令人颇为无奈。德行若是养得厚，能力必然强。主持人秉持公允，要尽量避免交战中情感失控，即使真的出现，也要能够首先保持冷静，特别要避免自己陷入到利益的争论当中，而应当以不容质疑的言语去借助意外的相关事物来打破节奏和调节氛围。\n发起人除了有主持的义务外，还有场记的义务，即便有专门做会议纪要的人，也仍旧应当将要点在脑海中梳理清晰。发起人必然有立场，也应当有立场，而场记与主持一样，应当放下立场、不带偏见。训练有素的场记应当保持开放、认真聆听，唯有如此才能将要点落在笔头的同时也印在脑海中。保持开放和认真聆听虽说依赖于理性，要将其当作原则，但绝不是强迫的、命令的，而是要能调动起积极的生命情感，能与各方感同身受，不偏不倚。在利益方较多的重要会议上，专门的场记就格外重要。发起人虽能记得要点，但可能会疏忽要点中的一些细节，好的场记若能提炼记录准确，不仅对发起人来说是好的补充，更能成为后续推进提案的重要参考资料。会议纪要应当围绕策略讨论的各个方面，用已发生的确定的语态记叙，将重点放在决策的结论和支撑论据上，若当场没有得出明确结论，则应当将后续跟进的工作逐点记录并确定负责人，同时商量好下次能得出结论的时间。\n会后应当做好提案的迭代与归档。提案是一种重要的创作成果。但凡是创作，不可能不经过修改，严重时内容失焦、提案毫无结构、利益方缺失，短时间看，一方面源自于作者文字叙述技艺的不足，另一方面源自于作者会前工作的不充分，长时间看，来源于眼界的狭隘、专业素养的欠缺与对提案产生预期效用的信心的缺乏。不论哪种病根，都要从自身能力上找问题去修正，做好迭代与归档不仅是为了给出短期的书面交代与总结，更是为了长远的自我成长。勤于做迭代与归档需要两个心态做支撑，始终期待自我的成长与随时察觉到自我的傲慢。\n讨论会第一作用是做决策，但也起着正式知会各利益方并将决策公开公正的作用，换言之，即便有些利益方参与感弱，提案发起人也有义务通知到。不轻视和不忽视他人感受是团结友方、获得敌方尊重的良缘。\n提案服务于项目的各个阶段，不限于立项、架构、设计与测试。任何需要与人做决定的会议中，会议的发起人都应当持有一种提案的意识，只是决议的事情参与人数和影响较小的时候，书面叙述的形式可以适当简化。\n一种常见的提案结构，是先阐述问题，再讲述愿景，然后给出提议，包括对蓝图进行描绘以及对提议与备选方案进行对比讨论。提案的结构并非固定不变，但往往前面所说的三种要素都要有。提案往往是分析与综合后得到的结果，一种误区是只做分析不做综合，把提案写成分析报告或者调研笔记，另一种误区是做了一种提议，但分析与综合皆不足，把提案写成详细设计或者规格说明书。这两种误区倒不全然是不好的结果，只是不是理想的提案。在需要审核的细节较多的时候，把详细设计或规格说明书当作一种提案也未见得不是一件好事，节省沟通次数。\n","date":"2023-09-27T00:00:00Z","permalink":"/posts/%E5%A6%82%E4%BD%95%E4%BD%9C%E6%8F%90%E6%A1%88/","title":"如何作提案"},{"content":"2023-03-03\n做工具的主人要有积极的态度与恰当的方法。方法恰当却态度不积极，是工具的敌人。方法不恰当态度积极，是工具的学徒。方法不恰当还态度不积极，是工具的奴隶。傲慢使人成为工具的敌人，懒惰使人成为工具的奴隶。人极容易沦为工具的奴隶。实际上，持有积极的态度已经是在运用恰当的方法。\n2023-03-02\n能不能、行不行、有没有，这样的问题总是充满挑战。若是能、行、有，也就不成为问题。问题，是困惑，是不满，是视野的狭窄，是内心的闭塞，是心胸的狭隘。解决问题，需要创造工具，而创造工具的方法永远都是要拓宽视野，开放内心，打开胸怀。心怀天下，不是一句抒情，而是真的装着每个人的困惑、不安与无奈。\n2023-03-01\n服务具有人的主观性，是人与人来往的途径，也表露着人的动机与目的。人们将客观的一般工具看作是无善恶的，但服务却有善恶。火药可以用来开山通路，也可以用来杀人，开山通路不一定都是善的，杀人也不全然是恶的。\n2023-02-28\n人活着的价值在于服务他人。价值于服务中体现，这是生存的需要，是成长的需要，是从痛苦中解脱的需要。劳动创造价值，服务背后是艰辛的劳动。\n2023-02-27\n服务是一类特殊的工具。相比于一般的工具，服务中留存的人的意图更鲜明、主观性更强，需求被满足得更及时。服务的形态更多是人对人的，而不像一般工具是人对物的。\n2023-02-26\n软件工具满足了人便捷、快速、大量地处理信息的需要。一切人所形成的观念都能表示成信息。处理信息在不同情形中侧重点不同，有的侧重计算的执行，有的侧重信息的存储和传输，还有的侧重硬件的操控。\n2023-02-25\n工具的操作界面是创造者意图的留存与妥协。在使用者操作工具之时，是两者意念上的相合。人与人之间意念的相合是超越观念的。\n2023-02-24\n工具必须可操作。操作工具，需要对应的能力，需要清晰的预期，需要针对意外的处理方法。人的能力通过操作转移到工具上，像是工具具备了某种能力。\n2023-02-23\n找到工具意味着工具可被定位。定位就要有方向和位置，尽管描述方向和位置的形式各异，但都需要先建立起空间的观念，并在空间上进行分割形成区域后进行命名或编号。时间是人与人之间用来协调与同步的工具。朝代是叙述历史的工具，定位朝代，要先建立起轴的观念，再进行分段和命名。\n2023-02-22\n对比就是个强大的工具。心中有了差异，才造成了真的差异。平等是差异产生后和而不同的状态，在无差异之前，也无所谓平等。使用对比这个工具就是主动让心中的差异浮现，自然地观察差异。\n2023-02-21\n观念（Idea）是对比的基础，一切都要形成观念才可以进行比较。观念通过语言来传达，肢体的、表情的、声音的、文字的。观察观念产生的来源是解读观念内涵与延伸的起点。观念的产生来源有外部的和内部的，外部通过感官刺激，内部通过心理活动和思维活动。\n2023-02-20\n知道此工具意味着此工具可被识别。这个有别于那个，因而这个是做这个的工具，那个是做那个的工具。识别产生于差异当中，可对比是可识别的前提。物质是可对比的，文字是可对比的，情绪和思想也都是可对比的。\n2023-02-19\n创造工具是为了构建使用的需要，是从多到一，是对过去的交代。创造汽车，构建了乘坐的需要。一辆汽车综合了耐磨的轮子、稳固的材料、宽敞的空间和充足的动力。汽车时代的到来，是马车时代的结束。\n2023-02-18\n使用工具是为了构建一种需要，是从一到多，是对未来的开创。拿杯子喝水，构建了止渴的需要。杯子可以用来喝水，也可以用来喝茶和果汁。一个废弃的杯子，可以拿来浇花，也可以用来做笔筒，还可以改造后做喇叭。开创总是要回到需要的，而需要从来都来自于人自身。\n2023-02-17\n知道和找到合适的工具是使用好工具的前提。知道有知道的方法，找到有找到的途径。广泛地阅读、观察和记忆是知道的方法，深入地列举、联想、比对和评价是找到的途径。广泛意味着保持开放、积极和谦卑，深入意味着保持好奇、勤奋和真诚。合适和好是理想，这样的理想藏在对痛苦和不满的消解之后。\n2023-02-16\n工具是手段、途径和方法的具象形态，它们同实而异名。工具的形态千变万化，可以是物质的、文字的、情绪的、思想的，还可以是人本身。人人都不愿被当作工具来使用，却也躲不开被当作工具的宿命。一个人若想不被别人当作工具，自己要先不把别人当作工具。这样的原则不是口头上的，而是发自内心的，内外统一的。\n2023-02-15\n创造并不比使用更高级，惊人的创造需要恰到好处的使用。创造面向未来，是从多到一，却也是对过去的交代。使用贴近过去，是从一到多，却也是对未来的开创。创造在求新求变的人眼里，要有创新，有创意，但在追本尚古的人眼中，只是水到渠成，因缘际会的结果。新意是对现存事物的不满，是对从痛苦中解脱的执着。\n2023-02-14\n人不仅是工具的使用者和创造者，还是维修者、改良者、推广者和拥有者。工具被人群广泛使用，不是一夜之间完成的，甚至不是一个时代所完成的。与一些经历成功改良和推广的工具的存续时间相比，一个人的寿命是极其短暂的。\n2023-02-13\n人是工具的使用者和创造者，不论作为哪个角色，都是为了构建活动。或者使用工具构建服务，或者使用旧工具构建新工具，人都是主体，也可以统称为构建者。举例来说，Java程序员是构建者，或者使用Java编译器构建Java应用服务于他人，或者使用旧版本的Java编译器构建新版本的Java编译器。\n2023-02-12\n工具是构建活动的必要元素。修房子需要建房的工具，造火箭需要制作火箭的工具，类似地，写软件或者软件服务，也需要趁手的工具。\n2023-02-11\n软件是构建得到的，而不只是编写的。编写只说了构建活动的一环，即编码，它侧重于编排与书写，可从活动整体看，更重要的是构架和建设。\n","date":"2023-02-11T00:00:00Z","permalink":"/posts/%E5%B7%A5%E5%85%B7/","title":"有关工具的思考"},{"content":"原文链接：https://source.android.google.cn/docs/core/architecture\nThe Android Open System Platform (AOSP) is publicly available and modifiable Android source code. Anyone can download and modify AOSP for their device. AOSP provides a complete and fully functional implementation of the Android mobile platform.\n要点：\n安卓开源系统平台。 代码开源。 下载修改自由。 提供安卓移动平台完整的功能实现。 评论：\n先说开放修改的自由精神，再说项目本身专注于提供什么。\nNote: AOSP can\u0026rsquo;t provide support for apps that require backend services, such as a cloud messaging or advanced location services app. AOSP also doesn\u0026rsquo;t include a full set of end-user apps that might be needed for particular types of devices.\n要点：\n与云端服务交互的应用不在支持的范围之列。 特定设备定制的应用不在支持的范围之列。 评论：\n要说清楚不支持什么，既是划清界限，也是免责申明。\nThere are two levels of compatibility for devices implementing AOSP: AOSP compatibility and Android compatibility. An AOSP-compatible device must conform to the list of requirements in the Compatibility Definition Document (CDD). An Android-compatible device must conform to the list of requirements in the CDD and Vendor Software Requirements (VSR) and tests such as those in the Vendor Test Suite (VTS) and Compatibility Test Suite (CTS). For further information on Android compatibility, refer to the Android compatibility program.\n要点：\n两个层面的兼容性：开源系统平台的兼容性和安卓兼容性。 第一个层面的兼容性：兼容性的定义文档中的需求。 第二个层面的兼容性：除了兼容性的定义文档外，还有供应商的软件需求、供应商的测试套件、兼容性测试套件。 安卓兼容性的计划。 评论：\n系统实现要能在各种各样的设备上运行，对安卓平台的维护者、设备硬件的供应商、设备的制造商而言，需要制定标准化的测试计划。测试是服务提供方站在消费方视角审视系统实现的方式，对功能的集成与产品质量的把控至关重要。系统的架构之初，测试计划应当在讨论之列。讨论测试计划是一种典型的逆向工作法。\nAOSP architecture\nThe software stack for AOSP contains the following layers:\n要点：\n软件堆栈。 评论：\n分层的体系结构风格是平台类复杂系统的必然选择。作为平台至少要有三种角色，生产者、消费者和平台搭建者。每一层都能从生产消费的角度看，但每一层所使用的沟通语言不同。上层靠近应用和接口，接近人的自然语言，而下层靠近原理和实现，接近人的逻辑和形式语言。平台要为生产者和消费者搭建起恰当的沟通语言。平台的搭建成本不能超过生产者和消费者从中获得的价值和利益。平台搭建的沟通语言要简单而且有效，不能过度创造，也不能创造不足。要做到恰到好处，要充分探究生产者和消费者的需求。这样想来，深入了解一个应用软件或者平台软件，阅读测试计划比阅读架构文档和源代码来得更加高效。测试计划可谓是需求文档的落地版，也是平台功能的大纲。当然架构文档能把设计中的重点和要点汇总在一起，免去了通过测试计划来推测的麻烦。源代码当然是比测试计划和架构文档都更为准确的东西，但也很容易让人迷失在细节中，找不到方向，甚至还可能看错了东西。源代码是要结合测试结果来看的，不过一般测试结果很少记录得事无巨细，通常需要借助人工测试或者调试。\nFollowing is a list of definitions for terms used in Figure 1:\nAndroid app\nAn app created solely using the Android API. Google Play Store is widely used to find and download Android apps, though there are many other alternatives. In some cases, a device manufacturer might want to preinstall an Android app to support the core functionality of the device. If you\u0026rsquo;re interested in developing Android apps, refer to developers.android.com\n要点：\n安卓应用。 只用安卓应用编程接口。 查找和下载应用的商店有谷歌官方的也有其它的。 设备制造商可能会预装应用支持一些设备的核心功能。 应用开发的站点不同于此站点。 评论：\n这是消费者最为常见的一类安卓应用，也是开发者最为众多的一类。设备制造商往往也会开发一些这类应用，但更多是一些预装应用。\nPrivileged app\nAn app created using a combination of the Android and system APIs. These apps must be preinstalled as privileged apps on a device.\n要点：\n特权应用。 结合使用安卓应用编程接口和系统应用编程接口。 必须预装。 评论：\n访问系统应用编程接口需要较高权限，因而叫做特权应用。这种应用是必须的，例如桌面启动器和设置。这类应用消费者往往不能卸载。\nDevice manufacturer app\nAn app created using a combination of the Android API, system API, and direct access to the Android framework implementation. Because a device manufacturer might directly access unstable APIs within the Android framework, these apps must be preinstalled on the device and can be updated only when the device\u0026rsquo;s system software is updated.\n要点：\n设备制造商应用。 除了特权应用可访问的两类接口外，这类应用还能直接访问安卓框架的实现。 为了使用一些安卓框架中不稳定的编程接口。 也必须预装。 只能跟着系统软件的升级而升级。 评论：\n对照来看，特权应用似乎可以单独升级。\nSystem API\nThe System API represents Android APIs available only to partners and OEMs for inclusion in bundled applications. These APIs are marked as @SystemApi in the source code.\n要点：\n系统应用编程接口。 仅开放给谷歌的合作商和设备制造商。 源代码中打了特殊标记。 评论：\n没有提供文档连接。这类编程接口恐怕只能通过源代码查找了。搜索代码库，找到一个系统属性类就是这类的接口，还有应用孵化器钩子。\n/** * Gives access to the system properties store. The system properties * store contains a list of string key-value pairs. * * \u0026lt;p\u0026gt;Use this class only for the system properties that are local. e.g., within * an app, a partition, or a module. For system properties used across the * boundaries, formally define them in \u0026lt;code\u0026gt;*.sysprop\u0026lt;/code\u0026gt; files and use the * auto-generated methods. For more information, see \u0026lt;a href= * \u0026#34;https://source.android.com/devices/architecture/sysprops-apis\u0026#34;\u0026gt;Implementing * System Properties as APIs\u0026lt;/a\u0026gt;.\u0026lt;/p\u0026gt; * * {@hide} */ @SystemApi public class SystemProperties { Android API\nThe Android API is the publicly available API for third-party Android app developers. For information on the Android API, refer to Android API reference.\n要点：\n安卓应用编程接口。 三方应用开发者。 编程接口文档链接。 评论：\n三方应该是站在设备制造商角度说的。设备制造商是一方，消费者是另一方，而开发者是第三方。至于谷歌和硬件的供应商应该同属于设备制造商一方，只做内部区分。这部分编程接口是有文档链接的。\nAndroid framework\nA group of Java classes, interfaces, and other precompiled code upon which apps are built. Portions of the framework are publicly accessible through the use of the Android API. Other portions of the framework are available only to OEMs through the use of the system APIs. Android framework code runs inside an app\u0026rsquo;s process.\n要点：\n安卓框架。 应用构建所依赖的Java类、接口和其它的预编译后的代码。 安卓框架皆是通过应用编程接口来被使用的。 安卓框架运行在每一个应用的进程中。 评论：\n安卓应用编程接口和系统应用编程接口都是接口，而安卓框架是这些接口的实现。对开发者而言，开发过程中所依赖的安卓库就包含了编程接口和安卓框架，打包生成的构建产物应当是不包含这个安卓框架的，而是从孵化器进程（Zygote）复刻应用时候就从固定位置加载的，甚至可能不需要额外加载就已经在孵化器进程中包含了。具体是如何实现的恐怕要看代码。兼容性定义文档中没做要求。\nSystem services\nSystem services are modular, focused components such as system_server, SurfaceFlinger, and MediaService. Functionality exposed by Android framework API communicates with system services to access the underlying hardware.\n要点：\n系统服务。 模块化、功能集中。 举了三例：system_server, SurfaceFlinger, and MediaService。 暴露出去的安卓框架的编程接口实际是通过系统服务来跟硬件打交道的。 评论：\nsystem_server中集成了大部分的系统服务。SurfaceFlinger用于图形显示的缓存服务。MediaService用于多媒体的服务。这些服务是从运行的状态来说的。使用编程接口的应用进程是客户端，而这些服务进程是服务器，所以这些服务进程的名字很多以server结尾。服务的注册和查找要通过ServiceManager来实现。由于这些服务进程实际上提供了安卓框架的功能实现，所以这些服务进程也可以称作框架进程。官方在使用Binder进行进程间通信的文档中就是这么称呼的。\nAndroid runtime (ART)\nA Java runtime environment provided by AOSP. ART performs the translation of the app\u0026rsquo;s bytecode into processor-specific instructions that are executed by the device\u0026rsquo;s runtime environment.\n要点：\n安卓运行时。 提供Java运行时环境。 安卓运行时将应用字节码翻译成特定处理器的指令。 在设备的运行时环境执行。 评论：\n代码有三种表示，源代码、字节码和机器码。源代码支持Java和Kotlin。字节码支持DEX，需要从Java字节码做变换。机器码取决于设备的处理器。从字节码翻译到机器码，若发生在安装阶段称作AOT，若发生在运行阶段称作JIT。早先的Dalvik方式是以虚拟机的方式直接解释执行DEX码，ART方式能够兼容Dalvik方式。\nHardware abstraction layer (HAL)\nA HAL is an abstraction layer with a standard interface for hardware vendors to implement. HALs allow Android to be agnostic about lower-level driver implementations. Using a HAL lets you implement functionality without affecting or modifying the higher level system. For further information, see the HAL overview.\n要点：\n硬件抽象层。 抽象了一层标准的接口给供应商实现。 安卓对底层驱动实现保持不可知。 功能实现不影响上层系统。 评论：\n这个抽象层的规定是安卓兼容性计划所覆盖的。兼容性的定义文档中有对硬件兼容性的要求。兼容性测试套件中没有特别针对硬件抽象层的，但上层的框架应该对此有依赖。供应商的软件需求没有专门的文档。供应商的测试套件在各种硬件专门的目录下，例如wifi 1.5的功能测试放在hardware/interfaces/wifi/1.5/vts/functional下。所有硬件的抽象层定义放在hardware/interfaces下。\nNative daemons and libraries\nNative daemons in this layer include init, healthd, logd, and storaged. These daemons interact directly with the kernel or other interfaces and don\u0026rsquo;t depend on a userspace-based HAL implementation.\nNative libraries in this layer include libc, liblog, libutils, libbinder, and libselinux. These Native libraries interact directly with the kernel or other interfaces and don\u0026rsquo;t depend on a userspace-based HAL implementation.\n要点：\n本地守护进程和库。 本地守护进程举了四例：init、healthd、logd、storaged。 守护进程直接跟内核交互。 守护进程跟其它接口交互并不依赖硬件抽象层实现。 本地库举了五个例子：libc、liblog、libutils、libbinder、libselinux。 本地库直接跟内核交互。 本地库跟其它接口交互并不依赖硬件抽象层实现。 评论：\ninit进程是用户空间的第一个进程，进程ID通常是1。本地守护进程运行在用户空间，都是从init复刻的。守护进程间的通信方式不是Binder。应用进程和框架进程一样可以访问本地守护进程。举例来说，应用进程通过android.util.Log写运行日志，而底层依赖的liblog使用了Socket通信向logd发起写日志的请求。本地库可以被不同的可执行程序所共享，应用进程也可以，比方说应用进程通过JNI在libandroid_runtime中使用liblog进行写日志。\n// android.jar // frameworks/base/core/java/android/util/Log.java public static int w(@Nullable String tag, @NonNull String msg) { return println_native(LOG_ID_MAIN, WARN, tag, msg); } @UnsupportedAppUsage public static native int println_native(int bufID, int priority, String tag, String msg); // libandroid_runtime.so // frameworks/base/core/jni/android_util_Log.cpp static jint android_util_Log_println_native(JNIEnv* env, jobject clazz, jint bufID, jint priority, jstring tagObj, jstring msgObj) { // 删掉了一些代码 int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg); if (tag != NULL) env-\u0026gt;ReleaseStringUTFChars(tagObj, tag); env-\u0026gt;ReleaseStringUTFChars(msgObj, msg); return res; } static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { \u0026#34;isLoggable\u0026#34;, \u0026#34;(Ljava/lang/String;I)Z\u0026#34;, (void*) android_util_Log_isLoggable }, { \u0026#34;println_native\u0026#34;, \u0026#34;(IILjava/lang/String;Ljava/lang/String;)I\u0026#34;, (void*) android_util_Log_println_native }, { \u0026#34;logger_entry_max_payload_native\u0026#34;, \u0026#34;()I\u0026#34;, (void*) android_util_Log_logger_entry_max_payload_native }, }; // liblog.so // system/logging/liblog/logger_write.cpp static __android_logger_function user_set_logger_function = nullptr; static __android_logger_function get_logger_function() { if (user_set_logger_function != nullptr) { return user_set_logger_function; } static __android_logger_function default_logger_function = []() { #if __ANDROID__ if (get_file_logger_path() != nullptr) { return file_logger; } else { return __android_log_logd_logger; } #else return file_logger; #endif }(); return default_logger_function; } void __android_log_write_log_message(__android_log_message* log_message) { ErrnoRestorer errno_restorer; // 删掉了一些代码 get_logger_function()(log_message); } int __android_log_buf_write(int bufID, int prio, const char* tag, const char* msg) { ErrnoRestorer errno_restorer; if (!__android_log_is_loggable(prio, tag, ANDROID_LOG_VERBOSE)) { return -EPERM; } __android_log_message log_message = { sizeof(__android_log_message), bufID, prio, tag, nullptr, 0, msg}; __android_log_write_log_message(\u0026amp;log_message); return 1; } void __android_log_logd_logger(const struct __android_log_message* log_message) { int buffer_id = log_message-\u0026gt;buffer_id == LOG_ID_DEFAULT ? LOG_ID_MAIN : log_message-\u0026gt;buffer_id; // 删掉了一些代码 write_to_log(static_cast\u0026lt;log_id_t\u0026gt;(buffer_id), vec, 3); } static int write_to_log(log_id_t log_id, struct iovec* vec, size_t nr) { // 删掉了一些代码 ret = LogdWrite(log_id, \u0026amp;ts, vec, nr); PmsgWrite(log_id, \u0026amp;ts, vec, nr); return ret; } // liblog.so // system/logging/liblog/logd_writer.cpp int LogdWrite(log_id_t logId, struct timespec* ts, struct iovec* vec, size_t nr) { ssize_t ret; static const unsigned headerLength = 1; struct iovec newVec[nr + headerLength]; android_log_header_t header; size_t i, payloadSize; static atomic_int dropped; LogdSocket\u0026amp; logd_socket = logId == LOG_ID_SECURITY ? LogdSocket::BlockingSocket() : LogdSocket::NonBlockingSocket(); Kernel\nThe kernel is the central part of any operating system and talks to the underlying hardware on a device. Where possible, the AOSP kernel is split into hardware-agnostic modules and vendor-specific modules. For a description, including definitions, of AOSP kernel components, refer to the Kernel overview.\n要点：\n内核。 内核是任何一个操作系统的核心。 直接跟设备硬件打交道。 安卓开源系统平台内核分为两部分，一部分与硬件无关，另一部分是特定供应商的模块。 内核概述链接。 评论：\n依据生产过程，定制内核需要三方参与，AOSP项目维护者、硬件单片机和外设的供应商、原始设备生产商。拿我手上的华为荣耀Play 6T来说，谷歌公司是AOSP项目维护者，联发科和华为是硬件供应商、荣耀终端有限公司是原始设备生产商。依据通用内核映像（GKI）项目的说法，内核由四部分构成，Linux长期支持版（LTS）内核、安卓公共内核、供应商内核、生产商设备内核。\n","date":"2023-01-28T00:00:00Z","permalink":"/posts/%E6%9E%B6%E6%9E%84%E6%A6%82%E8%BF%B0/","title":"架构概述"},{"content":" Jeremy\u0026rsquo;s World翻译成中文是吉里米的世界，取自《苏菲的世界》，博客搭建那段时间我刚好在读这本小书，格外喜欢，便用作了站点的标题。\nJeremy是新东方一位外教送我的名字，与我的中文名字佳明发音相近。World在Merriam-Webster中名词共14义，取其第6义“the system of created things”，直译作被造物的系统，意译作整个宇宙。\u0026lsquo;s所有格表达了属于Jeremy的World，通俗说也就是我眼中的世界。其实“眼中”也有两说，一说是眼睛这个器官，另一说是心灵，我更多想说后一个，但直接说“我心中的世界”又显得太过主观，只好这样啰嗦地解释一番。\n与世界相关的形象事物是地球，但若用了地球，就像是在讲天文地理，偏离了我的本意，于是我想到一句话“一花一世界，一叶一菩提”。这句话的出处网上讹传为《华严经》，但我在《华严经》的三个文本中作了搜索并未找到，想来这是现代人的附会。不论出处何在，话中所讲的道理能引发人的遐想或思考：世间万物都彼此联系，没有独存无依之物，透过一朵花能够看到整个世界，通过一片叶可以观想到整棵菩提树。\n以一朵花作为博客标志是切题的，但考虑到母亲名字中有花，而花又具有太多的文化含义，于是选择用菩提叶作标志。\n菩提在梵语中是觉悟的意思，英文音译Bodhi，意译作awakened。佛在毕钵罗树下证悟，而后毕钵罗树被称作菩提树。玄奘法师曾到树下瞻仰，想到佛住世时，自己不知飘零何方，不禁悲泪盈目，令人动容。取菩提叶作为站点标志，也想表达自己对正等正觉的向往之心。\n","date":"2023-01-26T00:00:00Z","permalink":"/posts/%E5%8D%9A%E5%AE%A2%E6%A0%87%E5%BF%97%E6%95%85%E4%BA%8B/","title":"博客标志故事"},{"content":"从2014年12月搭建博客以来，对站点做过三次大的维护，分别是2016年7月、2020年6月、2023年1月，具体维护的内容记录在了维护日志中，而这篇是为了规范化维护的各个方面，用以节省维护的时间成本，同时也给其他的博客人做个参考。\n托管服务 站点的数据库、网页服务器、域名、数字证书都需要托管服务，定制主题源代码也需要，此外也为垃圾评论过滤购买了服务。Google Fonts、MathJax等资源外链需要注意防火墙和内容分发网的效率。\n服务费用 在服务质量有保障的提前下，拣便宜免费的用。目前数据库和网页服务器用的阿里云的独享虚拟主机基础版，域名和解析服务用的阿里云云解析DNS，数字证书用的DigitCert免费版，垃圾评论过滤用的CleanTalk单站点无限制版。\n站点功能 站点功能涉及角色包括读者、作者、机器人、管理员、测试员和开发者。一项功能通常只涉及一个角色，但一项功能的发布可能涉及多项功能的添加。例如若要为读者提供更好的字体阅读体验，同时需要为作者提供更丰富的字体选择，还可能需要为管理员提供字体的开启和禁用功能，也需要为开发者提供字体的调试和预览环境。个人博客功能开发与维护，一人身兼六种角色，考虑成本，需要有所取舍。\n开发环境 主题定制是搭建博客的众多理由之一，WordPress通过主题机制和插件机制能满足大部分的需求。但如果市场中没有合适的选择，就需要自己动手开发主题或者插件，这种情况下自动化程度高的开发、测试和部署环境能够节省时间。这次维护对主题做了升级的同时，还提升了开发环境的自动化程度。\n数据备份 数据库服务版本升级、数据库服务更换、测试环境数据导入都需要做好数据备份。\n方法技术 添加一项站点功能或者修复一个漏洞需要一定的方法和技术，优先查看市场上的插件以及插件使用手册、评测结果并亲自体验，其次查找野路子并评估短期方案风险与长期方案进行对比，按情况择定。\n维护日志 站点的维护历史。虽然叫做日志，但维护往往比较集中并且时间仓促，实则以月为单位，记录简短概括。查看详情→\n","date":"2023-01-25T00:00:00Z","permalink":"/posts/%E5%8D%9A%E5%AE%A2%E7%BB%B4%E6%8A%A4%E5%A4%A7%E7%BA%B2/","title":"博客维护大纲"},{"content":"2023年1月 升级WordPress版本至6.1.1、MySQL至5.7.25-log、PHP至5.6。 为mjm1990.com域名开启SSL数字证书。关于为何要开启SSL，查看这篇。 清除两万两千多条垃圾评论。 启用并购买CleanTalk垃圾评论过滤服务。 通过Docker Compose提升主题开发的自动化程度，并用Github托管源代码。 更换定制主题jeremysworld，包括改善移动端用户体验、添加导航菜单、开启并引入Google字体、升级MathJax版本、支持管理员修改备案号。 发布归档、关于我页面。 添加站点favicon和logo，并发布博客标志故事。 替换用户头像服务为Cravatar。 2020年6月 万网关停X享主机-X3，切换到独享虚拟主机基础版。\n2018年1月 显示文章浏览次数。\n2016年7月 根据不同页面类型，启动永久链接。 更换定制主题BlogJ。 2014年12月 博客上线。 更新备案号。 ","date":"2023-01-25T00:00:00Z","permalink":"/posts/%E5%8D%9A%E5%AE%A2%E7%BB%B4%E6%8A%A4%E6%97%A5%E5%BF%97/","title":"博客维护日志"},{"content":"学位学科目录2011版中分了十三个学科门类，依次是哲学、经济学、法学、教育学、文学、历史学、理学、工学、农学、医学、军事学、管理学和艺术学。一般情况下，一个人全脱产学习四年能取得一个学位。获得学士学位意味着在这个学科门类中粗略浏览了一些内容，至于有没有被领进门，还待将来实践的检验。所谓的被领进门，意思是已经察觉并初步理解这个门类所偏重的思维方式，随后就是在实践中主动运用和深化这样的思维方式。诚实讲，我自己本科毕业并没有入门，而是在研究生毕业后才对工学的思维方式有了初步理解。\n工学的全称是工程学，是对工程规律的总结。工程学的一级学科最多，一共三十八个，不管它们研究对象差异有多大，能被放在一个门类，说明有着共通的东西。在我看来，这共通之处就是控制与构建的思维方式，譬如对水、火、气、电的控制，又譬如用木、石、泥、沙、金属所做的构建。不论是从无机的到有机的，还是从宏观的到微观的，甚至是从具体的到抽象的，核心都是控制与构建。以我本科学习的软件工程为例，即便研究对象较为抽象，但内核仍旧是控制与构建，要么通过软件控制某些机械过程，要么构建软件给人提供服务。\n理工经常被放在一起说，不仅是因为有许多以理工命名的大学，更是因为工学常常以理学为基础。理学为工学一方面提供了理想模型，另一方面提供了理论可行性的分析结论。理学思维与工学思维有明显的风格差异，工学是命令式的，而理学是描述式的。理学思维偏重于四项思维活动，观测、度量、解释和预测。依据观测的对象不同形成了不同的学科，譬如对象是抽象的数、形、关系和过程时，形成了数学，又譬如对象是物质的变化时，形成了化学。理学都以数学为基础，对观测对象进行度量，依据数量关系对事物间的现象进行解释和预测。观测与度量是理学思维的起点，解释和预测是理学思维的终点。观测是抽象与建模，度量是分类与推导，解释是演绎与归纳，预测是应用与证明。\n工除了跟理放在一起说，还会跟农、商、文、艺放在一起称工农、工商、文工、工艺。理工放在一起说是近现代的事，但工与农商放在一起却是自古就有，所谓士农工商四民。从古至今，这些字的文化政治含义发生了很大的变化，但其思维内核应该是一以贯之的。农学的思维偏重耕种与培育。耕种幼苗，培育良种，不仅是对植物，也是对动物，不仅是对陆地的，也是对水里的。工农一起，是社会生产的基石。商科的说法常有，但商学的说法较少。商科的内容主要来自管理学和经济学，商科的思维内核也就是管理学与经济学的内核。不同于工农，这两个学问都是直接对人展开的。管理学偏重沟通与激励。沟通目标、计划与绩效，激励工作与成果，通过沟通与激励来达成组织的生产与创造。经济学偏重分配与选择。分配人力、物力、时间等资源，选择耗费与收益，通过分配与选择来达成价值的创造、转化与实现。文艺的思维内核并不在于它的娱乐性与感性，而在于表达与传播。文学通过文字语言进行表达与传播，而艺术可以承载于任何的媒介上进行表达与传播，譬如歌唱、舞蹈、表演以人为媒介，而绘画、雕塑以物为媒介，工程构建产物自然也是一种媒介。\n在西方，医学、法学与神学并列为最古老的专业，可见这三个学科所面临要解决的问题是根本性的，割裂开看是三个，合起来看实则是一个。以割裂的角度看，三个学科思考对象不同，医学思考疾病，法学思考正义，神学思考神，一切的争辩与发展都基于思考的对象。合起来看，三个学科都是理论与实践并重的，每个学科的思维方式都能作用在其它两个上，不仅都可以解释得通，还可能取得切实的效果，于一个人来讲要做到知行合一。医学思维的起点是疾病，终点是健康，过程中要经历检测、诊断与疗愈，事后还有防治。将医学的思维方式放在法学问题中，起点是不正与不义的行为，终点是正义，四个过程均不可少。将医学的思维放在神学问题中，起点是人性，或者说是人的劣根性，终点是神性，是人性的光辉，检测和诊断人的劣根性，在外是法律，在内是道德，疗愈和防治人的劣根性，依旧在外是法律，在内是道德。法学思维在我看来，是通过赏罚分明，来维持正义。将法学思维作用在医学问题上，是通过奖赏顺从生理心理规律的观念与行为，惩处违背生理心理规律的观念与行为，来维持健康。将法学思维作用在神学问题上，是通过奖赏善念与善行，惩处恶念与恶行，来维持神性。西方中世纪神学蔚为壮观，如今显得凋零。靠近神学的是哲学、宗教与教育学。许多年轻人以为现代哲学偏重思辨与理论，而把实践丢给了宗教、政治与其它学科，这是一种误解。在我看来，神学、哲学与宗教的思维内核是一致的，都是反思与修身，思辨的前提是反省自己的观念与思想，反省自己的语言与行为，从而达到修正自身的错误观念，错误语言与错误行为的目的。也许有人会认为神学与宗教更强调信仰，一种无条件的相信，而反思与修身是一种怀疑，但我却认为信疑不二，坚信有条件的相信成为了一种无条件的相信，怀疑一切无条件的相信也将形成一种怀疑主义的信仰。将反思与修身用在医学与法学上，就是要反省自己有没有践行自己所思所想的医学和法学理论与观念，若是没有践行，就要对自己进行修正。\n教育的终极形态是自我教育，是圣人无常师，是反思与修身。教育学的思维应当是学习与教化并重的。学是像他人学，弃恶扬善，习是践行，是对自我的教导与驯化。人在没有达到终极形态之前，需要经历漫长的家庭、学校与社会教育。孔子是教育学的大家，要做到自我教育，必读《论语》。\n历史与军事是中国人格外擅长的，现代的历史学与军事学虽然在形式与媒介上有所变化，但各自独特的思维方式应当也是通行古今中外的。历史学是人反思活动外化的学问，偏重于汇编与校对，汇集各个角度、各种形式的材料信息，以尽力编纂和校对准确而不带偏见的历史样貌，进而供人吸取教训修正行为。军事是外交的延伸，是交涉不成的被迫动作，内部是不需要军事的，若内部有了军事，那便反映了内外转化的巨变。军事学的思维偏重于防卫与进攻，衡量各方实力，防御外部入侵，保卫所得所据，审时度势，以攻代守，减少损失。\n人类的知识浩如烟海，一个人穷其一生只能涉猎极小的部分，但作为一个人，不能只让自己的思维方式偏于一端，一种思维方式并不足够解决现实中遇到的问题，对此要有充分的认识，才能减少我们内心的傲慢与偏见，才能生起对别人的欣赏与感激。我们若是追求精神的自由与平等，更应该从放下内心的傲慢与偏见开始。我们若是不知道追求什么，那就要摒弃无知与懒惰，保持虚心与勤奋。\n","date":"2022-11-26T00:00:00Z","permalink":"/posts/%E5%85%B3%E4%BA%8E%E5%88%86%E7%A7%91%E6%80%9D%E7%BB%B4%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95/","title":"关于分科思维的一些想法"},{"content":"购置因由 年初作计划时，重新对深入理解安卓系统发生了兴趣。四年前，曾尝试在Windows的虚拟机上编译，失败告终。如今不只是工作中需要相关知识，更是带着一种惊叹与好奇，想要更多地接近时代所造就的一些逻辑上的庞然大物中所潜藏的智能，以安抚生起的不平静的思绪与心情。\n细想来，只身在移动互联网和物联网的时代，对云与端的深入理解，在于系统而非应用。系统才是构建起端与云生态的支柱。云侧的分布式系统是端系统的放大版，其中的核心技术挑战所需要的方法与技能并没有超出端侧的系统太多，差别之处，仅仅是外在表现的形式。云侧的能力再庞大，没有端侧的呈现和交互也是空无意义。即便是端系统，其构建速度也已远超想象，令人望洋兴叹。开源的安卓系统无疑是一个宝藏，值得花些闲暇时间深入一番。\n三月初，又尝试在MacOS的虚拟机上编译，再次失败。原因是内存不足，虚拟机几乎全部的时间都在做内存磁盘交换，宿主机性能也下降明显，鼠标响应迟缓。官方文档推荐的硬件配置是至少16GB的内存，建议64GB。并举了两个例子说，72核上，一次完整编译用了40分钟，6核上，用了3个小时。我的笔记本配着英特尔i5双核四线程的处理器，4MB L3缓存，16GB DDR3 2133MHz内存。开始以为只是会慢，也还可以用，实测后表明不可行。因此，决定购买一台主机。\n购买过程 坚定购买意向 产生了购买意向，但仍旧摇摆。犹疑有三。其一，主机较重，但也较为精细，搬家不便。其二，使用频率可能不高。其三，家庭耗电增多，废弃和回收麻烦。\n为了坚定意向，还需要找更多的理由来说服自己。\n在云服务商中简单浏览了一下满足我配置需求的云主机，都价格高昂。改装苹果笔记本的成本更是昂贵。价格战胜了重量。\n这台新的主机大概率是要直接装Ubuntu系统的，我也不会拿它作娱乐用途，笔记本和手机已经足够。唯一剩下的用途就是深入学习系统，不只在软件层面，还应该包括硬件层面，以弥补大学期间实践上的不足。操作系统的一个核心价值就是管理硬件，若对硬件不了解，也就谈不上管理。借此机会，对硬件做些深入了解，也仍旧是对专业领域内知识的增长。端设备的数量并没有因为云的出现了变得更少，代码库也没有变得更简单。通用系统和专用系统中涉及到的取舍平衡，如何在技术实现上得到体现，是个有趣的问题。嵌入式的操作系统中即使没有桌面系统中一些庞大工具（编辑器、编译器等）的身影，但构建操作系统的平台工具中这些部分也不可缺少。总之，我又为其增加了许多的使用价值。即使只是编译、运行和调试安卓系统，也不会使用频率不高。\n作为个人台式机，我没有搭建服务器的需要，不会7*24小时的运行。不使用的时候及时关机就好了。处理器大多数时候并不会高负荷运行，总功耗应该超不过电冰箱。至于废弃和回收，从前疏于理会，但此间事物没有东西是不损耗以及不需要花精力去保持其功能和效用的，我应当调整自己去做好这方面的管理。\n决定亲手组装 坚定了意向，就开始实施。最初我还在整装机中挑选，列了几个挑选的严格条件：\n处理器要是i5或i7的，不能低于笔记本的配置； 内存要至少32GB，或者可以扩容到32GB以上； 固态硬盘至少要512GB，机械硬盘2T以上； 机器的重量和体积不可过大，要小巧便于搬运； 机器外观要能看得过眼； 品牌商客服要能说得过去。 选了惠普、宏碁和戴尔的几款机器作了对比，比较下来，觉得惠普战99各方面都胜出，性价比高。可一想到硬件的扩展和维护，便觉得仍旧无法满足我的需求。我若没有亲历装机的过程，加装硬件可能还需要找人，而这样的事情很可能发生在内存和硬盘的升级方面。惠普战99的固态硬盘过小，销售网站也不支持直接加装和改造；内存的上限虽然适中，但原装的16GB可能也不够用。因此，决定亲手组装。\n名称 惠普HP小欧S01 S01-pF277rcn 惠普(HP)战99 HP ZHAN 99 Pro G4 MT 惠普HP小欧S01 S01-pF254rcn 宏碁(Acer)商祺SQX4270 786N 戴尔dell成就3690 Vostro 3690-R14NBR 价格 京东4899元 京东5499元 京东3199元 京东5499元 京东3799元 体积 长29cm 宽9.5cm 高27cm 体积7.4L 长27.7cm 宽17cm 高33.8cm 体积15.9L 长29cm 宽9.5cm 高27cm 体积7.4L 长30.79cm 宽10.2cm 高33.2cm 体积10.4L 长29cm 宽9.26cm 高29.28cm 体积7.9L 重量 毛重5.5kg 净重3.0kg 毛重7.75kg 毛重5.95kg 净重3.0kg 毛重6.6kg 毛重5.85kg 净重4.1kg 外观 纯黑 圆角 压花 银黑 圆角 条纹 纯黑 圆角 压花 银黑 尖角 树状条纹 纯黑 尖角 左下角网孔 能耗 180W电源 典型能源消耗656kWh 180W电源 300W电源 典型能源消耗184kWh 测试 3.9万小时测试 230项测试 2000小时风扇满荷测试 105万小时无故障认证 3.9万小时测试 230项测试 2000小时风扇满荷测试 20万小时无故障 无数据 50项出厂测试 硬件接口 前置1个电源键 前置1个音频接口 前置预留光驱位 前置4个USB 3.2 Gen1 后置2个音频接口 后置1个VGA接口 后置1个HDMI接口 后置1个网络接口 后置4个USB 2.0 后置1个电源接口 内置PCIe x 16插槽 内置PCIe x 1插槽 内置2个内存插槽 前置1个电源键 前置1个音频接口 前置预留光驱位 前置4个USB 3.2 Gen1 前置2个USB 3.2 Gen2 后置2个音频接口 后置1个VGA接口 后置1个HDMI接口 后置1个串口 后置1个RJ-45网络接口 后置2个USB 2.0 后置1个电源接口 后置标准锁槽 后置集成配件电缆锁 后置挂环锁 内置系统风扇 内置CPU风扇 前置1个电源键 前置1个音频接口 前置预留光驱位 前置4个USB 3.2 Gen1 后置2个音频接口 后置1个VGA接口 后置1个HDMI接口 后置1个网络接口 后置4个USB 2.0 后置1个电源接口 内置PCIe x 16插槽 内置PCIe x 1插槽 内置2个内存插槽 前置1个开机键 前置1个重启键 前置1个电源灯 前置1个HDD灯 前置1个网络灯 前置2个音频接口 前置4个USB 3.2 Gen1 后置3个音频接口 后置1个HDMI接口 后置1个VGA接口 后置4个USB 2.0 后置1个RJ-45网络接口 后置2个PS2串口 后置1个电源接口 后置1个Kinsington锁孔 后置1个理线架 内置1个3.5英寸硬盘位 内置1个2.5英寸硬盘位 前置1个电源键 前置1个HDD灯 前置1个音频接口 前置2个USB 2.0 前置2个USB 3.2 Gen1 后置1个音频接口 后置1个HDMI接口 后置1个VGA接口 后置2个USB 2.0 后置2个USB 3.2 Gen1 后置1个前兆以太网接口 后置1个电源接口 后置1个电源指示灯 内置2个内存插槽 软件接口 支持蓝牙4.2 支持Wi-Fi 支持蓝牙 支持Wi-Fi 802.11ac 2.4GHz/5GHz双频 支持蓝牙4.2 支持Wi-Fi 支持蓝牙4.2 支持Wi-Fi 802.11ac 支持Wi-Fi 主板 芯片组H570 集成声卡 集成显卡 无线网卡 芯片组H570 独立显卡 芯片组H570 集成声卡 集成显卡 无线网卡 芯片组H510 独立显卡 芯片组B560 集成显卡 处理器 Intel第十代i7-10700 8核16线程 Intel第十一代i7-11700 2.5GHz 8核16线程 三级缓存16MB Intel第十代i5-10400 6核12线程 Intel第十一代i7-11700 8核16线程 Intel第十一代i5-11400 6核12线程 三级缓存12MB 内存 16GB DDR4 2933MHz 最大容量32GB 16GB DDR4 2933MHz 最大容量64GB 8GB DDR4 2666MHz 最大容量32GB 16GB DDR4 2666MHz 最大容量32GB 16GB DDR4 2933MHz 最大容量64GB 硬盘 512GB PCIe M.2 SSD 2块1TB的3.5英寸HDD 7200rpm 1块256GB的M.2 SSD 最大支持2TB机械硬盘 最大支持1TB固态硬盘 1块1TB HDD 7200rpm 1块256GB SSD 1块1TB HDD 7200rpm 1块512GB SSD 最大支持512GB固态硬盘 1块1TB的3.5英寸HDD 7200rpm 1块256GB的M.2 SSD 显卡 集成UHD630 NVIDIA GeForce GTX 1660 2GB独立显存 集成UHD630 NVIDIA GeForce GT 730 2GB独立显存 集成UHD730 附赠 1个有线键盘 1个有线鼠标 1条电源线 1份保修卡 1个有线键盘 1个有线鼠标 1条电源线 1份保修卡 1个有线键盘 1个有线鼠标 1条电源线 1份保修卡 1个有线键盘 1个有线鼠标 1条电源线 1份保修卡 1个有线键盘 1个有线鼠标 1条电源线 1份保修卡 操作系统 Windows 11 Windows 11 Windows 11 Windows 10 64位家庭版 Windows 10 应用软件 预装正版Office家庭和学生版 预装正版Office家庭和学生版 Office必须要6个月内激活 预装正版Office家庭和学生版 无数据 无数据 维护 标准保修是主要部件两年，其他部件一年。 升级保修五年，需要购买半年内绑定微信公众号注册捆绑成功后才可享受。显示器享受三年保修，一年上门服务。 微信公众号“惠普服务”，输入“保修升级”。 标准保修是四年，光驱和外部设备一年。 升级保修五年，需要购买半年内绑定微信公众号注册捆绑成功后才可享受。显示器享受三年保修，一年上门服务。 微信公众号“惠普服务”，输入“保修升级”。 激活Windows和Office后的主机不能享受7天无理由退换货。 标准保修是主要部件两年，其他部件一年。 升级保修五年，需要购买半年内绑定微信公众号注册捆绑成功后才可享受。显示器享受三年保修，一年上门服务。 微信公众号“惠普服务”，输入“保修升级”。 三年有限上门保修。主要部件三年，其他部件一年。 微信公众号“Acer宏碁服务”。 三年整机上门保修。 售后电话 固话 800-820-6616 手机 400-885-6616 固话 800-810-3888 手机 400-610-3888 固话 800-820-6616 手机 400-885-6616 手机 400-700-0118 固话 800-858-2968 手机 400-886-8611 围绕机箱规划 挑选组装配件前，先从机箱入手，找了些视频和京东的商品对比。这样做是考虑到，最终放在家里的并不是一个个的配件，而是一个机箱，从它的物理参数开始，对内部的构造作全面的了解总是没错的。两个入门视频，质量一般，但基本的信息量也足够一个新人消化的。\n机箱篇：机箱选购指南（含机箱推荐） 电脑机箱篇-科普机箱尺寸和风道的知识，以后买机箱不会懵逼了 对比了十多个商品，最终都没买，可至少想清楚了机箱挑选中关键的参数。除了体积和重量以外，还需要关注\n主板类型 散热器限高 显卡限长 电源限长 通风设计 机箱风扇大小、数量和位置 硬盘位数量和位置 至于材质和外观，相对主观，一般人也都不会放弃考虑，无需强调。\n围绕主板规划 除了从机箱入手外，也可以从主板入手，先了解主板上外插的配件，再延展到机箱。总之，从空间入手，由整体到部分，由体积占比大的到占比小的，总错不了。实际上对于选购，看下面这两个视频更合适：\n装机不求人之：硬件基础讲解，零基础新手打造电脑配置单教程。一站式台式机DIY入门指南！游戏主机/生产力主机全攻略！ 史上最强！主板选购万能攻略。一站式主板基础知识入门指南！带你全面了解主板基础参数！ 我在装完机后才注意到上面两个视频，也就懒得细看了。我对各个配件的性能需求相对明确，只是对主板本身的构造和扩展槽没有太过深入地从各个角度一个个地考察过。我的主要做法是三点：\n先找了些装机视频，按需，反复观看揣摩； 然后具体挑选了一个有购买意向的主板，详细阅读了官网下载的中英文说明书； 此外也制定了整体计划，并记录了挑选的配件和心得。 装机视频中质量较高的是以下的两个：\n装机不求人之：史上最详细传说级装机教程，零基础新手一站式装机攻略。内含AMD、Intel双平台DIY组装教程 这可能是你能在网上找到最详细的装机教程 挑选主板，先看主板品牌，再看主板人气排行，同时要权衡价格。为了避免质量上的风险，我只看了京东自营的商品。最终下载了华硕的以下两款说明书，详细地进行阅读。阅读中，一方面是熟悉主板上的空间结构、插槽用途、插槽标准，另一方面是要搞清楚匹配的配件有哪些。虽然华硕官网可以查到些推荐的配件品牌和型号，但仍旧不够全面。\nTUF GAMING B660M-PLUS WIFI D4 PRIME B660M-A WIFI D4 在整体计划方面，我考虑了挑选的方法、配件间的兼容性、机器的组装以及操作系统的安装，却忽视了配送过程和硬件驱动的安装。导致下单后更换了内存，配置过程中，系统安装花费了很大的精力。不过好在，软件是我擅长的部分，不需要联系客服，也算不上规划上的失误，只能说，即便当下个性化组装盛行，接口设计已经十分友好，个性化定制也依旧是个复杂的事情。\n选定配件清单 我最终选定的配件如下：\n配件 品牌 型号 长 (cm) 宽 (cm) 高 (cm) 重量 (kg) 价格 (元) 主板 华硕 TUF GAMING B660M PLUS WI-FI D4 24.4 24.4 ~5 1.6 1037 处理器 英特尔 12600KF 4.5 3.75 ~0.5 0.088 1926 散热器+扣具 利民 TL-AS120+LGA17XX-SS2 12 7.3 15.4 0.935 142.4 内存 美商海盗船 复仇者LPX DDR4 3600 64GB(32G×2) 13.5 3.35 0.7 ~0.1 2368 固态硬盘 西部数据 SN770 1TB 8 2.2 0.238 0.041 868 显卡 华硕 GeForce GT730-SL-2GD5-BRK GDDR5 2GB 17 ~4 ~6 0.455 496 电源 全汉 HGE650 17 15 8.6 2.68 599 机箱 先马 平头哥M2 40 (\u0026gt; 24.4) 20.5 (\u0026gt; 15.4) 38 (\u0026gt; 30.75) 4.6 99 机箱风扇 先马 游戏风暴 12 12 2.5 0.1 9.9*3 总计 - - 40 20.5 38 10.6 7565.1 体积方面，主机箱的长取决于主板的长，宽取决于散热器的高，高取决于主板的宽加电源的高。重量方面，机箱、电源和主板占大头。表中有些数据用的是商品介绍中的毛重，即带着纸箱的重量，实际应该会轻个一两公斤，没有实测。价格方面，内存、处理器和主板占大头，这也符合我的需求；硬盘、电源和显卡是下一梯队；散热器、机箱和风扇较为廉价，我没有RGB灯的需求，似乎有点浪费主板的针脚，可我也没配机械硬盘，满足需求就好，关键要过心理关。\n内存最初选了金士顿KF432C16BBK2 DDR4，但两天过后，仍旧不发货，状态总变，于是换了64GB榜单中排名第二的美商海盗船。价格虽然贵了两百左右，但频率也有提升。显卡最初选了华硕PH GeForce GT1030-O2G 1252-1531MHz GDDR5，但下单前突然缺货，便换了差一些的GT730，也完全够用。电源曾想选全汉MS600，SFX的电源，其中虽然包含了ATX的转换面板，但还是担心模线长度不够在MATX的机箱中走线，只好牺牲小重量而取了大长度。\n装机过程 装机过程是一个典型的工程实践，符合工程学的规律。作为工程师，这一步应该是职业技能的直接应用。硬件与软件在方法论的层面，也没有太多的不同。方法层面归结为以下五点：\n说清楚装机完成后成功的状态； 根据成功状态划分大的阶段； 罗列各阶段主要操作步骤和注意事项； 罗列各阶段主要检验步骤和注意事项； 罗列意外处理和调试的方法。 购买过程中，通过看视频和说明书，我已经在头脑中过了几遍装机过程。意外处理和调试方法考虑得较少，但也有所涉及。\n描述成功状态 在观看装机视频过程中，注意到成功的开机状态应该是在显示器上看到类似下面图片一样的界面。具体来说，至少应当包含以下三个方面：\n硬件自检程序完成，进入UEFI BIOS界面，并能看到所有硬件的状态； 查看各个硬件信息是否符合商品描述； 查看机箱前面板和后面板的接口是否都能正常工作。 前两步到BIOS出现，基本可以算硬件没有故障。第三步需要装上操作系统后再实测以下，特别是网络接口和音频接口。显示器接口、电源开关、重启开关、电源指示灯和USB接口在BIOS阶段也都会得到检查。只要不是硬件的问题，就能省去沟通客服的麻烦。\n划分大的阶段 我给自己设定了两个阶段的目标。第一阶段，将配件全部组装好放入机箱后，不完全拧上8个固定螺丝，接好线，不扣主机盖，只接一个机箱风扇，不理线，插上电源线和显示器查看状态；第二阶段，将前面剩余的步骤全部做完，再作测试和检查。\n操作步骤和注意事项 装机过程的主要步骤和次序：\n洗手释放静电 处理器装入主板 内存插入主板 固态硬盘装入主板 散热器扣具装入主板 处理器上涂抹硅胶 散热器连接扣具 主板装入机箱 风扇装入机箱 电源装入机箱 显卡装入机箱并插入主板 主要的注意事项：\n没有想清楚前不要开机接电 螺丝刀要用手动的 螺丝刀长度要至少长过半个机箱宽度 仔细区分机箱中携带的各种型号的螺丝 避免用手触碰任何的针脚 避免用手触碰任何一个配件上裸露的电路元件 避免被主板或者散热器划伤桌面 注意插槽中缺口的方向和角度 插卡和紧固不要用蛮力 紧固螺丝要及时察觉滑丝 处理器盖臂上的软管要取下 按压内存要用力均匀 固态硬盘散热片的保护膜要撕掉 避免被散热器上锋利的部分划伤 散热器底的保护膜要撕掉 硅脂不要涂抹过多避免溢出染了主板或处理器 硅脂不要涂抹过少避免起不到导热的作用 散热器螺丝紧固程度要左右均衡 风扇的风向要符合机箱的设计 避免螺丝留在主板上 检验步骤和注意事项 主要的接线检查：\n电源接主板20+4pin 电源接处理器8+4pin或8pin 散热器风扇接主板4pin 前面板接主板USB 3.0 19针 角缺一针 前面板接主板USB 2.0 9针 角缺一针 前面板接音频 9针 边缺一针 前面板电源指示灯接主板 2pin 分正负极 前面板硬盘指示灯接主板 2pin 分正负极 前面板电源开机键接主板 2pin 前面板电源重启键接主板 2pin 机箱风扇接主板 4pin/3pin 由于我的配置简单，没有外挂的硬盘，显卡低端不需要单独供电，不玩灯效不需要考虑LED等的接线。电源出来的线只有两条。没有配置外挂的硬盘，也造成机箱头轻脚重。\n接线中的注意事项：\n看清接口针脚的数量和标签 接线要插到底 避免风扇供电的并联造成短路 意外处理和调试方法 意外处理的基本方法：\n先说清楚出现了怎样的问题， 其次要搞清楚造成问题的是哪个部分， 然后要评估这个部分的故障是不是自己能解决的，优先考虑利用手边工具解决，若不行，再考虑其他的工具或者购买工具解决，最后是找人帮助或者找客服。 意外的类型从伤害对象上可分为：\n伤害自己； 伤害某个配件； 伤害自己和主机之外的人和物。 关于调试，硬件方面，参考以下的视频足矣，软件方面，作为软件工程师，自己应该胜任所有问题的解决。\n电脑点不亮？黑屏？重启？ 史上最强电脑问题排查诊断攻略！装机不求人系列【超详细】 处理意外情况 注意事项越是做到提前心理有数，就越能避免意外的发生。不过也要减少过度担心，对于好的产品，工程师一定比用户有更加充分的考量。这次装机中，我过度担心风扇的3pin接口，插左插右的问题，网上也没人提，实际发现主板上做了很好的提示和兼容，不存在插错的问题。执行过程整体上比较顺利，一次成功，但也有两个小意外和一个大意外，但都还能独自处理。\n第一个小意外是，处理器盖子打开的方向和下压时的力度让人错愕。处理器的塑料保护盖没有在最下面的时候脱落，而是压到一半时候脱落，以为搞错了主板和处理器的型号，不过后来还是大胆地压了下去。\n第二个小意外是，机箱显卡槽位凸起对HDMI接口产生遮挡导致显卡的HDMI接口插不到底。想来这样的问题很难在网络挑选过程中发现，无奈只好让显卡不能垂直固定，偏了一定的角度。后面查看用户评论时候，有人也遇到过类似的问题，觉得这样做问题不大，我却有些担心长期如此造成PCIe插槽的形变。不过我嫌重新挑选和退换货麻烦，只能接受这点瑕疵。\n最大的意外是，因为疏忽了主机箱中有三种螺丝，导致固定主板时候出现滑丝。支撑主板的螺柱需要匹配直径小一点的螺丝，我没对螺丝分类，随机抓了个大的，导致螺丝拧不到底，固定不了主板，可反向松开，还把螺柱给带起来了。解决这个问题的关键是要将大号的螺丝从螺柱上拧下来，这步无论如何都要面对。基本思路是一只手用老虎钳夹住螺柱，同时另一只手松螺丝。随之产生了两种思路，一种是直接在机箱上操作，另一种是把主板取下来操作。第一种思路下，要在机箱上进一步固定紧螺柱，主板的背面螺柱会露出较长的部分，可以用老虎钳夹住，但由于机箱前面板和上面板的遮挡，看不清转动的位置，用力过大害怕直接把旁边的针脚碰断，也怕脱手直接将螺丝刀杵到主板上。另外，老虎钳夹住的部分并不算太长，若将眼睛放在主板背面，就顾及不到前面。若有两人，或许这种方法还可行。最终还是采用了第二种思路，折腾了许久才得到解决，代价是划伤了桌面。\n最后，还是应该配上第一时间成功点亮的照片，以作纪念。\n配置过程 五个困难 配置过程提前没做太多规划，只粗略地规划了以下三项：\n阅读官方BIOS文档 制作USB启动盘 安装操作系统 此前有安装操作系统的经验和配置安卓系统编译环境的经验，因而只规划到了安装完操作系统为止，但实际上离成功在模拟器上运行安卓系统还有很远的距离。不过，如前所言，软件的领域，我应当能去解决所有遇到的问题。具体遇到的问题有以下五个：\nUbuntu 18.04提示有线网卡芯片无法识别，安装程序直接退出关机； Ubuntu 20.04与21.10无法识别无线网卡和蓝牙，驱动无法加载； 家中没有有线鼠标，键盘无法操控每一个图形界面的功能； 存放安卓开源系统的移动硬盘是苹果的文件系统，Ubuntu无法直接挂载； 安卓模拟器无法正常加载系统。 解决方法 针对问题1，遇到的错误提示为“r8169 0000:05:00.0: unknown chip XID 641”。r8169是Realtek网络接口控制器的编号，这个错误意思应该是操作系统无法识别有线网卡，无法利用有线网卡控制器，因此不能进行后续安装。解决方法是安装高版本的20.04或者21.10，高版本内核中解决了这个问题。\n针对问题2，遇到的情况是，设置面板中无法设置无线网络和蓝牙。执行命令“sudo dmesg | grep iwlwifi”，发现驱动无法加载。查看英特尔官网和Linux固件的代码库，均找不到错误提示中所要求的驱动版本。安装最新的驱动，执行“ls /lib/firmware/iwlwifi-*”查看后也依旧不解决问题。最后发现是内核和固件驱动不匹配，需要内核与固件都升到最新。内核从5.13升级到了5.17。固件从默认升级到了20220329的版本。具体做法可参考以下的三篇文章：\n新电脑硬件DIY+ 安装Ubutun 18.04+排雷 更新Ubuntu内核到最新版本 Linux kernel 5.17 Released! How to Install it in Ubuntu 22.04 解决问题2的一个前提是必须要有网络，否则无法下载。好在读研究生时候的一条网线留着还能用。另一个前提是最好把问题3给解决了，否则，没有鼠标极难操控。这个问题说容易也容易，说麻烦也麻烦。说容易是因为，随便找一个有线鼠标就能解决问题。说麻烦恰恰是因为我不想买这个有线鼠标。最终倒腾许久找到了一个解决方案。手上罗技的鼠标支持无线发射器模式，驱动控制和配对可以通过安装一个名为Solaar的程序完成。有了鼠标后，一切都变得高效起来。有了鼠标，连上无线和蓝牙，第一件事情就是检查音频接口。能走到这里，USB接口基本都检查过了，剩下几个后面板的USB是主板自带的，出故障概率不大。有线网络接口也检查过了，否则无线和蓝牙也用不了。其他的开机键、重启键、指示灯也都通过了检查。\n针对问题4，解决思路是把移动硬盘挂回到苹果笔记本，通过开启苹果笔记本的远程登录，用scp命令进行复制。在一个局域网中传输速度也有20MB/s，166GB传输需要2.4小时。\n针对问题5，前后编译了三个目标，前两次遇到的错误不同，第三次成功运行。第一次错误提示是一个音频的函数执行出错，现象是一个古老版本的模拟器界面被运行，但有该错误日志且系统并没有被启动起来。第二次错误提示是userdata-qemu.img文件不存在，并且模拟器的运行界面也没有运行。这三次编译都顺利完成，解决前两次模拟器运行的失败，大概需要增加特定的模拟器启动的参数，网络上不太容易找到直接的解决方案。如果要自己琢磨出解决方案，需要对模拟器参数和编译产物有较多的理解，暂且搁置。\naosp_cf_x86_64_phone-userdebug aosp_x86_64-eng sdk_phone_x86_64 编译性能 性能方面，第一次编译，耗时近两个小时。这个记录不及官方72核的40分钟，但却好过6核的3个小时。16核的算力还算不错。内存消耗没有想象中那么多，始终稳定在20%上下。处理器的温度在50摄氏度上下，固态硬盘的温度到了60摄氏度。第二次编译，耗时一小时一刻钟。第三次编译，耗时一刻钟，应该是复用了前两个编译目标的一些编译产物。\n#### build completed successfully (01:54:50 (hh:mm:ss)) #### #### build completed successfully (01:14:37 (hh:mm:ss)) #### #### build completed successfully (14:45 (mm:ss)) #### 小结 这是一次有趣的购置体验，意外出现的量不小，但都还在个人以小时为单位能解决的范围内。从3月19日开始规划和调研，利用了三个周末和几个工作日的晚上，半个月顺利完成目标。归结下来，做成一件事，个人可控制的方面不外乎以下三点：\n产生意向并坚定意向； 想清楚目标并能描述清楚目标； 在头脑中预先想清楚每个大的步骤、注意事项、意外的应对策略，详细分解稍微陌生一点的领域的事项到能够上手执行。 做到意志坚定、成竹在胸，才能临阵不乱。\n","date":"2022-04-04T00:00:00Z","permalink":"/posts/%E8%B4%AD%E7%BD%AE%E4%B8%AA%E4%BA%BA%E5%8F%B0%E5%BC%8F%E6%9C%BA%E5%B0%8F%E8%AE%B0/","title":"购置个人台式机小记"},{"content":"引子 最近学习近世代数基础时，短短的一章，一共出现了32个定义、10个性质和30个定理。每一个性质和定理都要经过证明，并非一个顺畅的过程，特别是证明庞加莱定理的那个引理的证明，理解起来颇费精力。学习过程中最为愉快的是认识了同构。同构的定义将置换群与抽象群联系在了一起，从而构造同构的方法与构造对称群的子群的方法被联系在了一起，形成一个完美的闭环。\n课程中的性质和定理无非是一些判定，涉及到群、子群、陪集、正规子群、同态、同构的判定。课程中的定义和证明涉及到构造，包括正规子群、自同构的构造。任何一条都够抽象，很容易让人陷入到去找具体例子当中去，从而忘记了为什么要讨论当下的这条内容，这点与设计软件时，总是钻入下层甚至更底层有些类似。避免这样的状况发生的办法核心是一条，回到因果链的原始状态，找到那个大的因，并且从这个因上，感受到意义和价值。如果感受不到意义和价值，那放弃了，大概也没什么可惜的。例如，群论的产生的大的因是一元高次方程是否可根式求解的问题。我已经记不清为什么一年前会突然开始对这个问题非常感兴趣，但我很清楚，我迄今仍就对这个问题充满兴趣，虽然根式解的答案我已经很清楚，但了解其论证过程依旧能让我感到意义，并且激发我进一步的兴趣。\n主动做一件事情上让人觉得有意义，一定是过程中诱发了别样的生命体验，不一定舒适，但也不会太痛苦。学习近世代数诱发我体验到的是看清生命和思维的局限性，能够看清人生道路的边界，不至于走出去，偏离了终极目标。具体到思维上，经过此番学习，至少我对判定、构造和证明有了更加清晰的认识。\n判定、断定、断言是对所感知事物的描述和叙说，其结果称作是一个陈述或者一个命题。这个思维过程是基于感知和记忆来展开的，过程的结果以记忆的形式对内留存，或以语音和文字的形式对外留存。所形成的记忆并不局限于大脑，还包括身体各个部位的神经和肌肉，以致产生思维过程的本体，从而形成经验。当我们断言产生思维过程的本体与肉体同一的时候，会有超出经验的观察，被人们称作超验或者先验；可当我们断言本体跨越多个肉体的时候，只需要留存经验的概念来解释一切的观察。不论是超验还是经验都是基于本体可感知、可观察和可断言而谈的。可感知的事物在思维过程中被对象化、抽象化、符号化，从而脱离了感知，只留存为了记忆。\n构造、搭建、创造、创作是将经验运用在新的感知对象上，从而产生新的概念和感知对象的过程。在运用经验时，运用者必须意图明确并且能力充分，否则作用会产生偏差。明确意图与做判定的过程类似，要基于感知抽取记忆对象和符号，对将要进行的过程，全面清晰地描述。虽然使用描述这个字眼，但并不意味着一定要用嘴说或者用手写，而是通过念头来完成。明确意图意味着要将念头聚焦到与一个对象相关的一系列记忆上，也就是要专注。能够专注才能意图明确。能力是践行经验的要素。能力充分与否只有运用者才能够全面的认识到，因为从运用者的肉身到肉身以外的一切可感知的事物所具有的局限性就是运用者的能力。具备认知局限性的能力本身也是一种能力。可见能力必然是有边界的，否则所谓的创造也就没有了意义。人们追逐能力的提升，与追求出世间的自由是天然矛盾的，因为出世间的自由是没有边界的。回到世间的追求上，追求创造力的提升，也就是在追求局限性的缩小，也就要提升感知力、专注力和行动力。\n论述、论证、证明是命题（陈述）之间的推演，不产生新的概念和可感知对象。理想中推导和演绎的过程不需要感知力和行动力，这大概也是人们追求人工智能的一个基础假设，感知力和行动力对应到如今的计算机模型上，就是外部设备的功能。这样的假设显然与常人的经验是相悖的，具备与运用推导和演绎的能力往往需要强大的感知力和行动力（对于计算机，人们只好不停地加缓存，头疼于对信息不一致的问题）。现实中的论证过程，不可能是在所有的命题都具足的前提下进行的，这就要求论证者做判断的过程快速准确，若相信本体跨越多个肉体，那么论证者必然是一个经验丰富的跨越者。命题不具足的时候，往往还需要构造新的对象与符号，这又要求创造力。当然没有人会否认论证过程需要高度的专注，甚至从专注上升到了信念。\n","date":"2021-06-14T00:00:00Z","permalink":"/posts/%E5%88%A4%E5%AE%9A%E6%9E%84%E9%80%A0%E5%92%8C%E8%AF%81%E6%98%8E/","title":"判定、构造和证明"},{"content":"编译器前端的程序主干是字符串的匹配，可真正的目的是翻译，将源代码转换为目标码。若将匹配流程比作骨架，那么翻译方法就是血肉。设计翻译方法，在于解决三个问题：如何表示源代码中的语义？如何表示目标码？如何将源代码到目标代码的翻译步骤添加到程序的主干流程当中？\n语义是藏在文字符号本身之上的一种可被解释与理解的特性。比方说，符号\u0026gt;，符号本身只是个开口向左的V，而藏在符号之上的特性是大于，用于体现符号左右两侧的量的大小关系；如果两个连在一起，还表示右移。源代码中藏有的语义可分两类，一类体现了目标码的计算特性，另一类体现了源代码的控制复杂特性。第一类在翻译中会通过不同的形式表示，最终翻译为目标码。第二类在翻译中辅助程序做安全检查和组织目标码结构。体现目标码的计算特性的语句类型有算术表达式、逻辑表达式、比较表达式、函数调用和控制流。体现源代码的控制复杂特性的语句类型主要是类型声明，以及一些附加的限定规则。\n在上下文无关文法的框架下，一篇源代码中的字符流，会被转换为文法符号流，语义特性可以作为文法符号的某个属性。语法制导定义中，依据属性对其他符号属性的依赖的不同，将属性分作了两类，继承属性和综合属性。继承属性值的计算依赖于产生式中当前符号左侧的其他文法符号的属性值。综合属性值的计算依赖于产生式中右侧的文法符号的属性值。上下文无关文法通过产生式将源代码映射为了一棵语法分析树，分析树上的结点是文法符号。继承属性值的计算依赖于父结点和兄弟结点的属性值。如果是L属性的语法制导定义，那么规定只依赖于左侧的兄弟结点。综合属性值的计算依赖于孩子结点的属性值。目标码是语法分析树文法结点的主属性，可以表示为综合属性，或者直接依照分析过程生成到文件中或者数组、字符串中。\n目标码要运行在解释器上，而解释器的类型是多样的，可能是物理机器，也可能是软件虚拟机，一种语言若要兼容多种运行环境，那么设计一种中间代码能够让前端的程序得以复用。特别是当有M种语言要运行在N种解释器上时，可以让编写编译器的数量从M*N降低到M+N。\n中间代码要尽可能地接近解释器上运行的指令。一条指令通常包含一个指令名，可以理解为操作符，以及不超过两个的操作数。如果一条指令有两个操作符，那么一定能够拆成两条指令。如果一条指令有多于两个操作数，那么也一定能够拆成两条以上的指令。比如，函数的调用就是个很好的例子。每个参数都能单独拆成一条单操作数指令，函数调用本身也是一条单操作数指令。这种一个操作符和两个操作数的表示方法称作三地址代码，再考虑到指令本身相对其他指令的序列编号，即地址，也就有了中间代码的四元表示。\n三地址码的另一种等价形式是语法树，中间结点是操作符，叶子结点是操作数。如果考虑子表达式的复用，更一般的形式是有向无环图。语法树不同于语法分析树，语法树与三地址码等价，而语法分析树同语法推导的分析过程等价。\n在语法制导定义中添加构造语法树的语义动作，伴随符号的匹配和产生式的规约，执行属性求值、语法树的构造与翻译。在产生式中引入表记的技术能够被用来回填无条件跳转指令中缺失的地址信息。设计语义动作可以依据以下的步骤进行：一、找出关联的几个属性；二、找出哪些是综合属性，哪些是继承属性；三、写出该有哪些语义动作；四、确定语义动作的顺序；五、校验。\n","date":"2020-08-09T00:00:00Z","permalink":"/posts/%E7%BC%96%E8%AF%91%E5%99%A8%E5%89%8D%E7%AB%AF%E5%9B%9E%E9%A1%BE%E4%B8%8B/","title":"编译器前端回顾（下）"},{"content":"在设计编译器的前端时，程序驱动的主干是字符串的匹配，所回答的基本问题是_输入文本是否能够匹配**预定义规则**，因而返回值是是或否_。\n对于回答是的情况，说明输入文本落在了预定义规则划分的范围内。可当规则的描述具有一定规模、较为复杂的时候，又需要知道具体匹配到了哪些规则，这时才会涉及到翻译的问题，常称作语法制导翻译，原因是输入文本的匹配以及翻译前后的字符串的表示问题都围绕语法规则来展开。\n对于回答否的情况，说明输入文本落在了预定义规则划分的范围外。使用者关心的问题会是文本的哪个部分在匹配哪个规则的时候出了问题，设计者需要以易于理解的方式准确、高效地回答使用者关心的这个问题。错误的处理看似是一个边角料的问题，对编译器的设计者而言，与翻译问题是同一个层面的问题，无法回避。\n对输入文本进行建模，一方面是以基本的概念对其进行抽象，摒弃不关心的部分，规定清楚边界；另一方面是运用定义的基本概念对输入文本进行描述。听起来这个方法论同前面提到的匹配基本问题的方法论是相似的，概念即是规则，概念即是边界，这是理解与交流的基础，是广为认可的方法论。\n在建模输入文本时，设计者引入了字符、字符表、字符串和语言等基本概念，忽略了字符的样式、大小、空间位置、书写方向、颜色等。规定字符为基础元素，字符表为字符的集合；字符串为按照一种次序依次连在一起的字符的复合元素，空串是没有任何字符的复合元素，语言是由字符表中任意的字符组成的某些字符串所构成的集合。在此基础上，对复合元素字符串引入了前缀操作、后缀操作和连接操作，对集合语言引入了并操作、连接操作和闭包操作。\n将每一个输入文本都看作一个字符串，当作一种语言，理解起来简单，但语言的数量就等于了输入文本的数量，无法提前预定义规则去解决匹配的问题。将每一个输入文本的每个字符当作一个字符串，这些字符串构成的语言也就是字符表本身，能够描述所有的基于此字符表的输入文本，这样的语言预定义规则是确定的，语言的边界就是字符表的边界。通过以上两个角度，能够看到对输入文本切割的太粗或者太细，所得到的语言都距离人们习惯的自然语言相去甚远。如何选取文本的切割粒度，是门艺术，所持的原则是，让编译器所翻译的语言尽量靠近自然语言。之所以说是艺术，因为无法找到度量，能够说明按集合理论建模出的语言多么靠近自然语言，其中的难度在于自然语言是自然演变的，且在不断地发生着变化，并不存在一种符号系统对其自身再作出完整的描述，因为任何的符号系统一旦建立都是确定不变的，用不变去描述变化，其中总存在着的误差，永远无法弥合。\n如何将输入文本切割为合适粒度的字符串集合？就需要通过设计预定义规则对其进行描述。这样的规则系统就是上下文无关文法。一个文法是一个产生式的集合，一个产生式通过非终结符的替换，能够推导出一个句子，而一个句子可以是整个输入文本或者只是部分的输入文本。产生式规定了切割的粒度。\n产生式是值得深入讨论的模型，看似简单，却又千变万化。产生式的左端是非终结符号，规定可以被替换成右边的字符序列。产生式的右端是终结符和非终结符组成的字符串。终结符来自于字符表，而非终结符来自于字符表之外，单独构成另外的一个集合。\n观察单个的产生式，像是一个变量的定义，也像是一个函数的定义，像是一个类的定义，总之像是一种定义，就是拿一个符号来代表一组固定序列的符号。文字上人们称其为替换，逻辑上人们称其为抽象。看到产生式的左边，将其替换（展开）为右边的操作称作推导。看到产生式右边，将其替换（合并）为左边的操作称作归约。\n观察单个产生式的左边和右边的非终结符，存在一种特殊的形式：递归，即产生式右边的非终结符里包含产生式左边的符号。对于某个非终结符如果存在一个递归的展开（A → Aa ），那么一定还要有一个非递归的展开（A → b ），否则推导无法结束。容易联想到，在数学递推公式中等于在说，必须给定初始条件，否则推导无法结束。此外，这也往往作为检查递归程序是否正确的重要一点。\n根据左边的符号在右边出现的位置不同，分三种情况，开头、中间和结尾。出现在开头，被称作左递归。出现在结尾，被称作尾递归。出现在中间，就是普通的递归。左递归是设计文法时要避免的，含有左递归的文法无法进行自上而下的分析。消除左递归需要引入新的非终结符并利用空串，添加新的产生式。普通递归和尾递归在文法设计时没有特殊之处，可在设计解析器的时候，尾递归往往可以进行优化，即返回当前调用的上下文，清除当前栈帧，而进行新的调用，减少调用栈的层次。这样的优化虽然对执行本身起到了好处，但却给调试工具引入了麻烦。\n观察两个产生式之间的关系，有三种：并、嵌套和不相关。并指的是两个产生式具有相同的左端。嵌套指的是一个产生式的左端出现在另一个产生式的右端中。不相关是指不存在并和嵌套关系的关系。并的关系是对称的偏序关系，嵌套的关系是不对称的偏序关系。文法推导的过程中需要做两个选择，其一，存在并关系的产生式中选哪一个；其二，一个产生式的多个嵌套产生式中选哪一个。这也是文法产生二义性的来源。第一个选择可以就输入符号的情况加以选择，在自上而下的分析方法中表现为向前看几个符号的问题，在自下而上的分析方法中表现为不同项集之间的状态转移问题，此外，还有二义文法中利用优先级和结合性来额外处理的问题。第二个选择可以规定从左到右展开还是从右到左展开，从左到右的方法称作LL，从右到左的方法称作LR。第一个L是指的从左到右扫描输入文本，第二个是指的推导的展开次序。自下而上的分析方法虽然是归约式的，但其逆过程等价于一个从右到左的推导过程，因而常常被称作LR的。\n产生式模型的构建，将设计语言的问题转换为了设计产生式的问题，如何设计非终结符，如何规定非终结符的右端，选择设计多少个产生式，这是一个相对开放而又复杂的问题，并不在编译原理课程的讨论范围内。编译原理中关注和解决的问题是如何在给定了产生式集合的情况下，生成一个自动机，高效地完成匹配任务。\n编译原理中介绍了两种自动机，一种是不带栈的有穷状态自动机，另一种是带栈的有穷自动机。不带栈的有穷状态自动机通常被称作有穷状态机，通常包含一个状态转换的驱动程序、一个状态转换表、输入字符串和输出。带栈的有穷状态机通常被称作下推自动机，除了包含有穷状态机中的四种东西外，还包含一个不限大小的栈。虽然驱动程序和状态转换表两种自动机都有，但内容相似却不同，下推自动机的驱动程序中不只是移动输入和转移状态，还包括弹栈和入栈的操作。Lex可以用来将一组正则表达式生成一个有穷状态机，被用作词法分析器。Yacc可以用来将一组产生式生成一个下推自动机，被用作语法分析。正则文法能够表达的三种操作都能够用上下文无关无法表达，反之却不可以。如何选择哪些部分应该用正则表达，哪些部分应该用产生式表达，基本原则是如果能用正则就尽量用正则，如果不能则用产生式，例如括号、语句块、条件分支、循环、嵌套、递归等。\n若输入文本有错，报告错误的一个原则是，尽可能多、准确、快速地报告错误。若要达到多的目标，就要用到恐慌模式的思想，即碰到一个错误，记录下来，不要退出程序，消化错误，继续向前解析。采用的办法往往是丢弃掉一些输入，找到较为清晰的同步词法单元。若要达到准确的目标，就要用到短语层次的恢复策略，为不同的状态转移动作设计专门的报错例程。若要达到快速的目标，主要还是在于保证匹配算法本身的效率，与报告错误的处理关系不是太大，但也要尽量减小错误恢复的空间开销。\n","date":"2020-05-17T00:00:00Z","permalink":"/posts/%E7%BC%96%E8%AF%91%E5%99%A8%E5%89%8D%E7%AB%AF%E5%9B%9E%E9%A1%BE%E4%B8%8A/","title":"编译器前端回顾（上）"},{"content":"当心真正变得开放，一切障碍都会很快从眼前消失。例如，自以为能力不如己者的升职。职位和社会角色只是让心暂时安住的一个外在反馈，并不是心的本来面目，也不是能够永久安住心的力量，开放的心，不仅不会在意他人的职位和社会角色，更不会在意自己的职位和社会角色，所在意的，甚至都不应该是所共同追求的物质利益，而是让周围人的心能够变得更加开放。我的心还不够开放，因为我还在思考这些在意和不在意、开放和不开放。\n当心真正变得开放，能够不被年龄和日常经验所束缚，不被深信不移的观念基座所束缚。我不止一次感受到日常的年龄和心的年龄是不对等的两种观念，这种不对等不仅仅是日常人们所说的年轻人显得老成或是老年人显得像小孩子，而是应该从统计角度把心的年龄的范围扩大，不应该是120岁以内，而是一个更加宽广的范围。在这个宽广的范围中，日常的年龄、性格、基因、性别、思想和行为都只是一种投影和简化，肤色、地域、时代、文化、社会角色和社会关系都是心的年龄简化之后的再加工。深信的观念基座当中比年龄和岁月更难摆脱的是同一律和因果律。我的心还不够开放，因为我对衰老和死亡、舍弃和失去还难以坦然面对，无法真正感受到其所带来的慈悲和喜乐。\n","date":"2020-01-21T00:00:00Z","permalink":"/posts/%E5%BC%80%E6%94%BE%E7%9A%84%E5%BF%83/","title":"开放的心"},{"content":"不知如何选择（Deal with ambiguity）和不知未来如何（Deal with uncertainty）是两个不同的人生困扰。不知如何选择，至少有选择可选，如何找出选项，应用别人发现的技巧，刻意训练总能掌握，而不知未来如何则可能陷入茫然，也可能陷入混乱。茫然的状态是混沌，不同于混乱。混沌在于没有形态，而混乱则有形态。在有形态中，形式化混乱，提出问题，找出选项，追问意义，排排优先级，列出解决方案，对比方案，挑出中道，排除干扰，找出关键路径，照此实践，寻求反馈，迭代问题，迭代解决方案，以维持既定的秩序，防止陷入下一阶段的混乱。世上的聪明人都会试图让自己避开茫然和混沌的状态，因为那样是于生存不利，于竞争不利的。可思维是如何由混沌转向混乱，为何竞争躲也躲不开，为何生存躲也躲不开，要看到这些，大概只是个眼光问题，或是个态度问题，试图解构这样的过程和致力于回答相关的问题，无异于以卵击石。思维孕育于混沌之中，思维若要从混沌之中解脱出来，迄今也只有佛陀确定地说找到一条解脱之道。\n--\n听Kelly Wiggins讲_Why Didn’t I Think of That? Techniques for Dealing with Ambiguity_所想到的\n","date":"2019-10-29T00:00:00Z","permalink":"/posts/%E4%B8%A4%E4%B8%AA%E5%9B%B0%E6%89%B0/","title":"两个困扰"},{"content":"步入初中后，想来是11岁时，我的人生难再有游戏心态，因而我也基本上杜绝了主动玩任何形式的虚拟游戏，不论是桌游、竞技比赛还是电脑游戏；偶尔生活中，当痛苦于精神上的压力和无聊而逃避时，有捡起来过；可参加工作以来，没有追求学术成果的压力，读书的兴趣反倒高涨起来，虚拟游戏就基本不碰了。这里所讨论的游戏心态就是人们一以贯之通常所理解的，为了交际、为了填满欲望、为了躲避压力和无聊而持有的一种生活态度。\n人生本就可以看作一场游戏，身处其中，无从躲避，近两年来，我渐渐对高中时就生起的为他人而活、不执着于所追求之事物的我重新生起了深深的认同和钦佩，多年来，在这点上，我有过摆动，但从未有过动摇。与别人分享这点人生感悟时，我愿意委婉地去表露心声，如同J.K.罗琳通过小说去诉说那样，只有渴望得到而不使用的人才能获得，爱的获得如是、精神自足的获得如是，我想事业、财富、声望的获得也大概如是。我应当持有这样的一种心态去面对人生这场游戏。\n不执着于所追求之事物似乎是我的天性，可为他人而活，当有哪些实际行动呢？\n只有把钱捐出去让自己变穷才叫为他人而活吗？只有放弃一切追求孝敬父母才叫为他人而活吗？只有不计回报抚养子女才叫为他人而活吗？为他人而活是为了他人的利益吗？可究竟为的是什么利益呢？是情感的满足还是金钱的满足？是怎样的情感满足？若是伤害了我，伤害了别人，那也要满足吗？是怎样的金钱满足？买下一辆车，买下一座楼？金钱到底满足了什么？这些问题可以列得没有穷尽，也可以列得深不见底。\n于我而言，我想实际的行动就是让我每时每刻的言语、表情、文字和肢体动作在以某种方式面对另外一个人或一群人的时候都能够让那一个人或是一群人感受到我的真和善，有人大概会觉得这样的行为是戴了面具的真和善，可若是活着的每时每刻都戴着这样的面具，那带与不带面具也就没有了差别。实际行动中最为艰难的并不是面对另外一个人或一群人，而是我要能够将我自己也作为他人，也如此的对我自己这个他人采取这样的行动，让我感受到产生的来自于我的真和善。我应当坚持这样的实际行动去面对人生这场游戏。\n","date":"2019-10-17T00:00:00Z","permalink":"/posts/%E4%BA%BA%E7%94%9F%E6%B8%B8%E6%88%8F/","title":"人生游戏"},{"content":"人们会苦恼于无法住大房子、上好学校、接受贵族教育，会苦恼于他人的铺张浪费、奢淫无度、拍马逢迎，会苦恼于上层社会享有的无上特权，我的心灵对这些的感受，有，但几乎是转瞬即逝的，从不会停留，故而我也从来不会拿这些与人当谈资。我不清楚有多少人有多少时刻真的有这些苦恼，我从没有自发地产生过这些烦恼。听到饭桌上大家拿这些当谈资，我受到了些刺激，我想我需要回归内心的平静，这是我写这篇杂谈的原因。\n我被刺激的原因是什么，别说别人不知道，受刺激的我都不知道。我是在跟他人唱反调来显得与众不同吗？我可以立刻说不是，接受传统文化浸染的人，都是能少一事，绝不多一事，枪打出头鸟、明哲保身类的道理，不用特意教也学得会。并且我天然地不喜欢人们之间作标签上的比较，比较是产生新观念的手段和方法，但绝不是操控意志和情绪的主要动力。\n我想我被刺激的最直接的原因是，我太想让人认同我的观念、认同我，这难道是基因在作祟，不仅要的是生理上的遗传和控制力，还要精神上的同化和控制力。有趣的是，我的观念源自我的经历、我的感受和我的思维，哪里是举几个例子就能说清楚的。闲谈中，我不会用人生的价值和意义、生命轮回、人生真谛这样的一些词汇，容易遭人反感，容易让人觉得做人浮夸，容易被人贴上政治、宗教的标签，因为这些词汇在天生戴着眼镜的人们看来，含义早已沦为空洞和虚无的说教。避开这些词汇，谈寿命、谈感悟、谈天文、谈地理，总显得单薄和不着边际，没有逻辑关系。人们似乎害怕在饭桌上谈一些不务实的东西，但在我戴着的眼镜看来，人们在刻意避开的话题反倒是务实的。诸如，我是因何而选择结婚？我是因何而躲避结婚？我是因何而选择生孩子？我是因何而觉得我的孩子可爱？我是因何而觉得我的孩子该获得比别的孩子更好的关怀？我是因何而觉得我生的孩子就是我生命的延续？我是因何而觉得我的人生的价值就在于教育后代？我是因何而觉得以一百年为时间尺度去谈论就是科幻？我是因何而觉得谈论五十六亿七千万年的世界就是迷信？我是因何而觉得我是在把控当下？我是因何而被迫来到这个世界？\n我希望人们诉说烦恼时，能多考虑些细节和用些真情，不要将细节放在充实诸如权力、欲望、特权这些色彩浓厚虚妄不实的观念上面，而应该放在拿自己的心灵去拷问那一群自己不满的心灵上面。那个把皇帝看不到之处的鲜花都装点的艳丽绚烂、彰显时代物质富足的故事，为何成为了装点布置官员的逢迎拍马和对贫苦百姓的压榨，却不能是称颂装点布置官员的一丝不苟和给执着于追求阶级上升的人看到极尽奢华该有的样子以活下去的动力。有趣的是，人们很乐得用符号和既定的观念去讨论社会资源分配的问题，鲜有人有精力基于一个个被拷问和质疑的心灵之上去讨论资源分配问题。人们定会觉得这样的反问很是荒诞，同样荒诞而我依旧充满好奇的问题还有，地球为什么把淡水都弄到了南极，为何生命形式要依托于资源而存在。怕承认生活荒诞性的人似乎在抱着这样的想法：一切跟人斗的我不惧怕，跟天斗的我就认怂，至于天人之边界和期限在何方与何时，何须我去关心，反正我只活这几十年；这样的心灵大概是乐得忍受轮回之苦的。人们不怕被自己的五官感受所欺骗，因为还有思维、逻辑和心灵去增强分辨力，然而对于自己的思维和逻辑，许多人却任其欺骗，沉浸其中，无法自拔。\n文明的体系结构 - 颜色越浅越虚幻，颜色越深越贴近无可言说之实在 我说我感受到社会道德整体在下滑，说的是人们更多地在关注外在和表象，而且不认为外在和表象是内在和核心的显现（图里颜色越深的层级越靠近核心）。当问到物质、能量、生命和意志从何而生，人们多诉诸于科学、哲学、神秘力量或是流行的虚妄观念。科学的许多结论并不比科学这两个字本身显得更科学。流行的虚妄观念如一剂镇定剂，给了人们抱团取暖，寻找认同感的力量。我大概是因为近两年圣贤书读得多了起来，整天跟故去的人来往，大概忘记了活着的人为何而活着。\n我之反对并未在反对他人对住大房子、上好学校、接受贵族教育之向往，也不是在赞同铺张浪费、奢淫无度、拍马逢迎，更不是在为权力的滥用和所谓的上层社会享有的特权找说辞，而是在忧虑为什么人们都执着于追求一些无法选择的东西，执着于思维之观念会因努力或者反对而获得，执着于存在权力这样虚无的观念，人们乐于空谈听得的只言片语和看得的零碎场面，便将这些言语和场面附着到某个观念之上去寻求认同。苦恼于无关乎活着的意义之外问题的人，大概也难以理解患有冒名顶替综合症的人是种怎样的感受。\n我为何会因他人执着于无关乎超脱生死和病痛折磨的攀比心而心绪不宁、精神错乱呢？我想还是因为我的分别念难以消除，我和他人无法共情，才显得无法共理与共信。深层次的原因在于我没有相信生命最大的意义在于超脱生死和摆脱无聊与病痛折磨存在之永恒，也在于我对他人相信的人生意义或所执观念的不屑和轻蔑。这些原因都令我总难以摆脱分别我与他的念想。我应该去喜欢手足无错的我，亦应该去喜欢不被理解的我，也应该不惧看似失态的我。\n人们时常执着于思维之观念会因努力或者反对而获得，却不觉得追求与获得的东西必然不是所执着的思维之观念。此外，还时常不承认当下所闻、所见、所想之积极意义。\n人们总爱谈自由，但所求的自由是什么，于我而言大概是摆脱一切的束缚与依赖的绝对自由，否则我不知道其他的是否是真的自由，我感受到其他人说的自由，不过都是在找寻另一副枷锁罢了。人们总爱谈财务自由、按需分配的自由，所谓的财务和需求本都是枷锁，跟自由有什么关系呢。大概我所求之自由不应该叫自由，因为自由两个字的任何形态本也都是枷锁。\n我应该放下这层烦恼，免疫刺激，寻求内心的平静。\n","date":"2019-09-21T00:00:00Z","permalink":"/posts/%E6%9D%82%E8%B0%88%E7%83%A6%E6%81%BC/","title":"杂谈烦恼"},{"content":"求知欲是种怎样的欲望呢。\n我想从表象上来看，是对知识本身的渴望，这样的渴望的心理动机中，有以横向的攀比心为主的外部刺激，也有以纵向的恐惧心为主的内部刺激。攀比心较恐惧心理更为浅，因为攀比的动因也可能来自恐惧。恐惧心既在于对无限和未知的无法预知和无法触碰，也在于沉静下来后对当下感受到空荡荡的落魄、无法暂停和难以掌控。求知的行为能够满足攀比心、消除恐惧心。\n从深层上来看，是本性回归真相的一种天然倾向。求知欲是个很西化的词语，因为知识这个名词本就来自西方。在东方的传统文化中，我能想到与之相关的描述是“朝闻道，夕死可矣”。对道的记录、论述，从来都是玄之又玄的。西方能称得上玄的，是量子物理学、形而上学、神学。玄之所以为玄不在于不合观测和检验，而在于无法用语言形式化、无法下落为器、无法用逻辑去审视，因为形式化本身、器物本身、逻辑本身都已经是一种形式化、一种器物、一种逻辑。深层的求知欲——本性中的倾向——是一种没有玄的束缚的存在。\n","date":"2019-09-06T00:00:00Z","permalink":"/posts/%E6%B1%82%E7%9F%A5%E6%AC%B2/","title":"求知欲"},{"content":"问题 单位正方形内两个随机点的距离期望是多少？\n求解因由 何昆师兄博士毕业之际，小龙师兄发朋友圈称赞其深刻的数学思维时，提到这个问题，引起了我的兴趣。我的数学天分一般，小时候没出现机缘参加数学竞赛的训练，但对欣赏数学形式的优美这件事情从来都有着强烈的共鸣，特别是通过复杂的推导过程得到简洁的解析解之后。\n上学读书时候，我对随机和概率这样的观念和工具总是不太认同，这大概也源于我认知天性中对殊相比共相更贴近真相的一种倾向。不过，在阅读了《复杂》和一些量子力学的科普读物后，我渐渐感受到随机和概率是当下和未来最具确定性的工具，虽然局限性非常明显，即需要大量的观察和经验，且多适用于集体行为的预测。不过话又说回来，这本也是当下科学方法论的局限。语言文字和符号的局限性数学语言无法躲避，如今科学方法论的局限性，数学也难以躲避，可是要说发现形式上的美感这件事情，随机计算领域应该蕴藏丰富，聊以慰藉受困于苦痛中的人们。\n解后感受 这个问题的解析解形式很漂亮，求解过程也非常有趣，值得记录和分享。\n思考过程 问题中的关键词是随机点、距离和期望，需要先回顾这几个概念才好继续往下走。我的回顾方法是把问题简化为一维的问题，即\n单位长度上两个随机点的距离期望是多少？\n先看单位长度上一个点的随机。仔细考量，发现，能从两个角度来思考：分布律和概率密度函数。\n这两个角度能够通过几何方法产生关联和替换，但是彼此之间有着鲜明的鸿沟，即不是一样的东西。人们常讲“点构成线，线构成面，面构成体”，这是分布律的眼光，不是概率密度函数的眼光。通过分布律的眼光，才产生了极限、无穷多的势这样的观念。以概率密度函数的眼光来看，线和点完全就是不一样的两种东西，任意一段线可以由单位的线段计数组成，但绝对不是由点组成。再举例来讲，数字1既用来表示单位长度的线段，也用来表示单位大小的正方形，也用来表示单位大小的立方体。集合和映射的出现，丰富了代数手段，却容易让人忘记数字所代表的含义。数字再抽象，脱离了所表示的东西就显得毫无意义，推导本身也变得荒唐。\n角度一：分布律 将单位长度转化为间距相等的\\(n\\)个点，这样随机两个点就容易找样本空间和组合数了。随机抛点的问题转变为了从\\(n\\)个数中有放回的取两次的问题。样本空间是\n$$n^2$$\n转换后，距离也容易度量，相邻两点间的距离是\n$$\\frac1 {n-1}$$\n有了这两个基础，两个随机点的距离取值范围就清楚了，即\n$$0, \\frac1 {n-1}, \\frac2 {n-1}, \u0026hellip;, \\frac{n-2} {n-1}, 1$$\n令\\(L\\)为随机事件——取任意两点——所得的距离，那么\n$$P(L=\\frac{k}{n-1})=\\frac{2(n-k)}{n^2}$$\n其中\n$$1 \\le k \\le n-1$$\n对于距离为\\(0\\)的情况，其概率为\n$$P(L=0)=\\frac{n}{n^2}=\\frac{1}{n}$$\n根据分布律的规定，必须有\n$$\\sum_{k=0}^{n-1}{P(L=\\frac{k}{n-1})}=1$$\n验证\n$$\\begin{align*} \\sum_{k=0}^{n-1}{P(L=\\frac{k}{n-1})} \u0026amp;=\\frac{1}{n^2}[n+2\\sum_{k=1}^{n-1}(n-k)] \\\\ \u0026amp;=\\frac{1}{n^2}[n+2\\cdot\\frac{n(n-1)}{2}] \\\\ \u0026amp;=1 \\end{align*}$$\n数学期望是对分布律上随机变量均值的描述，形式化为\n$$\\begin{align*} \\sum_{k=0}^{n-1}{L \\cdot P(L=\\frac{k}{n-1})}\u0026amp;=\\sum_{k=1}^{n-1}\\frac{2k(n-k)}{(n-1)n^2} \\\\ \u0026amp;=\\frac{2}{(n-1)n^2}\\sum_{k=1}^{n-1}{k(n-k)} \\\\ \u0026amp;=\\frac{n+1}{3n} \\end{align*}$$\n以\u0026quot;点密成线“的观点来看，当\\(n\\)趋于无穷时候，所得的期望值，即是单位长度上随机两点距离的期望值，为\n$$\\lim_{n \\to \\infty}{\\frac{n+1}{3n}}=\\frac{1}{3}$$\n角度二：概率密度函数 连续型的概率只能讲同等规模的描述对象事件发生的概率，所有低于此等规模的描述对象的概率都是零。比如单位长度上，只能问点落在某个长度区域内的概率是多少，这样的概率值会是一个非零的数，因为这样的计算的描述对象是线段，样本空间是线段长度，不是点。倘若问点落在1/2处的概率，那一定是零，因为点相对于线段是不同的东西，甚至都很难说是不同量级的东西，定义这样事件发生的概率为零也没什么坏处。连续型的概率函数的事件通常都写成区间的形式，比如单位长度上一个随机点落在某个区域\n$$[x_1, x_2]$$\n这个事件表示为\n$$x_1\\le X\\le x_2$$\n基于前面的讨论，这个事件也等于\n$$x_1\u0026lt; X \u0026lt; x_2$$\n略去区域左边的边界（一般是零或者负的无穷大），概率函数为\n$$P(X\\le x)=x$$\n其中\n$$X \\in [0,1], x \\in [0, 1], X\\le x \\subseteq [0, 1]$$\n概率密度函数表征概率函数的变化率，形式上为概率函数的导数，因而单位长度上随机均匀分布的概率密度函数是\n$$f(x)=1$$\n验证\n$$\\int_{0}^{1}f(x)\\mathrm{d}x=1$$\n令\\(L\\)为随机事件——任意两点随机抛落在单位长度区间内——所得的距离，那么随机事件可以表示为\n$$L=|X_1-X_2|\\le l$$\n其中\n$$0\\le l \\le 1$$\n且\\(X_1\\)与\\(X_2\\)服从前述的均匀分布，即满足\n$$0\\le X_1 \\le 1, 0\\le X_2 \\le 1$$\n事件所在的样本空间为单位正方形，事件发生区域为二维图像上的一块面积，如图所示灰色区域。\n令\\(y=X_2, x=X_1\\)用积分的方法求灰色区域的面积为\n$$\\begin{align*} \u0026amp;P(L\\le l) \\\\ \u0026amp;=\\int_0^l{(x+l)\\mathrm{d}x}+\\int_{l}^{1-l}{(2l)\\mathrm{d}x}+\\int_{1-l}^{1}(1-x+l)\\mathrm{d}x\\\\ \u0026amp;=2l-l^2 \\end{align*}$$\n验证当\\(l=1\\)时，有\n$$P(L\\le 1)=1$$\n对分布函数求导数，得到距离的概率密度函数为\n$$f(l)=2-2l$$\n求数学期望，得\n$$\\mathrm{E}(f(l))=\\int_0^1{l\\cdot (2-2l)\\mathrm{d}l}=\\frac{1}{3}$$\n不论用分布律还是概率密度函数推导都能得出一样的期望值，即1/3. 同理，原问题也能应用同样的两个思路求解，不过求解难度却明显增加，两种方法增加难度之处不大一样。\n解题过程 角度一：分布律 假设单位正方形内均匀分布了\n$$n^2$$\n个点，沿笛卡尔横纵坐标轴方向的相邻两点的距离均为\n$$\\frac{1}{n-1}$$\n每个点可以通过唯一的坐标定位，即有矩阵 $$\\frac{1}{n-1}\\cdot \\left[ \\begin{array}{c} (0, 0) \u0026amp; (0, 1) \u0026amp; \u0026hellip; \u0026amp; (0, n-1) \\\\ (1, 0) \u0026amp; (1, 1) \u0026amp; \u0026hellip; \u0026amp; (1, n-1) \\\\ \u0026hellip; \u0026amp; \u0026hellip; \u0026amp; \u0026hellip; \u0026amp; \u0026hellip; \\\\ (n-1,0) \u0026amp; (n-1,1) \u0026amp; \u0026hellip; \u0026amp; (n-1, n-1) \\end{array} \\right ] $$\n令随机变量\\(L\\)表示为随机从\\(n^2\\)个点中有放回的抽取两次所得两点之间的欧几里得距离，于是开始考察距离取值的可能性。假设抽取的两个点，坐标分别为\\((x_1, y_1)\\)与\\((x_2,y_2)\\)，根据一维问题的经验，知道横坐标和纵坐标差值的取值可能性的数量各有\\(n\\)种，即\n$$\\vec{d}=\\frac{1}{n-1}\\cdot \\left[ \\begin{array}{c} 0 \\\\ 1 \\\\ \u0026hellip; \\\\ n-1 \\end{array} \\right ] $$\n两点欧式距离取值如一下矩阵所示，即\n$$\\begin{align*} \\mathbf{D}\u0026amp;=\\frac{1}{n-1} \\\\ \u0026amp;\\cdot \\left[ \\begin{array}{c} 0 \u0026amp; 1 \u0026amp; \u0026hellip; \u0026amp; n-1 \\\\ 1 \u0026amp; \\sqrt{2} \u0026amp; \u0026hellip; \u0026amp; \\sqrt{1^2+(n-1)^2}\\\\ \u0026hellip; \u0026amp; \u0026hellip; \u0026amp; \u0026hellip; \u0026amp; \u0026hellip; \\\\ n-1 \u0026amp; \\sqrt{(n-1)^2+1^2} \u0026amp; \u0026hellip; \u0026amp; (n-1)\\sqrt{2} \\end{array} \\right ] \\end{align*}$$\n矩阵的每个格子中距离\\(d\\)的计算方法，即\n$$\\begin{align*} L\u0026amp;=d[(x_1, y_1), (x_2, y_2)] \\\\ \u0026amp;=d(|x_1-x_2|, |y_1-y_2|) \\\\ \u0026amp;=d(\\frac{k_1}{n-1}, \\frac{k_2}{n-1}) \\\\ \u0026amp;=\\frac{\\sqrt{k_1^2+k_2^2}}{n-1} \\end{align*}$$\n其中\n$$0\\le k_1, k_2 \\le n-1$$\n观察距离取值的矩阵\\(\\mathbf{D}\\)，发现其具有对称性，只看右上三角矩阵即可，也就是只看\n$$0\\le k_1 \\le k_2 \\le n-1$$\n的那些项。至此，事件发生的样本空间清楚了，取值有\n$$\\frac{n(n+1)}{2}$$\n种可能性。虽然样本空间只有平方的量级，但抽样方法却是在四次方的样本空间下发生的，因而还得通过有放回的抽取四个数值（\\(x_1, y_1, x_2, y_2\\)）的事件或者有放回的抽取两个数值（\\(k_1, k_2\\)）的事件来模拟。不管是哪种，都需要分四类情况计算事件发生的概率。\n情况一：\\(L=0\\) 也即\n$$x_1=x_2 \\wedge y_1=y_2$$\n或是\n$$k_1=k_2=0$$\n这种情况表明两次抽到了同一个点，样本空间是\\(n^4\\)，事件发生次数是\\(n^2\\)，因而事件发生概率为\n$$P(L=0)=\\frac{n^2}{n^4}=\\frac{1}{n^2}$$\n情况二：\\(L=\\frac{k}{n-1}\\) 也即\n$$x_1=x_2 \\wedge y_1 \\ne y_2 \\vee x_1 \\ne x_2 \\wedge y_1 = y_2 $$\n或是\n$$k=k_1 \\ne 0 \\wedge k_2 = 0 \\vee k=k2 \\ne 0 \\vee k_1=0$$\n这种情况表明两次抽到的两个点来自同一横坐标或者同一纵坐标上的不同点。差值为\n$$L=\\frac{k}{n-1}$$\n其中\n$$1\\le k \\le n-1$$\n的事件发生次数可以这样计算：假设两点横坐标相同，先选横坐标，有\n$$n$$\n种选法，满足差值的纵坐标有\n$$2(n-k)$$\n种选法。同理若两点纵坐标相同，根据对称性，得到相同的结论。综合得到事件发生的概率为\n$$P(L=\\frac{k}{n-1})=\\frac{4n(n-k)}{n^4}$$\n其中\n$$1\\le k \\le n-1$$\n情况三：\\(L=\\frac{\\sqrt{2}k}{n-1}\\) 也即\n$$|x_1-x_2|=|y_1-y_2| \\ne 0$$\n或者\n$$k=k_1=k_2 \\ne 0$$\n这种情况表明两个点的横坐标差值和纵坐标差值相等，给定差值，那么横纵坐标各只需要选一次。对于差值为\n$$L=\\frac{\\sqrt{2}k}{n-1}$$\n其中\n$$1\\le k \\le n-1$$\n的事件发生次数可以这样计算：选横坐标，有\n$$2(n-k)$$\n种选法；选纵坐标，也有这样多种选法。依据乘法原理，综合得到事件发生的概率为\n$$P(L=\\frac{\\sqrt{2}k}{n-1})=\\frac{4(n-k)^2}{n^4}$$\n其中\n$$1\\le k \\le n-1$$\n情况四：\\(L=\\frac{\\sqrt{k_1^2+k_2^2}}{n-1}\\) 也即\n$$|x_1-x_2|\\ne |y_1-y_2| \\ne 0$$\n或者\n$$k_1 \\ne k_2 \\ne 0$$\n这种情况对应到矩阵\\(\\mathbf{D}\\)上，就是除去首行、首列、对角线外的其余部分，因为横纵坐标差在距离的计算上具有对称性，因而最终算得的概率系数为8. 计算方法类似情况二和三。\n$$P(L=\\frac{\\sqrt{k_1^2+k_2^2}}{n-1})=\\frac{8(n-k_1)(n-k_2)}{n^4}$$\n其中\n$$1\\le k_1 \u0026lt; k_2 \\le n-1$$\n综合四种情况，得到分布律为\n$$\\left\\{\\begin{array}{llr} P(L=0)=\\frac{n^2}{n^4}=\\frac{1}{n^2} \\\\ P(L=\\frac{k}{n-1})=\\frac{4n(n-k)}{n^4} \u0026amp; 1\\le k \\le n-1 \\\\ P(L=\\frac{\\sqrt{2}k}{n-1})=\\frac{4(n-k)^2}{n^4} \u0026amp; 1\\le k \\le n-1\\\\ P(L=\\frac{\\sqrt{k_1^2+k_2^2}}{n-1})=\\frac{8(n-k_1)(n-k_2)}{n^4} \u0026amp; 1\\le k_1 \u0026lt; k_2 \\le n-1 \\end{array}\\right. $$\n验证所求分布律是否正确\n$$\\begin{align*} \u0026amp;P(L=0)+\\sum_{k=1}^{n-1}{P(L=\\frac{k}{n-1})} \\\\ \u0026amp;+\\sum_{k=1}^{n-1}{P(L=\\frac{\\sqrt{2}k}{n-1})} \\\\ \u0026amp;+\\sum_{k_1=1}^{n-2}{\\sum_{k_2=k_1+1}^{n-1}{P(L=\\frac{\\sqrt{k_1^2+k_2^2}}{n-1})}} \\\\ \u0026amp;=\\frac{1}{n^2}+\\frac{4}{n^3}\\sum_{k=1}^{n-1}{(n-k)} \\\\ \u0026amp;+\\frac{4}{n^4}\\sum_{k=1}^{n-1}{(n-k)^2} \\\\ \u0026amp;+\\frac{8}{n^4}\\sum_{k_1=1}^{n-2}{\\sum_{k_2=k_1+1}^{n-1}(n-k_1)(n-k_2)} \\\\ \u0026amp;=\\frac{1}{n^2}+\\frac{4}{n^3}\\cdot \\frac{n(n-1)}{2} \\\\ \u0026amp;+\\frac{4}{n^4}\\cdot \\frac{n(n-1)(2n-1)}{6}\\\\ \u0026amp;+\\frac{8}{n^4}\\cdot \\sum_{k_1=1}^{n-2}{(n-k_1)\\sum_{k_2=k_1+1}^{n-1}(n-k_2)} \\\\ \u0026amp;=\\frac{1}{n^2}+\\frac{4}{n^3}\\cdot \\frac{n(n-1)}{2} \\\\ \u0026amp;+\\frac{4}{n^4}\\cdot \\frac{n(n-1)(2n-1)}{6} \\\\ \u0026amp;+\\frac{8}{n^4}\\cdot \\sum_{k_1=1}^{n-2}{(n-k_1)^2(n-k_1-1)} \\\\ \u0026amp;=\\frac{2n-1}{n^2}+\\frac{4}{n^4}\\cdot \\frac{n(n-1)(2n-1)}{6} \\\\ \u0026amp;+\\frac{4}{n^4}\\cdot [(\\frac{n(n-1)}{2})^2-\\frac{n(n-1)(2n-1)}{6}] \\\\ \u0026amp;=\\frac{2n-1}{n^2}+\\frac{(n-1)^2}{n^2} \\\\ \u0026amp;=1 \\end{align*} $$\n该分布律的数学期望为\n$$\\begin{align*} \\mathrm{E_n}(L) \u0026amp;= 0\\times \\frac{1}{n^2} \\\\ \u0026amp;+ \\sum_{k=1}^{n-1}\\frac{k}{n-1}\\frac{4n(n-k)}{n^4} \\\\ \u0026amp;+ \\sum_{k=1}^{n-1}\\frac{\\sqrt{2}k}{n-1}\\frac{4(n-k)^2}{n^4} \\\\ \u0026amp;+ \\sum_{k_1=1}^{n-2}{\\sum_{k_2=k_1+1}^{n-1}\\frac{\\sqrt{k_1^2+k_2^2}}{n-1}\\frac{8(n-k_1)(n-k_2)}{n^4}} \\end{align*}$$\n所求的单位正方形中随机两点的数学期望为\n$$\\begin{align*} \\mathrm{E}(L) \u0026amp;=\\lim_{n\\to \\infty}\\mathrm{E_n}(L) \\\\ \u0026amp;=\\lim_{n\\to \\infty}\\sum_{k_1=1}^{n-2}{\\sum_{k_2=k_1+1}^{n-1}\\frac{\\sqrt{k_1^2+k_2^2}}{n-1}\\frac{8(n-k_1)(n-k_2)}{n^4}} \\end{align*}$$\n以上等式之所以成立在于当\\(n\\)趋于无穷大时，中间两项的分子都只是\\(n\\)的三次幂和四次幂，极限值都为零。对于第四项的和，我曾经一度寻求不等式放缩，但发现无论怎样放缩缝隙都非常大，并且不可能找到一个\\(k_1\\)和\\(k_2\\)构成的线性组合去替换\\(\\sqrt{k_1^2+k_2^2}\\)。其实当把极限的数学形式写出来后，应该容易联想到转换为积分计算能将问题简化，毕竟在\\(n\\)趋向于无穷大时，\\(n\\)的最高幂次的系数决定了最终的结果，于是\n$$\\begin{align*} \u0026amp;\\lim_{n\\to \\infty}\\mathrm{E_n}(L) \\\\ \u0026amp;=\\lim_{n\\to \\infty}\\frac{8}{(n-1)n^4}\\sum_{k_1=1}^{n-2}{\\sum_{k_2=k_1+1}^{n-1}\\sqrt{k_1^2+k_2^2}(n-k_1)(n-k_2)} \\\\ \u0026amp;=\\lim_{n\\to \\infty}\\frac{8}{(n-1)n^4}\\int_0^n\\int_x^n\\sqrt{x^2+y^2}(n-x)(n-y)dydx \\end{align*}$$\n根据对称性，有\n$$\\begin{align*} \u0026amp;\\int_0^n\\int_x^n\\sqrt{x^2+y^2}(n-x)(n-y)dydx \\\\ \u0026amp;=\\int_0^n\\int_0^x\\sqrt{x^2+y^2}(n-x)(n-y)dydx \\end{align*}$$\n观察积分区域，发现其为90度的等腰三角形，转换到极坐标系更容易计算，于是\n$$x=\\rho\\cos\\theta$$\n$$y=\\rho\\sin\\theta$$\n积分区域从\n$$0\\le x \\le n$$\n$$0\\le y \\le x$$\n变为\n$$0\\le \\theta \\le \\frac{\\pi}{4}$$\n$$0\\le \\rho \\le n\\sec\\theta$$\n有\n$$\\begin{align*} \u0026amp;\\int_0^n\\int_0^x\\sqrt{x^2+y^2}(n-x)(n-y)\\mathrm{d}y\\mathrm{d}x \\\\ \u0026amp;=\\int_0^{\\frac{\\pi}{4}}\\int_0^{n\\sec\\theta}\\rho(n-\\rho\\cos\\theta)(n-\\rho\\sin\\theta)\\rho\\mathrm{d}\\rho\\mathrm{d}\\theta \\end{align*}$$\n积分的内容展开后一共四项，根据积分的线性可叠加性，可以拆开逐项计算\n第一项： $$ \\begin{align*} \u0026amp;n^2\\int_0^{\\frac{\\pi}{4}}\\int_0^{n\\sec\\theta}\\rho^2\\mathrm{d}\\rho\\mathrm{d}\\theta \\\\ \u0026amp;=\\frac{n^5}{3}\\int_0^{\\frac{\\pi}{4}}\\sec^3\\theta\\mathrm{d}\\theta \\\\ \u0026amp;=\\frac{n^5}{3}\\cdot \\frac{1}{2}[\\frac{\\sin\\theta}{\\cos^2\\theta}+\\ln|\\tan\\theta+\\sec\\theta|]_0^{\\frac{\\pi}{4}} \\\\ \u0026amp;=\\frac{n^5}{6}(\\sqrt{2}+\\ln(1+\\sqrt{2})) \\end{align*}$$\n第二项： $$ \\begin{align*} n\\int_0^{\\frac{\\pi}{4}}\\cos\\theta\\int_0^{n\\sec\\theta}\\rho^3\\mathrm{d}\\rho\\mathrm{d}\\theta \u0026amp;=\\frac{n^5}{4}\\int_0^{\\frac{\\pi}{4}}\\sec^3\\theta\\mathrm{d}\\theta \\\\ \u0026amp;=\\frac{n^5}{8}(\\sqrt{2}+\\ln(1+\\sqrt{2})) \\end{align*}$$\n第三项： $$ \\begin{align*} n\\int_0^{\\frac{\\pi}{4}}\\sin\\theta\\int_0^{n\\sec\\theta}\\rho^3\\mathrm{d}\\rho\\mathrm{d}\\theta \u0026amp;=\\frac{n^5}{4}\\int_0^{\\frac{\\pi}{4}}\\sin\\theta\\sec^4\\theta\\mathrm{d}\\theta \\\\ \u0026amp;=\\frac{n^5}{4}\\int_0^{\\frac{\\pi}{4}}\\cos^{-4}\\theta\\mathrm{d}\\cos\\theta \\\\ \u0026amp;=\\frac{n^5}{12}(2\\sqrt{2}-1) \\end{align*}$$\n第四项： $$ \\begin{align*} \\int_0^{\\frac{\\pi}{4}}\\cos\\theta\\sin\\theta\\int_0^{n\\sec\\theta}\\rho^4\\mathrm{d}\\rho\\mathrm{d}\\theta \u0026amp;=\\frac{n^5}{5}\\int_0^{\\frac{\\pi}{4}}\\sin\\theta\\sec^4\\theta\\mathrm{d}\\theta \\\\ \u0026amp;=\\frac{n^5}{15}(2\\sqrt{2}-1) \\end{align*}$$\n将计算所得带回原式，合并化简得到\n$$\\begin{align*} \u0026amp;\\lim_{n\\to \\infty}\\mathrm{E_n}(L) \\\\ \u0026amp;=\\lim_{n\\to \\infty}\\frac{8}{(n-1)n^4}\\cdot \\frac{[5\\ln(1+\\sqrt{2})+\\sqrt{2}+2]n^5}{120} \\\\ \u0026amp;= \\frac{5\\ln(1+\\sqrt{2})+\\sqrt{2}+2}{15} \\\\ \u0026amp;\\approx {0.5214} \\end{align*}$$\n角度二：概率密度函数 类比一维的解法，令\\(L\\)为随机事件——任意两点随机抛落在单位正方形区间内——所得的距离，那么随机事件可以表示为\n$$L=\\sqrt{(X_1-X_2)^2+(Y_1-Y_2)^2}\\le l$$\n其中\n$$0\\le l \\le 1$$\n且\\((X_1, Y_1)\\)与\\((X_2, Y_2)\\)服从均匀分布\n$$P(X\\le x, Y\\le y)=xy$$\n其中\n$$X, Y \\in [0, 1]$$\n类比前面的思路，下一步要求概率分布\n$$P(L\\le l)=\\iiiint\\limits_{\\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\\le l}f(x_1,x_2,y_1,y_2)\\mathrm{d}x_1\\mathrm{d}x_2\\mathrm{d}y_1\\mathrm{d}y_2$$\n单位区域内均匀分布的概率密度函数始终为1，即\n$$f(x_1,x_2,y_1,y_2)=1$$\n求解以上四重积分的难点在于，难以直观地看到8个四维空间上的三维平体和1个四维空间上的三维曲体所围成的四维体的形状，从而难以直接写出分变量积分的形式。还需要进一步的思考，当下想到的思考方向是利用数形结合的方式研究三维平体和三维曲体的相交特点，找出分区域分变量积分的形式。类比一维问题中求解灰色区域面积的方法，这个四重积分有机会简化为三重积分或是二重积分。等有时间再来补充完这个解法。\n","date":"2019-08-17T00:00:00Z","permalink":"/posts/%E9%9A%8F%E6%9C%BA%E4%B8%A4%E7%82%B9%E8%B7%9D%E7%A6%BB%E7%9A%84%E6%9C%9F%E6%9C%9B/","title":"随机两点距离的期望"},{"content":"通信和控制是目的，计算和存储是手段，模块化是方法。\n通信和控制体现着两种截然不同的人生态度。通信强调的是信息交换，即信息在时空中的转移、流动，这样的交换一般是平等的，交换主体之间彼此互惠，协商互换。可惜，信息无法脱离物质而单独存在，故而需要依赖于某些介质，从而也必然存在着信息安全的问题。控制强调的是行为可预测，即信息的流动、物质的时空变换呈现出确定性的状态，要借助周期性的运动（时钟和计数）方能达成。世事无常，控制只能在可认知的时空边界中生效，并且还要承受可认知时空里复杂所带来的灾难，而通信的时空边界似乎能够不断地被突破，给人们带来无限的希望。\n计算和存储是时间和空间中乘载着通信信息的信息。计算是对算法执行过程的称谓，算法是对线性次序、非线性次序和重复结构的描述，以静态的源码，用动态的眼光，经过排列（旋转、组合）、搜索（查找、访问、移动）、变换（加运算）后，提取出用于通信的信息。存储是对信息的空间组织方式的称谓，信息的空间组织方式是无方向、可对称的，既可作为计算的操作原料，也能记录算法本身。通信和控制都需要借助计算和存储来完成，进行通信的信息和进行控制的信息也需要借助计算和存储来完成。\n模块化是控制复杂的有效方法，既符合人的直觉思维，又有强大的理性根基。说其符合直觉思维是因为直觉只能感知事物的表象，而模块化能够有效地封装起内部，只暴露出事物的表象，称之为接口，如果不运用理性，难以想象接口之下隐藏着什么。说其具有理性根基是因为模块化的可叠加性、依赖管理能够形式化，此外，完整的运用模块化，还需要人将注意力从接口毫无间断地转移到内部，并且既会自顶向下看，还会自底向上看，这需要多年的浸染和领悟。实际上，模块化都不只是计算机科学的方法论，它还是整个工程学认知论的核心，属原子论的变体。\n","date":"2019-06-15T00:00:00Z","permalink":"/posts/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6%E7%9A%84%E8%A6%81%E4%B9%89/","title":"计算机科学的要义"},{"content":"年轻人的孤独，并不那么难以忍受，至少有眼睛、耳朵、腿脚相伴，有时甚至会是一种抛开一切嘈杂去讨好心灵的享受，但老年人的孤独，我无法体会。感官失灵后，要如何去讨好心灵呢，大概需要让心灵去讨好自己吧。如果心灵失灵了呢，大概就是别人说的死亡吧。可见心灵是不好去讨好的，何必白费力气呢，最好的办法就是钝化它、冷落它，于是有人去一味地讨好感官，还有些人去一味地讨好别人，因为自己的死亡终是从别人口里说出来的，葬礼也是开给别人看的。\n","date":"2019-02-20T00:00:00Z","permalink":"/posts/%E5%AD%A4%E7%8B%AC/","title":"孤独"},{"content":"最近想到一个问题，发现了一个有趣的分布，姑且叫其全触分布。可能这个分布已经有了名字，不过翻了一遍概率论的书，似乎没有看到有谈过这个分布。\n初始问题 假设有两台服务器，各自有独立的缓存需要预热（即初始化缓存），而预热时只能通过相同的访问地址，访问负载均衡器之后，由负载均衡器等概率随机选择一台预热，问至少需要几次地址访问，才能保证两台服务器中的缓存都被预热过的概率超过99%？\n这个问题等价于一个投硬币的问题，问至少多少次伯努利试验后，才能保证正反面都出现过的概率超过99%？\n令随机事件\\(X\\)表示，第\\(n\\)次伯努利试验时，才使得正反面都出现过。显然，当\\(n\u0026lt;2\\)时，事件不会发生；当\\(n=2\\)时，一定是一次正面一次反面；当\\(n\u0026gt;2\\)时，一定是前\\(n-1\\)次都是某一面，剩下的第\\(n\\)次是另外一面。 据此知道，随机事件\\(X=n\\)的概率为\n$$P(X=n)=\\frac{1}{2^{n-1}}$$\n其中\\(n \\ge 2\\)，而当\\(n \u0026lt; 2\\)时，\\(P(X=n)=0\\)。\n验证所求分布律的正确性\n$$P(X\\ge 2)=\\frac{1}{2}+\\frac{1}{2^2}+\u0026hellip;+\\frac{1}{2^{n-1}}+\u0026hellip;=1$$\n分布应该如此。返回原始问题，得知在问，使得不等式\\(P(X\\le n)\\ge0.99\\)成立的最小的\\(n\\)为几。\n由于\n$$P(X\\le n)=P(X=2)+P(X=3)+\u0026hellip;+P(X=n)$$\n$$=1-\\frac{1}{2^{n-1}}$$\n求得\n$$n\\ge 2\\log_2{10}+1 \\thickapprox7.6$$\n所以，最小的\\(n\\)为8，即至少8次伯努利试验后才能保证正反面都出现过的概率超过99%。\n问题拓展到\\(m\\) 进一步，假设原始问题中不止两台机器，而是\\(m\\)台，伯努利试验中也不是投掷硬币，而是从\\(m\\)个小球中随机选，问至少多少次试验后，才能保证每台机器或者每个小球都出现过的概率超过99%？\n类似地，令随机事件\\(X\\)表示，第\\(n\\)次试验时，才使得每个小球都出现过。显然，当\\(n\u0026lt;m\\)时，事件不会发生；当\\(n=m\\)时，一定是每个小球都只出现了一次；当\\(n\u0026gt;m\\)时，一定是前\\(n-1\\)次出现了\\(m-1\\)个小球，第\\(n\\)次恰好出现的是剩下的那个小球。\n\\(n\\)次试验的概率空间容易计算，是\\(m^n\\)，因为每次都有\\(m\\)种选择，一共要选\\(n\\)次。对于出现随机事件\\(X\\)的次数，可以假设为\\(F(n,m)\\)次，即\\(F(n,m)\\)表示第\\(n\\)次试验时，才使得\\(m\\)个小球每个小球都出现过，也即\n$$P(X=n|m)=\\frac{F(n,m)}{m^n}$$\n因为\\(P(X=n|m)\\)表示第\\(n\\)次试验时，才使得每个小球都出现过，或每个机器都被触碰过，因而称作全触分布。\n最终求解的目标是\\(P(X\\le n | m)\\ge0.99\\)，而\n$$P(X\\le n | m)=\\sum_{i=m}^{n}{P(X=i|m)}=\\sum_{i=m}^{n}{\\frac{F(i,m)}{m^i}}$$\n所以，关键在于如何求解\\(F(n,m)\\)。前面分析到，当\\(n\u0026gt;m\\)时，一定是前\\(n-1\\)次出现了\\(m-1\\)个小球，第\\(n\\)次恰好出现的是剩下的那个小球。如果用\\(G(n,m)\\)表示\\(n\\)次试验中，\\(m\\)个小球都出现过的次数，那么\n$$F(n,m)=m \\cdot G(n-1,m-1)$$\n\\(G(n,m)\\)不同于\\(F(n,m)\\)的地方在于，\\(G(n,m)\\)没有限制直到第\\(n\\)次试验，才满足\\(m\\)个小球都出现过，据此，有\\(G(n,m)\\ge F(n,m)\\)。\n求解\\(G(n,m)\\)，可以将集合划分为两个相似的缩小集合。这个划分可以根据，\\(m\\)个小球中的某一个是否只出现在了第\\(n\\)次试验中。如果某一个小球只出现在第\\(n\\)次试验中，那么前\\(n-1\\)次，就只有\\(m-1\\)个小球出现，即共有\\(m\\cdot G(n-1, m-1)\\)种；如果同样的小球，不止出现在第\\(n\\)次试验中，那么前\\(n-1\\)次，仍旧有\\(m\\)个小球出现，共有\\(m\\cdot G(n-1, m)\\)种。综合可得\n$$G(n,m)=m\\cdot G(n-1,m-1) + m\\cdot G(n-1,m)$$\n由以上两个等式可以知道，\\(G(n,m)\\)具体比\\(F(n,m)\\)多了多少，多了\\(m\\cdot G(n-1, m)\\)，即\n$$G(n,m)-F(n,m)= m\\cdot G(n-1,m)$$\n在求解\\(G(n,m)\\)的解析形式前，根据定义能够得出以下两个恒等式，即\n当\\(n\u0026lt;m\\)时，\\(G(n,m)\\equiv 0\\)；\n当\\(n=m\\)时，\\(G(n,m)\\equiv 1\\) 。\n当求得解析解后，验证概率分布律时，将会再次通过代数的方式证明两个恒等式。 这是函数\\(G(n,m)\\)非常有趣的两个特性。\n求\\(G(n,m)\\)的解析解 直接通过\\(G(n,m)\\)的递推形式，求解析形式比较困难，可以尝试用数学归纳法，先从较小的\\(m\\)开始。\n当\\(m=1\\)时，\\(G(n,1) \\equiv 1\\)。\n当\\(m=2\\)时，\\(G(n,2) = 2G(n-1,2)+2\\)，解析解为\\(G(n,2)=2^n-2\\)。\n当\\(m=3\\)时，\\(G(n,3) = 3G(n-1,3)+3 \\times (2^{n-1}-2)\\)，解析解为\\(G(n,3)=3^n-3\\times 2^n+3\\)。\n当\\(m=4\\)时，\\(G(n,4) = 4G(n-1,4)+4 \\times (3^{n-1}-3\\times 2^{n-1}+3)\\)，解析解为\\(G(n,4)=4^n-4\\times 3^n + 6 \\times 2^n -4\\)。\n如果在求解到\\(m = 4\\)时，还没注意到组合系数的话，那大概需要补补组合数学基础了。\n有了组合系数的观察，一般地，\\(G(n,m) = \\sum _{k=0} ^{m} (-1)^k {m \\choose k} (m-k)^n\\)。\n将\\(m = 1, 2, 3,4\\)分别依次带入方程，得出同直接由递推式求得一致的结果。\n接下来验证，解析解能使递推式始终成立。由解析解方程，可知\n$$G(n-1,m-1) = \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} (m-1-k)^{n-1}$$\n$$G(n-1,m) = \\sum _{k=0} ^{m} (-1)^k {m \\choose k} (m-k)^{n-1}$$\n令第一式的\\(t=k+1\\)，则\n\\(G(n-1,m-1) = \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} (m-1-k)^{n-1}\\) \\(= \\sum _{t=1} ^{m} { (-1)^{t-1} {m-1 \\choose t-1} (m-t)^{n-1} }\\)\n于是\n\\(G(n-1,m-1) + G(n-1,m)\\)\n\\(= \\sum _{k=0} ^{m} (-1)^k {m \\choose k} (m-k)^{n-1} + \\sum _{t=1} ^{m} { (-1)^{t-1} {m-1 \\choose t-1} (m-t)^{n-1} } \\)\n\\( = m^{n-1} + \\sum _{k=1} ^{m} { (m-k)^{n-1} \\lgroup (-1)^k {m \\choose k} + (-1)^{k-1} {m-1 \\choose k-1} \\rgroup } \\)\n\\( =m^{n-1} + \\sum _{k=1} ^{m} { (-1)^k (m - k) ^ {n-1} \\lgroup {m \\choose k} - {m-1 \\choose k-1} \\rgroup } \\)\n\\( =m^{n-1} + \\sum _{k=1} ^{m} { (-1)^k (m - k) ^ {n-1} {m-1 \\choose k} } \\)\n\\( =m^{n} \\cdot \\frac{1}{m} + \\sum _{k=1} ^{m} { (-1)^k (m - k) ^ {n} {m-1 \\choose k} \\frac{m}{m-k} \\cdot \\frac{1}{m} } \\)\n\\( = \\frac{1}{m} \\cdot \\lgroup m^{n} + \\sum _{k=1} ^{m} { (-1)^k (m - k) ^ {n} {m \\choose k} } \\rgroup \\)\n\\( = \\frac{1}{m} \\cdot \\sum _{k=0} ^{m} { (-1)^k {m \\choose k} (m - k) ^ {n} } \\)\n所以\n\\(G(n,m)=m\\cdot G(n-1,m-1) + m\\cdot G(n-1,m)\\)成立。\n验证分布律的正确性 由\\(G(n,m) = \\sum _{k=0} ^{m} (-1)^k {m \\choose k} (m-k)^n\\)和\\(F(n,m)=m \\cdot G(n-1,m-1)\\)，得知\n$$F(n,m) = m \\cdot \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} (m-1-k)^{n-1}$$\n又\\(P(X=n|m)=\\frac{F(n,m)}{m^n}\\)\n所以\n$$P(X=n|m)= \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} \\frac {(m-1-k)^{n-1}} {m^{n-1}}$$\n正确的分布律应满足\\(P(X \\ge m|m) \\equiv 1\\)，即须证明\n$$\\sum _{n=m} ^{\\infty} {P(X=n|m)} \\equiv 1$$\n即证明\n$$\\sum _{n=m} ^{\\infty} { \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} \\frac {(m-1-k)^{n-1}} {m^{n-1}} } \\equiv 1$$\n即证明\n$$\\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} \\sum _{n=m} ^{\\infty} { ( 1- \\frac {1+k} {m} )^{n-1} } \\equiv 1$$\n即证明\n$$\\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} \\frac {m} {1+k} ( 1- \\frac {1+k} {m} )^{m-1} \\equiv 1$$\n即证明\n$$\\sum _{k=0} ^{m-1} (-1)^k {m \\choose 1+k} ( 1- \\frac {1+k} {m} )^{m-1} \\equiv 1$$\n即证明\n$$\\sum _{k=0} ^{m-1} (-1)^k {m \\choose 1+k} ( m-1-k )^{m-1} \\equiv m^{m-1}$$\n也即证明\n$$\\sum _{k=0} ^{m} (-1)^k {m \\choose k} ( m-k )^{m-1} \\equiv 0$$\n观察恒等式左边，发现似曾相识，回看\\(G(n,m)\\)的解释式\n$$G(n,m) = \\sum _{k=0} ^{m} (-1)^k {m \\choose k} (m-k)^n$$\n发现\n$$\\sum _{k=0} ^{m} (-1)^k {m \\choose k} ( m-k )^{m-1} = G(m-1, m)$$\n根据前面的恒等关系\n当\\(n\u0026lt;m\\)时，\\(G(n,m)\\equiv 0\\)，得证。\n等式\\(\\sum _{k=0} ^{m} (-1)^k {m \\choose k} ( m-k )^{m-1} \\equiv 0\\)的常规证明 直接证明\\(G(m-1,m)\\equiv 0\\)，可能没有思路，可以先从\\(G(0,m)\\equiv 0\\)和\\(G(1,m)\\equiv 0\\)开始。\nA. 证明\\(G(0,m) = \\sum _{k=0} ^{m} (-1)^k {m \\choose k} \\equiv 0\\)\n这个恒等式，直接用二项式展开，即可证得。根据二项式定理，知道\n$$(x-1)^m = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot x^{m-k}$$\n令\\(x=1\\)，即得到\n$$0 = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k$$\n得证\\(G(0,m)\\equiv 0\\)。\nB. 证明\\(G(1,m) = \\sum _{k=0} ^{m} (-1)^k {m \\choose k} (m-k) \\equiv 0\\)\n类似于A步的证明，对二项式等式\n$$(x-1)^m = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot x^{m-k}$$\n两边同时求\\(x\\)的导数，得\n$$m\\cdot (x-1)^{m-1} = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot (m-k) x^{m-k-1}$$\n令\\(x=1\\)，即得到\n$$0 = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot (m-k)$$\n得证\\(G(1,m)\\equiv 0\\)。\nC. 证明\\(\\sum _{k=0} ^{m} (-1)^k {m \\choose k} ( m-k )^{m-1} \\equiv 0\\)\n类似于B步骤的证明，对二项式等式\n$$(x-1)^m = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot x^{m-k}$$\n两边同时求\\(x\\)的\\(n\\)阶导函数（其中\\(1 \\le n \\le m-1\\)），得\n$$\\frac{m!}{(m-n)!} \\cdot (x-1) = \\sum _{k=0} ^{m-n} {m \\choose k} (-1)^k \\cdot x^{m-k-n} \\cdot \\prod _{i=0} ^{n-1} (m-k-i)$$\n令\\(x=1\\)，即得到\n$$0 = \\sum _{k=0} ^{m-n} {m \\choose k} (-1)^k \\cdot \\prod _{i=0} ^{n-1} (m-k-i)$$\n因为当\\(m-n+1\\le k \\le m\\)时，有\n$$\\prod _{i=0} ^{n-1} (m-k-i)=0$$\n所以\n\\(0 = \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot \\prod _{i=0} ^{n-1} (m-k-i)\\)\n\\(= \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot \\sum _{i=1} ^{n} a_i \\cdot (m-k)^i\\)\n\\(= \\sum _{i=1} ^{n} a_i \\cdot \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot (m-k)^i\\)\n因为对于所有的\\(1 \\le n \\le m-1\\)，都有\n$$\\sum _{i=1} ^{n} a_i \\cdot \\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot (m-k)^i =0$$\n因而，不论常数\\(a_i\\)是多少，都有\n$$\\sum _{k=0} ^{m} {m \\choose k} (-1)^k \\cdot (m-k)^n =0$$\n成立。\n得证，当\\(1 \\le n \\le m-1\\)时，\n$$G(n,m)\\equiv 0$$\n\\(\\sum _{k=0} ^{m} (-1)^k {m \\choose k} ( m-k )^{m-1} \\equiv 0\\)显然是\\(n=m-1\\)时的情况。\n类似地，也能证得\\(G(m,m)\\equiv 1\\)。\n求解\\(P(X\\le n | m)\\ge0.99\\) 回到最初的目标，\n\\(P(X\\le n | m) = \\sum _{i=m} ^{n} {P(X=i|m)}\\)\n\\(= \\sum _{i=m} ^{n} \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} (1- \\frac{1+k}{m})^{i-1} \\)\n\\( = \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} \\sum _{i=m} ^{n} (1- \\frac{1+k}{m})^{i-1} \\)\n\\(= \\sum _{k=0} ^{m-1} (-1)^k {m-1 \\choose k} \\frac {m} {1+k} [ (1- \\frac{1+k}{m})^{m-1} - (1- \\frac{1+k}{m})^{n} ] \\)\n\\(= \\sum _{k=0} ^{m-1} (-1)^k {m \\choose k+1} (1- \\frac{1+k}{m})^{m-1} - \\sum _{k=0} ^{m-1} (-1)^k {m \\choose k+1} (1- \\frac{1+k}{m})^{n} \\)\n\\( = 1 - \\sum _{k=0} ^{m-1} (-1)^k {m \\choose k+1} (1- \\frac{1+k}{m})^{n} \\)\n若求\\(P(X\\le n | m)\\ge0.99\\)\n即求\n$$1 - \\sum _{k=0} ^{m-1} (-1)^k {m \\choose k+1} (1- \\frac{1+k}{m})^{n} \\ge 0.99$$\n即求\n$$\\sum _{k=0} ^{m-1} (-1)^k {m \\choose k+1} (1- \\frac{1+k}{m})^{n} \\le 0.01$$\n即求\n$$0.01 \\times m^n - \\sum _{k=0} ^{m-1} (-1)^k {m \\choose k+1} (m - 1 - k)^{n} \\ge 0$$\n即求\n$$0.01 \\times m^n - \\sum _{k=1} ^{m} (-1)^{k-1} {m \\choose k} (m - k)^{n} \\ge 0$$\n有此不等式，可知不同\\(m\\)时，满足不等式的\\(n\\)的最小取值，下表列举了前10项\nm 1 2 3 4 5 6 7 8 9 10 n 1 8 15 21 28 36 43 51 58 66 全触分布的分布律\n全触分布的累积分布函数\n","date":"2018-09-16T00:00:00Z","permalink":"/posts/%E5%85%A8%E8%A7%A6%E5%88%86%E5%B8%83/","title":"全触分布"},{"content":"汉语中的“研究”，虽用了两个动词，但望文生义，更像是从研究的结果来代指研究。研，本义是磨碎、碾碎的意思，自然是个动词，然而，大多数的研究并不涉及研碎、碾碎的动作，所以想来，研虽是个动词，在这里却是拿状态来拓展字本身的含义，研究的最终结果往往都是长篇大论，犹如将东西磨碎、碾碎之后细柔绵绵。究，本义是穷、尽的意思，既能说是动词，也能说是副词或形容词，有种追问到底，探求到枯竭、空、无的含义。从构词上来看，研究，既可以看作是联谓式的，也能看做是述宾式的。不论构词怎样，这个词汇的构成，反映了汉语中描述研究，更强调的是结果、状态，而非过程。借助多个别的动作或一个动作的特殊状态来引申出一个完全不同的新词汇是汉语构词中常用的方式，比如关心、出版、告别等。\n英语中的“research“，由前缀re-和单词search，表明了研究就是再次搜索、重复搜索，更多的在强调方法和过程。借助一个前缀和一个动词来加强、否定动词的含义，从而构造新词是英语构词中常用的方式，比如disclose、appear、equivocate等。英语中这种构词法不同于汉语的地方是加前缀前后的两个动词之间的联系并不需要类比和联想来完成。\n这样两种截然不同的构词方式，反映了两种风格迥异的思维方式，也同时对语言的使用者带来了巨大的影响。以我个人成长的经历来看，参加工作之前，对待研究，探索毫无目的、方法可言，甚至都不明白启发式的含义，以为就是随机的搜索。甚至都谈不上搜索，没有目的的搜索，也只能叫乱碰乱撞，效率无疑是低下的。那时的我可能事无巨细，喜欢整齐、像模像样的实验报告，喜欢东看西看，浮游在知识的汪洋大海中，张嘴吃自己喜欢吃的东西，不知身边的境况如何。如今，虽仍旧陷落在同样的海洋中，但却有意识地检验、审视到嘴边的任何一件东西，而后才再去做下一次的搜索。有意识的检验，是将到嘴边的东西分解、剖开了，捡关键的，将其放置在不同的情境中，去重新搜索、验证。这样的思维方式的转变，不仅仅能给自己的带来认识这片海洋的信心，更多地是利用这片广阔的海洋，来认识海洋之外的世界——物质的世界、精神的世界、周遭的环境和棘手的难题。\n","date":"2018-04-29T00:00:00Z","permalink":"/posts/%E5%AF%B9%E7%A0%94%E7%A9%B6%E7%9A%84%E4%B8%80%E7%82%B9%E6%83%B3%E6%B3%95/","title":"对研究的一点想法"},{"content":"《不要大惊小怪》是本有趣的小册子，引言中的例子就引人深思。题目虽然很容易，但抽取出背后的想问题的动机和方法却需要过去有一定量的实践和反思。\n原文的题目问：\n有两枚一模一样的硬币，它们半径相等，并排靠在一起，其中一枚固定不动。开始时一枚硬币上的箭头向上，将它沿着另一枚硬币的边缘无滑动地滚动，一直滚到这枚固定硬币的另一侧。那么现在滚动过来的硬币上那个箭头是向上还是向下？\n直觉上想起来转了半圈，那应该是向下吧，不过如果动手做下实验，立刻发现太过自信了，箭头还是向上。\n如果要明白为什么，自然需要做些分析，而分析的第一步是选好研究对象。\n如果选择了滚动硬币的圆心，观察其轨迹的变化，立刻能够得出圆心在半圈内整整转过了一周，自然箭头还是向上。如果选择了滚动硬币上其它的点，就不那么容易得出这个结论了，因为其它的点的轨迹是条心脏线。为此我写了动画模拟了整个过程。\n您的浏览器不支持Canvas API\n解决明白这个问题本身没有什么值得兴奋的，因为这是一个普通的中学生，甚至聪明的小学生就可以想明白的。真正值得兴奋的是我们能够比过去更加清晰地意识到选择好的研究对象的动机以及方法。\n研究对象选得不好会让解决方案变得复杂和偏离目标，我们的动机自然是让解决方案尽可能简单。\n我们选择好的研究对象的方法是什么呢？我想是对人的认知活动过程的深刻理解。既然要选择，那么说明被研究的物体不是单一的物体。圆是再简单不过的几何体，却也不是单一的概念构成的。数学上能抽象出圆心和半径的概念对其进行描述，圆心决定了圆的位置，半径决定了圆的大小。这两个概念的组合是描述一个圆最小的概念集合。数学和物理总给人简洁、优雅的感觉，就在于对于一个抽象的概念，它们经常可以找到一个最小的几个简单或者已知概念的最小集合对其进行描述。比如，研究概率分布这样难以捉摸的现象，数学家告诉我们只要去关注它的数字特征就能确定分布是什么样子。再比如，研究物体的受力分析，物理学家告诉我们只要去关注它的质心的受力情况，剩下的质点就很容易分析了。这样的例子不胜枚举。\n约翰·洛克给了我们理解人在建立复合观念时更加普遍的启示：\n人心在把自己的能力施用于简单的观念时，其作用约可分为三种：第一，它可以把几个简单观念合成一个复合观念，因而造成一切复杂观念。第二，它可以把两个观念（不论是简单的或复杂的）并列起来，同时观察，可是并不把它们结合为一；这样，它就得到它的一切关系观念。第三，它可以把连带的其他观念排斥于主要观念的真正存在以外；这便叫做抽象作用，这样就造成一切概括的观念，这就分明表示出，人类的能力同其作用方式，在物质世界方面同理性世界方面，都是一样的。\n虽然数学和物理中经典的例子不停地向我们展示这样的技巧，只是当遇到新问题时，我们的思维和注意力容易被复杂的细节和对象带偏，从而抓不住本质的对象。如果我们在遇到新问题难以找到方向时，不妨想一下约翰·洛克给我们的启示，我们一定不会太过迷茫。\n","date":"2018-01-23T00:00:00Z","permalink":"/posts/%E6%BB%9A%E5%8A%A8%E7%A1%AC%E5%B8%81%E7%9A%84%E5%90%AF%E7%A4%BA/","title":"滚动硬币的启示"},{"content":"年中在读《量子计算与量子信息原理》的时候，写了一篇《图灵停机问题的一个简单论述》的阅读笔记，对大学时没学明白的图灵停机问题有了一些基本认识。今天在读《复杂》的时候，里面采用了另外一种等价的说法，在符号形式上看起来略有差异，如今记录一下加深印象。\n回顾量子一书中的描述，先假设存在算法A具有判定任意算法是否能够停止运算的能力，用符号表述也就是\n对于算法T输入mh，可以停止运算时，A回答是 A(T(mh))=是\n对于算法T输入mf，不能停止运算时，A回答否 A(T(mf))=否\n现在构造算法B，对于A输出为是的，B算法不能停止运算 B(A(T(mh))=不\n对于A输出为否的，B算法可以停止运算 B(A(T(mf))=停\n此时，如果将算法B作为算法A和算法B的输入就会推出矛盾\n根据A算法具备的能力，那么以下的两个代入应该成立 A(B(A(T(mh)))=否 A(B(A(T(mf)))=是\n根据B算法具备的能力，那么以下的代入应该成立 B(A(B(A(T(mh))))=停 B(A(B(A(T(mf))))=不\n矛盾出现了，对于输入mh，既能停止运算，又不能停止运算；对于输入mf，既不能停止运算，有能停止运算。所以B不存在，A也不存在。\n复杂一书中的描述如下\nH算法（图灵机）可以判定任意M算法对于任意输入I的停机行为，即 对于M(I)可以停止，H(M, I)=是 对于M(I)不可停止，H(M, I)=否\n如果将M算法作为M的输入，那么根据前面的假设H也能够得到是与否的结论。不过，这时，我们去构造一个算法H\u0026rsquo;，对于M(M)可以停止的时候，H\u0026rsquo;算法不可停止；相反则课停止，即 对于M(M)可以停止，H\u0026rsquo;(M,M)=不 对于M(M)不可停止，H\u0026rsquo;(M,M)=停\n这时问H\u0026rsquo;(H\u0026rsquo;,H\u0026rsquo;)会如何呢？ 根据H\u0026rsquo;构造的逻辑，H\u0026rsquo;(H\u0026rsquo;)如果可以停止，那么H\u0026rsquo;(H\u0026rsquo;,H\u0026rsquo;)不能停止，而如果它不能停止，又是可停止的，于是得到矛盾。\n这两种叙述看起来有许多不同，但本质的两个方面是相同的。其一，算法本身可以作为算法的输入，这点观察不是显而易见的，并且也不那么容易理解。这点观察有个简单的等价问题就是理发师问题，此外，还有就是罗素的集合悖论以及哥德尔证明数学完备性的基础。拓展到计算机中，所有学过计算机软件理论的人都感到学习编译原理的难度要高过操作系统、计算机网络等，主要原因大概就是因为编译过程的输入、处理规则和输出都是程序，非常反直觉。其二，无矛盾是理性推理的基石，这点学过一些基础数学证明的人都曾会有些体会。\n","date":"2017-12-09T00:00:00Z","permalink":"/posts/%E5%9B%BE%E7%81%B5%E5%81%9C%E6%9C%BA%E9%97%AE%E9%A2%98%E7%9A%84%E4%B8%A4%E7%A7%8D%E7%AC%A6%E5%8F%B7%E8%A1%A8%E8%BF%B0/","title":"图灵停机问题的两种符号表述"},{"content":"——尾递归的应用\n这是《编程之美》中2.14节提出的一个问题，问题的描述为\n一个有N个整数元素的一维数组(A[0], A[1], \u0026hellip;, A[n-2], A[n-1])，这个数组有很多子数组，那么子数组之和的最大值是什么？\n以往遇到这种问题的第一种思维模式也像书中的第一种解法一样去枚举出所有的子数组，对每个子数组内部元素求和，然后找出所有和中最大的。这是一种分解问题的思路，但所分解的子问题已经偏离了原始的问题。比如第一步的分解就是枚举所有的子数组，单就这步就已经是\\(O(n^2)\\)了，而后的两个子问题，一个是内部元素求和，另一个是找出所有和中最大的，这两个问题与原问题也不具有太多的共性，因而能够由此想到最优的算法极为困难。\n书中的解法二用了递归分解子问题的思路，却没有给出适当的语言描述，使用了循环。用循环去描述，对思考者而言不是一种好的语言，正如我在《尾递归的启示》一篇中写的那样，循环是一种机器友好的语言。这篇文章，我将会用纯粹地过程调用的方式来完成这个问题的解答，最终得到的优化算法与《编程之美》中提到的最后一种解法是等价的。当然递归子问题的分解与解法二也不太一样。\n对于原问题，可以分解为以下两个子问题：\n求不包含A[0]的所有子数组之和的最大值； 求包含A[0]的所有子数组之和的最大值。 原问题的解就是两个子问题解的较大者。显然，第一个子问题是原问题的递归，不包含A[0]的所有子数组，意味着(A[1], A[2], \u0026hellip;, A[n-1])的所有子数组。第二个问题是一个新的子问题，但比原问题要简单的子问题。假设我们记原问题为sub_arr_max，数组A为arr，数组的起始坐标为s，结束坐标为e，第二个子问题为max_of_all_subs，那么以上的分解，很容易翻译为以下的代码\ndef sub_arr_max(arr, s, e): 接下来是如何解决子问题max_of_all_subs。先回顾这个子问题的含义，这个子问题是说所有包含arr[s]元素的子数组元素和中，最大的值。这个子问题可以进一步分解为两个子问题：\n求不包含arr[e]的数组中所有包含arr[s]的最大值； 求数组arr[s..e]所有元素的和。 这个问题的分解中，第一个子问题又一次是原问题的递归，而第二个子问题是一个更为简单的递归问题。假设记第二个子问题为sum_of_all，那么以上的问题分解可以立刻翻译为\ndef max_of_all_subs(arr, s, e): 解决子问题sum_of_all是一个常见的线性递归，可以表述为，当s \u0026gt; e时，\n\\(sum\\_of\\_all (arr, s, e) = \\) \\(sum\\_of\\_all(arr, e, e-1) + arr[e]\\)\n直接翻译以上的递归式就能得到下面的解法\ndef sum_of_all(arr, s, e): 以上就是一个完整可以运行的解法，并且很容易调试错误，作为寻找优化算法的起点。为了不偏离本文的核心要义，且不去分析这样的解法中有多少的重复计算和空间浪费。直接将三个过程依次改造为尾递归的形式，这个改造过程中，不仅会找到最优的解法，并且能够洞察原问题中的一些特殊性，算法分析也附带会变得清楚。\n第一步：改造sum_of_all sum_of_all方法是一个线性递归的过程，我们可以在参数中增加一个变量res来记录从第一个元素arr[s]开始累加到s[e]的结果，每次递归调用只需要增加s即可。这个改造过程与《尾递归的启示》中提到的阶乘的改造过程几乎是相同的。一种写法如下：\ndef tsum_of_all(arr, s, e, res): 为了区分与前面算法的不同，重命名为tsum_of_all，t代表tail recursion的意思。有了新方法，在max_of_all_subs中可以这样调用\ndef max_of_all_subs(arr, s, e): 或者\ndef max_of_all_subs(arr, s, e): 两种写法等价。这里之所以要写出这两种，其实是想提醒，新增变量的初始值一定要注意，0是个很特殊的值，有些情形下并不能初始为0，第二步的改造中就会遇到这样的问题。\n第二步：改造max_of_all_subs max_of_all_subs求解了arr[s], arr[s..s+1], arr[s..s+2], .., arr[s..e]中，所有数组各自求和中最大的那个。用动态规划的思路，就是从小的开始求解，arr[s]显然就是自己，而后的每一个，比如arr[s..s+i]，等于arr[s..s+i-1]的最大解和arr[s..s+i-1]的和加arr[s+i]两者比较的较大者。在求arr[s..s+i-1]时，可以保存两个结果，一个是arr[s..s+i-1]的最大解，记为res，另一个是arr[s..s+i-1]的和，记为ss，即sum_of_all问题已经融入到了问题的迭代中。改造后的算法如下\ndef tmax_of_all_subs(arr, s, e, res, ss): 为了区分与前面算法的不同，重命名为tmax_of_all_subs。当在sub_arr_max中使用这个方法时候，需要注意的是，初始值res不能为0，理由是如果数组中的元素都是负数，那么所有的子数组和都无法比0大，造成错误。因而调用时候要从第一个元素开始\ndef sub_arr_max(arr, s, e): 第三步：改造sub_arr_max 回顾改造尾递归的两个要素之一是从小问题开始，寻找合适的变量来记录中间结果。如果数组是一个元素，直接返回结果，如果是两个元素，我们可以记录一个元素时候的结果，然后同新加入元素之后的结构进行比较。最开始自顶向下考虑问题时，我们从A[0]元素开始划分，A[1..N-1]同原问题有着同样的结构，而从自底向上考虑时，可以反过来想，考虑到第i个元素时A[0..i-1]同原问题有着同样结构的子问题，而A[0..i]需要解决的是max_of_all_subs的问题。这时我们能够改写出一个tmax_of_all_subs的一个对称写法。\ndef tmax_of_all_subs(arr, s, e, res, ss): 在sub_arr_max中最终比较的两个对象，其一是与原问题有着同样结构子问题的值，我们可以用一个变量去记录这个值，其二是tmax_of_all_subs问题，我们不需要每次去重算，只需要保存arr[s..e-1]中的最大值，能比较的是保存的最大值+arr[e]和arr[e]的比较中较大的作为新的保存值。为什么保存的arr[s..e-1]中最大值可以加arr[e]？因为这个最大值一定包含arr[e-1]，维护了tmax_of_all_subs这个问题求值的结构。如同在第二步中省去sum_of_all一样，这个问题中我们一样可以省去max_of_all_subs。由此就得到了最终的解法\ndef tsub_arr_max(arr, s, e): 对照《编程之美》上的循环解法，容易看出，这两种写法运用了相同的思路，然而整个的思考过程却是不同的，对我而言，改写尾递归的方式更容易些。\n相关阅读\n尾递归的启示?⭐️⭐️⭐️⭐️⭐️ ","date":"2017-08-20T00:00:00Z","permalink":"/posts/%E6%B1%82%E6%95%B0%E7%BB%84%E7%9A%84%E5%AD%90%E6%95%B0%E7%BB%84%E4%B9%8B%E5%92%8C%E7%9A%84%E6%9C%80%E5%A4%A7%E5%80%BC/","title":"求数组的子数组之和的最大值"},{"content":"——读《计算机程序的构造和解释》第一章第二小节所想\n尾递归是指在过程调用中，递归调用过程本身的操作始终是过程的最后一步。举例来讲，计算阶乘的方法，根据定义，直接翻译成递归形式为\ndef factorial(n): if n == 1: return 1 else: return n * factorial(n-1) 这个递归中，最后一步操作是乘法，而非调用过程本身，因而不是尾递归。转换成尾递归的形式如下\ndef factorial(n): return factorial_iter(1, 1, n) def factorial_iter(product, counter, max_count): if counter \u0026gt; max_count: return product else: return factorial_iter(product*counter, counter+1, max_count) 使用尾递归的好处，可以从两方面来看，一则是同非尾递归过程比较的优势，另一则是同程序设计语言中专门的循环结构（也可以称作迭代结构）比较的优势。\n不论是同非尾递归过程比较还是专门的循环结构比较，都先需要明确的是过程调用意味着什么，过程到底是什么。\n初学程序设计的人会说，过程不就是一个函数么，接收一些输入，返回一些输出，有什么可以深究的呢。过程的概念初听，理解起来非常容易，但能清晰地想清楚如何利用好过程以及明白过程带来的意义并非显而易见。\n了解清楚过程，要从两个方面来看待，一方面是过程在如何影响我们设计和组织程序，另一方面是过程在如何指挥计算机执行任务。\n好的过程设计，会明确过程的输入和输出，过程的命名也明确意味着要执行的任务，整个过程如同黑盒子一般，除了依赖输入和输出之外，不会依赖其它的任何东西。物理世界中，人们生产的无数优秀的生活用品、科技产品都具有这个特性。比如水龙头，接水管的口径是明确的，操作水龙头闭合和打开的阀门是明确的，输出口的口径也是明确的，进而水流的速度也是可调控的。再比如白炽灯，螺纹接口的尺寸和样式是明确的，电灯消耗的电功率是明确的，输入的电压范围是明确的，电灯的材料是明确的，进而发光的亮度也是可调控的。物理世界中的物品，人们很容易注意到他们的依赖，也就是使用条件或者说输入和输出。当场景切换到计算机软件，逻辑的世界中，模块就如同物品，过程就是模块的基本构件。有人会觉得模块听起来像是静态的，过程听起来像是动态的，怎么能说是一回事。仔细想想，其实现实中的物品又有什么是完全静态的呢，不论水龙头还是白炽灯。从自然语言上来看，所有的动词又何尝不是一个名词呢，我们给一种动作起了个名字就是动词所表达的含义。逻辑的世界中，过程封装了一系列的指令用于去完成某个任务，而过程本身对设计者而言意味着一条新的计算机指令。软件本身就是一个复杂的过程，优秀的计算机软件都有着这样的设计。\n于计算机而言，一个过程有外部的环境，有内部的环境。设计良好的过程对外部的依赖应该仅局限于输入的参数提供的内容，暴露给外部环境的应该仅局限于输出的返回值。内部的环境不应该修改外部环境的任何内容，返回结果也应该始终稳定前后一致。过程的嵌套调用给环境的维护带来了一些开销。写过汇编语言的人知道每个调用指令执行时都要先将当前的寄存器状态压栈，然后才会加载新过程的指令。每个线程都会有各自的栈用来保存这些状态。高级语言中，也有类似的情形，当函数调用开始之后，实际参数替换了形式参数后，实际参数也都需要保存，以免出现调用返回之后找不到符号的问题。调用层次较多的非尾递归程序因为这样的原因，就需要更多的空间去保存调用前的参数状态，从而造成空间的浪费。然而尾递归却不用有这个忧虑，编译器通常会做优化，如果发现是尾递归，那么实际参数不会再被使用，调用之前的状态也就不必保存。\n非尾递归除了有明显的空间浪费外，往往还会有明显的重复计算，由于参数的保存，仅限于参数，并不会根据具体的问题，保存一些已经计算过的中间状态。这些重复计算在树形结构的调用中往往是巨大的。尾递归由于没有系统栈帮着保存状态，就要求程序设计者设计合理的参数来保存计算过程中的必要的中间状态，从而既减少了重复计算，又减少了空间浪费。\n拿前面阶乘的例子来看，product就是用来保存中间状态的参数，counter是用来控制迭代次数的参数。尾递归实现中通过增加这两个参数，将空间开销由O(n)减到了O(1)。阶乘的例子由于是线性递归，所以不存在重复计算，但即便如此，非尾递归的实现中也需要先展开再规约，而尾递归的实现中只需要一遍就能得到结果，计算量也会减少一半。\n很多的问题的递归解法，呈现出树形递归的特点，即原问题的解决依赖于多个相同子问题的解决，比如换零钱的问题。\n假设只有50美分、25美分、10美分、5美分和1美分的面值，如果将给定数额的钱用前面提到的五种面额兑换，那么有多少种换法？\n这个问题跟求组合数的问题非常类似，可以将原问题分解为两个子问题。第一，完全不用50美分兑换，用剩下的四种面值兑换给定额度的钱；第二，用一个50美分兑换，对于除去50美分剩下的钱再用五种面值去兑换。这两个子问题彼此互斥，所以求和就是原问题的解。用程序语言描述即为\ndef rec_count_change(amount): 这个解法显然不是尾递归，最后一步操作是加法，不过非尾递归的解法往往非常容易辅助在脑海中产生求解问题的分解结构。分解的结构是棵二叉树，树的叶子节点要么是0，要么是1，因而叶子的数目与问题的结果是同量级的，这其中的重复计算量是巨大的。当amount是100时，问题的结果是292；当amount是1000时，问题的结果是801,451。虽然amount只增长了10倍，但结果却增长了2700多倍，这是超线性的增长。此外，这棵树不太平衡，如果记rcc(amount, kinds_of_coins-1)为左子树，另外一个为右子树，那么由于kinds_of_coins很快就减到了0，所以左边的深度较浅，最左边的深度只有kinds_of_coins+1；右边由于50美分减得很快，深度也较浅，最右边的深度为int(amount/50)+1，最深的部分在中间为amount+kinds_of_coins+1，所以整棵树像是一串葡萄一样。最大的深度也意味空间开销与amount+kinds_of_coins是同量级的。\n将这个问题改造成尾递归的形式，需要两点技巧，第一，尾递归一般意味着自底向上地先求解最终问题依赖的子问题的结果，因而需要在参数中增加适当的变量，开辟适当的空间，用于存储中间子问题结果，空间的大小越小，不仅省空间，往往同时也会提升运行效率；第二，当问题中有两个以上的输入时，就需要找对迭代的方法和维度，这点往往对节省空间起着至关重要的作用。\n如果用表格记录所有可能子问题的结果，那么表格一定只有(amount+1)*kinds_of_coins的大小，共有kinds_of_coins行，amount+1列。在求解表格中任何一个格子中的值时，都只依赖于前一行同列（kinds_of_coins-1, amount）与同行前面某列（kinds_of_coins, amount-first_denomination(kinds_of_coins)）的值，如果我们逐行地填充表格，就不必要保存着整张表，而只需要一行的存储空间。这样的空间开销不会比非尾递归大，时间上要远好。想清楚了第一点技巧，还要想清第二点，也就是说，起始时候，amount从0开始，kinds_of_coins从1开始计算，到底是先固定amount为0不变，将所有的kinds_of_coins都算出来呢，还是相反将kinds_of_coins固定为1，而去计算出对应所有amount的值。其实在选择存储空间大小时候，就已经潜在回答了这个问题，我们选择了一行，即为后者。明白了改造尾递归的两个方面，改起算法来也不会非常困难。尾递归的解法为\ndef tail_rec_count_change(amount): return trcc(amount, 5, 0, 1, [0]*(amount+1)) def trcc(amount, kinds_of_coins, ca, ck, arr): if ck \u0026gt; kinds_of_coins: return arr[amount] elif ca \u0026gt; amount: return trcc(amount, kinds_of_coins, 0, ck+1, arr) else: if ca == 0: arr[ca] = 1 else: remain = ca - first_denomination(ck) if remain \u0026gt;= 0: arr[ca] = arr[ca] + arr[remain] return trcc(amount, kinds_of_coins, ca+1, ck, arr) 尾递归相比于专门的循环结构，既保持了原始递归分解的形状，又拥有了动态规划自底向上的实质。这两个特点是极其优秀的，人们思考问题时最自然的方式是自顶向下的分解，几乎所有的问题都如此，否则大型系统的构造无从谈起。从原始递归转换为尾递归时，设计者可以专注于寻找适当的存储空间，放在参数中即可，而专门的循环结构往往会干扰设计者的思路。循环结构中循环控制变量，会让人不停地去重复在大脑中运行循环，而不是去思考寻找适当的存储空间和解决小的子问题。我非常同意《计算机程序的构造和解释》一书中作者对尾递归存在意义的评价：“有了一个尾递归的实现，我们就可以利用常规的过程调用机制表述迭代，这也会使各种复杂的专用迭代结构变成不过是一些语法糖衣了”。面对复杂的算法，优先写出递归解法，再改造成尾递归形式，然后再用专用的循环结构去改造不失为一种好的策略。实际上，循环结构是机器友好的，并不是人类友好的，循环天然拥有着一种自底向上的特质，只适合于做，不适合于想。从尾递归改造成循环结构难度要小于从原始递归转变为尾递归。从原始递归转变为尾递归，需要思路上的转变，而从尾递归转变为循环结构，如同找了一些同义词，从新表达一个段落而已。\n然而，值得注意的是并不是所有的语言都适合写成尾递归的形式，很多解释型的语言并没有对尾递归做优化，比如上面所用的Python语言。编译型的语言多会对尾递归做优化，比如C、Java。我尝试在Python上运行tail_rec_count_change(1000)，结果抛出了RuntimeError: maximum recursion depth exceeded的异常，而在Java的虚拟机上运行，则会给出正常的结果。由此，尾递归适合用于辅助我们思考较为复杂的算法问题，最终实现时要改造为循环结构的迭代形式。\n后记 除了换零钱的例子外，求解组合数、求幂的O(log n)算法、求数组的子数组之和的最大值也都是良好的练习，相应的解法可以参考这里。\n相关阅读\n求数组的子数组之和的最大值?⭐️⭐️⭐️⭐️ ","date":"2017-08-19T00:00:00Z","permalink":"/posts/%E5%B0%BE%E9%80%92%E5%BD%92%E7%9A%84%E5%90%AF%E7%A4%BA/","title":"尾递归的启示"},{"content":"图灵停机问题问的是“能否设计一个算法，在判定任意的一段算法对给定的一些输入在有限步骤后停止运算时，返回是，而在判定任意的一段算法对给定的另外一些输入无法在有限步骤后停止运算时，返回否“。图灵的回答是这样的算法无法被设计出来。\n问题中所谓的算法等价于图灵机。\n假设存在算法A，具备这样的能力。设想对任意的算法T，对于输入mh，能够在有限步骤后停止运算，那么，此时算法A对于(T, mh)回答是。同样的算法T，对于输入mf，无法在有限步骤后停止运算，那么此时算法A对于(T, mf)回答否。\n这时，我们构造算法B，对于算法A判定回答是的输入mh，算法B不能在有限步骤后停止运算，而对于算法A判定回答否的输入mf，算法B在有限步骤后停止运算。如果算法A存在，那么一定能够设计出算法B。\n根据A具备的能力，算法B在输入为mf时，有限步骤后停止运算，A应该输出是，然而根据B的构造，凡是A输出是的输入，B应该无法在有限步骤后停止运算。这与前面说的“B在输入为mf时，有限步骤后停止运算”相矛盾。因此算法B不存在，因而算法A也不存在。\n有人说设计这类算法的困难之处在于给出出现无穷循环的条件。\n还有人从图灵停机问题上看出了人的不确定本质。\n我个人好奇的两个问题是，其一，人脑的计算能力和图灵机是否等价；其二，逻辑推理的最为锐利的武器就是推导出矛盾，因为我们观测到的现实的具象的某一个存在都应是无矛盾的，然而思维本身却不是无矛盾的，矛盾如何形式化，形式化后对解决现有逻辑无法解决的问题有帮助吗，我们有能力将具象的某一个存在也变成一个矛盾的综合体吗。\n本质的好奇在于思维和宇宙是什么关系。宇宙是否自洽，具象的存在是否无矛盾。是思维囊括了宇宙还是宇宙滋养了思维。如果宇宙自洽，具象无矛盾的，那么思维的能力似乎要强于宇宙。如果宇宙不自洽，那么思维能力只是宇宙的小部分。我说这段话的时候，自洽与非自洽已经在假设将宇宙给了某种定性，或许宇宙就像思维一样，是一个自洽和非自洽的综合体。我们的思维倾向于更加的符合某种逻辑性，而宇宙恰好是那种逻辑性的表述。\n","date":"2017-05-21T00:00:00Z","permalink":"/posts/%E5%9B%BE%E7%81%B5%E5%81%9C%E6%9C%BA%E9%97%AE%E9%A2%98%E7%9A%84%E4%B8%80%E4%B8%AA%E7%AE%80%E5%8D%95%E8%AE%BA%E8%BF%B0/","title":"图灵停机问题的一个简单论述"},{"content":"前辈的经验都说需要电话提前预约，需要问好网点是否有美元零钱。美元的整钱在国外也不容易找开。听了这些建议，我打了至少两三个电话，询问了哪些网点能够办理外币兑换业务，哪些网点清明节期间还在营业。客服的回复和营业点大堂的回复都是只有整钱。无奈之下，还是决定直接到网点询问。\n遂在招商银行的官网上找到了服务网点地图，发现离我最近的有货币兑换的网点是静安里支行。网点地图上连各个业务的排队信息都在实时更新，不禁又默默称赞招行的优质服务。\n到网点后，询问大堂工作人员，了解到，如果帐户中没有美元现钞，需要先办理购汇业务。购汇是对购买外国货币的简称，可以购买现汇或者现钞。如果要取美元现钞，那么就需要先用人民币购买美元现钞。对于现汇，是用于向境外转账业务时使用的一种货币形式，无法直接取得现钞。购买现汇和现钞的汇率都是一样的，不过当结汇的时候，现汇的汇率就比较高了。所以除非需要现钞，尽可能用现汇。\n购汇业务可以在机器上自助，或者手机银行办理。我在机器上自助购买了200美金的现钞，汇率是每100美金，需要691.47人民币。\n完成购汇业务后，自己的银行卡帐户中会生成200美金的现钞。这时可以办理外币的取现业务。柜台的工作人员手上还是有不少零钱的，之前完全没有必要电话预约和询问。最终给了我两张50的，两张20的和6张10块的。\n这次的教训是对于银行业务，了解够了网络上的信息，直接去网点办理就可以了，完全不用把精力耗在无谓的担心上。\n","date":"2017-04-04T00:00:00Z","permalink":"/posts/%E5%85%91%E6%8D%A2%E7%BE%8E%E5%85%83%E5%B0%8F%E8%AE%B0/","title":"兑换美元小记"},{"content":" 有\\(n\\)根棍子，棍子\\(i\\)的长度为\\(a_i\\)。想要从中选出3根棍子组成周长尽可能长的三角形。请输出最大周长的三根棍子，若无法组成三角形则输出空字符串。\n限制条件 \\(3\\le n\\le 100\\) \\(1\\le a_i\\le 10^6\\)\n例如，\n输入： 2,3,4,5,10 输出： 3,4,5 输入： 4,5,10,20 输出： [空行] 众所周知，满足三角形的条件为任意两边之和大于第三边，略微一想，等价于两短边之和大于最长边。知道这个条件后，立刻有了穷举的思路，利用三重循环，遍历所有可能的三元组，然后判断满足此条件的三元组周长是否大于已经发现的最大三元组周长，如果是，那么替换，否则继续找。寻找三元组有\\(C^3_n\\)种可能性，这是\\(O(n^3)\\)的算法。具体的实现可以参考这里解法一。\n实际上，由于题目限制了说\\(n\\)的范围仅在3到100之间，所以3次方也并没有多少计算，所以这样的解法也可行。\n不过对于\\(n\\)很大的情况，三次方的算法会有很多的冗余计算，常常较慢。这个问题是否有更快的解决办法。我们可以进一步形式化。假设选出的三条边为\\(a_i\\),\\(a_j\\),\\(a_k\\)，构成三角形的条件为\n\\(a_i\\le a_j\\le a_k\\) \\(2a_k\u0026lt;a_i+a_j+a_k\\le 3a_k\\)\n当\\(a_i\\le a_j\\le a_k\\)时，\\(a_i+a_j+a_k\\le 3a_k\\)是显然成立的，\\(2a_k\u0026lt;a_i+a_j+a_k\\)才是三角形成立的重要条件，变形移项后发现\\(a_i\u0026gt;a_k-a_j\\)。在充分考虑大小关系和移项后的不等式之后，很快会有第二种思路：先对\\(n\\)根棍子按长度从小到大排序，从大到小循环\\(a_k\\)和\\(a_j\\)，然后只要\\(a_{j-1}\u0026gt;a_k-a_j\\)，那么就找到了一个合理的三角形。为什么只要找\\(a_{j-1}\\)就可以呢，因为排序后，如果\\(a_{j-1}\\)都小于等于\\(a_k-a_j\\)，那么更前面的数字就更不用看了。这个解法只对\\(j\\)和\\(k\\)做了循环，所以复杂度为\\(O(n^2)\\)。具体的实现可以参考这里解法二。\n实测在\\(n\\)为200多时，解法一需要\\(1s\\)以上的时间，而解法二只需要几个毫秒。\n继续思考，还能更高效吗。前面形式化的时候，提到说\\(a_i+a_j+a_k\\le 3a_k\\)是显然成立的。不过即使是显然成立的条件，也依旧能够作为剪枝的条件，何况还是个上确界。在第二种思路的基础上，如果继续向下看的\\(a_k\\)都发现\\(3a_k\\)已经小于等于当前找到的最大的周长，那么其余的部分就没有看的的必要了。这有种贪心的意味在其中。这个剪枝可以让算法的效率比几个毫秒还更快。具体的实现参考这里解法三。\n实际上在想出解法二，论证为什么只要看\\(a_{j-1}\u0026gt;a_k-a_j\\)就可以的时候，我们就会产生一个猜想，最终的答案一定是排序后下标连续的三个数。对于\\(a_k\\)，周长的范围是大于\\(2a_k\\)，小于等于\\(3a_k\\)。由于\\(i\u0026lt;j\u0026lt;k\\)，那么必然满足小于等于\\(3a_k\\)的条件。对于下界，如果\\(a_{k-2}+a_{k-1}\\)都不能够大于\\(a_k\\)，那么也就不存在其它的\\(i\\)和\\(j\\)能满足大于\\(a_k\\)的条件了。所以只需要检查\\(a_{k-2}+a_{k-1}\u0026gt;a_{k}\\)即可。这样，只需要贪心地从最大的数字开始遍历就可以，最坏情况下是\\(O(n)\\)的复杂度。由此整个问题的瓶颈就转移给了排序。如果用基数或者计数排序，整个算法的复杂度就是\\(O(n)\\)了。具体的实现参考这里解法四。\n","date":"2017-02-25T00:00:00Z","permalink":"/posts/%E4%B8%89%E8%A7%92%E5%BD%A2%E5%91%A8%E9%95%BF/","title":"三角形周长"},{"content":" 像素密度和设备像素比的概念事实上比想象中的复杂，希望这篇文章能够消除开发者和设计师们的疑虑和错误认知\n显示器上常用的长度单位是像素（pixel），比如说一台显示器的分辨率是1280×800像素，一张照片的大小是1050×1500像素，一台照相机有300万像素。像素和物理上的长度单位不是等价的。物理上的长度是个连续的概念，所以物理上的长度单位也是连续的。像素是对显示器上的电子基础元器件或者图像文件的基础单元的抽象，是个具体离散的概念，只是用于计数，也没有平方、立方的概念。\n人对长度的感知，无非通过眼和手两种渠道。大多数时候用眼，少部分时候用手。举例来说用手的场景，比如写字、画画、投篮、扔标枪、射箭、做手术、开车等等，当然这些场景仍旧离不开眼的配合，不过手起了决定性的作用。具体地，以写字来看，普通的作文格子纸的格子大小为7.5mm×8mm，书写的汉字大小一般为3mm×3mm左右，所以普通人手能控制的精确度在1mm的数量级，书法家、画家和外科医生的手，应该能在0.1mm的数量级。相较而言，眼睛能够区分的精确度会更好，大约是0.02mm，原因是目前没有生产过比50分度更精确的游标卡尺，如果要更精确就需要借助一些物理量之间的转换去放大然后进行观测。不管精确度如何，都是对物理长度的感知。\n原始的像素密度 用像素去表示物理长度单位，需要一次转换，即单位英寸*的像素数，一般称作像素密度**。有些地方将像素密度写作PPI（pixels per inch)，而另外一些地方写作DPI（dots per inch），实际上都是一样的含义。这个类似的概念最早出现在印刷行业，印刷中的基本单位是点（Point, pt）[1]，著名的1个点代表1/72英寸已达成共识，因此也能说印刷标准中的点密度是72DPI。汉字印刷中常用的字体，小四是指12pt，即1/6inch或4.2mm，这意味着在不考虑字间距的情况下，1英寸能写6个小四的汉字。另外也能看出，一个小四的汉字是由12×12=144个点描绘出的图形。在高清的印刷中，多会选用300DPI，即单位英寸的点数是标准的4倍多，同样一个小四的汉字将需要50*50=2500个点描绘，自然更加高清。\n像素密度的概念很容易理解，但当应用到不同的场景后，特别是一些生产商偷换了概念后，问题就变得复杂了许多。\n先从最原始的像素密度含义说起。所有带显示器的硬件设备都会提供两个参数，总的像素数和屏幕尺寸。常见的屏幕都是长方形的***，所以一般爱用长乘宽的分辨率来说明总的像素数，比如文章一开头说的1280*800像素。用长乘宽的好处是屏幕比例也一目了然，同时在描述屏幕尺寸时候也可以简略地写几寸的屏幕，一般都用对角线的长度，这样显得屏幕比较大。有了像素数和屏幕尺寸，立即可以算出像素密度的值（表1列出了常见设备的像素密度比），这个值是所有屏幕的固有参数。像素密度越大，像素的物理长度就越小，同尺寸的屏幕就能放置更多的像素，设备就越有能力显示高像素数的图像，清晰度和细节由此增加。因而，像素密度是衡量显示器清晰度的重要指标。\n表1?常见设备的屏幕参数\n如果比较不同尺寸的屏幕，像素密度就无法作为唯一的清晰度衡量指标了。众所周知，人的眼球是凸透镜的结构，可以自由的调节焦距。面对不同的物体距离，清晰度就不单取决于像素密度了，和距屏幕的距离也有关系。一个简单的模型如图1所示，距离屏幕越远，像素大小可以取的越大，像素密度可以越小。换句话说，远距离的屏幕可以用较小的像素密度达到和距离近的屏幕一样的清晰度。前面提到人的眼睛能够区分的精确度大约是0.02mm，这实际上省略了一个前提是，距离大约20厘米的情况下，忽略了这个前提就无意义了。清晰度实际上是在考验人眼睛的精确度，也就是对长度的分辨能力。任何人站在一米开外都看不到0.02mm的长度。如果要达到0.02mm的精确度，20厘米左右的书面，需要1270DPI的像素密度；60厘米左右的电脑显示器，需要423DPI的像素密度；2米左右的电视机，需要127DPI；20米左右的电影荧幕，需要12.7DPI。通过这个关系，也就理解为什么手机屏幕的像素密度一般要高于显示器，而显示器要高于电视机。人类采集的图像和视频毕竟不能和自然本身相比，总有个限度，利用好像素密度，可以节省资源。\n图1 视距和分辨最短物理长度的关系示意图\n图像的“像素密度” 电脑的图片一般都有个图像的像素密度（Image DPI）的属性，Windows系统上还分水平分辨率和垂直分辨率。这个属性对于在显示器上显示图像没有任何的影响，对图像的文件大小也不会有任何的影响。显示器上影响图像显示的仅仅是图像尺寸（像素），像素越多，能展示的细节越多。图像的文件大小也与这个值没有任何关系，而是跟图像尺寸、图像格式和图像内容有关。图像尺寸越大，像素越多，需要编码的信息就越多，文件大小越大。图像的格式决定了图像存储时使用何种压缩算法，对于相同尺寸的图像，有损压缩的格式（比如JPEG）比无损压缩的格式（比如BMP）文件小。即使相同的算法，相同的尺寸，不同图像存储大小也有差异，单色的图像会小，内容丰富的图像会大。\n实际上，图像文件的元数据中提供DPI这个属性是为了打印照片用的。确定了图像尺寸和图像的“像素密度”，就能够确定打印时的照片的物理尺寸。由此可见，这里所谓的“像素密度”中的像素其实是打印机中的点，并非显示器中的像素，当然理解为图像文件中的像素也没问题。提到图像文件中的像素，不得不说一句，照相机的说明书中的像素一般指的是这个。我们总是听到照相机宣传语说几百万像素或者几千万像素，鲜有听说多少乘多少的像素的说法，意义正在于此。\nPhotoshop是修改图像尺寸和“像素密度”的有效工具，Mac上的Preview也能做到这点，Windows自带的图片浏览软件似乎不带这个功能。对于打印照片而言，了解常见的相片[2]和打印纸[3]的尺寸会对裁剪图像尺寸有所帮助。苹果给出的官方指南[4]，也是个不错的参考。\n字体的“像素密度” 显示器上显示字体的情况远比显示图像要复杂，“像素密度”再次被重新定义，这次改动的不是像素的含义，而是分母，物理长度的含义。\n先回到早期，苹果和微软第一次产生分歧的时候。20世纪80年代，苹果生产的Macintosh沿袭了印刷业的传统，用72个像素表示一个“英寸”。那时的阴极射线管（CTR）显示器中，一个像素的大小大约恰好是1/72英寸，所以纸面上印刷的同号字体与屏幕上的同号字体等大[5, 6]。然而，微软却用96个像素表示一个“英寸”，可以明显看出，这个“英寸”，在像素大小大约是1/72英寸的情况下，实际长度是1.3英寸。之所以这样做，有人分析说是因为微软认为人们看屏幕的距离一般比看纸面的距离多出了1/3，所以字体需要等比例放大[5]。96这个参数，一直沿用至今。从这次分歧可以看出，操作系统厂商，偷用了像素密度的概念，他们所谓的72DPI和96DPI中的1“英寸”都不是物理上的1英寸，为方便可以说是逻辑英寸。\n当下的屏幕，像素密度至少都在110PPI左右。不论是苹果的72DPI，还是微软的96DPI，逻辑的1英寸都比物理的1英寸要小。为此，我做了实际测量。以下的两个字“汉字”，是72号宋体字，可以写作72pt。在普通的Mac上，等于72px，在Windows上，等于96px（默认分辨率）。我预测在27英寸、分辨率为2560*1440的戴尔显示器上，像素密度为108PPI，Mac系统下，两个汉字的长度为3.4cm，误差不超过1mm；在14英寸、分辨率1366*768的Thinkpad显示器上，像素密度为113PPI，Windows系统下，两个汉字的长度为4.3cm，误差不超过1mm。实际测量后，结果和预测完全吻合。 汉字 纸面距离下的，两个72号字体物理长度应为2英寸，即5.08cm。以上两个显示器，使用距离都会比纸面远至少30%，甚至是3倍，而长度反而减少了33%和15%，显然，看起来会更加吃力。所以这样的显示器上，用12号字体，在Mac上就会不到3mm，加上距离的因素，至少应该使用14号字体才会显得舒服。\n对于像素密度在110PPI左右的电脑显示器，单个像素大小约0.2mm，虽然距离理想的423DPI（0.06mm）还有4倍的差距，不过对于大多数人已经足够用了，就好比普通的应用场景只需要1mm的精度，专业的应用场景才需要0.02mm甚至更高的精度。\n以这个4倍的差距来衡量移动手机屏幕，假设平均直视距离为15cm，理想的像素密度大约是1270DPI****，实际的像素密度是318PPI。查看表1，iPhone 6+的像素密度为461PPI，iPhone 6为326PPI，显示的清晰度能达到类似电脑显示器正常使用下的标准。\n回到字体上来，前面的“汉字”实验中，计算实际物理长度的方法是\n(操作系统DPI/72) * 字号 / 设备像素密度\n单位是英寸。对于普通的Mac系统，操作系统DPI是72，带入后，公式为\n字号/设备像素密度\n对于普通的Windows系统，操作系统DPI是96，带入后，公式为\n1.33 * 字号/设备像素密度\n操作系统DPI/72就如同一个放大系数一样，将屏幕上的字体调节到一个合适的尺寸。随着设备像素密度的不断提升，放大系数起到越来越重要的作用，这个系数能够将字体大小调整到合适的物理长度。苹果和微软在放大系数的设计中又一次产生了分歧，苹果抽取出了设备像素比的概念，不仅在操作系统层面能够用设备无关的单位控制控件大小，还将其写入webkit的核心中，在网页的视窗中也能继续发挥作用。苹果的笔记本Mac Pro 13英寸的Retina屏，设备像素密度是227，设备像素比是2，这样使用字号单位时如同在像素密度是113的屏幕上一样。举例来讲，12pt的长度在Mac Pro 13 Retina屏上长度与非Retina屏（像素密度为113的屏幕）显示的物理长度完全相同，注意这里所用的pt已经不同于1/72物理英寸，而是1/72逻辑英寸。在网页中，一般用px来表示字号，而少用pt。网页中的px已经不同于物理上的像素，而被称为逻辑像素，由逻辑像素转换为物理像素只需要乘以设备像素比即可。网页中的pt也不同于操作系统应用中的pt单位，以逻辑英寸来表达，而是用真实的物理英寸来表达。\n而微软，沿用了先前的一贯作风，去修改操作系统DPI，先后有了支持高清屏的120DPI和144DPI[7]。对应到上面的公式，放大系数变为1.6和2。虽然最终殊途同归，不过不及设备像素比更为直接。在移动网页中，应用设备像素比的概念，苹果支持得较早[8]。\n至此，有关像素密度和设备像素比的发展变化，以及这两个量给显示效果带来的影响已基本介绍完毕。\n最后不得不提的是Android系统中对这个问题的解决方案。Android定义了160DPI的屏为标准屏MDPI，这种屏幕上1dp=1px[9]。基于此标准，又增加了四种高清屏尺寸，240DPI的HDPI，320DPI的XHDPI，480DPI的XXHDPI以及640DPI的XXXHDPI。这四种高清屏的1dp分别是1.5px、2px、3px和4px。这里的系数不同于设备像素比，但具有类似的功效。Android会将像素密度在某一个区间内的屏幕归到某个类别里面，然后dp和px之间的转换基于160，而非物理像素密度。举例来讲，150DPI和170DPI的手机屏幕都属于160DPI的标准屏，两个屏幕上的1dp=1px，但是对于12dp，两个屏幕会相差0.2mm。\n总而言之，在屏幕上显示文字或者图像，影响显示效果的是物理长度，而决定显示物理长度的是像素密度和设备像素比，进一步，决定像素密度和设备像素比的是人眼在不同视距下的分辨率。\n脚注 * 我们需要去习惯西方的传统计量系统，1码（yard）约等于3英尺（foot），1英尺约等于12英寸（inch），1英寸约等于2.54厘米。 **人们常常混用像素密度和分辨率的概念，比如MSDN上的这篇描述。我比较偏向用像素密度来表示PPI或DPI，而分辨率说整个屏幕的像素数，理由是如果用分辨率去描述像素密度，那么屏幕总的像素数就不知道如何称呼了。另外值得注意的是在不讨论物理尺寸的前提下说分辨率毫无价值。 *** 智能手表出现后，有些厂商开始考虑圆形的屏幕，由于像素都是方形的，圆形屏幕的厂商需要高分辨率去消除一圈的锯齿。 ****这里对理想像素密度的假设是20cm以内的视距，都无法区分比0.02mm更小的距离。\n参考链接 [1] Point (typography) [2] Photo print sizes [3] ISO 216 [4] Image resolution guideline [5] Computer monitor DPI standards [6] Where does 96 DPI come from in Windows? [7] DPI [8] devicePixelRatio [9] Supporting Multiple Screens ","date":"2017-02-03T00:00:00Z","permalink":"/posts/%E5%83%8F%E7%B4%A0%E5%AF%86%E5%BA%A6%E5%92%8C%E8%AE%BE%E5%A4%87%E5%83%8F%E7%B4%A0%E6%AF%94/","title":"像素密度和设备像素比"},{"content":"每次坐火车时，总爱看窗外的风景。近处的树木看起来总比远处的高楼运动得快，令人眼花撩乱。细想来，以火车为参考系，不论近处的树木还是远处的高楼都以相同的速率向着火车运动的反方向运动，所以不应该是速率的变化造成的视觉差异，而应该是角度的变化率（即角速度）的不同造成的。\n假设初始零时刻，火车以速度\\(v\\)做匀速直线运动，取火车相对地面的运动方向为正方向。与此同时，假设我所处的位置为位移的零点，垂直于运动方向，距离我\\(r\\)之处有一个物体。显然初始时刻，这个物体与我的夹角为\\(\\pi/2\\)。对于\\(t\\)时刻，在火车的运动方向上，物体到我的距离为\\(vt\\)，以我为参考系，那么物体向着反方向运动了\\(vt\\)，这时的夹角变为\n$$\\theta=\\frac{\\pi}{2}+\\arctan{\\frac{vt}{r}}$$\n法向量方向垂直地面向上，物体做逆时针的旋转，旋转的角速率为\n$$\\omega=\\frac{d\\theta}{d{t}}=\\frac{vr}{r^2+(vt)^2}=\\frac{v}{r+\\frac{(vt)^2}{r}}$$\n固定\\(r\\)为常量，\\(\\theta\\)随着时间的增加在增加，夹角弧度无限趋近于\\(\\pi\\)。固定时间\\(t\\)为常量，\\(\\theta\\)随着距离\\(r\\)的增加在减小，夹角弧度无限趋近于0。\n固定\\(r\\)为常量，\\(\\omega\\)随着时间的增加在减小，角速率无限趋近于0. 固定时间\\(t\\)为常量，\\(\\omega\\)随着距离\\(r\\)的增加先增大后减小，角速率有一个最大值，在最近处和最远处都无限趋近于0.\n有趣的位置是角速率最大的位置。当\\(r=vt\\)时，不同距离的物体在同一时刻的夹角弧度均为\n$$\\frac{3\\pi}{4}$$\n运动角速率达到最大值，且该角速率的大小为\n$$\\omega=\\frac{1}{2t}$$\n当\\(t\\)无限趋近于0时，运动角速率的最大值应该达到无穷大，而根据前面固定\\(t\\)的分析中，远离最大位置的距离上，运动角速率均是在无限的趋于零，无穷大和零已经难以分辨。\n下面代入一些具体的数字做些直观的感受。假设火车运动的速度为\\(v=300km/h=83.3m/s\\)，人眼的时间分辨误差是\\(1/60s\\)，那么在火车运动了\\(0.017s\\)后，1.4m处的物体运动角速度最大。比1.4m更近处的物体，运动角速度已经越过了最大值，开始减小了。另外由于这部分物体的夹角已经超过了\\(3\\pi/4\\)，所以眼睛已经无法注意到这部分物体，而进一步跳到了位于更前方的物体（1.4m处），眼睛感到晃得很厉害。比1.4m更远处的物体，运动角速度还未越过最大值，角度不足\\(3\\pi/4\\)，所以对比1.4m处的物体，眼睛感觉这部分物体运动很慢。\n","date":"2017-02-01T00:00:00Z","permalink":"/posts/%E7%81%AB%E8%BD%A6%E7%AA%97%E5%A4%96/","title":"火车窗外"},{"content":"两个质量均为\\(m\\)的小车被长度为\\(l\\)的无形变的弹簧连在一起，放在光滑的水平面上，弹簧质量不计。初始时刻给左侧的小车一个\\(v_0\\)的初速度，求每个小车的运动方程。根据动能守恒得\n$$m\\dot{x}+m\\dot{y}=mv_0$$\n根据能量守恒得\n$$\\frac{1}{2}m\\dot{x}^2+\\frac{1}{2}m\\dot{y}^2+\\frac{1}{2}k(y-x-l)^2=\\frac{1}{2}mv_0^2$$\n直接去解这个微分方程组有些困难，可以换到整个系统的质心参考系中去考虑问题。整个系统的质心始终都在两小车连线的中点，根据动能守恒得\n$$2mv_c=mv_0$$\n即\n$$v_c=\\frac{1}{2}v_0$$\n根据牛顿第一定律，整个系统做匀速直线运动，所以立刻得到\n$$y-\\frac{1}{2}v_0t=\\frac{1}{2}v_0t-x$$\n即\n$$y=v_0t-x$$\n即使有这个关系式，微分方程仍旧无法下手。不过转换到质心的参考系后，会发现两个小车相对质心在做简谐振动。以质心为原点，向右为正方向，设右侧小车的位移为\\(x_r\\)，左侧小车的位移为\\(x_l\\)，由前面的分析知道\n$$x_l=-x_r$$\n利用胡克定律得\n$$m\\ddot{x_l}=-k(x_l-x_r+l)$$\n由牛顿第三定律得\n$$m\\ddot{x_r}=-k(x_r-x_l-l)$$\n带入前面的位移关系，得到\n$$m\\ddot{x_l}=-k(2x_l+l)$$\n$$m\\ddot{x_r}=-k(2x_r-l)$$\n这两个简谐振动的方程可以分别设为\n$$x_l(t)=A\\cos(\\omega t+\\phi)-\\frac{l}{2}$$\n$$x_r(t)=A\\cos(\\omega t+\\phi)+\\frac{l}{2}$$\n将解和这初始条件带入方程\n$$v_l(0)=\\dot{x_l}(0)=\\frac{1}{2}v_0$$\n$$v_r(0)=\\dot{x_r}(0)=-\\frac{1}{2}v_0$$\n立刻得到频率\n$$\\omega=\\sqrt{\\frac{2k}{m}}$$\n相位\n$$\\phi=\\frac{\\pi}{2}$$\n振幅为\n$$A=\\frac{1}{2}v_0\\sqrt{\\frac{m}{2k}}$$\n又因为质心在做匀速直线运动，所以最终的方程为\n$$x(t)=\\frac{v_0}{2}t+A\\sin(\\omega t)-\\frac{l}{2}$$\n$$y(t)=\\frac{v_0}{2}t-A\\sin(\\omega t)+\\frac{l}{2}$$\n其中，\n$$\\omega=\\sqrt{\\frac{2k}{m}}$$\n$$A=\\frac{v_0}{2\\omega}$$\n更一般地，如果两个小车质量分别为\\(m\\)和\\(M\\)，质量为\\(m\\)的小车在左侧，给它的初速度仍旧为\\(v_0\\)，则两个小车的运动方程为\n$$x(t)=\\mu_1v_{0}t+\\mu_2A\\sin(\\omega t)-\\mu_2l$$\n$$y(t)=\\mu_1v_{0}t-\\mu_1A\\sin(\\omega t)+\\mu_1l$$\n其中，\n$$\\mu_1=\\frac{m}{m+M}$$\n$$\\mu_2=\\frac{M}{m+M}$$\n$$\\omega=\\sqrt{\\frac{m+M}{mM}k}$$\n$$A=\\frac{v_0}{\\omega}$$\n最近解出这个问题之后兴奋了一天，看到结果后，突然联想到二体问题。两个物体的简谐振动可能是二体运动在直径上的投影，就如同一个物体的简谐运动是匀速圆周运动的投影运动一般。等有时间了，再去算一下二体运动的解。\n此外，我师兄还用纯代数的方法求解了这个问题，得到了一样的结果。\n","date":"2017-01-04T00:00:00Z","permalink":"/posts/%E4%B8%A4%E4%B8%AA%E7%89%A9%E4%BD%93%E7%9A%84%E7%AE%80%E8%B0%90%E6%8C%AF%E5%8A%A8/","title":"两个物体的简谐振动"},{"content":"一直以来，都在享受着SSH免密码登录的远端服务器的好处，但总觉得对背后的逻辑不是太清楚，或者说，根本没有细想过，因为网上充斥了大量的，如何做，却不告诉为什么，下一次再去做的时候，又费半天功夫，所以有必要熟悉完整的流程。近来有了“深入理解加密、解密、数字签名和数字证书”这篇文章做底子，SSH免密码登录背后的逻辑也容易理解很多。\nSSH协议的设计初衷是为rsh、rlogin、rcp等命令提供更佳安全的实现方案，需要对一切传输的数据进行加密、检验一致性。公钥系统中对大块的数据加密往往使用运算速度较快的对称密钥，在SSH协议中称作会话密钥。让彼此双方获得会话密钥，并且保证会话密钥不被窃听的过程称作建立安全会话。SSH-1建立安全会话的流程如下：\n客户端发起访问远端服务器的请求； 服务器发回主机密钥、服务器密钥、加密算法、校验序列等信息； 客户端接到传回信息后，进行服务器认证，如果传回的主机未知，需要人工判断是否信任这些信息，如果不信任，那么会话结束，否则，会话继续； 服务器认证通过后，客户端随机生成会话密钥，用主机密钥和服务器密钥依次对会话密钥加密后发给服务器； 服务器接到加密的会话密钥，用私有密钥依次解密得到会话密钥。 自此客户端和服务器都得到了会话密钥，接下来还需要进行客户端认证。客户端认证的方式有两种：口令认证和公钥认证。口令认证的方式流程如下：\n服务器没有找到用户密钥，就询问用户输入口令； 用户输入口令后，经过会话密钥加密传回给服务器； 服务器验证用户身份。 口令认证的方式简洁方便，但对每天需要登录很多不同的服务器的人而言，一遍遍重复输入口令比较繁琐，这种情况下采用公钥认证的方式会轻松许多，也更佳安全。公钥认证的方式流程如下：\n客户端将用户密钥传给服务器； 服务器在认证过的密钥库中查找，如果没有找到，那么请求失败，如果找到则生成一段随机序列，称作质询，用用户密钥加密后，发回给客户端； 客户端拿私有密钥解密得到质询，附带结合上会话的标识（主机密钥、服务器密钥和校验序列通过MD5散列后得到的序列）通过MD5散列后的序列作为响应传回给服务器； 服务器用同样的方式如果计算出相同的MD5序列，则验证通过。 客户端在使用私有密钥时，需要私有密钥的口令，这个口令可以为空，这样就相当于免密码，但这种方式让私有密钥的安全性降低，不推荐这种做法。最佳实践是借助SSH代理，可以记住不同私有密钥的口令，当客户端查找私有密钥时，只需要通过SSH代理去完成，这样就避免了重复私有密钥口令。\n以上文章只说明了公钥认证背后的流程，并未涉及为何要这样设计流程，比如为什么需要同时有主机密钥和服务器密钥，为什么需要会话标识，这一系列的设计背后都有原因，能够搞明白这些原因，才能更好理解安全是什么。本文只是粗略的总结，对每次传输的细节有些省略，也没有涉及SSH-1和SSH-2的差别以及一些更加丰富的客户端验证方法，更加深入的内容可以参考相关阅读的第一篇。\n相关阅读 SSH: The Secure Shell The Definitive Guide, Inside SSH-1 ⭐️⭐️⭐️⭐️⭐️ 深入理解加密、解密、数字签名和数字证书?⭐️⭐️⭐️⭐️⭐️ ","date":"2016-10-12T00:00:00Z","permalink":"/posts/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86%E5%9C%A8ssh%E8%BF%9C%E7%A8%8B%E7%99%BB%E5%BD%95%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/","title":"公开密钥加密在SSH远程登录中的应用"},{"content":"安卓包发布前必须要有正式签名才能在应用商店发布，对照公开密钥基础设施图解的常规流程而言，安卓包签名仅是个子集，只有数字签名，不涉及加密。\n数字签名中核心的要素是私有密钥、公钥证书、原始摘要和签名摘要。涉及的参与者有应用开发者、应用商店和用户（操作系统）。逐一了解了每个核心要素和参与者也就清楚了整个签名的动机和操作步骤。\n数字签名是拿私有密钥对原始摘要（不管是文件还是对称密钥本质上都是字符串）进行加密，利用大素数的一些特性对原字符串进行变换，得到签名摘要。这个签名摘要，只有用对应的公开密钥才能恢复为原始摘要。\n公开密钥是公钥证书的主要内容，但不是全部。公钥证书中还写明了应用开发者的基本信息包括开发者组织名称、组织所在地、证书失效时间等信息。公钥证书又叫数字证书和身份证书。身份证书的称谓也反映了这个证书是用来识别应用来源身份的。公钥证书需要被权威机构认证，对于安卓而言，这个组织就是Google Play和国内各大应用商店。各大应用商店需要验证应用开发者每次的公钥证书是否一致，不一致的证书就可能遭到拒绝。除此以外，还需要对签名摘要拿公开密钥解密获得原始摘要，并且同原始摘要进行比对，但凡发现不一致的地方，就可能是文件遭到了篡改，同样会拒绝应用发布。实际上操作系统同样会验证公钥证书的一致性和签名摘要的完整性，仅会提醒，但不拒绝安装有风险的安卓包。是否安装有风险的包就取决于用户自己了。\n前面的描述中提到对比解密后的签名摘要和原始摘要可以发现文件是否遭篡改。很容易产生的疑问是为什么比对摘要就可以发现这点？要回答这个问题，就需要了解摘要是什么。安卓包中的原始摘要是一个字符串的集合，每个字符串对应包中的一个文件，每个字符串都是通过哈希散列算法对文件计算出的一个短序列。这个字符串的集合要求包中的文件一个都不能少，也一个都不能多。这个集合中不包含原始摘要文件自己、签名摘要和公钥证书。签名摘要也是类似于原始摘要的一个字符串集合，只是每个短序列是都用公开密钥签名后的结果，此外还增加了原始摘要文件的短序列和签名序列。\n私有密钥由开发者秘密保存，公钥证书、原始摘要和签名摘要随签名包一起发布。实际上签名包和未签名包的差别就是公钥证书、原始摘要和签名摘要。在签名包中，一般放在META-INF中，后缀一般是CER、MF和SF。\n安卓包签名示意图： 相关阅读： Sign Your App?⭐️⭐️⭐️⭐️⭐️ 深入理解加密、解密、数字签名和数字证书?⭐️⭐️⭐️⭐️⭐️ Differentiate between apk and jar files | the comment by?user229002?⭐️⭐️⭐️⭐️⭐️ android APK签名过程之MANIFEST.MF分析?⭐️⭐️⭐️ How can I export my private key from a Java Keytool keystore??⭐️⭐️⭐️ ","date":"2016-10-11T00:00:00Z","permalink":"/posts/%E6%95%B0%E5%AD%97%E7%AD%BE%E5%90%8D%E5%9C%A8%E5%AE%89%E5%8D%93%E5%8C%85%E5%8F%91%E5%B8%83%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8/","title":"数字签名在安卓包发布中的应用"},{"content":"很久以来，一直搞不清楚各种加密算法、哈希函数的应用场景，直到读了“深入理解加密、解密、数字签名和数字证书”这篇博文后，一切概念立刻变得明朗起来，于是赶快画了一张图捋清了思路，方便自己和看到这篇文章的朋友回顾。因为原文作者写得足够精彩，逻辑性很强，所以在此只简略叙述图中所画内容。\nA要通过网络将文件（Original File）发送给B，为了能让B安全收到，避免传输过程中被截获、窃听或伪造，目前相对安全的做法是图中描述的流程。\nA需要执行的操作：\n(1) 用对称密钥（Symmetric Key）通过对称加密算法把文件加密成为密文文件（Encrypted File, or Cypher Text）； (2) 用B的公开密钥（Public Key）通过非对称加密算法把对称密钥加密成为加密的对称密钥（Encrypted Symmetric Key）； (3) 通过哈希算法生成文件的短摘要（Short Digest）； (4) 用自己的私有密钥（Private Key）通过非对称加密算法对短摘要签名，生成签名摘要； (5) 将自己的公开密钥和个人信息交付CA机构认证获取数字证书（Certificate）。 最后将密文文件、加密的对称密钥、签名摘要和数字证书通过网络传给B。 B收到A发来的文件需要执行的操作：\n(1) 用自己的私有密钥对A发来的加密的对称密钥解密，获得解密的对称密钥（Decrypted Symmetric Key）； (2) 用解密的对称密钥解密密文文件，获得解密文件（Decrypted File）； (3) 用相同的哈希算法，生成解密文件的短摘要作为待测摘要（Tested Short Digest）； (4) 用A发来的数字证书获取A的公开密钥； (5) 用A的公开密钥对签名摘要解密得到解密的摘要（Decrypted Short Digest）； (6) 对比待测摘要和解密摘要，如果完全一致，说明解密文件就是原始文件，如果不一致，说明解密文件是伪造文件。 ","date":"2016-09-30T00:00:00Z","permalink":"/posts/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%9F%BA%E7%A1%80%E8%AE%BE%E6%96%BD%E5%9B%BE%E8%A7%A3/","title":"公开密钥基础设施图解"},{"content":"log4j有三个主要的概念：记录员loggers、录入笔appenders和录入风格layouts。\n记录员是分级别、继承式的。每个记录员有三个基本特征：\n名称的继承 除总记录员之外的所有记录员都要有名称。名称往往是全路径类名，例如com.foo.Bar。名称的继承是指记录员之间有继承关系，com.foo是com.foo.Bar的父亲，com是com.foo.Bar的爷爷。每个记录员的名称唯一，并且能够通过getLogger方法直接被获取。每个记录员在第一次被获取时被实例化，总记录员除外，它始终都存在，所有没父亲的记录员都继承自它。 每个记录员都有记录级别，默认系统给出的级别，分六档，从低到高依次是跟踪TRACE、调试DEBUG、记录INFO、警告WARN、错误ERROR、灾难FATAL。使用者被允许自定义新的级别，但不被建议，通常这六种也足够用了。\n级别的继承 记录员的级别有两种方式取得，一种是使用者用setLevel直接指定，另一种是从祖先那里继承。直接指定就不必说了，继承也很简单，自己如果没被指定级别，那就继承父亲的级别，如果父亲还没有，那就继续向上，直到有祖先被指定级别。总记录员必须被指定级别，因为没有父亲了。\n赢得纪录权利的规则 记录员的每一次记录信息都有级别检查，记录信息的级别由记录方法决定，比如，默认的六个方法trace, debug, info, warn, error, fatal。记录员用比自己级别低的记录方法，不会有信息输出，只有用了高级别（大于等于自身级别）的记录方法才会输出。还有个一般性的记录方法log，可以通过指定级别，随意变身默认的六种方法。所以记录员赢得记录的权利就是调用比自身级别高的记录方法。\n录入笔 记录员只有方法没有工具也不知道把信息记到哪儿，录入笔就是这个工具。每个记录员可以有多个记录笔，不同记录笔记录到不同的平台，可以是控制台、文件、界面的某个控件、远程服务器的套接字端口、Java消息服务、Windows NT的日志系统、远程UNIX服务器的Syslog日志系统。\n录入笔也是可继承的，祖先的录入笔会继承到后代中。后代的记录员可以用继承来的录入笔和自身的录入笔同时将信息输出到多个数据源。\n记录员的录入笔默认是可叠加的，可叠加是指的继承上的可叠加。如果禁止录入笔的叠加性，即禁掉了当前录入员继承祖先的录入笔，自身的录入笔还是会被后代继承的，被继承的录入笔也是可以同时使用的。\n录入风格 录入风格顾名思义指的是记录信息的格式，每个录入笔可以指定一种专门的录入格式。\n","date":"2016-08-09T00:00:00Z","permalink":"/posts/%E5%88%9D%E8%AF%86log4j/","title":"初识log4j"},{"content":"WordPress的插件机制展现了强大扩展能力，它将用户模板定制、插件开发等从核心处理流程中剥离，也让开发者在核心之外有机会修改核心处理流程中的任何一个环节。\n基本概念 WordPress插件机制的核心是钩子（Hooks），每一次处理请求都会顺序执行一系列的钩子，每个钩子由唯一的标签（Tag）标识，每个钩子上能够注册数量不限的函数，在钩子执行中，函数按照注册时的优先级先后依次执行，每个钩子可以重复被执行。\n举例来讲，当服务器接到首页的请求时，第一个钩子_muplugins_loaded_会在加载完自动激活（Must-Use）插件后被执行，第二个钩子_registered_taxonomy_会在系统初始化默认的分类系统（create_initial_taxonomies）中执行。在响应信息完成前，有几十个钩子被依次执行。\n如果钩子上没有注册函数，那么执行钩子时并没有实际动作。比如_registered_taxonomy_是在每个分类系统注册结束时被执行，当初始化分类系统时，4.5.3版本默认注册了5个分类系统：category、post_tag、nav_menu、link_category、post_format，每个分类系统注册结束后_registered_taxonomy_都被执行一次，但由于WordPress核心并没有在这个钩子上注册过函数，所以没有实际的动作。\n如果钩子上注册了函数，那么执行钩子时，按照优先级从高到低顺序执行，优先级一样的，先注册的先执行。优先级用非负整数表示，数字越小优先级越高。4.5.3版本在加载主题模板前会执行_template_redirect_来处理若干URL重定向的问题。系统默认注册了6个函数，其中_wp_admin_bar_init优先级为0，wp_old_slug_redirect、redirect_canonical优先级为10，rest_output_link_header、wp_shortlink_header优先级为11，wp_redirect_admin_locations优先级为1000. 假如用户在Must-Use插件中注册了setup_custom_redirect到_muplugins_loaded_，而函数的内容是注册一个用户custom_redirect函数到_template_redirect_，那么系统在执行_muplugins_loaded_时，会执行setup_custom_redirect函数，从而注册custom_redirect到_template_redirect_。注册custom_redirect时，没有指定优先级，默认是10，这样就与wp_old_slug_redirect和redirect_canonical有着相同的优先级。由于执行_muplugins_loaded_是在default-filters.php（系统默认的两个优先级为10的函数都在这里注册）执行之后，所以custom_redirect执行时候也后执行。\n编程接口 钩子的类型有两种，过滤钩子（Filter）和动作钩子（Action），所以编程接口（API）也有两组。这两组编程接口定义在wp-includes/plugin.php中，函数签名如下：\nfunction add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ); add_filter和add_action用于函数注册，apply_filters、apply_filters_ref_array、do_action、do_action_ref_array用于钩子执行，remove_filters、remove_all_filters、remove_action、remove_all_actions用于函数移除。函数注册和函数移除必须在钩子（要注册和要移除的钩子，非其它的钩子）执行前或者执行中才能生效。在钩子执行中注册或者移除仅对低优先级的函数生效。\n动作钩子是一类特殊的过滤钩子，两种钩子的标签和注册函数是共享的，都存储在**$wp_filter**对象中，换句话说用add_action注册的函数，用apply_filters执行在某些情况下也是可以的。事实上，动作钩子的add_action方法直接调用了add_filter方法。\n过滤钩子顾名思义，钩子上注册的函数要起过滤的作用。具体来说，会对某个对象的内容，可能是字符串、整数或者复杂对象做一定的修改后再返回修改后的对象。所以一系列的钩子连在一起，对这个对象形成了层层的过滤，直到钩子执行结束。过滤钩子主要的特点是，前一个函数的处理结果可以传给下一个函数。动作钩子相较而言，无法接收前一个函数的返回值。对比两个函数的参数，也可以发现apply_filters的第二个参数$value是必选参数，这个参数也就是要过滤的对象，这个参数在第二个函数执行时，会传入第一个函数的返回值，而后依此类推。do_action的第二个参数$args不是必选，即使有返回值也不会再向下传递。类似地，apply_filters_ref_array的返回值会由$args[0]继续向后传递。值得注意的是，如果要用apply_filters代替do_action，第二个参数在第二个函数之后就无法正常获取，因此前面提到的某些情况，即是第二个参数无意义的时候。当然最好不要用apply_filters去代替do_action。\nhas_filter和has_action用于检查某个钩子是否存在，填写第二个参数可以检查某个钩子上是否注册了某个函数。\ncurrent_filter和current_action用于获取当前执行函数所在的钩子的名称，而doing_filter和doing_action用于获取当前所有在执行的钩子的名称。前后两组的区别是当前执行函数只会有一个（单线程），对应的钩子也只有一个，而在执行的钩子可以有多个，因而钩子A的注册函数中还可能执行钩子B，而执行到B的注册函数是，A并没有执行完，只是暂时压入了栈中。$wp_current_filter对象即是一个堆栈，用于存放执行中的钩子，而堆顶是正在执行函数的的钩子。doing_filter的参数为null时，只检查$wp_current_filter栈中是否为空，不为空，返回真；参数为某个钩子时，去检查钩子是否在栈中，如果在，返回真。\ndid_action用于检查某个钩子是否执行过，执行过的钩子都会在**$wp_actions**中登记一次，而且登记顺序是符合执行顺序的。利用$wp_actions可以在最后一个钩子_shutdown_执行时，顺序打印所有执行过的钩子，来获取真实的场景中钩子的执行顺序。\nfunction show_hooks_order() { print_r( $GLOBALS[\u0026#39;wp_actions\u0026#39;] ); } add_action( \u0026#39;shutdown\u0026#39;, \u0026#39;show_hooks_order\u0026#39; 了解有哪些钩子和钩子的作用是什么，除了直接查看源码外，Adam R Brown还汇总了历史上各个WordPress版本中钩子词典，也可以用作参考。\n结语 WordPress的钩子机制是一种扩展流程的通用思想，不论是否做网站开发，都应该学习这种机制，从而了解庞大系统为何能变得庞大还脉络清晰、适应性强大的缘由，进一步也会帮助自身在设计系统时有所借鉴。\n","date":"2016-08-07T00:00:00Z","permalink":"/posts/wordpress%E7%9A%84%E6%8F%92%E4%BB%B6%E6%9C%BA%E5%88%B6/","title":"WordPress的插件机制"},{"content":"一 六点过后，五百一十九微信群里未读消息更新的速度，已经远超我眼睛和耳朵的反应速度。\n上一秒刚看到苏龙罡打趣玉柱，说要求报销化掉的甜筒。\n下一秒就听到小龙和胡Sir在打算改签机票要飞往北京。\n地铁里嘈杂的声音，让我无法听清每一个语音信息；断断续续的信号，让我需要不断地回滚页面才好勾勒出事情的始末。\n我放弃了，随便点开一条听不太清楚的信息，站在地铁上傻乐。\n二 临近九点，城铁准时到达天津站。走出列车，未能感受到海河风的凉爽，只身浸没在燥热的夜晚中。\n夏天的晚上能有比火锅和烧烤更有气氛的聚餐地点吗。结束了与的士师傅生涩的聊天后，苏龙罡接我上楼跟大伙见面。\n刚上楼梯口，就远远地搜索到了迎面相对的枫少，看起来壮了不少。\n我们在枫少旁边空着的座位坐下，对面是昊哥、三毛和玉柱。\n昊哥看起来有些疲惫，大概是准备婚礼累得够呛。难得劳心专门把婚礼选在周末，让散落在天南海北的兄弟们在毕业五年后几近齐聚。大伙敬昊哥一个，为了婚礼，也为了不易的见面。\n三毛和玉柱看起来兴致不错，喝得应该有个二三分。我是个不太应付的了三个人以上场面的人，即使我的内心已是躁动不已，言语和行为还是显得平静。\n三毛天生能够带动气氛，年纪比整个07级软院的平均数小了近三岁，让他无畏于结交学院的任何人，主动、热情、自信大概是他的特质。不过看得出，工作的几年，让他的言行举止间增添了许多的成熟。他数落着我说，大伙前前后后基本都去南京玩过，就我跟玮哥没有去，邀我去时一定住他的大房子。\n苏龙罡有着东北人天生的幽默感，段子和包袱抖开得够自然，让人回想起来还觉得逗乐。胸口纹身的段子不知道他是不是真的试过，挺赞。我跟他虽然同在北京，一年也就能有一两次的见面机会，看到他的变化相比其他人还是更多些。在北京呆五年，善于交际的他比我见的场面丰富，应该找到了自己的一条既定轨道，正静心行驶在上面吧。\n玉柱恰逢休假，得以有空从家乡济源赶过来。他这五年在全球呆过不少地方，最开始在沙特，后来有到过墨西哥、埃及、摩洛哥。这些环球旅行，想来让人羡慕，但生活的单调和苦涩恐怕也让人畏惧。听得他在西安买了房子，接下来应该是会考虑安定下来了。\n酒过三巡，饭菜已尽。明天还要迎接一对新人步入婚姻的殿堂，应该保存体力。三毛陪昊哥去买水果，我们四人，溜达回酒店。\n三 我跟枫少一房间，玉柱跟苏龙罡一房间。\n等三毛回来，五个人又少喝了点，有的没的聊了些，呆到一点半后各自回房休息了。\n小龙和胡Sir的飞机晚点了近三个钟头，晚上十点多才起飞，凌晨两点多到天津。宝柱从宁波赶过来，也在凌晨才到。三毛在房里等他们来到酒店才睡下。\n四 天津城区人的婚礼，仪式一定要在午后日落前举行，正式的宴请都在傍晚。\n婚礼很赶时尚，在一个别墅里，仪式前是亲友派对。一楼的客厅里摆着桌上足球、街霸和PS4，还有跑步机和动感单车，客厅两侧一个KTV房，一个台球屋。二楼是一间卧室，另外一间并排放了七八张矮床，看起来不是榻榻米，大概是做什么特殊游戏用的。\n大多客人都呆在一楼，有小孩的地方，少不了热闹。街霸是男孩释放内心的野性的最好工具，有什么能比决斗获胜更能得到原始的满足感呢。小男孩跟大男孩之间的较量，也势必会引起看客们的一阵喧闹。\n大男孩之间，当暂时逃离日常生活的重压时，在自己熟络和喜欢的人身上，会释放一些原始的天性：恶作剧。\n小龙昨晚兴奋了一夜，加上旅途劳顿，坐在沙发上不小心睡着了，姿势有那么一点点“葛优躺”，关键裤裆平展无疑就是了。苏龙罡想逗他，轻轻抽出他手边抱着的水，在他裤裆上倒了两瓶盖。一看，深蓝色的牛仔裤，不够明显，又追加了两三瓶盖。旁边的振国看着乐坏了，枫少、玉柱、三毛和我都是“从犯”。一则没有及时制止，二则随后还有包庇纵容，更为甚者推波助澜。最后的两三盖，我有些看不下去了，拍了个小视频发群里，记录了这一“罪行”。没想到这视频只拍到了苏龙罡拧住瓶盖，把水放回去的片段。小龙被放瓶子惊醒时，苏龙罡拿出惯用的语气对他说，你真TM的恶心，居然还尿裤子。小龙看着湿漉漉的裤裆，顿时脸红到了脖子根，一脸尴尬、慌乱不堪的样子。再看着苏龙罡一脸正经的嘲笑，不似玩笑。方要质疑，政国唱起红脸，狠狠损说倒水的行为是多么幼稚、多么无聊，怎么可能，又深信了几分。待到看到视频时，又被解释说，把水洒在他身上，是为了掩盖他尿裤子的行为。小龙问到我头上，我谎说没看到开头。终于三人成虎，小龙决定到外面太阳下晒晒。虽说是恶作剧，我还是有些内疚感，我只能安慰自己是有底线的，如果小龙真要决定扔掉这裤子，要去买条新的，我就坦白了。事情到最后，苏龙罡自己坦白了。依小龙的性格，应该不会太在意吧。\n小龙有着骨子里的洒脱，今朝有酒今朝醉。天生的脾气倔强，待友直率。电影、游戏、动漫涉猎广泛，善言辞。婚后变了不少，女儿出生后，更是没命的工作，工作日的晚上、偶尔周末还兼职做技术顾问。大学期间，没有不挂科的学期，程序大概也没写过几行。毕业五年来，如今也在一个初创公司做起了技术负责人，让人刮目。\n四点多左右，太阳不再毒辣，仪式在院里举行。司仪是昊哥发小，知根知底，庄重的言语不可避免，但足够简洁，听来真挚，也足够暖人。新人互戴戒指后，最合中国传统的部分就是对双方父母的奉茶仪式，现代人虽免去了跪拜的大礼，但鞠躬往往还是有的。我们一行人做了仪式结束时的礼炮手，待切蛋糕、喝交杯酒前，燃起典礼的花火。\n五 宴请的宾客有十多桌，每桌不超过十人。\n我们十人硬要凑一桌，政国大学时经常混迹在我们宿舍，临毕业前还经常跟小龙和我一起吃藏龙鱼，也算半个五一九人，冯尧斐、江滨也都是软院院友，不好再单开一桌。加上江滨女友，我们一共十四人，挤得没法再插进一个人来。\n阿姨看不过去了，这样显得他们招待不周。出于礼貌，一半人坐到了旁边的空桌上。\n菜品足够硬实，鸡鸭鱼牛羊几乎都是双份，素菜成了桌上的点缀。\n酒桌上，政国成为众矢之的，扬言要放倒我们整个宿舍，还戏称我们老弱病残。是可忍孰不可忍，定要与之一决高下。三毛当仁不让，先锋叫阵，虽然不胜酒力，却有着压倒性的气势。政国又岂是吃素的，倒一杯喝半杯，歇歇停停，口中念念有词。玉柱随后出马，跟他过了两回招。苏龙罡又岂能放过政国，昊哥来敬酒时，检举他偷偷地只顾吃菜，必要喝上满满一杯方才罢休。\n宴请结束，天色已黑，合影留念，也好记下这个特别的夜晚。\n六 宴席上的酒喝得还不够起兴，回酒店休息片刻后，又齐聚烧烤店再来一轮。\n酒是男人间沟通感情的桥梁，工作、生活上的苦涩，恐怕非酒壮胆而不能言。言语发泄虽能缓解人的压力，男人却大多选择沉默。有人说这是野蛮人时代就留下来的基因，减少言语间的沟通，能够提高伏击猎物的几率，但我总觉得，很多人或许是觉得多费口舌很多时候无法立竿见影地解决问题，沉默又往往能减少冲突，慢慢变得不善言辞了。\n几升啤酒过后，所有人的胃大概都涨坏了，但酒精量应该是没到位。\n时间太匆忙，再过几个小时，离得最远的几位还要赶飞机回去，保重身体要紧。\n趁着离开前，我抓紧小敬了不常见到的几位。\n祝贺徐悦甡博士顺利毕业，并拿到了母校的教职。祝愿在未来的育人和研究中依旧出色。科研的道路上，我没能有勇气选择走下去，但转头却很欣喜，那里站着出色的你。\n祝贺斌哥、宝柱今年也都找到了另一半。\n祝愿胡Sir不久后能给儿女生个弟弟。\n七 夜里，欧洲杯德国大战意大利。\n斌哥了解我对德国队的情结，打算陪我一起观战，可惜没等到开战，他就睡着了，我没好意思叫醒他。\n等他睡醒时，跌宕起伏的点球大战开始了。穆勒罚丢点球，我还觉着没什么，但小猪、厄齐尔接连罚丢点球，顿时脚掌冒汗，觉得德国要输。好在之后的两位小将都顶住了压力，打进球门。最后靠左后卫赫克托一脚定乾坤，似乎平复了06年半决赛加时赛中，被意大利左后卫格罗索绝杀的伤痛。\n又一个难忘的夜晚。\n八 \u0026ldquo;相逢方一笑，相送还成泣。祖帐已伤离，荒城复愁入。\u0026rdquo;\n下一个三年或五年又是一番怎样的景象呢，我无暇去想象，我只知生活中的一些纯粹构筑了生活的美好。\n二零一六年七月十一日记\n","date":"2016-07-11T00:00:00Z","permalink":"/posts/%E6%B5%B7%E6%B2%B3%E7%95%94%E7%9A%84%E8%BA%81%E5%8A%A8/","title":"海河畔的躁动"},{"content":"在常规的网页中，宽一般有最大限制，而高没有，因而CSS规范并没有给出块级元素和多行文字垂直居中，建议性的实现方案。换句话说，但凡有垂直居中的要求，必然是设计者对包含块的高做了固定限制。\n默认的CSS块级元素的高由内容决定，通常内容有多少，高度就会算多少。固定了高意味着设计者必须确认内容的高度不会超过限制，否则会产生不合预期的结果。\n众所周知，限制高仅需要指定height样式属性即可。\n确认内容高度需要了解内容的组成，可能会是一张可替换的图片，也可能会是一段行数不确定的文本，甚至也可能是另外一个块级元素，每种内容有各自的模型在控制着自己的展示。\n情形1: 垂直居中一张图片 图片的模型最简单，行内元素，限制高，宽会等比例缩放。假设要在高度为200px的块中放置一个高度不超过100px的图片，垂直居中可以这样写：\n#middleWrapper { height: 200px; line-height: 200px; border-color: black; border-width: 1px; border-style: solid; } #middleWrapper \u0026gt; img { vertical-align: middle; max-height: 100px; } \u0026lt;div class=\u0026#34;middleWrapper\u0026#34;\u0026gt; \u0026lt;img src=\u0026#34;/wp-content/uploads/2015/01/violin.jpg\u0026#34;\u0026gt; \u0026lt;/div\u0026gt; 上面的代码中重要之处在于line-height恰好等于height，这样整个包含块就变成了一行，在单行内居中行内元素，只需要指定vertical-align是middle即可。\n垂直居中一张图片的应用场景很多，比如一个带有标志图片的按钮，再比如购物网站商品页上商品的图片展示（固定的方框内放各种不同尺寸的图片）等。\n情形2: 垂直居中一行 这种情况与情形1类似，不同之处在于文字如果一行放不下会换行，当换出新的一行，文字便超出了包含块，这时通常的处理手法是将超出部分隐藏（overflow: hidden）。更加普遍的做法是设置样式属性white-space为nowrap不允许文字换行，并且将超出部分换用三个点代替（text-overflow: ellipsis）。下面的例子中，将内容超过一行的文本，垂直居中地放在高200px的包含块中，并且只显示一行。\n#middleWrapper { height: 200px; line-height: 200px; text-overflow: ellipsis; overflow: hidden; border-color: black; border-width: 1px; border-style: solid; } #middleWrapper \u0026gt; span { vertical-align: middle; white-space: nowrap; } \u0026lt;div class=\u0026#34;middleWrapper\u0026#34;\u0026gt; \u0026lt;span\u0026gt;It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters.\u0026lt;/span\u0026gt; \u0026lt;/div\u0026gt; It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters. 注意white-space属性可以放在包含块中或是直接放在文本标签中均可，因为这个属性允许继承，并且只能作用在文本上。两个overflow属性却要放在包含块中，用户代理需要根据包含块的高度进行计算隐藏掉那一部分文字。值得一提的是text-overflow属性是CSS3中加入的新内容，主流浏览器都支持，但也有些例外，比如UC浏览器的Android手机版。\n垂直居中一行文字的应用场景包括按钮上的文字，水平导航栏中的文字等等。\n情形3: 垂直居中几行文字 如果要垂直居中的文字行数是确定的，并且包含块框的高度恰好等于总行框的高度，那么只需要将包含块的高度设置为总行框高度即可。例如有两行，字体13px，每行行高17px，那么包含块的高度为34px。\n这种情形最常见的应用场景是移动购物网站，浏览页商品描述的格式。这种场景下往往也要求能够隐藏多出来的行，以及将多出的部分替换为三个点。这种做法，纯粹的CSS无法胜任，只能计算出行宽，估算出展示的字符数用JS脚本控制。说估算是由于英文字体多数不是等宽，如果无法知道每个字母的宽度，难以精确地算出要展示的字符数目。\n情形4: 垂直居中一段文字 当一段文字行数不确定，且包含块的高度一定大于总行框高度时，需要将整段文字放在一个不限制高的行内块级元素中，像下面的写法一样：\n#middleWrapper { height: 200px; line-height: 200px; border-color: black; border-width: 1px; border-style: solid; } #middleWrapper \u0026gt; div { vertical-align: middle; display: inline-block; line-height: 1.5; text-align: justify; } \u0026lt;div class=\u0026#34;middleWrapper\u0026#34;\u0026gt; \u0026lt;div\u0026gt;It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters.\u0026lt;/div\u0026gt; \u0026lt;/div\u0026gt; It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters. 不同于单行元素的居中，多行元素的line-height需要重置成较小的值，上面例子中取了文字的1.5倍，远小于父级元素的200px。将块级元素变成行内块级元素也是关键。如果仍旧只是块级元素，即使充值了line-height也不会生效，因为块级元素的一行会去和父级包含块的一行去居中对齐。\n这种情况的应用场景极少遇到，恐怕只有按照列为主题布局时，才可能需要。\n另外有一种通行的做法是将要居中的内容放置在一个单元格中，这种方案可以应对以上所有情况。\n#middleWrapper { height: 200px; line-height: 1.5; vertical-align: middle; display: table-cell; border-color: black; border-width: 1px; border-style: solid; } \u0026lt;div class=\u0026#34;middleWrapper\u0026#34;\u0026gt; It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters. \u0026lt;/div\u0026gt; It is a truth universally acknowledged that a single man in possession of a good fortune must be in want of a wife. However little known the feelings or views of such a man may be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is considered as the rightful property of some one or other of their daughters. 此外，还有一些方法也可行，但显得不够优雅，比如设定上下的padding为某个固定值可以应对某些情形等。\n","date":"2015-11-01T00:00:00Z","permalink":"/posts/css%E5%AE%9E%E7%8E%B0%E5%9E%82%E7%9B%B4%E5%B1%85%E4%B8%AD/","title":"CSS实现垂直居中"},{"content":"乘车到郑州登机 车行深山叠崇峦，隧道盘亘奇多换。 忽见远树穷天际，平川畅往新郑站。 宿大研古城 朝阳耀朱户，闾巷柴烟起。 门牖逐户启，行人渐街熙。 绿柳低檐垂，青溪声淙脆。 手鼓丽人击，醉情大研里。 大研印象 平巷尽东望，木府天中央。 画阁朱楼旁，翠松绿槐傍。 高城眺远山，斜晖映城坊。 府门静幽幽，小镇熙攘攘。 丽江小镇 市集人熙攘，平巷幽寂深。 茶菊遍溪蹊，天净无霃尘。 木府 府门幽高立，平巷伫仰望。 天雨流芳前，吐司今已变。 峡中行 山隈云雾起，玉龙古道游。秋中林犹茂，潭深水悠悠。 昔时木家院，人去古风留。汉藏通茶马，纳西设税收。 土司虽已没，匠艺存街头。 霞客访至此，碑亭引客集。沿潭依山转，趣途游人稀。 慧泉水甘澈，可恨钱浸污。父母惜泉流，不忌俯身舀。 游人爱水净，不畏贴面饮。 香庙钟声远，密林遮天高。绝壁登石梯，悬崖滑轨道。 行至细峡伫，始见瑰怪出。千龙俯急下，水汽沁心脾。 青苔银帘泽，苍松岩边立。方叹人力尽，那堪天然成。 ","date":"2015-10-10T00:00:00Z","permalink":"/posts/%E4%B8%BD%E6%B1%9F%E8%A1%8C%E9%9A%8F%E7%AC%94/","title":"丽江行随笔"},{"content":"几乎所有的VCS都支持分支的机制，到底什么是分支，有什么作用？\n分支是一份完整的项目代码，一个项目可以有很多分支。多数VCS工具的分支机制很昂贵，需要完整的拷贝项目代码，对于代码量大的目录往往需要很长的时间。Git用快照加校验码的方式，让分支模型变得异常轻便，创建和切换分支都很快。Git的每个分支都是一些校验码构成的树或者图，要想理解Git的分支模型，请仔细阅读Branches in a Nutshell或者中文版何谓分支。\n如何创建分支呢？\n$ git branch testing 这种方式是在当前分支基础上创建了testing分支。首先应该明白，如果项目有多个分支，当前只有一个分支位于工作区域。一般一份代码至少有一个主干分支，叫做master。如果想指定从某个分支基础上创建分支只需要在后面再加上分支名字即可，例如\n$ git branch testing master 就从master新建分支，不管当前处于哪个分支下。这个命令的执行不会将新建的分支testing切换到工作区域。\n如何切换分支呢？\n$ git checkout testing 或者可以在创建分支的时候执行\n$ git checkout -b testing 表示创建新的分支testing并且切换过去。\n是否在分支中新加的代码不会加在主干中？\n是这样的。如果是在分支中做提交，那么只会影响分支，不会影响主干和其他的分支，可以保持主干的稳定性。\n分支开发完后要怎么将代码加回主干？\n$ git checkout?master $ git merge testing 注意切换到master时需要保证所有记录的修改都应该已经提交，否则切换会失败。加回主干一般称作合并，合并的过程是在被提交的分支上生成一个新的提交，将两个分支的代码差异合并起来的操作。当同一个文件在两个分支上都有修改时就会产生冲突，需要手动解决。详细的冲突解决的示例可以参考Basic Merge Conflicts。\n应该如何查看当前有哪些分支呢？\n$ git branch 会显示所有分支的名字，更详细的信息可以加-v选项。还有两个选项也常用，\u0026ndash;merged显示已合并到当前分支上的那些分支，\u0026ndash;nomerged显示还未合并到当前分支上的那些分支。\n分支合并后该怎么删除呢？\n$ git branch -d \u0026lt;branch\\_name\u0026gt; 之前提到的是否都是本地仓库的操作，本地的提交怎么会影响到远端呢，也需要合并吗？\n对的，之前说的都是本地的操作，提交到远端也需要合并，但命令不太一样，原则上有些差别。\n什么原则上的差别？\n前面提到过向远程提交代码是一个推送操作，需要执行\n$ git push 而能直接执行这个操作，需要当前分支跟踪着远端的某个分支。\n$ git branch -vv 可以查询本地跟踪远程的那些分支情况。不管用推送去合并哪个分支都需要本地的分支跟踪远程的某个分支。如果是要推送一个远程不存在的分支，那么直接会在远程新建一个对应名字的分支，并被本地分支跟踪，命令是\n$ git push \u0026lt;remote\\_name\u0026gt; \u0026lt;branch\\_name\u0026gt; 所以本地和远程的差别在于，远程使用推送去完成合并和创建新的分支。\n远端的分支在本地名字好像都是类似origin/master的格式？\n是的，origin是远端的名字，master是远端分支的名字。\n前面好像有提过，从远程拉取代码使用fetch或者pull的命令，差别在哪里？\n$ git fetch origin 会拉取所有在远端名为origin下的所有分支到本地，并且名字都叫origin/\u0026lt;branch_name\u0026gt;。这些拉取的分支是不能够直接切换和修改的，需要对它们用本地分支进行跟踪。如果本地已经有对应的跟踪分支，切换过去，直接进行合并，即执行\n$ git checkout tracking_branch $ git merge origin/tracking_branch 命令pull将fetch操作和merge操作一并执行。\n如果本地没有跟踪分支，那么怎么新建一个呢？\n$ git checkout -b branch_name remote_name/branch_name 这个命令看起来和本地新建一个分支好像没有差别？\n看起来是没有差别，但会让新建的分支跟踪远端的分支。如果想要显式地执行跟踪，可以执行\n$ git checkout --track remote_name/branch_name 如果要改变本地分支追踪的远程分支，可以执行\n$ git checkout -u remote_name/branch_name 假如错误地推送给远程一个分支，怎么能够删除？\n$ git push remote_name --delete branch_name 命令和选项都太多了，平常应该怎么用这些命令来做开发？\n通常情况下，远端只会有一个分支，姑且叫做远端的主干分支。远端主干分支上的代码都是稳定的，经过测试，可以直接编译、执行、部署。本地开发时，需要有一个本地主干来跟踪远程的主干，因而这个主干通常不做开发，也一般都是稳定的。如果代码中有bug，那么从本地主干上切换出一个新的分支来做修改，修改完后再合并到主干，主干测试无误，推送到远端主干进行测试。如果代码要开发新的功能，也从主干上切换出一个新的分支来添加代码，添加完后，测试无误合并到主干，然后推送到主干进行测试。所以稳定的主干一般只有一个，不管是开发新功能还是修改漏洞都要在新分支上完成。\n需要注意的一点是多人使用远端分支时候，主干推送可能会出错。这种情况发生在本地主干与远程的主干不同步，合作开发者已经将更新的提交推送到了远端，这时候需要本地主干同步后，再做本地的合并，然后再推送。\n意思是说每次合并主干前，都执行一次$ git pull吗？\n是的，最好这样。\n之前有提到过$ git pull -r的操作，与上面有什么差别？\n这个命令会以rebase的方式合并，而不是merge。\n什么是rebase的方式？\n假设在本地功能分支合并到主干分支的时候，忘记去同步远端主干到本地，这个时候直接执行$ git pull的话，可能会产生合并冲突，如果远端和本地的最新提交都修改了同一个文件的话。这种情况下，不仅需要手动合并，而且向远端提交分支的时候还后产生一个合并分支的分叉，提交历史看起来不太整齐。如果用rebase合并，Git会将本地合并的提交接在远端提交的后面，等价于先同步远端主干到本地，再去合并。\nrebase可以单独使用吗？\n可以的。rebase也能够用在本地功能分支向主干分支合并的时候。本地的主干可能有多个分支同时进行开发，也有可能同步了远程的主干，继续向前，所有头部的提交已经不再是当前功能分支切换时的情况了，这个时候rebase就很有用，直接在当前的功能分支下执行\n$ git rebase master 能够让当前功能分支的新提交追加在主干新提交之后。另外值得提一句rebase操作的-i操作还能够在合并的时候修改提交历史，这个功能其实很好用，但也引起了很多的争议。\n什么样的争议？\n反对者的声音是提交历史记录了原本发生的历史，而历史不应该被改变，使用rebase等于在篡改历史，你相当于是在对过去说谎。支持者的声音是提交历史里应该记录的是项目如何被完成这个完整的故事，哪些保留，哪些删除，应该有所取舍，没有人会将一本书的草稿出版。\n听起来挺有趣，那争议的结果怎样呢？\n其实就是我们现在看到的，两种方式都保留在Git中。有一点建议是_只用rebase修改自己本地仓库的提交，千万不要修改本地之外的提交_（Do not rebase commits that exist outside your repository）。\n这段文字改写自《Pro Git》一书的第二版第三章Branching部分。这里的改写仅用作回顾，不推荐直接学习，原书中有很多图示的说明更加直观。第二章请参考Git基础。\n","date":"2015-05-13T00:00:00Z","permalink":"/posts/git%E5%88%86%E6%94%AF/","title":"Git分支"},{"content":"如何开始用Git呢？\n可以通过命令行和界面使用Git，但推荐命令行。掌握了命令行，界面也就基本掌握了，反之就不行。\n如何创建一个Git仓库呢？\n有两种方式：\n第一种针对本地的某个项目，还未被Git记录过，那么cd到对应项目的根目录下，执行\n$ git init 然后执行\n$ git add *.c $ git add LICENSE $ git commit -m \u0026#39;initial project version\u0026#39; 后面三句先不解释含义，后面会逐步说明。只说明第一句git init，表示在当前目录下，生成.git仓库来记录该目录下的项目。\n第二种针对远端的某个项目，有对应项目的公开链接和权限，执行\n$ git clone https://github.com/libgit2/libgit2 这句命令会在当前目录新建一个名为libgit2的目录，并在其中放置远端同步过来的项目。如果想让目录叫别的名字，执行\n$ git clone https://github.com/libgit2/libgit2 会让目录叫mylibgit。\n如何确定成功初始化了一个Git仓库呢？\n进入对应项目跟目录下，执行\n$ git status 如果返回On branch master之类的信息，则表明初始化成功。\n如何开始用Git记录文件？\nGit能够识别目录中的文件是已记录（tracked）还是未记录（untracked）。开始记录某个文件，需执行\n$ git add \u0026lt;filename\u0026gt; 执行这句命令会将未记录的文件放入跟进区，文件变为已记录并且处于已跟进状态，等待被提交。\n如何跟进已修改的文件？\n如果一个已记录的文件被修改了，那么跟进的部分仍旧是未修改前的，要想让修改被跟进，那么也需要执行\n$ git add \u0026lt;filename\u0026gt; 如何查看已记录文件的修改后未跟进与已跟进之间的差异？\n执行\n$ git diff 如何查看已记录文件已跟进部分与前一次提交文件之间的差异？\n执行\n$ git diff --staged 或者执行\n$ git diff --cached 当执行git status时候，Git总把一些不相关的文件列在未记录的文件中，怎么样能够不看到这些文件，这些文件都不会被记录？\nGit提供了配置忽略文件（Ignoring Files）的方法，即配置.gitignore文件。该文件的每一行为一项，#开头的行会被当作注释。一行一般被用来配置要屏蔽的某一类文件，语法上支持通配符。https://github.com/github/gitignore中有很多很好的例子可以做参考。配置好的.gitignore文件放在项目根目录下即可。\n如何提交修改？\n执行\n$ git commit 会弹出编辑器让编辑提交的信息。或者直接用-m，即\n$ git commit -m \u0026#39;this is the message\u0026#39; 需要注意的是提交的修改都必须是已跟进的内容，如果想跳过跟进的步骤，直接加入-a选项，即\n$ git commit -a -m \u0026#39;this is the message\u0026#39; 不过需要明白的一点是，这句命令中被提交的都是已经有过记录的文件，如果是未记录文件，那么是无法提交的。\n至此git init部分的后三句命令应该都清楚含义了。\n如何删除一个文件呢？\n可以执行\n$ rm \u0026lt;filename\u0026gt; 这种方式仅会从磁盘上删除掉文件，但删除的操作并未被提交，还需要手动跟进提交一次。更容易的方法是执行\n$ git rm \u0026lt;filename\u0026gt; 会直接删除文件并自动做跟进。\n如果只是想不跟进这个文件，并不像从磁盘上删除该怎么办？\n$ git rm --cached \u0026lt;filename\u0026gt; 怎么对跟进的文件重命名呢？\n$ git mv \u0026lt;before_name\u0026gt; \u0026lt;after_name\u0026gt; 等价于执行\n$ mv \u0026lt;before_name\u0026gt; \u0026lt;after_name\u0026gt; $ git rm \u0026lt;before_name\u0026gt; $ git add \u0026lt;after_name\u0026gt; 提交的流程已经清楚，但要想查看提交历史怎么办？\n$ git log ?执行这条命令仅能够看到每次提交的校验码、作者、时间、修改的信息，怎么能够看到修改的概况？\n$ git log --stat 这条命令确实可以看到每次提交删除和新增的概况，不过要看具体的差异怎么办？\n$ git log -p 要是只想看最近两次的提交呢？\n$ git log -2 提交历史虽然是按照时间的倒序排列的，但似乎无法知道各个提交之间的继承关系？\n$ git log --graph 实际上git log还有查找特定字段--grep，自定义输出格式--pretty，显示单行--oneline等等一些更加复杂的命令，具体情况可参考Git的帮助手册。\n有时候查看提交历史后才想起来，有些文件忘记提交了，想覆盖最后一次提交的历史怎么办？\n$ git commit --amend 执行这句命令后，可以重新提交并覆盖最后一次的提交历史，实际上等了解了rebase后可以随意修改自己提交的历史。\n有时候提交时错误跟进了一些文件，怎么样能够取消跟进？\n$ git reset HEAD \u0026lt;file\u0026gt; 有时候想直接放弃某个文件的修改怎么办？\n$ git checkout -- \u0026lt;file\u0026gt; 到目前似乎都只是在讲本地的一些操作，怎么样能够知道远端仓库的信息？\n$ git remote 可以显示有哪些远端的分支\n$ git remote -v 可以显示分支的具体URL，关于分支的概念，在Git分支中会有更详细的说明。\n如果有多个远端仓库，怎么添加？\n$ git remote add \u0026lt;branch_name\u0026gt; \u0026lt;url\u0026gt; 如何获取添加的远端分支的代码？\n$ git fetch \u0026lt;branch_name\u0026gt; 这个操作，仅仅将远端代码同步到本地，不能编辑和修改，也不会自动并入到本地的任何一个分支。如果有某个本地分支在跟踪这个远程分支，直接切换到相应分支，执行\n$ git pull 或者\n$ git pull -r -r表示以rebase的方式并入本地分支，主要是将远端的提交记录与本地的提交做次序上的先后调整。\n如何将本地的代码推送到远端分支？\n$ git push \u0026lt;remote_branch\u0026gt; \u0026lt;local_branch\u0026gt; 或者当前的分支跟踪了远程的分支，直接执行\n$ git push 前面显示远端分支时候最多就是名字和URL，怎么显示更加详细的信息？\n$ git remote show \u0026lt;remote_branch\u0026gt; 怎么对远端分支重命名？\n$ git remote rename \u0026lt;old_name\u0026gt; \u0026lt;new_name\u0026gt; 怎么删除一个远端分支？\n$ git remote rm \u0026lt;remote_branch\u0026gt; 打标签是记录软件里程碑的重要功能，Git是怎么支持这个特性的？\n$ git tag 可以查看已经打过的标签。标签分含附注的标签和轻量级的标签，打含附注标签的命令是\n$ git tag -a \u0026lt;tag_version\u0026gt; -m \u0026lt;tag_message\u0026gt; 打轻量级的标签的命令是\n$ git tag \u0026lt;tag_version\u0026gt; 查看某个标签的具体情况的命令是\n$ git show \u0026lt;tag_version\u0026gt; 以上打标签的方法都是针对最新一次提交，对历史的某次提交打标签，只需要指定上检验码就好了。另外这些标签在本地打完，并不会被push命令推送到远端，除非显式的指出\n$ git push \u0026lt;remote_brach\u0026gt; \u0026lt;tag_version\u0026gt; Git中有些命令似乎很长，但又用得很频繁，有没有办法可以简化？\nGit提供了异名机制，可以自定义命令，例如\n$ git config --global alias.co checkout $ git config --global alias.br branch $ git config --global alias.ci commit $ git config --global alias.st status $ git config --global alias.unstage \u0026#39;reset HEAD --\u0026#39; $ git config --global alias.last \u0026#39;log -1 HEAD\u0026#39; 这段文字改写自《Pro Git》一书的第二版第二章Basics部分。这里的改写仅用作回顾，不推荐直接学习，原书中有很多图示的说明更加直观。第一章请参考Git初识。\n","date":"2015-05-08T00:00:00Z","permalink":"/posts/git%E5%9F%BA%E7%A1%80/","title":"Git基础"},{"content":"为什么要进行版本控制？ 我们需要记录对一些文档的编辑历史，特别是当多人合作编辑同一个文档时。有了这些编辑历史的记录，不仅能够方便查看更改，同时也能够回滚到过去的某个版本。\n版本控制系统有哪些应用？ 版本控制多用在代码管理中，但也有其他的应用，比如Google Docs、Wikipedia History等。\n版本控制系统经历了怎样的演进？ 简单说是从本地化版本控制系统（Local Version Control System）到中心化版本控制系统（Centralized Version Control System），再到分布式版本控制系统（Distributed Version Control System）。\n最初的版本控制用于本地的文档管理，通过一个数据库来记录修改前后的差异，被称作本地化版本控制系统（Local Version Control System, LVCS）。这种系统无法支持多人间的协作，进而产生了中心化版本控制系统（Centralized Version Control System, CVCS），将版本管理的数据库移到服务器端。CVCS中，客户端程序都只能够与服务器端进行同步，一旦服务器出现故障，所有的客户端程序都无法使用，服务器端的存储结构和历史记录也都可能丢失。分布式版本控制系统（Distributed Version Control System, DVCS），通过在每个客户端都克隆一个完整的服务器存储结构，从而解决了前面的问题。\n每种不同的版本控制系统有哪些代表？ LVCS：RCS CVCS：CSV, Subversion, Perforce DVCS：Git, Mercurial, Bazaar or Darcs 分布式的版本控制系统是否等于本地化的版本控制系统加上中心化的版本控制系统？ 功能上可以这样讲，但实现逻辑有着很大的不同。（怎样的实现逻辑呢？）不管是本地化还是中心化的VCS，主要记录的是修改文件之间的差异（又称补丁，differences or patches）。若要获得某个版本，就等于将很多的差异文件相加。分布式的VCS，记录的是每次提交的完整文件，常被称作快照（snapshots）。（这两种方式各自有哪些优缺点呢？）记录差异的优点在于磁盘空间消耗小，但获得不同的版本需要较多的运算。记录快照的优点在于获得不同的版本与对比版本差异计算都很快，缺点在于磁盘空间消耗大。由于磁盘空间现如今都不会是瓶颈，所以这个缺点基本可以忽略。分布式的版本控制系统带来的好处更多，所以越来越流行，特别是Git。\nGit是怎样记录文件的？ Git用SHA-1算法产生的40位长的校验码（checksum）记录所有的文件。具体讲是对每个被提交过的文件执行SHA-1算法，生成校验码作为该文件的名称或者身份，Git主要管理这些校验码。实际上不仅每个文件被执行SHA-1算法，每次的提交（commit）操作也会生成一个校验码，所以只要是提交过的内容，都有办法进行恢复。\nGit的基本结构是怎样的？ Git管理的文件会有三种状态：已提交（committed）、已修改（modified）、已跟进（staged）。已提交是指文件已经被保存在了本地的仓库中。已修改是指已提交过的文件有了新的修改但还没有提交。已跟进是准备提交前的一种状态。对应于三种状态，Git内部被分为三个区域，本地工作区（Working Directory）、跟进区又称缓存区（Staging Area）、本地仓库（Git directory）。已提交的文件记录在了本地仓库，已修改的文件仅位于本地工作区，而已跟进的文件位于跟进区。本地工作区是我们工作交互的区域，编辑修改的文件都位于这个区域，而提交前需要先做一步跟进，放在跟进区才能够提交。\n怎么样获取Git？ Linux: sudo yum install git （Redhat系列） sudo apt-get install git （Debian系列） Mac和Windows: 直接从Git网站下载安装包或者在GitHub网站下载安装包\n初次使用Git需要做哪些配置呢？ Git对每次的提交都会记录提交者的名字和邮箱，所以初次使用需要进行配置。此外，Git的许多命令都会调用编辑器进行交互，所以也需要配置默认的编辑器。\n怎么做这些配置呢？ 配置前需要简单明确Git对用户的配置信息有三个层次的管理：/etc/gitconfig、~/.gitconfig、.git/config。三个层次后一个层次覆盖前一个，比如在~/.gitconfig和/etc/gitconfig配置了同一个属性，~/.gitconfig会生效。/etc/gitconfig的修改会影响所有系统用户，~/.gitconfig只影响当前用户，.git/config只影响当前的项目包。具体可以直接编辑这三个文件，或者通过命令行完成。举例：\n$ git config --global user.name \u0026#34;Jon Doe\u0026#34; 配置文件中都是以键值对存储配置，例如user.name=\u0026quot;Jon Doe\u0026quot;。--global表示设置在~/.gitconfig中，--system表示设置在/etc/gitconfig中。\n如何确定当前项目包的配置情况呢？ 执行命令git config --list。\nGit中怎么获得命令的帮助？ $ git help \u0026lt;verb\u0026gt; 这段文字改写自《Pro Git》一书的第二版第一章Introduction部分。阅读过程中，发现写得非常流畅，是本值得力荐的好书。这里的改写仅用作回顾，不推荐直接学习，原书中有很多图示的说明更加直观。\n","date":"2015-05-06T00:00:00Z","permalink":"/posts/git%E5%88%9D%E8%AF%86/","title":"Git初识"},{"content":"之前的解决方案通过JavaScript脚本将公式转换为图片，即使用ASCIIMathTeXImg.js，在\u0026lt;head\u0026gt;\u0026lt;/head\u0026gt;中引用如下的代码。\n\u0026lt;script type=\u0026#34;text/javascript\u0026#34; src=\u0026#34;\u0026lt;?php bloginfo(\u0026#39;template_url\u0026#39;); ?\u0026gt;/js/ASCIIMathTeXImg.js\u0026#34;\u0026gt; \u0026lt;/script\u0026gt; 后面Google时发现了MathJax，提供了更加强大的公式服务。直接引用下面的代码即可支持。\n\u0026lt;script type=\u0026#34;text/javascript\u0026#34; src=\u0026#34;https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML\u0026#34;\u0026gt; \u0026lt;/script\u0026gt; 相比于第一种方式，第二种方式优势至少有两点：其一，加载的JavaScript脚本都是引用别人的链接，不会耗费自己托管服务器的流量；其二，功能更多，支持用户自定义，可以选择LaTex、MathML或者AsciiMath，解析结果也不再是图片，而是HTML、SVG或MathML。\n直接用MathJax服务唯一的担心是，如果被墙将无法访问，像Google的字体服务一样。实际上，MathJax也支持将脚本安装到自己的博客服务器上，源代码托管在GitHub上，但整个程序脚本较多，占空间，也会耗流量，所以还是推荐在没有被墙的情况下，直接使用服务为好。\n下面这个公式用第二种方式生成。\n$$e^{i\\pi}+1=0$$\n","date":"2015-02-05T00:00:00Z","permalink":"/posts/%E8%AE%A9%E5%8D%9A%E5%AE%A2%E6%94%AF%E6%8C%81%E6%95%B0%E5%AD%A6%E5%85%AC%E5%BC%8F/","title":"让博客支持数学公式"},{"content":"Chrome浏览器或者火狐浏览器按Ctrl+Shift+I，打开开发者工具，选择Network，可以用来分析加载网页时到底哪些链接拖慢了加载速度。以火狐浏览器为例，可以看到以下的分析结果：\n拖慢整个节奏的是来自域名fonts.googleapis.com的请求，无法解析的原因不言自明。找到原因后去相应的文件中修改代码即可解决问题。我站点使用模板的问题出现在style.css中，不同的模板会有不一样的变化，有了开发者工具，可以灵活应对。网上多有记录一般引起站点加载慢除了站点模板中有用google服务外，还有avatar也是一大类，这个可以通过安装Simple Local Avatar插件解决。修改后，加载时间立刻从40s减到了3.84s。\n由于模板来自网上，加之自己对前端也不太熟，看这个分析报告，可优化的代码还有很多，以后慢慢改吧。另外，以下的这张图显示Chrome加载速度略快。\n","date":"2015-01-08T00:00:00Z","permalink":"/posts/wordpress%E7%AB%99%E7%82%B9%E5%8A%A0%E8%BD%BD%E6%85%A2%E7%9A%84%E5%88%86%E6%9E%90/","title":"WordPress站点加载慢的分析"},{"content":"老子说“有无相生，难易相成，长短相形，高下相盈，音声相和，前后相随。”意在说明事物中普遍存在的对立统一的辩证关系，朴素确也深刻。这其中有无、难易、长短、高下、前后等五组都容易理解，大概是因为视觉比听觉更让人记忆清楚，容易想象。音和声的对立关系直觉中却难以建立，我想了许久才有些明白。\n声音在现代汉语中常常组合在一起表示耳朵的感知，准确一点是声波带动耳膜的振动感。实际上，音和声被用来描述不同对象。百科中的解释都太含糊，查音的时候，解释是声，而查声时候，又解释是音。有一种解释说音是有节奏的声，言外之意似乎是说音是一种特殊的声，说明的还是统一性，而难以体现音与声的对立关系。还有一种解释说音与心相通，声与耳相通，说得有些道理，却还不够直白。\n音和声在现代汉语中虽被组合在一起用，却也还有很多分开的时候。音的词组相对较多，像音阶、音律、辅音、高音、低音、乐音、噪音等，在这些词组中，替换成声不合适。声表本意的词组相对较少，我能想到的是声带、声波，这两个词组中也不可被替换为音。看这些词组的规律，音多用来表示具有特定名称的听觉感知，从对立的角度来讲声自然就表示相反的状态，可以说是非特定名称的听觉感知。好像还是不够具体，静下心来，闭上眼睛，听，左边传来喝水的声音，同时左前方传来打哈欠的声音，不到一秒右边倒水的声音，点击鼠标的声音，关门的声音，全部都分辨得清清楚楚。试想，我们的视觉感知有这种能力吗，有，放在眼前的东西，是长是短，是大是小一目了然，为什么，因为有了对比，脱离了小的物体，就无法说大，没有短，也就自然显不出长。音和声是同样的道理，假想世界上只有水流声，一个频率一种音色，关门声是这个频率这个音色，甚至咳嗽声也是这个频率这个音色，那么耳朵必定单调极了，只有小提琴没有长笛的世界不会快乐。\n","date":"2015-01-08T00:00:00Z","permalink":"/posts/%E9%9F%B3%E5%92%8C%E5%A3%B0/","title":"音和声"},{"content":"上周六晚接到贺老师的电话，说约我和小龙去香山探路，一方面为了筹备好下周第二届的pFinder聚会，另一方面也为了送一下我们两位毕业生。听到后免不了心中忐忑，想法很多。回宿舍的路上与师兄聊起来，头脑风暴一番，决定买几个气球，想几个问题，放在里面，埋到山中，届时娱乐一下出游气氛。到宿舍后，苦思冥想地写下八个问题，分开放在两个气球中，又放了常玩的智力游戏在额外的一个气球中。写到两点，方才睡下。\n一\n约定的时间在九点，我们提前二十五分钟到达，没想到，刚踱几步，贺老师就迎面走来。几句寒暄后，一起上路。跟贺老师走路，难免拘谨，我和师兄交替的一前一后，回应着。\n起步的地点在香山路和卧佛山西路的十字路口，从那里出发，一路向西，遇见岔路，再向西北，顺着碧云寺路，开始了一天的旅行。\n上山前的一段路，需穿过香山东北角的一个村落，待看到碧云寺高耸的塔顶，便知是后山的起点。很多的户外运动者与我们一道绕过碧云寺，来到山脚。我趁着休息调整的时间将第一个气球，埋在了旁边树林乱石堆中。怕自己忘记具体的位置，赶忙拍了照片。他们举旗拍照留念后，便与我们分道扬镳了。他们走向了一条还未完全开垦的坑洼土路，而我们走了一条平坦的水泥路。\n上山的路上，贺老师谈起了他本科、研究生时的事情。他很遗憾本科时，没能抽时间常到香山转转。令他印象深刻的是博士期间与北外的一次联谊，还在一起合影留念。他劝我们应当多参加一些户外的活动，多与人交流沟通。他大概是很清楚我们都不善与人交谈，希望能够有所改变。其实于我而言，跟有共同话题的人能滔滔不绝，说很久，但跟陌生人，或者完全没有共同价值取向的人很难聊到一起。读书越多，我发现自己越难去改变。\n随后的一路，有聊未来的人生路也有聊对过去人和事的回忆。\n贺老师提了个有趣的问题，说对于未来的子女，你希望他走艺术的道路吗？他提到父辈赚钱，子辈挥霍搞艺术，等几代一贫如洗后又重新开始奋斗。师兄对这个问题的回复是他大概希望，未来子女还能继续在他的领域学习，因为至少能给一些指导，艺术的道路有些陌生。我接过话讲，因为遗传因素，子女的天分和擅长应该跟自己相差不大，多半还是擅长自己擅长的领域，当然不排除例外。这个问题，其实我私底下曾不止一次想过，但当时还是忍住没发表看法。我想我大概不会限制子女必须要学什么，如果他（她）真的擅长艺术，我也不会反对，但我大概会让自己跟着他一起去了解，同时给他找好的引导者。\n谈到小时候对未来职业的期望和高考时候选专业。师兄说他小时候看了很多科学家的故事，所以希望成为科学家。他当初选择数学专业，是因为他对其他的专业根本不了解是在学什么，只有数学他比较熟悉。我对高考时选专业的理由也丝毫没有忌讳，完全是听从父母的选择，希望是高投资高收益，因为各学校的软件工程专业学费都很高。其实，我当初也还是受了初中一位同学的影响。他是我们初中班级中公认最聪明的学生，脑袋比一般人大，外号豆芽。我坐过他前面，曾经问他，你将来希望学什么，我以为他会回答物理，因为物理被普遍认为是聪明人学的专业，但我得到的答案是计算机。那时的计算机在我的概念中就是文字处理工具加游戏机。他的父亲多半受过大学教育，在市教委工作，他常常能接触到计算机，对一些电子设备也很了解。我虽然在五年级层学过一个暑期的计算机，但就学会了基本的绘图工具，文字处理工具以及开机关机。他的偶像不是爱因斯坦、牛顿，而是比尔盖茨、乔布斯。现在想想，那时的我离当代社会真的是有些远，即使是现在，我仍旧会有这种感觉。我似乎对当下的事情很少产生兴趣，学到的和喜欢的永远是所谓经典的。这些年逐渐有所改善，但我偶尔还是会担心赶不上时代步伐。对于职业的期望，我想会是架构师，这个我从小根本不知道的职业。说起天分，朦胧中曾对唱歌有想法，但从未被引导过，也就没有萌芽，现在对这个职业已经基本丧失兴趣。\n贺老师说他高考时候语文考得不好，所以后面很注意写作，他是在看过秀哥博客后才意识到他爱总结。贺老师高考最没压力的学科是英语，初中时总考满分，但上大学时候，因为词汇量欠缺，所以略感需要学习。我被问起什么时候觉得学英语有压力，我回答是在高中，刚开始上高中做完型填空总是错很多，经过高考的训练变得好一些。跟贺老师打过交道的人，大概不会觉得他语文学得不好，反而会觉得他很擅长，因为从他的邮件、演说、交谈中都无法让你相信他不擅长。我想，这大概是他后期刻意去注意的缘故，什么东西刻意去学，并且坚持下来，总是能变得更好。用贺老师的话来讲，大概就是日行二十英里与一万小时定律。\n边走边聊碰到了第一个分叉口。这是条少有人走的路，即使沿途没有荆棘丛生而且显得很平坦。遇到一个路人，他也不清楚快活林怎么走。没辙，凭直觉我们选了那条上山的路。走了半个多钟头，待又碰到路人问起还要多久到快活林时，方知岔路口选错了道，应该向下走。无奈，只好折回。回到分叉口，行走十多分钟后路遇第二个分叉口，踌躇不定之际，看到远处有对夫妇。小步快跑赶上他们询问。幸运的是他们对路很熟，被告知顺着远处有电线杆的路就可以上山。回来汇报贺老师和师兄，意识到差一点又选错了道。联想人生的道路，这几年做的研究道路，又何尝不是如此呢。谁人能看清人生道路的全貌，谁人又能搞明白研究道路的前方在哪里。我们应该感激那些给我们指导的人，他们如海上的灯塔，拨开迷雾的风，让我们清晰了选择，脑中逐渐绘全整个地图。固然，有过来人的指引是幸运的，免不了很多的时候需要摸黑走，这时一个人能否正真探出一条路，有更加惊奇的发现，才是真正的考验。\n绕过挂甲塔，就是上山路。临近中午时分，寒气已经散尽，浑身开始温热。道路两侧枯树依旧，路上人少，飞鸟也不多，显得寂静万分。三人不作声得走了一阵。身处吵闹中，心会随之躁动，身处寂静中，心会随之平静。山，威严雄壮，难容聒噪。山，起伏幽深，包容万物。万物丛生，给山增添灵气。万物冬眠，还原了山的庄严。三个来自山西的同乡人，大概对家乡的山都会有特别的情感。我依旧清晰记得老家山上的那棵酸枣树，那块大石头，还有石块上的青苔，都曾是乐园中我的爱物，我无法抹除对它们的记忆。\n贺老师放起了一首我和师兄都陌生的歌，关贵敏的《太行颂》。歌曲悠长舒缓，却又演唱得高昂嘹亮，初听来让人精神放松，情至高处，又让人血脉喷张。太行山脉北起北京西山，横跨北京、河北、山西、河南四省，绵延四百公里。我们此行的终点也就是西山国家森林公园。\n沿着电线杆的路实际上是香山公园背面的一条路，快接近山顶的地方，山路由北转向西。是香山和西山接壤的地方，也是香山山峰的边界线，这里视野开阔，可以看见远处的山脉，又可以看到广袤的蓝天，北京城西部一隅也尽收眼底。只身于山体和弯曲的山路中时，视线常被阻断，只有站在这高处，站在这开阔的地方，视线才能走得更广更远。这难得一见的景致，引得人驻足留念。只为这景致，也不虚此行。\n路过一座影壁墙时，对面的悬崖边散乱着一些碎石，大大小小，落在枯黄的荆棘下。我忙把第二个气球埋下。\n走到快活林，已是正午，这里是香山和西山的分界点。早晨出发只吃了一个鸡蛋和两小杯酸奶，此时腹中早已饥肠辘辘。我们匆匆下山，只为不错过中午饭点。\n离开西山公园前，在东门口的假山中埋藏了第三个气球。\n二\n七天内在一个新鲜的路上走过两遍，是一段有趣的经历。好比一部电影看两遍，第一遍新鲜感重，前方未知，突然伸出一只手，足以吓得浑身冒汗，第二遍看，会更多的去寻找第一遍记忆中有趣的桥段，重新温习，也略带会有新的发现，但突然伸出的手，已经没有原来的震慑力了。带陌生人一起走第二遍，会更加美好，因为你可以领着他人走上预期的正确道路。\n集齐十六人，不比三两人，只有强有力的号召力才能让所有人准时。预定八点半从山脚下出发，推迟到了九点。人多后行进的步调也难一致，三三两两结伴。我跟小龙一前一后，带着大家以防走散。\n路还是上周的路，但相伴行走的人不同，内心的情感也随之不同。组里不像以前外出时，黑压压的一片，现在映衬着红、天蓝、粉。有爱安静的，跟同行的师兄，有一句没一句的聊些山外的东西；也有活泼的，遇到下坡路，一路奔跑，跑热了，把外套脱下来交给男朋友；还有沉稳的，看着山里的风景，默默行走。\n第一次停脚处是埋第一个气球的地方。年长的对这种小游戏已经没有了兴趣，只有年轻的几个师弟师妹还乐意玩这个游戏。事情见多了，难免心中麻木，心里需要更强烈的刺激才能兴奋，亦或者是参与其中后会显得不够成熟稳重。第一个气球是被杨皓找到的。里面写了四个人物谜语，分别来自四大名著，都是性格凸出，虽不是主要角色，但留给人深刻印象的人物。\n他出生地芙蓉花满城。他为人短小，放荡不治节操，却很有才干。结交曹操，不被礼遇，而改为结交刘备。终死于兄长告发。\n猜《三国演义》中一人\n她也姓林，也叫玉，因避讳而改名。上司秋纹、碧痕骂她“没脸的下流东西，拿镜子照照，配递茶倒水不配”她生性聪明，口齿利索，攀了高枝。与人易帕，私定终身。\n猜《红楼梦》中一人\n他神通广大，法力无边，手持一柄月牙铲，是碧波潭万圣龙王的入赘女婿，因下血雨盗宝珠而遇孙悟空，后被二郎神、孙悟空制服。\n猜《西游记》中一人\n他的枪法天下独步，原为京师金枪班教头。吴用用计让时迁盗甲赚他上梁山，后大败呼延灼，破其连环马。终在征讨方腊时，被毒箭射死。\n猜《水浒传》中一人\n被猜到最多的是《红楼梦》的问题，慧君、小龙都有猜到是小红，本名林红玉。猜到问题最多的是樊师兄，猜到了三个，除了《水浒传》一题的徐宁没有猜出。我想如果浩哥在，或许能全部答对。\n第二个停脚点在挂甲塔，我带着几个师弟师妹走在前面，小龙跟师兄们走在后面，眼看绕过弯后，我们已经甩开他们上千米了。没想到，他们找了一条下山的小土路，超近道，赶在了我们前面。我远远的看见，以为碰见了跟他们穿一样衣服的人，走近了才确认确实是他们。这里是路标，得照个合影。大家迅速聚集，留念，以证明来此走过。\n走到第二个气球的埋藏点前，几个人纷纷上前寻找，乱石之中，大家都是先对照我预先发送的图找相似的方位，看来看去，没等下手，杨皓又找到了。这次的气球里写了四个哲学家的谜题。\n他出生在苏格兰爱丁堡。他是经验主义者，也是不可知论者。他只接受用感官认知的事物。除此之外，一切都有待证实。他与佛陀的观点一致，认为没有不变的自我。\n他是现代哲学之父，他是理性主义者，他发现了三件事：一、人是会思考的生物，二、上帝是存在的，三、宇宙有一个外在的真实世界。\n他是位严谨的逻辑学家，也是一位伟大的组织家，他发明了各种学科并加以分类。他批判柏拉图的理型论，并将事物的本身分“质料”和“形式”来看待。一件事物的“形式”不但说明了这件事物的潜能，也说明了它的极限。他描述了三种良好的政治制度，即君主制、贵族政治和民主政治。\n他是余秋雨的家乡人，著名哲学家，陆王心学之集大成者，精通儒家、道家、佛家，主张“知行合一，以致良知”。\n没想到最多人猜到的是王阳明，看来组里对明朝的历史比我熟，我是听了小龙介绍后才去查的。能答对休姆，应该是读过入门的哲学书了。\n下山，我们寻了条新路，途经八角亭，花溪，招远烈士林园。等出东门时，大家都已经疲惫不堪。留了假山处红色的气球待以后再来寻吧，不知到时还在不在。\n人生有些路可以重复走几遍，但有些路，只能向前，没有回头重走的机会，要踩稳脚下的步伐，尽可能让内心踏实。终点不是目的，沿途的风景最美。\n","date":"2014-12-12T00:00:00Z","permalink":"/posts/%E9%A6%99%E5%B1%B1%E8%A5%BF%E5%B1%B1%E6%B8%B8%E8%AE%B0/","title":"香山西山游记"},{"content":"过宝安机场安检排队时候，我不住回头看了三五次，酸楚瞬时涌上心头。前两次回头，看见小龙与甡哥还在向我挥手告别。第三次我有意不回头许久，待扭头时，看见的已经是他俩远去的背影……\n相聚太匆匆，来去不过一天不到的时间，但仿佛经历了许多。\n三年前毕业时，宿舍一伙人决定三年后相约北京，但因为一些变故，临时改在了深圳。\n深圳是小龙跟胡Sir的主场。他们在深圳都呆了三年有余，也都找到了心仪的人，应该计划长久落脚。心里很为他们高兴，也有些羡慕。\n去时乘坐的是十六日上午十一点半的飞机，结果近十二点半才起飞，到深圳着陆已是下午三点一刻。小龙接的我。出站口只有一个，远远看过去举着牌子的人围满了护栏。我朝着约定有着肯德基的标识走去，第一眼就看到了熟悉的身影，还是一样瘦得“销魂”，不变的白色短裤，不变的发际线。一个拥抱，感到温暖，令人怀念。\n还记得离开西安的那天，斌哥跟玉柱送的我，也是少有的拥抱，令人怀念。\n我决定到他家坐坐。公交地铁公交，一路倒了几次车，但丝毫没觉得疲惫。杂七杂八聊了一路，还是大四时候的那种感觉，熟悉的声音、语调，似乎时间的相隔没有三年。然而，谈话中，我能感觉到他还是有些变化。从前洒脱地为自己喜欢的东西不惜花掉一个月全部的生活费，经常性地拆了东墙补西墙，现在却有所顾忌。或许还是为了自己的所爱，但这种爱可能更加被认可为是一种担当。说实话，我向来都很羡慕，因为我做不到。\n见到了小龙的媳妇，广州人，很漂亮，看起来就很文静。讲普通话时是典型的广东式普通话，声音很好听，感觉很温柔，小龙你真是赚到了。\n家里虽不算整齐地令人发指，但很干净、整洁。房子不大，装修得不错，感觉简直太舒适了。\n家里养了两只猫，一只九年大，另一只三年大。九年的是家猫，公，混合品种，体态像波斯，脸型像传统家猫，通身白黄相间的长毛，白色白得洁白，黄色黄得金黄，非常好看。三年的是流浪猫，母，品种不详，短毛，白色为主，伴有黑色的花斑，也被养得圆滚滚，明显衬出了脑袋小。听说母猫生过几只小猫，长得都像自己，听来好可惜，公猫的良好基因没有被表达。\n晚饭被安排在了粤季轩，一家无论从名字上还是装修风格都很广式的餐厅。\n这次来聚的只有七人。苏龙罡、玉柱、斌哥、玮哥、宝柱没能到。苏龙罡在北京，三来来，每年至少能见一次面。玉柱在一二年在天津小聚时候也见过一次。斌哥毕业到北京工作，见了两次。宝柱在北京出差几次，有聊过。只是玮哥，可能要六年后见了。\n餐桌上气氛不错，聊得很开。昊哥跟小龙经常在群里聊天，彼此信息能熟悉些。有趣的事情还是回想起大学的时候，那时的我可能在自习室跟图书馆的时间比跟大家在一起娱乐的时间多，所以听来了很多不知道的事。诸如被三毛爆料说了SLG买Condom时的羞涩，昊哥接话讲了与SLG买Condom时尴尬的段子，还有胡Sir说起隔壁宿舍陶同学买望远镜偷窥宿舍对面宾馆的房间，也还有枫少的经典语录，胡Sir的花，小龙的点卡，玉柱的开心等等。黑辅导员大家也是乐此不疲，昊哥的段子挺逗。讲到辅导员查宿舍内务卫生跟早晨上课的出勤，给部分不爱听课的同学留下了“难忘”的记忆。我听到这些，感觉自己在大学还是错过了很多有趣的事情。想来人总是患得患失，只要当下过得踏实就足够了。聊天期间，我的思绪不停地跟着他们回到大学时光，仿佛是在昨日。\n饭桌间，斌哥打来电话，大家轮流一通问候。\n昨天的饭桌上，每个人可能都不像三年前那么单纯，每个人心里可能都藏了很多的苦涩，但饭桌上，每人都开心于相识、相聚的不易。\n抱怨还是有，但现在听来已经不同于以前。\n酒喝得不算多，但已经够助兴。\n大伙吃得不错，十点多后方才散去。\n今天清晨，七点多被枫少叫醒，退了房，等其他人起床后已是九点。\n十点多在粤季轩吃了顿特色的早茶。玲琅满目的蒸饺、包子，应接不暇的烧麦、点心、茶、粥。最逗的是枫少说出了大麦茶口感的真相，其实也真是说得通，方便面确实是用麦子做的。\n深圳其他的朋友还是有一些，时间仓促，中午找钿哥、柯柯坐一起聊了聊。意外的是镇嵩从香港那边过来兑换钱，刚好也一起。寒暄过后，一起坐了一个多钟头。随后便是照相、留念、离开。\n回来的飞机上，我坐在了靠窗的位置，飞机飞稳后，向下望去是一片片的云海。有些被阳光照得通亮，格外艳丽，有些灰蒙蒙，乌突突作一团。这些景象我难得见到，我将珍惜所有这些驻留过我脑中的景象，不管它是华丽漂亮的还是简陋朴素的。\n二零一四年八月十七日\n","date":"2014-08-17T00:00:00Z","permalink":"/posts/%E6%9D%A5%E5%8E%BB%E5%8C%86%E5%8C%86/","title":"来去匆匆"},{"content":"看着缓缓升起的孔明灯，我内心的希望又燃烧了起来，虽没有烈火那般炽热。\n第一只意外地坠落令我吃惊与失望，感慨命中注定，我默念的期盼大概就如同这灯，灯芯与灯罩身首异处，不能一起飞向高空、飞往远处。第二只起飞前也极不顺利，不仅是因为风大，也是大家的耐心不够，更因为我的躲避而不愿意更多的参与与承担。如第一只飞起时一样，我掌握着火源，只负责点火，大伙儿帮忙扶着灯罩，不同于第一只点燃时所犯的致命性错误，我参与了燃料绑缚于铁丝上的过程，了解到点固体燃料时要点四个角，千万不能点中间的小孔，因为那是固定铁丝的地方。点燃第一只时，师妹已经套好了燃料，我用火机烘烤固体燃料，半天没有动静，嘈杂中听到志远说点中间的小孔，我以为自己之前很蠢不知道小孔的地方是用了引火的材料，因为在我将火源移动到小孔所在的地方时，燃料上迅速窜起了火苗，不一会儿整个燃料就烧起来了。然而，在大家放手后，飘了还不到三米，燃料突然从灯罩上掉了下来，大伙失声而笑，但我却感到一阵的难过，不是因为这灯是我买来的，它的一切就要跟我有什么牵连，而是我的担心，我的踌躇，全都在它身上表现了出来。迅速大伙儿七嘴八舌发表意见，什么原因导致它没有起飞，多数归咎于风大，不适宜放飞，很多地方被气流压得鼓不起来，也有人说是大家耐心不够，气还没有完全充满灯罩，或许应该放低些，再耐心些，但这些都不能说明为什么燃料会掉下来，那只能是没有捆绑好。当我拿起第二只，问师妹你是怎么固定燃料的，她也有些慌乱，回答我说是直接穿透了中间的小孔，然后接手又固定了上去。顿时我意识到自己所犯了错误，错听了别人的意见，臆想了小孔的作用，但即便知道了这些，我还是没有信心指望它能够飞起来，毕竟我当时的心情已经失落之极，弄丢了跟朋友借来的相机的闪光灯，还放不起一只孔明灯，更别说寄托着我的期盼了。\n点第二只灯的时候，旁边的看客耐不住性子，拿起自己火机一起帮我点。两个火源，不一会儿四个角都着起了火，在他的指导下，大家把灯罩放低，想让冷气流尽可能少的进入灯罩，让灯罩里的空气快点暖热。在我的催促下，大家又一次齐手放开了孔明灯。最初像第一只一样，在离地面四五十公分的高度被风吹打，还时不时撞击一下地面，不过好在燃料没掉。志远在众人的瞩目下快速跑去追飘远的孔明灯，我当时犹豫了一下也追了上去，只是担心点着天津站周边的草坪，烧伤海河边的游客。贺老师也建议，灭了火拿回去改天再放，我也基本不指望它能够起飞了。在距最初点灯四五十米的地方，我与志远重新将灯撑了起来，因为他还是热情高涨，希望看到起飞的孔明灯。我们压低灯罩，撑起陷落的地方，其间还听旁边人说有个地方破了，我看了一眼也没找见，不过也足够浇灭我的愿望了。等了许久，我们齐手放开，可它还是低低不起，眼看快要撞着岸边的花池壁了，志远放声喊叫，“给力啊”，我虽没有那样，但心中的焦急冲上了整个心头，我全然感觉不到周围人群的存在，只盼望着它能起飞，终于它越过了花池，在夜风的助动下，扶摇而上，而后我听到了大伙儿的欢呼。\n走向天津站的路上，我时不时抬头凝望，直至它消失在视线之外，许是飞高飞远了，许是被冷风吹灭了，许是氧气不足熄灭了，许是灯芯又一次脱落了，但不论怎样，它都起飞了，它曾经飞高、飞远过。\n","date":"2013-04-01T00:00:00Z","permalink":"/posts/%E6%94%BE%E9%A3%9E%E5%AD%94%E6%98%8E%E7%81%AF/","title":"放飞孔明灯"},{"content":"为什么 为什么 数月已过 却仍旧无法倦腻 多么希望能像这雷声 响彻苍穹 如这雨滴 倾注大地 即便稍纵即逝 却也是爽痛畅快 然而因为那点私心 那点懦弱 却也只能在这般电闪雷鸣 风雨交加的夜晚孤枕难眠了\n好一阵雷雨 带走了闷热 带来了凉意 带走了焦虑 带来了愁绪 时有闪电划过帘外 如同轻闭的眼前亮起一道光 间或雷声入耳 震起心脏的跳动 雨点时疏时密 或弱或强 迫使无法入睡的人去倾听这自然的韵律\n","date":"2012-05-19T00:00:00Z","permalink":"/posts/%E9%AA%A4%E9%9B%A8/","title":"骤雨"},{"content":"越来越觉得人的情感需要寄托，当托给明月或者宠物也就离寂寞更近了，所以想要满足、想要幸福还是需要寄托他人。孩子的情感容易得到满足，因为他们所接受与付出的情感都是纯真无邪、毫无含蓄隐匿的。成人的情感却难以满足，因为他们的情感开始被包裹起来，遮掩的自己难以察觉到根本需求，直到时间磨平了内心那些狂乱的躁动。或许理智的情感不是青春的狂想曲，或许青春就本应放荡不羁、尽情挥霍，但片刻之后便更感失落与彷徨，这便是短暂兴奋所带来的副作用，但因为人处青春难免义无反顾。然而所有这些瞬时的冲动与稚嫩的想法只会徒增情感的空虚。唯有用心经营的情感才能永久填补这种空白，这样说来似乎无关爱情的事情，人生岁月中也唯有淡如水的朋友之交，相濡以沫的夫妻之道，牵挂千里之外的亲子之念，才足以胜任。年轻人总爱将心底那点小小的冲动长挂嘴边，但多数人大概还是清楚自己真正的需求的，所以他们也就只能在嘴边消遣消遣，而不会因为人云亦云而给自己的未来增添更多的不快与艰辛。\n2012年4月12日\n","date":"2012-04-12T00:00:00Z","permalink":"/posts/%E5%AF%84%E6%89%98%E6%83%85%E6%84%9F/","title":"寄托情感"},{"content":"人生的起起落落好似昨日的惊喜不断对比今朝的茫然四顾。人真的是主观意识极强的动物，活在快乐之时，总是外部周围的事物发展迎合了内心那点渴求与幻想；而失落之时，也总是计划落空或者期盼没有如期而至。我们的主观意识形成于社会观念的渗透与家庭环境的熏陶之中，这种意识在大脑中极其强烈，强烈到我们极少注意到它们的存在，所以我们也就难以调节自己的快乐与哀愁，即便我们终于意识到了它们的存在，也早就难以改变那种存在，或许人生环境的巨变会改变那种存在，如鲁滨孙在荒岛上生存了多年后，不过这也只是将其转换为了另外一种强烈的存在。实际上，人在成年之后这种存在必须强烈否则他永远都是个孩子。强烈的意识使我们平衡了心智，对万事万物都有了自己的解释，但同时也给我们带来了另外的负面影响，我们心甘情愿地墨守成规，我们做出去改变的努力多半也是徒劳。此外，现代人的空虚多半也是源自于意识的美好难以在生活中践行。\n随着年岁的增长这种意识只会变得更加强烈，我们也只有降低自己的期望去迎合这种意识来达到我们可能拥有的最大快乐了。\n","date":"2012-03-28T00:00:00Z","permalink":"/posts/%E5%A6%82%E4%BD%95%E5%BF%AB%E4%B9%90/","title":"如何快乐"},{"content":"I can not tell why this heart languishes in silence. It is for small needs it never asks, or knows, or remembers.\nfrom Stray Birds by Tagore\n穿过银锭桥走了不久，就听到前面的酒吧里传来新年来临前的倒计时，我有些按捺不住自己的情绪，好想放声大叫，但是终究有些顾忌，只是放大声音对着同行的思远和文斌抱怨了一句说年马上就要跨过去了我们却要在路上度过。 寻找约定地点的路上，我还是坚持发出了一些新年祝福的短信，虽然被思远嘲笑说现在早过了短信祝福轰炸的年代，但我渴望得到一些祝福，那些来自于憧憬、追忆、认同和宽恕的祝福。\n寒冬深夜的后海显得意外的热闹，形形色色的人进进出出于酒吧间，招揽生意的人像长途汽车站那些非法运营车辆司机一样对你穷追不舍，直到问清你的意图。来这里的人似乎总是很清楚自己的意图，对那些人也只是含糊回应，只盼望着能甩掉他们。 没费多少工夫便找到了汇合的酒吧，进去后老板很热情，但我们没有发现同行其他人的身影，于是文斌忙着联系，我们站在酒吧一层的一个狭窄的过道中，显得格外的拘束与不自在，至少我有这种感觉，直到在二层见到大家坐下后，心情才得以稍许的平静。寒暄、问候之后要点酒时，因是节日之际店家没有特价的酒品，鉴于大家囊中羞涩，所以打算换一家。出去朝着热闹的方向移动了稍许便找到了落脚点，这家的环境与风格与前家迥异，单从演出的乐手就能感觉出来。前面的店里是位独唱的女孩，打扮的有点台湾姑娘的感觉，唱的歌曲也都是甜甜的；后面的店里是个摇滚乐队，除了鼓手之外各个都是长发飘飘，还好演奏的都是些抒情的慢摇歌曲，我还可以接受。我点了杯Margarita，粉色的液体，表面浮着些许碎冰，杯壁周围撒着白色的盐粒，闻起来有股清香的酒精混杂着柠檬的味道，口感也还不错，但周围的盐令我有些不适应，因此基本只是沿着一个杯口在酌。难得有机会来这里放松一下，大家围在一起拿起筛子玩，虽然很吵，但大家兴致都很高，我终觉得提高嗓门说话有些费劲，也就没有参与，只是静静地听着他们的演出，时不时的和旁边两位搭几句话。时间总是过得飞快，因为说好早晨还要帮姐姐订火车票，要同来北京签证的大学舍友见面，所以还是决定两点之前离开。乐队早在一点一刻左右的时候就走了，酒吧的人也散的差不多了，看对面的桌子由一对青年男女到一位年轻女孩再到空无一人，我也觉得是时候回去了。好在有思远陪同一起，回去路上也没觉得很漫长。\n早晨在闹表的帮助下，按计划起床了，天气不错，心情也不错。订好票后等了近一个小时，终于接到了罡哥（这里不知如何称呼了，且这么叫吧）的电话。十几分钟后北影对面的天桥下公交站，见到了罡哥和枫少。大学毕业也有半年之余了，却没有丝毫久别之感，可能的确不算久吧，何况我和罡哥中间还吃过两次饭。隆冬季节，各处公园景点是没有看的必要了，798艺术区是这个时节的一个好去处。游客不比十月份时候来的少，丝毫没有萧条之意，只是寒风有些冷瑟瑟。绕着一个个的展间从一点左右转到四点。我也意外的发现了各式各样的卡通明信片格外的吸引我的眼球，遗憾我没有要寄送的人，或许是大家都更愿意用网络的缘故。突然想起刚上大一的时候我还买了七八张西电新校区的纪念卡，买了一本信纸，但至今信纸都未曾拆封，卡片也没有寄出去一张。废旧的生产车间或许天然就是容易萌生艺术的地方，明朗的写实艺术是备受普通人喜好的，做成的各种手工艺品也备受大家欢迎，这种小店中的人也是络绎不绝；隐晦的写实艺术只能留下游客们的一些猜测与调侃，这种地方人也算不少但都不会过长时间的驻足；然而另外一些凸显个人情感的作品我们这些俗人注定无法欣赏也无法做出评价了。\n离开798到西单吃了顿快餐后，在几个商场里疲惫的拖着腿走了一个多小时。逛商场是注定不适合我了，尤其是在疲惫的走了一天之后，好在该来的时候还是会来的。去北京西站的路上罡哥突然说要给我介绍位政法的学妹，让我顿时心慌起来，我知道他或许只是一说。我不知该如何回应，也许符合我性格的回答是我当时的回答，我是一个不会说出违背自己心愿话的人，如果我必须要做出回答也只好含糊其辞了，这也使得我在保送面试回答老师提问的时候显得很尴尬。曾经看到有人说单身意味着你足够坚强，有足够耐心去等待那个值得你拥有的人。我很认同前半句话，但觉得后半句只是单身的人对自己的一种心理安慰。或许那个值得你拥有的人就根本不存在，当你意识到这一点时，真正能够继续坚强的人我真的十分佩服，这样的人有但真的不多，然而我逐渐感觉到自己好似没有那般的坚强，却又不愿简单地屈服。自己没有足够的勇气，如今又缺少坚强，真的令自己感到十分心慌，害怕无端的梦中惊醒后独自到宿舍的阳台外难过地吟唱美雪的《时代》，害怕和朋友打完乒乓后在宿舍里无端地啜泣。最近越来越感觉一个人喜好的影视类型往往是一个人期望体验的东西，所以没有体验到理想中爱情的女生也就比较喜欢看些多愁善感的文艺片，而对爱情要求不高的男生也就更愿意去看科幻与动作片。生活总是会给人各种产生遐想的机会，却又剥夺了他实现遐想的机会。\n希望这一年里，能够少份忧愁，多份快乐，不是表面上的微笑，而是内心真正的快乐。\n2012年01月01日晚\n","date":"2012-01-01T00:00:00Z","permalink":"/posts/%E6%9D%82%E4%B9%B1%E7%9A%84%E6%80%9D%E7%BB%AA/","title":"杂乱的思绪"},{"content":"今天系统的学习了一下CSS(Cascading Style Sheets)的语法。之前看书时候感觉很乱但最后总结下来其实也就两个大的方面。现在记录下来以便帮助以后回顾。\nCSS代码放置的位置 1. 内联式样式表\n这里是指的每个html标签都有一个基本属性style，直接可以利用style设置该标签的样式。例如：\n\u0026lt;p style=\u0026#34;font-family:Times New Roman; color:blue\u0026#34;\u0026gt;content with decoration\u0026lt;/p\u0026gt; 2. 嵌入式样式表\n要对同一个页面中某种标签都产生统一的样式，而不必要采用上面的第一种方式，提高了代码的重用性。这种方式需要将代码放置在页面的head标签中，如下：\n\u0026lt;head\u0026gt; \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- p { font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; \u0026lt;/head\u0026gt; 按这种方式定义的只要该页面中使用\u0026lt;p\u0026gt;\u0026lt;/p\u0026gt;标签，则会使用该样式，除非定义自身的style属性则会覆盖全局的设定。\n3. 外部样式表\n为了进一步提高代码的复用性，有时候许多的页面会采用同样的样式，这样就有必要将相同的样式部分提取成一个专门的叠层样式文件，后缀名通常为.css。如果要在某个html中使用它，则需要用如下的语句包含进去，并且放置在\u0026lt;head\u0026gt;\u0026lt;/head\u0026gt;中：\n\u0026lt;link rel=\u0026#34;stylesheet\u0026#34; type=\u0026#34;text/css\u0026#34; href=\u0026#34;外部css文件名\u0026#34;\u0026gt; 4. 输入样式表\n这种方式是提供css文件中包含另外一个css的语法。当然也能够在html的嵌入式样式定义中使用。使用方法就是包含如下的语句：\n@IMPORT url(\u0026#34;外部css文件名\u0026#34;); 样式选择器 样式选择器一般说是六种，实际个人感觉就是四种基本的加上两种不同的复合定义方式。样式的定义本身就是属性的关键字style。后来为了提供全局的加入了style标签。但是无论采用上面提到四种方式的哪一种都只是针对具体某个标签或者全部的某种标签。例如页面中有十个p标签，如果想让其中4个有一组修饰样式，另外6中为另外一种修饰样式，则只能单个的定义每个p的style属性。代码量最少也就是定义一个全局的控制其中6个一致的，剩余的4个分别定义。但引入class样式选择器后上面的问题的解决就方便的多，只需要定义两个。css样式选择器使得样式的定义方式多种多样，这里就不做过多的个人体会了，重点说总结。样式选择器的六种分别是：\n1. html选择器\n这个是最基本的css修饰的对象，即每个body以内的html标签一般都可以修饰。\n2. class选择器\n每个html标签基本都有一个class属性使得它们即便标签名不同，也能够具有同样的修饰样式。\n如果针对的是某中标签，则为如下定义方式： \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- p.tradition { font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; 使用时 ```html \u0026lt;p class=\u0026#34;tradition\u0026#34;\u0026gt;content with decoration\u0026lt;/p\u0026gt; 如果要想让不同标签名的标签具有相同的修饰方式，只需以点开始定义样式，如下： \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- .tradition { font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; 使用时 ```html \u0026lt;p class=\u0026#34;tradition\u0026#34;\u0026gt;content with decoration\u0026lt;/p\u0026gt; \u0026lt;a class=\u0026#34;tradition\u0026#34; href=\u0026#34;index.html\u0026#34;\u0026gt;content with decoration\u0026lt;/a\u0026gt; 3. id选择器\nid选择器也是利用每个标签的另外一个属性，id. 进行定义，类似于class，但需要以进号开头，由于id名的唯一性，通常id用于定义div标签中整个区域块的修饰。定义方式：\n\u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- #top{ font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; 引用时\n\u0026lt;div id=\u0026#34;top\u0026#34;\u0026gt;\u0026lt;/div\u0026gt; 4. 伪元素选择器\n有些标签不同属性代表不同的状态，也可以具有当前状态的修饰，常用的就是链接标签a. 如下面的定义\n\u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- a:link { text-decoration: none; font-family: Times New Roman; color: blue; } a:hover { font-weight: bold; font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; **5. 关联选择器** 关联选择器相当于对标签之间做了次且运算，只有按照定义标签之间的组合顺序才能够正确的应用该定义的样式，比如下面的定义： ```html \u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- center h1 em { font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; 上面的组合情况说明只有center标签里面有h1标签，并且h1中套用了em标签的情况下才能正确的应用该样式。如下的使用：\n\u0026lt;center\u0026gt; \u0026lt;h1\u0026gt;This is a \u0026lt;em\u0026gt;test\u0026lt;/em\u0026gt;\u0026lt;/h1\u0026gt; \u0026lt;/center\u0026gt; 注意上面例子的显示结果只有test是蓝色的。另外需要注意的是几个标签之间都是空格分隔。\n当然关联也不止局限于html标签，当然也可以是自己定义class标签和id标签。如下的定义：\n\u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- #tradition .top em { font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; 使用规则还是一样，必须同时满足定义顺序的才可以生效。\n6. 组合选择器\n组合选择器相当于同一样式应用于不同标签，或者不同类别，不同id的简化定义。各个标签、class名或者id名之间使用逗号，即\u0026quot;,\u0026quot;，隔开。应用方式如下：\n\u0026lt;style type=\u0026#34;text/css\u0026#34;\u0026gt; \u0026lt;!-- #tradition, .top, em, h1 { font-family: Times New Roman; color: blue; } //--\u0026gt; \u0026lt;/style\u0026gt; ","date":"2011-01-07T00:00:00Z","permalink":"/posts/css%E5%9F%BA%E6%9C%AC%E8%AF%AD%E6%B3%95%E7%9A%84%E6%80%BB%E7%BB%93/","title":"CSS基本语法的总结"}]