<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>tuyafeng&#39;s blog</title>
    <link>https://tuyafeng.com/</link>
    <description>Recent content on tuyafeng&#39;s blog</description>
    <generator>Hugo</generator>
    <language>zh-cn</language>
    <lastBuildDate>Sun, 26 Jan 2025 12:47:47 +0800</lastBuildDate>
    <atom:link href="https://tuyafeng.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Tailscale 组网实践</title>
      <link>https://tuyafeng.com/article/tailscale-practice/</link>
      <pubDate>Wed, 22 Jan 2025 04:16:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/tailscale-practice/</guid>
      <description>引子 自从家里 HomeLab 跑的服务越来越多，我也越来越离不开这个网络环境。赶在过年前，好好研究了组网。过程相对还是轻松的，只是流程多，写篇博客做记录。&#xA;组网和内网穿透 组网，即把不同区域的设备，组到一个虚拟局域网中，在这个虚拟局域网内，设备之间可以互相访问。组网和内网穿透很像，但又不大一样，内网穿透是把内网服务器中的某个服务暴露出去供外网访问，而组网是把整个内网服务器暴露出去。在之前，我一直用 Cloudflare Tunnel 实现内网穿透，也很简单，服务器起一个 cloudflared 服务，再在 Cloudflare 后台添加端口映射规则就好。但是这么做有几个麻烦：&#xA;众所周知，Cloudflare 在国内是个减速器，别说跑满家里上传速度，能稳定访问就很好了； 我通常将内网的服务绑定到局域网域名下。比如内网搭建了一个 FreshRSS 服务，域名为 freshrss.xx.com，但你几乎不可能买到这么简短好记的域名，穿透到公网域名可能是 freshrss.yyyyyy.com，这很麻烦，域名不同会带来很多不必要的负担； 使用 Cloudflare Tunnel 实现穿透有局限性。比如我经常使用 Sunshine + Moonlight 连接到局域网 Windows 游戏机打游戏，这个场景就无法使用穿透实现外网串流，我没找到解决方式； 最后是安全问题。内网服务通常使用弱口令，有些甚至没有鉴权，这些服务暴露到公网都要再套一层 nginx 用于鉴权，麻烦不说，还要多记一个密码。 目前，组网方案已经相当多了，这里就不赘述了，我相信很难有比 Tailscale 更加易用简单的了，它基于 WireGuard 做底层协议，也足够安全，关键是用作个人用途还免费，这还要啥自行车。&#xA;网络环境介绍 让我先简单介绍一下目前家里的网络环境，这里省略一些不必要设备，只大概介绍基本结构。我使用运营商的光猫拨号，连到路由器，路由器下面连接交换机，挂载一台 Debian 服务器、一台 Windows 游戏机及一些其它设备。&#xA;Figure 1: 网络环境示意图&#xA;我个人倾向将不同需求和功能通过硬件分离，方便升级设备。比如路由器就只负责提供 Wi-Fi，服务器只负责跑服务，设备之间互相不耦合，这样即使某个设备出了故障也可以快速恢复，后续升级也更方便些。&#xA;目前，我的 HomeLab 服务器大概跑了四十个服务，几乎所有服务都是绑定到同一个局域网域名下，通过二级域名区分（比如 freshrss.xx.com、nextcloud.xx.com），配合自签证书实现 HTTPS 访问。服务器上还有一个 DNS 服务，实现局域网域名绑定。在需要使用内网服务的设备上，手动安装 HTTPS 证书，设置 DNS，便可以正常访问内网服务。&#xA;所以，我的组网需求就是，当我不在家里时，可以访问家里内网 192.168.x.x 网段，并且同时也可以访问这个局域网域名和这台局域网服务器的所有资源。&#xA;Tailscale 部署 局域网服务器节点配置 首先，在局域网服务器上，通过 Docker Compose 运行 Tailscale 服务，我的 docker-compose.</description>
    </item>
    <item>
      <title>客制化键盘</title>
      <link>https://tuyafeng.com/article/custom-keyboards/</link>
      <pubDate>Sun, 15 Sep 2024 12:50:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/custom-keyboards/</guid>
      <description>引子 今年五月份我开始折腾键盘，陆陆续续买了四五把键盘，从头到尾组过键盘、编译过键盘固件、画过键盘外壳模型，花了不少时间。作这篇博文一是为了分享自己的客制化键盘体验，刚开始折腾键盘时，少见有人主动分享自己的按键设置，也少见各种配列的分享文章，入门只能在群里请教大佬；二也是为了给折腾键盘这事收个尾，工具只是工具，能更好地完成需求就是好工具，再折腾下去对效率提升不大，反而徒增烦恼，故留个记录退烧。&#xA;一 我之前用的键盘是 Anne Pro 2，它是一把蓝牙有线双模连接、60% 配列、不支持热插拔（樱桃红轴）的键盘。我在 2020 年底购置了它，它很好用，我最喜欢它的改键软件 ObinsKit，可以随意指定 fn 的位置，支持按键复用，比如我是 Emacs 用户，又同时使用 Vim，就很喜欢将 CapsLock 按键设置为短按 Esc 长按 Ctrl，省力不少。&#xA;但它实在是有点旧了，电池寿命衰退，蓝牙模式下不打开 RGB 只能使用大概十天左右，轴本身的弹簧音也因为用久了变得很重，所以我在物色新键盘。现在的量产键盘虽卷，却很难挑到满意的，我希望买一把同样是 60% 配列、无旋钮无屏幕，能方便改键的键盘，刷了很久没看到特别心动的。虽然 Anne Pro 2 后面又更新了一代支持热插拔，但还是想体验下新品牌。机缘巧合接触到了 40% 配列，在网上常刷到这个配列效率很高的评论，我很好奇，如果舍弃了数字键、部分符号键，还怎么保持效率呢？这颗小小种子就这样埋在了我心里。&#xA;Figure 1: Anne Pro 2&#xA;二 关注键盘后，发现键盘形式多样，除了配列按键数量的不同，还有直列斜列的区别。我加了一个直列键盘讨论群，在群里了解到了普朗克配列（也即直列，所有按键都是 1u，整齐排列），因为按键大小统一，方方正正，很有美感，另外还了解到了直列分体，比如 46 直列分体键盘，如下图。&#xA;Figure 2: 46 直列分体键盘&#xA;但是这样的键盘还是太小众了，闲鱼上很少有卖家出售，群里也一直没有大佬开车。刷了几天后，我开始考虑另一把键盘，即 crkbd，也称 Corne 键盘。foostan/crkbd 是 GitHub 上一个开源的键盘项目，2018 年诞生，到现在能找到的资源不少。通常来说 Corne 是一把有线分体键盘（也有无线的版本），支持轴体热插拔，带有 RGB 和底灯（v3 版本），左右键盘通过 aux 音频线连接、各有一块屏幕，分体的任意一侧通过数据线连接电脑。当时正好看到闲鱼上一把 Corne 键盘在出售，价格合适，就直接拍下了。&#xA;Figure 3: Corne&#xA;第一次接触到这把键盘的朋友可能会好奇，如此少的按键，怎么使用？其实这些 DIY 键盘都有很成熟的改键方案，比如 Corne 通常使用 QMK 固件，通过 Vial 改键（Vial 是 VIA 改键的分支，此 VIA 非 Via）。像这种 40% 配列的键盘，一般是通过层、按键复用、按键覆写、宏来实现常规键盘的功能。</description>
    </item>
    <item>
      <title>博客从 Hexo 迁移到 Hugo</title>
      <link>https://tuyafeng.com/article/migrate-from-hexo-to-hugo/</link>
      <pubDate>Thu, 21 Mar 2024 23:59:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/migrate-from-hexo-to-hugo/</guid>
      <description>引子 好久没更新博客了，最近正好想把博客迁移到 CloudFlare Pages 上，索性升级下。&#xA;借着迁移的机会，聊聊我折腾博客的经历。我是在 2015 年开始折腾博客，当时距离 Via 已经发布了几个月，我刚好高考结束，时间充裕，天天在弯路群闲聊，认识了不少好友，依稀记得好像是在 sgfox 的帮助下，了解了 DNS 解析和搭建网站这回事。记得第一次搭建博客时，精心挑选了域名 1year.cc，一口气续费了十年（至今还在我的阿里云账户呢），当时觉得 wordpress 太重，用了 Typecho 搭建在虚拟主机上，不过只在搭建最初几天趁着新鲜劲写过几篇文章。2018 年我开始折腾树莓派，对当时的我来说这可真是个新奇玩意，学着搞了不少东西，想着记录一下，决定认真写博客，就又从 Typecho 迁移到了 Hexo，域名也换成了现在这个，断断续续又写了些。一直在折腾，却没留下多少文字，博客就这么一直睡在网络上，像是从未搭建过。如今只剩下这些用以凑数的零碎文章，本想迁移一并删掉，后来还是决定保留做个记录吧。&#xA;搭建 Hugo 博客 搭建过程很简单，跟着官方文档一步步来就好。我用的是 macOS，以下如不做特殊说明都是在 macOS 下操作。&#xA;首先，在本机安装 hugo：&#xA;brew install hugo 接着，创建站点并配置主题：&#xA;# 新建站点到当前目录下的 blog 文件夹 hugo new site blog # 打开 blog 文件夹 cd blog # 从远端下载 ananke 主题 git clone --depth=1 https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke # 将主题添加到配置中 echo &amp;#34;theme = &amp;#39;ananke&amp;#39;&amp;#34; &amp;gt;&amp;gt; hugo.toml # 启动 hugo 服务 hugo server 最后，就可以在浏览器打开 http://localhost:1313 查看了。想部署到服务器的话，使用 hugo 命令，会在 blog 文件夹的 public 目录下输出所有资源，把这个文件夹的所有内容推到服务器就好。更多的用法这里就不说了，官方文档写得很详细。</description>
    </item>
    <item>
      <title>Archives</title>
      <link>https://tuyafeng.com/archives/</link>
      <pubDate>Thu, 21 Mar 2024 23:09:18 +0800</pubDate>
      <guid>https://tuyafeng.com/archives/</guid>
      <description></description>
    </item>
    <item>
      <title>树莓派 CentOS 挂载硬盘</title>
      <link>https://tuyafeng.com/article/mount-hdd-on-raspi/</link>
      <pubDate>Mon, 05 Oct 2020 16:15:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/mount-hdd-on-raspi/</guid>
      <description>有个淘汰下来的笔记本硬盘，正好可以装在树莓派上做扩展用。&#xA;安装依赖 硬盘的文件系统格式是 exFAT，树莓派使用的是 CentOS，默认不支持 exFAT 格式的挂载，需要自己安装相应的支持包。&#xA;安装 fuse-exfat&#xA;以下命令行中链接随时可能失效，可以自己去 rpmfind.net 检索，后文不再赘述。&#xA;wget https://www.rpmfind.net/linux/rpmfusion/free/fedora/releases/28/Everything/armhfp/os/Packages/f/fuse-exfat-1.2.8-2.fc28.armv7hl.rpm sudo yum localinstall fuse-exfat-1.2.8-2.fc28.armv7hl.rpm 安装 exfat-utils&#xA;wget https://www.rpmfind.net/linux/rpmfusion/free/fedora/releases/28/Everything/armhfp/os/Packages/e/exfat-utils-1.2.8-2.fc28.armv7hl.rpm sudo yum localinstall exfat-utils-1.2.8-2.fc28.armv7hl.rpm 挂载硬盘 安装上述两个支持包之后，就可以顺利挂在 exfat 格式的硬盘了。&#xA;sudo fdisk -l # 查看硬盘位置 sudo mkdir /media/hdd # 创建挂载位置 sudo chown lakor:lakor /media/hdd # 变更目录归属，记住替换为自己的用户名 sudo mount -t exfat /dev/sda2 /media/hdd # 挂载硬盘 卸载的话直接 umount，如果提示设备忙就加上 -l 参数：&#xA;sudo umount /media/hdd 配置开机自动挂载 首先复制硬盘对应的 uuid：&#xA;sudo blkid 在 /etc/fstab 末尾加上：&#xA;UUID=****** /media/hdd exfat defaults 0 0 # 将 uuid 填入 配置硬盘自动休眠 硬盘一直挂载树莓派上，虽说不影响硬盘寿命，但是挺吵的，再配置个自动休眠吧。</description>
    </item>
    <item>
      <title>《天朝的崩溃：鸦片战争再研究》札记</title>
      <link>https://tuyafeng.com/article/tian-chao-de-beng-kui-reading-notes/</link>
      <pubDate>Thu, 30 Jul 2020 15:34:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/tian-chao-de-beng-kui-reading-notes/</guid>
      <description>鸦片战争一直因其作为中国近代史的开端而被反复提及，内容却几乎总是老生常谈，过分注重高屋建瓴，自上而下地讲述。这本书则侧重人物命运和历史现象本身，属于十分客观的一本论述。&#xA;两千年来，中国因其地理位置和资源的优势，虽时有战乱而偶有式微，但不久总能重兴，这种延续性，使得中国一直是亚洲文化圈的核心，同样影响了身在其中的人物思想，诞生了中国中心主义。在该理想主义下，中国的帝王是天子，王朝是天朝上国，其他民族和中国的关系是贡国和属国的关系，其首领只能被称为王。在东亚历史中，除游牧民族组织的部落制国家，很少有周边小国能挑战中国在东亚外交的统治地位的例子。这种自信，是深入当时人人共识的，这个背景十分重要，如何强调也不为过，今日或许还有圆月之谬谈，可鸦片战争前只有四海之外皆蛮夷，上层理论一直在完善着诸如「天子处中国以治万邦」之类的观念，这种自信是仅难从「天朝上国」之类只言片语的描述中具象出的，作者在书前篇几乎不厌其烦地累述。这种自信影响着清朝的方方面面，例如清朝虽有统有军队八十万，但目的也只是为了防止内部叛乱，驻扎十分分散，平时训练也多流于形式。至于武器装备方面，在康熙年间平定三藩、收复雅克萨城后，因处于长久的相对和平阶段，其武器装备在西北、西南边疆及内地也能保持优势，而使得清朝对武器装备的重点在垄断装备技术而非研制新武器。除却军事方面，其他也皆相似，一如作者陈述：&#xA;但是，由于文化背景的不同，英国最先进的事物，经过儒家教义的折光，顿时变为最荒谬不堪的东西。君主立宪，在皇权至上面前，有如大臣擅权；经商贸易，在农本主义面前，显为舍本求末；追逐利润，在性理名教面前，只是小人之举；至于女王主位、男女不辨，更是牝鸡司晨之类的“夷俗”；即便令人兴叹的西方器物（钟表、玻璃、呢羽等），享用赏玩收藏之余，仍可斥之为“坏人心术”的“奇技淫巧”。&#xA;而关于鸦片战争，矛盾的是，在我们总体承认失败在于中国的落伍，清王朝昧于世界大势；具体叙述却又认定只要坚持抵抗便可取胜，认为如果林则徐等人的主张得以实施，中国便还有救。皇权至上的社会中，认定天子圣明不应犯错，人们对政治的批判，最多也只能到大臣一级，传统史学让奸臣承担责任，皇帝不过只是用人不周。这又使得鸦片战争当中官员又成了旧有道统的替罪羊。一面是战争的不敌现实，一面是传统的性名理学，使得夹在其中的官员将领颇难行事，「桀骜不驯的“逆夷”不肯就“抚”，九重之上的道光帝不愿俯首，前者以兵势迫之，后者以权势压之。」当中官员便层层欺骗，九重之上的皇帝蒙在鼓里，不见事实。&#xA;值得一提的是，鸦片战争爆发后不久，日本也发生了黑船事件，次年德川幕府在武力胁迫下，无丝毫抵抗接受了美方条件，被迫开国，之后十几年，除割地赔款外，和中国相差无几。但日本唱着「惊破太平梦，彻夜不能眠」的狂歌，发生了历史上最重大的转折，明治维新。清朝未得梦醒，只是依旧如故，不免使人愤然。&#xA;历史已成烟，令人欣慰的是，事情并没有白白发生。</description>
    </item>
    <item>
      <title>《日本世相系列：饱食穷民》札记</title>
      <link>https://tuyafeng.com/article/bao-shi-qiong-min-reading-notes/</link>
      <pubDate>Wed, 29 Jul 2020 22:11:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/bao-shi-qiong-min-reading-notes/</guid>
      <description>《日本世相》共十二册，属纪实文学，记录日本二十世纪七十年代到九十年代间普通人的生活点滴。在这期间，日本经济发展迅速，世间一片繁华，个人却焦虑空虚，宛如资本机器快速运作，扮演各自角色，如果现实如此，那日本的资本主义究竟是什么 ，这便是作者斋藤茂男的思考。&#xA;书中纪实即使放到今日之中国，也不见违和，我随意摘录几处见下：&#xA;比如，可以看看第二章中一九八八年采访的计算机技术人员们的加班时间。根据统计数据显示，日本人的年度总劳动时间要比当时的德国人多五百四十七个小时，而这一差距在一九八九年也达到四百个小时以上。&#xA;设定这个上限（加班时间）的目的，并非让员工早些下班回家休息，而是为了解决经营上面临的一大难题——限制加班费的支出。&#xA;“缺少‘储蓄’的不安，还有另一层意义。打个比方，一个熟练工花一辈子时间磨炼出来的车床手艺，也许一夜之间就会被计算机化的数控车床所取代。一个人从根本上赖以生存的最终手段——技术、技能、知识、判断能力，也许一夜之间就会被彻底推翻。现代人心中的这种不安，都在日渐膨胀。”&#xA;关于日本泡沫景气的文字，实在不胜枚举，但又各不相似，这本书侧重点在时代下的个人。在经济快速向上的发展中，人人争先忙忙碌碌，仿佛工作机器，如此忙碌，使得无暇它顾，又只得投身其中，推动历史的进程。“终身役役而不见其成功，苶然疲役而不知其所归，可不哀邪！”叔本华在《人生的智慧》中将人命运的根本差异化作三类，一是人的自身，包括健康、力量、外貌、道德、智慧等；二是人所拥有的身外物，意即财富；三是他人的评价，包括名誉、地位和名望。后两类带来的幸福是脆弱而短暂的，而在人人忙碌追求六便士的时代，无人得闲抬头看月。书中所提家庭或个人，极少表现出幸福，大多如作者所说，只在扮演他人所以为的幸福模样。&#xA;我很早接触编程，所以对书中一个旁支观点尤其留意。作者并非技术人员，但却提出了一个「关于人的思想逐渐被计算机同化」的有趣问题。几千年前，人类驯服水稻，从某种意义上来说，水稻也同样驯服人类，获得了进化的胜利。计算机的发展也有其相似处，计算机、网络等技术因冷战结束，得以从军用下放到民用，时至今日，早已渗入个人生活，成为基础建设了，人类驯服了计算机，计算机是否也在某种意义上驯服了人类呢？计算机是逻辑关系的世界，非黑即白。如何写出顶级程序呢？自然是当人愈发理解计算机，愈加成为计算机，像计算机一般思考，似乎便有了可能，我们学习硬件，了解各类底层协议，工作原理，无非如此。“其分也，成也；其成也，毁也。”我不愿成为计算机。</description>
    </item>
    <item>
      <title>《反脆弱：从无序和不确定中获益》札记</title>
      <link>https://tuyafeng.com/article/antifragile-things-that-gain-from-disorder-notes/</link>
      <pubDate>Fri, 29 May 2020 14:52:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/antifragile-things-that-gain-from-disorder-notes/</guid>
      <description>什么是脆弱，是在意外面前不堪一击，脆弱不喜欢意外。一般提到脆弱的反义词，往往想到的是强韧，强韧不代表不脆弱，只代表在意外面前不那么不堪一击，强韧和脆弱从某种程度来看是相似的，都不太喜欢意外。那有没有什么词可以代表事物喜欢意外的特性呢？很遗憾，没有，所以，作者 Taleb 创了个新词，即反脆弱(antifragile)。&#xA;脆弱害怕意外，喜欢平稳的外部环境，如果外部环境不平稳，那就尽可能预测它，预测之后制定策略干预它，妄图使得意外变成意料之中。这里有两个问题，一个是如何精准地预测，一个是如何精明地干预。世界真的可预测吗？世界如此随机，变量复杂到远远超出我们能做出预测的程度，预测是天真的。既然如此，我们怎么可能基于对未来的错误预测做出精明地干预呢。作者提了一个我觉得非常棒的关于预测的例子，「风险管理专业人士往往通过回顾历史来推断所谓的最糟情境，并据此估计未来的风险，这种方法被称为“压力测试”。他们往往将历史上最糟糕的经济衰退、最惨烈的战争、最不利的利率波动或最低的失业率作为对未来最糟糕形势的精确估计。但是，他们从来没有注意到以下矛盾：这个所谓的最糟形势在发生时，已经超越了当时历史的最糟形势。可是，这个关键的逻辑却被忽略了。」同样的，天真的干预也可以用一个简单的例子来说明，「小森林的定期火灾清洗了这个系统中最易燃的树木，令其没有机会继续繁衍。而系统性地预防森林火灾以确保“安全”的措施，却将导致下一场火灾的程度更加惨重。」&#xA;教鸟儿如何飞行是愚蠢的，我们不会因为教授了鸟儿飞行的相关理论后鸟儿扑翅起飞，而误认为鸟儿能在空中飞行是因为事先学习了理论。实践和理论也存在这样的矛盾，我们并不是将理论付诸实践，我们是在实践中创造理论，就像大多数学科的基本认识都是基于实验得出的一样。「进化不依靠叙述故事，只有人类才需要；进化也不需要为“蓝色”指定一个称谓。」知道什么是错的，远比知道什么是对的更有价值，太多看似正确的知识，只会让我们忽略了基本的东西，更何况当下正确的事情，极有可能在未来被推翻，而错误的知识，却不那么容易变得正确。我们不需要了解所有信息以保证事事正确，只要保证不做明显错误的不明智的事情。就像那个农夫所说，我只想知道将来我会死在什么地方，这样我就不去那儿了。&#xA;时间是脆弱性最好的证明。脆弱的东西，在长久的时间面前，无论如何干预，总是逃不过消逝的命运。我们的地球已经运转了约 40 亿年，这是依靠强韧性无法做到的。只有时间颠扑不破的东西，才是属于我们永远需要的东西。「非自然的东西需要证明其利益，但自然的事物则不需要——根据我们早先阐述的统计原理，大自然比人类更少让我们上当。在一个复杂的领域，只有时间——很长的时间——才能成为证据。」&#xA;有一类不太道德的事是通过牺牲他人的可选择性来获益的。诚如作者所论述，「现代化的最严重问题在于，脆弱性和反脆弱性从一方向另一方的恶意转移，也就是说，只有一方受益，而另一方却（不知不觉地）受害。」此类行为诸如医源性损伤，任何依靠妄图做出精确预测谋生的人带来的问题，等等。这部分受限于篇幅，浅显归纳易导致断章取义而带来误导，还是去看看书中具体的论证吧。&#xA;两年前当我意识到过载的信息只会徒增焦虑后便不再关注噪声了，这让我的生活简单轻松了很多（但不得不说的是，这种改变让我感觉现在的自己像个严肃的小老头 orz），在我如此行动后，我看到了作者在《随机漫步的傻瓜》中提到的类似的观点（生活中充满噪声），深以为然，看这本书也是因为这个作者看的，我实在太认可他的观点了（诸如随机的世界，不可预测的未来），作者看待问题的角度很新奇，也很带有启发性。</description>
    </item>
    <item>
      <title>About</title>
      <link>https://tuyafeng.com/about/</link>
      <pubDate>Wed, 15 Apr 2020 02:09:15 +0800</pubDate>
      <guid>https://tuyafeng.com/about/</guid>
      <description>2005 年，乔布斯在斯坦福大学毕业典礼上的演讲说，「你不可能充满预见地将生命的点滴串联起来；只有在你回头看的时候，你才会发现这些点点滴滴之间的联系。所以，你要坚信，你现在所经历的将在你未来的生命中串联起来。你不得不相信某些东西，你的直觉、命运、生活、因缘际会…… 正是这种信仰让我不会失去希望，它让我的人生变得与众不同。」&#xA;碎片化的当下，媒介众多，信息却冗余而散乱，博客是一个可以畅快发声而不至于被随手可得的信息压得喘不过气的静谧角落，我在这里记录思考，记录经历，记录琐碎，也记录点滴。&#xA;你可以通过下列方式联系我：&#xA;发邮件 Github </description>
    </item>
    <item>
      <title>Android MVVM 实践</title>
      <link>https://tuyafeng.com/article/android-mvvm-practice/</link>
      <pubDate>Wed, 15 Apr 2020 00:24:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/android-mvvm-practice/</guid>
      <description>在经历了 android 项目 MVC 架构的万能 Activity 维护的困扰和 MVP 架构的令人头大的复杂接口之后，我打算尝试 MVVM，一开始是通过阅读 android 官方的 应用架构指南 入门，看完之后认为 MVVM 或许是个不错的解决方案。（如果没有阅读过官方的应用架构指南的话，强烈建议阅读一遍，官方文档写得很好也很透彻，看完之后会对 MVVM 架构会有个大致的认识。）&#xA;入门 大多数谈到架构的博客都会用登录页面举例，但是，实际的开发过程中怎么可能是这么简单的项目，这未免不现实，如果你真能通过一个登录页面的实例就能清晰地理解这个架构，那我觉得你可能不看那些博客也能理解。我是通过 android 官方的 architecture-samples 来学习的。接下来我会结合着这个项目简单谈谈我对 MVVM 的认知。&#xA;一般来说，应用的开发从数据开始，数据的来源有很多，有本地数据库的缓存，也有云端的真实数据，或者开发环境的测试数据。这些都是我们的数据源 (Data Source)，为了方便我们测试和变更数据源，我们用数据仓库来管理数据源 (Data Repository)，有了数据仓库，我们还需要一个桥梁来让界面 (Activity/Fragment) 获取仓库数据，这个桥梁就是 ViewModel。在 MVVM 中，数据是中心，界面围绕数据去变动，落到实现层面，也就是 LiveData，官方称其为「可观察的数据存储器」，应用中的其他组件通过它来监控对象的变更。这样，ViewModel 中持有 LiveData，界面监听这些 LiveData 的变化来动态响应，这样就形成了 MVVM 的核心思想，就像官方文档中给出的这幅图：&#xA;例如，在官方给出的 TODO 应用的实例中，数据部分的代码：&#xA;// Data Source interface TasksDataSource { suspend fun getTasks(): Result&amp;lt;List&amp;lt;Task&amp;gt;&amp;gt; suspend fun getTask(taskId: String): Result&amp;lt;Task&amp;gt; suspend fun saveTask(task: Task) suspend fun completeTask(task: Task) suspend fun completeTask(taskId: String) suspend fun activateTask(task: Task) suspend fun activateTask(taskId: String) suspend fun clearCompletedTasks() suspend fun deleteAllTasks() suspend fun deleteTask(taskId: String) } // Data Repository interface TasksRepository { suspend fun getTasks(forceUpdate: Boolean = false): Result&amp;lt;List&amp;lt;Task&amp;gt;&amp;gt; suspend fun getTask(taskId: String, forceUpdate: Boolean = false): Result&amp;lt;Task&amp;gt; suspend fun saveTask(task: Task) suspend fun completeTask(task: Task) suspend fun completeTask(taskId: String) suspend fun activateTask(task: Task) suspend fun activateTask(taskId: String) suspend fun clearCompletedTasks() suspend fun deleteAllTasks() suspend fun deleteTask(taskId: String) } // Data Repository 实现 class DefaultTasksRepository @Inject constructor( @TasksRemoteDataSource private val tasksRemoteDataSource: TasksDataSource, @TasksLocalDataSource private val tasksLocalDataSource: TasksDataSource, private val ioDispatcher: CoroutineDispatcher = Dispatchers.</description>
    </item>
    <item>
      <title>《影响力》札记</title>
      <link>https://tuyafeng.com/article/influence-reading-notes/</link>
      <pubDate>Sat, 28 Mar 2020 19:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/influence-reading-notes/</guid>
      <description>如果说《思考，快与慢》是行为决策理论层面的内容，这本《影响力》就是具象层面了。「互惠、承认和一致、社会认同、喜好、权威、稀缺」，作者总结得很具体，人毕竟是社会动物，在交流碰撞中，产生了一些社会约定俗成的规则，诚如作者所言，「这种策略给我们指明正确方向的可能性高于出错的可能性，我们可以把认知精力节省下来，去应付生活里铺天盖地的其他信息，作出更合理的决定」。当然，这些捷径也会被人利用，当被误导时，抵抗捷径是必要的。&#xA;这本书的大名如雷贯耳了，之前听说芒格第一次阅读到本书之后，便给他的每个孩子寄了一本，还送了作者一股伯克希尔的股票，因此初看时对书的期望太高，再加上之前看了《思考，快与慢》这样更贴近我口味的系统书籍，对这本书的感触反而不是特别深刻。</description>
    </item>
    <item>
      <title>《思考，快与慢》札记</title>
      <link>https://tuyafeng.com/article/thinking-fast-and-slow-reading-notes/</link>
      <pubDate>Sat, 28 Mar 2020 17:40:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/thinking-fast-and-slow-reading-notes/</guid>
      <description>最早其实是在《随机漫步的傻瓜》里第一次了解到这本书，当时便决定看看，作为 2020 年第一本书来说相当不错，理论系统，逻辑严密，论据充分，也难怪被各类相关书籍引用。顺带一提，当初看《穷查理宝典》中的人类误判心理学，感触颇深，但始终觉得受限于篇幅，表述过少，这本书为行为决策做了系统全面的阐述，很适合做深读。作者丹尼尔·卡尼曼也获得了 2002 年诺贝尔经济学奖，实至名归。&#xA;《思考，快与慢》全书系统地阐述了关于系统1和系统2的理论，及两种系统在生活中如何作用以影响决策。简言之，在物种进化的过程中，为应付周遭环境变化及威胁，需要快速反应，这种与生俱来的本能反应便是系统1，系统1是无意识且高效快速的，但依赖经验和记忆，记忆并不是线性保存在我们的脑海中的，系统1偏见因此存在。系统2是用来处理需要注意力参与的活动的，慵懒且耗费精力。思考时，大多情况是系统1先给出结论，系统2来怀疑并校验，一旦校验完成，我们便相信这个结论并且深信，如果之后出现不一致我们会偏向修正而不是推倒原有结论。系统1总是优先触发的，那么如果碰到了系统1难以应付的困难问题怎么办，用简单的问题替代咯（比如「你这些天对生活满意吗」会被替换为类似「我现在心情如何」），系统1还有一个巨大的局限，即我们无法关闭它。由此衍生的，我们不擅长处理统计学，总是高估低概率事件和看重小样本事件。由系统1和系统2的交互作用，影响了我们日常行为的方方面面。系统1和系统2的理论，为我们带来了很多行为发生的理论基础。&#xA;非常赞的书，受益匪浅，后悔这么晚才看到，也庆幸自己看完了。</description>
    </item>
    <item>
      <title>树莓派安装 ArchLinuxArm</title>
      <link>https://tuyafeng.com/article/install-archlinux-arm-on-raspi/</link>
      <pubDate>Sat, 28 Dec 2019 20:40:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/install-archlinux-arm-on-raspi/</guid>
      <description>为了在树莓派上使用 ArchLinuxArm 需要花些功夫，如果对 Linux 不是特别熟练的话推荐还是使用官方的 Raspbian 系统。&#xA;安装 ArchLinuxArm 必须在 Linux 系统下进行，如果你使用 macOS/Windows，可以通过安装 VirtualBox 再在 VirtualBox 中安装虚拟机来对内存卡操作。&#xA;安装 VirtualBox VirtualBox 官方下载链接：https://www.virtualbox.org/wiki/Downloads&#xA;国内清华大学镜像站点下载：https://mirror.tuna.tsinghua.edu.cn/help/virtualbox/&#xA;推荐使用清华大学的镜像下载，速度会快非常多。下载完成之后安装即可，安装比较简单，一路确定即可。&#xA;在 VirtualBox 中安装 CentOS7 我安装 CentOS 的目的就是为了给内存卡装系统，所以安装 Minimal 版本就可以了。&#xA;CentOS7 Minimal 下载链接：http://isoredirect.centos.org/centos/7/isos/x86_64/&#xA;推荐选择下载链接中的阿里云镜像，速度比较快。&#xA;下载完镜像后，打开VirtualBox，点击新建，名称CentOS7，版本选择 Other Linux(64-bit)，之后分配内存，创建虚拟硬盘（动态分配，8G）。&#xA;点击启动，选择刚刚下载的 iso 镜像，然后启动，启动之后，选择屏幕上的第一项 Install CentOS 7，之后进入安装系统页面，这里注意几个地方：1. 在网络和主机名中打开以太网，2. 设置 root 密码。进度条跑完之后点击重启。（话说既然都准备在树莓派上装 Arch 了，这些东西应该已经没啥问题了吧。）&#xA;添加扩展以支持虚拟机读取连接到电脑的读卡器。&#xA;打开 VirtualBox 扩展页面：https://download.virtualbox.org/virtualbox/。选择和你安装的客户端一样的版本号，下载文件名为 Oracle_VM_VirtualBox_Extension_Pack-&amp;lt;version&amp;gt;.vbox-extpack 的扩展包，在 VirtualBox 设置的扩展设置中添加，之后重启 VirtualBox。&#xA;本地 ssh 连接虚拟机(可选)&#xA;为了让我们的电脑可以通过 ssh 连接虚拟机，还需要做些配置。如果嫌麻烦跳过直接在虚拟机操作也行，我主要是因为嫌弃虚拟机操作体验割裂还有字体的不适应。&#xA;macOS：&#xA;如果你像我一样 mac 是通过 Wi-Fi 连接网络的，就这么设置。点击菜单栏的管理，进入主机网络管理器，点击创建，保持默认就行，然后保存关闭。</description>
    </item>
    <item>
      <title>记换行导致的爬虫错误</title>
      <link>https://tuyafeng.com/article/spider-error-caused-by-line-breaks/</link>
      <pubDate>Wed, 28 Aug 2019 20:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/spider-error-caused-by-line-breaks/</guid>
      <description>在最近的 python 爬虫中，爬取的 html 中有这样的数据段需要提取：&#xA;&amp;lt;a href=&amp;#34;http://www.example.cn/demo.htm&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;标题&amp;lt;/a&amp;gt; &amp;lt;span class=&amp;#34;date&amp;#34;&amp;gt;2019.10.27 &amp;lt;/span&amp;gt; （注：复制到文档时因为编辑器缘故将制表符替换为空格了，其实行之间为制表符）&#xA;刚开始处理时，因为对正则的不熟练，直接硬匹配：&#xA;pattern = r&amp;#39;&amp;lt;a href=&amp;#34;(.*?)&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;(.*?)&amp;lt;/a&amp;gt;\n\t{8}\n\t{9}\n\t{9}\n\t{10}&amp;lt;span class=&amp;#34;date&amp;#34;&amp;gt;(.*?) &amp;lt;/span&amp;gt;&amp;#39; 但是在爬取时出现了问题，即首次爬取 html 源码时匹配不出数据，但等到第二次往后从缓存中读取时，数据就能正常返回了。&#xA;思考了很久，有两个怀疑的原因：1. 爬取网页后直接使用的变量和从文件读取出的文本变量的数据类型不同；2. 换行符在 Windows 和 macOS 系统中不同导致的问题。&#xA;第一个怀疑比较好验证，在合适的时候使用 typeof 即可，但我认为换行符的嫌疑更大，所以没具体测试。&#xA;第二个将原先正则替换为 &amp;lt;a href=&amp;quot;(.*?)&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;(.*?)&amp;lt;/a&amp;gt;\r\n\t{8}\r\n\t{9}\r\n\t{9}\r\n\t{10}&amp;lt;span class=&amp;quot;date&amp;quot;&amp;gt;(.*?) &amp;lt;/span&amp;gt; （即将原先的 \n 换为 \r\n）时进行测试，果然，数据可以正常爬取了。&#xA;在查阅资料的过程中，也了解到了另一个匹配关键词，即 \s，其可匹配任意空白符号，包括空格制表符等等，所以最后的正则如下：&#xA;pattern = r&amp;#39;&amp;lt;a href=&amp;#34;(.*?)&amp;#34; target=&amp;#34;_blank&amp;#34;&amp;gt;(.*?)&amp;lt;/a&amp;gt;\s{40,44}&amp;lt;span class=&amp;#34;date&amp;#34;&amp;gt;(.*?) &amp;lt;/span&amp;gt;&amp;#39; All done.</description>
    </item>
    <item>
      <title>树莓派安装 CentOS</title>
      <link>https://tuyafeng.com/article/install-centos-on-raspi/</link>
      <pubDate>Wed, 28 Aug 2019 15:40:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/install-centos-on-raspi/</guid>
      <description>首先下载 CentOS 镜像，下载地址：mirror.centos.org&#xA;文件名带 RaspberryPi 的就是了，因为我的树莓派是放在家里当服务器用的，不需要桌面环境，所以我选择了 Minimal。&#xA;使用 Etcher 将系统刷入即可。工具下载地址为：Etcher。选择下载好的镜像文件，接着选择 TF 卡路径，之后便可直接写入。（Etcher 支持 xz 后缀的文件镜像）&#xA;也可以使用 macOS 命令行刷写系统：&#xA;diskutil list # 获取 sd 卡设备名，我的是 /dev/disk2 diskutil umount `mount | grep &amp;#34;&amp;lt;设备文件名&amp;gt;&amp;#34; | awk &amp;#39;{print $3}&amp;#39;` #卸载已挂载的分区，记得将设备文件名替换，例如我的是 diskutil umount `mount | grep &amp;#34;/dev/disk2&amp;#34; | awk &amp;#39;{print $3}&amp;#39;` sudo dd if=/path/to/centosimg of=/path/to/sdcard # 这里先把之前下载的镜像文件解压，之后 dd 写入 sdcard，我的是 dd if=/Users/lakor/Downloads/CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1908-sda.raw of=/dev/disk2 之后将内存卡插入树莓派。&#xA;连接树莓派 $ ssh root@your_raspi_ip 其中，your_raspi_ip 是你的树莓派 ip 地址，登入路由器后台可以看到，默认密码是 centos。&#xA;调整分区容量 使用 df -h 可以看到当前系统只有 2G 容量。</description>
    </item>
    <item>
      <title>记一次 Django 项目优化</title>
      <link>https://tuyafeng.com/article/django-performance-optimization/</link>
      <pubDate>Tue, 04 Sep 2018 22:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/django-performance-optimization/</guid>
      <description>把之前的一个 web 项目重写了一遍，语言从原先的 PHP 换成 Python，使用了 Django 框架。项目因为数据库比较庞大，有 600M 左右的 sql 数据，一些应用涉及到查询和修改时，导致网页操作十分缓慢。同时因为也是刚开始接触 Django，有些代码写得比较蠢，后来优化之后网页操作的速度基本可以接受。故写这篇文章记录一下。&#xA;模版自定义函数 因为数据库设计原因，从数据库提取出来的某个字段的数据还需要经过一次 base64 加密，原先是将筛选出来的 QuerySet 用 for 循环去遍历然后修改。但是，如果直接用 for 循环去遍历 QuerySet，Django 会把他们全部进行实例化，因为数据量本身也比较大的原因，会导致占用大量的内存。&#xA;因为我希望在不修改数据库和尽可能少的改动代码的前提下去解决问题，一番查阅资料之后发现自定义 Django 模版的函数是个不错的办法。&#xA;Django 模板里面有两种方式来自定义函数，分别是 simple_tag 和 filter 方式。实现的方式如下。&#xA;在对应 app 下创建一个名为 templatetags 的目录（不可修改目录名），在这个目录下创建一个名字任意的 py 文件，在这个 py 文件里导入模板类，实例化一个对象 register，然后执行一个相应的装饰器即可，文件代码如下：&#xA;from django import template from django.utils.safestring import mark_safe register = template.Library() @register.simple_tag def base64en(s): return base64.b64encode(s.encode(&amp;#39;utf-8&amp;#39;)).decode(&amp;#34;utf-8&amp;#34;) @register.filter def tobase64(s): return base64.b64encode(s.encode(&amp;#39;utf-8&amp;#39;)).decode(&amp;#34;utf-8&amp;#34;) 其中，base64en（simple_tag 方式） 和 tobase64（filter 方式） 是我自定义的函数。在模版文件里调用：</description>
    </item>
    <item>
      <title>树莓派关闭板载 Wi-Fi 及蓝牙</title>
      <link>https://tuyafeng.com/article/diable-wifi-and-bt-on-raspi/</link>
      <pubDate>Thu, 16 Aug 2018 21:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/diable-wifi-and-bt-on-raspi/</guid>
      <description>在文件 /boot/config.txt 后追加：&#xA;dtoverlay=pi3-disable-bt dtoverlay=pi3-disable-wifi 重启生效：&#xA;sudo reboot </description>
    </item>
    <item>
      <title>树莓派搭建 Git 服务器</title>
      <link>https://tuyafeng.com/article/deploy-git-server-on-raspi/</link>
      <pubDate>Sun, 05 Aug 2018 16:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/deploy-git-server-on-raspi/</guid>
      <description>需要在 vps 上搭建 Git 服务器，先在树莓派测试一下。&#xA;安装依赖 sudo apt-get install git-core 创建用户 这里为树莓派创建一个 git 用户，方便局域网内其他用户使用同时将 git 服务器文件与 pi 用户数据隔离开来。命令行如下：&#xA;adduser --system --shell /bin/bash --gecos &amp;#39;git version control by pi&amp;#39; --group --home /home/git git adduser --system --shell /bin/bash --comment &amp;#39;git version control&amp;#39; --user-group --create-home /home/git git 更改 git 密码：&#xA;passwd git 现在就可以切换到 git 用户：&#xA;su git 初始化仓库 git 用户负责 git 项目的管理，所有仓库我存放在 /home/git 中，这里我们初始化一个空仓库（记住是在切换到 git 用户之后）：&#xA;cd /home/git mkdir test.git cd test.git git --bare init 使用仓库 以上树莓派服务端配置完成后，我们就可以在本地客户端使用仓库了。</description>
    </item>
    <item>
      <title>树莓派开启 bbr 加速</title>
      <link>https://tuyafeng.com/article/enable-tcp-bbr-on-raspi/</link>
      <pubDate>Thu, 26 Jul 2018 10:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/enable-tcp-bbr-on-raspi/</guid>
      <description>先升级内核确保版本在 4.9 以上：&#xA;sudo rpi-update 之后开启 bbr 加速：&#xA;sudo bash -c &amp;#39;echo &amp;#34;net.core.default_qdisc=fq&amp;#34; &amp;gt;&amp;gt; /etc/sysctl.conf&amp;#39; sudo bash -c &amp;#39;echo &amp;#34;net.ipv4.tcp_congestion_control=bbr&amp;#34; &amp;gt;&amp;gt; /etc/sysctl.conf&amp;#39; sudo sysctl -p sudo reboot 重启后检查看看：&#xA;sysctl net.ipv4.tcp_available_congestion_control #输出：net.ipv4.tcp_available_congestion_control = bbr cubic reno lsmod | grep bbr #输出：tcp_bbr 20480 1 </description>
    </item>
    <item>
      <title>Via 定制进阶</title>
      <link>https://tuyafeng.com/article/customize-about-via/</link>
      <pubDate>Mon, 25 Jun 2018 20:36:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/customize-about-via/</guid>
      <description>Via 浏览器是一个定制性相当强的 android 浏览器，即使是技术上的「麻瓜」也可以通过「设置」-「定制」选项轻松实现自己满意的效果，但是，好奇如你，自然希望了解一些进阶玩法，将 Via 浏览器从「大家的浏览器」变成「专属于你的浏览器」，这篇教程便是为此而生。&#xA;HTML 代码 适当调整「设置」-「定制」-「Logo」-「Html 代码」也可以达到不错的效果。我们可以利用 Html 代码轻松实现一些特殊效果。以下效果直接复制粘贴代码至设置项即可用。&#xA;粗体文字 logo：&#xA;&amp;lt;span style=&amp;#34;font-size: 40px; font-weight: bold; text-transform:uppercase;&amp;#34;&amp;gt;cool&amp;lt;/span&amp;gt; 一言：&#xA;&amp;lt;span style=&amp;#34;font-size: 16px; font-weight: bold;&amp;#34;&amp;gt;&amp;lt;script type=&amp;#34;text/javascript&amp;#34; src=&amp;#34;https://api.lwl12.com/hitokoto/main/get?encode=js&amp;amp;charset=utf-8&amp;#34;&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;div id=&amp;#34;lwlhitokoto&amp;#34;&amp;gt;&amp;lt;script&amp;gt;lwlhitokoto()&amp;lt;/script&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/script&amp;gt;&amp;lt;/span&amp;gt; 天气：&#xA;&amp;lt;span style=&amp;#34;font-size: 25px; font-weight: bold;&amp;#34; id=&amp;#34;weather&amp;#34;&amp;gt;&amp;lt;script&amp;gt;function ajax(a){a=a||{};a.method=a.method.toUpperCase()||&amp;#34;POST&amp;#34;;a.url=a.url||&amp;#34;&amp;#34;;a.async=a.async||!0;a.data=a.data||null;a.success=a.success||function(){};var b=null;b=XMLHttpRequest?new XMLHttpRequest:new ActiveXObject(&amp;#34;Microsoft.XMLHTTP&amp;#34;);var c=[],d;for(d in a.data)c.push(d+&amp;#34;=&amp;#34;+a.data[d]);c=c.join(&amp;#34;&amp;amp;&amp;#34;);&amp;#34;POST&amp;#34;===a.method.toUpperCase()?(b.open(a.method,a.url,a.async),b.setRequestHeader(&amp;#34;Content-Type&amp;#34;,&amp;#34;application/x-www-form-urlencoded;charset=utf-8&amp;#34;),b.send(c)):&amp;#34;GET&amp;#34;===a.method.toUpperCase()&amp;amp;&amp;amp;(b.open(a.method, a.url+&amp;#34;?&amp;#34;+c,a.async),b.send(null));b.onreadystatechange=function(){4==b.readyState&amp;amp;&amp;amp;200==b.status&amp;amp;&amp;amp;a.success(JSON.parse(b.responseText))}}ajax({method:&amp;#34;GET&amp;#34;,url:&amp;#34;http://api.jirengu.com/getWeather.php&amp;#34;,success:function(a){console.log(a);now=document.getElementById(&amp;#34;weather&amp;#34;).innerHTML=a.results[0].weather_data[0];e=document.getElementById(&amp;#34;weather&amp;#34;);now&amp;amp;&amp;amp;(e.innerHTML=now.weather+&amp;#34;(&amp;#34;+now.temperature+&amp;#34;)&amp;#34;)}});&amp;lt;/script&amp;gt;&amp;lt;/span&amp;gt; 注，天气代码经过压缩，以下为更易二次修改的未压缩代码：&#xA;&amp;lt;span style=&amp;#34;font-size: 25px; font-weight: bold;&amp;#34; id=&amp;#34;weather&amp;#34;&amp;gt;&amp;lt;script&amp;gt; function ajax(opt) { opt = opt || {}; opt.method = opt.method.toUpperCase() || &amp;#39;POST&amp;#39;; opt.url = opt.url || &amp;#39;&amp;#39;; opt.async = opt.</description>
    </item>
    <item>
      <title>树莓派部署 Syncthing 实现私有云</title>
      <link>https://tuyafeng.com/article/deploy-syncthing-on-raspi/</link>
      <pubDate>Mon, 25 Jun 2018 20:16:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/deploy-syncthing-on-raspi/</guid>
      <description>手机上存着不少照片，自己又时常折腾手机，总有数据丢失的问题，又对市面上的云盘不怎么放心，所以打算在家里利用树莓派搭建一个私有云。一番查找之后，发现了 Syncthing。Syncthing 是一个跨平台，开源且免费的基于 P2P 的文件同步解决方案，支持 Windows，Mac，Linux，Android，Syncthing 官方暂不支持iOS平台，但在 AppStore 有可用的第三方客户端。&#xA;安装 Syncthing 首先需要获取最新版本的下载链接，打开官方 Github 项目的发布页。因为树莓派的 CPU 是 ARM 架构，所以我们需要文件名类似 syncthing-linux-arm-xxxxx.tar.gz 的下载链接，右键复制链接即可。我查看时，最新链接为：https://github.com/syncthing/syncthing/releases/download/v0.14.49-rc.2/syncthing-linux-arm-v0.14.49-rc.2.tar.gz。&#xA;接下来通过 SSH 连接到树莓派，并获取文件，命令行如下：&#xA;cd ~ wget https://github.com/syncthing/syncthing/releases/download/v0.14.49-rc.2/syncthing-linux-arm-v0.14.49-rc.2.tar.gz tar -zxvf syncthing-linux-arm-v0.14.49-rc.2.tar.gz 命令执行完成后，文件便下载解压完成了，为了便于操作，我们重命名下文件夹：&#xA;mv syncthing-linux-arm-v0.14.49-rc.2 syncthing chmod +x ~/syncthing/syncthing 部署 Syncthing 安装完成后，我们先运行一下：&#xA;~/syncthing/syncthing 这时会输出一些提示信息，我们可以等待两分钟让它自行初始化。&#xA;接着，我们开始修改配置文件以便局域网访问：&#xA;nano ~/.config/syncthing/config.xml 找到如下内容：&#xA;&amp;lt;gui enabled=&amp;#34;true&amp;#34; tls=&amp;#34;false&amp;#34;&amp;gt; &amp;lt;address&amp;gt;127.0.0.1:8384&amp;lt;/address&amp;gt; &amp;lt;apikey&amp;gt;XXXXXX&amp;lt;/apikey&amp;gt; &amp;lt;/gui&amp;gt; 将 127.0.0.1:8384 修改为 0.0.0.0:8384，之后 ctrl+o 回车保存，ctrl+x 退出编辑。&#xA;开机自启 这里参考了在树莓派上用 Syncthing 自建私有云盘的实现。&#xA;树莓派上执行命令：&#xA;sudo nano /etc/init.d/syncthing 粘贴如下内容：&#xA;#!/bin/sh ### BEGIN INIT INFO # Provides: Syncthing # Required-Start: $local_fs $remote_fs $network # Required-Stop: $local_fs $remote_fs $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Syncthing # Description: Syncthing is for backups ### END INIT INFO # Documentation available at # http://refspecs.</description>
    </item>
    <item>
      <title>Via 自定义主页</title>
      <link>https://tuyafeng.com/article/homepage-about-via/</link>
      <pubDate>Mon, 25 Jun 2018 19:36:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/homepage-about-via/</guid>
      <description>「不要重复造轮子」是大多数人的共识，同样的，Via 浏览器在酷安的评论区有着非常多热心友善的用户分享着自己的自定义主页，这里我们通过一个实例了解怎么使用自定义主页。（注：这里使用了酷安@Rainbow_Star 的素材并做了部分修改）&#xA;效果图 使用 下载文件：&#xA;链接:pan.baidu.com 密码:526b&#xA;以下为使用 Root Explorer 操作，其他文件管理器类同，操作步骤为：&#xA;打开下载文件所在的文件夹 解压文件并打开解压的文件夹 找到 html 文件（homepage.html） 长按该文件，选择「打开方式」-「应用」-「Via」，此时会调用 Via 打开文件 这时点击 Via 地址栏并复制该地址，粘贴到「设置」-「常规」-「主页」-「网页」 如果觉得以上方案繁琐，也可以：&#xA;更改路径file:///storage/emulated/0/&amp;lt;Extracted&amp;gt;/homepage.html，将 &amp;lt;Extracted&amp;gt; 部分替换为你解压文件存放的路径，并将该路径粘贴到「设置」-「常规」-「主页」-「网页」。&#xA;修改 解压文件后，编辑其中的 html 文件（homepage.html）即可，如果需要删除某个导航链接，删除如下相关代码即可：&#xA;&amp;lt;div class=&amp;#34;box&amp;#34;&amp;gt; &amp;lt;a href=&amp;#34;https://www.coolapk.com/apk&amp;#34;&amp;gt;&amp;lt;/a&amp;gt; &amp;lt;p&amp;gt;&amp;lt;img class=&amp;#34;icon&amp;#34; src=&amp;#34;img/酷安.png&amp;#34; &amp;gt;&amp;lt;/p&amp;gt; &amp;lt;p class=&amp;#34;url&amp;#34;&amp;gt;酷安&amp;lt;/p&amp;gt; &amp;lt;/div&amp;gt; 添加的话也是类似，将以上代码复制一份并修改相关内容（网页链接、图片链接、文字）。&#xA;总结 总之，使用酷友们提供的自定义主页的方式总结下来便是：&#xA;下载并解压压缩包 使用via打开其中的 html 文件，得到 html 文件路径 将得到的 html 文件路径复制到「设置-通用-主页-网页」中 编辑 html，根据需求修改代码（可选） 以上。</description>
    </item>
    <item>
      <title>树莓派部署 Django 项目</title>
      <link>https://tuyafeng.com/article/deploy-django-project-on-raspi/</link>
      <pubDate>Tue, 15 May 2018 18:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/deploy-django-project-on-raspi/</guid>
      <description>人生苦短，快用 python。因为刚刚接触到 django，实现项目之后，对部署不太熟悉，所以在树莓派上尝试一下。文中教程 Linux 通用。&#xA;部署概览 我们采用 nginx + uwsgi 的方案进行部署。整个系统架构图如下：&#xA;环境配置 首先需要安装 virtualenv 为其提供独立的环境，命令行如下：&#xA;pip3 install virtualenv 创建并生成环境，我的项目名为 demo，我决定将它放置在 /home/pi/www/demo 下，命令行如下：&#xA;cd ~/www/demo python3 -m virtualenv --no-site-packages venv 激活环境命令为：&#xA;source venv/bin/activate 注：激活环境后，输入命令的指示标志前会变成类似 (venv) pi@raspberrypi:~/www/demo $。&#xA;退出当前环境命令为：&#xA;deactivate django 项目配置 环境配置好后，便可以准备项目的上传。该部分的所有命令皆是在激活虚拟环境（source venv/bin/activate）之后进行。&#xA;(1). 在编写 django 项目的测试机器上，进入项目根目录（存着 manage.py 文件的目录），cd 到该目录，之后运行如下命令生成扩展库信息列表：&#xA;pip freeze &amp;gt; requirements.txt (2). 把 django 项目整个传到树莓派上，项目根目录（manage.py 同级目录）下的全部文件全部复制到树莓派项目目录，复制之后，情况大概是这样：&#xA;(venv) pi@raspberrypi:~/www/demo $ ls demo guestbook manage.py requirements.txt venv (3). 安装扩展库，记住在激活的环境下执行，命令行如下：&#xA;pip3 install -r requirements.</description>
    </item>
    <item>
      <title>树莓派使用 frp 实现内网穿透</title>
      <link>https://tuyafeng.com/article/access-raspi-everywhere-with-frp/</link>
      <pubDate>Thu, 26 Apr 2018 20:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/access-raspi-everywhere-with-frp/</guid>
      <description>如果没有公网ip，但又想随时随地都能连接到树莓派，我们可以使用 frp 来实现。&#xA;准备条件 我们需要一台 vps，以便做转发的服务端。&#xA;服务端配置 - frps frp 的服务器端，一般名为 frps，配置文件是 frps.ini。可以在 frp 官方页面 获取到最新版本的下载链接（此处以 frp_0.17.0_linux_amd64 为例）。接着使用 ssh 登录 vps 端操作，命令行如下：&#xA;wget https://github.com/fatedier/frp/releases/download/v0.17.0/frp_0.17.0_linux_amd64.tar.gz tar -zxvf frp_0.17.0_linux_amd64.tar.gz cd frp_0.17.0_linux_amd64 nano frps.ini 配置文件内容如下：&#xA;[common] bind_port = 7000 vhost_http_port = 80 dashboard_port = dashboard_port_number dashboard_user = dashboard_user_name dashboard_pwd = dashboard_pwd_value privilege_token = privilege_token_value ctrl+o 保存，之后 回车 确认，然后 ctrl+x 退出。&#xA;参数说明&#xA;bind_port：绑定的端口，需要与客户端中 server_port 参数保持一致 vhost_http_port：虚拟主机运行在本机的端口，如果 vps 有服务占用了端口，应当更换 dashboard_port：frp 后台服务页面的端口，如果设置 8000，便可通过 http://yourip:8000 来访问 frps 的后台页面 dashboard_user：frp 后台服务页面的管理员用户名 dashboard_pwd：frp 后台服务页面的管理员密码 privilege_token：自定义值，必须与客户端中的 privilege_token 保持一致 配置完成之后，便可以通过如下命令启动 frps：</description>
    </item>
    <item>
      <title>树莓派搭建 DNS 服务器</title>
      <link>https://tuyafeng.com/article/make-raspi-a-dns-server/</link>
      <pubDate>Sat, 14 Apr 2018 19:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/make-raspi-a-dns-server/</guid>
      <description>自建 DNS 服务器，可以规避运营商的 DNS 劫持，还可以一定程度上加速网络访问。除此之外，在自定一些配置之后，能实现广告拦截及其他的一些功能。在这里我们通过在树莓派使用 dnsmasq 搭建这样一个 DNS 服务器。&#xA;安装 dnsmasq sudo apt-get install dnsmasq 配置 dnsmasq 首先备份一下原配置文件，命令行如下：&#xA;sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.bak 接着编辑配置文件，命令行如下：&#xA;sudo vi /etc/dnsmasq.conf 这里，我们首先按下 esc 进入命令模式，然后使用快捷键 yddG 清空文件，之后使用 i 进入插入模式，ctrl+v 粘贴如下配置内容，粘贴完成后按下 esc，最后使用 :wq 保存文件：&#xA;resolv-file=/etc/my_dns.conf strict-order cache-size=10000 listen-address=127.0.0.1,192.168.1.37 address=/pi.com/192.168.1.37 其中 192.168.1.37 为树莓派的局域网 ip，address=/pi.com/192.168.1.37 是为了测试规则并将树莓派上的网站解析到 pi.com 。&#xA;其余各项解释：&#xA;resolve-file：定义 dnsmasq 的上游DNS服务器，默认是 /etc/resolv.conf。但是 resolv.conf 在每次树莓派重启后就会被系统重置，因此我们指定 resolve-file 文件 strict-order：表示严格按照 resolv-file 文件中的顺序从上到下进行DNS解析 listen-address：定义 dnsmasq 监听的地址，默认是监控本机的所有网卡上。为使局域网其他设备得以使用需要加上树莓派的局域网 ip cache-size：缓存条数 address：自定义域名解析的 ip 地址，以 pi.com 这个域名为例。也可以在其他文件中配置，配置文件放在 /etc/dnsmasq.</description>
    </item>
    <item>
      <title>树莓局 aria2 远程下载</title>
      <link>https://tuyafeng.com/article/make-raspi-a-remote-downloader-with-aria2/</link>
      <pubDate>Wed, 28 Mar 2018 15:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/make-raspi-a-remote-downloader-with-aria2/</guid>
      <description>安装 aria2 aira2 官方仓库：https://github.com/aria2/aria2/&#xA;静态编译 ARM 树莓派：https://github.com/q3aql/aria2-static-builds/releases&#xA;也可以使用软件源安装：sudo apt install -y aria2 创建配置文件：&#xA;mkdir -p ~/.config/aria2/ nano ~/.config/aria2/aria2.conf 配置文件，建议根据 aria2 配置 按需填写，以下为极简配置(请自行替换几个路径)：&#xA;# 后台运行 daemon=true # 断点续传 continue=true # Aria2 退出时保存错误/未完成的下载任务到会话文件（必须为全路径） save-session=/home/lakor/.config/aria2/aria2.session # 定时保存会话, 0为退出时才保存, 默认为 0 save-session-interval=60 # 强制保存会话, 默认:false force-save=true # 启用RPC, 默认:false enable-rpc=true # 允许所有来源, 默认:false rpc-allow-origin-all=true # 允许非外部访问, 默认:false rpc-listen-all=true # 事件轮询方式, 取值:[epoll, kqueue, port, poll, select], 不同系统默认值不同 #event-poll=kqueue # RPC监听端口, 端口被占用时可以修改, 默认:6800 #rpc-listen-port=6800 # 设置的RPC授权令牌, v1.</description>
    </item>
    <item>
      <title>树莓派局域网文件共享</title>
      <link>https://tuyafeng.com/article/share-files-on-lan-with-raspi/</link>
      <pubDate>Wed, 28 Mar 2018 15:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/share-files-on-lan-with-raspi/</guid>
      <description>树莓派局域网文件共享的方案，一般来说有两种，WebDav 和 Samba，两者的传输速度都相差不大，而 WebDav 在文件上传上问题会多些，还是更推荐 Samba。&#xA;安装 Samba samba 的安装很简单，命令行执行：&#xA;sudo apt-get install samba samba-common-bin 配置 Samba 配置文件为/etc/samba/smb.conf，这里对它进行修改，命令行执行：&#xA;sudo nano /etc/samba/smb.conf 注：nano 可以通过 ctrl+y（上一页） 和 ctrl+v（下一页） 实现翻页。&#xA;在文件末尾加上如下内容，其中 /mnt/udisk 为我设置的共享文件夹目录（将其替换为你想共享的目录即可，例如：/home/pi/public）：&#xA;[public] comment = Public Storage path = /media/udisk valid users = pi read only = no create mask = 0644 directory mask = 0755 guest ok = no browseable = yes ctrl+o 保存，之后 回车 确认，然后 ctrl+x 退出。&#xA;参数说明：&#xA;comment：共享文件夹说明 path：共享文件夹目录 valid users：有效用户 read only：是否只读 create mask：创建文件的权限 directory mask：创建文件夹的权限 guest ok：是否允许访客访问 browseable：是否可见 其中 valid users 即 pi 为有效用户，还需要添加其到 Samba 中，命令行执行：</description>
    </item>
    <item>
      <title>树莓派挂载 U 盘</title>
      <link>https://tuyafeng.com/article/mount-udisk-on-raspi/</link>
      <pubDate>Wed, 28 Mar 2018 13:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/mount-udisk-on-raspi/</guid>
      <description>因为我的树莓派后来用的系统是 CentOS，没法轻松地挂载 exfat 格式的 U 盘 (arm 生态缘故)，考虑到是个不常用的 U 盘，干脆格式化做 ext4 格式，就一直挂载在树莓派上当扩展用了。&#xA;查看硬盘标识：&#xA;sudo fdisk -l 查看硬盘格式：&#xA;sudo blkid 格式化硬盘为 ext4 格式 (注意替换盘符为你获取到的)：&#xA;sudo mkfs.ext4 /dev/sda1 挂载硬盘，首先创建挂载目录：&#xA;sudo mkdir /media/udisk # udisk 可自定 sudo chown pi:pi /media/udisk 挂载：&#xA;sudo mount -t ext4 /dev/sda1 /media/udisk 卸载直接 umount 即可，如果提示设备忙就加上 -l 参数：&#xA;sudo umount /media/udisk 开机自动挂载：&#xA;sudo blkid # 复制 uuid 备份 fstab：&#xA;sudo cp /etc/fstab /etc/fstab.bak 在 /etc/fstab 末尾加上：&#xA;UUID=****** /media/udisk ext4 defaults 0 0 # 将 uuid 填入 </description>
    </item>
    <item>
      <title>树莓派更新源更换</title>
      <link>https://tuyafeng.com/article/change-raspbian-update-sources/</link>
      <pubDate>Mon, 26 Mar 2018 12:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/change-raspbian-update-sources/</guid>
      <description>树莓派默认更新源访问速度很慢，换成国内源速度会有很大提升。&#xA;网上常见的教程往往都是替换软件更新源（/etc/apt/sources.list），实际上还存在一个系统更新源（/etc/apt/sources.d/raspi.list）。我们对这两个文件进行修改，将其中的源网址更换为国内镜像站点即可。&#xA;备份原文件 命令行执行：&#xA;sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo cp /etc/apt/sources.list.d/raspi.list /etc/apt/sources.list.d/raspi.list.bak 修改文件 此处更换为中科大站点，地址如下：&#xA;http://mirrors.ustc.edu.cn/raspbian/raspbian/ http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ 先修改软件更新源，命令行执行：&#xA;sudo nano /etc/apt/sources.list 将文件首行中网址修改即可，修改后文件如下：&#xA;deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ stretch main contrib non-free$ # Uncomment line below then &amp;#39;apt-get update&amp;#39; to enable &amp;#39;apt-get source&amp;#39; #deb-src http://archive.raspbian.org/raspbian/ stretch main contrib non-free rpi ctrl+o 保存，之后 回车 确认，然后 ctrl+x 退出。&#xA;再修改系统更新源，命令行执行：&#xA;sudo nano /etc/apt/sources.list.d/raspi.list 同样修改首行网址，修改后文件如下：&#xA;deb http://mirrors.ustc.edu.cn/archive.raspberrypi.org/debian/ stretch main ui # Uncomment line below then &amp;#39;apt-get update&amp;#39; to enable &amp;#39;apt-get source&amp;#39; #deb-src http://archive.</description>
    </item>
    <item>
      <title>树莓派系统安装</title>
      <link>https://tuyafeng.com/article/install-system-for-raspi/</link>
      <pubDate>Sun, 25 Mar 2018 10:20:00 +0800</pubDate>
      <guid>https://tuyafeng.com/article/install-system-for-raspi/</guid>
      <description>系统写入 Raspbian 系统下载页面: Raspbian&#xA;这里因为个人当作服务器使用，通过 ssh 连接来管理，不需要图形界面，所以选择的是 RASPBIAN STRETCH LITE，下载完成之后将 img 镜像写入 TF 卡。&#xA;Windows / macOS / Linux：&#xA;Etcher 是一个更加现代的 TF 卡写入工具。通过 Etcher 可以很简单的完成写入操作。工具下载地址为：Etcher。&#xA;选择镜像，选择 TF 卡路径之后便可直接写入。&#xA;配置 ssh 刷入系统后，不用着急取出 TF 卡，我们先允许树莓派启用 ssh。Windows 和 macOS 用户可以打开树莓派 TF 卡文件夹（Linux 用户打开 TF 卡中名称为 boot 且内存较小的主分区），在 TF 卡根目录放置一个名为 ssh 的空白文件（注：无后缀名）。&#xA;配置网络 推荐使用网线连接，树莓派在 Wi-Fi 信号以及网络速度方面并不是特别理想。如果确认使用网线连接则可以跳过这一部分了。&#xA;如果希望通过 Wi-Fi 连接网络，则在根目录在放置一个名为 wpa_supplicant.conf 的文件，文件内容如下：&#xA;country=CN ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1 network={ ssid=&amp;#34;WiFi-A&amp;#34; psk=&amp;#34;12345678&amp;#34; key_mgmt=WPA-PSK priority=1 } network={ ssid=&amp;#34;WiFi-B&amp;#34; psk=&amp;#34;12345678&amp;#34; key_mgmt=WPA-PSK priority=2 scan_ssid=1 } 其中，</description>
    </item>
  </channel>
</rss>
