<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tony Bai &#187; Blog</title>
	<atom:link href="http://tonybai.com/tag/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://tonybai.com</link>
	<description>一个程序员的心路历程</description>
	<lastBuildDate>Sat, 11 Apr 2026 00:16:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>2022年博客回顾与总结</title>
		<link>https://tonybai.com/2023/01/11/2022-blog-summary/</link>
		<comments>https://tonybai.com/2023/01/11/2022-blog-summary/#comments</comments>
		<pubDate>Tue, 10 Jan 2023 23:04:32 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[DSL]]></category>
		<category><![CDATA[eBPF]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go-module]]></category>
		<category><![CDATA[go1.19]]></category>
		<category><![CDATA[go1.20]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[gopherchina]]></category>
		<category><![CDATA[Gopher部落]]></category>
		<category><![CDATA[Go语言第一课]]></category>
		<category><![CDATA[Go语言精进之路]]></category>
		<category><![CDATA[Kubernetes]]></category>
		<category><![CDATA[log]]></category>
		<category><![CDATA[operator]]></category>
		<category><![CDATA[时序数据库]]></category>
		<category><![CDATA[智能网联]]></category>
		<category><![CDATA[极客时间]]></category>
		<category><![CDATA[知识星球]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=3779</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2023/01/11/2022-blog-summary 2022年对我来说，也是十分忙碌和充实的一年。尽管和2021年相比，成果物没那么多^_^。 伴随着二宝的长大，我发现自己的闲暇时间被进一步“压缩”，还好大宝上初中后领悟到了自驱学习的重要性和相关方法后，她的学习现在基本不需要我过问了。 2022年初，《Go语言精进之路：从新手到高手的编程思想、方法和技巧》系列1、2册上市后取得了不错的口碑，纸版书售卖量也还不错，在年中的时候都进入二印了，这也让我有机会修复一些勘误表中的问题，让读者拿到内容更准确的的版本。年中，我还借助谢大组织的“GoCN社区的Go读书会”分享了《Go语言精进之路》这本书的写作历程、内容导读以及个人的一些读书方法和经验。 我在极客时间的《Go语言第一课》专栏由于口碑相传，得到了很多Gopher的关注和学习，我也很积极的回答学员们的各种问题。目前该专栏大约排在极客时间周学习排行榜15名左右，不过还进不了首页推荐，和那些常驻首页的大V课程还没法比^_^。 2022年应谢大之邀，原本计划在GopherChina 2022之前的培训环节做一期《Go高级工程师训练营》培训的，但GopherChina因为疫情原因两次推迟，最终线下大会被取消，没能成行。期望在2023年能把这个培训补上。 2022年是我进入智能网联汽车这个赛道的第二个年头，精力主要花在研发几个重要的核心产品上，包括：车云通信产品、车端的基于DSL的数据处理产品、云端的流数据处理和时序数据存储产品等，跨度很大，难度很大。目前车云通信产品已经部署在我们主要客户的生产环境，为2023车型提供车云通道能力，另外我们也在与国内一些大主机厂做POC测试。时序数据存储产品进入关键的设计阶段，这块经验的确不足，需要投入较大精力学习、思考和尝试，2023年我将投入较大精力在这个产品上。 在博客写作方面，我仍然保持高昂的热情，粗略统计了一下，今年写了有80余篇。和2021年一样，这里我也根据阅读数量选出了2022年本博客最受欢迎的若干篇文章(排名不分先后)： 《2022年Go语言盘点：泛型落地，无趣很好，稳定为王》 《Go编程语言与环境：万字长文复盘导致Go语言成功的那些设计决策》 《评点2021-2022年上市的那些Go语言新书》 《这可能是最权威、最全面的Go语言编码风格规范了！》 《Go 1.20新特性前瞻》 《Go为什么能成功》 《通过实例理解Go标准库context包》 《slog：Go官方版结构化日志包》 《Go语言之道[译]》 《Go 1.19中值得关注的几个变化》 《使用Go开发Kubernetes Operator：基本结构》 《使用Go语言开发eBPF程序》 《使用C语言从头开发一个Hello World级别的eBPF程序》 《GoCN社区Go读书会第二期：《Go语言精进之路》》 《使用Go基于国密算法实现双向认证》 《小厂内部私有Go module拉取方案（续）》 《Go程序员拥抱C语言简明指南》 《使用ANTLR和Go实现DSL入门》 《Go 1.18中值得关注的几个变化》 《Go社区主流Kafka客户端简要对比》 《为什么有了Go module后“依赖地狱”问题依然存在》 《聊聊Go应用输出日志的工程实践》 复盘了一下2022年的博客文章，感觉目前的博客选题更多是“工作和学习中遇到的问题”来驱动的，还缺少系统化的规划和组织，2023年在这方面需要加强。 最后展望一下2023年！ 在纸版书写作方面，2023年是否开启《Go语言精进之路》第三册、 是否扩写《Go语言第一课》专栏，然后整理成纸版书出版等都是可尝试的但未确定的事情。 专栏方面也有一些不成熟的选题想法： 如何写出地道的Go代码 深入理解Go核心技术 Go高级工程师必知必会(在培训的基础上扩充) Gopher部落知识星球也将进入运营的第三个年头，2022年尝试做出了一些改变，效果还不错。2023年争取再聚焦一下：围绕少而精的几个主题做高质量分享。 2022年最大的“损失”是微博账号被冻结了，目前只能暂时用小号。之前的账号啥时候恢复也不清楚，也可能会永远失去那个账号。失去了微博这个重要的私域流量，损失还是蛮大的:( 2023年，由于时序数据存储这个产品的原因，可能会真正开始学习Rust语言，虽然之前了解过多次，但都是从入门到放弃了。这回有了产品和项目驱动，希望不会“重蹈覆辙”^_^。 “Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群！高品质首发Go技术文章，“三天”首发阅读权，每年两期Go语言发展现状分析，每天提前1小时阅读到新鲜的Gopher日报，网课、技术专栏、图书内容前瞻，六小时内必答保证等满足你关于Go语言生态的所有需求！2022年，Gopher部落全面改版，将持续分享Go语言与Go应用领域的知识、技巧与实践，并增加诸多互动形式。欢迎大家加入！ 著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个链接地址：https://m.do.co/c/bff6eed92687 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/2021-blog-summary-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2023/01/11/2022-blog-summary">本文永久链接</a> &#8211; https://tonybai.com/2023/01/11/2022-blog-summary</p>
<p>2022年对我来说，也是<strong>十分忙碌和充实的一年</strong>。尽管和<a href="https://tonybai.com/2021/12/31/2021-blog-summary">2021年</a>相比，成果物没那么多^_^。</p>
<p>伴随着<a href="https://daughter2.tonybai.com">二宝</a>的长大，我发现自己的闲暇时间被进一步“压缩”，还好<a href="https://daughter.tonybai.com">大宝</a>上初中后领悟到了自驱学习的重要性和相关方法后，她的学习现在基本不需要我过问了。</p>
<p>2022年初，<a href="https://book.douban.com/subject/35720728/">《Go语言精进之路：从新手到高手的编程思想、方法和技巧》</a>系列1、<a href="https://book.douban.com/subject/35720729/">2册</a>上市后取得了不错的口碑，纸版书售卖量也还不错，在年中的时候都进入二印了，这也让我有机会修复一些<a href="https://github.com/bigwhite/GoProgrammingFromBeginnerToMaster/blob/main/errata.md">勘误表</a>中的问题，让读者拿到内容更准确的的版本。年中，我还借助谢大组织的“GoCN社区的Go读书会”分享了<a href="https://tonybai.com/2022/07/07/gocn-community-go-book-club-issue2-go-programming-from-beginner-to-master">《Go语言精进之路》这本书的写作历程</a>、内容导读以及个人的一些读书方法和经验。</p>
<p>我在极客时间的<a href="http://gk.link/a/10AVZ">《Go语言第一课》</a>专栏由于口碑相传，得到了很多Gopher的关注和学习，我也<a href="https://tonybai.com/go-course-faq">很积极的回答学员们的各种问题</a>。目前该专栏大约排在极客时间周学习排行榜15名左右，不过还进不了首页推荐，和那些常驻首页的大V课程还没法比^_^。</p>
<p>2022年应谢大之邀，原本计划在GopherChina 2022之前的培训环节做一期《Go高级工程师训练营》培训的，但GopherChina因为疫情原因两次推迟，最终线下大会被取消，没能成行。期望在2023年能把这个培训补上。</p>
<p>2022年是我进入智能网联汽车这个赛道的第二个年头，精力主要花在研发几个重要的核心产品上，包括：车云通信产品、车端的基于DSL的数据处理产品、云端的流数据处理和时序数据存储产品等，跨度很大，难度很大。目前车云通信产品已经部署在我们主要客户的生产环境，为2023车型提供车云通道能力，另外我们也在与国内一些大主机厂做POC测试。时序数据存储产品进入关键的设计阶段，这块经验的确不足，需要投入较大精力学习、思考和尝试，2023年我将投入较大精力在这个产品上。</p>
<p>在博客写作方面，我仍然保持高昂的热情，粗略统计了一下，今年写了有80余篇。和2021年一样，这里我也根据阅读数量选出了2022年本博客最受欢迎的若干篇文章(排名不分先后)：</p>
<ul>
<li>《<a href="https://tonybai.com/2022/12/29/the-2022-review-of-go-programming-language">2022年Go语言盘点：泛型落地，无趣很好，稳定为王</a>》</li>
<li>《<a href="https://tonybai.com/2022/05/04/the-paper-of-go-programming-language-and-environment">Go编程语言与环境：万字长文复盘导致Go语言成功的那些设计决策</a>》</li>
<li>《<a href="https://tonybai.com/2022/06/01/reviewing-those-new-go-language-books-coming-out-in-2021-2022">评点2021-2022年上市的那些Go语言新书</a>》</li>
<li>《<a href="https://tonybai.com/2022/11/26/intro-of-google-go-style">这可能是最权威、最全面的Go语言编码风格规范了！</a>》</li>
<li>《<a href="https://tonybai.com/2022/11/17/go-1-20-foresight">Go 1.20新特性前瞻</a>》</li>
<li>《<a href="https://tonybai.com/2022/12/07/why-go-succeed/">Go为什么能成功</a>》</li>
<li>《<a href="https://tonybai.com/2022/11/08/understand-go-context-by-example">通过实例理解Go标准库context包</a>》</li>
<li>《<a href="https://tonybai.com/2022/10/30/first-exploration-of-slog">slog：Go官方版结构化日志包</a>》</li>
<li>《<a href="https://tonybai.com/2022/09/25/the-tao-of-go">Go语言之道[译]</a>》</li>
<li>《<a href="https://tonybai.com/2022/08/22/some-changes-in-go-1-19">Go 1.19中值得关注的几个变化</a>》</li>
<li>《<a href="https://tonybai.com/2022/08/15/developing-kubernetes-operators-in-go-part1">使用Go开发Kubernetes Operator：基本结构</a>》</li>
<li>《<a href="https://tonybai.com/2022/07/19/develop-ebpf-program-in-go/">使用Go语言开发eBPF程序</a>》</li>
<li>《<a href="https://tonybai.com/2022/07/05/develop-hello-world-ebpf-program-in-c-from-scratch">使用C语言从头开发一个Hello World级别的eBPF程序</a>》</li>
<li>《<a href="https://tonybai.com/2022/07/07/gocn-community-go-book-club-issue2-go-programming-from-beginner-to-master">GoCN社区Go读书会第二期：《Go语言精进之路》</a>》</li>
<li>《<a href="https://tonybai.com/2022/07/17/two-way-authentication-using-go-and-sm-algorithm">使用Go基于国密算法实现双向认证</a>》</li>
<li>《<a href="https://tonybai.com/2022/06/18/the-approach-to-go-get-private-go-module-in-house-part2">小厂内部私有Go module拉取方案（续）</a>》</li>
<li>《<a href="https://tonybai.com/2022/05/16/the-short-guide-of-embracing-c-lang-for-gopher">Go程序员拥抱C语言简明指南</a>》</li>
<li>《<a href="https://tonybai.com/2022/05/10/introduction-of-implement-dsl-using-antlr-and-go">使用ANTLR和Go实现DSL入门</a>》</li>
<li>《<a href="https://tonybai.com/2022/04/20/some-changes-in-go-1-18">Go 1.18中值得关注的几个变化</a>》</li>
<li>《<a href="https://tonybai.com/2022/03/28/the-comparison-of-the-go-community-leading-kakfa-clients">Go社区主流Kafka客户端简要对比</a>》</li>
<li>《<a href="https://tonybai.com/2022/03/12/dependency-hell-in-go/">为什么有了Go module后“依赖地狱”问题依然存在</a>》</li>
<li>《<a href="https://tonybai.com/2022/03/05/go-logging-practice">聊聊Go应用输出日志的工程实践</a>》</li>
</ul>
<p>复盘了一下2022年的博客文章，感觉目前的博客选题更多是“工作和学习中遇到的问题”来驱动的，还缺少系统化的规划和组织，2023年在这方面需要加强。</p>
<p>最后展望一下2023年！</p>
<p>在纸版书写作方面，2023年是否开启《Go语言精进之路》第三册、 是否扩写《Go语言第一课》专栏，然后整理成纸版书出版等都是可尝试的但未确定的事情。</p>
<p>专栏方面也有一些不成熟的选题想法：</p>
<ul>
<li>如何写出地道的Go代码</li>
<li>深入理解Go核心技术</li>
<li>Go高级工程师必知必会(在培训的基础上扩充)</li>
</ul>
<p><a href="https://wx.zsxq.com/dweb2/index/group/51284458844544">Gopher部落知识星球</a>也将进入运营的第三个年头，<a href="https://tonybai.com/2022/03/06/the-2022-plan-of-gopher-tribe">2022年尝试做出了一些改变</a>，效果还不错。2023年争取再聚焦一下：围绕少而精的几个主题做高质量分享。</p>
<p>2022年最大的“损失”是<a href="https://weibo.com/bigwhite20xx">微博账号</a>被冻结了，目前只能暂时用<a href="https://weibo.com/u/6484441286">小号</a>。之前的账号啥时候恢复也不清楚，也可能会永远失去那个账号。失去了微博这个重要的私域流量，损失还是蛮大的:(</p>
<p>2023年，由于时序数据存储这个产品的原因，可能会真正开始学习Rust语言，虽然之前了解过多次，但都是从入门到放弃了。这回有了产品和项目驱动，希望不会“重蹈覆辙”^_^。</p>
<hr />
<p><a href="https://wx.zsxq.com/dweb2/index/group/51284458844544">“Gopher部落”知识星球</a>旨在打造一个精品Go学习和进阶社群！高品质首发Go技术文章，“三天”首发阅读权，每年两期Go语言发展现状分析，每天提前1小时阅读到新鲜的Gopher日报，网课、技术专栏、图书内容前瞻，六小时内必答保证等满足你关于Go语言生态的所有需求！2022年，Gopher部落全面改版，将持续分享Go语言与Go应用领域的知识、技巧与实践，并增加诸多互动形式。欢迎大家加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-tribe-zsxq-small-card.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/go-programming-from-beginner-to-master-qr.png" alt="img{512x368}" /></p>
<p><img src="http://image.tonybai.com/img/tonybai/go-first-course-banner.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/imooc-go-column-pgo-with-qr.jpg" alt="img{512x368}" /></p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻)归档仓库 &#8211; https://github.com/bigwhite/gopherdaily</p>
<p>我的联系方式：</p>
<ul>
<li>微博(暂不可用)：https://weibo.com/bigwhite20xx</li>
<li>微博2：https://weibo.com/u/6484441286</li>
<li>博客：tonybai.com</li>
<li>github: https://github.com/bigwhite</li>
</ul>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2023, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2023/01/11/2022-blog-summary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>这可能是最权威、最全面的Go语言编码风格规范了！</title>
		<link>https://tonybai.com/2022/11/26/intro-of-google-go-style/</link>
		<comments>https://tonybai.com/2022/11/26/intro-of-google-go-style/#comments</comments>
		<pubDate>Sat, 26 Nov 2022 05:56:25 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[best-practices]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[cockroachdb]]></category>
		<category><![CDATA[Cpp]]></category>
		<category><![CDATA[decisions]]></category>
		<category><![CDATA[EffectiveGo]]></category>
		<category><![CDATA[FAQ]]></category>
		<category><![CDATA[gitlab]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[GoFAQ]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[gotips]]></category>
		<category><![CDATA[Go语言编码风格规范]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[idiomatic]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[sourcegraph]]></category>
		<category><![CDATA[style-guide]]></category>
		<category><![CDATA[uber]]></category>
		<category><![CDATA[代码风格]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[地道]]></category>
		<category><![CDATA[惯用法]]></category>
		<category><![CDATA[编码规范]]></category>
		<category><![CDATA[谷歌]]></category>
		<category><![CDATA[鹅厂]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=3747</guid>
		<description><![CDATA[本文永久链接 &#8211; https://tonybai.com/2022/11/26/intro-of-google-go-style 每种编程语言除了固定的语法之外，都会有属于自己的地道的(idiomatic)写法。其实，自然语言也不例外，你想，你用心想想是不是这样。 语言的设计者们希望开发人员都能编写统一风格的地道的代码，这样不仅代码可读性好，便于社区统一代码风格，而且针对惯用法的优化也可能会让地道的代码拥有更好的运行效率。语言团队也会不遗余力的通过各种方式(文档、blog、演讲、书籍、视频等)向开发者传授如何写出更地道、更高效、可读性更好的代码。 以Go语言为例，为了能让Gopher更好的了解如何写出高效、地道的Go代码，Go开源伊始就编写了《Effective Go》和《Go FAQ》两篇文档。前者负责介绍Go惯用法，后者则担负着将Go语言设计层面的问题以及解决思路与Gopher进行对齐的重任： 同时，Go语言之父们以及Go团队核心成员们在早期十分活跃并不遗余力的向Go社区推广Go的惯用法，Go官方站点上积累的各个早期的blog文章以及各个talk资料也成为了gopher学习地道Go编码的重要参考： 这些资料为了全世界Gopher的Go编码风格建立了基线。大多数情况下只要遵循这些资料并借助gofmt工具的自动格式化就可以写出风格比较地道的Go代码了。 然而《Effective Go》更像是说明地道风格Go代码的总体原则，不能“面面俱到”的覆盖每个编码的细节，而大公司对内部代码的风格一致性有着严格的要求。这不仅是高质量的要求，也是内部高效协作的要求。于是在若干年后，一些较早接纳Go且成为Go重度用户的大厂和初创公司结合自己的工程实践纷纷推出了公司内使用的Go编码风格规范，这里就包含我们耳熟能详的Uber、鹅厂、sourcegraph、CockroachDB、gitlab 等。这些Go代码风格指南也成为Go社区开发人员在代码风格规范性方面的重要参考。 不过，这些公司推出的代码风格指南有一个共同特点，那就是规范性有余，但权威性和全面性不足。Go社区都期待这Go语言的发源地：Google公司的Go编码风格规范的推出。之前，Google已经在其style guide站点上推出了其内部使用的很多主流编程语言的style guide，包括：C++、Java、C#、JavaScript、Python、Shell等。 在2022年11月份中旬，就在Go刚刚过完其第13个生日而步入青少年成长阶段之际，Google内部的Go语言编码风格规范终于出现在其style guide站点上了！ 不过，在介绍Google Go style guide前，我们首先要知道有关google style guide的几点内容： 这些guide的主要目的是Google内部自用，所有开发人员、代码审查人员、代码可读性导师必须要遵守并达成一致； 所有语言的style guide都会随着语言的演进而持续更新优化； 各个语言的style guide的结构布局与写作风格都不相同； 这些style guide都不接受Google之外人员的pr。 如上图，Google内部的Go语言编码风格规范系列文档目前由四个部分组成，它们分别是概述、指南、决定和最佳实践。根据概述篇的内容我们可以大体知道每篇文档的功用。这一系列文档汇集了当前编写可读的且地道的(idiomatic)Go代码的最佳方法，其目的是使刚接触这门语言的开发者能够避免常见的错误，同时也为那些在Google内部审查Go代码的人提供统一的风格。 这些文档的重要性略有不同： 指南篇（https://google.github.io/styleguide/go/guide）概述了Google的Go编码风格的基础。这份文件是权威性的，并被用作风格决定和最佳实践两个文档中建议的基础。 决定篇 (https://google.github.io/styleguide/go/decisions) 是一份内容更详细的文档，总结了关于特定风格点的决定，并在适当的地方讨论了决定背后的理由。这些决定可能偶尔会根据新的数据、新的语言特性、新的库或新出现的模式而改变。 最佳实践篇（https://google.github.io/styleguide/go/best-practices）记录了一些随着时间的推移而发展起来的模式，这些模式可以解决常见的问题，且可读性好并足够健壮，可以满足对代码可维护性的要求。 初步阅读了一下，这系列文档份的确算是目前最权威、最全面的Go语言编码风格规范了！其中决定篇和最佳实践篇涵盖的内容非常全面，内容和例子也非常到位。只不过，这套规范由于刚刚推出，还有很多改善优化和标记todo的地方。并且，其中有些内容是与Google是强相关的，但这依然是一份值得每个gopher认真阅读的资料。 此外，整套文档中经常引用一个名为“Go tips”的文档，不过该文档尚未放出，但从行文中引用的go tips的章节标题来看，很值得期待！ 本博客正在将这套文档翻译为中文供大家参考，目前概述篇、指南篇和决定篇和最佳实践篇均已经初步翻译完毕(机翻辅助)。待go tips文档发布后，这里也会将其译为中文。 “Gopher部落”知识星球旨在打造一个精品Go学习和进阶社群！高品质首发Go技术文章，“三天”首发阅读权，每年两期Go语言发展现状分析，每天提前1小时阅读到新鲜的Gopher日报，网课、技术专栏、图书内容前瞻，六小时内必答保证等满足你关于Go语言生态的所有需求！2022年，Gopher部落全面改版，将持续分享Go语言与Go应用领域的知识、技巧与实践，并增加诸多互动形式。欢迎大家加入！ 我爱发短信：企业级短信平台定制开发专家 https://tonybai.com/。smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。2020年4月8日，中国三大电信运营商联合发布《5G消息白皮书》，51短信平台也会全新升级到“51商用消息平台”，全面支持5G RCS消息。 著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个链接地址：https://m.do.co/c/bff6eed92687 [...]]]></description>
			<content:encoded><![CDATA[<p><img src="https://tonybai.com/wp-content/uploads/google-go-style/google-go-style-1.png" alt="" /></p>
<p><a href="https://tonybai.com/2022/11/26/intro-of-google-go-style">本文永久链接</a> &#8211; https://tonybai.com/2022/11/26/intro-of-google-go-style</p>
<p>每种编程语言除了固定的语法之外，都会有属于自己的<strong>地道的(idiomatic)写法</strong>。其实，自然语言也不例外，你想，你用心想想是不是这样。</p>
<p>语言的设计者们希望开发人员都能编写统一风格的地道的代码，这样不仅代码可读性好，便于社区统一代码风格，而且针对惯用法的优化也可能会让地道的代码拥有更好的运行效率。语言团队也会不遗余力的通过各种方式(<a href="https://go.dev/doc">文档</a>、<a href="https://go.dev/blog">blog</a>、<a href="https://go.dev/talks">演讲</a>、<a href="http://www.gopl.io">书籍</a>、视频等)向开发者传授如何写出更地道、更高效、可读性更好的代码。</p>
<p>以Go语言为例，为了能让Gopher更好的了解如何写出高效、地道的Go代码，Go开源伊始就编写了<a href="https://go.dev/doc/effective_go">《Effective Go》</a>和<a href="https://go.dev/doc/faq">《Go FAQ》</a>两篇文档。前者负责介绍Go惯用法，后者则担负着将Go语言设计层面的问题以及解决思路与Gopher进行对齐的重任：</p>
<p><img src="https://tonybai.com/wp-content/uploads/intro-of-google-go-style-2.png" alt="" /></p>
<p>同时，Go语言之父们以及Go团队核心成员们在早期十分活跃并不遗余力的向Go社区推广Go的惯用法，Go官方站点上积累的各个早期的<a href="https://go.dev/blog/all">blog文章</a>以及<a href="https://go.dev/talks/">各个talk资料</a>也成为了gopher学习地道Go编码的重要参考：</p>
<p><img src="https://tonybai.com/wp-content/uploads/intro-of-google-go-style-3.png" alt="" /></p>
<p>这些资料为了全世界Gopher的Go编码风格建立了基线。大多数情况下只要遵循这些资料并借助gofmt工具的自动格式化就可以写出风格比较地道的Go代码了。</p>
<p>然而《Effective Go》更像是说明地道风格Go代码的总体原则，不能“面面俱到”的覆盖每个编码的细节，而大公司对内部代码的风格一致性有着严格的要求。这不仅是高质量的要求，也是内部高效协作的要求。于是在若干年后，一些较早接纳Go且成为Go重度用户的大厂和初创公司结合自己的工程实践纷纷推出了公司内使用的Go编码风格规范，这里就包含我们耳熟能详的<a href="https://tonybai.com/2019/10/12/uber-go-style-guide/">Uber</a>、<a href="https://github.com/Tencent/secguide">鹅厂</a>、<a href="https://about.sourcegraph.com/handbook/engineering/go_style_guide">sourcegraph</a>、<a href="https://github.com/cockroachdb/cockroach/blob/master/docs/style.md">CockroachDB</a>、<a href="https://docs.gitlab.com/ee/development/go_guide/">gitlab</a> 等。这些Go代码风格指南也成为Go社区开发人员在代码风格规范性方面的<strong>重要参考</strong>。</p>
<p>不过，这些公司推出的代码风格指南有一个共同特点，那就是<strong>规范性有余，但权威性和全面性不足</strong>。Go社区都期待这Go语言的发源地：Google公司的Go编码风格规范的推出。之前，Google已经在其<a href="https://google.github.io/styleguide/">style guide站点</a>上推出了其内部使用的很多主流编程语言的style guide，包括：<a href="https://google.github.io/styleguide/cppguide.html">C++</a>、<a href="https://google.github.io/styleguide/javaguide.html">Java</a>、<a href="https://google.github.io/styleguide/csharp-style.html">C#</a>、<a href="https://google.github.io/styleguide/jsguide.html">JavaScript</a>、<a href="https://google.github.io/styleguide/pyguide.html">Python</a>、<a href="https://google.github.io/styleguide/shellguide.html">Shell</a>等。</p>
<p><img src="https://tonybai.com/wp-content/uploads/intro-of-google-go-style-4.png" alt="" /></p>
<p>在2022年11月份中旬，就在Go刚刚过完其<a href="https://tonybai.com/2022/11/11/go-opensource-13-years">第13个生日</a>而步入青少年成长阶段之际，<a href="https://google.github.io/styleguide/go/">Google内部的Go语言编码风格规范</a>终于出现在其style guide站点上了！</p>
<p><img src="https://tonybai.com/wp-content/uploads/intro-of-google-go-style-5.png" alt="" /></p>
<p>不过，在介绍Google Go style guide前，我们首先要知道有关google style guide的几点内容：</p>
<ul>
<li>这些guide的主要目的是Google内部自用，所有开发人员、代码审查人员、代码可读性导师必须要遵守并达成一致；</li>
<li>所有语言的style guide都会随着语言的演进而持续更新优化；</li>
<li>各个语言的style guide的结构布局与写作风格都不相同；</li>
<li>这些style guide都不接受Google之外人员的pr。</li>
</ul>
<p>如上图，Google内部的Go语言编码风格规范系列文档目前由四个部分组成，它们分别是概述、指南、决定和最佳实践。根据概述篇的内容我们可以大体知道每篇文档的功用。这一系列文档汇集了当前编写可读的且地道的(idiomatic)Go代码的最佳方法，其目的是使刚接触这门语言的开发者能够避免常见的错误，同时也为那些在Google内部审查Go代码的人提供统一的风格。</p>
<p>这些文档的重要性略有不同：</p>
<ul>
<li>
<p><a href="https://tonybai.com/google-go-style/google-go-style-guide">指南篇</a>（https://google.github.io/styleguide/go/guide）概述了Google的Go编码风格的基础。这份文件是权威性的，并被用作<strong>风格决定</strong>和<strong>最佳实践</strong>两个文档中建议的基础。</p>
</li>
<li>
<p><a href="https://tonybai.com/google-go-style/google-go-style-decisions">决定篇</a> (https://google.github.io/styleguide/go/decisions) 是一份内容更详细的文档，总结了关于特定风格点的决定，并在适当的地方讨论了决定背后的理由。这些决定可能偶尔会根据新的数据、新的语言特性、新的库或新出现的模式而改变。</p>
</li>
<li>
<p><a href="https://tonybai.com/google-go-style/google-go-style-best-practices">最佳实践篇</a>（https://google.github.io/styleguide/go/best-practices）记录了一些随着时间的推移而发展起来的模式，这些模式可以解决常见的问题，且可读性好并足够健壮，可以满足对代码可维护性的要求。</p>
</li>
</ul>
<p>初步阅读了一下，这系列文档份的确算是目前最权威、最全面的Go语言编码风格规范了！其中决定篇和最佳实践篇涵盖的内容非常全面，内容和例子也非常到位。只不过，这套规范由于刚刚推出，还有很多改善优化和标记todo的地方。并且，其中有些内容是与Google是强相关的，但这依然是一份值得每个gopher认真阅读的资料。</p>
<p>此外，整套文档中经常引用一个名为“Go tips”的文档，不过该文档尚未放出，但从行文中引用的go tips的章节标题来看，很值得期待！</p>
<p>本博客正在将这套文档翻译为中文供大家参考，目前<a href="https://tonybai.com/google-go-style">概述篇</a>、<a href="https://tonybai.com/google-go-style/google-go-style-guide">指南篇</a>和<a href="https://tonybai.com/google-go-style/google-go-style-decisions">决定篇</a>和<a href="https://tonybai.com/google-go-style/google-go-style-best-practices">最佳实践篇</a>均已经初步翻译完毕(机翻辅助)。待go tips文档发布后，这里也会将其译为中文。</p>
<hr />
<p><a href="https://wx.zsxq.com/dweb2/index/group/51284458844544">“Gopher部落”知识星球</a>旨在打造一个精品Go学习和进阶社群！高品质首发Go技术文章，“三天”首发阅读权，每年两期Go语言发展现状分析，每天提前1小时阅读到新鲜的Gopher日报，网课、技术专栏、图书内容前瞻，六小时内必答保证等满足你关于Go语言生态的所有需求！2022年，Gopher部落全面改版，将持续分享Go语言与Go应用领域的知识、技巧与实践，并增加诸多互动形式。欢迎大家加入！</p>
<p><img src="http://image.tonybai.com/img/tonybai/gopher-tribe-zsxq-small-card.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/go-programming-from-beginner-to-master-qr.png" alt="img{512x368}" /></p>
<p><img src="http://image.tonybai.com/img/tonybai/go-first-course-banner.png" alt="img{512x368}" /><br />
<img src="http://image.tonybai.com/img/tonybai/imooc-go-column-pgo-with-qr.jpg" alt="img{512x368}" /></p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/。smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。2020年4月8日，中国三大电信运营商联合发布《5G消息白皮书》，51短信平台也会全新升级到“51商用消息平台”，全面支持5G RCS消息。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻)归档仓库 &#8211; https://github.com/bigwhite/gopherdaily</p>
<p>我的联系方式：</p>
<ul>
<li>微博(暂不可用)：https://weibo.com/bigwhite20xx</li>
<li>微博2：https://weibo.com/u/6484441286</li>
<li>博客：tonybai.com</li>
<li>github: https://github.com/bigwhite</li>
</ul>
<p><img src="http://image.tonybai.com/img/tonybai/iamtonybai-wechat-qr.png" alt="" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2022, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2022/11/26/intro-of-google-go-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>又当爸爸了！</title>
		<link>https://tonybai.com/2020/07/29/my-second-daughter-was-born/</link>
		<comments>https://tonybai.com/2020/07/29/my-second-daughter-was-born/#comments</comments>
		<pubDate>Wed, 29 Jul 2020 06:01:34 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[生活簿]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Blogger]]></category>
		<category><![CDATA[七月]]></category>
		<category><![CDATA[二宝]]></category>
		<category><![CDATA[二胎]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[女儿]]></category>
		<category><![CDATA[家庭]]></category>
		<category><![CDATA[感悟]]></category>
		<category><![CDATA[摄影]]></category>
		<category><![CDATA[果果]]></category>
		<category><![CDATA[爸爸]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[老婆]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2932</guid>
		<description><![CDATA[2020年7月23日早6点46分，随着我家二宝(小名：七月)的呱呱坠地，我又当爸爸了! 图：二宝出生后的第一张照片 距离我家大宝(果果)的出生已经十年了。在这十年间，果果已经出落成一个聪明可爱、灵通剔透、漂亮温柔的大姑娘了，妥妥的是妈妈的小棉袄，爸爸的小情人:)，姥姥的小粘包，爷爷奶奶的乖孙女。 图：大宝果果是大姑娘了 但每每当果果提到其同班同学多数都有姐妹或兄弟陪伴上学、上才艺课的时候，我和我老婆的心里就会一动：究竟该不该给果果生一个亲弟弟/妹妹呢？ 2019下半年，我们决定为果果生个弟弟或妹妹。我们计划尝试半年，如果不行，我们年龄也大了，也许真的就不会再要了。结果上天十分眷顾我们，老婆在10月末怀上了。 大宝的愿望是我们要二宝的最直接和最主要的原因，我们也觉得两个宝宝在人生路上能相互陪伴总是更好的。其次，大宝出生时，我们还年轻，体验不充分，这次想再来一遍(也不知道哪来的这份勇气^_^)；再次，老人那边还有精力，还可以帮忙照顾孩子，我们在忙事业的同时，也不会有太多的后顾之忧；最后，两个宝宝也让家庭结构更合理。 写到这里，我也感觉上面的理由写得有些“冠冕堂皇”！想要就要，哪还需要这么多“借口”^_^。 生二宝唯一的担心就是已经是“高龄”的老婆。和十年前年轻的她相比，这次在孕期、生产和产后的风险都要高出许多。因此，在整个十月怀胎以及生产的过程中，我都更为紧张，但能做的也只有全程守护在老婆身边：制定营养计划、每天接送、全程陪检等。老婆本人倒是没有这方面担心，鉴于大宝生产前后的顺利，她坚信这次二宝也会同样顺利。 整个孕期也正如老婆坚信的那样，一切都很顺利，除了老婆患上了妊娠期糖尿病。老婆的一个性格特点就是认准一件事后，就能坚定不移地、自律地执行下去。由于妊娠期糖尿病对饮食的要求，老婆整整几个月都远离美味的“糖分”，保证了二宝在肚肚里的健康发育。同时，为了能够像一胎那样顺产，老婆坚持每天都要走上1w步，风雨无阻，天气不好，就在楼梯间里爬楼梯或在顶楼露台来回踱步。这份坚毅让老婆在38周的彩超检查中收获了期望的结论：医生看完彩超结果后给了我老婆十分肯定的诊断意见：你一定可以自己生！ 老婆，你真的很伟大！ 老婆在7月22日早晨见红了。按照一般经验，见红后24-48小时二宝就会出生了。7月23日凌晨3点老婆有了宫缩反应，虽然还不规律，但保险起见，我和老婆还是决定带上行李赶往医院。3:30到达医院急诊，产科的急诊大夫给开了一些检查和检验，结果出来后，就安排老婆去了(盛京医院滑翔园区)第五产科住院处办理住院。住院医生给老婆做了内检，说老婆今天很快就能生。早上5:00多，老婆进入待产室。随着规律性宫缩的到来，老婆十分痛苦。6点20分，医生决定让老妈进分娩室，我就在外面焦急等待。 老婆肚子里的二宝仿佛知道体谅她的妈妈，十分配合妈妈生产，让产程大大缩短，大大减少了老婆生产过程中承受的疼痛的时长。 在老婆进入分娩室后仅30分钟，站在分娩室外的我就听到了我家二宝第一声响亮的婴儿啼哭声。那时那刻，我和大宝出生时一样，流下了兴奋而又心疼老婆的眼泪。 母女平安！我的一颗高悬的心终于放下了，我再次当爸爸了！ 微信赞赏： &#169; 2020, bigwhite. 版权所有.]]></description>
			<content:encoded><![CDATA[<p>2020年7月23日早6点46分，随着我家<a href="https://daughter2.tonybai.com">二宝(小名：七月)</a>的呱呱坠地，<strong>我又当爸爸了</strong>!</p>
<p><img src="https://tonybai.com/wp-content/uploads/my-second-daughter/ally-was-born.jpeg" alt="img{512x368}" /><br />
<center>图：二宝出生后的第一张照片</center></p>
<p>距离我家<a href="https://tonybai.com/2010/05/11/now-i-am-a-father/">大宝(果果)的出生</a>已经十年了。在这十年间，<a href="https://daughter.tonybai.com">果果</a>已经出落成一个聪明可爱、灵通剔透、漂亮温柔的大姑娘了，妥妥的是<strong>妈妈的小棉袄，爸爸的小情人:)，姥姥的小粘包，爷爷奶奶的乖孙女</strong>。</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-10-years-old-1.jpg" alt="img{512x368}" /><br />
<center>图：大宝果果是大姑娘了</center></p>
<p>但每每当果果提到其同班同学多数都有姐妹或兄弟陪伴上学、上才艺课的时候，我和我老婆的心里就会一动：<strong>究竟该不该给果果生一个亲弟弟/妹妹呢？</strong> 2019下半年，我们决定为果果生个弟弟或妹妹。我们计划尝试半年，如果不行，我们年龄也大了，也许真的就不会再要了。结果<strong>上天十分眷顾我们，老婆在10月末怀上了</strong>。</p>
<p>大宝的愿望是我们要二宝的最直接和最主要的原因，我们也觉得两个宝宝在人生路上能相互陪伴总是更好的。其次，大宝出生时，我们还年轻，体验不充分，这次想再来一遍(<strong>也不知道哪来的这份勇气^_^</strong>)；再次，老人那边还有精力，还可以帮忙照顾孩子，我们在忙事业的同时，也不会有太多的后顾之忧；最后，两个宝宝也让家庭结构更合理。</p>
<blockquote>
<p>写到这里，我也感觉上面的理由写得有些“冠冕堂皇”！想要就要，哪还需要这么多“借口”^_^。</p>
</blockquote>
<p>生二宝唯一的担心就是已经是“高龄”的老婆。和十年前年轻的她相比，这次在孕期、生产和产后的风险都要高出许多。因此，在整个十月怀胎以及生产的过程中，我都更为紧张，但能做的也只有全程守护在老婆身边：制定营养计划、每天接送、全程陪检等。老婆本人倒是没有这方面担心，鉴于大宝生产前后的顺利，她坚信这次二宝也会同样顺利。</p>
<p>整个孕期也正如老婆坚信的那样，一切都很顺利，除了老婆患上了妊娠期糖尿病。老婆的一个性格特点就是认准一件事后，就能坚定不移地、自律地执行下去。由于妊娠期糖尿病对饮食的要求，老婆整整几个月都远离美味的“糖分”，保证了二宝在肚肚里的健康发育。同时，为了能够像一胎那样顺产，老婆坚持每天都要走上1w步，风雨无阻，天气不好，就在楼梯间里爬楼梯或在顶楼露台来回踱步。这份坚毅让老婆在38周的彩超检查中收获了期望的结论：医生看完彩超结果后给了我老婆十分肯定的诊断意见：<strong>你一定可以自己生</strong>！</p>
<p><strong>老婆，你真的很伟大！</strong></p>
<p>老婆在7月22日早晨见红了。按照一般经验，见红后24-48小时二宝就会出生了。7月23日凌晨3点老婆有了宫缩反应，虽然还不规律，但保险起见，我和老婆还是决定带上行李赶往医院。3:30到达医院急诊，产科的急诊大夫给开了一些检查和检验，结果出来后，就安排老婆去了(盛京医院滑翔园区)第五产科住院处办理住院。住院医生给老婆做了内检，说老婆今天很快就能生。早上5:00多，老婆进入待产室。随着规律性宫缩的到来，老婆十分痛苦。6点20分，医生决定让老妈进分娩室，我就在外面焦急等待。</p>
<p>老婆肚子里的二宝仿佛知道体谅她的妈妈，十分配合妈妈生产，让产程大大缩短，大大减少了老婆生产过程中承受的疼痛的时长。 在老婆进入分娩室后仅30分钟，站在分娩室外的我就听到了我家二宝第一声响亮的婴儿啼哭声。那时那刻，<strong>我和大宝出生时一样，流下了兴奋而又心疼老婆的眼泪</strong>。</p>
<p>母女平安！我的一颗高悬的心终于放下了，我再次当爸爸了！</p>
<hr />
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p style='text-align:left'>&copy; 2020, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2020/07/29/my-second-daughter-was-born/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>基于Markdown格式的电子书生成工具大比拼：gohugo、mdbook和peach</title>
		<link>https://tonybai.com/2020/06/27/gohugo-vs-mdbook-vs-peach/</link>
		<comments>https://tonybai.com/2020/06/27/gohugo-vs-mdbook-vs-peach/#comments</comments>
		<pubDate>Sat, 27 Jun 2020 11:35:53 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[ebook]]></category>
		<category><![CDATA[gitbook]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[gogs]]></category>
		<category><![CDATA[gohugo]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[hugo]]></category>
		<category><![CDATA[macos]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[mdbook]]></category>
		<category><![CDATA[peach]]></category>
		<category><![CDATA[ReadtheDocs]]></category>
		<category><![CDATA[Rust]]></category>
		<category><![CDATA[博客]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2926</guid>
		<description><![CDATA[基于Markdown格式文件写博客已经很多年了，一直使用的是Wordpress的markdown插件，由于各种遗留原因，一直没有转换到直接使用静态站点的方式。博客文章之间一般来说多是独立篇章，少有关联，即便是写一个系列文章，数量也不会太多。因此，用博客形式来组织书籍章节是不大合适的。“术业有专攻”，我们还得寻找专门用来制作电子书的工具或平台，并且要支持本地安装，支持基于Markdown格式的源数据文件。 专门用于制作电子书类文档的知名工具包括：gitbook和Read the Docs。不过前者的开源版本2018年末就不更新了，而Read the Docs则比较老，还需要多个工具配合。我个人倾向于单个二进制文件搞定一切。于是我找到了三个候选：gohugo、mdbook和peach，这三个候选部署时都只有一个二进制文件。gohugo和peach是Go语言实现的，而mdbook则是用Rust语言实现的。下面我们就来简单对比一下这三个基于Markdown格式的电子书制作工具。 1. mdbook mdbook是模仿gitbook样式的从markdown文件生成电子书的工具和静态站点服务，它仅聚焦于“电子书制作和站点服务”。如果不是类似gitbook风格的其他类静态内容服务，那么它并不适合。因此，该工具采用了惯例优先原则(convention over configuration)，使得使用时我们无需做太多的配置即可生成一个像模像样的电子书站点。 由于是rust实现的，mdbook本地部署时只需一个二进制文件，我们直接从它的github release上下载对应os平台的release文件（这里是macos的0.4.0版本）： wget -c https://github.com/rust-lang/mdBook/releases/download/v0.4.0/mdbook-v0.4.0-x86_64-apple-darwin.tar.gz 解压后，将mdbook所在路径添加到PATH环境变量中： $tar zxvf mdbook-v0.4.0-x86_64-apple-darwin.tar.gz x mdbook $ls mdbook* mdbook-v0.4.0-x86_64-apple-darwin.tar.gz $mdbook -help mdbook v0.4.0 Mathieu David &#60;mathieudavid@mathieudavid.org&#62; Creates a book from markdown files USAGE: mdbook [SUBCOMMAND] FLAGS: -h, --help Prints help information -V, --version Prints version information SUBCOMMANDS: build Builds [...]]]></description>
			<content:encoded><![CDATA[<p>基于<a href="http://en.wikipedia.org/wiki/Markdown">Markdown格式</a>文件<a href="https://tonybai.com/2015/09/19/write-blog-in-markdown/">写博客已经很多年了</a>，一直使用的是Wordpress的markdown插件，由于各种遗留原因，一直没有转换到直接使用静态站点的方式。博客文章之间一般来说多是独立篇章，少有关联，即便是写一个系列文章，数量也不会太多。因此，用博客形式来组织书籍章节是不大合适的。“术业有专攻”，我们还得寻找专门用来制作电子书的工具或平台，并且要支持本地安装，支持基于Markdown格式的源数据文件。</p>
<p>专门用于制作电子书类文档的知名工具包括：<a href="https://www.gitbook.com/">gitbook</a>和<a href="https://readthedocs.org/">Read the Docs</a>。不过前者的<a href="https://github.com/GitbookIO/gitbook">开源版本</a>2018年末就<a href="https://legacy.gitbook.com/">不更新了</a>，而<strong>Read the Docs</strong>则比较老，还需要多个工具配合。我个人倾向于单个二进制文件搞定一切。于是我找到了三个候选：<a href="https://gohugo.io/">gohugo</a>、<a href="https://github.com/rust-lang/mdBook">mdbook</a>和<a href="https://github.com/peachdocs/peach">peach</a>，这三个候选部署时都只有一个二进制文件。<a href="https://tonybai.com/2015/09/23/intro-of-gohugo/">gohugo</a>和peach是<a href="https://tonybai.com/tag/go">Go语言</a>实现的，而mdbook则是用<a href="https://www.rust-lang.org/">Rust语言</a>实现的。下面我们就来简单对比一下这三个基于Markdown格式的电子书制作工具。</p>
<h2>1. mdbook</h2>
<p>mdbook是模仿gitbook样式的从markdown文件生成电子书的工具和静态站点服务，它仅聚焦于“电子书制作和站点服务”。如果不是类似gitbook风格的其他类静态内容服务，那么它并不适合。因此，该工具采用了惯例优先原则(convention over configuration)，使得使用时我们无需做太多的配置即可生成一个<strong>像模像样</strong>的电子书站点。</p>
<p>由于是rust实现的，mdbook本地部署时只需一个二进制文件，我们直接从它的github release上下载对应os平台的release文件（这里是macos的0.4.0版本）：</p>
<pre><code>wget -c https://github.com/rust-lang/mdBook/releases/download/v0.4.0/mdbook-v0.4.0-x86_64-apple-darwin.tar.gz

</code></pre>
<p>解压后，将mdbook所在路径添加到<strong>PATH</strong>环境变量中：</p>
<pre><code>$tar zxvf mdbook-v0.4.0-x86_64-apple-darwin.tar.gz
x mdbook
$ls
mdbook*                        mdbook-v0.4.0-x86_64-apple-darwin.tar.gz

$mdbook -help
mdbook v0.4.0
Mathieu David &lt;mathieudavid@mathieudavid.org&gt;
Creates a book from markdown files

USAGE:
    mdbook [SUBCOMMAND]

FLAGS:
    -h, --help       Prints help information
    -V, --version    Prints version information

SUBCOMMANDS:
    build    Builds a book from its markdown files
    clean    Deletes a built book
    help     Prints this message or the help of the given subcommand(s)
    init     Creates the boilerplate structure and files for a new book
    serve    Serves a book at http://localhost:3000, and rebuilds it on changes
    test     Tests that a book's Rust code samples compile
    watch    Watches a book's files and rebuilds it on changes

For more information about a specific command, try `mdbook &lt;command&gt; --help`
The source code for mdBook is available at: https://github.com/rust-lang/mdBook

</code></pre>
<p>接下来，我们就使用<strong>mdbook init</strong>命令创建一个电子书工程：</p>
<pre><code>$mdbook init go-ml

Do you want a .gitignore to be created? (y/n)
y
What title would you like to give the book?
go machine learning
2020-06-27 15:58:03 [INFO] (mdbook::book::init): Creating a new book with stub content

All done, no errors...

</code></pre>
<p>我们看到<strong>mdbook init</strong>生成了一个目录，目录布局如下：</p>
<pre><code>➜  /Users/tonybai/MyEbook/mdbook git:(master) ✗ $tree
.
└── go-ml
    ├── book
    ├── book.toml
    └── src
        ├── SUMMARY.md
        └── chapter_1.md

3 directories, 3 files

</code></pre>
<p>接下来，我们直接运行<strong>mdbook serve</strong>即启动了一个服务，用于访问该电子书：</p>
<pre><code>➜  /Users/tonybai/MyEbook/mdbook git:(master) ✗ $mdbook serve go-ml
2020-06-27 16:06:56 [INFO] (mdbook::book): Book building has started
2020-06-27 16:06:56 [INFO] (mdbook::book): Running the html backend
2020-06-27 16:06:56 [INFO] (mdbook::cmd::serve): Serving on: http://localhost:3000
2020-06-27 16:06:56 [INFO] (warp::server): listening on http://[::1]:3000
2020-06-27 16:06:56 [INFO] (mdbook::cmd::watch): Listening for changes...

</code></pre>
<p>我们通过浏览器访问<strong>http://localhost:3000</strong>，可以看到如下页面：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gohugo-vs-mdbook-vs-peach/mdbook-1.png" alt="img{512x368}" /></p>
<p><center>图：mdbook生成的电子书首页</center></p>
<p>我们看到：我们没有做任何配置就生成了一个和gitbook样式差不多的电子书服务站点。该站点还支持选择页面显示模式（截图中使用的是默认的Light模式）、支持查询等。</p>
<p>如果我们要增加新章节、编排章节标题缩进，只需编辑电子书工程下面的<strong>src/SUMMARY.md</strong>：</p>
<pre><code>$cat SUMMARY.md
# Summary

- [Chapter 1](./chapter_1.md)
  - [Chapter 1.1](./chapter_1_1.md)
- [Chapter 2](./chapter_2.md)
</code></pre>
<p>这些对于多数人来说已经是足够了的，后续只需关注书籍内容即可，无需对mdbook生成的工程进行什么调整。mdbook会自动探测src目录下的文件变化并根据变化重新生成静态html文件。我们只需刷新页面即可看到最新变化。</p>
<h2>2. peach</h2>
<p><a href="https://peachdocs.org/docs">peach</a>是一款由Go语言实现的多语言、实时同步以及全文搜索功能的 Web 文档服务器。它由gogs的作者<a href="https://github.com/unknwon">无闻</a>打造，该作者的很多开源项目的文档也都是由peach生成和提供文档服务支撑的。<br />
我们可以直接使用<strong>go get</strong>安装peach：</p>
<pre><code>$export GONOSUMDB="github.com/russross/blackfriday"
$go get github.com/peachdocs/peach
go: github.com/peachdocs/peach upgrade =&gt; v0.9.8
$peach -v
Peach version 0.9.8.0810

</code></pre>
<p>接下来，我们用peach建立电子书工程：</p>
<pre><code>$peach new -target=go-ml.peach
➜  Creating 'go-ml.peach'...
➜  Creating 'templates'...
➜  Creating 'public'...
Do you want to use custom templates?[Y/n] n
✓  Done!

</code></pre>
<p>我们这里直接使用peach项目自身文档的自定义模板：</p>
<p>下载配置好的自定义模板：</p>
<pre><code>$ cd go-ml.peach

$ git clone https://github.com/peachdocs/peach.peach.git custom
Cloning into 'custom'...
remote: Enumerating objects: 62, done.
remote: Total 62 (delta 0), reused 0 (delta 0), pack-reused 62
Unpacking objects: 100% (62/62), done.
Checking connectivity... done.

</code></pre>
<p>启动web服务：</p>
<pre><code>$peach web

intro/
     |__ installation
     |__ getting_started
     |__ roadmap
howto/
     |__ documentation
     |__ webhook
     |__ templates
     |__ static_resources
     |__ navbar
     |__ pages
     |__ extension
     |__ protect_resources
     |__ upgrade
advanced/
        |__ config_cheat_sheet
faqs/
intro/
     |__ installation
     |__ getting_started
     |__ roadmap
howto/
     |__ documentation
     |__ webhook
     |__ templates
     |__ static_resources
     |__ navbar
     |__ pages
     |__ extension
     |__ protect_resources
     |__ upgrade
advanced/
        |__ config_cheat_sheet
faqs/
[Peach] 20-06-27 10:17:31 [ INFO] Peach 0.9.8.0810
[Peach] 20-06-27 10:17:31 [ INFO] Peach Server Listen on 127.0.0.1:5556

</code></pre>
<p>我们通过浏览器访问<strong>http://localhost:5556</strong>，可以看到如下页面：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gohugo-vs-mdbook-vs-peach/peach-1.png" alt="img{512x368}" /></p>
<p><center>图：peach生成的电子书目录页</center></p>
<p>不过，和mdbook不同，上面peach加载并渲染的文档并不在本地，我们在custom/app.ini中看到如下配置：</p>
<pre><code>[docs]
TYPE = remote
TARGET = https://github.com/peachdocs/docs.git
SECRET = peach

</code></pre>
<p>我们看到当前例子采用了<strong>remote</strong>模式，即使用Github上的仓库peachdocs/docs中的数据(markdown文件）作为源文件进行渲染，而这个仓库的结构如下：</p>
<pre><code>$tree -L 2 docs
docs
├── TOC.ini
├── en-US
│   ├── advanced
│   ├── faqs
│   ├── howto
│   └── intro
├── images
│   └── github_webhook.png
└── zh-CN
    ├── advanced
    ├── faqs
    ├── howto
    └── intro

11 directories, 2 files

</code></pre>
<p>TOC.ini文件描述了文档结构布局：</p>
<pre><code>$cat TOC.ini
-: intro
-: howto
-: advanced
-: faqs

[intro]
-: README
-: installation
-: getting_started
-: roadmap

[howto]
-: README
-: documentation
-: webhook
-: templates
-: static_resources
-: navbar
-: pages
-: extension
-: protect_resources
-: upgrade

[advanced]
-: README
-: config_cheat_sheet

[faqs]
-: README

</code></pre>
<p>我们看到，和mdbook相比，peach的门槛稍高一些，需要学习TOC.ini中的特殊配置语法，同时如果要改变peach的默认风格，还要学习peach使用的模板语法(Peach 使用 Go 语言 Pongo2 v3 版本 作为模板引擎，它使用的是 Django HTML 格式)。</p>
<h2>3. gohugo+git book theme</h2>
<p>gohugo是这几年最火的静态站点生成工具。和上面两个工具不同的是：它致力于成为一个通用的静态站点工具，与hexo等目标一致。结合gohugo与git book风格的theme也能实现电子书制作与站点服务。</p>
<p>经过多年发展，gohugo的安装十分方便：在macos上，我们既可以使用go get安装（gohugo支持module），也可以使用brew安装：</p>
<pre><code>$brew install hugo

==&gt; Downloading https://mirrors.ustc.edu.cn/homebrew-bottles/bottles/hugo-0.69.2.mojave.bottle.tar.gz

==&gt; Summary
/usr/local/Cellar/hugo/0.69.2: 42 files, 74.3MB
==&gt; `brew cleanup` has not been run in 30 days, running now...
Removing: /usr/local/Cellar/gettext/0.20.1... (1,899 files, 18.5MB)
... ...

$hugo version
Hugo Static Site Generator v0.69.2/extended darwin/amd64 BuildDate: unknown

</code></pre>
<p>通过<strong>hugo new site</strong>命令，我们来创建一个新的站点：</p>
<pre><code>$hugo new site go-machine-learning

Congratulations! Your new Hugo site is created in /Users/tonybai/MyEbook/gohugo/go-machine-learning.

Just a few more steps and you're ready to go:

1. Download a theme into the same-named folder.
   Choose a theme from https://themes.gohugo.io/ or
   create your own with the "hugo new theme &lt;THEMENAME&gt;" command.
2. Perhaps you want to add some content. You can add single files
   with "hugo new &lt;SECTIONNAME&gt;/&lt;FILENAME&gt;.&lt;FORMAT&gt;".
3. Start the built-in live server via "hugo server".

Visit https://gohugo.io/ for quickstart guide and full documentation.

</code></pre>
<p>下面是生成的站点的初始目录结构：</p>
<pre><code>$tree
.
└── go-machine-learning
    ├── archetypes
    │   └── default.md
    ├── config.toml
    ├── content
    ├── data
    ├── layouts
    ├── static
    └── themes

7 directories, 2 files

</code></pre>
<p>接下来我们来安装<a href="https://github.com/alex-shpak/hugo-book">gitbook theme</a>：</p>
<pre><code>$cd go-machine-learning

$git submodule add https://github.com/alex-shpak/hugo-book themes/book
Cloning into '/Users/tonybai/MyEbook/gohugo/go-machine-learning/hugo-book'...
remote: Enumerating objects: 3555, done.
Receiving objects:  18% (664/3555), 692.01 KiB | 4.00 KiB/s
... ...
remote: Total 3555 (delta 0), reused 0 (delta 0), pack-reused 3555
Receiving objects: 100% (3555/3555), 5.74 MiB | 5.00 KiB/s, done.
Resolving deltas: 100% (1809/1809), done.

</code></pre>
<p>我们可以修改一下顶层目录的config.toml，增加<strong>theme=”book”</strong>：</p>
<pre><code>baseURL = "http://example.org/"
languageCode = "zh-cn"
title = "Go机器学习"
theme = "book"

</code></pre>
<p>启动该站点：</p>
<pre><code>$hugo server --minify --theme book

                   | EN
-------------------+-----
  Pages            |  7
  Paginator pages  |  0
  Non-page files   |  0
  Static files     | 80
  Processed images |  0
  Aliases          |  0
  Sitemaps         |  1
  Cleaned          |  0 

Built in 26 ms
Watching for changes in /Users/tonybai/MyEbook/gohugo/go-machine-learning/{archetypes,content,data,layouts,static,themes}
Watching for config changes in /Users/tonybai/MyEbook/gohugo/go-machine-learning/config.toml
Environment: "development"
Serving pages from memory
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop

</code></pre>
<p>这时由于content目录为空，因此通过浏览器访问: localhost:1313后只能看到只有一个标题的空白页面。</p>
<p>我们将https://github.com/alex-shpak/hugo-book themes/book下面的样例站点的content拷贝到我们的站点中：</p>
<pre><code> $cp -R themes/book/exampleSite/content .
 $ll content
total 8
drwxr-xr-x   6 tonybai  staff   192  6 27 16:36 ./
drwxr-xr-x  12 tonybai  staff   384  6 27 16:35 ../
-rw-r--r--   1 tonybai  staff  1165  6 27 16:36 _index.md
drwxr-xr-x   4 tonybai  staff   128  6 27 16:36 docs/
drwxr-xr-x   3 tonybai  staff    96  6 27 16:36 menu/
drwxr-xr-x   7 tonybai  staff   224  6 27 16:36 posts/

</code></pre>
<p>再次启动hugo server后，我们通过浏览器浏览，可以看到下面页面：</p>
<p><img src="https://tonybai.com/wp-content/uploads/gohugo-vs-mdbook-vs-peach/gohugo-1.png" alt="img{512x368}" /></p>
<p><center>图：gohugo生成的电子书目录页</center></p>
<p>我们看到这个页面分为三栏，最左侧是站点目录栏，中间是章节内容，右侧显示的是内容中的标题结构。电子书源文件分布在content目录下，该目录的结构如下：</p>
<pre><code>$tree -L 2 content
content
├── _index.md
├── docs
│   ├── example
│   └── shortcodes
├── menu
│   └── index.md
└── posts
    ├── _index.md
    ├── chapter_1.md
    ├── creating-a-new-theme.md
    ├── goisforlovers.md
    ├── hugoisforlovers.md
    └── migrate-from-jekyll.md

5 directories, 8 files

</code></pre>
<ul>
<li>
<p>&#95;index.md是首页布局</p>
</li>
<li>
<p>menu/index.md是左侧栏的布局</p>
</li>
</ul>
<p>其他均为文章内容源文件。如果我们要调整首页布局或左侧栏的书籍结构，我们只需调整上述两个文件即可。</p>
<h2>4. 小结</h2>
<p>我们粗略、快速对mdbook、peach和gohugo工具做了比较，三者部署时都是单二进制文件。</p>
<p>我们的目标是利用工具生成电子书，仅从达到这个目的难易度来看：</p>
<ul>
<li>
<p>mdbook是“门槛”最低的，几乎无需配置，就能搭建出一个像模像样的类似gitbook的图书站点；</p>
</li>
<li>
<p>peach门槛较高一些，要配置的东西多一些；</p>
</li>
<li>
<p>gohugo门槛适中，但却最为灵活和强大。如果对gohugo的模板语法十分熟悉，可以定义出一套满足自己风格的电子书浏览页面风格。</p>
</li>
</ul>
<hr />
<p>我的网课“<a href="https://coding.imooc.com/class/284.html">Kubernetes实战：高可用集群搭建、配置、运维与应用</a>”在慕课网上线了，感谢小伙伴们学习支持！</p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/<br />
smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。</p>
<p>2020年4月8日，中国三大电信运营商联合发布《5G消息白皮书》，51短信平台也会全新升级到“51商用消息平台”，全面支持5G RCS消息。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻)归档仓库 &#8211; https://github.com/bigwhite/gopherdaily</p>
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2020, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2020/06/27/gohugo-vs-mdbook-vs-peach/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>果果十周岁了！</title>
		<link>https://tonybai.com/2020/05/03/guoguo-ten-years-old/</link>
		<comments>https://tonybai.com/2020/05/03/guoguo-ten-years-old/#comments</comments>
		<pubDate>Sun, 03 May 2020 05:24:50 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[生活簿]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Blogger]]></category>
		<category><![CDATA[七月]]></category>
		<category><![CDATA[二宝]]></category>
		<category><![CDATA[二胎]]></category>
		<category><![CDATA[十岁]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[女儿]]></category>
		<category><![CDATA[家庭]]></category>
		<category><![CDATA[感悟]]></category>
		<category><![CDATA[摄影]]></category>
		<category><![CDATA[果果]]></category>
		<category><![CDATA[爸爸]]></category>
		<category><![CDATA[生活]]></category>
		<category><![CDATA[老婆]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2937</guid>
		<description><![CDATA[好久没有在我的博客上写关于果果的事情了，因为很多关于果果成长的经历都记录在她自己的博客中了。但今天是她十周岁的生日，是个值得纪念的日子。闺女成长的十年，也是我学习为人父的十年。作为父亲，我发自内心地想说点啥，是回顾，也是感受，亦有些寄语^_^。 图：果果成长的十年 出生 老婆在2009年7月怀上了果果。那时我们刚刚新婚不久，二人世界还没过够^&#95;^，小家伙的突然到来还让我们有些“手足无措”。为此，我们还认真地讨论了两天，最终老婆拍板：我要生下这个孩子，于是果果保住了^&#95;^。如今，每当果果提及此事，都会“发狠”地盯上我几眼，我也只能呵呵呵呵地应对^_^。 老婆怀胎中段，我一直在福建出差，虽然有岳母陪在老婆身边，但年底那两个月，老婆心情十分差。直到那一年大年三十的下午2点，我才在桃仙机场下的飞机，匆匆赶回家。大街上连车的打不到，多亏还有公交系统。进入家门，心里满满的都是对老婆的愧疚。记忆中老婆似乎并没有说啥，只说了一句“吃饭吧”，我顿感心里热乎乎的。 果果似乎很享受在妈妈子宫中待着，预产期都过了几天了，她还没有反应，直到2010年5月3日凌晨1点多，规律性的宫缩“来袭”。我们匆忙赶到医院，早上6点半多，老婆进入产室，9点多，我在产室外听到了果果呱呱坠地后的第一声啼哭。 图：刚出生的果果 果果出生后，恰逢徐峥的作品《人在囧途》上映，影片中徐峥扮演角色的孩子叫果果，我们觉得这个小名不错，于是便给我们宝宝起名为果果。 第一次照顾这么小的孩子也着实让我们这些大人手忙脚乱一段时间。出月子后，生活逐渐恢复平稳。果果每天除了吃奶就是睡觉，也算是比较省心了。稍大一些后，果果似乎并不太愿意睡觉了，每次喂完奶都得放到小车上在厅里推过来推过去哄她睡觉，后来果果姥姥买的一个能发出大恐龙吼声的玩具也加入到促进果果睡眠的行列中^&#95;^。 第一次走路(0岁) 果果一直母乳喂养，身体也很壮实。抬头、翻身、学会爬行和其他孩子相比都略有提前。最让我印象深刻是她第一次学会独立行走。记得那是2010年农历春节前，我们家当时的供暖非常好，室温在28度以上。果果在家只穿一套内衣裤，因此行动和玩耍起来非常方便。之前果果就可以扶着床沿踱步了并且她似乎也很喜欢站起来的感觉。那天她自己在卧室的地板上玩耍，我在门口偷偷观察她。她玩了一会儿就开始扶着床站起来，看我站在门口，她居然放开了扶着床沿的双手，向我摇摇晃晃地走了过来。从床边到卧室门口大约有不到2米的距离，我也兴奋地张开双臂，引导她向我走来。她边走边兴奋地笑，似乎也在惊讶于自己能独立行走了。在她扑到我的怀中的那一刻，我才意识到我见证了果果人生第一次独立行走，老婆听到这个消息也是兴奋不已。自从果果学会了走路，此后便一发不可收拾^&#95;^。 打针不哭(1岁) 可能是因为母乳喂养，果果在一岁的这一年中没有患过任何感冒发烧的病症。但当母体带给她的免疫力逐渐失去作用后，果果便和其他小朋友一样，会得感冒，也会发烧。记得果果第一次感冒(刚过一岁生日没多久)就烧的特别厉害。由于我们也是第一次遇到这种情况，特别担心，于是就带她去医院检查。虽然我们期望医生开立口服药，但医生最终还是开了点滴。在护士站门口，果果看到其他孩子扎针时都哇哇的哭，心里也胆怯了。果不其然，当针头穿透她的皮肤进入血管的那一刻，果果也像其他孩子一样，哇哇大哭起来。 有了这次“痛苦”的扎针经历后，我们也对她进行了心理疏导，教她要学会坚强，从她的眼神看得出来，她似乎听懂了。在2011年的秋冬换季，果果又患感冒发烧。同样去了医院，同样开了点滴，但在护士站扎针的时候，果果居然很坚强的忍住了，没有哇哇的哭泣，这让看惯了孩子痛哭的护士也是惊奇不已。看着泪水在眼圈里打转但没有哭出来的果果，我们心里更是心疼她了。 送去幼儿园学说话(2岁) 果果在11个月的时候就会喊妈妈了，但直到2岁半她能吐出的字依然只有“妈妈”，偶尔也有“爸爸”。现在看来，果果说话晚是因为我们给她的语言刺激太少了。果果不愿意睡觉，一旦睡着了，老人生怕声音大吵醒她，于是就命令我们不许出声。久而久之，果果在潜意思中得到的声音刺激、语言刺激照比其他小朋友就要少很多。为此，我们还带着果果去看了生长发育门诊、做过筛查，结果都显示果果没有任何生理性的疾病。 我们需要找到一个让果果接受更多语言刺激的方法，最终我们决定在果果2岁零5个月的时候送她去幼儿园“学说话”。做过家长的都知道，送孩子去幼儿园的过程是“痛苦”的，孩子哭闹，家长心疼，但这个过程是必须要经历的。付出了就有收获。在果果上幼儿园后的一个月，果果的“话匣子”就彻底打开了^&#95;^。 更像女娃了，但怕大海(3岁) 出生时，果果头发稀少，为了让果果长出更好的头发，我们每隔一段时间就把她的头发剃的很短(几近光头)。在2岁之内，果果更像一个“男娃”。直到3岁以后，我们开始给她留头发了。小家伙似乎也知道留头发后自己更好看了，姥姥每次给她梳头扎辫她都很喜欢。留着还有些短的头发让她更像女娃了： 图：更像女娃的果果 下半年，我们把果果转到了更大的幼儿园，并且果果每天上幼儿园都不再费劲了。她在幼儿园也学到了许多知识、技能和礼节。 3岁的果果的身体显得比同龄的女宝高大一圈，我们也开始带着她到处出行游玩。劳动节黄金周我们第一次带孩子去海边。那天的风浪比较大，浪花拍击礁石的声音震耳欲聋，果果显得很害怕。我们抱着她向海边靠近，但她却一直在挣扎并大喊：“离开、离开、走、走”。当我自己独自向大海靠近时，她也大喊：“爸爸，你回来，你回来”。见此情景，我们都哈哈大笑起来。 后来我们去了一处比较海浪比较舒缓的地带，没有了海浪拍打的巨大轰隆声，果果镇定了许多。也开始站在沙滩上和其他小朋友一起挖起沙子了。 独立爬山(4岁) 4岁的果果不仅个头高，而且壮实了。我们在权衡了之后，决定在假期带她去爬山，并且我已经做好了背她上山的准备。那次我们爬的是千山。千山在整个省内的爬山困难指数排行榜上也是名列前茅的。不过小家伙似乎很喜欢爬山，在登山栈道上显得十分兴奋，我们也给她做心里建设，希望她自己爬到顶峰。虽然在中段她也曾打过退堂鼓，但最终小家伙还是凭借自己的双腿和毅力爬上了山顶，我和老婆也都是非常惊讶。下山过程中，小家伙也是一路欢喜，并没用我们费心。只是由于累了，在回程的车上，小家伙呼呼的睡了一道。 正因为此次爬山的经历，果果爱上了爬山。后续选择旅游景点，她总是先挑那些有山可爬的地方，比如：2019年的陕西的华山、骊山等。 和妈妈一起去普吉岛(5岁) 孩子小的时候，出行很麻烦，而且孩子能收获的东西有限。5岁是一个很好的节点，她基本能自立了，而且感知和吸收外界信息的能力已经很强了。 5岁这一年是果果第一次和妈妈出国旅游，此次出行的目的是泰国普吉岛，和她们一起去的还有老婆的同事，这些同事也能帮助老婆照顾照顾果果，顺道还能锻炼一下果果的交际能力。这也是果果第一次乘飞机出行，在机场她十分兴奋。她们的航班在首尔中转，从首尔飞到普吉需要5-6个小时，这下让果果过了一把飞行瘾，她尤其喜欢飞机起降过程中的那种感觉，以至于以后每次出行，她都嚷嚷着要买多次经停或中转的航班^&#95;^。 更难得可贵的是，这次的旅游经历深深印在果果的记忆中，至今每当翻看那时的照片时，她还能头头是道的给我们讲当时发生的故事。有些事情，我老婆都已经记不得了。 上小学了(6岁) 转眼间，果果来到了6周岁，已经到了上学的年龄了。9月份，果果正式成为一名珠江街第五小学一年级的“小豆包”。和第一次上幼儿园不同，这次果果适应的很快，也没有哭鼻子的情况。反倒是回来和我们说她班级有小朋友一直哭，她还很疑惑这些小朋友为什么要哭^&#95;^。 上学后，更多的教育责任“甩”给了班主任老师，我们平时更多是帮忙批改批改作业，督促读读书，带着上上才艺班。果果的古筝是各门才艺课中学的最好的，果果也有了那么一些古典的气质： 图：有一丝古典气质的果果 这一年我还给果果开了博客。有些东西，光靠脑子是记不住的，写下来，留给多年后的自己和孩子慢慢回味。在果果能自己维护这个博客之前，我就先替她维护了。 叛逆与独立(7~9岁) 进入到7岁以后，果果受到的教育多了，读的书多了，渐渐了有了自己的主见和小脾气，再也不是那个将父母话“奉为圭臬”的小女娃了。如果就某事“辩论”，她姥姥已经完全不是对手了。也只有我和老婆偶尔还能“恩威并举”的降住她:(。 果果喜欢读故事书。她最喜欢读郑渊洁的童话，按照她的说法，市面上郑渊洁的书她基本都读完了，有些书，她已经读过不止一遍了。受郑渊洁风格的影响，她喜欢写幻想类的作文，喜欢天马行空，因此在细节描写上就差了一些。 她还喜欢“米小圈上学记”，每天晚上都是在天猫精灵播放的米小圈上学记中入睡的。 她喜欢宜家买来的老虎和小狗玩偶，一个起名为花果，一个起名为木果，每天一左一右的陪她入睡。 天猫精灵是她每天不可或缺的“伙伴”。早上听新闻早报，天气预报；晚上听故事，听历史，听音乐；偶尔还和天猫精灵玩玩互动猜谜游戏。真不愧为互联网和智能时代的原著民。 8岁的果果，其古筝考级已经通过了10级，这还是在她不是很勤奋练琴的情况下取得的。 这个阶段的果果也十分贪玩，喜欢去游乐场，玩老爸都不敢玩的惊险刺激的项目(只能由她妈妈陪着)。 9岁时，她偶尔和妈妈看了一集“家有儿女”，从那时起就“沉迷”于该剧：只要拿起iPad就必然打开“家有儿女”视频。她看电视剧和她看书的特点一样，如果某一集是她喜欢的，她会反复看上好多遍，丝毫没有不耐烦的迹象。有些集的台词她都能背下来，并粘着我和我老婆要给我们讲。还别说，讲的还头头是道的^&#95;^。 亭亭玉立的大姑娘(10岁) 由于新冠疫情的影响，果果的10岁生日在家里过的，我们也没法带她出去“玩耍”一番。10岁的她已经是一个亭亭玉立的大姑娘了。她的个头快赶上她妈妈了，大长腿，身材是“青出于蓝而胜于蓝”。 图：十岁的果果 图：亭亭玉立的果果 这次10周岁的生日除了生日蛋糕，还有一个更为特殊的礼物，那就是妈妈肚里的二宝，这也是果果一直想要的弟弟/妹妹。自从知道妈妈怀了二宝之后，果果变得更加懂事了。每天晚上对着妈妈的肚子给二宝讲故事，晚上睡觉前也会对着妈妈肚子猛“亲”几口^&#95;^。 为了留下美好回忆，我们还特地在果果十周岁生日的时候在影楼留下了一家四口的合影： 图：十岁果果生日时一家四口合影 小结 果果成长的十年给我的最大感受就是：快！一晃间，果果都10岁了，二宝也即将出生。我和老婆也即将步入中年。这里做的这个阶段性的回顾，以期若干年后当记忆模糊时还能通过这篇文章回忆起当年果果小时候的点点滴滴。 这里也希望果果在未来的人生道路中能继续一帆风顺，身体健健康康，每天快快乐乐。 希望果果和即将出生的二宝一起姐妹情深，相濡以沫，共同走好人生之路。 [...]]]></description>
			<content:encoded><![CDATA[<p>好久没有在我的博客上写关于<a href="https://daughter.tonybai.com">果果</a>的事情了，因为很多关于果果成长的经历都记录在<a href="https://daughter.tonybai.com">她自己的博客</a>中了。但今天是她<a href="https://daughter.tonybai.com/2020/05/03/i-am-10-years-old/">十周岁的生日</a>，是个值得纪念的日子。闺女成长的十年，也是我学习为人父的十年。作为父亲，我发自内心地想说点啥，是回顾，也是感受，亦有些寄语^_^。</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-10-years-old-2.jpg" alt="img{512x368}" /><br />
<center>图：果果成长的十年</center></p>
<h3>出生</h3>
<p>老婆在2009年7月怀上了果果。那时我们刚刚新婚不久，二人世界还没过够^&#95;^，小家伙的突然到来还让我们有些“手足无措”。为此，我们还认真地讨论了两天，最终老婆拍板：<strong>我要生下这个孩子</strong>，于是果果保住了^&#95;^。如今，每当果果提及此事，都会“发狠”地盯上我几眼，我也只能呵呵呵呵地应对^_^。</p>
<p>老婆怀胎中段，我一直在福建出差，虽然有岳母陪在老婆身边，但年底那两个月，老婆心情十分差。直到那一年大年三十的下午2点，我才在桃仙机场下的飞机，匆匆赶回家。大街上连车的打不到，多亏还有公交系统。进入家门，心里满满的都是对老婆的愧疚。记忆中老婆似乎并没有说啥，只说了一句“吃饭吧”，我顿感心里热乎乎的。</p>
<p>果果似乎很享受在妈妈子宫中待着，预产期都过了几天了，她还没有反应，直到2010年5月3日凌晨1点多，规律性的宫缩“来袭”。我们匆忙赶到医院，早上6点半多，老婆进入产室，9点多，我在产室外听到了果果呱呱坠地后的第一声啼哭。</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-was-born.JPG" alt="img{512x368}" /><br />
<center>图：刚出生的果果</center></p>
<p>果果出生后，恰逢徐峥的作品《人在囧途》上映，影片中徐峥扮演角色的孩子叫果果，我们觉得这个小名不错，于是便给我们宝宝起名为<strong>果果</strong>。</p>
<p>第一次照顾这么小的孩子也着实让我们这些大人手忙脚乱一段时间。出月子后，生活逐渐恢复平稳。果果每天除了吃奶就是睡觉，也算是比较省心了。稍大一些后，果果似乎并不太愿意睡觉了，每次喂完奶都得放到小车上在厅里推过来推过去哄她睡觉，后来果果姥姥买的一个能发出大恐龙吼声的玩具也加入到促进果果睡眠的行列中^&#95;^。</p>
<h3>第一次走路(0岁)</h3>
<p>果果一直母乳喂养，身体也很壮实。抬头、翻身、学会爬行和其他孩子相比都略有提前。最让我印象深刻是她第一次学会独立行走。记得那是2010年农历春节前，我们家当时的供暖非常好，室温在28度以上。果果在家只穿一套内衣裤，因此行动和玩耍起来非常方便。之前果果就可以扶着床沿踱步了并且她似乎也很喜欢站起来的感觉。那天她自己在卧室的地板上玩耍，我在门口偷偷观察她。她玩了一会儿就开始扶着床站起来，看我站在门口，她居然放开了扶着床沿的双手，向我摇摇晃晃地走了过来。从床边到卧室门口大约有不到2米的距离，我也兴奋地张开双臂，引导她向我走来。她边走边兴奋地笑，似乎也在惊讶于自己能独立行走了。在她扑到我的怀中的那一刻，我才意识到我见证了果果人生第一次独立行走，老婆听到这个消息也是兴奋不已。自从果果学会了走路，此后便一发不可收拾^&#95;^。</p>
<h3>打针不哭(1岁)</h3>
<p>可能是因为母乳喂养，果果在一岁的这一年中没有患过任何感冒发烧的病症。但当母体带给她的免疫力逐渐失去作用后，果果便和其他小朋友一样，会得感冒，也会发烧。记得果果第一次感冒(刚过一岁生日没多久)就烧的特别厉害。由于我们也是第一次遇到这种情况，特别担心，于是就带她去医院检查。虽然我们期望医生开立口服药，但医生最终还是开了点滴。在护士站门口，果果看到其他孩子扎针时都哇哇的哭，心里也胆怯了。果不其然，当针头穿透她的皮肤进入血管的那一刻，果果也像其他孩子一样，哇哇大哭起来。</p>
<p>有了这次“痛苦”的扎针经历后，我们也对她进行了心理疏导，教她要学会坚强，从她的眼神看得出来，她似乎听懂了。在2011年的秋冬换季，果果又患感冒发烧。同样去了医院，同样开了点滴，但在护士站扎针的时候，果果居然很坚强的忍住了，没有哇哇的哭泣，这让看惯了孩子痛哭的护士也是惊奇不已。看着泪水在眼圈里打转但没有哭出来的果果，我们心里更是心疼她了。</p>
<h3>送去幼儿园学说话(2岁)</h3>
<p>果果在11个月的时候就会喊妈妈了，但直到2岁半她能吐出的字依然只有“妈妈”，偶尔也有“爸爸”。现在看来，果果说话晚是因为我们给她的语言刺激太少了。果果不愿意睡觉，一旦睡着了，老人生怕声音大吵醒她，于是就命令我们不许出声。久而久之，果果在潜意思中得到的声音刺激、语言刺激照比其他小朋友就要少很多。为此，我们还带着果果去看了生长发育门诊、做过筛查，结果都显示果果没有任何生理性的疾病。</p>
<p>我们需要找到一个让果果接受更多语言刺激的方法，最终我们决定在果果2岁零5个月的时候送她去幼儿园“学说话”。做过家长的都知道，送孩子去幼儿园的过程是“痛苦”的，孩子哭闹，家长心疼，但这个过程是必须要经历的。付出了就有收获。在果果上幼儿园后的一个月，果果的“话匣子”就彻底打开了^&#95;^。</p>
<h3>更像女娃了，但怕大海(3岁)</h3>
<p>出生时，果果头发稀少，为了让果果长出更好的头发，我们每隔一段时间就把她的头发剃的很短(几近光头)。在2岁之内，果果更像一个“男娃”。直到3岁以后，我们开始给她留头发了。小家伙似乎也知道留头发后自己更好看了，姥姥每次给她梳头扎辫她都很喜欢。留着还有些短的头发让她更像女娃了：</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-3-years-old.jpg" alt="img{512x368}" /><br />
<center>图：更像女娃的果果</center></p>
<p>下半年，我们把果果转到了更大的幼儿园，并且果果每天上幼儿园都不再费劲了。她在幼儿园也学到了许多知识、技能和礼节。</p>
<p>3岁的果果的身体显得比同龄的女宝高大一圈，我们也开始带着她到处出行游玩。劳动节黄金周我们第一次带孩子去海边。那天的风浪比较大，浪花拍击礁石的声音震耳欲聋，果果显得很害怕。我们抱着她向海边靠近，但她却一直在挣扎并大喊：“离开、离开、走、走”。当我自己独自向大海靠近时，她也大喊：“爸爸，你回来，你回来”。见此情景，我们都哈哈大笑起来。</p>
<p>后来我们去了一处比较海浪比较舒缓的地带，没有了海浪拍打的巨大轰隆声，果果镇定了许多。也开始站在沙滩上和其他小朋友一起挖起沙子了。</p>
<h3>独立爬山(4岁)</h3>
<p>4岁的果果不仅个头高，而且壮实了。我们在权衡了之后，决定在假期带她去爬山，并且我已经做好了背她上山的准备。那次我们爬的是千山。千山在整个省内的爬山困难指数排行榜上也是名列前茅的。不过小家伙似乎很喜欢爬山，在登山栈道上显得十分兴奋，我们也给她做心里建设，希望她自己爬到顶峰。虽然在中段她也曾打过退堂鼓，但最终小家伙还是凭借自己的双腿和毅力爬上了山顶，我和老婆也都是非常惊讶。下山过程中，小家伙也是一路欢喜，并没用我们费心。只是由于累了，在回程的车上，小家伙呼呼的睡了一道。</p>
<p>正因为此次爬山的经历，果果爱上了爬山。后续选择旅游景点，她总是先挑那些有山可爬的地方，比如：2019年的<a href="https://daughter.tonybai.com/2019/08/17/xian-chongqing-tour-2nd-day-2019/">陕西的华山</a>、<a href="https://daughter.tonybai.com/2019/08/17/xian-chongqing-tour-2nd-day-2019/">骊山</a>等。</p>
<h3>和妈妈一起去普吉岛(5岁)</h3>
<p>孩子小的时候，出行很麻烦，而且孩子能收获的东西有限。5岁是一个很好的节点，她基本能自立了，而且感知和吸收外界信息的能力已经很强了。</p>
<p>5岁这一年是果果第一次和妈妈出国旅游，此次出行的目的是泰国普吉岛，和她们一起去的还有老婆的同事，这些同事也能帮助老婆照顾照顾果果，顺道还能锻炼一下果果的交际能力。这也是果果第一次乘飞机出行，在机场她十分兴奋。她们的航班在首尔中转，从首尔飞到普吉需要5-6个小时，这下让果果过了一把飞行瘾，她尤其喜欢飞机起降过程中的那种感觉，以至于以后每次出行，她都嚷嚷着要买多次经停或中转的航班^&#95;^。</p>
<p>更难得可贵的是，这次的旅游经历深深印在果果的记忆中，至今每当翻看那时的照片时，她还能头头是道的给我们讲当时发生的故事。有些事情，我老婆都已经记不得了。</p>
<h3>上小学了(6岁)</h3>
<p>转眼间，果果来到了6周岁，已经到了上学的年龄了。9月份，果果正式成为一名珠江街第五小学一年级的“小豆包”。和第一次上幼儿园不同，这次果果适应的很快，也没有哭鼻子的情况。反倒是回来和我们说她班级有小朋友一直哭，她还很疑惑这些小朋友为什么要哭^&#95;^。</p>
<p>上学后，更多的教育责任“甩”给了班主任老师，我们平时更多是帮忙批改批改作业，督促读读书，带着上上才艺班。果果的古筝是各门才艺课中学的最好的，果果也有了那么一些古典的气质：</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-gavatar.jpg" alt="img{512x368}" /><br />
<center>图：有一丝古典气质的果果</center></p>
<p>这一年我还给果果开了<a href="https://daughter.tonybai.com">博客</a>。有些东西，光靠脑子是记不住的，写下来，留给多年后的自己和孩子慢慢回味。在果果能自己维护这个博客之前，我就先替她维护了。</p>
<h3>叛逆与独立(7~9岁)</h3>
<p>进入到7岁以后，果果受到的教育多了，读的书多了，渐渐了有了自己的主见和小脾气，再也不是那个将父母话“奉为圭臬”的小女娃了。如果就某事“辩论”，她姥姥已经完全不是对手了。也只有我和老婆偶尔还能“恩威并举”的降住她:(。</p>
<p>果果喜欢读故事书。她最喜欢读郑渊洁的童话，按照她的说法，市面上郑渊洁的书她基本都读完了，有些书，她已经读过不止一遍了。受郑渊洁风格的影响，她喜欢写幻想类的作文，喜欢天马行空，因此在细节描写上就差了一些。</p>
<p>她还喜欢“米小圈上学记”，每天晚上都是在天猫精灵播放的米小圈上学记中入睡的。</p>
<p>她喜欢宜家买来的老虎和小狗玩偶，一个起名为花果，一个起名为木果，每天一左一右的陪她入睡。</p>
<p>天猫精灵是她每天不可或缺的“伙伴”。早上听新闻早报，天气预报；晚上听故事，听历史，听音乐；偶尔还和天猫精灵玩玩互动猜谜游戏。真不愧为互联网和智能时代的原著民。</p>
<p>8岁的果果，其古筝考级已经通过了10级，这还是在她不是很勤奋练琴的情况下取得的。</p>
<p>这个阶段的果果也十分贪玩，喜欢去游乐场，玩老爸都不敢玩的惊险刺激的项目(只能由她妈妈陪着)。</p>
<p>9岁时，她偶尔和妈妈看了一集“家有儿女”，从那时起就“沉迷”于该剧：只要拿起iPad就必然打开“家有儿女”视频。她看电视剧和她看书的特点一样，如果某一集是她喜欢的，她会反复看上好多遍，丝毫没有不耐烦的迹象。有些集的台词她都能背下来，并粘着我和我老婆要给我们讲。还别说，讲的还头头是道的^&#95;^。</p>
<h3>亭亭玉立的大姑娘(10岁)</h3>
<p>由于新冠疫情的影响，果果的10岁生日在家里过的，我们也没法带她出去“玩耍”一番。10岁的她已经是一个亭亭玉立的大姑娘了。她的个头快赶上她妈妈了，大长腿，身材是“青出于蓝而胜于蓝”。</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-10-years-old-1.jpg" alt="img{512x368}" /><br />
<center>图：十岁的果果</center></p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-10-years-old-4.jpg" alt="img{512x368}" /><br />
<center>图：亭亭玉立的果果</center></p>
<p>这次10周岁的生日除了生日蛋糕，还有一个更为特殊的礼物，那就是妈妈肚里的二宝，这也是果果一直想要的弟弟/妹妹。自从知道妈妈怀了二宝之后，果果变得更加懂事了。每天晚上对着妈妈的肚子给二宝讲故事，晚上睡觉前也会对着妈妈肚子猛“亲”几口^&#95;^。</p>
<p>为了留下美好回忆，我们还特地在果果十周岁生日的时候在影楼留下了一家四口的合影：</p>
<p><img src="https://tonybai.com/wp-content/uploads/guoguo-ten-years-old/guoguo-10-years-old-3.jpg" alt="img{512x368}" /><br />
<center>图：十岁果果生日时一家四口合影</center></p>
<h3>小结</h3>
<p>果果成长的十年给我的最大感受就是：<strong>快</strong>！一晃间，果果都10岁了，二宝也即将出生。我和老婆也即将步入中年。这里做的这个阶段性的回顾，以期若干年后当记忆模糊时还能通过这篇文章回忆起当年果果小时候的点点滴滴。</p>
<p>这里也希望果果在未来的人生道路中能继续一帆风顺，身体健健康康，每天快快乐乐。</p>
<p>希望果果和即将出生的二宝一起姐妹情深，相濡以沫，共同走好人生之路。</p>
<p>最后，<strong>人生在于经历，而不在于得失</strong>。</p>
<hr />
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p style='text-align:left'>&copy; 2020, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2020/05/03/guoguo-ten-years-old/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Go官方发布的go.dev给gopher们带来了什么</title>
		<link>https://tonybai.com/2019/11/14/what-the-godev-website-bring-to-gophers/</link>
		<comments>https://tonybai.com/2019/11/14/what-the-godev-website-bring-to-gophers/#comments</comments>
		<pubDate>Thu, 14 Nov 2019 02:44:42 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[cloud-native]]></category>
		<category><![CDATA[CNCF]]></category>
		<category><![CDATA[DevOps]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[go-nuts]]></category>
		<category><![CDATA[go-tour]]></category>
		<category><![CDATA[go.dev]]></category>
		<category><![CDATA[gobridge]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[GOPATH]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[GopherCon]]></category>
		<category><![CDATA[hello-world]]></category>
		<category><![CDATA[logrus]]></category>
		<category><![CDATA[Package]]></category>
		<category><![CDATA[SRE]]></category>
		<category><![CDATA[tgpl]]></category>
		<category><![CDATA[云原生]]></category>
		<category><![CDATA[包]]></category>
		<category><![CDATA[命令行]]></category>
		<category><![CDATA[地鼠]]></category>

		<guid isPermaLink="false">https://tonybai.com/?p=2824</guid>
		<description><![CDATA[众所周知，Go是一个诞生于Google内部的编程语言，它在2009年11月份开源，在开源后立即受到了来自全世界开发人员的关注与贡献。但初期的Go语言的发展依旧是由Go核心团队的若干leader决定的，这种类“民主集中制”的方法延续了若干年。直到Go核心团队逐渐意识到Go应该更多倾听社区的声音，并让更多的gopher参与到Go项目的开发和贡献中来，甚至影响和决定一些语言特定的演化。于是Go团队开始特意为Go社区发展招兵买马。像Steve Francia、Francesc Campoy（后已经从google离职加入Dgraph）等都是在这个阶段加入Go team的。 Go团队在很长一段时间里尤其重视与社区的互动，比如连续多年发起Go user调查、Gophercon大会后的Go team与社区的见面会和分组讨论、去GOPATH降低Go入门学习曲线、发布Go新品牌标识、添加Go module机制、改善官网等。 在今天Go官博发文：“Go.dev: a new hub for Go developers”，正式发布go.dev站点，该站点被Go核心团队寄望于成为全世界Gopher开发人员的中心。它将告诉gopher（无论新手还是老油条）：谁在使用Go、用Go做什么、怎么学习Go(Go的各种学习资源、受欢迎的Go package都有哪些以及这些package的详细信息）。 go.dev发布之后，golang.org官网将更加聚焦go开源项目本身的开发、语言演化以及Go版本发布。而go.dev将成为gopher日常使用go语言的中心，包括go学习、go方案、go应用案例等。在这里我们简单探索一下go.dev这个站点究竟给gopher们带来了什么(这仅仅是go.dev的最小功能发布，后续go.dev可能会演化出更多特性、并根据社区反馈更好满足gopher需求)。 一. 学习资源聚合 go.dev的一个重要功能就是帮助首次进入Go世界的开发人员学习Go。 在go.dev的”learn”栏目下，我们在第一屏就看到了Go新手入门的三个步骤：安装、”Hello World”、Go tour以及更为详尽文档的入口： 接下来，go.dev提供了这些年口碑较好、受到gopher欢迎的一些初级在线学习资源： 像gobyexample.com、gophercises.com都在推荐行列。 Go技术类书籍以及培训资源是gopher学习Go过程中不可缺少的： Go.dev在learn栏目下推荐了一些口碑不错的Go书籍，比如：Alan A. A. Donovan和Brian W. Kernighan合著的Go圣经：《The Go Programming Language》被在首位推荐。知名Go培训师William Kennedy的培训也被推荐给了大家。不过口碑不错的书籍《Go in action》我觉得也应该列入推荐行列。 在Learn栏目最后，是全世界各地近期有关Go的meetup活动的schedule，Gopher可以得到最及时的meetup信息，并选择参加。 二. 成熟解决方案参考 go.dev开辟的”solution”栏目旨在提升go的开发过程。栏目从“云原生和网络服务开发”、“命令行程序开发”、“web开发”以及Devops/Site Reliability四个方面提供聚合化的资料。以“云原生和网络服务开发”为例，Go.dev提供了这方面的典型项目和用户、使用方法、关键方案（一些书籍、成熟框架、客户端库以及其他资源）。 go.dev solution栏目还提供了一些Go的典型客户以及这些客户使用Go的典型案例： 三、Package信息聚合中心 在go.dev的“explore”栏目下，我们看到的是Go package的信息中心： 就如上图所示，这里提供了受欢迎的package和特色package的推荐列表，以及package信息的搜索功能。 以logrus为例： 在logrus包的主页，我们看到了有关logrus的各种信息，项目repo地址、最新版本号、module名字、开源许可证信息、文档（应该是集成了godoc返回的结果）、它的依赖、以及以它为依赖的项目(见下图)： 四. 小结 go.dev目前处于最小产品状态(mvp)，从目前已经提供的栏目来看，go.dev能为gopher提供的帮助已经很全面了。后续go.dev站点的运营好坏（比如：信息更新是否及时等）将决定go.dev是否能达到其预期的期望。 go.dev目前似乎还缺少论坛功能。不过已有的golang-nuts、gobridge已经承担了这个角色，但如果能有一个官方论坛（一站式）就再好不过了。 [...]]]></description>
			<content:encoded><![CDATA[<p>众所周知，<a href="https://tonybai.com/2017/09/24/go-ten-years-and-climbing/">Go是一个诞生于Google内部的编程语言</a>，它在<a href="https://tonybai.com/2019/11/09/go-opensource-10-years/">2009年11月份开源</a>，在开源后立即受到了来自全世界开发人员的关注与贡献。但初期的Go语言的发展依旧是由Go核心团队的若干leader决定的，这种类“民主集中制”的方法延续了若干年。直到Go核心团队逐渐意识到Go应该更多倾听社区的声音，并让更多的gopher参与到Go项目的开发和贡献中来，甚至影响和决定一些语言特定的演化。于是Go团队开始特意为Go社区发展<strong>招兵买马</strong>。像<a href="https://spf13.com/">Steve Francia</a>、<a href="https://campoy.cat/">Francesc Campoy</a>（后已经从google离职加入<a href="https://dgraph.io/">Dgraph</a>）等都是在这个阶段加入Go team的。</p>
<p>Go团队在很长一段时间里尤其重视与社区的互动，比如连续多年发起<a href="https://blog.golang.org/survey2018-results">Go user调查</a>、<a href="https://www.gophercon.com/">Gophercon大会</a>后的Go team<a href="https://blog.golang.org/contributor-workshop">与社区的见面会和分组讨论</a>、<a href="https://tip.golang.org/doc/go1.8#gopath">去GOPATH降低Go入门学习曲线</a>、<a href="https://blog.golang.org/go-brand">发布Go新品牌标识</a>、添加<a href="https://tonybai.com/2018/11/19/some-changes-in-go-1-11/">Go module机制</a>、<a href="https://golang.org/">改善官网</a>等。</p>
<p>在今天Go官博发文：<a href="https://blog.golang.org/go.dev">“Go.dev: a new hub for Go developers”</a>，正式发布<a href="https://go.dev/">go.dev站点</a>，该站点被Go核心团队寄望于成为全世界Gopher开发人员的中心。它将告诉gopher（无论新手还是老油条）：谁在使用Go、用Go做什么、怎么学习Go(Go的各种学习资源、受欢迎的Go package都有哪些以及这些package的详细信息）。</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/homepage.png" alt="img{512x368}" /></p>
<p>go.dev发布之后，golang.org官网将更加聚焦go开源项目本身的开发、语言演化以及Go版本发布。而go.dev将成为gopher日常使用go语言的中心，包括go学习、go方案、go应用案例等。在这里我们简单探索一下go.dev这个站点究竟给gopher们带来了什么(这仅仅是go.dev的最小功能发布，后续go.dev可能会演化出更多特性、并根据社区反馈更好满足gopher需求)。</p>
<h2>一. <a href="https://learn.go.dev/">学习资源</a>聚合</h2>
<p>go.dev的一个重要功能就是<strong>帮助首次进入Go世界的开发人员学习Go</strong>。</p>
<p>在go.dev的”learn”栏目下，我们在第一屏就看到了Go新手入门的三个步骤：安装、”Hello World”、Go tour以及<a href="https://golang.org/doc/">更为详尽文档的入口</a>：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/learn-1.png" alt="img{512x368}" /></p>
<p>接下来，go.dev提供了这些年口碑较好、受到gopher欢迎的一些初级在线学习资源：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/learn-2.png" alt="img{512x368}" /></p>
<p>像gobyexample.com、gophercises.com都在推荐行列。</p>
<p>Go技术类书籍以及培训资源是gopher学习Go过程中不可缺少的：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/learn-3.png" alt="img{512x368}" /></p>
<p>Go.dev在learn栏目下推荐了一些口碑不错的Go书籍，比如：Alan A. A. Donovan和<a href="https://www.cs.princeton.edu/~bwk/">Brian W. Kernighan</a>合著的<a href="http://www.gopl.io/">Go圣经：《The Go Programming Language》</a>被在首位推荐。知名Go培训师William Kennedy的<a href="https://www.ardanlabs.com/">培训</a>也被推荐给了大家。不过口碑不错的书籍<a href="https://book.douban.com/subject/25858023/">《Go in action》</a>我觉得也应该列入推荐行列。</p>
<p>在Learn栏目最后，是全世界各地近期有关Go的meetup活动的schedule，Gopher可以得到最及时的meetup信息，并选择参加。</p>
<h2>二. 成熟解决方案参考</h2>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/solution-1.png" alt="img{512x368}" /></p>
<p>go.dev开辟的”solution”栏目旨在提升go的开发过程。栏目从“云原生和网络服务开发”、“命令行程序开发”、“web开发”以及Devops/Site Reliability四个方面提供聚合化的资料。以“云原生和网络服务开发”为例，Go.dev提供了这方面的典型项目和用户、使用方法、关键方案（一些书籍、成熟框架、客户端库以及其他资源）。</p>
<p>go.dev solution栏目还提供了一些Go的典型客户以及这些客户使用Go的典型案例：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/solution-2.png" alt="img{512x368}" /></p>
<h2>三、Package信息聚合中心</h2>
<p>在go.dev的“explore”栏目下，我们看到的是Go package的信息中心：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/explore-1.png" alt="img{512x368}" /></p>
<p>就如上图所示，这里提供了受欢迎的package和特色package的推荐列表，以及package信息的搜索功能。</p>
<p>以<a href="https://tonybai.com/2018/01/13/the-problems-i-encountered-when-writing-go-code-issue-1st/">logrus为例</a>：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/explore-2.png" alt="img{512x368}" /></p>
<p>在<a href="https://github.com/sirupsen/logrus">logrus包</a>的主页，我们看到了有关logrus的各种信息，项目repo地址、最新版本号、module名字、开源许可证信息、文档（应该是集成了godoc返回的结果）、它的依赖、以及以它为依赖的项目(见下图)：</p>
<p><img src="https://tonybai.com/wp-content/uploads/go.dev/explore-3.png" alt="img{512x368}" /></p>
<h2>四. 小结</h2>
<p>go.dev目前处于最小产品状态(mvp)，从目前已经提供的栏目来看，go.dev能为gopher提供的帮助已经很全面了。后续go.dev站点的运营好坏（比如：信息更新是否及时等）将决定go.dev是否能达到其预期的期望。</p>
<p>go.dev目前似乎还缺少论坛功能。不过已有的<a href="https://groups.google.com/forum/#!topic/golang-nuts/">golang-nuts</a>、<a href="https://forum.golangbridge.org/">gobridge</a>已经承担了这个角色，但如果能有一个官方论坛（一站式）就再好不过了。</p>
<p>go.dev在国内可以访问，就是速度有些慢（可能因地区而异）。</p>
<hr />
<p>我的网课“<a href="https://coding.imooc.com/class/284.html">Kubernetes实战：高可用集群搭建、配置、运维与应用</a>”在慕课网上线了，感谢小伙伴们学习支持！</p>
<p><a href="https://tonybai.com/">我爱发短信</a>：企业级短信平台定制开发专家 https://tonybai.com/<br />
smspush : 可部署在企业内部的定制化短信平台，三网覆盖，不惧大并发接入，可定制扩展； 短信内容你来定，不再受约束, 接口丰富，支持长短信，签名可选。</p>
<p>著名云主机服务厂商DigitalOcean发布最新的主机计划，入门级Droplet配置升级为：1 core CPU、1G内存、25G高速SSD，价格5$/月。有使用DigitalOcean需求的朋友，可以打开这个<a href="https://m.do.co/c/bff6eed92687">链接地址</a>：https://m.do.co/c/bff6eed92687 开启你的DO主机之路。</p>
<p>Gopher Daily(Gopher每日新闻)归档仓库 &#8211; https://github.com/bigwhite/gopherdaily</p>
<p>我的联系方式：</p>
<p>微博：https://weibo.com/bigwhite20xx<br />
微信公众号：iamtonybai<br />
博客：tonybai.com<br />
github: https://github.com/bigwhite</p>
<p>微信赞赏：<br />
<img src="https://tonybai.com/wp-content/uploads/wechat-zanshang-code-512x512.jpg" alt="img{512x368}" /></p>
<p>商务合作方式：撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。</p>
<p style='text-align:left'>&copy; 2019, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2019/11/14/what-the-godev-website-bring-to-gophers/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>给女儿搭建一个博客站点</title>
		<link>https://tonybai.com/2016/12/18/build-a-blog-website-for-my-daughter/</link>
		<comments>https://tonybai.com/2016/12/18/build-a-blog-website-for-my-daughter/#comments</comments>
		<pubDate>Sun, 18 Dec 2016 07:04:02 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[生活簿]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[CNAME]]></category>
		<category><![CDATA[DigitalOcean]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[github-page]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Gopher]]></category>
		<category><![CDATA[Hexo]]></category>
		<category><![CDATA[hugo]]></category>
		<category><![CDATA[Jekyll]]></category>
		<category><![CDATA[maupassant]]></category>
		<category><![CDATA[Octopress]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[theme]]></category>
		<category><![CDATA[vps]]></category>
		<category><![CDATA[主题]]></category>
		<category><![CDATA[博客]]></category>
		<category><![CDATA[域名]]></category>
		<category><![CDATA[女儿]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[果果]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=2087</guid>
		<description><![CDATA[时光荏苒。转眼间女儿已经成为一名小学生了，依稀还记得当年果果呱呱坠地的情景，独自回味，感慨万千。 果果3岁前，都是我来记录她的生活点滴和成长历程，那个时候她是我们生活舞台的主角。3岁后，果果学会了说话，上了幼儿园，开始学习各种知识、技能以及各种才艺。尤其是在幼儿园中班之后，她学会了写字、组词、造句和写日记，果果完全可以自己用文字来表达自己了! 我觉得是时候让她自己来记录她的成长历程了，我和她妈妈只是辅助和指导就好了。这种想法日益迫切，尤其是果果今年上了小学后，果果的成长更快了。我觉得迫切需要给她一个平台去表达她自己和记录她的成长。传统手段不能满足需求，于是我就想到给她搭建了一个博客站点，辅助她用网络文字、图片的形式记录自6岁上学之后的成长历程。于是这个周末就花了些时间，给女儿搭了一个博客站点。 下面以“流水账”的形式，记录一下这个站点的搭建过程，也许能给和我有同样需求的家长们带来一些帮助^_^。 一、选型和准备工作 博客站点，我首选静态页面的。静态页面，又要快速搭建，我首选github page。github page一般情况下在国内访问相对较为稳定，访问速度也不错，ping延迟一般在100多ms，比我独立购买的Digital Ocean的主机的延迟低很多。还有另外一个原因就是市面上几乎所有主流静态页面生成工具都对github pages有着不错的支持。由于采用静态页面，即便将来迁移到VPS，也几乎是无缝的。于是给果果在github上申请了账号。 用与搭建博客、个人站点的静态页面生成工具很多，比如：jekyll、octopress、hexo以及hugo，用哪个呢？作为Gopher，我首选hugo。接下来，我们来看看用hugo是否能搭建出满足我们需求的基于github page的博客站点吧。 hugo的安装参考hugo github主页上的说明即可。由于hugo import了很多第三方package，有些package可能在墙外，因此配置上加速器是更好的、更快的^_^。 二、基于hugo搭建博客站点 去年曾写过一篇《使用Hugo搭建静态站点(http://tonybai.com/2015/09/23/intro-of-gohugo/)》，讲述如何通过hugo这个golang开发的工具搭建一个属于自己的静态站点（static websites)。不过那篇文章并没有谈到hugo如何与github page结合。 hugo官方文档中，对如何使用hugo创建基于github page站点有着较为详尽的描述，这是由一位名为Spencer Lyon的外国开发者贡献的文章，并且Spencer Lyon给出hugo github page的工程template： hugo-gh-blog。我这里就直接使用了该工程模板，并基于hugo_gh_blog做一些定制化修改，比如“汉化”之类的。 下面是详细的步骤： 1、clone hugo_gh_blog 我们首先将Spencer Lyon的hugo_gh_blog代码库clone到本地，这是我们博客搭建的基础： $mkdir GuoGuoBlog $cd GuoGuoBlog $git clone https://github.com/spencerlyon2/hugo_gh_blog.git Cloning into 'hugo_gh_blog'... remote: Counting objects: 489, done. remote: Total 489 (delta 0), reused 0 (delta 0), [...]]]></description>
			<content:encoded><![CDATA[<p>时光荏苒。转眼间女儿已经成为一名小学生了，依稀还记得当年<a href="http://tonybai.com/2010/05/11/now-i-am-a-father/">果果呱呱坠地</a>的情景，独自回味，感慨万千。</p>
<p><a href="http://tonybai.com/2013/05/18/daughter-is-3-years-old/">果果3岁</a>前，都是我来<a href="http://tonybai.com/tag/女儿">记录她的生活点滴和成长历程</a>，那个时候她是我们生活舞台的主角。3岁后，果果学会了说话，上了幼儿园，开始学习各种知识、技能以及各种才艺。尤其是在幼儿园中班之后，她学会了写字、组词、造句和写日记，果果完全可以自己用文字来表达自己了! 我觉得是时候让她自己来记录她的成长历程了，我和她妈妈只是辅助和指导就好了。这种想法日益迫切，尤其是果果今年上了小学后，果果的成长更快了。我觉得迫切需要给她一个平台去表达她自己和记录她的成长。传统手段不能满足需求，于是我就想到给她搭建了一个博客站点，辅助她用网络文字、图片的形式记录自6岁上学之后的成长历程。于是这个周末就花了些时间，给女儿搭了一个博客站点。</p>
<p>下面以“流水账”的形式，记录一下这个站点的搭建过程，也许能给和我有同样需求的家长们带来一些帮助^_^。</p>
<h3>一、选型和准备工作</h3>
<p>博客站点，我首选静态页面的。静态页面，又要快速搭建，我首选<a href="https://pages.github.com/">github page</a>。github page一般情况下在国内访问相对较为稳定，访问速度也不错，ping延迟一般在100多ms，比我独立购买的<a href="https://www.digitalocean.com/?refcode=bff6eed92687">Digital Ocean的主机</a>的延迟低很多。还有另外一个原因就是市面上几乎所有主流静态页面生成工具都对github pages有着不错的支持。由于采用静态页面，即便将来<a href="http://tonybai.com/2014/11/28/migrate-blog-to-digitalocean-vps/">迁移到VPS</a>，也几乎是无缝的。于是给果果在github上申请了<a href="https://github.com/baisibei">账号</a>。</p>
<p>用与搭建博客、个人站点的静态页面生成工具很多，比如：<a href="http://jekyllrb.com/">jekyll</a>、<a href="http://octopress.org/">octopress</a>、<a href="https://hexo.io/">hexo</a>以及<a href="http://gohugo.io/">hugo</a>，用哪个呢？作为<a href="http://tonybai.com/tag/golang">Gopher</a>，我首选<a href="https://github.com/spf13/hugo">hugo</a>。接下来，我们来看看用hugo是否能搭建出满足我们需求的基于github page的博客站点吧。</p>
<p>hugo的安装参考hugo github主页上的说明即可。由于hugo import了很多第三方package，有些package可能在墙外，因此配置上加速器是更好的、更快的^_^。</p>
<h3>二、基于hugo搭建博客站点</h3>
<p>去年曾写过一篇《使用Hugo搭建静态站点(http://tonybai.com/2015/09/23/intro-of-gohugo/)》，讲述如何通过<a href="https://github.com/spf13/hugo">hugo</a>这个<a href="http://tonybai.com/tag/golang">golang</a>开发的工具搭建一个属于自己的静态站点（static websites)。不过那篇文章并没有谈到hugo如何与github page结合。</p>
<p>hugo官方文档中，对<a href="https://gohugo.io/tutorials/github-pages-blog/">如何使用hugo创建基于github page站点</a>有着较为详尽的描述，这是由一位名为<a href="https://github.com/spencerlyon2/">Spencer Lyon</a>的外国开发者贡献的文章，并且Spencer Lyon给出hugo github page的工程template： <a href="http://spencerlyon2.github.io/hugo_gh_blog">hugo-gh-blog</a>。我这里就直接使用了该工程模板，并基于hugo_gh_blog做一些定制化修改，比如“汉化”之类的。</p>
<p>下面是详细的步骤：</p>
<h4>1、clone hugo_gh_blog</h4>
<p>我们首先将Spencer Lyon的hugo_gh_blog代码库clone到本地，这是我们博客搭建的基础：</p>
<pre><code>$mkdir GuoGuoBlog
$cd GuoGuoBlog
$git clone https://github.com/spencerlyon2/hugo_gh_blog.git
Cloning into 'hugo_gh_blog'...
remote: Counting objects: 489, done.
remote: Total 489 (delta 0), reused 0 (delta 0), pack-reused 489
Receiving objects: 100% (489/489), 84.50 KiB | 24.00 KiB/s, done.
Resolving deltas: 100% (232/232), done.
Checking connectivity... done.
$cd hugo_gh_blog/
$ls
LICENSE        README.md    config.yaml    content/    deploy.sh*    static/        themes/
</code></pre>
<h4>2、编辑config.yaml和本地调试</h4>
<p>进入hugo_gh_blog目录，编辑config.yaml，设置站点的一些元数据：</p>
<pre><code>---
contentdir: "content"
layoutdir: "layouts"
publishdir: "public"
indexes:
  category: "categories"
baseurl: "http://baisibei.github.io"
title: "果果的成长历程"
canonifyurls: true
theme: "Lanyon"
...

</code></pre>
<p>接下来，我们来生成我们的静态博客页面：</p>
<pre><code>$hugo
0 draft content
0 future content
2 pages created
0 paginator pages created
2 categories created
in 48 ms
</code></pre>
<p>hugo将创建public目录，并将生成的页面放入该目录：</p>
<pre><code>$ls public
404.html    categories/    css/        favicon.ico    img/        index.html    index.xml    posts/        sitemap.xml
</code></pre>
<p>public/index.html就是站点首页。</p>
<p>我们在本地可以启动hugo server，并查看生成的站点情况：</p>
<pre><code>$hugo server -t Lanyon
0 draft content
0 future content
2 pages created
0 paginator pages created
2 categories created
in 54 ms
Serving pages from /Users/tony/GuoGuoBlog/hugo_gh_blog/public
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)

</code></pre>
<p>打开浏览器，输入localhost:1313。不出意外，你就可以看到类似下面的站点：</p>
<p><img src="http://tonybai.com/wp-content/uploads/baisibei-hugo-gh-blog-snapshot.png" alt="img{512x368}" /></p>
<h4>3、创建github page repository</h4>
<p>默认情况，github账号xxxx对应的github page repository是xxxx.github.io。于是我在女儿的github账号下创建public repository：baisibei.github.io。</p>
<p>接下来，我们需要将上步中生成的静态页面push到baisibei.github.io这个repository中。在本地进入到hugo_gh_blog/public目录下，执行：</p>
<pre><code>$git init
$git add -A
$git commit -m"initial commit" .
$git remote add origin https//github.com/baisibei.github.io.git
$git push -u origin master
</code></pre>
<p>如果你是用自己的github账号替孩子提交，那么请在该repository下设置collaborator。</p>
<p>push一旦成功后，你就可以直接访问：https://xxxx.github.io查看站点页面了。我这里要访问的是baisibei.github.io。</p>
<h4>4、样式问题</h4>
<p>问题出现了。在本地样式良好的首页，一旦push到github page上，再用浏览器（chrome）打开，我发现样式全部丢失了，首页被render为“全文字”版本。我一开始怀疑css文件路径不对或无法访问到某个css文件，通过“显示网页源代码”，单独试着访问所有css文件，发现这些文件都是可访问的。还有一个现象是：通过mac safari浏览器、手机上的ucweb、微信内置浏览器浏览，均没有样式问题，显示一切正常(Firefox、IE也均有问题)。将hugo_gh_blog放在我的VPS上，并用hugo作为web server，任何浏览器访问都是没有问题的。</p>
<p>针对这个问题，谷歌和度娘了半天，也没有解决掉。于是我有了换工具的想法。在搜索其他工具资料的过程中，我发现了基于hexo的<a href="https://github.com/tufu9441/maupassant-hexo">maupassant theme</a>！没错，就是那个和我目前博客同源的主题：maupassant。这个主题采用响应式的设计，对不同屏幕的访问均有很好的适配。</p>
<p>之前我的博客为了适应智能终端的浏览，采用了WPtouch插件，效果差强人意。这次我特地停用了该插件，直接用手机访问我的博客，发现maupassant的显示效果是棒棒的。于是下一步，我将hugo更换为<a href="https://hexo.io">hexo</a>，主题由Lanyon更换为maupassant。</p>
<p>hugo_gh_blog和baisibei.github.io依然保留在github.com上，后者的名字被rename为baisibei.github.io.using.hugo。</p>
<h3>三、基于hexo搭建博客站点</h3>
<h4>1、安装hexo相关工具</h4>
<p>第一次用hexo，安装hexo过程需要一些耐心：</p>
<pre><code>$npm install hexo-cli -g
{耐心的等待... ...}

$which hexo
/usr/local/bin/hexo

$hexo -v
hexo-cli: 1.0.2
os: Darwin 13.1.0 darwin x64
http_parser: 2.7.0
node: 6.9.1
v8: 5.1.281.84
uv: 1.9.1
zlib: 1.2.8
ares: 1.10.1-DEV
icu: 57.1
modules: 48
openssl: 1.0.2j
</code></pre>
<h4>2、创建blog</h4>
<p>使用hexo init在本地创建blog repository目录：</p>
<pre><code>$hexo init hexo_gh_blog
{耐心等待...}
... ...
INFO  Start blogging with Hexo!
</code></pre>
<p>进入hexo_gh_blog目录：</p>
<pre><code>$cd hexo_gh_blog
$ls
_config.yml    node_modules/    package.json    scaffolds/    source/        themes/
</code></pre>
<p>没完，我们还需要install一下相关的依赖：</p>
<pre><code>$npm install
{耐心等待....}

</code></pre>
<p>通过”hexo g”命令生成blog文件：</p>
<pre><code>$hexo g
INFO  Start processing
INFO  Files loaded in 270 ms
INFO  Generated: index.html
INFO  Generated: archives/index.html
INFO  Generated: fancybox/blank.gif
INFO  Generated: fancybox/jquery.fancybox.css
INFO  Generated: fancybox/fancybox_sprite.png
INFO  Generated: fancybox/fancybox_loading.gif
INFO  Generated: fancybox/fancybox_overlay.png
INFO  Generated: fancybox/fancybox_loading@2x.gif
INFO  Generated: fancybox/jquery.fancybox.pack.js
INFO  Generated: fancybox/jquery.fancybox.js
INFO  Generated: fancybox/fancybox_sprite@2x.png
INFO  Generated: archives/2016/12/index.html
INFO  Generated: css/fonts/fontawesome-webfont.eot
INFO  Generated: css/fonts/fontawesome-webfont.svg
INFO  Generated: css/style.css
INFO  Generated: css/fonts/fontawesome-webfont.ttf
INFO  Generated: fancybox/helpers/fancybox_buttons.png
INFO  Generated: css/fonts/FontAwesome.otf
INFO  Generated: js/script.js
INFO  Generated: fancybox/helpers/jquery.fancybox-buttons.css
INFO  Generated: archives/2016/index.html
INFO  Generated: css/fonts/fontawesome-webfont.woff
INFO  Generated: fancybox/helpers/jquery.fancybox-media.js
INFO  Generated: fancybox/helpers/jquery.fancybox-buttons.js
INFO  Generated: fancybox/helpers/jquery.fancybox-thumbs.css
INFO  Generated: fancybox/helpers/jquery.fancybox-thumbs.js
INFO  Generated: css/images/banner.jpg
INFO  Generated: 2016/12/16/hello-world/index.html
INFO  28 files generated in 867 ms

$ls
_config.yml    db.json        node_modules/    package.json    public/        scaffolds/    source/        themes/
</code></pre>
<p>和hugo命令类似，hexo g也创建了public目录，并将站点的静态文件生成在这个目录下面。</p>
<p>通过hexo s可以启动一个web server，在本地查看生成的静态站点：</p>
<pre><code>$hexo s
INFO  Start processing
INFO  Hexo is running at http://localhost:4000/. Press Ctrl+C to st
</code></pre>
<p>hexo自带的landscape theme真的是不咋好看。</p>
<h4>3、更换主题为maupassant</h4>
<p>先清理一下生成文件，再clone maupassant主题：</p>
<pre><code>$hexo clean
INFO  Deleted database.
INFO  Deleted public folder.

$git clone https://github.com/tufu9441/maupassant-hexo themes/maupassant
Cloning into 'themes/maupassant'...
remote: Counting objects: 1310, done.
remote: Total 1310 (delta 0), reused 0 (delta 0), pack-reused 1309
Receiving objects: 100% (1310/1310), 562.88 KiB | 382.00 KiB/s, done.
Resolving deltas: 100% (747/747), done.
Checking connectivity... done.

$ls themes/
landscape/    maupassant/
</code></pre>
<p>编辑hexo_gh_blog/_config.yml文件，修改theme为：maupassant</p>
<pre><code>//_config.xml
theme: landscape

=&gt;

theme: maupassant
</code></pre>
<p>重新生成站点静态文件之前，我们还需要安装下面两个工具，否则hexo生成出来的静态页面也是不可用的：</p>
<pre><code>$ npm install hexo-renderer-jade --save
$ npm install hexo-renderer-sass --save
</code></pre>
<p>hexo g和hexo s后，你就可以在本地：localhost:4000地址上看到生成的静态页面了：</p>
<p><img src="http://tonybai.com/wp-content/uploads/baisibei-hexo-gh-blog-snapshot.png" alt="img{512x368}" /></p>
<p>仿效上面章节中的步骤，将public目录push到baisibei.github.io repository中，看看我们上传后的站点通过公网访问是否还有“失真”现象，结果：一切正常。</p>
<h4>4、定制站点</h4>
<h5>a) 定制hexo_gh_blog/_config.yml</h5>
<p>这个_config.xml中的配置都是站点全局范畴的，这里仅我将我修改过的一些定制属性贴出来：</p>
<pre><code># Site
title: Amy Bai
subtitle: 果果的成长历程
description: 记录一个小女孩儿在学习、生活、家庭、情感方面的成长经历
author: Amy Bai
language: zh-CN
timezone: Asia/Shanghai
since: 2016
avatar: https://avatars0.githubusercontent.com/u/24524343?v=3&amp;s=400

# URL
## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/'
url: http://daughter.tonybai.com

</code></pre>
<p>默认情况下，maupassant主题的menu中包含rss菜单项（站点的订阅feed），对应的访问路径是/atom.xml，但要生成atom.xml，需要安装另外两个plugins：hexo-generator-feed和hexo-generator-sitemap：</p>
<pre><code>在_config.xml中添加：

plugins:
- hexo-generator-feed
- hexo-generator-sitemap

安装这两个插件；

$npm install hexo-generator-feed --save
hexo-site@0.0.0 /Users/tony/GuoGuoblog/hexo_gh_blog
└── hexo-generator-feed@1.2.0

$npm install hexo-generator-sitemap --save
hexo-site@0.0.0 /Users/tony/GuoGuoblog/hexo_gh_blog
└── hexo-generator-sitemap@1.1.2
</code></pre>
<p>安装后，执行hexo g，会看到atom.xml的生成。不过由于hexo版本似乎与feed插件有兼容性问题，当执行hexo s时，命令报错。我暂时在_config.xml中先注释掉这两个插件，待后期看是否能解决，不过这不影响站点的主要功能。</p>
<h5>b) about页面</h5>
<p>在maupassant主题的menu中默认还包含了about菜单项，但在生成的站点静态页面中点击about菜单项，将返回失败页面。如何给站点添加about页面呢？</p>
<p>在hexo_gh_blog/source下创建about目录，进入about目录，创建index.md文件，内容诸如：</p>
<pre><code>---
title: 关于我
---
我是Amy Bai，小名果果。
</code></pre>
<p>这样hexo g和hexo s后，你就有about页面可供访问了。</p>
<h4>5、写post</h4>
<p>hexo通过hexo new 命令来创建一篇post，我更喜欢简单粗暴，直接再hexo_gh_blog/source/_post创建一个xxx.md文件，这就是一篇post。post内的markdown格式和很多工具都是类似的：</p>
<pre><code>以initial-post.md为例：
---
title: "第一篇（待写）"
date: "2016-12-15"
description: "第一篇博文，敬请期待^O^"
categories:
    - "日记"
    - "感悟"
---

## 标题一

第一篇文章，敬请期待

### 子标题

## 小结

^O^

</code></pre>
<p>hexo按md文件头中的date对post进行排序。title就是显示在文章中的标题。description是文章摘要。默认情况下，maupassant主题在首页只是展示文章摘要而不是全文。</p>
<h3>四、域名绑定</h3>
<p>还没有申请顶级域名下的二级域名，目前打算绑定daughter.tonybai.com这个子域名。怎么做呢？</p>
<p>在public目录下，创建CNAME文件，文件内容：daughter.tonybai.com。然后将文件Push到github上去。</p>
<p>在你的域名管理站点，创建”daughter.tonybai.com”子域名，并将其CNAME值设置为”baisibei.github.io”。生效后，打开浏览器，访问”daughter.tonybai.com”，你就可以看到你刚刚生成的新站点了。</p>
<h3>五、小结</h3>
<p>站点搭建好了！用各种终端访问，感觉效果还不错。post发布也很方便，如果你想自动发布，定义一下hexo deploy即可。我个人习惯手动提交，也就没这个步骤了。</p>
<p>接下来，把内容创作的任务就交给果果了^_^。</p>
<p style='text-align:left'>&copy; 2016, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2016/12/18/build-a-blog-website-for-my-daughter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>使用Hugo搭建静态站点</title>
		<link>https://tonybai.com/2015/09/23/intro-of-gohugo/</link>
		<comments>https://tonybai.com/2015/09/23/intro-of-gohugo/#comments</comments>
		<pubDate>Wed, 23 Sep 2015 14:41:50 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[Disqus]]></category>
		<category><![CDATA[docker]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[Hexo]]></category>
		<category><![CDATA[highlight.js]]></category>
		<category><![CDATA[hugo]]></category>
		<category><![CDATA[Hyde]]></category>
		<category><![CDATA[Jekyll]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[Octopress]]></category>
		<category><![CDATA[分类]]></category>
		<category><![CDATA[多说]]></category>
		<category><![CDATA[插件]]></category>
		<category><![CDATA[标签]]></category>
		<category><![CDATA[评论]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1891</guid>
		<description><![CDATA[虽然前一篇Blog宣称自己要用Markdown开始写Post，但实际操作起来还是发现了诸多不兼容问题(插件与主题间、插件与插件间的)，让编写和修改文章变得十分繁琐，于是我研究了一下静态Web站点生成工具Hugo。Hugo是由前Docker的重量级员工(2015年8月末从Docker离职)：Steve Francia实现的一个开源静态站点生成工具框架，类似于Jekyll、Octopress或Hexo，都是将特定格式(最常见的是Markdown格式)的文本文件转换为静态html文件而生成一个静态站点，多用于个人Blog站点、项目文档(Docker的官方manual Site就是用Hugo生成的)、初创公司站点等。这类工具越来越多的受到程序员等颇具“极客”精神的群体的欢迎，结合github.com等版本控制服务，采用具有简单语法格式但强大表达力的Markdown标记语言，人们可以在很短时间内就构建出一个符合自己需求的静态Web站点。在这些工具中，Hugo算是后起之秀了，它最大的优点就是Fast! 一个中等规模的站点在几分之一秒内就可以生成出来。其次是良好的跨平台特性、配置简单、使用方便等。这一切均源于其良好的基因：采用Go语言实现。Steve Francia除了Hugo平台自身外，还维护了一个Hugo Theme的Repo，这个Hugo主题库可以帮助Hugo使用者快速找到自己心仪的主题并快速搭建起静态站点。目前国内使用Hugo的人还不多，但感觉其趋势是在逐渐增多。这里写下这篇Post，也算是为大家入个门，引个路吧。 一、安装Hugo Hugo托管在github.com上，因此获取Hugo很方面，目前有至少两种方法可以安装Hugo。 1、安装包 对于普通用户（无git、无开发经验）而言，直接下载安装包是最简单的方式。我们可以下载Hugo的Release版，截至目前为止最新版本是v0.14，可以在这里下载你的平台(支持linux, windows, darwin, netbsd, freebsd和arm等)对应的版本。不过我发现0.14版本似乎有Bug，在我的MacOsX上生成Hugo Docs站点总是panic。 2、源码编译 对于开发者而言，源码编译是最Geek的方式: go get -u -v github.com/spf13/hugo go build -o hugo main.go mv hugo $GOPATH/bin 在命令行下执行hugo命令，如果得到类似下面结果，则说明你已经成功安装了Hugo： $hugo version Hugo Static Site Generator v0.15-DEV BuildDate: 2015-09-20T23:53:39+08:00 二、生成静态站点 1、创建静态站点 我们来创建一个名为”tonybai.com”的静态站点： $hugo new site tonybai.com $tree . └── tonybai.com ├── archetypes ├── config.toml [...]]]></description>
			<content:encoded><![CDATA[<p>虽然前一篇Blog宣称自己要<a href="http://tonybai.com/2015/09/19/write-blog-in-markdown/">用Markdown开始写Post</a>，但实际操作起来还是发现了诸多不兼容问题(插件与主题间、插件与插件间的)，让编写和修改文章变得十分繁琐，于是我研究了一下静态Web站点生成工具<a href="http://gohugo.io/">Hugo</a>。Hugo是由前<a href="https://www.docker.com">Docker</a>的重量级员工(2015年8月末从Docker离职)：<a href="https://github.com/spf13">Steve Francia</a>实现的一个开源静态站点生成工具框架，类似于<a href="http://jekyllrb.com/">Jekyll</a>、<a href="http://octopress.org">Octopress</a>或<a href="http://hexo.io/">Hexo</a>，都是将特定格式(最常见的是Markdown格式)的文本文件转换为静态html文件而生成一个静态站点，多用于个人Blog站点、项目文档(Docker的官方manual Site就是用Hugo生成的)、初创公司站点等。这类工具越来越多的受到程序员等颇具“极客”精神的群体的欢迎，结合github.com等版本控制服务，采用具有简单语法格式但强大表达力的Markdown标记语言，人们可以在很短时间内就构建出一个符合自己需求的静态Web站点。在这些工具中，Hugo算是后起之秀了，它最大的优点就是Fast! 一个中等规模的站点在几分之一秒内就可以生成出来。其次是良好的跨平台特性、配置简单、使用方便等。这一切均源于其良好的基因：采用Go语言实现。Steve Francia除了Hugo平台自身外，还维护了一个<a href="https://github.com/spf13/hugoThemes">Hugo Theme</a>的Repo，这个Hugo主题库可以帮助Hugo使用者快速找到自己心仪的主题并快速搭建起静态站点。目前国内使用Hugo的人还不多，但感觉其趋势是在逐渐增多。这里写下这篇Post，也算是为大家入个门，引个路吧。</p>
<h3>一、安装Hugo</h3>
<p><a href="https://github.com/spf13/hugo/">Hugo托管</a>在github.com上，因此获取Hugo很方面，目前有至少两种方法可以安装Hugo。</p>
<h4>1、安装包</h4>
<p>对于普通用户（无git、无开发经验）而言，直接下载安装包是最简单的方式。我们可以下载Hugo的<a href="https://github.com/spf13/hugo/releases">Release版</a>，截至目前为止最新版本是v0.14，可以在<a href="https://github.com/spf13/hugo/releases/tag/v0.14">这里</a>下载你的平台(支持linux, windows, darwin, netbsd, freebsd和arm等)对应的版本。不过我发现0.14版本似乎有Bug，在我的MacOsX上生成Hugo Docs站点总是panic。</p>
<h4>2、源码编译</h4>
<p>对于开发者而言，源码编译是最Geek的方式:</p>
<pre><code>go get -u -v github.com/spf13/hugo
go build -o hugo main.go
mv hugo $GOPATH/bin
</code></pre>
<p>在命令行下执行hugo命令，如果得到类似下面结果，则说明你已经成功安装了Hugo：</p>
<pre><code>$hugo version
Hugo Static Site Generator v0.15-DEV BuildDate: 2015-09-20T23:53:39+08:00
</code></pre>
<h3>二、生成静态站点</h3>
<h4>1、创建静态站点</h4>
<p>我们来创建一个名为”tonybai.com”的静态站点：</p>
<pre><code>$hugo new site tonybai.com
$tree
.
└── tonybai.com
    ├── archetypes
    ├── config.toml
    ├── content
    ├── data
    ├── layouts
    └── static
</code></pre>
<p>我们看到，通过hugo new site命令，我们建立了tonybai.com站点的后台目录结构。但细心的你会发现：这里的目录都是空的。除了config.toml中可怜的三行内容：</p>
<pre><code>baseurl = "http://replace-this-with-your-hugo-site.com/"
languageCode = "en-us"
title = "My New Hugo Site"
</code></pre>
<p>不过即便目录为空，这也是一个完整的静态站点源文件，我们可以基于这些文件生成我们的站点。</p>
<pre><code>$cd tonybai.com
$hugo server

0 draft content
0 future content
0 pages created
0 paginator pages created
0 tags created
0 categories created
in 6 ms
Serving pages from /Users/tony/test/hugotest/tonybai.com/public
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
</code></pre>
<p>上面的hugo命令在将repo转换为静态Site文件放入public目录：</p>
<pre><code>├── public
│   ├── 404.html
│   ├── index.html
│   ├── index.xml
│   └── sitemap.xml
</code></pre>
<p>之后Hugo启动了一个server作为该Site的Web Server。通过浏览器访问http://localhost:1313，你将看到一个完全空白的站点首页。虽然这个站点没啥实用价值（一片空白），但这却是一个良好的起点。</p>
<h4>2、添加Theme</h4>
<p>添加了Theme后的站点才有血有肉，丰富多彩。</p>
<p>添加Theme的步骤如下，我们以Hyde Theme为例：</p>
<p>首先创建themes目录，并下载Hyde Theme文件：</p>
<pre><code>$ mkdir themes
$ cd themes
$ git clone https://github.com/spf13/hyde.git
</code></pre>
<p>接下来，我们需要对Site进行一些配置，tonybai.com/config.toml是Site的顶层配置文件，配置后的config.toml文件如下：</p>
<pre><code>baseurl = "http://tonybai.com/"
languageCode = "en-us"
title = "Tony Bai"
theme = "hyde"

[params]
    description = "这里是Tony Bai的个人博客"
    themeColor = "theme-base-08" # for hyde theme
</code></pre>
<p>其中：<br />
theme = “hyde” 指定站点使用Hyde主题；<br />
themeColor = “theme-base-08&#8243; 指定了站点的主题颜色（默认是黑色的，这里改成一种红色）</p>
<p>在tonybai.com目录下重新执行hugo server，并打开浏览器查看站点首页，你会发现视野里有内容了：</p>
<p><img src="http://tonybai.com/wp-content/uploads/tonybaicom-hyde-theme-1.jpg" alt="站点截图1" /></p>
<h4>3、第一个Post</h4>
<p>结构和样式有了，我们还没有内容。我们来创建站点的第一个Post：</p>
<pre><code>$hugo new welcome.md
/Users/tony/Test/hugotest/tonybai.com/content/welcome.md created
</code></pre>
<p>hugo在content下创建welcome.md文件，我们编写一些文件内容：</p>
<pre><code>+++
Categories = ["Development", "GoLang"]
Description = ""
Tags = ["Development", "golang"]
date = "2015-09-23T16:30:37+08:00"
menu = "main"
title = "你好，Hugo"

+++

这是使用Hugo创建的站点中的第一篇文章。
</code></pre>
<p>保存后，重新执行hugo server命令，打开浏览器，你将看到下面的情形：</p>
<p><img src="http://tonybai.com/wp-content/uploads/tonybaicom-hyde-theme-2.jpg" alt="站点截图2" /></p>
<p>至此，如果你是极简主义者，你对其他没有任何要求，你就可以用这个站点写Post了。</p>
<h3>三、调试与部署站点</h3>
<h4>1、调试站点</h4>
<p>采用Hugo的静态站点在编辑文章、调试站点时十分方便，你要做的就是编辑文本，保存后，打开浏览器看渲染后的结果。不过反复执行hugo server命令还是有些烦，hugo早想到了这一点，hugo提供了:<br />
<code>-w, --watch[=false]</code></p>
<p>执行hugo server命令时加上-w选项，hugo就可以自动检测本地站点文件的变更，并自动执行md -> html转换。这样刷新浏览器页面就可以看到你修改后的结果了：</p>
<pre><code>$hugo server -w
0 draft content
0 future content
1 pages created
0 paginator pages created
2 tags created
2 categories created
in 16 ms
Watching for changes in /Users/tony/test/hugotest/tonybai.com/{data,content,layouts,static,themes/hyde}
Serving pages from /Users/tony/test/hugotest/tonybai.com/public
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
</code></pre>
<p>通过hugo server -w的输出日志来看，hugo可以自动检测data,content,layouts,static,themes/hyde目录下的变更，但站点顶层config.toml的改动无法被检测，还需要重启hugo server。</p>
<h4>2、部署站点</h4>
<p>和Jekyll类似，使用hugo的静态站点可以部署到github page中，不过这里不详细描述这种方法，可以看<a href="http://gohugo.io/tutorials/github-pages-blog/">官方文档</a></p>
<p>如果是在vps下部署，那么hugo转换后的public文件夹可以被直接用于部署到像nginx、apache、<a href="http://tonybai.com/2015/06/04/caddy-a-web-server-in-go/">caddy</a>这样的Web Server下面。</p>
<p>当然hugo本身也可以作为一个Web server来支撑你的静态站点，就像上面提到的，你可以在你的站点目录(比如上面的”tonybai.com”)下执行：</p>
<pre><code>$sudo hugo server --bind="0.0.0.0" -v -w -p 80 -b http://tonybai.com
</code></pre>
<p>如果无法使用80端口（比如通过apache2反向代理），那么需要加上&#8211;appendPort=false，否则转换后的public下面的url地址都会带上你的hugo端口（1313）：</p>
<pre><code>$hugo server -v -w -p 1313 -b http://tonybai.com --appendPort=false
</code></pre>
<h3>四、配置和维护站点</h3>
<p>大多数人不会止步于上面那个仅仅能写Post的站点，配置分类、标签；修改字体样式；添加评论功能；增加统计代码；增加代码高亮(程序员最爱)；甚至定制主题是Geek们最喜欢折腾的事情，这里无法全表，列举几个常见的配置和维护方法，还是已hyde主题为例。</p>
<h4>1、配置分类、标签</h4>
<p>在浏览器中输入：http://localhost:1313/categories/或http://localhost:1313/tags，你会看到站点输出了一个类似目录列表似的页面：</p>
<pre><code>development/
golang/
</code></pre>
<p>development和golang从何而来呢？</p>
<p>隐藏得再深，也要给它揪出来：</p>
<pre><code>tonybai.com/themes/hyde/archetypes/default.md

+++
Description = ""
Tags = ["Development", "golang"]
Categories = ["Development", "GoLang"]
menu = "main"
+++

</code></pre>
<p>由于我们使用了hyde theme，所以我们只需看themes/hyde下面的目录结构即可，tonybai.com下面的除content之外的其他layout, data等可忽略不计。在hyde/archetypes下存放着这个主题下文章的默认分类和tags集合。这个default的作用是每次new post后，hugo会将default中的tags和categories自动copy到Post头中的tags和categories中。</p>
<p>每个Post的分类和tag在post自身的.md文件头中指定，见Categories和Tags两个配置项：</p>
<pre><code>tonybai.com/content/welcome.md

+++
Categories = ["Development", "GoLang"]
Description = ""
Tags = ["Development", "golang"]
date = "2015-09-23T16:30:37+08:00"
menu = "main"
title = "你好，Hugo"

+++
</code></pre>
<p>你可以根据需要在你的post md文件中灵活增删你的tags和categories，不局限于default.md中的那些已知项。</p>
<h4>2、修改字体样式</h4>
<p>hyde主题的字体样式在tonybai.com/themes/hyde/layouts/partials/head.html中指定：</p>
<pre><code>&lt;link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface"&gt;
</code></pre>
<p>由于googleapis在国内无法访问，因此要么注释掉这行（使用浏览器默认字体样式），要么将其换为其他字体公共服务，比如：</p>
<pre><code>&lt;link rel="stylesheet" href="http://fonts.useso.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface"&gt;
</code></pre>
<p>字体的设置在tonybai.com/themes/hyde/static/css下的各个css文件中，谨慎调整。</p>
<h4>3、添加评论功能</h4>
<p>Hugo没有内置评论功能，要增加评论功能需要集成第三方评论服务，比如国外最流行的<a href="https://disqus.com">Disqus</a>。hyde主题内置了disqus评论插件，不过需要你按如下操作配置一下，否则页面下方的disqus插件总是显示无法连接。</p>
<h5>获取disqusShortname</h5>
<p>这里用disqus主账号不行，需要用主账号login后：<em>add a newsite to disqus</em>，比如加入tonybaicom.disqus.com，这样你的disqusShortname就为：tonybaicom；</p>
<h5>配置disqusShortname</h5>
<p>在tonybai.com/config.toml中配置disqusShortname:</p>
<pre><code>[params]
    disqusShortname = "tonybaicom"
</code></pre>
<p>如果你要使用国内的评论服务，比如：<a href="http://duoshuo.com/">多说</a>，你可以参考tonybai.com/themes/hyde/layouts/partials/disqus.html，用多说提供的install code替换disqus的code，形成duoshuo.html：</p>
<pre><code>&lt;!-- 多说评论框 start --&gt;
&lt;div class="ds-thread" data-thread-key="{{ .URL }}" data-title="{{ .Title }}" data-url="{{ .Permalink }}"&gt;&lt;/div&gt;
&lt;!-- 多说评论框 end --&gt;

&lt;!-- 多说公共JS代码 start (一个网页只需插入一次) --&gt;
&lt;script type="text/javascript"&gt;
    var duoshuoQuery = {short_name:"{{.Site.Params.duoshuoShortname}}"};

    (function() {
     var ds = document.createElement('script');
     ds.type = 'text/javascript';ds.async = true;
     ds.src = (document.location.protocol == 'https:' ? 'https:' : 'http:') + '//static.duoshuo.com/embed.js';
     ds.charset = 'UTF-8';
     (document.getElementsByTagName('head')[0]
      || document.getElementsByTagName('body')[0]).appendChild(ds);
     })();
    &lt;/script&gt;
&lt;!-- 多说公共JS代码 end --&gt;
</code></pre>
<p>再在tonybai.com/themes/hyde/layouts/_default/single.html中替换下面的代码：</p>
<pre><code>{{ if and (isset .Site.Params "disqusShortname") (ne .Site.Params.disqusShortname "") }}
                &lt;h2&gt;Comments&lt;/h2&gt;
                {{ partial "disqus" . }}
            {{ end }}

</code></pre>
<p>为类似下面的代码：</p>
<pre><code>{{ if and (isset .Site.Params "duoshuoShortname") (ne .Site.Params.duoshuoShortname"") }}
                &lt;h2&gt;Comments&lt;/h2&gt;
                {{ partial "duoshuo" . }}
            {{ end }}
</code></pre>
<p>注意：一旦用上面多说代码，config.toml中就需要配置duoshuoShortname了：</p>
<pre><code>[params]
    duoshuoShortname = "tonybaicom"
</code></pre>
<h4>4、代码高亮</h4>
<p>Hugo官方说明中采用Pygments来进行<a href="http://gohugo.io/extras/highlighting/">代码高亮</a>的支持，在部署机上安装Pygments，个人觉得这个方法不好。于是换另一外一种js代码法，即采用<a href="http://highlightjs.org">highlightjs</a>的方法支持代码高亮。</p>
<p>highlightjs同样很强大，支持135种语言（关键是支持Golang）和60多种样式（有我喜爱的github样式和monokai_sublime样式），但不支持linenumber。</p>
<p>我们首先将highlightjs下载到本地:</p>
<pre><code>tonybai.com/themes/hyde/static/css/highlight.js/8.8.0/styles/github.min.css
tonybai.com/themes/hyde/static/js/highlight.js/8.8.0/highlight.min.js
</code></pre>
<p>然后在tonybai.com/themes/hyde/layouts/partials/head.html添加如下代码:</p>
<pre><code>    &lt;!-- Highlight.js and css --&gt;
    &lt;script src="{{ .Site.BaseURL }}js/highlight.js/8.8.0/highlight.min.js"&gt;&lt;/script&gt;
    &lt;link rel="stylesheet" href="{{ .Site.BaseURL }}css/highlight.js/8.8.0/styles/github.min.css"&gt;
    &lt;script&gt;hljs.initHighlightingOnLoad();&lt;/script&gt;
</code></pre>
<p>highlightjs会自动检测语言类型，并使用github样式。</p>
<h4>5、统计代码</h4>
<p>提供统计服务的站点，比如statcounter.com一般都会提供安装代码（js）的，将那段代码copy到tonybai.com/themes/hyde/layouts/partials/head.html中即可。</p>
<h3>四、进阶</h3>
<h4>1、index.html、single.html和list.html</h4>
<p>站点的首页模板在themes/hyde/layouts/index.html中。除首页外，其他Post或叫Page，都被Hugo抽象为两类：单体页面和列表页面，对应这两种页面的默认模板都在themes/hyde/layouts/_default中，分别对应着single.html和list.html。</p>
<p>我们之前通过hugo new welcome.md创建的Post使用的是single.html模板，而查看tags或categories的页面默认采用的是list.html，比如查看tonybai.com/categories/golang，你会在浏览器中看到分类在golang这一类的所有Post列表。</p>
<h4>2、type和section</h4>
<p>我们执行如下两个命令：</p>
<pre><code>$hugo new post/firstpost.md
tonybai.com/content/post/firstpost.md created
$hugo new post/secondpost.md
tonybai.com/content/post/secondpost.md created
</code></pre>
<p>创建后我们可以看到站点的源文件结构变成了：</p>
<pre><code>... ...
├── archetypes
├── config.toml
├── content
│   ├── post
│   │   ├── firstpost.md
│   │   └── secondpost.md
│   └── welcome.md
... ...
</code></pre>
<p>hugo中源码文件的布局影响着最终生成的html文件的结构布局。有些时候我们的站点可能会分成若干个部分，每部分通过目录隔离开，比如这里content下的post目录，这样hugo转换后，firstpost.html和secondpost.html也会在public的post目录下。这里的“post”被称为一个section。</p>
<p>hugo会为每个section自动生成index.html页，采用的是index.html模板。</p>
<p>至于是否采用的是hyde/layouts/_default下的list.html，这要看host的匹配order，官方给出的是：</p>
<pre><code>/layouts/section/SECTION.html
/layouts/_default/section.html
/layouts/_default/list.html
/themes/THEME/layouts/section/SECTION.html
/themes/THEME/layouts/_default/section.html
/themes/THEME/layouts/_default/list.html

这个例子中THEME=hyde, SECTION=post
</code></pre>
<p>在本例子中，/layouts/下是空的，不予考虑。/themes/hyde/layouts下没有建立section/post.html模板，/themes/hyde/layouts/_default/section.html也不存在，因此用的是_default/list.html。</p>
<p>hugo官方建议静态站点源码文件按section组织，每个section使用相应(同名）的type，这样section下面的.md就会自动使用响应type的meta data。</p>
<p>当我们hugo new post/firstpost.md时，hugo会到archetypes下找是否有post.md文件，如果有则使用post.md文件的categories和tags来初始化content/post/firstpost.md的元数据，如果没有post.md，则使用archetypes/default.md的。</p>
<h4>3、模板语言</h4>
<p>Hugo使用Golang的模板语法，表达能力很强大；配合Hugo predefined的变量或自定义变量，你可以玩转模板。关于模板内容较多，这里不赘述，需要时查看<a href="http://gohugo.io/templates/go-templates/">官方详细的manual</a>。</p>
<p style='text-align:left'>&copy; 2015, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2015/09/23/intro-of-gohugo/feed/</wfw:commentRss>
		<slash:comments>31</slash:comments>
		</item>
		<item>
		<title>开始使用Markdown写Blog</title>
		<link>https://tonybai.com/2015/09/19/write-blog-in-markdown/</link>
		<comments>https://tonybai.com/2015/09/19/write-blog-in-markdown/#comments</comments>
		<pubDate>Sat, 19 Sep 2015 03:01:10 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[ckeditor]]></category>
		<category><![CDATA[CrayonSyntaxHighlighter]]></category>
		<category><![CDATA[DigitalOcean]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[Go]]></category>
		<category><![CDATA[Golang]]></category>
		<category><![CDATA[jetpack]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Markdown]]></category>
		<category><![CDATA[monaco]]></category>
		<category><![CDATA[monokai]]></category>
		<category><![CDATA[Vim]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[插件]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1862</guid>
		<description><![CDATA[近期发了一些带有大量代码的Go技术文章，结果文章中的代码样式被大家鄙视了，比如评论中的“不忍直视”、“这代码看得让人难受”等。于是我决定花些时间尝试做些改变。 博客系统 目前使用的这个博客系统是放在DigitalOcean VPS的Wordpress 3.2.1。在迁移到VPS之前，我的博客是一直托管在同事的一个托管主机上的，当初从blogbus迁移到他的托管WordPress主机时使用的就是WordPress 3.2.1版本，这两年一直未动，目前WordPress版本都4.3.1了。WordPress 3.2.1有很多bug，尤其是其安全漏洞，今年就被黑过几次，为此在后台将blog纳入git version管理，这样被黑后就可以很容易恢复。但将版本升级到WordPress新版我还是担心的，主要是担心升级失败，尤其是>数据库表变化较大，担心无法恢复。 不过由于历史“负重”太大（900多篇），我很难将WordPress顺利平滑的切换到一些新博客系统，比如golang开发的hugo，Jekyll、Octopress等，只能继续坚守WordPress。 由于经常在文章里贴代码，也曾尝试过使用一些语法高亮的插件，但目前使用的富文本编辑器CKEditor似乎总是与语法高亮不兼容，试了N多都不好用，尤其是在html编辑器和富文本编辑器切换时高亮>部分代码内容被自动转码，于是放弃。这样在文章中只能暂时用Courier New字体来“高亮”代码部分。 Crayon Syntax Highlighter 在尝试之初思路主要还是想找到一款与CKEditor兼容的好用的语法高亮插件，在网上找到一个插件组合：CKEditor + SyntaxHighlighter CKEditor Button + Auto-SyntaxHighlighter。安装后简单>测试了一下发现的确比之前找的几款插件强。输入代码时只需要点击CKEditor工具栏上的一个Code Button，SyntaxHighlighter CKEditor Button会打开一个源码输入对话框，选择源码的语言种类贴入源码即可，还可以在”高级”tab中设置一些选项，是否带行号等。这个组合最大的好处就是无需切换到html编辑器手工输入html tag。 不过测试一段时间后还是发现了这个插件组合的问题，那就是不支持Go语法。Auto-SyntaxHighlighter内部使用的是syntaxhighligter的js，后者已经停止更新，并且即便是最新版本也不支持golang。我只能fork一个Auto-SyntaxHighlighter的repo，并“照猫画虎”的Auto-SyntaxHighlighter增加Go语法文件:shBrushGo-min.js和shBrushGo.js，并修改SyntaxHighlighter CKEditor Button的js文件，增加Go选项。不过try后，发现高亮格式依旧不对，最初以为是我修改的不正确，后来发现即便是用其支持的C/C++代码，高亮格式依旧有问题，我怀疑是与我当前的theme不兼容所致。 在知乎上看到人们都推荐Crayon Syntax Highlighter这个语法高亮插件，于是想最后再尝试一下。安装后发现Crayon Syntax Highlighter的确强大，我将字体设置为monaco, 字号14，主题：monokai，其渲染出来的高亮代码和我在本地mac上的几乎一模一样。不过小问题还是有的，比如: 行号无法去掉，浮动工具栏不好用等。 Crayon插件的最大的问题还是使用不便：需要切换到html源码editor中手工加入： &#60;pre lang:"go"&#62; &#60;/pre&#62; 如果再切换到富文本编辑器后，再切回来， &#60;pre&#62; &#60;/pre&#62; 之间的文本就会被转码，这极大增加了使用门槛。在没有理想办法之前，只能将就着用吧。 以上已经让我折腾我几个小时了，凌晨一点，睡。 Markdown on Save Improved 早上醒来，想到了Markdown，也许是最后稻草了。以前一直以为WordPress版本较低，很多Markdown plugin都不支持。但今天先不管那些了，装上试试。我找到了Markdown on Save Improved，这款插件最大的好处就是可以在每篇文章级别上加markdown开启选项。目前该插件已>经停更，并且其作者基于该插件开发了”Jetpack’s Markdown module”，Jetpack太大，对WordPress版本要求也太高，于是我就选择了”Markdown [...]]]></description>
			<content:encoded><![CDATA[<p>近期发了一些带有大量代码的<a href="http://tonybai.com/2015/09/17/7-things-you-may-not-pay-attation-to-in-go/">Go技术文章</a>，结果文章中的代码样式被大家鄙视了，比如评论中的“不忍直视”、“这代码看得让人难受”等。于是我决定花些时间尝试做些改变。</p>
<h3>博客系统</h3>
<p>目前使用的这个博客系统是放在<a href="https://www.digitalocean.com/?refcode=bff6eed92687">DigitalOcean VPS</a>的Wordpress 3.2.1。在<a href="http://tonybai.com/2014/11/28/migrate-blog-to-digitalocean-vps/">迁移到VPS</a>之前，我的博客是一直托管在同事的一个托管主机上的，当初<a href="http://tonybai.com/2012/02/29/a-new-departure-of-my-blog-move-from-blogbus-to-wordpress/">从blogbus迁移到他的托管WordPress主机</a>时使用的就是WordPress 3.2.1版本，这两年一直未动，目前WordPress版本都4.3.1了。WordPress 3.2.1有很多bug，尤其是其安全漏洞，<a href="http://tonybai.com/2015/04/12/fix-hacked-blog-site/">今年就被黑过几次</a>，为此在后台将blog纳入git version管理，这样被黑后就可以很容易恢复。但将版本升级到WordPress新版我还是担心的，主要是担心升级失败，尤其是>数据库表变化较大，担心无法恢复。</p>
<p>不过由于历史“负重”太大（900多篇），我很难将WordPress顺利平滑的切换到一些新博客系统，比如golang开发的<a href="http://gohugo.io/">hugo</a>，<a href="http://jekyllrb.com/">Jekyll</a>、<a href="http://octopress.org/">Octopress</a>等，只能继续坚守WordPress。</p>
<p>由于经常在文章里贴代码，也曾尝试过使用一些语法高亮的插件，但目前使用的富文本编辑器CKEditor似乎总是与语法高亮不兼容，试了N多都不好用，尤其是在html编辑器和富文本编辑器切换时高亮>部分代码内容被自动转码，于是放弃。这样在文章中只能暂时用Courier New字体来“高亮”代码部分。</p>
<h3>Crayon Syntax Highlighter</h3>
<p>在尝试之初思路主要还是想找到一款与CKEditor兼容的好用的语法高亮插件，在网上找到一个插件组合：<em>CKEditor + SyntaxHighlighter CKEditor Button + Auto-SyntaxHighlighter</em>。安装后简单>测试了一下发现的确比之前找的几款插件强。输入代码时只需要点击CKEditor工具栏上的一个Code Button，SyntaxHighlighter CKEditor Button会打开一个源码输入对话框，选择源码的语言种类贴入源码即可，还可以在”高级”tab中设置一些选项，是否带行号等。这个组合最大的好处就是无需切换到html编辑器手工输入html tag。</p>
<p>不过测试一段时间后还是发现了这个插件组合的问题，那就是不支持Go语法。Auto-SyntaxHighlighter内部使用的是syntaxhighligter的js，后者已经停止更新，并且即便是最新版本也不支持golang。我只能<a href="https://github.com/bigwhite/Auto-SyntaxHighlighter">fork一个Auto-SyntaxHighlighter</a>的repo，并“照猫画虎”的Auto-SyntaxHighlighter增加Go语法文件:shBrushGo-min.js和shBrushGo.js，并修改SyntaxHighlighter CKEditor Button的js文件，增加Go选项。不过try后，发现高亮格式依旧不对，最初以为是我修改的不正确，后来发现即便是用其支持的C/C++代码，高亮格式依旧有问题，我怀疑是与我当前的<a href="https://github.com/pagecho/maupassant">theme</a>不兼容所致。</p>
<p>在知乎上看到人们都推荐<a href="https://github.com/aramk/crayon-syntax-highlighter">Crayon Syntax Highlighter</a>这个语法高亮插件，于是想最后再尝试一下。安装后发现Crayon Syntax Highlighter的确强大，我将字体设置为monaco, 字号14，主题：monokai，其渲染出来的高亮代码和我在本地mac上的几乎一模一样。不过小问题还是有的，比如: 行号无法去掉，浮动工具栏不好用等。</p>
<p>Crayon插件的最大的问题还是使用不便：需要切换到html源码editor中手工加入：<br />
<code>&lt;pre lang:"go"&gt; &lt;/pre&gt;</code></p>
<p>如果再切换到富文本编辑器后，再切回来，</p>
<p><code>&lt;pre&gt; &lt;/pre&gt;</code></p>
<p>之间的文本就会被转码，这极大增加了使用门槛。在没有理想办法之前，只能将就着用吧。</p>
<p>以上已经让我折腾我几个小时了，凌晨一点，睡。</p>
<h3>Markdown on Save Improved</h3>
<p>早上醒来，想到了<a href="http://daringfireball.net/projects/markdown/">Markdown</a>，也许是最后稻草了。以前一直以为WordPress版本较低，很多Markdown plugin都不支持。但今天先不管那些了，装上试试。我找到了<a href="https://wordpress.org/plugins/markdown-on-save-improved/">Markdown on Save Improved</a>，这款插件最大的好处就是可以在每篇文章级别上加markdown开启选项。目前该插件已>经停更，并且其作者基于该插件开发了”Jetpack’s Markdown module”，<a href="https://wordpress.org/plugins/jetpack/">Jetpack</a>太大，对WordPress版本要求也太高，于是我就选择了”Markdown on Save Improved”，满足我使用就可以了。安装插件后，有一个“Markdown on Save Improved Convert to Jetpack”提示，似乎点击一个按钮，就可以将该插件转换为”Jetpack&#8217;s Markdown module”，不过我>也不能肯定，因为从表面上看不出来，没有什么变化。</p>
<p>“Markdown on Save Improved”给我的最大惊喜是它居然兼容Crayon Syntax Highlighter，我将Crayon的默认语言设置为go，这样markdown标记的代码块后者渲染后展现出很理想的高亮效果。</p>
<pre><code>package main

import "fmt"

func main() {
    fmt.Println("Hello, MarkDown and SyntaxHighlighter")
}
</code></pre>
<p>至于Markdown的预览，可以在<a href="https://stackedit.io/editor">stackedit.io</a>上来做。</p>
<p style='text-align:left'>&copy; 2015, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2015/09/19/write-blog-in-markdown/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Blog站点被黑以及问题解决过程</title>
		<link>https://tonybai.com/2015/04/12/fix-hacked-blog-site/</link>
		<comments>https://tonybai.com/2015/04/12/fix-hacked-blog-site/#comments</comments>
		<pubDate>Sun, 12 Apr 2015 01:35:35 +0000</pubDate>
		<dc:creator>bigwhite</dc:creator>
				<category><![CDATA[技术志]]></category>
		<category><![CDATA[apache2]]></category>
		<category><![CDATA[beyondcompare]]></category>
		<category><![CDATA[bitbucket]]></category>
		<category><![CDATA[Blog]]></category>
		<category><![CDATA[DigitalOcean]]></category>
		<category><![CDATA[DO]]></category>
		<category><![CDATA[Dreamhost]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Gmail]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Hacker]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[wordfence]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[安全插件]]></category>

		<guid isPermaLink="false">http://tonybai.com/?p=1708</guid>
		<description><![CDATA[记得前些日子，我在Blog评论里发现有人说我的Blog站点被黑： &#34;YOUR SITE HAS BEEN HACKED &#8211; THERE ARE PARASITE PAGES IN http://tonybai.com/dl SECURE YOUR SITE!!!&#34; 粗浅检查了一番，没有发现什么异常，也就没把这事当回事儿。 昨天上Gmail(由于需要搭梯子，不经常登录)，发现一位网友发来mail说我的站点被入侵了，还附上了google search结果的截图： 接着我也发现了google webmaster发来的mail，同样是警告我的博客站点被黑，并给出了两个可疑URL： http://tonybai.com/dl http://tonybai.com/dl/call-of-duty-4-modern-warfare-crack-download-tpb.html 我自己访问了一下上述URL，我靠！果然被黑了。 以前blog站点无论是搭建在dreamhost上还是朋友的主机上时都未出现过被黑的情况，这次在DO上居然被黑，之前没有解决类似问题的经验，这次只能从头摸索。 看了几篇解决wordpress被黑问题的文章，都推荐先安装几个安全插件对site进行扫描，于是我就试了两个：iThemes Security和Wordfence Security。前者似乎有问题，安装后，dashboard页一片空白。Wordfence Security还好，只是每次scan都无法finish，也就无法得到到底哪些wordpress文件被感染的结果。 插件不可靠，只能自己&#8220;手工&#8221;解决了。 首先到server上利用find , ls等命令对比时间，发现是否有哪些文件的最近访问时间戳与其他文件有差异。不过search了半天，也没发现半点痕迹。 网上还推荐用文件比对工具，比对现在的wordpress文件与backup的文件异同。多亏有backup插件的备份包，于是下载了20150326和20150409的backup zip，使用beyond compare进行目录比对。不比不知道，一比吓一跳啊：index.php文件时间戳相同，但内容居然不同。 0409中的index.php的头部居然多了一段代码： &#60;?php $V3a3xH8=&#34;JQAgHfEmQKV+JuR5Y38ZdWofSxp4PSPn00uzTC &#8230;. &#8230;. ($CdFxbnu0g($nGXNegRe($dvXZv9($cDjofDA))));?&#62; 显然这就是入侵代码了。删除这段代码，重启apache2，试试再访问以下上述那两个URL。结果是令人悲伤的，页面居然还能正常打开和显示。我第一时间想到的是浏览器和apache2的缓存。 强制刷新brower，无用。 查找apache2关于Cache的配置，发现一个：/etc/apache2/mods-available/cache_disk.conf 其内容： &#60;IfModule mod_cache_disk.c&#62; &#160;&#160;&#160;&#160;&#160;&#160;&#160; # cache cleaning is done by [...]]]></description>
			<content:encoded><![CDATA[<p>记得前些日子，我在Blog评论里发现有人说我的Blog站点被黑：</p>
<p><font face="Courier New">&quot;YOUR SITE HAS BEEN HACKED &#8211; THERE ARE PARASITE PAGES IN http://tonybai.com/dl SECURE YOUR SITE!!!&quot;</font></p>
<p>粗浅检查了一番，没有发现什么异常，也就没把这事当回事儿。</p>
<p>昨天上Gmail(由于需要搭梯子，不经常登录)，发现一位网友发来mail说我的站点被入侵了，还附上了google search结果的截图：</p>
<p><img alt="" src="/wp-content/uploads/blog-being-hacked.jpg" style="width: 557px; height: 133px;" /></p>
<p>接着我也发现了google webmaster发来的mail，同样是警告我的博客站点被黑，并给出了两个可疑URL：</p>
<p>http://tonybai.com/dl</p>
<p>http://tonybai.com/dl/call-of-duty-4-modern-warfare-crack-download-tpb.html</p>
<p>我自己访问了一下上述URL，我靠！果然被黑了。</p>
<p>以前blog站点无论是搭建在dreamhost上还是朋友的主机上时都未出现过被黑的情况，这次在DO上居然被黑，之前没有解决类似问题的经验，这次只能从头摸索。</p>
<p>看了几篇解决wordpress被黑问题的文章，都推荐先安装几个安全插件对site进行扫描，于是我就试了两个：iThemes Security和Wordfence Security。前者似乎有问题，安装后，dashboard页一片空白。Wordfence Security还好，只是每次scan都无法finish，也就无法得到到底哪些wordpress文件被感染的结果。</p>
<p>插件不可靠，只能自己&ldquo;手工&rdquo;解决了。</p>
<p>首先到server上利用find , ls等命令对比时间，发现是否有哪些文件的最近访问时间戳与其他文件有差异。不过search了半天，也没发现半点痕迹。</p>
<p>网上还推荐用文件比对工具，比对现在的wordpress文件与backup的文件异同。多亏有backup插件的备份包，于是下载了20150326和20150409的backup zip，使用beyond compare进行目录比对。不比不知道，一比吓一跳啊：<b>index.php文件时间戳相同，但内容居然不同</b>。</p>
<p>0409中的index.php的头部居然多了一段代码：</p>
<p><font face="Courier New">&lt;?php $V3a3xH8=&quot;JQAgHfEmQKV+JuR5Y38ZdWofSxp4PSPn00uzTC</font></p>
<p><font face="Courier New">&#8230;.</font></p>
<p><font face="Courier New">&#8230;.</font></p>
<p><font face="Courier New">($CdFxbnu0g($nGXNegRe($dvXZv9($cDjofDA))));?&gt;</font></p>
<p>显然这就是入侵代码了。删除这段代码，重启apache2，试试再访问以下上述那两个URL。结果是令人悲伤的，页面居然还能正常打开和显示。我第一时间想到的是浏览器和apache2的缓存。</p>
<p>强制刷新brower，无用。</p>
<p>查找apache2关于Cache的配置，发现一个：<font face="Courier New">/etc/apache2/mods-available/cache_disk.conf</font></p>
<p>其内容：<br />
	<font face="Courier New">&lt;IfModule mod_cache_disk.c&gt;</font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # cache cleaning is done by htcacheclean, which can be configured in<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # /etc/default/apache2<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # For further information, see the comments in that file,<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # /usr/share/doc/apache2/README.Debian, and the htcacheclean(8)<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # man page.</font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # This path must be the same as the one in /etc/default/apache2<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CacheRoot <b>/var/cache/apache2/mod_cache_disk</b></font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # This will also cache local documents. It usually makes more sense to<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # put this into the configuration for just one virtual host.<br />
	&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #CacheEnable disk /</font></p>
<p><font face="Courier New">&nbsp;&nbsp;&nbsp; # The result of CacheDirLevels * CacheDirLength must not be higher than<br />
	&nbsp;&nbsp;&nbsp; # 20. Moreover, pay attention on file system limits. Some file systems<br />
	&nbsp;&nbsp;&nbsp; # do not support more than a certain number of inodes and<br />
	&nbsp;&nbsp;&nbsp; # subdirectories (e.g. 32000 for ext3)<br />
	&nbsp;&nbsp;&nbsp; CacheDirLevels 2<br />
	&nbsp;&nbsp;&nbsp; CacheDirLength 1</font></p>
<p><font face="Courier New">&lt;/IfModule&gt;</font></p>
<p>查看CacheRoot，发现/var/cache/apache2/mod_cache_disk下是空的。显然并未缓存。</p>
<p>难道还有其他位置为hacked了？难道0326的backup也是被hack过的？</p>
<p>于是我翻箱倒柜，在电脑里发现了20150101的backup，用这个Backup和0409又对比了一次，这回发现了另外一个被hack的文件：.htaccess。</p>
<p>.htaccess中多了这么一行代码：<br />
	<font face="Courier New">RewriteRule ^dl/(.*)$ wp-add.php [L]</font></p>
<p>原来入侵的人或程序总共在我的主机上做了多处修改，这里总结一下：</p>
<p>1、.htaccess中增加一行规则<br />
	2、添加wp-add.php<br />
	3、修改了index.php<br />
	4、修改了wp-includes/theme-compat/header.php<br />
	5、修改了wp-content/themes/xx/header.php和footer.php</p>
<p>我ls了一下0409下的文件：</p>
<p><font face="Courier New">-rw-r&#8211;r&#8211;&nbsp;&nbsp;&nbsp; 1 tony&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4343 11 28 04:01 wp-activate.php<br />
	<b>-rw-r&#8211;r&#8211;&nbsp;&nbsp;&nbsp; 1 tony&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1991 11 28 04:01 wp-add.php</b><br />
	drwxr-xr-x&nbsp;&nbsp; 89 tony&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3026&nbsp; 4&nbsp; 9 11:00 wp-admin/<br />
	-rw-r&#8211;r&#8211;&nbsp;&nbsp;&nbsp; 1 tony&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp; 40243 11 28 04:01 wp-app.php</font></p>
<p>可以看出入侵代码在添加文件之后，对文件时间做了调整，让简单的时间戳对比无法揪出这个罪魁。</p>
<p>去除以上入侵代码后，上述可以网址就无法访问了。</p>
<p>在google webmaster提交request，期望google 早日将搜索结果中的&quot;<a class="fl" data-href="https://support.google.com/websearch?p=ws_hacked" href="https://www.google.com/url?sa=t&amp;rct=j&amp;q=&amp;esrc=s&amp;source=web&amp;cd=2&amp;ved=0CC0QpwgwAQ&amp;url=https%3A%2F%2Fsupport.google.com%2Fwebsearch%3Fp%3Dws_hacked&amp;ei=7rgpVcXGMYXKmAXt5IHAAQ&amp;usg=AFQjCNH1k7hr1cnoyVQ7hXq1P5Ozrgz7Zw&amp;sig2=eCRkyr4PWwZI7yoAvn5iSw" style="text-decoration: none; color: rgb(26, 13, 171); cursor: pointer; font-family: arial, sans-serif; font-size: small; line-height: 20.0200004577637px;" target="_blank">此网站可能遭到黑客入侵</a>&quot;标签去掉。</p>
<p>之后将密码修改了一遍，希望后续能免疫。</p>
<p>后记：<br />
	根据朋友建议，将blog的文件用git管理起来，并push到bitbucket的private repository中，这样一旦再被hack，恢复起来也较为方便。<br />
	步骤如下：<br />
	<span style="font-family:courier new,courier,monospace;">1、在/var/www目录下git init<br />
	2、git add ./<br />
	3、git commit -m&rdquo;initial import&rdquo; ./<br />
	4、git remote add origin https://user@bitbucket.org/user/blog.git<br />
	5、git push origin master</span></p>
<p style='text-align:left'>&copy; 2015, <a href='https://tonybai.com'>bigwhite</a>. 版权所有. </p>
]]></content:encoded>
			<wfw:commentRss>https://tonybai.com/2015/04/12/fix-hacked-blog-site/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
