<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>游钓四方</title><description>骑过湖边的小径，走过文字里的角落，偶尔停下，看见风，也看见自己</description><link>https://blog.lhasa.icu</link><item><title>三脚架到货了</title><link>https://blog.lhasa.icu/posts/technology/2026-01-27-fotopro-x-aircross-3-lite</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2026-01-27-fotopro-x-aircross-3-lite</guid><pubDate>Mon, 26 Jan 2026 16:17:00 GMT</pubDate><content:encoded>&lt;p&gt;早上九点，顺风打电话来：&quot;快递到了，放前台了啊。&quot; 估摸着是那三脚架到了&lt;/p&gt;
&lt;p&gt;这东西没有真不行，晚上出门一抹黑，不用长曝光，啥都拍不了&lt;/p&gt;
&lt;p&gt;我有三个需求：&lt;strong&gt;轻量化、收纳短、伸缩1.5m&lt;/strong&gt;，再三选择后，下单了富宝图旗下新品，&lt;strong&gt;空气三号 LITE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;图一拆包后，我直接蒙了&lt;/p&gt;
&lt;p&gt;周日在群里扯淡，看到 &lt;a href=&quot;http://loonlog.com&quot;&gt;菜鸟之志&lt;/a&gt; 推荐的八爪鱼支架，我笑了，这什么玩意，长得那么招笑&lt;/p&gt;
&lt;p&gt;真的受够了这种秒懂的日子&lt;/p&gt;
&lt;p&gt;还别说，这工具不错，小巧，轻便，灵活度很高，推荐&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260126204642_1069_266.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;20260126204650_1070_266.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;20260126204702_1071_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;八爪鱼是送的，但图三这个快拆套装我感觉买亏了。加了一百块钱，就换回这么一小块铁片，关键脚架本身就带一个&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260126204733_1072_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;出门前纠结了半天要不要背双肩包，最后想想算了，索性直接挂在包拉链上了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260126205104_1075_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;有没有一种&lt;strong&gt;吕布骑狗&lt;/strong&gt;的感觉，我这破尼康配上这个架子，多少有点高攀了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260126204843_1073_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260126205401_1077_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260126205326_1076_266.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;20260126205435_1078_266.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;20260126231122_1080_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天全程下雨，走在西湖边吹冷风，冻得头疼&lt;/p&gt;
&lt;p&gt;回家发现买的电池也到了，价格方面，只有原装的二分之一，应该够我折腾了&lt;/p&gt;
&lt;p&gt;天知道这支架是哪个小作坊代工的，漆水和碳布的质量，不敢苟同，我最垃圾的鱼竿，破烧火棍的碳纤维材料都比这个强，不如高性能的铝材料，甚至不如玻璃钢&lt;/p&gt;
&lt;p&gt;他的旋转设计也有缺陷，不容易锁紧，又不敢用力拧，因为碳布根本受不了这种扭矩，哪怕你有交叉工艺，也顶不住，这不符合物理规律&lt;/p&gt;
&lt;p&gt;再加上碳纤维这东西本身就是消耗品，树脂会氧化。三脚架这玩意，风吹雨打的，扭矩承受力只会越来越差。网上已经看到不少人把它拧断了，总之不推荐&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%89%E8%84%9A%E6%9E%B6%E5%88%B0%E8%B4%A7%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2026-01-27-fotopro-x-aircross-3-lite&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>MySQL 要没落了</title><link>https://blog.lhasa.icu/posts/technology/2026-01-24-mysql</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2026-01-24-mysql</guid><pubDate>Fri, 23 Jan 2026 21:50:00 GMT</pubDate><content:encoded>&lt;p&gt;这两天突发奇想，在赶一个新项目&lt;/p&gt;
&lt;p&gt;从早上 8 点写到晚上 11 点，除了去卫生间，人基本没动过，饭也没吃&lt;/p&gt;
&lt;p&gt;这不是我多能坐得住，我只是&lt;strong&gt;倔&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;妄想一步登天，做不完就死磕。十几个小时是日常，通宵是常态，哪个月没有 4～5 次 20h + 作战记录？&lt;/p&gt;
&lt;p&gt;GitHub Commits 一眼就能看出来：我从凌晨提交到凌晨，电子厂的狗都不会这么干&lt;/p&gt;
&lt;p&gt;也许这就是倔驴 + 心流？&lt;/p&gt;
&lt;p&gt;而我，&lt;strong&gt;天生心流圣体&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;老实说，我对“心流”没概念，只是前阵子偶然了解到。所以我并不明白，但我知道那是一种状态&lt;/p&gt;
&lt;p&gt;当然，不吃饭是不行的&lt;/p&gt;
&lt;p&gt;晚上 11:30，厨房炒个菜，微波炉热两个馒头，回屋再冲一大杯黑咖啡，两勺燕麦，少许牛奶，就算齐活&lt;/p&gt;
&lt;p&gt;坐回电脑前，打开 BlogFinder，随手一翻，看到了阮一峰的周刊&lt;/p&gt;
&lt;p&gt;心想，周五了&lt;/p&gt;
&lt;p&gt;低头再看，周六了&lt;/p&gt;
&lt;p&gt;然后，我看到了他的第一个推荐文章，心里“咯噔”一下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://optimizedbyotto.com/post/reasons-to-stop-using-mysql/&quot;&gt;2026 年，请停止使用 MySQL：它已不再是真正的开源项目&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;点进去，翻译看看，整篇文章的核心观点就是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;如果你在意开源软件，就应该停止使用 MySQL&lt;/p&gt;
&lt;p&gt;MySQL 虽然是基于 GPL v2 开源，实际上已经没有开源精神，因为 MySQL 正走向封闭&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;开发活跃度呈现断崖式下跌&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;mysql-github-commits-decreasing-2025.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是 Otto 在 1 月 11 日给出的截图&lt;/p&gt;
&lt;p&gt;数据显示，从去年 9 月开始，到今年 1 月 11 日，MySQL 几乎&lt;strong&gt;完全断更&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;我看到这里，第一反应是去查官方信息 &lt;a href=&quot;https://dev.mysql.com/blog-archive/&quot;&gt;MySQL 核心团队博客&lt;/a&gt;，无果后，再 Google 一下，事情就对上了&lt;/p&gt;
&lt;p&gt;早在 &lt;strong&gt;9 月 11 日&lt;/strong&gt;，外媒就曝出 &lt;a href=&quot;https://www.theregister.com/2025/09/11/oracle_slammed_for_mysql_job/&quot;&gt;Oracle 大幅裁减 MySQL 核心员工 (约 70 人) &lt;/a&gt;的消息，甚至还有传闻称，MySQL 团队已被并入 HeatWave 部门，Oracle 要把资源优先投入 AI&lt;/p&gt;
&lt;p&gt;新闻刚出来时，MySQL 还没断更&lt;/p&gt;
&lt;p&gt;现在再把这张“断崖式提交图”放出来，那可谓是&lt;strong&gt;深水炸弹&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;更有意思的是，Otto 还特意把图做成黑白，再配上大字标语当封面&lt;/p&gt;
&lt;p&gt;手段可见一斑，毕竟，这人是 &lt;a href=&quot;https://en.wikipedia.org/wiki/MariaDB&quot;&gt;MariaDB Foundation (玛利亚数据库基金会)&lt;/a&gt; CEO&lt;/p&gt;
&lt;p&gt;而 MariaDB 是 MySQL 的最重要的分支与直接竞争者&lt;/p&gt;
&lt;p&gt;当年 Oracle 宣布收购 Sun Microsystems 的当天，MySQL 原始作者之一 &lt;strong&gt;Monty Widenius&lt;/strong&gt; 就发起了 MariaDB fork&lt;/p&gt;
&lt;p&gt;有意思的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MariaDB：是以 Monty 的小女儿玛丽亚 (Maria) 的名字命名&lt;/li&gt;
&lt;li&gt;MySQL ：则以大女儿 (My) 命名&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;就连 MariaDB 的 LOGO 海狮，也是有故事背景的&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://mariadb.org/sea-lion/&quot;&gt;The Story of our Sea Lion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It happened when Monty and his older daughter My were snorkeling on one of the islands in the &lt;strong&gt;Galapagos&lt;/strong&gt;. Something big, brown and fast suddenly appeared at an arm’s distance, laughing in their faces. Fond memories of this fast and funny creature, scaring the tourists, popped into Monty’s mind when asked picking a logo for MariaDB. He wanted to adhere to the tradition of &lt;strong&gt;animals&lt;/strong&gt; as symbols of Open Source projects.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;the-story-of-our-sea-lion.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h3&gt;闭门造车&lt;/h3&gt;
&lt;p&gt;下面是 Otto  的举证，他认为 MySQL 所有开发工作都在 Oracle 内部进行&lt;/p&gt;
&lt;p&gt;而公开的 Bug 追踪器只是个摆设，Oracle 内部有自己的系统&lt;/p&gt;
&lt;p&gt;更离谱的是，他声称：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;那些提交 PR 的人，除了石沉大海，就只剩下第二个选择&lt;/p&gt;
&lt;p&gt;被 Oracle 员工重新编写并抹去原作者的贡献记录，原作者仅在博客中被提及其名&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Otto 还证言道：&lt;/p&gt;
&lt;p&gt;我在 AWS 负责 RDS MySQL 和 MariaDB 团队时，部门员工极其抗拒向 MySQL 提交代码，因为Oracle 的接纳态度极其恶劣&lt;/p&gt;
&lt;h3&gt;技术倒退&lt;/h3&gt;
&lt;p&gt;MySQL 8.0.29 将 &lt;code&gt;ALTER TABLE&lt;/code&gt; 的默认行为改为 &lt;strong&gt;in-place&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://forums.mysql.com/read.php?22,704532,704532#msg-704532&quot;&gt;结果导致大量生产环境数据库崩溃、数据损坏&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;而这个问题，直到 &lt;a href=&quot;https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-32.html&quot;&gt;8.0.32&lt;/a&gt; 才算彻底修完&lt;/p&gt;
&lt;p&gt;更大的问题在于：&lt;/p&gt;
&lt;p&gt;自 MySQL 8.0 发布以来，整整六年，没有一次真正意义上的大版本更新，几乎没有像样的功能可以讲&lt;/p&gt;
&lt;p&gt;甚至，有传言新版本的 MySQL 性能大幅下降，之后被 MySQL 性能专家 &lt;a href=&quot;https://smalldatum.blogspot.com/&quot;&gt;Mark Callaghan&lt;/a&gt; 进行基准测试后得出&lt;a href=&quot;https://smalldatum.blogspot.com/2025/12/performance-regressions-in-mysql-84-and.html&quot;&gt;MySQL 9.5 的吞吐量比 8.0 版本竟然低了 15%&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;最后，Otto 顺势给出了“迁移方案”：&lt;/p&gt;
&lt;p&gt;说自家的 MariaDB 作为 MySQL 的亲兄弟，有极高的兼容性，对于传统 LAMP 架构，可以无缝切换&lt;/p&gt;
&lt;p&gt;他说得也没错，MariaDB 起源于 MySQL 5.1 分支，早期开发策略几乎完全对标 MySQL，以至于后来被开源社区认可，尤其在 Debian、Ubuntu、Fedora 等发行版中，直接成为默认数据库&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;db-engines-ranking-mysql-going-down.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;说实话，我已经不想看下去了，我只是个普通人，一个喜欢编程的小学生&lt;/p&gt;
&lt;p&gt;从初一第一次接触数据库开始，就是 MySQL&lt;/p&gt;
&lt;p&gt;从上学、工作，到后来失业&lt;/p&gt;
&lt;p&gt;我靠它吃了很多年饭&lt;/p&gt;
&lt;p&gt;刚毕业那会儿，我为了面试，背得最多的就是 MySQL&lt;/p&gt;
&lt;p&gt;对着镜子：一会儿 Indexing、一会儿 Concurrency 人都要疯了&lt;/p&gt;
&lt;p&gt;所以，我对 MySQL，是有感情的&lt;/p&gt;
&lt;p&gt;现在它要没落了，心里说不出的滋味&lt;/p&gt;
&lt;p&gt;虽然国内教学体系还在用 MySQL，但现实已经很清楚了&lt;/p&gt;
&lt;p&gt;MySQL 不可能再回到从前老大哥的位置了&lt;/p&gt;
&lt;p&gt;哎，天道如来，也罢&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=MySQL%20%E8%A6%81%E6%B2%A1%E8%90%BD%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2026-01-24-mysql&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>民族劣根性</title><link>https://blog.lhasa.icu/posts/life/2026-01-23-renminribao-erliubaozhi-erjiguan</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2026-01-23-renminribao-erliubaozhi-erjiguan</guid><pubDate>Fri, 23 Jan 2026 02:05:00 GMT</pubDate><content:encoded>&lt;p&gt;今天聊聊所谓的“劣根性”，这是碰都不能碰的滑梯&lt;/p&gt;
&lt;p&gt;自西贝事件以来，某些“二流报纸”先后两次下场定调，蹭流量的自媒体紧跟实事充当“叼盘”&lt;/p&gt;
&lt;p&gt;群众一看，纷纷跳出来表态，生怕队站得慢了&lt;/p&gt;
&lt;p&gt;就好像你官媒一说话，事情就“定性”了？下面的人尾巴竖得比狗都直，太激进，太可怕了&lt;/p&gt;
&lt;p&gt;也是，宪法都随便改的国家，这确实算不了什么&lt;/p&gt;
&lt;p&gt;陈丹青曾对“原则问题”有过精辟的论述：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;中国人是不讲原则的，这既是最坏的地方，也是最好的地方&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;哎，就什么东西他妈的“有用”，就拿来用。没用就打倒他，结果翻出来还有用，再拿出来&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;说句难听的，民族劣根性&lt;/p&gt;
&lt;p&gt;话到嘴边打不住，我大抵是要挨骂了&lt;/p&gt;
&lt;p&gt;毕竟你在这个国家，你说他不好，他们就会说你是洋奴&lt;/p&gt;
&lt;p&gt;如果你说外国好，走狗是免不了的&lt;/p&gt;
&lt;p&gt;如果你说要入籍日本，汉奸的帽子也要扣上&lt;/p&gt;
&lt;p&gt;但是，若你闭口不言，悄悄入籍日本，那你就是成功人士&lt;/p&gt;
&lt;p&gt;若入了外籍，还说很爱国，恭喜你，摸到名利的门槛了&lt;/p&gt;
&lt;p&gt;若你把老婆孩子移居境外，自己却在国内教别人如何爱国，这最起码是个处长&lt;/p&gt;
&lt;p&gt;写到这，我心里很难受&lt;/p&gt;
&lt;p&gt;我爱我的国家，我为中国的悠久历史文化而自豪，我为唐宋八大家的文学思想而感到骄傲&lt;/p&gt;
&lt;p&gt;可如今，一切都变了，真的乱了套&lt;/p&gt;
&lt;p&gt;昧着良心说假话的人，生活的有滋有味&lt;/p&gt;
&lt;p&gt;而寻找真理追求真相的人，却苦不堪言，甚至还有失去自由的危险&lt;/p&gt;
&lt;p&gt;回望当年的庐山会议，多少人为了活命出卖同僚？&lt;/p&gt;
&lt;p&gt;有多少人，眼睁睁看着彭老总从成都被揪到北京批斗游街？一度打到瘫痪，囚于暗室，死不瞑目&lt;/p&gt;
&lt;p&gt;又有多少人，为了党的先进性和纯洁性，为了完成自我革命，而检举揭发与自己同床共枕几十年的爱人，甚至是自己的孩子&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;有党性，没人性&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这句话，我曾在王局的节目评论区看到过&lt;/p&gt;
&lt;p&gt;而我认为，真正有党性的人，凤毛麟角&lt;/p&gt;
&lt;p&gt;如毛的秘书李锐、中央党校教授蔡霞等等，他们在坚持原则的同时，从不失有人性的光辉&lt;/p&gt;
&lt;p&gt;那些只剩党性、泯灭人性的东西，他们哪来的信仰？不过是借党性之名，道貌岸然地活着，却早已不是人了&lt;/p&gt;
&lt;p&gt;说到底，中国人是没有信仰的，都是为了活着，活着最要紧&lt;/p&gt;
&lt;p&gt;至于独立思考是什么，早已抛在脑后&lt;/p&gt;
&lt;p&gt;想一想，中国发展了千年文明，从先秦诸子百家到宋明理学，再到改革开放引进西方科学&lt;/p&gt;
&lt;p&gt;可回过头看，中国人连独立思考都未曾普及，尤其是批判性思维和质疑权威的能力，那是碰都不能碰的滑梯&lt;/p&gt;
&lt;p&gt;所以中国人就缺乏鉴赏能力，什么都是和稀泥，没有是非，没有标准&lt;/p&gt;
&lt;p&gt;就喜欢讲道德，讲儒家那点奴性思维，以至于，法治社会，人没有人格，法律没有尊严&lt;/p&gt;
&lt;p&gt;在这种环境下，人性都畸形了：&lt;/p&gt;
&lt;p&gt;一方面逆来顺受，自甘卑贱屈辱贫寒而不自知&lt;/p&gt;
&lt;p&gt;另一方面，一朝得势，便以贵凌贱以富凌贫，加倍压迫自己的同胞&lt;/p&gt;
&lt;p&gt;这种轮回，在史书里转了数千年，直到今天，天安门依然贴着“万岁”，纯奴性&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%B0%91%E6%97%8F%E5%8A%A3%E6%A0%B9%E6%80%A7&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2026-01-23-renminribao-erliubaozhi-erjiguan&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>杨公堤，湖上客船</title><link>https://blog.lhasa.icu/posts/photo/2026-01-18-westlake-passenger-boat</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/photo/2026-01-18-westlake-passenger-boat</guid><pubDate>Sun, 18 Jan 2026 15:50:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;westlake-passenger-boat-1.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;westlake-passenger-boat-2.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;westlake-passenger-boat-3.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;westlake-passenger-boat-4.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;westlake-passenger-boat-5.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;westlake-passenger-boat-6.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;westlake-passenger-boat-7.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;westlake-passenger-boat-8.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;westlake-passenger-boat-9.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;westlake-passenger-boat-10.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;westlake-passenger-boat-11.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%9D%A8%E5%85%AC%E5%A0%A4%EF%BC%8C%E6%B9%96%E4%B8%8A%E5%AE%A2%E8%88%B9&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fphoto%2F2026-01-18-westlake-passenger-boat&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>实现自动拼图</title><link>https://blog.lhasa.icu/posts/technology/2026-01-18-photosuite-0-1-3</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2026-01-18-photosuite-0-1-3</guid><pubDate>Sun, 18 Jan 2026 15:48:00 GMT</pubDate><content:encoded>&lt;p&gt;这事半个月前就计划好了，本想放到 Photosuite 下个版本里&lt;/p&gt;
&lt;p&gt;拖到现在，若不是为了昨天拍的&lt;a href=&quot;https://blog.lhasa.icu/posts/photo/2026-01-18-westlake-passenger-boat&quot;&gt;一套图&lt;/a&gt;，我也懒得折腾&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;就是为了这口醋，才包的这顿饺子&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我的目的很简单：&lt;strong&gt;不引入新的语法，而是通过换行来实现拼图&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;在 Markdown 中连续插入多张图片，只要它们之间&lt;strong&gt;没有非空白内容&lt;/strong&gt;，就应被视为一个整体自动组合&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![图1](1.jpg)
![图2](2.jpg)

![图3](3.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;test1.jpg&quot; alt=&quot; &quot; /&gt;
&lt;img src=&quot;test2.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h3&gt;如何检测相邻图片&lt;/h3&gt;
&lt;p&gt;拼图分组思路由&lt;strong&gt;贪心算法&lt;/strong&gt;实现：&lt;/p&gt;
&lt;p&gt;当扫描到一张图片时，以它为起点向后遍历，将所有&lt;strong&gt;连续相邻&lt;/strong&gt;的图片依次纳入同一组&lt;/p&gt;
&lt;p&gt;一旦相邻关系被打断，就停止扩展，并根据组内图片数量决定是否生成拼图（不足两张则原样保留）&lt;/p&gt;
&lt;p&gt;难点在于“相邻”的定义：&lt;/p&gt;
&lt;p&gt;因为 Markdown 编译为 HTML 后，图片容器之间可能夹杂换行符或空白文本节点&lt;/p&gt;
&lt;p&gt;所有，不能直接依赖 &lt;code&gt;nextSibling&lt;/code&gt; 进行判断&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/modules/imageGrid.ts

/**
 * 检查两个容器是否相邻
 * 
 * @param container1 - 第一个容器
 * @param container2 - 第二个容器
 * @returns 是否相邻
 */
function areContainersAdjacent(container1: HTMLElement, container2: HTMLElement): boolean {
  // 获取两个容器的父元素
  const parent1 = container1.parentElement;
  const parent2 = container2.parentElement;

  // 如果父元素不同，不是相邻的
  if (parent1 !== parent2 || !parent1) return false;

  // 获取父元素的所有子元素
  const siblings = Array.from(parent1.children);
  const index1 = siblings.indexOf(container1);
  const index2 = siblings.indexOf(container2);

  // 检查是否相邻（中间只能有文本节点或空白节点）
  if (index2 !== index1 + 1) {
    // 检查中间是否只有空白文本节点
    let hasNonWhitespace = false;
    let node = container1.nextSibling;
    while (node &amp;amp;&amp;amp; node !== container2) {
      if (node.nodeType === Node.ELEMENT_NODE) {
        hasNonWhitespace = true;
        break;
      }
      if (node.nodeType === Node.TEXT_NODE &amp;amp;&amp;amp; node.textContent?.trim()) {
        hasNonWhitespace = true;
        break;
      }
      node = node.nextSibling;
    }
    return !hasNonWhitespace &amp;amp;&amp;amp; node === container2;
  }

  return true;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在解决了相邻判定的问题之后，分组逻辑本身就变得很简单了&lt;/p&gt;
&lt;p&gt;当 Photosuite 扫描到一张图片时，会从当前位置向后查找连续相邻的图片，并将它们归为一组&lt;/p&gt;
&lt;p&gt;出于美观考虑，我这里将单组图片数量限制为最多三张&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/modules/imageGrid.ts

function processImageGrids(root: Element) {
  // 获取所有图片元素
  const images = Array.from(root.querySelectorAll(&quot;img&quot;));

  // 用于标记已处理的图片
  const processed = new Set&amp;lt;Element&amp;gt;();

  for (let i = 0; i &amp;lt; images.length; i++) {
    const img = images[i];

    // 跳过已处理的图片
    if (processed.has(img)) continue;

    // 检查是否可以形成拼图
    const gridImages = [img];
    processed.add(img);

    // 查找连续的图片（最多3张）
    for (let j = i + 1; j &amp;lt; images.length &amp;amp;&amp;amp; gridImages.length &amp;lt; 3; j++) {
      const nextImg = images[j];

      // 检查两个图片容器是否相邻
      const currentContainer = ensurePhotosuiteContainer(gridImages[gridImages.length - 1]);
      const nextContainer = ensurePhotosuiteContainer(nextImg);

      if (areContainersAdjacent(currentContainer, nextContainer)) {
        gridImages.push(nextImg);
        processed.add(nextImg);
      } else {
        break;
      }
    }

    // 如果找到了多张连续的图片（2-3张），创建拼图
    if (gridImages.length &amp;gt;= 2) {
      createImageGrid(gridImages);
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://boardmix.cn/app/share/CAE.CKfxxBAgASoQcVANY5YIcaUJozRAwCeb-DAGQAE/h1bOR3&quot;&gt;我用 Boardmix 做了一个流程图&lt;/a&gt;，通俗易懂：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;greedy-algorithm-flowchart.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;如何处理不同比例的图片&lt;/h3&gt;
&lt;p&gt;把图片简单地放进一个 Flex 容器并不难&lt;/p&gt;
&lt;p&gt;如果一张是横图（16:9），另一张是竖图（9:16），直接使用 &lt;code&gt;flex: 1&lt;/code&gt; 只会让它们&lt;strong&gt;宽度相同&lt;/strong&gt;，却无法保证高度一致，结果要么高低不齐，要么图片被强行拉伸&lt;/p&gt;
&lt;p&gt;要让多张图片在同一行里&lt;strong&gt;等高对齐&lt;/strong&gt;，关键不在 Flex，而在比例关系&lt;/p&gt;
&lt;p&gt;直观来说：&lt;strong&gt;哪张图片更“扁”，就应该占更宽的位置；哪张更“瘦”，就占得窄一些&lt;/strong&gt;，这样它们的高度才能最终一致&lt;/p&gt;
&lt;p&gt;用更具体的话说：&lt;/p&gt;
&lt;p&gt;每张图片在一行中所占的宽度，应该和它本身的&lt;strong&gt;宽高比&lt;/strong&gt;成正比&lt;/p&gt;
&lt;p&gt;宽高比越大（越横），分到的宽度就越多；宽高比越小（越竖），分到的宽度就越少&lt;/p&gt;
&lt;p&gt;因此，在等高布局下，可以把每张图片的宽度理解为：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;每张图片的宽度占比 ≈ 自身宽高比 ÷ 所有图片宽高比之和&lt;/p&gt;
&lt;p&gt;其中：&lt;code&gt;宽高比 = 宽 / 高&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;基于这个思路，我没有让 Flex 自由分配空间，而是&lt;strong&gt;先计算好每张图片应占的宽度&lt;/strong&gt;，再通过 &lt;code&gt;flex-basis&lt;/code&gt; 精确控制布局&lt;/p&gt;
&lt;p&gt;具体实现上，会先异步获取每张图片的宽高比，计算出总比例后，将容器宽度按比例拆分。同时考虑到图片之间的间距（gap），使用 &lt;code&gt;calc()&lt;/code&gt; 对最终宽度进行修正，避免累计误差&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/modules/imageGrid.ts

/**
 * 异步更新拼图项宽度
 * 基于图片宽高比计算宽度，使得所有图片高度一致
 */
async function updateGridDimensions(images: HTMLImageElement[], gridItems: HTMLElement[]) {
  const ratios: number[] = [];

  // 获取所有图片的宽高比
  for (const img of images) {
    const ratio = await resolveImageRatio(img);
    ratios.push(ratio);
  }

  // 计算总比例
  const totalRatio = ratios.reduce((sum, r) =&amp;gt; sum + r, 0);
  const gapCount = gridItems.length - 1;

  // 设置每张图片的宽度百分比
  gridItems.forEach((item, index) =&amp;gt; {
    if (totalRatio &amp;gt; 0) {
      const ratio = ratios[index];
      const percent = (ratio / totalRatio) * 100;
      
      // 使用 calc 计算实际宽度：(比例% * 100) - (gap总宽 * 比例占比)
      // 公式: calc(33.33% - (2 * var(--gap) * 0.3333))
      const widthCalc = `calc(${percent}% - (${gapCount} * var(--photosuite-grid-gap, 4px)) * ${ratio / totalRatio})`;
      
      // 设置 flex-basis 和 max-width
      item.style.flex = `0 0 ${widthCalc}`;
      item.style.maxWidth = widthCalc;
    }
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样一来，不管图片比例多么悬殊，它们在拼图中都会自然对齐&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高度一致、宽度合理、边缘整齐&lt;/strong&gt;，同时也避免了任何形式的拉伸或裁剪&lt;/p&gt;
&lt;h3&gt;布局样式&lt;/h3&gt;
&lt;p&gt;样式只负责布局：Flex + gap + 响应式间距，没有额外装饰，所有空间都留给图片本身&lt;/p&gt;
&lt;p&gt;这里通过 CSS 变量统一管理间距；在移动端则适当缩小 gap，以保证有限屏幕宽度下的视觉紧凑度&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// src/styles/image-grid.scss

/* 拼图容器 */
.photosuite-grid {
  --photosuite-grid-gap: 4px;
  
  display: flex;
  gap: var(--photosuite-grid-gap);
  width: 100%;
  margin: 0;
  padding: 0;
  align-items: flex-start;
}

/* 移动端保持拼图布局，但减小间距 */
@media (max-width: 768px) {
  .photosuite-grid {
    --photosuite-grid-gap: 2px;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在交互层面，加了点人情味，当鼠标悬停在图片上时（拼图状态），会有一个轻微的放大效果&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;注：使用该功能无需配置，默认为 &lt;code&gt;imageGrid: true&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;拼图状态下不显示 EXIF 和标签，它们在编译阶段并未生成&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;至此，完成&lt;/p&gt;
&lt;p&gt;感谢 Claude Code、Gemini、ChatGPT 对项目的大力支持&lt;/p&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;p&gt;Photosuite 已发布至 npm，可直接安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm add photosuite
# or
npm install photosuite
# or
yarn add photosuite
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;参考&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Photosuite：&lt;a href=&quot;https://github.com/achuanya/photosuite&quot;&gt;https://github.com/achuanya/photosuite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;npmjs：&lt;a href=&quot;https://www.npmjs.com/package/photosuite&quot;&gt;https://www.npmjs.com/package/photosuite&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%AE%9E%E7%8E%B0%E8%87%AA%E5%8A%A8%E6%8B%BC%E5%9B%BE&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2026-01-18-photosuite-0-1-3&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>优化了一下博客的交互细节</title><link>https://blog.lhasa.icu/posts/technology/2026-01-13-blog-update-theme-animation</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2026-01-13-blog-update-theme-animation</guid><pubDate>Mon, 12 Jan 2026 16:39:00 GMT</pubDate><content:encoded>&lt;p&gt;晚上刷 1900 的博客，我忽然想起了 &lt;strong&gt;主题配色切换动画&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;随手输入关键字 “&lt;strong&gt;主题&lt;/strong&gt;” 一搜，果然找到了那篇：&lt;a href=&quot;https://1900.live/gei-bo-ke-zhu-ti-qie-huan-jia-ge-dong-hua/&quot;&gt;给博客主题切换加个动画&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看到左上角的发布日期时，不禁有些感叹，原来这已经是半年前的事了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;demo.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h3&gt;主题切换动画&lt;/h3&gt;
&lt;p&gt;实现思路与 1900 类似，本质上是利用 View Transitions API 接管视图更新，从而实现遮罩动画&lt;/p&gt;
&lt;p&gt;通过 &lt;code&gt;document.startViewTransition&lt;/code&gt; 捕获 DOM 快照，再配合 CSS 的 &lt;code&gt;clip-path&lt;/code&gt;（裁剪路径）实现平滑过渡：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const transition = document.startViewTransition(() =&amp;gt; {
  themeValue = themeValue === &quot;light&quot; ? &quot;dark&quot; : &quot;light&quot;;
  setPreference(true);
});

transition.ready.then(() =&amp;gt; {
  // 从上至下的裁剪路径
  const clipPath = [
    &apos;inset(0 0 100% 0)&apos;, // 开始：底部被完全裁剪
    &apos;inset(0 0 0 0)&apos;,    // 结束：完全显示
  ];
  
  document.documentElement.animate(
    { clipPath: clipPath },
    {
      duration: 1000, 	 // 长动画，可能会掉帧
      easing: &quot;ease-out&quot;,
      pseudoElement: &quot;::view-transition-new(root)&quot;,
    }
  );
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;返回按钮&lt;/h3&gt;
&lt;p&gt;此外，我还给博客增加了两个功能按钮，灵感借鉴自 &lt;a href=&quot;https://suus.me&quot;&gt;SeerSu&lt;/a&gt;，他的博客设计非常线性，我很喜欢&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;返回上一页（如果存在浏览记录），否则返回首页&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;class=&quot;fixed bottom-6 md:bottom-8 z-50 w-10 h-10 rounded-md bg-white/40 dark:bg-gray-900/40 backdrop-blur-md border border-white/50 dark:border-gray-700/50 text-gray-700 dark:text-gray-200 shadow-sm hover:bg-white/70 dark:hover:bg-gray-800/70 hover:scale-110 hover:shadow-lg transition-all duration-300 ease-out translate-y-8 opacity-0 pointer-events-none flex items-center justify-center gap-1&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;整体视觉设计上，采用了玻璃风格，悬停时有缩放效果&lt;/p&gt;
&lt;h3&gt;回到顶部&lt;/h3&gt;
&lt;p&gt;当页面向下滚动到一定范围，该按钮才会浮现，并自动调整“返回按钮”的位置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 监听 BackToTop
window.addEventListener(&quot;backToTopVisibilityChange&quot;, e =&amp;gt; {
  // 如果回到顶部按钮出现，返回按钮自动向上移动让出位置
  updateVerticalPosition(e.detail.visible);
});
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BC%98%E5%8C%96%E4%BA%86%E4%B8%80%E4%B8%8B%E5%8D%9A%E5%AE%A2%E7%9A%84%E4%BA%A4%E4%BA%92%E7%BB%86%E8%8A%82&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2026-01-13-blog-update-theme-animation&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>晨跑，破六</title><link>https://blog.lhasa.icu/posts/outdoors/2026-01-07-morning-run-sub6</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2026-01-07-morning-run-sub6</guid><pubDate>Wed, 07 Jan 2026 12:12:00 GMT</pubDate><content:encoded>&lt;p&gt;熟悉我的朋友都知道，我是一个懒人。懒得说话，懒得吃饭&lt;/p&gt;
&lt;p&gt;所以像我这样的人，按理说对运动是没什么兴趣的&lt;/p&gt;
&lt;p&gt;但耐不住压力大，我急需一种方式来发泄情绪&lt;/p&gt;
&lt;p&gt;毕竟，人是可以活活憋死的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260103101640_951_266.jpg&quot; alt=&quot;杭州城内，我最爱的一条路：南山路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我之前的发泄方式主要是骑车，但现在碳轮坏了，暂时没钱换，于是便转向了登山徒步&lt;/p&gt;
&lt;p&gt;不可否认，我非常喜欢这种方式，但徒步太耗时间了，我不可能每天都拨出大半天做这件事&lt;/p&gt;
&lt;p&gt;至于跑步，我没想过。仅有的尝试也纯粹是出于好奇。可以说，这辈子我跑过的次数，一个巴掌就能数得过来&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107140822_990_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;2025年12月31日，早晨七点。我实在憋不住了，穿上体能服直接冲了出去&lt;/p&gt;
&lt;p&gt;跑出一公里后，我有些后悔没戴帽子和手套。苏堤两岸吹来的冷风冻得我头皮发麻&lt;/p&gt;
&lt;p&gt;跑到岳湖附近时，想吐。我手撑着树干呕了几分钟，深感不适，当场掉头慢跑回家了，全程九公里&lt;/p&gt;
&lt;p&gt;纯菜逼，回到家后，连饭都吃不下&lt;/p&gt;
&lt;p&gt;第二天，也就是 2026 年的第一天。杭州下了一场暴雨，我便没出门&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260103101728_976_266.jpg&quot; alt=&quot;跑步的第二天，差点破六&quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果不算年前的那次，从 1 月 2 号到今天，是我连续晨跑的第六天&lt;/p&gt;
&lt;p&gt;以前我习惯通宵写代码，而现在为了凌晨能跑起来，作息也调整了&lt;/p&gt;
&lt;p&gt;不管手头有什么几把事，统统往后排，每天 12 点前必须睡觉&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107140646_986_266.jpg&quot; alt=&quot; 咖啡 + 牛奶 + 燕麦 &quot; /&gt;&lt;/p&gt;
&lt;p&gt;由于晚饭吃得少（或者干脆不吃），凌晨醒来时明显的饿&lt;/p&gt;
&lt;p&gt;所以出发前，我都会冲点麦片。这东西挺容易消耗，有饱腹感，即便吃半碗也不影响马上跑步&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260103101637_949_266.jpg&quot; alt=&quot;凌晨 6 点 13 分的湖滨路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;插播一个有意思的小插曲：跑步的第二天，经过湖滨银泰时，我貌似和马云擦肩而过&lt;/p&gt;
&lt;p&gt;当时我俩距离不过半米，几秒钟后我才反应过来，那个人很可能是他&lt;/p&gt;
&lt;p&gt;毕竟马云的相貌还是很出众的，有一定辨识度，可惜当时光线差，他还戴着帽子&lt;/p&gt;
&lt;p&gt;回家后我特意查了他近期的行程，啥也没搜到&lt;/p&gt;
&lt;p&gt;但如果他当时在杭州，我敢说大概率是他&lt;/p&gt;
&lt;p&gt;因为马云一直有户外运动的爱好，之前在杭州爬山、骑车也常被网友偶遇&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107140716_987_266.jpg&quot; alt=&quot;雷峰夕照&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;闻子状雷峰，老僧挂偏裻。日日看西湖，一生看不足&lt;br /&gt;
—— 张岱《雷峰塔》&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今天的天气极好，跑过苏堤时，恰好瞥见了西湖十景之七的“雷峰夕照”&lt;/p&gt;
&lt;p&gt;可惜当时站位欠佳，视线被桥两侧的树木挡了大半&lt;/p&gt;
&lt;p&gt;不过我也没打算专门跑到桥下去取景，毕竟我是出来跑步的，不是来搞摄影的&lt;/p&gt;
&lt;p&gt;日志里的这些照片，每张的拍摄停留时间都不会超过 5 秒&lt;/p&gt;
&lt;p&gt;因为我我习惯在跑步过程中提前打开相机，停下的瞬间，让远景对准参考线便按下快门，不过一瞬间&lt;/p&gt;
&lt;p&gt;其中不乏有运动过程中拍下的照片，所以有些画面难免会有重影或模糊&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107140744_988_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;实际上我这几天的跑步，都没怎么在中途停下过，也就是所谓的不间断&lt;/p&gt;
&lt;p&gt;骑行更是如此，即便是两百公里，我也宁愿在车上慢踩，而不会选择停下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107141036_993_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;当然，凡事皆有意外&lt;/p&gt;
&lt;p&gt;昨天跑得确实有点过火，到 11 公里时，左腿膝盖突然刺痛难忍&lt;/p&gt;
&lt;p&gt;眼看只剩最后两公里，我实在不想放弃，便拖着左腿蹦着跑，那种刺痛感真是钻心刺骨，疼得我直咬牙&lt;/p&gt;
&lt;p&gt;最后还是认怂了，不过我发现只要不刻意发力，刺痛感就不会有，于是快走了两公里。回到家一看配速：6:13，绝了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107141115_994_266.jpg&quot; alt=&quot;凌晨雨跑，环西湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;5 号那天是我人生第一次“雨跑”&lt;/p&gt;
&lt;p&gt;刚出门，万松岭的路面就已经全湿了，手掌伸出去能感觉到细密的水滴&lt;/p&gt;
&lt;p&gt;就这点降水量想挡住我跑步？门都没有&lt;/p&gt;
&lt;p&gt;毕竟我衣服都穿好了，脱是不可能脱的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107141200_995_266.jpg&quot; alt=&quot;白堤&quot; /&gt;&lt;/p&gt;
&lt;p&gt;雨跑给我的真实感受其实就两个字：湿、重&lt;/p&gt;
&lt;p&gt;汗水夹杂着雨水，上半身很快就湿透了，体感并不算舒服&lt;/p&gt;
&lt;p&gt;我想，产生这种不适感，也许是因为跑步时注意力还不够集中&lt;/p&gt;
&lt;p&gt;不像骑行，如果你行驶中分神，就有可能出事故&lt;/p&gt;
&lt;p&gt;所以骑行时，人的感官会高度聚焦，从而忽略身体的琐碎不适&lt;/p&gt;
&lt;p&gt;显然，我跑步还没达到那种境界&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260103101709_964_266.jpg&quot; alt=&quot;开水煮西蓝花&quot; /&gt;&lt;/p&gt;
&lt;p&gt;除了跑步，最近我还尝试着自己动手做饭&lt;/p&gt;
&lt;p&gt;凌晨 5-6 点起床，跑完步刚好是早餐时间&lt;/p&gt;
&lt;p&gt;到家后的第一件事通常是点根烟暖暖身，如果出汗多就洗个澡，然后从冰箱拿点能吃的搞一搞&lt;/p&gt;
&lt;p&gt;我的早餐口味偏清淡。比如这盘西兰花，什么调料都不放，开水烫一下就可以出锅&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107140959_992_266.jpg&quot; alt=&quot;鸡蛋 + 火腿 + 韭菜 + 上海青&quot; /&gt;&lt;/p&gt;
&lt;p&gt;南德调味料，河南的老乡应该都很熟悉，家乡话叫“南呆”&lt;/p&gt;
&lt;p&gt;这大概是我早餐里口味最重的一道菜了，再油腻的我也吃不下&lt;/p&gt;
&lt;p&gt;炒鸡蛋出锅时，高压锅里的米粥也熬好了。趁热再去微波炉里热个馒头，一顿饭就齐活了&lt;/p&gt;
&lt;p&gt;大概就是这样&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20260107140926_991_266.jpg&quot; alt=&quot;破六&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%99%A8%E8%B7%91%EF%BC%8C%E7%A0%B4%E5%85%AD&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2026-01-07-morning-run-sub6&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>聊聊贾跃亭</title><link>https://blog.lhasa.icu/posts/life/2025-12-31-liao-liao-jia-yue-ting</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-12-31-liao-liao-jia-yue-ting</guid><pubDate>Wed, 31 Dec 2025 15:22:00 GMT</pubDate><content:encoded>&lt;p&gt;跨年前夜，刷到贾跃亭发视频唱了一首北京北京，多少是想家了，希望他下周能回国吧&lt;/p&gt;
&lt;p&gt;点开评论区，还是一个吊样：嘲讽和谩骂。我就纳闷了，骂他究竟能让你舒服多少？&lt;/p&gt;
&lt;p&gt;有人指责他财务造假。说句不中听的，就这个环境，大到顶层建筑，小到微企个体，谁没做过一些违背良心的事？区别无非在于，有的你可以随便骂，有的你一句话就成了冒犯君主不敬之罪&lt;/p&gt;
&lt;p&gt;还有人替供应商鸣不平，“他们收不到货款，哪里错了？” 真鸡巴扯淡，既然选择创业，就得承担风险。你作为下游供应链，和企业就是一根绳上的蚂蚱，这是何尝不是投资？而不是去餐馆吃饭，不满意就说菜难吃&lt;/p&gt;
&lt;p&gt;就这一点，和那些把买房当理财的人有什么区别？&lt;br /&gt;
涨了炫耀，跌了骂娘，骂开发商、骂社会不公，甚至媒体曝光，集体诉讼。就好像风险只该由别人承担。这种逻辑，本身就很扯淡&lt;/p&gt;
&lt;p&gt;看着这些评论，我只想笑&lt;br /&gt;
就单论一个人创业十余年，面对失败，面对别人的冷嘲热讽，仍选择向前走，你有这个魄力吗？&lt;/p&gt;
&lt;p&gt;这还不算个爷们？&lt;/p&gt;
&lt;p&gt;换位思考，把你放在贾跃亭的位置，给你三个选项，你会怎么做？你还会坚持自己的梦想吗？&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;回国，放下梦想，不能造车，改行谋生&lt;/li&gt;
&lt;li&gt;打工，一辈子望到头，几乎没有还债的可能&lt;/li&gt;
&lt;li&gt;出国，坚持梦想，继续创业，继续赌&lt;/li&gt;
&lt;/ol&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%81%8A%E8%81%8A%E8%B4%BE%E8%B7%83%E4%BA%AD&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-12-31-liao-liao-jia-yue-ting&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>我的博客 2025</title><link>https://blog.lhasa.icu/posts/annual-reviews/2025-12-28-my-blog-annual-report</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/annual-reviews/2025-12-28-my-blog-annual-report</guid><pubDate>Sun, 28 Dec 2025 00:19:00 GMT</pubDate><content:encoded>&lt;p&gt;从 2018 年 8 月 31 日开始，我们一起走过了 &lt;strong&gt;2675 个昼夜&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;你的评论，让博友之间距离更近&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这一年，你写下了 233 条回复&lt;br /&gt;
世界偶尔沉默，而你选择了回应&lt;/p&gt;
&lt;p&gt;你还记得吗？ 1 月 7 日&lt;br /&gt;
你在&lt;a href=&quot;/posts/outdoors/2025-01-07-zhengzhou&quot;&gt;“骑行郑州 · 四环”&lt;/a&gt;日志里，写下了今年首条回复&lt;br /&gt;
&lt;a href=&quot;https://note-star.cn/&quot;&gt;@小彦&lt;/a&gt; 初次落笔，幸好有你&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;不算太长短的字句，都留下痕迹&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今年，你写了 48 篇日志，约 8.5 万字。这个数字占过去七年总和的 40%&lt;br /&gt;
&lt;strong&gt;相当于写完了两部呐喊&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;11 月是你的灵感高峰，相当于去年一整年的 60%&lt;br /&gt;
10 月 15 日，你写下了今年字数最多的一篇日志&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;/posts/outdoors/2025-10-15-first-hike-deep-forest-cliff-fall&quot;&gt;首次徒步爬山，误闯深山老林，徒手爬悬崖，两度滑落险些丧命&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;全文 4000 +，字字惊心，你爽了吗？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;热爱是唯一的通行证&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这一年，你的博客收获了&lt;/p&gt;
&lt;p&gt;12352 次页面访问&lt;br /&gt;
339 条访客评论&lt;/p&gt;
&lt;p&gt;这些回声，将你的声音推向更远的地方&lt;/p&gt;
&lt;p&gt;你的年度口头禅是：&lt;strong&gt;“实在太爽了！”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你最感兴趣的的领域是：&lt;strong&gt;骑行&lt;/strong&gt;，全年提及 177 次，贯穿 28 篇日志&lt;/p&gt;
&lt;p&gt;更有意思的是，你有 20 篇日志是在凌晨（00:00-05:00）完成的，你是真的不睡觉吗？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;希望新的一年，你能遇见更多同频的人&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2025 年，共有 &lt;strong&gt;103 位新朋友&lt;/strong&gt; 闯入你的世界，TA 们通常在&lt;strong&gt;凌晨至中午&lt;/strong&gt;出没&lt;/p&gt;
&lt;p&gt;年度首席读者是 &lt;a href=&quot;https://h4ck.org.cn/&quot;&gt;@obaby&lt;/a&gt;&lt;br /&gt;
TA 留下 37 条评论，真诚的人同路亦同心&lt;br /&gt;
特此颁发“年度最佳嘴替奖”：感谢这一年所有的欲言又止，都被你温柔接住&lt;/p&gt;
&lt;p&gt;和你互动最多的是 &lt;a href=&quot;https://1900.live/&quot;&gt;@1900&lt;/a&gt;&lt;br /&gt;
聊得这么热乎，很难不让人怀疑：这到底是爱情的火花？还是那种“懂的都懂”的男上加男？&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;关于 2025：你想打包什么&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这一年，真的要过去了&lt;/p&gt;
&lt;p&gt;时间会被打包&lt;/p&gt;
&lt;p&gt;记忆将会存档&lt;/p&gt;
&lt;p&gt;最后，让我们用这一句&lt;strong&gt;年度金句&lt;/strong&gt;，为你留下一份属于 2025 的真实源文件：&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/posts/outdoors/2025-05-11-yilu-xiang-nan-qi-jian-jiang-nan&quot;&gt;「时隔六年，再次为热爱脱皮。痛苦如影随形，却也因此更加坚定」&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%88%91%E7%9A%84%E5%8D%9A%E5%AE%A2%202025&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fannual-reviews%2F2025-12-28-my-blog-annual-report&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Photosuite：一个为博客而生的图片处理方案</title><link>https://blog.lhasa.icu/posts/technology/2025-12-23-photosuite</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-12-23-photosuite</guid><pubDate>Mon, 22 Dec 2025 23:58:00 GMT</pubDate><content:encoded>&lt;p&gt;每次给博客搞拆迁，最让人割舍不下的，往往不是瓦片和墙皮，而是那些被我用到形成肌肉记忆的家具。由于Jekyll 和 Astro 说着不同方言，导致家具根本拿不到“异地安置指标”，我只能含泪签字&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Photosuite&lt;/strong&gt; 正是在这样的背景下诞生的&lt;/p&gt;
&lt;p&gt;它由 Vite + Typescript 开发，拥有我博客图像的核心能力，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;灯箱&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EXIF 展示&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;图片说明&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;图片路径自动补全&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;example-picture.jpg&quot; alt=&quot;Example Picture&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上面的图片及其所有样式，仅通过下面这一行最普通的 Markdown 语法生成，而且我只需要输入文件名：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Example Picture](example-picture.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;设计思路&lt;/h2&gt;
&lt;p&gt;Photosuite 利用 Remark 和 Rehype 插件生态，在 Markdown 编译阶段完成图片处理，避免在运行时增加负担：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- 构建期
  ├→ Remark：补全图片 URL
  └→ Rehype：读取图片 EXIF 并写入 HTML
  ↓
- 运行期
  ├→ photosuite(opts) 入口：按需动态 import
  ├→ glightbox 模块：把图变成可点击灯箱
  ├→ imageAlts 模块：用 alt 自动生成 caption
  └→ exif 模块：加载 EXIF 样式，清理空条
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;图片路径解析&lt;/h3&gt;
&lt;p&gt;如前所述，Photosuite 的首要职责是&lt;strong&gt;补全图片 URL&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;设计目标很简单：&lt;strong&gt;在 Markdown 中只写文件名，其余交给 Photosuite  处理&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;整体思路如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- 使用标准 Markdown 语法插入图片，只填写文件名
  例：![Example Picture](demo.jpg)

- 配置一个基础 URL 作为图片域名
  https://cdn.example.com/images

- 子目录来源有两种策略：
  a. 通过 Frontmatter 指定图片目录（默认）
     imageDir: 2025-12-22-photosuite

  b. 以当前 Markdown 文件名作为目录（去除后缀）
     2025-12-22-photosuite.md

- 最终生成的完整路径一致，例如：
  https://cdn.example.com/images/2025-12-22-photosuite/demo.jpg
  
- 稍作调整即可实现按年 / 月分类等更复杂的目录结构。
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实现逻辑：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;使用 Remark 插件遍历 Markdown AST 中的所有 &lt;code&gt;image&lt;/code&gt; 节点&lt;/li&gt;
&lt;li&gt;判断图片 URL 是否为“短链接”（无协议、非绝对路径、非显式相对路径 &lt;code&gt;../&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;按配置策略拼接完整 URL（域名 + 目录 + 文件名）&lt;/li&gt;
&lt;li&gt;重写 AST 节点的 &lt;code&gt;url&lt;/code&gt; 属性&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;EXIF 展示&lt;/h3&gt;
&lt;p&gt;EXIF 本身并不是 Photosuite 的核心创新点，毕竟，也不是我实现的&lt;/p&gt;
&lt;p&gt;我只是在 HTML 生成之前，我通过 &lt;code&gt;exiftool-vendored.js&lt;/code&gt; 提取图片参数，并将其以文本形式注入到 DOM 中，仅此而已，零 JS 成本、零性能开销&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;遍历 HTML AST → 找到 img → 解析图片 → 提取 EXIF → 重写节点结构&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;HTTP 图片的临时下载策略&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;function isHttpUrl(u: string): boolean {
  const x = new URL(u);
  return x.protocol === &quot;http:&quot; || x.protocol === &quot;https:&quot;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;对于网络图片，Photosuite 不会直接让 exiftool 处理 URL，而是&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;下载到 &lt;code&gt;os.tmpdir()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;生成随机文件名&lt;/li&gt;
&lt;li&gt;在 &lt;code&gt;finally&lt;/code&gt; 中清理&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;const dl = await downloadToTemp(src);
filePath = dl.path;
cleanup = dl.cleanup;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;可配置字段&lt;/h4&gt;
&lt;p&gt;exiftool-vendored.js 解析的 EXIF 数据非常多。这里 Photosuite 做了封装处理，除默认字段外，还可以任意搭配&lt;/p&gt;
&lt;p&gt;默认展示字段：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[&apos;Model&apos;, &apos;LensModel&apos;, &apos;FocalLength&apos;, &apos;FNumber&apos;, &apos;ExposureTime&apos;, &apos;ISO&apos;, &apos;DateTimeOriginal&apos;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;通过 &lt;code&gt;formatField&lt;/code&gt; 做语义化输出：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;case &apos;FNumber&apos;:
  return `ƒ/${Number(value).toFixed(1)}`;
case &apos;ExposureTime&apos;:
  return value &amp;gt;= 1 ? `${value}s` : `1/${Math.round(1 / value)}s`;
case &apos;ISO&apos;:
  return `ISO ${value}`;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最终输出示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ILCE-7CM2 · E 28-200mm F2.8-5.6 A071 · 51.0 mm · ƒ/3.5 · 1/1250 · ISO 1000 · 2025/10/4
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际上，我最初我选择的是 &lt;a href=&quot;https://github.com/MikeKovarik/exifr&quot;&gt;MikeKovarik/exifr&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;它号称是&lt;strong&gt;速度最快、功能最全的 JavaScript EXIF 解析库&lt;/strong&gt;&lt;br /&gt;
结果，我 Nikon z30 拍摄的照片它居然识别不出来机身？我尼康就低人一等吗！果断 PASS！&lt;/p&gt;
&lt;h3&gt;按需加载&lt;/h3&gt;
&lt;p&gt;Photosuite 的所有功能都是&lt;strong&gt;模块化设计&lt;/strong&gt;的，样式同样如此&lt;/p&gt;
&lt;p&gt;当你关闭某个功能时：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;对应的 JavaScript &lt;strong&gt;不会加载&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;相关 CSS &lt;strong&gt;也不会出现在页面中&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;实现逻辑：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;检查配置中的 &lt;code&gt;scope&lt;/code&gt;（作用域选择器）是否存在于页面中&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;若不存在，直接终止执行&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;根据功能开关配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;enableLightbox&lt;/code&gt;, &lt;code&gt;enableAlts&lt;/code&gt;, &lt;code&gt;enableExif&lt;/code&gt; 并行、动态 &lt;code&gt;import()&lt;/code&gt; 对应模块&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;DOM 标准化&lt;/h3&gt;
&lt;p&gt;Photosuite 设计了一套统一的 DOM 规范，供所有模块共享&lt;/p&gt;
&lt;p&gt;核心思想是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;先把来源复杂的图片元素统一成稳定结构，再在此基础上扩展功能&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;开关 Photosuite 任意功能都会生成不同的结构，以下是所有功能开启时的最终结构：

&amp;lt;div class=&quot;photosuite-item&quot;&amp;gt;
	&amp;lt;div class=&quot;photosuite-exif&quot;&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;a class=&quot;glightbox&quot; href=&quot;...&quot;&amp;gt;
    &amp;lt;img ... /&amp;gt;
  &amp;lt;/a&amp;gt;
  &amp;lt;div class=&quot;photosuite-caption&quot;&amp;gt;alt&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;关键逻辑&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;export function ensurePhotosuiteContainer(el: Element): HTMLElement {
  let target: Element = el;

  // 如果 img 被 a.glightbox 包裹，则提升包裹层级
  if (
    el.tagName.toLowerCase() === &quot;img&quot; &amp;amp;&amp;amp;
    el.parentElement?.tagName.toLowerCase() === &quot;a&quot; &amp;amp;&amp;amp;
    el.parentElement.classList.contains(&quot;glightbox&quot;)
  ) {
    target = el.parentElement;
  }

  // 如果已经在 photosuite-item 中，直接复用
  const parent = target.parentElement as HTMLElement | null;
  if (parent?.classList.contains(&quot;photosuite-item&quot;)) {
    return parent;
  }

  // 创建统一容器
  const wrapper = document.createElement(&quot;div&quot;);
  wrapper.className = &quot;photosuite-item&quot;;

  // 用 wrapper 替换 target
  parent?.replaceChild(wrapper, target);
  wrapper.appendChild(target);

  return wrapper;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有了这个保证之后，后续逻辑可以&lt;strong&gt;完全不关心图片来源&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 查找主体
container.querySelector(&quot;img&quot;);

// 添加 UI（caption）
container.appendChild(caption);

// 查询数据：有就显示，没有就清理（EXIF）
container.querySelector(&quot;.photosuite-exif&quot;);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;p&gt;Photosuite 已发布至 npm，可直接安装：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm add photosuite
# or
npm install photosuite
# or
yarn add photosuite
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;快速开始&lt;/h2&gt;
&lt;p&gt;配置 Photosuite 非常简单，以&lt;code&gt;Astro&lt;/code&gt;为例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { defineConfig } from &apos;astro/config&apos;;
import photosuite from &apos;photosuite&apos;;
import &quot;photosuite/dist/photosuite.css&quot;;

export default defineConfig({
  integrations: [
    photosuite({
      // [必填] 生效范围选择器
      // 建议限定在文章容器内，避免影响站点其他区域。支持多个选择器，用逗号分隔
      scope: &apos;#main&apos;,
    })
  ]
});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;import &quot;photosuite/dist/photosuite.css&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Photosuite 基于 &lt;strong&gt;Vite + TypeScript&lt;/strong&gt; 开发，理论上适用于多种架构&lt;/p&gt;
&lt;p&gt;如果您在配置中遇到任何问题，欢迎联系我，为爱发电，无偿奉献&lt;/p&gt;
&lt;h2&gt;后续计划&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;引入 Lozad.js 实现图片懒加载&lt;/li&gt;
&lt;li&gt;构建期获取图片尺寸，生成占位符，避免布局抖动&lt;/li&gt;
&lt;li&gt;适配更多博客架构&lt;/li&gt;
&lt;li&gt;进一步优化 Photosuite 的按需加载机制&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;相关资料&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Photosuite：&lt;a href=&quot;https://github.com/achuanya/photosuite&quot;&gt;https://github.com/achuanya/photosuite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;npmjs：&lt;a href=&quot;https://www.npmjs.com/package/photosuite&quot;&gt;https://www.npmjs.com/package/photosuite&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;exiftool-vendored.js：&lt;a href=&quot;https://github.com/photostructure/exiftool-vendored.js&quot;&gt;https://github.com/photostructure/exiftool-vendored.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Glightbox：&lt;a href=&quot;https://github.com/achuanya/glightbox&quot;&gt;https://github.com/achuanya/glightbox&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果 Photosuite 对您有帮助，欢迎在 GitHub 点个 ⭐️&lt;br /&gt;
它不会让代码跑得更快，但会让我写得更勤快&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;PS：如果您正在使用 Photosuite&lt;br /&gt;
欢迎告诉我您的博客地址，我会把它展示在项目页面中&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Photosuite%EF%BC%9A%E4%B8%80%E4%B8%AA%E4%B8%BA%E5%8D%9A%E5%AE%A2%E8%80%8C%E7%94%9F%E7%9A%84%E5%9B%BE%E7%89%87%E5%A4%84%E7%90%86%E6%96%B9%E6%A1%88&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-12-23-photosuite&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>尼康 z30 开箱小记</title><link>https://blog.lhasa.icu/posts/photo/2025-12-02-nikon-z30-kaixiang-xiaoji</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/photo/2025-12-02-nikon-z30-kaixiang-xiaoji</guid><pubDate>Mon, 01 Dec 2025 17:40:00 GMT</pubDate><content:encoded>&lt;p&gt;有些年头没摸相机了。上一部相机还是 2019 年买的“佳能 EOS 200D”，那时 Fooleap 还没有退网，我还在做程序员
&lt;a href=&quot;https://blog.lhasa.icu/posts/life/2019-04-20-one-single-lens&quot;&gt;《我的第一部单反相机》&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;一晃眼，六年过去了。一切都变了，我刚入圈时，Fooleap 还在为哄女朋友而苦恼，现在孩子都会打酱油了。当初认识的博友大多已停更，中间我也曾断过更。不过后来因为喜
欢上户外活动，又把博客捡了起来。现在的博客大部分内容被户外生活占据，也是我持续更新的动力&lt;/p&gt;
&lt;p&gt;前天，我把 EXIF 样式重写了，但图中的照片画质实在太烂，这对于一个完美主义者来说是无法接受的。一时间想到了相机，早年那台佳能 200D 因为闲置太久早已出掉，
看了些博主评测，最终圈定了两款：“佳能 R50”和“尼康 Z30”。因为 R50 阉割了热靴接口，我选择了尼康 Z30&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251201235817_810_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;京东尼康旗舰店下的单，16-50mm 套机，价格是 4869 元。顺丰走了两天半，属实有点慢。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251201235853_811_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;下单送了四样东西：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;64G 内存卡&lt;/li&gt;
&lt;li&gt;屏幕钢化膜&lt;/li&gt;
&lt;li&gt;座充&lt;/li&gt;
&lt;li&gt;相机包&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果不要这些赠品可以少 100 元，但想了想没必要，毕竟存储卡总是要买的，差价不大。等以后手头宽裕了再换更好的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251201235921_812_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;上手的第一感觉：这相机真的很小！还没有三星手机大，感觉完全可以揣进兜里，便携性满分&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251202011620_822_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251201235950_814_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251202011623_823_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;实际试拍了不少照片，全程 M 档，不是过曝就是欠曝。晚上去西湖大道的桥上拍车流，又没控制好，画面还是过曝了&lt;/p&gt;
&lt;p&gt;先这样吧，接着回 B 站看摄影教程去了&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%B0%BC%E5%BA%B7%20z30%20%E5%BC%80%E7%AE%B1%E5%B0%8F%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fphoto%2F2025-12-02-nikon-z30-kaixiang-xiaoji&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>我的第一次 GitHub PR</title><link>https://blog.lhasa.icu/posts/technology/2025-11-26-my-first-github-pr</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-11-26-my-first-github-pr</guid><pubDate>Wed, 26 Nov 2025 15:23:00 GMT</pubDate><content:encoded>&lt;p&gt;我一直觉得 Artalk 的 ui 设计的很不协调，特别评论框下方的“ 评论数、通知中心&quot;&lt;br /&gt;
这并非重要功能，但是官方没有做开关控制。实现后，感觉很实用，可以推一下&lt;/p&gt;
&lt;h4&gt;确定上游&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ git remote remove upstream
$ git remote add upstream https://github.com/ArtalkJS/Artalk.git
$ git remote -v
origin  git@github.com:achuanya/Artalk-ui.git (fetch)
origin  git@github.com:achuanya/Artalk-ui.git (push)
upstream        https://github.com/ArtalkJS/Artalk.git (fetch)
upstream        https://github.com/ArtalkJS/Artalk.git (push)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为我 main 分支有非常多改动，比如评论框 UI 等等。那些我不想提交，这里必须创建一个干净的分支&lt;/p&gt;
&lt;h4&gt;创建分支&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ git fetch upstream
# 基于上游仓库创建一个干净分支
$ git checkout -b clean-pr-branch upstream/master
branch &apos;clean-pr-branch&apos; set up to track &apos;upstream/master&apos;.
Switched to a new branch &apos;clean-pr-branch&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;cherry-pick 指定 commit&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ git cherry-pick 6302e4216cc5c1f34df49475ef99e81d883a2d79
CONFLICT (modify/delete): conf/artalk-ui-example.yml deleted in HEAD and modified in 6302e421 新增两个前端配置开关，用于控制列表头部显示).  Version 6302e421 (新增两个前端配置开关，用于控制列表头部显示) of conf/artalk-ui-example.yml left in tree.
Auto-merging conf/artalk.example.simple.yml
Auto-merging conf/artalk.example.yml
Auto-merging ui/artalk/src/defaults.ts
Auto-merging ui/artalk/src/style/list.scss
error: could not apply 6302e421... 新增两个前端配置开关，用于控制列表头部显示
hint: After resolving the conflicts, mark them with
hint: &quot;git add/rm &amp;lt;pathspec&amp;gt;&quot;, then run
hint: &quot;git cherry-pick --continue&quot;.
hint: You can instead skip this commit with &quot;git cherry-pick --skip&quot;.
hint: To abort and get back to the state before &quot;git cherry-pick&quot;,
hint: run &quot;git cherry-pick --abort&quot;.
hint: Disable this message with &quot;git config set advice.mergeConflict false&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;解决冲突&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ git status
On branch clean-pr-branch
Your branch is up to date with &apos;upstream/master&apos;.

You are currently cherry-picking commit 6302e421.
  (fix conflicts and run &quot;git cherry-pick --continue&quot;)
  (use &quot;git cherry-pick --skip&quot; to skip this patch)
  (use &quot;git cherry-pick --abort&quot; to cancel the cherry-pick operation)

Changes to be committed:
        modified:   conf/artalk.example.simple.yml
        modified:   conf/artalk.example.yml
        modified:   conf/artalk.example.zh-CN.yml
        modified:   conf/artalk.example.zh-TW.yml
        modified:   ui/artalk/src/defaults.ts
        modified:   ui/artalk/src/list/list.ts
        modified:   ui/artalk/src/plugins/list/count.ts
        modified:   ui/artalk/src/style/list.scss
        modified:   ui/artalk/src/types/config.ts

Unmerged paths:
  (use &quot;git add/rm &amp;lt;file&amp;gt;...&quot; as appropriate to mark resolution)
        deleted by us:   conf/artalk-ui-example.yml

$ git rm conf/artalk-ui-example.yml
rm &apos;conf/artalk-ui-example.yml&apos;

$ git cherry-pick --continue
[clean-pr-branch 0b5de4d3] 新增两个前端配置开关，用于控制列表头部显示
 Date: Wed Nov 26 02:23:21 2025 +0800
 9 files changed, 61 insertions(+), 3 deletions(-)
 
 $ git push origin clean-pr-branch
Enumerating objects: 39, done.
Counting objects: 100% (39/39), done.
Delta compression using up to 16 threads
Compressing objects: 100% (20/20), done.
Writing objects: 100% (20/20), 2.75 KiB | 281.00 KiB/s, done.
Total 20 (delta 18), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (18/18), completed with 18 local objects.
remote: This repository moved. Please use the new location:
remote:   git@github.com:achuanya/artalk-ui.git
remote:
remote: Create a pull request for &apos;clean-pr-branch&apos; on GitHub by visiting:
remote:      https://github.com/achuanya/artalk-ui/pull/new/clean-pr-branch
remote:
To github.com:achuanya/Artalk-ui.git
 * [new branch]        clean-pr-branch -&amp;gt; clean-pr-branch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大致意思就是上游没有这个文件 &lt;code&gt;conf/artalk-ui-example.yml&lt;/code&gt; 这是我复制的备份配置，用处不大，删了然后推走&lt;/p&gt;
&lt;h4&gt;使用 GitHub CLI 创建 PR&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ gh auth login
? Where do you use GitHub? GitHub.com
? What is your preferred protocol for Git operations on this host? HTTPS
? Authenticate Git with your GitHub credentials? Yes
? How would you like to authenticate GitHub CLI? Login with a web browser

! First copy your one-time code: C42D-217C
Press Enter to open https://github.com/login/device in your browser...
✓ Authentication complete.
- gh config set -h github.com git_protocol https
✓ Configured git protocol
✓ Logged in as achuanya

$ gh pr create --repo ArtalkJS/Artalk --base master --head achuanya:clean-pr-branch

Creating pull request for achuanya:clean-pr-branch into master in ArtalkJS/Artalk

? Title (required) 新增两个界面配置开关，用于控制：左侧“评论数”、右侧“通知中心” 的显示控制
? Body &amp;lt;Received&amp;gt;
? What&apos;s next? Submit
https://github.com/ArtalkJS/Artalk/pull/1113
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;地址都给出了，说明 PR 已经创建好了&lt;br /&gt;
不过 Artalk 官方已经断更几年了，审核过与否都不重要，就当玩了&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E6%AC%A1%20GitHub%20PR&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-11-26-my-first-github-pr&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Introducing Astro Lhasa 1.0</title><link>https://blog.lhasa.icu/posts/technology/2025-11-25-introducing-astro-lhasa-1-0</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-11-25-introducing-astro-lhasa-1-0</guid><pubDate>Mon, 24 Nov 2025 20:09:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;astro-lhasa-v1-thumbnail.svg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;Astro Lhasa 是一款简洁、响应式、无障碍友好、并具备良好 SEO 的 Astro 博客主题&lt;/p&gt;
&lt;p&gt;该主题基于 &lt;a href=&quot;https://github.com/satnaing/astro-paper&quot;&gt;Astro Paper&lt;/a&gt;，并借鉴了好大哥 &lt;a href=&quot;https://blog.fooleap.org/&quot;&gt;Fooleap&lt;/a&gt; 博客的布局设计&lt;/p&gt;
&lt;h2&gt;特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[x] 极快的加载性能&lt;/li&gt;
&lt;li&gt;[x] 内置 SEO 优化&lt;/li&gt;
&lt;li&gt;[x] 多语言支持（i18n）&lt;/li&gt;
&lt;li&gt;[x] 支持 Markdown、Mdx&lt;/li&gt;
&lt;li&gt;[x] 无障碍支持（键盘/旁白）&lt;/li&gt;
&lt;li&gt;[x] 响应式设计（适配手机到桌面）&lt;/li&gt;
&lt;li&gt;[x] 本地模糊搜索&lt;/li&gt;
&lt;li&gt;[x] 草稿文章与置顶&lt;/li&gt;
&lt;li&gt;[x] GLightbox 图片灯箱&lt;/li&gt;
&lt;li&gt;[x] 超链接将会在新标签页打开&lt;/li&gt;
&lt;li&gt;[x] 自动生成 sitemap 与 RSS&lt;/li&gt;
&lt;li&gt;[x] Expressive Code 代码高亮&lt;/li&gt;
&lt;li&gt;[x] 全站懒加载滚动分页、返回顶部按钮&lt;/li&gt;
&lt;li&gt;[x] 基于时间的明暗模式切换（自动适应系统主题）&lt;/li&gt;
&lt;li&gt;[x] 深度适配 Artalk 评论系统（布局结构和主题配色）&lt;/li&gt;
&lt;li&gt;[x] 自动展开和折叠的文章目录（可在文章中配置开关）&lt;/li&gt;
&lt;li&gt;[x] 为 img 标签自动添加原始宽高，支持缓存&lt;/li&gt;
&lt;li&gt;[x] 图片美化：EXIF 样式、Alt 标签（长条与角标）&lt;/li&gt;
&lt;li&gt;[x] 图片懒加载，且 src 只需要输入文件名，编译时自动补全路径&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Lighthouse 评分&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;astro-lhasa-lighthouse-score.svg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h2&gt;项目结构&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/
├── public/
│   ├── assets/
│   └── pagefind/ # auto-generated when build
├── posts/
│   ├── life
│   └── technology
│       └── 2025-11-25-introducing-astro-lhasa-1-0.mdx
├── src/
│   ├── assets/
│   │   ├── icons/
│   │   └── images/
│   ├── components/
│   ├── i18n/
│   ├── layouts/
│   ├── pages/
│   ├── styles/
│   ├── utils/
│   ├── config.ts
│   ├── constants.ts
│   └── content.config.ts
├── ecosystem.config.cjs
└── astro.config.ts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Astro 会根据 &lt;code&gt;src/pages/&lt;/code&gt; 中的 &lt;code&gt;.astro、.md、.mdx&lt;/code&gt; 文件自动生成路由&lt;/p&gt;
&lt;p&gt;静态资源（如图片）可以放在 &lt;code&gt;public&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;博客文章都放在 &lt;code&gt;posts&lt;/code&gt; 下，创建文件夹后，按照文件夹名自动分类文章&lt;/p&gt;
&lt;h2&gt;技术栈&lt;/h2&gt;
&lt;p&gt;主要框架 - &lt;a href=&quot;https://astro.build/&quot;&gt;Astro 5&lt;/a&gt;&lt;br /&gt;
语言与类型 - &lt;a href=&quot;https://www.typescriptlang.org/&quot;&gt;TypeScript&lt;/a&gt;&lt;br /&gt;
样式 - &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind CSS v4&lt;/a&gt;（&lt;code&gt;@tailwindcss/vite&lt;/code&gt;、&lt;code&gt;@tailwindcss/typography&lt;/code&gt;）&lt;br /&gt;
代码高亮 - &lt;a href=&quot;https://expressive-code.com/&quot;&gt;Astro Expressive Code&lt;/a&gt;（行号、可折叠段落）&lt;br /&gt;
Markdown/MDX 扩展 - &lt;code&gt;remark-math&lt;/code&gt;、&lt;code&gt;rehype-katex&lt;/code&gt;、&lt;code&gt;rehype-figure&lt;/code&gt;、&lt;code&gt;rehype-slug&lt;/code&gt;、&lt;code&gt;rehype-autolink-headings&lt;/code&gt;、&lt;code&gt;rehype-external-links&lt;/code&gt;、&lt;code&gt;rehype-wrap-all&lt;/code&gt;
静态搜索 - &lt;a href=&quot;https://pagefind.app/&quot;&gt;Pagefind Default UI&lt;/a&gt;&lt;br /&gt;
图片灯箱 - &lt;a href=&quot;https://biati-digital.github.io/glightbox/&quot;&gt;GLightbox&lt;/a&gt;&lt;br /&gt;
OG 图像 - &lt;a href=&quot;https://github.com/vercel/satori&quot;&gt;Satori&lt;/a&gt; + &lt;a href=&quot;https://github.com/RazrFalcon/resvg&quot;&gt;Resvg&lt;/a&gt;（站点与文章均支持）&lt;br /&gt;
构建优化 - &lt;code&gt;astro-compressor&lt;/code&gt;、&lt;code&gt;@zokki/astro-minify&lt;/code&gt;&lt;br /&gt;
友联订阅 - &lt;a href=&quot;https://github.com/achuanya/rss-lhasa&quot;&gt;RSS Lhasa&lt;/a&gt;&lt;br /&gt;
评论系统 - &lt;a href=&quot;https://github.com/achuanya/artalk-ui&quot;&gt;Artalk ui&lt;/a&gt;&lt;br /&gt;
部署 - Docker/Nginx/Pm2（含 &lt;code&gt;Dockerfile&lt;/code&gt;、&lt;code&gt;docker-compose.yml&lt;/code&gt;、&lt;code&gt;ecosystem.config.cjs&lt;/code&gt;）&lt;br /&gt;
代码规范 - &lt;a href=&quot;https://eslint.org/&quot;&gt;ESLint 9&lt;/a&gt; + &lt;a href=&quot;https://prettier.io/&quot;&gt;Prettier 3&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;使用方法&lt;/h2&gt;
&lt;p&gt;启动项目：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;pnpm install
pnpm run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也可以使用 Docker：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker build -t astropaper .
docker run -p 4321:80 astropaper
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Google 网站验证&lt;/h3&gt;
&lt;p&gt;你可以通过环境变量轻松在 Astro Lhasa 中添加 &lt;a href=&quot;https://support.google.com/webmasters/answer/9008080?sjid=3020911180724672289-NA&quot;&gt;Google 网站验证 HTML 标签&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 在你的环境变量文件 (.env) 中
PUBLIC_GOOGLE_SITE_VERIFICATION=your-google-site-verification-value
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;命令&lt;/h2&gt;
&lt;p&gt;所有命令都在项目的根目录下，通过终端运行&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安装依赖&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动本地开发服务器，访问地址为 &lt;code&gt;localhost:4321&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;构建生产环境网站到 &lt;code&gt;./dist/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在部署之前预览本地构建&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run format:check&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;检查代码格式是否符合 Prettier 标准&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run format&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 Prettier 格式化代码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run sync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;为所有 Astro 模块生成 TypeScript 类型 &lt;a href=&quot;https://docs.astro.build/en/reference/cli-reference/#astro-sync&quot;&gt;Learn more&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run lint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 ESLint 进行代码检查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 Docker 运行 Astro Lhasa，你可以通过在 dev 命令中提供的相同主机名和端口访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose run app npm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;你可以在 Docker 容器内运行上述任何命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker build -t astrolhasa .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;构建 Docker 镜像&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker run -p 4321:80 astrolhasa&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在 Docker 中运行 Astro Lhasa，网站将在 &lt;code&gt;http://localhost:4321&lt;/code&gt; 上可访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pm2 start ecosystem.config.cjs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 Pm2 启动 Astro Lhasa，访问地址为 &lt;code&gt;localhost:4321&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;警告！Windows PowerShell 用户可能需要安装 &lt;a href=&quot;https://www.npmjs.com/package/concurrently&quot;&gt;concurrently&lt;/a&gt;，如果想在开发过程中&lt;a href=&quot;https://docs.astro.build/en/reference/cli-reference/#astro-check&quot;&gt;运行诊断命令&lt;/a&gt;（例如：astro check --watch &amp;amp; astro dev）&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;License&lt;/h2&gt;
&lt;p&gt;本项目采用 Anti 996 License 授权协议发布，详情请查阅 &lt;a href=&quot;https://github.com/achuanya/astro-lhasa/blob/main/LICENSE&quot;&gt;LICENSE&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Introducing%20Astro%20Lhasa%201.0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-11-25-introducing-astro-lhasa-1-0&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>读苏轼有感（1）</title><link>https://blog.lhasa.icu/posts/book/2025-11-20-sushi-reflection-01</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/book/2025-11-20-sushi-reflection-01</guid><pubDate>Wed, 19 Nov 2025 16:29:00 GMT</pubDate><content:encoded>&lt;p&gt;今天看了一本关于苏轼的传记，其中有首诗词让我感到震惊的同时又有一种无力感&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;人生到处知何似？应似飞鸿踏雪泥&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;回想我这活了二十多年，不过在欲望的追求与失落之间摇摆，实在没有意思&lt;/p&gt;
&lt;p&gt;难道说人，这种欲望下的产物，只能困于这悲苦之中不得解脱吗？&lt;/p&gt;
&lt;p&gt;没有欲望的人还有人性吗？还是人吗？&lt;/p&gt;
&lt;p&gt;大悲寺的和尚不食人间烟火，却求佛问道，这难道不是一种欲望吗？&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%AF%BB%E8%8B%8F%E8%BD%BC%E6%9C%89%E6%84%9F%EF%BC%881%EF%BC%89&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fbook%2F2025-11-20-sushi-reflection-01&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>坐于顶，闻茶香，听古典，观夕阳</title><link>https://blog.lhasa.icu/posts/outdoors/2025-11-17-sit-top-tea-classical-sunset</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-11-17-sit-top-tea-classical-sunset</guid><pubDate>Mon, 17 Nov 2025 10:29:00 GMT</pubDate><content:encoded>&lt;p&gt;坐于顶，闻茶香，听古典，观夕阳&lt;/p&gt;
&lt;p&gt;清晨跑西湖，傍晚之江路。生于闹市，独善其行。杭州给予的诱惑实在太多太多&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;论水&lt;/strong&gt;，南至钱塘江，北望西湖边，海竿、矶竿一字排开，可摆长蛇阵。而萧山、滨江，溪河交织，水网密布，网工、电工竟遍地开花，什么叫国际大都市？这就是包容&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;论山&lt;/strong&gt;，5A级西湖风景名胜区，群山环抱。行至十里琅珰，可品茶田古道。登临北高峰，云雾缭绕，下望灵隐寺，抬头便是财神庙。只要你想，自行车都可背进山峦之中，我爱死这个地方了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155214_728_266.jpg&quot; alt=&quot;十里琅珰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天只为观景，均速和野路不在考虑范围内，所以我穿了一双运动鞋出门，凤山门乘坐308转103到达龙井村山门“十里琅珰”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155216_729_266.jpg&quot; alt=&quot;半山腰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155219_730_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;周日的台阶，人挤人。终究还是没忍住，走了野路，要么说鞋子重要，手脚并用向上爬时，脚滑了好几次，每次落脚都没有安全感&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155222_731_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155225_732_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155239_733_266.jpg&quot; alt=&quot;龙井村&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155249_734_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155305_735_266.jpg&quot; alt=&quot;九溪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155329_736_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155342_737_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155348_738_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155352_739_266.jpg&quot; alt=&quot;标毅线途经点，云栖竹径方向（野路）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155356_740_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;下山后，来到了杭州的母亲河，矶钓，路亚的圣地：钱塘江（之江路）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155404_743_266.jpg&quot; alt=&quot;钱塘江施工处，这钓位的含金量，谁懂啊！&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155358_741_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155406_744_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155408_745_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155422_747_266.jpg&quot; alt=&quot;六和塔&quot; /&gt;&lt;/p&gt;
&lt;p&gt;六和塔最近非常火，据文保所记载，这里是鲁智深听潮圆寂，武松出家的地方。乾隆曾六下江南，六次登临。是杭州地标建筑之一，建于宋，修于清，有着千年文化底蕴，是中国第一批全国重点文物保护单位&lt;/p&gt;
&lt;p&gt;有意思的是六和塔的修建背景，塔基原址是吴越王钱弘俶的南果园，只因怀疑钱塘江大潮是河妖所施，便舍园建塔。天王盖地虎，宝塔镇河妖，用在此处再合适不过&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155436_748_266.jpg&quot; alt=&quot;钱塘江（之江路）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155448_749_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155458_750_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251117155210_727_266.jpg&quot; alt=&quot;夜西湖&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%9D%90%E4%BA%8E%E9%A1%B6%EF%BC%8C%E9%97%BB%E8%8C%B6%E9%A6%99%EF%BC%8C%E5%90%AC%E5%8F%A4%E5%85%B8%EF%BC%8C%E8%A7%82%E5%A4%95%E9%98%B3&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-11-17-sit-top-tea-classical-sunset&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>27 公里 1510 米！徒步新手毕业了</title><link>https://blog.lhasa.icu/posts/outdoors/2025-11-15-biaoyi-line-newbie-graduation</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-11-15-biaoyi-line-newbie-graduation</guid><pubDate>Sat, 15 Nov 2025 10:56:00 GMT</pubDate><content:encoded>&lt;p&gt;标毅线，又名“西湖群山标准毅行线路”，全长约25公里，累计爬升约1500米。它是杭州最著名的徒步登山路线，整条线路穿行于国家AAAAA级景区“&lt;a href=&quot;https://zh.wikipedia.org/zh-cn/%E8%A5%BF%E6%B9%96&quot;&gt;杭州西湖风景名胜区&lt;/a&gt;”的山峦之中&lt;/p&gt;
&lt;p&gt;该路线诞生于2002年6月1日。当时，杭州的户外爱好者借鉴香港“&lt;a href=&quot;https://www.oxfamtrailwalker.org.hk/tc&quot;&gt;乐施毅行者&lt;/a&gt;”的众筹模式，策划并举办了首届西湖群山徒步比赛&lt;/p&gt;
&lt;p&gt;此后，这条路线便被徒步登山爱好者们称为“标毅线”，并逐渐成为了杭州户外的一张名片，也被许多人视作户外爱好者的“毕业考核线路”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141934_687_266.jpg&quot; alt=&quot;河坊街&quot; /&gt;&lt;/p&gt;
&lt;p&gt;早上六点我就起床了，洗漱、吃饭。把两个500ml的软水瓶灌满凉水。中午不打算下山，所以带足了吃的：三块芝士牛乳吐司、两个糯玉米、两个土鸡蛋、两块黑巧德芙、一包康比特盐丸，以及明胶软糖若干&lt;/p&gt;
&lt;p&gt;走到鼓楼，看到卖早点的，感觉还是没吃饱，于是又吃了四个包子和一杯豆浆&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141938_688_266.jpg&quot; alt=&quot;起点，吴山广场山脚下捡的石头&quot; /&gt;&lt;/p&gt;
&lt;p&gt;半个月前，在还没接触徒步时，我看过一个电影《&lt;a href=&quot;https://movie.douban.com/subject/3750104/&quot;&gt;朝圣之路 The Way (2010)&lt;/a&gt;》 便也学着电影里的汤姆，在起点捡了一块石头&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141943_689_266.jpg&quot; alt=&quot;同志们，胜利的时候，请你们不要忘记我们 - 裘古怀烈士遗言&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141944_690_266.jpg&quot; alt=&quot;晨时的杭州&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141948_691_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天穿了套陆军体能服：上身07陆短袖 + 21圆边帽，下身17陆长裤 + 21陆战靴。我本以为天会冷些，还多穿了件蜂窝速干背心，结果艳阳高照，大约十公里后就热得脱掉了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141950_692_266.jpg&quot; alt=&quot;杭州少年儿童公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;标毅线的常规起点在“老和云起”，而我住在凤凰山脚下，距离终点很近（吴山广场），所以我是反向而行，经过杭州少年儿童公园时，需要交15元的门票（常规路线不需要花这个钱）。在公园深处有上山的野路&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141952_693_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;在贵人阁处拍摄。图中远方的山峰应该就是：龙井、上天竺、狮峰、棋盘山、天马山、龙门山、北高峰等等，这些均在本次的行程范围内&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115141959_694_266.jpg&quot; alt=&quot;九溪茶园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142007_695_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142011_696_266.jpg&quot; alt=&quot;文碧峰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142016_697_266.jpg&quot; alt=&quot;十里琅珰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;“十里琅珰”是一条南北向的山脊线，也是杭州群山中视野最好的路段之一，可以尽览茶园风光和江湖两望&lt;/p&gt;
&lt;p&gt;若时间紧张，可以通过：地铁、公交或社会车辆抵达&lt;strong&gt;梅家坞公交站&lt;/strong&gt;，在此处就可以看到&lt;strong&gt;十里琅珰入口的牌坊&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142021_698_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142026_699_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142031_700_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142044_701_266.jpg&quot; alt=&quot;大路太平坦，不舒服，在林子里行走还能按按摩&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142048_702_266.jpg&quot; alt=&quot;西湖区方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142055_703_266.jpg&quot; alt=&quot;老和云起（北门）终点合影&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142058_704_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142104_705_266.jpg&quot; alt=&quot;还特意穿了一双厚毛袜，太闷了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142110_707_266.jpg&quot; alt=&quot;起点，吴山广场山脚下捡的石头&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142115_708_266.jpg&quot; alt=&quot;临走的时候又带走了，拿回家放花坛也不错
&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115144621_718_266.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142121_709_266.jpg&quot; alt=&quot;下山后沿着非机动车道走了几公里，本想穿行去苏堤的，误打误撞又走进一座山&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142125_710_266.jpg&quot; alt=&quot;西湖最美转角，全天挤满人&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142131_711_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142134_712_266.jpg&quot; alt=&quot;逛了一圈，准备回家&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142142_714_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天的功臣，21式作战靴。几乎没有它不能踩的地方，唯一的缺点就是太闷了。若下次还有登山需求，我仍会选择它，但日常穿就算了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142138_713_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;我妈在双十一给我买了一双新鞋，一体成型三代。我大概已经有十年没穿过黑色鞋子了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251115142145_715_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;新书也到货了。拿少许燕麦冲了杯咖啡，躺床上看会儿书&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=27%20%E5%85%AC%E9%87%8C%201510%20%E7%B1%B3%EF%BC%81%E5%BE%92%E6%AD%A5%E6%96%B0%E6%89%8B%E6%AF%95%E4%B8%9A%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-11-15-biaoyi-line-newbie-graduation&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>最近的活动</title><link>https://blog.lhasa.icu/posts/outdoors/2025-11-14-recent-activities</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-11-14-recent-activities</guid><pubDate>Thu, 13 Nov 2025 17:31:00 GMT</pubDate><content:encoded>&lt;p&gt;最近一直在徒步登山，早晚就去环西湖跑跑步，也对杭州的地貌了解差不多了，准备来一次新手毕业徒步&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213052_628_266.jpg&quot; alt=&quot;貌似战时防空洞&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213130_631_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213206_634_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213235_635_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213340_644_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213350_645_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213357_646_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213404_647_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213409_648_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213413_649_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213423_651_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213442_654_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213510_659_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是我在山顶遇到的山地大神，上一次看到骑车上山的博主叫：猛蛇过江，也是个屌人&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213514_660_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213517_661_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213523_662_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213536_665_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;出去一定要带卫生纸，狂奔下山，幸亏山脚下有公共卫生间...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251108213540_667_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113211955_672_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;迪卡侬的包有些大，不适合日常跑步。我买了一个国产奥尼捷的包，蛮小的，很适合跑步用，若在外不过夜，徒步爬山也方便&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212018_673_266.jpg&quot; alt=&quot;杭州越野跑公开赛&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212029_674_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;去杭州动物园逛了逛，感觉就那样，不如成都动物园&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212032_675_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212035_676_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212130_685_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212122_684_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212042_677_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;如果在杭州只能选择一条徒步路线，我只去十里琅珰，视野太开阔啦&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212045_678_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212049_679_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212054_680_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212057_681_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;穿骑行服跑步确实降维打击，装东西都方便了。今天右脚踝有些不舒服，但是破纪录了，可以花更短的时间来跑步了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212110_682_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;自不做采购后，再也没去过超市和市场。今天我妈不上斑，陪她去盒马买菜，看到冰柜有卖就拿了点，还是那个屌味&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251113212112_683_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;饭后我妈给我拿了一个大壶，真漂亮啊，比上次那个青花瓷壶大两倍&lt;/p&gt;
&lt;p&gt;明天我要去的是杭州的一个加强版标毅线，大概在28公里，爬升1600，也有可能是35公里&lt;/p&gt;
&lt;p&gt;我准备了玉米、鸡蛋、巧克力、盐丸、面包，明天不打算下山了，一口气走完&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%9C%80%E8%BF%91%E7%9A%84%E6%B4%BB%E5%8A%A8&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-11-14-recent-activities&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>喜得配发物资</title><link>https://blog.lhasa.icu/posts/life/2025-11-07-got-issued-suede-and-camo-shoes</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-11-07-got-issued-suede-and-camo-shoes</guid><pubDate>Fri, 07 Nov 2025 10:57:00 GMT</pubDate><content:encoded>&lt;p&gt;我最近在找连队配发的体能服和奔雷帽，但网上仿品太多了，实在不容易&lt;/p&gt;
&lt;p&gt;这不，要啥来啥，很偶然的一个机会得到了些硬货，一分没花&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171244_615_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171250_616_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;07 低腰迷彩作训胶鞋，3520 配发品&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;鞋面是莱卡布，鞋底为橡胶，鞋子左右两侧和鞋头的关键受力部位都加大了灌胶面积，踩踏的感觉非常舒服，比我的耐克强多了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171241_614_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171259_618_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171301_619_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;07 WJ 短筒绒皮鞋，3515 配发品&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上好的黄牛皮，鞋舌都是一体式的，鞋里是平剪维罗绒，底鞋是双密度橡胶底，鞋头还做了加固，整个版型非常硬&lt;/p&gt;
&lt;p&gt;还配了山东起华的防伪码，扫了下，还是第一次验证&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171305_620_266.jpg&quot; alt=&quot;WJ 配发鞋垫&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251107171332_621_266.jpg&quot; alt=&quot;野战急救包&quot; /&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;剪子&lt;/th&gt;
&lt;th&gt;1 把&lt;/th&gt;
&lt;th&gt;碘伏片&lt;/th&gt;
&lt;th&gt;4 片&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;镊子&lt;/td&gt;
&lt;td&gt;1 个&lt;/td&gt;
&lt;td&gt;三角巾绷带&lt;/td&gt;
&lt;td&gt;1 包&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;纱布&lt;/td&gt;
&lt;td&gt;2 片&lt;/td&gt;
&lt;td&gt;止血带&lt;/td&gt;
&lt;td&gt;1 卷&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OK绷&lt;/td&gt;
&lt;td&gt;10 片&lt;/td&gt;
&lt;td&gt;别针&lt;/td&gt;
&lt;td&gt;2 个&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;弹性绷带&lt;/td&gt;
&lt;td&gt;1 卷&lt;/td&gt;
&lt;td&gt;合格证&lt;/td&gt;
&lt;td&gt;1 个&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;胶带&lt;/td&gt;
&lt;td&gt;1 卷&lt;/td&gt;
&lt;td&gt;简易说明书&lt;/td&gt;
&lt;td&gt;1 份&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;消毒片&lt;/td&gt;
&lt;td&gt;10 片&lt;/td&gt;
&lt;td&gt;收纳包&lt;/td&gt;
&lt;td&gt;1 个&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%96%9C%E5%BE%97%E9%85%8D%E5%8F%91%E7%89%A9%E8%B5%84&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-11-07-got-issued-suede-and-camo-shoes&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>让博客的代码块更有表现力</title><link>https://blog.lhasa.icu/posts/technology/2025-11-03-make-blog-codeblocks-more-expressive</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-11-03-make-blog-codeblocks-more-expressive</guid><pubDate>Mon, 03 Nov 2025 15:59:00 GMT</pubDate><content:encoded>&lt;p&gt;我最初用的代码高亮插件是&lt;a href=&quot;https://shiki.style/&quot;&gt;Shiki&lt;/a&gt;，由 &lt;a href=&quot;https://github.com/satnaing/astro-paper&quot;&gt;Astro Paper&lt;/a&gt; 自带，时间久了，就感觉平平无奇的。它无法像 Git diff 那样，把增删的代码做出差异化表达&lt;/p&gt;
&lt;p&gt;直到偶然遇见 &lt;a href=&quot;https://github.com/expressive-code/expressive-code&quot;&gt;Expressive Code&lt;/a&gt;，我才发现代码高亮还能这样玩&lt;/p&gt;
&lt;p&gt;它的渲染效果蛮惊艳的，让冷冰冰的代码赋有张力：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;func greet(id int, wg *sync.WaitGroup) {
	defer wg.Done()

	delay := time.Duration(rand.Intn(3000)) * time.Millisecond
	time.Sleep(delay)

	fmt.Printf(&quot;#%d Ping %v\n&quot;, id, delay)
}

func main() {
	rand.Seed(time.Now().UnixNano())

	var wg sync.WaitGroup
  numGoroutines := 10
	numGoroutines := 5

	for i := 1; i &amp;lt;= numGoroutines; i++ {
		wg.Add(1)
		go greet(i, &amp;amp;wg)
	}

	wg.Wait()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;$ go run main.go
#2 Ping 135ms
#4 Ping 694ms
#1 Ping 842ms
#5 Ping 1.662s
#3 Ping 1.862s
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;```go title=&quot;main.go&quot; {17-20,22} del={14} ins={15,4-7} collapse={2-7} &quot;rand.Seed(time.Now().UnixNano())&quot;
func greet(id int, wg *sync.WaitGroup) {
	defer wg.Done()

	delay := time.Duration(rand.Intn(3000)) * time.Millisecond
	time.Sleep(delay)

	fmt.Printf(&quot;#%d Ping %v\n&quot;, id, delay)
}

func main() {
	rand.Seed(time.Now().UnixNano())

	var wg sync.WaitGroup
  numGoroutines := 10
	numGoroutines := 5

	for i := 1; i &amp;lt;= numGoroutines; i++ {
		wg.Add(1)
		go greet(i, &amp;amp;wg)
	}

	wg.Wait()
}
```
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;而且 Expressive Code 对静态架构非常友好，只要你的博客支持 Rehype 插件，就可以安装使用&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Docs：&lt;/strong&gt;&lt;a href=&quot;https://expressive-code.com/&quot;&gt;Expressive Code&lt;/a&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;功能&lt;/th&gt;
&lt;th&gt;语法示例&lt;/th&gt;
&lt;th&gt;说明&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;标题&lt;/td&gt;
&lt;td&gt;&lt;code&gt;title=&quot;app.ts&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;显示编辑器标签标题&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;语法高亮（ANSI）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ansi&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;渲染 ANSI 终端转义&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;行标注（高亮）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;{3,5-9}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;高亮第 3 行与 5–9 行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;行标注（新增）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ins={4-6}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;以“新增”样式高亮&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;行标注（删除）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;del={7,12}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;以“删除”样式高亮&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;行标注 + 标签&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ins={&quot;Init&quot;:3-6}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;为 3–6 行添加引用标签&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内联标注（文本）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ins=&quot;inserted&quot; del=&quot;deleted&quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;高亮匹配到的片段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;内联标注（正则）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ins=/foo$.+$/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;用正则匹配片段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;折叠区块&lt;/td&gt;
&lt;td&gt;&lt;code&gt;collapse={1-5,12-14}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;折叠多段代码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;行号开关&lt;/td&gt;
&lt;td&gt;&lt;code&gt;showLineNumbers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;需安装行号插件&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;起始行号&lt;/td&gt;
&lt;td&gt;&lt;code&gt;startLineNumber=5&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;从第 5 行开始计数&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;自动换行&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wrap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;自动换行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;悬挂缩进&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wrap hangingIndent=2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;换行时额外缩进 2 列&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;不保留缩进&lt;/td&gt;
&lt;td&gt;&lt;code&gt;wrap preserveIndent=false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;换行后不缩进&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%AE%A9%E5%8D%9A%E5%AE%A2%E7%9A%84%E4%BB%A3%E7%A0%81%E5%9D%97%E6%9B%B4%E6%9C%89%E8%A1%A8%E7%8E%B0%E5%8A%9B&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-11-03-make-blog-codeblocks-more-expressive&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>上天竺</title><link>https://blog.lhasa.icu/posts/life/2025-11-03-upper-tianzhu</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-11-03-upper-tianzhu</guid><pubDate>Sun, 02 Nov 2025 16:51:00 GMT</pubDate><content:encoded>&lt;p&gt;杭州寺庙非常多&lt;/p&gt;
&lt;p&gt;据官方统计有 271 座，早些年甚至多达 500 座，号称：&quot;东南佛国&quot;&lt;/p&gt;
&lt;p&gt;在这数百座寺庙中，林隐寺则是顶流&lt;/p&gt;
&lt;p&gt;但要论到谁的香火最灵验？法喜寺是不二之选&lt;/p&gt;
&lt;p&gt;当然，我既不信宗教，也不信命，只是逛一逛&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220834_573_266.jpg&quot; alt=&quot;观音第一灵感道场&quot; /&gt;&lt;/p&gt;
&lt;p&gt;据院内文献记载，法喜寺的历史可以追溯到一千多年前：晋天福初年（936年）&lt;/p&gt;
&lt;p&gt;那时，它还只是一座很小的观音看经院，到了南宋时期才逐渐扩建，并改名为“天竺教寺”&lt;/p&gt;
&lt;p&gt;清康熙年间，康熙南巡路过此地，赐名：&quot;法喜寺&quot;&lt;/p&gt;
&lt;p&gt;虽几经更名，但以观音为主题的思想始终未变，因此，这里的牌额才写为：&quot;观音第一灵感道场&quot;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220838_574_266.jpg&quot; alt=&quot;入三摩（ma）地&quot; /&gt;&lt;/p&gt;
&lt;p&gt;迎面的门楣：“入三摩地” 它的背后同样有题词，而且是康熙所写：“莫向外求”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220848_576_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220845_575_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220851_577_266.jpg&quot; alt=&quot;观自在菩萨&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220912_578_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220917_580_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220936_587_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220934_586_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220940_588_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102220959_593_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;没记错的话，这两只猫就住在方丈楼下的假山处&lt;/p&gt;
&lt;p&gt;我看了半小时，它们也打了半小时&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102221013_597_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102221016_598_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102221042_605_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;我觉得法喜寺的出圈是脱不开出片的&lt;/p&gt;
&lt;p&gt;因为寺庙是依山而建，层层升高，到了顶处，站在石栏边，可以能俯瞰整座寺庙，房与房错落有致，瓦檐叠影，极有层次感&lt;/p&gt;
&lt;p&gt;而且，它们很明白自己的长处，招募志愿者把守各个高地，只为维护黄金点位，让游客更好的拍照&lt;/p&gt;
&lt;p&gt;当然，这里展现的图片并不是我所说的，今天穿太厚，很热，我拍不动了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251102221034_603_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%8A%E5%A4%A9%E7%AB%BA&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-11-03-upper-tianzhu&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>船游西湖，徒步河坊街</title><link>https://blog.lhasa.icu/posts/life/2025-11-01-west-lake-boat-hefang-walk</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-11-01-west-lake-boat-hefang-walk</guid><pubDate>Fri, 31 Oct 2025 17:06:00 GMT</pubDate><content:encoded>&lt;p&gt;下午三点左右，连日的降水终于停了，出门&lt;/p&gt;
&lt;p&gt;沿着万松岭路下山，穿过长桥，我看到湖面上不少电动船。没体验过，试试&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200331_550_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;每小时 60 元，押金 100 元，可坐四人，并不算贵&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200357_552_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200341_551_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200417_553_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200434_555_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200443_556_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200452_557_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;西湖周边的公园湿气极重，几乎每棵树的阴面都覆满大面积的青苔&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200455_558_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;上次来河坊街还是 &lt;a href=&quot;https://lhasa.icu/posts/life/2021-02-12-west-lake-tour.html&quot;&gt;2021 大年初一&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200500_559_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200508_560_266.jpg&quot; alt=&quot;人民的椅子&quot; /&gt;&lt;/p&gt;
&lt;p&gt;纯铜雕塑，门口竖立着牌匾称：「人民的椅子」一时间，我竟分不清谁是人民&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200514_561_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200521_562_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个藏馆以铜雕为主，个人 IP 商业化为目的，均为朱炳仁个人作品，馆内可做交易&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200532_564_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;从头走到尾，再从尾回到头，我感觉现在的河坊街档口产品同质化非常严重&lt;/p&gt;
&lt;p&gt;同品牌的金银饰品铺和小吃档口，一条街上竟能看到三家一模一样的，从门头装修到陈列布局，几乎毫无差别，地方也不管管&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200543_566_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里是鼓楼，是杭州的热门地标之一&lt;/p&gt;
&lt;p&gt;鼓楼旁有个叫“大马弄”的菜市场，我个人认为，那才是杭州的  No.1&lt;/p&gt;
&lt;p&gt;这地方可以说是杭州最后的老底子，有些烟火气&lt;/p&gt;
&lt;p&gt;我建议去逛早市，这是多数游客不知道的地方，平台也很少推&lt;/p&gt;
&lt;p&gt;在采购部工作时，大马弄也是常来的地方，可以买到不能说的秘密&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200554_567_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;在河坊街买了一盒明信片，有三十张。感觉质量略差，打算自费邮寄给博友&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251031200558_568_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;表妹要毕业了，给我邮寄来两份就业协议书，年轻人应该明白什么意思&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%88%B9%E6%B8%B8%E8%A5%BF%E6%B9%96%EF%BC%8C%E5%BE%92%E6%AD%A5%E6%B2%B3%E5%9D%8A%E8%A1%97&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-11-01-west-lake-boat-hefang-walk&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>打造全新 Artalk 评论界面</title><link>https://blog.lhasa.icu/posts/technology/2025-10-26-artalk-custom-comment-form</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-10-26-artalk-custom-comment-form</guid><pubDate>Sun, 26 Oct 2025 15:57:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;&lt;strong&gt;Artalk-ui&lt;/strong&gt;&lt;/em&gt; 是 &lt;a href=&quot;https://github.com/ArtalkJS/Artalk&quot;&gt;Artalk&lt;/a&gt; &lt;code&gt;v2.9.1&lt;/code&gt; 的一个分支，主要重构 ui&lt;/p&gt;
&lt;p&gt;本次更新的主要功能如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全新 Artalk 评论界面，评论框分段式折叠展开，响应式布局&lt;/li&gt;
&lt;li&gt;表单处展示动态头像，自动根据邮箱哈希计算，Artalk 后端可改 API&lt;/li&gt;
&lt;li&gt;扩展 Color 变量，尽力做到一切前端非硬编码&lt;/li&gt;
&lt;li&gt;优化 Markdown Preview 体验，修复 bug&lt;/li&gt;
&lt;li&gt;添加 Crypto-js 支持（&lt;a href=&quot;https://github.com/brix/crypto-js&quot;&gt;Crypto-js&lt;/a&gt;）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;大多数其他功能，例如后端逻辑、前端接口等，基本保持不变&lt;/p&gt;
&lt;h2&gt;用法：&lt;/h2&gt;
&lt;h3&gt;1.环境要求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Node.js（^ 20.17.0）&lt;/li&gt;
&lt;li&gt;PNPM (^ 9.10.0)&lt;/li&gt;
&lt;li&gt;Go（^1.22.7）&lt;/li&gt;
&lt;li&gt;Make（任意）&lt;/li&gt;
&lt;li&gt;Gcc  (必须启用&lt;code&gt;CGO_ENABLED=1&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对环境不熟悉的，直接复制下面一条龙命令，缺哪个装哪个&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Go + Make + Gcc
sudo apt update &amp;amp;&amp;amp; sudo apt install -y make gcc &amp;amp;&amp;amp; wget https://golang.google.cn/dl/go1.21.4.linux-amd64.tar.gz &amp;amp;&amp;amp; sudo rm -rf /usr/local/go &amp;amp;&amp;amp; sudo tar -C /usr/local -xzf go1.21.4.linux-amd64.tar.gz &amp;amp;&amp;amp; for file in ~/.bashrc ~/.zshrc; do grep -q &apos;export GOROOT=/usr/local/go&apos; &quot;$file&quot; || echo -e &apos;\nexport GOROOT=/usr/local/go&apos; &amp;gt;&amp;gt; &quot;$file&quot;; grep -q &apos;export GOPATH=$HOME/go&apos; &quot;$file&quot; || echo &apos;export GOPATH=$HOME/go&apos; &amp;gt;&amp;gt; &quot;$file&quot;; grep -q &apos;export PATH=\$PATH:\$GOROOT/bin:\$GOPATH/bin&apos; &quot;$file&quot; || echo &apos;export PATH=$PATH:$GOROOT/bin:$GOPATH/bin&apos; &amp;gt;&amp;gt; &quot;$file&quot;; grep -q &apos;export GOPROXY=https://goproxy.cn,direct&apos; &quot;$file&quot; || echo &apos;export GOPROXY=https://goproxy.cn,direct&apos; &amp;gt;&amp;gt; &quot;$file&quot;; done &amp;amp;&amp;amp; SHELL_NAME=$(basename &quot;$SHELL&quot;) &amp;amp;&amp;amp; [ &quot;$SHELL_NAME&quot; = &quot;zsh&quot; ] &amp;amp;&amp;amp; source ~/.zshrc || source ~/.bashrc

# Nvm + Node + pnpm + PM2
curl -o- https://cdn.jsdelivr.net/gh/nvm-sh/nvm@v0.39.7/install.sh | bash &amp;amp;&amp;amp; export NVM_DIR=&quot;$HOME/.nvm&quot; &amp;amp;&amp;amp; [ -s &quot;$NVM_DIR/nvm.sh&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/nvm.sh&quot; &amp;amp;&amp;amp; [ -s &quot;$NVM_DIR/bash_completion&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/bash_completion&quot; &amp;amp;&amp;amp; for file in ~/.bashrc ~/.zshrc; do grep -q &apos;export NVM_DIR=&quot;$HOME/.nvm&quot;&apos; &quot;$file&quot; || echo -e &apos;\nexport NVM_DIR=&quot;$HOME/.nvm&quot;&apos; &amp;gt;&amp;gt; &quot;$file&quot;; grep -q &apos;\. &quot;\$NVM_DIR/nvm.sh&quot;&apos; &quot;$file&quot; || echo &apos;[ -s &quot;$NVM_DIR/nvm.sh&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/nvm.sh&quot;&apos; &amp;gt;&amp;gt; &quot;$file&quot;; grep -q &apos;\. &quot;\$NVM_DIR/bash_completion&quot;&apos; &quot;$file&quot; || echo &apos;[ -s &quot;$NVM_DIR/bash_completion&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/bash_completion&quot;&apos; &amp;gt;&amp;gt; &quot;$file&quot;; done &amp;amp;&amp;amp; SHELL_NAME=$(basename &quot;$SHELL&quot;) &amp;amp;&amp;amp; [ &quot;$SHELL_NAME&quot; = &quot;zsh&quot; ] &amp;amp;&amp;amp; source ~/.zshrc || source ~/.bashrc &amp;amp;&amp;amp; nvm install --lts &amp;amp;&amp;amp; npm config set registry https://registry.npmmirror.com &amp;amp;&amp;amp; npm install -g pnpm pm2 &amp;amp;&amp;amp; pnpm config set registry https://registry.npmmirror.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2.源码编译&lt;/h3&gt;
&lt;p&gt;全程 Linux 操作，如果你用 Windows，建议 &lt;a href=&quot;https://www.msys2.org/&quot;&gt;MSYS2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;git clone https://github.com/achuanya/Artalk-ui.git&lt;/code&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;根目录执行 &lt;code&gt;pnpm i&lt;/code&gt; 安装依赖&lt;/li&gt;
&lt;li&gt;找到 &lt;code&gt;./conf/artalk.example.yml&lt;/code&gt; 复制到根目录，重命名为 &lt;code&gt;artalk.yml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;运行 &lt;code&gt;make build-frontend&lt;/code&gt; （会把嵌入的前端主程序和侧边栏前端程序放入 &lt;code&gt;/public&lt;/code&gt; 目录）&lt;/li&gt;
&lt;li&gt;执行 &lt;code&gt;make build&lt;/code&gt; 构建后端&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;➜  Artalk-ui git:(master) make build
go build \
    	-ldflags &quot;-s -w&quot; \
        -o ./bin/artalk \
    	github.com/artalkjs/artalk/v2
    
➜  Artalk-ui git:(master) ls -lh ./bin/artalk                  
-rwxr-xr-x 1 lhasa lhasa 46M 10月 27 06:14 ./bin/artalk
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.使用 PM2 持久化运行&lt;/h3&gt;
&lt;p&gt;执行前，在根目录创建一个&lt;code&gt;data&lt;/code&gt;目录，用于存储数据库文件&lt;/p&gt;
&lt;p&gt;后端运行后，会在其中生成&lt;code&gt;artalk.db&lt;/code&gt;文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;➜  Artalk-ui git:(master) pm2 start ./bin/artalk --name artalk -- server
[PM2] Spawning PM2 daemon with pm2_home=/home/lhasa/.pm2
[PM2] PM2 Successfully daemonized
[PM2] Starting /home/lhasa/code/Artalk-ui/bin/artalk in fork_mode (1 instance)
[PM2] Done.
┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐
│ id │ name               │ mode     │ ↺    │ status    │ cpu      │ memory   │
├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤
│ 0  │ artalk             │ fork     │ 0    │ online    │ 0%       │ 22.7mb   │
└────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘
➜  Artalk-ui git:(master) pm2 startup                         
[PM2] Init System found: systemd
[PM2] To setup the Startup Script, copy/paste the following command:
sudo env PATH=$PATH:/home/lhasa/.nvm/versions/node/v22.21.0/bin /home/lhasa/.nvm/versions/node/v22.21.0/lib/node_modules/pm2/bin/pm2 startup systemd -u lhasa --hp /home/lhasa
➜  Artalk-ui git:(master) pm2 save
[PM2] Saving current process list...
[PM2] Successfully saved in /home/lhasa/.pm2/dump.pm2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;4. 创建管理员账号&lt;/h3&gt;
&lt;p&gt;一定要先运行后端，然后再创建管理员账号，否则会丢失数据&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;➜  Artalk-ui git:(master) ./bin/artalk admin
2025/10/27 06:32:23.291 INFO [core/gen.go:70] File Generated: /home/lhasa/.config/artalk/artalk.yml
--------------------------------
 Create admin account
--------------------------------
Enter Username: lhasa
Enter Email: haibao1027@gmail.com
Enter Password: 
Retype Password: 
--------------------------------
  Name: lhasa
  Mail: haibao1027@gmail.com
--------------------------------
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Artalk CLI 命令&lt;/h4&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;命令&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;常见用法示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;server&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;启动 Artalk 服务端&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk server -c ./artalk.yml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;admin&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;创建或修改管理员账号&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk admin&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;config&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;输出当前配置文件信息&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk config&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;export&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;导出数据（Artransfer 格式）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk export --out backup.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;import&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;导入数据（Artransfer 格式）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk import --in backup.json&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;gen&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;工具集合（如生成配置、密钥等）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk gen&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;upgrade&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;升级到最新版本&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk upgrade&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;version&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;输出版本信息&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk version&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;completion&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;生成 Shell 自动补全脚本&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk completion zsh&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;code&gt;help&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;查看帮助信息&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk help&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;参数&lt;/th&gt;
&lt;th&gt;描述&lt;/th&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-c, --config &amp;lt;path&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定配置文件路径（默认 &lt;code&gt;./artalk.yml&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk server -c /etc/artalk.yml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-w, --workdir &amp;lt;dir&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;指定工作目录（默认 &lt;code&gt;./&lt;/code&gt;）&lt;/td&gt;
&lt;td&gt;&lt;code&gt;./bin/artalk -w /var/www/artalk server&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3&gt;5.集成到博客&lt;/h3&gt;
&lt;p&gt;该样式位于：&lt;code&gt;/ui/artalk/dist&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;!-- CSS --&amp;gt;
&amp;lt;link href=&quot;http://artalk.example.com:8080/dist/Artalk.css&quot; rel=&quot;stylesheet&quot; /&amp;gt;

&amp;lt;!-- JS --&amp;gt;
&amp;lt;script src=&quot;http://artalk.example.com:8080/dist/Artalk.js&quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;!-- Artalk --&amp;gt;
&amp;lt;div id=&quot;Comments&quot;&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;script&amp;gt;
Artalk.init({
  el:        &apos;#Comments&apos;,               // 绑定元素的 Selector
  server:    &apos;http://artalk.example.com:8080&apos;, // 后端地址
  site:      &apos;Artalk 的博客&apos;,               // 你的站点名
  pageKey:   &apos;/post/1&apos;,                   // 固定链接
  pageTitle: &apos;关于引入 Artalk 的这档子事&apos;,   // 页面标题 (留空自动获取)
})
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%89%93%E9%80%A0%E5%85%A8%E6%96%B0%20Artalk%20%E8%AF%84%E8%AE%BA%E7%95%8C%E9%9D%A2&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-10-26-artalk-custom-comment-form&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>西湖阅读初体验</title><link>https://blog.lhasa.icu/posts/book/2025-10-25-first-reading-experience-at-west-lake</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/book/2025-10-25-first-reading-experience-at-west-lake</guid><pubDate>Fri, 24 Oct 2025 18:30:00 GMT</pubDate><content:encoded>&lt;p&gt;昨天跑步回来后，大腿肌肉疼痛难忍，上下台阶非常吃力&lt;/p&gt;
&lt;p&gt;毕竟很久没跑了，突然跑了十几公里，身体难免吃不消&lt;/p&gt;
&lt;p&gt;今天早上照旧六点起床，一路上尽量不做停留，所以没有拍照&lt;/p&gt;
&lt;p&gt;跑步路线和昨天不太一样&lt;/p&gt;
&lt;p&gt;从断桥下来，沿北山街直行，右转进入环城西路，结果居然跑错了，跑到了延安路&lt;/p&gt;
&lt;p&gt;坚持跑完全程回到家后，发现跑得有点超纲，距离比昨天还要长：13.73 km、1h 55m&lt;/p&gt;
&lt;p&gt;不过以后不能这样了，我在想如何调整晨跑的时间&lt;/p&gt;
&lt;p&gt;以我目前的能力，绕西湖一圈接近两个小时，实在太奢侈，毕竟上午还有其他事情要做&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174334_503_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天的早餐吃得比较晚，九点半才吃&lt;/p&gt;
&lt;p&gt;眼看中午快到了，11:50了，我还是不饿，想着出去走走，但大腿是不允许的&lt;/p&gt;
&lt;p&gt;索性拿了两本书去西湖坐坐：一本是尚未看完的“C3环球游记”，一本是未曾读过的“阅读的方法”&lt;/p&gt;
&lt;p&gt;因为住在西湖边，这几天走了很多次。即便是中午，西湖边依旧非常冷，我特地穿了红色高领毛衣和一件轻薄款的带帽羽绒服&lt;/p&gt;
&lt;p&gt;出门时，大街上不少异样眼光看我这入冬装扮，我也不当回事。我看到的路人大多穿的是短袖和轻薄外套&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174447_504_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174502_506_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;不知道小学生们在做什么户外活动，老师带队，人数大约有500人&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174538_508_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174609_509_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174629_510_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;在西湖水边找到空位的椅子不容易，唯一空着的椅子，还不能坐&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174900_514_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;终于抢到一个位置，坐下五分钟后，我旁边的那人走了，我独享了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174837_513_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;低头看书，抬头便是西湖美景&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174800_512_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;自进了柳浪闻莺后，我便把羽绒服脱掉了，确实热&lt;/p&gt;
&lt;p&gt;坐下十分钟后，北风打脸一般呼呼的吹，冻得我发抖。遮阳帽和羽绒服帽子都戴上了，还是不行&lt;/p&gt;
&lt;p&gt;我只好侧身坐着看书，就这个姿势，坚持了两个小时&lt;/p&gt;
&lt;p&gt;可乐喝得有些多了，到了下午一点，我想去小便，但卫生间距离有点远&lt;/p&gt;
&lt;p&gt;如果我一走，这个位置肯定会被占，就这样憋到两点&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174944_516_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;是的，憋不住了，从卫生间回来后，没有再去西湖边，而是在柳浪闻莺公园坐着&lt;/p&gt;
&lt;p&gt;这个地方离西湖大约两百米，四周树木茂密，风吹不到我这&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024174914_515_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;虽然这里不冷，但小蚊虫实在太多，到了三点左右，我便回家了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024175022_520_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;我住在山脚下，地方比较潮湿，小蚊子很多，这两天夜里都是蒙着头睡的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251024233908_526_266.jpg&quot; alt=&quot; &quot; /&gt;
另外，还买了一个护腰椅，BKT 加大版，以后坐在床上玩电脑会舒服一些了&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%A5%BF%E6%B9%96%E9%98%85%E8%AF%BB%E5%88%9D%E4%BD%93%E9%AA%8C&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fbook%2F2025-10-25-first-reading-experience-at-west-lake&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>时隔四年，晨跑环西湖</title><link>https://blog.lhasa.icu/posts/outdoors/2025-10-24-four-years-later-morning-run-west-lake</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-10-24-four-years-later-morning-run-west-lake</guid><pubDate>Thu, 23 Oct 2025 16:01:00 GMT</pubDate><content:encoded>&lt;p&gt;凌晨六点，鸟鸣声和钢琴乐响起，即使不看表，我也知道现在几点了，因为这是我三个小时前定的闹钟&lt;/p&gt;
&lt;p&gt;是的，昨晚又只睡了三个小时&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git log -1
commit db8a16dab43cfb744b6a926ab4356a376030a147 (HEAD -&amp;gt; main, origin/main, origin/HEAD)
Author: achuanya &amp;lt;haibao1027@gmail.com&amp;gt;
Date:   Thu Oct 23 02:16:11 2025 +0800

    fix: 修正文章中的错别字“帮”为“棒”
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;确实有些困，但就这种强度而言，不算什么，早已习惯&lt;/p&gt;
&lt;p&gt;今天是我回到杭州的第一个清晨，可不能偷懒&lt;/p&gt;
&lt;p&gt;公路车暂时不能骑了，因为碳轮裂了。这段时间都不能骑车了&lt;/p&gt;
&lt;p&gt;先憋会儿吧，打算换一对 DT Swiss 顶级圈刹轮组，大概要两万左右，所以这段时间只能跑步了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192813_480_266.jpg&quot; alt=&quot;林隐寺·检票口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192849_481_266.jpg&quot; alt=&quot;雷峰塔·检票口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;住得近就是方便，跑到林隐寺两根烟的功夫&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192916_482_266.jpg&quot; alt=&quot;苏堤·南入口公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192929_483_266.jpg&quot; alt=&quot;鄙人不善于奔跑&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192937_485_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192944_486_266.jpg&quot; alt=&quot;西湖钓鱼区&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上次我来西湖钓鱼区时，这里的钓法还没有现在这么夸张&lt;/p&gt;
&lt;p&gt;可这次，我都看到有人已经摆龙门阵了，一人八根抛竿&lt;/p&gt;
&lt;p&gt;哎，不禁感叹，是杭州对钓鱼政策的包容度高，还是对权力的包容度高？&lt;/p&gt;
&lt;p&gt;众所周知，西湖区钓鱼证件不是随便就能拿到的，清一色红色背景&lt;/p&gt;
&lt;p&gt;而且这里是苏堤，来往行人非常多，不知道那些被地方暴政一刀切的钓友看到，有何感想？&lt;/p&gt;
&lt;p&gt;中央三令五申？向来是个笑话：“有__性，没人性”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023192953_487_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193002_488_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193015_489_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193026_490_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193037_491_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193055_493_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193105_494_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023193106_495_266.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%97%B6%E9%9A%94%E5%9B%9B%E5%B9%B4%EF%BC%8C%E6%99%A8%E8%B7%91%E7%8E%AF%E8%A5%BF%E6%B9%96&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-10-24-four-years-later-morning-run-west-lake&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>我从义乌搬家到杭州了</title><link>https://blog.lhasa.icu/posts/life/2025-10-23-moving_from_yiwu_to_hangzhou</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-10-23-moving_from_yiwu_to_hangzhou</guid><pubDate>Wed, 22 Oct 2025 18:07:00 GMT</pubDate><content:encoded>&lt;p&gt;还是想回杭州，自 2021 年末，前公司把我从杭州调到上海后，我再也没有回到杭州工作过&lt;/p&gt;
&lt;p&gt;22 号中午吃完饭，我在街道上看到几辆货拉拉。上前敲了敲车窗问：“杭州去不去？”&lt;/p&gt;
&lt;p&gt;他们都说太远、没回程单，纷纷拒绝了&lt;/p&gt;
&lt;p&gt;回家的路上，我用货拉拉预约了一单&lt;/p&gt;
&lt;p&gt;又和房东阿姨打了招呼，说今晚五六点左右把房子收拾好，请她来验收&lt;/p&gt;
&lt;p&gt;收拾行李的时候，我以为东西不多&lt;/p&gt;
&lt;p&gt;可当收纳到鞋子时，实在找不到地方放&lt;/p&gt;
&lt;p&gt;我鞋子不多，只有五双，只好下楼到商店买了两个中号行李袋，一袋装鞋，一袋装书&lt;/p&gt;
&lt;p&gt;大约一小时后，东西收拾完了：五个包，一个行李箱&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023004610_477_266.jpg&quot; alt=&quot;打扫卫生中&quot; /&gt;&lt;/p&gt;
&lt;p&gt;把地面拖净后，我再次联系房东阿姨&lt;/p&gt;
&lt;p&gt;和她坐在屋里聊聊天，得知这间房还没租出去&lt;/p&gt;
&lt;p&gt;来看房的租客各种挑刺：不是嫌不朝阳，就是嫌贵&lt;/p&gt;
&lt;p&gt;我这人是不挑的，躺哪都是睡&lt;/p&gt;
&lt;p&gt;毕竟我冬天的桥洞、夏天的广场都睡过，适应能力堪比蟑螂&lt;/p&gt;
&lt;p&gt;下午五点时，我已把行李搬到楼下&lt;/p&gt;
&lt;p&gt;司机还有十分钟到，我不想等了，没啥意义&lt;/p&gt;
&lt;p&gt;我给房东阿姨发了条消息：“剩余水电费等您儿子下班后抄下水表，照合同算吧，剩多少转我就行”&lt;/p&gt;
&lt;p&gt;简单寒暄几句后，司机到了，我便走了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251023004612_478_266.jpg&quot; alt=&quot;西湖·柳浪闻莺&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到这张图时，我已经到杭州了&lt;/p&gt;
&lt;p&gt;把行李放到屋里，来不及收拾，我便跑了出去&lt;/p&gt;
&lt;p&gt;我太期待这一刻了！&lt;/p&gt;
&lt;p&gt;我爱西湖，爱这个有山有水的城市。在国内，没有比杭州更合适我的城市了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025-10-23_01-44-53.png&quot; alt=&quot;红色标点的万松岭路，便是我的住址&quot; /&gt;&lt;/p&gt;
&lt;p&gt;而且我住的地方特别棒，这里是万松岭路，距离西湖只有 1.4 公里&lt;/p&gt;
&lt;p&gt;以至于，我每天都可以坐在西湖旁看书、跑步，太爽了！&lt;/p&gt;
&lt;p&gt;房子呢，是靠山的自建房宾馆，比较老，设施也不全&lt;/p&gt;
&lt;p&gt;不过我很满足，斯是陋室，惟吾德馨嘛&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%88%91%E4%BB%8E%E4%B9%89%E4%B9%8C%E6%90%AC%E5%AE%B6%E5%88%B0%E6%9D%AD%E5%B7%9E%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-10-23-moving_from_yiwu_to_hangzhou&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>知乎答疑：个人博客内容常陷入同质化，如何找到独特风格？</title><link>https://blog.lhasa.icu/posts/life/2025-10-18-answer-how-to-find-unique-style</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-10-18-answer-how-to-find-unique-style</guid><pubDate>Sat, 18 Oct 2025 11:04:00 GMT</pubDate><content:encoded>&lt;p&gt;写博客至今，已经快八年了&lt;/p&gt;
&lt;p&gt;从最初的代码笔记，到后来记录生活，我想，有些话可以说说&lt;/p&gt;
&lt;p&gt;首先，想让个人博客保持稳定的流量增长，其实是件很难的事&lt;/p&gt;
&lt;p&gt;如果你是为了打造个人IP才写博客，那多半是在走一条弯路&lt;/p&gt;
&lt;p&gt;技术博客这条赛道太窄，同质化严重，就像 1+1=2，当答案只有一个时，你再想打破这个“2”该有多难？&lt;/p&gt;
&lt;p&gt;但突破差异化并非毫无空间，我建议从表达方式下手，而非内容本身&lt;/p&gt;
&lt;p&gt;我很喜欢「云风的 BLOG」特别是他几十年如一日的写作，这样人可不多见。他写的内容并不是迎合他人，而是源自自己内心的思考，正如他的博客副标题所言：“思绪来得快去得也快，偶尔会在这里停留”&lt;/p&gt;
&lt;p&gt;说到底，个人博客的灵魂在人，而不在技&lt;/p&gt;
&lt;p&gt;在这个以文字为主导的地方，文字功底就是风格的根基&lt;/p&gt;
&lt;p&gt;见字如见人，一个人如何写字，用怎样的语言去表达自己对世界的理解，往往能看出他的性格与气质&lt;/p&gt;
&lt;p&gt;当然，我并非什么写作高手&lt;/p&gt;
&lt;p&gt;对于我这样的文盲来说，写出一篇顺畅的文章都不容易&lt;/p&gt;
&lt;p&gt;常常写完，还得靠 ChatGPT 帮我润色，不然标点都能错得离谱&lt;/p&gt;
&lt;p&gt;但没关系，我觉得，写作的意义不只是被看见，更是认识自己&lt;/p&gt;
&lt;p&gt;当你开始书写属于自己的语言的时候，我想，你就已经走在形成独立风格的路上了&lt;/p&gt;
&lt;p&gt;最后再说一句：&lt;/p&gt;
&lt;p&gt;风格不是你刻意去造出来的，而是你坚持写下去，慢慢留下来的痕迹&lt;/p&gt;
&lt;hr /&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://www.zhihu.com/question/1962140063472285501/answer/1962880004380681990&quot; target=&quot;_blank&quot;&amp;gt;原文：个人博客内容常陷入同质化，如何找到独特风格？ - 游钓四方的回答 - 知乎&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%9F%A5%E4%B9%8E%E7%AD%94%E7%96%91%EF%BC%9A%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%E5%86%85%E5%AE%B9%E5%B8%B8%E9%99%B7%E5%85%A5%E5%90%8C%E8%B4%A8%E5%8C%96%EF%BC%8C%E5%A6%82%E4%BD%95%E6%89%BE%E5%88%B0%E7%8B%AC%E7%89%B9%E9%A3%8E%E6%A0%BC%EF%BC%9F&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-10-18-answer-how-to-find-unique-style&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>首次徒步爬山，误闯深山老林，徒手爬悬崖，两度滑落险些丧命</title><link>https://blog.lhasa.icu/posts/outdoors/2025-10-15-first-hike-deep-forest-cliff-fall</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-10-15-first-hike-deep-forest-cliff-fall</guid><pubDate>Wed, 15 Oct 2025 02:05:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;偶尔走点野路，也是一种出路&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;徒步去哪？&lt;/h2&gt;
&lt;p&gt;我准备离开义乌了，去杭州，25 号之前房租到期，在此之前再看看义乌&lt;/p&gt;
&lt;p&gt;这座城市周边大多数山峰，只要骑车能走的，基本上都有我的车轮印&lt;/p&gt;
&lt;p&gt;但某些自行车无法涉足的地方，我却从未去过。所以这次，我决定徒步&lt;/p&gt;
&lt;p&gt;通过媒体了解到附近有几个徒步爬山的项目：仙华山、德胜岩、牛头山、大寒尖...&lt;/p&gt;
&lt;p&gt;最终，我选择了大寒尖。距离我所在的地方大约四十公里，就这点距离，骑公路车都不够我热身的，但这次不一样，这是首次徒步爬山&lt;/p&gt;
&lt;p&gt;出发前，我觉得头发太长，去万体广场理发，回家已是12:50。于是，我赶紧预约了滴滴顺风车，计划1:30点之前出发&lt;/p&gt;
&lt;p&gt;背了一个 QUECHUA FH500 背包，容量 17 升，内含 2 升水袋，下楼跑去好想来购物，买 3 瓶怡宝、3 个面包和 1 包巧克力&lt;/p&gt;
&lt;p&gt;结账出来，司机就到了。坐上车不久后才想起来，盐丸在家中没拿&lt;/p&gt;
&lt;h2&gt;羊印登寒山，天龙古道难&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251014013253_334_266.jpg&quot; alt=&quot;14:30 抵达 大寒尖-登山口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;大寒尖位于义乌市南部的赤岸镇，海拔 925.6 米，是义乌境内第一制高点&lt;/p&gt;
&lt;p&gt;登顶大寒尖的路线有很多种，据统计，至少有四五条，而我选择了“赤岸镇羊印村起步”的路线，是绝佳线路之一，途径天龙古寺，尚有一古道蜿蜒曲折，鲜为人知，当地人称“天龙古道”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013256_335_266.jpg&quot; alt=&quot;现在有人疼了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013257_336_266.jpg&quot; alt=&quot;神门&quot; /&gt;&lt;/p&gt;
&lt;p&gt;“神门”，这是道教文化中的象征性门户，代表人与天界、人与神灵之间的通道。也可以说是徒步通往山顶的门，心灵的门&lt;/p&gt;
&lt;p&gt;写作时，我回想整个行程，没有看到关于道教的踪迹啊？倒是有一个天龙古寺，但是佛教和神门属实是王八看绿豆&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013300_337_266.jpg&quot; alt=&quot;兴致勃勃&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013306_338_266.jpg&quot; alt=&quot;太阳能长凳，支持USB和无线充电&quot; /&gt;&lt;/p&gt;
&lt;p&gt;政绩工程开始发力，太阳能长凳，支持USB和无线充电，是个好东西，不过呢，这放在登山口又有何用？放高了，领导看不见？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013311_340_266.jpg&quot; alt=&quot;正道&quot; /&gt;&lt;/p&gt;
&lt;p&gt;正道，既天道。顺应天地，返照本心&lt;/p&gt;
&lt;p&gt;鄙人在此立下Flag：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;当初参与设计大寒尖羊印村路线的领导若不认同道教，我当场把这块石头吃掉&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;20251014013315_342_266.jpg&quot; alt=&quot;到达第一个可以遥望远处的点位&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013317_343_266.jpg&quot; alt=&quot;顽强的大树&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这树的生命力简直太强了！放在这里警示十分合适，有意而为之？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013321_345_266.jpg&quot; alt=&quot;非雨季一点水没有，还没有家里花洒降水大&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013323_346_266.jpg&quot; alt=&quot;还有五分钟就到了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013332_351_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013334_352_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013336_353_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个物价在山上并不贵，毕竟搬运到山上需要成本&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013337_354_266.jpg&quot; alt=&quot;天龙山-山塘-总库容：1.6 万立方米&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013344_358_266.jpg&quot; alt=&quot;羊印村方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013345_359_266.jpg&quot; alt=&quot;无人售水点，大妈欢乐地&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013346_360_266.jpg&quot; alt=&quot;天龙古寺&quot; /&gt;&lt;/p&gt;
&lt;p&gt;寺因山得名，山因寺著称，建于明初，前身为天龙庵&lt;/p&gt;
&lt;p&gt;据“浙江通志”记载，天龙庵内失火烧为灰烬，后又捐募重建为天龙古寺&lt;/p&gt;
&lt;p&gt;清康熙乾隆年间香火最旺，常年有居士近百人，而今天我只见到一个人&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013349_362_266.jpg&quot; alt=&quot;解锁地图一份&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013353_364_266.jpg&quot; alt=&quot;天龙古寺-石门匾&quot; /&gt;&lt;/p&gt;
&lt;p&gt;2014年山塘重修，在塘底发现石门匾，它在这里出现也是有原因的&lt;/p&gt;
&lt;p&gt;解放以后，官老爷搞政绩，把天龙古寺拆了扩容。1964 年开工,1972 年竣工，直到 2004 年才重建天龙古寺&lt;/p&gt;
&lt;h2&gt;误闯深山野林&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251014013354_365_266.jpg&quot; alt=&quot;天龙山方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013356_366_266.jpg&quot; alt=&quot;旱厕&quot; /&gt;&lt;/p&gt;
&lt;p&gt;至少有十年没见过旱厕了，小时候家里也有，屋外一个，屋内一个&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013401_369_266.jpg&quot; alt=&quot;分叉口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我最早走的是左边，半公里后看不到路，都是灌木丛就返回走了右边的路&lt;/p&gt;
&lt;p&gt;直到从右边走出去我才知道，左边的野路也能过去&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013404_370_266.jpg&quot; alt=&quot;中间是根电线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这边还在修缮中，我看到了整捆的电线丢在灌木丛中，想必是专门放在这的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013407_371_266.jpg&quot; alt=&quot;华南毛蕨，又名：大风寒、书子草&quot; /&gt;&lt;/p&gt;
&lt;p&gt;发现了毛蕨，长得太旺盛了，特漂亮。回家后查阅资料，原来这是华南毛蕨，又名：大风寒、书子草&lt;/p&gt;
&lt;p&gt;它有多重价值，叶子味苦性寒，可入中药，同时也能制造氧气，市面上小棵的售价都要三十多，像图中这品相，估摸着能卖四五百元&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013416_375_266.jpg&quot; alt=&quot;非常干净的白跑鞋（即将变色）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013417_376_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013419_377_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013421_379_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013427_382_266.jpg&quot; alt=&quot;蛮坚强的植物，你知道它叫什么吗？&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013431_386_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到这竹林，我不禁想起洛阳城外绿竹巷，想起了令狐冲和任盈盈，想起了清新普善咒。梦想有一天，我也能依山傍水，住在竹林深处，好不快活&lt;/p&gt;
&lt;h3&gt;误闯副本 “深林奇径”&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;20251014013432_387_266.jpg&quot; alt=&quot;三蹦子，羊印村方向（起点）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当我从灌木丛中出来，看到水泥路时，彻底打消了我在林中的所有疑虑，以为自己终于走上了“正道”&lt;/p&gt;
&lt;p&gt;然而，这段路竟是我最后享福的时刻。紧接着，道路彻底消失，只剩下一望无际的灌木丛和几乎无法直立行走的陡峭山坡&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013434_388_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013436_389_266.jpg&quot; alt=&quot;倒了的树&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;手机丢了&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;20251014013438_390_266.jpg&quot; alt=&quot;四周都是灌木丛，丢手机之前拍的照&quot; /&gt;&lt;/p&gt;
&lt;p&gt;走到这里，我才发觉不对劲。后面的灌木丛没有那么深，可以轻松踩踏过去。更扯淡的是，我的手机马上就要丢了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013441_391_266.jpg&quot; alt=&quot;处于高心率懵逼状态&quot; /&gt;&lt;/p&gt;
&lt;p&gt;穿越灌木丛后，又来到了一段上坡路，全是小溪和大石头&lt;/p&gt;
&lt;p&gt;此时，我的腿上、鞋上爬满了小虫子，一些不知名的带刺植物贴在身上，还有蚊子在脖子边上嗡嗡作响，时不时亲我一下&lt;/p&gt;
&lt;p&gt;由于需要上坡，我决定先把手机收起来，我穿着短裤，没有口袋，便将手机放进了背包附带的小腰包里，但手机只能竖着放进去2/3&lt;/p&gt;
&lt;p&gt;就这样，我踩着石头，跳过几条小溪，大约 300 米后，音乐声呢？手机没电了？&lt;/p&gt;
&lt;p&gt;低头一看腰包，手机没了！我立刻转身，扒开灌木丛寻找，又去小溪边查看&lt;/p&gt;
&lt;p&gt;万幸，最终我在第一个小溪的石头下面找到了丢失的手机，没有掉进水里...&lt;/p&gt;
&lt;h2&gt;首次爬山，徒手爬悬崖&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251014013442_392_266.jpg&quot; alt=&quot;悬崖峭壁&quot; /&gt;&lt;/p&gt;
&lt;p&gt;左边的灌木丛就是悬崖，角度很大，望一眼深不见底。幸好通道不算太窄，足够容纳一个人通过，我担心发生意外，侧身横着走的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013446_394_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;虽然心率很高，但这已经是登顶前最舒服的时刻了，因为接下来将开启地狱级试炼&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013448_395_266.jpg&quot; alt=&quot;我在休息&quot; /&gt;&lt;/p&gt;
&lt;p&gt;横穿悬崖峭壁后，我来到侧方，山路没了！他妈的灌木丛也没了！我环顾四周，脑子里只剩下两个选择：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;原路返回&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;徒手爬悬崖&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;我在山脚下犹豫了一分钟，思考是否要爬上去。毕竟今天是我首次徒步爬山，没有任何攀爬经验&lt;/p&gt;
&lt;p&gt;然而，当我爬到 1/3 处时就再也走不上去了。角度实在太大了，斜坡上满是树叶和山顶滑落的砂砾石子，特别滑，脚掌根本使不上力气！&lt;/p&gt;
&lt;p&gt;既然脚掌无用，那就用臂力。出于求生本能，我下意识地抓住一切能抓住的东西，向上攀爬&lt;/p&gt;
&lt;p&gt;图中的树看似相邻很近，实际上距离有 1 米，有的甚至 2 米，我用手试探性地抓住身边的石头和树根，微微用力拉扯，确认牢固后，快速向上调，再抓住大枝干&lt;/p&gt;
&lt;p&gt;此时，腿部的力量几乎毫无作用，在没有树木依靠的情况下，我连蹲着都会滚下悬崖，可想而知角度有多大&lt;/p&gt;
&lt;p&gt;就在这张图的下方，我还滑落两次，险些滚下悬崖。如果不是脚掌正好抵住了身后的树，我今天就不配在这里吹牛逼了&lt;/p&gt;
&lt;p&gt;你看看图中，遥望灌木丛，遥望灌木丛，白茫茫一片，什么都没有，底下就是悬崖啊！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013451_396_266.jpg&quot; alt=&quot;我在休息&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我的细胳膊臂力实在不行，爬到这里已经是精疲力尽了，我休息了大约 2 分钟，汗如雨下，几乎睁不开眼睛&lt;/p&gt;
&lt;p&gt;说实话，在这里掏出手机拍照，需要勇气&lt;/p&gt;
&lt;p&gt;上山前，我担心出现意外，就把手机装进了背后拉链包里的背包，自然不必担心&lt;/p&gt;
&lt;p&gt;但在这里，我必须脱下背包拿出手机，心里想着：回去必须写篇博客，吹牛逼&lt;/p&gt;
&lt;h3&gt;登顶后迷路&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;20251014013452_397_266.jpg&quot; alt=&quot;湿透的背包&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013454_398_266.jpg&quot; alt=&quot;湿透的我&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WOW！WOW！WOW！&lt;/p&gt;
&lt;p&gt;顺利登顶后，我的头脑是懵的，心率极高，加上太阳直射，热得我有点晕头转向&lt;/p&gt;
&lt;p&gt;我脱下背包和帽子，挂在树干上，环顾四周转了一圈。我确定自己到达了一个山顶，但不知道是哪一个&lt;/p&gt;
&lt;p&gt;当我意识到我所在的位置信息后，多少有些后怕。心想：彻底走错路了，我根本看不到生路啊！原路我根本下不去！&lt;/p&gt;
&lt;p&gt;我随即掏出手机，看了看时间，此时已经四点多了，想想以外我想起以往的生活经验，五点左右天色就会变暗，六点天就完全黑了！&lt;/p&gt;
&lt;p&gt;想到这，我开始焦急起来。我没有任何露营装备。我打开背包，检查水袋和瓶中的存水：两包面包、一包巧克力、水800毫升&lt;/p&gt;
&lt;p&gt;在进入深山野林后，我喝完的瓶子一个都没扔，就怕出事，留着瓶子还有用。心想：可能真要派上用场了！&lt;/p&gt;
&lt;p&gt;在环顾四周一圈后，实在看不到路，我不免有些心虚。我想起了“神秘园”，一位专门报道探险事故的抖音博主，像我这样的事件，他已经做过很多期了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013456_399_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;在确认没有生路后，我拨打了119，虽然手机没有网络信号，但电话确实可以打通，这也是我这辈子第一次打 119&lt;/p&gt;
&lt;p&gt;接通后，一个男生接了电话，直觉告诉我他年纪可能与我相仿。他问我什么事？&lt;/p&gt;
&lt;p&gt;我说：“我在大寒尖迷路了，登顶了一个不知道叫什么山的山峰，周围看不到生路。您了解这片区域吗？我该如何寻找下山的方向？”&lt;/p&gt;
&lt;p&gt;119 犹豫了半天没说话，回复道：“这事我们管不了，你打110。”无论我讲什么，他也只是轻描淡写地重复：“你打110。”&lt;/p&gt;
&lt;h3&gt;生路&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;20251014013457_400_266.jpg&quot; alt=&quot;找到生路，&quot; /&gt;&lt;/p&gt;
&lt;p&gt;挂断电话后，我不想再报警了，即便打了110，估计也是让我原地不动，等待救援&lt;/p&gt;
&lt;p&gt;此时已接近五点，我必须尽快离开深山老林，因为我浑身湿透，天色一暗，必定会失温&lt;/p&gt;
&lt;p&gt;我有过多次长途夜骑失温的经历，十分清楚后果是什么，所以留给我的时间已经不多了！&lt;/p&gt;
&lt;p&gt;我首先走到最左边，到悬崖边看了看，无望后，又沿着悬崖，一直找到了最右边&lt;/p&gt;
&lt;p&gt;下意识地抬了一下头，望向远处，我居然看到了大寒尖山顶的石台阶！低头，发现在我面前赫然是一条生路！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013459_401_266.jpg&quot; alt=&quot;两山中间的一条细长野路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013501_403_266.jpg&quot; alt=&quot;迷路方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;WOW！WOW！WOW！&lt;/p&gt;
&lt;p&gt;穿过灌木丛成功来到水泥路时，我当时太他妈激动了！我还看到山下有人在台阶上行走&lt;/p&gt;
&lt;p&gt;而我的右手边，就是最后的台阶，爬上去就是义乌的制高点，大寒尖！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013500_402_266.jpg&quot; alt=&quot;迷路方向的对面，悬崖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;望着登顶的台阶，我心里别提多高兴。但在进入深山野林之前，我是嗤之以鼻的&lt;/p&gt;
&lt;p&gt;所以，当我得知自己迷路后，其实是有赌的成分，我觉得我可以闯出去，也不用走枯燥的台阶，这很有意思&lt;/p&gt;
&lt;p&gt;其实，我本是个乖孩子，只是社会把我鞭打成了一个不安分的人&lt;/p&gt;
&lt;p&gt;长大后，出于对传统文化的厌恶，按规则办事是我最为反感的&lt;/p&gt;
&lt;p&gt;不走寻常路，面对各种未知的风险，会让我荷尔蒙上升，感觉自己还活着&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013504_404_266.jpg&quot; alt=&quot;最后的台阶&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013505_405_266.jpg&quot; alt=&quot;一直清理不干净的帽子&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013508_407_266.jpg&quot; alt=&quot;即将登顶&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013514_410_266.jpg&quot; alt=&quot;赶紧点火来一张&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013519_414_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013517_412_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;图中露出石壁的山峰，是我的来时路，更是我徒手爬山的地方，你是否还记得上章节，我侧身穿过的悬崖？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013518_413_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013522_416_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013525_418_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013528_420_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是我在最后登顶时遇到的大哥，他体力非常好，我俩互相帮对方拍了几张照。离开山顶后，我们便分开了&lt;/p&gt;
&lt;p&gt;下山后我把所拍视频发布在抖音，15 号下午大哥便刷到了我，缘分啊！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013532_423_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013534_424_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;图中显示已行走 3.53 km。鬼知道我跑到深山野林，在地图上画了个圈，比直线距离都长&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013549_430_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;下山走台阶是最无聊的事情，只能低头，不能抬头&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013551_431_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;走乏了，我并不是累了，只是觉得下楼梯好枯燥&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013553_432_266.jpg&quot; alt=&quot;天龙古寺-公共卫生间&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当我看到这个场景的时候，心里是什么滋味？谁能懂啊？&lt;/p&gt;
&lt;p&gt;我明明来到了天龙古寺，还拍下了路牌和地图，但我没有仔细看，所以我根本不知道正常的路线是在房子后面...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013615_433_266.jpg&quot; alt=&quot;天龙古寺-深林奇径方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;站在公共卫生间的水龙头旁，我简单冲洗了一下，把身上的脏东西擦掉。跨上背包，边下山，边干饭&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013616_434_266.jpg&quot; alt=&quot;面包、巧克力&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013617_435_266.jpg&quot; alt=&quot;傍晚时的天龙山山塘&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013619_436_266.jpg&quot; alt=&quot;傍晚时的山腰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013623_439_266.jpg&quot; alt=&quot;傍晚时的亭子，我上山时曾在此闭目打坐五分钟，以控制高心率&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013626_442_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是我下山路上遇到的第一个灯，而这个灯却装在起点门口&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013625_441_266.jpg&quot; alt=&quot;起点石门&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013634_449_266.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013627_443_266.jpg&quot; alt=&quot;大寒尖-广场方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013628_444_266.jpg&quot; alt=&quot;跳舞的老年人&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251014013629_445_266.jpg&quot; alt=&quot;顺风车&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下山时已是六点，天完全黑了。走到广场内，手机信号恢复满格&lt;/p&gt;
&lt;p&gt;我打开滴滴顺风车，发布了半天都没有人接单。毕竟我在非常偏远的地方，用我常说的那句话就是：鸟不拉屎的地方&lt;/p&gt;
&lt;p&gt;大约五分钟后，一名司机接了我的订单，通过在线消息说要 40 分钟左右才能赶到。我说我可以等，你过来吧。&lt;/p&gt;
&lt;p&gt;等到了约定时间，司机还没来，我有些焦急，打开手机准备联系司机。卧槽！订单被取消了！&lt;/p&gt;
&lt;p&gt;我白白等了 40 分钟！不过我发现好像是我的问题，六点以后手机自动开启了免打扰，不管是谁的电话都打不进来。通话记录显示，司机曾尝试联系我。&lt;/p&gt;
&lt;p&gt;没办法，只能再找一辆车。我又打开滴滴，这次接单速度慢了很多，十分钟后才有人接单&lt;/p&gt;
&lt;p&gt;在多次通话并增加了红包小费后，我等待了一个小时，司机终于到达登山口&lt;/p&gt;
&lt;h2&gt;视频素材&lt;/h2&gt;
&lt;h3&gt;下山遇到天龙古寺&lt;/h3&gt;
&lt;p&gt;&amp;lt;video width=&quot;736&quot; height=&quot;414&quot; controls&amp;gt;
&amp;lt;source
src=&quot;3eea00c93f425185f086a60d98df8b07.mp4&quot;
type=&quot;video/mp4&quot; /&amp;gt;
你的浏览器不支持 HTML5 视频播放。
&amp;lt;/video&amp;gt;&lt;/p&gt;
&lt;h3&gt;徒手爬悬崖登顶后&lt;/h3&gt;
&lt;p&gt;&amp;lt;video width=&quot;736&quot; height=&quot;414&quot; controls&amp;gt;
&amp;lt;source
src=&quot;8dfe602755e253e2a5d113e1c328bb6a.mp4&quot;
type=&quot;video/mp4&quot; /&amp;gt;
你的浏览器不支持 HTML5 视频播放。
&amp;lt;/video&amp;gt;&lt;/p&gt;
&lt;h2&gt;复盘&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;weixingditu.png&quot; alt=&quot;天龙古寺，卫星地图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我是在下山后，在等车时看地图才知道，我误闯进的深山老林是难度最高的路线。在卫星地图中向左走的那条路，官方将其命名为：&lt;strong&gt;“深林奇径”&lt;/strong&gt;
&lt;img src=&quot;20251014013636_450_266.jpg&quot; alt=&quot;Strava记录&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%A6%96%E6%AC%A1%E5%BE%92%E6%AD%A5%E7%88%AC%E5%B1%B1%EF%BC%8C%E8%AF%AF%E9%97%AF%E6%B7%B1%E5%B1%B1%E8%80%81%E6%9E%97%EF%BC%8C%E5%BE%92%E6%89%8B%E7%88%AC%E6%82%AC%E5%B4%96%EF%BC%8C%E4%B8%A4%E5%BA%A6%E6%BB%91%E8%90%BD%E9%99%A9%E4%BA%9B%E4%B8%A7%E5%91%BD&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-10-15-first-hike-deep-forest-cliff-fall&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>夜骑：环岩口水库，遭翻车</title><link>https://blog.lhasa.icu/posts/outdoors/2025-10-11-night-ride-yankou-crash</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-10-11-night-ride-yankou-crash</guid><pubDate>Sat, 11 Oct 2025 20:51:00 GMT</pubDate><content:encoded>&lt;h2&gt;又想去夜骑&lt;/h2&gt;
&lt;p&gt;傍晚六点，洗了个热水澡，换上骑行裤，带好装备便推车出了门&lt;/p&gt;
&lt;p&gt;到厚富夜市吃碗八宝粥，八个蒸饺，一颗茶叶蛋，还没想好去哪儿&lt;/p&gt;
&lt;p&gt;打开地图翻了翻，没想到北苑附近居然有依山傍水的地方“岩口水库”&lt;/p&gt;
&lt;p&gt;照片上是平整的柏油路，非常近，不到20公里&lt;/p&gt;
&lt;h2&gt;王羲之后裔的村落&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251011233354_309_266.jpg&quot; alt=&quot;东石线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;七点半，抵达东石线，整条路都没有灯光，路长大概几公里&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233347_308_266.jpg&quot; alt=&quot;石明堂&quot; /&gt;&lt;/p&gt;
&lt;p&gt;石明堂村，一个四面环山的小村庄&lt;/p&gt;
&lt;p&gt;有意思的是，这里人自称是王羲之的后裔&lt;/p&gt;
&lt;p&gt;相传王羲之长子当年从绍兴逃亡，携眷到伏龙西山定居（现在的石明堂村）&lt;/p&gt;
&lt;p&gt;目前家族人数在村中占比95%，村礼堂还供着王羲之的画像&lt;/p&gt;
&lt;h2&gt;岩口水库故事线开始&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251011233403_310_266.jpg&quot; alt=&quot;上溪岩口湖骑行线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;岩口水库是义乌最大的人工水库，当地人称小千岛湖，也是国家A级旅游景区&lt;/p&gt;
&lt;p&gt;每逢3月23日，金华体育局都会以上溪桃花节和岩口水库为主题举办骑行赛事&lt;/p&gt;
&lt;p&gt;我查阅了往年的赛事规则，估计不太好报名&lt;/p&gt;
&lt;p&gt;湖边路窄，赛事限定600人，报名还不挤破头？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233426_312_266.jpg&quot; alt=&quot;杨横线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这柏油路真不错，不止这一段，整个环湖几乎都是这样！&lt;/p&gt;
&lt;p&gt;握紧车把，感受管胎在地面滑行，静音顺滑，没有一点碎石的碾压反馈!&lt;/p&gt;
&lt;p&gt;在这样的路面骑行，就是一种享受！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233430_313_266.jpg&quot; alt=&quot;不知名黑坑&quot; /&gt;&lt;/p&gt;
&lt;p&gt;穿过铜陵隧道，右拐上岭线，看到一个黑坑&lt;/p&gt;
&lt;p&gt;我扫了一眼，有二十多人&lt;/p&gt;
&lt;p&gt;哎，我也好久没钓鱼了，至于上次去黑坑是什么时候，我记不得了&lt;/p&gt;
&lt;h2&gt;意外翻车&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251011233442_315_266.jpg&quot; alt=&quot;上岭线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;骑行到上岭线桥边，忽然感觉在进行踩踏时，大小腿施展不开&lt;/p&gt;
&lt;p&gt;我没多想，抬头看一眼湖面，便靠边停车，点了根烟&lt;/p&gt;
&lt;p&gt;看着车座和车把的高度差，这时才发现，车座高度不对，肯定降下去了，八成是上周螺丝没拧紧，导致颠簸下滑了&lt;/p&gt;
&lt;p&gt;更糟糕的是，尾灯光线忽明忽暗，还便随着闪烁&lt;/p&gt;
&lt;p&gt;我按了几下开关，没反应，得，这下尾灯怕是要没电了&lt;/p&gt;
&lt;p&gt;车座还能凑合，可没尾灯夜骑，那是拿命骑啊！&lt;/p&gt;
&lt;p&gt;之前，我从河南骑到上海，夜行赶路就吃过大亏，当时就是这个尾灯&lt;/p&gt;
&lt;p&gt;白天耽误了时间，为了赶路到宾馆，我在国道骑行到凌晨，尾灯亏电&lt;/p&gt;
&lt;p&gt;天色黑到伸手不见五指，后面半挂车时不时来个擦肩而过，我心跳声比车声还响！&lt;/p&gt;
&lt;p&gt;更扯淡的是，尾灯是 Micro USB 接口&lt;/p&gt;
&lt;p&gt;上海工作时，在黄浦TREK旗舰店买的，将近四百块，纯工业垃圾&lt;/p&gt;
&lt;h2&gt;等一个有缘人&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251011233605_329_266.jpg&quot; alt=&quot;岩口水库&quot; /&gt;&lt;/p&gt;
&lt;p&gt;犹豫片刻，想着&lt;/p&gt;
&lt;p&gt;如果我继续向前骑，车座可能会再往下滑&lt;/p&gt;
&lt;p&gt;从地图上看，进山有好几条路，我不知道里面是什么环境，一旦出问题更麻烦&lt;/p&gt;
&lt;p&gt;先不管了，坐在桥边，又点一根，等有缘人&lt;/p&gt;
&lt;p&gt;我知道后方有一队骑行佬在歇脚，该桥是他们的必经之地&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233458_318_266.jpg&quot; alt=&quot;大哥在帮我找内六角扳手&quot; /&gt;&lt;/p&gt;
&lt;p&gt;十分钟后，路过一辆摩托&lt;/p&gt;
&lt;p&gt;我高举右手，大声喊：“大哥，有修车工具吗？我需要扳手！”&lt;/p&gt;
&lt;p&gt;他骑出去五十米远后停下，回头望我一眼，又调头回来&lt;/p&gt;
&lt;p&gt;从车上的工具包里掏出一个工具包，说：“你看看有没有合适的，如果没有，我箱子里还有”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233452_317_266.jpg&quot; alt=&quot;内六角扳手&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我接过包，倒在石板上，一眼就看到合适的内六角&lt;/p&gt;
&lt;p&gt;拧松、上调、锁紧后，我把工具包双手递给了他&lt;/p&gt;
&lt;p&gt;真是巧，太幸运了！&lt;/p&gt;
&lt;p&gt;修好后，我俩坐在桥边抽烟，闲聊十分钟&lt;/p&gt;
&lt;p&gt;就在这时，后方的骑行队也呼啸而过&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233527_322_266.jpg&quot; alt=&quot;骑行逐风花海间，相守誓言山海鉴&quot; /&gt;&lt;/p&gt;
&lt;p&gt;骑上车后，锁鞋和锁踏扣紧的瞬间，熟悉的感觉又回来了，太舒服了！&lt;/p&gt;
&lt;p&gt;唯一的隐患就是尾灯，时亮时暗，像在喘气似得&lt;/p&gt;
&lt;p&gt;由于尾灯问题，这次环湖行程只完成了约九成&lt;/p&gt;
&lt;p&gt;翻越山路，直奔上溪镇，脑子里就俩字，回家&lt;/p&gt;
&lt;h2&gt;意外惊喜&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20251011233534_323_266.jpg&quot; alt=&quot;KIPRUNKIPRUN 马拉松腰带包 5号&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个腰带包是我刚学习跑步时在郑州迪卡侬买的&lt;/p&gt;
&lt;p&gt;原本只是跑步时装个手机和钥匙，没想到骑行的穿戴体验意外地舒服&lt;/p&gt;
&lt;p&gt;如今骑行服的款式越来越多，有些骑行裤也设计了储物口袋&lt;/p&gt;
&lt;p&gt;可真把东西放进去骑车时，我总觉得大腿伸展不自然&lt;/p&gt;
&lt;p&gt;至于骑行服，天气一热就闷得慌，背后的口袋一旦装上东西，那负重感时刻贴在背上&lt;/p&gt;
&lt;p&gt;如果像我一样单穿骑行服，先不说背后的负重感，口袋里的烟盒被汗水泡烂不知多少次了&lt;/p&gt;
&lt;p&gt;而腰带包完全没有这些问题&lt;/p&gt;
&lt;p&gt;至少对我来说，腰部一点负担都没有，轻松、自在&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251012001957_331_266.jpg&quot; alt=&quot;KIPRUNKIPRUN 马拉松腰带包 5号&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233548_326_266.jpg&quot; alt=&quot;KIPRUNKIPRUN 马拉松腰带包 5号&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这腰带包不到一百块，四个互通口袋加一个封闭袋&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251012002000_332_266.jpg&quot; alt=&quot;KIPRUNKIPRUN 马拉松腰带包 5号&quot; /&gt;&lt;/p&gt;
&lt;p&gt;大口袋不漏边，可塞进7英寸的手机&lt;/p&gt;
&lt;p&gt;但大口袋是和其他口袋互通，如果物品过小，在运动中，物品可能会移位&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251011233555_327_266.jpg&quot; alt=&quot;KIPRUNKIPRUN 马拉松腰带包 5号&quot; /&gt;&lt;/p&gt;
&lt;p&gt;小口袋只能装进6英寸，其为封闭空间&lt;/p&gt;
&lt;p&gt;这款腰包也有缺点，如果跑步时放了手机，受惯性影响，下方会来回摆动，松紧带要是系得不紧，就容易往下滑&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%A4%9C%E9%AA%91%EF%BC%9A%E7%8E%AF%E5%B2%A9%E5%8F%A3%E6%B0%B4%E5%BA%93%EF%BC%8C%E9%81%AD%E7%BF%BB%E8%BD%A6&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-10-11-night-ride-yankou-crash&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>国庆最后一天：倍鱼线二进宫</title><link>https://blog.lhasa.icu/posts/outdoors/2025-10-09-double-ride-beiyu-line</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-10-09-double-ride-beiyu-line</guid><pubDate>Wed, 08 Oct 2025 19:09:00 GMT</pubDate><content:encoded>&lt;p&gt;​二爬倍鱼线，别样体验。与往日不同，这次选择了走义武公路进山。进山前正值烈日当空，仿佛整个人被塞进了蒸炉。&lt;/p&gt;
&lt;p&gt;要么说光膀子就是自在，我实在不喜欢衣服黏在身上的那种感觉。哪怕是超薄的速干背心，也比不过赤膊的畅快。至于雅观，这不是我该考虑的问题，国庆骑车进景区，逛古镇庙会都是光膀子。&lt;/p&gt;
&lt;p&gt;摇车进山后，树影与山峰交织成天然的屏障，感受不到一点热，只剩下逆向的风和时不时的鸟叫声。&lt;/p&gt;
&lt;p&gt;临近傍晚，山里的蚊子开始活跃起来，我身上散发出的热气，引来成群的蚊子，边骑边拍，但凡时速慢一点，就要被强奸。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008225604_275_266.jpg&quot; alt=&quot;义乌公路，即将进山&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008225741_276_266.jpg&quot; alt=&quot;柏峰水库拍留念&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008225850_277_266.jpg&quot; alt=&quot;柏峰水库&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230049_278_266.jpg&quot; alt=&quot;半坑附近&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230222_279_266.jpg&quot; alt=&quot;半坑附近&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230259_280_266.jpg&quot; alt=&quot;不知道谁的房子，我想不是用来住的吧&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230432_281_266.jpg&quot; alt=&quot;倍鱼线 19&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230727_282_266.jpg&quot; alt=&quot;倍鱼线旁的小溪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230914_283_266.jpg&quot; alt=&quot;口非常多，一分钟一个，大小和小拇指差不多&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230956_284_266.jpg&quot; alt=&quot;路线图，该标识在胡公殿丁字路口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008230958_285_266.jpg&quot; alt=&quot;一口气憋到山顶，停下一秒都是不可能的&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008231036_286_266.jpg&quot; alt=&quot;出发前买的士力架，已化&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008231204_287_266.jpg&quot; alt=&quot;准备下山了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008231239_288_266.jpg&quot; alt=&quot;这种照片不是我拍的，把手机卡在自行车上误触了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008231341_290_266.jpg&quot; alt=&quot;阳光直射，拍不清&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008231719_292_266.jpg&quot; alt=&quot;另一个方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008231832_293_266.jpg&quot; alt=&quot;在这个位置蹲了五分钟，没见车经过，自拍一张走了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008232031_294_266.jpg&quot; alt=&quot;五菱下山了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008232101_295_266.jpg&quot; alt=&quot;临近傍晚了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008232216_296_266.jpg&quot; alt=&quot;这张照片和上面的一张照片是在同一个位置，不同的角度拍的&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008232245_297_266.jpg&quot; alt=&quot;文字大军已经出动了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008232441_299_266.jpg&quot; alt=&quot;柏峰水库晚上很漂亮，跑道也很好，就是蚊子太猖狂&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20251008232520_300_266.jpg&quot; alt=&quot;在厚富夜市吃了饭回家&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%9B%BD%E5%BA%86%E6%9C%80%E5%90%8E%E4%B8%80%E5%A4%A9%EF%BC%9A%E5%80%8D%E9%B1%BC%E7%BA%BF%E4%BA%8C%E8%BF%9B%E5%AE%AB&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-10-09-double-ride-beiyu-line&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>集成 LightGallery 灯箱</title><link>https://blog.lhasa.icu/posts/technology/2025-09-18-integrating-lightgallery</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-09-18-integrating-lightgallery</guid><pubDate>Thu, 18 Sep 2025 11:33:00 GMT</pubDate><content:encoded>&lt;p&gt;月初，一个博友留言反馈讲到文章页面图片看不清楚，今下午花点时间，收拾了一下&lt;/p&gt;
&lt;p&gt;LightGallery 这款灯箱我老博客用过，后来换到 Astro 就搁置了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;figure class={`img-container ${className || &apos;&apos;}`} style={style}&amp;gt;
  &amp;lt;div class=&quot;img-wrapper lightgallery-wrapper&quot;&amp;gt;
    &amp;lt;!-- EXIF --&amp;gt;
    {shouldShowExif &amp;amp;&amp;amp; (
      &amp;lt;div class=&quot;exif-tooltip&quot; data-exif-tooltip&amp;gt;
        &amp;lt;div class=&quot;exif-content&quot;&amp;gt;
          &amp;lt;div class=&quot;exif-loading&quot;&amp;gt;Loading EXIF data...&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    )}
    
    &amp;lt;!-- LightGallery --&amp;gt;
    &amp;lt;a href={finalSrc} 
       data-src={finalSrc} 
       data-lg-size=&quot;1600-2400&quot; 
       data-sub-html={alt}
       class=&quot;lightgallery-link&quot;&amp;gt;
      ![ ]()
    &amp;lt;/a&amp;gt;
    
    &amp;lt;!-- 标签 --&amp;gt;
    {caption &amp;amp;&amp;amp; (
      &amp;lt;figcaption class={`img-caption caption-${caption === &apos;long&apos; ? &apos;bar&apos; : &apos;tag&apos;}`}&amp;gt;
        &amp;lt;span class=&quot;caption-text&quot;&amp;gt;{alt}&amp;lt;/span&amp;gt;
      &amp;lt;/figcaption&amp;gt;
    )}
  &amp;lt;/div&amp;gt;
&amp;lt;/figure&amp;gt;

&amp;lt;script is:inline&amp;gt;
function initLightGallery() {
  // 全局初始化
  const galleryContainer = document.body;
  
  // 销毁
  if (galleryContainer.lightGalleryInstance) {
    galleryContainer.lightGalleryInstance.destroy();
  }
  
  galleryContainer.lightGalleryInstance = window.lightGallery(galleryContainer, {
    selector: &apos;.lightgallery-wrapper &amp;gt; a&apos;,
    subHtmlSelectorRelative: true,
    mousewheel: true,
    download: false,
  });
}

document.addEventListener(&apos;DOMContentLoaded&apos;, initLightGallery);
document.addEventListener(&apos;astro:page-load&apos;, initLightGallery);
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;moon-8579189.jpg&quot; alt=&quot;Canon EOS R7 RF100-400mm F5.6-8 IS USM 400.0mm · ƒ/8.0 · 1/200s · ISO 800 © Michael Kleinsasser&quot; /&gt;&lt;/p&gt;
&lt;p&gt;经过这段时间的调教，博客插入图片较为人性化了，只需要输入文件名，它会自动处理路径&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片统一路径：cos + slug + name&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;![Canon EOS R7 RF100-400mm F5.6-8 IS USM 400.0mm · ƒ/8.0 · 1/200s · ISO 800 © Michael Kleinsasser](moon-8579189.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;感觉还有进一步优化的空间，如果抛弃键值对，直接按照顺序传参，想必最简洁不过了&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片 URL&lt;/li&gt;
&lt;li&gt;图片描述&lt;/li&gt;
&lt;li&gt;EXIF（Boolean）&lt;/li&gt;
&lt;li&gt;标签（Boolean）&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;Img 
  &quot;moon-8579189.jpg&quot;
  &quot;Canon EOS R7 RF100-400mm F5.6-8 IS USM 400.0mm · ƒ/8.0 · 1/200s · ISO 800 © Michael Kleinsasser&quot;
  &quot;false&quot;
  &quot;false&quot;
&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有时候想想也是，看似隐式优于显式的想法，实际上和过去接手的屎山一样&lt;/p&gt;
&lt;p&gt;可读性极差，旁人一眼望去，完全不知道&lt;code&gt;&quot;false&quot; &quot;false&quot;&lt;/code&gt;代表啥&lt;/p&gt;
&lt;p&gt;说到底，屎山并不是一行行代码堆出来的，而是懒省事养成的&lt;/p&gt;
&lt;h2&gt;help&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.lightgalleryjs.com/docs/getting-started/&quot;&gt;LightGallery docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%9B%86%E6%88%90%20LightGallery%20%E7%81%AF%E7%AE%B1&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-09-18-integrating-lightgallery&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>EasyFill v1.3 发布：支持SPA机制、优化 Shadow DOM 遍历逻辑</title><link>https://blog.lhasa.icu/posts/technology/2025-09-18-easyfill-1-3-0</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-09-18-easyfill-1-3-0</guid><pubDate>Thu, 18 Sep 2025 00:44:00 GMT</pubDate><content:encoded>&lt;p&gt;本次更新（commit: 7764aa3） 对 &lt;code&gt;content.ts&lt;/code&gt; 文件进行了部分重构，详情如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;重构 Shadow DOM 遍历逻辑，使用 WeakSet 避免重复遍历&lt;/li&gt;
&lt;li&gt;新增页面变化检测机制，完美支持 PJAX/AJAX/SPA 等现代页面刷新方式&lt;/li&gt;
&lt;li&gt;新增两段填充：DOM 加载前后，提升容错&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Shadow DOM 遍历优化&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;const processedShadowRoots = new WeakSet&amp;lt;ShadowRoot&amp;gt;();

function traverseShadowDOM(root: Document | ShadowRoot | Element) {
  // 如果 ShadowRoot 已经处理过，跳过
  if (root instanceof ShadowRoot &amp;amp;&amp;amp; processedShadowRoots.has(root)) {
    return;
  }
  
  // 标记已处理的 ShadowRoot
  if (root instanceof ShadowRoot) {
    processedShadowRoots.add(root);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;页面变化检测机制&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;function setupAdvancedPageChangeDetection() {
  // 监听浏览器前进后退
  window.addEventListener(&apos;popstate&apos;, () =&amp;gt; {
    logger.info(&apos;检测到 popstate 事件&apos;);
    handlePageChange();
  });

  // 监听 PJAX、AJAX
  const originalPushState = history.pushState;
  const originalReplaceState = history.replaceState;

  history.pushState = function(...args) {
    originalPushState.apply(history, args);
    logger.info(&apos;检测到 pushState 事件&apos;);
    setTimeout(() =&amp;gt; handlePageChange(), 100);
  };

  // 监听 hashchange 事件
  window.addEventListener(&apos;hashchange&apos;, () =&amp;gt; {
    logger.info(&apos;检测到 hashchange 事件&apos;);
    handlePageChange();
  });

  // DOM 变化检测
  const observer = new MutationObserver((mutations) =&amp;gt; {
    if (fillState.isAutoFillStopped &amp;amp;&amp;amp; !fillState.pageChangeDetected) {
      let significantChanges = 0;
      
      mutations.forEach((mutation) =&amp;gt; {
        if (mutation.type === &apos;childList&apos;) {
          // 检查大量节点变化
          if (mutation.addedNodes.length &amp;gt; 5 || mutation.removedNodes.length &amp;gt; 5) {
            significantChanges++;
          }
          
          // 检查结构性变化
          mutation.addedNodes.forEach((node) =&amp;gt; {
            if (node instanceof Element) {
              if (node.matches(&apos;form, input, textarea&apos;) || 
                  node.querySelector(&apos;form, input, textarea&apos;)) {
                significantChanges += 2;
              }
              
              if (node.matches(&apos;main, article, section, .content, #content, .main, #main&apos;)) {
                significantChanges += 3;
              }
            }
          });
        }
      });
      
      // 判断是否为页面内容更新
      if (significantChanges &amp;gt;= 3) {
        logger.info(`检测到DOM变化 (${significantChanges}个变化点)`);
        
        if (detectPageChange()) {
          fillState.pageChangeDetected = true;
          handlePageChange();
        }
      }
    }
  });

  setInterval(() =&amp;gt; {
    if (detectPageChange()) {
      handlePageChange();
    }
  }, 2000);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;两段填充&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;async function executeFirstFill() {
  if (fillState.isFirstFillCompleted) {
    return;
  }
  
  await performFill(&apos;首次&apos;);
  fillState.isFirstFillCompleted = true;
  logger.info(&apos;首次填充已完成&apos;);
}

async function executeSecondFill() {
  if (fillState.isSecondFillCompleted) {
    return;
  }
  
  await performFill(&apos;第二次&apos;);
  fillState.isSecondFillCompleted = true;
  fillState.isAutoFillStopped = true;
  logger.info(&apos;第二次填充已完成，自动填充已停止&apos;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;立即体验&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;EasyFill v1.3&lt;/strong&gt; 已正式发布：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;新用户&lt;/strong&gt;：Chrome Web Store 搜索 &quot;&lt;a href=&quot;https://chromewebstore.google.com/detail/eamchegekphehbmebccbapnihegngobm?utm_source=item-share-cb&quot;&gt;EasyFill&lt;/a&gt;&quot; 安装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;现有用户&lt;/strong&gt;：魔法联网后 Chrome 扩展将自动更新到最新版本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发者&lt;/strong&gt;：访问 &lt;a href=&quot;https://github.com/achuanya/EasyFill&quot;&gt;github.com/achuanya/EasyFill&lt;/a&gt; 查看源代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大陆访问&lt;/strong&gt;：&lt;a href=&quot;https://cos.lhasa.icu/EasyFill/Version/easyfill-1.3.0-chrome.zip&quot;&gt;点此下载 Easyfill-1.3.0-chrome.zip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安装方式也很简单：下载后解压到文件夹，进入 &lt;strong&gt;Chrome → 管理扩展程序 → 加载未打包的扩展&lt;/strong&gt;，选择解压目录即可。其他基于 Chromium 内核的浏览器同样适用。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;EasyFill - 简易填充，让每一次评论更自然，与你的博友互动无缝连接&lt;/strong&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=EasyFill%20v1.3%20%E5%8F%91%E5%B8%83%EF%BC%9A%E6%94%AF%E6%8C%81SPA%E6%9C%BA%E5%88%B6%E3%80%81%E4%BC%98%E5%8C%96%20Shadow%20DOM%20%E9%81%8D%E5%8E%86%E9%80%BB%E8%BE%91&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-09-18-easyfill-1-3-0&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>EasyFill v1.2 发布：黑名单功能上线</title><link>https://blog.lhasa.icu/posts/technology/2025-09-16-easyfill-1-2-0</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-09-16-easyfill-1-2-0</guid><pubDate>Tue, 16 Sep 2025 03:21:00 GMT</pubDate><content:encoded>&lt;p&gt;距离上一次更新已经有一段时间了，最近抽空折腾了一下，在 &lt;strong&gt;EasyFill v1.2&lt;/strong&gt; 中带来了一些实用的新特性，特别是 &lt;strong&gt;黑名单功能&lt;/strong&gt;。&lt;/p&gt;
&lt;h3&gt;本次更新亮点&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;防抖机制&lt;/strong&gt;：避免频繁触发填充操作，更加顺滑稳定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;黑名单设置&lt;/strong&gt;：支持官方规则和用户自定义两种模式。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;自定义黑名单管理&lt;/strong&gt;：支持添加、删除、拖拽上传和导出，操作更直观。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据同步优化&lt;/strong&gt;：无论手动还是自动更新，都会跳过缓存，确保数据时效性。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;隐私政策更新&lt;/strong&gt;：新增黑名单数据处理条款，解释用途。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;fillsettings.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;隐私条款部分其实没啥复杂的，只是做了明确说明：插件仅有两个外部公开文件链接，其余所有数据都采用 &lt;strong&gt;本地加密存储（chrome.storage.local）&lt;/strong&gt;，没有隐私泄露的风险。&lt;/p&gt;
&lt;h2&gt;立即体验&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;EasyFill v1.2&lt;/strong&gt; 已正式发布：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;新用户&lt;/strong&gt;：Chrome Web Store 搜索 &quot;&lt;a href=&quot;https://chromewebstore.google.com/detail/eamchegekphehbmebccbapnihegngobm?utm_source=item-share-cb&quot;&gt;EasyFill&lt;/a&gt;&quot; 安装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;现有用户&lt;/strong&gt;：魔法联网后 Chrome 扩展将自动更新到最新版本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发者&lt;/strong&gt;：访问 &lt;a href=&quot;https://github.com/achuanya/EasyFill&quot;&gt;github.com/achuanya/EasyFill&lt;/a&gt; 查看源代码&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;大陆访问&lt;/strong&gt;：&lt;a href=&quot;https://cos.lhasa.icu/EasyFill/Version/easyfill-1.2.0-chrome.zip&quot;&gt;点此下载 easyfill-1.2.0-chrome.zip&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安装方式也很简单：下载后解压到文件夹，进入 &lt;strong&gt;Chrome → 管理扩展程序 → 加载未打包的扩展&lt;/strong&gt;，选择解压目录即可。其他基于 Chromium 内核的浏览器同样适用。&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;EasyFill - 简易填充，让每一次评论更自然，与你的博友互动无缝连接&lt;/strong&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=EasyFill%20v1.2%20%E5%8F%91%E5%B8%83%EF%BC%9A%E9%BB%91%E5%90%8D%E5%8D%95%E5%8A%9F%E8%83%BD%E4%B8%8A%E7%BA%BF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-09-16-easyfill-1-2-0&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>何为享受</title><link>https://blog.lhasa.icu/posts/life/2025-08-30-what-is-enjoyment</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2025-08-30-what-is-enjoyment</guid><pubDate>Sat, 30 Aug 2025 09:05:00 GMT</pubDate><content:encoded>&lt;p&gt;在初入职场时，我以为权力带来的快感才是享受&lt;/p&gt;
&lt;p&gt;在挣到小钱时，我以为挥霍物质才是享受&lt;/p&gt;
&lt;p&gt;在野外骑行时，我以为长途跋涉、纵身山川才是享受&lt;/p&gt;
&lt;p&gt;后来，我沉迷于古典乐，才感受到，人生真正的享受，不过是此刻心中的平静&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe frameborder=&quot;no&quot; border=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; width=298 height=52 src=&quot;//music.163.com/outchain/player?type=2&amp;amp;id=2156764039&amp;amp;auto=1&amp;amp;height=32&quot;&amp;gt;&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BD%95%E4%B8%BA%E4%BA%AB%E5%8F%97&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2025-08-30-what-is-enjoyment&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>热成铁板烧，又被暴雨淋成落汤鸡：西湖，我来了！</title><link>https://blog.lhasa.icu/posts/outdoors/2025-07-19-from-yiwu-to-west-lake-in-heat-and-rain</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-07-19-from-yiwu-to-west-lake-in-heat-and-rain</guid><pubDate>Sat, 19 Jul 2025 12:06:00 GMT</pubDate><content:encoded>&lt;h2&gt;从义乌出发去杭州&lt;/h2&gt;
&lt;p&gt;上次骑行是在6月24日，转眼半个月过去了，忍不住又开始怀念行驶在路上的感觉。&lt;/p&gt;
&lt;p&gt;7月17日 清晨，一时心血来潮，换上骑行服，简单带了件便装，便推车下楼。目的地：杭州。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_59.jpg&quot; alt=&quot;除骑行服外，只带了一件便装&quot; /&gt;&lt;/p&gt;
&lt;p&gt;还是这件迪卡侬背包，没有负重感，背着很轻松，很舒服。&lt;/p&gt;
&lt;p&gt;我夏天骑行很少穿短袖，出汗量也大，基本上能不穿就不穿。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_52.jpg&quot; alt=&quot;准备出发&quot; /&gt;&lt;/p&gt;
&lt;p&gt;抵达诸暨，约 50 公里。停下来抽根烟歇歇脚。&lt;/p&gt;
&lt;p&gt;天气太热，昨日天气预报 42℃，我感觉有五十几度。你随便热吧，爷们风雨一肩挑。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_53.jpg&quot; alt=&quot;绍兴，诸暨市，兴都路，公交站&quot; /&gt;
找个开空调的饭店吃饭很难，大部分小店都舍不得开。&lt;/p&gt;
&lt;p&gt;为了下午更恶劣的天气，强行灌了一口藿香正气水，这味道绝了，苦涩辣，难以下咽。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_54.jpg&quot; alt=&quot;绍兴，诸暨市，应镇南路，面馆&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下午更加闷热了，让我头疼无力，感觉在中暑边缘，幸好沿途加油站不少，此时已喝掉两升水，一包盐丸。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_55.jpg&quot; alt=&quot;杭州，萧山区，X120 桥戴线，中石化加油站&quot; /&gt;&lt;/p&gt;
&lt;p&gt;抵达复兴大桥很是激动，上一次在桥上骑行，还是 2021 年，那时还骑着我的 XTC800。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_56.jpg&quot; alt=&quot;杭州，滨江区，复兴大桥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;万松岭路落脚了，我已彻底湿透。身上一层汗、一层盐，一层雨水。真的太绝了！要知道，杭州已经连续多日滴雨未下，可就在我刚从复兴大桥下来，露出头的刹那，狂风暴雨！雨水如同密集的子弹般批头盖脸地往我脸上砸，就好像在说：“你咋又来了，你咋又来了？”&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;骑行距离：120km，时间：5h 26m，爬升：410m&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_57.jpg&quot; alt=&quot;杭州，上城区，万松岭路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_60.jpg&quot; alt=&quot;我的大腿&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_61.jpg&quot; alt=&quot;妈妈泡的茶叶&quot; /&gt;&lt;/p&gt;
&lt;p&gt;简单休息后，喝了杯妈妈泡的茶，躺下睡了一会儿。傍晚八点半醒来，直奔西湖&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_62.jpg&quot; alt=&quot;杭州西湖风景名胜区，柳浪闻莺，翠光亭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_63.jpg&quot; alt=&quot;杭州西湖风景名胜区，钱王祠入口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_64.jpg&quot; alt=&quot;杭州西湖风景名胜区，钱王祠外&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在杭州市区内，最美丽的行驶路段莫过于南山路，这里是法国梧桐树密集栽种区，树龄平均在70年左右。有些枝干伸进居民楼，连玻璃都撞碎了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_65.jpg&quot; alt=&quot;杭州，上城区，南山路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;晚上和妈妈去了老地方吃羊蹄，这也是我来杭州的目的之一，自出了老家，我只认这一家。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;a545de938140.jpg&quot; alt=&quot;杭州，上城区，西湖大道，老地方&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;微雨飞来峰&lt;/h2&gt;
&lt;p&gt;上午九点，和妈妈打车去了飞来峰，天飘着细雨，院内外，人挤人。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_67.jpg&quot; alt=&quot;杭州西湖风景名胜区，飞来峰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;枫叶做成的龙雕像，我妈说我属相大龙，非拉我拍照。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_68.jpg&quot; alt=&quot;飞来峰，入口处“叶龙”&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_70.jpg&quot; alt=&quot;飞来峰，水月观音坐像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;有些导游群体，到了景区，真成了路障了？导游后面站了几十个人看，干啥呢？排队早高峰呢？魂都跟着导游跑到九霄云外了，导致宽敞的道路被围得水泄不通。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_72.jpg&quot; alt=&quot;飞来峰，一线天&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_73.jpg&quot; alt=&quot;飞来峰，造像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_74.jpg&quot; alt=&quot;飞来峰，观音坐像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_75.jpg&quot; alt=&quot;飞来峰，释迦佛与释迦如来&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_77.jpg&quot; alt=&quot;飞来峰，小溪流&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_78.jpg&quot; alt=&quot;飞来峰，小溪流&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中午和妈妈来到公司吃饭——啫卤爷，就在杭州美院对面。这是西湖春天旗下的品牌，偏中低端、年轻化，以烧烤为主。&lt;/p&gt;
&lt;p&gt;广东的博友可能听说过，例如：江南厨子、江南味道、西湖春天、水岸十里等等，均以杭帮菜、粤菜，海鲜为主。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_80.jpg&quot; alt=&quot;杭州，上城区，南山路103-2号，啫卤爷&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_87.jpg&quot; alt=&quot;啫卤爷二楼靠窗位置&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这羊肉串我可想太久了！自第一次吃这羊肉串，去哪都找不到这个味，实际上这一串很大，我拍照不行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_81.jpg&quot; alt=&quot;啫卤爷，羊肉串&quot; /&gt;&lt;/p&gt;
&lt;p&gt;也是非常喜欢的一道菜，不过我比较怕这玩意，在上海做采购几年从来没摸过。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_82.jpg&quot; alt=&quot;啫卤爷，啫啫麻辣田鸡&quot; /&gt;&lt;/p&gt;
&lt;p&gt;炒饭中的最爱，没有之一。啫卤爷是没有这道菜的，还是从隔壁店西湖春天下单送过来的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_83.jpg&quot; alt=&quot;西湖春天，菠萝炒饭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;乳山生蚝个个七八两，肉质饱满，非常新鲜。作为公司曾经的海鲜采购，再熟悉不过这挑剔的原料标准。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;一条东星斑，在规格上，哪怕只重了一两也不行，身上哪怕有一点点影响美观的小瑕疵也不行。就连鲍鱼、花螺这些小海鲜，也得一个个用手仔细称重、挑选，只为确保每一道菜上桌时，食材的大小都能均匀划一。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;所以，在西湖春天旗的门店用餐，你几乎不用考虑卫生问题。&lt;/p&gt;
&lt;p&gt;这公司的供应链还是比较成熟的，对于原料的源头有些较真。许多原料都是从基地直采，就一个百合，经理能坐飞机跑甘肃，直接到田间地头和农民沟通，我也是很佩服。&lt;/p&gt;
&lt;p&gt;更扯淡的是，河南郑州的分店。他们连一根葱、一把香菜都要下单到采购部，然后杭州或深圳采购部打包后，用飞机空运过去。确实，不是一个产地的东西，那味就是不一样。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_84.jpg&quot; alt=&quot;啫卤爷，乳山生蚝&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_86.jpg&quot; alt=&quot;啫卤爷 菜品&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;暴雨再来，船游西湖&lt;/h2&gt;
&lt;p&gt;午睡两个小时，醒来时外头下起了大雨。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_88.jpg&quot; alt=&quot;杭州，上城区，万松岭路，暴雨中&quot; /&gt;&lt;/p&gt;
&lt;p&gt;雨稍小时，和妈妈来到长桥散步，吹着风，很凉快。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_89.jpg&quot; alt=&quot;杭州西湖风景名胜区，长桥公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_90.jpg&quot; alt=&quot;杭州西湖风景名胜区，学士公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_91.jpg&quot; alt=&quot;杭州西湖风景名胜区，学士公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;西湖区的绿化非常棒，这样大的树，通常只有在森林公园才会有，而西湖区遍地都是，这也是我喜欢这个城市的原因之一。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_92.jpg&quot; alt=&quot;杭州西湖风景名胜区，学士公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;雨后的西湖太美了，如水墨丹青，坐在游船上看水面泛起涟漪，若再来一根路亚竿，啊，人生不过如此啊！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_93.jpg&quot; alt=&quot;西湖，在船上&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_94.jpg&quot; alt=&quot;西湖，雨后晴时&quot; /&gt;&lt;/p&gt;
&lt;p&gt;刚做十分钟，又开始暴雨，真会挑时候，下得好。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_95.jpg&quot; alt=&quot;西湖，暴雨中&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中间的岛我也没去过，不知道有些什么？&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_96.jpg&quot; alt=&quot;西湖，三潭印月&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这时候刚六点出头，雷峰塔不到开灯时间，可惜了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_97.jpg&quot; alt=&quot;杭州西湖风景名胜区，长桥公园&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;烟雨柳浪，落座外婆家&lt;/h2&gt;
&lt;p&gt;坐船上约半小时，下船后继续沿着西湖漫步不知不觉就来到了外婆家（西湖天地店）。这家门店的位置实在绝了，面朝西湖、背靠绿荫。唯一的缺点，椅子太低，坐下就像在躺着吃饭。不过也不能要求太多，人均在这放着。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_98.jpg&quot; alt=&quot;杭州西湖风景名胜区，外婆家（西湖天地店）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_99.jpg&quot; alt=&quot;杭州，上城区，南山路，唐云艺术馆&quot; /&gt;&lt;/p&gt;
&lt;p&gt;傍晚时分的西湖美极了，没有正午的烈日，也少了游客的喧哗，最适合独坐柳浪闻莺的湖边长椅上，手边放本书，任风吹书页、吹到哪页读哪页。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_100.jpg&quot; alt=&quot;杭州西湖风景名胜区，长桥公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_101.jpg&quot; alt=&quot;杭州西湖风景名胜区，长桥公园&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;返程回义乌&lt;/h2&gt;
&lt;p&gt;杭州的旅程告一段落了，不打算骑行回去，我订好了高铁票。&lt;/p&gt;
&lt;p&gt;去高铁站之前，我心里没有底，我只在上海虹桥拿过自行车。不知道杭州会不会卡的严。&lt;/p&gt;
&lt;p&gt;如果托运的话，需要专业的硬壳自行车包，先不说一个便宜的硬壳自行车包都要几千块。&lt;/p&gt;
&lt;p&gt;前后轮、飞轮、包括车把都要拆。这拆卸、组装从来都不是一个小工程。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_102.jpg&quot; alt=&quot;杭州，上城区，万松岭路，货拉拉&quot; /&gt;&lt;/p&gt;
&lt;p&gt;顺利通过安检，检票员一句话都没说，她甚至都不愿意看我的车一眼。想必江浙沪的骑友已经实践无数次了，而且江浙沪是爬坡竞赛的大省，我爱这里。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;老家河南：谁管你规定1.6米限宽，自行车就是不让上，拆了也是自行车，不让上。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_103.jpg&quot; alt=&quot;杭州，上城区，杭州站，6号候车厅&quot; /&gt;&lt;/p&gt;
&lt;p&gt;非常完美，下次去义乌站试试，如果拆了前轮可以上高铁，那么这条路线就打通了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250719143714_104.jpg&quot; alt=&quot;杭州，上城区，杭州站，G491，8号车厢&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最后，上视频，以此纪念这段时光：&lt;/p&gt;
&lt;p&gt;&amp;lt;video width=&quot;736&quot; height=&quot;414&quot; controls&amp;gt;
&amp;lt;source src=&quot;487837dbd622415b42902.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
你的浏览器不支持 HTML5 视频播放。
&amp;lt;/video&amp;gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%83%AD%E6%88%90%E9%93%81%E6%9D%BF%E7%83%A7%EF%BC%8C%E5%8F%88%E8%A2%AB%E6%9A%B4%E9%9B%A8%E6%B7%8B%E6%88%90%E8%90%BD%E6%B1%A4%E9%B8%A1%EF%BC%9A%E8%A5%BF%E6%B9%96%EF%BC%8C%E6%88%91%E6%9D%A5%E4%BA%86%EF%BC%81&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-07-19-from-yiwu-to-west-lake-in-heat-and-rain&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>这个 RSS 有意思</title><link>https://blog.lhasa.icu/posts/technology/2025-07-10-beautify-rss</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-07-10-beautify-rss</guid><pubDate>Wed, 09 Jul 2025 18:26:00 GMT</pubDate><content:encoded>&lt;p&gt;晚上逛 #UNTAG 发现一个有意思的项目 —— &lt;strong&gt;RSS.Beauty&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一款开源 RSS 美化工具。支持 RSS 2.0 和 Atom 1.0 格式，可将原始订阅源转换加以渲染。&lt;/p&gt;
&lt;p&gt;此外，根据项目文档，作者还提供了四种食用方法，包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在线美化&lt;/li&gt;
&lt;li&gt;本地 XSL 样式&lt;/li&gt;
&lt;li&gt;Base64 内嵌样式&lt;/li&gt;
&lt;li&gt;Docker / Node.js 部署&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;一、在线美化 RSS&lt;/h3&gt;
&lt;p&gt;只需提供 RSS 地址，即可通过服务端转换美化：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://rss.lhasa.icu/rss?url=https://lhasa.icu/rss.xml
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;8143415125aab.png&quot; alt=&quot;RSS&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;二、食用 XSL 模板&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;XSL 文件必须与 RSS 源在同一域名下，否则会有跨域限制。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下载模板：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# RSS 2.0
wget https://rss.lhasa.icu/rss.xsl

# Atom 1.0
wget https://rss.lhasa.icu/atom.xsl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在 RSS 文件头部添加如下声明：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml-stylesheet href=&quot;/style/rss.xsl&quot; type=&quot;text/xsl&quot;?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;三、Base64 编码&lt;/h3&gt;
&lt;p&gt;适合不想托管样式文件，可以将样式直接内嵌进 RSS 文件中&lt;/p&gt;
&lt;p&gt;步骤如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;访问:&lt;code&gt;https://rss.lhasa.icu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;切换到 “Base64” 选项卡&lt;/li&gt;
&lt;li&gt;根据 RSS / Atom 格式选择对应样式&lt;/li&gt;
&lt;li&gt;将复制的代码插入 RSS 文件中，例如：&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;?xml-stylesheet href=&quot;data:text/xsl;base64,PD94bWw...&quot; type=&quot;text/xsl&quot;?&amp;gt;
&amp;lt;rss version=&quot;2.0&quot; xmlns:content=&quot;http://purl.org/rss/1.0/modules/content/&quot;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;四、Docker 部署&lt;/h3&gt;
&lt;p&gt;扒拉下来，启动：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker pull ghcr.io/ccbikai/rss.beauty:main
docker run -d --name rss-beauty -p 4321:4321 ghcr.io/ccbikai/rss.beauty:main
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nginx 反代：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# /etc/nginx/conf.d/rss.conf
server {
  listen 80;
  server_name rss.lhasa.icu;
  location / {
      proxy_pass         http://127.0.0.1:4321;
      proxy_http_version 1.1;
      proxy_set_header   Host $host;
      proxy_set_header   X-Real-IP $remote_addr;
      proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header   X-Forwarded-Proto $scheme;
  }
}

# 重载 Nginx
sudo nginx -t &amp;amp;&amp;amp; sudo nginx -s reload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Node.js 部署就不赘述了，天天接触，不新鲜。&lt;/p&gt;
&lt;p&gt;我小改了一下配色，不过目前还不支持输出文章配图和全文。等明天下班再来折腾吧。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://lhasa.icu/rss.xml&quot;&gt;我去看看&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;1752084104213.jpg&quot; alt=&quot;RSS&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;相关链接：&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ccbikai/rss.beauty&quot;&gt;项目主页：RSS.Beauty&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ccbikai/RSS.Beauty/blob/main/docs/deployment-guide.md&quot;&gt;官方部署指南&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%BF%99%E4%B8%AA%20RSS%20%E6%9C%89%E6%84%8F%E6%80%9D&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-07-10-beautify-rss&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>雨骑枫赤线</title><link>https://blog.lhasa.icu/posts/outdoors/2025-06-25-rain-ride-scarlet-maple</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-06-25-rain-ride-scarlet-maple</guid><pubDate>Wed, 25 Jun 2025 12:53:00 GMT</pubDate><content:encoded>&lt;h2&gt;近况&lt;/h2&gt;
&lt;p&gt;早上睡到九点钟，很困，睡不醒。直觉告诉我，我现在有种嗜睡的状态。实际上我这段时间都没有睡醒过，因为我时常编码到凌晨三四点，甚至通宵整晚，到了点直接去上班，也是常有的事。&lt;/p&gt;
&lt;p&gt;傍晚下了班吃完饭，出去跑跑步，回到家已经十点钟了，直接脱光站在花洒下，任凭水滴打着脸，我很享受这种感觉，这让我觉得，只有现在的我是清醒的，回头望这一天，怎么想也没有觉得什么事是有意义的，想做的事总赶不上时间，原来人的精力和时间都是有限的。&lt;/p&gt;
&lt;p&gt;我这个人对时间不敏感，可以说我是固执吧，我想，我很多时间我都花费在这性格上，但若是放在编码上也颇有钻研精神，为爱发电，成败与否不重要了，值了。&lt;/p&gt;
&lt;p&gt;总的来说我这人很怪，我不知道该归类到哪种类型，大概可以用那句话来形容：“见人说人话，见鬼说鬼话。”&lt;/p&gt;
&lt;p&gt;这两年，我的心态变了很多，也不知道从什么时候养成了一种无所谓的态度，大概是真的真躺平了，之前那种中年危机感也消失了，不再内耗了。&lt;/p&gt;
&lt;p&gt;说到中年危机，比我年长的朋友总笑，毕竟我才二十四岁，距离二十五还有一个多月，但事实就是那样。&lt;/p&gt;
&lt;h2&gt;周五&lt;/h2&gt;
&lt;p&gt;失业第二天，暂时也不想找工作，只想出去走走，手里米不多，紧着过。我是一个比较容易满足的人，吃穿不讲究，哪怕吃口馒头住桥洞呢，毕竟也不是第一次了。&lt;/p&gt;
&lt;p&gt;但这精神的苦，是真快忍不住了。来义乌二十天有余，就没有出过几次车，总想着跑步发泄一下吧，时间重要，骑车耽误时间，去你妈的时间。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003023.jpg&quot; alt=&quot;G527 · 佛堂大道&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这次出行，我多带了一件短袖骑行服外套，一是暴雨天气可以作为贴身保暖，二为了烟盒存放，我可不想背着包爬盘山公路。&lt;/p&gt;
&lt;p&gt;刚骑两公里，浑身黏黏的，实在难受，外套直接脱了挂在 ASSOS 的背带裤上，像往常一样，上半身只穿一件 MBO 白色背心。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003022.jpg&quot; alt=&quot;S218 · 赤岸大道&quot; /&gt;&lt;/p&gt;
&lt;p&gt;长时间不骑车，体力确实跟不上。而且我这个双腿隐约有些疼，一个月了未见好转，就因为那个半马，真让博友说中了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505240030221.jpg&quot; alt=&quot;S218 · 义武公路 · 永康方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;通过高德得知，到了这个丁字路口，就算正式进入盘山公路的入口了，我也是第一次来骑枫赤线，随便搜的一个地方&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003021.jpg&quot; alt=&quot;义乌公路，丁字路口，即将到达山脚下&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中间的湖，属于饮用水源一级保护区&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003020.jpg&quot; alt=&quot;此刻，我想钓鱼&quot; /&gt;&lt;/p&gt;
&lt;p&gt;湖叫啥名我不清楚，只记得每隔几百米都有牌子竖立写着：“饮用水源地一级”&lt;/p&gt;
&lt;p&gt;我停下车，往下望，看到一个浅水滩，岸边聚着一群大约四五公斤的锦鲤。&lt;/p&gt;
&lt;p&gt;这些地方通常不缺鱼，缺的是饲料。还记得钓友口口相传的段子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无标识&lt;/strong&gt; = 空军警告&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;禁止垂钓&lt;/strong&gt; = 有鱼，但不多&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;严禁钓鱼，违者后果自负&lt;/strong&gt; = 鱼多，但掉水里我们不管&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;禁止垂钓，违者罚款 500&lt;/strong&gt; = 鱼多，钓费 500&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;饮用水源，禁止垂钓&lt;/strong&gt; = 鱼多，本地人可以钓&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;去的时候没看到有人钓鱼，返程时在山顶往下看，发现一个打路亚的，那位置绝了，不是本地人，你真不知道从哪下去。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505240030191.jpg&quot; alt=&quot;浅水滩的锦鲤在觅食&quot; /&gt;&lt;/p&gt;
&lt;p&gt;照片里面的这段盘山公路是整条线的精髓，骑起来很舒服，可惜太短，还不够爽。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003018.jpg&quot; alt=&quot;枫赤线上面的盘山公路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;顶着细雨骑了一路，最近熬夜太多，精神状态很差。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003017.jpg&quot; alt=&quot;黑眼圈很重&quot; /&gt;&lt;/p&gt;
&lt;p&gt;突然暴雨，手机被雨砸的页面乱跳，镜头根本擦不干净，浑身湿透，很爽。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505240030171.jpg&quot; alt=&quot;手机和我都遭受到了枫赤线的洗礼&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;中场休息&lt;/h2&gt;
&lt;p&gt;骑行到达枫赤线终点，终点见到人家了，总算有百货店了，这一条街上只有两家店，另一家进去除了啤酒和水啥都没有，相比之下，这一家好多了。&lt;/p&gt;
&lt;p&gt;其实，我主要是借东西来充电的，吃饭是次要的。不吃饭我可以骑回去，但是没有手机，我不知道可以骑哪去。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003016.jpg&quot; alt=&quot;吃到东西了，还可以充电，太幸福了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;店面是个八零后阿姨开的，她给我泡了一碗面，边吃边聊，就这样过了一个多小时。&lt;/p&gt;
&lt;p&gt;她家的位置真的很顶，可谓是：“采菊东篱下，悠然见南山”&lt;/p&gt;
&lt;p&gt;庭院朝阳，面向群山，左边的庭院养了一池子锦鲤，右边的小庭院种满了花，&lt;/p&gt;
&lt;p&gt;铁栏杆外的杆子上挂满了月季，吃着聊着，还给我传授了一些栽培经验，蛮有意思的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003015.jpg&quot; alt=&quot;阿姨种的花&quot; /&gt;&lt;/p&gt;
&lt;p&gt;暴雨骤停，我也停了下来，望着群山大喊，太美了！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505240030141.jpg&quot; alt=&quot;暴雨骤停&quot; /&gt;&lt;/p&gt;
&lt;p&gt;不过，我现在写着博客，看着这些图片总觉得差了点什么，腾讯云的压缩太狠了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003014.jpg&quot; alt=&quot;合影留念&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003012.jpg&quot; alt=&quot;合影留念&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003009.jpg&quot; alt=&quot;盘山公路旁的小瀑布&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这时已经下山了，即将离开枫赤线。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524003006.jpg&quot; alt=&quot;此时此刻，山脚下&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;回家&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20250524003000.jpg&quot; alt=&quot;义乌市区方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250524002959.png&quot; alt=&quot;爬升：1376m · 距离：101.06 Km · 时间：5h 32m&quot; /&gt;&lt;/p&gt;
&lt;p&gt;义乌这座宝藏小城市，蛮不错的。&lt;/p&gt;
&lt;p&gt;绿水青山环绕，群山绵延，把整个城市都包裹了起来。像今天的枫赤线，我不知道义乌还有多少个这样的路线，太期待了！&lt;/p&gt;
&lt;p&gt;还有一个特别加分的点！路上的车不多。之前下班六点出去骑车，非机动车道人车都很少，相反，我去公园跑步人挤人。&lt;/p&gt;
&lt;p&gt;这一点很重要，是我目前去过的城市中，单飞的感受最好的，当然，我最爱的还是是宁波和舟山。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%9B%A8%E9%AA%91%E6%9E%AB%E8%B5%A4%E7%BA%BF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-06-25-rain-ride-scarlet-maple&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>生日骑遇“死亡摇摆”，差点成忌日骑</title><link>https://blog.lhasa.icu/posts/outdoors/2025-06-25-birthday-ride</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-06-25-birthday-ride</guid><pubDate>Wed, 25 Jun 2025 12:53:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;农历五月二十九，二十五岁生日到了&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;一边上班，一边创业，这样的活法让我骑车的时间越来越少。这不是我想要的状态，但为了三十岁之前出发环球骑行的梦想，我没有办法。&lt;/p&gt;
&lt;p&gt;前几日申请了调休，可算睡个安稳觉。早上睡到十点钟，吃完午饭，我觉得今天不能再碰电脑了，我现在很想出去骑车。可只剩下一个下午的时间了，太远去不了，近的没意思。打开高德地图扒拉半天，去横店。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250625190052.jpg&quot; alt=&quot;横店十里街 · 江南大桥方向&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250625190051.jpg&quot; alt=&quot;江南一镇（我觉得一般）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250625190046.jpg&quot; alt=&quot;横店影视城 · 明清宫苑景区外&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202506251900461.jpg&quot; alt=&quot;横店影视城 · 明清宫苑景区外&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250625190045.jpg&quot; alt=&quot;横店 · 明清西路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在我的印象中，横店是拍电影的地方，但我实际到了地方，感觉哪都没有意思，啥玩意？一个适合骑车的地方都没有，不如来时的路好玩。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250625190044.jpg&quot; alt=&quot;东阳市 · S217&quot; /&gt;&lt;/p&gt;
&lt;p&gt;实在没意思，已经在回去的途中了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202506251900441.jpg&quot; alt=&quot;距离：80.43km | 爬升：533m | 时间：4h 28m&quot; /&gt;&lt;/p&gt;
&lt;p&gt;值得一提的是，骑行这些年，我第一次遇到“死亡摇摆”&lt;/p&gt;
&lt;p&gt;在217省道放坡，点刹50码。行程到一半遭遇强逆风 + 侧风（大货车快速行驶向右推来的气流）&lt;/p&gt;
&lt;p&gt;刚开始车把只有轻微晃动，我就轻微点刹减点速。&lt;/p&gt;
&lt;p&gt;但没想到，几秒之后，车把开始剧烈左右甩动，大约持续十秒左右，幸好当时没慌，硬是拿捏住了！人和车都没摔！&lt;/p&gt;
&lt;p&gt;回到家洗澡时还是懵的，不知道当时怎么解决的问题。如果当时没解决死亡摇摆：&lt;/p&gt;
&lt;p&gt;向左摔，身后高速行驶的下坡车辆根本反应不过来，会直接从我身上碾压过去&lt;/p&gt;
&lt;p&gt;向右倒，四五十码栽进排水沟？我估计也不会太好受。想想有些后怕，真刺激！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;高速行驶下的死亡摇摆案例&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;death-swing-case.webp&quot; alt=&quot;高速行驶下的死亡摇摆案例&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%94%9F%E6%97%A5%E9%AA%91%E9%81%87%E2%80%9C%E6%AD%BB%E4%BA%A1%E6%91%87%E6%91%86%E2%80%9D%EF%BC%8C%E5%B7%AE%E7%82%B9%E6%88%90%E5%BF%8C%E6%97%A5%E9%AA%91&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-06-25-birthday-ride&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>独立开发者创业了</title><link>https://blog.lhasa.icu/posts/startup/2025-06-12-im-starting-up</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/startup/2025-06-12-im-starting-up</guid><pubDate>Thu, 12 Jun 2025 05:07:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;我们生命中最美好的时刻，并非是那些接受给予、放松享受的时刻，而是那些为了完成一件困难而有价值的事情，自愿将身心发挥到极限的时刻。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;像咱这种人，我觉得只有一种死法 —— 猝死。&lt;/p&gt;
&lt;p&gt;从6月10日早上九点，一直干到6月11日下午一点半，眼睛都没怎么合过。足足三十多个小时，一口气用Go，把整个企业级的RESTful API给撸完了！&lt;/p&gt;
&lt;p&gt;这可不是简单的CtrlCV，为了支持硬件，软件下了点功夫：MySQL做了主从复制架构 + Redis缓存 + 负载均衡。支持 Docker 一键部署。还没做压力测试，自我感觉并发二三十万如喝水。&lt;/p&gt;
&lt;p&gt;上午测完接口，兴奋的饭都顾不上吃，更别说休息了。立马开始写文档。接口文档、数据库文档...&lt;/p&gt;
&lt;p&gt;先用Cursor生成基本文档，再改改。每份大概3000字800行左右，足足写了八份。&lt;/p&gt;
&lt;p&gt;还有商业计划书的思维导图，2M的大小，不放大到190%字体都看不清楚，内容密度可想而知。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;740fba9c9.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;真的要特别感谢 Cursor，这AI工具真是赶上了好时代！要是没有它，就凭这些工作量，外包团队没一个月起步都别想搞定。&lt;/p&gt;
&lt;p&gt;不敢想象，我竟然在三十多个小时里，就搞定了这么多事，而且落地质量高！&lt;/p&gt;
&lt;p&gt;接下来，还剩微信小程序对接接口，以及和硬件的联调。先给这些小卡拉米放放假，我要好好休息一个下午。&lt;/p&gt;
&lt;p&gt;此刻，精力充沛去吃个早饭骑骑车。&lt;/p&gt;
&lt;h2&gt;6.12 注册公司：&lt;/h2&gt;
&lt;p&gt;实际上，我做的这些事情有没有公司都能推进，但没办法，就为了微信小程序后续的企业认证需求.&lt;/p&gt;
&lt;p&gt;在浙江线上办理，全程可以不出门。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;項目&lt;/th&gt;
&lt;th&gt;內容&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;企业名称&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;浪泳科技（义乌）有限公司&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;自主申报预选号&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;[2025]******&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;拟登记机关&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;义乌市市场监督管理局&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;住所所在地&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;******&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;生产经营地&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;******&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;法定代表人&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;******&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;从业人数&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;联系电话&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;186****7426&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;邮政编码&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;322000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;注册资本&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.001万元&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;企业类型&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;有限责任公司(自然人独资)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;行业&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;(6513) 应用软件开发&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;是否一照多址&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;经营范围&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;写不下&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;被驳回&lt;/h2&gt;
&lt;p&gt;提交申请还不到俩小时，我就收到了驳回通知：&lt;/p&gt;
&lt;p&gt;您申报的“浪泳科技（义乌）有限公司”设立登记申请，预审未通过，请补齐材料后再次申报。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;注册资本显著过低，不符实际，请调整；&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;身份证照片裁剪旋转摆正上传， 要求照片只保留身份证、其余无关背景裁去并放正上传；&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;部门产权信息核验不通过，需要提供产权证或是前往地名办办理登记，若房屋登记用途为住宅的，仅能从事电子商务、计算机数据处理、软件和信息服务、网络技术、文化创意、动漫游戏开发、翻译服务、工业设计，审核人将在经营范围最后添加以上销售仅限网上销售，咨询电话：0579-85232920/85117280/85518797/85518798（业务咨询电话：0579-85232920）&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;注册资本一元行不通，调整到了一万&lt;/p&gt;
&lt;p&gt;经营范围调整为：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;软件开发；信息系统集成服务；网络与信息安全软件开发；人工智能基础软件开发；数字技术服务；网络技术服务；软件外包服务；信息技术咨询服务；数字内容制作服务（不含出版发行）；数据处理和存储支持服务；互联网销售（除销售需要许可的商品）；软件销售(除依法须经批准的项目外，凭营业执照依法自主开展经营活动)。&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%8B%AC%E7%AB%8B%E5%BC%80%E5%8F%91%E8%80%85%E5%88%9B%E4%B8%9A%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fstartup%2F2025-06-12-im-starting-up&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>二零二五 - 六七月读书随笔</title><link>https://blog.lhasa.icu/posts/book/2025-06-07-reading-log</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/book/2025-06-07-reading-log</guid><pubDate>Sat, 07 Jun 2025 08:16:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;书犹药也，善读之可以医愚&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;20250713224907_26.jpg&quot; alt=&quot;C3环球游记Ⅲ：加勒比没有那么远 | 徒步进藏 | 不去会死&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;二手海淘&lt;/h2&gt;
&lt;p&gt;这三本书买的有段时间了，在 &lt;a href=&quot;/dragon-boat-cycling-beiyuxian/&quot;&gt;端午骑行：倍鱼线&lt;/a&gt; 里我随口提过一嘴，算起来，另外两本书吃灰近四周了。最近没心情敲代码，索性把书捡了起来。&lt;/p&gt;
&lt;p&gt;第一本看完的是《不去会死》，作者是小日子过得还不错的“石田裕辅”。&lt;/p&gt;
&lt;p&gt;这本书还是从 Pluskid 博主 2022 书单里看到的，我一眼瞄到封面是自行车，当时就放下鼠标，开始在在各个平台寻找这本实体书。由于发行较早，市面上大都是二手货，而且是非彩印版本。唯一的全新版本是台版的，八月开售（繁体）。&lt;/p&gt;
&lt;p&gt;我在手机上扒拉了很久，终于在某宝一个“倒江湖”的小商贩那里，以27元下单了（定价38）。我也没怀着捡漏的心态买这玩意，只希望它不缺页就行了。&lt;/p&gt;
&lt;p&gt;端午傍晚回家，看到快递，拆包后看到实物，如获至宝啊！上海译文出版，上海书刊印刷！而且是全彩印刷版本，还是2012年5月第一版的第一批印刷！看这纸张和文字印刷质量，正版无疑，且无一缺页。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713233054_27.jpg&quot; alt=&quot;不去会死，在版编目（CIP）数据&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;不去会死&lt;/h2&gt;
&lt;p&gt;端午过后的第一天，六月一号下午，我背着单肩挎包，带着书，骑着我的公路车，溜达到义乌植物园，找了一个石凳子，一坐就是一下午，把这本书给炫完了。怎么说呢？这本书实在太他妈的精彩了！&lt;/p&gt;
&lt;p&gt;想想看，打工三年攒了5400美金出发，期间还被土匪抢劫3000美金，就这样骑行环游世界七年半、横跨五大洲、八十七个国家！&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;p.s.不要问没钱怎么活，这大哥擅长钓鱼、自制鱼干&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;1732743676551.jpg&quot; alt=&quot;阿根廷，巴塔哥尼亚，1997年2月&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;遭遇土匪顶枪抢劫&lt;/h3&gt;
&lt;p&gt;在秘鲁·纳斯卡的沙漠公路骑行时，石田君惨遭绑架，连人带车被三个持枪土匪拖进沙漠深处。&lt;/p&gt;
&lt;p&gt;当时土匪拿枪顶着他，把他的双手反绑在背后，脚也被绑了。土匪为了敛财，裤头都给他扒光了。他还以为土匪要强奸他，哈哈哈。就这样，这大哥还在讲条件，恳求留下自行车。&lt;/p&gt;
&lt;p&gt;结果土匪把护照和全部财产的暗袋都抢走了，还有露营用品、药品和工具，所有装备洗劫一空。好在土匪太慌了，地上还散落一些杂物和掉落的二百美金。最重要的自行车，由于土匪来不及抢走也留下了。&lt;/p&gt;
&lt;p&gt;事后他联系保险公司索赔，但是片警连抢劫证明都不给开，开口嘴就是“Money”。&lt;/p&gt;
&lt;p&gt;后来他回忆说：“当时一点都不紧张。相反，土匪紧张得像热锅上的蚂蚁。”三个土匪还在他面前内讧，大吵一架，土匪跑之前还主动帮他穿好裤子。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;fd59eb8d41eaff50ca78239cfe.jpg&quot; alt=&quot;秘鲁，在纳斯卡的沙漠遇到土匪后，1996年&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;清田君&lt;/h3&gt;
&lt;p&gt;除了主人公石田裕辅，让我印象深刻的还有&quot;清田君&quot;，很有趣的一个人，特别是他那句：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;啊啊，真好吃，真好吃啊！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;起初他们在&quot;乔治王子城&quot;相识，石田裕辅这样描述他的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;头发朝四面八方乱长&lt;/li&gt;
&lt;li&gt;头大得出奇，整个巨大的蘑菇头&lt;/li&gt;
&lt;li&gt;脸黑的像烤焦的面包&lt;/li&gt;
&lt;li&gt;眼睛细长锐利&lt;/li&gt;
&lt;li&gt;体格矮小粗壮&lt;/li&gt;
&lt;li&gt;罗圈腿&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;中途他们因路线分开过几次，幸运的是，每次都能在异国他乡相遇！&lt;/p&gt;
&lt;p&gt;以至于后来清田君也遭遇土匪抢劫，还被枪打伤，一度悲惨，一路要饭.....&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713224908_10.jpg&quot; alt=&quot;大树下看书，好不快活&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;卖香菇的老伯&lt;/h3&gt;
&lt;p&gt;骑行到波兰首都华沙时，石田君看中了当地特产蘑菇，纯吃货，天天煲汤&lt;/p&gt;
&lt;p&gt;在骑行穿越森林小路时，他看到一个残障老伯在路边卖香菇，出于对老伯自力更生的感动，他拿出了一个兹罗提（波兰货币）铜板（相当于40日元），满脸笑容的指着蘑菇说：&quot;给我一个兹罗提的份。&quot;&lt;/p&gt;
&lt;p&gt;老伯看他拿一个铜板，马上就变脸了，嘴里一直喊着：“Nie Nie！（不！）”  然后不停地说着什么。&lt;/p&gt;
&lt;p&gt;由于波兰语他压根不懂，他以为老伯嫌他那点钱少。又掏出一张五兹罗提钞票，老伯当场就爆发怒吼：“Nie Nie！” 然后从衣袋里拿出自己的钱包，刻意在石田君面前取出几张钞票。&lt;/p&gt;
&lt;p&gt;石田君看到老伯从钱包里取钞票，他心都凉了，以为老伯想要更多。就在这时，老伯不断的把香菇装进袋子里，嘴里还是不停用波兰语快速说着什么，石田君连忙阻止，但是老伯一点都没有停下来的动作。&lt;/p&gt;
&lt;p&gt;这时候石田君脑海里冒出一个词：“Present？” 他带着疑问随口一说，老伯用力点头回应。&lt;/p&gt;
&lt;p&gt;这时候石田君才明白，老伯不停的用波兰语表达的意思可能就是：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;我怎么能从你这个贫困的旅客身上拿钱呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;a0b5267be32dff94e83aaf186d8.jpg&quot; alt=&quot;波兰，卖香菇的老伯，1997年10月&quot; /&gt;&lt;/p&gt;
&lt;p&gt;最近，我在网上查石田君的个人信息。它还有个人博客，2003年就开始运作了，日更级别！&lt;/p&gt;
&lt;p&gt;石田ゆうすけのエッセイ蔵：https://yusukeishida.jugem.jp&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505212791141.jpg&quot; alt=&quot;五月初，他在日本·静冈骑行撞山，摔断八根肋骨和锁骨。这是康复之旅的第一张照片&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;徒步进藏&lt;/h2&gt;
&lt;p&gt;这是一个京城富姐（凡凡）从成都出发徒步拉萨的故事。纯徒步，不搭车！&lt;/p&gt;
&lt;h3&gt;大路书：&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;成都 - 拉萨，2160公里，3304800步（迪卡侬计步器统计），90天&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;90天：2014年5月2日 — 7月30日（休整15天）&lt;/p&gt;
&lt;p&gt;2160公里：&lt;/p&gt;
&lt;p&gt;成都大件路 → 雅安 → 泸定 → 康定 → 新都桥 → 雅江 → 理塘 → 巴塘 → 芒康 → 左贡 → 邦达 → 八宿 → 然乌 → 波密 → 通麦 → 鲁朗 → 八一 → 工布江达 → 墨竹工卡 → 达孜 → 拉萨布达拉宫&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250715142725.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;凡凡的背包有些重了，出发时的重量在40斤，属于重装范畴。我这小体格是接受不了，毕竟这是肩包，不是驼包。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202507151427588.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h3&gt;书店不让带书&lt;/h3&gt;
&lt;p&gt;说到这我要吐槽一下，进书店不让带书？&lt;/p&gt;
&lt;p&gt;我就问你，你新华书店作为国企，内地从事图书行业的老大哥，你这样做真的好吗？&lt;/p&gt;
&lt;p&gt;是，不让带包，降低被盗风险。但就论书这东西，不看书的不会偷，看书的更不会偷。&lt;/p&gt;
&lt;p&gt;你们这一刀切的政策是和谁学的？开在商场的西西弗人流量不比你大？人家敢说带包不让进吗？今天不让进，明天他就倒闭。&lt;/p&gt;
&lt;p&gt;就你这还文化行业呢，呸，恶心！中国的国企都是他妈的社会寄生虫，从此以后不在新华书店买一本书。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713224908_11.jpg&quot; alt=&quot;义乌，新华书店（图书大厦店）&quot; /&gt;&lt;/p&gt;
&lt;h3&gt;转战西西弗&lt;/h3&gt;
&lt;p&gt;自从离开上海，我所在的十八线小城市再也见不到西西弗了。算下来，我已经有一年半没有去过了。在上海那段时间，我几乎每天上午都会去西西弗，买一杯最便宜的咖啡，提着书包去占座。因为西西弗离我们公司非常近，公司在万象城五楼，而西西弗在三楼，所以我站在五楼的视角俯瞰，完全可以看着他们开门营业，每天必抢到黄金位置。&lt;/p&gt;
&lt;p&gt;下午两点下班，我没有回家睡觉的欲望。我要么出去骑车去外滩，要么去西西弗看书，没有第三个选择。所以，坐电梯下3楼，一头扎进L333A-A号，直到听见 Going home。&lt;/p&gt;
&lt;p&gt;其实，待在西西弗，我的目的不止是看书。在下班后，店里几乎每天都会给我带来福报，这个帝王蟹客人晚宴要用，那个东星斑规格不行。接到骚扰电话后，我就得先打电话联系档口，然后起身开车去江阳市场，所以西西弗是一个很好的选择。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713224907_23.jpg&quot; alt=&quot;义乌，西西弗，印悦城店&quot; /&gt;&lt;/p&gt;
&lt;p&gt;实话说，以我目前的经济，来西西弗有些奢侈了。一杯咖啡四十块，还非常难喝。&lt;/p&gt;
&lt;p&gt;但是我在义乌找不到晚上六点后可以去看书的地方了，求推荐。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713224907_21.jpg&quot; alt=&quot;几年前在杭州林隐寺买的包，很适合装书&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713224907_19.jpg&quot; alt=&quot;正在读 C3环球游记&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250713224907_16.jpg&quot; alt=&quot;最爱的姿势：躺着，用抱枕托着书&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BA%8C%E9%9B%B6%E4%BA%8C%E4%BA%94%20-%20%E5%85%AD%E4%B8%83%E6%9C%88%E8%AF%BB%E4%B9%A6%E9%9A%8F%E7%AC%94&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fbook%2F2025-06-07-reading-log&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>EasyFill v1.1.1 发布：全面提升用户体验</title><link>https://blog.lhasa.icu/posts/technology/2025-06-02-easyfill-1-1-1</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-06-02-easyfill-1-1-1</guid><pubDate>Mon, 02 Jun 2025 15:27:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;版本：v1.1.1&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;经过两个月的偷懒，EasyFill 迎来了 v1.1.1 版本的重大更新。这次更新主要在匹配算法上进行大幅度优化，全面提升匹配效率&lt;/p&gt;
&lt;h2&gt;更新概览&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;支持动态 Shadow DOM 和三种全新识别方式&lt;/li&gt;
&lt;li&gt;可自定义数据源，智能缓存机制&lt;/li&gt;
&lt;li&gt;Markdown 文本异步并行加载&lt;/li&gt;
&lt;li&gt;自适应三级别日志，支持控制台调试&lt;/li&gt;
&lt;li&gt;更新隐私政策&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;全新识别方式&lt;/h2&gt;
&lt;h3&gt;1. 动态 Shadow DOM 支持&lt;/h3&gt;
&lt;p&gt;我发现有些评论系统通过 Shadow DOM 来实现封装，导致 v1.0 版本无法识别 Shadow DOM 生成的表单。在 v1.1.1 中，EasyFill 新增了对动态创建的 Shadow DOM 的完整支持。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function traverseShadowDOM(root: Document | ShadowRoot | Element) {
  const inputs = root.querySelectorAll(&apos;input, textarea&apos;);
  elements.push(...Array.from(inputs));
  
  const allElements = root.querySelectorAll(&apos;*&apos;);
  allElements.forEach(element =&amp;gt; {
    if (element.shadowRoot) {
      logger.info(&apos;发现 Shadow DOM，正在遍历&apos;, { 
        tagName: element.tagName, 
        shadowRootMode: element.shadowRoot.mode 
      });
      traverseShadowDOM(element.shadowRoot);
    }
  });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 三种识别方式全覆盖&lt;/h3&gt;
&lt;p&gt;在 v1.0 版本，EasyFill 只支持 name 字段识别。为了更加准确的匹配字段，引入了全新三种字段识别方式，确保在各种稀奇古怪的表单都可以识别：&lt;/p&gt;
&lt;h4&gt;Placeholder 识别&lt;/h4&gt;
&lt;p&gt;通过分析输入框的 &lt;code&gt;placeholder&lt;/code&gt; 属性来识别字段类型：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input placeholder=&quot;请输入您的姓名&quot; /&amp;gt;
&amp;lt;input placeholder=&quot;邮箱地址&quot; /&amp;gt;
&amp;lt;input placeholder=&quot;个人网站&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Type 识别&lt;/h4&gt;
&lt;p&gt;基于 HTML5 标准的 &lt;code&gt;type&lt;/code&gt; 属性进行智能识别：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&quot;email&quot; /&amp;gt;
&amp;lt;input type=&quot;url&quot; /&amp;gt;
&amp;lt;input type=&quot;text&quot; name=&quot;username&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;ID 识别&lt;/h4&gt;
&lt;p&gt;通过元素的 &lt;code&gt;id&lt;/code&gt; 属性进行精确匹配：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;input id=&quot;author&quot; /&amp;gt;
&amp;lt;input id=&quot;email&quot; /&amp;gt;
&amp;lt;input id=&quot;website&quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;匹配策略：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;inputs.forEach((input) =&amp;gt; {
  const typeAttr = (input.getAttribute(&quot;type&quot;) || &quot;&quot;).toLowerCase();
  const nameAttr = (input.getAttribute(&quot;name&quot;) || &quot;&quot;).toLowerCase();
  const idAttr = (input.getAttribute(&quot;id&quot;) || &quot;&quot;).toLowerCase();
  let valueToSet = &quot;&quot;; // 要填充的值
  let matchedBy = &quot;&quot;;  // 匹配方式（id, name, type）
  let fieldType = &quot;&quot;;  // 字段类型（name, email, url）

  // 匹配 URL 字段
  if (keywordSets.url.has(nameAttr) || keywordSets.url.has(`#${idAttr}`)) {
    valueToSet = url;
    matchedBy = keywordSets.url.has(`#${idAttr}`) ? &quot;id&quot; : &quot;name&quot;;
    fieldType = &quot;url&quot;;
  } else if (typeAttr === &quot;url&quot; &amp;amp;&amp;amp; url) {
    valueToSet = url;
    matchedBy = &quot;type&quot;;
    fieldType = &quot;url&quot;;
  }

  // 匹配 Email 字段
  else if (keywordSets.email.has(nameAttr) || keywordSets.email.has(`#${idAttr}`)) {
    valueToSet = email;
    matchedBy = keywordSets.email.has(`#${idAttr}`) ? &quot;id&quot; : &quot;name&quot;;
    fieldType = &quot;email&quot;;
  } else if (typeAttr === &quot;email&quot; &amp;amp;&amp;amp; email) {
    valueToSet = email;
    matchedBy = &quot;type&quot;;
    fieldType = &quot;email&quot;;
  }

  // 匹配 Name 字段
  else if ((keywordSets.name.has(nameAttr) || keywordSets.name.has(`#${idAttr}`)) &amp;amp;&amp;amp; name) {
    valueToSet = name;
    matchedBy = keywordSets.name.has(`#${idAttr}`) ? &quot;id&quot; : &quot;name&quot;;
    fieldType = &quot;name&quot;;
  }

  // 没有匹配上就跳过
  if (!valueToSet) return;

  // 设置值并触发事件
  (input as HTMLInputElement).value = valueToSet;
  input.dispatchEvent(new Event(&apos;input&apos;, { bubbles: true }));
  input.dispatchEvent(new Event(&apos;change&apos;, { bubbles: true }));

  // 记录日志
  logger.info(&apos;填充表单字段&apos;, {
    name: nameAttr || &quot;&quot;,
    id: idAttr || &quot;&quot;,
    type: typeAttr || &quot;&quot;,
    matchedBy,
    valueToSet,
    inShadowDOM: isInShadowDOM(input)
  });
});

&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;数据同步&lt;/h2&gt;
&lt;h3&gt;1. 自定义数据源功能&lt;/h3&gt;
&lt;p&gt;v1.1.1 版本允许用户完全自定义关键字数据源。&lt;/p&gt;
&lt;p&gt;该源来自我的腾讯云 COS，且由腾讯云境内 CDN 加速，基本上无延迟：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;https://cos.lhasa.icu/EasyFill/keywords.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;自定义数据源格式示例：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;name&quot;: [&quot;name&quot;, &quot;author&quot;, &quot;username&quot;, &quot;昵称&quot;, &quot;姓名&quot;],
  &quot;email&quot;: [&quot;email&quot;, &quot;mail&quot;, &quot;邮箱&quot;, &quot;电子邮件&quot;],
  &quot;url&quot;: [&quot;url&quot;, &quot;website&quot;, &quot;blog&quot;, &quot;网站&quot;, &quot;博客&quot;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 缓存机制&lt;/h3&gt;
&lt;p&gt;实现了基于 HTTP 标准的智能缓存系统，大幅减少不必要的网络请求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;304 Not Modified 响应处理&lt;/li&gt;
&lt;li&gt;自动缓存有效期管理（24小时）&lt;/li&gt;
&lt;li&gt;网络失败时自动回退到缓存&lt;/li&gt;
&lt;li&gt;支持强制刷新机制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;ETag 和 Last-Modified 支持：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (etag &amp;amp;&amp;amp; !forceSync) {
  headers[&apos;If-None-Match&apos;] = etag;
}
if (lastModified &amp;amp;&amp;amp; !forceSync) {
  headers[&apos;If-Modified-Since&apos;] = lastModified;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;性能优化&lt;/h2&gt;
&lt;h3&gt;1. localStorage 持久化存储&lt;/h3&gt;
&lt;p&gt;实现 Markdown 内容的持久化机制：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const fetchMarkdown = async (url: string) =&amp;gt; {
  try {
    // 检查 localStorage 是否已有缓存
    const cachedMarkdown = localStorage.getItem(url);
    if (cachedMarkdown) {
      logger.info(`从缓存加载 Markdown 文件: ${url}`);
      return cachedMarkdown;
    }

    // 如果没有缓存，从网络加载
    const response = await fetch(url);
    const markdown = await response.text();

    // 将加载的内容存入 localStorage
    localStorage.setItem(url, markdown);
    return marked(markdown);
  } catch (error) {
    logger.error(`加载 Markdown 文件失败: ${url}`, error);
  }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 异步并行加载优化&lt;/h3&gt;
&lt;p&gt;实现 Markdown 内容的异步并行加载：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const loadContent = async () =&amp;gt; {
  const [aboutAuthor, recommendedPlugins, updateLog, privacyPolicy] = await Promise.all([
    fetchMarkdown(&apos;/markdowns/about-author.md&apos;),
    fetchMarkdown(&apos;/markdowns/recommended-plugins.md&apos;),
    fetchMarkdown(&apos;/markdowns/UpdateLog.md&apos;),
    fetchMarkdown(&apos;/markdowns/privacy-policy.md&apos;),
  ]);

  setAboutAuthorContent(aboutAuthor);
  setRecommendedPluginsContent(recommendedPlugins);
  setUpdateLogContent(updateLog);
  setPrivacyPolicyContent(privacyPolicy);
};
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;h2&gt;日志系统&lt;/h2&gt;
&lt;h3&gt;1. 三级别日志架构&lt;/h3&gt;
&lt;p&gt;EasyFill v1.1.1 实现了单例日志系统，支持 INFO、WARN、ERROR 三个级别：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export enum LogLevel {
  INFO = &apos;INFO&apos;,
  WARN = &apos;WARN&apos;,
  ERROR = &apos;ERROR&apos;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 智能环境适配&lt;/h3&gt;
&lt;p&gt;日志系统能够根据运行环境自动调整输出策略：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;public configureByEnvironment(): Logger {
  const isProd = typeof process !== &apos;undefined&apos; &amp;amp;&amp;amp; process.env &amp;amp;&amp;amp; process.env.NODE_ENV === &apos;production&apos;;
  
  if (isProd) {
    // 生产环境：只显示警告和错误
    this.setLevel(LogLevel.WARN);
  } else {
    // 开发环境：显示所有日志，并启用彩色和时间戳
    this.setLevel(LogLevel.INFO)
        .useColors(true)
        .showTimestamp(true);
  }
  
  return this;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3. 控制台命令&lt;/h3&gt;
&lt;p&gt;生产状态下，日志默认关闭。所以，增加了命令调试：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 启用日志系统
EasyFillLogger.enable()

// 关闭日志系统
EasyFillLogger.disable()

// 查看当前状态
EasyFillLogger.status()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令绑定在全局 window 对象上，重启浏览器仍有效。&lt;/p&gt;
&lt;p&gt;在浏览器扩展环境中，使用 chrome.storage.local 来存储，在普通网页环境中，使用 localStorage。&lt;/p&gt;
&lt;p&gt;一样的是都用 easyfill_logger_enabled 这个键来存储&lt;/p&gt;
&lt;h3&gt;4. 链式配置接口&lt;/h3&gt;
&lt;p&gt;支持灵活的链式配置：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;logger
  .setLevel(LogLevel.INFO)
  .useColors(true)
  .showTimestamp(true)
  .setPrefix(&apos;[EasyFill]&apos;)
  .setPrefixColor(&apos;color: #4CAF50; font-weight: bold&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;配置选项：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义日志前缀和颜色&lt;/li&gt;
&lt;li&gt;时间戳显示控制&lt;/li&gt;
&lt;li&gt;彩色输出开关&lt;/li&gt;
&lt;li&gt;级别过滤设置&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;隐私权政策&lt;/h2&gt;
&lt;p&gt;v1.1.1 版本对隐私权政策进行了全面更新：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;主要更新内容：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明确了关键字数据同步的目的和方式&lt;/li&gt;
&lt;li&gt;增加了用户控制权的说明&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;界面改进&lt;/h2&gt;
&lt;h3&gt;1. 同步设置&lt;/h3&gt;
&lt;p&gt;新增了直观的同步设置界面，轻松管理数据同步：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;同步开关&lt;/strong&gt;：一键启用/禁用自动同步&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;同步频率&lt;/strong&gt;：支持 1 小时到 1 周的灵活设置&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;网络条件&lt;/strong&gt;：可选择任何网络或仅 WiFi&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据源管理&lt;/strong&gt;：支持自定义 URL 和一键重置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 状态反馈优化&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;实时显示同步状态和下次同步时间&lt;/li&gt;
&lt;li&gt;提供详细的操作成功/失败反馈&lt;/li&gt;
&lt;li&gt;使用 Snackbar 组件统一消息提示风格&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;短期计划&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;实现黑白名单机制，控制填充权限&lt;/li&gt;
&lt;li&gt;支持多身份设置，满足不同用户需求&lt;/li&gt;
&lt;li&gt;完成在 Edge 和 Firefox 浏览器上的上架与兼容&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;长远计划&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;使用 TensorFlow 训练机器学习模型，实现自动识别和评论补全功能&lt;/li&gt;
&lt;li&gt;在无性能开销的情况下，实现移动端跨平台支持（iOS 与 Android）&lt;/li&gt;
&lt;li&gt;依托 EasyFill 建立独立博客生态社区，面向计算机学生及爱好者提供系统性新手指南&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;致谢与支持&lt;/h2&gt;
&lt;p&gt;EasyFill 的每一次进步都离不开用户的支持和反馈。特别感谢：&lt;strong&gt;Mainbranch&lt;/strong&gt; 的反馈与支持&lt;/p&gt;
&lt;p&gt;如果您觉得 EasyFill 对您有帮助，欢迎：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;a href=&quot;https://github.com/achuanya/EasyFill&quot;&gt;GitHub&lt;/a&gt; 上给项目点星&lt;/li&gt;
&lt;li&gt;在 &lt;a href=&quot;https://chromewebstore.google.com/detail/eamchegekphehbmebccbapnihegngobm&quot;&gt;Chrome 应用商店&lt;/a&gt; 留下评价&lt;/li&gt;
&lt;li&gt;在我的&lt;a href=&quot;https://lhasa.icu&quot;&gt;博客&lt;/a&gt;上留言交流&lt;/li&gt;
&lt;li&gt;通过赞赏码支持项目发展&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;lt;details&amp;gt;
&amp;lt;summary&amp;gt;请我喝一杯咖啡&amp;lt;/summary&amp;gt;
&lt;img src=&quot;https://cos.lhasa.icu/StylePictures/Appreciation-code.webp&quot; alt=&quot; &quot; /&gt;
&amp;lt;/details&amp;gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;立即体验&lt;/h2&gt;
&lt;p&gt;EasyFill v1.1.1 现已在 Chrome 应用商店正式发布，您可以：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;新用户&lt;/strong&gt;：直接在 Chrome 应用商店搜索 &quot;EasyFill&quot; 安装&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;现有用户&lt;/strong&gt;：通过梯子 Chrome 扩展将自动更新到最新版本&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;开发者&lt;/strong&gt;：访问 &lt;a href=&quot;https://github.com/achuanya/EasyFill&quot;&gt;GitHub 仓库&lt;/a&gt; 查看源代码&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;strong&gt;EasyFill - 简易填充，让每一次评论更自然，与你的博友互动无缝连接&lt;/strong&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=EasyFill%20v1.1.1%20%E5%8F%91%E5%B8%83%EF%BC%9A%E5%85%A8%E9%9D%A2%E6%8F%90%E5%8D%87%E7%94%A8%E6%88%B7%E4%BD%93%E9%AA%8C&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-06-02-easyfill-1-1-1&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>端午骑行：倍鱼线</title><link>https://blog.lhasa.icu/posts/outdoors/2025-06-01-dragon-boat-cycling-beiyuxian</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-06-01-dragon-boat-cycling-beiyuxian</guid><pubDate>Sat, 31 May 2025 16:01:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;20250531195449.jpg&quot; alt=&quot;倍鱼线 入口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954481.jpg&quot; alt=&quot;柏峰水库 一级水源&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195447.jpg&quot; alt=&quot;横门殿桥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;养兵千日用兵一时，Samsung S Pen 触控笔有点作用了，遥控手机拍照&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195440.jpg&quot; alt=&quot;横门殿桥合影&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954471.jpg&quot; alt=&quot;横门殿桥合影&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195446.jpg&quot; alt=&quot;横门殿桥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954461.jpg&quot; alt=&quot;柏峰水库（横门殿桥视角）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954451.jpg&quot; alt=&quot;端午虽热，但来露营的人真不少&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954452.jpg&quot; alt=&quot;小溪旁的营地&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195444.jpg&quot; alt=&quot;不知道在抓什么物种&quot; /&gt;&lt;/p&gt;
&lt;p&gt;浙江的端午真不是盖的，室外像个桑拿房，给我一种快脱水的感觉。&lt;/p&gt;
&lt;p&gt;我把车停靠在护栏上就下来了，咱也来来体验一下山泉水。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954441.jpg&quot; alt=&quot;一级山泉水&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195443.jpg&quot; alt=&quot;热热热&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954431.jpg&quot; alt=&quot;即将脱水&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195442.jpg&quot; alt=&quot;山腰上&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531195441.jpg&quot; alt=&quot;山顶（鱼曹头村方向）&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954421.jpg&quot; alt=&quot;合影合影&quot; /&gt;&lt;/p&gt;
&lt;p&gt;太幸福了！刚到达鱼曹头村，正好碰到一户人家在做午饭，花小钱办大事啊！吃吃饭再给手机充充电。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954422.jpg&quot; alt=&quot;什么馅都有的馄饨&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上山俩小时，下坡十分钟。速度达到 45 - 60 码！各种弯道，非常刺激！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202505311954412.jpg&quot; alt=&quot;准备返程回家了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531232516.jpg&quot; alt=&quot;爬升：1355m | 时间：4.15 | 距离：80.09km&quot; /&gt;&lt;/p&gt;
&lt;p&gt;离家最后三公里时突然暴雨，我滴天啊，该下的时候你不下。&lt;/p&gt;
&lt;p&gt;到家后快递也到了，这三本书中我最期待石田裕辅写的&quot;不去会死&quot;&lt;/p&gt;
&lt;p&gt;这本书是 &amp;lt;a href=&quot;https://freemind.pluskid.org/books/2022-book-list-winter&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&amp;gt;Pluskid 2022 书单其中一本&amp;lt;/a&amp;gt; 看到他写的评语后，我就马上找这本书。偏小众些，年代久远不好找，都是二手货，全新没有简体版本，台版的八月开售（繁体）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250531232920.jpg&quot; alt=&quot;C3环游记Ⅲ：加勒比没有那么远 | 徒步进藏 | 不去会死&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%AB%AF%E5%8D%88%E9%AA%91%E8%A1%8C%EF%BC%9A%E5%80%8D%E9%B1%BC%E7%BA%BF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-06-01-dragon-boat-cycling-beiyuxian&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>基于 Astro Paper 的个人博客：深度定制和部署实践</title><link>https://blog.lhasa.icu/posts/technology/2025-05-31-astro-paper-deployment</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-05-31-astro-paper-deployment</guid><pubDate>Fri, 30 May 2025 19:12:00 GMT</pubDate><content:encoded>&lt;p&gt;今天是我独立博客走过的第八个年头。还记得那一年怀着对独立站的疑问，给孔令贤发邮件，询问是否可以使用他写的轮子，就是从他回复我那一刻起，我掉进了 WEB 深渊。&lt;/p&gt;
&lt;p&gt;独立博客这个词，在 2025 年这个年代确实足够小众，但其中的快乐和对生活的态度，想必也只有博友能理解。&lt;/p&gt;
&lt;p&gt;正是为了这第八个年头，才有了今天这全新的博客。从年初用 Jekyll 从零开始写，后来又用 Recat 写个半成品。最终阴差阳错选择了开源的 Astro Paper。&lt;/p&gt;
&lt;p&gt;Astro Paper 这款主题性能极强，可拓展性也非常高，这也得益于 Astro 的静态特性和原作者优越设计。&lt;/p&gt;
&lt;p&gt;经过一段时间的二次开发，这个博客差不多达到了我理想的样子。&lt;/p&gt;
&lt;p&gt;在全站无缝刷新的基础下，我把博客全站的图片都做了懒加载，订阅和归档模块也做了滚动懒加载。&lt;/p&gt;
&lt;p&gt;再加上页面内链的预加载处理，无论你点击哪个页面，都是一种享受。&lt;/p&gt;
&lt;h2&gt;Lighthouse 评分&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;astropaper-lighthouse-score.svg&quot; alt=&quot;Lighthouse 评分&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下面就把新增的功能一一道来。&lt;/p&gt;
&lt;h2&gt;分类路由支持&lt;/h2&gt;
&lt;p&gt;Astro Paper 原生不支持平铺式 URL，也不能把文章进行分类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://lhasa.icu/posts/astro-paper-deployment/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;改进后:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;文章可按分类（技术、生活、运动等）划分路由。&lt;/li&gt;
&lt;li&gt;支持按年份归档，且不会影响已有 URL 访问。&lt;/li&gt;
&lt;li&gt;URL 更加简洁：&lt;/li&gt;
&lt;/ol&gt;
&lt;ul&gt;
&lt;li&gt;https://lhasa.icu/astro-paper-deployment/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;分类路由结构如下，可在&lt;code&gt;/src/pages/&lt;/code&gt;中按需创建：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;blog/
  ├── _releases/
  ├── examples/
  ├── life/
  │   ├── 2024/
  │   └── 2025/
  ├── sports/
  │   ├── 2024/
  │   └── 2025/
  └── technology/
      ├── 2024/
      └── 2025/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;路由中间件处理&lt;/h2&gt;
&lt;p&gt;在不用 Artalk 评论系统的情况下，这个功能其实可有可无。但 Artalk 在路径识别上，存在很大的问题（带斜杠与不带斜杠会被视为不同页面），存在一定的隐患。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://lhasa.icu/sports&lt;/li&gt;
&lt;li&gt;https://lhasa.icu/sports/&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实使用 Nginx 会更方便一些。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { defineMiddleware } from &quot;astro:middleware&quot;;

export const onRequest = defineMiddleware((context, next) =&amp;gt; {
  const url = context.url;
  const pathname = url.pathname;
  
  const staticExtensions = [
    &apos;.png&apos;, &apos;.jpg&apos;, &apos;.jpeg&apos;, &apos;.gif&apos;, &apos;.svg&apos;, &apos;.webp&apos;, &apos;.ico&apos;,
    &apos;.css&apos;, &apos;.js&apos;, &apos;.json&apos;, &apos;.xml&apos;, &apos;.txt&apos;, &apos;.pdf&apos;,
    &apos;.woff&apos;, &apos;.woff2&apos;, &apos;.ttf&apos;, &apos;.eot&apos;, &apos;.otf&apos;
  ];
  
  const isStaticResource = staticExtensions.some(ext =&amp;gt; 
    pathname.toLowerCase().endsWith(ext)
  );
  
  // 如果是静态资源，不处理尾部斜杠
  if (isStaticResource) {
    return next();
  }
  
  // 如果URL不以斜杠结尾且不是根路径，则重定向到带斜杠的版本
  if (pathname !== &quot;/&quot; &amp;amp;&amp;amp; !pathname.endsWith(&quot;/&quot;)) {
    const newUrl = new URL(pathname + &quot;/&quot; + url.search + url.hash, url.origin);
    return Response.redirect(newUrl.toString(), 301);
  }
  
  return next();
}); 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;运动数据可视化&lt;/h2&gt;
&lt;p&gt;接入 Strava Riding Api 做了运动数据的可视化。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;光标悬浮可切换月数据&lt;/li&gt;
&lt;li&gt;点击日期可查看当天运动详情&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;sportsdonghua.webp&quot; alt=&quot;EasyFill·我的信息&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;EXIF 元数据显示&lt;/h2&gt;
&lt;p&gt;借助腾讯云数据万象 API，默认自动启用。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;参数为 Boolean 类型，false 可禁用&lt;/li&gt;
&lt;li&gt;光标悬浮显示两秒&lt;/li&gt;
&lt;li&gt;解析失败会自动生成合理参数并缓存&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;

![ ](20250524003018.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;20250524003018.jpg&quot; alt=&quot;EXIF 示例&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;图片标签&lt;/h2&gt;
&lt;p&gt;所有图片默认使用长标签，支持切换为短标签或禁用标签&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250530173339.jpg&quot; alt=&quot;义乌美术馆一角&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250530173339.jpg&quot; alt=&quot;义乌美术馆一角&quot; /&gt;&lt;/p&gt;
&lt;p&gt;若想在文章中启用 EXIF，需要将 .md 改为 .mdx，并引入组件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;

![义乌美术馆一角](20250530173339.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;悬停提示（tooltip）效果&lt;/h2&gt;
&lt;p&gt;图片的 title 属性不必声明，只要有 alt 属性，Img.astro 组件就会自动读取并渲染到页面中。&lt;/p&gt;
&lt;h2&gt;数学公式支持&lt;/h2&gt;
&lt;p&gt;通过 KaTeX 集成 支持了数学公式。纯静态渲染，无性能问题。示例：&lt;/p&gt;
&lt;p&gt;$$
\text{骑行里程} = \text{均速} \times \text{时间}
$$&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$$
\text{骑行里程} = \text{均速} \times \text{时间}
$$
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Artalk 集成&lt;/h2&gt;
&lt;p&gt;说到评论系统，首先感谢 Disqus PHP API 开源作者 Fooleap，感谢好大哥这些年来帮我在境外挂着接口...&lt;/p&gt;
&lt;p&gt;Artalk 官方提供了简单的配置文件，不过足够了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;services:
  artalk:
    container_name: artalk
    image: artalk/artalk-go
    restart: unless-stopped
    ports:
      - 9998:23366
    volumes:
      - ./data:/data
    environment:
      - TZ=Asia/Shanghai
      - ATK_LOCALE=zh-CN
      - ATK_SITE_DEFAULT=游钓四方的博客
      - ATK_SITE_URL=https://lhasa.icu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;创建容器运行 Artalk：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker-compose up -d

# 执行命令创建管理员账户
docker exec -it artalk artalk admin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;再使用 Nginx 反代 9998 端口就可以实现域名访问了。&lt;/p&gt;
&lt;p&gt;由于我是 Disqus 迁移过来的，需要把格式转换为 Artrans，然后再导入 Artalk。&lt;/p&gt;
&lt;p&gt;由于无缝刷新的存在，就单单评论来说，调试花了不少时间，踩了很多坑，这里还把 Artalk 随着主题变化适配了配色。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;script is:inline data-astro-rerun&amp;gt;
(function () {
  // 单例模式存储 Artalk 实例
  window.artalkInstance = window.artalkInstance || null;

  const artalkConfig = {
    el: &quot;#Comments&quot;,
    server: &quot;https://artalk.lhasa.icu&quot;,
    site: &quot;游钓四方的博客&quot;,
    pageKey: window.location.pathname,
    vote: false,

  };

  function destroyArtalk() {
    if (window.artalkInstance) {
      try {
        window.artalkInstance.destroy();
        document
          .querySelectorAll(&quot;.atk-sidebar, .atk-layer-wrap&quot;)
          .forEach(el =&amp;gt; el.remove());
        window.artalkInstance = null;
        console.log(&quot;Artalk 实例已销毁&quot;, window.location.pathname);
      } catch (err) {
        console.error(&quot;销毁失败:&quot;, err);
      }
    }
  }

  // 初始化 Artalk 实例
  function initArtalk() {
    const container = document.getElementById(&quot;Comments&quot;);
    if (!container || container.querySelector(&quot;.atk-app&quot;)) return;

    const isDark = document.documentElement.getAttribute(&quot;data-theme&quot;) === &quot;dark&quot;;

    artalkConfig.pageKey = window.location.pathname;
    artalkConfig.darkMode = isDark;

    window.artalkInstance = Artalk.init(artalkConfig);
    console.log(&quot;Artalk 初始化完成&quot;, window.location.pathname);
  }

  function handleThemeChange() {
    const themeBtn = document.querySelector(&quot;#theme-btn&quot;);
    if (!themeBtn) return;

    const observer = new MutationObserver(mutations =&amp;gt; {
      mutations.forEach(mutation =&amp;gt; {
        if (mutation.attributeName === &quot;aria-label&quot;) {
          const isDark =
            mutation.target.getAttribute(&quot;aria-label&quot;) === &quot;dark&quot;;
          if (window.artalkInstance) {
            window.artalkInstance.setDarkMode(isDark);
          }
        }
      });
    });

    observer.observe(themeBtn, {
      attributes: true,
      attributeFilter: [&quot;aria-label&quot;],
    });
  }

  function handlePageLoad() {
    destroyArtalk();
    initArtalk();
    handleThemeChange();
  }

  function setupArtalk() {
    if (window._artalkInitialized) return;
    window._artalkInitialized = true;

    document.addEventListener(&quot;astro:before-swap&quot;, destroyArtalk);
    document.addEventListener(&quot;astro:after-swap&quot;, handlePageLoad);

    if (document.readyState === &quot;complete&quot;) {
      handlePageLoad();
    } else {
      document.addEventListener(&quot;DOMContentLoaded&quot;, handlePageLoad);
    }

    // 监听主题
    window
      .matchMedia(&quot;(prefers-color-scheme: dark)&quot;)
      .addEventListener(&quot;change&quot;, ({ matches }) =&amp;gt; {
        if (window.artalkInstance) {
          window.artalkInstance.setDarkMode(matches);
        }
      });
  }

  setupArtalk();
})();
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Artalk 自带的验证码不好用，这里强烈推荐 Cloudflare Turnstile。无感验证，很省心。&lt;/p&gt;
&lt;p&gt;在 Cloudflare 控制台主页可以看到 Turnstile，在填完域名后可以申请到&lt;code&gt;Site Key&lt;/code&gt;和&lt;code&gt;Secret Key&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;随后打开 Artalk 控制中心，填入相应参数后，&lt;code&gt;captcha_type&lt;/code&gt;选择&lt;code&gt;turnstile&lt;/code&gt;即可。&lt;/p&gt;
&lt;h2&gt;本地开发&lt;/h2&gt;
&lt;p&gt;纯净版 Astro Paper：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# pnpm
pnpm create astro@latest --template satnaing/astro-paper

# npm
npm create astro@latest -- --template satnaing/astro-paper

# yarn
yarn create astro --template satnaing/astro-paper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者直接使用我的扩展版本：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/achuanya/Blog.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后通过安装依赖启动开发环境&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装依赖
pnpm install

# 启动开发环境
pnpm dev
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Docker 部署&lt;/h2&gt;
&lt;p&gt;用于生产环境的 Docker 配置已经写好了，可以直接构建镜像。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 构建生产镜像
docker build -t astropaper .

# 启动生产环境，端口为 4321
docker run -p 4321:80 astropaper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配合 Nginx 反代：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;server {
    listen 80;
    server_name lhasa.icu;

    # 404
    error_page 404 /404.html;
    location = /404.html {
        root /home/github/Blog/dist;
        internal;
    }

    location / {
        proxy_pass http://127.0.0.1:4321;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不想折腾，建议安装宝塔Linux面板，随便点击几下，两分钟上线&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if [ -f /usr/bin/curl ];then curl -sSO https://download.bt.cn/install/install_panel.sh;else wget -O install_panel.sh https://download.bt.cn/install/install_panel.sh;fi;bash install_panel.sh ed8484bec
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Github + Vercel 部署&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;https://vercel.com/templates/blog/astro-paper&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只需点击 Deploy 按钮，按提示一步步即可上线。&lt;/p&gt;
&lt;h2&gt;相关命令&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;安装依赖项&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;启动本地开发服务器，访问地址为 &lt;code&gt;localhost:4321&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run build&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;将生产环境网站构建到 &lt;code&gt;./dist/&lt;/code&gt; 目录&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run preview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;本地预览生产环境构建的站点，部署前检查效果&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run format:check&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 Prettier 检查代码格式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run format&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 Prettier 格式化代码&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run sync&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;为所有 Astro 模块生成 TypeScript 类型。 &lt;a href=&quot;https://docs.astro.build/en/reference/cli-reference/#astro-sync&quot;&gt;了解更多&lt;/a&gt;。&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;pnpm run lint&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 ESLint 进行代码检查&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose up -d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;使用 Docker 运行 AstroPaper，可通过 &lt;code&gt;dev&lt;/code&gt; 命令中相同的主机名和端口进行访问&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker compose run app npm install&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在 Docker 容器中执行任意上述命令&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker build -t astropaper .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;为 AstroPaper 构建 Docker 镜像&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;docker run -p 4321:80 astropaper&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;在 Docker 中运行 AstroPaper。网站可通过 &lt;code&gt;http://localhost:4321&lt;/code&gt; 访问&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;注意！&lt;/strong&gt;&lt;br /&gt;
Windows PowerShell 用户如果想在开发期间运行诊断（例如 &lt;code&gt;astro check --watch &amp;amp; astro dev&lt;/code&gt;），可能需要安装 &lt;a href=&quot;https://www.npmjs.com/package/concurrently&quot;&gt;concurrently 包&lt;/a&gt;。&lt;br /&gt;
更多信息请参考 &lt;a href=&quot;https://github.com/satnaing/astro-paper/issues/113&quot;&gt;这个 issue&lt;/a&gt;。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;下一步&lt;/h2&gt;
&lt;p&gt;目前来说，还有很多地方没有完善，细节没有做到位：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Strava Riding Api 还没有实现完全自动化，更新数据还是需要人工&lt;/li&gt;
&lt;li&gt;Img.astro 组件没有封装到位，还有细节需要把控&lt;/li&gt;
&lt;li&gt;Sports 在移动端时的表现还需要好好想想&lt;/li&gt;
&lt;li&gt;给 Feeds 做个后台管理，先把头像显示问题解决了。当然，有邮箱最好&lt;/li&gt;
&lt;li&gt;吃透 Astro Paper 无缝刷新机制&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;参考文档&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.astro.build/&quot;&gt;Astro&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://artalk.js.org/zh/guide/deploy.html&quot;&gt;Artalk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/achuanya/Blog&quot;&gt;博客源码&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developers.strava.com/&quot;&gt;Strava API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/satnaing/astro-paper&quot;&gt;Astro Paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/achuanya/Strava-Riding-Api&quot;&gt;Strava Riding Api&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cloudflare.com/zh-cn/application-services/products/turnstile/&quot;&gt;Cloudflare Turnstile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%9F%BA%E4%BA%8E%20Astro%20Paper%20%E7%9A%84%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%EF%BC%9A%E6%B7%B1%E5%BA%A6%E5%AE%9A%E5%88%B6%E5%92%8C%E9%83%A8%E7%BD%B2%E5%AE%9E%E8%B7%B5&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-05-31-astro-paper-deployment&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>一路向南，骑见江南：一人、一车、一旅途</title><link>https://blog.lhasa.icu/posts/outdoors/2025-05-11-yilu-xiang-nan-qi-jian-jiang-nan</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-05-11-yilu-xiang-nan-qi-jian-jiang-nan</guid><pubDate>Sun, 11 May 2025 08:28:00 GMT</pubDate><content:encoded>&lt;p&gt;4月24日，递交完辞职报告的那一刻，我心中一阵轻松。我终于可以离开了，离开熟悉的一切，前往下一个未知但让我心跳的地方——义乌。&lt;/p&gt;
&lt;p&gt;原本的计划是从郑州骑行到义乌，约一千公里。然而，我的长途骑行装备都还在老家淮阳，不得不先折返一趟，郑州到淮阳≈210公里。&lt;/p&gt;
&lt;h2&gt;第一站：淮阳&lt;/h2&gt;
&lt;p&gt;4月26日，天还没亮我就起床了，所有行李早已打包妥当，多亏了顺道的好大哥和双双姐姐，他会把行李直接送到义乌，精准投放到阿丽家门口。所以我只需要背上包、骑车走就行了。&lt;/p&gt;
&lt;p&gt;临出门前，我把钥匙存放在小区门口的保安亭，与保安打了招呼，等双姐有空再来取。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;05:42 AM 郑州·孙庄北院&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;20250426_054229.webp_736&quot; alt=&quot;出小区准备吃饭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在小区南门吃了碗大米红枣粥，这是我在郑州的最后一顿早餐。我吃得很慢，望着小区，心里百感交集。最不舍的，是我的双姐，直到离开，我们也没有一张合影。唉……今朝一别，不知何日再见。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250426_054839.webp_736&quot; alt=&quot;离开河南前·最后一碗粥&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;10:49 AM 开封·张市桥&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;从出发到现在，已骑行近百公里（99.81公里），历时4小时15分。中途几乎没停，一直到开封张市桥，看到一位大爷坐在家门口听戏，我停下来敬了他一根烟，顺势在他门口歇了口气。我实在太饿了，得找点吃的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;eeb872ce6c3681.webp_736&quot; alt=&quot;开封·张市桥 不知名大爷家门口歇脚&quot; /&gt;&lt;/p&gt;
&lt;p&gt;骑行至此，除了背包里三根香蕉，还有昨晚和双姐吃剩的半盒牛肉，没有其他补给。吃完香蕉后抽了两根烟，心理上稍有缓解，重新背上包，继续赶路，准备找个地方补点碳水。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250426_104502.webp_736&quot; alt=&quot;坐在大爷家门口板凳上，补个蕉&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;11:52 AM 周口·扶沟&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;点了一碗烩面和一个鸡爪，牛肉是我自带的。说实话，第一次见到餐桌上这么干净的盘子...鸡爪也很入味，咬一口我就扔了，太清真了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250426_115240.webp_736&quot; alt=&quot;白潭镇人民政府旁边的清真小饭店&quot; /&gt;&lt;/p&gt;
&lt;p&gt;骑到汴岗镇时，看到一家超市，顺便买水时偶遇了渤哥。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250426_142434.webp_736&quot; alt=&quot;牌子！班尼路儿~&quot; /&gt;&lt;/p&gt;
&lt;p&gt;经过东夏亭镇人民政府旁的一条支流，干涸得厉害，河床都裸露出来了。不知是人为抽干，还是自然干旱所致。在这段行程中，这样的场景我已经见过好几次。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250426_160541.webp_736&quot; alt=&quot;干旱，河床都漏了出来&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;5:39 PM 周口·淮阳&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;20250426_173919.webp_736&quot; alt=&quot;到家！在小区门口买了两杯最爱的粥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;全程逆风，路上每一米都艰难，越过扶沟、西华，路过麦田，虫子爬满全身，骑得越快身上越多，还有像蛆一样的小东西全身都是，包括脸上，这六十多公里真的折磨，全程都是虫。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;21697b228e.webp&quot; alt=&quot;骑行 204.4 Km&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本次行程装备大致如下：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Challenge ELITE 700×25c 管胎 x1&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Topeak 多功能工具组&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;康比特盐丸 x10包&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;CUKTECH 15 SE 移动电源&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;前后尾灯&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;便携打气筒&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;备用袜子 x4双&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;三合一充电线 若干&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;左边青蓝色的包是我从郑州背回来的，背负系统不科学，透气性也差，只适合日常出行，不适合长途骑行，这次回来扔家里让他吃灰。这次换上了右边的迪卡侬骑行包，内置水袋设计很实用，咬咬吸嘴就能补水，长途骑行相当方便。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1746593086313.webp_736&quot; alt=&quot;换个背包，准备补给&quot; /&gt;&lt;/p&gt;
&lt;p&gt;韶音耳机声音太小，周围稍有噪音就听不见。干脆把BOSE音箱扎带绑车上，没有音乐我不能活。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250427_160535.webp_736&quot; alt=&quot;把音箱绑在了车上&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;04-28 6:55 AM 淮阳·龙湖新城&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;奶奶身体最近不太好，高血压住院了，所以骑行晚走了一天。&lt;/p&gt;
&lt;p&gt;这是我在淮阳的最后一顿早餐：胡辣汤、鸡蛋饼、两个鸡蛋。早上的蛋尤为重要，它决定了我今天能不能顺利完成骑行&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250428_054521.webp_736&quot; alt=&quot;在淮阳的最后一顿早餐&quot; /&gt;&lt;/p&gt;
&lt;p&gt;刚吃完早餐，习惯性的捏捏车胎，发现车胎气压不足，我当时就觉得不对劲，很大概率已经爆胎了。当我拿打气筒充气时，气嘴滋滋漏气，我当时就服了。这次行程我就备了一个管胎，这种胎很贵，没那么多资金支持我买一堆备胎，管胎这种轮胎和其他胎不一样，换胎要除胶贴胶费时费力，你要说补胎，我估计一般的小品牌技师都没摸过管胎，手头宽裕了，我一定要把这轮组先换了，它不支持管胎以外的其他胎型。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250428_062856.webp_736&quot; alt=&quot;换胎，重新贴胶&quot; /&gt;&lt;/p&gt;
&lt;p&gt;真是服了，啥好事都让我碰上了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1746593468052.webp_736&quot; alt=&quot;安装好了，最后抽条&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1746593420028.webp_736&quot; alt=&quot;准备出发&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;12:12 AM 安徽·阜阳·太和县&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;骑行105公里到达阜·太和县，途中遇到很多有意思的场景，就是没有拍照，天气实在太热了，骑行的过程中实在懒得下来拍照。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;0d0719f9_2_11zon.webp_736&quot; alt=&quot;在阜阳吃个午饭&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;18:02 PM 安徽·淮南·凤台县&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;骑行202公里到达淮南·凤台，吃个晚饭，点了一晚大肉水饺还有一份鸭腿，这点饭量对骑行时的我是完全不够的，她们家的绿豆汤是免费的，不稀比较稠，而且还是免费的，我连着吃了三碗...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;5d90f82a_1_11zon.webp_736&quot; alt=&quot;在淮南吃个晚饭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本来想着吃完饭继续骑，奈何自己看见宾馆走不动路，想想两天也到不了，不急这一会儿。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250428_185327.webp_736&quot; alt=&quot;淮南·凤台 御唐宫&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到了屋里第一时间扒个精光，实在太热了，热了干，干了湿，浑身都很黏，&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250428_190944.webp_736&quot; alt=&quot;这胳膊，熟悉的痛感&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;f6a5c53bb9d.webp&quot; alt=&quot;骑行 202.6 Km&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;04-29 6:55 AM 安徽·淮南·凤台县&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;早餐还是老三样，这次的粥我多加了糖，高糖分有助于我长途骑行&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;cd1fcc41c88d27c.webp_736&quot; alt=&quot;在凤台县的最后一顿早餐&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;11:12 AM 安徽·淮南·田家庵区&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;路过淮南市区买了5根香蕉，这天实在太热了，隔着手套都能感觉到香蕉是热的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1746592663559.webp_736&quot; alt=&quot;补个蕉&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;12:32 AM 安徽·合肥·长丰县&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个披萨是我吃过最难吃的，已经不能称为披萨了，速冻的薄饼加热了一下，这顿饭是在蜜雪冰城吃的，就为了只有他们店舍得在荒无人烟的地方开空调&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250429_123213.webp_736&quot; alt=&quot;吃个中午饭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当时看到这个场景真的很惊艳，一抹绿，在这里钓鱼露营一定很爽&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;62585b9f45a2c2f1e3aebf341.webp_736&quot; alt=&quot;一抹绿&quot; /&gt;&lt;/p&gt;
&lt;p&gt;太热了，找了阴凉地，坐在国道两波护栏歇会儿...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250429_144559.webp_736&quot; alt=&quot;歇会儿&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;6:46 AM 安徽·合肥·肥东县&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;绝了，即出发后第二次爆胎，当时天已经黑了，还好不是在荒郊野外爆的，不然我就要提前体验田野生活了，补救的可能性很小，因为管胎里面的管子炸了，管胎这种东西不用考虑当地施救的可能性，实体店不会有管胎卖，修更别说了，几乎失传的手艺。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;243fed6f4a2f1af0e52b61e98e37db3.webp_736&quot; alt=&quot;再次炸管胎，而且是后轮&quot; /&gt;&lt;/p&gt;
&lt;p&gt;也怪我，左转速度太快，正好有个坡度看不到这缝，后轮当场巨响爆了！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;3080f547aa691b449944ba0eab8.webp_736&quot; alt=&quot;就是在这里&quot; /&gt;&lt;/p&gt;
&lt;p&gt;爆胎后，我穿着锁鞋推行了两公里左右，找了一家宾馆住了下来，我也懒得检查哪漏气了，碳轮坏了没有，一切都不重要了，现在就想着咋带车去义乌，我没有车包，高铁肯定是上不了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;ffcf8e1eb9e.webp&quot; alt=&quot;刚骑行 176 Km 当场退役&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;04-30 8:09 AM 安徽·淮南·瑶海区&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;经费紧张，去义乌我也有规划着时间，等不起在网上买管胎的代价，由于没有装车包，公路车无法上高铁，托运怕出事。在网上找了一个义乌直达大巴车，可以放下面，车费200，行李房120砍到88，合计费用比高铁还贵。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;a97fc5e54f3c99c32efbc19ce1dc3a0.webp_736&quot; alt=&quot;打包滚蛋&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;11:32 AM 江苏·南京·江宁区&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;到饭店了，客运公司开始收割了，大巴车把车停到了他们据点，周围几公里都没有商店，饭堂和商店的物价堪比上海浦东机场，有些人早有准备自带了泡面，但是人家的热水专供司机，不让旅客用，笑了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;95046624bd6b0c84a79bde3b17d49ec.webp_736&quot; alt=&quot;客运公司开始收割&quot; /&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;3:16 PM 浙江·杭州·上城区·九堡大桥&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;看到这里差点掉小珍珠，之前在杭州上班时经常开车路过这里，Hi 杭州 好久不见。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250430_151655.webp_736&quot; alt=&quot;杭州·九堡大桥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;时隔六年，再次为热爱脱皮。痛苦如影随形，却也因此更加坚定&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2a1b525ee02.webp_736&quot; alt=&quot;晒伤脱皮的右臂&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2a1b525ee04.webp_736&quot; alt=&quot;晒伤脱皮的左臂&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2a1b525ee01.webp_736&quot; alt=&quot;黑白分明&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%80%E8%B7%AF%E5%90%91%E5%8D%97%EF%BC%8C%E9%AA%91%E8%A7%81%E6%B1%9F%E5%8D%97%EF%BC%9A%E4%B8%80%E4%BA%BA%E3%80%81%E4%B8%80%E8%BD%A6%E3%80%81%E4%B8%80%E6%97%85%E9%80%94&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-05-11-yilu-xiang-nan-qi-jian-jiang-nan&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>新手跑步第五次：单人挑战不间断半马</title><link>https://blog.lhasa.icu/posts/outdoors/2025-04-24-day4-day6-running-log</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-04-24-day4-day6-running-log</guid><pubDate>Thu, 24 Apr 2025 04:50:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;从跑步小白，到不间断半马需要多久？答案是六天，五次！&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Day 4：首次不间断 10 公里&lt;/h2&gt;
&lt;p&gt;2025年4月20日 · 跑步第四天。早上起床时心情很好，因为我发现大腿已经不疼了，想必是适应了十公里的运动量，我决定今天晚上下班后，开始挑战不间断十公里&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250423004421.webp_736&quot; alt=&quot;Day 4 · 小区在放电影·智取威虎山&quot; /&gt;&lt;/p&gt;
&lt;p&gt;晚上刚下班，我直接回家换了运动装，出了门正好看到篮球场在放电影《智取威虎山》，我喜欢露天电影的氛围，有空一定要去看一场&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504230044221.webp_736&quot; alt=&quot;Day 4 · 中原区·西流湖公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;从小区北门起跑，沿着郑上路一路向南，经过郑州市实验小学、第一中学等地标，最后在T字形路口到达西流湖公园北侧门，目前里程为4公里左右，这条路被我骑车压过不知道多少次了，可这次是跑步，带给我的感觉不一样&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504230044222.webp_736&quot; alt=&quot;Day 4 · 西流湖公园·外围下坡&quot; /&gt;&lt;/p&gt;
&lt;p&gt;进了公园右转是上坡，向左则为两条路可以选择：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;公园外围下坡，路面宽阔、路灯明亮&lt;/li&gt;
&lt;li&gt;岸边小道，下坡路况一般&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;20250423004423.webp_736&quot; alt=&quot;Day 4 · 西流湖公园·不知名桥亭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这个桥亭设计了很多座位，栏杆也不高，下面是贾鲁河的支流，还做了一个闸口的设计，水流从上面流下来，下面是人工池，形成一个小瀑布的效果，非常适合路亚、溪流钓，台钓佬就省省吧，只能大跑铅&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504230044231.webp_736&quot; alt=&quot;Day 4 · 西流湖公园·不知名桥亭&quot; /&gt;
``&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250423005205.webp&quot; alt=&quot;Day 4 · 完成不间断 10 公里&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;分段成绩&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Km&lt;/th&gt;
&lt;th&gt;配速&lt;/th&gt;
&lt;th&gt;海拔&lt;/th&gt;
&lt;th&gt;心率 (bpm)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5′41″&lt;/td&gt;
&lt;td&gt;−2 m&lt;/td&gt;
&lt;td&gt;167&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;6′29″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;174&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;6′57″&lt;/td&gt;
&lt;td&gt;+2 m&lt;/td&gt;
&lt;td&gt;169&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;7′54″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;161&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;8′08″&lt;/td&gt;
&lt;td&gt;−12 m&lt;/td&gt;
&lt;td&gt;162&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;7′35″&lt;/td&gt;
&lt;td&gt;+13 m&lt;/td&gt;
&lt;td&gt;168&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;6′58″&lt;/td&gt;
&lt;td&gt;−4 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;7′07″&lt;/td&gt;
&lt;td&gt;+1 m&lt;/td&gt;
&lt;td&gt;166&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;6′47″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;173&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;6′42″&lt;/td&gt;
&lt;td&gt;+2 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.1&lt;/td&gt;
&lt;td&gt;6′05″&lt;/td&gt;
&lt;td&gt;−1 m&lt;/td&gt;
&lt;td&gt;175&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;10 km 综合数据&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;数值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;距离&lt;/td&gt;
&lt;td&gt;10.14 km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均配速&lt;/td&gt;
&lt;td&gt;7′01″ / km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最快分段&lt;/td&gt;
&lt;td&gt;5′41″ / km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均经过配速&lt;/td&gt;
&lt;td&gt;7′05″ / km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;移动时间&lt;/td&gt;
&lt;td&gt;1 h 11′ 08″&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全程耗时&lt;/td&gt;
&lt;td&gt;1 h 11′ 47″&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均心率&lt;/td&gt;
&lt;td&gt;168 bpm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;爬升&lt;/td&gt;
&lt;td&gt;35 m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;消耗卡路里&lt;/td&gt;
&lt;td&gt;643 kcal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;Day 6：新手跑步第五次，单人 挑战 不间断 半马！&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;2025年4月22日 · 跑步第六天 · 第五次&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今天我，昨天晚上忙着搬家没有跑步，处于内心的愧疚，我决定今天晚上把昨天的补回来，在跑之前我还不知道半马是什么意思&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504230038393.webp_736&quot; alt=&quot;Day 6 · 半马·五公里记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;像往常一样，再次来到西流湖，里程来到了五公里，这段距离的心率有些高，心率区间在165-180，往后的数据都没有这个高&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504230038412.webp_736&quot; alt=&quot;Day 6 · 半马·十公里记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;饮水没控制住，已经喝了550ml，当时非常兴奋，因为我即将跑返程了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250423003840.webp_736&quot; alt=&quot;Day 6 · 半马·十五公里记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;跑到这里时，体力消耗的差不多了，双腿感觉十分僵硬，停一秒钟感觉都会导致后面跑步下去&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250423003451.webp&quot; alt=&quot;Day 6 · 半马·记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到小区门口了，我感到非常兴奋，因为我即将完成我的第一次半马挑战，而且是不间断，除了中途买水，期间几乎没有停过&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504230052051.webp&quot; alt=&quot;Day 6 · 半马·记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250423003452.webp_736&quot; alt=&quot;Day 6 · 魔镜魔镜谁是最持久男人&quot; /&gt;&lt;/p&gt;
&lt;p&gt;跑完站在家里，小腿和大腿没有疼痛感，唯一不舒服的就是双腿的膝盖关节处，活动就会有些疼痛&lt;/p&gt;
&lt;h3&gt;半马·分段成绩&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Km&lt;/th&gt;
&lt;th&gt;配速&lt;/th&gt;
&lt;th&gt;海拔&lt;/th&gt;
&lt;th&gt;心率 (bpm)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;5′24″&lt;/td&gt;
&lt;td&gt;−1 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;5′51″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;178&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;6′23″&lt;/td&gt;
&lt;td&gt;+3 m&lt;/td&gt;
&lt;td&gt;180&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;6′40″&lt;/td&gt;
&lt;td&gt;−2 m&lt;/td&gt;
&lt;td&gt;177&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;7′45″&lt;/td&gt;
&lt;td&gt;−12 m&lt;/td&gt;
&lt;td&gt;165&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;8′28″&lt;/td&gt;
&lt;td&gt;+8 m&lt;/td&gt;
&lt;td&gt;161&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;7′52″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;162&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;7′28″&lt;/td&gt;
&lt;td&gt;+1 m&lt;/td&gt;
&lt;td&gt;164&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;6′52″&lt;/td&gt;
&lt;td&gt;−3 m&lt;/td&gt;
&lt;td&gt;171&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;7′21″&lt;/td&gt;
&lt;td&gt;−8 m&lt;/td&gt;
&lt;td&gt;166&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;8′46″&lt;/td&gt;
&lt;td&gt;−3 m&lt;/td&gt;
&lt;td&gt;158&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;7′04″&lt;/td&gt;
&lt;td&gt;−1 m&lt;/td&gt;
&lt;td&gt;171&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;8′13″&lt;/td&gt;
&lt;td&gt;+1 m&lt;/td&gt;
&lt;td&gt;164&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;7′11″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;7′17″&lt;/td&gt;
&lt;td&gt;+1 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;16&lt;/td&gt;
&lt;td&gt;7′43″&lt;/td&gt;
&lt;td&gt;+10 m&lt;/td&gt;
&lt;td&gt;167&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;17&lt;/td&gt;
&lt;td&gt;7′28″&lt;/td&gt;
&lt;td&gt;+2 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;td&gt;7′26″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;td&gt;7′22″&lt;/td&gt;
&lt;td&gt;−1 m&lt;/td&gt;
&lt;td&gt;170&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;7′37″&lt;/td&gt;
&lt;td&gt;+2 m&lt;/td&gt;
&lt;td&gt;167&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;21&lt;/td&gt;
&lt;td&gt;7′37″&lt;/td&gt;
&lt;td&gt;+2 m&lt;/td&gt;
&lt;td&gt;166&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;td&gt;7′02″&lt;/td&gt;
&lt;td&gt;0 m&lt;/td&gt;
&lt;td&gt;172&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.9&lt;/td&gt;
&lt;td&gt;6′34″&lt;/td&gt;
&lt;td&gt;+1 m&lt;/td&gt;
&lt;td&gt;176&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2&gt;半马 · 数据一览&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;指标&lt;/th&gt;
&lt;th&gt;数值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;距离&lt;/td&gt;
&lt;td&gt;22.96 km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均配速&lt;/td&gt;
&lt;td&gt;7′17″ / km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;最快分段&lt;/td&gt;
&lt;td&gt;5′24″ / km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均经过配速&lt;/td&gt;
&lt;td&gt;7′18″ / km&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;移动时间&lt;/td&gt;
&lt;td&gt;2 h 47′ 07″&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;全程耗时&lt;/td&gt;
&lt;td&gt;2 h 47′ 28″&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;平均心率&lt;/td&gt;
&lt;td&gt;169 bpm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;爬升&lt;/td&gt;
&lt;td&gt;69 m&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;消耗卡路里&lt;/td&gt;
&lt;td&gt;1450 kcal&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;img src=&quot;20250423003453.webp_736&quot; alt=&quot;Day 6 · 标签&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到家准备脱裤子时才发现，我中午买的第一条跑步用的紧身裤标签还没摘，现在已经被汗水浸湿烂掉了，让我有种破茧的感觉&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%96%B0%E6%89%8B%E8%B7%91%E6%AD%A5%E7%AC%AC%E4%BA%94%E6%AC%A1%EF%BC%9A%E5%8D%95%E4%BA%BA%E6%8C%91%E6%88%98%E4%B8%8D%E9%97%B4%E6%96%AD%E5%8D%8A%E9%A9%AC&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-04-24-day4-day6-running-log&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>记录我的前3次跑步：从陪跑到主动出发</title><link>https://blog.lhasa.icu/posts/outdoors/2025-04-20-day1-day3-running-log</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-04-20-day1-day3-running-log</guid><pubDate>Sun, 20 Apr 2025 07:25:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;从讨厌到上瘾，原来跑步也能这样有趣.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我一直是个不爱运动的人，尤其讨厌跑步。打小起，我对跑步总是敬而远之&lt;/p&gt;
&lt;p&gt;这次之所以开始跑步，完全是被阿坤和阿丽带动的&lt;/p&gt;
&lt;p&gt;起初只是想着陪他们减肥，没想到，从第三天开始，我居然有点跑上瘾了&lt;/p&gt;
&lt;h2&gt;Day 1：人生第一次 5 公里（其实只跑了 3 公里）&lt;/h2&gt;
&lt;p&gt;第一次跑步是阿坤叫我的，他想减肥，我就陪他出来遛弯。他说目标是 5 公里，结果我们大半时间都在走路，实际上只跑了 3 公里&lt;/p&gt;
&lt;p&gt;他有点胖，体力跟不上，但我直到活动结束都没有什么感觉&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250419233911.webp&quot; alt=&quot;Day 1 · 没有什么感觉&quot; /&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;跑步 Day 2：不间断 5 公里初体验&lt;/h2&gt;
&lt;p&gt;第二天我刚下晚班（19:00），我打电话问阿坤什么时候出发，他说八点半。我不想等太久，就先回家收拾一下便出门了&lt;/p&gt;
&lt;p&gt;第一天穿板鞋和牛仔裤实在太难受，这次吸取了教训，只穿了短裤、速干背心和跑鞋&lt;/p&gt;
&lt;p&gt;站在小区门口花两分钟热热身，把软件都打开便开始跑了&lt;/p&gt;
&lt;p&gt;刚开始跑到 0.86 公里 时，心率就达到了 183，但呼吸还算平稳&lt;/p&gt;
&lt;p&gt;跑到 2 公里时，心率稳定在 168–170，最终顺利完成不间断五公里，一点都不觉得累，只是非常口渴&lt;/p&gt;
&lt;p&gt;跑完后在楼下买了瓶水，还给阿坤发了个微信。结果瓶盖还都没拧开，就下起了暴雨，就像是天上开了个花洒一样，很突然...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250419232849.webp_736&quot; alt=&quot;Day 2 · 不间断 5 公里，暴雨突降&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250419233913.webp&quot; alt=&quot;Day 2 · 首次不间断 5 公里&quot; /&gt;&lt;/p&gt;
&lt;p&gt;阿坤因为下雨就没出门，我们在老地方随便吃了点东西聊聊天。准备回家时，我才发现自己腿已经快站不直了，大腿疼得厉害&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;跑步 Day 3：加码挑战，十公里！&lt;/h2&gt;
&lt;p&gt;早上起床，大腿肌肉酸痛，走路都不太舒服，走路都一瘸一拐的，就像当初刚学骑自行车一样，这种酸爽的痛感，反倒让我有点兴奋&lt;/p&gt;
&lt;p&gt;出门碰头时，阿坤说想骑我的自行车，我说你骑吧，我跑步&lt;/p&gt;
&lt;p&gt;相比昨天，今天的心率平稳多了，基本维持在 150–160。跑到 6.59 公里时，心率才到 181，那一刻我只觉得跑步，真的爽！掌握节奏之后，压根不想停下来！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250419232850.webp_736&quot; alt=&quot;Day 3 · 徐佳莹在奥体开演唱会&quot; /&gt;&lt;/p&gt;
&lt;p&gt;跑着跑着来到奥体，正好赶上徐佳莹的演唱会。场外摆摊的特别多，还有个露天KTV，这种我是第一回次见，他们的声音是真大，我在 2 公里外就听见了，没一会儿，三四个保安冲过来大喊：“里面在开演唱会呢！”结果一个大妈拿着话筒回了一句：“演唱会咋了，演唱会咋了！” 笑死我了&lt;/p&gt;
&lt;p&gt;之后我们绕着奥体转了一圈，发现个室外健身区，有很多器械，比如健身单车，还支持联网进行在线竞赛，而且运动数据可同步app，最重要的是全部免费！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250419232854.webp_736&quot; alt=&quot;Day 3 · 阿坤骑着我的自行车&quot; /&gt;&lt;/p&gt;
&lt;p&gt;返程时演唱会刚结束，整个奥体路被堵得水泄不通，到处是人和出租车&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202504192339131.webp&quot; alt=&quot;Day 3 · 首次十公里&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其实，今天的十公里多少有些违心，因为我实际只跑了 8.25 公里，剩下的两公里是骑车，阿坤说骑不动了，让我骑车，他跑着...&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%AE%B0%E5%BD%95%E6%88%91%E7%9A%84%E5%89%8D3%E6%AC%A1%E8%B7%91%E6%AD%A5%EF%BC%9A%E4%BB%8E%E9%99%AA%E8%B7%91%E5%88%B0%E4%B8%BB%E5%8A%A8%E5%87%BA%E5%8F%91&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-04-20-day1-day3-running-log&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Strava Riding Api 上线</title><link>https://blog.lhasa.icu/posts/technology/2025-04-10-stravaridingapi</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-04-10-stravaridingapi</guid><pubDate>Wed, 09 Apr 2025 16:23:00 GMT</pubDate><content:encoded>&lt;p&gt;该脚本基于 Strava API v3 获取指定用户当年的所有骑行活动数据，并将其保存为JSON格式&lt;/p&gt;
&lt;h2&gt;功能特性&lt;/h2&gt;
&lt;p&gt;Strava Riding Api 只实现了 OAuth 2.0 授权流程的部分自动化，由于技术限制，目前无法实现完全自动化：&lt;/p&gt;
&lt;p&gt;已实现部分&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;半自动 OAuth 2.0 授权流程，轻松访问您的 Strava 数据&lt;/li&gt;
&lt;li&gt;自动获取任意年份的所有骑行记录&lt;/li&gt;
&lt;li&gt;获取每个活动的完整运动数据&lt;/li&gt;
&lt;li&gt;智能令牌管理：自动保存和刷新过期的访问令牌&lt;/li&gt;
&lt;li&gt;数据自动转换：公里、时间、速度单位等数据格式化&lt;/li&gt;
&lt;li&gt;内置多重容错机制，确保数据获取的可靠性&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;使用前设置&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;重要：&lt;/strong&gt; 在使用此脚本前，请确保在Strava开发者平台上正确配置您的应用：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;访问 &lt;a href=&quot;https://www.strava.com/settings/api&quot;&gt;Strava开发者设置&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;将以下URL添加到&quot;授权回调域&quot;：&lt;pre&gt;&lt;code&gt;localhost
&lt;/code&gt;&lt;/pre&gt;
注意：只需输入 &lt;code&gt;localhost&lt;/code&gt; 而不是完整的 &lt;code&gt;http://localhost:8000&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;保存设置&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;使用方法&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;安装依赖：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn install
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获取并处理授权码：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn auth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;获取授权后，您会收到一个授权码。将其粘贴到命令行中。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;获取骑行数据：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn start
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;查看输出的JSON文件，文件名格式为：&lt;code&gt;strava_data.json&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;解决认证问题&lt;/h2&gt;
&lt;p&gt;如果您遇到API相关错误，请尝试以下解决方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;更新令牌&lt;/strong&gt;：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn auth
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;重新获取授权并更新令牌&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;检查API状态&lt;/strong&gt;：&lt;/p&gt;
&lt;p&gt;访问 &lt;a href=&quot;https://status.strava.com/&quot;&gt;Strava API状态&lt;/a&gt; 确认服务是否正常&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;常见问题解决&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;&quot;protocol mismatch&quot;错误&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;此问题已在最新版本中解决，使用了原生HTTPS模块发送请求&lt;/li&gt;
&lt;li&gt;确保在Strava开发者设置中添加了&lt;code&gt;localhost&lt;/code&gt;作为授权回调域
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;无法获取活动数据&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;确认您的账户中确实有骑行活动&lt;/li&gt;
&lt;li&gt;检查筛选条件是否正确（默认只获取&quot;Ride&quot;类型活动）
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;API错误或限流&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strava API有使用限制(每15分钟100次，每天1000次)&lt;/li&gt;
&lt;li&gt;数据量大时，脚本已添加延迟以避免触发限流&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;许可证&lt;/h2&gt;
&lt;p&gt;本项目采用 Mozilla 公共许可证 2.0 版发布&lt;/p&gt;
&lt;p&gt;Strava API v3：https://developers.strava.com/docs/reference&lt;/p&gt;
&lt;p&gt;Strava Riding Api：https://github.com/achuanya/Strava-Riding-Api&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Strava%20Riding%20Api%20%E4%B8%8A%E7%BA%BF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-04-10-stravaridingapi&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>EasyFill 发布了</title><link>https://blog.lhasa.icu/posts/technology/2025-04-07-easyfill</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-04-07-easyfill</guid><pubDate>Mon, 07 Apr 2025 12:38:00 GMT</pubDate><content:encoded>&lt;p&gt;就在刚刚 EasyFill 终于通过了 Chrome Web Store 的审核，正式发布了！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;chromewebstore1.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h2&gt;功能特性&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;智能填充&lt;/strong&gt;：DOM 加载完后，自动读取表单插入数据。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;无缝集成&lt;/strong&gt;：与主流博客平台和评论系统兼容。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;数据加密&lt;/strong&gt;：通过 AES-GCM 加密和解密功能，保护用户数据安全。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;现代化界面&lt;/strong&gt;：基于 Material-UI 和 React 提供用户友好的界面。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;打开 Chrome Web Store&lt;/li&gt;
&lt;li&gt;搜索 &lt;code&gt;EasyFill&lt;/code&gt;。&lt;/li&gt;
&lt;li&gt;点击 &lt;strong&gt;添加到浏览器&lt;/strong&gt; 按钮完成安装。&lt;/li&gt;
&lt;li&gt;安装完成后，浏览器工具栏会显示 EasyFill 图标。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;更新日志&lt;/h2&gt;
&lt;p&gt;查看 &lt;a href=&quot;https://github.com/achuanya/EasyFill/blob/main/public/markdowns/UpdateLog.md&quot;&gt;更新日志&lt;/a&gt; 了解最新功能和修复。&lt;/p&gt;
&lt;h2&gt;问题反馈&lt;/h2&gt;
&lt;p&gt;如果你在使用过程中遇到问题，请在我的博客&lt;a href=&quot;https://lhasa.icu/guestbook.html&quot;&gt;留言&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;支持作者&lt;/h2&gt;
&lt;p&gt;感谢您对我的支持，本人非程序员，忙里抽闲，为爱发电。&lt;/p&gt;
&lt;p&gt;如果您觉得 EasyFill 对您有帮助，可以通过以下方式支持我继续创作：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;appreciation-code.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h2&gt;许可证&lt;/h2&gt;
&lt;p&gt;本项目基于 &lt;a href=&quot;https://github.com/achuanya/EasyFill/blob/main/LICENSE&quot;&gt;Mozilla Public License Version 2.0&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;Github 仓库：https://github.com/achuanya/EasyFill&lt;/p&gt;
&lt;p&gt;✨ EasyFill 只为向那些在浮躁时代，依然坚守独立博客精神的你们致敬！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=EasyFill%20%E5%8F%91%E5%B8%83%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-04-07-easyfill&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>产品被拒</title><link>https://blog.lhasa.icu/posts/technology/2025-04-03-theproductwasrejected</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-04-03-theproductwasrejected</guid><pubDate>Wed, 02 Apr 2025 16:05:00 GMT</pubDate><content:encoded>&lt;p&gt;晚上下了班打开电脑刚坐下就看到了一封 Google 邮件，首先看到了发件人 &quot;Chrome Web Store&quot;，当时就心想提交审核一个多星期了，终于看到一点音信了。点开后，还没等我高兴，便看到了：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;easyfillrejectionnotice.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h2&gt;解决BUG&lt;/h2&gt;
&lt;p&gt;被拒的原因非常低级，声明了但未使用的 &lt;code&gt;scripting&lt;/code&gt; 权限。&lt;/p&gt;
&lt;p&gt;scripting 权限是 Manifest V3 中引入的一个重要权限，主要用于动态脚本执行&lt;code&gt;chrome.scripting.executeScript()&lt;/code&gt;和动态样式注入&lt;code&gt;chrome.scripting.insertCSS()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;而在&lt;code&gt;EasyFill&lt;/code&gt;中，使用的是静态声明：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;content_scripts: [
  {
    matches: [&quot;&amp;lt;all_urls&amp;gt;&quot;],
    js: [&quot;content-scripts/content.js&quot;],
  },
];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除&lt;code&gt;scripting&lt;/code&gt;参数后，重新打包并再次向 Chrome Web Store 提交了扩展。&lt;/p&gt;
&lt;p&gt;就这么一个小BUG，浪费了我一个星期的审核时间，太耽误事了，当时为了解决 Shadow DOM 才使用 scripting，直到现在这个问题也没有解决，希望下个版本可以解决问题&lt;/p&gt;
&lt;p&gt;产品谍照：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;myinformation.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BA%A7%E5%93%81%E8%A2%AB%E6%8B%92&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-04-03-theproductwasrejected&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>注册 Chrome Web Store 开发者</title><link>https://blog.lhasa.icu/posts/technology/2025-03-20-registering-as-a-chrome-web-store-developer</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-03-20-registering-as-a-chrome-web-store-developer</guid><pubDate>Wed, 19 Mar 2025 16:03:00 GMT</pubDate><content:encoded>&lt;p&gt;年前曾尝试过 Chrome 扩展开发，《写一个Chrome表单自动化插件》，但是由于没有注册 Chrome Web Store 开发者，无法上传到 Chrome 应用商店。&lt;/p&gt;
&lt;h2&gt;注册 WildCard&lt;/h2&gt;
&lt;p&gt;Chrome 注册开发者需要五美元，由于我没有境外信用卡就一直卡在这，2022 年我在杭州办过一张中信的双币卡，年费很高，后来经济紧张时注销了，现在急着用外币还挺麻烦，折腾一圈，最终无脑选择了 WildCard，尽管网上对它负面评论铺天盖地。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250319214114.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;[WildCard][p3] 开卡费用是 10.99 美元/年，实际付款 79.71 人民币，按照今天的市场汇率 7.23，实际多付了 0.24，而且这只是开卡费用，充值另算。&lt;/p&gt;
&lt;p&gt;开卡后我充值了 10 美元，支付宝付款 75.07，到账金额 10 美元：&lt;/p&gt;
&lt;p&gt;$$
\frac{2.77}{75.07} \times 100% \approx 3.69%
$$&lt;/p&gt;
&lt;p&gt;四个点我能接受（接不接受都要受着），这个开卡费不便宜，毕竟钱不是大风刮来的，所以注册时，我创建了两个号，推荐注册返现两美金...&lt;/p&gt;
&lt;h2&gt;注册 Chrome Web Store 开发者&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20250319225638.webp&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;注册账号就很容易了，Google 绑卡付钱就行。但是如果要销售发布就很麻烦：&lt;/p&gt;
&lt;h2&gt;个人交易者声明&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;您需要提供一个手机号码以验证是您本人在操作
&lt;ul&gt;
&lt;li&gt;您将通过手机接收代码&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;用于证明是您本人的身份证件&lt;/li&gt;
&lt;li&gt;可接受的文件包括：
&lt;ul&gt;
&lt;li&gt;驾照&lt;/li&gt;
&lt;li&gt;护照&lt;/li&gt;
&lt;li&gt;州身份证明&lt;/li&gt;
&lt;li&gt;绿卡&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;您需要提供一份显示您的姓名和当前地址的文件&lt;/li&gt;
&lt;li&gt;可接受的文件包括：
&lt;ul&gt;
&lt;li&gt;由政府签发的文件或带照片的身份证件&lt;/li&gt;
&lt;li&gt;公共事业缴费单或话费账单（日期在过去 60 天内）&lt;/li&gt;
&lt;li&gt;银行对账单（日期在过去 60 天内）&lt;/li&gt;
&lt;li&gt;租赁合同或抵押贷款合同&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因为 Google 已退出中国市场，不支持交易。而我是美国 Visa 卡，面对这样的要求不容易做到。&lt;/p&gt;
&lt;p&gt;日后再说吧，往后这段时间，我打算把博客评论表单自动填充插件重构一下，然后上架 Chrome 应用商店。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%B3%A8%E5%86%8C%20Chrome%20Web%20Store%20%E5%BC%80%E5%8F%91%E8%80%85&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-03-20-registering-as-a-chrome-web-store-developer&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>空腹骑行75公里</title><link>https://blog.lhasa.icu/posts/outdoors/2025-03-12-cycling75kilometersonanemptystomach</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-03-12-cycling75kilometersonanemptystomach</guid><pubDate>Wed, 12 Mar 2025 07:36:00 GMT</pubDate><content:encoded>&lt;h2&gt;周六&lt;/h2&gt;
&lt;p&gt;最近郑州天气突然转冷，骑行频率也降了下来，周六正好赶上休息，实在是憋坏了！今天不管刮风下雨，必须出去骑一趟&lt;/p&gt;
&lt;p&gt;原计划直接奔开封，结果路过龙湖就停了下来。好久没来了，上次来还是鹅毛大雪天，如今雪没了，只剩下鹅&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250312092725.jpg_736&quot; alt=&quot;倒挂白鹅&quot; /&gt;&lt;/p&gt;
&lt;p&gt;周六的公园人满为患，没法骑。我推着车沿湖边缓行，遥望着远处炸水的不知名鱼，不由自主的想蹲下摸摸湖水，真的很想钓鱼，自到郑州以来，我连最爱的路亚竿都没摸过&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927251.jpg_736&quot; alt=&quot;龙湖·北岸&quot; /&gt;&lt;/p&gt;
&lt;p&gt;此时正值中午，小孩在沙滩上牵着风筝奔跑，大人排队买小吃，顿时勾起了不少儿时回忆，我也好想光着脚奔跑在沙滩上...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250312092724.jpg_736&quot; alt=&quot;龙湖·人工沙滩&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在龙湖公园出来后，我关掉了导航线瞎跑，根本不认识路，不知道自己在哪，扫大街呗&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927241.jpg&quot; alt=&quot;STRAVA 74.6km  爬升313m  时间4h 19m&quot; /&gt;&lt;/p&gt;
&lt;p&gt;话说现在骑车很少拍照，不是不爱拍，而是懒得下车，即使趴到腰酸，感觉腰快要断了，也不想停下来&lt;/p&gt;
&lt;h2&gt;周日&lt;/h2&gt;
&lt;p&gt;拍这张照片时，已经快饿晕了，周六晚上吃得少，周日早上又空腹出门，体力消耗得厉害...&lt;/p&gt;
&lt;p&gt;周日早晨睡到自然醒，一看表，我整个人都快立正了，居然八点半了。着急忙慌洗漱后，脱下内衣裤直接换上骑行服，背上包，拿了五块巧克力出发了。因为周一要上班，所以今天必须放纵一下，出发前大致算了算，来回返程再加上逛街的时间，早饭根本来不及吃...哎...&lt;/p&gt;
&lt;p&gt;大约骑了25公里，在中石化买了瓶宝矿力水特。又骑行了二三十公里到了贾鲁河桥，饿的没劲，更别说爬坡了，挂上小盘，我慢悠悠到了桥中间，休息了几分钟，把五块巧克力补给全吃了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927242.jpg_736&quot; alt=&quot;郑州·贾鲁河桥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;就这样空腹骑到了开封郊区，此时的里程已经来到了 75.38公里，用时3小时23分钟&lt;/p&gt;
&lt;p&gt;到达开封后，心里那股坚持的信念瞬间消失了，又渴又饿，高德帮我找了最近一家名为三不炒(开封总店)的小炒店，我把车子靠着门店随便一放，就去买葡萄糖了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927243.jpg_736&quot; alt=&quot;就去买葡萄糖了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;买完水出来发现要排队，人还不少，我是真的饿得快走不动了，但还是懒得换地方，抱着水坐在外面等了半小时。饿得快虚脱了，感觉此时此刻，就算把馒头挂我脖子上都能饿死&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927244.jpg_736&quot; alt=&quot;我前面排了八个人&quot; /&gt;&lt;/p&gt;
&lt;p&gt;排队加吃饭花了一个半小时，吃得太撑，骑上车都趴不下去，推着车穿过老巷子走到了湖边&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927245.jpg_736&quot; alt=&quot;对面就是清明上河园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250312092723.jpg_736&quot; alt=&quot;御河桥洞下&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927231.jpg_736&quot; alt=&quot;御河桥洞下&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202503120927232.jpg_736&quot; alt=&quot;正在乐钓的五星开封好市民&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250312092722.jpg&quot; alt=&quot;STRAVA 164.1km  爬升417m  时间8h 5m&quot; /&gt;&lt;/p&gt;
&lt;p&gt;回到家已经八点半了，这条郑开大道路线真心推荐，毕竟二刷了，虽然沿途风景平平，但对于郑州来说，已经是顶级骑行路线了，一个人骑行在郑开大道，握着下把位，不用担心刹车，不用担心前方有没有人，听着歌，摇着车，也不枉来郑州走一遭&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%A9%BA%E8%85%B9%E9%AA%91%E8%A1%8C75%E5%85%AC%E9%87%8C&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-03-12-cycling75kilometersonanemptystomach&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>利用 Go + COS + GitHub 重构 RSS 爬虫</title><link>https://blog.lhasa.icu/posts/technology/2025-03-20-reconstructthelhasarssproject</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-03-20-reconstructthelhasarssproject</guid><pubDate>Tue, 11 Mar 2025 19:26:00 GMT</pubDate><content:encoded>&lt;p&gt;之前我写过一篇&lt;a href=&quot;https://lhasa.icu/GrabLatestRSS.html&quot;&gt;《利用Go+Github Actions写个定时RSS爬虫》&lt;/a&gt;来实现这一目的，主要是用 GitHub Actions + Go 进行持续的 RSS 拉取，再把结果上传到 GitHub Pages 站点&lt;/p&gt;
&lt;p&gt;但是遇到一些网络延迟、TLS 超时问题，导致订阅页面访问速度奇慢，抓取的数据也不完整，后来时断时续半个月重构了代码，进一步增强了并发和容错机制&lt;/p&gt;
&lt;p&gt;在此感谢 GPT o1 给予的帮助，我已经脱离老本行很多年了，重构的压力真不小，有空就利用下班的时间进行调试，在今天凌晨 03:00 我终于写完了&lt;/p&gt;
&lt;h1&gt;1. 为什么要重构&lt;/h1&gt;
&lt;p&gt;旧版本主要基于 GitHub Actions 的定时触发，抓取完后把结果存放进 _data/rss_data.json 然后 Jekyll 就可以直接引用这个文件来展示订阅，但是这个方案有诸多不足:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;网络不稳定导致的抓取失败&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;由于原先的重试机制不够完善，GitHub Actions 在国外，RSS 站点大多在国内，一旦连接超时就挂，一些 RSS 无法成功抓取&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;单线程串行，速度偏慢&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;旧版本一次只能串行抓取 RSS，效率低，数量稍多就拉长整体执行时间，再加上外网到内地的延时，更显迟缓&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志不够完善&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;出错时写到的日志文件只有大概的错误描述，无法区分是解析失败、头像链接失效还是RSS本身问题，排查不便&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;访问速度影响大&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这是主要的重构原因！在旧版本里，抓取后的 JSON 数据是要存储到 Github 仓库的，虽然有 CDN 加持，但 GitHub Pages 的定时任务会引起连锁反应，当新内容刷新时容易出现访问延迟，极端情况下网页都挂了&lt;/p&gt;
&lt;p&gt;重构后，在此基础上进行了大幅重构，引入了并发抓取 + 指数退避重试 + GitHub/COS 双端存储的能力，抓取稳定性和页面访问速度都得到显著提升&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;2. 主要思路&lt;/h1&gt;
&lt;h2&gt;2.1 整体流程&lt;/h2&gt;
&lt;p&gt;先看个简单的流程图&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;        +--------------------------+
        | 1. 读取RSS列表（双端可选）  |
        +------------+-------------+
                     |
                     v
           +---------------------+
           | 2. 并发抓取RSS,限流   |
           |  (max concurrency)  |
           +-------+-------------+
                   |
                   v
        +------------------------------+
        | 3. 指数退避算法 (重试解析失败)  |
        +------------------------------+
                   |
                   v
           +-------------------+
           | 4. 结果整合排序    |
           +--------+----------+
                    |
                    v
        +-------------------------+
        | 5. 上传 RSS (双端可选)   |
        +-------------------------+
                    |
                    v
           +--------------------+
           | 6. 写日志到GitHub   |
           +--------------------+
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;并发抓取 + 限流&lt;/strong&gt;&lt;br /&gt;
通过 Go 的 goroutine 并发抓取 RSS，同时用一个 channel 来限制最大并发数&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;指数退避重试&lt;/strong&gt;&lt;br /&gt;
每个 RSS 如果第一次抓取失败，则会间隔几秒后再次重试，且间隔呈指数级递增（1s -&amp;gt; 2s -&amp;gt; 4s），最多重试三次，极大提高成功率&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;灵活存储&lt;/strong&gt;&lt;br /&gt;
RSS_SOURCE: 可以决定从 COS 读取一个远程 txt 文件（里面存放 RSS 列表），或直接从 GitHub 的 data/rss.txt 读取&amp;lt;br/&amp;gt;
SAVE_TARGET: 可以把抓取结果上传到 GitHub，或者传到腾讯云 COS&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志自动清理&lt;/strong&gt;&lt;br /&gt;
每次成功写入日志后，会检查 logs/ 目录下的日志文件，若超过 7 天就自动删除，避免日志越积越多&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;2.2 指数退避&lt;/h2&gt;
&lt;p&gt;上一次写指数退避，还是在养老院写PHP的时候，时过境迁啊，这段算法我调试了很久，其实不难，也就是说失败一次，就等待更长的时间再重试，配置如下:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;最大重试次数: 3&lt;/li&gt;
&lt;li&gt;初始等待: 1秒&lt;/li&gt;
&lt;li&gt;等待倍数: 2.0&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说失败一次就加倍等待，下次若依然失败就再加倍，如果三次都失败则放弃处理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// fetchAllFeeds 并发抓取所有RSS链接，返回抓取结果及统计信息
//
// Description:
//
//   该函数读取传入的所有RSS链接，使用10路并发进行抓取
//   在抓取过程中对解析失败、内容为空等情况进行统计
//   若抓取的RSS头像缺失或无法访问，将替换为默认头像
//
// Parameters:
//   - ctx           : 上下文，用于控制网络请求的取消或超时
//   - rssLinks      : RSS链接的字符串切片，每个链接代表一个RSS源
//   - defaultAvatar : 备用头像地址，在抓取头像失败或不可用时使用
//
// Returns:
//   - []feedResult         : 每个RSS链接抓取的结果（包含成功的Feed及其文章或错误信息）
//   - map[string][]string  : 各种问题的统计记录（解析失败、内容为空、头像缺失、头像不可用）
func fetchAllFeeds(ctx context.Context, rssLinks []string, defaultAvatar string) ([]feedResult, map[string][]string) {
	// 设置最大并发量，以信道（channel）信号量的方式控制
	maxGoroutines := 10
	sem := make(chan struct{}, maxGoroutines)

	// 等待组，用来等待所有goroutine执行完毕
	var wg sync.WaitGroup

	resultChan := make(chan feedResult, len(rssLinks)) // 用于收集抓取结果的通道
	fp := gofeed.NewParser()                           // RSS解析器实例

	// 遍历所有RSS链接，为每个RSS链接开启一个goroutine进行抓取
	for _, link := range rssLinks {
		link = strings.TrimSpace(link)
		if link == &quot;&quot; {
			continue
		}
		wg.Add(1)         // 每开启一个goroutine，对应Add(1)
		sem &amp;lt;- struct{}{} // 向sem发送一个空结构体，表示占用了一个并发槽

		// 开启协程
		go func(rssLink string) {
			defer wg.Done()          // 协程结束时Done
			defer func() { &amp;lt;-sem }() // 函数结束时释放一个并发槽

			var fr feedResult
			fr.FeedLink = rssLink

			// 抓取RSS Feed, 无法解析时，使用指数退避算法进行重试, 有3次重试, 初始1s, 倍数2.0
			feed, err := fetchFeedWithRetry(rssLink, fp, 3, 1*time.Second, 2.0)
			if err != nil {
				fr.Err = wrapErrorf(err, &quot;解析RSS失败: %s&quot;, rssLink)
				resultChan &amp;lt;- fr
				return
			}

			if feed == nil || len(feed.Items) == 0 {
				fr.Err = wrapErrorf(fmt.Errorf(&quot;该订阅没有内容&quot;), &quot;RSS为空: %s&quot;, rssLink)
				resultChan &amp;lt;- fr
				return
			}

			// 获取RSS的头像信息（若RSS自带头像则用RSS的，否则尝试从博客主页解析）
			avatarURL := getFeedAvatarURL(feed)
			fr.Article = &amp;amp;Article{
				BlogName: feed.Title,
			}

			// 检查头像可用性
			if avatarURL == &quot;&quot; {
				// 若头像链接为空，则标记为空字符串
				fr.Article.Avatar = &quot;&quot;
			} else {
				ok, _ := checkURLAvailable(avatarURL)
				if !ok {
					fr.Article.Avatar = &quot;BROKEN&quot; // 无法访问，暂记为BROKEN
				} else {
					fr.Article.Avatar = avatarURL // 正常可访问则记录真实URL
				}
			}

			// 只取最新一篇文章作为结果
			latest := feed.Items[0]
			fr.Article.Title = latest.Title
			fr.Article.Link = latest.Link

			// 解析发布时间，如果 RSS 解析器本身给出了 PublishedParsed 直接用，否则尝试解析 Published 字符串
			pubTime := time.Now()
			if latest.PublishedParsed != nil {
				pubTime = *latest.PublishedParsed
			} else if latest.Published != &quot;&quot; {
				if t, e := parseTime(latest.Published); e == nil {
					pubTime = t
				}
			}
			fr.ParsedTime = pubTime
			fr.Article.Published = pubTime.Format(&quot;02 Jan 2006&quot;)

			resultChan &amp;lt;- fr
		}(link)
	}

	// 开启一个goroutine等待所有抓取任务结束后，关闭resultChan
	go func() {
		wg.Wait()
		close(resultChan)
	}()

	// 用于统计各种问题
	problems := map[string][]string{
		&quot;parseFails&quot;:   {}, // 解析 RSS 失败
		&quot;feedEmpties&quot;:  {}, // 内容 RSS 为空
		&quot;noAvatar&quot;:     {}, // 头像地址为空
		&quot;brokenAvatar&quot;: {}, // 头像无法访问
	}
	// 收集抓取结果
	var results []feedResult

	for r := range resultChan {
		if r.Err != nil {
			errStr := r.Err.Error()
			switch {
			case strings.Contains(errStr, &quot;解析RSS失败&quot;):
				problems[&quot;parseFails&quot;] = append(problems[&quot;parseFails&quot;], r.FeedLink)
			case strings.Contains(errStr, &quot;RSS为空&quot;):
				problems[&quot;feedEmpties&quot;] = append(problems[&quot;feedEmpties&quot;], r.FeedLink)
			}
			results = append(results, r)
			continue
		}

		// 对于成功抓取的Feed，如果头像为空或不可用则使用默认头像
		if r.Article.Avatar == &quot;&quot; {
			problems[&quot;noAvatar&quot;] = append(problems[&quot;noAvatar&quot;], r.FeedLink)
			r.Article.Avatar = defaultAvatar
		} else if r.Article.Avatar == &quot;BROKEN&quot; {
			problems[&quot;brokenAvatar&quot;] = append(problems[&quot;brokenAvatar&quot;], r.FeedLink)
			r.Article.Avatar = defaultAvatar
		}
		results = append(results, r)
	}
	return results, problems
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2.3 并发抓取 + 限流&lt;/h2&gt;
&lt;p&gt;为避免一下子开几十上百个协程导致阻塞，可以配合一个带缓存大小的 channel&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;maxGoroutines := 10
sem := make(chan struct{}, maxGoroutines)

for _, rssLink := range rssLinks {
    // 启动 goroutine 前先写入一个空 struct
    sem &amp;lt;- struct{}{}
    go func(link string) {
        // goroutine 执行结束后释放 &amp;lt;-sem
        defer func() { &amp;lt;-sem }()
        fetchFeedWithRetry(link, parser, 3, 1*time.Second, 2.0)
        // ...
    }(rssLink)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;3. 对比旧版本的改进&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;容错率显著提升&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;遇到网络抖动、超时等问题，能以10路并发限制式自动重试，很少出现直接拿不到数据&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;抓取速度更快&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;以 10 路并发为例，对于数量多的 RSS，速度提升明显&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;日志分类更细&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;分清哪条 RSS 是解析失败，哪条头像挂了，哪条本身有问题，后续维护比只给个403 Forbidden方便太多&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;支持 COS&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;可将最终 data.json 放在 COS 上进行 CDN 加速；也能继续放在 GitHub，视自己需求而定&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;自动清理过期日志&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每次抓取后检查 logs/ 目录下 7 天之前的日志并删除，不用手工清理了&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;4. Go 生成的 JSON 和日志长啥样&lt;/h1&gt;
&lt;h2&gt;4.1 RSS&lt;/h2&gt;
&lt;p&gt;抓取到的文章信息会按时间降序排列，示例:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;items&quot;: [
    {
      &quot;blog_name&quot;: &quot;obaby@mars&quot;,
      &quot;title&quot;: &quot;品味江南（三）–虎丘塔 东方明珠&quot;,
      &quot;published&quot;: &quot;10 Mar 2025&quot;,
      &quot;link&quot;: &quot;https://oba.by/2025/03/19714&quot;,
      &quot;avatar&quot;: &quot;https://oba.by/wp-content/uploads/2020/09/icon-500-100x100.png&quot;
    },
    {
      &quot;blog_name&quot;: &quot;风雪之隅&quot;,
      &quot;title&quot;: &quot;PHP8.0的Named Parameter&quot;,
      &quot;published&quot;: &quot;10 May 2022&quot;,
      &quot;link&quot;: &quot;https://www.laruence.com/2022/05/10/6192.html&quot;,
      &quot;avatar&quot;: &quot;https://www.laruence.com/logo.jpg&quot;
    }
  ],
  &quot;updated&quot;: &quot;2025年03月11日 07:15:57&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4.2 日志&lt;/h2&gt;
&lt;p&gt;程序每次运行完毕后，把抓取统计和问题列表写到 GitHub 仓库 logs/YYYY-MM-DD.log:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[2025-03-11 07:15:57] 本次订阅抓取结果统计:
[2025-03-11 07:15:57] 共 25 条RSS, 成功抓取 24 条.
[2025-03-11 07:15:57] ✘ 有 1 条订阅解析失败:
[2025-03-11 07:15:57] - https://tcxx.info/feed
[2025-03-11 07:15:57] ✘ 有 1 条订阅头像无法访问, 已使用默认头像:
[2025-03-11 07:15:57] - https://www.loyhome.com/feed
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;5. 照葫芦画瓢&lt;/h1&gt;
&lt;p&gt;如果你也想玩玩 LhasaRSS&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;准备一份 RSS 列表&lt;/strong&gt;（TXT）:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;格式：每行一个 URL&amp;lt;br/&amp;gt;
如果 RSS_SOURCE = GITHUB，则可以放在项目中的 data/rss.txt&amp;lt;br/&amp;gt;
如果 RSS_SOURCE = COS，就把它上传到某个 https://xxx.cos.ap-xxx.myqcloud.com/rss.txt&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;配置好环境变量&lt;/strong&gt;:&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;默认所有数据保存到 Github，所以 COS API 环境变量不是必要的&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;env:
	TOKEN:                    ${{ secrets.TOKEN }}                    # GitHub Token
	NAME:                     ${{ secrets.NAME }}                     # GitHub 用户名
	REPOSITORY:               ${{ secrets.REPOSITORY }}               # GitHub 仓库名
	TENCENT_CLOUD_SECRET_ID:  ${{ secrets.TENCENT_CLOUD_SECRET_ID }}  # 腾讯云 COS SecretID
	TENCENT_CLOUD_SECRET_KEY: ${{ secrets.TENCENT_CLOUD_SECRET_KEY }} # 腾讯云 COS SecretKey
	RSS:                      ${{ secrets.RSS }}                      # RSS 列表文件
	DATA:                     ${{ secrets.DATA }}                     # 抓取后的数据文件
	DEFAULT_AVATAR:           ${{ secrets.DEFAULT_AVATAR }}           # 默认头像 URL
	RSS_SOURCE                ${{ secrets.RSS_SOURCE }}               # 可选参数 GITHUB or COS
	SAVE_TARGET               ${{ secrets.SAVE_TARGET }}              # 可选参数 GITHUB or COS
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;部署并运行&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;只需 go run . 或在 GitHub Actions workflow_dispatch 触发
运行结束后，就会在 data 文件夹更新 data.json，日志则写进 GitHub logs/ 目录，并且自动清理旧日志&lt;/p&gt;
&lt;p&gt;注：如果你依旧想完全托管在 COS 上，需要把 RSS_SOURCE 和 SAVE_TARGET 都写为 COS，然后使用 GitHub Actions 去调度&lt;/p&gt;
&lt;h2&gt;相关文档&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;lhasaRSS:&lt;a href=&quot;https://github.com/achuanya/lhasaRSS&quot;&gt;https://github.com/achuanya/lhasaRSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;腾讯 Go SDK 快速入门: &lt;a href=&quot;https://cloud.tencent.com/document/product/436/31215&quot;&gt;https://cloud.tencent.com/document/product/436/31215&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;XML Go SDK 源码: &lt;a href=&quot;https://github.com/tencentyun/cos-go-sdk-v5&quot;&gt;https://github.com/tencentyun/cos-go-sdk-v5&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub REST API: &lt;a href=&quot;https://docs.github.com/zh/rest&quot;&gt;https://docs.github.com/zh/rest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;轻量级 RSS/Atom 解析库: &lt;a href=&quot;https://github.com/mmcdole/gofeed&quot;&gt;https://github.com/mmcdole/gofeed&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%88%A9%E7%94%A8%20Go%20%2B%20COS%20%2B%20GitHub%20%E9%87%8D%E6%9E%84%20RSS%20%E7%88%AC%E8%99%AB&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-03-20-reconstructthelhasarssproject&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>骑行开封</title><link>https://blog.lhasa.icu/posts/outdoors/2025-02-20-ridekaifengcity</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-02-20-ridekaifengcity</guid><pubDate>Thu, 20 Feb 2025 08:14:00 GMT</pubDate><content:encoded>&lt;p&gt;我对于开封的印象，还停留在开封府尹·包拯。处于好奇和无处可去的想法，周六早上吃完饭，说走就走了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250220150626.jpg_736&quot; alt=&quot;到达开封鼓楼&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里就到达开封了开封·鼓楼，郑开大道的路上很轻松，室外温度17°+，小风微微的吹着，不冷不热好不痛快&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250220153956.jpg&quot; alt=&quot;Strava记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在郑开大道单飞的过程中偶遇骑友，王哥是开封本地的，骑行的路上跟我聊开封哪里好玩，哪里最具性价比，把我领进开封鼓楼后，又带我在景区逛了一圈带我认路，在此感谢大哥&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202502201506261.jpg_736&quot; alt=&quot;与王哥的合照&quot; /&gt;&lt;/p&gt;
&lt;p&gt;早饭吃的比较仓促，真的很饿，在书店街附近买了些吃的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202502201506263.jpg_736&quot; alt=&quot;干饭&quot; /&gt;&lt;/p&gt;
&lt;p&gt;本来是想在开封呆一天，晚上去清明上河园玩，想到公司有事就提前回去了，怕耽误明天的行程&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250220150625.jpg_736&quot; alt=&quot;鼓楼合影&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250220150623.jpg_736&quot; alt=&quot;郑开大道&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这次跨市骑行急了一些，时间太紧张了！再过几天休息，我想回一次家，骑行约200KM&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250220150624.jpg&quot; alt=&quot;Strava记录&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%AA%91%E8%A1%8C%E5%BC%80%E5%B0%81&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-02-20-ridekaifengcity&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>博客功能更新 2025 (2)</title><link>https://blog.lhasa.icu/posts/technology/2025-02-06-blogfunctionupdate2025-2</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-02-06-blogfunctionupdate2025-2</guid><pubDate>Thu, 06 Feb 2025 05:03:00 GMT</pubDate><content:encoded>&lt;h2&gt;Update details&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;移除红灯笼&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新增 &lt;code&gt;sitemap.xml&lt;/code&gt; 和 &lt;code&gt;sitemap.txt&lt;/code&gt;，自动生成，不再手动更新！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;之前我一直使用 &amp;lt;a href=&quot;https://www.xml-sitemaps.com&quot; target=&quot;_blank&quot;&amp;gt;xml-sitemaps&amp;lt;/a&amp;gt;
手动生成&lt;code&gt;sitemap.xml&lt;/code&gt;，但每当 URL 新增或变更都需要手动提交。实在麻烦！所以，今日用 Liquid 实现自动生成，一劳永逸&lt;/p&gt;
&lt;h2&gt;sitemap.xml 优化策略&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;首页优先级最高 (&lt;code&gt;1.0&lt;/code&gt;)&lt;/strong&gt;，其他页面次之 (&lt;code&gt;0.8&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新文章优先级高&lt;/strong&gt;（30 天内 &lt;code&gt;0.9&lt;/code&gt;，半年内 &lt;code&gt;0.8&lt;/code&gt;，一年内 &lt;code&gt;0.6&lt;/code&gt;），让新内容更容易被搜索引擎收录&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;旧文章优先级降低&lt;/strong&gt;（1 年以上 &lt;code&gt;0.4&lt;/code&gt;，2 年以上 &lt;code&gt;0.2&lt;/code&gt;），减少搜索引擎对老旧内容的爬取&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;动态调整 &lt;code&gt;changefreq&lt;/code&gt;&lt;/strong&gt;，确保新内容频繁爬取，而老文章爬取频率降低&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;---
layout: null
---
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;urlset xmlns=&quot;http://www.sitemaps.org/schemas/sitemap/0.9&quot;&amp;gt;
  {% assign now = site.time | date: &quot;%s&quot; | plus: 0 %}
  
  {% for page in site.pages %}
    {% if page.url == &quot;/&quot; %}
    &amp;lt;!-- 首页优先级最高 --&amp;gt;
      {% assign page_priority = &quot;1.0&quot; %}
    {% else %}
      {% assign page_priority = &quot;0.8&quot; %}
    {% endif %}
    
    &amp;lt;url&amp;gt;
      &amp;lt;loc&amp;gt;{{ site.url }}{{ page.url | replace:&apos;index.html&apos;,&apos;&apos; }}&amp;lt;/loc&amp;gt;
      &amp;lt;lastmod&amp;gt;{{ site.time | date_to_xmlschema }}&amp;lt;/lastmod&amp;gt;
      &amp;lt;changefreq&amp;gt;weekly&amp;lt;/changefreq&amp;gt;
      &amp;lt;priority&amp;gt;{{ page_priority }}&amp;lt;/priority&amp;gt;
    &amp;lt;/url&amp;gt;
  {% endfor %}
  
  &amp;lt;!-- 根据发布时间动态调整 priority 和 changefreq --&amp;gt;
  {% for post in site.posts %}
    {% assign post_time = post.date | date: &quot;%s&quot; | plus: 0 %}
    {% assign diff = now | minus: post_time %}
    {% assign days_old = diff | divided_by: 86400 %}
    
    {% if days_old &amp;lt; 30 %}
      {% assign priority = &quot;0.9&quot; %}
      {% assign changefreq = &quot;daily&quot; %}
    {% elsif days_old &amp;lt; 180 %}
      {% assign priority = &quot;0.8&quot; %}
      {% assign changefreq = &quot;weekly&quot; %}
    {% elsif days_old &amp;lt; 365 %}
      {% assign priority = &quot;0.6&quot; %}
      {% assign changefreq = &quot;monthly&quot; %}
    {% elsif days_old &amp;lt; 730 %}
      {% assign priority = &quot;0.4&quot; %}
      {% assign changefreq = &quot;yearly&quot; %}
    {% else %}
      {% assign priority = &quot;0.2&quot; %}
      {% assign changefreq = &quot;never&quot; %}
    {% endif %}
    
    &amp;lt;url&amp;gt;
      &amp;lt;loc&amp;gt;{{ site.url }}{{ post.url }}&amp;lt;/loc&amp;gt;
      &amp;lt;lastmod&amp;gt;{{ post.date | date_to_xmlschema }}&amp;lt;/lastmod&amp;gt;
      &amp;lt;changefreq&amp;gt;{{ changefreq }}&amp;lt;/changefreq&amp;gt;
      &amp;lt;priority&amp;gt;{{ priority }}&amp;lt;/priority&amp;gt;
    &amp;lt;/url&amp;gt;
  {% endfor %}
&amp;lt;/urlset&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;sitemap.txt 兼容旧版爬虫&lt;/h2&gt;
&lt;p&gt;sitemap.txt 适用于不支持 XML 的搜索引擎（如某些旧版爬虫）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
layout: null
permalink: /sitemap.txt
---
{% for page in site.pages %}
{{ site.url }}{{ page.url | replace:&apos;index.html&apos;,&apos;&apos; }}
{% endfor %}

{% for post in site.posts %}
{{ site.url }}{{ post.url }}
{% endfor %}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;在 robots.txt 里声明 Sitemap&lt;/h2&gt;
&lt;p&gt;确保搜索引擎能找到 &lt;code&gt;Sitemap&lt;/code&gt;，需要在 &lt;code&gt;robots.txt&lt;/code&gt; 文件中声明 &lt;code&gt;sitemap.xml&lt;/code&gt; 和 &lt;code&gt;sitemap.txt&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;User-agent: *
Allow: /

User-agent: MJ12bot
Disallow: /
User-agent: AhrefsBot
Disallow: /
User-agent: SemrushBot
Disallow: /
User-agent: dotbot
Disallow: /

Sitemap: https://lhasa.icu/sitemap.xml
Sitemap: https://lhasa.icu/sitemap.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%8D%9A%E5%AE%A2%E5%8A%9F%E8%83%BD%E6%9B%B4%E6%96%B0%202025%20(2)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-02-06-blogfunctionupdate2025-2&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>1月26日 博客功能更新记录</title><link>https://blog.lhasa.icu/posts/technology/2025-01-26-blogfunctionupdate2025-1</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2025-01-26-blogfunctionupdate2025-1</guid><pubDate>Sat, 25 Jan 2025 16:10:00 GMT</pubDate><content:encoded>&lt;p&gt;由于郑州最近的雨夹雪天气，已经一周没有骑行了，实在憋得不行，给自己找点事做，今天中午下班时更新了一下博客&lt;/p&gt;
&lt;h2&gt;Update details&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;修复了柱形图显示错位&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移除了骑行页面的活动天数&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新增了全年骑行总时长、全年骑行总公里数&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;柱形图的宽度&lt;/strong&gt;不再由骑行时长来计算，而是由骑行公里数来计算显示&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;新增春节快乐红灯笼&lt;/strong&gt;（移动端不支持）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;移除 &lt;code&gt;node-sass&lt;/code&gt; 包，由 &lt;code&gt;sass&lt;/code&gt; 代替&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Fix Bugs：柱形图显示错位&lt;/h2&gt;
&lt;p&gt;当前的柱形图仅为有骑行数据的周生成柱形图，导致柱形图与日历中的周对齐错位，所以即某周没有骑行数据时，柱形图也要生成一根柱子&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function generateBarChart() {
    const barChartElement = document.getElementById(&apos;barChart&apos;);
    // 清空柱形图内容
    barChartElement.innerHTML = &apos;&apos;;

    const today = getChinaTime();
    const startDate = getStartDate(today, 21);

    // 创建所有周的时间范围
    const weeklyData = {};
    let currentWeekStart = new Date(startDate);
    currentWeekStart.setUTCHours(0, 0, 0, 0);

    // 按周计算未来 4 周的日期范围
    for (let i = 0; i &amp;lt; 4; i++) {
        const weekStart = new Date(currentWeekStart);
        const weekEnd = new Date(weekStart);
        // 一周结束日期为开始日期 +6 天
        weekEnd.setUTCDate(weekStart.getUTCDate() + 6);
        const weekKey = `${weekStart.toISOString().split(&apos;T&apos;)[0]} - ${weekEnd.toISOString().split(&apos;T&apos;)[0]}`;

        // 初始化每周骑行数据为 0
        weeklyData[weekKey] = 0;
        // 移动到下一周
        currentWeekStart.setUTCDate(currentWeekStart.getUTCDate() + 7);
    }

    // 累加每周的骑行距离
    processedActivities.forEach(activity =&amp;gt; {
        const activityDate = new Date(activity.activity_time);
        // 活动所在周的开始日期
        const weekStart = getWeekStartDate(activityDate);
        const weekEnd = new Date(weekStart);
        weekEnd.setUTCDate(weekStart.getUTCDate() + 6);

        const weekKey = `${weekStart.toISOString().split(&apos;T&apos;)[0]} - ${weekEnd.toISOString().split(&apos;T&apos;)[0]}`;
        if (weeklyData[weekKey] !== undefined) {
            weeklyData[weekKey] += parseFloat(activity.riding_distance);
        }
    });

    // 获取最大骑行距离（用于柱形图比例）
    const maxDistance = Math.max(...Object.values(weeklyData), 0);

    // 创建并显示每周的柱形图
    Object.keys(weeklyData).forEach(week =&amp;gt; {
        // 当前周的骑行距离
        const distance = weeklyData[week];
        const barContainer = document.createElement(&apos;div&apos;);
        barContainer.className = &apos;bar-container&apos;;

        const bar = document.createElement(&apos;div&apos;);
        bar.className = &apos;bar&apos;;

        // 计算柱形图的宽度
        const width = maxDistance &amp;gt; 0 ? (distance / maxDistance) * 190 : 0;
        bar.style.setProperty(&apos;--bar-width&apos;, `${width}px`);

        const distanceText = document.createElement(&apos;div&apos;);
        distanceText.className = &apos;cycling-kilometer&apos;;
        distanceText.innerText = &apos;0 km&apos;;

        const messageBox = createMessageBox();
        const clickMessageBox = createMessageBox();

        barContainer.style.position = &apos;relative&apos;;
        bar.appendChild(distanceText);
        barContainer.appendChild(bar);
        barContainer.appendChild(messageBox);
        barContainer.appendChild(clickMessageBox);
        barChartElement.appendChild(barContainer);

        // 动画效果：逐渐显示柱形图宽度
        bar.style.width = &apos;0&apos;;
        bar.offsetHeight;
        bar.style.transition = &apos;width 1s ease-out&apos;;
        bar.style.width = `${width}px`;

        distanceText.style.opacity = &apos;1&apos;;
        // 动态更新柱形图的数值
        animateText(distanceText, 0, distance, 1000, true);
        setupBarInteractions(bar, messageBox, clickMessageBox, distance);
    });
}

// 动态文本显示
function animateText(element, startValue, endValue, duration, isDistance = false) {
    const startTime = performance.now();
    function update() {
        const elapsed = performance.now() - startTime;
        const progress = Math.min(elapsed / duration, 1);
        const currentValue = (progress * endValue).toFixed(2);
        element.innerText = isDistance ? `${currentValue} km` : `${currentValue}h`;
        if (progress &amp;lt; 1) {
            requestAnimationFrame(update);
        } else {
            element.innerText = isDistance ? `${endValue.toFixed(2)} km` : `${endValue.toFixed(2)}h`;
        }
    }
    update();
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;New：全年骑行总时长、全年骑行总公里数&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// 显示总活动数和总公里数
function displayTotalActivities(activities) {
    // 全年骑行时长
    const ridingTimeThisYear = document.getElementById(&apos;totalCount&apos;);
    // 全年骑行公里数
    const milesRiddenThisYear = document.getElementById(&apos;milesRiddenThisYear&apos;);
    // 动态年标题《2025 骑行总时长》
    const totalTitleElement = document.getElementById(&apos;totalTitle&apos;);

    if (!ridingTimeThisYear || !milesRiddenThisYear || !totalTitleElement) return;

    const ridingTimeThisYearValue = ridingTimeThisYear.querySelector(&apos;#ridingTimeThisYearValue&apos;);
    const milesRiddenThisYearValue = milesRiddenThisYear.querySelector(&apos;#milesRiddenThisYearValue&apos;);

    const totalCountSpinner = ridingTimeThisYear.querySelector(&apos;.loading-spinner&apos;);
    const milesRiddenThisYearSpinner = milesRiddenThisYear.querySelector(&apos;.loading-spinner&apos;);

    totalCountSpinner.classList.add(&apos;active&apos;);
    milesRiddenThisYearSpinner.classList.add(&apos;active&apos;);

    const currentYear = new Date().getFullYear();
    totalTitleElement.textContent = `${currentYear} 骑行总时长`;

    // 筛选全年活动数据
    const filteredActivities = activities.filter(activity =&amp;gt; {
        const activityYear = new Date(activity.activity_time).getFullYear();
        return activityYear === currentYear;
    });

    // 计算全年活动时间的总和（单位：小时）
    const totalMovingTime = filteredActivities.reduce((total, activity) =&amp;gt; {
        return total + parseFloat(activity.moving_time) || 0;
    }, 0);

    // 计算全年总公里数
    const totalKilometers = calculateTotalKilometers(filteredActivities);

    // 动画效果
    animateCount(ridingTimeThisYearValue, totalMovingTime, 1000, 50, false);
    animateCount(milesRiddenThisYearValue, totalKilometers, 1000, 50, true);

    setTimeout(() =&amp;gt; {
        console.log(totalKilometers.toFixed(2));
        ridingTimeThisYearValue.textContent = `${totalMovingTime.toFixed(2)} h`;
        milesRiddenThisYearValue.textContent = `${totalKilometers.toFixed(2)} km`;
        totalCountSpinner.classList.remove(&apos;active&apos;);
        milesRiddenThisYearSpinner.classList.remove(&apos;active&apos;);
    }, 1000);
}

// 加载数据并生成日历
(async function() {
    const today = getChinaTime();
    const startDate = getStartDate(today, 21);

    const activities = await loadActivityData();
    // 显示4周的日历
    generateCalendar(activities, startDate, 4);

    // 显示全年骑行时长和公里数
    displayTotalActivities(activities);
})();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;New：春节快乐红灯笼&lt;/h2&gt;
&lt;p&gt;两年前在冲浪时下载的，已经是第二次用了：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// default.html
include lantern.html

// main.scss
@use &apos;lantern&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Fix Bugs：移除 node-sass 包&lt;/h2&gt;
&lt;p&gt;node-sass 是基于 LibSass 库构建的，而 LibSass 从 2019 年就停止了更新。所以，Sass 团队放弃了这个项目，重构了 sass（Dart 编写）&lt;/p&gt;
&lt;h3&gt;sass 相对 node-sass 的优点&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;原生支持 Dart&lt;/p&gt;
&lt;p&gt;sass 是由 Dart 编写，它不再依赖 C++ 编译器，安装和构建速度更快&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;不再依赖编译&lt;/p&gt;
&lt;p&gt;node-sass 需要本地编译，会遇到编译问题，尤其是 Windows 系统上。而 sass 是纯 JavaScript 实现，跨平台时不会有编译问题&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;devDependencies&quot;: {
        &quot;sass&quot;: &quot;^1.83.4&quot;,
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;89ffc8f51982841a4f04ce590446b07.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=1%E6%9C%8826%E6%97%A5%20%E5%8D%9A%E5%AE%A2%E5%8A%9F%E8%83%BD%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2025-01-26-blogfunctionupdate2025-1&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>骑行 桃花峪、黄河文化公园</title><link>https://blog.lhasa.icu/posts/outdoors/2025-01-19-ride-peach-blossom-valley-yellow-river-cultural-park</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-01-19-ride-peach-blossom-valley-yellow-river-cultural-park</guid><pubDate>Sat, 18 Jan 2025 19:57:00 GMT</pubDate><content:encoded>&lt;p&gt;周末假期被骑行占有，那种满足是一切都比不过&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;12025011818102.jpg_736&quot; alt=&quot;刚吃完饭准备出发&quot; /&gt;&lt;/p&gt;
&lt;p&gt;公园内设有多条越野骑行路线，坡度和难度多样，我这光胎的公路车进去根本生存不了。总的来说是一个不错的地方，集挑战、风景与文化于一体，是体验黄河沿岸自然与文化魅力的不二之选&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22025011818150.jpg_736&quot; alt=&quot;到达桃花峪-炎黄越野公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这条路很窄，一次只能过一辆汽车，有上有下，而且路面陡峭，路非常烂很危险，目测坡度15°&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;30250118181022.jpg_736&quot; alt=&quot;桃花峪最陡最烂的坡路&quot; /&gt;&lt;/p&gt;
&lt;p&gt;去窗口交费取票，姓名都不需要留&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;40250118181016.jpg_736&quot; alt=&quot;到达黄河文化公园 检票口&quot; /&gt;&lt;/p&gt;
&lt;p&gt;黄河流域地势平坦，水资源丰富，土壤肥沃，非常适宜农业发展。古人利用黄河水系灌溉农田，使中原成为中国古代经济、人口最为集中的地区，为中华民族的形成和壮大提供了物质基础，所以把黄河称呼为母亲河、民族摇篮也不足为过&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250118181019.jpg_736&quot; alt=&quot;民族摇篮牌坊&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;50250118181017.jpg_736&quot; alt=&quot;炎黄二帝塑像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;日晷是一种古老的计时器，利用太阳的影子来确定时间。它的起源可以追溯到公元前4000年的古埃及，后来广泛传播到世界各地。在中国，日晷被称为“圭表”，早在周朝时期便已使用，用于确定二十四节气和天文观测&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;60250118181042.jpg_736&quot; alt=&quot;日晷&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;70250118181412.jpg_736&quot; alt=&quot;遇到一位好大哥帮我拍的照片&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;80250118181410.jpg_736&quot; alt=&quot;鼎&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;90250118181408.jpg_736&quot; alt=&quot;广场的某个角落&quot; /&gt;&lt;/p&gt;
&lt;p&gt;终于到达了心心念念的黄河岸边，此处跨越黄河的建筑就是大名鼎鼎的京广铁路，它是一条纵贯中国南北的交通大动脉，途经黄河流域、长江流域和南岭山脉。旁边的郑太高铁则是中国“八纵八横”高速铁路网的重要主通道之一，大大缩短了晋东南、蒙西等地与中东部地区的时空距离&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;100250181814051.jpg_736&quot; alt=&quot;到达黄河岸边&quot; /&gt;&lt;/p&gt;
&lt;p&gt;湖水清澈见底，微风拂过时，水面波光粼粼，宛如点点繁星洒在湖面上，因此得名“星海湖”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;110250118181401.jpg_736&quot; alt=&quot;星海湖 原相机没有P图 水质水太好了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;120250111813591.jpg_736&quot; alt=&quot;黄河缆车门口 鸿运当头&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这辆车是我穿着锁鞋背上山的，如果没有体验过锁鞋的朋友，可以想象一下穿高跟鞋走山路，不过这里的高跟得反过来 —— 脚掌部分垫高，脚跟贴地&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;130250119001642.jpg_736&quot; alt=&quot;五龙峰 其中一个山峰顶&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;140250118181358.jpg_736&quot; alt=&quot;五龙峰 黄河少年雕像&quot; /&gt;&lt;/p&gt;
&lt;p&gt;中午时在超市吃了一碗凉皮，和老板沟通一番后把车子暂存于此，爬楼梯的路上三步一回头&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;150250118181356.jpg_736&quot; alt=&quot;毛主席视察黄河纪念地下方的超市&quot; /&gt;&lt;/p&gt;
&lt;p&gt;强烈推荐“浮天阁”，登顶后俯瞰整个黄河流域，东西南北尽收眼底&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;161250111813561.jpg_736&quot; alt=&quot;浮天阁&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;div style=&quot;text-align: center;&quot;&amp;gt;
&amp;lt;p&amp;gt;倒泻银河事有无，掀天浊浪只须臾&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;人间更有风涛险，翻说黄河是畏途&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;180250118181355.jpg&quot; alt=&quot;东&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;190250118181352.jpg&quot; alt=&quot;西&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;170250118181354.jpg&quot; alt=&quot;南&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;200250118813541.jpg&quot; alt=&quot;北&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;160250118181357.jpg&quot; alt=&quot;东南&quot; /&gt;&lt;/p&gt;
&lt;p&gt;对于喜欢骑行、越野和民族文化的朋友来说，桃花峪和黄河文化公园很适合，两个地方紧挨着，要场地有场地，要难度有难度，完事后紧挨着黄河散散步，傍晚时登顶浮天阁看日落，想想都美哦&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250119034252.jpg&quot; alt=&quot;结束&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%AA%91%E8%A1%8C%20%E6%A1%83%E8%8A%B1%E5%B3%AA%E3%80%81%E9%BB%84%E6%B2%B3%E6%96%87%E5%8C%96%E5%85%AC%E5%9B%AD&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-01-19-ride-peach-blossom-valley-yellow-river-cultural-park&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>骑行郑州·三环</title><link>https://blog.lhasa.icu/posts/outdoors/2025-01-07-weekendride</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-01-07-weekendride</guid><pubDate>Tue, 07 Jan 2025 12:39:00 GMT</pubDate><content:encoded>&lt;p&gt;上次我打算一天骑完郑州的三四环线，预计160km，没想到下午摔的手梆硬，昨天六号上午一雪前耻了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250107192510.jpg_736&quot; alt=&quot;郑州龙湖公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;路过龙湖公园被吸引了，多了10km+里程&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925103.jpg_736&quot; alt=&quot;公园放养的白天鹅&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里的天鹅挺不少，小百只了，小鸭子不计其数。岸边挤满了摄影发烧友，到处是大炮&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925101.jpg_736&quot; alt=&quot;人工沙滩&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925102.jpg_736&quot; alt=&quot;郑州龙湖公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925104.jpg&quot; alt=&quot;骑行郑州三环 结束&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到这里，骑行三环算是告一段落了，它比四环线少40km，难度低了几个档，三环红路灯非常多，而骑行四环时刹车都很少碰。三环道路也比较好，不像四环压根就没有路，什么路都没有。只能走菜地、翻墙、最后走高速绿化带，我提着车爬上机场高架，是用手爬，不是骑车爬...最后为了安全从高架上下来，走下水道过去了...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925105.jpg&quot; alt=&quot;骑行 金融岛&quot; /&gt;&lt;/p&gt;
&lt;p&gt;上午去了一次龙湖公园，但是中间的金融岛一直找不到地方上去，下午又去了一次，逛了 Specialized、colnago&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925106.jpg_736&quot; alt=&quot;骑行 中原福塔&quot; /&gt;&lt;/p&gt;
&lt;p&gt;沪上有明珠，中原有福塔&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071925107.jpg&quot; alt=&quot;回家&quot; /&gt;&lt;/p&gt;
&lt;p&gt;下午回了家，借同事电脑把博客整了下，前俩月博客处于失联状态，证书都过期了，开往都把我踢了，现在OK了，只是骑行页面每天要手动每天上传一下，Strava接口暂时没有精力搞了&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%AA%91%E8%A1%8C%E9%83%91%E5%B7%9E%C2%B7%E4%B8%89%E7%8E%AF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-01-07-weekendride&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>骑行郑州·四环</title><link>https://blog.lhasa.icu/posts/outdoors/2025-01-07-zhengzhou</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2025-01-07-zhengzhou</guid><pubDate>Tue, 07 Jan 2025 11:10:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;202501071808232.jpg&quot; alt=&quot;骑行西流湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20250107180823.jpg&quot; alt=&quot;骑行西流湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071808234.jpg&quot; alt=&quot;骑行西流湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071808231.jpg&quot; alt=&quot;骑行西流湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071808235.jpg&quot; alt=&quot;骑行西流湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;探金水河，溪流钓的天堂，台钓的地狱&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025010718082311.jpg&quot; alt=&quot;骑行桃花峪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;郑州的面积比我预计小不少
明天准备绕圈 ，骑行四环(97km)和三环(57km)
在地图上画两个正方形，好事成双&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071808239.jpg&quot; alt=&quot;骑行桃花峪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025010718082310.jpg&quot; alt=&quot;骑行桃花峪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202501071808236.jpg&quot; alt=&quot;骑行桃花峪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025010718082312.jpg&quot; alt=&quot;骑行桃花峪&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;437126116250681548.jpg&quot; alt=&quot;骑行桃花峪 结束&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025010718082313.jpg&quot; alt=&quot;这里是:郑州 四环 非机动车道&quot; /&gt;&lt;/p&gt;
&lt;p&gt;14点饭后出发骑三环，没一会儿出事了，太遗憾了
总而言之，郑州的西北南四环路况一般，且由北四环入东四环后非常拉跨，你除了走机场高架外没有选择，当时为了安全避免走机场高架，过草地和下水道硬控了我大半个小时&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;686884765634183642.jpg&quot; alt=&quot;骑行郑州四环&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025010718082314.jpg&quot; alt=&quot;骑行郑州四环&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;2025010718082315.jpg&quot; alt=&quot;骑行玩手机的下场&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;746075349627892760.jpg&quot; alt=&quot;骑行郑州四环 结束&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%AA%91%E8%A1%8C%E9%83%91%E5%B7%9E%C2%B7%E5%9B%9B%E7%8E%AF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2025-01-07-zhengzhou&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>十月份看完的第一本书</title><link>https://blog.lhasa.icu/posts/book/2024-10-03-thewaterofthecanglangriver</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/book/2024-10-03-thewaterofthecanglangriver</guid><pubDate>Thu, 03 Oct 2024 12:31:00 GMT</pubDate><content:encoded>&lt;p&gt;为这本书，我近两天几乎废寝忘食，心中感慨颇多，最深刻的收获便是对人性与形式的深刻理解。许多事情在当时看来似乎是理所当然，但如今回首，才发现那时的自己是多么稚嫩，甚至有些可笑&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;663e799114e3e4e30ff447394fbc284.jpg&quot; alt=&quot;微信读书 · 沧浪之水&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这是我第一次尝试电子书，有声加文字的双重体验感觉不错，美中不足的是，机械式的发音让情感显得苍白，在这个时代，做个拟人化的语音合成也不难啊，腾讯读书这块业务还是小众，资源太少了，很多我想看的书都找不到，涉及敏感话题的搜都搜不到，哎&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%8D%81%E6%9C%88%E4%BB%BD%E7%9C%8B%E5%AE%8C%E7%9A%84%E7%AC%AC%E4%B8%80%E6%9C%AC%E4%B9%A6&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fbook%2F2024-10-03-thewaterofthecanglangriver&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>一场说走就走的骑行</title><link>https://blog.lhasa.icu/posts/outdoors/2024-09-26-huaiyangtoluyicyclebackandforth</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-09-26-huaiyangtoluyicyclebackandforth</guid><pubDate>Thu, 26 Sep 2024 12:02:00 GMT</pubDate><content:encoded>&lt;p&gt;凌晨四点半，忽然醒了，辗转反侧，睡意全无，脑海中第一个蹦出的念头竟然是骑车&lt;/p&gt;
&lt;p&gt;连衣服都没顾得上穿，立刻下床检查车子胎压，拿好盐丸和刚冲泡的蛋白粉，穿上骑行服，扛着车冲出家门，直奔早餐店&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240926190847.jpg&quot; alt=&quot;家门口的早餐店&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到早餐店的时间是4.50，来的太早了，选择不多，只有小米粥和茶叶蛋，包子还要等五分钟才熟，要了一碗小米粥、两个茶叶蛋、三个牛肉包。吃得有些急促，可以用赵本山的急头白脸吃一顿来表示&lt;/p&gt;
&lt;p&gt;坐在店里，我心中还没想好骑去哪儿。随手打开地图，首页推荐了鹿邑的太清宫。还记得小时候常听到同学开玩笑说：老子是鹿邑的！&lt;/p&gt;
&lt;p&gt;看了一下路线，沿着322省道，往返148km，这个省道我走过，去年去骑行去上海就是这个，路况烂的没法说，这次过去更是炸裂&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202409261908471.jpg&quot; alt=&quot;椿树王庄的日出&quot; /&gt;&lt;/p&gt;
&lt;p&gt;路况越来越差了，柏油路被超载车辆压的细碎，我这25c管胎感觉随时都要爆，不禁怀念瓜车山地带来的安全感&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240926190846.jpg&quot; alt=&quot;太清宫外的香火小贩&quot; /&gt;&lt;/p&gt;
&lt;p&gt;8.20到达太清宫，但是车子的存放问题要解决一下，正好门口有卖香火的大妈，我付了她十块钱，让她帮我看着车子&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202409261908472.jpg&quot; alt=&quot;到达 鹿邑·太清宫&quot; /&gt;&lt;/p&gt;
&lt;p&gt;太清宫的门票要60，有些贵了，相比之下，淮阳的太昊陵只要40，且规模和和设计都远胜太清宫&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;51c7e2814efa11dc3ee3e03bfc8529b.jpg&quot; alt=&quot;太清宫·三清大殿&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202409261908461.jpg&quot; alt=&quot;三清大殿后的广场&quot; /&gt;&lt;/p&gt;
&lt;p&gt;从三清大殿出来后看到这，我瞬间挂上痛苦面具，因为我今天出来穿的是骑行锁鞋，前脚跟高，后脚跟低，走路时一步两响，比高跟鞋都变态&lt;/p&gt;
&lt;p&gt;出来后多少有些失望，毕竟这是老子的诞生地，但道教的气息却淡得几乎感觉不到，园林设计更是稀碎。相反，倒是社会主义的标语随处可见。我是感觉现在的寺庙和道观都没有其文化特色，如同各地方美食城的铁板鱿鱼&lt;/p&gt;
&lt;p&gt;想必这和上层意识脱不开干系，组织对于宗教信仰很敏感&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240926190845.jpg&quot; alt=&quot;来奶茶店补个电&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一路上导航和听歌消耗了不少电，在奶茶店喝了两杯，顺便给手机充了个电，不过鹿邑中午也太热了，我出发时还穿了棉背心&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240926190844.jpg&quot; alt=&quot;STRAVA记录&quot; /&gt;&lt;/p&gt;
&lt;p&gt;返程78km，全程逆风，出发前还吃多了，当我坐在车上那一刻，再次带上痛苦面具...&lt;/p&gt;
&lt;p&gt;下午五点半点到家，回来得有些匆忙，因为这个省道很窄，晚上全是半挂，我不敢贪玩冒这个风险，图片还是有点少了，骑行时不可自拔，除了点烟会顺手会拿起手机拍照，其他时候不想断了骑行的节奏&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%80%E5%9C%BA%E8%AF%B4%E8%B5%B0%E5%B0%B1%E8%B5%B0%E7%9A%84%E9%AA%91%E8%A1%8C&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-09-26-huaiyangtoluyicyclebackandforth&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>聊聊自行车</title><link>https://blog.lhasa.icu/posts/outdoors/2024-08-21-somethoughtsoncycling</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-08-21-somethoughtsoncycling</guid><pubDate>Tue, 20 Aug 2024 19:02:00 GMT</pubDate><content:encoded>&lt;h2&gt;洋车子的起源&lt;/h2&gt;
&lt;p&gt;在河南老家，人们通常称自行车为“洋车子”。确实，是洋鬼子的杰作，早在1791年，法国佬西夫拉克设计出了世界上第一辆自行车，据说他是受溜冰鞋的启发，整车为木制，上管由一根大横梁作为主体车架，下方装两个木制车轮，没有转向结构，拐弯全靠搬。当然，它也没有传动系统，骑多快这就真看腿了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1723739662885.jpg&quot; alt=&quot;河北 中国自行车博物馆 仿制藏品&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;0-100的开始&lt;/h2&gt;
&lt;p&gt;追溯历史，19世纪六七十年代，自行车由洋鬼子、华人带入中国，数量寥寥&lt;/p&gt;
&lt;p&gt;随着时间的推移，20世纪二十年代，上海做自行车销售的同昌车行开始仿制生自行车零部件，再搭配进口件的基础上进行组装贴牌。从此内地第一家仿制、组装整车的自行车企业诞生，据注册登记记载有：飞马、飞鹰、飞人、飞轮等型号。直到新中国1956年国家队将其收编、创新再贴牌。由此诞生：上海凤凰&lt;/p&gt;
&lt;p&gt;新中国1955-1957年期间，是内地自行车产业发展的关键时期，由主管自行车工业的工信部，组织上海、天津、沈阳的自行车厂进行标准化设计，确定了28寸自行车的规格和零配件的质量标准，为内地自行车行业制定了第一部行业标准，为后来几十年的自行车普及奠定了基础&lt;/p&gt;
&lt;p&gt;到了新中国六七十年代，自行车在全国范围内迅速普及，尽管当时的产业链尚不完善，但许多品牌已逐渐崭露头角，下面有请八十年代国产五虎上将：上海永久、凤凰、天津飞鸽、红旗、江苏金狮&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1723740844365.jpg&quot; alt=&quot;上海永久ZA51-9&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;富裕的象征&lt;/h2&gt;
&lt;p&gt;新中国1981年9月，三流日报曾转载了一篇文章：湖北农民杨小运在超额完成国家交售指标后，县里问他想要什么奖励，他说想要一辆永久牌自行车。很多年后，杨小运回忆：“我是壮起胆子提出了自己的想法。须知道那时候能够骑上一辆永久牌自行车是多么得意的事情，因为据说只有凭什么“工业券”才能买到这种稀罕物，比现在坐小轿车还要显摆，简直就是一种身份的象征。在我的印象中，好像只有公社党委书记这样的人物才配有这么一辆自行车&lt;/p&gt;
&lt;p&gt;由此可见，自行车不仅是代步工具，更是那个年代富裕与社会地位的象征，俗称小资三件套：缝纫机、手表，自行车&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1723745451589.jpg&quot; alt=&quot;60年代初-80年代末发行的自行车券&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;短暂的辉煌&lt;/h2&gt;
&lt;p&gt;然而，好景不长。随着改革开放的推进，外资品牌涌入中国市场，这些闭门仿车国产老品牌被外资的新工业设计所冲击，如：GIANT、Merida、Trek等等&lt;/p&gt;
&lt;p&gt;此时的自行车带来最直接的就是视觉感官，功能多样的车架和丰富多彩的颜色，彻底颠覆了内地自行车的固有形象。相比之下，国产品牌的市场份额断崖式下跌，怕不是编制兜底，如今已全部倒闭，至此，沪上小资品牌殊荣不再&lt;/p&gt;
&lt;p&gt;在新工业品牌中，最具代表性的是GIANT，尽管价格昂贵，但其时尚的设计和优越的性能激发了人民的购买欲望，迅速取代国产五虎上将，成为新一代的“高级自行车”，GIANT驻扎内地后年年蝉联市场第一，这一变革标志着中国内地自行车市场的一个重要转折点&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;758461846894.jpg&quot; alt=&quot;较受欢迎的 GIANT ATX 760 图为90款&quot; /&gt;&lt;/p&gt;
&lt;p&gt;从改革开放到21世纪初的几十年间，中国自行车运动突然就死在了襁褓里，由于汽车的普及和部分国人的观念癌症，自行车逐渐边缘化，成为人们眼中过时的交通工具。就此，内地再也没有形成新的自行车运动&lt;/p&gt;
&lt;p&gt;而在此期间，外面的世界发生了天翻地覆的变化。UCI在瑞士洛桑成立了世界自行车中心和场地车训练场，致力于培训精英选手并为赛事提供支持。高卢鸡的环法赛愈演愈烈，成为全球最受瞩目的公路自行车赛事之一。与此同时，小日子的Shimano凭借革命性的STI技术，将刹车和变速融合，逐步通过专利，垄断全球自行车零部件市场&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1723742326692.jpg&quot; alt=&quot;1998年环法路过一片向日葵地&quot; /&gt;&lt;/p&gt;
&lt;p&gt;反观中国内地。自行车产业在这一波全球变革中停滞不前，国产品牌没有主动认清提升技术和产品价值的重要性，依然闭门造车，专注于下沉市场。没有技术，没有创新，短期图利坑蒙拐骗，论长期发展无异于自我毁灭&lt;/p&gt;
&lt;p&gt;直到今天，大部分内地品牌在观念和行动上依然停留在过去的成功经验 ，靠坑蒙拐骗人民继续吃老本，最近又冒出一个内地品牌——Maserati玛莎拉蒂自行车，一个车架都要使用公模，搭配些工业垃圾套件组装。技术水平确实了不起，至少标贴得还算正。我都感到丢人，是不是人民好糊弄？都当成傻子？《这些，它们够用了》&lt;/p&gt;
&lt;h2&gt;昙花一现&lt;/h2&gt;
&lt;p&gt;进入21世纪后，随着资本经济的涌入，共享单车兴起，给中国的自行车运动带来了新的生机，环保意识的提升和健康生活方式的推广，使得越来越多的人将骑行作为健身方式和生活态度，骑行团体的壮大和各种赛事也愈发频繁&lt;/p&gt;
&lt;p&gt;疫情期间，由于长时间的封闭管控，许多人渴望户外活动的机会，当管控解除后，户外运动迅速升温，体育及户外运动板块纷纷涨停板，骑行也因此成为了炙手可热的选择之一&lt;/p&gt;
&lt;p&gt;然而，在各方面利好的同时，骑行运动也面临诸多挑战，在鄙人看来，部分国人对于新鲜事物的包容度较低，这与千百年来的文化属性密不可分&lt;/p&gt;
&lt;p&gt;在这个二十一世纪的现代社会，有些人甚至认为骑行是“文化入侵”，这一观点显然过于狭隘，抱着自由言论的心态，鄙人不敢苟同&lt;/p&gt;
&lt;p&gt;中国作为一个发展中国家，许多城市的道路基础设施尚未完善，尤其是在道路规划方面，机动车道与非机动车道的设计往往缺乏科学性和合理性，例如，原本就狭窄的非机动车道常常被汽车占用，加上逆行和鬼探头等行为，骑行安全难以保障，导致了骑行风险的增加。在这种情况下，所谓的“暴骑团”被迫驶入机动车道，进一步加剧了骑行者与机动车之间的矛盾，交通事故频发&lt;/p&gt;
&lt;p&gt;此外，骑行者的素质问题也是不可忽视的因素。部分骑行者缺乏基本的交规意识、逆行、闯红灯等行为屡见不鲜。面对这种情况，我只能说，管好自己&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1723744080741.jpg&quot; alt=&quot;非机动车道被抓&quot; /&gt;&lt;/p&gt;
&lt;p&gt;关于最近发生的河北亲子骑行事件，引发了社会的广泛关注和讨论，不少网友竟表示同情，在视频中司机被殴打被迫下跪，什么死者为大？呸恶心。鄙人认为这是家长全责！缺乏对骑行的敬畏之心，忽视了安全因素。对于部分圣母指责辱骂司机我只想说&lt;/p&gt;
&lt;p&gt;在这个环境内，你可以漠视周围发生的一切不公平，直到这种不公平在某一天以一种你无法预期的方式降临到你身上&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%81%8A%E8%81%8A%E8%87%AA%E8%A1%8C%E8%BD%A6&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-08-21-somethoughtsoncycling&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>写一个骑行页面(二)</title><link>https://blog.lhasa.icu/posts/outdoors/2024-08-14-cyclingpage2</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-08-14-cyclingpage2</guid><pubDate>Wed, 14 Aug 2024 12:40:00 GMT</pubDate><content:encoded>&lt;p&gt;在前几天写的数据展示页面中，日历与JSON数据的时间处理依赖于本地时区的getDay()和setDate()方法。然而，博客部署在GitHub Pages，时区的不同导致日历出现了显示偏差&lt;/p&gt;
&lt;h2&gt;本地时间异常&lt;/h2&gt;
&lt;p&gt;涉及函数：getStartDate&lt;/p&gt;
&lt;p&gt;原代码：&lt;/p&gt;
&lt;p&gt;这里的getDay()和setDate()方法是基于Github本地时区，不细心&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getStartDate(today, daysOffset) {
    const currentDayOfWeek = today.getDay();
    const daysToMonday = (currentDayOfWeek === 0 ? 6 : currentDayOfWeek - 1); 
    const startDate = new Date(today);
    startDate.setDate(today.getDate() - daysToMonday - daysOffset); 
    startDate.setDate(startDate.getDate() - (startDate.getDay() === 0 ? 6 : startDate.getDay() - 1)); 
    return startDate;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;改进后：&lt;/p&gt;
&lt;p&gt;修改后：采用getUTCDay()和setUTCDate()方法，使用UTC时间来保证时间处理的一致性&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function getStartDate(today, daysOffset) {
    const currentDayOfWeek = today.getUTC11Day();
    const daysToMonday = (currentDayOfWeek === 0 ? 6 : currentDayOfWeek - 1);
    const startDate = new Date(today);
    startDate.setUTCDate(today.getUTCDate() - daysToMonday - daysOffset);
    return startDate;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;JSON数据与日历数据两者时区不一致&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;
// 涉及函数：generateCalendar

// 原代码：

// 在与JSON日期数据进行比较时，由于时区问题，日历的显示存在错位

const todayStr = getChinaTime().toISOString().split(&apos;T&apos;)[0];
let currentDate = new Date(startDate);

// 改进后：

// 将currentDate时间归零，避免由于时区差异导致的日期比较错误

const todayStr = getChinaTime().toISOString().split(&apos;T&apos;)[0];
let currentDate = new Date(startDate);
currentDate.setUTCHours(0, 0, 0, 0);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;日期显示与更新逻辑异常&lt;/h2&gt;
&lt;p&gt;涉及函数：createDayContainer&lt;/p&gt;
&lt;p&gt;同上，本地时间异常&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 原代码：
dateNumber.innerText = date.getDate();

// 改进后
dateNumber.innerText = date.getUTCDate();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;异步打字机时区异常&lt;/h2&gt;
&lt;p&gt;涉及函数：displayCalendar&lt;/p&gt;
&lt;p&gt;同上，本地时间异常&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 原代码：
currentDate.setDate(currentDate.getDate() + 1);

// 改进后
currentDate.setUTCDate(currentDate.getUTCDate() + 1);
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;UPDATE 日历交互动画&lt;/h2&gt;
&lt;p&gt;1.默认显示当天日期，不显示球体&lt;/p&gt;
&lt;p&gt;2.光标悬浮其他日历时，隐藏当天日期，显示球体，反之亦然&lt;/p&gt;
&lt;p&gt;3.整体主题色为：rgb(36, 36, 40)&lt;/p&gt;
&lt;p&gt;4.日历的所有日期下添加2px厚下划线&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;function createDayContainer(date, activities) {
    const dayContainer = document.createElement(&apos;div&apos;);
    dayContainer.className = &apos;day-container&apos;;

    const dateNumber = document.createElement(&apos;span&apos;);
    dateNumber.className = &apos;date-number&apos;;
    dateNumber.innerText = date.getUTCDate();
    dayContainer.appendChild(dateNumber);

    const activity = activities.find(activity =&amp;gt; activity.activity_time === date.toISOString().split(&apos;T&apos;)[0]);
    // console.log(processedActivities);
    if (activity) processedActivities.push(activity);

    // 根据骑行距离设置球的大小
    const ballSize = activity ? Math.min(parseFloat(activity.riding_distance) / 4, 24) : 2;

    const ball = document.createElement(&apos;div&apos;);
    ball.className = &apos;activity-indicator&apos;;
    ball.style.width = `${ballSize}px`;
    ball.style.height = `${ballSize}px`;
    if (!activity) ball.classList.add(&apos;no-activity&apos;);
    ball.style.left = &apos;50%&apos;;
    ball.style.top = &apos;50%&apos;;
    dayContainer.appendChild(ball);

    dayContainer.addEventListener(&apos;mouseenter&apos;, () =&amp;gt; {
        if (date.toDateString() === new Date().toDateString()) {
            dateNumber.style.opacity = &apos;0&apos;;
            ball.style.opacity = &apos;1&apos;;
        } else {
            if (todayContainer) {
                todayContainer.querySelector(&apos;.date-number&apos;).style.opacity = &apos;0&apos;;
                todayContainer.querySelector(&apos;.activity-indicator&apos;).style.opacity = &apos;1&apos;;
            }
        }
    });
    dayContainer.addEventListener(&apos;mouseleave&apos;, () =&amp;gt; {
        if (date.toDateString() === new Date().toDateString()) {
            dateNumber.style.opacity = &apos;1&apos;;
            ball.style.opacity = &apos;0&apos;;
        } else {
            if (todayContainer) {
                todayContainer.querySelector(&apos;.date-number&apos;).style.opacity = &apos;1&apos;;
                todayContainer.querySelector(&apos;.activity-indicator&apos;).style.opacity = &apos;0&apos;;
            }
        }
    });

    if (date.toDateString() === new Date().toDateString()) {
        todayContainer = dayContainer;
        dayContainer.classList.add(&apos;today&apos;);
        ball.style.backgroundColor = &apos;#242428&apos;;
        dateNumber.style.color = &apos;#242428&apos;;
        dateNumber.style.opacity = &apos;1&apos;;
        ball.style.opacity = &apos;0&apos;;
    }
    return dayContainer;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%86%99%E4%B8%80%E4%B8%AA%E9%AA%91%E8%A1%8C%E9%A1%B5%E9%9D%A2(%E4%BA%8C)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-08-14-cyclingpage2&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>与时间抗衡：笔记本清灰换硅脂记</title><link>https://blog.lhasa.icu/posts/technology/2024-08-11-repaircomputer</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-08-11-repaircomputer</guid><pubDate>Sun, 11 Aug 2024 12:19:00 GMT</pubDate><content:encoded>&lt;p&gt;下午，笔记本忽然发出了咔哧咔哧的响声，仿佛是临死前的挣扎。我知道，又是哪零件坏了。大半年没清灰，这机器，似乎比人还脆弱&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181932.jpg&quot; alt=&quot;笔记本内部堆满灰尘&quot; /&gt;&lt;/p&gt;
&lt;p&gt;压CPU的螺丝多半滑丝，硅脂也是，抹得太多，溢得像过剩的腐败&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181929.jpg&quot; alt=&quot;过多的硅脂溢出&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202408111819311.jpg&quot; alt=&quot;满是灰尘的风扇&quot; /&gt;&lt;/p&gt;
&lt;p&gt;风扇拆下来时洒下许多灰尘，这风扇犹如一台无力的革命机器，快要垮掉。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181920.jpg&quot; alt=&quot;风满是灰尘的风扇&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一抹灰尘，手上黑漆漆的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202408111819321.jpg&quot; alt=&quot;满是污垢的盖板&quot; /&gt;&lt;/p&gt;
&lt;p&gt;折腾了半个小时，总算洗干净了，接下来是抹硅脂&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181919.jpg&quot; alt=&quot;清理干净，准备组装&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这硅脂还是一九年买的，小日子的信越X-23-7868-2D，导热效果还不错，不过这种产品很虚，需要时间来验证&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;d6c280f6091869e63280a500e4ef9d6.jpg&quot; alt=&quot;假一赔命&quot; /&gt;&lt;/p&gt;
&lt;p&gt;涂了不少，想压住它的病症，但心里知道，这些努力也只是苟延残喘。机器，终究是要坏的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181912.jpg&quot; alt=&quot;硅脂涂抹过多&quot; /&gt;&lt;/p&gt;
&lt;p&gt;螺丝虽然滑丝了，但还勉强拧得上。我想，我该买些新螺丝，以免将来它彻底罢工&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181909.jpg&quot; alt=&quot;安装完毕&quot; /&gt;&lt;/p&gt;
&lt;p&gt;一次点亮。这台笔记本跟了我好多年，从上学时就陪着我，现在还能跑动。除了渲染不给力，写代码倒是没问题。&lt;/p&gt;
&lt;p&gt;我觉得，电脑这东西，特别是Windows系统，得学会一些优化技巧。不然，即使配置再高，也会卡顿，这和底层设计脱不开关系，和Android有异曲同工之处。&lt;/p&gt;
&lt;p&gt;相比之下，我更喜欢Linux。之前用Manjaro Linux做主力机有四年时间。不过，Linux的图形界面BUG让我很头疼，几乎每个版本都有各种关于GUI的BUG。刚接触Linux时，最让我害怕的就是系统更新。说到这里，不得不提一下王垠&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://www.yinwang.org/blog-cn/2013/03/07/linux-windows-mac&quot; target=&quot;_blank&quot;&amp;gt;谈 Linux，Windows 和 Mac&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240811181907.jpg&quot; alt=&quot;点亮成功&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%8E%E6%97%B6%E9%97%B4%E6%8A%97%E8%A1%A1%EF%BC%9A%E7%AC%94%E8%AE%B0%E6%9C%AC%E6%B8%85%E7%81%B0%E6%8D%A2%E7%A1%85%E8%84%82%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-08-11-repaircomputer&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>写一个骑行页面</title><link>https://blog.lhasa.icu/posts/outdoors/2024-08-11-cyclingpage</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-08-11-cyclingpage</guid><pubDate>Sun, 11 Aug 2024 08:02:00 GMT</pubDate><content:encoded>&lt;p&gt;作为一个爱好骑行的博主，总觉得博客里少了点什么，骑行骑行的，怎么能没有一个专门的骑行数据展示页呢&lt;/p&gt;
&lt;p&gt;在设计这个页面的时候，参考了许多骑行APP，然而，国内的骑行数据页面设计真的是一言难尽...&lt;/p&gt;
&lt;p&gt;我骑行看数据用Strava多一些，但是它的PC端交互体验，实在不敢苟同。除了用APP版本，我几乎不会去它的网页。不得不说，国外这些骑行数据端做的确实很到位，我个人觉得数据分析方面Strava比Garmin要好！&lt;/p&gt;
&lt;h2&gt;项目结构&lt;/h2&gt;
&lt;p&gt;老规矩，先放目录结构。由于网站的主样式文件main压缩后都超160kb了，为了避免堵塞加载，新开辟一条生产线&lt;/p&gt;
&lt;p&gt;说起SCSS，还是受Fooleap的启发才接触到的，我非常喜欢这种方式，它允许嵌套CSS，让代码更加模块化、结构化，还支持变量、继承。比起传统CSS那真是有过之而无不及啊！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Blog
├─assets
│      cycling.min.css
│      cycling.min.js
│
├─pages
│      cycling.html
│
└─src
    │  cycling.js
    │  main.js
    │
    ├─cycling
    │      cycling.scss
    │      _bar-chart.scss
    │      _base.scss
    │      _calendar.scss
    │      _message-box.scss
    │      _sports.scss
    │
    └─sass
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;cycling.js&lt;/h2&gt;
&lt;p&gt;目前所有的逻辑都在这一个文件里完成，现在的功能还是个雏，因为没有打通Strava api，JSON数据是我手搓的..最近一直在搞Strava api，有好大哥懂吗？它们现在限制了每小时的请求次数，我本来就是半吊子水平，现在是雪上加霜&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &apos;./cycling/cycling.scss&apos;;

// 为了数据的统一性，generateCalendar处理后赋值供全局使用
let processedActivities = [];

// 日历
function generateCalendar(activities, startDate, numWeeks) {
    const calendarElement = document.getElementById(&apos;calendar&apos;);
    calendarElement.innerHTML = &apos;&apos;; 
    
    const daysOfWeek = [&apos;一&apos;, &apos;二&apos;, &apos;三&apos;, &apos;四&apos;, &apos;五&apos;, &apos;六&apos;, &apos;日&apos;]; 
    daysOfWeek.forEach(day =&amp;gt; {
        const dayElement = document.createElement(&apos;div&apos;);
        dayElement.className = &apos;calendar-week-header&apos;;
        dayElement.innerText = day;
        calendarElement.appendChild(dayElement);
    });

    const todayStr = getChinaTime().toISOString().split(&apos;T&apos;)[0];
    // 起始日期
    let currentDate = new Date(startDate);

    processedActivities = [];

    // 创建日历
    function createDayContainer(date, activities) {
        const dayContainer = document.createElement(&apos;div&apos;);
        dayContainer.className = &apos;day-container&apos;;

        const dateNumber = document.createElement(&apos;span&apos;);
        dateNumber.className = &apos;date-number&apos;;
        dateNumber.innerText = date.getDate();
        dayContainer.appendChild(dateNumber);

        const activity = activities.find(activity =&amp;gt; activity.activity_time === date.toISOString().split(&apos;T&apos;)[0]);
        if (activity) processedActivities.push(activity);

        // 根据骑行距离设置球的大小
        const ballSize = activity ? Math.min(parseFloat(activity.riding_distance) / 4, 24) : 2;

        const ball = document.createElement(&apos;div&apos;);
        ball.className = &apos;activity-indicator&apos;;
        ball.style.width = `${ballSize}px`;
        ball.style.height = `${ballSize}px`;
        if (!activity) ball.classList.add(&apos;no-activity&apos;);
        ball.style.left = &apos;50%&apos;;
        ball.style.top = &apos;50%&apos;;
        dayContainer.appendChild(ball);

        dayContainer.addEventListener(&apos;mouseenter&apos;, () =&amp;gt; {
            dateNumber.style.opacity = &apos;1&apos;;
            ball.style.opacity = &apos;0&apos;;
        });
        dayContainer.addEventListener(&apos;mouseleave&apos;, () =&amp;gt; {
            dateNumber.style.opacity = &apos;0&apos;;
            ball.style.opacity = &apos;1&apos;;
        });

        // 今天日期和球的颜色
        if (date.toDateString() === new Date().toDateString()) {
            dayContainer.classList.add(&apos;today&apos;);
            ball.style.backgroundColor = &apos;#2ea9df&apos;;
            dateNumber.style.color = &apos;#2ea9df&apos;;
        }

        return dayContainer;
    }

    // 异步显示，模仿打字机效果
    async function displayCalendar() {
        for (let week = 0; week &amp;lt; numWeeks; week++) {
            for (let day = 0; day &amp;lt; 7; day++) {
                const currentDateStr = currentDate.toISOString().split(&apos;T&apos;)[0];
                // 不再计算超过今天的日期
                if (currentDateStr &amp;gt; todayStr) return;

                const dayContainer = createDayContainer(currentDate, activities);
                calendarElement.appendChild(dayContainer);

                // 速度
                await new Promise(resolve =&amp;gt; setTimeout(resolve, 30));
                currentDate.setDate(currentDate.getDate() + 1);
            }
        }
    }
    displayCalendar().then(() =&amp;gt; {
        generateBarChart();
        displayTotalActivities();
    });
}

// 柱形图
function generateBarChart() {
    const barChartElement = document.getElementById(&apos;barChart&apos;);
    barChartElement.innerHTML = &apos;&apos;;

    const today = getChinaTime();
    const startDate = getStartDate(today, 21);

    // 每周数据
    const weeklyData = {};

    // 每周总活动时间
    processedActivities.forEach(activity =&amp;gt; {
        const activityDate = new Date(activity.activity_time);
        const weekStart = getWeekStartDate(activityDate);
        const weekEnd = new Date(weekStart);
        weekEnd.setDate(weekStart.getDate() + 6);

        const weekKey = `${weekStart.toISOString().split(&apos;T&apos;)[0]} - ${weekEnd.toISOString().split(&apos;T&apos;)[0]}`;
        weeklyData[weekKey] = (weeklyData[weekKey] || 0) + convertToHours(activity.moving_time);
    });

    // 最大时间
    const maxTime = Math.max(...Object.values(weeklyData), 0);

    // 创建柱形图
    Object.keys(weeklyData).forEach(week =&amp;gt; {
        const barContainer = document.createElement(&apos;div&apos;);
        barContainer.className = &apos;bar-container&apos;;

        const bar = document.createElement(&apos;div&apos;);
        bar.className = &apos;bar&apos;;
        const width = (weeklyData[week] / maxTime) * 190;
        bar.style.setProperty(&apos;--bar-width&apos;, `${width}px`);

        const durationText = document.createElement(&apos;div&apos;);
        durationText.className = &apos;bar-duration&apos;;
        durationText.innerText = &apos;0h&apos;;

        const messageBox = createMessageBox();
        const clickMessageBox = createMessageBox();

        barContainer.style.position = &apos;relative&apos;; 
        bar.appendChild(durationText);
        barContainer.appendChild(bar);
        barContainer.appendChild(messageBox);
        barContainer.appendChild(clickMessageBox);
        barChartElement.appendChild(barContainer);

        bar.style.width = &apos;0&apos;;
        bar.offsetHeight;
        // 动画效果
        bar.style.transition = &apos;width 1s ease-out&apos;;
        bar.style.width = `${width}px`;

        durationText.style.opacity = &apos;1&apos;;
        // 动态文本
        animateText(durationText, 0, weeklyData[week], 1000);
        setupBarInteractions(bar, messageBox, clickMessageBox, weeklyData[week]);
    });
}

// 动态文本显示
function animateText(element, startValue, endValue, duration) {
    const startTime = performance.now();
    function update() {
        const elapsed = performance.now() - startTime;
        const progress = Math.min(elapsed / duration, 1);
        const currentValue = Math.floor(progress * endValue);
        element.innerText = `${currentValue}h`;
        if (progress &amp;lt; 1) {
            requestAnimationFrame(update);
        } else {
            element.innerText = `${endValue.toFixed(1)}h`;
        }
    }
    update();
}

// 计算总公里数
function calculateTotalKilometers(activities) {
    return activities.reduce((total, activity) =&amp;gt; total + parseFloat(activity.riding_distance) || 0, 0);
}

// 显示总活动数和总公里数
function displayTotalActivities() {
    const totalCountElement = document.getElementById(&apos;totalCount&apos;);
    const totalDistanceElement = document.getElementById(&apos;totalDistance&apos;);

    if (!totalCountElement || !totalDistanceElement) return;

    const totalCountValue = totalCountElement.querySelector(&apos;#totalCountValue&apos;);
    const totalDistanceValue = totalDistanceElement.querySelector(&apos;#totalDistanceValue&apos;);

    const totalCountSpinner = totalCountElement.querySelector(&apos;.loading-spinner&apos;);
    const totalDistanceSpinner = totalDistanceElement.querySelector(&apos;.loading-spinner&apos;);

    totalCountSpinner.classList.add(&apos;active&apos;);
    totalDistanceSpinner.classList.add(&apos;active&apos;);

    const uniqueDays = new Set(processedActivities.map(activity =&amp;gt; activity.activity_time));
    const totalCount = uniqueDays.size;
    const totalKilometers = calculateTotalKilometers(processedActivities);

    animateCount(totalCountValue, totalCount, 1000, 50);
    animateCount(totalDistanceValue, totalKilometers, 1000, 50, true);

    setTimeout(() =&amp;gt; {
        totalDistanceValue.textContent = `${totalKilometers.toFixed(2)} km`;
        totalCountSpinner.classList.remove(&apos;active&apos;);
        totalDistanceSpinner.classList.remove(&apos;active&apos;);
    }, 1000);
}

// 获取一周的开始日期
function getWeekStartDate(date) {
    const day = date.getDay();
    const diff = (day === 0 ? -6 : 1) - day;
    const weekStart = new Date(date);
    weekStart.setDate(weekStart.getDate() + diff);
    return weekStart;
}

// 将JSON的时间数据转换为小时
function convertToHours(moving_time) {
    const [hours, minutes] = moving_time.split(&apos;:&apos;).map(Number);
    return hours + (minutes / 60);
}

// 博客托管Github Pages需要中国时间
function getChinaTime() {
    const now = new Date();
    const offset = 8 * 60 * 60 * 1000;
    return new Date(now.getTime() + offset);
}

// 手搓JSON
async function loadActivityData() {
    const response = await fetch(&apos;XXXXXX&apos;);
    return response.json();
}

(async function() {
    const today = getChinaTime();
    const startDate = getStartDate(today, 21);

    const activities = await loadActivityData();
    generateCalendar(activities, startDate, 4);
})();

// 创建消息盒子
function createMessageBox() {
    const messageBox = document.createElement(&apos;div&apos;);
    messageBox.className = &apos;message-box&apos;;
    return messageBox;
}

// 获取起始时间
function getStartDate(today, daysOffset) {
    const currentDayOfWeek = today.getDay();
    const daysToMonday = (currentDayOfWeek === 0 ? 6 : currentDayOfWeek - 1); 
    const startDate = new Date(today);
    startDate.setDate(today.getDate() - daysToMonday - daysOffset); 
    startDate.setDate(startDate.getDate() - (startDate.getDay() === 0 ? 6 : startDate.getDay() - 1)); 
    return startDate;
}

// 动态更新计数器
function animateCount(element, totalValue, duration, intervalDuration, isDistance = false) {
    const step = totalValue / (duration / intervalDuration);
    let count = 0;
    const interval = setInterval(() =&amp;gt; {
        count += step;
        if (count &amp;gt;= totalValue) {
            count = totalValue;
            clearInterval(interval);
        }
        element.textContent = isDistance ? count.toFixed(2) : Math.round(count);
    }, intervalDuration);
}

// 骚话集合
function setupBarInteractions(bar, messageBox, clickMessageBox, weeklyData) {
    let mouseLeaveTimeout;
    let autoHideTimeout;

    bar.addEventListener(&apos;mouseenter&apos;, () =&amp;gt; {
        clearTimeout(mouseLeaveTimeout);
        clearTimeout(autoHideTimeout);

        const message = weeklyData &amp;gt; 14 ? &apos;这周干的还不错&apos; : &apos;偷懒了啊&apos;;
        messageBox.innerText = message;
        messageBox.classList.add(&apos;show&apos;);

        autoHideTimeout = setTimeout(() =&amp;gt; {
            messageBox.classList.remove(&apos;show&apos;);
        }, 700);
    });

    bar.addEventListener(&apos;mouseleave&apos;, () =&amp;gt; {
        mouseLeaveTimeout = setTimeout(() =&amp;gt; {
            messageBox.classList.remove(&apos;show&apos;);
        }, 700);
    });

    bar.addEventListener(&apos;click&apos;, () =&amp;gt; {
        clickMessageBox.innerText = &apos;一起来运动吧！&apos;;
        clickMessageBox.classList.add(&apos;show&apos;);
        setTimeout(() =&amp;gt; {
            clickMessageBox.classList.remove(&apos;show&apos;);
        }, 700);

        messageBox.classList.remove(&apos;show&apos;);
        clearTimeout(mouseLeaveTimeout);
        clearTimeout(autoHideTimeout);
    });
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;cycling.scss&lt;/h2&gt;
&lt;p&gt;骑行统计页面不会止步于此，接下来还会有很大的延申改动，我提前把变量接口留好了，定义了一些主样式变量，SCSS模块化继承了一些基础样式，二次开发会轻松很多&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// 总次数和总距离字体
$primary-color: #2ea9df;
// 柱状图字体
$gray-color: #333;
// 柱状图颜色
$light-gray-color: #EBE6F2;
// 柱状图边框
$light-gray-border-color: #DFD7E9;
// 未活动日历
$no-activity-color: gray;
//------ 分类色
// 公路车
$cycling-color: #EBE6F2;
$cycling-border-color: #DFD7E9; 
// 跑步
$running-color: #D5E5D3;
$running-border-color: #BDD6BA;
// 背景和文本颜色
$background-color: #333;
$text-color: #fff;

@import &apos;base&apos;;
@import &apos;calendar&apos;;
@import &apos;bar-chart&apos;;
@import &apos;sports&apos;;
@import &apos;message-box&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;webpack配置&lt;/h2&gt;
&lt;p&gt;html和scss没啥好看的，配置一下收工&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;const path = require(&apos;path&apos;);
const MiniCssExtractPlugin = require(&apos;mini-css-extract-plugin&apos;);
const CssMinimizerPlugin = require(&apos;css-minimizer-webpack-plugin&apos;);
const TerserPlugin = require(&apos;terser-webpack-plugin&apos;);

module.exports = {
    mode: &apos;production&apos;,
    entry: {
        main: path.resolve(__dirname, &apos;src/main.js&apos;),
        cycling: path.resolve(__dirname, &apos;src/cycling.js&apos;),
    },
    output: {
        path: path.resolve(__dirname, &apos;assets&apos;),
        filename: &apos;[name].min.js&apos;,
        publicPath: &apos;/&apos;
    },
    stats: {
        entrypoints: false,
        children: false
    },
    module: {
        rules: [
            {
                test: /\.(scss|css)$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    &apos;css-loader&apos;,
                    &apos;postcss-loader&apos;,
                    &apos;sass-loader&apos;
                ]
            },
            {
                test: /\.html$/,
                use: [&apos;html-loader&apos;]
            }
        ],
    },
    resolve: {
        alias: {
            &apos;iDisqus.css&apos;: &apos;disqus-php-api/dist/iDisqus.css&apos;,
        }
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: &apos;[name].min.css&apos;
        })
    ],
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                parallel: true
            }),
            new CssMinimizerPlugin()
        ],
    }
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;效果&lt;/h2&gt;
&lt;p&gt;Fooleap的博客真的是相当不错，我特别喜欢他写的Jekyll主题，还有很大的折腾空间，比如全站PJAX、懒加载等等&lt;/p&gt;
&lt;p&gt;这一周，我也着手用JQuery重新了写整站，完事后感觉真傻逼了，属于画蛇添足，多此一举。毕竟小站点，拖着一个磨盘挺累的。不上国内服务器的话，原生这条路死磕到底了，不过PJAX是必须要上的，预计下星期全站PJAX、懒加载上线&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;6ebf4b151477aacd7908d80dad937a91.png&quot; alt=&quot;初稿&quot; /&gt;&lt;/p&gt;
&lt;p&gt;骑行：&lt;a href=&quot;https://lhasa.icu/cycling.html&quot;&gt;https://lhasa.icu/cycling.html&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%86%99%E4%B8%80%E4%B8%AA%E9%AA%91%E8%A1%8C%E9%A1%B5%E9%9D%A2&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-08-11-cyclingpage&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>写一个Chrome表单自动化插件</title><link>https://blog.lhasa.icu/posts/technology/2024-08-07-formautomationplugin</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-08-07-formautomationplugin</guid><pubDate>Wed, 07 Aug 2024 06:26:00 GMT</pubDate><content:encoded>&lt;p&gt;在刷博客的时候，最麻烦的事情之一就是手动填写各种表单。为了提高我的冲浪体验，诞生了这款表单自动化插件。经过爬虫上百次调教，兼容95%博客，另外5%的网站正常人写不出来，autocomplete小伎俩都上不了台面，各种防止逆向、防调试测试，心累。&lt;/p&gt;
&lt;h2&gt;项目结构&lt;/h2&gt;
&lt;p&gt;插件纯绿色，无隐私可言。除images外，全部资源和代码文件都经过Webpack打包，下面是项目的目录结构以及各部分的说明：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Form-automation-plugin
│  index.html
│  LICENSE
│  manifest.json
│  package-lock.json
│  package.json
│  README.md
│  webpack.config.js
│  
├─dist
│      33a80cb13f78b37acb39.woff2
│      8093dd36a9b1ec918992.ttf
│      8521c461ad88443142d9.woff
│      autoFill.min.js
│      eventHandler.min.js
│      formManager.min.js
│      main.min.css
│
└─src
    │  autoFill.js
    │  eventHandler.js
    │  formManager.js
    │  template.css
    │  template.html
    │
    ├─fonts
    │      iconfont.css
    │      iconfont.ttf
    │      iconfont.woff
    │      iconfont.woff2
    │
    └─images
            Appreciation-code.jpg
            icon128.png
            icon16.png
            icon48.png
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;webpack.config.js&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;const path = require(&apos;path&apos;);
const MiniCssExtractPlugin = require(&apos;mini-css-extract-plugin&apos;);
const HtmlWebpackPlugin = require(&apos;html-webpack-plugin&apos;);

module.exports = {
  entry: {
    autoFill: &apos;./src/autoFill.js&apos;,
    eventHandler: &apos;./src/eventHandler.js&apos;,
    formManager: &apos;./src/formManager.js&apos;,
  },
  output: {
    filename: &apos;[name].min.js&apos;,
    path: path.resolve(__dirname, &apos;dist&apos;),
    clean: true,
  },
  mode: &apos;production&apos;,
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          &apos;css-loader&apos;,
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: &apos;main.min.css&apos;,
    }),
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, &apos;src&apos;, &apos;template.html&apos;),
      filename: &apos;../index.html&apos;,
      inject: &apos;body&apos;,
    }),
  ],
  resolve: {
    extensions: [&apos;.js&apos;, &apos;.css&apos;],
  },
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;autoFill.js&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// autoFill.js文件是插件的最重要的核心模块，涉及到了插件的主要输出功能
// 遍历当前页面所有input，将autocomplete值设置为on，监听Textarea输入时触发
function handleAutocomplete() {
  const inputs = document.querySelectorAll(&apos;input&apos;);
  inputs.forEach(input =&amp;gt; {
    const autocompleteAttr = input.getAttribute(&apos;autocomplete&apos;);
    if (autocompleteAttr) {
      input.setAttribute(&apos;autocomplete&apos;, &apos;on&apos;);
    } else {
      input.setAttribute(&apos;autocomplete&apos;, &apos;on&apos;);
    }
  });
}

// 这个函数有些臃肿，马上要去骑车，懒得搞了，现在的逻辑已经完善到9成了，大多数意外情况都卷了进去，但是一些防逆向防调试，我暂时无法解决，前端菜鸟，还望大哥指点一二
function fillInputFields() {
  chrome.storage.sync.get([&quot;name&quot;, &quot;email&quot;, &quot;url&quot;], (data) =&amp;gt; {
    // console.log(data);

    const hasValidName = data.name !== undefined &amp;amp;&amp;amp; data.name !== &quot;&quot;;
    const hasValidEmail = data.email !== undefined &amp;amp;&amp;amp; data.email !== &quot;&quot;;
    const hasValidUrl = data.url !== undefined &amp;amp;&amp;amp; data.url !== &quot;&quot;;

    // 关键字
    const nameKeywords = [
      &quot;name&quot;, &quot;author&quot;, &quot;display_name&quot;, &quot;full-name&quot;, &quot;username&quot;, &quot;nick&quot;, &quot;displayname&quot;, 
      &quot;first-name&quot;, &quot;last-name&quot;, &quot;full name&quot;, &quot;real-name&quot;, &quot;given-name&quot;, 
      &quot;family-name&quot;, &quot;user-name&quot;, &quot;pen-name&quot;, &quot;alias&quot;, &quot;name-field&quot;, &quot;displayname&quot;
    ];
    const emailKeywords = [
      &quot;email&quot;, &quot;mail&quot;, &quot;contact&quot;, &quot;emailaddress&quot;, &quot;mailaddress&quot;, 
      &quot;email-address&quot;, &quot;mail-address&quot;, &quot;email-addresses&quot;, &quot;mail-addresses&quot;, 
      &quot;emailaddresses&quot;, &quot;mailaddresses&quot;, &quot;contactemail&quot;, &quot;useremail&quot;, 
      &quot;contact-email&quot;, &quot;user-mail&quot;
    ];
    const urlKeywords = [
      &quot;url&quot;, &quot;link&quot;, &quot;website&quot;, &quot;homepage&quot;, &quot;site&quot;, &quot;web&quot;, &quot;address&quot;, 
      &quot;siteurl&quot;, &quot;webaddress&quot;, &quot;homepageurl&quot;, &quot;profile&quot;, &quot;homepage-link&quot;
    ];

    const inputs = document.querySelectorAll(&quot;input, textarea&quot;);

    inputs.forEach((input) =&amp;gt; {
      const typeAttr = input.getAttribute(&quot;type&quot;)?.toLowerCase() || &quot;&quot;;
      const nameAttr = input.getAttribute(&quot;name&quot;)?.toLowerCase() || &quot;&quot;;
      let valueToSet = &quot;&quot;;

      // 处理 URL
      if (urlKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
        if (hasValidUrl) {
          valueToSet = data.url;
        }
      }
      // 处理邮箱
      else if (emailKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
        if (hasValidEmail) {
          valueToSet = data.email;
        }
      }
      // 处理名称
      else if (nameKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
        if (hasValidName) {
          valueToSet = data.name;
        }
      }

      // 处理没有 type 属性或者 type 为 text 的情况
      if ((typeAttr === &quot;&quot; || typeAttr === &quot;text&quot;) &amp;amp;&amp;amp; valueToSet === &quot;&quot;) {
        if (nameAttr &amp;amp;&amp;amp; nameKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
          if (hasValidName) {
            valueToSet = data.name;
          }
        } else if (nameAttr &amp;amp;&amp;amp; urlKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
          if (hasValidUrl) {
            valueToSet = data.url;
          }
        }
      }

      // 处理 type 为 email
      if (typeAttr === &quot;email&quot; &amp;amp;&amp;amp; valueToSet === &quot;&quot;) {
        if (nameAttr &amp;amp;&amp;amp; emailKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
          if (hasValidEmail) {
            valueToSet = data.email;
          }
        }
      }

      // 处理 type 为 url
      if (typeAttr === &quot;url&quot; &amp;amp;&amp;amp; valueToSet === &quot;&quot;) {
        if (nameAttr &amp;amp;&amp;amp; urlKeywords.some(keyword =&amp;gt; nameAttr.includes(keyword))) {
          if (hasValidUrl) {
            valueToSet = data.url;
          }
        }
      }

      // 填充输入字段
      if (valueToSet !== &quot;&quot;) {
        input.value = valueToSet;
      }
    });
  });
}

function clearInputFields() {
  const inputs = document.querySelectorAll(&quot;input&quot;);
  inputs.forEach((input) =&amp;gt; {
    const typeAttr = input.getAttribute(&quot;type&quot;)?.toLowerCase();
    if (typeAttr === &quot;text&quot; || typeAttr === &quot;email&quot;) {
      input.value = &quot;&quot;;
    }
  });
}

// 监听 textarea 标签的输入事件
document.addEventListener(&quot;input&quot;, (event) =&amp;gt; {
  if (event.target.tagName.toLowerCase() === &quot;textarea&quot;) {
    handleAutocomplete();
    fillInputFields();
  }
});
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;formManager.js&lt;/h2&gt;
&lt;p&gt;该文件负责向Chrome本地存储和修改，就CURD，没啥含量&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &apos;./fonts/iconfont.css&apos;;
import &apos;./template.css&apos;;

document.getElementById(&quot;save&quot;).addEventListener(&quot;click&quot;, () =&amp;gt; {
  const saveButton = document.getElementById(&quot;save&quot;);
  if (saveButton.textContent === &quot;更改&quot;) {
    unlockInputFields();
    changeButtonText(&quot;保存&quot;);
    return;
  }

  const name = document.getElementById(&quot;name&quot;).value.trim();
  const email = document.getElementById(&quot;email&quot;).value.trim();
  const url = document.getElementById(&quot;url&quot;).value.trim();

  // 验证邮箱格式的正则表达式
  const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (name === &quot;&quot; || email === &quot;&quot;) {
    alert(&quot;请填写必填字段：姓名和邮箱!&quot;);
    return;
  }

  if (!emailPattern.test(email)) {
    alert(&quot;请输入有效的邮箱地址!&quot;);
    return;
  }

  // 从 Chrome 存储中读取当前的值
  chrome.storage.sync.get([&quot;name&quot;, &quot;email&quot;, &quot;url&quot;], (data) =&amp;gt; {
    const isNameAndEmailChanged = name !== data.name || email !== data.email;
    const isUrlChanged = url !== data.url;

    if (isNameAndEmailChanged || isUrlChanged) {
      chrome.storage.sync.set({ name, email, url }, () =&amp;gt; {
        lockInputFields();
        changeButtonText(&quot;更改&quot;);
      });
    } else {
      lockInputFields();
      changeButtonText(&quot;更改&quot;);
    }
  });
});

// 页面加载完成时执行
document.addEventListener(&quot;DOMContentLoaded&quot;, () =&amp;gt; {
  chrome.storage.sync.get([&quot;name&quot;, &quot;email&quot;, &quot;url&quot;], (data) =&amp;gt; {
    document.getElementById(&quot;name&quot;).value = data.name || &quot;&quot;;
    document.getElementById(&quot;email&quot;).value = data.email || &quot;&quot;;
    document.getElementById(&quot;url&quot;).value = data.url || &quot;&quot;;

    if (data.name || data.email || data.url) {
      lockInputFields();
      changeButtonText(&quot;更改&quot;);
    }
  });

  const menuItems = document.querySelectorAll(&apos;.dl-menu li a&apos;);
  const tabContents = document.querySelectorAll(&apos;.tab-content&apos;);

  menuItems.forEach(menuItem =&amp;gt; {
    menuItem.addEventListener(&apos;click&apos;, (event) =&amp;gt; {
      event.preventDefault();
      tabContents.forEach(tab =&amp;gt; tab.classList.remove(&apos;active&apos;));
      const targetId = menuItem.getAttribute(&apos;href&apos;).substring(1);
      document.getElementById(targetId).classList.add(&apos;active&apos;);
      menuItems.forEach(item =&amp;gt; item.parentElement.classList.remove(&apos;active&apos;));
      menuItem.parentElement.classList.add(&apos;active&apos;);
    });
  });
});

// 锁定输入框
function lockInputFields() {
  document.getElementById(&quot;name&quot;).setAttribute(&quot;disabled&quot;, &quot;true&quot;);
  document.getElementById(&quot;email&quot;).setAttribute(&quot;disabled&quot;, &quot;true&quot;);
  document.getElementById(&quot;url&quot;).setAttribute(&quot;disabled&quot;, &quot;true&quot;);
}

// 解锁输入框
function unlockInputFields() {
  document.getElementById(&quot;name&quot;).removeAttribute(&quot;disabled&quot;);
  document.getElementById(&quot;email&quot;).removeAttribute(&quot;disabled&quot;);
  document.getElementById(&quot;url&quot;).removeAttribute(&quot;disabled&quot;);
}

// 更改按钮文本
function changeButtonText(text) {
  document.getElementById(&quot;save&quot;).textContent = text;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;使用方法&lt;/h2&gt;
&lt;p&gt;git clone到本地，浏览器打开：chrome://extensions/，加载已解压的扩展程序&lt;/p&gt;
&lt;p&gt;由于我没有注册Chrome应用商店开发者，目前只能本地运行，过几天上线应用商店，Tampermonkey等骑车回来再做&lt;/p&gt;
&lt;h2&gt;Github&lt;/h2&gt;
&lt;p&gt;Form-automation-plugin：&amp;lt;a href=&quot;https://github.com/achuanya/Form-automation-plugin&quot; target=&quot;_blank&quot;&amp;gt;https://github.com/achuanya/Form-automation-plugin&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%86%99%E4%B8%80%E4%B8%AAChrome%E8%A1%A8%E5%8D%95%E8%87%AA%E5%8A%A8%E5%8C%96%E6%8F%92%E4%BB%B6&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-08-07-formautomationplugin&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>七月最后一天骑行，有氧100公里</title><link>https://blog.lhasa.icu/posts/outdoors/2024-08-01-ridingonthelastdayofjuly</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-08-01-ridingonthelastdayofjuly</guid><pubDate>Wed, 31 Jul 2024 17:37:00 GMT</pubDate><content:encoded>&lt;p&gt;今天是七月的最后一天，晚上必须来一次有氧小长途骑行，目标暂且定为100公里&lt;/p&gt;
&lt;p&gt;出发前，先泡两瓶蛋白粉放进冰箱，一瓶550ML，一瓶750ML，我还是觉得不够用。骑车过程中不想下来，容易打断节奏。我打算坐尾再安装一个支架放一瓶750ML，只要室外温度不是特变态，百里油耗三瓶水没有问题。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;b83067a2ea7c373071f84295883919c.jpg&quot; alt=&quot;奥普帝蒙 黑标分离乳清蛋白粉&quot; /&gt;&lt;/p&gt;
&lt;p&gt;检查一下前变、后拨、夹气和胎压。前胎由于自补液在气嘴处凝固，导致无法打气，不过目前胎压足够，不影响骑行，估计再骑一周胎压就不行了，由于管胎的特殊结构，我还没有合适的解决方案，除了换胎。&lt;/p&gt;
&lt;p&gt;下午喝了两碗绿豆粥，吃了些核桃饼，开始做最后的准备，带了两件便携式螺丝刀，一小包纸巾，一包干湿巾，一包电解质盐丸，这些正好放进后尾包，占了大概60%空间，剩余空间还能放盒烟。&lt;/p&gt;
&lt;p&gt;衣服就没啥好挑的，穿条ASSOS背带裤和速白干背心就行了，如果不是为了注意个人形象，我直接背带裤光膀子。在上海生活的时候也特热，多次骑行都是背带裤光膀子，有两次路过外滩被交警抓了，说外滩都是游客，我个人形象影响市容。&lt;/p&gt;
&lt;p&gt;到地方了，这骑行路段是挺不错的，我有七年没来这里了，今天来到这里发现大变样了，还可以租皮划艇，改天一定玩玩。在这里绕圈骑了十五公里，又跑去周口公园绕圈，要说这夏天油耗确实高，机动车顶不住，人也顶不住啊！我的水有点不够了，今天才33°，河南的热和江浙沪的热真是不一样，回家后一直不适应，出公园后去蜜雪冰城买了一杯柠檬水，找店里的小妹妹白嫖了两瓶冰水，直奔淮阳区·龙湖&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;8aaee2d611764e6819dd41df4788121.jpg&quot; alt=&quot;周口植物园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;到龙湖后里程已经到了60公里，这时天也暗了，有些许疲惫，主要是颈椎疼，下把位骑多了。吃了两片盐丸，两手握把立边缘慢骑摆烂二十分钟，这个时候一定不能下来歇，推车都不行，下车体力直接归零，不知道别人咋样，我是这样的，与自己较劲，100公里？200公里又算个屁，出来了，就要干&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;abba2d44d1190120eb9a7ba9c40ad0c.jpg&quot; alt=&quot;奶奶煮的绿豆粥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在龙湖绕了三圈后达标，真是饿得不行了。到家已经十点，浑身湿透，黏糊糊的，洗了澡，洗了衣服，然后躺下看订阅，期待八月的骑行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;fb05cdae97a73fb17da66efc2bde383.jpg&quot; alt=&quot;今日有氧100公里完成&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%83%E6%9C%88%E6%9C%80%E5%90%8E%E4%B8%80%E5%A4%A9%E9%AA%91%E8%A1%8C%EF%BC%8C%E6%9C%89%E6%B0%A7100%E5%85%AC%E9%87%8C&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-08-01-ridingonthelastdayofjuly&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>利用Go+Github Actions写个定时RSS爬虫</title><link>https://blog.lhasa.icu/posts/technology/2024-07-27-grablatestrss</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-07-27-grablatestrss</guid><pubDate>Sat, 27 Jul 2024 01:50:00 GMT</pubDate><content:encoded>&lt;p&gt;说起这事，还是受一位博友的启发&amp;lt;a href=&quot;https://1900.live/links&quot; target=&quot;_blank&quot;&amp;gt;“1900”&amp;lt;/a&amp;gt;他的左邻右舍页面很棒，决定模仿一下&lt;/p&gt;
&lt;p&gt;起初，我打算使用 COS 和 GitHub Actions，但在测试过程中发现 GitHub 的延迟非常高，验证和文件写入速度极慢，频频失败。干脆直接上 GitHub 自产自销。&lt;/p&gt;
&lt;h2&gt;大致思路&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;main()
│
├── readFeedsFromGitHub()
│   ├── GitHub API 调用
│   │   ├── 读取 rss_feeds.txt 文件
│   │   └── 处理文件报错
│   └── Return
│
├── fetchRSS()
│   ├── 遍历 RSS
│   │   ├── HTTP GET 请求
│   │   └── 处理请求错误
│   ├── 解析 RSS
│   │   ├── 清理 XML 内容中的非法字符
│   │   ├── 提取域名
│   │   └── 格式化并排序
│   └── Return
│
└── saveToGitHub()
    ├── GitHub API 调用
    │   ├── 保存到 _data/rss_data.json 供 Jekyll 调用
    │   └── 处理错误
    └── Return
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;由于用 Go 搬砖，所有的包、类型和方法均可在 GitHub API 客户端库的第 39 版文档查询&lt;/p&gt;
&lt;p&gt;关于 Github API 有一点需要注意，配置好环境变量后，Token 操作仓库需要有一定的权限，务必启用 Read and write permissions 读取和写入权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;go mod init github.com/achuanya/Grab-latest-RSS
// Go-GitHub v39
go get github.com/google/go-github/v39/github
// RSS 和 Atom feeds 解析库
go get github.com/mmcdole/gofeed
// OAuth2 认证和授权
go get golang.org/x/oauth2
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Go RSS 爬虫 Code&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;bufio&quot;
	&quot;bytes&quot;
	&quot;context&quot;
	&quot;encoding/json&quot;
	&quot;fmt&quot;
	&quot;net/http&quot;
	&quot;net/url&quot;
	&quot;os&quot;
	&quot;regexp&quot;
	&quot;sort&quot;
	&quot;sync&quot;
	&quot;time&quot;

	&quot;github.com/google/go-github/v39/github&quot;
	&quot;github.com/mmcdole/gofeed&quot;
	&quot;golang.org/x/oauth2&quot;
)

const (
	maxRetries    = 3                // 最大重试次数
	retryInterval = 10 * time.Second // 重试间隔时间
)

type Config struct {
	GithubToken      string // GitHub API 令牌
	GithubName       string // GitHub 用户名
	GithubRepository string // GitHub 仓库名
}

// 用于解析 avatar_data.json 文件的结构
type Avatar struct {
	Name   string `json:&quot;name&quot;`   // 用户名
	Avatar string `json:&quot;avatar&quot;` // 头像 URL
}

// 爬虫抓取的数据结构
type Article struct {
	DomainName string `json:&quot;domainName&quot;` // 域名
	Name       string `json:&quot;name&quot;`       // 博客名称
	Title      string `json:&quot;title&quot;`      // 文章标题
	Link       string `json:&quot;link&quot;`       // 文章链接
	Date       string `json:&quot;date&quot;`       // 格式化后的文章发布时间
	Avatar     string `json:&quot;avatar&quot;`     // 头像 URL
}

// 初始化并返回配置信息
func initConfig() Config {
	return Config{
		GithubToken:      os.Getenv(&quot;TOKEN&quot;), // 从环境变量中获取 GitHub API 令牌
		GithubName:       &quot;achuanya&quot;,         // GitHub 用户名
		GithubRepository: &quot;lhasa.github.io&quot;,  // GitHub 仓库名
	}
}

// 清理 XML 内容中的非法字符
func cleanXMLContent(content string) string {
	re := regexp.MustCompile(`[\x00-\x1F\x7F-\x9F]`)
	return re.ReplaceAllString(content, &quot;&quot;)
}

// 尝试解析不同格式的时间字符串
func parseTime(timeStr string) (time.Time, error) {
	formats := []string{
		time.RFC3339,
		time.RFC3339Nano,
		time.RFC1123Z,
		time.RFC1123,
	}

	for _, format := range formats {
		if t, err := time.Parse(format, timeStr); err == nil {
			return t, nil
		}
	}
	return time.Time{}, fmt.Errorf(&quot;unable to parse time: %s&quot;, timeStr)
}

// 将时间格式化为 &quot;January 2, 2006&quot;
func formatTime(t time.Time) string {
	return t.Format(&quot;January 2, 2006&quot;)
}

// 从 URL 中提取域名，并添加 https:// 前缀
func extractDomain(urlStr string) (string, error) {
	u, err := url.Parse(urlStr)
	if err != nil {
		return &quot;&quot;, err
	}
	domain := u.Hostname()
	protocol := &quot;https://&quot;
	if u.Scheme != &quot;&quot; {
		protocol = u.Scheme + &quot;://&quot;
	}
	fullURL := protocol + domain

	return fullURL, nil
}

// 获取当前的北京时间
func getBeijingTime() time.Time {
	beijingTimeZone := time.FixedZone(&quot;CST&quot;, 8*3600)
	return time.Now().In(beijingTimeZone)
}

// 记录错误信息到 error.log 文件
func logError(config Config, message string) {
	logMessage(config, message, &quot;error.log&quot;)
}

// 记录信息到指定的文件
func logMessage(config Config, message string, fileName string) {
	ctx := context.Background()
	client := github.NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&amp;amp;oauth2.Token{
		AccessToken: config.GithubToken,
	})))

	filePath := &quot;_data/&quot; + fileName
	fileContent := []byte(message + &quot;\n\n&quot;)

	file, _, resp, err := client.Repositories.GetContents(ctx, config.GithubName, config.GithubRepository, filePath, nil)
	if err != nil &amp;amp;&amp;amp; resp.StatusCode == http.StatusNotFound {
		_, _, err := client.Repositories.CreateFile(ctx, config.GithubName, config.GithubRepository, filePath, &amp;amp;github.RepositoryContentFileOptions{
			Message: github.String(&quot;Create &quot; + fileName),
			Content: fileContent,
			Branch:  github.String(&quot;master&quot;),
		})
		if err != nil {
			fmt.Printf(&quot;error creating %s in GitHub: %v\n&quot;, fileName, err)
		}
		return
	} else if err != nil {
		fmt.Printf(&quot;error checking %s in GitHub: %v\n&quot;, fileName, err)
		return
	}

	decodedContent, err := file.GetContent()
	if err != nil {
		fmt.Printf(&quot;error decoding %s content: %v\n&quot;, fileName, err)
		return
	}

	updatedContent := append([]byte(decodedContent), fileContent...)

	_, _, err = client.Repositories.UpdateFile(ctx, config.GithubName, config.GithubRepository, filePath, &amp;amp;github.RepositoryContentFileOptions{
		Message: github.String(&quot;Update &quot; + fileName),
		Content: updatedContent,
		SHA:     github.String(*file.SHA),
		Branch:  github.String(&quot;master&quot;),
	})
	if err != nil {
		fmt.Printf(&quot;error updating %s in GitHub: %v\n&quot;, fileName, err)
	}
}

// 从 GitHub 仓库中获取 JSON 文件内容
func fetchFileFromGitHub(config Config, filePath string) (string, error) {
	ctx := context.Background()
	client := github.NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&amp;amp;oauth2.Token{
		AccessToken: config.GithubToken,
	})))

	file, _, resp, err := client.Repositories.GetContents(ctx, config.GithubName, config.GithubRepository, filePath, nil)
	if err != nil {
		if resp.StatusCode == http.StatusNotFound {
			return &quot;&quot;, fmt.Errorf(&quot;file not found: %s&quot;, filePath)
		}
		return &quot;&quot;, fmt.Errorf(&quot;error fetching file %s from GitHub: %v&quot;, filePath, err)
	}

	content, err := file.GetContent()
	if err != nil {
		return &quot;&quot;, fmt.Errorf(&quot;error decoding file %s content: %v&quot;, filePath, err)
	}

	return content, nil
}

// 从 GitHub 仓库中读取头像配置
func loadAvatarsFromGitHub(config Config) (map[string]string, error) {
	content, err := fetchFileFromGitHub(config, &quot;_data/avatar_data.json&quot;)
	if err != nil {
		return nil, err
	}

	var avatars []Avatar
	if err := json.Unmarshal([]byte(content), &amp;amp;avatars); err != nil {
		return nil, err
	}

	avatarMap := make(map[string]string)
	for _, a := range avatars {
		avatarMap[a.Name] = a.Avatar
	}

	return avatarMap, nil
}

// 从 RSS 列表中抓取最新的文章，并按发布时间排序
func fetchRSS(config Config, feeds []string) ([]Article, error) {
	var articles []Article
	var mu sync.Mutex     // 用于保证并发安全
	var wg sync.WaitGroup // 用于等待所有 goroutine 完成

	avatars, err := loadAvatarsFromGitHub(config)
	if err != nil {
		logError(config, fmt.Sprintf(&quot;[%s] [Load avatars error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), err))
		return nil, err
	}

	fp := gofeed.NewParser()
	httpClient := &amp;amp;http.Client{
		Timeout: 10 * time.Second,
	}

	for _, feedURL := range feeds {
		wg.Add(1)
		go func(feedURL string) {
			defer wg.Done()
			var resp *http.Response
			var bodyString string
			var fetchErr error

			for i := 0; i &amp;lt; maxRetries; i++ {
				resp, fetchErr = httpClient.Get(feedURL)
				if fetchErr == nil {
					bodyBytes := new(bytes.Buffer)
					bodyBytes.ReadFrom(resp.Body)
					bodyString = bodyBytes.String()
					resp.Body.Close()
					break
				}
				logError(config, fmt.Sprintf(&quot;[%s] [Get RSS error] %s: Attempt %d/%d: %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), feedURL, i+1, maxRetries, fetchErr))
				time.Sleep(retryInterval)
			}

			if fetchErr != nil {
				logError(config, fmt.Sprintf(&quot;[%s] [Failed to fetch RSS] %s: %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), feedURL, fetchErr))
				return
			}

			cleanBody := cleanXMLContent(bodyString)

			var feed *gofeed.Feed
			var parseErr error
			for i := 0; i &amp;lt; maxRetries; i++ {
				feed, parseErr = fp.ParseString(cleanBody)
				if parseErr == nil {
					break
				}
				logError(config, fmt.Sprintf(&quot;[%s] [Parse RSS error] %s: Attempt %d/%d: %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), feedURL, i+1, maxRetries, parseErr))
				time.Sleep(retryInterval)
			}

			if parseErr != nil {
				logError(config, fmt.Sprintf(&quot;[%s] [Failed to parse RSS] %s: %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), feedURL, parseErr))
				return
			}

			mainSiteURL := feed.Link
			domainName, err := extractDomain(mainSiteURL)
			if err != nil {
				logError(config, fmt.Sprintf(&quot;[%s] [Extract domain error] %s: %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), mainSiteURL, err))
				domainName = &quot;unknown&quot;
			}

			name := feed.Title
			avatarURL := avatars[name]
			if avatarURL == &quot;&quot; {
				avatarURL = &quot;https://cos.lhasa.icu/LinksAvatar/default.png&quot;
			}

			if len(feed.Items) &amp;gt; 0 {
				item := feed.Items[0]

				publishedTime, err := parseTime(item.Published)
				if err != nil &amp;amp;&amp;amp; item.Updated != &quot;&quot; {
					publishedTime, err = parseTime(item.Updated)
				}

				if err != nil {
					logError(config, fmt.Sprintf(&quot;[%s] [Getting article time error] %s: %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), item.Title, err))
					publishedTime = time.Now()
				}

				originalName := feed.Title
				// 该长的地方短，该短的地方长
				nameMapping := map[string]string{
					&quot;obaby@mars&quot;: &quot;obaby&quot;,
					&quot;青山小站 | 一个在帝都搬砖的新时代农民工&quot;:       &quot;青山小站&quot;,
					&quot;Homepage on Miao Yu | 于淼&quot;:    &quot;于淼&quot;,
					&quot;Homepage on Yihui Xie | 谢益辉&quot;: &quot;谢益辉&quot;,
				}

				validNames := make(map[string]struct{})
				for key := range nameMapping {
					validNames[key] = struct{}{}
				}

				_, valid := validNames[originalName]
				if !valid {
					for key := range validNames {
						if key == originalName {
							logError(config, fmt.Sprintf(&quot;[%s] [Name mapping not found] %s&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), originalName))
							break
						}
					}
				} else {
					name = nameMapping[originalName]
				}

				mu.Lock()
				articles = append(articles, Article{
					DomainName: domainName,
					Name:       name,
					Title:      item.Title,
					Link:       item.Link,
					Avatar:     avatarURL,
					Date:       formatTime(publishedTime),
				})
				mu.Unlock()
			}
		}(feedURL)
	}

	wg.Wait()
	sort.Slice(articles, func(i, j int) bool {
		date1, _ := time.Parse(&quot;January 2, 2006&quot;, articles[i].Date)
		date2, _ := time.Parse(&quot;January 2, 2006&quot;, articles[j].Date)
		return date1.After(date2)
	})

	return articles, nil
}

// 将爬虫抓取的数据保存到 GitHub
func saveToGitHub(config Config, data []Article) error {
	ctx := context.Background()
	client := github.NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&amp;amp;oauth2.Token{
		AccessToken: config.GithubToken,
	})))

	manualArticles := []Article{
		{
			DomainName: &quot;https://foreverblog.cn&quot;,
			Name:       &quot;十年之约&quot;,
			Title:      &quot;穿梭虫洞-随机访问十年之约友链博客&quot;,
			Link:       &quot;https://foreverblog.cn/go.html&quot;,
			Date:       &quot;January 01, 2000&quot;,
			Avatar:     &quot;https://cos.lhasa.icu/LinksAvatar/foreverblog.cn.png&quot;,
		},
		{
			DomainName: &quot;https://www.travellings.cn&quot;,
			Name:       &quot;开往&quot;,
			Title:      &quot;开往-友链接力&quot;,
			Link:       &quot;https://www.travellings.cn/go.html&quot;,
			Date:       &quot;January 01, 2000&quot;,
			Avatar:     &quot;https://cos.lhasa.icu/LinksAvatar/www.travellings.png&quot;,
		},
	}

	data = append(data, manualArticles...)
	jsonData, err := json.Marshal(data)
	if err != nil {
		return err
	}

	filePath := &quot;_data/rss_data.json&quot;
	file, _, resp, err := client.Repositories.GetContents(ctx, config.GithubName, config.GithubRepository, filePath, nil)
	if err != nil &amp;amp;&amp;amp; resp.StatusCode == http.StatusNotFound {
		_, _, err := client.Repositories.CreateFile(ctx, config.GithubName, config.GithubRepository, filePath, &amp;amp;github.RepositoryContentFileOptions{
			Message: github.String(&quot;Create rss_data.json&quot;),
			Content: jsonData,
			Branch:  github.String(&quot;master&quot;),
		})
		if err != nil {
			return fmt.Errorf(&quot;error creating rss_data.json in GitHub: %v&quot;, err)
		}
		return nil
	} else if err != nil {
		return fmt.Errorf(&quot;error checking rss_data.json in GitHub: %v&quot;, err)
	}

	_, _, err = client.Repositories.UpdateFile(ctx, config.GithubName, config.GithubRepository, filePath, &amp;amp;github.RepositoryContentFileOptions{
		Message: github.String(&quot;Update rss_data.json&quot;),
		Content: jsonData,
		SHA:     github.String(*file.SHA),
		Branch:  github.String(&quot;master&quot;),
	})
	if err != nil {
		return fmt.Errorf(&quot;error updating rss_data.json in GitHub: %v&quot;, err)
	}

	return nil
}

// 从 GitHub 仓库中获取 RSS 文件
func readFeedsFromGitHub(config Config) ([]string, error) {
	ctx := context.Background()
	client := github.NewClient(oauth2.NewClient(ctx, oauth2.StaticTokenSource(&amp;amp;oauth2.Token{
		AccessToken: config.GithubToken,
	})))

	filePath := &quot;_data/rss_feeds.txt&quot;
	file, _, resp, err := client.Repositories.GetContents(ctx, config.GithubName, config.GithubRepository, filePath, nil)
	if err != nil &amp;amp;&amp;amp; resp.StatusCode == http.StatusNotFound {
		errMsg := fmt.Sprintf(&quot;Error: %s not found in GitHub repository&quot;, filePath)
		logError(config, fmt.Sprintf(&quot;[%s] [Read RSS file error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), errMsg))
		return nil, fmt.Errorf(errMsg)
	} else if err != nil {
		errMsg := fmt.Sprintf(&quot;Error fetching %s from GitHub: %v&quot;, filePath, err)
		logError(config, fmt.Sprintf(&quot;[%s] [Read RSS file error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), errMsg))
		return nil, fmt.Errorf(errMsg)
	}

	content, err := file.GetContent()
	if err != nil {
		errMsg := fmt.Sprintf(&quot;Error decoding %s content: %v&quot;, filePath, err)
		logError(config, fmt.Sprintf(&quot;[%s] [Read RSS file error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), errMsg))
		return nil, fmt.Errorf(errMsg)
	}

	var feeds []string
	scanner := bufio.NewScanner(bytes.NewReader([]byte(content)))

	for scanner.Scan() {
		feeds = append(feeds, scanner.Text())
	}

	if err := scanner.Err(); err != nil {
		errMsg := fmt.Sprintf(&quot;Error reading RSS file content: %v&quot;, err)
		logError(config, fmt.Sprintf(&quot;[%s] [Read RSS file error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), errMsg))
		return nil, fmt.Errorf(errMsg)
	}

	return feeds, nil
}

func main() {
	config := initConfig()

	// 从 GitHub 仓库中读取 RSS feeds 列表
	rssFeeds, err := readFeedsFromGitHub(config)
	if err != nil {
		logError(config, fmt.Sprintf(&quot;[%s] [Read RSS feeds error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), err))
		fmt.Printf(&quot;Error reading RSS feeds from GitHub: %v\n&quot;, err)
		return
	}

	// 抓取 RSS feeds
	articles, err := fetchRSS(config, rssFeeds)
	if err != nil {
		logError(config, fmt.Sprintf(&quot;[%s] [Fetch RSS error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), err))
		fmt.Printf(&quot;Error fetching RSS feeds: %v\n&quot;, err)
		return
	}

	// 将抓取的数据保存到 GitHub 仓库
	err = saveToGitHub(config, articles)
	if err != nil {
		logError(config, fmt.Sprintf(&quot;[%s] [Save data to GitHub error] %v&quot;, getBeijingTime().Format(&quot;Mon Jan 2 15:04:2006&quot;), err))
		fmt.Printf(&quot;Error saving data to GitHub: %v\n&quot;, err)
		return
	}
	fmt.Println(&quot;Stop writing code and go ride a road bike now!&quot;)
}

&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Go 生成的 json 数据&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[
    {
        &quot;domainName&quot;: &quot;https://yihui.org&quot;,
        &quot;name&quot;: &quot;谢益辉&quot;,
        &quot;title&quot;: &quot;Rd2roxygen&quot;,
        &quot;link&quot;: &quot;https://yihui.org/rd2roxygen/&quot;,
        &quot;date&quot;: &quot;April 14, 2024&quot;,
        &quot;avatar&quot;: &quot;https://cos.lhasa.icu/LinksAvatar/yihui.org.png&quot;
    },
    {
        &quot;domainName&quot;: &quot;https://www.laruence.com&quot;,
        &quot;name&quot;: &quot;风雪之隅&quot;,
        &quot;title&quot;: &quot;PHP8.0的Named Parameter&quot;,
        &quot;link&quot;: &quot;https://www.laruence.com/2022/05/10/6192.html&quot;,
        &quot;date&quot;: &quot;May 10, 2022&quot;,
        &quot;avatar&quot;: &quot;https://cos.lhasa.icu/LinksAvatar/www.laruence.com.png&quot;
    }
]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Go 生成的日志&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[Sat Jul 27 08:42:2024] [Parse RSS error] https://lhasa.icu: Failed to detect feed type

[Sat Jul 27 08:41:2024] [Get RSS error] https://lhasa.icu: Get &quot;https://lhasa.icu&quot;: net/http: TLS handshake timeout
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Github Actons 1h/次&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;name: ScheduledRssRawler

on:
  schedule:
    - cron: &apos;0 * * * *&apos;
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout code
      uses: actions/checkout@v3

    - name: Set up Go
      uses: actions/setup-go@v3
      with:
        go-version: &apos;1.22.5&apos;

    - name: Install dependencies
      run: go mod tidy
      working-directory: ./api

    - name: Build
      run: go build -o main
      working-directory: ./api

    - name: Run Go program
      env:
        TOKEN: ${{ secrets.KEY }}
      run: ./main
      working-directory: ./api

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;腾讯 COS 也写了一份，Github 有延迟问题就没用，也能用，逻辑上和 Go 是没啥区别&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://github.com/achuanya/Grab-latest-RSS&quot; target=&quot;_blank&quot;&amp;gt;Grab-latest-RSS：https://github.com/achuanya/Grab-latest-RSS&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;a href=&quot;https://cloud.tencent.com/document/product/436/31215&quot; target=&quot;_blank&quot;&amp;gt;COS Go SDK：https://cloud.tencent.com/document/product/436/31215&amp;lt;/a&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://lhasa.icu/links.html&quot;&gt;效果页：https://lhasa.icu/links.html&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%88%A9%E7%94%A8Go%2BGithub%20Actions%E5%86%99%E4%B8%AA%E5%AE%9A%E6%97%B6RSS%E7%88%AC%E8%99%AB&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-07-27-grablatestrss&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>腾讯CDN流量被恶意盗刷</title><link>https://blog.lhasa.icu/posts/technology/2024-07-25-tencentcdntrafficwasmaliciouslystolen</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-07-25-tencentcdntrafficwasmaliciouslystolen</guid><pubDate>Wed, 24 Jul 2024 16:44:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;1721837126591.jpg&quot; alt=&quot;来自腾讯云的邮件&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到这张图的时候，我很震惊。这个CDN流量包是我昨天凌晨刚买的，直到此刻才发现我的CDN流量被恶意盗刷了。&lt;/p&gt;
&lt;p&gt;事情是这样的，前天23号我在写新功能，本地调试调用了很多资源，当时看到消耗了90G的流量，我没有在意，以为是调试的问题。因为那天我写了一天代码，不停地调用Tencent COS，而COS还套了一层Tencent CDN。当时我以为是正常消耗，眼看流量不够，我又充了一个CDN加速包。&lt;/p&gt;
&lt;p&gt;然而就在今晚22:45，我骑行回来关闭了免打扰模式，邮箱忽然弹出通知，腾讯云提示我CDN流量不足？我当时非常震惊，因为这是我24号凌晨刚买的流量包啊！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1721836262452.jpg&quot; alt=&quot;腾讯云 数据分析控制台&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到这张图时，我火了，在独立博客圈彻底火了，2天内请求数42万？赶超月光博客！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1721836283806.jpg&quot; alt=&quot;腾讯云 访问分布&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;1721836308939.jpg&quot; alt=&quot;TOP ONE 60.221.195.144&quot; /&gt;&lt;/p&gt;
&lt;p&gt;回想过去，我在博客圈认识的人一只手能数过来，更谈不上得罪谁。这事也怪我，之前COS没有任何防护，几乎处于裸奔状态。&lt;/p&gt;
&lt;p&gt;由于我的博客托管在Github Pages，主机问题大可不必考虑，我能做的只有设置黑白名单和周期限流。&lt;/p&gt;
&lt;p&gt;不再裸奔，已老实。&lt;/p&gt;
&lt;h2&gt;UPDATE 凌晨 02:32&lt;/h2&gt;
&lt;p&gt;知道怎么回事了，24年后，大陆境内出现一窝狗，利用PCDN恶意流量攻击！&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;攻击的主要IP来源于山西、江苏和安徽联通等地的固定网段&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;攻击时间非常规律，集中在19:50到23:00之间&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;攻击者会针对体积较大的静态文件进行持续攻击&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;自7月初以来，已转头无差别地对大陆中小型网站展开攻击。&lt;/p&gt;
&lt;p&gt;建议将山西等地的IP段暂时屏蔽，减少恶意流量的影响。&lt;/p&gt;
&lt;p&gt;目前，GitHub上已经有相关项目 &lt;a href=&quot;https://github.com/unclemcz/ban-pcdn-ip?tab=readme-ov-file&quot;&gt;ban-pcdn-ip&lt;/a&gt; 用于收集这些恶意IP段。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%85%BE%E8%AE%AFCDN%E6%B5%81%E9%87%8F%E8%A2%AB%E6%81%B6%E6%84%8F%E7%9B%97%E5%88%B7&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-07-25-tencentcdntrafficwasmaliciouslystolen&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>公路车管胎被扎，怎么补胎</title><link>https://blog.lhasa.icu/posts/outdoors/2024-07-19-tubulartirerepair</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-07-19-tubulartirerepair</guid><pubDate>Fri, 19 Jul 2024 06:38:00 GMT</pubDate><content:encoded>&lt;p&gt;管胎被扎了，还是后轮，我心如刀绞啊，太贵了，换不起，大多数技师都不会修的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240718143947.jpg&quot; alt=&quot;先拆后轮&quot; /&gt;&lt;/p&gt;
&lt;p&gt;解刨管胎&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;cc9a297937f92440c3d0eec0ce93932.jpg&quot; alt=&quot;解刨管胎&quot; /&gt;&lt;/p&gt;
&lt;p&gt;玻璃渣子把管胎扎透了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202407181439481.jpg&quot; alt=&quot;扎眼&quot; /&gt;&lt;/p&gt;
&lt;p&gt;拿砂纸打磨一下，涂完胶等风干&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202407181439482.jpg&quot; alt=&quot;打磨涂胶&quot; /&gt;&lt;/p&gt;
&lt;p&gt;胶风干后贴片，按按揉揉&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240718143949.jpg&quot; alt=&quot;贴片&quot; /&gt;&lt;/p&gt;
&lt;p&gt;好多年没做针线活了，没想到今天给管胎缝闭口&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202407181439491.jpg&quot; alt=&quot;穿针引线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202407181439492.jpg&quot; alt=&quot;管胎外皮真厚&quot; /&gt;&lt;/p&gt;
&lt;p&gt;线头有些遭了，扯断好多次&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202407181439493.jpg&quot; alt=&quot;穿针走线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;闭合管胎，涂胶加固&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240718143950.jpg&quot; alt=&quot;闭合管胎，涂胶加固&quot; /&gt;&lt;/p&gt;
&lt;p&gt;安装后轮打气&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240718143919.jpg&quot; alt=&quot;安装后轮打气&quot; /&gt;&lt;/p&gt;
&lt;p&gt;管胎缺点就优点就是轻，比开口胎、真空胎都轻，常用于专业竞赛和环法，就算车胎破了也能继续骑的，而开口胎和真空胎不行。&lt;/p&gt;
&lt;p&gt;缺点就是破了就废了，各大车店都是不修管胎的，只能换，这用管胎的成本真是太高了，不是富哥真用不起，这款是意大利产的Challenge Elite Pro 25c，零售价三百多/条，就这还全网缺货，八月初才到货。我的轮组不支持另外两种胎，缝缝补补吧&lt;/p&gt;
&lt;h2&gt;7-18 晚 测试补充&lt;/h2&gt;
&lt;p&gt;再次经历三过家门而不入，就是为了凑这个整，今天管胎补的可以经测试一百公里没有问题。现在我心率还不是稳不住，恢复到之前的状态好难啊&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;21957e908521d8e718c6661e9b79a51.jpg&quot; alt=&quot;测试管胎&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%85%AC%E8%B7%AF%E8%BD%A6%E7%AE%A1%E8%83%8E%E8%A2%AB%E6%89%8E%EF%BC%8C%E6%80%8E%E4%B9%88%E8%A1%A5%E8%83%8E&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-07-19-tubulartirerepair&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>喜提新车 Wilier Cento 10SL</title><link>https://blog.lhasa.icu/posts/outdoors/2024-07-12-wiliercento10sl</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-07-12-wiliercento10sl</guid><pubDate>Fri, 12 Jul 2024 14:33:00 GMT</pubDate><content:encoded>&lt;p&gt;得这辆车纯属缘分，前段时间在网上认识一个宁波的好大哥，没想到去年我们一起参加过同一个比赛，大哥是在宁波鄞州区开自行车店的，聊了许久大哥给我推荐一辆神车Wilier Cento 10SL！这是他朋友的爱车，财富自由润加拿大了，一些不方便带走的东西就卖掉了，这辆车刚到店里第一天，机缘巧合我就赶上了！&lt;/p&gt;
&lt;h2&gt;配置如下：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Wilier Cento 10SL RIM&lt;/li&gt;
&lt;li&gt;STEMMA SL 把立&lt;/li&gt;
&lt;li&gt;BARRA SL 弯把&lt;/li&gt;
&lt;li&gt;WIND BREAK 50框 碳辐条&lt;/li&gt;
&lt;li&gt;SHIMANO 105 R7000夹气，其他全车Ultegra 8000&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;算上平踏、水杯架 整车重为7.45KG，一对平踏重0.3KG，换DA夹气分分钟上6！&lt;/p&gt;
&lt;p&gt;这台车最吸引我的地方就是，圈刹！SL后最后一代顶级圈刹车，我在网上找了许久都找不到同款，这台车已经停产几年了，太稀有了，&lt;/p&gt;
&lt;h2&gt;上图&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;20240712214848.jpg&quot; alt=&quot;车到了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240712214849.jpg&quot; alt=&quot;我装车的时候把刹车线芯插坏了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;202407122148491.jpg&quot; alt=&quot;装好了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240712215100.jpg&quot; alt=&quot;寄回来之前，技师称重&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;20240712214833.jpg&quot; alt=&quot;骑行照&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%96%9C%E6%8F%90%E6%96%B0%E8%BD%A6%20Wilier%20Cento%2010SL&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-07-12-wiliercento10sl&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>搞个公众号</title><link>https://blog.lhasa.icu/posts/technology/2024-03-10-wechatpublicaccount</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-03-10-wechatpublicaccount</guid><pubDate>Sun, 10 Mar 2024 07:51:00 GMT</pubDate><content:encoded>&lt;p&gt;改名记录：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;2024年02月08日 “阿川的博客”改名“游钓四方的博客”&lt;/li&gt;
&lt;li&gt;2019年05月28日 “阿川的个人博客”改名“阿川的博客”&lt;/li&gt;
&lt;li&gt;2018年10月26日 注册“阿川的个人博客”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今天捡回了18年注册的公众号，数据重新导了一遍，这手动整理几年的文章数据，我多少有些疲惫&lt;/p&gt;
&lt;p&gt;这次熬的有点久了，明歇一天，再写个脚本让 Github Pages 文章自动同步到微信公众号，得想个办法&lt;/p&gt;
&lt;p&gt;公众号还需要做个人认证，不然内置超链接是个麻烦事&lt;/p&gt;
&lt;p&gt;公众号前端页面也需要重新写一个，腾讯自带UI限制文章数量&lt;/p&gt;
&lt;p&gt;任重而道远啊！加油。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%90%9E%E4%B8%AA%E5%85%AC%E4%BC%97%E5%8F%B7&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-03-10-wechatpublicaccount&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>腾讯云COS文件跨域</title><link>https://blog.lhasa.icu/posts/technology/2024-03-10-tencent-cloud-cos-file-cross-domain</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-03-10-tencent-cloud-cos-file-cross-domain</guid><pubDate>Sun, 10 Mar 2024 07:51:00 GMT</pubDate><content:encoded>&lt;p&gt;今天换博客主要文字了，&quot;仓耳今楷&quot;,字体更美观更适合阅读。但是过程中遇到点问题&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@font-face {
    font-family: 仓耳今楷01-W04;
    src: url(&quot;https://api.lhasa.icu/assets/font/tsanger01W04.ttf&quot;)  format(&quot;truetype&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段CSS写的是没有问题的，但是不生效，控制台报错跨域&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;has been blocked by CORS policy: No &apos;Access-Control-Allow-Origin&apos; header is present on the requested resource.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;腾讯云COS跨域访问CORS配置如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tencent-cloud-cos-cross-domain-configuration.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;配置好后又遇到麻烦了，字体太大了，一个字体文件17.9M！网站都脱垮了&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;textloading.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里做一下处理，取子集压缩文字，需要用到 &lt;a href=&quot;https://fontsmaller.github.io/&quot;&gt;FontSmaller&lt;/a&gt; 和 现代汉语常用3500汉字&lt;/p&gt;
&lt;p&gt;取子集压缩之后字体文件大小为1.94M&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;textloading2.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%85%BE%E8%AE%AF%E4%BA%91COS%E6%96%87%E4%BB%B6%E8%B7%A8%E5%9F%9F&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-03-10-tencent-cloud-cos-file-cross-domain&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>湖畔幽悠</title><link>https://blog.lhasa.icu/posts/life/2024-02-16-thelakeisveryquiet</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2024-02-16-thelakeisveryquiet</guid><pubDate>Thu, 15 Feb 2024 16:45:00 GMT</pubDate><content:encoded>&lt;p&gt;&amp;lt;div style=&quot;text-align: center;&quot;&amp;gt;
&amp;lt;p&amp;gt;湖畔独坐烟雾缭绕，古典旋律婉转悠扬&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;一毛钱贫瘠无关乐，心中富足任徜徉&amp;lt;/p&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;thelakeisveryquiet.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%B9%96%E7%95%94%E5%B9%BD%E6%82%A0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2024-02-16-thelakeisveryquiet&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>年味越来越淡，没有感觉</title><link>https://blog.lhasa.icu/posts/life/2024-02-12-22211records</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2024-02-12-22211records</guid><pubDate>Sun, 11 Feb 2024 16:35:00 GMT</pubDate><content:encoded>&lt;p&gt;出去转了转，拍点照片记录一下&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records4.jpg&quot; alt=&quot;淮阳的冬天&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records9.jpg&quot; alt=&quot;小时候常去玩的地方，人民公园对面的独木桥&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records6.jpg&quot; alt=&quot;弦歌东路 不知名湿地公园&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records10.jpg&quot; alt=&quot;姑姑家的仙人掌，看到这想起了西城墙的老家&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records1.jpg&quot; alt=&quot;老家已经被铲平了，现在成了古城墙遗址(西)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records7.jpg&quot; alt=&quot;我家曾经就在这个位置，我永远忘不了&quot; /&gt;&lt;/p&gt;
&lt;p&gt;之前在姑姑家移植过来的石榴树，一家人都走了，它留了下来，由于当时栽在河边政府没有铲掉&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records8.jpg&quot; alt=&quot;在姑姑家移植过来的石榴树，看的我五味杂陈&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records2.jpg&quot; alt=&quot;北关的抬花轿&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;22211records5.jpg&quot; alt=&quot;朝思暮想的毛鸡蛋&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%B9%B4%E5%91%B3%E8%B6%8A%E6%9D%A5%E8%B6%8A%E6%B7%A1%EF%BC%8C%E6%B2%A1%E6%9C%89%E6%84%9F%E8%A7%89&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2024-02-12-22211records&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>解决Jekyll时区数据源问题</title><link>https://blog.lhasa.icu/posts/technology/2024-02-11-jekylltzinfodata</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-02-11-jekylltzinfodata</guid><pubDate>Sun, 11 Feb 2024 15:07:00 GMT</pubDate><content:encoded>&lt;p&gt;由于Jekyll默认使用UTC时区，导致博客更新时间不准确。这里需要写入上海时间：timezone: Asia/Shanghai，但是我在本地调试时需要在配置内注释掉，不然就会报错&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;jekyll 3.9.3 | Error:  No source of timezone data could be found.
Please refer to https://tzinfo.github.io/datasourcenotfound for help resolving this error.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;上传到仓库 Github pages 不会出现这样的问题。老是注释调试挺麻烦的，Google搜出来的解决方案都是瞎扯淡，也不知道都是哪复制粘贴就发出来的。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gem install tzinfo-data
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Gemfile 直接指定版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;gem &apos;tzinfo-data&apos;, &apos;&amp;gt;= 1.2021a&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;写入配置 timezone: Asia/Shanghai，确保调试的电脑时区也正常，开始运行&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;bundle exec jekyll serve
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%A7%A3%E5%86%B3Jekyll%E6%97%B6%E5%8C%BA%E6%95%B0%E6%8D%AE%E6%BA%90%E9%97%AE%E9%A2%98&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-02-11-jekylltzinfodata&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>初一大吉，博客上上新</title><link>https://blog.lhasa.icu/posts/technology/2024-02-11-happynewyearblogonnew</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2024-02-11-happynewyearblogonnew</guid><pubDate>Sun, 11 Feb 2024 15:07:00 GMT</pubDate><content:encoded>&lt;h2&gt;图片预览&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;var preview = document.getElementById(&quot;preview&quot;);
var previewImage = document.getElementById(&quot;previewImage&quot;);

var previewImageTitle = &amp;lt;figcaption class=&quot;previewImageTitle&quot;&amp;gt; + image.title[i] + &amp;lt;/figcaption&amp;gt;;
previewImage.setAttribute(&apos;src&apos;, image.url[i]);
preview.style.display = &apos;flex&apos;;

var previousPreviewImageTitle = document.querySelector(&apos;.previewImageTitle&apos;);
if (previousPreviewImageTitle) {
    previousPreviewImageTitle.parentNode.removeChild(previousPreviewImageTitle);
}
previewImage.insertAdjacentHTML(&apos;afterend&apos;, previewImageTitle);

preview.addEventListener(&quot;click&quot;, function() {
    this.style.display = &apos;none&apos;;
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;markdown太丧心病狂了，js的代码块在转换的过程中给我生效了，大多方法都不能阻止这段代码不生效，把代码删删减减让我足足花了5分钟去注释这段代码.....&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;mounttaranaki-newzealand.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;前几天Fooleap留言建议我用cn-font-split把字体做一下分包处理，分包后原18M变1M不到，一篇千文的文章才几百KB，加载速度没得说。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;cn-font-splitfenbao.png&quot; alt=&quot;cn-font-split 分包后的效果&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Haibao@DESKTOP-IB7LLPB MINGW64 /d/lhasa.github.io (master)
$ bundle exec npm run build

&amp;gt; fooleap@1.0.0 build D:\lhasa.github.io
&amp;gt; webpack -p &amp;amp;&amp;amp; jekyll b

Hash: 470f4b7c37655d2798f9
Version: webpack 4.47.0
Time: 2347ms
Built at: 2024/02/11 上午5:27:39
       Asset      Size  Chunks             Chunk Names
main.min.css  27.2 KiB       0  [emitted]  main
 main.min.js   156 KiB       0  [emitted]  main
[0] ./src/main.js 25.7 KiB {0} [built]
[3] ./src/sass/main.scss 39 bytes {0} [built]
    + 3 hidden modules
Configuration file: D:/lhasa.github.io/_config.yml
To use retry middleware with Faraday v2.0+, install `faraday-retry` gem
            Source: D:/lhasa.github.io
       Destination: D:/lhasa.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 7.403 seconds.
 Auto-regeneration: disabled. Use --watch to enable.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这些天我把webPack临时学了一手，也是半斤八两，普通打个包是没问题，就是不知道这分包后的字体能不能用webPack打包，我还没试过。&lt;/p&gt;
&lt;p&gt;因为网站在Github pages，这加载速度也快到顶了。目前还缺少一个已备案的域名，我想把腾讯云的COS用CDN来加速一下，这样的话静态资源应该会更快点，博客也没啥访问量，按流量计费，也花不了几个钱。&lt;/p&gt;
&lt;h2&gt;2024/2/14 更新&lt;/h2&gt;
&lt;p&gt;后来注意到URL包含了腾讯图片处理样式后缀，这里用正则做一下处理&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;image.url[i] = image.url[i].replace(/\.(jpg|jpeg|png|gif)[^/]*$/, &apos;.$1&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%88%9D%E4%B8%80%E5%A4%A7%E5%90%89%EF%BC%8C%E5%8D%9A%E5%AE%A2%E4%B8%8A%E4%B8%8A%E6%96%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2024-02-11-happynewyearblogonnew&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>技术亦福亦是祸</title><link>https://blog.lhasa.icu/posts/life/2024-10-03-technologyblessingandcurse</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2024-10-03-technologyblessingandcurse</guid><pubDate>Fri, 02 Feb 2024 07:50:00 GMT</pubDate><content:encoded>&lt;p&gt;今天一个偶然接触到了Clarity Session Recording，当我看到它在我调试本地网站时，它居然录制了一条长达45分钟的视频，我大为震惊！由此，我怀揣着对技术的敬畏和亢奋的状态写下来这篇文章，虽然我非技术大牛，也非经济哲学家，但丝毫不影响我对技术的一些拙见。&lt;/p&gt;
&lt;p&gt;技术，造福与社会的同时也存在着弊端，这是一个漫长的历史过程。在资本主义原始积累时期，技术发展相对缓慢，因此，在人们利用自然资源的同时，对于群众的利益得失，那是既看不出来，也堂而皇之。&lt;/p&gt;
&lt;p&gt;在全民炼钢铁的时代，为了追求技术，挨家挨户交出铁器充数，上至灶台的铁锅，下至门板上的钢钉都要拆下来，全部投进了土高炉。先不讲炼铁对环境的污染，毕竟人都吃不饱，光是大食堂的一平二调、三高五风就饿死多少同胞啊！&lt;/p&gt;
&lt;p&gt;犹如二零年新冠疫情初期的口罩机，相当受欢迎的低成本高回报疫情红利生产技术，口罩是一片难求，人民苦不堪言。而资本业绩翻一翻。但好景不长，随着口罩机业务跳水，增速不再。口罩凉了，口罩机成了一堆废铁。&lt;/p&gt;
&lt;p&gt;要说技术亦福亦是祸，这不堪回首的民族历史足以证明。这种资本式的疯狂扩张给无知的人带来无尽的灾难，亦不可为，而为之，这就是资本的本性。&lt;/p&gt;
&lt;p&gt;随着技术的迅猛发展，尤其是在信息时代，技术对社会、经济、文化等方方面面的影响愈发显著。曾经由无知带来的寒蝉效应逐渐缓解。相对来说，资本已经完成原始积累，对于技术的态度更为复杂，当WEB市场各种大利好大利空时，毫不犹豫的用PHP进行开发。当PHP已经不能获得更多合理的利润时，就会对PHP嗤之以鼻，甚至会给予判处死缓，阻碍它进入生产领域。&lt;/p&gt;
&lt;p&gt;到了新媒体时代，我们在享受数字化便利的同时，也时刻面临着隐私泄露、信息滥用等风险。随着人工智能、大数据分析等技术的日益成熟，我们的个人信息被不断挖掘，商业巨头通过分析我们的行为、偏好来精准投放广告，甚至影响我们的决策过程，因百度竞价逝世的魏则西就是典型！&lt;/p&gt;
&lt;p&gt;此外，技术的快速发展也带来了社会的数字鸿沟。那些掌握先进技术的人群能够更好的适应现代社会，而缺乏技术接触的人可能会陷入信息贫困。这种信息差不仅是技术能力的差异，更是社会资源分配的问题。&lt;/p&gt;
&lt;p&gt;由此可见，在现代科技的巨大浪潮中，技术进步所带来的便利与其可能引发的负面效应是相对的。技术不仅仅是一种工具，更是对社会和人类价值观的挑战。我们在追逐技术的同时，必须寻找这个平衡点，制定法治和伦理准则，引导技术更加普惠，而非为一己之私，任道重远啊！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%8A%80%E6%9C%AF%E4%BA%A6%E7%A6%8F%E4%BA%A6%E6%98%AF%E7%A5%B8&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2024-10-03-technologyblessingandcurse&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>晒晒年中时的骑行</title><link>https://blog.lhasa.icu/posts/outdoors/2024-02-02-ridingrecordone</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/outdoors/2024-02-02-ridingrecordone</guid><pubDate>Thu, 01 Feb 2024 21:24:00 GMT</pubDate><content:encoded>&lt;p&gt;年前回家了，怀念年中在上海骑车日子&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;qicheluya.jpg&quot; alt=&quot;骑行 TCR PRO 在闵行区华漕路附近路亚&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;shanghai1.jpg&quot; alt=&quot;骑行 TCR PRO 在黄浦区苏州河喝咖啡&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;waitan1.jpg&quot; alt=&quot;骑行 XTC 800 在邹市明拳击馆附近夜骑&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;simingshanbisai2.jpg&quot; alt=&quot;从闵行区虹桥青杉路出发，目的地：余姚市全民健身中心签名报道！&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;zhuangbei2.jpg&quot; alt=&quot;宁波·余姚第六届环四明山比赛·第17届马自骑资格认证赛 公路车·全程租·A0753 张宏海&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;qixingfu.jpg&quot; alt=&quot;PAS骑行服&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;zhuangbei1.jpg&quot; alt=&quot;比赛前物品准备·军火展示&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;simingshan1.jpg&quot; alt=&quot;比赛前一周训练·在四明山入口处&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;simingshan3.jpg&quot; alt=&quot;比赛前一周训练·在四明山不知名山腰&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;simingshan4.jpg&quot; alt=&quot;比赛前一周训练·望着后方已经爬过的群山 我站在山腰极度兴奋，大概剩100公里结束训练&quot; /&gt;&lt;/p&gt;
&lt;p&gt;以下素材来自 2023年5月14日 开赛当天，比赛时闷头骑没时间拍，遗憾&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;jiangtaipaizhao.jpg&quot; alt=&quot;5月14日 完赛后 主办奖台留念&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;jiangzhuang.jpg&quot; alt=&quot;奖状与奖牌&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;simingshan5.jpg&quot; alt=&quot;最终成绩224名&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;simingshanbisai.jpg&quot; alt=&quot;Garmin Edge 1040 码表成绩&quot; /&gt;&lt;/p&gt;
&lt;p&gt;年中时iphone坏了换了手机，导致今年六月份 两天半的时间从 河南周口 骑行到 上海 记录没有了...是我目前用时最短，距离最长骑行的记录。还有好多在上海留下的足迹照片都没了，下次证据一定奉上！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%99%92%E6%99%92%E5%B9%B4%E4%B8%AD%E6%97%B6%E7%9A%84%E9%AA%91%E8%A1%8C&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Foutdoors%2F2024-02-02-ridingrecordone&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>南北饮食差异</title><link>https://blog.lhasa.icu/posts/life/2024-01-29-north-south-dietary-differences</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2024-01-29-north-south-dietary-differences</guid><pubDate>Mon, 29 Jan 2024 04:18:00 GMT</pubDate><content:encoded>&lt;p&gt;沪上为异客，巴月三成弦。朔风正摇落，行子已归旋。&lt;/p&gt;
&lt;p&gt;在家真好！今起了个大早，六点半时天蒙蒙亮，我穿着毛绒睡衣骑电动车赶早怼了碗胡辣汤，五元/碗经济实惠，舀上一勺感受这辛辣酸甜，顿时想起沪漂这些年的心酸往事...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;hulatang1.jpg&quot; alt=&quot;胡辣汤、肉包子、茶叶蛋、鸡蛋饼&quot; /&gt;&lt;/p&gt;
&lt;p&gt;回想上海20/碗清汤淡水，那是什么狗八胡辣汤，色香味你是一样都不沾。勾八商家，不要跟我说房租成本，原料物价高，我做原料采购这些年，江浙沪海鲜农产品行情不敢说是专家，多少有点自己的见解，那一两胡椒面值几个钱，一碗水放俩菜叶子净毛利有多少？这些投机倒把的无良商家一点诚信都没有，餐饮届都让你们这些老鼠屎给败坏了。&lt;/p&gt;
&lt;p&gt;说多说少我对爱丁堡有些偏见，但并不妨碍我对于淮阳菜、粤菜的喜爱，民以食为天嘛！由于之前就职粤菜杭菜的原料采购经历，今我想聊聊南北的饮食差异。&lt;/p&gt;
&lt;h2&gt;南甜北咸，东辣西酸&lt;/h2&gt;
&lt;p&gt;南米北面，若从菜系角度来讲，民间起初有四大菜系：粤菜、淮扬菜、鲁菜、川菜。后来随着生活提高又衍生出了：浙菜、闽菜、湘菜、徽菜。就此入的流的就这八大菜系，此外的就不讲了。&lt;/p&gt;
&lt;p&gt;在餐饮界，八大菜系是谁也不服谁。鲁师傅嘲讽粤菜淡不拉几没味，啥都剩着吃，俺鲁菜作为御膳才是八大菜系之首。
听到鲁菜叫嚣，淮扬菜师傅立马就坐不住了便大喊到：老子是国宴，一手白袍虾仁尼克松来了都要舔盘子。闻声，川师傅急忙插一嘴：你们淮阳菜太甜，像吃了蜜蜂屎，不如俺们的麻婆豆腐，那叫一个地道...你说一句我怼一句，一时间硝烟四起...本是同根生，口味差距为何如此之大？&lt;/p&gt;
&lt;h2&gt;南北气候差异&lt;/h2&gt;
&lt;p&gt;先从南北所处生态环境来讲，再映射原料。北方气候较为寒冷且干燥，北京为例，坐标蒙古高压的东南边缘，西北方向有广阔的沙漠和草原，所以北京全年降雨量少且集中在夏季。此外，北京的雾霾和沙尘暴也是常态化，春季最为明显。所以结论得出北方的土壤适合种植小麦、玉米、大豆等农作物，即面食，这些原料应对寒冷干燥的环境可以贮藏很长时间。&lt;/p&gt;
&lt;p&gt;而南方则相反，小桥流水，细雨芊芊，最属江浙，我的最爱。这里属亚热带季风气候，全年降水充沛，集中在春夏季。即使在降水量低的冬季，受冷暖空气共同作用，也不会像北方寒冷干燥，隐约的记得在杭州采购部的时候，屋里的被子感觉都没有干过。&lt;/p&gt;
&lt;p&gt;所以南方以湿润的气候独步天下，富饶的土壤和丰富的水资源在贫困的新手发育阶段显得尤为重要，我认为这也是南北方饮食差异的最大原因：经济。&lt;/p&gt;
&lt;h2&gt;差异的本质&lt;/h2&gt;
&lt;p&gt;结上来看，各菜系各有各的特色，鲁菜利用广阔的地理资源吃的有些粗犷，而南方的小资较为精细，要说原因，我看还是穷。从GDP来说，&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;bnanbeigdp.jpg&quot; alt=&quot;2019年中国各省GDP总量及增速情况&quot; /&gt;&lt;/p&gt;
&lt;p&gt;要么说还是南方人富裕，全面小康喊了几十年的口号，得道的又有几个地方？毕竟地理位置和气候环境决定了起步的高度。图上排名靠前的省份大多是清一色的长江中下游地区，从这里咱们可以从地理位置以农耕的角度来看经济效应。&lt;/p&gt;
&lt;p&gt;秦岭到淮河一线以南属亚热带地区，常年降水量大于800毫米，热量充足，降水充沛，得天独厚的条件能一年两熟或一年三熟。&lt;/p&gt;
&lt;p&gt;秦岭到淮河一线以北常年旱地，有一年一熟或两年三熟就不错了。所以秦岭到淮河这条线的走向也是决定了南北饮食差异化的原因之一。&lt;/p&gt;
&lt;p&gt;既然没钱，裤腰带勒紧过，川菜的辛辣起初也是经济的体现。如中国的旧社会，有势有钱有三吃：细，鲜，甜。就这三个条件在旧社会就不得了，穷人家别说吃甜，鲜，能有粮食就不错了，别管变质与否，所以难吃变质的食物加以调料掩盖其味道得以饱腹。&lt;/p&gt;
&lt;p&gt;我奶奶是从五八年走过来的人，我小时候常挑食的时候我奶奶马上就会讲，放到五八年，你们这群人都得饿死，树皮都没得吃。也就是这些历史传承原因导致了现在的南北饮食差异，现在的日子不同以往了，除个别困难地区，大多数家庭还是能温饱的，口味也都传承了下来。&lt;/p&gt;
&lt;p&gt;虽然现在的经济形势也很差，但比以前是好多了，人的嘴都吃叼了。我想南北饮食的差异化也会随着小康社会的推动逐渐减少。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%8D%97%E5%8C%97%E9%A5%AE%E9%A3%9F%E5%B7%AE%E5%BC%82&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2024-01-29-north-south-dietary-differences&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>置办了一套茶具</title><link>https://blog.lhasa.icu/posts/life/2024-01-28-tea-set</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2024-01-28-tea-set</guid><pubDate>Sun, 28 Jan 2024 08:36:00 GMT</pubDate><content:encoded>&lt;p&gt;我挺喜欢喝茶的，工作闲的时候，我常去江杨市场和江桥的国际餐具市场转悠，一是去询价看看新上市的原料了解一下当下行情，二是去供应商那坐坐，大伙聊聊行情吹吹牛逼，过程自然少不了盖碗茶。&lt;/p&gt;
&lt;p&gt;话说对于这茶具我是熟悉又陌生，我的工作有一部分是采购餐厨具，但主要的茶具多由集团向龙泉瓷集中采购，还轮不到我插一嘴。前些天茶喝的时候忽然想到了茶具，抱着对传统文化的好奇心，我就置办了点便宜的德化窑白陶瓷。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tea-set2.jpg&quot; alt=&quot;茶盘、盖碗、公道杯、斗笠杯、茶夹、茶漏&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我喜欢这样的陶瓷器，通透，一抹凝脂如玉的色，把玩着、抚摸着宛如女人的肌肤。&lt;/p&gt;
&lt;p&gt;说到陶瓷器，我认为景德镇为上佳，德化和他差的不是一丁半点，从出身、烧制起就有所不同。&lt;/p&gt;
&lt;p&gt;景德镇，始于唐，盛于宋，早在元世祖在位时就成立了御窑厂，上呈皇族，下卖显贵。由此以来景德镇的名号都成了陶瓷器的金字招牌，但凡沾上点关系，价格翻一翻。&lt;/p&gt;
&lt;p&gt;而德化不同于老大哥的官窑背景，少些贵族气质，多些烟火气息，怎么说德化也是世界陶瓷之都啊！&lt;/p&gt;
&lt;p&gt;其次，两者的工艺也有所不同，景德镇的高温烧制工艺讲究还原气氛，使其具有了独特搜刮钱财的光泽，最具代表性则为青白瓷釉，一线大师齐聚一堂，精益求精的工艺赋予了景德镇陶瓷独特的艺术品格。&lt;/p&gt;
&lt;p&gt;相关，德化的机械化流水线式生产就不像老大哥那考究，低温烧制，一个字，快！主打一个从人民中来，到人民中去。&lt;/p&gt;
&lt;p&gt;两者肉眼还是容易区分的，前者由于高岭土含铁元素较高，高温烧制后骚了点，脸颊上泛着隐约的青涩。小老弟则含钾多些，低温烧制属软性瓷，通透，特白，所以两者在颜色上可以很直观的区分出来。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tea-set1.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tea-set6.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;打了这么多字，我手都把不住门了，望着盖碗中的铁观音，捏住这斗笠杯，一饮而尽！入口清香，回甘绵长，这看着锅里的，吃着碗里的，神仙来了也上头啊！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%BD%AE%E5%8A%9E%E4%BA%86%E4%B8%80%E5%A5%97%E8%8C%B6%E5%85%B7&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2024-01-28-tea-set&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>我回来了</title><link>https://blog.lhasa.icu/posts/life/2024-01-22-the_song_begins</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2024-01-22-the_song_begins</guid><pubDate>Mon, 22 Jan 2024 04:36:00 GMT</pubDate><content:encoded>&lt;p&gt;一晃几年过去了，一切都物是人非，说起来有点哽咽...哎...&lt;/p&gt;
&lt;p&gt;最重要的域名也在今年搞丢了，续费保护期也过了，曾经二三百的域名，现在要二万块...先拿github的用用，以后再说吧&lt;/p&gt;
&lt;p&gt;一时间，脑子蒙蒙的，纵有千言万语却不知道说些什么。总之，接下来我会把丢掉的博客再捡起来，曾经的朋友你们还在吗？留言系统还没有弄好，可以联系Email&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%88%91%E5%9B%9E%E6%9D%A5%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2024-01-22-the_song_begins&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>大年初一，徒步西湖</title><link>https://blog.lhasa.icu/posts/life/2021-02-12-west-lake-tour</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2021-02-12-west-lake-tour</guid><pubDate>Fri, 12 Feb 2021 04:44:00 GMT</pubDate><content:encoded>&lt;p&gt;早上八点从滨康路地铁口出发，从候潮门出来就一直在走&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tubuzhong.jpeg&quot; alt=&quot;徒步中&quot; /&gt;&lt;/p&gt;
&lt;p&gt;因为穿的是薄薄的板鞋，走路实属不舒服，走好久到了西湖，下台阶走了两步差点来了一个“新年第一摔”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;xihutianxian.jpeg&quot; alt=&quot;西湖石板上的苔藓&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我写博客的时候才发现照片颜色不对劲，我也不知道咋回事...话说西湖环境管理的挺不错的，湖水没有太多垃圾，岸边都是可以清澈见底的&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;xihu.jpeg&quot; alt=&quot;西湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;gjcnm.jpg&quot; alt=&quot;西湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;在杭州我最喜欢的就是杭州的绿化，清晨或傍晚走在南山路散步，那感觉真是令人心旷神怡&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;shumu.jpeg&quot; alt=&quot;西湖绿化&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我站西湖岸边抽烟一扭头，发现岸边有一条大青！ (看体型像鲤鱼)  目测身长70cm-10斤左右！大年初一的真是让人喜出望外，难道这就是传说中的鸿运当头吗？啊哈哈哈！看的我也是手痒痒真想抽几杆，看来西湖也是有大货啊&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;qingyu1.jpeg&quot; alt=&quot;大青&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;qingyu2.jpeg&quot; alt=&quot;大青&quot; /&gt;&lt;/p&gt;
&lt;p&gt;果然好事连连！我妈给我打电话说今天和我爸们临时调休了，带着我出去玩！对于我这个十几年的留守儿童来到爸妈工作的城市，和爸妈一起出去玩坐一起吃吃饭，真的对我来说是多么奢侈的事情。&lt;/p&gt;
&lt;p&gt;我爸提议来河坊街玩&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;hefangjie.jpeg&quot; alt=&quot;河坊街&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我妈看到我喜欢吃的绿豆糕就给我买了一盒，挺好吃的，吃着面面的很细腻，有点绿豆甜那种味道，后来买了千层饼、长沙臭豆腐、糖雪球我都光顾着吃了并没有拍哈哈哈&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;lvdoubinggan.jpeg&quot; alt=&quot;绿豆冰糕&quot; /&gt;&lt;/p&gt;
&lt;p&gt;逛到大概一点钟我们去吃饭了，西湖春天南山店，我最喜欢吃的是糯米藕和乳鸽，乳鸽口感真的很脆，也没有很油腻&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;chifan.jpeg&quot; alt=&quot;吃饭喽&quot; /&gt;&lt;/p&gt;
&lt;p&gt;吃完饭，我妈带我去买了两双鞋，我妈说让我把身上穿这双板鞋扔了，我这双回力的板鞋穿三年了，就是穿去户外真的不舒服，底子薄还硬，走的远会很累。但是想想这双鞋跟了我好久，陪我走过好多路真的不是很舍得扔....&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;huijia.jpeg&quot; alt=&quot;回家了&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%A4%A7%E5%B9%B4%E5%88%9D%E4%B8%80%EF%BC%8C%E5%BE%92%E6%AD%A5%E8%A5%BF%E6%B9%96&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2021-02-12-west-lake-tour&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>PHP 笔记</title><link>https://blog.lhasa.icu/posts/technology/2021-02-12-php-notes</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2021-02-12-php-notes</guid><pubDate>Fri, 12 Feb 2021 04:44:00 GMT</pubDate><content:encoded>&lt;h2&gt;预定义变量&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 当前脚本所在的文档根目录(服务器VirtualHost定义)
DOCUMENBT_ROOT
# 获取当前域名
HTTP_HOST
# 获取当前页面地址 
PHP_SELF
# 获取完整url(包括?号后的参数)
REQUEST_URL
# 获得页面使用的请求方法
REQUEST_METHOD
# 当前php文件名
_FILE_
# 当前php文件中所在的行数
_LINE_
# PHP版本
PHP_VERSION
# 获得地址后的所有内容
REQUEST_URI
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;字符串函数&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 输出一个或多个字符串
echo
# 去除字符串首尾处的空白字符（或者其他字符）
trim
# 将一个字符串进行MD5算法加密
md5
# 将一个一维数组的值转化为字符串
implode
# 使用一个字符串分割另一个字符串
explode
# 将字符串解析成多.个变量
parse_str
# 使用另一个字符串填充字符串为指定长度
str_pad
# 重复一个字符串
str_repeat
# 子字符串替换
str_replace
# 随机打乱一个字符串
str_shuffle
# 将字符串转换为数组
str_split
# 获取字符串长度
strlen
# 从字符串中去除 HTML 和 PHP 标记
strip_tags
# 查找字符串首次出现的位置
strpos
# 查找指定字符在字符串中的最后一次出现
strrchr
# 计算指定字符串在目标字符串中最后一次出现的位置
strrpos
# 返回字符串的子串
substr
# 将字符串转化为小写
strtolower
# 将字符串转化为大写
strtoupper
# 反转字符串
strrev
# 指定文件进行MD5算法加密
md5_file
# 计算字符串的 sha1 散列值
sha1
# 以千位分隔符方式格式化一个数字
number_format
# 输出字符串
print
# 输出格式化字符串
printf
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;数组函数&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 新建一个数组
array
# 返回数组中所有的值
array_values
# 计算数组中的单元数目或对象中的属性个数
count
# 检查数组中是否存在某个值
in_array
# 将数组打乱
shuffle
# 将数组的内部指针指向第一个单元
reset
# 将数组的内部指针指向最后一个单元
end
# 将一个数组分割成多个
array_chunk
# 返回数组中指定的一列
array_column
# 创建一个数组，用一个数组的值作为其键名，另一个数组的值作为其值
array_combine
# 统计数组中所有的值出现的次数
array_count_values
# 用给定的值填充数组
array_fill
# 交换数组中的键和值
array_flip
# 检查给定的键名或索引是否存在于数组中
array_key_exists
# 返回数组中部分的或所有的键名
array_keys
# 合并一个或多个数组
array_merge
# 用值将数组填补到指定长度
array_pad
# 将数组最后一个单元弹出（出栈）
array_pop
# 从数组中随机取出一个或多个单元
array_rand
# 返回一个单元顺序相反的数组
array_reverse
# 在数组中搜索给定的值，如果成功则返回相应的键名
array_search
# 将数组开头的单元移出数组
array_shift
# 从数组中取出一段
array_slice
# 在数组开头插入一个或多个单元
array_unshift
# 对数组进行逆向排序并保持索引关系
arsort
# 对数组进行排序并保持索引关系
asort
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;GET 与 POST 的区别&lt;/h2&gt;
&lt;p&gt;GET在浏览器回退时是无害的，而POST会再次提交请求&lt;/p&gt;
&lt;p&gt;GET产生的URL地址可以被Bookmark，而POST不可以&lt;/p&gt;
&lt;p&gt;GET请求会被浏览器主动cache，而POST不会，除非手动设置&lt;/p&gt;
&lt;p&gt;GET请求只能进行url编码，而POST支持多种编码方式&lt;/p&gt;
&lt;p&gt;GET请求参数会被完整保留在浏览器历史记录里，而POST中的参数不会被保留&lt;/p&gt;
&lt;p&gt;GET请求在URL中传送的参数是有长度限制的，而POST么有&lt;/p&gt;
&lt;p&gt;对参数的数据类型，GET只接受ASCII字符，而POST没有限制&lt;/p&gt;
&lt;p&gt;GET比POST更不安全，因为参数直接暴露在URL上，所以不能用来传递敏感信息&lt;/p&gt;
&lt;p&gt;GET参数通过URL传递，POST放在Request body中&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=PHP%20%E7%AC%94%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2021-02-12-php-notes&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Ubuntu Server部署日记</title><link>https://blog.lhasa.icu/posts/technology/2021-02-12-ubuntu-deployment</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2021-02-12-ubuntu-deployment</guid><pubDate>Fri, 12 Feb 2021 04:44:00 GMT</pubDate><content:encoded>&lt;p&gt;出于挂一些签到软件的原因我一直在用Windows Server2012，因为服务器配置较低图形界面操作卡的要死，干脆直接上纯命令操作系统的linux&lt;/p&gt;
&lt;p&gt;关于linux发行版我几乎都玩过。在选择linux服务器这块也没有太犹豫，我个人比较痴情Ubuntu，&lt;/p&gt;
&lt;p&gt;我个人用户对于服务器要求没有那么高，所以选择了 Ubuntu Server 16.04.1 LTS。不过我第一次部署纯命令操作系统，部署的过程中还是遇到一些小麻烦，不过办法总比困难多嘛！&lt;/p&gt;
&lt;h2&gt;root登录&lt;/h2&gt;
&lt;p&gt;首先，使用&lt;a href=&quot;https://linux.51yip.com/search/ssh&quot;&gt;ssh命令&lt;/a&gt;在终端登录到远程主机&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;achuan@achuan-pc:~$ sudo ssh ubuntu@139.199.105.72
[sudo] achuan 的密码： 
ubuntu@139.199.105.72&apos;s password:
The authenticity of host &apos;139.199.105.72 (139.199.105.72)&apos; can&apos;t be established.
ECDSA Key fingerprint is SHA256:HNndgD6z/I2L8DzCA5nk9w9CEzHpW9WouGAmkMDR7LK.
Are you sure you want to continue connecting (yes/no)? yes
ubuntu@139.199.105.72&apos;s password:
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-130-generic x86_64)

* Documentation:    https://help.ubuntu.com
* Management:       https://landscape.canonical.com
* Support:          https://ubuntu.com/advantage
New release &apos;18.04.1 LTS&apos; available.
Run &apos;do-release-upgrade&apos; to upgrade to it.

Last login: Mon Nov 5 16:38:39 2018 From 119.28.7.195
ubuntu@VM-22-96-ubuntu:~$
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这时，登录时命令行出现了警告，它说这是一个新的地址，存在安全风险。简单了解一下之后，我选择面对风险　yes 顺利登入远程主机。&lt;br /&gt;
对我来说登入后第一件事莫过于设置root密码&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo passwd root
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装 vim&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 习惯性的更新源...
$ sudo apt-get update
# 安装vim
$ sudo apt-get install vim-gtk
......
Do you want to continue [Y/n]? Y
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令行敲入　vi ,Tab一下，不出问题已经有　viｍ&lt;/p&gt;
&lt;h3&gt;配置vim&lt;/h3&gt;
&lt;p&gt;强迫症的我，简单的配置一下...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo vim /etc/vim/vimrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;文件内容里有这么一句：&lt;code&gt;syntax on&lt;/code&gt;它的意思是“语法高亮”，别注释它！为了提升体验我们需要set一下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set nu          # 在左侧显示行号
set tabstop=4   # tab长度设置为4
set cursorline  # 覆盖文件时不备份
set ruler       # 在右下角显示状态栏
set autoindent  # 自动锁紧
set showmatch   # 高亮显示匹配的括号
# 编码设置
set fencs=utf=uft-8,ucs-bom,shift-jis,gb18030,gbk,gb2312,cp936
# 语言设置
set langmenu=zh_CN.UTF-8
set helplang=cn
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装apache&lt;/h2&gt;
&lt;p&gt;我们使用源安装&lt;a href=&quot;https://zh.wikipedia.org/wiki/Apache_HTTP_Server&quot;&gt;apache&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt-get install apache2
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置apache&lt;/h3&gt;
&lt;p&gt;启动apache的两种姿势&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo /etc/init.d/apache2 start
# 或
$ sudo service apache2 star
# [start] [restart] [stop] [status]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;推送文件到网站根目录&lt;/h3&gt;
&lt;p&gt;在这里我遇到一个问题&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;root@achuan-pc:/home/achuan/视频/ubuntu# scp -r htdocs ubuntu@139.199.105.72:/var/www
ubuntu@139.199.105.72&apos;s password: 
scp: /var/www/htdocs: Permission denied
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;用 scp 推送文件夹的时候出现了&lt;code&gt;Permission denied&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;what the?　我被拒绝了？&lt;/p&gt;
&lt;p&gt;想了想原来是网站的根目录&lt;code&gt;/var/www&lt;/code&gt;没有写入权限，让我们chmod一下？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ssh ubuntu@139.199.105.72
......
$ sudo chmod 777 -R /var/www
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;已经解决了让我们再 scp 一下！&lt;/p&gt;
&lt;h3&gt;解决ssh自动断连&lt;/h3&gt;
&lt;p&gt;这个自动断连就让我很是难受，不管是利用终端还是客户端工具都会出现这个问题，经过了解原来是正常的...&lt;br /&gt;
使用ssh连接远程服务器隔段时间没有任何操作，客户端与服务器就会自动断连，解决办法如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo vim /etc/ssh/sshd_config
$ sudo service sshd reload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们需要修改客户端或服务器端　&lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt;　配置文件，找到&lt;code&gt;ClientAliveInterval&lt;/code&gt;，改成 60（分钟单位，默认0）意思的每一分钟向客户端发送一个消息，用于保持连接，&lt;/p&gt;
&lt;h3&gt;VirtualHost配置&lt;/h3&gt;
&lt;p&gt;关于ubuntu serverd的apache配置文件在&lt;code&gt;/etc/apache2/apache.conf&lt;/code&gt;当apache启动时会自动读取这个文件的配置信息，而其他的一些配置文件，则是通过Include指令引入。奇怪的是我找不到httpd.conf，算了自己动手丰衣足食&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 进入apache文件夹 &amp;gt; 创建 httpd.conf
$ cd /etc/apache2/ &amp;amp;&amp;amp; sudo vi httpd.conf
# 并写入以下配置内容

# 如果你的服务器有多个IP、不同的虚拟用户时，你可以更改它
&amp;lt;VirtualHost [IP]:[端口]&amp;gt;
...
&amp;lt;/VirtualHost&amp;gt;

&amp;lt;VirtualHost *:80&amp;gt;
	ServerAdmin achuan@achuan.io         # 网站管理员邮箱，可填可不填
	DocumentRoot &quot;/var/www/chenbtpig&quot;    # 网站根目录
	ServerName chenchen1112.cn           # 域名
	&amp;lt;Directory &quot;/var/www/chenbtpig&quot;&amp;gt;	 # 网站根目录权限设置
		Options Indexes FollowSymLinks   # 禁止显示Apache目录
		AllowOverride All				 # 允许重写apache默认配置
		Order allow,deny				 # 允许所有
		Allow from all
	&amp;lt;/Directory&amp;gt;
	Errorlog &quot;logs/chenchen1112.cn-error.log&quot;   # 网站错误日志
	CustomLog &quot;logs/chenchen1112.cn-access.log&quot; common   # 网站访问日志
&amp;lt;/VirtualHost&amp;gt;

&amp;lt;VirtualHost *:80&amp;gt;
	ServerAdmin achuan@achuan.io
	DocumentRoot &quot;/var/www/code_rain&quot;
	ServerName lmissyou.club
	&amp;lt;Directory &quot;/var/www/code_rain&quot;&amp;gt;
		Options Indexes FollowSymLinks
		AllowOverride All
		Order allow,deny
		Allow from all
	&amp;lt;/Directory&amp;gt;
	Errorlog &quot;logs/lmissyou.club-errpr.log&quot;
	CustomLog &quot;logs/lmissyou.club-access.log&quot; common
&amp;lt;/VirtualHost&amp;gt;

# 打开apache配置文件并写入“Include httpd.conf”
$sudo vim /etc/apache2/apache2.conf

# 修改hosts /etc/hosts
$ sudo vi /etc/hosts
# 写入　IP与域名
# 139.199.105.72 www.chenchen.1112.cn
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;网站首页的优先级&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;#用于VirtualHost括号内，优先级从左往右依次降低
DirectoryIndex index.php index.html
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;错误日志&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 用于VirtualHost括号内，在apache配置目录应有logs文件夹，没有自己创建
Errorlog &quot;logs/chenchen1112.cn-error.log&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;访问日志&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;CustomLog &quot;logs/chenchen1112.cn-access.log&quot; common
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;错误页面的显示&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;ErrorDocument 404/missing.html
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装php5.6&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 添加PPA源
$ sudo add-apt-repository ppa:ondrej/php
# 若报错或没有发现命令则执行　$ sudo apt-get install python-software-properties
# 习惯性的更新源...
$ sudo apt-get update
# 安装php5.6
$ sudo apt-get install php5.6
# 验证版本
$ sudo php -v
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;apache2.conf文件，这个文件通过包含其他配置文件涵盖了所
让我们写个试试？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 进入www并创建新文件index.php
$ cd /var/www &amp;amp;&amp;amp; sudo vi index.php
# 写入到index.php	
&amp;lt;?php
phpinfo();
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置php&lt;/h3&gt;
&lt;p&gt;ubuntu serverd的php配置文件在&lt;code&gt;/etc/php/5.6/apache2/php.ini&lt;/code&gt;
近期发现php的时区是GMT（格林威治平时），而不是GMT+8（东八区）它们的显示时间会相差8个小时，这怎么行！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 打开php.ini配置文件
$ sudo vi /etc/php/5.6/apache2/php.ini
# 找到 date.timezone 并赋值 PRC（中华人民共和国英文缩写） date.timezone = PRC
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入我的公网ip查看一下&lt;/p&gt;
&lt;h2&gt;安装mysql&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 习惯性的更新源...
$ sudo apt-get update
# 安装mysql服务器与客户端，安装时会有两次交互，关于mysql密码的设置
$ sudo apt-get install mysql-server mysql-client

# 查看安装是否成功
$ sudo netstat -tap | grep mysql

root@VM-22-96-ubuntu:/etc/mysql/mysql.conf.d# sudo netstat -tap | grep mysql
tcp6       0      0 [::]:mysql              [::]:*                  LISTEN      7818/mysqld   
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置mysql&lt;/h3&gt;
&lt;p&gt;启动mysql的两种姿势&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo /etc/init.d/mysql start
# 或
$ sudo service mysql star
# [start] [restart] [stop] [status]
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;远程连接mysql&lt;/h4&gt;
&lt;p&gt;ubuntu serverd的mysql配置文件在&lt;code&gt;/etc/mysql/mysql.conf.d/mysqld.cnf&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 修改配置文件的端口绑定	
$ sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
# 注释掉 bind-adress = 127.0.0.1
# 进入数据库
$ mysql -u root -p
# 选择使用的数据库
mysql&amp;gt; use mysql;
# 修改host值（以通配符 % 增加主机/IP地址）当然你可以可以直接增加IP
mysql&amp;gt; update user set host = &apos;%&apos; where user = &apos;root&apos;;
# 让权限立即生效
mysql&amp;gt; flush privileges;
# 查看修改是否成功　**%         | root**说明远程连接已经开启 
mysql&amp;gt; select host, user from user;
+-----------+------------------+
| host      | user             |
+-----------+------------------+
| %         | root             |
| localhost | debian-sys-maint |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | root             |
+-----------+------------------+


# 如下连接成功！

achuan@achuan-pc:/etc/apache2$ mysql -h 139.199.105.72 -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.7.24-0ubuntu0.16.04.1 (Ubuntu)

Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type &apos;help;&apos; or &apos;\h&apos; for help. Type &apos;\c&apos; to clear the current input statement.

mysql&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;修改数据库编码&lt;/h4&gt;
&lt;p&gt;由于mysql默认编码为&lt;code&gt;latin&lt;/code&gt;如果不修改的话中文会导致数据库乱码报错，所以我们要修改为&lt;code&gt;utf8&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 打开my.cnf配置文件
$ sudo vi /etc/mysql/my.cnf
# 写入以下代码

[mysqld]
character-set-server = utf8
[client]
default-character-set = utf8
[mysql]
default-character-set = utf8

# 查看数据库编码
mysql&amp;gt; show variables like &apos;%char%&apos;;
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;安装phpmyadmin&lt;/h3&gt;
&lt;p&gt;不必要的情况下我还是喜欢可视化的操作mysql，开源的phpmyadmin就很不错！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 习惯性的更新源...
$ sudo apt-get update
# 安装phpmyadmin
$ sudo apt-get install phpmyadmin
# 虽然我们安装好了，但是phpmyadmin基于php环境开发的，所以我们需要把它放到网站的根目录/var/www，我这里在网站的根目录下放了一个软连接。
$ sudo ln -s /usr/share/phpmyadmin /var/www
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;输入网址即可： https://localhost/phpmyadmin&lt;/p&gt;
&lt;p&gt;这次部署Ubuntu Server体会不少，我真是越来越喜欢linux了，它真是一个非常有魅力的系统！哈哈哈，到这里吧，太晚了要回寝室睡觉了--&lt;br /&gt;
本篇文章如有写的不足之处，还请您多多指教！88！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Ubuntu%20Server%E9%83%A8%E7%BD%B2%E6%97%A5%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2021-02-12-ubuntu-deployment&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>爱上Go语言：常量与枚举</title><link>https://blog.lhasa.icu/posts/technology/2020-12-19-golang-consts</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-12-19-golang-consts</guid><pubDate>Sat, 19 Dec 2020 03:26:00 GMT</pubDate><content:encoded>&lt;h2&gt;常量&lt;/h2&gt;
&lt;p&gt;常量，一经定义不可改变的量，当出现不需要被更改的数据时，应该使用常量进行储存，从语法角度看，使用常量可以保证数据，在整个运行期间内，不会被更改&lt;/p&gt;
&lt;p&gt;常量的值仅仅支持，基础类型，字符串，字符，整型，浮点，布尔&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
)

func consts() {
	const (
        // 类型可以通过值推导出来，例如这个 filename 就是一个字符串
		filename = &quot;abc.txt&quot;
		a, b     = 3, 4
	)
	var c int
	// 常量没有定义类型的情况下，其数值可作为各种类型使用
	c = int(math.Sqrt(a*a + b*b))
	fmt.Println(filename, c)
}

func main() {
	consts()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;枚举&lt;/h2&gt;
&lt;p&gt;其实Golang并没有enum，但是可以使用 const和iota 来模拟枚举&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
)

func enums() {
	const (
		// iota 初始化后会自动递增
		c = iota
		_
		java
		php
		javascript
	)

	const (
		b = 1 &amp;lt;&amp;lt; (10 * iota)
		kb
		mb
		gb
		tb
		pb
	)

	// 0 2 4 3
	fmt.Println(c, java, javascript, php)

	// 1 1024 1048576 1073741824 1099511627776 1125899906842624
	fmt.Println(b, kb, mb, gb, tb, pb)
}


func main() {
	enums()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%88%B1%E4%B8%8AGo%E8%AF%AD%E8%A8%80%EF%BC%9A%E5%B8%B8%E9%87%8F%E4%B8%8E%E6%9E%9A%E4%B8%BE&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-12-19-golang-consts&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>爱上Go语言：变量定义与内建变量类型</title><link>https://blog.lhasa.icu/posts/technology/2020-12-18-golang-variable</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-12-18-golang-variable</guid><pubDate>Fri, 18 Dec 2020 03:46:00 GMT</pubDate><content:encoded>&lt;h2&gt;变量的定义&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;package main

import &quot;fmt&quot;

func variableZeroValue() {
	// var 关键字表示定义变量，定义变量时，名在前，类型在后
	// int默认值为0，string为空字符串
	var a int
	var s string
	fmt.Printf(&quot;%d %q\n&quot;, a, s)
}

func variableInitialValue() {
	// Golang语法严格，定义的变量必须被使用，否则报错：declared but not used
	var a, b int = 3, 4
	var s string = &quot;abc&quot;
	fmt.Println(a, b, s)
}
func variableTtypeDeduction() {
	// 定义多个变量的同时，也可以给其定义类型
	var a, b, c, s = 3, 4, true, &quot;def&quot;
	fmt.Println(a, b, c, s)
}

func variableShorter() {
	// : 冒号也表示定义变量，注意定义变量时才用！！！
	a, b, c, s := 3, 4, true, &quot;def&quot;
	// 若变量重复定义则会报错：no new variables on left side of :=
	b = 5
	fmt.Println(a, b, c, s)
}

// 在函数内定义的变量，它作用域只在函数内，但函数外也可以定义变量
// 不管函数内还是函数外都可以使用 var() 集中定义变量
var (
	id   = 1
	user = &quot;achuan&quot;
)

// 需要注意的是，在函数外定义变量只可以用var关键字进行定义，不能使用冒号
// 否则报错：syntax error: non-declaration statement outside function body
//ges := 20

// 注意上面定义的id，user变量，它们的作用域不是&quot;全局变量&quot;，而是包内部的变量
// Golang没有全局变量这个说法，只是包内部的

func main() {
	fmt.Println(&quot;Hi achuan&quot;)
	variableZeroValue()
	variableInitialValue()
	variableTtypeDeduction()
	variableShorter()
	fmt.Println(id, user)
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;内建变量类型&lt;/h2&gt;
&lt;h3&gt;布尔与字符串&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;bool、string&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;bool再了解不过了吧，它的值只有两种：true、false，if和for语句的条件部分都是布尔的值，并且&lt;code&gt;==&lt;/code&gt;和&lt;code&gt;&amp;lt;&lt;/code&gt;等比较操作也会产生bool值&lt;/p&gt;
&lt;p&gt;string是一个不可改变的字节序列，字符串可以包含任意的数据&lt;/p&gt;
&lt;h3&gt;整数型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;(u)int、(u)int8、(u)int16、(u)int32、(u)int64、uintptr&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;加（u）是无符号整数，不加（u）是有符号整数，有符号整数还分两类，一类规定长度的，如int8、int32、int64。还有一类是不规定长度的，不规定长度的是根据操作系统来，在32位操作系统里面它就是32位，在64位系统它就是64位&lt;/p&gt;
&lt;p&gt;还要一个uintptr类型，这个ptr就是指针，这个指针的长度也是跟着操作系统来的&lt;/p&gt;
&lt;p&gt;uintptr类型是无符号整型，用于存放一个指针，等过几天再详细学一下&lt;/p&gt;
&lt;h3&gt;字符型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;byte、rune&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Golang字符型有两种，一种是uint8，另一种就是rune&lt;/p&gt;
&lt;p&gt;byte就是uint8的别名，即一个字节长度，常用来处理ASCII字符&lt;/p&gt;
&lt;p&gt;rune同等于int32，代表一个UTF-8字符，即4个字节吗，常用于处理中文或其他复合字符&lt;/p&gt;
&lt;h3&gt;浮点型&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;float32、float64&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Golang提供了两种浮点型：float32和float64，它们的算术规范是由&lt;a href=&quot;https://zh.wikipedia.org/zh-cn/IEEE_754&quot;&gt;IEEE754国际标准&lt;/a&gt;定义，现代CPU都实现来这个规范。&lt;/p&gt;
&lt;p&gt;浮点数能够表示的极限范围可以在&lt;code&gt;math&lt;/code&gt;包中获取，&lt;code&gt;math.MaxFloat32&lt;/code&gt;表示float32的最大值，约3.4e38，&lt;code&gt;math.MaxFloat64&lt;/code&gt;大约是1.8e308，两个类型最小的非负值大约是1.4e-45和4.9e-324&lt;/p&gt;
&lt;p&gt;float32大约可以提供小数点后6位的精度，而float64可以提供小数点后15位的精度。&lt;/p&gt;
&lt;p&gt;Golang也提供了两种大小的复数：complex64和complex128，分别由float32和float64组成。内置函数&lt;code&gt;complex&lt;/code&gt;从指定的实部和虚部构建复数，内置函数&lt;code&gt;real&lt;/code&gt;和&lt;code&gt;imag&lt;/code&gt;用来获取复数的实部和虚部&lt;/p&gt;
&lt;p&gt;例如&lt;a href=&quot;https://zh.wikipedia.org/zh-hans/%E6%AC%A7%E6%8B%89%E5%85%AC%E5%BC%8F&quot;&gt;欧拉公式：&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
	&quot;math/cmplx&quot;
)

func euler() {
	fmt.Printf(cmplx.Exp(1i*math.Pi)+1)
}

func main() {
	euler()
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;强制类型转换&lt;/h2&gt;
&lt;p&gt;Golang是一种强类型语言，不同类型的数据不能赋值，不能在函数中传参，我个人是很喜欢这种。因很多错误在编译期间就被揪出来来，不像PHP等弱类型语言，很多错误只有运行时才能被发现，如下面这个例子：&lt;/p&gt;
&lt;p&gt;用Golang求出直角三角形斜边值&lt;code&gt;5&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;example.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
)

func triangle() {
	var a, b int = 3, 4
	var c int
	// 参数类型不一致报错：cannot use a * a + b * b (type int) as type float64 in argument to math.Sqrt
	// c = int(math.Sqrt(a*a + b*b))
	// 因为Sqrt参数要求float64类型，Golang语法严格，必须强制性转换
	c = int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println(c)
}

func main() {
	triangle()
}

// 5
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%88%B1%E4%B8%8AGo%E8%AF%AD%E8%A8%80%EF%BC%9A%E5%8F%98%E9%87%8F%E5%AE%9A%E4%B9%89%E4%B8%8E%E5%86%85%E5%BB%BA%E5%8F%98%E9%87%8F%E7%B1%BB%E5%9E%8B&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-12-18-golang-variable&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Manjaro Linux 双显卡切换解决方案</title><link>https://blog.lhasa.icu/posts/technology/2020-10-15-manjaro-dual-graphics</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-10-15-manjaro-dual-graphics</guid><pubDate>Thu, 15 Oct 2020 08:41:00 GMT</pubDate><content:encoded>&lt;h2&gt;1.卸载原有开源驱动&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看安装了哪些显卡驱动，全部删除
$ mhwd -li
$ sudo mhwd -r pci video-nvidia
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2.安装NVIDIA闭源驱动&lt;/h2&gt;
&lt;p&gt;具体这个驱动版本可以根据显卡型号去&lt;a href=&quot;https://www.nvidia.com/Download/index.aspx?lang=en-us&quot;&gt;NVIDIA官方查询&lt;/a&gt;，我的是GTX1060&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo mhwd -i pci video-nvidia-450xx
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3.安装依赖&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查询Linux内核版本
$ uname -r
5.8.11-1-MANJARO

# inux58-headers这个内核头文件包名‘58’是内核版本缩写
$ sudo pacman -S linux58-headers acpi_call-dkms xorg-xrandr xf86-video-intel git
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4.挂载acpi_call模块&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ sudo modprobe acpi_call
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果遇到&lt;code&gt;modprobe: FATAL: Module acpi_call not found in directory&lt;/code&gt;报错，需要安装&lt;code&gt;acpi_call&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装时注意选择相应的内核版本
$ sudo pacman -S acpi_call
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;5.清理文件&lt;/h2&gt;
&lt;p&gt;如果以下目录下有任何定义&lt;code&gt;video/gpu.conf&lt;/code&gt;文件，请备份/删除。因为脚本会删除所有的文件。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/X11/
/etc/X11/mhwd.d/
/etc/X11/xorg.conf.d/
/etc/modprobe.d/
/etc/modules-load.d/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;6.安装切换脚本&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ git clone git@github.com:dglt1/optimus-switch-sddm.git
$ cd optimus-switch-sddm
$ chmod +x install.sh
$ sudo ./install.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;7.切换命令&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 切换为Intel
$ sudo set-intel.sh
# 切换为NVIDIA
$ sudo set-nvidia.sh

# 切换后需要重启才能生效
$ reboot
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;相关文档&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dglt1/optimus-switch-sddm&quot;&gt;脚本英文文档&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/linesma/Optimus-indicator&quot;&gt;GUI切换&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Manjaro%20Linux%20%E5%8F%8C%E6%98%BE%E5%8D%A1%E5%88%87%E6%8D%A2%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-10-15-manjaro-dual-graphics&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Manjaro Linux 自动禁用触摸板</title><link>https://blog.lhasa.icu/posts/technology/2020-09-30-disabletouchpad</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-09-30-disabletouchpad</guid><pubDate>Wed, 30 Sep 2020 04:57:00 GMT</pubDate><content:encoded>&lt;h2&gt;安装&lt;/h2&gt;
&lt;p&gt;安装必要的函数库和驱动程序&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S libinput xf86-input-libinput xorg-xinput
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;编写Shell脚本&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ vim DisableTouchpad.sh

#!/bin/bash

declare -i ID
ID=`xinput list | grep -Eio &apos;(touchpad|glidepoint)\s*id\=[0-9]{1,2}&apos; | grep -Eo &apos;[0-9]{1,2}&apos;`
declare -i STATE
STATE=`xinput list-props $ID|grep &apos;Device Enabled&apos;|awk &apos;{print $4}&apos;`
if [ $STATE -eq 1 ]
then
    xinput disable $ID
else
    xinput enable $ID
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;赋予脚本读/写/执行权限&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo chmod 0755 DisableTouchpad.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Systemd 自启动&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ cd /usr/lib/systemd/system
# 创建Systemd服务
$ sudo vim touchpad.service

[Unit]
Description=Touchpad control service

[Service]
Type=oneshot
ExecStart=/File/Self-starting/DisableTouchpad.sh

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置&lt;code&gt;touchpad&lt;/code&gt;服务自启动&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ systemctl enable touchpad
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Manjaro%20Linux%20%E8%87%AA%E5%8A%A8%E7%A6%81%E7%94%A8%E8%A7%A6%E6%91%B8%E6%9D%BF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-09-30-disabletouchpad&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Docker Compose 快速构建 LNMP 笔记</title><link>https://blog.lhasa.icu/posts/technology/2020-09-25-docker-lnmp</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-09-25-docker-lnmp</guid><pubDate>Fri, 25 Sep 2020 01:41:00 GMT</pubDate><content:encoded>&lt;h2&gt;目录结构&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;/
├── data                        数据库数据目录
│   ├── esdata                  ElasticSearch 数据目录
│   ├── mongo                   MongoDB 数据目录
│   ├── mysql                   MySQL8 数据目录
│   └── mysql5                  MySQL5 数据目录
├── services                    服务构建文件和配置文件目录
│   ├── elasticsearch           ElasticSearch 配置文件目录
│   ├── mysql                   MySQL8 配置文件目录
│   ├── mysql5                  MySQL5 配置文件目录
│   ├── nginx                   Nginx 配置文件目录
│   ├── php                     PHP5.6 - PHP7.3 配置目录
│   ├── php54                   PHP5.4 配置目录
│   └── redis                   Redis 配置目录
├── logs                        日志目录
├── docker-compose.sample.yml   Docker 服务配置示例文件
├── env.smaple                  环境配置示例文件
└── www                         PHP 代码目录
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;快速使用&lt;/h2&gt;
&lt;p&gt;如果当前用户不是root，为了避免频繁输入root密码，需要将当前用户加入docker组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建Docker组  注：安装Docker时就自动创建了，如果没有则手动创建
$ sudo groupadd docker
# 当前用户加入Docker组
$ sudo gpasswd -a ${USER} docker
# 将当前用户的group切换到docker用户组
$ newgrp docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Clone项目&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ gh repo clone achuanya/dnmp
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;拷贝文件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ cd dnmp
# 复制环境变量文件
$ cp env,sample .env
# 复制docker-compose配置文件
$ cp docker-compose.sample.yml docker-compose.yml
# 创建并后台运行
$ docker-compose up -d
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;PHP与扩展&lt;/h2&gt;
&lt;h3&gt;切换Nginx使用的PHP版本&lt;/h3&gt;
&lt;p&gt;1.比如，从php切换到php56，那就先在&lt;code&gt;docker-compose.yml&lt;/code&gt;文件中查看PHP56有没有被注释掉，删掉注释后启动，再更改Nginx配置文件：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;fastcgi_pass   php:9000;
更改为：
fastcgi_pass   php56:9000;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;其中&lt;code&gt;php&lt;/code&gt;和&lt;code&gt;php56&lt;/code&gt;是&lt;code&gt;docker-compose.yml&lt;/code&gt;文件中&lt;code&gt;容器的NAME名称&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;2.让其配置生效还需再重新加载Nginx配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker exec -it nginx nginx -s reload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里有两个&lt;code&gt;Nginx&lt;/code&gt;，第一个是容器NAME名称，第二个是容器中的Nginx程序&lt;/p&gt;
&lt;h3&gt;在宿主机安装PHP扩展&lt;/h3&gt;
&lt;p&gt;1.如果要安装更多PHP扩展，在根目录找到&lt;code&gt;.env&lt;/code&gt;环境配置文件，如以下PHP扩展配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 安装扩展应当使用英文逗号隔开
PHP56_EXTENSIONS=pdo_mysql,mysqli,mbstring,gd,curl,opcache,redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.保存完成后，重新构建镜像&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker-compose build php
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;在Docker中安装扩展&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ docker exec -it php /bin/sh
# 安装redis扩展
$ install-php-extensions redis
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;支持安装扩展列表&lt;/h3&gt;
&lt;p&gt;此扩展来自Michele Locati，请前往查看最新支持的PHP扩展&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;https://github.com/mlocati/docker-php-extension-installer&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;在宿主机中使用命令行&lt;/h2&gt;
&lt;h3&gt;PHP CLI&lt;/h3&gt;
&lt;p&gt;1.参考根目录&lt;a href=&quot;https://github.com/achuanya/dnmp/blob/master/bash.alias.sample&quot;&gt;bash.alias.sample&lt;/a&gt;示例文件，将PHP CLI函数拷贝到&lt;code&gt;/etc/profile&lt;/code&gt;系统环境变量文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 刷新系统环境变量
$ source /etc/profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.在宿主机中执行PHP命令了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; ~ [06:24:00]
achuan$ php -v
PHP 7.4.7 (cli) (built: Jun 11 2020 19:07:15) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.7, Copyright (c), by Zend Technologies
    
 ~ [06:24:04]
achuan$ php56 -v
PHP 5.6.40 (cli) (built: Jan 31 2019 01:30:45) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Composer&lt;/h3&gt;
&lt;p&gt;1.首先确定Composer缓存目录，Composer配置文件在根目录中的&lt;code&gt;data/composer&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;2.参考根目录&lt;a href=&quot;https://github.com/achuanya/dnmp/blob/master/bash.alias.sample&quot;&gt;bash.alias.sample&lt;/a&gt;示例文件，将PHP CLI函数拷贝到&lt;code&gt;/etc/profile&lt;/code&gt;系统环境变量文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 刷新系统环境变量
$ source /etc/profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.之后就可以在宿主机使用Composer命令了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ cd /work/dnmp/www
$ composer -V
Composer version 1.10.13 2020-09-09 11:46:34
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.第一次使用Composer后&lt;code&gt;data/composer&lt;/code&gt;目录下会生成&lt;code&gt;config.json&lt;/code&gt;全局配置文件，可指定镜像，例如中国全量镜像：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &quot;config&quot;: {},
    &quot;repositories&quot;: {
        &quot;packagist&quot;: {
            &quot;type&quot;: &quot;composer&quot;,
            &quot;url&quot;: &quot;https://packagist.phpcomposer.com&quot;
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或使用命令修改Composer的全局配置文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ composer config -g repo.packagist composer https://packagist.phpcomposer.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;管理命令&lt;/h2&gt;
&lt;h3&gt;容器的创建、启动与构建&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ docker-compose
	up # 创建并且启动所有容器
	up -d # 创建并且后台运行所有容器
	up nginx php mysql # 创建并且启动多个容器
	
	start # 启动容器
	stop # 停止容器
	restart # 重启容器
	build # 构建容器
	
	rm # 停止并且删除容器
	down # 停止并且删除容器、网络、图像与挂载卷
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;快捷命令&lt;/h3&gt;
&lt;p&gt;1.参考根目录&lt;a href=&quot;https://github.com/achuanya/dnmp/blob/master/bash.alias.sample&quot;&gt;bash.alias.sample&lt;/a&gt;示例文件，将Composer函数拷贝到&lt;code&gt;/etc/profile&lt;/code&gt;系统环境变量文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 刷新系统环境变量
$ source /etc/profile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.例如，进入php容器&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ dphp
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Docker%20Compose%20%E5%BF%AB%E9%80%9F%E6%9E%84%E5%BB%BA%20LNMP%20%E7%AC%94%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-09-25-docker-lnmp&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)一个关于if else容易迷惑的问题</title><link>https://blog.lhasa.icu/posts/technology/2020-08-23-if-else-confuse</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-08-23-if-else-confuse</guid><pubDate>Sun, 23 Aug 2020 09:05:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://www.laruence.com/2020/07/09/6015.html&quot;&gt;Laruence&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这个本来是之前在微博上有个同学说他经常用来面试别人，大概是说，对于如下代码，你觉得会输出啥:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$a = true;if ($a) {  echo &quot;true&quot;;} else label: {  echo &quot;false&quot;;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;当时觉得有点偏，没想写，今天中午又有人问我，我想那就介绍下这个原因吧.&lt;/p&gt;
&lt;p&gt;首先，上面的代码输出truefalse, 如果你知道原因，那就不用继续往下看了，如果不知道，那么:&lt;/p&gt;
&lt;p&gt;这块让人比较迷惑的原因可能是因为，我们会很直观的认为:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;label : {  statement;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;应该是一个整体， 就好比类似:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if ($a) {} else switch($a) {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;或者:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if ($a) {} else do {} while (!$a);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为在PHP的语法设计中，if else本质上是:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if_stmt: if_stmt_without_else T_ELSE statement
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是说，else后面可以接一切statement，如果条件不成立，执行流就跳到else后面的statement，而while, switch都可以归约为statement。&lt;/p&gt;
&lt;p&gt;但label这块稍微有点特别（可以说是一个设计违反直觉的”缺陷”吧), 在zend_language_parser.y中:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;statement:  ...  | T_DO statement T_WHILE &apos;(&apos; expr &apos;)&apos; &apos;;&apos; {...}  | T_SWITCH &apos;(&apos; expr &apos;)&apos; switch_case_list {...}  | T_STRING ‘:’ { $$ = zend_ast_create(ZEND_AST_LABEL, $1); }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;大家可以看到， do while, switch 都会联合他们的body归约为statement（语句），但标签（label）有点不同，”label :”本身会规约为一条statement， 这就导致了这个看起来比较迷惑的问题的出现，他本质上就变成了:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$a = true;if ($a) { echo &quot;true&quot;;} else { label: ;  //单独的一条语句}echo &quot;false&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后多说一句，我忘了之前在那看到的，说是这个世界上本无elseif，有的只不过是else (if statement)，本质上其实就跟这个意思是一样的。 就是，else后面可以接语句（statement）。&lt;/p&gt;
&lt;p&gt;善用这个结合switch, for, do while等，有的时候可以让我们的代码更精简。
比如，我们要遍历处理一个数组，当数组的长度为零的时候，要做点其他事，那很多人可能会这么写:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (count($array)) {  for ($i = 0; $i &amp;lt; count($array); $i++) {  }} else {  //数组为空的逻辑}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但你也可以写成:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if (count($array) == 0) {   //数组为空的逻辑} else for ($i = 0; $i &amp;lt; count($array); $i++) {}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;至于这俩中写法孰好孰坏， 那就是萝卜白菜了。&lt;/p&gt;
&lt;p&gt;最后，大家如果在实际中遇到类似让大家觉得迷惑的问题，可以留言，也许以后也可以单独成文。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E4%B8%80%E4%B8%AA%E5%85%B3%E4%BA%8Eif%20else%E5%AE%B9%E6%98%93%E8%BF%B7%E6%83%91%E7%9A%84%E9%97%AE%E9%A2%98&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-08-23-if-else-confuse&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>使用开源项目免费申请 JetBrains 开源许可证</title><link>https://blog.lhasa.icu/posts/life/2020-08-22-jetbrains-open-source-license</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2020-08-22-jetbrains-open-source-license</guid><pubDate>Sat, 22 Aug 2020 00:31:00 GMT</pubDate><content:encoded>&lt;p&gt;JetBrains公司旗下产品都太棒了，我是深陷其中不可自拔，离了这个软件我写啥都不舒服，最近更新一下PHPSTORM之后发现网上买的教育认证老是失效，最终我在网上发现可以用开源项目免费申请到JetBrains全家桶且为Ultimate版本！免费订阅有效期为一年，许可证到期前不久，JetBrains会有电子邮件进行续订提醒！不过申请还是有要求的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你必须是项目的发起人或是活跃的 commiter&lt;/li&gt;
&lt;li&gt;你的项目需要积极开发3个月以上&lt;/li&gt;
&lt;li&gt;定期发布版本&lt;/li&gt;
&lt;li&gt;符合开源的定义，不能包含有关商业性质的内容&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;如何申请&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.jetbrains.com/shop/eform/opensource?product=ALL&quot;&gt;JetBrains开源许可证申请&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;填写表单就行了，提交申请后我两天后就收到了JetBrains官方的电子邮件。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;success.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BD%BF%E7%94%A8%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE%E5%85%8D%E8%B4%B9%E7%94%B3%E8%AF%B7%20JetBrains%20%E5%BC%80%E6%BA%90%E8%AE%B8%E5%8F%AF%E8%AF%81&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2020-08-22-jetbrains-open-source-license&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>今天我去钓鱼了</title><link>https://blog.lhasa.icu/posts/life/2020-06-29-fishing</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2020-06-29-fishing</guid><pubDate>Mon, 29 Jun 2020 07:44:00 GMT</pubDate><content:encoded>&lt;p&gt;今早晨9点多醒了，透过窗户看看天气不错，看看手机了解今最低气温23度，最高气温31度，很适合钓鱼鲢鱼。&lt;/p&gt;
&lt;p&gt;我正在穿衣服顺丰小哥就来电话了，前几天竿稍被我不小心折断了，虽然换了竿稍绳但是还是感觉不舒服。&lt;/p&gt;
&lt;p&gt;在狗东宝飞龙旗舰店花50多补了件竿稍，竿稍拿到换好确定没有问题后 饭都没吃我提着包就走了。&lt;/p&gt;
&lt;p&gt;到了地方后大概9点多了，开始干活了 装配钓椅、打窝又支伞...
大概20分钟东西准备好了。调漂、搓耳抛出了今的第一杆，因为我调的饵料物化较快，所以第一杆很快结束。&lt;/p&gt;
&lt;p&gt;收杆后搓耳抛出了第二杆，抛杆后直接放在炮台上，感觉刚打窝应该还没啥鱼，有点热脱掉外套。就特么在这时候，漂上下急跳，我急忙扔下外套直接猛提杆！&lt;/p&gt;
&lt;p&gt;中鱼了，劲还不小！溜大概半分钟漏个身 看得出来不是正口，锚的，直觉告诉我大概有3斤多，特么爽啊，上鱼真快今的第一炮，在第二杆打响！&lt;/p&gt;
&lt;p&gt;就在我高兴的时候，它脱钩了.....我特么.....艾。不过掉到中午的时候我也习惯了，今一早上我锚鱼 脱钩不下于10次......&lt;/p&gt;
&lt;p&gt;大概六七杆左右吊到今第一条鱼———花鲢。大概有一斤多左右。杆子不是很硬37调，抄网都没用稍微使劲鱼直接飞上来。&lt;/p&gt;
&lt;p&gt;比较遗憾的是上午脱钩了很多鱼，上午大概上了三四条全正口。看我发窝却上不了鱼，旁边老哥告诉我，我这新关东2号钩无倒刺，如果不是正口，溜鱼的话很容易跑。
我大概坚持两杆锚到一个不过又脱钩.....无奈之下换回前几天用的伊势尼10号钩。不想用倒刺钩原因是我老挂着东西，不好去掉。&lt;/p&gt;
&lt;p&gt;到了下午两三点的时候，我左手搓耳搓的手疼，频繁提杆有点累了，正好饵料快用完了，我借旁边老哥拉丝粉又搞了一些饵料。&lt;/p&gt;
&lt;p&gt;不一会儿有人来了，问我钓多少，我说大概7条，父女俩说想买，我听口音感觉他不是本地人。他们父女俩我们这旅游游玩，说想买我的鱼拿回去养，养大了再吃。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;sevenfish.png&quot; alt=&quot;七条鲢鱼&quot; /&gt;&lt;/p&gt;
&lt;p&gt;我当时挺蒙蔽的....第一回遇见这事，没了解过行情价格，想想早上买了饵料和鱼钩花了20多，给个饵料钱30吧。&lt;/p&gt;
&lt;p&gt;父女俩说三四十都行，我说三十就行，我这没有袋子，父女俩回车拿了个水桶箱，我把鱼放进去后。&lt;/p&gt;
&lt;p&gt;这时候男的犹豫一下，说鱼不是很大，吃了感觉有点残忍.....当时周围一几个人都特么蒙了.....说在家养着还是等会儿放生了。&lt;/p&gt;
&lt;p&gt;后来还是要了，微信给我转了30抱着水桶箱走了，旁边几个老哥说咋不多要点，人家外地来的有钱不缺钱，觉得咱龙湖里鱼好，要100都给...&lt;/p&gt;
&lt;p&gt;过了会儿，累了躺椅子，没一会我看见直接黑漂了，连忙起身提杆，鱼线直接拉直，鱼毛都没见，它一发力2.5主线加漂直接秒切...&lt;/p&gt;
&lt;p&gt;上午我还说想尝尝爆杆啥感觉，没想到切线了.....旁边老哥都说鱼不小，也有可能说线伤了，因为上午提杆过猛挂树上好几次。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;tangent.png&quot; alt=&quot;切剩下的线&quot; /&gt;&lt;/p&gt;
&lt;p&gt;翻翻渔具包，找不到5.4米的线了，一堆4米的，除了钩子和主线，太空豆还没买。&lt;/p&gt;
&lt;p&gt;旁边老哥好心拿他线给我做一套线组。3号主线配1.5子线，钩子伊势尼10号。说线不太好，不过拉个四五斤没问题，在这再谢谢我老哥&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;doawireset.png&quot; alt=&quot;老哥在帮我做线组&quot; /&gt;&lt;/p&gt;
&lt;p&gt;钓着钓着快6点了，哥几个下午鱼口不太好掉了，钓一天了，大伙聊垂钓、聊新闻还有八卦三四个人说说笑笑，几个人互相认识一下，加个微信创个群，挺开心的。&lt;/p&gt;
&lt;p&gt;我大概又钓了三条鲢鱼，老哥几个家离得远准备前走了，太少了不想吃，给他们都不要，我把鱼放湖里了，收拾一下也准备走了。&lt;/p&gt;
&lt;p&gt;临走拍张照晒一下哈哈哈&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;mygear.png&quot; alt=&quot;我的装备&quot; /&gt;&lt;/p&gt;
&lt;p&gt;弦歌台垂钓区&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;landscape.png&quot; alt=&quot;龙湖&quot; /&gt;&lt;/p&gt;
&lt;p&gt;回到家后洗洗澡，把回来时配的线组再截一下，4号主线配2号子线，老哥说窝子弹簧物化不错，我配上试了试，钩子伊势尼10号&lt;/p&gt;
&lt;p&gt;我感觉4号主线和10号钩有点大材小用，毕竟我钓鱼大多在1-5斤左右。不过想想线细了被切了呢，唉，大鱼可遇不可求啊！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;newlinegroup.png&quot; alt=&quot;新线组&quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天钓的鱼还是挺多的，哈哈哈，10条，大概十三四斤还多的样子，很是开心！
锚十几个的如果都上来20斤起步了。唉，我不太会钓，加油把！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BB%8A%E5%A4%A9%E6%88%91%E5%8E%BB%E9%92%93%E9%B1%BC%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2020-06-29-fishing&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>JetBrains 官方推中文简体包了</title><link>https://blog.lhasa.icu/posts/technology/2020-04-26-phpstorm-official-chinese</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-04-26-phpstorm-official-chinese</guid><pubDate>Sun, 26 Apr 2020 01:25:00 GMT</pubDate><content:encoded>&lt;p&gt;今天我在 Github &lt;a href=&quot;https://github.com/pingfangx/TranslatorX&quot;&gt;TranslatorX&lt;/a&gt; 这个 IDE 汉化项目的 Issues 下看到有个 JetBrains 员工说关于中文包的事：&lt;/p&gt;
&lt;p&gt;Hi, I&apos;m a JetBrains employee, and we&apos;re working on initial support for the Chinese language pack. If you&apos;re interested in, feel free to contact me: &lt;a href=&quot;mailto:ignatov@jetbrains.com&quot;&gt;ignatov@jetbrains.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cheers, Sergey.&lt;/p&gt;
&lt;p&gt;然后前不久 1-17 号官方中文插件在 2020.1 的 EAP 版本已经推出了，相见恨晚啊！&lt;/p&gt;
&lt;p&gt;然而朋友说中文IDE没有灵魂，这这这...&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://plugins.jetbrains.com/plugin/13710-chinese-simplified-language-pack&quot;&gt;Chinese (Simplified) Language Pack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;style.png&quot; alt=&quot;界面&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;2020-05-08更新&lt;/h2&gt;
&lt;p&gt;在 Plugins 里面搜索 Chinese，安装后重启即可。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=JetBrains%20%E5%AE%98%E6%96%B9%E6%8E%A8%E4%B8%AD%E6%96%87%E7%AE%80%E4%BD%93%E5%8C%85%E4%BA%86&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-04-26-phpstorm-official-chinese&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>ThinkPHP 6.0 下载安装与配置</title><link>https://blog.lhasa.icu/posts/technology/2020-04-14-thinkphp6-installation</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-04-14-thinkphp6-installation</guid><pubDate>Tue, 14 Apr 2020 07:28:00 GMT</pubDate><content:encoded>&lt;ul&gt;
&lt;li&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ThinkPHP &lt;code&gt;6.0&lt;/code&gt; 要求 PHP &amp;gt;= &lt;code&gt;7.1.0&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;6.0&lt;/code&gt;版本开始，必须通过&lt;code&gt;Composer&lt;/code&gt;方式安装和更新，无法使用Git下载安装。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;安装Composer&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ curl -sS https://getcomposer.org/installer | php

# 全局调用
$ sudo mv composer.phar /usr/local/bin/composer

 /usr/src [09:22:13]
achuan$ composer
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.10.5 2020-04-10 11:44:22

# 使用阿里云镜像
$ composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 稳定版
$ composer create-project topthink/think tp6

# 开发版
$ composer create-project topthink/think=6.0.x-dev tp6

# 更新已安装的旧版本核心框架
$ composer update topthink/framework
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# apache配置
$ sudo vim /etc/httpd/conf/extra/httpd-vhosts.conf
&amp;lt;VirtualHost *:80&amp;gt;
    ServerName tp6.io
    DocumentRoot /home/achuan/language/php/tp6/public
    &amp;lt;Directory  &quot;/home/achuan/language/php/tp6/&quot;&amp;gt;
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;

$ sudo vim /etc/hosts
127.0.0.1 tp6.io

# 不进行apache配置也可以测试运行 默认端口为：8000
$ php think run -p 1081

# 环境变量定义 可以更名为.env进行修改生效，该文件默认开启调试模式。
$ mv example.env .env

# 对外访问
$ sudo chmod -R 777 public

# 安装多应用模式扩展 think-multi-app
$ composer require topthink/think-multi-app
# 创建一个名为 index 的应用，返回Successed则成功
$ php think build index
# 多应用模式部署后，必须要删除controller目录，因为系统根据该目录作为判断是否为单应用
$ rm -rf controller
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;目录结构&lt;/h2&gt;
&lt;h3&gt;单应用模式&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;www  WEB部署目录（或者子目录）
├─app           应用目录
│  ├─controller      控制器目录
│  ├─model           模型目录
│  ├─ ...            更多类库目录
│  │
│  ├─common.php         公共函数文件
│  └─event.php          事件定义文件
│
├─config                配置目录
│  ├─app.php            应用配置
│  ├─cache.php          缓存配置
│  ├─console.php        控制台配置
│  ├─cookie.php         Cookie配置
│  ├─database.php       数据库配置
│  ├─filesystem.php     文件磁盘配置
│  ├─lang.php           多语言配置
│  ├─log.php            日志配置
│  ├─middleware.php     中间件配置
│  ├─route.php          URL和路由配置
│  ├─session.php        Session配置
│  ├─trace.php          Trace配置
│  └─view.php           视图配置
│
├─view            视图目录
├─route                 路由定义目录
│  ├─route.php          路由定义文件
│  └─ ...   
│
├─public                WEB目录（对外访问目录）
│  ├─index.php          入口文件
│  ├─router.php         快速测试文件
│  └─.htaccess          用于apache的重写
│
├─extend                扩展类库目录
├─runtime               应用的运行时目录（可写，可定制）
├─vendor                Composer类库目录
├─.example.env          环境变量示例文件
├─composer.json         composer 定义文件
├─LICENSE.txt           授权说明文件
├─README.md             README 文件
├─think                 命令行入口文件
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;默认应用文件&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;├─app           应用目录
│  │
│  ├─BaseController.php    默认基础控制器类
│  ├─ExceptionHandle.php   应用异常定义文件
│  ├─common.php            全局公共函数文件
│  ├─middleware.php        全局中间件定义文件
│  ├─provider.php          服务提供定义文件
│  ├─Request.php           应用请求对象
│  └─event.php             全局事件定义文件
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;相关文档：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.kancloud.cn/manual/thinkphp6_0/1037479&quot;&gt;ThinkPHP6.0完全开发手册&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://haha.tpsns.com/video2/index.php?video_id=i0867pch5zw&quot;&gt;ThinkPHP6.0讲解教学&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/top-think/framework&quot;&gt;ThinkPHP6.0核心框架包&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=ThinkPHP%206.0%20%E4%B8%8B%E8%BD%BD%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-04-14-thinkphp6-installation&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Manjaro KDE 调教日记</title><link>https://blog.lhasa.icu/posts/technology/2020-04-09-manjaro-kde</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-04-09-manjaro-kde</guid><pubDate>Thu, 09 Apr 2020 03:24:00 GMT</pubDate><content:encoded>&lt;h2&gt;更换源&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 更新数据源
$ sudo pacman -Sy
# 选清华源 mirrors.tuna.tsinghua.edu.cn
$ sudo pacman-mirrors -i -c China -m rank
$ sudo pacman -Syu

# 添加Arch源
$ sudo vi /etc/pacman.conf
# 把下面这几行写进去
[archlinuxcn]
SigLevel = Optional TrustedOnly
Server = https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/$arch
$ sudo pacman -Syy &amp;amp;&amp;amp; sudo pacman -S archlinuxcn-keyring
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;基础设置&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S vim git rpm yay unzip snapd you-get annie
$ sudo systemctl enable --now snapd.socket

# Git代理，需配合Qv2ray使用
$ git config --global https.proxy https://127.0.0.1:8888

# 主目录改为英文
$ sudo pacman -S xdg-user-dirs-gtk
$ export LANG=en_US &amp;amp;&amp;amp;  xdg-user-dirs-gtk-update

# 将时区设置为中国上海
$ timedatectl set-timezone Asia/Shanghai

# 细长的等宽字体
$ yay -S ttf-iosevka

export http_proxy=&quot;socks5://127.0.0.1:1080&quot;
export ALL_PROXY=socks5://127.0.0.1:1080

# 禁用封锁
$ sudo vim /etc/security/faillock.conf
deny = 0

# 虚拟终端字体问题
$ sudo pacman -S terminus-font
$ sudo vim /etc/vconsole.conf
FONT=ter-132n
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;自动挂载NTFS硬盘&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看磁盘分区的UUID
$ sudo blkid -o list
# 5016CF88CCD20C21 就是我的UUID，同时要记录一下device和fs_type等会要用
device                   fs_type    label       mount point                  UUID
-------------------run----------------------------------------------------------------------------------------------
/dev/sdb1                ntfs       File        /run/media/achuan/File          5016CF88CCD20C21

# /dev/sdb1挂载点
$ mkdir ~/File
# 打开fastab文件，看到以下文件内容
$ sudo vim /etc/fstab
# /etc/fstab: static file system information.
#
# Use &apos;blkid&apos; to print the universally unique identifier for a device; this may
# be used with UUID= as a more robust way to name devices that works even if
# disks are added and removed. See fstab(5).
#
# &amp;lt;file system&amp;gt;             &amp;lt;mount point&amp;gt;  &amp;lt;type&amp;gt;  &amp;lt;options&amp;gt;  &amp;lt;dump&amp;gt;  &amp;lt;pass&amp;gt;
UUID=8a9b74b7-c33a-413b-b654-80f3a16b5e12 /home          ext4    defaults,noatime,discard 0 2
UUID=b23b3470-26c1-4b39-9358-43278c73763e /              ext4    defaults,noatime,discard 0 1
UUID=ad103e33-78b7-4b33-8632-03c3fe6364fc /boot          ext4    defaults,noatime,discard 0 2
UUID=b0d5e88d-136a-4fa6-b164-5d70e5073b5d /opt           ext4    defaults,noatime,discard 0 2
tmpfs                                     /tmp           tmpfs   defaults,noatime,mode=1777 0 0

# 从这个文件内容可以看出文件有6列
 - 第一列file system选项是UUID
 - 第二列mount point选项是挂载点
 - 第三列type选项是所要挂载设备的文件系统或者文件系统类型
 - 第四列options选项是挂载选项，常见参数如下
 
|  配置选项    | 选项说明                                            
|-------------|-----------------------------------------------------
| async/sync  | 设置是否为同步方式运行，默认为async
| auto/noauto | 当下载mount -a命令时，此系统是否被主动挂载，默认为auto
| rw/ro       | 是否以只读或读写模式挂载
| exec/noexec | 限制此文件系统内是否能够进行“执行”操作
| user/nouser | 是否允许用户使用mount命令挂载
| suid/nosuid | 是否允许SUID的存在
| userquota   | 启动文件系统支持磁盘配额模式
| grpquota    | 启动文件系统对群组磁盘配额模式的支持
| defaults    | 同时具有rw、suid、suid、dev、exec、auto、nouser、async等默认参数的设置
 deepin-wine-wechat
 - 第五列dump选项是文件系统备份选项。0备份，1备份
 - 第六列pass选项是磁盘检查设置，其值是一个顺序，0不检查，１检查（根目录永远都为1）其它分区从2开始，数字越小越先检查，如果有两个分区的数字相同，同时检查

# 这是挂载/dev/sdb1的挂载配置，插入一行保存退出
UUID=5016CF88CCD20C21                     /home/achuan/File ntfs   defaults 0 0

# 如果/etc/fstab配置不对，会导致系统无法启动！一定要检查一下是否能正确挂载！如果改挂了，找个U盘改回来就行了。
$ sudo mount -a
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;常用软件&lt;/h2&gt;
&lt;h3&gt;Vim配置&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Lightline
$ git clone https://github.com/itchyny/lightline.vim ~/.vim/pack/plugins/start/lightline

# 更换 PaperColor_dark.vim
$ mv -f ~/.vim/pack/plugins/start/lightline/autoload/lightline/colorscheme/PaperColor_dark.vim ~/.vim/pack/plugins/start/lightline/plugin/lightline.vim

# 编辑全局配置并写入以下配置 # 用户个人配置 ~/.vimrc
$ sudo vim /etc/vimrc

&quot; 语法高亮
syntax on
&quot; 底部状态显示
set showmode
&quot; 使用UTF-8编码
set encoding=utf-8  
&quot; 启用256色
set t_Co=256
&quot; 开启文件类型检查，并且载入与该类型对应的缩进规则
filetype indent on
&quot; 按回车后，下一行缩进自动同上
set autoindent
&quot; 按TAB，Vim显示的空格数量
set tabstop=4
&quot; 在文本上按下&amp;gt;&amp;gt;（增加一级缩进）、&amp;lt;&amp;lt;（取消一级缩进）或者==（取消全部缩进）时，每一级的字符数
set shiftwidth=4
&quot; 由于 TAB 键在不同的编辑器缩进不一致，该设置自动将 TAB 转为空格
set expandtab
&quot; TAB转为多少个空格
set softtabstop=4
&quot; 显示行号
set number
&quot; 光标所在当前行高亮
set cursorline
&quot; 设置行宽，即一行显示多少个字符
set textwidth=80
&quot; 自动折行，即太长的行分成几行显示
set wrap
&quot; 只有遇到指定的符号（比如空格、连词号和其他标点符号），才发生折行。也就是说，不会在单词内部折行
set linebreak
&quot; 是否显示状态栏。0 表示不显示，1 表示只在多窗口时显示，2 表示显示
set laststatus=2
&quot; 在状态栏显示光标的当前位置（位于哪一行哪一列）
set  ruler
&quot; 搜索时，高亮显示匹配结果
set hlsearch
&quot; 输入搜索模式时，每输入一个字符，就自动跳到第一个匹配的结果
set incsearch
&quot; 搜索时忽略大小写
set ignorecase
&quot; 如果有一个大写字母，则切换到大小写敏感查找
set smartcase 
&quot; 保存撤销历史
set undofile
&quot; 出错时，发出视觉提示
set visualbell
&quot; 保存Vim历史操作次数
set history=1000
&quot; 打开文件监视。如果在编辑过程中文件发生外部改变（比如被别的编辑器编辑了），就会发出提示
set autoread
&quot; 如果行尾有多余的空格（包括 Tab 键），该配置将让这些空格显示成可见的小方块
set listchars=tab:»■,trail:■
set list
&quot; 命令模式下，底部操作指令按下 Tab 键自动补全。第一次按下 Tab，会显示所有匹配的操作指令的清单；第二次按下 Tab，会依次选择各个指令
set wildmenu
set wildmode=longest:list,full
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Oh-My-Zsh&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S zsh
$ sh -c &quot;$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)&quot;
# 切换到zsh
$ chsh -s /bin/zsh
# 安装3den主题
$ sudo vim ~/.zshrc
ZSH_THEME=&quot;3den&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;小狼毫输入法&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 搜狗装了十几回，它那个兼容性真让我抓狂，还是小狼毫香。 
$ sudo  pacman -S ibus ibus-rime
$ yay -S ibus-qt
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 默认是繁体，需要可以改为简体中文
$ vim ~/.config/ibus/rime/luna_pinyin.custom.yaml
# luna_pinyin.custom.yaml
patch:
  switches:                   # 注意缩进
    - name: ascii_mode
      reset: 0                # reset 0 的作用是当从其他输入法切换到本输入法重设为指定状态
      states: [ 中文, 西文 ]   # 选择输入方案后通常需要立即输入中文，故重设 ascii_mode = 0
    - name: full_shape
      states: [ 半角, 全角 ]   # 而全／半角则可沿用之前方案的用法。
    - name: simplification
      reset: 1                # 增加这一行：默认启用「繁→簡」转换。
      states: [ 漢字, 汉字 ]

# 编辑系统环境变量并写入以下配置
$ sudo vim /etc/profile
export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus
ibus-daemon -d -x
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;搜狗输入法&lt;/h3&gt;
&lt;p&gt;2020-2-11 Update：现在已经有fcitx5包了，体验确实提升不少，ibus没有搜狗香了哈哈哈&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -Sy fcitx fcitx-configtool 
$ yay -Sy fcitx-sogoupinyin

# 编辑系统环境变量并写入以下配置
$ sudo vim /etc/profile
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=&quot;@im=fcitx&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;微信 TIM 完美解决方案&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# QQ
$ yay -S deepin-wine-qq
# 自动切换前确保 deepin-wine5 包的支持，完成后就可以启动使用了
$ /opt/apps/com.qq.im.deepin/files/run.sh -d
# 高分辨率屏幕支持
$ env WINEPREFIX=&quot;$HOME/.deepinwine/Deepin-QQ&quot; deepin-wine5 winecfg
# 默认使用文泉驿微米黑(wqy-microhei)字体，可以使用其他字体替代，直接将字体文件或字体链接文件放置到字体文件夹就会生效，不会影响系统字体
$ cd ~/.deepinwine/Deepin-QQ/drive_c/windows/Fonts

# 新版TIM
$ yay -S com.qq.tim.spark
# 微信
$ yay -S com.qq.weixin.deepin
# 注意：如果是 N 卡用户，可能需要用安装 lib32-nvidia-libgl 才能使用
# 中文方块乱码：WINE_CMD=&quot;LC_ALL=zh_CN.UTF-8 deepin-wine5&quot;
# KDE/Plasma桌面 需要安装 xsettingsd，然后设置到 /usr/bin/xsettingsd 自启动
$ ln -s /usr/bin/xsettingsd ~/.config/plasma-workspace/env/xsettingsd

# KDE字体设置 DPI 120
$ env WINEPREFIX=$HOME/.deepinwine/Deepin-WeChat deepin-wine5 winecfg

# 添加字体到Fonts目录
$ cp MicrosoftYaheiConfig.ttf ~/.deepinwine/Deepin-WeChat/drive_c/windows/Fonts

# 修改系统注册表且修改以下两行
$ vim ~/.deepinwine/Deepin-WeChat/system.reg
&quot;MS Shell Dlg&quot;=&quot;MicrosoftYahei&quot;
&quot;MS Shell Dlg 2&quot;=&quot;MicrosoftYahei&quot;

# 注册字体并添加一下代码
$ vim MicrosoftYaheiConfig.reg
REGEDIT4
[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\FontLink\SystemLink]
&quot;Lucida Sans Unicode&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;Microsoft Sans Serif&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;MS Sans Serif&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;Tahoma&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;Tahoma Bold&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;MicrosoftYahei&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;Arial&quot;=&quot;MicrosoftYahei.ttc&quot;
&quot;Arial Black&quot;=&quot;MicrosoftYahei.ttc&quot;

# 注册
$ WINEPREFIX=~/.deepinwine/Deepin-WeChat deepin-wine5 regedit MicrosoftYaheiConfig.reg
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;开发&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 谷歌浏览器
$ sudo pacman -S google-chrome
# 火狐浏览器并汉化
$ sudo pacman -S firefox firefox-i18n-zh-cn
# 在浏览器的地址栏输入
about:config
# 搜索
intl.locale.requested
# 将其值修改为
zh_CN
# 360安全浏览器
$ yay -S browser360
# Opera 自带梯子的浏览器
$ sudo pacman -Sy opera
# 博主感觉最好的Markdown编辑器
$ sudo pacman -S typora
# phpstorm
$ yay -S phpstorm
# GoLand
$ sudo pacman -S goland
# CLion
$ sudo pacman -S clion clion-cmake make clion-lldb
# idea
$ sudo pacman -S intellij-idea-ultimate-edition
# Visual Studio Code
$ sudo pacman -S visual-studio-code-bin
# Postman
$ sudo pacman -S postman-bin
# Mycli 具有自动完成和语法突出显示功能的MySQL / MariaDB / Percona客户端
$ sudo pacman -S mycli
# 具有自动完成功能和语法突出显示功能的Redis客户端
$ yay -S iredis
# 开源图形化的Redis客户端管理软件
$ sudo snap install redis-desktop-manager
# Java JDK
$ sudo pacman -S jdk8-openjdk java-14-openjdk
$ archlinux-java status
$ sudo archlinux-java set java-14-openjdk
# Navicat Premium 150.0.10
# 链接: https://pan.baidu.com/s/1ihWcDY2Vs9igWuDfKh5giA  密码: nnft
$ chmod +x navicat15-premium-cs.AppImage
$ ./navicat15-premium-cs.AppImage
# 后来发现的，对不起Navicat我投入了DataGrip的怀抱
$ yay -S datagrip

# Jekyll
$ sudo pacman -S ruby
# 缺包了就装 bundle add
$ sudo vim /etc/profile
# 把ruby写入到系统环境变量
export PATH=&quot;$PATH:/home/achuan/.gem/ruby/3.0.0/bin/&quot;
$ source /etc/profile
$ sudo gem update
$ sudo gem install jekyll bundle bundler
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;办公&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;#　Thunderbird (邮件收发和RSS订阅，KDE预装)
$ sudo pacman -S thunderbird thunderbird-i18n-zh-cn
# XMind思维导图 (需要JAVA8+)
$ yay -S xmind
# KDE下最好用的PDF阅读器
$ sudo pacman -S okular
# WPS\字体\中文语言包
$ sudo pacman -S wps-office ttf-wps-fonts wps-office-mui-zh-cn
# 如果WPS不能输入中文
$ sudo vim /usr/bin/wps
# 写入以下配置
export GTK_IM_MODULE=ibus
export XMODIFIERS=@im=ibus
export QT_IM_MODULE=ibus
ibus-daemon -d -x
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;娱乐&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# Spotify
$ sudo pacman -S spotify
# 网易云音乐
$ sudo pacman -S netease-cloud-music
# Telegram
$ sudo pacman -S telegram-desktop
# Asciinema 在云端记录并分享你的终端会话
$ sudo pacman -S asciinema
# 开源的游戏平台（可以打美服LOL）
$ sudo pacman -S lutris
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;工具&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 查看内核版本
$ uname -r
# 安装时对应注意Linux内核版本
$ sudo pacman -S virtualbox virtualbox-guest-dkms
# vboxusers扩展包
$ yay -S virtualbox-ext-oracle virtualbox-guest-iso
# 添加当前用户到virtualbox用户组
$ sudo gpasswd -a $USER vboxusers
# 激活内核模块
$ sudo modprobe vboxdrv
# 坚果云
$ sudo pacman -S nutstore
# 百度网盘
$ yay -S baidunetdisk
# 新一代网络工具包
$ sudo pacman -S iproute2
# Snap Store
$ sudo snap install snap-store
# 程序启动器
$ sudo pacman -S albert
# 桌面面板
$ sudo pacman -S latte-dock
# 迅雷
$ yay -S deepin-wine-thunderspeed
# Teamviewer
$ sudo pacman -S teamviewer
# 如果无法打开或不能联网执行
$ sudo teamviewer --daemon enable
# 支持快捷键下拉的终端模拟器 (KDE预装默认F12唤醒)
$ sudo pacman -S yakuake
# 深度取色器
$ sudo pacman -S deepin-picker
# 深度录屏
$ sudo pacman -S deepin-screen-recorder
# 截图工具
$ sudo pacman -S flameshot-git
# Motrix (支持下载 HTTP、FTP、BT、磁力链、百度网盘等资源)
$ sudo pacman -S motrix
$ git clone git@github.com:sbwtw/deepin-repair-tools.git
# 全平台多线程下载管理器，恢复断/死下载、安排和转换下载、内置视频转换器、支持各大流行浏览器插件
$ yay -S xdman
# 腾讯播放器
$ yay -S debtap
# 升级 debtap
$ sudo debtap -u
$ wget https://dldir1.qq.com/qqtv/linux/Tenvideo_universal_1.0.10_amd64.deb
# 将deb包转换成pkg包
$ sudo debtap Tenvideo_universal_1.0.10_amd64.deb
# 安装pkg包
$ sudo pacman -U sogoupinyin-2.3.1.0112-1-x86_64.pkg.tar.xz

# xDroid 安卓模拟器
https://www.linzhuotech.com/index.php/home/index/xdroid.html
$ tar xvf xDroidInstall-x86_64-v3.0007.tar.gz
$ cd xDroidInstall-x86_64/
$ sh install.sh

# SwitchHosts（hosts管理）
https://github.com/oldj/SwitchHosts/releases
$ chmod +x SwitchHosts._linux_x86_64_3.5.4.5517.AppImage
$ ./SwitchHosts._linux_x86_64_3.5.4.5517.AppImage
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;开发环境&lt;/h2&gt;
&lt;h3&gt;Apache&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S apache
# 设置Apache开机启动服务
$ sudo systemctl enable httpd
# 启动apache服务
$ sudo systemctl start httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置参数&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ cd /etc/httpd/conf
# 备份源文件
$ sudo cp httpd.conf httpd.conf.backup
$ sudo vim httpd.conf 
# 开启重写
LoadModule rewrite_module modules/mod_rewrite.so

&amp;lt;/IfModule&amp;gt;
    ServerAdmin achuan@achuan.io
    ServerName io:80
&amp;lt;Directory /&amp;gt;
DocumentRoot &quot;/home/achuan/www&quot;
&amp;lt;Directory /&amp;gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
&amp;lt;/Directory&amp;gt;
&amp;lt;Directory &quot;/home/achuan/www&quot;&amp;gt;
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted
&amp;lt;/Directory&amp;gt;

$ sudo systemctl restart httpd
# 报错
[Sat Apr 25 00:36:21.725913 2020] [core:error] [pid 106186:tid 140238307444480] (13)Permission denied: [client 127.0.0.1:53420] AH00035: access to / denied (filesystem path &apos;/home/achuan/www&apos;) because search permissions are missing on a component of the path

# 很常见的权限问题
$ sudo chmod +x /home/achuan

&amp;lt;IfModule dir_module&amp;gt;
    DirectoryIndex index.php index.html
&amp;lt;/IfModule&amp;gt;

$ sudo systemctl restart httpd
# 让apache支持php
Include conf/extra/php7_module.conf
LoadModule php7_module modules/libphp7.so
Include conf/extra/httpd-vhosts.conf

$ sudo systemctl restart httpd
# 重启后直接无法启动了，查看httpd状态看看
$ sudo systemctl startus httpd
[pid 113670:tid 140226396240832] Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe.  You need to recompile PHP.

# Arch Wiki上说Apache 2.4.7不支持非线程安全版PHP。php-apache中包含的libphp7.so不支持mod_mpm_event，仅支持mod_mpm_prefork。需要在/etc/httpd/conf/httpd.conf中注释掉。
$ sudo vim httpd.conf
# 取消以下行的注释：
# LoadModule mpm_event_module modules/mod_mpm_event.so
# 取消以下行的注释：
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
$ sudo systemctl restart httpd

# 配置hosts
$ sudo vim /etc/hosts
# Virtual hosts
127.0.0.1  io
127.0.0.1  phpmyadmin.io
127.0.0.1  acphp.io
127.0.0.1  tp.io

# 配置虚拟主机
$ sudo vim extra/httpd-vhosts.conf
# Virtual Hosts
&amp;lt;VirtualHost _default_:80&amp;gt;
    DocumentRoot &quot;/home/achuan/www/&quot;
    ServerName io
&amp;lt;/VirtualHost&amp;gt;

# phpMyAdmin.io
&amp;lt;VirtualHost *:80&amp;gt;
    ServerName phpmyadmin.io
    DocumentRoot /home/achuan/Carry/phpMyAdmin/
    &amp;lt;Directory  &quot;/home/achuan/Carry/phpMyAdmin/&quot;&amp;gt;
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;

# tp.io
&amp;lt;VirtualHost *:80&amp;gt;
    ServerName tp.io
    DocumentRoot /home/achuan/language/php/tp/public
    &amp;lt;Directory  &quot;/home/achuan/language/php/tp/&quot;&amp;gt;
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    &amp;lt;/Directory&amp;gt;
&amp;lt;/VirtualHost&amp;gt;

$ sudo systemctl restart httpd
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;PHP&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S php php-apache
$ php -v
PHP 7.4.5 (cli) (built: Apr 15 2020 17:14:40) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;安装Redis并编译扩展&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S redis
# 设置Redis开机启动服务
$ sudo systemctl enable redis
$ sudo systemctl start redis

# 编译Redis扩展
$ git clone https://github.com/phpredis/phpredis.git
$ cd phpredis
# 下载下来后默认这develop分支，需要手动切换到主分支
$ git checkout master
$ /usr/bin/phpize
$ sudo ./configure --with-php-config=/usr/bin/php-config
$ sudo make &amp;amp;&amp;amp; sudo make install
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置参数&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ cd /etc/php
# 备份源文件
$ sudo cp php.ini php.ini.backup
$ sudo vim php.ini

error_reporting = E_ALL
display_errors = On
short_open_tag = On
display_startup_errors = On
memory_limit = 128M
post_max_size = 32M
date.timezone = Asia/Shanghai

extension=curl
extension=ftp
extension=imap
extension=mysqli
extension=pdo_mysql
extension=sockets
extension=zip
extension=redis
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Composer&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ curl -sS https://getcomposer.org/installer | php
# 全局调用
$ sudo mv composer.phar /usr/local/bin/composer
# 使用阿里云镜像
$ composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;MySQL&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S mysql
# 初始化
$ sudo mysqld --initialize --user=mysql --basedir=/usr --datadir=/var/lib/mysql
# 我遇到了问题，初始化没有提供密码，不管它直接改。
$ sudo vim /etc/mysql/my.cnf
在[mysqld]中写入
skip-grant-tables
$ sudo systemctl restart mysqld
$ mysql -uroot -p
# 设置MySQL开机启动服务
$ sudo systemctl enable mysqld
# 改密码
# 在这我遇到个问题，如果不先刷新权限，SQL语句就会报错
ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

mysql&amp;gt; FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql&amp;gt; ALTER user &apos;root&apos;@&apos;localhost&apos; IDENTIFIED BY &apos;achuan.io&apos;;
Query OK, 0 rows affected (0.02 sec)

mysql&amp;gt; FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

&amp;gt; QUIT
Bye
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;GoLand&lt;/h3&gt;
&lt;h4&gt;安装&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo pacman -S go
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 配置环境变量
$ sudo vim /etc/profile
export GOPATH=$HOME/Important/go
$ source /etc/profile
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Qv2ray 科学上网&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kucun.banwagong.org&quot;&gt;搬瓦工方案库存监控页面&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;我的VPS配置：CN2  1核  1GB  20GB  1TB  1Gbps  洛杉矶  $49.99&lt;/li&gt;
&lt;li&gt;要求：Ubuntu 16+ / Debian 8+ / CentOS 7+ 系统&lt;/li&gt;
&lt;li&gt;推荐使用 Debian 9 系统，脚本会自动启用 BBR 优化&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;v2ray安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ yum install curl -y
$ bash &amp;lt;(curl -s -L https://git.io/v2ray.sh)
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;快速管理&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 查看 V2Ray 配置信息
$ v2ray info
# 修改 V2Ray 配置
$ v2ray config
# 生成 V2Ray 配置文件链接
$ v2ray link
# 生成 V2Ray 配置信息链接
$ v2ray infolink
# 生成 V2Ray 配置二维码链接
$ v2ray qr
# 修改 Shadowsocks 配置
$ v2ray ss
# 查看 Shadowsocks 配置信息
$ v2ray ssinfo
# 生成 Shadowsocks 配置二维码链接
$ v2ray ssqr
# 查看 V2Ray 运行状态
$ v2ray status
# 启动 V2Ray
$ v2ray start
# 停止 V2Ray
$ v2ray stop
# 重启 V2Ray
$ v2ray restart 
# 查看 V2Ray 运行日志
$ v2ray log
# 更新 V2Ray
$ v2ray update
# 更新 V2Ray 管理脚本
$ v2ray update.sh
# 卸载 V2Ray
$ v2ray uninstall
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;配置文件路径&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# V2Ray 配置文件路径
/etc/v2ray/config.json
# Caddy 配置文件路径
/etc/caddy/Caddyfile
# 脚本配置文件路径
/etc/v2ray/233blog_v2ray_backup.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;v2ray客户端&lt;/h3&gt;
&lt;h4&gt;推荐俩v2ray客户端&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/Qv2ray/Qv2ray&quot;&gt;Qv2ray&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;三大平台GUI客户端，使用C++17/Qt5、支持订阅、扫描二维码、自定义路由编辑&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jiangxufeng/v2rayL&quot;&gt;v2rayL&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;linux GUI客户端，支持订阅、vemss、ss等协议，自动更新订阅、透明代理&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# AppImage版本
$ wget https://github.com/Qv2ray/Qv2ray/releases/download/v2.5.0/Qv2ray.v2.5.0.linux-x64.AppImage

# 因为政策原因Qv2ray并不自带v2ray核心
$ sudo pacman -S qv2ray v2ray

# 代理扩展
SwitchyOmega
# SwitchyOmega配置
https://raw.githubusercontent.com/wiki/FelisCatus/SwitchyOmega/GFWList.bak

# GoFW
# 境外网站加速器，Github一个项目，利用BootCDN加载境外网站某些静态资源
https://github.com/xmcp/GoFW
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Pacman&lt;/h2&gt;
&lt;h3&gt;更新&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 全面更新
$ pacman -Syyu
# 更新所有包
$ pacman -Syu
# 更新包数据源
$ pacman -Sy
# 更新已安装的包
$ pacman -Su
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;搜索安装&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 安装
$ pacman -S
# 搜索含关键字的包
$ pacman -Ss
# 同步包后再执行安装
$ pacman -Sy
# 安装本地包 (扩展名：pkg.tar.gz)
$ pacman -U
# 搜索已安装的包
$ pacman -Qs
# 升级全部包
$ pacman -Syu
# 只下载，不安装
$ pacman -Sw
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;显示删除&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 删除包，不会删除其依赖
$ pacman -R
# 删除包，及其所有没有被其它包使用的依赖
$ pacman -Rs
# 删除一个包，包括所有依赖
$ pacman -Rsc
# 清理未安装的包 (包文件目录：/var/cache/pacman/pkg/)
$ pacman -Sc
# 清理所有缓存文件
$ pacman -Scc
# 显示包信息
$ pacman -Si
# 查询本地包的详情信息
$ pacman -Qi
# 列出所有不再作为依赖的包
$ pacman -Qdt
# 列出所有明确安装而且不被其他包依赖的包
$ pacman -Qet
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Snap&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看版本信息
$ snap --version
# 找出所有snap应用
$ snap find
# 安装应用
$ snap install
# 重启应用
$ snap restart
# 升级应用
$ snap refresh
# 查看安装的应用
$ snap list
# 卸载应用
$ snap remove
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;you-get&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Github：https://github.com/soimort/you-get&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;命令行程序，提供便利的方式来下载网络上的媒体信息&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 下载视频
$ you-get -i
# 使用 --http-proxy/-x为you-get设置HTTP代理:
$ you-get -x 127.0.0.1:8888
# 加载okie，目前支持两种cookie格式：Mozilla cookies.sqlite 和 Netscape cookies.txt.
$ you-get -c
# 获得页面所有可下载URL列表，支持JSON格式
$ you-get -u
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;annie&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Github：https://github.com/iawia002/annie&lt;/li&gt;
&lt;li&gt;这是个国产的命令行下载器，用GO构建，目前支持的网站有&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;# 下载，如果URL包含特殊字符，需要用引号引起来
$ annie [URL]
# 显示视频质量等信息
$ annie -i https://www.bilibili.com/video/BV1FV411d7u7
 Site:      哔哩哔哩 bilibili.com
 Title:     bilibili献给新一代的演讲《后浪》 P1 bilibili献给新一代的演讲《后浪》
 Type:      video
 Streams:   # All available quality
     [80]  -------------------
     Quality:         高清 1080P
     Size:            65.55 MiB (68738121 Bytes)
     # download with: annie -f 80 ...
# 下载1080P列表所有视频，若只下载第一个去掉 -p
$ annie -f 80 -p https://www.bilibili.com/video/BV1FV411d7u7
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;最后再来一张图啊哈哈哈～&lt;/p&gt;
&lt;p&gt;![我的桌面]({{ site.ARTICLEPICTURES_PATH }}/My desktop.png &quot;我的桌面&quot;)&lt;/p&gt;
&lt;h2&gt;后续报错&lt;/h2&gt;
&lt;h3&gt;JetBrains DataGrip的JavaFx报错&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;tried to use preview panel provider (javafx webview), but it is unavailable. reverting to default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;打开Markdown文件就会报错，为在Medium上找到的一个解决方案，重装一下PHPSTORM JRE&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ yay -S phpstorm-jre
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Increasing the amount of inotify watchers&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;/home/achuan/.gem/ruby/2.7.0/gems/rb-inotify-0.10.1/lib/rb-inotify/watcher.rb:74:in `initialize&apos;: No space left on device - Failed to watch &quot;/home/achuan/github/achuanya.github.io/.jekyll-cache/Jekyll/Cache/Jekyll--Converters--Markdown/e6&quot;: The user limit on the total number of inotify watches was reached or the kernel failed to allocate a needed resource. (Errno::ENOSPC)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用&lt;code&gt;$ jekyll server&lt;/code&gt;提示被限额了，增加限额永久化：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
$ sudo sysctl -p
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Manjaro%20KDE%20%E8%B0%83%E6%95%99%E6%97%A5%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-04-09-manjaro-kde&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)谈 Linux，Windows 和 Mac</title><link>https://blog.lhasa.icu/posts/technology/2020-04-07-blog-fully-linux-working</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2020-04-07-blog-fully-linux-working</guid><pubDate>Tue, 07 Apr 2020 10:10:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://www.yinwang.org/blog-cn/2013/03/07/linux-windows-mac&quot;&gt;当然我在扯淡&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这段时间受到很多人的来信。他们看了我很早以前写的推崇 Linux 的文章，想知道如何“抛弃 Windows，学习 Linux”。天知道他们在哪里找到那么老的文章，真是好事不出门…… 我觉得我有责任消除我以前的文章对人的误导，洗清我这个“Linux 狂热分子”的恶名。我觉得我已经写过一些澄清的文章了，可是怎么还是有人来信问 Linux 的问题。也许因为感觉到“舆论压力”，我把文章都删了。&lt;/p&gt;
&lt;p&gt;简言之，我想对那些觉得 Linux 永远也学不会的“菜鸟”们说：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Linux 和 Unix 里面包含了一些非常糟糕的设计。不要被 Unix 的教条主义者吓倒。学不会有些东西很多时候不是你的错，而是 Linux 的错，是“Unix 思想” 的错。不要浪费时间去学习太多工具的用法，钻研稀奇古怪的命令行。那些貌似难的，复杂的东西，特别要小心分析。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Windows 避免了 Unix，Linux 和 Mac OS X 的很多问题。微软是值得尊敬的公司，是真正在乎程序开发工具的公司。我收回曾经对微软的鄙视态度。请菜鸟们吸收 Windows 设计里面好的东西。另外 Visual Studio 是非常好的工具，会带来编程效率的大幅度提升。请不要歧视 IDE。要正视 Emacs，VIM 等文本编辑器的局限性。当然，这些正面评价不等于说你应该为微软工作。就像我喜欢 iPhone，但是却不一定想给 Apple 工作一样。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;学习操作系统最好的办法是学会（真正的）程序设计思想，而不是去“学习”各种古怪的工具。所有操作系统，数据库，Internet，以至于 WEB 的设计思想（和缺陷），几乎都能用程序语言的思想简单的解释。&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;先说说我现在对 Linux 和相关工具（比如 TeX）的看法吧。我每天上班都用 Linux，可是回家才不想用它呢。上班的时候，我基本上只是尽我所能的改善它，让它不要给我惹麻烦。Unix 有许许多多的设计错误，却被当成了教条，传给了一代又一代的程序员，恶性循环。Unix 的 shell，命令，配置方式，图形界面，都是相当糟糕的。每一个新版本的 Ubuntu 都会在图形界面的设计上出现新的错误，让你感觉历史怎么会倒退。其实这只是表面现象。Linux 所用的图形界面（X Window）在本质上几乎是没救的。我不想在这里细说 Unix 的缺点，在它出现的早期，已经有人写了一本书，名叫 Unix Hater’s Handbook，里面专门有一章叫做 The X-Windows Disaster。它分析后指出，X Window 貌似高明的 client-server 设计，其实并不像说的那么好。&lt;/p&gt;
&lt;p&gt;这本书汇集了 Unix 出现的年代，很多人对它的咒骂。有趣的是，这本书有一个“反序言”，是 Unix 的创造者之一 Dennis Ritchie 写的。我曾经以为这些骂 Unix 的人都是一些菜鸟。他们肯定是智商太低，或者被 Windows 洗脑了，不能理解 Unix 的高明设计才在那里骂街。现在理解了程序语言的设计原理之后，才发现他们说的那些话里面居然大部分是实话！其实他们里面有些人在当年就是世界顶尖的编程高手，自己写过操作系统和编译器，功底不亚于 Unix 的创造者。在当年他们就已经使用过设计更加合理的系统，比如 Multics，Lisp Machine 等。&lt;/p&gt;
&lt;p&gt;可惜的是，在现在的操作系统书籍里面，Multics 往往只是被用来衬托 Unix 的“简单”和伟大。Unix 的书籍喜欢在第一章讲述这样的历史：“Multics 由于设计过于复杂，试图包罗万象，而且价格昂贵，最后失败了。” 可是 Multics 失败了吗？Multics，Oberon，IBM System/38， Lisp Machine，…… 在几十年前就拥有了 Linux 现在都还没有的好东西。Unix 里面的东西，什么虚拟内存，文件系统，…… 基本上都是从 Multics 学来的。Multics 的机器，一直到 2000 年都还在运行。Unix 不但“窜改”了历史教科书，而且似乎永远不吸取教训，到现在还没有实现那些早期系统早就有的好东西。Unix 的设计几乎完全没有一致性和原则。各种工具程序功能重复，冗余，没法有效地交换数据。可是最后 Unix 靠着自己的“廉价”，“宗教”和“哲学”，战胜了别的系统在设计上的先进，统治了程序员的世界。&lt;/p&gt;
&lt;p&gt;如果你想知道这些“失败的”操作系统里面有哪些我们现在都还没有的先进技术，可以参考这篇文章：Oberon - The Overlooked Jewel。它介绍的是 Niklaus Wirth（也就是 Pascal 语言的设计者）的 Oberon 操作系统。&lt;/p&gt;
&lt;p&gt;胜者为王，可是 Unix 其实是一个暴君，它不允许你批评它的错误。它利用其它程序员的舆论压力，让每一个系统设计上的错误，都被说成是用户自己的失误。你不敢说一个工具设计有毛病，因为如果别人听到了，就会以为你自己不够聪明，说你“人笨怪刀钝”。这就像是“皇帝的新装”里的人们，明明知道皇帝没穿衣服，还要说“这衣服这漂亮”！总而言之，“对用户友好”这个概念，在 Unix 的世界里是被歧视，被曲解的。Unix 的狂热分子很多都带有一种变态的“精英主义”。他们以用难用的工具为豪，鄙视那些使用“对用户友好”的工具的人。&lt;/p&gt;
&lt;p&gt;我曾经强烈的推崇 FVWM，TeX 等工具，可是现在擦亮眼睛看来，它们给用户的界面，其实也是非常糟糕的设计，跟 Unix 一脉相承。他们把程序设计的许多没必要的细节和自己的设计失误，无情的暴露给用户。让用户感觉有那么多东西要记，仿佛永远也没法掌握它。实话说吧，当年我把 TeXbook 看了两遍，做完了所有的习题（包括最难的“double bend”习题）。几个月之后，几乎全部忘记干净。为什么呢？因为 TeX 的语言是非常糟糕的设计，它没有遵循程序语言设计的基本原则。&lt;/p&gt;
&lt;p&gt;这里有一个鲜为人知的小故事。TeX 之所以有一个“扩展语言”，是 Scheme 的发明者 Guy Steele 的建议。那年夏天，Steele 在 Stanford 实习。他听说 Knuth 在设计一个排版系统，就强烈建议他使用一种扩展语言。后来 Knuth 采纳了他的建议。不幸的是 Steele 几个月后就离开了，没能帮助 Knuth 完成语言的设计。Knuth 老爹显然有我所说的那种“精英主义”，他咋总是设计一些难用的东西，写一些难懂的书？&lt;/p&gt;
&lt;p&gt;一个好的工具，应该只有少数几条需要记忆的规则，就像象棋一样。而这些源于 Unix 的工具却像是“魔鬼棋”或者“三国杀”，有太多的，无聊的，人造的规则。有些人鄙视图形界面，鄙视 IDE，鄙视含有垃圾回收的语言（比如 Java），鄙视一切“容易”的东西。他们却不知道，把自己沉浸在别人设计的繁复的规则中，是始终无法成为大师的。就像一个人，他有能力学会各种“魔鬼棋”的规则，却始终无法达到象棋大师的高度。所以，容易的东西不一定是坏的，而困难的东西也不一定是好的。学习计算机（或者任何其它工具），应该“只选对的，不选难的”。记忆一堆的命令，乌七八糟的工具用法，最后脑子里什么也不会留下。学习“原理性”的东西，才是永远不会过时的。&lt;/p&gt;
&lt;p&gt;Windows 技术设计上的很多细节，也许在早期是同样糟糕的。但是它却向着更加结构化，更加简单的方向发展。Windows 的技术从 OLE，COM，发展到 .NET，再加上 Visual Studio 这样高效的编程工具，这些带来了程序员和用户效率的大幅度提高，避免了 Unix 和 C 语言的很多不必存在的问题。Windows 程序从很早的时候就能比较方便的交换数据。比如，OLE 让你可以把 Excel 表格嵌入到 Word 文档里面。不得不指出，这些是非常好的想法，是超越“Unix 哲学”的。相反，由于受到“Unix 哲学”的误导，Unix 的程序间交换数据一直以来都是用字符串，而且格式得不到统一，以至于很多程序连拷贝粘贴都没法正确进行。Windows 的“配置”，全都记录在一个中央数据库（注册表）里面，这样程序的配置得到大大的简化。虽然在 Win95 的年代，注册表貌似老是惹麻烦，但现在基本上没有什么问题了。相反，Unix 的配置，全都记录在各种稀奇古怪的配置文件里面，分布在系统的各个地方。你搞不清楚哪个配置文件记录了你想要的信息。每个配置文件连语法都不一样！这就是为什么用 Unix 的公司总是需要一个“系统管理员”，因为软件工程师们才懒得记这些麻烦的东西。&lt;/p&gt;
&lt;p&gt;再来比较一下 Windows 和 Mac 吧。我认识一个 Adobe 的高级设计师。他告诉我说，当年他们把 Photoshop 移植到 Intel 构架的 Mac，花了两年时间。只不过换了个处理器，移植个应用程序就花了两年时间，为什么呢？因为 Xcode 比起 Visual Studio 真是差太多了。而 Mac OS X 的一些设计原因，让他们的移植很痛苦。不过他很自豪的说，当年很多人等了两年也没有买 Intel 构架的 Mac，就是因为他们在等待 Photoshop。最后他直言不讳的说，微软其实才是真正在乎程序员工具的公司。相比之下，Apple 虽然对用户显得友好，但是对程序员的界面却差很多。Apple 尚且如此，Linux 对程序员就更差了。可是有啥办法呢，有些人就是受虐狂。自己痛过之后，还想让别人也痛苦。就像当年的我。&lt;/p&gt;
&lt;p&gt;我当然不是人云亦云。微软在程序语言上的造诣和投入，我看得很清楚。我只是通过别人的经历，来验证我已经早已存在的看法。所以一再宣扬别的系统都是向自己学习的 Apple 受到这样的评价，我也一点不惊讶。Mac OS X 毕竟是从 Unix 改造而来的，还没有到脱胎换骨的地步。我有一个 Macbook Air，一个 iPhone 5，和一个退役的，装着 Windows 7 的 T60。我不得不承认，虽然我很喜欢 Macbook 和 iPhone 的硬件，但我发现 Windows 在软件上的很多设计其实更加合理。&lt;/p&gt;
&lt;p&gt;我为什么当年会鄙视微软？这很简单。我就是跟着一群人瞎起哄而已！他们说 Linux 能拯救我们，给我们自由。他们说微软是邪恶的公司…… 到现在我身边还有人无缘无故的鄙视微软，却不知道理由。可是 Unix 是谁制造的呢？是 AT&amp;amp;T。微软和 AT&amp;amp;T 哪个更邪恶呢？我不知道。但是你应该了解一下 Unix 的历史。AT&amp;amp;T 当年发现 Unix 有利可图，找多少人打了多少年官司？说微软搞垄断，其实 AT&amp;amp;T 早就搞过垄断了，还被拆散成了好几个公司。想想世界上还有哪一家公司，独立自主的设计出这从底至上全套家什：程序语言，编译器，IDE，操作系统，数据库，办公软件，游戏机，手机…… 我不得不承认，微软是值得尊敬的公司。&lt;/p&gt;
&lt;p&gt;公司还不都一样，都是以利益为本的。我们程序员就不要被他们利用，作为利益斗争的炮灰啦。见到什么好就用什么，就学什么。自己学到的东西，又不属于那些垄断企业。我们都有自由的头脑。&lt;/p&gt;
&lt;p&gt;当然我不是在这里打击 Linux 和 Mac 而鼓吹 Windows。这些系统的纷争基本上已经不关我什么事。我只是想告诉新人们，去除头脑里的宗教，偏激，仇恨和鄙视。每次仇恨一个东西，你就失去了向它学习的机会。&lt;/p&gt;
&lt;p&gt;后记：“对用户友好”是一个值得研究，却又研究得非常不够的东西。很多 UI 的设计者，把东西设计的很漂亮，但是却不方便，不顺手。如果你想了解我认为怎样的设计才是“对用户友好的”，可以参考这篇博客&lt;a href=&quot;https://www.yinwang.org/blog-cn/2012/05/18/user-friendliness&quot;&gt;《什么是“对用户友好”》&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E8%B0%88%20Linux%EF%BC%8CWindows%20%E5%92%8C%20Mac&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2020-04-07-blog-fully-linux-working&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)为什么犹太人如此优秀？</title><link>https://blog.lhasa.icu/posts/life/2020-03-18-the-jews</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2020-03-18-the-jews</guid><pubDate>Wed, 18 Mar 2020 11:44:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://www.zhihu.com/question/20802135&quot;&gt;有个老外叫马绍飞&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;虽然我几乎在每一个回复下都说“本人是土生土长的纽约人”，但我同时也是德系（Ashkenazi）犹太人。&lt;strong&gt;我选择回答这个问题并不是为了吹嘘或贬低自己的民族，而是想尽可能地消除很多人对德系犹太人的误解。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;首先，我们一定要弄清楚的是，那些所谓的“优秀”犹太人到底是谁呢？犹太人分布在全球各地，总人口数最多一千五百万，还不到全世界人口比例的0.2%。不过，犹太人分成了很多不同的民族和宗教派别。爱因斯坦、弗洛伊德、马克思、罗斯柴尔德，还有一些诺贝尔奖得主等著名的犹太人大多属于“世俗德系犹太人”这个群体，“世俗”意味着没有什么明确的宗教信仰。据我观察，亚洲人经常给这一部分犹太人贴上“努力”、”聪明”、“有钱”、“优秀”等标签，而欧美洋人们通常认为我们“小气”、“贪婪”、“狡猾”、“虚伪”等等。&lt;/p&gt;
&lt;p&gt;其次，我也希望大家不要盲目地吹捧犹太人，因为并不是所有的德系犹太人都很了不起。我们像其他民族一样有自己优缺点。不过确实有很多人对我们很感兴趣，我非常感谢这些人对我们民族的尊重。&lt;/p&gt;
&lt;p&gt;在东亚人民眼中，德系犹太人好像是一群特别能吃苦耐劳、又极具商业头脑的土豪。但在我和我身边人的眼中，我们德系犹太人不过是个有点古怪、无法融入周围社会的游牧民族。说实话，作为犹太人，我心里其实一直都有点自卑感，因为我自己的先辈们移民到美国的时候，真的是一穷二白。我长大之后，才逐渐意识到德系犹太人的成功率竟然是全球最高的。我估计这可能是因为我们的价值观跟大众不太一样吧。&lt;/p&gt;
&lt;p&gt;有哪里不一样呢？举个例子，&lt;strong&gt;大部分人努力学习是为了获得更好的挣钱机会，或者是给自己更多的职业选择。但犹太人恰恰相反，整体来说，德系犹太人努力挣钱是为了获得更多的学习时间。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;the-jews-are-studying.png&quot; alt=&quot;犹太人在学习&quot; /&gt;&lt;/p&gt;
&lt;p&gt;犹太人追求智慧并不是为了提高自己的经济地位，而更是为了让自己的生活变得更加丰富。上图中可能看出，虔诚（Orthodox）犹太人一天到晚都在读塔木德经，甚至到老年都不放弃学习。其实这个现象已经在以色列产生了严重的经济问题，因为很多虔诚犹太人去钻以色列的福利制度空子，然后拿政府的钱回家读书。&lt;/p&gt;
&lt;p&gt;世俗犹太人对智慧的这种忠贞不渝的态度和生活习惯，主要是传承于信仰犹太教的祖辈。但是十九世纪欧洲的“犹太启蒙运动”导致不少德系犹太人逐渐抛弃犹太教。放弃宗教学习后，世俗德系犹太人把自己的学习精力都转向了科学技术、金融、学术、哲学、艺术、音乐、外语等各种领域。&lt;/p&gt;
&lt;p&gt;但除了热爱学习之外，犹太人的高成功率还包括一些其他因素，比如：&lt;/p&gt;
&lt;p&gt;1、 欧洲中世纪期间，梵蒂冈的教皇宣称任何涉及发放贷款的工作都很不纯洁，所以禁止信仰基督教的人们从事银行工作。只有“肮脏龌龊”的犹太人才有权利发放贷款，这样银行企业自然而然地被犹太人垄断了。梵蒂冈教皇搬了石头砸了自己的脚，不过这个巨大的错误却有利于德系犹太人的长期经济回报。&lt;/p&gt;
&lt;p&gt;2、 犹太人的集体主义思想比较强。虽然犹太人对政治、宗教、巴以冲突等方面都持有完全不同的意见，但犹太人整体都互相帮助、互相热爱。我们确实喜欢吵架，但我们依然把其他的犹太人视为自己的亲人。&lt;/p&gt;
&lt;p&gt;3、 我们的价值观比大部分西方人稍微保守一点。比如我们大多数人不会花天酒地、吸毒约炮、吃喝嫖赌等等。德系犹太人也非常重视结婚生子、对家庭负责等生活习惯，这一点跟中国人的价值观比较相似。&lt;/p&gt;
&lt;p&gt;4、 德系犹太人的历史非常悲惨。近两千年的历史中，德系犹太人在欧洲各地不断被屠杀、驱逐、掠夺、强奸等等。为了能生存下来，犹太人必须努力奋斗，有时甚至是不择手段。基督教徒相信只要向上帝祈祷就能帮你的生活变得更好，但犹太人倒认为上帝对你的日常生活来说连个屁都不算。犹太人觉得只有通过自己的努力，才能改变自己的命运。&lt;/p&gt;
&lt;p&gt;还有人说德系犹太人的高成功率跟旧约本身有关系，我倒是觉得犹太教跟基督教或伊斯兰教本质上并没有太大的区别，这三个一神教其实都有良好的一面和残暴的一面，有理性的一面也有反智的一面。德系犹太人的生活方式确实受到犹太教的影响，但比起旧约的内容，他们的高成功率更多是由于历史原因以及德系犹太人的独特生活习惯。最直观的就是，传统德系犹太人和传统非洲犹太人都信仰旧约，但这两个民族的成功率截然不同....&lt;/p&gt;
&lt;p&gt;与其他民族和宗教派别的教学方式相比，德系犹太人的教学方式更重视“疑问”，而不怎么重视“回答”，因为很多问题并没有绝对正确的答案。从小长辈们就经常让我们问很多问题，跟同学们一起来进行辩论，从而不断地锻炼自己的独立思考能力。在这种环境下，小朋友们很快就会发现这个世界含有无限的奥秘以及无穷无尽的知识。对我们来说，追求智慧本身才是生命的意义。&lt;/p&gt;
&lt;p&gt;德系犹太人热爱学习的主要原因是为了追求智慧，而不是为了考高分、挣钱、竞争、炫耀、装逼等等。实际上，很多世俗德系犹太人倒是更趋向于谦虚低调、勤俭朴素的生活方式，而不怎么爱去购买豪宅豪车或者最新发布的苹果手机，因为这些东西对我们来说毫无意义。在纽约和加州确实有一部分笑贫不笑娼、纸醉金迷的犹太人富豪，但这一部分人毕竟还是少数，&lt;strong&gt;因为我们的文化很重视谦虚&lt;/strong&gt;。大部分德系犹太人把自己的钱都留在银行或者投入孩子的教育。犹太人也会用自己的钱来帮助周围的社区发展、创立非政府组织、建设新的图书馆等，或者把钱捐赠给艺术、教育、脱贫组织，以及慈善机构等等。根据犹太教的传统价值观，挣钱本身并没有什么不好，在这一方面我们的信仰跟基督教徒确实有区别。可是按照犹太教的规则，有钱人一定要用自己的钱来帮助穷人，所以贫穷犹太人从来不会被淘汰。虽然我们世俗犹太人并没有认真地信奉犹太教，但我们依然把这些传统的价值观都传承给了后代。我们对犹太教的态度是“取其精华，去其糟粕”，就像当代中国人对儒家思想以及中国传统社会道德的态度一样吧。&lt;/p&gt;
&lt;p&gt;我好像有点跑题了。除了上面提到的原因外，犹太人的高成功率还有另外一个原因，那就是德系犹太人根深蒂固的思维方式。这一点一言难尽，但我会尽量给大家解释一下：&lt;/p&gt;
&lt;p&gt;如果你把金钱、面子、社会地位等方面都排在智慧之前，你必然会活得很不开心，你的生活也没什么意义。此外，你在这种思想下也无法挣钱，因为缺乏智慧的人没有独立思考的能力。你的创造力不够全面、特殊技能不够发达、目光太短浅。相反的，如果你把智慧、教育、想象力、激情等方面都放在物质欲望的前面，你不仅可以填满你心里的空虚，也可以凭借丰富的知识和开阔的视野来得到更靠谱的工作机会，并给自己打造更美好的前途。&lt;/p&gt;
&lt;p&gt;举个例子，假设你对医学不怎么感兴趣，但你为了挣钱而选择去学医，你将来必定会成为一个没什么工作激情、心情沮丧的三流医生。但如果你是因为想了解人体构造、传染病的症状等去学医，通过自己的努力，你就可以成为一个心满意足、高薪酬的优秀医生。这样的人也有能力给全社会带来巨大的帮助。&lt;/p&gt;
&lt;p&gt;爱因斯坦的解释可能会更清楚一点吧：&lt;strong&gt;“对知识本身的追求，对正义近乎偏执的热爱，以及对个人独立的渴望，这些都是传统犹太人的特点。而我由衷感恩，我是其中的一员。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;albert-einstein.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E4%B8%BA%E4%BB%80%E4%B9%88%E7%8A%B9%E5%A4%AA%E4%BA%BA%E5%A6%82%E6%AD%A4%E4%BC%98%E7%A7%80%EF%BC%9F&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2020-03-18-the-jews&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>在 CentOS 下实现 MySQL 数据库定时自动备份</title><link>https://blog.lhasa.icu/posts/technology/2019-09-19-automatic-database-backup</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-09-19-automatic-database-backup</guid><pubDate>Thu, 19 Sep 2019 10:44:00 GMT</pubDate><content:encoded>&lt;p&gt;前几次系统数据老是出问题，前几天经理让我给写个数据库自动备份，Shell能力有限，周六日再改改...&lt;/p&gt;
&lt;h2&gt;编写 Shell&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看磁盘空间
$ df -h

    Filesystem      Size  Used Avail Use% Mounted on
    /dev/vda1        79G   36G   40G  48% /
    devtmpfs        3.9G     0  3.9G   0% /dev
    tmpfs           3.9G  1.1M  3.9G   1% /dev/shm
    tmpfs           3.9G  592K  3.9G   1% /run
    tmpfs           3.9G     0  3.9G   0% /sys/fs/cgroup
    tmpfs           783M     0  783M   0% /run/user/0

# 进入根目录，创建 DatabaseBackup 文件夹并进入
$ cd /
$ mkdir DatabaseBackup
$ cd DatabaseBackup

# 创建 gupiaocl188.sh 文件并编辑
$ vim gupiaocl188.sh

    #!/bin/bash
    mysqldump -u project gupiaocl188 | gzip &amp;gt; /DatabaseBackup/gupiaocl188__$(date +%Y-%m-%d__%H:%M:%S).sql.gz

    #生成格式
    www_gupiaocl188__2019-09-17__12:00:01.sql.gz

# 赋值可执行权限
$ sudo chmod u+x gupiaocl188.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;配置 MySQL&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 配置 MySQL [mysqldump]
$ my.ini

    [mysqldump]
    user     = project
    password = HiGirl0921

# 执行 Shell脚本测试
$ ./gupiaocl188.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装 Crontab&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;
# 安装 Crontab
$ yum install -y vixie-cron

# 设置 Crontab 开启启动
$ chkconfig –level 35 crond on

#　启动 Crontab 服务
$ service crond start

# 编辑计时器设置
$ crontab -e

    # 每俩小时自动备份 www_gupiaocl188_ 数据库
    */120 * * * * /DatabaseBackup/www_gupiaocl188_.sh

## Crontab 命令

# 启动服务
$ service crond start

# 关闭服务
$ service crond stop

# 重启服务
$ service crond restart

# 重载配置
$ service crond reload

# 查看状态
$ service crond status
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%9C%A8%20CentOS%20%E4%B8%8B%E5%AE%9E%E7%8E%B0%20MySQL%20%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%9A%E6%97%B6%E8%87%AA%E5%8A%A8%E5%A4%87%E4%BB%BD&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-09-19-automatic-database-backup&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>阿川的个人博客 创建一周年啦!</title><link>https://blog.lhasa.icu/posts/life/2019-08-31-blog-anniversary</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2019-08-31-blog-anniversary</guid><pubDate>Fri, 30 Aug 2019 21:18:00 GMT</pubDate><content:encoded>&lt;p&gt;岁月不居，时节如流。阿川的个人博客至今已经创建一周年了。还记得创建前看过别人的一些博客文章，说什么不推荐小白创建博客，说什么要支出各种域名服务器等费用，博客还挣不到钱，完全没必要创建博客。在我看来我觉这样的说真的误人子弟。在我创建博客这一年中我学会了太多东西，也在因为博客认识了一些志同道合的朋友。这些远比那些钱重要。当然把博客运营好且挣到钱，这也是非常有成就感的。&lt;/p&gt;
&lt;p&gt;创建博客这段时间，我也渐渐爱上了写作，它可以让我的知识更加牢固，也正好练习一下文笔，虽然我博客文章质量还不咋样...但是提交前我可究竟了好久，各种改。。。&lt;/p&gt;
&lt;p&gt;总之创建这个博客的初心就是记录，学习。希望自己能坚持下去，晚安。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%98%BF%E5%B7%9D%E7%9A%84%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2%20%E5%88%9B%E5%BB%BA%E4%B8%80%E5%91%A8%E5%B9%B4%E5%95%A6!&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2019-08-31-blog-anniversary&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>说说消失这二十多天发生的事情</title><link>https://blog.lhasa.icu/posts/life/2019-08-25-tech-what-happened</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2019-08-25-tech-what-happened</guid><pubDate>Sun, 25 Aug 2019 04:44:00 GMT</pubDate><content:encoded>&lt;p&gt;消失这二十多天，出了很多事情：离职，电脑坏了，找工作还有一大堆其他事情...可能这些东西看着也没啥。可是二十多天坏的电脑让我有点感觉人生低谷(；′⌒`)，先说第一件事情吧离职。&lt;/p&gt;
&lt;h2&gt;离职&lt;/h2&gt;
&lt;p&gt;在公司3个月左右就想离职了，其实我不是很讨厌前后端不分离，只是公司那项目也太乱了。Model不是Model。css+js+php+html一起写。我也想把样式分离出来，但是公司整体项目要统一。我特么服了，一大堆转义符很是烦人。&lt;/p&gt;
&lt;p&gt;还有就是工资的拖欠。我觉得公司有困难大家一起可以度，但是公司无公告无邮箱拖欠工资，问财务部根本不说话。我真是对公司这些混日子的很是反感。&lt;/p&gt;
&lt;h2&gt;电脑坏了&lt;/h2&gt;
&lt;p&gt;电脑坏了完全是我自己做的...我神舟是大问题没有，小问题不断。那天晚上写项目写完了，我像往常一样把笔记本放在床上折叠桌上并盖上了盖。
不知道是凌晨几点，我一脚把折叠桌踢下了床，大概笔记本离地板有半米。笔记本正朝下摔还挺响...当时意识比较模糊捡起来又睡着了。&lt;/p&gt;
&lt;p&gt;第二天起来也没在意，我擦擦电脑开机打开PHPSTORM，大概几分钟电脑开始出现报警声音一长一短不一会儿非正常关机了，不慌不慌反正也不是第一次了。直接拆开主板检查了一遍主板是不是哪摔松了，内存条没有问题，主板什么也是没有问题的。开机后打开Ps打开别的软件，不一会就报警了，报警声音和刚才一样。我直接把主板全拆了重新排线。就这样试了好多次。我有点慌了!!!∑(ﾟДﾟノ)ノ&lt;/p&gt;
&lt;p&gt;当时准备联系郑州神舟授权售后，然后想想授权售后估计没啥用（真几把没用），打开QQ联系买神舟电脑店长，找老船长问他解决问题。结果是说主板可能出问题了，他搞不了让我神舟苏州总部售后进行返厂，返厂且最低15天。谷歌搞一下返厂攻略。大家好像都是不太推荐。当时先放下返厂，找修电脑的。结果是我感觉他们只会清灰重装、组装电脑...我TM...问了十几家没有一家能修。&lt;/p&gt;
&lt;p&gt;找的很烦，只能返厂了，售后查我的保修期在8.31号后就过期了，当时还沾沾自喜赶上时候（现在想想真几把傻屌）。大概2天顺风寄过去了，因为11号周六不上班给拒收了，12号早上签收，下午给我打电话确认电脑。15号检查到问题并报价：“主板5000、键盘300”并监测到主板进水不保修。&lt;/p&gt;
&lt;p&gt;当时几把就火了，说劳资笔记本主板进水不保修？？？劳资键盘是排线断了，换根新的接口就十几块钱。你这什么意思，还想给我换个新键盘？？？主板坏了她说技术不修，直接换。是直接换！当时忍不住就想骂人，我说明写的清清楚楚的只修不换，我要换主板还要你们售后？？？主板牵扯到显卡，修不了就换Mac。几把当时就二种选择，修掏钱，不修寄回来。也就是说忙活一星期啥都没干成。&lt;/p&gt;
&lt;p&gt;给客服打电话让转接技术，客服说公司没这规定，有什么事情给她说。他妈的当时就想骂人，想要打电话告他们。我要客服工号，客服一个劲说要干什么干什么？？？我要告你们欺诈消费者？？？客服说一句：你去告吧！接着就挂了电话。我日尼玛这能忍？？？好好好不让你们修了，给我寄回来寄回来好不好。客服说包装一下给我寄回来，货到付款。&lt;/p&gt;
&lt;p&gt;我尼玛当初修的时候说我付一半，你们付一半。这时候给我说货到付款...客服：“公司有规定，没有修的一律货到付款！”。
心累...感觉自己太年轻了...我好难啊(；′⌒`)&lt;/p&gt;
&lt;p&gt;后来历经周转找到在郑州百脑汇找到一家硬件芯片维修，&lt;strong&gt;开元世纪电脑维修&lt;/strong&gt;大哥技术炒鸡帮！主板显卡接触不良，没多久就搞好了花了240&lt;/p&gt;
&lt;h2&gt;找工作&lt;/h2&gt;
&lt;p&gt;在郑州顶着太阳40°找工作真是是舒服...上午跑下午跑，一般一天面试俩，最多三家。我商城这块太弱，一直在找商城这块公司。有几个公司真是挺难受的，事之前联系好好的，到了公司给经理打电话，给我说招满了...明二十六号去试岗三天祝我好运吧。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%AF%B4%E8%AF%B4%E6%B6%88%E5%A4%B1%E8%BF%99%E4%BA%8C%E5%8D%81%E5%A4%9A%E5%A4%A9%E5%8F%91%E7%94%9F%E7%9A%84%E4%BA%8B%E6%83%85&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2019-08-25-tech-what-happened&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>ThinkPHP Save 方法引发的错误</title><link>https://blog.lhasa.icu/posts/technology/2019-07-31-tp-save</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-07-31-tp-save</guid><pubDate>Wed, 31 Jul 2019 00:21:00 GMT</pubDate><content:encoded>&lt;p&gt;事情是这样的，今下午在我在完善修改老人档案表单验证的时候遇到点问题。明明 Save 方法执行成功却报错？&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;if ( !empty( $ChildrenDate[ &apos;name&apos; ] ) OR !empty( $ChildrenDate[ &apos;idcard_no&apos; ] OR !empty( $ChildrenDate[ &apos;tel&apos; ] ) OR !empty( $ChildrenDate[ &apos;relation&apos; ] ) ) ) {
    if ( !empty( $ChildrenDate[ &apos;name&apos; ] ) ) {
        if ( $ChildrenDate[ &apos;sex&apos; ] AND $ChildrenDate[ &apos;idcard_no&apos; ] AND $ChildrenDate[ &apos;tel&apos; ] AND $ChildrenDate[ &apos;relation&apos; ] == TRUE ) {
            $AddChildren = D( &apos;OlderFamily&apos; ) -&amp;gt; where( array( &apos;id&apos; =&amp;gt; I( &apos;id&apos; ) ) ) -&amp;gt; save( $ChildrenDate );
            if ( $AddChildren == FALSE ) {
                print_r( D( &apos;OlderFamily&apos; ) -&amp;gt; getLastSql() );die;
                // $this -&amp;gt; error( &quot;数据操作失败，请与管理员联系！&quot; );
            }
        }
        else {
            $this -&amp;gt; error( &apos;请补充完整家属信息！&apos; );
        }
    }
    else {
        $this -&amp;gt; error( &apos;请输入家属姓名！&apos; );
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;就不能惯它！要么成功，要么就用&lt;code&gt;getLastSql()&lt;/code&gt;打它&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;UPDATE `glbt_older_family` SET `older_id` = 31649,`name` = &apos;阿川&apos;,`sex` = 2,`idcard_no` = &apos;412727200001160414&apos;,`tel` = &apos;18623947428&apos;,`relation` = &apos;家人&apos; WHERE( `id` = 4000 );
&amp;gt; Affected rows: 0
&amp;gt; 时间: 0.001s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行了一下UPDATE并返回 &lt;strong&gt;0&lt;/strong&gt;，也就是说语法并没有错只是没有修改数据。然后我又改变 sex 值为 1，然后返回了&lt;code&gt;Affected rows: 1&lt;/code&gt;修改成功了！&amp;lt;br&amp;gt;
这个UPDATE语句我输出输入几十遍，一点错都没有。我脑子笨，找了好长时间找不到，然后把这个逻辑重写了两遍。然而还是无用...一度感到难受...&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;好了事情的转折点来了！出于个人癖好，总是喜欢闲着没事敲键盘点鼠标，按着按着鼠标乱点到了save方法，跳到Model模型类源码...&amp;lt;br&amp;gt;
出于好奇，反正来都来了，也瞅瞅Save的源码（这里感谢PHPSTORM的强大）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Model.class.php
public function save ( $data = &apos;&apos;, $options = array() )
{
    if ( empty( $data ) ) {
        if ( !empty( $this -&amp;gt; data ) ) {
            $data = $this -&amp;gt; data;
        }
        else {
            $this -&amp;gt; error = L( &apos;_DATA_TYPE_INVALID_&apos; );
            return FALSE;
        }
    }
    $data = $this -&amp;gt; _facade( $data );
    
    $options = $this -&amp;gt; _parseOptions( $options );
    if ( !isset( $options[ &apos;where&apos; ] ) ) {
        if ( isset( $data[ $this -&amp;gt; getPk() ] ) ) {
            $pk                 = $this -&amp;gt; getPk();
            $where[ $pk ]       = $data[ $pk ];
            $options[ &apos;where&apos; ] = $where;
            unset( $data[ $pk ] );
        }
        else {
            $this -&amp;gt; error = L( &apos;_OPERATION_WRONG_&apos; );
            return FALSE;
        }
    }
    $result = $this -&amp;gt; db -&amp;gt; update( $data, $options );
    return $result;
}


// Db.calss.php
public function update ( $data, $options )
{
    $sql   = &apos;UPDATE &apos;
        . $this -&amp;gt; parseTable( $options[ &apos;table&apos; ] )
        . $this -&amp;gt; parseSet( $data )
        . $this -&amp;gt; parseWhere( isset( $options[ &apos;where&apos; ] ) ? $options[ &apos;where&apos; ] : &apos;&apos; )
        . $this -&amp;gt; parseOrder( isset( $options[ &apos;order&apos; ] ) ? $options[ &apos;order&apos; ] : &apos;&apos; )
        . $this -&amp;gt; parseLimit( isset( $options[ &apos;limit&apos; ] ) ? $options[ &apos;limit&apos; ] : &apos;&apos; )
        . $this -&amp;gt; parseLock( isset( $options[ &apos;lock&apos; ] ) ? $options[ &apos;lock&apos; ] : false );
    return $this -&amp;gt; execute( $sql );
}


// DbPdo.class.php
public function execute ( $str )
{
    $this -&amp;gt; initConnect( TRUE );
    if ( !$this -&amp;gt; _linkID )
        return FALSE;
    $this -&amp;gt; queryStr = $str;
    $flag             = FALSE;
    if ( $this -&amp;gt; dbType == &apos;OCI&apos; ) {
        if ( preg_match( &quot;/^\s*(INSERT\s+INTO)\s+(\w+)\s+/i&quot;, $this -&amp;gt; queryStr, $match ) ) {
            $this -&amp;gt; table = C( &quot;DB_SEQUENCE_PREFIX&quot; ) . str_ireplace( C( &quot;DB_PREFIX&quot; ), &quot;&quot;, $match[ 2 ] );
            $flag          = (boolean) $this -&amp;gt; query( &quot;SELECT * FROM user_sequences WHERE sequence_name=&apos;&quot; . strtoupper( $this -&amp;gt; table ) . &quot;&apos;&quot; );
        }
    }

    if ( !empty( $this -&amp;gt; PDOStatement ) )
        $this -&amp;gt; free();
    N( &apos;db_write&apos;, 1 );

    G( &apos;queryStartTime&apos; );
    $this -&amp;gt; PDOStatement = $this -&amp;gt; _linkID -&amp;gt; prepare( $str );
    if ( FALSE === $this -&amp;gt; PDOStatement ) {
        throw_exception( $this -&amp;gt; error() );
    }
    $result = $this -&amp;gt; PDOStatement -&amp;gt; execute();
    $this -&amp;gt; debug();
    if ( FALSE === $result ) {
        $this -&amp;gt; error();
        return FALSE;
    }
    else {
        $this -&amp;gt; numRows = $this -&amp;gt; PDOStatement -&amp;gt; rowCount();
        if ( $flag || preg_match( &quot;/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i&quot;, $str ) ) {
            $this -&amp;gt; lastInsID = $this -&amp;gt; getLastInsertId();
        }
        return $this -&amp;gt; numRows;
    }
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ThinkPHP内置抽象数据库访问层，它是基于PDO封装实现的，项目使用数据库是MySQL，下面开始找UPDATE方法的返回参数。&amp;lt;br&amp;gt;
通过&lt;code&gt;$result = $this -&amp;gt; db -&amp;gt; update( $data, $options );&lt;/code&gt;找到&lt;code&gt;UPDATE&lt;/code&gt;更新语句方法。&amp;lt;br&amp;gt;
再通过&lt;code&gt;return $this -&amp;gt; execute( $sql );&lt;/code&gt;找到&lt;code&gt;execute&lt;/code&gt;执行语句方法。&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$this -&amp;gt; numRows = $this -&amp;gt; PDOStatement -&amp;gt; rowCount();
if ( $flag || preg_match( &quot;/^\s*(INSERT\s+INTO|REPLACE\s+INTO)\s+/i&quot;, $str ) ) {
    $this -&amp;gt; lastInsID = $this -&amp;gt; getLastInsertId();
}
return $this -&amp;gt; numRows;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在&lt;code&gt;execute&lt;/code&gt;方法里有段代码返回个&lt;code&gt;rowCount()&lt;/code&gt;这是什么玩意...它认识我，我不认识它。翻一下手册了解到是返回SQL语句影响的行数（真是对不起楚老师当初还手把手教我们封装PDO...）&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;也就是说它返回的 SQL影响行数就是我判断的参数，根据SQL输出来说返回个0，是的，是个0。我的判断&lt;code&gt;$AddChildren == FALSE&lt;/code&gt;&amp;lt;br&amp;gt;
我瞬间就特么服了Save这个方法...，返回给我0，我是用等于号对比值&lt;code&gt;0 == FALSE&lt;/code&gt;这玩意貌似没啥意义...&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;p&gt;因为在使用&lt;code&gt;==&lt;/code&gt;比较的时候，&lt;strong&gt;0会进行布尔转换&lt;/strong&gt;，在PHP中0即FALSE。我是要你是用来判断错误的，你他妈一对比不是相等了...&amp;lt;br&amp;gt;
所以说全等&lt;code&gt;===&lt;/code&gt;进行比较值，&lt;strong&gt;拒绝类型转换&lt;/strong&gt;，&lt;strong&gt;直接比较值和类型&lt;/strong&gt;。结果就是整型不等于布尔，解决问题。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=ThinkPHP%20Save%20%E6%96%B9%E6%B3%95%E5%BC%95%E5%8F%91%E7%9A%84%E9%94%99%E8%AF%AF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-07-31-tp-save&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>爱上Go语言：终端命令</title><link>https://blog.lhasa.icu/posts/technology/2019-07-05-love-go</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-07-05-love-go</guid><pubDate>Fri, 05 Jul 2019 02:18:00 GMT</pubDate><content:encoded>&lt;h2&gt;Hello Golang！&lt;/h2&gt;
&lt;p&gt;在前段时间我学习Docker的过程中和Go进行了我们的第一次约会，超级简单的环境配置搭建、简洁而清晰的语法，近期我已经完全沦陷于Go，已经到了如痴如醉的地步。&lt;/p&gt;
&lt;p&gt;作为一个phper，我发现学习Go也是有优势的！PHP和Go都是C语系，上手难度不大，我在微服务、区块链专栏中也经常看到PHP\Go的需要。&lt;/p&gt;
&lt;p&gt;至于发展前景也是一片光明。Go诞生于Google且开源，打造的王牌项目都是没的说：Docker、Kubernetes...&lt;/p&gt;
&lt;h2&gt;build、run、clean&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;// 这是测试编译命令，和其他静态类型语言一样，要执行 Go程序，需要先进行编译，然后在执行产生的可执行 .exe 文件，
// 如果我们在执行 go build 命令时不后跟任何代码包，那么命令将编译当前目录下的代码包。但不是所有的 Go 程序都可以编译成可执行文件的，它需要满足两个条件：
$ go build
    // 例如以下代码且取名 main.go 在第一行 package main 表示是一个可执行的程序，当然每个 Go应用程序都应当包含一个名为 main 的包。
    // 看到 import (&quot;fmt&quot;) 这是指将 fmt 这个包导入 main.go，表示在 main.go 中可以使用 fmt 包中可见所有方法、类型等。

    package main
    import (
        &quot;fmt&quot;
    )
    func main() {
        fmt.Println(&quot;Hello Go!&quot;)
    }

// run 可以把编译源文件和运行对应的可执行文件，这两步化为一步（需要注意的是 run 不会产生文件）
$ go run

// 删除当前目录下的所有可执行文件（无参数）
$ go clean [alrtAFR]
    // 会删除对应的可执行文件
    sourcefile.go
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;install、test&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# install 用于编译并安装指定的代码包及依赖包。该命令分成两步操作，第一步是生成结果文件（.exe或.a），第二部把编译结果移到 $GOPATH/pkg 或 $GOPATH/bin
    # .exe：带 main 函数的Go文件产生的，有函数入口，所有可以直接运行
    # .a：应用包，不包含main函数的Go文件产生的，没有函数入口，只能被调用
$ go install

# 用来运行测试，这种测试是以包为单位的。需要遵循三个规则
    # 测试源码文件是名称以“_test.go”为后缀
    # 内涵若干测试函数的源文件
    # 测试函数一般是以“Test”为名称前缀并有一个类型为“testing.T”的参数声明的函数
$ go test
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;get、doc&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 获取代码进行自动编译和安装
$ go get [-alrtAFR]
    # 显示操作流程日志及信息
    -v
    # 下载丢失的包，但不更新已经存在的包
    -u
    # 只下载，不自动安装
    -d
    # 允许使用 HTTP 方式进行下载操作
    -insecure

# 支持 package、func const、var这些代码生成文档，且只对 Public 变量自动生成，而 Private 变量不会
$ go doc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;其他命令工具&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看Go当前的版本
$ go version

# 用来修复以前老版本的代码到新版本，列入go1之前老版本的代码转化到go1
$ go fix

# 查看当前go的环境变量
$ go env

# 列出当前全部安装的package
$ go list

# 格式化Go代码文件
$ go fmt
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%88%B1%E4%B8%8AGo%E8%AF%AD%E8%A8%80%EF%BC%9A%E7%BB%88%E7%AB%AF%E5%91%BD%E4%BB%A4&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-07-05-love-go&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)一个程序员眼中的价值</title><link>https://blog.lhasa.icu/posts/life/2019-06-04-phper-value</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2019-06-04-phper-value</guid><pubDate>Tue, 04 Jun 2019 03:54:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://www.laruence.com/2015/01/02/2999.html&quot;&gt;Laruence&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;前天看了TimYang的&amp;lt;&lt;a href=&quot;https://timyang.net/tao/thoughts-2014&quot;&gt;一个技术从业人员眼中的2014&lt;/a&gt;&amp;gt; , 有些观点我很是赞同, 于是我也有了想写点什么的冲动…&lt;/p&gt;
&lt;p&gt;在2015年的第二天, 我终于好像有了一些跳跃的想法, 可以说给大家听听. 也许不够体系, 不够完整, 但或许能得到一些共鸣.&lt;/p&gt;
&lt;p&gt;我先给我大家讲讲我的故事, 我在2007年的时候去了雅虎实习. 当时应聘实习的时候, 我记得我和面试官应该表达过, 我不在乎赚多钱(实习生工资), 只是希望学习.&lt;/p&gt;
&lt;p&gt;后来, 2008年的时候要毕业了, 因为在雅虎的氛围等让我觉得非常好, 我几乎没有看什么其他机会就签了雅虎中国, 当时的工资是7000一个月..&lt;/p&gt;
&lt;p&gt;就这样相安无事的过了2个月, 突然第三个月要补交社保什么的, 一个月的工资发到手只有不到1000多块(也许我记得不是很精确, 不过只记得很少)..&lt;/p&gt;
&lt;p&gt;然后, 我就意识到, 不行, 我得先养好自己…… 于是选择了跳槽…….&lt;/p&gt;
&lt;p&gt;到今天, 我已经不会给刚毕业的孩子们说: 刚毕业的时候不要注意工资了..&lt;/p&gt;
&lt;p&gt;这是我想说的程序员的一个”价值”方面…&lt;/p&gt;
&lt;p&gt;2011在百度呆了3年的时候, 我的技术职级到了T7, 太多的赞誉和给面子的称赞, 让我误以为自己技术已经是”登峰造极”了, 觉得自己特别特别牛逼, 公司对我的职级是不公平的. 我觉得我得到了不公平的评价, 我认为评价我的其他领域的架构师都是不懂我的牛逼.我觉得我的薪水实在是不衬我的能力..等等等….&lt;/p&gt;
&lt;p&gt;3年来, 我又进步了很多, 也在不少新的领域有了进一步的提升, 我认识到, 当时的我是多么的狭隘, 技术缺陷是多么的明显, 和楼外楼的人们又有多大的差别.&lt;/p&gt;
&lt;p&gt;现在的我, 更喜欢用自己的不足去和别人的优点做比较, 追赶他们的优点, 而不是把别人拉到自己的领域比较别人, 进一步蒙蔽自己的缺点…&lt;/p&gt;
&lt;p&gt;这是我想说的, 程序员自己眼中的一个”价值”方面…..&lt;/p&gt;
&lt;p&gt;在PHP开发组做了一段时间的时候, 帮助不少人解决了PHP的bug, 有一次很快速的解决ifix提出的一个bug, ifix的人发邮件想我表达谢意, 并且希望我给他们我的邮寄地址, 他们想要寄点礼物感谢我..&lt;/p&gt;
&lt;p&gt;我感觉好像不是那么好, 于是我就问Rasmus, 是否可以接受这个礼物, 他说: “我们不是政客, 我们做开源, 为不知道多少人创造了多大的价值, 接受点别人真心感谢的礼物, 没什么不好”.&lt;/p&gt;
&lt;p&gt;最后我收到了一个ifix套件… 上面还有一条便签, “Thanks for your help”.&lt;/p&gt;
&lt;p&gt;这是我想说的程序员的另外一个”价值”方面…..&lt;/p&gt;
&lt;p&gt;2014年, 应该是做贡献做的最大的一年, 在微博内, 我们把无线LAMP的性能提高了2.6倍, 响应时间下降一半多, 节省服务器60%(每年几百万的成本).&lt;/p&gt;
&lt;p&gt;在PHP社区, 我们经过去年到今年的各种尝试, 终于得到了PHP7, 性能相比PHP5.6有了成倍的提升, 每一个PHP项目都可以透明的得到巨大的性能提升, 也许整个社区也许都会为此而受益.&lt;/p&gt;
&lt;p&gt;我也发现有了很多支持我的人, 也有了不少的”粉丝”, 会收到很多或明显,或不明显的尊敬.&lt;/p&gt;
&lt;p&gt;这是我想说的, 我最看重的”价值”….&lt;/p&gt;
&lt;p&gt;好吧, 说了这么多, 总结下吧:&lt;/p&gt;
&lt;p&gt;一个程序员的价值, 在于你真正产生了多大的贡献, 为公司, 为他人..&lt;/p&gt;
&lt;p&gt;如果你真正做出了真正有价值的贡献, 那么你就可以得到于价值相当的肯定. 或多点, 或少点, 或早点, 或晚点.&lt;/p&gt;
&lt;p&gt;也许你会自认为得到的不是你期望的, 或者得到的少于付出得, 但, 那应该不会差太远.&lt;/p&gt;
&lt;p&gt;而如果只追求你得到的价值, 并且要追求各种价值, 而忽略了你付出的价值, 那会活的很幸苦..&lt;/p&gt;
&lt;p&gt;这些散落的点滴, 分享一下.&lt;/p&gt;
&lt;p&gt;2015, 祝福大家, 都能创造更大的价值, 追求到自己想要的价值, 新年快乐~&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E4%B8%80%E4%B8%AA%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9C%BC%E4%B8%AD%E7%9A%84%E4%BB%B7%E5%80%BC&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2019-06-04-phper-value&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>2019-05-22 博客功能更新记录</title><link>https://blog.lhasa.icu/posts/technology/2019-05-22-blog-feature-update</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-05-22-blog-feature-update</guid><pubDate>Wed, 22 May 2019 10:57:00 GMT</pubDate><content:encoded>&lt;p&gt;这段时间我居然有个危险的想法，更换博客板式...确实也下了狠心去找。弄了一些理想的 Jekyll 主题。&lt;/p&gt;
&lt;p&gt;可是那些主题代码都很乱。我很受不了...想一想还是自己动手改版吧。我博客主要问题就是移动端功能支持不太好，&lt;/p&gt;
&lt;p&gt;没有PC端一样的博文分类导航，这我怎么受得了？必须整它。平时上班也忙，大概整了俩星期。增加了：“移动端博文分类、移动端文章上滑”，&lt;/p&gt;
&lt;p&gt;经过这次给移动端改版我好喜欢 Jekyll 这个静态模板引擎很好用。摄影分类也需要改版，它跟技术这类文章不一样，在看摄影分类文章系列时，&lt;/p&gt;
&lt;p&gt;只有文字显的太古板了。我想做一个卡片格式的。友联板块也要改一改。好了太晚了好饿的，要回去了...公司六点下班，我呆到九点半...公司人七点就走光了，附图一张，白！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;blog-feature-update.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=2019-05-22%20%E5%8D%9A%E5%AE%A2%E5%8A%9F%E8%83%BD%E6%9B%B4%E6%96%B0%E8%AE%B0%E5%BD%95&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-05-22-blog-feature-update&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)我眼中的技术高手</title><link>https://blog.lhasa.icu/posts/technology/2019-05-19-tech-whiz</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-05-19-tech-whiz</guid><pubDate>Sun, 19 May 2019 03:47:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://github.com/lifesinger/blog/issues/126&quot;&gt;玉伯的博客&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;今天发了一条&lt;a href=&quot;https://weibo.com/1748374882/zoavsuWAz&quot;&gt;微博&lt;/a&gt;：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;会原生 JavaScript 不代表什么，懂 jQuery、YUI 等才真正好。怎么这么多人有原生主义情结呢？走出那点小天地，海阔天高。&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;很多人已经猜出，这是为了晚上的文章而发，提前收集大家的想法。这个话题，很早就想谈，肯定会引起口水仗，但有些事不辩不明，不理不清，与其和谐社会，不如辛亥革命。&lt;/p&gt;
&lt;h2&gt;奇怪的现象&lt;/h2&gt;
&lt;p&gt;平时工作，时不时能听到一些困惑、感慨：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;jQuery 虽好，但只会 jQuery，不会原生 JS 是不被大公司认可的。&lt;/code&gt;
&lt;code&gt;最近半年对原生 JS 有些生疏，得补一补。&lt;/code&gt;
&lt;code&gt;得好好看看 ECMAScript 规范，把 JS 语言学透彻。&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;和原生情结对应的，是国内程序员特别喜欢研读源码，比如：&lt;/p&gt;
&lt;p&gt;&lt;code&gt;jQuery 源码分析系列&lt;/code&gt;
&lt;code&gt;YUI 源码分析&lt;/code&gt;
&lt;code&gt;Backbone 及 Underscore 源码解析&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;国内程序员对源码的热衷，可以拿 SeaJS 的数据来看：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;seajs.png&quot; alt=&quot;SeaJS 数据&quot; /&gt;&lt;/p&gt;
&lt;p&gt;fork 数高达 500 多，但 watch 数只有 1000 多，这其实是不正常的。相比而言，RequireJS 的数据正常很多：&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;requirejs.png&quot; alt=&quot;RequireJS 数据&quot; /&gt;&lt;/p&gt;
&lt;p&gt;简言之，国内与国外相比，有比较明显的两个特点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;对原生 JS 的学习心更强。&lt;/li&gt;
&lt;li&gt;对类库、框架的源码更感兴趣。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这两点看起来很好，可是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;研究原生 JS 的优秀文章，大都出自国外程序员。&lt;/li&gt;
&lt;li&gt;类库、框架，国人好像一直在研究，鲜有产出。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这肯定跟我们是社会主义国家有关，但我越来越怀疑这一点。&lt;/p&gt;
&lt;h2&gt;语言高手们&lt;/h2&gt;
&lt;p&gt;真正的语言高手不多，我不是，正在看这篇文章的你，很可能也不是，而且这一辈子可能都和我一样成为不了语言高手。&lt;/p&gt;
&lt;p&gt;JavaScript（纯语言，不含 DOM 等）高手，在国内屈指可数。周爱民、白露飞、老赵、winter、月影、hax 等等等等，还有一些非常低调的隐士，这些人读 ECMAScript 规范像磕瓜子一样轻松，甚至能花几个晚上就像 BE 大神一样造出一门新语言来。你我等闲之辈，除了佩服之外，只能去谈恋爱。&lt;/p&gt;
&lt;p&gt;工作中，我们需要语言高手吗？肯定的说，需要！可是，我们需要大量语言高手吗？除了特殊岗位，我相信很多公司都不需要！&lt;/p&gt;
&lt;p&gt;题外话：目前为人知的 JS 语言高手里，除了周爱民，我最看好白露飞。这是一个有能力也有潜力造就 SuperScript 的人，最佩服的是他有实际行动，虽然方向未必正确。&lt;/p&gt;
&lt;h2&gt;我们的价值在哪&lt;/h2&gt;
&lt;p&gt;除了重新投胎，我们大部分人这辈子都不大可能有兴趣、有能力、有机缘去成为 BE 大神了。这是个残酷的现实，之所以残酷，只因视野太狭窄。&lt;/p&gt;
&lt;p&gt;跳出来，天大地大。妹子多着呢，而且更漂亮。&lt;/p&gt;
&lt;p&gt;Douglas Crockford 的 JS 能力很可能不及 winter，但 Douglas 规范并布道了 JSON 格式，天下留名，惠泽全球。&lt;/p&gt;
&lt;p&gt;Jeremy Ashkenas 的 JS 能力可能还不如老赵，但 Jeremy 用很裸的代码写就了 Backbone，至少影响了一万人，给各个公司创造的价值总额很可能过千万美刀。&lt;/p&gt;
&lt;p&gt;更不用说 Isaac Z. Schlueter，这小伙的 JS 功力很可能还不如我，但 Isaac 打造了 npm 生态圈，而我至今只有精力玩玩 Ant 和 Grunt。&lt;/p&gt;
&lt;p&gt;有幸还看过 Google Docs 的前端源码，那代码和 Java 一样中规中矩。但在 RTE 领域，Google Docs 是王者，里面的专利都一堆一堆的……&lt;/p&gt;
&lt;p&gt;特别想提及的还有开发 Evernote Clearly 的前端工程师，这小伙子的代码，我眼睁睁看着其从很生涩的 JS 代码，逐步演化成上万行牛逼代码还保持了相当好的可维护性。这份代码就像 Clearly 产品一样奕奕生光。&lt;/p&gt;
&lt;p&gt;以及把 jQuery 用得出神入化的 Amazon！前不久那个秒杀国内互联网公司的悬浮菜单，可不是研究原生 JS 能想出来的。&lt;/p&gt;
&lt;p&gt;还有 Facebook 的工程师们，Twitter 的工程师们…… 这些故事大家并不陌生。&lt;/p&gt;
&lt;h2&gt;不是总结的总结&lt;/h2&gt;
&lt;p&gt;不贬低语言高手们，也不反对去研究编译原理、ECMAScript 规范等。作为技术人员，我们需要这种精神。但是，这仅仅是很小很小很小很小很小的一个领域。并且在这个领域里，永远有比你更聪明的人。&lt;/p&gt;
&lt;p&gt;具体对 JavaScript 语言来说，会用就好。搞清楚数据类型、作用域、闭包、原型链等基本概念，足矣。再深入进去，对绝大部分人来说，除了能满足下心理上的优越感，对实际工作不会有任何实质性帮助。&lt;/p&gt;
&lt;p&gt;语言的本质和互联网一样，只是工具，是剪刀、石头、布。让张小泉去研究怎么做剪刀就好，我们用好剪头，去剪出各种窗花，更有意思。还有一个有趣的事实是，张小泉会造剪头，但剪不好窗花。&lt;/p&gt;
&lt;p&gt;跳出很小很小很小很小很小的语言领域之外，天大地大。永远不要妄自菲薄，每个人身上都背负着独特的使命。去努力寻找自己的，不要老盯着别人的，否则就会成为观众。&lt;/p&gt;
&lt;p&gt;好像跑题了。前面那个奇怪的现象，还有很多想吐槽的点。比如&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;源码只是很小很小的一部分。直接读源码往往无法领会类库框架的精髓。不读源码，用心去用，用时间去体味，偶尔针对性看看源码，往往更能掌握一个类库框架的真谛。
对社区的贡献可以有很多很多。你的使用经验、用心的 bug 提交、入乡随俗的 pull request、一个认真的评论等等，这些都比去研究什么狗屁源码更有价值。&lt;/li&gt;
&lt;li&gt;一个 Java 高手如果说他会原生 Java，那一定会遭来很多人的围观。我还会谭浩强教我的 C 呢，那几个 if else 还有结构体、指针等谁不会。语言之外的领域知识，才真正造就了高手。对于前端来说，会原生 JS 只能打 20 分，另外 40 分需要你深入使用 CSS、DOM、HTML5 等领域知识，还有 20 分需要你对业务需求、架构设计等有真正的运用，这已经 80 分了，不要太贪心。剩下 20 分，只有两个字：勤奋。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&quot;figure.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;题图：我的网名射雕的来历，喜欢郭靖，无底线。&lt;/p&gt;
&lt;p&gt;（完）&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E6%88%91%E7%9C%BC%E4%B8%AD%E7%9A%84%E6%8A%80%E6%9C%AF%E9%AB%98%E6%89%8B&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-05-19-tech-whiz&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>ionic 笔记 (环境搭建与命令)</title><link>https://blog.lhasa.icu/posts/technology/2019-05-06-ionic</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-05-06-ionic</guid><pubDate>Mon, 06 May 2019 00:34:00 GMT</pubDate><content:encoded>&lt;p&gt;昨天下午项目经理让我学习 ionic，我就折腾了一下，经过一番折腾我挺喜欢 ionic 和 node.js，不过我也是在折腾的道路上越走越远，别看这偏博客上就那么点东西，可我这小白操作，真的非常难受...中途遇到各种问题...哎...&lt;/p&gt;
&lt;h2&gt;在项目中用到的环境依赖：&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Android SDK&lt;/li&gt;
&lt;li&gt;Java JDK&lt;/li&gt;
&lt;li&gt;Gradle&lt;/li&gt;
&lt;li&gt;ionic&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;下载安装Node.js&lt;/h2&gt;
&lt;p&gt;安装的时候把环境变量默认勾选所以不用我们手动配置&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 查看的当前的Node版本
$ node -v 
v10.15.3 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;更换源&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 临时
$ npm --registry https://registry.npm.taobao.org install express

# 永久
$ npm config set registry https://registry.npm.taobao.org

# 验证是否更换成功
$ npm config get registry
https://registry.npm.taobao.org/
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第一个Node.js程序！&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;achuan@DESKTOP-CL4MMTQ MINGW64 /h/Node.js
$ vi HiNodeJs.js

    console.log(&quot;Hello World!&quot;);

achuan@DESKTOP-CL4MMTQ MINGW64 /h/Node.js
$ node HiNodeJs.js
Hello World!
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;交互模式&lt;/h3&gt;
&lt;p&gt;用终端 &lt;code&gt;node&lt;/code&gt; 进入交互模式，可以直接执行遇见并显示结果&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;achuan@DESKTOP-CL4MMTQ MINGW64 /h/Node.js  
$ node  
&amp;gt; console.log(&quot;Hello World!&quot;);  
Hello World!  
undefined
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;下载安装 Android SDK&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;微云链接：&lt;a href=&quot;https://share.weiyun.com/5ybFh0k&quot;&gt;https://share.weiyun.com/5ybFh0k&lt;/a&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;li&gt;密码：&lt;code&gt;achuan&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;配置环境变量&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;ANDROID_HOME
ANDROID_SDK_ROOT
H:\environment\Android\android-sdk

我也不是很理解，明明一样还要声明俩？但是少一个就报错，说 ANDROID_HOME 已经弃用......

# 在用户变量找&quot;PATH&quot;并新建环境变量
%ANDROID_HOME%\tools

# android 命令帮助，出现内容即环境配置成功
$ android -h 
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置 Android SDK Manager&lt;/h3&gt;
&lt;p&gt;在&lt;code&gt;Android SDK Manager&lt;/code&gt;找到下面这些勾选上，然后点击&lt;code&gt;Install packages&lt;/code&gt;按钮进行下载&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Tools
    # 工具包自带的Tools
    Aondroid SDK Tools

    # Android公用平台工具
    Aondroid SDK Plaform-tools
    
    # Android构建工具
    Aondroid SDK BUild-tools

# 必须安装，至少需要安装一个版本的API工具包！
Android 9 (API 28)
    # 开发app平台依赖和调试工具
    SDK Platform

    # 模拟器镜像
    Intel x86 Atom_64 System Image

    # API源码
    Sources for Android SDK

Extras
    # 安卓兼容库
    Android Support Repository

    # 加速 Intel 体系的安卓模拟器
    Intel x86 Emulator Accelerator (HAXM install)
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;创建、配置并运行 avd 模拟器&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 创建 avd 模拟器，执行后会有个对话框，右侧有创建按钮根据需要去配置模拟器配置
$ android avd

# 运行 avd 模拟器
$ emulator -avd [avdName]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;下载安装 Java JDK&lt;/h2&gt;
&lt;p&gt;在官网下载真是死慢，我下载后放在微云了&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微云链接：&lt;a href=&quot;https://share.weiyun.com/54nkkob&quot;&gt;https://share.weiyun.com/54nkkob&lt;/a&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;li&gt;密码：&lt;code&gt;achuan&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;配置环境变量&lt;/h3&gt;
&lt;p&gt;在安装 Java JDK 点被环境变量出现问题，需要自己手动配置一下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JAVA_HOME
H:\environment\Java\jdk1.8.0_211

# 在用户变量找&quot;PATH&quot;并新建环境变量
%JAVA_HOME%\bin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在系统环境变量&quot;Path&quot;里找下面这条删掉它&amp;lt;br&amp;gt;
&lt;code&gt;C:\Program Files (x86)\Common Files\Oracle\Java\javapath&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;下载安装 Gradle&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;微云链接：&lt;a href=&quot;https://share.weiyun.com/5AuD53j&quot;&gt;https://share.weiyun.com/5AuD53j&lt;/a&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;li&gt;密码：&lt;code&gt;achuan&lt;/code&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;安装完毕后查看一下版本，成功忽略下一步，我点背。&amp;lt;br&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ gradle -v
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;配置环境变量&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;GRADLE_HOME
H:\environment\gradle-4.10.3

# 在用户变量找&quot;PATH&quot;并新建环境变量
%GRADLE_HOME%\bin
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;安装ionic&lt;/h2&gt;
&lt;p&gt;这下轮到我们的猪脚&quot;ionic&quot;登场!&lt;code&gt;npm install -g cordova ionic&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;achuan@DESKTOP-CL4MMTQ MINGW64 /h/Node.js
$ npm install -g cordova ionic
C:\Users\achuan\AppData\Roaming\npm\cordova -&amp;gt; C:\Users\achuan\AppData\Roaming\npm\node_modules\cordov
a\bin\cordova
C:\Users\achuan\AppData\Roaming\npm\ionic -&amp;gt; C:\Users\achuan\AppData\Roaming\npm\node_modules\ionic\bi
n\ionic
+ ionic@4.12.0
+ cordova@9.0.0
added 718 packages from 390 contributors in 658.274s
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;第一个ionic应用！&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 创建一个空应用 myApp
$ ionic start myApp tabs

# 添加对 android 平台的支持 
$ ionic cordova platform add android

    # 参数可选
    [android] or [ios]

# 编译项目 apk
$ ionic cordova build android [可填选参数]

    # 压缩编译项目 apk
    --prod

    # 编译发行版 apk
    --release

    # 编译压缩发行版 apk
    --release --prod

生成的 apk 文件在  `[项目名]\platforms\android\app\build\outputs\apk\debug\`
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;运行项目进行调试&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 用默认浏览器运行调试，默认端口`8100`，`127.0.0.1:8100`。
$ ionic serve

# 在 AVD 模拟器中运行调试 [android] or [ios]
$ ionic cordova emulate android
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;遇到的问题&lt;/h3&gt;
&lt;p&gt; 看着终端依赖疯狂报错......心好累......忽然觉得我这辈子最让我难受的不是电脑卡、网速慢这都是死问题能搞好。而这软件框架在win运行真是各种奇葩环境依赖Bug......它能把我逼疯......&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;缺少 Android SDK&lt;/strong&gt;&amp;lt;br&amp;gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;You have been opted out of telemetry. To change this, run: cordova telemetry on.
Failed to find &apos;ANDROID_HOME&apos; environment variable. Try setting it manually.
Failed to find &apos;android&apos; command in your &apos;PATH&apos;. Try update your &apos;PATH&apos; to include path to valid SDK directory.
[ERROR] An error occurred while running subprocess cordova.

        cordova build android exited with exit code 1.

        Re-running this command with the --verbose flag may provide more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Java JDK 版本过低&lt;/strong&gt;&amp;lt;br&amp;gt;
这玩意有个对 Java JDK 版本要求，&lt;code&gt;不能低于1.7&lt;/code&gt;正好被我踩个准正好1.7.....&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Checking Java JDK and Android SDK versions
Requirements check failed for JDK 8 (&apos;1.8.*&apos;)! Detected version: 1.7.0
Check your ANDROID_SDK_ROOT / JAVA_HOME / PATH environment variables.
ANDROID_SDK_ROOT=undefined (recommended setting)
ANDROID_HOME=H:\environment\Android\android-sdk (DEPRECATED)
[ERROR] An error occurred while running subprocess cordova.

    cordova build android exited with exit code 1.

    Re-running this command with the --verbose flag may provide more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Gradle 版本过高导致不兼容&lt;/strong&gt;&amp;lt;br&amp;gt;
这玩意跟 Java JDK &quot;搞双簧？&quot;版本过高导致不兼容。
以前是我单独装的&lt;code&gt;Gradle 5.4.1 all&lt;/code&gt;报错后不知道怎么了，自动修复给下载了&lt;code&gt;Gradle 4.10.3 all&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code&gt;Using cordova-fetch for andrid
Failed to fetch platform andrid
Probably this is either a connection problem, or platform spec is incorrect.
Check your connection and platform name/version/URL.
Error: npm: Command failed with exit code 1 Error output:
npm ERR! code E404
npm ERR! 404 Not Found: andrid@latest

npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\achuan\AppData\Roaming\npm-cache\_logs\2019-05-07T05_31_11_192Z-debug.log
[ERROR] An error occurred while running subprocess cordova.

    cordova platform add andrid --save exited with exit code 1.

    Re-running this command with the --verbose flag may provide more information.
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;常用命令&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看 Node.js 版本
$ npm -v

# 安装 ionic
$ nmp install -g ionic

# 安装 Cordova 
$ nmp install -g cordova

# 更新 ionic cordova
$ nmp update -g ionic cordova

# 查看 ionic 版本
$ ionic -v

# 查看 ionic 环境信息
$ ionic info

# 查看 ionic 信息
$ ionic -info

# 移除 [android] or [ios] 平台的支持
$ ionic cordova platform remove android

# 用浏览器进行本地调试
$ ionic serve

# 在模拟器中运行调试 [android] or [ios]
$ ionic cordova emulate android

# 显示系统中全部 android 平台
$ android list targets

# 显示系统中全部 avd 模拟器
$ android list avd

# 删除 avd 模拟器
$ android delete avd -n [avdName]
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=ionic%20%E7%AC%94%E8%AE%B0%20(%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E4%B8%8E%E5%91%BD%E4%BB%A4)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-05-06-ionic&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>我的第一部单反相机</title><link>https://blog.lhasa.icu/posts/photo/2019-04-20-one-single-lens</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/photo/2019-04-20-one-single-lens</guid><pubDate>Sat, 20 Apr 2019 03:26:00 GMT</pubDate><content:encoded>&lt;p&gt;咱老百姓，今儿真啊么真高兴！嘿嘿，我的第一部单反相机&quot;佳能EOS 200D 银色单反套机&quot;，今早9:18快递到了！纸箱镇楼！
受苦了宝贝...发货之前忘了指定快递服务，默认发了圆通。看这箱子样子，想起以前我去快递分拣兼职，活太累了管它什么物品都是暴力扔...&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;sealing.jpg&quot; alt=&quot;纸箱镇楼&quot; /&gt;&lt;/p&gt;
&lt;p&gt;大大小小拆完了就是这样样子了（32G SD卡、新秀丽蓝色双肩包、限量20年礼盒、Luce波点内胆包、EOS 200D机身、电池充电器\线 LC-E17C、锂电池LP-E17、相机宽背带 EW-400D、EF-s 18-55m f/4-5.6 IS STM）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;all-the-items.jpg&quot; alt=&quot;所有的物品&quot; /&gt;&lt;/p&gt;
&lt;p&gt;看到这个狗头挺烦的，也怪自己吧...在天猫买件肯高UV镜55mm。买回来发现装不上...一看狗头58mm。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;the-lens.jpg&quot; alt=&quot;18-55mm狗头&quot; /&gt;&lt;/p&gt;
&lt;p&gt;为了业余摄影，还特地在博客开了个&quot;摄影&quot;分栏，感觉自己这次博客要大改了一下，需要做个几个相册，就那种卡片视图效果，不过我博客逻辑有点特殊，估计需要点时间，让我头疼的是图片，以后摄影照片一张5MB-10MB，就Github在国内这个接入速度有点吃不消，还是要想办法无备案DNS加速。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;place-the-sample.jpg&quot; alt=&quot;EOS 200D机身 + 18-55mm狗头合影&quot; /&gt;&lt;/p&gt;
&lt;p&gt;这里有点尴尬...本想来拍几张预热看看，没电来了，晚上准备骑行去广场玩玩&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;electricity.jpg&quot; alt=&quot;尴尬...刚买回来需要充电&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;install.jpg&quot; alt=&quot;装到内胆包&quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E9%83%A8%E5%8D%95%E5%8F%8D%E7%9B%B8%E6%9C%BA&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Fphoto%2F2019-04-20-one-single-lens&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>推荐 10 个优秀的技术栈社区</title><link>https://blog.lhasa.icu/posts/technology/2019-04-17-it-site</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-04-17-it-site</guid><pubDate>Wed, 17 Apr 2019 05:11:00 GMT</pubDate><content:encoded>&lt;p&gt;作为一个技术人，经验积累对于我们来说无比重要，我们只有不断的学习提升自己才能不被这个圈子淘汰。另外也要不断的总结自己的经验和教训。既然要学习那总要有途径吧，现在网络已经很发达了，社区\论坛随处可见，可高质量并不多。今天拿出来给大家分享一下，这些论坛\社区也是业界公认的优秀...&lt;/p&gt;
&lt;h2&gt;Github&lt;/h2&gt;
&lt;p&gt;网址：&lt;a href=&quot;https://github.com&quot;&gt;https://github.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Github是最活跃的开源代码库和版本控制平台，同时也是全球最大的男性交友平台，因此也有网友叫做：“Gayhub”（Gayhub是真实存在的网站就像“知乎”和“逼乎”...不过这个Gayhub真是Gay...）&lt;br /&gt;
Github几乎是在业界知名度最高的技术社区，各个领域的开源类库、代码应有尽有，当然也不缺乏大牛入住，比如我的偶像Linus。&lt;/p&gt;
&lt;h2&gt;Stack Overflow&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://stackoverflow.com&quot;&gt;https://stackoverflow.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Stack Overflow是最受程序猿欢迎的IT技术问答社区，而且内容也是最丰富的社区之一。百度我不知道，就说google搜索问题时，基本每次都有这小子。后来我在技术问题上遇到了难点直接上在Stack Overflow搜。搜不到满意的答案时再自己发起提问。不过这个网站是英文...扯淡是有人把Stack Overflow给汉化了...&lt;a href=&quot;https://routinepanic.com&quot;&gt;协慌网&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;InfoQ&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://www.infoq.com&quot;&gt;https://www.infoq.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;InfoQ是一个面向IT领域的技术媒体社区。通过提供高质量新闻、文章、演讲，以促进IT领域知识的传播和分享。InfoQ还专设的中文、英文、日文等海外版站点。&lt;/p&gt;
&lt;h2&gt;FreeBuf&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://www.freebuf.com&quot;&gt;https://www.freebuf.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;FreeBuf是国内活跃度较高的垂直类网络安全网站。网站主要内容就是国内外一些技术文章。网站人群以极客、黑客、从事安全类人员居多。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官宣: &quot;FreeBuf希望为国内网络安全领域带来一抹正能量，传递真正的黑客与极客精神。&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;ChinaUnix&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://www.chinaunix.net&quot;&gt;https://www.chinaunix.net/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;我想作为一个IT开发者人员，怎么也避免不了跟Linux系统打交道。而ChinaUnix就是以Linux\Unix、服务器、数据库、内核源码等技术为主的自由、开放的技术社区。运维人员居多。&lt;/p&gt;
&lt;h2&gt;看雪安全论坛&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://bbs.pediy.com&quot;&gt;https://bbs.pediy.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;看雪的历史比较悠久，创始于2000年（那年我刚出生...）看雪是国内首个讨论加密解密技术的论坛，看雪见证了中国互联网的发展及国内安全领域大环境的发展。社区大牛居多，氛围很棒，在国内安全圈具有很强的号召力。&lt;/p&gt;
&lt;h2&gt;吾爱破解&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://www.52pojie.cn&quot;&gt;https://www.52pojie.cn/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;吾爱破解成立于08年，与看雪一样是国内氛围很好的论坛，主要板块是逆向、脱壳。。站内帖子基本没有灌水评论，人群我感觉论坛学生不少，因为小时候喜欢软件破解，看雪和吾爱论坛我也是来回逛。&lt;/p&gt;
&lt;h2&gt;比格张&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://bigezhang.com&quot;&gt;https://bigezhang.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;比格张是一个发现和分享互联网优质资源的平台，网站资源比较广：技术、开发者、产品、设计运营、素材等，平台还设有新闻热榜，如知乎、微博等各种热榜话题。&lt;/p&gt;
&lt;h2&gt;黑客派&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://hacpai.com&quot;&gt;https://hacpai.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;黑客派是一个活跃的小众社区，大家在这里相互信任，以平等 • 自由 • 奔放的价值观进行分享交流。社区名称寓意：HacPai 分别取 Hacker / Painter 的头三个字母组成，源自《黑客与画家》。&lt;/p&gt;
&lt;h2&gt;图灵社区&lt;/h2&gt;
&lt;p&gt;网址: &lt;a href=&quot;https://www.ituring.com.cn&quot;&gt;https://www.ituring.com.cn/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;技术改变世界，阅读塑造人生。社区逛够了，我们坐下来安静的看会儿书吧！图灵社区是一个计算机书籍类社区。图灵社区电子书做的很帮，因为图灵自己就是出版社，电子书籍的排版真的是超赞！同时也提供 mobi 推送，可以在 Kindle 等设备阅读。而且图灵电子书全部是 DRM-Free（未加密），技术上来说我们可以任意拷贝。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%8E%A8%E8%8D%90%2010%20%E4%B8%AA%E4%BC%98%E7%A7%80%E7%9A%84%E6%8A%80%E6%9C%AF%E6%A0%88%E7%A4%BE%E5%8C%BA&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-04-17-it-site&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>快速定位 Apache 错误</title><link>https://blog.lhasa.icu/posts/technology/2019-04-15-apache-error</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-04-15-apache-error</guid><pubDate>Mon, 15 Apr 2019 08:15:00 GMT</pubDate><content:encoded>&lt;p&gt;今天给项目配置权限的时候又遇到了Apache错误，这种事情早习惯了，排错了...要说启动吧，您看这让人难受错误提示...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Windows 不能在 本地计算机 启动 apache24。有关更多信息，查阅系统事件日志。如果这是非 Microsoft 服务，请与服务厂商联系，并参考特定服务错误代码 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是啥？？？错误报告这么官方真的没意思。。。一般配置遇到问题我都是看日志，不过日志也是经常不靠谱，他描述的也是很扯淡...&lt;/p&gt;
&lt;p&gt;这个时候就是还是启动apache启动程序好使，文件名叫“httpd.exe”位置在apache根目录“bin”目录下，通过命令行启动就好。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;achuan@DESKTOP-CL4MMTQ MINGW64 /c/AppServ
$ cd Apache24/bin

achuan@DESKTOP-CL4MMTQ MINGW64 /c/AppServ/Apache24/bin
$ ./httpd.exe
AH00526: Syntax error on line 113 of C:/AppServ/Apache24/conf/extra/httpd-vhosts.conf:
&amp;lt;Directory &quot;H:\\tp5\\public&quot;&quot;&amp;gt; path is invalid.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个错误大概说的意思是 &lt;code&gt;C:/AppServ/Apache24/conf/extra/httpd-vhosts.conf&lt;/code&gt; 文件第113行语法错误，&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;Directory &quot;H:\tp5\public&quot;&quot;&amp;gt;路径无效。   打开httpd-vhosts.conf&lt;/code&gt;文件后，定位到113行发现路径多个“/”&lt;/p&gt;
&lt;p&gt;来回找目录可能麻烦一些，不过创建一个软连接就可以了。&lt;br /&gt;
不过若真的找不到错误或者错误找到解决不了也有办法，请点这个&lt;a href=&quot;https://www.google.com&quot;&gt;万能链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;好了开个玩笑，如果您有什么解决不了问题您可以在下方留言大家可以讨论一下。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%BF%AB%E9%80%9F%E5%AE%9A%E4%BD%8D%20Apache%20%E9%94%99%E8%AF%AF&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-04-15-apache-error&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>_initialize() 和 __construct() 的区别</title><link>https://blog.lhasa.icu/posts/technology/2019-04-08-initialize-construct</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-04-08-initialize-construct</guid><pubDate>Mon, 08 Apr 2019 02:28:00 GMT</pubDate><content:encoded>&lt;p&gt;今天项目经理让我做个一个功能页面，在查阅往常相同项目源码时遇到一个没有见过的函数 &lt;code&gt;_initialize()&lt;/code&gt;Google一下知道了它是Thinkphp内置函数，查阅了一番资料写了几遍总结一下。&lt;/p&gt;
&lt;p&gt;_initialize()函数是在任何函数之前，都要执行的，当然也包括__construct()也就是构造函数。也就是说如果_initialize()函数存在，调用对象的任何方法都会导致_initialize()函数的自动调用，而_construct()函数仅仅在创建一次，跟其它方法调用没有关系。&lt;/p&gt;
&lt;p&gt;__construct()函数它是&lt;strong&gt;双下划线&lt;/strong&gt;，而_initialize()函数是&lt;strong&gt;单下划线&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果父子类均有_initialize()函数，则子类覆盖父类，如果子类没有而父类有，则子类继承父类。&lt;/p&gt;
&lt;p&gt;默认情况下，子类的构造函数不会自动调用父类的构造函数。在调用子类对象的_initialize()函数时，也不会导致自动调用父类的_initialize()函数。
实际编写子类的构造函数时，一般都要加上父类构造函数的主动调用parent::__construct()，否则会导致子类对象空指针的异常，
如&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;`Call to a menmber function assign() on anon-obiect`。
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=_initialize()%20%E5%92%8C%20__construct()%20%E7%9A%84%E5%8C%BA%E5%88%AB&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-04-08-initialize-construct&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Jekyll 环境搭建 (Windows 10)</title><link>https://blog.lhasa.icu/posts/technology/2019-03-29-jekyll-installation</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-03-29-jekyll-installation</guid><pubDate>Fri, 29 Mar 2019 01:27:00 GMT</pubDate><content:encoded>&lt;p&gt;最近想把想博客改版需要在本地用到Jekyll，不过搭建的过程真的心累...过程中真的是各种问题谷歌百度各种乱七八糟的文章一点都不靠谱，折腾一天给重要给搭建成功了...&lt;br /&gt;
整个搭建过程需要用到的软件/安装依赖我先列下&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Rubyinstaller-2.3.3-x64&lt;/li&gt;
&lt;li&gt;DevKit-mingw64-64-4.7.2&lt;/li&gt;
&lt;li&gt;Gem&lt;/li&gt;
&lt;li&gt;Bundler&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;安装Ruby&lt;/h2&gt;
&lt;p&gt;因为Jekyll是基于ruby开发的，首先下载安装ruby，我不推荐下载Ruby2.3以上的版本，不知道怎么回事2.4、2.5、2.6我都试过感觉他们跟自带BUG似的，总是出现一堆莫名其妙的问题。&lt;br /&gt;
ruby官网下载地址（下载速度奇慢）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;官网链接：https://rubyinstaller.org/downloads&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我用的ruby 2.3.3这里给大家发出来微云的链接&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微云链接：https://share.weiyun.com/5vv4fjt&lt;/li&gt;
&lt;li&gt;微云密码：achuan&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再次声明一下，这里我用的是ruby 2.3.3，其他版本我并不保证。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;双击ruby应用程序，进行安装&lt;br /&gt;
注意：默认如果有已勾选项，它会自动帮你配置环境变量，但是环境变量如果不立即生效可以用cmd命令刷新环境变量，如果还不行就重启。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; echo %PATH%
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;安装完成后测试一下是否安装成功，若输出版本信息即安装成功。&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; ruby -v
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;更换源&lt;/h2&gt;
&lt;p&gt;通过gem sources查看当前源&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; gem sources -l
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;删除源默认源，我这个里默认有一个源，官方源，因为它太慢了，我们删掉它&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; gem sources -r https://rubygems.org/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以前还有淘宝源可以用，不过现在也就已经凉了，下面是我们要替换成国内RubyGems镜像站点&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; gem sources -a https://gems.ruby-china.com
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;DevKit的安装与配置&lt;/h2&gt;
&lt;p&gt;这里我用的是DevKit 64-4.7.2，这里依然提供微云存储&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;微云链接：https://share.weiyun.com/5sROg49&lt;/li&gt;
&lt;li&gt;微云密码：achuan&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;双击DevKit应用程序，运行它解压到你想要的位置，尽量url短一点因为等会要用到比如；C:DevKit&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;初始化与配置&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; # 进入DevKit目录并执行命令，初始化生成 config.yml
&amp;gt; ruby dk.rb init

进入DevKit目录并编辑config.yml

# 用cmd命令记事本来编辑config.yml
&amp;gt; notepad config.yml

      # Example:
      #
      # ---
      # - C:/ruby19trunk
      # - C:/ruby192dev
      #
      ---
      - H:/environment/Ruby23-x64


注意：“- H:/environment/Ruby23-x64”，其中的“-”也是符号！配置config.yml这一步非常重要，还请您仔细检查！
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;安装&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;# 安装
&amp;gt; ruby dk.rb install
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Bundler的安装&lt;/h2&gt;
&lt;p&gt;Bundler是管理Gem一个依赖工具
注意：minima是我在创建Jekyll项目的时候出现的问题，当我使用 jekyll new achuan.io 创建Jjekyll项目时，命令卡死了，随后Ctrl + C 强行停止后 cd achuan.io 使用 bundler show 查看缺少依赖文件&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Could not find gem &apos;minima (~&amp;gt; 2.0) x64-mingw32&apos; in any of the gem sources
listed in your Gemfile.

# 它说我在gem源中找不到 “minima”, 然后我就安装了，不过装好后又出现这样的tzinfo-data和wdm...提前列出以防大家走弯路。

&amp;gt; gem install bundler

# gem 依赖文件
&amp;gt; gem install minima
&amp;gt; gem install tzinfo-data
&amp;gt; gem install wdm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;下面是gem依赖列表&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;addressable (2.6.0)&lt;/li&gt;
&lt;li&gt;bundler (2.0.1)&lt;/li&gt;
&lt;li&gt;colorator (1.1.0)&lt;/li&gt;
&lt;li&gt;concurrent-ruby (1.1.5)&lt;/li&gt;
&lt;li&gt;em-websocket (0.5.1)&lt;/li&gt;
&lt;li&gt;eventmachine (1.2.7)&lt;/li&gt;
&lt;li&gt;ffi (1.10.0)&lt;/li&gt;
&lt;li&gt;forwardable-extended (2.6.0)&lt;/li&gt;
&lt;li&gt;http_parser.rb (0.6.0)&lt;/li&gt;
&lt;li&gt;i18n (0.9.5)&lt;/li&gt;
&lt;li&gt;jekyll (3.8.5)&lt;/li&gt;
&lt;li&gt;jekyll-feed (0.12.1)&lt;/li&gt;
&lt;li&gt;jekyll-sass-converter (1.5.2)&lt;/li&gt;
&lt;li&gt;jekyll-seo-tag (2.6.0)&lt;/li&gt;
&lt;li&gt;jekyll-watch (2.2.1)&lt;/li&gt;
&lt;li&gt;kramdown (1.17.0)&lt;/li&gt;
&lt;li&gt;liquid (4.0.3)&lt;/li&gt;
&lt;li&gt;listen (3.1.5)&lt;/li&gt;
&lt;li&gt;mercenary (0.3.6)&lt;/li&gt;
&lt;li&gt;minima (2.5.0)&lt;/li&gt;
&lt;li&gt;pathutil (0.16.2)&lt;/li&gt;
&lt;li&gt;public_suffix (3.0.3)&lt;/li&gt;
&lt;li&gt;rb-fsevent (0.10.3)&lt;/li&gt;
&lt;li&gt;rb-inotify (0.10.0)&lt;/li&gt;
&lt;li&gt;rouge (3.3.0)&lt;/li&gt;
&lt;li&gt;ruby_dep (1.5.0)&lt;/li&gt;
&lt;li&gt;safe_yaml (1.0.5)&lt;/li&gt;
&lt;li&gt;sass (3.7.4)&lt;/li&gt;
&lt;li&gt;sass-listen (4.0.0)&lt;/li&gt;
&lt;li&gt;tzinfo (2.0.0)&lt;/li&gt;
&lt;li&gt;tzinfo-data (1.2019.1)&lt;/li&gt;
&lt;li&gt;wdm (0.1.1)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;安装Jekyll&lt;/h2&gt;
&lt;p&gt;通过gem install安装jekyll&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;gt; gem install jekyll

# 分页
&amp;gt; gem install jekyll-paginate

# 查看版本号。出现就ok
&amp;gt; jekyll -v
jekyll 3.8.6
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;启动Jekyll&lt;/h2&gt;
&lt;p&gt;写到这里真的不容易，以前在Linux搭建Jekyll没有这么心累，今windows搭建真的...几十个bug疯狂涌出...算了...留着幸福的泪，码着命令...&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 生成一个Jekyll模板并进入它
&amp;gt; jekyll new achuan.io &amp;amp;&amp;amp; achuan.io

# 启动Jeykll，默认端口4000
&amp;gt; jekyll serve

# 成功后显示如下
H:\git\achuanya.github.io&amp;gt;jekyll serve
Configuration file: H:/git/achuanya.github.io/_config.yml
            Source: H:/git/achuanya.github.io
       Destination: H:/git/achuanya.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 1.196 seconds.
  Please add the following to your Gemfile to avoid polling for changes:
    gem &apos;wdm&apos;, &apos;&amp;gt;= 0.1.0&apos; if Gem.win_platform?
 Auto-regeneration: enabled for &apos;H:/git/achuanya.github.io&apos;
    Server address: https://127.0.0.1:4001/
  Server running... press ctrl-c to stop.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开浏览器输入：&lt;code&gt;127.0.0.1:4000&lt;/code&gt;&amp;lt;br&amp;gt;
本地ip：&lt;code&gt;127.0.0.1&lt;/code&gt;，端口：&lt;code&gt;4000&lt;/code&gt;。感觉IP+端口麻烦的话，去VirtualHost配置。&amp;lt;br&amp;gt;
如果不太熟悉VirtualHost配置，可以看我以前的文章：&lt;a href=&quot;https://lhasa.icu/2018-11-08-Ubuntu-Deployment.html&quot;&gt;Ubuntu Server部署日记&lt;/a&gt;。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Jekyll%20%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%20(Windows%2010)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-03-29-jekyll-installation&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>今日随笔</title><link>https://blog.lhasa.icu/posts/life/2019-03-26-thoughts</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2019-03-26-thoughts</guid><pubDate>Tue, 26 Mar 2019 02:17:00 GMT</pubDate><content:encoded>&lt;p&gt;到今天为止我已经工作了第十六天，我热爱我的工作也非常喜欢我司的文化与业务，公司也非常人性化&lt;/p&gt;
&lt;p&gt;我们开发部老总人高马大平易近人，同事们很幽默经常说说笑笑，别的部门不知道怎么样，但是我们开发部氛围很棒&lt;/p&gt;
&lt;p&gt;完全没有入职前感觉的紧张与压抑。美中不足的是小区楼下早餐店比较少，但是小区周围的绿化却很棒&lt;/p&gt;
&lt;p&gt;出门左右拐都有一条小路，小路两旁种植了很多我认不出的花草和树木，三月的初春，小路两旁的花草和树木都长得格外养眼&lt;/p&gt;
&lt;p&gt;它们挨挨挤挤，散发着清香。出了小区向左拐这个小路直通我公司，每次上下班我都喜欢从那里骑共享单车回家，耳机播着她喜欢的歌曲，&lt;/p&gt;
&lt;p&gt;欣赏着小路两旁的花草和树木，时不时吹来一阵微风把花草散发出清香吹入我的鼻子里，这味道能使我每一天都开心......日子过的可能太安逸了&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%BB%8A%E6%97%A5%E9%9A%8F%E7%AC%94&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2019-03-26-thoughts&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>第一次校招复试总结</title><link>https://blog.lhasa.icu/posts/technology/2019-03-04-summarize</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-03-04-summarize</guid><pubDate>Mon, 04 Mar 2019 02:28:00 GMT</pubDate><content:encoded>&lt;p&gt;上个月28号的时候校招拿到了一家公司offer，今天十号了也到了约定的时间，我早上8点30左右出发点去应聘，那会儿在公交车上晕车感觉真是生不如死...&lt;/p&gt;
&lt;p&gt;大概是9点到了目的地。进入他们公司后，环境跟自己想的差距有这么一点，我看他们应该都在忙着工作，不知道是是不是因为这个让我感觉气氛有些压抑。&lt;/p&gt;
&lt;p&gt;不过他们的技术主管给我印象还是很不错的，挺阳光的，我和他在对话的时候他也微笑的对我说，我很喜欢这人的人。&lt;/p&gt;
&lt;p&gt;这次复试大概的流程去了后填一下个人信息表，然后同把简历给了一个姐姐，提交了资料后大概十几分钟吧，我被第一个叫过去了。&lt;/p&gt;
&lt;p&gt;我这人内向第一次复试三个面试官盯着我一个我，看似我坐那抱着书包不慌，其实内心已经波涛澎湃...刚开始做个自我介绍，然后技术主管问了一些我是如何学习的，&lt;/p&gt;
&lt;p&gt;我举例说了一些Github，开源中国等等社区论坛...然后问了我项目制作的一个流程，还有MySQL的优化，MVC框架运作的原理等等...&lt;/p&gt;
&lt;p&gt;比较难受的两点是那个高并发之类的技术，因为我没有接触过这些前沿技术直接回答不懂，不过有一点真是扯淡...当时我非常紧张...他问我PHP数据类型有哪些，我直接懵逼了...&lt;/p&gt;
&lt;p&gt;差不多也就上述那些事，问完后就让我出去坐等一会儿，陆续了半个小时左右，我的朋友也都回来等最重结果。后来就是那样我们几个过了，&lt;/p&gt;
&lt;p&gt;谈论了一下公司的文化、项目与期望薪资，谈妥了经理说让我们回去等候电话，慎重考虑一下。&lt;/p&gt;
&lt;p&gt;基本是说完了，过程就是那么个过程，想想这次面试中犯的错真是幼稚，太紧张把PHP数据类型给忘了...自己面向对象这块抽象类和接口知识不太牢固，&lt;/p&gt;
&lt;p&gt;还是写的少。还有就是ThinkPHP的开发和CentOS部署，我没有玩过CentOS晚会儿装一下玩玩，正好再来一篇关于CentOS的博客。就到这里吧，第一次校招复试总结也就那么多内容。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%A0%A1%E6%8B%9B%E5%A4%8D%E8%AF%95%E6%80%BB%E7%BB%93&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-03-04-summarize&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>ThinkPHP 笔记(路由实现与操作方法)</title><link>https://blog.lhasa.icu/posts/technology/2019-02-28-tp5</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-02-28-tp5</guid><pubDate>Thu, 28 Feb 2019 08:25:00 GMT</pubDate><content:encoded>&lt;p&gt;前段时间一直在学习ThinkPHP，不过比较忙没有同步博客，今天发表一下。&lt;/p&gt;
&lt;h2&gt;路由文件&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;H:\tp5\thinkphp\library\think&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;生成一个控制器文件&lt;/h2&gt;
&lt;p&gt;控制器文件命名规范，大写字母开头的驼峰命名。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;php think make:controller index/Sql --plain&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;浏览器访问控制器（sql.php）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;tp5.io/index/Sql&lt;/li&gt;
&lt;li&gt;域名/模块/控制器&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ThinkPHP的控制器操作方法支持不同的响应输出，对于不同的响应输出会调用不同的Response子类 ，例如‘json’，‘xml’等，可以直接return一个数组或者对象数据，然后交给‘Response’对象。还有一种情况是，你可以统一使用系统提供的钩子输出进行额外的处理，而如果你使用了‘echo’直接输出，将无法享受这些功能特性。&lt;/p&gt;
&lt;h3&gt;更简短的url&lt;/h3&gt;
&lt;p&gt;路由定义前URL：tp5.io/index/Sql&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Route::get(&apos;sql&apos;,&apos;Sql/index&apos;);&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;路由定义后URL：tp5.io/Sql&lt;/p&gt;
&lt;h2&gt;添加操作方法&lt;/h2&gt;
&lt;p&gt;操作方法命名规范，小写字母开头的驼峰命名。&lt;br /&gt;
如果定义路由并且&lt;strong&gt;没有开启强制开路由&lt;/strong&gt;的话，那么系统会根据下面的默认规则解析URL&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;域名/&amp;lt;入口文件&amp;gt;/模块名/控制器/操作器名/参数1/值//参数2/...&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对于操作方法的必要参数，我们使用了方法的参数定义。对于方法的参数，通常包含两种类型：对象类型和普通类型。所有的参数都是来自于当前的请求，对象类型参数比较特殊一些，通常是通过依赖注入自动完成。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注意：并不是所有的URL地址中的变量都是 &lt;code&gt;$_GET&lt;/code&gt; 变量。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在ThinkPHP中URL中属于pathinfo地址，这个地址的的解析过程是由框架内部实现的，并且会自动解析成一个URL变量（但却不是GET变量，证据就是你用原生的 &lt;code&gt;$_GET[&apos;id&apos;]&lt;/code&gt; 是获取不到 &lt;code&gt;id&lt;/code&gt; 的值的），一个真正的GET变量应该是下面的请求URL。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;index/sql/read?id=123&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个时候id变量才是一个真正的 &lt;code&gt;$_GET&lt;/code&gt; 变量，因为我们可以通过原生的 &lt;code&gt;$_GET[&apos;id&apos;]&lt;/code&gt; 获取到 &lt;code&gt;id&lt;/code&gt; 值。
不过框架封装看一个 &lt;code&gt;param&lt;/code&gt; 变量，可以让你不管当前的请求类型是 &lt;code&gt;GET&lt;/code&gt; 还是 &lt;code&gt;POST&lt;/code&gt;，都能无差别的统一获取当前的请求变量。&lt;br /&gt;
所以，上面两种URL地址，我们都可以统一使用 &lt;code&gt;input(&apos;id&apos;)&lt;/code&gt;（这是一个助手函数，其实是调用 &lt;code&gt;Request&lt;/code&gt; 对象的 &lt;code&gt;param&lt;/code&gt; 方法）来获取当前请求的 &lt;code&gt;id&lt;/code&gt; 变量，当然 &lt;code&gt;$_GET&lt;/code&gt; 和 &lt;code&gt;$_POST&lt;/code&gt;
ThinkPHP定义操作名时不能用‘php’关键词，如果php版本低于5.6+，如果你担心你的应用可能存在此类问题，那么可以尝试使用方法后缀功能，代价就是你在定义方法的时候可能要多写几个字符了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;// 操作方法后缀&lt;/li&gt;
&lt;li&gt;&apos;action_suffix&apos; =&amp;gt; &apos;Action&apos;,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也是就说每个操作方法名都要加‘Action’的后缀，不过访问操作名的时候‘不需要加Action’&lt;br /&gt;
如果使用的是‘PHP7.0+’版本的话，基本不用担心这个问题，但可能会受到来自IDE自动格式化的困惑。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=ThinkPHP%20%E7%AC%94%E8%AE%B0(%E8%B7%AF%E7%94%B1%E5%AE%9E%E7%8E%B0%E4%B8%8E%E6%93%8D%E4%BD%9C%E6%96%B9%E6%B3%95)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-02-28-tp5&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>第一次校招面试总结</title><link>https://blog.lhasa.icu/posts/technology/2019-02-28-interview</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-02-28-interview</guid><pubDate>Thu, 28 Feb 2019 04:15:00 GMT</pubDate><content:encoded>&lt;p&gt;今天上午校招面试，也是我人生中对自己喜欢的工作的一次技能检验。面试提到几个问题，其中还有个关于与ajax异步请求，我记得不是太清没答上来。现在刚吃完饭就来总结一下。&lt;/p&gt;
&lt;h2&gt;Ajax的异步与同步&lt;/h2&gt;
&lt;p&gt;今天校招面试就这个没有答上来，想想前段时间刚学过，没及时复习真是不应该...&lt;/p&gt;
&lt;p&gt;ajax里面有个ES7的异步函数：async。ajax默认是异步请求，如果把async默认参数改城true，这标识着在请求开始后，其他代码依然能够执行，&lt;/p&gt;
&lt;p&gt;但是这样的话如果ajax代码不通，会导致下面的代码停止加载，会导致页面加载崩溃。&lt;/p&gt;
&lt;p&gt;举一个栗子：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;console.log(&apos;1&apos;);
$.ajax({
    url:&apos;admin/ajax_add&apos;,
    async:true,
    success:function(e)
    {
        console.log(&apos;2&apos;);
    }
});
console.log(&apos;3&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;也就是说async设置为true时，这时ajax是异步的，就算ajax出现问题，其他的代码还可以继续执行。如果当async是同步既（false）这样的话ajax请求不到数据就会停止下面的代码。&lt;/p&gt;
&lt;h2&gt;Mvc设计模式与Mvc框架的区别&lt;/h2&gt;
&lt;p&gt;这里之前先简单的说一下Mvc，它是为了代码分离而产出的一个程序模式。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;M（Model，‘模型’）专门处理应用程序数据逻辑，通常用于数据库中存取数据。&lt;/li&gt;
&lt;li&gt;V（View，‘视图’）指数据呈现后的状态，简单的说也就是用户看到的UI画面。&lt;/li&gt;
&lt;li&gt;C（Contrller，‘控制器’）它是控制视图的输出，并向模型发送数据。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我是这样理解的，Mvc设计模式是一群大佬经过长久的实践后的总结。也就是用于解决一系列问题的解决方法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mvc设计模式可以说是设计师设计的图纸，而Mvc框架则是工程师以设计师的图纸而建造的产品。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;面向对象知识点&lt;/h2&gt;
&lt;h3&gt;接口和抽象类的区别&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;抽象类&lt;/strong&gt;是一种不能被实例化的类，只能作为其他类的父类来使用。抽象类是通过关键字&lt;strong&gt;abstrat&lt;/strong&gt;来声明。&lt;br /&gt;
抽象类与普通类相似，都包含成员变量和成员方法，两者的区别在于，抽象类中至少要包含一个抽象方法，抽象方法没有方法体，该方法天生就是被子类重写的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;接口&lt;/strong&gt;是通过&lt;strong&gt;interface&lt;/strong&gt;关键词来声明的，接口中的成员常量和方法都是public，方法可以不写关键词public，接口中的方法也是没有方法体。接口中的方法也是天生就是要被子类实现的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;抽象类和接口实现的功能十分相似，最大的不同是接口能实现多继承&lt;/strong&gt;。在应用中选择抽象类还是接口要看具体实现。&lt;/p&gt;
&lt;h3&gt;__autoload()函数是如何运作的？&lt;/h3&gt;
&lt;p&gt;这个魔术函数的基本条件是类文件的文件名要和类名字保持一致，当程序执行到实例化某个类的时候，如果在实例化之前没有引入这个类文件，那么就会自动执行“__autoload()”函数。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;人生中第一次正式的技术面试，一向内向的我比较紧张，不过二次面试的机会还是拿到了，还有就是这次简历做的不是很理想，&lt;/p&gt;
&lt;p&gt;太简约了，我以为简约能让hr更好的阅读...好吧..虽然我本人不是很喜欢花里胡哨的东西，楚老师也说这是个看脸的时代...好了不写了，再写的话手机话费要超负额了....&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%AC%AC%E4%B8%80%E6%AC%A1%E6%A0%A1%E6%8B%9B%E9%9D%A2%E8%AF%95%E6%80%BB%E7%BB%93&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-02-28-interview&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>电信用户投诉攻略</title><link>https://blog.lhasa.icu/posts/life/2019-02-25-unicom</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2019-02-25-unicom</guid><pubDate>Mon, 25 Feb 2019 04:44:00 GMT</pubDate><content:encoded>&lt;p&gt;因为我手机卡是合约卡的原因，又临近毕业了，这张卡握在手里真的没得用，36元套餐1G流量，这样的套餐我来说真的是难受，只能更换套餐。以前我都是靠着校园网和移动纯流量卡，校园网出了校门就不能用了，不划算我给停了，那个打幌子的移动纯流量卡更是个坑，在此提醒不推荐大家办理这种卡。&lt;/p&gt;
&lt;p&gt;因为我这卡是合约卡，不能随意转套餐，然后我就拨打10010转人工客服说需求说转腾讯大王卡套餐，不过客服百般阻挠说这个不好那个不好，不过我态度比较强硬，之后在24号晚上8：25我收到了工单。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;unicom1.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;25号早上11点，我老家周口淮阳县城联通分公司给我打电话说，刚开始通话她说合约卡期间不能更换套餐又说让我准备证件回老家办理业务；我的天，这都9012年了，换个套餐还回老家，&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;unicom2.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;歹说好说最后她加我微信我把证件资料给了她，委托她帮我办理。差不多10分钟左右，她给我打电话说合约卡内不能更换套餐唯理由让我重新办卡...此时想到了一句话“老用户与狗不得办理”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;unicom3.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;客服解决不了事情也不是几次了，直接拔打联通总部电话，这里我搜集了三大运营商总部投诉电话&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;中国联通：010-10015（注意必须要加 010 北京区号）&lt;/li&gt;
&lt;li&gt;中国移动：4001110086&lt;/li&gt;
&lt;li&gt;中国电信：4008810000&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;果不其然，还是联通总部电话好使，拨打电话后直接人工服务诉说你的事情。差不多5分钟左右，联通总部那边说12小时内会有处理人员主动联系我。然而在下午4：25，那个劝我办理新卡的姐姐给我打电话声音很温柔的说她又试了一下办理好了说下月套餐生效...与上午完全不是一个人。&lt;br /&gt;
下面真香警告！&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;unicom4.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;unicom5.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;后来我查了一下，其实早在 2006 年，工信部就出了文件，即〔2006〕630号文件，其中明确规定“在同一移动电话归属地内（俗称“移动电话本地网”），移动通信企业应保证本企业同一网络的原有用户，可以在不改变号码的情况下，自主选择使用本企业的所有资费方案（已停止发展用户的除外）”，这意味着运营商对于目前老用户的限制是违规的。&lt;/p&gt;
&lt;p&gt;在2008年又出台了指导意见，用户对资费方案享有自主选择权，电信企业应给予充分尊重，不得限制用户选择其指定的资费方案，未经用户同意，不得擅自更改与用户约定的资费方案。&lt;/p&gt;
&lt;p&gt;如果总部投诉都不好使大家可以直接去工信网投诉相应的服务商，这是最有效的解决方法（如果总部投诉不好使再去投诉），成功案例可以 Google 一下&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.chinatcc.gov.cn/cms/shensus&quot;&gt;点击进入电信用户申诉受理中心&lt;/a&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E7%94%B5%E4%BF%A1%E7%94%A8%E6%88%B7%E6%8A%95%E8%AF%89%E6%94%BB%E7%95%A5&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2019-02-25-unicom&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)微不足道的坚持</title><link>https://blog.lhasa.icu/posts/life/2019-02-23-insist</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2019-02-23-insist</guid><pubDate>Sat, 23 Feb 2019 02:44:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://github.com/lifesinger/blog/issues/198&quot;&gt;玉伯的博客&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;在你最擅长的专业领域内，可曾有过一件让你骄傲，持续坚持下来的事情？每当别人谈论它时，你总是偷偷窃喜？&lt;/p&gt;
&lt;p&gt;我曾经这样勉励我的弟兄们，在满负荷的工作压力面前，总要找到一件有意义、自己感兴趣且擅长的事情，坚持做，是一种解压，更是为了让自己的专业所长，找到有意义的落脚点。分享三件事情，大家共勉&lt;/p&gt;
&lt;h3&gt;第一件事：&lt;/h3&gt;
&lt;p&gt;两前年，流火曾经找我聊想搭建一个行业内前端社区，他有清爽的界面，有优雅的交互体验，我当时并不看好，担心接下来的工作压力会让人抗不住，两年过去了，在百度搜索f2e可以在显要位置看到这个极简的域名&quot;&lt;a href=&quot;https://f2e.im&quot;&gt;f2e.im&lt;/a&gt;&quot;。社区雏形完整，代码完全开源，我也很幸运成为F2E社区&lt;a href=&quot;https://f2e.im/u/jayli&quot;&gt;第三号成员&lt;/a&gt;。&lt;/p&gt;
&lt;p&gt;我当然听到过太多质疑的声音，诸如&quot;这东东和某东东很类似？&quot;，或者&quot;这里菜鸟太多了，没有我想要的高手？&quot;云云。&lt;/p&gt;
&lt;p&gt;Whatever!~&lt;/p&gt;
&lt;p&gt;评论终将归于浮云，留下的是两年的坚持，以及它换来的微不足道的满足感！同样，当流火在解决了成百上千个无关紧要又繁琐冗碎的bugfix时，换来了对python的精通，对代码版本迭代的专业性把握，对网络协议和内容渲染模式的深刻理解，收获了直面一线用户的宝贵经验，更重要的是，懂得坚持的意义。这些硬技能直接促成了今天流火在业务上的钻研与精通。&lt;/p&gt;
&lt;h3&gt;第二件事：&lt;/h3&gt;
&lt;p&gt;前年年底，我们团队发起了针对校招同学的&quot;魔鬼训练营&quot;，宗旨是艰苦一年，主动成长，我们无条件的侵占了大家的加班、午餐、晚餐、甚至周末时间。工作的紧张压力下，还要准备给大家反讲，质量良心保证，精力严重透支，要不是靠着年轻的身子板，扛下来简直是个奇迹。&lt;/p&gt;
&lt;p&gt;迟伤、影逸、夕剑 全程坚持了下来。&lt;/p&gt;
&lt;p&gt;当年反讲的JavaScript设计模式、熟读W3C标准、NodeJS、Git、字符编码、HTTP协议这些基础知识，让充电加速。现在当面对业务压力和未知bug时，他们显然更勇于去透过表面看本质。并在 WebRocket（@影逸）、机票YUI体系的KISSY化（@迟伤）等项目中淋漓紧致的体现出自身专业水平。毕业一年，无压力的开始挑大梁了。&lt;/p&gt;
&lt;p&gt;回想起来，魔鬼训练营中辛苦的坚持，是如此微不足道。&lt;/p&gt;
&lt;h3&gt;第三件事：&lt;/h3&gt;
&lt;p&gt;两年前，我作为PM落地了一件看似不可能完成的任务，&lt;a href=&quot;https://ued.taobao.com/javascript&quot;&gt;JavaScript权威指南（第六版）&lt;/a&gt;的翻译。认领这个任务的初衷仅仅是想挑战下自己的能力极限，看清楚自己几斤几两，没想到一做就是一年。&lt;/p&gt;
&lt;p&gt;这段时间在工作和业余时间谨慎的保持平衡，压力面前各种放弃的冲动仍历历在目，但仍抵不过这本书上市之时的那股满足感。&lt;/p&gt;
&lt;p&gt;过程中听到太多质疑的声音，WhatEver，你所掌握关于JavaScript的一切，始终是我的子集。纯技能上的收获更是大大的丰厚。&lt;/p&gt;
&lt;h3&gt;结语&lt;/h3&gt;
&lt;p&gt;任何一件事情，有多大投入，就有多大收获。当你还是局内人时，不清楚傻傻的坚持的意义，这时内心的纠结最容易让人动摇和放弃。但事成之日，才会真正拨云见月，一树百获。这时，压力是浮云，纠结是浮云，抱怨是浮云，斤斤计较更是浮云。“坚持到胜利”，是如此言轻，又是如此言重。&lt;/p&gt;
&lt;p&gt;在你最擅长的领域内，可曾有过让你骄傲，持续坚持下来的事情？每当别人谈论它时，你总是偷偷窃喜？那么。。。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E5%BE%AE%E4%B8%8D%E8%B6%B3%E9%81%93%E7%9A%84%E5%9D%9A%E6%8C%81&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2019-02-23-insist&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Redis 笔记(安装与数据类型)</title><link>https://blog.lhasa.icu/posts/technology/2019-02-22-redis</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-02-22-redis</guid><pubDate>Fri, 22 Feb 2019 05:44:00 GMT</pubDate><content:encoded>&lt;h2&gt;Redis的安装&lt;/h2&gt;
&lt;p&gt;我用的系统是Ubuntu 16.04.1 LTS, 关于windows的安装就不说了&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 更新源
$ sudo apt-get update
# 安装
$ sudo apt-get install redis-server

# 启动
$ redis-server

# 启动之后再打开一个终端,连接redis服务
$ redis-cli

# 127.0.0.1是客户端ip, 6379是服务端口
# 我们发送一个 ping,如果返回PONG表示服务器正常
127.0.0.1:6379&amp;gt; ping
PONG
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Redis的数据类型&lt;/h2&gt;
&lt;p&gt;Redis支持五种数据类型：String（字符串），Hash（哈希），List（列表），Set（集合）及Zset(Sorted Set：有序集合)&lt;br /&gt;
关于这五中数据类型的操作，因为很多我都用不到，所以不是很内容不是很全面还请见谅，下面我们从字符串开始一一说&lt;/p&gt;
&lt;h3&gt;String（字符串）&lt;/h3&gt;
&lt;p&gt;这个String(字符串)是Redis五中数据类型中最基本的数据类型，也是最简单的一个，它是二进制安全的，它可以包含任何数据，&lt;/p&gt;
&lt;p&gt;如jpg、序列化的数据......不过它的容量也是有限度的，String的Value值最大可以存储512MB&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Redis的set是string类型的无需集合
集合通过哈希表表现的， 所以添加、删除、查找复杂度都是0（1）

# 添加一个string元素到key对应的set集合中，
SET key value

# 输出一个set集合
GET key

# 自增+1
INCY key

# 自减-1
DECY key

# 自定义自增+5
INCYBY key 5

# 自定义自减-5
DECYBY key 5

# 批量增加 set 
MSET key value [key value]...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;List（列表）&lt;/h3&gt;
&lt;p&gt; List它是链表而不是数组，这意味着list的插入和删除操作会非常的话，时间复杂度为0（1）但是索引定位很慢，时间复杂度为0（n）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 向列表的左边插入
LPUSH books value

# 输出 lpush（value）
LPOP key

# 向列表的右边插入
RPUSH key key key

# 输出 rpush（value）
RPOP key

# 输出 rpush（value）值的数量（不是具体值）
LLEN key

# 输出列表内容(status/stop 可以理解为 0 -1索引)
LRANGE key status/stop

# 清除列表内容
LTRIM key status/stop
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Hash（哈希）&lt;/h3&gt;
&lt;p&gt;Hash是一个string类型的fieid和value的映射表，Hash特别适合存储对象，Hash结构用户信息，不同于字符串一次性需要全部序列化整个对象，Hash可以对用户结构中的每个字段单独存储。&lt;/p&gt;
&lt;p&gt;这样我们需要获取用户信息时，可以进行部分获取。如果以字符串形势保存用户信息的话，就只能一次性全部读取这样就会失效浪费流量。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 创建一个 Haet值
HAST key fieid value

# 获取一个 Hest
HGET key fieid

# 更改 Hast值（也就是在创建的基础上重新赋值）
HAST key fieid value

# 批量添加
HMSET drinks milk &apos;value&apos; tea &apos;value&apos;

# 输出 Hast
HGETALL drinks

# 自增+5
HINCRBY drinks amount 5

# 自减-5
HINCRBY drinks amount -5

# 删除多个 Hash字段
HDEL drinks [fieid] [fieid]
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Set（集合）&lt;/h3&gt;
&lt;p&gt; Set它的内部的键值对无序的唯一的，它的内部实现相当于一个特殊的字典，字典中所有的value都是一个值Null。&lt;br /&gt;
 Set结构可以用来存储活动中奖的用户ID，因为有去除功能，可以保证同一个用户不会中两次！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 添加两个集合
SADD key meber meber

# 输出一个集合
SMEMBERS key

# 查询集合中，如果存在返回 1，否则返回 0
SISMEMBER key meber

# 在key集合中删除指定的元素或多个元素
SREM key meber

# 返回一个集合与给定集合的差集元素
SDIFF key key

# 移除集合中的指定 key 的一个或多个随机元素，并返回移除的元素
SPOP kecy count

# 交集，返回给定所有定集合的交集
SINTER key key

# 并集，返回一个集合的全部成员，该集合是所有给定集合的并集
SUNION key key
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Sorted Set（有序集合）（重点！）&lt;/h3&gt;
&lt;p&gt;Zset保证了内部的唯一性，另一方面它可以给每个value赋予一个score，代表value的排序权重。&lt;/p&gt;
&lt;p&gt;Zset可以用来存粉丝列表，value值是粉丝的用户ID，score是关注事件，我们可以对粉丝列表按照关注时间进行排序。&lt;/p&gt;
&lt;p&gt;Zset也可以用来存储学生成绩，value是学生ID，score是学生考试成绩，我们可以对成绩按分数进行排序就可以得到它们的名字。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 添加一个有序集合，30是数量，person是人数(添加也可以用于修改)
ZADD key 30 person

# 查看有序集合成员数量
ZCARD items

# 查看有序集合成员值（0 和 1 是索引）
ZRANGE key 0 1

# 查看有序集合成员值和名字，默认从小到大排序显示
ZRANGE key 0 -1 withscores

# 查看有序集合，成员值和名字，从大到小排序
ZREVRANGE key 0 -1 withsores

# 查看 member的值
ZSCORE key member

# 查看最小值和最大值之间的 member值
ZRANGEBYSCORE key min max

# 查看负无穷 - 2000之间的 member值
ZRANGEBYSOORE key -inf 2000

# 查看正无穷 - 2000之间的 member值
ZEANGEBYSOORE key inf 2000

# 批量删除有序集合
ZREM key member member
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Redis通用操作&lt;/h2&gt;
&lt;h3&gt;过期时间&lt;/h3&gt;
&lt;p&gt;Redis所有的数据结构都可以设置过期时间，时间到了，Redis会自动删除相应的对象。需要注意的是过期是以对象为单位，比如一个Hash结构的过期，而不是其中的某个key。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 设置 5 秒后数据过期，成功返回 1，否则 0
#（不会删除 key，只会删除 vlaue值）
EXPIRE key 5

# 查看过期时间
TTL key

# 失效过期时间
SETEX key secods value
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;事务&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 事务，当事务开启时，所有的命令都会延迟执行
MULTI

# 执行所有延迟命令
EXEC
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;回滚&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 回滚，回滚上一个操作前的状态（事务期间不支持回滚）
DISCARD
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这些都是这段时间记的笔记，全打出来了好累...不过辛苦的劳动得到了心理上的满足，很舒服，这五个Redis有序集合中我觉得 Sorted Set（有序集合）比较重要，&lt;/p&gt;
&lt;p&gt;需要多加练习，而Set（集合）是我的弱项也是需要多加练习。&lt;/p&gt;
&lt;p&gt;年后一直没发过什么博客，一直在忙着练习面向对象的项目，同时也在学习封装自己的MVC框架！本篇文章就到这里吧！Bai！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Redis%20%E7%AC%94%E8%AE%B0(%E5%AE%89%E8%A3%85%E4%B8%8E%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-02-22-redis&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Cmd 笔记</title><link>https://blog.lhasa.icu/posts/technology/2019-02-12-cmd</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2019-02-12-cmd</guid><pubDate>Tue, 12 Feb 2019 04:44:00 GMT</pubDate><content:encoded>&lt;p&gt;最近从 linux 换到 windows 真是一言难尽下次发表磁盘阵列的时候再说这个事吧...&lt;br /&gt;
转到windows后安装mysql,又想起linux的终端了,但是windows没这玩意,cmd凑合一下吧,再温习一下cmd的一些命令...&lt;/p&gt;
&lt;h2&gt;查看&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 查看本地ip
ipconfig
# 检查Windows版本
winver
# 查看默认用户
net user
# 查看用户组
net localgroup
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;复粘删拷&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 复制文件
copy
# 移动文件
move
# 删除文件
del
# 拷贝文件
xcopy
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;创建文件与属性权限&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 创建文件
copy
# 创建共享文件夹
shrpubw

# 属性权限
attrib
    +r # 只读
    +h # 隐藏
    +a # 存档
    +s # 系统
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;重关注销&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;shutdown
    # 关机
    -s
    # 取消事件
    -a
    # 重启
    -r
    # 注销当前用户
    -i
    # [20] 定时设置默认值是20秒
    -t
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;网络安全&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 显示网络连接\路由表和网络接口信息
netstat - 
    netstat [选项]
        # 显示所有socket,包括正在的监听的
        -a
        # 每个一秒就重新显示一遍,直到用户中断它
        -c
        # 显示每个协议统计信息
        -s
        # 显示以太网统计信息,此选项可以与 -s 结合
        -e
        # 显示当前连接卸载状态
        -t
        # 显示 NetworkDirect 连接、侦听器和共享
        -x
        # 显示所有连接的TCP连接模板
        -y
        # 显示正在进行的工作
        -v

# 查看80端口占用情况
netstat -aon|findstr &apos;80&apos;
    TCP  0.0.0.0:80  0.0.0.0:0  LISTENING  6436
# 查找PID对应的进程
tasklist|findstr &apos;6436&apos;
    httpd.exe  6436 Services  0  12,040 K
# 结束名为 httpd.exe 的进程
taskkill /f /t im httpd.exe  

# 打开控制台
mmc
# DNS测试
ping []
# 注册表
regedit.exe
# 事件查看器
eventvwr
# 查看本地ip
ipconfig
# 任务管理器
taskmgr
# 系统组件服务
dcomcnfg
# 系统配置
msconfig.exe
# 设备管理器
devmgmt.msc
# 计算机管理
compmgmt.msc
# 本地服务设置
services.msc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;系统维护&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 检查DirectX信息
dxdiag
# 垃圾整理
cleanmgr
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;功能&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 清除屏幕
cls
# 放大镜
magnify
# 启动计算器
calc
# 控制面板
control
# 鼠标属性
main.cpl
# 打开记事本
notepad
# 游戏控制器
joy.cpl
# 屏幕分辨率
desk.cpl
# 程序和功能
appwiz.cpl
# 打开资源管理器
explorer
# 共享文件夹管理器
fsmgmt.msc
# 木马捆绑工具，系统自带
iexpress
# 配置显示器和打印机中的色彩
colorcpl
# 远程桌面连接
mstsc
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2019-06-03 更新&lt;/h2&gt;
&lt;h3&gt;tskill&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;## 重启资源管理器
tskill explorer
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Cmd%20%E7%AC%94%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2019-02-12-cmd&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>2018 小总结</title><link>https://blog.lhasa.icu/posts/life/2018-12-31-summaryof</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2018-12-31-summaryof</guid><pubDate>Mon, 31 Dec 2018 03:44:00 GMT</pubDate><content:encoded>&lt;p&gt;岁月不居,时节如流。现在距离2019年还有5分钟,想一想年后...我的求学生涯也该结束了...挺难受的,不过收获还是一箩筐的!那些不该经历和不可能经历的事情都让我走了一遭...&lt;/p&gt;
&lt;h2&gt;关于生活方面&lt;/h2&gt;
&lt;p&gt;我比以前更耐草了,适应力极强,耳麦脑袋挂,手掌键盘放,能折腾两宿...不过让我比较高兴的是近一年我把常期的网瘾给戒掉了,这玩意真是让我投入了太多精力,现在想一想当初的我简直就是在犯罪！不过偶尔放松心情,缓解压力还是不错的。不过今年我失眠比较难受,希望明年让我睡的早一些...&lt;/p&gt;
&lt;h2&gt;关于实践学习&lt;/h2&gt;
&lt;p&gt;今年最让我扯淡的就是做一个Linux硬盘分区方案,明明很简单操作,我给大意了,后果导致我进几年来做的所有东西几乎都没了……编程方面学习的压力也挺大,可能是我脑子不太转圈...还有就是各种兼职,这个东西其实挺有意思的,时不时的周末兼职也让我学会很多东西。让我一个小白活生生的被迫成了老油条……&lt;/p&gt;
&lt;h2&gt;关于职业规划&lt;/h2&gt;
&lt;p&gt;早就已经确定方向,回想小时候想把爱好当成工作,别提多开心,现在想一想我抬手就是给自己一巴掌,不！你不想！&lt;/p&gt;
&lt;p&gt;好了,今天的熬夜点到为止, 2019 新的一年,祝大家乘风破浪！晚安。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;bainian.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=2018%20%E5%B0%8F%E6%80%BB%E7%BB%93&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2018-12-31-summaryof&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>解决ubuntu：E：无法获得锁(11：资源暂时不可用)</title><link>https://blog.lhasa.icu/posts/technology/2018-10-25-ubuntu-lock</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-10-25-ubuntu-lock</guid><pubDate>Thu, 25 Oct 2018 08:44:00 GMT</pubDate><content:encoded>&lt;p&gt;最近学习用到了&lt;a href=&quot;https://php.net&quot;&gt;php手册&lt;/a&gt;，平常我都是在网页查看，图个方便于是就下载了&lt;a href=&quot;https://github.com/gyunaev/kchmviewer&quot;&gt;KchmViewer&lt;/a&gt;（开源的CHM 阅读器）不过效果不太理想，今天想卸载了它，结果出段小插曲......&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;ubuntu-lock1.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;what the?&lt;br /&gt;
好吧，遇到问题解决问题&lt;/p&gt;
&lt;p&gt;刚开始我是以为软件没有完全关闭就打开了终端......&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 打开终端列出进程，找含有 apt-get 进程，然后　sudo kill PID
$ ps aux 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我以为ojbk　？不过这并没有什么用（啪）......&lt;/p&gt;
&lt;p&gt;这有什么难的？so easy　解决方式如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 首先强制解锁
$ sudo rm /var/cache/apt/archives/lock
# 然后找到错误信息里“无法获得锁的地址”并 rm
$ sudo rm /var/lib/dpkg/lock-frontend
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;卸载 KchmViewer 并确认卸载（Y）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ apt-get remove kchmviewer 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;ubuntu-lock2.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;dpkg 查一下 kchmviewer 是否存在&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ dpkg -s kchmviewer
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;ubuntu-lock3.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%A7%A3%E5%86%B3ubuntu%EF%BC%9AE%EF%BC%9A%E6%97%A0%E6%B3%95%E8%8E%B7%E5%BE%97%E9%94%81(11%EF%BC%9A%E8%B5%84%E6%BA%90%E6%9A%82%E6%97%B6%E4%B8%8D%E5%8F%AF%E7%94%A8)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-10-25-ubuntu-lock&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>开源分布式管理控制系统 —— Git 笔记</title><link>https://blog.lhasa.icu/posts/technology/2018-10-25-git</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-10-25-git</guid><pubDate>Thu, 25 Oct 2018 00:31:00 GMT</pubDate><content:encoded>&lt;h2&gt;Git的诞生&lt;/h2&gt;
&lt;p&gt;故事是自2002年开始，&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E6%9E%97%E7%BA%B3%E6%96%AF%C2%B7%E6%89%98%E7%93%A6%E5%85%B9&quot;&gt;林纳斯·托瓦兹&lt;/a&gt;决定使用&lt;a href=&quot;https://zh.wikipedia.org/wiki/BitKeeper&quot;&gt;BitKeeper&lt;/a&gt;作为&lt;a href=&quot;https://zh.wikipedia.org/wiki/Linux%E5%86%85%E6%A0%B8&quot;&gt;Linux内核&lt;/a&gt;版本控制系统，用于维护代码。你想想BitKeeper是&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E4%B8%93%E6%9C%89%E8%BD%AF%E4%BB%B6&quot;&gt;专有软件&lt;/a&gt;，&lt;/p&gt;
&lt;p&gt;人家靠这玩意挣钱，这个决定社群中长期遭受质疑。不过还是有人主张使用开源软件。我dalao（林纳斯·托瓦兹）何尝没有想过（如&lt;a href=&quot;https://zh.wikipedia.org/wiki/Monotone&quot;&gt;Monotone&lt;/a&gt;），&lt;/p&gt;
&lt;p&gt;但是这些软件都存在一些问题，特别是性能不佳。现成的方案，如&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%8D%94%E4%BD%9C%E7%89%88%E6%9C%AC%E7%B3%BB%E7%B5%B1&quot;&gt;CVS&lt;/a&gt;的架构，不过dalao并不喜欢连同痛批了一顿。&lt;/p&gt;
&lt;p&gt;2005年的时候有个叫&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%AE%89%E5%BE%B7%E9%AD%AF%C2%B7%E5%9E%82%E9%B3%A9&quot;&gt;安德鲁·垂鸠&lt;/a&gt;破解了BitKeeper（这么做的不止他一个），BitMover公司决定收回Linux社区的免费使用权。事后双方公司进行过磋商，&lt;/p&gt;
&lt;p&gt;结果可想而知。事后dalao以十天的时间，用C撸出来一个分布式版本控制系统，它就是Git的第一个版本！于2005年以&lt;a href=&quot;https://zh.wikipedia.org/wiki/GNU%E9%80%9A%E7%94%A8%E5%85%AC%E5%85%B1%E8%AE%B8%E5%8F%AF%E8%AF%81&quot;&gt;GPL&lt;/a&gt;发布。至于这个名字嘛，&lt;/p&gt;
&lt;p&gt;dalao自嘲地取了这个名字“&lt;strong&gt;Git&lt;/strong&gt;”，该词源自英国俚语，意思大约是“混账”。不过Git刚面世的时候，世界上开源社群反对声音不少，&lt;/p&gt;
&lt;p&gt;最大的理由是Git太艰涩难懂？（博主：一个程序员难道不该有钻研精神吗？）&lt;/p&gt;
&lt;p&gt;2016年IT界报道，Git统治编程社区11年后，BitKeeper宣布开源。挑战Linux内核开发者？dalao反手一掏Git灭掉BitMover。（这段让我看的热血沸腾，抽颗烟压压惊）&lt;/p&gt;
&lt;p&gt;在学习之前我门先学习一下四个专业术语&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;flow%20chart.jpg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Workspace&lt;/strong&gt;：工作区&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;lndex/Stage&lt;/strong&gt;：暂存区（又名索引）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Repository&lt;/strong&gt;：仓库区（又名本地仓库、储存库）&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remote&lt;/strong&gt;：远程仓库&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;开源分布式管理控制系统——Git笔记
开源分布式管理控制系统——Git笔记是工作区。&lt;br /&gt;
开源分布式管理控制系统——Git笔记态。&lt;br /&gt;
开源分布式管理控制系统——Git笔记库）。&lt;/p&gt;
&lt;p&gt;远程仓库：这个很简单但我却不知道怎么表达...可以说成云端仓库吧。&lt;/p&gt;
&lt;h2&gt;主要功能&lt;/h2&gt;
&lt;p&gt;Git主要用于Linux内核开发的版本控制系统，与&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%8D%94%E4%BD%9C%E7%89%88%E6%9C%AC%E7%B3%BB%E7%B5%B1&quot;&gt;CVS&lt;/a&gt;或&lt;a href=&quot;https://zh.wikipedia.org/wiki/Subversion&quot;&gt;Subversion&lt;/a&gt;这一类集中式版本控制系统的不同采用了分布式版本。&lt;/p&gt;
&lt;p&gt;它没有服务器端，就可以运行版本控制，这使得源码的发布与修改极其方便。git速度也是很给力。&lt;/p&gt;
&lt;h2&gt;实现原理&lt;/h2&gt;
&lt;p&gt;Git和其他版本控制系统（如&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%8D%94%E4%BD%9C%E7%89%88%E6%9C%AC%E7%B3%BB%E7%B5%B1&quot;&gt;CVS&lt;/a&gt;）有不少的差别，Git本身关心文件的整体性是否有改变，但多数的版本控制系统如&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%8D%94%E4%BD%9C%E7%89%88%E6%9C%AC%E7%B3%BB%E7%B5%B1&quot;&gt;CVS&lt;/a&gt;或&lt;a href=&quot;https://zh.wikipedia.org/wiki/Subversion&quot;&gt;Subversion&lt;/a&gt;系统则在乎文件内容的差异。&lt;/p&gt;
&lt;p&gt;我觉得Git更像一个文件系统，直接在本机上获取数据，不必连线到主机端获取数据。 每个开发者都可有全部开发历史的本地副本，&lt;/p&gt;
&lt;p&gt;changes从这种本地repository复制给其他开发者。这些changes作为新增的分支被导入，可以与本地分支合并。&lt;/p&gt;
&lt;p&gt;Git是用C语言开发的，以追求最高的性能。Git自动完成&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8)&quot;&gt;垃圾回收&lt;/a&gt;（也可以用 git gc --prune 调用）。&lt;br /&gt;
Git服务器典型的TCP监听，端口为9418。&lt;/p&gt;
&lt;h2&gt;Git的安装&lt;/h2&gt;
&lt;p&gt;Git平台支持有&lt;a href=&quot;https://zh.wikipedia.org/wiki/POSIX&quot;&gt;POSIX&lt;/a&gt;、&lt;a href=&quot;https://zh.wikipedia.org/wiki/Microsoft_Windows&quot;&gt;Windows&lt;/a&gt;、&lt;a href=&quot;https://zh.wikipedia.org/wiki/MacOS&quot;&gt;OS X&lt;/a&gt;，不过今天我们重点讲Linux。&lt;/p&gt;
&lt;p&gt;Git安装有许多种，主要分为两种：通过编译源代码、平台预编译安装包，源代码安装至少可以安装最新版本，不过Git慢慢壮大，不会出现安装包版本落后问题，这里也就不说了。&lt;/p&gt;
&lt;p&gt;在装软件之前我都会习惯的更新源&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;基于二进制安装Git&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo yum install git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ubuntu发行版&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt-get install  git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;查看Git当前版本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git version
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;初始化仓库&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 初始化当前目录为仓库
$ git init
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;克隆到本地仓库&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#　第二个参数克隆到指定目录，可带可不带
$ git clone [项目链接] [指定本地目录]
# 帮助
$ git clone -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;增加/删除文件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 提交新文件（new）和被修改（modified）文件，不包括被删除（deleted）文件
$ git add .
# 提交新文件（new）和已被删除（deleted）文件，不包括新文件
$ git add -u
# 提交所有变化。cunz
$ git add -A
# 提交当前目录.png后缀文件
$　git add *png
# 帮助
$ git add -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;检查工作目录/暂存区状态&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 检查工作目录与暂存区的状态
$ git status
# 只列出已被Git管理且被修改没提交的文件
$ git status -uno
# 帮助
$ git status -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获得远程仓库权限&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Git是分布式管理控制系统，基于SSH，所以我们要生成SSH公钥，然后它让输入的话就 Enter
$ ssh-keygen

# 之后切换到主目录下的 ~/.ssh 并找到 .pub 且复制文件内容（Windows在：C:/Users/当前用户名/.ssh/id_rsa.pub）
$ cd ~/.ssh &amp;amp;&amp;amp; ls
authorized_keys  id_rsa  id_rsa.pub  known_hosts

# 在Github页面 找到 Settigs -&amp;gt; SSH and GPG keys -&amp;gt;New SSH key 然后给这个秘钥取个名字，然后把Key填入并保存

# 当新文件添加到暂存区后，我们现在就准备创建第一个提交与注释了，不过在这之前我们要绑定Git账户，之后进行push操作需要填写账号\密码
$ git config --global user.email &quot;achuan@achuan.io&quot;
$ git config --global user.name &quot;achuanya&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;提交代码并注释&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ git commit -m &quot;这是一个测试&quot;
# 参数：
        # 自动检测修改文件
        -a
        # # 提交
        -m
# 帮助。
$ git commit -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;查看日志详情&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 显示当前分支的版本历史
$ git log
# 显示commit历史，以及每次commit发生变化的文件
$ git log --stat
# 搜索提交历史，根据关键词
$ git log -S [key Word]
# 显示某个文件的版本历史，包括文件改名
$ git log --follow [file]
# 显示过去的5次提交
$ git log -5 --pretty --oneline
# 帮助
$ git log -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;提交到远程仓库&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 提交到远程仓库，master即为分支
$ git push origin master
# 强行提交
$ git push -u origin master
# 上传本地指定分支到远程仓库（分支操作后面会说到）
$ git push [remote] [branch]
# 推送所有分支到远程仓库
$ git push [remote] --all
# 强行推送当前指定分支到远程仓库（即使有冲突）
$ git push [remote] --force
# 帮助
$ git push -h
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;移动、重命名与删除文件&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# 移动与重命名道理是一样的
$ git mv

# 继linux命令一样。
$ git rm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;rename.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;h2&gt;撤销修改/切换分支&lt;/h2&gt;
&lt;p&gt;git checkout 主要用于撤销修改或切换分支，它是一条较为常用的的命令，同时也很危险，因为这条命令会重新工作区！&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 恢复修改过的指定文件到工作区
$ git checkout [branch Name]
# 恢复暂存区所有文件到工作区
$ git checkout .
# 新建一个分支，并切换到该分支（切换分支不带参数 -b）
$ git checkout -b [name]
# 切换到上一个分支
$ git checkout -
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;管理分支&lt;/h2&gt;
&lt;p&gt;Git分支，好比一包零食，你可以选择和其他小伙伴一起吃一包，也可以自己吃一包，他们吃他们的，你吃你的相互之间没有影响，作为这包零食的主人，你也可以随时可以让两包零食放在一起（合并）。
​&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 现在让我们创建一包零食，不不不...一个新分支
$ git branch [name]
# 查看本地所有分支（当前分支前有个 * 号）
$ git branch
# 查看远程分支
$ git branch -r
# 查看本地和远程所有分支
$ git branch -a
# 重命名分支
$ git branch -m [name] [modify Name]
# 删除分支（ -D 强行删除）
$ git branch -d [name]
注：删除远程分支需要 git push 操作
$ git push origin :[name]
######################### 合并分支

# 把现有demo分支合并到master上
$ git metge [branch Name]

root@achuan-pc:/home/github/demo# git branch
demo
* master
root@achuan-pc:/home/github/demo# git merge demo
Updating d46f35e..b17d20e
Fast-forward
README.txt | 1 +
1 file changed, 1 insertion(+)

# 注意上面的合并信息 fasht-forward 意思是这次合并是快进模式，也就是直接吧master指向demo的当前提交，所以合并速度非常快。 
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Git常用命令&lt;/h2&gt;
&lt;p&gt;上面说的都是一些基本操作，下面也是一些常用命令，出于个人用途可能存在有些命令不全面，不过我往后学习中会进行添加，还请见谅。&lt;/p&gt;
&lt;h3&gt;查看信息&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 显示所有提交过的用户，按提交次数排序
$ git shortlog -sn
# 显示指定文件是什么人在什么时间修改过
$ git blame [file]
# 显示暂存区和工作区的差异
$ git diff
# 显示暂存区和上一个commit的差异
$ git diff --cached [file]
# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD
# 显示两次提交之间的差异
$ git diff [first Branch]...[second Branch]
# 显示今天你写了多少行代码
$ git diff --shortstat &quot;@{0 day ago}&quot;
# 显示某次提交的元数据和内容变化
$ git show [commit]
# 显示某次提交发生变化的文件
$ git show --name-only [commit]
# 显示某次提交时，某个文件的内容
$ git show [commit]:[filename]
# 显示当前分支的最近几次提交
$ git reflog
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;远程仓库的一些操作&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 下载远程仓库的所有变动
$ git fetch [remore Name]
# 跟踪存储库，不带参数，列出已存在的远程分支。
$ git remote
# 显示所有远程仓库
$ git remote -v
# 显示某个远程仓库的信息
$ gitremote shou [remote Name]
# 添加一个新的远程仓库，并命名
$ git remote add [shortname][url]
# 取远程仓库与本地分支合并  
$ git pull [remote] [branch]
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;拓展知识&lt;/h2&gt;
&lt;h3&gt;克隆下载某项目中的单个文件（文件夹）&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;$ wget https://github.com/acversionuanya/achuanya.github.io/blob/master/README.mdjinxing
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Github Chrome插件&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc/related&quot;&gt;Octotree&lt;/a&gt;，很直观的查看不同级文件夹，也方便进行文件跳转操作。&lt;br /&gt;
&lt;a href=&quot;https://chrome.google.com/webstore/detail/octo-mate/baggcehellihkglakjnmnhpnjmkbmpkf&quot;&gt;Octo Mate&lt;/a&gt;，增强你Githubt体验，它主要功能有四点：一键以.zip格式下载文件、
一键打开项目的Github Pages、显示仓库大小、显示未读消息数。&lt;/p&gt;
&lt;h3&gt;文件状态&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;未跟踪（untrack）：新增加文件。
已修改（modified）：已修改但为写入到暂存区。
已暂存（staged）：已经添加到暂存区。
已提交（committed）：已经添加到远程仓库。
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Git专业术语中英文对照表&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;terminology.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;br /&amp;gt;
ok写完了！通过这段时间的学习，关于Git命令我用到的差不多就这么多，可能存在有些命令不全面，不过我往后学习中会进行添加&lt;/p&gt;
&lt;p&gt;还请见谅。我现在真高兴当初出写博客这个决定，它让我每天学习都很有动力，有目标。最主要的是能把自己学会的知识分享给大家&lt;/p&gt;
&lt;p&gt;也能让这个知识点记的更加牢固。再过半年就要入职场了，压力也是不小。不过不能让压力阻止我向前跨步！下次文章关于“LAMP/LNMP架构”的相关内容&lt;/p&gt;
&lt;h3&gt;2019-04-28 更新&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 撤销所有
git reset HEAD -- .

# 撤销指定文件
git reset HEAD -- filename [文件名]

# 将文件从缓存中删除
git rm -cached filepath [文件名]
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E5%BC%80%E6%BA%90%E5%88%86%E5%B8%83%E5%BC%8F%E7%AE%A1%E7%90%86%E6%8E%A7%E5%88%B6%E7%B3%BB%E7%BB%9F%20%E2%80%94%E2%80%94%20Git%20%E7%AC%94%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-10-25-git&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)论胡编乱造的写作技巧</title><link>https://blog.lhasa.icu/posts/life/2018-10-24-theory-of-means</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/life/2018-10-24-theory-of-means</guid><pubDate>Wed, 24 Oct 2018 04:44:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://www.liaoxuefeng.com/article/1087739344711968&quot;&gt;廖雪峰的博客&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;theory-of-maens.jpeg&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;p&gt;今天给正在上小学二年级的女儿听写语文课文的词语时，发现有一篇课文讲的是爱迪生救妈妈的故事，大意就是爱迪生7岁那年，妈妈得了阑尾炎，医生在他家里准备给妈妈做手术，因为油灯的灯光太暗做不了，于是爱迪生想出了一个好办法：他找来很多镜子，把光聚在一起，让医生顺利地进行了手术。&lt;/p&gt;
&lt;p&gt;这个故事的意义是说爱迪生从小聪明过人，肯动脑筋，不过我越读感觉这个故事越假，在家里做阑尾手术这医生胆子也够大的。于是本着实事求是的精神，上网考证了一番，发现这个故事漏洞百出。&lt;/p&gt;
&lt;p&gt;首先，根据维基百科的记载，爱迪生出生于1847年，7岁那年是1854年，这么早的年份，到底能不能做阑尾炎手术呢？&lt;/p&gt;
&lt;p&gt;答案是：不能。&lt;/p&gt;
&lt;p&gt;因为根据医学资料记载，历史上最早使用“阑尾炎”的医生是美国人菲兹，他于1843年出生，也就是比爱迪生大4岁，爱迪生7岁那年他11岁，青春期才刚开始，呵呵。&lt;/p&gt;
&lt;p&gt;菲兹提出应该用手术切除阑尾是在1886年，那一年爱迪生39岁，菲兹43岁。而且，菲兹不是外科医生，所以，第一例真正成功的阑尾手术是1887年由费城外科医生毛顿做的。&lt;/p&gt;
&lt;p&gt;由于爱迪生没有发明过时光穿梭机，因此我们断定，该故事完全属于编造。&lt;/p&gt;
&lt;p&gt;我们总是说文章源于生活而高于生活，对生活进行一定程度的“加工”是可以的，但是加工前作者最好能有一点点基本的科学知识。如果硬要胡编乱造，我个人有两点心得体会：&lt;/p&gt;
&lt;p&gt;一种是写“很久很久以前，有一头大怪兽……”，神话故事，随便编。&lt;/p&gt;
&lt;p&gt;另一种是写“公元3017年，抵抗外星人的战争已经进入了第9个年头……”，科幻故事，也随便编。&lt;/p&gt;
&lt;p&gt;除此之外，故事里提到的人物、时间、事件，最好能用搜索引擎简单验证一下。&lt;/p&gt;
&lt;p&gt;不过值得欣慰的是，作者没有写电灯而是油灯，说明作者对爱迪生发明了电灯还是略知一二的：7岁的爱迪生尚未发明电灯。&lt;/p&gt;
&lt;p&gt;但我还是希望人教出版社能把这篇编造的课文从语文书里面删了，一是因为欺骗小孩子总是不好的，二是这篇文章暴露了人教社编辑的知识水平实在有限，出于面子的原因，也应该在再版时尽快删除。&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E8%AE%BA%E8%83%A1%E7%BC%96%E4%B9%B1%E9%80%A0%E7%9A%84%E5%86%99%E4%BD%9C%E6%8A%80%E5%B7%A7&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Flife%2F2018-10-24-theory-of-means&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>更换了域名、邮箱并修复了移动端 Bug</title><link>https://blog.lhasa.icu/posts/technology/2018-10-21-domain-name</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-10-21-domain-name</guid><pubDate>Sun, 21 Oct 2018 07:44:00 GMT</pubDate><content:encoded>&lt;p&gt;更换域名这件事我想了好久，原使用&lt;a href=&quot;https://zh.wikipedia.org/wiki/GitHub&quot;&gt;Github&lt;/a&gt;的三级域名但它太长，本来想换achuan&lt;a href=&quot;https://zh.wikipedia.org/wiki/.com&quot;&gt;.com&lt;/a&gt;不过早就被注册了，&lt;/p&gt;
&lt;p&gt;卖方叫价太高了，没有5000谈判都碰不着。ahuan&lt;a href=&quot;https://zh.wikipedia.org/wiki/.cn&quot;&gt;.cn&lt;/a&gt;也是早已注册，人家买了域名都不解析挂着玩，也联系过人家，不过人家不回消息。&lt;a href=&quot;https://zh.wikipedia.org/wiki/.net&quot;&gt;.net&lt;/a&gt; &lt;a href=&quot;https://zh.wikipedia.org/wiki/.me&quot;&gt;.me&lt;/a&gt; 都没了。&lt;/p&gt;
&lt;p&gt;偶然我了解到“&lt;a href=&quot;https://zh.wikipedia.org/wiki/.io&quot;&gt;.io&lt;/a&gt;”，它是一个&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%9C%8B%E5%AE%B6%E5%9C%B0%E5%8D%80%E4%BB%A3%E7%A2%BC&quot;&gt;国别域名&lt;/a&gt;，同时，它还可被理解为[inputoutput]即“输入输出接口”之意。“io”看着是是不是有点像二进制的“0 与 1”！感觉很有技术内涵，&lt;/p&gt;
&lt;p&gt;而且近几年.io在&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%8C%BA%E5%9D%97%E9%93%BE&quot;&gt;区块链&lt;/a&gt;方面比较火，我感觉用来搭建技术博客也是不错的选择。&lt;/p&gt;
&lt;p&gt;在选择域名商我也是非常纠结，.io后缀国内域名商几乎是没有的，主要是不能备案，毕竟这是国别后域名，估计不会开放备案。国内不行那就国外吧，&lt;/p&gt;
&lt;p&gt;怎么要有免费的隐私保护、网站访问速度正常、支付方式、域&lt;a href=&quot;https://en.wikipedia.org/wiki/Dynadot&quot;&gt;dynadot&lt;/a&gt;是我一个想到的，这家伙有大量的骚东西，特殊后缀域名&lt;a href=&quot;https://www.dynadot.com/zh/domain/love.html&quot;&gt;.love&lt;/a&gt; &lt;a href=&quot;https://zh.wikipedia.org/wiki/.io&quot;&gt;.blog&lt;/a&gt; &lt;a href=&quot;https://zh.wikipedia.org/wiki/.io&quot;&gt;.wiki&lt;/a&gt; 等...说一下它的一些服务吧，&lt;/p&gt;
&lt;p&gt;购买域名即送终身隐私保护，但我也不是什么明星大腕，隐私保护自然用不到，&lt;a href=&quot;https://en.wikipedia.org/wiki/Dynadot&quot;&gt;dynadot&lt;/a&gt;所有域名都赠送终身免费的隐私保护，&lt;a href=&quot;https://en.wikipedia.org/wiki/Dynadot&quot;&gt;dynadot&lt;/a&gt;网站自带各国域名很多种，自然有中文，而且在北京设立有分公司，国内网站速度打开正常并且支持支付宝，解析稳定这都不用说，虽然这家口碑不是理想中的那么好，但是跑路估计是不存在的，至于转出暂时我没试过不知道，唯一就是感觉这家&lt;a href=&quot;https://zh.wikipedia.org/wiki/.io&quot;&gt;.io&lt;/a&gt;价格有点高 $29。&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://zh.wikipedia.org/wiki/.io&quot;&gt;Namesilo&lt;/a&gt;也不错，号称全球最便宜，收费透明且支付支付宝，不过国内访问注册都过不了，翻墙就不至于了，不多考虑。&lt;a href=&quot;https://www.namecheap.com&quot;&gt;Namecheap&lt;/a&gt;呢价格上不算便宜，但是各方面做的不错，不限于速度、稳定性、免费的&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%82%B3%E8%BC%B8%E5%B1%A4%E5%AE%89%E5%85%A8%E6%80%A7%E5%8D%94%E5%AE%9A&quot;&gt;SSL&lt;/a&gt;、客服响应等等、但是它不支持支付宝。至于&lt;a href=&quot;https://zh.wikipedia.org/wiki/GoDaddy&quot;&gt;GoDaddy&lt;/a&gt;，虽然最为业界的NO 1，&lt;/p&gt;
&lt;p&gt;但是在网上查看那些相关新闻评论，看我的我不想买了都，虽然它有中文、支持支付宝、国内访问还算凑合。但是pass。&lt;br /&gt;
考虑了半天想想还是用“挑兵挑将”来选择吧 天选之商 &lt;a href=&quot;https://en.wikipedia.org/wiki/Dynadot&quot;&gt;dynadot&lt;/a&gt; 胜出....下了订单$29，吃土吧，快乐并痛苦着...买后即用，&lt;/p&gt;
&lt;p&gt;不用备案是真爽，进去NDS设置一下，ping achuanya.github.io获取IP，然后添加主域名&lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E4%BC%BA%E6%9C%8D%E5%99%A8%E8%A8%98%E9%8C%84%E9%A1%9E%E5%9E%8B%E5%88%97%E8%A1%A8&quot;&gt;A记录&lt;/a&gt; 185.199.109.153，&lt;/p&gt;
&lt;p&gt;子域名 www &lt;a href=&quot;https://zh.wikipedia.org/wiki/%E5%9F%9F%E5%90%8D%E4%BC%BA%E6%9C%8D%E5%99%A8%E8%A8%98%E9%8C%84%E9%A1%9E%E5%9E%8B%E5%88%97%E8%A1%A8&quot;&gt;A记录&lt;/a&gt;随主域名。更换了域名，邮箱也改一下吧，&lt;a href=&quot;https://ym.163.com&quot;&gt;网易企业邮箱&lt;/a&gt;免费，添加 &lt;a href=&quot;https://zh.wikipedia.org/wiki/MX%E8%AE%B0%E5%BD%95&quot;&gt;MX记录&lt;/a&gt; mx.ym.163.com&lt;/p&gt;
&lt;p&gt;优先级10（邮箱：&lt;a href=&quot;mailto:achuan@achuan.io&quot;&gt;achuan@achuan.io&lt;/a&gt;），访问 achuan.io 完全ojbk。&lt;/p&gt;
&lt;p&gt;除了域名\邮箱也没闲着，修改了博客移动端的一些bug：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;输入域名后自动进入主页且不能退回到文章栏。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;移动端增加了一项功能：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;增加返回菜单栏按钮。&lt;/li&gt;
&lt;/ul&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E6%9B%B4%E6%8D%A2%E4%BA%86%E5%9F%9F%E5%90%8D%E3%80%81%E9%82%AE%E7%AE%B1%E5%B9%B6%E4%BF%AE%E5%A4%8D%E4%BA%86%E7%A7%BB%E5%8A%A8%E7%AB%AF%20Bug&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-10-21-domain-name&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Linux 命令笔记</title><link>https://blog.lhasa.icu/posts/technology/2018-09-24-linux-command</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-09-24-linux-command</guid><pubDate>Mon, 24 Sep 2018 04:44:00 GMT</pubDate><content:encoded>&lt;p&gt;今天在写一些刚最近学到&lt;a href=&quot;https://zh.wikipedia.org/zh/Linux&quot;&gt;linux&lt;/a&gt;命令，看到笔记本上记得有点乱重写整理了一下。接触了linux也有近大半年了，越来越离不开它了，windows也是偶尔开一下虚拟机，接触linux这段时间也是受益匪浅。&lt;/p&gt;
&lt;p&gt;使用windows的时候虽然控制的住网瘾，但是偶尔也想打一把，自从独装了linux直接一棒子打死...挺好的...我也非常喜欢linux命令，它提升了我一些单词量。还让我接触了开源的概念、它的历史,这些我都非常喜欢。&lt;/p&gt;
&lt;p&gt;咳咳，关于开源过几天再说吧，进入正题，这些是记的笔记，linux命令虽多，但每个人玩linux的目的固然不同，常用的命令也有差异，当然你也用到它时Google一下。&lt;/p&gt;
&lt;h2&gt;cd&lt;/h2&gt;
&lt;p&gt;切换目录，可以是绝对路径，也可以是相对路径&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 切换到目录/achuan/achuan
cd /home/achuan

# 切换到当前目录下的achuan目录中
cd ./achuan

# 切换到上层目录中的chuan目录中，&quot;..&quot;表示上一层目录
cd ../achuan

# 切换到home
cd ~

# 切换到目录的上两级
cd ../..
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ls&lt;/h2&gt;
&lt;p&gt;查看目录与文件，list之意&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 列出长数据串，包含文件的属性与权限数据等
-l
# 列出全部的文件，连同隐藏文件（开头为.的文件）一起列出来（常用）
-a
# 仅列出目录本身，而不是列出目录的文件数据
-d
# 将文件容量以较易读的方式（GB，kB等）列出来
-h
# 连同子目录的内容一起列出（递归列出），等于该目录下的所有文件都会显示出来
-R
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;grep&lt;/h2&gt;
&lt;p&gt;强大的文本搜索命令，它能使用正则表达式搜索&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;grep
# 将binary文件以text文件的方式查找数据
-a
# 计算找到‘查找字符串’的次数
-c
# 忽略大小写的区别，即把大小写视为相同
-i
# 反向选择，即显示出没有&apos;查找字符串&apos;内容的那一行
-v
例如：
# 取出文件/etc/man.config中包含MANPATH的行，并把找到的关键字加上颜色
grep --color=auto &apos;MANPATH&apos; /etc/man.config
# 把ls -l的输出中包含字母file（不区分大小写）的内容输出
ls -l | grep -i file
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;find&lt;/h2&gt;
&lt;p&gt;基于查找文件命令，相对而言，使用复杂，参数多&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# n为数字，意思为在n天之前的“一天内”被更改过的文件
-mtime n
# 列出在n天之前（不含n天本身）被更改过的文件名
-mtime +n
# 列出在n天之内（含n天本身）被更改过的文件名
-mtime -n
# 列出比file还要新的文件名
-newer file
# 例如：
# 在当前目录下查找今天之内有改动的文件
find /root -mtime 0


# 与用户或用户组名有关的参数

# 列出文件所有者为name的文件
-user name
# 列出文件所属用户组为name的文件
-group name
# 列出文件所有者为用户ID为n的文件
-uid n
# 列出文件所属用户组为用户组ID为n的文件
-gid n
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;与文件权限及名称有关的参数：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 找出文件名为filename的文件
-name filename
# 找出比SIZE还要大（+）或小（-）的文件
-size [+-]SIZ

# 查找文件的类型为TYPE的文件，TYPE的值主要有：一般文件（f)、设备文件（b---术、c）
# 目录（d）、连接文件（l）、socket（s）、FIFO管道文件（p）
-tpye TYPE
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;cp&lt;/h2&gt;
&lt;p&gt;用于复制文件，还可以把多个文件一次性复制到一个目录下&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 将文件的特性一起复制
-a
# 连同文件的属性一起复制，而非使用默认方式，与-a相似（常用于备份）
-p
# 若目标文件已经存在时，在覆盖时会先询问操作的进行
-i
# 递归持续复制，用于目录的复制行为
-r
# 目标文件与源文件有差异时才会复制
-u
# 例如：
cp -a aa aab   //连同文件的所有特性把文件aa复制成文件aab
Cp aa aab aabb achuan   //把文件aa、aab、aabb复制到目录achuan中
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;mv&lt;/h2&gt;
&lt;p&gt;用于移动文件、目录或更名，move之意&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# force强制的意思，如果目标文件已经存在，不会询问而直接覆盖
-f
# 若目标文件已经存在，就会询问是否覆盖
-i
# 若目标文件已经存在，且比目标文件新，才会更新
-u

# 注：该命令可以把一个文件或多个文件一次移动一个文件夹中，但是最后一个目标文件一定要是“目录”。
# 例如：
mv aa aab aabb achuan   //把文件aa、aab、aabb移动到目录achuan中
mv aa aab   //把文件aa重命名为aab
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;rm&lt;/h2&gt;
&lt;p&gt;用于删除文件或目录，remove之间（数据无价，操作需谨慎！！！）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 就是force的意思，忽略不存在的文件，不会出现警告消息
-f
# 互动模式，在删除前会询问用户是否操作
-i
# 递归删除，最常用于目录删除，它是一个非常危险的参数
-r
# 例如：
rm -i achuan   //删除文件achuan，在删除之前会询问是否进行该操作
rm -fr achuan  //强制删除目录achuan中的所有文件
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;ps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;用于某个时间点的进程运行情况选取下来并输出，process之意&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  # 所有的进程均显示出来
  -A
  # 不与terminal有关的所有进程
  -a
  # 有效用户的相关进程
  -u
  # 一般与a参数一起使用，可列出较完整的信息
  -x
  # 较长，较详细地将PID的信息列出
  -l

  # 用到不多，记住一般使用命令参数搭配即可
  # 例如：`
  # 查看系统所有的进程数据
  ps aux
  # 查看不与terminal有关的所有进程
  ps ax
  # 查看系统所有的进程数据
  ps -lA
  #  查看连同一部分进程树状态
  ps axjf
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;kill&lt;/h2&gt;
&lt;p&gt;用于向某个工作或者是某个PID（数字）传送一个信号，它通常与ps和jobs命令一起使用，# 例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kill -signal PID
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;signal的常用参数如下：&lt;br /&gt;
注：最前面的数字为信号的代号，使用时可以用代号代替相应的信号。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 启动被终止的进程
1：SIGHUP
# 相当于输入ctrl+c，中断一个程序的进行
2：SIGINT
# 强制中断一个进程的进行
9：SIGKILL
# 以正常的结束进程方式来终止进程
15：SIGTERM
# 相当于输入ctrl+z，暂停一个进程的进行
17：SIGSTOP

# 例如：
# 以正常的结束进程方式来终于第一个后台工作，可用jobs命令查看后台中的第一个工作进程
kill -SIGTERM %1 
# 重新改动进程ID为PID的进程，PID可用ps命令通过管道命令加上grep命令进行筛选获得
kill -SIGHUP PID
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;file&lt;/h2&gt;
&lt;p&gt;用于判断file命令后的文件的基本数据，因为在linux下文件的类型并不是以后缀分的，这个命令显得非常有用，语法so easy&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;file filename
# 例如：
file ./test
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;tar&lt;/h2&gt;
&lt;p&gt;命令用于对文件进行打包，默认情况并不会压缩，如果指定相应的参数，还会调用相应的压缩程序（gzip和bzip等）进行压缩和解压&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 新建打包文件
-c
# 查看打包文件的内容含有哪些文件名
-t
# 解打包或解压缩的功能，可以搭配-C（大写）指定解压的目录，注意-c,-t,-x不能同时出现在同一条命令中
-x
# 通过bzip2的支持进行压缩/解压缩
-j
# 通过gzip的支持进行压缩/解压缩
-z
# 在压缩/解压缩过程中，将正在处理的文件名显示出来
-v
# filename为要处理的文件
-f filename
# 指定压缩/解压缩的目录achuan
-C achuan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;命令有点多哈，但是通常我们只需要记住下面三条命令即可：
# 压缩
tar -jcv -f filename.tar.bz2 要被处理的文件或目录名称
# 查询
tar -jtv -f filename.tar.bz2
# 解压
tar -jxv -f filename.tar.bz2 -C 欲解压缩的目录&lt;/p&gt;
&lt;h2&gt;chgrp&lt;/h2&gt;
&lt;p&gt;用于改变文件所属用户组&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;chgrp [-R] dirname/filename
-R   //进行递归的持续对所有文件和子目录更改
# 例如：
chgrp users -R ./achuan   //递归地把achuan目录下中的所有文件和子目录下所有文件的用户组修改为users
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;chmod&lt;/h2&gt;
&lt;p&gt;用于改变文件或目录的权限，非常重要的命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 当发生改变时，报告处理信息
-c
# 错误信息不输出
-f
# 进行递归的持续对所有文件和子目录更改
-R
# 运行时显示详细处
-v
# 读取权限
-4或r
# 写入权限
-2或w
# 执行或切换权限
-1或x
# 不具任何权限
-0或-
# 特殊权限
-s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注：该命令有两种用法，包含字母和操作符表达式的文字设定法；另一种是包含数字的数字设定法，在此我只说数字设定法。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;说数字设定法
0没有权限，1执行权限，2写权限，4读权限，然后将其相加。所以数字属性的格式应为3个从0到7的八进制数&lt;/p&gt;
&lt;p&gt;例如：&lt;br /&gt;
如果想让某个文件的属主有“读/写”二种权限，需要把4（可读）+2（可写）＝6（读/写）。
chmod 777 -R achuan&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;vim&lt;/h2&gt;
&lt;p&gt;vim命令要用于文本编辑，相比vim的话题不亚于，哪个编程语言更好...不过编辑器，在我看来不过是用哪个会提高我的工作效率，这因人而异。vim里面有很多好用的命令，以后我会单独说它。&lt;/p&gt;
&lt;h2&gt;gcc&lt;/h2&gt;
&lt;p&gt;前段时间学了点C才了解的，它主要用于编译，对于开发C语言的人来说，这是非常重要的命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# output之意，用于指定生成一个可执行文件的文件名
-o
# 用于把源文件生成目标文件（.o)，并阻止编译器创建一个完整的程序
-c
# 增加编译时搜索头文件的路径
-I
# 增加编译时搜索静态连接库的路径
-L
# 把源文件生成汇编代码文件
-S
# 表示标准库的目录中名为libm.a的函数库
-lm
# 连接NPTL实现的线程库
-lpthread
# 用于指定把使用的C语言的版本
-std=

例如：
# 把源文件demo1.c按照c99标准编译成可执行程序demo1
gcc -o demo1 demo1.c -lm -std=c99
# 把源文件demo1.c转换为相应的汇编程序源文件demo1.s
gcc -S demo1.c

shutdown
# 关机、重启命令，经常使用的命令

# 重启
-r
# 杀死所有运行中的程序后自动关机
-n
# 关机时，不进行磁盘检测
-f
# 关机时，进行磁盘检测
-c
# 例如：
# 立即重启
shutdown -r 、now
# 立即关机
shutdown now
# 5分钟后关机
shutdown +5 now
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;init是所有进程的祖先，它们的进程号始为1.所以发送TERM信号给init会终止所有的用户进程，守护进程等，shutdown就是使用这种机制，init定义了8个运行级别（runleve），inti 0 关机，init 1 重启......关于init就到这了。就不长篇大论了。&lt;/p&gt;
&lt;p&gt;暂且到这里，欲知后续如何，请看下回分解&lt;/p&gt;
&lt;h1&gt;2019-2-15 更新&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;scp
# 多用于系统文件之间的复制,scp 是 secure copy 的缩写,中文就是&quot;安全复制&quot;,  
scp是linux系统下基于ssh协议进行的远程文件

# 强制scp命令使用协议ssh1
-1
# 强制scp命令使用协议ssh2
-2
# 强制scp命令只使用IPv4寻址
-4
# 强制scp命令只使用IPv6寻址
-6
# 使用批处理模式（传输过程中不询问传输口令或短语）
-B
# 允许压缩（将-C标志传递给ssh，从而打开压缩功能）
-C
# 保留原文件的修改时间，访问时间和访问权限
-p
# 不显示传输进度条
-q
# 递归复制整个目录
-r
# 详细方式显示输出。scp和ssh(1)会显示出整个过程的调试信息。这些信息用于调试连接，验证和配置问题
-v
# Ssh_option：如果习惯于使用ssh_config(5)中的参数传递方式
-o
# port：注意是大写的P,port是指定数据传输用到的端口号
-P   
# 例如:
# windows传输到linux,[参数][文件][用户名][ip][地址]
scp -r - demo.text ubuntu@139.199.105.72:/var/www
&lt;/code&gt;&lt;/pre&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Linux%20%E5%91%BD%E4%BB%A4%E7%AC%94%E8%AE%B0&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-09-24-linux-command&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>面向对象(Object Oriented)学习笔记(一)</title><link>https://blog.lhasa.icu/posts/technology/2018-09-23-object_oriented</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-09-23-object_oriented</guid><pubDate>Sun, 23 Sep 2018 03:28:00 GMT</pubDate><content:encoded>&lt;h2&gt;一. 面向对象(OOP)的发展历程&lt;/h2&gt;
&lt;h3&gt;1. OOP的诞生&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://zh.wikipedia.org/wiki/Simula&quot;&gt;&lt;strong&gt;Simulaq&lt;/strong&gt;&lt;/a&gt;面向对象技术最早是在编程语言Simual中提出，1967年2月20日，在挪威奥斯陆郊外的小镇莉沙布举行的IFIP TC-2 工作会议上，&lt;/p&gt;
&lt;p&gt;挪威科学家 Ole-Johan Dahl 和 Kristen Nygaard 正式发布了Simula 67语言。Simula 67，是面向对象的开山祖师，&lt;/p&gt;
&lt;p&gt;它引入了所有后来面向对象程序设计语言所遵循的基础概念：对象、类、继承，但它的实现并不是很完整。后来&lt;a href=&quot;https://zh.wikipedia.org/wiki/Smalltalk&quot;&gt;&lt;strong&gt;Smalltalk&lt;/strong&gt;&lt;/a&gt;的诞生，&lt;/p&gt;
&lt;p&gt;第二个面向对象的程序语言的出现，而且是第一个完整实现了面向对象技术的语言，和第一个真正的集成开发环境(IED)。&lt;/p&gt;
&lt;h2&gt;二. 面向对象(OOP)的概念&lt;/h2&gt;
&lt;p&gt;OOP达到了软件工程的三个目标&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;重用性&lt;/strong&gt;、&lt;strong&gt;灵活性&lt;/strong&gt;、&lt;strong&gt;扩展性&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三. OOP三大特征&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;封装(Encapsulation)：对外部不可见&lt;/li&gt;
&lt;li&gt;继承(Inheritance)：扩展类的功能&lt;/li&gt;
&lt;li&gt;多态(Polymorphism)：对象的重载、对象的多态性&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四. 类与对象&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;类是对某一类事物的描述，是抽象的、概念上实际存在的该类事物的每个个体，因而也称实例(instance)，&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;换种方法解释类就像一个具体的事物，一个对象，用编程代码来描述出来，&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对象，简单的来说对象是可以使用的，而类只是对这件事物进行描述，它不能使用。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;五. 类与对象的关系&lt;/h2&gt;
&lt;p&gt;这个我表达能力不太好哈...这样说吧，类就好比工厂车间的模具，而对象就是模具所产生的事物，一个模具是可以产生很多对象!
也就是说对象是类的实例化&lt;/p&gt;
&lt;h2&gt;六. 类的声明与对象的创建及使用&lt;/h2&gt;
&lt;p&gt;好了我们来了解一下怎么找对象，...不..创建对象..&lt;/p&gt;
&lt;h3&gt;1. 类的声明&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;class 类名称{
    // 这里成员属性修饰还有好几种下次一次详解
    // 声明成员变量(属性)
    数据类型 属性...

    // public 表示公有
    public 返回值的数据类型 方法名称 (参数1，参数2){  // 定义方法
        // 程序语句..
        // return 等表达式
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;2. 对象的创建及使用:&lt;/h3&gt;
&lt;p&gt;// 实例化对象,有参数别忘了加括号!&amp;lt;br&amp;gt;
&lt;code&gt;$定义对象名称 = new 类名([参数列表]);&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;对象中成员的访问:
// 输出对象的属性&amp;lt;br&amp;gt;
&lt;code&gt;$对象名 -&amp;gt; 成员属性 = 赋值;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;// 调用对象的方法:&amp;lt;br&amp;gt;
&lt;code&gt;$对象名 -&amp;gt; 成员方法(参数);&lt;/code&gt;&amp;lt;br&amp;gt;
// 成员属性中还分有静态属性, 它是不能实例化的,往后我会补充&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php
/*---------------------------------*\
    对象实例化
    //实例化指OOP编程中，类创建对象的过程
\*---------------------------------*/
class phone{
    # 成员属性
    public $width;
    public $height;
    public $size;

    # 成员方法
    public function call($name){
        echo &quot;正在给{$name}打电话&quot;;}

    public function message($name){
        echo &quot;正在给{$name}发短信&quot;;}
    public function play(){
        echo &quot;正在玩游戏!&quot;;}

    public function info(){
        $this -&amp;gt; play();
        return &quot;&amp;lt;br&amp;gt; 手机的宽度；{$this -&amp;gt; width},&amp;lt;br&amp;gt; 手机的高度；{$this -&amp;gt; height}&quot;;}
}

# 实例化对象
$phone = new phone();
$phone -&amp;gt; width = &quot;5CM&quot;;
$phone -&amp;gt; height = &quot;10CM&quot;;

//$phone -&amp;gt; width = &quot;5CM&quot;; //对象对成员属性的赋值(引用变量时 $ 符可以不写)
//echo $phone -&amp;gt; width; //与对象取得成员属性存的值
//$phone1 = new phone();
//$phone1 -&amp;gt; height = &quot;10CM&quot;;
//$height = $phone1 -&amp;gt; height;
//echo $height; 
//echo $phone1 -&amp;gt; height;

//$phone1 -&amp;gt; aaaa = &quot;AAAA&quot;;font
//var_dump(&quot;&amp;lt;br&amp;gt;&quot;,$phone1);
$phone -&amp;gt; call(&quot;!list&quot;);
$phone -&amp;gt; call(&quot;&amp;lt;br&amp;gt; tom&quot;);
echo &quot;&amp;lt;br&amp;gt;&quot;;
$phone -&amp;gt; play();
echo $phone -&amp;gt; info();

?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;呼～ 第一章写完了，我也是近期刚学OOP，可能哪个方面写的并不是很好 嘿嘿，如有写的不足之处，还请您在下方留言!&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1(Object%20Oriented)%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0(%E4%B8%80)&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-09-23-object_oriented&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>致简写作神器 —— Markdown</title><link>https://blog.lhasa.icu/posts/technology/2018-09-03-markdown</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-09-03-markdown</guid><pubDate>Mon, 03 Sep 2018 04:44:00 GMT</pubDate><content:encoded>&lt;h2&gt;1. Markdown？&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Markdown&quot;&gt;Markdown&lt;/a&gt;是什么？&lt;br /&gt;
Markdown 是由 John Gruber 在2004年创建的「轻量级标记语言」，至今它已经有14岁了！&lt;/p&gt;
&lt;p&gt;Markdown最初的定义&lt;strong&gt;纯文本语法&lt;/strong&gt;。&lt;br /&gt;
设计理念就是易写、易读。
它那么的纯洁、致简、美妙感觉词汇已经不能形容Markdown的美。试着写一写，你也会爱上它。&lt;/p&gt;
&lt;h2&gt;2. Markdown 它有哪些优点？&lt;/h2&gt;
&lt;p&gt;前文说了它的定义与设计理念，易写、易读，无非就是Markdown最大的特点。&lt;/p&gt;
&lt;h3&gt;一. 所谓易写？&lt;/h3&gt;
&lt;p&gt;这里说的易写，是指写作的过程。因为它语法的原因且编辑器实时预览的情况下，差不多全程键盘，基本脱离对鼠标的依赖。这样就可以集中精力放在文章上。因为它语法简单，所以书写错误易发现。&lt;/p&gt;
&lt;h3&gt;二. 所谓易读？&lt;/h3&gt;
&lt;p&gt;所谓易读，可不要理解为&lt;strong&gt;排版之后呈现出来的结果&lt;/strong&gt;，这里的&lt;strong&gt;易读&lt;/strong&gt;是指&lt;strong&gt;源代码文件&lt;/strong&gt;（也就是以 &lt;strong&gt;.md&lt;/strong&gt;;&lt;strong&gt;.markdown&lt;/strong&gt;;&lt;strong&gt;.mdown&lt;/strong&gt; 后缀名的文件）它不会像写Html时那样，满屏幕都是密密麻麻的&amp;lt;标签&amp;gt;与选择器...&lt;/p&gt;
&lt;h2&gt;3. Markdown的优势与局限&lt;/h2&gt;
&lt;p&gt;我们知道Markdown只是一个&amp;lt;轻量级标记语言&amp;gt;，相比xml、html或Word、Pages这类，Markdown在排版的功能上显的弱一点。&lt;/p&gt;
&lt;h3&gt;一.  Markdown无法对段落进行灵活处理&lt;/h3&gt;
&lt;p&gt;在word中，像文本框，图片你可以随意调整它的位置。但Markdown不行，相比Markdown只能线性的对文字进行排版。&lt;/p&gt;
&lt;h3&gt;二. Markdown对非纯文本元素的排版能力很差&lt;/h3&gt;
&lt;p&gt;一篇文章，如果只有文字的话，总有感觉有点枯燥枯燥，但是Markdown限于纯文本格式，Markdown几乎做不到像Word那样对图片灵活的调整位置。&lt;/p&gt;
&lt;h3&gt;三. Markdown专注你的文字内容，而不是排版&lt;/h3&gt;
&lt;p&gt;Markdown不像Word那样花哨，应为语法的缘故吧，感觉它是那么的纯洁，做纯文字处理很棒的，我每次使用Markdown写文章时，有种很美妙的感觉...&lt;/p&gt;
&lt;h2&gt;4. Markdown语法与编辑器&lt;/h2&gt;
&lt;p&gt;Markdown语法的目标是：&lt;strong&gt;成为一种使用网络的书写语言&lt;/strong&gt;。&lt;br /&gt;
毕竟我们的易写、易读是有目共睹的，立志做书写语言我们是认真的！&lt;/p&gt;
&lt;h3&gt;Retext的安装&lt;/h3&gt;
&lt;p&gt;日常我都是用Ubuntu18.04LTS，Markdown编辑器我用的是&lt;a href=&quot;https://pypi.org/project/ReText&quot;&gt;ReText&lt;/a&gt;，不过windows、Mac也有很多优秀支持Markdown的编辑器，如MarkdownPad、Sublime Text3、Marxico等等...在这里我就不一一介绍了。&lt;/p&gt;
&lt;h4&gt;1. 安装&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;$ sudo apt-get install retext

# 也可以到官网下载，有deb包。
&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;2. 配置&lt;/h4&gt;
&lt;pre&gt;&lt;code&gt;# 添加数学公式的支持
$ sudo apt-get install libjs-mathjax
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;然后在&quot;&lt;strong&gt;extensions.txt&lt;/strong&gt;&quot;中添加&quot;&lt;strong&gt;mathjax&lt;/strong&gt;&quot;（没有这个文件创建一个）  `&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 添加：mathjax
$ vim .config/markdown-extensions.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;ok!  如果需要网页在线编辑器&lt;a href=&quot;https://www.zybuluo.com/mdeditor&quot;&gt;MaHua 在线markdown编辑器&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;语法比较简单，就不一一说了&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E8%87%B4%E7%AE%80%E5%86%99%E4%BD%9C%E7%A5%9E%E5%99%A8%20%E2%80%94%E2%80%94%20Markdown&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-09-03-markdown&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>(转)如何学习开源项目</title><link>https://blog.lhasa.icu/posts/technology/2018-08-31-learning-the-open-source</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-08-31-learning-the-open-source</guid><pubDate>Fri, 31 Aug 2018 05:28:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://yizhaolingyan.net/&quot;&gt;华为章宇的博客&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;学习各种开源项目，已经成为很多朋友不可回避的工作内容了。笔者本人也是如此。在接触并学习了若干个开源项目之后，笔者试图对自己工作过程中的若干体会加以总结，以期对一些希望借鉴的朋友有所裨益。&lt;/p&gt;
&lt;p&gt;需要说明的是，笔者本人接触的开源项目大多属于计算机系统领域，例如Linux kernel，KVM，QEMU，OpenStack等。因此，此处介绍的经验必定也有些局限。请读者们自行分辨，区别对待。&lt;/p&gt;
&lt;h2&gt;学习分层和目标管理&lt;/h2&gt;
&lt;p&gt;对于一个开源项目，可以将与之相关的各种知识和技能的学习大致划分为如下五个层次：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第一层次&lt;/strong&gt;：了解项目的基本概念、基本用途、逻辑结构、基本原理、产生背景、应用场景等基本知识。&lt;/p&gt;
&lt;p&gt;这个层次的基本定位其实就是“科普”。如果对于一个项目只需要有些基本了解，且短期内并不需要上手进行实际技术工作，则学习到这个层次也就可以先应付一下了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第二层次&lt;/strong&gt;：掌握项目的基本安装流程和使用方法。&lt;/p&gt;
&lt;p&gt;这个层次的基本定位是“入门”，以便对这个项目获得直观认识，对其安装和使用获得亲身体验。如果只是需要以as-is方式使用这个项目，则初步学习到这个层次即可。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第三层次&lt;/strong&gt;：了解代码的组织，找到各个主要逻辑/功能模块与代码文件之间的对应关系，通过代码分析走通几个关键的、有代表性的执行流程。&lt;/p&gt;
&lt;p&gt;这个层次的基本定位是“深入”，开始理解这个项目的实际实现，能够真正将项目的功能、工作原理和代码实现对应起来，获得对这个项目工作过程的直观认识。这个层次是学习开源项目代码的真正开始。如果希望基于这一项目进行应用开发，或者针对与这一项目密切相关的其他项目进行工作时，则对项目本身的代码进行这一层次的理解，会很有帮助。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第四层次&lt;/strong&gt;：了解该项目所有代码模块、程序文件的作用，走通所有主要执行流程。&lt;/p&gt;
&lt;p&gt;这个层次的基本定位是“掌握”，能够比较全面、系统地理解这个项目的设计和实现，并且熟悉项目各个部分的代码。如果希望对项目进行深度定制修改，或者对社区有所贡献，则应当以达到这个层次作为目标。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第五层次&lt;/strong&gt;：钻研、领悟该项目的各种设计思想与代码实现细节。&lt;/p&gt;
&lt;p&gt;这个层次的基本定位是“精通”，精益求精，学无止境。这是大神们追求的境界。如果希望成为项目社区的重要贡献者乃至核心贡献者，则应当以这个层次作为努力的目标。
综上，对于一个开源项目的学习过程可以大致分为五个层次。至于到底要学习到什么阶段，投入多少相关精力，则完全取决于学习的目的。&lt;/p&gt;
&lt;h2&gt;知识基础&lt;/h2&gt;
&lt;p&gt;学习一个开源项目需要的知识基础主要包括：&lt;/p&gt;
&lt;p&gt;1）该项目涉及的技术领域的背景知识。&lt;br /&gt;
举例而言，分析Linux Kenrel，则应该了解操作系统原理；学习OpenStack，则应该知道什么是云计算。如果没有这些背景知识作为基础，上来就死磕源代码，只能是事倍功半。&lt;/p&gt;
&lt;p&gt;2）	该项目开发使用的语言及其各种开发调试工具&lt;br /&gt;
这个就无需多言了。&lt;/p&gt;
&lt;p&gt;3）	英语&lt;br /&gt;
很遗憾，目前为止真正流行的开源项目大部分不是起源于国内。因此，除了学习个别极其流行、文档完备的项目之外，大家还是需要自行搜集阅读英文资料参考。学好英语很重要。&lt;/p&gt;
&lt;p&gt;当然，到底需要准备多少知识基础，完全取决于学习的目的和层次。如果只是想科普一下，也就不必太过麻烦了。&lt;/p&gt;
&lt;h2&gt;学习思路&lt;/h2&gt;
&lt;p&gt;学习一个项目的过程，其实就是由表及里了解分析它的过程。上述提及的五个学习层次便组成了这样一个逐渐深入的过程。在此基础之上，学习、分析代码的过程，也可以尝试做到由表及里、逐渐深入。&lt;/p&gt;
&lt;p&gt;在刚开始接触一个项目的时候，我们看到的其实就是一个黑盒子。根据文档，我们一定会发现盒子上具有若干对外接口。通常而言，这些接口可以被分为三类：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;配置接口：用于对盒子的工作模式、基本参数、扩展插件等等重要特性进行配置。这些配置往往是在盒子启动前一次性配好。在盒子的工作过程中，这些配置或者不变，或者只在少数的情况下发生改变。&lt;/li&gt;
&lt;li&gt;控制接口：用于在盒子的工作过程中，对于一些重要的行为进行操纵。这是盒子的管理员对盒子进行控制命令注入和状态信息读取的通路。&lt;/li&gt;
&lt;li&gt;数据接口：用于盒子在工作过程中读取外部数据，并在内部处理完成后向外输出数据。这是盒子的用户真正关心的数据通路。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此，在分析一个开源项目的代码时，可以围绕重要的配置、控制、数据接口展开分析工作，特别应该注意理解一个关键的接口背后隐藏的操作流程。例如，针对数据接口，至少应当走通一条完整的数据输入输出流程，也即在代码中找到数据从输入接口进入盒子后，经过各种处理、转发步骤，最终从输出接口被传输出去的整个执行过程。一旦走通了这样一条流程，则可以将与数据处理相关的各个主要模块、主要步骤贯穿起来，并将逻辑模块图上和文档中的抽象概念对应到代码实现之中，可以有效推进对于项目的深入理解。&lt;/p&gt;
&lt;p&gt;在实践这一思路的过程中，笔者建议可以优先从控制接口和数据接口中各自选择一二重要者进行背后的执行流程详细分析，力争找到其中每一步的函数调用及数据传递关系（对于一些系统、应用库提供的底层函数可以先行跳过以节省时间）。这一工作完成之后，则第1节中第三层次的学习目标即可初步达成。&lt;/p&gt;
&lt;p&gt;配置接口在不同的项目中的重要程度不同。对于一些架构极为灵活、配置空间甚大的项目（如OpenStack的Ceilometer），则可以适当多花些时间加以研究，否则简单了解即可。&lt;/p&gt;
&lt;p&gt;对于这个学习思路，下文中还将结合实例进行进一步的说明。&lt;/p&gt;
&lt;h2&gt;若干小建议&lt;/h2&gt;
&lt;p&gt;以下是笔者的一些零散建议，供大家参考。&lt;/p&gt;
&lt;p&gt;1）做好记录&lt;br /&gt;
在刚刚入手开始学习某个项目的源代码时，其实很有点破译密码的感觉。大量的数据结构和函数方法散落在代码的各个角落里，等待着学习者将它们贯穿到一个个重要的执行流程中。因此，在分析学习的过程中，无论有什么零散收获，都值得认真记录下来。珍珠自然会串成项链的。&lt;/p&gt;
&lt;p&gt;2）不要过分纠缠于细节&lt;br /&gt;
立志搞懂一个项目的每行源代码是值得尊敬的，但至少在刚刚入手的时候是没有必要的。如果过于纠缠于代码的实现细节，则可能很快就被搞得头晕眼花不胜其烦了（看英文资料的时候，每遇到一个不认识的词都要立刻查词典么？）。不妨避免细节上的过度纠缠，还是先尽快走通关键的执行流程，将项目的骨干框架搭起来，然后再以此为参照，就可以清晰判断什么代码值得深入分析，什么地方可以简单略过了。&lt;/p&gt;
&lt;p&gt;3）想像和联想很重要&lt;br /&gt;
如前所述，从零开始搞懂一个项目的代码，就像破译密码。因此，不妨展开合理的想象和联想，将各个零散的发现和理解联系起来，并加以分析印证。在这个过程中，对项目所在领域的背景知识、对项目本身的逻辑框架和工作原理等方面的理解，都是想像和联想的参照与指导。此外，一些关键的函数名、变量名等等都是联想的hint。本质上，编程语言也是语言，而程序代码就是说明文。在分析代码时，一定要超越语言和代码的细节去理解被说明的事物本身。&lt;/p&gt;
&lt;p&gt;4）该搜就搜&lt;br /&gt;
分析代码的时候，很容易出现的情况就是，一个执行流程走到半截找不到下一步了。。。在这种情况下，当然首先还是推荐采用各种调试工具的单步执行功能加以跟踪。如果暂时不会，或者种种原因只能进行静态代码分析，那么该搜就搜吧。各种IDE工具的文本搜索都能用，哪怕是grep也行。至于到底以什么为搜索关键词，就需要琢磨琢磨了。&lt;/p&gt;
&lt;p&gt;5）外事不决问google，内事不决问百度&lt;br /&gt;
如题，不解释。&lt;/p&gt;
&lt;h2&gt;一个例子：OpenStack Cinder分析&lt;/h2&gt;
&lt;p&gt;此处将以OpenStack Cinder为例，并结合KVM/Qemu和Ceph，说明如何参考上述思路对一个开源项目进行分析。
可能有朋友奇怪为什么选这么个东东做例子。这个吧。。。写文章是忽发起想，举例子是随手抓来。木有原因。。。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;首先，想对Cinder进行分析，一定要了解若干相关的基础知识&lt;/strong&gt;。什么是云计算？什么是块存储？什么是OpenStack？Cinder在OpenStack里的作用？等等等等。如果对这些东西没有概念，则后续学习是很难开展下去的。&lt;/p&gt;
&lt;p&gt;在此基础上，如果有条件，则最好能够亲自部署和实际操作一下Cinder（包括必要的其他OpenStack组件），以便对Cinder获得一个直观的认识和体验，为后续分析提供一些参考。此处假定Cinder使用的后端是Ceph，而OpenStack上运行的虚拟机是KVM。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;然后，应该从概念上对我们要分析的系统的逻辑框架有个理解&lt;/strong&gt;。从总体的范畴上讲，应该了解Horizon和Nova各自的逻辑模块结构，以及它们和Cinder的协同工作方式、关系。这部分与Cinder的控制接口及执行路径分析密切相关。此外，还应该了解Cinder和KVM/QEMU、Ceph之间的相互关系。这对于真正理解Cinder很有帮助。从Cinder自身而言，应该了解其内部逻辑模块构成、各自的功能、相互间的控制、数据连接关系等。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在完成上述准备之后，则可以开始对Cinder的代码进行分析了&lt;/strong&gt;。如前所述，应该考虑在控制接口和数据接口中各自选择一两个关键的、有代表性的加以分析。至于配置接口，假定其实现了某一配置即可，暂时不需要过多花费时间。
Cinder的核心功能其实是OpenStack上的volume管理。至少在Cinder+Ceph方案中，Cinder自身并不在数据传输关键路径上。因此，控制接口的分析就是Cinder源代码分析的重中之重。就入手阶段而言，则有两个接口及其对应执行流程可以作为Cinder分析的起点，即volume的create和attach操作。如果能够彻底打通这两个操作的执行流程（至少要看到Cinder与Ceph通过librbd交互的层面），则对于真正理解Cinder的功能与实现大有帮助。&lt;/p&gt;
&lt;p&gt;虽然基于KVM的虚拟机在通过QEMU访问Cinder创建的、Ceph提供的volume时并不通过Cinder，也即，这一部分的源代码其实已经超出了Cinder源代码学习的范畴，但是，如果希望真正彻底地理解Cinder，则对于这一部分知识还是应该有所涉猎，至少应该有概念上的了解。&lt;/p&gt;
&lt;p&gt;在达到上述阶段之后，则可以根据自身的需求决定后续计划了。&lt;/p&gt;
&lt;p&gt;以上就是笔者结合个人经验对开源项目学习方法给出的若干建议。见解粗浅，欢迎指正，非常感谢～&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=(%E8%BD%AC)%E5%A6%82%E4%BD%95%E5%AD%A6%E4%B9%A0%E5%BC%80%E6%BA%90%E9%A1%B9%E7%9B%AE&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-08-31-learning-the-open-source&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>为什么你写不好一个快速排序? 谈程序员的职业发展</title><link>https://blog.lhasa.icu/posts/technology/2018-08-31-programmer-development</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-08-31-programmer-development</guid><pubDate>Fri, 31 Aug 2018 01:44:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;本文转自&lt;a href=&quot;https://blogread.cn/it/article/6367?f=wb?achuan.io&quot;&gt;IT技术博客大学习&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;我常常在想，当初我若不离开完美，现在肯定也是总监级的title了，收入比现在高一倍不止。但是另一方面，在编码能力上我甚至不如某些刚毕业的本科生。比如，快速排序的算法我很熟悉，就一句话：“随机选一个元素，用它把输入集分成两半，对这两半继续递归，然后将递归得到(已排好序)的结果合并”。但几个月前看算法书的时候自己尝试写了一下快速排序，发现远远是另外一回事。虽然我对这个算法很清楚，但是用C++实现的时候充满了疑惑，写出来的代码BUG很多，调了很久才调对。相反，如果拿这个做面试题去面应届生，我相信对北大清华的学生通过率应该很高，至少过半。那么我比他们多了6-7年的工作经验，这些经验又是什么呢？&lt;/p&gt;
&lt;p&gt;工作经验是人生最容易积攒的财富，只增不减。钱和不动资产，差不多也是如此。所以要想向年轻人炫耀成功项目，牛B的经历，是很容易的事情。在一个很好的平台上，与聪明的人共事，顺水推舟，再加上运气不是太差的话，工作3-5年后，必然会有一个值得吹嘘的项目。比如我就老喜欢说我第一次做游戏就带着人做了梦诛，在线多少万多少万，等等。&lt;/p&gt;
&lt;p&gt;但是呢，对一个程序员来说，最核心的价值是什么？是&lt;strong&gt;快速的把想法，变成无bug的正确代码的能力&lt;/strong&gt;。像前面提到的快速排序，如果需求已经很明确，怎么实现已经很清楚，语言你自己选，工具你随便挑。20分钟内代码写不出来，写不对，那就是自己的问题，水平差。&lt;/p&gt;
&lt;p&gt;我之前走了一条弯路，听信软件工程的人说，不要重复造轮子。于是就忽视了这些基础训练。“不要重复造轮子“这句话在公司里是对的，但是在下班后，或是在学校，在自己写代码练手的时候，就绝对是错的。&lt;strong&gt;重写那些经典的算法，是绝佳的思维练习&lt;/strong&gt;。写二分查找的时候，需要根据区间的长度是奇数还是偶数，判断结果是大于还是小于，分成2x2=4种情况考虑，然后再想怎么缩减重复代码。写快速排序的时候，除了实现基本功能外，若是能考虑下比较时发生的相等的情况如何处理，又能把执行效率提升不少。&lt;/p&gt;
&lt;p&gt;看你想要什么。若是想挣更多的钱，谋求更高的职位(无论技术岗还是管理岗)，那么这些都和上述无关。在我现在的公司，每个程序员唯一的出路就是当架构师。这和你能不能写好快速排序没有关系，能看懂牛人写的代码，偶尔做做bug fix或者加个小模块就wonderful了！这就是我牢骚的关键点，随着地位、荣誉、薪水的提升，却逐渐忘却了作为一个程序员，最最基本、最最重要的技能是什么。医生可不像我们这样。即便那医生已经50-60岁了，即便已经是科主任了，依然要做手术主刀。一个手术一不留神做败了，半生积攒的声誉尽毁。&lt;/p&gt;
&lt;p&gt;于是我最近常在反复问自己，通过6年全职工作，我的编码能力有了多少提升？除了更喜欢用大括号把local variable局限在block level，除了更喜欢一心编码时被别人或自己打断，有什么显著、可量化的提升吗？若没有，为什么没有？&lt;/p&gt;
&lt;p&gt;我的职业梦想是，当我说自己是一个程序员的时候，熟悉我的人愿用excellent这个词来形容我。我在傲剑上班时，老板总喜欢说，你们要用自己的实际能力，去赢得同行的尊重。所以我要是下班后多花点时间去coding，总会达成我的愿望吧！&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=%E4%B8%BA%E4%BB%80%E4%B9%88%E4%BD%A0%E5%86%99%E4%B8%8D%E5%A5%BD%E4%B8%80%E4%B8%AA%E5%BF%AB%E9%80%9F%E6%8E%92%E5%BA%8F%3F%20%E8%B0%88%E7%A8%8B%E5%BA%8F%E5%91%98%E7%9A%84%E8%81%8C%E4%B8%9A%E5%8F%91%E5%B1%95&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-08-31-programmer-development&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item><item><title>Ubuntu 18.04 下安装 Sublime Text3 并解决它的疑难杂症</title><link>https://blog.lhasa.icu/posts/technology/2018-08-30-ubuntu-set-up-sublime</link><guid isPermaLink="true">https://blog.lhasa.icu/posts/technology/2018-08-30-ubuntu-set-up-sublime</guid><pubDate>Wed, 29 Aug 2018 16:01:00 GMT</pubDate><content:encoded>&lt;p&gt;接触linux这段时间真的是各种折腾，我几乎所有把流行的发行版都装了一遍，最终选择了ubuntu18.04，毕竟ui强迫症，还好社区比较强大，遇到毛病解决不会太难，初次接触它的过程中也是遇到各种问题，不过通过这几个月的学习，现在已经我可以熟练敲出各种命令并解决一些日常小毛病。没办法，生命在于折腾吧。&lt;/p&gt;
&lt;p&gt;Sublime Text3 是一款轻量级的编辑器，它干净、实用、漂亮，还有它那强大全面的插件库。不过我比较喜欢它的四个方面：跨平台、启动快、多行编辑和VIM模式。&lt;/p&gt;
&lt;p&gt;好了，我们直接入正题，按顺序执行下面命令开始安装！&lt;/p&gt;
&lt;h2&gt;一.安装篇&lt;/h2&gt;
&lt;p&gt;1.通过终端运行命令安装密钥：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;wget -qO - https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add -
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.安装apt-transport-https软件包&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install apt-transport-https
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.将Sublime Text稳定库添加到您的软件源中：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;deb https://download.sublimetext.com/ apt/stable/&quot; | sudo tee /etc/apt/sources.list.d/sublime-text.list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.更新软件源为最新版&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5.安装Sublime Text 耐心等待一会儿&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-get install sublime-text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;以上5步就安装成功了！接下来是解决Ubuntu下Sublime不能输入中文的问题！
按顺序执行一下命令！&lt;/p&gt;
&lt;p&gt;1.Git克隆项目到本地Clone&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git clone https://github.com/lyfeyaj/sublime-text-imfix.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.运行脚本&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;cd sublime-text-imfix &amp;amp;&amp;amp; ./sublime-imfix
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;执行完”运行脚本“命令后重启Sublime，就可以输入中文了！
如果还不行，你下方请留言咱们再讨论...&lt;/p&gt;
&lt;h2&gt;二.插件篇&lt;/h2&gt;
&lt;p&gt;如果说安装给予Sublime生命，那插件就是它的灵魂。Sublime拥有的插件非常全面且实用。做为一个UI强迫症的我，界面好不好看直接影响到工作的效率。下面这些插件都是我比较喜欢的，看一看说不定你也会深深爱上它。&lt;/p&gt;
&lt;p&gt;1.首先我们打开Sublime Text，按Ctrl+`（它和qq输入法快捷键冲突）&lt;/p&gt;
&lt;p&gt;2.复制粘贴以下代码添加至命令行，然后回车（它用来安装插件的工具）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import urllib.request,os; pf = &apos;Package Control.sublime-package&apos;; ipp = sublime.installed_packages_path(); urllib.request.install_opener( urllib.request.build_opener( urllib.request.ProxyHandler()) ); open(os.path.join(ipp, pf), &apos;wb&apos;).write(urllib.request.urlopen( &apos;https://sublime.wbond.net/&apos; + pf.replace(&apos; &apos;,&apos;%20&apos;)).read())
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.重启&lt;code&gt;Sublime Text&lt;/code&gt;，查看 &lt;code&gt;Perferences &amp;gt; Package settings&lt;/code&gt; 中是否有 &lt;code&gt;Package control&lt;/code&gt; （命令面板）这一项，如果有，则安装成功&lt;/p&gt;
&lt;p&gt;Package control 安装成功。方便以后更新、卸载Sublime插件啦。&lt;/p&gt;
&lt;p&gt;Package control 安装好之后打开它快捷键&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;输入&lt;code&gt;Install Package&lt;/code&gt;输入简写 IP 也可以找到一下对应的提示，选择安装包，下载安装稍等片刻左下角 状态栏&lt;/p&gt;
&lt;p&gt;下载好后会自动弹出该插件的配置信息，无需保存，关闭即可。
&lt;code&gt;Perferences &amp;gt; Package settings&lt;/code&gt;中看到对应的包名&lt;/p&gt;
&lt;p&gt;如果想要删除插件，调出命令面板输入&lt;code&gt;remove&lt;/code&gt; 调出 &lt;code&gt;Remove Package&lt;/code&gt; 选项并回车，选择你要删除的插件即可。&lt;/p&gt;
&lt;p&gt;更新插命令&lt;code&gt;upgrade packages&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;汉化Sublime，用&lt;code&gt;Package conntrol&lt;/code&gt;装第一个插件&lt;code&gt;localization&lt;/code&gt;
英文好的请略过...&lt;/p&gt;
&lt;p&gt;调出命令面板并输入&lt;code&gt;Install Package&lt;/code&gt;
然后在输入框中输入&lt;code&gt;localization&lt;/code&gt;
就会发现汉化语音的相关插件，稍微等待，自动弹出插件安装信息&lt;/p&gt;
&lt;p&gt;好了，折腾了半会儿，接下来的就是大家最喜欢的“皮肤主题和代码插件”&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# 路径提示插件，如 ![ ]()　就会出现提示，就不上图了...
AutoFileName

# 支持不被Sublime支持的文件，特别是中日韩用户使用的GB2312，GBK等
ConvertToUTF-8

# 拥有四个**高品质**的**主题**和多个配色方案
Boxy Theme

# 一个显示颜色代码的视觉颜色的插件,含颜色值的LESS,Sass,和Stylus变量,它是一个帮助您更直观处理颜色的插件
BracketHighlighter

# 修改配置路径方法如下:
Preferences -&amp;gt; Package Settings -&amp;gt; Color Highlighter -&amp;gt; Settings - User,
# 配置成如下内容： 
    {
    &quot;search_colors_in&quot;: {
        &quot;all_content&quot;: {
            &quot;enabled&quot;: true,
            &quot;color_highlighters&quot;: {
                &quot;color_scheme&quot;: {
                    # 主要是修改这两项
                    &quot;enabled&quot;: true,
                    # 填充的意思
                    &quot;highlight_style&quot;: &quot;filled&quot;
                    }
                }
            }
        }
    }
# 然后重启 Sublime 就可以了。

# 缩进，代码高亮等转换为 html 代码
Color Highlight

# 直接从Sublime Text更改主题
Colorsublime

# DocBlockr很好用，不仅仅可以自动生成注释，还可以自定义注释的格式
DocBlockr

# 修改配置路径方法如下:
Preferences -&amp;gt; Package Settings -&amp;gt; DocBlockr -&amp;gt; Settings - User,

# 配置成如下内容：
    {
    &quot;jsdocs_extra_tags&quot;:[
        &quot;@Author Hybrid&quot;,
        &quot;@DateTime {{date}}&quot;,
        &quot;@copyright ${1:[copyright]}&quot;,
        &quot;@license ${1:[license]}&quot;,
        &quot;@version ${1:[version]}&quot;
    ],
    &quot;jsdocs_function_description&quot;: false
    }

# 可以帮助 html 快速输入代码，如快速新建html头部,打出&quot;!&quot; 或者 html:5，然后按下 Tab 键或 Ctrl+E
Emmet

# 多个高品质的主题和多个配色方案
Material Theme

# 命令面板，Sublime 最重要的功能之一
Package Control

# 检查语法是否有错误
SublimeLinter

# 快捷浏览 html 文件，可以配置快捷键
View inBrowser
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;三.快捷键篇&lt;/h2&gt;
&lt;p&gt;熟练的掌握的快捷键，事半功倍！下面是一些是我认为较为实用的，并不全面。&lt;/p&gt;
&lt;h3&gt;选择类：&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 选中光标所占的文本，继续操作则会选中下一个相同的文本
Ctrl+D

# 选中文本按下快捷键，即可一次性选择全部的相同文本进行同时编辑
Alt+F3
# 先选中多行，再按下快捷键，会在每行行尾插入光标，即可同时编辑这些行
Ctrl+Shift+L

# 光标移动至括号内结束或开始的位置
Ctrl+M

# 在下一行插入新行，即使光标不在行尾，也能快速向下插入一行
Ctrl+Enter
# 在上一行插入新行。举个栗子：即使光标不在行首，也能快速向上插入一行
Ctrl+Shift+Enter

# 选中代码，按下快捷键，折叠代码
Ctrl+Shift+[
# 选中代码，按下快捷键，展开代码
Ctrl+Shift+]

# 展开所有折叠代码
Ctrl+K+0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;编辑类&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 合并选中的多行代码为一行
Ctrl+J

# 向右缩进
Tab
# 向左缩进
Shift+Tab

# 注释单行
Ctrl+/
# 注释多行
Ctrl+Shift+/ 

# 撤销
Ctrl+Z
# 恢复撤销
Ctrl+Y

# 保存
Ctrl+S
# 另存为
Ctrl+Shift+S

# 关闭文件
ctrl+W
# 重新打开最近关闭的文件
Ctrl+Shift+T
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;搜索类&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 打开底部搜索框，查找关键字
Ctrl+F
# 打开搜索框，输入项目文件名，快速搜索文件，输入@和关键字，查找文件中函数名，输入：和数字跳转到文件中该行代码，输入#和关键字，查找变量名
Ctrl+P

# 打开命令面板
Ctrl+Shift+P

# 退出光标多行选择，退出搜索框，命令面板等
Esc
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;显示类&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;# 按文件浏览过的顺序，切换当前窗口的标签页
Ctrl+Tab

# 窗口分屏，恢复默认1屏（非小键盘的数字）
Alt+Shift+1
# 左右分屏-2列
Alt+Shift+2
# 左右分屏-3列
Alt+Shift+3
# 左右分屏-4列
Alt+Shift+4

# 等分4屏
Alt+Shift+5

# 垂直分屏-2屏
Alt+Shift+8
# 垂直分屏-3屏
Alt+Shift+9
# 开启/关闭侧边栏
Ctrl+K+B

# 全屏模式
F11
# 免打扰模式
Shift+F11
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如有写的不足之处，还请您多多指教！&lt;br /&gt;
最后再秀一下我的 Sublime 感觉字体很棒，看着很舒服 嘿嘿&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;sublime.png&quot; alt=&quot; &quot; /&gt;&lt;/p&gt;
&lt;img src=&quot;https://analytics.lhasa.icu/matomo.php?idsite=1&amp;rec=1&amp;action_name=Ubuntu%2018.04%20%E4%B8%8B%E5%AE%89%E8%A3%85%20Sublime%20Text3%20%E5%B9%B6%E8%A7%A3%E5%86%B3%E5%AE%83%E7%9A%84%E7%96%91%E9%9A%BE%E6%9D%82%E7%97%87&amp;url=https%3A%2F%2Fblog.lhasa.icu%2Fposts%2Ftechnology%2F2018-08-30-ubuntu-set-up-sublime&quot; style=&quot;border:0;width:0;height:0;&quot; alt=&quot;&quot; /&gt;</content:encoded></item></channel></rss>