如果有人问我,你和四年前有何不同?很遗憾,我并不确定自己是否真正做出了改变。在相似的新旧交替之际,我试着寻回四年前的记忆,却不敢认出那个自己。穿越时间的相遇,让我发现自己并没有变得更好,反而失去了那时一般的快乐,也失去了那时对今日的期望。我不知道是否“成长”皆如此般令人怅然,只知道行路至此,我依然没有踏出那片荒野。
2023 年真的如去年期望一般变好了吗?也许有些,但在不同的阶段总会有不同的困难。2023 对我来说是一个比较大的转折点,从越来越躺平的本科生活到忙碌的研究生生活,我逐渐明白了若想有所为则需有所不为。遇到的选择题从来不会减少,所以只能按照局部最优踟躇向前。站在 2024,与背后的 2019 已经相隔了五年,却仍感觉 2019 很近,也许是因为 2020-2022 并没有留下太多的记忆点,这段时间被我们在内心折叠。
我的 2023 也如此一般飞逝。翻看相册才发觉,虽然上半年自由的时间很多,但下半年的大部分时间都忙于工作,甚至没留下许多照片。无法挽回我这越来越无聊的生活,只希望前行的路上亦能且行且歌。
现在回想起来,22 年冬天可能是我人生中最后一个美好的寒假。和家人团聚,和老友重聚,有许多时间自我冥想和放空。
通过了考试,准备复试,录取。这段时间很难熬,归根到底是对未知的恐惧和对未来的迷茫。只记得复试前的几天天气阴沉,复试之后开始放晴,我的内心也逐渐平静。总有许多话想记录,但零碎的空闲时间击碎了记录的热情。希望我能在下一个自己的时间完成这些事情……
上半年的空闲时间很多,重新逛了一次北京,感觉和七年前的印象好不一样。来一次说走就走的旅行,第一次踏上山东的土地,感谢 YF 的招待。看了很多风景,吃了很多美食,两次通宵 KTV 印象深刻。喜欢这种自由,希望 2024 依旧有心情行万里路。
毕业,一条分隔线将我的人生划开。也许是因为常常低头行路,却不曾发现自己已经走了很远。和朋友们一个一个道别,各自去往不同的方向,四年的喜怒哀乐在两本证书、一张照片中被封存。我知道这种经历不会再来,就像我的青春一去不复还。
分隔线开启了我忙碌的下半年。研究生生活虽然带来了更多自由的时间,但未曾涉足的领域和新的挑战也让我压力倍增。
It is no use doing what you like; you have got to like what you do.
导师和实验室的师兄都很 nice,大家都很有实力,希望我自己也能应对不断的挑战,继续走下去。
在少有的闲暇时间,突然对摄影很感兴趣,入手了 📷 。结局就是过于忙碌以至于吃灰了许久,虽然拍了一些照片,但还有好多没来得及修。希望有时间能多出去走走。
忙里得闲,压力需要娱乐缓解。重拾了 Steam 游戏,也突然对 NS 很感兴趣。遗憾的是 23 年的末尾才开始接触 NS,50 小时+ 畅游海拉鲁大陆没有让我感到疲倦。内心的紧张和压抑在游戏中得以释怀,希望 2024 能找回更多的乐趣。
OK,结束这压抑的流水账,接下来是一年一度的数字总结时间!
首先是网易云音乐,从下到上依次是 2020、2021、2022、2023 年度总结。
23 年用网易云的时间屈指可数,因为网易云音乐 app 冗余的功能、倒退的设计、少量的曲库、更多的广告,让我不得不放弃这个平台。去年曾开始使用 Apple Music,但每次 App Store 换区时我的音乐库都会被清空,所以我也不得不放弃它。最终选择了 Spotify,目前仍然是我的主要音乐平台。
然后是 Bilibili,我以为 2023 我会比 2022 时间更长,但事实上看的更少了。
2023 依然没有在开源事业上有所进步。有几个 project 的 idea,但苦于没有时间实现,也有几个 project 写了一点就不了了之。希望 2024 我能写完一个。
从去年开始,我计划每年评选出 1~2 个“年度 app”。2021 年度 app 是 Notion,这也是我目前主力笔记软件;2022 年度 app 是 Arc,这也是我目前主力浏览器。2022 另一个年度 app 是 ChatGPT,没想到它在 2023 年引发了世界人工智能和大语言模型的热潮。2023 我评选的年度 app 是 1Password,它改变了我记录密码的方式,也让我更加安全地管理越来越多的账户。
除了“年度 app”,我还打算评选出我的“年度影响力视频”。今年的是 【毕导】13年过去了,我终于毕业啦!_哔哩哔哩_bilibili。
除了“年度影响力视频”,我还打算评选“年度电影”和“年度剧集”。今年一共看了 33 部电影和剧集,我的“年度电影”是 《蝴蝶效应》,“年度剧集”是 《漫长的季节》。
以上评选的内容都出于我的主观评价,对我来说都很有意义。期待 2024 可以看到更多优秀的作品。
2023 带给我最大的感受就是,我开始更深刻地认识自身。
我不断认识到自己的缺点,这些在我独自完成有挑战性的任务时总会显现出来。
2023 是充满挑战的一年,我不在沉迷于自己的舒适圈,开始寻求一些改变。
痛苦常伴,快乐易逝;道阻且长,不虚此行。愿来年我能过得从容,至少改掉一个缺点,至少完成一个目标。
2024,要开心。
2023,再见!
]]>这个 commit 用于检测 netlify 的自动部署功能是否正常。
]]>忙碌了 5+3 个月,很多重要的事情终于有了结果。过去的一个月可能是比较 challenging 的一个月,面对种种未知和阻碍,最后还是挺了过来。很难说收获了什么经验,只不过是随着时间的流逝而不得不面对罢了。
话说回来,从寒假开始构思如何改造本站的 UI 以更符合我的审美,最终做了如下更改:
当然,这次对 NexT 主题的魔改也存在不合理之处,目前发现的 bug 有:
现在开始,是本站的新起点,也是我的新篇。
]]>最近应该会更新几篇文章,敬请期待(在写了在写了)。
在上一篇文章 —— 2022 年度总结 中,我提到了去年比较满意的一款产品:Arc 浏览器。它是一款基于 Chromium 的浏览器,有很多传统浏览器没有的新功能。这里不过多介绍它的其他功能,主要讲一讲自定义网页 —— 即 Arc Boost。
我喜欢使用浏览器,只要浏览器能做的,我一般不会下载 app。很多网站的布局、设计和推荐的内容都不是我想要的,我希望能够自定义网页,只看到我想要的内容。比如在用 Bilibili 时,视频上方的推荐搜索、直播间花里胡哨的活动通知和礼物等,我都不想看到。这些内容在 app 中是不可以自定义的,但正因为是浏览器,才有了自定义网页的可能。
这样做的话,每次网页刷新都需要重新修改,而且不同路由下的网页都需要修改,比较麻烦。
上文和下文提到的“插件”指的就是浏览器的扩展(extension)。
当然,对于 Bilibili 网站,有很多出色、强大的自定义插件可供使用。但插件提供了太多我不需要的功能,提供的需要的功能实现又过于复杂也不是我想要的样子,而且向插件中添加我想要的功能又太麻烦,最后成了为了自定义网页而去自定义插件。
首先,你要有一台运行 macOS 的电脑,因为 Arc 浏览器暂时只支持 macOS。
其次,你需要安装 Arc 浏览器,这里是邀请码:
hey, here’s an invite to Arc, the browser I was telling you about!
在浏览器中打开 Bilibili,在侧边栏的右下角 +
号中选择 New Boost
,即可进入 Arc Boost 编辑页面。
点击 Style
- A specific website
,在窗口中将 www.bilibili.com
改为 bilibili.com
,点击 Create Boost
,即可进入 styles.css
编辑页面。
因为 Bilibili 空间、直播间等页面的三级域名都不是 www,如果这里只写 www,会导致自定义 css 在这些页面无法生效。
这里就是自定义网页的地方了,你可以在这里添加你想要针对 Bilibili 的 css 代码,浏览器会自动覆盖掉原网页的 css。
你应该对 css 有一些比较基础的了解。如果完全不了解,Arc 浏览器还贴心地提供了很多教程,在右上角的 Handbook 中可以找到。
下面以隐藏 Bilibili 网页上方的推荐搜索为例,这里是修改前的网页:
用开发者工具找到搜索框的元素路径,这里是 #nav-searchform > div.nav-search-content > input
。
删除原有的 css 代码,添加如下代码:
1 | #nav-searchform > div.nav-search-content > input::placeholder { |
浏览器会自动保存并自动刷新,修改后的网页如下:
而且此后只要通过 Arc 浏览器访问 Bilibili,都会自动隐藏搜索框的推荐搜索。
是不是很简单!
这三行代码可以隐藏 Bilibili 首页 上方的推荐搜索,但在其他页面可能不生效。因为 Bilibili 其他页面的结构可能有所不同,所以需要到不生效的页面再次找到对应的元素路径,然后添加 css 代码。
这里以直播间页面 https://live.bilibili.com/ 的搜索框路径为例:
1 | #nav-searchform > div.p-relative.search-bar.over-hidden.border-box.t-nowrap > input::placeholder { |
应该可以隐藏全部搜索框的推荐搜索了。
说到直播间,默认的 Bilibili 直播间是这样的:
比如我只想看 v,不喜欢充值、送礼物、打赏、买周边、上舰,那么上面的礼物星球、限时领取、购物提示,以及下面的小橙车、一排礼物、上舰提示、充值按钮,都是我不想看到的。这时就可以找到它们的元素路径,然后添加 css 代码隐藏它们。
1 | #head-info-vm > div > div > div.lower-row > div.left-ctnr > div.gift-planet-entry { |
修改后:
是不是简洁很多!这下可以专心看直播了。
同理,你可以修改任何网页,只要找到对应的元素路径,然后添加 css 代码就可以了。
实际上,Arc Boost 就是为浏览器添加了一个插件。比如刚才我们添加的对于 bilibili.com 的 Boost,可以在已安装的插件中找到:
在插件管理中,可以看到具体信息,包括插件的大小、权限和存储位置等:
上面显示 < 1 MB,其实也就 2 KB。
得益于 Arc 浏览器优秀的套壳技术,对于已经添加的 Boost,可以在作用的网页右上角的插件列表(Extensions)中看到,且单独以“Boosts”列出,可以一键删除、修改或置顶,不需要单独在 Finder 中打开并修改。
Arc Boost 的作用远不止于此。本文只介绍了它的最简单的用法 —— 改变网站样式,实际上,正如一开始进入 Boost 所见,它还可以通过编写 JavaScript 代码替换、注入网站内容,或者做任何事情。它的存在将浏览器插件的开发门槛降到了极低,让任何人都可以轻松地编写并使用适合自己的浏览器插件,不依赖其他工具。
https://arcboosts.com/ 收录了很多有趣的 Boost,你可以在这里探索适合自己的,或者自己编写一个并上传上去。如果你有更多关于 Arc Boost 或 Arc 浏览器 的想法,欢迎在下方留言交流。
如果你只想看关于本文主题的内容,可以跳过这一部分。
细心的小伙伴应该已经发现了,我的博客域名又又又换了。从最开始的 .xyz 到后来的 .cn,再到现在的 .com,以后应该不会再换了。这次换域名的原因是,之前在 Value Domain 上面一元买到了 6 个域名,现在的这个域名就是其中之一。.com 域名确实更加通用,而且不用放在国内的阿里云或腾讯云上(相比 .cn),我转移到了 Cloudflare 上,体验也更好。原来的 .cn 域名做了跳转,所以这次迁移暂时也不会影响到原来的链接(为什么说是“暂时”呢,因为 .cn 域名过期之后大概率不会再续费了,所以到时候原来的链接肯定会失效)。唯一受影响的就是之前不蒜子统计的浏览数据了,不过也没什么关系,新的开始,新的计数。
]]>回看了 2021 的年度总结,感叹 2022 确实因各种原因变得更平淡无奇。一方面因为疫情和防控,基本没有出校的机会,枯燥的学校生活让人难以留下深刻的记忆,禁锢的脚步让人难以满足生活的现状,无休止的打扰让人充满无奈和妥协。另一方面由于下半年的考试准备,推辞了很多有趣的事情,也“忍痛割爱”地放弃了坚持许久的探索,而且准备考试的过程更加无聊和乏味。很惭愧,2021 对 2022 充满期待的我未能如愿以偿,在今天的心境下也难以抒发去年今日的积极感。
机缘巧合下,今年跨年在家里一个人度过。上次在家里跨年还是在 7 年前的初中,已经记忆不清了。之后几年的跨年都是在高中,然后就是在大学了。惟有感慨时光飞快,无数记忆碎片填满了过去的回忆,时间如刀割般在某些时刻断裂,又在整体上相连。太阳在 2022 年最后一次落下,也会在 2023 年第一次升起,希望新的一天可以扫除旧的阴霾,带来新的希望。
回忆上一个假期,只能想起寒假,而暑假的记忆却很模糊。寒假是和朋友们团聚的假期,在这之前满分通过科四拿到了驾驶证(然而并没有开车…),和朋友们去滑雪,也是第一次。
这是某次滑下来的场景,滑雪对身体不协调的人来说好难。
相比之下,暑假生活略显平淡和短暂。一方面朋友们大多忙于实习和工作,或疫情防控原因,或时间原因没能团聚;另一方面暑假开始准备考试,规划下半年的计划,也很少有能自由支配的时间。
不过从 6 月开始养成的记“日记”习惯让我比较受益。不是传统意义的日记,只是某时某刻想到的一句话、一个灵感、一个经验、一个总结,按时间和方向有意识地记下来,现在回看仍有很大的意义。让我觉得这一年并没有在浑浑噩噩中度过,相反,这一年可能是我思想上提高最大的一年,或多或少得益于我的大部分想法都能记录下来,当串连起来时更能引发新的感悟。
这一年也看了很多电影和剧,也有意识地记录在了 Notion 里,包括《爱、死亡和机器人》等充满创意的 Series,也有《Friends》等经典美剧,希望新的一年能有更多时间欣赏更多优秀的作品
暑假打卡了 Apple Store,在 Genius Bar 换了一个键盘,详情可以看 这篇文章。
a tour of Genius Bar pic.twitter.com/omgvOWzDZG
— 𝙎𝙐𝙋𝙀𝙍 (@repusme) July 24, 2022
同时也换了新 iPad,不巧在闲鱼上遇到了假冒的 Apple Pencil。和骗子斗争几天后,最终成功全身而退,对方也受到注销账号的处罚,我发布的一篇“如何辨别真假 Apple Pencil”的帖子也收获了数万次浏览。
今年是世界杯年,继初中(2014)、高中(2018)后,是第三次看世界杯。还记得 2018 年世界杯时,还在幻想 4 年后的 2022 我会以什么样的处境和心境看这场比赛。那时对今日的想象很不清楚,此时对彼刻的回忆也很模糊。总之,今年的世界杯决赛非常精彩,恭喜阿根廷、恭喜梅西夺冠 🏆。
最后记录一下数字总结。使用网易云音乐的第 7 年,也是正式使用 Apple Music 的第一年,所以使用网易云音乐的次数也在减少。
今年是重度使用 B 站的一年,留下了很多难忘的回忆,有 3 天因为太忙忘记了打开 B 站…
我觉得每年选出一个“年度 app”是很有意思的事情,以后会坚持下去。去年我认为我的年度 app 是 Notion,而今年则是 Arc。Arc 是一个充满革新性的浏览器,解决了 Chrome、Edge 和 Safari 等曾经常用浏览器的许多痛点,比如标签页的管理方式、主页面的布局等,达到了美观度和实用性的统一和提升。当然,它也有很多不足,比如书签管理是我认为它目前最大的短板,The Browser 官方也通过邮件告知我他们正在着手解决这一问题。而我通过转到 Raindrop 重新设计了我的工作流和信息流,从而很大程度上适应了 Arc 在此方面的不足。
hey, here’s an invite to Arc, the browser I was telling you about!
由于这个产品的流行度和颠覆性,我还打算选出第二大年度 app —— ChatGPT。作为 OpenAI 的对话机器人,ChatGPT 更有逻辑、有知识,能较为出色地、人性化地解决提出的许多主观问题,再一次为人工智能的力量折服。但在我看来,它并不能替代 Google 成为新一代搜索引擎,因为它虽然能解决好“How”,但不能解决好“What”。比如一些常识性、知识性的问题,它总能“一本正经地胡说八道”,看似很有道理,但在事实上是完全错误的答案。
除了生活方面,在学习方面进一步学习和发挥了 iOS 开发,参与开发了微北洋 4.2,也是一段很有趣的经历。对 iOS、对前端、对 git、对 cooperation 都有了新的理解。在闲暇之余我开展了 SuperLab 的 2022 年度项目 Galaxy,也是我的第 3 个 app,是包括 iOS 前端和后端完整的项目,有数据处理、音频处理等内容。
p1 是微北洋求实论坛一代神贴,被投稿到了某 channel,而图片里的 UI 是我写的,很奇妙的感觉。p2 是“海棠季”粉色主题。p3 和 p4 是 Galaxy 中的部分功能,一个是简单爬校园卡流水的(主要是方便记账),另一个是音乐播放器的功能。
2022 下半年大部分时间都在准备考试,全年大部分时间也都在图书馆,度过了图书馆的春夏秋冬。
p3 并不是图书馆的秋天,因为图书馆视角的秋天忘记拍照了。由此可见图书馆的窗户该擦了。
最喜欢的是青年湖畔的晚风。
考试前夕的某个夜晚,很安静。
23 考研第一天中午,车水马龙。
最后还是想记录一下 2022 最 upsetting 的事情,疫情,是 2022 年每个中国人都无法回避的话题。我的 2022 从疫情爆发开始,也从疫情爆发结束。21 年 12 月 31 日,我正写着年度总结、准备离校回家,未曾想过改变整个 2022 的疫情正悄然而至。1 月 8 日,奥密克戎首次在天津爆发(天津是国内首个发现奥密克戎境外输入的城市),爆发地恰是我 1 月 1 日去过的地方。第一次感觉和疫情如此接近,而我也在 1 月 10 日开始了一言难尽的隔离生活,直到 15 日。
当然这只是开始,不是结束。回到学校,开始了一言难尽的上百次(全年)核酸检测。没有疫情要做核酸检测,疫情爆发后就停止核酸检测,这陷入了一个诡异的逻辑,即如果核酸检测是为了防止疫情爆发,那么事实证明它并没有起到任何作用,疫情该爆发还是会爆发;如果核酸检测是为了保障每个人的健康,那么事实是在最容易感染的时刻停止了核酸检测,最终还是靠每个人自测抗原判断是否感染。讽刺的是,当寝室有感染风险时,找管理者要抗原试纸,管理者却说“抗原又不治病”,并没有给。试问核酸检测治病否?
难以忘记的秋雨中的核酸检测,一场温暖的双向奔赴。( p1 来自微北洋求实论坛,非本人拍摄 )
来自微北洋求实论坛的一篇短文。
在 2022,一切都可以是“非必要”的。( 图片来自微博,见水印 )
没有制约的权力,没有义务的责任。甚至最终 12 月 2 日疫情在学校爆发之时,学生都没有最基本的知情权,那几天是这一年中最混乱的日子。12 月也是最戏剧性的一月,官方的宣传和 11 月时形成 180 度反转,不过说明了宣传者只需要对上负责而无需对下负责,也说明了很多人并没有独立思考的能力。如今,疫情防控的乱象总算是告一段落,但这一年中发生的 各种事情 难以忘怀。社会运行的真相是什么,官方是不是歌颂太平的工具,其公信力还有几何,今后诸如全员核酸检测之类的无理要求不知还会有多少人听从。曾经引以为傲的制度优势,最终还是背离了“实事求是”。文章写尽太平事,不肯俯首见苍生。太多的事情就不赘述了,有良知的人总会听见、看到、记下,没有良知的人总会视而不见。
如果尖锐的批泙完全消失,
温和的批评将会变得刺耳。
如果温和的批评也不被允许,沉默将被认为居心叵测。
如果沉默也不再允许,赞扬不够卖力将是一种罪行。
我只能记下并活着,或者让活着的记下我,像 * * 爱我一样爱 * *。当然,让人不至于如此难过的,是仍然有很多人有思想、有良知、敢发声,希望你我都能保持这份清醒,心怀希望。
向 2022 年因未知原因而失去生命的人默哀。
正如前文所说,2022 是逐渐成熟、理性、清醒的一年,对待同一件事的看法不再像以前一样片面、情绪化、盲目从众。一方面是由于疫情,见得多了,自然就明白了;另一方面是反思自身的问题,找到存在的缺点和差距,每个人应该都会在大学生活将要结束时成长许多。
总之,无论 2022 有多糟糕,在 2023,还是要解放思想、实事求是,团结一致向前看。新年的鞭炮声已经响起,生命的新阶段已经到来。迎接新生和自由,拥抱梦想和彼岸。
2022,再见!
]]>起因是暑假在家时,突然发现 MacBook 的 fn 键和左 shift 键被卡住了,fn 键尤为严重,导致每次按 F12 都很别扭。可能 fn 键的唯二作用就是 F12 和表情符号了吧。初步怀疑可能是键盘缝隙进入了杂物,尝试了 Apple 推荐的做法,并没有成功。于是准备去 Genius Bar 让天才们修理一下。
截至目前,天津一共有 3 家 Apple Store,分别是位于南开区的 天津大悦城、位于和平区的 天津恒隆广场 和位于河西区的 天津万象城。很不巧,最近河西区和南开区先后出现了疫情中高风险区域,为避免因为有“高中风险地区和高中风险区所在县(市、区、旗、直辖市为所在区)旅居史”,我不得不退掉比较容易到达的 Apple 天津大悦城的预约,预约了 Apple 天津恒隆广场。
预约 Genius Bar 很简单,在 Apple 官网选择故障类型、预约时间段等信息进行预约即可,如果没有预约可能会导致排不上班的情况。预约成功后会收到 Apple 发来的短信和邮件(提醒:为接受 Genius Bar 天才吧服务做好准备),还可以将预约码添加到钱包。取消预约也很简单,进入预约列表点击取消即可。整个预约过程都是免费的。
根据 Apple 的提示,去 Genius Bar 之前需要备份你的数据,我用 Time Machine 备份了一下。Apple 还提醒需要确保可以提供相关单据(带上身份证)并携带购买凭证。虽然 Apple 说“请务必携带购买凭证”,但我也找不到我的购买凭证了,事实证明最后也并没有要我出示它,Apple Store 可以直接查到你的购买信息。
24 日我如约 来到 Apple Store,在门口签到后坐下等待安排给我的天才到来。对了,在官网预约时应该登录了你的 Apple ID,所以预约的姓名是你的 Apple ID 对应的姓名。几分钟后天才来了,让我拿出 MacBook,问我出现了什么问题。得知键盘问题后,他按了几下发现确实如此,说可以给换个键盘。同意后,他开始对 MacBook 进行检测,关掉了 Find My Mac(据说是为了连接到 Apple Store 的设备)。检测没什么问题,告知我现在键盘并没有现货,需要从上海调配才能给我换,需要一周内时间。我同意,然后他开了维修记录(Apple Store 工作授权),我签字后收到了副本邮件,有维修编号、客户信息、产品信息、问题说明 / 诊断、维修估价等信息。当然,维修估价共计 RMB 0。
第一日游并没有如愿修好我的 MacBook,我也把 MacBook 带回了。在 Apple Store 看到了春季新品,比如指纹收集器暗夜色 MacBook Air M2 和怀旧设计 MacBook Pro M2。指纹收集器是真的容易沾上指纹,显得尤为突兀。不过它的配色是我心目中最好看的 MacBook 配色。
回去之后,fn 键竟然似乎有些好转了,真是玄学。好几天过去了,Apple 并没有给我打电话,就在我以为 Apple 应该是不能如其到货了的昨天,Apple 打来了电话,问我什么时候有空去送修。我选择了上午的时间,然后就收到了短信和邮件。和前一次预约相同。天才让我做好备份,我又用 Time Machine 备份了一遍。
29 日我又如约 来到 Apple Store,准确说来得稍早了一些,我又摸了一遍 Apple Store 的样机。不得不说,iPhone 13 Pro 和 iPhone 13 Pro Max 的 120 Hz 高刷真的震惊到我了,第一次认真体验才发现如此丝滑。我再拿起旁边的 iPhone 13 和 iPhone 13 mini,竟感觉如此卡顿……(不过多刷一会 60 Hz 也就习惯了)(反转了,后悔没有买 iPhone 13 Pro >_<)Mac Studio 是真的重。iMac 的大下巴是真的丑。MacBook Pro 16 英寸新款也丑,键盘的黑色底色尤为突兀,而且在那么大的 C 面上留那么小的键盘区域,感觉比例有些失调。
摸了半天,终于到我了。签到后又等着天才来找我,过来后又检测了一遍,和第一次来一样。最后签了字开了条就让我走了。理论上最快 4 小时可以换好,据天才说 M1 款的维修比 Intel 款的简单,而且维修后的检测时间也比 Intel 款的更短(0.5h < 2~3h)。将信将疑下,他说最快今晚可以取回,比较稳妥是明天。一番交谈过后,我离开了 Apple Store(该吃午饭了)。
由于不想再浪费一天来个“三日游”,坐地铁时间还挺长的,我打算到处转转等今晚拿下。在 M 吃完午饭后回恒隆广场转了一圈,看到了无人问津的小米之家。体验了一下 12 S Ultra,广告是真的多,发现小米的触感反馈做得也很不错了,感觉比 iPhone 的触感体验还要好。恒隆广场挺大的,走一会我又回到了 Apple Store。过了一段时间 Apple 打来了电话,是下午 4:03,说我的 MacBook 修好了可以取货。看来天才诚不欺我,说 4 个小时就 4 个小时。等了一会后,天才拿着我的 MacBook 过来了,让我试一试键盘,试了一下挺好的,像新的一样。然后看了一下我的身份证,签字后就拿走了。
给我拿 iPad 的小哥让我印象深刻,他是一位听障人士,靠打字和我交流,能感受到他的紧张但很认真。很感动,致敬每一位努力生活的人,也致敬 Apple 强大的辅助功能为残障人士带来了科技的温暖。
回归正题,最后发现我的 MacBook 应该是整个 C 面都换新了,包括键盘和触控板,顺带给清洁了屏幕(忘了问天才是如何把屏幕清洁得这么干净的了)。当然,最希望电池也能直接给换了,但并没有。总之这次 Genius Bar 的体验还是很棒的,全过程没有任何数据丢失,0 成本(除去路费)九舍一入拿到了“全新”的 MacBook Air,感觉又可以再战几年了(希望 256 GB 硬盘能多撑一会)。
]]>怀念 2019 年在滨江道散步的夜晚,Apple 天津恒隆广场店人潮涌动(当时靠马路边的门是开的),那种景象大抵是回不去了罢。
tap 和 tun 是操作系统内核中的虚拟网络设备,tap 位于二层,tun 位于三层。它们的数据结构如下:
1 | struct tun_struct { |
tap 和 tun 的数据结构定义相同,两者仅通过一个 Flag 来区分。但二者承载的功能区别很大:
tap 从功能定位上来讲,位于数据链路层,数据链路层的主要协议有:
tap 只与其中一种协议——以太网(Ethernet)协议对应。所以 tap 有时也称为“虚拟以太设备”。
创建 tap 的方法:
modinfo tun
检查lsmod | grep tuntun
检查 tun 模块是否已经加载yum install tunctl
tunctl -t tap_test
ip link list
或 ifconfig -a
ip addr add local 192.168.100.1/24 dev tap_test
或 ifconfig tap_test 192.168.100.1/24
传统的 Linux 的许多资源是全局的,namespace 的目的首先就是将这些资源做资源隔离。Linux 可以在一个 Host 内创建许多 namespace,不同 namespace 的资源互相不可见、彼此透明。namespace 示意图如下所示:
从网络的视角来看,一个 namespace 提供了一份独立的网络协议栈(网络设备接口、IPv4、IPv6、IP路由、防火墙规则、sockets 等)。一个设备(Linux Device)只能位于一个 namespace 中,不同 namespace 中的设备可以利用 veth pair 进行桥接。
namespace 操作:
ip netns list
ip netns add ns_test
ip link set tap_test netns ns_test
ip [-all] netns exec [NAME] cmd ...
veth pair 不是一个设备,而是一对设备,以连接两个虚拟以太端口。操作 veth pair,需要跟 namespace 一起配合,否则没有意义。
veth pair 简单示例:
创建简单示例:
ip link add tap1 type veth peer name tap2
ip netns add ns1ip netns add ns2
ip link set tap1 netns ns1ip link set tap2 netns ns2
ip netns exec ns1 ip addr add local 192.168.50.1/24 dev tap1
、ip netns exec ns2 ip addr add local 192.168.50.2/24 dev tap2
ip netns exec ns1 ifconfig tap1 up
、ip netns exec ns2 ifconfig tap2 up
ip netns exec ns2 ping 192.168.50.1
、ip netns exec ns1 ping 192.168.50.2
Linux 中 Bridge(网桥)即为 Switch(交换机)。Linux 实现 Bridge 功能的是 brctl 模块,相关用法如下:
1 | brctlUsage: brctl [commands] |
veth pair 综合示例:
实现这个用例:
ip link add tap1 type veth peer name tap1_peer
、ip link add tap2 type veth peer name tap2_peer
、ip link add tap3 type veth peer name tap3_peer
、ip link add tap4 type veth peer name tap4_peer
ip netns add ns1
、ip netns add ns2
、ip netns add ns3
、ip netns add ns4
ip link set tap1 netns ns1
、ip link set tap2 netns ns2
、ip link set tap3 netns ns3
、ip link set tap4 netns ns4
brctl addbr br1
brctl addif br1 tap1_peer
、brctl addif br1 tap2_peer
、brctl addif br1 tap3_peer
、brctl addif br1 tap4_peer
ip netns exec ns1 ip addr add local 192.168.50.1/24 dev tap1
、ip netns exec ns2 ip addr add local 192.168.50.2/24 dev tap2
、ip netns exec ns3 ip addr add local 192.168.50.3/24 dev tap3
、ip netns exec ns4 ip addr add local 192.168.50.4/24 dev tap4
ip link set br1 up
、ip link set tap1_peer up
、ip link set tap2_peer up
Linux 就是路由器(Router),修改配置文件 “/etc/sysctl.conf”, 将 net.ipv4.ip_forward = 0
修改为 1
,保存后退出,即打开了路由转发功能。
查看路由表:route -nee
,添加静态路由:route add -net [ip] netmask [netmask] gw [gateway]
。
tun 是一个网络层(IP)的点对点设备,它启用了 IP 层隧道功能。Linux 原生支持的三层隧道,可以通过命令行 ip tunnel help
查看:
1 | ip tunnel help |
可以看到,Linux 一共原生支持 5 种三层隧道(tunnel):
隧道 | 简述 |
---|---|
ipip | IP in IP,在 IPv4 报文的基础上再封装一个 IPv4 报文头,属于IPv4 in IPv4 |
gre | 通用路由封装(Generic Routing Encapsulation),定义了在任意一种网络层协议上封装任意一个其他网络层协议的协议,属于 IPv4/IPv6 over IPv4 |
sit | 这个跟 ipip 类似,只不过是用一个 IPv4 的报文头封装 IPv6 的报文,属于 IPv6 over IPv4 |
isatap | 站内自动隧道寻址协议,一般用于 IPv4 网络中的 IPv6/IPv4 节点间的通信 |
vti | 全称是 Virtual Tunnel Interface,为 IPsec 隧道提供了一个可路由的接口类型 |
通过 iptables 相关的命令行,可以实现了防火墙、NAT 的功能,而这种功能的实现是通过运行在内核空间的 netfilter 模块完成的,它们之间的关系如下所示:
iptables 内置了三张表:filter、nat 和 mangle。filter 和 nat 是为了实现防火墙和 NAT 功能而服务的,mangle 主要应用在修改数据包内容上,用来做流量整形。iptables 还内置了另外 2 张表 raw 和 security,这里不详细介绍了。
iptables 内置的既是三张表,也是三条链(chain),也是三种策略(policy),这些策略由不同规则(rule)串接而成。
iptables -A INPUT -i eth0 -p icmp -j ACCEPT
这条规则表达的意思是:允许所有从eth0 端口进入且协议是 ICMP 的报文可以接受(可以进入下一个流程)的。
NAT(Network Address Translation,网络地址转换),顾名思义,就是从一个 IP 地址转换为另一个 IP 地址。当然,这里面的根本原因还是IP地址不够用的问题(解决 IP 地址枯竭的方法一个是 IPv6,另一个就是 NAT)。
NAT 从实现技术角度分为:静态 NAT、动态 NAT 和端口多路复用三种方案:
静态 NAT(Static NAT)
静态 NAT 有两个特征:
动态 NAT
一般情况是公网 IP 比私网 IP 地址少的时候,用到动态 NAT 方案。动态 NAT,就是一批私网 IP 与公网 IP 地址之间不是固定的转换关系,而是在 IP 报文处理过程中由 NAT 模块进行动态匹配。虽然,公网 IP 比私网 IP 地址少,但是,同时在线的私网 IP 需求小于等于公网 IP 数量,不然某些私网 IP 将得不到正确的转换,从而导致网络通信失败。
动态 NAT,有三个特征:
端口多路复用 / PAT
如果私网 IP 地址有多个,而公网 IP 地址只有一个,那么,静态 NAT 显然是不行了,动态 NAT 也基本不行(只有一个公网 IP,不够用)。此时,就需要用到端口多路复用。多个私网 IP 映射到同一个公网 IP,不同的私网 IP 利用端口号进行区分,这里的端口号指的是 TCP/UDP 端口号。所以端口复用又叫 PAT(Port Address Translation)。
端口多路复用(PAT)的特征是:
SNAT / DNAT
前面说的静态 NAT(Static NAT)和动态 NAT不能简称 SNAT、DNAT,因为 SNAT/DNAT 有另外的含义,是另外的缩写。要区分SNAT(Source Network Address Translation,源地址转换)与DNAT(Destination Network Address Translation,目的地址转换)这两个功能可以简单地由连接发起者是谁来区分。
Linux 内核空间 Netfilter 模块的 NAT 处理,一共有三个 Chain(处理时刻点):
流 | 流描述 | Chain | NAT类型 | NAT说明 |
---|---|---|---|---|
流1 | 流从外部到达 Linux 用户空间(私网 IP) | PREROUTING | DNAT | 将目的 IP 从公网 IP(Linux 内核空间对应的 IP)转换到私网 IP(Linux 用户空间对应的 IP) |
流2 | 流从 Linux 用户空间(私网 IP)到达外部 | POSTROUTING | SNAT | 将源 IP 从私网 IP(Linux 用户空间对应的 IP)转换到公网 IP(Linux 内核空间对应的 IP) |
流3 | 流从 Linux 内核空间(公网 IP)到达外部 | OUTPUT | DNAT |
iptables 中的 Firewall(防火墙)概念,属于网络防火墙的概念。iptables 中的防火墙的规则就是基于 TCP/IP 协议栈的规则,所以我们称之为网络防火墙。这些规则有:
符合这些规则的,可以设置为通过(ACCEPT),反之,则不通过(DROP)。或者,符合这些规则的,设置为不通过(DROP);反之,则通过(ACCEPT)。
Netfilter 中的 Firewall,会在三个时刻点,进行处理,如下图所示:
mangle 表主要用于修改数据包的 ToS(Type of Service,服务类型)、TTL(Time to Live,生存周期)以及为数据包设置 Mark 标记,以实现 QoS(Quality of Service,服务质量)调整以及策略路由等应用。
netfilter 模块中的 mangle 处理的时刻点如下图所示:
tap、tun、veth pair 在 Linux 中都被称为设备,但是在与日常概念的类比中,常常被称作接口。Neutron 利用这些“接口”进行 Bridge 之间的连接、Bridge 与 VM(虚拟机)的连接、Bridge 与 Router之间的连接。三者与物理网卡之间的对比关系,如下图所示:
Router、Bridge 这些在 Linux 中没有被称为设备的网络功能,反而在日常概念中常常被称为设备。Bridge 提供二层转发功能,Router 提供三层转发功能。Router 还常常借助 iptable 提供 SNAT/DNAT 功能。Bridge 也常常借助 iptable 提供 Firewall 功能。
在 Neutron中,隔离是一个非常重要的特性,利用 namespace 做隔离也是 Neutron 的一个非常重要的手段。
Neutron 是 OpenStack 项目中负责提供网络服务的组件,它基于软件定义网络的思想,实现了网络虚拟化下的资源管理。Neutron 的设计目标是实现“网络即服务”,为了达到这一目标,在设计上遵循了基于“软件定义网络”实现网络虚拟化的原则,在实现上充分利用了 Linux 系统上的各种网络相关的技术。
Neutron管理下面的实体:
无论哪种具体的网络虚拟化实现,一个简化和抽象后的系统架构可以表述为下图所示。
在启用 DVR 特性(J 版本以后支持)之前,所有流量(东西向、南北向)都需要经过网络节点的转发;DVR 特性则允许东西向流量和带有 Floating IP 的南北向流量不经过网络节点的转发,直接从计算节点的外部网络出去。
网络节点有且仅有 Neutron 服务,就是网络服务。Neutron 主要负责管理私有网段和公有网段之间的通信,同时管理虚拟机网络之间的通信以及防火墙等等。一般在部署时会部署两个以上的网络端口,分别用于与控制节点通信、同计算/存储节点通信、用于外部的虚拟机与相应的网络之间的通信。
计算节点主要包含计算服务、网络服务以及监控服务。计算节点对所部署的虚拟机提供基本的网络功能支持,包括隔离不同租户的虚拟机和进行一些基本的安全策略管理。计算节点包含 Nova,Neutron,Telemeter 三个服务:
在 OpenStack 中网络实现的一个简化的架构示意:
计算节点上包括两台虚拟机 VM1 和 VM2,分别经过一个网桥(如 qbr-XXX)连接到 br-int 网桥上。br-int 网桥再经过 br-tun 网桥(物理网络是 GRE 实现)连接到物理主机外部网络。对于物理网络通过 vlan 来隔离的情况,则一般会存在一个 br-eth 网桥,替代 br-tun 网桥。
br-tun将带有 vlan tag 的 vm 跟外部通信的流量转换到对应的 gre 隧道,这上面要实现主要的转换逻辑,规则要复杂,一般通过多张表来实现,这些规则所组成的整体转发逻辑如下图所示。
计算节点上发往 GRE 隧道的网包最终抵达网络节点上的 br-tun,该网桥的规则跟计算节点上 br-tun 的规则相似,完成 tunnel 跟 vlan 之间的转换。br-int 上挂载了很多进程来提供网络服务,包括路由器、DHCP服务器等。这些进程不同的租户可能都需要,彼此的地址空间可能冲突,也可能跟物理网络的地址空间冲突,因此都运行在独立的网络名字空间中。规则跟计算节点的br-int规则一致,表现为一个正常交换机。
Vlan 模式下的系统架构跟 GRE 模式下类似,如下图所示。
需要注意的是,在 vlan 模式下,vlan tag 的转换需要在 br-int 和 br-ethx 两个网桥上进行相互配合。即 br-int 负责从 int-br-ethX 过来的包(带外部 vlan)转换为内部 vlan,而 br-ethx 负责从 phy-br-ethx 过来的包(带内部 vlan)转化为外部的 vlan。
在计算节点中,类似 GRE 模式下,br-int 负责租户隔离,br-eth1 负责跟计算节点外的网络通信。在 Vlan 模式下,租户的流量隔离是通过 vlan 来进行的,因此此时包括两种 vlan,虚拟机在计算内流量带有的 local vlan 和在计算之外物理网络上隔离不同租户的 vlan。br-int 和 br-eth1 分别对从端口 int-br-eth1 和 phy-br-eth1 上到达的网包进行 vlan tag 的处理。此处有两个网,分别带有两个 vlan tag(内部 tag1 对应外部 tag101,内部 tag2 对应外部 tag102 )。其中,安全组策略仍然在 qbr 相关的 iptables 上实现。
在网络节点中,类似 GRE 模式下,br-eth1 收到到达的网包,int-br-eth1 和 phy-br-eth1 上分别进行 vlan 转换,保证到达 br-int 上的网包都是带有内部 vlan tag,到达 br-eth1 上的都是带有外部 vlan tag。br-ex 则完成到 OpenStack 以外网络的连接。
VXLAN 模式下,网络的架构跟 GRE 模式类似,所不同的是,不同节点之间通过 VXLAN 隧道互通,即虚拟化层是采用的 VXLAN 协议,基本结构如下图所示。
计算节点主要包括两个网桥:集成网桥 br-int 和 隧道网桥 br-tun,网络节点担负着进行网络服务的任务,包括DHCP、路由和高级网络服务等,一般包括三个网桥:br-tun、br-int 和 br-ex。
网络命名空间
在 Linux 中,网络名字空间可以被认为是隔离的拥有单独网络栈(网卡、路由转发表、iptables)的环境。网络名字空间经常用来隔离网络设备和服务,只有拥有同样网络名字空间的设备,才能看到彼此。
DHCP 服务
dhcp 服务是通过 dnsmasq 进程(轻量级服务器,可以提供 dns、dhcp、tftp 等服务)来实现的,该进程绑定到 dhcp 名字空间中的 br-int 的接口上。可以查看相关的进程。
路由服务
router 是提供跨 subnet 的互联功能的。比如用户的内部网络中主机想要访问外部互联网的地址,就需要 router 来转发(因此,所有跟外部网络的流量都必须经过 router)。目前router 的实现是通过 iptables 进行的。
安全组
安全组通过 Linux IPtables 来实现,为此,在计算节点上引入了 qbr* 这样的 Linux 传统 bridge(iptables 规则目前无法加载到直接挂在到 ovs 的 tap 设备上),整体逻辑如下图所示:
负载均衡即服务
负载均衡即服务(Load Balance as a Service,LBaaS)是一项网络高级服务。它允许租户动态的在自己的网络创建一个负载均衡设备,可以说是分布式系统中比较基础的组件,它接收前端过来的请求,然后将请求按照某种均衡的策略转发给后端资源池中的某个处理单元,以完成处理。进而可以实现高可用性和横向的扩展性。OpenStack Neutron 通过高级服务扩展的形式支持 LBaaS,目前默认是通过 HAProxy 软件来实现的。
防火墙即服务
防火墙即服务(FireWall as a Service)在网络节点上(具体说来是在路由器命名空间中)来实现。目前,OpenStack 中实现防火墙基于 Linux 系统自带的 iptables 实现。一个可能混淆的概念是安全组(Security Group),安全组的对象是虚拟网卡,由 L2 Agent 来实现,比如 neutron_openvswitch_agent 和 neutron_linuxbridge_agent,会在计算节点上通过配置 iptables 规则来限制虚拟网卡的进出访问。防火墙可以在安全组之前隔离外部过来的恶意流量,但是对于同个子网内部不同虚拟网卡间的通讯不能过滤(除非它要跨子网)。可以同时部署防火墙和安全组实现双重防护。
分布式路由
为了降低网络节点的负载,同时提高可扩展性,OpenStack 自 Juno 版本开始正式引入了分布式路由(Distributed Virtual Router,DVR)特性(用户可以选择使用与否),来让计算节点自己来处理原先的大量东西向流量和非 SNAT 南北流量(有 floating IP 的 vm 跟外面的通信)。这样网络节点只需要处理占到一部分的 SNAT (无 floating IP 的 vm 跟外面的通信)流量,大大降低了负载和整个系统对网络节点的依赖。很自然的,FWaaS 也可以跟着放到计算节点上。DHCP 服务、VPN 服务目前仍然需要集中在网络节点上进行。
挂载本地镜像源,安装以下 rpm 包:python3-openstackclient
、mariadb
、mariadb-server
、python3-PyMySQL
、rabbitmq-server
、memcached
、python3-memcached
、openstack-keystone
、httpd
、python3-mod_wsgi
、openstack-neutron
、openstack-neutron-ml2
、openstack-neutron-openvswitch
、ebtables
、ipset
。
定义 IP 和主机名变量,后续部署使用
1 | LOCALMANAGEMENTIP="192.168.230.134" |
设置语言为中文、编码为 UTF-8
1 | localectl set-locale LANG=zh_CN.UTF-8 |
利用 firewalld
开放端口,更新防火墙规则
1 | firewall-cmd --permanent --add-port 9696/tcp #neutron |
配置 MySQL
1 | cat > /etc/my.cnf.d/openstack.cnf << EOF |
启动 mariadb.service
1 | systemctl enable mariadb.service |
启动 rabbitmqp-server
,增加新用户名和密码,给用户赋予配置、读、写权限
1 | systemctl enable rabbitmq-server.service |
此处发生错误,在
/etc/rabbitmq/rabbitmq-env.conf
文件中添加NODENAME=rabbit@localhost
,重启rabbitmq-server
解决。
将 memcached
监听地址改为所有 IP,启动服务
1 | sed -i '/OPTIONS/c\OPTIONS="-l 0.0.0.0"' /etc/sysconfig/memcached |
MySQL 创建 keystone
和 neutron
数据库
1 | mysql -u root -p <<EOF 2>/dev/null |
更新 keystone
配置文件,设置文件所有权,设置管理 IP,初始化数据库信息和 Fernet
密钥数据库,并设置密码和节点
1 | rm -rf /etc/keystone/keystone.conf |
设置管理 IP,配置 HTTP 配置文件,启动服务
1 | ln -s /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d/ |
配置用户名、密码、项目名等信息
1 | cat >> ~/.bashrc << EOF |
获取 openstack token 并创建 service 项目
1 | source ~/.bashrc |
创建 neutron 用户,将 neutron 用户添加入 service 项目并拥有 admin 权限,创建 network 服务并添加三个 endpoint
1 | openstack user create --domain default --password neutron neutron |
更新 neutron 配置文件,设置文件所有权和管理 IP
1 | rm -rf /etc/neutron/neutron.conf |
更新 ml2 配置文件和所有权
1 | rm -rf /etc/neutron/plugins/ml2/ml2_conf.ini |
更新 openvswitch_agent 配置文件、所有权、业务 IP
1 | rm -rf /etc/neutron/plugins/ml2/openvswitch_agent.ini |
更新 l3_agent 配置文件和所有权
1 | rm -rf /etc/neutron/l3_agent.ini |
更新 dhcp_agent 配置文件和所有权,杀死 dnsmasq 进程
1 | rm -rf /etc/neutron/dhcp_agent.ini |
更新 ml2_conf 配置文件,同步数据库
1 | ln -s /etc/neutron/plugins/ml2/ml2_conf.ini /etc/neutron/plugin.ini |
启动 neutron 服务
1 | systemctl enable neutron-server.service openvswitch.service neutron-dhcp-agent.service neutron-l3-agent.service neutron-openvswitch-agent.service |
使用 openstack network agent list
命令列出代理以验证启动 neutron 代理是否成功,得到输出如下:
启动成功。
使用 neutron net-create net1
命令创建名为 net1
的网络:
使用 neutron subnet-create net1 192.168.2.0/24 --name subnet1
命令创建名为 subnet1
、IP 为 192.168.0.2/24
的子网:
查看创建结果:
]]>假设有一系列「状态」(state)组成的环境,在每一个状态中都可以采取一种「动作」(action)到达下一个状态。 这些状态并不都是相同的,根据实际应用,不同的状态有不同的「奖励」(reward),而且存在终止状态。我们的目标是从任意初始状态出发,到达终止状态,且所获得的奖励最大。
Q-Learning 就是这样一种决策算法,帮助我们在每个状态决定应该采取何种动作,才能最终得到最大奖励。
Q-Learning 算法的核心是维护一张 Q 表,它的每一行对应一个状态,每一列对应一种动作,每个值代表了这个状态下采取这种动作最终可以得到的最大奖励。Q-Learning 会经过多次尝试去更新其中的值,不断试错,从而“学习”到外部环境的机制。
步骤如下:
要说明的:
根据上面数学角度的分析,不难看出实际需要处理的就是两个部分:选择动作和更新 Q 表。下面用 python
演示这两部分。
__init__
初始化函数主要为建立 Q 表:
1 | def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9): |
其中 actions
为动作的集合(list
类型),需要用到 pandas
和 numpy
库。
choose_action
choose_action
是选择动作的函数,需要接收一个参数作为当前状态:
1 | def choose_action(self, observation): |
为方便后续处理和操作,将参数转换为 str
类型:
1 | observation = str(observation) |
接下来需要选择要执行的动作了,但我们首先要判断参数对应的状态是否在 Q 表中,需要引入函数 check_state_exist
:
1 | def check_state_exist(self, state): |
逻辑很简单,当这个状态不在 Q 表中时,我们就把它加入 Q 表。
若此处出现报错 TypeError: unhashable type: 'list'
,应该是把 list
类型的 state
作为参数传了过来。list
类型是不可以作为 key 的,注意需要转换为 str
类型。
在 choose_action
中调用函数 check_state_exist
进行判断:
1 | self.check_state_exist(observation) |
接下来就可以进行动作的选择了!
注意之前提到的 $\epsilon$-greedy 策略,我们需要在一定的概率下选择 Q 表中最优值:
1 | if np.random.uniform() < self.epsilon: |
回忆一下,Q 表每一行对应一个状态、每一列对应一种动作。所以在 Q 表中选择动作,首先要找到当前的状态:
1 | state_action = self.q_table.loc[observation, :] |
然后就可以找这一行中的最大值对应的动作了。
但是这里有一个问题,如果有多个相同的最大值呢?这种情况下如果我们直接判断 argmax,返回的将永远是第一个最大值,永远不会遍历到后面的最大值对应的动作。所以这里我们需要随机选择一个最大值来避免这种情况:
1 | action = np.random.choice(state_action[state_action == state_action.max()].index) |
这就是基于 Q 表选择的动作了。
在另一个分支进行随机选择:
1 | action = np.random.choice(self.actions) |
最后返回执行的动作:
1 | return action |
完整代码:
1 | def choose_action(self, observation): |
learn
learn
是学习的过程,也就是更新 Q 表的函数,需要接收当前状态、当前执行的动作、获得的奖励和下一个状态 4 个参数:
1 | def learn(self, s, a, r, s_): |
同样对状态做字符串化处理,并判断下一个状态是否在 Q 表中:
1 | s = str(s) |
根据上一部分的分析,更新 Q 表需要知道当前选择对应的最大奖励值($r+\gamma max_{a’}Q(s’,a’)$,记作 q_target
)和 Q 表预测的最大奖励值($Q(s,a)$,记作 q_predict
)。
其中 q_predict
比较容易得到:
1 | q_predict = self.q_table.loc[s, a] |
而 q_target
需要判断下一状态是否到了最终状态,如果是,则 q_target
直接为当前获得的奖励 r
,否则根据公式计算:
1 | if s_ != 'terminal': |
更新 Q 表:
1 | self.q_table.loc[s, a] += self.lr * (q_target - q_predict) |
强化学习 (Reinforcement Learning) | 莫烦Python
MuJava 是一个变异测试的工具,可以生成变异体并运行,最终可以得到变异测试的结果。
变异测试是衡量测试充分性的有效方法,其思想就是模拟程序编写中可能会出现的错误,得到一系列和源程序不同的“变异体”,用来“测试”你的测试程序是否能测出来这些“变异”。你的测试程序杀死(使变异体的运行结果不同于源程序)的变异体越多,测试越充分。
直接到 官网 下载 mujava.jar
。
为了后续实验进行,还需要下载 junit.jar
(编写测试程序)、openjava.jar
。
保存三个 jar 包到固定路径,编辑 ~/.bash_profile
引入环境:
1 | export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_281.jdk/Contents/Home |
(适用于 macOS,Windows 略有不同)
保存并运行 source ~/.bash_profile
。
为了使用 MuJava,需要创建需要的目录结构:
1 | |--\classes\ |
\src\
目录。javac
编译源文件,得到 classes
文件,移至 \classes\
目录。java mujava.gui.GenMutantsMain
,进入图形化设置界面,勾选需要生成变异体的文件和需要的变异算子,点击 Generate
即可生成(保存在 result
目录)。若此处出现问题,请检查 0x00 第 3 步中路径是否包含空格。即使使用 \
转译也可能存在问题,建议用 -
或 _
代替空格。
使用 JUnit 编写即可,比较简单,得到 xxxTest.java
。
javac
编译测试文件,得到 classes
文件,移至 \testset\
目录。java mujava.gui.RunTestMain > TestResult.log
,将变异测试日志输出至文件保存。若此处出现问题,请检查 0x00 第 3 步中是否引入了 $JAVA_HOME/lib/tools.jar
和 $JAVA_HOME/lib/dt.jar
。
变异测试完成,后续可以进一步分析测试代码和变异体,做进一步改进。
Major 和 Mujava 功能相近,也是变异测试的工具。
直接到 官网 下载 Major v1.3.5,解压为 major 目录,存放到固定路径。
配置环境变量:
1 | export PATH=/path/to/major/bin:$PATH:$JAVA_HOME/bin |
保存并运行 source ~/.bash_profile
。
验证是否配置成功:
1 | ❯ javac -version |
如果验证时得到的输出和上述不同,特别是 javac -version
输出结果不包含 Major-v1.3.5
,建议检查第 2 步引入环境变量的顺序,应将 major/bin
目录放在最前面。
Major 使用 ant
运行变异测试,并在 major/example/
目录下给出运行模板。所以我们需要依此建立目录结构:
1 | |--\src\ |
将源文件移至 src
目录,将 JUnit
测试文件移至 test
目录。
请确保代码文件的 package
和目录结构对应,参照给出的运行模板。
build.xml
和 run.sh
是 Major 运行的重要文件,前者是配置文件、后者是运行脚本。由于运行目录不同,所以在运行前我们需要在 example
的基础上,根据自己的实际情况对两个文件做一些修改。
build.xml
可以在第一行修改自己的项目名称:
1 | <project name="YourProjectName" default="compile" basedir="."> |
修改 /javac/
文件的路径:
1 | <property name="major" value="/your/path/to/major/bin/javac"/> |
它上面两行一般不需要改动。
run.sh
修改 /major/
目录的路径:
1 | MAJOR_HOME="/your/path/to/major" |
如果没有编写 MML 脚本(一般情况下不需要自己编写),修改 ant
运行的参数:
1 | MAJOR_HOME/bin/ant -DmutOp=":ALL" clean compile |
直接指定为 ALL
对应全部变异算子,若此处不修改可能会导致后续生成变异体数量为 0。
运行 ./run.sh
,得到类似下方的输出则成功:
1 | ... |
和 MuJava 类似,后续可以进一步分析测试代码和变异体,做进一步改进。
如果 Mutants covered 未达到 100%,请移除源程序的 main
方法。
如有其他问题,强烈建议阅读 官方文档,十分详细。
]]>每一天都看似平常,但 365 个平常交叠,总会带来不一样的感受。是啊,茫茫中又度过了一年。2020 的记忆未曾消去,2021 却已悄然而过,来不及沉浸在过去的回忆里,时间催促着我们向前看,2022 的曙光即将在黑夜之后到来。
每逢新年伊始,心中满怀对新年的企盼。无数次盼望新年胜旧年,盼望旧年的伤悲都能随风,盼望新年的喜乐都能常伴。心怀希望永远是我们面对陌生的勇气,即使时代并不会对我们好些,我们也会继续走下去。
即使新冠疫情改变了世界的运作方式,但 2021 对我来说也不算很糟。做出了很多新的尝试,有很多有意义的回忆,并没有停留在以前的认知。热爱着我所热爱的,坚持着我所坚持的,继续学习,继续进步。
这一年的课余时间除了休息外,应该只有做一些项目和学一些新的知识了。开始使用 Notion 作为笔记管理工具,所以很惭愧没有经常更新博客……(2022 一定会多更新的,不能荒废了)学习真是一件容易让人满足的事情。
找到几张比较有意义的照片,不能说可以贯穿 2021,但也能在漫无目的中留下一些意义。
2021 收到最有心的生日礼物,感谢一直陪伴我的 peggy。
在天津大悦城 Apple Store 第一次体验了 iPhone 12 mini,可以说是理想中的手机大小了。
AirPods Pro 牛年限定……
拥有了第一台 Mac(也是最贵的生日礼物……),陪伴我一年的 Hackintosh 终于光荣退役,让它重新回到了 Windows。
第一次坐救护车……希望不再有这种经历了。
青年湖畔的落日和晚霞。
重回卫津路,19 年的回忆浮现
打卡三里屯 Apple Store。
第一次听周鸿祎老板的讲座。
第一次去海洋馆,看到了北极狐。
去看了世界智能大会。
AirPods Pro,喧嚣离我远一步。
青年湖畔的午后。
青年湖畔的晚霞。
可能……是继 4s 后的第一部小手机?
夜景模式下的体育场。
2021 初雪,随立冬而至。前一天晚上还在下雨,第二天醒来室外已是银装素裹。
打卡天津恒隆广场 Apple Store。
22 考研第一天傍晚,路上满是出校的车。
每一年都和网易云度过,今年比去年多听了近 200 小时、近 1000 首歌。
没想到今年有 324 天都登录了 B 站 🤣
照片可以定格时间,时间也让照片有了岁月的意义。回望 2021 迈出的每一步,似乎都是平平无奇的一个念头,但这些「抉择」确确实实改变了许多。「落子无悔,抉择本身就是向前」,希望自己可以摆脱抱怨,坚持自己的选择,永远向前看。
来不及停留,来不及等待。来不及感伤岁月,来不及蹉跎光阴。惟愿 2022 的每一分时光都有意义,继续热爱生活。
2021,再见!
]]>好久没有更新博客了。上一次更新还是在 7 月 13 日,正好过去了两个月的时间。上一篇文章是在学习 swiftUI 时记录的,如今已经完成了 100 days of swiftUI。写上一篇文章的时候还没开始做这个 App,如今已经结束了。
两个月的时间,从在家躺平到提前返校,再到开始小学期、开始暑期训练营,再到正式上课……与此同时,这个 App 的开发也正好伴随着我度过这两个月。
做的第一个 App 是在 2020 年的暑期训练营,是一个 Todo 的快应用。虽然获了奖,但确实太简单了。一个人完成的项目,并没有付出很大的精力。但是在今年的暑期训练营,深深感受到了 Android 原生开发的困难,可能这也是 Flutter 等框架兴起的原因吧。
言归正传,我的第二个 App 并不能称作“我的”,因为小组的产品和设计起了很大作用,没有她们的努力,这个 App 最终也不会呈现。特别感谢设计组的朋友,无论是界面、配色、交互等各个方面,都设计得很完美。也要感谢 iOS 组组长提供的学习机会,学到了很多。
App 的功能是记账,当这个需求发布的时候我正想找一个记账的软件,遂即开始开发。我试用了很多记账的 App,大多十分冗杂。最终我选择了 iCost,并且至今仍在使用。它界面的简介和纯粹在我看来是十分可贵的,我正需要这样一款 App。在我的 App 开发大部分完成后,我发现它和 iCost 仍有很多差距,iCost 某些方面的布局和设计十分巧妙,也正是我之后需要学习的地方。
虽然 App 的展示结束了,但我认为这款 App 的开发远没有结束。我的 commit 集中在 8 月 8 日的一周(86 commits)和 8 月 15 日的一周(10 commits),之后由于小学期、课程设计、训练营、选修课等无数 ddl 就只能搁置了,大约暂停了 25 天……直到最近才开始修改之前留下的各种 bug,还有很多功能需要完善……
还有很长的路要走……所以先告一段落吧,希望有朝一日可以把 App 完善得更好。
]]>首先定义结构体,在其中对内容修饰:
1 | struct Watermark: ViewModifier { |
然后根据此结构体,定义 extension
,在其中定义修饰器函数:
1 | extension View { |
最终只需调用 extension
中的函数即可实现:
1 | Color.green |
效果图:
]]>大学生活度过了一半,仍旧在学期内忙碌、假期内无所事事两个状态间切换,却没有留下些什么。
看到许多同龄人在大学两年快速成长,收获颇丰,学习生活两开花,令人羡慕。
假期前度过的考试周着实令人感到紧张刺激,感觉是一个学期记忆里的高峰,也是学习新知识的最多阶段。
关于课业,鄙人的大类课程终于告一段落了,接下来将面对专业方向的选择,于是在这个历史性的阶段,想着整理一番两年的学习资料,与它们告别,同时便于后人翻阅。
考试周前在 GitHub 上偶然间看到了许多课程资料分享的 repo,于是 Google 了一下,发现本校尚无,遂自创之。
后在考试期间、放假之初也在想如何归纳,后来慢慢变得细化、有条理,最终花了几天时间创建完成。
本想着能节约一下本就贫瘠的硬盘空间,没想到百余次 commit 让 .git 文件夹达到了 10 G,是资料文件的好几倍……
算了,10 G 就 10 G 吧……
就放在 这里 了,欢迎有缘人看到提提 Issue 或 PR……
希望这个项目可以帮助到更多的人吧……
2020 年感觉经历了很多,本想在寒假的时候认真总结一下,但却又想不出什么值得纪念的事情。
从人类尺度上来说,时间是连续的,所谓的年也不过是人为根据天体运行规律与气候所做的尺度划分。
虽然从回忆中单单拎出任何一件事来说,都不足以道,但是聚在一起,反倒如潮水般,暗流奔涌。
无数件小事堆叠、重合,不断推搡着时间前进,有时多得让人喘不过气,有时空闲得静看庭花。
对所有人来说非同寻常的 2020 年,不知改变了多少人的人生轨迹。
疫情束缚了人的脚步,史无前例的线上教学,给了我莫大的自由空间。
2020 年,继续在博客上活跃,也尝试了公众号(因为发了很多实验讲解导致同学关注的很多),找到了喜欢做的事。
2020 年, 举行了线上发布会,这也是我开始凌晨一点守候 发布会的开端。从 WWDC20 开始, 至今所有的发布会都熬夜看完直播。从惊艳的 iOS 14、iPadOS 14,还有 macOS Big Sur;从 iPad Air、Apple Watch 6 到 iPhone 12、Apple Silicon M1、新的 MacBook Air、MacBook Pro、Mac mini,再到不痛不痒的 iOS 15、iPadOS 15、macOS Monterey……一年多的时光, 正潜移默化地影响着我的生活。
第一次接触 macOS 是官网的 Mojave 介绍,壁纸随着时间的推移,光影也在变化。后来了解到了黑苹果,最后熬了几个夜终于给装好了,用了一年多没出现异常。
后来换了真正的 MacBook,原来的电脑也结束了使命,重装回了 Windows。
在此记录一下,以纪念陪伴我一年的 Hackintosh。
2020 年,被困在内,但也可能是我向外迈出的第一步。参加了创新计划,最终顺利结题。参加了暑期训练营,第一次写应用,还获得了小奖(那段时间忙得甚至没来得及记录……)。第一次参加社团,当上了部长,组织了几次活动,有些成就感。
鄙人虽然才疏学浅,但很喜欢向别人分享学到的知识。2020 年报名了新生小班,遇到了非常厉害的几位“同事”,也接触了许多刚入大学的新生。
有幸指挥了开学典礼,印象深刻的是前夜的准备。
(这张图片拍的不错,出自摄影师之手)
准备完,回宿舍的路上,安静的没有人,忽然觉得很自由。
(这张图片当然是我自己拍的,但不是趴在地上)
新生周结束的时候,好多小班都感慨颇深。
工作很辛苦,几乎把宿舍搬到了办公室,随时回消息,提前商量通知,虽然累,但是很快乐,一起吐槽奇葩问题,一起欣慰工作顺利,脑洞大开,脑回路拓宽,一起唱歌,一起蹦迪,一起吃喝,一起复习准备考试,一起湖边看星星唱歌。
好久没有这种一个团队一起付出的感觉了,这三周我很开心,很回味,机会不再有,友谊不会散~
——hrq
太多的话来不及表达,太多的人来不及道别,太多的事来不及结尾。
时过境迁,岂敢奢求驻足暂歇
幸甚至哉,得同道之人渡日夜
愿君前程皆坦途,往来莫徘徊
——hzy
永远不要甘于自己的平庸,永远对梦想和目标满怀热忱,永远永远不要习惯懒惰。
——zyn
面对大学里的众多选择,我曾选择逃避,选择承认自己的平庸然后自暴自弃。这段操心而忙碌的时光就像闹铃一般吵醒了我,让我突然摆脱了之前浑浑噩噩的状态,找到了自己为之奋斗的目标。
请永远保持踏进校门时心中的那份希冀与热忱。
——zyh
还有很多,现在可能也回忆不起来了。只记得那是一个夏夜,十几个少年在湖边且行且歌。
有星空相伴,亦如星般璀璨。
2020 年,有些事情确实没有白做,但得到的同时也伴有失去。没有什么两全其美的办法,尽力去弥补就好了。
在此记录一下,以纪念逝去的 2020。
]]>社会主义没有辜负中国
宣言
习近平总书记在党史学习教育动员大会上深刻指出,对共产主义的信仰,对中国特色社会主义的信念,是共产党人的政治灵魂,是共产党人经受住任何考验的精神支柱,强调党的百年奋斗历程和伟大成就,是我们增强道路自信、理论自信、制度自信、文化自信最坚实的基础。总书记的话语,掷地有声、坚定豪迈,深刻揭示了社会主义、共产主义与百年求索、百年奋斗的内在关系,彰显了中国共产党人沿着中国特色社会主义这条唯一正确道路前进的坚毅和执着。
百年历程,许多人和事仍然历历在目,许多呐喊和高歌犹在耳旁。走过风霜雪雨,创造人间奇迹,我们有义务用胜利告慰先烈:社会主义没有辜负中国!我们有责任让历史告诉未来:社会主义不会辜负中国!
(一)
历史的偶然中往往带着必然。19世纪40年代,古老的中国被列强的坚船利炮打开了国门,中国命运从此进入前所未有的悲惨境地。几乎是同样的年代,在资本主义发展方兴未艾的欧洲,马克思、恩格斯开始了对科学社会主义、对人类解放进步事业的伟大探索。
鸦片战争后的中国,积贫积弱、任人宰割。“四万万人齐下泪,天涯何处是神州”。谭嗣同的这句诗,字字血泪、字字彷徨。太平天国、戊戌变法、义和团运动、辛亥革命……中国人在黑暗中苦苦摸索救亡图存之路;改良主义、自由主义、社会达尔文主义、无政府主义、实用主义……种种西方的理论和学说都被引进作为强国富民的药方。一个个方案都试过了,却又屡屡化为泡影。一条条道路都探寻了,却撞得头破血流。“无量头颅无量血,可怜购得假共和。”列强横行、军阀混战,人民水深火热,第一次世界大战更是戳穿了资本主义文明看似美好的幻象。无数仁人志士一次次地用生命和灵魂发问:中国的出路在哪里?民族的希望在哪里?
十月革命一声炮响,给中国送来了马克思列宁主义。这是一场伟大的历史之约,这是一个郑重的历史之诺!封建社会上千年来的枷锁太严密,非进行彻底的社会改造不能除旧布新。帝国主义带给中国人的压迫太沉重,非动员几万万劳苦大众的伟力不能与之相抗。
李大钊赞叹:“人道的警钟响了!自由的曙光现了!试看将来的环球,必是赤旗的世界!”陈独秀宣示:“十八世纪法兰西的政治革命,二十世纪俄罗斯的社会革命,当时的人都对着他们极口痛骂;但是后来的历史家都要把他们当做人类社会变动和进化的大关键。”年轻的毛泽东疾呼:“时机到了!世界的大潮卷得更急了!洞庭湖的闸门动了,且开了!浩浩荡荡的新思潮业已奔腾澎湃于湘江两岸了!”
1920年乍暖还寒的春天,29岁的陈望道在老家浙江义乌分水塘的柴房里,废寝忘食两个月,第一次完整译出了《共产党宣言》,首印1000册即刻售罄,到1926年重印再版达17次之多。先进的、不屈的中国人经过反复比较、反复推求,选择了马克思主义作为救国救民的道路,作为始终不渝的志向。
1921年7月,以马克思主义为指导思想、以共产主义为奋斗目标的政党——中国共产党诞生,胸怀着信念、嘱托和梦想,在上海石库门的旭日里、在嘉兴南湖的碧波中毅然起航。从此以后,社会主义的火种就在东方点燃,曾经困顿无望的中国就有了方向!
(二)
大革命失败后,共产党员夏明翰在汉口被捕,英勇就义前给妻子写信诀别:“抛头颅、洒热血,明翰早已视等闲。各取所需终有日,革命事业代代传。红珠留着相思念,赤云孤苦望成全。坚持革命继吾志,誓将真理传人寰。”在那些风雨如晦的岁月里,像夏明翰这样为了共产主义信仰九死而不悔、坚信革命理想一定会实现的烈士,何止千千万万。他们一旦认定了信仰和主义,就再也没有彷徨过、动摇过,不惜用青春和鲜血浇灌“共产花开”。
这个信仰和主义,闪耀着理想烛照人心的光芒。《共产党宣言》描绘道:“代替那存在着阶级和阶级对立的资产阶级旧社会的,将是这样一个联合体,在那里,每个人的自由发展是一切人自由发展的条件。”在社会主义新世界里,人的价值居于第一位,没有剥削、没有压迫,劳动光荣、劳工至上,人人平等富足,彼此亲如一家……这是超越资本主义世界的新世界,也是中华民族自古以来向往的“天下大同”,吸引着无数先进分子心驰之、神往之、践行之。
这个信仰和主义,揭示着社会发展演化的规律。世界大势、浩浩汤汤,顺之者生、逆之者亡。中国共产党是工人阶级的先锋队,代表着先进生产力的方向,代表着历史前进的潮流。经过科学理论武装、掌握社会发展规律的党,就具备了引领社会变革、推进正义事业的自觉,就具备了无坚不摧、百折不挠的力量。
这个信仰和主义,指引着革命走向胜利的道路。以毛泽东为主要代表的中国共产党人,用马克思主义立场观点方法分析中国国情、解决中国问题,鲜明提出中国革命的任务是推翻帝国主义、封建主义、官僚资本主义“三座大山”的压迫,中国革命的道路是农村包围城市、武装夺取政权,中国革命的力量是工人阶级、农民阶级、小资产阶级和一定条件下的民族资产阶级,无产阶级是领导力量、人民是真正的英雄,中国革命要分民主主义革命和社会主义革命两个阶段进行……这些科学认识,处处闪耀着马克思主义真理的光辉,引领着中国革命澎湃向前。
革命理想高于天。正是在理想信念的火炬下,我们党广泛发动工农群众,敢于突击冲锋,成功推进了北伐战争;正是在理想信念的火炬下,幸存的共产党人掩埋了被反动派屠杀的同伴的尸首,拿起武器、走进山林,投入新的战斗;正是在理想信念的火炬下,红军将士闯天险、战强敌,爬雪山、过草地,“风雨浸衣骨更硬,野菜充饥志越坚”,完成了彪炳人类史册的二万五千里长征;正是在理想信念的火炬下,党和人民用坚忍不拔、血战到底,书写了抗击日本军国主义的民族壮歌,取得了抵御外侮的最终胜利;正是在理想信念的火炬下,英勇的人民解放军只用三年时间就打垮了国民党反动派800万军队,彰显了什么是“天若有情天亦老,人间正道是沧桑。”
“批判的武器当然不能代替武器的批判,物质力量只能用物质力量来摧毁。”28年浴血奋战,28年砥砺前行,我们的国家从任人欺辱的“东亚病夫”变成令世界刮目相看的“东方醒狮”,我们的人民从做牛做马的奴隶变成扬眉吐气的主人。中国革命的胜利,就是中国共产党人运用马克思主义挽救中国的伟大实践,就是科学真理彰显力量的伟大历程!
(三)
1949年6月30日,毛泽东发表《论人民民主专政》提出,我们要经过人民共和国,由农业国进到工业国,由新民主主义社会进到社会主义社会和共产主义社会。中华人民共和国的成立,是科学社会主义原则与中国革命实际相结合的历史结果,也标志着人类进步事业和社会主义力量的发展壮大,开启了社会主义在世界东方的伟大时代。
这是一个革故鼎新、改天换地的时代。面对重重困难考验,中国共产党带领人民迅速医治战争创伤、恢复国民经济,以中国独有的形式实现了对农业、手工业、资本主义工商业的社会主义改造,创造性地完成了由新民主主义革命向社会主义革命的转变,成功实现了中国历史上最深刻最伟大的社会变革。轰轰烈烈的土地改革,使三亿多农民无偿获得七亿亩土地和生产资料;1954年宪法,用根本大法的形式把人民民主和社会主义的原则固定下来;人民代表大会制度、中国共产党领导的多党合作和政治协商制度、民族区域自治制度,构筑起社会主义制度的“四梁八柱”……在这个古老而青春的国度,中国人民建设着社会主义的巍巍大厦,品尝着幸福生活的滋味。
这是一个朝气蓬勃、激情燃烧的时代。“每一秒钟都为创造社会主义社会而劳动”。规划于清末的成渝铁路在新中国成立前的40多年里还是地图上一条虚线,1950年正式开工后只用两年就全线贯通;“一五”期间156个重点工程、694个建设项目全部建成,打下了社会主义工业化的坚实基础;治淮治黄、治理长江取得明显效果,农田水利建设在全国热火朝天铺开;全国城乡卫生医疗网基本形成,天花、霍乱、血吸虫病、疟疾、鼠疫等疾病,或被根除、或得到有效防治……新生的人民政权唤醒了巨大的生产力,新生的社会主义制度激活了人民的能量、促进了人民的福祉。
这是一个英雄辈出、斗志昂扬的时代。为了和平,志愿军将士出国作战,谱写了以“钢少气多”力克“钢多气少”的雄壮史诗;为摘掉“贫油少油”的帽子,“铁人”王进喜带领钻井队战天斗地,“宁肯少活20年,拼命也要拿下大油田”;为改变贫穷落后的面貌,县委书记的榜样焦裕禄带领兰考人民整治“三害”,“生也沙丘,死也沙丘,父老生死系”;为打牢国家自立自强的基石,钱学森、钱三强、邓稼先等一大批科研工作者把汗水和热血洒在茫茫戈壁,创造了“两弹一星”的奇迹……无数有名字的英雄和没有留下名字的英雄,用血肉之躯和坚强臂膀,扛起民族的责任、共和国的荣光。
“筚路蓝缕,以启山林。”在中国这样经济文化比较落后、人口众多的东方大国建设社会主义,犹如攀登一座人迹未至的高山,没有笔直的大道可走,没有现成的路径可循。我们依靠“人民创造历史”的伟力,依靠“集中力量办大事”的优势,创造了一个又一个可以载入中华民族和人类史册的奇迹。我们凭着“革命加拼命”的精神,凭着“一万年太久、只争朝夕”的勇气,在九百六十多万平方公里的土地上描绘了社会主义新中国的最美图画。我们也曾在摸索探求的路上,遭受“文化大革命”这样严重的挫折,惨痛教训值得永远汲取。
无论平坦还是崎岖,无论阳光还是风雨,党领导人民探索社会主义道路的脚步始终向前。历史已经证明:“我们不但善于破坏一个旧世界,我们还将善于建设一个新世界”!
(四)
“什么是社会主义?怎样建设社会主义?”这个回荡在中国上空的历史之问,中国共产党人从未停止作答。从深刻揭示社会主义建设和社会主义改造的“十大关系”,到及时作出我国社会主要矛盾已经转变成“先进的社会主义制度同落后的社会生产力之间的矛盾”的重要论断,到鲜明提出正确处理人民内部矛盾,无不是宝贵的探索、艰难的行进。
党的十一届三中全会成为党的历史和新中国历史上具有深远意义的伟大转折。停止使用“以阶级斗争为纲”,把全党工作重点转移到社会主义现代化建设上来,重新确立解放思想、实事求是的思想路线……为了建设社会主义,中国共产党领导人民矢志推进新的伟大革命,开启了改革开放的伟大航程。
贫穷不是社会主义!邓小平指出:“社会主义的本质,是解放生产力,发展生产力,消灭剥削,消除两极分化,最终达到共同富裕。”为了使生产关系适应生产力的发展,家庭联产承包责任制广泛施行,经济特区先行先试,乡镇企业异军突起,科技体制改革深入推进,对外开放格局加快形成,蕴藏在广大人民中的活力创造力充分迸发。
走自己的道路,建设有中国特色的社会主义!我们深刻认识到我国处于并将长期处于社会主义初级阶段,提出党在社会主义初级阶段的基本路线,积极发展公有制为主体、多种所有制经济共同发展的基本经济制度,不断完善社会主义市场经济体制,提出小康社会目标和现代化分步走战略,开创和发展了中国特色社会主义。
坚持改革开放的社会主义方向!坚持改革开放、坚持四项基本原则,这两个基本点紧密联系、不可偏废。我们坚持社会主义物质文明和精神文明“两手抓、两手都要硬”,坚定推进党的建设新的伟大工程,全面推进中国特色社会主义经济、政治、文化、社会、生态文明建设,让人民群众共享改革发展成果,为社会主义理想插上现实的翅膀。
改革开放40多年来,我国经济总量一路超过意大利、法国、英国、德国、日本,稳居世界第二;我国人民生活水平持续提升,已经进入中高收入国家行列;神州大地面貌日新月异,公路成网、铁路密布、西气东输、南水北调、高坝矗立、大桥巍峨,天堑变通途;中国还战胜了历史罕见的洪涝、雨雪冰冻、地震等重大自然灾害和非典等重大疫病,经受住了亚洲金融危机和国际金融危机严峻考验,风雨过后更见气度从容、身姿挺拔。
在把握历史前进的逻辑中前进,在顺应时代发展的潮流中发展。中华大地汹涌澎湃的伟大实践表明:只有社会主义才能发展中国,只有改革开放才能让中国大踏步赶上时代、让人民过上幸福生活。中国特色社会主义道路越走越宽广!
(五)
雄伟壮丽的社会主义事业,凝结着一代代共产党人的艰苦卓绝和付出奉献,负载着多少先哲英烈的寄托与热望。当历史的接力棒再次传递,习近平总书记的话语铿锵有力:我们这一代共产党人的任务,就是继续把坚持和发展中国特色社会主义这篇大文章写下去!
党的十九大向全党全国和全世界庄严宣告:“经过长期努力,中国特色社会主义进入了新时代,这是我国发展新的历史方位。”
新时代的中国,理想的旗帜鲜艳高扬。面对世界百年未有大变局,习近平总书记带领全党全国人民揽全局、应变局、开新局,党和国家事业取得历史性成就、实现历史性变革,中华民族比历史上任何时候都更接近民族复兴的伟大目标。中国人民对马克思主义、共产主义的信仰更加坚定,对中国特色社会主义的信念更加牢固,对实现中华民族伟大复兴的信心空前高涨。
新时代的中国,发展的动力深厚强劲。从十八届三中全会的全面深化改革,到全面依法治国、全面建成小康社会,再到全面从严治党、以党的自我革命推动社会革命,从坚持和完善中国特色社会主义制度,到立足新发展阶段、贯彻新发展理念、构建新发展格局、推动高质量发展,全面建设社会主义现代化国家,中国特色社会主义的战略布局日益完善,现代化建设的方向目标愈加清晰。
新时代的中国,人民的地位充分彰显。“江山就是人民,人民就是江山”,初心的回响穿越时空。“人民对美好生活的向往,就是我们的奋斗目标”,铿锵的宣示淬铁成钉。为了实现中国人民摆脱贫困的千年夙愿,党领导人民打响了脱贫攻坚战,贫困地区广大干部群众顽强拼搏,第一书记和驻村干部全力投入,东西部协作精准对接,社会各界有钱出钱、有力出力,一户户贫困乡亲感受着社会主义大家庭的温暖,一座座寂静的深山涌动着生机和希望。
新时代的中国,团结的力量一往无前。面对科技的高峰,我们从不退缩。嫦娥飞天、蛟龙入海、天眼观星、北斗组网,就在前不久,“祝融”号火星车经过295天的旅程,成功登陆火星。面对霸凌和打压,我们从未屈服,全党全国敢于斗争、勇于胜利,攒成一股劲、拧成一股绳。百年不遇的新冠肺炎疫情,把我们每个人的命运与国家的、集体的命运紧紧连在一起,14亿中国人心手相连、守家护国,创造了人类抗疫斗争史上的伟大奇迹……社会主义的制度优势得到极大彰显。
天地有正气,浩然塞苍冥。如果说社会主义作为人类的正义事业、崇高的价值追求,赋予了新时代以最鲜明的底色、最厚重的底气;那么,新时代就以它最波澜壮阔的实践,赋予了科学社会主义以新的思想维度、新的历史高度。
2021年4月,习近平总书记专程来到广西全州,瞻仰红军长征湘江战役纪念园,他动情地说,理想信念之火一经点燃就会产生巨大的精神力量,要缅怀革命先烈,赓续共产党人精神血脉,坚定理想信念,砥砺革命意志。
回望八十七年前,长征路上、湘江岸边,无数红军战士为了保存革命的火种鏖战拼杀,用鲜血染红了漫漫征程、滚滚江水。这些大多二十来岁、甚至只有十五六岁的战士们,视死而如归、乐观而顽强,就是因为胸怀着对革命必胜的信念,对社会主义、共产主义美好社会的憧憬。这是一个党永生不灭的基因,是一个民族由衰而兴的密码。
今天,我们可以告慰百年来一切先辈和英魂的是:此时此刻,社会主义的阳光正映照在奋斗者的身影中、孩子们的笑脸上,中国特色社会主义旗帜正引领中华民族伟大复兴呈现出前所未有的光明前景。我们必将创造让世界刮目相看的更大奇迹,必将实现共产党人最崇高的伟大理想!
中国没有辜负社会主义
宣言
英国伦敦,大英博物馆,1516年出版的莫尔的《乌托邦》一书静静躺在展柜里。同时留在这座博物馆图书阅览室地板上的,是一位伟人厚重的足印。正是这位为人类解放事业奋斗终身的马克思,将社会主义从空想变为科学,从而广泛而深刻地影响了世界,也广泛而深刻地改变了中国。
中国北京,人民大会堂,习近平总书记2016年在庆祝中国共产党成立95周年大会上向世界宣示:中国共产党领导中国人民取得的伟大胜利,使具有500年历史的社会主义主张在世界上人口最多的国家成功开辟出具有高度现实性和可行性的正确道路,让科学社会主义在21世纪焕发出新的蓬勃生机。
数百年奔流激荡。曾经苦难深重,如今意气昂扬。在科学真理和崇高理想的指引下,中国大地发生历史巨变,我们无比坚定,社会主义没有辜负中国!在中国共产党领导人民的顽强奋斗中,信仰的光芒熠熠闪烁,伟大的事业青春盎然,我们无比自豪,中国没有辜负社会主义!
(一)
走进江苏常州的瞿秋白纪念馆,“我总想为大家辟一条光明的路”的誓言格外醒目。
中国共产党这个百折不回的寻路者、大勇无畏的开路人,面对种种考验、重重难关,以愚公移山的坚定、精卫填海的奉献,带领中国人民走出了一条险峻而壮丽、艰辛而宽广的中国道路。中国特色社会主义道路,是党和人民100年奋斗、创造、积累的根本成就,是引领中国进步、增进人民福祉、实现民族复兴的康庄大道。
这是一条在历史洪流中扭转民族命运、书写人间奇迹的奋斗之路。在“山重水复疑无路”的彷徨困顿中,马克思主义给中国带来“柳暗花明”。从此,中国共产党开展了以马克思主义之“矢”射中国之“的”的伟大实践。为了推翻“三座大山”,党领导人民开创了农村包围城市、武装夺取政权的革命道路,建立了新中国。为了改变一穷二白的落后面貌,我们建立起全新的社会主义制度,形成了独立的比较完整的工业体系和国民经济体系,并在总结正反两方面经验的基础上,开启了改革开放的伟大航程,极大解放和发展了生产力。面对民族复兴和世界变局的交织激荡,我们坚定理想信念、保持战略定力,围绕坚持和发展中国特色社会主义,完善总体布局、确立战略布局,引领中华民族迎来了从站起来到富起来、强起来的伟大飞跃。
这是一条把人民放在最高位置,得民心、顺民意、惠民利的初心之路。“人民就是江山,共产党打江山、守江山,守的是人民的心,为的是让人民过上好日子。”一代代共产党人为了人民的利益和福祉,把青春和生命、鲜血和汗水,倾注在这片可爱的土地。“小康路上一个都不能少”!为了让幸福的阳光洒遍神州每一个角落,习近平总书记带领全党全国打响脱贫攻坚战,25.5万个驻村工作队挺进一线,近200万名乡镇干部、数百万村干部倾力奋战,八年时间实现了9899万农村贫困人口全部脱贫,832个贫困县全部摘帽,12.8万个贫困村全部出列。这是党、人民、民族的伟大光荣,是我国社会主义制度优越性的充分体现,标志着中华民族向着共同富裕迈出了一大步。
这是一条在经济文化落后国家探索建设现代化的创造之路。现代化是世界近代以来的历史潮流,也寄托着马克思主义先驱对理想社会的期许。错失了工业革命机遇的中国,从所谓“天朝上国”跌落成任人宰割的“鱼肉”。严复著《原强》《辟韩》,郭嵩焘著《使西纪程》,孙中山著《建国方略》,都见证着对现代化的希望和失望。只有中国共产党登上历史舞台,根除了帝国主义和封建主义的祸根,实现了经济基础和上层建筑的彻底改造,才为中国现代化提供了根本前提。从“四个现代化”目标到“三步走”战略,从建设小康社会到建设现代化强国……党领导人民不但用几十年时间走完了发达国家几百年走过的工业化历程,而且探索开辟了物质文明和精神文明相协调、全体人民共同富裕、人与自然和谐共生、走和平发展道路的中国式现代化,为人类社会发展提供了现代化的全新选择。
这是一条始终保持革命精神、以党的自我革命引领伟大社会革命的锻造之路。列宁指出:“无产阶级在争取政权的斗争中,除了组织,没有别的武器。”把曾经“一盘散沙”的中国凝聚起来,不能不依靠有理想、有纪律的马克思主义政党;为宏伟的目标、艰巨的任务而奋斗,不能不保持党的先进性和纯洁性、创造力和战斗力。古田会议、遵义会议、延安整风、“两个务必”、伟大工程和新的伟大工程……每到重大关头,党都指引着前进的方向、担当起历史的责任,坚持真理、修正错误,带领人民翻过一座又一座山,夺取一个又一个胜利。党的十八大以来,以习近平同志为核心的党中央坚持党对一切工作的领导,以自我革命精神推进全面从严治党,以党的革命性锻造引领新的伟大斗争。“打铁必须自身硬。”新时代共产党人用决心和勇气夯实了事业常青之基,用行动回答了跳出“历史周期率”的世纪之问!
2021年3月,俄罗斯联邦共产党中央委员会主席根纳季·久加诺夫在《真理报》撰文指出:“中国共产党的经验证明,20世纪末社会主义的失利,并不是各种反共产主义者喜欢说的‘乌托邦社会主义计划的失败’……在中共领导下,中国人民有能力应对时代的一切挑战,沿着建设新时代中国特色社会主义的正确道路前进”。
中国用铁一般的事实宣告:历史没有终结也不会终结,社会主义生机蓬勃、前途无限!中国特色社会主义道路不但走得对、走得通,而且必将通往更加光明的未来!
(二)
马克思主义为人间带回真理的火种,但它并没有结束真理,而是开启了真理之书的扉页。中国,以鲜活厚重的理论创新、思想创造,在科学社会主义这部巨著里写下了属于自己的不朽篇章。
——坚守:中国从未背离科学社会主义基本原则
马克思、恩格斯曾对未来社会主义社会的发展过程、发展方向、一般特征作过科学预测和设想。比如,在生产资料公有制基础上组织生产,满足全体社会成员的需要是社会主义生产的根本目的;对社会生产进行有计划的指导和调节,实行等量劳动领取等量产品的按劳分配原则;合乎自然规律地改造和利用自然……这些构成了科学社会主义基本原则。
百年峥嵘岁月,无论弱小还是强大,无论处于高潮还是遭遇挫折,中国共产党从未动摇对科学社会主义基本原则的坚持。我们坚持党的领导;坚持人民民主专政的国体和人民代表大会制度的政体;坚持劳动光荣、按劳分配的社会主义分配原则;坚持把人的价值放在第一位,不断促进人的全面发展和社会全面进步……这些都在新的历史条件下体现了科学社会主义基本原则,赓续了社会主义的基因血脉。
——发展:中国不断推进马克思主义中国化
“马克思的整个世界观不是教义,而是方法。它提供的不是现成的教条,而是进一步研究的出发点和供这种研究使用的方法。”只有发展马克思主义,才能坚持马克思主义,这就是历史的辩证法。
百年风雨兼程,中国共产党始终高举真理的旗帜、进行理论的创造,坚持解放思想和实事求是相统一、培元固本和守正创新相统一,不断推进马克思主义基本原理同中国实际相结合,产生了毛泽东思想、邓小平理论、“三个代表”重要思想、科学发展观等重大理论创新成果,不断丰富和发展中国化的马克思主义,用与时俱进的科学理论回答了“中国向何处去、社会主义向何处去”的历史课题、时代之问。这些深深扎根于中国大地的思想成果,深刻影响着国家民族的前途命运,极大改变着中国人民的精神面貌,社会主义参天大树在世界东方根深叶茂。
——领航:引领中国、影响世界的当代中国马克思主义、21世纪马克思主义
“哲学把无产阶级作为自己的物质武器。同样,无产阶级也把哲学作为自己的精神武器。”从现实的此岸通向梦想的彼岸,从必然王国通向自由王国,必定依靠揭示客观规律、洞察历史大势、回应时代呼声的科学理论。
百年大江奔流,在中华民族伟大复兴的关键时期,在当今世界动荡变革的历史变局之中,中国共产党人凭着历史的积淀、理想的坚守、开拓的勇毅,紧紧围绕新时代坚持和发展什么样的中国特色社会主义、怎样坚持和发展中国特色社会主义,推进实践的新革命、思想的新长征,结出了饱含中国精神、时代精华的硕果——习近平新时代中国特色社会主义思想。
“中国共产党领导是中国特色社会主义最本质的特征”“坚持以人民为中心的发展思想”“推动全体人民共同富裕取得更为明显的实质性进展”“充分发挥市场在资源配置中的决定性作用,更好发挥政府作用”“坚持创新、协调、绿色、开放、共享的发展理念”“绿水青山就是金山银山”“推动构建人类命运共同体”……这些富有创见的思想、观点和论断,对马克思主义作出了原创性、时代性贡献,开拓了中国特色社会主义的新境界。
新时代中国共产党人赋予马克思主义以鲜明的中国特色、民族特色、时代特色,使人们对共产党执政规律、社会主义建设规律、人类社会发展规律的认识达到了一个新的历史高度,使科学社会主义释放出具有强大说服力、感召力的真理光芒!
(三)
从莫尔笔下的“乌托邦”,到康帕内拉书中的“太阳城”,从摩莱里苦心写就的《自然法典》,到欧文身体力行的“新和谐公社”,从只存在了72天的巴黎公社,到世界上第一个社会主义国家苏联,人类对社会主义社会和制度形态的探索从未停止。中国在社会主义道路上的制度探索和实践,成就了经济快速发展和社会长期稳定“两大奇迹”。
中国共产党一经成立,就把建立体现社会主义原则的制度作为追求。无论是互助合作运动还是工农兵代表大会制度,无论是“三三制”还是“豆选法”,这些在革命根据地的早期实践,都蕴含着社会主义的制度因素和价值理念,为建立新型国家制度积累了宝贵经验。
新中国成立后,我们及时把成功的实践经验转化为制度成果,使我国国家制度既体现科学社会主义基本原则,又符合中国的特殊国情。社会主义公有制、人民代表大会制度、中国共产党领导的多党合作和政治协商制度、民族区域自治制度等一系列制度逐步建立健全。
习近平总书记深刻指出:“制度问题更带有根本性、全局性、稳定性、长期性。”“只有扎根本国土壤、汲取充沛养分的制度,才最可靠、也最管用。”
进入新时代,我们聚焦坚持和完善中国特色社会主义制度、推进国家治理体系和治理能力现代化,在实践探索的基础上加强顶层设计和战略安排,党和国家制度建设“施工图”恢弘展开。从党的领导、人民代表大会、坚持马克思主义在意识形态领域指导地位、党对人民军队的绝对领导等根本制度,到社会主义基本经济制度、基本政治制度,再到不同领域具有创新性、支撑性的重要制度,中国特色社会主义制度体系层次分明、系统完备,各项制度更加成熟、更加定型,在国家治理中日益显现出巨大的制度效能。
危机是制度的试金石。面对百年不遇的新冠肺炎疫情,党领导人民不惜一切代价阻断疫情传播链条,不惜一切代价抢救生命,仅用3个月左右的时间取得了武汉保卫战、湖北保卫战的决定性成果,以最快速度研制出安全有效的疫苗,在压力巨大的情况下确保了经济发展、社会稳定,并为世界各国抗击疫情提供了有力支持。中国速度、中国奇迹的背后,是人民至上、生命至上的社会主义价值理念,是同舟共济、集中力量办大事的制度优越性,是心系世界人民安危福祉的国际主义精神!
德国政治家埃贡·克伦茨这样评价:中国应对这场全球性危机的方式方法,展示了社会主义的制度优势。资本主义世界的旧药方已经不受欢迎,重心正在发生偏移。阿根廷学者马塞洛·罗德里格斯这样写道:这场危机再次凸显了两种理念之争,一种是资本主义,将所有社会关系都商品化,倡导消费主义、个人主义、剥削和社会达尔文主义;另一种是社会主义,倡导健康、教育、文化等不是市场上可交易的商品,而是人民的权利。
在中国特色社会主义制度下,中国人民享受着前所未有的民主、自由和人权,感受着前所未有的获得感、幸福感、安全感。中国制度和治理体系是党和人民历尽千辛万苦、付出巨大代价取得的伟大成就,矗立起人类制度文明和政治文明发展史上的一座丰碑!
(四)
“文化自信是一个国家、一个民族发展中更基本、更深沉、更持久的力量。”源自于源远流长的中华优秀传统文化,熔铸于党领导人民创造的革命文化和社会主义先进文化,植根于中国特色社会主义伟大实践……历经百年,中国特色社会主义文化已经融入在中国共产党的精神血脉,时刻形塑着亿万中国人的精神气质。
悠远的文明传承是她的基因。今年3月22日,正在福建考察的习近平总书记来到朱熹园,语重心长地指出:“如果没有中华五千年文明,哪里有什么中国特色?如果不是中国特色,哪有我们今天这么成功的中国特色社会主义道路?”五千年文明的薪火相传、生生不息,赋予了我们党百折不挠的顽强与坚韧;中华文化特有的气质和禀赋,赋予了我们党质朴刚健、艰苦奋斗的宝贵品格;华夏先人对天下大同的追求向往,赋予了我们党心系苍生、天下为公的博大胸襟。凝结着人类思想精华的马克思主义,激活了古老的华夏文明;历史上唯一一个从未中断的伟大文明,又为马克思主义在中国的发展注入丰富的养分和深厚的动力。
威武不屈的革命精神是她的本色。在一百年来党领导人民开天辟地、改天换地、翻天覆地的进程中,不但书写了足以彪炳史册的伟大功绩,而且铸就了可歌可泣、光照千秋的伟大精神。上海兴业路的石库门,嘉兴南湖的红船,井冈山麓的八角楼,长征路上的大渡桥,大庆油田第一口油井,戈壁深处的“两弹一星”科研基地,深圳的莲花山,荆江大堤的抗洪纪念碑,汶川地震后建成的新城,旧貌换新颜的湘西十八洞村……这些早已不只是闻名中外的地理标识,更已成为中华民族不甘落后、拼搏奋斗的精神图腾。每当风雨来袭,每当挑战来临,中国人民都在精神之旅中坚定信心、鼓足勇气,凝聚起众志成城、一往无前的磅礴伟力。
社会主义不但要提高物质生产力、也要提高精神生产力,实现现代化一个重要目标就是建成社会主义文化强国。新时代的中国,党的创新理论深入人心,社会主义核心价值观广为弘扬,文化体制改革扎实推进,文化事业、产业蓬勃发展,文明之花处处绽放。《我和我的祖国》《我和我的家乡》等电影诉说着家国的情怀,《觉醒年代》《跨过鸭绿江》《山海情》等电视剧拨动着人民的心弦,《不忘初心》《天耀中华》《沂蒙山》《大地颂歌》等主题作品传扬着时代的旋律,更有那一支支乌兰牧骑活跃在边疆草原,一支支文艺志愿小分队扎根在工厂田间,一部部作品走出国门、走向世界……这一切,构成了激荡人心的时代协奏、感动世界的中国交响。
这是人民蓬勃向上的中国,这是文化繁盛绚丽的中国。中国特色社会主义文化,成为新时代中国屹立于世界民族之林的精神支柱,成为中华民族为人类贡献的文明瑰宝!
五百年来,人类追求社会主义的路途上,有鲜花芬芳,也有荆棘密布。一百年来,中国人追求社会主义的历程中,闪耀着光荣和梦想,也充满着奋斗和牺牲,伟大的中国共产党和英雄的中国人民从未退却、从未动摇。历史雄辩地证明:中国没有辜负社会主义!
面向未来,中国必将为人类文明进步、为世界社会主义发展作出更大贡献,让这个正义而充满前途的事业迸发出更加夺目的光芒!
转载自:新华网
原文链接:
]]>去年的此时,在家里迎来了 WWDC20,升级了 iOS 14、iPadOS 14 和 watchOS 7。不得不说,14 的更新幅度确实很大,有很多令人惊喜的功能,当时宣布的 Apple Silicon 也更是充满期待。当时使用的 Hackintosh 仍在 macOS Catalina,并不支持 Big Sur。后来添加了设备 MacBook Air,很喜欢 Big Sur 的新界面,很多地方做了半透明化,像是打通了边界,除了很丑的方形图标。
今年充满期待地迎接 WWDC21,但说实话远没有去年那么多惊喜。但还是想记录一下使用了一天的体验。官方的新功能就不过多列举了,只记录我自己的想法,会持续更新。
总体来看,感觉 Apple 对这次升级准备的很少,很多地方显得很突兀、不和谐,而且官网的中文介绍暂时还没有出,macOS Monterey 中新的特性很少。
型号名称:iPhone XR
感觉弧度也变大了,很不适应,感觉更丑了,以前统一的好看。
很多地方都开始采用卡片式布局,造成了左右的留白。
输入法选中的字符增加了白色底框,很明显。
新增「专注」功能,整合了勿扰模式和睡眠模式,而且支持增加新的模式。
感觉很鸡肋,设置新模式略显繁琐,勿扰+睡眠已经足够了。
备忘录增强,新增快速备忘录、标签等功能,界面微调,准备替代 macOS 上的「便笺」,同时也可以作为笔记 app 使用。
升级后多了一个「放大镜」app,对于 iPhone 这放大倍数,无用。
iMessage、FaceTime 增强,无用。
屏幕小组件的字体变细了。
天气 app 增强,个人非常喜欢的点:动画效果增多、描述更详细(更智能)、10 日天气预报增加了温度条、最下方天气情况变大变好看。很遗憾的点:城市间切换的动画没有了,猜测可能是动画变多导致衔接情况变多,还没完全解决,期待后续版本能完善切换动画;空气质量地图虽然没用,但是不准确,图形会重复铺满,以至于很丑很卡顿,不如不要。
Safari 升级:iPhone 端的有点反直觉,刷新网页虽然可以下拉实现,但是变麻烦了;为了展示更多网页内容去掉了很多按钮,目前很不适应。
以前明明也可以全面屏显示,不懂为什么要改变。
很多地方的模糊透明的程度有变化。
钱包 app 升级,添加交通卡可以选择其他国家或地区。
十分期待钱包 app 可以自由绑定 NFC,希望 16 可以。
App Store 的“正在载入”字体变小,应该是 bug。
升级后校园网需要重新认证(mac 地址不会变吧(?)),不知道什么原因。
app 请求位置服务时左上角变为蓝色圆圈白色标识。
通知摘要功能一样鸡肋。
闹钟的时间选择转盘回来了,不错。
有时分隔线会和上面文本框的底线重合,等待修复。
照片 app 增强,可以显示图片信息,编辑图片时字体更改。
测试版发热、耗电略显严重。
流畅度提升!
相比于 Beta 1,更新后熟悉的流畅感回来了。Beta 1 是真的卡卡卡。
流畅度提升!
「天气」中“周”改成了“星期”,导致显示不全……
基本没更新。
型号名称:iPad(第 6 代)
增加了「健身」app,但没什么用。
macOS Big Sur 还没用多久,软件厂商还没全适配,又更新。
和 Catalina 到 Big Sur 相比,Big Sur 到 Monterey 的更新幅度太小了,以至于图标壁纸都是直接改的 Big Sur。Big Sur 至少还有很多壁纸,但是 Monterey 就一张。
触发角设置时,Big Sur 的壁纸忘记换成 Monterey 的了。
最直观的感受,菜单栏的透明度似乎调整了,变好看了。也有可能是新壁纸更好看。
Safari 增强,支持标签页组,这个功能不错,很好用。重新排列的 Safari 可以显示更多内容,很好。部分动画效果更新,很好。
但是博客顶部的彩虹效果在新版 Safari 中没有了,等待解决。Safari 中字体有问题。
AirPlay 终于有用了。以前就觉得为什么 iPhone 不能用屏幕镜像功能投屏到 mac,现在终于打通了。
目前存在 bug:mac 端结束屏幕镜像后鼠标指针消失。
Universal Control 很好,但目前还不能用。
访达边栏增加「共享」文件夹,显示共享的文件。
系统扩展需要重新设置,部分兼容 Big Sur 的软件不能兼容 Monterey,本来不兼容 Big Sur 的软件应该更不能兼容 Monterey。
降级更新:Safari 变回了原来的样子,甚至更难看了:
笑死,直接打脸自己。
使用了这么长时间,感觉 Monterey 刚更新的 Safari 标签栏确实不太好用,恢复到原来的样子也是情理之中,但是加大标签页栏的宽度只是把原来的方形变成卡片式,只能说是很丑,且没有意义,毫不实用。
致命 bug:Xcode 无法连接模拟器……直接回到 Big Sur。
回不去,无法降级……
Xcode 无法连接模拟器不完全解决方式:取消 Debug executable,但会导致无法打断点。
推荐文章:WWDC 这 9 个细节关键词,我想展开说说|果核 Group
]]>2021 年的 WWDC 给的功能很少,但它给的想象很多。
构造一个用户通过 socket 访问和控制远程文件的项目
开始理解的时候感觉很困难,但实际上就是一个文件操作的实验,套了一个 socket 的壳。
和 h60 类似,请确保你已经理解 h60。
先来看一下目录结构:
MyRemoteFile
远程文件类,是远程主机下的文件MyHost
远程主机,即客户端,向服务器发出操作文件的请求MyDaemon
监听类,即服务器端,接收客户端请求,直接操作文件MyDaemonConfigVo
服务器配置my_user.txt
存放用户名和口令,MyHost
登录需要Test
测试文件实际上,先配置好服务器,创建监听线程,用于响应主机的请求。然后创建远程主机,根据远程主机和路径访问并控制远程文件。
MyDaemonConfigVo
服务器配置。
在这里,服务器就是可以直接操作本地文件的一层。根据 Test
,配置项有本地文件目录、端口号和用户信息。其中用户信息可以直接在这里读文件转换为字符串列表(不用 Map)。
1 | private String root; |
然后创建对应的 setter 和 getter。
读取文件的经典方法:
1 | private List<String> readLines(String filePath) throws IOException { |
MyDaemon
监听类,服务器端,继承 Thread
。
创建时直接将服务器配置传过来,直接保存三个配置项:
SocketServer
1 | private final ServerSocket server; |
重写 run
,循环从输入流读入并用 readLine
分析(进一步直接操作本地文件):
1 |
|
其中 readLine
是自己写的,在下文和客户端放在一起叙述。
MyHost
远程主机,客户端,需要向输出流写各种操作文件的请求,在服务器那边处理,再从输入流读入服务器输出的内容。
1 | private String ip; |
远程主机需要登录,即输入 用户名\t口令
到服务器端判断:
1 | public void login() throws IOException { |
MyRemoteFile
-> MyHost
-> MyDaemon
MyRemoteFile
是远程文件类,需要一个远程主机再加上路径才能创建一个远程文件。
1 | private final MyHost host; |
根据 Test
,需要实现的功能有:
path
)实现的过程,就是远程文件调用远程主机的方法,向监听发送请求,监听对远程主机的请求作出相应,远程主机根据响应来返回值。这里服务器端(监听)和客户端(远程主机)需要遵从一个协议,即:
操作类型 | 格式 |
---|---|
登录 | “login” + username + “\t” + password |
列出子目录和文件 | “getAscDir” + path |
判断文件类型 | “type” + path |
写入文件 | “write” + path + “:” + content |
删除文件 | “delete” + path |
获取文件大小 | “length” + path |
检查文件是否存在 | “exist” + path |
为简化输出,定义方法 writeLine
:
1 | private void writeLine(String line) { |
举例:为实现登录操作,客户端需要:
1 | writeLine("login" + username + "\t" + password); |
服务器端需要:
1 | if (line.startsWith("login")) { |
如上文所叙述,服务器端始终用 readLine
方法处理所有请求:
1 | private void readLine(String line) throws IOException { |
如上文所叙述,创建一个远程文件时需要登录主机,主机登录时依照协议向服务器端写入用户名和口令。
服务器判断请求为“登录”操作,执行 checkLogin
,遍历用户信息字符串列表,存在则写出 "success"
否则 "failed"
,客户端根据服务器的响应修改 valid
状态。
远程文件类:
直接调用远程主机的方法。
1 | public MyRemoteFile[] dirByNameAsc() throws IOException, InterruptedException { |
远程主机类:
发出请求后,服务器先发来文件个数,据此创建远程文件数组;服务器再依次发来文件路径,据此创建每一个远程文件。
1 | public MyRemoteFile[] getDirByNameAsc(String path) throws IOException, InterruptedException { |
监听类:
根据请求得到文件列表,然后按照名称顺序排序,先输出文件个数再依次输出远程文件路径(远程文件根目录路径+文件名,如果是目录则再加上 /
)。
1 | private void listFiles(String filepath) { |
远程文件类:
规定一个文件如果是目录则返回 0,如果是文件则返回 1,否则返回 -1。
1 | public boolean isDirectory() throws IOException { |
远程主机类:
规定一个文件如果是目录则输出 "dir"
,如果是文件则输出 "file"
。
1 | public int getType(String path) throws IOException { |
监听类:
根据路径创建本地文件对象,判断文件类型。
1 | private void getFileType(String filepath) { |
远程文件类:
1 | public String getPathFileName() { |
远程文件类:
直接调用远程主机,传入路径和文件内容。
1 | public void writeByBytes(byte[] bytes) { |
远程主机类:
根据字节数组创建字符串。
1 | public void writeByBytes(String path, byte[] bytes) { |
监听类:
根据格式分离路径和文件内容,文件不存在则新建文件,然后通过文件输出流输出文件内容。
1 | private void writeFile(String pathAndContent) throws IOException { |
远程文件类:
直接调用远程主机。
1 | public void delete() { |
远程主机类:
按照格式发送请求。
1 | public void delete(String path) { |
监听类:
由于客户端没有读取操作,这里也不能输出。
file.delete()
是有返回值的。
1 | private void delete(String filepath) { |
远程文件类:
直接调用远程主机。
1 | public int length() throws IOException { |
远程主机类:
按照格式发送请求,将返回的字符串转换为数字。
1 | public int getLength(String path) throws IOException { |
监听类:
根据路径新建文件,若存在则输出文件大小(转换为字符串),否则输出 "0"
。
1 | private void getLength(String filepath) { |
远程文件类:
直接调用远程主机。
1 | public boolean exists() throws IOException { |
远程主机类:
按照格式发送请求,对服务器输出的结果进行判断。
1 | public boolean isExist(String path) throws IOException { |
监听类:
新建文件,判断是否在本地存在。
1 | private void isExist(String filepath) { |