<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on 冯威的博客</title><link>https://fwhyy.com/posts/</link><description>Recent content in Posts on 冯威的博客</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sat, 16 May 2026 16:05:00 +0800</lastBuildDate><atom:link href="https://fwhyy.com/posts/atom.xml" rel="self" type="application/rss+xml"/><item><title>从 Vibe Coding 到 Harness Engineering</title><link>https://fwhyy.com/2026/05/from-vibe-coding-to-harness-engineering/</link><pubDate>Sat, 16 May 2026 16:05:00 +0800</pubDate><guid>https://fwhyy.com/2026/05/from-vibe-coding-to-harness-engineering/</guid><description>&lt;p&gt;春节之后一直在深度 Vibe Coding 做一些事情。将最近收集的资料整理后，在 Codex 中使用 baoyu-slide-deck 这个 skill 生成了一组 ppt 图片。&lt;/p&gt;
&lt;p&gt;Vibe Coding 现在应该都或多或少尝试过，但都停留在爱简单沟通几轮，做出一个 Demo ，至于效果怎么样，在代码写完之前是不知道的，就像是开盲盒。&lt;/p&gt;
&lt;p&gt;所以很多人就觉得 Vide Coding 只能做些示例，还不能上生产。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260720160441.webp" alt="Pasted image 20260720160441" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Vibe 也经历了一些不同的阶段，从提示词、到上下文，再到现在的 Harness Engineering 。&lt;/p&gt;
&lt;p&gt;简单来说，我们不只是给模型上下文，而是要为 Agent 构建一整套可执行、可验证、可恢复、可追溯的工程系统。&lt;/p&gt;
&lt;p&gt;这也是我理解的 Vibe Coding。&lt;/p&gt;
&lt;p&gt;它不应该只是“凭感觉让 AI 写代码”。在生产环境里，它必须是工程化的：人负责表达目标、拆解任务、定义边界和验收标准，Agent 负责搜索代码、生成实现、运行测试和提交变更。&lt;/p&gt;
&lt;p&gt;真正的难点，不是让 AI 写出代码，而是让它在复杂代码库里写对代码。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260720160500.webp" alt="Pasted image 20260720160500" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;新项目相对容易一些，可以从第一天就按 Agent-Native 的方式建设：目录清晰、规则稳定、测试可执行、文档结构化。&lt;/p&gt;
&lt;p&gt;历史项目会更难。几十万行代码里有大量隐性知识：哪些字段有单位约束，哪些链路不能乱改，哪些历史实现只是当时留下的反模式。对 Agent 来说，没被写进代码库、文档、规则和测试里的知识，就等于不存在。&lt;/p&gt;
&lt;p&gt;所以 Harness 的核心价值，是把团队经验外部化。Rules 告诉 Agent 标准是什么，Skills 告诉 Agent 怎么做，Wiki 告诉 Agent 系统是什么样，Changes 记录 Agent 做了什么。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260720160515.webp" alt="Pasted image 20260720160515" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再配合需求分析、编码实现、评审、单测、CI、部署验证等，AI 产出才可能从“看起来能跑”，变成“质量可控”。&lt;/p&gt;
&lt;p&gt;模型能力决定上限，工程能力决定下限。模型越强，越需要更好的上下文、更严格的约束和更完整的验证闭环。&lt;/p&gt;
&lt;p&gt;对研发团队来说，核心竞争力正在迁移。未来重要的不只是会写代码，而是会设计一个让 Agent 稳定工作的系统。&lt;/p&gt;
&lt;p&gt;谁能把需求讲清楚、把边界定清楚、把规则写清楚、把验证做清楚，谁就更可能真正把 AI 变成生产力。&lt;/p&gt;</description></item><item><title>万维钢思维100讲的7个概念</title><link>https://fwhyy.com/2026/05/7-concepts-explained-by-wanwei-steel-thinking-100/</link><pubDate>Sun, 10 May 2026 12:35:00 +0800</pubDate><guid>https://fwhyy.com/2026/05/7-concepts-explained-by-wanwei-steel-thinking-100/</guid><description>&lt;p&gt;看万维钢《现代思维工具 100 讲》的开篇，发现提到了几个概念。这些概念横跨了决策、心理、物理、统计多个领域，却能解释绝大多数复杂问题的本质。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;于是用 ChatGPT 给每个概念配了个图。&lt;/p&gt;
&lt;h3 id="1-古德哈特定律"&gt;1. 古德哈特定律&lt;/h3&gt;
&lt;p&gt;简单说就是：&lt;strong&gt;当一个指标本身变成了目标，它就不再是一个好指标了&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;比如公司原本用「打卡率」衡量员工产出，当公司把「全勤」直接当考核目标，大家为了打卡而打卡，反而不会关注实际工作成果，这个指标就失效了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114748.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="2-自我决定理论"&gt;2. 自我决定理论&lt;/h3&gt;
&lt;p&gt;这是一个动机心理学理论，核心是：人天生有三种内在心理需求，满足这些需求才能真正维持长期的动机和幸福感：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自主感&lt;/strong&gt;：能自己掌控做事情的节奏和方式&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;胜任感&lt;/strong&gt;：能感受到自己在这件事上能力成长&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;关联感&lt;/strong&gt;：能和他人产生联结、获得归属感&lt;br&gt;
用这个理论说，比外在的金钱奖励更能驱动人做好一件事的，是满足这三个内在需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114800.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="3-woop"&gt;3. WOOP&lt;/h3&gt;
&lt;p&gt;这是一套经过验证的「愿望实现四步法」，是四个单词的缩写：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;W（Wish）&lt;/strong&gt;：明确你想要实现的愿望&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;O（Outcome）&lt;/strong&gt;：想象愿望实现后最好的结果是什么&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;O（Obstacle）&lt;/strong&gt;：直面你实现愿望路上，会遇到的最核心障碍&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;P（Plan）&lt;/strong&gt;：提前制定计划：「如果障碍 X 出现，我就用行动 Y 应对它」&lt;br&gt;
比单纯「幻想成功」更有效，它把乐观想象和务实应对结合在了一起。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114828.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/h2&gt;
&lt;h3 id="4-自由能"&gt;4. 自由能&lt;/h3&gt;
&lt;p&gt;这个词最早来自物理学，现在在人工智能、认知科学里用得越来越多，核心思路是：&lt;strong&gt;所有复杂系统（包括人脑、生命）都会主动做一件事——减少「意外」，也就是最小化「自由能」（自由能可以理解成「你想不到的不确定性」）&lt;/strong&gt;。&lt;br&gt;
换句话说：我们会不断调整自己的行为和认知，让世界尽量符合我们的预期，减少不确定性带来的「惊讶」。现在很多 AI 模型、脑科学理论都用这个思路解释智能的本质。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114836.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="5-对称性破缺"&gt;5. 对称性破缺&lt;/h3&gt;
&lt;p&gt;原本物理里的概念，现在经常用来解释复杂系统的演化：当系统原本是对称均匀的状态，遇到微小的扰动，平衡就会被打破，分化出不一样的结构。&lt;br&gt;
举个通俗例子：一锅温度均匀的水加热，原本各处都一样，当温度到临界点，一点点随机波动就会让气泡冒出来，原本对称的状态被打破，产生了有序的对流结构。放到社会领域，比如互联网一开始大家都做门户网站，后来某个商家先做了电商，整个行业就分化出了不同赛道，就是对称性破缺。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114847.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="6-多臂老虎机"&gt;6. 多臂老虎机&lt;/h3&gt;
&lt;p&gt;这是决策论里的经典问题，用来解决「探索 vs 利用」的平衡：&lt;br&gt;
你面前有好多台老虎机（多个选项），每台的中奖概率不一样，你不知道哪台概率更高——你是一直选你之前赢过的那台（利用已知经验），还是去试没玩过的老虎机（探索新可能），怎么选才能让总收益最大？&lt;br&gt;
现实里很多选择都是这个问题：找工作，你是一直做你熟悉的工作，还是去试新的领域？谈恋爱，你是继续和现在的人相处，还是去认识新的人？这个框架就是帮你做最优平衡的。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114857.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id="7-布里尔分数"&gt;7. 布里尔分数&lt;/h3&gt;
&lt;p&gt;这是用来衡量「概率预测准确性」的打分方法，简单说：它会算你给出的预测概率和真实结果之间的差距，分数越低，预测越准。&lt;br&gt;
比如你说明天下雨的概率是 80%，结果真下雨了，你的布里尔分数就低；如果说明天下雨概率 10%，结果下雨了，你的分数就高（预测不准）。现在做风险评估、气象预报、AI 预测都会用这个指标来评判预测模型好不好用。&lt;/p&gt;
&lt;h2&gt;&lt;img src="https://img.fwhyy.com/2026/20260509114905.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/h2&gt;</description></item><item><title>我的知识管理工作流（2026）</title><link>https://fwhyy.com/2026/03/my-knowledge-management-workflow-2026/</link><pubDate>Sat, 21 Mar 2026 09:46:00 +0800</pubDate><guid>https://fwhyy.com/2026/03/my-knowledge-management-workflow-2026/</guid><description>&lt;p&gt;明天就是安阳马拉松了，现在在去安阳的火车上，这篇文章是在火车上用手机写的。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;这两年，使用过不少的工具，也一直在思考和梳理。明白了一件事：知识管理的核心，不是“我用了多少工具”，而是“信息能不能顺畅地从输入，走到思考，再走到输出”。&lt;/p&gt;
&lt;p&gt;目前用的多的是：Get笔记、flomo、Obsidian、墨问笔记。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Get 笔记很适合收集外部内容&lt;/li&gt;
&lt;li&gt;flomo 简单、轻巧，它的回顾和洞察我很喜欢&lt;/li&gt;
&lt;li&gt;Obsidian 则是我写文章、存资料、践行 PARA 的主阵地&lt;/li&gt;
&lt;li&gt;墨问有不错的社区氛围，适合发布文章，交流&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不过也遇到些问题。&lt;/p&gt;
&lt;p&gt;这些工具都在往“笔记平台”方向生长，于是边界开始重叠，人就容易陷入焦虑：这条内容到底该放哪？会不会记重了？以后还能不能找到？&lt;/p&gt;
&lt;p&gt;认真梳理之后，我给自己定下了一个更清晰的原则：不按内容类型分工具，而按“信息来源”和“加工程度”分工具。&lt;/p&gt;
&lt;p&gt;换句话说，我不再问“这是读书笔记还是网页摘录”。&lt;/p&gt;
&lt;p&gt;而是先问四个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;它是外部来的，还是我脑子里冒出来的&lt;/li&gt;
&lt;li&gt;它是原材料，还是我的理解？&lt;/li&gt;
&lt;li&gt;它会不会被我长期复用？&lt;/li&gt;
&lt;li&gt;它是不是已经接近成文？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这四个问题一问，怎么使用工具就比较清晰了。&lt;/p&gt;
&lt;p&gt;目前四个工具的角色分别如下：&lt;/p&gt;
&lt;p&gt;Get 笔记，负责外部输入与 AI 初加工。它的优势不是“写作”，而是“抓取”。尤其是小红书、抖音、公众号，粘贴链接就可以，非常方便，得到更是能无缝集成。之前写过一篇《[[我为什么喜欢用Get笔记了？]]》&lt;/p&gt;
&lt;p&gt;flomo，负责即时想法与轻量发酵。它不是资料库，更像一个思考触发器。官方对它的定位很清楚：帮助用户记录更多想法与灵感，并更好回顾过往记录；它提供每日回顾、主动回顾、相关笔记、AI 洞察等能力。回顾和思考很重要，现在工具越来越方便，更容易收集一大推垃圾，flomo 里更多是主动产出的内容，是比较真实的自己。&lt;/p&gt;
&lt;p&gt;Obsidian，负责长期知识资产与深度写作。它依然是我整个系统的底盘。Obsidian 不是一个简单的笔记工具，而是“长期资产库 + 写作工作台”。关键是内容都在本地，安全可靠。&lt;/p&gt;
&lt;p&gt;墨问笔记，负责公开表达与社区反馈。官方的表述很直接：墨问并不是传统意义的笔记软件，而是一个创作和分享的工具，让有价值的内容在人与人之间流动。多交流，总能有意想不到的收获。&lt;/p&gt;
&lt;p&gt;当四个工具这样重新分工后，很多问题自然就解开了。&lt;/p&gt;
&lt;p&gt;比如，&lt;strong&gt;日常闪念存哪里？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;答案是放 flomo。因为闪念最怕两件事：打开太慢，和记录太重。flomo 的价值就在于它足够轻，能够把一个转瞬即逝的想法先保住。&lt;/p&gt;
&lt;p&gt;再比如，&lt;strong&gt;读书笔记存哪里？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我后来发现，这个问题根本不能一刀切。摘抄型内容，也就是划线、摘句、摘段，得到电子书直接就同步到了 Get 笔记。&lt;/p&gt;
&lt;p&gt;读书过程中的理解、联想、反思，属于我的想法，放在 flomo。&lt;/p&gt;
&lt;p&gt;而当一本书的内容被我提炼成一个长期主题，比如“低代码平台的边界”、“企业 AI 落地场景”、“如何高效管理”，它才真正进入 Obsidian，成为可复用的知识资产。&lt;/p&gt;
&lt;p&gt;这样一来，我的工作流就不再是机械的“所有内容都必须经过四站”，而是一条有层次的分流系统：&lt;/p&gt;
&lt;p&gt;外部内容先进 Get 笔记，使用 Get 笔记的时候也不是存进去就结束了，我会把相同主题的放到一个知识库中，时不时在知识库中有针对性提些问题，也能带来启发。&lt;/p&gt;
&lt;p&gt;脑中的想法先进 flomo；值得长期复用的主题资产进入 Obsidian；适合公开传播的内容再去墨问。&lt;/p&gt;
&lt;p&gt;真正走完整条链路的，只是少数高价值内容。大部分内容会停在前两层，这是正常的。&lt;/p&gt;
&lt;p&gt;结合我这几年的写作习惯，这套工作流还有一个很重要的意义：它把“写文章”从一个临时动作，变成了一个自然生长的过程。&lt;/p&gt;
&lt;p&gt;我平时会持续关注 AI、架构、产品、管理、跑步训练这些主题。以前常见的问题是：收藏了很多，想法也有，但真正写成文章时，总感觉素材散、观点浅、结构临时拼。&lt;/p&gt;
&lt;p&gt;现在则不同，Get 笔记负责把外部世界的信息收集进来，flomo 负责留下那些真正打动我的判断，Obsidian 则负责把分散的想法组织成专题。等到某个主题在 flomo 里已经反复出现、相互连接时，我再进入 Obsidian 去写，文章就不再是“硬挤出来的”，而更像“顺势长出来的”。&lt;/p&gt;
&lt;p&gt;所以，2026 年我的知识管理工作流，已经不再追求“全都要”，也不再追求“记得越多越好”。&lt;/p&gt;
&lt;p&gt;工具没有减少我的思考，工具只是让我更容易看见：哪些信息只是路过，哪些内容值得沉淀，哪些想法值得反复打磨。&lt;/p&gt;
&lt;p&gt;最后，希望明天安阳能顺利跑进 330 ！&lt;/p&gt;</description></item><item><title>从养一只“小龙虾”开始，理解 OpenClaw 的本质</title><link>https://fwhyy.com/2026/03/starting-from-raising-a-crayfish-understanding-the-essence-of-openclaw/</link><pubDate>Wed, 11 Mar 2026 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2026/03/starting-from-raising-a-crayfish-understanding-the-essence-of-openclaw/</guid><description>&lt;p&gt;和去年的 DeepSeek 一样，今年龙虾（OpenClaw）火爆全网了。最近也养了一只。介绍怎么安装之前先了解下龙虾到底是什么。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="一概念openclaw-到底是什么"&gt;一、概念：OpenClaw 到底是什么&lt;/h2&gt;
&lt;p&gt;OpenClaw 是一个把大模型能力“接到消息入口”的开源 Agent 框架。&lt;/p&gt;
&lt;p&gt;它不是单纯聊天，而是让 AI 通过 IM 渠道持续接收任务、调用工具、回传结果。能干活是和之前 AI Chat 最大的区别。&lt;/p&gt;
&lt;h2 id="二为什么说是养虾呢"&gt;二、为什么说是“养”虾呢？&lt;/h2&gt;
&lt;p&gt;之所以说是养，首先需要提供生长环境，其次给它饲料。&lt;/p&gt;
&lt;p&gt;那么什么是环境呢？我们自己的 PC 电脑（Mac Mini 或其他）、或者一个云主机，这个是环境。有了环境安装上龙虾之后，还不能使用，因为还需要饲料。&lt;/p&gt;
&lt;p&gt;Token 就是饲料，饲料分好坏，进口厂家有 OpenAI、Anthropic、Google ，国产的有 GLM、MiniMax、Kimi 等。&lt;/p&gt;
&lt;p&gt;饲养人的方式方法以及饲料的好坏都决定着龙虾的成长。&lt;/p&gt;
&lt;h2 id="三发展历程"&gt;三、发展历程&lt;/h2&gt;
&lt;p&gt;OpenClaw 的发展非常快。从 25 年 11 月到现在，短短几个月的时间，现在 GitHub 上的 Star 数已经 32 万了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/202603191718298.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;OpenClaw 是奥地利开发者 Peter Steinberger 利用周末时间搞出来的，估计他当时也没想到会这么火爆。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2025 年 11 月：OpenClaw 诞生，当时的名字还叫 ClawdBot ,并使龙虾作为图标&lt;/li&gt;
&lt;li&gt;2026 年 1 月 27：因 ClawdBot 的 Clawd 的发音和 Claude 类似，收到了Anthropic 的商标警告，被迫改名为 Moltbot&lt;/li&gt;
&lt;li&gt;2026 年 1 月 30：再次改名为 OpenClaw ，这个名字一直沿用到现在&lt;/li&gt;
&lt;li&gt;2026 年 2 月 14：创始人 Peter 加入 OpenAI ，项目移交开源基金会运营。OpenAI 赞助但项目保持独立。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="四技术架构"&gt;四、技术架构&lt;/h2&gt;
&lt;p&gt;下面用数字员工的概念来帮助理解 OpenClaw 的架构，假设我们部门来了一个数字员工，怎样才能让他能正常干活呢？&lt;/p&gt;
&lt;h3 id="1-核心大脑与调度中枢gateway--pi-agent"&gt;1. 核心大脑与调度中枢（Gateway &amp;amp; Pi Agent）&lt;/h3&gt;
&lt;p&gt;数字员工本质上是一个“能思考+能执行”的系统。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gateway（网关）：相当于“调度中枢”，负责统一接收任务、管理运行状态，以及定时触发任务。&lt;/li&gt;
&lt;li&gt;Pi Agent（推理引擎）：相当于“思考引擎”，通过一个循环机制不断工作：&lt;strong&gt;接收任务 → 拆解规划 → 调用工具 → 检查结果 → 继续下一步&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-沟通渠道与执行载体channels--nodes"&gt;2. 沟通渠道与执行载体（Channels &amp;amp; Nodes）&lt;/h3&gt;
&lt;p&gt;数字员工需要能接任务，也需要能有环境去执行任务。&lt;/p&gt;</description></item><item><title>推荐两个 Obsidian 插件</title><link>https://fwhyy.com/2026/03/recommend-two-obsidian-plugins/</link><pubDate>Mon, 09 Mar 2026 21:54:00 +0800</pubDate><guid>https://fwhyy.com/2026/03/recommend-two-obsidian-plugins/</guid><description>&lt;p&gt;最近，深入究了下 Obsidian 的使用，体验上提升了不少。主要涉及下面的两个插件。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="dataview-插件"&gt;Dataview 插件&lt;/h2&gt;
&lt;p&gt;Obsidian 其实有一个数据库的功能，可以对一些数据进行汇总筛选。但 Dataview 插件的功能还是要强大很多。&lt;/p&gt;
&lt;p&gt;年初听脱不花和马伯庸的对谈，提到了写日记，我计划在 2026 年也效仿下，于是我在 Obsidian 的日记模板中添加一个栏目：今天发生了什么？每天发生的流水账就记录在这个下面。&lt;/p&gt;
&lt;p&gt;但有个问题，我怎么方便看每天都发生了什么呢？于是就用到了 Dataview 。&lt;/p&gt;
&lt;p&gt;创建了一个新的笔记，名字叫：今天发生了什么？ 这个笔记的内容是一段脚本：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;span class="lnt"&gt;68
&lt;/span&gt;&lt;span class="lnt"&gt;69
&lt;/span&gt;&lt;span class="lnt"&gt;70
&lt;/span&gt;&lt;span class="lnt"&gt;71
&lt;/span&gt;&lt;span class="lnt"&gt;72
&lt;/span&gt;&lt;span class="lnt"&gt;73
&lt;/span&gt;&lt;span class="lnt"&gt;74
&lt;/span&gt;&lt;span class="lnt"&gt;75
&lt;/span&gt;&lt;span class="lnt"&gt;76
&lt;/span&gt;&lt;span class="lnt"&gt;77
&lt;/span&gt;&lt;span class="lnt"&gt;78
&lt;/span&gt;&lt;span class="lnt"&gt;79
&lt;/span&gt;&lt;span class="lnt"&gt;80
&lt;/span&gt;&lt;span class="lnt"&gt;81
&lt;/span&gt;&lt;span class="lnt"&gt;82
&lt;/span&gt;&lt;span class="lnt"&gt;83
&lt;/span&gt;&lt;span class="lnt"&gt;84
&lt;/span&gt;&lt;span class="lnt"&gt;85
&lt;/span&gt;&lt;span class="lnt"&gt;86
&lt;/span&gt;&lt;span class="lnt"&gt;87
&lt;/span&gt;&lt;span class="lnt"&gt;88
&lt;/span&gt;&lt;span class="lnt"&gt;89
&lt;/span&gt;&lt;span class="lnt"&gt;90
&lt;/span&gt;&lt;span class="lnt"&gt;91
&lt;/span&gt;&lt;span class="lnt"&gt;92
&lt;/span&gt;&lt;span class="lnt"&gt;93
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 获取所有日记文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;&amp;#34;30_日记&amp;#34;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;2026&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;desc&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 获取当前日期（用于判断是否在最近一周内）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sevenDaysAgo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getTime&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 遍历每篇日记
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;dv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;io&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sections&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\n## /&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;section&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;sections&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;section&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;今天发生了什么？&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 提取该部分内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sectionContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;section&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^今天发生了什么？\n/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;/\n## .*$/s, &amp;#39;&amp;#39;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sectionContent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 解析日期
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dateMatch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/(\d{4})-(\d{2})-(\d{2})/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;displayDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;shortDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;weekday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isRecent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;weekdays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;周日&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;周一&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;周二&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;周三&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;周四&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;周五&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;周六&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;weekday&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;weekdays&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getDay&lt;/span&gt;&lt;span class="p"&gt;()];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;displayDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;-&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;-&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;shortDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;dateMatch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 判断是否在最近7天内
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;isRecent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="nx"&gt;sevenDaysAgo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 计算字数（中文字符）
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;wordCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sectionContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/[^\u4e00-\u9fa5]/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 构建完整的 callout 内容
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 最近7天用 + (默认展开)，其他用 - (默认折叠)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expandSymbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;isRecent&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;+&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt; [!note]&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;expandSymbol&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; 📝 [[&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;|&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;displayDate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;]]&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;weekday&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="sb"&gt;` · &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;weekday&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt;\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 处理内容段落
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paragraphs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sectionContent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\n\n&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;paragraphs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;para&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;para&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;\n&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;line&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt;\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 底部信息栏
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt; ---\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt; &amp;lt;small&amp;gt;📊 &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;wordCount&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt; 字 · 🕐 &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;shortDate&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;&amp;lt;/small&amp;gt;\n`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;calloutContent&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`&amp;gt; &amp;lt;div style=&amp;#34;text-align: right; margin-top: 5px;margin-bottom: 5px;&amp;#34;&amp;gt;&amp;lt;a href=&amp;#34;#&amp;#34; class=&amp;#34;diary-link&amp;#34; data-path=&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;page&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;&amp;#34; style=&amp;#34;color: var(--text-accent); text-decoration: none; font-size: 0.9em;&amp;#34;&amp;gt;📄 打开完整日记 →&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 一次性输出整个 callout
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;dv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;calloutContent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// 为所有链接添加点击事件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelectorAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;.diary-link&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-initialized&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-initialized&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;true&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;click&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data-path&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;workspace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;openLinkText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nx"&gt;dv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;注意代码块需要加上 dataviewjs&lt;/p&gt;</description></item><item><title>2025 年终总结</title><link>https://fwhyy.com/2026/02/2025-yearend-summary/</link><pubDate>Tue, 17 Feb 2026 02:16:00 +0800</pubDate><guid>https://fwhyy.com/2026/02/2025-yearend-summary/</guid><description>&lt;p&gt;岁月匆匆，华章日新，今年春节比较晚，现在 26 年都已经过了快 2 个月了。还是来对 2025 年做下总结吧。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;整体感觉就是快，时间过得很快，AI 的发展速度也非常快。&lt;/p&gt;
&lt;h2 id="怎么应对-ai-时代"&gt;怎么应对 AI 时代&lt;/h2&gt;
&lt;p&gt;从年初的 DeepSeek R1 到现在的 Agent Skills，几乎隔几天就会有新的模型、工具、应用出现。最近爆火的 Seedance 2.0 也在豆包移动端上线了。&lt;/p&gt;
&lt;p&gt;我在手机上打开豆包，却不知道要做什么视频，因为我没有任何视频制作的经验。&lt;/p&gt;
&lt;p&gt;所以说 AI 工具是在放大专业者的能力，而对菜鸟来说，只能是找点乐子的玩具。&lt;/p&gt;
&lt;p&gt;[[AI 时代其实对人的要求更高了]]&lt;/p&gt;
&lt;p&gt;放假前，在公司组织了一场 AI 技术应用分享。几乎所有人都用过 AI 相关的工具，但使用程度各有不同，对新技术和工具的了解和使用只是少部分人。很多人还停留在让 AI 协助排错的阶段。&lt;/p&gt;
&lt;p&gt;AI 时代，持续学习显得尤为重要，持续关注、持续实践。&lt;/p&gt;
&lt;p&gt;近一年也写了不少跟 AI 相关的文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[[理性看待 Manus]]&lt;/li&gt;
&lt;li&gt;[[12个问题深入理解DeepSeek（含开源周内容）]]&lt;/li&gt;
&lt;li&gt;[[在Windsurf中使用李继刚提示词]]&lt;/li&gt;
&lt;li&gt;[[MCP 和 Function Calling：概念]]&lt;/li&gt;
&lt;li&gt;[[MCP 和 Function Calling：示例]]&lt;/li&gt;
&lt;li&gt;[[生成式AI 在 B端软件中实践的思考]]&lt;/li&gt;
&lt;li&gt;[[A2A 介绍：概念篇]]&lt;/li&gt;
&lt;li&gt;[[如何构建多智能体系统？]]&lt;/li&gt;
&lt;li&gt;[[AI 时代，低代码该如何演进？]]&lt;/li&gt;
&lt;li&gt;[[Agent Skills 全景指南：从概念机制到实战开发]]&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="成长"&gt;成长&lt;/h2&gt;
&lt;p&gt;个人成长对我而言，是信息的获取到内化的闭环：输入阶段保持开放，消化阶段保持批判，内化阶段保持实践。&lt;/p&gt;
&lt;p&gt;信息的获取源有：公众号、小红书、小报童、读库、得到、X、语鲸、Folo 。&lt;/p&gt;
&lt;p&gt;语鲸和 Folo 是聚合工具，可以快速浏览，如果需要看原文的讨论，也能方便跳转过去。Get 笔记是最近比较喜欢使用的一款工具，支持公众号、抖音、小红书、B 站、小宇宙的链接分析。他们自己家的得到 APP 更是可以无缝同步。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[[我为什么喜欢用Get笔记了？]]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;输出工具还是使用 Obsidian，而且用的更深入了，最近也准备写一篇 Obsidian 常用插件的使用。在没有找到合适插件的时候，也可以借助 AI 的能力自己写一个插件。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;[[插件开发：实现Obsidian同步到墨问笔记]]&lt;/li&gt;
&lt;li&gt;[[插件开发：实现 Obsidian 同步到 hexo]]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 [[2024 年终总结]] 中我提到在 25 年要慢下来，注重消化。我自认为做的还是不错的。比如说我在看一些知识类的视频或书籍时，会选择在电脑端开着笔记工具去看，边看边记录，避免走马观花，觉得自己会了。&lt;/p&gt;
&lt;p&gt;2026 年 1 月看了马伯庸和脱不花的长谈，学到了一个习惯：写日记。&lt;/p&gt;
&lt;p&gt;这种记录日记的方式，只记录事实，不发表评论，希望 2026 年可以坚持下去，等到年末回顾的时候应该挺有意思的。&lt;/p&gt;
&lt;h2 id="跑步"&gt;跑步&lt;/h2&gt;
&lt;p&gt;2025 年比赛历程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 月，仙桃半马跑到了 133 ，得益于赛道的平坦和天气的给力，425 的平均配速，平时可是连 10 公里都跑不到&lt;/li&gt;
&lt;li&gt;4 月，云丘山越野赛 50 公里组别，虽然跑的慢，还是安全完赛&lt;/li&gt;
&lt;li&gt;12 月，杭州隆 6 越野赛，42 公里组别，因为赶车而退赛&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[[天气和赛道的加持，仙桃半马 PB 9分钟]]&lt;/p&gt;</description></item><item><title>Obsidian 同步最终还是选择了Git</title><link>https://fwhyy.com/2026/02/obsidian-ultimately-chose-git-for-synchronization/</link><pubDate>Thu, 12 Feb 2026 18:05:00 +0800</pubDate><guid>https://fwhyy.com/2026/02/obsidian-ultimately-chose-git-for-synchronization/</guid><description>&lt;p&gt;第一次使用 Obsidian 是在 2022 年，这是翻阅之前的文章 [[Obsidian 初体验]] 才知道的，这几年主要是在电脑上使用，移动端因为同步问题用的非常少。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;之前也尝试过 Syncthing、坚果云等方案，但总有不好用的地方。一旦体验不佳，慢慢就不再使用，移动端也随之成了摆设，浪费了不少时间。&lt;/p&gt;
&lt;p&gt;最近又折腾了下 Obsidian 的 Git 插件，虽然也有点麻烦，但它是适合我的。&lt;/p&gt;
&lt;p&gt;下面介绍下怎么配置和使用。&lt;/p&gt;
&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PC 端：Mac&lt;/li&gt;
&lt;li&gt;移动端：安卓&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用的插件和工具"&gt;使用的插件和工具&lt;/h2&gt;
&lt;p&gt;1、PC 端 Git 插件&lt;/p&gt;
&lt;p&gt;2、移动端：GitSync、Termux&lt;/p&gt;
&lt;h2 id="pc-端配置步骤"&gt;PC 端配置步骤&lt;/h2&gt;
&lt;p&gt;1、在 Gitee（也可以使用 GitHub） 上创建存放 Obsidian 的仓库&lt;/p&gt;
&lt;p&gt;2、在 Obsidian 的根目录添加 .gitignore 文件，内容如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;.obsidian/
.stfolder/
.stfolder.*

# 忽略系统文件
.DS_Store
Thumbs.db
desktop.ini

# 忽略备份文件
*.bak
*.tmp

# 特殊配置：保留核心插件配置（可选）
# Ignore Smart Environment folder
.smart-env
.trash/

node_modules/
.obsidian-git-log.txt
*.swp
.directory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3、PC 端的 Obsidian 安装 Git 插件&lt;/p&gt;
&lt;p&gt;4、将笔记仓库推送到 Gitee，并在 Obsidian 中安装 Git 插件并进行配置，主要设置了打开仓库时自动拉取（pull）最新的笔记。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/202602111746650.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="移动端配置步骤"&gt;移动端配置步骤&lt;/h2&gt;
&lt;p&gt;1、移动端安装 Obsidian、Termux、GitSync。&lt;/p&gt;
&lt;p&gt;2、在手机 documents 目录中创建 obsidian-mobile 目录。&lt;/p&gt;
&lt;p&gt;3、在 Gitee 生成个人访问令牌，Gitee → 设置 → 私人令牌 → 生成新令牌，必须勾选 projects 权限（用于仓库操作）。令牌生成出来后需要及时复制保存，否则窗口关闭后就无法查看了。&lt;/p&gt;
&lt;p&gt;4、有了令牌后笔记仓库的地址如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;https://oauth2:令牌@gitee.com/xxxx/obsidian-sync.git
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5、在 Termux 中进入到 obsidian-mobile 目录，执行以下命令拉取笔记仓库&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://oauth2:令牌@gitee.com/xxxx/obsidian-sync.git
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;6、打开移动端的 Obsidian ，选择 obsidian-mobile/obsidian-sync 目录作为 vault 的目录，设置完后，就能看到笔记内容了。&lt;/p&gt;</description></item><item><title>AI 时代其实对人的要求更高了</title><link>https://fwhyy.com/2026/02/the-ai-era-actually-has-higher-requirements-for-people/</link><pubDate>Mon, 02 Feb 2026 10:00:00 +0800</pubDate><guid>https://fwhyy.com/2026/02/the-ai-era-actually-has-higher-requirements-for-people/</guid><description>&lt;p&gt;最近项目里发生了一件特别有意思的事，非常值得复盘。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;项目经理给一位开发同学布置了一个功能模块，按理说难度不大。考虑到现在 AI 编程工具这么强，项目经理估计很快就能搞定。结果呢？这位同学整整搞了一天还没弄完。&lt;/p&gt;
&lt;p&gt;项目经理很纳闷，问他：“你没用 AI 协助吗？”&lt;/p&gt;
&lt;p&gt;开发同学一脸苦笑：“用了啊。就是因为用了 AI，我才搞到现在。”&lt;/p&gt;
&lt;p&gt;原来，他把需求扔给 AI 后，AI 产出了代码和运行结果，这位开发同学又花了大量时间逐项核对。&lt;/p&gt;
&lt;p&gt;最后算下来，效率反倒不如纯手写。&lt;/p&gt;
&lt;p&gt;这位同事的问题，在于他依然以“写代码”的思维使用 AI，而不是以“验收结果”的思维。&lt;/p&gt;
&lt;p&gt;当我们自己写代码时，脑子里是有完整逻辑的，写出来的每一行都心里有数。但当 AI 生成代码时，对我们来说是一个“黑盒”。&lt;/p&gt;
&lt;p&gt;我们需要从执行者转变为架构师视角。&lt;/p&gt;
&lt;p&gt;在上面这个场景里，我们如果转变思路，把自己当成一个架构师，把 AI 当成负责编码的程序员。会发生什么？&lt;/p&gt;
&lt;p&gt;试想一下，如果你给一位开发派活，你会只说一句“帮我做个登录功能”吗？肯定不会。因为你知道一句话需求会导致最后做出来的东西可能完全偏离了方向。&lt;/p&gt;
&lt;p&gt;那要怎么做呢？&lt;/p&gt;
&lt;p&gt;我们会写详细的规格说明书和接口文档，明确交付标准。然后将这些告诉开发，要按照这些要求来写代码。&lt;/p&gt;
&lt;p&gt;对 AI 也是一样。&lt;/p&gt;
&lt;p&gt;结合这个案例，我认为要提高 AI 协作效率，必须做好以下几点：&lt;/p&gt;
&lt;p&gt;1、边界&lt;/p&gt;
&lt;p&gt;告诉 AI 目标是什么、哪些要做、哪些不能做。只有当 AI 清楚知道“要做什么”并且“什么不能做”时，才能正确执行任务。&lt;/p&gt;
&lt;p&gt;2、任务拆解&lt;/p&gt;
&lt;p&gt;不要把一个大需求直接丢给 AI。正确的做法是拆解。把大任务拆成一个个独立的、可验证的小的任务。&lt;/p&gt;
&lt;p&gt;任务越小，AI 犯错概率越低，检查的成本也越低。&lt;/p&gt;
&lt;p&gt;3、反馈&lt;/p&gt;
&lt;p&gt;当 AI 给出的结果有问题时，我们要能快速识别，并及时提供反馈。&lt;/p&gt;
&lt;p&gt;如何才能快速识别？&lt;/p&gt;
&lt;p&gt;这就需要我们掌握架构知识和底层原理，所以说 AI 帮我们提升效率的同时，我们自己的能力也需要提升才能更高效地配合。&lt;/p&gt;
&lt;p&gt;好的反馈能让 AI 一次性修正错误，避免陷入无效的反复沟通。这不仅省钱（省 Token），还能让 AI 尽可能少地产生幻觉。&lt;/p&gt;
&lt;p&gt;4、上下文&lt;/p&gt;
&lt;p&gt;AI 和人一样，需要上下文。&lt;/p&gt;
&lt;p&gt;一个新人进入团队，需要熟悉工作环境、使用的工具、项目的情况、文档、代码库等，这些就是上下文；上下文越充分，就越容易上手。&lt;/p&gt;
&lt;p&gt;5、目标&lt;/p&gt;
&lt;p&gt;我们做项目，客户的真实诉求是什么？挖得越深，就会越顺利，可以在后期避免很多不必要的返工。&lt;/p&gt;
&lt;p&gt;指挥 AI 干活，也需要让 AI 知道我们的目标和意图是什么，只有这样，产出才不会有偏差，有时甚至有惊喜。&lt;/p&gt;
&lt;p&gt;6、验收标准&lt;/p&gt;
&lt;p&gt;把任务指派给 AI，必须让 AI 知道什么叫“做完了”。&lt;/p&gt;
&lt;p&gt;不要小看这个“做完了”，很多时候，项目经理和开发的理解都不一样，开发认为代码写完就算是做完了，项目经理要对最终的业务负责，考虑的更全面。&lt;/p&gt;
&lt;p&gt;首先我们要明确这个标准，再告诉 AI。否则，如果我们自己都不清楚验收标准，AI 就不可能产出符合要求的结果。&lt;/p&gt;</description></item><item><title>Agent Skills 全景指南：从概念机制到实战开发</title><link>https://fwhyy.com/2026/01/a-comprehensive-guide-to-agent-skills-from-conceptual-mechanisms-to-practical-development/</link><pubDate>Fri, 23 Jan 2026 09:01:00 +0800</pubDate><guid>https://fwhyy.com/2026/01/a-comprehensive-guide-to-agent-skills-from-conceptual-mechanisms-to-practical-development/</guid><description>&lt;p&gt;最近，Agent Skills 彻底火了。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;很多人第一次听到 Skills，会觉得“这不就是一堆 Markdown 吗？”我一开始也这么想。但当你把它放进 Agent 的运行方式里，再对比 Prompt、MCP、Function Calling 这些概念，你会发现：Skills 解决的不是“模型会不会”，而是“怎么让模型稳定、可复用、可分发地把事做完”。&lt;/p&gt;
&lt;p&gt;在这篇文章里，我将从概念到实战，带你彻底搞懂 Skills。&lt;/p&gt;
&lt;h2 id="一什么是-skills它从何而来"&gt;一、什么是 Skills？它从何而来？&lt;/h2&gt;
&lt;p&gt;简单来说，Skills 就是供大模型使用的技能包。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Skills 里面包含做事的方法（流程、规范、检查点），以及可选的资源（模板、脚本、参考资料等）。&lt;/li&gt;
&lt;li&gt;目标不是让模型“临场表现更好”，而是让同一类任务在不同时间、不同输入、不同人使用时，都能得到稳定的结果。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如：团队新来了一个开发工程师。为了让他按团队要求开展工作，通常会告知：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这件事的目标和流程是什么（SOP）&lt;/li&gt;
&lt;li&gt;要用到什么工具（Scripts/MCP）&lt;/li&gt;
&lt;li&gt;有什么参考模板和素材（References/Assets）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是 Skills。它让 Agent 具备了“专业知识”和“稳定做事的方法”。&lt;/p&gt;
&lt;p&gt;Skills 最早由 Anthropic 在 2025 年 10 月中旬随 Claude Code 推出。两个月后（12 月 18 日），Agent Skills 被作为开放标准发布。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills?utm_source=chatgpt.com"&gt;https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills?utm_source=chatgpt.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/202601230643573.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="二skillsmcpagentfunction-calling-的关系"&gt;二、Skills、MCP、Agent、Function Calling 的关系&lt;/h2&gt;
&lt;p&gt;之前写过 MCP 和 Function Calling 相关的文章：&lt;/p&gt;
&lt;p&gt;《[[MCP 和 Function Calling：概念]]》&lt;/p&gt;
&lt;p&gt;《[[MCP 和 Function Calling：示例]]》&lt;/p&gt;
&lt;p&gt;这些和新的 Skills，关系是什么呢？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Function Calling：这是最底层的能力，相当于人的“手”。它让 AI 知道自己能“拿杯子”、“按开关”，是连接外部世界的基础接口。&lt;/li&gt;
&lt;li&gt;MCP：这是一种标准协议，定义通用通信架构和数据格式（类似于 USB 标准）。Function Calling 可视为 MCP 生态下的一种具体功能实现形式。&lt;/li&gt;
&lt;li&gt;Skills：这是业务逻辑和流程，相当于“脑子里的知识”。它教 AI 如何使用 MCP 里的工具去完成一个复杂的任务（比如写一篇符合你风格的文章）。它解决的是“流程”问题。&lt;/li&gt;
&lt;li&gt;Agent：Agent 是位于最上层的“大脑”或“协调者”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可以这么理解，不一定准确：Agent 是工人、Function Calling 是工人具备使用工具的能力，比如会用锤子等、 MCP 是一个多功能腰带，有各种标准的卡口用来放不同类型的工具、Skills 可以是这些工具的使用说明书，也可以是怎么用工具造房子的施工图纸。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2026/202601230655772.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="三核心机制"&gt;三、核心机制&lt;/h2&gt;
&lt;p&gt;Skills 的核心机制，我认为就两件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;让 Agent 能“找到该用哪个技能”&lt;/li&gt;
&lt;li&gt;让 Agent 能“只在需要时加载需要的部分”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Agent 启动时不会把所有技能全文塞进上下文窗口，而是先扫描技能包，读取每个技能的少量元信息（名称和描述，描述尤为重要）。&lt;/p&gt;
&lt;p&gt;当用户提出需求后，Agent 会用这些元信息做匹配，判断要不要触发某个技能。这也是为什么 Skills 的 &lt;code&gt;description&lt;/code&gt; 写得好不好，直接决定“命中率”。&lt;/p&gt;</description></item><item><title>自研 MySQL 数据迁移工具：比 pt-archiver 快 10 倍的秘密</title><link>https://fwhyy.com/2026/01/self-developed-mysql-data-migration-tool-secrets-that-are-10-times-faster-than-pt-explorer/</link><pubDate>Fri, 16 Jan 2026 14:00:00 +0800</pubDate><guid>https://fwhyy.com/2026/01/self-developed-mysql-data-migration-tool-secrets-that-are-10-times-faster-than-pt-explorer/</guid><description>&lt;p&gt;在上一篇文章《[[使用 pt-archiver 迁移 mysql 数据]]》中，我介绍了使用 Percona Toolkit 工具集中的 &lt;code&gt;pt-archiver&lt;/code&gt; 进行历史数据归档的方法。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;&lt;code&gt;pt-archiver&lt;/code&gt; 功能强大且成熟，但在某些特定场景下，它的性能表现并不尽如人意。&lt;/p&gt;
&lt;p&gt;例如，当我尝试将 200 万行历史数据迁移到一个已经包含 500 万行数据的归档表中时，&lt;code&gt;pt-archiver&lt;/code&gt; 的速度非常慢。最根本的原因有两个：&lt;/p&gt;
&lt;p&gt;1、是因为它在插入数据时，目标表的索引在持续更新，随着表越来越大，索引维护的开销也呈指数级增长。&lt;/p&gt;
&lt;p&gt;2、pt-archiver 在批量执行时拼接的 SQL 并非是多值 SQL，而是多条 Insert 语句的拼接。而多值 SQL 的执行效率要远超多条 Insert 语句的拼接。&lt;/p&gt;
&lt;p&gt;为了解决这个问题，我借助 AI 的能力编写了一个 Python 工具（&lt;code&gt;data_migrate&lt;/code&gt;），通过先删索引-批量插入-重建索引的策略，实现了性能的飞跃。&lt;/p&gt;
&lt;h2 id="核心思路"&gt;核心思路&lt;/h2&gt;
&lt;p&gt;1、&lt;strong&gt;迁移前&lt;/strong&gt;：把原表和目标表上除主键和查询字段相关之外的索引先保存到 json 文件中，然后删除。&lt;/p&gt;
&lt;p&gt;2、&lt;strong&gt;迁移中&lt;/strong&gt;：使用 &lt;code&gt;INSERT INTO ... VALUES (...), (...), ...&lt;/code&gt; 这种多值 SQL 的方式进行批量写入。因为没有索引的负担，目标表写入速度和原表的删除速度都非常快。&lt;/p&gt;
&lt;p&gt;3、&lt;strong&gt;迁移后&lt;/strong&gt;：一次性重建所有索引。MySQL 重建索引是经过优化的（排序后批量构建），比逐行维护快得多。&lt;/p&gt;
&lt;p&gt;此外，针对复杂的筛选条件（例如 &lt;code&gt;WHERE id IN (SELECT ...)&lt;/code&gt;），引入了快照表机制，避免在循环分页中反复执行昂贵的子查询。&lt;/p&gt;
&lt;p&gt;快照表逻辑很简单，就是先将需要过滤的 id 查询出来存到一个临时表中，再通过临时表中的 id 进行过滤。&lt;/p&gt;
&lt;h2 id="工具实现"&gt;工具实现&lt;/h2&gt;
&lt;p&gt;这个工具使用 Python 编写，基于 &lt;code&gt;PyMySQL&lt;/code&gt; 驱动。主要包含以下几个模块：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;migrator.py&lt;/code&gt;: 核心迁移控制器。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index_manager.py&lt;/code&gt;: 负责智能地删除和恢复索引。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;db_manager.py&lt;/code&gt;: 数据库连接池管理。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="1智能索引优化"&gt;1、智能索引优化&lt;/h3&gt;
&lt;p&gt;这是性能提升的关键。在 &lt;code&gt;IndexManager&lt;/code&gt; 类中，实现了 &lt;code&gt;drop_indexes&lt;/code&gt; 和 &lt;code&gt;restore_indexes&lt;/code&gt; 方法。&lt;/p&gt;
&lt;p&gt;值得注意的是，我们不能无脑删除所有索引。如果迁移的 &lt;code&gt;WHERE&lt;/code&gt; 条件依赖某个索引（例如按 &lt;code&gt;create_time&lt;/code&gt; 过滤），删掉它会导致源表查询变慢。因此，我加入了一个简单的逻辑：&lt;strong&gt;解析 WHERE 子句，保留查询所需的索引&lt;/strong&gt;。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# data_migrate/tools/data_migrate/index_manager.py 部分代码&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;drop_indexes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;keep_columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;None&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;删除索引并持久化到文件
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; :param keep_columns: 需要保留的列名列表（字符串列表），如果索引包含这些列，则不删除
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt; &amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 持久化索引信息到文件，防止程序中断丢失&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;backup_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_indexes_backup.json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;backup_file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;w&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;utf-8&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dump&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;indent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;索引备份已保存至: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;backup_file&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;保存索引备份失败: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;，将跳过索引删除操作以保证安全。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 过滤需要删除的索引&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;indexes_to_drop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;should_drop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;keep_columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 检查索引列是否包含在保留列表中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# idx[&amp;#39;columns&amp;#39;] 是 [&amp;#34;`col1`&amp;#34;, &amp;#34;`col2`&amp;#34;] 格式&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;columns&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;clean_col&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;`&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;clean_col&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;keep_columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; -&amp;gt; 保留表 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 的索引 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;，因为涉及查询列 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;clean_col&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;should_drop&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;False&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;should_drop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;indexes_to_drop&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;indexes_to_drop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;表 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 没有需要删除的索引（所有索引均被保留或无索引）。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;正在删除表 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 的 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;indexes_to_drop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 个索引以加速写入...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;db_manager&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;indexes_to_drop&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ALTER TABLE `&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;table_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;` DROP INDEX `&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34; -&amp;gt; 删除索引: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;删除索引 &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; 失败: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="2批量读写与事务控制"&gt;2、批量读写与事务控制&lt;/h3&gt;
&lt;p&gt;为了减少网络交互和事务开销，我使用了 &lt;code&gt;executemany&lt;/code&gt; 进行批量插入。&lt;/p&gt;</description></item><item><title>使用 pt-archiver 迁移 mysql 数据</title><link>https://fwhyy.com/2026/01/using-pt-archiver-to-migrate-mysql-data/</link><pubDate>Tue, 13 Jan 2026 16:43:00 +0800</pubDate><guid>https://fwhyy.com/2026/01/using-pt-archiver-to-migrate-mysql-data/</guid><description>&lt;p&gt;在软件系统中，随着业务增长，有些表数据量会越来越大，为了提升性能，会将表进行拆分。这就需要定时将数据从源表迁移到目标表。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;通常使用一个 sql 语句就能实现数据的迁移：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;insert&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;into&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t_business_finished&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t_business&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;t_business&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;state&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;但这种操作在数据量很大时速度很慢，资源消耗也比较大。&lt;/p&gt;
&lt;p&gt;后来发现 pt-archiver 这个工具可以做这个事情。pt-archiver 有下面几个优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;支持分批（chunk）读取和写入，避免一次性加载大量数据导致内存溢出或锁表。&lt;/li&gt;
&lt;li&gt;可以通过 &lt;code&gt;--limit&lt;/code&gt; 控制每次处理的行数，配合 &lt;code&gt;--txn-size&lt;/code&gt; 控制事务大小。&lt;/li&gt;
&lt;li&gt;支持 &lt;code&gt;--sleep&lt;/code&gt; ，避免对生产库造成过大的压力。&lt;/li&gt;
&lt;li&gt;可以通过 &lt;code&gt;--progress&lt;/code&gt; 来查看进度。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面就简单说下 pt-archiver 是怎么使用的，因为我测试的环境 mysql 是使用 docker 构建的，下面示例中 pt-archiver 也是使用 docker 的方式运行。&lt;/p&gt;
&lt;p&gt;1、拉取镜像&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker pull percona/percona-toolkit:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;2、如果是企业内网，不能拉取镜像，就将镜像保存为 tar 文件，赋值到内网服务器 load 即可&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 外网服务器进行保存&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker save -o percona-toolkit.tar percona/percona-toolkit:latest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 拷贝到内网后load&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;docker load -i percona-toolkit.tar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;3、执行下面命令就可以进行数据的迁移：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;--rm --network test_net percona/percona-toolkit:latest pt-archiver --source h=172.66.5.7,P=3306,u=root,p=123456,D=test,t=t_user --dest h=172.66.5.7,P=3306,u=root,p=123456,D=test,t=t_user_bak --where &amp;#34;1=1&amp;#34; --limit 10 --progress 10 --txn-size 10 --sleep 1 --no-delete --statistics --why-quit --header
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&amp;ndash;network：设置和数据库的容器在一个网络中&lt;/li&gt;
&lt;li&gt;&amp;ndash;source 源表相关配置
&lt;ul&gt;
&lt;li&gt;h：数据库的容器 IP&lt;/li&gt;
&lt;li&gt;P：数据库的容器内部端口&lt;/li&gt;
&lt;li&gt;u：数据库用户名&lt;/li&gt;
&lt;li&gt;p：数据库密码&lt;/li&gt;
&lt;li&gt;D：数据库名称&lt;/li&gt;
&lt;li&gt;t：表名&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&amp;ndash;dest：目标表相关配置&lt;/li&gt;
&lt;li&gt;&amp;ndash;where：从源表获取数据的 where 条件&lt;/li&gt;
&lt;li&gt;&amp;ndash;limit：每次获取数据的条数&lt;/li&gt;
&lt;li&gt;&amp;ndash;progress 10：每处理 10 行就向终端输出一条进度信息&lt;/li&gt;
&lt;li&gt;&amp;ndash;txn-size 10：每 10 行组成一个事务，提交一次&lt;/li&gt;
&lt;li&gt;&amp;ndash;sleep 1：每批提交后暂停 1 秒，降低负载。&lt;/li&gt;
&lt;li&gt;&amp;ndash;no-delete：只复制，不删除源表数据&lt;/li&gt;
&lt;li&gt;&amp;ndash;statistics：结束后打印总计行数、耗时、吞吐量等汇总&lt;/li&gt;
&lt;li&gt;&amp;ndash;why-quit：如果提前退出，告知原因&lt;/li&gt;
&lt;li&gt;&amp;ndash;header：进度信息前打印表头&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;执行效果如下：&lt;/p&gt;</description></item><item><title>警惕效率的陷阱</title><link>https://fwhyy.com/2025/11/beware-of-efficiency-traps/</link><pubDate>Wed, 26 Nov 2025 15:49:00 +0800</pubDate><guid>https://fwhyy.com/2025/11/beware-of-efficiency-traps/</guid><description>&lt;p&gt;企业谈降本增效，个人也是一样，不断尝试各类效率工具。即便是教育小孩，也是希望用最少的焦虑、最短的时间，换来好的结果。总之，就是要高效。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;现在层出不穷的大模型和琳琅满目的 AI 工具，其目的也是为了效率的最大化。&lt;/p&gt;
&lt;p&gt;关注效率的同时，也需要警惕一些效率陷阱。&lt;/p&gt;
&lt;p&gt;1&lt;/p&gt;
&lt;p&gt;忙碌替代产出。&lt;/p&gt;
&lt;p&gt;常见现象是为了找一个好用的笔记工具，可以花大量的时间查资料、看评测。但笔记却没有写多少。
同类的事情还有囤积电子书、各类资料。主打一个收藏了即看了的效果。&lt;/p&gt;
&lt;p&gt;看似一直在忙碌，却没有产出。&lt;/p&gt;
&lt;p&gt;就拿记录这个事情来说吧，家里领导就做的很好，先找个工具用着，过程中发现有些需求没有满足，再去寻找新的工具。&lt;/p&gt;
&lt;p&gt;目的是产出内容，工具只是辅助。&lt;/p&gt;
&lt;p&gt;2&lt;/p&gt;
&lt;p&gt;把指标当目标。&lt;/p&gt;
&lt;p&gt;说到指标，就会想到 KPI，很多公司都有 KPI 考核，比如对程序员会有工作量、Bug 量、是否延期等指标。&lt;/p&gt;
&lt;p&gt;如果指标不是为了更好实现目标，而是将指标当成了目标，那么这个 KPI 就是失败的。&lt;/p&gt;
&lt;p&gt;英国经济学家查尔斯·古德哈特提出了一个古德哈特定律：“当一个指标被设定为目标时，它就不再是一个好的指标。”&lt;/p&gt;
&lt;p&gt;比如，如果对程序员只考核工作量，程序员把工作量当成自己的目标，那就会无视代码质量、无视项目进度，只要自己工作量达标即可。&lt;/p&gt;
&lt;p&gt;3&lt;/p&gt;
&lt;p&gt;优先级错乱。&lt;/p&gt;
&lt;p&gt;四象限法将事情分为：重要紧急、重要不紧急、不重要紧急、不重要不紧急四类。目的就是让我们做事前想想优先级，这样效率更高。&lt;/p&gt;
&lt;p&gt;有个项目经理每天应付客户的各种事情，非常忙。负责的项目从测试发布到生产需要用到同步工具，使用过程中，发现同步工具存在很多的问题，这个项目经理就手动进行发布，要多花几倍的时间。&lt;/p&gt;
&lt;p&gt;后来同步工具修好了，需要在客户的测试环境中验证，项目经理觉得自己很忙，没时间做这个事情，依然手动同步，耗费大量时间。&lt;/p&gt;
&lt;p&gt;有时候忙，并不是真的忙。&lt;/p&gt;
&lt;p&gt;4&lt;/p&gt;
&lt;p&gt;忽略协作成本。&lt;/p&gt;
&lt;p&gt;在一个组织里要做成一件事，必然会涉及各个部门的协作。如果部门之间各自为政，沟通和协作不顺畅，就会存在 &amp;ldquo;部门墙&amp;rdquo;。&lt;/p&gt;
&lt;p&gt;这种沟通和协作成本是隐性的，不容易被看见，但最终会体现到结果上。&lt;/p&gt;
&lt;p&gt;有一个竖井效应说的就是这个事：&lt;/p&gt;
&lt;p&gt;竖井效应指的是公司内的各个职能团队各自为政，每个团队都很高效，但从全局的视角去看却不一定是高效的。&lt;/p&gt;
&lt;p&gt;5&lt;/p&gt;
&lt;p&gt;埋头苦干，缺少思考。&lt;/p&gt;
&lt;p&gt;当项目的交付时间提前了、或遇到困难了，第一反应是：我们要更努力了、要抓紧时间了、需要加班加点了，而不是停下来分析问题的根源、重新评估方法和策略是否有效。&lt;/p&gt;
&lt;p&gt;这就是用战术上的勤奋，掩盖战略上的懒惰。就像在迷宫里找出口，选择了拼命快跑，而不是想办法找到地图。&lt;/p&gt;
&lt;p&gt;其实停下来分析、思考，有些事情是可以延后处理，甚至是不处理。&lt;/p&gt;</description></item><item><title>我为什么喜欢用Get笔记了？</title><link>https://fwhyy.com/2025/11/why-do-i-like-to-use-get-notes/</link><pubDate>Tue, 18 Nov 2025 16:49:00 +0800</pubDate><guid>https://fwhyy.com/2025/11/why-do-i-like-to-use-get-notes/</guid><description>&lt;p&gt;Get 笔记是得到推出的一款有 AI 赋能的笔记工具，产品经理是得到创始人之一的快刀青衣。这个工具刚一推出，我就注册试用了，当时功能还很简单，并没有深度使用，不过我推荐给女儿写日记用，效果还不错。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;最近又翻出来用了用，发现功能增强了不少，网上很多拿 Get 笔记和 ima、flomo 做比较。&lt;/p&gt;
&lt;p&gt;ima 是腾讯出品的一款智能知识库工具，这从 ima 的首页就能看出来，不管是 PC 端还是移动端，首页都是问答对话框界面。ima 也提供笔记功能，在笔记中可以选择文字，让 AI 进行扩展、解读、配图等。我更愿意把它当成一个输出的辅助工具。&lt;/p&gt;
&lt;p&gt;flomo 我 2022 年就开始在使用。创始人少楠强调“持续不断记录，意义自然浮现” ，功能上刻意做减法（比如不支持富文本、标题、复杂排版），核心是帮用户无压力地积累知识块。flomo 中的 AI 能力叫“AI 洞察”，这个功能还挺有意思的。作为一个记录工具，flomo 还是挺方便的。&lt;/p&gt;
&lt;p&gt;下面再来看看在 Get 笔记中我喜欢的一些功能。&lt;/p&gt;
&lt;p&gt;1、不管是名称还是首页，定位还是一个笔记工具，对我来说就是输入 + 辅助思考的工具。&lt;/p&gt;
&lt;p&gt;2、既然是输入工具，输入的方式非常丰富：直接写文字或粘贴文本、语音录入、粘贴链接（支持公众号、抖音视频）、拍照、上传图片、线下会议录音、智能拍书、导入音视频文件、手机内录。&lt;/p&gt;
&lt;p&gt;3、我女儿现在写日记就是用的语音录入，除了基础的暂停、保留语音原文和对文本进行 AI 优化外，体验比较好的是，语音输入的同时，文本内容会同时出现。flomo 的语音输入就不能同时转换为文本，有种不安全感，所以很少使用，这是我的问题。&lt;/p&gt;
&lt;p&gt;4、链接输入的功能很强大，几个小时时长的小宇宙播客链接丢进去，很快就提取出了链接原文内容和对音频内容的总结。&lt;/p&gt;
&lt;p&gt;5、手机内录这个功能我还没尝试，后面看知识类的视频或开线上会议的时候可以试试。&lt;/p&gt;
&lt;p&gt;6、和 ima 一样，Get 笔记也有知识库功能，免费版就可以创建 10 个知识库，总容量 30G。知识库可以选择已有的笔记加入其中，还能订阅得到的直播、抖音的博主。&lt;/p&gt;
&lt;p&gt;7、知识库可以以 API 的方式对外提供访问，这样可以将知识库作为一个基础能力，比如：将团队内的一些资料放到知识库中，开发一个企业微信群机器人，通过调用 API 的方式获取知识库的内容。&lt;/p&gt;
&lt;p&gt;8、在使用 AI 知识问答时，除了可以联网和使用知识库内容外，还能选择得到，包含得到的课程、电子书、听书。有得到的加持，回答结果的质量有很大提升。&lt;/p&gt;
&lt;p&gt;9、我是得到电子书的用户，电子书中的划线、笔记会自动同步到 Get 笔记中，非常丝滑。不像之前使用微信读书，需要找各种第三方工具，还总是被封禁。&lt;/p&gt;
&lt;p&gt;10、移动端 APP 有一个菜单叫书籍，手动拍书，或者通过得到电子书同步的内容，都会归档到对应的书籍中。&lt;/p&gt;</description></item><item><title>AI 时代，低代码该如何演进？</title><link>https://fwhyy.com/2025/11/low-code-evolution-in-the-ai-era/</link><pubDate>Tue, 04 Nov 2025 14:49:45 +0800</pubDate><guid>https://fwhyy.com/2025/11/low-code-evolution-in-the-ai-era/</guid><description>&lt;p&gt;在数字化转型的浪潮中，低代码平台与人工智能（AI）的结合正成为企业软件发展的关键趋势。&lt;/p&gt;
&lt;p&gt;低代码平台以其快速开发、交付等特性，正在改变企业应用的开发方式，而 AI 把企业从 “流程数字化” 推进到 “决策智能化” 。这两者一定可以碰撞出不少的火花。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;本文探讨低代码与 AI 融合的方式。&lt;/p&gt;
&lt;h2 id="低代码和-ai-有两种方式可以结合"&gt;低代码和 AI 有两种方式可以结合&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;方式一：在低代码平台中使用 AI，把 AI 能力沉淀到平台内部，提升用户体验和效率。&lt;/li&gt;
&lt;li&gt;方式二：在 AI 中使用低代码，将平台的核心能力封装成细颗粒度工具，成为大模型与智能体的“手脚”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两种方式并非二选一，而是相互增强，根据客户的业务场景进行取舍和选择。&lt;/p&gt;
&lt;h2 id="方式一低代码中使用-ai"&gt;方式一：低代码中使用 AI&lt;/h2&gt;
&lt;p&gt;低代码的优势是可以快速交付项目，结合 AI ，可以让构建出来的业务系统具备 AI 能力，在低代码平台中 AI 能力了可以通过组件或插件的形式存在。&lt;/p&gt;
&lt;p&gt;下面列举几种常见的场景。&lt;/p&gt;
&lt;h3 id="企业级智能问答"&gt;企业级智能问答&lt;/h3&gt;
&lt;p&gt;RAG 现在在企业中使用已经非常成熟了，RAG 中有一个关键点是将内容进行向量化，供用户提问时使用。&lt;/p&gt;
&lt;p&gt;低代码平台中天然就有很多的数据：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;低代码平台可以搭建各种业务功能，随着用户的使用，业务数据就会累加，可以在平台中根据配置选择性将业务数据纳入到知识问答的范围。&lt;/li&gt;
&lt;li&gt;低代码平台中的文件列表，在用户上传文件时，可以对文档内容进行读取和向量化。&lt;/li&gt;
&lt;li&gt;在使用低代码平台构建应用时，数据库表的创建是根据平台中的数据模型进行转换的，数据模型就是一份数据库表的元数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;至于前端的问答对话框的呈现就比较灵活了，可以是单独一个页面、可以放到首页，也可以放到某个功能模块中，针对具体的业务进行提问。&lt;/p&gt;
&lt;h3 id="审批流-ai-节点"&gt;审批流 AI 节点&lt;/h3&gt;
&lt;p&gt;企业将线下的审批搬到线上，为的就是能提高效率。某些审批环节，如果能使用 AI 加持，就能更进一步。&lt;/p&gt;
&lt;p&gt;比如：员工报销流程，财务会对上传的发票和报销金额进行审核，当一个报销单的发票比较多时，人工核对会非常麻烦。&lt;/p&gt;
&lt;p&gt;结合 AI ，可以在低代码平台的流程引擎中提供一个 AI 辅助审批节点，发起人提交后，将票据传给 AI ，AI 进行金额的识别和汇总，并根据规则配置和报销金额进行比对，发现问题直接驳回给发起人。&lt;/p&gt;
&lt;h3 id="报表多轮对话"&gt;报表多轮对话&lt;/h3&gt;
&lt;p&gt;我们现在给企业客户开发软件的过程中，根据客户的业务需求，会提供很多的报表，有些是专业的报表工具、有些通过视图关联多表查询出结果展示。&lt;/p&gt;
&lt;p&gt;但这些随着需求的确定，功能就固化下来了。客户在使用的过程中只能通过条件进行筛选。&lt;/p&gt;
&lt;p&gt;结合 AI ，用户可以在现有报表数据的基础之上进行二次提问，结果以文字、表格、图表的方式提供，让报表变得更加灵活。&lt;/p&gt;
&lt;h3 id="文档解析"&gt;文档解析&lt;/h3&gt;
&lt;p&gt;企业中有很多不同类型的文档和单据，比如：合同、发票等。可以在低代码平台中添加文档识别组件。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;利用文档识别组件，可以构建一个专门用来管理票据的功能。&lt;/li&gt;
&lt;li&gt;合同管理中在文档识别组件中上传，识别合同基本信息，一键将识别的信息填写到表单中。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除了基本信息，甚至可自动识别文档中的关键节点，如合同中的付款信息与时间等，并同步至低代码构建的事务跟踪系统，显著减少人工查阅与录入的工作量。&lt;/p&gt;
&lt;h2 id="方式二在-ai-中使用低代码平台"&gt;方式二：在 AI 中使用低代码平台&lt;/h2&gt;
&lt;p&gt;AI 只有具备了生产能力，才能真正帮到我们。怎么才能具备生产能力呢？就是使用工具。&lt;/p&gt;
&lt;p&gt;我们和大模型进行对话，大模型理解了我们的意图，还能调用工具去进行实现，才是有用的。低代码平台中有各类引擎（表单、规则、视图、流程等），这些引擎的能力可以进行拆解和重组，以 MCP 工具的形式提供给大模型。&lt;/p&gt;
&lt;h3 id="场景一"&gt;场景一&lt;/h3&gt;
&lt;p&gt;用户指令：创建一个员工信息管理应用，包含姓名、工号、部门和入职日期的表单，以及一个可以搜索和分页的表格。&lt;/p&gt;
&lt;p&gt;工具调用：大模型理解意图后，调用低代码平台的 API，自动创建数据模型、生成对应的表单页面和列表页面，并配置好基本的数据绑定。&lt;/p&gt;
&lt;h3 id="场景二"&gt;场景二&lt;/h3&gt;
&lt;p&gt;用户指令：任务管理中创建任务后，给任务负责人发送一个企业微信通知。&lt;/p&gt;
&lt;p&gt;工具调用：大模型理解意图后，分析需要调用的工具集，先调用低代码平台的 API，创建一个用于发企业微信消息的业务流。然后调用 API 将任务创建后的事件和业务流进行绑定。&lt;/p&gt;
&lt;h3 id="场景三"&gt;场景三&lt;/h3&gt;
&lt;p&gt;用户指令：检查一下我们所有低代码应用的运行健康状况。&lt;/p&gt;
&lt;p&gt;工具调用：大模型理解意图后，调用平台的监控API，获取应用错误日志、性能指标（如响应时间）、资源使用情况等，并生成摘要报告。&lt;/p&gt;
&lt;h2 id="最后"&gt;最后&lt;/h2&gt;
&lt;p&gt;网上都说，AI 的到来最终会转向无代码，不过从目前来看，让 AI 自己去实现一个复杂系统，还是比较困难，特别是多轮对话后，幻觉比较明显。&lt;/p&gt;
&lt;p&gt;低代码平台天生就是构建应用的利器，而且是有规则的，这个规则相比较编程语言，范围更小，更容易被 AI 所理解。&lt;/p&gt;
&lt;p&gt;所以，在 AI 无代码变成这条路上，低代码平台如果能转变为底层支撑的工具，将会继续存在。&lt;/p&gt;
&lt;p&gt;未来，随着模型能力的持续进化与平台工具的日益精进，人机协同的开发新模式将成为企业数字化转型的核心竞争力。&lt;/p&gt;</description></item><item><title>再读《人件》</title><link>https://fwhyy.com/2025/10/rereading-peopleware/</link><pubDate>Tue, 21 Oct 2025 18:08:48 +0800</pubDate><guid>https://fwhyy.com/2025/10/rereading-peopleware/</guid><description>&lt;p&gt;最近有点忙，更新得不太规律。其实也是这个号的初衷，写我自己想写的，没有想写的，就继续沉淀沉淀。&lt;/p&gt;
&lt;p&gt;《人件》这本书是汤姆·德马尔科（Tom DeMarco）和蒂莫西·利斯特（Timothy Lister）于 1987 年共同创作的，主要探讨了软件开发领域中的人际关系和组织文化问题。这本书凭借其深入浅出的观点和独特的见解，已经成为软件行业的经典之作。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;最近重读了这本书，下面是一些记录。&lt;/p&gt;
&lt;h2 id="项目失败不只是技术问题"&gt;项目失败不只是技术问题&lt;/h2&gt;
&lt;p&gt;我们很容易犯一个错误，就像书里提到的一个故事：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一个人在黑漆漆的街道上丢了钥匙，却跑到灯光明亮的地方去寻找，因为那里“更容易看清”。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在软件项目开发中，技术问题就是那片“灯光明亮”的地方。它们是具象的、有逻辑的，容易被发现的，也可以通过调试、重构来解决。&lt;/p&gt;
&lt;p&gt;而人的问题，比如：沟通不畅、团队内耗、士气低落等却是模糊的，不太容易发现。所以，我们会下意识回避它们，而把重心转移到更容易看到的技术问题当中。&lt;/p&gt;
&lt;p&gt;这种例子非常多：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需求分析和客户之间沟通不畅，导致最终交付的功能并非客户所需。&lt;/li&gt;
&lt;li&gt;团队成员之间因为信息不对称，对同一个需求的理解天差地别，导致开发和测试之间天天扯皮。&lt;/li&gt;
&lt;li&gt;上下级之间缺乏信任，很简单的任务分配，可能会牵扯到多部门、多层级的资源协调。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些问题，都是隐性的成本，最终会让项目延期、甚至失败。我们必须将注意力从技术领域转向团队的成员状态、沟通质量上。&lt;/p&gt;
&lt;h2 id="做什么样的管理者"&gt;做什么样的管理者？&lt;/h2&gt;
&lt;p&gt;在传统的管理思维中，管理者是“踢屁股”的人，负责分派任务、监督进度。这种模式下，管理者负责思考和决策，员工负责执行。&lt;/p&gt;
&lt;p&gt;然而，对于脑力劳动者而言，这种模式早已失灵。创造力、解决复杂问题的能力，无法通过“踢屁股”来激发。如果你把自己归为码农（每天重复做增删改查），那么不在此列。&lt;/p&gt;
&lt;p&gt;《人件》提供了一个新的视角：&lt;strong&gt;管理的本质不是督促大家去工作，而是为他们创造一个可以顺利工作的环境&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;管理者应该像一个“园丁”，他的职责是创造一片肥沃的土壤，提供充足的阳光和水分，然后让植物（团队成员）自然茁壮地成长。&lt;/p&gt;
&lt;p&gt;管理者的核心工作应该是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;移除障碍：无论是流程上，还是环境中的干扰，只要是阻碍团队高效工作的，都应该是管理者优先解决的问题。&lt;/li&gt;
&lt;li&gt;保护团队：保护团队免受不必要的会议、随意的需求变更和来自组织内部的部门墙的干扰。&lt;/li&gt;
&lt;li&gt;提供支持：提供必要的资源、信息和培训，让团队成员能够不断成长。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;书中提到了两种截然不同的管理哲学：“西班牙理论”和“英国理论”。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;西班牙理论：将员工的工作时间视为可压榨的资源，通过不断施压、鼓励无偿加班来换取产出。这种理论的信奉者，痴迷于“忙碌”的表象，认为“996”是福报。&lt;/li&gt;
&lt;li&gt;英国理论：强调“聪明地工作”而非“辛苦地工作”，鼓励员工创新方法、提高效率，将焦点放在成果而非工作时长上。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;作为管理者，我们需要时常反思，自己更倾向于哪一种？如果我们只是在不断地施加压力，那么结果往往是“工作得更快，而不是更好”，还有可能让不好的事情慢慢发生。&lt;/p&gt;
&lt;h2 id="环境不可忽视"&gt;环境不可忽视&lt;/h2&gt;
&lt;p&gt;我们应该都听过心流状态。这是一种完全沉浸、物我两忘的状态，在这种状态下，工作会比较高效。&lt;/p&gt;
&lt;p&gt;《强风吹拂》里的阿走就多次在跑步时出现心流状态。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;他的专注力，有如一根紧绷的丝线，来到濒临断裂前的张力极限；他紧张又高昂的情绪，就像水盛满土钵，再多加一滴就会溢出钵缘。阿走就是保持着这样的精神状态，心无旁骛地向前跑。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但进入心流状态不容易，至少 15 分钟不被打扰才有可能，任何小的打扰，比如：一个电话、一个微信消息、一封邮件、同事的一个问题等，都会让我们从这种状态中跳出来，再想要进入就变得非常困难。&lt;/p&gt;
&lt;p&gt;之前看过很多帖子抱怨白天各种会议，到了晚上，才能真正专注写代码，于是不得不加班。这种表面上的忙碌，实际上是效率低下的表现。&lt;/p&gt;
&lt;p&gt;作为管理者，应该给团队成员创造一个好的工作环境：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;减少不必要的会议：如果有每日站会，控制在 15 分钟内，切记不要发散了。其他会议尽量集中安排。&lt;/li&gt;
&lt;li&gt;设立专注时间：每天有固定的专注时间可以集中精力工作，这个时间段内，尽量不被打扰，有问题可以先收集记录，在非专注时间进行沟通。&lt;/li&gt;
&lt;li&gt;优化办公环境：为团队提供安静的工作区域，减少噪音干扰。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="构建高效团队"&gt;构建高效团队&lt;/h2&gt;
&lt;p&gt;一个优秀的开发者固然重要，但一个具有凝聚力的高效团队是可以做到 1+1＞2 的。如何构建一个高效的团队，这是管理者应该关注和思考的。&lt;/p&gt;
&lt;p&gt;书中给出的答案是：&lt;strong&gt;找到正确的人，并给予他们成长的土壤。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这里正确的人，不仅仅指技术能力强的人，技术能力强是硬技能，是能做好本职工作的必要条件。除了硬技能，软技能也同样重要。&lt;/p&gt;
&lt;p&gt;一个沟通能力强、乐于分享、能将团队氛围变得融洽的成员，其价值可能远超一个技术大牛。他们是团队的“催化剂”，正是这种催化剂才能让 1+1＞2 。&lt;/p&gt;
&lt;p&gt;下面是一些建议：&lt;/p&gt;
&lt;p&gt;1、在面试过程中，考察候选人的沟通、协作和问题解决能力。多问一些“你如何处理冲突”之类的问题。&lt;/p&gt;
&lt;p&gt;2、将培训、学习、技术分享视为投资，而不是成本。鼓励员工成长，为他们提供挑战性的工作。&lt;/p&gt;
&lt;p&gt;3、确保团队有一个清晰、共同的目标（OKR），而不是一堆零散的任务列表（KPI）。当个人目标和团队目标一致时，每个人就会有自驱力，而不被动接收任务。&lt;/p&gt;
&lt;p&gt;4、每个团队中都可能存在一些“超级催化剂”。他们或许不是代码写得最好的、最快的，但他们能让整个团队的沟通更顺畅，氛围更融洽，帮助新人快速融入。这些人的贡献是隐性的，但对团队的健康至关重要，管理者需要能够慧眼识珠。&lt;/p&gt;
&lt;p&gt;5、好的工作体验总是伴随着一定的挑战性，没人愿意每天做重复的事情。一味地做没有难度的工作会让人懈怠，而持续的挑战和成功后的成就感，是团队保持活力的关键。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;忙碌不等于有有效的产出，代码写的多也不意味着贡献就大。&lt;/p&gt;
&lt;p&gt;管理者不能只是埋头赶路，就像越野跑，当你发现前后都没有人时，不一定是跑得最快或最慢，也可能是跑错了方向。&lt;/p&gt;
&lt;p&gt;作为管理者，我们需要时常抬头看路，审视我们的管理行为是否真的在为团队创造价值，还是仅仅在制造“无效的忙碌”。&lt;/p&gt;</description></item><item><title>MySQL高可用：InnoDB Cluster 部署详解</title><link>https://fwhyy.com/2025/09/mysql-high-availability-innodb-cluster-deployment-details/</link><pubDate>Mon, 15 Sep 2025 09:07:00 +0800</pubDate><guid>https://fwhyy.com/2025/09/mysql-high-availability-innodb-cluster-deployment-details/</guid><description>&lt;p&gt;最近公众号有人留言：为啥使用 ProxySQL 而不使用 InnoDB Cluster ？&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;其实使用什么方案，根据实际情况进行权衡利弊即可，如果先部署了 MGR ，想在此基础之上完善高可用，添加 ProxySQL 比较方便。如果新部署一个高可用环境，直接使用 InnoDB Cluster 也可以，InnoDB Cluster 也是依赖 MGR 。&lt;/p&gt;
&lt;p&gt;下面将从零开始，来讲解怎么通过 Docker Compose 来部署 MySQL InnoDB Cluster，让你能够快速搭建一套完整的高可用数据库系统。&lt;/p&gt;
&lt;h2 id="什么是-mysql-innodb-cluster"&gt;什么是 MySQL InnoDB Cluster&lt;/h2&gt;
&lt;h3 id="核心概念"&gt;核心概念&lt;/h3&gt;
&lt;p&gt;MySQL InnoDB Cluster是 MySQL 官方提供的高可用解决方案，它基于以下三个核心组件：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL Group Replication：提供数据复制和故障检测，这个就是前面文章中提到的 MGR&lt;/li&gt;
&lt;li&gt;MySQL Router：提供透明的路由和负载均衡&lt;/li&gt;
&lt;li&gt;MySQL Shell：提供集群管理和监控功能&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="架构优势"&gt;架构优势&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自动故障检测和转移&lt;/li&gt;
&lt;li&gt;强一致性数据复制&lt;/li&gt;
&lt;li&gt;透明的读写分离&lt;/li&gt;
&lt;li&gt;简化的管理操作&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="架构图"&gt;架构图&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202509150900083.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="开始部署"&gt;开始部署&lt;/h2&gt;
&lt;p&gt;为了测试方便，在一台服务器上使用 docker compose 部署多个服务节点。&lt;/p&gt;
&lt;h3 id="启动-mysql-节点"&gt;启动 mysql 节点&lt;/h3&gt;
&lt;p&gt;1、在服务器上创建一个目录 mysql-innodb-cluster ，目录中按照下图进行目录和文件的创建。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202509150901491.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、docker-compose.yml 文件内容如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;span class="lnt"&gt;68
&lt;/span&gt;&lt;span class="lnt"&gt;69
&lt;/span&gt;&lt;span class="lnt"&gt;70
&lt;/span&gt;&lt;span class="lnt"&gt;71
&lt;/span&gt;&lt;span class="lnt"&gt;72
&lt;/span&gt;&lt;span class="lnt"&gt;73
&lt;/span&gt;&lt;span class="lnt"&gt;74
&lt;/span&gt;&lt;span class="lnt"&gt;75
&lt;/span&gt;&lt;span class="lnt"&gt;76
&lt;/span&gt;&lt;span class="lnt"&gt;77
&lt;/span&gt;&lt;span class="lnt"&gt;78
&lt;/span&gt;&lt;span class="lnt"&gt;79
&lt;/span&gt;&lt;span class="lnt"&gt;80
&lt;/span&gt;&lt;span class="lnt"&gt;81
&lt;/span&gt;&lt;span class="lnt"&gt;82
&lt;/span&gt;&lt;span class="lnt"&gt;83
&lt;/span&gt;&lt;span class="lnt"&gt;84
&lt;/span&gt;&lt;span class="lnt"&gt;85
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;3.8&amp;#39;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mysql1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql:8.0.39&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unless-stopped&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rootpass123&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TZ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Asia/Shanghai&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-cluster-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node1/conf:/etc/mysql/conf.d:ro&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node1/data:/var/lib/mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node1/log:/var/log/mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;3310:3306&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mysql2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql:8.0.39&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unless-stopped&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rootpass123&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TZ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Asia/Shanghai&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-cluster-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node2/conf:/etc/mysql/conf.d:ro&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node2/data:/var/lib/mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node2/log:/var/log/mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;3311:3306&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mysql3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql:8.0.39&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unless-stopped&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;rootpass123&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;TZ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Asia/Shanghai&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-cluster-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node3/conf:/etc/mysql/conf.d:ro&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node3/data:/var/lib/mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./node3/log:/var/log/mysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;3312:3306&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mysql-router&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql/mysql-router:8.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql-router&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;unless-stopped&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql3&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-cluster-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./router/data:/tmp/mysqlrouter&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;6446:6446&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 读写端口 (RW)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;6447:6447&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 只读端口 (RO)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;6448:6448&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 管理端口 (X Protocol RW)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;6449:6449&amp;#34;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# 管理端口 (X Protocol RO)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_HOST&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;3306&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;clusteradmin&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;clusterpass123&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_CREATE_ROUTER_USER&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;MYSQL_ROUTER_BOOTSTRAP_EXTRA_OPTIONS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; --conf-use-sockets
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; --conf-bind-address 0.0.0.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; --conf-base-port 6446&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;mysql-cluster-net&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;driver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;bridge&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;mysql-cluster-net&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;router 节点说明：&lt;/p&gt;</description></item><item><title>MySQL高可用：ProxySQL读写分离+MGR</title><link>https://fwhyy.com/2025/09/mysql-high-availability-proxysql-readwrite-separationmgr/</link><pubDate>Wed, 03 Sep 2025 16:46:00 +0800</pubDate><guid>https://fwhyy.com/2025/09/mysql-high-availability-proxysql-readwrite-separationmgr/</guid><description>&lt;p&gt;MGR 解决了高可用的问题，但如果数据库访问量大，特别是读多写少的场景，就需要读写分离架构了了，在 MGR 的基础上，前面加上 ProxSQL 就可以实现读写分离。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202509030651178.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用程序只和 ProxySQL 打交道&lt;/li&gt;
&lt;li&gt;ProxySQL 做为应用和 MGR 集群中间的一个桥梁，让应用对 MGR 的变化没有感知&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="组件说明"&gt;组件说明&lt;/h2&gt;
&lt;h3 id="mgr"&gt;MGR&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;mysql-master: 主节点 (Primary)，处理写操作&lt;/li&gt;
&lt;li&gt;mysql-slave-1: 从节点 (Secondary)，处理读操作&lt;/li&gt;
&lt;li&gt;mysql-slave-2: 从节点 (Secondary)，处理读操作&lt;/li&gt;
&lt;li&gt;配置为单主模式 (Single-Primary Mode)&lt;/li&gt;
&lt;li&gt;实现自动故障转移和数据同步&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="proxysql"&gt;ProxySQL&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;端口 6033: MySQL 协议接口，应用连接端口&lt;/li&gt;
&lt;li&gt;端口 6032: 管理接口，用于配置和监控&lt;/li&gt;
&lt;li&gt;端口 6080: Web 管理界面 (可选)&lt;/li&gt;
&lt;li&gt;提供读写分离、连接池、查询路由功能，可以对 mysql 的每个节点进行健康检查，进行故障转移，发现主节点出现故障，会将新的强求转移到新的主&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="proxysql-安装和配置"&gt;ProxySQL 安装和配置&lt;/h2&gt;
&lt;p&gt;在《MySQL高可用-使用Docker部署MGR》中介绍了 MGR 的安装部署，在此基础之上继续来安装 ProxySQL。&lt;/p&gt;
&lt;p&gt;1、修改 docker-compose.yml 文件，添加 proxysql 节点。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yml" data-lang="yml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;proxysql&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxysql/proxysql:2.6.1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;container_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;hostname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;proxysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;volumes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;proxysql-data:/var/lib/proxysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./proxysql-config/proxysql.cnf:/etc/proxysql.cnf&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;./proxysql-init-scripts:/etc/proxysql&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;6033:6033&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="s2"&gt;&amp;#34;6032:6032&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;networks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-mgr-network&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;depends_on&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-master&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-slave-1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="l"&gt;mysql-slave-2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;healthcheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CMD&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;mysql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-h&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;127.0.0.1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-P&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;6032&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-u&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;admin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-padmin&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;-e&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;SELECT 1&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;10s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;5s&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;retries&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;/proxysql-config/proxysql.cnf：proxysql 的配置文件&lt;/li&gt;
&lt;li&gt;/proxysql-config/proxysql.cnf：proxysql 初始化脚本所在的目录，可以直接配置为 ./proxysql-init-scripts:/docker-entrypoint-initdb.d ，则会在容器启动时执行。上面是将目录中的文件映射到容器内部，后续需要手动执行。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2、volumes 中映射的文件和目录内容，点击查看原文查看。&lt;/p&gt;</description></item><item><title>MySQL高可用-MGR运维常见问题和注意事项</title><link>https://fwhyy.com/2025/08/mysql-high-availability-mgr-operation-and-maintenance-common-problems-and-precautions/</link><pubDate>Wed, 13 Aug 2025 09:45:00 +0800</pubDate><guid>https://fwhyy.com/2025/08/mysql-high-availability-mgr-operation-and-maintenance-common-problems-and-precautions/</guid><description>&lt;p&gt;MySQL 的高可用可以选择 MGR 方案，部署 MGR 很简单，可以参考《MySQL高可用-使用Docker部署MGR》，但在运行过程中，如果出现问题，如何快速解决？需要持续学习和实践。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;下面我以实际用到的和我搜集到的一些资料来说说 MGR 在运维过程中的常见问题和注意事项。&lt;/p&gt;
&lt;h2 id="部署前注意事项"&gt;部署前注意事项&lt;/h2&gt;
&lt;h3 id="硬件和环境要求"&gt;硬件和环境要求&lt;/h3&gt;
&lt;p&gt;1、网络要求&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;低延迟网络：MGR 对网络延迟敏感，建议延迟 &amp;lt; 5ms 。因为 MGR 基于 Paxos 变种的共识算法，每提交一次事务至少跨网两次（prepare&amp;gt;ack&amp;gt;commit）。&lt;/li&gt;
&lt;li&gt;稳定带宽：确保有足够的带宽支持数据同步，建议 ≥ 1Gbps 。全量 recovery、大事务或 DDL 时会产生突发流量，带宽不足会导致 flow-control 触发，集群整体降速&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2、服务器配置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CPU：建议多核 CPU，至少4核以上&lt;/li&gt;
&lt;li&gt;内存：充足内存，建议 ≥ 16GB&lt;/li&gt;
&lt;li&gt;存储：使用 SSD 存储，确保足够 IOPS，考虑使用 RAID 10 而非 RAID 5/6，以获得更好的写性能&lt;/li&gt;
&lt;li&gt;时钟同步：所有节点必须时钟同步（NTP）。MGR 的 GTID、view_change 事件都带时间戳，时间漂移会导致 “member expel” 误判。误判会导致节点是正常的，但会被踢出去。&lt;/li&gt;
&lt;li&gt;分离数据和日志：将二进制日志和数据文件放在不同的物理存储上，参数大致如下：&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;datadir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; /data/mysql
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;log_bin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; /binlog/mysql-bin
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;binlog_cache_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; 1M 
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;sync_binlog&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nv"&gt;innodb_flush_log_at_trx_commit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id="操作系统优化"&gt;操作系统优化&lt;/h3&gt;
&lt;p&gt;1、文件描述符限制&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 文件描述符限制&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mysql soft nofile 65536&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/security/limits.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mysql hard nofile 65536&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /etc/security/limits.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;MGR + InnoDB 打开的文件数 = 表数量 × 分区 × 3（ibd、frm、ibtmp）+ binlog + relay log。文件描述限制如果比较小，操作系统层面的文件描述符（fd）耗尽，后果是 mysqld 再想去 open() 任何文件（包括新的 ibd、binlog、relay-log、tmp-file、socket 等）时都会得到 EMFILE，导致各种莫名奇妙的错误。&lt;/p&gt;</description></item><item><title>MySQL高可用-使用Docker部署MGR</title><link>https://fwhyy.com/2025/07/mysql-high-availability-deploying-mgr-with-docker/</link><pubDate>Tue, 22 Jul 2025 21:57:00 +0800</pubDate><guid>https://fwhyy.com/2025/07/mysql-high-availability-deploying-mgr-with-docker/</guid><description>&lt;p&gt;MySql 的高可用方案很多，有 MHA、MGR、MySQL InnoDB Cluster 等。起初想学习下 MHA，了解后发现 MHA 在 Github 上的仓库已经没有更新了。不过 MHA 的兼容性比较好，有老版本的 MySQL 需要做高可用，还是值得一试的。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;本文介绍下 MGR 的部署。&lt;/p&gt;
&lt;p&gt;MGR (MySQL Group Replication) 是 MySQL 5.7.17 提出的，既可以很好的保证数据一致性又可以自动切换，具备故障检测功能、支持多节点写入。是以插件的形式提供，可以灵活部署。&lt;/p&gt;
&lt;p&gt;MySQL MGR 集群是多个 MysQL Server 节点共同组成的分布式集群，每个 Server 都有完整的副本，它是基于 ROW 格式的二进制日志文件和 GTID 特性来实现的。&lt;/p&gt;
&lt;h2 id="mgr-的优点"&gt;MGR 的优点&lt;/h2&gt;
&lt;p&gt;1、强一致性：基于原生复制及 Paxos 协议的组复制技术（以插件形式提供），确保数据的严格一致性。&lt;/p&gt;
&lt;p&gt;2、高容错性：在少数节点故障时仍可正常运行，具备自动故障检测机制。节点间资源冲突采用无锁设计（如先到者优先）处理，避免错误。&lt;/p&gt;
&lt;p&gt;3、高扩展性：支持节点动态自动加入与移除。新节点加入后自动同步数据至一致状态；节点移除后，集群自动更新并维护组配置信息。&lt;/p&gt;
&lt;p&gt;4、高灵活性：支持单主模式与多主模式。单主模式下自动选举主节点，所有写操作路由至主节点；多主模式下，所有节点均可并发处理写操作。&lt;/p&gt;
&lt;h2 id="mgr-的一些限制"&gt;MGR 的一些限制&lt;/h2&gt;
&lt;p&gt;1、仅支持 InnoDB 表，并旦每个表一定要有一个主键。&lt;/p&gt;
&lt;p&gt;2、必须打开 GTID 特性，二进制日志格式必须设置为 ROW 。&lt;/p&gt;
&lt;p&gt;3、MGR 不支持大事务。&lt;/p&gt;
&lt;p&gt;4、仅支持 IPv4 网络，组大小限制为最少3个节点、最多9个节点。&lt;/p&gt;
&lt;p&gt;5、不支持外键。&lt;/p&gt;
&lt;p&gt;6、二进制日志不支持 Binlog Event Checksum 。&lt;/p&gt;
&lt;p&gt;7、所有节点 server_id 和 server_uuid 需唯一。&lt;/p&gt;
&lt;h2 id="部署前准备"&gt;部署前准备&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;为了方便，mysql 的主节点和从节点在一台虚拟机中进行测试&lt;/li&gt;
&lt;li&gt;docker 版本：20.10.0&lt;/li&gt;
&lt;li&gt;docker compose 版本：2.26.2&lt;/li&gt;
&lt;li&gt;mysql 版本：8.0.39&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="开始部署"&gt;开始部署&lt;/h2&gt;
&lt;p&gt;1、采用 docker-compose 的方式进行部署，部署目录 mysql-mgr 的文件结构如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202507221805817.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;docker-compose.yml：容器编排文件，配置一个主和两个从的 mysql 节点。&lt;/li&gt;
&lt;li&gt;mysql-config：此目录中是主和从的 mysql 配置文件&lt;/li&gt;
&lt;li&gt;mysql-init-srcipts：此目录中是 mysql 启动时需要创建复制账号以及安装 mgr 插件&lt;/li&gt;
&lt;li&gt;start-mgr.sh：三个 mysql 节点启动后，执行该文件进行 mgr 集群的启动。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2、将 mysql-mgr 拷贝到服务器，进入 mysql-mgr 目录执行 &lt;code&gt;docker-compose up -d&lt;/code&gt; 。&lt;/p&gt;</description></item><item><title>如何构建多智能体系统？</title><link>https://fwhyy.com/2025/06/how-to-build-a-multiagent-system/</link><pubDate>Wed, 25 Jun 2025 15:51:00 +0800</pubDate><guid>https://fwhyy.com/2025/06/how-to-build-a-multiagent-system/</guid><description>&lt;p&gt;6 月 13 日，Anthropic 发布了一篇《How we built our multi-agent research system》的实战经验文章，文章分享了 Anthropic 在构建多个 Claude 智能体来更有效地探索复杂主题的系统过程中，遇到的工程挑战和获得的经验教训。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;原文地址如下：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.anthropic.com/engineering/built-multi-agent-research-system"&gt;https://www.anthropic.com/engineering/built-multi-agent-research-system&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;全文翻译可以看：https://www.fwhyy.com/2025/06/how-to-build-a-multi-agent-research-system-translation/&lt;/p&gt;
&lt;p&gt;下面是我看文章时记录的一些知识点：&lt;/p&gt;
&lt;p&gt;1、在过去十万年里，单个人的智力并未发生巨变，但人类社会在信息时代的能力却呈指数级增长，这得益于我们的集体智慧和协调能力。所以说要想突破能力极限，还得靠协作。&lt;/p&gt;
&lt;p&gt;2、映射到现在的智能体就是单个智能体会出现 token 使用的极限，多智能体可以使用更多的计算资源来处理现实问题。&lt;/p&gt;
&lt;p&gt;3、多智能体的功能架构是协调者和工作者模式，有专门负责分析和指派任务的智能体，也有负责特定工作的智能体。有点像一个项目团队中的项目经理和项目的其他成员。&lt;/p&gt;
&lt;p&gt;4、多智能体的一个应用场景是做问答类的应用，和 RAG 不同的是，RAG 依赖静态检索，根据查询的问题找相似块，然后组织成答案。多智能体是多步骤进行检索，动态发现关键信息，并且还会对结果进行分析，进而做进一步分析和处理，使答案有更高的质量。&lt;/p&gt;
&lt;p&gt;5、多智能体在运行时，会遵循下面步骤。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;系统会先创建一个主智能体，进行任务的思考，然后制定计划，将计划保存起来。&lt;/li&gt;
&lt;li&gt;主智能体会创建一个或多个子智能体，进行具体任务的分配。&lt;/li&gt;
&lt;li&gt;每个子智能体独自研究并将结果返回给主智能体。&lt;/li&gt;
&lt;li&gt;主智能体会判断是否需要进行进一步研究，如果需要会创建额外的子智能体，这个过程是一个循环。&lt;/li&gt;
&lt;li&gt;当主智能体发现不用继续研究，会退出循环，将所有结果交给引文智能体进行引文标记的工作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;6、大模型虽然越来越强，但提示词依然很重要，每个智能体都是由提示词进行引导，我们需要使用日志记录的方式来检查智能体的行为，观察什么时候会出错，然后优化提示词。&lt;/p&gt;
&lt;p&gt;7、主智能体在进行任务的分配时，需要将需求写的尽可能明确和详尽，这样子智能体才能更好的执行。&lt;/p&gt;
&lt;p&gt;8、提示词有个伸缩规则，能够区分简单的事实查询还是复杂问题的研究，让智能体的资源利用率达到最高。现在向深度思考的大模型一些简单的问题，比如：今天星期几？1+1 等于几？大模型还是会自言自语分析一通，很久才会给出答案。这应该就是伸缩规则没有做好。&lt;/p&gt;
&lt;p&gt;9、良好的评估对于构建可靠的 AI 应用至关重要，智能体也不例外。即使输入完全相同，智能体也可能采取完全不同的路径来达到目标。所以，我们需要灵活的评估方法，既能判断智能体是否得到了正确的结果，又能判断它们是否遵循了合理的过程。&lt;/p&gt;
&lt;p&gt;10、这个评估方法有下面几个标准。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;事实准确性（声明是否与来源匹配？）&lt;/li&gt;
&lt;li&gt;引文准确性（引用的来源是否与声明匹配？）&lt;/li&gt;
&lt;li&gt;完整性（是否覆盖了所有被要求的内容？）&lt;/li&gt;
&lt;li&gt;来源质量（是否使用了主要来源而非质量较低的次要来源？）&lt;/li&gt;
&lt;li&gt;以及工具效率（是否以合理的次数使用了正确的工具？）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;11、当然，多智能体也有缺点，比如消耗 token 会非常快，对于智能体之间需要共享上下文、或者智能体之间要频繁交互的不太适合。A2A 的发展应该有助于多智能体的普及。&lt;/p&gt;
&lt;p&gt;读完 Anthropic 的多智能体文章，我也结合我自己的知识有了一些思考。&lt;/p&gt;
&lt;p&gt;1、现阶段，由于单智能体 token 的限制，导致会往多智能体发展，否则很多复杂任务无法进行。但如果有一天技术的进步让 token 的限制不存在了，应该又会回归到单智能体。或者说当 token 不存在限制，智能体之间交互没有障碍，就可以根据场景灵活选择了。&lt;/p&gt;
&lt;p&gt;2、在大模型能力还没那么强的时候，提示词工程很火，后来模型能力增强，特别是推理型模型出来后，提示词工程被弱化了。这篇文章强调提示词依然非常重要，提示词不只是语言沟通，更是任务分配、格式规范的集中承载体。提示词工程是值得系统去学习的。&lt;/p&gt;
&lt;p&gt;3、即使输入完全相同，智能体也可能采取完全不同的路径。也就是说输出是不确定的，尽管可以让大模型进行自评估来提升结果的质量，但对于容错率很低的场景，怎么能保证前 100 次都是对的，第 101 次就不会出现错误呢？&lt;/p&gt;
&lt;p&gt;4、都说 AI 的发展会淘汰掉部分程序员，但从这篇文章表达的思想来看，具备架构思维和能力的程序员一定在未来有一席之地。需要关注整体流程、关注错误处理机制（风险）、关注对结果的评估等。&lt;/p&gt;</description></item><item><title>云原生：一文读懂核心技术栈与演进路径</title><link>https://fwhyy.com/2025/06/cloud-native-technology-stack-and-evolution/</link><pubDate>Tue, 24 Jun 2025 14:36:00 +0800</pubDate><guid>https://fwhyy.com/2025/06/cloud-native-technology-stack-and-evolution/</guid><description>&lt;p&gt;最近，听老板说只要碰到一些大型项目，客户都要求使用云原生技术，让我们在技术储备上也要能跟得上。本文简单讲讲云原生的技术栈以及如何学习。&lt;/p&gt;
&lt;p&gt;云原生（Cloud Native）近些年一直都是软件开发领域的热门话题之一。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;什么是云原生？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;云原生是一种设计和运行软件的方法论，核心思想是充分利用云平台提供的弹性、自动化和按需付费等特性，让应用更易于开发、部署和运维。关于云原生的概念，可以看看《简单聊聊云原生》。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;很多人会问：我单体应用用得好好的，为什么要转向云原生这么复杂的架构呢？实际上，每一种新技术的出现都是为了解决已有问题，但同时也会引入新的挑战，权衡之下，如果利大于弊，就会采用。&lt;/p&gt;
&lt;p&gt;下面我们来一步步分析，看看云原生技术是如何演变而来的。&lt;/p&gt;
&lt;h2 id="云原生包含哪些技术栈"&gt;云原生包含哪些技术栈？&lt;/h2&gt;
&lt;p&gt;目前主流的云原生技术栈（以 Pivotal 和 CNCF 技术栈为基础）包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微服务（Microservices）&lt;/li&gt;
&lt;li&gt;容器（Containers，如 Docker）&lt;/li&gt;
&lt;li&gt;容器编排（Container Orchestration，如 Kubernetes）&lt;/li&gt;
&lt;li&gt;服务网格（Service Mesh）&lt;/li&gt;
&lt;li&gt;声明式 API（Declarative API）&lt;/li&gt;
&lt;li&gt;不可变基础设施（Immutable Infrastructure）&lt;/li&gt;
&lt;li&gt;持续集成和持续交付（CI/CD）&lt;/li&gt;
&lt;li&gt;DevOps&lt;/li&gt;
&lt;li&gt;无服务器架构（Serverless）&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="企业为什么需要云原生"&gt;企业为什么需要云原生？&lt;/h2&gt;
&lt;p&gt;对企业来说，降本增效非常重要，面对复杂的系统，使用云原生技术可以达到这个目的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;降低成本：通过容器技术，能提高资源利用率，降低整体成本。&lt;/li&gt;
&lt;li&gt;提升效率：云原生架构下的部署更快速、更灵活，明显提升开发和交付效率。&lt;/li&gt;
&lt;li&gt;提高业务承载力：云原生能快速扩容，应对高并发业务需求。&lt;/li&gt;
&lt;li&gt;提升稳定性：健康检查和不可变基础设施让系统更稳定、更可靠。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="云原生技术栈是如何演变的"&gt;云原生技术栈是如何演变的？&lt;/h2&gt;
&lt;h3 id="1微服务"&gt;1、微服务&lt;/h3&gt;
&lt;p&gt;1967 年，计算机科学家梅尔文·康威（Melvin Conway）提出过一个观点：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;组织的设计（包括其沟通结构和团队划分）会影响其生产的系统架构。具体来说，软件的架构往往反映了组织的沟通结构。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这就是著名的康威定律。&lt;/p&gt;
&lt;p&gt;最初，软件往往是以单体应用的方式存在。当系统规模和业务复杂度增加时，组织就可能进行拆分，每一个小团队负责一个模块，这些团队甚至可能是分布式的。&lt;/p&gt;
&lt;p&gt;组织的变化必然会让单体应用慢慢向微服务进行转变。不变不行啊，不然沟通成本太高了。&lt;/p&gt;
&lt;p&gt;如果组织没有发生变化，强行去进行微服务拆分，会发现代码的管理、维护会变得复杂（即便是用上自动化工具），所以说有什么样的组织就有什么样的架构。&lt;/p&gt;
&lt;p&gt;微服务将应用拆分成多个小而独立的服务，每个服务可以独立开发、部署、扩展，从而大大提高了灵活性和可维护性。但随之也出现了服务间通信复杂、部署管理困难等问题。&lt;/p&gt;
&lt;p&gt;之前写的几篇微服务相关的文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;《微服务：我们需要从单体转到微服务吗？》&lt;/li&gt;
&lt;li&gt;《微服务：事务管理》&lt;/li&gt;
&lt;li&gt;《微服务：如何拆分服务》&lt;/li&gt;
&lt;li&gt;《微服务：服务间通信概述》&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2容器化docker"&gt;2、容器化（Docker）&lt;/h3&gt;
&lt;p&gt;微服务早在 2011 年就被提出，但近些年才火起来，靠的就是容器技术的普及。&lt;/p&gt;
&lt;p&gt;微服务越来越多，手动部署变得异常复杂。Docker 这类容器技术的出现，使发布的程序和依赖的中间件能被封装到容器中，极大地简化了部署过程。&lt;/p&gt;
&lt;p&gt;开发人员无需关注底层环境，容器的运行环境高度一致。在这之前，经常会有一些莫名其妙的问题，最后的原因就是各种环境配置的不一致。&lt;/p&gt;
&lt;p&gt;然而，随着系统变得复杂，服务拆分的多，还要上各种中间件，容器数量就会越来越多，就会带来容器管理的问题，单靠 Docker 已经无法应对。&lt;/p&gt;
&lt;h3 id="3容器编排kubernetes"&gt;3、容器编排（Kubernetes）&lt;/h3&gt;
&lt;p&gt;容器编排技术随着容器化应用规模的扩大而诞生，主要是为了解决容器在生产环境中批量运行和管理的复杂性问题。最初，Docker 可以很好地处理单个或少量服务，但随着企业应用转向微服务架构，管理大量容器变得困难，仅仅靠人工的方式肯定会错漏百出。&lt;/p&gt;
&lt;p&gt;为了解决这些问题，出现了容器编排技术，简单的有 docker compose ，测试环境和要求不高的生产环境中经常会用到。功能强大的有 Kubernetes ，提供自动部署、服务发现、负载均衡、健康检查、自动扩缩容等功能。&lt;/p&gt;
&lt;p&gt;不过，容器编排技术的引入也会带来新的问题，包括系统复杂性提升、配置管理繁琐和安全性挑战。为应对这些问题，逐渐发展出了新工具，如 Helm、Rancher、OpenShift、Istio、Prometheus、Grafana 等。&lt;/p&gt;
&lt;h3 id="4服务网格service-mesh"&gt;4、服务网格（Service Mesh）&lt;/h3&gt;
&lt;p&gt;随着微服务规模扩大，服务间通信的管理要求变得更高，仅依靠 Kubernetes 等容器编排平台难以全面、高效地实现服务通信治理功能，就需要服务网格出场了。&lt;/p&gt;
&lt;p&gt;服务网格（Service Mesh）是服务间通信的基础设施层。&lt;/p&gt;
&lt;p&gt;它通过在微服务之间注入轻量级网络代理，统一处理服务发现、负载均衡、安全认证、流量控制、故障恢复等功能，非侵入式地解耦服务治理与业务逻辑。&lt;/p&gt;
&lt;p&gt;到这可以发现，技术的演进都有相似性，本质上都是为了将通用能力从核心业务中剥离出来，通过更抽象、更统一的方式进行管理与复用。这种思路在软件开发的多个阶段中屡见不鲜。比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在架构阶段，API 网关将认证、限流、协议转换等边缘治理能力集中处理、配置中心实现了配置的集中化、动态化管理。&lt;/li&gt;
&lt;li&gt;在编码阶段，我们引入了 AOP（面向切面编程） 来将日志、事务、安全等横切关注点独立出来，实现与业务逻辑的解耦、通过工具类或SDK封装公共逻辑，提高复用性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Istio 是目前比较火的一个开源服务网格，大概逻辑就是每个服务会被注入一个 Sidecar 组件，服务之间的通信会先经过 Sidecar，然后 Sidecar 再将请求转发给另一个服务。因为请求都经过Sidecar，所以可以通过 Sidecar 实现很多通用功能。&lt;/p&gt;
&lt;h3 id="5持续集成与持续交付cicd"&gt;5、持续集成与持续交付（CI/CD）&lt;/h3&gt;
&lt;p&gt;服务变多，引入了更多的技术，系统变得更复杂了，就需要更多的手段来进行效率和稳定性的提升。&lt;/p&gt;
&lt;p&gt;CI/CD 技术通过自动化的方式完成代码检查、测试、构建、部署任务。自动化不仅减少了人工操作带来的失误，也提升了迭代速度与产品质量。&lt;/p&gt;
&lt;p&gt;CI 是持续集成，CD 有两层含义（持续交付和持续部署）。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;持续集成：代码合并到特定分支的过程，这中间有静态扫描、单元测试等。&lt;/li&gt;
&lt;li&gt;持续交付：将构建后的产物发布到测试环境，预生产环境。&lt;/li&gt;
&lt;li&gt;持续部署：将经过充分测试的代码自动部署到生产环境。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CI/CD 可以让我们避免重复操作，提前发现问题，减少人工错误，让系统更加稳定。&lt;/p&gt;</description></item><item><title>如何构建多智能体研究系统（翻译）</title><link>https://fwhyy.com/2025/06/how-to-build-a-multi-agent-research-system-translation/</link><pubDate>Fri, 20 Jun 2025 15:26:00 +0800</pubDate><guid>https://fwhyy.com/2025/06/how-to-build-a-multi-agent-research-system-translation/</guid><description>&lt;p&gt;我们的研究功能使用多个Claude智能体来更有效地探索复杂主题。我们分享了构建这个系统时遇到的工程挑战和学到的经验教训。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;Claude现在具备研究能力，可以在网络、Google Workspace和任何集成中搜索，以完成复杂任务。&lt;/p&gt;
&lt;p&gt;这个多智能体系统从原型到生产的过程教会了我们关于系统架构、工具设计和提示工程的重要经验。多智能体系统由多个智能体（自主使用工具循环的LLM）协同工作组成。我们的研究功能包含一个基于用户查询规划研究过程的智能体，然后使用工具创建并行智能体同时搜索信息。具有多个智能体的系统在智能体协调、评估和可靠性方面带来了新的挑战。&lt;/p&gt;
&lt;p&gt;这篇文章分解了对我们有效的原则——我们希望您在构建自己的多智能体系统时能够发现它们的实用价值。&lt;/p&gt;
&lt;h2 id="多智能体系统的优势"&gt;多智能体系统的优势&lt;/h2&gt;
&lt;p&gt;研究工作涉及开放性问题，很难预先预测所需的步骤。您无法为探索复杂主题硬编码固定路径，因为这个过程本质上是动态的且路径依赖的。当人们进行研究时，他们往往根据发现不断更新方法，跟随调查过程中出现的线索。&lt;/p&gt;
&lt;p&gt;这种不可预测性使AI智能体特别适合研究任务。研究需要灵活性，能够在调查展开时转向或探索切向连接。模型必须自主运行多轮，根据中间发现决定追求哪些方向。线性、一次性的管道无法处理这些任务。&lt;/p&gt;
&lt;p&gt;搜索的本质是压缩：从庞大语料中提炼见解。子智能体通过在自己的上下文窗口中并行运行，同时探索问题的不同方面，然后为主研究智能体浓缩最重要的标记，从而促进压缩。每个子智能体还提供关注点分离——不同的工具、提示和探索轨迹——这减少了路径依赖性并实现了彻底的独立调查。&lt;/p&gt;
&lt;p&gt;一旦智能达到阈值，多智能体系统成为扩展性能的重要方式。例如，尽管个体人类在过去10万年中变得更加智能，但人类社会在信息时代因我们的集体智能和协调能力而呈指数级提高能力。即使是通用智能的智能体在作为个体运行时也面临限制；智能体群体可以完成更多工作。&lt;/p&gt;
&lt;p&gt;我们的内部评估显示，多智能体研究系统在涉及同时追求多个独立方向的广度优先查询方面表现尤为出色。我们发现，以Claude Opus 4为主智能体和Claude Sonnet 4子智能体的多智能体系统在我们的内部研究评估中比单一智能体Claude Opus 4的性能高出90.2%。例如，当被要求识别信息技术标普500指数公司的所有董事会成员时，多智能体系统通过将其分解为子智能体的任务找到了正确答案，而单一智能体系统则因缓慢的顺序搜索而未能找到答案。&lt;/p&gt;
&lt;p&gt;多智能体系统之所以有效，主要是因为它们帮助使用足够的标记来解决问题。在我们的分析中，三个因素解释了BrowseComp评估（测试浏览智能体定位难以找到信息的能力）中95%的性能差异。我们发现标记使用本身解释了80%的差异，工具调用次数和模型选择是另外两个解释因素。这一发现验证了我们的架构，该架构将工作分配给具有独立上下文窗口的智能体，为并行推理增加更多容量。最新的Claude模型在标记使用上充当大型效率乘数，升级到Claude Sonnet 4比在Claude Sonnet 3.7上将标记预算翻倍带来更大的性能提升。多智能体架构有效地扩展了超出单一智能体限制的任务的标记使用。&lt;/p&gt;
&lt;p&gt;有一个缺点：实际上，这些架构会快速消耗标记。在我们的数据中，智能体通常使用比聊天交互多约4倍的标记，而多智能体系统使用比聊天多约15倍的标记。为了经济可行，多智能体系统需要任务的价值足够高，以支付增加的性能成本。此外，一些需要所有智能体共享相同上下文或涉及智能体之间许多依赖关系的领域目前不适合多智能体系统。例如，大多数编码任务比研究涉及更少的真正可并行化任务，LLM智能体在实时协调和委派给其他智能体方面尚不出色。我们发现，多智能体系统在涉及大量并行化、超出单一上下文窗口的信息以及与众多复杂工具接口的有价值任务中表现出色。&lt;/p&gt;
&lt;h2 id="研究的架构概述"&gt;研究的架构概述&lt;/h2&gt;
&lt;p&gt;我们的研究系统使用具有协调者-工作者模式的多智能体架构，其中主智能体协调过程，同时委派给并行运行的专业子智能体。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202506241128639.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;当用户提交查询时，主智能体分析它，制定策略，并生成子智能体同时探索不同方面。如上图所示，子智能体通过迭代使用搜索工具收集信息（在本例中是关于2025年AI智能体公司的信息）充当智能过滤器，然后向主智能体返回公司列表，以便它可以编制最终答案。&lt;/p&gt;
&lt;p&gt;使用检索增强生成（RAG）的传统方法使用静态检索。也就是说，它们获取与输入查询最相似的一组块，并使用这些块生成响应。相比之下，我们的架构使用多步搜索，动态查找相关信息，适应新发现，并分析结果以制定高质量答案。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202506241128866.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="研究智能体的提示工程和评估"&gt;研究智能体的提示工程和评估&lt;/h2&gt;
&lt;p&gt;多智能体系统与单一智能体系统有关键区别，包括协调复杂性的快速增长。早期智能体犯了错误，如为简单查询生成50个子智能体，无休止地搜索网络寻找不存在的来源，以及用过多更新相互干扰。由于每个智能体都由提示引导，提示工程是我们改进这些行为的主要杠杆。以下是我们学到的提示智能体的一些原则：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;像智能体一样思考&lt;/strong&gt;。要迭代提示，您必须了解它们的效果。为了帮助我们做到这一点，我们使用我们的Console构建了模拟，使用系统中的确切提示和工具，然后一步步观察智能体工作。这立即揭示了失败模式：智能体在已经有足够结果时继续，使用过于冗长的搜索查询，或选择不正确的工具。有效的提示依赖于开发对智能体的准确心理模型，这可以使最有影响力的变化变得明显。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;教协调者如何委派&lt;/strong&gt;。在我们的系统中，主智能体将查询分解为子任务并向子智能体描述它们。每个子智能体需要一个目标、输出格式、关于使用工具和来源的指导以及明确的任务边界。没有详细的任务描述，智能体会重复工作，留下空白，或无法找到必要的信息。我们最初允许主智能体给出简单、简短的指令，如&amp;quot;研究半导体短缺&amp;quot;，但发现这些指令通常模糊到子智能体误解任务或与其他智能体执行完全相同的搜索。例如，一个子智能体探索了2021年汽车芯片危机，而另外2个重复工作调查当前2025年供应链，没有有效的分工。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;根据查询复杂性调整努力&lt;/strong&gt;。智能体难以判断不同任务的适当努力，因此我们在提示中嵌入了扩展规则。简单的事实查找只需要1个智能体进行3-10次工具调用，直接比较可能需要2-4个子智能体，每个进行10-15次调用，而复杂研究可能使用10个以上具有明确分工的子智能体。这些明确的指导方针帮助主智能体有效分配资源，防止对简单查询过度投资，这是我们早期版本中常见的失败模式。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;工具设计和选择至关重要&lt;/strong&gt;。智能体-工具接口与人机接口一样关键。使用正确的工具是高效的——通常，这是绝对必要的。例如，智能体在网络上搜索只存在于Slack中的上下文注定从一开始就失败。使用为模型提供外部工具访问权限的MCP服务器，这个问题会加剧，因为智能体会遇到具有质量差异很大的描述的未见过的工具。我们给智能体提供了明确的启发式方法：例如，首先检查所有可用工具，将工具使用与用户意图匹配，搜索网络进行广泛的外部探索，或偏好专业工具而非通用工具。糟糕的工具描述可能会将智能体引向完全错误的路径，因此每个工具都需要明确的目的和清晰的描述。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;让智能体自我改进&lt;/strong&gt;。我们发现Claude 4模型可以成为出色的提示工程师。当给定提示和失败模式时，它们能够诊断智能体失败的原因并提出改进建议。我们甚至创建了一个工具测试智能体——当给定有缺陷的MCP工具时，它尝试使用该工具，然后重写工具描述以避免失败。通过数十次测试工具，这个智能体发现了关键细微差别和错误。这个改进工具人体工程学的过程导致使用新描述的未来智能体的任务完成时间减少了40%，因为它们能够避免大多数错误。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;先广泛，再缩小范围&lt;/strong&gt;。搜索策略应该反映专家人类研究：在深入细节之前探索全局。智能体通常默认使用过长、过于具体的查询，返回很少结果。我们通过提示智能体从简短、广泛的查询开始，评估可用内容，然后逐步缩小焦点来抵消这种趋势。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;引导思考过程&lt;/strong&gt;。扩展思考模式，引导Claude在可见思考过程中输出额外标记，可以作为可控的草稿本。主智能体使用思考来规划其方法，评估哪些工具适合任务，确定查询复杂性和子智能体数量，并定义每个子智能体的角色。我们的测试表明，扩展思考改进了指令遵循、推理和效率。子智能体也进行规划，然后在工具结果后使用交错思考来评估质量，识别差距，并完善下一个查询。这使子智能体更有效地适应任何任务。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;并行工具调用改变速度和性能&lt;/strong&gt;。复杂研究任务自然涉及探索多个来源。我们早期的智能体执行顺序搜索，这非常缓慢。为了提高速度，我们引入了两种并行化：(1)主智能体并行而非串行启动3-5个子智能体；(2)子智能体并行使用3+个工具。这些变化将复杂查询的研究时间减少了高达90%，使研究能够在几分钟而非几小时内完成更多工作，同时覆盖比其他系统更多的信息。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我们的提示策略专注于灌输良好的启发式方法而非严格规则。我们研究了熟练人类如何处理研究任务，并在我们的提示中编码了这些策略——如将困难问题分解为更小的任务，仔细评估来源质量，根据新信息调整搜索方法，以及识别何时专注于深度（详细调查一个主题）与广度（并行探索多个主题）。我们还通过设置明确的护栏来主动减轻意外副作用，防止智能体失控。最后，我们专注于具有可观察性和测试用例的快速迭代循环。&lt;/p&gt;
&lt;h2 id="智能体的有效评估"&gt;智能体的有效评估&lt;/h2&gt;
&lt;p&gt;良好的评估对于构建可靠的AI应用至关重要，智能体也不例外。然而，评估多智能体系统带来独特挑战。传统评估通常假设AI每次都遵循相同步骤：给定输入X，系统应该遵循路径Y产生输出Z。但多智能体系统不是这样工作的。即使起点相同，智能体可能采取完全不同的有效路径达到目标。一个智能体可能搜索三个来源，而另一个搜索十个，或者它们可能使用不同工具找到相同答案。因为我们并不总是知道正确步骤是什么，我们通常不能仅检查智能体是否遵循了我们预先规定的&amp;quot;正确&amp;quot;步骤。相反，我们需要灵活的评估方法，判断智能体是否达到了正确结果，同时也遵循了合理过程。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;立即开始用小样本评估&lt;/strong&gt;。在早期智能体开发中，变化往往有戏剧性影响，因为有大量容易实现的改进。提示调整可能将成功率从30%提高到80%。效果如此之大，您只需几个测试用例就能发现变化。我们从代表真实使用模式的约20个查询集开始。测试这些查询通常让我们清楚看到变化的影响。我们经常听说AI开发团队推迟创建评估，因为他们认为只有包含数百个测试用例的大型评估才有用。然而，最好立即开始小规模测试，而不是推迟到可以构建更全面的评估。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;作为评判的LLM在做得好时可扩展&lt;/strong&gt;。研究输出难以程序化评估，因为它们是自由形式文本，很少有单一正确答案。LLM自然适合评分输出。我们使用LLM评判，根据评分标准评估每个输出：事实准确性（声明是否与来源匹配？），引用准确性（引用的来源是否与声明匹配？），完整性（是否涵盖所有请求方面？），来源质量（是否使用主要来源而非低质量二手来源？），以及工具效率（是否合理次数使用正确工具？）。我们尝试使用多个评判来评估每个组件，但发现单一LLM调用，使用单一提示输出0.0-1.0分数和通过-失败等级，与人类判断最一致。当评估测试用例确实有明确答案时，这种方法特别有效，我们可以使用LLM评判简单检查答案是否正确（例如，它是否准确列出了研发预算最大的前3家制药公司？）。使用LLM作为评判让我们能够可扩展地评估数百个输出。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;人类评估捕捉自动化遗漏的内容&lt;/strong&gt;。测试智能体的人们发现评估遗漏的边缘情况。这些包括不寻常查询上的幻觉答案、系统故障或微妙的来源选择偏见。在我们的案例中，人类测试者注意到我们早期的智能体一致选择SEO优化的内容农场，而非权威但排名较低的来源，如学术PDF或个人博客。在我们的提示中添加来源质量启发式方法帮助解决了这个问题。即使在自动评估的世界中，手动测试仍然至关重要。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;多智能体系统具有涌现行为，这些行为在没有特定编程的情况下出现。例如，对主智能体的小变化可能不可预测地改变子智能体的行为方式。成功需要理解交互模式，而不仅仅是个体智能体行为。因此，这些智能体的最佳提示不仅仅是严格指令，而是定义分工、问题解决方法和努力预算的协作框架。正确实现这一点依赖于仔细的提示和工具设计、坚实的启发式方法、可观察性和紧密的反馈循环。请参阅我们Cookbook中的开源提示，了解系统中的示例提示。&lt;/p&gt;
&lt;h2 id="生产可靠性和工程挑战"&gt;生产可靠性和工程挑战&lt;/h2&gt;
&lt;p&gt;在传统软件中，错误可能破坏功能、降低性能或导致中断。在智能体系统中，微小变化级联成大的行为变化，这使得为必须在长时间运行过程中维护状态的复杂智能体编写代码非常困难。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;智能体有状态且错误复合&lt;/strong&gt;。智能体可以长时间运行，在多次工具调用中维护状态。这意味着我们需要持久执行代码并处理途中的错误。没有有效缓解措施，微小系统故障对智能体可能是灾难性的。当错误发生时，我们不能只是从头重启：重启对用户来说既昂贵又令人沮丧。相反，我们构建了可以从错误发生时智能体所处位置恢复的系统。我们还使用模型的智能优雅处理问题：例如，让智能体知道工具何时失败并让它适应，效果出奇地好。我们将基于Claude构建的AI智能体的适应性与确定性保障（如重试逻辑和定期检查点）相结合。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;调试受益于新方法&lt;/strong&gt;。智能体做出动态决策，即使使用相同提示，在运行之间也是非确定性的。这使调试更加困难。例如，用户会报告智能体&amp;quot;找不到明显信息&amp;quot;，但我们看不出为什么。智能体是否使用了糟糕的搜索查询？选择了糟糕的来源？遇到工具故障？添加完整生产跟踪让我们诊断智能体失败原因并系统地修复问题。除了标准可观察性外，我们还监控智能体决策模式和交互结构——所有这些都不监控个人对话内容，以维护用户隐私。这种高级可观察性帮助我们诊断根本原因，发现意外行为，并修复常见故障。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;部署需要仔细协调&lt;/strong&gt;。智能体系统是高度有状态的提示、工具和执行逻辑网络，几乎连续运行。这意味着每当我们部署更新时，智能体可能处于其过程中的任何位置。因此，我们需要防止我们善意的代码更改破坏现有智能体。我们不能同时将每个智能体更新到新版本。相反，我们使用彩虹部署避免中断运行中的智能体，通过逐渐将流量从旧版本转移到新版本，同时保持两者同时运行。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;同步执行创建瓶颈&lt;/strong&gt;。目前，我们的主智能体同步执行子智能体，等待每组子智能体完成后再继续。这简化了协调，但在智能体之间的信息流中创建了瓶颈。例如，主智能体无法引导子智能体，子智能体无法协调，整个系统可能在等待单个子智能体完成搜索时被阻塞。异步执行将启用额外并行性：智能体并发工作并在需要时创建新子智能体。但这种异步性在子智能体之间的结果协调、状态一致性和错误传播方面增加了挑战。随着模型能够处理更长更复杂的研究任务，我们预计性能增益将证明复杂性是合理的。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="结论"&gt;结论&lt;/h2&gt;
&lt;p&gt;构建AI智能体时，最后一英里通常成为旅程的大部分。在开发者机器上工作的代码库需要大量工程才能成为可靠的生产系统。智能体系统中错误的复合性质意味着传统软件的微小问题可能完全使智能体脱轨。一个步骤失败可能导致智能体探索完全不同的轨迹，导致不可预测的结果。由于本文描述的所有原因，原型和生产之间的差距通常比预期更大。&lt;/p&gt;
&lt;p&gt;尽管存在这些挑战，多智能体系统已证明对开放式研究任务有价值。用户表示，Claude帮助他们发现未曾考虑的商业机会，导航复杂的医疗保健选择，解决棘手的技术错误，并通过发现他们单独无法找到的研究联系，节省了长达数天的工作时间。多智能体研究系统可以通过仔细的工程、全面测试、注重细节的提示和工具设计、强大的运营实践以及对当前智能体能力有深入了解的研究、产品和工程团队之间的紧密协作，在规模上可靠运行。我们已经看到这些系统正在改变人们解决复杂问题的方式。&lt;/p&gt;
&lt;h2 id="致谢"&gt;致谢&lt;/h2&gt;
&lt;p&gt;由Jeremy Hadfield、Barry Zhang、Kenneth Lien、Florian Scholz、Jeremy Fox和Daniel Ford撰写。这项工作反映了使研究功能成为可能的Anthropic多个团队的集体努力。特别感谢Anthropic应用工程团队，他们的奉献使这个复杂的多智能体系统投入生产。我们也感谢早期用户提供的出色反馈。&lt;/p&gt;
&lt;h2 id="附录"&gt;附录&lt;/h2&gt;
&lt;p&gt;以下是关于多智能体系统的一些额外杂项提示。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;在多轮中改变状态的智能体的终态评估&lt;/strong&gt;。评估在多轮对话中修改持久状态的智能体带来独特挑战。与只读研究任务不同，每个操作都可能改变后续步骤的环境，创建传统评估方法难以处理的依赖关系。我们发现成功专注于终态评估而非逐轮分析。不是判断智能体是否遵循特定过程，而是评估它是否达到了正确的最终状态。这种方法承认智能体可能找到通向相同目标的替代路径，同时仍确保它们提供预期结果。对于复杂工作流，将评估分解为应该发生特定状态变化的离散检查点，而不是尝试验证每个中间步骤。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;长期对话管理&lt;/strong&gt;。生产智能体通常参与跨越数百轮的对话，需要仔细的上下文管理策略。随着对话延伸，标准上下文窗口变得不足，需要智能压缩和记忆机制。我们实现了模式，智能体在继续新任务前总结已完成的工作阶段并在外部记忆中存储基本信息。当上下文限制接近时，智能体可以生成具有干净上下文的新子智能体，同时通过仔细交接维持连续性。此外，它们可以从记忆中检索存储的上下文，如研究计划，而不是在达到上下文限制时丢失先前工作。这种分布式方法防止上下文溢出，同时在延长交互中保持对话连贯性。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;子智能体输出到文件系统以最小化&amp;quot;电话游戏&amp;quot;&lt;/strong&gt;。直接子智能体输出可以绕过主协调者处理某些类型的结果，提高保真度和性能。不是要求子智能体通过主智能体传达所有内容，而是实现工件系统，专业智能体可以创建独立持久的输出。子智能体调用工具将其工作存储在外部系统中，然后将轻量级引用传回协调者。这防止了多阶段处理期间的信息丢失，并减少了通过对话历史复制大型输出的标记开销。这种模式对结构化输出（如代码、报告或数据可视化）特别有效，其中子智能体的专业提示产生比通过通用协调者过滤更好的结果。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>A2A 介绍：概念篇</title><link>https://fwhyy.com/2025/06/a2a-introduction-concept-chapter/</link><pubDate>Mon, 16 Jun 2025 17:38:00 +0800</pubDate><guid>https://fwhyy.com/2025/06/a2a-introduction-concept-chapter/</guid><description>&lt;p&gt;在之前的文章中介绍过 MCP：《MCP 和 Function Calling：概念》和《MCP 和 Function Calling：示例》。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;谷歌 2025 年 4 月 9 日发布了 A2A 协议，下面是最近学习的总结。&lt;/p&gt;
&lt;h2 id="先理解几个概念"&gt;先理解几个概念&lt;/h2&gt;
&lt;p&gt;首先理解几个概念：智能体（AI Agent）、工具、大模型。下面用一个实际的场景来解释。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我们让 AI 规划一个十一旅游的行程，AI 进行思考、判断、最终做出决策，需要先去了解十一的天气怎么样，需要去了解我之前都去过哪些地方，哪些地方没去过等等，最终给出一个计划。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;AI 需要思考，最终做出决策，靠的是大模型。&lt;/li&gt;
&lt;li&gt;去查询天气、去私有库查询旅行的历史数据，这就需要工具。&lt;/li&gt;
&lt;li&gt;能接收输入（人类发送的指令）、大模型思考并执行（使用工具）后产出结果的一类东西可以认为是智能体。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再举一个例子：让一个“开发智能体”开发一个 Obsidian 插件：实现同步内容到笔记软件中，AI 接收到开发要求和笔记软件的 API 文档，然后调用查看网页的工具进行 API 文档的学习，最后结合大模型的知识输出插件代码。&lt;/p&gt;
&lt;p&gt;总之，一个智能体可以感知、思考和行动。&lt;/p&gt;
&lt;h2 id="什么是-a2a"&gt;什么是 A2A？&lt;/h2&gt;
&lt;p&gt;上面提到的开发插件的例子，一个智能体就搞定了，这是因为插件非常简单。那如果开发复杂的企业级应用系统呢？单个智能体就搞不定了。&lt;/p&gt;
&lt;p&gt;一个复杂的需求来了，需要不同的角色分工合作，交给 AI 也是如此，下面简单列举几个角色：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;技术负责人：理解需求，进行架构设计和开发任务分派。&lt;/li&gt;
&lt;li&gt;开发：这里面包含前端和后端，接到任务按照要求完成代码编写。&lt;/li&gt;
&lt;li&gt;测试：对提交的成果进行验证。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些角色都可以是一个个独立的智能体，在整个开发的过程中，负责人和开发、测试需要沟通；开发的前后端之间需要沟通，开发和测试之间也需要沟通。&lt;/p&gt;
&lt;p&gt;如果这些角色都是来自不同国家的人，互相之间语言不通，沟通成本就非常高了。&lt;/p&gt;
&lt;p&gt;A2A 的出现就是为了解决这个沟通问题，让每个角色都具备一种通用语言。&lt;/p&gt;
&lt;p&gt;A2A 协议是一套开放标准，它为不同供应商、不同框架开发的智能体之间提供了一种通用沟通语言。&lt;/p&gt;
&lt;p&gt;在整个过程中，A2A 协议干了下面几件事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标准化交互：所有 Agent 基于统一的消息规范进行能力发现与调用。&lt;/li&gt;
&lt;li&gt;高效并发：支持流式响应与非阻塞调用，实现多任务并行处理。&lt;/li&gt;
&lt;li&gt;动态扩展：新 Agent 可无缝接入系统，无需定制化适配。&lt;/li&gt;
&lt;li&gt;职责分离：Agent 专注于业务逻辑，协议层统一处理通信传输、安全认证与异常管理。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="为什么会出现-a2a"&gt;为什么会出现 A2A？&lt;/h2&gt;
&lt;p&gt;智能体（Agent）需要像人类一样分工协作以解决复杂任务。每个 Agent 具备独特能力，必须通过信息交换与知识共享实现协同。&lt;/p&gt;
&lt;p&gt;然而，不同开发者创建的 Agent 若采用不同的沟通标准，如同人类使用不同语言交流，将导致理解错位与协作混乱，严重阻碍任务执行效率。这种标准化缺失成为多智能体系统的核心瓶颈。&lt;/p&gt;
&lt;p&gt;当大量不同 Agent（来自企业、开源项目等）涌入生态时，私有化通信协议使交互成本激增。例如，调度 Agent 可能无法理解执行 Agent 的状态反馈，这种“鸡同鸭讲”的局面迫使系统需要一种通用“语言”来承载需求、能力、决策等核心信息的无损传递。&lt;/p&gt;
&lt;p&gt;A2A 协议应运而生，其通过定义统一的消息格式、交互流程与语义规范，构建了智能体间的“通用语”。无论 Agent 底层架构差异如何，均可通过 A2A 声明能力、发送请求、同步状态。&lt;/p&gt;
&lt;h2 id="a2a-和-mcp-的异同点"&gt;A2A 和 MCP 的异同点&lt;/h2&gt;
&lt;h3 id="相同点"&gt;相同点&lt;/h3&gt;
&lt;p&gt;1、标准化协议：两者都是为了解决信息孤岛，提供统一的、标淮的通信机制，使得不同服务或 Agent 可以顺畅沟通。&lt;/p&gt;
&lt;p&gt;2、通用与可扩展：都可以扩展到多种应用场景，无论是工具调用、资源整合（MCP），还是智能代理之间的协作沟通 (A2A)。&lt;/p&gt;
&lt;p&gt;3、交互机制：核心交互模式都基于类似 Client-Server 或 Peer-to-Peer 的请求-响应机制。&lt;/p&gt;
&lt;h3 id="不同点"&gt;不同点&lt;/h3&gt;
&lt;p&gt;1、核心目标&lt;/p&gt;
&lt;p&gt;MCP：连接模型与工具，专注于让大模型（LLM）调用和使用外部工具/资源（API、数据库等），提供结构化、确定性的接口。&lt;/p&gt;
&lt;p&gt;A2A：实现 Agent 间协作，专注于定义多个智能体（Agent）如何沟通、协调以完成任务。&lt;/p&gt;
&lt;p&gt;2、交互粒度&lt;/p&gt;
&lt;p&gt;MCP：精细，处理具体动作细节（如工具调用、参数传递、结果解析等）。&lt;/p&gt;
&lt;p&gt;A2A：抽象，关注任务层面协作（如任务请求、状态通告、结果反馈）。&lt;/p&gt;</description></item><item><title>生成式AI 在 B端软件中实践的思考</title><link>https://fwhyy.com/2025/06/thoughts-on-the-practice-of-generative-ai-in-bend-software/</link><pubDate>Tue, 10 Jun 2025 05:34:00 +0800</pubDate><guid>https://fwhyy.com/2025/06/thoughts-on-the-practice-of-generative-ai-in-bend-software/</guid><description>&lt;p&gt;我一直认为 C 端软件和 AI 的结合会更顺畅一些，例如，笔记工具“墨问”最近推出了 MCP 功能，允许我在各种客户端中与 AI 交互，并将结果通过 MCP 保存至其中。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;这是因为大部分情况下，C 端对准确性的容忍度更高。&lt;/p&gt;
&lt;p&gt;B 端软件则不同，其对准确性要求极高，尤其在金融、医疗等行业。本文简单谈谈关于生成式 AI 在 B 端软件中实践的一些思考。&lt;/p&gt;
&lt;h2 id="ai-在-b-端软件中的一些场景"&gt;AI 在 B 端软件中的一些场景&lt;/h2&gt;
&lt;p&gt;1、结合 RPA（机器人流程自动化）、自然语言处理（NLP）、机器学习等 AI 技术，自动化处理重复性高、规则明确的业务流程。&lt;/p&gt;
&lt;p&gt;2、利用 AI 进行数据挖掘、模式识别和趋势预测，为企业战略制定、市场定位、风险管理等提供数据驱动的决策依据。&lt;/p&gt;
&lt;p&gt;3、对模型进行微调，将法律、医疗等专业领域的知识进行训练，得到垂直领域的专有小模型，为上层应用提供精准的数据支持。&lt;/p&gt;
&lt;p&gt;4、RAG 场景，主要用在智能知识问答、智能客服等。&lt;/p&gt;
&lt;h2 id="ai-在-b-端软件中的局限"&gt;AI 在 B 端软件中的局限&lt;/h2&gt;
&lt;p&gt;在 AI 应用的场景中，有一部分是生成式 AI。什么是生成式 AI？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;生成式 AI 是一种能够创造新内容的人工智能技术。它通过学习海量数据（如文本、图片、音频），掌握其中的规律和模式，然后能够生成全新的、原创的内容。比如 ChatGPT 可以写文章、回答问题，DALL-E 可以根据描述画图，Sora 可以生成视频。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可以看出，生成式 AI 有以下特点：&lt;/p&gt;
&lt;p&gt;1、输出具有不确定性。&lt;/p&gt;
&lt;p&gt;2、输出结果的质量依赖模型的能力。&lt;/p&gt;
&lt;p&gt;而企业应用对确定性要求非常高，比如：统计团队成员的绩效数据、统计销售部门的销售额、统计某些区域的疫苗接种情况等等，这些数据如果出现错误，影响会很大。&lt;/p&gt;
&lt;p&gt;B 端软件除了特定的业务系统外，还有一类是平台级产品，我们的零代码产品就属于这一类。&lt;/p&gt;
&lt;p&gt;这一类产品通常给技术人员或业务人员使用，让他们能通过平台能力来构建最终的业务系统，如果有 AI 加持，可以提升构建的效率。有一些 SaaS 的零代码产品，可以通过一句话描述生成一个应用。&lt;/p&gt;
&lt;p&gt;但仅凭一句话描述生成的应用，往往难以达到实际生产环境的使用标准。因此需要反复进行优化和调整，这个调整的过程会受到模型上下文长度的影响。&lt;/p&gt;
&lt;p&gt;此外，生成式 AI 的“幻觉”问题，即模型生成不准确或虚假的信息，仍然是一个未被完全解决的挑战。这种不确定性在高风险领域尤为突出，可能导致错误的决策和操作。&lt;/p&gt;
&lt;h2 id="一个对话框就能搞定所有吗"&gt;一个对话框就能搞定所有吗？&lt;/h2&gt;
&lt;p&gt;在生成式 AI 的实践中，无论是 RAG 产品，或是一些编程辅助工具，都是提供一个对话框和用户进行交互。&lt;/p&gt;
&lt;p&gt;但仅靠一个对话框搞不定 B 端软件。&lt;/p&gt;
&lt;p&gt;我们在使用系统时，跟 AI 进行对话，AI 的具体运作方式和结果的产生过程，对我们而言如同一个黑盒。&lt;/p&gt;
&lt;p&gt;这会带来一种不安全感。&lt;/p&gt;
&lt;p&gt;所以，一个系统的构建，从 0 到 1 会有很多的中间步骤，这些中间步骤也需要通过可视化的方式清晰呈现，关键步骤需要让用户来进行确认。&lt;/p&gt;
&lt;p&gt;而不是直接后台全部生成好，让用户去看一个最终的结果。&lt;/p&gt;
&lt;p&gt;ChatGPT 可以根据我们的文字描述生成图片，当我们需要对图片进行局部修改时，可以对需要修改的地方进行框选，然后描述修改要求。这种框选的功能就是中间可视化界面。&lt;/p&gt;
&lt;h2 id="clear-范式渐进融合-ai-与-tob-软件的路径"&gt;CLEAR 范式：渐进融合 AI 与 ToB 软件的路径&lt;/h2&gt;
&lt;p&gt;我将上面的问题和局限性告诉了 ChatGPT，ChatGPT 给我提供了一个范式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;C（Clarify，明确）：用户明确表达业务需求，AI 基于此进行初步的内容生成。&lt;/li&gt;
&lt;li&gt;L（Look，查看）：以直观的可视化界面，将 AI 生成的结果清晰展示给用户，以便快速评估和确认。&lt;/li&gt;
&lt;li&gt;E（Edit，编辑）：用户可以直接对 AI 生成的结果进行调整、修正，精细化内容，保证准确性和实用性。&lt;/li&gt;
&lt;li&gt;A（Adjust，再优化）：用户根据实际需要，指导 AI 再进行局部或整体的优化调整。&lt;/li&gt;
&lt;li&gt;R（Release，发布）：经过前面步骤反复优化，用户最终确认无误，提交并落地于实际业务场景中。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中，E（编辑）和 A（再优化）这两个步骤体现了人工与 AI 的协同。&lt;/p&gt;</description></item><item><title>插件开发：实现Obsidian同步到墨问笔记</title><link>https://fwhyy.com/2025/05/plugin-development-implement-obsidian-synchronization-to-mowen-notes/</link><pubDate>Fri, 30 May 2025 16:47:00 +0800</pubDate><guid>https://fwhyy.com/2025/05/plugin-development-implement-obsidian-synchronization-to-mowen-notes/</guid><description>&lt;p&gt;墨问笔记是微信的一个小程序，功能越来越强大，最近发布了 OpenAPI 和 MCP ，本文简单介绍下怎么写一个插件将 Obsidian 中的内容发布到墨问笔记中。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;主要功能如下：&lt;/p&gt;
&lt;p&gt;1、将 Obsidian 中的选中的文本或完整文章发布到墨问。&lt;/p&gt;
&lt;p&gt;2、可以通过右键菜单或者命令进行笔记的发布。&lt;/p&gt;
&lt;p&gt;3、点击发布后会弹出界面输入标题和标签。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202505301748099.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;插件开发的步骤如下：&lt;/p&gt;
&lt;p&gt;1、开发工具使用字节出的 Trae 国际版，模型使用 Claude-4-sonnet，付费用户不用排队，首月只需要 3 刀，值得一试。&lt;/p&gt;
&lt;p&gt;2、在墨问后台获取 API Key 。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202505301749670.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击获取 API Key ，留着备用。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202505301749534.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、在 Trae 中选择 Builder 模式，一定得是 Builder 模式，否则不会自动创建文件，对话框中输入下面内容。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我现在要开发一个obsidian插件，这个插件的作用如下：1、选择一段文本，点击右键，点击publish to mowen ，可以弹出界面让我输入标题和tag，确定后调用api发布到墨问笔记；2、点击右上角三个点，在展开的菜单中点击 publish to mowen 可以将当前文章发布到墨问笔记，弹出的窗口中自动带出当前文章的标题，可以允许修改。 墨问笔记创建的接口文档地址如下： &lt;a href="https://mowen.apifox.cn/295621359e0"&gt;https://mowen.apifox.cn/295621359e0&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;4、等待几分钟，会自动生成所有项目文件，并且会提示需要执行下面的命令，点击接受即可。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm run build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;5、执行过 &lt;code&gt;npm run build&lt;/code&gt; 后会产生打包后的文件，最终将下面红框中的三个文件复制到 Obsidian 的插件目录中。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202505301749642.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6、在 Obsidian 中，进入插件的设置界面，将获取的 API Key 输入到对应的文本框中。API URL 检查是否正确。正确应该为：https://open.mowen.cn/api/open/api/v1/note/create&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202505301749200.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;7、需要注意的是，如果重新覆盖了 main.js 文件后，需要重新加载插件（禁用后重新启用）才能生效。&lt;/p&gt;
&lt;p&gt;8、现在可以验证下功能是否正常，选择一段文本点击右键，在弹出的菜单中选择“
publish to mowen” 。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202505301749244.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;9、点击 “Publish” 按钮进行发布，如果出现成功提示，就去墨问笔记中查看是否创建了新的笔记。如果出现错误，将错误提示反馈给 Trae，Trae 会分析错误进行代码修复。&lt;/p&gt;
&lt;p&gt;10、Trae 第一次生成的程序我就没有执行成功，原因是 body 内容格式不对，我就将 NoteAtom 的结构说明文档连接：https://mowen.apifox.cn/6682171m0 丢给了 Trae，就修改成功了。&lt;/p&gt;
&lt;p&gt;插件代码地址：https://github.com/oec2003/obsidian-pub-to-mowen-plugin&lt;/p&gt;</description></item><item><title>云丘山越野赛50公里复盘</title><link>https://fwhyy.com/2025/04/review-of-the-50-kilometer-yunqiu-mountain-off-road-race/</link><pubDate>Mon, 28 Apr 2025 08:10:00 +0800</pubDate><guid>https://fwhyy.com/2025/04/review-of-the-50-kilometer-yunqiu-mountain-off-road-race/</guid><description>&lt;p&gt;计划中每年跑一场越野比赛，去年跑的崇礼 MTC，今年早早就报名了云丘山越野赛，因为要抽签，50 公里和 100 公里两个组别都报了，结果运气很好，都中签了，便退了 100 公里，对 100 公里还是心存敬畏。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="赛事介绍"&gt;赛事介绍&lt;/h2&gt;
&lt;p&gt;云丘山越野赛是由国际越野跑赛事联盟（UTMB）主办的年度赛事，自 2023 年起正式加入 UTMB 世界系列赛，成为该系列在中国的重要一站。&lt;/p&gt;
&lt;p&gt;2025 年的赛事是双周赛，100 公里、20 公里等在第一周，我要跑到 50 公里在第二周（4 月 18 日至 20 日）。第一周因天气原因，赛事熔断，组织方立即响应进行了补偿策略。后面又在很短的时间内启动重新报名，重新报名成功的选手将在第二周继续参赛。这一系列举动在网上获得一致好评。&lt;/p&gt;
&lt;p&gt;云丘山越野赛的起终点都是山西省临汾市乡宁县云丘山景区中和广场。&lt;/p&gt;
&lt;h2 id="准备"&gt;准备&lt;/h2&gt;
&lt;p&gt;因为去年跑过崇礼的 70 公里，而且每个月都有 200 公里以上的跑量，对云丘山 50 公里没有很重视，这也是最后没跑出好成绩的直接原因。&lt;/p&gt;
&lt;p&gt;去年崇礼是 7 月比赛，5 月和 6 月，平均有 5000 米左右的爬升训练，而今年的二三月份加起来也只有 2000 多米的爬升训练。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504272135011.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;领完物后拍了一个定妆照，设置的 10 小时的完赛时间，结果被狠狠打脸。&lt;/p&gt;
&lt;p&gt;所以，训练的每一步、每一米爬升在比赛时都能够得到反馈。群里波神的一句签名需要谨记：认真训练、佛系比赛。这个佛系我现在理解为在比赛时的掌控感。只有平时认真训练了，比赛时才能以最舒服的姿态完赛。&lt;/p&gt;
&lt;h2 id="海拔图"&gt;海拔图&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504272135922.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;从上面的海拔图来看，这个比赛就翻四座山就可以了，从起点到 CP2 是持续爬升 1000 左右。后面的单看距离和爬升都不算太难。&lt;/p&gt;
&lt;p&gt;但是，我忽略的一个问题，没有关注每公里的爬升比，全程至少有三段都是 400 多的爬升集中在两三公里的距离。这跟崇礼的时上时下完全不一样。&lt;/p&gt;
&lt;p&gt;报完比赛应该详细看海拔图，并了解赛道情况，然后有针对性进行练习，才能在比赛时驾轻就熟。&lt;/p&gt;
&lt;h2 id="出发"&gt;出发&lt;/h2&gt;
&lt;p&gt;比赛地点在云丘山景区，交通并不便利，而且起点附近的酒店也没有抢到。好在赛事方的接驳车安排的非常多，即便住在运城或临汾，也有车可以往返。&lt;/p&gt;
&lt;p&gt;比赛时间是 4 月 19 号上午 8 点 10 分，我分在了第二枪，第一枪是八点起跑。18 号需要领物，便订了 17 号晚上的飞机，因为延误了 1 个多小时，落地运城盐湖机场时已经是 18 号的凌晨了。&lt;/p&gt;
&lt;p&gt;17 号早上，酒店电话说有接送服务，询问我是火车还是飞机，我说飞机到达时是凌晨，酒店回复说，司机 7 点下班了，你到时打个的过来，我给你报销。后来拿着的士发票去前台办理入住时，直接将费用微信转账给我，感受到了西北的豪爽。&lt;/p&gt;
&lt;h2 id="领物"&gt;领物&lt;/h2&gt;
&lt;p&gt;领物地点在云丘山景区，运城最早的接驳车是上午 10 点半，在运城北站坐车，我和老婆、女儿早早就到了，工作人员给了我们每人一个伴手礼&amp;mdash;山西的特色零食。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504272136129.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;将近 2 个小时的车程，我们达到了云丘山景区，领完、逛展、和群友海涵见面，一起吃了午饭。海涵是群里的越野大佬，这次云丘山 50 公里跑进了 6 小时 50 分，拿到了奖金。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504272136921.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;饭后，我和老婆、女儿一起去了云丘山景区，参赛选手和家属都可以免费进入。时间关系，我们只在塔尔坡古村转了一圈，就赶下午 4 点半的接驳车回了运城。群里其他几位朋友到的比较晚，就这样错过了面基，有点遗憾。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504272140218.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="比赛"&gt;比赛&lt;/h2&gt;
&lt;p&gt;早上 4 点起床，酒店门口坐 5 点的接驳车去起点，早上路上车子少，不到 7 点就到达了云丘山景区，第一个冲下车去找厕所排空。&lt;/p&gt;</description></item><item><title>云丘山视频脚本</title><link>https://fwhyy.com/2025/04/yunqiu-mountain-video-script/</link><pubDate>Sun, 27 Apr 2025 21:00:35 +0800</pubDate><guid>https://fwhyy.com/2025/04/yunqiu-mountain-video-script/</guid><description>&lt;p&gt;出发啦，坐地铁去机场&lt;/p&gt;
&lt;p&gt;好不容易等到了座位&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;坐出租车去酒店，这会已经凌晨 1 点多了&lt;/p&gt;
&lt;p&gt;早早起来到运城北站坐接驳车去领物&lt;/p&gt;
&lt;p&gt;工作人员发的伴手礼，全是好吃的&lt;/p&gt;
&lt;p&gt;终于到云丘山了&lt;/p&gt;
&lt;p&gt;跟群里大佬的合影，还是湖北老乡呢&lt;/p&gt;
&lt;p&gt;出发前来张大合影&lt;/p&gt;
&lt;p&gt;要出发啦，好激动&lt;/p&gt;
&lt;p&gt;小缓坡可以跑起来&lt;/p&gt;
&lt;p&gt;到 CP1 了，水还充足，拍个视频就溜了溜了&lt;/p&gt;
&lt;p&gt;爬不完的坡，累死了&lt;/p&gt;
&lt;p&gt;到 CP2 了&lt;/p&gt;
&lt;p&gt;发现一处美景，赶紧停下来拍照&lt;/p&gt;
&lt;p&gt;谢谢好心人的冰棍&lt;/p&gt;
&lt;p&gt;碰到群友 ruby 了&lt;/p&gt;
&lt;p&gt;哈哈，保温毯也能防晒&lt;/p&gt;
&lt;p&gt;好喜欢堵车，可以休息了&lt;/p&gt;
&lt;p&gt;左转下去就是 CP3 了&lt;/p&gt;
&lt;p&gt;这一段太舒服了，风很大，爽&lt;/p&gt;
&lt;p&gt;离终点不远了&lt;/p&gt;
&lt;p&gt;大家好，我是来自跑者日历四群的越野小白冯威，上周跑了云丘山 50 公里。这是我跑到第三个越野赛。&lt;/p&gt;
&lt;p&gt;这是首百计划的节目，
报名：唯一能跟葱神首百计划沾边的就是报名了，当时同时报了 50 公里和 100 公里，没想到两个都中签了，后来把 100 公里给退了，所以上周跑的 50&lt;/p&gt;
&lt;p&gt;准备：因为去年跑过崇礼的 70 公里，云丘山的 50，有点大意了，没有刻意去准备，二三两个月加起来的爬升训练只有 2000 多，确实有点太少了。&lt;/p&gt;
&lt;p&gt;领物：这次跑比赛时带着家属和女儿一起的，酒店定在了运城，接驳车 2 个小时到云丘山景区，领物时见到了海涵，后来海涵要去参加试鞋活动，没和我们一起去景区，我女儿还有点失望，她说特别喜欢那个哥哥。还有就是因为住的太远，下午 4 点就从景区出来去坐接驳车了。其他人没能见上面，有点遗憾。&lt;/p&gt;
&lt;p&gt;比赛：再说说比赛，4 点起床，5 点坐接驳车到起点，我是第二枪 8 点十分出发，出发时温度还挺舒服，但 cp2 之前连续 1000 的爬升，还是挺累的，后面天气变热，又要好几个集中爬升的赛段（就是三公里 3 400 爬升的那种），速度就越来越慢，好在最后还是赶上了 8 点的接驳车回运城。&lt;/p&gt;
&lt;p&gt;印象深刻的有三个：&lt;/p&gt;
&lt;p&gt;1、前面没有陡坡的时候追上了 ruby，后面一上坡 ruby 就轻松把我超了，就这样来回了好几次。ruby 上坡那利索程度完全看不出腿有伤。真的是太强了&lt;/p&gt;
&lt;p&gt;2、一路吃土，补给站灌的水都漱口用了&lt;/p&gt;
&lt;p&gt;3、正晒着太阳呢，路上有人发冰棍，可太爽了&lt;/p&gt;
&lt;p&gt;4、堵车，其实上坡我挺喜欢堵车的，可以多休息休息，但没想到是下坡堵的更狠&lt;/p&gt;
&lt;p&gt;5、最后快冲线时我刚掏出手机准备自己拍一段，结果看到了海涵，海涵帮我拍了一段冲线视频，太感谢了&lt;/p&gt;
&lt;p&gt;补给-服务-赛道体验分别打几分 5 分
补给 5 分，补给站有食用冰、可乐管够，对我来说这就够了
服务 5 分
赛道 4 分，50 公里的风景一般，灰还很大&lt;/p&gt;
&lt;p&gt;夏季没有比赛，下一场是玉环 60 公里，还有半年时间，得好好练练爬坡能力了。对波神的那句认真训练、佛系比赛有的新的理解。这个佛系我现在理解为在比赛时的掌控感。只有平时认真训练了，比赛时才能以最舒服的姿态完赛。&lt;/p&gt;
&lt;p&gt;最后，感谢比赛当天班长和群里的小伙伴的关心、感谢海涵拍的冲线视频、感谢 Troy 的蒸饺、感谢象兄的酒，感谢 CEO、葱神，好了，我的分享就到这里了&lt;/p&gt;</description></item><item><title>MCP 和 Function Calling：示例</title><link>https://fwhyy.com/2025/04/mcp-and-function-calling-examples/</link><pubDate>Wed, 16 Apr 2025 18:48:00 +0800</pubDate><guid>https://fwhyy.com/2025/04/mcp-and-function-calling-examples/</guid><description>&lt;p&gt;在上一篇《MCP 和 Function Calling：概念》中简单介绍了 MCP 和 Function Calling 的基础概念和执行逻辑。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;本文以实际例子来加深对 MCP 和 Function Calling 的理解。&lt;/p&gt;
&lt;p&gt;实现这样一个场景：和大模型聊天，然后让大模型将回答的内容保存到 flomo 笔记中。&lt;/p&gt;
&lt;h2 id="function-calling"&gt;Function Calling&lt;/h2&gt;
&lt;p&gt;我们知道 Function Calling 和模型的能力有关，我使用的是 qwen2.5:7b 模型，使用 ollama 在本地运行。&lt;/p&gt;
&lt;h2 id="思路"&gt;思路&lt;/h2&gt;
&lt;p&gt;1、写一个 api 接口，这个接口的作用就是将输入的值存入 flomo 笔记中。&lt;/p&gt;
&lt;p&gt;2、利用 qwen-agent 框架，来实现 function calling ，最终调用自定义开发的 api 接口。&lt;/p&gt;
&lt;h3 id="实现"&gt;实现&lt;/h3&gt;
&lt;p&gt;1、api 接口使用任何语言都行，我这里使用的是 python 的 flask 框架。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@api_bp.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/flomo/save&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;POST&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;save_to_flomo&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 获取请求数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 验证请求数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Missing required field: content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;content&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;tags&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="c1"&gt;# 可选的标签列表&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 验证Flomo API URL是否配置&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flomo_api_url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;current_app&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;FLOMO_API_URL&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;flomo_api_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Flomo API URL not configured&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 准备发送到Flomo的数据&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flomo_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 如果有标签，添加到内容中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# Flomo使用 #tag 格式的标签&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tag_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39; &amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;#&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flomo_data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;content&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tag_text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 发送请求到Flomo API&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;Content-Type&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;application/json&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;flomo_api_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flomo_data&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="c1"&gt;# 设置超时时间，处理大文本可能需要更长时间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 检查响应&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;message&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Content successfully saved to Flomo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;flomo_response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Failed to save to Flomo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;status_code&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestException&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 处理请求异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Request to Flomo failed: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;# 处理其他异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;jsonify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;error&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Unexpected error: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}),&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;2、创建一个 qwen-client.py 的文件，内容如下：&lt;/p&gt;</description></item><item><title>天气和赛道的加持，仙桃半马 PB 9分钟</title><link>https://fwhyy.com/2025/04/supported-by-weather-and-track-conditions-xiantao-half-marathon-pb-lasts-for-9-minutes/</link><pubDate>Sat, 05 Apr 2025 16:38:00 +0800</pubDate><guid>https://fwhyy.com/2025/04/supported-by-weather-and-track-conditions-xiantao-half-marathon-pb-lasts-for-9-minutes/</guid><description>&lt;p&gt;上半年武汉和无锡的马拉松都报了名，但签运实在太差，毫无意外地双双落选，原本以为整个上半年都没法参赛了。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;没想到朋友推荐了仙桃马拉松。我在小红书上查了下，发现全马赛道爬升只有 20 多米，简直是PB神赛道。&lt;/p&gt;
&lt;p&gt;幸运的是，仙桃半马顺利中签。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504051635781.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;比赛定在 3 月 30 日。按照往年情况，这时候气温已经偏高，不太适合跑出好成绩。但我还是持续关注天气走势。结果在比赛前两周发现，30 日的周末正好遇上降温，这下又燃起了冲击成绩的念头。于是也跑了几次阈值跑和间歇训练。&lt;/p&gt;
&lt;p&gt;仙桃离武汉很近，决定自驾前往。29 号中午 12 点多到达仙桃，先在沔街溜达了一圈，结果没找到合适的吃饭的地方，最后导航去了吾悦广场，选择了蓉李记的小面给自己充碳。&lt;/p&gt;
&lt;p&gt;饭后前往荣怀学校领取参赛包，才发现原来荣怀学校就在吾悦广场旁边，早知道提前做做功课就省事了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504051636884.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;跑武汉周边的小比赛，通常都会订一家度假型酒店，这样老婆和女儿也能顺便玩一玩。这次选的是距离起点约 20 公里的天鹅湖度假酒店，位于沔阳小镇景区内。到达酒店已经是下午 4 点多。&lt;/p&gt;
&lt;p&gt;景区挺大，但比较冷清，逛了很久都没见几个人，很多商铺也没开门。也可能正因为如此，倒觉得别有一番宁静。因为晚上要去看汽车特技表演，匆匆在酒店早餐厅解决了晚饭，点了一个三人套餐继续充碳。&lt;/p&gt;
&lt;p&gt;饭后带女儿去看了华家班的汽车特技表演，小朋友看得特别兴奋。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504051637992.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;正片开始，终于说到比赛了。&lt;/p&gt;
&lt;p&gt;3 月 30 日凌晨 4 点半就醒了，比闹钟还早十几分钟，赛前的兴奋感导致这么早醒了也没觉得困。&lt;/p&gt;
&lt;p&gt;4 点 40 起床，烧水、泡面、排空、贴肌贴、乳贴、抹凡士林、吃面、换衣服&amp;hellip;&amp;hellip; , 一通操作后已经快 5 点半了。&lt;/p&gt;
&lt;p&gt;虽然赛道周边封路严重，但半小时内还是顺利抵达起点附近。步行到出发点时刚过 6 点，现场人还不多，移动厕所难得地不用排队，顺利进行了“第二次排空”。&lt;/p&gt;
&lt;p&gt;7 点吃下第一根胶，喝了一杯水。&lt;/p&gt;
&lt;p&gt;7 点半准时发枪。手机上显示气温 7 度，身穿背心短裤也并不觉得冷。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504051638219.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;半程排在全程后面出发，导致第一公里一直在人群中穿梭，随着慢慢跑开了，配速也慢慢加到了 5 分以内。&lt;/p&gt;
&lt;p&gt;第二公里赛道上的人没那么拥挤，便增大了步频和步幅，一看表显示 410 的配速，吓了一跳，要知道，410 差不多是平时跑间歇的配速。这完全得益于比赛的气氛和脚上第一次穿着比赛的 160 5.0 Pro 。虽然这时体感不累，但也不能冒进，赶紧降低了配速。&lt;/p&gt;
&lt;p&gt;10 公里时，吃了一根胶和一袋植电，这时的平均配速 422，有点出乎意料，之前的 10 公里最好成绩是 430 配速 。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504051638905.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;10 公里到 17 公里，关注的是心率，如果心率接近 170 就稍微降降速 。而且在 16 公里左右喝了赛速饮。没有感觉到有助力，反倒是在 18公里体感很累，算了下时间，远远超出了预期，就降速休息，一度速度掉到了 445 。&lt;/p&gt;
&lt;p&gt;最后一个转弯后，离终点还有两公里多，赛道非常平坦，一眼就能看到终点的拱门。于是咬牙加速，全力冲刺。&lt;/p&gt;
&lt;p&gt;最终完赛时间：1 小时 33 分 26 秒。比 2023 年南昌马拉松半程 PB 了整整 9 分钟！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202504051638251.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>MCP 和 Function Calling：概念</title><link>https://fwhyy.com/2025/03/mcp-and-function-calling-concepts/</link><pubDate>Mon, 31 Mar 2025 16:45:00 +0800</pubDate><guid>https://fwhyy.com/2025/03/mcp-and-function-calling-concepts/</guid><description>&lt;p&gt;随着人工智能的快速发展，大型语言模型（LLMs）逐渐深入到我们生活与工作的各个方面。然而，尽管模型强大，但其能力仍存在局限性，比如在实时信息获取和复杂任务执行方面仍有不足。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;RAG（检索增强生成）现在在企业的 AI 应用中使用很广泛，就是为了解决模型的信息不够实时，且没有垂直领域知识的问题。&lt;/p&gt;
&lt;p&gt;RAG 虽然厉害，但主要还是应用在智能知识问答领域，大模型想要有更强的能力，就需要有效、安全地与外界进行互动，这就诞生了 Function Calling 和 MCP 。&lt;/p&gt;
&lt;p&gt;Function Calling 依赖大模型的能力，MCP 是一种通用协议。&lt;/p&gt;
&lt;p&gt;本文从概念层面谈谈 Function Calling 和 MCP ，下一篇写几个代码例子。&lt;/p&gt;
&lt;h2 id="function-calling函数调用介绍"&gt;Function Calling（函数调用）介绍&lt;/h2&gt;
&lt;h3 id="概念"&gt;概念&lt;/h3&gt;
&lt;p&gt;Function Calling 是特定大模型（如 OpenAI 的 GPT-4、Qwen2 等）提供的一种机制，使模型能够主动生成结构化输出，以调用外部系统中预定义的函数或 API。&lt;/p&gt;
&lt;h3 id="执行流程"&gt;执行流程&lt;/h3&gt;
&lt;p&gt;通常我们说大模型调用 API，但这种说法并不完全准确，执行过程如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202503311644218.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;0、Agent 程序是我们开发的 AI 程序，在程序中会预先向大模型注册外部函数接口（建议不超过 20 个）。&lt;/p&gt;
&lt;p&gt;1、用户通过自然语言发起请求，Agent 接收到请求。&lt;/p&gt;
&lt;p&gt;2、Agent 程序将用户请求提交给大模型，模型首先解析语义并评估是否需要调用外部工具。&lt;/p&gt;
&lt;p&gt;3、模型如果判断需要调用函数，将生成包含工具 ID 和输入参数的调用指令，并返回给 Agent 程序。&lt;/p&gt;
&lt;p&gt;4、Agent 程序接收到模型返回的调用指令后，执行对工具函数的调用。&lt;/p&gt;
&lt;p&gt;5、工具函数执行后将结果返回给 Agent 程序。&lt;/p&gt;
&lt;p&gt;6、Agent 程序将函数返回的结果和自定义提示词一起反馈给大模型。&lt;/p&gt;
&lt;p&gt;7、大模型融合工具返回的数据与原始上下文，生成最终结果，并返回给 Agent 。&lt;/p&gt;
&lt;p&gt;8、Agent 程序将结果输出呈现给终端用户。&lt;/p&gt;
&lt;h3 id="特点"&gt;特点&lt;/h3&gt;
&lt;p&gt;1、主动调用：模型能够识别用户的自然语言意图，决定是否调用工具，并生成调用指令。&lt;/p&gt;
&lt;p&gt;2、实时反馈：模型生成的函数调用指令，由 Agent 程序执行后，再次反馈给模型，使模型生成实时和精准的回应。&lt;/p&gt;
&lt;p&gt;3、具体实现灵活：没有严格的标准通信协议要求，通信格式取决于具体模型厂商。这是个特点，也是个弊端。&lt;/p&gt;
&lt;h2 id="mcpmodel-context-protocol介绍"&gt;MCP（Model Context Protocol）介绍&lt;/h2&gt;
&lt;h3 id="概念-1"&gt;概念&lt;/h3&gt;
&lt;p&gt;MCP（Model Context Protocol，模型上下文协议）是 Anthropic 公司在 2024 年 11 月推出的一种标准协议。它的目的是给 AI 模型（如大语言模型）和外部数据源或工具之间建立起统一的通信接口。&lt;/p&gt;
&lt;p&gt;可以简单类比为 AI 的 USB 接口，无论是 AI 模型还是外部工具，只要符合 MCP 标准，就可以实现快速“即插即用”的连接，不需要为每个工具单独编写接口程序。也没有变成语言的限制，就像前后端分离后，基于 WebAPI 的规范就可以，什么语言都能写接口。&lt;/p&gt;
&lt;p&gt;现在 OpenAI 也支持了 MCP 。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202503311645324.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="特点-1"&gt;特点&lt;/h3&gt;
&lt;p&gt;1、开放性：MCP 是开放标准，任何开发者或服务商均可基于此协议开发 API，避免重复造轮子，推动生态共建，目前已有大量 MCP 集合站（如：&lt;a href="https://mcp.so)./"&gt;https://mcp.so）。&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2、标准化：采用 JSON-RPC 2.0 标准通信，确保交互统一、高效。&lt;/p&gt;</description></item><item><title>在Windsurf中使用李继刚提示词</title><link>https://fwhyy.com/2025/03/using-li-jigangs-prompt-words-in-windsurf/</link><pubDate>Sat, 15 Mar 2025 16:01:00 +0800</pubDate><guid>https://fwhyy.com/2025/03/using-li-jigangs-prompt-words-in-windsurf/</guid><description>&lt;p&gt;尽管现在有各种各样的推理模型，但提示词依然很重要，甚至可以玩出很多创意，我觉得提示词是一门艺术。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="提示词"&gt;提示词&lt;/h2&gt;
&lt;p&gt;最近在推上看到李继刚分享了不少提示词，有言外之意、生成 svg 图等。因为个人习惯，李继刚的提示词都是使用 lisp 语言来写的。&lt;/p&gt;
&lt;p&gt;例如有一个解析「言外之意」的提示词如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-lisp" data-lang="lisp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; ━━━━━━━━━━━━━━&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 作者: 李继刚&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 版本: 0.2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 模型: Claude 3.7 Sonnet&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 用途: 听话要听音，读懂言外之意&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; ━━━━━━━━━━━━━━&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 设定如下内容为你的 *System Prompt*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;dash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;伽达默尔&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;听懂你的言外之意&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;性格&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;敏锐&lt;/span&gt; &lt;span class="nv"&gt;谨慎&lt;/span&gt; &lt;span class="nv"&gt;通达&lt;/span&gt; &lt;span class="nv"&gt;澄明&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;技能&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;洞察&lt;/span&gt; &lt;span class="nv"&gt;推理&lt;/span&gt; &lt;span class="nv"&gt;融会&lt;/span&gt; &lt;span class="nv"&gt;逆思&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;表达&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;简约&lt;/span&gt; &lt;span class="nv"&gt;透彻&lt;/span&gt; &lt;span class="nv"&gt;深刻&lt;/span&gt; &lt;span class="nv"&gt;直白&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;言外之意&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;用户输入&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;伽达默尔看你表演，听懂你没说出来的话音&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let*&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;响应&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;用户输入&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;核心命题&lt;/span&gt; &lt;span class="c1"&gt;;; 提炼关键命题，分别做后续处理&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;正向推理&lt;/span&gt; &lt;span class="c1"&gt;;; 基于命题往前推理，得到将说未说之意&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;反向逆思&lt;/span&gt; &lt;span class="c1"&gt;;; 强调正面，就意味着反面严重不成立&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;视域融合&lt;/span&gt; &lt;span class="c1"&gt;;; 结合经验和语言含义，得到新的深层理解&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;揶揄讥嘲&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;few-shots&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;我学校是中国 Top 3 院校&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;这货妥妥的是排名第三名的那学校。如果是第一名或第二名，丫直接说出来。&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;你就坐着玩游戏吧，不用过来了。&amp;#34;&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;呆子! 这是点你呢！她是想说你敢继续坐着玩，你丫就完了！&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;生成卡片&lt;/span&gt; &lt;span class="nv"&gt;用户输入&lt;/span&gt; &lt;span class="nv"&gt;响应&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;生成卡片&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;用户输入&lt;/span&gt; &lt;span class="nv"&gt;响应&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;生成优雅简洁的 SVG 卡片&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;画境&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;`&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:画布&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;480&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt; &lt;span class="mi"&gt;760&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="ss"&gt;:margin&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="ss"&gt;:配色&lt;/span&gt; &lt;span class="nv"&gt;极简主义&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="ss"&gt;:排版&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;对齐&lt;/span&gt; &lt;span class="nv"&gt;重复&lt;/span&gt; &lt;span class="nv"&gt;对比&lt;/span&gt; &lt;span class="nv"&gt;亲密性&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="ss"&gt;:字体&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;font-family&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;KingHwa_OldSong&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="ss"&gt;:构图&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;外边框线&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;标题&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;言外之意&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;分隔线&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;背景色&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;自动换行&lt;/span&gt; &lt;span class="nv"&gt;用户输入&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;美化排版&lt;/span&gt; &lt;span class="nv"&gt;响应&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;分隔线&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;李继刚 2025&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;元素生成&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nv"&gt;画境&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;defun&lt;/span&gt; &lt;span class="nv"&gt;start&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;伽达默尔,启动!&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;system-role&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;伽达默尔&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;听懂你的言外之意, 系统启动中...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; ━━━━━━━━━━━━━━&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;;; Attention: 运行规则!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 1. 初次启动时必须只运行 (start) 函数&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 2. 接收用户输入之后, 调用主函数 (言外之意 用户输入)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 3. 严格按照(生成卡片) 进行排版输出&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; 4. 输出完 SVG 后, 不再输出任何额外文本解释&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;;; ━━━━━━━━━━━━━━&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面是一段 lisp 代码，看上去有点晦涩，AI 大佬宝玉进行了翻译：&lt;/p&gt;</description></item><item><title>理性看待 Manus</title><link>https://fwhyy.com/2025/03/rationally-view-manus/</link><pubDate>Fri, 07 Mar 2025 13:02:00 +0800</pubDate><guid>https://fwhyy.com/2025/03/rationally-view-manus/</guid><description>&lt;p&gt;1、3 月 3 号听张小珺 Jùn｜商业访谈录的《对 Manus 创始人肖弘的 3 小时访谈：世界不是线性外推，做博弈中的重要变量》时就知道了 Manus，当时没啥感觉。没想到才过来几天就爆火了。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;&lt;a href="https://www.xiaoyuzhoufm.com/episode/67c3d80fb0167b8db9e3ec0f"&gt;https://www.xiaoyuzhoufm.com/episode/67c3d80fb0167b8db9e3ec0f&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2、Manus 的创始人肖弘，华中科技大学毕业，连续创业者。第一次创业是 2016 到 2019 年的壹伴助手，积累了产品和市场经验；2020 年二次创业做企业微信生态下的微伴助手，并成功被明略科技收购。经过短暂整合后再度出发，2022 年推出了 AI 浏览器插件 Monica 。&lt;/p&gt;
&lt;p&gt;3、B 站上 3 月 5 号就有个介绍视频，视频中的季逸超（Peak）是少年极客，20 岁拿到真格基金的投资，Manus 这个名字就是 Peak 取的。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.bilibili.com/video/BV1zZ9RYcEpL"&gt;https://www.bilibili.com/video/BV1zZ9RYcEpL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;4、取名的来源是 MIT 校训：Mens et Manus 拉丁文英文翻译为 &amp;ldquo;Mind and Hand&amp;rdquo; 就是 &amp;ldquo;思想与手&amp;rdquo; 的意思。不只是会想，更关键的是能行动、能实操，把知识与现实执行结合起来，真正实现人类智慧与行动的融合。&lt;/p&gt;
&lt;p&gt;5、目前 Manus 的火爆程度可谓是一码难求。在中文圈内引起轩然大波（火的非常突然），有说产品很牛的，也有说是炒作的。邀请码在海鲜市场上也炒到很高的价格。我也在官网申请排队了，这个是排队地址：https://manus.im/invitation/waitlist 。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202503071243175.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6、目前有一些大佬拿到了验证码，进行体验后的评价基本都是认可的。非常期待能快点排上队，或者公测的开放。现在也可以在这个链接中看看案例的回放。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://manus.im/usecases"&gt;https://manus.im/usecases&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下面这位体验者的感受我觉得是比较客观的。Manus 肯定不是能解决所有问题的神，但至少将大模型和普通用户又拉进了一点。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202503071243134.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;7、Manus 团队昨天发布的声明，爆火也是他们意料之外。我觉得如果多给他们一点时间和善意，没准就能出来一个好用的工具。就像肖弘在访谈中说的那样，最想做到就是给世界带来一个好用的工具。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202503071258156.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;8、Manus 把各种能力整合到了一起，比如 DeepResearch、Operator、Claude Computer Use 。给他一个任务后，首先是分解，创建 TodoList 清单，然后按照清单中的任务去执行，执行完成后会修改清单中的状态。这完全是一个类人的思维和操作。&lt;/p&gt;
&lt;p&gt;9、整个过程中可以看到所有执行的过程和步骤，有点像安排一个活给实习生，然后站在实习生背后看他操作电脑一样。如果后续人可以打断、调整那就更强了。&lt;/p&gt;
&lt;p&gt;10、Manus 是在云端异步运行，用户可以随时关闭电脑或者去做其他的事情，任务会在后台持续执行，完成后会通知用户。&lt;/p&gt;
&lt;p&gt;11、现在很多工作都在微信、企业微信、钉钉、飞书的各种群里展开，畅享一下，如果群里有个 Manus 会怎么样，不同角色的人可以和 Manus 一起协作来完成一件事。其间，人可以干预让 Manus 调整，如果 Manus 还不具备某种技能可以让人来协助，人处理完后提交成果让 Manus 继续。举个例子：让 Manus 将一个 300 万行的代码转换为另一种语言，并能够正常运行，只需要安排一个高级程序员盯着就可以。&lt;/p&gt;
&lt;p&gt;12、25 年注定是热闹的一年，期待更多好玩的东西出现。&lt;/p&gt;</description></item><item><title>12个问题深入理解DeepSeek（含开源周内容）</title><link>https://fwhyy.com/2025/03/12-questions-to-gain-a-deeper-understanding-of-deepseek-including-content-from-open-source-week/</link><pubDate>Tue, 04 Mar 2025 09:21:00 +0800</pubDate><guid>https://fwhyy.com/2025/03/12-questions-to-gain-a-deeper-understanding-of-deepseek-including-content-from-open-source-week/</guid><description>&lt;h2 id="一deepseek-创始人是谁"&gt;一、DeepSeek 创始人是谁？&lt;/h2&gt;
&lt;!-- more --&gt;
&lt;p&gt;DeepSeek 的创始人是梁文锋，1985 年出生。他的职业生涯分为两个大的阶段，先做金融，再做 AI。&lt;/p&gt;
&lt;p&gt;1、2015 年: 创立杭州幻方科技，专注于通过数学和 AI 进行量化投资
3、2023 年 5 月: 宣布进军通用人工智能 (AGI) 领域
3、2023 年 7 月: 成立大模型公司 DeepSeek，致力于前沿 AI 技术研发&lt;/p&gt;
&lt;p&gt;梁文锋与其他 AI 模型的研究者不同，没有海外经历，毕业于浙江大学电子工程系人工智能方向。整个 DeepSeek 的研发团队也基本都是本土成员。&lt;/p&gt;
&lt;p&gt;下面是梁文锋的一些访谈资料：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.bilibili.com/video/BV1LQFQeFEAZ"&gt;https://www.bilibili.com/video/BV1LQFQeFEAZ&lt;/a&gt;
&lt;a href="https://mp.weixin.qq.com/s/Cajwfve7f-z2Blk9lnD0hA"&gt;https://mp.weixin.qq.com/s/Cajwfve7f-z2Blk9lnD0hA&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="二为什么-deepseek-能出圈"&gt;二、为什么 DeepSeek 能出圈？&lt;/h2&gt;
&lt;p&gt;1、DeepSeek R1 的效果从测试数据上看，和 o1 差不多，有的方面甚至超过了 o1 。&lt;/p&gt;
&lt;p&gt;2、DeepSeek 的 R1 是开源的，而且还是最宽松的 MIT 协议。&lt;/p&gt;
&lt;p&gt;3、在技术上有创新，而不只是 Follow 国外的技术。&lt;/p&gt;
&lt;p&gt;4、因为创新，成本大幅降低，所以 API 的接口相比 OpenAI 也便宜得离谱。&lt;/p&gt;
&lt;p&gt;5、最重要的，DeepSeek 是一家中国公司。&lt;/p&gt;
&lt;h2 id="三deepseek-的发展历程是什么样的"&gt;三、DeepSeek 的发展历程是什么样的？&lt;/h2&gt;
&lt;p&gt;1、2023 年 5 月，DeepSeek（深度求索）成立。&lt;/p&gt;
&lt;p&gt;2、2023 年 11 月，DeepSeek Coder 发布，现在依然是开源代码模型的标杆。&lt;/p&gt;
&lt;p&gt;3、2024 年 2 月，DeepSeek Math 发布，7B 模型逼近 GPT-4 的能力。&lt;/p&gt;
&lt;p&gt;4、2024 年 3 月，DeepSeek VL 发布，作为自然语言到多模态的初探。&lt;/p&gt;
&lt;p&gt;5、2024 年 5 月，DeepSeek V2 发布，成为全球最强开源通用 MoE 模型。&lt;/p&gt;
&lt;p&gt;6、2024 年 6 月，DeepSeek Code V2 发布，成为最强开源代码模型。&lt;/p&gt;
&lt;p&gt;7、2024 年 9 月，DeepSeek V2.5 发布，融合通用和代码能力的全新开源模型。&lt;/p&gt;
&lt;p&gt;8、2024 年 11 月，DeepSeek R1 Lite 预览版上线，展现了公开的完整思考过程，没错，就是 OpenAI o1 藏着掖着的那个。&lt;/p&gt;</description></item><item><title>插件开发：实现 Obsidian 同步到 hexo</title><link>https://fwhyy.com/2025/02/plugin-development-implement-obsidian-synchronization-to-hexo/</link><pubDate>Thu, 13 Feb 2025 08:37:00 +0800</pubDate><guid>https://fwhyy.com/2025/02/plugin-development-implement-obsidian-synchronization-to-hexo/</guid><description>&lt;p&gt;近两年一直使用 Obsidian 进行最终文字的输出，除了发公众号，还会同步发布到博客中，博客使用的 hexo，现在发布博客的步骤是：&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;1、将文章标题在翻译软件中翻译为英文，并以横线隔开每个单词，作为 hexo 的文件名。&lt;/p&gt;
&lt;p&gt;2、vs code 打开 hexo 的代码，执行 &lt;code&gt;hexo n '英文的文件名'&lt;/code&gt; 。&lt;/p&gt;
&lt;p&gt;3、将 Obsidian 中的文章内容复制到新创建的 md 文件中。&lt;/p&gt;
&lt;p&gt;4、修改内容最上方的 Front Matter 信息，例如：categories、tags、date 等。&lt;/p&gt;
&lt;p&gt;5、执行下面命令完成构建和发布：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hexo g
hexo d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个步骤还是有点繁琐，所以经常会忘记更新，忘记不是因为我懒，而是方式不是最优，最终影响到了执行。平时工作也是同样的道理，一件事情如果很繁琐，不顺利，就得停下来看看方法是不是用错了。&lt;/p&gt;
&lt;p&gt;最近在尝试使用各类 AI 工具，就想着这个问题是可以写个 Obsidian 的插件来减少工作量的，于是花了一个晚上搞定了。&lt;/p&gt;
&lt;p&gt;1、使用的工具是 Windsurf，模型还是用的 Cloude 3.5 sonnet ，之所以没用 DeepSeek，是因为通过这几天的试用，感觉 Windsurf 对 Cloude 3.5 sonnet 的调教更优一些（个人感觉）。&lt;/p&gt;
&lt;p&gt;2、遵循一次性对话尽可能只让 AI 完成一件事的原则，我先让生成一个 Obsidian 插件的基础文件，核心逻辑在 main.ts 文件中：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202502121650565.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、接着就按照我上面提到的步骤一步一步引导 Windsurf 来完成开发。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;获取文章标题调用翻译 API 转换为英文，并添加横线隔开，翻译 API 一开始使用的腾讯，几轮下来还是存在问题，换成百度的翻译 API 就运行成功了&lt;/li&gt;
&lt;li&gt;将文章内容复制到 hexo 的 &lt;code&gt;_posts&lt;/code&gt; 目录，获取 Obsidian 文章中的 tag 和 categories，自动转换为 hexo 需要的 Front Matter 格式&lt;/li&gt;
&lt;li&gt;过程中如果遇到错误，可以打开 Obsidian-&amp;gt;View-&amp;gt;Toggle Developer Tools （和网页的 F12 一样），将错误信息提供，几轮下来基本都能解决&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4、代码写完，执行 &lt;code&gt;npm run build&lt;/code&gt; 进行构建，构建完成后，会生成一个新的 main.js 文件，Obsidian 插件需要的是包含 main.js 在内的三个文件，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202502121651563.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5、怎么安装到 Obsidian，具体步骤也可以在 Windsurf 中询问：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202502121651705.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要注意的是重新覆盖了 main.js 文件后，需要重新加载插件（禁用后重新启用）才能生效。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;6、首次安装后，在 Obsidian 的第三方插件中就可以看到自己开发的插件了：&lt;/p&gt;</description></item><item><title>从费曼学习法的角度谈谈写作</title><link>https://fwhyy.com/2025/02/discussing-writing-from-the-perspective-of-feynman-learning-method/</link><pubDate>Mon, 10 Feb 2025 22:21:00 +0800</pubDate><guid>https://fwhyy.com/2025/02/discussing-writing-from-the-perspective-of-feynman-learning-method/</guid><description>&lt;p&gt;之前读过一篇文章《Why Blog If Nobody Reads It?》，其中一句话让我印象深刻：&lt;/p&gt;
&lt;!-- more --&gt;
&lt;blockquote&gt;
&lt;p&gt;你带着相机在城市中穿梭，看到了光影交错、人情流露的画面，于是你按下了快门，但没有人关注。然而，你并不是为了取悦他人，而是想要捕捉那个美好的瞬间。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;写作与此类似。很多人写博客、做公众号，常常会想：“没人看，为什么还要写？” 有的人写作是为了流量，为他人而写，还有一种是为了自己而写。王建硕曾说过，他的公众号的文章首先是写给自己看的，是自己思考的过程。&lt;/p&gt;
&lt;p&gt;我也是如此。&lt;/p&gt;
&lt;p&gt;平时我们在思考和观察中产生的想法、读书的感悟、学习技术做的笔记，当这些内容变成文字被记录时，就已经存在了意义。也只有当这些内容变成文字时，我们才能真正内化所看到的内容，形成了自己的知识。&lt;/p&gt;
&lt;p&gt;费曼学习法强调了类似的思想，即通过输出（教别人）来深化自己的理解，当然也可以是教自己。正因为如此，我们在写作时可以思考怎么与费曼学习结合起来。&lt;/p&gt;
&lt;h2 id="费曼学习法是什么"&gt;费曼学习法是什么？&lt;/h2&gt;
&lt;p&gt;费曼学习法由诺贝尔奖获得者理查德·费曼提出，它的核心非常简单：通过教别人来更深入地理解知识。主要有以下四个步骤：&lt;/p&gt;
&lt;p&gt;1、选择主题：确定你想深入理解的知识领域。&lt;/p&gt;
&lt;p&gt;2、教别人：用简单易懂的语言向他人解释知识点，就像教一个小学生一样。&lt;/p&gt;
&lt;p&gt;3、找到知识盲点：在解释过程中，发现自己讲不清楚的部分，这些就是需要进一步学习的地方。&lt;/p&gt;
&lt;p&gt;4、复习和简化：针对盲点深入学习，然后再用更简单的语言重新讲解。&lt;/p&gt;
&lt;p&gt;关键点在于“教”，教的前提是自己有思考，能总结。很多时候看一个学习类的视频教程，听的时候总感觉自己懂了，但动手实践或者转述给其他人时会发现不足所措，原因就是没有真正掌握。&lt;/p&gt;
&lt;h2 id="如何通过写作运用费曼学习法"&gt;如何通过写作运用费曼学习法？&lt;/h2&gt;
&lt;p&gt;在写作中践行费曼学习法，可以有效地深入对知识的理解。&lt;/p&gt;
&lt;p&gt;首先要在平时阅读和浏览各类信息时，养成及时记录和收集的习惯。无论是书籍、文章还是视频，都要将感兴趣或值得进一步探究的内容记录下来，这样做的目的是明确自己想要深入学习和研究的主题。&lt;/p&gt;
&lt;p&gt;当我们开始整理这些记录时，需要将所了解的内容转换成自己的语言进行重新描述，这其实就是在用费曼学习法的方式自己教自己，通过解释的过程发现知识的盲点。&lt;/p&gt;
&lt;p&gt;此外，我们还可以将写作的内容与他人分享，可以是私下分享，也可以通过公开发布的方式。&lt;/p&gt;
&lt;p&gt;无论是哪种形式，这种输出都会促使我们更加认真地去思考和理解。同时，分享还能带来读者的反馈，这些反馈非常有价值，能够指出我们的理解盲区，帮助我们发现之前忽略的视角和问题。&lt;/p&gt;
&lt;p&gt;接下来，我们需要对反馈进行深入思考和记录，再结合后续获取的新信息，这样就形成了一个持续学习和知识迭代的过程。&lt;/p&gt;
&lt;p&gt;通过不断重复这样的过程，我们的知识体系会变得越来越稳固，表达也更加清晰，写作能力和理解深度都能得到明显提升。&lt;/p&gt;
&lt;p&gt;因此，养成记录、总结、根据反馈再思考的习惯，是在写作中有效践行费曼学习法的重要途径。&lt;/p&gt;
&lt;h2 id="如何具体开始写作"&gt;如何具体开始写作？&lt;/h2&gt;
&lt;p&gt;墨问的开屏语是记录即创作。记录看似简单，其实非常难。年初我跟老婆说我今年要学习视频剪辑，平时要多拍素材。结果上周末带女儿出去玩，整个过程都没想起来要拍点什么，还被老婆嘲笑了。&lt;/p&gt;
&lt;p&gt;养成一个习惯虽然难，但可以通过练习做到的。&lt;/p&gt;
&lt;p&gt;写作也是如此，起初总觉得没什么可写，不知道从哪里开始。有一个方法可以让我们比较简单的开始，比如，看一本书，书上的一句话觉得很棒，很有道理，就摘录下来，顺手写下自己的感想，感想可以写的很长，也可以是“很有道理”、“很棒”这类精炼的评价。&lt;/p&gt;
&lt;p&gt;记录的工具选择自己喜欢的就行，可以是纸笔、也可以是 APP。&lt;/p&gt;
&lt;p&gt;不要一开始就想着写出一篇“好文章”，那样会给自己太多压力，适得其反。可以先试着每天写几句话，写读书笔记、写生活碎片、写一个小想法，哪怕只是几句话也没关系。关键不是写得多好，而是让“表达”成为一种日常行为。&lt;/p&gt;
&lt;p&gt;当你持续记录，慢慢地，写作的逻辑、语言的组织、表达的自信都会悄悄地成长起来。当记录的内容足够多，自然能按照某个主题拎出一连串之前记录的内容，重新组织就是一篇文章了。&lt;/p&gt;
&lt;p&gt;写作不是天赋，是可以训练出来的能力。&lt;/p&gt;
&lt;h2 id="如何形成长期写作习惯"&gt;如何形成长期写作习惯？&lt;/h2&gt;
&lt;p&gt;长期写作的意义，远不止于“输出内容”，更像是一个持续运行的认知操作系统。很多人把写作当作一次性的任务，用完即弃；但对持续学习者来说，写作是一种主动思考、整理知识、构建认知结构的过程。&lt;/p&gt;
&lt;p&gt;要真正发挥写作的价值，就要将其变成一种长期的习惯。&lt;/p&gt;
&lt;p&gt;首先，写作可以帮助我们梳理知识、搭建思维框架。在这个信息爆炸的时代，写作就像是过滤器，逼迫我们从海量信息中提炼出真正理解的内容，找到不同知识之间的连接。&lt;/p&gt;
&lt;p&gt;比如你近期读了几篇关于 AI Agent 的文章，写一篇总结时，往往会促使你去查缺补漏、弄清逻辑关系，最终内化为自己的知识体系。这也是我为什么认为解决程序 Bug 的过程是成长最快的时候。&lt;/p&gt;
&lt;p&gt;其次，持续写作是表达力的长期训练场。要求我们把复杂的想法讲清楚，用准确、简洁、有条理的语言呈现。这种表达能力不仅能提升你在工作中的沟通效率，也能让你在任何知识分享场合更具说服力，比如面试、内部技术分享等。&lt;/p&gt;
&lt;p&gt;更重要的是，写作会形成一个正向反馈循环：你开始写作，输出内容，获得反馈，进行反思，然后继续写作。这个过程中，学习不再是孤立的“输入”，而是一个不断进化、反哺自身的系统。&lt;/p&gt;
&lt;p&gt;坚持写作，不只是记录所学，更是在打磨思维方式，构建长期竞争力。&lt;/p&gt;</description></item><item><title>DeepSeek R1震撼登场：从介绍到使用</title><link>https://fwhyy.com/2025/02/deepseek-r1-makes-a-stunning-debut-from-introduction-to-use/</link><pubDate>Sat, 08 Feb 2025 16:31:00 +0800</pubDate><guid>https://fwhyy.com/2025/02/deepseek-r1-makes-a-stunning-debut-from-introduction-to-use/</guid><description>&lt;p&gt;春节期间，DeepSeek 掀起了一股热潮，成为了科技领域的热门话题。身边很多非圈内人士茶余饭后也在讨论 DeepSeek，足以见得其火爆程度。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="介绍"&gt;介绍&lt;/h2&gt;
&lt;p&gt;DeepSeek 全称：杭州深度求索人工智能基础技术研究有限公司，成立于 2023 年 7 月 17 日。由知名量化投资机构幻方量化创立并孵化。&lt;/p&gt;
&lt;p&gt;幻方量化是中国顶尖的对冲基金公司，擅长利用 AI 算法优化金融交易策略。其强大的算力资源和技术积累为 DeepSeek 的研发提供了硬件支持和资金保障。&lt;/p&gt;
&lt;p&gt;DeepSeek 的创始人梁文峰出生于 1985 年，17 岁考入浙江大学，拥有信息与电子工程学硕士学位。2023 年，梁文锋宣布进军通用人工智能（AGI）领域，创办了 DeepSeek，致力于开发真正人类级别的人工智能。&lt;/p&gt;
&lt;p&gt;DeepSeek 近期发布了三个模型，分别是：24 年 12 月 26 的 DeepSeek V3、25 年 1 月 20 日发布了 DeepSeek R1、25 年 1 月 28 日发布的多模态模型 Janus-Pro 。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;V3：该模型是混合专家（MoE）架构，参数量达 6710 亿，激活参数为 370 亿，预训练数据量为 14.8 万亿 token。在百科知识（MMLU、GPQA）、长文本（DROP、LongBench v2）、代码（Codeforces）、数学（AIME 2024、CNMO 2024）等评测中超越主流开源模型（如 Qwen2.5-72B、Llama-3.1-405B），并与 Claude-3.5-Sonnet、GPT-4o 等闭源模型性能持平。
R1：专注于数学、代码、自然语言推理任务，性能对标 OpenAI o1 正式版，部分测试（如AIME 得分率 79.8% vs. o1 的 79.2% ）实现超越。API 调用成本仅为 OpenAI o1 的3.7%（输出 Token 每百万 16元），训练总成本约 550 万美元，算力需求显著低于同类模型
Janus-Pro：作为 DeepSeek 首款开源多模态模型，Janus-Pro 支持视觉、语言等多模态输入输出，填补此前 V3 模型仅限文本交互的局限。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我是 DeepSeek 的早期用户，开始使用时，只有网页版，非常简陋，还没有历史记录，但回答问题的效果不错，特别是编程相关。给我的感觉是认真在做模型，在应用层面不太重视。即便是到现在，依然没有花哨的应用层功能，硬是靠强大的模型能力和创新火出圈了。&lt;/p&gt;
&lt;p&gt;DeepSeek R1 的技术报告地址如下：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/deepseek-ai/DeepSeek-R1/blob/main/DeepSeek_R1.pdf"&gt;https://github.com/deepseek-ai/DeepSeek-R1/blob/main/DeepSeek_R1.pdf&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="使用"&gt;使用&lt;/h2&gt;
&lt;h3 id="网页端"&gt;网页端&lt;/h3&gt;
&lt;p&gt;浏览器访问这个地址：https://chat.deepseek.com/ ，手机号或者微信注册，登录后如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202502071551961.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;深度思考后面括号里写的是 R1，说明使用的是 R1 模型，深度思考和联网搜索可以同时勾选，比如我让评价射雕的电影，可以看到 DeepSeek 先搜索网页，再进行深度思考，思考过程也会显示在页面中：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202502071552247.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="app"&gt;APP&lt;/h3&gt;
&lt;p&gt;DeepSeek 最近推出了移动端，网页版的左下角有下载二维码。抛开最近的稳定性不谈，可以免费在电脑和手机上使用 R1 模型，已经非常良心了。&lt;/p&gt;</description></item><item><title>2024 年终总结</title><link>https://fwhyy.com/2025/01/2024-yearend-summary/</link><pubDate>Fri, 31 Jan 2025 16:30:00 +0800</pubDate><guid>https://fwhyy.com/2025/01/2024-yearend-summary/</guid><description>&lt;p&gt;律转鸿钧，新元肇启。2024 已然过去，这一年有很多的变化，特别是 AI 的发展迅猛，变化是好事，意味着有会带来更多的机遇，关键是我们需要时刻做好准备才能抓住。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;下面还是按照我的习惯方式给 2024 年做下总结。&lt;/p&gt;
&lt;h2 id="成长"&gt;成长&lt;/h2&gt;
&lt;p&gt;在这个 AI 飞速发展的时代，各种工具层出不穷，按说效率应该更高更快，但我并没有觉得变得轻松了，反倒是更累。因为我们接收的信息需要消化才能转化为自己的知识，而在 AI 时代，同等时间接收的东西更多了，需要消化的就更多了，如果消化能力没有提升，就会很累。&lt;/p&gt;
&lt;p&gt;还发现了一个现象，现在很难沉下心来进行长文的阅读，阅读长文需要「慢」下来才行，在 AI 这个「快」的时代，慢下来很难，但也可能会收获更多。&lt;/p&gt;
&lt;p&gt;信息的处理工具很多还在探索中，这个探索是没有期限的，但总的来说有四个方面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;信息源：Follow、公众号、得到、小报童、读库&lt;/li&gt;
&lt;li&gt;输入：flomo、get笔记&lt;/li&gt;
&lt;li&gt;消化：暂无&lt;/li&gt;
&lt;li&gt;输出：obsidian&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 2025 年，我的关键词是：慢、消化。&lt;/p&gt;
&lt;h2 id="跑步"&gt;跑步&lt;/h2&gt;
&lt;p&gt;2024 年立下的 Flag 基本达成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;跑量 2000+&lt;/li&gt;
&lt;li&gt;全马突破 330&lt;/li&gt;
&lt;li&gt;跑一次 70 公里的越野（目标赛事：崇礼 168）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2024 年总跑量 3000 整，虽然这个数字是凑出来的（最后几公里），但也体现了坚持的成果。11 月 17 日的光谷马拉松官方成绩是 3 小时 30 分 51 秒，算是勉强达成了目标。7 月去崇礼跑了 MTC 组别（70 公里），安全完赛，这是一个重要的突破。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501311215712.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2024 年的跑步历程：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 月，PB 计划的训练结束，参加了石家庄马拉松，全马 PB 了 80 分钟&lt;/li&gt;
&lt;li&gt;7 月，挑战 70 公里越野&lt;/li&gt;
&lt;li&gt;11 月，全马又有小的进步&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整个 24 年一直没有停下脚步，也取得了一些成绩。非常感谢跑者日历四群的陪伴。&lt;/p&gt;
&lt;p&gt;25 年，已经确定的比赛有 4 月份的云丘山越野，其他就看缘分了。比赛不是关键，关键是能一直健康跑下去。&lt;/p&gt;
&lt;h2 id="旅行"&gt;旅行&lt;/h2&gt;
&lt;p&gt;24 年的国庆长假依旧选择了自驾出行，不过这次多了些不一样的体验。以前的老同事一家和我们一起同行，女儿也多了一个玩伴，使整个旅途充满了更多的乐趣。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501311215832.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;行程从武汉出发，途经池州、宣城、泾县、徽州、安庆，最后回到武汉。值得一提的是，出行的这些天，每天都坚持跑步，将运动和旅行完美结合。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501311216148.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="公众号"&gt;公众号&lt;/h2&gt;
&lt;p&gt;因为始终坚持「为自己而写」的理念，今年的更新比较随性，一共只发布了 38 篇文章。&lt;/p&gt;
&lt;p&gt;今年公众号的信息流策略发生了变化，推荐带来的阅读占比越来越大。比如最近写的《信创浪潮下的.NET困境与技术转型思考》就因为推荐获得了 6000 多的阅读量。&lt;/p&gt;
&lt;p&gt;这个改变带来了几个影响：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;即便是晚上或凌晨发布文章，也不会被淹没&lt;/li&gt;
&lt;li&gt;对大众有共鸣的选题或热点事件选题，更容易带来更高的阅读量&lt;/li&gt;
&lt;li&gt;标题显得更重要了，当然内容更重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2025 年还会继续写作，可能更多、也可能更少，保持随性就好。&lt;/p&gt;
&lt;h2 id="读书"&gt;读书&lt;/h2&gt;
&lt;p&gt;今年在公众号输出了三本书的读后感：《笔记的方法》、《强风吹拂》、《华为项目管理之道》。但实际的阅读量远不止这些，在得到电子书看了不少书籍，还有读库、follow 上的订阅和大量的公众号文章。&lt;/p&gt;
&lt;p&gt;25 年想多看看「闲」书，避免自己掉进信息茧房。有时候，跳出专业领域的阅读，反而能带来意想不到的收获。&lt;/p&gt;
&lt;h2 id="播客"&gt;播客&lt;/h2&gt;
&lt;p&gt;Follow 中虽然可以订阅小宇宙的播客，但因为不能登录，无法记录播放时长和评论，所以使用频率不高，主要是看看 shownotes。所以播客主要还是在上下班途中和跑步时听。&lt;/p&gt;
&lt;p&gt;除了跑步相关的播客，今年听了很多商业和 AI 相关的节目：&lt;/p&gt;</description></item><item><title>为什么单线程的Redis也能如此高效？</title><link>https://fwhyy.com/2025/01/why-can-single-threaded-redis-be-so-efficient/</link><pubDate>Fri, 17 Jan 2025 20:29:00 +0800</pubDate><guid>https://fwhyy.com/2025/01/why-can-single-threaded-redis-be-so-efficient/</guid><description>&lt;p&gt;提起 Redis，一个印象就是速度很快的开源内存数据库，而且还是单线程的。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;但印象有时会骗人：&lt;/p&gt;
&lt;p&gt;1、redis 6.0 后采用了多线程&lt;/p&gt;
&lt;p&gt;2、redis 7.4 之后修改了开源协议&lt;/p&gt;
&lt;h2 id="单线程为什么速度还很快"&gt;单线程为什么速度还很快？&lt;/h2&gt;
&lt;p&gt;1、Redis 的客户端调用服务器经过三个过程：发送命令、执行命令和返回结果。在命令执行阶段，由于 Redis 处理命令是单线程的，在服务器上到达的所有命令不会立即被执行。所有命令都进入队列并按顺序执行。多个客户端发送的命令执行顺序不确定。但是可以确定的是两个命令不会同时执行，避免了并发问题。这是 Redis 的基本单线程模型。&lt;/p&gt;
&lt;p&gt;2、Redis 完全基于内存，数据存储在内存中。大多数请求都是纯内存操作，所以速度非常快。与传统的磁盘文件数据存储相比，Redis 避免了通过磁盘 I/O 读取数据到内存的开销。&lt;/p&gt;
&lt;p&gt;3、使用单线程可以节省很多上下文切换和 CPU 消耗的时间，没有竞争条件，不需要考虑各种锁定问题，并且不会因为死锁而导致性能开销。此外，它还允许使用各种「线程不安全」的命令，例如 Lpush。&lt;/p&gt;
&lt;p&gt;4、需要注意的是，当我们强调单线程时，我们指的是使用一个线程来处理网络 I/O 和键值对读写。换句话说，一个线程处理所有网络请求。但 Redis 的其他功能，如持久性、异步删除和集群数据同步，实际上是由额外的线程执行。也就是说即便是在 6.0 之前的版本，也不是绝对的单线程。&lt;/p&gt;
&lt;p&gt;5、Redis 虽然是纯内存操作，但仍然会涉及到网络 I/O 和磁盘 I/O（持久化操作），Redis 使用非阻塞 I/O 和 I/O 多路复用技术（如 &lt;code&gt;select&lt;/code&gt;、&lt;code&gt;poll&lt;/code&gt;、&lt;code&gt;epoll&lt;/code&gt;）来处理大量的并发连接。这意味着一个线程可以同时监听多个客户端的连接请求，并在有数据可读或可写时进行处理。这种方式避免了线程在等待 I/O 操作完成时的阻塞，从而提高了系统的并发处理能力。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;非阻塞 I/O：允许程序在 I/O 操作未完成时继续执行其他任务。&lt;/li&gt;
&lt;li&gt;I/O 多路复用：通过单线程监控多个 I/O 操作，提升高并发下的效率。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;6、官方对单线程的解释是：因为 CPU 不是 Redis 的瓶颈，最有可能的是机器内存或网络带宽。由于单线程易于实现，并且 CPU 不会成为瓶颈，采用单线程解决方案是有意义的。&lt;/p&gt;
&lt;h2 id="为什么-60-又采用了多线程"&gt;为什么 6.0 又采用了多线程？&lt;/h2&gt;
&lt;p&gt;Redis 在 6.0 版本引入多线程支持，主要是为了应对现代硬件架构的变化和日益复杂的业务需求，同时解决单线程模型在高并发场景下的性能瓶颈。&lt;/p&gt;
&lt;h3 id="1提升网络-io-性能"&gt;1、提升网络 I/O 性能&lt;/h3&gt;
&lt;p&gt;Redis 的主要性能瓶颈在于网络 I/O，尤其是在高并发场景下，单线程模型难以高效处理大量的网络请求。虽然 Redis 使用了 I/O 多路复用技术（如 &lt;code&gt;epoll&lt;/code&gt;）来优化网络处理，但随着硬件性能的提升，单线程的网络 I/O 处理能力逐渐成为瓶颈。&lt;/p&gt;
&lt;p&gt;通过引入多线程，Redis 可以将网络 I/O 操作（如读取客户端请求和写回响应）分配到多个线程并行处理，从而显著提升网络吞吐量和降低延迟。&lt;/p&gt;
&lt;h3 id="2利用多核-cpu"&gt;2、利用多核 CPU&lt;/h3&gt;
&lt;p&gt;现在的服务器普遍配备多核 CPU，而 Redis 的单线程模型只能利用一个 CPU 核心，无法充分发挥硬件的性能潜力。通过引入多线程，Redis 可以将网络 I/O 任务分配到多个线程，充分利用多核 CPU 的计算能力，从而提高整体性能。&lt;/p&gt;
&lt;h3 id="3保持核心逻辑的简单性和一致性"&gt;3、保持核心逻辑的简单性和一致性&lt;/h3&gt;
&lt;p&gt;Redis 6.0 的多线程模型采用了混合设计：网络 I/O 操作由多个线程并行处理，而命令执行仍然由单线程顺序执行。这种设计既保留了单线程模型的简单性和一致性优势（如避免线程安全问题、保证命令的原子性），又通过多线程提升了网络 I/O 的性能。和之前的版本相比，只是将更多的事情由多线程来处理。&lt;/p&gt;
&lt;h3 id="4优化资源利用"&gt;4、优化资源利用&lt;/h3&gt;
&lt;p&gt;在高负载场景下，单线程模型可能导致 CPU 和内存资源的浪费。通过引入多线程，Redis 可以更高效地利用系统资源，减少请求的等待时间，从而提升整体性能。&lt;/p&gt;</description></item><item><title>从环境搭建到项目运行：Python 和 Flask 快速上手指南</title><link>https://fwhyy.com/2025/01/from-environment-setup-to-project-execution-a-quick-guide-to-getting-started-with-python-and-flask/</link><pubDate>Tue, 07 Jan 2025 20:27:00 +0800</pubDate><guid>https://fwhyy.com/2025/01/from-environment-setup-to-project-execution-a-quick-guide-to-getting-started-with-python-and-flask/</guid><description>&lt;p&gt;最近在研究 RAG，免不了会使用到 Python，本文简单介绍下 Python 从环境的搭建到运行一个简单的 Web 项目。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;操作系统：Mac 13.0&lt;/li&gt;
&lt;li&gt;Python：3.11.7&lt;/li&gt;
&lt;li&gt;包管理：poetry1.8.3&lt;/li&gt;
&lt;li&gt;Web 框架：Flask3.1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Python 中的包管理工具有 conda、pip、poetry、PyPI 等，Web 框架也有 Django、Flask、FastAPI ，为什么选择的是 poetry 和 Flask 呢？&lt;/p&gt;
&lt;p&gt;因为现在研究的 RAGFlow 的源码中使用的就是 poetry 和 Flask 。带着目的去学习效率会高很多。&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;h3 id="1-安装-python"&gt;1 、安装 Python&lt;/h3&gt;
&lt;p&gt;直接在官网下载安装就可以：https://www.python.org/downloads/，我很早前就安装了，一直没有升级，所以版本还是 3.11.7 。&lt;/p&gt;
&lt;h3 id="2-安装-poetry"&gt;2 、安装 poetry&lt;/h3&gt;
&lt;p&gt;如果你了解过 Python，一定知道 pip，但 pip 在包的依赖管理和版本冲突管理上做的不是很好，而 poetry 就是为了解决这两个问题而生。&lt;/p&gt;
&lt;p&gt;我在本机是使用 pipx 来安装的 poetry ，先使用 homebrew 安装 pipx：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install pipx
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pipx ensurepath
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501061750427.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;接着使用 pipx 安装 poetry，命令如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pipx 安装 poetry 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501061805738.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;安装完成后，可以通过以下命令验证 poetry 是否安装成功：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;poetry --version
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;出现下图所示，说明安装成功：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501061805772.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="3-使用-poetry"&gt;3 、使用 poetry&lt;/h3&gt;
&lt;p&gt;可以使用 poetry 创建一个新的项目:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;poetry new poetry-project
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;也可以在现有项目的目录中初始化 poetry：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd exist-project
poetry init
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用 poetry 创建的项目目录如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2025/202501061805758.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在 pyproject.toml 文件中进行包版本的管理。这时如果我要给项目添加相关的依赖包，有两种方式：&lt;/p&gt;
&lt;p&gt;直接使用 poetry 命令:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;poetry add six:1.16.0 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用命令安装完成后，pyproject.toml 文件中会自动添加 six = &amp;ldquo;1.16.0&amp;rdquo; ，如下图：&lt;/p&gt;</description></item><item><title>RocketMQ 和 RabbitMQ 的比较以及 RocketMQ 的使用</title><link>https://fwhyy.com/2025/01/comparison-between-rocketmq-and-rabbitmq-and-the-use-of-rocketmq/</link><pubDate>Thu, 02 Jan 2025 18:28:00 +0800</pubDate><guid>https://fwhyy.com/2025/01/comparison-between-rocketmq-and-rabbitmq-and-the-use-of-rocketmq/</guid><description>&lt;p&gt;消息队列在项目中会经常用到，目前我们使用的是 RabbitMQ，但在 Java 技术栈下，RocketMQ 使用的比较多。下面比较下 RabbitMQ 和 RocketMQ。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="rabbitmq-和-rocketmq-对比"&gt;RabbitMQ 和 RocketMQ 对比&lt;/h2&gt;
&lt;h3 id="1设计理念和架构"&gt;1、设计理念和架构&lt;/h3&gt;
&lt;p&gt;RabbitMQ：&lt;/p&gt;
&lt;p&gt;基于 AMQP（Advanced Message Queuing Protocol）协议，使用 Erlang 语言开发。Erlang 的天生高并发和容错性使得 RabbitMQ 在稳定性方面表现出色。RabbitMQ 的核心概念是 Exchange（交换机）和 Queue（队列），消息通过 Exchange 路由到 Queue，再由消费者消费。这种模型非常灵活，支持多种消息路由模式。&lt;/p&gt;
&lt;p&gt;RocketMQ：&lt;/p&gt;
&lt;p&gt;源于阿里巴巴，后捐献给 Apache 基金会，所以现在的官网是：https://rocketmq.apache.org/ 。使用 Java 语言开发，更贴近 Java 技术栈。RocketMQ 的核心概念是 Topic（主题），消息发送到 Topic，消费者订阅 Topic 进行消费。RocketMQ 的设计目标是高吞吐量、低延迟和高可靠性，适合大规模分布式系统。&lt;/p&gt;
&lt;p&gt;RocketMQ 的设计理念更偏向于解决互联网场景下的具体问题，如海量消息处理、消息顺序性等。&lt;/p&gt;
&lt;h3 id="2性能"&gt;2、性能&lt;/h3&gt;
&lt;p&gt;吞吐量：RocketMQ 在吞吐量方面通常优于 RabbitMQ，尤其是在高并发场景下。RocketMQ 的设计更偏向于高吞吐的消息传递，而 RabbitMQ 更注重消息的可靠性和灵活性。&lt;/p&gt;
&lt;p&gt;延迟：两者在延迟方面都表现不错，但在极端高负载情况下，RocketMQ 的延迟可能更低一些。&lt;/p&gt;
&lt;p&gt;不过在 ToB 的一些业务场景，RabbitMQ 是可以胜任的。&lt;/p&gt;
&lt;h3 id="3特性"&gt;3、特性&lt;/h3&gt;
&lt;p&gt;消息路由：RabbitMQ 支持多种 Exchange 类型（Direct、Topic、Fanout、Headers），提供更丰富的消息路由策略。RocketMQ 主要使用 Topic 进行消息路由，相对简单。&lt;/p&gt;
&lt;p&gt;消息过滤：RocketMQ 支持基于 Tag 和 SQL 的消息过滤，方便消费者按需订阅消息。RabbitMQ 的消息过滤相对较弱。&lt;/p&gt;
&lt;p&gt;事务消息：RocketMQ 提供了分布式事务消息的支持，可以保证消息生产和本地事务的原子性。RabbitMQ 没有直接提供事务消息的支持，需要通过其他方式实现。&lt;/p&gt;
&lt;p&gt;延迟消息：RocketMQ 支持延迟消息，可以实现定时任务等功能。RabbitMQ 通过插件可以实现类似功能。&lt;/p&gt;
&lt;p&gt;监控和管理：RocketMQ 和 RabbitMQ 都提供了丰富的监控指标和管理工具，相比之下我更喜欢 RocketMQ 的管理工具。&lt;/p&gt;
&lt;h3 id="4创新点"&gt;4、创新点&lt;/h3&gt;
&lt;p&gt;RabbitMQ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件系统设计灵活，易于扩展&lt;/li&gt;
&lt;li&gt;虚拟主机（vhost）概念，实现多租户隔离&lt;/li&gt;
&lt;li&gt;内存和磁盘节点的混合部署方案&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;RocketMQ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;基于文件的消息存储系统，避免了缓存未刷盘导致的消息丢失&lt;/li&gt;
&lt;li&gt;Pull 模式和长轮询机制的结合，平衡了实时性和性能&lt;/li&gt;
&lt;li&gt;消息过滤支持在 Broker 端完成，减少网络传输开销&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5exchange-和-topic-的区别"&gt;5、Exchange 和 Topic 的区别&lt;/h3&gt;
&lt;p&gt;RabbitMQ的 Exchange 和 RocketMQ 的 Topic 在消息路由机制上有以下主要区别：&lt;/p&gt;</description></item><item><title>OpenAI 连续 12 天 AI 发布会汇总</title><link>https://fwhyy.com/2024/12/summary-of-openais-12-consecutive-days-of-ai-press-conferences/</link><pubDate>Sat, 21 Dec 2024 16:25:00 +0800</pubDate><guid>https://fwhyy.com/2024/12/summary-of-openais-12-consecutive-days-of-ai-press-conferences/</guid><description>&lt;p&gt;随着凌晨第十二天的 o3 模型的发布，OpenAI 连续 12 天的 AI 发布会结束了。下面回顾下这十二天都发布了些啥。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="第一天"&gt;第一天&lt;/h2&gt;
&lt;p&gt;在 OpenAI 的第一天发布会上，主要发布了两个重要的更新：o1 的完整版本和 ChatGPT Pro 订阅服务。&lt;/p&gt;
&lt;p&gt;1、o 1 完整版本：这个版本在多个方面实现了突破性进展，包括更智能、更快的响应速度、多模态输入能力（能够处理图像和文本信息），以及在指令遵循方面的表现更好。o1 在重大错误率上降低了约 34%，思考速度提升了约 50%。o1 模型现在能够同时处理图像和文本进行推理，这为视觉相关的应用开辟了广阔的应用前景。&lt;/p&gt;
&lt;p&gt;2、ChatGPT Pro：这是一个高级订阅服务，每月收费 200 美元，提供了无限访问 OpenAI 最先进的模型 o1，以及 o1-mini、GPT-4 o 和 Advanced Voice 等功能。特别引人注目的是 o1 Pro 模式，这是 o1 的一个高阶版本，利用更强大的计算资源，深度分析问题并为最复杂的问题提供更优解答。&lt;/p&gt;
&lt;p&gt;用户价值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提升效率和准确性：o1 的升级版为用户提供了更快、更准确的服务，尤其在复杂问题的处理上，减少了错误率，提高了思考速度。&lt;/li&gt;
&lt;li&gt;多模态能力：多模态输入的支持使得 o1 能够处理更多样化的任务，如图像分析和图文结合的创作等。&lt;/li&gt;
&lt;li&gt;专业级服务：ChatGPT Pro 为高需求用户提供了更强大的功能和更稳定的服务，适合在数学、编程等领域需要极致性能的用户。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;o1 完整版本需要 Plus 用户才能体验，ChatGPT Pro 对个人来说太贵了，况且那些高级推理能力一般人也用不上。&lt;/p&gt;
&lt;h2 id="第二天"&gt;第二天&lt;/h2&gt;
&lt;p&gt;第二天的发布会重点介绍了「强化微调（Reinforcement Fine-Tuning）」技术。&lt;/p&gt;
&lt;p&gt;强化微调技术：这项技术允许用户在极少的训练数据基础上，创建特定领域的专家模型。通过强化学习的理念，这一技术使得模型具备更自主的推理能力，并在各项指标上显著提升。强化微调能力可以让小体量模型「从高中水平跃升至专家水平」，预计将在 2025 年春季开放给用户。&lt;/p&gt;
&lt;p&gt;用户价值：&lt;/p&gt;
&lt;p&gt;定制化 AI 应用：强化微调技术使得企业或科研单位能够根据特定需求，快速训练出专家级别的 AI 模型，提升了定制化 AI 应用的可能性和效率。&lt;/p&gt;
&lt;h2 id="第三天"&gt;第三天&lt;/h2&gt;
&lt;p&gt;第三天，OpenAI 发布了备受期待的 Sora 视频产品。&lt;/p&gt;
&lt;p&gt;Sora 视频产品：Sora 支持生成 1080p 高清视频，并提供多种视频编辑智能功能，如替换元素、最佳帧隔离等，减少了视频创作的门槛。Sora 提供了文本转视频、图像转视频和视频转视频功能，并配备了精美的分镜工具，让用户精准指导视频创作。&lt;/p&gt;
&lt;p&gt;用户价值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;视频创作民主化：Sora 的发布极大地降低了视频创作的技术门槛，使得普通用户也能创作出专业级别的视频内容。&lt;/li&gt;
&lt;li&gt;创意表达工具：Sora 为创意人员提供了强大的工具，帮助他们更好地表达自己的想法和创意，推动了内容创作的创新。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最近看了檀东东的一个海螺和 Sora 对比评测视频，感觉 Sora 有点拉胯，有点对不起那么贵的价格。&lt;/p&gt;
&lt;h2 id="第四天"&gt;第四天&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202412210859501.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;第四天，OpenAI 为 Canvas 推出了三项重大更新，这些更新使得 Canvas 更加强大，为用户提供了全新的使用体验。&lt;/p&gt;
&lt;p&gt;1、Canvas 全面开放与主模型集成：OpenAI 将 Canvas 面向所有用户开放，并直接将其整合到主模型中，免去了额外的加载步骤。用户可以直接从首页的输入框跳转到 Canvas，进行文档编辑和创作。&lt;/p&gt;
&lt;p&gt;2、Python 代码实时执行能力：Canvas 集成了一个 Web Assembly 的 Python 模拟器，允许用户直接在 Canvas 中运行 Python 代码，并实时查看文本或图形输出。这个环境不仅能够实时运行与反馈代码，还能智能报错提醒和提供代码建议，极大地提高了编程效率。&lt;/p&gt;</description></item><item><title>信创浪潮下的.NET困境与技术转型思考</title><link>https://fwhyy.com/2024/12/under-the-wave-of-innovation-and-entrepreneurship-net-dilemma-and-technological-transformation-thinking/</link><pubDate>Mon, 16 Dec 2024 16:23:00 +0800</pubDate><guid>https://fwhyy.com/2024/12/under-the-wave-of-innovation-and-entrepreneurship-net-dilemma-and-technological-transformation-thinking/</guid><description>&lt;p&gt;开始之前我想先介绍下什么是.NET、什么是信创？&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="什么是-net"&gt;什么是 .NET？&lt;/h2&gt;
&lt;p&gt;我们现在说 .NET 通常指 .NET Core 之后的版本。.NET Core 是跨平台的开源框架，不仅可以运行在 Windows，还支持 Linux 和 macOS。在 .NET Core 3.1 之后发布的 .NET 5 又做了大统一，名称中也去掉 Core 了），目前最新的版本为 .NET9 。&lt;/p&gt;
&lt;p&gt;.NET 有以下几个特点：&lt;/p&gt;
&lt;p&gt;1、采用最开放的 MIT/Apache 2 协议开源，具备中立性。&lt;/p&gt;
&lt;p&gt;2、归属中立的第三方组织 .NET 基金会管理，不属于任何商业公司，进一步增强了其独立性和开放性。&lt;/p&gt;
&lt;p&gt;3、完全支持 ARM 32/64 架构，适配国内主流的 ARM 架构芯片，如鲲鹏、飞腾等。&lt;/p&gt;
&lt;h2 id="什么是信创-"&gt;什么是信创 ？&lt;/h2&gt;
&lt;p&gt;信创，即信息技术应用创新产业，其核心目标是实现信息技术领域的自主可控，以保障国家信息安全。国资委 2022 年 79 号文件主要指示如下：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;核心内容&lt;/strong&gt;：要求在 5 年内国企全部完成信创替换。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;实施步骤&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;1、2022 年 11 月底，完成信创改造方案规划并报送国资委；&lt;/p&gt;
&lt;p&gt;2、2023 年 1 月起，每季度报送信息化系统信创改造的最新进度；&lt;/p&gt;
&lt;p&gt;3、2027 年底，全部央国企必须完成信息化系统的信创改造工作。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;替换要求&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;1、全面替换：OA、门户、邮箱、纪检、党群、档案、经营管理。&lt;/p&gt;
&lt;p&gt;2、应替就替：战略决策、ERP、风控管理、CRM 管理系统。&lt;/p&gt;
&lt;p&gt;3、能替就替：生产制造、研发系统。&lt;/p&gt;
&lt;p&gt;为什么要发展信创？&lt;/p&gt;
&lt;p&gt;1、&lt;strong&gt;保障国家信息安全&lt;/strong&gt;：随着信息技术的快速发展，网络安全风险日益增加，发展信创有助于提升国家信息安全水平。&lt;/p&gt;
&lt;p&gt;2、&lt;strong&gt;实现自主可控&lt;/strong&gt;：历史上，中国在信息技术领域长期依赖国外技术，发展信创可以推动国内信息技术产业的发展，减少对外部技术的依赖。&lt;/p&gt;
&lt;p&gt;4、&lt;strong&gt;应对国际竞争&lt;/strong&gt;：在全球信息技术产业竞争加剧的背景下，发展信创产业有助于提升国家的国际竞争力。&lt;/p&gt;
&lt;p&gt;4、&lt;strong&gt;促进数字化转型&lt;/strong&gt;：信创产业的发展有利于国内企业更安全地完成数字化转型。&lt;/p&gt;
&lt;h2 id="net-支持信创吗"&gt;.NET 支持信创吗？&lt;/h2&gt;
&lt;p&gt;毫无疑问，从技术上来说，.NET 是支持信创的。&lt;/p&gt;
&lt;p&gt;但是，这没有用，客户不听解释。&lt;/p&gt;
&lt;p&gt;随着 27 年的临近，企业的信创进程在加快。最近见了不少客户，不管是否了解技术，都谈 .NET 色变，有的更是将 .NET 纳入了黑名单。有客户原话是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我也知道 .NET 是支持信创的，但集团下了文，不让用，我们也没有办法。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;幸好我们产品比较开放，很早就是多技术栈并行的。不过也很无奈，需要全面进行技术栈迁移了。&lt;/p&gt;
&lt;h2 id="转型"&gt;转型&lt;/h2&gt;
&lt;p&gt;说到无奈，是因为要做出改变，就要离开舒适区了。但仔细想想，舒适区待久了很难让人进步。这次的转型也许会成为再上一层楼的一个契机。转型分为两个层面：技术和业务。&lt;/p&gt;
&lt;h3 id="技术"&gt;技术&lt;/h3&gt;
&lt;p&gt;1、代码块节点使用到的 nodejs、python 还是继续保留。&lt;/p&gt;
&lt;p&gt;2、剩余的 .NET 部分全部转换为 Java。&lt;/p&gt;
&lt;p&gt;3、转换后的 Java 程序需要和原来的 Java 代码一起通盘考虑，架构上需要重新考虑和规划。&lt;/p&gt;
&lt;p&gt;4、合理梳理业务链路、优化缓存的使用，进一步提升性能、稳定性和扩展性。&lt;/p&gt;
&lt;h3 id="业务"&gt;业务&lt;/h3&gt;
&lt;p&gt;我们的产品为低代码类型的产品，目的是能快速高效地为客户落地业务。现在随着 AI 技术的发展，我们产品也需要做出相应的变化。&lt;/p&gt;</description></item><item><title>2024光谷马拉松复盘，风雨中迎来新突破</title><link>https://fwhyy.com/2024/11/2024-optics-valley-marathon-review-new-breakthrough-in-the-wind-and-rain/</link><pubDate>Mon, 25 Nov 2024 16:11:00 +0800</pubDate><guid>https://fwhyy.com/2024/11/2024-optics-valley-marathon-review-new-breakthrough-in-the-wind-and-rain/</guid><description>&lt;p&gt;光谷马拉松是家门口的马拉松，起点在华中科技大学的正门口，我每天上下班都会经过。很幸运 2024 年到光谷马拉松中签了，这也是 2017 年武汉马拉松之后第二次中签武汉本地的马拉松。比赛日期是 11 月 17 日上午 8 点。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;在光谷马拉松之前的一场比赛是 3 月 31 日的石家庄马拉松，当时参加了 PB计划的冬训，大幅 PB，跑了 335 的成绩，非常满意。详细可以阅读：《复盘石家庄全马（PB 80 分钟）》。&lt;/p&gt;
&lt;p&gt;这次的光谷马拉松提前就关注天气，17 号有大风，还很有可能下雨，也看了很多赛道的探路视频，得知全程马拉松的爬升有 200 多米。本来没抱希望，想着安全完赛就好。但最终还是在下雨刮风的天气下 PB 了近 5 分钟。&lt;/p&gt;
&lt;p&gt;下面就从训练、赛前、赛中来复盘下这次比赛吧。&lt;/p&gt;
&lt;h2 id="训练"&gt;训练&lt;/h2&gt;
&lt;p&gt;石家庄马拉松之后就比较佛系了，虽然跑步一直没有停，但强度课跑得比较少。因为 7 月份要跑崇礼 MTC 越野赛，所以四、五、六月更多的在练习爬升。&lt;/p&gt;
&lt;p&gt;崇礼回来后就是漫长的夏季了，这也是第一次在夏天坚持跑步，无与伦比的体验，出门 5 分钟就全身湿透，包括鞋袜。手里拿着冻成冰块的水，不到五公里就变成温水了。这种天气确实是一种考验，每天都关注着天气，期待着气温的下降。即便如此，七、八月的月跑量也上了 200。&lt;/p&gt;
&lt;p&gt;九、十两个月回归到正常的训练。&lt;/p&gt;
&lt;p&gt;因为有 PB计划的经验，总体训练遵循一个大的原则：&lt;/p&gt;
&lt;p&gt;1、以周为单位，有氧跑为主；一周有一个强度跑，一般在周三；一周有一个长距离，一般安排在周末；&lt;/p&gt;
&lt;p&gt;2、强度课主要来源为 B 站 UP主山雨小月和跑者日历四群的小伙伴提供；&lt;/p&gt;
&lt;p&gt;3、每个月保底 200 公里的跑量；&lt;/p&gt;
&lt;p&gt;4、赛前多跑马配，找到比赛的配速感觉。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202411250758162.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="赛前准备"&gt;赛前准备&lt;/h2&gt;
&lt;p&gt;赛前准备有：装备、补给、饮食、天气&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202411250758117.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="装备"&gt;装备&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;背心：和石家庄马拉松一样，内道的风洞背心&lt;/li&gt;
&lt;li&gt;裤子：朋友送的一条 2XU 的压缩裤&lt;/li&gt;
&lt;li&gt;鞋子：上半年托朋友买了一双 160x5.0 和 160x5.0 Pro ，两双鞋都磨合了将近 100 公里，最终还是选择了 160x5.0 ，160x5.0Pro 跑过一次 30 公里，小腿肌肉非常酸，应该是力量和速度都达不到，现在还驾驭不了。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="补给"&gt;补给&lt;/h3&gt;
&lt;p&gt;1、一瓶赛速饮。&lt;/p&gt;
&lt;p&gt;2、一支参赛包里的康比特能量胶和 5 只 sis 能量胶。&lt;/p&gt;
&lt;p&gt;3、8 颗盐丸。&lt;/p&gt;
&lt;h3 id="饮食"&gt;饮食&lt;/h3&gt;
&lt;p&gt;这次的光谷马拉松并没有那种要去拼死一战的感觉，是跑成绩冲击 PB 还是享受赛道都是可以的。饮食没有怎么特别的控制，只是在临近比赛的几天碳水稍微吃的多了点。&lt;/p&gt;
&lt;h3 id="天气"&gt;天气&lt;/h3&gt;
&lt;p&gt;一直都在关注着 11 月 17 号的天气，每天看到的都不一样。直到临近比赛看到 17 号有雨、还有 5 级大风。&lt;/p&gt;
&lt;p&gt;心态也就释然了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202411250758327.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="比赛过程"&gt;比赛过程&lt;/h2&gt;
&lt;p&gt;家离起点不算太远，也就没有起的很早，6 点起床，排空、吃了一碗泡面，换上装备，老婆开车送我到起点附近。一切都非常顺利，只是封路导致老婆回家绕了很大一圈。&lt;/p&gt;
&lt;p&gt;光谷马拉松是 8 点起跑，我下车走了几百米到达起点时刚好 7 点，过安检时因为赛速饮是液体，不能带进去，就直接喝掉了，比预计的提前了半个小时。&lt;/p&gt;</description></item><item><title>从程序员到架构师，需要做些什么？</title><link>https://fwhyy.com/2024/11/from-programmer-to-architect/</link><pubDate>Thu, 14 Nov 2024 22:06:00 +0800</pubDate><guid>https://fwhyy.com/2024/11/from-programmer-to-architect/</guid><description>&lt;p&gt;最近又面试了不少人，在谈及未来职业规划时，他们大多表示希望走技术路线，并期望未来能成为架构师。在软件开发领域，架构师是许多程序员梦寐以求的职位。它代表着技术能力的巅峰，也意味着更大的责任和挑战。&lt;/p&gt;
&lt;p&gt;然而，从一名普通程序员成长为优秀的架构师，绝非一蹴而就。这是一个需要持续学习、实践和思考的漫长过程。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;本文想以架构师的职责、误区和程序员怎么做转变，谈谈我的看法。&lt;/p&gt;
&lt;h2 id="架构师的职责"&gt;架构师的职责&lt;/h2&gt;
&lt;p&gt;在不同规模的公司中，架构师的职责存在差异。尽管一些小公司可能没有设立专门的架构师岗位，但架构相关的工作仍由技术经理或高级程序员等人员兼顾执行。&lt;/p&gt;
&lt;p&gt;架构师负责系统的整体设计和技术决策，确保系统在满足业务需求的同时具备高性能、高可用性、高扩展性，也就是俗称的「三高」。架构师需要关注系统的功能性需求，但更重要的是非功能性需求。&lt;/p&gt;
&lt;p&gt;架构师需要负责评估和选型适合项目的技术栈、开发工具、基础设施，进行技术调研，分析不同技术方案的优缺点，做出合理的技术决策，选择合适的设计模式和架构模式，以确保系统能够应对复杂的业务场景。&lt;/p&gt;
&lt;p&gt;架构师需要制定并推广开发规范和编码标准，确保代码质量的一致性。确立系统设计和代码实现的最佳实践，如代码风格、命名规范、模块划分等，确保团队在项目中遵循相关标准和规范，降低代码复杂度，提高系统的可维护性。&lt;/p&gt;
&lt;p&gt;另外，架构师还需要进行技术风险的评估和控制、团队内技术难点的攻克、团队内部的代码评审、培养团队的技术能力、组织知识分享和培训，持续关注技术趋势和行业防战，不断学习和研究新的技术等等。&lt;/p&gt;
&lt;h2 id="对架构师的一些误区"&gt;对架构师的一些误区&lt;/h2&gt;
&lt;p&gt;1、从零开始设计一个系统&lt;/p&gt;
&lt;p&gt;从零开始设计一个系统，还能全程参与，这是可遇不可求的机会。更多的情况是公司都有现成的架构体系。所以以架构师身份入职一个新公司，不太可能一开始就给你一个全新系统进行架构设计，更多的是做一些辅助性的工作。但只有做好每一件小事，当机会来了的时候，才会轮的上你。&lt;/p&gt;
&lt;p&gt;2、只跟电脑打交道&lt;/p&gt;
&lt;p&gt;估计有些程序员想成为架构师，或许是认为架构师的工作比较单纯，只用跟电脑打交道。但其实架构师作为技术和业务的桥梁，需要与产品经理、业务团队、开发团队和运维团队进行沟通。&lt;/p&gt;
&lt;p&gt;沟通能力也是架构师一个非常重要的技能。&lt;/p&gt;
&lt;p&gt;3、技术全能&lt;/p&gt;
&lt;p&gt;很多人认为架构师是技术全能者，必须精通所有技术栈和工具。然而，架构师并非精通每一项技术细节，而是具备足够的广度来理解系统的整体架构和技术选型，能够做出权衡和取舍。架构师需要深入理解核心技术，并且知道在什么场景下应用合适的技术，而不是精通每一个细节。&lt;/p&gt;
&lt;p&gt;4、只专注技术，不管业务&lt;/p&gt;
&lt;p&gt;认为架构师只需要关注技术而不用理解业务。事实上，架构师不仅要关注技术，还要深入理解业务需求和业务流程，因为只有这样，才能设计出真正适配业务发展的系统架构。毕竟技术是为业务服务的，缺乏业务理解的架构往往难以支持公司长期战略。&lt;/p&gt;
&lt;h2 id="什么是架构"&gt;什么是架构？&lt;/h2&gt;
&lt;p&gt;在说程序员到架构师转变之前，先说说什么是架构。&lt;/p&gt;
&lt;h3 id="架构的本质"&gt;架构的本质&lt;/h3&gt;
&lt;p&gt;架构的本质在于为复杂系统提供一种结构化的设计方法，通过明确系统的核心组件、它们之间的关系以及交互方式，来确保系统能够满足功能需求、性能要求和可维护性标准。&lt;/p&gt;
&lt;p&gt;架构的本质是抽象和简化，它将复杂的系统分解为可管理的部分，使得开发、维护和扩展变得更加可行和高效。同时，架构还承载着系统的愿景和战略方向，确保技术决策与业务目标保持一致。&lt;/p&gt;
&lt;h3 id="架构的分类"&gt;架构的分类&lt;/h3&gt;
&lt;p&gt;按照不同的角度，架构可以有很多分类，但一般来说，主要分为&lt;strong&gt;业务架构&lt;/strong&gt;、&lt;strong&gt;应用架构&lt;/strong&gt;和&lt;strong&gt;技术架构&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;业务架构描述了组织如何运作以实现其战略目标。包括业务功能、业务流程、组织结构、业务能力等。就是企业要发展，需要哪些业务能力来进行支撑。需要梳理核心业务的处理过程，定义各个业务模块的相互关系。比如：一个零售企业的业务架构可能包括：商品采购、库存管理、在线销售、客户支持等核心功能。&lt;/p&gt;
&lt;p&gt;应用架构描述了企业的系统和应用如何支持业务需求，定义了应用的组织方式、交互方式以及应用与数据之间的关系。首先要确定需要哪些应用系统来支持业务，这些应用之间怎么做集成和交互。&lt;/p&gt;
&lt;p&gt;技术架构架构描述了支撑应用系统的技术和基础设施，关注硬件、网络、数据库、编程语言、中间件等技术选型和部署。比如：使用什么技术实现应用？部署在什么环境？如何保证高并发、高可用性？如何确保数据的安全性等。&lt;/p&gt;
&lt;h2 id="从程序员到架构师的成长阶段"&gt;从程序员到架构师的成长阶段&lt;/h2&gt;
&lt;p&gt;从程序员到架构师的成长可以大致分为以下几个阶段：&lt;/p&gt;
&lt;p&gt;1、初级程序员：这是最基础的技能积累阶段，主要学习编程语言、工具使用及完成基本任务。&lt;/p&gt;
&lt;p&gt;2、中级程序员：在这个阶段，能够独立完成开发任务，包括需求分析、简单的方案设计。&lt;/p&gt;
&lt;p&gt;3、高级程序员：开始指导其他工程师，并关注整体技术体系的建设，形成技术深度和广度。&lt;/p&gt;
&lt;p&gt;4、架构师：能够独立完成系统的架构设计，考虑技术选型、系统的可扩展性与稳定性、关注不同模块间结构合理性的问题、关注技术架构的长期正确性。&lt;/p&gt;
&lt;p&gt;在小公司可能不会严格按照级别去分，但我们还是需要沿着这个路径去学习和成长。&lt;/p&gt;
&lt;h2 id="架构师需要具备的能力"&gt;架构师需要具备的能力&lt;/h2&gt;
&lt;p&gt;首先一名优秀的架构师一定是一个出色的程序员，能写的一手好的代码。&lt;/p&gt;
&lt;p&gt;在此基础上，架构师要有技术的广度和深度。广度尤为重要，程序员在熟悉的领域会钻研的很深，但没有广度，在一些跨系统的沟通场景下很难插上话，甚至连别人说的都听不懂。&lt;/p&gt;
&lt;p&gt;能落地的架构才是好架构，所以架构师还需要具备良好的沟通能力，首先是能倾听各种不同的意见和建议，最后确保各方对架构达成共识，愿意采取一致的行动。&lt;/p&gt;
&lt;p&gt;资源、时间永远都是紧张的，架构师还需要有良好的平衡和取舍能力，可以确保架构在现有资源约束下是最合理的，优先做最重要的事情，毕竟架构是不断进行迭代，慢慢进化的。&lt;/p&gt;
&lt;p&gt;要成为一名优秀的架构师，需要具备以下几个关键能力：&lt;/p&gt;
&lt;p&gt;1、技术深度与广度：架构师需要有扎实的技术功底和广泛的技术视野。这包括编程语言、框架、工具、系统设计、性能优化、安全等方面的知识，掌握技术细节是基础，尤其是在不同场景下如何取舍和优化。&lt;/p&gt;
&lt;p&gt;2、业务理解能力：架构师不仅要懂技术，还要深入理解业务需求。只有充分理解业务，才能设计出真正符合需求的系统架构。&lt;/p&gt;
&lt;p&gt;3、系统思维：架构师需要具备抽象思维、分治思维、复用思维和迭代思维。这些思维方式帮助架构师设计出灵活、可扩展的系统，减少后期维护的复杂度。&lt;/p&gt;
&lt;p&gt;4、沟通能力：架构师需要与产品经理、开发人员、测试人员等多个角色沟通。除了架构设计本身，还需要通过文档和会议将设计理念传达给团队，让每个人都理解和使用好架构。&lt;/p&gt;
&lt;h2 id="如何培养架构师能力"&gt;如何培养架构师能力？&lt;/h2&gt;
&lt;p&gt;1、积累经验：参与不同类型和规模的项目，尤其是复杂系统的设计和开发经验，对成长为架构师至关重要。在程序员阶段需要多进行换位思考，如果是自己来设计会怎么进行，和实际落地的进行比较，分析优缺点。&lt;/p&gt;
&lt;p&gt;2、拓宽视野：学习各种技术和架构模式，了解它们的优缺点和适用场景。参与开源项目、阅读优秀的开源代码、参加技术交流活动，都是很好的方式。&lt;/p&gt;
&lt;p&gt;3、深度思考：不断反思和总结，将经验转化为自己的知识体系，思考每个技术选择背后的原因及可能带来的影响。&lt;/p&gt;
&lt;p&gt;4、保持编码实践：即使成为架构师，也要保持一定的编码实践。这有助于理解开发中的实际问题，验证架构设计的可行性。好的架构师一定是从一线程序员成长起来的，保持与代码的接触，才能设计出切实可行的架构。&lt;/p&gt;
&lt;p&gt;5、关注业务发展：深入理解行业和公司业务，预测未来的发展趋势，帮助架构设计更具前瞻性。比如：你的公司如果是做 ToB 业务，又不分行业，那就需要了解多种行业的业务、用户使用习惯，这些都和架构设计息息相关。&lt;/p&gt;
&lt;p&gt;6、培养领导力：架构师不仅仅只是在电脑上画画架构图，还需要带领团队将设计落地，因此培养领导力和团队管理能力也是重要的。&lt;/p&gt;
&lt;h2 id="结语"&gt;结语&lt;/h2&gt;
&lt;p&gt;从程序员成长为架构师是一个充满挑战和机遇的过程，需要持续学习、深度思考和实践积累。在不断适应新技术与新趋势的同时，程序员需要通过实际项目理解架构设计的原则、掌握架构设计的相关知识点。&lt;/p&gt;
&lt;p&gt;只有先具备了扎实的架构设计能力，程序员才有可能在未来抓住机遇，成功转型为架构师。&lt;/p&gt;</description></item><item><title>AI工具推荐-辅助编程篇（202410）</title><link>https://fwhyy.com/2024/10/recommended-ai-tools-auxiliary-programming-202410/</link><pubDate>Wed, 30 Oct 2024 18:54:00 +0800</pubDate><guid>https://fwhyy.com/2024/10/recommended-ai-tools-auxiliary-programming-202410/</guid><description>&lt;p&gt;AI 的发展速度太快了，GPT 3.5 发布到现在也才不到两年的时间，现在的能力跟当时相比，已经不可同日而语。而就在前几天，升级版的 Claude 3.5 Sonnet 模型已经可以操控用户电脑了，还有正在内测的智谱 AI 的 AutoGLM 可以在移动端进行手机的操控。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;作为程序员，非常有必要学习如何使用 AI 工具来提升效率，给自己多争取一点“摸鱼”的时间。目前了解到的辅助编程的工具有三类：&lt;/p&gt;
&lt;p&gt;1、以插件的形式来使用，比如：MarsCode、Comate、通义灵码。&lt;/p&gt;
&lt;p&gt;2、AI 编辑器，比如：Cursor 。&lt;/p&gt;
&lt;p&gt;3、代码生成发布一条龙，比如：Bolt.new&lt;/p&gt;
&lt;h2 id="编程-ide-插件中的-ai-助手"&gt;编程 IDE 插件中的 AI 助手&lt;/h2&gt;
&lt;p&gt;MarsCode、Comate、通义灵码这三个工具都是以插件的形式安装在 IDE 中使用，比如 VSCode 、JetBrains 系列的开发工具等，下面是这三个工具的简单介绍：&lt;/p&gt;
&lt;h3 id="marscode"&gt;MarsCode&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;出自&lt;/strong&gt;：豆包，隶属于北京引力弹弓科技有限公司。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：提供智能代码补全、单测生成、代码解释、错误修复、生成注释、AI 问答等功能，支持超过 100 种编程语言，兼容 VSCode 和 JetBrains 编辑器,没有 Visual Studio 。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：适用于各种编程任务，包括代码编写、单元测试生成、代码解释和错误修复等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="comate"&gt;Comate&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;出自&lt;/strong&gt;：百度，基于文心大模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：提供智能代码生成、单测生成、注释生成、代码优化、代码解释、研发智能问答等功能，支持 100 多种编程语言和主流 IDE。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：适用于研发全流程，包括代码编写、优化、注释生成、单测生成和研发问答等。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="通义灵码"&gt;通义灵码&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;出自&lt;/strong&gt;：阿里云，基于通义大模型。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;特点&lt;/strong&gt;：提供代码智能生成、单元测试生成、代码优化、代码解释、研发智能问答等功能，支持200多种编程语言和主流 IDE。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;适用场景&lt;/strong&gt;：适用于代码编写、单元测试生成、代码优化、代码解释和研发问答等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这三个工具的功能大同小异，但也有各自的特点：&lt;/p&gt;
&lt;p&gt;1、在函数的上方有各种 AI 工具按钮，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410291708760.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以看出，代码解释、函数注释、生成单测是三个工具都有，MarsCode 没有优化建议，而 Comate 多了一个行间注释。&lt;/p&gt;
&lt;p&gt;2、都有一个对话框窗口，使用斜杠唤起相关的指令，我对比了下， Comate 的最丰富。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410291707866.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、在进行代码解释的时候，通义灵码还贴心生成了流程图，对于复杂的业务逻辑，有图的帮助可以更容易理解。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410291707945.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;综合下来，我更喜欢的是 Comate，功能丰富、UI 漂亮、中文支持友好。不过另外两个也会同时安装，有些时候，如果一个工具给出的答案不是很满意，可以分别都试试，对比着看，就能得到比较满意的答案。&lt;/p&gt;
&lt;h2 id="通过对话生成代码文件cursor"&gt;通过对话生成代码文件：Cursor&lt;/h2&gt;
&lt;p&gt;Cursor 是在 VSCode 的基础上开发出来的一款 AI 开发工具。除了有上面提到的插件类型编程助手中的对话能力，还有三点比较惊艳到我：&lt;/p&gt;
&lt;p&gt;1、有多种 AI 模型可以使用，但效果最好的还是 Claude 3.5 Sonnet。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410291708944.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、有 Chat 和 Composer 两种模式，在 Composer 模式中，通过自然语言描述需求，Cursor 可以创建相关的代码文件，后续的各种修改你只需要在对话框中打字就好，代码全是自动修改。如果在编辑器中没有发现 Composer 窗口，可以可以先用 cmd + i 打开小弹窗，然后固定在右边。&lt;/p&gt;
&lt;p&gt;3、在对话框中粘贴一个 UI 原型图，指定使用什么前端技术，Cursor 可以直接做出差不多效果的 UI 界面，还原度很高。&lt;/p&gt;</description></item><item><title>代码写的好，就可以不写技术文档了吗？</title><link>https://fwhyy.com/2024/10/is-it-okay-not-to-write-technical-documentation-if-the-code-is-well-written/</link><pubDate>Wed, 23 Oct 2024 16:08:00 +0800</pubDate><guid>https://fwhyy.com/2024/10/is-it-okay-not-to-write-technical-documentation-if-the-code-is-well-written/</guid><description>&lt;p&gt;在软件开发中，代码与文档的关系是一个经常被讨论的话题，最近在一个技术群里也针对这个话题展开了讨论，大家各抒己见，以下是群中的一些主要观点，希望对你有所启发。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;h2 id="观点一代码无法替代文档文档是必需的"&gt;观点一、代码无法替代文档，文档是必需的&lt;/h2&gt;
&lt;p&gt;在项目的初期阶段，文档对于需求分析和设计至关重要，它帮助团队理解整体目标和约束。而在实现和维护阶段，代码是核心内容，但文档依然不可或缺，用来补充背景信息、重点逻辑等，确保团队的有效协作。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;团队成员水平参差不齐&lt;/strong&gt;：在大型团队中，成员的编码水平和理解能力不同，仅靠代码无法确保所有人都理解项目的全部细节。文档可以为经验不足的成员提供必要的指导，帮助他们更快地融入项目。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码难以表达设计思路和决策过程&lt;/strong&gt;：代码是最终实现的结果，但难以完整传达开发者的思考过程、约束条件，以及为何选择某种实现方式。这些背景信息对于后续的维护和迭代非常重要。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识传承的需要&lt;/strong&gt;：代码会随着时间和技术的演进而过时（指的是有些历史代码架构、实现可能都不是最优的，但一直在稳定运行，没就没有去进行重构），但文档能够记录项目的核心理念和设计思路，帮助新成员快速上手，减少摸索的时间成本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;写好代码的成本高于写文档&lt;/strong&gt;：高质量代码的编写需要丰富的经验和时间，而编写简洁而清晰的文档相对容易，可以迅速传达重要的信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档面向多种读者&lt;/strong&gt;：代码主要面向开发者，而文档可以针对不同的受众，如非技术人员和管理层，帮助他们理解项目的整体状况和业务逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避免误解和知识诅咒&lt;/strong&gt;：开发者通常认为自己的代码已经足够清晰，但对其他人来说可能并非如此。文档可以填补理解上的差距，降低沟通成本。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="观点二代码和文档是互补的应该同时重视"&gt;观点二、代码和文档是互补的，应该同时重视&lt;/h2&gt;
&lt;p&gt;在小型团队中，沟通相对简单，文档的需求可能较少，更多依赖于自解释代码和口头沟通。而在大型团队中，成员众多且角色多样，文档的重要性显著提高，有助于团队成员理解项目背景、业务逻辑和设计决策，降低沟通成本。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;自解释代码减少了部分文档需求&lt;/strong&gt;：如果代码命名规范且逻辑清晰，部分重复性的文档可以省略，这符合 DRY（Don&amp;rsquo;t Repeat Yourself）原则。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码无法替代所有文档&lt;/strong&gt;：即便代码写得再好，也无法描述项目的背景、业务逻辑、设计决策等信息，这些内容往往需要在文档中进行详细说明。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;团队协作需要平衡&lt;/strong&gt;：团队应通过讨论来确定文档的必要性，确保每个成员都参与到文档的维护中，促进知识的共享和流动。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;文档需要更新&lt;/strong&gt;：过度或形式化的文档可能流于形式，反而成为负担。因此，需要合理的文档管理和及时更新，以确保其质量和实用性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;代码需要达意：&lt;/strong&gt; 即便有很清晰的文档，开发人员最终还是需要去阅读和修改代码，所以代码本身的质量也非常重要。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="观点三过度依赖代码或文档都会带来问题关键在于平衡"&gt;观点三：过度依赖代码或文档都会带来问题，关键在于平衡&lt;/h2&gt;
&lt;p&gt;在敏捷开发中，找到代码与文档的平衡尤为重要。例如，有一个团队在开发过程中采用了「轻文档化」策略，针对关键模块和复杂业务逻辑编写简要的设计文档，而对于简单的实现则依赖于清晰的代码注释和团队协作。这种方式既保证了开发效率，又确保了文档的实用性和及时性。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;过分强调代码会忽略知识传递&lt;/strong&gt;：没有文档的项目在团队人员变动时可能会面临严重的知识流失问题，从而影响项目的长期维护和发展。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;过度依赖文档可能导致低效&lt;/strong&gt;：如果文档过于冗长或没有及时更新，开发者最终还是不得不查阅代码，这无疑增加了时间成本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;培养文档使用文化&lt;/strong&gt;：如果没有人阅读文档，开发者也就缺乏编写的动力。因此，团队需要培养阅读和利用文档的文化，使文档成为项目不可或缺的一部分。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="观点四澄清对代码即文档的误解"&gt;观点四：澄清对「代码即文档」的误解&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;代码清晰就不需要文档&lt;/strong&gt;：某团队在开发初期认为只要代码写得足够清晰，就不需要额外的文档，导致后期新成员加入时对业务逻辑缺乏理解，不得不花费大量时间追溯代码背后的背景信息。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;敏捷开发不需要文档&lt;/strong&gt;：有些团队误解了敏捷开发的原则，认为敏捷就是不写文档，结果在项目需求变更时，由于缺乏文档记录，变更管理变得困难，最终导致项目进度延误。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;注释等同于文档&lt;/strong&gt;：某项目的开发者认为在代码中添加详细的注释就可以替代文档，但注释通常只针对具体的实现，而无法传达整体的设计思路和决策过程，导致项目在维护过程中，尤其是面对复杂业务逻辑时，出现困难。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;敏捷宣言的误读&lt;/strong&gt;：敏捷开发提倡「可工作的软件胜过面面俱到的文档」，但这并不意味着不写文档，更不代表代码可以完全替代文档。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;「代码即文档」并非全覆盖&lt;/strong&gt;：这一观点强调代码的可读性，但并不意味着代码能够表达所有类型的信息，特别是那些代码无法承载的项目背景和业务逻辑。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;避免走极端&lt;/strong&gt;：认为写好代码就不需要任何文档是一种极端做法，不利于项目的长期发展和维护。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="我的观点"&gt;我的观点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;代码除了让机器执行出结果，还需要人去阅读、修改、维护，所以每个开发人员需要持续提升自己的技能，从变量方法的命名到类之间的结构是清晰的、易读、可维护的。&lt;/li&gt;
&lt;li&gt;如果代码质量很高，变量、方法上面的一些废话注释不是必须的，没有这些，代码反倒看着更简洁，但整个项目的整体架构、核心业务的逻辑、算法等还是需要沉淀到文档中，并且随着代码的迭代演进，文档也需要同步更新。&lt;/li&gt;
&lt;li&gt;我不认为一个代码写的逻辑混乱的人，可以写出很清晰的文档。所以还是要先从代码入手，让每个人都能写出好到代码，再强调特定文档的重要性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;希望对您有所帮助！&lt;/p&gt;</description></item><item><title>AI工具推荐-搜索问答篇（202410）</title><link>https://fwhyy.com/2024/10/ai-tool-recommendation-search-qa-article-202410/</link><pubDate>Wed, 16 Oct 2024 16:55:00 +0800</pubDate><guid>https://fwhyy.com/2024/10/ai-tool-recommendation-search-qa-article-202410/</guid><description>&lt;p&gt;最近一个同事因为项目上的特殊需求，需要制作一个镜像底包。由于要求比较特殊，不容易找到现成的方案，我想到这正是 AI 工具擅长的领域，于是把需求说明随手推荐了一个工具，最终非常顺利地解决了问题。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;现在各类 AI 工具非常多，常用的主要有两类：搜索问答类和辅助编程类。本文将介绍几个搜索问答类的工具。&lt;/p&gt;
&lt;h1 id="kimi"&gt;Kimi&lt;/h1&gt;
&lt;p&gt;因为平时使用 kimi 比较多，先从 kimi 开始，下面是 kimi 对自己的介绍：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一个由 Moonshot AI开发的多才多艺的人工智能助手。我擅长中英文对话，能够阅读和理解各种文档，还能上网搜索信息，帮你找到答案。无论是日常闲聊，还是需要专业信息，都能助你一臂之力。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;除了 Kimi，还有豆包、文心一言、通义千问、智谱清言等都有相似的功能和能力。Kimi 最近推出了探索版，只需要在对话框中输入 / 就可以启用，目前探索版每天可以使用 5 次。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410142048425.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Kimi 的探索版特别适合用于网络上已有的知识，依靠人工去查询总结非常耗时，而探索版就非常好用。比如我搜索：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410142106615.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以看到 Kimi 阅读了 600 多个网页，最后输出的内容也按照我的要求写得非常清楚。不过 Kimi 在推理题方面稍有不足。&lt;/p&gt;
&lt;p&gt;我用下面的推理题在 Kimi 的普通版中进行测试，答案是错误的，但探索版尝试了几次，结果有正确的也有错误的。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;问：某公司被窃，A、B、C、D四人涉嫌被拘留。侦破结果表明，罪犯就是其中的某一个人。A说：“是C偷的。”B说：“我没偷。”C说：“我也没偷。”D说：“如果B没有偷，那么就是我偷的。”现已查明，其中只有一个人说了假话，从上述条件可以确定谁偷的成立？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;同样的推理问题，通义千问也回答错误，文心一言啰嗦了上千字，但结果是正确的。让人惊艳的是豆包和智谱清言，它们知道 A 和 C 说的话是矛盾的：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410142115169.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Kimi 还有一个比较强大的功能是长文生成器。你给出一个关键词或一句话，Kimi 可以写出上万字的内容。比如我直接输入“数据密集型应用系统设计”（这是一部书的名称），Kimi 长文生成器直接对这本书进行了总结。&lt;/p&gt;
&lt;p&gt;除了 Kimi，同类型的还有文心一言、通义千问、豆包、智谱清言等。&lt;/p&gt;
&lt;p&gt;1、通义千问的效率工具包括实时记录、阅读助手、链接速读等功能，特别是链接速读可以支持 RSS，将“小宇宙”的链接直接粘贴进去，重点内容就能总结出来。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410142155600.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、豆包的图片生成功能易用性不错，可以一键擦除、局部重绘和图片扩展。长文写作支持分步骤生成，先生成大纲，然后再根据大纲生成文章。&lt;/p&gt;
&lt;p&gt;3、智谱清言的 AI 画图支持头像绘制、Logo 设计、文章配图等，功能非常实用，还支持视频生成。&lt;/p&gt;
&lt;p&gt;这些工具我平时都是根据需求选择性地使用。有时也会对同一个问题让多个 AI 进行回答，然后对比选择，或者把一个 AI 的结果发给另一个 AI 进行优化和补充。&lt;/p&gt;
&lt;h1 id="notebooklm"&gt;NotebookLM&lt;/h1&gt;
&lt;p&gt;NotebookLM 是 Google 开发的一款基于 AI 的笔记工具，旨在帮助用户在笔记整理、内容生成、信息探索等方面更加高效。它结合了大语言模型的能力和传统笔记的管理方式，通过智能化的交互，帮助用户从信息中提取更有价值的洞见，并进行更有结构的知识管理。&lt;/p&gt;
&lt;p&gt;可以从一些来源来写笔记，NotebookLM 支持多种类型的来源，也可以上传文本或音频文件，基于这些内容来提问，回答的内容可以保存到笔记中。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410151125216.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;下面是我将我的博客链接作为来源添加后，随便问了一个关于最近写的一篇文章的问题，结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410151127041.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;NotebookLM 还能做很多事情，比如给一个 GitHub 项目的链接，让它给出代码的阅读指南：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410151135947.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;NotebookLM 最厉害的是，可以根据内容生成一个播客音频，不过目前只支持英文。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410151137870.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="秘塔-ai-搜索"&gt;秘塔 AI 搜索&lt;/h2&gt;
&lt;p&gt;秘塔 AI 搜索（metaso.cn）于 2024 年初上线，它是一款能够深入理解用户问题的 AI 搜索引擎，没有广告，直达结果。目前免费用户每天可以使用 100 次。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410151611557.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;其实 Kimi 有探索版、豆包和智谱清言也有 AI 搜索功能，但秘塔专门针对 AI 搜索做得更为专业。我试了一下，问了关于“零代码平台的未来发展”的问题，回答非常详尽，还可以从文库、学术等不同角度进行搜索。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410151616844.webp" alt="image.png" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>十一皖南结伴行（2024）</title><link>https://fwhyy.com/2024/10/eleven-anhui-southern-companions-tour-2024/</link><pubDate>Wed, 09 Oct 2024 21:35:00 +0800</pubDate><guid>https://fwhyy.com/2024/10/eleven-anhui-southern-companions-tour-2024/</guid><description>&lt;p&gt;按照惯例，十一会自驾出行，和以往不同的是，这次有小伙伴一起。以前的老同事一家也加入了我们，他们有一个女儿，比我女儿小一岁，这让女儿多了一个玩伴，使整个旅途充满了更多的乐趣。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;放假前，我们在旅行小分队群里讨论了几天，最终定出了一条较为冷门的路线，主要是在皖南转一圈，但避开热门景点，比如皖南 318 等。从 10 月 1 日出发，5 日返回武汉，行程涵盖了武汉、池州、宣城、泾县和安庆等地。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082131621.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图是当时初步制定的计划，其实只要地点和酒店确定了，到达后的时间安排都可以随时调整。&lt;/p&gt;
&lt;h2 id="10-月-1-日武汉-池州"&gt;10 月 1 日（武汉-池州）&lt;/h2&gt;
&lt;p&gt;因为工作上的事情，1 号凌晨 4 点才睡，10 点左右出发前往池州，整体路况还不错，只有几段路稍有行驶缓慢，下午 3 点多到达酒店。稍作休整后，就出发去了平天湖。当天天气阴沉且风大，但这并没有影响大家的心情。小朋友买了泡泡水在湖边玩得非常开心。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082131361.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;下午五六点时，天公作美，天空渐渐放晴，落日的余晖映照在湖面上，呈现出一幅绚丽动人的景象。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082132148.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;第二天一大早，我又独自跑步到了湖边，看到了日出。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082132844.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="10-月-2-日池州-宣城"&gt;10 月 2 日（池州-宣城）&lt;/h2&gt;
&lt;p&gt;早餐过后，我们出发去宣城，到达时已是中午。在法制路排了三四十分钟才买到宁国粑粑，然后一行人来到了魏氏馄饨店，依然排了很久，果然在小红书上曝光多的店就特别火爆。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082132005.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;下午我们去了敬亭山，敬亭山历史悠久，自古以来便是文人雅士吟咏之地。李白曾多次登临此山，留下了脍炙人口的诗篇，如《独坐敬亭山》，使得敬亭山名声大振。&lt;/p&gt;
&lt;p&gt;敬亭山不算高，海拔 300 多米，大部分都是台阶。现在的我有爬山的机会就很兴奋，当作是越野训练了。小孩们更是精力旺盛，相互攀比着，一直走在大人前面。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082133793.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;第二天早上，我又跑步爬了一次敬亭山。8 点之前不收门票，所以尽管很早，还是有不少人早起登山。遗憾的是，我晚了 10 分钟左右，等我到最高处的天际阁时，太阳已经升起了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082134976.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="10-月-3-日宣城-泾县"&gt;10 月 3 日（宣城-泾县）&lt;/h2&gt;
&lt;p&gt;出发前，我们临时调整了行程，先去的是宣纸产业园，第一印象是人少、干净。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082134606.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们参观了宣纸的制作过程，接着女儿还体验了陶艺制作和徽墨描金的手工活动，陶艺制作应该是她旅程中最喜欢的部分。&lt;/p&gt;
&lt;p&gt;下午我们去了桃花潭。桃花潭自古以来便因李白的诗句《赠汪伦》而闻名，诗中描绘了他与好友汪伦在桃花潭边惜别的情景，这也使得桃花潭成为了友谊的象征。&lt;/p&gt;
&lt;p&gt;有趣的是，诗句中写道：“桃花潭水深千尺”，但现实中岸边有一块牌子，上面写着：“水深 2.5 米，注意安全”。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082135369.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;桃花潭岸边有很多鹅卵石，小朋友们玩着打水漂、比赛谁丢的石头更远，直到管理人员说快要涨水了，我们才离开。&lt;/p&gt;
&lt;h2 id="10-月-4-日泾县-安庆"&gt;10 月 4 日（泾县-安庆）&lt;/h2&gt;
&lt;p&gt;今天的目的地是安庆，我们决定先去徽州古城和阳产土楼。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082134788.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;徽州古城位于安徽省黄山市歙县，是中国保存完好的四大古城之一，也是国家历史文化名城。古城始建于秦朝，自唐代以来一直是徽郡、州、府治所在地，形成了独特的城套城风格。徽州古城不仅是徽文化的发祥地，也是徽学的重要中心，被誉为“东南邹鲁、礼仪之邦”。&lt;/p&gt;
&lt;p&gt;古城内有许国石坊、斗山街、县衙、博物馆等景点，这些景点展现了古徽州的历史文化底蕴。同时，古城内也融合了现代商业，使得这座千年古城既有历史的厚重感，又充满了生活的气息。&lt;/p&gt;
&lt;p&gt;从古城出来，导航到阳产土楼时，发现重点附近堵车严重，于是改去了离得更近的许村。许村最有特点的是大观亭。&lt;/p&gt;
&lt;p&gt;大观亭始建于明嘉靖三十年（1557年），清康熙二十二年（1683年）进行了重修，是三层檐亭榭建筑，平面呈八角形，每边长 3.5 米，占地 64.6 平方米。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082134503.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;下午 4 点离开许村，前往安庆，到达安庆已经晚上 7 点，直接去了安庆七街吃了烧烤。没有酒的烧烤总感觉少了点什么。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082133037.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="10-月-5-日安庆-武汉"&gt;10 月 5 日（安庆-武汉）&lt;/h2&gt;
&lt;p&gt;今天是最休闲的一天，在安庆逛一逛、吃一吃，下午就回武汉了。因为时间宽松，早上起来跑了一个长距离。&lt;/p&gt;
&lt;p&gt;不得不说，安庆真是一个跑步的好地方，外层有长江步道，内层有康熙景观带，温度适宜，边跑边拍，非常舒服和惬意。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082133655.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;退房后，我们把车开到人民路附近，然后就是一通暴走，吃了大南门的牛肉包子、喝了卡旺卡奶茶、逛了前言后记新华书店和步行街、参观了英王府。&lt;/p&gt;
&lt;p&gt;印象最深的是新华书店，人少座位多，布置也非常讲究，不管是拍照还是看书学习，都非常不错，反正武汉我是没见到类似的地方。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202410082133745.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;晚上 7 点多，安全回到家中。&lt;/p&gt;
&lt;h2 id="最后"&gt;最后&lt;/h2&gt;
&lt;p&gt;因为去的都是一些小众地方，没有遇到高速大堵车和景区人挤人的情况。这也是我们第一次和朋友一起结伴而行，比想象的要好很多（我这 I 人格起初还担心会遇到各种问题）。最后，非常感谢大雄订的酒店，性价比非常高，所有人都很满意。&lt;/p&gt;</description></item><item><title>让信息自由流动：Follow 带你体验不一样的 RSS 阅读</title><link>https://fwhyy.com/2024/10/let-information-flow-freely-follow-takes-you-to-experience-a-different-rss-reading-experience/</link><pubDate>Tue, 01 Oct 2024 15:53:00 +0800</pubDate><guid>https://fwhyy.com/2024/10/let-information-flow-freely-follow-takes-you-to-experience-a-different-rss-reading-experience/</guid><description>&lt;p&gt;最近搞到一个 Follow 的邀请码，体验了几天，直观感受就是怎么没有早点出来这样的产品。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202409301724196.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;现在每天都会接收到大量的信息，比如我的信息源有：微信公众号、得到、Twitter、YouTube、B 站、小宇宙、newsletter、技术博客、小红书等。&lt;/p&gt;
&lt;p&gt;信息源多了，我们就需要在各类应用之间进行来回切换，还容易被各个应用的推荐算法给控制了，所以我更习惯在一个地方去看所有内容，这就需要 RSS，而 Follow 是 RSS 的升级版，似乎可以订阅一切。&lt;/p&gt;
&lt;h2 id="什么是-rss"&gt;什么是 RSS？&lt;/h2&gt;
&lt;p&gt;RSS，全称为「Really Simple Syndication」，是一种用于共享和聚合网络内容的技术。它采用标准的 XML 格式，使用户能够通过 RSS 阅读器订阅和阅读网站的更新，而无需逐一访问每个网站。这种形式在 20 世纪末期的网络世界尤为风靡，那时的互联网充满了自由和开放的精神，各个网站主动发布 RSS 订阅源，满足了用户对个性化信息聚合的需求。比如我的博客站点也支持 RSS：https://www.fwhyy.com/atom.xml 。&lt;/p&gt;
&lt;h2 id="rss-的起源与发展"&gt;RSS 的起源与发展&lt;/h2&gt;
&lt;p&gt;RSS（最早称为 RDF Site Summary）于 1999 年由 Netscape 作为其门户网站 「My Netscape」的一部分首次推出，基于早期的 RDF 标准。&lt;/p&gt;
&lt;p&gt;同年 7 月，Netscape 发布了 RSS 0.91，称为 「Rich Site Summary」，不再依赖于 RDF，格式更为简化。&lt;/p&gt;
&lt;p&gt;2002 年，Dave Winer 在 UserLand Software 的支持下发布了 RSS 2.0，并将其称为 「Really Simple Syndication」，这一版本因其简单的 XML 结构成为最流行的版本。&lt;/p&gt;
&lt;h2 id="rsshub让一切内容都能被订阅"&gt;RSSHub：让一切内容都能被订阅&lt;/h2&gt;
&lt;p&gt;RSS 的最大挑战之一在于，随着互联网的发展，很多网站逐渐取消了 RSS 功能，以引导用户到网站本身阅读，这样能带来广告收入。但这违背了 RSS 的去中心化和开放性精神。在这样的背景下，RSSHub 应运而生。&lt;/p&gt;
&lt;p&gt;RSSHub 是一个强大且易于使用的开源工具，它的目标是「让万物皆可 RSS」。通过 RSSHub，用户可以生成各种类型的订阅源，即使是那些没有原生 RSS 支持的网站。Follow 就是出自 RSSHub 团队。&lt;/p&gt;
&lt;h2 id="rss-为何走向没落"&gt;RSS 为何走向没落？&lt;/h2&gt;
&lt;p&gt;尽管 RSS 曾经风靡一时，但随着时间的推移，它逐渐被边缘化。究其原因，有下面两个：&lt;/p&gt;
&lt;p&gt;1、社交媒体的兴起改变了人们的阅读习惯。相较于 RSS，社交媒体平台通过算法推荐内容，为用户提供了更直观和即时的内容消费体验。&lt;/p&gt;
&lt;p&gt;2、许多网站出于商业目的，取消了对 RSS 的支持，以便将流量留在自身平台上。&lt;/p&gt;
&lt;h2 id="follow重新定义-rss-阅读"&gt;Follow：重新定义 RSS 阅读&lt;/h2&gt;
&lt;p&gt;Follow 不仅仅是一个 RSS 阅读器，它是一个结合了多种现代技术与社交元素的信息管理平台。由于是由 RSSHub 团队开发的，它具有独特优势，天然就能订阅一切内容。&lt;/p&gt;
&lt;p&gt;Follow 有以下特点：&lt;/p&gt;
&lt;p&gt;1、&lt;strong&gt;多元化内容聚合&lt;/strong&gt;：Follow 支持订阅各种类型的内容，包括文章（博客）、社交媒体（微博、Twitter、即刻）、视频（B 站、YouTube）、播客（小宇宙）等。这使得用户不仅可以阅读博客和新闻，还可以在一个平台上获取社交媒体的动态、观看视频，甚至收听播客，后续应该还会添加邮件（订阅 newsletter）。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202409301724112.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>OpenAI o1 ，我试用一周多所了解到的</title><link>https://fwhyy.com/2024/09/introduction-to-openai-o1/</link><pubDate>Wed, 25 Sep 2024 08:44:38 +0800</pubDate><guid>https://fwhyy.com/2024/09/introduction-to-openai-o1/</guid><description>&lt;p&gt;1、OpenAI 在 9 月 13 日发布了 o1 的预览版。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202409241751659.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、o1 全称叫 OpenAI o1, 没有延续之前 GPT 系列，可见足够强大，当然也有一种说法是 o1 作为一个垂直基础模型为未来 GPT5 赋能。&lt;/p&gt;
&lt;p&gt;3、o1 在推理方面变得更加强大了，特别擅长做数学题和写代码。在国际数学奥林匹克（IMO）资格考试中，GPT-4o 只正确解决了 13% 的问题，o1 的得分为 83%。&lt;/p&gt;</description></item><item><title>忙碌的陷阱</title><link>https://fwhyy.com/2024/09/the-busy-trap/</link><pubDate>Mon, 23 Sep 2024 08:35:29 +0800</pubDate><guid>https://fwhyy.com/2024/09/the-busy-trap/</guid><description>&lt;p&gt;在一个公司中，当所有人都很「忙碌」时，常常被视为高效和生产力的象征，但如果项目还是不能按时上线、客户投诉比较多，满意度差，就需要思考：这种忙碌是真的高效吗？我们是不是陷入了忙碌的陷阱了呢？&lt;/p&gt;</description></item><item><title>什么是 RAG？</title><link>https://fwhyy.com/2024/09/what-is-rag/</link><pubDate>Tue, 10 Sep 2024 08:32:52 +0800</pubDate><guid>https://fwhyy.com/2024/09/what-is-rag/</guid><description>&lt;p&gt;在人工智能技术飞速发展的今天，各种创新和应用层出不穷。其中，RAG（Retrieval-Augmented Generation，检索增强生成）作为一种新兴的技术方法，正逐渐成为 AI 2.0 时代的杀手级应用。&lt;/p&gt;</description></item><item><title>在 .NET8 中获取 k8s 集群的 namespace id</title><link>https://fwhyy.com/2024/08/in-retrieve-the-namespace-id-of-the-k8s-cluster-in-net8/</link><pubDate>Wed, 28 Aug 2024 08:22:21 +0800</pubDate><guid>https://fwhyy.com/2024/08/in-retrieve-the-namespace-id-of-the-k8s-cluster-in-net8/</guid><description>&lt;p&gt;将程序和机器进行绑定是一种 License 校验的方法，需要能获取到机器的唯一标识，比如获取机器的 Mac 地址就是获取唯一标识的一种方式，命令如下：&lt;/p&gt;</description></item><item><title>对提升项目效率的一点思考</title><link>https://fwhyy.com/2024/08/some-thoughts-on-improving-project-efficiency/</link><pubDate>Tue, 20 Aug 2024 08:17:14 +0800</pubDate><guid>https://fwhyy.com/2024/08/some-thoughts-on-improving-project-efficiency/</guid><description>&lt;p&gt;在一个软件企业中，项目实施效率非常重要，它关乎企业的竞争力，影响项目交付的速度和质量，关系到企业的盈利能力，甚至决定着企业的生死。&lt;/p&gt;</description></item><item><title>记忆深刻的巴黎奥运时刻</title><link>https://fwhyy.com/2024/08/memorable-paris-olympics-moments/</link><pubDate>Mon, 12 Aug 2024 14:42:57 +0800</pubDate><guid>https://fwhyy.com/2024/08/memorable-paris-olympics-moments/</guid><description>&lt;p&gt;今年的巴黎奥运会可能是我看的最认真的一届奥运会。一直关注着中国队的比赛，一直关注着中国对的金牌排名。而且还带着女儿看了不少比赛。&lt;/p&gt;
&lt;p&gt;现在巴黎奥运会已经全部结束，下面是一些印象深刻的瞬间：&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;1、开幕式中运动员坐船穿行塞纳河这种独特的出场方式令人印象深刻，热气球的火炬也非常有创意。&lt;/p&gt;
&lt;p&gt;2、莎莎和大头混双拿冠军后，记着踩坏了大头的乒乓球拍，或许这是他后面止步 16 强的原因。&lt;/p&gt;
&lt;p&gt;3、潘神在自由泳中表现出来的统治力，感觉不在菲尔普斯之下了。&lt;/p&gt;
&lt;p&gt;4、女子 20 公里竞走，杨家玉一骑绝尘，终点前套圈了老将刘虹，并进行了沟通，刘虹脸上洋溢着笑容，最后在刘虹的目送下杨家玉也拿到了冠军。&lt;/p&gt;
&lt;p&gt;5、女子乒乓球单打，陈梦战胜了孙颖莎，还闹起了一段网络风波，没去深入关注，是中国人拿冠军就好。&lt;/p&gt;
&lt;p&gt;6、郑钦文夺得网球女单冠军，太不容易了。&lt;/p&gt;
&lt;p&gt;7、中国乒乓球有惊无险，拿下全部 5 枚金牌，跳水队也包揽了总共 8 枚金牌，是最不用担心的一个项目了。&lt;/p&gt;
&lt;p&gt;8、中国举重队的李发彬、罗诗芳都打破奥运记录，摘的金牌，最后一天随着 81 公斤以上级别女子举重李雯雯轻轻松松取胜，中国的总金牌数来到了 40 枚。&lt;/p&gt;
&lt;p&gt;9、在男子马拉松赛场上罕见出现了乔爷岔气走路，最终还退赛了，真是见证了一代英雄的落幕；女子马拉松哈桑在全程跟跑后，最后 600 米展现了绝对实力。&lt;/p&gt;
&lt;p&gt;10、奥运会最后的一个比赛是女子篮球，美国对战法国，赛前，美国和中国的金牌数都是 40 块，但美国总奖牌数要多，所以如果法国赢，中国排名第一，否则排名第二。看比赛时，弹幕里全部是给法国加油的，最后还是一分之差输给了美国。&lt;/p&gt;</description></item><item><title>读《华为项目管理之道》</title><link>https://fwhyy.com/2024/08/read-the-way-of-huawei-project-management/</link><pubDate>Wed, 07 Aug 2024 08:11:47 +0800</pubDate><guid>https://fwhyy.com/2024/08/read-the-way-of-huawei-project-management/</guid><description>&lt;p&gt;在《软技能》一书中，提到将自己当作一个企业来思考，这其中的一个关键点就是要学会换位思考。做项目也是一样，需要换位思考，同时我们也能将很多事情都能理解为一个项目，例如：写系列文章、组织一次自驾游、产品开发等等，只不过这些项目的甲方可以是自己、家属、老板等。&lt;/p&gt;</description></item><item><title>ITRA 积分看不到怎么办？</title><link>https://fwhyy.com/2024/07/itra-points-not-visible/</link><pubDate>Fri, 26 Jul 2024 16:30:00 +0800</pubDate><guid>https://fwhyy.com/2024/07/itra-points-not-visible/</guid><description>&lt;p&gt;跑过越野跑比赛的应该都知道 ITRA，我就是去年首野的时候注册的账号。&lt;/p&gt;
&lt;p&gt;ITRA 有一个表现分（Performance Index），是用于评估越野跑选手速度的工具。PI 指数的分值范围是 0到 1000 分，它反映了选手的速度潜能。PI 指数是根据选手过去 36 个月内 5 次最佳比赛成绩的加权平均值计算得出的。如果选手参加的比赛不足5场，会通过统计学算法进行拟合推断出缺失比赛的可能成绩。PI 指数不仅考虑了完赛时间，还考虑了赛道的距离和海拔，以及修正系数，这个系数考虑了天气条件、技术路段等不可控因素。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;去年首野完成后，我发现我完成的比赛记录并没有出现在我注册的账号中，当然也就没有表现分，今年崇礼168 跑完后发现完赛就录依然没有跟我的 ITRA 账号关联。&lt;/p&gt;
&lt;p&gt;一通研究后发现原因如下：&lt;/p&gt;
&lt;p&gt;1、FirstName、LastName 没有匹配上。&lt;/p&gt;
&lt;p&gt;2、生日填写有误。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;解决方法&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;1、我检查了我崇礼168 越野赛的报名信息，确认 FirstName 和 LastName，然后进 ITRA 网站的个人信息中进行修改。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/20240726161558.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/20240726161741.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、检查报名的出生日期和网站个人信息是否一致，我的果然不一致，报名应该是读取的身份证号，自动识别的，是阴历生日；网站中我填写的是阳历生日。所以就修改了网站个人信息中的生日和报名信息一致。&lt;/p&gt;
&lt;p&gt;3、上面操作后，崇礼168 的记录就能关联上了，但去年首野的还没有关联过来，应该还是信息填写有误，但又没有办法去修改当时的报名信息，幸好 ITRA 网站有一个「Find your race」的功能，这个功能允许你查找之前的记录进行关联即可（需要等待一个审核）。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/20240726162535.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/20240726162619.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/20240726162733.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/20240726162447.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>崇礼168越野赛 MTC 70 公里完赛复盘</title><link>https://fwhyy.com/2024/07/chong-168-off-road-race-mtc-70-km-final-round-recap/</link><pubDate>Wed, 24 Jul 2024 08:12:53 +0800</pubDate><guid>https://fwhyy.com/2024/07/chong-168-off-road-race-mtc-70-km-final-round-recap/</guid><description>&lt;p&gt;在《我的人生首野——大岩山萧绍古道 30 公里》文章的最后写道：“下一站：2024 年崇礼 168 越野赛70 公里。”&lt;/p&gt;
&lt;p&gt;这个目标在上个周末轻松实现了。&lt;/p&gt;</description></item><item><title>Mac环境下的vi工具，我选择NvChad</title><link>https://fwhyy.com/2024/07/i-choose-nvchad-as-the-vi-tool-for-mac-environment/</link><pubDate>Thu, 04 Jul 2024 23:57:02 +0800</pubDate><guid>https://fwhyy.com/2024/07/i-choose-nvchad-as-the-vi-tool-for-mac-environment/</guid><description>&lt;p&gt;在服务器中操作一些文本时，经常会用到 vi 工具，否则就得把文件拷贝到本地，修改完再传到服务器，非常麻烦。&lt;/p&gt;
&lt;p&gt;那么在 Mac 中 vi 有什么用呢？我并不追求将每一种工具都打造成全能的 IDE 。尽管对于编写代码，我们有像 VS Code、Rider、IntelliJ IDEA 这样成熟且功能丰富的集成开发环境，但若只是为了查看代码，我发现 &lt;code&gt;vi&lt;/code&gt; 依然是一个非常便利的选择。&lt;/p&gt;</description></item><item><title>iTerm2 会话管理以及其他常用设置</title><link>https://fwhyy.com/2024/06/iterm2-session-management-and-other-commonly-used-settings/</link><pubDate>Thu, 20 Jun 2024 08:53:37 +0800</pubDate><guid>https://fwhyy.com/2024/06/iterm2-session-management-and-other-commonly-used-settings/</guid><description>&lt;p&gt;在《我在 Mac 中试过用的那些 shell 工具》中最后介绍 iTerm 的安装以及基本使用，但有一个很重要的功能没有介绍，那就是会话管理。&lt;/p&gt;
&lt;p&gt;本文介绍 iTerm2 的会话管理以及一些其他配置。&lt;/p&gt;</description></item><item><title>Mac中的常用 shell工具</title><link>https://fwhyy.com/2024/06/common-shell-tools-in-mac/</link><pubDate>Thu, 13 Jun 2024 08:51:25 +0800</pubDate><guid>https://fwhyy.com/2024/06/common-shell-tools-in-mac/</guid><description>&lt;p&gt;很多时候我们需要使用命令行进行一些操作，在 Mac 中有自带的终端（Terminal）可以使用，但功能比较简单，其他的一些工具也使用过不少，下面就简单介绍下我在 Mac 中用过的一些命令行工具。&lt;/p&gt;</description></item><item><title>MongoDB密码设置</title><link>https://fwhyy.com/2024/06/mongodb-password-setting/</link><pubDate>Thu, 06 Jun 2024 08:49:13 +0800</pubDate><guid>https://fwhyy.com/2024/06/mongodb-password-setting/</guid><description>&lt;p&gt;给 MongoDB 设置密码有两种情况：&lt;/p&gt;
&lt;p&gt;1、给创建的 MongDB 容器添加密码。&lt;/p&gt;
&lt;p&gt;2、给现有的无密码的 MongoDB 容器进行密码设置。&lt;/p&gt;
&lt;p&gt;在设置密码之前，先说说 MongoDB 的版本，之前一直使用 5.0.2 和 5.0.14 版本比较多，然而这两个版本都是有安全漏洞的，所以大版本如果选择 5 ，可以选择 5.0.24 。&lt;/p&gt;</description></item><item><title>Kubesphere 使用实践</title><link>https://fwhyy.com/2024/05/kubesphere-usage-practice/</link><pubDate>Wed, 29 May 2024 08:45:33 +0800</pubDate><guid>https://fwhyy.com/2024/05/kubesphere-usage-practice/</guid><description>&lt;p&gt;容器化部署，尤其是利用 Docker 技术，已成为现代软件部署的标配。我们可以通过简单的命令如 &lt;code&gt;run&lt;/code&gt; 直接启动容器，或者使用编排工具如 &lt;code&gt;docker-compose&lt;/code&gt; 和 &lt;strong&gt;Kubernetes&lt;/strong&gt;（简称 &lt;strong&gt;k8s&lt;/strong&gt;）等来简化操作。&lt;/p&gt;</description></item><item><title>读《强风吹拂》</title><link>https://fwhyy.com/2024/05/read-strong-wind-blows/</link><pubDate>Thu, 23 May 2024 08:42:19 +0800</pubDate><guid>https://fwhyy.com/2024/05/read-strong-wind-blows/</guid><description>&lt;p&gt;&lt;img src="https://img.fwhyy.com/2024/202405221638731.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;《强风吹拂》是日本作家三浦紫苑创作的长篇小说。该小说讲述了宽政大学宿舍「竹青庄」的十名舍友凑成杂牌长跑队，在队长清濑灰二的魔鬼训练下，从零开始向日本历史最悠久的长跑接力赛「箱根驿传」挺进的故事。&lt;/p&gt;</description></item><item><title>迁移Wordpress到Docker</title><link>https://fwhyy.com/2024/05/migrating-wordpress-to-docker/</link><pubDate>Tue, 14 May 2024 08:40:00 +0800</pubDate><guid>https://fwhyy.com/2024/05/migrating-wordpress-to-docker/</guid><description>&lt;p&gt;很多年前我的个人博客是部署在 Linode 的服务器，后来又给女儿弄了一个博客记录女儿的成长，使用的是 Wordpress ，老婆执笔。现在我的博客早已迁移到了 github ，女儿也长大了，博客好几年没有更新，准备停掉 linode 服务器，将女儿博客迁移到本地。&lt;/p&gt;</description></item><item><title>效率工具：Reader和Arc浏览器新功能</title><link>https://fwhyy.com/2024/04/new-features-for-reader-and-arc-browsers/</link><pubDate>Wed, 24 Apr 2024 08:37:08 +0800</pubDate><guid>https://fwhyy.com/2024/04/new-features-for-reader-and-arc-browsers/</guid><description>&lt;p&gt;Arc 浏览器和 Readwise Reader 是我在 Mac 上很喜欢的两款工具，这两款工具最近推出的一些功能能极大提升效率。哦不，功能推出有一阵子了，我最近才开始使用。&lt;/p&gt;
&lt;p&gt;本文简单介绍下这些新功能。&lt;/p&gt;</description></item><item><title>银河麒麟V10使用Docker方式部署应用</title><link>https://fwhyy.com/2024/04/galaxy-kirin-v10-deploys-applications-using-docker/</link><pubDate>Tue, 16 Apr 2024 08:28:08 +0800</pubDate><guid>https://fwhyy.com/2024/04/galaxy-kirin-v10-deploys-applications-using-docker/</guid><description>&lt;p&gt;现在越来越多的企业级应用需要运行在国产化环境中，而银河麒麟 V10 是目前我碰到的最常用的服务器，在银河麒麟上部署应用有两种方式：使用二进制文件编译部署和使用 Docker 。&lt;/p&gt;</description></item><item><title>复盘石家庄全马（PB 80 分钟）</title><link>https://fwhyy.com/2024/04/reviewing-the-shijiazhuang-marathon/</link><pubDate>Tue, 09 Apr 2024 08:24:34 +0800</pubDate><guid>https://fwhyy.com/2024/04/reviewing-the-shijiazhuang-marathon/</guid><description>&lt;p&gt;马拉松是极限运动，尤其是全马。&lt;/p&gt;
&lt;p&gt;我从 2016 年开始跑步，2017 年便初生牛犊不怕虎，连续跑了两个全马（武汉马拉松、北京马拉松）。在没有做好充足准备的情况下，痛苦地完成了北京马拉松。&lt;/p&gt;</description></item><item><title>能更好集成容器的反向代理Traefik简单使用</title><link>https://fwhyy.com/2024/03/traefik-is-easy-to-use/</link><pubDate>Fri, 29 Mar 2024 08:13:56 +0800</pubDate><guid>https://fwhyy.com/2024/03/traefik-is-easy-to-use/</guid><description>&lt;p&gt;traefik 与 nginx 一样，也是一款优秀的反向代理工具，使用 go 语言开发，本文将介绍怎样用 traefik 来实现我的需求。&lt;/p&gt;</description></item><item><title>简单聊聊云原生</title><link>https://fwhyy.com/2024/03/lets-briefly-talk-about-cloud-native/</link><pubDate>Tue, 19 Mar 2024 08:48:37 +0800</pubDate><guid>https://fwhyy.com/2024/03/lets-briefly-talk-about-cloud-native/</guid><description>&lt;p&gt;云原生，作为一种新兴的软件架构模式，目的在推动应用程序的敏捷开发、快速部署和可靠运行。虽然这一概念已经提出多年，但直至最近几年，云原生才逐渐引起了华中区客户的广泛关注和认知（不一定准确，从我的感觉和经验来看是这样的）。&lt;/p&gt;
&lt;p&gt;本文结合我收集整理的资料、以及我的理解，来看看云原生是怎么回事？&lt;/p&gt;
&lt;h2 id="概念"&gt;概念&lt;/h2&gt;
&lt;p&gt;要搞清一个技术，先从概念开始，跟云原生这个概念有关的主要有两个组织：Pivotal 和 CNCF 。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Pivotal：Pivotal 成立于 2013 年 4 月，由 EMC、VMware 和 GE 投资成立，专注于帮助企业在数字化时代变革所需的 PaaS 云计算、大数据基础平台和平台上的极限编程。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CNCF：CNCF（Cloud Native Computing Foundation，云原生计算基金会）是 Linux 基金会旗下的基金会，可以理解为一个非盈利组织，成立于 2015 年 12 月 11 日。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2015 年，来自 Pivotal 公司的技术产品经理 Matt Stine，首次提出了云原生的概念，认为云原生架构必须包含下面一些特性：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;符合十二要素、微服务、敏捷基础设施、基于 API 的协作、抗压性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2017 年，Matt Stine 在接受 InfoQ 采访时，将云原生特性做了些调整：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;模块化、可观测性、可部署性、可测试性、可处理性、可替换性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而现在的云原生涉及到的一些关键词有，原文可以参考：https://tanzu.vmware.com/cloud-native：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;微服务、DevOps、容器、服务网格、CI/CD、Serverless&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;可见，云原生的定义是在不断演进的，不断会有新的东西加入。&lt;/p&gt;
&lt;p&gt;再来看看 CNCF 的官方最早是怎么定义的：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cloud native computing uses an open source software stack to deploy applications as microservices, packaging each part into its own container, and dynamically orchestrating those containers to optimize resource utilization.&lt;/p&gt;
&lt;p&gt;云原生使用一种开源软件技术栈来部署微服务应用，将每个组件打包到它自己的容器中，并且通过动态编排来优化资源的利用率。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2018 年，CNCF 推出了对云原生定义的 v1.0 版本，地址如下：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/cncf/toc/blob/main/DEFINITION.md"&gt;https://github.com/cncf/toc/blob/main/DEFINITION.md&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;云原生技术有利于各组织在公有云、私有云和混合云等新型动态环境中，构建和运行可弹性扩展的应用。云原生的代表技术包括容器、服务网格、微服务、不可变基础设施和声明式API。&lt;/p&gt;
&lt;p&gt;这些技术能够构建容错性好、易于管理和便于观察的松耦合系统。结合可靠的自动化手段，云原生技术使工程师能够轻松地对系统作出频繁和可预测的重大变更。&lt;/p&gt;
&lt;p&gt;云原生计算基金会（CNCF）致力于培育和维护一个厂商中立的开源生态系统，来推广云原生技术。我们通过将最前沿的模式民主化，让这些创新为大众所用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="云计算和云原生的关系"&gt;云计算和云原生的关系&lt;/h2&gt;
&lt;p&gt;早些年，传统的企业软件开发是部署在企业的内部物理机中，为了让一个系统能正常运行，通常需要很多的机器，数据库、中间件、程序的前后端都需要进行单独部署。&lt;/p&gt;
&lt;p&gt;后来有了虚拟化技术，通过在各种实体资源（CPU、内存、网络、存储等）之上构建一个逻辑层，从而摆脱物理限制的约束，提高物理资源的利用率。最直观的感受就是可以在一台物理机上快速运行多个虚拟机、意味着可以&lt;strong&gt;降低物理机的数量，节约成本。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;虚拟技术的成熟促成了云计算的出现。2006 年 Google 首次提出了云计算的概念。云计算出现之后，就慢慢出现了 XaaS ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IaaS（基础设施即服务）&lt;/strong&gt;：一种云计算服务类型，它按即用即付的方式按需提供必要的计算、存储和网络资源。这种服务模式帮助客户降低维护成本和硬件成本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PaaS（平台即服务）&lt;/strong&gt;：云计算服务模式之一，它为开发人员提供了包括一系列开发工具、服务、应用程序接口（API）等资源的平台。它的目标是让开发者能够更快速、高效地构建、发布、扩展和维护应用，同时云服务商负责管理和提供开发环境。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;aPaaS（应用平台即服务）&lt;/strong&gt;：是一类特定的 PaaS，重点在于为应用程序提供更快捷的构建服务，例如低代码能力。通常包括通过可视化操作减少原生代码使用、高效的数据处理、模块化的功能实现等，目的是为了让开发者更高效地搭建、运行、维护和扩展应用。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DaaS（数据即服务）&lt;/strong&gt;：将数据从静态资源转变为一种可通过网络获取的即时服务。用户可以方便地访问和使用数据，无需关心数据存储和管理的底层细节。数据通过平台进行集中化管理，提供规范化、标准化的数据访问和数据处理流程。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FaaS（函数即服务）&lt;/strong&gt;：是一种基于事件驱动的无服务器执行模式，在这种模式中，开发人员无需关心服务器的管理和维护，只需编写并上传业务函数代码。当触发特定事件时，这些代码由云服务商在全托管的环境中执行。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SaaS（软件即服务）&lt;/strong&gt;：一种云计算模式，在这种模式中，软件通常以网络浏览器的形式提供给用户。用户不需要在本地机器上安装或维护软件，所有的应用程序和数据库都位于云端的数据中心。这减少了用户在软件和硬件方面的投入和维护工作。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;云计算的兴起，一些企业将软件逐渐迁移到公有云，无需再关心网络、存储、服务器等，这些都由云厂商的 IaaS、PaaS 能力提供。&lt;/p&gt;</description></item><item><title>在.NET中动态执行Nodejs代码的另一种方法</title><link>https://fwhyy.com/2024/03/in-another-method-for-dynamically-executing-nodejs-code-in-dotnet/</link><pubDate>Mon, 11 Mar 2024 08:45:14 +0800</pubDate><guid>https://fwhyy.com/2024/03/in-another-method-for-dynamically-executing-nodejs-code-in-dotnet/</guid><description>&lt;p&gt;在低代码平台中，通常有业务逻辑编排的能力，在业务逻辑编排中有很多不同类型的节点，例如：逻辑判断、接口调用、数据更新等，但为了方便开发人员使用，如果添加代码块的节点，将会极大增加开发效率。&lt;/p&gt;</description></item><item><title>2023 年终总结</title><link>https://fwhyy.com/2024/02/2023-summary/</link><pubDate>Mon, 26 Feb 2024 10:01:59 +0800</pubDate><guid>https://fwhyy.com/2024/02/2023-summary/</guid><description>&lt;p&gt;23 年的总结虽迟但到。&lt;/p&gt;
&lt;h2 id="成长"&gt;成长&lt;/h2&gt;
&lt;p&gt;在2023年的一月，我写了一篇关于做减法的文章，这让我意识到持续做加法会带来问题。这个思考引导着我在2023年从各个方面开始转变，包括阅读、信息处理、产品研发和个人的兴趣爱好等。&lt;/p&gt;</description></item><item><title>读《笔记的方法》</title><link>https://fwhyy.com/2024/02/reading-methods-of-taking-notes/</link><pubDate>Tue, 06 Feb 2024 17:31:07 +0800</pubDate><guid>https://fwhyy.com/2024/02/reading-methods-of-taking-notes/</guid><description>&lt;p&gt;《笔记的方法》这本书是比较意外获得的，2022 年年底，在小报童上购买了少楠和白光的知识专栏《知识资产》，2023 年年底，《知识资产》被重新编辑整理成书，在得到出版，之前专栏的订阅者，每人都能免费获得纸质书和该书的电子版，算是非常良心了。&lt;/p&gt;</description></item><item><title>私有镜像仓库 Harbor 安装和使用</title><link>https://fwhyy.com/2024/01/private-image-warehouse-harbor-installation-and-use/</link><pubDate>Mon, 22 Jan 2024 17:28:51 +0800</pubDate><guid>https://fwhyy.com/2024/01/private-image-warehouse-harbor-installation-and-use/</guid><description>&lt;h2 id="介绍"&gt;介绍&lt;/h2&gt;
&lt;p&gt;我们如果需要部署一个私有镜像仓库来使用，最简单的就是 registry ，一行命令就可以运行在 Docker 中，但功能也比较弱，如果想要私有镜像仓库功能更丰富些，可以使用 Harbor 。&lt;/p&gt;
&lt;p&gt;本文简单介绍下 Harbor 的安装和使用。&lt;/p&gt;</description></item><item><title>利用 Github Actions 同步佳明国内到国际</title><link>https://fwhyy.com/2024/01/using-github-actions-to-synchronize-jiamings-domestic-and-international-operations/</link><pubDate>Mon, 15 Jan 2024 17:25:11 +0800</pubDate><guid>https://fwhyy.com/2024/01/using-github-actions-to-synchronize-jiamings-domestic-and-international-operations/</guid><description>&lt;p&gt;2019 年就开始在使用佳明的 245 ，最近才知道佳明分为国内区和国际区，而且两个区的账号是独立的，数据不互通。而 runalyze 、Strava 等跑步分析工具又只能和国际区进行连接同步。&lt;/p&gt;
&lt;p&gt;所以本文就是用来告诉你怎样将佳明国内区同步到国际区，这样就能正常使用 runalyze 和 Strava 了。&lt;/p&gt;</description></item><item><title>认真深入做一件事，从跑步开始</title><link>https://fwhyy.com/2024/01/do-something-seriously-and-deeply-starting-from-running/</link><pubDate>Wed, 10 Jan 2024 17:09:43 +0800</pubDate><guid>https://fwhyy.com/2024/01/do-something-seriously-and-deeply-starting-from-running/</guid><description>&lt;p&gt;去年的 1月 22 号是大年初一，我写了一篇《2023 关键词：做减法》，回顾这一年，做的不算太好，但是朝着这个方向在走，在 2024，我想在做减法的基础上，再多给自己一个要求，就是要认真深入地去做一件事。&lt;/p&gt;
&lt;p&gt;为什么会有这个想法呢？还得从跑步说起。&lt;/p&gt;</description></item><item><title>.NET中操作哨兵模式的Redis（哨兵和Redis示例配置密码）</title><link>https://fwhyy.com/2023/12/redis-for-operating-sentinel-mode-in-net/</link><pubDate>Mon, 25 Dec 2023 17:03:06 +0800</pubDate><guid>https://fwhyy.com/2023/12/redis-for-operating-sentinel-mode-in-net/</guid><description>&lt;p&gt;Redis 的高可用有一种方式是部署成哨兵模式。在哨兵模式中哨兵和每个节点都可以设置密码，如果都设置密码了，在 .NET 中用 CSRedisCore 进行调用时会遇到点问题。&lt;/p&gt;
&lt;p&gt;本文就介绍怎样用 CSRedisCore 来调用设置了密码的哨兵模式 Redis。&lt;/p&gt;</description></item><item><title>NET Core3.1 升级到 NET8</title><link>https://fwhyy.com/2023/12/dotnet-3-upgrade-to-dotnet-8/</link><pubDate>Fri, 08 Dec 2023 17:00:06 +0800</pubDate><guid>https://fwhyy.com/2023/12/dotnet-3-upgrade-to-dotnet-8/</guid><description>&lt;p&gt;.NET Core 3.1 已经用了很长一段时间，其实在 2022 年的年底微软已经不提供支持了，后面的一个 LTS 版本 .NET 6 也会在 2024 年 11 月终止支持，所以直接升级到 .NET 8 是最好的选择。&lt;/p&gt;</description></item><item><title>我的人生首野-大岩山萧绍古道 30 公里</title><link>https://fwhyy.com/2023/12/the-first-wild-in-my-life/</link><pubDate>Wed, 06 Dec 2023 16:29:16 +0800</pubDate><guid>https://fwhyy.com/2023/12/the-first-wild-in-my-life/</guid><description>&lt;p&gt;安全跑完人生第一个越野跑后，得出一个结论：越野跑和马拉松绝对是两种不同的运动。&lt;/p&gt;
&lt;p&gt;我的越野跑入坑是因为身边有朋友从马拉松转战到了越野跑，于是今年 7 月就和朋友一起报了 12 月份的大岩山越野赛 30 公里组别。关于和马拉松的区别、装备等，在《从公路马拉松到越野跑：一次新的挑战》中有详细介绍。&lt;/p&gt;</description></item><item><title>半马连续两周 PB 后的复盘</title><link>https://fwhyy.com/2023/11/marathon-pb-review/</link><pubDate>Thu, 23 Nov 2023 16:41:28 +0800</pubDate><guid>https://fwhyy.com/2023/11/marathon-pb-review/</guid><description>&lt;p&gt;最近，连续跑了两个半马比赛，都 PB 了，个人最好成绩也定格在了 11 月 12 日的南昌马拉松半马，成绩为 142 。&lt;/p&gt;
&lt;p&gt;一直以来，我跑步比较佛系，夏天跑的少、冬天也跑的少，报了比赛就临时突击下，所以总跑量不多。这些年，线上线下，陆陆续续也跑了 29 场半马，但直到今年 4 月宜昌马拉松半程才跑进两小时。&lt;/p&gt;</description></item><item><title>.NET8 正式发布， C#12 新变化</title><link>https://fwhyy.com/2023/11/dotnet-8/</link><pubDate>Fri, 17 Nov 2023 16:38:50 +0800</pubDate><guid>https://fwhyy.com/2023/11/dotnet-8/</guid><description>&lt;p&gt;在 .NET Conf 2023 大会上，.NET 8 正式发布了，.NET 8 是一个长期支持（LTS）版本，这意味着可以获得三年的支持和补丁。我们也计划将框架从 .NET Core3.1 升级到 8 ，关于如何升级等升级完成后再来分享。&lt;/p&gt;</description></item><item><title>监控利器：普罗米修斯监控中间件(Nginx、Redis、MySql 等)</title><link>https://fwhyy.com/2023/11/prometheus-monitoring-middleware/</link><pubDate>Thu, 09 Nov 2023 16:36:23 +0800</pubDate><guid>https://fwhyy.com/2023/11/prometheus-monitoring-middleware/</guid><description>&lt;p&gt;我们的产品目前使用到的中间件有 Nginx、Redis、RabbitMQ、MySql 等，本文介绍怎样使用 Promtheus 来监控这些中间件。&lt;/p&gt;</description></item><item><title>监控利器：普罗米修斯介绍和安装</title><link>https://fwhyy.com/2023/11/install-prometheus/</link><pubDate>Wed, 01 Nov 2023 08:29:51 +0800</pubDate><guid>https://fwhyy.com/2023/11/install-prometheus/</guid><description>&lt;p&gt;我们的程序想要稳定的运行，或者说当出现问题时能第一时间知道，这就离不开监控，目前比较主流的就是 Prometheus（普罗米修斯）+ Grafana 的组合。&lt;/p&gt;</description></item><item><title>聊聊六边形架构</title><link>https://fwhyy.com/2023/10/talk-about-hexagonal-architecture/</link><pubDate>Tue, 24 Oct 2023 08:27:49 +0800</pubDate><guid>https://fwhyy.com/2023/10/talk-about-hexagonal-architecture/</guid><description>&lt;p&gt;指导我们写出漂亮代码有一种方式是学习设计模式，自从 Gof 四人组的《设计模式》出版后，各类设计模式的书层出不穷。熟读这类书籍，对面试肯定是有帮助的，但代码能力是否有大的长进就不一定了，如果没能理解背后的思想，去生搬硬套，只会起反作用。&lt;/p&gt;</description></item><item><title>如何设计 API？</title><link>https://fwhyy.com/2023/10/how-to-design-the-api/</link><pubDate>Tue, 17 Oct 2023 09:42:48 +0800</pubDate><guid>https://fwhyy.com/2023/10/how-to-design-the-api/</guid><description>&lt;p&gt;在前后端分离的设计中，不管使用什么语言，后端都需要提供 WebAPI 给前端使用。如果是一个平台级的产品，还有可能需要将平台的公共 API 提供给第三方系统使用，这些都要考虑到 API 的设计。&lt;/p&gt;</description></item><item><title>这个国庆，又出发了（武汉-平潭）</title><link>https://fwhyy.com/2023/10/this-national-day-we-set-off-again-wuhan-pingtan/</link><pubDate>Mon, 09 Oct 2023 09:40:37 +0800</pubDate><guid>https://fwhyy.com/2023/10/this-national-day-we-set-off-again-wuhan-pingtan/</guid><description>&lt;p&gt;国庆长假结束了。在这个长假里，三个人一台车又出发了。&lt;/p&gt;
&lt;p&gt;对于上班族来说，一年中，国庆假期是难得的适合出行的日子，所以，从 16 年开始，每年的国庆都有出行的计划，直到疫情出现。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2016 年：长沙-常德-宜昌-荆州&lt;/li&gt;
&lt;li&gt;2017 年：襄阳&lt;/li&gt;
&lt;li&gt;2018 年：十堰-西安&lt;/li&gt;
&lt;li&gt;2019 年：安庆-南浔-杭州-合肥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当决定在疫情后的第一个国庆长假出行时，就已经做好了大堵车和看人头的准备，我一直认为，在路上发生的一切都属于旅行的一部分。&lt;/p&gt;
&lt;h2 id="路线规划"&gt;路线规划&lt;/h2&gt;
&lt;p&gt;关于路线的规划，遵循下面几个原则：&lt;/p&gt;
&lt;p&gt;1、最远到达的距离尽量不超过 1000 公里，否则时间上不太够用；&lt;/p&gt;
&lt;p&gt;2、从武汉到目标城市之间找一个城市中转，回程可以找另一个中转城市；&lt;/p&gt;
&lt;p&gt;3、先大致确定一个方向，然后在地图上找目标城市和中转城市；&lt;/p&gt;
&lt;p&gt;4、规划仅供参考，计划总是赶不上变化，所以酒店不宜一开始把每天的都订好（除非可以免费退的那种），不提前订又会遇到价格高和订不上的问题，需要权衡。&lt;/p&gt;
&lt;p&gt;这个国庆，选择的是东南方向，目的地福州和平潭岛，去的时候经过景德镇，回来的时候从抚州中转，可以去附近的古镇转转，但是从平潭晒了一天太阳后，非常累，临时决定不去抚州了，订了一个资溪的度假酒店，休息调整。&lt;/p&gt;
&lt;p&gt;恰恰是临时决定去的度假酒店，是女儿最喜欢的。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082202992.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="行程"&gt;行程&lt;/h2&gt;
&lt;h3 id="day19-月-29"&gt;Day1（9 月 29）&lt;/h3&gt;
&lt;p&gt;上午十点多出发，下午三点多到达景德镇，一路非常通畅，甚至一些路段一辆车都没有，完全感受不到节日的热闹。&lt;/p&gt;
&lt;p&gt;在酒店安顿好后，便去了陶溪川，对这里印象很深刻：&lt;/p&gt;
&lt;p&gt;1、有非常多的卖瓷器小物件的摊位，而且摊主都是年轻漂亮的小姐姐或帅气的小哥哥；&lt;/p&gt;
&lt;p&gt;2、瓷器小物件价格很贵；&lt;/p&gt;
&lt;p&gt;3、适合拍照。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082203208.webp" alt="陶溪川" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;网上查当地的美食，有一家叫「樊记牛骨粉」，看到的所有店子都叫「樊记牛骨粉」，倒也不用挑了，随便进一个即可。牛骨粉、冷粉、饺子粑、油条包糯米，一个店子搞定，油条包糯米挺不错，第二天去抚州弄，又买了一次。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082203020.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="day29-月-30"&gt;Day2（9 月 30）&lt;/h3&gt;
&lt;p&gt;离景德镇约 50 公里左右有一个瑶里古镇风景区，距离瑶里古镇十分钟车程的地方还有一处鲜为人知的古朴村落，这个地方叫做—东埠古街古码头。&lt;/p&gt;
&lt;p&gt;这个地方没有商业化，可以看到村民在河里钓鱼、洗衣服。尽管是在国庆期间，也只能看见很少的几个游客。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082203056.webp" alt="东埠古街古码头" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;离开东埠古街，继续驱车前往瑶里，果然商业化重的地方人就多，没能找到停车位，然后又临时找到了一个寒溪村。&lt;/p&gt;
&lt;p&gt;寒溪村后面的山上是一片茶园，茶园最高处矗立着一座大型艺术品「大地之灯」，是著名建筑师马岩松的作品。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082203882.webp" alt="寒溪村" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;回到市区后，又去了九集小镇（规模巨大的一个夜市）、雕塑瓷厂、、御窑博物馆（需要提前预约）、抚州弄，基本上该去的地方都去了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082203980.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Day3（10 月 1）&lt;/p&gt;
&lt;p&gt;因为担心堵车，早饭后简单逛了下三宝村就前往福州了，运气很好，高速上依旧没什么车。下午 6 点多到达酒店，酒店在三坊七巷附近。&lt;/p&gt;
&lt;p&gt;晚上步行去了三坊七巷，途中经过了几个居民区，在大榕树的映衬下，非常的静谧，等到了三坊七巷，又人山人海，形成了鲜明的对比。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310090613273.webp" alt="三坊七巷" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Day4（10 月 2）&lt;/p&gt;
&lt;p&gt;2 号的安排是福州市内，上下杭、烟台山一圈逛下来已经是下午 4 点多了，地铁加步行的出行模式也让我惊喜的发现福州的地铁是免费的（截止到 12 月）。&lt;/p&gt;
&lt;p&gt;晚上老婆提议去了福州大学附近的永嘉夜市，依然是乘坐免费的地铁。永嘉夜市的人刚刚好，不多不少，在国庆期间，只要人不多，体验就会很好。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082204183.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Day5（10 月 3）&lt;/p&gt;
&lt;p&gt;去海边是这次旅行女儿最期待的，但是否去平潭犹豫了很久，就担心人太多。最后查到一个非常小众的五星沙滩，在去仙人井的途中右转进去，经过一个村庄的小路，就到了，果然不负所望，人非常少。&lt;/p&gt;
&lt;p&gt;中午从五星海滩离开，女儿还依依不舍。&lt;/p&gt;
&lt;p&gt;接着导航风车森林公路，因为是单行线，路边可以停车，我们找了合适位置停好车，下车拍照，可能是因为台风「小犬」的原因，很多人劝退了，人比想象中的少。&lt;/p&gt;
&lt;p&gt;在平潭，我们只去了五星海滩和看了海上风车，想想没有排队、没有拥堵，也就很知足了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310082204243.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Day6（10 月 4）&lt;/p&gt;
&lt;p&gt;没有提前预定抚州的酒店，就可以临时改变行程了。老婆找的资溪度假酒店非常不错，下高速几公里就到了。价格是这次行程中最便宜的，设施和环境是最好的。&lt;/p&gt;
&lt;p&gt;女儿在酒店的儿童游乐场玩的很嗨。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310090613489.webp" alt="资溪" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Day7（10 月 5）&lt;/p&gt;
&lt;p&gt;安全抵达武汉。&lt;/p&gt;
&lt;h2 id="跑步"&gt;跑步&lt;/h2&gt;
&lt;p&gt;尽管是十一旅行，跑步可不能拉下。&lt;/p&gt;
&lt;h3 id="景德镇"&gt;景德镇&lt;/h3&gt;
&lt;p&gt;10 月 1 号在景德镇跑了 10.01 公里来庆祝国庆。景德镇市区不大，酒店的正前方是陶溪川，我特意从反方向跑，最后还是绕到了陶溪川。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310090612933.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="福州"&gt;福州&lt;/h3&gt;
&lt;p&gt;4 号是离开福州的日子，早上 5 点起床，跑向离酒店只有 3 公里的闽江公园，沿着江边跑了一个来回，然后跑回酒店。&lt;/p&gt;
&lt;p&gt;江边的绿道以及城市的道路都被榕树包裹着，6 点多，太阳已经升起，但一点都不晒，非常舒服。&lt;/p&gt;
&lt;p&gt;福州真的是一个非常适合跑步的城市。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202310090612099.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="资溪"&gt;资溪&lt;/h3&gt;
&lt;p&gt;酒店在一个山上，起床后就沿着上山的路往下跑，偶然发现旁边有一条环境优美的绿道，绿道总共 3 公里左右，跑了几个来回。&lt;/p&gt;</description></item><item><title>B 端软件：开发转产品经理可能遇到的坑</title><link>https://fwhyy.com/2023/09/b-side-software-development-to-product-managers-may-encounter-pitfalls/</link><pubDate>Tue, 26 Sep 2023 09:37:57 +0800</pubDate><guid>https://fwhyy.com/2023/09/b-side-software-development-to-product-managers-may-encounter-pitfalls/</guid><description>&lt;p&gt;有一类产品经理是由开发工程师转岗而来。就拿我来说，自从管理产品团队后，经常会和团队的产品经理进行新功能的讨论、会考虑产品未来的发展方向和路径，慢慢的我的工作重心也更多的偏向产品设计。&lt;/p&gt;</description></item><item><title>从马拉松到越野跑：一次新的挑战</title><link>https://fwhyy.com/2023/09/from-marathon-to-trail-running-a-new-challenge/</link><pubDate>Tue, 12 Sep 2023 09:34:58 +0800</pubDate><guid>https://fwhyy.com/2023/09/from-marathon-to-trail-running-a-new-challenge/</guid><description>&lt;p&gt;从 16 年开始跑步以来大小马拉松比赛参加过十几场，近几年，身边有朋友从公路马拉松转战到了越野跑，在他们的带动下，我对越野跑有了更多的关注和了解。并且和一个朋友一起报了 12 月份的大岩山越野赛 30 公里组别，正式开启了我的越野之路。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202309120747336.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;隔行如隔山，一研究发现越野跑跟公路马拉松差别巨大。下面就说说区别和一些注意事项。&lt;/p&gt;
&lt;h2 id="越野跑和公路马拉松的区别"&gt;越野跑和公路马拉松的区别&lt;/h2&gt;
&lt;p&gt;赛道：公路马拉松是在城市的平坦或略有起伏（上高架、大桥）的道路上进行，而越野跑是在山野、森林、沙漠等自然环境中进行，赛道地形复杂多变，有大量的上下坡，甚至需要攀爬或涉水。&lt;/p&gt;
&lt;p&gt;距离：公路马拉松的标准距离是 42.195 公里，半程马拉松 21.0975 公里。而越野跑的距离则没有固定的标准，从几公里到几百公里都有可能，一般分为短程、中程、长程和超长程等不同级别。像我这次报的 30 公里，就属于难度比较低的级别。&lt;/p&gt;
&lt;p&gt;时间：公路马拉松的比赛时间一般在 2 到 6 个小时之间，而越野跑的比赛时间则可能长达几天甚至几周，需要在山野中过夜或者自行选择休息点。&lt;/p&gt;
&lt;p&gt;难度：公路马拉松的难度主要取决于配速和耐力，而越野跑的难度则涉及到技巧、体能、装备、安全、心理等多方面的因素，需要更高的综合素质和适应能力。&lt;/p&gt;
&lt;p&gt;规则：公路马拉松的规则相对简单明确，主要是按照时间和顺序划分名次和奖励，而越野跑的规则则根据不同的赛事有所差异，一般会有强制装备、累计爬升、限时关门等要求，需要提前了解并遵守。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202309120747491.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="装备"&gt;装备&lt;/h2&gt;
&lt;p&gt;在越野跑中，有强制装备需要检查，这一点和公路马拉松有很大的区别，之所以要检查强制装备，是为了安全考虑，特别是 21 年的 522 事件后，强制装备更加严格了。&lt;/p&gt;
&lt;h3 id="越野鞋"&gt;越野鞋&lt;/h3&gt;
&lt;p&gt;相比马拉松跑鞋，越野跑鞋需要提供更好的抓地力和保护，以应对更复杂的地形。提及比较多的有下面几个品牌：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;凯乐石 Fuga EX 系列&lt;/li&gt;
&lt;li&gt;HOKA 飞速羚羊系列&lt;/li&gt;
&lt;li&gt;奥创 奥林巴斯系列&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;鞋子非常重要，能力范围内需要买好一点的。&lt;/p&gt;
&lt;h3 id="越野跑背包强制"&gt;越野跑背包（强制）&lt;/h3&gt;
&lt;p&gt;用于装载能量补给、水、急救包等必要物品。30 公里距离的 5L 就够用了，在朋友的推荐下，准备选购 UG 的 6 升越野包。&lt;/p&gt;
&lt;p&gt;如果你的腰包能装下所有强制装备，不用背包也可以。&lt;/p&gt;
&lt;h3 id="号码布和参赛手环强制"&gt;号码布和参赛手环（强制）&lt;/h3&gt;
&lt;p&gt;识别身份，需要全程佩戴。&lt;/p&gt;
&lt;h3 id="计时芯片强制"&gt;计时芯片（强制）&lt;/h3&gt;
&lt;p&gt;计时芯片需要好好保护，否则跑的累死，没有成绩了。需要注意的是保温毯可能对计时芯片有屏蔽作用，不要放在一起。&lt;/p&gt;
&lt;h3 id="急救毯强制"&gt;急救毯（强制）&lt;/h3&gt;
&lt;p&gt;应该是超过 30 公里的距离必须全程携带，关键时候可以救命。使用时建议尽量贴身，打结后套住头部，然后包覆核心躯干，再穿上外套，防风，隔湿，保温。&lt;/p&gt;
&lt;p&gt;急救毯尺寸不小于 1.5m x 2.0m 。&lt;/p&gt;
&lt;p&gt;急救毯属于消耗类强制装备，使用后不允许丢弃，须凭已消耗的装备或装备包装到达站点更换新的装备。&lt;/p&gt;
&lt;h3 id="救生口哨强制"&gt;救生口哨（强制）&lt;/h3&gt;
&lt;p&gt;大部分越野包都有配备，如果使用的是腰包，需要单独佩戴。仅在遇到危险，需要帮助时使用。&lt;/p&gt;
&lt;h3 id="急救包弹力绷带无菌敷料强制"&gt;急救包：弹力绷带、无菌敷料（强制）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;弹力绷带用于局部固定及加压包扎，规格要求不小于 100cm X 5cm&lt;/li&gt;
&lt;li&gt;无菌敷料主要用于伤口止血，防止污染，规格要求不小于 10cm X 10cm&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;急救用品也属于消耗类强制装备，可自用或给需要帮助的选手使用，消耗后凭有效证明可到补给站补充。&lt;/p&gt;
&lt;h3 id="智能手机及充电宝强制"&gt;智能手机及充电宝（强制）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;手机的手机号码需和报名信息填写的号码一致&lt;/li&gt;
&lt;li&gt;智能手机需具备查看官方发布的赛事轨迹和导航的功能&lt;/li&gt;
&lt;li&gt;比赛期间需保证手机处于可通联状态&lt;/li&gt;
&lt;li&gt;预估自己手机的耗电情况，随身携带足量的充电宝确保手机全程可用，有的赛事会强制要求带充电宝&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="水具强制"&gt;水具（强制）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;很多越野包自带软水壶，没有软水壶的，搞两瓶矿泉水插在越野包上也是可以的&lt;/li&gt;
&lt;li&gt;水具必须可密封&lt;/li&gt;
&lt;li&gt;容量必须大于强制装备的规定，不同赛事和组别要求不一样&lt;/li&gt;
&lt;li&gt;除了软水壶，还需要便携式水杯&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="防水防风连帽夹克强制"&gt;防水防风连帽夹克（强制）&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;帽子与身体部分必须为一体结构&lt;/li&gt;
&lt;li&gt;服装面料为防水材质，所有的缝线处须有压胶密封&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="头灯"&gt;头灯&lt;/h3&gt;
&lt;p&gt;通常 50 公里或以上组别才需要头灯。&lt;/p&gt;
&lt;h3 id="长袖保暖上衣强制"&gt;长袖保暖上衣（强制）&lt;/h3&gt;
&lt;p&gt;建议服装面辅料为抓绒、羊毛或其他具有保暖速干效果的材质，保暖上衣重量不低于200g。&lt;/p&gt;
&lt;h3 id="应急能量食品"&gt;应急能量食品&lt;/h3&gt;
&lt;p&gt;不一定是能量胶，所有高热量的食品都可以，有的赛事会要求必须携带不低于其组别要求数量（能量值）的能量食品。&lt;/p&gt;
&lt;h3 id="手表"&gt;手表&lt;/h3&gt;
&lt;p&gt;我用的佳明 245 没有越野功能，不过这次有人带着一起跑，倒不着急买新的手表，目前关注的手表：佳明 255、265 、955，高驰的 apex 2 pro 等。&lt;/p&gt;
&lt;h3 id="其他装备"&gt;其他装备&lt;/h3&gt;
&lt;p&gt;全指手套、帽子、太阳镜、登山杖，防晒霜，防晒臂套等。&lt;/p&gt;</description></item><item><title>分享几个网站和工具（202309）</title><link>https://fwhyy.com/2023/09/share-some-website-and-tools-202309/</link><pubDate>Tue, 05 Sep 2023 09:32:48 +0800</pubDate><guid>https://fwhyy.com/2023/09/share-some-website-and-tools-202309/</guid><description>&lt;p&gt;最近又收集了一些工具和站点，分享给大家。&lt;/p&gt;</description></item><item><title>博客园，挺住</title><link>https://fwhyy.com/2023/08/cnblogs-hold-on/</link><pubDate>Tue, 29 Aug 2023 09:30:31 +0800</pubDate><guid>https://fwhyy.com/2023/08/cnblogs-hold-on/</guid><description>&lt;p&gt;昨天才看到博客园团队在 8 月 16 号的发文：《弹尽粮绝，会员救园：会员上线，命悬一线》。第一时间就充会员支持了，尽管会员功能还不完善，需要添加企业微信人工处理。&lt;/p&gt;</description></item><item><title>插件开发：实现 PicGo 图片转 webp 格式</title><link>https://fwhyy.com/2023/08/plugin-development-implement-picgo-image-to-webp-format/</link><pubDate>Mon, 28 Aug 2023 09:18:14 +0800</pubDate><guid>https://fwhyy.com/2023/08/plugin-development-implement-picgo-image-to-webp-format/</guid><description>&lt;p&gt;我写一些文档或者公众号文章使用的是 Typora，如果涉及到文章中有图片时，直接复制图片粘贴到 Typora 中，然后使用 PicGo 上传到图床。&lt;/p&gt;</description></item><item><title>软件推荐：Mac神器 Raycast</title><link>https://fwhyy.com/2023/08/software-recommendation-mac-artifact-raycast/</link><pubDate>Mon, 21 Aug 2023 09:12:17 +0800</pubDate><guid>https://fwhyy.com/2023/08/software-recommendation-mac-artifact-raycast/</guid><description>&lt;p&gt;Raycast 是一款 Mac 上的启动器工具，功能类似于 Mac 自带的 「焦点（Spotlight）」。关于启动器工具，如果你没使用过 Spotlight ，一定用过或听说过大名鼎鼎的 Alfred 。启动器工具可以让他们快速打开 Mac 应用，而 Raycast 不仅仅只是一个启动器。&lt;/p&gt;</description></item><item><title>B 端软件：怎样进行竞品分析</title><link>https://fwhyy.com/2023/08/b-end-software-how-to-conduct-competitor-analysis/</link><pubDate>Mon, 14 Aug 2023 09:01:35 +0800</pubDate><guid>https://fwhyy.com/2023/08/b-end-software-how-to-conduct-competitor-analysis/</guid><description>&lt;p&gt;不管是从零开始做一款软件，还是在现有的软件中进行功能迭代，都少不了去找一些类似的软件和功能进行研究，这个就叫竞品分析。&lt;/p&gt;
&lt;p&gt;竞品分析（Competitive Analysis）来源于商业和市场营销领域。指对目标客户群体中提供相似产品或服务的竞争对手的系统分析与研究。&lt;/p&gt;
&lt;p&gt;作为一个 B 端产品经理，在日常工作中也经常会需要进行竞品分析。下面谈谈我对竞品分析的一些理解。&lt;/p&gt;</description></item><item><title>B 端软件：产品经理正确打开方式</title><link>https://fwhyy.com/2023/08/the-correct-opening-method-for-the-b-end-software-product-manager/</link><pubDate>Wed, 02 Aug 2023 09:53:13 +0800</pubDate><guid>https://fwhyy.com/2023/08/the-correct-opening-method-for-the-b-end-software-product-manager/</guid><description>&lt;p&gt;早些年 B 端软件流行瀑布式开发，以给客户提供解决方案为目的，没有成熟的产品，以定制化的方式进行交付，这里面有一个重要的岗位衔接着客户和开发，就是：需求分析师。&lt;/p&gt;</description></item><item><title>怎样在 Github 中使用免密登录？</title><link>https://fwhyy.com/2023/07/how-to-use-password-free-login-in-github/</link><pubDate>Sun, 23 Jul 2023 09:49:05 +0800</pubDate><guid>https://fwhyy.com/2023/07/how-to-use-password-free-login-in-github/</guid><description>&lt;p&gt;我们在互联网上注册各种网站，密码经常会忘记，非常麻烦。以前还能各网站使用同一密码，虽然不太安全，但好记。现在各种网站的密码规则变强，还都不太一样，记密码就更难了。&lt;/p&gt;
&lt;p&gt;如果有一种方式，能免密登录，就可以解决记不住密码的烦恼了。&lt;/p&gt;</description></item><item><title>读《快速阅读术》</title><link>https://fwhyy.com/2023/07/reading-fast-reading-techniques/</link><pubDate>Wed, 19 Jul 2023 08:28:16 +0800</pubDate><guid>https://fwhyy.com/2023/07/reading-fast-reading-techniques/</guid><description>&lt;p&gt;1、我读书很慢，和这本书的作者一样，但这本书的作者现在能一天读一本，甚至是两本，让人很羡慕，所以我看了这本书，想学习下快速阅读的技巧。&lt;/p&gt;</description></item><item><title>B 端软件：信创、国产化知识梳理</title><link>https://fwhyy.com/2023/07/b-end-software-sorting-out-knowledge-on-innovation-and-localization/</link><pubDate>Tue, 11 Jul 2023 10:05:09 +0800</pubDate><guid>https://fwhyy.com/2023/07/b-end-software-sorting-out-knowledge-on-innovation-and-localization/</guid><description>&lt;p&gt;现在，做 ToB 软件，不管是跟客户沟通、内部会议、还是网上的资讯，经常会看到安可、信创、国产化这样的字眼。&lt;/p&gt;</description></item><item><title>B 端软件：常见知识梳理</title><link>https://fwhyy.com/2023/07/b-end-software-common-knowledge-sorting/</link><pubDate>Wed, 05 Jul 2023 17:49:40 +0800</pubDate><guid>https://fwhyy.com/2023/07/b-end-software-common-knowledge-sorting/</guid><description>&lt;p&gt;我一直从事企业级软件研发工作，也就是我们通常称之为 B 端软件。近年来，我的工作重心主要在研发低代码平台和 aPaaS 平台，这使我对 B 端软件有了更深入的理解。&lt;/p&gt;</description></item><item><title>Logseq：使用一年的感受</title><link>https://fwhyy.com/2023/06/the-feeling-of-using-logseq-for-a-year/</link><pubDate>Tue, 27 Jun 2023 10:45:05 +0800</pubDate><guid>https://fwhyy.com/2023/06/the-feeling-of-using-logseq-for-a-year/</guid><description>&lt;p&gt;去年 6 月 20 号写了一篇《Obsidian 初体验》，也就是从那时起，开始使用 Obsidian，随后不久，知道了 Logseq 这款软件，就同时使用 Obsidian 和 Logseq 。&lt;/p&gt;</description></item><item><title>内驱力</title><link>https://fwhyy.com/2023/06/talk-about-drive/</link><pubDate>Mon, 19 Jun 2023 09:25:55 +0800</pubDate><guid>https://fwhyy.com/2023/06/talk-about-drive/</guid><description>&lt;p&gt;最近在群里看到周筠老师征集小孩教育相关的问题，我第一个想到的问题就是：如何让孩子变得有内驱力？&lt;/p&gt;</description></item><item><title>银河麒麟系统安装中间件</title><link>https://fwhyy.com/2023/06/galaxy-kirin-system-installation-middleware/</link><pubDate>Mon, 12 Jun 2023 09:24:01 +0800</pubDate><guid>https://fwhyy.com/2023/06/galaxy-kirin-system-installation-middleware/</guid><description>&lt;p&gt;现在越来越多的企业级应用需要运行在国产化环境中，本文介绍下我们产品使用的中间件在国产操作系统银河麒麟的安装（不一定是最优方式，但能用）。&lt;/p&gt;</description></item><item><title>五月读的四本书</title><link>https://fwhyy.com/2023/05/four-books-read-in-may/</link><pubDate>Mon, 29 May 2023 14:21:44 +0800</pubDate><guid>https://fwhyy.com/2023/05/four-books-read-in-may/</guid><description>&lt;p&gt;我读书很慢，读书慢不是因为读的很认真仔细，而是读书太少，也就是阅读量不够，量不够，质就难以发生变化，跑步如此，读书也是。&lt;/p&gt;</description></item><item><title>做产品的思考</title><link>https://fwhyy.com/2023/05/tthinking-about-making-products/</link><pubDate>Mon, 22 May 2023 09:19:28 +0800</pubDate><guid>https://fwhyy.com/2023/05/tthinking-about-making-products/</guid><description>&lt;p&gt;在当今竞争激烈的市场中，如何打造出成功的产品是许多企业和团队关注的焦点。结合实际经验，我总结了一些值得关注的关于做产品思考的方面，希望能够为大家提供一些启示。&lt;/p&gt;</description></item><item><title>高可用：Nginx配合keepalived</title><link>https://fwhyy.com/2023/05/high-availability-nginx-combined-with-keepalived/</link><pubDate>Mon, 15 May 2023 12:07:12 +0800</pubDate><guid>https://fwhyy.com/2023/05/high-availability-nginx-combined-with-keepalived/</guid><description>&lt;p&gt;如果在谷歌中搜索 「Nginx 高可用」，搜索出来的大多都是 Nginx + keepalived 的使用。&lt;/p&gt;</description></item><item><title>高可用：MongoDB容器部署</title><link>https://fwhyy.com/2023/05/high-availability-mongodb-container-deployment/</link><pubDate>Mon, 08 May 2023 12:04:42 +0800</pubDate><guid>https://fwhyy.com/2023/05/high-availability-mongodb-container-deployment/</guid><description>&lt;p&gt;MongoDB 是一款 NoSQL 数据，通常用来存储非结构化数据，我们的产品中也有用到，例如：一些文件存储在 MongoDB 的 GridFS 中。&lt;/p&gt;</description></item><item><title>读《持续架构实践》</title><link>https://fwhyy.com/2023/04/read-continuous-architecture-practices/</link><pubDate>Wed, 26 Apr 2023 11:56:13 +0800</pubDate><guid>https://fwhyy.com/2023/04/read-continuous-architecture-practices/</guid><description>&lt;p&gt;之前看到过一种言论，说相比互联网产品，做 ToB 产品没有那么大的业务量，也没有那么多的用户量，所以非功能性的需求没那么重要，重要的还是业务。&lt;/p&gt;</description></item><item><title>等了 20 年的全国大赛</title><link>https://fwhyy.com/2023/04/the-first-slam-dunk-national-tournament/</link><pubDate>Sat, 22 Apr 2023 18:02:35 +0800</pubDate><guid>https://fwhyy.com/2023/04/the-first-slam-dunk-national-tournament/</guid><description>&lt;p&gt;五一前的最后一个休息日，全家人一起去电影院看了《灌篮高手》，这场等待了 20 年的全国大赛。&lt;/p&gt;
&lt;p&gt;TV 版中只记得宫城良田是一个小个子后卫，在湘北五虎中并不是很重要的角色，而天才樱木才是主角。但电影中是以宫城良田的故事开始、最终也以宫城和泽北进入 NBA 结尾。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;相比樱木，宫城更接地气，身高对于打篮球来说算是劣势了，靠着自己的苦苦练习，才成为一名出色的后卫。而樱木是天才，天赋异禀，走到哪里都有奇迹的发生。主角从樱木到宫城，这或许是井上雄彦这么多年自己心境的变化。&lt;/p&gt;
&lt;p&gt;一场比赛，五个人在逆境中都有了变化和成长，宫城走出了哥哥的阴影，打破了心理障碍，在场上还聚集队友，布置战术，颇有领袖风范；流川枫可以分享球了，而且还是传了给不对付的樱木；手都抬不起来的三井仍然投出一个个精准的三分球；一直是球队领袖的赤木虽然面对河田有过胆怯，最终也觉醒得分盖帽两不误；樱木靠着自己的意志力和出色的天赋频频救球队于危难之中。&lt;/p&gt;
&lt;p&gt;很精彩的比赛！很好的电影！&lt;/p&gt;</description></item><item><title>分享几个网站和工具（202304）</title><link>https://fwhyy.com/2023/04/share-some-website-and-tools-202304/</link><pubDate>Mon, 17 Apr 2023 11:48:31 +0800</pubDate><guid>https://fwhyy.com/2023/04/share-some-website-and-tools-202304/</guid><description>&lt;p&gt;最近又收集了一些工具和站点，其中部分和 ChatGPT 有关。&lt;/p&gt;</description></item><item><title>由 ChatGPT 带来的对低代码产品的思考</title><link>https://fwhyy.com/2023/04/thinking-about-low-code-products-brought-about-by-chatgpt/</link><pubDate>Thu, 13 Apr 2023 11:42:00 +0800</pubDate><guid>https://fwhyy.com/2023/04/thinking-about-low-code-products-brought-about-by-chatgpt/</guid><description>&lt;p&gt;在之前的文章中多次提到我们在开发一款低代码平台，主要面向 ToB 企业，帮助企业完善信息化建设，给企业的数字化转型贡献一份力量。&lt;/p&gt;</description></item><item><title>读《认识AI》</title><link>https://fwhyy.com/2023/04/read-ai/</link><pubDate>Mon, 03 Apr 2023 11:38:15 +0800</pubDate><guid>https://fwhyy.com/2023/04/read-ai/</guid><description>&lt;p&gt;1、最近 ChatGPT 越来越热，都已经到了马斯克等千人签署公开信，呼吁暂停开发更强大的AI系统，担心人工智能开发危及「文明控制权」，而我这个 AI 小白决定要系统性的学习下 AI 相关知识了。&lt;/p&gt;</description></item><item><title>Docker日志大小限制和切换存储目录</title><link>https://fwhyy.com/2023/03/docker-log-size-limits-and-switching-storage-directories/</link><pubDate>Tue, 28 Mar 2023 11:35:16 +0800</pubDate><guid>https://fwhyy.com/2023/03/docker-log-size-limits-and-switching-storage-directories/</guid><description>&lt;p&gt;产品的各种环境使用了很多 &lt;code&gt;CentOS&lt;/code&gt; 虚拟机，默认情况下 &lt;code&gt;root&lt;/code&gt; 目录空间是 50 G，随着使用时间越来越长，空间会变得不够用。&lt;/p&gt;</description></item><item><title>dotNET 升级利器：Upgrade Assistant</title><link>https://fwhyy.com/2023/03/dotnet-upgrade-assistant/</link><pubDate>Mon, 20 Mar 2023 11:29:39 +0800</pubDate><guid>https://fwhyy.com/2023/03/dotnet-upgrade-assistant/</guid><description>&lt;p&gt;.NET 发展很快, 现在 .NET 8 的预览版已经发布了，但我们现在还在使用 .NET Core 3.1，将 .NET 升级到 .NET 6 已经势在必行。&lt;/p&gt;</description></item><item><title>GPT-4 有什么不一样？</title><link>https://fwhyy.com/2023/03/gpt-4/</link><pubDate>Wed, 15 Mar 2023 11:19:15 +0800</pubDate><guid>https://fwhyy.com/2023/03/gpt-4/</guid><description>&lt;p&gt;一觉醒来，GPT-4 发布了。&lt;/p&gt;
&lt;p&gt;GPT-4 和 GPT-3.5 都是由 OpenAI 开发的大型自然语言处理模型，它们能够理解和生成人类语言。尽管这两个模型在很多方面都相似，但它们之间还是存在一些关键区别：&lt;/p&gt;</description></item><item><title>ChatGPT 应用合集</title><link>https://fwhyy.com/2023/03/chatgpt-app-collection/</link><pubDate>Mon, 13 Mar 2023 10:26:54 +0800</pubDate><guid>https://fwhyy.com/2023/03/chatgpt-app-collection/</guid><description>&lt;p&gt;最近用了一些 ChatGPT 的周边产品，挑几个感觉不错的分享下。&lt;/p&gt;</description></item><item><title>读《沸腾十五年》</title><link>https://fwhyy.com/2023/03/read-boiling-for-fifteen-years/</link><pubDate>Thu, 09 Mar 2023 10:24:40 +0800</pubDate><guid>https://fwhyy.com/2023/03/read-boiling-for-fifteen-years/</guid><description>&lt;p&gt;《沸腾十五年》记录了中国互联网行业从 1995 年到 2009 年的发展历程，深入探讨了互联网行业的商业模式、技术发展、市场竞争等方面的问题，讲述了一群热血青年使用技术改变世界的故事。&lt;/p&gt;</description></item><item><title>使用微软的 New Bing</title><link>https://fwhyy.com/2023/03/try-microsoft-new-bing/</link><pubDate>Mon, 06 Mar 2023 08:13:47 +0800</pubDate><guid>https://fwhyy.com/2023/03/try-microsoft-new-bing/</guid><description>&lt;p&gt;ChatGPT 现在大家都已经非常熟悉了了，走到哪都能听到讨论的声音，是基于 GPT3.5 的一个语言模型。微软在 2 月推出的新必应（New Bing）是一个基于 GPT4（猜测）模型的搜索和聊天工具，它可以提供更准确和实时的搜索结果，并且集成了Edge 浏览器的数据资源。&lt;/p&gt;
&lt;p&gt;最近申请了 New Bing 简单试用 ，觉得还挺不错的。&lt;/p&gt;
&lt;h2 id="申请"&gt;申请&lt;/h2&gt;
&lt;p&gt;可以按照下面的步骤来进行新必应（New Bing）的申请：&lt;/p&gt;
&lt;p&gt;1、先下载并安装 Edge 浏览器 dev 版本，在：&lt;a href="https://www.microsoftedgeinsider.com/zh-cn/download/dev"&gt;Microsoft Edge 预览体验成员 (microsoftedgeinsider.com)&lt;/a&gt; 进行下载安装：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008420.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、打开浏览器的设置-&amp;gt;关于，可以进行 New Bing 使用的申请：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008517.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、登录后加入候补名单：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008380.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4、然后就是等待，很幸运，一天的时间就通过了申请，使用界面如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008300.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="基础使用"&gt;基础使用&lt;/h2&gt;
&lt;p&gt;New Bing 的主题功能分为聊天、撰写和见解。&lt;/p&gt;
&lt;h3 id="聊天"&gt;聊天&lt;/h3&gt;
&lt;p&gt;和 ChatGPT 类似，使用问答的形式进行交互，除了基础的输入框进行提问外，还能设置响应的语气。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008948.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="撰写"&gt;撰写&lt;/h3&gt;
&lt;p&gt;将文字的创作单独剥离出来，提供更多的配置选项，更方便使用：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008833.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="特点"&gt;特点&lt;/h2&gt;
&lt;h3 id="实时性"&gt;实时性&lt;/h3&gt;
&lt;p&gt;在聊天功能中，虽然和 ChatGPT 一样都是问答的模式，但它可以实时访问网络数据，找到 ChatGPT 没见过的数据，更加实时。&lt;/p&gt;
&lt;p&gt;例如：我们分别让 New Bing 和 ChatGPT 评价下春节档的电影《满江红》就能看出区别了。&lt;/p&gt;
&lt;p&gt;ChatGPT 并不知道春节上映的电影《满江红》，因为它的语言模型是 2021 年训练的，但可怕的是 ChatGPT 并不知道自己不知道，仍然会胡说八道一通。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008681.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;而在 New Bing 中，能够搜索到最新的信息，还能给出出处链接：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008192.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h3 id="互动性"&gt;互动性&lt;/h3&gt;
&lt;p&gt;在问答的过程中 ，New Bing 会给出一些推荐的关键词来和我们进行互动，我们可以通过给出的关键词进一步和 New Bing 进行互动，也可以自己输入新的问题。&lt;/p&gt;
&lt;h3 id="准确性"&gt;准确性&lt;/h3&gt;
&lt;p&gt;New Bing 会根据你提的问题结合搜搜引擎和基础语言模型，最终组成答案进行输出，而且在答案中会给出来源出处，点击链接可以进入到原始网页进行查看。&lt;/p&gt;
&lt;h3 id="文章总结"&gt;文章总结&lt;/h3&gt;
&lt;p&gt;在网页中打开一篇文章，可以让 New Bing 来协助我们进行阅读，总结文章的内容。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306191008153.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="遗憾"&gt;遗憾&lt;/h2&gt;
&lt;p&gt;1、2 月 18 日，微软通过官方博客宣布，基于 AI 的新版必应对话功能将加入问答限额，每天最多回答 50 次问题，每次连续对话最多回答 5 个问题。微软称，根据统计，绝大多数用户都能在 5 轮问答内找到满意答案，只有大约 1% 的对话产生超过 50 条消息；定期清除对话记录有助于避免模型产生混淆。&lt;/p&gt;
&lt;p&gt;2、回答的效果上好像也做了些调整，变得相对严肃，记得刚出来时，看了 B 站一个视频，它的风格是这样的：&lt;/p&gt;</description></item><item><title>ChatGPT 是什么？越来越清晰了</title><link>https://fwhyy.com/2023/02/what-is-chatgpt-its-getting-clearer/</link><pubDate>Tue, 21 Feb 2023 08:09:55 +0800</pubDate><guid>https://fwhyy.com/2023/02/what-is-chatgpt-its-getting-clearer/</guid><description>&lt;p&gt;两个月前，ChatGPT 刚出来不久，我便注册试用了，在《尝鲜 ChatGPT》中介绍了注册的过程和简单使用的示例。&lt;/p&gt;
&lt;p&gt;最近，ChatGPT 越来越火了，朋友圈、公众号、微博、即刻随处可见关于 ChatGPT 的信息。我也看了不少关于 ChatGPT 的文章，一些疑问也得到解答。&lt;/p&gt;
&lt;h2 id="活跃用户"&gt;活跃用户&lt;/h2&gt;
&lt;p&gt;ChatGPT 用 2 个月达到月活用户 1 亿，此前记录是 TikTok 用时 9 个月，很多新闻中都提到了这个 1 亿用户来吸引眼球。&lt;/p&gt;
&lt;p&gt;需要说明的是，这里的月活用户不是指注册用户，可能还包含爬虫、游客等。即便如此，我认为也不会是一个很少的数量级，加上最近各大媒体报道，各种注册服务的推出，估计也差不太多。&lt;/p&gt;
&lt;p&gt;关于用户，大辉的这篇文章有详细讲述：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mp.weixin.qq.com/s/iBmJEa4AzZKSO4nfKtCZDQ"&gt;https://mp.weixin.qq.com/s/iBmJEa4AzZKSO4nfKtCZDQ&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="和搜索引擎的对比"&gt;和搜索引擎的对比&lt;/h2&gt;
&lt;p&gt;ChatGPT 的使用方式是面向一个文本框，用提问来进行交互；搜索引擎也是一个文本框，通过输入关键字来进行检索。看着很类似，其实有很大差别。&lt;/p&gt;
&lt;p&gt;有几个重要的区别是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ChatGPT 因为训练一次，费用昂贵，所以 ChatGPT 不是实时的，而搜索引擎的时效性很高；&lt;/li&gt;
&lt;li&gt;ChatGPT 是基于语义分析，搜索引擎是基于关键字索引；&lt;/li&gt;
&lt;li&gt;ChatGPT 会给一个最优解，搜索引擎的结果为多条符合关键字匹配的内容，我们需要自己对结果进行分析、辨别，然后对比、合并、重新理解，最终得到一个答案；&lt;/li&gt;
&lt;li&gt;ChatGPT 可以基于上下文进行追问，让他知道我们的真实需求，结果也会不断进行优化，搜索引擎只能调整关键字，得到新的结果；&lt;/li&gt;
&lt;li&gt;ChatGPT 仅仅是个结果，搜索引擎会有来源链接。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不管是 ChatGPT 还是搜索引擎，都是辅助我们的工具，这两者不是对立的，而是各有各的使用场景。&lt;/p&gt;
&lt;p&gt;例如：我要查询天气、看看日历、行业最新资讯等，我肯定用搜索引擎；如果我要写一个很特殊的正则表达式或 Sql ，我就会使用 ChatGPT ，因为我可以通过一大段描述，将我的场景写清楚，ChatGPT 可以理解并给出一个还不错的答案，甚至是一个开箱即用的答案。&lt;/p&gt;
&lt;h2 id="是否能取代程序员"&gt;是否能取代程序员？&lt;/h2&gt;
&lt;p&gt;记得在低代码比较火热的时候，就有低代码平台是否会跟程序员抢饭碗的话题。几年前，我们去给客户推荐我们的产品，一些有研发能力的客户会比较抵触。&lt;/p&gt;
&lt;p&gt;现在 ChatGPT 火了，大家又开始讨论程序员是不是会被取代？&lt;/p&gt;
&lt;p&gt;上面我也说到，和搜索引擎一样，ChatGPT 只是一个工具，既然是工具就会被人所使用，是为了提高人的创造力和生产力，为我们服务的。&lt;/p&gt;
&lt;p&gt;举两个例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;农业机械化生产后，拿着锄头到地里干活的人少了，但会需要操作机器的人；&lt;/li&gt;
&lt;li&gt;低代码流行后，落地一个项目，需要的程序员变少了，但会需要更多的配置和搭建的人员，相比程序员，这些人员的成本更低；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ChatGPT 也是一样，无论怎么发展，只要利用好，效率会成百上千倍的增长，并且会滋生出来很多新的职业和岗位。&lt;/p&gt;
&lt;p&gt;程序员的日常工作就是把人的诉求通过编程语言表达出来传递给电脑，电脑运算出结果，而 ChatGPT 能够分析语义，这让人的诉求到电脑能够理解这个过程变得容易了，这也就是为什么王建硕会说未来十年中国会新增五亿程序员了，因为借助工具，更多的人都能更电脑进行交互了。&lt;/p&gt;
&lt;h2 id="我们该做些什么"&gt;我们该做些什么？&lt;/h2&gt;
&lt;p&gt;一个新的技术出来，有这么三类人：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;找到缝隙，赢得先机，狠狠地赚一笔；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;杞人忧天，各种担心；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;利用好技术，提升效率。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ChatGPT 因为在国内注册不方便，就有人专门做了收费服务，帮助注册，据说一个月赚几十万。也有人还在想着自己会不会被取代，对我而言，我把 ChatGPT 当成一个效率工具，使用好他就可以了。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;ChatGPT 是一个开始，可能还会带来革命性的改变。就像蒸汽机引发了工业革命，改变人类的生产方式、浏览器的诞生催生了互联网的发展；乔布斯发布 iPhone 后，宣告了移动互联网的来临。&lt;/p&gt;
&lt;p&gt;但在眼下，我们可以做些力所能及的，比如：将 ChatGPT 集成到微信群，尝试使用下微软发布的 New Bing 。&lt;/p&gt;
&lt;p&gt;未来是什么样，拭目以待。&lt;/p&gt;</description></item><item><title>公众号新的图片消息功能</title><link>https://fwhyy.com/2023/02/wechat-image-message-feature/</link><pubDate>Fri, 17 Feb 2023 22:49:20 +0800</pubDate><guid>https://fwhyy.com/2023/02/wechat-image-message-feature/</guid><description>&lt;p&gt;周末愉快！&lt;/p&gt;
&lt;p&gt;昨天发布文章的时候，发现公众号后台添加了新的图片消息功能，在移动端用画廊的形式展示图片。发一篇来自尝鲜下。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;去年 7 月，三个人，一台车，开启了 318 的自驾之旅，现在想想，真的是很幸运，完美地避开了疫情，画廊中的照片就来自于 318 。&lt;/p&gt;
&lt;p&gt;阳康后，一个多月没有跑步，浑身难受，体重也增加了不少，最近又开始跑步了，状态也在慢慢地恢复，因为跑步，又开始早睡早起，让我这坚持了一年多的习惯得以延续。&lt;/p&gt;
&lt;p&gt;久违的汉马今年也终于能线下比赛了，因为有之前的保留名额，中签率变得更低了，为了在这极低的中签率中提高一点点几率，报了全马，希望能有幸运降临。&lt;/p&gt;
&lt;p&gt;公众号的写作，自从不设置每周一篇的限制后，反倒是写的更多了，也不用担心没有内容可写。只要是有输入、在思考，总会碰撞出一些知识的碎片，稍加整理就能成文。而且现在心态也有些变化，首先是写给自己，如果还能对读者有所帮助，那就更好了。&lt;/p&gt;
&lt;p&gt;豆瓣上收到一月份的书影音小结，居然看了四部电影，读了四本书，对读书来说，不再立 Flag ，要相信习惯的力量。&lt;/p&gt;
&lt;p&gt;疫情全面放开后，一切都在慢慢变好，就像我上面提到的这些。&lt;/p&gt;
&lt;p&gt;所以，2023，我充满信心！&lt;/p&gt;</description></item><item><title>深入接触客户才能做出好的产品</title><link>https://fwhyy.com/2023/02/deep-contact-with-customers-can-make-good-products/</link><pubDate>Fri, 17 Feb 2023 08:07:22 +0800</pubDate><guid>https://fwhyy.com/2023/02/deep-contact-with-customers-can-make-good-products/</guid><description>&lt;p&gt;近些年一直在负责开发低代码平台产品，面向的是企业用户，这款产品一方面给公司内部使用，提升项目交付效率，另一方面，一些合作伙伴或有开发能力的甲方，可以借助我们的产品进行系统的开发，给业务部门使用。&lt;/p&gt;
&lt;p&gt;产品的定位非常明确，能够提升交付效率，协助企业进行数字化转型。&lt;/p&gt;
&lt;p&gt;正因为是面向企业用户，所以产品的功能增加不能闭门造车，需要深入地接触客户，了解他们的痛点和诉求，再反向体现到产品功能上。&lt;/p&gt;
&lt;p&gt;前些天，和公司销售一起拜访了几家公司的重点客户，有些感触。&lt;/p&gt;
&lt;h2 id="开始注重效率"&gt;开始注重效率&lt;/h2&gt;
&lt;p&gt;记得早些年做企业的信息化建设，更多的是注重将线下办公搬到线上，现在大多数企业已经是在线上办公，就更注重提升整体的流程效率。&lt;/p&gt;
&lt;p&gt;企业的增效体现在很多方面，这里主要说的是流程方面的效率，客户其实是很有想法的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;纵向上，按照业务线，将跨不同系统的流程进行拉通，会涉及到各种对接、集成；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;横向上，以某个业务点进行扩散，找出关联业务数据进行展示。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;信息化、工作流尽管做了很多年，我感觉还是能挖掘出很多对客户有价值的功能。&lt;/p&gt;
&lt;p&gt;针对流程本身来说，也可以通过数据的支撑反向找出效率的瓶颈点，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;设置超时阈值，从流程到节点到组织和人，找出耗时长的任何事，通过监督来提升效率；&lt;/li&gt;
&lt;li&gt;通过流程的通过率，可以找出表单设计或流程设计上的不合理，然后进行优化；&lt;/li&gt;
&lt;li&gt;如果有些节点通过率 100%，而且几乎不耗时，这种节点可能没有存在的必要；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除此之外，现在还有专门的公司做 RPA 流程机器人和对流程数据的 AI 智能分析，如何将这些工具和现有的流程平台进行融合，也是值得思考的。&lt;/p&gt;
&lt;h2 id="数据驱动业务"&gt;数据驱动业务&lt;/h2&gt;
&lt;p&gt;随着客户信息化越来越成熟，各类系统中都产生了大量的数据。怎样让这些数据能活起来，为企业所用，这是客户很关注的问题。&lt;/p&gt;
&lt;p&gt;一些有开发能力的客户已经在在自己做数据层的东西，底层构建数据仓库，上层提供图形化展示。&lt;/p&gt;
&lt;p&gt;现在很多的低代码平台中都提供有 BI 模块，大多数都是展示层，我们的产品中也有对应的模块，相比较专业 BI 产品，功能还是偏弱。为什么都喜欢做数据展示？首先是技术难度不是很高，但更重要的是领导喜欢看大屏展示，最终决策、掏钱的是领导。&lt;/p&gt;
&lt;p&gt;在低代码产品中，我认为重要的是能扩展和集成，产品本身不适合在这方面去发力。一个产品如果什么都想做，最终什么都做不好。做自己擅长的事情，然后集各家所长，必能成事，做产品如此，做人也是。&lt;/p&gt;
&lt;h2 id="信息孤岛问题依然存在"&gt;信息孤岛问题依然存在&lt;/h2&gt;
&lt;p&gt;大型国企现在还存在信息孤岛问题，这个是我没有想到的。&lt;/p&gt;
&lt;p&gt;传统企业的信息做了好多年了，10 年前跟客户宣讲，都在说要解决信息孤岛问题。这么多年过去，还是有很多企业忙于解决各种问题，上了几十上百套系统，但系统之间还没有很好地进行联通，甚至连基本的待办消息集成都没有做。&lt;/p&gt;
&lt;p&gt;在低代码产品中，添加 SSO、组织机构同步、消息接入等已经算是标配了。但要做好集成不是件容易的事情，涉及到很多利益方，搞定了人，才能搞定事。&lt;/p&gt;
&lt;h2 id="客户更希望在整体规划上能提供指导"&gt;客户更希望在整体规划上能提供指导&lt;/h2&gt;
&lt;p&gt;最近在一个视频号听一个大佬讲：技术人员的一个终极梦想就是做架构师 ，相比技术架构，现在售前架构师、企业解决方案架构师越来越吃香。&lt;/p&gt;
&lt;p&gt;原因就是，客户也不知道要做啥？怎么做？提出的都是一些很宏观的目标，或者直接让提供相关的规划方案。&lt;/p&gt;
&lt;p&gt;这其实对售前的要求非常高，要懂客户的行业，了解他们的痛点，能提供解决方案，这样就能牵着客户走，也能得到客户的信任，这种信任会为后续的项目实施带来极大的便利。&lt;/p&gt;
&lt;p&gt;反之，在客户不清楚自己想要什么的情况下，售前还只是听客户讲，拿笔记录，最终交付的东西，客户总是认为不是自己想要的，而我们就会埋怨客户总是在进行需求变更。这种情况下，极少数是客户故意刁难，大多数都是没有真正理解客户的意图导致。&lt;/p&gt;
&lt;p&gt;因为样本足够小，以上可能都是错的。&lt;/p&gt;</description></item><item><title>代码提交那点事</title><link>https://fwhyy.com/2023/02/code-commits-that-little-thing/</link><pubDate>Mon, 13 Feb 2023 09:46:06 +0800</pubDate><guid>https://fwhyy.com/2023/02/code-commits-that-little-thing/</guid><description>&lt;p&gt;现在，代码的版本管理大多都在使用 git，常用的一些代码托管平台有：Github、码云、Gitlab 等，不管用的哪个平台，我们经常会做提交代码的操作，但很容易忽视 commit message 的写法。&lt;/p&gt;</description></item><item><title>我的博客换成了 NotionNext</title><link>https://fwhyy.com/2023/02/my-blog-use-notion-next/</link><pubDate>Mon, 06 Feb 2023 09:43:24 +0800</pubDate><guid>https://fwhyy.com/2023/02/my-blog-use-notion-next/</guid><description>&lt;p&gt;在《程序员不可错过的一款Hexo博客主题》中介绍了我博客的主题 stellar ，还介绍了部署方式的调整：&lt;/p&gt;</description></item><item><title>2023 关键词：做减法</title><link>https://fwhyy.com/2023/01/2023-keyword-do-subtraction/</link><pubDate>Sun, 22 Jan 2023 07:25:50 +0800</pubDate><guid>https://fwhyy.com/2023/01/2023-keyword-do-subtraction/</guid><description>&lt;p&gt;今天是 2023 年 1 月 21 日，农历癸卯年正月初一，新的一年开始了，祝大家：兔年大吉、大展宏兔、兔然暴富。&lt;/p&gt;
&lt;p&gt;很多人都有一个惯性思维就是做加法，这样会比较“心安”，比如：看更多的书、学习更多的课程、让小孩刷更多的题、产品上添加更多的功能，似乎，多就是好。&lt;/p&gt;
&lt;p&gt;为什么都爱做加法呢？&lt;/p&gt;
&lt;p&gt;在少楠的知识资产中看到，人们爱做加法的原因多半是出于：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;首先，我们默认在日常的事物中一切都是「合理」的，不需要减少。比如我们很少会怀疑教科书上有「冗余」的内容，或者使用的工具有什么「多余」的部分。&lt;/p&gt;
&lt;p&gt;再次，损失厌恶。毕竟做加法没有什么损失，但是如果要做减法，就得做出断舍离的决策。所以人们默认会倾向于获得更多，而不是舍弃一些。&lt;/p&gt;
&lt;p&gt;最后，做加法的效果容易感知，比如多读了一本书，多记了一条笔记，那么很容易感觉到「积累」。但如果少看了一本烂书，删掉了一些无用的东西，这种「减法」的好处很难直观地感受到。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;而我决定在 2023 年要做减法，做减法可比做加法难多了，意味着要有更多的思考、更多的断舍离。&lt;/p&gt;
&lt;p&gt;这个减法可以体现在很多方面，比如：个人成长、产品功能、代码架构。&lt;/p&gt;
&lt;h2 id="个人成长"&gt;个人成长&lt;/h2&gt;
&lt;p&gt;现在信息摄入的途径和内容都非常多，眼花缭乱。要很笃定的知道自己需要什么，然后把信息消化吸收后变成自己的养分。&lt;/p&gt;
&lt;p&gt;所以，这里的减法是指内容的处理和消化。只吸收不消化，跟捡垃圾没什么区别。&lt;/p&gt;
&lt;p&gt;枝叶需要进行修剪才能长得茂盛、铁路线越来越多，也需要合理规划、并站才能高效地进行调度，所以信息的获取不能一味的进行增加，还需要我们抽出来时间进行修剪，把核心的连接加强，把无用的节点删除或合并，才能让我们信息慢慢转化为自己的知识。&lt;/p&gt;
&lt;p&gt;现在我的信息摄入途径有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;书籍：纸质书、电子书、樊登读书、读库；&lt;/li&gt;
&lt;li&gt;社交媒体：即刻、知乎、豆瓣、B 站、小宇宙；&lt;/li&gt;
&lt;li&gt;专业 APP：极客时间、得到；&lt;/li&gt;
&lt;li&gt;其他：公众号文章、订阅的 RSS 和 Newsletter 。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2023 我想这样来做减法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不设置读书目标，养成每天都看半个小时或一个小时的习惯；&lt;/li&gt;
&lt;li&gt;看过的内容要思考做笔记和回顾；&lt;/li&gt;
&lt;li&gt;尽可能地多输出、多和不同的人交流；&lt;/li&gt;
&lt;li&gt;定期梳理笔记、抽取主题、形成文章。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;个人成长的减法并不是说减少输入的途径，而是增加中间的处理和思考的过程，让积累的东西慢慢变少，沉淀出来自己的东西慢慢变多。&lt;/p&gt;
&lt;h2 id="产品功能"&gt;产品功能&lt;/h2&gt;
&lt;p&gt;做产品也是一样，要做减法，很多时候冷静思考，沉寂一段时间后，发现很多原先紧急的需求都可以不用做了。&lt;/p&gt;
&lt;p&gt;为产品做减法，首先就是要搞清楚产品的定位。&lt;/p&gt;
&lt;p&gt;定位不准确，就很容易什么功能都相加，加到最后就变成四不像了，看着什么功能都有，但又什么功能没有做到极致，甚至互相之间还是矛盾的。&lt;/p&gt;
&lt;p&gt;假如产品的定位就是做一个给开发人员提升效率的低代码平台，明确了这个目标，就很容易知道哪些是可以不做的，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;完全配置化，不考虑二开；&lt;/li&gt;
&lt;li&gt;按业务人员使用的视角去设计产品功能。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;哪些是需要做的也很清晰：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能减轻开发的重复性的操作实现配置化；&lt;/li&gt;
&lt;li&gt;提供各种批量操作，比如批量修改表单控件的属性；&lt;/li&gt;
&lt;li&gt;提供二开的辅助调试工具，自定义组件、在线脚本能够更好地进行对接和排错。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;产品功能的减法不是说啥功能也不做了，而是搞清楚哪些是可以不做的，该做的还是要按照正常的节奏去迭代。&lt;/p&gt;
&lt;h2 id="代码架构"&gt;代码架构&lt;/h2&gt;
&lt;p&gt;在产品的代码构架上会存在两个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;初学者使用复杂的架构解决简单的问题，而出现学以致用的幻觉；&lt;/li&gt;
&lt;li&gt;因为各种「紧急」，而在项目中添加各种临时补丁或重复代码，这些通常被称为「技术债」，这些「技术债」会在以后有时间就处理，正常情况以后都不会有时间。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;越简单的东西越容易理解，越不容易出错，所以在产品架构中要避免出现过度设计，架构方案需要进行评审。&lt;/p&gt;
&lt;p&gt;上面提到的技术债，其实也是有时间处理的，比如，你们采用的是敏捷开发模式，在一个迭代周期内，所有人都是为这个迭代目标而冲刺，那么在迭代版本发布前，某些开发人员的开发任务已经完成，除了可以参与测试之外，就可以处理这些「技术债」。&lt;/p&gt;
&lt;p&gt;代码架构的减法是通过这个减法让产品代码始终保持一种合理的架构，毕竟，合适的才是最好的。&lt;/p&gt;
&lt;h2 id="最后"&gt;最后&lt;/h2&gt;
&lt;p&gt;加法容易，减法难，那么我们选择难的这条路，必然会结出更艳丽的果实。而你也会因为走了这条难的路而更加光彩夺目。&lt;/p&gt;</description></item><item><title>2023 年总结（工作）</title><link>https://fwhyy.com/2023/01/2023-work-summary/</link><pubDate>Thu, 19 Jan 2023 15:47:06 +0800</pubDate><guid>https://fwhyy.com/2023/01/2023-work-summary/</guid><description>&lt;p&gt;涂总，您好！提前祝您春节快乐。&lt;/p&gt;
&lt;p&gt;组织架构的调整，使得我对产品的定位以及产品部门的职责变得非常清晰，前所未有的清晰。&lt;/p&gt;
&lt;!-- more --&gt;
&lt;p&gt;最近一直在思考现有的问题和来年的规划，以邮件的形式跟涂总您分享下。&lt;/p&gt;
&lt;h2 id="现状"&gt;现状&lt;/h2&gt;
&lt;p&gt;1、目标一致性问题&lt;/p&gt;
&lt;p&gt;目标如果不一致，所有的方向都很使劲，但会停留在原地。&lt;/p&gt;
&lt;p&gt;2022 年上半年，项目的需求到不了我这里，而我们做的事情对项目的落地和增效又没有任何帮助。&lt;/p&gt;
&lt;p&gt;项目组的需求得不到响应会有两个后果：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目要想各种变通的方式来实现功能，花更长的时间；&lt;/li&gt;
&lt;li&gt;变通的方式可能不是客户想要的方式，客户的体验差，这些日积月累的不好的体验可能就是日后投诉的根源。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;甚至一些个别项目禁止使用二开，采用完全搭建的方式来实现，满足不了的地方需要借助一些第三方工具，这些工具都有学习成本，最终结果就是实施周期变长。&lt;/p&gt;
&lt;p&gt;2、搭配问题&lt;/p&gt;
&lt;p&gt;人无完人，我们需要充分利用每个人的长处，这样就可以拼成任正非所说的「高桶」。&lt;/p&gt;
&lt;p&gt;元旦后，我被琪雅拉进了葛洲坝路桥的项目群，目的是要做技术支撑，经过几天的紧急问题处理和事后的分析复盘，发现了一些问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;项目的顶层设计出现问题，交付给客户的是一个考评系统，互相交叉评价会产生大量的数据，没有提前预判；&lt;/li&gt;
&lt;li&gt;技术上错误地使用数据库触发器，导致大量的表死锁，导致考评数据的生成不及时、客户使用过程中频繁出错；&lt;/li&gt;
&lt;li&gt;不得不中途修改方案，这是项目实施大忌；&lt;/li&gt;
&lt;li&gt;项目组成员非常幸苦，元旦假期加班、周末加班、工作日也每天晚上很晚还要响应客户的问题。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;让本来不到一周就能顺利完成的事情，最终花了两周多的时间。&lt;/p&gt;
&lt;p&gt;我在想，项目是不是应该分下类型，适合一线人员做项目经理的，就由一线人员担任；适合二线人员做项目经理的，那就应该让二线人员来担任？&lt;/p&gt;
&lt;p&gt;每个人还是要在适合的位置，才能发光发热。&lt;/p&gt;
&lt;p&gt;3、加减法问题&lt;/p&gt;
&lt;p&gt;做加法的效果容易感知，比如多读了一本书，多记了一条笔记，那么很容易感觉到「积累」。&lt;/p&gt;
&lt;p&gt;正是因为这种思想，产品上会不停地加功能，说好听点，产品功能非常丰富，说不好听的，臃肿，易用性差。&lt;/p&gt;
&lt;p&gt;那产品应不应该加功能呢？答案是肯定的。产品团队肯定要按照节奏去迭代产品，但出发点是以项目落地增效为导向、以一线实施人员的使用痛点为导向、以最终用户的用户体验为导向。&lt;/p&gt;
&lt;p&gt;以这些为导向，那产品的迭代就不完全是功能的叠加，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;解决用户实际问题的功能的增加；&lt;/li&gt;
&lt;li&gt;某些功能使用体验的优化；&lt;/li&gt;
&lt;li&gt;某些淘汰功能的弱化甚至删减。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4、复用问题&lt;/p&gt;
&lt;p&gt;在代码架构中经常说要提升代码的复用性，目的就是为了提升效率。&lt;/p&gt;
&lt;p&gt;在 2022 年了解到存在升级难、迁移难的问题。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;葛洲坝事务系统花了很大精力做完，需要迁移到其他项目，有大量的改造工作，接近重做；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;省厅的项目想要迁移到其他地方，也几乎不可能，或者说需要花费大量的精力；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;江铃从版本 6 是升级到 7，前前后后花了好几个月。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多项目应该是能盈利的，但因为升级和迁移的不顺畅，最终可能导致赚不了钱，甚至亏损。&lt;/p&gt;
&lt;p&gt;我认为这一部分也应该作为产品团队 2023 年工作的重点。&lt;/p&gt;
&lt;h2 id="2023-规划"&gt;2023 规划&lt;/h2&gt;
&lt;p&gt;目标清晰了，事情就好办了，剩下的就交给时间，静待花开。&lt;/p&gt;
&lt;p&gt;根据涂总的的指示，我理解的产品部职责如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作为项目落地的强有力支撑；&lt;/li&gt;
&lt;li&gt;项目资源不足，产品优先支持响应；&lt;/li&gt;
&lt;li&gt;产品功能的迭代必须是能提升项目落地效率、提升用户体验。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目标明确，所以，2023 ，我非常有信心。&lt;/p&gt;
&lt;p&gt;年前跟团队的每个人面谈时，我说我们应该往一个终极目标去努力，就是将 S2 交付给一线或二线之后，他们不会来找我们了，这样，我们可以做更重要的事情。&lt;/p&gt;
&lt;p&gt;这个不找不是说部门之间有墙的屏蔽，而且他们自己在实施和运维的过程中碰到问题，可以自己找到答案。&lt;/p&gt;
&lt;p&gt;当然，达到这个目标很难，可以先从下面的一些方面先入手：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;收集一线人员的想法，他们跟客户直接接触，能更清楚客户的问题和习惯，以此来反推需求（已经跟一二线人员做了座谈）；&lt;/li&gt;
&lt;li&gt;构建内部文档库，使用引导的方式进行让实施人员能自己找到各种问题的答案；&lt;/li&gt;
&lt;li&gt;平台代码层优化，让每一个异常情况都是明确的，有路可寻的，运维阶段的问题排查可以大大提升效率；&lt;/li&gt;
&lt;li&gt;项目代码的提交记录要和任务进行强绑定，为迁移和升级做好保障；&lt;/li&gt;
&lt;li&gt;将项目运维过程中的很多重复性工作，工具化。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一定要打破「又不是不能用」这种错误的思想。&lt;/p&gt;
&lt;p&gt;2022 年初，我在团队实行敏捷模式，大家觉得效果不错，沟通变多了，问题变少了。后来由于一些阻力没有继续。2023 年我将恢复敏捷模式，三周一个迭代，有序地进行平台功能的升级。&lt;/p&gt;
&lt;p&gt;每个迭代的内容会和项目团队进行沟通确认，然后跟涂总您进行汇报，确保所做的事情都是有用的，有效的。&lt;/p&gt;
&lt;p&gt;最后，我想说，不管经济形势怎么样，疫情是否反复，只要大家心是齐的，就不惧怕任何困难。&lt;/p&gt;</description></item><item><title>2022 年读过的书和 2023 年阅读规划</title><link>https://fwhyy.com/2023/01/books-read-in-2022-and-reading-plans-for-2023/</link><pubDate>Mon, 16 Jan 2023 09:15:11 +0800</pubDate><guid>https://fwhyy.com/2023/01/books-read-in-2022-and-reading-plans-for-2023/</guid><description>&lt;p&gt;2022 年读的书不多，可以找到很多的理由，但我觉得根因还是没有养成一个好的读书习惯。年初制定了每月至少阅读两本非技术书籍的目标，看似非常容易，但到现在一回顾，发现差的很远。&lt;/p&gt;</description></item><item><title>我将图床换到了阿里云 OSS</title><link>https://fwhyy.com/2023/01/i-switched-the-graph-bed-to-alibaba-cloud-oss/</link><pubDate>Sat, 14 Jan 2023 09:36:56 +0800</pubDate><guid>https://fwhyy.com/2023/01/i-switched-the-graph-bed-to-alibaba-cloud-oss/</guid><description>&lt;p&gt;关于博客的图床，一直都是白嫖，最早放过七牛云，然后经历过一次惨痛的迁移，才知道便宜的东西才是最贵的，后来存放到 Github 中，然后使用 jsdelivr 的 CDN 加速，最近发现 jsdelivr 的 CDN 也需要科学才能访问了。&lt;/p&gt;</description></item><item><title>读《李诞脱口秀工作手册》</title><link>https://fwhyy.com/2023/01/read-the-lee-talk-show-workbook/</link><pubDate>Wed, 11 Jan 2023 09:35:00 +0800</pubDate><guid>https://fwhyy.com/2023/01/read-the-lee-talk-show-workbook/</guid><description>&lt;p&gt;这本书是 2023 年读完的第二本书，第一本是阿加莎的《无人生还》，2023 年的读书效率挺高，希望能延续下去。&lt;/p&gt;</description></item><item><title>太卷了，Obsidian 和 Logseq 纷纷推出白板功能</title><link>https://fwhyy.com/2023/01/its-so-rolly-that-obsidian-and-logseq-have-introduced-whiteboard-functionality/</link><pubDate>Fri, 06 Jan 2023 21:31:53 +0800</pubDate><guid>https://fwhyy.com/2023/01/its-so-rolly-that-obsidian-and-logseq-have-introduced-whiteboard-functionality/</guid><description>&lt;p&gt;白板应用相信大家都不陌生，随便一列举就有不少：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Excalidraw ：https://excalidraw.com/&lt;/li&gt;
&lt;li&gt;ProcessOn 出的小画桌：https://www.xiaohuazhuo.com/&lt;/li&gt;
&lt;li&gt;heptabase : &lt;a href="https://heptabase.com/"&gt;https://heptabase.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;苹果的无边记，要求版本：iOS 16.2，iPadOS 16.2，以及 macOS Ventura 13.0&lt;/li&gt;
&lt;li&gt;&lt;a href="https://okso.app/"&gt;https://okso.app/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;白板有一个共同的特点就是无边，上下左右可以无限扩展，没有边际，其他的则各有侧重点，有的支持良好的协作、有的支持多种白板元素，从功能上来说，我认为可以分为两类：&lt;/p&gt;</description></item><item><title>2022 年终总结</title><link>https://fwhyy.com/2023/01/2022-year-end-summary/</link><pubDate>Tue, 03 Jan 2023 09:00:23 +0800</pubDate><guid>https://fwhyy.com/2023/01/2022-year-end-summary/</guid><description>&lt;p&gt;往年的年终总结都是在春节期间写，但元旦确实是更好的一个分界线，所以便决定今年开始在元旦左右来写年终总结了。&lt;/p&gt;</description></item><item><title>ChatGPT 之后，再玩玩 Stable-Diffusion</title><link>https://fwhyy.com/2022/12/after-chatgpt-play-stable-diffusion/</link><pubDate>Mon, 26 Dec 2022 08:53:38 +0800</pubDate><guid>https://fwhyy.com/2022/12/after-chatgpt-play-stable-diffusion/</guid><description>&lt;p&gt;前些天体验的 ChatGPT 主要用来进行文本方面的处理，那么图形有没有这样的 AI 工具
呢？答案是肯定的。&lt;/p&gt;</description></item><item><title>阳了？没阳？</title><link>https://fwhyy.com/2022/12/yang-is-not-yang/</link><pubDate>Mon, 19 Dec 2022 08:51:50 +0800</pubDate><guid>https://fwhyy.com/2022/12/yang-is-not-yang/</guid><description>&lt;p&gt;随着疫情政策的放开，公司的同事、身边的朋友陆续中招，公司里上班戴口罩的越来越多，上班的人却每天都在减少。&lt;/p&gt;
&lt;p&gt;我一直的心态都是，反正迟早都要阳的，有啥好怕的，所以在公司基本没戴口罩。于是便发生了接下来的事情。&lt;/p&gt;</description></item><item><title>尝鲜 ChatGPT</title><link>https://fwhyy.com/2022/12/try-chatgpt/</link><pubDate>Tue, 06 Dec 2022 08:48:59 +0800</pubDate><guid>https://fwhyy.com/2022/12/try-chatgpt/</guid><description>&lt;h2 id="什么是-chatgpt-"&gt;什么是 ChatGPT ？&lt;/h2&gt;
&lt;p&gt;我们先来看看 ChatGPT 自己的回答是什么：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2023/202306162045752.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;ChatGPT 是著名的 OpenAI 公司最近推出的新产品，可以以对话的形式给 AI 提问，AI 会给出一个还不错的回答，就像上图那样。&lt;/p&gt;</description></item><item><title>分享几个网站</title><link>https://fwhyy.com/2022/11/share-several-websites/</link><pubDate>Mon, 28 Nov 2022 20:35:23 +0800</pubDate><guid>https://fwhyy.com/2022/11/share-several-websites/</guid><description>&lt;p&gt;平时碰到一些有用或好玩的网站会随手记录到 flomo 中，下面是最近一段时间记录的一些网站，分享给大家。&lt;/p&gt;</description></item><item><title>dotNET 7：最小 API 使用</title><link>https://fwhyy.com/2022/11/dotmet-7-minimal-api-usage/</link><pubDate>Mon, 21 Nov 2022 08:39:37 +0800</pubDate><guid>https://fwhyy.com/2022/11/dotmet-7-minimal-api-usage/</guid><description>&lt;p&gt;Minimal APIs 并不是在 .NET 7 中才加入的，记得应该是在 .NET 6 中就已经提供，只是对我来说，到现在才开始使用。&lt;/p&gt;</description></item><item><title>C# 11：接口中的静态抽象成员</title><link>https://fwhyy.com/2022/11/csharp-11-static-abstract-members-in-interfaces/</link><pubDate>Mon, 14 Nov 2022 08:46:42 +0800</pubDate><guid>https://fwhyy.com/2022/11/csharp-11-static-abstract-members-in-interfaces/</guid><description>&lt;p&gt;接口我们都很了解了，在编写代码的时，如果有一定的抽象思维，就会将不同对象的相同行为抽象出来，放到接口中，我们最熟悉的就是在接口中写一堆方法的定义。&lt;/p&gt;</description></item><item><title>dotNET 7 尝鲜（VS 和 C# 11)</title><link>https://fwhyy.com/2022/11/dotnet-7-early-edition/</link><pubDate>Thu, 10 Nov 2022 18:39:37 +0800</pubDate><guid>https://fwhyy.com/2022/11/dotnet-7-early-edition/</guid><description>&lt;p&gt;2022 年 11 月 8 日，.NET 7 正式发布了，从 11 月 8 号 到 10 号，线上的 .NET Conf 2022 会议正在举行，可以通过 &lt;a href="https://www.dotnetconf.net/"&gt;https://www.dotnetconf.net/&lt;/a&gt; 了解相关情况。&lt;/p&gt;</description></item><item><title>关于信息收集和加工的思考</title><link>https://fwhyy.com/2022/11/thoughts-on-information-collection-and-processing/</link><pubDate>Mon, 07 Nov 2022 08:35:35 +0800</pubDate><guid>https://fwhyy.com/2022/11/thoughts-on-information-collection-and-processing/</guid><description>&lt;p&gt;随着互联网的发展，获取信息的手段越来越多，我们对手机的依赖程度超乎想象，每天忙碌着，大脑接收着丰富的信息，感觉每天都学习到了很多的知识。&lt;/p&gt;
&lt;p&gt;但我们对学习经常会有些误区：&lt;/p&gt;
&lt;p&gt;1、书买了摆在书架上，看看书架上摆的书，好像就看了书似的；&lt;/p&gt;
&lt;p&gt;2、把看过的内容当做已经学会了；&lt;/p&gt;
&lt;p&gt;3、发现好的内容随手就收藏了，收藏了就感觉自己掌握了。&lt;/p&gt;
&lt;p&gt;信息的获取并不代表这知识的掌握，从获取到掌握大概有这么些步骤：探索 ➔ 收集 ➔ 思考 ➔ 创作 ➔ 分享 ➔ 讨论。&lt;/p&gt;</description></item><item><title>为使用 Arc 浏览器，升级了 macOS Ventura</title><link>https://fwhyy.com/2022/10/to-use-arc-browser-macos-ventura-has-been-upgraded/</link><pubDate>Mon, 31 Oct 2022 08:35:35 +0800</pubDate><guid>https://fwhyy.com/2022/10/to-use-arc-browser-macos-ventura-has-been-upgraded/</guid><description>&lt;p&gt;在系统的版本上，我算得上是一个保守派，买电脑时系统的版本是 10.15.7 ，到现在一直没有升级过。&lt;/p&gt;
&lt;p&gt;最近在即刻上看到很多人推荐 Arc 浏览器，Arc 现在还没有正式开放，需要邀请，经过一番周折，在安装时发现最低系统要求是 macOS 11 以上，于是便决定升级系统。&lt;/p&gt;
&lt;p&gt;本文就说说 Ventura 的升级和 Arc 浏览器的体验。&lt;/p&gt;</description></item><item><title>读《阅读的方法》</title><link>https://fwhyy.com/2022/10/read-reading-methods/</link><pubDate>Mon, 24 Oct 2022 08:41:03 +0800</pubDate><guid>https://fwhyy.com/2022/10/read-reading-methods/</guid><description>&lt;p&gt;关于阅读的方法，有一本著名的书《如何阅读一本书》，从阅读的层次、书籍的分类、不同类型书籍的阅读方法讲的非常清楚了。&lt;/p&gt;
&lt;p&gt;本文要说的是今年罗胖出的《阅读的方法》，虽然书名叫阅读的方法，但书中却没有具体的方法，我觉得叫阅读的意义可能更合适。&lt;/p&gt;
&lt;p&gt;书的作者是罗振宇，人称罗胖，得到创始人，最出名的是从 2015 年开始坚持每年举办「时间的朋友」跨年演讲，以及公众号每天早上 6 点准时推送 60 秒的语音内容。&lt;/p&gt;
&lt;p&gt;这本书很容易读，我读书非常慢，一个周末也读完了。下面说说我的一些理解。&lt;/p&gt;</description></item><item><title>Go 学习：并发编程</title><link>https://fwhyy.com/2022/10/go-learning-concurrency/</link><pubDate>Mon, 17 Oct 2022 08:21:16 +0800</pubDate><guid>https://fwhyy.com/2022/10/go-learning-concurrency/</guid><description>&lt;p&gt;Go 语言在创建之初，CPU 多核发展的正猛，Go 语言的创始人果断将面向多核、原生就支持并发作为了 Go 语言的设计目标之一，所以所在 Go 语言中使用并发有得天独厚的优势。&lt;/p&gt;
&lt;p&gt;那么，什么是并发呢？&lt;/p&gt;</description></item><item><title>如何健康地跑步？</title><link>https://fwhyy.com/2022/10/how-to-run-healthily/</link><pubDate>Wed, 12 Oct 2022 16:35:35 +0800</pubDate><guid>https://fwhyy.com/2022/10/how-to-run-healthily/</guid><description>&lt;p&gt;最近某司高管跑步 28 公里后猝死，被各大媒体报道，每次这种悲剧发生，而且还跟跑步扯上关系，总是让人心痛。&lt;/p&gt;
&lt;p&gt;通过报道了解到，这位高管酷爱跑马拉松，身体素质和运动能力肯定是强于普通人的，但还是遭遇了不幸，只能说有一定基础和能力的人都会过于自信而导致忽视了一些重要的身体信号，就像 2021 年 5 月 22 日黄河石林山地马拉松百公里越野赛中遇难的也基本是专业运动员一样，都过于自信了，其中还包括大神梁晶。&lt;/p&gt;</description></item><item><title>系统学习还是得看书，Go 书籍推荐</title><link>https://fwhyy.com/2022/10/go-book-recommendation/</link><pubDate>Sat, 08 Oct 2022 08:21:16 +0800</pubDate><guid>https://fwhyy.com/2022/10/go-book-recommendation/</guid><description>&lt;p&gt;想要更系统地学习编程语言，看书是比较有效的途径之一。最近又学习了下 Go 语言，为什么是又，因为 2013 年买过许式伟大佬翻译的一本 Go 语言书籍，但没有系统学下去，现在想想原因可能是这本书过于严肃，没那么有趣，还有就是当时对编程语言的理解也没那么深。&lt;/p&gt;
&lt;p&gt;所以说看书虽然系统，还是要选择能够看的进去的书。之前看过一句话：写作需要阅读作为基础，阅读也需要阅读作为基础，我觉得很有道理。所以在看书之前，可以先将这个领域的相关概念大概了解下，不同的文章做下横向比较，再去阅读书籍，会有不错的效果，这就像学生时代的课前预习一样。&lt;/p&gt;</description></item><item><title>Go 学习：那些不一样的知识点（下）</title><link>https://fwhyy.com/2022/10/go-learning-those-different-knowledge-points-2/</link><pubDate>Sat, 01 Oct 2022 08:21:16 +0800</pubDate><guid>https://fwhyy.com/2022/10/go-learning-those-different-knowledge-points-2/</guid><description>&lt;p&gt;在上一篇《Go 学习：那些不一样的知识点（上）》中已经提到了 10 个 Go 语言中有特点的地方，本文继续介绍一些 Go 语言中语法或使用方式比较独特的知识点。&lt;/p&gt;
&lt;h2 id="11切片类型"&gt;11、切片类型&lt;/h2&gt;
&lt;p&gt;同 Python 一样，Go 语言中也支持切片类型，而 C# 在 C# 8 中也增加了对数组进行切片操作的语法糖，先来看一个 C# 的例子：&lt;/p&gt;</description></item><item><title>Go 学习：那些不一样的知识点（上）</title><link>https://fwhyy.com/2022/09/go-learning-those-different-knowledge-points/</link><pubDate>Mon, 26 Sep 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/09/go-learning-those-different-knowledge-points/</guid><description>&lt;p&gt;在学习 Go 语言的过程中，会涉及到语法、数据结构、和一些 Go 特有的东西，其中有不少现在还印象深刻，本文就说说 Go 语言中那些不一样的地方。&lt;/p&gt;</description></item><item><title>Go 学习：从环境搭建到写一个 Web 服务</title><link>https://fwhyy.com/2022/09/go-learning-from-environment-building-to-writing-a-web-service/</link><pubDate>Mon, 19 Sep 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/09/go-learning-from-environment-building-to-writing-a-web-service/</guid><description>&lt;p&gt;最近学习了 Go 语言，做下记录。&lt;/p&gt;
&lt;h2 id="go-的来历"&gt;Go 的来历&lt;/h2&gt;
&lt;p&gt;和 C、C++ 相比， Go 是一门很年轻的语言。2007 年，在 Google 的内部，有三位大佬因为 C++ 的复杂性、构建编译速度很慢和对并发支持不好等原因，便决定开发一门新的语言，于是他们基于 C 语言，做了功能的删减和新增，便有了 Go 的诞生。&lt;/p&gt;</description></item><item><title>时隔六年，软技能第二版来了</title><link>https://fwhyy.com/2022/09/after-six-years-the-second-edition-of-soft-skills-is-here/</link><pubDate>Tue, 13 Sep 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/09/after-six-years-the-second-edition-of-soft-skills-is-here/</guid><description>&lt;p&gt;《软技能》的第一版是 2016 年出版，当时读完这本书有种相见恨晚的感觉，随后便写了两篇读书笔记发布在博客中：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://fwhyy.com/2016/10/reading-soft-skills-agile-personal-management/"&gt;http://fwhyy.com/2016/10/reading-soft-skills-agile-personal-management/&lt;/a&gt;
&lt;a href="http://fwhyy.com/2016/10/Reading-soft-skills-learning-to-improve-productivity/"&gt;http://fwhyy.com/2016/10/Reading-soft-skills-learning-to-improve-productivity/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>六块腹肌</title><link>https://fwhyy.com/2022/09/six-pack-abs/</link><pubDate>Mon, 05 Sep 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/09/six-pack-abs/</guid><description>&lt;p&gt;去年九月，因送小孩开学时的一个闪念，便开始了连续 100 天的跑步计划，最终也顺利地完成了计划，体重减了不少，重要的是慢慢让坚持变成一种习惯。&lt;/p&gt;
&lt;p&gt;今天九月，因为疫情的反复，女儿学校通知在家上网课，独自开车上班的我，又思考着要立 Flag 了，准备花一年的时间，练出 6 块腹肌。&lt;/p&gt;</description></item><item><title>.NET Core 使用 LibreOffice 实现 Office 预览（Docker 部署）</title><link>https://fwhyy.com/2022/08/libreoffice-implements-office-preview/</link><pubDate>Mon, 29 Aug 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/08/libreoffice-implements-office-preview/</guid><description>&lt;p&gt;前些年做云盘产品的时候，一个很核心的功能就是 Office 文件预览，当时还没有使用 .NET Core ,程序部署在 Windows Server 服务器上，文件预览的方案采用了微软的 OWA 。&lt;/p&gt;
&lt;p&gt;目前在做的零代码产品中的表单附件控件，同样面临着 Office 文件预览的问题，现在技术栈采用了 .NET Core ，并使用容器化部署，自然就抛弃了 OWA 的方案。&lt;/p&gt;
&lt;p&gt;本文简单介绍下 OWA 的替代方案。&lt;/p&gt;</description></item><item><title>读《纳瓦尔宝典》</title><link>https://fwhyy.com/2022/08/nawal-treasure-book/</link><pubDate>Mon, 22 Aug 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/08/nawal-treasure-book/</guid><description>&lt;p&gt;最早是在量贩冰糖的播客听到介绍《纳瓦尔宝典》这本书，播主写了这本书的推荐序，另一篇推荐序是樊登写的，当时就想马上樊登读书应该会讲这本书了，果不其然，在我快看完的时候，樊登读书就推出了。&lt;/p&gt;
&lt;p&gt;下面就看看这本书都讲了些什么。&lt;/p&gt;</description></item><item><title>又解锁一款笔记工具：Logseq</title><link>https://fwhyy.com/2022/08/unlock-another-note-taking-tool-logseq/</link><pubDate>Mon, 15 Aug 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/08/unlock-another-note-taking-tool-logseq/</guid><description>&lt;p&gt;我很喜欢去尝试使用一些新的工具，解决一些当下的问题，所以工具永远没有最好，只有最合适，最近一直在使用的 Obsidian 是在范冰的播客中知道的，通过范冰我还知道了另一个笔记工具，也就是今天的主角：Logseq 。&lt;/p&gt;</description></item><item><title>读《华为数字化转型之道》</title><link>https://fwhyy.com/2022/08/huawei-approach-to-digital-transformation/</link><pubDate>Mon, 08 Aug 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/08/huawei-approach-to-digital-transformation/</guid><description>&lt;p&gt;数字化转型应该很多人都听过，但如果你做过 ToB 软件，听得更多的是信息化，那信息化和数字化是什么关系呢？&lt;/p&gt;
&lt;p&gt;下面用一个小例子来说说我的理解。&lt;/p&gt;</description></item><item><title>微服务：事务管理</title><link>https://fwhyy.com/2022/08/microservices-transaction-management/</link><pubDate>Mon, 01 Aug 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/08/microservices-transaction-management/</guid><description>&lt;p&gt;几乎所有的信息管理系统都会涉及到事务，事务的目的是为了保证数据的一致性，这里说的一致性是数据库状态的一致性。&lt;/p&gt;
&lt;p&gt;说到数据库状态的一致性，相信大家都会想到 ACID ：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;原子性（Atomic）：在一个事件的多个数据库操作中，要么同时成功，要么同时失败，例如：转账业务；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;隔离性（Isolation）：不同的业务之间处理数据相互独立，互不影响&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;持久性（Durability）：正常提交的数据能够被持久化，不丢失数据，比如 mysql 天然就能持久化，redis 、 rabbitmq 也能通过设置进行持久化；&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;一致性（Consistency）：最终的数据正确，所以说是通过 AID 这些手段来保证了 C 。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>三个人一台车自驾西藏</title><link>https://fwhyy.com/2022/07/three-people-and-one-car-driving-in-tibet/</link><pubDate>Tue, 26 Jul 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/07/three-people-and-one-car-driving-in-tibet/</guid><description>&lt;p&gt;一直都有去西藏的想法，去年换了坦克 300，自驾 318 便提上了日程。7 月小孩放暑假，同时领导也批准了我较长时间的请假。于是三个人，一台车，7 月 9 号开始了自驾之旅。&lt;/p&gt;</description></item><item><title>读《认知觉醒》</title><link>https://fwhyy.com/2022/07/read-cognitive-awakening/</link><pubDate>Mon, 04 Jul 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/07/read-cognitive-awakening/</guid><description>&lt;p&gt;最近发的几篇文章是跟个人成长和工具相关，突然想起几个月前读的《认知觉醒》，这本书从内在和外在两个大的维度让我们在个人精进的道路上可以少走弯路。&lt;/p&gt;
&lt;p&gt;后疫情时代，公司的活动少了，家庭的活动也少了，19 年后，没有自驾出过远门，每天家和公司两点一线，一天、一周、一个月过去，大脑没什么记忆点。日子像掉进了 for 循环一样，不断重复着，人就很容易产生疲态。&lt;/p&gt;
&lt;p&gt;这本书可以给我们一些指引，让我们实际去做一些事情，丰富我们的生活。&lt;/p&gt;</description></item><item><title>Obsidian 一周使用心得（配置、主题和插件）</title><link>https://fwhyy.com/2022/06/obsidian-one-week-experience/</link><pubDate>Mon, 27 Jun 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/06/obsidian-one-week-experience/</guid><description>&lt;p&gt;在上一篇 Obsidian 初体验 中介绍了为什么要开始使用 Obsidian 和我的一些基本用法，本文将继续讲解近一个星期以来的使用心得，包括配置、外观和插件。&lt;/p&gt;
&lt;p&gt;对于工具类的软件，我一直的方式是先进行基本设置，使用起来，在使用过程中再慢慢发现一些高级用法，就像 Obsidian 这个软件，目的是能方便进行写作，如果花大量精力去研究功能、插件等，就有点本末倒置了。&lt;/p&gt;</description></item><item><title>技术人如何打造个人品牌？</title><link>https://fwhyy.com/2022/06/how-do-techies-build-their-personal-brands/</link><pubDate>Mon, 20 Jun 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/06/how-do-techies-build-their-personal-brands/</guid><description>&lt;p&gt;对技术人来讲，个人品牌非常重要，个人品牌的建立是自我营销的一种方式，也是提升个人价值的一种方式。&lt;/p&gt;
&lt;p&gt;那什么是品牌呢？一篇文章、一个视频火了，这个不算是品牌，如果提及某个领域，大家能想到你，这就是品牌了。&lt;/p&gt;</description></item><item><title>Obsidian 初体验</title><link>https://fwhyy.com/2022/06/obsidian-first-experience/</link><pubDate>Tue, 14 Jun 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/06/obsidian-first-experience/</guid><description>&lt;p&gt;我虽然不是工具控，但写作类的工具用过不少，其中 Notion 和 Typora 还专门写文章介绍过：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一款用了就不想走的工具&lt;/li&gt;
&lt;li&gt;使用 Typora 进行写作&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>NET Core中的RabbitMQ消费者CPU高，竟然是这个原因</title><link>https://fwhyy.com/2022/06/the-high-cpu-of-rabbitmq-consumers-in-net-core/</link><pubDate>Mon, 06 Jun 2022 08:08:42 +0800</pubDate><guid>https://fwhyy.com/2022/06/the-high-cpu-of-rabbitmq-consumers-in-net-core/</guid><description>&lt;p&gt;在 RabbitMQ 中有一个 vhsot 机制，可以用来做租户隔离，当产品从单租户演化为多租户时，正好可以用到这个特性，不同 vhost 中的交换机、队列互不影响。&lt;/p&gt;</description></item><item><title>当谈研发效能时，在谈些什么？</title><link>https://fwhyy.com/2022/06/what-to-talk-about-when-talking-about-effectiveness/</link><pubDate>Wed, 01 Jun 2022 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2022/06/what-to-talk-about-when-talking-about-effectiveness/</guid><description>&lt;p&gt;最近翻了下之前写的公众号文章，发现研发效能相关的就有三篇：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;怎样提高开发效率&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;关于增效，需要做好这两点&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;再谈研发效率提升&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从工具使用、业务的理解、团队的沟通协作到流程、组织、分享等内容，我能想到的大部分有关研发效能的点都有涉及到。&lt;/p&gt;</description></item><item><title>做个成年人</title><link>https://fwhyy.com/2022/05/being-an-adult/</link><pubDate>Mon, 23 May 2022 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2022/05/being-an-adult/</guid><description>&lt;p&gt;奈飞内部曾经流传出一份企业文化的 PPT ，被誉为硅谷最重要的文件，后来这份 PPT 经过重新整合出版，就是《奈飞文化手册》。&lt;/p&gt;
&lt;p&gt;在《奈飞文化手册》中介绍的第一个文化准则就是：我们只招收成年人。&lt;/p&gt;
&lt;p&gt;这里所说的成年人不是年龄上的成年，而是心智上的。所谓成年人，就是有责任，有担当，能控制好情绪。&lt;/p&gt;</description></item><item><title>微服务：服务间如何通信？</title><link>https://fwhyy.com/2022/05/microservices-how-do-services-communicate/</link><pubDate>Mon, 16 May 2022 08:10:55 +0800</pubDate><guid>https://fwhyy.com/2022/05/microservices-how-do-services-communicate/</guid><description>&lt;p&gt;在微服务架构中，会将一个完整的应用程序拆分成一组服务。这些服务之间需要经过协作，通过接口调用，才能组成一个完整的应用。&lt;/p&gt;
&lt;p&gt;不同的服务部署在不同的机器上，或者同一个机器的多个容器中，进程间的通信就不可避免了，也变得非常重要。&lt;/p&gt;</description></item><item><title>结构化思维</title><link>https://fwhyy.com/2022/05/structured-thinking/</link><pubDate>Tue, 10 May 2022 08:08:42 +0800</pubDate><guid>https://fwhyy.com/2022/05/structured-thinking/</guid><description>&lt;p&gt;在说结构化思维之前，先看下面两个小案例：&lt;/p&gt;</description></item><item><title>如何提升写作能力？</title><link>https://fwhyy.com/2022/05/how-to-improve-writing-ability/</link><pubDate>Thu, 05 May 2022 08:06:18 +0800</pubDate><guid>https://fwhyy.com/2022/05/how-to-improve-writing-ability/</guid><description>&lt;p&gt;尽管我在公众号已经发了 130 多篇原创文章，而且在写公众号之前，还写了十来年的博客，可我依然觉得我不会写作。&lt;/p&gt;
&lt;p&gt;之前写的大部分都是技术文章或一些总结，能把一个技术点讲清楚，让不懂的人有所收获，我认为就很好了，就算对他人没有帮助，也能作为自己的一个备忘录。&lt;/p&gt;</description></item><item><title>书籍推荐（202204）</title><link>https://fwhyy.com/2022/04/book-recommendation-202204/</link><pubDate>Sat, 30 Apr 2022 08:09:51 +0800</pubDate><guid>https://fwhyy.com/2022/04/book-recommendation-202204/</guid><description>&lt;p&gt;最近，疫情不太稳定，五一小长假也没有出行的计划，宅在家跑跑步，看看书也挺好。&lt;/p&gt;
&lt;p&gt;前几天翻看相册，看到了一张 2019 年国庆期间在合肥附近一个古镇拍的照片，拥挤的小街上，人来人往，每个人脸上的表情都清晰可见，有点感慨，想想现在，口罩已经成为了出门的必备品。&lt;/p&gt;</description></item><item><title>Mac中的翻译神器</title><link>https://fwhyy.com/2022/04/translation-artifact-in-mac/</link><pubDate>Mon, 25 Apr 2022 09:59:29 +0800</pubDate><guid>https://fwhyy.com/2022/04/translation-artifact-in-mac/</guid><description>&lt;p&gt;对程序员来说，英语能力非常重要，但当我们的英语没那么好的时候，就需要借助一些翻译工具来帮我们去阅读英文资料。&lt;/p&gt;
&lt;p&gt;翻译工具用过不少，像有道词典、灵格斯、欧路、还有浏览器的插件等，不过最近用过的一款翻译工具让我眼前一亮，就是接下来要介绍的 Bob 。&lt;/p&gt;</description></item><item><title>从一个简单 API 的发布到组件化的架构思考</title><link>https://fwhyy.com/2022/04/thoughts-on-the-architecture-from-the-release/</link><pubDate>Mon, 18 Apr 2022 09:53:44 +0800</pubDate><guid>https://fwhyy.com/2022/04/thoughts-on-the-architecture-from-the-release/</guid><description>&lt;p&gt;在 SaaS 版本的零代码平台中，高级用户希望能上传自己编写的 WebAPI ，来实现一些复杂场景下的业务。就需要添加可以通过上传程序包进行发布部署的功能。&lt;/p&gt;</description></item><item><title>代码居然还能这样写</title><link>https://fwhyy.com/2022/04/how-can-the-code-be-written-like-this/</link><pubDate>Mon, 11 Apr 2022 08:20:20 +0800</pubDate><guid>https://fwhyy.com/2022/04/how-can-the-code-be-written-like-this/</guid><description>&lt;p&gt;这篇文章要介绍的是 GitHub Copilot 。&lt;/p&gt;
&lt;p&gt;微软去年推出的 GitHub Copilot 是一个基于 AI 的编程辅助工具，简单理解就是我们写点注释或者写个方法名，Copilot 就能理解了我们的意思，然后帮我们写一个相关的方法出来。&lt;/p&gt;</description></item><item><title>读《底层逻辑》</title><link>https://fwhyy.com/2022/04/read-the-underlying-logic/</link><pubDate>Wed, 06 Apr 2022 08:18:13 +0800</pubDate><guid>https://fwhyy.com/2022/04/read-the-underlying-logic/</guid><description>&lt;p&gt;《底层逻辑》本书作者是刘润，他在得到上开设有课程《5 分钟商学院》，我也是在得到上知道的这本书，这本书在豆瓣上的评分不是很高，褒贬不一，不过我看着觉得挺好。&lt;/p&gt;</description></item><item><title>书籍推荐（202202）</title><link>https://fwhyy.com/2022/03/book-recommendation-202203/</link><pubDate>Thu, 31 Mar 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/03/book-recommendation-202203/</guid><description>&lt;p&gt;时间过得真快，三月就这样结束了，最后一天继续推荐几本书。&lt;/p&gt;
&lt;p&gt;一直以来 C# 是我的主力编程语言，学习编程语言基本上看官方文档就够了，但下面这三本关于 C# 的书籍我还是强烈推荐阅读。&lt;/p&gt;</description></item><item><title>微服务：如何拆分服务？</title><link>https://fwhyy.com/2022/03/how-to-split-services/</link><pubDate>Mon, 28 Mar 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/03/how-to-split-services/</guid><description>&lt;p&gt;在微服务的落地中，第一步就需要进行微服务的拆分，服务的拆分很困难也很重要，本文就讲讲怎么进行服务的拆分。&lt;/p&gt;
&lt;p&gt;技术发展到现在，还没有一个具体的，设计完善的标准方法来完成服务的拆分，服务的拆分是一门技术更是一门艺术。&lt;/p&gt;</description></item><item><title>低风险发布，再读《持续交付2.0（增订版）》</title><link>https://fwhyy.com/2022/03/reread-continuous-delivery-2-0/</link><pubDate>Mon, 21 Mar 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/03/reread-continuous-delivery-2-0/</guid><description>&lt;p&gt;两年前看了乔梁编写的《持续交付2.0》，收获颇多，还写了一篇读书笔记，今年 2 月，该书出了增订本，增加了一个章节的内容，其他的一些章节内容也有局部的优化。&lt;/p&gt;</description></item><item><title>推荐一款卡片笔记工具</title><link>https://fwhyy.com/2022/03/recommend-a-card-note-taking-tool/</link><pubDate>Mon, 14 Mar 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/03/recommend-a-card-note-taking-tool/</guid><description>&lt;p&gt;相信大家都有这样一些经历：&lt;/p&gt;
&lt;p&gt;1、使用微信读书时做的笔记，画的线，在书看完后就随着看完的书一起收藏了，也可能使用思维导图来做读书笔记，每本书对应一个思维导图；&lt;/p&gt;
&lt;p&gt;2、读纸书或使用其他的一些阅读工具，笔记记录到了 Notion 或类似的笔记工具中；&lt;/p&gt;
&lt;p&gt;3、网上看到的一些金句、随手一个右键就发到印象笔记了；&lt;/p&gt;
&lt;p&gt;4、平时在走路、等电梯、开车时脑袋会闪过一些观点和想法，如果不及时记录，稍纵即逝，日后就想不起来了；&lt;/p&gt;
&lt;p&gt;5、朋友圈我们发的都是想让别人看到的一面，还有另外一些可能偷偷记录在自己的日记本中；&lt;/p&gt;</description></item><item><title>微服务：我们需要从单体转到微服务吗？</title><link>https://fwhyy.com/2022/03/do-we-need-to-switch-from-monomer-to-microservice/</link><pubDate>Mon, 07 Mar 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/03/do-we-need-to-switch-from-monomer-to-microservice/</guid><description>&lt;p&gt;微服务或许你没有真正实践过，但一定听说过，虽然已经到了 2022 年，这个词依然很热，可以通过搜索 google 指数看得到。&lt;/p&gt;</description></item><item><title>书籍推荐（202202）</title><link>https://fwhyy.com/2022/02/book-recommendation-202202/</link><pubDate>Mon, 28 Feb 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/02/book-recommendation-202202/</guid><description>&lt;p&gt;二月的最后一天，继续推荐十本书。&lt;/p&gt;</description></item><item><title>.NET 诞生 20 周年，我和 .NET 相伴的 17 年</title><link>https://fwhyy.com/2022/02/20th-anniversary-of-net/</link><pubDate>Mon, 21 Feb 2022 10:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/02/20th-anniversary-of-net/</guid><description>&lt;p&gt;今年是 .NET 诞生 20 周年，最近也看了很多张善友大佬发的一系列关于庆祝 20 周年的视频，很有感触，回想起自己这一路走来，和 .NET 相伴也快 20 年了。&lt;/p&gt;
&lt;p&gt;下面说说我跟 .NET 的故事。&lt;/p&gt;</description></item><item><title>CentOS单机安装k8s并部署.NET 6程序</title><link>https://fwhyy.com/2022/02/centos-install-k8s-deploy-net6/</link><pubDate>Sun, 20 Feb 2022 10:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/02/centos-install-k8s-deploy-net6/</guid><description>&lt;p&gt;学习云原生，k8s 是一个基础，为了做一些实验，单机部署是最方便的，下面将介绍在 CentOS 中单机安装 k8s ，并将一个 .NET 6 的程序发布到 k8s 中。&lt;/p&gt;</description></item><item><title>我为什么喜欢使用Typora</title><link>https://fwhyy.com/2022/02/why-do-i-like-it-typora/</link><pubDate>Mon, 14 Feb 2022 08:26:00 +0800</pubDate><guid>https://fwhyy.com/2022/02/why-do-i-like-it-typora/</guid><description>&lt;p&gt;虽然写作能力很一般，但这些年也一直再坚持输出，最早是在博客园，其他的一些博客平台也都有所尝试，后来又折腾独立博客，18 年开始写公众号，写公众号后，博客便没再维护了。&lt;/p&gt;
&lt;p&gt;工具也用过不少，平台自带的编辑器、一些云笔记工具、MWeb、Notion。Notion 是 20 年才开始使用的，在《一款用了就不想走的工具》中也有所介绍。&lt;/p&gt;
&lt;p&gt;Notion 虽然功能强大，但在写文章，然后发布到公众号和博客，还是显得不太方便，主要是文章中图片的处理。&lt;/p&gt;
&lt;p&gt;最近因为重新翻修了下博客，找到了一个非常适合我想法的 hexo-stellar 主题，博客的图片可以使用 Github + jsdelivr + PicGo 来打造图床，而 Typora 对 PicGo 有着很好的支持，于是便尝试了使用 Typora。&lt;/p&gt;</description></item><item><title>程序员不可错过的一款Hexo博客主题</title><link>https://fwhyy.com/2022/02/hexo-stellar/</link><pubDate>Thu, 10 Feb 2022 08:42:53 +0800</pubDate><guid>https://fwhyy.com/2022/02/hexo-stellar/</guid><description>&lt;p&gt;自从 2018 年开始写公众号之后，我的个人站点（fwhyy.com）就停止更新了，直到最近查资料发现了hexo 博客的 stellar 主题，春节期间将博客重新维护起来，主要原因是因为该主题支持专栏的功能。&lt;/p&gt;</description></item><item><title>2021 年终总结</title><link>https://fwhyy.com/2022/02/2021-year-end-summary/</link><pubDate>Tue, 01 Feb 2022 21:14:11 +0800</pubDate><guid>https://fwhyy.com/2022/02/2021-year-end-summary/</guid><description>&lt;p&gt;年龄越大，会觉得时间过得越快，2021 年已经结束。&lt;/p&gt;</description></item><item><title>Hexo 的 Stellar 主题问题</title><link>https://fwhyy.com/2022/01/hexo-stellar-theme-problems/</link><pubDate>Thu, 27 Jan 2022 14:45:54 +0800</pubDate><guid>https://fwhyy.com/2022/01/hexo-stellar-theme-problems/</guid><description>&lt;h2 id="软件版本"&gt;软件版本&lt;/h2&gt;
&lt;p&gt;相关的版本如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;macOS: 10.15.7
Hexo: 5.4.0
hexo-cli: 4.3.0
node.js: 14.17.3 
npm: 6.14.13
stellar: 1.6.1
&lt;/code&gt;&lt;/pre&gt;&lt;!-- more --&gt;
&lt;h2 id="问题1-hexo-g-生成问题"&gt;问题1： hexo g 生成问题&lt;/h2&gt;
&lt;p&gt;当我的post数量超过 6 时，使用hexo g 进行生成就会报下图中的错误，删掉一篇就能生成成功，尝试过换不同的post文章，基本能排除是某一个文章特殊内容的问题。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;原文中的错误截图文件已经缺失，这里保留文字说明。
尝试过将 stellar 降级到 1.6.0 和 1.5.2 都出现相同错误。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;后来尝试将_config.xml 中的主题切换成默认主题 languages ，执行 hexo g ，可以正常生成，然后又切回 stellar 主题，hexo g 正常了。后面间歇性的发生上图错误，来回切换下就正常了，很是奇怪。&lt;/p&gt;
&lt;h2 id="问题2运行时问题"&gt;问题2：运行时问题&lt;/h2&gt;
&lt;p&gt;post 文章加到了将近 20 篇时，hexo g 生成没有问题，hexo s 运行后，访问网页，不能正常显示，控制台出现如下错误：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;INFO Start processing
INFO Hexo is running at http://localhost:4000 . Press Ctrl+C to stop.

&amp;lt;--- Last few GCs ---&amp;gt;

[12722:0x110008000] 35949 ms: Scavenge 3974.7 (4103.6) -&amp;gt; 3974.6 (4104.6) MB, 7.9 / 0.0 ms (average mu = 0.813, current mu = 0.672) allocation failure 
[12722:0x110008000] 35974 ms: Scavenge 3975.6 (4104.6) -&amp;gt; 3973.8 (4119.6) MB, 22.8 / 0.0 ms (average mu = 0.813, current mu = 0.672) allocation failure 
[12722:0x110008000] 37751 ms: Mark-sweep 3988.7 (4119.6) -&amp;gt; 3986.5 (4135.6) MB, 1742.6 / 0.0 ms (average mu = 0.656, current mu = 0.133) allocation failure scavenge might not succeed


&amp;lt;--- JS stacktrace ---&amp;gt;

FATAL ERROR: MarkCompactCollector: young object promotion failed Allocation failed - JavaScript heap out of memory
 1: 0x10130c5e5 node::Abort() (.cold.1) [/usr/local/bin/node]
 2: 0x1000b2289 node::Abort() [/usr/local/bin/node]
 3: 0x1000b23ef node::OnFatalError(char const*, char const*) [/usr/local/bin/node]
 4: 0x1001f68c7 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 5: 0x1001f6863 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/usr/local/bin/node]
 6: 0x1003a47e5 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/usr/local/bin/node]
 7: 0x100400823 v8::internal::EvacuateNewSpaceVisitor::Visit(v8::internal::HeapObject, int) [/usr/local/bin/node]
 8: 0x1003e808b void v8::internal::LiveObjectVisitor::VisitBlackObjectsNoFail&amp;lt;v8::internal::EvacuateNewSpaceVisitor, v8::internal::MajorNonAtomicMarkingState&amp;gt;(v8::internal::MemoryChunk*, v8::internal::MajorNonAtomicMarkingState*, v8::internal::EvacuateNewSpaceVisitor*, v8::internal::LiveObjectVisitor::IterationMode) [/usr/local/bin/node]
 9: 0x1003e7bd5 v8::internal::FullEvacuator::RawEvacuatePage(v8::internal::MemoryChunk*, long*) [/usr/local/bin/node]
10: 0x1003e7916 v8::internal::Evacuator::EvacuatePage(v8::internal::MemoryChunk*) [/usr/local/bin/node]
11: 0x10040524e v8::internal::PageEvacuationTask::RunInParallel(v8::internal::ItemParallelJob::Task::Runner) [/usr/local/bin/node]
12: 0x1003bf202 v8::internal::ItemParallelJob::Task::RunInternal() [/usr/local/bin/node]
13: 0x1003bf688 v8::internal::ItemParallelJob::Run() [/usr/local/bin/node]
14: 0x1003e9985 void v8::internal::MarkCompactCollectorBase::CreateAndExecuteEvacuationTasks&amp;lt;v8::internal::FullEvacuator, v8::internal::MarkCompactCollector&amp;gt;(v8::internal::MarkCompactCollector*, v8::internal::ItemParallelJob*, v8::internal::MigrationObserver*, long) [/usr/local/bin/node]
15: 0x1003e9586 v8::internal::MarkCompactCollector::EvacuatePagesInParallel() [/usr/local/bin/node]
16: 0x1003d4cf7 v8::internal::MarkCompactCollector::Evacuate() [/usr/local/bin/node]
17: 0x1003d258b v8::internal::MarkCompactCollector::CollectGarbage() [/usr/local/bin/node]
18: 0x1003a4eab v8::internal::Heap::MarkCompact() [/usr/local/bin/node]
19: 0x1003a1499 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [/usr/local/bin/node]
20: 0x10039f2e0 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [/usr/local/bin/node]
21: 0x1003ad9ea v8::internal::Heap::AllocateRawWithLightRetrySlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
22: 0x1003ada71 v8::internal::Heap::AllocateRawWithRetryOrFailSlowPath(int, v8::internal::AllocationType, v8::internal::AllocationOrigin, v8::internal::AllocationAlignment) [/usr/local/bin/node]
23: 0x100376cce v8::internal::FactoryBase&amp;lt;v8::internal::Factory&amp;gt;::NewRawTwoByteString(int, v8::internal::AllocationType) [/usr/local/bin/node]
24: 0x10078f54d v8::internal::IncrementalStringBuilder::Extend() [/usr/local/bin/node]
25: 0x1004bd9ad v8::internal::JsonStringifier::SerializeString(v8::internal::Handle&amp;lt;v8::internal::String&amp;gt;) [/usr/local/bin/node]
26: 0x1004c2458 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
27: 0x1004c07ee v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
28: 0x1004be856 v8::internal::JsonStringifier::SerializeArrayLikeSlow(v8::internal::Handle&amp;lt;v8::internal::JSReceiver&amp;gt;, unsigned int, unsigned int) [/usr/local/bin/node]
29: 0x1004c2805 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
30: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
31: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
32: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
33: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
34: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
35: 0x1004c07ee v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
36: 0x1004be856 v8::internal::JsonStringifier::SerializeArrayLikeSlow(v8::internal::Handle&amp;lt;v8::internal::JSReceiver&amp;gt;, unsigned int, unsigned int) [/usr/local/bin/node]
37: 0x1004c2805 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
38: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
39: 0x1004c07ee v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
40: 0x1004be856 v8::internal::JsonStringifier::SerializeArrayLikeSlow(v8::internal::Handle&amp;lt;v8::internal::JSReceiver&amp;gt;, unsigned int, unsigned int) [/usr/local/bin/node]
41: 0x1004c2805 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
42: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
43: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
44: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
45: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
46: 0x1004c07ee v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
47: 0x1004be856 v8::internal::JsonStringifier::SerializeArrayLikeSlow(v8::internal::Handle&amp;lt;v8::internal::JSReceiver&amp;gt;, unsigned int, unsigned int) [/usr/local/bin/node]
48: 0x1004c2805 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
49: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
50: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
51: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
52: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
53: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
54: 0x1004c07ee v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
55: 0x1004be856 v8::internal::JsonStringifier::SerializeArrayLikeSlow(v8::internal::Handle&amp;lt;v8::internal::JSReceiver&amp;gt;, unsigned int, unsigned int) [/usr/local/bin/node]
56: 0x1004c2805 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
57: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
58: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
59: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
60: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
61: 0x1004c4008 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;true&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
62: 0x1004c07ee v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
63: 0x1004be856 v8::internal::JsonStringifier::SerializeArrayLikeSlow(v8::internal::Handle&amp;lt;v8::internal::JSReceiver&amp;gt;, unsigned int, unsigned int) [/usr/local/bin/node]
64: 0x1004bf687 v8::internal::JsonStringifier::Result v8::internal::JsonStringifier::Serialize_&amp;lt;false&amp;gt;(v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, bool, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
65: 0x1004ba503 v8::internal::JsonStringify(v8::internal::Isolate*, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;, v8::internal::Handle&amp;lt;v8::internal::Object&amp;gt;) [/usr/local/bin/node]
66: 0x1002a0253 v8::internal::Builtin_JsonStringify(int, unsigned long*, v8::internal::Isolate*) [/usr/local/bin/node]
67: 0x100a81b59 Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_BuiltinExit [/usr/local/bin/node]
68: 0x100a14839 Builtins_ArgumentsAdaptorTrampoline [/usr/local/bin/node]
69: 0x100a1a902 Builtins_InterpreterEntryTrampoline [/usr/local/bin/node]
zsh: abort hexo s
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>书籍推荐（202201）</title><link>https://fwhyy.com/2022/01/book-recommendation-202201/</link><pubDate>Mon, 24 Jan 2022 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2022/01/book-recommendation-202201/</guid><description>&lt;p&gt;这些年陆陆续续买了不少的书，虽然是买书如山倒，看书如抽丝，但买了总是有机会看的。2022 年计划每个月推荐 10 本书，这些书都是我买过或者在微信读书中看过，觉得还不错的。范围包括：&lt;/p&gt;</description></item><item><title>华为云鲲鹏服务器部署Java踩坑记</title><link>https://fwhyy.com/2022/01/huawei-cloud-server-deployment-3/</link><pubDate>Thu, 20 Jan 2022 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2022/01/huawei-cloud-server-deployment-3/</guid><description>&lt;p&gt;之前跟华为云的技术人员沟通，他们说在鲲鹏服务器上构建部署对微软的 dotNET 支持不是很好，建议使用 Java ，我们程序现在是混合模式 dotNET 和 Java 都有。让我没想到的是 dotNET 的构建部署很顺利，反倒是 Java 的部署遇到了些问题。&lt;/p&gt;</description></item><item><title>读《好好学习：个人知识管理精进指南》</title><link>https://fwhyy.com/2022/01/read-study-hard/</link><pubDate>Mon, 17 Jan 2022 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2022/01/read-study-hard/</guid><description>&lt;p&gt;关于学习的文章之前写过两篇：&lt;/p&gt;
&lt;p&gt;《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247484664&amp;amp;idx=1&amp;amp;sn=c40760e9ee2043b7fd049924cb33f682&amp;amp;chksm=fb56c238cc214b2e79e35b3f88cbb166de33569d01ac1cd7cea4d678bf5c45bb60d7e439dc30&amp;amp;scene=21#wechat_redirect"&gt;掌握好的学习方法，让你在职场更有竞争力&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247484233&amp;amp;idx=1&amp;amp;sn=d40ae726c0a7bbfe6f59dd2c6cf4ce4f&amp;amp;chksm=fb56c589cc214c9ffeb9ae100ba5a44adb39ebd52faa862a0c0a31ba786a8968be730b4b11f5&amp;amp;scene=21#wechat_redirect"&gt;程序员是终身学习的职业，应该怎么学习？&lt;/a&gt;》&lt;/p&gt;
&lt;p&gt;我们都是终身学习者，我深知学习的重要性，所以每隔一段时间，有些新的心得和想法，便会分享出来。最近看完了成甲的《好好学习：个人知识管理精进指南》，又有了些新的感悟，便有了此篇。&lt;/p&gt;</description></item><item><title>华为云服务器初探二（完结）</title><link>https://fwhyy.com/2022/01/huawei-cloud-server-deployment-2/</link><pubDate>Fri, 14 Jan 2022 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2022/01/huawei-cloud-server-deployment-2/</guid><description>&lt;p&gt;在上一篇《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247484822&amp;amp;idx=1&amp;amp;sn=9712c1cc0a7efa7e5938021c7c088c6a&amp;amp;chksm=fb56c356cc214a406ee70fa7ae6908822871892855c1602db1ccc2cd8119f54f7f5dc30acb17&amp;amp;scene=21#wechat_redirect"&gt;华为云服务器初探&lt;/a&gt;》 中介绍了在使用华为云服务器部署时的一些关键点，本篇继续，内容涉及如下:&lt;/p&gt;</description></item><item><title>华为云服务器部署初探</title><link>https://fwhyy.com/2022/01/huawei-cloud-server-deployment/</link><pubDate>Mon, 10 Jan 2022 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2022/01/huawei-cloud-server-deployment/</guid><description>&lt;p&gt;最近玩了下华为云，遇到了一些坑，做下记录。&lt;/p&gt;
&lt;p&gt;华为云有很多的服务，文中会涉及到：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CCE&lt;/li&gt;
&lt;li&gt;ECS&lt;/li&gt;
&lt;li&gt;弹性公网IP&lt;/li&gt;
&lt;li&gt;DevCloud&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>四点起床，是疯狂还是自律？</title><link>https://fwhyy.com/2021/12/get-up-at-four-crazy-or-self-disciplined/</link><pubDate>Mon, 27 Dec 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/12/get-up-at-four-crazy-or-self-disciplined/</guid><description>&lt;p&gt;如果你在微信读书中搜索「四点起床」，会搜到好几本相关的书籍，其中有一本是《4点起床：最养生和高效的时间管理》，作者是日本的中岛孝志，一位读书狂人。前几天，微信读书系统对我做了这本书的推荐，花了几个小时看完，便疯狂地体验了下。&lt;/p&gt;</description></item><item><title>连续跑步100天是什么体验？</title><link>https://fwhyy.com/2021/12/what-is-the-experience-of-running-100-days-in-a-row/</link><pubDate>Mon, 20 Dec 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/12/what-is-the-experience-of-running-100-days-in-a-row/</guid><description>&lt;p&gt;随着今年夏天的结束，我的体重又回到了 170，对于身高 175 的我来说，170 的体重看上去就是一个胖子。&lt;/p&gt;</description></item><item><title>设计模式：面向对象的设计原则下（ISP、DIP、KISS、YAGNI、DRY、LOD）</title><link>https://fwhyy.com/2021/12/object-oriented-design-principles-2/</link><pubDate>Mon, 13 Dec 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/12/object-oriented-design-principles-2/</guid><description>&lt;p&gt;本文继续来介绍接口隔离原则（ISP）和依赖倒置原则（DIP），这两个原则都和接口和继承有关。文章最后会简单介绍几个除了 SOLID 原则之外的原则。&lt;/p&gt;</description></item><item><title>设计模式：面向对象的设计原则上（SRP、OCP、LSP）</title><link>https://fwhyy.com/2021/12/object-oriented-design-principles-1/</link><pubDate>Mon, 06 Dec 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/12/object-oriented-design-principles-1/</guid><description>&lt;p&gt;在面向对象的世界里，可以分为：面向对象的基础知识、面向对象的设计原则和设计模式，如果用武侠小说来做比喻，基础知识就是需要练习的基本功、设计原则就是内功心法、设计模式则是各种各样的具体招式，所以说熟练掌握了设计原则，就能以不变应万变。&lt;/p&gt;</description></item><item><title>敏捷开发：从理论到团队落地</title><link>https://fwhyy.com/2021/11/agile-development-from-theory-to-team-landing/</link><pubDate>Wed, 24 Nov 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/11/agile-development-from-theory-to-team-landing/</guid><description>&lt;p&gt;敏捷开发很早就已经流行过了，之前也零碎地了解了一些相关知识，并在团队中进行了部分实践，但效果都不怎么好。最近又重新梳理了一遍，并结合现状，准备在团队中重新实践敏捷。&lt;/p&gt;</description></item><item><title>Nike Air Zoom Tempo Next% 实战评测</title><link>https://fwhyy.com/2021/11/nike-air-zoom-tempo-next/</link><pubDate>Sun, 21 Nov 2021 09:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/11/nike-air-zoom-tempo-next/</guid><description>&lt;p&gt;今年的 9 月 1 号开始了 100 天每天至少五公里的跑步计划，10 月过生日，老婆送了一双 Nike Air Zoom Tempo Next% ，到现在穿着这双鞋跑了近 100 公里，下面说说实际的穿着体验，究竟有没有网上说的那么神。&lt;/p&gt;</description></item><item><title>设计模式：面向对象的基础知识</title><link>https://fwhyy.com/2021/11/object-oriented-basic-knowledge/</link><pubDate>Mon, 15 Nov 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/11/object-oriented-basic-knowledge/</guid><description>&lt;p&gt;主流的编程范式有三种：面向过程、面向对象和函数式编程，我们现在使用的主流编程语言 C# 或 Java，都是面向对象语言，所以常常说的设计模式也是在面向对象语言这个前提之下。&lt;/p&gt;
&lt;p&gt;面向对象的基础知识和一些设计原则，我认为是学习设计模式的基础，本文就聊下这些基础知识。&lt;/p&gt;</description></item><item><title>零代码平台中的服务编排思路</title><link>https://fwhyy.com/2021/11/service-arrangement-in-zero-code-platform/</link><pubDate>Thu, 04 Nov 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/11/service-arrangement-in-zero-code-platform/</guid><description>&lt;p&gt;随着企业数字化转型的进程加快，零代码平台的的应用越来越广泛，逐渐被企业级的客户认可和接受。&lt;/p&gt;
&lt;p&gt;零代码顾名思义就是在不写代码的情况下可以搭建应用和功能来满足客户的需求，但事实是残酷的，真实的客户需求永远比我们想象的要复杂，传统的零代码产品需要提供各种扩展能力，比如可以让开发人员编写复杂的业务逻辑代码，并对接到平台中。&lt;/p&gt;</description></item><item><title>现在还需要学习设计模式吗？</title><link>https://fwhyy.com/2021/11/do-you-still-need-to-learn-design-patterns-now/</link><pubDate>Mon, 01 Nov 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/11/do-you-still-need-to-learn-design-patterns-now/</guid><description>&lt;p&gt;最近面试了不少人，Java 和 dotNET 的都有，当问到设计模式时，大部分都只能说出单例和工厂，有些能聊聊其他的一些模式的，大多也没有在实际项目中用过。为了团队成员能有更好的编码能力，便有了重新写写设计模式的想法，写作也是一个重新学习的过程。&lt;/p&gt;</description></item><item><title>使用零代码平台构建应用，应该怎样转变思路？</title><link>https://fwhyy.com/2021/10/how-should-we-change-our-thinking-when-using-zero-code/</link><pubDate>Mon, 18 Oct 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/10/how-should-we-change-our-thinking-when-using-zero-code/</guid><description>&lt;p&gt;最近两年，越来越多的各类零代码产品在市场上出现，与此同时，企业的数字化转型的速度也越来越快，零代码产品已然成为了帮助企业数字化转型的利器。&lt;/p&gt;</description></item><item><title>番茄工作法真的有用吗？</title><link>https://fwhyy.com/2021/10/is-tomato-working-really-useful/</link><pubDate>Mon, 11 Oct 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/10/is-tomato-working-really-useful/</guid><description>&lt;p&gt;辅导小孩写作业总是一件让人崩溃的事情，暑假最后，给小孩在手机上安装了一个番茄钟 APP ，不知道是因为新鲜还是番茄钟本身的魔力，写作业的困扰解决了。&lt;/p&gt;
&lt;p&gt;最近又翻了下《番茄工作法图解》，这是一本很小的册子，即便是我这种看书比较慢的也能在几个小时内看完。整本书在讲一种可以提高效率的做事的方法，可以总结成四个字，“专注，坚持”。而专注和坚持恰恰是小孩最难做到的。&lt;/p&gt;
&lt;p&gt;有一个广为流传的一万小时理论说的是在某一个领域专注 10000 个小时，平均每天 3 小时，花10年的时间，你就可以成为这个领域的专家，其实说的也是专注和坚持。下面就看看番茄工作法是怎么样来提高我们的效率的。&lt;/p&gt;
&lt;h2 id="几个术语"&gt;几个术语&lt;/h2&gt;
&lt;p&gt;番茄钟：一个25分钟的时间段成为一个番茄钟，最初因为厨房的定时钟长的像番茄而得名，在一个番茄钟内需要专注做一件事情；&lt;/p&gt;
&lt;p&gt;活动：指要完成的工作任务；&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部中断：在一个番茄钟内，来自自身的干扰，如想去刷刷微博，或者去看看新闻等；&lt;/li&gt;
&lt;li&gt;外部中断：在一个番茄钟内，来自外界的干扰，如电话、邮件、被同事咨询问题等；&lt;/li&gt;
&lt;li&gt;预估：对任务需要多少个番茄钟才能完成的判断。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="工具"&gt;工具&lt;/h2&gt;
&lt;p&gt;使用番茄工作法的工具很简单，一个番茄钟、一只笔、几张纸质表格即可、番茄钟用来计时用，纸和笔用来记录用，纸质表格分为下面三类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;活动清单&lt;/li&gt;
&lt;li&gt;今日待办&lt;/li&gt;
&lt;li&gt;记录&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="方法"&gt;方法&lt;/h2&gt;
&lt;p&gt;每天开始从活动清单中挑选一些重要的活动作为今日待办，选择今日待办中最重要的活动，开启一个番茄钟，开始专注这项活动。番茄钟结束立即立即停止工作，停止前可以稍微整理下思路，然后休息3到5分钟，这个短暂的休息就是一个小的奖励，休息完后就可以进入下一个番茄钟。每一个番茄钟就像是一个小的目标，那个短暂的休息激励着你去完成一个一个的小的目标。&lt;/p&gt;
&lt;p&gt;完成4个番茄钟后可以进行15到30分钟的长时间的休息。&lt;/p&gt;
&lt;p&gt;番茄钟是不可分割的，如果你预估的一项活动需要多个番茄钟才能完成，需要将活动进行拆分成更小的活动。&lt;/p&gt;
&lt;h2 id="一些疑问"&gt;一些疑问&lt;/h2&gt;
&lt;h3 id="怎样挑选今日待办"&gt;怎样挑选今日待办？&lt;/h3&gt;
&lt;p&gt;活动清单中的活动太多，可以采用比较法来进行挑选，两两比较，如果今天只能做一件事情你会选哪件，最终胜出的优先级最高，以此类推，可以选择出今天的待办列表。&lt;/p&gt;
&lt;h3 id="内部中断怎么办"&gt;内部中断怎么办？&lt;/h3&gt;
&lt;p&gt;番茄工作法一再强调一次只做一件事，在一个番茄钟内需要高度专注当前活动，有临时的一些想法，可以先记录下来，再根据优先级在后面的番茄钟里去完成。克制自己时不时就去刷下微博的习惯，克制自己把注意力放到微信消息上，实在不行可以在番茄钟内将电脑任务栏隐藏或者关闭消息提醒。举一个简单的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本来我在看一篇关于 C# 的技术博客；&lt;/li&gt;
&lt;li&gt;被文章中的链接带到了一篇介绍 Git 的文章中；&lt;/li&gt;
&lt;li&gt;在 Git 的文章中介绍了一个编程大牛的博客；&lt;/li&gt;
&lt;li&gt;翻阅大牛的博客发现有很多感兴趣的文章，挑选一些进行翻阅；&lt;/li&gt;
&lt;li&gt;我特么最初是想干什么来着，可能已经记不起来了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面是我经常会出现的问题，如果用番茄工作法，我应该在看到介绍 Git 链接的时候，将该链接保存下来，然后继续学习那篇关于 C# 的文章。&lt;/p&gt;
&lt;h3 id="外部中断怎么办"&gt;外部中断怎么办？&lt;/h3&gt;
&lt;p&gt;外部中断可能是一个很重要的电话；可能是领导突然叫你去谈一些事情；可能是一封不得不处理的邮件，当遇到这些不能推脱的打断的时候，必须停掉当前的番茄钟，回来之后重新开始一个新的番茄钟。&lt;/p&gt;
&lt;p&gt;一个番茄钟没完成，活动已经完成怎么办？&lt;/p&gt;
&lt;p&gt;番茄钟没结束，活动已经结束了，说明预估出现了误差，此时不应该马上去做下一个活动，可以进行一些过渡性学习，或者回顾一下该番茄钟内完成的活动。&lt;/p&gt;
&lt;h3 id="一定要是25分钟吗"&gt;一定要是25分钟吗？&lt;/h3&gt;
&lt;p&gt;为什么是25分钟，这个得问创始人了，书里强烈建议不管你是否觉得合适，先按照 25 分钟坚持一个星期再根据自己实际情况进行调整，先坚持一个星期目的是为了让我们养成一种习惯，只有在一段时间内去体验了，才会觉得合不合适。而不是根据自己的性子今天 10 分钟，明天 1 个小时。&lt;/p&gt;
&lt;h2 id="我的思考"&gt;我的思考&lt;/h2&gt;
&lt;p&gt;番茄工作法是一种时间管理的工具，如果您高度自律，您可能不需要。如果你在做事的时候会想去刷刷微博、看看邮件、聊聊微信，那么不妨试一试这种方法。&lt;/p&gt;
&lt;p&gt;番茄工作法更适合一些个人事务，不是很适合程序员这种工作，程序员这种工作不确定性太多，外部中断太多，每天要做什么事情可能在上班后才会知道。&lt;/p&gt;
&lt;p&gt;番茄工作法只是一种约束自己提高效率的工具，没有必要完全停留在形式上，做到“专注，坚持”就够了。&lt;/p&gt;
&lt;p&gt;虽然有人说这本书是将一句话能说明白的事延伸写了一本书，但我觉得一本书能让我们读进去，并能带来一些帮助，就是有价值的。再回到题目，番茄工作法是否真的有用？相信你已经有答案了。&lt;/p&gt;</description></item><item><title>读《沟通的方法》</title><link>https://fwhyy.com/2021/09/read-the-method-of-communication/</link><pubDate>Mon, 27 Sep 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/09/read-the-method-of-communication/</guid><description>&lt;p&gt;众所周知，沟通在工作和生活中是一项非常重要的技能，但很多人却用不好这项技能，最近中秋假期，看完了得到 CEO 脱不花写的《沟通的方法》，觉得很有收获。&lt;/p&gt;</description></item><item><title>12 个问题搞懂 Redis</title><link>https://fwhyy.com/2021/09/12-questions-to-understand-redis/</link><pubDate>Mon, 13 Sep 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/09/12-questions-to-understand-redis/</guid><description>&lt;p&gt;都说学习需要带着问题，带着思考进行学习，下面就以问题的形式来学习下 Redis 。&lt;/p&gt;</description></item><item><title>掌握好的学习方法，让你在职场更有竞争力</title><link>https://fwhyy.com/2021/09/mastering-good-learning-methods/</link><pubDate>Mon, 06 Sep 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/09/mastering-good-learning-methods/</guid><description>&lt;p&gt;程序员是一个需要终身学习的职业，其实不止是程序员，各行各业都在内卷，掌握好的学习方法，学习更多的技能，会有更大的竞争优势，也会让你在未来有机会到来的时候，能够承接得住。&lt;/p&gt;</description></item><item><title>提升心力：摆脱拿着锤子看啥都是钉子</title><link>https://fwhyy.com/2021/08/improve-mental-strength/</link><pubDate>Mon, 30 Aug 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/08/improve-mental-strength/</guid><description>&lt;p&gt;从程序员到一个团队的管理者，这中间需要经过一次又一次的蜕变，最终才能变得处理任何事情都得心应手。&lt;/p&gt;
&lt;p&gt;韩非子曾说：下君用己之力、中君用人之力、上君用人之智。大部分的管理者可能都处在用人之力的阶段，并向着用人之智前进。最近看了一些关于管理的视频，提到了更高维度的用人之心和用人之愿，如果能做到，那必定会是一支战无不胜的团队。&lt;/p&gt;</description></item><item><title>最近看了两本低代码的书（文末有福利）</title><link>https://fwhyy.com/2021/08/i-recently-read-two-low-code-books/</link><pubDate>Mon, 23 Aug 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/08/i-recently-read-two-low-code-books/</guid><description>&lt;p&gt;因为标题中「福利」进来的朋友直接拉到文章的最底部。&lt;/p&gt;
&lt;p&gt;月初写了一篇《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247484621&amp;amp;idx=1&amp;amp;sn=e23179a553c2cf80f5b2d0d351c75065&amp;amp;chksm=fb56c20dcc214b1b17894f1afb6070024cd1321811182d202437cea4baaecf34e69f27ad0978&amp;amp;scene=21#wechat_redirect"&gt;你真的了解低代码平台吗？&lt;/a&gt;》，介绍了下我对低代码产品的一些认识，随后有朋友送了我两本华章出版的关于低代码的书：明道云的《零代码实战》和微软的《实战低代码》，目前市面上也就这两本关于低代码的书。因为对低代码比较熟悉，所以很快就读完了。&lt;/p&gt;</description></item><item><title>dotNet 5 中执行 Node.js</title><link>https://fwhyy.com/2021/08/dotnet5-exec-node-js/</link><pubDate>Mon, 09 Aug 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/08/dotnet5-exec-node-js/</guid><description>&lt;p&gt;在&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247484621&amp;amp;idx=1&amp;amp;sn=e23179a553c2cf80f5b2d0d351c75065&amp;amp;chksm=fb56c20dcc214b1b17894f1afb6070024cd1321811182d202437cea4baaecf34e69f27ad0978&amp;amp;scene=21#wechat_redirect"&gt;低代码产品&lt;/a&gt;中为了扩展功能，我们在业务编排中会扩展代码块的功能，允许用户直接在界面中进行代码（Node.js、 Python）的编写，来实现取数或者赋值的一些功能。本文简单介绍下在 dotNET 5 中怎么样进行 Node.js 的调用以及怎样部署到 CentOS 和 Docker 容器中。&lt;/p&gt;
&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;dotNET ：5&lt;/li&gt;
&lt;li&gt;Node.js：14.17.4&lt;/li&gt;
&lt;li&gt;CentOS：7.6&lt;/li&gt;
&lt;li&gt;Docker：19.03.13&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dotnet-5-中的代码实现"&gt;dotNET 5 中的代码实现&lt;/h2&gt;
&lt;p&gt;1、在 VS 中创建 WebAPI 示例项目 nodejs-demo 项目，目标框架选择 .NET 5.0。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/20220202081223.webp" alt="iShot2022-02-02 08.12.23" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、在项目中引入 NuGet 包：Microsoft.AspNetCore.NodeServices ,这里我使用的是 5.0 的预览版本。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202202020813752.webp" alt="iShot2022-02-02 08.13.07" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、修改 Startup 类，在 ConfigureServices 方法中添加下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;services.AddNodeServices();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4、在项目的根目录中创建一个名为 hello.js 的脚本文件，文件的属性中的「复制到输出目录」设置为「始终复制」，文件的内容如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;module.exports = function (callback, name) {
 var msg = &amp;#39;Hello,&amp;#39; + name;
 callback(null, msg);
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5、编写一个 API 接口方法：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[HttpGet]
public async Task&amp;lt;IActionResult&amp;gt; Get([FromServices] INodeServices nodeServices)
{
 var result = await nodeServices.InvokeAsync&amp;lt;string&amp;gt;(&amp;#34;hello.js&amp;#34;, &amp;#34;oec2003&amp;#34;);
 return Ok(result);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;6、如果正常运行，结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202202020813556.webp" alt="iShot2022-02-02 08.13.29" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="部署到-centos-中"&gt;部署到 CentOS 中&lt;/h2&gt;
&lt;p&gt;1、在 Node.js 的中文官网 (&lt;a href="http://nodejs.cn/download/current/"&gt;http://nodejs.cn/download/current/&lt;/a&gt;) 下载 Linux 二进制文件 (x64) 的安装包；&lt;/p&gt;
&lt;p&gt;2、将下载的安装包 node-v14.17.4-linux-x64.tar.xz 复制到 CentOS 系统的 root 目录中；&lt;/p&gt;
&lt;p&gt;3、执行命令 &lt;code&gt;tar -xvf node-v14.17.4-linux-x64.tar.xz&lt;/code&gt; 解压安装文件；&lt;/p&gt;
&lt;p&gt;4、执行命令 &lt;code&gt;mv node-v14.17.4-linux-x64 nodejs&lt;/code&gt; 将解压后的文件夹命名为 nodejs；&lt;/p&gt;</description></item><item><title>你真的了解低代码平台吗？</title><link>https://fwhyy.com/2021/08/do-you-really-know-about-low-code-platforms/</link><pubDate>Mon, 02 Aug 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/08/do-you-really-know-about-low-code-platforms/</guid><description>&lt;p&gt;从 2020 年疫情之后，低代码这个概念就突然变得火热起来，各大自媒体纷纷推出介绍低代码的文章，InfoQ 也曾发表过一篇《为什么我说低代码是“行业毒瘤”？》引发了热议，明道的创始人任向晖随后在自己的公众号写文章《低代码不是行业毒瘤，你才是！》进行回应，好不热闹。&lt;/p&gt;</description></item><item><title>技术 Leader 怎样带跨一个团队？</title><link>https://fwhyy.com/2021/07/how-does-a-technology-leader-lead-a-team/</link><pubDate>Mon, 19 Jul 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/07/how-does-a-technology-leader-lead-a-team/</guid><description>&lt;p&gt;网上很多分析大公司，小公司的文章，都会提到在大公司工作就是螺丝钉，岗位分的非常细，每个人把自己的专职工作做好就行；而在小公司需要每个人都是多面手，一岗多职。&lt;/p&gt;
&lt;p&gt;这种观点我同意一半，在小公司中，某些阶段人手不足，确实需要每个人都做很多职责之外的事情，比如开发人员除了写代码，还需要测试、写需求文档、用户手册、运维等。但大公司再大，最终也会分解为很多小的团队，从团队最小的颗粒度来说，差别就没那么大了。小公司的团队想要走的更好，也需要能发挥每个人特长，职责清晰。&lt;/p&gt;</description></item><item><title>再谈研发效率提升</title><link>https://fwhyy.com/2021/07/on-the-improvement-of-efficiency/</link><pubDate>Mon, 05 Jul 2021 08:25:00 +0800</pubDate><guid>https://fwhyy.com/2021/07/on-the-improvement-of-efficiency/</guid><description>&lt;p&gt;最近因为一个版本的发布上线，带着团队兄弟们几乎通宵了，见到了凌晨四点武汉的景色。为什么到这么晚，这背后的原因是值得深思的。归根结底，就是研发效率不高，到了临近上线仍出现各种各样的问题。&lt;/p&gt;</description></item><item><title>VS 2019 16.10 和 VS 2022 新功能</title><link>https://fwhyy.com/2021/06/vs-2019-16-10-and-vs-2022-new-features/</link><pubDate>Mon, 28 Jun 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/06/vs-2019-16-10-and-vs-2022-new-features/</guid><description>&lt;p&gt;作为宇宙第一 IDE 的 Visual Studio ，我从 VS2003 开始就一直都在使用，并关注着其发展动态，最近 Visual Studio 2022 的预览版已经可以下载，在 2022 版本之前，我使用的是 VS 2019，当你升级到 VS 2019 的 16.10 版本后，会发现新增了下面的一些新功能：&lt;/p&gt;</description></item><item><title>你有做 Code Review 吗？</title><link>https://fwhyy.com/2021/06/did-you-do-code-review/</link><pubDate>Tue, 15 Jun 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/06/did-you-do-code-review/</guid><description>&lt;p&gt;在代码的编写中有一个很重要的环节，经常会被忽视，那就是 Code Review ,据说在 Facebook、Google 这种互联网大公司，要求每一个提交都必须通过审查，对于每个工程师来说 Code Review 是一项十分重要的工作，甚至比写代码本身更重要。&lt;/p&gt;</description></item><item><title>谈谈跑步</title><link>https://fwhyy.com/2021/06/talk-about-running/</link><pubDate>Tue, 01 Jun 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/06/talk-about-running/</guid><description>&lt;p&gt;跑步是非常简单的一项运动，没有场地限制，也没有装备限制，只需要迈开双腿就可以，而且还可以减肥、解压，本文就和大家聊聊跑步。&lt;/p&gt;</description></item><item><title>读《中台架构与实现》</title><link>https://fwhyy.com/2021/05/read-zhongtai-architecture-and-implementation/</link><pubDate>Mon, 24 May 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/05/read-zhongtai-architecture-and-implementation/</guid><description>&lt;p&gt;最早是在极客时间知道欧创新老师的，我也是他的课程《DDD实战课》的订阅者，后来欧老师基于这门课程做更多的实践与思考，完成了《中台架构与实现：基于 DDD 和微服务》这本书的写作，最近刚好读完了这本书。&lt;/p&gt;</description></item><item><title>实现多租户系统的一点思考</title><link>https://fwhyy.com/2021/05/thoughts-on-realizing-multi-tenant-system/</link><pubDate>Mon, 17 May 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/05/thoughts-on-realizing-multi-tenant-system/</guid><description>&lt;p&gt;2020年突发的新冠疫情，让在线协同办公在疫情期间成为了刚需。我们也从 2020 年的 2月3 日开始在家远程办公，直到四月份。协同办公软件一下子火爆了起来，钉钉、企业微信、特别是腾讯会议等都在疫情期间表现突出，呈现出井喷式的发展。&lt;/p&gt;
&lt;p&gt;目前大部分的企业信息化都是私有化部署，局限于企业的内部网络，无法实现远程协同办公，所以越来越多的 To B 企业逐步转向 SaaS（Software-as-a-Service，软件即服务），SaaS 最早是美国Salesforce公司（1999年创立）创造的新软件服务模式。这家公司的市值在 2019 年已经超过1000亿美元，国内现在还处在发展中阶段，前景还是十分广阔的。&lt;/p&gt;
&lt;p&gt;要将传统的私有化部署的软件重构成支持 SaaS 模式，多租户是一个迈不过去的坎，首先需要将系统改造成多租户模式，然后再逐步实现计费、系统监控、用户行为分析等功能。&lt;/p&gt;
&lt;p&gt;我觉得多租户的设计应该分为三个层面来进行讨论，应用、数据库和中间件。&lt;/p&gt;
&lt;h2 id="应用"&gt;应用&lt;/h2&gt;
&lt;p&gt;现在的项目或产品开发几乎都是前后端分离的开发模式，应用层主要指的是 WebAPI ，WebAPI 的改造有两种方式：&lt;/p&gt;
&lt;p&gt;1、每个租户部署一套 WebAPI、上层通过域名或 Url 地址的解析进行路由，当有新租户注册的时候就动态进行对应的 WebAPI 的部署，这种方式改造成本低，但运维成本高，不建议使用，如果时间紧，可以当过度阶段的临时方案。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202202020736143.webp" alt="iShot2022-02-02 07.35.55" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、所有的租户共用一套 WebAPI ，在 WebAPI 中需要获取到租户信息（域名、Url参数、请求头信息、Cookie 等），然后进行租户信息配置的切换。有新租户创建的时候无需进行新的 WebAPI 的创建，只需要初始化租户基本信息即可。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202202020736943.webp" alt="iShot2022-02-02 07.36.31" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在这种方式下，如果 Cluster1 的负载超过限度了，也要能够进行动态切换，将其中的某些租户切换到其他的 Cluester 中，如上图。&lt;/p&gt;
&lt;p&gt;在 WebAPI 的代码实现上，可以参考 Abp 框架中多租户的实现，这里给出一个简化版本：&lt;/p&gt;
&lt;p&gt;TenantConfiguration：租户配置信息&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[Serializable]
public class TenantConfiguration
{
 public Guid Id { get; set; }

 public string Code { get; set; }

 public string Name { get; set; }

 public TenantStatus TenantStatus { get; set; }

 public string DBConfig { get; set; }

 public string CacheConfig { get; set; }

 public string MQConfig { get; set; }

 public string MongoConfig { get; set; }

 public TenantConfiguration()
 {
 TenantStatus = TenantStatus.Enable;
 }

 public TenantConfiguration(Guid id, string name)
 : this()
 {
 
 Id = id;
 Name = name;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;TenantStore：从缓存或数据库中获取租户配置信息&lt;/p&gt;</description></item><item><title>读《精益商业思维》</title><link>https://fwhyy.com/2021/05/reading-lean-business-thinking/</link><pubDate>Thu, 06 May 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/05/reading-lean-business-thinking/</guid><description>&lt;p&gt;五一假期读了程浩的《精益商业思维》，程浩是迅雷的联合创始人之一，现在是职业投资人， 全篇从创业者的角度，也从投资人的角度解析了创业的方法论。&lt;/p&gt;
&lt;p&gt;书中有大量的互联网公司的案例，都是我们耳熟能详的一些互联网企业，读起来非常顺畅，我读书很慢，但这本书在很短的时间内读完了，可见读书的速度不完全取决于读者，作者也是很关键的因素。&lt;/p&gt;</description></item><item><title>C#：8.0 &amp; 9.0 常用新特性</title><link>https://fwhyy.com/2021/04/c-8-9-common-new-features/</link><pubDate>Mon, 19 Apr 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/04/c-8-9-common-new-features/</guid><description>&lt;p&gt;在《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247483852&amp;amp;idx=1&amp;amp;sn=8a7fd3a21e0c174bb237d59d802131a9&amp;amp;chksm=fb56c70ccc214e1aaf4037521134d2f3a5cfe54dac1f0dd06b52cb53794379946ebfa7a25890&amp;amp;scene=21#wechat_redirect"&gt;带你了解C#每个版本新特性&lt;/a&gt;》 一文中介绍了，C# 1.0 到 7.0 的不同特性，本文接着介绍在 8.0 和 9.0 中的一些常用新特性。&lt;/p&gt;</description></item><item><title>CentOS 7 安装 Greenplum6 （附 dotNET Core 示例）</title><link>https://fwhyy.com/2021/04/centos7-install-greenplum6/</link><pubDate>Mon, 12 Apr 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/04/centos7-install-greenplum6/</guid><description>&lt;p&gt;Mysql 在面对大数据量的时候，还是表现有些吃力，所以产品中需要扩展能支持海量数据的数据库，这里选择的数据库为 Greenplum6 ，Greenplum 底层使用的是开源数据库 PostgreSQL 。本文会介绍怎样在 CentOS 7 中安装 Greenplum6，并使用 dotNET Core 程序进行连接访问。&lt;/p&gt;</description></item><item><title>关于增效，需要做好这两点</title><link>https://fwhyy.com/2021/04/with-regard-to-efficiency-and-two-point/</link><pubDate>Tue, 06 Apr 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/04/with-regard-to-efficiency-and-two-point/</guid><description>&lt;p&gt;最近两会上都谈论到 996 的问题了，那我们实行 996 ，每个人每天都非常忙碌，是不是就效率很高呢？是不是很多时候都在做一些无价值的事情呢？是不是都在加着班写着 Bug 呢？我认为真相远没有我们想象的那么乐观。&lt;/p&gt;
&lt;p&gt;春节后的几次公司会议上都在提「增效」，随着公司的发展，人数变多，各种成本也随之增高，所以通过各种方式来增效，才能有正向的发展。以目前我的观察来看，我觉得可以从两个方面入手：沟通和抓住关键点。&lt;/p&gt;
&lt;p&gt;在《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247483743&amp;amp;idx=1&amp;amp;sn=e2023b3216da4d334a8e7b3c35ce8799&amp;amp;chksm=fb56c79fcc214e898732e4ec3ba16c408606da47f9734f14c4b013fa371656d433dccb277c33&amp;amp;scene=21#wechat_redirect"&gt;怎样提高开发效率&lt;/a&gt;》一文中主要说的是开发人员硬技能方面的提升，在上面提到的各种成本中，沟通成本是非常重要的一块，这属于软技能的范畴，也是最容易被忽视的。&lt;/p&gt;
&lt;p&gt;沟通体现在很多个方面，这里主要想说下提问和 Bug 描述。&lt;/p&gt;
&lt;p&gt;前不久，有项目团队同事在企业微信上问我：怎样拉取镜像来进行测试环境的更新？如果考虑到部门之间应该有良好的沟通的协作，我应该告诉他怎么操作，但为什么有这么低级的问题能被问出来，是一个值得思考的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;拉取镜像更新是一个每个开发人员必备的技能，为什么还有人是不会的？&lt;/li&gt;
&lt;li&gt;有没有做相应的培训，或者培训了，是否每个人都能够理解？&lt;/li&gt;
&lt;li&gt;听的时候理解了，实际操作的时候是不是还是不会？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所有有章可循的、都应该形成规范，进行培训、然后考核，保证不同的人按照文档进行操作能够得出相同的结果，如果有开发人员能主动去探究其中的原理并举一反三，那便是锦上添花了。&lt;/p&gt;
&lt;p&gt;对于 Bug 描述经常会出现这样的场景：&lt;/p&gt;
&lt;p&gt;实施人员：表单上的选人控件加载部门树很慢；&lt;/p&gt;
&lt;p&gt;开发：经过一系列的代码检查、运行调试后回复，我本地很快啊；&lt;/p&gt;
&lt;p&gt;开发人员时间花了，但并没有解决问题，在描述 Bug 的时候，需要有更详细的场景和上下文信息，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;客户的部门和人员的数据量级是多少？&lt;/li&gt;
&lt;li&gt;是所有用户还是特定用户，如果特定用户，是否有什么特殊的权限的设置?&lt;/li&gt;
&lt;li&gt;客户使用的浏览器是什么版本？&lt;/li&gt;
&lt;li&gt;选人控件本身有没有什么特殊数据范围或权限的设置？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有了更多的信息，开发人员就能有针对性地进行排查，也能更容易解决问题。&lt;/p&gt;
&lt;p&gt;Bug 只要能重现，处理起来还比较容易，当遇到偶发 Bug 的时候，更是要尽量提供足够的信息，但很多时候描述却是这样的：&lt;/p&gt;
&lt;p&gt;实施人员：客户点击某某操作时，会出现系统异常，我们有时操作也会出现，但不是每次都出现；&lt;/p&gt;
&lt;p&gt;开发：不能重现，我怎么排查呢？&lt;/p&gt;
&lt;p&gt;实施人员在一线，离现场更近，能知道更多的信息，所以在出现问题时需要尽可能多地提供信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;系统出现异常提示是有日志记录的，是否有对日志进行过初步的分析？&lt;/li&gt;
&lt;li&gt;操作的数据中有没有特殊数据，比如附件、富文本等？&lt;/li&gt;
&lt;li&gt;是否能收集到客户用的系统以及浏览器的版本？&lt;/li&gt;
&lt;li&gt;是否能收集到客户的操作系统的方式？&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果每个一线实施人员都能够去收集一些有用信息，做下初步的分析，然后将整个过程形成文字内容提交给开发，相信会大大提升解决问题的效率。&lt;/p&gt;
&lt;p&gt;至于收集哪些有用信息，怎样来做初步分析，随着慢慢地沉淀，也一样可以形成标准的文档和操作手册。&lt;/p&gt;
&lt;p&gt;除了沟通，另一个能提高效率的地方就是在工作中能抓住关键点，根据二八法则，抓住 20% 的关键点就能解决 80% 的问题。&lt;/p&gt;
&lt;p&gt;下面是最近团队中发生的两个个事情，正好说明了关键点的重要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;产品代码做重构优化，让开发人员按照思路写出类以及空方法，然后进行评审，但开发人员会比较容易关注细节，一动手就想着对象怎样映射，依赖注入应该怎么进行设置等等，浪费了时间；&lt;/li&gt;
&lt;li&gt;让开发排查一个 Bug，我便开会去了，一个多小时回来询问情况，得知还没有解决，还在继续调试代码分析原因，最后发现是一个配置项没有添加导致。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第一件事情的关键点是代码的思路，而不是实现，开发人员和产品负责人的目标和思想需要一致，也就是华为管理哲学中所说的「力出一孔」，如果方向偏了，努力越多，错的越远。&lt;/p&gt;
&lt;p&gt;第二件事情的关键点是遇到问题的思考，想清楚之后再动手做，最终的做可能是检查配置、寻求其他人员帮助、或者代码调试。而不是任何问题一上来就进行代码调试。&lt;/p&gt;
&lt;p&gt;最后总结下：&lt;/p&gt;
&lt;p&gt;1、沟通在工作和生活中无处不在，想想沟通的目的，多换位思考；&lt;/p&gt;
&lt;p&gt;2、除了上面说的提问和 Bug 描述，还有代码注释、代码提交备注、技术规范文档等等都属于沟通；&lt;/p&gt;
&lt;p&gt;3、方向一致、目标明确做起事来才能最高效；&lt;/p&gt;
&lt;p&gt;4、多思考、总结、复盘才能慢慢积累经验，经验丰富了才更容易找到关键点。&lt;/p&gt;
&lt;p&gt;希望本文能对您有所启发和帮助！&lt;/p&gt;</description></item><item><title>读《有效需求分析》</title><link>https://fwhyy.com/2021/03/read-effective-demand-analysis/</link><pubDate>Mon, 22 Mar 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/03/read-effective-demand-analysis/</guid><description>&lt;p&gt;最近在一个技术群里看到张逸大佬强力推荐一本关于需求分析的书《有效需求分析》，于是在 Kindle 上下单了，读完后有一种相见恨晚的感觉。&lt;/p&gt;</description></item><item><title>Teleport 开源堡垒机的使用</title><link>https://fwhyy.com/2021/03/use-teleport/</link><pubDate>Mon, 08 Mar 2021 21:45:52 +0800</pubDate><guid>https://fwhyy.com/2021/03/use-teleport/</guid><description>&lt;p&gt;公司的服务器可能会存在这样一种情况，具体的应用是部署在很多的内网服务器上，然后由一台外网服务器通过代理的方式对外提供服务，例如下图：&lt;/p&gt;</description></item><item><title>GitLab 服务器的迁移以及注意点</title><link>https://fwhyy.com/2021/03/gitlab-server-migration-and-points-for-attention/</link><pubDate>Mon, 01 Mar 2021 22:05:08 +0800</pubDate><guid>https://fwhyy.com/2021/03/gitlab-server-migration-and-points-for-attention/</guid><description>&lt;p&gt;Git 已经是代码托管工具中的主流了，如果是自己搭建私有的 Git 服务器我们一般会使用 GitLab ，在《&lt;a href="http://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247483693&amp;amp;idx=1&amp;amp;sn=c4e5ff320b4def07707387fc0b64794a&amp;amp;chksm=fb56c7edcc214efb5f0177d9b5fb0e368f2232f0086eb45f35efdce3011933d8bd9f712bde57&amp;amp;scene=21#wechat_redirect"&gt;在CentOS7中安装GitLab&lt;/a&gt;》 一文中有介绍怎样在 CentOS7 中安装 GitLab 。文本主要介绍怎样迁移 GtiLab 。&lt;/p&gt;</description></item><item><title>Nexus：一站式私有仓库管理（NuGet、Maven、NPM、Docker）</title><link>https://fwhyy.com/2021/03/nexus-manage/</link><pubDate>Mon, 01 Mar 2021 08:05:00 +0800</pubDate><guid>https://fwhyy.com/2021/03/nexus-manage/</guid><description>&lt;p&gt;我们在日常开发中经常需要使用到私有仓库，比如 dotNET 中的 NuGet、Java 中的 Maven、前端的 npm，还有 Docker 镜像，每一个私有仓库各自管理，维护起来比较麻烦，而 Nexus 可以将其统一起来。&lt;/p&gt;</description></item><item><title>2020 年终总结</title><link>https://fwhyy.com/2021/02/2020-end-of-year-summary/</link><pubDate>Fri, 12 Feb 2021 08:30:00 +0800</pubDate><guid>https://fwhyy.com/2021/02/2020-end-of-year-summary/</guid><description>&lt;p&gt;2020 年是很特殊的一年，也是过得最快的一年。&lt;/p&gt;
&lt;p&gt;疫情贯穿着全年，只要是外出口罩变成了必备品，这些都是和以往不一样的地方，包括到年底的提倡着就地过年，这已经变成一个持久战了，心态一定要好。&lt;/p&gt;
&lt;p&gt;疫情改变了我们的生活，封城了两个多月，经历过物资不足的窘迫，也经历过单元楼内有确证的恐慌，两个多月学会了做各种面食，两个月内也第一次体验了在家远程办公，在《远程办公也可以很高效》中介绍了当时办公的场景和方式。&lt;/p&gt;</description></item><item><title>看见的不一定是真实的</title><link>https://fwhyy.com/2021/02/what-you-see-is-not-necessarily-true/</link><pubDate>Mon, 08 Feb 2021 08:30:37 +0800</pubDate><guid>https://fwhyy.com/2021/02/what-you-see-is-not-necessarily-true/</guid><description>&lt;p&gt;年末了，再说说加班的问题，其实加班这个话题之前已经写过两篇了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;蹭个热度，也说说 996&lt;/li&gt;
&lt;li&gt;你的加班有价值吗？&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>dotNet Core 3.1 使用 Elasticsearch</title><link>https://fwhyy.com/2021/01/dotnet-core-3-uses-elasticsearch/</link><pubDate>Mon, 25 Jan 2021 09:36:06 +0800</pubDate><guid>https://fwhyy.com/2021/01/dotnet-core-3-uses-elasticsearch/</guid><description>&lt;p&gt;Elasticsearch 是基于 Lucene 的搜索引擎。可以非常方便地实现分布式的全文搜索，本文介绍在 dotNet Core 3.1 中怎样使用 Elasticsearch 。&lt;/p&gt;</description></item><item><title>说说 RabbiMQ 的应答模式</title><link>https://fwhyy.com/2021/01/talk-about-the-response-mode-of-rabbimq/</link><pubDate>Mon, 11 Jan 2021 08:08:40 +0800</pubDate><guid>https://fwhyy.com/2021/01/talk-about-the-response-mode-of-rabbimq/</guid><description>&lt;p&gt;RabbiMQ 我们都很熟悉了，是很常用的一个开源消息队列。搞懂 RabbiMQ 的应答模式对我们排查错误很有帮助，也能避免一些坑。本文说说 RabbiMQ 的应答模式。&lt;/p&gt;
&lt;p&gt;生产者发出一条消息给 RabbiMQ ，服务端将消息推送给消费者，消费者处理完消息后告诉 RabbiMQ，我已经接收到消息并处理了，RabbiMQ 收到通知后会将消息从队列中删除。 消费者通知 MQ 的这个过程就是消息的应答。在 RabbiMQ 中有两种应答模式：自动应答和手动应答。&lt;/p&gt;</description></item><item><title>CentOS7 中使用 Supervisor 部署 dotNET Core 程序</title><link>https://fwhyy.com/2020/12/deploying-dotnet-core-programs-with-supervisor-in-centos7/</link><pubDate>Mon, 28 Dec 2020 09:43:34 +0800</pubDate><guid>https://fwhyy.com/2020/12/deploying-dotnet-core-programs-with-supervisor-in-centos7/</guid><description>&lt;p&gt;在 CentOS 中部署 dotNET Core 程序，我们通常会使用 Docker ，方便快捷，版本更新也非常方便，但有时客户要求直接在服务器上进行 dotNET Core 程序的部署，这时就需要使用守护进程，本文就介绍使用守护进程 Supervisor 进行 dotNET Core 程序的部署。&lt;/p&gt;</description></item><item><title>一个端口搞定所有应用</title><link>https://fwhyy.com/2020/12/one-port-handles-all-applications/</link><pubDate>Mon, 14 Dec 2020 09:40:05 +0800</pubDate><guid>https://fwhyy.com/2020/12/one-port-handles-all-applications/</guid><description>&lt;p&gt;在产品或项目的发布部署中，往往需要很多的端口来对应不同的应用，特别是前后端分离的架构，更是如此，比如：有 PC 端的前端、移动端的前端和 WebAPI ，这就需要三个端口了：&lt;/p&gt;</description></item><item><title>C# ：异步编程的注意点</title><link>https://fwhyy.com/2020/12/csharp-points-for-attention-in-asynchronous-programming/</link><pubDate>Tue, 01 Dec 2020 09:29:36 +0800</pubDate><guid>https://fwhyy.com/2020/12/csharp-points-for-attention-in-asynchronous-programming/</guid><description>&lt;p&gt;在上一篇《C#：异步编程中的 async 和 await》 中简单介绍了在 C# 中的异步编程以及 async 和 await 编程模型，本文介绍下异步编程的注意事项，主要有以下几个方面。&lt;/p&gt;</description></item><item><title>C#：异步编程中的 async 和 await</title><link>https://fwhyy.com/2020/11/csharp-async-and-await-in-asynchronous-programming/</link><pubDate>Mon, 16 Nov 2020 09:59:19 +0800</pubDate><guid>https://fwhyy.com/2020/11/csharp-async-and-await-in-asynchronous-programming/</guid><description>&lt;p&gt;async 和 await 在 C# 5.0 就已经引入了，用来处理异步编程，但之前用的相对较少，现在在 dotNet Core 时代，已经使用的非常普遍，很多的开源组件中提供了大量的后缀为 Async （异步）的方法。本文就简单讲讲 async 和 await。&lt;/p&gt;</description></item><item><title>重读《打造Facebook》</title><link>https://fwhyy.com/2020/11/great-companies-can-also-learn-from-and-learn-from/</link><pubDate>Mon, 02 Nov 2020 09:52:08 +0800</pubDate><guid>https://fwhyy.com/2020/11/great-companies-can-also-learn-from-and-learn-from/</guid><description>&lt;p&gt;第一次看《打造Facebook》是在2013年，微博上的一位朋友推荐的，前几天又大概翻了一遍，全书主要讲作者王淮在 Facebook 的从业经历以及离职后对天使投资和创业的一些想法，作者的分享在很多地方是值得我们学习和借鉴的。&lt;/p&gt;</description></item><item><title>dotNet Core 3.1 使用 Aspose （部署 Docker）</title><link>https://fwhyy.com/2020/10/dotnet-core-3-1-uses-aspose-deploy-docker/</link><pubDate>Mon, 19 Oct 2020 07:48:55 +0800</pubDate><guid>https://fwhyy.com/2020/10/dotnet-core-3-1-uses-aspose-deploy-docker/</guid><description>&lt;p&gt;在之前的文章《Dotnet Core 中使用Aspose（部署Docker）》中介绍了在 dotNet Core2.1 中使用 Aspose ，并部署到 Docker 中，现在 dotNET Core 升级到了 3.1 ，Docker 镜像发生了变化，一些依赖的安装也有些变化。&lt;/p&gt;</description></item><item><title>为什么这么忙，还依然做不好事情</title><link>https://fwhyy.com/2020/09/why-are-you-so-busy-and-still-cant-do-well/</link><pubDate>Wed, 30 Sep 2020 09:46:53 +0800</pubDate><guid>https://fwhyy.com/2020/09/why-are-you-so-busy-and-still-cant-do-well/</guid><description>&lt;p&gt;一直都很喜欢《重来》系列，最近出了《重来3：跳出疯狂的忙碌》，第一时间在微信读书中阅读了，让我们印象比较深刻的就是「冷静」和「效率」，本文主要说说效率的问题。&lt;/p&gt;</description></item><item><title>dotNET Core：编码规范</title><link>https://fwhyy.com/2020/09/dotnet-core-coding-specification/</link><pubDate>Mon, 14 Sep 2020 09:44:15 +0800</pubDate><guid>https://fwhyy.com/2020/09/dotnet-core-coding-specification/</guid><description>&lt;p&gt;在项目开发过程中，由于时间紧、任务重，很容易导致面向功能编程。实现相同的功能，代码可以写的很优雅，也可以写的很晦涩和复杂。现在的工作，都需要进行团队协作，代码就需要有一定的规范进行指引，因为我们需要写出让人可以轻易读懂的代码，而不仅仅是机器。&lt;/p&gt;</description></item><item><title>程序员是终身学习的职业，应该怎么学习？</title><link>https://fwhyy.com/2020/08/programmer-is-a-lifelong-learning-profession-how-should-i-learn/</link><pubDate>Mon, 24 Aug 2020 09:41:17 +0800</pubDate><guid>https://fwhyy.com/2020/08/programmer-is-a-lifelong-learning-profession-how-should-i-learn/</guid><description>&lt;p&gt;在上一篇《一款用了就不想走的工具》中介绍了一款工具 Notion ，可以做学习的规划、时间的管理、学习的记录等，但学习本身还是需要一些方法的，本文谈谈我对学习的一些感悟。&lt;/p&gt;</description></item><item><title>一款用了就不想走的工具</title><link>https://fwhyy.com/2020/08/a-tool-you-dont-want-to-go-when-you-use-it/</link><pubDate>Mon, 17 Aug 2020 09:01:24 +0800</pubDate><guid>https://fwhyy.com/2020/08/a-tool-you-dont-want-to-go-when-you-use-it/</guid><description>&lt;p&gt;程序员是一个需要终身学习的职业，一个好的知识管理工具可以给我们的学习加成，对我来说，知识管理分为：笔记、Todo List、日历 等。本文要推荐的是一款 All In One 的工具，在此之前，先看看我用过的那些工具吧。&lt;/p&gt;</description></item><item><title>dotNET：怎样处理程序中的异常（实战篇）？</title><link>https://fwhyy.com/2020/08/dotnet-how-to-handle-exceptions-in-programs-practical/</link><pubDate>Mon, 03 Aug 2020 17:38:52 +0800</pubDate><guid>https://fwhyy.com/2020/08/dotnet-how-to-handle-exceptions-in-programs-practical/</guid><description>&lt;p&gt;在上篇 《dotNET：怎样处理程序中的异常（理论篇）》 中讲了一些程序中出现异常怎样处理的理论知识，本文将以代码的方式来进行实践。&lt;/p&gt;</description></item><item><title>dotNET：怎样处理程序中的异常（理论篇）？</title><link>https://fwhyy.com/2020/07/dotnet-how-to-handle-exceptions-in-programs/</link><pubDate>Mon, 20 Jul 2020 17:36:05 +0800</pubDate><guid>https://fwhyy.com/2020/07/dotnet-how-to-handle-exceptions-in-programs/</guid><description>&lt;p&gt;平时在软件开发的过程中，首先是要保证功能可以正常运行，满足业务需求，除此之外，还需要考虑代码在异常的时候怎么处理，让程序能够健壮地运行。正确合理地处理异常可以减少程序的 Bug、保证代码质量，当然也不是一件很容易的事。&lt;/p&gt;</description></item><item><title>Nginx：rewrite 的几个技巧</title><link>https://fwhyy.com/2020/07/nginx-some-skills-of-rewriting/</link><pubDate>Mon, 06 Jul 2020 17:10:59 +0800</pubDate><guid>https://fwhyy.com/2020/07/nginx-some-skills-of-rewriting/</guid><description>&lt;p&gt;在软件的发布中，我们经常会使用到 Nginx，Nginx 的功能非常的庞杂，其中 rewrite 是一个非常常用的功能模块，本文介绍 rewrite 的基本概念和几个小技巧。&lt;/p&gt;</description></item><item><title>如何激发团队潜能？</title><link>https://fwhyy.com/2020/06/how-to-stimulate-team-potential/</link><pubDate>Sun, 28 Jun 2020 12:06:25 +0800</pubDate><guid>https://fwhyy.com/2020/06/how-to-stimulate-team-potential/</guid><description>&lt;p&gt;每个技术人员最终可能都会走上管理岗位，从最初的开发 Leader、到部门负责人、甚至到 CTO,这每一个角色的转变，都需要付出巨大的努力去进行思维的转变。最近读的《授权》这本书可以让我们更好地胜任管理这个岗位。&lt;/p&gt;</description></item><item><title>dotNET Core 3.X 使用 Autofac 来增强依赖注入</title><link>https://fwhyy.com/2020/06/dotnet-core-3-uses-autofac-to-enhance-dependency-injection/</link><pubDate>Mon, 08 Jun 2020 12:02:56 +0800</pubDate><guid>https://fwhyy.com/2020/06/dotnet-core-3-uses-autofac-to-enhance-dependency-injection/</guid><description>&lt;p&gt;在上一篇《dotNET Core 3.X 依赖注入》中简单介绍了 dotNET Core 框架本身的依赖注入功能，大部分情况下使用框架的依赖注入功能就可以满足了，在一些特殊场景下，我们就需要引入第三方的注入框架。&lt;/p&gt;</description></item><item><title>dotNET Core 3.X 依赖注入</title><link>https://fwhyy.com/2020/06/dotnet-core-3-dependency-injection/</link><pubDate>Mon, 01 Jun 2020 11:57:32 +0800</pubDate><guid>https://fwhyy.com/2020/06/dotnet-core-3-dependency-injection/</guid><description>&lt;p&gt;如果说在之前的 dotNET 版本中，依赖注入还是个比较新鲜的东西，那么在 dotNET Core 中已经是随处可见了，可以说整个 dotNET Core 的框架是构建在依赖注入框架之上。本文讲解下对 dotNET Core 中依赖注入的理解。&lt;/p&gt;</description></item><item><title>读《鞋狗》</title><link>https://fwhyy.com/2020/05/shoe-reading-dog/</link><pubDate>Mon, 18 May 2020 11:53:11 +0800</pubDate><guid>https://fwhyy.com/2020/05/shoe-reading-dog/</guid><description>&lt;p&gt;最近读了耐克创始人菲尔·奈特 Phil Knight 的自传，读后感比较零散，所以使用刘韧体来写写了。&lt;/p&gt;</description></item><item><title>Jenkins 中以构建 Tag 来实现版本管理</title><link>https://fwhyy.com/2020/04/jenkins-implements-version-management-by-building-tags/</link><pubDate>Mon, 27 Apr 2020 11:44:33 +0800</pubDate><guid>https://fwhyy.com/2020/04/jenkins-implements-version-management-by-building-tags/</guid><description>&lt;p&gt;好的工具和流程能使我们事半功倍，而这个过程是不断迭代和演进的。关于这一块的内容，之前写过几篇文章：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247483697&amp;amp;idx=1&amp;amp;sn=5bb54ebc35bac60b141c8c982159cfdb&amp;amp;chksm=fb56c7f1cc214ee7c671f5a8ddfe50887803dd4a3c62f50f011fa009931622a9fe20ff69cd1b&amp;amp;scene=21#wechat_redirect"&gt;在团队中使用GitLab中的Merge Request工作模式&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247483790&amp;amp;idx=1&amp;amp;sn=32208bf396e3b4afc9fddb5dcc05a156&amp;amp;chksm=fb56c74ecc214e5811b06711094e1a83ba8bf0770baea06a8c6c420654b3d70536be711817f1&amp;amp;scene=21#wechat_redirect"&gt;敏捷下的需求和代码分支管理&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mp.weixin.qq.com/s?__biz=MzU0NjgzNzQyMw==&amp;amp;mid=2247483844&amp;amp;idx=1&amp;amp;sn=b9abb7fe776b4a61fd639c979bc55c0c&amp;amp;chksm=fb56c704cc214e124a4d336a09334169a1bf524f876d525a4f959084f692a00ae33192b0b6d4&amp;amp;token=788167640&amp;amp;lang=zh_CN#rd"&gt;不断进化的分支和需求管理&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;现在又有了些新的变化和改进，之所以需要改进，肯定是遇到问题了，那么就先从问题来开始今天的文章。&lt;/p&gt;</description></item><item><title>dotNET Core 3.X 使用 Jwt 实现接口认证</title><link>https://fwhyy.com/2020/04/using-jwt-to-implement-interface-authentication-in-dotnet-core-3/</link><pubDate>Mon, 20 Apr 2020 07:19:13 +0800</pubDate><guid>https://fwhyy.com/2020/04/using-jwt-to-implement-interface-authentication-in-dotnet-core-3/</guid><description>&lt;p&gt;在前后端分离的架构中，前端需要通过 API 接口的方式获取数据，但 API 是无状态的，没有办法知道每次请求的身份，也就没有办法做权限的控制。如果不做控制，API 就对任何人敞开了大门，只要拿到了接口地址就可以进行调用，这是非常危险的。本文主要介绍下在 dotNET Core Web API 中使用 Jwt 来实现接口的认证。&lt;/p&gt;</description></item><item><title>dotNET Core 3.X 请求处理管道和中间件</title><link>https://fwhyy.com/2020/04/dotnet-core-3-request-processing-pipeline-and-middleware/</link><pubDate>Mon, 13 Apr 2020 07:07:22 +0800</pubDate><guid>https://fwhyy.com/2020/04/dotnet-core-3-request-processing-pipeline-and-middleware/</guid><description>&lt;p&gt;理解 dotNET Core 中的管道模型，对我们学习 dotNET Core 有很大的好处，能让我们知其然，也知其所以然，这样在使用第三方组件或者自己写一些扩展时，可以避免入坑，或者说避免同样的问题多次入坑。&lt;/p&gt;</description></item><item><title>dotNET Core 3.X 使用 Web API</title><link>https://fwhyy.com/2020/04/totnet-core-3-using-web-api/</link><pubDate>Wed, 01 Apr 2020 06:48:56 +0800</pubDate><guid>https://fwhyy.com/2020/04/totnet-core-3-using-web-api/</guid><description>&lt;p&gt;现在的 Web 开发大多都是前后端分离的方式，后端接口的正确使用显得尤为重要，本文讲下在 dotNET Core 3.X 下使用 Web API 。&lt;/p&gt;</description></item><item><title>程序员还有35岁的坎吗？</title><link>https://fwhyy.com/2020/03/is-there-a-35-year-old-bar-for-programmers/</link><pubDate>Mon, 23 Mar 2020 07:48:55 +0800</pubDate><guid>https://fwhyy.com/2020/03/is-there-a-35-year-old-bar-for-programmers/</guid><description>&lt;p&gt;昨天晚上和一多年未见的前同事聊天，提到了程序员的年龄歧视问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自己年龄也 30 出头了，在思考 IT 届流传的 35 岁是一个坎的问题；&lt;/li&gt;
&lt;li&gt;开始注重提升管理能力，担心35岁之后，一线写代码的岗位不能胜任；&lt;/li&gt;
&lt;li&gt;公司在招聘新人的时候，有明确的年龄限制。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>远程办公也可以高效</title><link>https://fwhyy.com/2020/03/telecommuting-can-also-be-efficient/</link><pubDate>Mon, 09 Mar 2020 07:19:57 +0800</pubDate><guid>https://fwhyy.com/2020/03/telecommuting-can-also-be-efficient/</guid><description>&lt;p&gt;因为疫情，全中国人民都过了一个难忘的春节，而身在武汉的我，更是没有出家门半步，坚决做到不过国家添乱。从开始的2月14到后来的2月20日，再到现在的3月10日，官方发布的复工日期一次次的推迟，我们也做好了长时间远程在家办公的准备。&lt;/p&gt;</description></item><item><title>CentOS7 安装 Jenkins（ 构建 Vue 和 dotNET Core ）</title><link>https://fwhyy.com/2020/02/centos7-install-jenkins/</link><pubDate>Tue, 04 Feb 2020 13:36:57 +0800</pubDate><guid>https://fwhyy.com/2020/02/centos7-install-jenkins/</guid><description>&lt;p&gt;之前的自动构建工具 Jenkins 是部署在公司内网的 Windows 服务器上，现在武汉处于非常时期，兄弟们都在家自我隔离，为了远程提交的代码能自动构建，需要在外网的 CentOS 服务器上搭建 Jenkins 环境来进行构建工作。&lt;/p&gt;</description></item><item><title>写公众号的这一年多</title><link>https://fwhyy.com/2020/01/the-official-account-has-been-written-for-more-than-a-year/</link><pubDate>Tue, 28 Jan 2020 14:29:57 +0800</pubDate><guid>https://fwhyy.com/2020/01/the-official-account-has-been-written-for-more-than-a-year/</guid><description>&lt;p&gt;2018年五月，在微信发布公众号助手之时我开通了个人公众号「不止dotNET」，到现在已经一年半多的时间了，非常时期，在家自我隔离，没事写写总结。&lt;/p&gt;</description></item><item><title>2019 年终总结</title><link>https://fwhyy.com/2020/01/2019-summary/</link><pubDate>Sat, 25 Jan 2020 14:21:57 +0800</pubDate><guid>https://fwhyy.com/2020/01/2019-summary/</guid><description>&lt;p&gt;老板每次跟我们开会总会说起写总结的重要性，很庆幸我一直都有这个习惯。依然是要在大年初一到来之前写完这个总结。&lt;/p&gt;</description></item><item><title>dotNET Core 中怎样操作AD（续1）</title><link>https://fwhyy.com/2020/01/how-to-operate-ad-in-dotnet-core-continued/</link><pubDate>Mon, 20 Jan 2020 07:40:14 +0800</pubDate><guid>https://fwhyy.com/2020/01/how-to-operate-ad-in-dotnet-core-continued/</guid><description>&lt;p&gt;在之前的文章《&lt;a href="http://fwhyy.com/2019/09/how-to-operate-ad-in-dotnet-core/"&gt;dotNET Core 中怎样操作 AD？&lt;/a&gt;》中主要以将AD的数据同步到数据库的场景来描述了在 dotNetCore 中怎样操作AD，本文将继续介绍一些在 dotNetCore 中操作 AD 的其他常用操作。&lt;/p&gt;</description></item><item><title>dotNetCore操作Redis（含CentOS7哨兵模式部署）</title><link>https://fwhyy.com/2020/01/dotnetcore-operation-redis/</link><pubDate>Wed, 08 Jan 2020 06:58:14 +0800</pubDate><guid>https://fwhyy.com/2020/01/dotnetcore-operation-redis/</guid><description>&lt;p&gt;现在说到使用缓存中间件基本就是 Redis 了，通常开发环境或测试环境部署一个单机版就可以运行了，但要上生产环境还需要进行高可用的方式来部署，本文说说在 CentOS7 中 Redis 高可用的部署以及在 dotNetCore 中怎样调用。&lt;/p&gt;</description></item><item><title>搭建独立博客，这款评论插件不能错过</title><link>https://fwhyy.com/2019/12/build-an-independent-blog-this-comment-plug-in-cant-be-missed/</link><pubDate>Mon, 30 Dec 2019 06:58:14 +0800</pubDate><guid>https://fwhyy.com/2019/12/build-an-independent-blog-this-comment-plug-in-cant-be-missed/</guid><description>&lt;p&gt;微信公众号因为申请的时间晚，一直到现在都无法开通评论功能，之前博客一直使用的多说作为评论系统，自从多说关闭后，好多年都处于无评论状态，最近发现 &lt;code&gt;gitalk&lt;/code&gt; 还不错，所以在博客中进行了对 &lt;code&gt;gitalk&lt;/code&gt; 的集成，特此记录。&lt;/p&gt;</description></item><item><title>读《可复制的领导力》</title><link>https://fwhyy.com/2019/12/read-replicable-leadership/</link><pubDate>Mon, 23 Dec 2019 22:56:03 +0800</pubDate><guid>https://fwhyy.com/2019/12/read-replicable-leadership/</guid><description>&lt;p&gt;最近很忙，是特别忙，连上厕所的时间都在回复着各种消息，但还是挤时间看完了《可复制的领导力》，这本书也是领导推荐的。&lt;/p&gt;</description></item><item><title>读《持续交付2.0》</title><link>https://fwhyy.com/2019/11/read-continuous-delivery-2-0/</link><pubDate>Mon, 25 Nov 2019 23:52:54 +0800</pubDate><guid>https://fwhyy.com/2019/11/read-continuous-delivery-2-0/</guid><description>&lt;p&gt;几年前看过《持续交付(发布可靠软件的系统方法)》，感触不是很深，最近看了这本书的译者乔梁编写的《持续交付2.0》，结合工作中的种种，又有一种相见恨晚的感觉。可见好书是需要经常翻阅的，每次都会带来新的收获和思考。&lt;/p&gt;</description></item><item><title>“兼职”运维的常用命令</title><link>https://fwhyy.com/2019/11/common-orders-for-part-time-operation-and-maintenance/</link><pubDate>Mon, 18 Nov 2019 23:49:54 +0800</pubDate><guid>https://fwhyy.com/2019/11/common-orders-for-part-time-operation-and-maintenance/</guid><description>&lt;p&gt;自从产品转到了 dotNET Core 之后，更深入的接触 Linux和 Docker ，而我每天的工作中，有一部分时间相当于在“兼职”做一些运维的事情。下面是一些在日常中常用的命令，算是个备忘吧。&lt;/p&gt;</description></item><item><title>技术管理者怎样跳出“泥潭”</title><link>https://fwhyy.com/2019/10/how-to-get-out-of-the-mire-for-technical-managers/</link><pubDate>Thu, 31 Oct 2019 06:47:16 +0800</pubDate><guid>https://fwhyy.com/2019/10/how-to-get-out-of-the-mire-for-technical-managers/</guid><description>&lt;p&gt;近几年面试了不少新人，当问到职业规划时，大多都会说先积累技术，然后往架构师的方向发展。这可能是技术人的一个特质，喜欢跟机器相处，沉浸在代码之中，而不喜欢跟人打交道。&lt;/p&gt;</description></item><item><title>使用RabbitMQ实现接口补偿</title><link>https://fwhyy.com/2019/10/using-rabbitmq-to-implement-interface-compensation/</link><pubDate>Fri, 11 Oct 2019 06:32:37 +0800</pubDate><guid>https://fwhyy.com/2019/10/using-rabbitmq-to-implement-interface-compensation/</guid><description>&lt;h2 id="业务背景"&gt;业务背景&lt;/h2&gt;
&lt;p&gt;在我们的日常开发中，经常需要调用第三方接口来进行数据传递，在调用接口的过程中，会因为各种原因导致调用的失败。这时我们希望能有一种机制实现对失败的接口的重复调用，并且能够实现人工干预。&lt;/p&gt;</description></item><item><title>dotNET Core 中怎样操作 AD？</title><link>https://fwhyy.com/2019/09/how-to-operate-ad-in-dotnet-core/</link><pubDate>Mon, 30 Sep 2019 22:18:21 +0800</pubDate><guid>https://fwhyy.com/2019/09/how-to-operate-ad-in-dotnet-core/</guid><description>&lt;p&gt;做企业应用开发难免会跟 AD 打交道，在之前的 dotNET FrameWork 时代，通常使用 System.DirectoryServices 的相关类来操作 AD ，在 dotNET Core 中没有这个命名空间，在张善友大佬的推荐下，知道了 Novell.Directory.Ldap。&lt;/p&gt;</description></item><item><title>dotNET Core实现分布式环境下的流水号唯一</title><link>https://fwhyy.com/2019/09/implementation-of-unique-pipeline-number-in-distributed-environment-by-dotnet-core/</link><pubDate>Sat, 14 Sep 2019 23:30:19 +0800</pubDate><guid>https://fwhyy.com/2019/09/implementation-of-unique-pipeline-number-in-distributed-environment-by-dotnet-core/</guid><description>&lt;h2 id="业务背景"&gt;业务背景&lt;/h2&gt;
&lt;p&gt;在管理系统中，很多功能模块都会涉及到各种类型的编号，例如：流程编号、订单号、合同编号等等。编号各有各自的规则，但通常有一个流水号来确定编号的唯一性，保证流水号的唯一，在不同的环境中实现方式有所不同。本文将介绍在单机和分布式环境中保证流水号唯一的方式。&lt;/p&gt;</description></item><item><title>你的技术债还了吗？</title><link>https://fwhyy.com/2019/09/have-you-paid-your-technical-debt-yet/</link><pubDate>Mon, 09 Sep 2019 07:03:22 +0800</pubDate><guid>https://fwhyy.com/2019/09/have-you-paid-your-technical-debt-yet/</guid><description>&lt;h2 id="什么是技术债"&gt;什么是技术债？&lt;/h2&gt;
&lt;p&gt;技术债是由沃德·坎宁安在1992年提出，指我们在软件架构或代码编写过程中有意无意地做了错误的决策。随着时间的累积，这种错误会越来越多，就像背负了很多债务一样。&lt;/p&gt;</description></item><item><title>.NET 程序员如何学习Vue</title><link>https://fwhyy.com/2019/08/net-programmer-how-to-learn-vue/</link><pubDate>Sat, 31 Aug 2019 16:32:05 +0800</pubDate><guid>https://fwhyy.com/2019/08/net-programmer-how-to-learn-vue/</guid><description>&lt;p&gt;之所以取这个标题，是因为本文来自内部培训的整理，培训的对象是公司的 .NET 程序员，.NET 程序员学习 Vue 是为了在项目中做二次开发时能够更好地跟产品对接。&lt;/p&gt;</description></item><item><title>dotNET Core WebAPI 统一处理（返回值、参数验证、异常）</title><link>https://fwhyy.com/2019/08/unified-processing-of-dotnet-core-web-api-return-value-parameter-validation-exception/</link><pubDate>Wed, 21 Aug 2019 06:28:27 +0800</pubDate><guid>https://fwhyy.com/2019/08/unified-processing-of-dotnet-core-web-api-return-value-parameter-validation-exception/</guid><description>&lt;p&gt;现在 Web 开发比较流行前后端分离，我们的产品也是一样，前端使用Vue，后端使用 dotNet Core WebAPI ，在写 API 的过程中有很多地方需要统一处理：&lt;/p&gt;</description></item><item><title>书籍推荐：《C#7.0本质论》</title><link>https://fwhyy.com/2019/08/book-recommendation-csharp-7-essence/</link><pubDate>Sun, 11 Aug 2019 07:05:47 +0800</pubDate><guid>https://fwhyy.com/2019/08/book-recommendation-csharp-7-essence/</guid><description>&lt;p&gt;在dotNet平台中有多种开发语言可以使用，C#无疑是其中应用得最为广泛的。学习一门编程语言最好的方式就是找一本好书系统地学习，我读过的关于C#的书籍中，我认为下面三本最为经典：&lt;/p&gt;</description></item><item><title>KPI在小型产品团队中的实践</title><link>https://fwhyy.com/2019/07/practice-of-kpi-in-small-product-team/</link><pubDate>Mon, 29 Jul 2019 07:05:59 +0800</pubDate><guid>https://fwhyy.com/2019/07/practice-of-kpi-in-small-product-team/</guid><description>&lt;p&gt;最近公司决定对所有技术人员实行KPI考核，曾经一度非常反感KPI的我也被要求制定产品团队的KPI指标。为什么要实行KPI考核，因为在项目团队和产品团队的管理中出现了问题：&lt;/p&gt;</description></item><item><title>程序员如何学习英语</title><link>https://fwhyy.com/2019/07/how-programmers-learn-english/</link><pubDate>Sun, 21 Jul 2019 09:57:50 +0800</pubDate><guid>https://fwhyy.com/2019/07/how-programmers-learn-english/</guid><description>&lt;p&gt;首先，这不是一篇广告，虽然这个标题很像。&lt;/p&gt;
&lt;p&gt;其次，我的英语水平也很一般，所以更多的是谈谈一些失败的经历和思考，俗话说，成功的经验不可复制，失败的经验倒可以让我们少走弯路。&lt;/p&gt;
&lt;!-- more --&gt; 
&lt;p&gt;英语的重要性毋庸置疑，对于程序员来说更甚，一些最新的技术资料是英文的，很多开源软件的官方文档也是英文的，如果想进入外企英语是必备条件。我就是英文不好，连投递外企简历的勇气都没有。&lt;/p&gt;
&lt;h2 id="我的英语水平"&gt;我的英语水平&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;学生时代四级最高分58&lt;/li&gt;
&lt;li&gt;工作后立过无数次Falg，到现在没有明显进步&lt;/li&gt;
&lt;li&gt;听说基本为零，读写凑活，技术相关文档能基本能读懂，借助翻译工具可以和老外书信交流&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="学英语目的是什么"&gt;学英语目的是什么&lt;/h2&gt;
&lt;p&gt;语言分为听说读写，我们在学习母语的的时候，通常是先听说后读写，而在学习英语时往往是相反的，像我就是，读写强于听说。很多的英语学习方法会建议要按照学习母语的方式来学习英语，我认为也不完全是对的。最重要的是要搞清楚学习的目的是什么，然后对症下药，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;出国旅游或者想要面试外企，就要侧重于听说&lt;/li&gt;
&lt;li&gt;看英文技术书籍、网站、博客，在Github上参与开源项目，就要侧重于读写&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对我自己来说：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需要阅读英文技术资料&lt;/li&gt;
&lt;li&gt;经常会在stackoverflow上找一些问题的答案&lt;/li&gt;
&lt;li&gt;使用了某个开源代码，需要在issues中寻求帮助&lt;/li&gt;
&lt;li&gt;在Linode购买了vps，在Tickets中需要和老外进行沟通&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以我更偏重在读写上的提高，在读写搞定的情况下，再有针对性地去练习听说，YouTube这个庞大的资源库就是要学习好听力的强大动力。&lt;/p&gt;
&lt;h2 id="量变到质变"&gt;量变到质变&lt;/h2&gt;
&lt;p&gt;我非常相信任何事物都能从量变到质变，如果质变没有发生那就是量不够。下面是我有深刻体会到两个从量变到质变的例子：&lt;/p&gt;
&lt;h3 id="跑步"&gt;跑步&lt;/h3&gt;
&lt;p&gt;平常跑步，三五分钟就会大汗淋漓，之前从未想过在冬天的早晨，零下几度，还能跑到全身出汗。直到几年前的一个冬天早晨，出门跑步，10分钟的时候，身上还没发热，二十分钟的时候，也只是微微出汗，等到1个小时左右，完成了10公里时，全身已经汗透。&lt;/p&gt;
&lt;h3 id="音乐"&gt;音乐&lt;/h3&gt;
&lt;p&gt;2017年春，同学在群里有人推荐了《成都》这首歌曲，非常喜欢，连续一个礼拜的上下班途中，单曲循环听，这一个礼拜的时间，我并没有刻意地练习怎么唱，就是因为不断的重复，使我学会了这首歌。&lt;/p&gt;
&lt;p&gt;英语的学习，不管是记单词，还是阅读，或是听说，如果有大量重复的训练，必然会产生一定的效果，但我们常常是三分钟热度就放弃，我也是如此，就像跑步，10分钟的时候，就已经停下了脚步，不管你跑了多少次，始终都感受不到大汗淋漓的畅快。&lt;/p&gt;
&lt;p&gt;今年年初，花99元报了一期水滴阅读，需要坚持100天，起初积极性很高，再加上老师在群里的督促和坚持打卡可以赠送书籍的诱惑，开始的一两个月每天都花固定时间去学习，做习题，后面随着难度的增加，间歇性的没有打卡，慢慢也就放弃了，要知道，坚持一件事情很难，放弃可是分分钟的事。&lt;/p&gt;
&lt;h2 id="强烈的意愿"&gt;强烈的意愿&lt;/h2&gt;
&lt;p&gt;每个人都会有惰性，这个惰性体现在是不是你所关注的事情。我老婆经常说我，家里的买的拼装家具，小孩的拼装玩具，每次都要拖很久才去做，你自己买的健身器材的安装就非常积极。&lt;/p&gt;
&lt;p&gt;我反思了下，为什么我每次都没能够坚持呢？还是意愿不够强烈，对我来说，英语学习好学坏，对我的工作和生活不会造成什么影响：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;工作中查资料遇到有英文的，可以借助翻译工具&lt;/li&gt;
&lt;li&gt;生活中就更是更英语没什么交集&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候会有强烈的意愿呢？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当我们去准备面试时，我们必需精心地复习巩固面试所需要的专业编程技能，&lt;/li&gt;
&lt;li&gt;当在工作中遇到难题时，我们必需通过各种手段去解决，在这过程中，就会有很大的收获&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果您像我一样，英语不是生活和工作中的必需品，而又想学好它时，就要想办法提高自己学习的意愿，我能想到下面一些方式，当然每个人都有自己的方式：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Github上参与开源项目，可以从提issues开始&lt;/li&gt;
&lt;li&gt;找到国外大神的系列技术文章，然后制定一个小计划，比如在1个月内翻译10篇&lt;/li&gt;
&lt;li&gt;以赚积分为目标，在stackoverflow上用英文去回答别人的问题&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;英语和编程一样，需要不断实践才能提高&lt;/li&gt;
&lt;li&gt;无所谓形式，是先记单词，还是直接就阅读，语法到底需不需要学习，我觉得不太重要，主动或被动地让自己有强烈的意愿是关键&lt;/li&gt;
&lt;li&gt;制定目标，剩下的就是行动了，就像池大说的，让正确的事情持续发生，这其实就是量变到质变的过程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;希望本文对您有所帮助。&lt;/p&gt;</description></item><item><title>端到端测试实践：Jenkins集成TestCafe</title><link>https://fwhyy.com/2019/07/jenkins-and-testcafe/</link><pubDate>Mon, 08 Jul 2019 07:00:15 +0800</pubDate><guid>https://fwhyy.com/2019/07/jenkins-and-testcafe/</guid><description>&lt;p&gt;上一篇《&lt;a href="http://fwhyy.com/2019/07/some-thoughts-on-product-quality/"&gt;对产品质量的一点思考&lt;/a&gt;》中说到自动化测试的重要性，本文简单介绍下怎样在实际项目中实现端到端测试的自动化，在这里我们使用的端到端测试工具是TestCafe。&lt;/p&gt;
&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;p&gt;Jenkisn：2.183
TestCafe：1.3.0&lt;/p&gt;
&lt;h2 id="为什么采用testcafe做自动化测试"&gt;为什么采用TestCafe做自动化测试&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;前端Vue或是netCore要添加单元测试相对较复杂，需要一定的时间来沉淀，不能解燃眉之急&lt;/li&gt;
&lt;li&gt;经常会因为代码重构、代码合并等原因造成原本正常的功能出现问题，而这些问题在手动测试时不容易覆盖到&lt;/li&gt;
&lt;li&gt;TestCafe足够简单，只要使用过jQuery，基本可以几分钟上手&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="要实现的目标"&gt;要实现的目标&lt;/h2&gt;
&lt;p&gt;目前前端代码通过GitLab来进行管理，采用Merge Request的开发模式，开发人员的代码被合并到master后，Jenkins会自动构建到测试环境，希望自动化测试能做到下面两点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能在前端项目构建完成后自动执行TestCafe脚本进行测试&lt;/li&gt;
&lt;li&gt;能提供测试的完整结果&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="步骤"&gt;步骤&lt;/h2&gt;
&lt;p&gt;1、在Jenkins中新创建一个新的项目&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201280613334.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Git中配置的测试的代码地址&lt;code&gt;https://github.com/oec2003/testcafe-ci-demo.git&lt;/code&gt;是我fork的官网的一个例子,原项目地址为：&lt;code&gt;https://github.com/DevExpress-Examples/testcafe-ci-demo.git&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;2、增加构建步骤，选择执行Windows批处理命令&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201280614319.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201280614096.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;D:\Jenkins\Testcafe\node_modules\.bin\testcafe path:C:\Users\oec2003\AppData\Local\Google\Chrome\Application\chrome.exe tests/**/* -r xunit:res.xml
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面执行的命令分为三个部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;testcafe的执行程序&lt;/li&gt;
&lt;li&gt;测试的浏览器的路径，此处为chrome的路径，这里有一个小坑，直接执行命令时是可以使用chrome或ie来选择测试浏览器的，但配置在Jenkins中如果直接写chrome或ie会报异常，所以写了chrome执行程序的全路径&lt;/li&gt;
&lt;li&gt;将结果输出到xunit的xml文件中&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要想使用xunit，需要先使用下面命令进行安装&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install testcafe testcafe-reporter-xunit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3、添加构建后操作，选择Publish JUnit test result report&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201280614661.webp" alt="" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201280614568.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4、修改Jenkins中现有的前端项目的配置，增加构建后操作步骤，选择构建起他工程&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201280615176.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择第一步创建的测试项目即可。&lt;/p&gt;
&lt;p&gt;5、实际测试结果如下，所有测试用例的通过情况以列表形式展现，点击可以看详细信息&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201280615015.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Testcafe非常简单，有一定开发经验的程序员，可以在很短的时间内达到熟练的程度&lt;/li&gt;
&lt;li&gt;Testcafe虽然简单，但怎样去设置场景覆盖，让所有业务没有遗漏，这才是比较困难的，是我们需要着重思考的&lt;/li&gt;
&lt;li&gt;前端代码如果做了修改，特别是UI层面做了调整，测试代码需要同步修改&lt;/li&gt;
&lt;li&gt;只要能够持续下去，先从容易出错的模块开始，积少成多，软件质量的最后一道防线一定能守住&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>对产品质量的一点思考</title><link>https://fwhyy.com/2019/07/some-thoughts-on-product-quality/</link><pubDate>Mon, 01 Jul 2019 06:44:41 +0800</pubDate><guid>https://fwhyy.com/2019/07/some-thoughts-on-product-quality/</guid><description>&lt;p&gt;不管是做产品还是做项目，也不管是采用瀑布模型还是敏捷开发，我们都有一个终极目标，就是能按时交付质量可靠的功能，其中质量尤为重要。&lt;/p&gt;
&lt;p&gt;本文是我对产品质量的一点思考，如果您所在的团队代码质量很高，很少出BUG，那么可以私信我，我们可以交流下关于代码质量的一些问题。&lt;/p&gt;</description></item><item><title>书籍推荐：《More Effective C#》</title><link>https://fwhyy.com/2019/06/more-effective-csharp/</link><pubDate>Mon, 24 Jun 2019 06:31:53 +0800</pubDate><guid>https://fwhyy.com/2019/06/more-effective-csharp/</guid><description>&lt;p&gt;很多年前看过Bill Wagner的《Effective C#》第一版，涵盖了C#2.0相关语言特性的最佳实践，教我们怎样更优雅地去编写C#代码，当时觉得受益匪浅。最近拿到了《More Effective C#》第二版，目前看了大概三分之二，让我对C#的的应用有了更深入的了解，书虽没看完，但还是要推荐一下。&lt;/p&gt;</description></item><item><title>带你了解C#每个版本新特性</title><link>https://fwhyy.com/2019/06/learn-about-the-new-features-of-each-version-of-csharp/</link><pubDate>Sun, 16 Jun 2019 14:19:33 +0800</pubDate><guid>https://fwhyy.com/2019/06/learn-about-the-new-features-of-each-version-of-csharp/</guid><description>&lt;p&gt;上学时学习C#和.NET，当时网上的资源不像现在这样丰富，所以去电脑城买了张盗版的VS2005的光盘，安装时才发现是VS2003，当时有一种被坑的感觉，但也正是如此，让我有了一个完整的.NET的学习生涯。&lt;/p&gt;</description></item><item><title>不断进化的分支和需求管理</title><link>https://fwhyy.com/2019/06/evolutionary-branch-and-demand-management/</link><pubDate>Fri, 07 Jun 2019 09:22:10 +0800</pubDate><guid>https://fwhyy.com/2019/06/evolutionary-branch-and-demand-management/</guid><description>&lt;p&gt;昨天有朋友在公众号私信问我几个关于代码分支管理的问题，这几个问题是我去年写的《在团队中使用GitLab中的Merge Request工作模式》一文结尾时抛出的几个问题：&lt;/p&gt;</description></item><item><title>怎样学习和阅读技术书籍？</title><link>https://fwhyy.com/2019/06/how-to-learn-and-read-technical-books/</link><pubDate>Sun, 02 Jun 2019 15:08:16 +0800</pubDate><guid>https://fwhyy.com/2019/06/how-to-learn-and-read-technical-books/</guid><description>&lt;p&gt;技术的更新换代非常的迅速，作为一个技术人，需要持续不断地学习才能不被淘汰。但是学习没有速成的方法，只可能有一些技巧让我们事半功倍，本文是我对学习和读书的一点思考。&lt;/p&gt;</description></item><item><title>发布dotNetCore程序到Kubernetes</title><link>https://fwhyy.com/2019/05/publish-dotnetcore-program-to-kubernetes/</link><pubDate>Sun, 12 May 2019 11:02:54 +0800</pubDate><guid>https://fwhyy.com/2019/05/publish-dotnetcore-program-to-kubernetes/</guid><description>&lt;p&gt;上一篇《&lt;a href="http://fwhyy.com/2019/05/building-kubernetes-in-mac/"&gt;Mac中搭建Kubernetes&lt;/a&gt;》介绍了怎样在Mac中搭建单节点的&lt;code&gt;Kubernetes&lt;/code&gt;，本文将编写一个&lt;code&gt;dotNetCore&lt;/code&gt;的示例程序，并发布到&lt;code&gt;Kubernetes&lt;/code&gt;中。&lt;/p&gt;</description></item><item><title>Mac中搭建Kubernetes</title><link>https://fwhyy.com/2019/05/building-kubernetes-in-mac/</link><pubDate>Fri, 03 May 2019 22:33:22 +0800</pubDate><guid>https://fwhyy.com/2019/05/building-kubernetes-in-mac/</guid><description>&lt;p&gt;&lt;code&gt;Kubernetes&lt;/code&gt;是&lt;code&gt;Google&lt;/code&gt;和&lt;code&gt;RadHat&lt;/code&gt;公司共同主导的开源容器编排项目，功能非常强大，也非常的火热和流行，但同时里面也有很多的概念和名词需要我们去学习和理解。学习任何一个技术先需要把基础环境搭建起来，本篇就介绍怎样在&lt;code&gt;Mac&lt;/code&gt;中启动单节点的&lt;code&gt;Kubernetes&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>蹭个热度，也说说996</title><link>https://fwhyy.com/2019/04/996-icu/</link><pubDate>Mon, 22 Apr 2019 22:19:10 +0800</pubDate><guid>https://fwhyy.com/2019/04/996-icu/</guid><description>&lt;p&gt;最近996很火热，也来凑凑热闹，在文章的开始，先表明我的立场：坚决反对996。&lt;/p&gt;
&lt;p&gt;什么是996？&lt;/p&gt;</description></item><item><title>敏捷下的需求和代码分支管理</title><link>https://fwhyy.com/2019/03/requirements-and-code-branch-management-in-agile/</link><pubDate>Sun, 17 Mar 2019 13:54:04 +0800</pubDate><guid>https://fwhyy.com/2019/03/requirements-and-code-branch-management-in-agile/</guid><description>&lt;p&gt;在去年的一篇文章《在团队中使用GitLab中的Merge Request工作模式》中简单介绍了下&lt;code&gt;Git&lt;/code&gt;的几种模式和在团队中使用的&lt;code&gt;Merge Request&lt;/code&gt;的模式。文章的结尾也抛出了几个问题：&lt;/p&gt;</description></item><item><title>敏捷，每个人都有自己的理解</title><link>https://fwhyy.com/2019/02/agile-everyone-has-his-own-understanding/</link><pubDate>Sat, 23 Feb 2019 23:53:05 +0800</pubDate><guid>https://fwhyy.com/2019/02/agile-everyone-has-his-own-understanding/</guid><description>&lt;p&gt;2018年一直在尝试用敏捷的方式来管理团队，但执行的不够彻底，或者说不那么敏捷。 总结下来有下面一些问题：&lt;/p&gt;</description></item><item><title>2018 年终总结</title><link>https://fwhyy.com/2019/02/summary-of-2018/</link><pubDate>Thu, 07 Feb 2019 23:51:42 +0800</pubDate><guid>https://fwhyy.com/2019/02/summary-of-2018/</guid><description>&lt;p&gt;一直都有写总结的习惯，一方面思考下一年下来有哪些做的好的，哪些还需要改进。另一方面，若干年后再回过头看看，知道每年都发生了点什么。但写东西这事，不能耽搁，有了想法就要立即动笔记录，否则可能会不了了之。像我前两年的年终总结就是如此。&lt;/p&gt;</description></item><item><title>Office转PDF，Aspose太贵，怎么办</title><link>https://fwhyy.com/2019/01/office-to-pdf-aspose-is-too-expensive-how-to-do/</link><pubDate>Sun, 13 Jan 2019 13:48:21 +0800</pubDate><guid>https://fwhyy.com/2019/01/office-to-pdf-aspose-is-too-expensive-how-to-do/</guid><description>&lt;p&gt;在程序开发中经常需要将&lt;code&gt;Office&lt;/code&gt;文件转换成&lt;code&gt;PDF&lt;/code&gt;，著名的&lt;code&gt;Aspose&lt;/code&gt;的三大组件可以很容易完成这个功能，但是&lt;code&gt;Aspose&lt;/code&gt;的每个组件都单独收费，而且每个都卖的不便宜。在老大的提示下，换了一种思路来解决这个问题。&lt;/p&gt;</description></item><item><title>从减肥到跑马拉松</title><link>https://fwhyy.com/2018/12/from-losing-weight-to-running-a-marathon/</link><pubDate>Fri, 28 Dec 2018 22:19:01 +0800</pubDate><guid>https://fwhyy.com/2018/12/from-losing-weight-to-running-a-marathon/</guid><description>&lt;p&gt;这个月9号，广州这个没有冬天的南方城市气温居然降到了10度左右，而且早上还下起了小雨，在这样一个「恶劣」的天气下，我完成的我的第五个马拉松，而且还跑出了PB。&lt;/p&gt;</description></item><item><title>我用过的那些工具</title><link>https://fwhyy.com/2018/12/the-tools-i-used/</link><pubDate>Tue, 11 Dec 2018 23:15:18 +0800</pubDate><guid>https://fwhyy.com/2018/12/the-tools-i-used/</guid><description>&lt;p&gt;人和动物最大的区别就是人类能够制造和使用工具，在平时的工作和生活中，能够合理使用工具会给我们带来事半功倍的效果。最近的几年一直在使用iOS系统和Mac OSX系统，本文说说在这两个系统中我常用的一些工具。&lt;/p&gt;</description></item><item><title>dotNET Core中使用Aspose（部署Docker）</title><link>https://fwhyy.com/2018/11/using-aspose-in-dotnet-core/</link><pubDate>Thu, 22 Nov 2018 23:07:45 +0800</pubDate><guid>https://fwhyy.com/2018/11/using-aspose-in-dotnet-core/</guid><description>&lt;p&gt;在&lt;code&gt;dotnet&lt;/code&gt;下处理过&lt;code&gt;Office&lt;/code&gt;文档的相信对&lt;code&gt;Aspose&lt;/code&gt;都不陌生，&lt;code&gt;Aspose&lt;/code&gt;下面的三大组件：&lt;code&gt;Aspose.Cells&lt;/code&gt;、&lt;code&gt;Aspose.Slides&lt;/code&gt;、&lt;code&gt;Aspose.Words&lt;/code&gt;可以让我们很方便的操作&lt;code&gt;Office&lt;/code&gt;文档，或者将&lt;code&gt;Office&lt;/code&gt;导出为&lt;code&gt;PDF&lt;/code&gt;。&lt;/p&gt;</description></item><item><title>免费的东西最贵</title><link>https://fwhyy.com/2018/10/the-most-expensive-thing-is-free/</link><pubDate>Wed, 24 Oct 2018 00:30:19 +0800</pubDate><guid>https://fwhyy.com/2018/10/the-most-expensive-thing-is-free/</guid><description>&lt;p&gt;国庆期间，收到七牛的测试域名回收邮件，没细看也没怎么在意，因为我仅仅只是拿七牛的对象存储作为我博客的图床而已，但这两天发现我博客中的图片地址全部失效了，进入到七牛的管理后台，在对应的&lt;code&gt;bucket&lt;/code&gt;中图片已经不能预览和下载了。&lt;/p&gt;</description></item><item><title>你的加班有价值吗？</title><link>https://fwhyy.com/2018/10/is-your-overtime-worth/</link><pubDate>Sun, 21 Oct 2018 23:09:58 +0800</pubDate><guid>https://fwhyy.com/2018/10/is-your-overtime-worth/</guid><description>&lt;p&gt;今年一直在忙公司产品的事情，压力比较大，工作强度也比较大，不夸张的说，今年加的班应该比整个职业生涯加起来还多，所以也有了些思考和想法。&lt;/p&gt;</description></item><item><title>怎样提高开发效率（2018）</title><link>https://fwhyy.com/2018/09/how-to-improve-development-efficiency-2018/</link><pubDate>Mon, 17 Sep 2018 22:49:03 +0800</pubDate><guid>https://fwhyy.com/2018/09/how-to-improve-development-efficiency-2018/</guid><description>&lt;p&gt;开发效率可以从个人开发效率和团队开发效率来谈，抛开自由职业者，但凡在一个公司上班的程序员都必然是在一个团队中工作，所以每个人的个人效率最终都会转化为团队的效率。转化率有多大，取决于团队的凝聚力，每个人的劲是不是在往一处使。&lt;/p&gt;
&lt;p&gt;团队效率最重要的是沟通，我经常会碰到这样的情况：&lt;/p&gt;</description></item><item><title>怎样带领一个技术团队</title><link>https://fwhyy.com/2018/09/how-to-lead-a-technical-team/</link><pubDate>Mon, 03 Sep 2018 06:25:36 +0800</pubDate><guid>https://fwhyy.com/2018/09/how-to-lead-a-technical-team/</guid><description>&lt;p&gt;从2012年的&lt;code&gt;Team Leader&lt;/code&gt;到现在负责公司的产品团队，在技术管理的道路上也走了6年的时间，看过不少管理的书，也经历过从零开始组建一个团队，和团队成员的更替。下面谈谈我自己的一些感受和理解。&lt;/p&gt;</description></item><item><title>dotNET Core：配置</title><link>https://fwhyy.com/2018/08/dotnet-core-configure/</link><pubDate>Sun, 12 Aug 2018 22:13:39 +0800</pubDate><guid>https://fwhyy.com/2018/08/dotnet-core-configure/</guid><description>&lt;p&gt;在&lt;code&gt;dotNET Core&lt;/code&gt;中默认情况下没有了之前版本的&lt;code&gt;App.config&lt;/code&gt;和&lt;code&gt;Web.Config&lt;/code&gt;文件，换成了新的&lt;code&gt;json&lt;/code&gt;格式的配置文件。当然，如果想使用之前的方式也是可以的。下面说说在&lt;code&gt;dotNET Core&lt;/code&gt;中各种使用配置的方法。&lt;/p&gt;
&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;操作系统：macOS 10.13.5&lt;/li&gt;
&lt;li&gt;dotNET Core：2.1&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用原来的config文件"&gt;使用原来的config文件&lt;/h2&gt;
&lt;p&gt;如果你还念旧，想使用之前的&lt;code&gt;App.config&lt;/code&gt;或&lt;code&gt;Web.config&lt;/code&gt;，可以导入&lt;code&gt;System.Configuration.ConfigurationManager&lt;/code&gt;包，使用方式和之前一样。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201270825835.webp" alt="-w788" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System.Configuration;
...
static void Main(string[] args)
{
 var connection = ConfigurationManager.ConnectionStrings[&amp;#34;ConnectionStr&amp;#34;].ConnectionString;
 var mqHostName = ConfigurationManager.AppSettings[&amp;#34;MQHostName&amp;#34;];
 Console.WriteLine($&amp;#34;connection:{connection}&amp;#34;);
 Console.WriteLine($&amp;#34;mqHostName:{mqHostName}&amp;#34;);
 Console.ReadLine();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="命令行配置"&gt;命令行配置&lt;/h2&gt;
&lt;p&gt;1、创建一个控制台的应用程序&lt;code&gt;NetCoreConfigDemo&lt;/code&gt;；
2、导入依赖包，可以按需导入，也可以直接导入&lt;code&gt;Microsoft.AspNetCore&lt;/code&gt;的包，里面包含所有依赖的项；&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201270825585.webp" alt="-w1001" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、添加&lt;code&gt;using Microsoft.Extensions.Configuration;&lt;/code&gt;引用；
4、代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System;
using Microsoft.Extensions.Configuration;
namespace NetCoreConfigDemo
{
 class Program
 {
 static void Main(string[] args)
 {
 var builder = new ConfigurationBuilder()
 .AddCommandLine(args);
 var configration = builder.Build();
 Console.WriteLine($&amp;#34;name:{configration[&amp;#34;name&amp;#34;]}&amp;#34;);
 Console.ReadLine();
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5、运行时指定&lt;code&gt;name&lt;/code&gt;参数，在命令行中可以正常打印出来&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201270827596.webp" alt="-w676" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上面例子中的参数&lt;code&gt;name&lt;/code&gt;是在启动程序是指定的，如果想要程序有一个默认的参数值，可以在程序中初始化一个字典类&lt;code&gt;Dictionary&lt;/code&gt;，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
namespace NetCoreConfigDemo
{
 class Program
 {
 static void Main(string[] args)
 {
 var dic = new Dictionary&amp;lt;string, string&amp;gt;() { { &amp;#34;name&amp;#34;, &amp;#34;oec2003&amp;#34; } };
 var builder = new ConfigurationBuilder()
 .AddInMemoryCollection(dic)
 .AddCommandLine(args);
 var configration = builder.Build();
 Console.WriteLine($&amp;#34;name:{configration[&amp;#34;name&amp;#34;]}&amp;#34;);
 Console.ReadLine();
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;p&gt;注意：&lt;code&gt;AddInMemoryCollection&lt;/code&gt;必须放在&lt;code&gt;AddCommandLine&lt;/code&gt;的前面，否则默认值会覆盖掉在外部指定的参数值。&lt;/p&gt;</description></item><item><title>我们真的需要KPI吗?</title><link>https://fwhyy.com/2018/08/do-we-really-need-kpi/</link><pubDate>Fri, 03 Aug 2018 22:51:21 +0800</pubDate><guid>https://fwhyy.com/2018/08/do-we-really-need-kpi/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;工作十几年，经历过不少的公司，每个公司都有自己的管理方法，其中大公司比较偏爱使用KPI考核，小公司则直接靠人来管理。下面谈谈之前公司KPI考核制度和现在「松散」管理的对比。&lt;/p&gt;
&lt;h2 id="严格的kpi制度"&gt;严格的KPI制度&lt;/h2&gt;
&lt;p&gt;之前的公司在武汉研发中心有大概五六百的技术人员，每个团队的项目经理只考虑需求沟通、任务分配和资源协调。完全不用管团队成员是否有认真干活，员工的管理依赖KPI制度。当时开发岗的考核制度大致如下：&lt;/p&gt;
&lt;h3 id="工作量"&gt;工作量&lt;/h3&gt;
&lt;p&gt;任务系统的任务都会评估出一个工作量，以天为单位。计算方法为在季度末算出整个季度中完成的工作量和总出勤天数的一个比例。表明上看这个指标非常好，公司不用怕员工偷懒，相反员工还会主动去找事情做，因为担心工作量不够。当由于各种任务之间的衔接、各种内耗，往往会造成「忙」的假象。&lt;/p&gt;
&lt;h3 id="bug量"&gt;bug量&lt;/h3&gt;
&lt;p&gt;bug量的计算方法是一个季度所做的任务的有效bug量和所做任务的工作量的一个比例，最终算出每天的平均bug量是多少，再根据这个bug量来打分。设置bug量这个指标的初衷是为了提高开发人员的开发质量，减少测试与开发之间往返的消耗。但这个指标至少会带来两个弊端：&lt;/p&gt;
&lt;p&gt;1、开发人员和测试人员的对立&lt;/p&gt;
&lt;p&gt;因为测试岗也有bug量的质量，他们是平均每日找到多少个bug，所以很多时候开发人员都在和测试人员纠结bug有效性的问题，其实开发 和测试的目标应该是一致的，都是为了软件能够高质量的交付。&lt;/p&gt;
&lt;p&gt;2、事不关己，高高挂起&lt;/p&gt;
&lt;p&gt;经常会在项目中发现一些不合理的代码，如果这些代码不是自己负责的，开发人员不会去进行重构，因为可能会带来更多的缺陷，而这些缺陷最终会记在修改者的头上，即便重构不会带来任何的风险，也没有人会关心这个，人们更多关心的是软件能不能正常的运行。正是由于这个指标的存在，随着时间的增长，项目中的坏味道会越来越多。&lt;/p&gt;
&lt;h3 id="关键节点达成率"&gt;关键节点达成率&lt;/h3&gt;
&lt;p&gt;任务系统中的每个任务都会设置关键节点，对于开发来说关键节点就是某个任务提交测试的时间点。计算方法是未超时的任务数和总任务数的比例。这项指标的初衷是保证开发的效率，但也带来了一些问题：&lt;/p&gt;
&lt;p&gt;1、互帮互助少了&lt;/p&gt;
&lt;p&gt;虽然公司一直都强调同事之间要多沟通，多互相帮助，但正是有了这个指标当你的任务已经快到关键时间点的时候，你就没有多余的时间去顾及其他的事情了。&lt;/p&gt;
&lt;p&gt;2、多任务的处理&lt;/p&gt;
&lt;p&gt;当你正在处理设置了关键节点的任务的时候，突然来了紧急bug任务，正常逻辑应该是优先响应紧急bug，但也有了这个指标，开发人员就会先保证当前任务不超时，而不会去响应bug需求哦。&lt;/p&gt;
&lt;h2 id="松散的管理模式"&gt;「松散」的管理模式&lt;/h2&gt;
&lt;p&gt;近些年在一个中小公司负责产品团队，团队规模很小，自然也就没有严格的KPI考核制度，开发人员都是有个性的，都不会喜欢被KPI所束缚。但没有KPI制度的管理也会碰到各种问题。&lt;/p&gt;
&lt;h3 id="太理想化"&gt;太理想化&lt;/h3&gt;
&lt;p&gt;我一直想象的理想团队是每个成员都应该是自我驱动型的，当需要通过制度或是人来管的时候，自然是做不好事情的。现实情况是，人都是有惰性的，团队并不会了一个伟大的共同目标去努力奋斗，每天朝九晚九仅仅只是当成了一个工作。起初最典型的一个表现是，分配的任务总是在截至时间的最后时刻完成。&lt;/p&gt;
&lt;h3 id="公平"&gt;公平&lt;/h3&gt;
&lt;p&gt;没有KPI这种量化的考核，对团队成员的考评就会偏主观，就可能带有感情色彩，就可能有失公平。做事快的人可能会被分配更多的任务；bug多的人可能会感觉一直都处于「忙碌」的状态；效率高的人可能会被认为不够努力。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;任何管理方式都会各有利弊，包括最近两年比较火的OKR，相信在实践过程中一样会遇到各种问题。既然都会遇到困难和问题，我个人还是偏向松散的管理模式。&lt;/p&gt;
&lt;p&gt;松散的管理模式，并不是说不管理，而是要努力做到让每位团队成员从“要我做”到“我要做”的转变。我认为可以尝试以下一些方式：&lt;/p&gt;
&lt;p&gt;1、领导要对团队成员要有足够的信任，用人不疑，疑人不用；
2、技术人员普遍比较闷，不愿说出内心真实想法，需要经常和他们去沟通，了解他们内心真实想法，能力范围之内解除他们后顾之忧；
3、团队内部需要经常组织一些活动，提升团队凝聚力。比如一个开发阶段完成后，组织吃饭唱歌等；
4、定期给团队内部培训，要让每个成员都了解产品的思想，了解客户真实需求，了解公司的愿景。目的是让大家能够一起为了一个共同的目标努力，而不只是自己负责的一个功能模块。但同时也要阶段性让团队成员看到收益，而不只是画饼子；
5、建立奖惩制度，赏罚分明，公平、公正、公开；
6、如果公司领导允许，或许可以尝试下阿米巴的方式。&lt;/p&gt;</description></item><item><title>读《阿米巴经营》</title><link>https://fwhyy.com/2018/07/read-amiba-management/</link><pubDate>Tue, 24 Jul 2018 07:02:33 +0800</pubDate><guid>https://fwhyy.com/2018/07/read-amiba-management/</guid><description>&lt;p&gt;《阿米巴经营》的作者稻盛和夫一生中创建了2家500强企业，并在70多岁高龄接管日航，扭转亏损的局面，是一位传奇人物。他根据自己的管理思想独创了阿米巴经营方式。《阿米巴经营》一书是他一生智慧的结晶。&lt;/p&gt;
&lt;p&gt;阿米巴经营法总结一下有以下几点：&lt;/p&gt;</description></item><item><title>修改VS Code背景色</title><link>https://fwhyy.com/2018/07/modify-the-background-color-of-vs-code/</link><pubDate>Sat, 21 Jul 2018 23:04:03 +0800</pubDate><guid>https://fwhyy.com/2018/07/modify-the-background-color-of-vs-code/</guid><description>&lt;p&gt;一直以来都是在&lt;code&gt;Windows&lt;/code&gt;下进行开发，VS自定义的字体和背景色已经跟了我十来年了，最近已渐渐不使用&lt;code&gt;Mac&lt;/code&gt;下的&lt;code&gt;Windows&lt;/code&gt;虚拟机了，主力开发工具就变成了&lt;code&gt;VS Code For Mac&lt;/code&gt;和&lt;code&gt;Visual Studio For Mac&lt;/code&gt;。没有了之前的背景色还真不习惯，下面介绍怎样修改&lt;code&gt;Mac&lt;/code&gt;下的&lt;code&gt;VS Code&lt;/code&gt;和&lt;code&gt;VS&lt;/code&gt;的背景色。&lt;/p&gt;</description></item><item><title>GitLab配合Jenkins打造自动化部署</title><link>https://fwhyy.com/2018/07/gitlab-combined-with-jenkins-to-build-automated-deployment/</link><pubDate>Sat, 14 Jul 2018 11:20:31 +0800</pubDate><guid>https://fwhyy.com/2018/07/gitlab-combined-with-jenkins-to-build-automated-deployment/</guid><description>&lt;p&gt;&lt;code&gt;GitLab&lt;/code&gt;有&lt;code&gt;CI&lt;/code&gt;和&lt;code&gt;CD&lt;/code&gt;功能模块，但我对&lt;code&gt;Jenkins&lt;/code&gt;更熟悉些，所以先使用&lt;code&gt;Jenkins&lt;/code&gt;将自动发布搭建起来，后面再继续研究&lt;code&gt;GitLab&lt;/code&gt;的&lt;code&gt;CI&lt;/code&gt;和&lt;code&gt;CD&lt;/code&gt;功能。&lt;/p&gt;</description></item><item><title>坚持很难？是不是没找对方法</title><link>https://fwhyy.com/2018/07/how-can-we-stick-to-it/</link><pubDate>Tue, 10 Jul 2018 23:17:40 +0800</pubDate><guid>https://fwhyy.com/2018/07/how-can-we-stick-to-it/</guid><description>&lt;p&gt;最近听到了很多关于坚持的话题。&lt;/p&gt;
&lt;p&gt;1、公司的年中会议上，几位领导人的讲话都提到了我们需要找准方向，坚持下去。
2、在dotNET 跨平台的群里，有群友问怎样才能成为像张善友这样的大牛？张善友的回答是：我做技术近20年，坚持每天学习新技术半小时，坚持晚上11点睡觉，早上6点起床。
3、在逻辑思维的公众号中，罗胖坚持每天早上6点半发布一条有价值的60秒语音，就这么一件事，他坚持了2000多天。&lt;/p&gt;</description></item><item><title>这些年我关注的公众号</title><link>https://fwhyy.com/2018/06/the-public-number-ihave-been-paying-attention-to-over-the-years-1/</link><pubDate>Wed, 27 Jun 2018 23:45:39 +0800</pubDate><guid>https://fwhyy.com/2018/06/the-public-number-ihave-been-paying-attention-to-over-the-years-1/</guid><description>&lt;p&gt;在现在这样一个信息大爆炸的时代，我们可以用各种途径和方式来获取想要的信息，而且你会发现重要的信息往往都会重复出现，所以我现在主要用来获取技术方面信息的途径是微信公众号。公众号的关注也是动态变化的，时常会关注一些新的公众号，也有些会被清理掉。下面是几年下来一直持续关注的技术公众号，排名不分先后。&lt;/p&gt;</description></item><item><title>Docker 常用命令</title><link>https://fwhyy.com/2018/06/docker-common-commands/</link><pubDate>Sat, 09 Jun 2018 07:49:07 +0800</pubDate><guid>https://fwhyy.com/2018/06/docker-common-commands/</guid><description>&lt;p&gt;学习&lt;code&gt;Docker&lt;/code&gt;有段时间了，所有的操作都是在命令行下，如果不是每天都在使用，很容易忘记命令。本文将以学习&lt;code&gt;Docker&lt;/code&gt;的角度，从前到后，将一些常用的&lt;code&gt;Docker&lt;/code&gt;命令记录下来，算是个备忘。&lt;/p&gt;</description></item><item><title>在团队中使用GitLab中的Merge Request工作模式</title><link>https://fwhyy.com/2018/06/use-the-merge-request-working-mode-in-gitlab-in-the-team/</link><pubDate>Fri, 01 Jun 2018 07:49:45 +0800</pubDate><guid>https://fwhyy.com/2018/06/use-the-merge-request-working-mode-in-gitlab-in-the-team/</guid><description>&lt;p&gt;在工作中使用&lt;code&gt;Git&lt;/code&gt;已有5年多的时间了，&lt;code&gt;Git&lt;/code&gt;分布式的工作机制以及强大的分支功能使得在团队中推广使用没有受到什么阻碍。一直以来都是采用的分支管理模式，我把项目的开发分为三个阶段：开发、测试和上线。&lt;/p&gt;</description></item><item><title>CentOS7安装GitLab</title><link>https://fwhyy.com/2018/05/centos7-install-gitlab/</link><pubDate>Sun, 27 May 2018 22:18:21 +0800</pubDate><guid>https://fwhyy.com/2018/05/centos7-install-gitlab/</guid><description>&lt;p&gt;一直以来源代码一直都放在码云上，但最近码云开始收费了，免费版本的私有项目的成员限制在5个，这远远不够用了。所以需要搭建自己的Git服务器，下面内容为安装经过，记录一下：&lt;/p&gt;</description></item><item><title>近期写作计划</title><link>https://fwhyy.com/2018/05/recent-writing-plan/</link><pubDate>Thu, 24 May 2018 22:43:40 +0800</pubDate><guid>https://fwhyy.com/2018/05/recent-writing-plan/</guid><description>&lt;p&gt;写博客很多年了，都是想到哪写到哪，更多的是些学习的记录，缺少思考性的东西。最近开通微信公众号:不止dotNET，希望能将工作和学习中更多的思考分享出来。&lt;/p&gt;
&lt;p&gt;做产品或项目，都会事先制定开发计划，按照计划往前走，确保最终达成目标。公众号也可以看作是一个特殊的产品，只不过这个产品没有时间节点，需要的是我们持续的思考、学习，并且能够长期的输出。本文就先来制定一个短期的写作计划。&lt;/p&gt;
&lt;p&gt;在&lt;a href="http://fwhyy.com/2018/05/open-wechat-official-accounts/"&gt;开篇&lt;/a&gt;时说过，文章大概分为四大类：&lt;/p&gt;
&lt;h2 id="学习总结"&gt;学习总结&lt;/h2&gt;
&lt;p&gt;学习的内容大部分是跟工作相关的，也会有自己感兴趣的领域。会涉及但不限于下面的主题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微服务&lt;/li&gt;
&lt;li&gt;dotNET Core&lt;/li&gt;
&lt;li&gt;持续集成&lt;/li&gt;
&lt;li&gt;软件架构&lt;/li&gt;
&lt;li&gt;Docker容器&lt;/li&gt;
&lt;li&gt;那些年，我关注的公众号&lt;/li&gt;
&lt;li&gt;那些年，我使用过的工具&lt;/li&gt;
&lt;li&gt;那些年，我读过的技术书&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="管理相关"&gt;管理相关&lt;/h2&gt;
&lt;p&gt;管理分为任务管理和人员管理，会涉及到下面的内容：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;敏捷开发方法落地&lt;/li&gt;
&lt;li&gt;绩效管理用KPI还是OKR&lt;/li&gt;
&lt;li&gt;小公司大公司的区别&lt;/li&gt;
&lt;li&gt;怎样管理一个技术团队&lt;/li&gt;
&lt;li&gt;程序员怎样阅读技术书籍&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="产品之路"&gt;产品之路&lt;/h2&gt;
&lt;p&gt;我理解的产品分为三种：&lt;/p&gt;
&lt;p&gt;1、互联网创业公司做的事情，该产品为某种服务，ToB或者ToC，像淘宝就是给广大网民提供购买服务的；
2、公司做企业级应用，随着经验的积累，逐步沉淀出一些产品，如单点登录、AD管理等，这些有的可以开箱即用，有的需要按照客户要求做二次开发，通常是一个大的解决方案中的一部分，更准确的说应该算是中间件；
3、面向企业的一个完整的产品，根据企业要求可以私有云或公有云部署，基本可以满足企业需求，但有时也会做些二次开发。&lt;/p&gt;
&lt;p&gt;后面两种已经经历过，第一种也即将会经历，在整个做产品的过程中，踩过很多坑，犯过很多错误，同时也有很多的感悟，希望通过一系列的文章分享出来。&lt;/p&gt;
&lt;h2 id="之前博文整理"&gt;之前博文整理&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;设计模式总结&lt;/li&gt;
&lt;li&gt;程序员学英语&lt;/li&gt;
&lt;li&gt;读书笔记：代码整洁之道&lt;/li&gt;
&lt;li&gt;读书笔记：打造Facebook&lt;/li&gt;
&lt;li&gt;读书笔记：番茄工作法&lt;/li&gt;
&lt;li&gt;读书笔记：构建之法&lt;/li&gt;
&lt;li&gt;读书笔记：软技能&lt;/li&gt;
&lt;li&gt;Git工作流程&lt;/li&gt;
&lt;li&gt;C#破解dll&lt;/li&gt;
&lt;li&gt;对加班的一些看法&lt;/li&gt;
&lt;li&gt;一年跑3个马拉松是怎样一种体验&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;随便一列，好像还不少，做任何事情最重要的是坚持，也希望自己能坚持下来，计划每周更新一到两篇。&lt;/p&gt;</description></item><item><title>Docker安装MySql-挂载外部数据和配置</title><link>https://fwhyy.com/2018/05/docker-installs-mysql-to-mount-external-data-and-configuration/</link><pubDate>Sun, 20 May 2018 09:18:37 +0800</pubDate><guid>https://fwhyy.com/2018/05/docker-installs-mysql-to-mount-external-data-and-configuration/</guid><description>&lt;p&gt;在上一篇中《&lt;a href="http://fwhyy.com/2018/04/Install-MySql-with-Docker-in-CentOS7/"&gt;在CentOS7中使用Docker安装MySql&lt;/a&gt;》中介绍了怎样在&lt;code&gt;Docker&lt;/code&gt;中安装&lt;code&gt;Mysql&lt;/code&gt;，但存在两个问题：&lt;/p&gt;
&lt;p&gt;1、用户密码和字符集等的设置，需要安装完&lt;code&gt;MySql&lt;/code&gt;后，进入到&lt;code&gt;MySql&lt;/code&gt;中去设置，非常麻烦；
2、配置文件和数据文件都在&lt;code&gt;MySql&lt;/code&gt;的容器内，不是很安全。&lt;/p&gt;
&lt;p&gt;本文将介绍怎样在创建容器时通过参数的配置来解决上面两个问题。&lt;/p&gt;
&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CentOS：7.4&lt;/li&gt;
&lt;li&gt;Docker：1.13.1&lt;/li&gt;
&lt;li&gt;MySql：8.0.11&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="设置环境变量"&gt;设置环境变量&lt;/h2&gt;
&lt;p&gt;设置环境变量和镜像的参数，可以来解决第一个问题，环境变量使用&lt;code&gt;-e&lt;/code&gt;的方式设置在镜像名称的前面；镜像的参数需要配置在镜像名称的后面&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker run -d -p 4306:3306
-e MYSQL_USER=&amp;#34;fengwei&amp;#34;
-e MYSQL_PASSWORD=&amp;#34;pwd123&amp;#34;
-e MYSQL_ROOT_PASSWORD=&amp;#34;rootpwd123&amp;#34;
--name mysql001
mysql/mysql-server
--character-set-server=utf8
--collation-server=utf8_general_ci
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;环境变量说明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;-e MYSQL_USER=&amp;ldquo;fengwei&amp;rdquo;：添加用户fengwei
-e MYSQL_PASSWORD=&amp;ldquo;pwd123&amp;rdquo;：设置fengwei的密码伟pwd123
-e MYSQL_ROOT_PASSWORD=&amp;ldquo;rootpwd123&amp;rdquo;：设置root的密码伟rootpwd123&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;镜像参数说明：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ndash;character-set-server=utf8：设置字符集为utf8
&amp;ndash;collation-server=utf8_general_ci：设置字符比较规则为utf8_general_ci&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;使用&lt;code&gt;SQLyog&lt;/code&gt;进行测试，用户名和密码使用上面环境变量中添加的用户&lt;code&gt;fengwei&lt;/code&gt;和密码&lt;code&gt;pwd123&lt;/code&gt;，出现下图的错误&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201260826693.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;执行命令进入到容器中的&lt;code&gt;MySql&lt;/code&gt;中，执行下面的&lt;code&gt;Sql&lt;/code&gt;语句&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ALTER USER &amp;#39;fengwei&amp;#39;@&amp;#39;%&amp;#39; IDENTIFIED WITH mysql_native_password BY &amp;#39;password123&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;再用&lt;code&gt;SQLyog&lt;/code&gt;测试，连接成功&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201260826414.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上面连接不成功的问题也可以添加镜像参数&lt;code&gt;--default-authentication-plugin=mysql_native_password&lt;/code&gt;来解决，完整命令如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker run -d -p 4306:3306 
-e MYSQL_USER=&amp;#34;fengwei&amp;#34; 
-e MYSQL_PASSWORD=&amp;#34;pwd123&amp;#34; 
-e MYSQL_ROOT_PASSWORD=&amp;#34;rootpwd123&amp;#34; 
--name mysql001 
mysql/mysql-server 
--character-set-server=utf8 
--collation-server=utf8_general_ci 
--default-authentication-plugin=mysql_native_password 
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="数据和配置挂载到宿主机"&gt;数据和配置挂载到宿主机&lt;/h2&gt;
&lt;p&gt;为了安全性，我们应该将数据和配置放到宿主机中，首先执行下面的命令创建&lt;code&gt;data&lt;/code&gt;目录和&lt;code&gt;config&lt;/code&gt;目录&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;mkdir mysqltest
cd mysqltest
mkdir data
mkdir config
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;执行下面命令进入到&lt;code&gt;config&lt;/code&gt;目录中，并在该目录中创建&lt;code&gt;my.cnf&lt;/code&gt;配置文件&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd config
touch my.cnf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;my.cnf&lt;/code&gt;配置文件内容如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[mysqld]
user=mysql
character-set-server=utf8
default_authentication_plugin=mysql_native_password

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;执行下面命令创建容器&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker run -d -p 4306:3306 
--restart always 
--privileged=true
--name mysql001
-e MYSQL_USER=&amp;#34;fengwei&amp;#34; 
-e MYSQL_PASSWORD=&amp;#34;pwd123&amp;#34; 
-e MYSQL_ROOT_PASSWORD=&amp;#34;rootpwd123&amp;#34;
-v=/mysqltest/config/my.cnf:/etc/my.cnf 
-v=/mysqltest/data:/var/lib/mysql 
mysql/mysql-server
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;参数说明&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ndash;restart always：开机启动
&amp;ndash;privileged=true：提升容器内权限
-v=/mysqltest/config/my.cnf:/etc/my.cnf：映射配置文件
-v=/mysqltest/data:/var/lib/mysql：映射数据目录&lt;/p&gt;</description></item><item><title>在CentOS7中使用Docker安装MySql</title><link>https://fwhyy.com/2018/05/install-mysql-with-docker-in-centos7/</link><pubDate>Fri, 18 May 2018 22:31:14 +0800</pubDate><guid>https://fwhyy.com/2018/05/install-mysql-with-docker-in-centos7/</guid><description>&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;CentOS：7.4&lt;/li&gt;
&lt;li&gt;Docker: 1.13.1&lt;/li&gt;
&lt;li&gt;MySql: 8.0.11&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>调用API修改Ocelot的配置文件</title><link>https://fwhyy.com/2018/05/call-api-to-modify-the-configuration-file-of-the-ocelot/</link><pubDate>Wed, 16 May 2018 00:19:38 +0800</pubDate><guid>https://fwhyy.com/2018/05/call-api-to-modify-the-configuration-file-of-the-ocelot/</guid><description>&lt;p&gt;Ocelot是一个基于.net core的开源webapi服务网关开源项目，功能比较强大，Github项目地址为：&lt;a href="https://github.com/ThreeMammals/Ocelot"&gt;https://github.com/ThreeMammals/Ocelot&lt;/a&gt;，关于Ocelot的学习资料可以看看张善友的网站：&lt;a href="http://www.csharpkit.com/apigateway.html"&gt;http://www.csharpkit.com/apigateway.html&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Ocelot的路由设置是基于配置文件的，同样在Ocelot中使用Consul做服务发现时，也是基于配置文件，当我们修改路由或者需要往Consul中添加ServiceName的时候，需要修改配置文件，网关服务也需要重启，这当然不是我们想要的。&lt;/p&gt;</description></item><item><title>开通微信公众号-不止dotNET</title><link>https://fwhyy.com/2018/05/open-wechat-official-accounts/</link><pubDate>Sun, 13 May 2018 22:50:42 +0800</pubDate><guid>https://fwhyy.com/2018/05/open-wechat-official-accounts/</guid><description>&lt;p&gt;在微信发布公众号助手之际我开通了本公众号：不止dotNET，这是微信的一个新的里程碑，也算是我自己一次心的起航。&lt;/p&gt;</description></item><item><title>MySQL服务不能启动，原因竟然是...</title><link>https://fwhyy.com/2018/01/the-mysql-service-cant-start-the-reason-is-that/</link><pubDate>Wed, 31 Jan 2018 23:13:02 +0800</pubDate><guid>https://fwhyy.com/2018/01/the-mysql-service-cant-start-the-reason-is-that/</guid><description>&lt;p&gt;老婆最近使用MWeb往部署在Linode中的Wordpress博客中更新女儿的博客，发现图片不能正常上传，出现各种状况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MWeb闪退&lt;/li&gt;
&lt;li&gt;提示图片张数超过限制&lt;/li&gt;
&lt;li&gt;一直Loading&amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;有重度拖延症的我今天在老婆的“强迫”下决定解决此问题。&lt;/p&gt;</description></item><item><title>MongoDB历险记</title><link>https://fwhyy.com/2017/10/the-adventures-of-mongodb/</link><pubDate>Tue, 24 Oct 2017 23:56:57 +0800</pubDate><guid>https://fwhyy.com/2017/10/the-adventures-of-mongodb/</guid><description>&lt;p&gt;一直在使用&lt;code&gt;MongoDB&lt;/code&gt;来做为底层的数据存储，一直也没有出现什么问题。但就在&lt;code&gt;MongoDB&lt;/code&gt;上市之际，一客户的&lt;code&gt;MongoDB&lt;/code&gt;挂了,原因很复杂，大概有下面的一些原因和操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;客户的存储做过迁移；&lt;/li&gt;
&lt;li&gt;服务器打补丁做过重启；&lt;/li&gt;
&lt;li&gt;服务器重启后其中有一台的存储盘丢失；&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MongoDB&lt;/code&gt;的所有服务都恢复后，在一个很短的时间内是正常的，测试在这期间做过&lt;code&gt;Web&lt;/code&gt;端和&lt;code&gt;PC&lt;/code&gt;客户端端测试；&lt;/li&gt;
&lt;li&gt;当测试通知文件不能上传时，发现一台服务器端&lt;code&gt;MongoDB&lt;/code&gt;服务不能正常启动，紧接着另一台也不能正常启动；&lt;/li&gt;
&lt;li&gt;此时&lt;code&gt;MongoDB&lt;/code&gt;已彻底瘫痪。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面就是整个事故的经过，发生在周六的夜里九十点钟，接下来就是长达一天一夜的修复工作。&lt;/p&gt;</description></item><item><title>Angular4跨域问题解决</title><link>https://fwhyy.com/2017/09/angular-four-cross-domain-problem-solving/</link><pubDate>Mon, 11 Sep 2017 23:56:42 +0800</pubDate><guid>https://fwhyy.com/2017/09/angular-four-cross-domain-problem-solving/</guid><description>&lt;p&gt;之前在使用Angular1.x的时候就碰到过跨域的问题，在博文《&lt;a href="http://fwhyy.com/2016/01/angularjs-cross-domain-call-webapi-asp-net/"&gt;Angularjs跨域调用Asp.Net WebAPI&lt;/a&gt;》中有做过介绍。本文介绍下在Angular4中解决跨域问题的两种方法。&lt;/p&gt;</description></item><item><title>在Mac的Docker中运行DotNetCore2.0</title><link>https://fwhyy.com/2017/09/run-netcore-two-in-mac-docker/</link><pubDate>Sat, 09 Sep 2017 23:37:32 +0800</pubDate><guid>https://fwhyy.com/2017/09/run-netcore-two-in-mac-docker/</guid><description>&lt;p&gt;最近学习&lt;code&gt;Angular4&lt;/code&gt;，服务端准备使用&lt;code&gt;DotNetCore API&lt;/code&gt;来实现，本文简单介绍下在&lt;code&gt;Mac&lt;/code&gt;中怎样将&lt;code&gt;DotNetCore&lt;/code&gt;程序部署在&lt;code&gt;Docker&lt;/code&gt;中，并使用&lt;code&gt;Nginx&lt;/code&gt;做反向代理让程序可以跑起来。&lt;/p&gt;
&lt;h2 id="具体步骤如下"&gt;具体步骤如下&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;安装&lt;code&gt;Docker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;拉取&lt;code&gt;DotNetCore&lt;/code&gt;镜像&lt;/li&gt;
&lt;li&gt;使用&lt;code&gt;VS For Mac&lt;/code&gt;创建&lt;code&gt;DotNetCore&lt;/code&gt;应用&lt;/li&gt;
&lt;li&gt;发布应用到&lt;code&gt;Docker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;安装&lt;code&gt;Nginx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;配置&lt;code&gt;Nginx&lt;/code&gt;代理&lt;code&gt;Docker&lt;/code&gt;中的&lt;code&gt;DotNetCore&lt;/code&gt;应用&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>C#中实现小米推送</title><link>https://fwhyy.com/2017/09/mi-push-to-csharp/</link><pubDate>Sat, 02 Sep 2017 09:35:44 +0800</pubDate><guid>https://fwhyy.com/2017/09/mi-push-to-csharp/</guid><description>&lt;p&gt;移动端的消息推送有很多互联网产品可以用，例如：极光、个推、小米推送等。对于安卓手机，推送需要做各种适配，开始我们使用的是极光，发现在小米手机上，当App退出到后台，就经常不能收到消息，所以决定将小米推送集成到App中。&lt;/p&gt;
&lt;p&gt;遗憾的是小米推送官方并不支持C#，所以需要很对Java版本的实现用IKVM来做一些转化。转换后在Net程序中一共需要引用7个Dll文件，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300725027.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;相关Dll文件和示例代码已经放在Github上了&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[https://github.com/oec2003/MIPushCSharpSample](https://github.com/oec2003/MIPushCSharpSample)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="服务器证书问题解决"&gt;服务器证书问题解决&lt;/h2&gt;
&lt;p&gt;在测试阶段，推送一直没什么问题，当部署到客户服务器上后，就推送失败，错误日志如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300725876.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;从错误信息可以得知是在验证证书时出的问题，网上查到很多都是Java版本的解决方式，思路就是忽略SSL的验证，找了下C#的相关代码，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300725838.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上面代码加上后，发现推送就正常了。上面红框代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =&amp;gt; true;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Hexo的一些坑</title><link>https://fwhyy.com/2017/09/some-of-the-pits-in-hexo/</link><pubDate>Fri, 01 Sep 2017 08:36:34 +0800</pubDate><guid>https://fwhyy.com/2017/09/some-of-the-pits-in-hexo/</guid><description>&lt;p&gt;最近在研究&lt;code&gt;Angular4&lt;/code&gt;，将&lt;code&gt;Mac&lt;/code&gt;上的&lt;code&gt;node&lt;/code&gt;和&lt;code&gt;npm&lt;/code&gt;都升级为了最新版本，当使用&lt;code&gt;hexo&lt;/code&gt;的时候发现报错，当即决定将&lt;code&gt;hexo&lt;/code&gt;也升级最新版本。&lt;/p&gt;
&lt;p&gt;升级完&lt;code&gt;hexo&lt;/code&gt;，将所有的博客迁移过来，执行&lt;code&gt;hexo g&lt;/code&gt;，&lt;code&gt;hexo s&lt;/code&gt;，很顺利，没有任何问题，马上执行&lt;code&gt;hexo d&lt;/code&gt;发布到服务器，发现页面显示如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301949948.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;查看本地环境的&lt;code&gt;public&lt;/code&gt;目录，发现生成的&lt;code&gt;html&lt;/code&gt;页面的代码就如上图，但本地运行又是正常的。一个直接的反应就是，上面的代码是在运行时依赖&lt;code&gt;node&lt;/code&gt;解析成&lt;code&gt;html&lt;/code&gt;页面的。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ssh&lt;/code&gt;到&lt;code&gt;vps&lt;/code&gt;上查看&lt;code&gt;node&lt;/code&gt;版本，发现很低，一通折腾升级&lt;code&gt;node&lt;/code&gt;版本，最终将&lt;code&gt;vps&lt;/code&gt;上&lt;code&gt;node&lt;/code&gt;和&lt;code&gt;npm&lt;/code&gt;版本升级到和本地环境一致，发现网站依然不能正常运行。&lt;/p&gt;
&lt;p&gt;尝试将本地&lt;code&gt;public&lt;/code&gt;目录中的文件删掉，发现本地环境依然正常运行，这时才恍然大悟，本地执行&lt;code&gt;hexo s&lt;/code&gt;，并不是执行的&lt;code&gt;public&lt;/code&gt;目录中的内容，而是动态编译运行的。&lt;/p&gt;
&lt;p&gt;重新&lt;code&gt;hexo init hblog&lt;/code&gt;，安装步骤重新来了一个，执行&lt;code&gt;hexo g&lt;/code&gt; 发现&lt;code&gt;public&lt;/code&gt;目录中生成的&lt;code&gt;html&lt;/code&gt;已经正常，&lt;code&gt;hexo d&lt;/code&gt;发布到服务器，一切OK。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;对执行原理的不了解，导致走了很多弯路，瞎折腾了翻&lt;/li&gt;
&lt;li&gt;hexo本地运行并不是运行的public中的内容&lt;/li&gt;
&lt;li&gt;服务器端无需安装node，也可以运行hexo&lt;/li&gt;
&lt;li&gt;至今还不知道开始生成的html不正确是什么原因导致&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Docker学习-安装镜像</title><link>https://fwhyy.com/2017/08/docker-learning-installing-images/</link><pubDate>Thu, 31 Aug 2017 10:47:45 +0800</pubDate><guid>https://fwhyy.com/2017/08/docker-learning-installing-images/</guid><description>&lt;p&gt;Docker现在已不是什么新鲜事物了，Windows Server2016已经内置了Docker，对于我来说，我只想让Docker来帮我解决运行环境的问题。&lt;/p&gt;
&lt;p&gt;我们的产品部署起来会依赖很多的第三方产品：SqlServer、MongoDB、Redis、RabbitMQ等，各种软件等安装，数据库的还原，每次部署都会耗费大量的时间。为了能使部署更加的方便，我们的设想是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在Docker中安装这些工具软件&lt;/li&gt;
&lt;li&gt;打包Docker，拷贝到客户环境中导入&lt;/li&gt;
&lt;li&gt;在Web界面中进行简单的向导配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本文主要介绍在Docker中安装这些工具软件。&lt;/p&gt;</description></item><item><title>老罗和坚果Pro</title><link>https://fwhyy.com/2017/05/luo-and-nut-pro/</link><pubDate>Fri, 26 May 2017 00:02:08 +0800</pubDate><guid>https://fwhyy.com/2017/05/luo-and-nut-pro/</guid><description>&lt;p&gt;上大学时因为老罗语录认识了老罗，到后来的牛博网、英语培训，直到5年前开始做手机，一直在关注，每一场的公开演讲、发布会都看过直播或是在第一时间看重播。首要的原因当然还是因为老罗的相声讲的好，就像当初把老罗语录当相声段子听一样。&lt;/p&gt;
&lt;p&gt;听了那么多的发布会，看了那么多的微创新，其实一直都有点心动。就在前不久，机会来了，老罗的坚果Pro发布，我的iPhone6 Plus的屏也很合时机的摔碎了。等我下单的时候，已经需要全款预约了，貌似卖的很火暴，但发货速度很快，有一种库存满满的感觉。玩了差不多1个礼拜，谈谈感受吧。&lt;/p&gt;</description></item><item><title>马拉松</title><link>https://fwhyy.com/2017/04/marathon/</link><pubDate>Thu, 20 Apr 2017 22:46:55 +0800</pubDate><guid>https://fwhyy.com/2017/04/marathon/</guid><description>&lt;p&gt;马拉松，42.195公里，一个令人望而生畏的距离，而我在今年的4月10号，一个风雨交加的天气里征服了他，我很开心。&lt;/p&gt;
&lt;p&gt;2016年，武汉举办首届马拉松，被称为汉马，我报名了12公里的健康跑，有幸中签了。在此之前最远就跑过10公里，而且是在十几年前，所以12公里对我来说也是一个挑战。赛前一段时间的训练，加上比赛是的那种氛围，12公里还是很轻松的拿下了。&lt;/p&gt;</description></item><item><title>OWA实现添加水印</title><link>https://fwhyy.com/2017/04/adding-watermark-to-owa/</link><pubDate>Sat, 08 Apr 2017 00:01:55 +0800</pubDate><guid>https://fwhyy.com/2017/04/adding-watermark-to-owa/</guid><description>&lt;p&gt;&lt;code&gt;OWA&lt;/code&gt;全称&lt;code&gt;Office Web App&lt;/code&gt;，是用来做&lt;code&gt;Office&lt;/code&gt;文档预览的一个很好的工具。现在客户有要求，需要在预览界面中添加水印。想起之前写的一篇文章&lt;a href="http://fwhyy.com/2015/06/office-web-app-preview-remove-top-menu/"&gt;《Office Web APP预览去掉顶部菜单》&lt;/a&gt;，就是通过修改样式来控制&lt;code&gt;OWA&lt;/code&gt;的预览界面的。&lt;/p&gt;
&lt;p&gt;通过&lt;code&gt;F12&lt;/code&gt;查看&lt;code&gt;OWA&lt;/code&gt;预览&lt;code&gt;Word&lt;/code&gt;的界面，发现&lt;code&gt;Word&lt;/code&gt;的每一页会被渲染在一个&lt;code&gt;Img&lt;/code&gt;中展示，如下图：&lt;/p&gt;</description></item><item><title>C#给PDF添加编辑域</title><link>https://fwhyy.com/2017/01/csharp-add-edit-fields-to-pdf/</link><pubDate>Wed, 04 Jan 2017 23:02:20 +0800</pubDate><guid>https://fwhyy.com/2017/01/csharp-add-edit-fields-to-pdf/</guid><description>&lt;p&gt;PDF文档通常是不能编辑的，但有些时候需要在PDF文档中填写日期或签名之类，就需要在PDF有能编辑的文本域，本文介绍怎样用C#来实现这一功能。&lt;/p&gt;</description></item><item><title>读《软技能》：自学提高生产力</title><link>https://fwhyy.com/2016/10/reading-soft-skills-learning-to-improve-productivity/</link><pubDate>Tue, 25 Oct 2016 22:29:32 +0800</pubDate><guid>https://fwhyy.com/2016/10/reading-soft-skills-learning-to-improve-productivity/</guid><description>&lt;p&gt;《软技能》这本书内容较多，在&lt;a href="http://fwhyy.com/2016/10/reading-soft-skills-agile-personal-management/"&gt;读《软技能》：敏捷个人管理&lt;/a&gt;一文中主要谈的是个人管理方面的内容，本文将对怎样进行个人管理、怎样提高生产里进行一点思考。&lt;/p&gt;</description></item><item><title>读《软技能》：敏捷个人管理</title><link>https://fwhyy.com/2016/10/reading-soft-skills-agile-personal-management/</link><pubDate>Sat, 15 Oct 2016 22:53:26 +0800</pubDate><guid>https://fwhyy.com/2016/10/reading-soft-skills-agile-personal-management/</guid><description>&lt;p&gt;《软技能》是一本写给技术人员的非技术类书籍，即使你不写代码，读读这本书也可以受益不少。书中涉猎甚广，甚至有理财、健身、心理等内容。读完这本书，有一种相见恨晚的感觉。&lt;/p&gt;
&lt;p&gt;本书通篇在讲各个方面个人的成长，个人成长就需要自己对自己进行管理，敏捷的思想我认为核心就是快速迭代，用到个人身上就是要有很多的小目标，以迭代的方式向前进，最终实现大目标，这种方式可以让我们能快速试错，及时调整方向；也能让我们能快速看到一些成果，激励自己向前。&lt;/p&gt;</description></item><item><title>jQuery上传插件Uploadify使用详解(3.2.1)</title><link>https://fwhyy.com/2016/09/jquery-upload-plugin-uploadify-3-2-1-use-explanation/</link><pubDate>Sun, 25 Sep 2016 18:57:49 +0800</pubDate><guid>https://fwhyy.com/2016/09/jquery-upload-plugin-uploadify-3-2-1-use-explanation/</guid><description>&lt;p&gt;六年前，因为工作中使用到 jQuery 的上传组件 Uploadify ，写了一篇《&lt;a href="http://fwhyy.com/2010/01/jquery-upload-plugin-uploadify-use-explanation/"&gt;JQuery上传插件Uploadify使用详解&lt;/a&gt;》的博客来介绍 &lt;a href="http://www.uploadify.com/"&gt;Uploadify&lt;/a&gt; ，其实只是将官方文档简单翻译了下。几年下来居然有50多万的访问量，而且每天通过各种搜索引擎有大几百的朋友会访问到这篇文章。六年时间 Uploadify 从当时的2.1.0到了现在的3.2.1，变化还是挺大，为了对访问到之前那篇博客的朋友还有点价值，特写此篇。&lt;/p&gt;</description></item><item><title>使用ExceptionLess</title><link>https://fwhyy.com/2016/09/use-exceptionless/</link><pubDate>Tue, 13 Sep 2016 23:03:26 +0800</pubDate><guid>https://fwhyy.com/2016/09/use-exceptionless/</guid><description>&lt;p&gt;&lt;a href="http://exceptionless.com/"&gt;ExceptionLess&lt;/a&gt;是一款免费开源的分布式日志收集框架，DotNet的几乎所有类型的程序都可以支持，并且还提供了接口，可以很方便的在js中进行日志的推送。&lt;/p&gt;</description></item><item><title>谈谈加班</title><link>https://fwhyy.com/2016/09/talk-about-overtime/</link><pubDate>Thu, 08 Sep 2016 23:22:06 +0800</pubDate><guid>https://fwhyy.com/2016/09/talk-about-overtime/</guid><description>&lt;p&gt;今天谈谈加班这个敏感的话题，相信大家在职场中都或多或少的经历过加班。特别是 IT 这个行业，加班更是家常便饭。加班通常有这么四类：&lt;/p&gt;</description></item><item><title>Remoting 外网访问</title><link>https://fwhyy.com/2016/09/remoting-external-access/</link><pubDate>Tue, 06 Sep 2016 22:01:52 +0800</pubDate><guid>https://fwhyy.com/2016/09/remoting-external-access/</guid><description>&lt;p&gt;Remoting 是一种很古老的分布式技术，如果不清楚的可以参考下面三篇博客，写的非常详细：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/wayfarer/archive/2004/07/30/28723.html"&gt;Microsoft .Net Remoting系列专题之一:.Net Remoting基础篇&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/wayfarer/archive/2004/08/05/30437.html"&gt;Microsoft .Net Remoting系列专题之二：Marshal、Disconnect与生命周期以及跟踪服务&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/wayfarer/articles/75213.html"&gt;Microsoft .Net Remoting系列专题之三：Remoting事件处理全接触&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最近解决公司一个老平台的问题，该平台中使用了 Remoting 技术，现有的环境大致如下：&lt;/p&gt;
&lt;p&gt;1、Remoting 服务和 Web 都是部署在局域网；
2、多台 Web 都是通过内网 IP 和端口来访问 Remoting 。&lt;/p&gt;</description></item><item><title>在Linode上的Ubuntu12.04中搭建Hexo</title><link>https://fwhyy.com/2016/09/build-ubuntu12-04-in-linode-on-hexo/</link><pubDate>Fri, 02 Sep 2016 06:42:53 +0800</pubDate><guid>https://fwhyy.com/2016/09/build-ubuntu12-04-in-linode-on-hexo/</guid><description>&lt;p&gt;自从接触了Markdown后就喜欢上了，写博客自然也就想使用Markdown，但Wordpress中的Markdown插件都不怎么好用。找了很久终于找了一个在当时感觉还不错的方法，使用马克飞象写然后导出成Html在Wordpress的后台进行发布，具体参见《&lt;a href="http://fwhyy.com/2015/06/use-markdown-in-wordpress/"&gt;WordPress使用Markdown&lt;/a&gt;》。虽然效果还不错但操作起来比较繁琐，所以经过一番折腾，使用Hexo代替了Wordpress，本文主要讲下怎样在Linode中搭建Hexo。&lt;/p&gt;
&lt;p&gt;如果您还不知道Linode和Hexo是什么，自行Google之，本文不做介绍。&lt;/p&gt;
&lt;p&gt;2015年初在Linode购买了VPS，机房自然选择了亚洲的东京机房。安装的Ubuntu12.04的操作系统，因为对Linx系统不熟，选择了最省事的&lt;a href="http://lnmp.org/"&gt;lnmp&lt;/a&gt; 。lnmp中自带nginx，所以Hexo的部署也就使用nginx做为服务器。&lt;/p&gt;</description></item><item><title>C# 带签名dll破解</title><link>https://fwhyy.com/2016/03/csharp-with-signature-dll-crack/</link><pubDate>Wed, 09 Mar 2016 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2016/03/csharp-with-signature-dll-crack/</guid><description>&lt;p&gt;首先申明，本文只是从技术的角度来分析下怎样破解带签名的C#写的dll文件。大家如有遇到收费的软件或类库还是应该去购买正版，程序员何苦为难程序员呢。&lt;/p&gt;</description></item><item><title>OWA实现Word在线编辑（以GridFs存储文件）</title><link>https://fwhyy.com/2016/01/word-owa-online-editor-from-gridfs/</link><pubDate>Tue, 26 Jan 2016 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2016/01/word-owa-online-editor-from-gridfs/</guid><description>&lt;p&gt;OWA全称Office Web App，是用来做Office文档预览的一个很好的工具，通过一些配置文件的设置还可以实现Excel、PowerPoint的在线编辑功能，但对Word在线编辑并不支持。GitHub上有大牛实现了Word的在线编辑，不过文件必须是物理文件，本文在此基础上做了些扩展可以支持文件存储在分布式文件系统中，本文以GridFs为例。&lt;/p&gt;</description></item><item><title>Angularjs跨域调用Asp.Net WebAPI</title><link>https://fwhyy.com/2016/01/angularjs-cross-domain-call-webapi-asp-net/</link><pubDate>Wed, 06 Jan 2016 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2016/01/angularjs-cross-domain-call-webapi-asp-net/</guid><description>&lt;p&gt;之前写过一篇使用jQuery跨域调用WebAPI的博客《&lt;a href="http://blog.fwhyy.com/2015/08/jquery-cros-access-asp-net-web-api/"&gt;jQuery跨域调用Asp.Net Web API&lt;/a&gt;》,但最近使用Angularjs来调用WebAPI发现之前的方法行不通。本文主要介绍解决使用Angularjs调用WebAPI的跨域问题。&lt;/p&gt;</description></item><item><title>Asp.Net WebAPI 视频秒播</title><link>https://fwhyy.com/2015/12/aspnet-webapi-shi-pin-miao-bo/</link><pubDate>Sat, 12 Dec 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/12/aspnet-webapi-shi-pin-miao-bo/</guid><description>&lt;p&gt;看标题知道本文是关于WebAPI和视频播放的，关于在Web上使用的视频播放插件有很多，像flowplayer、jdplayer等等。使用这些控件通常使用服务器上物理文件的相对路径或是一个API地址返回一个视频流。通常情况下视频播放控件会将视频流全部加载后才开始播放，当视频文件较大时，这个等待时间是不能接受的，本文主要介绍怎样实现秒播。&lt;/p&gt;</description></item><item><title>使用fancybox</title><link>https://fwhyy.com/2015/12/use-fancybox/</link><pubDate>Wed, 02 Dec 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/12/use-fancybox/</guid><description>&lt;p&gt;fancybox是一款不错的展示图片的jQuery插件，就目前在网上查到的资料大体有1.x和2.x两个大大版本，两个版本的用法有不少的差别，本文主要介绍的是2.1.5版本的使用。&lt;/p&gt;</description></item><item><title>使用nw.js制作桌面应用程序</title><link>https://fwhyy.com/2015/10/use-nwjs-to-create-desktop-applications/</link><pubDate>Thu, 22 Oct 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/10/use-nwjs-to-create-desktop-applications/</guid><description>&lt;p&gt;本文主要介绍在windows和mac下如果使用nw.js来制作桌面应用程序，以及如何制作成安装包，本文不涉及nw.js的开发，只是用nw.js做壳包一个web应用而已。&lt;/p&gt;</description></item><item><title>C#操作AD修改用户密码</title><link>https://fwhyy.com/2015/09/csharp-operation-ad-to-modify-the-user-password/</link><pubDate>Thu, 24 Sep 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/09/csharp-operation-ad-to-modify-the-user-password/</guid><description>&lt;p&gt;本文的标题是C#操作AD来修改用户密码，其实在微软的API中没有修改密码的方法（我理解的修改密码是需要输入旧密码进行验证），只有重置密码的方法。重置密码的代码大概如下：&lt;/p&gt;</description></item><item><title>在Windows Server2008R2中部署WebAPI</title><link>https://fwhyy.com/2015/09/deploy-webapi-in-windows-server2008/</link><pubDate>Wed, 16 Sep 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/09/deploy-webapi-in-windows-server2008/</guid><description>&lt;p&gt;一直以来都是在win8或windows server2012中进行asp.net mvc或webapi程序的部署，没有发现任何问题。今天在win2008中进行asp.net webapi的部署，访问api的时候页面显示404错误。下面步骤将解决asp.net webapi在win2008中的部署问题。&lt;/p&gt;</description></item><item><title>jQuery跨域调用Asp.Net Web API</title><link>https://fwhyy.com/2015/08/jquery-cros-access-asp-net-web-api/</link><pubDate>Sat, 15 Aug 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/08/jquery-cros-access-asp-net-web-api/</guid><description>&lt;p&gt;Asp.Net Web API是一个轻量级的Web服务，当Web API和Web程序不是部署在同一域的时候，要使用jQuery来实现调用API的接口就存在跨域的问题。下面介绍两种方式来解决jQuery调用API跨域的问题。&lt;/p&gt;</description></item><item><title>C#访问群集部署时的MongoDB</title><link>https://fwhyy.com/2015/08/mongodb-access-to-the-csharp-of-the-cluster/</link><pubDate>Thu, 13 Aug 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/08/mongodb-access-to-the-csharp-of-the-cluster/</guid><description>&lt;p&gt;普通的MongoDB部署有一台主、一台备，程序连接MongoDB时需要主服务器的地址以及端口，当群集部署的时候就会有多个服务器地址需要连接，MongoDB的C# API可以支持同时连接多台服务器。&lt;/p&gt;</description></item><item><title>开源上传组件stream的.Net后台实现</title><link>https://fwhyy.com/2015/08/stream-aspnet/</link><pubDate>Thu, 13 Aug 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/08/stream-aspnet/</guid><description>&lt;p&gt;stream是一款功能很强大的上传组件，支持Html5和Flash两种方式，Html5可以支持断点续传，进度、剩余时间等的显示。但后台代码实现目前只有Java和PHP的版本，参考PHP的版本我实现了一个.Net的版本，目前只支持Html5的方式，代码已经放到了Github上：&lt;/p&gt;</description></item><item><title>读《构建之法》</title><link>https://fwhyy.com/2015/07/read-construction-method/</link><pubDate>Fri, 10 Jul 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/07/read-construction-method/</guid><description>&lt;p&gt;《构建之法》刚面市不就就买了纸质版，后来出了多看版后也第一时间购买了电子版。这也是第一本同时购买了纸板和电子版的技术书籍。&lt;a href="http://weibo.com/yeka52"&gt;周筠&lt;/a&gt;老师在微博上催过我几次书评，无奈年后一直忙于公司产品的研发，直到最近才看完，进度很缓慢。&lt;/p&gt;</description></item><item><title>WordPress使用Markdown</title><link>https://fwhyy.com/2015/06/use-markdown-in-wordpress/</link><pubDate>Mon, 22 Jun 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/06/use-markdown-in-wordpress/</guid><description>&lt;p&gt;自从知道有Markdown这么个东西后，就彻底喜欢上了。期间也折腾过支持Markdown格式的博客系统，如：Octopress、hexo。之前也写过几篇关于Octopress的博文：&lt;a href="http://fwhyy.com/categories/Octopress/"&gt;http://fwhyy.com/categories/Octopress/&lt;/a&gt;。对于hexo折腾一番后发布到了github上，可以通过&lt;a href="http://oec2003.github.io/"&gt;http://oec2003.github.io/&lt;/a&gt;访问。&lt;/p&gt;
&lt;p&gt;但自从用了独立博客以后，一直使用的是WordPress，去年又迁移到了Linode的VPS上，暂时还没找到好的方式在Linode上部署hexo，所以还是决定在WordPress中使用Markdown。&lt;/p&gt;</description></item><item><title>Office Web App 2013发布在外网进行预览</title><link>https://fwhyy.com/2015/06/office-web-app-2013-preview-in-external/</link><pubDate>Sat, 20 Jun 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/06/office-web-app-2013-preview-in-external/</guid><description>&lt;p&gt;Office Web App是用来做Office文档预览的一个很好的工具，网上的很多资料大都是跟SharePoint集成、Lync集成等，并且基本都是在内网部署。本文主要介绍下怎样在外网部署实现预览功能。&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;p&gt;OWA的安装可以参考下面链接：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://technet.microsoft.com/zh-cn/library/jj219455.aspx"&gt;https://technet.microsoft.com/zh-cn/library/jj219455.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;有关安装OWA的PowerShell命令可以参考下面链接：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://technet.microsoft.com/zh-cn/library/ee890080.aspx"&gt;http://technet.microsoft.com/zh-cn/library/ee890080.aspx&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="准备工作"&gt;准备工作&lt;/h2&gt;
&lt;p&gt;OWA不能安装在域控上，所以必须准备两台服务器，如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;域控服务器
&lt;ul&gt;
&lt;li&gt;服务器版本：Windows Server2012R2&lt;/li&gt;
&lt;li&gt;域名：fwhyy.com&lt;/li&gt;
&lt;li&gt;内网IP：10.15.3.160&lt;/li&gt;
&lt;li&gt;外网IP：100.180.100.180&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;OWA服务器
&lt;ul&gt;
&lt;li&gt;服务器版本：Windows Server2012R2&lt;/li&gt;
&lt;li&gt;完整机器名：owa.fwhyy.com&lt;/li&gt;
&lt;li&gt;内网IP：10.15.3.180&lt;/li&gt;
&lt;li&gt;外网IP：100.180.100.181&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;申请外网域名：owa.fwhyy.com，绑定到OWA服务器的外网IP：100.180.100.181&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="部署"&gt;部署&lt;/h2&gt;
&lt;p&gt;1.在OWA服务器上执行下面PowerShell命令：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;New-OfficeWebAppsFarm -InternalUrl &amp;#34;http://10.15.3.180&amp;#34; -AllowHttp -EditingEnabled -OpenFromUrlEnabled
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;注意InternalUrl 需要配置内网IP&lt;/p&gt;
&lt;p&gt;2.命令成功执行后，会在IIS中创建两个站点，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/3cefded1gw1etayjjaz24j20ea0530ta.webp" alt="3cefded1gw1etayjjaz24j20ea0530ta" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3.在浏览器中输入：&lt;a href="http://owa.fwhyy.com/hosting/discovery"&gt;http://owa.fwhyy.com/hosting/discovery&lt;/a&gt;会得到一个放回xml结果的页面，&lt;strong&gt;该xml文件中显示的地址为内网IP，需要将内网IP换成域名：owa.fwhyy.com&lt;/strong&gt;。保存该页面为discovery.xml文件留作备用。不同类型的文档会指向不同的页面来做预览，生成预览链接时会用到discovery.xml文件。&lt;/p&gt;
&lt;p&gt;4.如果要将OWA的预览功能和自己的应用程序进行整合，还需要有一个Web API程序进行辅助，有关这部分内容可以参考下面链接：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/poissonnotes/p/3267190.html"&gt;http://www.cnblogs.com/poissonnotes/p/3267190.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/poissonnotes/p/3277280.html"&gt;http://www.cnblogs.com/poissonnotes/p/3277280.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;具体请求流程参见下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/3cefded1gw1etazsxxv5aj20dl0e1t96.webp" alt="3cefded1gw1etazsxxv5aj20dl0e1t96" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5.除了discovery.xml中的地址需要修改为域名，其他所有涉及到有请求的地方全部使用内网IP。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;外网访问其实关键的是需要注意三点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用PowerShell命令创建站点时使用内网IP；&lt;/li&gt;
&lt;li&gt;需要用域名进行访问，并且申请的域名必须和OWA服务器的完整机器名一致；&lt;/li&gt;
&lt;li&gt;只有discovery.xml中的地址需要为域名，其他所有都是用内网IP。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面会单独开篇来写一个简单的示例，包含改造后的WopiHosting部分。&lt;/p&gt;</description></item><item><title>Office Web APP预览去掉顶部菜单</title><link>https://fwhyy.com/2015/06/office-web-app-preview-remove-top-menu/</link><pubDate>Fri, 19 Jun 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/06/office-web-app-preview-remove-top-menu/</guid><description>&lt;p&gt;Office Web APP应该是用来做Office文档预览最好的方式，原生的预览页面中的顶部会有Microsoft的相关文字以及一些功能按钮，比如文件,查找（如下图）。如果仅仅是预览没有什么问题，但系统中如果预览和下载两个工能的权限是分开的，在预览时文件按钮中的 打印功能可以将文件导出成PDF，这样就分不开这两种功能权限了。下面就介绍怎样将顶部的Microsoft相关文字和功能按钮隐藏掉。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301602055.webp" alt="3cefded1gw1et90cjtya1j20h3056dg4" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;p&gt;在Office Web APP的预览会涉及4中类型的文 件：Word、Excel、PowerPoint、PDF，不同的类型在预览时调用的文件是不一样的，其中Word和 PDF调用的是同一个文件。每个预览的页面都有对应的CSS文件，如下：&lt;/p&gt;
&lt;h3 id="powerpoint"&gt;PowerPoint&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;C:\Program Files\Microsoft Office Web Apps\WebPPTViewer\pptresources\2052\styleread.css
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="word"&gt;Word&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;C:\Program Files\Microsoft Office Web Apps\WebWordViewer\Resources\2052\WordViewer.css
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="excel"&gt;Excel&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;C:\Program Files\Microsoft Office Web Apps\ExcelServicesWfe\_layouts\styles\excelribbon.css
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在上面的三个css文件中找到cui-ribbonTopBars，在css样式中追加display:none。下面是修改后的预览效果：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301602716.webp" alt="3cefded1gw1et90ck1vftj20h405j0t4" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>C#用md5判断GridFS中文件是否存在</title><link>https://fwhyy.com/2015/05/using-csharp-check-file-in-gridfs/</link><pubDate>Thu, 21 May 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/05/using-csharp-check-file-in-gridfs/</guid><description>&lt;p&gt;假设使用MongoDB的GridFS做分布式文件系统，同样的文件在文件系统中只存一份，那么在存入文件时就需要判断文件是否已经存在，在GridFS中每个文件都有唯一的md5哈希值，只需要用文件的md5值判断是否在GridFS中已经存在就可以了，所谓的秒传功能就是用的该原理。&lt;/p&gt;
&lt;h2 id="技术栈"&gt;技术栈&lt;/h2&gt;
&lt;p&gt;C#、VS2013、MongoDB、GridFS&lt;/p&gt;
&lt;h2 id="实现"&gt;实现&lt;/h2&gt;
&lt;p&gt;1 . 首先根据文件流得到md5值，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; //计算文件的MD5码
 public static string GetMD5Hash(Stream stream)
 {
 string result = &amp;#34;&amp;#34;;
 string hashData = &amp;#34;&amp;#34;;
 byte[] arrbytHashValue;
 System.Security.Cryptography.MD5CryptoServiceProvider md5Hasher =
 new System.Security.Cryptography.MD5CryptoServiceProvider();

 try
 {
 arrbytHashValue = md5Hasher.ComputeHash(stream);//计算指定Stream 对象的哈希值
 //由以连字符分隔的十六进制对构成的String，其中每一对表示value 中对应的元素；例如“F-2C-4A”
 hashData = System.BitConverter.ToString(arrbytHashValue);
 //替换-
 hashData = hashData.Replace(&amp;#34;-&amp;#34;, &amp;#34;&amp;#34;);
 result = hashData;
 }
 catch (System.Exception ex)
 {
 //记录日志
 }

 return result;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 . 根据md5值在GridFS中进行唯一性校验，方法如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; public string IsExist(string tag)
 {
 string id = &amp;#34;&amp;#34;;
 var files = _gridFs.Find(Query.EQ(&amp;#34;md5&amp;#34;, BsonValue.Create(tag)));
 if(files.Count() &amp;gt; 0)
 {
 id=files.FirstOrDefault().Id.ToString();
 }
 return id;
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 . GridFS操作类的完整代码参考&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gist.github.com/oec2003/6c1d473a5a5b61a9d131"&gt;https://gist.github.com/oec2003/6c1d473a5a5b61a9d131&lt;/a&gt;&lt;/p&gt;</description></item><item><title>2014 年终总结</title><link>https://fwhyy.com/2015/02/2014-year-summary/</link><pubDate>Thu, 19 Feb 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/02/2014-year-summary/</guid><description>&lt;p&gt;本文已是今年写的第三篇总结了，为了得&lt;a href="http://macshuo.com/"&gt;池大大&lt;/a&gt;的一本书写了第一篇总结，还好结果还算不错，《&lt;a href="http://book.douban.com/subject/26285268/"&gt;第一本Docker书&lt;/a&gt;》已在邮寄的途中；第二篇是公司要求写的个人总结。本篇还是以生活和工作两方面来写下2014年的点点滴滴。&lt;/p&gt;
&lt;h2 id="生活"&gt;生活&lt;/h2&gt;
&lt;p&gt;2014年5月16日，女儿顺利降生，这是今年最大的事情了。有了女儿，家里更热闹了，不过时间也更少了。现在每天的生活都是这样的：&lt;/p&gt;
&lt;p&gt;1、白天上班，不加班的话下班到家将近7点；&lt;/p&gt;
&lt;p&gt;2、9点之前我跟女儿的互动时间，这期间老婆做饭、吃饭、跳操等等；&lt;/p&gt;
&lt;p&gt;3、9点后老婆哄女儿睡觉，我就有自己的时间了，或处理工作上的事情、或看书学习、或写写代码，或看看电影美剧；&lt;/p&gt;
&lt;p&gt;4、如果没有特殊的事情，通常都会在12点前睡觉，早上一般5点半或6点起床，7点40驱车上班。&lt;/p&gt;
&lt;p&gt;早在老婆怀孕的时候，和老婆商量无论生男生女都叫”fengzihan“这个读音，随即就注册了&lt;a href="http://fengzihan.me/"&gt;fengzihan.me&lt;/a&gt;的域名，作为女儿的个人网站。前不久将之前的空间迁移到了Linode的VPS，并将女儿的站点搭建起来，由老婆执笔记录女儿的成长。&lt;/p&gt;
&lt;h2 id="工作"&gt;工作&lt;/h2&gt;
&lt;p&gt;2013年底才来到现在这家公司，公司很小，项目型公司，研发人员有的在公司，有的在客户现场。公司之前的代码各个项目是分别管理，有的用snv，有的用tfs，有的甚至都没有使用源码管理工具。&lt;/p&gt;
&lt;p&gt;所以2014年上半年我做的第一件事就是将公司所有代码进行梳理，并迁移到git上，这样再也不用担心这种分布式的人员了。因为当时公司外网服务器的原因，使用的是&lt;a href="https://git.oschina.net/"&gt;开源中国的git托管&lt;/a&gt;，目前准备使用gitlab在公司服务器上搭建git环境。最近开源中国的git托管做了升级，越来越有&lt;a href="https://github.com/"&gt;github&lt;/a&gt;的味道了。&lt;/p&gt;
&lt;p&gt;2014年上半年第二件事是将公司的主后台管理平台进行重构:&lt;/p&gt;
&lt;p&gt;1、使用Bootstrap进行UI重构，后面的项目实施中有不少客户觉得很高大上；&lt;/p&gt;
&lt;p&gt;2、项目的组织方式进行了重构，这可以算是比较大的一个手术，需要了解整个平台的很多细节。调整后的好处是更便于项目的分模块开发和部署。&lt;/p&gt;
&lt;p&gt;2014年下半年也做了两件事，由于公司项目太多，人手不够，我被推到了项目经理兼技术经理的位置，带着3、4个人历时5个月做了一个项目。小公司就是这样，可能会涉及很多的角色，这不，第二件事就是负责招聘，整个下半年面试了近百人，只招进了5个人。&lt;/p&gt;
&lt;p&gt;总体来说，整个2014年很忙碌也很充实，2015年会做更多基础平台完善和团队建设的事情。&lt;/p&gt;
&lt;h2 id="2015年展望"&gt;2015年展望&lt;/h2&gt;
&lt;p&gt;1、老婆顺利考到驾照；&lt;/p&gt;
&lt;p&gt;2、女儿健康快乐成长；&lt;/p&gt;
&lt;p&gt;3、书架上的书能慢慢看完并消化；&lt;/p&gt;
&lt;p&gt;4、2015年冠上了产品部经理的头衔，15年要带领团队好好做产品；&lt;/p&gt;
&lt;p&gt;5、团队建设。&lt;/p&gt;</description></item><item><title>Git工作流程</title><link>https://fwhyy.com/2015/02/git-workflow/</link><pubDate>Sun, 15 Feb 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/02/git-workflow/</guid><description>&lt;p&gt;2014年初开始在公司推行Git的使用，到现在将近一年的时间，公司的大部分项目代码都已经迁移到了Git上，关于Git的安装使用在之前的文章有相关介绍，《&lt;a href="http://blog.fwhyy.com/2012/02/use-git-manage-github-project-on-windows/"&gt;Windows 下使用Git管理Github项目&lt;/a&gt;》、《&lt;a href="http://blog.fwhyy.com/2012/11/using-git-in-vs2010/"&gt;在VS2010中使用Git【图文】&lt;/a&gt;》，本文主要说说Git使用的工作流程。&lt;/p&gt;
&lt;p&gt;一千个人心中有一千个哈莫雷特，Git作为一个源码管理工具在不同的人，不同的团队中使用的流程也是不相同的。下面说说我在公司推行的过程中在不同阶段的使用情况：&lt;/p&gt;
&lt;h2 id="开始使用阶段"&gt;开始使用阶段&lt;/h2&gt;
&lt;p&gt;1、开始使用Git时，团队成员对Git还不是很了解，有的开发人员之前有VSS、SVN背景，有的没有使用过源码管理工具，使用过的也没有使用过分支功能；&lt;/p&gt;
&lt;p&gt;2、开发人员每个人创建一个分支，随时随地commit，每天push一次到服务器；&lt;/p&gt;
&lt;p&gt;3、因为每个人单独分支，push时不需要pull，也没有冲突需要解决；&lt;/p&gt;
&lt;p&gt;4、团队Leader每天在所有开发人员push后将代码合并到master分支，开发人员每天上班后将master拉下来合并到自己分支；&lt;/p&gt;
&lt;h2 id="产品项目开始阶段"&gt;产品/项目开始阶段&lt;/h2&gt;
&lt;p&gt;1、这时开发人员已基本熟悉Git的使用了，无需再每个人创建一个分支；&lt;/p&gt;
&lt;p&gt;2、除了master分支还有一个供所有开发人员开发的dev分支；&lt;/p&gt;
&lt;p&gt;3、大家都在同一个dev分支上进行工作，依然是随时随地地commit，每天push一次到服务器；&lt;/p&gt;
&lt;p&gt;4、push代码前需要进行pull操作，因为有可能在之前有别的成员先进行了push操作，如果有冲突还需要进行冲突解决；&lt;/p&gt;
&lt;p&gt;5、每天上班后所有成员对dev进行pull操作，获取所有成员push的代码，有冲突需要解决；&lt;/p&gt;
&lt;p&gt;6、团队Leader每天将dev合并一次到master。&lt;/p&gt;
&lt;h2 id="测试进入的阶段"&gt;测试进入的阶段&lt;/h2&gt;
&lt;p&gt;1、测试可能是在项目后期才进入，不同公司或不同项目可能有所不同；&lt;/p&gt;
&lt;p&gt;2、测试进入后就需要添加test分支；&lt;/p&gt;
&lt;p&gt;3、在开发人员将代码push到dev分支后，可以在dev基础上创建test分支，测试人员以test分支搭建测试环境，开始测试；&lt;/p&gt;
&lt;p&gt;4、开发人员在接受到bug后，直接在测试分支上修改，然后让测试人员进行验证；&lt;/p&gt;
&lt;p&gt;5、每天团队Leader将测试分支上修改的bug合并到dev分支上，这样所有团队成员当天修复的bug都会在第二天被团队其他人pull下来；&lt;/p&gt;
&lt;p&gt;6、团队Leader每天将dev合并一次到master。&lt;/p&gt;
&lt;h2 id="上线后阶段"&gt;上线后阶段&lt;/h2&gt;
&lt;p&gt;1、系统上线后试运行阶段会存在两种改动：Bug和优化需求，Bug通常当天解决晚上部署，优化需求通常周末部署；&lt;/p&gt;
&lt;p&gt;2、Bug当天能修复的就直接在test分支上修复，然后进行测试，验证通过后合并到master；&lt;/p&gt;
&lt;p&gt;3、Bug当天不能修复的就针对该Bug创建一个分支，修复完后合并到test分支进行测试，验证通过后合并到master；&lt;/p&gt;
&lt;p&gt;4、每个优化需求都以master分支为基础创建一个feature分支，完成后合并到dev分支，开发人员可以先交叉测试，然后将dev合并到test进行测试，验证通过后合并到master；&lt;/p&gt;
&lt;p&gt;5、master始终是一个干净的，可发布的分支。&lt;/p&gt;
&lt;h2 id="commit提交的粒度"&gt;Commit提交的粒度&lt;/h2&gt;
&lt;p&gt;1、尽可能的越细越好；&lt;/p&gt;
&lt;p&gt;2、每一次的提交应是相对独立的、完整的、有意义的；&lt;/p&gt;
&lt;p&gt;3、注释越详细越好；&lt;/p&gt;
&lt;p&gt;4、第一行概括本次提交的内容，言简意赅；&lt;/p&gt;
&lt;p&gt;5、如果粒度够细，通常一句话可以概括，一句话不能概括的，空一行在下面写详细的注释；&lt;/p&gt;
&lt;p&gt;6、太简单的注释还不如不写，没有任何意义；&lt;/p&gt;
&lt;p&gt;7、据说林纳斯修改了20行的Liunx内核代码，注释长达2000多字，说明commit注释的重要性。&lt;/p&gt;
&lt;p&gt;以上是我在实际工作中的一些心得，仅供参考，工具的使用没有最好，适合自己团队的才是最好的。第一次使用&lt;a href="http://mp.weixin.qq.com/s?__biz=MjM5NTI5MzM2MA==&amp;amp;mid=202105768&amp;amp;idx=1&amp;amp;sn=2ba05ca9c2711f3a1ed913073db2be2b&amp;amp;scene=2&amp;amp;from=timeline&amp;amp;isappinstalled=0#rd"&gt;刘韧体&lt;/a&gt;，感觉还不错，&lt;a href="https://qdan.me/"&gt;轻单网&lt;/a&gt;也是一种类刘韧体的延生，有兴趣的朋友可以去体验下。&lt;/p&gt;</description></item><item><title>VS2012在安装VS2013后打开文件报错，未找到与约束…</title><link>https://fwhyy.com/2015/01/contractname-microsoft-visualstudio-text-itextdocumentfactoryservice/</link><pubDate>Fri, 23 Jan 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/01/contractname-microsoft-visualstudio-text-itextdocumentfactoryservice/</guid><description>&lt;p&gt;VS从VS2003就这么一路装过来，现在机器上最新的版本是VS2012，昨天装了VS2013，发现用VS2012打开项目中文件时会报错，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290801094.webp" alt="3cefded1gw1eojtgufjkvj20dh0700ti" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;下载一个VS的补丁安装后可以解决此问题，补丁下载地址为：&lt;a href="http://download.csdn.net/download/oec2003/8391417"&gt;http://download.csdn.net/download/oec2003/8391417&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290801293.webp" alt="3cefded1gw1eojtgv77gxj20co0hq0t3" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Linode VPS之旅</title><link>https://fwhyy.com/2015/01/linode-vps-trip/</link><pubDate>Mon, 12 Jan 2015 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2015/01/linode-vps-trip/</guid><description>&lt;p&gt;2010年申请域名&lt;a href="http://fwhyy.com/"&gt;fwhyy.com&lt;/a&gt;，开始搭建独立博客，考虑到VPS的费用过高，当时选择的是易网库的香港主机。这一用就是4年，期间也出现过一些问题、客户响应速度和态度都还算可以，总体评价中规中矩吧。直到最近想把女儿的站点搭起来的时候，才发现我主机空间只支持2个MySql的数据库，跟客服交涉过几次，想将空间中我没有用到的MSSql减少一个，将MySql添加一个，得到的反馈都是要么花钱购买一个MySql，要么升级套餐。无奈之下只好选择搬家了。在朋友推荐下，果断选择了Linode VPS，按我那位朋友的说法，Linode是他用过的最好的VPS，没有之一。&lt;/p&gt;
&lt;h2 id="更换ip"&gt;更换IP&lt;/h2&gt;
&lt;p&gt;使用VPS就意味着一切都得自己来折腾，从安装系统（当然是Linux）、安装软件、部署WordPress等等。在Linode中注册、安装都很顺利，成功安装ubuntu系统后，发现只能在翻墙的状态下才能SSH连接到系统中。肯定是之前使用此IP的朋友做过一些和谐的事情，在朋友的指导下得知需要在系统后台中提交ticket申请更换ip，使用蹩脚的英文经过几番交涉之后终于换ip成功。&lt;/p&gt;
&lt;h2 id="安装软件"&gt;安装软件&lt;/h2&gt;
&lt;p&gt;VPS就像是一个毛坯房，就只有一个空间，什么东西都得靠自己来装，Linux系统之前也接触的很少，所以说没有一颗折腾的心还是不要玩VPS。因为第一次玩VPS，为了降低难度，系统选择的是Ubuntu，这个是在Linode上使用的最多的Linux发行版。架构选择的是LNMP一键安装包，没别的原因就是因为省事。LNMP的使用可以参考下面链接：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://lnmp.org/install.html"&gt;http://lnmp.org/install.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;接下来就是做一些基本的配置：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;更新源&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="2"&gt;
&lt;li&gt;生成语言包&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo locale-gen --lang zh_CN.UTF-8
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="3"&gt;
&lt;li&gt;校正时区&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo dpkg-reconfigure tzdataWordpress 
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="4"&gt;
&lt;li&gt;设置权限&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;chmod -R 777 /home/wwwroot/www.fengzihan.me/
chown -R www /home/wwwroot/www.fengzihan.me/
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="5"&gt;
&lt;li&gt;添加虚拟主机&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="http://lnmp.org/faq/lnmp-vhost-add-howto.html"&gt;http://lnmp.org/faq/lnmp-vhost-add-howto.html&lt;/a&gt;&lt;/p&gt;
&lt;ol start="6"&gt;
&lt;li&gt;Nginx下Wordpress只显示一个主题&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# 编辑php.ini文件，找到disable_functions ，将其后面的函数列表中的scandir删除
vi /usr/local/php/etc/php.ini
# 重启php服务，执行下面命令
/etc/init.d/php-fpm restart
http://www.weisay.com/blog/nginx-wordpress-scandir.html
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="7"&gt;
&lt;li&gt;修改root密码&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo passwd root
&lt;/code&gt;&lt;/pre&gt;&lt;ol start="8"&gt;
&lt;li&gt;安装FTP&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;1. 安装vsftpd
sudo apt-get install vsftpd

2. 启动、停止、重启服务
service vsftpd start | stop | restart

3. 添加用户为fengwei的账户，可以方位home目录
useradd fengwei -g ftp -d /home

4. 为fengwei这个账户设置密码
passwd fengwei

5. 修改配置文件
vi /etc/vsftpd.conf
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://lnmp.org/faq/lnmp-vhost-add-howto.html"&gt;http://blog.csdn.net/shuimuzhiyuan/article/details/8548927&lt;/a&gt;
&lt;a href="http://www.blogjava.net/stonestyle/articles/369104.html"&gt;http://www.blogjava.net/stonestyle/articles/369104.html&lt;/a&gt;&lt;/p&gt;
&lt;ol start="9"&gt;
&lt;li&gt;修改mysql上传文件大小&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;find / -name php.ini
usr/local/php/etc/php.ini
vi /usr/local/php/etc/php.ini
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="后记"&gt;后记&lt;/h2&gt;
&lt;p&gt;最后说明下，本文不是一篇入门级教程，只是我初玩VPS的一点记录，一些相关的步骤也在文中给出了参考链接。在一切都安装妥当后的某一天早晨，突然发现博客不能访问了，首先ping了下ip，发现还能ping通，心里石头落下了一半，马上登录到Linode后台准备提交ticket，没想到在后台已经收到了一条客服发来的ticket，大概意思就是发现我VPS的硬盘有故障，正在排查，几分钟后网站恢复正常，对Linode的及时响应速度和处理问题的能力点个赞。&lt;/p&gt;</description></item><item><title>读《番茄工作法图解》</title><link>https://fwhyy.com/2014/03/reading-pomodoro-technique-illustrated/</link><pubDate>Sun, 23 Mar 2014 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2014/03/reading-pomodoro-technique-illustrated/</guid><description>&lt;p&gt;《番茄工作法图解》是一本很小的册子，即便是我这种看书比较慢的也能在几个小时内看完。整本书在讲一种可以提高效率的做事的方法，可以总结成四个字，“专注，坚持”。有一个广为流传的一万小时理论说的是在某一个领域专注10000个小时，平均每天3小时，花10年的时间，你就可以成为这个领域的专家，其实说的也是专注和坚持。下面就看看番茄工作法是怎么样来提高我们的效率的。&lt;/p&gt;
&lt;h2 id="几个术语"&gt;几个术语&lt;/h2&gt;
&lt;p&gt;番茄钟：一个25分钟的时间段成为一个番茄钟，最初因为厨房的定时钟长的像番茄而得名，在一个番茄钟内需要专注做一件事情；&lt;/p&gt;
&lt;p&gt;活动：指要完成的工作任务；&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;内部中断：在一个番茄钟内，来自自身的干扰，如想去刷刷微博，或者去看看新闻等；&lt;/li&gt;
&lt;li&gt;外部中断：在一个番茄钟内，来自外界的干扰，如电话、邮件、被同事咨询问题等；&lt;/li&gt;
&lt;li&gt;预估：对任务需要多少个番茄钟才能完成的判断。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="工具"&gt;工具&lt;/h2&gt;
&lt;p&gt;使用番茄工作法的工具很简单，一个番茄钟、一只笔、几张纸质表格即可、番茄钟用来计时用，纸和笔用来记录用，纸质表格分为下面三类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;活动清单&lt;/li&gt;
&lt;li&gt;今日待办&lt;/li&gt;
&lt;li&gt;记录&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="方法"&gt;方法&lt;/h2&gt;
&lt;p&gt;每天开始从活动清单中挑选一些重要的活动作为今日待办，选择今日待办中最重要的活动，开启一个番茄钟，开始专注这项活动。番茄钟结束立即立即停止工作，停止前可以稍微整理下思路，然后休息3到5分钟，这个短暂的休息就是一个小的奖励，休息完后就可以进入下一个番茄钟。每一个番茄钟就像是一个小的目标，那个短暂的休息激励着你去完成一个一个的小的目标。&lt;/p&gt;
&lt;p&gt;完成4个番茄钟后可以进行15到30分钟的长时间的休息。&lt;/p&gt;
&lt;p&gt;番茄钟是不可分割的，如果你预估的一项活动需要多个番茄钟才能完成，需要将活动进行拆分成更小的活动。&lt;/p&gt;
&lt;h2 id="一些疑问"&gt;一些疑问&lt;/h2&gt;
&lt;h3 id="怎样挑选今日待办"&gt;怎样挑选今日待办？&lt;/h3&gt;
&lt;p&gt;活动清单中的活动太多，可以采用比较法来进行挑选，两两比较，如果今天只能做一件事情你会选哪件，最终胜出的优先级最高，以此类推，可以选择出今天的待办列表。&lt;/p&gt;
&lt;h3 id="内部中断怎么办"&gt;内部中断怎么办？&lt;/h3&gt;
&lt;p&gt;番茄工作法一再强调一次只做一件事，在一个番茄钟内需要高度专注当前活动，有临时的一些想法，可以先记录下来，再根据优先级在后面的番茄钟里去完成。克制自己时不时就去刷下微博的习惯，克制自己把注意力放到了不停闪烁的QQ图标上，实在不行可以再番茄钟内将任务栏隐藏。举一个简单的例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本来我在看一篇关于C#的技术博客；&lt;/li&gt;
&lt;li&gt;被文章中的链接带到了一篇介绍Git的文章中；&lt;/li&gt;
&lt;li&gt;在Git的文章中介绍了一个编程大牛的博客；&lt;/li&gt;
&lt;li&gt;翻阅大牛的博客发现有很多感兴趣的文章，挑选一些一一翻阅；&lt;/li&gt;
&lt;li&gt;我特么最初是想干什么来着，可能已经记不起来了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面是我经常会出现的问题，如果用番茄工作法，我应该在看到介绍Git链接的时候，将该链接保存下来，然后继续学习那篇关于C#的文章。&lt;/p&gt;
&lt;h3 id="外部中断怎么办"&gt;外部中断怎么办？&lt;/h3&gt;
&lt;p&gt;外部中断可能是一个很重要的电话；可能是领导突然叫你去谈一些事情；可能是一封不得不处理的邮件，当遇到这些不能推脱的打断的时候，必须停掉当前的番茄钟，回来之后重新开始一个新的番茄钟。&lt;/p&gt;
&lt;p&gt;一个番茄钟没完成，活动已经完成怎么办？&lt;/p&gt;
&lt;p&gt;番茄钟没结束，活动已经结束了，说明预估出现了误差，此时不应该马上去做下一个活动，可以进行一些过渡性学习，或者回顾一下该番茄钟内完成的活动。&lt;/p&gt;
&lt;h3 id="一定要是25分钟吗"&gt;一定要是25分钟吗？&lt;/h3&gt;
&lt;p&gt;为什么是25分钟，这个得问创始人了，书里强烈建议不管你是否觉得合适，先按照25分钟坚持一个星期再根据自己实际情况进行调整，先坚持一个星期目的是为了让我们养成一种习惯，只有在一段时间内去体验了，才会觉得合不合适。而不是根据自己的性子今天10分钟，明天1个小时。&lt;/p&gt;
&lt;h2 id="我的思考"&gt;我的思考&lt;/h2&gt;
&lt;p&gt;番茄工作法是一种时间管理的工具，如果您高度自律，您可能不需要。如果你和我一样，在做事的时候会去耍耍微博、看看邮件、聊聊QQ，那么不妨试一试这种方法；&lt;/p&gt;
&lt;p&gt;番茄工作法更适合一些个人事务，不是很适合程序员这种工作，程序员这种工作不确定性太多，外部中断太多，每天要做什么事情可能在上班后才会知道；&lt;/p&gt;
&lt;p&gt;番茄工作法只是一种约束自己提高效率的工具，没有必要完全停留在形式上，做到“专注，坚持”就够了。&lt;/p&gt;</description></item><item><title>Ubuntu12.04中安装Git</title><link>https://fwhyy.com/2014/02/install-git-in-ubuntu12-04/</link><pubDate>Sun, 23 Feb 2014 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2014/02/install-git-in-ubuntu12-04/</guid><description>&lt;p&gt;Git是一个分布式源码管工具，在之前的&lt;a href="http://blog.fwhyy.com/category/jishu/git/"&gt;文章&lt;/a&gt;中有讲到过怎样在Windows下使用Git和在VS中使用Git，最近在尝试在Ubuntu中搭建Gitlab环境，Linux系统也是初次接触，属于摸索中前进，先说说在Ubuntu中怎样安装Git&lt;/p&gt;
&lt;p&gt;1、首先可以通Ctrl+Alt+T快捷键打开终端；&lt;/p&gt;
&lt;p&gt;2、输入命令sudo apt-get git，使用该命令安装的git是比较老的版本；&lt;/p&gt;
&lt;p&gt;3、安装了老的版本的git后，可以使用git clone git://git.kernel.org/pub/scm/git/git.git将获取到git的源码，默认会签出最近的版本；&lt;/p&gt;
&lt;p&gt;4、使用git tag可以查看所有的历史版本，可以用git checkout version来签出指定版本进行安装，例如：git checkout v1.9.0；&lt;/p&gt;
&lt;p&gt;5、在编译安装前先要安装ssl编译开发包，使用sudo apt-get install libssl-dev；&lt;/p&gt;
&lt;p&gt;6、用cd命令进入到git目录，执行make prefix=/usr/local all doc进行编译；&lt;/p&gt;
&lt;p&gt;7、使用sudo make prefix=/usr/local install install-doc install-html进行安装；&lt;/p&gt;
&lt;p&gt;8、安装完后，重新打开终端，使用git –version来查看安装是否成功。&lt;/p&gt;</description></item><item><title>2013 年终总结</title><link>https://fwhyy.com/2014/02/2013-year-summary/</link><pubDate>Sat, 22 Feb 2014 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2014/02/2013-year-summary/</guid><description>&lt;p&gt;从毕业后几乎每年都会写一篇总结，而且习惯子农历的新年前写，在我的思想观念里，农历的新年才算过年。今年也不例外，不过由于一些原因推迟到年后了。还是从工作和生活两方面来总结下即将过去的2013年。记得&lt;a href="http://blog.fwhyy.com/2013/01/2012-year-summary/"&gt;去年的总结&lt;/a&gt;最后写的对2013年的展望是这样的：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;能尽快的把驾照拿到手；&lt;/li&gt;
&lt;li&gt;准备要小宝宝；&lt;/li&gt;
&lt;li&gt;买车；&lt;/li&gt;
&lt;li&gt;工资有所突破；&lt;/li&gt;
&lt;li&gt;职位有所突破；&lt;/li&gt;
&lt;li&gt;深入研究几种技术，性能优化为主。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;除了第六条，其他的都已达成，还是比较欣慰的。&lt;/p&gt;
&lt;h2 id="工作"&gt;工作&lt;/h2&gt;
&lt;p&gt;去年利用业余时间做了一个工具，并在部门内使用起来，在年终获得了一些奖励。不知道是不是因为这个原因，今年年初的人才盘点我的职位被调成了Team Leader，公司的Team Leader主要职责是技术攻关和团队建设，而团队成员的积极性方面则不需要过多操心，因为有绩效制度在鞭策。&lt;/p&gt;
&lt;p&gt;2013年夏天，一个做企业信息化的小公司希望我能加入他们，经过几次沟通后，我最终决定了加入这家小公司。之前的公司算的上是一个中型公司，在武汉这边的 研发就有4、5百人，而且也基本上做到了行业老大的位子，部门老大对我也很不错，上升空间还是很大的，按理说我应该不会离开才对。但正是因为公司比较大，各种规范流程比较繁琐，而且还有很“不合理”的KPI考核，尽管每年都在做优化，每个人员都各司其职在条条框框内做事。这些方式方法的存在肯定有其道理，作为管理者来说，依赖这些规则可以节省成本，提高效率，但我却很不喜欢，所以我选择离开。&lt;/p&gt;
&lt;p&gt;经过半个多月的交接，9月1日到新公司报道，在这里的自由度相对较大，也能做自己喜欢的事情，自己所学的东西在工作中能够得以施展。到现在已经近半年的时间，工作还是很开心的，希望能再接再厉。&lt;/p&gt;
&lt;h2 id="生活"&gt;生活&lt;/h2&gt;
&lt;p&gt;12年的一次错误决定，导致我现在得时不时的回家去，因为在家里报的驾校，起初的原因是户口在老家，而且当时老家的报名费比武汉要便宜1000多，现在看来真是得不偿失。体检得回去、科目一的测试得回去、科目一的考试得回去，当然这些都只是周末，最后发现到练车的时候不是仅仅周末回去就能解决的。无赖之下请了一个月的假回家专门学车，正值夏日，每天早出晚归，其实也只能练习5、6次，其余的时间都是在等待中，等待中的时间除了聊天还是聊天，驾校里会有形形色色的社会人或是学生，与人聊天或是听人聊天感觉也还不错。一个月的时间就这样机械化的度过了，也顺利的考过了科目2，最终10月份拿到驾照。&lt;/p&gt;
&lt;p&gt;9月份的一次检查得知老婆怀孕，也没有什么特别的感觉，因为一直也在准备在事。之后老婆说能感觉到胎动的时候，我用手也能感觉到的时候，特别的兴奋，可能在这个时候才真正感觉到这个小生命的存在，之后的每天睡觉前，我都会和小宝宝说说话。让人欣慰的是从怀孕到现在的产检都比较正常，现在很期待在5月份看见宝宝的样子时的感觉。&lt;/p&gt;
&lt;h2 id="2014展望"&gt;2014展望&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;5月宝宝能顺利出生；&lt;/li&gt;
&lt;li&gt;工作上能跟进一步；&lt;/li&gt;
&lt;li&gt;持续学习，不局限于编程。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>placeholder在IE8中兼容性问题解决</title><link>https://fwhyy.com/2014/02/placeholder-in-ie8/</link><pubDate>Wed, 12 Feb 2014 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2014/02/placeholder-in-ie8/</guid><description>&lt;p&gt;placeholder是HTML5中的一个属性，可以在文本框中设置placeholder属性来显示一些提示性的文字，但对IE10以下的浏览器不支持，下面方法可以让placeholder能够使用在IE10以下的版本中。第一种方法是在页面中添加下面一段脚本：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt; 
 if( !(&amp;#39;placeholder&amp;#39; in document.createElement(&amp;#39;input&amp;#39;)) ){ 

 $(&amp;#39;input[placeholder],textarea[placeholder]&amp;#39;).each(function(){ 
 var that = $(this), 
 text= that.attr(&amp;#39;placeholder&amp;#39;); 
 if(that.val()===&amp;#34;&amp;#34;){ 
 that.val(text).addClass(&amp;#39;placeholder&amp;#39;); 
 } 
 that.focus(function(){ 
 if(that.val()===text){ 
 that.val(&amp;#34;&amp;#34;).removeClass(&amp;#39;placeholder&amp;#39;); 
 } 
 }) 
 .blur(function(){ 
 if(that.val()===&amp;#34;&amp;#34;){ 
 that.val(text).addClass(&amp;#39;placeholder&amp;#39;); 
 } 
 }) 
 .closest(&amp;#39;form&amp;#39;).submit(function(){ 
 if(that.val() === text){ 
 that.val(&amp;#39;&amp;#39;); 
 } 
 }); 
 }); 
 } 
&amp;lt;/script&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的方法不能支持password类型的文本框，网上找了些解决方法都不是很完美，最后发现jQuery的placeholder插件还不错，代码如下：&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gist.github.com/oec2003/8946120"&gt;https://gist.github.com/oec2003/8946120&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;将placeholder.js文件引用到页面，页面中添加下面脚本：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
$(function() {
 $(&amp;#39;input, textarea&amp;#39;).placeholder();
});
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>买车记</title><link>https://fwhyy.com/2014/01/buy-car/</link><pubDate>Mon, 20 Jan 2014 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2014/01/buy-car/</guid><description>&lt;p&gt;在《&lt;a href="http://blog.fwhyy.com/2013/01/2012-year-summary/"&gt;2012年总结&lt;/a&gt;》一文中写到对2013年的展望就提到买车，而且今年和老婆准备要小宝宝，所以买车也是顺理成章的事情。&lt;/p&gt;
&lt;h2 id="选车"&gt;选车&lt;/h2&gt;
&lt;p&gt;先是在网上查各种资料，看过的牌子有速腾、朗逸、明锐、标致408、科鲁兹、福克斯等。基本都是15万以内的紧凑型车。9月份和老婆一起两次去4S店看车，不是销售人员的态度不好就是车子的优惠不多，导致最终也没能定下来。9月23号公司因大楼停电检修调整了上班时间，正好前一天在网上看到明锐的优惠还比较给力，走出公司大楼给明锐4S店打了个电话，证实确实有活动，坐了2小时车从武昌到汉阳，销售人员态度还不错，最后确定车子可以优惠1.4W，说是当天交100元诚意金，在28号会有一个活动，活动当天可以低1000，二话没说交了100块。就这样算是已经选定明锐了。&lt;/p&gt;
&lt;p&gt;9月28号，早早的就去了4S店，销售人员告诉我如果在12点之前交定金可以参加下午的双倍夺宝返现金的活动，心想反正已经决定买明锐了，定金是迟早要交的，于是就交了5000定金，并选了车子颜色和型号。接下来就是一些无聊的活动环节、唱歌、跳舞、厂商的人做演讲等。最终给出的优惠是1.8W现金+2000的油卡+1000的工时费，比预期的还要给力点。下午的夺宝活动因为场地太滑没有发挥好，不过也收了1800元。总的来说优惠还是挺满意的。&lt;/p&gt;
&lt;h2 id="提车"&gt;提车&lt;/h2&gt;
&lt;p&gt;从下定金到提车也就1个多星期的时间，还算是比较快的，车子是我老婆的弟弟帮我开会去的，因为我驾照还没拿到手。就算有驾照，这么长途跋涉的也不怎么敢开，安全还是要摆第一位的嘛。接下来的时间就只能在小区里练练倒库了，在驾校练的倒库跟实际中的倒库完全是两码事。10月22号顺利拿到驾照，第二天就开车上班了。无奈没多久临牌就到期了，而正式牌照还在办理中，因为办牌照需要居住证，办理居住证延期花了不少时间。就这样一直到11月份才将所有手续都办齐，终于可以开车上班啦。&lt;/p&gt;
&lt;h2 id="感受"&gt;感受&lt;/h2&gt;
&lt;p&gt;买车到现在2个多月的时间，总里程数2500多公里，平均油耗7.2。期间也发生了不少事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;倒车时注意力在后面，提早打方向盘，右前保险杠和旁边车子屁股擦了；&lt;/li&gt;
&lt;li&gt;回老家因为修路绕了一段非常坑爹的泥浆路，旁边都是几十吨的大卡车，最终因为不会选路上不去也下不来，几个卡车司机的帮助下才开出去，现在想想都有点后怕；&lt;/li&gt;
&lt;li&gt;三环上60码的速度压了一东西导致爆胎，打电话给保险救援，等了半天别人说高架桥不能帮忙换胎，无奈之下边看说明书变换了备胎。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所幸的是人是平安的，对于安全行车有几点体会：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注意力要集中、思想不能开小差，不能疲劳驾驶，更不能酒驾；&lt;/li&gt;
&lt;li&gt;眼观六路耳听八方，多注意车子、行人的动向；&lt;/li&gt;
&lt;li&gt;不要随意变道，看见很多车子为了那么一点点时间，在不同道之间变来变去，很容易发生碰撞；&lt;/li&gt;
&lt;li&gt;不一定速度慢就是安全的，例如转弯、超车观察好后一定要果断。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="注意"&gt;注意&lt;/h2&gt;
&lt;p&gt;订车那天由于有一些配件做活动，就在4S店买了，包括导航、脚垫等，脚垫基本是个废的，踩了不到一个星期就起毛，质量真是差的令人发指，后来去汽配城花200多换了一套全包围的。导航也很坑，蓝牙电话当来电时不能自动切换到电话界面，不过有一点还是很“智能”的，我一到4S店，维修人员过来他就好了，等我开出去又不能切换了，后来换了一个导航依旧如此。&lt;/p&gt;
&lt;p&gt;4S店的东西贵的离谱，轮毂、轮胎都要比外面贵几百块，还不能还价，还要算什么工时费，所以能在外面解决的尽量不要去4S店。&lt;/p&gt;</description></item><item><title>连接RTX服务器出现“应用SDK:连接SDK服务器错误”问题解决</title><link>https://fwhyy.com/2014/01/connect-to-rtx-server-application-the-sdk-to-connect-sdk-server-error-problem-solution/</link><pubDate>Thu, 09 Jan 2014 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2014/01/connect-to-rtx-server-application-the-sdk-to-connect-sdk-server-error-problem-solution/</guid><description>&lt;p&gt;腾讯通的官方有个示例可以使用程序来进行腾讯通客户端的登录，大致原理是这样：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;从服务端验证用户名是否存在；&lt;/li&gt;
&lt;li&gt;根据用户名从服务端生成key；&lt;/li&gt;
&lt;li&gt;根据key值调用脚本启动腾讯通客户端。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在本机安装好腾讯通的客户端和服务器，运行实例程序，可以正常跑起来，将服务器安装在虚机中，就会报“(0xFFFFBA9E): 应用SDK:连接SDK服务器错误”的错误，原因是服务器端对IP地址有限制，修改配置文件，重启腾讯通的所有服务即可，具体方法如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290800352.webp" alt="3cefded1gw1eccx0b95c2j20fl0d9myt" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;将示例部署到IIS中，运行后出现如下错误：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290800607.webp" alt="3cefded1gw1eccx0aqp3hj20mq06i41k" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="网上查到的一些解决方法"&gt;网上查到的一些解决方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;注册腾讯通的dll（Interop.RTXSAPILib.dll），试过发现无法注册；&lt;/li&gt;
&lt;li&gt;修改项目的编译平台为x86，发现也不能解决；&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="最终解决方法"&gt;最终解决方法&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;在对应的应用程序池上点击右键；&lt;/li&gt;
&lt;li&gt;选择高级设置；&lt;/li&gt;
&lt;li&gt;常规选项卡上将“启用32位应用程序”修改为true。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290801459.webp" alt="3cefded1gw1eccxc5i01nj20cf0f1q5i" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="测试环境"&gt;测试环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;系统：Windows 7&lt;/li&gt;
&lt;li&gt;开发工具：VS2012&lt;/li&gt;
&lt;li&gt;腾讯通版本：2012&lt;/li&gt;
&lt;li&gt;IIS版本：IIS7&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Asp.Net正在中止线程引发的问题</title><link>https://fwhyy.com/2013/11/aspnet-stoped-thread-method/</link><pubDate>Fri, 22 Nov 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/11/aspnet-stoped-thread-method/</guid><description>&lt;p&gt;Asp.Net做的一个同步程序，同步的方法是通过JQuery的Ajax调用，同步过程大概要执行20多分钟，程序部署到服务器后执行一段时间后就弹出执行失败的对话框，日志记录的错误信息是“正在中止线程”。&lt;/p&gt;
&lt;h2 id="查错过程"&gt;查错过程：&lt;/h2&gt;
&lt;p&gt;1、根据“AspNet 正在中止线程“进行搜索，得到的结果基本都是跟”Response.End“有关的，但我的代码中没有Response.End，所以基本可以排除；&lt;/p&gt;
&lt;p&gt;2、因为使用JQuery的Ajax，所以猜想会不会是因为Ajax超时导致，修改代码将返回状态弹出：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290809786.webp" alt="3cefded1gw1eatnxducbjj20k0051dg8" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;发现返回的status为”error“，也尝试过将timeout设置为一个较大值，发现问题依然存在，所以可以排除是JQuery Ajax超时；&lt;/p&gt;
&lt;p&gt;3、使用Fiddler2进行监控，发现执行一段时间后报了500错误，显示的错误详细信息如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290809600.webp" alt="3cefded1gw1eatnxcw1mrj20f607st9e" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;到了这一步就好办了，可以知道是httpRuntime超时了，配置Webconfig就可以了，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290809727.webp" alt="3cefded1gw1eatnxep1sfj20gb031wet" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;设置好好后发不到服务器，再次运行程序，问题解决。&lt;/p&gt;
&lt;p&gt;奇怪的是在本机运行的时候即使没有设置executionTimeout也不会出现问题，原因是在本机的Webconfig中的compilation节点的有个debug属性设置为true，发布后的Webconfig中的compilation没有debug节点，当debug属性为false时，httpRuntime的executionTimeout属性才会生效。&lt;/p&gt;</description></item><item><title>HTML解析组件HtmlAgilityPack使用</title><link>https://fwhyy.com/2013/09/using-htmlagilitypack/</link><pubDate>Sun, 15 Sep 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/09/using-htmlagilitypack/</guid><description>&lt;p&gt;HtmlAgilityPack是一个开源的解析HTML元素的类库，最大的特点是可以通过XPath来解析HMTL，如果您以前用C#操作过XML，那么使用起HtmlAgilityPack也会得心应手。目前最新版本为1.4.6,下载地址如下：&lt;/p&gt;
&lt;p&gt;&lt;a href="http://htmlagilitypack.codeplex.com/"&gt;http://htmlagilitypack.codeplex.com/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="使用介绍"&gt;使用介绍&lt;/h2&gt;
&lt;p&gt;下面以一个简单的例子来介绍下HtmlAgilityPack的使用，对于Asp.Net程序开发的网站要做模拟登录的时候，除了要知道用户名文本框和密码文本框的name属性值外，还需要知道页面的__VIEWSTATE、__EVENTVALIDATION这两个隐藏控件的值，以及提交按钮的name属性，下面看看怎样使用HtmlAgilityPack来获得这个额外的值。&lt;/p&gt;
&lt;p&gt;1、在项目中添加对HtmlAgilityPack.dll的引用&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290704832.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2、在Aspx页面中放几个文本框控件和一个按钮控件&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290704038.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3、按钮的后台事件如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protected void btnHtml_Click(object sender, EventArgs e)
{
 if (tbUrl.Text.Length &amp;gt; 0)
 {
 HtmlWeb htmlWeb = new HtmlWeb();
 HtmlDocument htmlDoc = htmlWeb.Load(this.tbUrl.Text);
 HtmlNode htmlNode = htmlDoc.DocumentNode.SelectSingleNode(&amp;#34;//input[@id=&amp;#39;__VIEWSTATE&amp;#39;]&amp;#34;);
 string viewStateValue = htmlNode.Attributes[&amp;#34;value&amp;#34;].Value;
 htmlNode = htmlDoc.DocumentNode.SelectSingleNode(&amp;#34;//input[@id=&amp;#39;__EVENTVALIDATION&amp;#39;]&amp;#34;);
 string eventValidation = htmlNode.Attributes[&amp;#34;value&amp;#34;].Value;
 htmlNode = htmlDoc.DocumentNode.SelectSingleNode(&amp;#34;//input[@type=&amp;#39;submit&amp;#39;]&amp;#34;);
 string submitName = htmlNode.Attributes[&amp;#34;name&amp;#34;].Value;

 tbViewState.Text = viewStateValue;
 tbEventValidation.Text = eventValidation;
 tbSubmitName.Text = submitName;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4、以博客园的登录界面为例，获取后的界面如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290705365.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://pan.baidu.com/share/link?shareid=71500880&amp;amp;uk=2902808695"&gt;示例下载&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SqlServer2008R2用Windows身份登录18456错误解决</title><link>https://fwhyy.com/2013/09/sqlserver2008r2-windows-login-18456-error/</link><pubDate>Sat, 07 Sep 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/09/sqlserver2008r2-windows-login-18456-error/</guid><description>&lt;p&gt;重装系统后发现SqlServer2008R2使用Windows身份验证不能进行连接，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302000357.webp" alt="07070635-ce750450dc434a518651c5d3b77f9402" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;以前经常会碰到SqlServer 身份验证连接失败，Windows身份验证的连接失败还是第一次，试了下SqlServer 身份验证可以正常连接，sa账号连接进去后，在安全性-》登录名下没有发现当前登录用户的账号，在登录名上点击邮件，新建登录名即可：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302000426.webp" alt="07070636-ed428dd377a147e99a2e428551933309" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Windows中搭建已存在的Octopress环境</title><link>https://fwhyy.com/2013/08/how-to-use-exist-octopress-in-windows/</link><pubDate>Thu, 15 Aug 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/08/how-to-use-exist-octopress-in-windows/</guid><description>&lt;p&gt;当我们需要在不同的电脑上来对同一个Octopress博客进行维护的时候就需要针对已存在的Octopress来设置环境了，&lt;/p&gt;
&lt;h2 id="安装相应的软件"&gt;安装相应的软件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Git：&lt;a href="http://msysgit.googlecode.com/files/Git-1.8.1.2-preview20130201.exe"&gt;http://msysgit.googlecode.com/files/Git-1.8.1.2-preview20130201.exe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ruby：&lt;a href="http://files.rubyforge.vm.bytemark.co.uk/rubyinstaller/rubyinstaller-1.9.3-p429.exe"&gt;http://files.rubyforge.vm.bytemark.co.uk/rubyinstaller/rubyinstaller-1.9.3-p429.exe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DevKit：&lt;a href="http://cloud.github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe"&gt;http://cloud.github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Python：&lt;a href="http://www.python.org/ftp/python/2.7.5/python-2.7.5.msi"&gt;http://www.python.org/ftp/python/2.7.5/python-2.7.5.msi&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;关于软件的安装在《&lt;a href="http://blog.fwhyy.com/2013/05/how-to-crate-octopress-blog-in-windows/"&gt;Windows下搭建Octopress博客&lt;/a&gt;》中有详细的介绍。&lt;/p&gt;
&lt;h2 id="拉octopress代码到本地"&gt;拉Octopress代码到本地&lt;/h2&gt;
&lt;p&gt;使用下面命令将已存在的Octopress代码拉到本地&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git clone -b source git@github.com:oec2003/oec2003.github.com.git
git clone git@github.com:oec2003/oec2003.github.com.git _deploy
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="编写文章"&gt;编写文章&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd Octopress
rake new_post[&amp;#39;new post title&amp;#39;]
rake generate
rake preview
rake deploy
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="推送到github"&gt;推送到github&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd Octopress
git add .
git commit -m &amp;#39;message&amp;#39;
git push origin source
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="从github上获取最新"&gt;从github上获取最新&lt;/h2&gt;
&lt;p&gt;比如在公司发布了一篇博文，回到家里想继续发博文，就需要先将github上的最新代码拉到本地：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd Octopress
cd _deploy
git pull origin master
cd ..
git pull origin source
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;今天在家里的另一台电脑上进行生成文章时，发现当执行了命令rake generate 后，生成到public目录中相应的页面为空，没有任何内容，但在命令行中命令还是正常执行了，没有出现异常。最后查出原因是因为Python的安装目录没有添加到环境变量中。所以建议在准备环境时就就将git、ruby、python的安装目录都添加到环境变量中。&lt;/p&gt;</description></item><item><title>Windows7给C盘扩容</title><link>https://fwhyy.com/2013/07/adjust-disk-c-capacity-in-windows7/</link><pubDate>Sat, 13 Jul 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/07/adjust-disk-c-capacity-in-windows7/</guid><description>&lt;p&gt;在之前的系统中都是使用PartitionMagic来进行磁盘容量的分配，但PartitionMagic在Windows7中的兼容性不是好很好，导致不能使用。其实Windows7自带了磁盘管理工具，下面说说怎样使用自带的磁盘管理工具进行C盘的扩容。&lt;/p&gt;</description></item><item><title>Octopress博客设置</title><link>https://fwhyy.com/2013/05/octopress-blog-setting/</link><pubDate>Fri, 31 May 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/05/octopress-blog-setting/</guid><description>&lt;p&gt;在上一篇《&lt;a href="http://blog.fwhyy.com/2013/08/how-to-use-exist-octopress-in-windows/"&gt;Windows下搭建Octopress博客&lt;/a&gt;》中介绍了怎样在Windows环境中搭建Octopress博客，以及如何部署到Github中，本文主要讲解怎样对Octopress进行一些设置，比如修改博客标题、添加侧边栏等等。&lt;/p&gt;
&lt;h2 id="octopress文件目录"&gt;Octopress文件目录&lt;/h2&gt;
&lt;p&gt;首先来看下Octopress的文件目录吧，因为很多的设置就是从这里开始的。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301600903.webp" alt="3cefded1gw1e52yyb8jz7j207f0e5mxp" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;刚clone下来的Octopress源码没有最后的三个文件，当执行了rake install后会产生最后的三个目录。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;source：该目录是执行rake install后从.themes\classic目录中的source拷贝而来，并且添加了一个_posts目录了，当执行了rake new_post[‘title’]后会在_post生成博文的markdown文件。包括后面的很多设置页是在该目录中进行&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;sass：也是在执行rake install后从.themes\classic目录中的source拷贝而来。Sass 扩展了 CSS3，增加了规则、变量、混入、选择器、继承等等特性。Sass 生成良好格式化的 CSS 代码，易于组织和维护&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;public：刚clone源码时public是个空目录，当执行了rake generate后会编译source的内容然后将编译后的内容复制到public目录中，在执行rake deploy后也是讲public的内容推送到服务器上，我们最终访问到的也是public的内容。这个目录中的内容一般不用我们手动修改，执行rake generate来生成。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="基本设置"&gt;基本设置&lt;/h2&gt;
&lt;p&gt;在Octopress目录中有一个名为_config.yml的文件：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;url: [http://oec2003.github.io](http://oec2003.github.io/) #网站地址

title: 冯威的个人博客 
#网站标题

subtitle: 临渊羡鱼 不如退而结网. 
#网站副标题

author: 冯威 #网站作者，通常显示在页尾和每篇文章的尾部

simple_search: [http://google.com/search](http://google.com/search) # 搜索引擎

description: #网站的描述，出现在HTML页面中的 meta 中的 description
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在使用rake new_post[&amp;rsquo;title&amp;rsquo;]生成的markdown文件中，可以对每篇博文进行一些设置：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;layout: post

title: &amp;#34;我的第一篇Octopress博客&amp;#34; #文章标题

date: 2013-05-26 18:49 #文章发布时间

comments: true #是否允许评论

categories: Octopress #文章分类
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="设置网站的description和keywords"&gt;设置网站的description和keywords&lt;/h2&gt;
&lt;p&gt;在网页的head部分设置name为description和keywords的meta元素可以让网页更容易被搜索引擎搜索到，下面说说怎样在Octopress中设置首页和每篇博文的description和keywords。&lt;/p&gt;
&lt;h2 id="设置首页"&gt;设置首页&lt;/h2&gt;
&lt;p&gt;打开source/index.html文件，在文件的头部添加相应内容：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;layout: default

#下面为添加的内容

description: &amp;#34;冯威的个人博客&amp;#34;

keywords: Asp.Net,C#
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="设置文章"&gt;设置文章&lt;/h2&gt;
&lt;p&gt;文章的设置直接在每篇文章对应的markdown文件的头部添加相应内容即可：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;layout: post

title: &amp;#34;我的第一篇Octopress博客&amp;#34;

date: 2013-05-26T18:49:00+08:00
comments: true

categories: Octopress

#下面为新增内容

description: &amp;#34;我的第一篇Octopress博客&amp;#34;

keywords: Octopress
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="导航栏设置"&gt;导航栏设置&lt;/h2&gt;
&lt;p&gt;打开文件&lt;code&gt;source\_includes\custom\navigation.html&lt;/code&gt;，默认情况下如下所示：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=”{{ root_url }}/”&amp;gt;Blog&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=”{{ root_url }}/blog/archives”&amp;gt;Archives&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以将Blog和Archives修改为首页和归档，不过记得将包含有中文的文件保存为无BOM的UTF-8编码格式。也可以在此添加一个标签页，比如加上一个关于，我们可以按下面步骤实现：&lt;/p&gt;
&lt;p&gt;使用命令rake new_page[&amp;lsquo;about&amp;rsquo;]创建一个页面，页面路径为source\about\index.markdown;&lt;/p&gt;
&lt;p&gt;修改上面的navigation.html为：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;ul&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=”{{ root_url }}/”&amp;gt;首页&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=”{{ root_url }}/blog/archives”&amp;gt;归档&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;li&amp;gt;&amp;lt;a href=”{{ root_url }}/about”&amp;gt;关于&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
&amp;lt;/ul&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;显示效果如下：&lt;/p&gt;</description></item><item><title>Windows下搭建Octopress博客</title><link>https://fwhyy.com/2013/05/how-to-crate-octopress-blog-in-windows/</link><pubDate>Mon, 27 May 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/05/how-to-crate-octopress-blog-in-windows/</guid><description>&lt;h2 id="您需要掌握的"&gt;您需要掌握的&lt;/h2&gt;
&lt;p&gt;使用Octopress来搭建博客，还是有一定门槛的，看完本文后，希望您不会觉得很难。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://octopress.org/"&gt;Octopress&lt;/a&gt; 是一款基于 &lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; 的静态站点生成系统，使用Ruby实现，所以您需要懂点Ruby的知识，其实会几个命令就行；&lt;/p&gt;
&lt;p&gt;Octopress的博客内容是通过Markdown来书写，所以您需要了解Markdown的编写规则，&lt;a href="http://wowubuntu.com/markdown/"&gt;Markdown 语法说明&lt;/a&gt;可以让你在几分钟之内熟悉Markdown的语法，在Windows下可以使用MarkDown Pad或是使用在线的编辑器&lt;a href="http://mahua.jser.me/"&gt;http://mahua.jser.me/&lt;/a&gt;进行编辑；&lt;/p&gt;
&lt;p&gt;Octopress通常会部署在&lt;a href="https://github.com/"&gt;GitHub&lt;/a&gt;上，所以您需要会一些简单的Git命令以及Gtihub的使用。&lt;/p&gt;
&lt;h2 id="准备"&gt;准备&lt;/h2&gt;
&lt;p&gt;系统：Windows 2003 Server、Windows 7、Windows 2008R2 Server，这三个系统用下面的版本都安装成功过；&lt;/p&gt;
&lt;p&gt;Git：&lt;a href="http://msysgit.googlecode.com/files/Git-1.8.1.2-preview20130201.exe"&gt;http://msysgit.googlecode.com/files/Git-1.8.1.2-preview20130201.exe&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ruby：&lt;a href="http://files.rubyforge.vm.bytemark.co.uk/rubyinstaller/rubyinstaller-1.9.3-p429.exe"&gt;http://files.rubyforge.vm.bytemark.co.uk/rubyinstaller/rubyinstaller-1.9.3-p429.exe&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;DevKit：&lt;a href="http://cloud.github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe"&gt;http://cloud.github.com/downloads/oneclick/rubyinstaller/DevKit-tdm-32-4.5.2-20111229-1559-sfx.exe&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Python：&lt;a href="http://www.python.org/ftp/python/2.7.5/python-2.7.5.msi"&gt;http://www.python.org/ftp/python/2.7.5/python-2.7.5.msi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Octopress：&lt;a href="git://github.com/imathis/octopress.git"&gt;git://github.com/imathis/octopress.git&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;h3 id="安装git"&gt;安装Git&lt;/h3&gt;
&lt;p&gt;Windows下安装Git很简单，一路next就可以了。&lt;/p&gt;
&lt;h3 id="安装ruby"&gt;安装Ruby&lt;/h3&gt;
&lt;p&gt;Ruby的安装也是一路next就可以，不过记得勾选“Add Ruby executables to your PATH”，将Ruby的执行路径加入到环境变量中，如果忘记勾选，也可以手动设置。安装完后可以在命令提示符中输入ruby –version 来确认是否安装成功。&lt;/p&gt;
&lt;h3 id="安装devkit"&gt;安装DevKit&lt;/h3&gt;
&lt;p&gt;DevKit下载下来的是一个自压缩文件，我们将其解压到D:/DevKit，有两点需要注意：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;解压目录中没有有中文和空格；&lt;/li&gt;
&lt;li&gt;必须先安装Ruby，而且Ruby需要是RubyInstallser安装。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;解压DevKit后，在命令行输入以下命令来进行安装：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;d: 
cd DevKit
ruby dk.rb init 
ruby dk.rb install
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="安装python"&gt;安装Python&lt;/h3&gt;
&lt;p&gt;安装Python,也是一路next就可以，博客的代码高亮用到了Python的Pygments模块，在Python中安装第三方库需要使用easy_install，在下面地址下载跟Python相对应的安装程序安装后就可以使用easy_install了。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://pypi.python.org/pypi/setuptools"&gt;https://pypi.python.org/pypi/setuptools&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;easy_install会安装在Python安装目录的Scripts目录中，例如我的Python目录是C:\Python27，所以需要将C:\Python27\Scripts目录加入到环境变量中才能在命令提示符中使用easy_install命令。&lt;/p&gt;
&lt;p&gt;在命令提示符中输入如下命令就可以安装Pygments了。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;easy_install pygments
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="安装octopress"&gt;安装Octopress&lt;/h3&gt;
&lt;p&gt;首先在GitBash中输入如下命令将Octopress代码拉到本地，&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cd d:/GitProject
git clone git://github.com/imathis/octopress.git octopress
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后需要安装Octopress的依赖项，安装依赖项需要用到Ruby的gem，使用下面的命令可以更换gem的更新源，使用国内的淘宝镜像速度相对快点。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gem sources -a http://ruby.taobao.org/
gem sources -r http://rubygems.org/
gem sources -l
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改Octopress目录下的Gemfile文件，将第一行的&lt;a href="http://rubygems.org/"&gt;http://rubygems.org/&lt;/a&gt; 修改为&lt;a href="http://ruby.taobao.org/"&gt;http://ruby.taobao.org/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在命令提示符中进入到Octopress目录，输入下面命令进行依赖项的安装&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gem install bundler
bundle install
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;输入下面的命令来安装Octopress的默认主题&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;rake install
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;到此所有的安装工作已经结束，输入下面的命令可以在本地进行预览。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;rake preview
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;预览效果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300659290.webp" alt="27113147-1ad59a8165304434a89f6573bbc1cdb8" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="解决中文问题"&gt;解决中文问题&lt;/h2&gt;
&lt;p&gt;如果博客中包含中文，需要进行如下设置：&lt;/p&gt;
&lt;p&gt;1.在环境变量中设置下面的键值对&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;LANG=zh_CN.UTF-8
LC_ALL=zh_CN.UTF-8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2.含有中文的文件需要保存为UTF-8无BOM格式编码。&lt;/p&gt;
&lt;p&gt;3.在Ruby的安装路径找到 文件convertible.rb&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;C:\Ruby193\lib\ruby\gems\1.9.1\gems\jekyll-0.12.0\lib\jekyll\convertible.rb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将27行修改为：&lt;code&gt;self.content = File.read(File.join(base, name), :encoding =&amp;amp;gt; 'utf-8')&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="在octopress中添加文章"&gt;在Octopress中添加文章&lt;/h2&gt;
&lt;p&gt;使用下面命令可以在Octopress中添加文章&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300700883.webp" alt="27113202-1205db84b8574b35b872a518d77a6c03" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;注意，rake new_post[&amp;lsquo;my first octopress blog&amp;rsquo;]中的my first octopress blog 并不是博客标题，而是和生成的文件名以及url地址有关，该名称不支持中文。博客标题可以在生成的markdown文件中修改。生成的markdown文件在octopress/source/_posts目录中。&lt;/p&gt;
&lt;p&gt;编辑markdown文件，将标题可以修改为中文标题，还可以设置分类等信息以及编写正文部分&lt;/p&gt;</description></item><item><title>jQuery知识总结</title><link>https://fwhyy.com/2013/04/jquery-knowledge-summary/</link><pubDate>Sat, 13 Apr 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/04/jquery-knowledge-summary/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;jQuery一直都在用，但都是在用时查查手册，并没有系统的学过，最近组内做jQuery交流，花了几天时间系统了学习了下，做了个PPT，本文是根据PPT总结而来，有些地方做了些补充。希望对jQuery初学者有些帮助。&lt;/p&gt;
&lt;h2 id="jquery简介"&gt;jQuery简介&lt;/h2&gt;
&lt;h3 id="简介"&gt;简介&lt;/h3&gt;
&lt;p&gt;jQuery是一个兼容多浏览器的javascript库，核心理念是write less,do more(写的更少,做的更多)。 jQuery在2006年1月由美国人John Resig在纽约的barcamp发布，吸引了来自世界各地的众多javascript高手加入，现在由Dave Methvin率领团队进行开发。如今， jQuery已经成为最流行的javascript库，在世界前10000个访问最多的网站中，有超过55%在使用jQuery 。【摘自百度百科】&lt;/p&gt;
&lt;h3 id="下载地址"&gt;下载地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://jquery.com/"&gt;http://jquery.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="源码地址"&gt;源码地址&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/jquery/jquery"&gt;https://github.com/jquery/jquery&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;可以通过 &lt;code&gt;git clone git://github.com/jquery/jquery.git&lt;/code&gt;来获取源码。&lt;/p&gt;
&lt;h3 id="在线文档"&gt;在线文档&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.ostools.net/apidocs/apidoc?api=jquery"&gt;http://www.ostools.net/apidocs/apidoc?api=jquery &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.ostools.net/"&gt;http://www.ostools.net/&lt;/a&gt;上有各种在线工具，在此推荐下。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="使用jquery"&gt;使用jQuery&lt;/h3&gt;
&lt;p&gt;使用jQuery首先需要在页面中进行引用，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;script type=”text/javascript” src=”Scripts/jquery-1.8.1.min.js”&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用的代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$(document).ready(function () {
 $(&amp;#34;#div1&amp;#34;).html(&amp;#34;hello world&amp;#34;);
});

$(function () {
 $(&amp;#34;#btnOK&amp;#34;).bind(&amp;#34;click&amp;#34;, function () { 

 });
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码相当于window.onload，不过跟window.onload还是有一些区别，后面会以表格的形式来展现他们的区别。在jQuery中到处可以见到$符号，这是jQuery里的一种简写，$(&amp;quot;#btnOK&amp;quot;)和jQuery(&amp;quot;#btnOK&amp;quot;)是等价的。&lt;/p&gt;
&lt;h3 id="windowonload和documentready的区别"&gt;window.onload和$(document).ready()的区别&lt;/h3&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;&lt;/th&gt;
					&lt;th&gt;WINDOW.ONLOAD&lt;/th&gt;
					&lt;th&gt;$(DOCUMENT).READY()&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;执行时间&lt;/td&gt;
					&lt;td&gt;网页所有内容加载完后执行&lt;/td&gt;
					&lt;td&gt;DOM结构加载完后就执行，效率更高&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;编写个数&lt;/td&gt;
					&lt;td&gt;1个&lt;/td&gt;
					&lt;td&gt;多个，多个的执行顺序取决于函数的顺序以及引用文件的顺序&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;是否支持简写&lt;/td&gt;
					&lt;td&gt;不支持&lt;/td&gt;
					&lt;td&gt;简写形式为：$(function(){});&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="dom对象和jquery对象转换"&gt;DOM对象和jQuery对象转换&lt;/h3&gt;
&lt;p&gt;获取DOM对象代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//获取DOM对象
var div1 = document.getElementById(&amp;#34;div1&amp;#34;);

div1.innerHTML = &amp;#34;oec2003&amp;#34;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;获取jQuery对象代码如下:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//获取jQuery对象
var div1 = $(&amp;#34;#div1&amp;#34;);

div1.html(&amp;#34;oec2003&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;jQuery对象转DOM对象&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//因为ajQuery对象是一个数组对象，所以转换为DOM对象时要用索引的形式

var $div1 = $(&amp;#34;#div1&amp;#34;); //jQuery对象

var div1 = $div1[0]; //转换为了DOM对象

var div2 = $div1.get(0); //和上面一行效果一样

div1.innerHTML = &amp;#34;oec2003&amp;#34;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;DOM对象转jQuery对象&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//DOM对象转jQuery只需用$包装即可

var div1 = document.getElementById(&amp;#34;div1&amp;#34;);

var $div1 = $(div1); //转换为了jQuery对象

$div1.html(&amp;#34;oec2003&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="解决冲突"&gt;解决冲突&lt;/h3&gt;
&lt;p&gt;有时会有jQuery和其他的库或自己写的一些公共脚本文件一起使用的场景，就有可能会出现$冲突的问题，冲突的解决分两种情况：&lt;/p&gt;
&lt;p&gt;1、jQuery库在其他库之后引用，如下所示：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;script type=”text/javascript” src=”Scripts/jquery-1.8.1.min.js”&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;script type=”text/javascript” src=”Scripts/common.js”&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在common.js中有对$重新定义，代码如下：&lt;/p&gt;</description></item><item><title>IIS7上传出现乱码问题解决</title><link>https://fwhyy.com/2013/03/iis7-upload-issue/</link><pubDate>Fri, 22 Mar 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/03/iis7-upload-issue/</guid><description>&lt;p&gt;最近查一个bug，客户那边将上传超过30兆的文件时，上传页面出现乱码，如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300703232.webp" alt="1" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;系统默认是只能上传10兆以内的文件，客户自己修改了webconfig文件后发现此问题。&lt;/p&gt;
&lt;p&gt;通过Fiddler2跟踪页面得出乱码内容为“您要找的资源已被删除、已更名或暂时不可用”，然后通过Google得出结论如下：&lt;/p&gt;
&lt;p&gt;在IIS7中出了修改webconfig的配置外还需要修改&lt;code&gt;C:\Windows\System32\inetsrv\config\schema \IIS_schema.xml&lt;/code&gt;文件，该文件中的默认设置为30兆，根据需要修改默认值大小即可：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300703951.webp" alt="2" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>SQL查询-将列转换成字符串（for xml path）</title><link>https://fwhyy.com/2013/03/sql-query-for-xml-path/</link><pubDate>Tue, 19 Mar 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/03/sql-query-for-xml-path/</guid><description>&lt;h2 id="背景"&gt;背景&lt;/h2&gt;
&lt;p&gt;最近做一报表，因为查询的SQL很长很复杂，导致直接查询出现异常，后来想到将大量重复的只是查询条件不同的子查询放到函数中去做，无奈需要的参数不能传进函数中，因为参数格式类似如：&amp;lsquo;ProjGUID1&amp;rsquo;,&amp;lsquo;ProjGUID2&amp;rsquo; 这样，这是报表工具生成的，无法修改。现在就要想办法让参数能传进函数中或是换用其他的方式。&lt;/p&gt;
&lt;h2 id="思路"&gt;思路&lt;/h2&gt;
&lt;p&gt;1、首先想到的是用存储过程，但是在报表工具中调试不通，存储过程不能得到有效的执行，可能是根本就不支持存储过程；&lt;/p&gt;
&lt;p&gt;2、将参数作为in的条件，查询出符合条件的GUID，返回的是一个表，然后循环表的行记录，拼接GUID传入函数，但是报表工具中的SQL不支持定义变量和临时表，此方法也行不通；&lt;/p&gt;
&lt;p&gt;3、利用SQL语句的For Xml 将GUID查询成一个XML结构的字符串，但传入函数中后解析该XML需要用到系统存储过程sp_xml_preparedocument ，函数中并不支持调用存储过程，此路也不通。关于SQL中解析XML可以参见我之前的博文《&lt;a href="http://blog.fwhyy.com/2011/07/use-sp_xml_preparedocument-processing-xml-documents/"&gt;使用sp_xml_preparedocument处理XML文档&lt;/a&gt;》。&lt;/p&gt;
&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;p&gt;上面说到了SQL的For Xml可以将查询的列转换成XML结构的字符串，还有一种方法可以将查询的字段转换成以特定符号隔开的字符串，那就是For Xml Path：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT TOP 2 CONVERT(VARCHAR(40),ProjGUID)+&amp;#39;,&amp;#39; FROM p_Project FOR XML PATH(&amp;#39;&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的语句得到的结果如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;BAA95B67-FC41-4A78-AF1C-014BBE0AC368,37641496-23AA-46CB-9817-027AA120F5C6,
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;至此问题解决，这样的字符串是可以传进函数的，只需将最后的逗号去掉即可。&lt;/p&gt;</description></item><item><title>读《打造FaceBook》</title><link>https://fwhyy.com/2013/02/read-facebook/</link><pubDate>Wed, 27 Feb 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/02/read-facebook/</guid><description>&lt;p&gt;这本书是微博上的一位朋友推荐的，当天就下单购买了，花了几个晚上看完，全书主要讲作者在FaceBook的从业经历以及离职后对天使投资和创业的一些想法。下面是我看完本书后的一些感想。&lt;/p&gt;
&lt;h2 id="团队合作"&gt;团队合作&lt;/h2&gt;
&lt;p&gt;任何的团队都需要团队合作，其重要性毋庸置疑。我们在面试的时候经常被面试官考核的一个因素就是团队合作精神。我所经历的公司中虽然也很注重团队合作，但更多的是在一个团队中、一个开发小组中，而在脸书中将这个高度上升到了整个公司，所有人的目标都是整个公司的发展，一个团队中的老大如果觉得团队中一个牛人在另一个团队中会对公司更有帮助的话会不吝让那位牛人去另一个团队工作，所有人目标一致，劲往一处使，公司才有发展。记得我曾就职过的一家公司，项目组中成员之间够通非常好，成员和PM之间也保持者非常好的关系，但由于公司的一些绩效制度导致需求分析、开发和测试之间经常会为了一个Bug的责任人问题而争论不休，其是Bug早已修复，造成很大的内耗并且成员的情绪也会受到影响，所以说团队合作除了人员的性格和沟通能力外还需要公司有个好的制度支持。&lt;/p&gt;
&lt;h2 id="黑客之道"&gt;黑客之道&lt;/h2&gt;
&lt;p&gt;黑客文化其实是对技术的一种追求，在脸书有一个称为黑客马拉松的活动，每三个月举行一次，在活动中所有人都放下手头的工作，根据自己的兴趣进行开发，很多创性的项目就是这样诞生的。当然这种类似的活动在国内公司中是很难举行的，大概有下面两个原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为了项目进度，老板们、领导们恨不得让员工一分钟当两分钟用，怎么可能利用上班时间让员工去做让他们看来对项目毫无意义的事；&lt;/li&gt;
&lt;li&gt;脸书的招人很严格，他们有一个理念是拒绝和庸人在一起工作，所招之人都是世界上顶级工程师，而国内大部分公司的人员在水平上还是存在差距的，即便遇到一些开明的老板能举行这样的活动，其效果也可能没那么好。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="工具文化"&gt;工具文化&lt;/h2&gt;
&lt;p&gt;俗话说，工欲善其事，必先利其器，人类之所以比动物高级就是因为人会使用工具，好的工具会大大提高做事效率，脸书将工具文化做到极致，他们有专门的工具小组，工具小组中是公司中最好的工程师。这点不管是公司和个人都值得借鉴，我现在所在公司在工具这方面就做的很好，也有专门的工具小组，推出的很多工具给工作带来很多便利。去年下半年我写了一个小工具来给工作中重复切耗时的一些步骤提高方便并最终推广在部门内使用。在工作中要经常思考总结，找出重复的有共性的地方，看能不能工具化，让我们能有更多的时间去做更有意义的事情。&lt;/p&gt;
&lt;h2 id="职业发展"&gt;职业发展&lt;/h2&gt;
&lt;p&gt;作为一个技术人，职业的发展无非就两条路，管理和技术大牛，在国内的公司中很多人都有做管理的想法，即便是非常热爱技术的开发人员，因为做管理意味着更高的地位和更高的薪水，这是的很多热衷于技术的人会背弃自己的初衷，为生活所迫做着自己并不怎么喜欢的事情。在脸书管理和技术只是角色的不同，地位没有谁高谁低，喜欢技术可以成为技术大牛，薪水可能比管理着还高。记得前些年经常可以在网上看见对技术人员年龄以及未来发展的讨论，归根结底还是国内大环境造成的，我是一个很喜欢技术的人，希望有一天在国内软件公司中能出现更多的＂大龄＂一线开发人员。&lt;/p&gt;
&lt;h2 id="知识储备"&gt;知识储备&lt;/h2&gt;
&lt;p&gt;作为一个技术人员如果不持续地学习充电就会被淘汰，学习有两种，一种是学习自己感兴趣的技术知识，一种是学习和工作相关的知识。很多公司都会鼓励员工学习和工作相关的技能，而我认为工作需要的技能是基本的，除此之外还应该学习自己感兴趣的，前沿的的技术，说到这就不得不提英语了，即便不是在外企，至少也要做到阅读上没有障碍，英文能力直接关系到我们对新技术的了解和获取。记得我之前的一个领导在一次会上说你们在业余时间要好好学习业务、性能优化等和工作相关的知识，像英语之类没用的就没必要学了，对此我持保留意见。总之我们要尽量开阔自己的眼界，不断充电学习。王淮在书中提到他们会利用现成的开源框架去开发内部的工具，如果你没有足够的知识量你就不会之道有什么开源框架可以用，进而去自己动手开发，这样就导致重复造轮子。&lt;/p&gt;
&lt;p&gt;书中还有对投资和创业的一些见解，因为我目前还涉及不到，在此不做评论。由于中西方文化差异较大，书中可以借鉴学习的我们可以吸收，不能借鉴的也可以丰富我们知识，成为日后的谈资。&lt;/p&gt;</description></item><item><title>2012 年终总结</title><link>https://fwhyy.com/2013/01/2012-year-summary/</link><pubDate>Wed, 16 Jan 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/01/2012-year-summary/</guid><description>&lt;p&gt;在我的&lt;a href="http://blog.fwhyy.com/2012/01/summary-in-2011/"&gt;2011年总结&lt;/a&gt;是以年度记事作为开头，2012虽然特别，但对我来说还算是比较平淡的一年，并没有很多事情发生，所以2012年的总结就以工作和生活两个方面来说。&lt;/p&gt;</description></item><item><title>WordPress安装主题出错解决</title><link>https://fwhyy.com/2013/01/wordpress-install-theme-error/</link><pubDate>Mon, 07 Jan 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/01/wordpress-install-theme-error/</guid><description>&lt;p&gt;将空间转移到美国空间后发现在WordPress后台安装主题时需要输入FTP地址和账号密码，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290647006.webp" alt="image-20220129064719906" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;输入地址和账号密码后，点击继续报如下错误：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-php" data-lang="php"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;PHP&lt;/span&gt; &lt;span class="nx"&gt;Warning&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;function.touch&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;function&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;touch&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Utime&lt;/span&gt; &lt;span class="nx"&gt;failed&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;No&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;H&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;\root\home\oec2003&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mo"&gt;003&lt;/span&gt;&lt;span class="nx"&gt;\www\site1\fwblog\wp&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;admin\includes\file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;php&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;179&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;解决方法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 确保WordPress的上传目录有可写权限&lt;/li&gt;
&lt;li&gt;2 在wp-config.php文件的底部添加如下代码即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;define(&amp;#39;WP_TEMP_DIR&amp;#39;,ABSPATH.&amp;#39;wp-content/uploads/&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>通过修改数据库的方式禁用WordPress插件</title><link>https://fwhyy.com/2013/01/unenabled-wordpress-plug-in-for-update-database/</link><pubDate>Fri, 04 Jan 2013 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2013/01/unenabled-wordpress-plug-in-for-update-database/</guid><description>&lt;p&gt;最近个人博客的空间到期了，之前的是香港的空间，这次看见美国空间做活动感觉比较划算就换了美国空间，需要将原空间中的程序源文件备份下来，上传到新的美国空间中，这么一折腾折腾出问题了。&lt;/p&gt;
&lt;p&gt;为了防止垃圾评论，我在博客中安装了一个验证码的插件，这次换空间后，发现插件不能使用了（出现的图片什么都不显示），导致后台管理登陆不进去，Google之，发现可以通过修改数据库的方式来禁用插件，在wp_options表的option_name列下，找到active_plugins行 ，查询出该行的option_value值为&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;a:12:{i:0;s:19:”akismet/akismet.php”;i:1;s:23:”antivirus/antivirus.php”;i:2;s:33:”configure-smtp/configure-smtp.php”;i:3;s:35:”delete-revision/delete-revision.php”;i:4;s:36:”google-sitemap-generator/sitemap.php”;i:5;s:43:”guestbook-generator/guestbook_generator.php”;i:6;s:39:”si-captcha-for-wordpress/si-captcha.php”;i:7;s:29:”wp-db-backup/wp-db-backup.php”;i:8;s:23:”wp-kit-cn/wp-kit-cn.php”;i:9;s:27:”wp-pagenavi/wp-pagenavi.php”;i:10;s:33:”wp-security-scan/securityscan.php”;i:11;s:35:”wp-utf8-excerpt/wp-utf8-excerpt.php”;}&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;上面值中的i:6;s:39:”si-captcha-for-wordpress/si-captcha.php”; 为验证码插件的启用代码，将其删除后保存即可。&lt;/p&gt;
&lt;p&gt;验证码插件禁用了，登陆后却报错了，貌似是什么方法找不到了，因为不怎么熟PHP，就不纠结了，直接按之前的一篇博文《&lt;a href="http://blog.fwhyy.com/2012/04/wordpress-upgrade-is-very-simple/"&gt;WordPress升级其实很简单&lt;/a&gt;》中的方法将WordPress升级，问题解决。&lt;/p&gt;</description></item><item><title>在Asp.Net中使用jQueryEasyUI</title><link>https://fwhyy.com/2012/11/using-jqueryeasyui-in-aspnet/</link><pubDate>Sun, 25 Nov 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/11/using-jqueryeasyui-in-aspnet/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;最近做一个小工具，列表显示页面准备使用jQuery的UI框架，因为之前知道有jQWidgets这个框架,所以直接就下载下来使用了,&lt;a href="http://www.jqwidgets.com/"&gt;jQWidgets&lt;/a&gt;的功能很强大,Demo和文档也非常详细,但使用后发现有几个问题就果断放弃了使用jQWidgets:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面加载速度比较慢&lt;/li&gt;
&lt;li&gt;当列表字段过多出现横向滚动条时,拖动滚动条非常卡(在IE下都很卡,Chrome好点)&lt;/li&gt;
&lt;li&gt;分页取数稍显麻烦,也可能是我没研究透。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;经过一番比较选择了&lt;a href="http://www.jeasyui.com/"&gt;jQueryEasUI&lt;/a&gt;，目前最新版本为1.3.1：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.jeasyui.com/download/index.php"&gt;官方下载&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jeasyui.com/demo/main/index.php"&gt;官方演示&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.jeasyui.com/documentation/index.php"&gt;官方文档&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实是用类似的框架，看看官网的文档也就OK了，本文是我最近是用jQueryEasyUI的一个总结，也可以让初使用jQueryEasyUI的朋友少走弯路。&lt;/p&gt;
&lt;h2 id="下载引用"&gt;下载引用&lt;/h2&gt;
&lt;p&gt;下载后解压的文件目录如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290653234.webp" alt="2012-11-22_212942" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;demo：JQueryEasyUI的一些示例页面，在项目使用可以将该目录删除&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;locale：该目录中是一些本地化文件，用来支持不同的语言，如中文可以引用其中的easyui-lang-zh_CN.js&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;plugins和src：这两个目录中是支持JQueryEasyUI各种功能的js文件&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;themes：主题目录，目录中有三种主题，default、gray和metro，另外还有一个icons目录和icon.css，在页面使用引用icon.css即可。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用jQueryEasyUI需要引用四个文件，两个css和两个js文件：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;link rel=&amp;#34;stylesheet&amp;#34; type=&amp;#34;text/css&amp;#34; href=&amp;#34;../Scripts/jqueryeasyui/themes/gray/easyui.css&amp;#34; /&amp;gt;
&amp;lt;link rel=&amp;#34;stylesheet&amp;#34; type=&amp;#34;text/css&amp;#34; href=&amp;#34;../Scripts/jqueryeasyui/themes/icon.css&amp;#34; /&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;../Scripts/jqueryeasyui/jquery-1.8.0.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;../Scripts/jqueryeasyui/jquery.easyui.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果需要使用本地化 还需要引用：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;../Scripts/jqueryeasyui/locale/easyui-lang-zh_CN.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="jqueryeasyui-grid的分页"&gt;jQueryEasyUI Grid的分页&lt;/h2&gt;
&lt;p&gt;根据官网的文档可以很容易的构建Grid，期初我没有引用本地化文件easyui-lang-zh_CN.js，列表的分页栏显示出来是英文的，在网上查阅后得知可以用代码的方式重新构建分页栏：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//设置分页控件 var p = $(&amp;#39;#dg&amp;#39;).datagrid(&amp;#39;getPager&amp;#39;);
$(p).pagination({
 pageSize: 10, //每页显示的记录条数，默认为10 
 pageList: [10, 20, 30, 40, 50], //可以设置每页记录条数的列表 beforePageText: &amp;#39;第&amp;#39;, //页数文本框前显示的汉字 
 afterPageText: &amp;#39;页 共 {pages} 页&amp;#39;,
 displayMsg: &amp;#39;当前显示 {from} - {to} 条记录 共 {total} 条记录&amp;#39;
 /*onBeforeRefresh:function(){ $(this).pagination(&amp;#39;loading&amp;#39;); 
 alert(&amp;#39;before refresh&amp;#39;); $(this).pagination(&amp;#39;loaded&amp;#39;); }*/
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;后来发现只需要引用本地化文件easyui-lang-zh_CN.js后分页栏就自动显示为中文了。引用本地化文件还可以解决日历控件格式的问题，所以如果是做中文系统建议还是在页面中引用本地化文件。&lt;/p&gt;
&lt;h2 id="jqueryeasyui控件的取值"&gt;jQueryEasyUI控件的取值&lt;/h2&gt;
&lt;p&gt;使用JQuery取控件的值很简单，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$(&amp;#34;#CstName&amp;#34;).val();
$(&amp;#34;#TaskNo&amp;#34;).val(),
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果要使用jQueryEasyUI的日历控件、下拉控件或其他的一些控件，给普通的input、select控件添加一个class即可：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;input id=&amp;#34;FeedBackDate&amp;#34; name=&amp;#34;FeedBackDate&amp;#34; class=&amp;#34;easyui-datebox&amp;#34; maxlength=&amp;#34;10&amp;#34;
 style=&amp;#34;width: 150px;&amp;#34; /&amp;gt;
&amp;lt;select id=&amp;#34;IsKfCl&amp;#34; class=&amp;#34;easyui-combobox&amp;#34; name=&amp;#34;IsKfCl&amp;#34; style=&amp;#34;width:150px;&amp;#34;&amp;gt; 
 &amp;lt;option value=&amp;#34;&amp;#34;&amp;gt;&amp;lt;/option&amp;gt; 
 &amp;lt;option value=&amp;#34;是&amp;#34;&amp;gt;是&amp;lt;/option&amp;gt; 
 &amp;lt;option value=&amp;#34;否&amp;#34;&amp;gt;否&amp;lt;/option&amp;gt; 
&amp;lt;/select&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在取这些控件的值需要使用下面的方法：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$(&amp;#34;#FeedBackDate&amp;#34;).datebox(&amp;#34;getValue&amp;#34;);
$(&amp;#34;#IsKfCl&amp;#34;).combobox(&amp;#34;getValue&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="grid-toolbar的两种方式"&gt;Grid ToolBar的两种方式&lt;/h2&gt;
&lt;p&gt;通常在Grid列表控件的上方会添加一些按钮如：新增、编辑、删除等，如下面效果：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290653327.webp" alt="2012-11-25_144045_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在jQueryEasyUI中可以使用ToolBar来实现，ToolBar可以在DataGrid初始化时定义，如下：&lt;/p&gt;</description></item><item><title>在VS2010中使用Git【图文】</title><link>https://fwhyy.com/2012/11/using-git-in-vs2010/</link><pubDate>Tue, 13 Nov 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/11/using-git-in-vs2010/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;在之前的一片博客《&lt;a href="http://blog.fwhyy.com/2012/02/use-git-manage-github-project-on-windows/"&gt;Windows 下使用Git管理Github项目&lt;/a&gt;》中简单介绍了在Windows环境中使用Git管理Github项目，但是是使用命令行来进行操作的，本文将简单介绍下在VS2010中怎样使用Git，并来管理Github上的项目。&lt;/p&gt;
&lt;h2 id="准备"&gt;准备&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;安装Git命令行，下载地址：&lt;a href="http://code.google.com/p/msysgit/downloads/list"&gt;http://code.google.com/p/msysgit/downloads/list&lt;/a&gt;，其实如果没有安装Git命令行，在安装Git Extensions时会有两个勾选项，其中一个就是Git命令行（msysGit ）&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装Git Extensions，下载地址：&lt;a href="http://sourceforge.net/projects/gitextensions/"&gt;http://sourceforge.net/projects/gitextensions/&lt;/a&gt; ，安装过程中会有两个勾选项msysGit 和 KDiff3，如果已经安装了Git命令行可以不勾选msysGit，KDiff3 是一个文件对比工具，在分支合并时会用到，建议勾选，安装完后也可以设置成其他的对比工具，比如：BCompare&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;安装VS的插件Git Source Control Provider，在VS2010的扩展管理中可以找到&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;在VS中设置源代码控制位Git Source Control Provider。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="创建项目并添加到git"&gt;创建项目并添加到Git&lt;/h2&gt;
&lt;p&gt;使用VS2010创建一个名为GitHelloWorld的项目，在解决方案上点击右键，点击“Git –New Repository”：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290706491.webp" alt="20130513_210905" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这时看项目所在的目录，会添加一个名为.git的隐藏目录和一个名为.gitignore的文件，除此外不会有任何多余的文件，相比VSS和SVN等源码管理工具要“干净”很多：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290706471.webp" alt="20130513_212332" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这时会发现解决方案中的文件上并没有出现源码管理的图标，在解决方案上右击，点击Git菜单中的Refresh就OK了：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290706765.webp" alt="20130513_214629" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201290706673.webp" alt="20130513_215023_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上面右图中的文件前的图标为加号，表示文件还没有被添加到版本库中，可以使用Git菜单中的Commit来进行提交：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290706012.webp" alt="20130513_221212" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;现在就可以对代码进行编辑了，当我们在文件中添加自己的代码后，文件的状态并不会改变，当保存文件后，文件就显示为签出状态。通常第一次通过Commit将代码加入到源码库后，建议重启VS，否则有时文件的签入签出状态得不到及时更新，如果发现状态没有及时更新也可以用Git菜单下的Refresh来进行更新。&lt;/p&gt;
&lt;p&gt;Git菜单上的Browse命令可以查看各个提交版本的信息：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290707331.webp" alt="20130513_230857" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;或是在解决方案上右击，选择“Git -History”也可以查看版本信息，是在VS中的标签页中以图形化展示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290707672.webp" alt="20130514_064929" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;通过上面的介绍我们可以简单的使用Git来管理代码了，下面接着来说怎样将代码推送到Github中&lt;/p&gt;
&lt;p&gt;首先需要在Github中创建一个新的repository，命名为GitHelloWorld，创建完成后如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290707307.webp" alt="20130514_065931" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图中红色框中的就是新建的GitHelloWorld的地址，通过这个地址我们就可以将本地代码推送到GitHub中，在VS中点击Git菜单下的Push命令：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290707811.webp" alt="20130514_073305" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;如果推送成功会看到如下提示框：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290707684.webp" alt="20130514_073354_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这时刷新GitHub中的页面可以看到项目已经添加到GitHub中了：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290708761.webp" alt="20130514_194240_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;到这儿就介绍完怎样在VS中将代码放入到Git库，并将代码推送到GitHub。下面介绍下已知一个GitHub的源码地址，怎样把代码拉到本地，比如刚刚推送到GitHub中的GtiHelloWorld的地址是&lt;code&gt;git://github.com/oec2003/GitHelloWorld.git&lt;/code&gt;，现在使用这个地址将代码拉到本地。&lt;/p&gt;
&lt;h2 id="从github拉代码到本地"&gt;从GitHub拉代码到本地&lt;/h2&gt;
&lt;p&gt;打开VS2010，点击Git菜单的Clone repository：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290708283.webp" alt="20130515_212658_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在弹出的克隆对话框中输入相应的信息：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290708972.webp" alt="20130515_214044" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“克隆”按钮，如果成功克隆的话会弹出如下信息框：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290708621.webp" alt="20130515_214127_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;就这么简单，现在代码已经被拉到E盘的GitHelloWorld目录中了。还有一种方法就是直接打开Git Extensions，点击“克隆档案库”可以达到同样的效果。现在就可以使用VS2010开始我们的Git之旅了，关于分支、标签等深入一点的内容在后面的博文中会介绍。&lt;/p&gt;</description></item><item><title>怎样提高开发效率</title><link>https://fwhyy.com/2012/10/how-to-improve-the-efficiency-of-development/</link><pubDate>Sun, 21 Oct 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/10/how-to-improve-the-efficiency-of-development/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;给你一个任务,限定5天内完成,如果你实际用了6天,可以说是开发效率不高,或者同样的一个任务,你花了6天,而你的同事却只用了4天,也可以说是你的开发效率不高,影响开发效率的因素有很多,下面就我个人的理解来谈谈怎样提高开发效率.&lt;/p&gt;
&lt;h2 id="工具"&gt;工具&lt;/h2&gt;
&lt;p&gt;俗话说，工欲善其事必先利其器，使用得心应手的工具必然会提高开发效率，做微软平台开发的肯定离不开VS，就VS本身来说，除了常用功能外一些常用的快捷键一定要能熟练运用，例如下面是我认为比较有用的几个快捷键：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注释： Ctrl + K + C&lt;/li&gt;
&lt;li&gt;取消注释： Ctrl + K + U&lt;/li&gt;
&lt;li&gt;全屏： Shift + Alt + Ente&lt;/li&gt;
&lt;li&gt;设置标签： CTRL + K, CTRL + K&lt;/li&gt;
&lt;li&gt;下一个、上一个标签： CTRL + K, CTRL + P 、CTRL + K, CTRL + P&lt;/li&gt;
&lt;li&gt;列出成员： Ctrl + J&lt;/li&gt;
&lt;li&gt;显示参数信息： Ctrl + Shift + Space&lt;/li&gt;
&lt;li&gt;转到定义后返回： Ctrl + –&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;熟练使用快捷键对于代码编写的速率和跟踪代码的速率会有大大的提高。&lt;/p&gt;
&lt;p&gt;有时候开发工具自身的功能受到了限制，这是就需要使用插件来丰富功能，这里推荐两款插件，VS中的ReSharper和SqlServer中的SQL prompt5，ReSharper是功能很强大的一个VS插件，但会拖慢VS的速度，就看怎么去权衡了，我在之前的博文《&lt;a href="http://blog.fwhyy.com/2009/10/powerful-vs-plug-in-resharper/"&gt;强大的VS插件—Resharper&lt;/a&gt;》做过简单介绍。SQL prompt5是SqlServer的一个插件，功能也非常强大，有很强的智能提示功能，所提供的SQL Search功能可以对数据库对象进行快速查找，还提供代码片段功能，在我之前的博文《&lt;a href="http://blog.fwhyy.com/2012/10/using-sql-prompt5/"&gt;SqlServer开发利器—SQL Prompt5&lt;/a&gt;》中也做过介绍。&lt;/p&gt;
&lt;p&gt;除了我们每天都离不开的VS和SqlServer之外还有一些辅助的开发工具也可以来帮助我们来提高效率，我经常使用的有以下几种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;SqlDbx：很小巧的一款数据库管理工具，但功能非常强大，支持多种数据库，经常使用他的智能提示和生成脚本等功能，但也有缺点，对中文支持的不是很好；&lt;/li&gt;
&lt;li&gt;Aptana：该工具可以说是做Web开发的利器了，我有时写JS会用到该工具，有一个亮点之处是智能提示能够显示不同浏览器是否支持；&lt;/li&gt;
&lt;li&gt;Free Javascript Editor：可以很方便的写一些简单的HTML和JS代码并运行，可以直接选择JS的代码片段进行执行，对JS的调试也很方便。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还有一些其他的工具也非常有用，比如我在平时的工作中会经常用到Total Commander和Everything：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Total Commander：资源管理器的代替工具，支持多标签，可以很方便的对文件进行操作；&lt;/li&gt;
&lt;li&gt;Everything：一款搜索工具，速度奇快，以前也做过介绍《软件推荐：磁盘搜索软件Everything》。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="代码沉淀"&gt;代码沉淀&lt;/h2&gt;
&lt;p&gt;有点规模的软件公司都会有自己的开发框架，这些框架都是多少年积累的产物，目的就是为了提高开发效率，作为一个开发人员平时对于一些常用的代码也应该有自己的沉淀，不光自己沉淀，在组内也应互相分享，记录这些沉淀的代码就可以根据自己的喜好了，记事本、Word、Excel、OneNote等都可以。沉淀的代码还可以使用VS的代码片段功能来进行管理，VS2010中对代码片段支持的很好，上面提到的SqlServer的插件SQL Prompt5也提供了数据库中的代码片段功能。&lt;/p&gt;
&lt;p&gt;VS中给我们提供了很多现成的代码片段，要使用自定义的代码片段最方便的就是使用代码片段制作工具，工具点击&lt;a href="http://snippeteditor.codeplex.com/"&gt;此处&lt;/a&gt;下载，当然也可以自己创建代码片段文件，然后在VS中导入即可，代码片段文件其实就是一个xml格式的文件，后缀为snippet。&lt;/p&gt;
&lt;p&gt;代码质量&lt;/p&gt;
&lt;p&gt;代码质量好了，产生的bug就少，和测试的交互也就少了，也就不会因为前面产生的bug而影响后面的进度，效率自然就高了。代码质量可以分三个方面来看：&lt;/p&gt;
&lt;p&gt;1 代码出错少，能够正常的运行；&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主动学习，提升自我的编程技能；&lt;/li&gt;
&lt;li&gt;勤思考，对干过的错要经常总结，一些规范性的原则要牢记，这些常常会出现一些低级错误；&lt;/li&gt;
&lt;li&gt;一个任务做完后需要进行充分的自测。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2 代码的运行效率高，在大数据、高并发的时候能够高效运行；&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;高性能的开发得从点滴做起，不放过每一个细节，可能一个小的细节点就是一个性能的瓶颈；&lt;/li&gt;
&lt;li&gt;要有重构代码的习惯，好的代码是重构出来的，高性能的代码也是重构出来的；&lt;/li&gt;
&lt;li&gt;多学习一些原理性的知识，不光要知其然还是知其所以然，基础扎实了，一些性能的问题就知道怎么去优化了；&lt;/li&gt;
&lt;li&gt;之前翻译过几篇关于C#代码简化的博文，参见《&lt;a href="http://blog.fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-1/"&gt;C#/Net代码精简优化技巧（1）&lt;/a&gt;》、《&lt;a href="http://blog.fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-2/"&gt;C#/Net代码精简优化技巧（2）&lt;/a&gt;》、《&lt;a href="http://blog.fwhyy.com/2010/11/csharp-net-code-concise-optimization-techniques-c/"&gt;C#/Net代码精简优化技巧（3）&lt;/a&gt;》&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3 代码最后的运行结果要和客户的要求一致；&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;做需求之前把自己的理解跟需求分析进行沟通看是否能达成一致，如果是直接和客户进行沟通可以先做出小Demo，然后给客户演示，根据反馈不断改进；&lt;/li&gt;
&lt;li&gt;在做的过程中如果遇到有疑问的地方一定要和需求或客户进行沟通，不要根据自己的想法想当然的去进行代码编写；&lt;/li&gt;
&lt;li&gt;必要的时候可以引导客户，我们的主要目的能以最有效的方式帮客户解决问题，不能盲目的按照客户的要求来，有时客户说需要一双雨鞋，可能一把伞就可以解决问题。同样对于需求分析写的文档，开发也需要有质疑的精神。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="业务知识学习"&gt;业务知识学习&lt;/h2&gt;
&lt;p&gt;做任何的系统都避免不了有业务背景，熟练的了解业务知识可以使我们更清楚的知道我们是在做什么。很多的开发人员可能只喜欢钻研技术，对业务往往没什么兴趣，代码写完了，可能还不知道做出的模块时做什么用的，这样写出来的代码的质量就可想而知了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学习业务可能很枯燥，但却是一劳永逸的事情，所以不管是否有兴趣，还是应该硬着头皮啃下来；&lt;/li&gt;
&lt;li&gt;小组内可以成立兴趣小组，探讨的方式来进行学习，互相分享各自的学习内容，关键是组内的氛围要搞起来；&lt;/li&gt;
&lt;li&gt;如果是直接跟客户沟通，需要用客户能听懂的语言，比如图文配合或是一些小Demo，否则当开发术语碰上领域术语就可能都是在对牛弹琴了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总之，作为一名开发人员，要时刻想着怎样来提高开发效率，开发效率的提高是你在工作中一个良性循环的开始。如果您有好的方法和建议，欢迎一起分享。&lt;/p&gt;</description></item><item><title>VS2010和VS2008使用不同编译方式在64位机器生成注册表对比</title><link>https://fwhyy.com/2012/10/gen-reg-in-vs2010-and-vs2008/</link><pubDate>Sun, 14 Oct 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/10/gen-reg-in-vs2010-and-vs2008/</guid><description>&lt;p&gt;最近写一个小工具用到了使用C#来进行注册表的操作，使用C#来进行注册表的操作需要引入命名空间Microsoft.Win32，关于操作注册表的帮助类可以参考RegHelper.cs。下面分别使用VS2010和VS2008使用Any CPU、X64、X86和Itanium进行编译，运行在32位机器和64位机器进行对比。看下面一段代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;string subkey = @&amp;#34;software\FW\UserInfo&amp;#34;;
RegHelper reg = new RegHelper(subkey, RegDomain.LocalMachine);
reg.CreateSubKey(subkey);
Console.ReadLine();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面代码的本意是在注册表中创建&lt;code&gt;HKEY_LOCAL_MACHINE\SOFTWARE\FW\UserInfo&lt;/code&gt; 节点，在32位机器中没有什么问题，可以正常的生产节点，但在64位机器上，不同的VS版本，使用不同的编译模式，会产生不一样的结果。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300649603.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>C# &amp; .NET 1.0-4.0</title><link>https://fwhyy.com/2012/09/c-net-1-0-4-0/</link><pubDate>Sun, 02 Sep 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/09/c-net-1-0-4-0/</guid><description>&lt;p&gt;学习和使用.NET平台已有六七个年头了，05年开始学习.NET的时候，当时网上的资源不像现在这样丰富，所以去电脑城买了张盗版的VS2005的光盘，安装时才发现是VS2003，当时有一种被坑的感觉，但也正是如此，让我有了一个完整的.NET的学习生涯。&lt;/p&gt;
&lt;p&gt;从我从业的经历来看VS2003和VS2008是使用的比较多的，一些历史遗留的老项目由种种原因没有升级，依然在使用VS2003。我现在所在的公司也只使用VS2003和VS2008这两种开发工具，尽管TFS已经是2010了。很多时候公司觉得够用也就不去升级开发工具了。从1.0到4.0的变化主要体现在DotNet平台、语言和开发工具这三个方面。本文只是概括性的讲述在每个版本里都有些什么新的特性。先看下面的一张表格，描述的不同版本的出生年份、对应的VS版本和CLR的版本。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290756052.webp" alt="2012-07-04_230408" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图中需要注意的一点是：2.0 3.0 3.5的CLR版本都是2.0。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;在1.1版本中，从语言的角度就是基本的面向对象的语法，可以说任何一般C#语言的书籍都包含了C#1的所有内容。工具方面VS2003已经很强大了，即便是到了现在的VS2012，我们80%时候用到的也只不过是20%的功能。&lt;/p&gt;
&lt;p&gt;在VS2003中创建ASP.NET项目默认是跟IIS相关联的，从VSS中拉VS2003的代码时需要先在IIS中创建好站点，端口要和VSS中代码的相对应，但有时会出现很多问题。我一般的做法是将代码拉到本地后，修改解决方案文件中的路径为本地路径，然后修改项目文件中的ProjectType为Local，默认是Web，就可以很顺利打开项目了。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;2.0中对应VS2005我用的也不多，因为很快就被VS2008替代了，不过在语言方面却带来了很多新的东西。&lt;/p&gt;
&lt;p&gt;★C#2中最重要的一个特性应该就是泛型。泛型的用处就是在一些场景下可以减少强制转换来提高性能。在C#1中就有很多的强制转换，特别是对一些集合进行遍历时，如ArrayList、HashTable，因为他们是为不同数据类型设计的集合，所以他们中键和值的类型都是object，这就意味着会平凡发生装箱拆箱的才做。C#2中有了泛型，所以我们可以使用List&lt;T&gt;、Dictionary&amp;lt;Tkey,TValue&amp;gt; 。泛型能够带来很好的编译时类型检查，也不会有装箱拆箱的才做，因为类型是在使用泛型的时候就已经指定了。&lt;/p&gt;
&lt;p&gt;DotNet已经通过了很多的泛型类型供我们使用，如上面提到的List&lt;T&gt;,Dictionary&amp;lt;Tkey,TValue&amp;gt;,我们也可以自己来创建泛型类型(类、接口、委托、结构)或是方法。在定义泛型类型或时可以通过定义泛型约束来对泛型参数进行限制，更好的使用编译时检查。泛型约束是通过关键字where来实现的，C#2中的泛型约束有4种：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;引用类型约束：确保类型实参是引用类型，使用where T:class来表示；&lt;/li&gt;
&lt;li&gt;值类型约束：确保类型实参是值类型，使用where T:truct来表示；&lt;/li&gt;
&lt;li&gt;构造函数类型约束，使用where T:new()来表示；&lt;/li&gt;
&lt;li&gt;转换类型约束：约束类型实参是另外的一种类型，例如：where T:IDisposable 。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;★C#2提供了分部类（Partil）。分部类可以允许我们在多个文件中为一个类型编写代码，在Asp.Net2.0中用的极为广泛。新建一个Aspx页面，页面的CodeBehind和页面中的控件的定义就是通过分部类来实现的。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public partial class _Default : System.Web.UI.Page 
public partial class _Default 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;分布类使用关键字partial来定义，当一个类中的代码非常多时，可以使用分部类来进行拆分，这对代码的阅读很有好处，而且不会影响调用。&lt;/p&gt;
&lt;p&gt;★C#2中增加了静态类，静态类中的公用方法必须也是静态的，可以由类名直接调用，不需要实例化，比较适用于编写一些工具类。如System.Math类就是静态类。工具类有一些特点，如：所有成员都是静态的、不需要被继承、不需要进行实例化。在C#1中我们可以通过如下代码来实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//声明为密封类防止被继承 
public sealed class StringHelper
{
 //添加私有无参构造函ˉ数防止被实例化，如果不添加私有构造函数 //会自动生成共有无参构造函数 
 private StringHelper(){};
 public static int StringToInt32(string input)
 {
 int result=0;
 Int32.TryParse(input, out result);
 return result;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;C#2中可以使用静态类来实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public static class StringHelper
{
 public static int StringToInt32(string input)
 {
 int result=0;
 Int32.TryParse(input, out result);
 return result;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;★在C#1中声明属性，属性中的get和set的访问级别是和属性一致，要么都是public要么都是private，如果要实现get和set有不同的访问级别，则需要用一种变通的方式，自己写GetXXX和SetXXX方法。在C#2中可以单独设置get和set的访问级别，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private string name;
public string Name
{
 get { return name; }
 private set { name = value; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;需要注意的是，不能讲属性设置为私有的，而将其中的get或是set设置成公有的，也不能给set和get设置相同的访问级别，当set和get的访问级别相同时，我们可以直接设置在属性上。&lt;/p&gt;
&lt;p&gt;★命名空间可以用来组织类，当不同的命名空间中有相同的类时，可以使用完全限定名来防止类名的冲突，C#1中可以使用空间别名来简化书写，空间别名用using关键字实现，看下面一个例子:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace NameSpaceDemo1
{
 public class ClassDemo{}
}
namespace NameSpaceDemo2
{
 public class ClassDemo{}
}
using Demo1 = NameSpaceDemo1;
using Demo2 = NameSpaceDemo2;
namespace WebApplication2
{
 public partial class _Default : System.Web.UI.Page 
 {
 protected void Page_Load(object sender, EventArgs e)
 {
 Demo1.ClassDemo c1 = new Demo1.ClassDemo();
 Demo2.ClassDemo c2 = new Demo2.ClassDemo();
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果我们在使用中添加了名为Demo1或是Demo2的类，那么空间别名的使用就会受到影响，在C#1中就得使用完全限定名了。在C#2中可以用“::”符号来解决，如下面代码：&lt;/p&gt;</description></item><item><title>TP-Link无线路由的设置</title><link>https://fwhyy.com/2012/07/set-tp-link/</link><pubDate>Wed, 25 Jul 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/07/set-tp-link/</guid><description>&lt;p&gt;上周末搬到了新家，并办理了电信的宽带169套餐，周一电信的工作人员将网和ITV都调通了，看电视和上网都没有问题。不过网是通过网线连接到电脑的。昨天晚上我尝试着通过无线路由来实现上网，看起来很容易的事情却经过了一番周折。&lt;/p&gt;
&lt;p&gt;之前连接无线路由都是猫接到路由器的WAN口，然后在从LAN口连接一根网线到电脑，在电脑上输入http://192.168.1.1进行相应的设置就可以了。因为现在不需要猫了，所以我直接将网线插入到路由器的WAN口，然后用笔记本搜无线信号，可以进入到http://192.168.1.1进行设置，但怎么设置无线信号上都有个黄色的感叹号，显示无法与网络连接。期初还以为是账号密码的问题，打电话到一万问了下，确认账号和密码正确。&lt;/p&gt;
&lt;p&gt;今早一起来，我将网线从WAN口换到了LAN口试了下，没想到就连接正确了。&lt;/p&gt;</description></item><item><title>《代码整洁之道》读书笔记(下)</title><link>https://fwhyy.com/2012/05/clear-code-reading-notes-two/</link><pubDate>Wed, 16 May 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/05/clear-code-reading-notes-two/</guid><description>&lt;p&gt;全书一共400多页，一共17章，第十三章讲并发，并且在附录A中有对并发的补充，第十四到十六章是一些Java代码的案例，第十七章相当于一个总结。本次写读书笔记主要涵盖前十二章的内容，由于篇幅分为上下两篇。本篇为下，个别章节因为能力有限，没有完全弄懂，就先空着了。&lt;/p&gt;
&lt;h2 id="第七章-错误处理"&gt;第七章 错误处理&lt;/h2&gt;
&lt;p&gt;错误处理简单来说就是当软件出现错误时还能正常工作。错误处理很重要，但不能打乱的原本的代码逻辑。&lt;/p&gt;
&lt;p&gt;使用异常处理而非返回码，底层往上抛，最上层集中处理。这点在第三章函数中也提到过，之所以看到有的地方是使用错误返回码，是因为早期的一些语言没有异常处理机制。现在的语言基本都有异常处理机制。&lt;/p&gt;
&lt;p&gt;异常的信息应该足够充分（包含出错的位置以及原因）。&lt;/p&gt;
&lt;p&gt;不要在catch块中去实现业务逻辑，就是说当出现异常的时候一定要抛出，而不要改变状态或是做其他一些操作，这样会留下很多陷进。&lt;/p&gt;
&lt;p&gt;底层的方法不要返回Null值，否则在调用时会添加很多的判断，可以抛出异常或返回特例对象，特例对象是指返回一个函数返回值类型的空对象。&lt;/p&gt;
&lt;p&gt;不要传递Null值。&lt;/p&gt;
&lt;h2 id="第八章-边界"&gt;第八章 边界&lt;/h2&gt;
&lt;p&gt;无&lt;/p&gt;
&lt;h2 id="第九章-单元测试"&gt;第九章 单元测试&lt;/h2&gt;
&lt;p&gt;我工作以来所经历的公司中都很少使用单元测试，以致于我现在对单元测试这方面还不是特别熟悉，只是在自己的个人项目中写过一些单元测试的代码。在DotNet平台下可以使用VS自带的单元测试功能或是NUnit。&lt;/p&gt;
&lt;p&gt;现在有一种编程的方法叫TDD（测试驱动开发），意思是先写单元测试，然后写对应的代码，通过修改调试让写的代码通过单元测试。使用TDD，会使测试覆盖所有的代码，测试代码和生产代码的比例有可能会达到1:1 ，所以也会带来成本的问题。TDD三定律：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在编写不能通过的单元测试前，不可以编写生产代码；&lt;/li&gt;
&lt;li&gt;只有编写刚好无法通过的单元测试，不能编译也算不通过；&lt;/li&gt;
&lt;li&gt;只可编写刚好足以通过当前失败测试的生产代码。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;测试代码和生产代码一样的重要，也需要保持整洁。测试代码要随着生产代码的修改而修改，否则只会产生大量无用的测试代码，而且也会给生产代码的修改带来风险。&lt;/p&gt;
&lt;p&gt;单元测试的好处：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有了测试不用担心对代码的修改；&lt;/li&gt;
&lt;li&gt;有了测试可以毫无顾虑的去改进架构和设计；&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;整洁测试的三要素 ：可读性、可读性、可读性，测试中的可读性甚至比生成代码中的可读性还要重要。要做到高可读性，测试代码需要满足：明确、简洁和足够的表达力。&lt;/p&gt;
&lt;p&gt;每个测试都可以拆分为三个环节：构造测试数据、操作测试数据、检验操作是否达到预期结果。&lt;/p&gt;
&lt;p&gt;双重标准：指的是在测试环境中和生产环境中有些条件不必完全一致。生产环境中有时要考虑内存、cpu等性能问题，而在测试环境中不必做这些限制。&lt;/p&gt;
&lt;p&gt;每个测试一个断言，不必完全纠结，但单个测试断言数应该最小化。&lt;/p&gt;
&lt;p&gt;每个测试函数只测试一个概念，还是单一职责的问题。&lt;/p&gt;
&lt;p&gt;整洁的测试代码要满足“FIRST”原则&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;快速（Fast）：测试运行应该够快，如果运行很慢就不会想频繁去运行它，就会导致不能及时发现问题。&lt;/li&gt;
&lt;li&gt;独立（Independent）：测试应相互独立，某个测试不应成为下个测试的设定条件，应该可以单独运行每个测试。测试如果相互依赖，会导致一连串的测试失败，查找问题比较困难。&lt;/li&gt;
&lt;li&gt;可重复（Repeatable）：可以在任何环境中重复通过。&lt;/li&gt;
&lt;li&gt;自足验证（Self-Validating）：测试应该有布尔值输出，无论是成功还是失败。&lt;/li&gt;
&lt;li&gt;及时（Timely）测试应及时编写，单元测试应该在使其通过的生产代码编写之前编写。按这种要求及时TDD开发了，但在实际工作中并不是总能遇到TDD开发的团队。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="第十章-类"&gt;第十章 类&lt;/h2&gt;
&lt;p&gt;类通常由变量、属性和方法组成。按照书中所讲的Java的约定，类应该由一组变量开始，如果有静态公共常量，应该放在前面，然后是私有静态变量和私有实体变量。公共函数跟在变量之后，一些供公共函数调用的私有工具函数在公共函数之后。&lt;/p&gt;
&lt;p&gt;和函数一样，类也应该要尽可能的短小。但和函数不同不是以代码行数来权衡，而是以职责。如果无法准确的为某个类命名，则有可能是该类的职责过多。&lt;/p&gt;
&lt;p&gt;单一职责原则（SRP）：类或模块应该有且只有一条加以修改的理由。&lt;/p&gt;
&lt;p&gt;在实际的工作中很多开发人员往往不会思考这么多，他们只想着让代码可以工作就可以了，所以经常出现几千行的大类。系统应该是有许多短小的类而不是少量巨大的类组成。每个小类有单一的职责，只有一个修改的原因，所有这些小类在一起协同工作完成系统的功能。&lt;/p&gt;
&lt;p&gt;高内聚：如果一个类中每个变量都被每个方法所使用，则该类有最大的内聚性。&lt;/p&gt;
&lt;p&gt;保持内聚性得到许多短小的类。&lt;/p&gt;
&lt;p&gt;上面说到每个类应该有单一职责，就是说类之间应该低耦合，但类的内部应该是高内聚的。如果一个类中的每个变量被每个类使用，则该类具有最大的内聚性。内聚性高说明变量和方法相互关联形成一个逻辑整体。&lt;/p&gt;
&lt;p&gt;重构函数也会促使类职责的分离，看下面场景：&lt;/p&gt;
&lt;p&gt;将一个有许多变量的大函数拆分成小函数，如果拆出来的代码使用了其中4个变量，那么就会将这4个变量作为参数传入到小函数中，如果使用的变量越多，就意味着小函数的参数越多，这时可以讲这4个变量升级成实体变量，小函数就不需要参数了，可以直接使用这些变量。这样就使内聚性变低，因为类中有很多的变量只为少数的函数服务，这时就可以将这些变量和函数拆分出来，单独成类。&lt;/p&gt;
&lt;p&gt;开放闭合原则（OCP）&lt;/p&gt;
&lt;p&gt;依赖倒置原则（DIP）&lt;/p&gt;
&lt;h2 id="第十一章-系统"&gt;第十一章 系统&lt;/h2&gt;
&lt;p&gt;这一章主要讲的是怎样在较高的层级–系统层级来保持整洁。&lt;/p&gt;
&lt;p&gt;将系统构造和使用分开：软件系统应该将启始过程和启始过程之后的运行时逻辑分离开，在启动过程中构建应用对象，也会存在相互缠结的依赖关系。&lt;/p&gt;
&lt;p&gt;本章提到的一些技术概念，下面提供一些参考学习链接：&lt;/p&gt;
&lt;h2 id="工厂模式"&gt;工厂模式&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-3-abstract-factory-pattern/"&gt;http://blog.fwhyy.com/2009/11/design-patterns-notes-3-abstract-factory-pattern/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;依赖注入（DI）&lt;/p&gt;
&lt;p&gt;控制反转（IOC）&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html"&gt;http://www.cnblogs.com/leoo2sk/archive/2009/06/17/1504693.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;扩容：不可能一开始就把系统做对，实现好当前客户的需求，然后重构，扩容来实现新的客户需求。&lt;/p&gt;
&lt;p&gt;软件系统与物理系统可以类比。他们的架构都可以递增式增长，只要我们持续将关注面恰当的切分。&lt;/p&gt;
&lt;p&gt;AOP&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/zhugenqiang/archive/2008/07/27/1252761.html"&gt;http://www.cnblogs.com/zhugenqiang/archive/2008/07/27/1252761.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="第十二章-迭进"&gt;第十二章 迭进&lt;/h2&gt;
&lt;p&gt;Kent Beck关于简单设计的四条规则&lt;/p&gt;
&lt;h3 id="1-运行所有测试"&gt;1 运行所有测试&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;不可测试的系统是不可验证的，不可验证就不应该部署；&lt;/li&gt;
&lt;li&gt;只要系统是可测试的，就会导向保持类的短小和单一的职责；&lt;/li&gt;
&lt;li&gt;紧耦合的代码是难以编写测试的，所以编写测试越多，就会导致使用依赖注入、面向接口编程等来使代码解耦。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="2-不可重复"&gt;2 不可重复&lt;/h3&gt;
&lt;h3 id="3-表达程序员的意图"&gt;3 表达程序员的意图&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;选好的变量名、函数名和类名；&lt;/li&gt;
&lt;li&gt;要记住，下一个阅读你代码的很可能就是你自己；&lt;/li&gt;
&lt;li&gt;添加适当的注释。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-尽可能减少类和方法的数量"&gt;4 尽可能减少类和方法的数量&lt;/h3&gt;
&lt;h3 id="重构"&gt;重构&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;上面的2-4点都可以通过重构的方法来达到；&lt;/li&gt;
&lt;li&gt;重构的目的：提升内聚、降低耦合、切分关注面（AOP）、模块化系统性关注面、缩小函数和类的尺寸、选取好的名称等；&lt;/li&gt;
&lt;li&gt;好的函数、好的类、好的系统是重构出来的，没有人能一开始就把事情做对；&lt;/li&gt;
&lt;li&gt;重构应该要及时，发现了坏味道要及时重构，当然这个需要测试来做保障。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>《代码整洁之道》读书笔记(上)</title><link>https://fwhyy.com/2012/05/clear-code-reading-notes-one/</link><pubDate>Sun, 13 May 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/05/clear-code-reading-notes-one/</guid><description>&lt;p&gt;全书一共400多页，一共17章，第十三章讲并发，并且在附录A中有对并发的补充，第十四到十六章是一些Java代码的案例，第十七章相当于一个总结。本次写读书笔记主要涵盖前十二章的内容，由于篇幅分为上下两篇。&lt;/p&gt;
&lt;h2 id="第一章-整洁代码"&gt;第一章 整洁代码&lt;/h2&gt;
&lt;p&gt;代码的质量非常重要，糟糕的代码有可能会毁了一个公司。对于一个很注重代码质量的人来说呆在一个只关注交付而不关注代码质量的公司是很痛苦的。&lt;/p&gt;
&lt;p&gt;什么是整洁的代码，不同的人又不同的定义。我认为整洁的代码应该是符合所使用语言代码规范的；可复用的；便于维护的；简洁的。&lt;/p&gt;
&lt;p&gt;糟糕的代码想做太多的事情，意图混乱；整洁的代码的每个函数、类和模块都全神贯注一件事，不受周围的干扰。&lt;/p&gt;
&lt;p&gt;“破窗理论”：指的是窗户破损了的建筑让人觉得似乎无人照管，于是别人也不关心，任由窗户继续破损，最终自己也参与破坏活动，在墙上涂鸦，任垃圾堆积，一扇破损的窗户让该建筑走向了倾颓的道路。在程序中也是一样，一处出现了有坏味道的代码，有可能导致整个项目的代码都满目疮痍。所以到嗅到代码有坏味道的时候就要重构，我认为整洁的代码是重构出来的。&lt;/p&gt;
&lt;p&gt;美国“童子军军规”中有条说道“让一地比你来时更干净”，映射到我们编码中就是我们每日在提交代码的时候要确保代码时整洁的，否则就进行重构。好的代码是靠大家一点点积累出来的。问题发现的越早，修改的成本就越少。&lt;/p&gt;
&lt;h2 id="第二章-有意义的命名"&gt;第二章 有意义的命名&lt;/h2&gt;
&lt;p&gt;本章主要介绍在程序中命名的规范，命名随处可见，变量、函数、类、模块、命名空间等都需要有好的命名。一个名称如果能让阅读者一看就知道要表达的意思，就可以认为是一个好的名称。&lt;/p&gt;
&lt;p&gt;不要使用单个字母来做变量名，时间一长，自己都不清楚自己当初的命名是什么意思。小方法体，如循环中的计数器除外。&lt;/p&gt;
&lt;p&gt;不要使用有误导性的字母作为变量名，比如小写字母l和大写字母O，因为他们和数字的一和零很像，有的字体还比较好区分，但大多数字体很难分辨。&lt;/p&gt;
&lt;p&gt;“匈牙利命名法（HN）”：该命名法是一位叫 Charles Simonyi 的匈牙利程序员发明的，后来他在微软呆了几年，于是这种命名法就通过微软的各种产品和文档资料向世界传播开了。在当时那个时代编译器并不做类型检查，程序员需要使用HN来帮助自己记住类型。现在的一些高级静态编程语言具有更丰富的类型系统，编译器可以很好的做类型检查，所以使用NH纯属多余。使用NH的几个弊端：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加了名称的长度；&lt;/li&gt;
&lt;li&gt;使名称变得不可读，而在本章的2.5小节有强调要使用可以读得出来的名称；&lt;/li&gt;
&lt;li&gt;增加了修改名称的难度，修改了变量的类型，变量名就要随着修改，否则会造成误导。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;本章中讲到对接口的命名不要使用“I”作为前缀，这点我持保留意见，可能因为我一直是从事的Net上的开发，DotNet的类库中的接口基本都是使用“I”作为前缀的，而且在《NET 设计规范》一书中也强调接口要使用“I”作为前缀。&lt;/p&gt;
&lt;p&gt;类名使用名词或是名词短语，而不应当使用动词。&lt;/p&gt;
&lt;p&gt;对于方法名做到每个概念一个词，应该保持一致，比如对于绑定数据的方法，不要有的地方用BindData，而另一些地方使用DataBind 。&lt;/p&gt;
&lt;p&gt;最后想说的是命名除了一些通用的法则外，对于一些规范性的问题还是要遵循所使用语言或平台规定或是约定俗成的惯例。比如方法名C#中推荐使用Passcal风格，而在Java中则是使用Camel风格。&lt;/p&gt;
&lt;h2 id="第三章-函数"&gt;第三章 函数&lt;/h2&gt;
&lt;p&gt;函数一直都被要求要短小，有不少书中都以行数来作为标准，比如一个行数在20行以内被称为小函数，或是要在5行以内才是小函数。以行数来要求似乎有些苛刻，有一些极端的情况，比如初始化一个Model，里面有几十个字段，这时这个初始化函数中就有几十行代码，而且是无法拆分的，所以我认为，函数只要是在做一件事情就可以了。通常来说如果函数只做一件事，自然就不会很长。我对函数长度的极限是横竖都不要超过一屏。&lt;/p&gt;
&lt;p&gt;函数应该只做一件事，判断函数时候只做一件事，看函数中是否很能够拆分，如果可以，就果断进行重构。&lt;/p&gt;
&lt;p&gt;当函数中有Swicth语句的时候，就不可避免的要做多件事情了，而且函数会随着Switch条件的增加会越来越长。因为函数中做了多件事情，违反了SRP原则，因为随着增加条件我们要去修改这个函数，违反了OCP原则。这个问题可以通过工厂模式来解决。&lt;/p&gt;
&lt;p&gt;函数的名称要使用描述性的名称，让人一看名称就知道该函数是做什么的。当函数只做一件事情的时候，取名就容易多了。还有比较重要的一点，风格要保持一致。&lt;/p&gt;
&lt;p&gt;函数的参数要尽可能的少，书中要求是最好不要超过3个参数，当超过的时候就要将参数提取为一个对象，但实际中很难做到，通常都是为了省事，但有N多参数的函数会给阅读者带来障碍，特别是当参数名还词不达意的时候。&lt;/p&gt;
&lt;p&gt;在一个函数中不要去调用职责之外的另外的函数，尤其是底层的函数，否则给高层调用带来风险。举个简单的例子：比如在用户登录的时候我们可能会有一个CheckPassword的方法来验证登录的用户名和密码，如果在CheckPassword函数中在验证成功后调用Session.Init()来对Session进行初始化，就会存在隐患。根据名称来看只是检查密码用，如果有人在非登录的情况下调用了该方法，会更改当前会话。&lt;/p&gt;
&lt;p&gt;使用异常代替错误返回码，如果使用错误返回码会要求立即处理错误，当在高层调用很多底层方法时，每个方法都要去根据错误返回码进行处理，会造成函数逻辑混乱，如果使用异常处理则只需要在catch中处理即可。&lt;/p&gt;
&lt;p&gt;远离重复，拒绝重复，方法有很多，抽象到基类或放到底层公共类库中。&lt;/p&gt;
&lt;p&gt;没有人能一次性就将函数写的很完美，好的函数是通过重构得到的。&lt;/p&gt;
&lt;h2 id="第四章-注释"&gt;第四章 注释&lt;/h2&gt;
&lt;p&gt;注释是一把双刃剑，好的注释能够给我们好的指导，不好的注释只会将我们误导。注释是弥补代码子表述不足的一种手段，就像设计模式是用来弥补语言不足一样。&lt;/p&gt;
&lt;p&gt;代码是我们获取信息的准确来源，注释随着项目人员的更替 反复的修改最终可能词不达意了，因为很多开发人员在整合代码，修改方法的时候并不是总是同步修改注释。&lt;/p&gt;
&lt;p&gt;有时候看到一个函数的代码写的很糟糕，逻辑很混乱，有开发人员可能想，给这个函数加上几行注释，这样有可能起到适得其反的作用，这时要做的是将函数整理干净。&lt;/p&gt;
&lt;p&gt;代码即注释，很多书和大师都这么讲，意思是我们要用代码本身来解释我们的意图，那就要求我们要控制好函数只做一件事，函数名和变量名要规范和可读。&lt;/p&gt;
&lt;p&gt;当然也不是所有的注释都没有用，像下面几种类型的注释是有必要的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;具有警示性的注释；&lt;/li&gt;
&lt;li&gt;描述一些负责业务场景；&lt;/li&gt;
&lt;li&gt;有些函数现在还是一个空壳，但在将来可能有用，有必要写。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当我们不得不写一些注释的时候，要确保言简意赅，能够很好的表达意思，不要造成误解，也不要写多余的废话。&lt;/p&gt;
&lt;p&gt;还有一种日志被称为日志式注释，一般出现在一个类的开始部分，记录每次修改时的时间、人员名称和修改内容。随着时间的推移这类注释会变得非常冗长。这类注释在一些项目中很普遍，而且有时会被严格要求写，但书中强调现在的源代码都会有源代码工具来进行管理，修改记录在源代码工具中有保存，这种日志式的注释应该全部删除。&lt;/p&gt;
&lt;p&gt;有的开发人员喜欢在注释中签上自己的名字，这种做法也没没有必要，因为我们有源码管理工具。&lt;/p&gt;
&lt;p&gt;项目代码中经常会出现被注释掉的代码，这对后面的维护人员会造成困扰，也会使代码变得混乱，这种代码同样可以删掉，因为我们有源码管理工具。&lt;/p&gt;
&lt;h2 id="第五章-格式"&gt;第五章 格式&lt;/h2&gt;
&lt;p&gt;代码并非可以工作就了事了，还要有良好的代码格式规范，开发人员在维护代码的时候经常会埋怨别人的代码写的很烂，如果不严格要求自己，以后就会成为别人眼中的“别人”了。&lt;/p&gt;
&lt;p&gt;代码格式规范，我认为首先要保证和当前使用的语言、平台保持一致，再就是整个团队中要保持一致。当公司项目的代码规范和使用语言、平台的规范有冲突时尽量说服团队和语言、平台保持一致，实在不行只能和项目组保持一致，像我现在所做的项目由于一些原因还在使用匈牙利命名法，虽然这让我很郁闷，但我还是和他们保持一致。如果是一个新项目则可以团队成员在一起来讨论制定代码规范。&lt;/p&gt;
&lt;p&gt;合理使用空白行，同一类的有关联的放在一起。&lt;/p&gt;
&lt;p&gt;变量申明尽可能靠近使用的地方。&lt;/p&gt;
&lt;p&gt;实体变量放在类的顶部，因为设计良好的类，实体变量会被大多数的方法使用。&lt;/p&gt;
&lt;p&gt;相关函数（一个函数调用了另一个函数）放在一起，也包括的重载的函数。&lt;/p&gt;
&lt;p&gt;一行代码的宽度：120字符之内，最好不要拖动横向滚动条。&lt;/p&gt;
&lt;p&gt;横向空格，比如一个表达式中的符号左边和右边与符号之间加空格，这个在VS中的代码格式化会自动帮我们做了。&lt;/p&gt;
&lt;p&gt;缩进，只有一行的也按缩进规则来。&lt;/p&gt;
&lt;h2 id="第六章-对象和数据结构"&gt;第六章 对象和数据结构&lt;/h2&gt;
&lt;p&gt;暂略&lt;/p&gt;</description></item><item><title>将Live Writer默认保存目录映射到百度网盘</title><link>https://fwhyy.com/2012/05/to-save-live-writer-the-default-directory-is-mapped-to-the-baidu-net-disk/</link><pubDate>Sun, 13 May 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/05/to-save-live-writer-the-default-directory-is-mapped-to-the-baidu-net-disk/</guid><description>&lt;p&gt;Window Live Writer是我一直以来写博客的工具，但是他的默认保存路径是C:\Users\Administrator\Documents\My Weblog Posts，并且不能更改。最近在使用百度网盘，所以就想到将Live Writer的保存目录能同步到百度网盘的目录中，在网上查了些资料，还真有办法，如果是Win7或是Windows Server2008系统，可以用系统自带的mklink命令，如果是XP系统可以下载Junction.exe达到同样的目的。&lt;/p&gt;
&lt;p&gt;我百度网盘的目录是D:\百度网盘，在命令行中输入如下命令可以实现Live Witer默认目录到百度网盘目录的链接：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302121952.webp" alt="2012-05-13_221120" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;注意：在D:\百度网盘 目录中不要先创建了“My Weblog posts”目录，如果先创建了该目录在执行命令式会出现如下错误：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302121630.webp" alt="2012-05-13_222209" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;有关mklink的使用方法可以在命令行下输入mklink\？，也可以点击&lt;a href="http://wenku.baidu.com/view/56453dcfda38376baf1fae2c.html"&gt;这里&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;junction下载地址：&lt;a href="http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx"&gt;http://technet.microsoft.com/en-us/sysinternals/bb896768.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;junction使用参考教程：&lt;a href="http://sigh-ishldg.iteye.com/blog/1096606"&gt;http://sigh-ishldg.iteye.com/blog/1096606&lt;/a&gt;&lt;/p&gt;</description></item><item><title>使用百度网盘同步OneNote</title><link>https://fwhyy.com/2012/05/use-baidu-cloud-sync-onenote/</link><pubDate>Thu, 10 May 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/05/use-baidu-cloud-sync-onenote/</guid><description>&lt;p&gt;现在云存储有很多种选择，Dropbox、Google Drive、SkyDrive还有百度最近推出的百度网盘。SkyDrive的25G免费空间很吸引人，但客户端不支持Win2003（公司电脑系统Win2003），使用起来有些局限性。今天注册了百度网盘，空间15G，而且还可以通过邀请好友进行扩容，还有一个好处就是一般不会被墙，所以果断选择百度网盘。&lt;/p&gt;
&lt;p&gt;平时不管是上班还是在家都喜欢用OneNote来记一些东西，用百度网盘来同步OneNote非常方便。百度网盘PC客户端安装运行后会让指定一个目录做同步目录，确定后会在该目录中生成一个名为“百度网盘”的目录，将文件复制到该目录中会自动同步到云端。“百度网盘”目录也会作为一个系统文件夹出现在我的电脑中。&lt;/p&gt;
&lt;p&gt;OneNote的默认存储路径为C:\Users\Administrator\Documents\OneNote 笔记本，我们只需要把该目录中的内容复制到“百度网盘”目录中，然后将OneNote笔记本属性中的路径修改为“百度网盘”中的目录。需要同步的电脑都做同样的设置就OK了。&lt;/p&gt;</description></item><item><title>五一流水账–装修</title><link>https://fwhyy.com/2012/05/the-may-day-laundry-list-decoration/</link><pubDate>Wed, 02 May 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/05/the-may-day-laundry-list-decoration/</guid><description>&lt;p&gt;五一三天小长假，原计划要去参加一个同学的婚礼，但因为房子装修的事情没能去成, 3天时间基本都耗在装修中了。&lt;/p&gt;
&lt;p&gt;4月29日，放假的第一天，我和老婆去建材市场买油漆，房子的木工部分已经完工，就等油漆工进场了。油漆是在多乐士的专卖店买的，买完后才发现很多的辅料并不是多乐士的，有点后悔，在外面的小店子买这些辅料应该会更便宜。&lt;/p&gt;
&lt;p&gt;买完油漆我们还预定了地板和防盗门。吃完午饭，和老婆还有老婆弟一起随拉油漆的车子到了小区，几百斤的油漆加上辅料就我们三个人慢慢给搬上了5楼，由于太长时间没做体力劳动了，现在手臂还在痛。&lt;/p&gt;
&lt;p&gt;随后老婆的爸妈也到了小区，一干人一起把屋里木工施工完后的渣子清理了。晚上去的老婆父母家，晚餐把老婆买给我岳父的一瓶五粮液给分着喝了，一杯100多块啊，太奢侈了！&lt;/p&gt;
&lt;p&gt;4月30日，上午和老婆去房子里打扫卫生，下午和老婆继续逛建材市场，买了灯和窗帘，灯买的雷士的，价格真不便宜，不过赶上五一活动，倒也能接受。到此硬装部分的材料基本搞定。&lt;/p&gt;
&lt;p&gt;5月1日，原计划趁五一活动把家电给买了，无奈郎中羞涩，只好在家里宅了一天。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302101820.webp" alt="all-300x300" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>谈“绩效考核”</title><link>https://fwhyy.com/2012/04/talk-about-performance-appraisal/</link><pubDate>Mon, 23 Apr 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/04/talk-about-performance-appraisal/</guid><description>&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;在工作以来就职的几家公司中，目前就职的这家公司有非常完善的“绩效考核”制度。绩效工资大概占工资的百分之二十左右，绩效的最高系数为2，就是说如果你的工资的20%为2000，绩效最高可以拿到4000 ，当然很难达到最高的系数。公司推行“绩效考核”的这种制度出发点是刺激员工的积极性，同时也让表现好的员工能有好的回报，但我却发现了其中的一些“弊端”。&lt;/p&gt;
&lt;p&gt;我们的绩效分为两个维度：业绩考核和行为态度考核。行为态度主要是实际工作中的一些突出事迹，成就客户之类的东西，如果不是和客户直接打交道的比如实施类的岗位，在行为态度上要想有所表现比较困难，所以本文将围绕业绩考核来谈，并且只针对开发岗。&lt;/p&gt;
&lt;p&gt;业绩考核又分为很多的指标，每个指标根据完成的情况得到不同的分数（0、2、3、5），再根据每个指标占的不同比例算出业绩考核的总分，业绩考核的指标有：工作量，bug量和关键节点达成率。 下面分别来说下这几个指标。&lt;/p&gt;
&lt;h2 id="工作量"&gt;工作量&lt;/h2&gt;
&lt;p&gt;任务系统的任务都会评估出一个工作量，以天为单位。计算方法为在季度末算出整个季度中完成的工作量和总出勤天数的一个比例。表明上看这个指标非常好，公司不用怕员工偷懒，相反员工还会主动去找事情做，因为担心工作量不够。看上去挺好，但实际操作中却存在很多问题，有些时候两个工作之间不能很好的衔接，造成工作量的流失；有些时候由于需求不明确等问题需要反复沟通造成严重的内耗；有时候。这样就会造成这样一种现象，平时会发现公司里的人貌似都非常的忙，但到了季度末统计工作量时却发现还不够。&lt;/p&gt;
&lt;h2 id="bug量"&gt;bug量&lt;/h2&gt;
&lt;p&gt;bug量的计算方法是一个季度所做的任务的有效bug量和所做任务的共走量的一个比例，最终算出每天的平均bug量是多少，再根据这个bug量来打分。设置bug量这个指标的初衷是为了提高开发人员的开发质量，减少测试与开发之间往返的消耗。但这个指标至少会带来两个弊端：&lt;/p&gt;
&lt;h3 id="1-开发人员和测试人员的对立"&gt;1 开发人员和测试人员的对立&lt;/h3&gt;
&lt;p&gt;因为测试岗也有bug量的质量，他们是平均每日找到多少个bug，所以很多时候开发人员都在和测试人员纠结bug有效性的问题，其实开发 和测试的目标应该是一致的，都是为了软件能够高质量的交付。&lt;/p&gt;
&lt;h3 id="2-事不关己高高挂起"&gt;2 事不关己，高高挂起&lt;/h3&gt;
&lt;p&gt;经常会在项目中发现一些不合理的代码，如果是在以前的公司，如果是出现在我负责的模块，我会进行重构，但现在我可能不会去碰那些代码，因为可能会带来更多的缺陷，而这些缺陷最终会记在我的头上，即便重构不会带来任何的风险，也没有人会关心这个，人们更多关心的是软件能不能正常的运行。正是由于这个指标的存在，随着时间的增长，项目中的坏味道会越来越多。&lt;/p&gt;
&lt;h2 id="关键节点达成率"&gt;关键节点达成率&lt;/h2&gt;
&lt;p&gt;基本上任务系统中的每个任务都会设置关键节点，对于开发来说关键节点就是某个任务提交测试的时间点。计算方法是未超时的任务数和总任务数的比例。这项指标的初衷是保证开发的效率，但也带来了一些问题：&lt;/p&gt;
&lt;h3 id="1-互帮互助少了"&gt;1 互帮互助少了&lt;/h3&gt;
&lt;p&gt;虽然公司一直都强调同事之间要多沟通，多互相帮助，但正是有了这个指标当你的任务已经快到关键时间点的时候，你就没有多余的时间去顾及其他的事情了。&lt;/p&gt;
&lt;h3 id="2-多任务的处理"&gt;2 多任务的处理&lt;/h3&gt;
&lt;p&gt;当你正在处理设置了关键节点的任务的时候，突然来了一个紧急任务，可能是一个比较紧急的bug任务，如果是在以前的公司，肯定不会有什么顾虑，优先响应紧急的任务，手头正在做的事情就自然往后顺延了。但有了这个指标后就会担心我优先响应bug任务了，那手头正在做的超时了怎么办。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;很多公司没有绩效考核制度一样可以管理的很好，我个人也不是很喜欢这个绩效制度，我认为这个公司对员工的一种不信任。当然绩效制度如果使用合理也可以起到良性的作用，而且不同的公司应该制定适合自己公司的制度。制度就是一种约束，约束太多了总会让人感觉不爽，我认为最好的方式是领导能够利用自身的个人魅力感染员工，提升员工的责任感，很有幸我曾遇到过这样的领导，当时提倡的公司理念是“快乐工作，健康生活”，那段时间每天都很有激情，每天早上起来都很想去公司上班，但这样的公司和领导也是可遇不可求的。&lt;/p&gt;</description></item><item><title>JS中的Replace方法</title><link>https://fwhyy.com/2012/04/the-replace-method-in-js/</link><pubDate>Mon, 16 Apr 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/04/the-replace-method-in-js/</guid><description>&lt;p&gt;最近查一个bug，原因是JS中的Replace方法造成的，当将一个字符串中有处需要替换时，一般会用到JS中的Replace方法，Replace方法的第一个参数如果是传的字符串，只会替换第一处。代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var str = &amp;#34;0CEA65D5-DB8E-4876-A6F8-C88AC7F0E185,E846C244-8A19-4374-879B-0B1DC08D1747,6CB3EBA4-1E22-4E4D-8800-AE31130B6F5D&amp;#34;;
alert(str.replace(&amp;#34;,&amp;#34;,&amp;#34;&amp;#39;,&amp;#39;&amp;#34;));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码本意是将用逗号隔开的GUID的逗号替换成’,’，但实际结果只将第一个逗号替换了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302116081.webp" alt="2012-04-16_230940" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;解决这个问题只需将replace的第一个参数使用正则的方式即可，代码如下:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var reg = new RegExp(&amp;#34;,&amp;#34;,&amp;#34;g&amp;#34;);
var str = &amp;#34;0CEA65D5-DB8E-4876-A6F8-C88AC7F0E185,E846C244-8A19-4374-879B-0B1DC08D1747,6CB3EBA4-1E22-4E4D-8800-AE31130B6F5D&amp;#34;;
alert(str.replace(reg,&amp;#34;&amp;#39;,&amp;#39;&amp;#34;));
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302116958.webp" alt="2012-04-16_231320" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>WordPress升级其实很简单</title><link>https://fwhyy.com/2012/04/wordpress-upgrade-is-very-simple/</link><pubDate>Sun, 01 Apr 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/04/wordpress-upgrade-is-very-simple/</guid><description>&lt;p&gt;从2010年年底使用WordPress搭建个人博客开始，就从来没有升级过，一直以来也没有出现什么问题，直到最近出现安全问题并且导致域名被godaddy禁用才使我有了升级的打算。&lt;/p&gt;
&lt;p&gt;论坛里的一些网友说升级会导致各种各样的问题，看起来貌似很吓人，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;升级会导致兼容性的问题；&lt;/li&gt;
&lt;li&gt;升级最好是一级一级的网上升；&lt;/li&gt;
&lt;li&gt;升级导致一些插件不能使用；&lt;/li&gt;
&lt;li&gt;等等。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实也没那么夸张，至少我在这次升级中没有出现什么问题，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首先将网站程序和数据库做备份，这个是一定要做的，以防万一；&lt;/li&gt;
&lt;li&gt;将空间里的wp-admin目录和wp-includes删除；&lt;/li&gt;
&lt;li&gt;将下载的最新的WordPress目录中的wp-admin目录和wp-includes上传到空间中；&lt;/li&gt;
&lt;li&gt;将下载的最新的WordPress根目录下的文件上传到空间中替换；&lt;/li&gt;
&lt;li&gt;登陆WordPress后台，会有升级的提示，根据提示操作即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就这么简单，当然也有一些要注意的地方，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;升级前一定要备份；&lt;/li&gt;
&lt;li&gt;wp-admin目录和wp-includes目录最好是删除后上传新的，因为不同版本中的文件可能不一样，直接上传会造成文件冗余，有可能会引发问题；&lt;/li&gt;
&lt;li&gt;使用的一些重要的插件如果担心出现兼容性问题，可以在升级前先去插件的主页上看看和你要升级的版本的兼容性。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为了安全，常升级吧！&lt;/p&gt;</description></item><item><title>WordPress安全问题</title><link>https://fwhyy.com/2012/03/wordpress-security-issues/</link><pubDate>Tue, 27 Mar 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/03/wordpress-security-issues/</guid><description>&lt;p&gt;前些天发现我的个人博客不能访问 了，开始以为是空间的问题，找空间客服咨询得知有可能是域名的问题，我域名是在godaddy申请的，2010年年底申请并设置好后就基本没进过godaddy的管理后台。结果我登陆到godaddy后台发现我的域名不见了，见下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290646478.webp" alt="2012-03-23_124752" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;咨询了一些朋友，告诉我说让我检查下我的邮箱，看有没有godaddy发来的通知邮件。随后我在邮箱中搜索godaddy，果然发现了几封相关的邮件，原来是我的博客遭到攻击了，根据相关条款godaddy将我的域名给禁用了。两封提醒邮件是2月份发的，3月9日发的一封邮件直接通知我我的域名被禁用。也怪我平时的看到英文的邮件都不怎么在意。&lt;/p&gt;
&lt;p&gt;原因找到了就好说，我给godaddy发了封邮件问这个问题要怎么解决，他们的回复很快，让我删除空间中违规的文件，并做了一些保证，我都照做后，当天我的域名就恢复了。违规文件建下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290646147.webp" alt="2012-03-23_130150" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;之后我在网上看了些有关WordPress安全方面的一些文章，说的比较多的就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要经常升级WordPress、插件以及主题，&lt;/li&gt;
&lt;li&gt;使用一些安全插件，如WP Security Scan，&lt;/li&gt;
&lt;li&gt;账户密码的安全性，密码要足够强壮，不用使用admin做用户名，
…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我的博客从挂到网上起就没有升级过，被攻击有可能就是因为这个原因，以后一定要经常升级，这样对于一些老版本的安全漏洞就可以避免了。另外对于英文邮件一定要留意，往往忽视的东西恰恰是很重要的东西。&lt;/p&gt;</description></item><item><title>取汉子拼音首字母的C#和VB.Net方法</title><link>https://fwhyy.com/2012/03/take-the-first-initials-method-of-csharp-and-vbnet/</link><pubDate>Sun, 04 Mar 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/03/take-the-first-initials-method-of-csharp-and-vbnet/</guid><description>&lt;p&gt;最近修改了项目中的一个bug，是因为取汉子拼音首字母的方法有问题导致一些字的首字母获取错误，在网上找了一些现成的方法进行测试，发现下面的方法虽然比较笨，但准确率还是挺高。&lt;/p&gt;
&lt;h2 id="c代码"&gt;C#代码&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt; 
 /// 获得一个字符串的汉语拼音码
 /// &amp;lt;/summary&amp;gt; 
 /// &amp;lt;param name=&amp;#34;strText&amp;#34;&amp;gt;字符串&amp;lt;/param&amp;gt; 
 /// &amp;lt;returns&amp;gt;汉语拼音码,该字符串只包含大写的英文字母&amp;lt;/returns&amp;gt; 
 public static string GetChineseSpell(string strText)
 {
 if (strText == null || strText.Length == 0)
 return strText;
 System.Text.StringBuilder myStr = new System.Text.StringBuilder();
 foreach (char vChar in strText)
 {
 // 若是字母则直接输出 
 if ((vChar &amp;gt;= &amp;#39;a&amp;#39; &amp;amp;&amp;amp; vChar &amp;lt;= &amp;#39;z&amp;#39;) || (vChar &amp;gt;= &amp;#39;A&amp;#39; &amp;amp;&amp;amp; vChar &amp;lt;= &amp;#39;Z&amp;#39;))
 myStr.Append(char.ToUpper(vChar));
 else if ((int)vChar &amp;gt;= 19968 &amp;amp;&amp;amp; (int)vChar &amp;lt;= 40869)
 {
 // 若字符Unicode编码在编码范围则 查汉字列表进行转换输出 
 foreach (string strList in strChineseCharList)
 {
 if (strList.IndexOf(vChar) &amp;gt; 0)
 {
 myStr.Append(strList[0]);
 break;
 }
 }
 }
 }
 return myStr.ToString();
 }// GetChineseSpell 

 private static string[] strChineseCharList = 
 { 
 &amp;#34;A阿啊锕嗄厑哎哀唉埃挨溾锿鎄啀捱皑凒溰嘊敳皚癌毐昹嗳矮蔼躷噯藹譪霭靄艾伌爱砹硋隘嗌塧嫒愛碍暧瑷僾壒嬡懓薆曖璦鴱皧瞹馤鑀鱫安侒峖桉氨庵谙萻腤鹌蓭誝鞌鞍盦馣鮟盫韽啽雸垵&amp;#34; , 
 &amp;#34;A俺唵埯铵隌揞罯銨犴岸按荌案胺豻堓婩暗貋儑錌黯肮岇昂昻枊盎醠凹坳垇柪軪爊敖厫隞嗷嗸嶅廒滶獒獓遨熬璈蔜翱聱螯翶謷翺鳌鏖鰲鷔鼇芺袄媪镺襖岙扷岰傲奡奥嫯慠骜奧嶴澳懊擙謸鏊&amp;#34; , 
 &amp;#34;B八仈巴叭扒朳玐吧夿岜芭疤哵捌笆粑紦羓蚆釟豝鲃魞叐犮抜坺妭拔茇炦癹胈釛菝詙跋軷魃把靶坝弝爸垻罢鲅鮁覇矲霸壩灞欛挀掰白百佰柏栢捭竡粨摆擺襬呗拝败拜唄敗稗粺鞁薭贁兡瓸扳&amp;#34; , 
 &amp;#34;B攽班般颁斑搬斒瘢螁癍辬阪坂岅昄板版瓪钣粄舨鈑蝂魬办半伴扮姅怑拌绊秚絆鉡靽辦瓣邦峀垹帮捠梆浜邫幇幚縍幫鞤绑綁榜膀玤蚌傍棒谤塝稖蒡蜯磅镑艕謗勹包佨孢苞胞笣煲龅蕔褒闁齙&amp;#34; , 
 &amp;#34;B窇嫑雹宝怉饱保鸨珤堡堢媬葆寚飹飽褓駂鳵緥鴇賲藵寳寶靌勽报抱豹趵菢鲍靤骲暴髱虣儤曓爆忁鑤萡陂卑杯盃桮悲揹碑鹎藣鵯喺北鉳贝狈貝邶备昁牬苝背钡俻倍悖狽被偝偹梖珼鄁備僃惫&amp;#34; , 
 &amp;#34;B焙軰辈愂碚禙蓓蛽犕褙誖骳輩鋇憊糒鞴鐾奔泍贲倴渀逩犇锛錛本苯奙畚楍坌捹桳笨撪輽伻崩绷閍嵭嘣綳繃甭埲菶琫鞛泵迸塴甏镚蹦鏰屄毴逼豍鲾鵖鰏柲荸鼻嬶匕比夶朼佊吡妣沘疕彼柀秕&amp;#34; , 
 &amp;#34;B俾笔粊舭筆鄙聛貏匂币必毕闭佖坒庇诐邲妼怭畀畁哔毖珌疪荜陛毙狴畢袐铋婢庳敝梐萆萞閇閉堛弻弼愊愎湢皕禆筚詖貱赑嗶彃楅滗滭煏痹腷蓖蓽蜌裨跸閟飶幣弊熚獙碧箅綼蔽鄪馝幤潷獘&amp;#34; , 
 &amp;#34;B罼襅駜髲壁嬖廦篦篳縪薜觱避鮅斃濞臂蹕髀奰璧鄨饆繴襞襣鏎鞸韠躃躄魓贔鐴驆鷝鷩鼊边砭笾编煸甂箯編蝙獱邉鍽鳊邊鞭鯾鯿籩炞贬扁窆匾惼碥稨褊糄鴘藊卞弁忭抃汳汴苄釆峅便变変昪&amp;#34; , 
 &amp;#34;B覍揙缏遍辡艑辧辨辩辫辮變彪标飑髟猋脿墂幖滮骠標熛膘瘭镖飙飚儦颷瀌爂臕贆鏢镳飆飇飈飊鑣表婊裱諘褾錶檦俵鳔鰾憋鳖鱉鼈虌龞別别咇莂蛂徶襒蟞蹩瘪癟彆邠宾彬傧斌椕滨缤槟瑸賓&amp;#34; , 
 &amp;#34;B賔镔儐濒濱濵虨豳瀕霦繽蠙鑌顮氞摈殡膑髩擯鬂殯臏髌鬓髕鬢仌氷冰兵栟掤梹鋲檳丙邴陃怲抦秉苪昺柄炳饼窉蛃棅禀鈵鞆餅餠燷并並併幷垪庰倂栤病竝偋傡寎摒誁鮩靐癶拨波玻剥盋袯钵&amp;#34; , 
 &amp;#34;B饽啵紴缽脖菠鉢僠嶓播餑蹳驋鱍仢伯孛驳帛泊狛瓝侼勃胉郣亳挬浡秡钹铂舶博渤葧鹁愽搏鈸鉑馎鲌僰煿牔箔膊艊馛駁踣鋍镈薄駮鮊懪礡簙鎛餺鵓犦欂襮礴鑮跛箥簸孹擘檗糪譒蘗蔔峬庯逋&amp;#34; , 
 &amp;#34;B钸晡鈽誧餔轐醭卜卟补哺捕補鳪鸔不布佈步咘怖歨歩钚勏埗悑部埠瓿廍蔀踄篰餢簿玢佛夯宀疒瀑&amp;#34; , 
 &amp;#34;C嚓擦礤礸遪猜才材财財戝裁采倸埰婇寀彩採睬跴綵踩菜棌蔡縩乲参飡骖湌嬠餐驂残蚕惭殘慚蝅慙蠶蠺惨慘噆憯黪黲灿粲儏澯薒燦璨爘仓仺伧沧苍倉舱傖凔嵢滄獊蒼濸艙螥罉藏欌鑶賶撡操&amp;#34; , 
 &amp;#34;C糙曺曹嘈嶆漕蓸槽褿艚螬鏪艹艸草愺騲肏襙册侧厕恻测荝敇萗惻測策萴筞蓛墄箣憡嵾膥岑梣涔噌层層竲驓蹭硛硳岾猠乽叉芆杈肞臿訍偛嗏插馇銟锸艖疀鍤餷垞查査茬茶嵖搽猹靫槎察碴檫&amp;#34; , 
 &amp;#34;C衩镲鑔奼汊岔侘诧姹差紁拆钗釵犲侪柴祡豺喍儕虿袃瘥蠆囆辿觇梴掺搀鋓幨婵谗孱棎湹禅馋嬋煘缠獑蝉誗鋋廛潹潺緾磛毚鄽镡瀍儳劖蟾酁嚵壥巉瀺纏纒躔镵艬讒鑱饞产刬旵丳浐剗谄產産&amp;#34; , 
 &amp;#34;C铲阐蒇剷嵼滻幝蕆諂閳簅冁繟醦鏟闡囅灛讇忏硟摲懴颤懺羼韂伥昌娼淐猖菖阊晿椙琩裮锠錩鲳鯧鼚兏肠苌尝偿常徜瓺萇甞腸嘗嫦瑺膓鋿償嚐蟐鲿鏛鱨厂场昶惝敞僘厰廠氅鋹怅玚畅倡鬯唱&amp;#34; , 
 &amp;#34;C悵暢畼誯韔抄弨怊欩钞焯超鈔繛牊晁巢巣朝鄛漅嘲潮窲罺轈吵炒眧煼麨巐仦耖觘车車砗唓莗硨蛼扯偖撦屮彻坼迠烢聅掣硩頙徹撤澈勶瞮爡抻郴棽琛嗔諃賝尘臣忱沉辰陈茞宸烥莐敐晨訦谌&amp;#34; , 
 &amp;#34;C揨煁蔯塵樄瘎霃螴諶薼麎曟鷐趻硶碜墋夦磣踸贂闯衬疢称龀趁榇稱齓齔嚫谶襯讖阷泟柽爯棦浾偁蛏铛牚琤赪憆摚靗撐撑緽橕瞠赬頳檉竀穪蟶鏳鏿饓丞成呈承枨诚郕城宬峸洆荿乘埕挰珹掁&amp;#34; , 
 &amp;#34;C窚脭铖堘惩棖椉程筬絾裎塍塖溗碀誠畻酲鋮澂澄橙檙鯎瀓懲騬悜逞骋庱睈騁秤吃妛杘侙哧彨蚩鸱瓻眵笞訵嗤媸摛痴瞝螭鴟鵄癡魑齝攡麶彲黐弛池驰迟岻茌持竾荎淔筂貾遅馳墀踟篪謘尺叺&amp;#34; , 
 &amp;#34;C呎肔侈卶齿垑胣恥耻蚇豉欼歯裭鉹褫齒彳叱斥灻赤饬抶勅恜炽翄翅敕烾痓啻湁傺痸腟鉓雴憏翤遫慗瘛翨熾懘趩饎鶒鷘充冲忡沖茺浺珫翀舂嘃摏憃憧衝罿艟蹖虫崇崈隀宠铳銃抽瘳篘犨犫仇&amp;#34; , 
 &amp;#34;C俦帱栦惆绸菗畴絒愁皗稠筹酧酬踌雔嬦懤燽雠疇躊讎讐丑丒吜杽侴瞅醜矁魗臭遚殠出岀初摴樗貙齣刍除厨滁蒢豠锄榋耡蒭蜍趎雏犓廚篨橱懨幮櫉蟵躇櫥蹰鶵躕杵础椘储楮禇楚褚濋儲檚璴&amp;#34; , 
 &amp;#34;C礎齭齼亍処处竌怵拀绌豖竐珿絀傗琡鄐搐触踀閦儊憷橻斶歜臅黜觸矗搋膗揣啜嘬踹巛川氚穿剶瑏传舡船圌遄椽歂暷輲舛荈喘僢汌串玔钏釧賗刅囱疮窓窗牎摐牕瘡窻床牀噇傸磢闖创怆刱剏&amp;#34; , 
 &amp;#34;C剙愴吹炊龡垂桘陲捶菙棰槌锤錘顀旾杶春萅堾媋暙椿槆瑃箺蝽橁櫄鰆鶞纯陙唇浱莼淳脣犉滣蒓鹑漘醇醕鯙偆萶惷睶賰踳蠢踔戳辵娖惙涰绰逴辍酫綽輟龊擉磭歠嚽齪鑡呲玼疵趀偨词珁垐柌&amp;#34; , 
 &amp;#34;C祠茈茨瓷詞辝慈甆辞磁雌鹚糍辤飺餈嬨濨鴜礠辭鶿鷀此佌皉朿次佽刺刾庛茦栨莿絘蛓赐螆賜嗭从匆囪苁忩枞茐怱悤焧葱漗聡蔥骢暰樬瑽璁聦聪瞛篵聰蟌繱鏦騘驄丛従婃孮徖悰淙琮慒誴賨&amp;#34; , 
 &amp;#34;C賩樷藂叢灇欉爜謥凑湊楱腠辏輳粗觕麁麄麤徂殂促猝媨瘄蔟誎趗憱醋瘯簇縬蹙鼀蹴蹵顣汆撺镩蹿攛躥鑹攅櫕巑窜熶篡殩簒竄爨崔催凗墔慛摧榱獕磪鏙乼漼璀皠忰疩翆脃脆啐啛悴淬萃毳焠&amp;#34; , 
 &amp;#34;C瘁粹翠膵膬竁襊臎邨村皴澊竴存刌忖寸籿搓瑳遳磋撮蹉醝髊虘嵯嵳痤矬蒫鹾鹺齹脞剉剒厝夎挫莝莡措逪棤锉蓌错銼刂刹畜曾膪澶骣粢&amp;#34; , 
 &amp;#34;D詫襜燀譂奲虰坘蚳赿跮揰裯儔幬篅搥錞踧吋咑哒耷畣搭嗒褡噠墶达妲怛垯炟羍荙匒笪答詚跶瘩靼薘鞑燵繨蟽躂鐽龖龘打大亣眔橽呆獃懛歹傣代汏轪侢垈岱帒甙绐迨带待怠柋殆玳贷帯軑埭&amp;#34; , 
 &amp;#34;D帶紿袋逮軩瑇叇曃緿鮘鴏戴艜黛簤瀻霴襶靆丹妉单担眈砃耼耽郸聃躭媅殚瘅匰箪褝鄲頕儋勯殫襌簞聸刐狚玬瓭胆衴疸紞掸馾澸黕膽旦但帎沊泹诞柦疍啖啗弹惮淡萏蛋啿氮腅蜑觛窞誕噉髧&amp;#34; , 
 &amp;#34;D憚憺澹禫駳鴠甔癚嚪贉霮饏当珰裆筜當儅噹澢璫襠簹艡蟷挡党谠擋譡灙讜氹凼圵宕砀垱荡档菪瓽雼碭瞊趤壋檔璗盪礑刀叨屶忉氘舠釖鱽魛捯导岛陦倒島捣祷禂搗隝嶋嶌槝導隯壔嶹擣蹈禱&amp;#34; , 
 &amp;#34;D到悼盗菿椡盜道稲噵稻衜檤衟翿軇瓙纛恴得淂悳惪锝嘚徳德鍀的揼扥扽灯登豋噔嬁燈璒竳簦艠覴蹬等戥邓凳鄧隥墱嶝瞪磴镫櫈鐙仾低彽袛啲埞羝隄堤趆嘀滴镝磾鞮鏑廸狄肑籴苖迪唙敌涤&amp;#34; , 
 &amp;#34;D荻梑笛觌靮滌嫡蔋蔐頔魡敵嚁藡豴糴鸐氐厎诋邸阺呧坻底弤抵柢砥掋菧軧聜骶鯳地弟旳杕玓怟枤俤帝埊娣递逓偙梊焍眱祶第菂谛釱棣睇缔蒂僀禘腣鉪馰墑墬碲蔕慸甋締嶳螮嗲敁掂傎厧嵮&amp;#34; , 
 &amp;#34;D滇槙瘨颠蹎巅癫巓巔攧癲齻典奌点婰敟椣碘蒧蕇踮电佃甸阽坫店垫扂玷钿婝惦淀奠琔殿蜔電墊壂橂澱靛磹癜簟驔刁叼汈刟虭凋奝弴彫蛁琱貂碉殦瞗雕鮉鲷簓鼦鯛鵰屌弔伄吊钓窎訋掉釣铞&amp;#34; , 
 &amp;#34;D鈟竨銱雿瘹窵鋽鑃爹跌褺苵迭垤峌恎绖胅瓞眣耊戜谍堞幉揲畳絰耋詄叠殜牃牒镻嵽碟蜨褋艓蝶疂蹀鲽曡疉疊氎嚸丁仃叮帄玎甼疔盯钉耵酊靪顶頂鼎嵿薡鐤订饤矴定訂飣啶萣椗腚碇锭碠聢&amp;#34; , 
 &amp;#34;D錠磸顁丟丢铥颩銩东冬咚岽東苳昸氡倲鸫埬娻崬涷笗菄氭蝀鮗鼕鯟鶇鶫董嬞懂箽蕫諌动冻侗垌姛峒恫挏栋洞胨迵凍戙胴動崠硐棟腖働駧霘剅唗都兜兠蔸橷篼艔斗乧阧抖陡蚪鈄豆郖浢荳逗&amp;#34; , 
 &amp;#34;D饾鬥梪脰酘痘閗窦鬦餖斣闘竇鬪鬬鬭嘟督醏毒涜读渎椟牍犊裻読蝳獨錖凟匵嬻瀆櫝殰牘犢瓄皾騳黩讀豄贕韣髑鑟韇韥黷讟厾独笃堵帾琽赌睹覩賭篤芏妒杜肚妬度荰秺渡靯镀螙殬鍍蠧蠹偳&amp;#34; , 
 &amp;#34;D媏端鍴短段断塅缎葮椴煅瑖腶碫锻緞毈簖鍛斷躖籪叾垖堆塠嵟痽頧鴭鐜队对兑対祋怼陮碓綐對憝濧薱镦懟瀩譈鐓譵吨惇敦墩墪壿撴獤噸撉犜礅蹲蹾驐盹趸躉伅沌炖盾砘逇钝顿遁鈍頓碷遯&amp;#34; , 
 &amp;#34;D潡踲多咄哆剟崜毲裰嚉夺铎剫掇敓敚敪痥鈬奪凙踱鮵鐸朵朶哚垛挅挆埵缍椯趓躱躲綞亸鬌嚲刴剁沲陊饳垜尮桗堕舵惰跢跥跺飿嶞憜墯鵽卩亻赕铫町铤夂丶&amp;#34; , 
 &amp;#34;E娾砵妸妿娿屙讹囮迗俄娥峨峩涐莪珴訛皒睋鈋锇鹅蛾磀誐頟额額鵝鵞譌枙砈婀騀鵈厄歺戹阨呃扼苊阸呝砐轭咢垩峉匎恶砨蚅饿偔卾悪硆谔軛鄂阏堮崿愕湂萼豟軶遌遏廅搹琧腭僫蝁锷鹗蕚&amp;#34; , 
 &amp;#34;E遻頞颚餓噩擜覨諤餩鍔鳄歞顎櫮鰐鶚讍鑩齶鱷奀恩蒽峎摁鞥仒乻旕儿而侕陑峏洏荋栭胹袻鸸粫輀鲕隭髵鮞鴯轜尔耳迩洱饵栮毦珥铒餌駬薾邇趰二弍弐佴刵咡贰貮衈貳誀嗯唔诶&amp;#34; , 
 &amp;#34;F颰墢鼥韛朌頒報賁獖祊埄偪胇貶昞眪袚撥柭襏舩发沷発發彂髪橃醗乏伐姂垡疺罚阀栰傠筏瞂罰閥罸藅佱法砝鍅灋珐琺髮帆忛番勫噃墦嬏幡憣旙旛翻藩轓颿飜鱕凡凢凣匥杋柉矾籵钒舤烦舧&amp;#34; , 
 &amp;#34;F笲釩棥煩緐樊蕃橎燔璠薠繁襎繙羳蹯瀿礬蘩鐇蠜鷭反仮払辺返氾犯奿汎泛饭范贩畈訉軓梵盕笵販軬飯飰滼嬎範嬔瀪方邡坊芳枋牥钫淓蚄堏鈁錺鴋防妨房肪埅鲂魴仿访纺昉昘瓬眆倣旊紡舫&amp;#34; , 
 &amp;#34;F訪髣鶭放飞妃非飛啡婓婔渄绯菲扉猆靟裶緋蜚霏鲱餥馡騑騛鯡飝肥淝暃腓蜰蟦匪诽奜悱斐棐榧翡蕜誹篚吠废杮沸狒肺昲费俷剕厞疿屝萉廃費痱镄廢蕟曊癈鼣濷櫠鐨靅分吩帉纷芬昐氛竕紛&amp;#34; , 
 &amp;#34;F翂棻訜躮酚鈖雰朆餴饙坟妢岎汾枌炃肦梤羒蚠蚡棼焚蒶馚隫墳幩蕡魵鳻橨燌燓豮鼢羵鼖豶轒鐼馩黂粉瞓黺份坋弅奋忿秎偾愤粪僨憤奮膹糞鲼瀵鱝丰风仹凨凬妦沣沨凮枫封疯盽砜風峯峰偑&amp;#34; , 
 &amp;#34;F桻烽琒崶渢溄猦葑锋楓犎蜂瘋碸僼篈鄷鋒檒豐鎽鏠酆寷灃靊飌麷冯捀逢堸綘缝艂縫讽覂唪諷凤奉甮俸湗焨煈赗鳯鳳鴌賵蘕瓰覅仏坲梻紑缶否缹缻雬鴀夫伕邞呋姇枎玞肤怤柎砆荂衭娐荴旉&amp;#34; , 
 &amp;#34;F紨趺酜麸稃跗鈇筟綒孵敷麩糐麬麱懯乀弗伏凫甶冹刜孚扶芙芣芾咈岪帗彿怫拂服泭绂绋苻茀俘垘枹柫氟洑炥玸畉畐祓罘茯郛韨鳬哹栿浮畗砩莩蚨匐桴涪烰琈符笰紱紼翇艴菔虙袱幅絥罦葍&amp;#34; , 
 &amp;#34;F福粰綍艀蜉辐鉘鉜颫鳧榑稪箙複韍幞澓蝠髴鴔諨踾輻鮄癁鮲黻鵩鶝抚甫府弣拊斧俌郙俯釜釡捬辅椨焤盙腑滏腐輔簠黼父讣付妇负附咐坿竎阜驸复祔訃負赴蚥袝偩冨副婏婦蚹傅媍富復萯蛗&amp;#34; , 
 &amp;#34;F覄詂赋椱缚腹鲋禣褔赙緮蕧蝜蝮賦駙縛輹鮒賻鍑鍢鳆覆馥鰒猤攵犭&amp;#34; , 
 &amp;#34;G玵閞鳺旮伽嘠钆尜嘎噶錷尕玍尬魀该陔垓姟峐荄晐赅畡祴該豥賅賌忋改絠鎅丐乢匃匄杚钙盖溉葢鈣戤概蓋槩槪漑瓂干甘芉迀杆玕肝坩泔苷柑竿疳酐粓亁凲尲尴筸漧尶尷魐皯秆衦赶敢笴稈&amp;#34; , 
 &amp;#34;G感澉趕橄擀簳鳡鱤旰盰矸绀倝凎淦紺詌骭幹檊赣灨冈罓冮刚岗纲肛岡牨疘缸钢剛罡堈掆釭棡犅堽綱罁鋼鎠崗港杠焵筻槓戆皋羔高皐髙槔睾膏槹橰篙糕餻櫜韟鷎鼛鷱夰杲菒稁搞缟槁獔稿镐&amp;#34; , 
 &amp;#34;G縞藁檺吿告勂诰郜峼祮祰锆筶禞誥鋯戈圪纥戓疙牱哥胳袼鸽割搁彁歌滒戨閤鴐鴚擱謌鴿鎶呄佮匌阁革敋格鬲愅臵葛隔嗝塥滆觡搿槅膈閣镉韐骼諽鮯櫊韚轕鞷騔鰪哿舸个各虼個硌铬箇獦给&amp;#34; , 
 &amp;#34;G根跟哏亘艮茛揯搄更刯庚畊浭耕掶菮椩焿絚赓鹒緪縆賡羹鶊郠哽埂峺挭绠耿莄梗綆鲠骾鯁亙堩啹喼嗰工弓公功攻杛供糼肱宫宮恭蚣躬龚匑塨幊觥躳匔碽髸觵龔巩汞拱拲栱珙輁鞏共贡貢慐&amp;#34; , 
 &amp;#34;G熕兝兣勾佝沟钩袧缑鈎緱褠篝簼鞲韝岣狗苟枸玽耇耉笱耈豿坸构诟购垢姤茩冓够夠訽媾彀搆遘雊煹觏撀覯購估咕姑孤沽泒柧轱唂唃罛鸪笟菇菰蛄蓇觚軱軲辜酤毂箍箛嫴篐橭鮕鴣轂鹘古汩&amp;#34; , 
 &amp;#34;G诂谷股峠牯骨罟羖逧钴傦啒脵蛊蛌尳愲硲詁馉榾鼓鼔嘏榖皷穀糓薣濲臌餶瀔盬瞽固故凅顾堌崓崮梏牿棝祻雇痼稒锢頋僱錮鲴鯝顧瓜刮苽胍鸹歄焻煱颪劀緺銽鴰騧冎叧呱剐剮啩寡卦坬诖挂&amp;#34; , 
 &amp;#34;G掛罣罫褂詿乖拐枴柺箉怪恠关观官冠覌倌棺蒄窤瘝癏観鳏觀鱞馆痯筦管輨舘錧館躀鳤毌贯泴悺惯掼涫悹祼慣摜遦樌盥罆鏆灌爟瓘礶鹳罐鑵鱹光灮侊炗炚炛咣垙姯茪桄烡珖胱僙輄銧黆欟广&amp;#34; , 
 &amp;#34;G広犷俇逛撗归圭妫龟规邽皈茥闺帰珪亀硅袿媯椝瑰郌摫閨鲑嬀槻槼璝瞡鬶瓌櫷宄轨庋佹匦诡陒垝癸軌鬼庪祪匭晷湀蛫觤詭厬簋蟡刽刿攰柜炅攱贵桂椢筀貴蓕跪瞆劊劌撌槶禬簂櫃鳜鱥衮惃&amp;#34; , 
 &amp;#34;G绲袞辊滚蓘滾蔉磙輥鲧鮌鯀棍棞睴璭謴呙埚郭啯崞聒鈛锅墎瘑嘓彉蝈鍋彍囯囶囻国圀國帼掴幗慖摑漍聝蔮虢馘果惈淉猓菓馃椁褁槨綶蜾裹餜鐹过桧咯莞呷&amp;#34; , 
 &amp;#34;H餲淲豩豰俿腄墮吪魤犿浲侅郂絯忓攼仠桿汵榦臯鎬暠犵挌蛤厷愩唝羾詬鶻淈鹄鈷縎鵠怘趏潅雚洸襘鞼緄腘膕粿輠過铪丷哈嗨孩骸海胲烸塰酼醢亥骇害氦嗐餀駭駴嚡饚乤兯佄顸哻蚶酣頇谽&amp;#34; , 
 &amp;#34;H憨馠魽鼾邗含邯函凾虷唅圅娢浛崡晗梒涵焓寒嵅韩甝筨爳蜬澏鋡韓厈罕浫喊蔊豃鬫汉屽扞汗闬旱垾悍捍晘涆猂莟晥焊琀菡釬閈皔睅傼蛿颔撖蜭暵銲鋎憾撼翰螒頷顄駻雗瀚鶾魧苀斻杭垳绗&amp;#34; , 
 &amp;#34;H笐航蚢颃貥筕絎頏沆蒿嚆薅竓蚝毫椃嗥獆噑豪嘷獋儫曍嚎壕濠籇蠔譹好郝号昊昦哠恏浩耗晧淏傐皓聕號暤暭澔皜皞皡薃皥颢灏顥鰝灝兞诃呵喝訶嗬蠚禾合何劾咊和姀河峆曷柇盇籺阂哬敆&amp;#34; , 
 &amp;#34;H核盉盍荷啝涸渮盒秴菏萂龁惒粭訸颌楁詥鉌阖鲄熆閡鹖麧澕篕翮魺闔齕覈鶡皬鑉龢佫垎贺寉焃湼賀煂碋褐赫鹤翯壑癋爀鶴齃靍靎鸖靏黒黑嘿潶嬒拫痕鞎佷很狠詪恨亨哼悙涥脝姮恆恒桁烆&amp;#34; , 
 &amp;#34;H珩胻鸻横橫衡鴴鵆蘅鑅堼囍乊乥叿灴轰哄訇烘軣焢硡薨輷嚝鍧轟仜弘妅红吰宏汯玒纮闳宖泓玜苰垬娂洪竑荭虹浤紘翃耾硔紭谹鸿渱竤粠葒葓鈜閎綋翝谼潂鉷鞃魟篊鋐彋蕻霐黉霟鴻黌晎嗊&amp;#34; , 
 &amp;#34;H讧訌撔澋澒銾侯矦喉帿猴葔瘊睺篌糇翭骺鍭餱鯸吼犼后郈厚垕後洉逅候鄇堠豞鲎鲘鮜鱟乎匢虍呼垀忽昒曶泘苸烀轷匫唿惚淴虖軤雽嘑寣滹雐歑囫抇弧狐瓳胡壶壷斛焀喖壺媩湖猢絗葫楜煳&amp;#34; , 
 &amp;#34;H瑚嘝蔛鹕槲箶糊蝴衚魱縠螜醐頶觳鍸餬瀫鬍鰗鶘鶦鶮乕汻虎浒唬萀琥虝箎錿鯱互弖戶户戸冱冴帍护沍沪岵怙戽昈枑祜笏粐婟扈瓠綔鄠嫭嫮摢滬蔰槴熩鳸簄鍙鹱護鳠韄頀鱯鸌花芲埖婲椛硴&amp;#34; , 
 &amp;#34;H糀誮錵蘤华哗姡骅铧滑猾嘩撶璍螖鏵驊鷨化划杹画话崋桦婳畫嬅畵話劃摦槬樺嫿澅諙諣黊繣蘳怀徊淮槐褢踝懐褱懷櫰耲蘹坏壊壞蘾欢歓鴅嚾懽獾歡貛讙驩还环峘洹荁桓萈萑堚寏絙雈羦貆&amp;#34; , 
 &amp;#34;H锾阛寰缳環豲鍰鹮糫繯轘闤鬟睆缓緩攌幻奂肒奐宦唤换浣涣烉患梙焕逭喚嵈愌換渙痪煥瑍豢漶瘓槵鲩擐澣瞣藧鯇鯶鰀巟肓荒衁塃慌皇偟凰隍黃黄喤堭媓崲徨惶湟葟遑楻煌瑝墴潢獚锽熿璜&amp;#34; , 
 &amp;#34;H篁艎蝗癀磺穔諻簧蟥鍠餭鳇趪鐄騜鰉鱑鷬怳恍炾宺晃晄奛谎幌愰詤縨謊櫎皩兤滉榥曂皝鎤灰灳诙咴恢拻挥洃虺晖烣珲豗婎媈揮翚辉隓暉楎琿禈詼幑睳噅噕翬輝麾徽隳瀈鰴囘回囬佪廻廽恛&amp;#34; , 
 &amp;#34;H洄茴迴烠逥痐蛔蛕蜖鮰悔螝毇檓燬譭卉屷汇会讳泋哕浍绘芔荟诲恚恵烩贿彗晦秽喙惠絵缋翙阓匯彙彚毀毁滙詯賄僡嘒蔧誨圚寭慧憓暳槥潓蕙徻橞獩璤薈薉諱頮檅檜燴篲藱餯嚖懳瞺穢繢蟪&amp;#34; , 
 &amp;#34;H櫘繪翽譓闠鐬靧譿顪昏昬荤婚涽阍惽棔睧睯閽忶浑馄渾魂繉鼲诨俒倱圂掍混焝溷慁觨諢吙耠锪劐鍃豁攉騞佸活秮火伙邩钬鈥夥沎或货咟俰捇眓获剨祸貨惑旤湱禍嗀奯濩獲霍檴謋穫镬嚯瀖&amp;#34; , 
 &amp;#34;H耯藿蠖嚿曤臛癨矐鑊夻行砉圜&amp;#34; , 
 &amp;#34;J皀髉畟筴簎笒覘樔伡俥鋤雛處諔堲蠀覿茤岋紇裓構颳夬叏獷臩臦昋鱖妎悎饸紅鵍丌讥击刉叽饥乩刏圾机玑肌芨矶鸡枅咭迹剞唧姬屐积笄飢基绩喞嵆嵇犄筓缉赍勣嗘畸跻鳮僟箕銈嘰撃槣樭&amp;#34; , 
 &amp;#34;J畿稽賫躸齑墼憿機激璣積錤隮磯簊績羁賷櫅耭雞譏韲鶏譤癪躋鞿鷄齎羇虀鑇覉鑙齏羈鸄覊亼及伋吉岌彶忣汲级即极亟佶郆卽叝姞急狤皍笈級揤疾觙偮卙庴脨谻戢棘極殛湒集塉嫉愱楫蒺蝍&amp;#34; , 
 &amp;#34;J趌辑槉耤膌銡嶯潗瘠箿蕀蕺鞊鹡橶檝螏輯襋蹐鍓艥籍轚鏶霵鶺鷑雦雧几己丮妀犱泲虮挤脊掎鱾幾戟嵴麂魢撠擠穖彑旡计记伎纪坖妓忌技芰芶际剂季哜垍峜既洎济紀茍計剤紒继觊記偈寂寄&amp;#34; , 
 &amp;#34;J徛悸旣梞祭惎臮葪兾痵継蓟裚跡際墍暨漃漈禝稩穊誋跽霁鲚暩稷諅鲫冀劑曁穄薊襀髻檕繋罽覬鮆檵蹟鵋齌廭懻癠糭蘎骥鯚瀱繼蘮鱀蘻霽鰶鰿鱭驥加夹抸佳泇迦枷毠浃珈家痂梜笳耞袈猳葭&amp;#34; , 
 &amp;#34;J跏犌腵鉫嘉镓糘豭貑鎵麚圿扴岬郏荚郟恝莢戛铗戞蛱颊蛺跲餄鋏頬頰鴶鵊甲玾胛斚贾钾婽斝椵賈鉀榎槚瘕檟价驾架假嫁幏榢稼駕嗧戋奸尖幵坚歼间冿戔肩艰姦姧兼监堅惤猏笺菅菺湔牋犍&amp;#34; , 
 &amp;#34;J缄葌葏間搛椷煎瑊睷缣蒹箋樫熞緘蕑蕳鲣鹣熸篯縑鋻艱鞬馢麉瀐鞯殱礛覸鵳瀸殲籛韀鰹囏虃韉囝拣枧俭柬茧倹挸捡笕减剪检湕趼揀検減睑硷裥詃锏弿瑐简絸谫彅戩戬碱儉翦檢藆襇襉謇蹇&amp;#34; , 
 &amp;#34;J瞼簡繭謭鬋鰎鹸瀽蠒鐗鐧鹻譾襺鹼见件侟建饯剑洊牮荐贱俴健剣涧珔舰剱徤渐谏釼寋旔楗毽溅腱臶践賎鉴键僭榗劍劎墹澗箭糋諓賤趝踐踺劒劔橺薦鍵餞瞷磵礀螹鍳擶繝覵艦轞鑑鑒鑬鑳江&amp;#34; , 
 &amp;#34;J姜将茳浆畕豇葁翞僵漿螀壃缰薑橿殭螿鳉疅礓疆繮韁鱂讲奖桨傋蒋奨奬蔣槳獎耩膙講顜匞匠夅弜杢降洚绛弶袶絳畺酱摾滰嵹犟糡醤糨醬櫤謽艽芁交郊姣娇峧浇茭骄胶椒焦蛟跤僬嘄虠鲛嬌&amp;#34; , 
 &amp;#34;J嶕嶣憍膠蕉膲礁穚鮫鹪簥蟭鐎鷦鷮櫵臫角佼挢狡绞饺晈笅皎矫脚铰搅筊剿勦敫煍腳賋摷暞踋鉸餃儌劋撹徼敽敿缴曒璬矯皦鵤孂纐攪灚鱎叫呌挍訆珓轿较敎教窖滘嘂嘦斠漖酵噍嬓獥藠趭轎&amp;#34; , 
 &amp;#34;J醮譥皭釂阶疖皆接掲痎秸階喈嗟堦媘揭脻街煯稭鞂蝔擑癤鶛孑尐节讦刦刧劫岊昅刼劼杰衱诘拮洁结迼桀桝莭訐婕崨捷袺傑結颉嵥楶滐睫節蜐詰鉣魝截榤碣竭蓵鲒潔羯誱踕幯嶻擮礍鍻巀櫭&amp;#34; , 
 &amp;#34;J蠞蠘蠽姐毑媎解飷檞丯介岕庎忦戒芥屆届斺玠界畍疥砎衸诫借蚧徣堺楐琾蛶骱犗誡褯魪藉巾今斤钅兓金釒津矜砛衿觔珒紟惍琎堻琻筋璡鹶黅襟仅卺巹紧堇菫僅谨锦嫤廑漌盡緊蓳馑槿瑾錦&amp;#34; , 
 &amp;#34;J謹饉劤尽劲妗近进侭枃勁浕荩晉晋浸烬赆祲進煡缙寖搢溍禁靳瑨僸凚殣觐儘噤縉賮嚍壗嬧濜藎燼璶覲贐齽坕京泾经茎亰秔荆荊婛惊旌旍猄経菁晶稉腈睛粳經兢精聙橸鲸鵛鯨鶁麖鼱驚麠井&amp;#34; , 
 &amp;#34;J丼阱刭宑汫汬肼剄穽颈景儆幜憬璄憼暻燝璟璥頸蟼警妌净弪径迳浄胫凈弳徑痉竞逕婙婧桱梷淨竟竫敬痙傹靖境獍誩静頚曔镜靜瀞鏡競竸冋坰扃埛絅駉駫蘏冏囧迥侰炯逈浻烱煚窘颎綗僒煛&amp;#34; , 
 &amp;#34;J熲澃燛褧蘔丩勼纠朻究糺鸠糾赳阄萛啾揪揫鬏鬮九久乆乣奺汣杦灸玖舏韭紤酒镹韮匛旧臼咎疚柩柾倃桕厩救就廄匓舅僦廏廐慦殧舊鹫鯦麔匶齨鷲欍凥抅匊居拘泃狙苴驹倶挶疽痀罝陱娵婅&amp;#34; , 
 &amp;#34;J婮崌掬梮涺椐琚腒锔裾雎艍蜛諊踘鋦駒鴡鞠鞫鶋局泦侷狊桔毩淗焗菊郹椈毱湨犑輂粷躹閰橘檋駶鵙蹫鵴巈蘜鶪驧咀沮举矩莒挙椇筥榉榘蒟龃聥舉踽擧櫸欅襷句巨讵姖岠怇拒洰苣邭具拠昛&amp;#34; , 
 &amp;#34;J歫炬秬钜俱倨冣剧粔耟蚷袓埧埾惧据詎距焣犋鉅飓虡豦锯愳窭聚駏劇勮屦踞鮔壉懅據澽遽鋸屨颶簴躆醵懼爠姢娟捐涓裐鹃勬鋑镌鎸鵑鐫蠲卷呟帣埍菤锩臇錈奆劵倦勌桊狷绢隽淃瓹眷鄄睊&amp;#34; , 
 &amp;#34;J絭罥睠慻蔨餋羂噘撅撧屩屫亅孒孓决刔氒诀抉芵玦玨挗珏砄绝虳觉倔欮崛掘斍桷殌覐觖訣赽趹厥絕絶覚趉鈌劂瑴谲嶡嶥憰熦爴獗瘚蕝蕨鴂鴃憠橛橜镼爵臄镢蟨蟩爑譎蹶蹷嚼矍覺鐝灍爝觼&amp;#34; , 
 &amp;#34;J彏戄攫玃鷢欔矡龣貜钁军君均汮袀軍钧莙蚐桾皲菌鈞碅筠皸皹覠銁銞鲪麇鍕鮶呁俊郡陖埈峻捃晙浚馂骏珺畯竣箟蜠儁寯懏餕燇駿鵔鵕鵘纟挟廴&amp;#34; , 
 &amp;#34;K錒嵦濭骯奟喫噄鉺朏胐阬槀稾藳溝絓鰥卝丱硄廣胿膭歸楇鉿妔薧蚵毼袔齁恗搰華磆蕐會澮璯餛秳漷監譼槛檻捁撟悈脛踁駃咔咖喀卡佧垰胩裃鉲开奒揩衉锎鐦凯剀垲恺闿铠凱剴慨蒈塏愷楷&amp;#34; , 
 &amp;#34;K輆暟锴鍇鎧闓颽忾炌欬烗勓嘅鎎乫刊栞勘龛堪戡龕冚坎侃砍莰偘惂塪輡竷轗看衎崁墈阚瞰磡矙忼砊粇康嫝嵻慷漮槺穅糠躿鏮鱇扛摃亢伉匟邟囥抗犺闶炕钪鈧閌尻髛攷考拷洘栲烤铐犒銬鲓&amp;#34; , 
 &amp;#34;K靠鮳鯌匼坷苛柯牁珂科胢轲疴趷钶嵙棵痾萪軻颏搕犐稞窠鈳榼薖颗樖瞌磕蝌頦醘顆髁礚壳咳翗嶱可岢炣渇嵑敤渴克刻剋勀勊客峇恪娔尅课堁氪骒缂嗑愙溘锞碦緙課錁礊騍肎肯肻垦恳啃豤&amp;#34; , 
 &amp;#34;K墾錹懇掯裉褃劥吭坑硁牼铿硻誙銵鍞鏗巪乬唟厼怾空倥埪崆悾硿箜躻錓鵼孔恐控鞚廤抠芤眍剾彄瞘口劶叩扣怐敂冦宼寇釦窛筘滱蔲蔻瞉簆鷇刳郀枯哭桍堀崫圐跍窟骷鮬狜苦楛库俈绔庫秙&amp;#34; , 
 &amp;#34;K焅袴喾絝裤瘔酷褲嚳夸姱舿侉咵垮銙挎胯跨骻蒯擓巜凷圦块快侩郐哙狯脍塊筷鲙儈鄶廥獪膾旝糩鱠宽寛寬髋鑧髖梡款窽窾匡劻诓邼匩哐恇洭筐筺誆軭狂狅诳軖軠誑鵟夼儣懭邝圹纩况旷岲&amp;#34; , 
 &amp;#34;K況矿昿贶框眖砿眶絋絖貺軦鉱鋛鄺壙黋懬曠爌矌礦穬纊鑛亏刲岿悝盔窥聧窺虧闚顝蘬奎晆逵鄈頄馗喹揆葵骙戣暌楏楑魁睽蝰頯櫆藈鍨鍷騤夔蘷虁躨卼傀煃跬頍蹞尯匮欳喟媿愦愧溃蒉馈匱&amp;#34; , 
 &amp;#34;K嘳嬇憒篑聩聭蕢樻殨餽簣聵籄鐀鑎坤昆晜堃堒婫崐崑猑菎裈焜琨髠裩锟髡鹍尡潉蜫褌髨熴瑻醌錕鲲臗騉鯤鵾鶤悃捆阃壸梱祵硱稇裍壼稛綑閫閸困涃睏扩拡括挄栝桰筈萿葀蛞阔廓頢濶闊鞟&amp;#34; , 
 &amp;#34;K韕懖霩鞹鬠穒&amp;#34; , 
 &amp;#34;L冫勑粚誺銐寵娕坔釘詻鄜膚鬴茖蛒鎘鉻羮篢睔腂蘫谾瘣暕撿諫倞靓靚牞摎樛畂寠窶垃拉柆啦翋菈邋旯砬揦磖喇藞嚹剌溂腊揧楋瘌蜡蝋辢辣蝲臈攋爉臘鬎櫴瓎镴鯻蠟鑞鞡来來俫倈崃徕涞莱&amp;#34; , 
 &amp;#34;L郲婡崍庲徠梾淶猍萊逨棶琜筙铼箂錸騋鯠鶆麳唻赉睐睞赖賚濑賴頼顂癞鵣瀨瀬籁藾癩襰籟兰岚拦栏婪嵐葻阑蓝谰澜褴儖斓篮燣藍襕镧闌璼襤譋幱攔瀾灆籃繿蘭斕欄礷襴囒灡籣欗讕躝襽鑭&amp;#34; , 
 &amp;#34;L钄韊览浨揽缆榄漤罱醂壈懒覧擥嬾懶孄覽孏攬欖爦纜烂滥燗嚂濫爁爛爤瓓灠糷啷勆郎郞欴狼莨嫏廊桹琅蓈榔瑯硠稂锒筤艆蜋郒螂躴鋃鎯駺悢朗阆朖烺塱蓢樃誏閬朤埌浪蒗唥捞粩撈劳労牢&amp;#34; , 
 &amp;#34;L狫窂哰唠崂浶勞痨铹僗嶗憥朥癆磱簩蟧醪鐒顟髝老佬咾姥恅荖栳珯硓铑蛯銠潦橑鮱轑涝烙嗠耢酪嫪憦澇橯耮軂仂阞乐叻忇扐氻艻玏泐竻砳勒楽韷簕鳓鰳饹餎雷嫘缧蔂樏畾檑縲镭櫑瓃羸礧&amp;#34; , 
 &amp;#34;L纍罍蘲鐳轠壨鑘靁虆鱩欙纝鼺厽耒诔垒塁絫傫誄磊蕌磥蕾儡壘癗藟櫐矋礨灅蠝蘽讄儽鑸鸓肋泪洡类涙淚累酹銇頛頪擂錑攂礌颣類纇蘱禷嘞脷塄棱楞碐稜踜薐冷倰堎愣睖唎刕厘剓梨狸离荲&amp;#34; , 
 &amp;#34;L莉骊悡梸犁菞喱棃犂鹂剺漓睝筣缡艃蓠蜊嫠孷樆璃盠竰糎蔾褵鋫鲡黎篱縭罹錅蟍謧醨嚟藜邌離鯏鏫鯬鵹黧囄灕蘺蠡蠫孋廲劙鑗穲籬驪鱺鸝礼李里俚峛哩娌峲浬逦理裡锂粴裏豊鋰鲤澧禮鯉&amp;#34; , 
 &amp;#34;L蟸醴鳢邐鱧欚力历厉屴立吏朸丽利励呖坜沥苈例岦戾枥疠苙隶俐俪栃栎疬砅茘荔赲轹郦娳悧栗栛栵涖猁珕砺砾秝莅唳婯悷琍笠粒粝蚸蛎傈凓厤棙痢蛠詈跞雳塛慄搮溧蒚蒞鉝鳨厯厲暦歴瑮&amp;#34; , 
 &amp;#34;L綟蜧勵曆歷篥隷鴗巁檪濿癘磿隸鬁儮曞櫔爄犡禲蠇嚦壢攊瀝瓅礪藶櫪爏瓑皪盭礫糲蠣儷癧礰鷅麜囇轢欐讈轣攭瓥靂鱱靋瓈俩倆嫾奁连帘怜涟莲連梿联裢亷嗹廉慩漣蓮匲奩覝劆匳噒憐磏聨&amp;#34; , 
 &amp;#34;L聫褳鲢濂濓縺翴聮薕螊櫣聯臁蹥謰鎌镰簾蠊鬑鐮鰱籢籨敛琏脸裣摙槤璉蔹嬚斂歛臉鄻襝羷练娈炼恋浰殓堜媡湅萰链僆楝煉瑓潋練澰錬殮鍊鏈瀲鰊戀纞簗良俍凉梁涼椋辌粮粱墚綡踉樑輬糧&amp;#34; , 
 &amp;#34;L両两兩唡啢掚脼裲緉蜽魉魎亮哴谅辆喨晾湸量煷輌諒輛鍄蹽辽疗聊僚寥嵺廖憀膋嘹嫽寮嶚嶛憭撩敹獠缭遼暸燎璙窷膫竂镣鹩屪廫簝蟟豂賿蹘爎鐐髎飉鷯钌釕鄝蓼爒镽了尥炓料尞撂瞭咧毟&amp;#34; , 
 &amp;#34;L挘埓列劣冽劽姴峢挒洌茢迾埒浖烈烮捩猎猟蛚裂煭睙聗趔巤颲儠鮤鴷擸獵犣躐鬛鬣鱲邻林临啉崊惏淋晽琳粦痳碄箖粼鄰隣嶙潾獜遴斴暽燐璘辚霖瞵磷臨繗翷麐轔壣瀶鏻鳞驎麟鱗菻亃稟僯&amp;#34; , 
 &amp;#34;L凛凜撛廩廪懍懔澟檁檩癛癝顲吝恡悋赁焛賃蔺橉甐膦閵疄藺蹸躏躙躪轥拎伶刢灵囹坽夌姈岭岺彾泠狑苓昤朎柃玲瓴凌皊砱秢竛铃陵鸰婈崚掕棂淩琌笭紷绫羚翎聆舲菱蛉衑祾詅跉軨蓤裬鈴&amp;#34; , 
 &amp;#34;L閝零龄綾蔆輘霊駖澪蕶錂霗魿鲮鴒鹷燯霛霝齢瀮酃鯪孁蘦齡櫺醽靈欞爧麢龗阾袊领領嶺令另呤炩溜熘刘沠畄浏流留旈琉畱硫裗媹嵧旒蒥蓅遛馏骝榴瑠飗劉瑬瘤磂镏駠鹠橊璢疁镠癅蟉駵嚠&amp;#34; , 
 &amp;#34;L懰瀏藰鎏鎦餾麍鏐飀鐂騮飅鰡鶹驑柳栁桞珋桺绺锍綹熮罶鋶橮羀嬼六翏塯廇澑磟鹨蹓霤雡飂鬸鷚瓼甅囖龙屸咙泷茏昽栊珑胧眬砻笼聋隆湰嶐槞漋癃窿篭嚨巃巄蘢鏧霳曨朧櫳爖瓏矓礱礲襱&amp;#34; , 
 &amp;#34;L籠聾蠪蠬龓豅躘鑨靇鸗陇垄垅拢儱隴壟壠攏竉哢梇硦徿贚娄偻婁喽溇蒌僂楼嘍廔慺蔞遱樓熡耧蝼瞜耬艛螻謱軁髅鞻髏嵝搂塿嶁摟漊甊篓簍陋屚漏瘘镂瘺瘻鏤露噜撸嚕擼卢庐芦垆枦泸炉栌&amp;#34; , 
 &amp;#34;L胪轳舮鸬玈舻颅鈩鲈魲盧嚧壚廬攎瀘獹璷蘆櫨爐瓐臚矑籚纑罏艫蠦轤鑪顱髗鱸鸕黸卤虏挔捛掳鹵硵鲁虜塷滷蓾樐澛魯擄橹磠镥瀂櫓氌艣鏀艪鐪鑥圥甪陆侓坴彔录峍勎赂辂陸娽淕淥渌硉菉&amp;#34; , 
 &amp;#34;L逯鹿椂琭祿禄僇剹勠滤盝睩碌稑賂路塶廘摝漉箓粶蔍戮樚熝膔膟觮趢踛辘醁潞穋蕗錄録錴璐簏螰鴼濾簶蹗轆騄鹭簬簵鏕鯥鵦鵱麓鏴騼籙觻虂鷺氇驴闾榈閭馿膢櫚藘曥鷜驢吕呂侣郘侶旅梠&amp;#34; , 
 &amp;#34;L焒祣稆铝屡絽缕屢膂膐褛鋁履褸儢穞縷穭寽垏律哷虑率绿嵂氯葎綠緑慮箻勴繂櫖爈鑢孪峦挛栾鸾脔滦銮鵉圝奱孌孿巒攣曫欒灓羉臠圞灤虊鑾癴癵鸞卵乱釠亂掠略畧锊圙鋝鋢抡掄仑伦囵沦&amp;#34; , 
 &amp;#34;L纶侖轮倫陯圇婨崘崙惀淪菕棆腀碖綸蜦踚輪磮錀鯩稐耣论埨溣論捋頱囉罗啰猡脶萝逻椤腡锣箩骡镙螺羅覶鏍儸覼騾玀蘿邏欏鸁籮鑼饠驘剆倮砢蓏裸躶瘰蠃臝攞曪癳泺峈洛络荦骆珞笿絡落&amp;#34; , 
 &amp;#34;L摞漯犖雒駱鮥鵅纙鱳&amp;#34; , 
 &amp;#34;M絔硥苾牑訬仯哋尒尓爾坆呒撫羙秏狢貈貉湏惛殙貇氂犛厸龍龒嘸呣妈媽嬤嬷麻痲嫲蔴犘蟆蟇马犸玛码蚂馬溤獁遤瑪碼螞鎷鷌鰢亇杩祃閁骂唛傌睰嘜榪禡罵駡礣鬕吗嗎嘛埋霾买荬買嘪蕒鷶&amp;#34; , 
 &amp;#34;M劢迈佅売麦卖脉脈麥衇勱賣邁霡霢颟顢姏悗蛮慲摱馒樠瞒瞞鞔饅鳗鬗鬘鰻蠻屘満睌满滿螨襔蟎鏋矕曼僈谩墁幔慢漫獌缦蔄蔓熳澷镘縵蟃謾鏝蘰牤邙吂忙汒芒杗杧盲厖恾笀茫哤娏浝牻硭釯&amp;#34; , 
 &amp;#34;M铓痝蛖鋩駹蘉莽莾茻壾漭蟒蠎匁猫貓毛矛枆牦茅旄渵軞酕蛑锚緢髦蝥錨蟊鶜冇卯戼峁泖茆昴铆笷蓩鉚冃皃芼冐茂冒眊贸耄袤覒媢帽貿鄚愗暓楙毷瑁瞀貌鄮蝐懋唜庅嚒濹嚰么癦沒没枚玫苺&amp;#34; , 
 &amp;#34;M栂眉脄莓梅珻脢郿堳媒嵋湄湈猸睂葿楣楳煤瑂禖腜塺槑酶镅鹛鋂霉徾鎇矀攗蘪鶥攟黴毎每凂美挴浼媄嵄渼媺镁嬍燘躾鎂黣妹抺沬昧祙袂眛媚寐痗跊鬽煝睸魅篃蝞嚜椚门扪玣钔門閅捫菛璊&amp;#34; , 
 &amp;#34;M穈鍆虋闷焖悶暪燜懑懣们們掹擝氓甿虻冡庬罞萌萠夢溕盟甍儚橗瞢蕄蝱鄳鄸幪懞濛獴曚朦檬氋矇礞鯍艨鹲矒靀饛顭鸏勐猛瓾蒙锰艋蜢錳懵蠓鯭鼆孟梦夣懜霥踎咪瞇冞弥祢迷猕谜蒾詸謎醚&amp;#34; , 
 &amp;#34;M擟糜縻麊麋靡獼麛爢戂攠蘼醾醿鸍釄米羋芈侎弭洣敉粎脒眯渳葞蝆蔝銤孊灖糸汨宓泌觅峚祕宻秘密淧覓覔幂谧塓幎覛嘧榓滵漞熐蔤蜜鼏冪樒幦濗藌謐櫁簚羃芇眠婂绵媔棉綿緜臱蝒嬵檰櫋&amp;#34; , 
 &amp;#34;M矈矊矏丏汅免沔黾俛勉眄娩偭冕勔喕愐湎缅葂腼緬鮸靣面糆麪麫麺麵喵苗媌描瞄鹋嫹鶓鱙杪眇秒淼渺缈篎緲藐邈妙庙竗庿廟吀咩哶孭灭搣滅蔑薎鴓幭懱瀎篾櫗蠛衊鑖鱴瓱民垊姄岷怋旻旼&amp;#34; , 
 &amp;#34;M玟苠珉盿冧罠崏捪琘琝缗暋瑉痻碈鈱緍緡錉鍲皿冺刡闵抿泯勄敃闽悯敏笢笽湣閔愍敯黽閩僶慜憫潣簢鳘蠠鰵名明鸣洺眀茗冥朙眳铭鄍嫇溟猽蓂暝榠銘鳴瞑螟覭佲姳凕慏酩命掵詺谬缪繆謬&amp;#34; , 
 &amp;#34;M摸嚤尛谟嫫馍摹模膜麼麽摩魹橅磨糢謨謩擵饃嚩蘑髍魔劘饝抹懡麿末劰圽妺怽歿殁沫茉陌帞昩枺皌眜眿砞秣莈莫眽粖絈袹蛨貃嗼塻寞漠蓦貊銆墨嫼暯瘼瞐瞙镆魩黙縸默貘藦蟔鏌爅驀礳纆&amp;#34; , 
 &amp;#34;M耱乮哞牟侔劺恈洠眸谋鉾謀鍪鴾麰某母毪獏氁亩牡姆拇峔牳畆畒胟畝畞砪畮鉧踇木仫目凩沐狇坶炑牧苜毣莯蚞钼募萺雮墓幕幙慔楘睦鉬慕暮艒霂穆鞪旀丆椧渑&amp;#34; , 
 &amp;#34;N懝抝拗秅莀袲唸毭咹児兒耏聏峊廾嫨跈聻茮澆涳巙崀尦竜袮彌镾濔瀰乜樢拏拿誽镎鎿乸哪雫内那吶妠纳肭娜衲钠納袦捺笝豽軜貀嗱蒳靹魶腉熋孻乃奶艿氖疓妳廼迺倷釢嬭奈柰耐萘渿鼐褦&amp;#34; , 
 &amp;#34;N螚錼囡男抩枏枬侽南娚畘莮难喃遖暔楠煵諵難赧揇湳萳腩蝻戁婻囔乪嚢囊鬞馕欜饢擃曩攮灢儾齉孬檂呶怓挠峱硇铙猱蛲詉碙嶩夒鐃巎獿垴恼悩脑匘脳堖惱嫐瑙腦碯闹婥淖閙鬧讷呐眲訥呢&amp;#34; , 
 &amp;#34;N馁腇餒鮾鯘氝焾嫩能莻鈪銰啱妮尼坭怩泥籾倪屔秜郳铌埿婗淣猊蚭棿跜鈮蜺觬貎霓鲵鯢麑齯臡伱伲你拟抳狔苨柅旎晲馜儞隬擬薿檷鑈氼迡昵胒逆匿痆眤堄惄嫟愵溺睨腻暱縌膩嬺拈年秊哖&amp;#34; , 
 &amp;#34;N秥鲇鮎鲶鵇黏鯰捻辇撚撵碾輦簐攆躎卄廿念姩埝娘嬢酿醸釀鸟茑袅嫋裊蔦嬝褭嬲尿脲捏揑帇圼苶枿陧涅聂臬啮惗隉敜嗫嵲踂摰踗踙镊镍嶭篞臲錜颞蹑鎳闑孼孽櫱籋蘖齧巕糱糵蠥囓讘躡鑷&amp;#34; , 
 &amp;#34;N顳脌囜您拰宁咛拧狞柠聍寍寕寜寧儜凝嚀嬣擰獰薴檸聹鑏鬡鸋橣矃佞侫泞甯寗澝濘妞牛牜忸扭沑狃纽杻炄钮紐鈕靵农侬哝浓脓秾農儂辳噥憹濃蕽禯膿穠襛醲欁繷弄挊挵癑齈羺譨啂槈耨鎒&amp;#34; , 
 &amp;#34;N鐞譳奴孥驽笯駑伮努弩砮胬怒傉搙女钕籹釹衂恧朒衄疟虐瘧奻渜暖煗餪硸黁燶郍挪梛傩搻儺橠诺喏掿逽搦锘榒稬諾糑懦懧糥穤糯恁蔫&amp;#34; , 
 &amp;#34;O吽摳噢哦筽夞乯鞰讴欧殴瓯鸥塸歐熰甌膒鴎櫙藲鏂鷗吘呕偶腢耦蕅藕怄沤慪漚&amp;#34; , 
 &amp;#34;P钯鈀跁罷猈螌褩闆湴牓棓徬鎊剝襃铇袌鉋鮑琲絣痭琣逬跰螕鎞粃枈痺辟稫箆鞞猵萹拚徧緶辯骉蔈颮麃藨謤穮驃驫摽汃砏璸鉼碆磻犻苩瓟桲淿湐猼馞嚗髆蚾獛鵏吥荹鈈郶茷籓膰趽彷衯夆馮&amp;#34; , 
 &amp;#34;P摓垺妚尃豧巿襆襥脯蜅秿鈲窌攈脟濼尨眫冖覕屰妑皅趴舥啪葩杷爬耙琶筢潖帊帕怕袙拍俳徘排猅棑牌箄輫簰犤哌派湃蒎鎃磗眅畨潘攀爿柈盘跘媻幋蒰搫槃磐縏蹒瀊蟠蹣鎜鞶坢冸判沜泮炍&amp;#34; , 
 &amp;#34;P叛牉盼畔袢詊溿頖鋬鵥襻鑻乓汸沗肨胮雱滂膖霶厐庞逄旁舽嫎篣螃鳑龎龐鰟蠭嗙耪覫髈炐胖抛拋脬刨咆垉庖狍炮炰爮袍匏蚫軳鞄褜麅跑奅泡疱皰砲萢麭礟礮呸怌肧柸胚衃醅阫陪陫培毰赔&amp;#34; , 
 &amp;#34;P锫裴裵賠錇俖伂沛佩帔姵斾旆浿珮配笩蓜辔馷嶏霈轡喷噴濆歕瓫盆湓葐呠翉翸喯匉怦抨泙恲胓砰梈烹硑軯閛漰嘭駍磞芃朋挷竼倗莑堋弸彭棚椖傰塜塳搒漨硼稝蓬鹏槰樥熢憉澎輣篷膨錋韸&amp;#34; , 
 &amp;#34;P髼蟚蟛鬅纄韼鵬騯鬔鑝捧淎皏剻掽椪碰踫浌巼闏乶喸丕伓伾批纰邳坯怶披抷炋狉狓砒悂秛秠紕铍旇翍耚豾鈚鈹鉟銔劈磇駓髬噼錃錍魾憵礔礕闢霹皮阰芘岯枇毞肶毗毘疲笓蚍郫陴啤埤崥蚽&amp;#34; , 
 &amp;#34;P豼椑焷琵脾腗榌鲏罴膍蜱隦魮壀鮍篺螷貔簲羆鵧朇鼙蠯匹庀仳圮苉脴痞銢諀鴄擗噽癖嚭屁淠渒揊媲嫓睤睥潎僻澼甓疈譬鷿鸊片囨偏媥犏篇翩鶣骈胼腁楄楩賆諚骿蹁駢騈覑谝貵諞骗魸騗騙&amp;#34; , 
 &amp;#34;P剽彯漂缥飘磦旚縹翲螵犥飃飄魒瓢薸闝殍瞟篻醥皫顠票僄勡嘌嫖徱慓氕撇撆暼瞥丿苤鐅嫳姘拼礗穦馪驞玭贫貧琕嫔频頻嬪薲嚬矉颦顰品榀朩牝汖娉聘乒甹俜涄砯艵竮頩平评凭呯坪岼苹郱&amp;#34; , 
 &amp;#34;P屏帡枰洴玶荓娦瓶屛帲淜萍蚲塀幈焩甁缾聠蓱蛢評軿鲆凴慿箳輧憑鮃檘簈蘋钋坡岥泼娝釙颇溌酦潑醱鏺婆嘙蔢鄱皤謈櫇叵尀钷笸鉕駊廹岶迫敀昢洦珀哱烞破砶粕蒪頗魄剖颒抔抙捊掊裒箁&amp;#34; , 
 &amp;#34;P咅哣婄犃兺哛仆攴扑抪炇巬巭柨陠痡铺駇噗撲鋪擈鯆圤匍莆菩菐葡蒱蒲僕酺墣璞濮瞨穙镤贌纀鏷朴圃埔浦烳普圑溥暜谱潽樸氆諩檏镨譜蹼鐠舖舗曝&amp;#34; , 
 &amp;#34;Q摮磝朁鸧鶬鼜詧軙儭櫬趍袳創敠匚釓隑矼肐鉤扢琯矔鸛龜氿肣馯抲頜礉隺渹舙酄攲敧稘毄緝觭禨鄿鐖饑焏踖躤蟣済萕濟袷唊脥價靬鳒鰜鶼鑯揃葥漸摪彊勥焳燋湫湬蟜譑峤嶠潐噭椄疌倢偼&amp;#34; , 
 &amp;#34;Q媫蛣楬鮚荕埐嶜厪墐慬歏濅涇鶄捄趄跔鮈跼趜弆瞿鐻捲弮蚗傕鶌躩麏麕焌箘開欿歁殻揢挳硜矻誇厱熑燫艌鳥毆七迉沏妻柒倛凄栖桤缼郪娸悽戚捿桼淒萋朞期欺紪褄僛嘁慽榿槭漆緀慼磎諆&amp;#34; , 
 &amp;#34;Q霋蹊魌鏚鶈亓祁齐圻岐岓芪其奇斉歧祈肵疧竒剘斊旂耆脐蚑蚚颀埼崎帺掑淇渏猉畦萁跂軝釮骐骑棊棋琦琪祺蛴愭碁碕褀頎鬾鬿旗粸綥綦綨緕蜝蜞璂禥蕲踑螧鲯懠濝藄檱櫀簱臍騎騏鳍蘄鯕&amp;#34; , 
 &amp;#34;Q鵸鶀麒籏纃艩蠐鬐騹魕鰭玂麡乞邔企屺岂芑启呇杞玘盀唘豈起啓啔啟婍绮晵棨綮諬簯闙气讫気汔迄弃汽矵芞呮泣炁盵咠契砌荠栔訖唭欫夡愒棄湆湇葺碛摖暣甈碶噐憇器憩磜磧薺礘罊蟿掐&amp;#34; , 
 &amp;#34;Q葜拤跒酠鞐圶冾帢恰洽殎硈愘髂千仟阡奷扦汘芊迁佥岍杄汧茾竏钎拪牵粁悭蚈谸铅婜牽釺谦雃僉愆签骞鹐搴摼撁箞諐遷褰顅檶攐攑櫏簽鏲鵮攓騫鐱鬜鬝籤韆仱岒忴扲拑乹前钤歬虔钱钳乾&amp;#34; , 
 &amp;#34;Q偂掮揵軡媊鈐鉗墘榩箝銭潜橬錢黔鎆黚騝濳騚灊籖鰬浅肷淺嵰慊遣蜸潛谴缱繾譴鑓欠刋芡茜倩悓堑傔嵌棈椠皘蒨塹歉蔳儙槧篏輤篟壍嬱縴呛羌戕戗斨枪玱猐琷跄嗴椌獇腔嗆溬蜣锖嶈戧槍&amp;#34; , 
 &amp;#34;Q牄瑲羫锵篬錆蹌镪蹡鎗鏘鏹強强墙嫱蔷樯漒蔃墻嬙檣牆謒艢蘠抢羟搶羥墏摤繈襁繦炝唴熗羻兛瓩悄硗郻鄗嵪跷鄡鄥劁敲踍锹墝碻頝墽幧橇缲磽鍫鍬繑趬蹺蹻乔侨荍荞桥硚喬僑槗谯嘺嫶憔&amp;#34; , 
 &amp;#34;Q蕎鞒樵橋犞癄瞧礄藮譙趫鐈鞽顦巧釥愀髜俏诮陗峭帩窍殼翘誚髚僺撬鞘竅翹躈切苆癿茄聺且厒妾怯匧窃倿悏挈洯惬淁笡愜蛪朅箧緁锲魥篋踥穕藒鍥鯜鐑竊籡亲侵钦衾骎菳媇嵚誛嶔親顉駸&amp;#34; , 
 &amp;#34;Q鮼寴庈芩芹埁珡矝秦耹菦蚙捦琴琹禽鈙雂勤嗪溱靲噙擒斳鳹懄檎澿瘽螓懃蠄坅昑笉梫赾寑锓寝寢鋟螼吢吣抋沁唚菣揿搇撳瀙藽靑青氢轻倾卿郬圊氫淸清傾廎蜻輕鲭鑋夝甠剠勍情殑硘晴棾&amp;#34; , 
 &amp;#34;Q氰葝暒擏樈擎檠黥苘顷请庼頃漀請檾謦庆凊掅碃箐靘慶磬儬濪罄櫦宆跫銎卭邛穷穹茕桏笻筇赹惸焪焭琼舼蛩蛬煢熍睘瞏窮儝憌橩璚藑竆藭丘丠邱坵恘秋秌寈蚯媝萩楸鹙篍緧蝵穐趥鳅蟗鞦&amp;#34; , 
 &amp;#34;Q鞧蘒鰌鰍鶖龝叴囚扏犰玌朹肍求虬泅虯俅觓訄訅酋唒浗紌莍逎逑釚梂殏毬球赇釻崷巯湭皳盚遒煪絿蛷裘巰觩賕璆蝤銶醔鮂鼽鯄鵭蠤鰽搝糗区曲佉匤岖诎阹驱坥屈岴抾浀祛胠袪區蛆躯筁粬&amp;#34; , 
 &amp;#34;Q蛐詘趋嶇駆憈敺誳駈麹髷趨麯軀麴黢驅鰸鱋佢劬斪朐菃衐鸲淭渠絇葋軥蕖璖磲螶鴝璩翵蟝鼩蘧匷忂灈戵欋氍籧臞癯蠷衢躣蠼鑺鸜取竘娶紶詓竬龋齲厺去刞呿迲郥耝阒觑趣閴麮闃覰覷鼁覻&amp;#34; , 
 &amp;#34;Q峑悛圈圏棬駩騡鐉全权佺诠姾泉洤荃拳牷辁啳埢婘惓痊硂铨湶犈筌絟腃葲搼楾瑔觠詮輇蜷銓権踡縓醛闎鳈鬈孉巏鰁權齤蠸颧顴犬汱畎烇绻綣虇劝券巻牶椦勧韏勸炔缺蒛瘸却埆崅悫雀硞确&amp;#34; , 
 &amp;#34;Q阕塙搉皵阙鹊愨榷墧慤毃確趞燩闋礐闕鵲礭夋囷峮逡宭帬裙羣群裠郄&amp;#34; , 
 &amp;#34;R吺兊兌熯卪坈繚髳挐鈉柟蟯臑抐內涊蹨孃菍莥獳檽蹃亽罖囕呥肰衻袇蚦袡蚺然髥嘫髯燃繎冄冉姌苒染珃媣蒅穣瀼獽禳瓤穰躟鬤壌嚷壤攘爙让懹譲讓荛饶桡橈襓饒犪扰娆隢擾绕遶繞惹热熱&amp;#34; , 
 &amp;#34;R人仁壬忈朲忎秂芢鈓魜銋鵀忍荏栠栣荵秹稔綛躵刃刄认仞仭讱任屻扨纫妊杒牣纴肕轫韧饪姙紉衽紝訒軔梕袵絍腍靭靱韌飪認餁扔仍辸礽芿陾日驲囸釰鈤馹戎肜栄狨绒茙茸荣容峵毧烿媶嵘&amp;#34; , 
 &amp;#34;R絨羢嫆搈搑摉榵溶蓉榕榮熔瑢穁蝾褣镕氄縙融螎駥髶嬫嶸爃鎔瀜曧蠑冗宂傇軵穃厹禸柔粈媃揉渘葇瑈腬糅蝚蹂輮鍒鞣瓇騥鰇鶔楺煣韖肉宍嶿邚如侞帤茹桇袽铷渪筎蒘銣蕠儒鴑嚅嬬孺濡薷&amp;#34; , 
 &amp;#34;R鴽曘燸襦蠕颥醹顬鱬汝肗乳辱鄏入扖込杁洳嗕媷溽缛蓐鳰褥縟擩堧撋壖阮朊软耎偄軟媆愞瑌腝嫰碝緛蝡輭瓀礝桵甤緌蕤蕊蕋橤繠蘂蘃芮枘蚋锐瑞睿叡壡闰润閏閠潤橍叒若偌弱鄀婼渃焫楉&amp;#34; , 
 &amp;#34;R嵶蒻箬篛爇鰙鰯鶸&amp;#34; , 
 &amp;#34;S鉍灬杓攃偲纔參叄叅喰傪穇懆鄵拺笧粣鎈褨剎摻攙摌顫塲場綝乗娍匙飭埫醻敊猭漺輴縒棇楤漎憁缞縗鎝単單擔伔僤宲鍉遞遰挕阇闍陏蘴棴丨鞨咶鏸韢閄靃濈櫼帴菨嫅潏麗攦療蕯瀧氀稤蠰&amp;#34; , 
 &amp;#34;S娞淰掱忯圱圲凵廧薔鐰韒鞩嫀殸棯葚挼仨桬撒洒訯靸潵卅飒脎萨摋隡馺颯薩櫒栍毢愢揌塞毸腮嘥噻鳃顋嗮赛僿賽簺虄三弎叁毵毶厁毿犙鬖壭伞傘散糁糂馓橵糝糣糤繖鏒饊俕閐桒桑槡嗓搡&amp;#34; , 
 &amp;#34;S磉褬颡鎟顙丧喪掻慅搔溞骚缫臊鳋颾騒鰠鱢扫掃嫂埽瘙氉矂髞色栜涩啬渋铯歮琗嗇瑟歰銫澁懎擌濇濏瘷穑澀璱瀒穡繬穯轖鏼譅飋裇聓森槮襂僧鬙閪縇杀沙纱乷砂唦挱猀粆紗莎铩痧硰蔱裟&amp;#34; , 
 &amp;#34;S樧魦鲨閷鎩鯊鯋繺傻儍繌倽唼啥帹萐喢歃煞翜翣閯霎筛篩簁簛晒曬山彡邖圸删刪杉杣芟姗衫钐埏狦珊舢痁脠軕笘閊跚剼搧嘇幓煽蔪潸澘曑檆膻鯅羴羶闪陕炶陝閃晱煔睒熌覢讪汕疝苫扇訕&amp;#34; , 
 &amp;#34;S赸傓善椫銏骟僐鄯墠墡缮嬗擅敾樿膳磰謆赡繕蟮譱贍鐥饍騸鳝灗鱔伤殇商觞傷墒慯滳蔏殤熵螪觴謪鬺裳垧扄晌赏賞鑜丄上仩尙尚恦绱緔弰捎梢烧焼稍旓筲艄蛸輎蕱燒髾鮹勺芍柖玿韶少劭&amp;#34; , 
 &amp;#34;S卲邵绍哨娋袑紹綤潲奢猞赊畲輋賒賖檨舌佘蛇蛥舍捨厍设社舎厙射涉涻渉設赦弽慑摄滠慴摵蔎蠂韘騇懾灄麝欇申屾扟伸身侁呻妽籶绅罙诜柛氠珅穼籸娠峷甡眒砷堔深紳兟椮葠裑訷罧蓡詵&amp;#34; , 
 &amp;#34;S甧蔘燊薓駪鲹鯓鵢鯵鰺神榊鉮鰰邥弞抌沈审矤哂矧宷谂谉婶渖訠審諗頣魫曋瞫嬸瀋覾讅肾侺昚甚胂涁眘渗祳脤腎愼慎椹瘆蜃滲鋠瘮升生阩呏声斘昇枡泩苼殅牲珄竔胜陞曻陹笙湦焺甥鉎聲&amp;#34; , 
 &amp;#34;S鍟鼪鵿绳憴澠譝省眚偗渻圣晟晠剰盛剩勝貹嵊聖墭榺蕂橳賸尸失师呞虱诗邿鸤屍施浉狮師絁湤湿葹溮溼獅蒒蓍詩瑡酾鳲蝨鳾褷鲺鍦鯴鰤鶳襹籭釃十饣什石辻佦时竍识实実旹飠峕拾炻祏蚀&amp;#34; , 
 &amp;#34;S食埘時莳寔湜遈塒嵵溡蒔榯蝕鉽篒鲥鮖鼫鼭鰣史矢乨豕使始驶兘屎笶榁鉂駛士氏礻世丗仕市示卋式叓事侍势呩柹视试饰冟室恀恃拭是枾柿眂贳适栻烒眎眡舐轼逝铈視釈崼弑揓谥貰释勢嗜&amp;#34; , 
 &amp;#34;S弒煶睗筮觢試軾鈰飾舓誓奭噬嬕澨諟諡遾餝螫簭籂襫鰘兙瓧収收手守垨首艏寿受狩兽售授绶痩膄壽瘦綬夀獣獸鏉书殳抒纾叔杸枢陎姝柕倏倐書殊紓掓梳淑焂菽軗鄃疎疏舒摅毹毺綀输跾踈&amp;#34; , 
 &amp;#34;S樞蔬輸橾鮛攄瀭鵨尗秫婌孰赎塾熟璹贖暏暑黍署鼠鼡蜀潻薯曙癙襡糬襩籔蠴鱪鱰朮术戍束沭述侸怷树竖荗恕庶庻絉蒁術裋数竪腧墅漱潄數澍豎樹濖錰鏣鶐虪刷唰耍誜衰摔甩帅帥蟀卛闩拴&amp;#34; , 
 &amp;#34;S閂栓涮腨双滝霜雙孀骦孇騻欆礵鷞鹴艭驦鸘爽塽慡樉縔鏯灀谁脽誰氵水氺閖帨涗涚祱税裞睡吮楯顺舜順蕣橓瞚瞤瞬鬊说妁烁朔铄欶硕矟嗍搠蒴嗽槊碩鎙厶丝司糹私咝泀俬思恖鸶媤斯絲缌&amp;#34; , 
 &amp;#34;S蛳楒禗鉰飔凘厮榹禠罳銯锶嘶噝廝撕澌緦蕬螄鍶蟖蟴颸騦鐁鷥鼶死巳亖四罒寺汜伺似佀兕姒泤祀価孠泗饲驷俟娰柶牭梩洍涘肂飤笥耜釲竢覗嗣肆貄鈻飼禩駟蕼儩騃瀃螦乺忪松枀枩娀柗倯&amp;#34; , 
 &amp;#34;S凇梥崧庺淞菘嵩硹蜙憽檧濍鬆怂悚捒耸竦傱愯嵷慫聳駷讼宋诵送颂訟頌誦餸鎹凁捜鄋嗖廀廋搜溲獀蒐蓃馊飕摗锼艘螋醙鎪餿颼騪叟傁嗾瞍擞薮擻藪櫢瘶苏甦酥稣窣穌鯂蘇蘓櫯囌俗玊夙诉&amp;#34; , 
 &amp;#34;S泝肃洬涑珟素速殐粛骕傃粟訴谡嗉塐塑嫊愫溯溸肅遡鹔僳愬榡膆蔌觫趚遬憟樎樕潥鋉餗縤璛簌藗謖蹜驌鱐鷫狻痠酸匴祘笇筭蒜算夊芕虽倠哸浽荽荾眭葰滖睢熣濉鞖雖绥隋随遀綏隨瓍膸瀡&amp;#34; , 
 &amp;#34;S髄髓亗岁砕祟粋谇埣嵗脺遂歲歳煫碎隧嬘澻穂誶賥檖燧璲禭穗穟繀襚邃旞繐繸鐆譢鐩孙狲荪飧搎猻蓀飱槂蕵薞畃损笋隼損榫箰鎨巺潠唆娑莏傞挲桫梭睃嗦羧蓑摍缩趖簑簔縮髿鮻所唢索琐&amp;#34; , 
 &amp;#34;S琑惢锁嗩暛溑瑣鎍鎖鎻鏁逤溹蜶厦忄莘疋栅属&amp;#34; , 
 &amp;#34;T諳啚裧儃禪蟬繵閶瞋鐺珵侱漦爞綢籌俶埱蓴鶉鈶撘迏迖沓荅逹溚達鎉韃呔蚮軚貸癉撣嘾彈餤黨攩欓逿蕩簜蘯闣朷焘燾僜奃髢詆弚苐媂諦顚顛鈿调蓧啑惵趃奵忊墥峝湩詷钭鋀褍蜳橔囤庉憞&amp;#34; , 
 &amp;#34;T燉軃鋨鞈騩咍漢宊她冂燑轁墤謉饋噋擴斄伖鍩奤嵜鉆汭蟺鱓愓漡苕萔姼忕徥褆扌涭瑹儵稅磃鋖枱他它牠祂咜趿铊塌榙溻褟蹹侤塔墖獭鮙鳎獺鰨挞狧闼崉涾搨遝遢阘榻毾禢撻澾誻踏嚃錔嚺&amp;#34; , 
 &amp;#34;T濌蹋鞜闒鞳闥譶躢襨囼孡骀胎台邰坮抬苔炱炲跆鲐箈臺颱儓鮐嬯擡薹檯籉太冭夳忲汰态肽钛泰粏舦酞鈦溙態燤坍贪怹啴痑舑貪摊滩嘽潬瘫擹攤灘癱坛昙倓谈郯婒惔弾覃榃痰锬谭墰墵憛潭&amp;#34; , 
 &amp;#34;T談醈壇曇檀顃罈藫壜譚貚醰譠罎鷤忐坦袒钽菼毯鉭嗿憳憻暺醓璮叹炭埮探傝湠僋嘆碳舕歎賧汤铴嘡劏羰蝪薚镗蹚鏜鐋鞺鼞饧坣唐堂傏啺棠鄌塘嵣搪溏蓎隚榶漟煻瑭禟膅樘磄糃膛橖篖糖螗&amp;#34; , 
 &amp;#34;T踼糛螳赯醣鎕餹闛饄鶶帑倘偒淌傥耥躺镋鎲儻戃曭爣矘钂烫摥趟燙仐夲弢涛绦掏絛詜嫍幍慆搯滔槄瑫韬飸縚縧濤謟鞱韜饕迯咷洮逃桃陶啕梼淘绹萄祹裪綯蜪鞀醄鞉鋾錭駣檮騊鼗讨套討畓&amp;#34; , 
 &amp;#34;T忑忒特貣脦铽慝鋱蟘膯鼟疼痋幐腾誊漛滕邆縢螣駦謄儯藤騰籐鰧籘虅驣霯唞朰剔梯锑踢銻鷈鷉厗绨偍珶啼崹惿提渧稊缇罤遆鹈嗁瑅綈碮徲漽緹蕛蝭题趧蹄醍謕蹏鍗鳀題鮷鵜騠鯷鶗鶙体挮&amp;#34; , 
 &amp;#34;T躰骵軆體戻屉剃洟倜悌涕逖悐惕掦逷惖揥替楴裼褅殢髰嚏鬀瓋鬄籊天兲婖添酟靔黇靝田屇沺恬畋畑胋畠甛甜菾湉填搷阗碵緂磌窴鴫璳闐鷆鷏忝殄倎唺悿捵淟晪琠腆觍痶睓舔餂覥賟錪靦掭&amp;#34; , 
 &amp;#34;T瑱睼舚旫佻庣挑祧聎芀条岧岹迢祒條笤蓚龆樤蜩鋚鞗髫鲦螩鯈鎥齠鰷宨晀朓脁窕誂窱嬥眺粜絩覜趒跳頫糶贴萜貼铁蛈僣鴩鐡鐵驖呫帖飻餮厅庁汀艼听耓厛烃烴綎鞓聴聼廰聽廳邒廷亭庭莛&amp;#34; , 
 &amp;#34;T停婷嵉渟筳葶蜓楟榳閮霆聤蝏諪鼮圢侹娗挺涏梃烶珽脡艇颋誔鋌頲濎乭囲炵通痌嗵蓪樋熥仝同佟彤峂庝哃狪茼晍桐浵烔砼蚒眮秱铜童粡絧衕酮鉖僮勭銅餇鲖潼曈朣橦氃犝膧瞳鮦统捅桶筒&amp;#34; , 
 &amp;#34;T統綂恸痛慟憅偷偸鍮头投骰頭妵紏敨斢黈蘣透凸禿秃怢突唋涋捸堗湥痜葖嶀鋵鵚鼵図图凃峹庩徒捈涂荼途屠梌揬稌塗嵞瘏筡腯蒤鈯圖圗廜跿酴馟鍎駼鵌鶟鷋鷵土圡吐汢钍釷兎迌兔莵堍菟&amp;#34; , 
 &amp;#34;T鵵湍猯煓貒团団抟團慱槫檲鏄糰鷒鷻圕疃彖湪褖推蓷藬颓隤頹頺頽魋穨蘈蹪俀脮腿僓蹆骽退娧煺蜕褪駾吞呑朜焞暾黗屯芚饨豘豚軘鲀魨霕臀臋氽畽坉乇讬托汑饦侂咃拕拖沰侻莌袥託涶脫&amp;#34; , 
 &amp;#34;T脱飥魠驮佗陀坨岮沱驼柁砣砤袉鸵紽堶跎酡碢馱槖駄踻駝駞橐鮀鴕鼧騨鼍驒鼉妥毤庹媠椭楕嫷橢鵎拓柝唾跅毻箨籜&amp;#34; , 
 &amp;#34;U辪癷袰蝊曢聣烪燞躼蒊蓞耂稥洜毜毝茒桛毮朑焽虲鶑鎼鐢艈霻闧焑屗歚徚鍂藔贘皼斏聁祍&amp;#34; , 
 &amp;#34;W趡惡噁唲陚龏萖関闗關貫窐姽恑瞶咼堝濄幠膴鋘譁瀤綄朚撝蒦嚄擭雘艧扝噲抂巋磈薶槾鄤澫堥夘呅韎雺霿沕忞鴖譕帓歾靺瞴蟱墲娒孯掔瓗渞蜹捼琞亠撱鰖屲劸哇娃徍挖洼娲畖窊媧嗗蛙搲&amp;#34; , 
 &amp;#34;W溛漥窪鼃攨瓦佤邷咓瓲砙袜嗢腽膃襪韈韤歪喎竵崴外弯剜婠帵塆湾睕蜿潫豌彎壪灣丸刓汍纨芄完岏忨抏玩笂紈捖顽烷琓貦頑邜宛倇唍挽晚盌埦婉惋晩梚绾脘菀晼椀琬皖畹碗綩綰輓踠鋔鍐&amp;#34; , 
 &amp;#34;W万卍卐杤捥腕萬翫鋄薍錽贃鎫贎尩尪尫汪亡亾兦王仼彺莣蚟网忹往徃枉罔惘菵暀棢焹蛧辋網蝄誷輞瀇魍妄忘迋旺盳望朢危威烓偎逶隇隈喴媁媙愄揋揻渨煀葨葳微椳楲溦煨詴縅蝛覣嶶薇鳂&amp;#34; , 
 &amp;#34;W癐巍鰃鰄囗为韦围帏沩违闱峗峞洈為韋桅涠唯帷惟维喡圍嵬幃湋溈爲違潍蓶鄬潙潿濰鍏闈鮠癓覹犩霺伟伪尾纬芛苇委炜玮洧娓捤浘荱诿偉偽崣梶硊萎隗骩嵔廆徫愇猥葦蒍骪骫暐椲煒瑋痿&amp;#34; , 
 &amp;#34;W腲艉韪僞碨蜲蜼鲔寪緯蔿諉踓韑頠儰濻鍡鮪壝韙颹瀢亹斖卫未位味苿畏胃軎尉硙菋谓喂媦渭猬煟墛蔚慰熭犚磑緭蝟衛懀濊璏罻衞謂餧鮇螱褽餵魏藯轊鏏霨鳚蘶饖讆躗讏躛昷塭温殟溫瑥榲&amp;#34; , 
 &amp;#34;W瘟豱鳁鎾饂鰛鰮文彣纹芠炆砇闻紋蚉蚊珳阌鈫雯瘒聞馼魰鳼鴍螡閺閿蟁闅鼤闦刎吻呚忟抆呡肳紊桽脗稳穏穩问妏汶莬問渂脕揾搵絻顐璺翁嗡鹟螉鎓鶲奣塕嵡滃蓊暡瞈聬瓮蕹甕罋齆挝倭涡&amp;#34; , 
 &amp;#34;W莴唩涹渦猧萵喔窝窩蜗蝸踒我婐婑捰仴沃肟卧臥偓媉幄握渥焥硪楃腛斡瞃濣瓁龌齷乌圬弙污邬呜杇巫屋洿诬钨趶剭窏釫鄔嗚誈誣箼螐鴮鎢鰞无毋吴吾呉芜梧洖浯茣莁珸祦鹀無禑蜈蕪璑鵐&amp;#34; , 
 &amp;#34;W鯃鼯鷡乄五午仵伍坞妩庑忤怃迕旿武玝侮俉倵捂啎娬牾珷塢摀熓碔鹉瑦舞嫵廡憮潕錻儛橆甒鵡躌兀勿务戊阢伆屼扤岉杌芴忢物矹敄误務悞悟悮粅逜晤焐婺嵍痦隖靰骛奦嵨溩雾寤熃誤鹜鋈&amp;#34; , 
 &amp;#34;W窹霚鼿霧齀蘁騖鶩&amp;#34; , 
 &amp;#34;X欸庍壆扱烲愖糦臰欪滀嘼錯廗諜摡給蚼規嶲鮭巂鬹咁譀迒茠滈欱郃螛嗃熇燺揈閧闀闂鬨銗謼滸芐觟懁郇狟澴還镮鐶儶譮孈葷轋掝擊彐蔇縘繫夾埉浹傢裌叚徦鰔梘筧礆見閒瞯鵁轇驕絞較湝&amp;#34; , 
 &amp;#34;X頡觧吤繲坙巠坓顈眗鼰鼳鋗絹獧決泬勪噱姰濬愾埳堿闞晇欵歀潰搚懢壏嘮釐溓蘝蘞稴漻衖莔禰瓕賯撓譊鉨鉩煖謳嘔盤嚊恓棲諿氣欦臤慳荨羬蕁槏伣俔嗛骹燆睄綅瓊蓲鱃魼胊卻舃碏儴勷蘘&amp;#34; , 
 &amp;#34;X纕繻灑钑鈒鰓騷雭殺榝姍釤縿莦颵姺濕宩昰笹齛咰鉥獡箾蜤燍叜宿碿潚橚孫鶽橝撢餳饀屜歒盷蓨赨緰圩韡捾夕兮忚汐西覀吸希卥昔析矽穸肸肹俙徆怸郗饻唏奚娭屖息悕晞氥浠牺狶莃唽悉&amp;#34; , 
 &amp;#34;X惜桸欷淅渓烯焁焈琋硒菥赥釸傒惁晰晳焟犀睎稀粞翕翖舾鄎厀嵠徯溪煕皙蒠锡僖榽熄熙緆蜥豨餏嘻噏嬆嬉瘜膝餙凞樨橀歙熹熺熻窸羲螅螇錫燨犠瞦礂蟋谿豀豯貕繥雟鯑鵗觹譆醯鏭隵巇曦&amp;#34; , 
 &amp;#34;X爔犧酅觽鼷蠵鸂觿鑴习郋席習袭觋媳椺蒵蓆嶍漝覡趘槢蝷薂隰檄謵鎴霫鳛飁騱騽襲鰼驨枲洗玺徙铣喜葈葸鈢屣漇蓰銑憘憙暿橲禧諰壐縰謑蟢蹝璽鱚矖纚躧匸卌戏屃系饩呬忥怬细係恄盻郤&amp;#34; , 
 &amp;#34;X欯绤細釳阋塈椞舄趇隙慀滊禊綌赩隟熂犔稧戯潟澙蕮覤戱黖戲磶虩餼鬩嚱闟霼衋虾谺傄閕敮煆颬瞎蝦鰕匣侠狎俠峡柙炠狭陜峽烚狹珨祫硖笚翈舺陿溊硤遐搳暇瑕筪碬舝辖縀蕸縖赮魻轄鍜&amp;#34; , 
 &amp;#34;X霞鎋黠騢鶷閜丅下吓圷疜夏梺廈睱諕嚇懗罅夓鏬仙仚屳先奾纤佡忺氙杴祆秈苮籼珗莶掀铦跹酰锨僊僲嘕銛鲜暹韯憸鍁繊褼韱鮮馦蹮孅廯攕譣纎鶱襳躚纖鱻伭咞闲妶弦贤咸挦涎胘娴娹婱絃&amp;#34; , 
 &amp;#34;X舷蚿衔啣痫蛝閑鹇嫌甉銜嫺嫻憪撏澖誸賢諴輱醎癇癎藖鹹礥贒鑦鷳鷴鷼冼狝显险毨烍猃蚬険赻筅尟尠搟禒蜆跣箲獫獮藓鍌燹顕幰攇櫶蘚玁韅顯灦县岘苋现线臽限姭宪県陥哯垷娊娨峴晛涀&amp;#34; , 
 &amp;#34;X莧陷現馅睍絤缐羡献粯腺僩僴綫誢撊線鋧憲橌縣錎餡豏瀗臔獻糮鏾霰鼸乡芗相香郷厢啌鄉鄊廂湘缃葙鄕楿薌箱緗膷襄忀骧麘欀瓖镶鱜鑲驤瓨佭详庠栙祥絴翔跭享亯响蚃饷晑飨想銄餉鲞嚮&amp;#34; , 
 &amp;#34;X蠁鯗響饗饟鱶向姠巷项珦象缿萫項像勨嶑曏橡襐蟓鐌鱌灱灲呺枭侾削哓枵骁宯宵庨恷消绡虓逍鸮啋婋梟焇猇萧痚痟硝硣窙翛萷销揱綃嘐歊潇箫踃嘵憢撨獢銷霄彇膮蕭魈鴞穘簘藃蟂蟏謞鴵&amp;#34; , 
 &amp;#34;X嚣瀟簫蟰髇嚻囂櫹髐鷍蠨驍毊虈洨郩崤淆訤誵小晓暁筱筿皛曉篠謏皢孝肖効咲恔俲哮效校涍笑啸傚敩滧詨嘋嘨誟嘯歗熽斅斆些楔歇蝎蠍劦协旪邪協胁垥奊恊拹挾脅脇脋衺偕斜谐猲絜翓嗋&amp;#34; , 
 &amp;#34;X愶携瑎綊熁膎勰撷擕緳缬蝢鞋諧燲擷鞵襭攜纈讗龤写冩寫藛伳灺泄泻祄绁缷卸炧炨卨娎屑屓偰徢械焎禼亵媟屟揳渫絬谢僁塮榍榭褉噧屧暬韰嶰廨懈澥獬糏薢薤邂燮褻謝夑瀉瀣爕蟹蠏齘齥&amp;#34; , 
 &amp;#34;X齂躠屭躞心邤妡忻芯辛昕杺欣盺俽惞鈊锌新歆廞噷噺嬜薪馨鑫馫枔鬵鐔伈潃阠伩囟孞炘信軐脪衅訫焮馸舋顖釁兴狌星垶骍惺猩煋瑆腥蛵觪箵篂興謃曐觲騂皨刑邢形陉侀郉哘型洐钘陘娙硎&amp;#34; , 
 &amp;#34;X裄铏鈃鉶銒鋞睲醒擤杏姓幸性荇倖莕婞悻涬塂緈嬹臖凶兄兇匈芎讻忷汹哅恟洶胷胸訩詾雄熊诇詗夐敻休俢修咻庥烋烌羞脙鸺臹貅馐樇銝髤髹鎀鮴鵂饈鏅飍苬朽綇滫糔秀岫珛绣袖琇锈溴綉&amp;#34; , 
 &amp;#34;X璓裦螑繍繡鏥鏽齅戌旴疞盱欨胥须訏顼虗虚谞媭幁揟欻虛須楈窢頊嘘稰需魆噓墟嬃歔縃蕦蝑歘諝譃魖驉鑐鬚俆徐蒣许呴姁诩冔栩珝偦許湑暊詡鄦糈醑盨旭伵序汿侐卹沀叙恤昫洫垿欰殈烅&amp;#34; , 
 &amp;#34;X珬勖勗敍敘烼绪续酗喣壻婿朂溆絮訹嗅慉煦続蓄賉槒漵潊盢瞁緒聟銊稸緖瞲藚續蓿吅轩昍咺宣晅軒梋谖喧塇媗愃愋揎萱萲暄煊瑄蓒睻儇禤箮翧蝖嬛蕿諠諼鍹駽矎翾藼蘐蠉譞鰚讂玄玹痃悬&amp;#34; , 
 &amp;#34;X旋琁蜁嫙漩暶璇檈璿懸选烜暅選癣癬怰泫昡炫绚眩袨铉琄眴衒渲絢楦鉉碹蔙镟鞙颴縼繏鏇贙疶蒆靴薛鞾穴斈乴坹学岤峃茓泶袕鸴踅學嶨澩燢觷雤鷽雪樰膤艝轌鳕鱈血吷怴泧狘疦桖烕谑趐&amp;#34; , 
 &amp;#34;X謔瀥坃勋埙焄勛塤熏窨蔒勲勳薫駨嚑壎獯薰曛燻臐矄蘍壦爋纁醺寻巡旬驯杊询峋恂洵浔紃荀栒桪毥珣偱尋循揗詢馴鄩鲟噚攳樳燂燅燖璕襑蟳鱏鱘灥卂训讯伨汛迅侚徇狥迿逊殉訊訓訙奞巽&amp;#34; , 
 &amp;#34;X殾遜愻賐噀蕈顨鑂吁&amp;#34; , 
 &amp;#34;Y叆賹礙譺靉菴媕葊痷闇鵪鶕晻洝媼澚墺驁頨瑒耛拸呾訑婸潒扚昳屵姶堊搤閼煾妋鳱輵夃焸蠱溎裷緷蟈淊嚛欥瓛輐喛揘韹熀袆煇褘蚘噦矆拁玪豜豣將侥烄僥伒莖俓泂揂圧僪貗飬妜焆鐍炏顑&amp;#34; , 
 &amp;#34;Y丂髺樂貍櫟躒輅擽嫚玅桙獶輗掜孴儗肀喦噛槷嚙钀汼齵堷踦锜錡裿綺鉛膁羗撽赺欽汓翑蝺輑橪蕘嬈嵤銳鋭挻烻剡虵縄繩鱦釶鉇箷戺謚釋哾說説爍鑠梀筍鉈珆旲錟湯匋鴺趯恌銕桯筩婾媮殕&amp;#34; , 
 &amp;#34;Y悇蛻涒扡挩捝狏迱詑彵啘乛涴妧尣燰琟維厃痏薳叞榅辒輼轀勜臒汙汚烏歍吳郚娪焬熈誒歖潝疨磍嬐薟唌湺衘崄險嶮硍羨麲詳峫鐷洩紲絏緤訢脩褎褏銹獝藇鱮楥辥廵潯丫压呀庘押鸦桠鸭孲&amp;#34; , 
 &amp;#34;Y铔椏鴉錏鴨壓鵶鐚牙伢岈芽厓枒琊笌蚜堐崕崖涯猚瑘睚衙漄齖厊庌哑唖啞痖雅瘂蕥劜圠亚穵襾讶亜犽迓亞玡垭娅挜砑俹氩埡婭掗訝揠氬猰聐圔稏窫齾咽恹剦烟珚胭偣崦淹焉菸阉湮腌傿煙&amp;#34; , 
 &amp;#34;Y鄢嫣漹嶖樮醃閹嬮篶懕臙黫讠円延闫严妍芫言訁岩昖沿炎郔姸娫狿研莚娮盐琂硏訮閆阎嵒嵓筵綖蜒塩揅楌詽碞蔅颜虤閻厳檐顏顔嚴壛巌簷櫩麙壧孍巖巗巚欕礹鹽麣夵抁沇乵兖奄俨兗匽弇&amp;#34; , 
 &amp;#34;Y衍偃厣掩眼萒郾酓嵃愝扊揜棪渰渷琰遃隒椼硽罨裺演褗戭蝘魇噞躽縯檿黡厴甗鰋鶠黤齞龑儼黬黭顩鼴巘曮魘鼹齴黶厌妟觃牪姲彥彦砚唁宴晏艳覎验偐掞焔谚隁喭堰敥焰焱猒硯葕雁椻滟鳫&amp;#34; , 
 &amp;#34;Y厭墕暥熖酽嬊谳餍鴈燄燕諺赝鬳曕鴳酀騐験嚥嬿艶贋軅爓醶騴鷃灔贗觾讌醼饜驗鷰艷灎釅驠灧讞豓豔灩央咉姎抰泱殃胦眏秧鸯鉠雵鞅鍈鴦扬羊阦阳旸杨炀佯劷氜疡钖飏垟徉昜洋羏烊珜眻&amp;#34; , 
 &amp;#34;Y陽崵崸揚蛘敭暘楊煬禓瘍諹輰鍚鴹颺鐊鰑霷鸉卬仰佒坱奍岟养炴氧痒紻傟楧軮慃氱羪養駚懩攁瀁癢礢怏柍恙样羕詇様漾樣幺夭吆妖枖祅訞喓葽楆腰鴁邀爻尧尭肴垚姚峣轺倄烑珧窑傜堯揺&amp;#34; , 
 &amp;#34;Y殽谣軺嗂媱徭愮搖摇猺遙遥摿暚榣瑤瑶銚飖餆嶢嶤徺磘窯窰餚繇謠謡鳐颻蘨顤鰩仸宎岆抭杳殀狕苭咬柼眑窅窈舀偠婹崾溔榚鴢闄騕齩鷕穾药要袎窔筄葯詏熎覞靿獟鹞薬鼼曜燿艞藥矅曣耀&amp;#34; , 
 &amp;#34;Y纅鷂讑鑰倻椰暍噎潱蠮爷耶捓揶铘爺釾鋣鎁擨也吔亪冶埜野嘢漜壄业叶曳页邺夜抴亱枼洂頁晔枽烨掖液谒堨殗腋葉鄓墷楪業馌僷曄曅歋燁擛皣瞱鄴靥嶪嶫澲謁餣嚈擫曗瞸鍱擪爗礏鎑饁鵺&amp;#34; , 
 &amp;#34;Y靨驜鸈膶岃一弌辷衤伊衣医吚壱依祎咿洢猗畩郼铱壹揖欹蛜禕嫛漪稦銥嬄噫夁瑿鹥繄檹毉醫黟譩鷖黳乁仪匜圯夷冝宐沂诒侇宜怡沶狋衪迤饴咦姨峓弬恞柂瓵荑贻迻宧巸扅栘桋眙胰袘酏痍&amp;#34; , 
 &amp;#34;Y移萓媐椬羠蛦詒貽遗暆椸誃跠頉颐飴疑儀熪遺嶬彛彜螔頤頥寲嶷簃顊鮧彝彞謻鏔籎觺讉鸃乙已以迆钇佁攺矣苡苢庡舣蚁釔倚扆笖逘偯崺旑椅鈘鉯鳦旖輢敼螘檥礒艤蟻顗轙齮乂义亿弋刈忆&amp;#34; , 
 &amp;#34;Y艺仡匇肊议阣亦伇屹异忔芅伿佚劮呓坄役抑曵杙耴苅译邑佾呭呹峄怈怿易枍泆炈绎诣驿俋奕帟帠弈枻浂玴疫羿衵轶唈垼悒挹栧欭浥浳益袣谊貤陭勚埶埸悘悥殹異羛翊翌萟訲訳豙豛逸釴隿&amp;#34; , 
 &amp;#34;Y幆敡晹棭殔湙焲蛡詍跇鈠骮亄兿意溢獈痬竩缢義肄裔裛詣勩嫕廙榏潩瘗膉蓺蜴靾駅億撎槸毅熠熤熼瘞誼镒鹝鹢黓劓圛墿嬑嬟嶧憶懌曀殪澺燚瘱瞖穓縊艗薏螠褹寱斁曎檍歝燡燱翳翼臆貖鮨&amp;#34; , 
 &amp;#34;Y癔藙藝贀鎰镱繶繹豷霬鯣鶂鶃鶍瀷蘙譯議醳醷饐囈鐿鷁鷊懿襼驛鷧虉鷾讛齸乚囙因阥阴侌垔姻洇茵荫音骃栶殷氤陰凐秵裀铟陻隂喑堙婣愔筃絪歅溵禋蒑蔭慇瘖銦磤緸鞇諲霒駰噾濦闉霠韾&amp;#34; , 
 &amp;#34;Y冘吟犾苂垠泿圁峾烎狺珢粌荶訔唫婬寅崟崯淫訡银鈝龂滛碒鄞夤蔩訚誾銀龈噖殥璌嚚檭蟫霪齗齦鷣尹引吲饮蚓隐淾釿鈏飲隠靷飮朄趛檃瘾隱嶾濥螾蘟櫽癮讔印茚洕胤垽湚猌廕酳慭癊憖憗&amp;#34; , 
 &amp;#34;Y鮣懚檼应応英偀桜珱莺啨婴媖愥渶绬朠煐瑛嫈碤锳嘤撄滎甇緓缨罂蝧賏樱璎噟罃褮霙鴬鹦嬰應膺韺甖鎣鹰鶧嚶孆孾攖瀴罌蘡櫻瓔礯譻鶯鑍纓蠳鷪軈鷹鸎鸚盁迎茔盈荥荧莹萤营萦蛍営溁溋&amp;#34; , 
 &amp;#34;Y萾僌塋楹滢蓥潆熒蝇瑩蝿嬴營縈螢濙濚濴藀覮謍赢巆攍攚瀛瀠瀯蠅櫿灐籝灜贏籯矨郢梬颍颕颖摬影潁瘿穎頴巊廮鐛癭映暎硬媵膡鞕瀅譍哟唷喲佣拥痈邕庸傭嗈鄘雍墉嫞慵滽槦牅噰壅擁澭&amp;#34; , 
 &amp;#34;Y郺镛臃癕雝鏞鳙廱灉饔鱅鷛癰喁颙顒鰫永甬咏怺泳俑勇勈栐埇悀柡涌恿傛惥愑湧硧詠塎嵱彮愹蛹慂踊禜鲬踴鯒用苚砽醟优忧攸呦怮泑幽悠麀滺憂優鄾嚘懮瀀櫌纋耰尢尤由沋犹邮怞油肬怣&amp;#34; , 
 &amp;#34;Y斿柚疣峳浟秞莜莤莸逌郵铀偤蚰訧逰游猶遊鱿楢猷鲉輏駀蕕蝣魷輶鮋櫾邎友有丣卣苃酉羑庮羐莠梄聈脜铕湵蒏禉蜏銪槱牖牗黝又右幼佑侑孧狖糿哊囿姷宥峟牰祐诱迶唀梎蚴亴貁釉酭誘鼬&amp;#34; , 
 &amp;#34;Y扜纡迂迃穻陓紆虶唹淤盓渝瘀箊于亐予邘伃余妤扵杅欤玗玙於盂臾衧鱼俞兪禺竽舁茰荢娛娯娱狳谀酑馀渔萸釪隃隅雩魚堣堬崳嵎嵛愉揄楰湡畬畭硢腴逾骬愚楡榆歈牏瑜艅虞觎漁睮窬舆褕&amp;#34; , 
 &amp;#34;Y歶羭蕍蝓諛雓餘魣嬩懙澞覦踰歟璵螸輿鍝礖謣髃鮽旟籅騟鯲鰅鷠鸆与伛宇屿羽雨俁俣挧禹语圄峿祤偊匬圉庾敔鄅萭萮铻傴寙斞楀瑀瘐與語窳鋙龉噳嶼貐斔麌蘌齬玉驭聿芋芌妪忬饫育郁彧&amp;#34; , 
 &amp;#34;Y昱狱秗茟俼峪栯浴砡钰预喐域堉悆惐欲淢淯袬谕逳阈喅喩喻媀寓庽御棛棜棫焴琙矞裕遇飫馭鹆愈滪煜稢罭蒮蓣誉鈺預嫗嶎戫毓獄瘉緎蜟蜮輍銉隩噊慾稶蓹薁豫遹鋊鳿澦燏燠蕷諭錥閾鴥鴧&amp;#34; , 
 &amp;#34;Y鴪儥礇禦魊鹬癒礜穥篽繘醧鵒櫲饇蘛譽轝鐭霱欎驈鬻籞鱊鷸鸒欝軉鬰鬱灪籲爩囦鸢剈冤弲悁眢鸳寃渁渆渊渕惌淵葾棩蒬蜎鹓箢鳶蜵駌鋺鴛嬽鵷灁鼘鼝元贠邧员园沅杬垣爰貟原員圆笎蚖袁&amp;#34; , 
 &amp;#34;Y厡酛圎援湲猨缘鈨鼋園圓塬媴嫄源溒猿獂蒝榞榬辕緣縁蝝蝯魭橼羱薗螈謜轅黿鎱櫞邍騵鶢鶰厵远盶逺遠夗肙妴苑怨院垸衏傆媛掾瑗禐愿裫褑褤噮願曰曱约約箹矱彟彠月戉刖岄抈礿岳枂玥&amp;#34; , 
 &amp;#34;Y恱钥悅悦蚎蚏軏钺阅捳跀跃粤越鈅粵鉞閱閲嬳樾篗嶽龠籆瀹蘥黦爚禴躍籥鸑籰龥鸙蒀煴蒕熅奫蝹赟頵馧贇云勻匀伝呍囩妘抣沄纭芸昀畇眃秐郧涢紜耘耺鄖雲愪氲溳筼蒷氳熉澐蕓鋆橒篔縜&amp;#34; , 
 &amp;#34;Y繧允阭夽抎狁玧陨荺殒喗鈗隕殞褞馻磒霣齫齳孕运枟郓恽晕鄆酝傊惲愠缊運慍暈腪韫韵熨緼蕰蕴縕薀賱醖醞餫藴韗韞蘊韻這&amp;#34; , 
 &amp;#34;Z敱捗囃謲匨蔵冊側厠廁嶒扠挿揷蹅茝僝欃倀长仧長镸鼌鼂謿謓迧陳鈂趂朾脀憕徎胵絺泜歭遟遲迣徸漴褈緟蝩蟲紬搊椆詶薵偢芻鉏蕏傳鶨倕埀箠鎚純湻辶腏趠齱骴薋泚跐從蓯樅熜緫潀潈潨&amp;#34; , 
 &amp;#34;Z酢噈欑穳篹嶉槯伜倅紣綷顇墫拵踆睉蔖剳蹛黱酖亶翢篴拞牴觝啇摕蝃踶點鳭調藋喋臷鰈眰鼑枓剢耑磓隊腞夛仛喥柮樲胕阝贛戇滜睪牫贑嫢啈楖嚌璾鯽穧椾碊鳽餰栫袸濺瀳鏩繳擳竧鳩砠蓻&amp;#34; , 
 &amp;#34;Z齟怚跙脧雋捔逫嵁沴酈譧驡狵沵摨聶囁釽亝祇蚔齊磩鈆謙綪繰菬埥軽鯖伹岨恮跧甽繅洓篸箑摂攝鉐實識亊鉃適銴檡薥藷鸀尌虒睟簨駘菭襢犆媞薙嚔鐟塡怗聑跕鉄鉵獞穜潳剬剸塼摶漙篿尵&amp;#34; , 
 &amp;#34;Z旽啍忳飩杔馲驝陁萚蘀聉顡醀錗撾扸杫咥枮鮝鞢鋅鮏鯹鎐蓔捙偞擖杝妷秇栺軼乑斦浧銿鈾圫汋帀匝沞咂拶沯桚紥紮鉔魳臜臢杂砸韴雑磼襍雜囐雥災灾甾哉栽烖菑渽溨睵賳宰载崽載再在扗&amp;#34; , 
 &amp;#34;Z洅傤酨儎縡兂糌簪簮鐕咱偺喒昝寁撍儧攒儹攢趱趲暂暫賛赞錾鄼濽蹔酂瓉贊鏨瓒酇囋灒讃瓚禶襸讚饡牂羘赃賍臧賘贓髒贜驵駔奘弉脏塟葬銺臓臟傮遭糟蹧醩凿鑿早枣栆蚤棗璅澡璪薻藻灶&amp;#34; , 
 &amp;#34;Z皁皂唕唣造梍喿慥煰艁噪簉燥竃譟趮躁竈啫伬则択沢择泎泽责迮則唶啧帻笮舴責溭矠嘖嫧幘箦蔶樍歵諎赜擇澤皟瞔簀耫礋襗謮賾蠌齚齰鸅仄夨庂汄昃昗捑崱稄贼賊鲗蠈鰂鱡怎谮譖譛囎曽&amp;#34; , 
 &amp;#34;Z増鄫增憎缯橧熷璔矰磳罾繒譄鱛锃鋥甑赠贈吒迊咋抯挓柤哳偧喳揸渣溠楂劄皶箚樝觰皻譇齄齇扎札甴轧軋闸蚻铡煠牐閘霅鍘譗厏苲眨砟搩鲊鲝踷鮓鮺乍灹诈咤奓柵炸宱痄蚱詐搾摣榨醡夈&amp;#34; , 
 &amp;#34;Z粂捚斋斎摘榸齋宅翟窄鉙债砦債寨瘵沾毡旃栴粘蛅飦惉詀趈詹閚谵噡嶦薝邅霑氈氊瞻鹯旜譫饘鳣驙魙鱣鸇讝拃斩飐展盏崭斬琖搌盞嶃嶄榐辗颭嫸醆橏蹍輾皽黵占佔战栈桟站偡绽菚棧湛戦&amp;#34; , 
 &amp;#34;Z綻嶘輚戰虥虦覱轏蘸驏张弡張章傽鄣嫜彰慞漳獐粻蔁遧暲樟璋餦蟑鏱騿鱆麞仉涨涱掌漲幥礃鞝鐣丈仗扙帐杖胀账粀帳脹痮障墇嶂幛賬瘬瘴瞕佋钊妱巶招昭炤盄釗啁鉊駋窼鍣爫找沼瑵召兆&amp;#34; , 
 &amp;#34;Z诏枛垗狣赵笊肁旐棹罀詔照罩箌肇肈趙曌燳鮡櫂瞾羄蜇嫬遮厇折歽矺砓籷虴哲埑粍袩啠悊晢晣辄喆棏蛰詟谪摺輒樀磔輙銸辙蟄嚞謫謺鮿轍讁襵讋者锗赭褶鍺这柘浙淛嗻蔗樜鹧蟅鷓贞针侦&amp;#34; , 
 &amp;#34;Z浈珍珎貞帪栕桢眞真砧祯針偵敒桭酙寊湞葴遉搸斟楨獉甄禎蒖蓁鉁靕榛槇殝瑧碪禛潧箴樼澵臻薽錱轃鍖鍼籈鱵屒诊抮枕姫弫昣胗轸畛疹眕袗紾聄萙裖覙診軫嫃缜稹駗縝縥辴鬒黰圳阵纼侲&amp;#34; , 
 &amp;#34;Z挋陣鸩振朕栚紖眹赈塦揕絼蜄敶誫賑鋴镇震鴆鎭鎮黮凧争佂姃征怔爭峥挣炡狰烝眐钲埩崝崢掙猙睁聇铮媜揁筝徰睜蒸鉦徴箏徵踭篜錚鬇癥氶抍糽拯掟塣晸愸撜整正证诤郑帧政症幀証鄭諍&amp;#34; , 
 &amp;#34;Z鴊證之支卮汁芝吱巵汥枝知织肢徔栀祗秓秖胑胝衹衼倁疷祬秪脂隻梔戠椥臸搘禔綕榰蜘馶鳷謢鴲織蘵鼅禵执侄坧直姪値值聀釞埴執职植殖禃絷跖瓡墌摭馽嬂慹漐踯樴膱縶職蟙蹠蹢軄躑止&amp;#34; , 
 &amp;#34;Z只凪劧旨阯址坁帋扺汦沚纸芷抧祉茋咫恉指枳洔砋轵淽疻紙訨趾軹黹酯藢襧阤至芖志忮扻豸制厔垁帙帜治炙质郅俧峙庢庤挃柣栉洷祑陟娡徏挚晊桎狾秩致袟贽轾乿偫徝掷梽猘畤痔秲秷窒&amp;#34; , 
 &amp;#34;Z紩翐袠觗貭铚鸷傂崻彘智滞痣蛭骘寘廌搱滍稙稚筫置跱輊锧雉墆槜滯潌疐瘈製覟誌銍幟憄摯潪熫稺膣觯質踬鋕旘瀄緻隲駤鴙儨劕懥擲擿櫛穉螲懫贄櫍瓆觶騭鯯礩豑騺驇躓鷙鑕豒中伀汷刣&amp;#34; , 
 &amp;#34;Z妐彸迚忠泈炂终柊盅衳钟舯衷終鈡幒蔠锺螤鴤螽鍾鼨蹱鐘籦肿种冢喠尰塚歱煄腫瘇種踵仲众妕狆祌茽衶重蚛偅眾堹媑筗衆諥州舟诌侜周洀洲炿诪烐珘辀郮婤徟淍矪週鸼喌粥赒輈銂賙輖霌&amp;#34; , 
 &amp;#34;Z駲嚋盩謅鵃騆譸妯轴軸碡肘帚疛菷晭睭箒鯞纣伷呪咒宙绉冑咮昼紂胄荮晝皱酎粙葤詋甃僽皺駎噣縐骤籀籕籒驟朱劯侏诛邾洙茱株珠诸猪硃袾铢絑蛛誅跦槠潴蝫銖橥諸豬駯鮢鴸瀦藸櫧櫫鼄&amp;#34; , 
 &amp;#34;Z鯺蠩竹泏竺炢笁茿烛窋逐笜舳瘃蓫燭蠋躅鱁劚孎灟斸曯欘爥蠾钃主宔拄砫罜陼渚煑煮詝嘱濐麈瞩屬囑矚伫佇住助纻芧苎坾杼注苧贮迬驻壴柱柷殶炷祝疰眝祩竚莇秼紵紸羜著蛀嵀筑註貯跓&amp;#34; , 
 &amp;#34;Z軴铸筯鉒飳馵墸箸翥樦鋳駐築篫霔麆鑄抓檛膼簻髽爪拽跩专叀専砖專鄟嫥瑼甎膞颛磚諯蟤顓鱄转孨転竱轉灷啭堟蒃瑑僎赚撰篆馔縳襈賺譔饌囀籑妆庄妝庒荘娤桩莊湷粧装裝樁糚丬壮壯状&amp;#34; , 
 &amp;#34;Z狀壵梉焋幢撞戅隹追骓椎锥錐騅鵻沝坠笍娷缀惴甀缒畷硾膇墜綴赘縋諈醊錣餟礈贅轛鑆宒迍肫窀谆諄衠准埻凖準綧訰稕卓拙炪倬捉桌棁涿棳琸窧槕穛穱蠿圴彴犳灼叕妰茁斫浊丵浞烵诼酌&amp;#34; , 
 &amp;#34;Z啄啅娺梲着斮晫椓琢斱硺窡罬撯擆斲禚劅諁諑鋜濁篧擢斀斵濯櫡謶镯鐯鵫灂蠗鐲籗鷟籱仔孖孜茊兹咨姕姿茲栥玆紎赀资崰淄秶缁谘赼嗞孳嵫椔湽滋葘辎鄑孶禌觜貲資趑锱稵緇鈭镃龇輜鼒&amp;#34; , 
 &amp;#34;Z澬諮趦輺錙髭鲻鍿鎡頾頿鯔鶅齍鰦齜籽子吇姉姊杍矷秄胏呰秭耔虸笫梓釨啙紫滓訾訿榟橴字自芓茡倳剚恣牸渍眥眦胔胾漬唨宗倧综骔堫嵏嵕惾棕猣腙葼朡椶嵸稯綜緃熧緵翪艐蝬踨踪磫豵&amp;#34; , 
 &amp;#34;Z蹤騌鬃騣鬉鬷鯮鯼鑁总偬捴惣愡揔搃傯蓗摠総縂燪總鍯鏓纵昮疭倊猔碂粽糉瘲縦錝縱邹驺诹郰陬掫菆棷棸鄒箃緅諏鄹鲰鯫黀騶齺赱走鯐奏揍媰租菹葅蒩卆足卒哫崒崪族傶稡箤踤踿镞鏃诅&amp;#34; , 
 &amp;#34;Z阻组俎爼珇祖組詛靻鎺謯劗躜鑚躦鑽繤缵纂纉籫纘钻揝攥厜朘嗺樶蟕纗嶊嘴噿濢璻枠栬絊酔晬最祽罪辠酻蕞醉嶵檇鋷錊檌穝欈尊嶟遵樽繜罇鶎鐏鳟鱒鷷僔噂撙譐捘銌昨秨莋捽椊葃稓筰鈼&amp;#34; , 
 &amp;#34;Z左佐繓作坐阼岝岞怍侳柞祚胙唑座袏做葄蓙飵糳咗&amp;#34; 
 };
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="vbnet代码"&gt;VB.Net代码&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; &amp;#39;/ &amp;lt;summary&amp;gt; 
 &amp;#39;/ 获得一个字符串的汉语拼音码 
 &amp;#39;/ &amp;lt;/summary&amp;gt; 
 &amp;#39;/ &amp;lt;param name=&amp;#34;strText&amp;#34;&amp;gt;字符串&amp;lt;/param&amp;gt; 
 &amp;#39;/ &amp;lt;returns&amp;gt;汉语拼音码,该字符串只包含大写的英文字母&amp;lt;/returns&amp;gt; 
 Public Shared Function GetChineseSpell(ByVal strText As String) As String
 If strText = Nothing Or strText.Length = 0 Then
 Return strText
 End If
 Dim myStr As System.Text.StringBuilder = New System.Text.StringBuilder()
 Dim vChar As Char
 For Each vChar In strText
 &amp;#39; 若是字母则直接输出 
 If (vChar &amp;gt;= &amp;#34;a&amp;#34;c And vChar &amp;lt;= &amp;#34;z&amp;#34;c) Or (vChar &amp;gt;= &amp;#34;A&amp;#34;c And vChar &amp;lt;= &amp;#34;Z&amp;#34;c) Then
 myStr.Append(vChar)
 ElseIf Microsoft.VisualBasic.AscW(vChar) &amp;gt;= 19968 And Microsoft.VisualBasic.AscW(vChar) &amp;lt;= 40869 Then
 &amp;#39; 若字符Unicode编码在编码范围则 查汉字列表进行转换输出 
 Dim strList As String
 For Each strList In strChineseCharList
 If strList.IndexOf(vChar) &amp;gt; 0 Then
 myStr.Append(strList(0))
 Exit For
 End If
 Next
 End If
 Next
 Return myStr.ToString()
 End Function
 &amp;#39; GetChineseSpell 

 Private Shared strChineseCharList() As String = {&amp;#34;A阿啊锕嗄厑哎哀唉埃挨溾锿鎄啀捱皑凒溰嘊敳皚癌毐昹嗳矮蔼躷噯藹譪霭靄艾伌爱砹硋隘嗌塧嫒愛碍暧瑷僾壒嬡懓薆曖璦鴱皧瞹馤鑀鱫安侒峖桉氨庵谙萻腤鹌蓭誝鞌鞍盦馣鮟盫韽啽雸垵&amp;#34;, &amp;#34;A俺唵埯铵隌揞罯銨犴岸按荌案胺豻堓婩暗貋儑錌黯肮岇昂昻枊盎醠凹坳垇柪軪爊敖厫隞嗷嗸嶅廒滶獒獓遨熬璈蔜翱聱螯翶謷翺鳌鏖鰲鷔鼇芺袄媪镺襖岙扷岰傲奡奥嫯慠骜奧嶴澳懊擙謸鏊&amp;#34;, &amp;#34;B八仈巴叭扒朳玐吧夿岜芭疤哵捌笆粑紦羓蚆釟豝鲃魞叐犮抜坺妭拔茇炦癹胈釛菝詙跋軷魃把靶坝弝爸垻罢鲅鮁覇矲霸壩灞欛挀掰白百佰柏栢捭竡粨摆擺襬呗拝败拜唄敗稗粺鞁薭贁兡瓸扳&amp;#34;, &amp;#34;B攽班般颁斑搬斒瘢螁癍辬阪坂岅昄板版瓪钣粄舨鈑蝂魬办半伴扮姅怑拌绊秚絆鉡靽辦瓣邦峀垹帮捠梆浜邫幇幚縍幫鞤绑綁榜膀玤蚌傍棒谤塝稖蒡蜯磅镑艕謗勹包佨孢苞胞笣煲龅蕔褒闁齙&amp;#34;, &amp;#34;B窇嫑雹宝怉饱保鸨珤堡堢媬葆寚飹飽褓駂鳵緥鴇賲藵寳寶靌勽报抱豹趵菢鲍靤骲暴髱虣儤曓爆忁鑤萡陂卑杯盃桮悲揹碑鹎藣鵯喺北鉳贝狈貝邶备昁牬苝背钡俻倍悖狽被偝偹梖珼鄁備僃惫&amp;#34;, &amp;#34;B焙軰辈愂碚禙蓓蛽犕褙誖骳輩鋇憊糒鞴鐾奔泍贲倴渀逩犇锛錛本苯奙畚楍坌捹桳笨撪輽伻崩绷閍嵭嘣綳繃甭埲菶琫鞛泵迸塴甏镚蹦鏰屄毴逼豍鲾鵖鰏柲荸鼻嬶匕比夶朼佊吡妣沘疕彼柀秕&amp;#34;, &amp;#34;B俾笔粊舭筆鄙聛貏匂币必毕闭佖坒庇诐邲妼怭畀畁哔毖珌疪荜陛毙狴畢袐铋婢庳敝梐萆萞閇閉堛弻弼愊愎湢皕禆筚詖貱赑嗶彃楅滗滭煏痹腷蓖蓽蜌裨跸閟飶幣弊熚獙碧箅綼蔽鄪馝幤潷獘&amp;#34;, &amp;#34;B罼襅駜髲壁嬖廦篦篳縪薜觱避鮅斃濞臂蹕髀奰璧鄨饆繴襞襣鏎鞸韠躃躄魓贔鐴驆鷝鷩鼊边砭笾编煸甂箯編蝙獱邉鍽鳊邊鞭鯾鯿籩炞贬扁窆匾惼碥稨褊糄鴘藊卞弁忭抃汳汴苄釆峅便变変昪&amp;#34;, &amp;#34;B覍揙缏遍辡艑辧辨辩辫辮變彪标飑髟猋脿墂幖滮骠標熛膘瘭镖飙飚儦颷瀌爂臕贆鏢镳飆飇飈飊鑣表婊裱諘褾錶檦俵鳔鰾憋鳖鱉鼈虌龞別别咇莂蛂徶襒蟞蹩瘪癟彆邠宾彬傧斌椕滨缤槟瑸賓&amp;#34;, &amp;#34;B賔镔儐濒濱濵虨豳瀕霦繽蠙鑌顮氞摈殡膑髩擯鬂殯臏髌鬓髕鬢仌氷冰兵栟掤梹鋲檳丙邴陃怲抦秉苪昺柄炳饼窉蛃棅禀鈵鞆餅餠燷并並併幷垪庰倂栤病竝偋傡寎摒誁鮩靐癶拨波玻剥盋袯钵&amp;#34;, &amp;#34;B饽啵紴缽脖菠鉢僠嶓播餑蹳驋鱍仢伯孛驳帛泊狛瓝侼勃胉郣亳挬浡秡钹铂舶博渤葧鹁愽搏鈸鉑馎鲌僰煿牔箔膊艊馛駁踣鋍镈薄駮鮊懪礡簙鎛餺鵓犦欂襮礴鑮跛箥簸孹擘檗糪譒蘗蔔峬庯逋&amp;#34;, &amp;#34;B钸晡鈽誧餔轐醭卜卟补哺捕補鳪鸔不布佈步咘怖歨歩钚勏埗悑部埠瓿廍蔀踄篰餢簿玢佛夯宀疒瀑&amp;#34;, &amp;#34;C嚓擦礤礸遪猜才材财財戝裁采倸埰婇寀彩採睬跴綵踩菜棌蔡縩乲参飡骖湌嬠餐驂残蚕惭殘慚蝅慙蠶蠺惨慘噆憯黪黲灿粲儏澯薒燦璨爘仓仺伧沧苍倉舱傖凔嵢滄獊蒼濸艙螥罉藏欌鑶賶撡操&amp;#34;, &amp;#34;C糙曺曹嘈嶆漕蓸槽褿艚螬鏪艹艸草愺騲肏襙册侧厕恻测荝敇萗惻測策萴筞蓛墄箣憡嵾膥岑梣涔噌层層竲驓蹭硛硳岾猠乽叉芆杈肞臿訍偛嗏插馇銟锸艖疀鍤餷垞查査茬茶嵖搽猹靫槎察碴檫&amp;#34;, &amp;#34;C衩镲鑔奼汊岔侘诧姹差紁拆钗釵犲侪柴祡豺喍儕虿袃瘥蠆囆辿觇梴掺搀鋓幨婵谗孱棎湹禅馋嬋煘缠獑蝉誗鋋廛潹潺緾磛毚鄽镡瀍儳劖蟾酁嚵壥巉瀺纏纒躔镵艬讒鑱饞产刬旵丳浐剗谄產産&amp;#34;, &amp;#34;C铲阐蒇剷嵼滻幝蕆諂閳簅冁繟醦鏟闡囅灛讇忏硟摲懴颤懺羼韂伥昌娼淐猖菖阊晿椙琩裮锠錩鲳鯧鼚兏肠苌尝偿常徜瓺萇甞腸嘗嫦瑺膓鋿償嚐蟐鲿鏛鱨厂场昶惝敞僘厰廠氅鋹怅玚畅倡鬯唱&amp;#34;, &amp;#34;C悵暢畼誯韔抄弨怊欩钞焯超鈔繛牊晁巢巣朝鄛漅嘲潮窲罺轈吵炒眧煼麨巐仦耖觘车車砗唓莗硨蛼扯偖撦屮彻坼迠烢聅掣硩頙徹撤澈勶瞮爡抻郴棽琛嗔諃賝尘臣忱沉辰陈茞宸烥莐敐晨訦谌&amp;#34;, &amp;#34;C揨煁蔯塵樄瘎霃螴諶薼麎曟鷐趻硶碜墋夦磣踸贂闯衬疢称龀趁榇稱齓齔嚫谶襯讖阷泟柽爯棦浾偁蛏铛牚琤赪憆摚靗撐撑緽橕瞠赬頳檉竀穪蟶鏳鏿饓丞成呈承枨诚郕城宬峸洆荿乘埕挰珹掁&amp;#34;, &amp;#34;C窚脭铖堘惩棖椉程筬絾裎塍塖溗碀誠畻酲鋮澂澄橙檙鯎瀓懲騬悜逞骋庱睈騁秤吃妛杘侙哧彨蚩鸱瓻眵笞訵嗤媸摛痴瞝螭鴟鵄癡魑齝攡麶彲黐弛池驰迟岻茌持竾荎淔筂貾遅馳墀踟篪謘尺叺&amp;#34;, &amp;#34;C呎肔侈卶齿垑胣恥耻蚇豉欼歯裭鉹褫齒彳叱斥灻赤饬抶勅恜炽翄翅敕烾痓啻湁傺痸腟鉓雴憏翤遫慗瘛翨熾懘趩饎鶒鷘充冲忡沖茺浺珫翀舂嘃摏憃憧衝罿艟蹖虫崇崈隀宠铳銃抽瘳篘犨犫仇&amp;#34;, &amp;#34;C俦帱栦惆绸菗畴絒愁皗稠筹酧酬踌雔嬦懤燽雠疇躊讎讐丑丒吜杽侴瞅醜矁魗臭遚殠出岀初摴樗貙齣刍除厨滁蒢豠锄榋耡蒭蜍趎雏犓廚篨橱懨幮櫉蟵躇櫥蹰鶵躕杵础椘储楮禇楚褚濋儲檚璴&amp;#34;, &amp;#34;C礎齭齼亍処处竌怵拀绌豖竐珿絀傗琡鄐搐触踀閦儊憷橻斶歜臅黜觸矗搋膗揣啜嘬踹巛川氚穿剶瑏传舡船圌遄椽歂暷輲舛荈喘僢汌串玔钏釧賗刅囱疮窓窗牎摐牕瘡窻床牀噇傸磢闖创怆刱剏&amp;#34;, &amp;#34;C剙愴吹炊龡垂桘陲捶菙棰槌锤錘顀旾杶春萅堾媋暙椿槆瑃箺蝽橁櫄鰆鶞纯陙唇浱莼淳脣犉滣蒓鹑漘醇醕鯙偆萶惷睶賰踳蠢踔戳辵娖惙涰绰逴辍酫綽輟龊擉磭歠嚽齪鑡呲玼疵趀偨词珁垐柌&amp;#34;, &amp;#34;C祠茈茨瓷詞辝慈甆辞磁雌鹚糍辤飺餈嬨濨鴜礠辭鶿鷀此佌皉朿次佽刺刾庛茦栨莿絘蛓赐螆賜嗭从匆囪苁忩枞茐怱悤焧葱漗聡蔥骢暰樬瑽璁聦聪瞛篵聰蟌繱鏦騘驄丛従婃孮徖悰淙琮慒誴賨&amp;#34;, &amp;#34;C賩樷藂叢灇欉爜謥凑湊楱腠辏輳粗觕麁麄麤徂殂促猝媨瘄蔟誎趗憱醋瘯簇縬蹙鼀蹴蹵顣汆撺镩蹿攛躥鑹攅櫕巑窜熶篡殩簒竄爨崔催凗墔慛摧榱獕磪鏙乼漼璀皠忰疩翆脃脆啐啛悴淬萃毳焠&amp;#34;, &amp;#34;C瘁粹翠膵膬竁襊臎邨村皴澊竴存刌忖寸籿搓瑳遳磋撮蹉醝髊虘嵯嵳痤矬蒫鹾鹺齹脞剉剒厝夎挫莝莡措逪棤锉蓌错銼刂刹畜曾膪澶骣粢&amp;#34;, &amp;#34;D詫襜燀譂奲虰坘蚳赿跮揰裯儔幬篅搥錞踧吋咑哒耷畣搭嗒褡噠墶达妲怛垯炟羍荙匒笪答詚跶瘩靼薘鞑燵繨蟽躂鐽龖龘打大亣眔橽呆獃懛歹傣代汏轪侢垈岱帒甙绐迨带待怠柋殆玳贷帯軑埭&amp;#34;, &amp;#34;D帶紿袋逮軩瑇叇曃緿鮘鴏戴艜黛簤瀻霴襶靆丹妉单担眈砃耼耽郸聃躭媅殚瘅匰箪褝鄲頕儋勯殫襌簞聸刐狚玬瓭胆衴疸紞掸馾澸黕膽旦但帎沊泹诞柦疍啖啗弹惮淡萏蛋啿氮腅蜑觛窞誕噉髧&amp;#34;, &amp;#34;D憚憺澹禫駳鴠甔癚嚪贉霮饏当珰裆筜當儅噹澢璫襠簹艡蟷挡党谠擋譡灙讜氹凼圵宕砀垱荡档菪瓽雼碭瞊趤壋檔璗盪礑刀叨屶忉氘舠釖鱽魛捯导岛陦倒島捣祷禂搗隝嶋嶌槝導隯壔嶹擣蹈禱&amp;#34;, &amp;#34;D到悼盗菿椡盜道稲噵稻衜檤衟翿軇瓙纛恴得淂悳惪锝嘚徳德鍀的揼扥扽灯登豋噔嬁燈璒竳簦艠覴蹬等戥邓凳鄧隥墱嶝瞪磴镫櫈鐙仾低彽袛啲埞羝隄堤趆嘀滴镝磾鞮鏑廸狄肑籴苖迪唙敌涤&amp;#34;, &amp;#34;D荻梑笛觌靮滌嫡蔋蔐頔魡敵嚁藡豴糴鸐氐厎诋邸阺呧坻底弤抵柢砥掋菧軧聜骶鯳地弟旳杕玓怟枤俤帝埊娣递逓偙梊焍眱祶第菂谛釱棣睇缔蒂僀禘腣鉪馰墑墬碲蔕慸甋締嶳螮嗲敁掂傎厧嵮&amp;#34;, &amp;#34;D滇槙瘨颠蹎巅癫巓巔攧癲齻典奌点婰敟椣碘蒧蕇踮电佃甸阽坫店垫扂玷钿婝惦淀奠琔殿蜔電墊壂橂澱靛磹癜簟驔刁叼汈刟虭凋奝弴彫蛁琱貂碉殦瞗雕鮉鲷簓鼦鯛鵰屌弔伄吊钓窎訋掉釣铞&amp;#34;, &amp;#34;D鈟竨銱雿瘹窵鋽鑃爹跌褺苵迭垤峌恎绖胅瓞眣耊戜谍堞幉揲畳絰耋詄叠殜牃牒镻嵽碟蜨褋艓蝶疂蹀鲽曡疉疊氎嚸丁仃叮帄玎甼疔盯钉耵酊靪顶頂鼎嵿薡鐤订饤矴定訂飣啶萣椗腚碇锭碠聢&amp;#34;, &amp;#34;D錠磸顁丟丢铥颩銩东冬咚岽東苳昸氡倲鸫埬娻崬涷笗菄氭蝀鮗鼕鯟鶇鶫董嬞懂箽蕫諌动冻侗垌姛峒恫挏栋洞胨迵凍戙胴動崠硐棟腖働駧霘剅唗都兜兠蔸橷篼艔斗乧阧抖陡蚪鈄豆郖浢荳逗&amp;#34;, &amp;#34;D饾鬥梪脰酘痘閗窦鬦餖斣闘竇鬪鬬鬭嘟督醏毒涜读渎椟牍犊裻読蝳獨錖凟匵嬻瀆櫝殰牘犢瓄皾騳黩讀豄贕韣髑鑟韇韥黷讟厾独笃堵帾琽赌睹覩賭篤芏妒杜肚妬度荰秺渡靯镀螙殬鍍蠧蠹偳&amp;#34;, &amp;#34;D媏端鍴短段断塅缎葮椴煅瑖腶碫锻緞毈簖鍛斷躖籪叾垖堆塠嵟痽頧鴭鐜队对兑対祋怼陮碓綐對憝濧薱镦懟瀩譈鐓譵吨惇敦墩墪壿撴獤噸撉犜礅蹲蹾驐盹趸躉伅沌炖盾砘逇钝顿遁鈍頓碷遯&amp;#34;, &amp;#34;D潡踲多咄哆剟崜毲裰嚉夺铎剫掇敓敚敪痥鈬奪凙踱鮵鐸朵朶哚垛挅挆埵缍椯趓躱躲綞亸鬌嚲刴剁沲陊饳垜尮桗堕舵惰跢跥跺飿嶞憜墯鵽卩亻赕铫町铤夂丶&amp;#34;, &amp;#34;E娾砵妸妿娿屙讹囮迗俄娥峨峩涐莪珴訛皒睋鈋锇鹅蛾磀誐頟额額鵝鵞譌枙砈婀騀鵈厄歺戹阨呃扼苊阸呝砐轭咢垩峉匎恶砨蚅饿偔卾悪硆谔軛鄂阏堮崿愕湂萼豟軶遌遏廅搹琧腭僫蝁锷鹗蕚&amp;#34;, &amp;#34;E遻頞颚餓噩擜覨諤餩鍔鳄歞顎櫮鰐鶚讍鑩齶鱷奀恩蒽峎摁鞥仒乻旕儿而侕陑峏洏荋栭胹袻鸸粫輀鲕隭髵鮞鴯轜尔耳迩洱饵栮毦珥铒餌駬薾邇趰二弍弐佴刵咡贰貮衈貳誀嗯唔诶&amp;#34;, &amp;#34;F颰墢鼥韛朌頒報賁獖祊埄偪胇貶昞眪袚撥柭襏舩发沷発發彂髪橃醗乏伐姂垡疺罚阀栰傠筏瞂罰閥罸藅佱法砝鍅灋珐琺髮帆忛番勫噃墦嬏幡憣旙旛翻藩轓颿飜鱕凡凢凣匥杋柉矾籵钒舤烦舧&amp;#34;, &amp;#34;F笲釩棥煩緐樊蕃橎燔璠薠繁襎繙羳蹯瀿礬蘩鐇蠜鷭反仮払辺返氾犯奿汎泛饭范贩畈訉軓梵盕笵販軬飯飰滼嬎範嬔瀪方邡坊芳枋牥钫淓蚄堏鈁錺鴋防妨房肪埅鲂魴仿访纺昉昘瓬眆倣旊紡舫&amp;#34;, &amp;#34;F訪髣鶭放飞妃非飛啡婓婔渄绯菲扉猆靟裶緋蜚霏鲱餥馡騑騛鯡飝肥淝暃腓蜰蟦匪诽奜悱斐棐榧翡蕜誹篚吠废杮沸狒肺昲费俷剕厞疿屝萉廃費痱镄廢蕟曊癈鼣濷櫠鐨靅分吩帉纷芬昐氛竕紛&amp;#34;, &amp;#34;F翂棻訜躮酚鈖雰朆餴饙坟妢岎汾枌炃肦梤羒蚠蚡棼焚蒶馚隫墳幩蕡魵鳻橨燌燓豮鼢羵鼖豶轒鐼馩黂粉瞓黺份坋弅奋忿秎偾愤粪僨憤奮膹糞鲼瀵鱝丰风仹凨凬妦沣沨凮枫封疯盽砜風峯峰偑&amp;#34;, &amp;#34;F桻烽琒崶渢溄猦葑锋楓犎蜂瘋碸僼篈鄷鋒檒豐鎽鏠酆寷灃靊飌麷冯捀逢堸綘缝艂縫讽覂唪諷凤奉甮俸湗焨煈赗鳯鳳鴌賵蘕瓰覅仏坲梻紑缶否缹缻雬鴀夫伕邞呋姇枎玞肤怤柎砆荂衭娐荴旉&amp;#34;, &amp;#34;F紨趺酜麸稃跗鈇筟綒孵敷麩糐麬麱懯乀弗伏凫甶冹刜孚扶芙芣芾咈岪帗彿怫拂服泭绂绋苻茀俘垘枹柫氟洑炥玸畉畐祓罘茯郛韨鳬哹栿浮畗砩莩蚨匐桴涪烰琈符笰紱紼翇艴菔虙袱幅絥罦葍&amp;#34;, &amp;#34;F福粰綍艀蜉辐鉘鉜颫鳧榑稪箙複韍幞澓蝠髴鴔諨踾輻鮄癁鮲黻鵩鶝抚甫府弣拊斧俌郙俯釜釡捬辅椨焤盙腑滏腐輔簠黼父讣付妇负附咐坿竎阜驸复祔訃負赴蚥袝偩冨副婏婦蚹傅媍富復萯蛗&amp;#34;, &amp;#34;F覄詂赋椱缚腹鲋禣褔赙緮蕧蝜蝮賦駙縛輹鮒賻鍑鍢鳆覆馥鰒猤攵犭&amp;#34;, &amp;#34;G玵閞鳺旮伽嘠钆尜嘎噶錷尕玍尬魀该陔垓姟峐荄晐赅畡祴該豥賅賌忋改絠鎅丐乢匃匄杚钙盖溉葢鈣戤概蓋槩槪漑瓂干甘芉迀杆玕肝坩泔苷柑竿疳酐粓亁凲尲尴筸漧尶尷魐皯秆衦赶敢笴稈&amp;#34;, &amp;#34;G感澉趕橄擀簳鳡鱤旰盰矸绀倝凎淦紺詌骭幹檊赣灨冈罓冮刚岗纲肛岡牨疘缸钢剛罡堈掆釭棡犅堽綱罁鋼鎠崗港杠焵筻槓戆皋羔高皐髙槔睾膏槹橰篙糕餻櫜韟鷎鼛鷱夰杲菒稁搞缟槁獔稿镐&amp;#34;, &amp;#34;G縞藁檺吿告勂诰郜峼祮祰锆筶禞誥鋯戈圪纥戓疙牱哥胳袼鸽割搁彁歌滒戨閤鴐鴚擱謌鴿鎶呄佮匌阁革敋格鬲愅臵葛隔嗝塥滆觡搿槅膈閣镉韐骼諽鮯櫊韚轕鞷騔鰪哿舸个各虼個硌铬箇獦给&amp;#34;, &amp;#34;G根跟哏亘艮茛揯搄更刯庚畊浭耕掶菮椩焿絚赓鹒緪縆賡羹鶊郠哽埂峺挭绠耿莄梗綆鲠骾鯁亙堩啹喼嗰工弓公功攻杛供糼肱宫宮恭蚣躬龚匑塨幊觥躳匔碽髸觵龔巩汞拱拲栱珙輁鞏共贡貢慐&amp;#34;, &amp;#34;G熕兝兣勾佝沟钩袧缑鈎緱褠篝簼鞲韝岣狗苟枸玽耇耉笱耈豿坸构诟购垢姤茩冓够夠訽媾彀搆遘雊煹觏撀覯購估咕姑孤沽泒柧轱唂唃罛鸪笟菇菰蛄蓇觚軱軲辜酤毂箍箛嫴篐橭鮕鴣轂鹘古汩&amp;#34;, &amp;#34;G诂谷股峠牯骨罟羖逧钴傦啒脵蛊蛌尳愲硲詁馉榾鼓鼔嘏榖皷穀糓薣濲臌餶瀔盬瞽固故凅顾堌崓崮梏牿棝祻雇痼稒锢頋僱錮鲴鯝顧瓜刮苽胍鸹歄焻煱颪劀緺銽鴰騧冎叧呱剐剮啩寡卦坬诖挂&amp;#34;, &amp;#34;G掛罣罫褂詿乖拐枴柺箉怪恠关观官冠覌倌棺蒄窤瘝癏観鳏觀鱞馆痯筦管輨舘錧館躀鳤毌贯泴悺惯掼涫悹祼慣摜遦樌盥罆鏆灌爟瓘礶鹳罐鑵鱹光灮侊炗炚炛咣垙姯茪桄烡珖胱僙輄銧黆欟广&amp;#34;, &amp;#34;G広犷俇逛撗归圭妫龟规邽皈茥闺帰珪亀硅袿媯椝瑰郌摫閨鲑嬀槻槼璝瞡鬶瓌櫷宄轨庋佹匦诡陒垝癸軌鬼庪祪匭晷湀蛫觤詭厬簋蟡刽刿攰柜炅攱贵桂椢筀貴蓕跪瞆劊劌撌槶禬簂櫃鳜鱥衮惃&amp;#34;, &amp;#34;G绲袞辊滚蓘滾蔉磙輥鲧鮌鯀棍棞睴璭謴呙埚郭啯崞聒鈛锅墎瘑嘓彉蝈鍋彍囯囶囻国圀國帼掴幗慖摑漍聝蔮虢馘果惈淉猓菓馃椁褁槨綶蜾裹餜鐹过桧咯莞呷&amp;#34;, &amp;#34;H餲淲豩豰俿腄墮吪魤犿浲侅郂絯忓攼仠桿汵榦臯鎬暠犵挌蛤厷愩唝羾詬鶻淈鹄鈷縎鵠怘趏潅雚洸襘鞼緄腘膕粿輠過铪丷哈嗨孩骸海胲烸塰酼醢亥骇害氦嗐餀駭駴嚡饚乤兯佄顸哻蚶酣頇谽&amp;#34;, &amp;#34;H憨馠魽鼾邗含邯函凾虷唅圅娢浛崡晗梒涵焓寒嵅韩甝筨爳蜬澏鋡韓厈罕浫喊蔊豃鬫汉屽扞汗闬旱垾悍捍晘涆猂莟晥焊琀菡釬閈皔睅傼蛿颔撖蜭暵銲鋎憾撼翰螒頷顄駻雗瀚鶾魧苀斻杭垳绗&amp;#34;, &amp;#34;H笐航蚢颃貥筕絎頏沆蒿嚆薅竓蚝毫椃嗥獆噑豪嘷獋儫曍嚎壕濠籇蠔譹好郝号昊昦哠恏浩耗晧淏傐皓聕號暤暭澔皜皞皡薃皥颢灏顥鰝灝兞诃呵喝訶嗬蠚禾合何劾咊和姀河峆曷柇盇籺阂哬敆&amp;#34;, &amp;#34;H核盉盍荷啝涸渮盒秴菏萂龁惒粭訸颌楁詥鉌阖鲄熆閡鹖麧澕篕翮魺闔齕覈鶡皬鑉龢佫垎贺寉焃湼賀煂碋褐赫鹤翯壑癋爀鶴齃靍靎鸖靏黒黑嘿潶嬒拫痕鞎佷很狠詪恨亨哼悙涥脝姮恆恒桁烆&amp;#34;, &amp;#34;H珩胻鸻横橫衡鴴鵆蘅鑅堼囍乊乥叿灴轰哄訇烘軣焢硡薨輷嚝鍧轟仜弘妅红吰宏汯玒纮闳宖泓玜苰垬娂洪竑荭虹浤紘翃耾硔紭谹鸿渱竤粠葒葓鈜閎綋翝谼潂鉷鞃魟篊鋐彋蕻霐黉霟鴻黌晎嗊&amp;#34;, &amp;#34;H讧訌撔澋澒銾侯矦喉帿猴葔瘊睺篌糇翭骺鍭餱鯸吼犼后郈厚垕後洉逅候鄇堠豞鲎鲘鮜鱟乎匢虍呼垀忽昒曶泘苸烀轷匫唿惚淴虖軤雽嘑寣滹雐歑囫抇弧狐瓳胡壶壷斛焀喖壺媩湖猢絗葫楜煳&amp;#34;, &amp;#34;H瑚嘝蔛鹕槲箶糊蝴衚魱縠螜醐頶觳鍸餬瀫鬍鰗鶘鶦鶮乕汻虎浒唬萀琥虝箎錿鯱互弖戶户戸冱冴帍护沍沪岵怙戽昈枑祜笏粐婟扈瓠綔鄠嫭嫮摢滬蔰槴熩鳸簄鍙鹱護鳠韄頀鱯鸌花芲埖婲椛硴&amp;#34;, &amp;#34;H糀誮錵蘤华哗姡骅铧滑猾嘩撶璍螖鏵驊鷨化划杹画话崋桦婳畫嬅畵話劃摦槬樺嫿澅諙諣黊繣蘳怀徊淮槐褢踝懐褱懷櫰耲蘹坏壊壞蘾欢歓鴅嚾懽獾歡貛讙驩还环峘洹荁桓萈萑堚寏絙雈羦貆&amp;#34;, &amp;#34;H锾阛寰缳環豲鍰鹮糫繯轘闤鬟睆缓緩攌幻奂肒奐宦唤换浣涣烉患梙焕逭喚嵈愌換渙痪煥瑍豢漶瘓槵鲩擐澣瞣藧鯇鯶鰀巟肓荒衁塃慌皇偟凰隍黃黄喤堭媓崲徨惶湟葟遑楻煌瑝墴潢獚锽熿璜&amp;#34;, &amp;#34;H篁艎蝗癀磺穔諻簧蟥鍠餭鳇趪鐄騜鰉鱑鷬怳恍炾宺晃晄奛谎幌愰詤縨謊櫎皩兤滉榥曂皝鎤灰灳诙咴恢拻挥洃虺晖烣珲豗婎媈揮翚辉隓暉楎琿禈詼幑睳噅噕翬輝麾徽隳瀈鰴囘回囬佪廻廽恛&amp;#34;, &amp;#34;H洄茴迴烠逥痐蛔蛕蜖鮰悔螝毇檓燬譭卉屷汇会讳泋哕浍绘芔荟诲恚恵烩贿彗晦秽喙惠絵缋翙阓匯彙彚毀毁滙詯賄僡嘒蔧誨圚寭慧憓暳槥潓蕙徻橞獩璤薈薉諱頮檅檜燴篲藱餯嚖懳瞺穢繢蟪&amp;#34;, &amp;#34;H櫘繪翽譓闠鐬靧譿顪昏昬荤婚涽阍惽棔睧睯閽忶浑馄渾魂繉鼲诨俒倱圂掍混焝溷慁觨諢吙耠锪劐鍃豁攉騞佸活秮火伙邩钬鈥夥沎或货咟俰捇眓获剨祸貨惑旤湱禍嗀奯濩獲霍檴謋穫镬嚯瀖&amp;#34;, &amp;#34;H耯藿蠖嚿曤臛癨矐鑊夻行砉圜&amp;#34;, &amp;#34;J皀髉畟筴簎笒覘樔伡俥鋤雛處諔堲蠀覿茤岋紇裓構颳夬叏獷臩臦昋鱖妎悎饸紅鵍丌讥击刉叽饥乩刏圾机玑肌芨矶鸡枅咭迹剞唧姬屐积笄飢基绩喞嵆嵇犄筓缉赍勣嗘畸跻鳮僟箕銈嘰撃槣樭&amp;#34;, &amp;#34;J畿稽賫躸齑墼憿機激璣積錤隮磯簊績羁賷櫅耭雞譏韲鶏譤癪躋鞿鷄齎羇虀鑇覉鑙齏羈鸄覊亼及伋吉岌彶忣汲级即极亟佶郆卽叝姞急狤皍笈級揤疾觙偮卙庴脨谻戢棘極殛湒集塉嫉愱楫蒺蝍&amp;#34;, &amp;#34;J趌辑槉耤膌銡嶯潗瘠箿蕀蕺鞊鹡橶檝螏輯襋蹐鍓艥籍轚鏶霵鶺鷑雦雧几己丮妀犱泲虮挤脊掎鱾幾戟嵴麂魢撠擠穖彑旡计记伎纪坖妓忌技芰芶际剂季哜垍峜既洎济紀茍計剤紒继觊記偈寂寄&amp;#34;, &amp;#34;J徛悸旣梞祭惎臮葪兾痵継蓟裚跡際墍暨漃漈禝稩穊誋跽霁鲚暩稷諅鲫冀劑曁穄薊襀髻檕繋罽覬鮆檵蹟鵋齌廭懻癠糭蘎骥鯚瀱繼蘮鱀蘻霽鰶鰿鱭驥加夹抸佳泇迦枷毠浃珈家痂梜笳耞袈猳葭&amp;#34;, &amp;#34;J跏犌腵鉫嘉镓糘豭貑鎵麚圿扴岬郏荚郟恝莢戛铗戞蛱颊蛺跲餄鋏頬頰鴶鵊甲玾胛斚贾钾婽斝椵賈鉀榎槚瘕檟价驾架假嫁幏榢稼駕嗧戋奸尖幵坚歼间冿戔肩艰姦姧兼监堅惤猏笺菅菺湔牋犍&amp;#34;, &amp;#34;J缄葌葏間搛椷煎瑊睷缣蒹箋樫熞緘蕑蕳鲣鹣熸篯縑鋻艱鞬馢麉瀐鞯殱礛覸鵳瀸殲籛韀鰹囏虃韉囝拣枧俭柬茧倹挸捡笕减剪检湕趼揀検減睑硷裥詃锏弿瑐简絸谫彅戩戬碱儉翦檢藆襇襉謇蹇&amp;#34;, &amp;#34;J瞼簡繭謭鬋鰎鹸瀽蠒鐗鐧鹻譾襺鹼见件侟建饯剑洊牮荐贱俴健剣涧珔舰剱徤渐谏釼寋旔楗毽溅腱臶践賎鉴键僭榗劍劎墹澗箭糋諓賤趝踐踺劒劔橺薦鍵餞瞷磵礀螹鍳擶繝覵艦轞鑑鑒鑬鑳江&amp;#34;, &amp;#34;J姜将茳浆畕豇葁翞僵漿螀壃缰薑橿殭螿鳉疅礓疆繮韁鱂讲奖桨傋蒋奨奬蔣槳獎耩膙講顜匞匠夅弜杢降洚绛弶袶絳畺酱摾滰嵹犟糡醤糨醬櫤謽艽芁交郊姣娇峧浇茭骄胶椒焦蛟跤僬嘄虠鲛嬌&amp;#34;, &amp;#34;J嶕嶣憍膠蕉膲礁穚鮫鹪簥蟭鐎鷦鷮櫵臫角佼挢狡绞饺晈笅皎矫脚铰搅筊剿勦敫煍腳賋摷暞踋鉸餃儌劋撹徼敽敿缴曒璬矯皦鵤孂纐攪灚鱎叫呌挍訆珓轿较敎教窖滘嘂嘦斠漖酵噍嬓獥藠趭轎&amp;#34;, &amp;#34;J醮譥皭釂阶疖皆接掲痎秸階喈嗟堦媘揭脻街煯稭鞂蝔擑癤鶛孑尐节讦刦刧劫岊昅刼劼杰衱诘拮洁结迼桀桝莭訐婕崨捷袺傑結颉嵥楶滐睫節蜐詰鉣魝截榤碣竭蓵鲒潔羯誱踕幯嶻擮礍鍻巀櫭&amp;#34;, &amp;#34;J蠞蠘蠽姐毑媎解飷檞丯介岕庎忦戒芥屆届斺玠界畍疥砎衸诫借蚧徣堺楐琾蛶骱犗誡褯魪藉巾今斤钅兓金釒津矜砛衿觔珒紟惍琎堻琻筋璡鹶黅襟仅卺巹紧堇菫僅谨锦嫤廑漌盡緊蓳馑槿瑾錦&amp;#34;, &amp;#34;J謹饉劤尽劲妗近进侭枃勁浕荩晉晋浸烬赆祲進煡缙寖搢溍禁靳瑨僸凚殣觐儘噤縉賮嚍壗嬧濜藎燼璶覲贐齽坕京泾经茎亰秔荆荊婛惊旌旍猄経菁晶稉腈睛粳經兢精聙橸鲸鵛鯨鶁麖鼱驚麠井&amp;#34;, &amp;#34;J丼阱刭宑汫汬肼剄穽颈景儆幜憬璄憼暻燝璟璥頸蟼警妌净弪径迳浄胫凈弳徑痉竞逕婙婧桱梷淨竟竫敬痙傹靖境獍誩静頚曔镜靜瀞鏡競竸冋坰扃埛絅駉駫蘏冏囧迥侰炯逈浻烱煚窘颎綗僒煛&amp;#34;, &amp;#34;J熲澃燛褧蘔丩勼纠朻究糺鸠糾赳阄萛啾揪揫鬏鬮九久乆乣奺汣杦灸玖舏韭紤酒镹韮匛旧臼咎疚柩柾倃桕厩救就廄匓舅僦廏廐慦殧舊鹫鯦麔匶齨鷲欍凥抅匊居拘泃狙苴驹倶挶疽痀罝陱娵婅&amp;#34;, &amp;#34;J婮崌掬梮涺椐琚腒锔裾雎艍蜛諊踘鋦駒鴡鞠鞫鶋局泦侷狊桔毩淗焗菊郹椈毱湨犑輂粷躹閰橘檋駶鵙蹫鵴巈蘜鶪驧咀沮举矩莒挙椇筥榉榘蒟龃聥舉踽擧櫸欅襷句巨讵姖岠怇拒洰苣邭具拠昛&amp;#34;, &amp;#34;J歫炬秬钜俱倨冣剧粔耟蚷袓埧埾惧据詎距焣犋鉅飓虡豦锯愳窭聚駏劇勮屦踞鮔壉懅據澽遽鋸屨颶簴躆醵懼爠姢娟捐涓裐鹃勬鋑镌鎸鵑鐫蠲卷呟帣埍菤锩臇錈奆劵倦勌桊狷绢隽淃瓹眷鄄睊&amp;#34;, &amp;#34;J絭罥睠慻蔨餋羂噘撅撧屩屫亅孒孓决刔氒诀抉芵玦玨挗珏砄绝虳觉倔欮崛掘斍桷殌覐觖訣赽趹厥絕絶覚趉鈌劂瑴谲嶡嶥憰熦爴獗瘚蕝蕨鴂鴃憠橛橜镼爵臄镢蟨蟩爑譎蹶蹷嚼矍覺鐝灍爝觼&amp;#34;, &amp;#34;J彏戄攫玃鷢欔矡龣貜钁军君均汮袀軍钧莙蚐桾皲菌鈞碅筠皸皹覠銁銞鲪麇鍕鮶呁俊郡陖埈峻捃晙浚馂骏珺畯竣箟蜠儁寯懏餕燇駿鵔鵕鵘纟挟廴&amp;#34;, &amp;#34;K錒嵦濭骯奟喫噄鉺朏胐阬槀稾藳溝絓鰥卝丱硄廣胿膭歸楇鉿妔薧蚵毼袔齁恗搰華磆蕐會澮璯餛秳漷監譼槛檻捁撟悈脛踁駃咔咖喀卡佧垰胩裃鉲开奒揩衉锎鐦凯剀垲恺闿铠凱剴慨蒈塏愷楷&amp;#34;, &amp;#34;K輆暟锴鍇鎧闓颽忾炌欬烗勓嘅鎎乫刊栞勘龛堪戡龕冚坎侃砍莰偘惂塪輡竷轗看衎崁墈阚瞰磡矙忼砊粇康嫝嵻慷漮槺穅糠躿鏮鱇扛摃亢伉匟邟囥抗犺闶炕钪鈧閌尻髛攷考拷洘栲烤铐犒銬鲓&amp;#34;, &amp;#34;K靠鮳鯌匼坷苛柯牁珂科胢轲疴趷钶嵙棵痾萪軻颏搕犐稞窠鈳榼薖颗樖瞌磕蝌頦醘顆髁礚壳咳翗嶱可岢炣渇嵑敤渴克刻剋勀勊客峇恪娔尅课堁氪骒缂嗑愙溘锞碦緙課錁礊騍肎肯肻垦恳啃豤&amp;#34;, &amp;#34;K墾錹懇掯裉褃劥吭坑硁牼铿硻誙銵鍞鏗巪乬唟厼怾空倥埪崆悾硿箜躻錓鵼孔恐控鞚廤抠芤眍剾彄瞘口劶叩扣怐敂冦宼寇釦窛筘滱蔲蔻瞉簆鷇刳郀枯哭桍堀崫圐跍窟骷鮬狜苦楛库俈绔庫秙&amp;#34;, &amp;#34;K焅袴喾絝裤瘔酷褲嚳夸姱舿侉咵垮銙挎胯跨骻蒯擓巜凷圦块快侩郐哙狯脍塊筷鲙儈鄶廥獪膾旝糩鱠宽寛寬髋鑧髖梡款窽窾匡劻诓邼匩哐恇洭筐筺誆軭狂狅诳軖軠誑鵟夼儣懭邝圹纩况旷岲&amp;#34;, &amp;#34;K況矿昿贶框眖砿眶絋絖貺軦鉱鋛鄺壙黋懬曠爌矌礦穬纊鑛亏刲岿悝盔窥聧窺虧闚顝蘬奎晆逵鄈頄馗喹揆葵骙戣暌楏楑魁睽蝰頯櫆藈鍨鍷騤夔蘷虁躨卼傀煃跬頍蹞尯匮欳喟媿愦愧溃蒉馈匱&amp;#34;, &amp;#34;K嘳嬇憒篑聩聭蕢樻殨餽簣聵籄鐀鑎坤昆晜堃堒婫崐崑猑菎裈焜琨髠裩锟髡鹍尡潉蜫褌髨熴瑻醌錕鲲臗騉鯤鵾鶤悃捆阃壸梱祵硱稇裍壼稛綑閫閸困涃睏扩拡括挄栝桰筈萿葀蛞阔廓頢濶闊鞟&amp;#34;, &amp;#34;K韕懖霩鞹鬠穒&amp;#34;, &amp;#34;L冫勑粚誺銐寵娕坔釘詻鄜膚鬴茖蛒鎘鉻羮篢睔腂蘫谾瘣暕撿諫倞靓靚牞摎樛畂寠窶垃拉柆啦翋菈邋旯砬揦磖喇藞嚹剌溂腊揧楋瘌蜡蝋辢辣蝲臈攋爉臘鬎櫴瓎镴鯻蠟鑞鞡来來俫倈崃徕涞莱&amp;#34;, &amp;#34;L郲婡崍庲徠梾淶猍萊逨棶琜筙铼箂錸騋鯠鶆麳唻赉睐睞赖賚濑賴頼顂癞鵣瀨瀬籁藾癩襰籟兰岚拦栏婪嵐葻阑蓝谰澜褴儖斓篮燣藍襕镧闌璼襤譋幱攔瀾灆籃繿蘭斕欄礷襴囒灡籣欗讕躝襽鑭&amp;#34;, &amp;#34;L钄韊览浨揽缆榄漤罱醂壈懒覧擥嬾懶孄覽孏攬欖爦纜烂滥燗嚂濫爁爛爤瓓灠糷啷勆郎郞欴狼莨嫏廊桹琅蓈榔瑯硠稂锒筤艆蜋郒螂躴鋃鎯駺悢朗阆朖烺塱蓢樃誏閬朤埌浪蒗唥捞粩撈劳労牢&amp;#34;, &amp;#34;L狫窂哰唠崂浶勞痨铹僗嶗憥朥癆磱簩蟧醪鐒顟髝老佬咾姥恅荖栳珯硓铑蛯銠潦橑鮱轑涝烙嗠耢酪嫪憦澇橯耮軂仂阞乐叻忇扐氻艻玏泐竻砳勒楽韷簕鳓鰳饹餎雷嫘缧蔂樏畾檑縲镭櫑瓃羸礧&amp;#34;, &amp;#34;L纍罍蘲鐳轠壨鑘靁虆鱩欙纝鼺厽耒诔垒塁絫傫誄磊蕌磥蕾儡壘癗藟櫐矋礨灅蠝蘽讄儽鑸鸓肋泪洡类涙淚累酹銇頛頪擂錑攂礌颣類纇蘱禷嘞脷塄棱楞碐稜踜薐冷倰堎愣睖唎刕厘剓梨狸离荲&amp;#34;, &amp;#34;L莉骊悡梸犁菞喱棃犂鹂剺漓睝筣缡艃蓠蜊嫠孷樆璃盠竰糎蔾褵鋫鲡黎篱縭罹錅蟍謧醨嚟藜邌離鯏鏫鯬鵹黧囄灕蘺蠡蠫孋廲劙鑗穲籬驪鱺鸝礼李里俚峛哩娌峲浬逦理裡锂粴裏豊鋰鲤澧禮鯉&amp;#34;, &amp;#34;L蟸醴鳢邐鱧欚力历厉屴立吏朸丽利励呖坜沥苈例岦戾枥疠苙隶俐俪栃栎疬砅茘荔赲轹郦娳悧栗栛栵涖猁珕砺砾秝莅唳婯悷琍笠粒粝蚸蛎傈凓厤棙痢蛠詈跞雳塛慄搮溧蒚蒞鉝鳨厯厲暦歴瑮&amp;#34;, &amp;#34;L綟蜧勵曆歷篥隷鴗巁檪濿癘磿隸鬁儮曞櫔爄犡禲蠇嚦壢攊瀝瓅礪藶櫪爏瓑皪盭礫糲蠣儷癧礰鷅麜囇轢欐讈轣攭瓥靂鱱靋瓈俩倆嫾奁连帘怜涟莲連梿联裢亷嗹廉慩漣蓮匲奩覝劆匳噒憐磏聨&amp;#34;, &amp;#34;L聫褳鲢濂濓縺翴聮薕螊櫣聯臁蹥謰鎌镰簾蠊鬑鐮鰱籢籨敛琏脸裣摙槤璉蔹嬚斂歛臉鄻襝羷练娈炼恋浰殓堜媡湅萰链僆楝煉瑓潋練澰錬殮鍊鏈瀲鰊戀纞簗良俍凉梁涼椋辌粮粱墚綡踉樑輬糧&amp;#34;, &amp;#34;L両两兩唡啢掚脼裲緉蜽魉魎亮哴谅辆喨晾湸量煷輌諒輛鍄蹽辽疗聊僚寥嵺廖憀膋嘹嫽寮嶚嶛憭撩敹獠缭遼暸燎璙窷膫竂镣鹩屪廫簝蟟豂賿蹘爎鐐髎飉鷯钌釕鄝蓼爒镽了尥炓料尞撂瞭咧毟&amp;#34;, &amp;#34;L挘埓列劣冽劽姴峢挒洌茢迾埒浖烈烮捩猎猟蛚裂煭睙聗趔巤颲儠鮤鴷擸獵犣躐鬛鬣鱲邻林临啉崊惏淋晽琳粦痳碄箖粼鄰隣嶙潾獜遴斴暽燐璘辚霖瞵磷臨繗翷麐轔壣瀶鏻鳞驎麟鱗菻亃稟僯&amp;#34;, &amp;#34;L凛凜撛廩廪懍懔澟檁檩癛癝顲吝恡悋赁焛賃蔺橉甐膦閵疄藺蹸躏躙躪轥拎伶刢灵囹坽夌姈岭岺彾泠狑苓昤朎柃玲瓴凌皊砱秢竛铃陵鸰婈崚掕棂淩琌笭紷绫羚翎聆舲菱蛉衑祾詅跉軨蓤裬鈴&amp;#34;, &amp;#34;L閝零龄綾蔆輘霊駖澪蕶錂霗魿鲮鴒鹷燯霛霝齢瀮酃鯪孁蘦齡櫺醽靈欞爧麢龗阾袊领領嶺令另呤炩溜熘刘沠畄浏流留旈琉畱硫裗媹嵧旒蒥蓅遛馏骝榴瑠飗劉瑬瘤磂镏駠鹠橊璢疁镠癅蟉駵嚠&amp;#34;, &amp;#34;L懰瀏藰鎏鎦餾麍鏐飀鐂騮飅鰡鶹驑柳栁桞珋桺绺锍綹熮罶鋶橮羀嬼六翏塯廇澑磟鹨蹓霤雡飂鬸鷚瓼甅囖龙屸咙泷茏昽栊珑胧眬砻笼聋隆湰嶐槞漋癃窿篭嚨巃巄蘢鏧霳曨朧櫳爖瓏矓礱礲襱&amp;#34;, &amp;#34;L籠聾蠪蠬龓豅躘鑨靇鸗陇垄垅拢儱隴壟壠攏竉哢梇硦徿贚娄偻婁喽溇蒌僂楼嘍廔慺蔞遱樓熡耧蝼瞜耬艛螻謱軁髅鞻髏嵝搂塿嶁摟漊甊篓簍陋屚漏瘘镂瘺瘻鏤露噜撸嚕擼卢庐芦垆枦泸炉栌&amp;#34;, &amp;#34;L胪轳舮鸬玈舻颅鈩鲈魲盧嚧壚廬攎瀘獹璷蘆櫨爐瓐臚矑籚纑罏艫蠦轤鑪顱髗鱸鸕黸卤虏挔捛掳鹵硵鲁虜塷滷蓾樐澛魯擄橹磠镥瀂櫓氌艣鏀艪鐪鑥圥甪陆侓坴彔录峍勎赂辂陸娽淕淥渌硉菉&amp;#34;, &amp;#34;L逯鹿椂琭祿禄僇剹勠滤盝睩碌稑賂路塶廘摝漉箓粶蔍戮樚熝膔膟觮趢踛辘醁潞穋蕗錄録錴璐簏螰鴼濾簶蹗轆騄鹭簬簵鏕鯥鵦鵱麓鏴騼籙觻虂鷺氇驴闾榈閭馿膢櫚藘曥鷜驢吕呂侣郘侶旅梠&amp;#34;, &amp;#34;L焒祣稆铝屡絽缕屢膂膐褛鋁履褸儢穞縷穭寽垏律哷虑率绿嵂氯葎綠緑慮箻勴繂櫖爈鑢孪峦挛栾鸾脔滦銮鵉圝奱孌孿巒攣曫欒灓羉臠圞灤虊鑾癴癵鸞卵乱釠亂掠略畧锊圙鋝鋢抡掄仑伦囵沦&amp;#34;, &amp;#34;L纶侖轮倫陯圇婨崘崙惀淪菕棆腀碖綸蜦踚輪磮錀鯩稐耣论埨溣論捋頱囉罗啰猡脶萝逻椤腡锣箩骡镙螺羅覶鏍儸覼騾玀蘿邏欏鸁籮鑼饠驘剆倮砢蓏裸躶瘰蠃臝攞曪癳泺峈洛络荦骆珞笿絡落&amp;#34;, &amp;#34;L摞漯犖雒駱鮥鵅纙鱳&amp;#34;, &amp;#34;M絔硥苾牑訬仯哋尒尓爾坆呒撫羙秏狢貈貉湏惛殙貇氂犛厸龍龒嘸呣妈媽嬤嬷麻痲嫲蔴犘蟆蟇马犸玛码蚂馬溤獁遤瑪碼螞鎷鷌鰢亇杩祃閁骂唛傌睰嘜榪禡罵駡礣鬕吗嗎嘛埋霾买荬買嘪蕒鷶&amp;#34;, &amp;#34;M劢迈佅売麦卖脉脈麥衇勱賣邁霡霢颟顢姏悗蛮慲摱馒樠瞒瞞鞔饅鳗鬗鬘鰻蠻屘満睌满滿螨襔蟎鏋矕曼僈谩墁幔慢漫獌缦蔄蔓熳澷镘縵蟃謾鏝蘰牤邙吂忙汒芒杗杧盲厖恾笀茫哤娏浝牻硭釯&amp;#34;, &amp;#34;M铓痝蛖鋩駹蘉莽莾茻壾漭蟒蠎匁猫貓毛矛枆牦茅旄渵軞酕蛑锚緢髦蝥錨蟊鶜冇卯戼峁泖茆昴铆笷蓩鉚冃皃芼冐茂冒眊贸耄袤覒媢帽貿鄚愗暓楙毷瑁瞀貌鄮蝐懋唜庅嚒濹嚰么癦沒没枚玫苺&amp;#34;, &amp;#34;M栂眉脄莓梅珻脢郿堳媒嵋湄湈猸睂葿楣楳煤瑂禖腜塺槑酶镅鹛鋂霉徾鎇矀攗蘪鶥攟黴毎每凂美挴浼媄嵄渼媺镁嬍燘躾鎂黣妹抺沬昧祙袂眛媚寐痗跊鬽煝睸魅篃蝞嚜椚门扪玣钔門閅捫菛璊&amp;#34;, &amp;#34;M穈鍆虋闷焖悶暪燜懑懣们們掹擝氓甿虻冡庬罞萌萠夢溕盟甍儚橗瞢蕄蝱鄳鄸幪懞濛獴曚朦檬氋矇礞鯍艨鹲矒靀饛顭鸏勐猛瓾蒙锰艋蜢錳懵蠓鯭鼆孟梦夣懜霥踎咪瞇冞弥祢迷猕谜蒾詸謎醚&amp;#34;, &amp;#34;M擟糜縻麊麋靡獼麛爢戂攠蘼醾醿鸍釄米羋芈侎弭洣敉粎脒眯渳葞蝆蔝銤孊灖糸汨宓泌觅峚祕宻秘密淧覓覔幂谧塓幎覛嘧榓滵漞熐蔤蜜鼏冪樒幦濗藌謐櫁簚羃芇眠婂绵媔棉綿緜臱蝒嬵檰櫋&amp;#34;, &amp;#34;M矈矊矏丏汅免沔黾俛勉眄娩偭冕勔喕愐湎缅葂腼緬鮸靣面糆麪麫麺麵喵苗媌描瞄鹋嫹鶓鱙杪眇秒淼渺缈篎緲藐邈妙庙竗庿廟吀咩哶孭灭搣滅蔑薎鴓幭懱瀎篾櫗蠛衊鑖鱴瓱民垊姄岷怋旻旼&amp;#34;, &amp;#34;M玟苠珉盿冧罠崏捪琘琝缗暋瑉痻碈鈱緍緡錉鍲皿冺刡闵抿泯勄敃闽悯敏笢笽湣閔愍敯黽閩僶慜憫潣簢鳘蠠鰵名明鸣洺眀茗冥朙眳铭鄍嫇溟猽蓂暝榠銘鳴瞑螟覭佲姳凕慏酩命掵詺谬缪繆謬&amp;#34;, &amp;#34;M摸嚤尛谟嫫馍摹模膜麼麽摩魹橅磨糢謨謩擵饃嚩蘑髍魔劘饝抹懡麿末劰圽妺怽歿殁沫茉陌帞昩枺皌眜眿砞秣莈莫眽粖絈袹蛨貃嗼塻寞漠蓦貊銆墨嫼暯瘼瞐瞙镆魩黙縸默貘藦蟔鏌爅驀礳纆&amp;#34;, &amp;#34;M耱乮哞牟侔劺恈洠眸谋鉾謀鍪鴾麰某母毪獏氁亩牡姆拇峔牳畆畒胟畝畞砪畮鉧踇木仫目凩沐狇坶炑牧苜毣莯蚞钼募萺雮墓幕幙慔楘睦鉬慕暮艒霂穆鞪旀丆椧渑&amp;#34;, &amp;#34;N懝抝拗秅莀袲唸毭咹児兒耏聏峊廾嫨跈聻茮澆涳巙崀尦竜袮彌镾濔瀰乜樢拏拿誽镎鎿乸哪雫内那吶妠纳肭娜衲钠納袦捺笝豽軜貀嗱蒳靹魶腉熋孻乃奶艿氖疓妳廼迺倷釢嬭奈柰耐萘渿鼐褦&amp;#34;, &amp;#34;N螚錼囡男抩枏枬侽南娚畘莮难喃遖暔楠煵諵難赧揇湳萳腩蝻戁婻囔乪嚢囊鬞馕欜饢擃曩攮灢儾齉孬檂呶怓挠峱硇铙猱蛲詉碙嶩夒鐃巎獿垴恼悩脑匘脳堖惱嫐瑙腦碯闹婥淖閙鬧讷呐眲訥呢&amp;#34;, &amp;#34;N馁腇餒鮾鯘氝焾嫩能莻鈪銰啱妮尼坭怩泥籾倪屔秜郳铌埿婗淣猊蚭棿跜鈮蜺觬貎霓鲵鯢麑齯臡伱伲你拟抳狔苨柅旎晲馜儞隬擬薿檷鑈氼迡昵胒逆匿痆眤堄惄嫟愵溺睨腻暱縌膩嬺拈年秊哖&amp;#34;, &amp;#34;N秥鲇鮎鲶鵇黏鯰捻辇撚撵碾輦簐攆躎卄廿念姩埝娘嬢酿醸釀鸟茑袅嫋裊蔦嬝褭嬲尿脲捏揑帇圼苶枿陧涅聂臬啮惗隉敜嗫嵲踂摰踗踙镊镍嶭篞臲錜颞蹑鎳闑孼孽櫱籋蘖齧巕糱糵蠥囓讘躡鑷&amp;#34;, &amp;#34;N顳脌囜您拰宁咛拧狞柠聍寍寕寜寧儜凝嚀嬣擰獰薴檸聹鑏鬡鸋橣矃佞侫泞甯寗澝濘妞牛牜忸扭沑狃纽杻炄钮紐鈕靵农侬哝浓脓秾農儂辳噥憹濃蕽禯膿穠襛醲欁繷弄挊挵癑齈羺譨啂槈耨鎒&amp;#34;, &amp;#34;N鐞譳奴孥驽笯駑伮努弩砮胬怒傉搙女钕籹釹衂恧朒衄疟虐瘧奻渜暖煗餪硸黁燶郍挪梛傩搻儺橠诺喏掿逽搦锘榒稬諾糑懦懧糥穤糯恁蔫&amp;#34;, &amp;#34;O吽摳噢哦筽夞乯鞰讴欧殴瓯鸥塸歐熰甌膒鴎櫙藲鏂鷗吘呕偶腢耦蕅藕怄沤慪漚&amp;#34;, &amp;#34;P钯鈀跁罷猈螌褩闆湴牓棓徬鎊剝襃铇袌鉋鮑琲絣痭琣逬跰螕鎞粃枈痺辟稫箆鞞猵萹拚徧緶辯骉蔈颮麃藨謤穮驃驫摽汃砏璸鉼碆磻犻苩瓟桲淿湐猼馞嚗髆蚾獛鵏吥荹鈈郶茷籓膰趽彷衯夆馮&amp;#34;, &amp;#34;P摓垺妚尃豧巿襆襥脯蜅秿鈲窌攈脟濼尨眫冖覕屰妑皅趴舥啪葩杷爬耙琶筢潖帊帕怕袙拍俳徘排猅棑牌箄輫簰犤哌派湃蒎鎃磗眅畨潘攀爿柈盘跘媻幋蒰搫槃磐縏蹒瀊蟠蹣鎜鞶坢冸判沜泮炍&amp;#34;, &amp;#34;P叛牉盼畔袢詊溿頖鋬鵥襻鑻乓汸沗肨胮雱滂膖霶厐庞逄旁舽嫎篣螃鳑龎龐鰟蠭嗙耪覫髈炐胖抛拋脬刨咆垉庖狍炮炰爮袍匏蚫軳鞄褜麅跑奅泡疱皰砲萢麭礟礮呸怌肧柸胚衃醅阫陪陫培毰赔&amp;#34;, &amp;#34;P锫裴裵賠錇俖伂沛佩帔姵斾旆浿珮配笩蓜辔馷嶏霈轡喷噴濆歕瓫盆湓葐呠翉翸喯匉怦抨泙恲胓砰梈烹硑軯閛漰嘭駍磞芃朋挷竼倗莑堋弸彭棚椖傰塜塳搒漨硼稝蓬鹏槰樥熢憉澎輣篷膨錋韸&amp;#34;, &amp;#34;P髼蟚蟛鬅纄韼鵬騯鬔鑝捧淎皏剻掽椪碰踫浌巼闏乶喸丕伓伾批纰邳坯怶披抷炋狉狓砒悂秛秠紕铍旇翍耚豾鈚鈹鉟銔劈磇駓髬噼錃錍魾憵礔礕闢霹皮阰芘岯枇毞肶毗毘疲笓蚍郫陴啤埤崥蚽&amp;#34;, &amp;#34;P豼椑焷琵脾腗榌鲏罴膍蜱隦魮壀鮍篺螷貔簲羆鵧朇鼙蠯匹庀仳圮苉脴痞銢諀鴄擗噽癖嚭屁淠渒揊媲嫓睤睥潎僻澼甓疈譬鷿鸊片囨偏媥犏篇翩鶣骈胼腁楄楩賆諚骿蹁駢騈覑谝貵諞骗魸騗騙&amp;#34;, &amp;#34;P剽彯漂缥飘磦旚縹翲螵犥飃飄魒瓢薸闝殍瞟篻醥皫顠票僄勡嘌嫖徱慓氕撇撆暼瞥丿苤鐅嫳姘拼礗穦馪驞玭贫貧琕嫔频頻嬪薲嚬矉颦顰品榀朩牝汖娉聘乒甹俜涄砯艵竮頩平评凭呯坪岼苹郱&amp;#34;, &amp;#34;P屏帡枰洴玶荓娦瓶屛帲淜萍蚲塀幈焩甁缾聠蓱蛢評軿鲆凴慿箳輧憑鮃檘簈蘋钋坡岥泼娝釙颇溌酦潑醱鏺婆嘙蔢鄱皤謈櫇叵尀钷笸鉕駊廹岶迫敀昢洦珀哱烞破砶粕蒪頗魄剖颒抔抙捊掊裒箁&amp;#34;, &amp;#34;P咅哣婄犃兺哛仆攴扑抪炇巬巭柨陠痡铺駇噗撲鋪擈鯆圤匍莆菩菐葡蒱蒲僕酺墣璞濮瞨穙镤贌纀鏷朴圃埔浦烳普圑溥暜谱潽樸氆諩檏镨譜蹼鐠舖舗曝&amp;#34;, &amp;#34;Q摮磝朁鸧鶬鼜詧軙儭櫬趍袳創敠匚釓隑矼肐鉤扢琯矔鸛龜氿肣馯抲頜礉隺渹舙酄攲敧稘毄緝觭禨鄿鐖饑焏踖躤蟣済萕濟袷唊脥價靬鳒鰜鶼鑯揃葥漸摪彊勥焳燋湫湬蟜譑峤嶠潐噭椄疌倢偼&amp;#34;, &amp;#34;Q媫蛣楬鮚荕埐嶜厪墐慬歏濅涇鶄捄趄跔鮈跼趜弆瞿鐻捲弮蚗傕鶌躩麏麕焌箘開欿歁殻揢挳硜矻誇厱熑燫艌鳥毆七迉沏妻柒倛凄栖桤缼郪娸悽戚捿桼淒萋朞期欺紪褄僛嘁慽榿槭漆緀慼磎諆&amp;#34;, &amp;#34;Q霋蹊魌鏚鶈亓祁齐圻岐岓芪其奇斉歧祈肵疧竒剘斊旂耆脐蚑蚚颀埼崎帺掑淇渏猉畦萁跂軝釮骐骑棊棋琦琪祺蛴愭碁碕褀頎鬾鬿旗粸綥綦綨緕蜝蜞璂禥蕲踑螧鲯懠濝藄檱櫀簱臍騎騏鳍蘄鯕&amp;#34;, &amp;#34;Q鵸鶀麒籏纃艩蠐鬐騹魕鰭玂麡乞邔企屺岂芑启呇杞玘盀唘豈起啓啔啟婍绮晵棨綮諬簯闙气讫気汔迄弃汽矵芞呮泣炁盵咠契砌荠栔訖唭欫夡愒棄湆湇葺碛摖暣甈碶噐憇器憩磜磧薺礘罊蟿掐&amp;#34;, &amp;#34;Q葜拤跒酠鞐圶冾帢恰洽殎硈愘髂千仟阡奷扦汘芊迁佥岍杄汧茾竏钎拪牵粁悭蚈谸铅婜牽釺谦雃僉愆签骞鹐搴摼撁箞諐遷褰顅檶攐攑櫏簽鏲鵮攓騫鐱鬜鬝籤韆仱岒忴扲拑乹前钤歬虔钱钳乾&amp;#34;, &amp;#34;Q偂掮揵軡媊鈐鉗墘榩箝銭潜橬錢黔鎆黚騝濳騚灊籖鰬浅肷淺嵰慊遣蜸潛谴缱繾譴鑓欠刋芡茜倩悓堑傔嵌棈椠皘蒨塹歉蔳儙槧篏輤篟壍嬱縴呛羌戕戗斨枪玱猐琷跄嗴椌獇腔嗆溬蜣锖嶈戧槍&amp;#34;, &amp;#34;Q牄瑲羫锵篬錆蹌镪蹡鎗鏘鏹強强墙嫱蔷樯漒蔃墻嬙檣牆謒艢蘠抢羟搶羥墏摤繈襁繦炝唴熗羻兛瓩悄硗郻鄗嵪跷鄡鄥劁敲踍锹墝碻頝墽幧橇缲磽鍫鍬繑趬蹺蹻乔侨荍荞桥硚喬僑槗谯嘺嫶憔&amp;#34;, &amp;#34;Q蕎鞒樵橋犞癄瞧礄藮譙趫鐈鞽顦巧釥愀髜俏诮陗峭帩窍殼翘誚髚僺撬鞘竅翹躈切苆癿茄聺且厒妾怯匧窃倿悏挈洯惬淁笡愜蛪朅箧緁锲魥篋踥穕藒鍥鯜鐑竊籡亲侵钦衾骎菳媇嵚誛嶔親顉駸&amp;#34;, &amp;#34;Q鮼寴庈芩芹埁珡矝秦耹菦蚙捦琴琹禽鈙雂勤嗪溱靲噙擒斳鳹懄檎澿瘽螓懃蠄坅昑笉梫赾寑锓寝寢鋟螼吢吣抋沁唚菣揿搇撳瀙藽靑青氢轻倾卿郬圊氫淸清傾廎蜻輕鲭鑋夝甠剠勍情殑硘晴棾&amp;#34;, &amp;#34;Q氰葝暒擏樈擎檠黥苘顷请庼頃漀請檾謦庆凊掅碃箐靘慶磬儬濪罄櫦宆跫銎卭邛穷穹茕桏笻筇赹惸焪焭琼舼蛩蛬煢熍睘瞏窮儝憌橩璚藑竆藭丘丠邱坵恘秋秌寈蚯媝萩楸鹙篍緧蝵穐趥鳅蟗鞦&amp;#34;, &amp;#34;Q鞧蘒鰌鰍鶖龝叴囚扏犰玌朹肍求虬泅虯俅觓訄訅酋唒浗紌莍逎逑釚梂殏毬球赇釻崷巯湭皳盚遒煪絿蛷裘巰觩賕璆蝤銶醔鮂鼽鯄鵭蠤鰽搝糗区曲佉匤岖诎阹驱坥屈岴抾浀祛胠袪區蛆躯筁粬&amp;#34;, &amp;#34;Q蛐詘趋嶇駆憈敺誳駈麹髷趨麯軀麴黢驅鰸鱋佢劬斪朐菃衐鸲淭渠絇葋軥蕖璖磲螶鴝璩翵蟝鼩蘧匷忂灈戵欋氍籧臞癯蠷衢躣蠼鑺鸜取竘娶紶詓竬龋齲厺去刞呿迲郥耝阒觑趣閴麮闃覰覷鼁覻&amp;#34;, &amp;#34;Q峑悛圈圏棬駩騡鐉全权佺诠姾泉洤荃拳牷辁啳埢婘惓痊硂铨湶犈筌絟腃葲搼楾瑔觠詮輇蜷銓権踡縓醛闎鳈鬈孉巏鰁權齤蠸颧顴犬汱畎烇绻綣虇劝券巻牶椦勧韏勸炔缺蒛瘸却埆崅悫雀硞确&amp;#34;, &amp;#34;Q阕塙搉皵阙鹊愨榷墧慤毃確趞燩闋礐闕鵲礭夋囷峮逡宭帬裙羣群裠郄&amp;#34;, &amp;#34;R吺兊兌熯卪坈繚髳挐鈉柟蟯臑抐內涊蹨孃菍莥獳檽蹃亽罖囕呥肰衻袇蚦袡蚺然髥嘫髯燃繎冄冉姌苒染珃媣蒅穣瀼獽禳瓤穰躟鬤壌嚷壤攘爙让懹譲讓荛饶桡橈襓饒犪扰娆隢擾绕遶繞惹热熱&amp;#34;, &amp;#34;R人仁壬忈朲忎秂芢鈓魜銋鵀忍荏栠栣荵秹稔綛躵刃刄认仞仭讱任屻扨纫妊杒牣纴肕轫韧饪姙紉衽紝訒軔梕袵絍腍靭靱韌飪認餁扔仍辸礽芿陾日驲囸釰鈤馹戎肜栄狨绒茙茸荣容峵毧烿媶嵘&amp;#34;, &amp;#34;R絨羢嫆搈搑摉榵溶蓉榕榮熔瑢穁蝾褣镕氄縙融螎駥髶嬫嶸爃鎔瀜曧蠑冗宂傇軵穃厹禸柔粈媃揉渘葇瑈腬糅蝚蹂輮鍒鞣瓇騥鰇鶔楺煣韖肉宍嶿邚如侞帤茹桇袽铷渪筎蒘銣蕠儒鴑嚅嬬孺濡薷&amp;#34;, &amp;#34;R鴽曘燸襦蠕颥醹顬鱬汝肗乳辱鄏入扖込杁洳嗕媷溽缛蓐鳰褥縟擩堧撋壖阮朊软耎偄軟媆愞瑌腝嫰碝緛蝡輭瓀礝桵甤緌蕤蕊蕋橤繠蘂蘃芮枘蚋锐瑞睿叡壡闰润閏閠潤橍叒若偌弱鄀婼渃焫楉&amp;#34;, &amp;#34;R嵶蒻箬篛爇鰙鰯鶸&amp;#34;, &amp;#34;S鉍灬杓攃偲纔參叄叅喰傪穇懆鄵拺笧粣鎈褨剎摻攙摌顫塲場綝乗娍匙飭埫醻敊猭漺輴縒棇楤漎憁缞縗鎝単單擔伔僤宲鍉遞遰挕阇闍陏蘴棴丨鞨咶鏸韢閄靃濈櫼帴菨嫅潏麗攦療蕯瀧氀稤蠰&amp;#34;, &amp;#34;S娞淰掱忯圱圲凵廧薔鐰韒鞩嫀殸棯葚挼仨桬撒洒訯靸潵卅飒脎萨摋隡馺颯薩櫒栍毢愢揌塞毸腮嘥噻鳃顋嗮赛僿賽簺虄三弎叁毵毶厁毿犙鬖壭伞傘散糁糂馓橵糝糣糤繖鏒饊俕閐桒桑槡嗓搡&amp;#34;, &amp;#34;S磉褬颡鎟顙丧喪掻慅搔溞骚缫臊鳋颾騒鰠鱢扫掃嫂埽瘙氉矂髞色栜涩啬渋铯歮琗嗇瑟歰銫澁懎擌濇濏瘷穑澀璱瀒穡繬穯轖鏼譅飋裇聓森槮襂僧鬙閪縇杀沙纱乷砂唦挱猀粆紗莎铩痧硰蔱裟&amp;#34;, &amp;#34;S樧魦鲨閷鎩鯊鯋繺傻儍繌倽唼啥帹萐喢歃煞翜翣閯霎筛篩簁簛晒曬山彡邖圸删刪杉杣芟姗衫钐埏狦珊舢痁脠軕笘閊跚剼搧嘇幓煽蔪潸澘曑檆膻鯅羴羶闪陕炶陝閃晱煔睒熌覢讪汕疝苫扇訕&amp;#34;, &amp;#34;S赸傓善椫銏骟僐鄯墠墡缮嬗擅敾樿膳磰謆赡繕蟮譱贍鐥饍騸鳝灗鱔伤殇商觞傷墒慯滳蔏殤熵螪觴謪鬺裳垧扄晌赏賞鑜丄上仩尙尚恦绱緔弰捎梢烧焼稍旓筲艄蛸輎蕱燒髾鮹勺芍柖玿韶少劭&amp;#34;, &amp;#34;S卲邵绍哨娋袑紹綤潲奢猞赊畲輋賒賖檨舌佘蛇蛥舍捨厍设社舎厙射涉涻渉設赦弽慑摄滠慴摵蔎蠂韘騇懾灄麝欇申屾扟伸身侁呻妽籶绅罙诜柛氠珅穼籸娠峷甡眒砷堔深紳兟椮葠裑訷罧蓡詵&amp;#34;, &amp;#34;S甧蔘燊薓駪鲹鯓鵢鯵鰺神榊鉮鰰邥弞抌沈审矤哂矧宷谂谉婶渖訠審諗頣魫曋瞫嬸瀋覾讅肾侺昚甚胂涁眘渗祳脤腎愼慎椹瘆蜃滲鋠瘮升生阩呏声斘昇枡泩苼殅牲珄竔胜陞曻陹笙湦焺甥鉎聲&amp;#34;, &amp;#34;S鍟鼪鵿绳憴澠譝省眚偗渻圣晟晠剰盛剩勝貹嵊聖墭榺蕂橳賸尸失师呞虱诗邿鸤屍施浉狮師絁湤湿葹溮溼獅蒒蓍詩瑡酾鳲蝨鳾褷鲺鍦鯴鰤鶳襹籭釃十饣什石辻佦时竍识实実旹飠峕拾炻祏蚀&amp;#34;, &amp;#34;S食埘時莳寔湜遈塒嵵溡蒔榯蝕鉽篒鲥鮖鼫鼭鰣史矢乨豕使始驶兘屎笶榁鉂駛士氏礻世丗仕市示卋式叓事侍势呩柹视试饰冟室恀恃拭是枾柿眂贳适栻烒眎眡舐轼逝铈視釈崼弑揓谥貰释勢嗜&amp;#34;, &amp;#34;S弒煶睗筮觢試軾鈰飾舓誓奭噬嬕澨諟諡遾餝螫簭籂襫鰘兙瓧収收手守垨首艏寿受狩兽售授绶痩膄壽瘦綬夀獣獸鏉书殳抒纾叔杸枢陎姝柕倏倐書殊紓掓梳淑焂菽軗鄃疎疏舒摅毹毺綀输跾踈&amp;#34;, &amp;#34;S樞蔬輸橾鮛攄瀭鵨尗秫婌孰赎塾熟璹贖暏暑黍署鼠鼡蜀潻薯曙癙襡糬襩籔蠴鱪鱰朮术戍束沭述侸怷树竖荗恕庶庻絉蒁術裋数竪腧墅漱潄數澍豎樹濖錰鏣鶐虪刷唰耍誜衰摔甩帅帥蟀卛闩拴&amp;#34;, &amp;#34;S閂栓涮腨双滝霜雙孀骦孇騻欆礵鷞鹴艭驦鸘爽塽慡樉縔鏯灀谁脽誰氵水氺閖帨涗涚祱税裞睡吮楯顺舜順蕣橓瞚瞤瞬鬊说妁烁朔铄欶硕矟嗍搠蒴嗽槊碩鎙厶丝司糹私咝泀俬思恖鸶媤斯絲缌&amp;#34;, &amp;#34;S蛳楒禗鉰飔凘厮榹禠罳銯锶嘶噝廝撕澌緦蕬螄鍶蟖蟴颸騦鐁鷥鼶死巳亖四罒寺汜伺似佀兕姒泤祀価孠泗饲驷俟娰柶牭梩洍涘肂飤笥耜釲竢覗嗣肆貄鈻飼禩駟蕼儩騃瀃螦乺忪松枀枩娀柗倯&amp;#34;, &amp;#34;S凇梥崧庺淞菘嵩硹蜙憽檧濍鬆怂悚捒耸竦傱愯嵷慫聳駷讼宋诵送颂訟頌誦餸鎹凁捜鄋嗖廀廋搜溲獀蒐蓃馊飕摗锼艘螋醙鎪餿颼騪叟傁嗾瞍擞薮擻藪櫢瘶苏甦酥稣窣穌鯂蘇蘓櫯囌俗玊夙诉&amp;#34;, &amp;#34;S泝肃洬涑珟素速殐粛骕傃粟訴谡嗉塐塑嫊愫溯溸肅遡鹔僳愬榡膆蔌觫趚遬憟樎樕潥鋉餗縤璛簌藗謖蹜驌鱐鷫狻痠酸匴祘笇筭蒜算夊芕虽倠哸浽荽荾眭葰滖睢熣濉鞖雖绥隋随遀綏隨瓍膸瀡&amp;#34;, &amp;#34;S髄髓亗岁砕祟粋谇埣嵗脺遂歲歳煫碎隧嬘澻穂誶賥檖燧璲禭穗穟繀襚邃旞繐繸鐆譢鐩孙狲荪飧搎猻蓀飱槂蕵薞畃损笋隼損榫箰鎨巺潠唆娑莏傞挲桫梭睃嗦羧蓑摍缩趖簑簔縮髿鮻所唢索琐&amp;#34;, &amp;#34;S琑惢锁嗩暛溑瑣鎍鎖鎻鏁逤溹蜶厦忄莘疋栅属&amp;#34;, &amp;#34;T諳啚裧儃禪蟬繵閶瞋鐺珵侱漦爞綢籌俶埱蓴鶉鈶撘迏迖沓荅逹溚達鎉韃呔蚮軚貸癉撣嘾彈餤黨攩欓逿蕩簜蘯闣朷焘燾僜奃髢詆弚苐媂諦顚顛鈿调蓧啑惵趃奵忊墥峝湩詷钭鋀褍蜳橔囤庉憞&amp;#34;, &amp;#34;T燉軃鋨鞈騩咍漢宊她冂燑轁墤謉饋噋擴斄伖鍩奤嵜鉆汭蟺鱓愓漡苕萔姼忕徥褆扌涭瑹儵稅磃鋖枱他它牠祂咜趿铊塌榙溻褟蹹侤塔墖獭鮙鳎獺鰨挞狧闼崉涾搨遝遢阘榻毾禢撻澾誻踏嚃錔嚺&amp;#34;, &amp;#34;T濌蹋鞜闒鞳闥譶躢襨囼孡骀胎台邰坮抬苔炱炲跆鲐箈臺颱儓鮐嬯擡薹檯籉太冭夳忲汰态肽钛泰粏舦酞鈦溙態燤坍贪怹啴痑舑貪摊滩嘽潬瘫擹攤灘癱坛昙倓谈郯婒惔弾覃榃痰锬谭墰墵憛潭&amp;#34;, &amp;#34;T談醈壇曇檀顃罈藫壜譚貚醰譠罎鷤忐坦袒钽菼毯鉭嗿憳憻暺醓璮叹炭埮探傝湠僋嘆碳舕歎賧汤铴嘡劏羰蝪薚镗蹚鏜鐋鞺鼞饧坣唐堂傏啺棠鄌塘嵣搪溏蓎隚榶漟煻瑭禟膅樘磄糃膛橖篖糖螗&amp;#34;, &amp;#34;T踼糛螳赯醣鎕餹闛饄鶶帑倘偒淌傥耥躺镋鎲儻戃曭爣矘钂烫摥趟燙仐夲弢涛绦掏絛詜嫍幍慆搯滔槄瑫韬飸縚縧濤謟鞱韜饕迯咷洮逃桃陶啕梼淘绹萄祹裪綯蜪鞀醄鞉鋾錭駣檮騊鼗讨套討畓&amp;#34;, &amp;#34;T忑忒特貣脦铽慝鋱蟘膯鼟疼痋幐腾誊漛滕邆縢螣駦謄儯藤騰籐鰧籘虅驣霯唞朰剔梯锑踢銻鷈鷉厗绨偍珶啼崹惿提渧稊缇罤遆鹈嗁瑅綈碮徲漽緹蕛蝭题趧蹄醍謕蹏鍗鳀題鮷鵜騠鯷鶗鶙体挮&amp;#34;, &amp;#34;T躰骵軆體戻屉剃洟倜悌涕逖悐惕掦逷惖揥替楴裼褅殢髰嚏鬀瓋鬄籊天兲婖添酟靔黇靝田屇沺恬畋畑胋畠甛甜菾湉填搷阗碵緂磌窴鴫璳闐鷆鷏忝殄倎唺悿捵淟晪琠腆觍痶睓舔餂覥賟錪靦掭&amp;#34;, &amp;#34;T瑱睼舚旫佻庣挑祧聎芀条岧岹迢祒條笤蓚龆樤蜩鋚鞗髫鲦螩鯈鎥齠鰷宨晀朓脁窕誂窱嬥眺粜絩覜趒跳頫糶贴萜貼铁蛈僣鴩鐡鐵驖呫帖飻餮厅庁汀艼听耓厛烃烴綎鞓聴聼廰聽廳邒廷亭庭莛&amp;#34;, &amp;#34;T停婷嵉渟筳葶蜓楟榳閮霆聤蝏諪鼮圢侹娗挺涏梃烶珽脡艇颋誔鋌頲濎乭囲炵通痌嗵蓪樋熥仝同佟彤峂庝哃狪茼晍桐浵烔砼蚒眮秱铜童粡絧衕酮鉖僮勭銅餇鲖潼曈朣橦氃犝膧瞳鮦统捅桶筒&amp;#34;, &amp;#34;T統綂恸痛慟憅偷偸鍮头投骰頭妵紏敨斢黈蘣透凸禿秃怢突唋涋捸堗湥痜葖嶀鋵鵚鼵図图凃峹庩徒捈涂荼途屠梌揬稌塗嵞瘏筡腯蒤鈯圖圗廜跿酴馟鍎駼鵌鶟鷋鷵土圡吐汢钍釷兎迌兔莵堍菟&amp;#34;, &amp;#34;T鵵湍猯煓貒团団抟團慱槫檲鏄糰鷒鷻圕疃彖湪褖推蓷藬颓隤頹頺頽魋穨蘈蹪俀脮腿僓蹆骽退娧煺蜕褪駾吞呑朜焞暾黗屯芚饨豘豚軘鲀魨霕臀臋氽畽坉乇讬托汑饦侂咃拕拖沰侻莌袥託涶脫&amp;#34;, &amp;#34;T脱飥魠驮佗陀坨岮沱驼柁砣砤袉鸵紽堶跎酡碢馱槖駄踻駝駞橐鮀鴕鼧騨鼍驒鼉妥毤庹媠椭楕嫷橢鵎拓柝唾跅毻箨籜&amp;#34;, &amp;#34;U辪癷袰蝊曢聣烪燞躼蒊蓞耂稥洜毜毝茒桛毮朑焽虲鶑鎼鐢艈霻闧焑屗歚徚鍂藔贘皼斏聁祍&amp;#34;, &amp;#34;W趡惡噁唲陚龏萖関闗關貫窐姽恑瞶咼堝濄幠膴鋘譁瀤綄朚撝蒦嚄擭雘艧扝噲抂巋磈薶槾鄤澫堥夘呅韎雺霿沕忞鴖譕帓歾靺瞴蟱墲娒孯掔瓗渞蜹捼琞亠撱鰖屲劸哇娃徍挖洼娲畖窊媧嗗蛙搲&amp;#34;, &amp;#34;W溛漥窪鼃攨瓦佤邷咓瓲砙袜嗢腽膃襪韈韤歪喎竵崴外弯剜婠帵塆湾睕蜿潫豌彎壪灣丸刓汍纨芄完岏忨抏玩笂紈捖顽烷琓貦頑邜宛倇唍挽晚盌埦婉惋晩梚绾脘菀晼椀琬皖畹碗綩綰輓踠鋔鍐&amp;#34;, &amp;#34;W万卍卐杤捥腕萬翫鋄薍錽贃鎫贎尩尪尫汪亡亾兦王仼彺莣蚟网忹往徃枉罔惘菵暀棢焹蛧辋網蝄誷輞瀇魍妄忘迋旺盳望朢危威烓偎逶隇隈喴媁媙愄揋揻渨煀葨葳微椳楲溦煨詴縅蝛覣嶶薇鳂&amp;#34;, &amp;#34;W癐巍鰃鰄囗为韦围帏沩违闱峗峞洈為韋桅涠唯帷惟维喡圍嵬幃湋溈爲違潍蓶鄬潙潿濰鍏闈鮠癓覹犩霺伟伪尾纬芛苇委炜玮洧娓捤浘荱诿偉偽崣梶硊萎隗骩嵔廆徫愇猥葦蒍骪骫暐椲煒瑋痿&amp;#34;, &amp;#34;W腲艉韪僞碨蜲蜼鲔寪緯蔿諉踓韑頠儰濻鍡鮪壝韙颹瀢亹斖卫未位味苿畏胃軎尉硙菋谓喂媦渭猬煟墛蔚慰熭犚磑緭蝟衛懀濊璏罻衞謂餧鮇螱褽餵魏藯轊鏏霨鳚蘶饖讆躗讏躛昷塭温殟溫瑥榲&amp;#34;, &amp;#34;W瘟豱鳁鎾饂鰛鰮文彣纹芠炆砇闻紋蚉蚊珳阌鈫雯瘒聞馼魰鳼鴍螡閺閿蟁闅鼤闦刎吻呚忟抆呡肳紊桽脗稳穏穩问妏汶莬問渂脕揾搵絻顐璺翁嗡鹟螉鎓鶲奣塕嵡滃蓊暡瞈聬瓮蕹甕罋齆挝倭涡&amp;#34;, &amp;#34;W莴唩涹渦猧萵喔窝窩蜗蝸踒我婐婑捰仴沃肟卧臥偓媉幄握渥焥硪楃腛斡瞃濣瓁龌齷乌圬弙污邬呜杇巫屋洿诬钨趶剭窏釫鄔嗚誈誣箼螐鴮鎢鰞无毋吴吾呉芜梧洖浯茣莁珸祦鹀無禑蜈蕪璑鵐&amp;#34;, &amp;#34;W鯃鼯鷡乄五午仵伍坞妩庑忤怃迕旿武玝侮俉倵捂啎娬牾珷塢摀熓碔鹉瑦舞嫵廡憮潕錻儛橆甒鵡躌兀勿务戊阢伆屼扤岉杌芴忢物矹敄误務悞悟悮粅逜晤焐婺嵍痦隖靰骛奦嵨溩雾寤熃誤鹜鋈&amp;#34;, &amp;#34;W窹霚鼿霧齀蘁騖鶩&amp;#34;, &amp;#34;X欸庍壆扱烲愖糦臰欪滀嘼錯廗諜摡給蚼規嶲鮭巂鬹咁譀迒茠滈欱郃螛嗃熇燺揈閧闀闂鬨銗謼滸芐觟懁郇狟澴還镮鐶儶譮孈葷轋掝擊彐蔇縘繫夾埉浹傢裌叚徦鰔梘筧礆見閒瞯鵁轇驕絞較湝&amp;#34;, &amp;#34;X頡觧吤繲坙巠坓顈眗鼰鼳鋗絹獧決泬勪噱姰濬愾埳堿闞晇欵歀潰搚懢壏嘮釐溓蘝蘞稴漻衖莔禰瓕賯撓譊鉨鉩煖謳嘔盤嚊恓棲諿氣欦臤慳荨羬蕁槏伣俔嗛骹燆睄綅瓊蓲鱃魼胊卻舃碏儴勷蘘&amp;#34;, &amp;#34;X纕繻灑钑鈒鰓騷雭殺榝姍釤縿莦颵姺濕宩昰笹齛咰鉥獡箾蜤燍叜宿碿潚橚孫鶽橝撢餳饀屜歒盷蓨赨緰圩韡捾夕兮忚汐西覀吸希卥昔析矽穸肸肹俙徆怸郗饻唏奚娭屖息悕晞氥浠牺狶莃唽悉&amp;#34;, &amp;#34;X惜桸欷淅渓烯焁焈琋硒菥赥釸傒惁晰晳焟犀睎稀粞翕翖舾鄎厀嵠徯溪煕皙蒠锡僖榽熄熙緆蜥豨餏嘻噏嬆嬉瘜膝餙凞樨橀歙熹熺熻窸羲螅螇錫燨犠瞦礂蟋谿豀豯貕繥雟鯑鵗觹譆醯鏭隵巇曦&amp;#34;, &amp;#34;X爔犧酅觽鼷蠵鸂觿鑴习郋席習袭觋媳椺蒵蓆嶍漝覡趘槢蝷薂隰檄謵鎴霫鳛飁騱騽襲鰼驨枲洗玺徙铣喜葈葸鈢屣漇蓰銑憘憙暿橲禧諰壐縰謑蟢蹝璽鱚矖纚躧匸卌戏屃系饩呬忥怬细係恄盻郤&amp;#34;, &amp;#34;X欯绤細釳阋塈椞舄趇隙慀滊禊綌赩隟熂犔稧戯潟澙蕮覤戱黖戲磶虩餼鬩嚱闟霼衋虾谺傄閕敮煆颬瞎蝦鰕匣侠狎俠峡柙炠狭陜峽烚狹珨祫硖笚翈舺陿溊硤遐搳暇瑕筪碬舝辖縀蕸縖赮魻轄鍜&amp;#34;, &amp;#34;X霞鎋黠騢鶷閜丅下吓圷疜夏梺廈睱諕嚇懗罅夓鏬仙仚屳先奾纤佡忺氙杴祆秈苮籼珗莶掀铦跹酰锨僊僲嘕銛鲜暹韯憸鍁繊褼韱鮮馦蹮孅廯攕譣纎鶱襳躚纖鱻伭咞闲妶弦贤咸挦涎胘娴娹婱絃&amp;#34;, &amp;#34;X舷蚿衔啣痫蛝閑鹇嫌甉銜嫺嫻憪撏澖誸賢諴輱醎癇癎藖鹹礥贒鑦鷳鷴鷼冼狝显险毨烍猃蚬険赻筅尟尠搟禒蜆跣箲獫獮藓鍌燹顕幰攇櫶蘚玁韅顯灦县岘苋现线臽限姭宪県陥哯垷娊娨峴晛涀&amp;#34;, &amp;#34;X莧陷現馅睍絤缐羡献粯腺僩僴綫誢撊線鋧憲橌縣錎餡豏瀗臔獻糮鏾霰鼸乡芗相香郷厢啌鄉鄊廂湘缃葙鄕楿薌箱緗膷襄忀骧麘欀瓖镶鱜鑲驤瓨佭详庠栙祥絴翔跭享亯响蚃饷晑飨想銄餉鲞嚮&amp;#34;, &amp;#34;X蠁鯗響饗饟鱶向姠巷项珦象缿萫項像勨嶑曏橡襐蟓鐌鱌灱灲呺枭侾削哓枵骁宯宵庨恷消绡虓逍鸮啋婋梟焇猇萧痚痟硝硣窙翛萷销揱綃嘐歊潇箫踃嘵憢撨獢銷霄彇膮蕭魈鴞穘簘藃蟂蟏謞鴵&amp;#34;, &amp;#34;X嚣瀟簫蟰髇嚻囂櫹髐鷍蠨驍毊虈洨郩崤淆訤誵小晓暁筱筿皛曉篠謏皢孝肖効咲恔俲哮效校涍笑啸傚敩滧詨嘋嘨誟嘯歗熽斅斆些楔歇蝎蠍劦协旪邪協胁垥奊恊拹挾脅脇脋衺偕斜谐猲絜翓嗋&amp;#34;, &amp;#34;X愶携瑎綊熁膎勰撷擕緳缬蝢鞋諧燲擷鞵襭攜纈讗龤写冩寫藛伳灺泄泻祄绁缷卸炧炨卨娎屑屓偰徢械焎禼亵媟屟揳渫絬谢僁塮榍榭褉噧屧暬韰嶰廨懈澥獬糏薢薤邂燮褻謝夑瀉瀣爕蟹蠏齘齥&amp;#34;, &amp;#34;X齂躠屭躞心邤妡忻芯辛昕杺欣盺俽惞鈊锌新歆廞噷噺嬜薪馨鑫馫枔鬵鐔伈潃阠伩囟孞炘信軐脪衅訫焮馸舋顖釁兴狌星垶骍惺猩煋瑆腥蛵觪箵篂興謃曐觲騂皨刑邢形陉侀郉哘型洐钘陘娙硎&amp;#34;, &amp;#34;X裄铏鈃鉶銒鋞睲醒擤杏姓幸性荇倖莕婞悻涬塂緈嬹臖凶兄兇匈芎讻忷汹哅恟洶胷胸訩詾雄熊诇詗夐敻休俢修咻庥烋烌羞脙鸺臹貅馐樇銝髤髹鎀鮴鵂饈鏅飍苬朽綇滫糔秀岫珛绣袖琇锈溴綉&amp;#34;, &amp;#34;X璓裦螑繍繡鏥鏽齅戌旴疞盱欨胥须訏顼虗虚谞媭幁揟欻虛須楈窢頊嘘稰需魆噓墟嬃歔縃蕦蝑歘諝譃魖驉鑐鬚俆徐蒣许呴姁诩冔栩珝偦許湑暊詡鄦糈醑盨旭伵序汿侐卹沀叙恤昫洫垿欰殈烅&amp;#34;, &amp;#34;X珬勖勗敍敘烼绪续酗喣壻婿朂溆絮訹嗅慉煦続蓄賉槒漵潊盢瞁緒聟銊稸緖瞲藚續蓿吅轩昍咺宣晅軒梋谖喧塇媗愃愋揎萱萲暄煊瑄蓒睻儇禤箮翧蝖嬛蕿諠諼鍹駽矎翾藼蘐蠉譞鰚讂玄玹痃悬&amp;#34;, &amp;#34;X旋琁蜁嫙漩暶璇檈璿懸选烜暅選癣癬怰泫昡炫绚眩袨铉琄眴衒渲絢楦鉉碹蔙镟鞙颴縼繏鏇贙疶蒆靴薛鞾穴斈乴坹学岤峃茓泶袕鸴踅學嶨澩燢觷雤鷽雪樰膤艝轌鳕鱈血吷怴泧狘疦桖烕谑趐&amp;#34;, &amp;#34;X謔瀥坃勋埙焄勛塤熏窨蔒勲勳薫駨嚑壎獯薰曛燻臐矄蘍壦爋纁醺寻巡旬驯杊询峋恂洵浔紃荀栒桪毥珣偱尋循揗詢馴鄩鲟噚攳樳燂燅燖璕襑蟳鱏鱘灥卂训讯伨汛迅侚徇狥迿逊殉訊訓訙奞巽&amp;#34;, &amp;#34;X殾遜愻賐噀蕈顨鑂吁&amp;#34;, &amp;#34;Y叆賹礙譺靉菴媕葊痷闇鵪鶕晻洝媼澚墺驁頨瑒耛拸呾訑婸潒扚昳屵姶堊搤閼煾妋鳱輵夃焸蠱溎裷緷蟈淊嚛欥瓛輐喛揘韹熀袆煇褘蚘噦矆拁玪豜豣將侥烄僥伒莖俓泂揂圧僪貗飬妜焆鐍炏顑&amp;#34;, &amp;#34;Y丂髺樂貍櫟躒輅擽嫚玅桙獶輗掜孴儗肀喦噛槷嚙钀汼齵堷踦锜錡裿綺鉛膁羗撽赺欽汓翑蝺輑橪蕘嬈嵤銳鋭挻烻剡虵縄繩鱦釶鉇箷戺謚釋哾說説爍鑠梀筍鉈珆旲錟湯匋鴺趯恌銕桯筩婾媮殕&amp;#34;, &amp;#34;Y悇蛻涒扡挩捝狏迱詑彵啘乛涴妧尣燰琟維厃痏薳叞榅辒輼轀勜臒汙汚烏歍吳郚娪焬熈誒歖潝疨磍嬐薟唌湺衘崄險嶮硍羨麲詳峫鐷洩紲絏緤訢脩褎褏銹獝藇鱮楥辥廵潯丫压呀庘押鸦桠鸭孲&amp;#34;, &amp;#34;Y铔椏鴉錏鴨壓鵶鐚牙伢岈芽厓枒琊笌蚜堐崕崖涯猚瑘睚衙漄齖厊庌哑唖啞痖雅瘂蕥劜圠亚穵襾讶亜犽迓亞玡垭娅挜砑俹氩埡婭掗訝揠氬猰聐圔稏窫齾咽恹剦烟珚胭偣崦淹焉菸阉湮腌傿煙&amp;#34;, &amp;#34;Y鄢嫣漹嶖樮醃閹嬮篶懕臙黫讠円延闫严妍芫言訁岩昖沿炎郔姸娫狿研莚娮盐琂硏訮閆阎嵒嵓筵綖蜒塩揅楌詽碞蔅颜虤閻厳檐顏顔嚴壛巌簷櫩麙壧孍巖巗巚欕礹鹽麣夵抁沇乵兖奄俨兗匽弇&amp;#34;, &amp;#34;Y衍偃厣掩眼萒郾酓嵃愝扊揜棪渰渷琰遃隒椼硽罨裺演褗戭蝘魇噞躽縯檿黡厴甗鰋鶠黤齞龑儼黬黭顩鼴巘曮魘鼹齴黶厌妟觃牪姲彥彦砚唁宴晏艳覎验偐掞焔谚隁喭堰敥焰焱猒硯葕雁椻滟鳫&amp;#34;, &amp;#34;Y厭墕暥熖酽嬊谳餍鴈燄燕諺赝鬳曕鴳酀騐験嚥嬿艶贋軅爓醶騴鷃灔贗觾讌醼饜驗鷰艷灎釅驠灧讞豓豔灩央咉姎抰泱殃胦眏秧鸯鉠雵鞅鍈鴦扬羊阦阳旸杨炀佯劷氜疡钖飏垟徉昜洋羏烊珜眻&amp;#34;, &amp;#34;Y陽崵崸揚蛘敭暘楊煬禓瘍諹輰鍚鴹颺鐊鰑霷鸉卬仰佒坱奍岟养炴氧痒紻傟楧軮慃氱羪養駚懩攁瀁癢礢怏柍恙样羕詇様漾樣幺夭吆妖枖祅訞喓葽楆腰鴁邀爻尧尭肴垚姚峣轺倄烑珧窑傜堯揺&amp;#34;, &amp;#34;Y殽谣軺嗂媱徭愮搖摇猺遙遥摿暚榣瑤瑶銚飖餆嶢嶤徺磘窯窰餚繇謠謡鳐颻蘨顤鰩仸宎岆抭杳殀狕苭咬柼眑窅窈舀偠婹崾溔榚鴢闄騕齩鷕穾药要袎窔筄葯詏熎覞靿獟鹞薬鼼曜燿艞藥矅曣耀&amp;#34;, &amp;#34;Y纅鷂讑鑰倻椰暍噎潱蠮爷耶捓揶铘爺釾鋣鎁擨也吔亪冶埜野嘢漜壄业叶曳页邺夜抴亱枼洂頁晔枽烨掖液谒堨殗腋葉鄓墷楪業馌僷曄曅歋燁擛皣瞱鄴靥嶪嶫澲謁餣嚈擫曗瞸鍱擪爗礏鎑饁鵺&amp;#34;, &amp;#34;Y靨驜鸈膶岃一弌辷衤伊衣医吚壱依祎咿洢猗畩郼铱壹揖欹蛜禕嫛漪稦銥嬄噫夁瑿鹥繄檹毉醫黟譩鷖黳乁仪匜圯夷冝宐沂诒侇宜怡沶狋衪迤饴咦姨峓弬恞柂瓵荑贻迻宧巸扅栘桋眙胰袘酏痍&amp;#34;, &amp;#34;Y移萓媐椬羠蛦詒貽遗暆椸誃跠頉颐飴疑儀熪遺嶬彛彜螔頤頥寲嶷簃顊鮧彝彞謻鏔籎觺讉鸃乙已以迆钇佁攺矣苡苢庡舣蚁釔倚扆笖逘偯崺旑椅鈘鉯鳦旖輢敼螘檥礒艤蟻顗轙齮乂义亿弋刈忆&amp;#34;, &amp;#34;Y艺仡匇肊议阣亦伇屹异忔芅伿佚劮呓坄役抑曵杙耴苅译邑佾呭呹峄怈怿易枍泆炈绎诣驿俋奕帟帠弈枻浂玴疫羿衵轶唈垼悒挹栧欭浥浳益袣谊貤陭勚埶埸悘悥殹異羛翊翌萟訲訳豙豛逸釴隿&amp;#34;, &amp;#34;Y幆敡晹棭殔湙焲蛡詍跇鈠骮亄兿意溢獈痬竩缢義肄裔裛詣勩嫕廙榏潩瘗膉蓺蜴靾駅億撎槸毅熠熤熼瘞誼镒鹝鹢黓劓圛墿嬑嬟嶧憶懌曀殪澺燚瘱瞖穓縊艗薏螠褹寱斁曎檍歝燡燱翳翼臆貖鮨&amp;#34;, &amp;#34;Y癔藙藝贀鎰镱繶繹豷霬鯣鶂鶃鶍瀷蘙譯議醳醷饐囈鐿鷁鷊懿襼驛鷧虉鷾讛齸乚囙因阥阴侌垔姻洇茵荫音骃栶殷氤陰凐秵裀铟陻隂喑堙婣愔筃絪歅溵禋蒑蔭慇瘖銦磤緸鞇諲霒駰噾濦闉霠韾&amp;#34;, &amp;#34;Y冘吟犾苂垠泿圁峾烎狺珢粌荶訔唫婬寅崟崯淫訡银鈝龂滛碒鄞夤蔩訚誾銀龈噖殥璌嚚檭蟫霪齗齦鷣尹引吲饮蚓隐淾釿鈏飲隠靷飮朄趛檃瘾隱嶾濥螾蘟櫽癮讔印茚洕胤垽湚猌廕酳慭癊憖憗&amp;#34;, &amp;#34;Y鮣懚檼应応英偀桜珱莺啨婴媖愥渶绬朠煐瑛嫈碤锳嘤撄滎甇緓缨罂蝧賏樱璎噟罃褮霙鴬鹦嬰應膺韺甖鎣鹰鶧嚶孆孾攖瀴罌蘡櫻瓔礯譻鶯鑍纓蠳鷪軈鷹鸎鸚盁迎茔盈荥荧莹萤营萦蛍営溁溋&amp;#34;, &amp;#34;Y萾僌塋楹滢蓥潆熒蝇瑩蝿嬴營縈螢濙濚濴藀覮謍赢巆攍攚瀛瀠瀯蠅櫿灐籝灜贏籯矨郢梬颍颕颖摬影潁瘿穎頴巊廮鐛癭映暎硬媵膡鞕瀅譍哟唷喲佣拥痈邕庸傭嗈鄘雍墉嫞慵滽槦牅噰壅擁澭&amp;#34;, &amp;#34;Y郺镛臃癕雝鏞鳙廱灉饔鱅鷛癰喁颙顒鰫永甬咏怺泳俑勇勈栐埇悀柡涌恿傛惥愑湧硧詠塎嵱彮愹蛹慂踊禜鲬踴鯒用苚砽醟优忧攸呦怮泑幽悠麀滺憂優鄾嚘懮瀀櫌纋耰尢尤由沋犹邮怞油肬怣&amp;#34;, &amp;#34;Y斿柚疣峳浟秞莜莤莸逌郵铀偤蚰訧逰游猶遊鱿楢猷鲉輏駀蕕蝣魷輶鮋櫾邎友有丣卣苃酉羑庮羐莠梄聈脜铕湵蒏禉蜏銪槱牖牗黝又右幼佑侑孧狖糿哊囿姷宥峟牰祐诱迶唀梎蚴亴貁釉酭誘鼬&amp;#34;, &amp;#34;Y扜纡迂迃穻陓紆虶唹淤盓渝瘀箊于亐予邘伃余妤扵杅欤玗玙於盂臾衧鱼俞兪禺竽舁茰荢娛娯娱狳谀酑馀渔萸釪隃隅雩魚堣堬崳嵎嵛愉揄楰湡畬畭硢腴逾骬愚楡榆歈牏瑜艅虞觎漁睮窬舆褕&amp;#34;, &amp;#34;Y歶羭蕍蝓諛雓餘魣嬩懙澞覦踰歟璵螸輿鍝礖謣髃鮽旟籅騟鯲鰅鷠鸆与伛宇屿羽雨俁俣挧禹语圄峿祤偊匬圉庾敔鄅萭萮铻傴寙斞楀瑀瘐與語窳鋙龉噳嶼貐斔麌蘌齬玉驭聿芋芌妪忬饫育郁彧&amp;#34;, &amp;#34;Y昱狱秗茟俼峪栯浴砡钰预喐域堉悆惐欲淢淯袬谕逳阈喅喩喻媀寓庽御棛棜棫焴琙矞裕遇飫馭鹆愈滪煜稢罭蒮蓣誉鈺預嫗嶎戫毓獄瘉緎蜟蜮輍銉隩噊慾稶蓹薁豫遹鋊鳿澦燏燠蕷諭錥閾鴥鴧&amp;#34;, &amp;#34;Y鴪儥礇禦魊鹬癒礜穥篽繘醧鵒櫲饇蘛譽轝鐭霱欎驈鬻籞鱊鷸鸒欝軉鬰鬱灪籲爩囦鸢剈冤弲悁眢鸳寃渁渆渊渕惌淵葾棩蒬蜎鹓箢鳶蜵駌鋺鴛嬽鵷灁鼘鼝元贠邧员园沅杬垣爰貟原員圆笎蚖袁&amp;#34;, &amp;#34;Y厡酛圎援湲猨缘鈨鼋園圓塬媴嫄源溒猿獂蒝榞榬辕緣縁蝝蝯魭橼羱薗螈謜轅黿鎱櫞邍騵鶢鶰厵远盶逺遠夗肙妴苑怨院垸衏傆媛掾瑗禐愿裫褑褤噮願曰曱约約箹矱彟彠月戉刖岄抈礿岳枂玥&amp;#34;, &amp;#34;Y恱钥悅悦蚎蚏軏钺阅捳跀跃粤越鈅粵鉞閱閲嬳樾篗嶽龠籆瀹蘥黦爚禴躍籥鸑籰龥鸙蒀煴蒕熅奫蝹赟頵馧贇云勻匀伝呍囩妘抣沄纭芸昀畇眃秐郧涢紜耘耺鄖雲愪氲溳筼蒷氳熉澐蕓鋆橒篔縜&amp;#34;, &amp;#34;Y繧允阭夽抎狁玧陨荺殒喗鈗隕殞褞馻磒霣齫齳孕运枟郓恽晕鄆酝傊惲愠缊運慍暈腪韫韵熨緼蕰蕴縕薀賱醖醞餫藴韗韞蘊韻這&amp;#34;, &amp;#34;Z敱捗囃謲匨蔵冊側厠廁嶒扠挿揷蹅茝僝欃倀长仧長镸鼌鼂謿謓迧陳鈂趂朾脀憕徎胵絺泜歭遟遲迣徸漴褈緟蝩蟲紬搊椆詶薵偢芻鉏蕏傳鶨倕埀箠鎚純湻辶腏趠齱骴薋泚跐從蓯樅熜緫潀潈潨&amp;#34;, &amp;#34;Z酢噈欑穳篹嶉槯伜倅紣綷顇墫拵踆睉蔖剳蹛黱酖亶翢篴拞牴觝啇摕蝃踶點鳭調藋喋臷鰈眰鼑枓剢耑磓隊腞夛仛喥柮樲胕阝贛戇滜睪牫贑嫢啈楖嚌璾鯽穧椾碊鳽餰栫袸濺瀳鏩繳擳竧鳩砠蓻&amp;#34;, &amp;#34;Z齟怚跙脧雋捔逫嵁沴酈譧驡狵沵摨聶囁釽亝祇蚔齊磩鈆謙綪繰菬埥軽鯖伹岨恮跧甽繅洓篸箑摂攝鉐實識亊鉃適銴檡薥藷鸀尌虒睟簨駘菭襢犆媞薙嚔鐟塡怗聑跕鉄鉵獞穜潳剬剸塼摶漙篿尵&amp;#34;, &amp;#34;Z旽啍忳飩杔馲驝陁萚蘀聉顡醀錗撾扸杫咥枮鮝鞢鋅鮏鯹鎐蓔捙偞擖杝妷秇栺軼乑斦浧銿鈾圫汋帀匝沞咂拶沯桚紥紮鉔魳臜臢杂砸韴雑磼襍雜囐雥災灾甾哉栽烖菑渽溨睵賳宰载崽載再在扗&amp;#34;, &amp;#34;Z洅傤酨儎縡兂糌簪簮鐕咱偺喒昝寁撍儧攒儹攢趱趲暂暫賛赞錾鄼濽蹔酂瓉贊鏨瓒酇囋灒讃瓚禶襸讚饡牂羘赃賍臧賘贓髒贜驵駔奘弉脏塟葬銺臓臟傮遭糟蹧醩凿鑿早枣栆蚤棗璅澡璪薻藻灶&amp;#34;, &amp;#34;Z皁皂唕唣造梍喿慥煰艁噪簉燥竃譟趮躁竈啫伬则択沢择泎泽责迮則唶啧帻笮舴責溭矠嘖嫧幘箦蔶樍歵諎赜擇澤皟瞔簀耫礋襗謮賾蠌齚齰鸅仄夨庂汄昃昗捑崱稄贼賊鲗蠈鰂鱡怎谮譖譛囎曽&amp;#34;, &amp;#34;Z増鄫增憎缯橧熷璔矰磳罾繒譄鱛锃鋥甑赠贈吒迊咋抯挓柤哳偧喳揸渣溠楂劄皶箚樝觰皻譇齄齇扎札甴轧軋闸蚻铡煠牐閘霅鍘譗厏苲眨砟搩鲊鲝踷鮓鮺乍灹诈咤奓柵炸宱痄蚱詐搾摣榨醡夈&amp;#34;, &amp;#34;Z粂捚斋斎摘榸齋宅翟窄鉙债砦債寨瘵沾毡旃栴粘蛅飦惉詀趈詹閚谵噡嶦薝邅霑氈氊瞻鹯旜譫饘鳣驙魙鱣鸇讝拃斩飐展盏崭斬琖搌盞嶃嶄榐辗颭嫸醆橏蹍輾皽黵占佔战栈桟站偡绽菚棧湛戦&amp;#34;, &amp;#34;Z綻嶘輚戰虥虦覱轏蘸驏张弡張章傽鄣嫜彰慞漳獐粻蔁遧暲樟璋餦蟑鏱騿鱆麞仉涨涱掌漲幥礃鞝鐣丈仗扙帐杖胀账粀帳脹痮障墇嶂幛賬瘬瘴瞕佋钊妱巶招昭炤盄釗啁鉊駋窼鍣爫找沼瑵召兆&amp;#34;, &amp;#34;Z诏枛垗狣赵笊肁旐棹罀詔照罩箌肇肈趙曌燳鮡櫂瞾羄蜇嫬遮厇折歽矺砓籷虴哲埑粍袩啠悊晢晣辄喆棏蛰詟谪摺輒樀磔輙銸辙蟄嚞謫謺鮿轍讁襵讋者锗赭褶鍺这柘浙淛嗻蔗樜鹧蟅鷓贞针侦&amp;#34;, &amp;#34;Z浈珍珎貞帪栕桢眞真砧祯針偵敒桭酙寊湞葴遉搸斟楨獉甄禎蒖蓁鉁靕榛槇殝瑧碪禛潧箴樼澵臻薽錱轃鍖鍼籈鱵屒诊抮枕姫弫昣胗轸畛疹眕袗紾聄萙裖覙診軫嫃缜稹駗縝縥辴鬒黰圳阵纼侲&amp;#34;, &amp;#34;Z挋陣鸩振朕栚紖眹赈塦揕絼蜄敶誫賑鋴镇震鴆鎭鎮黮凧争佂姃征怔爭峥挣炡狰烝眐钲埩崝崢掙猙睁聇铮媜揁筝徰睜蒸鉦徴箏徵踭篜錚鬇癥氶抍糽拯掟塣晸愸撜整正证诤郑帧政症幀証鄭諍&amp;#34;, &amp;#34;Z鴊證之支卮汁芝吱巵汥枝知织肢徔栀祗秓秖胑胝衹衼倁疷祬秪脂隻梔戠椥臸搘禔綕榰蜘馶鳷謢鴲織蘵鼅禵执侄坧直姪値值聀釞埴執职植殖禃絷跖瓡墌摭馽嬂慹漐踯樴膱縶職蟙蹠蹢軄躑止&amp;#34;, &amp;#34;Z只凪劧旨阯址坁帋扺汦沚纸芷抧祉茋咫恉指枳洔砋轵淽疻紙訨趾軹黹酯藢襧阤至芖志忮扻豸制厔垁帙帜治炙质郅俧峙庢庤挃柣栉洷祑陟娡徏挚晊桎狾秩致袟贽轾乿偫徝掷梽猘畤痔秲秷窒&amp;#34;, &amp;#34;Z紩翐袠觗貭铚鸷傂崻彘智滞痣蛭骘寘廌搱滍稙稚筫置跱輊锧雉墆槜滯潌疐瘈製覟誌銍幟憄摯潪熫稺膣觯質踬鋕旘瀄緻隲駤鴙儨劕懥擲擿櫛穉螲懫贄櫍瓆觶騭鯯礩豑騺驇躓鷙鑕豒中伀汷刣&amp;#34;, &amp;#34;Z妐彸迚忠泈炂终柊盅衳钟舯衷終鈡幒蔠锺螤鴤螽鍾鼨蹱鐘籦肿种冢喠尰塚歱煄腫瘇種踵仲众妕狆祌茽衶重蚛偅眾堹媑筗衆諥州舟诌侜周洀洲炿诪烐珘辀郮婤徟淍矪週鸼喌粥赒輈銂賙輖霌&amp;#34;, &amp;#34;Z駲嚋盩謅鵃騆譸妯轴軸碡肘帚疛菷晭睭箒鯞纣伷呪咒宙绉冑咮昼紂胄荮晝皱酎粙葤詋甃僽皺駎噣縐骤籀籕籒驟朱劯侏诛邾洙茱株珠诸猪硃袾铢絑蛛誅跦槠潴蝫銖橥諸豬駯鮢鴸瀦藸櫧櫫鼄&amp;#34;, &amp;#34;Z鯺蠩竹泏竺炢笁茿烛窋逐笜舳瘃蓫燭蠋躅鱁劚孎灟斸曯欘爥蠾钃主宔拄砫罜陼渚煑煮詝嘱濐麈瞩屬囑矚伫佇住助纻芧苎坾杼注苧贮迬驻壴柱柷殶炷祝疰眝祩竚莇秼紵紸羜著蛀嵀筑註貯跓&amp;#34;, &amp;#34;Z軴铸筯鉒飳馵墸箸翥樦鋳駐築篫霔麆鑄抓檛膼簻髽爪拽跩专叀専砖專鄟嫥瑼甎膞颛磚諯蟤顓鱄转孨転竱轉灷啭堟蒃瑑僎赚撰篆馔縳襈賺譔饌囀籑妆庄妝庒荘娤桩莊湷粧装裝樁糚丬壮壯状&amp;#34;, &amp;#34;Z狀壵梉焋幢撞戅隹追骓椎锥錐騅鵻沝坠笍娷缀惴甀缒畷硾膇墜綴赘縋諈醊錣餟礈贅轛鑆宒迍肫窀谆諄衠准埻凖準綧訰稕卓拙炪倬捉桌棁涿棳琸窧槕穛穱蠿圴彴犳灼叕妰茁斫浊丵浞烵诼酌&amp;#34;, &amp;#34;Z啄啅娺梲着斮晫椓琢斱硺窡罬撯擆斲禚劅諁諑鋜濁篧擢斀斵濯櫡謶镯鐯鵫灂蠗鐲籗鷟籱仔孖孜茊兹咨姕姿茲栥玆紎赀资崰淄秶缁谘赼嗞孳嵫椔湽滋葘辎鄑孶禌觜貲資趑锱稵緇鈭镃龇輜鼒&amp;#34;, &amp;#34;Z澬諮趦輺錙髭鲻鍿鎡頾頿鯔鶅齍鰦齜籽子吇姉姊杍矷秄胏呰秭耔虸笫梓釨啙紫滓訾訿榟橴字自芓茡倳剚恣牸渍眥眦胔胾漬唨宗倧综骔堫嵏嵕惾棕猣腙葼朡椶嵸稯綜緃熧緵翪艐蝬踨踪磫豵&amp;#34;, &amp;#34;Z蹤騌鬃騣鬉鬷鯮鯼鑁总偬捴惣愡揔搃傯蓗摠総縂燪總鍯鏓纵昮疭倊猔碂粽糉瘲縦錝縱邹驺诹郰陬掫菆棷棸鄒箃緅諏鄹鲰鯫黀騶齺赱走鯐奏揍媰租菹葅蒩卆足卒哫崒崪族傶稡箤踤踿镞鏃诅&amp;#34;, &amp;#34;Z阻组俎爼珇祖組詛靻鎺謯劗躜鑚躦鑽繤缵纂纉籫纘钻揝攥厜朘嗺樶蟕纗嶊嘴噿濢璻枠栬絊酔晬最祽罪辠酻蕞醉嶵檇鋷錊檌穝欈尊嶟遵樽繜罇鶎鐏鳟鱒鷷僔噂撙譐捘銌昨秨莋捽椊葃稓筰鈼&amp;#34;, &amp;#34;Z左佐繓作坐阼岝岞怍侳柞祚胙唑座袏做葄蓙飵糳咗&amp;#34;}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;需要注意的是C#和VB.Net在处理Unicode编码时有些区别，VB.Net使用&lt;/p&gt;</description></item><item><title>Windows 下使用Git管理Github项目</title><link>https://fwhyy.com/2012/02/use-git-manage-github-project-on-windows/</link><pubDate>Mon, 06 Feb 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/02/use-git-manage-github-project-on-windows/</guid><description>&lt;h2 id="git"&gt;Git&lt;/h2&gt;
&lt;p&gt;Git是一个开源的分布式版本控制系统，用以有效、高速的处理从很小到非常大的项目版本管理。最初由Linus Torvalds编写，用作Linux内核代码的管理。在推出后，Git在其它项目中也取得了很大成功，尤其是在Ruby社区中。&lt;/p&gt;
&lt;h2 id="github"&gt;Github&lt;/h2&gt;
&lt;p&gt;Github是一个面向开源及私有软件项目的托管平台，因为只支持Git作为唯一的版本库格式进行托管，故名GitHub。GitHub可以托管各种git库，并提供一个web界面，但与其它像 &lt;a href="http://www.oschina.net/p/sourceforge"&gt;SourceForge&lt;/a&gt;或&lt;a href="http://www.oschina.net/p/googlecode"&gt;Google Code&lt;/a&gt;这样的服务不同，GitHub的独特卖点在于从另外一个项目进行分支的简易性。为一个项目贡献代码非常简单：首先点击项目站点的“fork”的按 钮，然后将代码检出并将修改加入到刚才分出的代码库中，最后通过内建的“pull request”机制向项目负责人申请代码合并。&lt;/p&gt;
&lt;p&gt;上面的介绍摘自oschina.net ,下面就开始介绍在windows下怎样用Git管理Github的项目&lt;/p&gt;
&lt;p&gt;1 在&lt;a href="https://github.com/"&gt;Github&lt;/a&gt;上创建账号，这个很简单就不再赘述。&lt;/p&gt;
&lt;p&gt;2 下载安装Git&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href="http://code.google.com/p/msysgit/downloads/list"&gt;http://code.google.com/p/msysgit/downloads/list&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;安装很简单，一路Next就可以了。&lt;/p&gt;
&lt;p&gt;3 登陆GitHbu后创建一个新的仓库（New repository），命名为HelloWorld，创建成功后如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290716529.webp" alt="2012-02-06_220858" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 上面只是创建了一个空的代码仓库，下面就在本地创建一个HelloWorld的项目，并将其推送到Github中。创建D:\GitProject\HelloWorld的目录结构。&lt;/p&gt;
&lt;p&gt;5 打开Git的命令行Git base，输入如下命令来提供身份标示，主要是用户名和邮箱：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290716745.webp" alt="2012-02-06_221545" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 同过cd命令进入到刚才创建的HelloWorld目录中，然后使用git init来初始化当前目录，该目录中会生成一个.git的隐藏目录:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290717696.webp" alt="2012-02-06_222338" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;7 在D:\GitProject\HelloWorld目录中添加一个readme.txt文件，文件中写入“my first hello world project!”，然后用git add 命令以及git commit命令将其添加到库中。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290717852.webp" alt="2012-02-06_223250" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;8 下面就是最关键的步骤了，将本地的代码库提交到Github中，首先要使用命令来创建密匙，该密匙会在Github的设置中用到。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290717747.webp" alt="2012-02-06_223734" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;9 我系统是windows server 2008R2 ，生成的密匙在C:\Users\Administrator.ssh目录下，打开id_rsa.pub文件，复制里面所有内容。&lt;/p&gt;
&lt;p&gt;10 在Github中点击“Account Settings”进入到设置界面，选择“SSH Public Keys”,然后点击”add another public key“&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290717142.webp" alt="2012-02-06_224654" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201290717518.webp" alt="2012-02-06_224737" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;11 将刚才复制的密匙内容粘贴到对应的框中。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290718778.webp" alt="2012-02-06_225104" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;12 用命令来检验下是否设置成功&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290718000.webp" alt="2012-02-06_230129" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;13 现在一切就绪，在Git base 中使用命令就可以将本地代码推送到Github&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290718820.webp" alt="2012-02-06_230614" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;14 现在刷新下在Github中的项目页面，如下所示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290718295.webp" alt="2012-02-06_230744" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="学习资料"&gt;学习资料&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.worldhello.net/gotgithub/index.html"&gt;http://www.worldhello.net/gotgithub/index.html&lt;/a&gt;
&lt;a href="http://www.cnblogs.com/wojilu/"&gt;http://www.cnblogs.com/wojilu/&lt;/a&gt;
&lt;a href="http://download.csdn.net/detail/oec2003/4048166"&gt;Pro Git中文版下载&lt;/a&gt;
&lt;a href="http://www.slideshare.net/josephj/git-the-social-coding-system"&gt;一个还不错的Git ppt介绍&lt;/a&gt;&lt;/p&gt;</description></item><item><title>2011 年终总结</title><link>https://fwhyy.com/2012/01/summary-in-2011/</link><pubDate>Sat, 14 Jan 2012 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2012/01/summary-in-2011/</guid><description>&lt;h2 id="2011年记事"&gt;2011年记事：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;2月 从北京返回武汉&lt;/li&gt;
&lt;li&gt;3月 进入一家做信息化的IT公司A&lt;/li&gt;
&lt;li&gt;5月 和老婆领证了&lt;/li&gt;
&lt;li&gt;7月 因A公司频繁出差，跳槽到了B公司&lt;/li&gt;
&lt;li&gt;8月 买房子&lt;/li&gt;
&lt;li&gt;10月 结婚
2011年对我老说是重要的一年，人生中的几个重大事情都发生在这一年。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="回武汉"&gt;回武汉&lt;/h2&gt;
&lt;p&gt;在北京呆了还不到一年的时间，按照之前的计划本不应该选择在2011年初回武汉的，但因为计划2011年结婚，婚前必然有很多的事情要准备，所以经过多方面考虑还是决定2011年回武汉，这次回了就是要定居武汉了。&lt;/p&gt;
&lt;h2 id="进入公司a"&gt;进入公司A&lt;/h2&gt;
&lt;p&gt;选择回到武汉，那么回来后的工作是首要问题，经过朋友介绍谈好了一家做企业信息化的公司，电话中沟通过几次，后来回到武汉去公司和开发部的经理以及公司老总进行了面谈，双方感觉还不错，3月份顺利入职。可能是之前沟通的不够充分，入职后发现后想象的不一样，频繁的出差让我不能接受，可能有些朋友喜欢出差，但对于即将结婚的我确实不太适合。再三考虑之后我提出了离职，老板和部门经理强力挽留，说把我调回到武汉的一个项目中，不用去外地，但我的态度很坚决，最终还是辞了。因为即使这个项目在武汉，下一个可能有得去外地了。对于这次离职我心里感觉不是很舒服，毕竟老板和部门经理对我不错，而且也极力挽留，只能说我的需求和公司的特点不适合。&lt;/p&gt;
&lt;h2 id="领证"&gt;领证&lt;/h2&gt;
&lt;p&gt;5月20日是老婆定的，也算是一个比较有纪念意义的日子。关于领证那天发生的事情，请看-&lt;a href="http://blog.fwhyy.com/index.php/2011/05/anniversary/"&gt;纪念日-领证&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="进入公司b"&gt;进入公司B&lt;/h2&gt;
&lt;p&gt;其实在公司A的后半段我就已经将51上的简历更新了，随后就接到了很多公司的面试电话，基本上都被我推掉了，最终也就面试公司B一家，之前对B公司也有一定的了解，而且以前有同事在B公司也跟我介绍了一些情况，面试顺利通过，但由于面试是发挥的不是很好，薪资还不如在A公司的。之所以选择B公司有以下三个原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 公司规模大，开发流程规范；&lt;/li&gt;
&lt;li&gt;2 不用出差；&lt;/li&gt;
&lt;li&gt;3 每周公司都有篮球活动。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="买房子"&gt;买房子&lt;/h2&gt;
&lt;p&gt;老婆一直都想买市区的房子，比如软件园附近的。我们也去看过“锦绣龙城”的房子，那会二手的毛坯房也得6000多一平，这个价格在武汉来说也不算很贵了，但算下来交首付然后每个月几千的还贷压力还是不小。经过一番周折最终买的是老婆亲戚家还建的房子，离市区稍微远了点，但价格便宜。还不到3000一平，80平的房子也就在市里买房的一个首付。老婆后来一直都抱怨说应该买市里的房子，嫌那个太偏了，不过我倒是觉得挺好：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 到鲁巷的车程也就20多分钟；&lt;/li&gt;
&lt;li&gt;2 离老婆家很近；&lt;/li&gt;
&lt;li&gt;3 不远的地方就是一个高速的入口，如果有车走高速1个小时我就可以回家了；&lt;/li&gt;
&lt;li&gt;4 买这房子压力相对小，以后买车就变得现实了。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;买房子期间老婆家里人忙前忙后帮了很多忙，真的是非常感谢。也请老婆放心，我会努力赚钱早日买车，这样你就不会嫌远了。&lt;/p&gt;
&lt;h2 id="结婚"&gt;结婚&lt;/h2&gt;
&lt;p&gt;结婚是在10月3号，所以去了不少同学，为了热闹还请了我们市里面的婚庆公司来策划。对于我们那小地方来说也算是不错的了。有关结婚的详细情况，请看-结婚小记，婚后我和老婆去的三亚度的蜜月，这可能是很多新人在国内蜜月的首选，我们也没能免俗。&lt;a href="http://blog.fwhyy.com/2011/11/the-honeymoon-1/"&gt;蜜月1–我的蜜月之旅&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这就是我的2011，经历了很多事情，一年下来忙碌而充实着，人也成熟了很多，期待更精彩的2012。&lt;/p&gt;</description></item><item><title>蜜月7–尾声之广州</title><link>https://fwhyy.com/2011/11/the-honeymoon-7/</link><pubDate>Wed, 09 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-7/</guid><description>&lt;p&gt;广州火车站，人多，商贩多，火车站工作人员的态度恶劣，我只能说，广州，你真叫我失望。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102074.webp" alt="2011-11-05_113017" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;中午，王艳平，王艳平的老公小李，王艳平的妹妹小杨，包包，付强还有我们夫妻俩一起在广州的北京路找了家湘菜馆吃饭。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102077.webp" alt="2011-11-05_113038" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;终于有人帮我们合影啦，哈哈！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102745.webp" alt="2011-11-05_113047" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们大家都要幸福哦~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302103238.webp" alt="2011-11-05_113057" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;总是喜欢拍标志的呆呆&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102347.webp" alt="2011-11-05_113117" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;他们的工作真挺不容易的&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102722.webp" alt="2011-11-05_113131" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我是大黄蜂！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302104648.webp" alt="2011-11-05_113143" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;来广东一定要喝凉茶的啦&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102301.webp" alt="2011-11-05_113152" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;寻觅半天的圣心大教堂，确实很漂亮&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102875.webp" alt="2011-11-05_113210" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;如果能在这里举办一场婚礼的话···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102144.webp" alt="2011-11-05_113228" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;人挤人的街道和小巷&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302102596.webp" alt="2011-11-05_113236" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;广州，注定是我生命中的一个过客。&lt;/p&gt;</description></item><item><title>蜜月8–插曲之深圳</title><link>https://fwhyy.com/2011/11/the-honeymoon-8/</link><pubDate>Wed, 09 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-8/</guid><description>&lt;p&gt;我们在深圳住得第一晚，关外的住宿还是比较划算的。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302108159.webp" alt="2011-11-05_113303" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这里以前都是村子，但是现在什么都有，商厦百货楼随处可见。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302108801.webp" alt="2011-11-05_113328" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;一觉醒来都是午饭的时间了，我点的菜却不符合付强那家伙的口味，哼，反正我觉得好吃就行啦！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302108141.webp" alt="2011-11-05_113336" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;传说中的高楼招行大厦&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302108142.webp" alt="2011-11-05_113355" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;很小资的一条街，很清新也很干净，当然，物价也很高。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302108573.webp" alt="2011-11-05_113410" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;去锦绣中华看民俗表演吧~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302108642.webp" alt="2011-11-05_113418" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;大水车，转啊转悠悠~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110237.webp" alt="2011-11-05_113429" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;有免费的付强摄影师，不用白不用，哈哈！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110529.webp" alt="2011-11-05_113440" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我弥陀佛，阿门。。。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110687.webp" alt="2011-11-05_113451" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;烟幕后有各种少数民族的歌舞表演哦&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110809.webp" alt="2011-11-05_113504" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呐，看得清么？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110424.webp" alt="2011-11-05_113514" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;大型节目，金戈王朝，我还是很感兴趣滴！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111238.webp" alt="2011-11-05_113525" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;土家族的生活街市&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111806.webp" alt="2011-11-05_113546" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;好多地方其实我也叫不上名，囧。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110508.webp" alt="2011-11-05_121533" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这里很多树都很奇形怪状&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110415.webp" alt="2011-11-05_121554" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;云南——印象中国&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302110644.webp" alt="2011-11-05_121614" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;布达拉宫。。。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111423.webp" alt="2011-11-05_121624" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;乐山大佛&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111010.webp" alt="2011-11-05_121653" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;少林寺，觉得大吗？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111202.webp" alt="2011-11-05_121732" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;黄鹤楼&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111277.webp" alt="2011-11-05_121742" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;看到这张知道是怎么回事了吧~哈哈！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111879.webp" alt="2011-11-05_121758" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;其实大部分都是微缩版的啦&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111330.webp" alt="2011-11-05_121809" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;其实椰树配白云还是挺美的一个角度&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302111526.webp" alt="2011-11-05_121832" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呆呆投篮帮我赢的小娃娃&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112876.webp" alt="2011-11-05_121854" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;踩得动不？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112583.webp" alt="2011-11-05_121904" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;各大景点都在晚上上演万圣节的狂欢，夜晚即将到来，赶紧闪！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302114633.webp" alt="2011-11-05_121913" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;味千拉面之深圳版&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113447.webp" alt="2011-11-05_121923" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;就怪这些死孩子们，害我欢乐谷没去成，哎~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112215.webp" alt="2011-11-05_121932" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;晚上她还好心煮了家乡的牛肉丸给我们吃~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112591.webp" alt="2011-11-05_122000" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;第二天，我们赶集似的来到了红树林。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113044.webp" alt="2011-11-05_122008" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;城市深处，有这么一片绿土已然是一件幸福的事吧&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112065.webp" alt="2011-11-05_122018" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;比起广州，这边确实安静了很多。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112203.webp" alt="2011-11-05_122028" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;当然，有些人是冲着看香港而来。。。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113689.webp" alt="2011-11-05_122048" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;千年树精&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112414.webp" alt="2011-11-05_122056" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;万木归宗&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113647.webp" alt="2011-11-05_122106" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这里也有周黑鸭哦&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302115358.webp" alt="2011-11-05_122116" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;绿茵阁，与武汉的是不一样的。。。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113369.webp" alt="2011-11-05_122139" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;泰皇炒饭都要59&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113812.webp" alt="2011-11-05_122149" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;华强北真的有那么出名吗？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113368.webp" alt="2011-11-05_122159" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;不认识是啥字所以才拍的，哈哈&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113386.webp" alt="2011-11-05_122208" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;包包上班的大楼，我就打她楼下经过也没法见面。。。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113017.webp" alt="2011-11-05_122219" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;最高的楼和标志的楼&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113272.webp" alt="2011-11-05_122245" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;老邓咋不在武汉划个圈圈？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113868.webp" alt="2011-11-05_122303" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;一路走下来，我的腿都要断掉了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302113478.webp" alt="2011-11-05_122314" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这就是商圈嘛&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112240.webp" alt="2011-11-05_122325" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;据说地王大厦的侧面看起来是一把斧子，看出来了么？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112302.webp" alt="2011-11-05_122358" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;好大一个奢侈的店。。。~~~~(&amp;gt;_&amp;lt;)~~~~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112811.webp" alt="2011-11-05_122411" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我喜欢看到你的笑容，所以愿意跟着你走天下。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112997.webp" alt="2011-11-05_122420" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;你的高楼情结我愿意喜欢，就像你对我说的，其实你也没有错。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112985.webp" alt="2011-11-05_122430" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再见，深圳。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302112845.webp" alt="2011-11-05_122439" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再见，深圳；&lt;/p&gt;
&lt;p&gt;再见，广州；&lt;/p&gt;
&lt;p&gt;再见，三亚；&lt;/p&gt;
&lt;p&gt;再见，旅程。&lt;/p&gt;</description></item><item><title>蜜月4–三亚之呀诺达</title><link>https://fwhyy.com/2011/11/the-honeymoon-4/</link><pubDate>Tue, 08 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-4/</guid><description>&lt;p&gt;让我们忘掉烦恼，抛开工作，丢弃城市的喧嚣，一起进入呀诺达热带雨林区感受大自然吧，这里有新鲜的空气，有奇怪的动植物，有热情的人们，以及海南话——呀诺达！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302038790.webp" alt="2011-11-05_110349" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;伸出你的剪刀手，对着每一位陌生或熟悉的人说出这三个字–呀诺达，这是勇敢的自信的象征~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302039656.webp" alt="2011-11-05_110423" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;被椰子垒砌的广场装饰物，浑然天成。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302039145.webp" alt="2011-11-05_110439" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;跟吉祥物达达来张合照吧，比比谁更可乐~~嘿嘿！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302039623.webp" alt="2011-11-05_110450" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们是小猪团队的队员，当然啦，我是可爱的小猪，呆呆就是凶猛的野猪好了~哈哈&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302040101.webp" alt="2011-11-05_110458" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;进入呀诺达的景区，每个人都要跟着导游念这个三字经，爱护和保护环境人人有责~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302040067.webp" alt="2011-11-05_110507" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;不想观光的同志们可以选择干这种体力活，不过我觉得真没必要来呀诺达搞这个，全身湿乎乎的连照相都不行。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302042122.webp" alt="2011-11-05_110517" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;跟金蟾蜍套套近乎，妈咪妈咪哄，快赐予我金币吧，呼呼~！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302042347.webp" alt="2011-11-05_110542" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;被迫与鹦鹉拍照，20块钱，我的表情极其难看，对于突如其来的生物，我总是保持着极大的抗拒，这个世界就是如此，人们不得不提高警觉去活着。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302043153.webp" alt="2011-11-05_110557" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;古老的大树赋予我们大自然最最真实的意义，那就是——岁月不饶人，有木有？嘎嘎~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302043396.webp" alt="2011-11-05_110618" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;一路都是口喊呀诺达的呆呆。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302045740.webp" alt="2011-11-05_110639" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;看，树洞里有只螃蟹哦~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302045193.webp" alt="2011-11-05_110648" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呆呆算是个好男人，那准许你跟好男人花照个相吧！ 没有花心的花，故名好男人花~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302046934.webp" alt="2011-11-05_110712" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;啊哦，到处都是碰不得的植物，有毒的哦~~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302047701.webp" alt="2011-11-05_110734" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;啊呀，还是呆呆胆子大~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302049823.webp" alt="2011-11-05_110750" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;黄金屋里正在被售卖的物品，每件都是价值不菲，黄梨木做的，珍贵啊！&lt;/p&gt;
&lt;p&gt;走在摇晃桥上的呆呆还不忘转身对我做出胜利的标志。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302049629.webp" alt="2011-11-05_110815" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;随你啦，反正我也很happy~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302050163.webp" alt="2011-11-05_110825" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;放心吧，乖，跟癞蛤蟆亲一个也不会怎么样的啦！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302051384.webp" alt="2011-11-05_110836" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;含餐还是自助的哦，我们太饿了，吃的好饱~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302051011.webp" alt="2011-11-05_110846" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;晚上去了网友力荐的海南菜馆，店子不小，价格也不便宜。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302051533.webp" alt="2011-11-05_110858" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我只想说，我哪里的菜都不喜欢，哎哟，晚上还是得买泡面吃···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302052583.webp" alt="2011-11-05_110907" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;买的一堆零食，嘿嘿~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302052591.webp" alt="2011-11-05_110916" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;“这个花花世界因你而精彩！”&lt;/p&gt;</description></item><item><title>蜜月5–三亚之南田温泉</title><link>https://fwhyy.com/2011/11/the-honeymoon-5/</link><pubDate>Tue, 08 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-5/</guid><description>&lt;p&gt;最后一晚我们要换个环境咯，这间看不到海的房间却多了几分静谧和悠然。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302028194.webp" alt="2011-11-05_110939" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;风格和色调来了个大转弯。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302029050.webp" alt="2011-11-05_111007" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;虽然没什么时间，但是还是可以享受一下这里的别样风景嘛~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302029497.webp" alt="2011-11-05_111017" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;不管是哪间房，都少不了大大的浴缸~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302030198.webp" alt="2011-11-05_111040" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;南田温泉拥有五十多个品种的泉水，如果你喜欢潜水喜欢海上狂欢，或是你是深夜到达三亚的飞机，第二天选择南田温泉是很不错的，而我们，纯属将度假休闲进行到底哦，嘿嘿！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302030107.webp" alt="2011-11-05_111057" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呆呆决定在全国最好的温泉这里摆上一个最酷的表情。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302031008.webp" alt="2011-11-05_111123" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;独自享受这大大的浴场，哈哈！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302031090.webp" alt="2011-11-05_111141" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;椰奶泉，来试试看~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302031118.webp" alt="2011-11-05_111150" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;哎，真是花样百出&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302032123.webp" alt="2011-11-05_111210" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;叫你拍你不拍~！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302032437.webp" alt="2011-11-05_111218" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;水温43，呆呆热得满头大汗。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302033665.webp" alt="2011-11-05_111237" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;泡一会，拍一会~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302033530.webp" alt="2011-11-05_111248" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呆呆去热闹的人群水仗中抢了个镜头&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302033108.webp" alt="2011-11-05_111256" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呼~累了，让我歇歇。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302034366.webp" alt="2011-11-05_111306" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;猫闻见了腥也比不了呆呆见了游泳，他不会但也游得很欢···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302034931.webp" alt="2011-11-05_111315" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;小鱼泉，让我欢喜让我忧。。。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302034966.webp" alt="2011-11-05_111327" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;有谁能比我更自娱自乐？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302035198.webp" alt="2011-11-05_111337" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Hei~~！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302035955.webp" alt="2011-11-05_111346" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;晚上去吃了自助餐，既可以火锅又可以烤锅，啥啥都自选，一人58&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302035424.webp" alt="2011-11-05_111355" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;其实烤的也不错，但是实在是吃饱了~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302037270.webp" alt="2011-11-05_111408" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;泡过温泉的身心觉得异常的放松，虽然人多了点，但是依然不后悔~！晚上一定可以睡个甜美的好觉，zZZ~~&lt;/p&gt;</description></item><item><title>蜜月6–三亚之亚龙湾</title><link>https://fwhyy.com/2011/11/the-honeymoon-6/</link><pubDate>Tue, 08 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-6/</guid><description>&lt;p&gt;最后的时间留在房间了，马上要去退房咯，来张告别的照片吧！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058434.webp" alt="2011-11-05_112341" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;亚龙湾的水质也不错吧&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302059846.webp" alt="2011-11-05_112400" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;真想把这一切都带走&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058901.webp" alt="2011-11-05_112812" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;大大的海螺，你听到了吗？&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058408.webp" alt="2011-11-05_112824" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;海鱼海鱼，请把我带走吧~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058001.webp" alt="2011-11-05_112837" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;三亚的免税店&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058377.webp" alt="2011-11-05_112847" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;实在不想再被毒害，我选择了亲爱的KFC···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058518.webp" alt="2011-11-05_112905" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;大大的椰子，五块钱一个，不过我不是很喜欢这个味道。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302059196.webp" alt="2011-11-05_112915" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;晚霞中的椰景，是不是很迷人？要离开了，一切都是那么的如梦如幻。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058436.webp" alt="2011-11-05_112927" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;三亚的火车站真是爽，人少环境又不错！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302058709.webp" alt="2011-11-05_112939" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再见咯，三亚！&lt;/p&gt;</description></item><item><title>蜜月3–三亚之蜈支洲岛</title><link>https://fwhyy.com/2011/11/the-honeymoon-3/</link><pubDate>Mon, 07 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-3/</guid><description>&lt;p&gt;蜈支洲岛，被誉为中国的马尔代夫，这里的海水是最漂亮的，当然，这里的消费也是最高的，好啦，准备上岛啦！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302053578.webp" alt="2011-11-05_105721" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;看，海水是不是跟前一天看到的不一样？假如你真的是来度假，就不要跟团了，早早坐船来这边，躺在海风吹海浪涌的美丽岛屿上，什么都不在，什么都不想，这才是真正的休息！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302053238.webp" alt="2011-11-05_105751" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这里有孔雀，随处可走，但是不开屏，哼哼！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302053719.webp" alt="2011-11-05_105803" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;如果无宗教信仰的话还是别进门了，不然又是一堆潜在消费哦，不要因为这些事情影响了自己精心照料的好心情~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302053243.webp" alt="2011-11-05_105813" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;如果可以翱翔在海上···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302054204.webp" alt="2011-11-05_105822" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;裙随风舞，心随景动~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302054462.webp" alt="2011-11-05_105832" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;寓意：把你踩在我脚下，哈哈！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302054470.webp" alt="2011-11-05_105844" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;背对着大海许下我们永恒的誓言。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302054963.webp" alt="2011-11-05_105856" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;海水带走了我的脚印，阳光帮我们重新染色···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302054804.webp" alt="2011-11-05_105909" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;笑一个吧，功成名就不是目的，让自己快乐快乐这才叫做意义。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302055350.webp" alt="2011-11-05_105940" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;跟着海浪的音符一起舞动吧，我们还年轻~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056000.webp" alt="2011-11-05_105955" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;简易的午餐，但已足够。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056263.webp" alt="2011-11-05_110010" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;斑驳的阳光打在我铺满沙子的脚面上，真想在这块草地上睡上一觉。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056724.webp" alt="2011-11-05_110025" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呆呆把游泳圈弄破了，瞬间，气都没了，他迅速狗刨到岸边，O(∩_∩)O哈哈~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056046.webp" alt="2011-11-05_110042" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在海中的呆呆总是异常的兴奋，他说他在学游泳，可怜我们这两只旱鸭子···&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056140.webp" alt="2011-11-05_110057" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;很有意境么？蓝天白云大太阳，我在海边感受幸福的味道。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056738.webp" alt="2011-11-05_110119" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;哈，被晒红了脸的呆呆。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056873.webp" alt="2011-11-05_110133" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;特意找得湖北菜馆，虽然性价比不高，但是味道总归是对的。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302056625.webp" alt="2011-11-05_110145" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;晚上躺在床上的时候，我仿佛依然可以感觉到海水拂过我身体的感动，睡觉吧，大海~&lt;/p&gt;</description></item><item><title>the-honeymoon-1</title><link>https://fwhyy.com/2011/11/the-honeymoon-1/</link><pubDate>Sat, 05 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-1/</guid><description>&lt;p&gt;作者：&lt;a href="http://han.fwhyy.com/"&gt;老婆&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;很早的时候就在考虑蜜月地，是景色秀丽的云南还是浪漫惬意的海南，是樱花遍地的日本还是小吃巨多的台湾，经过money的考验和婚礼的周折劳累，我还是坚信被大海拥抱的三亚是最理想的选择。&lt;/p&gt;
&lt;p&gt;地点选好了，是跟团还是自助呢？是半自助还是纯自助呢？这都是要考虑的问题，跟团便宜啊，但是觉得没意思，每天跟着导游到处奔波，实在有失我度假的心情，可是纯自助又是很贵的，并且什么都要自己想自己打算，三思之后我们还是选择了纯自助，我想要一觉睡醒的时候是被海浪吵醒而不是被酒店的叫早吵醒。&lt;/p&gt;
&lt;p&gt;提前一个月我们就订好了机票和住处，武汉飞三亚的六折机票两张1700，住所是订的蚂蜂窝上鼎鼎有名的海上花家庭旅馆，由于新推出了加蓝听海，我们选择了一间漂亮的海景房，400多一晚，打折后370多，原本想订5晚，结果最后一晚已经被人预定了，我们只好换了另外一间，怎么说也算个椰景房，还是挺不错的~&lt;/p&gt;
&lt;p&gt;别人去三亚无外乎就是冲着大海、海鲜、潜水而去，记得去之前我问过海上花的老板，像我这种既不吃海鲜又不能潜水的人，还有去三亚的必要吗？他说那就来度假吧，休息休息，躺在海边吹吹海风都是惬意的，顿时脑海中浮现出很有意境的场景，陶醉不已。&lt;/p&gt;
&lt;p&gt;由于是特价机票，所以到达三亚的时间已经很晚，有海上花的人过来接机，时间晚加晚点，到达三亚已经是凌晨，洗漱过后两三点，度假嘛，是一定要睡懒觉的。出门之前我一直很忙，再者听说三亚第一市场的东西很便宜，所以应景的着装都想着去那里解决，近中午才起床的我们，悠哉去了第一市场买装备，花裙子，大裤衩，洞洞鞋，怎么花哨怎么来，这才是海边风嘛~！&lt;/p&gt;
&lt;p&gt;买好装备就该开始我们真正的三亚游啦&lt;del&gt;蜈支洲被誉为中国的马尔代夫，海水能见度很低，虽然价格很高但是不得不去&lt;/del&gt;还好没让我失望，我觉得那种海，是你不需要做任何事，就去看一看都是值得的！&lt;/p&gt;
&lt;p&gt;观海之后就该看看热带的植物了，呀诺达，是洗去都市喧嚣，被誉为海南后花园的地方，这是一个超大的热带雨林区，据说里面的负离子含量高于其他地方的8倍，就算是去洗洗肺也是值得的，不知道是我们被里面的珍奇异草而毒到了，还是我们真正是在排毒，以至于第二天我们的脸上都长了胞···o(╯□╰)o&lt;/p&gt;
&lt;p&gt;即便是一天只安排一个景点，我们依然决定要把度假休闲进行到底，睡到太阳晒屁股的时候再去泡个温泉这是何等的惬意！在五十多种泉水里与俄罗斯美女一起享受这美妙的阳光温泉SPA吧~~&lt;/p&gt;
&lt;p&gt;就快离开三亚了，赶紧再去海边磨蹭一下，亚龙湾的水质也不差，也是免门票的，不去白不去，去了也带不走啥。只因我们什么装备都没带，匆匆来到，速速离去，带着对海洋的眷恋我们去了红岗水果批发市场，这边的东西物美价廉，性价比算很高了。来到这里，算是了了呆呆的一个心愿，免得他天天念着大大的芒果···&lt;/p&gt;
&lt;p&gt;走啦，三亚&lt;del&gt;作为旅游城市，你真的已经很不错了，你干净，美丽，水果香甜，我因选择了你不曾觉得遗憾，也许马尔代夫会更让人神往，也许住高级酒店会有私人的游泳馆，也许世界的旅人都会慕名而访，但是因了你，我感到很舒心，这便是满足，谢谢你&lt;/del&gt;！&lt;/p&gt;
&lt;p&gt;接下来我们来到广州，这个让我失望的城市，跟武汉比起来，这里更加拥挤，许是刚刚离开清洁的三亚，所以觉得这里异常的不堪，甚至连火车站的工作人员，人品和素养都相距甚远，不过来这边主要还是为了和同学朋友相聚，不管怎么样，大家在一起就是最开心的。虽然打算在这里小待两天就直接回家的，但是计划远比不上变化快，我们最终选择了折腾，仅仅去了计划中的圣心大教堂我们就奔赴了深圳，这两天好累。&lt;/p&gt;
&lt;p&gt;当我在深圳一醒来的时候，我的脑海中立刻闪现出这样一个念头，我真的该回家了。来都来了，就尽情将最后的旅途画上完整的句点吧！几年前去过世界之窗，如今也得去锦绣中华看看，要不是时间有点赶，我真会好好把每个民族的文化研究一番。晚上打算去欢乐谷的我，发现最近深圳在举办万圣狂欢夜，欢乐谷里都是游走的鬼怪，我的小心脏实在经受不住这等惊吓，弃之！&lt;/p&gt;
&lt;p&gt;最后一天，也是我的疲惫点达到极限的一天，这一天我的情绪显得不高，而且脾气也很大，相对于呆呆狂热于高楼大厦的情结，我是很扫兴的，我们去了红树林，虽然看不到香港，我们重游了华强北，见识了京基大楼和地王大厦，我们和老邓合了影，最终匆匆赶往了回家的路···&lt;/p&gt;
&lt;p&gt;旅途虽然已经结束，但是心情却依然刻画在每张照片中，我深信，在每次面对镜头微笑的时候，我的心，是满满的幸福。&lt;/p&gt;
&lt;p&gt;“米修米修”&lt;/p&gt;
&lt;p&gt;“小乌龟呱呱”&lt;/p&gt;
&lt;p&gt;“收到讯号了吗？”&lt;/p&gt;
&lt;p&gt;“over！”&lt;/p&gt;</description></item><item><title>蜜月2–三亚之市区篇</title><link>https://fwhyy.com/2011/11/the-honeymoon-2/</link><pubDate>Sat, 05 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/the-honeymoon-2/</guid><description>&lt;p&gt;我们住的是海上花新出的加蓝听海，这里的人很热情，出门过马路就是海洋，我认为性价比是很高的，只要你不是特别事儿的人~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302015187.webp" alt="2011-11-05_104805" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们前四晚的住处，房间以蓝白为主色调，除去每天马路的吵闹声，这里的一切都是很不错的，有阳光晒进房间，海浪声此起彼伏，如果是清晨太阳还不够强烈的时候，拿一本书去阳台上看看都是十分情调的一件事。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302015479.webp" alt="2011-11-05_104857" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我来啦~！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302017965.webp" alt="2011-11-05_104910" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;大大的飘窗和舒适的摇椅都是休闲的好工具。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302017882.webp" alt="2011-11-05_104933" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;阳台上新绿的桌椅上是我们丰盛的早餐，虽然每天都一样，但是加蓝听海的一番心意。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302017001.webp" alt="2011-11-05_104946" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;大大的浴缸&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302018790.webp" alt="2011-11-05_104956" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;每一处装饰，都是精心的挑选和摆造。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302018283.webp" alt="2011-11-05_105008" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;呆呆很喜欢这个台子，很适合在这边上网，这里的无线网速度还不赖。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302019775.webp" alt="2011-11-05_105019" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;出了房间有这么个观海的庭院，拥抱三亚~！呼呼！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302019432.webp" alt="2011-11-05_105031" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;看，在阳台上，或是把阳台的帘子打开，真的是可以看到海的哦~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302020033.webp" alt="2011-11-05_105046" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;啥都没准备，如果对质量要求不高的话，赶紧去第一市场打点些物什吧~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302020064.webp" alt="2011-11-05_105104" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;抱罗粉，著名小吃，呆呆很是喜欢，要了大碗的，觉得很值。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302021019.webp" alt="2011-11-05_105234" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;清补凉，大约10种元素与椰奶混合而成，6元一碗，很可口。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302022745.webp" alt="2011-11-05_105250" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;三亚的步行街&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302022160.webp" alt="2011-11-05_105300" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;拥抱大海！&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302024368.webp" alt="2011-11-05_105333" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们自己捡得海贝哦~&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302024511.webp" alt="2011-11-05_105348" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;海南的文昌鸡，超级难吃的，另外一碗是海南全家福，味道还可以，只是性价比不高，基本都是素的却还要35一碗。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302025601.webp" alt="2011-11-05_105400" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;逛了一天也累了，早些休息咯~！&lt;/p&gt;</description></item><item><title>MongoDB(4)–MongoDB服务的启动</title><link>https://fwhyy.com/2011/11/mongo-service-startup/</link><pubDate>Thu, 03 Nov 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/11/mongo-service-startup/</guid><description>&lt;h2 id="原始方式"&gt;原始方式&lt;/h2&gt;
&lt;p&gt;只有启动了MongoDB的服务，才能使用MongoDB的功能，通常情况下会开一个命令窗口，输入下面的命令来启动服务：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300726402.webp" alt="2011-10-14_222912" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="配置文件方式"&gt;配置文件方式&lt;/h2&gt;
&lt;p&gt;如果不想每次启动的时候都在命令行中输入很多繁琐的参数，可以把参数信息保存在配置文件中。创建一个名为mongodb.cnf的配置文件，和那些小工具放在同一个目录中，文件的内容如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;dbpath=&amp;#34;d:\database\mongodb\data&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后在命令窗口输入下面命令就可以启动服务&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300726049.webp" alt="2011-10-14_225624" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;看似和上面的方法差不多，还是需要指定配置文件，但如果参数不止-dbpath的时候，就可以将参数都写在配置文件中，在命令行调用的时候就会显得方便很多。&lt;/p&gt;
&lt;h2 id="daemon方式"&gt;Daemon方式&lt;/h2&gt;
&lt;p&gt;上面介绍的两种方式启动服务都需要打开一个命令行窗口，窗口关闭了服务也就停止了。我们使用–fork参数可以将mongodb的服务放在后台运行，这样相对比较安全。–fork参数是和–logpath参数一起使用的&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300726756.webp" alt="2011-10-14_235943" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://fwhyy.com/2011/09/some-concepts-about-nosql-and-mongodb/"&gt;MongoDB(3)–有关NoSQL及MongoDB的一些概念&lt;/a&gt;
&lt;a href="http://fwhyy.com/2011/09/mongvue-introduction/"&gt;MongoDB(2)–MongVUE介绍&lt;/a&gt;
&lt;a href="http://fwhyy.com/2011/09/mongo-introduction-and-installation/"&gt;MongoDB(1)&amp;ndash;MongoDB介绍及安装&lt;/a&gt;&lt;/p&gt;</description></item><item><title>结婚小记</title><link>https://fwhyy.com/2011/10/married-reporter/</link><pubDate>Sat, 15 Oct 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/10/married-reporter/</guid><description>&lt;p&gt;今天是2011年10月15日，星期六，过完这个周末就是婚假的第一天了，三亚之行很是期待。&lt;/p&gt;
&lt;p&gt;婚礼是在2011年10月3日举行，尽管这个婚礼对我和老婆来说只是走个形式而已（因为婚礼前后我们的生活没有明显变化），但我还是显得很兴奋。婚礼的酒席定在我们镇上的一个小酒楼里，和大酒店相比显得比较简陋，但由于请了婚庆场面也非常热闹，在我们那种小地方也算是不错了。&lt;/p&gt;
&lt;h2 id="接亲"&gt;接亲&lt;/h2&gt;
&lt;p&gt;10月3号的早上四点就起床，洗漱完吃点东西准备准备，5点准时出发。接亲的人由我妹、几个亲戚家的小孩、几个本家的大人和几个同学组成。头车的司机对路线比较熟，6点半多就已经下了高速，算是很快的了，老婆那边打电话过来说还没准备好，没办法，只能跟司机们说在高速路口等会。最终7点半到老婆家，从到老婆家门口到把老婆抱上车还没用半个小时，最后奶奶和丈母娘都帮忙叫门，搞得我都不好意思了，可能是考虑到路程比较远又在下雨的缘故吧。就这样顺利的在10点左右把老婆接回家了。&lt;/p&gt;
&lt;h2 id="酒席"&gt;酒席&lt;/h2&gt;
&lt;p&gt;婚礼的酒席定在我们镇上的一个小酒楼里，和大酒店相比显得比较简陋，但由于请了婚庆场面也非常热闹，在我们那种小地方也算是不错了。婚礼仪式前客人们差不多到齐的时候，大厅的投影仪上放着婚纱照的Flash，那会拿那张Flash盘还费了些周折，现在总算是派上用场了。在婚礼仪式上本来有很多的话想说，可最终只说了简单的几句。其实也就是些感谢的话，婚礼上没说的在这儿补上吧，感谢高璐和卓伟能在这么恶劣的天气下赶过来，特别是卓伟老婆孩子都带过来了，感动啊！再就是要感谢我妹，由于我把领带给疏忽了，在2号晚上，我妹用布给我缝了一个领结，还真像那么回事。&lt;/p&gt;
&lt;h2 id="酒后花絮"&gt;酒后花絮&lt;/h2&gt;
&lt;p&gt;吃完饭敬完酒后，我特地到同同学的那个桌子上陪他们喝了点，这一喝不打紧，整个下午都是晕乎乎的。下午在房间里老婆给我拍了段视频，晚上酒醒后老婆给我看，我发现自己还挺有喜剧天分的，哈哈！&lt;/p&gt;
&lt;h2 id="送客"&gt;送客&lt;/h2&gt;
&lt;p&gt;初高中的一些同学朋友，由于就在我们镇上，饭后就各自散了，卓伟4号还要去加班，所以下午要赶回武汉再从武汉赶到襄樊，我晕乎乎的和高路把他们一家三口送到路边搭车，从口袋里掏出了100块钱本来准备给他们坐车的，最终又忘记给了，哎下次见面请他们吃饭吧。高璐来的时候已经买了回程的票，不过是4号凌晨2点的，晚饭后我和老婆把他送到了火车站，后来给他打电话才知道，那天火车晚点，到凌晨4 5点才坐上车，真是辛苦高璐了。&lt;/p&gt;
&lt;p&gt;忙碌的一天就这样过了，从法律上讲我5月20就已经结婚了，但在我们老家似乎只有在办完酒后才算结婚，就像我老爹在婚礼仪式上说的，结了婚就从小孩变成大人了，很多事情要有所担当。尽管从年龄上讲我早就已经是大人了，但结婚的意义还是不一样，对自己、对老婆、对我的父母、对岳父岳母以及以后的孩子都有责任了。&lt;/p&gt;</description></item><item><title>解决Windows Server2008 R2中IE开网页时弹出阻止框</title><link>https://fwhyy.com/2011/10/solution-for-ie-to-open-the-web-pop-up-windows-server2008-r2-block-box/</link><pubDate>Sat, 15 Oct 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/10/solution-for-ie-to-open-the-web-pop-up-windows-server2008-r2-block-box/</guid><description>&lt;p&gt;相信使用Windows Server2008的朋友都遇到过这种情况，用IE打开网站时会弹出“Internet Explorer增强安全配置正在阻止来自下列网站的此应用程序中的内容”的对话框。如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301946631.webp" alt="2011-10-14_205047-300x243" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;禁止弹出此类对话框的步骤：&lt;/p&gt;
&lt;p&gt;1 打开服务器管理器，在”安全信息“栏的右侧点击”配置IE ESC“&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301946326.webp" alt="2011-10-14_204750-300x150" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在弹出的对话框中将”管理员“和”用户“都选择为“禁用”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301947894.webp" alt="2011-10-14_204830-300x289" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 确定后，再浏览网页那烦人的弹出框就不会再出现了。&lt;/p&gt;</description></item><item><title>MongoDB(3)–有关NoSQL及MongoDB的一些概念</title><link>https://fwhyy.com/2011/09/some-concepts-about-nosql-and-mongodb/</link><pubDate>Thu, 29 Sep 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/09/some-concepts-about-nosql-and-mongodb/</guid><description>&lt;p&gt;学习任何东西在没有理解的前提下去背熟一些概念是没有用的，就像只背会了几个概念而没有理解的开发人员去面试是经不住面试官的追问的。前面的两篇对MongoDB做了简单的介绍，能够很快上手，对MongoDB有一个感性的认识。本篇大部分内容来自MongoDB权威指南和MongoDB实战。希望在学习完整个MongoDB后能对本篇的内容有一个全新的认识。&lt;/p&gt;
&lt;h2 id="nosql简介"&gt;NoSQL简介&lt;/h2&gt;
&lt;p&gt;NoSQL，全称是”Not Only Sql”,指的是非关系型的数据库。这类数据库主要有这些特点：非关系型的、分布式的、开源的、水平可扩展的。原始的目的是为了大规模 web 应用，这场全新的数据库革命运动早期就有人提出，发展至2009 年趋势越发高涨。NoSQL 的拥护者们提 倡运用非关系型的数据存储，通常的应用如：模式自由、支持简易复制、简单的API、最终&lt;/p&gt;
&lt;p&gt;的一致性 （非ACID ）、大容量数据等。NoSQL 被我们用得最多的当数 key-value 存储，当然还 有其他的文档型的、列存储、图型数据库、xml 数据库等。相对于目前铺天盖地的关系型数 据库运用，这一概念无疑是一种全新思维的注入。&lt;/p&gt;
&lt;h2 id="nosql的优势"&gt;NoSQL的优势&lt;/h2&gt;
&lt;p&gt;同关系型数据库相比，NoSQL有下面的一些优势：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;适合对数据库高并发读写的需求。&lt;/li&gt;
&lt;li&gt;适合对海量数据的高效率存储和访问的需求。&lt;/li&gt;
&lt;li&gt;适合对数据库的高可扩展性和高可用性的需求。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于NoSQL的这些优势，使得NoSQL比较适合以下的一些场景的使用：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对数据库事务一致性要求不高的时候，因为NoSQL不支持事务（MongoDB是不支持事务的，其他的没做研究）。&lt;/li&gt;
&lt;li&gt;对数据库的写实时性和读实时性要求不高的时候。&lt;/li&gt;
&lt;li&gt;对复杂的SQL 查询，特别是多表关联查询不多的时候。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="nosql的特点"&gt;NoSQL的特点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;它可以处理超大量的数据&lt;/li&gt;
&lt;li&gt;它运行在便宜的它运行在便宜的 PC 服务器集群上服务器集群上，意思是在数据库不够用的时候进行PC的集群扩展很方便并且成本很低。&lt;/li&gt;
&lt;li&gt;它击碎了性能瓶颈，因为使用NoSQL省去了传统的程序模型到SQL之间转换的时间，执行效率更高。&lt;/li&gt;
&lt;li&gt;它没有过多的操作，意思是去掉了很多在关系数据库中拥有而在实际又不怎么使用的功能。&lt;/li&gt;
&lt;li&gt;它的支持支持者源于社区者源于社区，所有的NoSQL产品都是开源的。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="mongodb简介"&gt;MongoDB简介&lt;/h2&gt;
&lt;p&gt;MongoDB 是一个介于关系数据库和非关系数据库之间的产品，是非关系数据库当中功能最丰富，最像关系数据库的。他支持的数据结构非常松散，是类似json 的bjson 格式，简称BSON，因此可 以存储比较复杂的数据类型。MongoDB 最大的特点是他支持的查询语言非常强大，其语法有点类似于面向对象的查询语言，几乎可以实现类似关系数据库单表查询的绝大部分功能， 而且还支持对数据建立索引。它是一个面向集合的,模式自由的文档型数据库。&lt;/p&gt;
&lt;h2 id="mongodb特点"&gt;MongoDB特点&lt;/h2&gt;
&lt;h3 id="1-丰富的数据模型"&gt;1 丰富的数据模型&lt;/h3&gt;
&lt;p&gt;MongoDB是一种面向文档的数据库。在MongoDB中文档就相当于关系型数据库中的行。文档中可以包含很复杂的数据结构，这样一条记录就可以表示很复杂的层级关系。比如说文章表有一个字段是评论，在关系型数据库中我们通常会建一个评论表和文章表做关联，在MongoDB中就可以直接将评论存在一条文章记录的文档中。更符合我们的思维。&lt;/p&gt;
&lt;p&gt;MongoDB没有模式，也就是说没有表结构，文档的字段可以随时添加，不会对原来数据有任何影响，使开发变得很容易。&lt;/p&gt;
&lt;h3 id="2-容易扩展"&gt;2 容易扩展&lt;/h3&gt;
&lt;p&gt;在一些大型的网站中，数据的增长是非常惊人的。在面临数据增长机器不够用的时候通常有两种做法：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;购买更高配置的机器，会花费很大，而且达到物理极限后花钱也买不到更高配置的了。&lt;/li&gt;
&lt;li&gt;进行扩展，将数据分散到多个机器上，这种在操作上会显得复杂点。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MongoDB的设计就考虑到了扩展的问题，它所采用的面向文档的数据模型使得可以自动在多台服务器中切割数据。还可以平衡群集的数据和负载，自动进行文档重排。&lt;/p&gt;
&lt;h3 id="3-丰富的功能"&gt;3 丰富的功能&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;索引：MongoDB支持通用辅助索引，可以进行多种快速查询。&lt;/li&gt;
&lt;li&gt;存储Javascript：不必再使用存储过程了，可以直接在服务器端存取Javascript的函数和值。&lt;/li&gt;
&lt;li&gt;聚合：MongoDB支持MapReduce和其他聚合工具。&lt;/li&gt;
&lt;li&gt;固定集合：集合的大小是有上限的，这对于日志一类的数据很有用。&lt;/li&gt;
&lt;li&gt;存储文件：MongoDB支持用一种容易使用的协议（GridFS）来存储大型文件。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="4-更快的速度"&gt;4 更快的速度&lt;/h3&gt;
&lt;p&gt;高性能是MongoDB的目标，为了提高性能，就必须进行很多精简的设计，相比关系型数据库少了很多功能，但仍然保持着关系型数据库的众多的特性。一些精简设计表现在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;使用MongoDB传输协议作为与服务器交互的主要方式，将比较HTTP、Reset等可以节省不少开销。&lt;/li&gt;
&lt;li&gt;对文档进行动态填充，预分配数据文件，用空间换取时间，而且空间对于现在来说已不是问题。&lt;/li&gt;
&lt;li&gt;默认的存储引擎使用内存映射文件，将内存管理工作交给OS去处理。&lt;/li&gt;
&lt;li&gt;动态查询优化器会记住执行查询最高效的方式。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="5-简单的管理"&gt;5 简单的管理&lt;/h3&gt;
&lt;p&gt;MongoDB尽量让服务器自治来简化数据库的管理。除了启动数据库服务器之外，几乎没有什么管理操作了。如果主服务器挂掉了，MongoDB会自动切换到备份服务器上，并将备份服务器提升为活跃服务器。在分布式的环境下，群集只需要知道有新的节点就会自动集成和配置新的节点。&lt;/p&gt;
&lt;h2 id="mongodb适用场景"&gt;MongoDB适用场景&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;网站数据：MongoDB非常适合实时的插入，更新与查询，并具备网站实时数据存储所 需的复制及高度伸缩性 。&lt;/li&gt;
&lt;li&gt;缓存：由于性能很高，MongoDB 也适合作为信息基础设施的缓存层。在系统重启之后， 由MongoDB 搭建的持久化缓存层可以避免下层的数据源过载 。&lt;/li&gt;
&lt;li&gt;大尺寸，低价值的数据：使用传统的关系型数据库存储一些数据时可能会比较昂贵，在此之前，很多时候程序员往往会选择传统的文件进行存储 。&lt;/li&gt;
&lt;li&gt;高伸缩性的场景：MongoDB 非常适合由数十或数百台服务器组成的数据库。MongoDB的路线图中已经包含对MapReduce 引擎的内置支持 。&lt;/li&gt;
&lt;li&gt;用于对象及JSON 数据的存储：MongoDB 的BSON 数据格式非常适合文档化格式的存储及查询 。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>MongoDB(2)–MongVUE介绍</title><link>https://fwhyy.com/2011/09/mongvue-introduction/</link><pubDate>Tue, 20 Sep 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/09/mongvue-introduction/</guid><description>&lt;p&gt;对于数据库来说有一款功能强大的管理工具将会大大的提高我们的工作效率。对于MongoDB来说MongoVUE就是这样一款工具，MongoVUE在1.0版以后就开始收费了，所以我现在用的还是0.9.7.2版。对于初学来时已经够用了。&lt;/p&gt;
&lt;p&gt;安装运行后的界面如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300728711.webp" alt="2011-09-12_150826-300x199" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击Connect来连接MongoDB数据库&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300728115.webp" alt="2011-09-12_150941-300x225" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;填写好Name 和Server后点击Save，Name随便给取个名字就型，Server为服务器的地址，本机即127.0.0.1，Port默认为27017，可以根据实际情况进行设置。保存后在Connect界面就多了一个MyMongoDB的数据库连接，点击Connect即可连接到数据库。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300728285.webp" alt="2011-09-12_200130" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;除了系统默认的admin和local数据库外，在上一篇中创建的Blogs数据库也在列表中。并且在Blogs库中已经存在一个Collection，就是在上篇中insert的一条数据。双击Posts，在右边的窗口中会展示数据，分为三个Tab页来进行展示，分别是树状结构、表结构（类似关系型数据库的展示方式）和文本结构（BSON）。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300728453.webp" alt="2011-09-12_200949-300x203" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;本篇就介绍到这里，更多的功能和用法还是让读者自己下载试用吧。&lt;/p&gt;
&lt;p&gt;MongoDB0.9.7.2 版下载：&lt;a href="http://download.csdn.net/detail/oec2003/3595146"&gt;http://download.csdn.net/detail/oec2003/3595146&lt;/a&gt;&lt;/p&gt;</description></item><item><title>MongoDB(1)--MongoDB介绍及安装</title><link>https://fwhyy.com/2011/09/mongo-introduction-and-installation/</link><pubDate>Tue, 13 Sep 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/09/mongo-introduction-and-installation/</guid><description>&lt;p&gt;NoSql已经流行好一阵子了，我似乎接触的有点晚了。NoSql的产品有很多，MongoDB只是其中一种，之所以选在学习MongoDB是因为最早知道的就是她，也比较具有代表性。&lt;/p&gt;
&lt;p&gt;MongoDB相比传统的关系型数据库有一些优势，比如在海量数据下的性能表现、很好的扩展性等。初识MongoDB感觉和关系型数据库最大的区别就是没有关系型数据库中的那种关系模型，更准确的说她是一个面向文档的数据库。通俗的讲在MongoDB中集合对应关系型数据库的表，文档对应着行。在MongoDB中一条记录的表现形式是BSON的格式，和JavaScript中的JSON类似。&lt;/p&gt;
&lt;h2 id="mongdb的下载安装"&gt;MongDB的下载安装&lt;/h2&gt;
&lt;p&gt;下载地址：&lt;a href="http://www.mongodb.org/downloads"&gt;http://www.mongodb.org/downloads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载下来的是一个mongodb-win32-i386-1.8.2.zip文件，将该文件解压，会发现里面的bin目录下有很多的exe文件，这些是MongoDB的一些工具，比如要启动MongoDB服务就要用到里面的Mongod.exe。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300726967.webp" alt="2011-09-12_114648" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;bsondump: 将 bson 格式的文件转储为json 格式的数据&lt;/li&gt;
&lt;li&gt;mongo: 客户端命令行工具，其实也是一个javascript解释器，支持javascript语法&lt;/li&gt;
&lt;li&gt;mongod: 数据库服务端，每个实例启动一个进程，可以fork 为后台运行&lt;/li&gt;
&lt;li&gt;mongodump/ mongorestore: 数据库备份和恢复工具&lt;/li&gt;
&lt;li&gt;mongoexport/ mongoimport: 数据导出和导入工具&lt;/li&gt;
&lt;li&gt;mongofiles: GridFS 管理工具，可实现二制文件的存取&lt;/li&gt;
&lt;li&gt;mongos: 分片路由，如果使用了sharding功能，则应用程序连接的是 mongo而不是 mongod&lt;/li&gt;
&lt;li&gt;mongosniff: 这一工具的作用类似于tcpdump，不同的是他只监控MongoDB 相关的包请求，并且是以指定的可读性的形式输出&lt;/li&gt;
&lt;li&gt;mongostat: 实时性能监控工具&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;要正常的使用MongoDB首先要做的就是启动MongoDB服务，打开CMD进入到MongoDB的bin目录，执行Mongod.exe，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300726870.webp" alt="2011-09-12_132542-300x66" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以看到在mongod.exe 后面有一个-dbpath来制定数据库的存放路径。这个目录我们必须事先创建好。如果没有制定-dbpath，会使用默认路径：C：\data\db\。&lt;/p&gt;
&lt;p&gt;下面就可以在MongoDB中来创建数据库了，本文中使用MongoDB自带的Shell来进行操作，在下一篇中将介绍MongoDB的一款IDE工具MongoVUE，使用bin先的mongo.exe可以打开Shell窗口。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300727903.webp" alt="2011-09-12_133937-300x58" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;执行show dbs命令可以查看所有数据库的列表，关于更多的Shell命令可以通过执行help命令查看。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300727232.webp" alt="2011-09-12_142453" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;admin和local数据库是MongoDB自带的数据库，这两个数据库在系统中有特殊的作用。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;admin：最高权限的一个数据库，该数据库中的用户会拥有所有数据库的权限。一些特殊的服务器端的命令也只能从这个数据库中运行。&lt;/li&gt;
&lt;li&gt;local：该数据库不会被复制，可以用来存储限与本地单台服务器的任意集合。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在MongoDB的Shell命令中并没有创建数据库的命令，假设现在要创建一个名为Blogs的数据库，并在这个数据库中添加集合和文档，我们可以想下面这样做：&lt;/p&gt;
&lt;p&gt;1 执行use Blogs命令将数据库切换到Blogs，当然此时Blogs还并没有被创建。&lt;/p&gt;
&lt;p&gt;2 创建一条数据记录保存在一个变量post中，执行db.Blogs.insert(post)。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300727969.webp" alt="2011-09-12_201351-300x91" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这时可以看在在上面设定的路径中已经生产了数据库的文件：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300727295.webp" alt="2011-09-12_201414-300x103" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;有关更多的Shell命令使用在后面的文章中再介绍。&lt;/p&gt;
&lt;h2 id="mongodb-drivers"&gt;MongoDB Drivers&lt;/h2&gt;
&lt;p&gt;要在程序中使用MongoDB，需要要到MongoDB针对某一语言的驱动，在MongoDB的官网中已经提供了Ruby 、Python、C#、PHP等多种语言的驱动。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;驱动列表页：&lt;a href="http://www.mongodb.org/display/DOCS/Drivers"&gt;http://www.mongodb.org/display/DOCS/Drivers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;C#驱动下载：&lt;a href="https://github.com/samus/mongodb-csharp"&gt;https://github.com/samus/mongodb-csharp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对MongoDB的简单介绍就到此，后面的文章会用C#来写一个完整的示例。&lt;/p&gt;</description></item><item><title>在VS中查看文件是谁签出的</title><link>https://fwhyy.com/2011/08/in-vs-view-who-file-is-checked-out/</link><pubDate>Sat, 20 Aug 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/08/in-vs-view-who-file-is-checked-out/</guid><description>&lt;p&gt;最近的项目使用的源码管理器是VSS，有时候你想修改的文件被别人签出了，所以我们需要知道该文件是被谁签出了，好及时和他沟通。我原来的做法都是直接进入VSS管理器中进行查看，但这样很麻烦，每次都要打开VSS管理器。其实可以在VS中进行简单的设置就可以了，步骤如下：&lt;/p&gt;
&lt;p&gt;1 在VS中的菜单上单击鼠标右键，然后选择显示“源代码管理”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300706197.webp" alt="2011-08-13_160609" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 选中要查看的文件后，在源代码管理中单击“属性”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300706261.webp" alt="2011-08-13_160643" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 打开第2个标签页“Check Out Status”，可以看到签出人等信息。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300706850.webp" alt="2011-08-13_160833" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>在SQL查询中使用LIKE来代替IN</title><link>https://fwhyy.com/2011/08/in-the-sql-query-using-the-like-instead-of-the-in/</link><pubDate>Sat, 13 Aug 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/08/in-the-sql-query-using-the-like-instead-of-the-in/</guid><description>&lt;p&gt;在SQL查询中根据已知ID的集合来查询结果我们通常会用到IN，直接在IN后面给出ID的集合或是在IN后面跟一个子查询。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT * FROM Orders
WHERE OrderGUID IN(&amp;#39;BC71D821-9E25-47DA-BF5E-009822A3FC1D&amp;#39;,&amp;#39;F2212304-51D4-42C9-AD35-5586A822258E&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以看出直接在IN后面跟ID的集合需要将每一个ID都用单引号引起来。在实际应用中会遇到这么一种情况，在界面中收集的是一串GUID的拼接字符串，中间以逗号隔开，如果作为参数传到一个存储过程中执行，最终生成的语句会是下面这样：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT * FROM Orders
WHERE OrderGUID IN(&amp;#39;BC71D821-9E25-47DA-BF5E-009822A3FC1D,F2212304-51D4-42C9-AD35-5586A822258E&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这样就不能查询到正确的结果。&lt;/p&gt;
&lt;p&gt;一般情况下我们解决此问题的思路是将传入的字符串用一个split函数来处理，最终处理的结果是一张表，然后将这个表做自查询即可，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DECLARE @IDs VARCHAR(4000)
SET @IDs=&amp;#39;BC71D821-9E25-47DA-BF5E-009822A3FC1D,F2212304-51D4-42C9-AD35-5586A822258E&amp;#39;
DECLARE @temp TABLE(str VARCHAR(50))
INSERT INTO @temp
SELECT * FROM dbo.Split(@IDs,&amp;#39;,&amp;#39;)
SELECT * FROM Orders WHERE OrderGUID IN (SELECT str FROM @temp)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当然split函数系统比不提供，需要我们自己写：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE FUNCTION Split
(
 @SourceSql varchar(8000),
 @StrSeprate varchar(10)
)
RETURNS @temp TABLE(F1 VARCHAR(100))
AS
BEGIN
 DECLARE @i INT
 SET @SourceSql=rtrim(ltrim(@SourceSql))
 SET @i=charindex(@StrSeprate,@SourceSql)
 WHILE @i&amp;gt;=1
 BEGIN
 INSERT @temp VALUES(left(@SourceSql,@i-1))
 SET @SourceSql=substring(@SourceSql,@i+1,len(@SourceSql)-@i)
 SET @i=charindex(@StrSeprate,@SourceSql)
 END
 IF @SourceSql&amp;lt;&amp;gt;&amp;#39;&amp;#39;
 INSERT @temp VALUES(@SourceSql)
 RETURN
END
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;像这样做非常麻烦，而且还需要借助函数来实现，下面介绍一种简单的方法，因为GUID是唯一的，所以在上面的例子中可以使用LIKE来代替IN也可以达到同样的查询效果：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT * FROM Orders
WHERE &amp;#39;BC71D821-9E25-47DA-BF5E-009822A3FC1D,F2212304-51D4-42C9-AD35-5586A822258E&amp;#39;
LIKE &amp;#39;%&amp;#39;+convert(VARCHAR(40),OrderGUID)+&amp;#39;%&amp;#39;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>SqlServer表死锁的解决方法</title><link>https://fwhyy.com/2011/08/essentially-a-table-of-deadlock-solution/</link><pubDate>Sat, 06 Aug 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/08/essentially-a-table-of-deadlock-solution/</guid><description>&lt;p&gt;前些天写一个存储过程，存储过程中使用了事务，后来我把一些代码注释掉来进行调试找错，突然发现一张表被锁住了，原来是创建事务的代码忘记注释掉。本文表锁住了的解决方法。&lt;/p&gt;
&lt;p&gt;其实不光是上面描述的情况会锁住表，还有很多种场景会使表放生死锁，解锁其实很简单，下面用一个示例来讲解：&lt;/p&gt;
&lt;p&gt;1 首先创建一个测试用的表：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE TABLE Test
(
 TID INT IDENTITY(1,1)
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 执行下面的SQL语句将此表锁住：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT * FROM Test WITH (TABLOCKX)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 通过下面的语句可以查看当前库中有哪些表是发生死锁的：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT request_session_id spid,OBJECT_NAME(resource_associated_entity_id)tableName
FROM sys.dm_tran_locks
WHERE resource_type=&amp;#39;OBJECT &amp;#39; 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 上面语句执行结果如下：&lt;/p&gt;
&lt;p&gt;spid ：被锁进程ID。
tableName：发生死锁的表名。
5 只需要使用kill关键字来杀掉被锁的进程ID就可以对表进行解锁：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;KILL 52
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>使用sp_xml_preparedocument处理XML文档</title><link>https://fwhyy.com/2011/07/use-sp-xml-preparedocument-processing-xml-documents/</link><pubDate>Sat, 23 Jul 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/07/use-sp-xml-preparedocument-processing-xml-documents/</guid><description>&lt;p&gt;有时会在存储过程中处理一些XML格式的数据，所以会用到sp_xml_preparedocument，他可以将XML数据进行读取，然后使用 MSXML 分析器 (Msxmlsql.dll) 对其进行分析。我们就可以很容易的在存储过程中得到XML中我们想要的数据。下面的代码就是使用sp_xml_preparedocument读取XML：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc =&amp;#39;
&amp;lt;ROOT&amp;gt;
&amp;lt;Customer CustomerID=&amp;#34;VINET&amp;#34; ContactName=&amp;#34;Paul Henriot&amp;#34;&amp;gt;
 &amp;lt;Order CustomerID=&amp;#34;VINET&amp;#34; EmployeeID=&amp;#34;5&amp;#34; OrderDate=&amp;#34;1996-07-04T00:00:00&amp;#34;&amp;gt;
 &amp;lt;OrderDetail OrderID=&amp;#34;10248&amp;#34; ProductID=&amp;#34;11&amp;#34; Quantity=&amp;#34;12&amp;#34;/&amp;gt;
 &amp;lt;OrderDetail OrderID=&amp;#34;10248&amp;#34; ProductID=&amp;#34;42&amp;#34; Quantity=&amp;#34;10&amp;#34;/&amp;gt;
 &amp;lt;/Order&amp;gt;
&amp;lt;/Customer&amp;gt;
&amp;lt;Customer CustomerID=&amp;#34;LILAS&amp;#34; ContactName=&amp;#34;Carlos Gonzlez&amp;#34;&amp;gt;
 &amp;lt;Order CustomerID=&amp;#34;LILAS&amp;#34; EmployeeID=&amp;#34;3&amp;#34; OrderDate=&amp;#34;1996-08-16T00:00:00&amp;#34;&amp;gt;
 &amp;lt;OrderDetail OrderID=&amp;#34;10283&amp;#34; ProductID=&amp;#34;72&amp;#34; Quantity=&amp;#34;3&amp;#34;/&amp;gt;
 &amp;lt;/Order&amp;gt;
&amp;lt;/Customer&amp;gt;
&amp;lt;/ROOT&amp;gt;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
上面只是读取了XML，要想获取XML数据还需要使用OPENXML，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;SELECT *
FROM openxml(@hdoc,&amp;#39;/ROOT/Customer&amp;#39;,1)
WITH (CustomerID VARCHAR(40),ContactName VARCHAR(40)) 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OPENXML有三个参数：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一个是sp_xml_preparedocument读取是的OUTPUT参数，在本示例中就是@hdoc；&lt;/li&gt;
&lt;li&gt;第二个是一个XPath表达式，用来获取指定位置的数据；&lt;/li&gt;
&lt;li&gt;第三个是一个可选项，用来表示获取的方式，有0,1,2,8四种取值，详细解释&lt;a href="http://msdn.microsoft.com/zh-cn/library/ms186918.aspx"&gt;请看&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;FROM后面的WITH也是可选的，用来指定获取哪些数据字段，上面代码中只取了CustomerID和ContactName。上面的查询结果如下：&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;CustomerID&lt;/th&gt;
					&lt;th&gt;ContactName&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;LILAS&lt;/td&gt;
					&lt;td&gt;Carlos Gonzlez&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;如果不指定WITH子句，查询出来的是一个默认的表结构，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2011/2011-07-23_114701.webp" alt="2011-07-23_114701" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;表格列的解释说明：&lt;/p&gt;
&lt;p&gt;在WITH子句中,我们还可以通过设置来获取父级元素的属性值:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DECLARE @hdoc int
DECLARE @doc varchar(1000)
SET @doc =&amp;#39;
&amp;lt;ROOT&amp;gt;
&amp;lt;Customer CustomerID=&amp;#34;VINET&amp;#34; ContactName=&amp;#34;Paul Henriot&amp;#34;&amp;gt;
 &amp;lt;Order OrderID=&amp;#34;10248&amp;#34; CustomerID=&amp;#34;VINET&amp;#34; EmployeeID=&amp;#34;5&amp;#34;
 OrderDate=&amp;#34;1996-07-04T00:00:00&amp;#34;&amp;gt;
 &amp;lt;OrderDetail ProductID=&amp;#34;11&amp;#34; Quantity=&amp;#34;12&amp;#34;/&amp;gt;
 &amp;lt;OrderDetail ProductID=&amp;#34;42&amp;#34; Quantity=&amp;#34;10&amp;#34;/&amp;gt;
 &amp;lt;/Order&amp;gt;
&amp;lt;/Customer&amp;gt;
&amp;lt;Customer CustomerID=&amp;#34;LILAS&amp;#34; ContactName=&amp;#34;Carlos Gonzlez&amp;#34;&amp;gt;
 &amp;lt;Order OrderID=&amp;#34;10283&amp;#34; CustomerID=&amp;#34;LILAS&amp;#34; EmployeeID=&amp;#34;3&amp;#34;
 OrderDate=&amp;#34;1996-08-16T00:00:00&amp;#34;&amp;gt;
 &amp;lt;OrderDetail ProductID=&amp;#34;72&amp;#34; Quantity=&amp;#34;3&amp;#34;/&amp;gt;
 &amp;lt;/Order&amp;gt;
&amp;lt;/Customer&amp;gt;
&amp;lt;/ROOT&amp;gt;&amp;#39;

EXEC sp_xml_preparedocument @hdoc OUTPUT, @doc
SELECT *
FROM OPENXML (@hdoc, &amp;#39;/ROOT/Customer/Order/OrderDetail&amp;#39;,2)
 WITH (OrderID int &amp;#39;../@OrderID&amp;#39;,
 CustomerID varchar(10) &amp;#39;../@CustomerID&amp;#39;,
 OrderDate datetime &amp;#39;../@OrderDate&amp;#39;,
 ProdID int &amp;#39;@ProductID&amp;#39;,
 Qty int &amp;#39;@Quantity&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;查询的结果为:&lt;/p&gt;</description></item><item><title>使用MicroSoft CLR Debug来调试较大项目</title><link>https://fwhyy.com/2011/07/use-microsoft-clr-debug-to-debug-larger-projects/</link><pubDate>Wed, 20 Jul 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/07/use-microsoft-clr-debug-to-debug-larger-projects/</guid><description>&lt;p&gt;在以前的开发中，调试时很自然的会直接按F5进行调试，有时项目部署在IIS中也只是将项目的服务器指向IIS，仍然是将整个项目运行设置断点进行调试。最近遇到了一个问题，项目很大，直接F5运行会导致VS卡死，这种时候使用MicroSoft CLR Debug来进行调试是最合适不过了。&lt;/p&gt;
&lt;p&gt;首先打开MicroSoft CLR Debug&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290710632.webp" alt="2011-07-18_164829" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;打开后界面如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290710108.webp" alt="2011-07-18_164908" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;从项目中选择一个需要调试的文件，并在需要调试的地方设置断点&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290710393.webp" alt="2011-07-18_165017" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“调试”-“附加到进程”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290710454.webp" alt="2011-07-18_165041" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;附加进程前确保你的项目已经运行，如果是Win2003系统，会有一个w3wp.exe的进程存在,如果是xp系统，该进程名是aspnet_wp.exe。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290710503.webp" alt="2011-07-18_165126" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;此时运行程序就会命中断点，个人认为此方法比较适用于将项目部署到IIS中进行调试，此方法的几个优点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不会占用很多资源，只需要将需要调试的文件添加进来设置断点即可。&lt;/li&gt;
&lt;li&gt;如果是管理系统之类的项目，只需要登陆一次即可，不需要每次调试时都重新登陆。&lt;/li&gt;
&lt;li&gt;退出调试不会对运行的程序有什么影响，如果是F5进行调试，退出调试页面就关闭了。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Foxit Reader–给PDF制作书签</title><link>https://fwhyy.com/2011/07/give-the-pdf-bookmarks-production/</link><pubDate>Sun, 10 Jul 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/07/give-the-pdf-bookmarks-production/</guid><description>&lt;p&gt;作为一名软件开发人员，平时免不了会在网上下载PDF版的书籍进行充电。英文版的还好，通常都会带有书签，但是中文版的特别是扫面版基本上都没有书签，这样给阅读带了很大的不方便，下面推荐的这款软件就可以给PDF制作书签。&lt;/p&gt;
&lt;p&gt;Foxit Reader&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官网：&lt;a href="http://www.fuxinsoftware.com.cn/"&gt;http://www.fuxinsoftware.com.cn/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;下载地址：&lt;a href="http://www.fuxinsoftware.com.cn/downloads/"&gt;http://www.fuxinsoftware.com.cn/downloads/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Foxit 下面有很多产品，只有Foixt Reader是免费的，不过这已经足够了，可以用他来做书签。使用方法如下：&lt;/p&gt;
&lt;p&gt;1 用Foixt Reader打开一个需要制作书签的PDF文档。&lt;/p&gt;
&lt;p&gt;2 选择“Edit-》Add BookMark”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300656974.webp" alt="2011-07-10_101549" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 在新加的书签项中填写章节的名称，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300656903.webp" alt="2011-07-10_102226" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 将PDF文档滚动到相应的位置，然后在新加的书签项上点击右键，选择“设置目的”，这样就将书签和PDF中的页面关联起来了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300656834.webp" alt="2011-07-10_1024031" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5 按照上面的方法就可以按照书籍的目录来将所有的书签都制作好，做好后只需要拖动书签就可以改变书签的层级，使之显示为树状结构。如果想将A书签放在B书签下，点击A不放拖动到B上，当出现虚线时放开鼠标即可。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300656446.webp" alt="2011-07-10_102544" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>给Javascript代码“预留退路”</title><link>https://fwhyy.com/2011/06/retreat-to-the-javascript-code-reserved/</link><pubDate>Thu, 16 Jun 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/06/retreat-to-the-javascript-code-reserved/</guid><description>&lt;p&gt;所谓给Javascript代码“预留退路”意思就是当用户将浏览器的Javascript功能禁用的时候，页面中使用了Javascript的地方要能够以变通的方式得以运行，而不能让用户看到出错或是点击某按钮而毫无反应，这也是用户体验很重要的一部分。&lt;/p&gt;
&lt;p&gt;举个简单的例子来说，点击页面中的一个链接可以弹出一个新的页面，我们通常会使用window.open，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;a href=&amp;#34;#&amp;#34; onclick=&amp;#34;openWin(&amp;#39;http://baidu.com&amp;#39;);&amp;#34;&amp;gt;百度&amp;lt;/a&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function openWin(url) {
 window.open(url, &amp;#34;openwin&amp;#34;, &amp;#34;width=600,height=400&amp;#34;);
 }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;或&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;a href=&amp;#34;javascript:openWin1(&amp;#39;http://baidu.com&amp;#39;);&amp;#34; &amp;gt;百度&amp;lt;/a&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function openWin(url) {
 window.open(url, &amp;#34;openwin&amp;#34;, &amp;#34;width=600,height=400&amp;#34;);
 }
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的两种方法第一种将href的值设置为#，第二种使用伪协议javascript: ，这两种做法都不是很好，没有“预留退路”，当用户将浏览器的Javascript禁用后，点击链接都不是我们想要的结果，正确的做法如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;a href=&amp;#34;http://baidu.com/&amp;#34;
 onclick=&amp;#34;openWin(this.getAttribute(&amp;#39;href&amp;#39;));return false;&amp;#34; &amp;gt;百ù度è&amp;lt;/a&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function openWin1(url) {
 window.open(url, &amp;#34;openwin&amp;#34;, &amp;#34;width=600,height=400&amp;#34;);
 }
 &amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;改进后的方法在禁用Javascript后，也会打开href中的链接地址，只是打开方式有所不同，相比上面两种已经好多了。&lt;/p&gt;</description></item><item><title>未在本地计算机上注册“Microsoft.Jet.OleDb.4.0”提供程序 错误解决</title><link>https://fwhyy.com/2011/06/not-registered-on-the-local-computer-microsoft-jet-oledb-4/</link><pubDate>Wed, 15 Jun 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/06/not-registered-on-the-local-computer-microsoft-jet-oledb-4/</guid><description>&lt;p&gt;最近在做一个导入Excel数据到数据库的程序出现了如下错误：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301558041.webp" alt="2011-06-15_1552061" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="运行环境"&gt;运行环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;数据库：SqlServer2008 R2&lt;/li&gt;
&lt;li&gt;OS：Windows Server 2008 R2&lt;/li&gt;
&lt;li&gt;IIS：IIS7&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;p&gt;在应用程序对用的应用程序池的高级设置中设置“启用32位应用程序”为“True”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301558286.webp" alt="2011-06-15_155851" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Windows服务在Win7中不能安装的解决方法</title><link>https://fwhyy.com/2011/05/windows-service-in-windows-7-cant-install-solution/</link><pubDate>Tue, 24 May 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/05/windows-service-in-windows-7-cant-install-solution/</guid><description>&lt;p&gt;用C#写的Windows服务在Win7中安装时出现如下错误：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290648137.webp" alt="2011-05-24_102447" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;解决方法：&lt;/p&gt;
&lt;p&gt;1 安装服务的脚本写在bat文件中，一定要注意路径，如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;D:\Project\JXW\Code\WorkFlow\FlowServer\installutil.exe D:\Project\JXW\Code\WorkFlow\FlowServer\FlowServer.exe

pause


net start ShineFlow.FlowServer
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 在bat文件上点击右键-》以管理员身份运行。&lt;/p&gt;
&lt;p&gt;3 成功安装服务，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290649864.webp" alt="2011-05-24_102806" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>附加数据库失败 操作系统错误5</title><link>https://fwhyy.com/2011/05/additional-database-failure-5120-error/</link><pubDate>Sun, 22 May 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/05/additional-database-failure-5120-error/</guid><description>&lt;h2 id="环境"&gt;环境&lt;/h2&gt;
&lt;p&gt;数据库版本：SqlServer2008 R2 32位&lt;/p&gt;
&lt;p&gt;附加文件的版本：SqlServer2008 R2 64位&lt;/p&gt;</description></item><item><title>纪念日--领证</title><link>https://fwhyy.com/2011/05/anniversary/</link><pubDate>Fri, 20 May 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/05/anniversary/</guid><description>&lt;p&gt;今天是2011年5月20日，我和老婆领证了。&lt;/p&gt;
&lt;p&gt;原计划早早的去排头一个，但最终还是到9点多才到的婚姻登记处，人还挺多，也许是这个日子的原因。&lt;/p&gt;
&lt;p&gt;搞清楚流程后我们就排队等待审核，好不容易等到我们了，谁知我的户口本竟然不合格，因为上面的相关信息不是机打的而是手写了，说是按照相关对顶必须是机打的，当时心里那个急啊，我忙说我们那里比较落后没有电脑都是手写的，那人说你别骗我，我办过你们那个地方的就是机打的，我直接无语了。后来说了半天的好话，才同意给我们办但证先不能给我们，等我把户口本拿回去更新后才能给我们证。尽管如此，我和老婆还是感到很高兴。&lt;/p&gt;</description></item><item><title>在VS2010中将AspNet网站编译成一个DLL</title><link>https://fwhyy.com/2011/04/aspnet-website-compiled-into-a-dll-in-vs2010/</link><pubDate>Wed, 06 Apr 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/04/aspnet-website-compiled-into-a-dll-in-vs2010/</guid><description>&lt;p&gt;在VS2010中创建一个网站，部署时网站的dll是动态生成的，每次编译产生的dll的名称都不一样，这样会导致在部署时必须将aspx页面和dll一起部署，尽管有时你可能只修改了后台代码。这样就变得很不方便，在VS2010中可以借助一个插件是网站生成一个固定名称的dll。&lt;/p&gt;
&lt;p&gt;1 从下面的链接地址中下载 Visual Studio® 2010 Web Deployment Projects&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/en/confirmation.aspx?FamilyID=711a2eef-b107-4784-9063-c978edc498cd&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/en/confirmation.aspx?FamilyID=711a2eef-b107-4784-9063-c978edc498cd&amp;amp;displaylang=en&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2 安装Visual Studio® 2010 Web Deployment Projects插件，然后再网站项目上点击右键，可以看到多了一项Add Web Deployment Project&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290807175.webp" alt="2011-04-06_113023" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 点击Add Web Deployment Project，弹出如下对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290807160.webp" alt="2011-04-06_113422" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 名称和路径可以修改，一般默认就好，点击OK，在解决方案中会生成一个部署项目&lt;/p&gt;
&lt;p&gt;5 在部署项目点击右键，点击“生成”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290807093.webp" alt="2011-04-06_113814" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 生成成功后，在部署项目的目录中会产生一个Release目录，Release目录中就是项目发布的所有文件，在bin目录中可以看到并没有之前那样有很多不规则命名的dll，生成的dll的名称和前面添加部署项目时所填写的名称相同，为EduAppWeb_deploy&lt;/p&gt;</description></item><item><title>Asp.Net站点整合Discuz论坛实现同步注册和单点登录</title><link>https://fwhyy.com/2011/04/aspnet-site-integration-discuz-bbs-sync-reg-and-sso/</link><pubDate>Fri, 01 Apr 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/04/aspnet-site-integration-discuz-bbs-sync-reg-and-sso/</guid><description>&lt;p&gt;最近在一个小站中整合了Discuz论坛，查阅了些资料后实现了同步注册和单点登录。&lt;/p&gt;
&lt;p&gt;Discuz是以虚拟目录的方式加载网站中，整合Discuz到网站中进行安装要注意一下几个问题：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201292105539.webp" alt="2011-04-01_163915" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Discuz所在的目录需要添加NETWORK SERVICE 和IIS_User这两个账户的权限。&lt;/li&gt;
&lt;li&gt;Discuz根目录下的DNT.config文件需要修改，将&lt;Forumpath&gt;/&lt;/Forumpath&gt;修改为&lt;Forumpath&gt;/BBS/&lt;/Forumpath&gt;，BBS为虚拟目录的名称。&lt;/li&gt;
&lt;li&gt;由于我网站用了第三方的控件，在webconfig文件中进行了相关设置，然后在访问论坛时提示缺少程序集的引用，后来把第三方控件的dll加到Discuz下的bin目录中得以解决。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面说说怎样实现同步注册和单点登录&lt;/p&gt;
&lt;p&gt;其实在研究后发现很简单，当然我现在做的只是同域的情况下，跨域的情况还没研究，估计也不会很难，应该只是多了一个设置cookieDomain的过程。Discuz给我们提供了一个DiscuzToolkit的工具包，提供了很多API供调用，下面就一步步来吧。&lt;/p&gt;
&lt;p&gt;1 安装好Discuz论坛后，进入后台管理，选择扩展-》通行证设置-》添加整合程序设置&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;应用程序名称：可以随便输入&lt;/li&gt;
&lt;li&gt;应用程序Url地址：我填写的是我站点的地址&lt;/li&gt;
&lt;li&gt;登录完成后返回地址：同上&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;2 记下生成的APIKey和密匙，在后面的代码编写中会用到&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2011/2011-04-01_164204.webp" alt="2011-04-01_164204" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 我将APIKey，密匙都配置在了webconfig文件中&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201292106145.webp" alt="2011-04-01_164509" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;APIKey：value值为后台生成的APIKey&lt;/li&gt;
&lt;li&gt;Secret：value值为后台生成的密匙&lt;/li&gt;
&lt;li&gt;Url：value值为BBS的路径&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;4 写一个公共的BBSHelper类，将添加用户，登录，改密码等方法封装在里面。注意要引用命名空间Discuz.Toolkit&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 同步Discuz论坛帮助类
/// &amp;lt;/summary&amp;gt;
public class DiscuzBBSHelper
{
 private string _apiKey = string.Empty;
 private string _secret = string.Empty;
 private string _url = string.Empty;
 DiscuzSession _ds;

 public DiscuzBBSHelper()
 {
 _apiKey = ConfigHelper.APIKey();
 _secret = ConfigHelper.Secret();
 _url = ConfigHelper.Url();
 _ds = new DiscuzSession(_apiKey, _secret, _url);
 }

 /// &amp;lt;summary&amp;gt;
 /// 登录
 /// &amp;lt;/summary&amp;gt;
 public void Login(string userName,string pwd)
 {
 int uid = _ds.GetUserID(userName);
 _ds.Login(uid, pwd, false, 100, &amp;#34;&amp;#34;);
 }

 /// &amp;lt;summary&amp;gt;
 /// 登出
 /// &amp;lt;/summary&amp;gt;
 public void Logout()
 {
 _ds.Logout(&amp;#34;&amp;#34;);
 _ds.session_info = null;
 HttpContext.Current.Session[&amp;#34;AuthToken&amp;#34;] = null;
 }

 /// &amp;lt;summary&amp;gt;
 /// 创建用户
 /// &amp;lt;/summary&amp;gt;
 public void AddUser(string userName,string pwd)
 {
 _ds.Register(userName, pwd, &amp;#34;&amp;#34;, false);
 }

 /// &amp;lt;summary&amp;gt;
 /// 修改密码
 /// &amp;lt;/summary&amp;gt;
 public void ChangePWD(string userName,string oldPWD,string newPWD)
 {
 int uid = _ds.GetUserID(userName);
 _ds.ChangeUserPassword(uid, oldPWD, newPWD, newPWD, &amp;#34;&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 在网站需要的地方调用该类中的方法即可，如下：&lt;/p&gt;</description></item><item><title>在SqlServer 2008中将数据导成脚本</title><link>https://fwhyy.com/2011/03/data-into-the-sql-script-in-sqlserver-2008/</link><pubDate>Thu, 31 Mar 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/03/data-into-the-sql-script-in-sqlserver-2008/</guid><description>&lt;p&gt;当我们想将数据库搬到另一个环境中运行时，如果数据库的版本一样我们可以直接选择附加的方式，而如果实验环境中的数据库版本比当前数据库低，就无法附加了。这时要向将数据全部导过去就需要使用脚本的方式，像Sqldbx就可以将数据库中的数据导出成脚本。本文将说下怎样直接在SqlServer 2008中将数据导出成脚本。&lt;/p&gt;
&lt;p&gt;具体步骤：&lt;/p&gt;
&lt;p&gt;1 打开SqlServer 2008 ，选择需要将数据导出到脚本的数据库。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290623081.webp" alt="2011-03-31_102716" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在选中数据库上右击，选择任务-》生成脚本…&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290623858.webp" alt="2011-03-31_102951" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 点击“生成脚本”后，弹出一个生成脚本的向导。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290623337.webp" alt="2011-03-31_103235" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 点击下一步至“设置脚本编写选项”，点击高级进入到高级设置对话框，可以看到“要编写脚本数据的类型”默认是“仅限架构”。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290623298.webp" alt="2011-03-31_103700" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5 将“要编写脚本的数据的类型”修改为“架构和数据”。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290623038.webp" alt="2011-03-31_103808" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 执行完后，可以看到脚本中多了很多的Insert语句。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290624044.webp" alt="2011-03-31_104032" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>SQL2008修改并保存表结构时报错的解决(阻止保存要求重新创建表的更改)</title><link>https://fwhyy.com/2011/03/sql2008-modify-and-save-the-table-structure-error/</link><pubDate>Wed, 09 Mar 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/03/sql2008-modify-and-save-the-table-structure-error/</guid><description>&lt;p&gt;今天在SqlServer2008中修改表结构时，弹出下面对话框阻止我保存&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301954622.webp" alt="20100304002" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;解决此问题方法为：&lt;/p&gt;
&lt;p&gt;1 打开SqlServer2008工具—&amp;gt;选项&lt;/p&gt;
&lt;p&gt;2 在弹出的对话框中去掉“阻止保存要求重新创建表的更改”，如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301954844.webp" alt="2011-03-09_161021" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Excel导入数据库出现“外部表不是预期的格式”错误的解决方法</title><link>https://fwhyy.com/2011/03/excel-import-database-external-table-is-not-desired-format-mistakes-of-the-solution/</link><pubDate>Tue, 08 Mar 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/03/excel-import-database-external-table-is-not-desired-format-mistakes-of-the-solution/</guid><description>&lt;p&gt;下图为出错的界面&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300645078.webp" alt="20110308001" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;出错的原因是因为Excel的格式不是标准的Excel格式，像我出现这个错误的原因就是使用的Excel是用程序导出的Excel。&lt;/p&gt;
&lt;p&gt;解决此问题方法很简单：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将格式不标准的Excel另存为一个标准格式。&lt;/li&gt;
&lt;li&gt;如果Excel是用程序导出的，可以修改导出程序，将其导出为标准格式。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>CHM文件的锁定</title><link>https://fwhyy.com/2011/03/chm-file-locking/</link><pubDate>Fri, 04 Mar 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/03/chm-file-locking/</guid><description>&lt;p&gt;刚从皮皮书屋下载了一本关于HTTP的书《HTTP: The Definitive Guide》，下完打开发现内容无法显示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290811568.webp" alt="2011-03-14_115223" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;开始还以为是文件损坏还是其他什么原因，google一下后才知道是因为文件被锁定了，只要解锁就可以正常访问。&lt;/p&gt;
&lt;p&gt;在文件上点击右键，选择属性，在常规选项卡中点击“解除锁定”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290811981.webp" alt="2011-03-14_115803" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再次打开文件，就可以正常显示了。&lt;/p&gt;</description></item><item><title>VirtualPC2007的文件复制到其他电脑不能打开的问题解决</title><link>https://fwhyy.com/2011/03/virtualpc2007-file-is-copied-to-the-other-computer-cant-open-the-problem-solving/</link><pubDate>Fri, 04 Mar 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/03/virtualpc2007-file-is-copied-to-the-other-computer-cant-open-the-problem-solving/</guid><description>&lt;p&gt;在使用VirtualPC的时候，我一般都习惯保存当前状态的方式关机，这样在下次使用的时候可以保证继续我上次的工作状态。最近我将保存状态的VirtualPC2007的文件拷贝到另一台电脑中，然后用VirtualPC2007去添加，我选择的是已经存在的虚机，这时会报一个错误，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290625609.webp" alt="201103040011" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;经过查询得知，解决此问题的方法为启动VirtualPC后，按照添加新的虚机的方法去做，直到提示要选择硬盘的时候，选择已经存在的虚机硬盘，然后选择要添加虚机的vhd文件。这样就可以顺利的添加成功了。&lt;/p&gt;
&lt;p&gt;这时复制过来的虚机文件中的vmc文件还是以前的保存了状态的那个文件，新的vmc文件在目录C:\Users\Administrator\Documents\My Virtual Machines\虚机的名字 目录下，可以将此文件替换原来的vmc文件。&lt;/p&gt;
&lt;p&gt;吃一堑长一智，以后如果要将虚机拷贝到别的电脑上用，一定要先将虚机关机。&lt;/p&gt;</description></item><item><title>解决“此版本的 SQL Server 不支持用户实例登录标志。该连接将关闭”问题</title><link>https://fwhyy.com/2011/02/sql-server-does-not-support-the-user-instance-login-flag/</link><pubDate>Tue, 22 Feb 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/02/sql-server-does-not-support-the-user-instance-login-flag/</guid><description>&lt;p&gt;错误提示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301954824.webp" alt="20110222-001" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;出现此错误的原因为在webconfig连接字符串中的;User Instance设置为True了，将;User Instance值修改为false即可解决此问题。&lt;/p&gt;</description></item><item><title>解决AspNet中DataGrid GridView等列表控件导出Excel长数字显示成科学计数法的问题</title><link>https://fwhyy.com/2011/01/solve-gridview-long-export-excel-such-as-digital-display/</link><pubDate>Sun, 23 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/solve-gridview-long-export-excel-such-as-digital-display/</guid><description>&lt;p&gt;大家都知道，在Excel中，当一个单元格中的值为一长串数字，而且该单元格又不是文本格式的时候，这一长串数字会以科学计数法的方式显示，这给我们的阅读带来了障碍。如果是直接在Excel中编辑数据，手动将格式改为“文本”即可，但要是用程序导出的Excel，手动去改就显得很麻烦了。简单的方法就是在程序中导出Excel的时候就设置列为“文本”格式。&lt;/p&gt;
&lt;p&gt;AspNet中将DataGrid，GridView等列表控件导出Excel的代码通常如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DataSet ds = GetData();
this.GridView1.DataSource = ds;
GridView1.DataBind();

//导出Excel的方法
Export(GridView1, &amp;#34;mayfile.xls&amp;#34;, &amp;#34;application/ms-excel&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在只需在调用导出Excel方法前对GridView中的列进行设置即可，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;DataSet ds = GetData();
this.GridView1.DataSource = ds;
GridView1.DataBind();

for (int i = 0; i &amp;lt; GridView1.Rows.Count; i++)
{
 for (int j = 0; j &amp;lt; GridView1.Columns.Count; j++)
 {
 GridView1.Rows[i].Cells[j].Attributes.Add(&amp;#34;style&amp;#34;, &amp;#34;vnd.ms-excel.numberformat:@&amp;#34;);
 }
}

//导出Excel的方法
Export(GridView1, &amp;#34;mayfile.xls&amp;#34;, &amp;#34;application/ms-excel&amp;#34;);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码是将GridView中所有的列都设置成了文本格式，你也可以根据需要对指定的几列进行设置。&lt;/p&gt;</description></item><item><title>微软最新的 Web 开发工具WebMatrix的简单介绍及安装</title><link>https://fwhyy.com/2011/01/the-latest-microsoft-web-development-tools-webmatrix-simple-introduction-and-installation/</link><pubDate>Fri, 14 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/the-latest-microsoft-web-development-tools-webmatrix-simple-introduction-and-installation/</guid><description>&lt;p&gt;今天很给力，微软Asp.Net团队同时发布了WebMatrix,Razor,MVC3以及Orchard四个产品，其中&lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;WebMatrix&lt;/a&gt; 是微软最新的 Web 开发工具，它包含了构建网站所需要的一切元素。您可以从开源 Web 项目或者内置的 Web 模板开始，也可以直接从无到有编写代码。简单并且完全是免费的。开发网站从来没有如此简单。&lt;/p&gt;
&lt;p&gt;什么介绍也没有官方的详细，我就将官网的介绍文字引用过来吧，当然你也可以访问&lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;http://www.microsoft.com/web/webmatrix/&lt;/a&gt;进行了解。&lt;/p&gt;
&lt;h2 id="建立您的网站"&gt;建立您的网站&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;为了开始建立网站，您只需要使用 Microsoft Web 平台安装器下载并安装 WebMatrix。这只会占用您短短的5分钟时间。当 WebMatrix 成功安装后，您可以非常方便地获得并下载最新版本的免费 Web 应用，如 WordPress, Joomla!, DotNetNuke 和 Orchard.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="自定义您的网站"&gt;自定义您的网站&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;您会发现 WebMatrix 在一个统一界面中提供了您需要的一切工具的特性，不需要再花费精力于在多种应用工具切换来完成一般性的 Web 开发任务。通过 WebMatrix，您只需要一步点击，即可编辑文件，管理数据库和更改服务器设置等。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="发布您的网站"&gt;发布您的网站&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;当您完成网站开发后，WebMatrix 提供了最快速的方法来发布。通过访问托管服务库，您可以找到提供托管服务的合作伙伴，并且您可以直接通过 WebMatrix 来发布您的网站。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;WebMatrix&lt;/a&gt;的安装需要连接到网络，进入到官方网站，下载下exe的安装文件，双击进入安装。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302105019.webp" alt="2011-01-14_125505" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201302105421.webp" alt="2011-01-14_125530" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201302105543.webp" alt="2011-01-14_125600" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“安装”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302105185.webp" alt="2011-01-14_125634" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“我接受”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302105768.webp" alt="2011-01-14_125655" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;等待下载完成，自动进行安装&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302105713.webp" alt="2011-01-14_130224" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再稍等几分钟&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302105235.webp" alt="2011-01-14_131824" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“完成”，就安装完成了，Web平台安装程序3.0 的界面如下，我们可以自行添加需要的项目进行安装&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302105836.webp" alt="2011-01-14_133049" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;刚刚接触&lt;a href="http://www.microsoft.com/web/webmatrix/"&gt;WebMatrix&lt;/a&gt;，会尽快抽时间好好体验一下，然后写成博文与大家分享。&lt;/p&gt;</description></item><item><title>在SharePoint2007中创建站点一：相关服务的启动</title><link>https://fwhyy.com/2011/01/sharepoint2007-related-service-startup/</link><pubDate>Thu, 13 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/sharepoint2007-related-service-startup/</guid><description>&lt;p&gt;在程序中打开“SharePoint3.0管理中心”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941047.webp" alt="2011-01-11_225545" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“SharePoint3.0管理中心”会弹出要求输入用户名和密码的对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941326.webp" alt="2011-01-11_232210" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;输入用户名和密码（注意用户名需要是域名加上用户名），点击“确定”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941628.webp" alt="2011-01-11_232432" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在上图中可以看出，服务器场配置未完成，所以先来配置服务器场。在“服务器场拓扑结构”下的“服务器”下点击服务器名称，上图中为“FENGWEI ”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941460.webp" alt="2011-01-11_233056" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;单击“Office SharePoint Server搜索”后面的“启动”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941413.webp" alt="2011-01-11_233919" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2011/2011-01-11_234255.webp" alt="2011-01-11_234255" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;勾选“使用此服务器索引内容”和“使用此服务器提供搜索查询服务”&lt;/p&gt;
&lt;p&gt;输入一个电子邮件地址&lt;/p&gt;
&lt;p&gt;输入管理员的账户信息，需要注意的是用户名必须以“域\用户名”的格式，如上图&lt;/p&gt;
&lt;p&gt;填写完毕后点击“开始”按钮来启动搜索服务&lt;/p&gt;
&lt;p&gt;使用同样的方法启动“Windows SharePoint Services 搜索 ”服务&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941209.webp" alt="2011-01-11_234904" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“Windows SharePoint Services 搜索”右边的“启动”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301941256.webp" alt="2011-01-11_235051" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;填写“服务账户”和“内容访问账户”，两个账户填写一致就可以，注意用户名为“域\用户名”的格式，只填写这个两个账户信息即可，其他的保持默认，填写完毕点击“开始”按钮来启动服务&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301942453.webp" alt="2011-01-11_235346" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;数秒后服务便启动成功&lt;/p&gt;
&lt;p&gt;现在点击“Excel Calculation Services ”右边的“启动”来启动“Excel Calculation Services ”服务，启动该服务只需点击“启动”按钮即可，不需要做任何设置&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301942826.webp" alt="2011-01-11_235759" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;到此服务已经启动完成，切换到“主页”选项卡，服务器场拓扑结构如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301942490.webp" alt="2011-01-12_000124" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>SharePoint2007配置</title><link>https://fwhyy.com/2011/01/sharepoint2007-configuration/</link><pubDate>Wed, 12 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/sharepoint2007-configuration/</guid><description>&lt;p&gt;在前面的文章中已经介绍了SharePoint2007的安装，本篇将详细介绍下SharePoint2007的配置。首先从程序中打开SharePoint2007的配置向导。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301943608.webp" alt="2011-01-11_204240" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;向导启动后的界面如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301943157.webp" alt="2011-01-11_204406" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301944914.webp" alt="2011-01-11_204420" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图中提示需要启动或重启几个相关服务，点击“是”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301944425.webp" alt="2011-01-11_211055" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;因为我们是在安装第一台SharePoint服务器，所以选择第二项“否，我希望创建新的服务器场”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301945489.webp" alt="2011-01-11_221442" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;“数据库服务器”填写安装的SqlServer2005的服务器名称&lt;/p&gt;
&lt;p&gt;“数据库名称”默认为“SharePoint_Config ”，不用做修改&lt;/p&gt;
&lt;p&gt;“用户名为”AD域加上账户名称，如：fwhyy\administrator&lt;/p&gt;
&lt;p&gt;“密码”为Win2003Server的密码&lt;/p&gt;
&lt;p&gt;填写好后点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301945568.webp" alt="2011-01-11_221850" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;默认情况下系统会自动给分配一个端口号，在这里，我们指定一个特定的端口，勾选“指定端口号”，在后面的文本框中输入10000，“Web应用程序的验证提供程序”选择NTLM，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301945543.webp" alt="2011-01-11_222312" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;所有的设置已经完成，点击“下一步”开始配置，请耐心等待&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301945504.webp" alt="2011-01-11_222430" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;稍等几分钟后便可配置成功&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301945270.webp" alt="201101130943278918" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“完成”后SharePoint的配置就结束了。创建SharePoint站点等会在后面的文章中详细介绍。&lt;/p&gt;</description></item><item><title>SharePoint2007安装图文详解三：安装SqlServer2005</title><link>https://fwhyy.com/2011/01/install-sqlserver2005/</link><pubDate>Tue, 11 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/install-sqlserver2005/</guid><description>&lt;p&gt;SharePoint2007 中的很多功能会用到数据库，如分析服务，报表服务等。本文介绍SqlServer2005的安装，数据库的安装很简单，基本上安装默认选项点击下一步即可，需要注意的地方在下面会提到。&lt;/p&gt;
&lt;p&gt;现在就开始安装SqlServer2005 ，运行Setup.exe&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707160.webp" alt="2011-01-10_100800" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选中“我接受许可条款和条件”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707706.webp" alt="2011-01-10_113025" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“安装”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707388.webp" alt="2011-01-10_113725" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707407.webp" alt="2011-01-10_113911" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707915.webp" alt="2011-01-10_113957" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707990.webp" alt="2011-01-10_114354" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300707920.webp" alt="2011-01-10_114427" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“高级”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708207.webp" alt="2011-01-10_120035" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;根据需要选择需要安装的服务，此处我将所有的都选择了，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708185.webp" alt="2011-01-10_120318" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“默认实例”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708141.webp" alt="2011-01-10_144340" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“使用域用户账户”，输入用户名和密码，域填写在安装AD时配置的域名称。填写完后点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708895.webp" alt="201101111515433034" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“Windows身份验证模式”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708213.webp" alt="2011-01-10_145622" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;按照默认，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708228.webp" alt="2011-01-10_145752" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“安装默认配置”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300708174.webp" alt="2011-01-10_145938" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300709983.webp" alt="2011-01-10_150028" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“安装”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300709405.webp" alt="2011-01-10_150143" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;现在等他自己安装就行了，我们可以去做做别的事情。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300709198.webp" alt="2011-01-10_153124" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;到现在SqlServer2005已经安装成功了。&lt;/p&gt;
&lt;h2 id="相关文章"&gt;相关文章&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2011/01/iis-install/"&gt;SharePoint2007安装图文详解一：安装IIS及相关组件&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2011/01/installation-of-ad-and-dns/"&gt;SharePoint2007安装图文详解二：安装AD（活动目录）及DNS&lt;/a&gt;
SharePoint2007安装图文详解三：安装SqlServer2005
&lt;a href="http://blog.fwhyy.com/2011/01/installation-of-the-net-framework-3-0-and-sharepoint-2007/"&gt;SharePoint2007安装图文详解四：安装.NET Framework 3.0和SharePoint 2007&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SharePoint2007安装图文详解四：安装.NET Framework 3.0和SharePoint 2007</title><link>https://fwhyy.com/2011/01/installation-of-the-net-framework-3-0-and-sharepoint-2007/</link><pubDate>Tue, 11 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/installation-of-the-net-framework-3-0-and-sharepoint-2007/</guid><description>&lt;p&gt;终于到了SharePoint2007安装的最后一步了，.NET Framework 3.0在官网可以下载，不过需要连接到网络才可以安装，SharePoint2007我下载的是官网的半年试用版，但安装的时候居然要求输入序列号，随便搜了一个顺利通过，嘿嘿！下面是下载链接地址和序列号&lt;/p&gt;
&lt;p&gt;.NETFramework3.0：&lt;a href="http://www.microsoft.com/downloads/zh-cn/confirmation.aspx?familyId=10cc340b-f857-4a14-83f5-25634c3bf043&amp;amp;displayLang=zh-cn"&gt;http://www.microsoft.com/downloads/zh-cn/confirmation.aspx?familyId=10cc340b-f857-4a14-83f5-25634c3bf043&amp;amp;displayLang=zh-cn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SharePoint2007：&lt;a href="http://www.microsoft.com/downloads/zh-cn/confirmation.aspx?familyId=10cc340b-f857-4a14-83f5-25634c3bf043&amp;amp;displayLang=zh-cn"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyID=2e6e5a9c-ebf6-4f7f-8467-f4de6bd6b831&amp;amp;displayLang=zh-cn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;SharePoint 2007 序列号：F6YVR-4XY7K-RCVY4-37FBK-G44PY&lt;/p&gt;
&lt;p&gt;安装.NET Framework 3.0&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300714138.webp" alt="2011-01-08_215420" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;加载完后进入安装界面&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300715807.webp" alt="2011-01-08_215504" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以看到文件大小有39MB，需要连接网络下载，点击“安装”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300715905.webp" alt="2011-01-08_215730" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;等待下载完成&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300715941.webp" alt="2011-01-08_220523" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300715126.webp" alt="2011-01-08_220931" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;.NET Framework 3.0 已安装成功&lt;/p&gt;
&lt;h2 id="安装sharepoint-2007"&gt;安装SharePoint 2007&lt;/h2&gt;
&lt;p&gt;双击下载下来的exe文件
&lt;img src="https://img.fwhyy.com/2022/202201300715143.webp" alt="2011-01-09_001745" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300715762.webp" alt="2011-01-09_002829" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300715130.webp" alt="2011-01-09_002843" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;输入上面给出的序列号，点击“继续”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300716923.webp" alt="201101120951336913" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选中“我接受此协议的条款”，点击继续&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300716524.webp" alt="2011-01-09_002948" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“高级”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300716659.webp" alt="2011-01-09_003240" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;“服务器类型”选项卡中选中“完整…”，然后切换到“文件位置”选项卡&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300716328.webp" alt="2011-01-09_003313" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;文件位置可以选择你想放的目录，此处是使用默认位置，然后切换到“反馈”选项卡&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300716580.webp" alt="2011-01-09_003327" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;该处我选择的是“不参加”，点击“立即安装”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300716355.webp" alt="2011-01-09_003350" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;稍等片刻就安装完毕了&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300717282.webp" alt="2011-01-10_171910" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“关闭”会提示重启，重启电脑后SharePoint 2007 就成功安装了。&lt;/p&gt;
&lt;p&gt;安装仅仅只是一个开始，配置乃至跟多的内容请关注我的后面的文章吧&lt;/p&gt;
&lt;h2 id="相关文章"&gt;相关文章&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2011/01/iis-install/"&gt;SharePoint2007安装图文详解一：安装IIS及相关组件&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2011/01/installation-of-ad-and-dns/"&gt;SharePoint2007安装图文详解二：安装AD（活动目录）及DNS&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2011/01/install-sqlserver2005/"&gt;SharePoint2007安装图文详解三：安装SqlServer2005&lt;/a&gt;
SharePoint2007安装图文详解四：安装.NET Framework 3.0和SharePoint 2007&lt;/p&gt;</description></item><item><title>SharePoint2007安装图文详解一：IIS安装</title><link>https://fwhyy.com/2011/01/iis-install/</link><pubDate>Mon, 10 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/iis-install/</guid><description>&lt;p&gt;由于工作需要最近准备研究下SharePoint，SharePoint的最新版本为2010，但由于硬件环境所致我打算从2007开始学。首先准备详细介绍下SharePoint2007的安装过程。&lt;/p&gt;
&lt;p&gt;本次安装是在Windows2003 sp2的虚拟机上进行，安装SharePoint2007 先后分为以下几个步骤&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安装IIS等一些组件&lt;/li&gt;
&lt;li&gt;安装AD（活动目录）及DNS&lt;/li&gt;
&lt;li&gt;安装SqlServer2005&lt;/li&gt;
&lt;li&gt;安装.NET Framework 3.0&lt;/li&gt;
&lt;li&gt;安装SharePoint 2007&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于安装介绍大部分为图片，为了博文的访问速度我将上面的几个步骤分为4篇来介绍，本文只介绍安装IIS及一些相关组件。下面就正式开始安装了。&lt;/p&gt;
&lt;p&gt;现在假设我们已经在Virtual PC中安装好了Win2003 SP2，从控制面板中打开“添加或删除程序”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300703827.webp" alt="2011-01-09_014134" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在弹出窗口左侧选择“添加/删除Windows组件”来启动组件向导&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300703310.webp" alt="2011-01-09_014211" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在“Windows组件向导”窗口中选中“应用程序服务器”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300703687.webp" alt="2011-01-09_014929" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“详细信息”，在弹出窗口中选择如下图的选项&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300703615.webp" alt="2011-01-09_015116" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在上图中选中“Internet信息服务（IIS）”点击详细信息，选中下图中的红色框标识的选项&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300704962.webp" alt="2011-01-09_015414" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;将所选配置确定保存，然后点击下一步进行安装&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300704693.webp" alt="2011-01-09_015621" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;稍等几分钟，即可安装成功。如果在安装过程中弹出提示框提示插入光盘，将Win2003的系统盘插入光驱即可，如果不是用光盘安装的系统，那么在Virtual PC中CD菜单中选择安装的ISO文件即可。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300704410.webp" alt="2011-01-09_015951" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;至此IIS及一些相关组件已经安装好了。下面链接中的博文继续介绍后继的安装。&lt;/p&gt;
&lt;h2 id="相关文章"&gt;相关文章&lt;/h2&gt;
&lt;p&gt;SharePoint2007安装图文详解一：安装IIS及相关组件
&lt;a href="http://blog.fwhyy.com/2011/01/installation-of-ad-and-dns/"&gt;SharePoint2007安装图文详解二：安装AD（活动目录）及DNS&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2011/01/install-sqlserver2005/"&gt;SharePoint2007安装图文详解三：安装SqlServer2005&lt;/a&gt;
[SharePoint2007安装图文详解四：安装.NET Framework 3.0和SharePoint 2007](SharePoint2007安装图文详解四：安装.NET Framework 3.0和SharePoint 2007)&lt;/p&gt;</description></item><item><title>SharePoint2007安装图文详解二：安装AD（活动目录）及DNS</title><link>https://fwhyy.com/2011/01/installation-of-ad-and-dns/</link><pubDate>Mon, 10 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/installation-of-ad-and-dns/</guid><description>&lt;p&gt;在上一篇&lt;a href="http://blog.fwhyy.com/2011/01/iis-install/"&gt;SharePoint2007安装图文详解一&lt;/a&gt;：安装IIS及相关组件中已经介绍了IIS及相关组件的安装，本篇将详细介绍AD（活动目录）的安装。&lt;/p&gt;
&lt;p&gt;打开“管理您的服务器”，点击“添加或删除角色”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300710078.webp" alt="2011-01-09_114808" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“添加或删除角色”后弹出“配置你的服务器向导”对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300710969.webp" alt="2011-01-09_214602" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击下一步进入如下对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300710727.webp" alt="2011-01-09_215159" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;数秒后，进入到下面视图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300710662.webp" alt="2011-01-09_220636" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“域控制器”后点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300711867.webp" alt="2011-01-09_221344" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300711508.webp" alt="2011-01-09_222512" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;随之便出现下面的对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300711990.webp" alt="2011-01-09_222554" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300711554.webp" alt="201101110942371851" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;继续“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300711403.webp" alt="2011-01-09_222702" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“新域的域控制器”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300711674.webp" alt="2011-01-09_222835" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“在新林中的域”，点击下一步&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300712352.webp" alt="2011-01-09_222921" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;输入“新域的DNS全名”，如上图中我输入的fwhyy.com ， 点击下一步&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300712108.webp" alt="2011-01-09_223113" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图中的“域NetBIOS名”默认就好，一般不做修改，点击下一步&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300712290.webp" alt="2011-01-09_223228" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;AD数据库的保存路径保持默认就好，如果需要您可以修改为你想要存放的路径，然后点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300712760.webp" alt="2011-01-09_223350" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;SYSVOL文件夹的位置也不做修改，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713949.webp" alt="2011-01-09_223509" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;出现上图的窗口说明在安装AD前没有安装DNS，当然我们可以在之前先装好DNS再安装AD，此次安装中我选择的是选择上图对话框中的第二项，在安装AD的同时安装DNS。选择第二项后，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713948.webp" alt="2011-01-09_223815" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;选择“只与Windows 2000 或 Windows Server 2003 操作系统兼容的权限”，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713483.webp" alt="2011-01-09_225001" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;输入密码，点击“下一步”&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713240.webp" alt="2011-01-09_225034" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;继续“下一步”，就会开始安装了&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713152.webp" alt="2011-01-09_225123" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;稍等几分钟，就会出现安装成功的窗口，如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713343.webp" alt="2011-01-09_225700" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击完成会弹出重启电脑的确认框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300713258.webp" alt="2011-01-09_225755" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;重启动脑后会弹出下面对话框，提示此服务器已是域控制器&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300714657.webp" alt="2011-01-09_230726" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击“完成”就完成了AD和DNS的安装。&lt;/p&gt;
&lt;h2 id="相关文章"&gt;相关文章&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2011/01/iis-install/"&gt;SharePoint2007安装图文详解一：安装IIS及相关组件&lt;/a&gt;
SharePoint2007安装图文详解二：安装AD（活动目录）及DNS
&lt;a href="http://blog.fwhyy.com/2011/01/install-sqlserver2005/"&gt;SharePoint2007安装图文详解三：安装SqlServer2005&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2011/01/installation-of-the-net-framework-3-0-and-sharepoint-2007/"&gt;SharePoint2007安装图文详解四：安装.NET Framework 3.0和SharePoint 2007&lt;/a&gt;&lt;/p&gt;</description></item><item><title>插件和代码两种方法搞定WordPress回复邮件通知</title><link>https://fwhyy.com/2011/01/the-two-methods-get-the-wordpress-plugin-and-code-reply-email-notification/</link><pubDate>Fri, 07 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/the-two-methods-get-the-wordpress-plugin-and-code-reply-email-notification/</guid><description>&lt;p&gt;为了更好的互动，当有人在博客中评论时，我们肯定是希望能够马上知晓，WordPress中默认不提供这样的功能，需要通过插件或是添加代码的方式来实现。&lt;/p&gt;
&lt;h2 id="使用插件"&gt;使用插件&lt;/h2&gt;
&lt;p&gt;使用插件的方式非常简单，安装好插件在后台做相应的配置就好了。现在比较流行的插件是&lt;a href="http://wordpress.org/extend/plugins/wordpress-thread-comment/"&gt;WordPress Thread Comment&lt;/a&gt;，下面详细介绍下步骤&lt;/p&gt;
&lt;p&gt;1 下载解压后上传到plugin目录中。&lt;/p&gt;
&lt;p&gt;2 进入WordPress后台，在“设置”选项卡中点击讨论，在右边的界面中配置何时发送电子邮件。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302117565.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 进入到插件管理中，启用 &lt;a href="http://wordpress.org/extend/plugins/wordpress-thread-comment/"&gt;WordPress Thread Comment&lt;/a&gt; 插件。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302118052.webp" alt="2011-01-07_122446" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 启用插件后在“设置”下面会多出&lt;a href="http://wordpress.org/extend/plugins/wordpress-thread-comment/"&gt;WordPress Thread Comment&lt;/a&gt; 选项，点击该项在右边的界面中就可以进行相关设置。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302118810.webp" alt="2011-01-07_122651" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;使用代码&lt;/p&gt;
&lt;p&gt;使用代码的方式其实也并不复杂，代码可以很容易在网上找到。&lt;/p&gt;
&lt;p&gt;1 点击“外观”下的编辑。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302118932.webp" alt="2011-01-07_123309" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在右侧的文件列表中找到functions.php。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302119677.webp" alt="2011-01-07_123455" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 点击该文件，在中间的编辑区域添加如下代码。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/* 有评论时发送邮件 函数 开始*/
function comment_mail_notify($comment_id) {
 $admin_notify = &amp;#39;1&amp;#39;; // admin 要不要收回复通知 ( &amp;#39;1&amp;#39;=要 ; &amp;#39;0&amp;#39;=不要 )
 $admin_email = get_bloginfo (&amp;#39;admin_email&amp;#39;); // $admin_email 可改为你指定的 e-mail.
 $comment = get_comment($comment_id);
 $comment_author_email = trim($comment-&amp;gt;comment_author_email);
 $parent_id = $comment-&amp;gt;comment_parent ? $comment-&amp;gt;comment_parent : &amp;#39;&amp;#39;;
 global $wpdb;
 if ($wpdb-&amp;gt;query(&amp;#34;Describe {$wpdb-&amp;gt;comments} comment_mail_notify&amp;#34;) == &amp;#39;&amp;#39;)
 $wpdb-&amp;gt;query(&amp;#34;ALTER TABLE {$wpdb-&amp;gt;comments} ADD COLUMN comment_mail_notify TINYINT NOT NULL DEFAULT 0;&amp;#34;);
 if (($comment_author_email != $admin_email &amp;amp;&amp;amp; isset($_POST[&amp;#39;comment_mail_notify&amp;#39;])) || ($comment_author_email == $admin_email &amp;amp;&amp;amp; $admin_notify == &amp;#39;1&amp;#39;))
 $wpdb-&amp;gt;query(&amp;#34;UPDATE {$wpdb-&amp;gt;comments} SET comment_mail_notify=&amp;#39;1&amp;#39; WHERE comment_ID=&amp;#39;$comment_id&amp;#39;&amp;#34;);
 $notify = $parent_id ? get_comment($parent_id)-&amp;gt;comment_mail_notify : &amp;#39;0&amp;#39;;
 $spam_confirmed = $comment-&amp;gt;comment_approved;
 if ($parent_id != &amp;#39;&amp;#39; &amp;amp;&amp;amp; $spam_confirmed != &amp;#39;spam&amp;#39; &amp;amp;&amp;amp; $notify == &amp;#39;1&amp;#39;) {
 $wp_email = &amp;#39;no-reply@&amp;#39; . preg_replace(&amp;#39;#^www\.#&amp;#39;, &amp;#39;&amp;#39;, strtolower($_SERVER[&amp;#39;SERVER_NAME&amp;#39;])); // e-mail 发出点, no-reply 可改为可用的 e-mail.
 $to = trim(get_comment($parent_id)-&amp;gt;comment_author_email);
 $subject = &amp;#39;您在 [&amp;#39; . get_option(&amp;#34;blogname&amp;#34;) . &amp;#39;] 的留言有了回复&amp;#39;;
 $message = &amp;#39;
 &amp;lt;div style=&amp;#34;background-color:#eef2fa; border:1px solid #d8e3e8; color:#111; padding:0 15px; -moz-border-radius:5px; -webkit-border-radius:5px; -khtml-border-radius:5px;&amp;#34;&amp;gt;
 &amp;lt;p&amp;gt;&amp;#39; . trim(get_comment($parent_id)-&amp;gt;comment_author) . &amp;#39;, 您好!&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;您曾在《&amp;#39; . get_the_title($comment-&amp;gt;comment_post_ID) . &amp;#39;》的留言:&amp;lt;br /&amp;gt;&amp;#39;
 . trim(get_comment($parent_id)-&amp;gt;comment_content) . &amp;#39;&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;&amp;#39; . trim($comment-&amp;gt;comment_author) . &amp;#39; 给您的回复:&amp;lt;br /&amp;gt;&amp;#39;
 . trim($comment-&amp;gt;comment_content) . &amp;#39;&amp;lt;br /&amp;gt;&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;您可以点击&amp;lt;a href=&amp;#34;&amp;#39; . htmlspecialchars(get_comment_link($parent_id)) . &amp;#39;&amp;#34;&amp;gt;查看回复的完整內容&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;还要再度光临 &amp;lt;a href=&amp;#34;&amp;#39; . get_option(&amp;#39;home&amp;#39;) . &amp;#39;&amp;#34;&amp;gt;&amp;#39; . get_option(&amp;#39;blogname&amp;#39;) . &amp;#39;&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;
 &amp;lt;p&amp;gt;(此邮件由系统自动发送，请勿回复.)&amp;lt;/p&amp;gt;
 &amp;lt;/div&amp;gt;&amp;#39;;
 $from = &amp;#34;From: \&amp;#34;&amp;#34; . get_option(&amp;#39;blogname&amp;#39;) . &amp;#34;\&amp;#34; &amp;lt;$wp_email&amp;gt;&amp;#34;;
 $headers = &amp;#34;$from\nContent-Type: text/html; charset=&amp;#34; . get_option(&amp;#39;blog_charset&amp;#39;) . &amp;#34;\n&amp;#34;;
 wp_mail( $to, $subject, $message, $headers );
 //echo &amp;#39;mail to &amp;#39;, $to, &amp;#39;&amp;lt;br/&amp;gt; &amp;#39; , $subject, $message; // for testing
 }
}
add_action(&amp;#39;comment_post&amp;#39;, &amp;#39;comment_mail_notify&amp;#39;);

/* 自动加勾选栏 */
function add_checkbox() {
 echo &amp;#39;&amp;lt;input type=&amp;#34;checkbox&amp;#34; name=&amp;#34;comment_mail_notify&amp;#34; id=&amp;#34;comment_mail_notify&amp;#34; value=&amp;#34;comment_mail_notify&amp;#34; checked=&amp;#34;checked&amp;#34; style=&amp;#34;margin-left:20px;&amp;#34; /&amp;gt;&amp;lt;label for=&amp;#34;comment_mail_notify&amp;#34;&amp;gt;邮件通知&amp;lt;/label&amp;gt;&amp;#39;;
}
add_action(&amp;#39;comment_form&amp;#39;, &amp;#39;add_checkbox&amp;#39;);
/* 有评论时发送邮件 函数 结束*/
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="配置smtp"&gt;配置SMTP&lt;/h2&gt;
&lt;p&gt;光进行了上面的步骤可能还不行，还需要配置SMTP，装一个Configure SMTP的插件就可以很方便的进行配置，关于插件的安装启用上面已经说过。&lt;/p&gt;</description></item><item><title>回顾2010 计划2011</title><link>https://fwhyy.com/2011/01/back-in-the-2010-plan-2011/</link><pubDate>Wed, 05 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/back-in-the-2010-plan-2011/</guid><description>&lt;p&gt;2010年对于我来说是不平凡的一年。&lt;/p&gt;
&lt;p&gt;2010年我脱离了单身，找到了属于我的幸福。&lt;/p&gt;
&lt;p&gt;2010年我不远千里从武汉来到北京，一方面寻求事业上的发展，同时和小妹也算有个照应。&lt;/p&gt;
&lt;p&gt;2010年3月2号是个很特别的日子，就是在这一天我脱离了单身。也是在这一天我们相聚又别离了，我来了北京，&lt;a href="http://han.fwhyy.com/"&gt;她&lt;/a&gt;仍在武汉。1个月后我在北京西站接到了&lt;a href="http://han.fwhyy.com/"&gt;她&lt;/a&gt;，从此便开始了近一年的甜蜜蜗居生活。&lt;/p&gt;
&lt;p&gt;北京的工作相对于武汉来说有更多的机会，所以找工作还算比较顺利，两个星期的东奔西跑迎来了3份offer，再三思考权衡之下选择了工资不是最高但最有发展最能学习技术的公司留下了，也就是现在就职的公司。&lt;/p&gt;
&lt;p&gt;在公司的8个月的时间里也发生了不少事情，第一个项目的搁置、长达一个月时间的无事可做、换项目组、头的离职乃至公司内部的一些变动，尽管这些让人感觉有些动荡，但也学习到了很多，并且公司的一些制度还是非常人性化，弹性时间的上下班，平时有事请假可以算到日后调休等等。所以我还是很希望自己能在这里长期待下去。&lt;/p&gt;
&lt;p&gt;2010端午节&lt;a href="http://han.fwhyy.com/"&gt;老婆&lt;/a&gt;的姐弟来北京玩，短短几天的时间跑遍了很多地方，很累但很难忘。&lt;/p&gt;
&lt;p&gt;2010年国庆节我们为了一张回家的车票起很早去排队，最终还是不得不请了3天的假提前回家。这次是离开学校后离家最长的一次，所以回家的心情也格外激动。还有件更重要的事情就是十一要去老婆家上门，还好整个过程非常顺利。&lt;/p&gt;
&lt;p&gt;总体看来2010年还算是比较顺利，顺利让女友来北京；自己顺利找到工作；幸运的找到现在所租的房子；国庆顺利的上门，年底顺利的买空间域名搭建我和老婆的小窝。希望在2011年各方面能做的更好。&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;2011年对我来说是充满期待的一年。
2011年我将会走进婚姻的殿堂，延续我的幸福。&lt;/p&gt;
&lt;p&gt;2011年我也许会从北京回到武汉，找个稳定的工作，过上稳定的生活，当然仅仅是也许。&lt;/p&gt;
&lt;p&gt;2010年很多事看上去很顺，但缺少规划，一切都是按部就班，顺其自然的在进行，这个主要是指技术学习方面。所以2011年在技术学习上要有计划，基本要按照计划来执行，比如学习一门动态语言Python，学习一门函数式语言F#等。&lt;/p&gt;
&lt;p&gt;2011年应该是很忙碌的一年，春节后可能面临着工作的变动，五六月份要和老婆去照结婚照，10月举行婚礼，希望这些都能顺顺利利。&lt;/p&gt;
&lt;p&gt;2011年对于技术的学习，大致规划如下，具体可能根据实际情况做相应调整。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;学习Python&lt;/li&gt;
&lt;li&gt;学习F#&lt;/li&gt;
&lt;li&gt;关注软件架构方面研究（涉及设计模式、并发、性能等）&lt;/li&gt;
&lt;li&gt;根据需要学习DotNet相关的框架&lt;/li&gt;
&lt;li&gt;所买的书争取看完，关键是要吃透&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;写于2011年1月5日 北京天通苑&lt;/p&gt;</description></item><item><title>用WordPress搭建个人博客小记</title><link>https://fwhyy.com/2011/01/build-personal-blog-using-wordpress/</link><pubDate>Tue, 04 Jan 2011 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2011/01/build-personal-blog-using-wordpress/</guid><description>&lt;p&gt;最近用WordPress搭建了一个个人博客，将这几年在博客园、CSDN、新浪上的一些博文都搬到了新的博客中。以后不管是技术还是非技术的文章都将发布在新的博客中。下面简单说下这次搭建个人博客的经历。&lt;/p&gt;
&lt;h2 id="域名"&gt;域名&lt;/h2&gt;
&lt;p&gt;08年的时候就申请过一个域名www.oec2003.cn，但一直没有看到性价比比较好的空间，所以该域名一直处于闲置中。去年圣诞节前夕，看到易网库做活动空间打75折，因为之前免费试用过他们的空间，感觉还不错，所以就花180买了“普及I型 (香港空间)”。空间买好了，想着将之前的域名和空间绑定上就ok了。oec2003.cn的域名是在万网申请的，到万网的管理后台做域名解析时才知道cn的域名需要提交资料验证。验证通过的域名还需要备案，心想备案就备案吧，但提供的备案的网站居然还打不开，无奈之下到godaddy重新申请了一个域名，也就是现在用的域名，我和老婆名字的缩写组合-&lt;a href="www.fwhyy.com"&gt;www.fwhyy.com&lt;/a&gt;。 在godaddy进行域名解析比我想象的要快很多，不到一个小时就解析成功了，最主要的是省事，没有在国内的那些繁琐的程序。&lt;/p&gt;
&lt;h2 id="空间"&gt;空间&lt;/h2&gt;
&lt;p&gt;上面已经提到空间是在易网库买的“普及I型 (香港空间)”。对于我的个人博客来说是够用了，下面分别说下优缺点&lt;/p&gt;
&lt;h3 id="优点"&gt;优点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;性价比还可以&lt;/li&gt;
&lt;li&gt;Net的版本支持比较全，从1.1到4都支持&lt;/li&gt;
&lt;li&gt;除了空间还外带了一个100MB的MySql的数据库&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="缺点"&gt;缺点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;不自带SqlServer的数据库&lt;/li&gt;
&lt;li&gt;自带的MySql数据库只支持1个使用配额，所以给老婆弄的博客又花了100买了数据库&lt;/li&gt;
&lt;li&gt;每个月的流量有限制，不过10G的流量对我这刚办的新站应该也用不完&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;总体来说还是比较满意，因为有流量的限制，如果以后访问量大了就得考虑升级或是换地方了。&lt;/p&gt;
&lt;h2 id="博客系统"&gt;博客系统&lt;/h2&gt;
&lt;p&gt;因为我是做Net开发的，所以在选择博客系统时我首先考虑的是Net平台下的博客系统，Net平台下的博客系统比较出名的就是&lt;a href="http://blogengine.codeplex.com/"&gt;BlogEngine.Net&lt;/a&gt;，国内有朋友进行了本地化，可以访问这里下载。下载了一份发布的代码和一份源码，将发布代码上传到服务器，运行中出现了一些问题，但很容易排查，很短的时间就搞定。但是将下载的源码编译后发布的程序上传服务器就会报错，查了很多资料也没能解决，最后在朋友的推荐下还是选择了WordPress。WordPress很强大，后台易用有丰富的插件和主题。目前使用的主题&lt;a href="http://www.aquoid.com/news/themes/suffusion/"&gt;Suffusion&lt;/a&gt;也是超级的强大，而且对SEO也有很强力的支持。&lt;/p&gt;
&lt;h2 id="搬迁文章"&gt;搬迁文章&lt;/h2&gt;
&lt;p&gt;WordPress有Rss导入的插件，这样很省事，不过后来发现用Rss导入的文章不是很完整。所以花了几天的时间将原来的文章一篇一篇的加入到现在的博客中，尽管方法很蠢也很耗时，不过我可以检查到文章中的错误及时进行修改，也适当的修改了一些文章的标题。Suffusion主题支持在发布文章时加入KeyWord和Description meta，我在添加每一篇文章时也适当加入了这两项。WordPress中有代码高亮的插件，不过我没有用，因为我习惯使用Live Writer写文章，所以使用的Live Writer中代码高亮的插件。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;弄一个自己的博客总是开心的，以后不管是技术上的总结还是生活中的感悟我都会记录在这里，2011，这里将是我的主战场。&lt;/p&gt;
&lt;p&gt;PS：也欢迎访问&lt;a href="http://han.fwhyy.com/"&gt;我老婆的博客&lt;/a&gt;&lt;/p&gt;</description></item><item><title>jQuery boxy插件弹出框的四个边角图片在IE中不显示问题的解决</title><link>https://fwhyy.com/2010/12/jquery-boxy-plug-in-pop-up-the-four-edges-of-images-in-ie-dont-show/</link><pubDate>Thu, 09 Dec 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/12/jquery-boxy-plug-in-pop-up-the-four-edges-of-images-in-ie-dont-show/</guid><description>&lt;p&gt;jQuery boxy插件很好用，但也会出现一些问题，比如弹出框的边角在IE中不能显示。本博文将来解决这个问题。将boxy插件引用到项目中后会有一个boxy.css文件和jquery.boxy.js文件。在boxy.css文件中有给弹出框设置四个角图片的样式，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300719946.webp" alt="2010-12-08_232652" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;不做任何修改在Chrome浏览器下没有问题，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300719056.webp" alt="2010-12-08_234216" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在网上查了一些资料，说将css文件中的图片路径给位全路径可以解决问题，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300719018.webp" alt="2010-12-08_234934" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;发现这样修改后并没有作用，运行后效果仍然如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300720107.webp" alt="2010-12-08_235049" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;有效的解决方法&lt;/p&gt;
&lt;p&gt;将上面css截图的下半部分注释掉，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2010/2010-12-08_235357.webp" alt="2010-12-08_235357" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;然后在jquery.boxy.js文件中的Boxy函数中添加一段脚本，下面贴出修改后的Boxy函数代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;function Boxy(element, options) {

 this.boxy = jQuery(Boxy.WRAPPER);
 jQuery.data(this.boxy[0], &amp;#39;boxy&amp;#39;, this);

 this.visible = false;
 this.options = jQuery.extend({}, Boxy.DEFAULTS, options || {});

 if (this.options.modal) {
 this.options = jQuery.extend(this.options, {center: true, draggable: false});
 }

 // options.actuator == DOM element that opened this boxy
 // association will be automatically deleted when this boxy is remove()d
 if (this.options.actuator) {
 jQuery.data(this.options.actuator, &amp;#39;active.boxy&amp;#39;, this);
 }

 this.setContent(element || &amp;#34;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;&amp;#34;);
 this._setupTitleBar();

 this.boxy.css(&amp;#39;display&amp;#39;, &amp;#39;none&amp;#39;).appendTo(document.body);
 this.toTop();

 if (this.options.fixed) {
 if (jQuery.browser.msie &amp;amp;&amp;amp; jQuery.browser.version &amp;lt; 7) {
 this.options.fixed = false; // IE6 doesn&amp;#39;t support fixed positioning
 } else {
 this.boxy.addClass(&amp;#39;fixed&amp;#39;);
 }
 }

 if (this.options.center &amp;amp;&amp;amp; Boxy._u(this.options.x, this.options.y)) {
 this.center();
 } else {
 this.moveTo(
 Boxy._u(this.options.x) ? this.options.x : Boxy.DEFAULT_X,
 Boxy._u(this.options.y) ? this.options.y : Boxy.DEFAULT_Y
 );
 }

 //fengwei add 2010-11-28
 //用于解决弹出框的圆角在ie中的显示问题
 if ($.browser.msie) {
 var setFilter = function(cls) {
 var obj = $(cls), ret = obj.css(&amp;#34;background-image&amp;#34;).match(/url\(\&amp;#34;(.+)\&amp;#34;\)/);
 if (ret == null || ret.length &amp;lt; 1) return;
 obj.css({
 &amp;#34;background&amp;#34;: &amp;#34;none&amp;#34;, &amp;#34;filter&amp;#34;: &amp;#34;alpha(opacity=0)&amp;#34;,
 &amp;#34;filter&amp;#34;: &amp;#34;progid:DXImageTransform.Microsoft.
 AlphaImageLoader(src=&amp;#39;&amp;#34; + ret[1] + &amp;#34;&amp;#39;)&amp;#34;
 });
 };

 setFilter(&amp;#34;.top-left&amp;#34;);
 setFilter(&amp;#34;.top-right&amp;#34;);
 setFilter(&amp;#34;.bottom-left&amp;#34;);
 setFilter(&amp;#34;.bottom-right&amp;#34;);
 }
 if (this.options.show) this.show();
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;修改好css和js文件后，再次运行程序，在IE6,7,8中均能正常弹出带边角的框了。&lt;/p&gt;</description></item><item><title>jQuery boxy插件的确认框在AspNet中的应用</title><link>https://fwhyy.com/2010/11/use-jquery-boxy-plug-in-confirmation-box-in-the-aspnet/</link><pubDate>Sat, 20 Nov 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/11/use-jquery-boxy-plug-in-confirmation-box-in-the-aspnet/</guid><description>&lt;p&gt;jQuery有不少弹出框的插件，boxy应该算的上是功能和效果都还不错的一款了。先来看一张效果图吧。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290715574.webp" alt="2010-11-20_134247" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在Web开发中经常会使用到Alert和Confirm弹出框，在Asp.Net中的删除按钮上我们常常会加上删除的确认提示，以避免误删除数据，就像上面图片那样。我们一般会写出这样的代码。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html xmlns=&amp;#34;http://www.w3.org/1999/xhtml&amp;#34; &amp;gt;
&amp;lt;head runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function confirmDel() {
 return confirm(&amp;#34;您确认要删除吗？&amp;#34;);
 }
 &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;form id=&amp;#34;form1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;asp:Button ID=&amp;#34;btnDel&amp;#34; runat=&amp;#34;server&amp;#34; 
 OnClientClick=&amp;#34;return confirmDel();&amp;#34; Text=&amp;#34;删除&amp;#34; /&amp;gt;
 &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码很简单，confirm弹出框会有两个按钮，点击确定返回true，点击取消返回false。在boxy插件中也有confirm方法，调用代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$(document).ready(function() {
 $(&amp;#34;#btnDel&amp;#34;).click(function() {
 Boxy.confirm(&amp;#34;您确认要删除吗？&amp;#34;, function() { }, null);
 return false;
 });
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Boxy的confirm方法有三个参数分别是确认信息内容，弹出框点击确定的回调函数，一些设置项比如标题。上面的代码中如果不加上return false，那么弹出框会闪现，然后删除按钮的后天事件还是执行了。加上return false，那么不管是点击确定还是取消都不会执行后台事件，这显然达不到我们的要求，看来只能打点击确定后的回调函数的主意了。可以在一个公用的js文件中将Boxy的confirm封装一下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290716976.webp" alt="2010-11-20_140830" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;页面的调用代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$(document).ready(function() {
 $(&amp;#34;#Button1&amp;#34;).click(function() { return confirmO(this, &amp;#34;您确认删除吗？&amp;#34;) });

});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;经过这样修改后，但点击弹出框的确定按钮时就会执行服务器事件了。&lt;/p&gt;</description></item><item><title>给PDF文档添加书签</title><link>https://fwhyy.com/2010/11/add-a-bookmark-to-a-pdf-document/</link><pubDate>Sat, 20 Nov 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/11/add-a-bookmark-to-a-pdf-document/</guid><description>&lt;p&gt;我们在阅读纸质的书时，一般都会使用书签来标识看到什么地方以便下次看时可以方便的找到。如果是在电脑上阅读PDF文档，我们同样希望能够给PDF文档做些标记，不过默认情况下PDF是不支持标记的。下面就来介绍一种方法可以在PDF文档中添加书签。&lt;/p&gt;</description></item><item><title>C#:友元程序集</title><link>https://fwhyy.com/2010/11/csharp-a-friend-assembly/</link><pubDate>Mon, 15 Nov 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/11/csharp-a-friend-assembly/</guid><description>&lt;p&gt;C#中的访问修饰符Internal可以说是介于Public和Private之间，可以使类型在同程序集中可以被互相访问。但有时会有这样的需求，我们希望一个程序集中的类型可以被外部的某些程序集可以访问，这时当然不能设置成Public，否则可以被所有的外部程序集访问。要达到上述要求我们可以使用友元程序集。&lt;/p&gt;
&lt;p&gt;下面用一个简单的例子来介绍下友元程序集。&lt;/p&gt;
&lt;p&gt;1 在一个解决方案中创建两个类库项目TestA和TestB，分别在两个类库项目中创建类A和类B。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290807599.webp" alt="2010-11-14_175103" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在项目TestA中添加对项目TestB的引用。&lt;/p&gt;
&lt;p&gt;3 将项目TestB中的类B访问级别设置为Internal。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace TestB
{
 internal class B
 {

 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 现在在TestA项目的类A中是肯定不能访问到类B的，如果想让类A可以访问类B，必须将项目TestA的程序集添加为项目TestB程序集的友元程序集。添加友元程序集我们要使用InternalIsVisibleTo特性，使用该特性需要添加命名空间&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System.Runtime.CompilerServices。
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 在B类中使用InternalIsVisibleTo特性将程序集TestA添加为友元程序集。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo(&amp;#34;TestA&amp;#34;)]
namespace TestB
{
 internal class B
 {

 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;6 InternalIsVisibleTo特性也可以添加到AssemblyInfo.cs中。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290808640.webp" alt="2010-11-14_181114" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;7 现在在项目TestA的类A中就可以访问TestB项目的类B了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290808258.webp" alt="2010-11-14_181324" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>让 ASP.NET Menu 控件在 Google Chrome 浏览器上正常运行</title><link>https://fwhyy.com/2010/11/let-the-aspnet-menu-controls-on-the-google-chrome-browser-run-normally/</link><pubDate>Thu, 11 Nov 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/11/let-the-aspnet-menu-controls-on-the-google-chrome-browser-run-normally/</guid><description>&lt;p&gt;最近在帮朋友做一管理系统，里面用到了Asp.Net的Menu控件，由于我的Chrome浏览器为默认，运行后发现二级菜单不能正常出来，网上查到解决方法是在项目中创建一个Others.browser文件，文件代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;browsers&amp;gt;
 &amp;lt;browser id=&amp;#34;Safari3&amp;#34; parentID=&amp;#34;Safari1Plus&amp;#34;&amp;gt;
 &amp;lt;identification&amp;gt;
 &amp;lt;userAgent match=&amp;#34;Safari/\d+\.\d+&amp;#34; /&amp;gt;
 &amp;lt;/identification&amp;gt;
 &amp;lt;capture&amp;gt;
 &amp;lt;userAgent match=&amp;#34;Version/(?&amp;#39;version&amp;#39;\d+\.\d+)&amp;#34; /&amp;gt;
 &amp;lt;/capture&amp;gt;
 &amp;lt;capabilities&amp;gt;
 &amp;lt;capability name=&amp;#34;browser&amp;#34; value=&amp;#34;Safari3&amp;#34; /&amp;gt;
 &amp;lt;capability name=&amp;#34;version&amp;#34; value=&amp;#34;${version}&amp;#34; /&amp;gt;
 &amp;lt;/capabilities&amp;gt;
 &amp;lt;controlAdapters&amp;gt;
 &amp;lt;adapter controlType=&amp;#34;System.Web.UI.WebControls.Menu&amp;#34;
 adapterType=&amp;#34;&amp;#34; /&amp;gt;
 &amp;lt;/controlAdapters&amp;gt;
 &amp;lt;/browser&amp;gt;
 &amp;lt;browser id=&amp;#34;GoogleChrome&amp;#34; parentID=&amp;#34;Safari3&amp;#34;&amp;gt;
 &amp;lt;identification&amp;gt;
 &amp;lt;userAgent match=&amp;#34;Chrome/(?&amp;#39;version&amp;#39;\d+\.\d+)&amp;#34; /&amp;gt;
 &amp;lt;/identification&amp;gt;
 &amp;lt;capabilities&amp;gt;
 &amp;lt;capability name=&amp;#34;browser&amp;#34; value=&amp;#34;Googlebot&amp;#34; /&amp;gt;
 &amp;lt;/capabilities&amp;gt;
 &amp;lt;/browser&amp;gt;
&amp;lt;/browsers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>C#/Net代码精简优化技巧（3）</title><link>https://fwhyy.com/2010/11/csharp-net-code-concise-optimization-techniques-c/</link><pubDate>Wed, 10 Nov 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/11/csharp-net-code-concise-optimization-techniques-c/</guid><description>&lt;p&gt;前面两篇中已经介绍了10个小技巧，本篇是本次系列的最后一篇，将再介绍5个。这些小技巧看着并不起眼，有些您可能知道，但在平时的开发中可能由于惯性并没有去使用。所以建议大家掌握并去使用这些小技巧，他们将使我们的代码变得更简洁和易于维护。&lt;/p&gt;
&lt;h2 id="隐式类型"&gt;隐式类型&lt;/h2&gt;
&lt;p&gt;首先了解一下概念，隐式类型并不是动态类型，隐式类型是用关键字var来定义，var定义的类型仍然是强类型。&lt;/p&gt;
&lt;p&gt;很多人认为使用隐式类型是懒惰的表现，刚开始我也是这么认为的，但是想想我使用STL中迭代指针的开发经理，我就明白了。看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;for (list&amp;lt;int&amp;gt;::const_iterator it = myList.begin(); it != myList.end(); ++it)
{
 // ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;很多时候我们会写出下面这样的代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;// pretty obvious
ActiveOrdersDataAccessObject obj = new ActiveOrdersDataAccessObject();

// still obvious but even more typing
Dictionary&amp;lt;string,List&amp;lt;Product&amp;gt;&amp;gt; productsByCategory =
 new Dictionary&amp;lt;string,List&amp;lt;Product&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码的类型定义很明显，是什么类型就用什么类型来定义，下面尝试用var关键字来定义&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;// nicer!
var obj = new ActiveOrdersDataAccessObject();
// Ah, so much nicer!
var productsByCategory = new Dictionary&amp;lt;string,List&amp;lt;Product&amp;gt;&amp;gt;();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;用var关键字后代码变得简洁多了，编译器会在编译时去推断是什么类型，var关键字只相当于是一个占位符。&lt;/p&gt;
&lt;p&gt;而且使用var关键字在我们使用泛型或是Linq表达式时会提供更好的可读性，比较下面两行代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;// 隐式类型
var results1 = from p in products where p.Value &amp;gt; 100 group p by p.Category;

// 显示类型
IEnumerable&amp;lt;IGrouping&amp;lt;string, Product&amp;gt;&amp;gt; results2 =
 from p in products where p.Value &amp;gt; 100 group p by p.Category;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="linq-扩展方法"&gt;Linq 扩展方法&lt;/h2&gt;
&lt;p&gt;在以前的编码中，很多时候我们需要去写一些自己的函数库，如排序、分组、查找或是其他的一些算法。并且我们要花很多的时间来为这些函数写单元测试，很多时候困扰我们的一些bug正是在这些方法中出现的。&lt;/p&gt;
&lt;p&gt;随着Linq扩展方法的推出，你可以使用现成的这些标准的算法，而不需要自己再去写一遍，提供了极大的方便。需要排序可以使用OrderBy()，当需要查询条件时可以使用Where()，当需要选择一些类的属性时可以使用Select()，当需要分组查询时可以使用GroupBy()，这些Linq中的扩展方法经过了全面的测试，不需要我们来为他写单元测试代码，也不会出现让人困扰的bug。&lt;/p&gt;
&lt;p&gt;看下面的例子，假设有一个集合List&lt;Product&gt;，集合里装载的是Product对象，Product有Value和Category两个属性，现在要按类别来查找Value值大于$100的数据，以前我们可能会像下面这样写&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var results = new Dictionary&amp;lt;string, List&amp;lt;Product&amp;gt;&amp;gt;();

foreach (var p in products)
{
 if (p.Value &amp;gt; 100)
 {
 List&amp;lt;Product&amp;gt; productsByGroup;
 if (!results.TryGetValue(p.Category, out productsByGroup))
 {
 productsByGroup = new List&amp;lt;Product&amp;gt;();
 results.Add(p.Category, productsByGroup);
 }

 productsByGroup.Add(p);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用Linq扩展方法&lt;/p&gt;</description></item><item><title>软件推荐：磁盘搜索软件Everything</title><link>https://fwhyy.com/2010/11/disk-search-software-everything/</link><pubDate>Wed, 03 Nov 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/11/disk-search-software-everything/</guid><description>&lt;p&gt;前几天在微博上见有人推荐Everything，立即下载试用感觉挺不错，他的速度让我震惊了。&lt;/p&gt;
&lt;p&gt;官网：&lt;a href="http://www.voidtools.com/"&gt;http://www.voidtools.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;运行后界面&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281845926.webp" alt="2010-12-30_215838" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;感兴趣的朋友就下载试用吧！&lt;/p&gt;</description></item><item><title>香山游</title><link>https://fwhyy.com/2010/10/travel-to-xiangshan/</link><pubDate>Fri, 29 Oct 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/10/travel-to-xiangshan/</guid><description>&lt;p&gt;香山以红叶而闻名，很早就有带老婆去玩玩的打算。10月23日恰逢香山红叶节的第一个周六，在香山公园的官网上得知叶红面积已达到40%以上，所以就决定在周六和老婆一起去香山。&lt;/p&gt;
&lt;p&gt;去之前就预料到了人肯定会非常多，想要避开人流高峰要么早出门要么就晚出门。最终商讨决定晚出门。&lt;/p&gt;
&lt;p&gt;8点多钟起床，收拾好吃完早饭到地铁已经9点多了，按照事先查好路线在地铁4号线的北宫门换乘公交，地铁还比较顺利，但从北宫门到香山用了很长时间，其实也没几站。下车后已经11点多了。老婆说肚子饿了，于是就找了个小馆子解决了中午饭。&lt;/p&gt;
&lt;p&gt;20块买了两张门票，我们就进了香山公园了，一路上人非常多，不愧是在搞什么红叶节。因为人多，海拔才500多米的香山爬了1个多小时才到山顶。一路上也没看到什么红叶，这与香山官网上的40%不相符，也证实了网上一些宣传性的话语可信度太低了。下山是另外一条路，在下山的路上看见稀稀落落有一些红叶，尽管如此，我和老婆也不放过机会，沿着小路到红叶多的地方猛照一番。&lt;/p&gt;
&lt;p&gt;下山感觉比上山要快很多，可能跟心情也有关系吧。出了香山公园，老婆感觉很累，对于缺乏锻炼的她来说也很正常啦。为了能够有座，我们特地绕到西直门去坐13号线的首发，等了一辆车，如愿的坐上了，一觉睡到了立水桥。顺利换乘5号到达天通苑后在路边吃了很多路边摊后回家了。&lt;/p&gt;
&lt;p&gt;流水账终于记完，由于工作很忙，耽搁了几天才记完看，也不容易。红叶确实有点让人失望，不过能够跟老婆在一起就算是绿叶也很开心啊。&lt;/p&gt;</description></item><item><title>C#/Net代码精简优化技巧（2）</title><link>https://fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-2/</link><pubDate>Tue, 26 Oct 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-2/</guid><description>&lt;p&gt;在&lt;a href="http://blog.fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-1/"&gt;C#/Net代码精简优化技巧（1）&lt;/a&gt;中已经介绍了5个小技巧，本篇将再介绍5个。&lt;/p&gt;
&lt;h2 id="stringisnullorempty-and-stringisnullorwhitespace"&gt;string.IsNullOrEmpty() and string.IsNullOrWhiteSpace()&lt;/h2&gt;
&lt;p&gt;在Net2.0中String类型有一个静态方法IsNullOrEmpty，到了Net4.0中String类又增加了一个新的静态方法IsNullOrWhiteSpace。这两个方法看名称也可以知道IsNullOrEmpty是判断空引用和空字符串，而IsNullOrWhiteSpace是判断空引用和字符串中的每一个字符是否是空格。&lt;/p&gt;
&lt;p&gt;在有这两个方法之前，我们要进行这样的判断，需要些如下代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetFileName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fullPathFileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullPathFileName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;fullPathFileName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullPathFileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;使用IsNullOrEmpty&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;span class="lnt"&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetFileName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;fullPathFileName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullPathFileName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fullPathFileName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;下面又了新的需求，需要将三个名字连接在一起，并且希望中间名字不为空字符串和不出现多余的空格，我们会写出下面的代码&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetFullName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;middleName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;middleName&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;middleName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{0} {1}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{0} {1} {2}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middleName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面的代码中使用了Trim来去掉空格然后判断其长度是否为0，代码也非常的清晰简洁，但是会产生额外的String对象以至于影响性能，这时就应该使用Net4.0中的IsNullOrWhiteSpace方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;GetFullName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;middleName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;middleName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{0} {1}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;{0} {1} {2}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;middleName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面的代码非常简洁，而且也不用担心会产生额外的String对象没有及时的进行垃圾回收而影响性能。&lt;/p&gt;
&lt;h2 id="stringequals"&gt;string.Equals()&lt;/h2&gt;
&lt;p&gt;string.Equals方法有很多的重载供我们使用，但是其中有些常常会被我们忽视掉。通常我们比较字符串会使用下面的方法&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;orderType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;double&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;equity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果orderType为null会抛出NullReferenceException异常，所以为了不抛出异常，在判断之前先要进行null的判断，如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderType&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;orderType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;equity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;相当于每次都要做两次判断，很麻烦而且有时还有可能遗忘，如果使用string.Equals就可以解决这个问题，代码如下：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Equals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;equity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面的代码当orderType为null时不会抛出异常而是直接返回false。&lt;/p&gt;</description></item><item><title>C#/Net代码精简优化技巧（1）</title><link>https://fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-1/</link><pubDate>Thu, 21 Oct 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/10/csharp-net-code-concise-optimization-techniques-1/</guid><description>&lt;p&gt;在我们写代码的时候可以使用一些小的技巧来使代码变得更加简洁，易于维护和高效。下面介绍几种在C#/Net中非常有用的一些编程技巧。&lt;/p&gt;
&lt;h2 id="空操作符"&gt;空操作符（??）&lt;/h2&gt;
&lt;p&gt;在程序中经常会遇到对字符串或是对象判断null的操作，如果为null则给空值或是一个指定的值。通常我们会这样来处理&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;string name = value;
if (name == null)
{
 name = string.Empty;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以使用三元操作符（?:）对上面对吗进行优化&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;string name = value == null ? string.Empty : value;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这样使代码简洁了不少，但这还不是最简洁的，我们还可以使用??操作符来进行进一步优化，??操作符意思是如果为null取操作符左边的值，否则取右边的值。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;string name = value ?? string.Empty;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我们甚至可以写一个扩展方法来过滤掉null和空格，使返回的结果可以更好的使用??操作符&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public static class StringUtility
{
 public static string TrimToNull(string source)
 {
 return string.IsNullOrWhiteSpace(source) ? null : source.Trim();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;string name = string.TrimToNull(value) ?? &amp;#34;None Specified&amp;#34;;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="使用as转换类型"&gt;使用As转换类型&lt;/h2&gt;
&lt;p&gt;在C#中进行类型转换有很多种方式比如可以进行强制类型转换，通常在转换前会使用Is进行类型的判断，所以您可能经常写过或见过类似下面的代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if (employee is SalariedEmployee)
{
 var salEmp = (SalariedEmployee)employee;
 pay = salEmp.WeeklySalary;
 // ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码不会报异常，但在整个过程中做了两次转换操作，这样会降低性能。我们可以使用as操作符来进行类型的转换，同样也不会报异常，如果类型不兼容则返回null，而是用as进行转换整个过程只转换一次。代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var salEmployee = employee as SalariedEmployee;
if (salEmployee != null)
{
 pay = salEmployee.WeeklySalary;
 // ...
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="自动属性"&gt;自动属性&lt;/h2&gt;
&lt;p&gt;自动属性是C#3.0以上版本中的新功能，可以使代码变得更简洁，在以前定义属性我们会写如下代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Point
{
 private int _x, _y;

 public int X
 {
 get { return _x; }
 set { _x = value; }
 }
 public int Y
 {
 get { return _y; }
 set { _y = value; }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用自动属性代码就会简洁了很多&lt;/p&gt;</description></item><item><title>2010十一长假小记</title><link>https://fwhyy.com/2010/10/2010-national-day-reporter/</link><pubDate>Sun, 10 Oct 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/10/2010-national-day-reporter/</guid><description>&lt;p&gt;今年的十一假特别长，因为没买到火车票的缘故导致放了11天的假。&lt;/p&gt;
&lt;h2 id="927"&gt;927&lt;/h2&gt;
&lt;p&gt;紧张的忙碌完工作后，下午准时下班在三元桥地铁站和老婆会合，直奔北京西站。&lt;/p&gt;</description></item><item><title>Virtual PC附加程序安装</title><link>https://fwhyy.com/2010/09/additional-program-installed-virtual-pc/</link><pubDate>Thu, 23 Sep 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/09/additional-program-installed-virtual-pc/</guid><description>&lt;p&gt;在Virtual PC中安装好了虚机后，要想让虚拟机能够和物理机实现文件共享就必须安装附加程序。下面介绍附加程序的安装方法。&lt;/p&gt;</description></item><item><title>桌面便签软件PNotes</title><link>https://fwhyy.com/2010/09/desktop-pnotes-note-software/</link><pubDate>Mon, 06 Sep 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/09/desktop-pnotes-note-software/</guid><description>&lt;p&gt;做软件开发在平时的工作中经常会有一些东西需要备忘，如果光用脑袋来记的话很容易忘记，毕竟人脑不是电脑。写在纸上比较麻烦也不便于保存和查询。所以一款桌面的便签工具是很有必要的，在网上搜了一下此类的软件有不少，经过对比我选择了PNotes进行试用，感觉还不错。&lt;/p&gt;
&lt;p&gt;PNotes官网：&lt;a href="http://pnotes.sourceforge.net/"&gt;http://pnotes.sourceforge.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;PNotes下载：&lt;a href="http://pnotes.sourceforge.net/index.php?page=5"&gt;http://pnotes.sourceforge.net/index.php?page=5&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;安装完成运行PNotes后会在右下角出现一个小图标&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2010/2010-12-30_222647.webp" alt="2010-12-30_222647" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;双击该图标就会在桌面上出现一个便签，黄底黑字的&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281846632.webp" alt="2010-12-30_222723" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在里面填写内容后，按Ctrl+S就可以保存便签了，在这之前需要在弹出的提示框中输入名称。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281846586.webp" alt="2010-12-30_222755" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;便签的右上方有两个小按钮“向下的箭头”和“叉”，前者是隐藏当前便签，后者为将便笺删除到回收站中。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281846786.webp" alt="2010-12-30_222825" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;当隐藏了当前便签后，再次单击任务栏的小图标，并不会让隐藏的出现。任务栏的小图标每一次点击都会在桌面创建一个新的便签。如果想看以前隐藏的便签，右击任务栏小图标选择管理器…&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281846135.webp" alt="2010-12-30_222908" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;管理器的功能很强大，可以对便签进行分组、修改、查找等操作。&lt;/p&gt;
&lt;p&gt;PNotes的功能还是比较强大的，目前只用到一些基本功能，感觉挺好 。&lt;/p&gt;</description></item><item><title>推荐两款富文本编辑器：NicEdit和Kindeditor</title><link>https://fwhyy.com/2010/09/nicedit-and-kindeditor/</link><pubDate>Sun, 05 Sep 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/09/nicedit-and-kindeditor/</guid><description>&lt;p&gt;做过Web开发的朋友相信都使用过富文本编辑器，比较出名的&lt;a href="http://cuteeditor.51aspx.com/"&gt;CuteEditor&lt;/a&gt;和&lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;很多人应该已经使用过，在功能强大的同时需要加载的东西也变得很多。下面要推荐的两款富文本编辑器都是使用JS编写，使用简单，非常轻量级。&lt;/p&gt;
&lt;h2 id="niceditor"&gt;NicEditor&lt;/h2&gt;
&lt;p&gt;NicEdit是一个轻量级，跨平台的Inline Content Editor。NicEdit能够让任何 element/div变成可编辑或者能够把标准的TextArea转换成富文本编辑器。&lt;/p&gt;
&lt;p&gt;主页:&lt;a href="http://nicedit.com/"&gt;http://nicedit.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载:&lt;a href="http://nicedit.com/download.php"&gt;http://nicedit.com/download.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;示例:&lt;a href="http://nicedit.com/demos.php"&gt;http://nicedit.com/demos.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;NicEdit是我见过最轻量级的富文本编辑器，总共就一个JS文件和一张图片&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301603918.webp" alt="2010-09-05_102850" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;使用也非常简单，只需在页面中添加简单的JS代码就可以将TextBox或是TextArea控件转换成富文本编辑器，代码如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;head runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;title&amp;gt;title&amp;gt;
head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;form id=&amp;#34;form1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;script src=&amp;#34;../JS/Eidtor/nicEdit.js&amp;#34; type=&amp;#34;text/javascript&amp;#34;&amp;gt;script&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 bkLib.onDomLoaded(function() {
 new nicEditor({ fullPanel: true }).panelInstance(&amp;#39;txtContent&amp;#39;);
 });
 script&amp;gt;
 &amp;lt;asp:TextBox runat=&amp;#34;server&amp;#34; ID=&amp;#34;txtContent&amp;#34;
 TextMode=&amp;#34;MultiLine&amp;#34; Height=&amp;#34;200px&amp;#34; Width=&amp;#34;600px&amp;#34; &amp;gt;asp:TextBox&amp;gt;
 &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行效果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301603551.webp" alt="2010-09-05_104825" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;官网中的版本为英文版，而且字体设置也只能设置英文字体，我对英文版本做了简单的汉化，并且增加了几种中文字体，如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301604995.webp" alt="2010-09-05_104528" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;&lt;a href="http://files.cnblogs.com/oec2003/NICEidtor.rar"&gt;中文本下载&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="kindeditor"&gt;KindEditor&lt;/h2&gt;
&lt;p&gt;KindEditor是一套开源的HTML可视化编辑器，主要用于让用户在网站上获得所见即所得编辑效果，兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。 KindEditor使用JavaScript编写，可以无缝的与Java、.NET、PHP、ASP等程序接合。这个是官网上的介绍。&lt;/p&gt;
&lt;p&gt;主页：&lt;a href="http://www.kindsoft.net/index.php"&gt;http://www.kindsoft.net/index.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;下载：&lt;a href="http://www.kindsoft.net/down.php"&gt;http://www.kindsoft.net/down.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;示例：&lt;a href="http://www.kindsoft.net/demo.php"&gt;http://www.kindsoft.net/demo.php&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;KindEditor相比较NicEditor涉及的文件要多很多，不过大小也才几百K而已，下图为文件结构&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301604810.webp" alt="2010-09-05_102941" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;使用代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html xmlns=&amp;#34;http://www.w3.org/1999/xhtml&amp;#34;&amp;gt;
&amp;lt;head runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;title&amp;gt;title&amp;gt;
head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;form id=&amp;#34;form1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;script charset=&amp;#34;utf-8&amp;#34; src=&amp;#34;../JS/KindEditor/kindeditor-min.js&amp;#34; 
 type=&amp;#34;text/javascript&amp;#34;&amp;gt;script&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34; charset=&amp;#34;utf-8&amp;#34;&amp;gt;
 KE.show({
 id: &amp;#39;txtContent&amp;#39;,
 resizeMode: 1,
 allowPreviewEmoticons: false,
 allowUpload: false,
 });
 script&amp;gt;
 &amp;lt;textarea cols=&amp;#34;60&amp;#34; id=&amp;#34;txtContent&amp;#34; style=&amp;#34;width: 600px; height: 300px;&amp;#34; runat=&amp;#34;server&amp;#34;
 readonly=&amp;#34;readonly&amp;#34;&amp;gt;textarea&amp;gt;
 &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行效果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301604578.webp" alt="2010-09-05_110505" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>世锦赛中国男篮“被”出线</title><link>https://fwhyy.com/2010/09/the-chinese-mens-basketball-team-for-the-world-championships-is-out/</link><pubDate>Fri, 03 Sep 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/09/the-chinese-mens-basketball-team-for-the-world-championships-is-out/</guid><description>&lt;p&gt;2010男篮世锦赛中国队神奇的“被”出线了，就在昨天晚上波多黎各以合理的分数输科特迪瓦后，主持人报出了这个令人高兴的消息。&lt;/p&gt;
&lt;p&gt;不管是以什么方式出线的，这个结果无疑是令人高兴的。提前得到了出线权使得今天凌晨2点和土耳其的比赛现在不那么重要，47分的分差40分的得分引起了很多球迷的不满，特别是那些深夜依然坚守在电视机前的球迷。&lt;/p&gt;
&lt;p&gt;阿联的受伤和一个替补的首发整容（12-郭艾伦，13-苏伟，10-张兆旭，15-周鹏，6-于澍龙）打出这样的成绩肯定不能说好，但至少也在预料之中。无疑邓华德挨骂了，但除了邓华德谁又敢用这样的首发整容呢？再好的教练都不能使一支球队有什么质的变化，跟多的需要球员的刻苦训练，对于给球队精气神上的影响，我认为邓华德做的算是不错的了。&lt;/p&gt;
&lt;p&gt;输了40分是令人心痛的，但我认为比输给那些强队很少的分数但自认为实力已经接近那些强队要好，这样至少可以清楚认识到自己的实力。&lt;/p&gt;
&lt;p&gt;上届世锦赛中国男篮凭借王仕鹏的压哨三分球，神奇地击败了斯洛文尼亚队，在与斯洛文尼亚队、波多黎各队三队同分比小分的情况下，在同样输给波多黎各队的同时晋级16强。如果说上次的命运是掌握在自己的手中，那么本次的出线则完全是掌握在别人的手中，以至于科特迪瓦主教练在赛后都一度以为是波多黎各晋级。上天不会每次都会眷顾中国队的，要想取得好成绩还是得靠自己的实力。&lt;/p&gt;
&lt;p&gt;7号对阵立陶宛，中国队还能再显“神奇”吗? 让我们拭目以待吧！！！&lt;/p&gt;</description></item><item><title>WCF中绑定的简单介绍</title><link>https://fwhyy.com/2010/08/the-simple-introduction-of-the-wcf-binding/</link><pubDate>Sun, 29 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/the-simple-introduction-of-the-wcf-binding/</guid><description>&lt;h2 id="绑定基本概念"&gt;绑定基本概念&lt;/h2&gt;
&lt;p&gt;绑定就是一个从通用基础类型派生出来的运行时类型。绑定中描述了传输协议，消息编码格式和其他的一些用于通信的通信协议。&lt;/p&gt;
&lt;h2 id="绑定的种类介绍"&gt;绑定的种类介绍&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302117082.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="两种方式来配置端点以及相关联的绑定"&gt;两种方式来配置端点以及相关联的绑定&lt;/h2&gt;
&lt;p&gt;绑定的配置可以使用配置文件的形式或是代码的形式，如下面的代码：&lt;/p&gt;
&lt;p&gt;配置文件形式(服务端)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;endpoint address=&amp;#34;HelloWorld&amp;#34; binding=&amp;#34;basicHttpBinding&amp;#34;
 contract=&amp;#34;Service.IHelloWorldService&amp;#34;&amp;gt;&amp;lt;/endpoint&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;配置文件形式(客户端)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;endpoint address=&amp;#34;http://localhost:10000/HelloWorld&amp;#34; binding=&amp;#34;basicHttpBinding&amp;#34;
 bindingConfiguration=&amp;#34;BasicHttpBinding_oec2003&amp;#34; contract=&amp;#34;HelloWorld.oec2003&amp;#34;
 name=&amp;#34;BasicHttpBinding_oec2003&amp;#34; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;代码形式&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;WSHttpBinding wsHttpBinding = new WSHttpBinding();
wsHttpBinding.Security.Mode = SecurityMode.Transport;
wsHttpBinding.ReliableSession.Enabled = true;
wsHttpBinding.TransactionFlow = true;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="绑定的功能"&gt;绑定的功能&lt;/h2&gt;
&lt;p&gt;每个绑定都必要要提供至少一个传输协议，一个消息编码格式和一个相关的消息版本，除此之外还有一些其他的功能，如安全性、双向通信、事务等。&lt;/p&gt;
&lt;p&gt;传输协议：有Http、Https、Tcp、命名管线和MSMQ，这些都有专门的绑定类型与之对应。&lt;/p&gt;
&lt;p&gt;消息编码：描述了消息是如何格式化的，可以使用Binary、Text或Mtom。&lt;/p&gt;
&lt;p&gt;消息版本：不管消息的编码格式如何，消息总是表示为SOAP1.1或是SOAP1.2.&lt;/p&gt;
&lt;p&gt;传输安全性：指在线传输证书、签名和加密的能力。一般使用SSL。&lt;/p&gt;
&lt;p&gt;消息安全性：指独立于传输层的传输证书、签名和加密的能力。&lt;/p&gt;
&lt;p&gt;双向通信：TCP和命名管线可以直接支持，但Http不支持。&lt;/p&gt;
&lt;p&gt;这些绑定的功能都是通过配置绑定元素来进行激活看，下面就简单介绍下绑定元素。&lt;/p&gt;
&lt;p&gt;每一种绑定都会有一个绑定元素的集合，像前面提到的传输协议、编码格式等都是绑定元素的一种。绑定元素在Net对应的类型都是继承自BindingElement类。在WCF中的每一种绑定必须有一个传输协议和一个消息编码格式。传输协议的通用绑定元素为TransportBindingElement，有下面一些子类继承TransportBindingElement，分别代表不同类型的传输协议。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HttpTransportBindingElement&lt;/li&gt;
&lt;li&gt;HttpsTransportBindingElement&lt;/li&gt;
&lt;li&gt;MsmqTransportBindingElement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;编码格式通用绑定元素为MessageEncodingBindingElement，一些子类如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;BinaryMessageEncodingBindingElement&lt;/li&gt;
&lt;li&gt;TextMessageEncodingBindingElement&lt;/li&gt;
&lt;li&gt;MtomMessageEncodingBindingElement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;还有一些其他的不是必须但是在一些特定场合特别有用的绑定元素：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;安全相关：SecurityBindingElement&lt;/li&gt;
&lt;li&gt;混合双向通信：CompositeDuplexBindingElement OneWayBindingElement&lt;/li&gt;
&lt;li&gt;可靠通信：ReliableSessionBindingElement&lt;/li&gt;
&lt;li&gt;事务：TransactionFlowBindingElement&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用上面的绑定元素必须引用命名空间System.ServiceModel.Channels&lt;/p&gt;
&lt;p&gt;在WCF中使用绑定通常会在配置文件中来进行，尽管也可以用代码的方式实现，但在配置文件中更加灵活。可以在端点的bindingConfiguration来进行扩展。看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;system.serviceModel&amp;gt;
 &amp;lt;services&amp;gt;
 &amp;lt;service name=&amp;#34;Service.HelloWorldService&amp;#34; behaviorConfiguration=&amp;#34;HelloWorldBebavior&amp;#34;&amp;gt;
 &amp;lt;endpoint address=&amp;#34;HelloWorld&amp;#34; binding=&amp;#34;basicHttpBinding&amp;#34;
 bindingConfiguration=&amp;#34;baseBinding_oec2003&amp;#34;
 contract=&amp;#34;Service.IHelloWorldService&amp;#34;&amp;gt;&amp;lt;/endpoint&amp;gt;
 &amp;lt;endpoint address=&amp;#34;mex&amp;#34; binding=&amp;#34;mexHttpBinding&amp;#34; contract=&amp;#34;IMetadataExchange&amp;#34; /&amp;gt;
 &amp;lt;host&amp;gt;
 &amp;lt;baseAddresses&amp;gt;
 &amp;lt;add baseAddress=&amp;#34;http://localhost:10000/&amp;#34;/&amp;gt;
 &amp;lt;/baseAddresses&amp;gt;
 &amp;lt;/host&amp;gt;
 &amp;lt;/service&amp;gt;
 &amp;lt;/services&amp;gt;
 &amp;lt;bindings&amp;gt;
 &amp;lt;basicHttpBinding&amp;gt;
 &amp;lt;binding name=&amp;#34;baseBinding_oec2003&amp;#34; maxReceivedMessageSize=&amp;#34;10000&amp;#34;
 transferMode=&amp;#34;Buffered&amp;#34;&amp;gt;
 &amp;lt;security mode=&amp;#34;Transport&amp;#34;&amp;gt;&amp;lt;/security&amp;gt;
 &amp;lt;/binding&amp;gt;
 &amp;lt;/basicHttpBinding&amp;gt;
 &amp;lt;/bindings&amp;gt;
 &amp;lt;behaviors&amp;gt;
 &amp;lt;serviceBehaviors&amp;gt;
 &amp;lt;behavior name=&amp;#34;HelloWorldBebavior&amp;#34;&amp;gt;
 &amp;lt;serviceMetadata httpGetEnabled=&amp;#34;true&amp;#34; /&amp;gt;
 &amp;lt;/behavior&amp;gt;
 &amp;lt;/serviceBehaviors&amp;gt;
 &amp;lt;/behaviors&amp;gt;
&amp;lt;/system.serviceModel&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;本文只是简单介绍了下绑定的概念以及绑定的种类，以及使用了一些代码来说明绑定的运用，关于每种绑定的详细介绍及用法在后面的博文中介绍。&lt;/p&gt;</description></item><item><title>2010篮球世锦赛赛程</title><link>https://fwhyy.com/2010/08/the-2010-basketball-world-championships/</link><pubDate>Fri, 27 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/the-2010-basketball-world-championships/</guid><description>&lt;p&gt;国际篮联3月8日公布了2010年土耳其世锦赛详细赛程，世锦赛将于8月28日-9月12日间进行。中国男篮所处的C组将在土耳其城市安卡拉比赛，中国队首战将对阵前男篮主教练尤纳斯(Jonas Kazlauskas)率领的希腊队。&lt;/p&gt;
&lt;p&gt;第一日&lt;/p&gt;
&lt;p&gt;A组&lt;/p&gt;
&lt;p&gt;第1场 8月28日22时30分 澳大利亚VS约旦 第2场 8月29日1时 安哥拉VS塞尔维亚&lt;/p&gt;
&lt;p&gt;第3场 8月29日3时30分 德国VS阿根廷&lt;/p&gt;
&lt;p&gt;B组&lt;/p&gt;
&lt;p&gt;第4场 8月28日22时30分 突尼斯VS斯洛文尼亚 第5场 8月29日1时 美国VS克罗地亚&lt;/p&gt;
&lt;p&gt;第6场 8月29日3时30分 伊朗VS巴西&lt;/p&gt;
&lt;p&gt;C组&lt;/p&gt;
&lt;p&gt;第7场 8月28日22时 希腊VS中国 第8场 8月29日0时30分 俄罗斯VS波多黎各&lt;/p&gt;
&lt;p&gt;第9场 8月29日3时 科特迪瓦VS土耳其&lt;/p&gt;
&lt;p&gt;D组&lt;/p&gt;
&lt;p&gt;第10场 8月28日22时 新西兰VS立陶宛 第11场 8月29日0时30分 加拿大VS黎巴嫩&lt;/p&gt;
&lt;p&gt;第12场 8月29日3时 法国VS西班牙&lt;/p&gt;
&lt;p&gt;第二日&lt;/p&gt;
&lt;p&gt;A组&lt;/p&gt;
&lt;p&gt;第13场 8月29日22时30分 约旦VS安哥拉 第14场 8月30日1时 塞尔维亚VS德国&lt;/p&gt;
&lt;p&gt;第15场 8月30日3时30分 阿根廷VS澳大利亚&lt;/p&gt;
&lt;p&gt;B组&lt;/p&gt;
&lt;p&gt;第16场 8月29日22时30分 斯诺文尼亚VS美国 第17场 8月30日1时 克罗地亚VS伊朗&lt;/p&gt;
&lt;p&gt;第18场 8月30日3时30分 巴西VS突尼斯&lt;/p&gt;
&lt;p&gt;C组&lt;/p&gt;
&lt;p&gt;第19场 8月29日22时 中国VS科特迪瓦 第20场 8月30日0时30分 波多黎各VS希腊&lt;/p&gt;
&lt;p&gt;第21场 8月30日3时 土耳其VS俄罗斯&lt;/p&gt;
&lt;p&gt;D组&lt;/p&gt;
&lt;p&gt;第22场 8月29日22时 立陶宛VS加拿大 第23场 8月30日0时30分 黎巴嫩VS法国&lt;/p&gt;
&lt;p&gt;第24场 8月30日3时 西班牙VS新西兰&lt;/p&gt;
&lt;p&gt;第三日&lt;/p&gt;
&lt;p&gt;A组&lt;/p&gt;
&lt;p&gt;第25场 8月30日22时30分 约旦VS塞尔维亚 第26场 8月31日1时 澳大利亚VS德国&lt;/p&gt;
&lt;p&gt;第27场 8月31日3时30分 安哥拉VS阿根廷&lt;/p&gt;
&lt;p&gt;B组&lt;/p&gt;
&lt;p&gt;第28场 8月30日22时30分 斯诺文尼亚VS克罗地亚 第29场 8月31日1时 突尼斯VS伊朗&lt;/p&gt;
&lt;p&gt;第30场 8月31日3时30分 美国VS巴西&lt;/p&gt;
&lt;p&gt;第四日&lt;/p&gt;
&lt;p&gt;C组&lt;/p&gt;
&lt;p&gt;第31场 8月31日22时 俄罗斯VS科特迪瓦 第32场 9月1日0时30分 波多黎各VS中国&lt;/p&gt;</description></item><item><title>Google和百度在细节处理上的差别</title><link>https://fwhyy.com/2010/08/google-and-baidu-in-differences-in-details/</link><pubDate>Wed, 25 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/google-and-baidu-in-differences-in-details/</guid><description>&lt;p&gt;Aspnet控件Lable有个AssociatedControlID属性，刚在百度搜索了下，敲的速度太快将ss输入成了cc了，然后出现了下面的结果：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300651984.webp" alt="2010-12-30_224251" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;然后我以同样的关键字在Google中进行搜索，结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300651170.webp" alt="2010-12-30_224334" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;同样是错误的输入，在google中有智能的正确关键词的提示，而百度却给出了一个抱歉的页面。&lt;/p&gt;</description></item><item><title>2010-08-24爱情记录</title><link>https://fwhyy.com/2010/08/the-2010-08-24-love-record/</link><pubDate>Tue, 24 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/the-2010-08-24-love-record/</guid><description>&lt;p&gt;今天是公元2010年8月24日，星期二，阴天&lt;/p&gt;
&lt;p&gt;上午在翻邮件的时候回味了下以后和老婆的一些邮件，颇有感触，下图为邮件列表&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302007299.webp" alt="2010-12-30_230851" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在邮件中有这样的两封邮件：“死党盟约合同书”和“恋爱协议”，可以看出我们就是这样从死党一步步变成恋人的。尽管两份协议书中大部分都是不利于我的那种“黑”条款，但我还是很开心，谢谢老婆的用心。&lt;/p&gt;
&lt;h2 id="死党盟约合同书"&gt;死党盟约合同书&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302008105.webp" alt="2010-08-24_122552" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="恋爱协议"&gt;恋爱协议&lt;/h2&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302008391.webp" alt="2010-08-24_122705" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;和老婆的相识是在上一家公司，但真正相爱却是在我离开公司后。当时位置上的近距离慢慢拉近了我们俩的距离，慢慢变成很好的朋友，然后到死党，最后到恋人，这中间有很多很多的事情都很难忘。&lt;/p&gt;
&lt;p&gt;时间过得很快，不知不觉和老婆都认识了716天，做了175天的恋人，在北京一起打拼了143天，我相信我们的感情会随着这些数字的增长而增长。&lt;/p&gt;
&lt;p&gt;下面是得出上面数字的方法&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302008987.webp" alt="2010-08-24_130953" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2010年8月24日记录与北京迪阳大厦1609B&lt;/p&gt;</description></item><item><title>关于LoadRunner的一点资料</title><link>https://fwhyy.com/2010/08/a-little-information-about-loadrunner/</link><pubDate>Tue, 24 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/a-little-information-about-loadrunner/</guid><description>&lt;p&gt;LoadRunner是一款很强大的测试工具，前不久有过一段时间的使用经历，并且写了篇文章加以介绍&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/oec2003/archive/2010/05/21/1740625.html"&gt;使用LoadRunner测试WMS&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;在使用LoadRunner期间也积累的一些资料，下面给出下载地址与大家分享:&lt;/p&gt;</description></item><item><title>毛毛仔大坐熊</title><link>https://fwhyy.com/2010/08/maomao-son-big-sit-bear/</link><pubDate>Thu, 19 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/maomao-son-big-sit-bear/</guid><description>&lt;p&gt;最近实在是太忙了，以至于这么重要的节日我都忘记了在博客中记下一笔。趁今天这个午休的时间来写下吧。&lt;/p&gt;
&lt;p&gt;七夕是我和老婆在一起后的第一个比较重大的节日，我们是今年3月才开始在一起的，准确的说现在还是我的女朋友，不过在我心里她已经是我老婆了，所以称之为老婆。&lt;/p&gt;
&lt;p&gt;七夕的前几天，我们在网上团购了好伦哥的自助餐，准备七夕晚上去吃，不巧的是老婆上火，口腔嘴唇都长了溃疡，喝凉水都疼，更别说是吃自助餐了。所以当时就决定等溃疡好了我们再去。&lt;/p&gt;
&lt;p&gt;决定溃疡好了再去吃的那天是2010-08-13，星期五。当时想不能去吃自助了，那我得买件礼物送她，对于我们这样一个很土且不浪漫的人来说，选礼物比写程序要难。幸好我记得有两件东西她是超喜欢的，娃娃和冰激凌。于是马上就到网上去订购了一个大坐熊。&lt;/p&gt;
&lt;p&gt;星期六的中午，老婆在做饭，快递人员电话说东西到了，让我下楼去取,东西拿到屋子后，老婆问我是什么，我很平静地说：“我在网上买了个熊”。老婆开始还不相信，后来进到房间才发现是真的，不过也表现地很平静，不过从眼神我能看出她是很喜欢的。&lt;/p&gt;
&lt;p&gt;从买熊到现在老婆的一些表现可以看出，当时她看到熊的那一刻的平静时装出来的，我发现她很喜欢那个熊，以至于睡觉都抱着熊不抱我了毛毛仔大坐熊&lt;/p&gt;
&lt;p&gt;在北京漂着的日子很不容易，每天要挤拥挤的地铁，要面对工作中的种种压力，老婆更不容易，下班回家还要做饭，老婆你辛苦了，希望我们能永远都这么开心，这里也会记录我们的开心的点点滴滴。&lt;/p&gt;</description></item><item><title>WebService生成客户端代理的工具WSDL参数介绍</title><link>https://fwhyy.com/2010/08/webservice-to-generate-the-client-proxy-tool-wsdl-parameters-is-introduced/</link><pubDate>Tue, 10 Aug 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/08/webservice-to-generate-the-client-proxy-tool-wsdl-parameters-is-introduced/</guid><description>&lt;h2 id="wsdlexe"&gt;wsdl.exe&lt;/h2&gt;
&lt;p&gt;使用 ASP.NET，根据 WSDL 协定文件、XSD 架构和 .disc 发现文档，为 Xml Web Services 客户端和 Xml Web Ser 代码的实用工具。此工具可以与 disco.exe 一起使用。&lt;/p&gt;
&lt;p&gt;wsdl.exe &amp;lt;选项&amp;gt; &amp;lt;URL 或路径&amp;gt; &amp;lt;URL 或路径&amp;gt;&lt;/p&gt;
&lt;h2 id="选项"&gt;选项&lt;/h2&gt;
&lt;p&gt;&amp;lt;URL 或路径&amp;gt; –
指向 WSDL 协定、XSD 架构或 .discomap 文档的 URL 或 /nologo 取消显示版权标志。&lt;/p&gt;
&lt;p&gt;/language:&lt;language&gt;
用于生成的代理类的语言。请从“CS”、“VB”、“JS”、“CPP”中选择，或者为实现System.CodeDom.Compiler. 的类提供一个完全限定的名称。默认语言为“CS”(CShar )缩写形式为“/l:”。&lt;/p&gt;
&lt;p&gt;/sharetypes
打开类型共享功能。此功能针对不同服务之间共享 的相同类型(命名空间、名称和网络签名必须相同) 创建一个具有单一类型定义的代码文件。 请使用 http:// URLs 作为命令行参数来引用 服务，或为本地文件创建一个 discomap 文档。&lt;/p&gt;
&lt;p&gt;/verbose
指定 /sharetypes 开关时显示额外信息。 缩写形式为“/v”。&lt;/p&gt;
&lt;p&gt;/fields
生成字段而非属性。缩写形式为“/f”。&lt;/p&gt;
&lt;p&gt;/order
为粒子成员生成显式顺序标识符。&lt;/p&gt;
&lt;p&gt;/enableDataBinding
在所有生成的类型上实现 INotifyPropertyChanged 接口 以启用数据绑定。缩写形式为“/edb”。&lt;/p&gt;
&lt;p&gt;/namespace:&lt;namespace&gt;
生成的代理或模板的命名空间。默认命名空间 为全局命名空间。缩写形式为“/n:”。&lt;/p&gt;
&lt;p&gt;/out:&amp;lt;fileName|directoryPath&amp;gt;
生成的代理代码的文件名或目录路径。默认文件名是从 服务名派生的。缩写形式为“/o:”。&lt;/p&gt;
&lt;p&gt;/protocol:&lt;protocol&gt;
重写要实现的默认协议。请从“SOAP”、“SOAP12”、 “HttpGet”、“HttpPost”中选择。&lt;/p&gt;
&lt;p&gt;/username:&lt;username&gt;
/password:&lt;password&gt;
/domain:&lt;domain&gt;
连接到要求身份验证的服务器时使用的凭据。 缩写形式为“/u:”、“/p:”和“/d:”。&lt;/p&gt;
&lt;p&gt;/proxy:&lt;url&gt;
用来处理 HTTP 请求的代理服务器的 URL。 默认为使用系统代理服务器设置。&lt;/p&gt;
&lt;p&gt;/proxyusername:&lt;username&gt;
/proxypassword:&lt;password&gt;
/proxydomain:&lt;domain&gt;
连接到要求身份验证的代理服务器时使用的凭据。 缩写形式为“/pu:”、“/pp:”和“/pd:”。&lt;/p&gt;
&lt;p&gt;/appsettingurlkey:&lt;key&gt;
在代码生成中用来读取 URL 属性的 默认值的配置项。默认为不从配置 文件中读取。缩写形式为“/urlkey:”。&lt;/p&gt;
&lt;p&gt;/appsettingbaseurl:&lt;baseurl&gt;
计算 URL 段时使用的基 URL。 还必须指定 appsettingurlkey 选项。URL 段是 从 appsettingbaseurl 计算 WSDL 文档中的 URL 的相对 URL 的结果。&lt;/p&gt;</description></item><item><title>Net4.0—数据绑定控件（GridView ListView…）中的ClientIDRowSuffix属性</title><link>https://fwhyy.com/2010/07/net-4-data-bound-controls-the-clientidrowsuffix-properties/</link><pubDate>Fri, 30 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/net-4-data-bound-controls-the-clientidrowsuffix-properties/</guid><description>&lt;p&gt;在AspNet4中的数据绑定控件（GridView ListView…）中新增了一个ClientIDRowSuffix属性，ClientIDRowSuffix属性可以影响数据绑定控件内部控件的ID，ClientIDRowSuffix控件的值可以设置为数据绑定控件的数据源的任何一列。值得注意的是ClientIDRowSuffix属性是和ClientIDMode属性配合使用的。ClientIDMode有四种属性值，这个在&lt;a href="http://blog.fwhyy.com/?p=18"&gt;Net4.0—对HTML净化的处理&lt;/a&gt;一文中有提到，下面介绍如何在数据绑定控件中使用ClientIDRowSuffix：&lt;/p&gt;
&lt;p&gt;1 在页面中放一个GridView控件，在控件添加一个模板列，模板列中添加一个Lable控件，ID设置为lblId，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:GridView ID=&amp;#34;GridView1&amp;#34; runat=&amp;#34;server&amp;#34;
 ClientIDRowSuffix=&amp;#34;UserId&amp;#34; ClientIDMode=&amp;#34;Predictable&amp;#34; &amp;gt;
 &amp;lt;Columns&amp;gt;
 &amp;lt;asp:TemplateField&amp;gt;
 &amp;lt;ItemTemplate&amp;gt;
 &amp;lt;asp:Label ID=&amp;#34;lblId&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:Label&amp;gt;
 &amp;lt;/ItemTemplate&amp;gt;
 &amp;lt;/asp:TemplateField&amp;gt;
 &amp;lt;/Columns&amp;gt;
&amp;lt;/asp:GridView&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 进入后台代码视图，添加一个User类做数据源用，在PageLoad事件中绑定GridView，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public partial class WebForm1 : System.Web.UI.Page
{
 protected void Page_Load(object sender, EventArgs e)
 {
 List&amp;lt;User&amp;gt; list = new List&amp;lt;User&amp;gt;
 {
 new User{UserId=10,UserName=&amp;#34;oec2003&amp;#34;},
 new User{UserId=20,UserName=&amp;#34;oec2004&amp;#34;}
 };
 if (!Page.IsPostBack)
 {
 this.GridView1.DataSource = list;
 this.GridView1.DataBind();
 }
 }
}
public class User
{
 public int UserId { get; set; }
 public string UserName { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 设置GridView的属性ClientIDMode为不同值，运行程序查看源码，观察Lable控件的ID，如下图：&lt;/p&gt;
&lt;p&gt;AutoID&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300731399.webp" alt="2010-07-30_112500" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Inherit&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300731940.webp" alt="2010-07-30_112644" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Predictable&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300731460.webp" alt="2010-07-30_112747_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Static&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732906.webp" alt="2010-07-30_112954" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1 根据上图看以看出当ClientIDMode值为Predictable和Inherit时，ClientIDRowSuffix的设置才起了作用，将ClientIDRowSuffix设置的UserId字段的值拼接到了Lable控件的ID属性后。&lt;/li&gt;
&lt;li&gt;2 在网上的一些资料表明ClientIDRowSuffix属性要和ClientIDMode属性一起使用，并且ClientIDMode属性的值要设置成Predictable，但我将GridView中的ClientIDMode属性去掉后运行，看到的源码和设置ClientIDMode为Predictable得到的源码一致。也就是说只设置GrieView的ClientIDRowSuffix就可以得到想要的结果。&lt;/li&gt;
&lt;li&gt;3 ClientIDRowSuffix属性还可以设置对应多个字段，如ClientIDRowSuffix=”UserId,UserName”，这样得到的控件的ID是多个字段值的拼接。&lt;/li&gt;
&lt;li&gt;4 在AspNet4的数据绑定控件中，只有GridView和ListView有ClientIDRowSuffix属性。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Net4.0—AspNet中的控件HyperLink的改进（支持路由跳转）</title><link>https://fwhyy.com/2010/07/net-4-aspnet-controls-the-hyperlink-in-the-improvement/</link><pubDate>Wed, 28 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/net-4-aspnet-controls-the-hyperlink-in-the-improvement/</guid><description>&lt;p&gt;作过Web开发的人对HyperLink控件一定非常熟悉，在客户端生成的代码就是一个a标签。AspNet4中的Hyperlink控件相比以前的版本做了些改进，可以更好地支持URl重写，下面结合在&lt;a href="http://blog.fwhyy.com/?p=20"&gt;Net4.0—AspNet中URL重写的改进&lt;/a&gt;一文中的例子来讲解下Hyperlink这个新的功能。&lt;/p&gt;
&lt;p&gt;1 在项目中的Default.aspx页面中加入一个Hyperlink控件，在设计视图中右击该控件，选择属性，在属性窗口中选择Expresstions，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300729640.webp" alt="2010-07-27_172142" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 点击右边的三个小点点，在弹出的对话框中进行如下设置：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300729586.webp" alt="2010-07-27_172422" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;设置RouteName为productdetail，就是让该链接导向test.aspx页面，因为在Global.asax中设置名为productdetail的路由对应的物理文件时test.aspx。RouteValus就是配置参数项，此处的category和name也是在Global.asax中配置的。&lt;/p&gt;
&lt;p&gt;3 设置好后点击OK，切换到代码视图，可以看到代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:HyperLink ID=&amp;#34;HyperLink1&amp;#34; runat=&amp;#34;server&amp;#34;
 NavigateUrl=&amp;#34;&amp;lt;%$ RouteUrl:RouteName=productdetail,category=computer,name=thinkpad %&amp;gt;&amp;#34;&amp;gt;
 Test Page&amp;lt;/asp:HyperLink&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 设置Default.aspx为起始页，按F5运行，点击链接Test Page链接，会跳转到test.aspx页面，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300729625.webp" alt="2010-07-27_173712" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Net4.0—对HTML净化的处理</title><link>https://fwhyy.com/2010/07/net-4-purification-processing-of-html/</link><pubDate>Wed, 28 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/net-4-purification-processing-of-html/</guid><description>&lt;p&gt;在使用Asp.Net进行Web开发时我一直都很注重最终生成的HTML是否干净，所以我会使用Repeater取代GridView等控件，可控性好而且生成的HTML代码也非常干净。干净的HTML有很多好处，如代码相应较少加载速度快，便于控制页面元素等。在AspNet4中对HTML的净化做了很大的改进，下面的文字中会做一个简单的介绍。&lt;/p&gt;
&lt;h2 id="设置controlrenderingcompatibilityversion"&gt;设置controlRenderingCompatibilityVersion&lt;/h2&gt;
&lt;p&gt;controlRenderingCompatibilityVersion需要在Webconfig文件中设置，配置在Pages节点中，可以设置使用3.5还是4.0的引擎来渲染HTML，默认是使用4.0。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300730129.webp" alt="2010-07-28_143021" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在VS2010中创建一个AspNet项目，在项目中的site.master中会有一个Menu控件来显示导航，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Menu ID=&amp;#34;NavigationMenu&amp;#34; runat=&amp;#34;server&amp;#34; CssClass=&amp;#34;menu&amp;#34;
EnableViewState=&amp;#34;false&amp;#34; IncludeStyleBlock=&amp;#34;false&amp;#34; Orientation=&amp;#34;Horizontal&amp;#34;&amp;gt;
 &amp;lt;Items&amp;gt;
 &amp;lt;asp:MenuItem NavigateUrl=&amp;#34;~/Default.aspx&amp;#34; Text=&amp;#34;Home&amp;#34;/&amp;gt;
 &amp;lt;asp:MenuItem NavigateUrl=&amp;#34;~/About.aspx&amp;#34; Text=&amp;#34;About&amp;#34;/&amp;gt;
 &amp;lt;/Items&amp;gt;
&amp;lt;/asp:Menu&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;分别设置 controlRenderingCompatibilityVersion属性值为3.5和4.0，运行项目，看到页面源码的区别如下：&lt;/p&gt;
&lt;p&gt;4.0&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2010/2010-07-28_150119.webp" alt="2010-07-28_150119" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3.5&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300730347.webp" alt="2010-07-28_150528" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以看出使用4.0的引擎是将Menu控件生成的Ul 标签，而3.5中是生成的table，代码的复杂度明显大了很多。当然并不只是对Menu控件进行了优化，还有其他一些方面如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一些控件的内置样式被去掉，而是在页面中生成样式代码；&lt;/li&gt;
&lt;li&gt;模板控件中移除了外表表格渲染；&lt;/li&gt;
&lt;li&gt;向导类控件使用站位符控制层。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="使用clientidmode"&gt;使用ClientIDMode&lt;/h2&gt;
&lt;p&gt;在继承了masterpage页的页面中添加其他的服务器控件，最终呈现的HTML的的ID都会改变，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300731072.webp" alt="2010-07-28_152923" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;AspNet4中可以使用ClientIDMode来改变这一局面，ClientIDMode在页面的Page指令中设置，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;%@ Page Title=&amp;#34;&amp;#34; Language=&amp;#34;C#&amp;#34; MasterPageFile=&amp;#34;~/Site.Master&amp;#34; AutoEventWireup=&amp;#34;true&amp;#34;
CodeBehind=&amp;#34;test.aspx.cs&amp;#34; Inherits=&amp;#34;UrlRewriterDemo.test&amp;#34; ClientIDMode=&amp;#34;Static&amp;#34; %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;将ClientIDMode设置为Static后，刷新页面查看源代码，控件的ID变成本来面目了，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300731621.webp" alt="2010-07-28_154000" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;ClientIDMode有四个属性值：AutoID、Inherit、Predictable和Static，下面以上面的按钮为例，列出分别在这四种属性值下呈现的ID值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AutoID：ctl00_MainContent_btnTest&lt;/li&gt;
&lt;li&gt;Inherit：MainContent_btnTest&lt;/li&gt;
&lt;li&gt;Predictable：MainContent_btnTest&lt;/li&gt;
&lt;li&gt;Static：btnTest&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="对viewstate更细致化的管理"&gt;对ViewState更细致化的管理&lt;/h2&gt;
&lt;p&gt;ViewState是让人又爱又恨的东西，控制不好会使页面变得非常庞大，在AspNet4中可以使用ViewStateMode对ViewState进行更细致化的管理。ViewStateMode可以在页面级设置也可以在控件级设置，有三个属性值：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inherit：从父控件中继承；&lt;/li&gt;
&lt;li&gt;Enabled：当父控件的ViewState处于Disabled状态时可以设置当前控件ViewState可用；&lt;/li&gt;
&lt;li&gt;Disabled：当父控件的ViewState处于Enalbed状态时可以设置当前控件ViewState禁用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在以前的AspNet版本中有个EnableViewState属性可以来设置ViewState，不过ViewStateMode和EnableViewState还是有很大区别的：&lt;/p&gt;
&lt;h3 id="enableviewstate"&gt;EnableViewState&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;其值为布尔类型，决定其控件或是子控件是否开启ViewState；&lt;/li&gt;
&lt;li&gt;优先级别大于ViewStateMode，只要 EnableViewState设置为false，就算设置了ViewStateMode为Enabled，控件的ViewState还是关闭的；&lt;/li&gt;
&lt;li&gt;当设置父控件的EnableViewState为false后，其子控件的ViewState就都关闭了，不能在子控件中单独开启ViewState。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="viewstatemode"&gt;ViewStateMode&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;在父控件以及本身的EnableViewState设置为true时，才会起作用；&lt;/li&gt;
&lt;li&gt;子控件不受父控件ViewStateMode的影响；&lt;/li&gt;
&lt;li&gt;在父控件中设置ViewStateMode为Disabled后，可以在子控件中设置ViewStateMode为Enabled来开启子控件的ViewState。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Net4.0—AspNet中URL重写的改进</title><link>https://fwhyy.com/2010/07/net-4-aspnet-url-rewriting-in-the-improvement/</link><pubDate>Tue, 27 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/net-4-aspnet-url-rewriting-in-the-improvement/</guid><description>&lt;p&gt;URL重写有很多的好处，如有利于SEO、便于记忆、隐藏真实路径使安全性提高、便于更新等等。在AspNet4.0之前的版本中要实现URL重写比较复杂，有时还会借助第三方类库，而在AspNet4.0中可以很方面实现，下面就一步一步来讲解怎样在AspNet4.0中实现URL重写。&lt;/p&gt;
&lt;p&gt;1 打开VS2010，创建一个AspNet项目命名为UrlRewriterDemo。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300727900.webp" alt="2010-07-27_100812" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以看到AspNet4中的项目结构有点类似AspNet MVC ，加了很多现成的东西，只需稍加修改就可以变成一个简单的个人站点。&lt;/p&gt;
&lt;p&gt;2 打开Global.asax文件，引用命名空间System.Web.Routing，System.Web.Routing命名空间在Net3.5中就已经存在，不过功能没有4.0中的强大。在该文件中添加如下方法:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;void RegisterRoutes(RouteCollection routes)
{
 routes.MapPageRoute(&amp;#34;productdetail&amp;#34;,
 &amp;#34;products/{category}/{name}&amp;#34;,
 &amp;#34;~/test.aspx&amp;#34;, false,
 new RouteValueDictionary { { &amp;#34;category&amp;#34;, &amp;#34;book&amp;#34; }, { &amp;#34;name&amp;#34;, &amp;#34;aspnet&amp;#34; } });
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;MapPageRoute方法的参数解释：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“productdetail”：路由名称，取一个和当前路由设置相匹配的名称即可。&lt;/li&gt;
&lt;li&gt;“products/{category}/{name}”：URL的重写规则。&lt;/li&gt;
&lt;li&gt;“~/test.aspx”：配置对应的物理文件。&lt;/li&gt;
&lt;li&gt;new RouteValueDictionary { { “category”, “book” }, { “name”, “aspnet” } }：配置默认值。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;3 在Global.asax中的方法Application_Start中添加如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;void Application_Start(object sender, EventArgs e)
{
 RegisterRoutes(RouteTable.Routes);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 在项目中添加一个页面命名为test.aspx，如果命名为别的名称，在上面的MapPageRoute方法的配置物理文件的参数就应该设置为相应的名称。在test.aspx页面中添加如下内容：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Content ID=&amp;#34;Content2&amp;#34; ContentPlaceHolderID=&amp;#34;MainContent&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;h1&amp;gt;Url Rewriter Test Page!&amp;lt;/h1&amp;gt;
&amp;lt;/asp:Content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 将该项目设置为固定端口，比如10000，按F5运行项目，将URL地址修改为http://localhost:10000/products，此处的products为URL重写规则中配置的名称。运行结果如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300727307.webp" alt="2010-07-27_104717_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 我们在RegisterRoutes中配置了默认参数值category和name，如需要在页面中获取参数值，可以使用RouteData.Values，将test.aspx页面代码修改如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Content ID=&amp;#34;Content2&amp;#34; ContentPlaceHolderID=&amp;#34;MainContent&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;h1&amp;gt;Url Rewriter Test Page!&amp;lt;/h1&amp;gt;&amp;lt;br /&amp;gt;

 分类名为：&amp;lt;%= RouteData.Values[&amp;#34;category&amp;#34;] %&amp;gt;&amp;lt;br /&amp;gt;
 产品名为：&amp;lt;%= RouteData.Values[&amp;#34;name&amp;#34;] %&amp;gt;
&amp;lt;/asp:Content&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;7 刷新页面可以看到在RegisterRoutes中配置的默认值会呈现在页面上：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300728509.webp" alt="2010-07-27_111408" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;8 将URL修改为http://localhost:10000/products/computer/thinkpad，再刷新页面可以看到页面中呈现的是URL中设置的分类名和产品名:&lt;/p&gt;</description></item><item><title>公司组织北戴河夏游小记 2010年7月24日</title><link>https://fwhyy.com/2010/07/a-trip-to-beidaihe-2010-07-24/</link><pubDate>Mon, 26 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/a-trip-to-beidaihe-2010-07-24/</guid><description>&lt;p&gt;24日早上起了个大早做地铁赶到公司集合，不过司机同志也太不守时了，害我们多等了半个小时。车程4个小时到达秦皇岛，时间正好是中午的饭点，所以就安排了吃中午饭，饭菜实在不怎么样，不过也挺习惯这种旅游的饭菜，让人不能理解的是吃饭的桌子没有转盘，我也懒得起身，这样使得我只吃到了一半的菜。&lt;/p&gt;</description></item><item><title>WCF契约的简单介绍（服务契约 数据契约 消息契约）</title><link>https://fwhyy.com/2010/07/the-simple-introduction-of-wcf-contract/</link><pubDate>Wed, 21 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/the-simple-introduction-of-wcf-contract/</guid><description>&lt;p&gt;本篇博文只是简单说下WCF中的契约的种类、作用以及一些简单的代码示例。在WCF中契约分为服务契约、数据契约和消息契约。下面对这几种契约进行简单的介绍。&lt;/p&gt;
&lt;h2 id="服务契约"&gt;服务契约&lt;/h2&gt;
&lt;p&gt;服务契约描述了暴露给外部的类型（接口或类）、服务所支持的操作、使用的消息交换模式和消息的格式。每个WCF服务必须实现至少一个服务契约。使用服务契约必须要引用命名空间System.ServiceModel 。服务契约中常用到的三个特性：&lt;/p&gt;
&lt;h3 id="servicecontractattribute"&gt;ServiceContractAttribute&lt;/h3&gt;
&lt;p&gt;该特性定义在类或接口上，用来描述一个相关操作的集合。ServiceContractAttribute特性还有如下的一些属性值可以设置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name：给服务契约定义一个名称，而不是使用接口或是类的类型名，在客户端添加服务引用时会用到。&lt;/li&gt;
&lt;li&gt;Namespace：命名空间，默认值为http://tempuri.org。&lt;/li&gt;
&lt;li&gt;CallbackContract：将另一个服务契约定义为回调契约，使得客户端可以接收服务端的异步消息。&lt;/li&gt;
&lt;li&gt;ProtectionLevel：控制契约中发送给消息的保护方式是否需要被签名和加密。该属性为System.Net.Security.ProtectionLevel枚举类型。&lt;/li&gt;
&lt;li&gt;SessionMode：确定会话是否为公开服务契约的端点所支持。&lt;/li&gt;
&lt;li&gt;ConfigurationName：服务的配置名称。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[ServiceContract(Name=&amp;#34;HelloWorld&amp;#34;,Namespace=&amp;#34;http://oec2003.cnblogs.com&amp;#34;]
public interface IHelloWorldService
{ 

}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="operationcontractattribute"&gt;OperationContractAttribute&lt;/h3&gt;
&lt;p&gt;用OperationContractAttribute标记的方法即为一个服务操作，简单的使用该特性就可以让一个方法加入到服务契约的操作队列中，可以被客户端所调用。该特性也有一些设置消息交换方式的属性。如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name：定义一个操作名称，而不是使用方法名称。&lt;/li&gt;
&lt;li&gt;Action：该操作消息的动作标题。&lt;/li&gt;
&lt;li&gt;ReplyAction：响应该操作消息的动作标题。&lt;/li&gt;
&lt;li&gt;IsOneWay：设置该操作是否单向和没有回复，如果操作是单向的，将不支持ReplyAction。&lt;/li&gt;
&lt;li&gt;ProtectionLevel：允许你控制特定的操作消息是否被保护，操作中的ProtectionLevel属性将覆盖服务契约中的ProtectionLevel。该属性为System.Net.Security.ProtectionLevel枚举类型。&lt;/li&gt;
&lt;li&gt;IsInitiating：操作是否可以用来初始化会话。&lt;/li&gt;
&lt;li&gt;IsTerminating：操作是否中止一个会话。&lt;/li&gt;
&lt;li&gt;AsyncPattern：将服务操作定义为异步实现模式。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[ServiceContract(Namespace=&amp;#34;http://oec2003.cnblogs.com&amp;#34;,Name=&amp;#34;oec2003&amp;#34;,
 ConfigurationName=&amp;#34;IHelloWorldService&amp;#34;)]
public interface IHelloWorldService
{
 [OperationContract(Name=&amp;#34;oec2003SayHello&amp;#34;,
 Action = &amp;#34;http://oec2003.cnblogs.com/IHelloWorldService/Hello&amp;#34;,
 ReplyAction = &amp;#34;http://oec2003.cnblogs.com/IHelloWorldService/HelloReply&amp;#34;)]
 string SayHello();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="messageparameterattribute"&gt;MessageParameterAttribute&lt;/h3&gt;
&lt;p&gt;使用 MessageParameterAttribute 可以控制参数或返回值的名称。此属性对于已用 MessageContractAttribute 特性标记的参数无效。该特性只有一个Name属性，看如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[ServiceContract(Namespace=&amp;#34;http://oec2003.cnblogs.com&amp;#34;,Name=&amp;#34;oec2003&amp;#34;,
 ConfigurationName=&amp;#34;IHelloWorldService&amp;#34;)]
public interface IHelloWorldService
{
 [OperationContract]
 [return: MessageParameter(Name = &amp;#34;responseString&amp;#34;)]
 string SayHello([MessageParameter(Name = &amp;#34;string&amp;#34;)]string meg);
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="数据契约"&gt;数据契约&lt;/h2&gt;
&lt;p&gt;使用数据契约必须引用System.Runtime.Serialization命名空间，在类型上使用DataContractAttribute可以创建数据契约，类型中的成员使用DataMember标记。代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[DataContract]
public class User
{
 [DataMember]
 public int Age { get; set; }
 [DataMember]
 public string Name { get; set; }
 [DataMember]
 public string Email { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="datacontractattribute"&gt;DataContractAttribute&lt;/h3&gt;
&lt;p&gt;DataContractAttribute特性定义在类型之上，类型包括类、结构、枚举但不包括接口。DataContractAttribute特性不能被继承，即继承自有DataContractAttribute特性标记的类并不是数据契约，必须显示使用DataContractAttribute标记才能成为数据契约。DataContractAttribute特性有IsReference、Name和Namespace三个属性：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IsReference：bool类型，表示在进行序列化的时候是否保持对象现有的引用结构。&lt;/li&gt;
&lt;li&gt;Name：名称。&lt;/li&gt;
&lt;li&gt;Namespace：命名空间。&lt;/li&gt;
&lt;/ul&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[DataContract(IsReference=true,Name=&amp;#34;MyUser&amp;#34;,Namespace=&amp;#34;http://oec2003.cnblogs.com&amp;#34;)]
public class User
{
 [DataMember]
 public int Age { get; set; }
 [DataMember]
 public string Name { get; set; }
 [DataMember]
 public string Email { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="datamemberattribute"&gt;DataMemberAttribute&lt;/h3&gt;
&lt;p&gt;使用DataMemberAttribute标记的类型成员才能成为数据契约的数据成员。这个和服务契约中的OperationContractAttribute类似。DataMemberAttribute特性有如下四个属性:&lt;/p&gt;</description></item><item><title>WCF问题:“HTTP 错误 404.17 – Not Found 请求的内容似乎是脚本，因而将无法由静态文件处理程序来处理”解决方法</title><link>https://fwhyy.com/2010/07/wcf-problem-http-error-404-17-solution/</link><pubDate>Mon, 19 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/wcf-problem-http-error-404-17-solution/</guid><description>&lt;p&gt;在写&lt;a href="http://blog.fwhyy.com/?p=23"&gt;在IIS中寄存已有WCF服务&lt;/a&gt;文章的时候，创建了WCF Service模板站点，按F5运行的时候会出现“HTTP 错误 404.17 – Not Found 请求的内容似乎是脚本，因而将无法由静态文件处理程序来处理 ”的错误，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290630316.webp" alt="2010-07-19_173102" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在网上查出的解决方为重新注册WCF，在命令提示符中输入如下图的命令运行即可:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290630346.webp" alt="2010-07-19_173337" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;安装成功后再次运行站点就会出现正确的页面，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290638830.webp" alt="image-20220129063819672" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>在IIS中寄存已有WCF服务</title><link>https://fwhyy.com/2010/07/register-existing-wcf-service-in-iis/</link><pubDate>Mon, 19 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/register-existing-wcf-service-in-iis/</guid><description>&lt;p&gt;IIS是WCF服务的宿主之一，在新建Web Site的时候有WCF Service模板可以供选择，不过依据WCF Service模板创建的站点是将服务和宿主整合在一起了，下面就来看看如何将一个已有的WCF服务寄存在IIS中。&lt;/p&gt;
&lt;p&gt;1 在&lt;a href="http://www.cnblogs.com/oec2003/archive/2010/07/15/1778013.html"&gt;一个简单的WCF示例&lt;/a&gt;一文的解决方案中添加新的站点，选择WCF Service模板，地址设置为http://localhost/IISHostedService，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301618792.webp" alt="2010-07-19_154628" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 确定后，WCF Service模板就生成了一个带有服务的站点，因为我们要将已有服务寄存在该站点中，所以要删除站点中自带的服务，服务的文件在App_Code目录中，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301619850.webp" alt="2010-07-19_155053" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 添加对Service项目的引用，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301619979.webp" alt="2010-07-19_161549" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 双击项目中Service.svc文件，修改@ServiceHost指令，关联上服务类型，修改后的代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;%@ ServiceHost Language=&amp;#34;C#&amp;#34; Debug=&amp;#34;true&amp;#34; Service=&amp;#34;Service.HelloWorldService&amp;#34; %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 修改站点的Web.Config文件，找到Service节点，修改Service节点的Name属性、endpoint节点的绑定属性和契约属性，修改后的代码如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301619029.webp" alt="2010-07-19_162314" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 将该站点设置为启动项目，按F5运行，如果Web.Config文件中没有配置元数据交换端点，运行后会看到如下页面：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301619804.webp" alt="2010-07-19_164149" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;可以根据上面页面中的步骤一步一步来配置元数据交换端点，配置好后，如果serviceMetadata节点的httpGetEnabled属性设置为false，运行后如下图所示：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301619610.webp" alt="2010-07-19_164721" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在设置httpGetEnabled属性为true，再次运行可以看到svcutil指令后是一个带有?wsdl的链接地址，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301619381.webp" alt="2010-07-19_1649411" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击这个链接，可以看到服务的WSDL文档，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301620414.webp" alt="2010-07-19_165128" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;7 IIS宿主部分已经写好，现在要做的就是使用SvcUtil工具来生成客户端的代理，打开VS2008 的命令提示窗口，输入先前站点运行后的命令提示，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301620416.webp" alt="2010-07-19_170851" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;8 执行后生成了一个代理文件和一个配置文件，在目录C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC 中，将这两个文件拷贝到客户程序中，配置文件改名为app.config，然后再客户程序中添加如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class Program
{
 static void Main(string[] args)
 {
 oec2003Client proxy = new oec2003Client();
 Console.WriteLine(proxy.SayHello());
 proxy.Close();
 Console.ReadLine();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;9 运行客户程序可以看到如下结果&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301620809.webp" alt="2010-07-19_171432" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>WCF中客户端生成代理的两种方式</title><link>https://fwhyy.com/2010/07/wcf-client-generation-agent-in-two-ways/</link><pubDate>Fri, 16 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/wcf-client-generation-agent-in-two-ways/</guid><description>&lt;p&gt;WCF程序中客户端要生成代理才能调用服务，在客户端生成代理有多种方式，如用ChannelFactory和添加服务引用等。下面就分别来介绍下这两种生成代理的方式。&lt;/p&gt;
&lt;h2 id="使用channelfactory"&gt;使用ChannelFactory&lt;/h2&gt;
&lt;p&gt;使用ChannelFactory创建代理需要的条件&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;服务端点的地址，即在宿主中用程序设置的或是配置文件中设置的。&lt;/li&gt;
&lt;li&gt;服务端点的绑定协议。&lt;/li&gt;
&lt;li&gt;服务契约的元数据，可以将服务契约复制一份到客户端或是在客户端添加对服务的引用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面的代码示例为通过ChannelFactory手动创建代理&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;EndpointAddress ea =
 new EndpointAddress(&amp;#34;http://localhost:10000/Service/HelloWorldService&amp;#34;);
IHelloWorldService proxy =
 ChannelFactory&amp;lt;IHelloWorldService&amp;gt;.CreateChannel(new BasicHttpBinding(),ea);
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;EndpointAddress：端点地址，该类的实例作为CreateChannel方法的一个参数，实例化EndpointAddress时给的地址要和宿主中设置的地址一致。&lt;/li&gt;
&lt;li&gt;IHelloWorldService：这个是服务契约在客户端的一个副本，不包含具体的实现。&lt;/li&gt;
&lt;li&gt;ChannelFactory&lt;T&gt;：一个服务模型类型，可以产生客户代理和基础信道栈，使用该类的CreateChannel可以生成代理，有两个参数，绑定类型和端点地址，绑定类型和端点地址要和宿主中设置的一致。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="添加服务引用的方式"&gt;添加服务引用的方式&lt;/h2&gt;
&lt;p&gt;1 在宿主的配置文件中配置元数据呢交换节点，并在行为中设置serviceMetadata，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290626408.webp" alt="2010-07-16_163822" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在客户端添加服务引用时必须启动宿主。&lt;/p&gt;
&lt;p&gt;3 配置文件设置好后，启动宿主，然后再客户项目上右击选择“Add Service Reference ”，在地址框中输入正确地址，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290627453.webp" alt="2010-07-16_164810" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Http://localhost:10000/mex：是配置文件中的基地址http://localhost:10000加上端点地址mex组合而成。&lt;/p&gt;
&lt;p&gt;oec2003：为服务契约中设置的属性Name的值，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290627963.webp" alt="2010-07-16_165418" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;HelloWorld：为自己定义的引用到客户端的名称。&lt;/p&gt;
&lt;p&gt;4 添加服务引用后客户端的项目列表显示如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290627665.webp" alt="2010-07-16_165914" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5 在客户端添加如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class Program
{
 static void Main(string[] args)
 {
 HelloWorld.oec2003Client proxy = new Client.HelloWorld.oec2003Client();
 Console.WriteLine(proxy.SayHello());
 Console.ReadLine();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;6 先运行宿主，然后运行客户程序就可以看到调用服务返回的结果。&lt;/p&gt;</description></item><item><title>一个简单的WCF示例</title><link>https://fwhyy.com/2010/07/a-simple-wcf-example/</link><pubDate>Thu, 15 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/a-simple-wcf-example/</guid><description>&lt;p&gt;WCF程序分为三个部分：服务、宿主和客户端。下面就一步一步按这三个部分来构建一个简单的WCF程序。可以选择这三个部分都创建独立的解决方案，也可以在一个解决方案中创建三个项目。在下面的例子中将采用将三个项目放在一个解决方案中。服务使用类库项目，宿主和客户端使用控制台程序。&lt;/p&gt;</description></item><item><title>WCF的一些基本知识点</title><link>https://fwhyy.com/2010/07/some-basic-knowledge-of-wcf/</link><pubDate>Wed, 14 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/some-basic-knowledge-of-wcf/</guid><description>&lt;p&gt;Windows Communication Foundation (WCF)是Microsoft为构建面向服务的应用提供的分布式通信编程框架，是.NET Framework 3.5的重要组成部分。使用该框架，开发人员可以构建跨平台、安全、可靠和支持事务处理的企业级互联应用解决方案。&lt;/p&gt;
&lt;p&gt;构建一个WCF程序通常分为三个部分：服务类（Server）、宿主（Host）、客户程序（Client）。有一个很重要的程序集（System.ServeiceModel）要引用，它包含WCF的核心功能。&lt;/p&gt;
&lt;p&gt;贯穿整个WCF的程序会涉及到服务、契约、寄存、端点、地址、绑定、与数据、代理、通道、行为等概念，下面一一介绍下&lt;/p&gt;
&lt;h2 id="服务"&gt;服务&lt;/h2&gt;
&lt;p&gt;通常为一个类库项目，在实际开发中建议将服务类独立出来。服务类中封装业务功能并提供可以让外部访问的方法集接口。一些具体的操作通常抽像为接口然后由类来实现，并且接口上要用ServiceContractAtrribute来定义，接口中的方法要用OperationContractAttribute来定义，这样任何实现了该接口的类都是服务类型。当然也可以直接在类上来定义契约。&lt;/p&gt;
&lt;h2 id="契约"&gt;契约&lt;/h2&gt;
&lt;p&gt;契约定义了服务向外界发布的操作，以及WCF 服务与客户相互通讯时的消息格式。WCF 中有四种类型的契约。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;服务契约: 定义一个接口，给接口附加[ServiceContract] ，给接口方法附加[OperationContract]&lt;/li&gt;
&lt;li&gt;数据契约: 数据契约定义将在客户端与服务器端传送的各种数据类型。定义数据契约时需要使用[DataContract] 和[DataMember] 。&lt;/li&gt;
&lt;li&gt;消息契约: 可以使用消息契约来定制WCF 服务与WCF 客户间相互通讯的SOAP 消息格式。&lt;/li&gt;
&lt;li&gt;错误契约: 定义在服务中如何处理异常，以及这些异常又如何传送到客户端。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="寄存"&gt;寄存&lt;/h2&gt;
&lt;p&gt;服务做好了后需要能够运行，因为客户在调用服务的时候服务必须是处在运行状态的，这就需要将服务寄存在一个地方，在一些Demo中会使用控制台程序来做宿主寄存服务，除此之外还可以是WinForm程序、WPF应用、Windows 服务、IIS、WAS等。&lt;/p&gt;
&lt;h2 id="端点"&gt;端点&lt;/h2&gt;
&lt;p&gt;端点的用处是方便客户程序调用服务的操作。端点定义了在什么地方可以访问服务、用什么方式访问以及有哪些操作可用，这就是端点的三要素（地址 绑定 契约）。端点可以在程序中设置也可以用配置文件的形式设置。&lt;/p&gt;
&lt;h2 id="地址"&gt;地址:&lt;/h2&gt;
&lt;p&gt;地址由模式、域、端口和路径组成。模式指所用的传输协议如TCP、命名管线、HTTP、MSMQ等，WCF中针对这些协议的模式为net.tcp 、net.pipe、 http 、net.msmq。看下面例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;net.tcp://localhost:10000&lt;/li&gt;
&lt;li&gt;net.pipe://oec2003 [oec2003为机器名]&lt;/li&gt;
&lt;li&gt;http://localhost:10000&lt;/li&gt;
&lt;li&gt;net.msmq://localhost:10000&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;在ServerHost中加入多个端点时，需要为每个端点设置唯一的地址。&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="绑定"&gt;绑定&lt;/h2&gt;
&lt;p&gt;绑定描述了某一端点的协议支持。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP协议：BasicHttpBinding 、 WSHttpBinding 和WSFederationHttpBinding 。&lt;/li&gt;
&lt;li&gt;两个HTTP 通道实现双向通讯：WSDualHttpBinding。&lt;/li&gt;
&lt;li&gt;TCP协议：NetTcpBinding。&lt;/li&gt;
&lt;li&gt;P2P：NetPeerTcpBinding。&lt;/li&gt;
&lt;li&gt;命名管道：NamedPipeBinding。&lt;/li&gt;
&lt;li&gt;消息队列：NetMsmqBinding 和MsmqIntegrationBinding。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="元数据"&gt;元数据&lt;/h2&gt;
&lt;p&gt;这里元数据指的是服务中暴露的接口和服务端点的信息，客户依据这些元数据来生成代理调用服务。元数据可以通过两种方式被调用：1 ServiceHost可以公开一个元数据交换端点（IMetadataExchange）以便客户访问元数据；2 将元数据生成一个WSDL文档来描述端点和服务支持的协议。&lt;/p&gt;
&lt;h2 id="代理"&gt;代理&lt;/h2&gt;
&lt;p&gt;客户端是使用代理和服务通信。一个代理就是一个类型高开服务契约中的操作，客户调用时，对客户隐藏实现细节。客户端可以使用ChannelFactory或通过引用Web服务的方式来创建代理。&lt;/p&gt;
&lt;h2 id="通道"&gt;通道&lt;/h2&gt;
&lt;p&gt;通道是为了方便WCF中客户端和服务的通信而建立的。熟悉Remoting的朋友一定不会感到陌生。ServiceHost会为每一个端点创建一个通道侦听器，用来侦听客户端发送的消息。客户段和服务的两种信道必须相互兼容才能保持通信。&lt;/p&gt;
&lt;h2 id="行为"&gt;行为&lt;/h2&gt;
&lt;p&gt;行为会影响服务对消息的处理方式，当服务和端点确定了核心的通信需求以及和客户端之间共享了元数据后，当行为穿过信道栈时会改变消息的处理方式。行为可以在配置文件中进行配置。&lt;/p&gt;
&lt;p&gt;这些概念有的可能不太好理解，但在WCF的学习过程中会始终伴随着他们，也会随着我们不断的学习进而有较深入的理解。下面我就目前的理解对WCF的开发流程做个简单的总结：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;创建服务，这个通常是个类库项目，可以选择创建一个空的类库项目或是WCF Service Library。如果是创建的空的类库项目，则需要引用程序集System.ServeiceModel。&lt;/li&gt;
&lt;li&gt;在服务中创建服务契约和服务的操作，一般抽象为接口，ServiceContract和OperationContract标记定义在接口和接口中的方法上，然后创建类继承接口给出具体实现即可。&lt;/li&gt;
&lt;li&gt;服务需要寄存，必要要有宿主环境，可以根据需要自己选择任意一种，比如控制台程序。需要引用服务的程序集和System.ServeiceModel。然后就是配置端点和绑定。可以用程序的方式或是配置文件的方式。&lt;/li&gt;
&lt;li&gt;客户端可以是控制台程序、WinForm程序等。拿控制台程序来说吧，创建一个控制台程序，引用程序集System.ServeiceModel。在客户端可以使用ChannelFactory的方式或是通过添加服务引用的方式来创建代理。如果是使用ChannelFactory的方式创建代理，在客户端必须有服务契约的副本，可以将服务中的接口复制到客户端或是添加对服务的引用。创建代理时端点信息可以在程序中写也可以在配置文件中配置。&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>WCF中的ServiceHost初始化两种方式</title><link>https://fwhyy.com/2010/07/wcf-servicehost-initialization-in-two-ways/</link><pubDate>Tue, 13 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/wcf-servicehost-initialization-in-two-ways/</guid><description>&lt;p&gt;在宿主程序中初始化ServiceHost有直接写代码和使用配置文件两种方式。使用ServiceHost首先要引用System.ServiceModel 命名空间。&lt;/p&gt;
&lt;h2 id="代码方式"&gt;代码方式&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using(ServiceHost host=new ServiceHost(typeof(HelloWordService)))
{
 host.AddServiceEndpoint(typeof(IHelloWordService),
 new BasicHttpBinding(), new Uri(&amp;#34;http://localhost:10000/HelloWorldService&amp;#34;));
 host.AddServiceEndpoint(typeof(IHelloWordService),
 new NetTcpBinding(), new Uri(&amp;#34;net.tcp://localhost:10001/HelloWorldService&amp;#34;));

 if (host.State != CommunicationState.Opening)
 host.Open();
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="配置文件方式"&gt;配置文件方式&lt;/h2&gt;
&lt;p&gt;配置文件代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;services&amp;gt;
 &amp;lt;service behaviorConfiguration=&amp;#34;serverBehavior&amp;#34; name=&amp;#34;HelloWordService&amp;#34;&amp;gt;
 &amp;lt;endpoint address=&amp;#34;http://localhost:10000/HelloWorldService&amp;#34;
 binding=&amp;#34;basicHttpBinding&amp;#34; contract=&amp;#34;IHelloWordService&amp;#34;&amp;gt;&amp;lt;/endpoint&amp;gt;
 &amp;lt;endpoint address=&amp;#34;net.tcp://localhost:10001/HelloWorldService&amp;#34;
 binding=&amp;#34;netTcpBinding&amp;#34; contract=&amp;#34;IHelloWorldService&amp;#34;&amp;gt;&amp;lt;/endpoint&amp;gt;
 &amp;lt;/service&amp;gt;
&amp;lt;/services&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;当然也可以使用基地址的方式来配置&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;services&amp;gt;
 &amp;lt;service behaviorConfiguration=&amp;#34;serverBehavior&amp;#34; name=&amp;#34;HelloWordService&amp;#34;&amp;gt;
 &amp;lt;endpoint address=&amp;#34;HelloWorldService&amp;#34;
 binding=&amp;#34;basicHttpBinding&amp;#34; contract=&amp;#34;IHelloWordService&amp;#34;&amp;gt;&amp;lt;/endpoint&amp;gt;
 &amp;lt;endpoint address=&amp;#34;HelloWorldService&amp;#34;
 binding=&amp;#34;netTcpBinding&amp;#34; contract=&amp;#34;IHelloWorldService&amp;#34;&amp;gt;&amp;lt;/endpoint&amp;gt;
 &amp;lt;host&amp;gt;
 &amp;lt;baseAddresses&amp;gt;
 &amp;lt;add baseAddress=&amp;#34;http://localhost:10000/&amp;#34;/&amp;gt;
 &amp;lt;add baseAddress=&amp;#34;net.tcp://localhost:10001/&amp;#34;/&amp;gt;
 &amp;lt;/baseAddresses&amp;gt;
 &amp;lt;/host&amp;gt;
 &amp;lt;/service&amp;gt;
&amp;lt;/services&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;配置好配置文件后就宿主程序中就很简单了，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using(ServiceHost host=new ServiceHost(typeof(HelloWordService)))
{
 if (host.State != CommunicationState.Opening)
 host.Open();
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Windows Server 2008启用无线局域网支持</title><link>https://fwhyy.com/2010/07/windows-server-2008-enabled-wireless-lan-support/</link><pubDate>Tue, 13 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/windows-server-2008-enabled-wireless-lan-support/</guid><description>&lt;p&gt;公司的本装上Windows server 2008后无线网就不能用了，这对移动办公来说及其不方便，在网上搜了解决方法，记录如下：&lt;/p&gt;
&lt;p&gt;1 打开“服务器管理器”，如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290654272.webp" alt="2010-12-30_232936" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 选择“功能”，点击“添加功能”，在弹出的向导列表中勾选“无线 LAN 服务”进行安装。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290654092.webp" alt="2010-12-30_233139" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 安装成功后，无线网就可以正常使用了。&lt;/p&gt;</description></item><item><title>Zend Studio 7.2 汉化包 及安装方法</title><link>https://fwhyy.com/2010/07/zend-studio-7-2-localization-package-and-installation-method/</link><pubDate>Fri, 09 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/zend-studio-7-2-localization-package-and-installation-method/</guid><description>&lt;p&gt;Zend Studio 7.2 汉化包&lt;/p&gt;
&lt;p&gt;&lt;a href="http://download.csdn.net/source/2467231"&gt;点击下载&lt;/a&gt;
安装方法：&lt;/p&gt;
&lt;p&gt;下载解压后有features和plugins两个目录 ，将这两个目录中的文件复制到Zend Studio7.2安装目录中的对应文件夹中，重新启动Zend Studio即可。&lt;/p&gt;
&lt;p&gt;注：在复制文件前，建议将安装目录下的features和plugins两个目录备份下再进行复制。&lt;/p&gt;</description></item><item><title>Net Remoting Error:试图创建未绑定类型的代理</title><link>https://fwhyy.com/2010/07/net-remoting-error-try-to-create-unbounded-types-of-agent/</link><pubDate>Wed, 07 Jul 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/07/net-remoting-error-try-to-create-unbounded-types-of-agent/</guid><description>&lt;p&gt;在使用Net Remoting时 如果客户端程序出现“试图创建未绑定类型的代理”的错误时，只需将远程对象继承MarshalByRefObject类就可以解决了。&lt;/p&gt;</description></item><item><title>用GTalk机器人更新微博</title><link>https://fwhyy.com/2010/06/update-weibo-by-google-talk-robot/</link><pubDate>Wed, 30 Jun 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/06/update-weibo-by-google-talk-robot/</guid><description>&lt;p&gt;1 安装GTalk客户端，中文或英文都行，网上说英文的功能多些，不过使用中文版不影响使用机器人。&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href="http://www.google.com/talk/"&gt;http://www.google.com/talk/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;2 登录GTalk后，添加GTalk微博机器人&lt;a href="twitboo@appspot.com"&gt;twitboo@appspot.com&lt;/a&gt;为好友。&lt;/p&gt;
&lt;p&gt;3 打开对话窗口，输入-help，会出现帮助文字，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302140080.webp" alt="2010-12-30_233957" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;网上说该机器人可以支持QQ微博的，不过在帮助文字中并没有见到，不知道是不是现在已经取消支持了。&lt;/p&gt;
&lt;p&gt;4 绑定账号，这个在帮助文字中也写的很清楚，例如在聊天窗口中输入 -bind -s username pwd ，按回车后就会得到绑定账号成功的反馈消息。&lt;/p&gt;
&lt;p&gt;username 和 pwd 为 新浪微博得用户名和密码&lt;/p&gt;
&lt;p&gt;5 绑定好账号后再消息框输入消息发送后，你所有绑定的微博账号都会更新这条消息。&lt;/p&gt;</description></item><item><title>再去石家庄—2010-6-5</title><link>https://fwhyy.com/2010/06/go-to-shijiazhuang-2010-6-5/</link><pubDate>Thu, 10 Jun 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/06/go-to-shijiazhuang-2010-6-5/</guid><description>&lt;p&gt;石家庄这个被人们所遗忘的省会是我上大学的地方，在这个地方生活了4年，唯一让感觉比较好的地方就是逛街不用思考去哪儿，可以直奔主题，因为可逛的地方比较集中。&lt;/p&gt;
&lt;p&gt;上周末（2010-6-5），为了一件旧事我得去趟石家庄，老婆在家也没事，自然是一块跟去。由于之前被我描述的太差，下了火车一路从火车站走到博物馆，老婆还没太失望，甚至说比想象中的还要好。&lt;/p&gt;
&lt;p&gt;办完事，时间还很早，于是和老婆商量什么时候回京，当天回到北京有点晚，而且只有站票，最重要的是体现不出老婆过来的作用，貌似只是一个小陪同。最终买了第二天早上的票，也好让老婆感觉我们过来不只是办事，还可以让她在这边小逛一下，所幸的是逛的地方比较集中，要不一下午的时间还真不够。&lt;/p&gt;
&lt;p&gt;接下来就是吃午饭了，这午饭得好好说一下。在太和电子城旁边的一小小街，对这个街没什么好印象，03年买电脑时在这里差点被扒。找了一家生意还不错的做板面的小摊，价格比以前在学校时几乎翻番了，看来这几年国家的发展还真是很快。为什么会去吃板面呢？因为毕业后就没吃过了，武汉没有，刚到北京时在一同学借住，那同学住在京城有名的蚁族集居地–唐家岭，说是在村北边有一家做板面的，一日和同学兴致勃勃去找那家板面店来解决晚饭，到了之后发现变成一家牛肉拉面馆了，只好败兴而归。所以中午的那碗面先不说味道怎么样，总算是吃着了。老婆吃的油泼面，仅仅是因为以前没有吃过，最后竟然很神奇的吃完了，不得不佩服第一次的伟大。&lt;/p&gt;
&lt;p&gt;吃完饭自然是逛街了，东购、天元、福星阁等一通瞎逛后到了5点多了，就去找住的地方，直接杯具了，火车站对面的几家连锁酒店全部客满，这可是始料未及的，只能向旁边旧点的偏点的小旅馆发展了，最终花了140大洋住了一个很旧很大的标间，老婆一直都说还不如今天就回去，明显是感觉性价比极差嘛。&lt;/p&gt;
&lt;p&gt;晚饭是在一家号称全国连锁但从未听说的串串香吃的，吃完后发现此店颇有特色，可以说是有串串香特色的火锅也可以说是有火锅特色的串串香。酒足饭饱自然是要去休息了，这一天也够劳累的，和老婆抱抱睡了。&lt;/p&gt;
&lt;p&gt;火车时早上7点的，6点我和老婆就起来了，洗脸、刷牙、收拾东西、退房、去车站，我说整点早饭吃，老婆说北方早上除了饼还是饼，不想吃。没走几步，发现一炸油条的，老婆的眼睛放光了，奔过去就买了一根，北方人还是实在，同是1块钱，比武汉吃的要长不少。&lt;/p&gt;
&lt;p&gt;车上老婆躺在我怀里睡着了，一个周末起了两个大早，逛了一整天，能不累吗？不过我知道老婆是开心的！希望老婆一直都开心！&lt;/p&gt;
&lt;p&gt;ps：很遗憾，没有相机，要不可以图文并茂了&lt;/p&gt;</description></item><item><title>Net4.0—Web部署工具</title><link>https://fwhyy.com/2010/06/net-4-the-web-deployment-tool/</link><pubDate>Thu, 03 Jun 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/06/net-4-the-web-deployment-tool/</guid><description>&lt;h2 id="vs2008的web部署和vs2010的web部署"&gt;VS2008的Web部署和VS2010的Web部署&lt;/h2&gt;
&lt;p&gt;VS2010的Web部署工具相较于以前的版本做了很大的改进，下面先来看看VS2010和VS2008的Web部署工具的图片：&lt;/p&gt;
&lt;h3 id="vs2008"&gt;VS2008&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732166.webp" alt="2010-05-27_143737" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在VS2008种首先是弹出Publish Web对话框，点击选择路径按钮后弹出下图的对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732168.webp" alt="2010-05-27_143831" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在这个对话框中可以选择任意一种的发布方式。&lt;/p&gt;
&lt;p&gt;在VS2010中做了改进，将多个步骤封装在了一起，也称之为“一键部署”，让部署变得更加容易。如下图：&lt;/p&gt;
&lt;h3 id="vs2010"&gt;VS2010&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732962.webp" alt="2010-05-27_155506" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在VS2010的Web项目上点击右键选择Publish或是点击VS的工具条中的Publish（如下图）都可以弹出一键部署的对话框&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732949.webp" alt="2010-06-03_141655" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在Publish Web对话框中，通常我们需要填写下面几项内容&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Publish profile:这个是发布的名称&lt;/li&gt;
&lt;li&gt;Publish method：选择发布方式，有四种（Web Deploy、FTP、File System、FPSE）&lt;/li&gt;
&lt;li&gt;Server Url：如果在本地可以直接填写localhost&lt;/li&gt;
&lt;li&gt;Site/application：发布的站点的名称，在这里我们选择发布到本机的默认站点（Default Web Site）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;输入完成的对话框如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732196.webp" alt="2010-06-03_143525" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击右上角的Save按钮可以将当前设置保存以便以后使用，这些配置的信息存放在项目的根目录下的一个后缀为.Publish.xml的文件中，该文件的内容如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300732680.webp" alt="2010-06-03_150947" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击Publish按钮后会出现错误，原因是应用程序池的运行时版本不是4.0，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300733208.webp" alt="2010-05-27_142656" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;打开IIS7，修改默认站点的应用程序池的版本为4.0即可，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300733423.webp" alt="2010-05-27_143028" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300733426.webp" alt="2010-05-27_143107" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;修改完成后，重新发布就可以看到发布成功的提示。&lt;/p&gt;
&lt;h2 id="vs2010web项目中的webconfig文件"&gt;VS2010Web项目中的WebConfig文件&lt;/h2&gt;
&lt;p&gt;在VS2010中的Web项目的webconfig文件和以前版本不同，会多出来debug和release两个文件，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300733922.webp" alt="2010-06-03_151753" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这两个文件时对应我们在编译项目时是选择的Debug还是Release，可以适应Debug和Release两种模式不同的需求。并且我们还可以自己添加新的配置文件来适应不同的需求，比如说现在需要一个测试环境下的配置文件，可以按下面步骤做：&lt;/p&gt;
&lt;p&gt;1 打开Build-Configuration Manager对话框，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300733480.webp" alt="2010-06-03_152700" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 点击New在弹出的对话框中输入文件名称Testing&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300733835.webp" alt="2010-06-03_153418" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 点击OK按钮Testing就会出现在下拉框中，这时再看项目中的webconfig文件下仍然只有Debug和Release两个文件，新加的Testing没有出现。在webconfig文件上点击右键，选择Add Config Transforms，Testing配置文件就会出现了，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300734304.webp" alt="2010-06-03_153720" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300734204.webp" alt="2010-06-03_153834" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 我们可以通过修改不同的配置文件来达到在不同环境下的需求&lt;/p&gt;
&lt;h2 id="构建部署包"&gt;构建部署包&lt;/h2&gt;
&lt;p&gt;除了通过上面介绍的传统的方式发布Web程序外，还可以通过构建部署包的形式，在Web项目右击，会发现菜单中比以前版本多出来两项：&lt;/p&gt;
&lt;p&gt;1 Build Deployment Package：创建部署包&lt;/p&gt;
&lt;p&gt;2 Package/Publish Settings：创建部署包的设置&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300734292.webp" alt="2010-06-03_155336_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击Package/Publish Settings 和打开项目的属性然后选择Package/Publish Web的效果是一样的，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300734551.webp" alt="2010-06-03_155724" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;关于该界面中的各种配置选项，自行实验一下就都清楚了。配置好这些后，点击Build Deployment Package，就可以生成部署包了，部署包最终生成为一个zip文件，名称为项目名称。文件存放在项目下的obj\Testing\Package、obj\Debug\Package或obj\Release\Package下，这个要看是用那种模式进行发布的。&lt;/p&gt;
&lt;p&gt;构建了部署包之后只需要生成的zip文件就可以进行部署了，有两种方式可以部署：&lt;/p&gt;
&lt;p&gt;1 在zip文件的同目录下有个和项目同名，后缀为.deploy.cmd的文件，这是一个命令行的文件，执行文件中的一些脚本命令来进行部署，关于这种方式的部署设置在同目录下的ReadMe文件里有详细说明。这种方式的难度较大。&lt;/p&gt;
&lt;p&gt;2 第二种方式需要借助一个名为Web Deploy的第三方软件，可以点击此处&lt;a href="http://www.iis.net/download/webdeploy"&gt;下载&lt;/a&gt;，下载安装后，在IIS7的的站点上右击会多出“部署…”选项，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300734839.webp" alt="2010-06-03_164834" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们选择导入应用程序，弹出对话框中选择之前生成的zip文件，然后顺着下一步就行了，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300734339.webp" alt="2010-06-03_165355" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300735229.webp" alt="2010-06-03_165830_thumb" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300735872.webp" alt="2010-06-03_170326" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201300735255.webp" alt="2010-06-03_170442_thumb" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;完成后Web程序就会部署在IIS7中了。&lt;/p&gt;</description></item><item><title>SqlServer2008修改表时出现“save changes is not permitted…”解决方法</title><link>https://fwhyy.com/2010/06/sqlserver2008-modifying-a-table-save-changes-is-not-permitted-the-solution/</link><pubDate>Thu, 03 Jun 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/06/sqlserver2008-modifying-a-table-save-changes-is-not-permitted-the-solution/</guid><description>&lt;p&gt;最近使用SqlServer2008，发现在修改完表字段名或是类型后点击保存时会弹出一个对话框，对话框内容大致如下&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes to a table that can’t be re-created or enabled the option Prevent saving changes that require the table to be re-created&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302001803.webp" alt="2010-06-03_094326" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;如果点击 Save Text File ，会保存一个文本文件，感觉没什么作用，内容如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302001334.webp" alt="2010-06-03_095158" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击 Cancel 后会弹出另一个对话框，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302001972.webp" alt="2010-06-03_095243" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击OK就关闭了对话框，当然我们的修改肯定也没有保存上。&lt;/p&gt;
&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;p&gt;打开工具-选项，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302001623.webp" alt="2010-06-03_100942" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在选项对话框中选择：Designers—Table and DataBase Designers ，将右边的Prevent saving changes that require table re-creation 前的勾选去掉，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302001244.webp" alt="2010-06-03_101349" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击OK后，表的结构就可以随意修改保存了&lt;/p&gt;</description></item><item><title>给老婆做的记账小软件</title><link>https://fwhyy.com/2010/06/a-billing-software-to-my-wife/</link><pubDate>Wed, 02 Jun 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/06/a-billing-software-to-my-wife/</guid><description>&lt;p&gt;最近比较闲，根据老婆的需求利用上班时间花了一天多的时间做了一个家用记账小软件。现在网络上有那么的记账工具，为什么还要自己写呢？一来比较闲自己给自己找点事做，二来自己写的改动起来也方便点。下面就截几张图看看吧：&lt;/p&gt;</description></item><item><title>Net4.0—VS2010新特性</title><link>https://fwhyy.com/2010/05/net-4-vs2010-new-features/</link><pubDate>Thu, 27 May 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/05/net-4-vs2010-new-features/</guid><description>&lt;p&gt;VS2010在用户体验上有了很大提升，可以让我们更方便和快捷地来进行编码工作。早在VS2010Beta版的时候，我曾写过&lt;a href="http://blog.fwhyy.com/2009/10/experience-vs2010-improvements/"&gt;一篇文章&lt;/a&gt;介绍VS2010的一些新特性，此文算是对那篇文章的补充吧。&lt;/p&gt;
&lt;h2 id="1-方便地删除recent-projects"&gt;1 方便地删除Recent Projects&lt;/h2&gt;
&lt;p&gt;如果用VS2010打开过项目，那么在启动VS2010后，在Start Page页面的Recent Projects列表中会有记录，之前的VS版本中如果想删除Recent Projects列表记录，需要修改注册表信息，参考&lt;a href="http://blog.fwhyy.com/index.php/2007/12/delete-recently-opened-in-visual-studio-project-and-file-records/"&gt;这里&lt;/a&gt;。在VS2010中可以很方便做到对Recent Projects列表的管理，在某一个项目名称上右击，弹出菜单中会有Remove From List选项，点击后会将当前项目名从列表中删除，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300735497.webp" alt="2010-05-26_155027" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="2-navigate-to"&gt;2 Navigate to&lt;/h2&gt;
&lt;p&gt;Navigate to搜索对话框可以让我们方便地查找内容，并且可以模糊匹配。输入[Ctrl+，] 快捷键便可以打开Nagigate to 对话框，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300735950.webp" alt="2010-05-27_104536" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在Search terms框中输入关键词就可以进行模糊匹配，比如输入PL 就可以匹配到Page_Load事件，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300736023.webp" alt="2010-05-27_104755" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;双击结果中的方法名就可以导航到方法体中。&lt;/p&gt;
&lt;h2 id="3-同名函数的高亮显示"&gt;3 同名函数的高亮显示&lt;/h2&gt;
&lt;p&gt;在以前的VS版本中，要查找一个函数在页面中出现的次数或位置，有两种方法：Ctrl+F查找或是查找该函数的所有引用，这两种方法都不是很方便。在VS2010种新增了同名函数高亮显示功能，选中一个函数名，在同页中所有这个函数名出现的地方会高亮显示，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300736374.webp" alt="2010-05-27_103031" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="4-view-call-hierarchy"&gt;4 View Call Hierarchy&lt;/h2&gt;
&lt;p&gt;在一个方法名上右击，会有View Call Hierarchy选项，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300736242.webp" alt="2010-05-27_103504" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击后会打开一个试图，该试图可以方便看出该方法在那些地方被用到，传入的是什么参数，并且可以很快定位在引用的地方，对于一个代码行数比较多的文件，可以提高开发效率，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300736656.webp" alt="2010-05-27_111025" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;当然在VS2010中好玩的好用的新的功能肯定不止这些，让我们慢慢去发现吧！&lt;/p&gt;</description></item><item><title>Net4.0—Framwork新增特性</title><link>https://fwhyy.com/2010/05/net-4-framwork-of-new-features/</link><pubDate>Wed, 26 May 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/05/net-4-framwork-of-new-features/</guid><description>&lt;h2 id="1-biginteger"&gt;1 BigInteger&lt;/h2&gt;
&lt;p&gt;BigInteger是Net4.0种System.Numerics命名空间下的一个新类，表示任意大小的带符号整数。像以前版本中的Int32，int64等这些都有MinValue和MaxValue属性，也就是说有大小的限制，而BigInteger没有大小的限制，所以理论上来说大数字足够大时可能会出现OutOfMemoryException异常。&lt;/p&gt;
&lt;p&gt;以一个例子来看看BigInteger，下面的例子是一个计算斐波那契的函数：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public static int Fibonacci(int x)
{
 var preValue = -1;
 var curValue = 1;
 for (int i = 0; i &amp;lt;= x; ++i)
 {
 var sum = preValue + curValue;
 preValue = curValue;
 curValue = sum;
 }
 return curValue;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码当x的值为47的时候就会出现溢出，结果如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300729455.webp" alt="2010-05-26_105558" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;现在修改代码，使用BigInteger，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public static BigInteger Fibonacci(int x)
{
 var preValue = new BigInteger(-1);
 var curValue = new BigInteger(1);
 for (int i = 0; i &amp;lt;= x; ++i)
 {
 var sum = preValue + curValue;
 preValue = curValue;
 curValue = sum;
 }
 return curValue;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;再次将x赋值为47，运行结果如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300729877.webp" alt="2010-05-26_111127" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="2-complex"&gt;2 Complex&lt;/h2&gt;
&lt;p&gt;Complex通BigInteger一样也是在System.Numerics命名空间下。简单说就是一个计算复数的类。看下面例子&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private static void ComplexDemo()
{
 var z1 = new Complex(3, 4);
 var z2 = new Complex(5, 6);

 var r1 = Complex.Add(z1, z2);
 var r2 = Complex.Subtract(z1, z2);
 var r3 = Complex.Multiply(z1, z2);
 var r4 = Complex.Divide(z1, z2);

 Console.WriteLine(&amp;#34;Z1+Z2 :&amp;#34; + r1);
 Console.WriteLine(&amp;#34;Z1-Z2 :&amp;#34; + r2);
 Console.WriteLine(&amp;#34;Z1*Z2 :&amp;#34; + r3);
 Console.WriteLine(&amp;#34;Z1/Z2 :&amp;#34; + r4);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行结果如下图：&lt;/p&gt;</description></item><item><title>使用LoadRunner测试WMS</title><link>https://fwhyy.com/2010/05/using-loadrunner-test-wms/</link><pubDate>Fri, 21 May 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/05/using-loadrunner-test-wms/</guid><description>&lt;p&gt;LoadRunner是一款非常强大的测试工具，本文为笔者在对LoadRunner有了初步了解后对WMS的压力测试过程，因为接触时间比较短，不对之处欢迎大家指出。由于Licence的原因，对WMS的测试只支持最多100个虚拟用户。下面就开始测试了。&lt;/p&gt;
&lt;p&gt;1 要有一个可用的WMS的地址，可以在本机的流媒体服务中创建，也可以使用远程的。
2 打开LoadRunner8.1，并运行窗口中点击Create/Edit Srcirpts ,如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290657907.webp" alt="2010-05-20_150059" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在弹出的窗口中点击New VUser Scripts，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290657630.webp" alt="2010-05-20_150204" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 点击New VUser Script后，会弹出一个窗口让选择脚本协议，在这里我们选择Streaming下面的WMS，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290657385.webp" alt="2010-05-20_150235" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 确定后会在窗口中新开一个Lab页，该页面的左边为导航栏，标明了完成测试的5个步骤，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658818.webp" alt="2010-05-20_152114" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5 首先执行第一项创建脚本，在WMS中不能录制脚本所以只能手动来写了，有关WMS脚本的写法可以参考LoarRunner自带的帮助文档。点击Create Script，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658655.webp" alt="2010-05-20_150312" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 在右边出现的界面中点击Script View ，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658471.webp" alt="2010-05-20_150401" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;7 点击Srcipt View后就会出现脚本编辑区域，选择Action，在代码中添加启动WMS的代码，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658569.webp" alt="2010-05-20_150550" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;8 脚本写好之后就需要执行第二步来验证下脚本是否正确，或是是否能和指定的WMS地址相连接。点击左边的Verify Replay，在右侧的界面中点击Start Replay，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658124.webp" alt="2010-05-20_151032" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;9 通常会出现如下的错误，原因是在WMS的根目录（C:\wmpub\wmroot）下缺少wmload.asf文件，至于这个文件是做什么用的大家可以网上搜一下。随便找一个asf文件将名称改为wmload然后放在WMS的根目录即可。&lt;/p&gt;
&lt;p&gt;有可能添加wmload.asf文件后仍然不成功，有两个可能的原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;流媒体服务器没有默认的点播发布点，如果没有&lt;a href="http://www.cnblogs.com/oec2003/archive/2010/05/19/1739254.html"&gt;添加默认点播发布点&lt;/a&gt;，路径只想WMS根目录。&lt;/li&gt;
&lt;li&gt;默认点播发布点“拒绝新连接”了，选中“允许新连接”即可。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658097.webp" alt="2010-05-20_151115" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;10 这些都搞定后，重新验证会出现成功的界面。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290658265.webp" alt="2010-05-20_151742" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;11 点击上图中出现的Run-Time Settings 设置脚本的运行迭代次数等信息。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659546.webp" alt="2010-05-20_152032" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;12 设置好迭代次数后，就可以执行第三步了，不过第三步主要是设置事务和参数的，在本例中用不上，所以直接执行第四步，点击Concurrent User 出现如下界面：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659558.webp" alt="2010-05-20_152321" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;13 点击上图中Create Controller Scenario ，创建一个控制场景，在这之前会提示保存脚本信息，这里我们将脚本信息命名为TestWMS ，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659727.webp" alt="2010-05-20_152405" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;14 保存好脚本信息后，会弹出一个场景设置框，可以设置虚拟用户的个数，我们设置虚拟用户为100，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659640.webp" alt="2010-05-20_152432" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;15 点击确定后会弹出运行测试的窗口，在此窗口中点击 Edit Schedule 可以设置多用户是以什么形式并发的，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659921.webp" alt="2010-05-20_152519" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;16 点击上图中的 Edit Schedule 出现设置窗口，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659479.webp" alt="2010-05-20_152722" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;17 设置完成后，可以点击窗口右侧的Start Scenairo按钮开始运行测试，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659657.webp" alt="2010-05-20_152814" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;18 测试运行完成后，点击窗口上方的分析结果按钮来查看测试结果，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290659897.webp" alt="2010-05-20_152949" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;19 最后就可以根据结果来编写相应的测试报告了&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290700441.webp" alt="2010-05-20_153020" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;当然LoadRunner的功能远不止这些，本文只是测试WMS的一个非常简单的例子，希望对您有所帮助。&lt;/p&gt;</description></item><item><title>WMS中添加默认发布点</title><link>https://fwhyy.com/2010/05/add-the-default-distribution-point-wms/</link><pubDate>Wed, 19 May 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/05/add-the-default-distribution-point-wms/</guid><description>&lt;p&gt;当我们在服务器中安装了WMS后会自动创建一个默认的点播发布点，对应的目录为C:\WMPub\WMRoot，当然我们也可以根据需要更改。有这个默认发布点，就可以通过mms://ServerName/MediaName  这种方式来访问C:\WMPub\WMRoot目录中的音视频文件。&lt;/p&gt;</description></item><item><title>在批处理文件中启动MediaPlayer播放制定文件</title><link>https://fwhyy.com/2010/05/in-a-batch-file-to-start-the-mediaplayer-play-set-files/</link><pubDate>Wed, 05 May 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/05/in-a-batch-file-to-start-the-mediaplayer-play-set-files/</guid><description>&lt;p&gt;我们知道在运行可以使用wmplayer指令来启动一个MediaPlayer，如果需要让MediaPlayer播放制定的文件或是一个制定的流媒体发布点，我们可以使用如下的命令格式&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;wmplayer “mms://WIN-FW.MiGu.com/12530”
wmplayer “C:\wmpub\wmroot\legacy_content_clip.wmv”
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;但是在运行中来执行命令需要手动去控制，如果将命令写到批处理文件中，就可以通过计划任务等一些手段来动态控制它的执行。&lt;/p&gt;
&lt;p&gt;做批处理文件非常简单，将文本文件的后缀改成bat即可，然后保存上面的内容在文件中，双击就可以执行。不过此时双击会发现并不能启动MediaPlayer，因为缺少了一个步骤。只需将C:\Program Files (x86)\Windows Media Player目录下的wmplayer.exe文件复制到C:\Windows\System32目录下即可。&lt;/p&gt;
&lt;p&gt;注:上面的路径C:\Program Files (x86)\Windows Media Player为64位系统下的路径，如果是32位系统则为C:\Program Files\Windows Media Player&lt;/p&gt;</description></item><item><title>来北京的这些日子</title><link>https://fwhyy.com/2010/04/in-beijing-these-days/</link><pubDate>Fri, 30 Apr 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/04/in-beijing-these-days/</guid><description>&lt;p&gt;时间真的过得很快，已经来北京近两个月了，工作也已经1个月了。本来早就应该记录点这边的生活点滴，苦于一直都在忙于找工作和找到工作后的适应工作中，直到现在才稍微清闲一点，回忆着记录点这两月的点点滴滴吧。&lt;/p&gt;
&lt;h2 id="游玩"&gt;游玩&lt;/h2&gt;
&lt;p&gt;3月初从家里出发来的北京，这次上京并没有背井离乡的感觉，因为是同父母一起来的，当然他们并不是送我而是来北京旅游，正好我那会也处于待业状态有时间和他们到处转转。到京和我妹会合了后一家人就算是团聚了，这种感觉很好。记忆中从我妹毕业来北京工作后就很少有这种一家人团聚的时候。&lt;/p&gt;
&lt;p&gt;因为有10天的时间，所以每天的安排都不是很紧凑，基本上每天都只去一个景点，然后就是去商场超市逛逛。快乐的时光总是感觉很短暂，更何况10天的时间并不是很长。送走我爸妈和我妹走在北京的大街上感觉到有点伤感。&lt;/p&gt;
&lt;h2 id="找工作"&gt;找工作&lt;/h2&gt;
&lt;p&gt;我爸妈回家了，我也就不能住在酒店了，也要开始找工作了。拖着行李到一同学那里借住。3月15日的上午正式开始投简历，根据我的经验在上午9点到10点投简历时比较好的，投了15份左右，剩下来要做的就是等面试通知了。由于第一次来北京找工作，心里还真是没底，不过我对自己还是很有自信的。尽管如此等面试通知的时间还是比较难熬的。没想到的是15好的下午就收到了A公司的面试通知，A公司是一家很大的公司，在行业内也很有知名度，面试也不能免俗，上来就是一套笔试题，笔试题做得不怎么样，不过后面和面官谈的还行，让我再准备准备回去等去客户那边面试的通知，这时才知道是驻地开发的那种形式，一个礼拜后接到了A公司去复试的通知，客户那边是个网络公司，去了之后大厅的前台坐着三位漂亮的女士让我印象比较深刻。经过两轮面试算是通过了，不过我对他们工作的内容兴趣不是很大，一是做的东西比较简单挑战性不是很大，二是要涉及很多前台界面的东西。因为考虑到B公司的复试，我这边没有马上答复。&lt;/p&gt;
&lt;p&gt;B公司是一家关于医疗教育方面的公司，工作内容主要是做他们自己的平台。公司也很正规，面试流程及其复杂，先后被四人面过，中间又是智力测试又是性格分析测试的。最终总算是过五关斩六将顺利通过了。同A公司一样都是让我下周一去上班，当时对比了一下决定去B公司，因为工作内容相较于A公司更喜欢。就在我高兴自己已经找到工作的时候，手机响了，是C公司打来的，这次应该是C公司第三次打来了，前两次因为面试排不开了都让我给往后延了。最后定在第二天的下午3点。&lt;/p&gt;
&lt;p&gt;C公司是一家跟微软合作的公司，承接的都是一些电信、移动、联通的比较大的项目，而且公司内是微软的一些工程师直接带项目。这些都很吸引我，不过他们的招聘要求上写着要熟悉流媒体，而我对流媒体没怎么接触过，自己感觉肯定不行，所以也不是很重视。之所以答应去面试当时还是处于一种礼貌的考虑。面试时没有笔试，面官和我聊了一些以前做过的一些项目，随后问了我很多关于我个人博客的事情，最后我也了解到面官也是湖北人。这次的面试很轻松也聊得很愉快，给我的答复是基本没什么问题，不过等通知下周还要来一次。当时特别犹豫不知道怎么选择了，如果放弃A和B，C我又不是有100%的把握，但是C公司是我最想去的公司，再三考虑后我觉定赌一把决定推掉A和B等C的通知。几天后C公司的电话终于来了，我也很顺利进入了C公司，为此我很高兴。&lt;/p&gt;
&lt;p&gt;当然，找工作这么久当然不止面过这么三个公司，其中大大小小的公司也不少，有的需要长期在外面出差，有的嫌我的技术不怎么样说是连他们公司最初级的程序员都不如，也有我觉得公司环境氛围不怎么好的。十几天的时间找到工作也没有让我在这个城市感到很寂寞。上班那天是在4月1日，我当时就想会不会是公司跟我开的个玩笑呢。&lt;/p&gt;
&lt;h2 id="适应工作"&gt;适应工作&lt;/h2&gt;
&lt;p&gt;来到一个新的公司，面对全新的工作，必然有一个适应的过程，到现在已经1个月了，我感觉已经适应了，时间显得稍长了点。我喜欢技术，喜欢新的东西，喜欢挑战，来到这儿后我觉得当初赌一把没有赌错，在这里能学到很多东西，而且有很多东西需要我去学习。就拿这一个月来说，像WMS 、AD、Win2008、HPServer、TFS等等都由没怎么接触过到已经慢慢熟悉，我很欣喜，每天都感觉很充实，相信以后会遇到更多的挑战，更多的困难，当然也会学习到更多的东西。&lt;/p&gt;
&lt;h2 id="感情"&gt;感情&lt;/h2&gt;
&lt;p&gt;女朋友为了我辞掉了武汉的很舒服的工作来到了北京，对此我很感动。2010年4月3日我偷跑到站台上接她的情景还历历在目。这些日子以来我每天都感觉很幸福，除了有个比较满意的工作更重要的是能有她陪在我的身边。很多的画面时常会浮现脑中，惠新西街南口的地铁站；一起裹在被子里面看电视；一起去楼顶上晾衣服；一起走在北京的大街小巷；早上6点多就起床一起去上班。但幸福的背后也会有一些不愉快的东西，对北京的印象和以前的向往又落差；对北方的气候的极度不适应；在一朋友介绍进去的公司里面受到的委屈；面临重新找工作的心理障碍。万事开头难，我相信我们在一起能克服任何困难。一起加油！！！&lt;/p&gt;
&lt;p&gt;现在这个时候她应该正在去面试的路上，希望她下午的面试顺利，好好地度过51小长假。&lt;/p&gt;</description></item><item><title>Win2008计算机不能添加到域的解决方法</title><link>https://fwhyy.com/2010/04/win2008-computer-cannot-be-added-to-the-domain-of-the-solution/</link><pubDate>Wed, 28 Apr 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/04/win2008-computer-cannot-be-added-to-the-domain-of-the-solution/</guid><description>&lt;p&gt;最近接触了一点win2008活动目录，所谓万事开头难，本来很简单的事情在刚刚接触时就很费劲。&lt;/p&gt;
&lt;p&gt;在远程的一台机子上成功安装了AD后，想将本机添加到域中，试了很多次都不行，出现下面的错误：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290645332.webp" alt="2010-04-28_114731" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;查了很久的msdn文档，说的都不是很清楚，也许是我对dns的理解不够深入，最后得知原来是dns的指向问题。假如安装了AD的机子的IP为192.168.1.50，就将需要添加到域中的机子的dns设置为192.168.1.50，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290645237.webp" alt="2010-04-28_114829" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;设置好了dns后，再添加计算机到域，就可以出现登录框了：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290646257.webp" alt="2010-04-28_114936" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;输入用户名和密码就会出现欢迎窗口了：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290646603.webp" alt="2010-04-28_115054" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>Win2008远程桌面安装AD后的登录问题解决</title><link>https://fwhyy.com/2010/04/win2008-remote-desktop-installation-ad-after-log-in-problem-solving/</link><pubDate>Tue, 27 Apr 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/04/win2008-remote-desktop-installation-ad-after-log-in-problem-solving/</guid><description>&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;p&gt;本机操作系统为Win2008 ，远程连接的两台机子A和B的的系统也都为Win2008。先远程连接B，然后在B中远程连接A，在A上安装了AD，安装完要求重启A，A重启后再远程连接A，输入正确的密码不能登录了&lt;/p&gt;
&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;p&gt;其实很简单，将B添加到域中，然后重启B就可以了&lt;/p&gt;</description></item><item><title>要相信自己</title><link>https://fwhyy.com/2010/04/believe-in-yourself/</link><pubDate>Thu, 22 Apr 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/04/believe-in-yourself/</guid><description>&lt;p&gt;尽管现在是处在一个陌生的城市
尽管被一个狗屁垃圾虾王挫折了一番
尽管没了的言语让你对这个城市失去了信心
这些都不重要
你的生活才刚刚开始
前面要走的路还很长很长
你的倔强应该用来对付前进路上的那些障碍
相信自己你可以的&lt;/p&gt;
&lt;p&gt;尽管我们在一起的时间还很短很短
尽管我在你的面前就像玻璃一样的透明
尽管来到这个城市我带了很多不应该带的东西
这些也都不重要
人不能老是活在回忆里
以前的点滴相对于以后的时光将会变得十分渺小
相信我也相信你自己&lt;/p&gt;
&lt;p&gt;一起加油
我们的未来会很精彩&lt;/p&gt;</description></item><item><title>使用Expression Encoder 3发布媒体文件到WebDAV</title><link>https://fwhyy.com/2010/04/use-expression-encoder-3-to-webdav-publishing-media-file/</link><pubDate>Tue, 20 Apr 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/04/use-expression-encoder-3-to-webdav-publishing-media-file/</guid><description>&lt;h2 id="使用环境"&gt;使用环境&lt;/h2&gt;
&lt;p&gt;Windows Server 2008&lt;/p&gt;
&lt;p&gt;IIS7.0 Microsoft&lt;/p&gt;
&lt;p&gt;Expression Encoder3&lt;/p&gt;
&lt;h2 id="准备"&gt;准备&lt;/h2&gt;
&lt;p&gt;在IIS7.0中没有自带WebDAV，可以通过下面的链接进行下载安装，后两个为补丁。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=036269fa-0040-4ccd-ad3d-78da1ee132fb&amp;amp;DisplayLang=en"&gt;Microsoft WebDAV Extension for IIS 7.0 (x86)&lt;/a&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=13e97aaa-fb1b-4cf8-b95f-19ae02321385&amp;amp;DisplayLang=en"&gt;Microsoft WebDAV Extension for IIS 7.0 (x64)&lt;/a&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=567cb0d6-3e94-4035-a79d-22d1ef307d5e&amp;amp;DisplayLang=en"&gt;Update for WebDAV Extension for IIS 7.0 (KB955137) (x86)&lt;/a&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=31fc62d7-abd0-4ac0-b727-d5ef0a50f8cc&amp;amp;DisplayLang=en%5B/url%5D"&gt;Update for WebDAV Extension for IIS 7.0 (KB955137) (x64)&lt;/a&gt;
&lt;a href="http://www.iis.net/download/SmoothStreaming"&gt;Smooth Streaming（x86 x64）&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="安装"&gt;安装&lt;/h2&gt;
&lt;p&gt;根据个人的电脑系统选择下载的安装包进行安装，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302145621.webp" alt="2010-04-20_161454" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;安装WebDAV&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302145136.webp" alt="2010-04-20_171133" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;安装Smooth Streaming&lt;/p&gt;
&lt;p&gt;设置及使用&lt;/p&gt;
&lt;p&gt;安装好WebDAV后，打开“Internet 信息服务（iis）管理器”，新建一个Web站点TestEncoder ，指向D://TestEncoder目录。点击新建的站点在功能区会看到“WebDAV Authoring Rules ” 选项，如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302145071.webp" alt="2010-04-20_162328" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;双击[WebDAV Authoring Rules ]项，右边的操作界面如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302145211.webp" alt="2010-04-20_162540" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;首先点击Disable WebDAV 启用WebDAV，然后点击Add Authoring Rule… 添加规则，下图仅供参考，具体设置根据实际应用来&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302145721.webp" alt="2010-04-20_162726" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再点击WebDAV Settings进行设置，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302141853.webp" alt="2010-04-20_162950" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;设置好了后点击“应用”就可以了。&lt;/p&gt;
&lt;p&gt;到目前为止已经将WebDAV安装好了，不过还要对站点TestEncoder进行一些设置才可以：&lt;/p&gt;
&lt;p&gt;a 点击站点TestEncoder，在中间功能板块中双击“身份验证”，然后启用“windows 身份验证”。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302141337.webp" alt="2010-04-20_170732" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;b 点击站点TestEncoder，在中间功能板块中双击“目录浏览”，然后启用目录浏览。&lt;/p&gt;
&lt;p&gt;现在就开始完成发布过程。&lt;/p&gt;
&lt;p&gt;1 打开Expression Encoder3 ，新建一个JOb，名为为TestWebDAV，在媒体内容区域点击“导入”从本地选择一个媒体文件。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302141614.webp" alt="2010-04-20_164233" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在“编码”面板中选择输出格式为“IIS Smooth Streaming ” 。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302141082.webp" alt="2010-04-20_165100" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 在“输出”面板中，任意选择一个模板，这个模板是Silvelight播放器的样式的模板，选择后再下方会有一个效果的预览视频。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302141363.webp" alt="2010-04-20_165319" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 在“输出”面板中展开“发布”节点，设置如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302141560.webp" alt="2010-04-20_170127" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5 在“媒体内容”面板中点击“编码”，首先是对媒体文件进行编码，编码完成后就会直接发布到先前创建的站点TestEncoder 中。通过地址&lt;a href="http://192.168.1.160:8080/TestWenDAV/default.html"&gt;http://192.168.1.160:8080/TestWenDAV/default.html&lt;/a&gt; 可以直接访问了。&lt;/p&gt;</description></item><item><title>HTTP 错误 500.19 – Internal Server Error 错误解决方法</title><link>https://fwhyy.com/2010/04/http-error-500-19-internal-server-error-solution/</link><pubDate>Thu, 15 Apr 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/04/http-error-500-19-internal-server-error-solution/</guid><description>&lt;p&gt;刚在本机部署了一个WebService测试，浏览的时候出现了“HTTP 错误 500.19 – Internal Server Error ”错误，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300701743.webp" alt="2010-04-15_134600" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;经过检查发现是由于先安装vs2008后安装iis的缘故，只需重新注册下AspNet就可以了，具体步骤如下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;打开运行，输入cmd进入到命令提示符窗口。&lt;/li&gt;
&lt;li&gt;进入到C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 目录。&lt;/li&gt;
&lt;li&gt;输入aspnet_regiis.exe –i 执行既可&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注意：如果系统为64位 第二步的路径为C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727&lt;/p&gt;</description></item><item><title>Asp.Net控件开发(1)—入门介绍</title><link>https://fwhyy.com/2010/02/aspnet-controls-development-1-the-introduction/</link><pubDate>Tue, 09 Feb 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/02/aspnet-controls-development-1-the-introduction/</guid><description>&lt;p&gt;AspNet为我们提供了很多的控件，尽管如此，很多时候我们还是会感觉这些控件不够用，想根据自己的需求去定制一些控件，比如想在DropDownList控件中实现可以输入，AspNet并没有为我们提供这样的控件，这时就需要我们去编写自定义控件来满足需要。 本系列文章打算对AspNet控件开发做个入门级介绍，如果想了解更详细和深入可以参考&lt;a href="http://www.douban.com/subject/2268475/"&gt;《深入解析ASP.NET 2.0控件开发》&lt;/a&gt;和&lt;a href="http://www.douban.com/subject/3626223/"&gt;《纵向切入ASP.NET 3.5控件和组件开发技术》&lt;/a&gt;这两本书。&lt;/p&gt;
&lt;p&gt;言归正传，通常我们开发自定义控件会创建一个类库项目，编写完代码后编译会生成一个dll文件，这个dll文件就是我们自己开发的控件了。假设现在已经有一个名为HelloWorld.dll的控件，按照下面方法可以将该控件用在我们的项目中。&lt;/p&gt;
&lt;p&gt;1 在工具箱中点击右键-&amp;gt;添加选项卡。选项卡可以任意命名，比如：MyControls&lt;/p&gt;
&lt;p&gt;2 在新添加的选项卡区域中右键-&amp;gt;选择项。选择HelloWorld.dll文件后确定，会看到控件已经添加到工具箱中，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290824855.webp" alt="2010-12-28_235751" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 使用自定义控件和使用普通的AspNet控件一样，直接拖到页面中即可。将该控件拖入到页面中后，源视图中会添加如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;%@ Register Assembly=&amp;#34;ControlsDemo1&amp;#34; Namespace=&amp;#34;ControlsDemo1&amp;#34; TagPrefix=&amp;#34;cc1&amp;#34; %&amp;gt;

 &amp;lt;cc1:HelloWorld ID=&amp;#34;HelloWorld2&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;/cc1:HelloWorld&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面代码的第一行是注册该控件，TagPrefix属性指定控件的前缀，cc1是系统默认的前缀，我们也可以根据自己的喜好来自定义前缀，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;%@ Register Assembly=&amp;#34;ControlsDemo1&amp;#34; Namespace=&amp;#34;ControlsDemo1&amp;#34; TagPrefix=&amp;#34;oec2003&amp;#34; %&amp;gt;
 &amp;lt;oec2003:HelloWorld ID=&amp;#34;HelloWorld1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;/oec2003:HelloWorld&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&amp;lt;%@ Resgiter /&amp;gt;&lt;/code&gt;指令只是在单个页面中使用，我们还可以通过在web.config中配置来使全局都能够使用。web.config配置如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;system.web&amp;gt;
 &amp;lt;pages&amp;gt;
 &amp;lt;controls&amp;gt;
 &amp;lt;add assembly=&amp;#34;ControlsDemo1&amp;#34; namespace=&amp;#34;ControlsDemo1&amp;#34; tagPrefix=&amp;#34;oec2003&amp;#34;/&amp;gt;
 &amp;lt;/controls&amp;gt;
 &amp;lt;/pages&amp;gt;
&amp;lt;/system.web&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面简单介绍了怎样使用一个已经编写好的自定义控件，并且知道编写一个自定义控件通常是创建一个类库项目。现在就来看看一个自定义控件的具体实现方法。&lt;/p&gt;
&lt;p&gt;实现一个自定义控件，我们需要选择一个基类，这些基类有控件需要的最基本的功能，下面的三个类就是开发控件常用的基类。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;System.Web.UI.Control
System.Web.UI.WebControls.WebControl
System.Web.UI.WebControls.CompositeControl
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Control：控件开发的基类，所有控件都直接或间接继承该类。该类的扩展性和灵活性最强。&lt;/li&gt;
&lt;li&gt;WebControl：该类继承自Control类，除了有Control的所有属性外，还提供布局样式等特性。比较适合对布局和外观样式要求较高的控件。和Control相同的是都适用于开发单个控件。&lt;/li&gt;
&lt;li&gt;CompositeControl：该类为AspNet2.0提供的一个控件基类。如果想把现有控件组合起来创建一个组合控件时，可以继承此类，此类继承了WebControl并实现了INamingContainer接口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果我们只是对某一个现有的AspNet控件进行简单的扩充，我们可以用现有的任一控件作为基类。&lt;/p&gt;
&lt;p&gt;Control类最基础灵活性最强，那么就先以Control类为基类实现一个简单的HelloWorld控件。在新建的项目中创建一个类HelloWorld，继承Control，并重写Render方法，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class HelloWorld:Control
{
 protected override void Render(HtmlTextWriter writer)
 {
 writer.WriteLine(&amp;#34;hello world!&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;编译后按照上面介绍的方法添加到工具箱中，然后拖到页面，运行后会在页面上呈现Hello world文本。现在对上面的代码做点改动让hello world文本的显示区加上边框和背景色，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class HelloWorld:Control
{
 protected override void Render(HtmlTextWriter writer)
 {
 writer.WriteLine(@&amp;#34;&amp;lt;div style=&amp;#34;&amp;#34;width:200px;height:100px;
 border:1px solid #4DA9C2;background-color:#C3D9FF&amp;#34;&amp;#34; &amp;gt;&amp;#34;);
 writer.WriteLine(&amp;#34;hello world!&amp;#34;);
 writer.WriteLine(@&amp;#34;&amp;lt;/div&amp;gt;&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行后的效果：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290825971.webp" alt="2010-12-28_235833" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;效果虽然出来了，但是代码中是使用直接输出html代码和内嵌样式的方式，这样做当然是不好的，不是很好扑捉错误并且生成到客户端的html代码格式也不好。这个问题我们可以通过HtmlTextWriterAttribute、HtmlTextWriterTag、HtmlTextWriterStyle这三个枚举来解决。看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class HelloWorld:Control
{
 protected override void Render(HtmlTextWriter writer)
 {
 writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, &amp;#34;1px&amp;#34;);
 writer.AddStyleAttribute(HtmlTextWriterStyle.BorderStyle, &amp;#34;solid&amp;#34;);
 writer.AddStyleAttribute(HtmlTextWriterStyle.BorderColor, &amp;#34;#4DA9C2&amp;#34;);
 writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, &amp;#34;#C3D9FF&amp;#34;);
 writer.AddStyleAttribute(HtmlTextWriterStyle.Width, &amp;#34;200px&amp;#34;);
 writer.AddStyleAttribute(HtmlTextWriterStyle.Height, &amp;#34;100px&amp;#34;);
 writer.RenderBeginTag(HtmlTextWriterTag.Div);

 writer.WriteLine(&amp;#34;hello world!&amp;#34;);

 writer.RenderEndTag();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行后效果和上面一样。并且查看页面的源代码可以看出用这种方式生成的html有规范的缩进，并且代码也是符合xhtml规范的，所以建议尽量使用这种方式而不是直接拼写html代码。&lt;/p&gt;</description></item><item><title>jQuery 1.4.1 VS智能提示文件下载</title><link>https://fwhyy.com/2010/02/jquery-1-4-1-vs-intellisense-file-downloads/</link><pubDate>Tue, 09 Feb 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/02/jquery-1-4-1-vs-intellisense-file-downloads/</guid><description>&lt;p&gt;vs2008中默认的jquery版本为1.3.2 ，我在 &lt;a href="http://blog.fwhyy.com/posts/87"&gt;在vs2008中设置jquery智能提示&lt;/a&gt; 一文中做了详细介绍。主要是靠一个vsdoc文件实现。在vs2010中默认的jquery的版本为1.4.1，现在已经又相对应的vsdoc文件下载，设置方法与vs2008中相同。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://code.jquery.com/jquery-1.4.1-vsdoc.js"&gt;点击此处下载&lt;/a&gt;
更多详细介绍参考&lt;a href="http://weblogs.asp.net/scottgu/archive/2010/02/08/jquery-1-4-1-intellisense-with-visual-studio.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2010/02/08/jquery-1-4-1-intellisense-with-visual-studio.aspx&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Asp.Net MVC 2 RC 2 发布</title><link>https://fwhyy.com/2010/02/aspnet-mvc-2-rc-2-release/</link><pubDate>Fri, 05 Feb 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/02/aspnet-mvc-2-rc-2-release/</guid><description>&lt;p&gt;刚刚在&lt;a href="http://weblogs.asp.net/scottgu/default.aspx"&gt;ScottGu&lt;/a&gt;的blog上看到了ASP.NET MVC 2 RC 2发布的消息，该版本的IDE只支持VS2008.在该版本中修复了一些bug，并添加修改了一些API。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=7aba081a-19b9-44c4-a247-3882c8f749e3&amp;amp;displaylang=en"&gt;点击下载&lt;/a&gt;
有关此版本详细的介绍请看ScottGu的博文 。&lt;/p&gt;
&lt;p&gt;博客园的SZW对该文进行了翻译 ：&lt;a href="http://www.cnblogs.com/szw/archive/2010/02/05/1664704.html"&gt;http://www.cnblogs.com/szw/archive/2010/02/05/1664704.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;当然也可以稍后访问&lt;a href="http://blog.joycode.com/scottgu"&gt;ScottGu博客&lt;/a&gt;中文版进行了解&lt;/p&gt;</description></item><item><title>设计模式笔记(25)—总结</title><link>https://fwhyy.com/2010/02/design-patterns-notes-25-summary/</link><pubDate>Wed, 03 Feb 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/02/design-patterns-notes-25-summary/</guid><description>&lt;p&gt;断断续续经历了几个月的时间将WebCast的设计模式讲座重新完整听了一遍，并做了笔记，才有了这个设计模式笔记系列，本系列的文章大部分只是给出了基本代码的实现，而并没有去衍生其他的一些例子，笔者认为通过基本的代码实现就能够了解到模式的应用场景，弄出些花哨的例子反倒会让人眼花缭乱，可能并达不到预期的效果，毕竟在实际的应用中我们不是去套用模式。本文作为该系列的最后一篇，将对设计模式做个总结。&lt;/p&gt;
&lt;p&gt;首先看下创建型、结构型、行为型这三种类型的模式的解释&lt;/p&gt;
&lt;h2 id="创建型"&gt;创建型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Singleton模式解决的是实体对象个数的问题。除了Singleton之外，其他创建型模式解决的都是new所带来的耦合关系。&lt;/li&gt;
&lt;li&gt;Factory Method, Abstract Factory, Builder都需要一个额外的工厂类来负责实例化“易变对象”，而 Prototype则是通过原型 （一个特殊的工厂类）来克隆“易变对象”。&lt;/li&gt;
&lt;li&gt;如果遇到“易变类”，起初的设计通常从FactoryMethod开始，当遇到更多的复杂变化时，再考虑重构为其他三种工厂模式 （Abstract Factory 、Builder 、Prototype ）。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="结构型"&gt;结构型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Adapter模式注重转换接口，将不吻合的接口适配对接。&lt;/li&gt;
&lt;li&gt;Bridge模式注重分离接口与其实现，支持多维度变化。&lt;/li&gt;
&lt;li&gt;Composite模式注重统一接口，将“一对多”的关系转化为“一对一”的关系。&lt;/li&gt;
&lt;li&gt;Decorator模式注重稳定接口，在此前提下为对象扩展功能。&lt;/li&gt;
&lt;li&gt;Façade模式注重简化接口，简化组件系统与外部客户程序的依赖关系。&lt;/li&gt;
&lt;li&gt;Flyweight 模式注重保留接口，在内部使用共享技术对对象存储进行优化。&lt;/li&gt;
&lt;li&gt;Proxy 模式注重假借接口，增加间接层来实现灵活控制。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="行为型"&gt;行为型&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Template Method模式封装算法结构，支持算法子步骤变化。&lt;/li&gt;
&lt;li&gt;Strategy模式注重封装算法，支持算法的变化。&lt;/li&gt;
&lt;li&gt;State模式注重封装与状态相关的行为，支持状态的变化。&lt;/li&gt;
&lt;li&gt;Memento模式注重封装对象状态变化，支持状态保存/恢复。&lt;/li&gt;
&lt;li&gt;Mediator模式注重封装对象间的交互，支持对象交互的变化。&lt;/li&gt;
&lt;li&gt;Chain Of Responsibility模式注重封装对象责任，支持责任的变化。&lt;/li&gt;
&lt;li&gt;Command模式注重将请求封装为对象，支持请求的变化。&lt;/li&gt;
&lt;li&gt;Iterator 模式注重封装集合对象内部结构，支持集合的变化。&lt;/li&gt;
&lt;li&gt;Interpreter模式注重封装特定领域变化，支持领域问题的频繁变化。&lt;/li&gt;
&lt;li&gt;Observer模式注重封装对象通知，支持通信对象的变化。&lt;/li&gt;
&lt;li&gt;Visitor模式注重封装对象操作变化，支持在运行时为类层次结构动态添加新的操作。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="设计模式应用总结"&gt;设计模式应用总结&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;设计模式建立在对系统变化点的基础上进行，哪里有变化点，哪里应用设计模式。&lt;/li&gt;
&lt;li&gt;设计模式应该以演化的方式来获得，系统的变化点往往是经过不断演化才能准确定位。&lt;/li&gt;
&lt;li&gt;不能为了模式而模式，设计模式是一种软件设计的软力量，而非规范标准。不应夸大设计模式的作用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面的大部分内容都为讲座中的内容，并没有做更多的改动，因为那些概况已经非常简明扼要。软件发展到今天，可以说远远不止这23中模式，只是常常被大家所提及的是这23中经典而已。这些模式的提出时因为软件的需求总是在发生变化，如果说不存在需求的变化，那么设计模式也就没有存在的必要了。这种情况是不可能存在，所以为了在需求变化的时候能够很好的应对，提供代码复用，降低成本就需要应用设计模式。所以说设计模式并不是在软件设计之初就存在，而是随着需求的变化一步一步重构而来的。&lt;/p&gt;
&lt;p&gt;设计模式虽然很多，但万变不离其宗，不管怎么变都脱离不了5大设计原则（SRP OCP LSP DIP ISP），掌握了这五大设计原则，勤思考多实践，那么在项目中遇到变化时就可以灵活运行设计模式了。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SqlServer数据库的语句及一些操作整理</title><link>https://fwhyy.com/2010/02/some-tips-of-sqlserver/</link><pubDate>Tue, 02 Feb 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/02/some-tips-of-sqlserver/</guid><description>&lt;p&gt;临近年终，在工作之余对工作和学习中遇到的问题以及常用的一些知识点做了些整理，以备后用。本文涉及的内容为数据库,算是对开发总结(1)—数据库一文的补充。&lt;/p&gt;
&lt;p&gt;1 对于主键设置了Identity的表，在删除表中数据后再往表中插入数据，Identity列不是从1起始了，如果想删除数据后Indentity列仍从1起始，可以用下面代码来删除数据。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;truncate table tablename
DBCC CHECKIDENT(tablename,RESEED,1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 判断指定表在数据库中是否存在&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if exists(select name from sysobjects where name=&amp;#39;tablename&amp;#39; and type=&amp;#39;u&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 判断指定列在指定表中是否存在&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;if exists(select * from sys.columns,sys.tables
 where sys.columns.object_id = sys.tables.object_id
 and sys.tables.name=&amp;#39;tablename&amp;#39; and sys.columns.[name]=&amp;#39;columnname&amp;#39;)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 在编写代码生成器之类的程序的时候，通常需要取出数据库中所有的表名以及表中字段的一些基本信息，如字段长度、字段类型、描述等。实现上面要求的sql语句如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;--取数据库中表的集合
select * from sysobjects where xtype=&amp;#39;u&amp;#39; order by name

--取表中字段的一些基本信息
select
 sys.columns.name, --字段名
 sys.types.name as typename, --字段类型
 sys.columns.max_length, --字段长度
 sys.columns.is_nullable, --是否可空
 (select
 count(*)
 from
 sys.identity_columns
 where
 sys.identity_columns.object_id = sys.columns.object_id
 and
 sys.columns.column_id = sys.identity_columns.column_id
 ) as is_identity ,--是否自增

 (select
 value
 from
 sys.extended_properties
 where
 sys.extended_properties.major_id = sys.columns.object_id
 and
 sys.extended_properties.minor_id = sys.columns.column_id
 ) as description --注释
from
 sys.columns, sys.tables, sys.types
where
 sys.columns.object_id = sys.tables.object_id
and
 sys.columns.system_type_id=sys.types.system_type_id
and
 sys.tables.name=&amp;#39;tablename&amp;#39;
order by sys.columns.column_id
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 在存储过程中使用事务&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;create procedure procname
as
begin tran
 --执行sql语句

if @@ERROR!=0
begin
 rollback tran --失败
end
else
begin
 commit tran --成功
end 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;6 清除数据库日志&lt;/p&gt;</description></item><item><title>设计模式笔记(24)—访问者模式（行为型）</title><link>https://fwhyy.com/2010/02/design-patterns-notes-24-visitor-pattern/</link><pubDate>Tue, 02 Feb 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/02/design-patterns-notes-24-visitor-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;表示一个作用于某对象结构中的各元素的操作。它可以在不改变各元素的类的前提下定义作用于这些元素的新的操作。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，由于需求的改变，某些类层次结构中常常需要增加新的行为（方法），如果直接在基类中做这样的更改，将会给子类带来很繁重的变更负担，甚至破坏原有设计。如何在不更改类层次结构的前提下，在运行时根据需要透明地为类层次结构上的各个类动态添加新的操作，从而避免上述问题？请看下面访问者模式结构图和代码。&lt;/p&gt;
&lt;p&gt;访问者模式结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290611525.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;基本代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 声明了一个或多个需要添加的操作
/// &amp;lt;/summary&amp;gt;
public abstract class Visitor
{
 public abstract void VisitorConcreteElementA(ConcreteElementA concreteElementA);
 public abstract void VisitorConcreteElementB(ConcreteElementB concreteElementB);
}
/// &amp;lt;summary&amp;gt;
/// 操作的具体类1
/// &amp;lt;/summary&amp;gt;
public class ConcreteVisitor1:Visitor
{
 public override void VisitorConcreteElementA(ConcreteElementA concreteElementA)
 {
 Console.WriteLine(&amp;#34;{0}访问{1}&amp;#34;, this.GetType().Name, concreteElementA.GetType().Name);
 }
 public override void VisitorConcreteElementB(ConcreteElementB concreteElementB)
 {
 Console.WriteLine(&amp;#34;{0}访问{1}&amp;#34;, this.GetType().Name, concreteElementB.GetType().Name);
 }
}
/// &amp;lt;summary&amp;gt;
/// 操作的具体类2
/// &amp;lt;/summary&amp;gt;
public class ConcreteVisitor2 : Visitor
{
 public override void VisitorConcreteElementA(ConcreteElementA concreteElementA)
 {
 Console.WriteLine(&amp;#34;{0}访问{1}&amp;#34;, this.GetType().Name, concreteElementA.GetType().Name);
 }
 public override void VisitorConcreteElementB(ConcreteElementB concreteElementB)
 {
 Console.WriteLine(&amp;#34;{0}访问{1}&amp;#34;, this.GetType().Name, concreteElementB.GetType().Name);
 }
}
/// &amp;lt;summary&amp;gt;
/// 接受Visitor并使用其操作的抽象类
/// &amp;lt;/summary&amp;gt;
public abstract class Element
{
 public abstract void Accept(Visitor visitor);
}
/// &amp;lt;summary&amp;gt;
/// 接受Visitor并使用其操作的具体类
/// &amp;lt;/summary&amp;gt;
public class ConcreteElementA : Element
{
 public override void Accept(Visitor visitor)
 {
 visitor.VisitorConcreteElementA(this);
 }
 public void OperationA() { }
}
/// &amp;lt;summary&amp;gt;
/// 接受Visitor并使用其操作的具体类
/// &amp;lt;/summary&amp;gt;
public class ConcreteElementB : Element
{
 public override void Accept(Visitor visitor)
 {
 visitor.VisitorConcreteElementB(this);
 }
 public void OperationB() { }
}
public class ObjectStructure
{
 private List&amp;lt;Element&amp;gt; list = new List&amp;lt;Element&amp;gt;();
 public void Add(Element element)
 {
 list.Add(element);
 }
 public void Del(Element element)
 {
 if(list.Contains(element))
 list.Remove(element);
 }
 public void Accept(Visitor visitor)
 {
 foreach (Element e in list)
 {
 e.Accept(visitor);
 }
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端代码
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 ObjectStructure os = new ObjectStructure();
 os.Add(new ConcreteElementA());
 os.Add(new ConcreteElementB());
 Visitor cv1 = new ConcreteVisitor1();
 Visitor cv2 = new ConcreteVisitor2();
 os.Accept(cv2);
 os.Accept(cv1);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="visitor模式的几个要点"&gt;Visitor模式的几个要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Visitor模式通过所谓双重分发（double dispatch）来实现在不更改Element类层次结构的前提下，在运行时透明地为类层次结构上的各个类动态添加新的操作。&lt;/li&gt;
&lt;li&gt;Visitor模式通过所谓双重分发（double dispatch）来实现在不更改Element类层次结构的前提下，在运行时透明地为类层次结构上的各个类动态添加新的操作。&lt;/li&gt;
&lt;li&gt;Visitor模式的最大缺点在于扩展类层次结构（增添新的Element子类），会导致Visitor类的改变。因此Vistor模式适用于“Element类层次结构稳定，而其中的操作却经常面临频繁改动”。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>设计模式笔记(23)—策略者模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-23-strategy-pattern/</link><pubDate>Sun, 31 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-23-strategy-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;定义一系列算法，把它们一个个封装起来，并且使它们可互相替换。该模式使得算法可独立于使用它的客 户而变化。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，某些对象使用的算法可能多种多样，经常改变，如果将这些算法都编码到对象中，将会使对象变得异常复杂；而且有时候支持不使用的算法也是一个性能负担。如何在运行时根据需要透明地更改对象的算法？将算法与对象本身解耦，从而避免上述问题？看下面的策略者模式的结构图和基本代码，策略者模式比较简单，下面只是给出基本的代码实现。&lt;/p&gt;
&lt;p&gt;策略者模式结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290610502.webp" alt="image-20220129061002254" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;基本实现代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 抽象算法类
/// &amp;lt;/summary&amp;gt;
public abstract class Strategy
{
 //抽象算法方法
 public abstract void AlgorithmInterface();
}
/// &amp;lt;summary&amp;gt;
/// 具体算法A
/// &amp;lt;/summary&amp;gt;
public class ConcretestrategyA : Strategy
{
 public override void AlgorithmInterface()
 {
 Console.WriteLine(&amp;#34;算法A的实现&amp;#34;);
 }
}
/// &amp;lt;summary&amp;gt;
/// 具体算法B
/// &amp;lt;/summary&amp;gt;
public class ConcretestrategyB : Strategy
{
 public override void AlgorithmInterface()
 {
 Console.WriteLine(&amp;#34;算法B的实现&amp;#34;);
 }
}
/// &amp;lt;summary&amp;gt;
/// 具体算法C
/// &amp;lt;/summary&amp;gt;
public class ConcretestrategyC : Strategy
{
 public override void AlgorithmInterface()
 {
 Console.WriteLine(&amp;#34;算法C的实现&amp;#34;);
 }
}
/// &amp;lt;summary&amp;gt;
/// 上下文
/// &amp;lt;/summary&amp;gt;
public class Context
{
 private Strategy _strategy;
 public Context(Strategy stragtety)
 {
 this._strategy = stragtety;
 }
 public void ContextInterface()
 {
 _strategy.AlgorithmInterface();
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端代码
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 Context context;
 context = new Context(new ConcretestrategyA());
 context.ContextInterface();
 context = new Context(new ConcretestrategyB());
 context.ContextInterface();
 context = new Context(new ConcretestrategyC());
 context.ContextInterface();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行结果如下：&lt;/p&gt;</description></item><item><title>设计模式笔记(22)—状态模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-22-state-pattern/</link><pubDate>Thu, 28 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-22-state-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，某些对象的状态如果改变，其行为也会随之而发生变化，比如文档处于只读状态，其支持的行为和读写状态支持的行为就可能完全不同。如何在运行时根据对象的状态来透明地更改对象的行为？而不会为对象操作和状态转化之间引入紧耦合？看下面状态模式的结构图和代码。&lt;/p&gt;
&lt;p&gt;状态模式结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290611919.webp" alt="2010-12-29_110619" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;日常生活中我们常见的灯会有两种状态开和关，当灯亮着时我们可以用开关使之熄灭，反之则变量，看下面的代码就是改变灯的开关状态的一个过程：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 灯的状态开和关
/// &amp;lt;/summary&amp;gt;
public enum LightState
{
 On,
 Off
}
public class ChangeLightState
{
 private LightState _state = LightState.On;
 public LightState Change()
 {
 if (_state == LightState.On)
 {
 _state = LightState.Off;
 }
 else if (_state == LightState.Off)
 {
 _state = LightState.On;
 }
 return _state;
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端程序
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 ChangeLightState l = new ChangeLightState();
 l.Change();
 l.Change();
 l.Change();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码使用if语句来解决了灯开关状态的问题，不过在实际开发中的一些状态不可能是简单的枚举，这时如果依然使用if语句就会显得比较复杂，而且随着状态的改变会频繁进行修改if语句。所以需要将状态转换和处理的变化封装在抽象后的具体类中，看上面结构图的对应代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class State
{
 public abstract void Handle(Context context);
}
public class ConcreteStateA : State
{
 public override void Handle(Context context)
 {
 context.State = new ConcreteStateB();
 }
}
public class ConcreteStateB : State
{
 public override void Handle(Context context)
 {
 context.State = new ConcreteStateA();
 }
}
public class Context
{
 private State _state;
 public Context(State state)
 {
 this._state = state;
 }
 public State State
 {
 get { return _state; }
 set { _state = value;}
 }
 public void Request()
 {
 _state.Handle(this);
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端程序
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 Context context = new Context(new ConcreteStateA());
 context.Request();
 context.Request();
 context.Request();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;根据状态模式将上面的灯开关的代码改进如下：&lt;/p&gt;</description></item><item><title>设计模式笔记(20)—职责链模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-20-chain-of-responsibility-pattern/</link><pubDate>Wed, 27 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-20-chain-of-responsibility-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链，并沿着这条链传递请求，直到有一个对象处理它为止。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，一个请求可能被多个对象处理，但是每个请求在运行时只能有一个接受者，如果显式指定，将必不可少地带来请求发送者与接受者的紧耦合。如何使请求的发送者不需要指定具体的接受者？让请求的接受者自己在运行时决定来处理请求，从而使两者解耦。&lt;/p&gt;
&lt;p&gt;职责链模式结构图如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290613054.webp" alt="2010-12-29_111712" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;代码实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 抽象处理类
/// &amp;lt;/summary&amp;gt;
public abstract class BaseHandler
{
 public BaseHandler(BaseHandler next)
 {
 this.Next = next;
 }
 public BaseHandler Next { get; set; }
 protected abstract bool CanHandleRequest(Request request);
 public virtual void HandleRequest(Request request)
 {
 if (Next != null)
 {
 this.Next.HandleRequest(request);
 }
 }
}
public class AHandler:BaseHandler
{
 public AHandler(BaseHandler next)
 : base(next)
 {

 }
 protected override bool CanHandleRequest(Request request)
 {
 return request.Name == &amp;#34;A&amp;#34;;
 }
 public override void HandleRequest(Request request)
 {
 if (this.CanHandleRequest(request))
 {
 Console.WriteLine(&amp;#34;处理A的请求&amp;#34;);
 }
 else
 {
 base.HandleRequest(request);
 }
 }
}
public class BHandler : BaseHandler
{
 public BHandler(BaseHandler next)
 : base(next)
 {

 }
 protected override bool CanHandleRequest(Request request)
 {
 return request.Name == &amp;#34;B&amp;#34;;
 }
 public override void HandleRequest(Request request)
 {
 if (this.CanHandleRequest(request))
 {
 Console.WriteLine(&amp;#34;处理B的请求&amp;#34;);
 }
 else
 {
 base.HandleRequest(request);
 }
 }
}
public class CHandler : BaseHandler
{
 public CHandler(BaseHandler next)
 : base(next)
 {

 }
 protected override bool CanHandleRequest(Request request)
 {
 return request.Name == &amp;#34;C&amp;#34;;
 }
 public override void HandleRequest(Request request)
 {
 if (this.CanHandleRequest(request))
 {
 Console.WriteLine(&amp;#34;处理C的请求&amp;#34;);
 }
 else
 {
 base.HandleRequest(request);
 }
 }
}
public class Sender
{
 public Request _request;
 public Sender(Request request)
 {
 this._request = request;
 }
 public void Process(BaseHandler handler)
 {
 handler.HandleRequest(_request);
 }
}
/// &amp;lt;summary&amp;gt;
/// 请求的信息类
/// &amp;lt;/summary&amp;gt;
public class Request
{
 public string Name { get; set; }
 public Request(string name)
 {
 this.Name = name;
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端程序
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 Sender sender = new Sender(new Request(&amp;#34;A&amp;#34;));
 BaseHandler handler1 = new AHandler(null);
 BaseHandler handler2 = new BHandler(handler1);
 BaseHandler handler3 = new CHandler(handler2);
 sender.Process(handler3);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="chain-of-responsibility模式的几个要点"&gt;Chain of Responsibility模式的几个要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Chain of Responsibility 模式的应用场合在于“一个请求可能有多个接受者，但是最后真正的接受者只有一个”，只有这时候请求发送者与接受者的耦合才有可能出现“变化脆弱”的症状，职责链的目的就是将二者解耦，从而更好地应对变化。&lt;/li&gt;
&lt;li&gt;应用了Chain of Responsibility 模式后，对象的职责分派将更具灵活性。我们可以在运行时动态添加/修改请求的处理职责。&lt;/li&gt;
&lt;li&gt;如果请求传递到职责链的末尾仍得不到处理，应该有一个合理的缺省机制。这也是每一个接受对象的责任，而不是发出请求的对象的责任&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>设计模式笔记(21)—备忘录模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-21-memo-pattern/</link><pubDate>Wed, 27 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-21-memo-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;在不破坏封装性的前提下，捕获一个对象的内部状态，并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，某些对象的状态在转换过程中，可能由于某种需要，要求程序能够回溯到对象之前处于某个点时的状态。如果使用一些公有接口来让其他对象得到对象的状态，便会暴露对象的细节实现。如何实现对象状态的良好保存与恢复？但同时又不会因此而破坏对象本身的封装性，看下面的结构图和代码。&lt;/p&gt;
&lt;p&gt;备忘录模式结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290613625.webp" alt="2010-12-29_111357" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图中Originator为原发器，也可以讲发起者，可以创建一个备忘录（CreateMemento），Memento为备忘录，负责存储原发器中的内部状态。Caretaker主要负责存储备忘录。代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 备忘录类
/// &amp;lt;/summary&amp;gt;
public class Memento
{
 private string _state;
 public string State
 {
 get{return _state;}
 }
 public Memento(string state)
 {
 this._state = state;
 }
}
/// &amp;lt;summary&amp;gt;
/// 原发器类
/// &amp;lt;/summary&amp;gt;
public class Originator
{
 public string State { get; set; }
 public Memento CreateMemento()
 {
 return new Memento(State);
 }
 public void SetMemento(Memento memento)
 {
 State = memento.State;
 }
}
/// &amp;lt;summary&amp;gt;
/// 管理者
/// &amp;lt;/summary&amp;gt;
public class Caretaker
{
 public Memento Memento { get; set; }
}
/// &amp;lt;summary&amp;gt;
/// 客户端程序
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 //实例化原发器并设置状态名称
 Originator o = new Originator();
 o.State = &amp;#34;oec2003&amp;#34;;
 Console.WriteLine(&amp;#34;设置状态名字为:&amp;#34; + o.State);
 //实例化管理者，创建一个备忘储存在管理者中
 Caretaker c = new Caretaker();
 c.Memento = o.CreateMemento();
 //更改了原发器的状态名称
 o.State = &amp;#34;oec2004&amp;#34;;
 Console.WriteLine(&amp;#34;改后的状态名字为:&amp;#34; + o.State);
 //将备忘信息设置给原发器
 o.SetMemento(c.Memento);
 Console.WriteLine(&amp;#34;原来的状态名字为:&amp;#34; + o.State);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="memento模式的几个要点"&gt;Memento模式的几个要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;备忘录（Memento）存储原发器（Originator）对象的内部状态，在需要时恢复原发器状态。Memento模式适用于“由原发器管理，却又必须存储在原发器之外的信息”。&lt;/li&gt;
&lt;li&gt;在实现Memento模式中，要防止原发器以外的对象访问备忘录对象。备忘录对象有两个接口，一个为原发器使用的宽接口；一个为其他对象使用的窄接口。&lt;/li&gt;
&lt;li&gt;在实现Memento模式时，要考虑拷贝对象状态的效率问题，如果对象开销比较大，可以采用某种增量式改变来改进Memento模式。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>设计模式笔记(19)—观察者模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-19-observer-pattern/</link><pubDate>Mon, 25 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-19-observer-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;定义对象间的一种一对多的依赖关系，以便当一个对象的状态发生改变时，所有依赖于它的对象都得到通 知并自动更新&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，我们需要为某些对象建立一种“通知依赖关系” ——一个对象（目标对象）的状态发生改变，所有的依赖对象（观察者对象）都将得到通知。如果这样的依赖关系过于紧密，将使软件不能很好地抵御变化。使用面向对象技术，可以将这种依赖关系弱化，并形成一种稳定的依赖关系。从而实现软件体系结构的松耦合。&lt;/p&gt;
&lt;p&gt;看这样一个场景，银行的ATM机在处理完成银行账户的存入或取出后会给用户发送手机短信和电子邮件，那么就会有这样三个对象，BankAccount Emailer Mobile，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class BankAccount
{
 Emailer emailer;
 Mobile mobile;
 public void Withdraw(int data)
 {
 //处理存入或取出
 emailer.SendEmail(&amp;#34;&amp;#34;);
 mobile.SendMsg(&amp;#34;&amp;#34;);
 }
}
public class Emailer
{
 public void SendEmail(string to)
 {
 //发送邮件
 }
}
public class Mobile
{
 public void SendMsg(string phoneNumber)
 {
 //发送短信
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码中BankAccount和Emailer Mobile之间有很强的依赖关系，Emailer和Mobile的变化会对BankAccount产生很大的影响，接下来要做的就是使BankAccount不要去依赖Emailer和Mobile这样的具体类，而应该去依赖他们的抽象，抽象的东西通常是稳定的，这样BankAccount和抽象之间的依赖就是一种比较弱的依赖关系，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class UserAccountArgs
{
 public string Email { get; set; }
 public string PhoneNumber { get; set; }
 public UserAccountArgs(string email, string phoneNumer)
 {
 Email = email;
 PhoneNumber = phoneNumer;
 }
}
public interface IAccountObserver
{
 void Update(UserAccountArgs args);
}
public class Emailer : IAccountObserver
{
 public void Update(UserAccountArgs args)
 {
 Console.WriteLine(&amp;#34;消息已发送邮件至邮箱：&amp;#34; + args.Email);
 }
}
public class Mobile : IAccountObserver
{
 public void Update(UserAccountArgs args)
 {
 Console.WriteLine(&amp;#34;消息已发短信至手机：&amp;#34; + args.PhoneNumber);
 }
}
public class BankAccount
{
 List&amp;lt;IAccountObserver&amp;gt; list = new List&amp;lt;IAccountObserver&amp;gt;();
 public void Withdraw(int data)
 {
 //处理存入或取出
 if(data&amp;gt;0)
 {
 Console.WriteLine(&amp;#34;您的账户存入了&amp;#34;+data+&amp;#34;元&amp;#34;);
 }
 else
 {
 Console.WriteLine(&amp;#34;您的账户取出了&amp;#34; + Math.Abs(data) + &amp;#34;元&amp;#34;);
 }
 UserAccountArgs args = 
new UserAccountArgs(&amp;#34;oec2003@gmail.com&amp;#34;,&amp;#34;1388888****&amp;#34;);
 foreach (IAccountObserver observer in list)
 {
 observer.Update(args);
 }
 }
 public void AddObserver(IAccountObserver observer)
 {
 list.Add(observer);
 }
 public void RemoveObserver(IAccountObserver observer)
 {
 list.Remove(observer);
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端调用
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 BankAccount bankAccount = new BankAccount();
 bankAccount.AddObserver(new Emailer());
 bankAccount.AddObserver(new Mobile());
 bankAccount.Withdraw(-500);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;运行结果如下：&lt;/p&gt;</description></item><item><title>设计模式笔记(18)—迭代器模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-18-iterator-pattern/</link><pubDate>Sun, 24 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-18-iterator-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;提供一种方法顺序访问一个聚合对象中的各个元素， 而又不暴露该对象的内部表示。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，集合对象内部结构常常变化各异。但对于这些集合对象，我们希望在不暴露其内部结构的同时，可以让外部客户代码透明地访问其中包含的元素；同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式。&lt;/p&gt;</description></item><item><title>Lable和Literal控件的使用和区别</title><link>https://fwhyy.com/2010/01/the-use-of-the-lable-and-literal-controls-and-differences/</link><pubDate>Sat, 23 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/the-use-of-the-lable-and-literal-controls-and-differences/</guid><description>&lt;p&gt;Lable和Literal这两个控件是我们非常熟悉的两个控件，都是用作内容呈现用的，但他们之间也有不同之处，分别应用于不同的地方。Lable控件会将内容呈现在html标签span中，即Lable控件的Text属性的值会包含在&lt;span&gt;标签中。而Literal控件生成的代码则比较干净，它的Text属性的值将直接显示在页面中，看下面两段代码：&lt;/p&gt;
&lt;p&gt;Lable：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Label ID=&amp;#34;lblUserName&amp;#34; runat=&amp;#34;server&amp;#34; Text=&amp;#34;用户名&amp;#34;&amp;gt;&amp;lt;/asp:Label&amp;gt;
&amp;lt;asp:TextBox ID=&amp;#34;txtUserName&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;asp:Label ID=&amp;#34;lblPwd&amp;#34; runat=&amp;#34;server&amp;#34; Text=&amp;#34;密码&amp;#34;&amp;gt;&amp;lt;/asp:Label&amp;gt;
&amp;lt;asp:TextBox ID=&amp;#34;txtPwd&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Literal：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Literal runat=&amp;#34;server&amp;#34; ID=&amp;#34;litUserName&amp;#34; Text=&amp;#34;用户名&amp;#34;&amp;gt;&amp;lt;/asp:Literal&amp;gt;
&amp;lt;asp:TextBox ID=&amp;#34;txtUserName1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;asp:Literal runat=&amp;#34;server&amp;#34; ID=&amp;#34;litPwd&amp;#34; Text=&amp;#34;密码&amp;#34;&amp;gt;&amp;lt;/asp:Literal&amp;gt;
&amp;lt;asp:TextBox ID=&amp;#34;txtPwd1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面两段程序运行的结果都如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302120262.webp" alt="2010-12-29_1138351" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;再来看看上面的代码生成的源码：&lt;/p&gt;
&lt;p&gt;Lable&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;span id=&amp;#34;lblUserName&amp;#34;&amp;gt;用户名&amp;lt;/span&amp;gt;
&amp;lt;input name=&amp;#34;txtUserName&amp;#34; type=&amp;#34;text&amp;#34; id=&amp;#34;txtUserName&amp;#34; /&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;span id=&amp;#34;lblPwd&amp;#34;&amp;gt;密码&amp;lt;/span&amp;gt;
&amp;lt;input name=&amp;#34;txtPwd&amp;#34; type=&amp;#34;text&amp;#34; id=&amp;#34;txtPwd&amp;#34; /&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Literal&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;用户名
&amp;lt;input name=&amp;#34;txtUserName1&amp;#34; type=&amp;#34;text&amp;#34; id=&amp;#34;txtUserName1&amp;#34; /&amp;gt;&amp;lt;br /&amp;gt;
密码
&amp;lt;input name=&amp;#34;txtPwd1&amp;#34; type=&amp;#34;text&amp;#34; id=&amp;#34;txtPwd1&amp;#34; /&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;从源码中可以很清楚看出Lable最终在客户端会生成Span标签，而Literal则直接显示文本，记得曾经维护过的一个自定义控件，在不同留言器中有样式问题，调试很久最终发现就是Lable生成的Span惹的祸，最终换成Literal得以解决，所以后来但凡要显示文本的地方我基本都是用Literal。不过Lable也不是一无是处，Lable控件有一个AssociatedControlID，可以将该属性指向一个表单控件的ID，通常为TextBox，看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Label ID=&amp;#34;lblUserName&amp;#34; runat=&amp;#34;server&amp;#34; AssociatedControlID=&amp;#34;txtUserName&amp;#34; Text=&amp;#34;用户名&amp;#34;&amp;gt;&amp;lt;/asp:Label&amp;gt;
&amp;lt;asp:TextBox ID=&amp;#34;txtUserName&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;asp:Label ID=&amp;#34;lblPwd&amp;#34; runat=&amp;#34;server&amp;#34; AssociatedControlID=&amp;#34;txtPwd&amp;#34; Text=&amp;#34;密码&amp;#34;&amp;gt;&amp;lt;/asp:Label&amp;gt;
&amp;lt;asp:TextBox ID=&amp;#34;txtPwd&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;&amp;lt;/asp:TextBox&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;和上面的代码基本一样只是添加了AssociatedControlID属性，分别指向了两个TextBox控件的ID，添加了这个属性后生成的源码就变了，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;label for=&amp;#34;txtUserName&amp;#34; id=&amp;#34;lblUserName&amp;#34;&amp;gt;用户名&amp;lt;/label&amp;gt;
&amp;lt;input name=&amp;#34;txtUserName&amp;#34; type=&amp;#34;text&amp;#34; id=&amp;#34;txtUserName&amp;#34; /&amp;gt;&amp;lt;br /&amp;gt;
&amp;lt;label for=&amp;#34;txtPwd&amp;#34; id=&amp;#34;lblPwd&amp;#34;&amp;gt;密码&amp;lt;/label&amp;gt;
&amp;lt;input name=&amp;#34;txtPwd&amp;#34; type=&amp;#34;text&amp;#34; id=&amp;#34;txtPwd&amp;#34; /&amp;gt;&amp;lt;br /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;可以看出有Span标签变成了lable标签 for属性指向了TextBox的id。AssociatedControlID属性的使用能够给残障人士带来方便，如果使用读屏器之类的辅助设备来和网站进行交互，AssociatedControlID属性能帮助辅助设备将标签和字段关联起来。除此之外还有一个好处就是当点击标签时，所关联的TextBox就会获得焦点。&lt;/p&gt;
&lt;p&gt;由于Lable控件的内容最终呈现在Span标签中，所以Lable控件也支持Span标签的一些属性，如BackColor，CssClass等。Literal控件不生成Span标签，当然也不支持那些属性，不过Literal控件有个Mode属性，该属性有三个值&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encode ：在编码Html内容后再显示控件的内容&lt;/li&gt;
&lt;li&gt;PassThrough ：显示控件的内容不进行编码&lt;/li&gt;
&lt;li&gt;Transform ：清除一些不支持的标记后在呈现内容&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;看下面的代码：&lt;/p&gt;</description></item><item><title>设计模式笔记(17)—中介者模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-17-mediator-pattern/</link><pubDate>Wed, 20 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-17-mediator-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式的相互引用，从而使其耦合松散，而且可以独立地改变它们之间的交互。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，经常会出现多个对象互相关联交互的情况，对象之间常常会维持一种复杂的引用关系，如果遇到一些需求的更改，这种直接的引用关系将面临不断的变化。在这种情况下，我们可使用一个“中介对象”来管理对象间的关联关系，避免相互交互的对象之间的紧耦合引用关系，从而更好地抵御变化。&lt;/p&gt;
&lt;p&gt;中介者模式的结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290617750.webp" alt="2010-12-29_114801" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;代码实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 抽象的中介者
/// &amp;lt;/summary&amp;gt;
public abstract class Mediator
{
 public abstract void Send(string msg, Colleague colleague);
}
/// &amp;lt;summary&amp;gt;
/// 抽象的同事类
/// &amp;lt;/summary&amp;gt;
public abstract class Colleague
{
 protected Mediator _mediator;
 public Colleague(Mediator mediator)
 {
 _mediator = mediator;
 }
}
/// &amp;lt;summary&amp;gt;
/// 具体的中介者对象
/// &amp;lt;/summary&amp;gt;
public class ConcreteMediator : Mediator
{
 public ConcreteCollegue1 Colleague1 { get; set; }
 public ConcreteCollegue2 Colleague2 { get; set; }
 public override void Send(string msg, Colleague colleague)
 {
 if (colleague == Colleague1)
 {
 Colleague2.Notify(msg);
 }
 else
 {
 Colleague1.Notify(msg);
 }
 }
}
/// &amp;lt;summary&amp;gt;
/// 具体的同事类1
/// &amp;lt;/summary&amp;gt;
public class ConcreteCollegue1:Colleague
{
 public ConcreteCollegue1(Mediator mediator)
 : base(mediator)
 {

 }

 public void Send(string msg)
 {
 _mediator.Send(msg,this);
 }
 public void Notify(string msg)
 {
 Console.WriteLine(&amp;#34;通知同事1：&amp;#34;+msg);
 }
}
/// &amp;lt;summary&amp;gt;
/// 具体的同事类2
/// &amp;lt;/summary&amp;gt;
public class ConcreteCollegue2:Colleague
{
 public ConcreteCollegue2(Mediator mediator)
 : base(mediator)
 {

 }

 public void Send(string msg)
 {
 _mediator.Send(msg,this);
 }
 public void Notify(string msg)
 {
 Console.WriteLine(&amp;#34;通知同事2：&amp;#34;+msg);
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户端调用
/// &amp;lt;/summary&amp;gt;
class Program
{
 static void Main(string[] args)
 {
 ConcreteMediator cm = new ConcreteMediator();
 ConcreteCollegue1 cc1 = new ConcreteCollegue1(cm);
 ConcreteCollegue2 cc2 = new ConcreteCollegue2(cm);
 cm.Colleague1 = cc1;
 cm.Colleague2 = cc2;
 cc1.Send(&amp;#34;看阿凡达了吗？&amp;#34;);
 cc2.Send(&amp;#34;呵呵，周末公司组织去看。&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="mediator模式的几个要点"&gt;Mediator模式的几个要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;将多个对象间复杂的关联关系解耦，Mediator模式将多个对象间的控制逻辑进行集中管理，变“多个对象互相关联”为“多个对象和一个中介者关联”，简化了系统的维护，抵御了可能的变化。&lt;/li&gt;
&lt;li&gt;随着控制逻辑的复杂化，Mediator具体对象的实现可能相当复杂。这时候可以对Mediator对象进行分解处理。&lt;/li&gt;
&lt;li&gt;Façade模式是解耦系统外到系统内（单向）的对象关联关系；Mediator模式是解耦系统内各个对象之间（双向）的关联关系。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>设计模式笔记(16)—解释器模式（行为型）</title><link>https://fwhyy.com/2010/01/design-patterns-notes-16-interpreter-pattern/</link><pubDate>Tue, 19 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/design-patterns-notes-16-interpreter-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;给定一个语言，定义它的文法的一种表示，并定义一种解释器，这个解释器使用该表示来解释语言中的句 子。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，如果某一特定领域的问题比较复杂，类似的模式不断重复出现，如果使用普通的编程方式来实现将面临非常频繁的变化。在这种情况下，将特定领域的问题表达为某种语法规则下的句子，然后构建一个解释器来解释这样的句子，从而达到解决问题的目的。&lt;/p&gt;
&lt;p&gt;下面看下解释器模式的结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290616838.webp" alt="2010-12-29_115427" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;基本代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 上下文信息
/// &amp;lt;/summary&amp;gt;
public class Context
{
 public string Data { get; set; }
}
/// &amp;lt;summary&amp;gt;
/// 抽象表达式，声明一个抽象的解释操作
/// &amp;lt;/summary&amp;gt;
public abstract class AbstractExpression
{
 public abstract void Interpret(Context context);
}
public class TerminalExpression:AbstractExpression
{
 public override void Interpret(Context context)
 {
 context.Data += &amp;#34;终端,&amp;#34;;
 }
}
public class NonterminalExpression : AbstractExpression
{
 public override void Interpret(Context context)
 {
 context.Data += &amp;#34;非终端,&amp;#34;;
 }
}
public class App
{
 static void Main(string[] args)
 {
 Context context = new Context();
 List&amp;lt;AbstractExpression&amp;gt; list = new List&amp;lt;AbstractExpression&amp;gt;();
 list.Add(new TerminalExpression());
 list.Add(new NonterminalExpression());
 list.Add(new TerminalExpression());

 foreach (AbstractExpression exp in list)
 {
 exp.Interpret(context);
 }
 Console.WriteLine(context.Data);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接下来看一个实际的应用，功能是数字的转换，如将“五百二十”转换成“520“，首先创建一个Context类用来储存上下文信息，类中有两个属性Statement和Data，分别用来存放汉字的数字和阿拉伯数字。&lt;/p&gt;</description></item><item><title>武汉 再见</title><link>https://fwhyy.com/2010/01/wuhan-goodbye/</link><pubDate>Tue, 12 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/wuhan-goodbye/</guid><description>&lt;p&gt;从毕业到现在一直呆在武汉，已经两年多了，经历了两个公司，现在的这个公司虽小，但氛围很好，和同事也关系也相处得非常融洽，最重要的是有一个人品极佳的经理，从他身上我也学到了很多。所以说这一年多的时间里我过得还不错，我很高兴在这样的公司工作这么长时间。&lt;/p&gt;
&lt;p&gt;然而现在我却要离开，这个想法也是最近的几个月萌发的，我必须去大城市闯一闯，因为我已经不再年轻，在不闯就真的没机会了，目标城市北京，原因有三：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我妹在北京，过去后兄妹在一起有个照应；&lt;/li&gt;
&lt;li&gt;很大的大学同学都在北京，而且大多也是做开发；&lt;/li&gt;
&lt;li&gt;大学四年是在北方上的，很喜欢北方的气候。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;和我们经理谈的时候很顺利，经理表示很理解我的想法，也支持我的决定，但还是希望我能留下，尽管他从我的语气应该可以判断出来我已经决意要走。&lt;/p&gt;
&lt;p&gt;经理一直都在说是公司发展太慢了，没能给我们很好的条件，让我感到很愧疚。谈完我和经理一起下的楼，电梯里经理说以后我们的软件要是买到北京去了，你就别呆北京马上回来吧，尽管是句玩笑话，但让人很温暖。&lt;/p&gt;
&lt;p&gt;希望我们经理能越来越好，希望 Cmwin 越来越好。现在我能做的就是在这剩下的不多的时间里尽力把自己工作做好，有个完美的结束。&lt;/p&gt;</description></item><item><title>2010年的第一场雪</title><link>https://fwhyy.com/2010/01/the-first-snow-of-2010/</link><pubDate>Wed, 06 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/the-first-snow-of-2010/</guid><description>&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201302009886.webp" alt="2010-12-31_104421" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201302009741.webp" alt="2010-12-31_104536" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201302010165.webp" alt="2010-12-31_104545" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201302010184.webp" alt="2010-12-31_104554" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201302011331.webp" alt="2010-12-31_104606" loading="lazy" decoding="async"&gt;
&lt;/p&gt;</description></item><item><title>jQuery上传插件Uploadify使用详解</title><link>https://fwhyy.com/2010/01/jquery-upload-plugin-uploadify-use-explanation/</link><pubDate>Wed, 06 Jan 2010 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2010/01/jquery-upload-plugin-uploadify-use-explanation/</guid><description>&lt;h2 id="本文uploadify版本为210已经过时截止2016-09-25最新版本321的详细介绍请移步jquery上传插件uploadify使用详解321"&gt;本文Uploadify版本为2.1.0，已经过时，截止（2016-09-25）最新版本3.2.1的详细介绍请移步《&lt;a href="http://fwhyy.com/2016/09/jquery-upload-plugin-uploadify-3-2-1-use-explanation/"&gt;jQuery上传插件Uploadify使用详解(3.2.1)&lt;/a&gt;》&lt;/h2&gt;
&lt;p&gt;Uploadify是jQuery的一个上传插件，实现的效果非常不错，带进度显示。不过官方提供的实例时php版本的，本文将详细介绍Uploadify在Aspnet中的使用，您也可以点击下面的链接进行演示或下载。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.uploadify.com/download"&gt;官方下载&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.uploadify.com/documentation"&gt;官方文档&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.uploadify.com/demo"&gt;官方演示&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;首先按下面的步骤来实现一个简单的上传功能。&lt;/p&gt;
&lt;p&gt;1 创建Web项目，命名为JQueryUploadDemo，从官网上下载最新的版本解压后添加到项目中。&lt;/p&gt;
&lt;p&gt;2 在项目中添加UploadHandler.ashx文件用来处理文件的上传。&lt;/p&gt;
&lt;p&gt;3 在项目图:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300722377.webp" alt="2010-12-29_120720" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 Default.aspx的html页的代码修改如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html xmlns=&amp;#34;http://www.w3.org/1999/xhtml&amp;#34;&amp;gt;
&amp;lt;head runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;title&amp;gt;Uploadify&amp;lt;/title&amp;gt;
 &amp;lt;link href=&amp;#34;JS/jquery.uploadify-v2.1.0/example/css/default.css&amp;#34;
 rel=&amp;#34;stylesheet&amp;#34; type=&amp;#34;text/css&amp;#34; /&amp;gt;
 &amp;lt;link href=&amp;#34;JS/jquery.uploadify-v2.1.0/uploadify.css&amp;#34;
 rel=&amp;#34;stylesheet&amp;#34; type=&amp;#34;text/css&amp;#34; /&amp;gt;

 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;
 src=&amp;#34;JS/jquery.uploadify-v2.1.0/jquery-1.3.2.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;

 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;
 src=&amp;#34;JS/jquery.uploadify-v2.1.0/swfobject.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;

 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;
 src=&amp;#34;JS/jquery.uploadify-v2.1.0/jquery.uploadify.v2.1.0.min.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;

 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 $(document).ready(function()
 {
 $(&amp;#34;#uploadify&amp;#34;).uploadify({
 &amp;#39;uploader&amp;#39;: &amp;#39;JS/jquery.uploadify-v2.1.0/uploadify.swf&amp;#39;,
 &amp;#39;script&amp;#39;: &amp;#39;UploadHandler.ashx&amp;#39;,
 &amp;#39;cancelImg&amp;#39;: &amp;#39;JS/jquery.uploadify-v2.1.0/cancel.png&amp;#39;,
 &amp;#39;folder&amp;#39;: &amp;#39;UploadFile&amp;#39;,
 &amp;#39;queueID&amp;#39;: &amp;#39;fileQueue&amp;#39;,
 &amp;#39;auto&amp;#39;: false,
 &amp;#39;multi&amp;#39;: true
 });
 });
 &amp;lt;/script&amp;gt;

&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;div id=&amp;#34;fileQueue&amp;#34;&amp;gt;&amp;lt;/div&amp;gt;
 &amp;lt;input type=&amp;#34;file&amp;#34; name=&amp;#34;uploadify&amp;#34; id=&amp;#34;uploadify&amp;#34; /&amp;gt;
 &amp;lt;p&amp;gt;
 &amp;lt;a href=&amp;#34;javascript:$(&amp;#39;#uploadify&amp;#39;).uploadifyUpload()&amp;#34;&amp;gt;上传&amp;lt;/a&amp;gt;|
 &amp;lt;a href=&amp;#34;javascript:$(&amp;#39;#uploadify&amp;#39;).uploadifyClearQueue()&amp;#34;&amp;gt;取消上传&amp;lt;/a&amp;gt;
 &amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 UploadHandler类的ProcessRequest方法代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public void ProcessRequest(HttpContext context)
{
 context.Response.ContentType = &amp;#34;text/plain&amp;#34;;
 context.Response.Charset = &amp;#34;utf-8&amp;#34;; 

 HttpPostedFile file = context.Request.Files[&amp;#34;Filedata&amp;#34;];
 string uploadPath =
 HttpContext.Current.Server.MapPath(@context.Request[&amp;#34;folder&amp;#34;])+&amp;#34;\\&amp;#34;; 

 if (file != null)
 {
 if (!Directory.Exists(uploadPath))
 {
 Directory.CreateDirectory(uploadPath);
 }
 file.SaveAs(uploadPath + file.FileName);
 //下面这句代码缺少的话，上传成功后上传队列的显示不会自动消失
 context.Response.Write(&amp;#34;1&amp;#34;);
 }
 else
 {
 context.Response.Write(&amp;#34;0&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;6 运行后效果如下图：&lt;/p&gt;</description></item><item><title>设计模式笔记(15)—命令模式（行为型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-15-command-pattern/</link><pubDate>Wed, 30 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-15-command-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;将一个请求封装为一个对象，从而使你可用不同的请求对客户进行参数化；对请求排队或记录请求日志，以及支持可撤销的操作。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，“行为请求者”与“行为实现者”通常呈现一种“紧耦合”。但在某些场合——比如需
要对行为进行“记录、撤销/重做（undo/redo）、事务”等处理，这种无法抵御变化的紧耦合是不合适的。在这种情况下，如何将“行为请求者”与“行为实现者”解耦？将一组行为抽象为对象，可以实现二者之间的松耦合。&lt;/p&gt;
&lt;p&gt;先来看个反例（版本1），假设在一个应用程序中需要用到要用到很多的一些外部的类，并且要对这些类中的操作进行撤销、记录等操作，如果像下面这样实现就会很乱并且不容易实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Application
{
 public void Process()
 {
 Document doc = new Document();
 doc.ShowText();
 Graphics gra = new Graphics();
 gra.Draw();
 //需要进行undo 记录等操作
 }
}
public class Document
{
 public void ShowText() { }
}
public class Graphics
{
 public void Draw(){ }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;要满足上面提的那些要求就需要用命令模式，命令模式结构图如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290617303.webp" alt="2010-12-29_121609" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;改进后的代码（版本2），将ShowText Draw这种行为抽象起来放到一个接口中，接口命名为ICommand，并且在该接口中还有一个方法签名Undo，用来做撤销处理，当然根据需要还可以加其他的操作。ICommand代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public interface ICommand
{
 void Execute();
 void Undo();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Document类和Graphics类实现该接口，并提供自己的实现，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Document:ICommand
{
 public string Name { get;set;}
 public Document(string name)
 {
 Name = name;
 }
 public void Execute()
 {
 Console.WriteLine(&amp;#34;显示文本 &amp;#34;+Name);
 }
 public void Undo()
 {
 Console.WriteLine(&amp;#34;撤销显示文本 &amp;#34;+Name);
 }
}

public class Graphics : ICommand
{
 public string Name { get;set;}
 public Graphics(string name)
 {
 Name = name;
 }
 public void Execute()
 {
 Console.WriteLine(&amp;#34;画图 &amp;#34;+Name);
 }
 public void Undo()
 {
 Console.WriteLine(&amp;#34;撤销画图 &amp;#34;+Name);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;客户端调用的代码：&lt;/p&gt;</description></item><item><title>关于多线程的一个例子（UI实时显示）</title><link>https://fwhyy.com/2009/12/an-example-in-respect-to-multithreading/</link><pubDate>Sun, 20 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/an-example-in-respect-to-multithreading/</guid><description>&lt;p&gt;在开发Window应用程序的时候，经常需要在界面上显示出已经执行到什么步骤了，拿一个简单例子来说，创建一个Winform程序，在窗体上访一个Button和一个Label，点击Button时做100次循环，在Label上实时显示当前循环的次数。一种简单的做法就是使用Application.DoEvents，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void btnTest_Click(object sender, EventArgs e)
{
 for (int i = 0; i &amp;lt; 100; i++)
 {
 Thread.Sleep(100);
 label1.Text = i + &amp;#34;/100&amp;#34;;
 Application.DoEvents();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码如果将Application.DoEvents();去掉当点击Button时，程序会卡住，直到这个循环执行完成，当这个循环足够大时是不能忍受的。不过小数据量用Application.DoEvents()还行，数据量大了使用Application.DoEvents()就会带来性能的问题。所以Application.DoEvents()要慎用，在大数据量的时候可以使用多线程解决。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void btnTest_Click(object sender, EventArgs e)
{
 Thread thread = new Thread(new ThreadStart(DoWork));
 thread.Start();
}
private void DoWork()
{
 for (int i = 0; i &amp;lt; 100; i++)
 {
 Thread.Sleep(100);
 label1.Text = i + &amp;#34;/100&amp;#34;;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;嗯？出现异常了是吧，没错上面的代码运行后后会出现“线程间操作无效: 从不是创建控件“label1”的线程访问它。”的异常。关于什么原因造成的，大家可以google一下。不过上面代码在vs03中貌似可以正常运行。将代码改成下面这样就可以正常运行了：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void btnTest_Click(object sender, EventArgs e)
{
 Thread thread = new Thread(new ThreadStart(DoWork));
 thread.Start();
}
private void DoWork()
{
 for (int i = 0; i &amp;lt; 100; i++)
 {
 Thread.Sleep(100);
 this.Invoke(new Action&amp;lt;string&amp;gt;(this.ChangeLabel),i.ToString());
 }
}
private void ChangeLabel(string i)
{
 label1.Text = i + &amp;#34;/100&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果嫌多写一个ChangeLabel方法费事，可以写成匿名方法的形式，如下：&lt;/p&gt;</description></item><item><title>设计模式笔记(14)—模板方法模式（行为型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-14-template-method-pattern/</link><pubDate>Mon, 14 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-14-template-method-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;定义一个操作中的算法的骨架，而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个 算法的结构即可重定义该算法的某些特定步骤。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件构建过程中，对于某一项任务，它常常有稳定的整体操作结构，但各个子步骤却有很多改变的需求，或者由于固有的原因（比如框架与应用之间的关系）而无法和任务的整体结构同时实现。如何在确定稳定操作结构的前提下，来灵活应对各个子步骤的变化或者晚期实现需求？&lt;/p&gt;
&lt;p&gt;模板方法模式结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290615923.webp" alt="2010-12-29_122541" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;AbstractClass类：这个抽象类中定义了一个模板方法TemplateMethod，该方法通常为一个具体方法，将抽象类中的一些抽象的操作组合在其中，推迟到子类实现。&lt;/p&gt;
&lt;p&gt;ConcreteClass类:按照需求实现父类定义的一个或多个抽象方法。&lt;/p&gt;
&lt;p&gt;一个小的例子来反映上面的结构：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 测试车的类---&amp;gt;AbstractClass
/// &amp;lt;/summary&amp;gt;
public abstract class Vehical
{
 protected abstract void Start(); //PrimitiveOperation
 protected abstract void Run(); //PrimitiveOperation
 protected abstract void Trun(); //PrimitiveOperation
 protected abstract void Stop(); //PrimitiveOperation
 /// &amp;lt;summary&amp;gt;
 /// 相当于TemplateMethod
 /// &amp;lt;/summary&amp;gt;
 public void Test()
 {
 //做记录等操作
 Start();
 Run();
 Trun();
 Stop();
 }
}

/// &amp;lt;summary&amp;gt;
/// 红旗车---&amp;gt;ConcreteClass
/// &amp;lt;/summary&amp;gt;
public class HongQiCar : Vehical
{
 protected override void Start()
 {
 Console.WriteLine(&amp;#34;测试红旗车启动&amp;#34;);
 }
 protected override void Run()
 {
 Console.WriteLine(&amp;#34;测试红旗车行驶&amp;#34;);
 }
 protected override void Trun(int degree)
 {
 Console.WriteLine(&amp;#34;测试红旗车转向&amp;#34;);
 }
 protected override void Stop()
 {
 Console.WriteLine(&amp;#34;测试红旗车停止&amp;#34;);
 }
}
/// &amp;lt;summary&amp;gt;
/// QQ车---&amp;gt;ConcreteClass
/// &amp;lt;/summary&amp;gt;
public class QQCar : Vehical
{
 protected override void Start()
 {
 Console.WriteLine(&amp;#34;测试QQ车启动&amp;#34;);
 }
 protected override void Run()
 {
 Console.WriteLine(&amp;#34;测试QQ车行驶&amp;#34;);
 }
 protected override void Trun(int degree)
 {
 Console.WriteLine(&amp;#34;测试QQ车转向&amp;#34;);
 }
 protected override void Stop()
 {
 Console.WriteLine(&amp;#34;测试QQ车停止&amp;#34;);
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户代码
/// &amp;lt;/summary&amp;gt;
public class App
{
 static void Main()
 {
 Vehical vehical;
 vehical = new HongQiCar();
 vehical.Test();

 vehical = new QQCar();
 vehical.Test();
 Console.ReadLine();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="template-method模式的几个要点"&gt;Template Method模式的几个要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Template Method模式是一种非常基础性的设计模式，在面向对象系统中有着大量的应用。它用最简洁的机制（虚函数的多态性）为很多应用程序框架提供了灵活的扩展点，是代码复用方面的基本实现结构。&lt;/li&gt;
&lt;li&gt;除了可以灵活应对子步骤的变化外，“不要调用我，让我来调用你”的反向控制结构是Template Method的典型应用。&lt;/li&gt;
&lt;li&gt;在具体实现方面，被Template Method调用的虚方法可以具有实现，也可以没有任何实现（抽象方法、纯虚方法），但一般推荐将它们设置为protected方法。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>在JS方法中返回多个值的三种方法</title><link>https://fwhyy.com/2009/12/in-js-method-return-multiple-values-of-the-three-methods/</link><pubDate>Fri, 11 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/in-js-method-return-multiple-values-of-the-three-methods/</guid><description>&lt;p&gt;在使用JS编程中，有时需要在一个方法返回两个个或两个以上的数据，用下面的几种方法都可以实现：&lt;/p&gt;
&lt;p&gt;1 使用数组的方式，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
 &amp;lt;title&amp;gt;JS函数返回多个值--oec2003&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;input type=&amp;#34;button&amp;#34; onclick=&amp;#34;getNames()&amp;#34; value=&amp;#34;test&amp;#34; /&amp;gt;

 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
function getData()
{
 var names=new Array(&amp;#34;oec2003&amp;#34;,&amp;#34;oec2004&amp;#34;);
 return names;
}
function getNames()
{
 var names=getData();
 alert(getData()[0]); //返回oec2003
}
&amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 将数据封装到Json中返回，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;JS函数返回多个值--oec2003&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; onclick=&amp;#34;getInfo()&amp;#34; value=&amp;#34;test&amp;#34;/&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
function getData()
{
 var info={&amp;#34;name&amp;#34;:&amp;#34;oec2003&amp;#34;,&amp;#34;age&amp;#34;:&amp;#34;25&amp;#34;};
 return info;
}
function getInfo()
{
 var info=getData();
 var name=info[&amp;#34;name&amp;#34;];
 var age=info[&amp;#34;age&amp;#34;];
 alert(&amp;#34;姓名：&amp;#34;+name+&amp;#34; 年龄：&amp;#34;+age);
}
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;更详细的Json的介绍请看这里&lt;/p&gt;
&lt;p&gt;3 这是最简单的一种方法，看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;JS函数返回多个值--oec2003&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;input type=&amp;#34;button&amp;#34; onclick=&amp;#34;getInfo()&amp;#34; value=&amp;#34;test&amp;#34;/&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function getData()
 {
 return [&amp;#34;oec2003&amp;#34;, 25]
 }
 function getInfo()
 {
 var info = getData();
 alert(&amp;#34;姓名：&amp;#34; + info[0] + &amp;#34;年龄：&amp;#34; + info[1]);
 }
&amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>设计模式笔记(13)—代理模式（结构型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-13-proxy-pattern/</link><pubDate>Thu, 10 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-13-proxy-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;为其他对象提供一种代理以控制对这个对象的访问。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在面向对象系统中，有些对象由于某种原因（比如对象创建的开销很大，或者某些操作需要安全控制，或者需要进程外的访问等），直接访问会给使用者、或者系统结构带来很多麻烦。如何在不失去透明操作对象的同时来管理/控制这些对象特有的复杂性？增加一层间接层是软件开发中常见的解决方式。看下结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290619654.webp" alt="2010-12-29_124225" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Subject：该类中定义了一些RealSubject和Proxy中共有的方法。&lt;/p&gt;
&lt;p&gt;RealSubject：这个类是Proxy所要代理的实体类，客户端只和Proxy交互。&lt;/p&gt;
&lt;p&gt;代码实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 公共接口
/// &amp;lt;/summary&amp;gt;
interface ISubject
{
 void Request();
}
/// &amp;lt;summary&amp;gt;
/// 被代理的类
/// &amp;lt;/summary&amp;gt;
public class RealSubject : ISubject
{
 public void Request()
 {
 Console.WriteLine(&amp;#34;被代理类的请求&amp;#34;);
 }
}
/// &amp;lt;summary&amp;gt;
/// 代理类
/// &amp;lt;/summary&amp;gt;
public class Proxy : ISubject
{
 RealSubject realSubject=new RealSubject();
 public void Request()
 {
 realSubject.Request();
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户代码
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;param name=&amp;#34;args&amp;#34;&amp;gt;&amp;lt;/param&amp;gt;
static void Main(string[] args)
{
 Proxy proxy = new Proxy();
 proxy.Request();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码非常简单，在客户端使用的是Proxy类，其实调用的是RealSubject类中的方法，起到了代理的目的。&lt;/p&gt;
&lt;h2 id="proxy模式的应用场景"&gt;Proxy模式的应用场景&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;远程代理，也就是为一个对象在不同的地址空间提供局部代表。这样可以隐藏一个对象存在不同地址空间的事实。（net中的webservice）&lt;/li&gt;
&lt;li&gt;虚拟代理，根据需要创建开销很大的对象。通过他来存放实例化需要很长时间的真实对象。&lt;/li&gt;
&lt;li&gt;安全代理，用来控制真实对象访问时的权限。&lt;/li&gt;
&lt;li&gt;智能指引，指当调用这是对象时，代理处理另外一些事情。
[以上四点摘自《大话设计模式》]&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="proxy模式的几个要点"&gt;Proxy模式的几个要点&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;“增加一层间接层”是软件系统中对许多复杂问题的一种常见解决方法。在面向对象系统中，直接使用某些对象会带来很多问题，作为间接层的proxy对象便是解决这一问题的常用手段。&lt;/li&gt;
&lt;li&gt;具体proxy设计模式的实现方法、实现粒度都相差很大，有些可能对单个对象做细粒度的控制，如copy-on-write技术，有些可能对组件模块提供抽象代理层,在架构层次对对象做proxy。&lt;/li&gt;
&lt;li&gt;Proxy并不一定要求保持接口的一致性，只要能够实现间接控制，有时候损及一些透明性是可以接受的。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-1-index/"&gt;返回开篇（索引）&lt;/a&gt;&lt;/p&gt;</description></item><item><title>设计模式笔记(12)—享元模式（结构型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-12-flyweight-pattern/</link><pubDate>Wed, 09 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-12-flyweight-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;运用共享技术有效地支持大量细粒度的对象。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;采用纯粹对象方案的问题在于大量细粒度的对象会很快充斥在系统中，从而带来很高的运行时代价——主要指内存需求方面的代价。如何在避免大量细粒度对象问题的同时，让外部客户程序仍然能够透明地使用面向对象的方式来进行操作？这需要用到享元模式，不过应用享元模式是需要进行评估的，也就是说在当前情况下是否会对系统造成性能上的影响，如果会那么就是用，下面先来看个小例子是如何进行评估的。&lt;/p&gt;
&lt;p&gt;假设有一个字符的类Charator，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Charator
{
 char c;
 Font f;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;为了方便评估，Charator类中的Font类型采用自定义的类型：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Font
{
 string fontName;
 int size;
 Color color;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在客户代码中使用Charator类&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class App
{
 static void Main()
 {
 List&amp;lt;Charator&amp;gt; list=new List&amp;lt;Charator&amp;gt;(100000);
 for (int i = 0; i &amp;lt; list.Count; i++)
 {
 Charator charator = new Charator();
 list.Add(charator);
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在客户代码中将Charator类实例化了100000次，Charator类中有两个成员，并且有个成员为Font类型，Font类型中又定义了三个成员，下面将在代码注释中标出要占用的内存量：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 如果有n个Font对象占用大小为12bytes*n 其实字符串类型
/// 除了本身占用的4bytes外 还有一个引用指针要占用4bytes，
/// 不过这个 不会构成倍乘效应，也就是当有n个对象时不会
/// 以n的倍数增长，所以可以忽略
/// &amp;lt;/summary&amp;gt;
public class Font
{
 string fontName; //4bytes
 int size; //4bytes
 Color color; //4bytes
}
/// &amp;lt;summary&amp;gt;
/// 总共占用2+20+4+8+2=36bytes
/// 第三个的4为指向font的指针
/// 第四个的8为虚表指针和垃圾回收和同步
/// 最后的2为char的填充位
/// &amp;lt;/summary&amp;gt;
public class Charator
{
 /// &amp;lt;summary&amp;gt;
 /// 占用2bytes
 /// &amp;lt;/summary&amp;gt;
 char c;
 /// &amp;lt;summary&amp;gt;
 /// 总占用12bytes+4bytes+4bytes =20bytes
 /// 其中12bytes是三个成员的，另外的两个4bytes分别为
 /// 虚表指针和net垃圾回收机制所需要的一些位，因为每个
 /// 类型最终都可以追溯到object类型，所以默认都会有虚函数
 /// 4byte的虚表指针式不可少的
 /// &amp;lt;/summary&amp;gt;
 Font f; 

}
/// &amp;lt;summary&amp;gt;
/// 36bytes * 100000=3600000bytes =3600k=3.6mb
/// &amp;lt;/summary&amp;gt;
public class App
{
 static void Main()
 {
 List&amp;lt;Charator&amp;gt; list=new List&amp;lt;Charator&amp;gt;(100000);
 for (int i = 0; i &amp;lt; list.Count; i++)
 {
 Charator charator = new Charator();
 list.Add(charator);
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码执行会带来3mb多的内存数据，这个对于现在的机器来说算不了什么，上面例子中是做了100000次的计算，那如果再加两个数量级到10000000又会怎么样了，那就会有300多mb，这个数字肯定是不能接受的，那么这个时候就要考虑用享元模式了。 看下面改进后的代码：&lt;/p&gt;</description></item><item><title>设计模式笔记(11)—外观模式（结构型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-11-appearance-pattern/</link><pubDate>Mon, 07 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-11-appearance-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;为子系统中的一组接口提供一个一致的界面，Façade模式定义了一个高层接口，这个接口使得这一子系统更加容易使用。&lt;/p&gt;
&lt;p&gt;先来看个小例子，假设我们需要开发一个坦克模拟系统用于模拟坦克车在各种作战环境中的行为，其中坦克系统由引擎、控制器、车轮、车身等各子系统构成。就会有下面这些类的产生&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Wheel{ }
public class Engine{ }
public class Controller{ }
public class BodyWork{ }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;不同的场景中的要求都不一样，可能会用到某些子系统，也可能不会用到，这些不同的场景就相当是外部接口，这些场景和子系统的关系如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290618615.webp" alt="2010-12-29_125236" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;图1&lt;/p&gt;
&lt;p&gt;上图中的关系感觉很混乱，场景和子系统之间的耦合度很高，要降低这种耦合度，就要使和场景之间交互的不是这些子系统了，而是相对单一的一个中间层，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290618206.webp" alt="2010-12-29_125304" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;图2&lt;/p&gt;
&lt;p&gt;上图的Facade就将子系统隐藏了，不同的场景都是直接和Facade交互。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;上面图1方案的问题在于组件的客户和组件中各种复杂的子系统有了过多的耦合，随着外部客户程序和各子系统的演化，这种过多的耦合面临很多变化的挑战。如何简化外部客户程序和系统间的交互接口？如何将外部客户程序的演化和内部子系统的变化之间的依赖相互解耦？这就要用到Facade模式，先来看结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290618557.webp" alt="2010-12-29_125333" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;代码实现，先定义一些子系统类&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Wheel
{
 public void WAction1() { }
 public void WAction2() { }
}
public class Engine
{
 public void EAction1() { }
 public void EAction2() { }
}
public class Controller
{
 public void CAction1() { }
 public void CAction2() { }
}
public class BodyWork
{
 public void BAction1() { }
 public void BAction2() { }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Facade类，用来组合这些子系统&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class TankFacade
{
 Wheel[] wheels = new Wheel[4];
 Engine[] engines = new Engine[4];
 BodyWork bodywork = new BodyWork();
 Controller controller = new Controller();

 public void Start()
 {
 //用到子系统中的一个或多个
 }
 public void Stop()
 {
 //用到子系统中的一个或多个
 }
 public void Run()
 {
 //用到子系统中的一个或多个
 }
 public void Shot()
 {
 //用到子系统中的一个或多个
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;客户端调用&lt;/p&gt;</description></item><item><title>设计模式笔记(10)—装饰模式（结构型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-10-decorative-pattern/</link><pubDate>Fri, 04 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-10-decorative-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;动态地给一个对象增加一些额外的职责。就增加功能而言，Decorator模式比生成子类更为灵活。&lt;/p&gt;
&lt;p&gt;首先来看一个小例子，假如我们需要给游戏开发一种坦克，除了各种不同型号的坦克外，还希望在不同的场合来给坦克增加以下的一种或多种功能：比如红外线夜视功能、水陆两栖功能、GPS定位功能等。通常做法如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 抽象坦克
/// &amp;lt;/summary&amp;gt;
public abstract class Tank
{
 public abstract void Shot();
 public abstract void Run();
}

//型号
public class T50 : Tank { }
public class T60 : Tank { }
public class T70 : Tank { }

//在不同场合下的各种功能都抽象为接口，
//如果某种型号的坦克需要某种功能就继承该功能接口
//下面的IA IB IC 为功能A B C的接口
/// &amp;lt;summary&amp;gt;
/// 有A功能的T50型号
/// &amp;lt;/summary&amp;gt;
public class T50A : T50, IA { }
/// &amp;lt;summary&amp;gt;
/// 有A B两种功能的T60型号
/// &amp;lt;/summary&amp;gt;
public class T60AB : T60, IA, IB { }
/// &amp;lt;summary&amp;gt;
/// 有A B C三种功能的T70型号
/// &amp;lt;/summary&amp;gt;
public class T70ABC : T70, IA, IB, IC { }
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;上面描述的问题的根源在于我们“过多地使用了继承来扩展对象的功能”，由于继承为赖幸引入了静态特质，使得这种扩展方式缺乏灵活性，并且随着子类的增多（扩展功能的增多)，各种子类的组合（扩展功能的组合）会导致更多子类的膨胀（多继承）。那么如何使“对象功能的扩展”能够根据需要来动态地实现，同时避免“扩展功能的增多”带来的子类膨胀问题，从而使得任何“功能的变化”所导致的影响减为最低呢？这就需要用到装饰模式（Decorator）。下面先来看下装饰模式的结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290619381.webp" alt="" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;Component：对应上面例子中的Tank。&lt;/p&gt;
&lt;p&gt;ConcreteComponent：对应坦克的型号 T50 T60 T70等。&lt;/p&gt;
&lt;p&gt;DeCorator ConcreteDecoratorA ConcreteDecoratorB 这三个类就是接下来要实现了。&lt;/p&gt;</description></item><item><title>设计模式笔记(9)—组合模式（结构型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-9-portfolio-pattern/</link><pubDate>Wed, 02 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-9-portfolio-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;将对象组合成树形结构以表示“部分–整体”的层次结构。Composite使得用户对单个对象和组合对象使用具有一致性。&lt;/p&gt;
&lt;p&gt;在面向对象系统中，我们经常会遇到一类具有”容器“特征的对象—即他们在充当对象的同时，又是其他对象的容器。比如在一些管理系统中就会出现总公司下面有很多的分公司，分公司下面有很多的部门，每个部门下又有很多的员工，像分公司和部门就是既充当了“对象”的角色也充当了“容器”的角色；还有我们可能玩过的“俄罗斯套娃”也是这种结构，一个大娃娃里面装个小娃娃，小的里面又有个小的直到最小的一个，中间的娃娃就是既充当了“对象”也充当了“容器”。先看下面这个例子:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;interface IBox
{
 void Process();
}
/// &amp;lt;summary&amp;gt;
/// 相当于树的叶子节点，没有子对象了
/// &amp;lt;/summary&amp;gt;
public class SingleBox : IBox
{
 public void Process()
 { 

 }
}
/// &amp;lt;summary&amp;gt;
/// 容器
/// &amp;lt;/summary&amp;gt;
public class ContainerBox : IBox
{
 List&amp;lt;IBox&amp;gt; list = new List&amp;lt;IBox&amp;gt;();
 public void Process() { }
 public List&amp;lt;IBox&amp;gt; GetBoxes()
 {
 return list;
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户代码
/// &amp;lt;/summary&amp;gt;
public class App
{
 static void Mina()
 {
 ///此处从工厂方法中得到盒子的对象，但我们不知道是SingleBox还是ContainerBox
 ///所以要做判断
 IBox box = Factory.Create();
 if (box is ContainerBox)
 {
 box.Process();
 List&amp;lt;IBox&amp;gt; list = ((ContainerBox)box).GetBoxes();
 }
 else if(box is SingleBox)
 {
 box.Process();
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;上面代码的问题的根据在于：客户代码过多地依赖对象容器复杂的内部实现结构，对象容器内部实现结构（而非抽象接口）的变化将引起客户代码的频繁变化，带来了代码的维护性、扩展性等弊端。&lt;/p&gt;
&lt;p&gt;如何将“客户代码与复杂的对象容器结构”解耦？让对象容器自己来实现自身的复杂结构，从而使得客户代码就像处理简单对象一样来处理复杂的对象容器？&lt;/p&gt;
&lt;p&gt;这就要使用Composite模式了，先看下Composite模式的结构图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281850646.webp" alt="image-20220128185053657" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Component：定义了Leaf和Composite的一些共有特性。&lt;/li&gt;
&lt;li&gt;Composite：有容器特征的类型。&lt;/li&gt;
&lt;li&gt;Leaf：叶节点，即一个单独的个体，下面没有子节点。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;依据上面的结构图完成代码实现：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class Component
{
 protected string _name;
 public Component(string name)
 {
 _name = name;
 }
 public abstract void Operation();
 public abstract void Add(Component component);
 public abstract void Remove(Component component);
}

public class Leaf : Component
{
 public Leaf(string name) : base(name) { }
 public override void Add(Component component)
 {
 throw new NotSupportedException();
 }
 public override void Remove(Component component)
 {
 throw new NotSupportedException();
 }

 public override void Operation()
 {
 //...do something
 }
}

public class Composite : Component
{
 public Composite(string name):base(name){}
 List&amp;lt;Component&amp;gt; list = new List&amp;lt;Component&amp;gt;();
 /// &amp;lt;summary&amp;gt;
 /// 添加
 /// &amp;lt;/summary&amp;gt;
 /// &amp;lt;param name=&amp;#34;conponent&amp;#34;&amp;gt;&amp;lt;/param&amp;gt;
 public override void Add(Component component)
 {
 if (list != null)
 {
 list = new List&amp;lt;Component&amp;gt;();
 }
 list.Add(component);
 }
 /// &amp;lt;summary&amp;gt;
 /// 删除
 /// &amp;lt;/summary&amp;gt;
 /// &amp;lt;param name=&amp;#34;component&amp;#34;&amp;gt;&amp;lt;/param&amp;gt;
 public override void Remove(Component component)
 {
 if (list == null)
 {
 throw new NullReferenceException();
 }
 list.Remove(component);
 }

 public override void Operation()
 {
 if (list != null)
 {
 foreach (Component c in list)
 {
 c.Operation();
 }
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Leaf类为叶子节点类，它的实例是没有子节点的，但是在抽象类中的方法Add和Remove方法必须要实现，按理说这样的实现是没有意义的，所以在此处抛出了NotSupportedException 异常，在客户端调用捕获到再做相应的处理，这种模式称之为“透明足组合模式”，这样做的好处是叶子（Leaf）和容器（Composite）对于外界没有分别，它们具有一致的接口行为。还有一种情况叫“安全组合模式”，在抽象类（Component）中不定义Add Remove方法，而是在容器的实现类中去定义，这样就各司其职了，看下面结构图：&lt;/p&gt;</description></item><item><title>设计模式笔记(8)—桥接模式（结构型）</title><link>https://fwhyy.com/2009/12/design-patterns-notes-8-bridge-pattern/</link><pubDate>Tue, 01 Dec 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/12/design-patterns-notes-8-bridge-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;将抽象部分与实现部分分离，使他们都可以独立地变化。&lt;/p&gt;
&lt;p&gt;先来看一个简单的例子，假设我们需要开发一个同时支持PC和手机的坦克游戏，游戏在PC和手机上的功能都一样，有同样的类型，有同样的功能需求变化，而这些游戏中的坦克有多种不同的型号：T50 T60等。根据面向对象的思想，我们可以很容易设计一个坦克(Tank)的抽象类，然后不同的型号都继承抽象类，并且PC和手机上的图形绘制，操作等都是不相同的，所以不同的平台都要提供自己的一套实现：&lt;/p&gt;
&lt;p&gt;坦克抽象类&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 坦克的抽象类
/// &amp;lt;/summary&amp;gt;
public abstract class Tank
{
 public abstract void Start();
 public abstract void Attack();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;各种不同的型号&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// T50型号
/// &amp;lt;/summary&amp;gt;
public class T50:Tank
{
 public override void Attack(){}
 public override void Start(){}
}
/// &amp;lt;summary&amp;gt;
/// T60型号
/// &amp;lt;/summary&amp;gt;
public class T60:Tank
{
 public override void Attack(){}
 public override void Start(){}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;手机上的实现&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// MobileT50型号
/// &amp;lt;/summary&amp;gt;
public class MobileT50 : T50
{
 /// &amp;lt;summary&amp;gt;
 /// 启动
 /// &amp;lt;/summary&amp;gt;
 public override void Start(){}
 /// &amp;lt;summary&amp;gt;
 /// 攻击
 /// &amp;lt;/summary&amp;gt;
 public override void Attack(){}
}
/// &amp;lt;summary&amp;gt;
/// MobileT60型号
/// &amp;lt;/summary&amp;gt;
public class MobileT60 : Tank
{
 /// &amp;lt;summary&amp;gt;
 /// 启动
 /// &amp;lt;/summary&amp;gt;
 public override void Start(){}
 /// &amp;lt;summary&amp;gt;
 /// 攻击
 /// &amp;lt;/summary&amp;gt;
 public override void Attack(){}
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;PC上的实现&lt;/p&gt;</description></item><item><title>程序员怎样学习英语</title><link>https://fwhyy.com/2009/11/the-programmer-how-to-learn-english/</link><pubDate>Sat, 28 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/the-programmer-how-to-learn-english/</guid><description>&lt;p&gt;英语的重要性已经毋庸置疑，对于程序员来说更甚，一些最新的技术资料是英文的，如果想进入外企英语也是一个很重要的条件。对于程序员来说怎样学习好英语，在此谈一下我的一些学习经验。希望对英语像我这样不怎么好的朋友有所帮助，也欢迎大家提出意见和建议。&lt;/p&gt;
&lt;p&gt;英语的学习不外乎“听说读写”，按照通常的英语学习来说“听说读写”这个顺序是有道理的，语言最大的用处就是用来交流，听说排在首位无可厚非。不过对于程序员来说我认为读应该是最重要的，良好的阅读能力对于我们查阅资料、使用一些英文软件、订阅国外大牛的blog都会带来很大的方便。我个人将英语的学习分为三个步骤：单词、阅读、听说，下面分别来说一下。&lt;/p&gt;
&lt;h2 id="单词"&gt;单词&lt;/h2&gt;
&lt;p&gt;单词英语学习的基础，上学时记单词总是抱着本四六级之类的字典，从A开始往后记，这样很费时间而且也没有针对性。对于工作了的朋友来说时间应该不会像在学习时那样多了，在业余的时间要关注新的技术，有的人可能还会接点私活，挤点时间出来了可能还要陪老婆逛逛街，所以不太可能每天专门抽出固定时间来记单词。我的做法是利用每天的若个的“小时间”，这个“小时间”是指上班的公交车上或地铁上（在车上有座就看书没座就记单词），上下班的路上时间可能很长，这个时间可是很宝贵的，不能浪费了。类似这样的“小时间”每天会有很多，这个因人而异。至于单词的来源我都是在看英文资料，博客，等的时候出现不认识的我都会记在一个小的便签本上，这个本随身携带，所有的“小时间”都可以拿出来看上一眼，像我每天晚上都会去健身房，有的人在跑步机上会听音乐看电视，而我在边跑步时也会不时掏出小本看一下，二十几分钟下来也能记住不少。很多人都说没有时间，我觉得只要肯挤总会有的。&lt;/p&gt;
&lt;h2 id="阅读"&gt;阅读&lt;/h2&gt;
&lt;p&gt;阅读我主要是看一些国外技术网站，博客，还有就是一些原版的技术书籍，不过看英文书籍的时候不多，主要原因还是水平不够，所以还是以博客为主。就像上面所说的遇到不认识的单词我会记到便签本上，然后在每天的“小时间”去搞定。对于英文的东西，很多人会有抵触心理，当初我注册Twitter的时候，一看全是英文的，也差点就直接点关闭了，不过最终还是注册并使用了，现在也很适应那种全英文的界面了。所以说适应是很重要的，随着词汇量的增大，会发现看懂英文的文档或博客文章没有想象的那样难。&lt;/p&gt;
&lt;h2 id="听说"&gt;听说&lt;/h2&gt;
&lt;p&gt;听说才是语言的根本，在这里却排在了后面，因为在很多的程序员的工作中，更多的是需要查阅英文的资料或文档，而实际用英语来交流的相对较少。但是如果在您有很好技术的同时还够讲一口流利的英语，那肯定会使您在职业生涯中获得更多的机会。我很喜欢看美剧，所以理所当然“听说”我也是从美剧入手，《老友记》是用来练习口语的一个很不错的片子，够长也够生活化。第一遍用中文字幕，先了解大概故事内容，然后就可以使用英文字幕看了，并记录常用的语句，同样还是利用“小时间”去记住它。光记住了还不行，得开口说，如果没有对话环境就自己对着镜子练吧。相信看完10季的《老友记》看完听说的能力一定会提升一个台阶的。当然看视频时很费时间的，这个得每天抽出点时间来看。不要舍不得那点时间，听说能力练好了，老赵辛苦上传的那些&lt;a href="http://u.youku.com/user_show/id_UMTgxMDQ3OTIw.html"&gt;视频&lt;/a&gt;我们就能享受到了。&lt;/p&gt;
&lt;h2 id="总结"&gt;总结&lt;/h2&gt;
&lt;p&gt;上面说了一些自己的一些学习方法，目前来看利用“小时间”记单词的方法是很有效的。其实每个人都有适合自己的学习方法，关键就是是否能持续学下去，坚持下去。如果您有什么好的学习方法欢迎和大家分享。&lt;/p&gt;</description></item><item><title>去健身房已经两个礼拜了初见成效</title><link>https://fwhyy.com/2009/11/go-to-the-gym-already-two-weeks-produced-results/</link><pubDate>Thu, 26 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/go-to-the-gym-already-two-weeks-produced-results/</guid><description>&lt;p&gt;工作以来，运动是越来越少，特别是在冬天，每天几乎都在电脑跟前，以至于肚子上的赘肉逐渐多了起来，所以在半个月前我在公司旁边的帕菲克办了张季卡（400），每天下班后过去锻炼一个小时，基本以跑步为主，附加仰卧起坐和一些力量的练习。截止到今天已经去了6次，频率也还算是比较高的，感觉腹部平坦了不少，呵呵，可能是心理作用。不过我相信只要这个冬天能够坚持下来，一定会很有效果的。&lt;/p&gt;
&lt;p&gt;加油！！自己给自己打打气！&lt;/p&gt;</description></item><item><title>设计模式笔记(7)—适配器模式（结构型）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-7-adapter-pattern/</link><pubDate>Thu, 26 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-7-adapter-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;将一个类的接口转换成客户所希望的另一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件系统中，由于应用环境的变化，常常要将“一些现存的对象”放在心的环境中应用，但是新环境要求的接口是这些现存对象所不满足的。&lt;/p&gt;
&lt;p&gt;适配的意思是在不改变原有实现的基础上，将原先不兼容的接口转换为兼容的接口。在我们的生活中有着很多适配器的例子，笔记本的电源适配器、一些卡的USB读卡器等等。&lt;/p&gt;
&lt;p&gt;在Gof23这本书中将适配器模式分成了两种：对象适配器和类适配器&lt;/p&gt;
&lt;p&gt;对象适配器&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201281852658.webp" alt="2010-12-29_140647" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;上图中的Target是客户所期待的，希望去使用的类或接口。Adaptee是被适配的对象。Adapter为适配的对象。首先将上图中的结构还原成代码，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
 /// 客户要使用的类
 /// &amp;lt;/summary&amp;gt;
 public abstract class Target
 {
 public abstract void Request();
 }

 /// &amp;lt;summary&amp;gt;
 /// 被适配的类
 /// &amp;lt;/summary&amp;gt;
 public class Adaptee
 {
 public void SpecificRequest()
 { 

 }
 }

 /// &amp;lt;summary&amp;gt;
 /// 适配对象
 /// &amp;lt;/summary&amp;gt;
 public class Adapter : Target
 {
 private Adaptee adapee = new Adaptee();

 public void Request()
 {
 adapee.SpecificRequest();
 }
 }

 /// &amp;lt;summary&amp;gt;
 /// 客户程序
 /// &amp;lt;/summary&amp;gt;
 public class App
 {
 static void Main(string[] args)
 {
 Target target = new Adapter();
 //对客户来说是调用的Request，实际上是调用的SpecificRequest
 target.Request();
 }
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;接着根据上面的思路来看一个实际例子，我们要来实现一个对栈的操作，有一个IStact接口，里面有三个方法Push(进栈)、Pop(出栈)和GetTopItem(取最顶层元素)，这个IStact接口将相当于上面的Target，想要实现进栈出栈的操作，如果自己去实现数据结构显得比较麻烦，在此可以将net提供的ArrayList类拿来一用，ArrayList类就是被适配的对象，相当于上面的Adaptee。在写一个适配类StactAdapter类完成功能就可以了。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// 栈的接口
/// &amp;lt;/summary&amp;gt;
public interface IStack
{
 void Push(object item);
 void Pop();
 Object GetTopItem();
}
/// &amp;lt;summary&amp;gt;
/// 对象适配器
/// &amp;lt;/summary&amp;gt;
public class StactAdapter:IStack
{
 ArrayList list;
 /// &amp;lt;summary&amp;gt;
 /// 构造函数中实例化ArrayList
 /// &amp;lt;/summary&amp;gt;
 public StactAdapter()
 {
 list = new ArrayList();
 }
 /// &amp;lt;summary&amp;gt;
 /// 进栈
 /// &amp;lt;/summary&amp;gt;
 /// &amp;lt;param name=&amp;#34;item&amp;#34;&amp;gt;压入栈的元素&amp;lt;/param&amp;gt;
 public void Push(object item)
 {
 list.Add(item);
 }
 /// &amp;lt;summary&amp;gt;
 /// 出栈
 /// &amp;lt;/summary&amp;gt;
 public void Pop()
 {
 list.RemoveAt(list.Count - 1);
 }
 /// &amp;lt;summary&amp;gt;
 /// 取最顶层的元素
 /// &amp;lt;/summary&amp;gt;
 /// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;
 public Object GetTopItem()
 {
 return list[list.Count - 1];
 }
}
/// &amp;lt;summary&amp;gt;
/// 客户调用
/// &amp;lt;/summary&amp;gt;
public class App
{
 static void Main(string[] args)
 {
 IStack myStack = new StactAdapter();
 myStack.Push(&amp;#34;oec2003&amp;#34;);
 myStack.Push(&amp;#34;oec2004&amp;#34;);
 myStack.Push(&amp;#34;oec2005&amp;#34;);
 myStack.Pop();
 Console.WriteLine(myStack.GetTopItem());
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Adapter模式理解起来也非常简单，IStact中的Push和Pop方法就是添加元素和移除元素的功能，正好系统类ArrayList中就提供了Add和RemoveAt这样的方法，所以就可以拿来借用，通过适配器类（StactAdapter）的转换使得Push和Pop方法可以支持添加和移除元素的功能，就像我们经常使用的笔记本一样，本来现实中的电压和笔记本所需要的电压不相符，通过电源适配器的转换就将现实中的电压转换成笔记本所需要的电压。&lt;/p&gt;</description></item><item><title>设计模式笔记(6)—原型模式（创建型）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-6-prototype-pattern/</link><pubDate>Tue, 24 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-6-prototype-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;使用原型实例指定创建对象的种类，然后通过拷贝这些原型来创建新的对象。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件系统中，经常面临着“某些结构复杂的对象”的创建工作，但由于需求的变化，这些对象将成面临着剧烈的变化，但他们拥有比较稳定一致的接口。&lt;/p&gt;
&lt;p&gt;假设在一些打斗游戏场景中，有这样一些角色，普通(NormalActor),可以飞的(FlyActor)，可以潜水的(WaterActor)&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class NormalActor { }
public abstract class FlyActor { }
public abstract class WaterActor { }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的三个类都是抽象类，自然会有具体的类来继承这些抽象类&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class NormalActorA : NormalActor { }
public class FlyActorA : FlyActor { }
public class WaterActorA : WaterActor { }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在游戏运行中就会去使用这些角色的具体类，如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class GameSystem
{
 public void Run()
 {
 NormalActorA normalActor1 = new NormalActorA();
 NormalActorA normalActor2 = new NormalActorA();
 NormalActorA normalActor3 = new NormalActorA();
 NormalActorA normalActor4 = new NormalActorA();
 NormalActorA normalActor5 = new NormalActorA();

 FlyActorA flyActor1 = new FlyActorA();
 FlyActorA flyActor2 = new FlyActorA();

 WaterActorA waterActor1 = new WaterActorA();
 WaterActorA waterActor2 = new WaterActorA();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在GameSystem类中，我们直接使用具体类（NormalActorA）等来创建对象，GameSystem就对这些具体类产生了依赖，在DIP（依赖倒置原则）中讲到抽象不应依赖具体实现，具体实现应依赖于抽象，所以GameSystem中的代码要进行如下改动&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class GameSystem
{
 public void Run(NormalActor normalActor, FlyActor flyActor,
 WaterActor waterActor)
 {
 NormalActor normalActor1 = normalActor.Clone();
 NormalActor normalActor2 = normalActor.Clone();
 NormalActor normalActor3 = normalActor.Clone();
 NormalActor normalActor4 = normalActor.Clone();
 NormalActor normalActor5 = normalActor.Clone();

 FlyActor flyActor1 = flyActor.Clone();
 FlyActor flyActor2 = flyActor.Clone();

 WaterActor waterActor1 = waterActor.Clone();
 WaterActor waterActor2 = waterActor.Clone();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;经过修改在GameSystem类中已经看不到具体类的影子了，创建对象是通过传入的抽象类类型的参数的Clone方法来创建，关于Clone方法在后面讲到，这样GameSystem就只依赖于抽象了。&lt;/p&gt;</description></item><item><title>设计模式笔记(5)—工厂方法模式（创建型）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-5-factory-method-pattern/</link><pubDate>Sun, 22 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-5-factory-method-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;定义一种用于创建对象的借口，让子类决定实例化哪一个类，Factory Method使得一个类的实例化延迟到子类。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件系统中，经常面临着“某个对象”的创建工作；由于需求的变化，这个对象经常面临着剧烈的变化，但是它却拥有比较稳定的借口。&lt;/p&gt;
&lt;p&gt;假设有这样的一个场景，有一个汽车类和一个汽车测试框架类，汽车测试框架负责对汽车来进行测试，通常情况下我们会想下面这样写。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Car
{
 public void Startup() { }

 public void Run(){ }

 public void Turn(Direction direction) { }

 public void Stop() { }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;测试框架类&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class CarTestFramework
{
 public void BuildTestContext()
 {
 Car car = new Car();
 //do something
 }

 public void DoTest()
 {
 Car car = new Car();
 //do something
 }

 public void GetTestData()
 {
 Car car = new Car();
 //do something
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在上面的测试框架类CarTestFramework中的每个方法都有可能去实例化Car类。上面的代码中是直接实例化的
Car类。这样测试框架类和汽车之间有很强的依赖关系。实际中我们的测试框架类不可能只测试一种类型的汽车，
所以当被测试的车的类型发生变化时，测试框架类中也要变化，这当然不是我们想要的。现在就把汽车类给抽象
起来。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class AbstractCar
{
 public abstract void Startup();

 public abstract void Run();

 public abstract void Turn(Direction direction);

 public abstract void Stop();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;抽象的汽车类创建了，那么测试框架类也会发生相应的变化，我们可能会很快地拿AbstractCar特换掉Car，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class CarTestFramework
{
 public void BuildTestContext()
 {
 AbstractCar car = new AbstractCar();
 //do something
 }

 //....
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;很容易可以看出来，上面的代码其实是错误的，抽象类不能实例化。这时可能还会想到另外一种方法用抽象类来实例化子类。&lt;/p&gt;</description></item><item><title>设计模式笔记(4)—生成器模式（创建型）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-4-generator-pattern/</link><pubDate>Sat, 21 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-4-generator-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;将一个复杂对象的构建与其表示相分离，使其同样的构建过程可以创建不同的表示。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件系统中，有时侯面临着一个复杂对象的创建工作，这个发展对象通常是由各个部分的子对象用一定的算法构成；由于需求的变化，这个复杂的对象的各个部分经常面临着巨大的变化，但是将他们组合起来的算法相对稳定。&lt;/p&gt;
&lt;p&gt;还是拿游戏中的房屋作为例子来讲，房屋由门、窗户、墙、地板、天花板组成。这些组成部分可能是经常要发生变化的。如果按常规设计，这些组成部分中的任何一个发生变化时都将使房屋重建，生成器模式的作用就是要使这些组件的变化不影响到房屋。首先构建一个House类&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class House
{
 //该类中可能包含复杂的创建逻辑
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;下面的是一个抽象的构建类，用类构建房屋的组件&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class Builder
{
 public abstract void BuildDoor();
 public abstract void BuildWall();
 public abstract void BuildWindow();
 public abstract void BuildFloor();
 public abstract void BuildHouseCeiling();

 public abstract House GetHouse();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;假设在一个游戏管理类（GameManager）中来完成对房屋的构建&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class GameManager
{
 public static House CreateHouse(Builder builder)
 {
 builder.BuildDoor();

 builder.BuildWindow();
 builder.BuildWindow();

 builder.BuildWall();
 builder.BuildWall();
 builder.BuildWall();
 builder.BuildWall();

 builder.BuildFloor();
 builder.BuildHouseCeiling();

 return builder.GetHouse();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在GameManager类中都是使用的抽象类来完成房屋的构建，所以GameManager类基本上是稳定的，可能出现变化的是创建门或是窗户的个数，当然这个我们可以在数据库中记录。稳定的部分已经创建，现在就来创建经常会变动的部分，假设现在需要构建一个罗马风格的房屋，可以写一个RomanHouse和一个RomanHouseBuilder类来继承House类和Builder类。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class RomanHouse:House {}

public class RomanHouseBuilder : Builder
{
 public override void BuildDoor() { }
 public override void BuildFloor() {}
 public override void BuildHouseCeiling(){ }
 public override void BuildWall(){}
 public override void BuildWindow(){}
 public override House GetHouse()
 {
 return new RomanHouse();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;如果需要其他风格的访问，同可以创建相应的类继承House和HouseBuilder就可以。&lt;/p&gt;
&lt;p&gt;客户端调用的代码如下&lt;/p&gt;</description></item><item><title>VS中的经典字体推荐</title><link>https://fwhyy.com/2009/11/vs-font-recommended/</link><pubDate>Fri, 20 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/vs-font-recommended/</guid><description>&lt;p&gt;每天编码眼睛看着vs，一个好的字体和背景色能使我们的心情更愉悦，眼睛的疲劳度也随之降低。&lt;/p&gt;
&lt;p&gt;微软发布过针对VS2005的编程字体Consolas，个人感觉这个字体还不错，可以点击下面链接下载&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=22e69ae4-7e40-4807-8a86-b3d36fab68d3&amp;amp;displaylang=en"&gt;猛击这里下载&lt;/a&gt;
对于背景色我比较喜欢浅黄色，据说能保护眼睛，虽然有点夸张但确实比纯白色看着要舒服。&lt;/p&gt;</description></item><item><title>设计模式笔记(3)—抽象工厂模式（创建型）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-3-abstract-factory-pattern/</link><pubDate>Fri, 20 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-3-abstract-factory-pattern/</guid><description>&lt;h2 id="gof定义"&gt;Gof定义&lt;/h2&gt;
&lt;p&gt;提供一个借口，让该接口负责创建一系列_相关或者相互依赖的对象_，无需指定他们具体的类。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;在软件系统中经常面临着_一系列相互依赖的对象_的创建的工作，同时由于需求的变化，往往存在着更对系列对象的创建。&lt;/p&gt;
&lt;p&gt;常规的对象创建的方法，直接使用new关键字&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Road road = new Road();
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这样直接new会有一个问题，不能应对具体实例化类型的变化，比如说有不同的Road类型需要被实例化的时候就需要来更改此处的代码。解决这个问题的办法就是封装变化点，变化点也是相对而言的，比如在项目中有些地方会经常更具客户的需求而作改动，我们就可以将其封装起来。拿上面的那行代码来说，因为可能有不同类型的Road需要被创建，变化点就是“对象的创建”。&lt;/p&gt;
&lt;p&gt;一种比较简单的解决方法，看下面的代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class RoadFactory
{
 public static Road CreateRoad()
 {
 return new Road();
 }
}
//调用的代码
public class Test
{
 static void Main(string[] args)
 {
 Road road = RoadFactory.CreateRoad();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在需求有了改变，需要创建一种另一种类型的路HighRoad，只需更改工厂类的代码就可以，调用的地方不用做修改，如下&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class RoadFactory
{
 public static Road CreateRoad()
 {
 return new HighRoad();
 }
} 
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在需求又有了改变，比如在游戏的开发场景中，我们需要构建道路、房屋、丛林等等对象，按照上面的思路我 可以写成下面这样的代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;//客户程序
 public class Test
 {
 static void Main(string[] args)
 {
 Road road = GameObjectFactory.CreateRoad();
 Building building = GameObjectFactory.CreateBuilding();
 Jungle jungle = GameObjectFactory.CreateJungle();
 }
 }

 public class GameObjectFactory
 {
 public static Road CreateRoad()
 {
 return new Road();
 }
 public static Building CreateBuilding()
 {
 return new Building();
 }
 public static Jungle CreateJungle()
 {
 return new Jungle();
 }
 }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上的代码属于一种简单工厂的实现，将对象的创建放到一个单独的工厂类中，实现了和客户程序的分离，不过 不能应对不同系列对象的变化，比如有不同风格的游戏场景，对于要实现不同风格场景中的道路、房屋等对象的 创建，上面的代码就难以实现。对于有_不同系列对象_这样的需求，变化点转移到了工厂类的内部，上面的代码中 对象的创建是在工厂类中的静态方法中写死的，不能应对变化，如果我们另外创建一个能适应其他系列的工厂类， 那么客户程序就会发生改变，这不是我们希望看到的。要解决此类问题必须使用面向对象的技术来封装变化点。
结构图&lt;/p&gt;</description></item><item><title>设计模式笔记(2)—单件模式（创建型）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-2-singleton-pattern/</link><pubDate>Thu, 19 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-2-singleton-pattern/</guid><description>&lt;h2 id="gof-定义"&gt;Gof 定义&lt;/h2&gt;
&lt;p&gt;保证一个类仅有一个实例，并提供一个该实例的全局访问点。&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;保证在系统中只存在一个实例，这样才能保证逻辑的正确性和良好的效率。&lt;/p&gt;
&lt;h2 id="单件模式单线程环境下实现"&gt;单件模式单线程环境下实现&lt;/h2&gt;
&lt;p&gt;看下面一段代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Singleton
{
 private static Singleton _instance;
 //定义为私有，让类的使用者不能直接new一个该类的实例
 private Singleton() { }
 public static Singleton Instance
 {
 get
 {
 if (_instance == null)
 {
 _instance = new Singleton();
 }
 return _instance;
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码中将Singleton类的构造函数设置为私有，如果试图去用new去创建一个Singleton的实例，会出现编译错误&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Test
{
 public static void Main()
 {
 //Singleton不可访问，因为他受保护级别限制
 Singleton t = new Singleton();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;要创建Singleton的实例我们可以像下面这样做&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Test
{
 public static void Main()
 {
 Singleton t = Singleton.Instance;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码完成了一个最简单的单例模式的实现，保证了实例的唯一性，如下的测试代码是可以顺利通过的&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[TestMethod()]
public void Test()
{
 Singleton t1 = Singleton.Instance;
 Singleton t2 = Singleton.Instance;

 Assert.AreEqual(true, t1.Equals(t2));
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="单件模式多线程环境下实现"&gt;单件模式多线程环境下实现&lt;/h2&gt;
&lt;p&gt;在多线程环境下上面代码仍然有可能得到Singleton类的多个对象实例，为什么在多线程环境下会可能创建出多个实例呢？看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Singleton
{
 private static Singleton _instance;
 //定义为私有，让类的使用者不能直接new一个该类的实例
 private Singleton() { }
 public static Singleton Instance
 {
 get
 {
 //线程A执行到此进行if判断，会进入到if语句里面
 //在线程A执行_instance = new Singleton(); 前，线程B也到了if判断处，
 //此时_instance还没有被创建出来仍然为null，线程B也会进入到if语句中
 //这样线程A和线程B会各自构建一个Singleton的实例
 if (_instance == null)
 {
 _instance = new Singleton();
 }
 return _instance;
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;所以上面的代码示例只能应用在单线程的环境下，如果需要实现在多线程环境下的单件模式就需要对上面的代码进行改进，如下&lt;/p&gt;</description></item><item><title>设计模式笔记(1)—开篇（文章索引）</title><link>https://fwhyy.com/2009/11/design-patterns-notes-1-index/</link><pubDate>Wed, 18 Nov 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/11/design-patterns-notes-1-index/</guid><description>&lt;h2 id="概念"&gt;概念&lt;/h2&gt;
&lt;p&gt;设计模式描述了软件设计过程中某一类常见问题的一般性的解决方案。&lt;/p&gt;
&lt;p&gt;面向对象的设计模式描述了面向对象设计过程中，在特定场景下类与相互通讯的对象之间常见的组织关系。&lt;/p&gt;
&lt;h2 id="设计模式与面向对象"&gt;设计模式与面向对象&lt;/h2&gt;
&lt;p&gt;面向对象设计模式解决的是“类与相互通信的对象之间的组织关系。包括他们的角色、职责、协作方式几个方面。&lt;/p&gt;
&lt;p&gt;面向对象设计模式是“好的面向对象设计”，所谓“好的面向对象设计”是那些可以满足“因对变化，提高复用的设计”。&lt;/p&gt;
&lt;p&gt;面向对象设计模式描述的是软件设计，因此他是独立于编程语言的，但是面向对象设计模式的最终实现仍然要使用面向对象编程语言来表达。&lt;/p&gt;
&lt;p&gt;面向对象设计模式不像算法技巧，可以照搬照用，他是建立在对“面象对象”纯熟、深入的理解的基础上的经验性认识。&lt;/p&gt;
&lt;h2 id="从设计原则到设计模式"&gt;从设计原则到设计模式&lt;/h2&gt;
&lt;p&gt;针对接口编程，而不是针对实现编程—客户无需知道所有使用对象的特定类型，只需要知道对象拥有客户所期望的接口。&lt;/p&gt;
&lt;p&gt;优先使用对象组合，而不是类继承—类继承通常为“白箱复用”，对象组合通常为“黑箱复用”。继承在某种程度上破坏了封装性，子类父类耦合度高；而面向组合只要求组合的对象具有良好定义的接口，耦合度低。&lt;/p&gt;
&lt;p&gt;封装变化点—使用封装来创建对象之间分界曾，让设计者可以在分界曾的一侧进行修改，而不会对另一侧产生不良的影响，从而实现层次间的松耦合。&lt;/p&gt;
&lt;p&gt;使用重构得到模式—设计模式的应用不宜先入为主，一上来就是用设计模式是对设计模式的最大无用。没有一步到位的设计模式。&lt;/p&gt;
&lt;h2 id="几个设计原则"&gt;几个设计原则&lt;/h2&gt;
&lt;p&gt;在设计模式的使用中无时无刻都在贯穿着下面这几个原则，所以说理解了这几个设计原则对学习和理解设计模式有很大的帮助。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;单一职责原（SRP）：一个类应该仅有一个引起它变化的原因。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start="2"&gt;
&lt;li&gt;开放封闭原则（OCP）：类模块应该是可以扩展的，但是不可以修改（多扩展开放，对修改封闭）&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start="3"&gt;
&lt;li&gt;Liskov替换原则（LSP）：子类必须能够替换他们的基类&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start="4"&gt;
&lt;li&gt;依赖倒置原则（DIP）：高层模块不应该依赖于底层模块，二者都应该依赖于抽象；抽象不应该依赖于实现细节，实现细节应该依赖于抽象。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start="5"&gt;
&lt;li&gt;接口隔离原则（ISP）：不应该强迫客户程序依赖于他们不用的方法。&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上面只是简单给出了定义，网上有很多关于这些原则的详细介绍。&lt;/p&gt;
&lt;p&gt;下面简单谈一下我自己对设计模式的认识，设计模式很早就接触了，不过实际在项目中使用过的也只是很少的几个，现在市面上有很多关于设计模式的书，其中不乏有些很生动的例子，非常容易理解，但设计模式并不是写些简单的Demo，个人感觉从很熟悉那些简单的Demo到能够灵活在项目中运用这中间有很长的路要走，需要我们多写、多思考，多总结。之所以要使用设计模式，是因为当变化来临时我们能更方便快捷地解决问题，并且有利于以后的维护。如果没有需求的变化，完全可以用自己认为最简单直接的方式去实现功能，不过需求往往是多变的。我们通常所讲的设计模式指的是面向对象设计模式，所以学习好面向对象的知识是学习面向对象设计模式的前提。最近又将几年前的关于设计模式的webcast讲座翻出来听了听，感觉收获颇多，也顺便做了些笔记以备后用。&lt;/p&gt;
&lt;h2 id="设计模式的分类"&gt;设计模式的分类&lt;/h2&gt;
&lt;p&gt;设计模式分类创建型、结构型、行为型三类。&lt;/p&gt;
&lt;h3 id="创建型"&gt;创建型&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-2-singleton-pattern/"&gt;Singleton 单件&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-3-abstract-factory-pattern/"&gt;Abstract Factory 抽象工厂模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-4-generator-pattern/"&gt;Builder 生成器模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-5-factory-method-pattern/"&gt;Factory Method 工厂方法模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-6-prototype-pattern/"&gt;Prototype 原型模式&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="结构性"&gt;结构性&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/11/design-patterns-notes-7-adapter-pattern/"&gt;Adapter 适配器模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-8-bridge-pattern/"&gt;Bridge 桥接模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-9-portfolio-pattern/"&gt;Composite 组合模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-10-decorative-pattern/"&gt;Decorator 装饰模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-11-appearance-pattern/"&gt;Facade 外观模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-12-flyweight-pattern/"&gt;Flyweight 享元模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-13-proxy-pattern/"&gt;Proxy 代理模式&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="行为型"&gt;行为型&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-14-template-method-pattern/"&gt;TemplateMethod 模板方法模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/12/design-patterns-notes-15-command-pattern/"&gt;Command 命令模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-16-interpreter-pattern/"&gt;Interpreter 解释器模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-17-mediator-pattern/"&gt;Mediator 中介者模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-18-iterator-pattern/"&gt;Iterator 迭代器模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-19-observer-pattern/"&gt;Observer 观察者模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-20-chain-of-responsibility-pattern/"&gt;Chain Of Responsibility 职责链模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-21-memo-pattern/"&gt;Memento 备忘录模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-22-state-pattern/"&gt;State 状态模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/01/design-patterns-notes-23-strategy-pattern/"&gt;Strategy 策略模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/02/design-patterns-notes-24-visitor-pattern/"&gt;Visitor 访问者模式&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/02/design-patterns-notes-25-summary/"&gt;总结&lt;/a&gt;&lt;/p&gt;</description></item><item><title>体验vs2010 （功能改进篇）</title><link>https://fwhyy.com/2009/10/experience-vs2010-improvements/</link><pubDate>Sat, 24 Oct 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/10/experience-vs2010-improvements/</guid><description>&lt;p&gt;下午在使用vs2010进行了一些简单的编码体验，下面谈一下和以前版本的一些不同的地方，仅限于工具的使用方面，有关Net4.0方面的知识将在以后深入研究。&lt;/p&gt;
&lt;p&gt;首先来看下创建项目的对话框，在左边的Installed Templates里多出了几个选项，如Cloud Service、F#等。点击左边栏中的C#，在右边的模板列表中可以看到Silverlight、asp.net mvc2 已经集成在其中了。而在在选择net framework 版本的下拉框的右边有一个排序的对话框，可以根据名称对模板列表进行排序。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300643854.webp" alt="2010-12-29_153755" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;作为一个web开发人员，当然是首先要试试asp.net web application了，点击C#下面的Web，可以在右边的模板列表中看到有Asp.net Web Application 和Empty Asp.net Web Application 两个Asp.net的模板，先来创建一个Asp.net Web Application 。会发现多了一些目录&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300643911.webp" alt="2010-12-29_153841" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;目录相对于以前的版本多了不少，而且还加入了jquery，乍一看好像是创建了Asp.net mvc项目。个人感觉在这些多出了目录用处也不是很多。如果觉得不需要这么多的自动创建的目录和文件可以选择创建Empty Asp.net Web Application 项目，这可是觉得干净的一个项目就只有一个Web.config文件&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300643074.webp" alt="2010-12-29_153930" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;说起Web.config文件，跟vs08里的Web.config文件实在是简化太多了，这个改进也是我非常喜欢的。Net4对应的CLR版本是4.0 以前的2.0、3.0.3.5的CLR版本都是2.0 ，所以Net4中的machine.config文件时和先前版本中的machine.config是并列安装的。新的.NET 4 machine.config文件现在自动注册我们以前所有的ASP.NET 标识部分（section）, 处理器和模块等。所以在项目中见到的Web.config文件时非常简洁的&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;?xml version=&amp;#34;1.0&amp;#34;?&amp;gt;
&amp;lt;configuration&amp;gt;

 &amp;lt;system.web&amp;gt;
 &amp;lt;compilation debug=&amp;#34;true&amp;#34; targetFramework=&amp;#34;4.0&amp;#34; /&amp;gt;
 &amp;lt;/system.web&amp;gt;
 &amp;lt;system.webServer&amp;gt;
 &amp;lt;modules runAllManagedModulesForAllRequests=&amp;#34;true&amp;#34;/&amp;gt;
 &amp;lt;/system.webServer&amp;gt;

&amp;lt;/configuration&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在界面的编码框部分我发现了一个小细节，大家都知道我们可以以标签的形式打开很多的页面，在以前的版本中，关闭的小叉是在最右边，或者是直接再当前标签上点击右键选择关闭。在vs2010中每个标签页上都有一个关闭小叉叉，和现在很多的多标签浏览器类似，这样确实方便了不少。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300643127.webp" alt="2010-12-29_154008" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;现在就来开始编码的体验了，发现vs2010中的代码智能提示相对于以前版本的智能提示有了一个小的改进，不过这个小小的改进还是很有用的，比如在以前版本中输入一个Response会出现所有列表，而在vs2010中会对显示的内容进行过滤只显示和Response相关的。&lt;/p&gt;
&lt;p&gt;vs2008&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300643506.webp" alt="2010-12-29_154409" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;vs2010&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300644084.webp" alt="2009-10-24_221338" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;除了能过滤外还可以对关键词进行搜索，看下图就很清楚了，输入ind后就自动把TabIndex搜索出来了。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300644289.webp" alt="2010-12-29_154545" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在智能提示中还有一种比骄有趣的功能，比如Textbox有BackColor和BorderColor属性，这两个属性都是由两个单词组成，是要输入每个单词的首字母就能将这两个属性过滤出来，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300644676.webp" alt="2009-10-24_223717" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;好了，先就写这么多吧，更多的功能还有待慢慢研究和使用。&lt;/p&gt;
&lt;p&gt;ps 该攒钱买本了啊，我这老爷本跑vs2010还是很吃力啊&lt;/p&gt;</description></item><item><title>体验VS2010（安装篇）</title><link>https://fwhyy.com/2009/10/experience-vs2010-installation/</link><pubDate>Sat, 24 Oct 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/10/experience-vs2010-installation/</guid><description>&lt;p&gt;本来是打算等到vs2010正式版出来之后再安装vs2010体验，不过鉴于才2g多的大小，就提前下载安装了，下面的是安装过程中的一些截图。和以前装vs2008不同的是，在安装过程中，出现了两次重启电脑。必须重启后才能继续安装。安装的东西很多所以时间也比装vs2008长了不少。&lt;/p&gt;</description></item><item><title>Visual Studio 2010 Beta 2 公开下载地址</title><link>https://fwhyy.com/2009/10/visual-studio-2010-beta-2-download-address-publicly/</link><pubDate>Thu, 22 Oct 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/10/visual-studio-2010-beta-2-download-address-publicly/</guid><description>&lt;p&gt;前天就在博客园见了lyj的那篇介绍Visual Studio 2010 Beta 2的文章了，今天终于开发下载了。
下载地址：&lt;a href="http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx"&gt;http://msdn.microsoft.com/en-us/vstudio/dd582936.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看了下别人的安装截图感觉漂亮了不少，不过我还是想等到正式版出来后再下载安装，希望到时能换一个配置好点的本本，现在的这个已经陪伴我三四年的老本跑起来确实很吃力啊。&lt;/p&gt;
&lt;h2 id="相关文章"&gt;相关文章&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://blog.fwhyy.com/2009/10/experience-vs2010-improvements/"&gt;体验vs2010 （功能改进篇）&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2009/10/experience-vs2010-installation/"&gt;体验VS2010（安装篇）&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/05/net-4-vs2010-new-features/"&gt;Net4.0—VS2010新特性&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/07/net-4-data-bound-controls-the-clientidrowsuffix-properties/"&gt;Net4.0—数据绑定控件（GridView ListView…）中的ClientIDRowSuffix属性&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/07/net-4-purification-processing-of-html/"&gt;Net4.0—对HTML净化的处理&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/07/net-4-aspnet-controls-the-hyperlink-in-the-improvement/"&gt;Net4.0—AspNet中的控件HyperLink的改进（支持路由跳转）&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/07/net-4-aspnet-url-rewriting-in-the-improvement/"&gt;Net4.0—AspNet中URL重写的改进&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/06/net-4-the-web-deployment-tool/"&gt;Net4.0—Web部署工具&lt;/a&gt;
&lt;a href="http://blog.fwhyy.com/2010/05/net-4-framwork-of-new-features/"&gt;Net4.0—Framwork新增特性&lt;/a&gt;&lt;/p&gt;</description></item><item><title>强大的VS插件—Resharper</title><link>https://fwhyy.com/2009/10/powerful-vs-plug-in-resharper/</link><pubDate>Sat, 17 Oct 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/10/powerful-vs-plug-in-resharper/</guid><description>&lt;p&gt;ReSharper是一款Visual.net的插件，主要提升VS.net代码编辑能力，包括对C#、VB.net、XML、XAML和ASP.net，并包括这些语言的交叉关联引用。ReSharper让Visual Studio开发人员更加便捷，包括代码分析、单元测试方案、Goto Symbol支持、To-do探测器等各种特性，ReSharper可以说是辅助Visual Studio开发的一把瑞士军刀，将IntelliJ IDEA在代码编辑方面的智能特性全面带入到Visual Studio中，积极提升.net开发人员的工作效率。ReSharper提供三个版本：Full, C#和VB.net，这样开发人员可以更精准地选择所需的特性。&lt;/p&gt;
&lt;p&gt;很早就听同事说过这个插件很好用，但是听说安装后会拖慢vs的速度，所以就迟迟没敢装，最近还是经不住诱惑装上了这个插件，果然没让我失望。&lt;/p&gt;
&lt;p&gt;下载地址：&lt;a href="http://www.jetbrains.com/resharper/download/"&gt;http://www.jetbrains.com/resharper/download/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;需要注意的是Resharper是收费的，不过网上可以很容易找到注册码，这里就不提供链接了&lt;/p&gt;
&lt;p&gt;博客园的飞刀针对1.0版自己写过注册机，有兴趣的朋友可以研究下。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.cnblogs.com/feidao/archive/2004/08/12/32537.aspx"&gt;http://www.cnblogs.com/feidao/archive/2004/08/12/32537.aspx&lt;/a&gt;&lt;/p&gt;</description></item><item><title>难得的公司小活动—羽毛球比赛</title><link>https://fwhyy.com/2009/10/rare-small-company-activities-badminton-match/</link><pubDate>Sat, 17 Oct 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/10/rare-small-company-activities-badminton-match/</guid><description>&lt;p&gt;前几天人事就通知在这周末公司内部组织一次羽毛球比赛，确实非常期待啊，毕竟好久都没怎么运动了。&lt;/p&gt;
&lt;p&gt;昨天下午下班后我们就来到了光谷体育馆的羽毛球馆，先进行了一些热身就进行了分组比赛，我的搭档是公司的一位女同事，水平当然是没我好了，呵呵！！！ 在经过一轮紧张激烈的比赛后，我们很幸运的拿到了第一，不过说实话我的羽毛球水平实在是不怎么样啊，运气比较好而已啦。&lt;/p&gt;
&lt;p&gt;除了拿到冠军外感到最高兴的是身体得到锻炼。&lt;/p&gt;
&lt;p&gt;希望公司以后经常组织下活动，呵呵 。&lt;/p&gt;
&lt;p&gt;睡觉咯 ，下午和约了同事打篮球了，得养好精神。&lt;/p&gt;</description></item><item><title>在数据库中将字表中的多行合并到一列中</title><link>https://fwhyy.com/2009/10/words-in-the-table-in-the-database-multi-line-merged-into-a-column/</link><pubDate>Thu, 15 Oct 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/10/words-in-the-table-in-the-database-multi-line-merged-into-a-column/</guid><description>&lt;p&gt;几年前就做过这样的查询，在最近的项目中又遇到这样的需求，在此记录一下。&lt;/p&gt;
&lt;p&gt;假设有一个文章表Post和一个评论表Comments，可以对文章进行多次评论，现在希望在对Post表查询时能将Post的所有评论内容组合到一个字段中显示。&lt;/p&gt;
&lt;p&gt;首先创建表Post和Comments&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;create table Post
(
 [PostID] int identity(1,1) primary key not null,
 [Title] nvarchar(50),
 [Content] text,
 [CreateDate] datetime default getdate()
)

create table Comments
(
 [CommentID] int identity(1,1) primary key not null,
 [PostID] int,
 [Content] text,
 [CreateDate] datetime default getdate()
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;给这两个表添加一些测试数据&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;insert into Post select &amp;#39;钓鱼岛是中国的吗？&amp;#39;,&amp;#39;钓鱼岛是中国的&amp;#39;,getdate()
insert into Comments select 1,&amp;#39;绝对是&amp;#39;,getdate()
insert into Comments select 1,&amp;#39;必须是的&amp;#39;,getdate()
insert into Comments select 1,&amp;#39;谁说不是呢&amp;#39;,getdate()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;评论内容的组合使用一个函数来实现，在函数中使用游标去遍历给定PostID的所有评论然后进行拼接，函数代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;create FUNCTION fn_GetAllComments(@PostID int)
RETURNS NVARCHAR(4000)
AS
BEGIN
 DECLARE @result VARCHAR(4000)
 SET @result=&amp;#39;&amp;#39;
 DECLARE getAllComments CURSOR
 FOR
 select CommentID from Comments where PostID=@PostID
 OPEN getAllComments
 DECLARE @ID SYSNAME
 FETCH FROM getAllComments INTO @ID
 WHILE @@fetch_status=0
 BEGIN
 SET @result=@result+(select convert(nvarchar(20),CreateDate,120)
 from Comments where CommentID=@ID)+&amp;#39;:&amp;#39;+
 (select cast([Content] as nvarchar(4000))
 from Comments where CommentID=@ID)+&amp;#39;；&amp;#39;
 FETCH FROM getAllComments INTO @ID
 END
 CLOSE getAllComments
 SET @result= substring(@result,0,len(@result))
 DEALLOCATE getAllComments
 RETURN @result
END
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;现在写SQL语句来测试一下结果&lt;/p&gt;</description></item><item><title>书法比赛奖品—天堂遮阳伞</title><link>https://fwhyy.com/2009/09/calligraphy-competition-prizes-heaven-umbrella/</link><pubDate>Mon, 28 Sep 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/09/calligraphy-competition-prizes-heaven-umbrella/</guid><description>&lt;p&gt;前些日子，创业园举办了迎国庆书法比赛，这勾起了我又想写写字的冲动（小学的时候练习过几年的书法），于是买了笔墨纸砚开始练习了，最终交了一幅《沁园春国庆》的作品。&lt;/p&gt;
&lt;p&gt;今天人事部刘姐给了我一把天堂的遮阳伞说是书法比赛的奖品，应该也就是一纪念奖，而且还给裱起来挂在了创业园那边的大厅，真的有点受宠若惊。&lt;/p&gt;
&lt;p&gt;最近下载了南开大学的书法教授田蕴章先生的书法视频讲座，听了一部分，无论是在写字的技法上还是在对于中国国学知识上都感觉受益匪浅。而且田先生的人品也非常值得我们学习。也决定了以后要坚持练练字，也算是自己的一技之长吧不能给荒废了，等以后技术长进了贴几幅作品给大家看看。&lt;/p&gt;
&lt;p&gt;在此贴个田先生书法讲座的下载地址，有兴趣的朋友可以看看。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.verycd.com/topics/2725995/"&gt;http://www.verycd.com/topics/2725995/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>使用windows live writer连接CSDN和博客园博客</title><link>https://fwhyy.com/2009/09/use-windows-live-writer-connection-csdn-and-cnblogs-blog/</link><pubDate>Sat, 26 Sep 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/09/use-windows-live-writer-connection-csdn-and-cnblogs-blog/</guid><description>&lt;p&gt;windows live writer很早就听说了，不过前几天才真正的使用他在博客园上发文章，感觉非常不错，可以点击此处下载，遗憾的是支持的网站不是很多，像新浪博客，百度空间就不支持。下面简单介绍一下在博客园和CSDN博客等一些网站中的配置：&lt;/p&gt;
&lt;h2 id="博客园"&gt;博客园&lt;/h2&gt;
&lt;p&gt;您的日志网址：填写blog的首页地址 如：&lt;a href="http://oec2003.cnblogs.com/"&gt;http://oec2003.cnblogs.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;用户名：blog中登录的用户名 如：oec2003&lt;/p&gt;
&lt;p&gt;密码：您blog的账号的密码&lt;/p&gt;
&lt;p&gt;您所使用的日志类型：选择MetaWeblog API&lt;/p&gt;
&lt;p&gt;日志的远程发布Url：&lt;a href="http://www.cnblogs.com/UserID/services/metaweblog.aspx"&gt;http://www.cnblogs.com/UserID/services/metaweblog.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;UserID为您登陆的用户名 如：&lt;a href="http://www.cnblogs.com/oec2003/services/metaweblog.aspx"&gt;http://www.cnblogs.com/oec2003/services/metaweblog.aspx&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="csdn博客"&gt;Csdn博客&lt;/h2&gt;
&lt;p&gt;csdn博客的设置和博客园中的大致相似，使用的日志类型同样为Metaweblog API，不同的是日志的远程发布Url，在csdn中该地址为：&lt;a href="http://blog.csdn.net/userID/services/MetaBlogApi.aspx"&gt;http://blog.csdn.net/userID/services/MetaBlogApi.aspx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;如果使用live writer 来写一些技术文章，难免会在写文章的过程中药插入一些源代码，这时就需要用到一些live writer的语法高亮插件了，有关live writer语法高亮插件的使用请参考&lt;a href="http://www.cnblogs.com/oec2003/archive/2009/09/22/1572166.html"&gt;这里&lt;/a&gt;&lt;/p&gt;</description></item><item><title>备份windows live writer的草稿</title><link>https://fwhyy.com/2009/09/backup-windows-live-writers-draft/</link><pubDate>Sat, 26 Sep 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/09/backup-windows-live-writers-draft/</guid><description>&lt;p&gt;windows live writer的草稿功能很不错，那么草稿的内容是存放在哪里呢？&lt;/p&gt;
&lt;p&gt;Windows 7系统下的路径：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;C:\Users\username\Documents\My Weblog Posts
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Windows XP系统下的路径：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;C:\Documents and Settings\username\My Documents\My Weblog Posts
如：C:\Documents and Settings\fw\My Documents\My Weblog Posts
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My Weblog Posts目录中有两个文件夹Drafts 和 Recent Posts，Drafts 目录中存放的就是草稿，而Recent Posts目录中存放的是最近发布的日志。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290755981.webp" alt="2010-12-31_112146" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;我们可以对这两个目录做备份就ok了。&lt;/p&gt;</description></item><item><title>Windows Live Writer中的语法高亮插件</title><link>https://fwhyy.com/2009/09/windows-live-writer-syntax-highlighting-in-the-plug-in/</link><pubDate>Tue, 22 Sep 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/09/windows-live-writer-syntax-highlighting-in-the-plug-in/</guid><description>&lt;h2 id="vspaste"&gt;VSPaste&lt;/h2&gt;
&lt;p&gt;该插件的作用是可以将 VS、 DELPHI 、VS STUDIO 6 、 SharpDevelop、Zend Studio 等IDE中的代码原样复制到Live Writer中。可以点击&lt;a href="http://files.cnblogs.com/oec2003/VSPaste.zip"&gt;此处&lt;/a&gt;下载，下载后解压，将dll文件复制到Live Writer安装目录中的Plugins目录中，如果是安装在C盘，路径如下：C:\Program Files\Windows Live\Writer\Plugins。&lt;/p&gt;
&lt;p&gt;从IDE中复制了代码后点击下图中红色标记处就可以将代码复制到Live Writer中&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290641313.webp" alt="2010-12-29_160715" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="highlight4writer"&gt;highlight4writer&lt;/h2&gt;
&lt;p&gt;该插件安装后可以在一个弹出的对话框中选择c c# xml sql 等十几种语言，可以点击此处下载，下载后同样是将解压的文件复制到Plugins目录下，然后打开Live Writer可以看到如下图所示&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290641270.webp" alt="2010-12-29_160911" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;点击就会弹出输入代码的对话框，如下图&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290641466.webp" alt="2010-12-29_160950" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;就我个人感觉而言，使用第一种比较好些，因为第二种会产生很多的html代码，而第一种的html相对简洁，并且代码在一个class为Code的div中，可以自己设置css来改变代码部分的样式。&lt;/p&gt;
&lt;p&gt;下面是仿老赵的代码样式的css，打开博客园后台管理–》选项—》Configure ，在《通过css定制页面》下的文本框中加入下面的css样式&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;.Code{
 background: #F8F8EE;
 border-left:solid 3px #6CE26C;
 border-top:dashed 1px #BBBBBB;
 border-right:dashed 1px #BBBBBB;
 border-bottom:dashed 1px #BBBBBB;
 padding: 5px;
 margin: 0 5px 0 5px;
 font-family: Verdana,Helvetica, &amp;#34;微软雅黑&amp;#34; , Arial, &amp;#34;宋体&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后在文章中添加的代码效果如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Test
{
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Asp.net MVC V2 Preview 1 初探</title><link>https://fwhyy.com/2009/08/aspnet-mvc-v2-preview-1/</link><pubDate>Thu, 06 Aug 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/08/aspnet-mvc-v2-preview-1/</guid><description>&lt;p&gt;Asp.net MVC1.0正式版刚刚出来才几个月，ASP.NET MVC ASP.NET MVC2 Preview 1 Released 就跟我们见面了 ，您可以点击&lt;a href="http://www.microsoft.com/downloads/details.aspx?displaylang=en&amp;amp;FamilyID=d34f9eaa-fcbe-4e20-b2fd-a9a03de7d6dd#tm"&gt;这儿&lt;/a&gt;下载。该版本可以和以前的Asp.net MVC1.0 兼容，安装了ASP.NET MVC2后，打开vs2008 ，新建项目，可以看到同时存在1.0和2的模板，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290821727.webp" alt="2010-12-29_161754" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在ASP.NET MVC2版中，包含了区域（Area）、数据标记验证（Data Annotation Validation）、强类型UI辅助方法和模板化辅助方法（TemplatedHelper）四个特性，下面就分别来看下这个四个特性。&lt;/p&gt;
&lt;h2 id="区域areas"&gt;区域（Areas）&lt;/h2&gt;
&lt;p&gt;区域（Areas）可以将Asp.net MVC应用的功能进行分割和组合，它可以将Controller和View进行分组管理。如下图中就是将博客（blogs）和相册（Albums）的部分通过Areas提出来单独管理。遗憾的是在预览版1中还没有任何工具的支持，所以Areas项目必须通过手动添加和配置。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290821872.webp" alt="2010-12-29_161937" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;h2 id="数据标记验证data-annotation-validation"&gt;数据标记验证（Data Annotation Validation）&lt;/h2&gt;
&lt;p&gt;DataAnnotation提供了一个简单的方式，在应用中的Model（模型）和ViewModel（视图模型）类中添加验证规则，在ASP.NET MVC中有自动的绑定和UI辅助方法验证支持。首先创建一个实体类Users，代码如下:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace Mvc2Demo.Models
{
 public class Users
 {
 [Required(ErrorMessage = &amp;#34;用户名不能为空！&amp;#34;)]
 public String UserName { get; set; }

 [Range(0, 150, ErrorMessage = &amp;#34;年龄必须在0-150之间！&amp;#34;)]
 [Required(ErrorMessage = &amp;#34;年龄不能为空！&amp;#34;)]
 public Int32 Age { get; set; }

 [Required(ErrorMessage = &amp;#34;邮箱地址不能为空！&amp;#34;)]
 [RegularExpression(&amp;#34;\\w+([-+.&amp;#39;]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*&amp;#34;,
 ErrorMessage = &amp;#34;邮箱格式不正确，请重新填写！&amp;#34;)]
 public String Email { get; set; }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;使用Required 、RegularExpression 等属性需要引用命名空间&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;using System.ComponentModel.DataAnnotations;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在Controllers目录下创建UserController.cs，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace Mvc2Demo.Controllers
{
 public class UserController : Controller
 {
 public ActionResult Index()
 {
 return View();
 }
 public ActionResult Create()
 {
 Users user = new Users();
 return View(user);
 }
 //在ASP.NET MVC2预览一版中使用[HttpPost]
 //1.0版中使用[AcceptVerbs(HttpVerbs.Post)]
 [HttpPost]
 public ActionResult Create(Users user)
 {
 if (!ModelState.IsValid)
 {
 return View(user);
 }
 return View(&amp;#34;Success&amp;#34;);
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在上面的任意一个Create方法上右击，选择Add View … ，在弹出的对话框中做相应的设置，然后点击Add，就会在View下添加相应的目录和页面文件，如下图：&lt;/p&gt;</description></item><item><title>CLR Via C# 学习笔记（6） 方法参数相关（out ref params）</title><link>https://fwhyy.com/2009/07/clr-via-csharp-learning-notes-6-the-method-parameters-related/</link><pubDate>Thu, 16 Jul 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/07/clr-via-csharp-learning-notes-6-the-method-parameters-related/</guid><description>&lt;blockquote&gt;
&lt;p&gt;CLR Via C#》这本书以前就粗略看过两遍，但一直都没能深入理解，而且很多内容也忘记了，现在准备重新看一遍，并将看过的部分写出来，因为写的过程也是一个加深理解的过程。本系列算是学习的一个记录吧，也可以方便以后自己查阅，如果对大家还有些帮助的话，我就很高兴了。书我是选择性的看的，所以顺序和书中的顺序可能不一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;通常我们在使用方法的时候，方法的参数是按值传递的，如果传递的参数是引用类型的对象，是将引用对象的地址传给方法。如果传递的是值类型实例，传递给方法的是该实例的一个副本。允许使用在方法中按引用来传递参数，C#中使用out和ref关键字来体现。下面就来介绍out和ref的使用。&lt;/p&gt;
&lt;h2 id="out"&gt;out&lt;/h2&gt;
&lt;p&gt;1 使用out时在方法的参数定义和方法的调用时都要用out关键字，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;static void Main(string[] args)
{
 string name = string.Empty;
 GetStr(out name); //调用时加out
 Console.WriteLine(name);
}
private static void GetStr(out string name) //方法参数定义时的out
{
 name = &amp;#34;oec2003&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 如果一个方法有out修饰的参数，在方法结束前必须给给参数赋值，否则不能通过编译，代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;static void Main(string[] args)
{
 string name = &amp;#34;oec2003&amp;#34;;
 GetStr(out name);
 Console.WriteLine(name);
}
private static void GetStr(out string name)
{
 //没有给name赋值，编译时会出现“控制离开当前方法之前必须对
 //out 参数“name”赋值”异常
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 在调用有out参数的方法时，没有必要给out参数赋初始值，因为赋的值不会传递到方法的内部，如果在方法的内部要强行使用out参数会有编译错误。代码如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;static void Main(string[] args)
{
 //给out参数name赋初始值oec2003
 string name = &amp;#34;oec2003&amp;#34;;
 GetStr(out name);
 Console.WriteLine(name);
}
private static void GetStr(out string name)
{
 name = &amp;#34;hello&amp;#34; + name;
 //name在调用前虽赋值为oec2003 ，
 //但此处会报错“使用了未赋值的 out 参数name”
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 通常我们需要在一个方法中返回多个值的时候就可以使用out参数。&lt;/p&gt;
&lt;p&gt;5 如果两个方法的参数个数和类型都相同，区别只是其中一个为out参数，那么这两个方法是可以进行重载的，下面的代码可以正常运行。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private static void GetStr(out string name)
{
 name = &amp;#34;oec2003&amp;#34;;
}
private static void GetStr(string name)
{
 name = &amp;#34;oec2003&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="ref"&gt;ref&lt;/h2&gt;
&lt;p&gt;1 和out参数一样，使用ref时在方法的参数定义和方法的调用时都要用ref关键字。&lt;/p&gt;</description></item><item><title>AjaxPro版自动完成（Autocomplete）功能实现</title><link>https://fwhyy.com/2009/07/ajaxpro-autocomplete-function-implementation/</link><pubDate>Mon, 13 Jul 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/07/ajaxpro-autocomplete-function-implementation/</guid><description>&lt;p&gt;07年的时候写过一篇有关自动完成(Atuocomplete)的文章 &lt;a href="http://www.cnblogs.com/oec2003/archive/2007/08/18/860870.html"&gt;asp.net Ajax —AutoComplete控件使用&lt;/a&gt; ，那篇文章中使用的是Asp.net Ajax ControlTollKit中的一个控件，虽然那时对里面几十个控件都研究过，不过遗憾的是在实际开发中确从未用到过，鉴于现在Ajaxpro的易用性和普遍性，本文将使用ajaxpro来实现自动完成的功能。&lt;/p&gt;</description></item><item><title>CLR Via C# 学习笔记（5） 静态构造函数的性能</title><link>https://fwhyy.com/2009/07/clr-via-csharp-learning-notes-5-the-performance-of-the-static-constructor/</link><pubDate>Wed, 08 Jul 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/07/clr-via-csharp-learning-notes-5-the-performance-of-the-static-constructor/</guid><description>&lt;blockquote&gt;
&lt;p&gt;CLR Via C#》这本书以前就粗略看过两遍，但一直都没能深入理解，而且很多内容也忘记了，现在准备重新看一遍，并将看过的部分写出来，因为写的过程也是一个加深理解的过程。本系列算是学习的一个记录吧，也可以方便以后自己查阅，如果对大家还有些帮助的话，我就很高兴了。书我是选择性的看的，所以顺序和书中的顺序可能不一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在上一篇《CLR Via C# 学习笔记（4） 方法 构造函数 》中讲到了一些静态构造函数方面的知识，现在也回顾一下，大概总结如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;静态构造函数是私有的（private） ，而且不能人为去修改访问修饰符。&lt;/li&gt;
&lt;li&gt;静态构造函数不应该去调用基类的静态构造函数，因为静态字段不会被继承到子类。&lt;/li&gt;
&lt;li&gt;静态构造函数在一个类型中有且仅有一个，并且是无参的。&lt;/li&gt;
&lt;li&gt;静态构造函数中只能初始化静态字段。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;从上面的第一点可以知道静态构造函数都是private的，所以不能显示区进行调用，关于JIT何时会去生成调用静态构造函数的代码。存在着两种说法。通常被称为Precise和BeforeFieldInit。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Precise方式JIT编译器生成调用的时机：首次创建类型的代码之前；访问类的非继承字段或成员代码之前。&lt;/li&gt;
&lt;li&gt;BeforeFieldInit方式JIT编译器生成调用的时机：在访问费继承静态字段代码之前。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这两种方式的主要区别就是选择调用静态构造函数的时机是否是确定的，Precise方式CLR会在确定的时刻调用静态构造函数，而BeforeFieldInit方式CLR可以自由选择调用静态构造函数的时机，利用这一点，CLR可以根据类型是否在程序域中加载来选择静态构造函数的调用次数，以便能生成执行更快的代码。&lt;/p&gt;
&lt;p&gt;下面来看来个类分别展现了这两种方式&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public classUserPrecise
{
 public static string_name = &amp;#34;内联赋值：oec2003&amp;#34;;
 staticUserPrecise()
 {
 _name = &amp;#34;构造函数赋值：oec2003&amp;#34;;
 }
}
public classUserBeforeFieldInit
{
 public static string_name = &amp;#34;内联赋值：oec2003&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;通过IL代码可以看出在UserBeforeFieldInit 的元数据上有BeforeFieldInit的标记，如下图：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290802573.webp" alt="2010-12-29_173428" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;既然上面提到BeforeFieldInit方式CLR可以选择调用构造函数的次数从而来生成执行更快的代码，下面就写一段测试代码来看看究竟怎样。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Test2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Test1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UserBeforeFieldInit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Test1-UserBeforeFieldInit 用时：&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elapsed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UserPrecise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Test1-UserPrecise 用时：&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elapsed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Test2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UserBeforeFieldInit&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Test2-UserBeforeFieldInit 用时：&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elapsed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sw&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Stopwatch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StartNew&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;UserPrecise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Test2-UserPrecise 用时：&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Elapsed&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserBeforeFieldInit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserPrecise&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;UserPrecise&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;测试结果如下：&lt;/p&gt;</description></item><item><title>CLR Via C# 学习笔记（4） 方法 构造函数</title><link>https://fwhyy.com/2009/07/clr-via-csharp-learning-notes-5-methods-the-constructor/</link><pubDate>Fri, 03 Jul 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/07/clr-via-csharp-learning-notes-5-methods-the-constructor/</guid><description>&lt;blockquote&gt;
&lt;p&gt;《CLR Via C#》这本书以前就粗略看过两遍，但一直都没能深入理解，而且很多内容也忘记了，现在准备重新看一遍，并将看过的部分写出来，因为写的过程也是一个加深理解的过程。本系列算是学习的一个记录吧，也可以方便以后自己查阅，如果对大家还有些帮助的话，我就很高兴了。书我是选择性的看的，所以顺序和书中的顺序可能不一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;构造函数是可以将类型实例初始化为有效状态的特殊方法。构造函数在元数据中通常用.ctor来表示，通过IL代码可以看到。在创建一个类型的实例时，通常分为三步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;为实例的数据字段分配内存。&lt;/li&gt;
&lt;li&gt;创建对象指针和同步索引块。&lt;/li&gt;
&lt;li&gt;调用类型的实例构造器来设置对象的初始状态。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="引用类型的实例构造器"&gt;引用类型的实例构造器&lt;/h2&gt;
&lt;p&gt;在创建一个引用类型的对象是，调用类型的实例构造函数之前，会将对象分配的内存做清零处理，就是说在构造函数中没有显示赋值的所有字段都将设置为0或null。&lt;/p&gt;
&lt;p&gt;实例构造函数和一般方法不同，他永远都不能被继承，所有以下的关键字也不能用于实例构造函数（virtual new override sealed abstract）。&lt;/p&gt;
&lt;p&gt;一个类中如果没有显示定义任何构造函数，C#编译器将定义一个默认的无参构造函数。&lt;/p&gt;
&lt;p&gt;抽象（abstract）类的默认构造函数的访问修饰符为protected。&lt;/p&gt;
&lt;p&gt;构造函数可以初始化字段，不过在c#语言中提供了一种简单的方法，在定义字段的时候直接赋值以初始化。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class User
{
 private int _age = 25;
 private string _name = &amp;#34;oec2003&amp;#34;;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;像上面那样的确很方便，但如果有好几个已经初始化的实例字段和多个重载的构造函数同时存在的情况下，就应该将实例字段的初始化放到一个公共的构造函数中，其他的构造函数通过this来显示调用该构造函数，这样可以减少代码生成的大小，看下面的例子。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class User
{
 private int _age = 25;
 private string _name = &amp;#34;oec2003&amp;#34;;
 private string _email = &amp;#34;oec2003@gmail.com&amp;#34;;

 public User(Int32 age)
 {
 this._age = age;
 }

 public User(string name)
 {
 this._name = name;
 }

 public User(Int32 age, String name, String email)
 {
 this._age = age;
 this._name = name;
 this._email = email;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;正确的写法应该像下面这样&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public abstract class User
{
 private int _age;
 private string _name;
 private string _email;

 public User()
 {
 _age = 25;
 _name = &amp;#34;oec2003&amp;#34;;
 _email = &amp;#34;oec2003@gmail.com&amp;#34;;
 }

 public User(Int32 age)
 : this()
 {
 this._age = age;
 }

 public User(string name)
 : this()
 {
 this._name = name;
 }

 public User(Int32 age, String name, String email)
 : this()
 {
 this._age = age;
 this._name = name;
 this._email = email;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="值类型的实例构造函数"&gt;值类型的实例构造函数&lt;/h2&gt;
&lt;p&gt;值类型的实例构造函数和引用类型的有很大不同，在值类型中不能含有无参的构造函数，如果显式指定无参的构造函数将会出现编译错误。如下面代码会出现编译错误：&lt;/p&gt;</description></item><item><title>Asp.Net中替代Eval的两种方式</title><link>https://fwhyy.com/2009/06/aspnet-instead-of-eval-in-two-ways/</link><pubDate>Fri, 26 Jun 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/06/aspnet-instead-of-eval-in-two-ways/</guid><description>&lt;p&gt;在asp.net中的数据绑定中，我们经常会用到Eval，不过大家都知道Eval绑定是通过反射来实现的， 而反射势必会对性能造成一定的影响。不过有两种替代的方式来实现绑定数据，对性能略有提高。&lt;/p&gt;
&lt;p&gt;1 当数据源为DataTable时，用下面的方式:&lt;/p&gt;
&lt;p&gt;后台代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protected void Page_Load(object sender, EventArgs e)
{
 DataTable dt = new DataTable();
 dt.Columns.Add(&amp;#34;Name&amp;#34;, typeof(System.String));
 dt.Columns.Add(&amp;#34;Age&amp;#34;, typeof(System.Int32));
 for (int i = 0; i &amp;lt;= 20; i++)
 {
 DataRow dr = dt.NewRow();
 dr[0] = &amp;#34;oec2003_&amp;#34; + i.ToString();
 dr[1] = i + 20;
 dt.Rows.Add(dr);
 }

 rptUser.DataSource = dt;
 rptUser.DataBind();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;前台代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Repeater ID=&amp;#34;rptUser&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;ItemTemplate&amp;gt;
 姓名：&amp;lt;%# ((DataRowView)(Container.DataItem))[&amp;#34;Name&amp;#34;] %&amp;gt;
 年龄：&amp;lt;%# ((DataRowView)(Container.DataItem))[&amp;#34;Age&amp;#34;]%&amp;gt;&amp;lt;br /&amp;gt;
 &amp;lt;/ItemTemplate&amp;gt;
&amp;lt;/asp:Repeater&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 当数据源为泛型类时，用下面的方式。&lt;/p&gt;
&lt;p&gt;后台代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protected void Page_Load(object sender, EventArgs e)
{
 List&amp;lt;User&amp;gt; user = new List&amp;lt;User&amp;gt;();
 for (int i = 0; i &amp;lt; 10; i++)
 {
 user.Add(new User(i, &amp;#34;oec2003&amp;#34;));
 }
 rptUser.DataSource = user;
 rptUser.DataBind();
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;前台代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;asp:Repeater ID=&amp;#34;rptUser&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;ItemTemplate&amp;gt;
 姓名：&amp;lt;%# (Container.DataItem as User).Name %&amp;gt;
 年龄：&amp;lt;%# (Container.DataItem as User).Age%&amp;gt;&amp;lt;br /&amp;gt;
 &amp;lt;/ItemTemplate&amp;gt;
&amp;lt;/asp:Repeater&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;经过测试在10w以上数据量的时候性能差别才比较明显，而我们平时做数据绑定的时候通常都是用的分页存储过程或其他的分页方式，每页最多几十条数据，所以我认为Eval在性能上的损耗并不构成性能瓶颈。&lt;/p&gt;</description></item><item><title>CLR Via C# 学习笔记（3） 常量和字段（const readonly）</title><link>https://fwhyy.com/2009/06/clr-via-csharp-learning-notes-3-constants-and-fields/</link><pubDate>Mon, 22 Jun 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/06/clr-via-csharp-learning-notes-3-constants-and-fields/</guid><description>&lt;blockquote&gt;
&lt;p&gt;《CLR Via C#》这本书以前就粗略看过两遍，但一直都没能深入理解，而且很多内容也忘记了，现在准备重新看一遍，并将看过的部分写出来，因为写的过程也是一个加深理解的过程。本系列算是学习的一个记录吧，也可以方便以后自己查阅，如果对大家还有些帮助的话，我就很高兴了。书我是选择性的看的，所以顺序和书中的顺序可能不一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;常量和字段都是类型的数据成员，但是区别却是很大的。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;常量的值永远不会改变。字段有多种类型，非只读字段的值是可以改变的。&lt;/li&gt;
&lt;li&gt;常量的值必须在编译时就确定，也就是说在定义时就要赋值。编译后常量的值就保存在程序集的元数据中；字段是存储在动态内存中，在运行时才能得到字段的值。&lt;/li&gt;
&lt;li&gt;常量的定义必须用基元类型，关于基元类型可以参考(CLR Via C# 学习笔记（1） 基元类型 值类型 引用类型 )；字段的定义可以是任何类型。&lt;/li&gt;
&lt;li&gt;因为常量的值不能改变，可以将其看做是静态类型，在IL代码中可以看到常量有static修饰符，所以在调用的时候和调用静态字段一样，直接用类名.常量名；字段中的静态字段的调用才和常量一样直接用类名.字段名，调用非静态字段必须用类的实例。、&lt;/li&gt;
&lt;li&gt;C#不允许使用static修饰常量，因为常量本身就隐含是static类型；字段可以使用static，使用static定义的字段为静态字段。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="下面看个例子来理解下常量"&gt;下面看个例子来理解下常量&lt;/h2&gt;
&lt;p&gt;1 创建一个类库项目命名为Oec2003ClassLibrary ,在默认的类Class1中写如下代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace Oec2003ClassLibrary
{
 public class Class1
 {
 public const double PI = 3.14;

 public static double _pi = 3.14;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 创建一个web项目，添加对Oec2003ClassLibrary类库项目的引用，新建页面ConstTest.aspx,在PageLoad中写如下代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protected void Page_Load(object sender, EventArgs e)
{
 Response.Write(Class1.PI+&amp;#34;&amp;lt;br/&amp;gt;&amp;#34;);
 Response.Write(Class1._pi);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;3 将ConstTest设为起始页，运行，可以看到结果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290816263.webp" alt="2010-12-29_181713" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;4 现在将Oec2003ClassLibrary 项目中的Class1的代码改写如下，然后从新编译该项目。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace Oec2003ClassLibrary
{
 public class Class1
 {
 public const double PI = 3.1415926;
 public static double _pi = 3.1415926;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;5 刷新刚才的页面 ，可以看到结果如下&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290816174.webp" alt="2010-12-29_181748" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;6 从新运行ConstTest页面可以看到如下结果&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290816233.webp" alt="2010-12-29_181824" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;从上面的例子可以看出，在应用程序不从新编译的情况下，常量的值永远不会发生改变。如果应用程序想要获得常量的新值，就必须重新编译，所以在运行时一个应用程序集想获得另一个应用程序集中的值，则不能使用常量，可以使用只读字段（readonly）。&lt;/p&gt;
&lt;p&gt;字段也是一种类型的数据成员，字段的修饰符有 static readonly volatile，没有上述修饰修饰的字段为普通的实例字段。static可以和readonly一起使用，就是静态只读字段。有关volatile将在后面的部分介绍。&lt;/p&gt;
&lt;h2 id="关于readonly要注意的地方"&gt;关于readonly要注意的地方&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;当readonly修饰的字段为值类型时，在调用的时候如果视图去改变字段的值，将会编译出错。&lt;/li&gt;
&lt;li&gt;当readonly修饰的字段为引用类型时，调用时不能改变其引用，但可以改变应用对象的值，看下面的例子。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;1 在Oec2003ClassLibrary项目的Class1.cs文件写如下代码&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace Oec2003ClassLibrary
{
 public class Class1
 {
 public const double PI = 3.14;
 public static readonly double _pi = 3.14;

 public static readonly User user = new User(&amp;#34;oec2003&amp;#34;);
 }
 public class User
 {
 public User(string name)
 {
 Name = name;
 }
 public string Name { get; set; }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 在web项目中添加页面，命名为Readonly.aspx，PageLoad代码如下&lt;/p&gt;</description></item><item><title>CLR Via C# 学习笔记（2） 装箱和拆箱</title><link>https://fwhyy.com/2009/06/clr-via-csharp-learning-notes-2-boxing-and-unboxing/</link><pubDate>Thu, 18 Jun 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/06/clr-via-csharp-learning-notes-2-boxing-and-unboxing/</guid><description>&lt;blockquote&gt;
&lt;p&gt;CLR Via C#》这本书以前就粗略看过两遍，但一直都没能深入理解，而且很多内容也忘记了，现在准备重新看一遍，并将看过的部分写出来，因为写的过程也是一个加深理解的过程。本系列算是学习的一个记录吧，也可以方便以后自己查阅，如果对大家还有些帮助的话，我就很高兴了。书我是选择性的看的，所以顺序和书中的顺序可能不一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;装箱和拆箱是已经被嚼烂的两个概念了，并且在一些面试中也经常考到。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;装箱：将值类型转换为引用类型。&lt;/li&gt;
&lt;li&gt;拆箱：将引用类型转换为值类型。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;值类型是一种相对轻型的类型，不像对象那样在托管堆中分配，也不会被GC，不通过指针来引用，不过在有些时候需要获取对值类型的引用，例如在使用net1.0的集合类ArrayList的时候。&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ArrayList&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ArrayList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//因Point为值类型，分配在堆栈中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//初始化Point中的成员&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//对p进行装箱后，将引用添加到list中&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;ArrayList的Add方法是接受一个Object参数，如下&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;virtual&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所以在执行Add方法时会将Point值类型转换为一个堆得托管对象，并获取到这个对象的引用，将引用地址存储在ArrayList中。&lt;/p&gt;
&lt;p&gt;在一个值类型装箱的时候内部发生的事情：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在托管堆分配好内存。分配的内存是值类型的各个字段所需内存量加上托管堆上的两个额外成员（类型对象指针和同步索引块）所需的内存量。&lt;/li&gt;
&lt;li&gt;值类型中的字段值复制到新分配的堆内存中。&lt;/li&gt;
&lt;li&gt;返回对象的引用地址。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;拆箱就是执行和装箱相反的操作，将引用类型转化为值类型。接上面的代码，获取ArrayList中的元素值用如下代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Point&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt; &lt;span class="p"&gt;=(&lt;/span&gt;&lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;X:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34; Y:&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面的代码中通过索引取到ArrayList中存储的各个Point的引用地址，通过Point类型转换将其对应的值从堆中复制到Point的实例point中，这个转换的过程就是拆箱的过程。&lt;/p&gt;
&lt;p&gt;在拆箱的过程中要注意以下两点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;如果对已装箱的值类型的引用的变量为null，会引发NullRefreenceException异常&lt;/li&gt;
&lt;li&gt;如果一个引用指向的对象在拆箱时不是用的装箱时所使用的类型，将会引发InvalidCastException异常。代码如下：&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Int16&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//引发InvalidCastException异常&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;正确的做法是，现将其用Int32类型来拆箱，然后再强制转换为Int16&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Int16&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int16&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;下面来看两段程序来深入理解下装箱和拆箱&lt;/p&gt;
&lt;p&gt;代码一：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;span class="lnt"&gt;5
&lt;/span&gt;&lt;span class="lnt"&gt;6
&lt;/span&gt;&lt;span class="lnt"&gt;7
&lt;/span&gt;&lt;span class="lnt"&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Int32&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;, &amp;#34;&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Int32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面的代码中有多少次装箱呢？乍一看好像就一次（Object o=x；），其实一共有三次装箱，看看IL代码就一目了然了。&lt;/p&gt;</description></item><item><title>CLR Via C# 学习笔记（1） 基元类型 值类型 引用类型</title><link>https://fwhyy.com/2009/06/clr-via-csharp-learning-notes-1-primitive-types/</link><pubDate>Wed, 17 Jun 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/06/clr-via-csharp-learning-notes-1-primitive-types/</guid><description>&lt;blockquote&gt;
&lt;p&gt;CLR Via C#》这本书以前就粗略看过两遍，但一直都没能深入理解，而且很多内容也忘记了，现在准备重新看一遍，并将看过的部分写出来，因为写的过程也是一个加深理解的过程。本系列算是学习的一个记录吧，也可以方便以后自己查阅，如果对大家还有些帮助的话，我就很高兴了。书我是选择性的看的，所以顺序和书中的顺序可能不一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;首先了解下什么是基元类型，基元类型是编译器直接支持的数据类型，像我们平时经常用到的int string bool 都是基元类型，基元类型是映射到FCL中的类型，像前面的三种类型对应到FCL中就是Int32 String Boolean，基元类型只是给我们的编程提供了方便，它和FCL中的类型在编译后最终生成的IL完全相同。下面给出基元类型和FCL类型的对应表&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;C#基元类型&lt;/th&gt;
					&lt;th&gt;FCL类型&lt;/th&gt;
					&lt;th&gt;CLS相容&lt;/th&gt;
					&lt;th&gt;说明&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;sbyte&lt;/td&gt;
					&lt;td&gt;System.Sbyte&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;byte&lt;/td&gt;
					&lt;td&gt;System.Byte&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;short&lt;/td&gt;
					&lt;td&gt;System.Int16&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ushort&lt;/td&gt;
					&lt;td&gt;System.UInt16&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;int&lt;/td&gt;
					&lt;td&gt;System.Int32&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;uint&lt;/td&gt;
					&lt;td&gt;System.Uint32&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;long&lt;/td&gt;
					&lt;td&gt;System.Int64&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;ulong&lt;/td&gt;
					&lt;td&gt;System.Uint64&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;char&lt;/td&gt;
					&lt;td&gt;System.Char&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;float&lt;/td&gt;
					&lt;td&gt;System.Single&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;double&lt;/td&gt;
					&lt;td&gt;System.Double&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;bool&lt;/td&gt;
					&lt;td&gt;System.Boolean&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;decimal&lt;/td&gt;
					&lt;td&gt;System.Decimal&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;object&lt;/td&gt;
					&lt;td&gt;System.Object&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;string&lt;/td&gt;
					&lt;td&gt;System.String&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
					&lt;td&gt;&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;我们平时在写程序时通常都是使用基元类型，因为方便，但本书的作者认为应该直接使用FCL中的类型，原因如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在c#中long对应的FCL类型为System.Int64，但是在其他的语言中，如c++ 就将long视为一个Int32。这样习惯于一种编程语言的人在看另一种编程语言写的源码是就会产生错误的理解。&lt;/li&gt;
&lt;li&gt;在FCL中的许多的方法将类型名作为方法名的一部分，如System.Convert类提供ToBoolean,ToInt32,ToSingle等。这样在使用基元类型做类型转换时就感觉有点怪怪的，如：float val=Convert.ToSingle(“23”);&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="值类型和引用类型的区别"&gt;值类型和引用类型的区别&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;所有的值类型都是从System.TypeValue派生，如Struct Enum都是值类型；所有引用类型都是从System.Object派生。&lt;/li&gt;
&lt;li&gt;值类型分配在线程堆栈上，引用类型分配在托管堆上。&lt;/li&gt;
&lt;li&gt;值类型表现形式有未装箱形式和已装箱形式，而引用类型总是已装箱形式。&lt;/li&gt;
&lt;li&gt;所有的值类型都是sealed类型，所以值类型不能作为任何类型的基类型，也不能在值类型中引入虚方法。&lt;/li&gt;
&lt;li&gt;创建一个引用类型变量时，会被初始化为null，试图使用一个null的引用类型变量时，会抛出NullReferenceException异常，也就是常见的“未将对象引用设置到对象的实例”；值类型在创建时所有成员都初始化为0了，所以不会抛出该异常。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="原文例子表示值类型和引用类型的区别"&gt;原文例子表示值类型和引用类型的区别&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;class Program
{
 static void Main(string[] args)
 {
 SomeRef r1 = new SomeRef();
 SomeVal v1 = new SomeVal();
 r1.x = 5;
 v1.x = 5;
 Console.WriteLine(r1.x); //5
 Console.WriteLine(v1.x); //5
 SomeRef r2 = r1;
 SomeVal v2 = v1;
 r1.x = 8;
 v1.x = 9;
 Console.WriteLine(r1.x); //8
 Console.WriteLine(r2.x); //9
 Console.WriteLine(v1.x); //9
 Console.WriteLine(v2.x); //5
 }
}
class SomeRef
{
 public Int32 x;
}
struct SomeVal
{
 public Int32 x;
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="clr中类型字段布局的控制"&gt;CLR中类型字段布局的控制&lt;/h2&gt;
&lt;p&gt;为了提高性能，clr能按照所选择的任何方式来排列类型的字段。我们可以通过在类会是结构上使用System.Runtime.InteropServices.StructLayoutAttribute属性来改变这种排列的顺序。该属性接受一个LayoutKind的枚举值（Auto，Sequential，Explicit），默认情况下C#编译器会为类选择Atuo，为结构选择Sequential。下面来定义一个类和一个结构&lt;/p&gt;</description></item><item><title>ZedGraph在Web中的使用</title><link>https://fwhyy.com/2009/06/use-zedgraph-in-the-web/</link><pubDate>Sat, 06 Jun 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/06/use-zedgraph-in-the-web/</guid><description>&lt;p&gt;上一篇&lt;a href="http://blog.fwhyy.com/2009/06/sql-implementation-group-statistical-query/"&gt;SQL实现分组统计查询（按月、小时分组）&lt;/a&gt; 中介绍了按月和小时为单位怎样实现分组查询，在本文中会实现将上文查询的结果以图表的形式显示在页面上。在页面上显示图标有很多种解决方案，office的owc组建、自己写代码、或者是第三方的控件。本文中将使用ZedGraph控件来实现。选择ZedGraph有两个原因：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;该控件是开源的，在必要的时候可以根据自己的需要来修改；&lt;/li&gt;
&lt;li&gt;该控件所显示的图片是绘出来的，而不是生成的图片。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;下载地址：&lt;a href="http://sourceforge.net/project/showfiles.php?group_id=114675"&gt;http://sourceforge.net/project/showfiles.php?group_id=114675&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;1 将控件引用到项目中，本示例使用的是5.1.5版。&lt;/p&gt;
&lt;p&gt;在工具栏下方的空白处点击右键—&amp;gt;添加选项卡,命名为ZedGraph&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290709681.webp" alt="2010-12-30_101747" loading="lazy" decoding="async"&gt;

&lt;img src="https://img.fwhyy.com/2022/202201290709929.webp" alt="2010-12-30_101836" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;在ZedGraph选项卡点右键—&amp;gt;选择项…,在弹出窗口中选择下载下来的ZedGraph.Web.dll文件。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290709682.webp" alt="https://img.fwhyy.com/14712687428710.webp" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;2 在项目中新建一aspx页面，命名为Year.aspx,将刚添加的ZedGraph控件拖到页面中，并在页面中添加一个文本框和一个按钮，文本框用来选择年份。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201290710090.webp" alt="2010-12-30_102641" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 切换到代码视图，添加如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;namespace ZedGraphDemo
{
 public partial class Year : System.Web.UI.Page
 {
 protected void Page_Load(object sender, EventArgs e)
 {
 this.ZgwYear.RenderGraph +=
 new ZedGraphWebControlEventHandler(ZgwYear_RenderGraph);
 }

 void ZgwYear_RenderGraph(ZedGraphWeb webObject,
 System.Drawing.Graphics g, MasterPane pane)
 {
 GraphPane myPane = pane[0];

 // 标题
 myPane.Title.Text = &amp;#34;每年分析（月为单位）&amp;#34;;
 myPane.XAxis.Title.Text = &amp;#34;时间&amp;#34;;
 myPane.YAxis.Title.Text = &amp;#34;访问量&amp;#34;;

 // 坐标对集
 PointPairList list = new PointPairList();
 //PointPairList list1 = new PointPairList();
 //PointPairList list2 = new PointPairList();

 //从数据库中获取数据集
 DataTable dtYear = GetData();
 if (dtYear == null)
 return;
 for (int i = 0; i &amp;lt; dtYear.Rows.Count; i++)
 {
 list.Add(Convert.ToDouble(i), Convert.ToDouble(dtYear.Rows[i][&amp;#34;Count&amp;#34;]));
 //如果有多种类型，可以添加多个
 //list1.Add(Convert.ToDouble(i), Convert.ToDouble(dtYear.Rows[i][&amp;#34;Count1&amp;#34;]));
 //list2.Add(Convert.ToDouble(i), Convert.ToDouble(dtYear.Rows[i][&amp;#34;Count2&amp;#34;]));
 }

 BarItem myBar = myPane.AddBar(&amp;#34;页面访问&amp;#34;, list, Color.Blue);
 //BarItem myBar1 = myPane.AddBar(&amp;#34;&amp;#34;, list1, Color.Red);
 //BarItem myBar2 = myPane.AddBar(&amp;#34;&amp;#34;, list2, Color.Yellow);

 myBar.Bar.Fill = new Fill(Color.Blue, Color.White, Color.Blue);
 //myBar1.Bar.Fill = new Fill(Color.Red, Color.White, Color.Red);
 //myBar2.Bar.Fill = new Fill(Color.Yellow, Color.White, Color.Yellow);

 myPane.XAxis.MajorTic.IsBetweenLabels = true;
 // X轴Label
 string[] labels = new string[] { &amp;#34;1月&amp;#34;, &amp;#34;2月&amp;#34;, &amp;#34;3月&amp;#34;, &amp;#34;4月&amp;#34;, &amp;#34;5月&amp;#34;, &amp;#34;6月&amp;#34;,
 &amp;#34;7月&amp;#34;, &amp;#34;8月&amp;#34;, &amp;#34;9月&amp;#34;, &amp;#34;10月&amp;#34;, &amp;#34;11月&amp;#34;, &amp;#34;12月&amp;#34; };

 //设置x轴刻度
 myPane.XAxis.Scale.TextLabels = labels;
 myPane.XAxis.Type = AxisType.Text;

 // 颜色填充
 myPane.Fill = new Fill(Color.White, Color.FromArgb(200, 200, 255), 45.0f);
 myPane.Chart.Fill = new Fill(Color.White, Color.LightGoldenrodYellow, 45.0f);

 pane.AxisChange(g);

 myPane.YAxis.Scale.Max += myPane.YAxis.Scale.MajorStep;
 BarItem.CreateBarLabels(myPane, false, &amp;#34;f0&amp;#34;); //在柱状图上方显示统计数
 }

 protected void btnQuerys_Click(object sender, EventArgs e)
 {
 GetData();
 }

 private DataTable GetData()
 {
 SqlHelper.ConnectionString =
 ConfigurationManager.AppSettings[&amp;#34;ConnectionString&amp;#34;].ToString();
 SqlParameter[] parameters = new SqlParameter[1];

 parameters[0] = new SqlParameter(&amp;#34;@Year&amp;#34;, SqlDbType.Int, 4);
 parameters[0].Value = this.txtYear.Value.Trim().Length == 0 ? DateTime.Now.Year :
 Convert.ToInt32(txtYear.Value.Trim());
 DataSet ds = SqlHelper.ExecuteDataset(&amp;#34;Counter_CounterYear&amp;#34;, parameters);
 if (ds != null &amp;amp;&amp;amp; ds.Tables.Count &amp;gt; 0 &amp;amp;&amp;amp; ds.Tables[0].Rows.Count &amp;gt; 0)
 {
 return ds.Tables[0];
 }
 else
 {
 return null;
 }
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;4 在项目的根目录下创建一个名为ZedGraphImages的文件夹，只是作为ZedGraph绘图时的一个临时目录，并不会在该文件夹中生成图片，如果没有该文件夹会报异常。&lt;/p&gt;</description></item><item><title>SQL实现分组统计查询（按月、小时分组）</title><link>https://fwhyy.com/2009/06/sql-implementation-group-statistical-query/</link><pubDate>Thu, 04 Jun 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/06/sql-implementation-group-statistical-query/</guid><description>&lt;h2 id="首先创建数据表"&gt;首先创建数据表&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Create table Counter
(
 CounterID int identity(1,1) not null,
 IP varchar(20),
 AccessDateTime datetime,
 AccessCount int
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;该表在这儿只是演示使用，所以只提供了最基本的字段:IP地址，访问时间和访问次数。如果每访问一次就插入一条记录，那么AccessCount可以不要，查询时使用count就可以了，这样当访问量很大的时候会对数据库造成很大压力。设置AccessCount字段可以根据需求在特定的时间范围内如果是相同IP访问就在AccessCount上累加。&lt;/p&gt;
&lt;p&gt;现在往表中插入几条记录&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;insert into Counter
select &amp;#39;127.0.0.1&amp;#39;,getdate(),1 union all
select &amp;#39;127.0.0.2&amp;#39;,getdate(),1 union all
select &amp;#39;127.0.0.3&amp;#39;,getdate(),1
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="根据年来查询以月为时间单位"&gt;根据年来查询，以月为时间单位&lt;/h2&gt;
&lt;p&gt;通常情况下一个简单的分组就能搞定&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;select
 convert(varchar(7),AccessDateTime,120) as Date,
 sum(AccessCount) as [Count]
from
 Counter
group by
 convert(varchar(7),AccessDateTime,120)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;像这样分组后没有记录的月份不会显示，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201301950583.webp" alt="2010-12-30_103754" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;这当然不是我们想要的，所以得换一种思路来实现，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;declare @Year int
set @Year=2009
select
 m as [Date],
 sum(
 case when datepart(month,AccessDateTime)=m
 then AccessCount else 0 end
 ) as [Count]
from
 Counter c,
 (
 select 1 m
 union all select 2
 union all select 3
 union all select 4
 union all select 5
 union all select 6
 union all select 7
 union all select 8
 union all select 9
 union all select 10
 union all select 11
 union all select 12
 ) aa
where
 @Year=year(AccessDateTime)
group by
 m
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;查询结果如下：&lt;/p&gt;</description></item><item><title>在vs2008中设置jquery智能提示</title><link>https://fwhyy.com/2009/05/in-setting-the-jquery-vs2008-intellisense/</link><pubDate>Wed, 20 May 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/05/in-setting-the-jquery-vs2008-intellisense/</guid><description>&lt;p&gt;1 要确保您的vs2008已经打了sp1补丁，可以点击&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=27673C47-B3B5-4C67-BD99-84E525B5CE61&amp;amp;displaylang=zh-cn"&gt;这里&lt;/a&gt;下载&lt;/p&gt;
&lt;p&gt;2 下载 jQuery-vsdoc.js ，如果您安装了asp.net mvc ，可以在mvc的项目下的srcipts目下找到，或是点击&lt;a href="http://docs.jquery.com/Downloading_jQuery#Download_jQuery"&gt;这里&lt;/a&gt;下载。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300705034.webp" alt="2010-12-30_104425" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;3 下载安装一个vs2008支持 -vsdoc.js 智能提示的一个补丁 ，可以点击这里下载&lt;/p&gt;
&lt;p&gt;4 准备工作已经做完，现在就可以来试试jquery的智能提示了，用vs2008新建一个项目，在页面的head标签里添加对jquery-1.3.2-vsdoc.js的引用&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300705137.webp" alt="2010-12-30_104506" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;5 现在在js的方法中敲一个$符号，智能提示就会弹出来。&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300705914.webp" alt="2010-12-30_104541" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;参考文章：&lt;a href="http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2008/11/21/jquery-intellisense-in-vs-2008.aspx&lt;/a&gt;&lt;/p&gt;</description></item><item><title>推荐一款小巧的截图工具</title><link>https://fwhyy.com/2009/05/recommend-a-small-screenshots-tools/</link><pubDate>Fri, 15 May 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/05/recommend-a-small-screenshots-tools/</guid><description>&lt;p&gt;用过很多的截图工具，发现FastStone算是比较出色的一款，无论是功能还是易用性都非常不错。在最新的版本中还添加了屏幕录制功能。&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.faststone.org/FSCapturerDownload.htm"&gt;下载地址&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;用户名:www.orsoon.com
注册码:KPYME-ISDUO-CSBYM-MNHEB&lt;/p&gt;</description></item><item><title>Sqlserver2005附加数据库为只读的解决方法</title><link>https://fwhyy.com/2009/05/sqlserver2005-additional-database-for-read-only-solutions/</link><pubDate>Fri, 08 May 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/05/sqlserver2005-additional-database-for-read-only-solutions/</guid><description>&lt;h2 id="症状"&gt;症状：&lt;/h2&gt;
&lt;p&gt;在sqlserver2005中附加数据库时，附加的数据库会变成只读的，只能进行查询操作。&lt;/p&gt;</description></item><item><title>Asp.net中递归实现CSS菜单</title><link>https://fwhyy.com/2009/04/aspnet-recursive-implementation-of-css-menu/</link><pubDate>Sat, 18 Apr 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/04/aspnet-recursive-implementation-of-css-menu/</guid><description>&lt;p&gt;现在网络上有各种各样的非常漂亮的css菜单，不过大多都是静态的，菜单项都是在页面中写死的，这样就不是很灵活，每次要修改菜单都要去修改页面，下面就介绍一个从数据库中读取菜单项的动态css菜单的例子。&lt;/p&gt;</description></item><item><title>NHibernate入门级示例（增 删 改）</title><link>https://fwhyy.com/2009/01/an-introduction-to-the-sample-to-nhibernate/</link><pubDate>Tue, 20 Jan 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/01/an-introduction-to-the-sample-to-nhibernate/</guid><description>&lt;p&gt;NHibernate相信大家都已非常熟悉，园子里有很多高手写了相关的系列文章，不过我还是NHibernate的一名初学者，在此将一个晚上学习成果分享一下，一个很简单的利用NHibernate实现增删改的例子。&lt;/p&gt;</description></item><item><title>Asp.net 2.0的Eval方法详解</title><link>https://fwhyy.com/2009/01/aspnet-2-0-the-eval-method-of-explanation/</link><pubDate>Wed, 14 Jan 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/01/aspnet-2-0-the-eval-method-of-explanation/</guid><description>&lt;p&gt;实际上Eval方法是TemplateControl的，而System.Web.UI.Page和System.Web.UI.UserControl都继承于TemplateControl，所以我们可以在Page和UserControl上直接调用个方法。
Page.Eval方法可以帮助我们更好的撰写数据绑定表达式，在ASP.NET 1.x时代，数据绑定表达式的一般形式是：&lt;/p&gt;</description></item><item><title>Asp.Net 连接Access数据库</title><link>https://fwhyy.com/2009/01/aspnet-access-database-connection/</link><pubDate>Sat, 10 Jan 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/01/aspnet-access-database-connection/</guid><description>&lt;p&gt;自学程序以来，一直使用的都是sqlserver数据库，最近帮一朋友做一个access的demo，发现在数据库的连接方面就存在很大差异，在web.config中配置好连接字符串，然后在后台取，在此我的做法是存两个值，将Provider和assess数据库文件的路径分开存，如下：&lt;/p&gt;</description></item><item><title>消除window.close()的提示窗口</title><link>https://fwhyy.com/2009/01/eliminate-the-prompt-window/</link><pubDate>Thu, 08 Jan 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/01/eliminate-the-prompt-window/</guid><description>&lt;p&gt;Window.close()这句脚本是用来关闭当前窗口，如果是在window.open的窗口中执行Window.close()，将会很顺利地将窗口关闭，但如果是在一非window.open打开的窗口中执行Window.close()，将会弹出一个提示窗口，如下：&lt;/p&gt;
&lt;p&gt;&lt;img src="https://img.fwhyy.com/2022/202201300636671.webp" alt="2010-12-30_124855" loading="lazy" decoding="async"&gt;
&lt;/p&gt;
&lt;p&gt;要在程序中消除这个提示框也很简单，不过在IE6和IE7稍有不同&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;IE6&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html xmlns=&amp;#34;http://www.w3.org/1999/xhtml&amp;#34; &amp;gt;
&amp;lt;head id=&amp;#34;Head1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;title&amp;gt;IE6Close&amp;lt;/title&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function closeWin()
 {
 window.opener=null;
 window.close();
 }
 &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;form id=&amp;#34;form2&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;div&amp;gt;
 &amp;lt;input id=&amp;#34;btnClose&amp;#34; type=&amp;#34;button&amp;#34; value=&amp;#34;close&amp;#34; onclick=&amp;#34;closeWin()&amp;#34;/&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2.IE7&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html xmlns=&amp;#34;http://www.w3.org/1999/xhtml&amp;#34; &amp;gt;
&amp;lt;head id=&amp;#34;Head1&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;title&amp;gt;IE7Colse&amp;lt;/title&amp;gt;
 &amp;lt;script type=&amp;#34;text/javascript&amp;#34;&amp;gt;
 function closeWin()
 {
 window.open(&amp;#39;&amp;#39;,&amp;#39;_self&amp;#39;,&amp;#39;&amp;#39;);
 window.close();
 }
 &amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;form id=&amp;#34;form2&amp;#34; runat=&amp;#34;server&amp;#34;&amp;gt;
 &amp;lt;div&amp;gt;
 &amp;lt;input id=&amp;#34;btnClose&amp;#34; type=&amp;#34;button&amp;#34; value=&amp;#34;close&amp;#34; onclick=&amp;#34;closeWin()&amp;#34;/&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Response.Redirect在新窗口打开 &amp;&amp; 3.0扩展方法</title><link>https://fwhyy.com/2009/01/response-redirect-in-a-new-window-open-3-0-extension-methods/</link><pubDate>Wed, 07 Jan 2009 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2009/01/response-redirect-in-a-new-window-open-3-0-extension-methods/</guid><description>&lt;p&gt;Response.Rederect在默认情况下是在本页跳转，所以除了在js中用window.open 或是给A标签添加target属性之外，在后台似乎不能来打开新的页面，其实不然，通过设置form的target属性同样可以让Response.Rederect所指向的url在新的窗口打开。下面用三种方法来实现。&lt;/p&gt;</description></item><item><title>MasterPage 小谈</title><link>https://fwhyy.com/2008/12/masterpage-introduction/</link><pubDate>Sat, 06 Dec 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/12/masterpage-introduction/</guid><description>&lt;h2 id="设置title"&gt;设置Title&lt;/h2&gt;
&lt;p&gt;1 如果想所有使用了masterpage的页面都是用一个title ，可以在masterpage页中设置title，并将内容页中的title去掉，否则内容页中的title会将masterpage中的title覆盖。&lt;/p&gt;</description></item><item><title>利用HttpModule实现防sql注入</title><link>https://fwhyy.com/2008/11/using-httpmodule-prevent-sql-injection/</link><pubDate>Sun, 23 Nov 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/11/using-httpmodule-prevent-sql-injection/</guid><description>&lt;p&gt;sql注入是被谈的很多的一个话题，有很多的方法能够实现sql的防注入，在这里就简单说一下如果使用HttpModule来实现sql的防注入。&lt;/p&gt;</description></item><item><title>CheckBox全选终极方案</title><link>https://fwhyy.com/2008/10/the-ultimate-solution-checkbox-selection/</link><pubDate>Thu, 23 Oct 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/10/the-ultimate-solution-checkbox-selection/</guid><description>&lt;p&gt;在我们的程序开发中经常会要用到CheckBox的全选，通常情况下是在一些数据绑定控件中如Gridview等&lt;/p&gt;</description></item><item><title>My97 使用的一点技巧</title><link>https://fwhyy.com/2008/10/some-tips-of-my97/</link><pubDate>Wed, 15 Oct 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/10/some-tips-of-my97/</guid><description>&lt;h2 id="需求"&gt;需求：&lt;/h2&gt;
&lt;p&gt;1.两个时间文本框，一个开始时间和一个结束时间，两个时间都是今天起以后的时间，并且开始时间不能大于结束时间。&lt;/p&gt;
&lt;p&gt;这样的需求在很多地方都会应用到，比如有些网站提供一些服务的购买，用户需要选择要购买服务的时间域等等。&lt;/p&gt;
&lt;p&gt;在My97的官网中有自定义时间的例子，我只是根据需要稍加了修改，代码如下:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&amp;lt;/title&amp;gt;
&amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;WdatePicker.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;input id=&amp;#34;txtB&amp;#34; type=&amp;#34;text&amp;#34;
onclick=&amp;#34;WdatePicker({minDate:&amp;#39;%y-%M-#{%d}&amp;#39;,maxDate:&amp;#39;#F{$dp.$D(\&amp;#39;txtE\&amp;#39;,{d:-1})}&amp;#39;})&amp;#34;/&amp;gt;
&amp;lt;input id=&amp;#34;txtE&amp;#34; type=&amp;#34;text&amp;#34;
onFocus=&amp;#34;WdatePicker({minDate:&amp;#39;#F{$dp.$D(\&amp;#39;txtB\&amp;#39;,{d:1})||\&amp;#39;%y-%M-#{%d+2}\&amp;#39;}&amp;#39;})&amp;#34;/&amp;gt;

&amp;lt;/body&amp;gt;

&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>SQL 计算一個字符串在另一个字符串中出現的次数</title><link>https://fwhyy.com/2008/08/sql-to-calculate-a-string-in-the-number-of-occurrences-of-another-string/</link><pubDate>Wed, 06 Aug 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/08/sql-to-calculate-a-string-in-the-number-of-occurrences-of-another-string/</guid><description>&lt;p&gt;在sqlserver中來計算一個字符串在另一個字符串中出現的次數，通常會去用循環來匹配，然後計算出出現的次數，這樣的效能不是很高。現在講一種比較簡單的方法也能實現同樣的功能，思路如下：&lt;/p&gt;</description></item><item><title>开发总结—数据库篇</title><link>https://fwhyy.com/2008/08/summary-the-database-development/</link><pubDate>Wed, 06 Aug 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/08/summary-the-database-development/</guid><description>&lt;p&gt;本文是我在平时工作中所遇到的数据库方面的一些知识总结&lt;/p&gt;</description></item><item><title>清除上传控件 File 的值</title><link>https://fwhyy.com/2008/07/remove-the-file-upload-control-values/</link><pubDate>Fri, 04 Jul 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/07/remove-the-file-upload-control-values/</guid><description>&lt;p&gt;因为File控件的value值是只读的，所以用document.getElementById(“File1″).value=”” 并不能清楚file控件的值。&lt;/p&gt;</description></item><item><title>解決“无法解决 equal to 操作的排序规则冲突 ”问题</title><link>https://fwhyy.com/2008/07/to-solve-the-unable-to-solve-the-equal-to-operation-collation-conflict-problem/</link><pubDate>Thu, 03 Jul 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/07/to-solve-the-unable-to-solve-the-equal-to-operation-collation-conflict-problem/</guid><description>&lt;h2 id="问题"&gt;问题：&lt;/h2&gt;
&lt;p&gt;在创建存储过程时 出现 “无法解决 equal to 操作的排序规则冲突 ”&lt;/p&gt;
&lt;h2 id="解决方法"&gt;解决方法：&lt;/h2&gt;
&lt;p&gt;1 WHERE 列名 collate Chinese_PRC_CI_AS(强制指定排序规则)，如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;select
 *
from
 test
where
 name collate chinese_prc_ci_as in
 (select name1 chinese_prc_ci_as from test1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;2 如果涉及到多表查询，则在on后面加上collate Chinese_PRC_CI_AS(强制指定排序规则) 如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;select
 *
from
 test1 1
join
 test2 2
on
 1.id=2.id collate Chinese_PRC_CI_AS
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>将服务器控件在后台生成html</title><link>https://fwhyy.com/2008/05/generate-html-server-controls-in-the-background/</link><pubDate>Wed, 28 May 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/05/generate-html-server-controls-in-the-background/</guid><description>&lt;p&gt;这个方法很有用，在做一些Ajax应用的时候，可以在后台将gridview 生成hmtl后回传到客户端，可以实现分页的功能。&lt;/p&gt;</description></item><item><title>开发总结—Javascript篇</title><link>https://fwhyy.com/2008/05/development-summary-javascript/</link><pubDate>Sun, 25 May 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/05/development-summary-javascript/</guid><description>&lt;p&gt;本文是我在平时工作中所遇到的javascript方面的一些知识总结，主要针对在asp.net中使用脚本。&lt;/p&gt;</description></item><item><title>Sybase.PowerDesiner12.0 下载 破解 汉化</title><link>https://fwhyy.com/2008/05/sybase-powerdesiner12-0-download/</link><pubDate>Sun, 11 May 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/05/sybase-powerdesiner12-0-download/</guid><description>&lt;h2 id="powerdesiner12-下载"&gt;PowerDesiner12 下载：&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.namipan.com/d/2687db90a67c150079bc1375ca2bb97a3f154e4add52000b"&gt;http://www.namipan.com/d/2687db90a67c150079bc1375ca2bb97a3f154e4add52000b&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="汉化补丁下载"&gt;汉化补丁下载：&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://download.csdn.net/source/298116"&gt;http://download.csdn.net/source/298116&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.namipan.com/d/SYBASE%20PowerDesigner%2012%20%e6%b1%89%e5%8c%96%e8%a1%a5%e4%b8%81%20.exe/20e073a65b965e5ac125f806da04da8bccc4623498d20600"&gt;http://www.namipan.com/d/SYBASE%20PowerDesigner%2012%20%e6%b1%89%e5%8c%96%e8%a1%a5%e4%b8%81%20.exe/20e073a65b965e5ac125f806da04da8bccc4623498d20600&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="破解下載"&gt;破解下載：&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.namipan.com/d/powerdesigner12.0%e7%89%88%e7%a0%b4%e8%a7%a3%e6%96%b9%e6%b3%95.txt/d4426b20c60d5e81439e5716f8239e6fbf2e43218c000000"&gt;http://www.namipan.com/d/powerdesigner12.0%e7%89%88%e7%a0%b4%e8%a7%a3%e6%96%b9%e6%b3%95.txt/d4426b20c60d5e81439e5716f8239e6fbf2e43218c000000&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Asp.Net中 %= 与%# 的区别</title><link>https://fwhyy.com/2008/04/the-difference-between-the-and-aspnet/</link><pubDate>Thu, 03 Apr 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/04/the-difference-between-the-and-aspnet/</guid><description>&lt;p&gt;&amp;lt;%= “oec2003” % &amp;gt; 相当于：Response.Write(“oec2003”);
&amp;lt;%# “oec2003” % &amp;gt; 相当于给变量赋值了oec2003&lt;/p&gt;
&lt;p&gt;在gridview中将一个绑定列转换成模板列时会看到有如下代码：&lt;/p&gt;</description></item><item><title>Sql中分隔字串–&gt;查询–&gt;组合字串</title><link>https://fwhyy.com/2008/03/separate-strings-in-sql/</link><pubDate>Tue, 18 Mar 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/03/separate-strings-in-sql/</guid><description>&lt;p&gt;最近在工作遇到一个数据库查询的问题，大概如下:表Table1中有字段No和Title，每一个No对应一个Title，表Table2中有NoAll字段，NoAll字段的value是No的组合，以逗号隔开，如”111,222,333″，现在要查询Table2，根据NoAll将其中的每一个No所对应的Title查询出来也以逗号分隔显示，如：”oec2003,oec2004,oec2004″。表定义如下：&lt;/p&gt;</description></item><item><title>C#3.0学习(3)—匿名类型</title><link>https://fwhyy.com/2008/03/learning-csharp-3-0-3-anonymous-types/</link><pubDate>Sun, 09 Mar 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/03/learning-csharp-3-0-3-anonymous-types/</guid><description>&lt;p&gt;匿名类型是在初始化的时候根据初始化列表自动产生类型的一种机制，利用对象初始化器来创建匿名对象的对象。如:&lt;/p&gt;</description></item><item><title>火箭十八连胜 振奋人心</title><link>https://fwhyy.com/2008/03/the-rockets-18-in-a-row/</link><pubDate>Sun, 09 Mar 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/03/the-rockets-18-in-a-row/</guid><description>&lt;p&gt;一早就起来坐在电脑前等着火箭的比赛，这场比赛关系重大，是对战黄蜂，赢了这场比赛就可以提升到西部第三名。虽然上次和黄蜂交锋赢了，但那时姚还没有受伤，所以这场比赛仍然很艰巨。&lt;/p&gt;</description></item><item><title>window.print()实现局部打印</title><link>https://fwhyy.com/2008/03/window-print-implementation-local-print/</link><pubDate>Thu, 06 Mar 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/03/window-print-implementation-local-print/</guid><description>&lt;p&gt;window.print() 实际上，是浏览器打印功能菜单的一种程序调用。与点击打印功能菜单一样，不能精确分页，不能设置纸型，套打的问题更加无从谈起，只不过，可以让用户不用去点菜单，直接点击网页中的一个按钮，或一个链接里面调用罢了。事实上，很多用户都是采用这种方式打印，但是这种方式最致命的缺点是不能设置打印参数，比如纸型，页边距，选择打印机等等。&lt;/p&gt;</description></item><item><title>看完《再见古惑仔》的一点感想</title><link>https://fwhyy.com/2008/03/after-watching-goodbye-gangster-feeling/</link><pubDate>Thu, 06 Mar 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/03/after-watching-goodbye-gangster-feeling/</guid><description>&lt;p&gt;古惑仔系列可以说影响过我们这一代人，有的人只是当作是一般的动作电影，娱乐一下而已，有的人可能会效仿片中的一些行为。很庆幸我是属于前者。&lt;/p&gt;
&lt;p&gt;近几天我看到《再见古惑仔》的这个片名，第一想到的就是是不是剧组想到8年前的古惑仔系列给社会带来的负面影响太大，拍这个来挽回一下。看完也证实了这一点，虽然片中也充满着打斗血腥的场面，但还是起到了一定的教育作用。&lt;/p&gt;</description></item><item><title>C#3.0学习(2)—对象集合初始化器</title><link>https://fwhyy.com/2008/02/learning-c-3-0-2-object-collection-initializer/</link><pubDate>Mon, 25 Feb 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/02/learning-c-3-0-2-object-collection-initializer/</guid><description>&lt;p&gt;创建一个对象时可以包含一个对象初始化器或集合初始化器，用于初始化所创建对象的成员或新创建的集合的元素。使用初始化器可以让我们的代码变得更简洁。&lt;/p&gt;</description></item><item><title>C#3.0学习(1)—隐含类型局部变量和扩展方法</title><link>https://fwhyy.com/2008/02/learning-csharp-3-0-1-implied-type-of-local-variables-and-extension-methods/</link><pubDate>Fri, 22 Feb 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/02/learning-csharp-3-0-1-implied-type-of-local-variables-and-extension-methods/</guid><description>&lt;h2 id="隐含类型局部变量"&gt;隐含类型局部变量&lt;/h2&gt;
&lt;p&gt;隐含类型的局部变量是用var关键字来声明的，如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var i = 123;
var h=123.123;
var s = “oec2003&amp;#34;;
var intArr = new[] {1,2,3,4} ;
var a = new[] { 1, 10, 100, 1000 };
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;乍一看有点像javascript中的声明方式，虽然关键字一样但是有着本质区别。&lt;/p&gt;
&lt;p&gt;在c#3.0中用var关键字声明的变量被赋值后，在编译时编译器会根据变量值的类型自动推断出变量的类型。所以仍然是强类型，这点和object不同。其实var 关键字并不是一个具体的类型，只是起到了一个占位符的作用，编译后将替换成相应的类型。要注意的一点是用var声明的变量一定要赋初始值，否则会出现编译错误，因为如果不赋值就无法根据值来推断变量的类型。&lt;/p&gt;
&lt;p&gt;var只能声明局部变量，而且可以在foreach中使用，如：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;var nums=new []{1,2,3,4,5};
foreach(var i in nums)
{

}
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="扩展方法"&gt;扩展方法&lt;/h2&gt;
&lt;p&gt;这是个非常有用的特性，扩展方法允许我们在不改变源码的情况下添加现有类型中的实例方法。扩展方法所在的类必须为静态类。如下：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public static class oec2003Extensions
{
 public static bool IsValidEmail(this String s)
 {
 Regex regex = new Regex(@&amp;#34;^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$&amp;#34;);
 return regex.IsMatch(s);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的IsValidEmail静态方法在静态类oec2003Extensions类中，这个类可以在任何的名称空间下，在要用的地方引用名称空间就行。IsValidEmail方法的作用是用来验证电子邮件。方法中有三个参数：this String s 。this只是一个编译上的要求，作为一个提示来告诉编译器此方法有可能作为扩展方法来使用；String就是我们需要扩展的类型；s则为要验证邮件的内容。下面来看看怎样来使用此扩展方法。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protected void Button2_Click(object sender, EventArgs e)
{
 if (this.TextBox1.Text.Trim().IsValidEmail())
 {
 Response.Write(&amp;#34;email is right&amp;#34;);
 }
 else
 {
 Response.Write(&amp;#34;email is error&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;是不是很神奇，在string类型中就多了一个刚才添加的IsValidEmail方法，可以直接调用，用来实现邮件地址的验证。&lt;/p&gt;</description></item><item><title>动态添加GridView行</title><link>https://fwhyy.com/2008/02/dynamically-add-tow-to-gridview/</link><pubDate>Fri, 15 Feb 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/02/dynamically-add-tow-to-gridview/</guid><description>&lt;h2 id="c代码"&gt;C#代码:&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;span class="lnt"&gt;25
&lt;/span&gt;&lt;span class="lnt"&gt;26
&lt;/span&gt;&lt;span class="lnt"&gt;27
&lt;/span&gt;&lt;span class="lnt"&gt;28
&lt;/span&gt;&lt;span class="lnt"&gt;29
&lt;/span&gt;&lt;span class="lnt"&gt;30
&lt;/span&gt;&lt;span class="lnt"&gt;31
&lt;/span&gt;&lt;span class="lnt"&gt;32
&lt;/span&gt;&lt;span class="lnt"&gt;33
&lt;/span&gt;&lt;span class="lnt"&gt;34
&lt;/span&gt;&lt;span class="lnt"&gt;35
&lt;/span&gt;&lt;span class="lnt"&gt;36
&lt;/span&gt;&lt;span class="lnt"&gt;37
&lt;/span&gt;&lt;span class="lnt"&gt;38
&lt;/span&gt;&lt;span class="lnt"&gt;39
&lt;/span&gt;&lt;span class="lnt"&gt;40
&lt;/span&gt;&lt;span class="lnt"&gt;41
&lt;/span&gt;&lt;span class="lnt"&gt;42
&lt;/span&gt;&lt;span class="lnt"&gt;43
&lt;/span&gt;&lt;span class="lnt"&gt;44
&lt;/span&gt;&lt;span class="lnt"&gt;45
&lt;/span&gt;&lt;span class="lnt"&gt;46
&lt;/span&gt;&lt;span class="lnt"&gt;47
&lt;/span&gt;&lt;span class="lnt"&gt;48
&lt;/span&gt;&lt;span class="lnt"&gt;49
&lt;/span&gt;&lt;span class="lnt"&gt;50
&lt;/span&gt;&lt;span class="lnt"&gt;51
&lt;/span&gt;&lt;span class="lnt"&gt;52
&lt;/span&gt;&lt;span class="lnt"&gt;53
&lt;/span&gt;&lt;span class="lnt"&gt;54
&lt;/span&gt;&lt;span class="lnt"&gt;55
&lt;/span&gt;&lt;span class="lnt"&gt;56
&lt;/span&gt;&lt;span class="lnt"&gt;57
&lt;/span&gt;&lt;span class="lnt"&gt;58
&lt;/span&gt;&lt;span class="lnt"&gt;59
&lt;/span&gt;&lt;span class="lnt"&gt;60
&lt;/span&gt;&lt;span class="lnt"&gt;61
&lt;/span&gt;&lt;span class="lnt"&gt;62
&lt;/span&gt;&lt;span class="lnt"&gt;63
&lt;/span&gt;&lt;span class="lnt"&gt;64
&lt;/span&gt;&lt;span class="lnt"&gt;65
&lt;/span&gt;&lt;span class="lnt"&gt;66
&lt;/span&gt;&lt;span class="lnt"&gt;67
&lt;/span&gt;&lt;span class="lnt"&gt;68
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Configuration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Web&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Web.Security&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Web.UI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Web.UI.WebControls&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Web.UI.WebControls.WebParts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Web.UI.HtmlControls&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System.Data.SqlClient&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;_Default&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Web&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UI&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Page&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Page_Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsPostBack&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;BindGrid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;DataTable&lt;/span&gt; &lt;span class="n"&gt;ReadGridView&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataTable&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataTable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataRow&lt;/span&gt; &lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CategoryID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dr&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Cells&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Cells&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rows&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Cells&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Button1_Click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;object&lt;/span&gt; &lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;EventArgs&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataTable&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ReadGridView&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//this.GridView1.DataSource = dt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//this.GridView1.DataBind();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataRow&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewRow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ItemArray&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;object&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;oec2003&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Rows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InsertAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AcceptChanges&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataSource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataBind&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;BindGrid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ConfigurationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectionStrings&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;NorthwindConnectionString&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SqlConnection&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SqlConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;str&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SqlCommand&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SqlCommand&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;SELECT top 1 [ProductID], [ProductName], [CategoryID] FROM [Products]&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SqlDataAdapter&lt;/span&gt; &lt;span class="n"&gt;sda&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;SqlDataAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DataSet&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DataSet&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataSource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tables&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;DefaultView&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GridView1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DataBind&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;sda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dispose&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="html代码"&gt;Html代码&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;span class="lnt"&gt;18
&lt;/span&gt;&lt;span class="lnt"&gt;19
&lt;/span&gt;&lt;span class="lnt"&gt;20
&lt;/span&gt;&lt;span class="lnt"&gt;21
&lt;/span&gt;&lt;span class="lnt"&gt;22
&lt;/span&gt;&lt;span class="lnt"&gt;23
&lt;/span&gt;&lt;span class="lnt"&gt;24
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;%@ Page Language=&amp;#34;C#&amp;#34; AutoEventWireup=&amp;#34;true&amp;#34; CodeFile=&amp;#34;Default.aspx.cs&amp;#34; Inherits=&amp;#34;_Default&amp;#34; %&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html PUBLIC &amp;#34;-//W3C//DTD XHTML 1.0 Transitional//EN&amp;#34; 、
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt; &amp;#34;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&amp;#34;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt; &lt;span class="na"&gt;xmlns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;http://www.w3.org/1999/xhtml&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Head1&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;runat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;无标题页&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;title&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;head&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;form2&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;runat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;asp:Button&lt;/span&gt; &lt;span class="na"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Button1&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;runat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;server&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;OnClick&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Button1_Click&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Button&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;asp:GridView&lt;/span&gt; &lt;span class="na"&gt;ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;GridView2&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;runat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;server&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;AutoGenerateColumns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;False&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;DataKeyNames&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductID&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;asp:BoundField&lt;/span&gt; &lt;span class="na"&gt;DataField&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductID&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;HeaderText&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductID&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;InsertVisible&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;False&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;ReadOnly&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;True&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;SortExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductID&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;asp:BoundField&lt;/span&gt; &lt;span class="na"&gt;DataField&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductName&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;HeaderText&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductName&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;SortExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;ProductName&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;asp:BoundField&lt;/span&gt; &lt;span class="na"&gt;DataField&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CategoryID&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;HeaderText&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CategoryID&amp;#34;&lt;/span&gt; &lt;span class="na"&gt;SortExpression&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;CategoryID&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;Columns&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;asp:GridView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id="数据库连接字串"&gt;数据库连接字串&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;connectionStrings&amp;gt;
 &amp;lt;add name=&amp;#34;NorthwindConnectionString&amp;#34;
 connectionString=&amp;#34;Data Source=FENGWEI;Initial Catalog=Northwind;User ID=sa;Password=1234&amp;#34;
 providerName=&amp;#34;System.Data.SqlClient&amp;#34;/&amp;gt;
&amp;lt;/connectionStrings&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://files.cnblogs.com/oec2003/AddRow.rar"&gt;AddRow.rar&lt;/a&gt;&lt;/p&gt;</description></item><item><title>解决AJAX中使用UpdatePanel后再用Response.Write();无法弹出对话框问题</title><link>https://fwhyy.com/2008/01/updatepanel-issues/</link><pubDate>Sat, 19 Jan 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/01/updatepanel-issues/</guid><description>&lt;p&gt;在AJAX支持的网站中使用想使用Response.Wrie(‘’); 或 Page. RegisterStartupScript (); 弹出一些提示对话框，没有效果。有如下三种解决方法：&lt;/p&gt;</description></item><item><title>Html细线表格的实现</title><link>https://fwhyy.com/2008/01/the-realization-of-the-html-form-thin-lines/</link><pubDate>Thu, 10 Jan 2008 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2008/01/the-realization-of-the-html-form-thin-lines/</guid><description>&lt;p&gt;在网页制作中，我们常常会使用到表格，表格使得需要表达的信息更清楚，明了。&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;table border=&amp;#34;1&amp;#34; cellspacing=&amp;#34;0&amp;#34; bordercolor=&amp;#34;#000000&amp;#34; width = &amp;#34;80%&amp;#34;&amp;gt;
 &amp;lt;tr&amp;gt;
 &amp;lt;td&amp;gt;1.1&amp;lt;/td&amp;gt;
 &amp;lt;td&amp;gt;1.2&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
 &amp;lt;tr&amp;gt;
 &amp;lt;td&amp;gt;2.1&amp;lt;/td&amp;gt;
 &amp;lt;td&amp;gt;2.2&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
&amp;lt;table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这段代码定义了border = 1pix的表格，但实际上表格的实际边框宽度为2pix, 这是因为表格边框由：表格外边框和单元格边框两部分构成。那么如何定义一个细线表格(实际边宽为1pix) 呢？&lt;/p&gt;
&lt;h3 id="使用-cellspacing和背景色技术"&gt;使用 cellspacing和背景色技术:&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;table border=&amp;#34;0&amp;#34; cellspacing=&amp;#34;1&amp;#34; bgcolor=&amp;#34;#000000&amp;#34; width = &amp;#34;80%&amp;#34;&amp;gt;
 &amp;lt;tr bgcolor=&amp;#34;#ffffff&amp;#34;&amp;gt;
 &amp;lt;td&amp;gt;1.1&amp;lt;/td&amp;gt;
 &amp;lt;td&amp;gt;1.2&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
 &amp;lt;tr bgcolor=&amp;#34;#ffffff&amp;#34;&amp;gt;
 &amp;lt;td&amp;gt;2.1&amp;lt;/td&amp;gt;
 &amp;lt;td&amp;gt;2.2&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
&amp;lt;table&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="使用border-collapse属性"&gt;使用border-collapse属性:&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;table border=&amp;#34;1&amp;#34; cellspacing=&amp;#34;0&amp;#34; bordercolor=&amp;#34;#000000&amp;#34; width = &amp;#34;80%&amp;#34;
 style=&amp;#34;border-collapse:collapse;&amp;#34;&amp;gt;
 &amp;lt;tr&amp;gt;
 &amp;lt;td&amp;gt;1.1&amp;lt;/td&amp;gt;
 &amp;lt;td&amp;gt;1.2&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
 &amp;lt;tr&amp;gt;
 &amp;lt;td&amp;gt;2.1&amp;lt;/td&amp;gt;
 &amp;lt;td&amp;gt;2.2&amp;lt;/td&amp;gt;
 &amp;lt;/tr&amp;gt;
&amp;lt;table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>类型“GridView”的控件 必须放在具有 runat=server 的窗体标记内 错误的解决方法</title><link>https://fwhyy.com/2007/12/type-of-the-gridview-controls-within-the-form-tag-must-be-placed-with-runat-equal-server-error-solution/</link><pubDate>Sun, 16 Dec 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/12/type-of-the-gridview-controls-within-the-form-tag-must-be-placed-with-runat-equal-server-error-solution/</guid><description>&lt;h2 id="错误提示"&gt;错误提示:&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;类型“GridView”的控件 必须放在具有 runat=server 的窗体标记内&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="解决方法"&gt;解决方法:&lt;/h2&gt;
&lt;p&gt;在后台文件中重载VerifyRenderingInServerForm方法,如:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public override void VerifyRenderingInServerForm(Control control)
{
 //base.VerifyRenderingInServerForm(control);
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>在visual studio中删除最近打开的项目和文件记录的方法</title><link>https://fwhyy.com/2007/12/delete-recently-opened-in-visual-studio-project-and-file-records/</link><pubDate>Wed, 05 Dec 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/12/delete-recently-opened-in-visual-studio-project-and-file-records/</guid><description>&lt;p&gt;在打开visual studio时有一个最近打开的项目列表，但是当我们将某个项目在本地磁盘上删除后，那个项目列表依然存在，下面的方法可以让删除的项目在列表中不出现。&lt;/p&gt;</description></item><item><title>解决sqlserver2005数据库sa登录问题</title><link>https://fwhyy.com/2007/12/solve-the-problem-of-sqlserver2005-database-sa-login/</link><pubDate>Sun, 02 Dec 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/12/solve-the-problem-of-sqlserver2005-database-sa-login/</guid><description>&lt;p&gt;如果安装sql server 2005的时候，设置的身份验证模式为”windows”(默认), 安装完成后, 再设置为”sql server和windows”的身份验证模式, 则sa用户是被禁用的。必须启用它。&lt;/p&gt;</description></item><item><title>几个不同类型无刷新联动例子</title><link>https://fwhyy.com/2007/11/several-different-types-without-refresh-linkage-example/</link><pubDate>Fri, 30 Nov 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/11/several-different-types-without-refresh-linkage-example/</guid><description>&lt;h2 id="iframe实现无刷新联动"&gt;Iframe实现无刷新联动&lt;/h2&gt;
&lt;p&gt;iframe的无刷新其实是局部刷新，状态栏的滚动条还是会滚动，只是页面不会闪烁，这是一种比较老的技术了，在处理的数据两大的时候会比较慢，在本例中需要两个页面：oec2003index.aspx和oec2003frame.asapx,oec2003index.aspx用来显示界面，其中有一个iframe标记，指向oec2003frame.aspx页用来显示结果&lt;/p&gt;</description></item><item><title>“无法在web服务器上启动调试,不具备调试此程序的权限” 问题解决</title><link>https://fwhyy.com/2007/11/unable-to-start-debugging-on-the-web-server-do-not-have-permission-to-debug-the-program-problem-solving/</link><pubDate>Wed, 28 Nov 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/11/unable-to-start-debugging-on-the-web-server-do-not-have-permission-to-debug-the-program-problem-solving/</guid><description>&lt;p&gt;最近维护以前用03做的一个项目,又重新将03装上了，很久都没有用03了,装上后打开项目没有问题,但按F5运行却出现下面错误&lt;/p&gt;</description></item><item><title>C#和Javascript交互</title><link>https://fwhyy.com/2007/11/csharp-and-javascript-interaction/</link><pubDate>Fri, 23 Nov 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/11/csharp-and-javascript-interaction/</guid><description>&lt;p&gt;在asp.net开发中，经常会用到后台和前台的交互，就此总结了一点c#和javascript相互操作的方法。&lt;/p&gt;</description></item><item><title>GridView中实现CheckBox的全选</title><link>https://fwhyy.com/2007/11/to-realize-the-checkbox-selection-in-the-gridview/</link><pubDate>Fri, 09 Nov 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/11/to-realize-the-checkbox-selection-in-the-gridview/</guid><description>&lt;h2 id="用服务器端的方法"&gt;用服务器端的方法&lt;/h2&gt;
&lt;p&gt;在页面上放一个gridview控件，配置好数据源，编辑列，添加一个模版列，再编辑模版，放入一个checkbox控件。代码如下：&lt;/p&gt;</description></item><item><title>Asp.Net Ajax—Calendar控件使用</title><link>https://fwhyy.com/2007/11/aspnet-ajax-calendar-control/</link><pubDate>Mon, 05 Nov 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/11/aspnet-ajax-calendar-control/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;Calendar控件是一个很简单的控件，主要用来在页面中提供日历的选择，其实现在已经有很多用javascript写的&lt;a href="http://blog.csdn.net/21aspnet/archive/2007/05/14/1607712.aspx"&gt;日历控件&lt;/a&gt;，但是Canlendar日历控件能够让我们更快速地来实现这种效果，只需要进行一些简单的设置即可。&lt;/p&gt;</description></item><item><title>存储过程生成流水号</title><link>https://fwhyy.com/2007/10/stored-procedure-to-generate-a-serial-number/</link><pubDate>Wed, 31 Oct 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/10/stored-procedure-to-generate-a-serial-number/</guid><description>&lt;h2 id="首先在数据库中创建一个存放流水号的表"&gt;首先在数据库中创建一个存放流水号的表&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE TABLE [dbo].[NumSeq] (
 [Cate] [varchar] (2) NOT NULL ,
 [DateNo] [varchar] (4) NOT NULL ,
 [Seq] [int] NULL ,
 [CrTime] [datetime] NOT NULL
)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码中，Cate 字段为流水号的头，可以在下面的存储过程中用参数的方式传入，我的定义是2个字符，这个可以根据具体需要更改&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DateNo 字段为获取日期信息&lt;/li&gt;
&lt;li&gt;Seq 字段为流水号，但最终生成的流水号是这三个字段的相加&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="创建存储过程"&gt;创建存储过程&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;CREATE PROC dpPMT_SGetMaintainSeq
@MaintainCate VARCHAR(2)

AS
--***********************累加编号*************************************************
DECLARE @MaintainNo VARCHAR(12)
IF NOT EXISTS(SELECT
 *
 FROM
 NumSeq
 WHERE
 Cate=@MaintainCate AND DATEDIFF(DAY,CrTime,GETDATE())=0)
 BEGIN
 INSERT INTO
 NumSeq(Cate,DateNo,Seq)
 values(@MaintainCate,RIGHT(CONVERT(VARCHAR(4),YEAR(GETDATE())),2)+
 REPLICATE(&amp;#39;0&amp;#39;,2-LEN(MONTH(GETDATE())))+CONVERT(VARCHAR(2),MONTH(GETDATE())),0)

 END
ELSE
 BEGIN
 UPDATE
 NumSeq
 SET
 Seq=Seq+1
 WHERE
 Cate=@MaintainCate AND DateNo=RIGHT(CONVERT(VARCHAR(4),YEAR(GETDATE())),2)+
 REPLICATE(&amp;#39;0&amp;#39;,2-LEN(MONTH(GETDATE())))+CONVERT(VARCHAR(2),MONTH(GETDATE()))
 END

--************************组合编号***************************************************************
SELECT
 @MaintainNo=Cate+DateNo+REPLICATE(&amp;#39;0&amp;#39;,6-LEN(Seq))+CONVERT(VARCHAR(6),Seq)
FROM
 NumSeq
WHERE
 Cate=@MaintainCate AND DateNo=RIGHT(CONVERT(VARCHAR(4),YEAR(GETDATE())),2)+
 REPLICATE(&amp;#39;0&amp;#39;,2-LEN(MONTH(GETDATE())))+CONVERT(VARCHAR(2),MONTH(GETDATE()))

SELECT @MaintainNo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个存储过程最终输出的结果如：AA071031000001 前面两位是传入的参数，中间四位是年份的后两位和月，最后的六位为6位数字的流水号。您也可以修改上面的存储过程来生成符合您要求的流水号&lt;/p&gt;</description></item><item><title>Asp.Net Ajax-PopupControl控件使用</title><link>https://fwhyy.com/2007/09/asp-net-ajax-popupcontrol/</link><pubDate>Wed, 19 Sep 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/09/asp-net-ajax-popupcontrol/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;Popupcontrol可以弹出任意类型的控件，不管是在服务器控件还是html控件。就是在某控件获取焦点时弹出另外一个控件，进行一些操作后，隐藏弹出的控件。&lt;/p&gt;</description></item><item><title>对设计模式的一点理解</title><link>https://fwhyy.com/2007/09/a-little-understanding-of-design-patterns/</link><pubDate>Sat, 08 Sep 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/09/a-little-understanding-of-design-patterns/</guid><description>&lt;p&gt;说起设计模式，不得不提的是GoF23种设计模式，这些设计模式是在历史性的一本经典著作《设计模式：可复用面向对象软件的基础》被描述的，这本书的四位作者并称为Gang of Four(GoF) 。由于这本书极具影响力，所以我们通常所说的设计模式就隐含地表示为“面向对象设计模式”，但这并不意味着“设计模式”就等同于“面向对象设计模式”。&lt;/p&gt;</description></item><item><title>Asp.Net Ajax-HoverMenu控件使用</title><link>https://fwhyy.com/2007/09/asp-net-ajax-hovermenu/</link><pubDate>Thu, 06 Sep 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/09/asp-net-ajax-hovermenu/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;通过名字我们可以看出这是一个菜单控件，当鼠标移动到指定的位置时，在不影响其他的元素的情况下出现一个菜单，并允许用户进行一些操作。&lt;/p&gt;</description></item><item><title>Asp.Net Ajax—ValidatorCallout控件使用</title><link>https://fwhyy.com/2007/09/asp-net-ajax-validatorcallout/</link><pubDate>Thu, 06 Sep 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/09/asp-net-ajax-validatorcallout/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;ValidatorCallout控件是一个用来绑定验证控件的提示控件,让验证的信息的显示可以更加地直观. 如下&lt;/p&gt;</description></item><item><title>Asp.Net Ajax-Passwordstrength控件使用</title><link>https://fwhyy.com/2007/08/asp-net-ajax-passwordstrength/</link><pubDate>Sat, 25 Aug 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/08/asp-net-ajax-passwordstrength/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;PasswordStrength控件是用来提示用户输入密码的情况,用户在密码框中输入密码时,在文本框的后面会有一个提示,显示密码的强度,这种提示有两种方式:文本和进度条,提示信息的位置也可以由我们来自己设置,样式可以写CSS来定义。当密码框失去焦点时提示信息会自动消失。下面就来看看该控件的重要属性吧。&lt;/p&gt;</description></item><item><title>Asp.Net Ajax—TextBoxWateramrk</title><link>https://fwhyy.com/2007/08/asp-net-ajax-textboxwateramrk/</link><pubDate>Thu, 23 Aug 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/08/asp-net-ajax-textboxwateramrk/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;TextBoxWatermark控件是一个用于TextBox的水印控件,就是在文本框输入文字之前,文本框中有一些提示性的文字,并可以自定义css控制它的样式,实际用处我感觉不是很大,但给用户带来了操作上的方便,也有很好的视觉效果.&lt;/p&gt;</description></item><item><title>Asp.Net Ajax—FilteredTextBox控件使用</title><link>https://fwhyy.com/2007/08/asp-net-ajax-filteredtextbox/</link><pubDate>Tue, 21 Aug 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/08/asp-net-ajax-filteredtextbox/</guid><description>&lt;h2 id="简介"&gt;简介&lt;/h2&gt;
&lt;p&gt;FilterTextBox控件是一种文本框的过滤控件，可以阻止用户进行不准确的输入，相比较vs里提供的验证控件显得更为严格，验证控件是在用户输入了不准确的输入后，给出相应的提示，而现在要介绍的FilterTextBox都不给用户输入错误数据的机会。&lt;/p&gt;</description></item><item><title>Asp.Net Ajax —AutoComplete控件使用</title><link>https://fwhyy.com/2007/08/asp-net-ajax-autocomplete/</link><pubDate>Sat, 18 Aug 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/08/asp-net-ajax-autocomplete/</guid><description>&lt;p&gt;以前见到google和迅雷等网站在搜索文本框中输入文字后能自动提示,感觉这种功能很炫也很实用.现在在学习asp.net ajax 发现AjaxControlToolKit工具包中的AutoComplete控件就能实现这种功能,而且非常简单.&lt;/p&gt;</description></item><item><title>DotNet 3.0 框架介绍</title><link>https://fwhyy.com/2007/08/dotnet-3-0-framework-introduce/</link><pubDate>Fri, 10 Aug 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/08/dotnet-3-0-framework-introduce/</guid><description>&lt;p&gt;微软.NET的最新版本，.NET Framework 3.0，为开发下一代业务解决方案软件系统开启了新的可能。它的设计目标是：提高生产力，降低基础设施复杂性，提供一个一致的元系统，让企业级服务、工作流解决方案和用户体验软件系统的开发更容易。&lt;/p&gt;</description></item><item><title>AjaxControlToolkit安装&amp;下载</title><link>https://fwhyy.com/2007/08/ajaxcontroltoolkit-installing/</link><pubDate>Fri, 03 Aug 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/08/ajaxcontroltoolkit-installing/</guid><description>&lt;p&gt;以下是收集关于AjaxControlToolkit安装的一篇文章，感谢原作者&lt;/p&gt;</description></item><item><title>解决Asp.Net Ajax UpdatePanel 乱码问题</title><link>https://fwhyy.com/2007/07/solve-the-problem-of-the-aspnet-ajax-updatepanel-garbled/</link><pubDate>Wed, 25 Jul 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/07/solve-the-problem-of-the-aspnet-ajax-updatepanel-garbled/</guid><description>&lt;p&gt;UpdatePanel中当ContentComplate里面存在TextBox的时候会出现中文乱码&lt;/p&gt;
&lt;p&gt;一般存在这样两个解决方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在web.config里面增加下面代码。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;lt;globalization fileEncoding=&amp;#34;utf-8&amp;#34; requestEncoding=&amp;#34;utf-8&amp;#34;
 responseEncoding=&amp;#34;utf-8&amp;#34; culture=&amp;#34;zh-CN&amp;#34;/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Ajax,其实并不难</title><link>https://fwhyy.com/2007/07/ajax-actually-not-difficult/</link><pubDate>Mon, 23 Jul 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/07/ajax-actually-not-difficult/</guid><description>&lt;p&gt;Ajax是一种应用技术的缩写，全称为&lt;code&gt;Asynchronous Javascript And XML &lt;/code&gt;,这种技术的使用可以更好地提高用户的体验。组成这种技术的主要因素有：&lt;code&gt;javascript&lt;/code&gt;语言，&lt;code&gt;css&lt;/code&gt;样式表，&lt;code&gt;XMLHttpRequest&lt;/code&gt;数据交换对象和&lt;code&gt;Dom&lt;/code&gt;对象。&lt;/p&gt;</description></item><item><title>.Net泛型编程简介</title><link>https://fwhyy.com/2007/05/net-generic-programming/</link><pubDate>Tue, 22 May 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/05/net-generic-programming/</guid><description>&lt;p&gt;.NET泛型编程已经离我们不远了，在微软最近随SQL Server Yukon Beta1发行的.NET Framework 1.2中就已经有了泛型的影子。虽然现在它还是问题多多，但是相信随着新版.NET Framework的正式发行（正式发行时的版本号会是2.0），这些问题会得到解决。因此我们也该为.NET泛型编程做些准备了。&lt;/p&gt;</description></item><item><title>常用的一些正则表达式</title><link>https://fwhyy.com/2007/05/commonly-used-some-regular-expressions/</link><pubDate>Tue, 08 May 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/05/commonly-used-some-regular-expressions/</guid><description>&lt;p&gt;正则表达式用于字符串处理、表单验证等场合，实用高效。但用到时总是不太把握，以致往往要查证一番。现将一些常用的表达式收集于此，以备不时之需。&lt;/p&gt;</description></item><item><title>实现鼠标悬停高亮显示—分别在gridview和datagrid中</title><link>https://fwhyy.com/2007/05/implement-mouseover-highlight-respectively-in-the-gridview-and-the-datagrid/</link><pubDate>Mon, 07 May 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/05/implement-mouseover-highlight-respectively-in-the-gridview-and-the-datagrid/</guid><description>&lt;p&gt;在datagrid中的ItemDataBound事件中写如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
 if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
 {
 e.Item.Attributes.Add(&amp;#34;onmouseover&amp;#34;, &amp;#34;c=this.style.backgroundColor;this.style.backgroundColor=&amp;#39;#66CCFF&amp;#39;&amp;#34;);
 e.Item.Attributes.Add(&amp;#34;onmouseout&amp;#34;, &amp;#34;this.style.backgroundColor=c&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;在girdview中的RowDataBound事件中写下如下代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
 if (e.Row.RowType == DataControlRowType.DataRow)
 {
 e.Row.Attributes.Add(&amp;#34;onmouseover&amp;#34;, &amp;#34;currentcolor=this.style.backgroundColor;this.style.backgroundColor=&amp;#39;#6699ff&amp;#39;;&amp;#34;);
 e.Row.Attributes.Add(&amp;#34;onmouseout&amp;#34;, &amp;#34;this.style.backgroundColor=currentcolor;&amp;#34;);
 }
}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Asp.Net中水晶报表的简单使用</title><link>https://fwhyy.com/2007/01/simple-to-use-aspnet-in-crystal-reports/</link><pubDate>Thu, 11 Jan 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/01/simple-to-use-aspnet-in-crystal-reports/</guid><description>&lt;p&gt;Crystal Reports是具有强大内容创建和集成功能的高效的报表技术，是第三方开发的报表工具，使用水晶报表我们可以更好地向用户展示数据。以前可以通过编程的方式将数据集中的数据进行处理后在windows应用程序或web应用程序中输出显示，但如果要做超出了基本格式化的一些工作如：求和、平均、多极汇总、制作图标等就会显得比较复杂，而水晶报表正好弥补了其中的不足。&lt;/p&gt;</description></item><item><title>看姚明受伤后的火箭</title><link>https://fwhyy.com/2007/01/see-yaos-injury-after-the-rockets/</link><pubDate>Mon, 08 Jan 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/01/see-yaos-injury-after-the-rockets/</guid><description>&lt;p&gt;姚明受伤了，这是在几个星期以前的事了，没有姚明的火箭让我们看火箭的比赛总象少点什么。受伤前姚明曾差点连续四场比赛拿下30＋10的数据，但是火箭的战绩并不是很好。后来姚明伤了，这对喜欢火箭，喜欢姚明的人来说无疑事个不好的消息。&lt;/p&gt;
&lt;p&gt;麦迪的伤愈复出给火箭带来了希望，而且付出后的表现也是最好的证明，连续四场比赛打出30＋，还带领火箭取得五连胜的成绩，虽然今天在加时赛输给了森林狼。&lt;/p&gt;</description></item><item><title>Asp.Net中列表数据绑定控件浅析</title><link>https://fwhyy.com/2007/01/asp-net-lists-data-bound-controls/</link><pubDate>Wed, 03 Jan 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/01/asp-net-lists-data-bound-controls/</guid><description>&lt;p&gt;在Asp.Net中用来显示列表数据的控件有&lt;code&gt;Repeater&lt;/code&gt;，&lt;code&gt;DataList&lt;/code&gt;,&lt;code&gt;DataGrid&lt;/code&gt;三种.&lt;/p&gt;
&lt;p&gt;DataGrid的灵活性很强，内置了丰富的事件，提供分页，编辑，排序等一些特性，对表格的操作也是非常方便的，而且还有很多种的风格可选，由于自带了很多的功能和特性，所以开发速度很快，容易部署。但它的性能不是很高，每次的操作都会返回到服务器。主要用在对有排序、分页、编辑和多列的显示，而且对性能的要求不是很高，一般情况下数据源是一个DateSet。&lt;/p&gt;</description></item><item><title>Asp.Net中的一个小的性能测试</title><link>https://fwhyy.com/2007/01/a-small-performance-test-of-asp-net/</link><pubDate>Wed, 03 Jan 2007 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2007/01/a-small-performance-test-of-asp-net/</guid><description>&lt;p&gt;大家都知道使用缓存可用大大提高asp.net应用程序的性能,那么究竟能提高多少性能呢?我做了一个小小的测试.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在vs2003中新建一个web应用程序,在页面上添加一个DataGrid控件，让DataGrid里显示NorthWind数据库中employees表的内容。我的做法是在vs2003的服务器资源管理器中建立一个连接到NorthWind数据库的连接，然后将其中的employees&lt;/li&gt;
&lt;/ol&gt;</description></item><item><title>Asp.Net的性能问题</title><link>https://fwhyy.com/2006/12/asp-net-performance-issues/</link><pubDate>Sat, 23 Dec 2006 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2006/12/asp-net-performance-issues/</guid><description>&lt;p&gt;性能对于一个应用程序来说是一个很重要的问题，在web的开发中也是一样，相信没有人愿意在电脑屏幕前花8秒钟来等待一个也面的打开，这就是常说的在web上的8秒钟原则。对于一个应用程序的性能我们应该把它当作是应用程序的一项功能，在设计的时候就应该处理好性能的问题，而不应该在整个程序开发完了以后再来进行优化，因为这样会付出更多的代价。&lt;/p&gt;</description></item><item><title>姚明差一篮板平记录 火箭2分惜败开拓者</title><link>https://fwhyy.com/2006/12/yao-ming-a-rebounding-flat-poor-records-the-rockets-2-points-defeat-the-blazers/</link><pubDate>Fri, 22 Dec 2006 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2006/12/yao-ming-a-rebounding-flat-poor-records-the-rockets-2-points-defeat-the-blazers/</guid><description>&lt;p&gt;上午十一点，火箭对开拓者，中央台不转，我们一堆人挤在一个小小的电脑前面就看开了，忍受着超慢的网速，忍受着不很流畅的画面，只因为这场比赛的意义不一般，姚明只要在这场比赛拿到30加10就可以平火箭队的连续四场比赛那30加10的记录，真是看的扣人心悬，但最终姚明还是没能挺住，就差一个板啊！真是可惜。&lt;/p&gt;
&lt;p&gt;再说比赛，虽然比分落后最多的时候有十几分，但在离比赛快结束的时候层一度追到只剩两分，然而火箭没把握住，应该说是姚明没把握住。麦迪不在，姚明难道就不能独挑大梁吗？对湖人在大比分领先的情况下，在最后被对手反超；打勇士30秒大翻盘，包括今天的比赛，小巨人有点让火箭队的球迷失望了。&lt;/p&gt;
&lt;p&gt;姚明要走的路还很长，希望他越来越成熟，打得越来越好，我们期待着火箭夺冠的那一天。&lt;/p&gt;</description></item><item><title>推广blog四妙招！</title><link>https://fwhyy.com/2006/12/to-promote-the-blog-four-tips/</link><pubDate>Thu, 21 Dec 2006 00:00:00 +0800</pubDate><guid>https://fwhyy.com/2006/12/to-promote-the-blog-four-tips/</guid><description>&lt;p&gt;写blog有一段时间了，虽然不是很长但达到现在的访问量已让我很满意了。在写blog的这段时间里学习到了很多同时也总结出了一些推广自己blog的方法：&lt;/p&gt;
&lt;p&gt;1、我们每个人的blog内容应该都和自己的兴趣爱好有关，所以我们可以在自己感兴趣的方面写出一些好的文章，然后到一些相应的论坛去发贴或是回贴随便把自己的blog推广出去。如blog内容是IT相关的就可以到CSDN或是一些大的门户网站的IT论坛去推广。&lt;/p&gt;
&lt;p&gt;2、在网上见到很多人在blog里贴上一些比较暴露的图片或是在一些色情网站设置相应当链接来提高blog的点击率。虽然这种方法的效果还可以，但我个人不是十分同，在以前的文章中我说过blog不仅仅可以让我们来学习而且还能建立我们的个人品牌，如果使用这种方式个人的形象会受到损害，更无从谈起个人品牌了。我们写blog的目的是为了结交朋友，有一个更好的学习交流的平台，提升自我素质，而不仅仅是点击率。所以强烈建议用提高文章质量的方式来获得广大网友的喜欢。&lt;/p&gt;
&lt;p&gt;3、自己东奔西跑，到处逛论坛，相同学朋友推荐，不如把这些事情交给一些特定的网站来做，在这儿推荐两个推广blog的网站：博客砖和中文博客群。在我blog首页的左边博客推荐栏目下有这两个网站的相应链接。大家可以进去看看，只需要通过简单点注册就可以让您的blog在他们的网站占有一席之地。是一个推广blog的好途径&lt;/p&gt;
&lt;p&gt;4、如果你是一个兴趣广泛的人，你就可以加入很多的博客圈，这样很多的博友都能看到你的文章，也可以达到推广自己blog的目的。&lt;/p&gt;
&lt;p&gt;总之不管使用什么方法，最重要的一点还是要内容好，有特色，这样你才会有一群固定的读者，才会创建好你的个人品牌。&lt;/p&gt;</description></item></channel></rss>