<?xml version="1.0" encoding="utf-8"?>


<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-CN">
    <title type="text">若星若望__</title>
    <subtitle type="html">流动的水没有形状，漂流的风找不到踪迹</subtitle>
    <updated>2024-02-26T16:05:01&#43;00:00</updated>
    <id>https://rxrw.me/</id>
    <link rel="alternate" type="text/html" href="https://rxrw.me/" />
    <link rel="self" type="application/atom&#43;xml" href="https://rxrw.me/atom.xml" />
    <author>
            <name>纠结当道</name>
            <uri>https://rxrw.me/</uri>
            
                <email>rxrw@me.com</email>
            </author>
    <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights>
    <generator uri="https://gohugo.io/" version="0.107.0">Hugo</generator>
        <entry>
            <title type="text">Notion - All in One 的写作 &amp; 协作工具</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/notion_-_all_in_one_%E7%9A%84%E5%86%99%E4%BD%9C__%E5%8D%8F%E4%BD%9C%E5%B7%A5%E5%85%B7/" />
            <id>https://rxrw.me/tech/notion_-_all_in_one_%E7%9A%84%E5%86%99%E4%BD%9C__%E5%8D%8F%E4%BD%9C%E5%B7%A5%E5%85%B7/</id>
            <updated>2022-12-11T04:45:00&#43;08:00</updated>
            <published>2022-12-10T11:43:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">前言 今天是分享工具的一篇文章，因为实在是太太太太舒服了用着。 本来是因为我司使用 Notion 作为……</summary>
            
                <content type="html">&lt;h1 id=&#34;前言&#34;&gt;前言&lt;/h1&gt;
&lt;p&gt;今天是分享工具的一篇文章，因为实在是太太太太舒服了用着。&lt;/p&gt;
&lt;p&gt;本来是因为我司使用 Notion 作为文档工具，但后来发觉这个平台——是原生支持 Markdown 语法，自带数据库，支持 API，支持协作的！这不就是个近似完美的写作平台吗！&lt;/p&gt;
&lt;p&gt;就是要钱而已。&lt;/p&gt;
&lt;h2 id=&#34;简介&#34;&gt;简介&lt;/h2&gt;
&lt;p&gt;数据库真的是这个平台的一大神器啊。。&lt;/p&gt;
&lt;p&gt;Notion 是一个很强大的平台。。有什么想添加的功能比如 todo、阅读列表等完全可以自己设计数据库去添加。而且数据库支持各种展示模式，再也不用担心没有合适的软件了。&lt;/p&gt;
&lt;p&gt;你可以认为它是一个 Markdown 编辑 + 内容整理工具。也可以认为它是一个大而全的数据库、写作平台、协作工具，它都可以。。&lt;/p&gt;
&lt;h1 id=&#34;看效果&#34;&gt;看效果&lt;/h1&gt;
&lt;p&gt;首先想让大家看一下最后我的 Notion 是什么样子的。&lt;/p&gt;
&lt;h2 id=&#34;自动发布部署博客&#34;&gt;自动发布/部署博客&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/3b189d8c-5f25-48bd-bf38-7b2740394b60/Untitled.png&#34; alt=&#34;可以自动发布到 Hugo 的 database，当然是用到了我的代码和 Notion API&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;观影记录影评&#34;&gt;观影记录/影评&lt;/h2&gt;
&lt;p&gt;灵感来自于 Notion 的模板 Reading List。但作为观影记录，只有简简单单的标题和内容实在平平无奇，不如看看这个怎么样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/54f74624-1e59-453b-98bf-9e7f6ee7c02a/Untitled.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;可以自动从 Trakt 上导入观看历史，通过 TMDB 的接口获取电影的详情，然后可以根据各种内容分类，比如&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/f01be491-7e74-4580-8dbf-b981acb010ce/Untitled.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;让写观后感成为一种享受吧。😎&lt;/p&gt;
&lt;h2 id=&#34;外卖评价&#34;&gt;外卖评价&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/e82cae28-40fc-4ae5-9305-3971a6d7e260/Untitled.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;现在的外卖 app 并不会提供这种功能，那只好自己进行记录了～&lt;/p&gt;
&lt;h2 id=&#34;旅行计划&#34;&gt;旅行计划&lt;/h2&gt;
&lt;p&gt;这是我设计一天的模板。。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/b0919329-2c55-4b02-b26f-499dbf20c863/Untitled.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/912a2572-c389-4ceb-9471-0f715040314c/Untitled.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/secure.notion-static.com/9c5b9c71-cb41-4e8e-b592-959a52f03b3b/Untitled.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;图中分享的旅行记录是我今天改了一天的模板，emm，没有特别的功能，只是以后再做旅行规划的时候，不需要乱七八糟的软件了！（之前用 tripit 和 wanderlog 纠结了很久）&lt;/p&gt;
&lt;h1 id=&#34;工具分享&#34;&gt;工具分享&lt;/h1&gt;
&lt;p&gt;分享模板的人已经很多了，我主要分享一些工具吧。。主要还是我自己做的。&lt;/p&gt;
&lt;h2 id=&#34;notion-blog&#34;&gt;Notion Blog&lt;/h2&gt;
&lt;p&gt;我把自己的博客——一个纯前端页面（hugo）使用 Github Actions 和 Notion API 实现了在 Notion 写文档，自动同步到博客页面。这个功能我还在开发，计划之后支持直接同步到知乎、小红书、微信公众号。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a href=&#34;https://github.com/rxrw/notion-blog&#34;&gt;https://github.com/rxrw/notion-blog&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;notion-blog-hugo-meme&#34;&gt;Notion Blog Hugo Meme&lt;/h2&gt;
&lt;p&gt;这是上述工具的一个模板，懒得折腾的可以直接用这个，一键建站。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a href=&#34;https://github.com/rxrw/notion-hugo-meme&#34;&gt;https://github.com/rxrw/notion-hugo-meme&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;ifttt-等&#34;&gt;iFTTT 等&lt;/h2&gt;
&lt;p&gt;通过 iFTTT 和其他同步工具，可以实现将 Notion 数据库同步到其他（国外）平台。比如我现在使用 Notion 可以将日记写好自动同步到 Day One。&lt;/p&gt;
&lt;p&gt;通过 Notion 自己支持的各种第三方工具（Github、JIRA 等），可以方便地与其他平台实现连接。比如我现在没有用任何平台。&lt;/p&gt;
&lt;h2 id=&#34;trakt&#34;&gt;Trakt&lt;/h2&gt;
&lt;p&gt;上文说的 Trakt 观影记录，是我今天简单写的一个脚本。不过支持增量同步，感兴趣可以来试一下。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a href=&#34;https://github.com/rxrw/notion-trakt&#34;&gt;https://github.com/rxrw/notion-trakt&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;evernote&#34;&gt;Evernote&lt;/h2&gt;
&lt;p&gt;Notion 目前有一个不足（我觉得也是估计这样设计）的地方在于，没有办法修改创建时间。导入进来的东西的创建时间只能是当前时间。因此，我也是利用了一些其他方法写了点代码将历史的文档导入进来。&lt;/p&gt;
&lt;p&gt;为此也有一个脚本，但这个我不解释.. 保留一点神秘。&lt;/p&gt;
&lt;p&gt;项目地址：&lt;a href=&#34;https://github.com/rxrw/md2evernote&#34;&gt;https://github.com/rxrw/md2evernote&lt;/a&gt;&lt;/p&gt;
&lt;h1 id=&#34;最后&#34;&gt;最后&lt;/h1&gt;
&lt;h2 id=&#34;总结式发言&#34;&gt;总结式发言&lt;/h2&gt;
&lt;p&gt;对于每个人来说，Notion 或者其他的内容工具是用来记录东西的，不论是文档还是日记。&lt;/p&gt;
&lt;p&gt;小红书上很多人以找到最好看的模板为乐趣，把 Notion 变成了做好了就再也不会用的手帐工具、TODO List。虽然我本身也这么做过，但很明显这是一个本末倒置的行为。&lt;/p&gt;
&lt;p&gt;对于我来说，更多的是把现有的内容从杂乱的地方整理出来。比如博客从 Git 到了 Notion 等等。在此之后，一切变得简单和直观多了后，再去想其他的吧。&lt;/p&gt;
&lt;h2 id=&#34;notion-中文社区&#34;&gt;Notion 中文社区&lt;/h2&gt;
&lt;p&gt;关于好的模板我看已经有很多人进行分享了，我是写代码的不是搞设计的。。因此，只是浅浅安利一下 Notion。毕竟，用的人越多，Notion 越赚钱才会开发新的功能（开个玩笑）。&lt;/p&gt;
&lt;p&gt;我浅浅查了一下，目前国内用 Notion 的人很多，但是基本都是单打独斗。有一个“中文社区”，但其实只是一个人的博客，而且很久不更新了。我也很希望有一个小团体可以一起建立一个官方的可持续维护的 Notion 中文站，用于分享模板、工具，以及一些日常交流。&lt;/p&gt;
&lt;p&gt;所以我先建一个电报群为敬：&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://t.me/+70w2cslubr1lYjY1&#34;&gt;https://t.me/+70w2cslubr1lYjY1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;希望能把 Notion 通过这种分享推广给更多的人～&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B-%E5%B7%A5%E5%85%B7%E5%88%86%E4%BA%AB/" term="技术 教程 工具分享" label="技术 教程 工具分享" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">北京市工作居住证办理指北 —— 14天搞定之经验总结</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E5%8C%97%E4%BA%AC%E5%B8%82%E5%B7%A5%E4%BD%9C%E5%B1%85%E4%BD%8F%E8%AF%81%E5%8A%9E%E7%90%86%E6%8C%87%E5%8C%97__14%E5%A4%A9%E6%90%9E%E5%AE%9A%E4%B9%8B%E7%BB%8F%E9%AA%8C%E6%80%BB%E7%BB%93/" />
            <id>https://rxrw.me/tech/%E5%8C%97%E4%BA%AC%E5%B8%82%E5%B7%A5%E4%BD%9C%E5%B1%85%E4%BD%8F%E8%AF%81%E5%8A%9E%E7%90%86%E6%8C%87%E5%8C%97__14%E5%A4%A9%E6%90%9E%E5%AE%9A%E4%B9%8B%E7%BB%8F%E9%AA%8C%E6%80%BB%E7%BB%93/</id>
            <updated>2022-09-26T04:37:00&#43;08:00</updated>
            <published>2022-06-14T14:27:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">先放图 用途 有很多人把居住证和工作居住证混为一谈，分不清概念。 居住证是由当地公安局户籍……</summary>
            
                <content type="html">&lt;p&gt;先放图&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/gzjzz-guide/DraggedImage.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;用途&#34;&gt;用途&lt;/h2&gt;
&lt;p&gt;有很多人把居住证和工作居住证混为一谈，分不清概念。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;居住证是由当地公安局户籍管理中心颁发的，代表此人在当地有合法住所并且长期居住。居住证是每个长期居住在异地的朋友应该有的一个证件。&lt;/li&gt;
&lt;li&gt;工作居住证是由社保局发的证件，有和北京市户口几乎同等的待遇，可以摇号买房什么的，因此很多人也管他叫北京市绿卡。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;难点&#34;&gt;难点&lt;/h2&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;需要单位配合。很多材料都需要单位 hr 盖章签字，一页一页的应税材料，看着都累。&lt;/li&gt;
&lt;li&gt;审核严格。从基本资料到详细内容，人家都是一页一页看的，几乎不存在侥幸通过的可能。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;流程说明&#34;&gt;流程说明&lt;/h2&gt;
&lt;p&gt;首先先说大体流程：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;确认单位资格。海淀区工作居住证办理指南上是这样的：&lt;code&gt;符合首都城市功能定位和经济发展方向及产业规划要求的具有法人资格的企事业单位、民办非企业单位、社会团体等，原则上应在海淀区登记注册并缴纳税费满1年。其中，具有法人资格的企业，注册资本应不低于100万元，年纳税额原则上不低于50万元（符合高精尖产业发展方向的成长型科技类企业可适当放宽条件）。&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;跟单位确认办理资格，正常的单位与人才工作网上的资格应该是一致的。不排除有些恶心人的单位（比如之前在饿了么，要求绩效达到 B+以上才可以办理），那就可以退出这篇文章了。如果是普通打工人，应该都是要满足在当前单位连续缴纳社保、个人所得税满一年，平均工资达到全市上一年度平均工资 1.2 或 1.5 倍以上的。&lt;/li&gt;
&lt;li&gt;在单位排队吧，一般来说，一个单位同一时间只能提交一个工作居住证办理申请。如果运气好的话，可能等的时间不长。我排队排了小一年。之前的那位同事办了九个月才把工作居住证办下来。咱也不知道卡在哪里了。&lt;/li&gt;
&lt;li&gt;在提交好材料后等待四次审核，据说是两次区审核两次市社保局审核。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;注册账号&#34;&gt;注册账号&lt;/h2&gt;
&lt;p&gt;登录&lt;a href=&#34;https://fw.bjrcgz.gov.cn/person-platform/#/person-platform/overview&#34;&gt;  北京市人才业务办理平台  &lt;/a&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;li&gt;现居住地址，一定要和居住证/租房合同上的地址完全一致。我虽然填的是对的，不排除很多人填写得不精确导致被拒绝。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;准备材料&#34;&gt;准备材料&lt;/h2&gt;
&lt;p&gt;关联单位在开始办理之前，是没有代码给你的，不过可以在附件管理中先准备好内容。大概要上传的是这些：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/gzjzz-guide/DraggedImage-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;包含随往人员的估计要传结婚证等其他内容。其中，应税收入材料、诚信声明、在京合法稳定住所证明都是时效性的材料，其他的可以提前准备好。&lt;/p&gt;
&lt;p&gt;我简单问过之前办了九个月的同事，为什么会办那么久。她说，隔两三个星期才会告诉她审核不通过，而且不知道审核不通过的地方是什么。于是反反复复一直在折腾。因此，准备材料是重中之重。根据本人经验，这里提供一般打工人（工作满一年这种）要准备的材料和细节。
首先说明一点，办理指南中提到的所有扫描件都要摆正，有轮廓清晰。但像很多材料都是 A4 大小的纸张，只要保证贴合扫描仪边缘即可，审查没有那么严格。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;基本资料&lt;/em&gt;。这个可以在（其实所有材料都可以在）单位通知你之前准备，不过很多有时效性的材料还是在开始办理的时候准备吧。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;户口本首页及本人页&lt;/em&gt;。一般就是联系家人把户口本到打印店扫描后发过来就可以了。首页指的是家庭情况，标有户主姓名的那页，不是「居民户口簿」那页！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;一寸白底免冠照片&lt;/em&gt;。这个大家一般手里都有，没有可以去照相馆拍照，要电子版。这个是放在个人材料里的。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;学历证书、学位证书&lt;/em&gt;。这两个上面说可以提交验证报告。事实证明，只要学信网可查，没必要提交——就是说只要你的材料是从学信网查得到的，就只传这两个证书正页的扫描件即可。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;诚信声明&lt;/em&gt;。这个在办理的材料中有模板，打印出来，你和单位人事签字盖单位公章就可以了。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;重点来了。&lt;em&gt;应税收入材料&lt;/em&gt;。由于现在的个税缴纳方式与之前不同，因此要上传《申报收入查询记录》和《个人所得税纳税记录》，访问&lt;a href=&#34;https://etax.chinatax.gov.cn/webstatic/special-app&#34;&gt;北京市电子税务局-特色应用&lt;/a&gt;里面可以「纳税记录开具」和「申报收入查询」，纳税可以一次性打出来，收入需要按年打印，这个是系统限制。这个网站奇奇怪怪的问题还比较多，经常打不开，我是用 edge+热点才打印出来的。打印好了要 hr 在每页都写上「经核真实有效」，签字盖财务章，自己也要签字。&lt;/p&gt;
&lt;/li&gt;
&lt;li&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;li&gt;住单位公房的由房屋产权单位出具房屋产权证明或租赁合同，单位出具的申请人居住证明；&lt;/li&gt;
&lt;li&gt;居住亲友住房的出具《房屋所有权证》或《不动产权证书》或商品房买卖网签合同，亲友双方签署的声明，双方身份证；&lt;/li&gt;
&lt;/ol&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;h2 id=&#34;等待审核&#34;&gt;等待审核&lt;/h2&gt;
&lt;p&gt;在单位给到关联代码了之后，就可以按流程操作了。附件已经上传好了的话，基本直接下一步到最后一页填理由就可以了。理由如实填写，比如我是为了长期生活在北京方便，就这么写就好了。
提交了之后告知单位负责办理的同事，进行第一次审核。
区级审核很快，第二天就会给出结果。基本资料和材料没什么问题，基本就会通过。然后转交给市局进行审核。
我的后两次审核时间都在每周的结束那天（有一天是调休上班），所以我估计也有可能是每周审核后统一返回结果。最后一次审核通过正好是我生日，因此还挺开心的。&lt;/p&gt;
&lt;h2 id=&#34;fq&#34;&gt;F&amp;amp;Q&lt;/h2&gt;
&lt;p&gt;Q: 哪些情况会被拒
A: 根据办事指南，如果某些期限性的材料距离到期还剩不到三个月可能会被拒，主要是一旦审核时间拉长，可能会导致最后一次审核的时候材料过期了。我的居住证期限不到三个月，但依旧审核通过了可能是因为审核比较快的原因。还有第一次被拒是因为单位应税材料没有签字盖章。。这个个人是无法检查的，也不要问，如果被拒了再找人家说。这是人情世故。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E7%94%9F%E6%B4%BB/" term="生活" label="生活" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">Zerotier - 分分钟组网工具</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/zerotier_-_%E5%88%86%E5%88%86%E9%92%9F%E7%BB%84%E7%BD%91%E5%B7%A5%E5%85%B7/" />
            <id>https://rxrw.me/tech/zerotier_-_%E5%88%86%E5%88%86%E9%92%9F%E7%BB%84%E7%BD%91%E5%B7%A5%E5%85%B7/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2022-04-29T15:16:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">之前一直在用，v2ray 服务器在内网开端口，相当于通过代理的方式访问内网，利用内网的……</summary>
            
                <content type="html">&lt;p&gt;之前一直在用，v2ray 服务器在内网开端口，相当于通过代理的方式访问内网，利用内网的 openwrt 中 smartdns 做 dns 解析服务。&lt;/p&gt;
&lt;p&gt;同事最近买了个群晖，但是家里没有公网 IP，所以一直在用 Frp 做内网穿透。但是 FRP 使用过的比较清楚，速度依靠公网服务器的带宽，而且每起一个服务都要暴露一个端口。&lt;/p&gt;
&lt;p&gt;在此之上，我进行了一番搜索，发现了一个新东西——Zerotier。&lt;/p&gt;
&lt;p&gt;这是一个类似于 ZooKeeper 的工具，一款异地组网工具。每台服务器上只需要安装对应的客户端，连接到同一个网络，就可以实现 IP 互相访问。在此之上，还有自定义 DNS 服务器的功能，将通过 IP 这个步骤转换为通过域名进行访问，相当实用。&lt;/p&gt;
&lt;p&gt;纵观国内的文章，基本都是上来就一步一步搭建，没有任何解释性说明。在几天的折腾后，搞了篇解释比较强的文章。&lt;/p&gt;
&lt;p&gt;根据 Zerotier 的官方简介，是这个意思：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Connect team members from anywhere in the world on any device.
ZeroTier creates secure networks between on-premise, cloud, desktop, and mobile devices.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;概念&#34;&gt;概念&lt;/h2&gt;
&lt;p&gt;所有的设备都是客户端，连接方式是点对点。在路由器下面的话是用 uPnP 的方式进行转发实现客户端到客户端的直接连接。如果 uPnP 没有开启，会通过传统的服务器转发的方式进行连接。&lt;/p&gt;
&lt;h3 id=&#34;earth&#34;&gt;Earth&lt;/h3&gt;
&lt;p&gt;根据其介绍，将地球上的所有设备连起来。那这里的 Earth 指的就是整体的一个服务。&lt;/p&gt;
&lt;h3 id=&#34;network&#34;&gt;Network&lt;/h3&gt;
&lt;p&gt;每一个 Network 包含的所有设备都在同一个网络里。每个网络有一个 Network ID。各客户端通过这个 ID 连接到此网络。当然，一个账号是可以创建多个网络的。&lt;/p&gt;
&lt;p&gt;网络氛围 Public 和 Private。一般我们自己组网是要用 Private，需要在页面授权设备才可以进行访问。Public 权限好像不太有人会需要吧..&lt;/p&gt;
&lt;p&gt;以下介绍的所有概念都是属于 Network 下的。&lt;/p&gt;
&lt;h3 id=&#34;planet&#34;&gt;Planet&lt;/h3&gt;
&lt;p&gt;星球嘛。指的是官方提供的服务器节点。各客户端都是通过这些服务来互相寻址的。相当于 zookeeper 的不同节点。&lt;/p&gt;
&lt;h3 id=&#34;moon&#34;&gt;Moon&lt;/h3&gt;
&lt;p&gt;自定义的 Planet。由于 Zerotier 没有国内节点，在两个设备刚开始互连的时候有可能需要通过国外的节点寻址（不过我没发现有什么慢的）导致创建连接的速度偏慢。在自己的网络里搭建 Moon 可以使连接提速。&lt;/p&gt;
&lt;h3 id=&#34;leaf&#34;&gt;Leaf&lt;/h3&gt;
&lt;p&gt;客户端。就是连接到网络上的每一个设备。其实经过测试，Moon 也是客户端的一种。这里特指没有额外功能，单纯用于连接的客户端。&lt;/p&gt;
&lt;h2 id=&#34;开始使用&#34;&gt;开始使用&lt;/h2&gt;
&lt;p&gt;Zerotier 支持基本所有设备：Windows、MacOS、iOS、Android、Linux、FreeBSD、Synology、QNAP、WD MyCloud、OpenWRT。再不济，支持 Docker，凡是能跑 Docker 能联网的设备都可以用。&lt;/p&gt;
&lt;p&gt;其中 iOS 不支持自定义 Moon，Android 的自定义 Moon 要下载非官方的 APP。&lt;/p&gt;
&lt;p&gt;本着不给自己找麻烦的原则，能用 ui 就用 ui，能一键搭建就一键搭建。给了 docker-compose 就直接用，不要折腾乱七八糟的东西。&lt;/p&gt;
&lt;h3 id=&#34;注册账号&#34;&gt;注册账号&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://my.zerotier.com/&#34;&gt;官方网站登录&lt;/a&gt;，我直接用 Github 登录。登录后发现我两年前玩过这个东西…&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/zerotier/DraggedImage.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h3 id=&#34;创建网络&#34;&gt;创建网络&lt;/h3&gt;
&lt;p&gt;不用输入任何没用的信息，上来直接创建网络，只需一次点击，网络就创建好了。&lt;/p&gt;
&lt;p&gt;记住这个 Network ID，以后会经常见到。&lt;/p&gt;
&lt;p&gt;点击网络进去，默认配置基本够用。&lt;/p&gt;
&lt;h3 id=&#34;连接客户端&#34;&gt;连接客户端&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;MacOS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;brew install zerotier-one&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://download.zerotier.com/dist/ZeroTier%20One.pkg&#34;&gt;官方下载链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;安装好后，启动。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/zerotier/DraggedImage-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;在下面输入网络 ID，点击 Join Network 即可。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Windows 的 UI 跟这个一毛一样。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;iOS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;AppStore 搜索 Zerotier，下载。点击右上角加号，输入网络 ID，OK。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;根据官网给的说明，直接运行脚本即可。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;curl -s https://install.zerotier.com | sudo bash&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;如果你安装了 GPG 密钥验证，用下面这条命令&lt;code&gt; curl -s &#39;https://raw.githubusercontent.com/zerotier/ZeroTierOne/master/doc/contact%40zerotier.com.gpg&#39; | gpg --import &amp;amp;&amp;amp; \ if z=$(curl -s &#39;https://install.zerotier.com/&#39; | gpg); then echo &amp;quot;$z&amp;quot; | sudo bash; fi&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;脚本会自动将 Zerotier 的源添加到 apt/yum 里并安装。&lt;/p&gt;
&lt;p&gt;安装好后，运行命令&lt;code&gt; sudo zerotier-cli join 你的网络ID&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;即可。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;群晖&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DSM 7 不支持 root 安装第三方程序，因此官网建议使用 Docker 来实现。英文文档在这里：&lt;a href=&#34;https://docs.zerotier.com/devices/synology/&#34;&gt;https://docs.zerotier.com/devices/synology/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;简单说就是 ROOT 权限。&lt;/p&gt;
&lt;p&gt;首先，将虚拟网卡添加到启动项：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; -e &lt;span class=&#34;s1&#34;&gt;&amp;#39;#!/bin/sh -e \ninsmod /lib/modules/tun.ko&amp;#39;&lt;/span&gt; &amp;gt; /usr/local/etc/rc.d/tun.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;chmod a+x /usr/local/etc/rc.d/tun.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;/usr/local/etc/rc.d/tun.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;以上执行后就有虚拟网卡了。然后创建 docker 容器：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker run -d           &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --name zt             &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --restart&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;always      &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --device&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;/dev/net/tun &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --net&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;host            &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --cap-add&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;NET_ADMIN   &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --cap-add&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;SYS_ADMIN   &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  -v /var/lib/zerotier-one:/var/lib/zerotier-one zerotier/zerotier-synology:latest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;启动后，执行以下加入网络&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-docker&#34; data-lang=&#34;docker&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; -it zt zerotier-cli join 你的网络ID&lt;span class=&#34;err&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;有 compose 的话，我是这么操作的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;3.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;zerotier-synology&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;container_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;zt&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;restart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;always&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;devices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;/dev/net/tun&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cap_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;NET_ADMIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;SYS_ADMIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;network_mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;s2&#34;&gt;&amp;#34;./data:/var/lib/zerotier-one&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;zerotier/zerotier-synology:latest&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;加入网络：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;docker-compose &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; zerotier-synology zerotier-cli join 你的网络ID
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;OpenWRT&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;软路由上，有一个 Zerotier 工具，启用，输入网络 ID，保存并启用即可。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;首先启用虚拟网卡（跟群晖一样，这步我还不知道怎么搞）&lt;/p&gt;
&lt;p&gt;用以下 docker compose 文件：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;3.3&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;services&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;zerotier&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;devices&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;/dev/net/tun&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;privileged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;image&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;zerotier/zerotier&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;network_mode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;host&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;cap_add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;NET_ADMIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;SYS_ADMIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;command&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;你的网络ID&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;volumes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;- &lt;span class=&#34;l&#34;&gt;./data:/var/lib/zerotier-one&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;我不知道为什么网上的人都爱用第三方很久不更新的镜像。用官方的不香吗。&lt;/p&gt;
&lt;p&gt;直接启动即可。&lt;/p&gt;
&lt;h3 id=&#34;授权&#34;&gt;授权&lt;/h3&gt;
&lt;p&gt;每一次添加了客户端后，在控制面板上会显示新设备加入，勾上前面的勾表示对这个设备授权，会给其分配 IP，显示 zerotier 客户端的版本号和物理地址。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/zerotier/DraggedImage-2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;免费版最多一个网络可以有 50 个设备。真大方.. 怎么用都够用了。&lt;/p&gt;
&lt;h3 id=&#34;使用&#34;&gt;使用&lt;/h3&gt;
&lt;p&gt;好了，这回，只要输入对应的虚拟 IP，就可以访问对应的设备了。这些设备相当于都处于同一个局域网下了。你会发现，速度相当快了。&lt;/p&gt;
&lt;h2 id=&#34;状态管理&#34;&gt;状态管理&lt;/h2&gt;
&lt;h3 id=&#34;命令行的使用&#34;&gt;命令行的使用&lt;/h3&gt;
&lt;p&gt;所有的设备都是使用 zerotier 相同源码编译的客户端。我们平时主要操作的就是 zerotier-cli。其他的，zerotier-one 是运行程序，zerotier-idtool 是生成客户端 id 使用的。zerotier-cli 要使用&lt;strong&gt;root&lt;/strong&gt;权限运行。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看所有设备&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;zerotier-cli peers&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/zerotier/DraggedImage-3.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Path 指的是连接时连接到的 IP 地址。这台机器是我最头疼的一台，它给 zerotier 的地址都是 ipv6 的，导致它的节点与其他 ipv4 的节点没办法互联，搞了我好几天了。&lt;/p&gt;
&lt;p&gt;不过也可以看见，同一内网下的话，IP 会使用内网的 IP，不需要再经历转发的流程。&lt;/p&gt;
&lt;p&gt;其中 link 代表了连接状况。DIRECT 代表可以直接连接，RELAY 代表需要转发。转发的速度当然会慢一些，因此尽量保证你的 NET 类型为 A/B。（跟 switch 学来的）这里我还没有细致研究，不过只要你的路由器支持 uPnP，一般都是直连。&lt;/p&gt;
&lt;p&gt;这里有连接方式的官方介绍，我懒得看：&lt;a href=&#34;https://docs.zerotier.com/zerotier/troubleshooting#recommended-local-network-and-internet-gateway-configuration&#34;&gt;https://docs.zerotier.com/zerotier/troubleshooting#recommended-local-network-and-internet-gateway-configuration&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看网络&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;zerotier-cli listnetworks&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/zerotier/DraggedImage-4.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;这里有以下信息：网络 ID、名称、本机的虚拟 IP 地址，和网络状态。其中，网络状态 OK 表示正常，REQUEST_CONFIGURATION 表示没有 uPNP，连不上，ACCESS_DENIED 表示还没有授权。其他的状态我还没见过。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;查看连接情况&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;zerotier-cli info
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;高级&#34;&gt;高级&lt;/h2&gt;
&lt;h3 id=&#34;自定义-moon&#34;&gt;自定义 Moon&lt;/h3&gt;
&lt;p&gt;任何一个节点都可以作为 Moon 使用。当然，正常的我们肯定会选择公网 IP 的节点，一般都会使用云服务器。&lt;/p&gt;
&lt;p&gt;官方文档在这里：&lt;a href=&#34;https://docs.zerotier.com/zerotier/moons&#34;&gt;https://docs.zerotier.com/zerotier/moons&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;那么第一步就是搞一台云服务器，在上面连接好网络。&lt;/p&gt;
&lt;p&gt;进入配置文件夹，linux 上的是&lt;code&gt;/var/lib/zerotier-one&lt;/code&gt;。执行&lt;code&gt;zerotier-idtool initmoon identity.public &amp;gt;&amp;gt;moon.json&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;打开的文件大概长这个样子：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deadbeef00&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;objtype&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;world&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;roots&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;identity&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;deadbeef00:0:34031483094...&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;nt&#34;&gt;&amp;#34;stableEndpoints&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;signingKey&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;b324d84cec708d1b51d5ac03e75afba501a12e2124705ec34a614bf8f9b2c800f44d9824ad3ab2e3da1ac52ecb39ac052ce3f54e58d8944b52632eb6d671d0e0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;signingKey_SECRET&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ffc5dd0b2baf1c9b220d1c9cb39633f9e2151cf350a6d0e67c913f8952bafaf3671d2226388e1406e7670dc645851bf7d3643da701fd4599fedb9914c3918db3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;updatesMustBeSignedBy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;b324d84cec708d1b51d5ac03e75afba501a12e2124705ec34a614bf8f9b2c800f44d9824ad3ab2e3da1ac52ecb39ac052ce3f54e58d8944b52632eb6d671d0e0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nt&#34;&gt;&amp;#34;worldType&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;moon&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">Github Copilot —— 全自动写代码的神器</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/github_copilot__%E5%85%A8%E8%87%AA%E5%8A%A8%E5%86%99%E4%BB%A3%E7%A0%81%E7%9A%84%E7%A5%9E%E5%99%A8/" />
            <id>https://rxrw.me/tech/github_copilot__%E5%85%A8%E8%87%AA%E5%8A%A8%E5%86%99%E4%BB%A3%E7%A0%81%E7%9A%84%E7%A5%9E%E5%99%A8/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2022-04-08T12:05:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">代码提示真的是经历了从 0 到 1 到 2 的蜕变啊。。 我记得刚学代码时，还是用记事本，note……</summary>
            
                <content type="html">&lt;p&gt;代码提示真的是经历了从 0 到 1 到 2 的蜕变啊。。&lt;/p&gt;
&lt;p&gt;我记得刚学代码时，还是用记事本，notepad++写代码的时代，大括号、语法全靠自己检查。&lt;/p&gt;
&lt;p&gt;后来知道有了 sublime text，象征性地给&lt;code&gt;function&lt;/code&gt;，&lt;code&gt;public&lt;/code&gt;等公用关键字标记颜色，大括号检查的编辑器。&lt;/p&gt;
&lt;p&gt;再后来，用了 IDE，比如 PHPStorm、Eclipse、Android Studio 等工具，根据语言特性和依赖分析可以自动补全。&lt;/p&gt;
&lt;p&gt;2020 年，leader 告诉我们有个叫 tabnine 的工具，根据 AI 算法，可以学习自己写过的东西，对代码进行补全。一直用到了上个月。&lt;/p&gt;
&lt;p&gt;虽然补全的东西经常驴唇不对狗肉，但也算能用。&lt;/p&gt;
&lt;p&gt;直到之前在抖音上刷到的&lt;a href=&#34;https://copilot.github.com/&#34;&gt;Github Copilot&lt;/a&gt;。。。&lt;/p&gt;
&lt;p&gt;微软也是够可以的，把 Github 全部的公开代码全部爬了一遍，大概官方给的示例长这样：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/github-poilot/DraggedImage.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;我本以为仅限于此，就是补充一些公用的算法等等，而且所说支持的语言有限，Java、Go、Python、Js 等等，不过我也申请了内测，第三天收到内测资格试用了一下，出乎意料。。&lt;/p&gt;
&lt;h2 id=&#34;支持语言&#34;&gt;支持语言&lt;/h2&gt;
&lt;p&gt;不止官方所说的那几种，我感觉全部语言，它都能编。&lt;/p&gt;
&lt;p&gt;公司主力语言是 PHP，我写 APP 用 dart，都支持。&lt;/p&gt;
&lt;p&gt;由此类推，应该是支持全部语言的吧。。&lt;/p&gt;
&lt;h2 id=&#34;支持注释生成代码&#34;&gt;支持注释生成代码&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/github-poilot/DraggedImage-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;注释甚至都不是我写的。。我只是写了个&lt;code&gt;create a table named posts&lt;/code&gt;，后面完全是 copilot 提示出来的。&lt;/p&gt;
&lt;h2 id=&#34;根据函数名写代码&#34;&gt;根据函数名写代码&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/github-poilot/DraggedImage-2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;上下文推断&#34;&gt;上下文推断&lt;/h2&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/github-poilot/DraggedImage-3.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;现在，有懒得写的代码，比如 Flutter 中的复杂布局，交给 Copilot，我只需要在注释里写好想干嘛，就 ok 了。。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E5%B7%A5%E5%85%B7%E5%88%86%E4%BA%AB/" term="技术 工具分享" label="技术 工具分享" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">MySQL 数据库的事务性（InnoDB）</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/mysql_%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%BA%8B%E5%8A%A1%E6%80%A7innodb/" />
            <id>https://rxrw.me/tech/mysql_%E6%95%B0%E6%8D%AE%E5%BA%93%E7%9A%84%E4%BA%8B%E5%8A%A1%E6%80%A7innodb/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2022-01-21T09:16:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">只有 InnoDB 引擎才支持 MySQL 的事务（transaction）。 事务用于维护数据库的完整性，保证……</summary>
            
                <content type="html">&lt;p&gt;只有 InnoDB 引擎才支持 MySQL 的事务（transaction）。&lt;/p&gt;
&lt;p&gt;事务用于维护数据库的完整性，保证 SQL 语句要么全部执行，要么全部不执行。&lt;/p&gt;
&lt;p&gt;每一条语句都是一个事务。&lt;/p&gt;
&lt;h2 id=&#34;mysql-事务性的特点acid&#34;&gt;MySQL 事务性的特点（ACID）&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;原子性（Atomicity，不可分割性） 一个事务中的所有操作，要么全部完成，要么全部不完成，不会结束在中间某个环节。事务在执行过程中发生错误，会被回滚（rollback）到事务开始前的状态，就像这个事务从来没有被执行过一样。&lt;/li&gt;
&lt;li&gt;一致性（Consistency） 事务开始和结束前后，数据库的完整性没有被破坏。&lt;/li&gt;
&lt;li&gt;隔离性（Isolation，又称独立性） 数据库允许多个并发事务同时对其数据进行读写和修改的能力。隔离性可以防止多个事务并发执行时由于交叉执行而导致的数据不一致。事务隔离分为不同级别，包括读未提交（Read Uncommitted）、读已提交（Read Committed）、可重复读（Repeatable Read）、串行化（Serializable）。&lt;/li&gt;
&lt;li&gt;持久性（Durability） 事务处理结束后，对数据的修改是永久的，即使系统故障也不会丢失。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;如何保证-acid&#34;&gt;如何保证 ACID&lt;/h2&gt;
&lt;h3 id=&#34;原子性的保证&#34;&gt;原子性的保证&lt;/h3&gt;
&lt;p&gt;MySQL 的原子性是利用 InnoDB 的 &lt;code&gt;Undo Log&lt;/code&gt; 来实现的。&lt;/p&gt;
&lt;p&gt;Undo Log：回滚日志。提供回滚和多个行版本控制（MVCC）。&lt;/p&gt;
&lt;p&gt;当数据需要回滚时，使用 Undo Log 进行回滚。当 delete 一条记录时，记录一条相反的 Insert 记录；update 一条记录时，记录一条相反的 update 记录；insert 一条记录时，记录一条 delete 记录。进行 rollback 时，便可根据逻辑记录反向执行语句。&lt;/p&gt;
&lt;p&gt;若需要行版本控制，即某一行被其他事务锁定时，它可以从 Undo Log 中分析出以前的数据是什么，从而提供该行版本信息，让用户实现非锁定一致性读取。&lt;/p&gt;
&lt;p&gt;事务提交的时候，InnoDB 不会立即删除 Undo Log。但会将事务对应的 Undo Log 放入删除列表中，未来通过 &lt;code&gt;purge&lt;/code&gt; 来删除。提交事务时，会判断 Undo Log 分配的页是否可以重用。如果可以，则会分配给后面来的事务，避免浪费存储空间和性能。&lt;/p&gt;
&lt;p&gt;根据 Undo Log 记录分析 delete 和 update 操作：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;delete 操作不会立即删除数据，而是将 delete 对象打上 flag，最终的删除操作是 purge 线程完成的。&lt;/li&gt;
&lt;li&gt;update 非主键列是直接进行的。&lt;/li&gt;
&lt;li&gt;update 主键列是先删除该行，再插入一行目标行。&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;一致性的保证&#34;&gt;一致性的保证&lt;/h3&gt;
&lt;p&gt;通过其他三个特性来保证一致性。为了保证一致性，才会有其他三种特性。&lt;/p&gt;
&lt;h3 id=&#34;隔离性的保证&#34;&gt;隔离性的保证&lt;/h3&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;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;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;读已提交（read-committed）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;是&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;可重复读（repeatable-read）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;否&lt;/td&gt;
&lt;td&gt;串行化（serializable）&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;读未提交&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;事务 B 读数据，事务 A 修改了数据没有提交，事务 B 可以看到 A 还未修改的数据。而此时若 A 回滚，B 读到的就是脏数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读已提交&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;事务 B 读数据，事务 A 修改了数据没有提交，B 读到的是 A 修改前的数据。解决了脏读。&lt;/p&gt;
&lt;p&gt;但当事务 A 修改了数据提交后，B 再次查询，得到的数据是 A 提交后的数据，不一致。产生了不可重复读的数据。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;可重复读&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;使用了快照读的方式，通过 MVVC 机制（Undo Log），读取了事务提交前的数据。&lt;/p&gt;
&lt;p&gt;可重复读通过以下方式解决了幻读问题：检索条件有索引时，使用 Next-Key 锁，没有索引时锁表。（Next-Key：间隙锁，其他事务不能在这个间隙插入记录）&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;串行读&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;同时只能有一个事务读取数据。&lt;/p&gt;
&lt;h3 id=&#34;持久性的保证&#34;&gt;持久性的保证&lt;/h3&gt;
&lt;p&gt;利用 InnoDB 的 &lt;code&gt;Redo Log&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;Redo Log 分别内存中的日志缓冲区（Redo Log Buffer）和磁盘上的重做日志文件（Redo Log File）。前者为易失的，后者为持久的。&lt;/p&gt;
&lt;p&gt;在事务提交时，首先要记录日志，即写入磁盘上的 Redo Log File 和 Undo Log File 进行持久化。每次写入的过程都会调用一次系统的&lt;code&gt;fsync&lt;/code&gt;，用于将 OS Buffer 中的日志刷到磁盘上。记录 Redo Log 后才会提交事务。&lt;/p&gt;
&lt;p&gt;一般所说的 Log File 是操作系统缓存中的 Log File，不是磁盘上的。&lt;/p&gt;
&lt;p&gt;LSN 代表事务写入重做日志字节的总量，单位为字节。LSN 同时记录在重做日志和每个页中。数据库启动时，InnoDB 检测写入重做日志中的 LSN。如果重做日志中的 LSN 大于页上的 LSN 并且已经提交，那么数据库需要进行回复操作，将重做日志应用到页中。否则不需要。&lt;/p&gt;
&lt;p&gt;Redo Log 是物理日志。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/mysql-%E5%9F%BA%E7%A1%80%E7%9F%A5%E8%AF%86-%E6%95%B0%E6%8D%AE%E5%BA%93/" term="MySQL 基础知识 数据库" label="MySQL 基础知识 数据库" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">编程语言发展 &amp; 中文编程的相关讨论</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%E5%8F%91%E5%B1%95__%E4%B8%AD%E6%96%87%E7%BC%96%E7%A8%8B%E7%9A%84%E7%9B%B8%E5%85%B3%E8%AE%A8%E8%AE%BA/" />
            <id>https://rxrw.me/tech/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80%E5%8F%91%E5%B1%95__%E4%B8%AD%E6%96%87%E7%BC%96%E7%A8%8B%E7%9A%84%E7%9B%B8%E5%85%B3%E8%AE%A8%E8%AE%BA/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2022-01-21T07:28:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">背景 不知道为什么最近知乎上经常能刷到中文编程的前景如何的，本来不想浪费时间回答这种问……</summary>
            
                <content type="html">&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;不知道为什么最近知乎上经常能刷到中文编程的前景如何的，本来不想浪费时间回答这种问题。但看到太多不太动脑子就回答，就像不动脑子就说鸿蒙不是安卓套壳一样，实在难以理解。&lt;/p&gt;
&lt;p&gt;我不是计算机专业，没有完整地了解过计算机组成原理，但是电子信息工程稍微知道一些，因此用词、逻辑不一定十分准确，欢迎指正，但请勿杠。&lt;/p&gt;
&lt;h2 id=&#34;历史&#34;&gt;历史&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;机器指令码&lt;/strong&gt;：众所周知，CPU 作为电子设备的计算核心，是用逻辑门也就是电子元件的通电与否来表示状态的。通过海量的元件组成了计算逻辑，对于我们来说就是 0 和 1 的二进制。在编程界叫做机器指令码。日常写代码时用 16 进制表示。当年比克盖茨就是靠给别人写机器码，输入计算机来赚钱的。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/programming-language-and-chinese/DraggedImage.tiff&#34; alt=&#34;网上随便找的图，应该是某程序反编译回来的机器指令&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;汇编语言&lt;/strong&gt;：随着程序越来越复杂，这些指令是在令人难受。于是有人用机器码写了一个程序。开发者将简单的英文字母输入到这个程序里，这个程序就会将这些英文字母转换成机器指令来执行。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/programming-language-and-chinese/DraggedImage-1.tiff&#34; alt=&#34;依旧随便找的，汇编语言的简单程序。&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高级语言（C/C++）&lt;/strong&gt;：汇编语言也很复杂，因为指令简单所以写起来复杂。而且，上述语言对机器 CPU 指令集有着极强的一致性要求，同一段程序放在不同的 CPU 上，是不能正常运行的。第一个高级语言叫做 FORTRAN，目前依旧在使用。但是由于离我们不叫远，不多介绍。随后，1969 年，B 语言诞生。但由于其没有数据类型的概念，无法表示字符等信息。随后，1971 年开始，改进后的 C 语言诞生了。这也是目前大部分高级语言的底子。相对于前两者，C 语言的特性就是用比较自然化的指令去描述程序，通过不同平台的编译器，对不同 CPU 进行了跨平台兼容。也就是不需要修改程序就可以运行程序了。C 语言的工作流程，就是代码检查.c-编译为汇编语言.o-将不同依赖链接到一起生成可执行文件。C 语言上到自然语言，下到内存汇编，因此很多操作系统也是用 C 语言写的。C 语言是面向过程的语言，跟汇编、机器指令一样。后来随着工程量变大，结构变复杂，又出现了 C++这种面向对象的编程语言。不展开了。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;高级语言（Java 等一切日常看得见的语言）&lt;/strong&gt;： C 语言是可以直接操作硬件的。。而且内存回收等机制不完善。给了开发者很大的自由，也就给了开发者很大的错误空间。C++本质上是 C 语言扩充了面向对象的功能，上述说的也没有完善。并且其本身也不是完全面向对象的。此外，对不同机器上 int 长度不同这种事情也是个问题。因此，更多的语言逐渐诞生了。首当其冲就是 Java，前身是 Oak，现在的实现是，利用 C++在不同的平台上编写 JVM 虚拟机，将 Java 编译成虚拟机可识别的字节码来运行。也可以说是跑在 C++上的语言。借此，Java 成为了第一个一套代码全兼容的开发语言。
当然，说到自然语言，没有比 python 更直观的语言了。不过，像 python、php 这种语言，底层均是由 C 语言和汇编语言组成的。这也就是为什么源码编译（也就是 C 语言的编译过程）一定要有 GCC。他们的标准库、各种库都是由 C 语言/C++写的（比如 php 扩展）。由此我们才说这些语言是基于 C 语言的。像 Java 运行起来已经看不到 C 语言的影子了。
golang 属于比较特别的。其实它最初的底层也是 C+汇编。不过随后，开发者用 go 语言实现了 gcc 编译器的功能。也就是说，它可以用自己的编译器编译自己的代码，也就脱离了 c 语言，实现了“自举”。C 语言也是当初汇编语言写出后实现的自举。&lt;/p&gt;
&lt;h2 id=&#34;现状&#34;&gt;现状&lt;/h2&gt;
&lt;p&gt;上面比较简单地说了一下目前的语言和发展过程。现在的语言基本都是开源的，比如 python、php、go 等等。我们写代码时，所谓的复制粘贴，更多的是在网上找开源的库避免实现同一复杂功能。因此，各流行语言都有自己的包管理工具，比如 python 的 pypi、go 的 mod、php 的 composer(这个不是官方，官方应该是扩展 pecl)、swift 的 swift package manager 等等。通过设计模式和业务相结合，利用各种工具带来的便捷，实现了各种各样的功能。&lt;/p&gt;
&lt;p&gt;那么问题来了：中文编程现实么？&lt;/p&gt;
&lt;p&gt;先说结论，也是必然：不可能。即使有，也只是昙花一现，获取不了正常的开发者。&lt;/p&gt;
&lt;h2 id=&#34;为什么中文不能作为编程语言&#34;&gt;为什么中文不能作为编程语言&lt;/h2&gt;
&lt;p&gt;先看一个网站：&lt;a href=&#34;https://www.wikihow.com/Create-a-Programming-Language&#34;&gt;https://www.wikihow.com/Create-a-Programming-Language&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;不好意思又是英文的。&lt;/p&gt;
&lt;p&gt;听着有些难受，但是，上述的内容，都是外国人做的。当然，随着开源的进程，我们国内的开发者对各种语言均有不同程度的贡献。&lt;/p&gt;
&lt;p&gt;我们现在知道了目前流行语言编程的步骤，其语言的语法结构、产生模式，那么设计一门编程语言，是不是轻而易举了呢？&lt;/p&gt;
&lt;h3 id=&#34;高级语言层&#34;&gt;高级语言层&lt;/h3&gt;
&lt;p&gt;在这里用高级语言去代表 C 语言除外的高级语言，以便于区分。&lt;/p&gt;
&lt;p&gt;这层是必然可以实现的。有一个叫做易语言的东西。我没用过。据百度百科介绍（看起来也是易语言公司的人写的），其支持可视化编程、多语言兼容等等。其实无非是 VB 套壳，可以调用其他语言的可执行文件。本质不能算是目前讨论的编程语言。而且这属于一个公司的一个产品，要收费的。&lt;/p&gt;
&lt;p&gt;此外，其实利用中文写代码，通过 gcc 的编译器翻译成汇编（编译型语言），或者直接调用 C 语言编写的的扩展库（脚本语言）来实现功能，这个是可行的。不过在不同机器上，就要考虑编码问题。我们也知道，计算机目前的字节编码已经从 ASCII 过渡到 utf8 了。其目的就是为了兼容 unicode 字符，也就是除了英文、数字和常见标点符号之类的内容。这会是写这个编译器比较复杂的地方。而且，编译器将会有大量的英文代码用来将中文转成英文。如果这是这些人所谓的编程语言，那你们赢了。&lt;/p&gt;
&lt;h3 id=&#34;c-语言汇编语言&#34;&gt;C 语言/汇编语言&lt;/h3&gt;
&lt;p&gt;单说编码问题就不现实&amp;hellip;&lt;/p&gt;
&lt;p&gt;u 还是上面的问题。utf8 是占多字节的，汇编语言是不可能将中文直接转为字节码的。&lt;/p&gt;
&lt;h3 id=&#34;机器语言&#34;&gt;机器语言&lt;/h3&gt;
&lt;p&gt;机器语言本身就不存在语种的问题。不过我们平时表示的时候会用十六进制表示，比如 0xfa，其实机器识别的还是二进制，十六进制只是一个易于阅读的表示方法而已。这里如果你愿意用中文表示那就随你了。。&lt;/p&gt;
&lt;h3 id=&#34;日常认知&#34;&gt;日常认知&lt;/h3&gt;
&lt;p&gt;最简单地举个例子，以下是一段最简单的 C++代码：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;#&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;include&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;iostream&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;namespace&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;std&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kr&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;cout&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;Hello, World!&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果直接用中文表示是这样的：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;提示包括标准库&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;《&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;输入输出流&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;》&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;使用&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;命名空间&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;标准&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;整型&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;入口函数&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;（）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;「&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;输出以下内容&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;《&lt;/span&gt; &lt;span class=&#34;err&#34;&gt;“&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;你好世界&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;”；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nx&#34;&gt;返回&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;；&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;」&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果按某些人说的，按我们中文的语义进行翻译的话：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-javascript&#34; data-lang=&#34;javascript&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;使用&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;《&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;出入流&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;》&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;这个库&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;使用&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;“&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;标准&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;”&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;这个命名空间&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;叫入口函数并且不接收参数返回整数的函数如下&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;：&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;把&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;“&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;你好世界&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;”&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;传递给标准库里的输出函数&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;然后函数结束&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;正常返回&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;。&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;不知道各位想看到的是哪种写法呢？&lt;/p&gt;
&lt;p&gt;换一个所有语言都有的循环，&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;++&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;	&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;中文：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;使用库《格式化》&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;对于（定义循环标志为&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，当循环标志小于&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;的时候，每次循环结束后循环标志加&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;使用格式化库的打印方法输出循环标志&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;以上。我已经尽量语义化了。&lt;/p&gt;
&lt;p&gt;这是你们想要的中文编程吗？&lt;/p&gt;
&lt;p&gt;如果有人想说“是”的话，那接下来，请问单纯说最后一个循环的中文，怎么写在你的编辑器里？&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;shiyong1ku&lt;/span&gt;  &lt;span class=&#34;err&#34;&gt;《&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;geshihua&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;》&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;duiyu&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;（&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dingyi&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xunhuan&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;biaozhi&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;wei20&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dang&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xunhuanbiaozhi&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xiaoyu&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;deshihou&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;，&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;meici&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xunhuanjieshuhou&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xunhuanbiaozhi&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;jia1&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;）&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;shiyong&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;geshihua&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ku&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;de&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dayinfangfa&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;shuchu&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;xunhuanbiaozhi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;以上。&lt;/p&gt;
&lt;p&gt;好玩吗？？？&lt;/p&gt;
&lt;p&gt;一帮不会编程的人在那做梦，疯了？&lt;/p&gt;
&lt;p&gt;请问你打算在写这段文字的时候是用英文开发的搜狗拼音输入法还是英文开发的微软拼音输入法呢？&lt;/p&gt;
&lt;h3 id=&#34;结论&#34;&gt;结论&lt;/h3&gt;
&lt;p&gt;有人喜欢乱扣帽子，比如以下：&lt;/p&gt;
&lt;p&gt;我的回答是这样的：&lt;/p&gt;
&lt;p&gt;这 zz 给我的反驳是这样的：&lt;/p&gt;
&lt;p&gt;链接在这：&lt;a href=&#34;https://www.zhihu.com/question/512297310/answer/2318423686&#34;&gt;https://www.zhihu.com/question/512297310/answer/2318423686&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/programming-language-and-chinese/DraggedImage.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/programming-language-and-chinese/DraggedImage-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;这位自己的回答是这样的：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/programming-language-and-chinese/DraggedImage-2.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;是否为计算机专业与学习英文有任何的关系吗？编程中出现的英文，别说四级，但凡有能力考上全日制普通大学都知道是什么意思吧？&lt;/p&gt;
&lt;p&gt;之前怼过的话我就不再重复了。接下来是教学时间：&lt;/p&gt;
&lt;p&gt;截止到目前，所有的编程语言中都有以下关键字：&lt;/p&gt;
&lt;p&gt;for、while、if、else、return。&lt;/p&gt;
&lt;p&gt;普遍出现的有：&lt;/p&gt;
&lt;p&gt;int、string、float、double、var、let、const、null、class、func(tion)、struct、use、print、do、try、catch、finally、foreach、range、public、protected、private、extends、implement、interface、trait、override..&lt;/p&gt;
&lt;p&gt;这已经包含了大部分语言的大部分关键字了。&lt;/p&gt;
&lt;p&gt;连超过 10 个字母的单词都没有哎，学不会？&lt;/p&gt;
&lt;p&gt;有人好像会说，我们中国人就要有自己的编程语言。&lt;/p&gt;
&lt;p&gt;如果你能发明真正的中文键盘，重设计中文汇编语言、中文指令集定义、再上升到高级语言、编译器，适合所有人的中文语法结构，你牛。然而即使真的设计出来了，谁会采用？谁会为了你这个独树一帜的想法买单，抛弃原有成熟的架构、语法、库，从复杂的中文中选出合适的字词当作关键字写代码来为了你们骄傲？&lt;/p&gt;
&lt;p&gt;有需求才会有市场，在现今相对饱和，完全满足当下需求的开发界，要搞中文编程，对此，我只想说仨字，闲的。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;9
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// 东北话版hello world
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;给我整个个打字儿的&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;再给我整个差不离儿的流儿&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;开整吧&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;给我整个世界&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;整完了，再见&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF%E6%97%A5%E5%B8%B8-%E5%90%90%E6%A7%BD/" term="技术日常 吐槽" label="技术日常 吐槽" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">Fig - 不知道干什么但莫名好用的命令行工具</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/fig_-_%E4%B8%8D%E7%9F%A5%E9%81%93%E5%B9%B2%E4%BB%80%E4%B9%88%E4%BD%86%E8%8E%AB%E5%90%8D%E5%A5%BD%E7%94%A8%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7/" />
            <id>https://rxrw.me/tech/fig_-_%E4%B8%8D%E7%9F%A5%E9%81%93%E5%B9%B2%E4%BB%80%E4%B9%88%E4%BD%86%E8%8E%AB%E5%90%8D%E5%A5%BD%E7%94%A8%E7%9A%84%E5%91%BD%E4%BB%A4%E8%A1%8C%E5%B7%A5%E5%85%B7/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-12-16T06:57:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">今天翻推特，看见了一个这样的图片 好像是可以统计 终端下 每个命令敲击的次数，然后我闲的无……</summary>
            
                <content type="html">&lt;p&gt;今天翻推特，看见了一个这样的图片&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/fig/FGjbuIPX0AQ2ox1.jpeg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;好像是可以统计 终端下 每个命令敲击的次数，然后我闲的无聊 &lt;code&gt;brew install fig&lt;/code&gt; 了一下，忽然发现 brew 终于可以不用来回思考要不要加 &amp;ndash;cask 了。&lt;/p&gt;
&lt;p&gt;安装好后，是个 gui 界面，跟着说明激活了命令行的快捷方式。&lt;/p&gt;
&lt;p&gt;支持代码提示，历史记录等智能提示。&lt;/p&gt;
&lt;p&gt;用起来第一感觉有点像 &lt;code&gt;zsh-autosuggestion&lt;/code&gt; ，但是比这个要强大得多。它内置/也有可能是读取了各个命令的 help，在下拉列表中选择命令和参数的时候下面还会出现命令相关的说明。&lt;/p&gt;
&lt;p&gt;只不过 ssh 估计目前的情况来看是暂时没人会支持了。。&lt;/p&gt;
&lt;p&gt;上个图好了&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/fig/WX20211216-150519.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;主要是太久没发东西了。。阿里云一个月 34 呢。&lt;/p&gt;
&lt;p&gt;又看见了 vscode 上的一个插件，frontmatter，是我见过唯一支持 hugo 编辑的东西了。。还挺顺的&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E5%B7%A5%E5%85%B7%E5%88%86%E4%BA%AB/" term="技术 工具分享" label="技术 工具分享" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">从pt到家庭媒体中心全攻略（补充）（用Emby看电视直播，居然比用电视看电视还爽）</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E8%A1%A5%E5%85%85%E7%94%A8emby%E7%9C%8B%E7%94%B5%E8%A7%86%E7%9B%B4%E6%92%AD%E5%B1%85%E7%84%B6%E6%AF%94%E7%94%A8%E7%94%B5%E8%A7%86%E7%9C%8B%E7%94%B5%E8%A7%86%E8%BF%98%E7%88%BD/" />
            <id>https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E8%A1%A5%E5%85%85%E7%94%A8emby%E7%9C%8B%E7%94%B5%E8%A7%86%E7%9B%B4%E6%92%AD%E5%B1%85%E7%84%B6%E6%AF%94%E7%94%A8%E7%94%B5%E8%A7%86%E7%9C%8B%E7%94%B5%E8%A7%86%E8%BF%98%E7%88%BD/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-09-28T12:16:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">今天一时冲动买了 Emby Premiere Lifetime 会员。。 既然买了，会员专用的功能肯定要体验一下。 之前一直因为找……</summary>
            
                <content type="html">&lt;p&gt;今天一时冲动买了 Emby Premiere Lifetime 会员。。&lt;/p&gt;
&lt;p&gt;既然买了，会员专用的功能肯定要体验一下。&lt;/p&gt;
&lt;p&gt;之前一直因为找不到合适的 IPTV 源，没有玩过电视直播。今天发现居然有大佬一直在维护炒鸡牛鼻的地址源。先看效果。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-4/PastedGraphic1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-4/G.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;从外网看的，丝毫不卡。&lt;/p&gt;
&lt;p&gt;Emby 本身还是支持电视节目录制的。我&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-4/PastedGraphic3.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;还可以按计划录制。不过偏偏今天新闻联播时间延长了，导致节目单有些冲突。&lt;/p&gt;
&lt;p&gt;可以查看同时在播的其他频道&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-4/PastedGraphic4.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;如何配置呢。。 算了要花钱买会员的，也懒得讲。。之前的文章都没人看。不说了，得瑟一下算了。&lt;/p&gt;
&lt;p&gt;看看现在媒体中心运行的服务们：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-4/Necmter.bteler.1mtrypoint.th.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;从上至下依次是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;emby 播放服务器&lt;/li&gt;
&lt;li&gt;lidarr 音乐搜刮&lt;/li&gt;
&lt;li&gt;bthelper pt 站自动辅种&lt;/li&gt;
&lt;li&gt;flaresolverr 搜刮器的辅助工具&lt;/li&gt;
&lt;li&gt;flexget rss 自动搜刮，用于柯南最新集的下载&lt;/li&gt;
&lt;li&gt;logtail 看日志&lt;/li&gt;
&lt;li&gt;m3u 本来是一个 python 搜刮最新直播源的，但是发现了更厉害的源&lt;/li&gt;
&lt;li&gt;p3 搜刮器&lt;/li&gt;
&lt;li&gt;readarr 电子书搜刮，至今没有下载一本书&lt;/li&gt;
&lt;li&gt;subfinder 根据字幕下载器自己编写的 docker 版字幕搜刮&lt;/li&gt;
&lt;li&gt;radarr 电影搜刮&lt;/li&gt;
&lt;li&gt;sonarr 剧集搜刮&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;666&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B-pt/" term="技术 教程 pt" label="技术 教程 pt" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">选择合适的用户系统 - cas、keyclock、authz、authing等的对比</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E9%80%89%E6%8B%A9%E5%90%88%E9%80%82%E7%9A%84%E7%94%A8%E6%88%B7%E7%B3%BB%E7%BB%9F_-_caskeyclockauthzauthing%E7%AD%89%E7%9A%84%E5%AF%B9%E6%AF%94/" />
            <id>https://rxrw.me/tech/%E9%80%89%E6%8B%A9%E5%90%88%E9%80%82%E7%9A%84%E7%94%A8%E6%88%B7%E7%B3%BB%E7%BB%9F_-_caskeyclockauthzauthing%E7%AD%89%E7%9A%84%E5%AF%B9%E6%AF%94/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-09-17T08:34:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">从我刚开始学习互联网方面的编程开始，无论是写什么项目（除了微信公众号的消息收发），用……</summary>
            
                <content type="html">&lt;p&gt;从我刚开始学习互联网方面的编程开始，无论是写什么项目（除了微信公众号的消息收发），用户都是一个耗时间、耗精力而又无法保证开发最终稳定、无法复用的功能。对于每个业务需求，有一半的时间都是去做用户系统。从最开始的原生 PHP 手写笨拙的注册流程和表单，到 ThinkPHP（呕），再到后来的 Laravel 开箱即用的认证模块——虽然说是开箱即用，但国外的邮箱策略和国内的手机号、微信授权功能对比，开发成本还是很大的。并且，对于多产品来说，用户信息的集中也是个必要的功能。所以，相对于开发 N 多个用户系统，不如使用单一的用户系统，然后从其他的系统中通过 token、cookie 等方式进行同步维护状态。这也是我们常说的单点登录（Single Sign-On，SSO）。&lt;/p&gt;
&lt;p&gt;无论是作为一个企业，还是一个有小项目的开发者（Both of me），都需要有一个合适的用户系统做支撑。写项目至今，接触过的认证方式和认证系统，综合对比一下。&lt;/p&gt;
&lt;h2 id=&#34;协议&#34;&gt;协议&lt;/h2&gt;
&lt;p&gt;用户中心系统作为服务端，肯定是要跟客户端进行对接来授权&amp;amp;获取用户信息的。目前大致流行的有 LDAP、CAS、OIDC(基于 Oauth2.0)、SAML 等，此外还有 Kerberos 等不太常见的协议。其宗旨基本一致：浏览器向客户端发起请求，客户端访问用户系统获取 Cookie 或其他认证条件，由用户系统负责登录并将认证后的条件返回给客户端。&lt;/p&gt;
&lt;h3 id=&#34;ldap&#34;&gt;LDAP&lt;/h3&gt;
&lt;p&gt;Lightweight Directory Access Protocol，轻型目录访问协议。这个协议稍微有接触过企业服务的同学可能都不陌生，这是比较古老的认证协议，但至今仍在企业内部和大部分的用户系统中提供支持。LDAP 是文件型存储的，通过 IP 协议进行用户认证授权，层级结构分明，特别适用于公司内部的用户系统。新员工入职时，只需要添加一个 LDAP 成员，就可以访问 wiki、gitlab、oa 等所有系统了。百度、阿里、饿了么等大部分互联网公司内部均采用此协议进行员工管理。具体参考： &lt;a href=&#34;https://ldap.com/&#34;&gt;https://ldap.com/&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&#34;cas&#34;&gt;CAS&lt;/h3&gt;
&lt;p&gt;CAS 是由耶鲁大学实验室 2002 年出的一个开源的统一认证服务中的标准协议，也是很多企业内部系统登录所使用的标准协议，如阿里巴巴等。作为 C 端登录协议如支付宝、淘宝等。详细协议标准可以参考&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://apereo.github.io/cas/6.4.x/protocol/CAS-Protocol-Specification.html&#34;&gt;https://apereo.github.io/cas/6.4.x/protocol/CAS-Protocol-Specification.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;。其核心是服务端返回 ticket 作为认证条件，由客户端判断条件是否存在，存在则通过验证接口验证用户登录状态，同时返回用户信息，否则进行登录。同时客户端可以自定义登录流程，通过服务端提供的接口进行认证。总体流程如图[^1]：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/user-system-compare/DraggedImage.79fb707ab2834234bd2fd72f4a2d0f51.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;使用方也就是 Apereo CAS，此外有少数的语言也按此协议开发了不同的服务端，不过应用甚少。&lt;/p&gt;
&lt;h3 id=&#34;oidcoauth-20-实现&#34;&gt;OIDC（Oauth 2.0 实现）&lt;/h3&gt;
&lt;p&gt;Open ID Connect 是基于 Oauth 2.0 的开放身份认证协议。Oauth2 本身是一个认证协议，它提供了一个授权流和标准通用协议，其中并没有有关用户身份认证相关的内容。OIDC 在此基础上实现了用户相关的认证，完全兼容 Oauth2.0。所以我们常见的微博、QQ、微信等开放平台，文档概述是 Oauth2.0 协议，其实采用的也是非标准结构的 OIDC，因此大家基本谈到的 Oauth2.0==OIDC。&lt;/p&gt;
&lt;p&gt;OIDC 是目前应用比较广泛的用户认证协议，官网： &lt;a href=&#34;https://openid.net/connect/&#34;&gt;https://openid.net/connect/&lt;/a&gt; 。最基本的是授权码模式，然后支持直接授权流、隐式授权流、密码授权等客户端对等认证、一次性认证等方式进行授权流程。&lt;/p&gt;
&lt;p&gt;授权码模式基本流程就是客户端向服务端发起请求，带着 state、client_id、client_secret、redirect_uri、scope 参数请求服务端的授权接口，服务端打开自己的授权页进行授权后，会回调给 redirect_uri 地址，带有 code 参数，客户端通过 code 向服务端换取 access_token，然后就可以拿 token 去做任何事情了。（懒得画图。。）&lt;/p&gt;
&lt;p&gt;OIDC 在所有（没有几乎）语言、框架中均有提供，所有的用户系统也都支持，因此这是一个非常广泛使用的协议。我们平时常见的微信授权登录、QQ 授权登录、Github 登录无一不采用此认证方式。&lt;/p&gt;
&lt;h3 id=&#34;saml&#34;&gt;SAML&lt;/h3&gt;
&lt;p&gt;Security Assertion Markup Language，安全断言标记语言。一个基于 xml 的在不同安全域间进行交换认证和授权数据的协议，是很经典的一个授权协议。因此在大部分的用户系统中，都会有 SAML 协议的支持。不过国内使用的还是偏少，OIDC 的出现抢了它的风头。简介可以参考维基百科： &lt;a href=&#34;https://zh.wikipedia.org/wiki/%E5%AE%89%E5%85%A8%E6%96%AD%E8%A8%80%E6%A0%87%E8%AE%B0%E8%AF%AD%E8%A8%80&#34;&gt;安全断言标记语言&lt;/a&gt; ，其官网（没有找到官网）。&lt;/p&gt;
&lt;h3 id=&#34;其他&#34;&gt;其他&lt;/h3&gt;
&lt;p&gt;此外，还有很多用户认证的协议如 Active Directory、Kerberos 等大大小小的协议，在此不一一列举。&lt;/p&gt;
&lt;h2 id=&#34;框架--平台&#34;&gt;框架 &amp;amp; 平台&lt;/h2&gt;
&lt;p&gt;很多框架或语言本身提供了搭建 SSO 的工具、脚手架，如 &lt;a href=&#34;https://laravel.com/docs/8.x/passport&#34;&gt;Laravel Passport&lt;/a&gt;、&lt;a href=&#34;https://pkg.go.dev/gopkg.in/oauth2.v3&#34;&gt;Go Auth Server&lt;/a&gt; 等，在此不一一列举，基本都是基于 OIDC 协议进行开发的。而支持单点登录的客户端如 Confluence（私有部署版）、Gitlab（私有部署版）、Laravel、WordPress（有个收钱很贵的插件）等，也都是支持 OIDC 的，其中前两者也支持 LDAP，Gitlab 也支持 SAML 协议。讲道理，自己开发最快的方式可能还是基于 OIDC 协议进行认证授权吧。&lt;/p&gt;
&lt;p&gt;在这里整理一下自己尝试过的 SSO 平台，其中包括开源、收费和云原生的，不争高低，合适就好。&lt;/p&gt;
&lt;h3 id=&#34;apereo-cas&#34;&gt;Apereo CAS&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&#34;https://apereo.github.io/cas/6.4.x/index.html&#34;&gt;https://apereo.github.io/cas/6.4.x/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这是老牌的 SSO 系统，Java 语言开发，至今仍在积极维护，有完整的发布时间表和维护周期。以下是官网介绍的特性：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Spring Webflow/Spring Boot Java server component.
Pluggable authentication support (LDAP, Database, X.509, SPNEGO, JAAS, JWT, RADIUS, MongoDb, etc)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Support for multiple protocols (CAS, SAML v1, SAML v2, WS-Federation, OAuth2, OpenID, OpenID Connect, REST)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Support for multifactor authentication via a variety of providers (Duo Security, FIDO U2F, YubiKey, FIDO2 WebAuthN, Google Authenticator, Authy, Acceptto, Inwebo, etc.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Support for delegated authentication to external providers such as ADFS, Facebook, Twitter, SAML2 IdPs, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Built-in support for password management, notifications, terms of use and impersonation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Support for attribute release including user consent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Monitor and track application and system behavior, statistics and metrics in real-time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Manage and review audits and logs centrally, and publish data to a variety of downstream systems.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Manage and register client applications and services with specific authentication policies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Cross-platform client support (Java, .Net, PHP, Perl, Apache, etc).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Integrations with InCommon, Box, Office365, ServiceNow, Salesforce, Workday, WebAdvisor, Drupal, Blackboard, Moodle, Google Apps, etc.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;其可插拔认证支持、多协议支持、OTP 支持等等非常多的功能均是亮点。还是刚才说的，内部系统很多都在使用其二次开发或扩展的 CAS，如阿里巴巴。&lt;/p&gt;
&lt;p&gt;部署支持 Docker、原生 war。&lt;/p&gt;
&lt;p&gt;开发采用 &lt;code&gt;CAS Overlay&lt;/code&gt; 的方式，就是说在第一次部署后，将某个资源文件或 class 文件复制到你的&lt;code&gt;src/main&lt;/code&gt;目录下进行二次开发，在 package 的时候会自动将你的文件替换到原有项目中去，实现功能自定义的目的。&lt;/p&gt;
&lt;p&gt;最新版的（6.4）CAS 默认的登录界面如下：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/user-system-compare/DraggedImage.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;是使用 Docker 启动的。登录后界面也十分简单，在左侧有相关文档链接的侧边栏。基础启动方法可以参考其他人的文章：&lt;a href=&#34;https://www.cnblogs.com/zhzhlong/p/11551361.html&#34;&gt;https://www.cnblogs.com/zhzhlong/p/11551361.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;CAS 是一个专注于认证的系统，因此——没有注册功能，默认是内存存储用户信息，一切配置均采用 Java 的 yaml 格式文件。因此，如果你想用 MySQL 作为存储引擎，那么你需要引入&lt;code&gt;mysql-connector&lt;/code&gt;然后再在 yaml 中配置好数据库连接、表结构等信息。而注册等功能需要通过 overlay 的方式进行扩展。而 overlay 我是尝试过的，用起来可以说是相当复杂。其自定义后的 Docker 镜像也是要重新编译的。&lt;/p&gt;
&lt;p&gt;总而言之，CAS 本身是一个十分强大的用户认证系统，相关开源的插件也很多。但其因为过于强大而专一，导致我们平时很需要的额外功能反倒不支持，想把 CAS 作为生产环境使用将会有很大的工作量。而且文档也并不是很详细。接入 CAS 需要其支持客户端语言，如 PHP-CAS 等。&lt;/p&gt;
&lt;h3 id=&#34;keycloak&#34;&gt;Keycloak&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&#34;https://keycloak.org/&#34;&gt;https://keycloak.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Keycloak 于 2013 年末发布 1.0-alpha 版，到现在最新版已经是 15.0.2 了，16.0.0 在紧锣密鼓地开发中。这是一个支持比较完整的用户认证系统，由 Java 开发，基于 jboss。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;就在写这段的时候，Keycloak 官网发布了一条消息，迎来的新的 maintainer: Tomas Darimont，主要负责 keycloak.X 的开发。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;相对于 CAS，Keycloak 没有那么多的协议的支持，认证协议支持 OIDC 和 SAML，将 LDAP 和 Kerberos 作为用户存储协议集成。使用 Freemarker 作为 HTML 模板。内置第三方授权登录。通过 jboss 提供的热加载服务可实现扩展。内置的所有功能都可以扩展。支持注册！原生支持 Postgres、MySQL、SQLite 等数据库引擎。&lt;/p&gt;
&lt;p&gt;而且，其默认的登录界面基本没有侵略性。如图：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/user-system-compare/DraggedImage-1.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;部署支持 Docker、原生部署等。内置管理控制台，支持多 realm。默认提供一个 Master 的 realm 供整体管理使用，一般我们都会建立自己的 realm。&lt;/p&gt;
&lt;p&gt;扩展方式是基于&lt;a href=&#34;https://www.keycloak.org/docs/latest/server_development/index.html&#34;&gt;https://www.keycloak.org/docs/latest/server_development/index.html&lt;/a&gt;，将要自定义的功能定义为一个 SPI，部署到 deployments 目录里即可。主题也可以自定义，方式是通过编写 base 模板的 css 来实现。上图的主题是内置的&lt;code&gt;keycloak&lt;/code&gt;主题。&lt;/p&gt;
&lt;p&gt;当然，缺点也是有的，比如支持的协议不够多，用户的存储无法自定义，文档也不够详细～～（到底要多详细的模板才满意）比较重要的是，其用户属性是可以扩展的，但是默认的必填项是无法删除的，比如国外常用的&lt;code&gt;First Name&lt;/code&gt;、&lt;code&gt;Last Name&lt;/code&gt;，而我们可能只需要一个昵称，取消前两者的必填属性就需要一定的开发了。&lt;/p&gt;
&lt;p&gt;这里是我同事写的 Keycloak 的基础搭建过程：&lt;a href=&#34;https://zhuanlan.zhihu.com/p/411062890&#34;&gt;https://zhuanlan.zhihu.com/p/411062890&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;目前 keycloak 的扩展基本跟不上其更新速度，基本都停留在 12.0.1 的版本。我用了到目前三个星期的时间来适配不同的插件，包括 oauth、短信验证等。这里可以放出来一个看看：&lt;a href=&#34;https://github.com/rxrw/keycloak-justauth&#34;&gt;https://github.com/rxrw/keycloak-justauth&lt;/a&gt;是基于 justauth 让 Keycloak 支持国内数十种平台的第三方授权登录。&lt;/p&gt;
&lt;p&gt;Demo: &lt;a href=&#34;https://auth.iuv520.com/auth/realms/test/account/#/&#34;&gt;https://auth.iuv520.com/auth/realms/test/account/#/&lt;/a&gt;，我内置了一个通用的 key &amp;amp; secret，感兴趣的同学可以自己搞个客户端来体验一下。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nt&#34;&gt;client_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;client_secret&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;eyJhbGciOiJIUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJmZGYxNmJjOS04M2U0LTRjZmEtOWRiZC0yNTE1OWQyMWE3YWEifQ.eyJleHAiOjE3MTgyNjYxMDcsImlhdCI6MTYzMTg2NjEwNywianRpIjoiMmQxOTBjODgtZWQ5NC00ZDEwLWIwMGUtZDcwZjY2MWQwOTZlIiwiaXNzIjoiaHR0cHM6Ly9hdXRoLml1djUyMC5jb20vYXV0aC9yZWFsbXMvdGVzdCIsImF1ZCI6Imh0dHBzOi8vYXV0aC5pdXY1MjAuY29tL2F1dGgvcmVhbG1zL3Rlc3QiLCJ0eXAiOiJJbml0aWFsQWNjZXNzVG9rZW4ifQ.CNgndfSSJo-ahVFVFSlRehayPSCRr9I6tiuc5hXulrU&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;redirect_uri&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;*&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;授权地址&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://auth.iuv520.com/auth/realms/test/protocol/openid-connect/auth&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;token地址&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://auth.iuv520.com/auth/realms/test/protocol/openid-connect/token&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nt&#34;&gt;用户信息&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;l&#34;&gt;https://auth.iuv520.com/auth/realms/test/protocol/openid-connect/userinfo&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;auth0&#34;&gt;auth0&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&#34;https://auth0.com/&#34;&gt;https://auth0.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;与前两个不同，auth0 是国外一个云原生（Cloud Native）用户认证系统，要 💰 的商业化平台。免费版可以支持 7000 用户。作为一个云原生项目，特点就是不需要存储、不需要很多开发就可以使用（登录 UI 可以自定义）。但是对于用户系统，把自己公司的用户数据放到别的平台，可能是需要思考一下。登录流程会走 auth0 自己的服务器，虽然可以自定义域名，但本质没有改变，对于国内用户来说速度无法接受。因此自己玩耍一下还可以。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/user-system-compare/auth0.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;不是要搭建自己的用户平台么，怎么用上人家的了..&lt;/p&gt;
&lt;h3 id=&#34;authing&#34;&gt;authing&lt;/h3&gt;
&lt;p&gt;官网：&lt;a href=&#34;https://www.authing.co/&#34;&gt;https://www.authing.co/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;这是国内少有的还比较成型的身份认证系统，开发语言 NodeJS。与 auth0 类似，其也是一个云原生平台。虽说不用服务器，每月的价格也够一台不错的阿里云服务器了。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/user-system-compare/DraggedImage-3.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;整体的架构和 Auth0 差不多，第三方授权登录都是微信等国内常用的授权方式。&lt;/p&gt;
&lt;p&gt;也是各种用户数据存储在第三方，难道真的有企业会愿意把自己的用户信息放在别人那里管么。因此支持私有部署，不过就之前与其进行对接的经历，感觉系统内部的代码其实很乱，基本私有部署也没什么定制化的空间。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;其实真正开源的用户系统也就 CAS 和 Keycloak 两家比较完善且流行的。如果有特别严重的定制化需求，建议还是采用自己开发的方式吧。毕竟国外的用户系统不一定合我们的胃口，而国内的某些平台吃相也是真的难看。如果定制化需求没那么严重，可以在现有开源项目的基础上扩展，那是最好的了。我现在就是在 Keycloak 的基础上进行的扩展，感觉经过一定修改和兼容后，产品可用性还是很强的。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">从pt到家庭媒体中心全攻略（一）</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E4%B8%80/" />
            <id>https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E4%B8%80/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-09-08T13:24:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">背景 本人一直是玩 PT 站的，从去年开始到现在一年左右了吧。 从最开始百度云+迅雷到群晖+t……</summary>
            
                <content type="html">&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;本人一直是玩 PT 站的，从去年开始到现在一年左右了吧。&lt;/p&gt;
&lt;p&gt;从最开始百度云+迅雷到群晖+transmission+video station 到 pt 助手，再到 Emby，再到 sonarr+radarr+jackett，中间也试水了 plex，到现在基本定型的 Sonarr + Radarr + Prowlarr + Lidarr + Readarr + Subfinder + Emby + Infuse + Transmission + qBittorrent，着实是踩了不少坑涨了不少经验。在此总结之际做个总结。&lt;/p&gt;
&lt;h2 id=&#34;先看效果&#34;&gt;先看效果&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;媒体资源库
&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-1/4015fe5f9b006a92284aa4246fce5c55.png&#34; alt=&#34;媒体资源库&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;电视剧/综艺自动搜刮器
&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-1/54ad7da111d08f1a27e25d5a33738155.png&#34; alt=&#34;剧集搜刮器&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;电影搜刮器
&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-1/76f2a0fb56a00a58d3c50f075d900640.png&#34; alt=&#34;电影搜刮器&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;追剧跟踪
&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-1/4c19920fbe934ddea9f4ab24009ad0b7.png&#34; alt=&#34;追剧跟踪&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个是第三方平台。&lt;/p&gt;
&lt;p&gt;还有很多其他意义没这么重要的就不截图了。&lt;/p&gt;
&lt;h2 id=&#34;基础准备&#34;&gt;基础准备&lt;/h2&gt;
&lt;p&gt;硬件配置：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;群晖（1618+，配了 6 块 12t 硬盘）媒体的存储和下载器&lt;/li&gt;
&lt;li&gt;主机（i7-10700+32g 内存） 各类应用软件的搭建&lt;/li&gt;
&lt;li&gt;Apple tv 6 当然是主要的观看设备了&lt;/li&gt;
&lt;li&gt;千兆交换机 便于网内通信不需要走路由器，提高速度&lt;/li&gt;
&lt;li&gt;装有 openwrt 的树莓派 对于媒体信息搜刮提供有效帮助&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;网络情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;联通 500M&lt;/li&gt;
&lt;li&gt;移动 200M&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;资源情况：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;零至多个 PT 站账号&lt;/li&gt;
&lt;li&gt;如果没有 PT 站账号，可以选用公开站点，但是资源有限且保种情况很差&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先来看一下网上通用的解决方案：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;在群晖中套件中心搜索 Emby、transmission、Sonarr、Radarr 等下载安装…然后一番配置之后就可以用了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但实际上，群晖作为一个存储器，cpu 采用的是 intel atom 系列，算是低端到不行的芯片，内存也只有 4G，一般配置也并没有显卡。而 emby 的媒体分析（ffmpeg）是极度消耗 CPU 和显卡计算能力的。&lt;/p&gt;
&lt;p&gt;对于种子的搜刮，也需要大量的网络请求。而且这几个 Servarr 系列工具都是用 C# 去写的，在 linux 中跑.exe 程序所需要的 cpu 资源可想而知。我最初也是这么实现的，但是这几个程序都慢的不行。一开始我以为就是这个样子的，直到后来切换到了主机端才发现这些程序真正的速度是怎么样的。&lt;/p&gt;
&lt;h2 id=&#34;核心&#34;&gt;核心&lt;/h2&gt;
&lt;p&gt;所以我的部署方案是利用 Docker，正好有 &lt;code&gt;linuxserver&lt;/code&gt; 项目组为这些项目提供了合适的容器镜像。再通过容器挂载的方式进行媒体访问&lt;/p&gt;
&lt;h2 id=&#34;服务介绍&#34;&gt;服务介绍&lt;/h2&gt;
&lt;p&gt;在这里只讲一些重要的服务，搭建过程比较简单。&lt;/p&gt;
&lt;h3 id=&#34;radarr&#34;&gt;Radarr&lt;/h3&gt;
&lt;p&gt;电影搜刮器。是基于 Sonarr 进行改造开发的，但是作者我感觉人还是不错的，至少目前在我看来这个的功能比 Sonarr 强大得多，但是性质不一样，两者依旧不可缺。说是搜刮器，其实就是调用着别人的搜刮接口~查着别人的电影信息~ 调用别的下载工具~ 把下载好的媒体重命名到合适的文件夹然后，调用别人的播放器~ 但就这一个作为中间桥梁的，一直使用其他人的成果的程序，反倒是不可或缺。&lt;/p&gt;
&lt;p&gt;它呢，基本上是以列表连接（imdb、imdb、trakt 等列表）或自己手动搜索添加电影，通过 jackett(现在我用 prowlarr)等支持 Torznab 协议转换的工具搜刮各 bt/pt 站的有效种子，将种子发送到下载服务器并按时监控下载状态。当下载完成后，则会自动将下载好的媒体文件按照预设的方式存储到固定目录中去，并发送通知给用户或其他程序。&lt;/p&gt;
&lt;h3 id=&#34;sonarr&#34;&gt;Sonarr&lt;/h3&gt;
&lt;p&gt;剧集搜刮器好听一点吧。包含了电视剧、电视节目的搜刮。算是这个系列的鼻祖了。但是作者维护一直处于佛系+懒散的状态，奈何我又不会 C#，没有办法自己改动一些东西。不过说起来，剧集搜刮确实要比电影搜刮复杂很多。&lt;/p&gt;
&lt;p&gt;跟 Radarr 相比，少了一些功能：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;不支持中文&lt;/li&gt;
&lt;li&gt;国内 pt 站剧集格式可能单季不会按&lt;code&gt;S01&lt;/code&gt;这种格式命名，这货就不会自动搜刮。作者解释是为了防止出现把第一季和全剧弄混的情况（大哥就只有一季的电视剧第一季和全剧有什么区别），并且死活不改。&lt;/li&gt;
&lt;li&gt;搜刮时的名称不支持中文（甚至源语言），只支持英文。他说他认为所有的 pt 站种子命名格式一定要有标准英文格式，因此不会做额外工作（又来了，tvdb 上名字都全的，搜一下又不会死，我的柯南就因为这个一直没办法自动搜索下载，不过扫黑风暴倒是每一集都有下）。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;emby&#34;&gt;emby&lt;/h3&gt;
&lt;p&gt;不用过多介绍，emby 是一款支持多种视频格式，支持自动搜刮、自动搜索字幕、格式整理，支持各端同步播放状态（播放要钱，状态不要）、多用户管理（权限管理）等等功能。与其作为竞争对手的还有 plex 等，但是都用过之后还是觉得这个更顺手一些。&lt;/p&gt;
&lt;h3 id=&#34;qbittorrenttransmission-等&#34;&gt;qbittorrent、transmission 等&lt;/h3&gt;
&lt;p&gt;下载器，类似于迅雷。但事实上，迅雷是传说中的吸血软件。bt 的原理是通过大家互相上传下载所需要的文件内容，从而实现下载越多速度越快的原理。而迅雷则是自己建立了一个大的分享网络，将从别人那里拿来的据为己有，只在自己的客户端内传播。（当然，迅雷也自己建立了自己的文件库，所以下载速度才那么快。但是它是不分享给其他下载软件的。）而 pt 站所需要的分享精神也正是其保密、不公开注册的原因。因此，pt 站就只可以用标准 bt 协议即 qb、tr 这种下载工具。据说 qb 抢上传比较厉害，而 tr 资源占用小，适合保种。（pt 相关知识在此不予说明）&lt;/p&gt;
&lt;h3 id=&#34;jackettprowlarr&#34;&gt;Jackett、Prowlarr&lt;/h3&gt;
&lt;p&gt;传说中的种子搜刮器。由于国内大部分 PT 站都是很久以前的 nexusPHP 架构，而 pt 的本质大同小异，资源命名也有很固定的规范。因此，这种搜刮器就是利用爬虫的原理对 pt 站进行资源搜索，找到所需要的资源种子返回给客户端。&lt;/p&gt;
&lt;h3 id=&#34;其他&#34;&gt;其他&lt;/h3&gt;
&lt;p&gt;其他服务比如 Lidarr 音乐搜索、Readarr 电子书搜索等服务，国内资源较少，我搭建起来只是为了看起来全面一些，并没太大用处，因此也不会详细讲解。&lt;/p&gt;
&lt;h2 id=&#34;开始搭建&#34;&gt;开始搭建&lt;/h2&gt;
&lt;h3 id=&#34;群晖的设置下载器文件目录及权限&#34;&gt;群晖的设置（下载器、文件目录及权限）&lt;/h3&gt;
&lt;p&gt;首先，在群晖上建立一个共享文件夹，在我这里叫做 media，里面存储着所有下载和格式化的媒体文件。在文件夹中建立 downloads、video、music 等目录，分别存储下载资源、格式化后的视频、音乐等资源。&lt;/p&gt;
&lt;p&gt;在群晖上安装 transmission，设置默认的下载路径为 media，未完成的下载设定在&lt;code&gt;/volume1/media/downloads/incomplete&lt;/code&gt; （按自己喜欢）。安装好后，输入 群晖 ip:9091 访问群晖，设置下载路径为 &lt;code&gt;/volume1/media/downloads/complete&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;通过群晖打开/media/downloads 文件夹，将其权限设置为 sc-tranmission:sc-tranmission 完全访问权限，包含子文件夹：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/pt-1/bd02b4ff8a7a952064ca668c42f77d54.png&#34; alt=&#34;群晖设置&#34;&gt;&lt;/p&gt;
&lt;p&gt;这样才能保证下载过程畅通无阻。&lt;/p&gt;
&lt;p&gt;群晖的部分设置完了，下一章会讲媒体服务的设置，今天太晚了该下班了。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B-pt/" term="技术 教程 pt" label="技术 教程 pt" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">GOLANG 常用包整理</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/golang_%E5%B8%B8%E7%94%A8%E5%8C%85%E6%95%B4%E7%90%86/" />
            <id>https://rxrw.me/tech/golang_%E5%B8%B8%E7%94%A8%E5%8C%85%E6%95%B4%E7%90%86/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-08-06T02:44:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">不得不说，go 是真的快。当然，这个避免重复造轮子的年代，还是要多多整理一些 go 常用的包……</summary>
            
                <content type="html">&lt;p&gt;不得不说，go 是真的快。当然，这个避免重复造轮子的年代，还是要多多整理一些 go 常用的包，毕竟不像 python pip，php composer，nodejs 还有 npm，go 的源除了 pkg.go.dev 之外还有很多自定义源比如 github 等。整理一些可能大众可能小众的扩展包方便之后的查找。&lt;/p&gt;
&lt;h2 id=&#34;iris&#34;&gt;iris&lt;/h2&gt;
&lt;p&gt;地址：&lt;a href=&#34;https://github.com/kataras/iris&#34;&gt;https://github.com/kataras/iris&lt;/a&gt;
简介：作者自称是速度和优雅度堪比 gin 的框架，在使用过程中深有感触。只不过之前是写 php 的常用 Laravel，向 go、node 这种语言写法转有些累。请求兼容原生 Request、支持 grpc、用了很多自己写的框架。&lt;/p&gt;
&lt;h2 id=&#34;xorm&#34;&gt;xorm&lt;/h2&gt;
&lt;p&gt;地址：&lt;a href=&#34;https://gitea.com/xorm/xorm&#34;&gt;https://gitea.com/xorm/xorm&lt;/a&gt;
简介：少有的 golang 的 orm 框架，支持各种驱动。结构体与表结构同步等。我在用增强版的 xormplus，不过这个项目有几个月没有代码提交了，不知道还会不会继续维护。&lt;/p&gt;
&lt;h2 id=&#34;go-extend&#34;&gt;Go-extend&lt;/h2&gt;
&lt;p&gt;地址：&lt;a href=&#34;https://github.com/thinkeridea/go-extend&#34;&gt;https://github.com/thinkeridea/go-extend&lt;/a&gt;
简介：提供了一些啥都有的工具，主要是我懒得查 ip，这个就可以。&lt;/p&gt;
&lt;h2 id=&#34;rod&#34;&gt;Rod&lt;/h2&gt;
&lt;p&gt;地址：&lt;a href=&#34;https://github.com/go-rod/rod&#34;&gt;https://github.com/go-rod/rod&lt;/a&gt;
简介：go 版本的 puppyteer，功能强大速度快。&lt;/p&gt;
&lt;h2 id=&#34;redis&#34;&gt;Redis&lt;/h2&gt;
&lt;p&gt;地址：&lt;a href=&#34;https://github.com/go-redis/redis/v8&#34;&gt;https://github.com/go-redis/redis/v8&lt;/a&gt;
简介：redis 官方的 go 版本驱动，应该是通用驱动翻译来的，跟 nodejs 版本的语法很像。讲真，go 的结构体和 redis 有仇。。&lt;/p&gt;
&lt;h2 id=&#34;go-admin&#34;&gt;Go-admin&lt;/h2&gt;
&lt;p&gt;不发地址了，从来不用这个，在这里不是推荐单纯想吐槽一下。概念上是抄的 Laravel Admin，功能上又少的可怜。代码侵入非常强。有一次打算试一下，结果刚 init 了一下就把我的代码目录搞乱了。说是支持多种框架，其实是利用 gin 的兼容来兼容其他 web 框架的。后台管理这方面，还是 PHP 吧。&lt;/p&gt;
&lt;p&gt;之后有好的轮子会继续写在这里。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">xorm 缓存的问题</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/xorm_%E7%BC%93%E5%AD%98%E7%9A%84%E9%97%AE%E9%A2%98/" />
            <id>https://rxrw.me/tech/xorm_%E7%BC%93%E5%AD%98%E7%9A%84%E9%97%AE%E9%A2%98/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-08-05T09:36:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">今天用 xormplus 对数据进行查询，因为查询量有些大，发现其实 xorm/xormplus 是支持缓存的，因此添加了默认的缓……</summary>
            
                <content type="html">&lt;p&gt;今天用 xormplus 对数据进行查询，因为查询量有些大，发现其实 xorm/xormplus 是支持缓存的，因此添加了默认的缓存，即 &lt;code&gt;MemoryCacher&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;但在使用中发现了个很奇怪的问题。在我的方法里会将返回的模型 Content 进行一些循环文字 append 的操作。输出的结果会随着页面刷新不停地叠加。&lt;/p&gt;
&lt;p&gt;在日志中发现了问题所在，其实是因为在我循环的方法中使用的是指针，而查询器缓存的结果也是这个指针，就导致了每次修改都会修改内存中的地址所对应的模型。&lt;/p&gt;
&lt;p&gt;知道了问题，解决也很简单，在循环方法中将模型赋值给一个新的变量，修改相关操作在新的变量上。&lt;/p&gt;
&lt;p&gt;其实更好的方法是直接参数传参不要用指针，不过因为要改动的太多了，懒得弄。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">修改 git 历史提交的用户名邮箱</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BF%AE%E6%94%B9_git_%E5%8E%86%E5%8F%B2%E6%8F%90%E4%BA%A4%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E9%82%AE%E7%AE%B1/" />
            <id>https://rxrw.me/tech/%E4%BF%AE%E6%94%B9_git_%E5%8E%86%E5%8F%B2%E6%8F%90%E4%BA%A4%E7%9A%84%E7%94%A8%E6%88%B7%E5%90%8D%E9%82%AE%E7%AE%B1/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-05-14T03:45:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">之前由于工作，以及自己比较混乱等原因，在 github 和自己的仓库中提交的历史邮箱、用户名不一致……</summary>
            
                <content type="html">&lt;p&gt;之前由于工作，以及自己比较混乱等原因，在 github 和自己的仓库中提交的历史邮箱、用户名不一致，就很烦。后来通过百度找到了 &lt;code&gt;git filter-branch&lt;/code&gt; 的方法。但是它一直在提示&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;WARNING: git-filter-branch has a glut of gotchas generating mangled &lt;span class=&#34;nb&#34;&gt;history&lt;/span&gt; rewrites.  Hit Ctrl-C before proceeding to abort, &lt;span class=&#34;k&#34;&gt;then&lt;/span&gt; use an alternative filtering tool such as &lt;span class=&#34;s1&#34;&gt;&amp;#39;git filter-repo&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;https://github.com/newren/git-filter-repo/&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; instead.  See the filter-branch manual page &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; more details&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; to squelch this warning, &lt;span class=&#34;nb&#34;&gt;set&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;FILTER_BRANCH_SQUELCH_WARNING&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;1.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;意思是这个命令会产生大量的混乱提交。因为之前的项目都是自己写的，也没在意。直到后来整理一份 forked 项目时里面多出了很多冲突。于是查找并使用 &lt;code&gt;git-filter-repo&lt;/code&gt;来解决问题。国内使用这个命令的少之又少，因此在此记录一下。&lt;/p&gt;
&lt;h2 id=&#34;git-filter-branch-用法&#34;&gt;git filter-branch 用法&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git filter-branch -f --env-filter &lt;span class=&#34;s1&#34;&gt;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;OLD_EMAIL=&amp;#34;原邮箱&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;CORRECT_NAME=&amp;#34;要修改的用户名&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;CORRECT_EMAIL=&amp;#34;要修改的邮箱&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;if [ &amp;#34;$GIT_COMMITTER_EMAIL&amp;#34; = &amp;#34;$OLD_EMAIL&amp;#34; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    export GIT_COMMITTER_NAME=&amp;#34;$CORRECT_NAME&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    export GIT_COMMITTER_EMAIL=&amp;#34;$CORRECT_EMAIL&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;if [ &amp;#34;$GIT_AUTHOR_EMAIL&amp;#34; = &amp;#34;$OLD_EMAIL&amp;#34; ]
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;then
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    export GIT_AUTHOR_NAME=&amp;#34;$CORRECT_NAME&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    export GIT_AUTHOR_EMAIL=&amp;#34;$CORRECT_EMAIL&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;fi
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&lt;/span&gt; --tag-name-filter cat -- --branches --tags
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;OLD_EMAIL&lt;/code&gt; 是要修改的邮箱，&lt;code&gt;CORRECT_NAME&lt;/code&gt; 和 &lt;code&gt;CORRECT_EMAIL&lt;/code&gt; 是要修改为的邮箱。将命令保存到 .sh 文件中，在仓库根目录执行 &lt;code&gt;bash rewrite.sh &amp;amp;&amp;amp; git push --force --tags origin &#39;refs/heads/*&#39;&lt;/code&gt; 就可以了。&lt;/p&gt;
&lt;h2 id=&#34;git-filter-repo&#34;&gt;git-filter-repo&lt;/h2&gt;
&lt;p&gt;这是一个 python 脚本，需要安装：&lt;code&gt;brew install git-filter-repo&lt;/code&gt; ，或者在 github 上下载：https://github.com/newren/git-filter-repo/&lt;/p&gt;
&lt;p&gt;命令如下：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git-filter-repo --email-callback &lt;span class=&#34;s1&#34;&gt;&amp;#39;return email.replace(b&amp;#34;原邮箱&amp;#34;, b&amp;#34;要修改的邮箱&amp;#34;)&amp;#39;&lt;/span&gt; --force
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git-filter-repo --name-callback &lt;span class=&#34;s1&#34;&gt;&amp;#39;return name.replace(b&amp;#34;原用户名&amp;#34;, b&amp;#34;要修改的用户名&amp;#34;)&amp;#39;&lt;/span&gt; --force
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;其原理是执行 python 来处理其 commits。&lt;/p&gt;
&lt;p&gt;整理 ing&amp;hellip;&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">博客的一些更新</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E5%8D%9A%E5%AE%A2%E7%9A%84%E4%B8%80%E4%BA%9B%E6%9B%B4%E6%96%B0/" />
            <id>https://rxrw.me/tech/%E5%8D%9A%E5%AE%A2%E7%9A%84%E4%B8%80%E4%BA%9B%E6%9B%B4%E6%96%B0/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-03-05T06:40:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">许久没有更新博客了，2 月份一直在优化一些博客相关的服务和设施，最近在搞一个生产力工具……</summary>
            
                <content type="html">&lt;p&gt;许久没有更新博客了，2 月份一直在优化一些博客相关的服务和设施，最近在搞一个生产力工具。&lt;/p&gt;
&lt;h2 id=&#34;服务器&#34;&gt;服务器&lt;/h2&gt;
&lt;p&gt;从原来的 GitHub Pages 迁移到了阿里云轻量云服务器（中国香港）。因为家里全局有梯子，在公司也有，因此没感觉加载上有什么速度问题。直到有一次做测试才发现，实在是太慢了。。
于是，把服务搬到国内来，由于域名不能备案，只能选在香港服务器了。
同时，ci 一套也就相应变了，不过从原来用别人的 actions 到直接在服务器上跑一个 Github Actions Runner，直接 cp 就好了。&lt;/p&gt;
&lt;h2 id=&#34;再见图床&#34;&gt;再见图床&lt;/h2&gt;
&lt;p&gt;之前每一次都是要传图床，然后粘贴地址，很费劲，于是自己搞了一个 Markdown 中的图片自动上传+替换链接的工具。用 go 写的。之前有人用 python 写过，感觉还不错。不过有一些需要牺牲的就是博客源码的文件结构可能会很乱了。。
但是！以后写博客可以直接复制粘贴 ulysses，写好了之后直接导出到 content 目录下加个 fromt matter 就好了&lt;/p&gt;
&lt;h2 id=&#34;algolia&#34;&gt;algolia&lt;/h2&gt;
&lt;p&gt;之前的博客用的是 lunr.js 索引，在打包时生成文件在浏览器索引。那么结果是不支持中文的。
经过一番改造，将搜索框变成了可以支持 algolia 的索引，巴适得很。
Github Marketplace 上不知道这群人写的自动上传索引的工具咋这么奇怪呢，都用不了。于是自己又写了一个。&lt;/p&gt;
&lt;h2 id=&#34;很奇怪&#34;&gt;很奇怪&lt;/h2&gt;
&lt;p&gt;之前说过我用的主题是 &lt;code&gt;reuixiy&lt;/code&gt; 小姐姐写的 &lt;code&gt;hugo-theme-meme&lt;/code&gt; 。提过两个 pr。一个是图库模式，一个是 &lt;code&gt;algolia&lt;/code&gt; 索引支持。第一个回复了我再也没管过，另一个压根就没回复，反倒能看见她 merge 了其他的简单的修改。可能是因为太忙了吗。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF%E6%97%A5%E5%B8%B8/" term="技术日常" label="技术日常" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">代码的管理</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BB%A3%E7%A0%81%E7%9A%84%E7%AE%A1%E7%90%86/" />
            <id>https://rxrw.me/tech/%E4%BB%A3%E7%A0%81%E7%9A%84%E7%AE%A1%E7%90%86/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-01-22T07:05:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">因为自用的 Gitlab 搭建在了内网，只能通过加密协议访问，前几天在老文件中找到了当初初学代码时……</summary>
            
                <content type="html">&lt;p&gt;因为自用的 Gitlab 搭建在了内网，只能通过加密协议访问，前几天在老文件中找到了当初初学代码时候的一堆… 放了进去，跑题了。&lt;/p&gt;
&lt;p&gt;然后对于开源项目肯定是放在 GitHub 上了。而一些需要公网访问的内容只能部署在阿里云。那从家中的 Gitlab 搭出一个 Runner 给阿里云的方案也试过，比较折腾。闲来无事在阿里云 Code 发现它升级了。。把原来集团内的 Aone 商业化了相当于。&lt;/p&gt;
&lt;p&gt;配合 Gitlab 的镜像仓库功能，实现代码统一集中管理，由 Gitlab 去负责将代码推到该在的地方，完美。&lt;/p&gt;
&lt;p&gt;阿里云 Flow :&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/code-management/fc9d3a36be3a887c12161ae866706b81.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;最终效果：&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/code-management/c97f5a547345ea846393c95d253b4948.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;就是从以前要管理很多很多远程库变成只需要管一个就好了。同时，对代码的存储也是一个不错的选择。&lt;/p&gt;
&lt;h2 id=&#34;gitlab-的配置&#34;&gt;Gitlab 的配置&lt;/h2&gt;
&lt;p&gt;Gitlab 的部署不是本篇的范围。。&lt;/p&gt;
&lt;p&gt;没什么好配置的呀。首先假设我们的代码源是 Github。以我的博客为例。
在 Gitlab 中新建仓库，从 Github 中导入仓库。那么就选了这个仓库导入，这个过程小白化的，不多讲。
阿里云的项目呢，就一个道理，在 &lt;a href=&#34;https://codeup.aliyun.com/&#34;&gt;阿里云 Codeup&lt;/a&gt; 上新建项目。
这是最基本的配置。&lt;/p&gt;
&lt;h2 id=&#34;gitlab-与-github-的联动&#34;&gt;Gitlab 与 Github 的联动&lt;/h2&gt;
&lt;p&gt;在 Github 上进入设置页面，在 &lt;code&gt;Developer Settings&lt;/code&gt; -&amp;gt; &lt;code&gt;Personal access token&lt;/code&gt; 里面新建一个 token ，权限选择 &lt;code&gt;repo&lt;/code&gt;, &lt;code&gt;workflow&lt;/code&gt; 两个，OK。记住这个 token ，这是 GitHub 的同步密码。
回到 Gitlab 。选刚刚同步过来的仓库。&lt;code&gt;设置&lt;/code&gt; -&amp;gt; &lt;code&gt;镜像仓库&lt;/code&gt; -&amp;gt; &lt;code&gt;展开&lt;/code&gt; (&lt;code&gt;Settings&lt;/code&gt; -&amp;gt; &lt;code&gt;Repository Mirrors&lt;/code&gt; -&amp;gt; &lt;code&gt;Expand&lt;/code&gt;)
在 &lt;code&gt;Git仓库URL&lt;/code&gt; 中填入 Github 仓库的 HTTPS 地址，在地址前面加上你的&lt;code&gt;用户名@&lt;/code&gt;，方向选择推送，密码则是刚刚的 token。
点击保存，下方刷新试一下，没有问题的话，选择拉取再填一下。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;镜像仓库只可以有一个拉取仓库，可以有多个推送仓库，原因不用多说。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;现在，Gitlab 和 Github 之间的这个仓库就可以完全同步了。在本地将代码仓库的 remote 改为 gitlab 的地址，尝试 push 一下吧。&lt;/p&gt;
&lt;h2 id=&#34;gitlab-与-阿里云-code-的联动&#34;&gt;Gitlab 与 阿里云 Code 的联动&lt;/h2&gt;
&lt;p&gt;此处的前提是先有 Gitlab 的仓库。如果先有的阿里云 Code 的仓库跟上述操作是差不多的。
初始化阿里云 Codeup ，设置推送密码，然后跟 上面一样配置就好了。&lt;/p&gt;
&lt;h2 id=&#34;阿里云-flow-的配置&#34;&gt;阿里云 flow 的配置&lt;/h2&gt;
&lt;p&gt;在阿里云 Code 的仓库里选择流水线，新建流水线，可根据需要去选择模板。像我没什么追求，就直接 docker 部署到 ecs 主机了，因此流水线是自建的。直接 ssh 到机器上 &lt;code&gt;git pull&lt;/code&gt; 然后&lt;code&gt;docker-compose up -d&lt;/code&gt; 就 ok。
如果是自建镜像可以通过这里推送到阿里云的仓库，然后在主机 pull。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;好像没什么难度…&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">家庭网络布局改造</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E5%AE%B6%E5%BA%AD%E7%BD%91%E7%BB%9C%E5%B8%83%E5%B1%80%E6%94%B9%E9%80%A0/" />
            <id>https://rxrw.me/tech/%E5%AE%B6%E5%BA%AD%E7%BD%91%E7%BB%9C%E5%B8%83%E5%B1%80%E6%94%B9%E9%80%A0/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-01-14T18:58:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">背景 原来家里有一只群晖，20 年 4 月份的时候入了 1618+，本来想当服务器+存储使的。……</summary>
            
                <content type="html">&lt;h2 id=&#34;背景&#34;&gt;背景&lt;/h2&gt;
&lt;p&gt;原来家里有一只群晖，20 年 4 月份的时候入了 1618+，本来想当服务器+存储使的。跟联通申请了个公网 IP，就一直这么用着。直到有一天群晖开始发邮件，要实名认证。再然后跑数据，发现群晖的 atom 根本跟不上速度。因此遇到了一些问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;直接暴露公网 IP 直接导致一堆黑客在扫描尝试攻击，影响安全；&lt;/li&gt;
&lt;li&gt;需要一台主机充当服务器，存储和计算分开；&lt;/li&gt;
&lt;li&gt;使用特殊通道设置一个只有自己可以连接的网络；&lt;/li&gt;
&lt;li&gt;在此之上实现一些增强需求；&lt;/li&gt;
&lt;li&gt;无论是内网还是外网，实现自定义 DNS。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;实现&#34;&gt;实现&lt;/h2&gt;
&lt;p&gt;因此，在 leader 大神的帮助下，我大概规划了自己家里的网络结构图。&lt;/p&gt;
&lt;h3 id=&#34;硬件部分&#34;&gt;硬件部分&lt;/h3&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/network-of-home/32395cb25e4d6ae98f7b5e82dfc59549.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;其中实线使用网线连接，虚线是无线。
里面有几个比较特殊，就是 PC 和树莓派和群晖，乍一看像一个环形结构，其实是有特殊原因的。先说这种布局的理由：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先说网线都是 CAT6 的，毕竟，千兆网络和路由器，五类网线的速度达不到数据传输的要求。&lt;/li&gt;
&lt;li&gt;光猫只负责拨号和 &lt;code&gt;DMZ&lt;/code&gt; ，其中 &lt;code&gt;DMZ&lt;/code&gt; 是遗留之前的公网套路没有换，映射到了群晖上。因此，公网依旧可以访问群晖。这是由于搭建之初防止连接出现问题的兜底方案。&lt;/li&gt;
&lt;li&gt;一级路由使用了新 3，可以换更好一些的，主要是我把自己的小米路由器 3 玩儿死了，不想折腾直接淘宝买了个&lt;code&gt;breed&lt;/code&gt;的。用&lt;code&gt;openwrt&lt;/code&gt;来实现一些额外功能。&lt;/li&gt;
&lt;li&gt;一级路由下直接接交换机。不是因为口不够了（确实不够），而是因为内网间数据传输使用交换机的速度要比通过一个路由器解析转发快得多。现在通过交换机间进行数据传输基本是百兆的速度。&lt;/li&gt;
&lt;li&gt;交换机下接二级路由，即小米路由器。利用它的 &lt;code&gt;WIFI&lt;/code&gt; 对内提供 WIFI6 的速度。 WIFI6 和原有的速度相比差一个量级——虽然我没感觉到。同时，光猫和一级路由的无线功能关闭，让它们做好本职工作。&lt;/li&gt;
&lt;li&gt;群晖和作为服务器的主机接在交换机上。&lt;/li&gt;
&lt;li&gt;树莓派可以广告拦截，可以做外网与内网的桥。无线网络接二级路由，有线网络接一级路由，作为一级路由网络环境和二级之间的桥梁，主要用于远程控制智能家居。&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;软件部分&#34;&gt;软件部分&lt;/h3&gt;
&lt;p&gt;首先，断掉公网（也可以不断），使用树莓派做内网穿透，只穿透下面要作为代理的服务端口。
由于迁移改造工作尚未完成，因此现在用的是群晖作为代理服务。也就是，不暴露公网，只有自己在外可以访问的这个内网的工作，本应由树莓派去做。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;桥&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体的配置可以看 &lt;a href=&#34;https://github.com/rxrw/bridge&#34;&gt;这里&lt;/a&gt; ，其中：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;需申请一个证书用来 TLS ， 如果你不需要加密，那就改一下配置。相关配置在 v2ray 和 caddy 中都可以找到。&lt;/li&gt;
&lt;li&gt;此处 v2ray 暴露的端口在 caddyfile 中写明，&lt;code&gt;docker-compose.yaml&lt;/code&gt; 中的端口与内网穿透服务的端口一致。如果使用公网直接暴露，需要通过光猫 DMZ 或端口转发将此接口暴露。&lt;/li&gt;
&lt;li&gt;客户端的端口则是网络出口，即内网穿透出来的端口/光猫暴露的对外端口。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如此，在群晖上起 server ：&lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;在要用的客户端上起 client ： &lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;没有意外的话，现在内网和你所在的外网就是通的了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dns&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;主机上肯定是要跑服务的，而我们又不可能每一个服务写一个 host 或者每一个服务开一个端口。因此，群晖和主机上都起了一个 &lt;a href=&#34;https://traefik.io/&#34;&gt;Traefik&lt;/a&gt; 进行集中反向代理。为了识别方便，群晖叫 &lt;code&gt;dsm.io&lt;/code&gt; ， 主机叫 &lt;code&gt;opti.io&lt;/code&gt;。具体 traefik 相关的配置不展开。
在一级路由上，由于是 &lt;code&gt;openwrt&lt;/code&gt; 的环境，因此使用自带的 smartdns 即可，将对应的域名映射到 IP 上去。这里会遇到下一个问题，就是提供 https 服务。
使用 &lt;a href=&#34;https://github.com/FiloSottile/mkcert&#34;&gt;mkcert&lt;/a&gt; 实现证书自签，将根证书导入到 iCloud 钥匙串，iOS 系统根证书，android 证书，windows 受信任凭据中去。具体用法参见作者文档。这样家里的服务都可以通过 ssl 进行访问了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;梯子&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不多说，&lt;code&gt;openwrt&lt;/code&gt; 自带。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;广告拦截&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最初使用的是 &lt;code&gt;openwrt&lt;/code&gt;上自带的 &lt;code&gt;AdGuardHome&lt;/code&gt; 。用了之后发现比较占用运行速度。虽说可以使用它做一些额外的功能，但是路由器的核心还是转发，因此使用树莓派做这个功能。简单说就是将 &lt;code&gt;smartdns&lt;/code&gt; 的上游 dns 服务器设置为树莓派上 &lt;code&gt;adguard home&lt;/code&gt; 的 IP 即可。&lt;/p&gt;
&lt;h3 id=&#34;客户端部分&#34;&gt;客户端部分&lt;/h3&gt;
&lt;p&gt;家中网络基本配置好了。从外网访问，需要将相关的服务启动。此时 &lt;code&gt;docker&lt;/code&gt; 会起一个 14280 端口的 http 代理（依客户端 &lt;code&gt;docker-compose.yaml&lt;/code&gt; 的配置）。
Chrome 上推荐 &lt;a href=&#34;https://chrome.google.com/webstore/detail/proxy-switchyomega/padekgcemlokbadohgkifijomclgjgif&#34;&gt;Proxy SwitchOmega&lt;/a&gt; 插件，可以实现不同域名访问不同代理。使用自动切换模式，将自己的代理配置好。&lt;/p&gt;
&lt;h2 id=&#34;总结&#34;&gt;总结&lt;/h2&gt;
&lt;p&gt;目前，家中使用 &lt;code&gt;Emby&lt;/code&gt; + &lt;code&gt;Infuse Pro&lt;/code&gt; 看电影，通过&lt;code&gt;媒体中心&lt;/code&gt; + &lt;code&gt;PT&lt;/code&gt; 进行媒体管理，域名解析到 &lt;code&gt;dsm.io&lt;/code&gt; 。内网跑一个 &lt;code&gt;gitlab&lt;/code&gt; 和其他服务。通过外网可以拉代码，部署。一切运行正常&lt;/p&gt;
&lt;h3 id=&#34;刚才说的比较怪的配置&#34;&gt;刚才说的比较怪的配置&lt;/h3&gt;
&lt;p&gt;大部分都解释完了，主要是 PC 为什么会连到光猫呢？打英雄联盟的时候突然发现网络不稳定，以为是 DNS 配置导致的，因此直接连到光猫上了。但是后来发现，似乎不是这么回事儿，貌似是光猫不太稳定。&lt;/p&gt;
&lt;h2 id=&#34;优化&#34;&gt;优化&lt;/h2&gt;
&lt;p&gt;接下来的优化点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关闭公网，使用内网穿透进行访问&lt;/li&gt;
&lt;li&gt;网络代理切换到树莓派上&lt;/li&gt;
&lt;/ul&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">ulysses 和 vscode ?</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/ulysses_%E5%92%8C_vscode_/" />
            <id>https://rxrw.me/tech/ulysses_%E5%92%8C_vscode_/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-01-13T07:52:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">初 其实最初接触 markdown ，还用了比较久的时间想要用什么 IDE 。因为主力工作本已经换成了 mac ，所以可……</summary>
            
                <content type="html">&lt;h2 id=&#34;初&#34;&gt;初&lt;/h2&gt;
&lt;p&gt;其实最初接触 &lt;code&gt;markdown&lt;/code&gt; ，还用了比较久的时间想要用什么 IDE 。因为主力工作本已经换成了 mac ，所以可以暂时不考虑 windows 下的东西了。&lt;/p&gt;
&lt;p&gt;日常百度一下，发现了一个 &lt;code&gt;mweb&lt;/code&gt;。当时试用了一段时间，还比较好用，就买了 2。&lt;/p&gt;
&lt;p&gt;大概用了 2 个月吧，放弃了。原因：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;卡，超级卡&lt;/li&gt;
&lt;li&gt;移动端体验不好&lt;/li&gt;
&lt;li&gt;丑&lt;/li&gt;
&lt;li&gt;文库管理的稀烂，只能在 icloud 云盘里建一个文件夹存着。要是说规范的格式也好，给我存的乱七八糟..&lt;/li&gt;
&lt;li&gt;作者很傲慢.. 从他平时发的文档就可以看出来，&lt;code&gt;v2ex&lt;/code&gt;已经有 3 个月没人回复的 issue 了&lt;/li&gt;
&lt;li&gt;更可气的是，出了个 mweb3，居然没有升级优惠.. 然后我发现我买的时候不久黑五半价&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;纠结&#34;&gt;纠结&lt;/h2&gt;
&lt;p&gt;同时在寻找下一个 &lt;code&gt;markdown&lt;/code&gt; IDE 。然后 &lt;code&gt;ulysses&lt;/code&gt; 被发现了。&lt;/p&gt;
&lt;p&gt;第一个感觉就是清新，自然。于是没有多想直接就买了。因为是订阅制，所以每月价格也不高，就按年续订了。&lt;/p&gt;
&lt;p&gt;因为当时写文章主要是发到公众号，所以，能渲染就行。而且它的进度-成就做的还不错，在写小说的时候还是比较有用的。&lt;/p&gt;
&lt;p&gt;但是最近因为写博客（部落格），发现了它的一些问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不支持图床&lt;/li&gt;
&lt;li&gt;发布功能极其有限（&lt;code&gt;wordpress&lt;/code&gt;,&lt;code&gt;ghost&lt;/code&gt;,&lt;code&gt;medium&lt;/code&gt;）&lt;/li&gt;
&lt;li&gt;文件管理黑盒（而且！看不见文件创建时间..）&lt;/li&gt;
&lt;li&gt;不是标准的 &lt;code&gt;markdown&lt;/code&gt; 语法&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为什么大家都喜欢自创语法呢..&lt;/p&gt;
&lt;p&gt;在写《永别 2020》的时候删除线要哭死我了。&lt;/p&gt;
&lt;p&gt;那时候发现甚至 &lt;code&gt;vscode&lt;/code&gt; 写博客也不错哦…&lt;/p&gt;
&lt;p&gt;毕竟&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;markdown 只是一个标记语言，放到哪里都是一样用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;但是屈服于 &lt;code&gt;ulysses&lt;/code&gt; 的文库管理，这篇文章还是在这里写的..&lt;/p&gt;
&lt;p&gt;同时也看 &lt;code&gt;typeora&lt;/code&gt; 等其他的编辑器，可能.. 就像 &lt;code&gt;vscode&lt;/code&gt; 和各种 &lt;code&gt;idea&lt;/code&gt; 家产品是一样的区别吧。一个是编辑器，一个是 IDE 。&lt;/p&gt;
&lt;p&gt;不过，话说回来，在一般情况下，也不会太考虑各种 &lt;code&gt;markdown&lt;/code&gt; 之间的太大差别。&lt;/p&gt;
&lt;p&gt;前两天被 &lt;code&gt;ulysses&lt;/code&gt; 的文库管理折腾了半天，还是归咎于自己换 &lt;code&gt;Apple ID&lt;/code&gt; 的锅，能同步回来已经很不错了。&lt;/p&gt;
&lt;h2 id=&#34;答案&#34;&gt;答案&lt;/h2&gt;
&lt;p&gt;写完这篇，我想我大概也有答案了。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E9%9A%8F%E7%AC%94/" term="技术 随笔" label="技术 随笔" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">无聊早安生成器</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E6%97%A0%E8%81%8A%E6%97%A9%E5%AE%89%E7%94%9F%E6%88%90%E5%99%A8/" />
            <id>https://rxrw.me/tech/%E6%97%A0%E8%81%8A%E6%97%A9%E5%AE%89%E7%94%9F%E6%88%90%E5%99%A8/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2021-01-08T14:25:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">这两天写了一个特别无聊的东西.. 可以通过 ui 界面生成想要的模块，然后添加快捷指令，设置……</summary>
            
                <content type="html">&lt;p&gt;这两天写了一个特别无聊的东西..&lt;/p&gt;
&lt;p&gt;可以通过 ui 界面生成想要的模块，然后添加快捷指令，设置自动化，然后就可以每天早晨听到了。&lt;/p&gt;
&lt;p&gt;代码在此：&lt;a href=&#34;https://github.com/rxrw/daily_reminder&#34;&gt;https://github.com/rxrw/daily_reminder&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;模块根据大家的需求可以开发。&lt;/p&gt;
&lt;p&gt;使用直接： &lt;a href=&#34;https://qr.iuv520.com&#34;&gt;https://qr.iuv520.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;很难看的界面…&lt;/p&gt;
&lt;p&gt;写下来发现 &lt;code&gt;go&lt;/code&gt; 还是个很爽的语言，hhh&lt;/p&gt;
&lt;p&gt;没啥写的..&lt;/p&gt;
&lt;p&gt;目前支持：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;彩票中奖的播报&lt;/li&gt;
&lt;li&gt;所在地天气预报&lt;/li&gt;
&lt;li&gt;微博热搜&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;六小时更新一次&lt;/p&gt;
&lt;p&gt;为什么开源呢？&lt;/p&gt;
&lt;p&gt;因为 push 的时候发现家里的 git 挂了…&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;动机是因为每天兑奖彩票太麻烦了&amp;hellip;所以里面还包含了一个小算法哦&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;最近感觉 ulysses 用的好难受哦&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3-%E5%B7%A5%E5%85%B7%E5%88%86%E4%BA%AB/" term="技术 开发文档 工具分享" label="技术 开发文档 工具分享" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">PHP GRPC 的试水</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/php_grpc_%E7%9A%84%E8%AF%95%E6%B0%B4/" />
            <id>https://rxrw.me/tech/php_grpc_%E7%9A%84%E8%AF%95%E6%B0%B4/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2020-11-16T04:06:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">先说环境 MacOS 10.16 brew php 7.4+ 前言 研究微服务治理，苦于找不到相对于 php 合适的 rpc 框架。多个服务起来，……</summary>
            
                <content type="html">&lt;h2 id=&#34;先说环境&#34;&gt;先说环境&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;MacOS 10.16&lt;/li&gt;
&lt;li&gt;brew&lt;/li&gt;
&lt;li&gt;php 7.4+&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;研究微服务治理，苦于找不到相对于 &lt;code&gt;php&lt;/code&gt; 合适的 &lt;code&gt;rpc&lt;/code&gt; 框架。多个服务起来，用 &lt;code&gt;curl&lt;/code&gt; 或者 &lt;code&gt;guzzle&lt;/code&gt; 相互域名请求简直太逆天奇葩了。由于服务大部分都是 &lt;code&gt;php&lt;/code&gt; 的，没有常驻后台的 &lt;code&gt;daemon&lt;/code&gt; 开发送心跳。因此对于 &lt;code&gt;rpc&lt;/code&gt; 的选型也是个很严肃的问题。
看过 &lt;code&gt;yar&lt;/code&gt; 、 &lt;code&gt;dubbo&lt;/code&gt; 等协议，但是不是特别理想。 &lt;code&gt;yar&lt;/code&gt; 本身是 &lt;code&gt;php&lt;/code&gt; 的扩展。但是不支持服务治理，或者说只是一个远程过程调用的工具。 &lt;code&gt;dubbo&lt;/code&gt; 主力支持 &lt;code&gt;java&lt;/code&gt;，其他语言虽然支持，但本质对于 &lt;code&gt;php&lt;/code&gt; 来说和 &lt;code&gt;curl&lt;/code&gt; 没大区别。今儿记录一下 &lt;code&gt;php&lt;/code&gt; + &lt;code&gt;grpc&lt;/code&gt; 的过程&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;p&gt;官方文档：&lt;a href=&#34;https://grpc.io/docs/languages/php/quickstart/&#34;&gt;https://grpc.io/docs/languages/php/quickstart/&lt;/a&gt;
本身就支持 php 的服务端和客户端，按文档操作如下：
安装扩展：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pecl install protobuf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pecl install grpc
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面 &lt;code&gt;protobuf&lt;/code&gt; 是 &lt;code&gt;grpc&lt;/code&gt; 通信所使用的协议。类似&lt;code&gt;thrift&lt;/code&gt;，一个跨语言的结构定义工具？（瞎起）&lt;/p&gt;
&lt;p&gt;安装好后，按照文档，装个 &lt;code&gt;php-protoc&lt;/code&gt; 插件，用来生成 &lt;code&gt;php&lt;/code&gt; 相关的 &lt;code&gt;class&lt;/code&gt; 和 &lt;code&gt;service&lt;/code&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone -b v1.33.2 https://github.com/grpc/grpc
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; grpc
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git submodule update --init
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make grpc_php_plugin
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第一次安装一直在报&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Can&lt;span class=&#34;err&#34;&gt;&amp;#39;&lt;/span&gt;t &lt;span class=&#34;nb&#34;&gt;exec&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aclocal&amp;#34;&lt;/span&gt;: No such file or directory at /usr/local/Cellar/autoconf/2.69/share/autoconf/Autom4te/FileUtils.pm line 326.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;然后发现是因为&lt;code&gt;automake&lt;/code&gt;没装。好吧。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install automake
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;brew install protobuf &lt;span class=&#34;c1&#34;&gt;#这个我偶然装的 不知道不装对后续会不会有影响&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;重新执行上述命令，编译安装完了。&lt;/p&gt;
&lt;h2 id=&#34;first-example&#34;&gt;First Example&lt;/h2&gt;
&lt;p&gt;继续按照文档，执行代码库里的 &lt;code&gt;submoudle&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; examples/php
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./greeter_proto_gen.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如此应该是把预定义好的这个生成了 &lt;code&gt;php&lt;/code&gt; 的文件，目录结构如下&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;i@wdeMacBook-Pro:~/Code/grpc-try/grpc/examples/php&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;ee5b762f33⚡ ⇒  ll
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;total &lt;span class=&#34;m&#34;&gt;40&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;drwxr-xr-x   &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; i  staff    96B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 11:11 GPBMetadata
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;drwxr-xr-x   &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; i  staff   160B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 11:11 Helloworld
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw-r--r--   &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; i  staff   1.0K &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 README.md
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw-r--r--   &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; i  staff   348B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 composer.json
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;drwxr-xr-x  &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; i  staff   352B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 &lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rw-r--r--   &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; i  staff   1.5K &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 greeter_client.php
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rwxr-xr-x   &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; i  staff   728B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 greeter_proto_gen.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;drwxr-xr-x   &lt;span class=&#34;m&#34;&gt;6&lt;/span&gt; i  staff   192B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 route_guide
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;-rwxr-xr-x   &lt;span class=&#34;m&#34;&gt;1&lt;/span&gt; i  staff   691B &lt;span class=&#34;m&#34;&gt;11&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; 10:42 run_greeter_client.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;接着执行&lt;code&gt;composer install&lt;/code&gt; 安装相关依赖。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ../node
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;教程中用 node 起了一个服务端。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;npm install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;第一次安装报错，好吧。再装一次，提示我 &lt;code&gt;Error: The gRPC binary module was not installed. This may be fixed by running &amp;quot;npm rebuild&amp;quot;&lt;/code&gt;
我 tm。。
经过各种&lt;code&gt;npm install&lt;/code&gt;，算是装完了。然后&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; dynamic_codegen
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;node greeter_server.js
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;目测已经起来了，没有任何提示
再开一个窗口，执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./run_greeter_client.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PHP Warning:  PHP Startup: Unable to load dynamic library &lt;span class=&#34;s1&#34;&gt;&amp;#39;grpc.so&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;tried: /usr/local/lib/php/pecl/20190902/grpc.so &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dlopen&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;/usr/local/lib/php/pecl/20190902/grpc.so, 9&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: image not found&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, /usr/local/lib/php/pecl/20190902/grpc.so.so &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dlopen&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;/usr/local/lib/php/pecl/20190902/grpc.so.so, 9&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: image not found&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt; in Unknown on line &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Warning: PHP Startup: Unable to load dynamic library &lt;span class=&#34;s1&#34;&gt;&amp;#39;grpc.so&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;tried: /usr/local/lib/php/pecl/20190902/grpc.so &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dlopen&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;/usr/local/lib/php/pecl/20190902/grpc.so, 9&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: image not found&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;, /usr/local/lib/php/pecl/20190902/grpc.so.so &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;dlopen&lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;/usr/local/lib/php/pecl/20190902/grpc.so.so, 9&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt;: image not found&lt;span class=&#34;o&#34;&gt;))&lt;/span&gt; in Unknown on line &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PHP Fatal error:  Uncaught Error: Class &lt;span class=&#34;s1&#34;&gt;&amp;#39;Grpc\ChannelCredentials&amp;#39;&lt;/span&gt; not found in /Users/i/Code/grpc-try/grpc/examples/php/greeter_client.php:30
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Stack trace:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#0 /Users/i/Code/grpc-try/grpc/examples/php/greeter_client.php(44): greet(&amp;#39;localhost:50051&amp;#39;, &amp;#39;world&amp;#39;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#1 {main}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  thrown in /Users/i/Code/grpc-try/grpc/examples/php/greeter_client.php on line &lt;span class=&#34;m&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Fatal error: Uncaught Error: Class &lt;span class=&#34;s1&#34;&gt;&amp;#39;Grpc\ChannelCredentials&amp;#39;&lt;/span&gt; not found in /Users/i/Code/grpc-try/grpc/examples/php/greeter_client.php:30
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Stack trace:
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#0 /Users/i/Code/grpc-try/grpc/examples/php/greeter_client.php(44): greet(&amp;#39;localhost:50051&amp;#39;, &amp;#39;world&amp;#39;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;#1 {main}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  thrown in /Users/i/Code/grpc-try/grpc/examples/php/greeter_client.php on line &lt;span class=&#34;m&#34;&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;。。。官网说的 &lt;code&gt;congratulation&lt;/code&gt; 给谁听呢。。
&lt;code&gt;php -m&lt;/code&gt;果然没看见我的 &lt;code&gt;grpc&lt;/code&gt; 。。再装一遍看看
…漫长的编译之旅
这回看见了 难道我刚才装了个寂寞
这回执行&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;./run_greeter_client.sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;PHP Warning:  Module &lt;span class=&#34;s1&#34;&gt;&amp;#39;grpc&amp;#39;&lt;/span&gt; already loaded in Unknown on line &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Warning: Module &lt;span class=&#34;s1&#34;&gt;&amp;#39;grpc&amp;#39;&lt;/span&gt; already loaded in Unknown on line &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;Hello world
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;OK，这是看见了服务端的返回了。（btw，安装的时候自己在 &lt;code&gt;php.ini&lt;/code&gt; 里加了 &lt;code&gt;extension&lt;/code&gt; ，然后还说重复了。我再删了就好了。原因是脚本中执行的语句，自己看。）&lt;/p&gt;
&lt;h2 id=&#34;看一看代码&#34;&gt;看一看代码&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;vscode&lt;/code&gt; 打开 &lt;code&gt;php&lt;/code&gt; 目录， &lt;code&gt;HelloWorld&lt;/code&gt; 和 &lt;code&gt;GPBMetadata&lt;/code&gt; 都是由 &lt;code&gt;protobuf&lt;/code&gt; 生成的。 &lt;code&gt;proto&lt;/code&gt; 文件在上层目录的 &lt;code&gt;protos&lt;/code&gt; 下，长如下这样：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Copyright 2015 gRPC authors.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// you may not use this file except in compliance with the License.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// You may obtain a copy of the License at
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//     http://www.apache.org/licenses/LICENSE-2.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// Unless required by applicable law or agreed to in writing, software
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// See the License for the specific language governing permissions and
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// limitations under the License.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;syntax&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;proto3&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;java_multiple_files&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;java_package&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;io.grpc.examples.helloworld&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;java_outer_classname&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;HelloWorldProto&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;option&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;objc_class_prefix&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;HLW&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;helloworld&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// The greeting service definition.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;service&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Greeter&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;c1&#34;&gt;// Sends a greeting
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nx&#34;&gt;rpc&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;SayHello&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;HelloRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;returns&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;HelloReply&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// The request message containing the user&amp;#39;s name.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;HelloRequest&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// The response message containing the greetings
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;HelloReply&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;定义了 &lt;code&gt;package&lt;/code&gt; 名 &lt;code&gt;helloworld&lt;/code&gt; ， &lt;code&gt;service&lt;/code&gt; 对应 &lt;code&gt;php&lt;/code&gt; 的命名空间， &lt;code&gt;message&lt;/code&gt; 对应的是结构体。对应 &lt;code&gt;php&lt;/code&gt; 的 &lt;code&gt;HelloWorld&lt;/code&gt; 目录下的东西。可以用 &lt;code&gt;composer&lt;/code&gt; 加载，也可以用 &lt;code&gt;require\_once&lt;/code&gt; 加载。
看下函数&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;php&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;require&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;dirname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;__FILE__&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;/vendor/autoload.php&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;greet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;$client&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Helloworld\GreeterClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;s1&#34;&gt;&amp;#39;credentials&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Grpc\ChannelCredentials&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;createInsecure&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;$request&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Helloworld\HelloRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nv&#34;&gt;$request&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;setName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$client&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;SayHello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;wait&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!==&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Grpc\STATUS_OK&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ERROR: &amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;code&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;, &amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$status&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;details&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;PHP_EOL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;exit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$response&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;getMessage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;.&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;PHP_EOL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;world&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$hostname&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;])&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$argv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;localhost:50051&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;greet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$hostname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;直接通过 &lt;code&gt;protobuf&lt;/code&gt; 定义的 &lt;code&gt;Client&lt;/code&gt; 就可以实例化啦。对应的方法啥的都已经在里面了。没错，就是我们想要的亚子。&lt;/p&gt;
&lt;p&gt;接下来需要考虑的还有服务端的架设，服务中心的架设。不说了，再研究研究。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">（四）判断条件 —— 一起学python系列</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E5%9B%9B%E5%88%A4%E6%96%AD%E6%9D%A1%E4%BB%B6__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/" />
            <id>https://rxrw.me/tech/%E5%9B%9B%E5%88%A4%E6%96%AD%E6%9D%A1%E4%BB%B6__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2019-08-26T12:22:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">前言 欢迎回来大家。今天言归正传，之前的内容大家学习的怎么样了呢？有点难理解？没关系，……</summary>
            
                <content type="html">&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;欢迎回来大家。今天言归正传，之前的内容大家学习的怎么样了呢？有点难理解？没关系，周末视频讲解，消化好之前的知识！&lt;/p&gt;
&lt;h2 id=&#34;判断条件&#34;&gt;判断条件&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;how_old_are_you&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;你比我大哦&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;year&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;我们一样大，都是&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;年出生的哦&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;我比你大，叫哥哥！&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;回到第二篇的这个方法。首先我们知道 def 表示声明一个函数，叫 how_old_are_you。它接收一个变量叫 your_age。通过第三节的运行我们看到这个方法可以根据年龄比较大小。它是怎么做到的呢？那很明显就是通过里面的 if 进行判断的啦。
Python 语言的一大优势就是比起其他语言更贴近自然语言。if your_age &amp;gt; self.age: 直译出来就是如果前者大于后者。如果前者大于后者怎么样呢？那就执行冒号后面的语句吧！也就是 print(‘你比我大哦’)这句话啦！
再然后，elif 就是 else if 的缩写，不过 python 中要用 elif 来代替。这回中间这两者就是==符号。这个在编程界叫做逻辑运算符，如果==两边的值完全相等，则这个表达式就是“正确”的意思，在 python 中用”True”表示。if 后面的表达式如果是 True 则执行这句话冒号后面的语句块。先来看判断条件。如果都不符合，最后还有一个 else，就是否则的意思啦。如果都不符合那就执行 else 后面的话咯。&lt;/p&gt;
&lt;h2 id=&#34;简单的模块调用&#34;&gt;简单的模块调用&lt;/h2&gt;
&lt;p&gt;在上一节看到 elif 中的语句是什么 datetime 呀。还记得我们之前引入了个包吗，import datetime 引入的就是一个第三方扩展。这个包里的内容可以帮我们处理事件相关的一些内容。像 datetime.date.today()就是 datetime 包中 date 类里的 today()方法，用来返回一个日期对象。那么这个对象中有一个属性就是 year。通过这个我们就可以拿到年份啦。相减得出了最后的结果！&lt;/p&gt;
&lt;h2 id=&#34;逻辑运算符和赋值运算符&#34;&gt;逻辑运算符和赋值运算符&lt;/h2&gt;
&lt;p&gt;刚才我们提到了 if 里面的判断条件。这里需要稍微详细讲解一下。
我们日常说的“你是不是 XXX？”这里面的“是不是”就是一个逻辑运算符。表达的是两者是否相等呢？这种情况和上述的 your_age 与 age 之间的比较是一个道理。因此，两个等号组成的符号叫做逻辑运算符。同样地，&amp;gt;和&amp;lt;也是逻辑运算符。他们是用来将两者进行判断，最终返回是或否的，在计算机里就是真或假，用代码表示就是 True 和 False。
之前我们说过 age=10 是将 10 赋值给了 age 这个变量。就像 y=2x+1，这里的等号是用于右边的表达式计算后得出结果给 y 一样。这个等号是赋值运算符。同样地，+-*/也是赋值运算符。它们最终得到的是计算后的结果。
这里简单介绍一下，不要弄混了哦，这两个没什么相关性的。&lt;/p&gt;
&lt;h3 id=&#34;结束啦&#34;&gt;结束啦&lt;/h3&gt;
&lt;p&gt;明天我们可能会讲循环，也可能出视频。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">（三）函数 —— 一起学python系列</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%B8%89%E5%87%BD%E6%95%B0__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/" />
            <id>https://rxrw.me/tech/%E4%B8%89%E5%87%BD%E6%95%B0__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2019-08-25T12:22:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">前言 上一篇我们讲了一段简单代码的一部分，今天我们继续讲。 另，后续我会开一个新的公众号……</summary>
            
                <content type="html">&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;上一篇我们讲了一段简单代码的一部分，今天我们继续讲。
另，后续我会开一个新的公众号来专讲 python，将采用全新生动的模式来为小白零基础的同学们开启新世界的大门。欢迎关注！&lt;/p&gt;
&lt;h2 id=&#34;变量&#34;&gt;变量&lt;/h2&gt;
&lt;p&gt;上节课我们讲了包的引入和类的概念。今天我们继续之前的代码往下讲。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;首先我们要注意一点，这句话和后面的一大堆都是带有缩进的。也就是在 class 那句话的后面。缩进代表有缩进的部分都是上一行里面的部分，也就是这一大块都是类的内容。我们可以用空格或者 tab 来进行缩进但是一定不能混用。一般我们用 2 或 4 个空格来表示缩进。一般情况下一个 tab 等于 4 个空格。
来我们看一下这一行代码。&lt;code&gt;age&lt;/code&gt;是一个属性，也是一个类变量。变量就是一个单词可以代表一个值的东西。类变量就是能表示类属性，在类中直接定义的变量。在 python 中是不需要定义类型的。python 只有字符串，整数和小数三种基本类型。数字和小数直接写就好，字符串要加双引号。这个之后会说。像 age 就是一个数字属性的变量。是类&lt;code&gt;Hello&lt;/code&gt;的一个属性。我们在以后会用到这个变量。&lt;/p&gt;
&lt;h2 id=&#34;函数&#34;&gt;函数&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;say_hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;hello &amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;!&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这段呢是一个函数，我们也可以称之为方法。数学中的函数呢是有自变量，有因变量。那么括号里的可以看作是自变量，函数如果最后有&lt;code&gt;return&lt;/code&gt;就是会返回一个因变量。函数嘛就是来实现功能的，标准格式就是前方空一行，开头 def 加空格，然后是函数名，后面的括号里就是参数也就是自变量列表，然后跟一个冒号。下面缩进一格写函数内容，也叫函数体。在里面就是具体的实现方法啦。这里没有写很复杂的方法，就是输出了个 Hello +传入的参数 name。
这里的 print 将内容输出到屏幕上。字符串之间是可以通过加号连接的。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;how_old_are_you&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;你比我大哦&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;year&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;我们一样大，都是&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;年出生的哦&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;我比你大，叫哥哥！&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个方法也是一个输出方法，但是里面涉及的内容比较多。明天我们主要讲这个方法，今天有点晚了可能讲不完，就先不讲啦，下一章我们通过这个方法认识条件语句，也叫流程控制语句。&lt;/p&gt;
&lt;h2 id=&#34;运行程序&#34;&gt;运行程序&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;请输入你的姓名：&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;请输入你的年龄：&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;各位请看好，这两句话没有缩进哦。说明从这里开始已经不是 Hello 类中的内容啦。那么当我们运行一个 python 脚本时，就是按顺序执行的。类中的内容属于预先定义的内容，你不调用它不执行，而是从这种独立的语句开始执行的。
input 方法用于接收用户输入，并返回给等号前面的变量。这个方法是我们暂时和计算机程序交互的一个方法。通过执行了这两句话，计算机就可以收到我们输入的内容啦！&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;say_hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;how_old_are_you&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在接收到我们的内容的同时，&lt;code&gt;name&lt;/code&gt;和&lt;code&gt;age&lt;/code&gt;两个值也就存起来了。python 把它们放到内存的某个区域中。接下来，&lt;code&gt;hello = Hello()&lt;/code&gt;这句话就是我们上面所说的，将&lt;code&gt;Hello&lt;/code&gt;这个类实例化，产生了&lt;code&gt;hello&lt;/code&gt;这个对象。这里我们要注意，两个单词的大小写不同，所代表的含义也不同哦。他俩在这里是类和对象的关系，在其他地方可能没什么联系，这是人为定义的。所以大家一定要注意，在编程中大小写的要求是很严格的，千万不要混淆哦。
在实例化了&lt;code&gt;Hello&lt;/code&gt;类生成了&lt;code&gt;hello&lt;/code&gt;对象后，就可以通过&lt;code&gt;hello&lt;/code&gt;这个对象来调用类中定义的方法啦。有的同学可能会问：为什么不能直接用类来调用方法呢？答案是可以。但是只是一些其中的方法。接着猫猫狗狗的例子，你可能对你家的狗狗喊道：“欢欢，过来！”它会开开心心地朝你跑过来。这里接收指令执行动作的是欢欢，也就是狗的实例，而不是狗这个分类。所以，大部分情况下，调用类方法必须先将方法实例化。&lt;/p&gt;
&lt;p&gt;最后看一下这个程序的演示：&lt;/p&gt;
&lt;p&gt;第一行和最后一行是系统输出不用管。中间则是我们定义好的函数和输入输出的方法。系统先让我们输入了姓名和年龄，然后实例化了&lt;code&gt;Hello&lt;/code&gt;类，最终执行了其中的&lt;code&gt;say_hello&lt;/code&gt;和&lt;code&gt;how_old_are_you&lt;/code&gt;方法，输出了这两句话！&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/learn-python-together-3/b6da7936d2fe77e2d70e923445f03dd2.jpg&#34; alt=&#34;演示&#34;&gt;&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">（二）速览 —— 一起学python系列</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BA%8C%E9%80%9F%E8%A7%88__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/" />
            <id>https://rxrw.me/tech/%E4%BA%8C%E9%80%9F%E8%A7%88__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2019-08-24T12:22:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">说在前面 为了目标而努力 周末休息… 之后的周末，会给大家留一个简单的小题目，我自己也是学……</summary>
            
                <content type="html">&lt;h2 id=&#34;说在前面&#34;&gt;说在前面&lt;/h2&gt;
&lt;h3 id=&#34;为了目标而努力&#34;&gt;为了目标而努力&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;周末休息… 之后的周末，会给大家留一个简单的小题目，我自己也是学习状态，所以不会太难啦。&lt;/li&gt;
&lt;li&gt;如果对于一起学系列有什么意见和建议，欢迎在文章下留言或在公众号里发送消息，我一定会及时回复每一条消息的～&lt;/li&gt;
&lt;li&gt;上一篇文章过后，大家提出了一些建议。所以文末有一个投票，希望大家参与一下，是关于如何能让这个系列文章做得更好一些的，也让大家有所收获，这样我也不算白写。&lt;/li&gt;
&lt;li&gt;如果你对这些内容感兴趣的，欢迎点击文末“在看”，分享出去吧！
&lt;blockquote&gt;
&lt;p&gt;有一个比较严肃的问题，就是这个的载体是公众号，手机端的网页，所以大家看起来可能不太舒服。但是这未免不是一件好事，在学习过程中，大家可以慢慢敲代码去学习，而不是复制粘贴，加强记忆哦。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;目标和计划&#34;&gt;目标和计划&lt;/h3&gt;
&lt;p&gt;如果说学习，应该是有规划的，怪我之前没有交代清楚，接下来补充交代一下。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;第一周：安装和初步知道 python 是什么&lt;/li&gt;
&lt;li&gt;第二周：大概对 python 和编程基础知识有一定了解，这周我们不会太深入代码。&lt;/li&gt;
&lt;li&gt;第三周：python 基础知识，包括但不限于常用函数、基础语法等，第三周后，大家应该可以用 python 写一些简单的程序啦。&lt;/li&gt;
&lt;li&gt;第四周：包、函数、类等。从第四周开始，不一定讲什么啦
最终目标：&lt;/li&gt;
&lt;/ul&gt;
&lt;ol&gt;
&lt;li&gt;我们一起用 python 爬个虫，存到数据库中&lt;/li&gt;
&lt;li&gt;分析多张 excel 中的内容，并生成词云&lt;/li&gt;
&lt;li&gt;写一个简单的微信公众号对话程序&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;初识-python&#34;&gt;初识 python&lt;/h2&gt;
&lt;p&gt;首先，我们先来看一个比较简单的程序：&lt;/p&gt;
&lt;p&gt;其中包含了最基本的语法和结构，我们对照着来解读一下，一个 python 程序是怎么构成的吧！&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/learn-python-together-2/f716f2ff7bd2a40e1bce5f080db81c1f.png&#34; alt=&#34;比较简单的程序&#34;&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;温馨提示：代码在 pycharm 中写的，这个编辑工具比较适合大家开发，之后会简单讲一下它的用法。左边是行号，中间是代码。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;datetime&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这一行以后可能会有很多行，关键字&lt;code&gt;import&lt;/code&gt;用来将外部的包导入到我们的代码中。这样，在我们的代码里就可以使用别人写好的功能，省时省力哦。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;包：在很多语言中都有类似的概念。比如我们要写一个排列组合的计算程序，里面会涉及到阶乘。在普通概念中，我们要自己写一个或多个阶乘的方法。但是引入了别人写好的包后，只需要一句话就可以完成这个操作啦。可以说，在 python 的路上，包是必不可少的内容。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;object&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;class&lt;/code&gt;关键字用来标识这是一个类。什么是类呢？用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实现，之后我们会提到。听了定义是不是有些头大？我们举个栗子：就说动物吧。比如有一种动物叫狗 🐶，那么狗有什么特征呢？有尾巴，有眼睛鼻子，有年龄身高等等。那么这些就是狗的属性。狗喜欢啃骨头，开心喜欢摇尾巴，这些就是狗能做的事情的一部分，也就是 🐶 具有的方法。好，那么狗就是一个类，它标识了具有这些属性的集合。对象是类的实例。花花就是一个狗的对象。刚才我们描述的内容花花都具备，更重要的是，它本身是一条狗。正因为它是一条狗，所以他会有这些属性。那么大毛也是，欢欢也是。它们都是狗这个类实际化后产生的对象。
回到&lt;code&gt;Hello&lt;/code&gt;类，它后面有个括号是什么呢？它表示一种继承关系，表示&lt;code&gt;Hello&lt;/code&gt;是属于&lt;code&gt;object&lt;/code&gt;的。&lt;code&gt;object&lt;/code&gt;是什么，继承又是什么呢？我们继续说 🐶。我们知道了狗是一个类，有这个那个属性，但是猫也有啊，甚至有的属性人也有呀？因为我们都是哺乳动物。那么狗，猫，人都是属于哺乳动物的吧，哺乳动物也有一些特性。比如用肺呼吸，体温恒定等等。我们把共同的特征放在哺乳动物类里面去，这样就不用提到狗或者猫就要说很多相同的内容啦，只需要说一个哺乳动物就可以概括了。那么我们可以说猫狗人三个类都是哺乳动物的子类，换句话说，它们继承了哺乳动物类。在 python 中就可以表达为 &lt;code&gt;class 猫(哺乳动物):&lt;/code&gt;。
这么说可以理解了吧。那么 object 是什么类？为什么我们的 Hello 要继承它呢？原来&lt;code&gt;object&lt;/code&gt;是 python 中最顶级的类，它是所有类的父类。类似于现实世界中的夸克。当然，我们也可以省略这个&lt;code&gt;object&lt;/code&gt;，因为默认没有父类的类都是继承于它的。
有了类之后就要有自己的属性和方法啦。我们接着往下看。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;可以看到，class 这句话距离上方有两个空行。这可不是随意按的回车哦。这个是 python 标准语法格式。类定义之前要有两个空行。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;n&#34;&gt;age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;首先我们要注意一点，这句话和后面的一大堆都是带有缩进的。也就是在 class 那句话的后面。缩进代表有缩进的部分都是上一行里面的部分，也就是这一大块都是类的内容。我们可以用空格或者 tab 来进行缩进但是一定不能混用。一般我们用 2 或 4 个空格来表示缩进。一般情况下一个 tab 等于 4 个空格。
来我们看一下这一行代码。&lt;code&gt;age&lt;/code&gt;是一个属性，也是一个类变量。变量就是一个单词可以代表一个值的东西。类变量就是能表示类属性，在类中直接定义的变量。在 python 中是不需要定义类型的。python 只有字符串，整数和小数三种基本类型。数字和小数直接写就好，字符串要加双引号。这个之后会说。像 age 就是一个数字属性的变量。是类&lt;code&gt;Hello&lt;/code&gt;的一个属性。我们在以后会用到这个变量。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;say_hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;hello &amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;!&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这段呢是一个函数，我们也可以称之为方法。数学中的函数呢是有自变量，有因变量。那么括号里的可以看作是自变量，函数如果最后有&lt;code&gt;return&lt;/code&gt;就是会返回一个因变量。函数嘛就是来实现功能的，标准格式就是前方空一行，开头 def 加空格，然后是函数名，后面的括号里就是参数也就是自变量列表，然后跟一个冒号。下面缩进一格写函数内容，也叫函数体。在里面就是具体的实现方法啦。这里没有写很复杂的方法，就是输出了个 Hello +传入的参数 name。
这里的 print 将内容输出到屏幕上。字符串之间是可以通过加号连接的。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;def&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;how_old_are_you&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;你比我大哦&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;elif&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;your_age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;datetime&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;today&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;year&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;我们一样大，都是&amp;#39;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;str&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;-&lt;/span&gt; &lt;span class=&#34;bp&#34;&gt;self&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;年出生的哦&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;我比你大，叫哥哥！&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;这个方法也是一个输出方法，但是里面涉及的内容比较多。明天我们主要讲这个方法，今天有点晚了可能讲不完，就先不讲啦，下一章我们通过这个方法认识条件语句。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;请输入你的姓名：&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nb&#34;&gt;input&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;请输入你的年龄：&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;各位请看好，这两句话没有缩进哦。说明从这里开始已经不是 Hello 类中的内容啦。那么当我们运行一个 python 脚本时，就是按顺序执行的。类中的内容属于预先定义的内容，你不调用它不执行，而是从这种独立的语句开始执行的。
input 方法用于接收用户输入，并返回给等号前面的变量。这个方法是我们暂时和计算机程序交互的一个方法。通过执行了这两句话，计算机就可以收到我们输入的内容啦！&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;say_hello&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;hello&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;how_old_are_you&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;age&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在接收到我们的内容的同时，&lt;code&gt;name&lt;/code&gt;和&lt;code&gt;age&lt;/code&gt;两个值也就存起来了。python 把它们放到内存的某个区域中。接下来，&lt;code&gt;hello = Hello()&lt;/code&gt;这句话就是我们上面所说的，将&lt;code&gt;Hello&lt;/code&gt;这个类实例化，产生了&lt;code&gt;hello&lt;/code&gt;这个对象。这里我们要注意，两个单词的大小写不同，所代表的含义也不同哦。他俩在这里是类和对象的关系，在其他地方可能没什么联系，这是人为定义的。所以大家一定要注意，在编程中大小写的要求是很严格的，千万不要混淆哦。
在实例化了&lt;code&gt;Hello&lt;/code&gt;类生成了&lt;code&gt;hello&lt;/code&gt;对象后，就可以通过&lt;code&gt;hello&lt;/code&gt;这个对象来调用类中定义的方法啦。有的同学可能会问：为什么不能直接用类来调用方法呢？答案是可以。但是只是一些其中的方法。接着猫猫狗狗的例子，你可能对你家的狗狗喊道：“欢欢，过来！”它会开开心心地朝你跑过来。这里接收指令执行动作的是欢欢，也就是狗的实例，而不是狗这个分类。所以，大部分情况下，调用类方法必须先将方法实例化。&lt;/p&gt;
&lt;p&gt;最后看一下这个程序的演示：&lt;/p&gt;
&lt;p&gt;第一行和最后一行是系统输出不用管。中间则是我们定义好的函数和输入输出的方法。系统先让我们输入了姓名和年龄，然后实例化了&lt;code&gt;Hello&lt;/code&gt;类，最终执行了其中&lt;code&gt;的say_hello&lt;/code&gt;和&lt;code&gt;how_old_are_you&lt;/code&gt;方法，输出了这两句话！&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/learn-python-together-2/01d79d756072ae87e248206190f5bc4f.png&#34; alt=&#34;程序的演示&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;写在后面&#34;&gt;写在后面&lt;/h2&gt;
&lt;p&gt;本周的目的是让大家能简单的看懂 python 的代码，并且对基本的概念有一定的了解。所以大家不用心急什么时候可以写代码呀。以后每个周末我都会出一段视频带着大家回顾一下上一周学过的内容，欢迎支持！&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">（一）前言 —— 一起学python系列</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%B8%80%E5%89%8D%E8%A8%80__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/" />
            <id>https://rxrw.me/tech/%E4%B8%80%E5%89%8D%E8%A8%80__%E4%B8%80%E8%B5%B7%E5%AD%A6python%E7%B3%BB%E5%88%97/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2019-08-23T12:22:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">哥哥我突然有了个 good idea。 以前在社团的时候，我尝试过教我的干事们写代码。 但是由于当……</summary>
            
                <content type="html">&lt;p&gt;哥哥我突然有了个 good idea。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;以前在社团的时候，我尝试过教我的干事们写代码。
但是由于当时我也是入门编程初级阶段，炫耀的成分可能多一点，在讲的时候没有什么逻辑，于是乎效果甚微。
最近花了 ¥8.9 报名了个 python 入门教程，其实我是会的，但是想看看能在人家的教程下学到什么。于是乎——跟着教程学了三章，学到了输入数据… 然后就是买课开始。联想到之前有朋友花大价钱去学习编程课程，最近突然冒出了个想法。
对于专业论坛或者类似菜鸟教程的课程，很简单，但是对于对编程一窍不通的人是如同天书一般。我寻思着我之前也学过 python 啊，但是一直没有正式使用过（讲真，php、java 两个后端目前够我用），所以记得不太住。那之后我会把 python 基础的一些内容在这里分享给大家，不说废话，也尽量不说让大家听不懂的话。so 如果有兴趣的话，欢迎关注，我争取以两天一篇的节奏发布。
简单说，适合零基础小白的课程。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;目标&#34;&gt;目标&lt;/h2&gt;
&lt;p&gt;哥哥我的目标，也是想跟着哥哥一起的同学的目标，就是在这个教程结束之后，能自己写一个简单的爬虫程序。（爬虫就是在互联网上爬呀爬，教程结束后，我还会讲一下当年我是怎么潜入我们学校的教务系统的，这也是爬虫的一种）&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.python.org/&#34;&gt;python™&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;为什么要从 python 开始学习呢？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol&gt;
&lt;li&gt;操作简单，上手容易。python 相对于其他语言来说，语法简单，更贴近自然语言。让小白学习的时候少了一层阻力 2. 用途广泛，不会白学。像其他语言可能在互联网开发中用处比较大，比如软硬件开发，网站搭建等。而 python 除了这些呢，也可以在日常的工作中用到。简单的比如 excel 表格处理呀，数据分析呀，复杂的比如数据处理、机器学习，也可以写一个自己喜欢的小程序噢。 3. 小孩子都在学的语言。很久很久以前，毛主席讲过，“计算机要从娃娃抓起”。当年，我们学的是 QB（QBASIC 语言，不是 q 币）。现在，小孩子们上微机课都是学 python 啦。多年以后，你滴孩子没事儿写了个脚本控制智能家居，你如果不会，只会打游戏，那可咋办捏。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;起步&#34;&gt;起步&lt;/h2&gt;
&lt;p&gt;起步就是今天呢，先让大家把 python 装在自己的电脑里，没有电脑的话，手机貌似也可以运行，但是最好还是有一台自己的 computer 吧。&lt;/p&gt;
&lt;h3 id=&#34;准备工作&#34;&gt;准备工作&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;windows/mac/linux 电脑/笔记本一台&lt;/li&gt;
&lt;li&gt;互联网连接&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;安装过程&#34;&gt;安装过程&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;打开浏览器，访问 &amp;lt;www.python.org&amp;gt; ，按图示点击如果你是 mac 用户，请选择 mac。
&lt;img src=&#34;https://rxrw.me/images/zh/tech/learn-python-together-1/10928910f73813091124102161375e56.png&#34; alt=&#34;选择操作系统&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;点击第一个按钮，。我们学习的 python3 最新版。
&lt;img src=&#34;https://rxrw.me/images/zh/tech/learn-python-together-1/863ad3ef398057335134dbd6d9871632.png&#34; alt=&#34;下载&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;然后在新页面的下方选择你的系统开始下载。
&lt;img src=&#34;https://rxrw.me/images/zh/tech/learn-python-together-1/c5b203139f7b368825d1cf6c6f2abeec.png&#34; alt=&#34;选择系统&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;下载完了后，按照正常的安装步骤进行安装。 &amp;gt; mac 用户系统中其实自带了 python，不过是 2.7，而我们需要 3。所以还是要自己下。如果你有一定 shell 基础，可以参考&lt;code&gt;brew install python3&lt;/code&gt;。
mac 用户运行 python 时需要输入 python3。这是为防止与系统自带 python 冲突，所以要加版本号。&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;看一下吧&#34;&gt;看一下吧&lt;/h3&gt;
&lt;p&gt;windows 用户可以从开始菜单中运行 python，也可以打开命令行（开始-&amp;gt;所有程序-&amp;gt;附件-&amp;gt;命令提示符，或者按 windows+R 输入 cmd 按回车。打开后输入&lt;code&gt;python&lt;/code&gt;回车即可）。
mac 用户打开终端 Terminal，如果有 iterm2 最好，输入 python3 回车就 ok。
在黑黑的框中，会产生无限可能噢。以后我们的学习之路就从这个框框开始啦。
输入&lt;code&gt;print(“hello world”)&lt;/code&gt;，按下回车，出现了什么呢？
出现了另一个 hello world 对不对！虽然看不出来什么，但这可能是你的第一行代码。大家的第一行代码都是从 hello world 开始的。
在这个过程中&lt;code&gt;print&lt;/code&gt;是一个函数，python 对他已经定义了。他负责的就是将括号里的东西输出到屏幕上。为什么叫 print 而不是 display 呢。因为很久之前的电脑是没有显示器的。当时都是将输出打印出来的。所以 print 一直流传到了现在。虽然当时没有 python…
这将是你写的最简单的程序之一啦。&lt;/p&gt;
&lt;h3 id=&#34;结尾&#34;&gt;结尾&lt;/h3&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;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">如果你想学Coding II</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E5%AD%A6coding_ii/" />
            <id>https://rxrw.me/tech/%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E5%AD%A6coding_ii/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2018-08-22T07:41:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">最近搞了个新的 ipad pro，升了 ios13，好多软件都闪退，幸好这个 ulysses 还能用，多写点东西……</summary>
            
                <content type="html">&lt;blockquote&gt;
&lt;p&gt;最近搞了个新的 ipad pro，升了 ios13，好多软件都闪退，幸好这个 ulysses 还能用，多写点东西。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;之前说了些写代码入门的东西。但大概还是概念啊理解什么的，没有具体的东西。那接下来我给出一些具体的东西，哈哈哈哈，最近玩这几个东西比较上瘾。几个小游戏，锻炼编程思维和代码基础的东西。&lt;/p&gt;
&lt;h2 id=&#34;正文&#34;&gt;正文&lt;/h2&gt;
&lt;h3 id=&#34;swift-playground&#34;&gt;Swift Playground&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;硬件需求：&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ipad 一部，iphone 不可以哦&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;没了 这是一款面向于零基础编程学习软件。但是！内容由浅入深，在玩游戏的过程中学会了编程，岂不是美哉？而且这个软件自带编程功能，你也可以在空白的项目中自己创建项目自己写着玩，甚至可以创建 xcode 项目哦！&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;截图：
&lt;img src=&#34;https://rxrw.me/images/zh/tech/if-you-want-to-learn-coding-2/39d23e5adba33d0a143dbeeab9b5f382.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/if-you-want-to-learn-coding-2/e2be37713fd3a948297c3ba037a3d368.png&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;human-being-resouce&#34;&gt;Human Being Resouce&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;硬件需求：&lt;/li&gt;
&lt;li&gt;ios 系统设备，android 貌似不支持&lt;/li&gt;
&lt;li&gt;30 RMB&lt;/li&gt;
&lt;li&gt;没了 这是一款 0 代码，偏向算法的游戏。怎么玩呢，你要控制小人按照你的指令执行需求。前面很简单呐，到后来，就会要求你的代码精简并且执行速度快，一步一步完成任务吧！&lt;/li&gt;
&lt;li&gt;截图： 通过拖拽就可完成任务哦。
&lt;img src=&#34;https://rxrw.me/images/zh/tech/if-you-want-to-learn-coding-2/dcb20d41c2f1763b994a5921f15014f5.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;7-bliion-humans&#34;&gt;7 bliion humans&lt;/h3&gt;
&lt;p&gt;同样地，30RMB
跟上述的软件差不多，但这个会一起控制很多个小人儿，一家公司出的&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;截图：
&lt;img src=&#34;https://rxrw.me/images/zh/tech/if-you-want-to-learn-coding-2/77bf38fb89722d992c1db3ab42ec19d4.png&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;加油吧！&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">如果你想学Coding</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E5%AD%A6coding/" />
            <id>https://rxrw.me/tech/%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%83%B3%E5%AD%A6coding/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2018-08-21T07:41:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">前言 还是老话，虽然我会的语言多了点，但也都是一知半解，细分给不出什么建议，但大体的入……</summary>
            
                <content type="html">&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;还是老话，虽然我会的语言多了点，但也都是一知半解，细分给不出什么建议，但大体的入门方向我还是能说说的。
身边好多人都有向编程方向努力的，无论是为了多赚钱还是什么(目前我了解到的还是多赚钱)，我都予以支持。有个目标总比碌碌无为来的有意义。
但也见过挺多人从入门到放弃，甚至没有入门。想了想，打算说一下我个人认为的入门到精通编程的技巧。&lt;/p&gt;
&lt;h2 id=&#34;目的&#34;&gt;目的&lt;/h2&gt;
&lt;p&gt;先说一下你为什么想学编程。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;为了有个好的工作以及赚钱无可厚非，但写代码不是那么容易的，也很累，而且貌似现在这个时代，coding 也不是唯一一个高薪的出路。现在市场还很饱和。不是会写个 console.log 就能拿高薪的，所以单纯为了这个目的请斟酌。&lt;/li&gt;
&lt;li&gt;为了兴趣爱好，可以，但是路程可能要走的长一点。弯路是不得不走的。&lt;/li&gt;
&lt;li&gt;也没啥别的了。其实说上面两点还是我见的最多的。但是大部分人包括我都会有误区，尽我所能，聊一聊。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;说我自己&#34;&gt;说我自己&lt;/h2&gt;
&lt;p&gt;说一说我从学编程到现在的状态。高中买过一本 C++ 的书，但是看了前几章，vs 都没装过，就忙高考去了。直到大一学 C 语言，也是我唯一一科认真学了的课程。后来做微信公众平台，再后来一发不可收拾做各种东西。直到毕业，做了比较多的项目，第一份工作也算是个项目小负责人。满满意到了现在发现很多东西都在变，一直在赶。学新语言，架构什么的感觉还比较轻松。我一直归功于有 C 语言做基础。大部分人一直跟我说我有天赋分什么的。好吧其实我自己也这么认为。但光有所谓的“天赋”没有努力，谁也不能写出东西来。&lt;/p&gt;
&lt;h2 id=&#34;学什么语言&#34;&gt;学什么语言&lt;/h2&gt;
&lt;p&gt;大部分来问我的人我都推荐他们学了前端。。
优势在于，上手快，直观。对于还没入门者来说，这些东西更能提起兴趣。如果说做 python, php 什么的，可能很快就放弃了。虽然入门简单，但是不直观。同样是做一个日历程序，可能前端去完成的成就感更高一点。
缺点在于，1.需要后端支持; 2.上手容易深入难 3. 框架太多 等等吧。
但是相对于一个项目的目的来说来说，前端是一个必需品。你可以不用 php，用 java 但是你需要用 html 去让用户看见，等等。这个暂且不谈。说白了，什么语言都一样，学好了都厉害，学不好都完蛋。&lt;/p&gt;
&lt;h2 id=&#34;学习技巧&#34;&gt;学习技巧&lt;/h2&gt;
&lt;p&gt;其实说起来，技巧是有的，可能跟大家想的还真不太一样。当然了，纯个人见解。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;拒绝视频。这一点我跟和我聊过的朋友都说过。但大家并不买账，觉得有人教，跟着做就行了。of course，如果你是打算赶紧随便找个小公司混着，随意。有人说看视频教程快，但是过一阵什么都忘掉了。这个就是常态。你看视频，看的是讲师的思路，并不是你自己所想，当然记不住。而且视频只会教你一些你用的到的东西。一个学弟，在后来我带他写代码的时候，他说好多内容视频里都没讲。可那些是最基础的东西。不可能通过 1 小时的视频教你学会写一个轮播图。如果你自己是其他的方法去学习，可能用了 2 个小时甚至更多，但你学会的不仅仅是一个轮播图。&lt;/li&gt;
&lt;li&gt;耐心。无论在做什么，你是在学习过程。在写代码的过程中，对于任何可能或不可能发生的事情，都要保持一个平和的心态。首先，编程不是很随意的过程，在你完全了解一个语言之前，不是你认为他应该什么样就是什么样。学习也不是你看了什么就要会什么。写不出来也不是你个人能力有问题，相反，这才是提升你编程技巧的时候。浮躁是学习 coding 甚至可以说学习任何东西中的大忌。我也经常这样。比如我今天一天都在尝试搭一个 tomcat 的环境，但是应用一直部署不上去。这时候，你急有什么用，你总不能把电脑砸了。就算你砸了，该跑不通还是跑不通。与其每天“被”逼着思考我要不要继续做这个，还不如想想办法找找解决方案。&lt;/li&gt;
&lt;li&gt;注意风格。朋友跟我说，代码我就随便写，要什么格式化，无所谓。包括看很多代码的注释啊，甚至代码格式都是乱的。像 php 的变量不用定义，但是全局变量需要声明。这个时候，不声明也可以，代码就会产生一种不清晰的结构。甚至你不知道这个是什么东西。包括缩进、命名等等。这些都是有规范可参考的。养成一个良好的代码风格（这个不是因人而异的），对于理解别人代码和自己未来的发展都是很必要的。&lt;/li&gt;
&lt;li&gt;切莫比较。这个是刚想出来的。不要跟别人比。写代码这种事情，总而言之是一个经验积累的过程，在跟别人比较的时候，你已经被更多人拉到很远。而且，问这种问题，你就永远比不上我 ^_^&lt;/li&gt;
&lt;li&gt;多问 Google。再补充一句，少问人。就初学者而言，网上一大片。搜索可以培养你筛选关键词的良好习惯。举个例子，初中我们写一篇作文来介绍孔子。我妹妹去百度：“孔子个人简介”，“孔子介绍”，结果没什么有用的信息。然而我就搜了“孔子”，就能得到我需要的内容。包括前一阵带着朋友写代码。他会搜索“怎么给元素设置内容”，但其实正确的搜索方式是&amp;quot;js dom value&amp;quot;。如果不懂，可以搜&amp;quot;js &lt;div&gt; 操作&amp;quot;类似的内容。现在的搜索要比之前聪明许多，但冗长的问题得不到正确的答案。这就是一个经验积累的过程。同样，文档不是用来学习的，是用来当作词典，如果你不会，去文档翻是最准确的。（我指的文档是官方发布的文档，不是菜鸟教程什么的）&lt;/li&gt;
&lt;li&gt;勇于面对 out of box 的问题。out of box 在文档里就是指“不在考虑范围内”。也就是说，如果你遇到了可能不属于当前学习知识的范畴甚至不是本门语言的范畴，这不意味着你不应该去学。相反，向这个方向的钻研，会使你的知识大步向前跨。通过搜索和文档，你可以知道更多你本不知道的东西。&lt;/li&gt;
&lt;li&gt;带着脑子。不要写着程序想着我能不能写，而是去想怎么写。动脑思考的过程是吸收知识的过程。在你不识字的时候你就会说话了对么；这个就是用脑子去完成的过程，而不是写了一页纸也学不会写字。编程也是一样。每一个不同的内容都会有不同的想法。如果按死规矩，一切复制粘贴（我没说不能复制粘贴），那这段学习之路就没什么意义啊，对么。&lt;/li&gt;
&lt;li&gt;自信点。本来想放在上面去讲，但是与内容没啥关系。学习初期，用 6 个小时写一个 js 联动，很快了。我最开始接触 php 的时候，写一堆简单的 curl，写了一个星期，每天早起晚睡。现在看来 so easy。其实我也是进行过对比的，第一次写了一周，第二次做了 ui，写了一周，第三次就写了 3 天吧，再后来就是结构编程了，现在想想，几个小时也就写完了。所以，不要当你花很长时间写了一个你看起来很简单（你怎么看起来这个简单呢）的界面时就气馁。这本应是他给你的成就感啊，别太消极。&lt;/li&gt;
&lt;li&gt;多看代码。看别人的代码可以学人家写的编程结构，思考方式，编程风格，最优解，也有助于你读懂以后你可能会遇到的源码，二次开发，等等。在你复制粘贴之前，先明白这是什么意思吧。不要看见复杂的内容就复制不管了，你要保证你写的代码里每一句话你都知道是做什么用的。&lt;/li&gt;
&lt;li&gt;多写代码。这个不用说。只有写代码才是熟练的开始。很多人在纠结写什么。想写什么就写什么咯。。。你可以写一个抽奖系统、一个轮播图、甚至一个网站。对于后端，最好的建议就是你去写一个微信公众平台。。也算是一个比较直观的东西了。&lt;/li&gt;
&lt;li&gt;原生起步。有人不会写代码就先会用框架了。。。&lt;/li&gt;
&lt;li&gt;追求极致。&lt;/li&gt;
&lt;li&gt;兴趣及目标。&lt;/li&gt;
&lt;/ol&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E6%95%99%E7%A8%8B/" term="技术 教程" label="技术 教程" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">从 DCloud 到 React Native ( Weex 从入门到放弃 )</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BB%8E_dcloud_%E5%88%B0_react_native__weex_%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83_/" />
            <id>https://rxrw.me/tech/%E4%BB%8E_dcloud_%E5%88%B0_react_native__weex_%E4%BB%8E%E5%85%A5%E9%97%A8%E5%88%B0%E6%94%BE%E5%BC%83_/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2018-08-04T14:39:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">前言 好多人学习的时候都会记笔记，像我这种从不记笔记的，能写点东西也很不容易。。 众所周……</summary>
            
                <content type="html">&lt;h2 id=&#34;前言&#34;&gt;前言&lt;/h2&gt;
&lt;p&gt;好多人学习的时候都会记笔记，像我这种从不记笔记的，能写点东西也很不容易。。
众所周知，我是个以后端为主的，当然自己写东西，肯定不能是写点 php 就满足了。从纯原生代码写 php 到初学 ThinkPHP ，过了两年终于走进了 Laravel 的世界。关于前段的方向也从原生 js 到 jQuery 到响应式布局，从 html 到 h5 再到 Android 原生过渡到小程序最后到了 js 混合开发。关于 php 的经历有点多，今天主要想说的是，在 js 混合开发的探索阶段遇到的各种大坑和技术选型的经历。&lt;/p&gt;
&lt;h2 id=&#34;技术选型&#34;&gt;技术选型&lt;/h2&gt;
&lt;p&gt;其实所谓的技术选型，无非是觉得哪个好用，哪个适合我去开发而已。
最近想做点小玩意（写代码能作为一种爱好我还是很开心的），自然想到了 App 。从这个角度开始，去选择一个合适的框架。
一开始有如下几种方案：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Android &amp;amp; iOS 原生开发。Android 原生倒是做过，毕竟至少毕设就是 Android 端的，但也不是很熟。iOS 的呢，就比较陌生了，毕竟，苹果设备都是 17 年末我才开始接触的。之前闲得慌注册了个 iOS 的 Developer Membership ，但一直没有接触过。&lt;/li&gt;
&lt;li&gt;ApiCloud。之前创业的时候，自己的 App 就是用 ApiCloud 实现的。据 DCloud 官网讲，ApiCloud 的技术大部分是从他们那里窃取的，这个我们倒是不关心。因为在我的开发之路上，这两个的实现方式还是有很大差别的。&lt;/li&gt;
&lt;li&gt;DCloud。之前第一次做混合开发时用的就是它。当时还不熟，也是创业而用的一个简单的程序。据他们介绍自己是 w3c+html5plus 中国产业联盟的发起者之一。&lt;/li&gt;
&lt;li&gt;Weex。Weex 是阿里巴巴由 2016 年开源的由 vue 进行编写的一种混合式开发框架。2017 年推出了 &lt;a href=&#34;https://market.dotwe.org/&#34;&gt;Weex Market 市场&lt;/a&gt;，但是域名解析貌似有些问题。2018 年由飞猪开源了自己所用的 UI 框架 —— Weex UI。&lt;/li&gt;
&lt;li&gt;React Native。简称 rn ，与 Weex 类似，是由 Facebook 发布的，以 React 作为编程语言的框架。但是诞生较早，现在已经迭代到 0.56（为啥到现在还没 1.0）&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;今天要比较和选型过程的就上述几个，具体内容下面将从使用到放弃一个一个讲。&lt;/p&gt;
&lt;h2 id=&#34;分门别类&#34;&gt;分门别类&lt;/h2&gt;
&lt;p&gt;首先说，以下仅代表我个人观点。好与不好，都是自己的认知。我最多呢就是给纠结中的人一些参考，以及一些&lt;em&gt;学什么都学不下去的&lt;/em&gt;孩子们一些鼓励。毕竟，我从大一 C 语言结束后的每一行代码都是自己学着写的。
其实目前比较多用户的已经在悄悄转移了，以前一开始的 PhoneGap 等等已经逐渐没有声音了。说回来，人越发展，越趋向社区型的产品。&lt;/p&gt;
&lt;h3 id=&#34;产品型&#34;&gt;产品型&lt;/h3&gt;
&lt;p&gt;产品型有一个显著的特征：收费为主。其实直说，他们是卖产品的，而不是做生态或社区的。因此是一些专做这个的技术公司运营起来的。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;DCloud&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;好啦，这次的第一选型就是 DCloud 了。毕竟在将 DCloud 与 APICloud 对比一下，还是前者比较能吹。又产业联盟又各种超级 IDE 的，而且说 APICloud 的技术也是从这儿拿的，是吧。
以下是 DCloud 的官网首页公告。没见法院要求的 APICloud 往首页放，倒是原告一直在摆着。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/from-dcloud-to-weex/d104b6d93a79ce274bbfba7d9e75920a.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;因为以前也开发过，所以比较有经验。还是下载 HBuilder 开发。什么是 HBuilder 呢？&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/from-dcloud-to-weex/277ed95152dab05d0eca382e648be39c.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;p&gt;下载下来，居然跟以前几乎一样。还是 eclipse 的拓展包拼出来的。包含了真机调试，云端打包以及最基本的代码提示等功能。我不知道为什么他能把「护眼模式」说了这么多年，有什么稀奇么。。
开发的路上，初始化项目。然后依旧是右边可以开一个预览，但只能看 html 的内容，有关动态页面还是要跑去 Chrome 里面去看了。然后提供了一个 ui 框架叫做 AUI ， 代码逻辑都是 jQuery 的语法。貌似看见过有人将 vue 工程转移到上面做 app。但我知道效果肯定很一般。关于各种登录分享地图等等插件都是集成好的，在工程设置里直接填 token/access_key 什么的就行了。但我毕竟也是接触过原生开发的，我不知道他要求填写微信的 AppSecret 是为什么。。
真机运行的话，用的是 Hbuilder 的基座进行预览。打包发布就不是开发者的事儿了，还是给他开发者 key 什么的就好了
一行代码都没写，决定放弃了。原因如下：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这种框架还是比较适合前端新手 + Anroid iOS 小白的。而且运行过去，如果不是你主动用 &lt;code&gt;plus.ready&lt;/code&gt;中的方法，样式啊元素都是由 Webview 展示的。性能堪忧。包括官网首页介绍的什么底端安卓机显示无线列表，纯骗人的。。由于大部分实现是原生 js，用户体验基本没法提。而他官网所说的用户案例，其实大部分是自己仿制的，以及一些小公司去弄的，纯为了快速迭代。&lt;/li&gt;
&lt;li&gt;理想与差距过大，由于 1 的原因，没办法用自己喜欢的框架去实现内容。要知道，一个天天写模块化开发的人突然跑去写单页实现，很心累的。&lt;/li&gt;
&lt;li&gt;集成度过高，比如刚才所说的微信什么的，其基座真的只是个带所有权限的 Webview 而已。想要拓展自定义的原生功能，难。&lt;/li&gt;
&lt;li&gt;IDE 过于不友好。说什么的都没用，基本是想垄断所谓的产业联盟。只能用 Hbuilder 进行开发，而且主动权不控制在自己手里。 放弃。无关复杂度。其实在我看来，更像是一个写好的东西让你去填内容罢了。&lt;/li&gt;
&lt;li&gt;APICloud&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;不细说了，之前是那这个做过一个半完整的 app 的。这次也尝试了一下，也是一行代码都没写就放弃了。
原因与上述大部分相同，还有几点：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;商业化太严重，比如刚登录进来的弹框：
&lt;img src=&#34;https://rxrw.me/images/zh/tech/from-dcloud-to-weex/716a64d67b067cf46776e3cea72c745b.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;据我回忆，这是唯一一个我注册了第二天还会给我打电话的。。&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;倒是有我想要的模块市场，可是。。 你见过动不动就要收钱的，代码还要自己写的开发者网站么。。
&lt;img src=&#34;https://rxrw.me/images/zh/tech/from-dcloud-to-weex/8a7c2219130d1e8b43543b954a873560.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;自己有一套 ui 库叫 MUI，听起来是不是跟 AUI 很像。 放弃&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;社区型&#34;&gt;社区型&lt;/h3&gt;
&lt;p&gt;其实这个名字也是最近写 rn 的时候看见了介绍的。比如 php、Laravel，ThinkPHP 也算是一个不完整的社区吧。就是开源、大家都可以为之做出贡献，不以盈利为目的，但产品质量是由大家一起维护的，因此，你懂的。因此，从 Laravel 之后，便越来越倾向于社区型的产品了。其实以前就听说过 react native 的大名了，但是对其有一些误解，以为其在 Android 和 iOS 每次调用原生的时候都要分别处理，以及我会用的前端框架也就 vue 了。因此想找找有没其他的。于是，就到了 weex 的了。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Weex&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;刚开始就百度搜索关键字， 「vue」 「app」，大家都在说 Weex。不过也有说其迭代速度已经很慢了的。但是看了看文档，感觉自己对其还是比较有兴趣的。从看一脸懵逼的文档到放弃，居然用了两周的时间。
因为中间一直看到那些说已经不维护的消息，但是对照 github 上的发布时间，前几天还在更新代码。但是版本还没发。而且，网上说阿里系的 app 已经好久没有全应用都用 Weex 的方案了。这点我无从考证。但是初始化后，发现 Android 和 iOS 生成的编译 sdk 版本都好低。再加上我发现社区真的没有做起来。官方没有 issue ，都是 apache 的邮件组（阿里后来吧 weex 交给了 apache 基金会来维护）。而且所谓的插件市场甚至一直都上不去，直到有一次偶然发现好像是其域名重定向出了问题。但是基本也没什么内容。甚至调用原生接口都调不通。包括但不限于微信登录、高德地图等插件，有是有，该过期的都过期了，基本都用不了，最新的提交是 6 个月前。
可以看一下[Weex 和 React Native] 的对比文档。大部分人建议就是，如果从现有应用修改，比较适合用 Weex ，但是从头开发还是 React Native。
对了，还有一个从 Weex 衍生出来的项目， Eros。没有用。。用了那个，好像又回到了 DCloud。
然后经过两周的研究+没有写多少业务代码，一直配置运行环境来着。算了。。放弃了。
即使是阿里开源社区的产品，但是几乎没有人在弄的东西，也就是社区环境最怕的内容——没有支持者。最后，抛下对 React Native 的偏见，走向了人生的道路。
给大家看一下许久没更新的 Weex 文档&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://rxrw.me/images/zh/tech/from-dcloud-to-weex/66c783c097e74eb5d657f8426a70badc.jpg&#34; alt=&#34;&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;React Native&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;目前卡壳在 Android 沉浸式状态栏，一直也不知道这个布局是什么样子的。
前几天用了两个小时差不多看懂了 reactjs，随后便将王妃送了出来。
优点就是&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;大社区产品，很多插件都通过热情的开发者们补充了&lt;/li&gt;
&lt;li&gt;自定义项目集成&lt;/li&gt;
&lt;li&gt;视图、网络及存储都接好了原生&lt;/li&gt;
&lt;li&gt;JSX 语法，用起来还是比较爽的 更何况，在第一次接触 React 和 React Native 当天，就已经开始搞下 Tab 一样。
&lt;img src=&#34;https://rxrw.me/images/zh/tech/from-dcloud-to-weex/f55f65c9039e54c0b38ded58e02a571c.jpg&#34; alt=&#34;&#34;&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;太困了，不说了，晚安&lt;/p&gt;
&lt;h3 id=&#34;补充&#34;&gt;补充&lt;/h3&gt;
&lt;p&gt;现在已经开始用&lt;code&gt;Flutter&lt;/code&gt;了。。&lt;/p&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF/" term="技术" label="技术" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text">高德开放平台API封装SDK</title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E9%AB%98%E5%BE%B7%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0api%E5%B0%81%E8%A3%85sdk/" />
            <id>https://rxrw.me/tech/%E9%AB%98%E5%BE%B7%E5%BC%80%E6%94%BE%E5%B9%B3%E5%8F%B0api%E5%B0%81%E8%A3%85sdk/</id>
            <updated>2022-09-06T13:37:00&#43;08:00</updated>
            <published>2017-08-23T12:22:00&#43;08:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html">小版本更新了 psr 规范 之前对这方面了解不多，因此写的可能有点问题。 但是欢迎指出错误而不是……</summary>
            
                <content type="html">&lt;blockquote&gt;
&lt;p&gt;小版本更新了 psr 规范
之前对这方面了解不多，因此写的可能有点问题。
但是欢迎指出错误而不是带着一股子嘲讽过来喷人好吗。
用处不多维护精力比较少
但基本够用
注：可能有不兼容改动，一些类名大小写可能有问题 请注意&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;需求&#34;&gt;需求&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;php &amp;gt;=7.0.0
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;guzzlehttp/guzzlehttp:^6.3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;没有安装 guzzlehttp 也不要紧，在 require 的时候回自动安装&lt;/p&gt;
&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;composer require reprover/amap
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h2 id=&#34;用法&#34;&gt;用法&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;use&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Reprover\Amap\Amap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;(1)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$amap&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Amap&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$gateway&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$amap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;uses&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;Georegeo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;gateway&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;geo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;key&amp;#34;&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;你的api key&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;其他选项&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//这里支持setKey(&amp;#34;key值&amp;#34;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;//这里支持useHttps(true);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$gateway&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;如果不需要额外的配置，可以用以下方法：&lt;/p&gt;
&lt;p&gt;(2)&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$gateway&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Amap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;georegeo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;gateway&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;regeo&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$gateway&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;(3)
如果请求的接口大类只有一个子方法（例如坐标转换），则可以省略 gateway()方法&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$gateway&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Amap&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;use&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;convert&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;build&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$gateway&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;ask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;h3 id=&#34;额外方法&#34;&gt;额外方法&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;build 方法传什么？
传$config 参数，参数列表为一数组，具体实现为一 Reprover/Support/Config 对象，&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;返回结果为一个 Reprover\AMap\Support\Result 对象，类似于 Laravel 的 Collection，不过没那么全面。可用的方法：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;count&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;所得数据结果数量，如果有多种类型结果则只返回主要数据（如天气只返回实时天气数量，天气预报也可以用$result-&amp;gt;forecast）获取。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$result&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;as&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;$k&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;$v&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;){&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;...&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;可以用 foreach 进行结果的循环&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-php&#34; data-lang=&#34;php&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nx&#34;&gt;isValid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;boolean&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;判断结果是否正确，即根据高德返回数据 status(errcode)是否为 1(0)&lt;/p&gt;
&lt;p&gt;部分特殊接口有一些特殊用法，开发 ing&lt;/p&gt;
&lt;h2 id=&#34;说明&#34;&gt;说明&lt;/h2&gt;
&lt;p&gt;这个 sdk 是第一版，还存在很多不足的地方，欢迎大家提交 pr 和 issue！同时也在版本迭代中，建议大家不要急于将此插件用于生产环境中～&lt;/p&gt;
&lt;h2 id=&#34;接下来的任务&#34;&gt;接下来的任务&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;√ 优化类名和驼峰法命名&lt;/li&gt;
&lt;li&gt;√ 修改验证类规则（现在是一个方法，需要写一个类）&lt;/li&gt;
&lt;li&gt;√ 优化使用方法，注入配置项等&lt;/li&gt;
&lt;li&gt;数字签名自动完成&lt;/li&gt;
&lt;li&gt;√ http 与 https 的切换&lt;/li&gt;
&lt;/ul&gt;
</content>
            
            
            
            
            
                
                    
                
                    
                        
                            
                            
                            
                                <category scheme="https://rxrw.me/tags/%E6%8A%80%E6%9C%AF-%E5%BC%80%E6%BA%90-%E5%BC%80%E5%8F%91%E6%96%87%E6%A1%A3/" term="技术 开源 开发文档" label="技术 开源 开发文档" />
                            
                        
                    
                
            
        </entry>
    
        <entry>
            <title type="text"></title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/vscode__%E9%80%89%E6%8B%A9%E4%B8%80%E6%AC%BE%E5%90%88%E9%80%82%E7%9A%84%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/" />
            <id>https://rxrw.me/tech/vscode__%E9%80%89%E6%8B%A9%E4%B8%80%E6%AC%BE%E5%90%88%E9%80%82%E7%9A%84%E5%BC%80%E5%8F%91%E5%B7%A5%E5%85%B7/</id>
            <updated>2024-02-26T16:04:57&#43;00:00</updated>
            <published>0001-01-01T00:00:00&#43;00:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html"></summary>
            
                <content type="html"></content>
            
            
            
            
            
                
                    
                
                    
                
            
        </entry>
    
        <entry>
            <title type="text"></title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E4%B8%89/" />
            <id>https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E4%B8%89/</id>
            <updated>2024-02-26T16:04:57&#43;00:00</updated>
            <published>0001-01-01T00:00:00&#43;00:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html"></summary>
            
                <content type="html"></content>
            
            
            
            
            
                
                    
                
                    
                
            
        </entry>
    
        <entry>
            <title type="text"></title>
            <link rel="alternate" type="text/html" href="https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E4%BA%8C/" />
            <id>https://rxrw.me/tech/%E4%BB%8Ept%E5%88%B0%E5%AE%B6%E5%BA%AD%E5%AA%92%E4%BD%93%E4%B8%AD%E5%BF%83%E5%85%A8%E6%94%BB%E7%95%A5%E4%BA%8C/</id>
            <updated>2024-02-26T16:04:57&#43;00:00</updated>
            <published>0001-01-01T00:00:00&#43;00:00</published>
            <author>
                    <name>纠结当道</name>
                    <uri>https://rxrw.me/</uri>
                    <email>rxrw@me.com</email>
                    </author>
            <rights>Copyright [RXRW.ME](https://rxrw.me) with Heartbeat. All rights reserved.</rights><summary type="html"></summary>
            
                <content type="html"></content>
            
            
            
            
            
                
                    
                
                    
                
            
        </entry>
    
</feed>
