<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>秋码分享</title><link>https://qiucode.cn/</link><description>Recent content on 秋码分享</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 25 Feb 2026 16:37:43 +0800</lastBuildDate><atom:link href="https://qiucode.cn/index.xml" rel="self" type="application/rss+xml"/><item><title>一套由 Hugo 驱动的博客主题 hugo-theme-kiwi 开源啦</title><link>https://qiucode.cn/article/185/</link><pubDate>Sun, 24 Dec 2023 23:27:17 +0800</pubDate><guid>https://qiucode.cn/article/185/</guid><description>自 秋码记录 没再为云服务器续费那会儿起，便选用了由Hugo驱动的博客主题，来迁移秋码记录 上的所有文章，然而，在众多Hugo博客主题之列，竟找不出一套属于自己想要的风格的主题，故而，也只能暂且套用了一个还算可以的博客主题。
那套没有秋码记录 博客风格的主题，终究是会被替换的，一切都只是时间问题。可没想到的是，暂时选用那套博客主题，竟然暂时了这么久，这一搁就是好几个月了。还记得，秋码记录 云服务器到期是在 6 月 20 日，那是一个盛夏的季节，可如今呢，却是一个寒冬腊月、冷风凌冽、大雪纷飞的残冬时节，我不禁感叹，时间真的过的好快啊！快的让人喘不过气来。
其实，一套拥有 秋码记录 风格的主题，早已在云服务器到期之际，便应运而生了，可为什么一直拖到现如今呢？想必这也是您想问的吧！拖本不是我的本意，奈何有其他事傍身，无暇他顾，故而一拖再拖，拖到这寒冬腊月，窝在室内，身披被子，势必也要写出它来。
hugo-theme-kiwi 名字的缘故 说出来不怕您笑话，我很喜欢吃猕猴桃（也可以叫奇异果），而kiwi便是奇异果的英文，所以就将这套具有 秋码记录 博客风格的主题称为 hugo-theme-kiwi了。
或许您会问，那为什么不叫qiyiguo或mihoutao，也不是不可以，只是个名称而已嘛！何必那么讲究呢！只要自己欢喜，那么起什么样的名称，又有什么关系呢！还管业内人士怎么说，说这个太 low了，然而，我们又何必去在乎那些所谓的”技术专家“呢！说这个不符合命名规范，我们不要去在意别人怎么说，人生苦短，何必将自己束缚的那么紧绷呢！我们应该摒弃掉人生当中的各种条条框框。
扯多了，还是回到为何将这套主题叫hugo-theme-kiwi呢？其实，起初，我本想将这套主题叫hugo-theme-qiucode，然而，这个想法也只在我脑中停留了几秒钟，像是一阵轻风拂过，吹乱了头发，然而，下一秒，我却及时的将头发捋好，仿佛那阵风并为吹过一般。
也许是因为qiucode比kiwi多了几个字符吧！但还是由于qiucode太过于局限了，总抵不过kiwi来得更加宽泛，没有专为某人而设计的主题！
hugo-theme-kiwi目下拥有的功能 我们讲完了hugo-theme-kiwi名称的由来，我们也该聊聊它到底有哪些功能？当然，这些才是您浏览本文的最终目的，毕竟，一套好看的hugo主题总是那么吸引人，好比我们走在街上，忽然，迎面走来一位牵手高挑的美女，我想，那一刻，任一男人都会将目光迅速地移到那位美女身上的！当然咯，相貌与身材不及那位美女的其他女人（多是相貌平平），她们对那位美女瞬间把那条街所有男人的心给俘获了，心中难免怨恨，嘴角略微上扬，轻轻地一声“啧”，和那默契的翻白眼（或许，这才是女人与男人见到美女的所表现出的天然之别的情绪）
hugo-theme-kiwi V0.01已实现如下功能：
1、首页文章列表展示，以文章缩略图和文章摘要显示（毕竟是图文内容嘛！总得给个文章缩略图吧！）
2、是列表，那它就需要分页，而这套主题摒弃了随着滚动条触底而加载下一页数据（让人感觉有种加载不完数据）
3、文章详情页，当然，与用户交互那是必须的，所以加入了评论，也就是您可以对某篇文章进行评论。
4、文章详情页右侧，自动识别出文章目录，点击目录可以快速到达您所感兴趣的目录下阅读，减少了您宝贵的时间。
5、友情链接，用于添加拥有个人博客网站链接，虽然你我身处天南地北，但能在此处以博客会友建立了（可以称为博友）“友情”。
6、右侧侧边栏，分类和标签各自跳转到各自的页面
还未实现的功能：
1、首页文章搜索 2、时间轴 3、右侧侧边栏，分类与标签跳转页面优化 …… 今夜是平安页，您吃了苹果了吗？我衷心的祝愿您和您家人一生平安，同时，我也祈愿我和我的家人以及我身边的人一生平安！</description></item><item><title>我是如何解决将 c++ 编译成可以在 node.js 中使用的 *.node，中间出现的一大堆问题的（指纹浏览器基石篇）</title><link>https://qiucode.cn/article/246/</link><pubDate>Wed, 25 Feb 2026 16:37:43 +0800</pubDate><guid>https://qiucode.cn/article/246/</guid><description>若只是将 c++ 代码编译成某个系统下的动态链接库，或许并不会出现这么多问题，当然咯，也就不会有这篇文章的出现了。
那为什么非要将 c++ 编译成 *.node 文件呢？这是个好问题啊！其实，我在做之前，也曾思量过这个问题。
很显然，回答这个问题的答案很是宽泛。
那么，既是如此，我便开始编译 c++ 代码为 *.node 文件了。
*.gyp 文件骨架：
{ &amp;#34;targets&amp;#34;: [ { &amp;#34;target_name&amp;#34;: &amp;#34;编译后的最终名称&amp;#34;, &amp;#34;sources&amp;#34;: [ &amp;#34;c++源码文件相对路径&amp;#34;, ], &amp;#34;include_dirs&amp;#34;: [ &amp;#34;&amp;lt;!@(node -p \&amp;#34;require(&amp;#39;node-addon-api&amp;#39;).include\&amp;#34;)&amp;#34;, &amp;#34;../include&amp;#34; ], &amp;#34;defines&amp;#34;: [ &amp;#34;NAPI_CPP_EXCEPTIONS&amp;#34; ], &amp;#34;msvs_settings&amp;#34;: { &amp;#34;VCCLCompilerTool&amp;#34;: { &amp;#34;ExceptionHandling&amp;#34;: 1 } } } ] } package.json 文件：
{ &amp;#34;name&amp;#34;: &amp;#34;项目名称&amp;#34;, &amp;#34;version&amp;#34;: &amp;#34;1.0.0&amp;#34;, &amp;#34;description&amp;#34;: &amp;#34;项目描述&amp;#34;, &amp;#34;main&amp;#34;: &amp;#34;c++入口文件&amp;#34;, &amp;#34;scripts&amp;#34;: { &amp;#34;install-node&amp;#34;: &amp;#34;node-gyp rebuild&amp;#34; }, &amp;#34;dependencies&amp;#34;: { &amp;#34;node-addon-api&amp;#34;: &amp;#34;^6.1.0&amp;#34; }, &amp;#34;devDependencies&amp;#34;: { &amp;#34;node-gyp&amp;#34;: &amp;#34;^10.</description></item><item><title>eSIM Plus 爱沙尼亚手机号彻底翻车？“永久有效”悄然变成了一年！</title><link>https://qiucode.cn/article/245/</link><pubDate>Fri, 23 Jan 2026 11:37:43 +0800</pubDate><guid>https://qiucode.cn/article/245/</guid><description>相信小伙伴在接触众多 eSIM 时，定然不会错过 eSIM Plus 这款神卡，虽然它来自于小众国家，但其无限期使用终是俘获了大量用户。
然而，近段时间，有部分用户反馈，eSIM Plus已不再是“无限期”了，而是悄无声息地将用户原本地&amp;quot;无限&amp;quot;使用期限改为了为期一年。
如若只是针对新用户的话，那倒还可以说的过去。毕竟，现今eSIM竞争如此激烈，平台修改策略，应对市场变动，无可厚非。
可平台却将该策略波及到所有用户，它可不管你是老用户，还是刚刚注册的新用户，使用期限都是一年。
作为一家商业平台，在没有任何通知的情况下，悄无声息的将老用户以前购买时可无限期使用，改为了一年期限，着实不讲武德，背刺老用户。
作为先前本可以无限期使用的老用户，对该平台这种操作，很是不解。故而，与客服展开消费者权益保护的辩论。
虽然客服始终保持着敬业精神，凡是以平台策略为重。对于老用户提及的无限期怎么突然变为了一年的期限等问题，均以供应商贴错了标签来搪塞老用户。
可身为该平台的老用户，除了在该平台与客户发发牢骚，还能怎么办呢？
虽然，一切解释权归属平台所有，但当大量老用户询问客户同一问题，以此来增加客户的工作强度，迫使客户向上级领导反馈用户切实关注的问题，倒是有可能得到一些补偿。
就像前段时间的 SMS-Activate一样，刚开始，也是给出严苛的提款条件，这导致了大量用户的余额只能给该平台践行了。但总有那么一部分用户不甘心，与客户进行据理力争，最终换来了可以将余额转移到新平台的功能。
然而，这次 eSIM Plus背刺老用户，是否会因为大量用户向客服反馈同一问题诉求，平台最终会给出相应的补偿策略呢？
虽然平台总以无限期使用为噱头来吸引用户，等该平台知名度上去了，平台总会背刺老用户的！但不管是购买某某平台产品，都要以一种能使用多久就使用多久的平常心对待。</description></item><item><title>接码平台 SMS-Activate 余额可以转移到新平台使用，截止日期：2026年1月29日</title><link>https://qiucode.cn/article/244/</link><pubDate>Sun, 18 Jan 2026 21:37:43 +0800</pubDate><guid>https://qiucode.cn/article/244/</guid><description>前些天，邮箱里收到一封来自 SMS-Activate 停止运营的邮件。
当我点开这封邮件时，一下子就被震惊到了。这个看着既熟悉又陌生的平台，终究还是倒下了。
时间可追溯到三年前，也就是 2022 年 12 月 8 日，此时，正是 OpenAI再次点燃了 AI 这把火，而当时身在国内的你我，想要把玩上线不到一周便突破 100 万用户的生成式对话 AI（ChatGPT），SMS-Activate便成了大多人的`接码平台了。
OpenAI重燃 AI这把火，让全球为之狂欢至今。虽然国内呈现出百模乱战的怪象，但用户总是会在这种怪象下耗些羊毛。
也许是 AI的爆火，给SMS-Activate带来了冲击；还是竞品，分了SMS-Activate那份本该不大的蛋糕呢？没谁能说得清楚，天知道呢！
看完了邮件，便立即登录SMS-Activate平台，把余额提取出来。毕竟那封邮件说明了，提现截止日期为2026年1月29日。
可当我还是以三年前的链接进行访问SMS-Activate平台，却跳转到sms-activate.ru，不用怀疑，这就是该平台的官方域名。
然而，我满怀热情的将鼠标移入头像处，并点击它时，在头像下方弹出的下拉菜单中，点击提款文字按钮后，随后又弹出了一个modal确认框。
从确认框中可以看出，提款最低金额得是$30啊！很显然，我是不符合该提款条件。
相信大部分人也是不符合该条件吧！都是即充即用的。
既然达不到该平台的提款要求，那么还能怎么办？凉拌，就算给平台饯行吧！
若账号长时间没有登陆，会出现下图这般的提示，并由用户确认在邮件中确认账户身份信息。
打开邮件，点击确认按钮，会在浏览器新开一个标签页。
可是，却出现了神奇的一幕啊！我当时又被震惊了，难不成网络卡顿了(此刻，不禁联想到前段时间，老罗吐槽电信宽带的事情。面对网络卡顿的情况，口中呼出了一口浊气，叹了口气！)
然而，在我以为网络卡顿的同时，刷新了该链接好多次，闪现在我眼前的画面，始终如一，未曾改变！
可当我拿起水杯，喝了一口茶时，猛然间，联想到这个sms-activate.io域名DNS解析不了，难不成是sms-activate.ru。
果不其然，修改了用户确认链接后，直接跳转到该平台的首页，并弹出了一个提款资金或转移资金到新平台的modal确认框。
我这个账户，提款是不可能的了，那么就剩转移资金到新平台这条路了。
无论是提款，抑或转移资金，都需要2FA验证。关于什么是2FA验证，这里就不赘述了，毕竟不是本文的重点。
想必大伙都有过对github账户的2FA验证经验吧！
先把这个modal框关闭，去个人中心把2FA开启。
鼠标移入头像处，点击它，在出现的下拉框里，点击总览文字链接。
然而，出乎意料的一幕出现了，什么？怎么出现了404？这是怎么了？此刻，我再次被该平台给震惊到了，很是无语……
可当我去除了/cn之后，神奇的一幕又出现了！
随后，我点击了启用双因素验证按钮。
我打开了手机的验证器应用，并扫码了。
填入邮箱验证码，以及验证器临时验证码后，点击添加双因素验证按钮。
随后，便会看到我的账户已开启了双因素验证。
现在，可以回到首页了。
在弹出的modal确认框中，依次填入邮箱验证码，以及验证器临时验证码，之后便点击获取促销代码按钮。
将该促销代码复制到某个地方。
之后，我来到了由sms-activate首页提供的新平台。
目前，我这个新账户没有余额。
我点击了头像，在出现的下拉菜单中，点击Redeem Promcode文字按钮。
在弹出的modal确认框中，黏贴我刚才在sms-activate平台上获取到的促销代码，黏贴好了，就可以点击Redeem按钮，完成从SMS-Activate平台上余额转移到hero-sms.com平台上。
当我刷新hero-sms这个新平台后，看到了我这个账户余额已不再是$0了。
当我再次回到sms-activate平台时，我那个账户的余额已变回了$0。
如果，你看到了，还没有把你的SMS-Activate平台上余额进行转移，那么，请尽快转移吧！留给SMS-Activate用户的时间不多了！
若你没有SMS-Activate平台账户，那么，你就当看个热闹……</description></item><item><title>是时候将 hugo-theme-kiwi 主题提交到 themes.gohugo.io 站点上了</title><link>https://qiucode.cn/article/243/</link><pubDate>Wed, 31 Dec 2025 18:37:43 +0800</pubDate><guid>https://qiucode.cn/article/243/</guid><description>起初，在写 hugo-theme-kiwi 主题那会儿，就想着，等写完了，便提交到 themes.gohugo.io 站点上。
可这事被我一再耽搁，便拖到了这寒冬腊月，我依旧身披被子，势必要将 hugo-theme-kiwi 提交给 themes.gohugo.io 。
而此时正值跨年之夜，借此机会，祝大伙新年快乐。
然而，在这 2025 年的最后几小时里，心中难免泛起一阵酸楚。在过去的一年里，虽看似很忙碌，但实际很闲啊！最终什么事情也没完成！
好了，废话少叙，切入正题。
Fork 项目 首先，需要对 https://github.com/gohugoio/hugoThemesSiteBuilder 该项目进行 fork 到我的 github 仓库中。
而该项目，便是在 themes.gohugo.io 站点上所列出的所有开源的 hugo主题了。而若想要在 themes.gohugo.io 站点上列出你的开源 hugo主题，那便是在该开源项目进行 PR 提交了。
点击 fork 到我的 github 仓库中。
克隆刚刚 fork的项目 在 fork 项目到我的 github 仓库之后，便是在本地电脑，在电脑的任意一空闲盘符下，打开 Git Bash 黑窗口，执行以下命令，进行 clone 我刚刚 fork 过来的项目。
git clone https://github.com/zhenqicai/hugoThemesSiteBuilder #注意这里的 username 及所 fork 后的仓库名称变化 配置远程上游仓库 为了保持我的Fork与原始仓库同步，添加原始仓库为远程上游仓库：
git remote add upstream https://github.com/gohugoio/hugoThemesSiteBuilder #注意，所 fork 的远程上游仓库的 username 及仓库名称 保持我的 fork 同步 在进行修改之前，确保我刚刚 fork 是最新的。</description></item><item><title>Flux2 刚开源就凉了？Z-Image 本地部署狠狠打了个样</title><link>https://qiucode.cn/article/242/</link><pubDate>Sat, 29 Nov 2025 14:37:43 +0800</pubDate><guid>https://qiucode.cn/article/242/</guid><description>过去一周，AI 生图圈发生了两件颇具戏剧性的事情：
1️⃣ Flux2 开源了，号称第二代旗舰文生图模型。 2️⃣ Z-Image bf16 量化版悄然支持 Windows 本地部署。
结果很明显—— Flux2 开源了，社区反应平淡； Z-Image 本地部署了，几乎全网惊呼：“这是普通人能跑的旗舰模型！”
🧊 一、Flux2：开源了，却离普通用户太远 Flux2 由原 Flux 团队开发，本身技术能力不容置疑，但其开源策略与用户实际能力产生了巨大的落差：
显存要求：最低 48GB，旗舰配置 80GB 本地部署成本：Linux + 高端 GPU + 一堆依赖 出图速度：即使在 48GB 显卡上，单张也可能耗时 10–60 秒 对绝大多数普通创作者来说：
“你开源得再好，我也跑不动。”
社区吐槽如潮：
“开源个寂寞” “我连下载都点了，但我知道我跑不动” “这不是给用户开源，这是给科研实验室开源” 一句话总结：Flux2 开源了，但没人能真正用起来。
🔥 二、Z-Image bf16：企业实力 + 技术优化，让本地生图触手可及 与此同时，另一边出现了一个实力派选手：
Z-Image bf16 本地量化版，由 Alibaba.com 集团旗下 Tongyi Labs 开发，依托企业级技术与科研实力，通过 bf16 量化 优化模型大小和显存占用，实现 Windows 本地 16GB 显卡可用。
当我们第一次在 RTX 4060 上部署成功时，显存监控跳出：
12.7GB</description></item><item><title>声音的未来：Chatterbox —— 用「夸张度旋钮」提升表现力的开源 TTS 向导</title><link>https://qiucode.cn/article/241/</link><pubDate>Thu, 04 Sep 2025 20:37:43 +0800</pubDate><guid>https://qiucode.cn/article/241/</guid><description>在开源 TTS（文本转语音）界，情感控制一直是科研与实际应用追求的目标。然而，当 Resemble AI 提出的 Chatterbox 宣称自己是「第一个支持情感夸张控制的开源 TTS 模型」时，我们该如何审视这项说法的准确性，又该如何展现它真正的创新所在？
一、情感控制：开源 TTS 项目的竞争图谱 实际上，在 Chatterbox 之前，已有多个开源项目在“情感控制”层面做出了重要探索：
EmoSphere-TTS（INTERSPEECH 2024 官方实现） 通过在三维情感空间（arousal, valence, dominance）基础上引入“球面情感向量”，支持连续的 情绪风格 + 强度控制，精细度和自然表现力都值得称道。GitHubarXiv EmotiVoice（网易有道，2024） 提供离线开源引擎，支持中文和英文，可使用情绪标签（如“开心”“激动”“悲伤”“愤怒”）控制语调与情绪表达。GitHub 其他探索类工具和基础组件 包含 Coqui TTS、ESPnet TTS、Mozilla TTS 等框架，它们支持通过调节音高、音量、速度等参数来生成情绪化语音。Reddit 最新研究成果 包括 EmoVoice（LLM + 自然语言情绪提示控制）、EmoSteer-TTS（训练自由的激活引导方式）、EmoMix（情绪混合与强度调控）、EmoKnob（克隆 + 情绪细致调控）等研究，为开源情感 TTS 系带来更多可能。arXiv+3arXiv+3arXiv+3 结论：Chatterbox 并非历史上第一个拥有情感控制能力的开源 TTS。但它的情绪“夸张度”滑块是一种独特且易用的控制方式。
二、Chatterbox 的真正卖点：更直观、更生产力 1. 「情感夸张度（emotion exaggeration）旋钮」 Chatterbox 将复杂的情绪表现提取为一个用户可调节的单参数滑块，从「冷静」到「夸张」，让用户更容易定制。（官网与 README 均强调该功能）GitHubchatterbox.run 2. 面向生产的用户体验 安装简便：支持 pip，一行代码启动。 实时化：延迟低于 200ms，适合在线服务、互动式应用。Resemble AIchatterbox.run 3. 零样本语音克隆 + 多语言支持 支持仅用少量参考音进行克隆，无需训练即可生成个性化声音。 官方页面提及支持“23+”语言，让它更适配全球多语内容生成。Resemble AI 4. 水印保障：PerTh 隐形音频水印 嵌入人耳不易察觉但可精确检测的水印，支持追责与内容溯源，即使经过压缩剪辑也能识别。chatterbox.</description></item><item><title>还以为那只是换个背景？Qwen-Image-Edit 在 ComfyUI 中能做到更离谱的事</title><link>https://qiucode.cn/article/240/</link><pubDate>Wed, 20 Aug 2025 18:37:43 +0800</pubDate><guid>https://qiucode.cn/article/240/</guid><description>阿里巴巴 通义千问团队发布并开源了 Qwen-Image-Edit 图像编辑大模型，它是基于 20B 的 Qwen-Image 模型进一步训练，成功将 Qwen-Image 的文本渲染特色能力拓展到编辑任务上，以支持精准的文字编辑。此外，Qwen-Image-Edit 将输入图像同时输入到 Qwen2.5-VL（获取视觉语义控制）和 VAE Encoder（获得视觉外观控制），以同时获得语义/外观双重编辑能力。
精准文字编辑: Qwen-Image-Edit 支持中英双语文字编辑，可以在保留文字大小/字体/风格的前提下，直接编辑图片中文字，进行增删改。 语义/外观 双重编辑: Qwen-Image-Edit 不仅支持 low-level 的视觉外观编辑（例如风格迁移，增删改等），也支持 high-level 的视觉语义编辑（例如 IP 制作，物体旋转等） 强大的跨基准性能表现: 在多个公开基准测试中的评估表明，Qwen-Image-Edit 在编辑任务中均获得 SOTA，是一个强大的图像生成基础模型。 下载模型 对于国内的朋友，可以在国内镜像下载 Qwen-Image-Edit 模型： https://hf-mirror.com/Comfy-Org/Qwen-Image-Edit_ComfyUI/tree/main/split_files/diffusion_models
LoRA
Qwen-Image-Lightning-4steps-V1.0.safetensors Text encoder
qwen_2.5_vl_7b_fp8_scaled.safetensors VAE
qwen_image_vae.safetensors 等以上模型都下载完成后，按以下存放路径，拖入到 Comfyui 对应的文件夹内。
📂 ComfyUI/ ├── 📂 models/ │ ├── 📂 diffusion_models/ │ │ └── qwen_image_edit_fp8_e4m3fn.safetensors │ ├── 📂 loras/ │ │ └── Qwen-Image-Lightning-4steps-V1.0.safetensors │ ├── 📂 vae/ │ │ └── qwen_image_vae.</description></item><item><title>Windows 结合最新版 ComfyUI 部署阿里最新开源的 Qwen-Image 图像大模型</title><link>https://qiucode.cn/article/239/</link><pubDate>Thu, 14 Aug 2025 19:42:43 +0800</pubDate><guid>https://qiucode.cn/article/239/</guid><description>引言 曾几何时，当 Stable Diffusion 文生图开源后，输入一段文本便能生成图片，而惊艳之时。能否在图片写入中文，而不再是乱码，苦求各种解决方案，而不得其一二，多半还是那么强差人意。
然而，阿里巴巴千问团队震撼开源的 Qwen-Image ，这款模型不仅精准渲染中文文本，还能智能编辑图像，堪称AI绘画界的&amp;quot;全能选手&amp;quot;！
那么，接下来，就和我一起在 Windows下基于最新版的 ComfyUI ，来部署 Qwen-Image 工作流。
安装 ComfyUI 或更新它 若你还没安装过 ComfyUI，那么你可以先进入 ComfyUI 官网，下载它。
ComfyUI 官网地址：https://www.comfy.org/zh-cn/
假使你跟我一样，之前在电脑下载过 ComfyUI，那么，只需双击 ComfyUI根路径下的 update 文件夹里的 update_comfyui_stable.bat 即可完成更新。
下载模型 目前，千问团队开放了 40B 和 20B量化版本这两种参数的模型。这里选用了 20B 量化模型。
https://huggingface.co/Comfy-Org/Qwen-Image_ComfyUI/tree/main/non_official/diffusion_models
下载好这个量化模型，还需下载编码器和 VAE。
https://comfyanonymous.github.io/ComfyUI_examples/qwen_image/
下载好了这些模型，移动到对应的文件夹。
启动 ComfyUI 加载工作流，使用示例提示词生成图片 在 ComfyUI根目录下，双击 run_nvidia_gpu.bat ,随后便会弹出一个黑窗口（ Terminal），稍待几秒后，它会自动打开你电脑默认浏览器，在一个新页签下展示 ComfyUI 的界面。
之后，将 https://comfyanonymous.github.io/ComfyUI_examples/qwen_image/ 中的图片拖入到这个页面里，即可展现在你面前的便是 Qwen-Image 工作流了。
写入 Qwen-Image 官方提示词。
宫崎骏的动漫风格。平视角拍摄，阳光下的古街热闹非凡。一个穿着青衫、手里拿着写着“阿里云”卡片的逍遥派弟子站在中间。旁边两个小孩惊讶的看着他。左边有一家店铺挂着“云存储”的牌子，里面摆放着发光的服务器机箱，门口两个侍卫守护者。右边有两家店铺，其中一家挂着“云计算”的牌子，一个穿着旗袍的美丽女子正看着里面闪闪发光的电脑屏幕；另一家店铺挂着“云模型”的牌子，门口放着一个大酒缸，上面写着“千问”，一位老板娘正在往里面倒发光的代码溶液。 虽然与官方给出的图片有些许出入，但这已经很不错了，至少在中文渲染上面，没有出现所谓的乱码。毕竟这是量化版本。
Qwen-Image官方示例提示词：https://qwenlm.github.io/blog/qwen-image/
Lora 模型加持 若你想要生成 Lora 写实风格的图片，那么只需加载 Lora 模型即可。</description></item><item><title>从零样本到跨场景：Seed-VC语音转换技术的革命性突破</title><link>https://qiucode.cn/article/238/</link><pubDate>Fri, 18 Apr 2025 22:42:43 +0800</pubDate><guid>https://qiucode.cn/article/238/</guid><description>引言：当声音克隆不再需要训练 在传统语音转换技术中，用户往往需要数小时的录音数据和复杂的模型训练才能实现声音克隆。而2024年发布的Seed-VC（Speech-to-Speech Voice Conversion）技术打破了这一范式——它通过零样本学习（Zero-Shot Learning）实现即时声音克隆，仅需1-30秒的参考音频即可完成音色复制，甚至支持实时转换和歌声生成 。这项技术不仅在学术界引发关注，更在娱乐、影视、教育等领域掀起应用浪潮。
技术解析：Seed-VC的核心创新 零样本学习的实现原理 Seed-VC基于上下文学习（Contextual Learning）和深度神经网络，通过以下流程完成声音克隆： 特征提取：从源语音和目标语音中提取音高、音色、韵律等关键特征 特征编码：利用XLSR或Whisper模型将声音编码为中间表示 扩散模型生成：采用HiFT或BigVGAN声码器合成高质量语音波形，支持25-100步的扩散过程平衡速度与质量这种架构无需预训练特定音色模型，真正实现“即插即用” 突破性功能：实时与歌声转换 300ms实时处理：通过优化算法延迟和设备侧处理，支持在线会议、直播等场景的即时变声 歌声合成黑科技：将说话语音转换为歌声时，保留原音色特征并自动调整音高，解决传统SVC技术中音色失真问题 性能优势 在客观评估中，Seed-VC在语音清晰度（PESQ 4.32）和相似度（SIM 0.89）上显著超越OpenVoice、CosyVoice等模型，甚至优于部分需训练的模型（如So-VITS 4.0） 应用场景：声音的无限可能 影视与娱乐 为动画角色快速生成定制音色（如用30秒明星语音生成角色配音） 直播中实时切换音色，创造虚拟主播的多样化声线 音乐创作 将未受过声乐训练者的语音转换为专业级歌声，支持半音调校以适配背景音乐 案例演示：用户通过剪映分离背景音后，用Seed-VC将干声转换为数字人演唱版本 教育与医疗 语言学习中模拟不同口音发音，例如中文方言到标准普通话的即时转换。 为失声患者复刻个性化语音，保留情感表达特征。 实践指南：如何快速上手 部署方式
小白友好型：通过Hugging Face的Gradio网页界面直接上传音频 开发者模式：命令行工具支持参数微调，如设置扩散步数（--diffusion-steps）控制生成质量。 模型选择建议
模型版本 适用场景 延迟 参数量 seed-uvit-tat-xlsr-tiny 实时语音转换 &amp;lt;400ms 25M seed-uvit-whisper-base 高保真歌声合成 1-2s 200M 进阶技巧
使用--semi-tone-shift调整音高适配歌曲调性 开启auto-f0-adjust自动对齐说话与歌唱音高 行业影响与未来展望 Seed-VC的出现标志着语音合成技术从“专用模型”向“通用基座”的转型。其自定义微调功能（每位说话人仅需1条语音）让个性化声音克隆门槛大幅降低 。据预测，到2030年，语音转换市场将突破10亿美元，而零样本技术将成为主流 。
Seed-VC不仅是一项技术突破，更是一场关于声音表达的革命。它让每个人都能低成本拥有“声音分身”，重新定义了创作、沟通与身份表达的边界。正如开发者所言：“我们的目标是让任何声音都能被自由塑造，就像文字一样。”
本地部署 我依旧使用python3自带的venv模块来构建python虚拟环境。
python -m venv seed-vc-v2-env cd seed-vc-v2-env/Scripts activate 之后，我们克隆Seed-VC推理代码。
git clone https://github.com/Plachtaa/seed-vc.git 安装与你电脑CUDA版本匹配的torch。</description></item><item><title>大语音模型轻量化革命：MegaTTS3 如何重新定义文本生成语音的技术边界（windows篇）</title><link>https://qiucode.cn/article/237/</link><pubDate>Thu, 10 Apr 2025 23:02:43 +0800</pubDate><guid>https://qiucode.cn/article/237/</guid><description>传统语音合成技术受限于高昂的数据需求和庞大的模型参数规模，难以实现个性化语音的实时生成。而字节跳动与浙江大学联合推出的 MegaTTS3，以其 0.45亿参数轻量级架构 和 零样本语音克隆 能力，打破了这一僵局。作为首个完全开源的高效语音生成模型，MegaTTS3 不仅支持中英双语无缝切换，还能通过短短几秒的音频样本克隆音色，甚至灵活调整口音强度，堪称语音合成领域的“瑞士军刀”
架构解析：扩散模型与Transformer的协同创新 MegaTTS3 的核心架构融合了 扩散模型（Diffusion Model） 与 Transformer 的优势，通过模块化设计实现语音属性的精准解耦与控制。其技术亮点包括：
多模态信息解耦 内容、音色、韵律分离建模：借鉴前作Mega-TTS2的研究成果，MegaTTS3 将语音分解为内容（文本语义）、音色（说话人特征）和韵律（语调节奏）三个独立维度，并通过多参考音色编码器（MRTE）和韵律语言模型（PLM）分别优化，显著提升克隆语音的自然度。 自回归时长模型（ADM）：动态捕捉语音节奏变化，确保长句合成的连贯性。 轻量化扩散Transformer主干 采用TTS Diffusion Transformer架构，仅0.45亿参数即可实现与数十亿参数模型相媲美的生成质量。通过混合专家（MoE）设计，模型仅激活部分参数，大幅降低推理资源消耗。 高效训练策略 基于38k小时中英文混合数据训练，结合轻量级监督微调（SFT）和直接偏好优化（DPO），在保证质量的同时提升训练效率。 技术新亮点：不止于“克隆” 零样本语音克隆的突破 仅需3-5秒的参考音频，即可实时生成与目标说话人音色高度相似的语音，无需微调。这一能力得益于其音色编码器的跨说话人泛化能力，支持从儿童到老人、不同语种的多样化音色捕捉。 口音强度可控的语音生成 用户可通过调节参数生成带有特定口音的语音（如“带粤语腔调的普通话”），为虚拟角色赋予地域特色或个性化表达。 中英混合朗读与语音修复 支持同一段文本中中英文自然切换，解决传统模型在双语混合场景下的生硬断句问题。同时，模型可自动修复含噪声或低质量的输入音频，提升鲁棒性。 CPU环境下的高效推理 模型体积仅数百MB，支持在无GPU的本地设备（如普通PC或手机）上实时生成语音，打破硬件限制。 本地部署 首先我们得下载anaconda或miniconda这款用于python虚拟环境管理软件。也许，你有所纳闷，我一贯使用python3自带的venv模块来搭建python虚拟环境，可为什么这次却使用miniconda了呢？
究其原因，是因为MegaTTS3依赖了pynini，而这个依赖库却对windows系统并不是那么的友好，换句话说，若使用python3自带的venv模块来构建的虚拟环境，大概率是安装不了pynini这个依赖库了。
安装miniconda 在安装miniconda时，需将它的安装路径添加到环境变量（PATH）中。
clone MegaTTS3推理代码 我们把MegaTTS3的推理代码给clone到本地。
https://github.com/bytedance/MegaTTS3
使用miniconda创建虚拟环境 我们打开一个Terminal，输入以下命令来搭建一个用于MegaTTS3的虚拟环境：
conda create -n megatts3-env 等它创建初始化成功后，我们继续输入以下命令来激活刚刚创建好的虚拟环境。
conda activate megatts3-env 安装依赖 安装pynini==2.1.5 我们cd到刚刚clone MegaTTS3推理代码的目录下，安装pynini==2.1.5。
安装 WeTextProcessing==1.0.3 这个依赖库就是MegaTTS3所必须的，而它又依赖了我们上面刚刚安装的pynini。这就是为什么使用venv模块创建的虚拟环境安装不了pynini依赖库的原因了，前提是在windows系统下噢。
pip install WeTextProcessing==1.0.3 安装MegaTTS3推理代码所需的依赖库 在安装MegaTTS3推理代码的依赖库之前，我们得修改requirements.txt文件，将WeTextProcessing==1.0.41这一行给删除了，你问了，那就回答你，至于为什么删除它，那是我们刚刚不安装了吗！
删除了WeTextProcessing==1.0.41这一行后，保存并关闭requirsments.txt文件。随后在Terminal输入以下命令：
pip install -r requirements.txt 设置MegaTTS3虚拟环境的环境变量 至于为什么要设置，若你这么问了，具体的我也回答不上来了，详情请浏览我的博客：秋码记录</description></item><item><title>竞赛级编程大模型OlympicCoder-7B之本地部署（Windows篇）</title><link>https://qiucode.cn/article/236/</link><pubDate>Tue, 01 Apr 2025 23:02:43 +0800</pubDate><guid>https://qiucode.cn/article/236/</guid><description>一、核心定位与技术亮点 竞赛级代码推理能力 OlympicCoder-7B 针对编程竞赛（如国际信息学奥林匹克竞赛 IOI）需求设计，通过 CodeForces-CoTs 数据集（包含 10 万高质量思维链样本）进行训练，覆盖 C++ 和 Python 语言的算法实现。该模型在 IOI 挑战赛中表现出色，生成代码的通过率和效率显著优于同规模模型 。
真实竞赛场景优化 模型模拟了竞赛中的提交策略优化机制，例如在严格的时限内生成代码并通过测试用例验证，确保生成结果的正确性和效率。其训练数据整合了 CodeForces、DeepMind CodeContests 等竞赛平台的问题及官方解题思路，强化了算法逻辑的精准性 。
轻量化与高效部署 作为 7B 参数量的模型，OlympicCoder-7B 在保证性能的同时降低了硬件门槛，可在消费级 GPU 上运行，适合开发者和教育机构本地化部署。量化版本（如 Q4_K_M）内存占用仅约 5GB，生成速度可达 45 tokens/s 。
二、性能对比与实测表现 算法竞赛任务 在 CodeForces 和 IOI 题型测试中，OlympicCoder-7B 的代码生成准确率接近 32B 版本（如 OlympicCoder-32B），且在贪吃蛇游戏等复杂编程任务中生成代码的可执行性显著优于同规模模型 。
跨模型对比 与同属代码生成领域的 aiXcoder-7B（北大开源）相比，OlympicCoder-7B 在竞赛题目上的表现更优，但 aiXcoder 在长上下文补全（支持 32k 上下文）和企业级开发场景中更具优势 。而与 Magicoder-7B（UIUC/清华联合开发）相比，OlympicCoder 更专注于算法优化而非通用代码生成 。
三、应用场景与局限性 适用场景 算法竞赛训练：为选手提供代码思路和解题参考。 编程教育工具：辅助学生理解复杂算法实现逻辑。 自动化评测系统：生成测试用例或验证代码正确性。 局限性 领域专注性：在通用软件开发场景（如 Web 开发）中表现不及专用模型。 数据时效性：需定期更新竞赛题库以保持模型对最新题型的适应能力。 四、本地部署 首先，我们使用python3自带的venv模块来搭建python 虚拟环境。当然，你也可以使用anaconda或者miniconda来构建python 虚拟环境。</description></item><item><title>阿里开源了端到端全模态大模型Qwen-2.5-Omini-7B之本地部署（windows篇）</title><link>https://qiucode.cn/article/235/</link><pubDate>Fri, 28 Mar 2025 22:02:43 +0800</pubDate><guid>https://qiucode.cn/article/235/</guid><description>阿里千问团队开源了到端全模态大模型Qwen-2.5-Omini-7B，一时之间，炸燃了AI界。
而这次千问团队开源的Qwen-2.5-Omini-7B，可谓是将看、听、读及写集于一身的全能型的大模型。
Thinker-Talker双核架构 Thinker模块：统一处理文本、图像、音频、视频输入，通过多模态编码器提取特征并生成语义理解结果。 Talker模块：基于双轨Transformer解码器，实时生成文本与自然语音响应，支持4种拟人化音色切换。 创新技术： TMRoPE时间对齐算法：实现音视频输入的毫秒级同步对齐，视频推理准确率提升3.1%。 FlashAttention-2加速：降低显存占用并提升推理速度，支持8K分辨率图像输入。 全模态统一处理能力 支持文本、图像、音频、视频的端到端输入与输出，无需分模块处理。 实测性能： OmniBench基准测试：综合得分56.13%，超越Gemini 1.5-Pro（42.91%）。 语音合成自然度：Seed-tts-eval评分0.88，接近人类水平。 本地部署 虽然官方给出了最小GPU内存需求，但如果我们不是去分析（Analysis）视频的话，还是在8G显存下把玩的，当然咯，也是可以使用量化版本。
精度 15(s) 音频 30(s) 音频 60(s) 音频 FP32 93.56 GB 不推荐 不推荐 BF16 31.11 GB 41.85 GB 60.19 GB pip uninstall transformers pip install git+https://github.com/huggingface/transformers@3a1ead0aabed473eafe527915eea8c197d424356 pip install accelerate 你得先创建python虚拟环境，可以使用anaconda或miniconda。而我始终使用的是python3自带的venv模块来构建python虚拟环境。
安装qwen-omni-utils这个工具类库。
pip install qwen-omni-utils 由于这个依赖默认安装的是CPU版的torch，所以，我们得先卸载它，而后安装CUDA版本的torch。
pip uninstall torch pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124 我们身处国内，使用modelscope来下载模型，故而，需安装它。
pip install modelscope 推理模型 我们新建一个python文件，输入以下脚本，以实现语音识别的功能。
from qwen_omni_utils import process_mm_info import torch #from transformers import Qwen2_5OmniModel, Qwen2_5OmniProcessor from modelscope import Qwen2_5OmniModel, Qwen2_5OmniProcessor from qwen_omni_utils import process_mm_info model_path = &amp;#34;Qwen/Qwen2.</description></item><item><title>语音识别之whisper本地部署（实时语音之开篇）</title><link>https://qiucode.cn/article/234/</link><pubDate>Tue, 25 Mar 2025 22:02:43 +0800</pubDate><guid>https://qiucode.cn/article/234/</guid><description>Whisper是由OpenAI开发的开源语音识别模型，以其多语言支持、高准确率与鲁棒性著称。它通过68万小时的多语言、多任务数据训练，覆盖100+语言，支持语音转录、翻译和语言检测，成为目前最通用的语音识别工具之一。
其核心优势在于：
端到端训练：直接处理原始音频输入，无需复杂预处理，输出包含标点符号的完整文本。 噪声鲁棒性：在嘈杂环境、方言口音场景下仍能保持高精度。 多任务能力：支持语音翻译（如中文转英文）、时间戳标注等复杂任务。 本地安装 我始终使用python3自带的venv来搭建python虚拟环境，当然咯，你也是可以使用anaconda或miniconda来构建python虚拟环境。
python -m venv whisper-env cd whisper-env/Scripts activate 随后，我们安装openai-whisper这个依赖库。
pip install -U openai-whisper 或者直接从github.com仓库获取最新的。
# 或从 GitHub 安装最新版本 pip install git+https://github.com/openai/whisper.git 我们可以看到，所安装的依赖库中包含了tiktoken，故而，就不需要在安装了。
虽然，whisper是可以通过CPU来推理的，但是在电脑设备具有GPU的情况，还是选择torch的CUDA版本。
pip uninstall torch pip install torch --index-url https://download.pytorch.org/whl/cu124 之后，新建一个demo.py文件，写入以下脚本。
import whisper model = whisper.load_model(&amp;#34;turbo&amp;#34;) result = model.transcribe(&amp;#34;audio.wav&amp;#34;) print(result[&amp;#34;text&amp;#34;]) 首次运行，会去下载模型，而我使用的是turbo，所以自动下载的便是large-v3-turbo。
如果自动下载失败了，那么就手动下载吧。
模型默认加载路径：C:\Users\你电脑的用户名\.cache\whisper
https://www.modelscope.cn/models/iic/Whisper-large-v3-turbo/files</description></item><item><title>甭管是个人还是企业都能部署的Mistral-Small3.1，远超同级别的模型</title><link>https://qiucode.cn/article/233/</link><pubDate>Wed, 19 Mar 2025 22:06:43 +0800</pubDate><guid>https://qiucode.cn/article/233/</guid><description>这不Gemma3刚开源出来，立马炸裂了整个“科技界”，还没等它把“热度”持续火下去，Mistral-Small3.1却再次掀起了“科技界”的热度。
Mistral-Small3.1是Mistral AI推出的240亿参数开源多模态模型，基于Transformer架构优化设计，核心特性包括：
多模态支持：支持文本与图像结合的任务处理，扩展了应用场景边界。 128k超长上下文窗口：可一次性处理长篇文档或复杂对话，显著优于前代的32k窗口。 高效推理引擎：采用量化技术优化推理速度，每秒处理150个token，延迟低至毫秒级，适合实时交互场景。 本地化部署能力：支持在RTX 4090显卡或32GB内存的Windows设备上运行，通过Ollama等工具实现轻量化部署. 通过Ollama部署 那么，接下来，我们在本地通过Ollama来部署Mistral-Small3.1。
如果你还没安装Ollama的话，那么，你可以去它的官网进行下载安装，Ollama官网。
我这里选择了量化版，根据自己电脑的硬件设备来下载对应的量化版本。
拷贝命令，直接黏贴到Terminal中。
ollama run MHKetbi/Mistral-Small3.1-24B-Instruct-2503:q6_K_L 主要特性和功能 轻量级：Mistral Small 3.1 可以在单个 RTX 4090 或具有 32GB RAM 的 Mac 上运行。这使其非常适合设备上的使用情况。 快速响应对话帮助：非常适合虚拟助手和其他需要快速、准确响应的应用程序。 低延迟函数调用：能够在自动化或代理工作流程中快速执行函数 针对专业领域进行微调：Mistral Small 3.1 可以针对特定领域进行微调，打造精准的主题专家。这在法律咨询、医疗诊断和技术支持等领域尤其有用。 高级推理的基础：社区在开放的 Mistral 模型之上构建模型的方式继续给留下深刻印象。仅在过去几周，就看到了几个基于 Mistral Small 3 构建的出色推理模型，例如Nous Research 的DeepHermes 24B。为此，发布了 Mistral Small 3.1 的基础和指令检查点，以便进一步对模型进行下游定制。 如果你本地电脑硬件资源有限的话，那么是可以前往Mistral 官方平台上使用，上面是满血版【点击前往】</description></item><item><title>文生音乐开源项目DiffRhythm，8G显存本地部署之Windows篇</title><link>https://qiucode.cn/article/232/</link><pubDate>Sat, 15 Mar 2025 22:06:43 +0800</pubDate><guid>https://qiucode.cn/article/232/</guid><description>一、DiffRhythm：颠覆音乐创作的AI黑科技 DiffRhythm是由西北工业大学音频语音与语言处理实验室（ASLP@NPU）与香港中文大学（深圳）联合开发的开源音乐生成模型，其采用全扩散架构，能够在10秒内生成4分45秒的高质量双轨立体声音乐（包含人声与伴奏） 。该模型以非自回归结构实现极速推理，支持纯文字风格描述生成音乐（如&amp;quot;Jazzy Nightclub Vibe&amp;quot;或&amp;quot;Arctic research station, theremin auroras&amp;quot;等创意场景） ，且最低仅需8GB显存即可本地部署。
技术亮点：
端到端生成：无需多阶段拼接，直接输出完整歌曲； 句级歌词对齐：通过音素映射实现人声与歌词精准同步； 压缩鲁棒VAE：支持从MP3等压缩格式还原无损音质； 多模态输入：兼容文本提示、参考音频、歌词等多类型输入。 本地部署 我电脑依旧是使用python 3.10.9，而仍然使用python3自带的venv模块来搭建python 虚拟环境。
当然咯，你也非得要跟我一样，你也可以使用python 3.11.X、python 3.12.x，用anaconda或miniconda来构建python 虚拟环境，这一点，并没有什么特定要求。
创建python 虚拟环境 你可以在电脑任一磁盘较为宽裕，来构建一个python 虚拟环境。
下载DiffRhythm推理代码 你得确保你的电脑安装好了git，否则的话，将无法通过以下命令进行clone DiffRhythm推理代码。
至于这么安装git工具，就不在这里进行赘述了，毕竟我前几篇文章是有讲解过的。
git clone https://github.com/ASLP-lab/DiffRhythm.git cd DiffRhythm 安装espeak-ng DiffRhythm生成的音乐包含人声演唱的歌词，这需要将文本歌词转化为音素序列（如国际音标IPA），并精确映射到音频的时间轴上。eSpeak-NG作为开源音素合成引擎，在此环节发挥关键作用：
音素解析：将用户输入的歌词（如中文、英文）转换为标准音素表示，例如中文你好 →/ni haʊ/，确保模型理解发音规则。 发音规则库支持：eSpeak-NG内置100+语言的音素规则库，能够处理多语言歌词混合场景（如中英双语歌曲），避免发音错误。 对齐算法依赖：DiffRhythm通过句子级对齐机制，将音素序列映射到潜在表示的特定位置，确保生成的歌声与歌词在时间轴上严格同步。eSpeak-NG提供底层音素时间戳数据支撑这一过程。 我们直接下载espeak-NG官方编译好的安装包，https://github.com/espeak-ng/espeak-ng/releases。
双击刚刚下载的espeak-ng.msi,一路Next下去就好了。
还需将espeak-ng安装路径添加到PATH环境变量中。
安装项目所需的依赖 这一步是必不可少的，毕竟现代的项目都是集成项目，换句话说，一个大项目或多或少需要去集成优秀的框架及工具库等。
pip install -r requirements.txt 在国内，我们还是先设置一个国内镜像源，以便下载依赖库能够加快些，毕竟，pypi.org在国内访问起来真是一言难尽啊，就更别说再去pypi.org下载什么依赖库了。
下载模型 我们可以通过HuggingFace.co的国内镜像站hf-mirror.com进行下载模型。
DiffRhythm-base模型地址：https://hf-mirror.com/ASLP-lab/DiffRhythm-base/tree/main
我们仍然是通过git工具来下载模型，所以，你的电脑得提前安装好git，是很有必要的。
git clone https://hf-mirror.com/ASLP-lab/DiffRhythm-base ASLP-lab/DiffRhythm-base 运行python infer/infer.py 当模型下载完成了之后，这时，我们便可以通过以下命令，来生成音乐了。
python infer/infer.py --lrc-path infer/example/eg_cn.lrc --ref-audio-path infer/example/eg_cn.wav --audio-length 95 --repo_id ASLP-lab/DiffRhythm-base --output-dir infer/example/output --chunked 倘若，你运行了上述命令后，也出现了与下图一样的错误。</description></item><item><title>阿里QwQ-32B本地部署指南：用Ollama轻松运行320亿参数大模型</title><link>https://qiucode.cn/article/231/</link><pubDate>Thu, 13 Mar 2025 20:26:43 +0800</pubDate><guid>https://qiucode.cn/article/231/</guid><description>在本地电脑硬件条件有限情况下，只能部署些参数小点的模型，虽然很多平台也提供了免登录，可以在线把玩满血版的DeepSeek。
可我们总是寄望于国内外的这些大厂，能够训练出一个参数小点，且又能比肩DeepSeek满血版。
这不，阿里推出了一款可以媲美DeepSeek满血版（671B）的小参数模型——QwQ-32B。
QwQ-32B一经发布，激起了千层浪，可谓是：QwQ-32B小钢炮撼动了DeepSeek满血版的“江湖地位”。
甭管是QwQ团队的测评结果，还是来自“民间”的吹捧。最终，我们总得自己亲身部署了，方知这款小钢炮是否真的能比肩DeepSeek满血版呢？
下载Ollama 访问Ollama官网下载Windows安装包 双击执行安装程序，保持默认配置（注意C盘空间） 验证安装：CMD输入 ollama -v 显示版本号即成功。 下载模型 访问QwQ-32B模型页
你得先设置好你的网络，否则是下载不下来的。
安装 page assist 浏览器扩展 首先，我对国内很多人把浏览器扩展说成了浏览器插件，这是错误的，真正的浏览器插件是什么？那是可以改变浏览器内核的一套组件，而不是只修改网页上的内容。
并且，google也都是叫extension（扩展），而插件（plugin）。
可能是我本地模型“串”了。</description></item><item><title>基于Qwen2.5大模型的Spark-TTS，零样本语音克隆，CPU可运行之本地部署（Windows篇）</title><link>https://qiucode.cn/article/230/</link><pubDate>Mon, 10 Mar 2025 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/230/</guid><description>在人工智能时代，语音合成（TTS）技术已成为人机交互的核心组件之一。然而，传统TTS系统长期受限于多阶段架构复杂、语音控制能力弱、跨语言表现差等问题。
基于Qwen2.5大模型的**Spark-TTS**横空出世，凭借其创新的BiCodec编码技术、零样本语音克隆能力和细粒度语音控制，迅速成为开源社区的热点。
技术突破：Spark-TTS的三大创新 1、BiCodec：重新定义语音编码 Spark-TTS首创BiCodec单流语音编码器，将语音分解为两类核心编码：
语义Tokens：低比特率捕捉语言内容，确保信息的高效传输。 全局Tokens：固定长度编码说话人属性（音色、性别、语调等）。 这种设计简化了传统TTS的多模型协作流程，实现端到端生成，推理速度提升30%以上 2、零样本语音克隆：无需训练，秒级复刻
仅需3秒参考音频，Spark-TTS即可生成高度相似的个性化语音，音色一致性（SIM）指标超越同类模型如LLaMA-TTS。其核心在于结合Qwen2.5的语言理解能力与BiCodec的解码精度，突破了传统TTS依赖大量训练数据的限制。
3、细粒度语音控制：从参数到情感的精准调节
粗粒度：性别、情感风格一键切换。 细粒度：音高、语速、停顿时长可逐句微调。 用户甚至可通过文本描述生成虚拟音色（如“沉稳的中年男声，语速加快20%”），远超传统基于参考音频的模拟方式。 功能实测：性能与效果全解析 多语言与跨语种切换 Spark-TTS支持中英文无缝切换，无需单独训练语言模型。例如，输入混合文本“2025年Q1财报增长15%”，合成语音能自然处理数字与语言边界，避免传统TTS的机械断句问题 。
语音质量指标
自然度（MOS）：评分&amp;gt;4.5（满分5），接近真人水平。
重建质量：在STOI、PESQ等指标上超越VITS、FastSpeech2等主流模型。
实时性（RTF）
：单GPU推理速度达0.15秒/秒，满足实时交互需求。
实战对比：与其他开源TTS的差异 数据来源：公开评测与社区实测
项目 零样本克隆 多语言支持 细粒度控制 推理速度 Spark-TTS ✅ 中英 ✅ 快 CosyVoice2 ✅ 中英 ❌ 中等 Fish-Speech ❌ 中英日 ❌ 慢 本地部署 那么接下来，我们将在本地电脑部署这款开源的文本转语音模型，看看效果是否真如官方所宣传的那般。
我还是一如既往的使用python3自带的venv模块来创建python 虚拟环境，当然，你也是可以使用anaconda或着miniconda等软件来搭建python 虚拟环境。
我本地电脑使用python的版本，始终是python 3.10.9，系统则是windows11。
创建python虚拟环境 python -m venv Spark-TTS-env cd Spark-TTS-env/Scripts activate clone推理代码 Spark-TTS的推理代码托管于享誉全球的github.com上，倘若你的电脑安装了git，那么直接在Terminal中执行以下命令，便把Spark-TTS推理代码下载到你的电脑硬盘里。
git clone https://github.com/SparkAudio/Spark-TTS.git 安装项目所需的依赖 pip install -r requirements.txt 安装CUDA版的torch（可选） 这一步是可选的，项目是可以通过CPU来推理的，也就是刚刚安装的torch是CPU版的，如果你想要使用GPU来加速推理，那么，就先卸载CPU版的torch，安装支持GPU的torch。</description></item><item><title>智谱开源了文生图CogView4-6B模型，支持中文提示词之本地部署（Windows篇）</title><link>https://qiucode.cn/article/229/</link><pubDate>Fri, 07 Mar 2025 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/229/</guid><description>在文生图这个领域里，甭管是开源的Stable Diffusion 3.5，还是闭源的在线绘图平台Midjourney，一度都是不支持中文提示词。
连prompt都不支持中文，就别提想要在图中写入中文。
虽然SD3.5、Midjourney等优秀绘画模型不支持中文提示词，但国内各大厂商一直致力于中文提示词。
CogView4-6B是智谱AI（Zhipu AI）推出的文生图模型，通过结合文本与图像的跨模态生成技术，在中文场景下展现出显著优势。
本地部署 那么，接下来，我们就在本地电脑部署下CogView4-6B这款开源的绘画模型，看看效果是否真有其官方宣传的那么好。
创建虚拟环境 首先，我们创建个python虚拟环境，你可以使用anaconda或miniconda来创建虚拟环境。我还是使用python3自带的venv模块搭建的虚拟环境。
我电脑使用的python版本为python 3.10.9，当然你也可以使用python 3.11。
python -m venv CogView4-env cd CogView4-env\Scripts activate clone 推理代码及下载模型 git clone https://github.com/THUDM/CogView4 cd CogView4 # 根据自身网络条件 选择以下任一方式来下载模型。 # modelscope git clone https://www.modelscope.cn/ZhipuAI/CogView4-6B.git # Huggingface.co git clone https://huggingface.co/THUDM/CogView4-6B 安装项目所需依赖 其实，如果按照官方的，也就是执行以下这行命令，是无法启动项目的。
pip install -r inference/requirements.txt 按照requirements.txt的依赖来安装torch是CPU版本，并不支持GPU，所以我们需要uninstall这个不带GPU版本的torch以及torchao。
如果你电脑的显存低于12G的话，那么需要设置set MODE=1。
然而，在Terminal下载torch的CUDA版本，下载速度总是那么不尽如人意。
那么，我们可以直接去https://download.pytorch.org/whl/torch 下载 对应的whl文件。
我们直接在Terminal直接pip install torch-xxx.whl。
卸载CPU版的torchao，安装带有CUDA版本的torchao。
运行 inference/gradio_web_demo.py 当我们安装好了CUDA版的torch和torchao后，再次执行python inference/gradio_web_demo.py。
会为我们自动在默认浏览器打开一个页签，如下图。
我这里使用了官方的prompt，只是把Happy New Year改成了新春快乐，看看是不是能真正的写上中文字。
为了出图快点，我只修改了图片的width和height，其他都是默认的，然而，生成的图片，图中的中文文字却崩了。</description></item><item><title>基于歌词生成整首歌的开源AI音乐模型，支持中、英、日、韩等多种语言，本地化部署YuE（windows篇）</title><link>https://qiucode.cn/article/228/</link><pubDate>Wed, 05 Mar 2025 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/228/</guid><description>说起文生音乐，我们自然会想到suno.ai这个音乐生成式平台，它算是目前市面上音乐生成式比较好的AI项目，虽然它是闭源的。
然而，一款由Multimodal Art Projection(M-A-P)（多模态艺术投影）团队与香港科技大学（HKUST）联合研发的YuE开源了，它是根据歌词生成整首歌的开源AI音乐模型。
YuE的开源，着实在开发者社区掀起了一阵热潮，但也给了AI浪潮中的文生音乐助推了不小波澜。
YuE 是一系列开创性的开源基础模型，专为音乐生成而设计，专门用于将歌词转换成完整的歌曲（lyrics2song）。它可以生成一首完整的歌曲，持续几分钟，包括朗朗上口的声乐曲目和伴奏曲目。YuE 能够模拟多种流派/语言/声乐技巧。请访问演示页面，了解令人惊叹的声乐表演。
概述 YuE项目地址：https://github.com/multimodal-art-projection/YuE 。
按照官方描述：
YuE 需要大量 GPU 来生成长序列。以下是推荐的配置：
对于具有 24GB 或更少的 GPU：运行最多 2 个会话以避免内存不足 (OOM) 错误。
对于完整的歌曲生成（许多会话，例如 4 个或更多）：使用具有至少 80GB 的 GPU。即 H800、A100 或具有张量并行的多个 RTX4090。
要自定义会话数，界面允许您指定所需的会话数。默认情况下，模型运行 2 个会话（1 节 + 1 合唱）以避免 OOM 问题。
在 H800 GPU 上，生成 30 秒的音频需要 150 秒。在 RTX 4090 GPU 上，生成 30 秒的音频大约需要 360 秒。
社区提供了对于 GPU 资源有限的人，有 YuE-exllamav2 和 YuEGP。虽然两者都提高了生成速度和连贯性，但它们可能会损害音乐性。
YuEGP github地址：https://github.com/deepbeepmeep/YuEGP 。
YuE-exllamav2 github地址： https://github.com/sgsdxzy/YuE-exllamav2。</description></item><item><title>阿里云开源的文生视频万相 Wan2.1之本地部署Wan2.1-T2V-1.3B模型</title><link>https://qiucode.cn/article/227/</link><pubDate>Sat, 01 Mar 2025 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/227/</guid><description>概述 阿里云开源了其视频生成大模型Wan2.1（万相）,采用了较为宽松的Apache2.0协议。
而这次对外了1.3B（极速版）和14B（专业版）两个参数规格的权重，及推理的全部代码。
这两种模型均支持文生视频（T2V）和图生视频（I2V）任务。
14B版本在权威评测集VBench中以86.22%总分超越Sora、Luma等国内外模型；1.3B版本可在消费级显卡运行（仅需8.2GB显存生成480P视频），适合二次开发和研究。
复杂运动生成：精准模拟人物旋转、跳跃、翻滚等动作，支持高级运镜控制 物理规律建模：真实还原碰撞、反弹、切割等场景，符合现实物理规则 中英文指令理解：支持长文本指令，实现场景切换、角色互动和多语言文字特效 技术原理 架构设计 因果3D VAE：专为视频设计的变分自编码器，高效压缩时空信息并保持生成连贯性 视频Diffusion Transformer（DiT）：结合扩散模型和Transformer，逐步去噪生成视频，捕捉长时程依赖关系 分布式训练优化：采用DP、FSDP、RingAttention等混合并行策略，加速训练与推理 性能提升技术 引入插件式增强块（如Enhance-A-Video），通过跨帧注意力调节提升时序一致性，减少画面模糊和跳帧问题 本地部署 我电脑的环境：
python：3.10.9
CUDA：12.4
windows11
我们还是一如既往的先创建python虚拟环境，我这里使用的是python3自带的venv来搭建虚拟环境，当然咯，你也是可以使用anaconda或miniconda来创建虚拟环境。
python -m venv Wan2.1-env cd Scripts activate 随后，我们clone万相的推理代码。
git clone https://github.com/Wan-Video/Wan2.1.git cd Wan2.1 项目依赖库安装 之后我们安装torch&amp;gt;=2.4.0，这是官方所要求的。
pip install torch torchvision --index-url https://download.pytorch.org/whl/cu124 再者我们安装项目的requirements.txt依赖文件时，发现有flash-attention这个依赖，它可是可以加速推理的一个框架。
然而，它对windows可并那么友好啊。但是flash-attention社区还是有人编译出了windows的wheel，也省的我们自己去编译了。
为此，我特意将CUDA toolkit从12.1升级到12.4，关于这一点，是可以从我前几篇的文章看出来的。
https://github.com/kingbri1/flash-attention/releases 将下载下来的wheel直接通过pip install进行安装。
pip install flash_attn-2.7.4.post1+cu124torch2.6.0cxx11abiFALSE-cp310-cp310-win_amd64.whl 至此，我们再来执行以下命令，来完成安装项目所需的依赖库。
pip install -r requirements.txt 下载模型 我们通过modelscope来下载模型。
pip install modelscope 我这里下载的是Wan-AI/Wan2.1-T2V-1.3B，若你要下载14B的模型，只需将1.3B换成14B即可（前提是你电脑的硬件环境允许的条件下）。
modelscope download Wan-AI/Wan2.1-T2V-1.3B --local_dir ./Wan2.1-T2V-1.3B 模型 下载链接 备注 T2V-14B 🤗 Huggingface 🤖 ModelScope 支持 480P 和 720P I2V-14B-720P 🤗 Huggingface 🤖 ModelScope 支持 720P I2V-14B-480P 🤗 Huggingface 🤖 ModelScope 支持 480P T2V-1.</description></item><item><title>互动式开源AI图像编辑神器，Windows11本地部署 MagicQuill</title><link>https://qiucode.cn/article/226/</link><pubDate>Tue, 25 Feb 2025 22:26:43 +0800</pubDate><guid>https://qiucode.cn/article/226/</guid><description>曾几何时，我们想要对图片进行PS，那可是难为了我们这般PS门外汉。
然而，MagicQuill这款开源的图像元素修改，可算是解救了我们这些PS小白啊。
那么，现在我们就可以在自己电脑部署这款开源的图像编辑神器。
但想要在本地电脑部署这款开源的AI图像编辑神器，你的电脑显存要大于12G（虽然官方说是8G），预留硬盘空间在40G（模型就有30G），CUDA版本得在12.1或更高。
创建 python 虚拟环境 创建python虚拟环境是为了每个项目，库依赖各自隔离，不受影响。
我电脑python使用的版本是3.10.9，使用python自带的venv来创建虚拟环境，当然咯，你也可以使用anaconda或miniconda来创建虚拟环境。
随后，我们激活刚刚创建好的虚拟环境。
python -m venv MagicQuill-env cd MagicQuill-env/Scripts activate clone MagicQuil 项目代码 git clone --recursive https://github.com/magic-quill/MagicQuill.git cd MagicQuill 安装支持GPU的 torch 依赖 至于版本，那是官方的READMD.md中提到的，使用了阿里云镜像，能加速torch在国内的下载。
pip install torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 -f https://mirrors.aliyun.com/pytorch-wheels/cu121 安装 MagicQuill 支持 gradio 依赖 这个位于项目根路径下，我们直接pip install这个wheel文件即可。
pip install gradio_magicquill-0.0.1-py3-none-any.whl 安装 llava 依赖 这个llava也是包含在项目中的。
首先，我们需要将项目根路径下的pyproject.toml复制到MagicQuill\LLaVA\。
随后，安装llava依赖。
copy /Y pyproject.toml MagicQuill\LLaVA\ pip install -e MagicQuill\LLaVA\ 7、安装项目必须依赖。
安装项目必须依赖 pip install -r requirements.txt 下载模型 模型大小总共29.9GB，所以电脑硬盘得预留出这么大的空间出来。
国内可直接：https://hkustconnect-my.sharepoint.com/:u:/g/personal/zliucz_connect_ust_hk/EWlGF0WfawJIrJ1Hn85_-3gB0MtwImAnYeWXuleVQcukMg?e=Gcjugg&amp;amp;download=1</description></item><item><title>本地部署Qwen2.5-VL-7B-Instruct多模态视觉大模型（Windows篇）</title><link>https://qiucode.cn/article/225/</link><pubDate>Sun, 23 Feb 2025 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/225/</guid><description>Qwen2.5-VL是阿里云推出的开源多模态大模型，支持图像理解、视频分析、文档结构化处理等功能。
较上一个版本Qwen2-VL有质的飞越，Qwen2.5-VL通过动态分辨率适配和窗口注意力机制，显著降低显存占用并提升推理速度，72B模型在单卡A100上推理速度提升30% 。
身在AI这股浪潮中，只要本地电脑硬件条件允许的话，我都会尝试着去部署优秀的开源大模型。
说到开源大模型，相对而言的就是闭源大模型，我们在脑海中很自然地浮现出国外的OPENAI，以及国内的百度，也就是李彦宏所说的“开源大模型，对个人是没有好处”（好像是这么说的吧）。
由于DeepSeek的冲击，据说百度将要开源大模型了，这李彦宏不是妥妥的打了自己的脸了吗？很想隔空问李彦宏一句话，难道你的脸不痛吗？
克隆Qwen2.5-VL代码及安装必须依赖 git clone https://github.com/QwenLM/Qwen2.5-VL.git 使用Python3自带的venv库，创建虚拟环境。当然你也可以使用anaconda或miniconda工具进行创建python虚拟环境。
python -m venv qwen-vl-env cd qwen-vl-env\Script activate 之后回到Qwen2.5-VL代码的根路径下，进行必须依赖安装。
cd Qwen2.5-VL pip install -r requirements_web_demo.txt 当然，为了可以使用GPU来推理，还需安装与你的CUDA版本匹配的pytorch
pip install torch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 --index-url https://download.pytorch.org/whl/cu121 其实pytorch依赖是包含在requirements_web_demo.txt文件中，那是CPU版本的。
而对于windows用户来说，以下这步也是多余的。
pip install qwen-vl-utils 下载模型 Qwen2.5-VL开源三个不同参数的大模型，分别是3B、7B、72B。
Huggingface模型地址：https://huggingface.co/collections/Qwen/qwen25-vl-6795ffac22b334a837c0f9a5
Modelscope魔塔社区：https://modelscope.cn/collections/Qwen25-VL-58fbb5d31f1d47
运行官方的gradio demo示例 可不知是什么原因，我运行python web_demo_mm.py却出现错误，报的错误都是与gradio相关的错误信息，致使我一度怀疑，是不是需要更新gradio的依赖呢。
然而，事与愿违，报错还是一如既往报错，它可不会因为你更新了gradio依赖，就停止报错了。
所以呢，我就运行官方不带gradio的示例，结果却成功，这让我异常兴奋。
import torch from modelscope import snapshot_download from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor from qwen_vl_utils import process_vision_info # default: Load the model on the available device(s) # model = Qwen2_5_VLForConditionalGeneration.</description></item><item><title>保持角色一致性的绘本生成AI开源项目之Story-Adapter本地部署Windows篇</title><link>https://qiucode.cn/article/224/</link><pubDate>Sun, 16 Feb 2025 16:26:43 +0800</pubDate><guid>https://qiucode.cn/article/224/</guid><description>在人工智能领域，生成一致且连贯的故事绘本一直是一个具有挑战性的任务。Story-Adapter作为一个开源项目，旨在解决这一问题，为用户提供无需训练即可生成长篇故事视觉化的工具。本文将指导您如何在Windows系统上本地部署并运行Story-Adapter。
项目简介 Story-Adapter项目提出了一种无需训练的迭代框架，用于长篇故事的可视化生成，特别关注在生成过程中保持角色的一致性。通过利用现有的文本到图像生成模型，Story-Adapter能够根据输入的故事文本，生成一系列连贯且一致的图像帧，适用于绘本创作、动画制作等领域。
项目地址：https://github.com/UCSC-VLAA/story-adapter
环境准备 从项目的README.md中有关于本地安装的必要条件：
Python 3.10.14 PyTorch 2.2.2 CUDA 12.1 cuDNN 8.9.02 虽然官方是通过anaconda来创建python项目的虚拟环境，这也官方推荐的，可以说是所有开源AI 项目的友好方式。
然而我却不使用anaconda，而使用python自带创建虚拟环境的方式。
python -m venv story-adapter-env #创建 story-adapter-env 虚拟环境 cd story-adapter-env\Script activate #激活虚拟环境 1. 安装Python 前往Python官方网站下载适用于Windows的最新版本Python安装包。在安装过程中，务必勾选“Add Python to PATH”选项，以便在命令提示符中直接使用Python命令。
我安装的是python 3.10.9。
2.安装Git 访问Git for Windows下载并安装Git。安装完成后，您可以在命令提示符中使用git命令。
3.安装CUDA 如果您的计算机配备了NVIDIA GPU，并希望利用GPU加速，请前往NVIDIA官方网站下载并安装适用于您GPU型号的CUDA Toolkit。
克隆项目代码 执行以下命令以克隆Story-Adapter项目代码：
git clone https://github.com/UCSC-VLAA/story-adapter.git cd story-adapter 此操作将在当前目录下创建一个名为story-adapter的文件夹，包含项目的所有代码。
安装依赖项 pip install-r requirements.txt-i https://pypi.tuna.tsinghua.edu.cn/simpe/ 下载模型 在下载模型，请提前准备好网络（你应该懂的什么是网络吧）。
按照官方的指引来下载对应的模型，及存放的位置。
Download the checkpoint
downloading RealVisXL_V4.0 put it into &amp;ldquo;./RealVisXL_V4.0&amp;rdquo;
downloading clip_image_encoder put it into &amp;ldquo;.</description></item><item><title>本地部署 Stable Diffusion 3.5（最新 ComfyUI记录篇）</title><link>https://qiucode.cn/article/223/</link><pubDate>Mon, 03 Feb 2025 20:26:43 +0800</pubDate><guid>https://qiucode.cn/article/223/</guid><description>当你在看到文章标题，以及发布时间时，想必你是不会继续浏览下去的，这一点，是可以理解的，换做是我，也会做出同样的抉择。
既然如此，而又为什么又要写这篇文章呢？
其一，之所以没能在Stable Diffusion3.5发布时，在本地电脑部署它，那是因为彼时的老破电脑是不足以安装它的。
其二，赤巨资购买了可以把玩Machine Learning的高配电脑，这才想要在新电脑中部署Stable Diffusion3.5这个文生图大模型，故此，将本地部署过程记录下。
模型大小的区别 Stable Diffusion3.5发布三个不同参数的模型，分别是Medium、Large Turbo、Large。
Stable Diffusion 3.5 Large：该基础型号拥有 80 亿个参数，质量卓越，响应迅速，是 Stable Diffusion 系列中最强大的型号。该型号非常适合 1 百万像素分辨率的专业用例。 稳定扩散 3.5 Large Turbo：稳定扩散 3.5 Large 的精简版仅需 4 个步骤即可生成高质量图像，且具有出色的快速依从性，速度比稳定扩散 3.5 Large 快得多。 Stable Diffusion 3.5 Medium： 该模型拥有 25 亿个参数，采用改进的 MMDiT-X 架构和训练方法，可在消费级硬件上“开箱即用”，在质量和定制易用性之间取得平衡。它能够生成分辨率在 0.25 到 2 百万像素之间的图像。 可以从Hugging Face下载
Stable Diffusion 3.5 Large 【点击下载】 推荐16G以上显存
Stable Diffusion 3.5 Large Turbo 【点击下载】 推荐8G以上显存
安装 下载最新 ComfyUI 我们可以在github.com下载ComfyUI官方打包版，ComfyUI v0.3.13
当然咯，你也是可以下载源码，进行编译。
下载适合自己电脑显存的模型 在Huggingface.co下载Stable Diffusion3.</description></item><item><title>谁说Win7安装不了Node.js最新版的呢？都2025年，还不更新系统到Win11</title><link>https://qiucode.cn/article/222/</link><pubDate>Thu, 26 Dec 2024 20:26:43 +0800</pubDate><guid>https://qiucode.cn/article/222/</guid><description>近年来，Node.js作为前端开发的顶梁柱，已经被越来越多的开发者广泛使用。但不少坚持用Windows 7的朋友却发出了这样的抱怨：“Win7根本装不了最新版的Node.js！这该怎么办？” 其实，这个问题既和技术有关，也和理念有关。如果你还在用Win7，或许是时候重新思考一下升级的必要性了。本文将详细分析为什么Win7无法直接安装最新版的Node.js，并提供解决方案。
下载二进制压缩包 在win7系统下安装最新版node.js，提示最低要求Win版本是Win8.1或Server 2012，然后拒绝安装。
也是，这都2025年了，而你却还在使用早被microsoft停止维护的win7系统，你是不是该去升级下你的系统了。
然而，在某种情况下，如政府项目等，他们还在使用win7系统，他们总不可能为了迁就你，而去更新可能含有“潜在风险”的系统。
既然如此，那么该如何在win7系统下安装最新的node.js呢？
其实，win7是可以安装最新版的node.js的。
我们将下载下来的压缩包，进行解压到你想要存放的任意位置。
在cmd窗口中运行node -v，输出当前node.js的版本。
然而依旧会给出警告提示，那么，我们可以通过set NODE_SKIP_PLATFORM_CHECK=1。
之后再次输入node -v命令，便能够正常输出node版本信息了。
配置环境变量 虽然通过上述步骤，我们已然在win7系统下安装上了node.js最新版本。但你发现没node -v命令是需要在它解压路径下，换句话说，便是离开该目录，是找不到node.exe这个可执行文件的。
或许你早就想到了，那么将node.exe所在的路径添加到PATH环境变量中即可。
然而，我们还需设置set NODE_SKIP_PLATFORM_CHECK=1这个环境变量，因为这种设置只对当前cmd窗口有效，为了一劳永逸，我们也将它设置进环境变量。
而如果想要切换成其他版本，只需下载对应版本的二进制压缩包即可，配置方式同上，是不是感觉很丝滑呢！</description></item><item><title>vs code远程调试Linux服务器上的php代码</title><link>https://qiucode.cn/article/221/</link><pubDate>Thu, 19 Dec 2024 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/221/</guid><description>前言 不管是测试服务器，还是生产服务器，程序出现了问题，虽然可以根据日志来锁定问题，但从效率上来讲，总是那么不尽如人意。
虽然PHP可以在代码中通过var_dump()和dump()来调试输出，但这效率，可真是一言难尽啊。
由于Coder开发都是在本地，一番测试各个功能并没有什么问题，可一旦部署到测试服务器上，再次进行测试时，却出现了诡异的问题，也许这些问题，是你见都没见过的问题。
面对这种困惑，我们能想到的就是，能不能在本地电脑通过工具，远程调试测试服务器上的PHP代码呢？
答案当然是可以的。
VS Code安装 Remote 如果你的电脑还没有安装这款开源免费且开箱即用的IDE，那么你可以先去下载安装它。
VS Code官方下载地址：https://code.visualstudio.com/
作为一位Coder，我想你应该不至于会去国内的什么下载站进行下载李鬼版的VS Code吧，除了官方的，其他的都是盗版，如果你无知到下载了国内付费的VS Code（原先武汉就有一家公司，无耻到把VS Code开源代码套个壳，拿出来卖，什么公司忘了），那你算是给IT界丢人了。
安装 Remote-SSH 在打开的VS Code，在左侧的功能栏里，点击那个田字格的图标，搜索框中输入remote后，点开如下图所示的，点击install，安装这个插件，它就是用来远程连接的。
连接远程服务 ctrl+shift+p打开命令框输入remote ssh，或者点击左下角绿色按钮，这里没能截取全图。
首次是需要建一个配置文件。
# Read more about SSH config files: https://linux.die.net/man/5/ssh_configHost &amp;lt;给连接的服务器命名&amp;gt;HostName &amp;lt;需要连接的服务器IP&amp;gt;User &amp;lt;连接服务器的用户&amp;gt;ForwardAgent yes windows7出现的错误（非win7系统可以跳过） 选择远程服务器的系统类型，出现下图的错误，那是因为在windows7系统中没有安装SSH，当然现如今，几乎很少开发者会在windows7进行开发了。
64 位操作系统下载这个：点击下载（备用下载） 32 位操作系统下载这个：点击下载（备用下载）
将OpenSSH安装路径添加到环境变量 Path中。
使用 RSA 进行免密登录 生成公钥/密钥对 直接在VS Code中打开terminal，或者cmd打开一个黑窗口，输入以下命令。
ssh-keygen -t rsa 将公钥添加到服务器上 把公钥文件id_rsa.pub拷贝到需要登录的服务器上（存储路径可以随意，但是之后加入到另一个文件尾部的时候注意路径地址。）
将公钥id_rsa.pub填充到authorized_keys尾部。
cat /home/id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys Remote-SSH配置中添加本地秘钥文件路径 我们打开之前的Remote-SSH配置文件，在文件末尾加入以下内容。
IdentityFile &amp;lt;你本地的SSH秘钥文件路径&amp;gt; #这个非必要，通过它可以避免每次连接都要输入密码的麻烦。 最终的Remote-SSH配置文件将会是这般。</description></item><item><title>浏览器定制 | Windows11 编译 Chromium 133.0.6885.0（截稿前Chromium最新版之编译篇[一]）</title><link>https://qiucode.cn/article/220/</link><pubDate>Thu, 12 Dec 2024 21:26:43 +0800</pubDate><guid>https://qiucode.cn/article/220/</guid><description>序章回顾 其实，在此之前，我已经发表过如何在Windows下编译Chromium及前期环境准备的系列文章了。
那么，既然之前已然撰写过了，缘何又出这么一篇类似的文章呢？
倘若你看过我那几篇关于windows编译Chromium的系列文章，你或许就会明白我写这篇文章的意义了。
可假使你还没看过，也没关系，毕竟彼时windows系统版本还处于win8.1，机器很久了，光是编译，就费了两天一夜，期间CPU一直处于高负荷状态，途中不能操作任何事物，虽然到最后是编译出来。
然而，当我双击打开刚刚编译出来的chrome.exe时，却并不能打开。
花费了这么长的时间来编译，可最终却不能打开，气得我一度将out\Default删除掉，重新编译它，然而，又将是一个漫长的编译过程。
很显然，导致编译时间过长的罪魁祸首就是我的那台（为了区别于赤巨资购买了可用于把玩Mechine Learning的新笔记本）笔记本过于老旧，虽然我期间也为这台笔记本，把内存增加到了16G，可终究还是无法补救其卡顿的`悲惨命运。
新电脑拉开了新篇章 对于那台老旧电脑，若用来编译大型项目（诸如：Chromium）时，它将是有心无力、廉颇老矣，善能战否？
可即便是不去编译项目，光是打开号称宇宙界最耗内存的微信，与我弟视频，期间是不能运行其他软件，否则的话，它就直接闪退。
凡此种种缘故，也正借artificial intelligence（AI）这股强劲的风，我便有了买台新点电脑的预算。
其实，也在新电脑编译过chromium 103.0.5060.66，可最终我还是选择了编译chromium 最新版（最新版只限于截稿前），毕竟这都是高配置的电脑，何不编译最新版本呢，之前那台电脑是受到客观因素，故而编译了Chromium 103.0.5060.66这个版本。
系统要求 一台至少具有 8GB RAM 的 x86-64 计算机。强烈建议超过 16GB。 NTFS 格式的硬盘驱动器上至少有 100GB 的可用磁盘空间。FAT32 将不起作用，因为某些 Git 包文件大于 4GB。 Visual Studio 的适当版本，如下所述。 Windows 10 或更高版本 visual studio 新版Chromium 需要 Visual Studio 2022 （&amp;gt;=17.0.0） 才能构建。Visual Studio 还可用于调试 Chromium。使用 clang-cl 编译器，但需要 Visual Studio 的头文件、库和一些工具。如果 Visual Studio Community Edition 的许可证适合您，则应该可以正常工作。必须安装“使用 C++ 进行桌面开发”组件和“MFC/ATL 支持”子组件。这可以通过将这些参数传递给 Visual Studio 安装程序从命令行完成。
这跟我之前安装visual studio 2019 community一样的。对于Chromium每个版本所对应的visual studio版本要求也各不相同。</description></item><item><title>不说是彻底搞懂，至少让你不再惧怕c/c++指针，以及各种奇葩指针变种</title><link>https://qiucode.cn/article/219/</link><pubDate>Fri, 29 Nov 2024 21:46:43 +0800</pubDate><guid>https://qiucode.cn/article/219/</guid><description>经历过C/C++的Coder，说起指针，无不是摇头晃脑的。
然而，没弄懂指针，可以说是无法在C/C++世界里徜徉，毕竟指针可是C/C++的灵魂所在。
由于C/C++的Coder可以通过指针自由玩转内存，从而让外界给C/C++戴上了一顶内存不安全的语言。
相较于现代语言，诸如，Java、golang、python、PHP等这些具有垃圾回收机制的语言来说，C/C++把操控内存的主动权交给了Coder，之所以会被誉为内存不安全的语言，其最大责任便是Coder使用指针不当而引发内存崩溃。
什么是指针呢？ 对于初学者而言，到底什么是指针（pointer）呢？我们光从字面上就大抵能猜出个一二，指针，指针，无非就是一个事物指向另一个事物。
说起指针，便无法抛开内存而不谈。
我们知道数据（Data）+ 算法（algorithm）= 程序（program），那么程序的本质就是在操控数据，而内存便是存放数据（这里存放数据，不要与数据库存放的数据混淆了。）
由于变量的类型和作用域所限制，内存可分为：堆（heap）、栈（stack）、全局（global）以及静态存储（static）。
无论是C/C++，抑或是Java等其他高级语言，最终都是要编译成汇编语言，而这种语言它可不管你为变量起了个多么好听的名字，在它那里统统都转变成了内存寻址。
而指针便是存放着某一块的内存地址，可以是某个基础类型变量的地址，也可以是复合类型变量的地址，甚至还可以是指针的地址。
#include &amp;lt;iostream&amp;gt; using namespace std; int main() { int a = 10; int* ptr = &amp;amp;a; //声明一个int类型的指针，并指向变量a的地址 cout &amp;lt;&amp;lt; &amp;#34;变量 a 的地址=&amp;#34; &amp;lt;&amp;lt; &amp;amp;a &amp;lt;&amp;lt; endl; cout &amp;lt;&amp;lt; &amp;#34;指针变量 ptr 存放着变量 a 的地址=&amp;#34; &amp;lt;&amp;lt; ptr &amp;lt;&amp;lt; endl; cout &amp;lt;&amp;lt; &amp;#34;通过 * 解引用操作，间接获得变量 a 的值=&amp;#34; &amp;lt;&amp;lt; *ptr &amp;lt;&amp;lt; endl; *ptr = 15; //通过 * 解引用操作，来修改指针指向的内容。 cout &amp;lt;&amp;lt; &amp;#34;通过 * 解引用操作，间接修改变量 a 的值=&amp;#34; &amp;lt;&amp;lt; a &amp;lt;&amp;lt; endl; return 0; } 数组名就是指针 在初步了解了什么是指针的前提下，我们将继续探讨下一个话题，数组与指针到底有着怎样的联系呢？</description></item><item><title>解决windows下php8.x及以上版本，在Apache2.4中无法加载CURL扩展的问题</title><link>https://qiucode.cn/article/218/</link><pubDate>Wed, 27 Nov 2024 19:46:43 +0800</pubDate><guid>https://qiucode.cn/article/218/</guid><description>在日新月异的信息化下，软件也在跟随着互联网的脚步，逐步推进着各项计划。
近些年，各大语言像是不约而同的都在改进或优化，从而能让programmer在开发效率上有所提升，还使得软件在升级了新版本的program language加持下，运行速度和处理并发的能力得到前所未有的提升。
Java自2014年发布了新的里程碑的Java 8版本号，之后，Oracle变向外界承诺每三年发布一个LTS（Long Time Support）长期支持版本，每年的三月份和九月份都发布一个版本。然而，java社区可不管java发布了多少个新版本，他们依旧是在使用Java 8版本。
直到Java 17的发布，且Oracle更改了协议，或许是促使开发者使用Java 17 LTS，由享誉全球、Java 开发离不开的Spring framework牵头，也就是Spring framework 6.x 及以上版本必须使用Java 17、而Springboot 3.x版本及后续版本也必须是Java 17，因为Srpingboot 3.x依赖的是Spring framework 6.x。
而php5.6.x版本后，也在响应着互联网的潮流，顺应当下瞬息万变的信息化，也在改进着、优化着，或许试图挽回曾今那句PHP是世界上最好的语言！而努力奋进。
即使我们没有使用PHP新版本的特性，只要你的软件运行在新版本的PHP下，性能那跟之前的，可就没的说了。（这里说的不单单只是PHP，像Java、C/C++、Python、golang、C#等）
下载 Apache 对于php7.4及PHP 5版本而言，可以下载Apache历史版本。
Apache 历史版本链接：https://www.apachelounge.com/download/additional/ 。
我们将下载下来的压缩包进行解压，打开其根路径下的conf文件夹，用你常用的IDE编辑httpd.conf文件。
#php5 support LoadModule php5_module &amp;#34;D:/software/php-5.6.30/php5apache2_4.dll&amp;#34; AddHandler application/x-httpd-php .php # configure the path of php ini PHPIniDir &amp;#34;D:/software/php-5.6.30&amp;#34; 有时，你可能还需要开启URL重写模块。
而对于PHP7.X版本，其实是与PHP5.X配置大同小异。
#php7 support LoadModule php7_module &amp;#34;D:/software/php-7.4.8/php7apache2_4.dll&amp;#34; AddHandler application/x-httpd-php .php .html .htm #configure the path to php.ini PHPIniDir &amp;#34;D:/software/php-7.4.8&amp;#34; #startup openssl LoadFile &amp;#34;D:/software/php-7.</description></item><item><title>在 Windows8.1 下编译 Chromium （103.0.5060.68 之三）</title><link>https://qiucode.cn/article/217/</link><pubDate>Fri, 27 Sep 2024 08:26:43 +0800</pubDate><guid>https://qiucode.cn/article/217/</guid><description>说在前面的话 或许你在看到文章标题中的windows8.1，难免会让你望而却步。
谁说不是呢！毕竟按chromium官方文档要求，win8.1是达不到编译 chromium高版本的要求的。
但不管怎么样，我的win8.1电脑最终还是编译出了chromium，足以说明win8.1系统编译chromium是可行的。
虽然在编译期间，占有了电脑大量使用时间，好在我都是在白天出门前，电脑开着让它静静地build。
让我庆幸的是，在那漫长的编译过程中，竟没有因errorhuofailed而中断，就连warning也是瞧不见身影。
编译途中出现error或failed总是再所难免`的，但却平添了我们去解决该问题的时间。
下载 chromium 源码 据Chromium官方文档来看，是需要至少100G的空闲磁盘，为此，我查看电脑里的几个盘，最终还是选择了C盘，清理了很大一部分空间出来，也就是你现在看到的下图这般。
新建一个名为chromium的文件夹，名字你可以随意起，这个倒无所谓的！
chromium 官方文档是通过fetch chromium来下载代码，但是这种下载是chromium最新代码，还包括历史log，虽然可以带上--no-history参数，它终究还是拉取最新代码。
在当前文件夹内，空白地方鼠标右键，再弹出的选项列表里，选择Git Bash here，再弹出的对话框中输入以下命令。
第一种方案： git clone --depth 100 -b 103.0.5060.68 https://chromium.googlesource.com/chromium/src.git src 直接从chromium 官网拉取源码，下载的速度取决于你的网络。
第二种方案（我采取这种方案，为的是节省网络流量）： git clone --depth 100 -b 103.0.5060.68 https://gitee.com/mirrors/chromium.git src # 还原git仓库地址 cd src git remote set-url origin https://chromium.googlesource.com/chromium/src.git cd .. 参数说明：
--depth 100 意思是拉取深度为100，这将会拉取一些 log，因为编译脚本会基于仓库的 log 反查版本发布时间。如果这个值太小，可能会查不到，因而报错。所以，建议设为 100 或更大些。或者，直接去掉这个参数，但这样将拉取全部的 log，特别慢。 -b 103.0.5060.68 指定拉取的 tag 版本。 不管你采取了那种方案，在git或cmd总是要设置好网络，至于怎么设置网络，可以查看秋码记录，这里将不再赘述，毕竟后面同步第三方依赖，是必须要用到网络的！
若你的电脑安装过了git工具，可以在Git Bash，输入上述任何一种方案。
假使你电脑没安装过git，那么直接在cmd中，输入上述任何一种方案。
生成 .</description></item><item><title>安装 depot_tools 和 Windows 10 SDK 为在Windows下构建基于 chromium 的浏览器（103.0.5060.68 之二）</title><link>https://qiucode.cn/article/216/</link><pubDate>Sun, 22 Sep 2024 15:26:43 +0800</pubDate><guid>https://qiucode.cn/article/216/</guid><description>为何要安装depot_tools 虽然我们在上一篇 Windows构建基于 Chromium 的浏览器之环境准备篇安装 Visual Studio（103.0.5060.68 之一） ，已经在Windows系统安装好了Visual Studio 2019 Community版本。
然而chromium源码工程之庞大，并不是我们平时坐在写字楼里，捣鼓了几个月，勉强符合上级领导的要求而上线的项目，这也就为什么chromium 官方文档里要求你在build里，需要有100G的空闲磁盘的缘故了。
那么，如此巨大的项目，以及如何很好来管理chromium依赖的第三方library呢？
我想这时，肯定会脱口而出，“使用git来管理项目，并且还能有效地处理好第三方library。”
的确，chromium官方就是采用了git来管理这么庞大的项目。
但chromium 源码所依赖的第三方library可不是一两个而已，我们从图中也是可以看出，chromium依赖的第三方library可不是一般的多啊！那是非常的多啊！
我借助了visual studio code这款IDE，在Terminal中输入以下命令，可以计算出当前路径下拥有多少个子文件夹（直到第一级，不会去递归计算哦！）
(Get-ChildItem -Directory | Measure-Object).Count 注意：这行命令只在`PowerShell`中生效，这也就为什么我会借助`visual studio code`这款`IDE`的缘故。或许你有点纳闷，这visual studio code是不是我们在上一篇安装的visual studio呢？
初次捣鼓的你，难免会被这两者给弄混淆了。
这其实也不能全怪你啦！毕竟visual studio系列与visual studio code的应用程序图标是一样，只是颜色差异而已罢了，且它们同是microsoft公司的产品。
对于chromium依赖了这么多第三方library，你总不可能对每个library手动写git submodule吧！
而此时的你可能会想到可以借助python来编写脚本，用来synchronized（同步）chromium第三方library。
为此，chromium 官方提供了一个用于synchronized第三方library的工具，它不仅能synchronized thried_party，而且还能build chromium，那么，它是谁呢？
它就是本文的主角——depot_tools.depot（是仓库的意思）。
安装depot_tools 要想安装depot_tools工具，那么毫无疑问的是从chromium官网上下载depot_tools工具。
下载地址 https://storage.googleapis.com/chrome-infra/depot_tools.zip，将其解压至 任意不包含中文或空格的目录里。
注意：不要使用鼠标拖拽或复制粘贴，否则其中 .git 目录可能不会正常复制过来，请使用 zip 压缩包管理工具直接解压到目标目录。当我们解压下载下来的depot_tools压缩包后，需要在系统环境变量中添加depot_tools的路径。
注意：如果你的电脑安装了`python`和`git`，请将`depot_tools`路径添加在它们之前，因为`depot_tools`工具里内置了`python`和`git`。随后，我们需要再设置一个DEPOT_TOOLS_WIN_TOOLCHAIN的变量名，其变量值为0。作用是让 depot_tools 使用本地安装的 Visual Studio 版本（默认情况下，depot_tools 将尝试使用 google 内部版本）：
然后cmd一个命令窗口，先是设置网络。
注意：该设置网络只会在当前窗口有效，也就说你每新打开一个新窗口，都需要设置网络`。
# windows set http_proxy=127.</description></item><item><title>Windows构建基于 Chromium 的浏览器之环境准备篇安装 Visual Studio（103.0.5060.68 之一）</title><link>https://qiucode.cn/article/215/</link><pubDate>Sat, 21 Sep 2024 13:26:43 +0800</pubDate><guid>https://qiucode.cn/article/215/</guid><description>引言 在信息快速发展的当今，人们似乎对电子设备依赖层度越来越深了，尤其是智能手机的普及，逐渐改变了人们在网上冲浪的方式，除非了是需要在电脑上处理的事情，才会去打开那落满灰尘的电脑。
手机本就是为了能与方便交流沟通而诞生的，虽然现如今，在手机前加了智能两字，并不是说这手机能有多智能，它无非是能像电脑一样，能浏览各大网站，玩游戏，看视频，网上购物等等。
甭管是在电脑上，抑或是在智能手机里，我们想要搜查资料，第一得先打开浏览器应用程序，一般浏览器都默认为用户选定了一个搜索引擎，第二，我们在搜索引擎的输入框打上要查找资料的相关信息，等输入好了，等它个几百毫秒之后，你会看到，搜索引擎为你罗列出了与你在输入框填写文字相关的内容。第三，点击列表中你看似符合你要求的结果。
说起浏览器，可谓是五花八门，王婆卖瓜，自卖自夸。如果你不是一个IT人士，那么你的电脑装上了国内的360浏览器、2345浏览器、hao123浏览器、qq浏览器……（毕竟你作为一个非互联网人，不知道国内的这些流氓软件还可原谅，这其中尤以360浏览器最为离谱，了解过360杀毒的，都知道它自己本身就一个病毒）。
可假使你是一位互联网从业人员，却在电脑里安装了360极速浏览器的话，那么只能说明你是……（自行脑补吧！）
市场份额排在第一的Chrome（身为一个IT人员，对它应该不陌生吧！它可是google公司的开发的浏览器，而且还是基于google开源的chromium V8），你却不用，非要使用国内的360浏览器，可当你电脑安装了360浏览器之后，时不时的会在电脑右下角弹出广告（也就是显示日期和时间的那个角落里弹出一个广告，这是不是很恶心，这就是这些国内浏览器的套路和玩法！）
除了Chrome，你也可以选择其他的浏览器，诸如：Mozilla出品的firefox（火狐），它也是基于Mozilla公司开源的浏览器，microsoft公司的Edge（Edge也是基于chromium开源项目的浏览器）、Apple公司的Safari浏览器，opera浏览器也是基于chromium的，……
序言 我想要构建一个基于Chromium内核的浏览器由来已久，可为什么直到现如今才着手开始搭建呢？
拖大抵是人类的通病吧，但最主要的莫过于把空闲时间用在了旅游（无非是逛逛商场，虽然鲜少在商场内购物，但我还是比较逛的）、爬爬山去暂时的放空心灵，暂避那喧嚣的都市。
逛商场，目之所及皆是人来人往，有人手里拎着好多东西，与同伴有说有笑着，从我身旁路过；而有些人则是将商场几个层楼，都绕了一圈下来，也没见他进哪家店里买东西，我就是属于这类人，纯粹是来这里感受下商场里人流量的震撼。
信步登山，不单单只是放空自己，远离那喧嚣的都市；而是在贴近大自然，你可以把生活或工作的烦闷给释放出来，甚至你大可吼一声。
不管是购物时的满心欢悦，抑或是爬上山巅坐在石凳，惬意的度过一个下午，但你终究还是要回到现实生活中来，闲暇的时光总是那么短暂的。
那么现在怎么就能把闲暇时间用起来呢？难道不去逛商场了吗？亦不去登山了？
也全是，商场该逛还是会去逛的，山也会去爬，偶尔也会在山巅吼上那么一嗓子的，但是现在，也该做些自己曾说过要做的事情了。
必备准备 在编译chromium源码之前，我们有必要为电脑配置好所需的environment（环境）。
作为一名coder（程序员或码农），深知开发一套软件或是编译知名的开源项目时，系统里总是免不了配置好符合当前开发软件或编译开源软件的必要environment（环境），这就好比，想要开发C/C++软件，那么你的电脑是少不了安装GCC/g++decompiler（编译器），其次你还需有一个对C/C++语法支持且纠错的IDE。
要说哪款IDE广受C/C++程序员的热捧，那么microsoft公司出品的Visual Studio无疑是登上C/C++ IDE宝座的王者，想必是无人敢反驳吧！
还有一个必要的条件，那就是你的电脑能正常访问以下网站（至于怎么可以正常访问呢？却不在本文范畴内，我想你总能找得到）。
1、Chromium官网：https://www.chromium.org/ 2、Chromium git 仓库：https://chromium.googlesource.com/chromium/src.git 3、Chromium 版本分支说明：https://chromiumdash.appspot.com/branches 从chromium 官网文档中可以看出，你的电脑还必须具备以下条件：
1、64 位 Intel电脑，至少 8GB 内存。 强烈建议超过 16GB。 2、NTFS 格式硬盘至少有 100GB 可用磁盘空间。 FAT32 将无法使用，因为某些 Git 包文件大于 4GB。 3、安装相应版本的Visual Studio。 4、Windows 10 或更新版本。 然而我的电脑除了不是Intel外，系统还达不到要求，还是贫民级别的Win8.1。
为此我还特意把电脑磁盘空间清理了下，看看最后哪个盘符下最接近100G的可用空间。
安装Visual Studio 2019 Community 对于Windows系统想要build（构建）chromium，安装Visual Studio版本是有要求的：
Chromium 需要 Visual Studio 2017 (&amp;gt;=15.7.2) 来构建，但首选 Visual Studio 2019 (&amp;gt;=16.</description></item><item><title>为什么网站加载速度总是那么不尽如人意呢？（网站优化篇）</title><link>https://qiucode.cn/article/214/</link><pubDate>Sat, 14 Sep 2024 16:26:43 +0800</pubDate><guid>https://qiucode.cn/article/214/</guid><description>那些年，但凡一得空，便会去逛逛公园、爬爬山，让那颗浑浊的心灵，能在这大自然中洗涤。
公园树荫下，总是有那么多人，他们或坐于石凳与好友畅聊，或是往那石桌上摆下棋盘，你总能遇到对手。
既然选择放空自己，不管是与好友们闲聊，抑或是棋逢对手，就不要把生活中的不如意或当下的困境说出来，因为这里并不是宣泄消极情绪的好地方。
然而，快节奏生活的当下，鲜有人会在公园逛那么一个下午了。
快节奏的生活，逐渐使人们失去了耐心，同时也让人变得很容易烦躁。
即便是当下人手一部智能手机（更有甚者多达好几部），也不愿花几秒钟来等待访问某个网站，页面却一直处在加载中。用户会毫无犹豫的关掉这个网站。
因为等待让人觉得烦躁，这便是时下快节奏的生活所导致的！
用户评判一个应用（APP）、网站的体验效果好坏，其中很重要的一点便是，产品的响应速度是否能控制在用户接受的范围之内（除非你的应用或网站是知名的，如：阿里云、腾讯云等网站响应速度何止是慢。）
网站优化方案 无论是简单的企业门户网站，还是看似复杂的博客网站，它们总是由html、javascript、css、图片文件等构成的，而呈现在用户眼前，便是通过这些文件拼凑而来的一个页面。
提升服务器带宽 在你访问网站时，网站文件所在的服务器在接受到你的指令后，是要将服务器上相对应的html、javascript文件等响应给你，也就是浏览器请求这些资源（可以说从服务器下载这些资源）。
我们深知，但凡从网络上下载任何文件，它总是跟你的网速有关的，若你带宽是100M的话，那么下载那是很快。当然咯，网站所搭载的服务器带宽若不是很好，网站加载慢那是再所难免的！这便是网站优化的方案之一，关于这一块，是需要花费的成本的。
使用 CDN 有没有那么一种可能，那就是你把服务器的带宽提升上去了，可用户访问你的网站，依旧是页面处于正在加载中。那可能是浏览器访问你的网站，需要请求很多javascript、css文件等资源，虽然用户与你的网站服务器同属在国内，但不免由于地域的缘故。
为了解决用户在不同地域访问你的网站，能以用户所能承受的加载时间范围内，渲染出网站页面出来，那么，这样对用户来说，你的网站算是一个用户体验不错的网站。
我们既然知道了，导致网站加载慢的症结是javascript等资源，那么，我们可以将这些文件托管在距离用户较近区域的节点上，让用户在访问你的网站，不再是请求服务器的javascript等资源，而是从歫用户较近的节点上读取这些文件，从而使得用户所在的区域访问你的网站便快了。
没错，这便是内容分发（CDN）。它不单是在国内每个区域设有节点，还遍布全球，你可以把原先放在服务器上的javascript等文件，迁移到CDN上，这样一来，继而减轻了服务器的”压力“，又能让你的网站在用户眼前加载起来快如闪电。当然咯，这也需要你额外付出成本的！
压缩静态资源 若你不想再额外花钱的话，那么，就要从javascript、css等文件大小上来考虑，相对于网络传输来讲，当然是文件小一些，它自然快于大文件的传输速度了。
虽然，市面上有公共CDN，但那也都是些知名的第三方library，自己的网站，总是离不开自定义的javascript、css等文件。
对于压缩方式可以选择，网上在线压缩，前提是你只定义了那么一两个javascript、css文件。
可若是你为你的网站自定义了好些个javascript、css，那么，在线压缩就不适合了，一来文件多了，处在起来还是比较麻烦的，二来文件一多，处理起这些繁杂的工作，总是让人很是烦躁。
既然在线压缩，处理多个文件，委实使人力不从心，那么，我们可以借助程序来实现文件压缩啊。
Gulp 压缩静态资源 至于gulp是什么呢？ https://www.gulpjs.com 介绍说它是自动化构建你的项目，减少你浪费的时间，从而创造出更大的价值。（虽然口气有点大）
首先，你的确保你的电脑是否安装了node.js，如果没有，那么可以去 https://nodejs.com 进行下载安装。安装nodejs还是比较简单的，一路Next。
若你的电脑已安装过nodejs的话，那么，你可以使用以下命令来检查，你电脑安装的nodejs版本。
node --version 在nodejs高版本，都会在你安装了nodejs之后，同时默认的安装了npm（用于管理nodejs的library，就像java的maven、gradle，PHP的composer，golang的module等一样），和npx，同样的话，可以使用以下命令来检查npm、npx的版本。
npm --version npx --version 随后，我们通过以下命令来全局安装gulp。
npm install --global gulp-cli 创建项目 我们可以在一个空文件下，再次新建一个空文件夹，而后通过npm init来初始化项目，这条命令能为我们在当前文件夹下自动生成一个package.json文件。
npm init 之后我们再项目安装gulp依赖，来为项目实现自动化构建。
npm install --save-dev gulp 创建 gulpfile.js文件来压缩静态资源 我们在项目根路径下，新建一个名为gulpfile的javascript文件，文件名必须叫gulpfile这个名称，若你问我为什么？那我只能回答你，那是因为gulp规定的，也就是gulp-cli会读取这个名为gulpfile的javascript文件，若你改成了其它名称，那么gulp-cli是无法找到名为gulpfile`文件的，那么也就无法进行下去了。
在编写gulpfile.js文件之前，我们的项目需要安装几个依赖，它们适用于压缩javascript、css文件的。
npm install --save-dev gulp-uglify npm install --save-dev gulp-minify-css 安装好library后，那么，我们可以对gulpfile.js进行编辑了。
const { src, dest, series } = require(&amp;#39;gulp&amp;#39;); const uglify = require(&amp;#39;gulp-uglify&amp;#39;); const minifyCss = require(&amp;#34;gulp-minify-css&amp;#34;); //在 gulp 里 这就是一个任务 function miniCss () { return src(&amp;#39;src/css/*.</description></item><item><title>海外云服务器安装 Redis 6.2.x （Ubuntu 18.04 记录篇三）</title><link>https://qiucode.cn/article/213/</link><pubDate>Sat, 07 Sep 2024 18:26:43 +0800</pubDate><guid>https://qiucode.cn/article/213/</guid><description>通过前两篇的实践，我们已然在海外云服务器/VPS安装了JDK和MariaDB数据库，一个能够运行Java项目的海外云服务器/VPS算是告一段落了。
然而，在这请求量与日俱增的情况下，MariaDB数据库显然是在超负债·的工作，压力那不是一般的大。
为了缓解mariaDB数据库的压力，我们可以采取缓存策略，也就是那些请求量比较频繁的数据，可以缓存起来，以便用户再次请求时，不再去读取数据库数据，而是将缓存数据响应给用户，从而减少了因频繁读取数据给数据库带来的压力。
我们可以使用业界、开源界享誉盛名的NoSQL——redis。它是一个K/V 键值对存储，内存型的非关系型数据库，也正是由于它是内存型存储方式，所以它在读写方面快于SSD 型存储的数据库。
下载 redis 由于redis都是通过源码编译进行安装的，故而我们首先得下载redis源码，随后在Linux 发行版进行编译安装。
redis官方地址： https://redis.io/downloads/
截止发稿前，redis最新版本已经到7.4.x了，然而7.x版本以上是需要商业授权的，这也是众多开源软件走向商业化的途径。
当然咯，redis官方还是会一如既往地向公众开源，但那只是community（社区版），却足以应对日常问题了。
我们将下载下来的tar压缩包，通过SSH工具上传到海外云服务器/VPS对应的目录下。
解压压缩包 首先我们进入到刚刚上传过来的redis压缩包目录下。
使用以下命令进行解压：
tar -zxvf redis-6.2.14.tar.gz 在Terminal执行完这行命令后，会在当前目录下多了一个与压缩包同名的文件夹。
编译并安装 redis 由于redis采用C language编写，而想要编译C language的话，是需要专门用来编译的C language 的编译器。
首先，我们先在Terminal输入gcc -v命令，查看当前的Linux 发行版是否安装了gcc，假使你在输入命令后，得到了如下与下图一样的提示信息，那么说明当前的Linux 发行版是没有安装过gcc，你可以从提示信息中看到，有一行apt install gcc的信息，瞬间让你觉得很是贴心，虽然当前Linux 发行版没有gcc环境，但你可以通过apt install gcc来安装gcc。
你可以使用apt update命令来更新你的系统镜像源。
apt update apt install gcc gcc -v 随后，我们再次输入gcc -v命令，terminal便输出了刚刚安装gcc版本信息了。
之后，我们进入redis刚解压的目录内，对redis源码进行编译。
提示：某些`linux 发行版`可能出现以下信息，那么，按照提示信息进行操作即可。root@XXXX:/usr/local/redis# cd redis-6.2.14/ root@XXXX:/usr/1ocal/redis/redis-6.2.14# make Command &amp;#39;make&amp;#39; not found, but can be installed with: apt install make apt install make-guile root@XXXX:/usr/1ocal/redis/redis-6.</description></item><item><title>海外云服务器安装 MariaDB 10.6.X （Ubuntu 18.04 记录篇二）</title><link>https://qiucode.cn/article/212/</link><pubDate>Wed, 04 Sep 2024 20:36:43 +0800</pubDate><guid>https://qiucode.cn/article/212/</guid><description>MariaDB 的由来（历史） 谈起新秀MariaDB，或许很多人都会感到陌生吧，但若聊起享誉开源界、业界知名的关系型数据库——Mysql，想必混迹于互联网的人们（coder）无不知晓。
其实mariaDB是由Mysql分支出来的一个项目，而且同属于同一个作者（Michael Widenius）。或许你会纳闷，既然Mysql如此优秀，作者而又为什么再次创造出一个新的数据库呢？
谈起mariadb的诞生，那就不得不说Mysql那命运多舛的际遇咯！起初，Mysql以开源的形式瞬间火爆互联网圈，这其中就包括创造出 Java 的公司—— sun，彼时的他们亟需一套小巧且功能强大的数据库，来摆脱其他商业化数据库。故而，sun 公司看准了时机，斥巨资收购了彼时还处在蓬勃发展的Mysql。
时间一晃，来到了2009年，号称全球数据库巨头 Oracle以当时看来是天价的价格收购了sun 公司，作为sun 公司的附庸品，当然也卖身到新雇主，Mysql再次改投公司，并非它所愿，实是无奈之举。
倘若sun 公司没被Oracle收购，或许不会出现mariaDB，毕竟sun 公司创造出了java这一从它诞生以来稳居于年度 program language（编程语言）排行榜前三，毫不夸张的说，它影响了一代的互联网的进程。
可事与愿违，sun 公司终将被oracle 公司收购了。自打oracle公司并购了sun 公司，全球数以千万计的Java Engineer，便开始为Java是否还会开源起了忧虑之心。
果不其然，oracle 公司还是向java开刀了，他们修改了java的一些开源策略，如：商业授权……
也正源于此，作为Mysql的作者，不得不为mysql的未来而担忧。然而，现在的mysql已经属于Oracle 公司，看似开源出来，但Oracle 公司随时都有可能将它闭源化。可他唯一能做的就是从开源的mysql开出一个分支，构建出一个新的数据库，而它将改进Mysql所出现的问题，虽然mariadb是由mysql作者主导的，但主要还是靠开源社区来贡献代码。
安装前准备 我们知道大多数开源软件，多多少少会使用第三方（开源工具类库）软件包。虽然，你的项目大可不必依赖第三方类库，完全由自己着手编码来实现，那也是没问题，但在编写完这些工具库时，你的项目引入之前，你总得为你所编写的类库做unit test吧！
工具类库代码量不是非常庞大的话，由你自己编写，亲自做unit test，这都没什么，毕竟自己从零开始实现一个与第三方相似的工具类库，给自己带来的不单单是一种炫技感，更多的是成就感、喜悦感。
可倘若工具类库代码行数达到上万，甚至十来万行呢？此时的你，再想从头写起与第三方类库类似的功能，怕是力不从了吧！且不说编写那十来万行的代码所消耗的时间，而是在接下来的事，是需要对它做unit test，将会让你开始怀疑人生。
一个开源项目/产品能赢得越来越多用户的追捧，其中最为重要的一点莫过于产品的迭代更新速度是否快于竞争对手/友商。
为了能使产品在迭代更新上快于他人，产品的研发团队往往会将项目中公共模块抽取出来，形成一个工具类库，或是使用了第三方开源类库，从而降低了花在这上面的时间以及精力4，以便能够全身心的着眼于产品本身。
安装所需的软件包 至于安装mariaDB前，为何要安装software-properties-common这个软件包呢？其实你也是可以不安装这个依赖库，而是直接安装MariaDB，那也是没问题的！只是在安装MariaDB过程中，会出现Error，最终导致无法正常的安装MariaDB，而出现错误的原因却是当前Linux发行版还未安装某个软件包。
为了使MariaDB能够继续的安装下去，你便按照error提示，安装MariaDB所需的第三方类库。
既然是这样的话，我们何不将MariaDB所需的软件包提前安装呢！
apt install software-properties-common -y 添加 MariaDB 镜像仓库 无论你当前系统属于哪个Linux 发行版，使用在线安装软件时，总是会在当前系统的镜像库搜寻，以此来下载软件。
当然咯，系统里的镜像仓库的软件版本或许有些旧，毕竟某些软件更新迭代快，以至于Linux 发行版来不及去更新镜像仓库内的软件版本。
故而，我们可以将需要下载哪个版本的MariaDB添加到系统镜像仓库里面。
至于那个MariaDB key 是官方所要求的，你将它下载下来就对咯！
apt-key adv --fetch-keys &amp;#39;https://mariadb.org/mariadb_release_signing_key.asc&amp;#39; sudo add-apt-repository &amp;#39;deb [arch=amd64,arm64,ppc64el] https://mirrors.ustc.edu.cn/mariadb/repo/10.6/ubuntu bionic main&amp;#39; 安装 mariadb-server 和 mariadb-client 热身的差不多了，是该真正露出本领的时刻了，此处应有振聋发聩的掌声，不绝于耳的那种掌声。</description></item><item><title>海外云服务器安装 JDK8 （Ubuntu 18.04 记录篇）</title><link>https://qiucode.cn/article/211/</link><pubDate>Sun, 01 Sep 2024 16:46:43 +0800</pubDate><guid>https://qiucode.cn/article/211/</guid><description>曾几何时，我可是国内云厂商的忠实用户啊。
而今，却不再为云服务器（尤指国内云厂商）续费了，作为我的个人网站 秋码记录 选择了托管在 gitlab.com Pages服务上。
国内云厂商对新老用户持有两种截然不同的价格，致使众多用户在云服务到期之际，便毅然决然地弃用了这家云厂商。
国内云厂商对同一配置、同一规格、同一型号、同一时限……的云产品来说，新用户总是能得到低于市场同类产品的价格，这便是国内云厂商让利于新用户，以求得在用户量上碾压行业内竞争对手。
反观老用户，通常老用户是指，但凡在国内云厂商某个平台购买了云产品，那么，你的身份便由新用户转换为老用户了（美其名曰：会员），那么，彼时的你是再也无法享受只专供于新用户的优惠云产品咯。而这样的规则，却不局限于互联网这个圈子，可以说，整个国内各行各业都在运用这条规则，小到街边门店，大到商场酒楼……，随处可见它的身影。
云服务器即将到期了，作为老用户是很少会选择续费的（除了特别有钱的企业或个人），那是对该云服务器续费价格望而却步，或有转场它处继续前行下去，也是大有人在，几轮下来，国内各大云厂商你都混了个脸熟，这也就是近几年来国内各大云厂商的新用户增长量有所放缓的缘故。
新用户增长量持续放缓，那说明了云产品卖不出去了，因为国内云厂商销售云产品很大程度上是靠新用户，虽然从新用户身上得到的利益明显少于老用户，但也总比老用户不再卖他家的云产品强，正所谓，苍蝇再小，它也有肉。
国内云厂商的云产品卖不出去了，不单单是市场饱和了，还有更多深层次问题（我相信你是懂得，倘若你不懂的话，那就忽略它。其实，懂得太多，它也是一种烦恼！）。
国内云厂商的窘迫该如何有效的决解呢？其实我不知道，但从年初 罗永浩直播卖阿里云服务，揭秘中国云计算走向衰落的真相 便能瞧出国内云厂商的穷途末路（虽然有点夸张的成分）。
在说完国内云厂商的那摊破事，也该聊聊本文的标题海外云服务/VPS了。或许，你会问，“你不是说了，qiucode.cn 租用的国内云服务器不再续费了吗？难不成国外的云服务器/VPS就很便宜了，就算国外云服务器/VPS便宜，但在国内访问起来，那犹如蜗牛爬树——何时能爬上啊？”
“qiucode.cn 现在既没有选择国内云服务器，也没有改用国外云服务器/VPS产品，依旧托管于 gitlab.com pages，而标题中的海外云服务，那是一客户租用的，我搭建了Linux·基础环境，在这里只是纯粹做个记录而已罢了！”
将JDK 上传到服务器 首先我们先到oracle官网下载JDK8，至于该怎么下载，可以浏览 虚拟机 Linux 安装 JDK（Vagrant 之二 CentOS7 篇），这里就不再赘述。
你可以选择惯用的SSH工具，进行操作。
虽然，也是可以在云服务器内使用wget命令来直接下载JDK的tar压缩包文件，究其原因，无非是云服务器带宽所限。
我们将下载下来的JDK tar压缩包，通过SSH工具，上传到云服务器。
我们可以将中间件及基础环境同一放在/usr/local/目录下。
cd /usr/local mkdir java 对 tar 压缩包进行解压 等待JDK压缩包上传成功后，我们便要对压缩包进行解压。
tar -zxvf jdk-8u421-linux-x64.tar.gz 当压缩包解压好了之后，我们要对解压后的文件夹进行重命名，那是因为，tar命令默认将压缩包文件名作为解压后的目录名，除非你带了参数-O 目录名称。
可以使用mv命令对目录名，进行重命名。
mv jdk-8u421-linux-x64 jdk-8u421 配置环境变量 配置JDK环境变量犹如一道魔咒，始终盘旋在即将踏入Java Engineer的上空，给他们带去了无法抹去的记忆。
我们打开/etc/profile文件，在其末尾追加上以下内容。
`JAVA_HOME`是你`JDK`解压缩的文件路径（需根据实际情况，做出相应修改）。export JAVA_HOME=/usr/local/java/jdk1.8.0_421export CLASSPATH=.:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jarexport PATH=$PATH:$JAVA_HOME/bin 若你使用的是像我这样的可视化编辑器，那么你可以直接按住键盘上的Ctrl + s组合键，进行保存。
可假使你使用的是Terminal Command的话，如：vi、vim等命令，那么你需先按住键盘上的Esc，之后输入:wq，在按Enter键即可。
配置好了JDK环境变量后，先是让/etc/profile文件生效。</description></item><item><title>虚拟机 Linux 安装 JDK（Vagrant 之二 CentOS7 篇）</title><link>https://qiucode.cn/article/210/</link><pubDate>Thu, 29 Aug 2024 18:06:43 +0800</pubDate><guid>https://qiucode.cn/article/210/</guid><description>我们已然在上一篇讲解了如何快速的搭建一个Linux虚拟机，通过vagrant命令化工具，我们很方便的构筑了虚拟机，那么，我们所搭建出来的Linux系统主要是为了调试产品，以便产品在部署生产环境之后，能够顺利运行，这才是我们在本地电脑或局域网安装虚拟机的最终目的。
由于你服务端程序所选的program language（编程语言）因素，造成了虚拟机或将要部署到生产环境上的所必要基础环境差异化，这是无可厚非的。
闲话少叙，切入正题。本篇除了在安装JDK与其他服务端有所差异之外，其他mid-ware（中间件）安装方式都是一样的，没有什么不同，包括但不限于redis、MariaDB、mongodb等。
安装JDK 首先，我们进入Oracle官网：https://www.oracle.com/cn/java/technologies/downloads/ ，找到你项目所对应的JDK版本，系统当然选择的Linux。
当你再看到下图时，请你暂时别笑，虽然现在JDK最新的LTS（长时间支持）是JDK21，而我呢，却还在下载JDK8，之所以选择JDK8，那是因为项目是早期的，我相信有很多与我相似情形的。
我现在的做法便是，保持生产环境能够稳定运行，随后则在本地迁移到JDK17，直至项目整体架构迁移完成，在虚拟机调试没有太大的问题之后，再行更改生产环境的JDK版本。
我们将下载下来的JDK，移动到宿主机映射到虚拟机的文件夹内，这样就将宿主机文件成功的挂载到虚拟机里面了。
那么接下来，我们打开VirtualBox这款虚拟化工具，之后进入到虚拟机的路径，调出Terminal，输入vagrant up来启动虚拟机。
当虚拟机启动成功后，我们可以使用vagrant ssh进行连接虚拟机，也就是进入虚拟机，对其操作。
进入到虚拟机后，我们由vagrant用户切换到root用户。
若你对root用户如何修改密码，可以查看我的上一篇文章，倘若你又不想链接来链接去的，那么你可以使用sudo passwd root来修改root密码，输入你新的root密码即可。
在安装JDK之前，我们有必要对当前虚拟机或将要部署到生产环境检测是否默认安装了JDK，因为Linux某些分支会在系统默认安装了JDK。
java -version 随后我们在虚拟机中创建一个java文件夹。
mkdir /usr/java 创建好java文件夹之后，我们cd到宿主机文件挂载虚拟机的路径下，对刚刚下载好的JDK的tar包进行解压。
tar -zxvf jdk-8u421-linux-x64.tar.gz 等解压完成了，我们将解压好的整个文件移动到刚刚创建好的路径里，也就是移动到/usr/java/这个路径下。
mv jdk1.8.0_421/ /usr/java/ 那么，接下来将要配置JDK的环境变量了，关于这一点，相信很多Java Engineer是再清楚不过了。
配置JDK环境变量 要想在Linux系统中配置JDK环境，只需对/etc/profile文件进行追加java相关信息即可。
export JAVA_HOME=/usr/java/jdk1.8.0_421 export CLASSPATH=.:%JAVA_HOME%/lib/dt.jar:%JAVA_HOME%/lib/tools.jar export PATH=$PATH:$JAVA_HOME/bin 先按键盘上的Ins（插入键），它的位置处在Del（后置删除键）的上方，让profile处于INSERT（编辑）状态，才能对文件进行修改。
配置好了JDK信息后，我们需要保存此次所做的修改，故而，我们敲下键盘上的Esc，它的位置是在键盘的左上角。
紧接着，我们继续敲下:wq!几个字符，这才保存了刚刚对profile文件所做的任何修改。而加不加!，其实都可以保存，但加了!则表示是强制退出。
这时你便可以在当前Terminal输入java -version命令，以验证你是否安装java成功，然而当你Enter（回车键）之后，却出现了之前系统没有安装java的状况。
可是不过几秒钟的时间，你忽然拍了前额，笑道，“居然忘记了这一步……”。
那么，你究竟是遗漏了哪一步呢？而又为什么你能在几秒钟反应过来呢？
但凡你修改了系统的相关配置文件，在当前Terminal是不会生效，若想配置生效，除非打开一个新的Terminal，可倘若你不想弹出另外的Terminal呢，你就要在当前Terminal验证呢！那么你只需输入以下命令即可：
source /etc/profile</description></item><item><title>怎样快速搭建 Linux 虚拟机呢？（vagrant 篇）</title><link>https://qiucode.cn/article/209/</link><pubDate>Sat, 24 Aug 2024 15:46:43 +0800</pubDate><guid>https://qiucode.cn/article/209/</guid><description>作为一名Coder（程序员或码农），供职于中小型互联网公司，而你恰恰偏向于服务端，那么，产品部署在生产环境的艰巨任务，便毫无疑问的落在你身上了。
只有大厂（大型互联网）企业才有运维部，而能进大厂的显然是少部分人，大多数Coder终究还是混迹于初创或中小型互联网公司，一名服务端 Coder往往都是身兼数职，甚至有可能干掉了frontend（这也就是初创或·中小型·互联网公司在Job Descriptio[职位描述]中，要求你在懂得服务端技术知识，还需熟悉frontend相关内容），当然咯，也有些中小型公司会分工明确，虽然没设立什么运维部，但起码也有一两个深耕于Linux 服务器多年的运维人员。
甭管你是Full Stack engineer（全栈），抑或是backend（服务端），总逃不掉要将开发完成的程序部署到服务器上吧！由于开发环境和生产环境之间存在着差异，从而导致了你按照开发环境所需的必要准备，在生产环境开始部署程序，出乎意料的一幕总能让你吃惊不已，你挠着头，口中喃喃说道，“这不可能吧，都按着必要环境部署的，不应该啊！……”
所以嘛，在把程序部署到生产环境之前，我们有必要在本地安装虚拟机，而这虚拟机所对应的系统便是生产环境上的系统，之后在该虚拟机上安装程序运行的必要条件，随后，在虚拟机环境里调试程序，等一切调试妥当后，方可部署到生产环境中。
安装 Vagrant 安装 VirtualBox 在安装Vagrant之前，我们必须安装一个虚拟化工具，它是跨平台的，也就是说，搭建一个虚拟机，安装了它就可以，Vagrant可以到一边凉快去了。
既然它（VirtualBox）本身就可以搭建一个虚拟机，而为什么又要Vagrant呢？对于这个问题，我不置可否，你回过头看看本文的标题，其中有个关键词——快速（虽然有点夸张的成分），你或许便能明白了。
至于怎么安装 VirtualBox，不在本文的范畴内，况且它跟其他软件安装方式一样，一路Next（下一步）下去 。
VirtualBox 官方地址：https://www.virtualbox.org/
安装 Vagrant 在安装完VirtualBox，接着安装Vagrant，而它的安装也是同安装其他软件一样，一路Next（下一步）下去，除非你要修改安装路径。
Vagrant官方地址：https://www.vagrantup.com/ 。
安装好Vagrant后，可以在Terminal中输入vagrant version，便会输出当前安装的Vagrant版本信息。
初始化虚拟机 我们在某个空文件夹下，调出Terminal，并输入vagrant init centos/7
当初始化成功之后，会在当前目录下自动生成一个Vagrantfile配置文件。
你可在这里：https://portal.cloud.hashicorp.com/vagrant/discover 找到你想要的系统。
我们启动刚刚安装好的VirtualBox软件，可以看出目前是没有任何虚拟机。
我们再次回到Vagrant初始化虚拟机的Terminal中，继续输入vagrant up命令，用于启动虚拟机。
当我们转过身，去看VirtualBox，明显有一个虚拟机正在运行。
连接到虚拟机 我们可以在当前Terminal中，键入vagrant ssh进入虚拟机，默认是vagrant用户。
可是有时在Linux安装软件时，是需要root权限的，那么，总得使用root来操作吧！
sudo passwd root 再输入两次密码后，便可以使用su root切换到root用户了。
退出虚拟机 可是使用logout退出虚拟机，回到宿主机。
关闭虚拟机 在回到宿主机下，方能使用vagrant的所有命令。
vagrant halt 配置私有网络（内部网络/局域网网络） 在虚拟机搭建起的服务，总得需要外部来访问吧，这其中当然就包括宿主机，所以，就需要就知道虚拟机的IP地址。
我们打开前面用Vagrant init初始化的虚拟机，自动为我们生成了一个vagrantfile配置文件。
打开注释。
config.vm.network &amp;#34;private_network&amp;#34;, ip: &amp;#34;192.168.33.10&amp;#34; 还需配置一个使用频繁的文件传输功能，毕竟，我们在宿主机开发的程序，需要传输到虚拟机进行部署调试，那么，宿主机与虚拟机之间的文件传输就再所难免，在使用过VirtualBox 或VMware等虚拟化工具时，文件传输总是令人头疼。然而，Vagrant通过文件夹映射，实现了宿主机与虚拟机之间能很好的进行文件传输。
还是在vagrantfile配置文件中，去掉文件夹间的映射前的注释。
config.vm.synced_folder &amp;#34;./data&amp;#34;, &amp;#34;/vagrant_data&amp;#34; ./data是在宿主机下的文件夹，也就是与vagrantfile配置文件同属一个路径下。
/vagrant_data是虚拟机内的文件夹。</description></item><item><title>个人站点迁移之gitlab.com pages 绑定自定义域名</title><link>https://qiucode.cn/article/208/</link><pubDate>Mon, 12 Aug 2024 20:46:43 +0800</pubDate><guid>https://qiucode.cn/article/208/</guid><description>前言概要 能浏览本文的你，想必是在gitlab.com上创建了Repository（仓库），并将本地代码push（推送）到该Repository（仓库）中了，开启了Pages服务，然而，gitlab.com并不会像github.com那样，给你生成以username.gitlab.io这样的子域名（二级域名/subdomain），而是生成了以你的的Repository（仓库）名称（比如我创建的Repository名称是qiucode.gitlab.io）加上-你的username，再加上一串由字母、数字组成的字符串，像是UUID一般的字符串，最后则拼接上gitlab.io,最后便如我的这般：https://qiucode-gitlab-io-qiucode-aee06712da2e10b24ab5079f6b5a4a09c943b.gitlab.io/
这也就是我在上一篇 不要你掏腰包，就能搭建个人网站之 gitlab.com Pages 托管服务 所遗留的问题，之所以会产生那么一长串的domain（子域名），那是由于gitlab.com给你生成URL时，默认是开启了unique domain（唯一域），这也是我查看了官方文档方才知道的，其实，稍微注意一下，在Pages当前页滚动页面，就会看到那个unique domain（唯一域）的开关了。
既然知道了gitlab.com默认开启了unique domain（唯一域），那么，我们只要把它关闭了，不就可以了嘛！是的，那么在当前Repository（仓库）左侧选项中找到Deploy（部署）中的子选项Pages，会看到下方settings属性，有个checkbox（复选框），它就是是否Use unique domain（使用唯一域）的开关，我们只需点击它，checkbox也就处于未选中（Uncheck）状态，点击底下的save changes（保存更改）就可以了。
配置自定义域名 如果你不想花钱去购买域名，而使用username.gitlab.iol来作为你的站点的域名，是可以的，没有任何毛病，毕竟很多博主、站长也都是这么干的。既省去了购买域名的费用（当然也有免费的二级域名，但那还不如使用username.gitlab.io呢！），又省去了SSL的困惑。这才是真正意义上的不要你掏腰包，就能搭建一个个人网站的最终完结篇。
可有些博主、站长（比如： qiucode.cn）还是希望能自定义域名。
要想自定义域名，还是在当前Repository中找到Deploy，选择它的子选项Pages
滚动页面找到Domain属性，点击右侧的New domain（新域名/添加新的域名）
当你添加完了域名后，来到了Pages Domain新页面，它便是要求你在你的域名 DNS 添加下列Record（记录），以此来验证你添加的域名所有权。
可以看出，我们需要在域名 DNS添加两条记录，然而，第一条记录中ALIAS（别名），却没在我的域名 DNS选项里，你说这，是不是在为难我啊！
这么着吧，还是看官方文档，看看该如何配置自定义域名。
官方文档关于如何配置自定义域名：https://docs.gitlab.com/ee/user/project/pages/custom_domains_ssl_tls_certification/index.html 。
按官方文档来看，分为三种情况：
root domain（根域名/主域名，如： qiucode.cn）
DNS添加一条A记录并指向gitlab.com Pages服务器IP地址（gitlab.com上的IP是35.185.44.232）。 再添加一条TXT记录用来验证你的域名所有权。 主机记录 记录类型 记录值 @ A 35.185.44.232 _gitlab-pages-verification-code.qiucode.cn TXT gitlab-pages-verification-code=00112233445566778899aabbccddeeff subdomain（子域名：如：lab.qiucode.cn）
DNS添加一条ALIAS 或 CNAME 记录，并指向Pages服务器 再添加一条TXT记录用来验证你的域名所有权。 主机记录 记录类型 记录值 lab.qiucode.cn ALIAS/CNAME qiucode.gitlab.io _gitlab-pages-verification-code.lab.qiucode.cn TXT gitlab-pages-verification-code=00112233445566778899aabbccddeeff 可按照官方文档来配置自定义域名，那个Verification status（验证状态）却一直都是Unverified，当然你在域名DNS添加纪录之后，得点击旁边的刷新按钮，其实它是将整个页面进行刷新，而不是页面局部更新数据。以至于修改DNS主机记录：
主机记录 记录类型 记录值 lab.qiucode.cn ALIAS / CNAME qiucode.</description></item><item><title>不要你掏腰包，就能搭建个人网站之 gitlab.com Pages 托管服务</title><link>https://qiucode.cn/article/207/</link><pubDate>Sun, 11 Aug 2024 16:46:43 +0800</pubDate><guid>https://qiucode.cn/article/207/</guid><description>当你看到文章标题时，不会还以为我实在忽悠人吧！也难怪，这是我们身处的环境所造就的，这一点我倒是可以理解，毕竟，我们身边总是充斥着以免费、不要你一分钱……为噱头的各种声音，贪小便宜是人的天性，殊不知，他们因贪这小小地便宜，反倒是损失了更多。
人们在上当受骗了首次，也就对身边的“免费”东西不再感冒了。只有那么少部分人知晓这世上是不会有免费的午餐、天上也不会无缘无故的掉馅饼，倘若真掉馅饼了，并且还砸中了你，那是行骗之人瞄准了你的口袋而不去理会这些所谓的“免费”。
要是在互联网早期，你说，“不用你掏腰包，就可以搭建一个专属的个人网站。”那么，在别人眼中，此时的你就是个骗子。
而到了云计算兴起后，你再说同样的话，这时便有少部分人相信了。
可以参考：其实，低成本甚至免费的，也是可以搭建个人网站的哦！
为何选择 gitlab.com pages 服务呢？ 但凡是代码托管平台，它都提供pages服务，如果没有，那它就是阉割版的代码托管平台。
享誉海内外知名的github.com、提供开源版和在线的gitlab.com、……等众多海外声名显赫的代码托管平台，都提供了pages 服务。
当然咯，国内也是有很多代码托管平台，诸如：gitee.com pages 已经光荣下线了，请不要试图在上面托管任何静态网站了！！！、coding.net pages 服务会在页面停留 5s（5秒），像是在检测你的静态站点、以及一些不知名小众的托管平台，也都提供了pages 服务，但是，这些国内托管平台对于个人想要开启pages是有要求（条件）的。
若不是github.com在国内的访问速度限制，以及时常出现该网站无法访问的种种原因，想必国内的coder（码农或程序员）是不会将站点托管在国内的coding.net等其他不知名小众托管平台上的，gitee.com就别提了，现在可以把gitee.com称为阉割版的托管平台了，因为它不再提供pages了。
你以为将站点托管在coding.net,你就会觉得在国内访问速度提升了嘛？你是否觉得它会比github.com托管站点访问来的快？若你是这么觉得，那你认为错了，正所谓：你以为的以为不是你的以为。coding.net pages 服务会在你托管在其上的站点提留5秒钟，这反倒没有github.com快了。
国内的gitee.com骤然下线了pages服务，使得众多托管在gitee.com上的众多站长纷纷迁往它处（github.com、gitlab.com等海外托管平台），而托管在国内的coding.net上，迟早也是会忍受不了那莫名其妙的5秒钟页面空白提留检测，改用其他托管平台的。
或许有人跳起脚来，指着我的鼻子，骂道，“你为何老是贬低国内互联网产品呢？而一味地夸耀海外的互联网产品呢？照这样下去，国内的互联网行业还这么能兴起呢？”
“在你说这些话之前，烦请你在电子设备中使用浏览器访问国内的gitee.com,看看它的pages服务是不是下线了，以及coding.net是不是有在页面提留5秒中，还有些国内小众托管平台，如CSDN也有托管平台，它也提供了pages，对于个人来讲，是有条件限制的。”
对于国内的这些托管平台，gitee.com可谓是坐上了国内托管平台的“第一把交椅”，然而，它却没有任何形式的通知托管在其上的众多站长，以至于很多站长都蒙在鼓里，也只有在更新文章，推送到gitee.com上，方才知晓，自己托管在gitee.com上的站点出现了Timeout；coding.net给每个托管在它上面的站点停留 5 秒钟的时间，以此来检查你的站点；国内数一数二的托管平台都有这样或那样的限制，或者干脆下线了，那么，国内那些小众的、初出茅庐的托管平台岂不是对个人想要在该平台开启pages有了更多严苛`的条件了。
gittlab.com 创建 Repository（仓库） 在创建Repository之前，你得为你的gitlab.com配置好SSH Key，以便Repository的pull（拉取）和push（推送），至于该如何配置，可参考：国内 gitee.com Pages 下线了，致使众多站长纷纷改用其他托管平台 或在 CSDN上的 国内 gitee.com Pages 下线了，致使众多站长纷纷改用 github、gitlab Pages 托管平台 。
登陆gitlab.com官网，在左上角，点击账户头像旁边+按钮，进行创建一个新的project或repository。
随后，我们便在右侧看到，可以创建project或repository的各种“款式”。
我这里选择Create blank project（创建一个空白/白板项目）。
这里的项目名称取为username.gitlab.io是方便公网访问的。
假设project name为blog，那么你的project URL为：https://gitlab.com/username/blog/ 。一旦这个project启用了GitLab pages，并构建了站点，站点访问url为：https://uesrname.gitlab.io/blog/ 。如果你要创建一个user page，假设此时project name为qiucode.gitlab.io(qiucode为你的Gitlab username)，则你的project URL为：https://gitlab.com/qiucode/qiucode.gitlab.io 。一旦这个project启用了GitLab pages，并构建了站点，站点访问url为：https://qiucode.gitlab.io。
使用以下命令将创建好的project克隆到本地。
git clone git@gitlab.com:username/qiucode.gitlab.io.git 当然咯，你要在gitlab.</description></item><item><title> 国内 gitee.com Pages 下线了，致使众多站长纷纷改用其他托管平台</title><link>https://qiucode.cn/article/206/</link><pubDate>Sat, 10 Aug 2024 18:46:43 +0800</pubDate><guid>https://qiucode.cn/article/206/</guid><description>作为一位IT或coder（码农、程序员），在日常工作中，多多少少都会有技术知识的积累（生产环境中所遇到的问题【亦可称为是坑】）。俗话说得好，好记性抵不过烂笔头。不管是前沿技术的研习后的心得，还是工作中所遇到的问题，亟需将这些笔记留存下来，为的是以备后续查看（未来有可能遇到类似的坑，也好该如何下手，以不至于手忙脚乱的），当然咯，在方便自己的同时，也分享给他人。
那既然只是为了留存笔记而已，又何必去搭建一个个人博客网站呢？国内在线攥写博客的平台多如牛毛，既“省时”又“省力”，又何必非要去为难自己来搭建一个专属于自己的个人博客网站呢？诸如CSDN、知乎、博客园、掘金、简书……，攥写文章都是免费的（如果这都不免费，那恐怕这些平台都要下线了），又何必花钱购买云服务器/VPS、域名，网站你可以自己编写（省去了这部分成本），或是可以使用github pages、gitee.com pages来免费托管静态网站，但至少比在大平台攥写文章时，多了一步，那是将写好的文章push（推送）到你的远程仓库，那不成大平台免费的，它不香么？
回答上述“三个何必” 既然只是工作中的知识笔记，或是前沿技术的研习心得，国内有大把的博客、社区以供攥写，而缘何非得去搭建一个个人博客呢？的确，第三方平台有诸多的优点，但它的弊端也是显而易见的，就拿我2022-12-08在CSDN攥写的一篇关于如何注册 ChatGPT的文章，过了几个月后，居然被CSDN批注为未通过审核。
当我看到CSDN发来的站内通知，顿时懵圈了，不禁发问，“这是怎么回事？CSDN居然还有这波操作，着实令人费解啊！”
这就是你在第三方平台上攥写文章的困境，当然咯，你写的文章符合该平台的规则，那么一切将是风平浪静，反之，平台随时可以以审核未通过之借口，使得你热心分享知识给他人，却无形之中让人泼了一脚盆洗脚水，从头凉到脚。故而，搭建一个个人博客势在必行，而大三方平台照样会更新文章，而它只是作为更好地分享知识给他人，诸如 花了不到1块5，玩了下全网最火的ChatGPT 。
有人说，“你平常就写写知识笔记、以及你工作所遇到的问题解决方案，你就非得去花钱折腾出一个个人网站出来吗？难不成现成的大平台它不香吗？”
“大平台它香，但也让瞬间挠着头发，在房间里踱来踱去。而现如今搭建一个人网站也可以是低成本，甚至免费。”可以参考： 其实，低成本甚至免费的，也是可以搭建个人网站的哦！ 。
github、gitlab、gitee（已经下线了）、coding.net（要结合腾讯云）等国内外知名代码托管平台，都有提供Pages服务，也就是可以托管你的静态资源，以此来搭建一个静态网站，然而，每次在本地编译生成好的静态资源 推送（push）到这些托管平台总是比较麻烦的，毕竟，这相较于在第三方平台上攥写文章，费力了很多。
对于每次更新文章，都要在本地编译生成静态资源，总让觉得很是枯燥。去这些托管平台看看有没有属于这套程序的CI/CD（持续集成）相关文档。
gitee.io（gitee pages）终究还是下线了 据将站点托管在gitee pages的站长称，2024-05-01假期回岗，却发现自己的站点出现了Timeout，一时间，他很是不解，不应该啊！只是托管个静态资源，既然也出现了Timeout。
随即，他去gitee.com咨询官方客服，到底是出现了什么问题？回复他的是，gitee pages光荣下线了。（这是我预料之中的，我也并不是看不好国内这些互联网平台）
当然咯，有些站长还是不死心，竟然跑到gitee官方账号下提issue，很显然，这个issue官方是不会回复的，犹如一封信，内容写好了，却在最后忘记把寄往何处的地址写上，最终信是无法到达彼处的，可谓是遥遥无期。
当初，那些站长之所以会选择gitee pages来建站，也是有原因的，毕竟github pages在国内访问速度，，真是一言难尽啊，如果光是访问速度慢些，到还是勉强接受，不幸的是，github pages时常在国内出现了无法访问该网站的情形，这还让你的站点怎么分享知识给他人呢？
介于github pages在国内访问速度慢，还时常无法打开的缘故，很多站长终究还是勉为其难地选择了国内的托管平台（诸如：gitee.com pages、coding.net pages）。
gitlab.com pages托管站点 不同于github pages，gitlab pages是通过CI/CD来实现pages，也就是他没有像github那样的纯静态托管机制。当然咯，github也是可以通过CI/CD来实现站点的托管的。
要想在gitlab.com pages上托管站点，那么，毫无疑问的是，你得登陆 gitlab.com或注册一个新的gitlab.com账号（可以直接使用你的github账号），这里就不赘述gitlab.com账号的注册了。
在登陆gitlab.聪明·后，我们着手创建一个仓库（Repository`）,名称随你意，只要你欢喜。
通常，我们都是使用SSH来远程操作的，那么，就需要配置gitlab的SSH Key，关于key的配置，之前，我也是有相应的文章来介绍配置github和gitee的SSH Key，如果不是很清楚的话，在这里，我将再次讲解如何配置gitlab SSH Key。
我们本地使用以下命令来生成SSH公私钥.
ssh-keygen -t rsa -f ~/.ssh/gitlab.com/id_rsa -c &amp;#34;邮箱地址&amp;#34; # -f SSH私钥文件地址 随后，我们将生成好的公钥复制到gitlab.com上，可以使用以下命令。
cat 以 .pub 后缀的文件 当你git clone时，却出错了。
然而，你以为这样就好了嘛，可gitlab却还不行，还需再生成SSH 公私钥的文件位置下，编辑config文件，加入以下内容。
# GitLab.com Host gitlab.</description></item><item><title>canvas绘制文本时，该如何处理首行缩进、自动换行、多内容以省略号结束、竖排的呢？</title><link>https://qiucode.cn/article/205/</link><pubDate>Sat, 03 Aug 2024 15:46:43 +0800</pubDate><guid>https://qiucode.cn/article/205/</guid><description>实现如标题所示的这些文本效果，在css看来，不就是一两行css属性。然而，对于canvas来讲，要想呈现这样的文字样式，就没css那么轻松简便了。
既然如此，那为何还要使用对文本支持度不友好的canvas来绘制文字呢？而不是采用对文本天然支持的css呢？
canvas 绘制文本的场景 在给为何弃对文本天然支持的 css而不用，拣起了文本支持度不友好的canvas的答复之时。不妨先来看看，究竟是在什么样的场景下，需要用到canvas去绘制文本呢？
常逛商场的，总会不时地看到一些商家为了吸引客流而制作出的一张精美海报；再看艺术展前，也总能在大门看到本次参展的“艺术家”们最为得意的艺术及简介，所绘制的一张海报；去电影院观看的，大都是被该片前期在各大商场及公共场合宣传的那张海报而吸引来的。……
是咯，照这样看来，海报的确可以作为事物的重要途径，虽然海报承载的内容有限，但一张足够优美的海报，总是能把人们的目光给吸引过来的，好比去书店买书，总是会翻到书的背面。
甭管对前沿技术的学习，抑或是为了解决问题而去搜寻资料，你总免不了在各大博客（如：秋码记录 ）、论坛、社区以及生活类情感博客等网站游离，那些博文、贴文等总能解决你的燃眉之急的问题，而你也会在兴奋之余随手将该文分享给朋友。
很显然，文章分享功能可以说是各大网站的基础功能，网站运营者也热衷于你把文章分享出去，从而悄无声息的向你朋友推荐了该网站。所以，网站运营者是绝不会错失这样一个向用户宣传网站媒介之一的机会。然而，社会分享组件（第三方分享：诸如 QQ、微信、微薄……）并不能很好的推介网站，基于这种状况，一张既有文章的概要，又有网站的简介的海报便应运而生了。（秋码记录 便能为文章生成一张精美的海报）。
网站生成海报的几种方案 无论是线下的，还是线上的海报，它都是一张图。对于线下，想要制作出一张海报，只需将事先做好的海报图打印出来即可，但就线上而言，网站页面结构主要由html、css、javascript构成，而文章内容及文章封面图都是不一样的，那么，在这样的情况下，又该如何为文章生成一张海报呢？
既然知道了，海报是一张图，而文章页面结构又是html，那么只需将html转变成图不就成了吗？
没错，要想为文章生成海报，只需把html转成图片即可，而且还有开源的第三方实现。
1、html2canvas.js：从其命名上来看，一眼便能知晓，它是将页面的html转成canvas。这也是众多网站生成海报的首选之一。它的便捷在于你想要为海报生成什么款式的，你只需像修改你网站那样去修改就好。（目前 秋码记录 是采用这种方式来为文章生成海报） 2、dom-to-image.js:与html2canvas.js大致差不多。 3、canvas：直接使用canvas绘制而生成的海报，基于wordpress的很多主题也都使用它来生成海报。（ 秋码记录 即将采用这种方案） canvas绘制文本 在使用canvas绘制文本之前，有必要了解下什么是canvas？
其实，canvas也是作为html标签而存在于html结构中，而它常常被用来绘制图形及图形动画。
在现实生活中，艺术家想要画出一张画，有两样东西是必不可少的——素描纸（写生纸）、HB铅笔。
而在canvas中，同样需要设置画布的大小——width、height。
canvas绘制文本API
CanvasRenderingContext2D.fillText(text, x, y [, maxWidth]); text ： text是需要绘制的文本。 x ： x是文本绘制的水平参考点坐标。随着CanvasRenderingContext2D.textAlign的设置不同，x的坐标位置也不同。可以表示这段文字内容左侧坐标，或水平中心坐标，或右侧坐标。 y ： y是文本绘制的垂直参考点坐标。随着CanvasRenderingContext2D.textBaseline的设置不同，y的坐标位置也不同。支持多种基线类型（CSS中也有对应概念），MDN上有一张图可以很好地表示文本基线和文本垂直位置的关系。 **maxWidth**： maxWidth表示文本内容占据的最大宽度。这里的maxWidth概念和CSS中的max-width差别很大，其最终的文本表现是：当文本占据宽度超过maxWidth的后，所有的文本自动变窄以适应这个最大宽度限制。表现类似这样： canvas 如何实现文本首行缩进、自动换行、内容过多省略号呢？ 虽然到目前为止，canvas API中还并没有提供文本首行、自动换行、内容过多以省略号结束等的支持，但还是可以通过计算X Y偏移量来实现的。
首行缩进 对于文本首行缩进，也就是在首行空出相对应的字符个数的空白位置，从而使得与其它行在视觉上达到了缩进的效果。
那么，canvas要想绘制出如css那样的首行缩进的文本样式效果，只需将X水平向右偏移相应的像素（pixel）即可。
内容过多以省略号结尾 无论是海报，还是书本的封面，总不肯多写几个字，倒像是一个惜字如命的家伙，生怕自己写多了，给自个儿带来了寿命减少几秒钟的担忧。那么，这时候，省略号这时候便闪亮登场了，很好地诠释着这一足够吸引用户眼球的重要任务。
而在canvas绘制文本时，只需判断是否绘制到文本的最后，若是，便在最后给原有文本追加上...即可。
自动换行 相对于首行缩进来讲，canvas要想实现文本自动换行，不单单只是计算X水平偏移量那么简单咯！
而还要计算Y纵向（垂直）偏移量，为了让你能够理解Y纵向偏移，我举个通俗的例子，我们平时不管是拿笔在纸上写字，还是在电子设备上敲击着文字，文本内容无不是由上而下、自上而下、从上而下的顺序呈现在我们的面前。由于纸或电子设备的宽度所限制，文本不得不另起一行，而这另起一行与之前的一行，就存在着纵向关系——另起一行是在之前的一行的下面（下方/ under），而之前的一行则就在另起一行的上方（上面 / upper）。
在实现自动换行这一效果时，我们应考虑到canvas该如何知道绘制当前在哪个位置（X水平位置）确需另起一行呢？这一点很重要，也是实现canvas自动换行的核心所在。
还是拿我们在纸张上写字或在电子设备上敲击文本时，我们知道换行（那是由于在纸张写的字大小差不多，一行只能容纳这么多文字）或电子设备设定好了字体大小，以此来推算出你写到哪个文字时，让你另起一行。
那么，canvas实现自动换行可以通过计算文字字体大小`及纵向（Y）偏移量的。
canvas提供了CanvasRenderingContext2D.measureText(text)这个API，它可以用来计算字符的宽度。
canvas 是以左上角为原点，也就是说，X轴 水平向右是`正数`，反之亦然；Y 轴纵向则是以向下为`正数`，反向则负。要让canvas知道该在哪个位置自动换行，只需将文本的每个字符宽度进行累加，判断总字符宽度是否达到了canvas所设定的画布宽度，若是，则另起一行继续绘制剩余的文本字符，当然咯，在另起一行时，纵向 Y偏移量是要往下移动。</description></item><item><title>其实，低成本甚至免费的，也是可以搭建个人网站的哦！</title><link>https://qiucode.cn/article/204/</link><pubDate>Fri, 26 Jul 2024 12:46:43 +0800</pubDate><guid>https://qiucode.cn/article/204/</guid><description>在日新月异的互联网浪潮下，想要搭建一个网站，已不再需要花费高昂的IDC 服务器费用以及人员维护等其他费用（相对于公有云来讲）。
身为一名IT、Coder（码农或程序员），对于搭建一个网站的过程，是在清楚不过的了。那就是搭建网站所需的三要素（三兄弟）——服务器、一套程序、域名。
云计算的崛起，致使越来越多的人上云体验了一把，与此同时，个人网站如雨后春笋般拔地而起，网站类型可谓是五花八门。（当然咯，云计算没出现之前，也是有人搭建个人网站，只是那高昂的IDC服务器，并不是每个人都愿意花那高昂的IDC服务器费）。
虽然云计算的云服务器对IDC服务器造成了巨大冲击，但摆在你我眼前的云服务器费用，着实不低啊！（国内各大云厂商为了抢占用户，不惜打起了价格仗，你我索性从中薅起了羊毛，虽然你我深知这羊毛终究是出自羊身上的）。
服务器（云服务器） 想要搭建一个网站，服务器（云服务器）是少不了的。毕竟网站也是程序编写出来的，而程序是需要编译 、运行的，很显然，服务器正扮演着运行这套网站程序的角色。
你我都知道，在云计算之前，想要搭建一个网站，光是租用IDC服务器的费用，就可能让你望而却步了。
可当云计算的到来，个人拥有一个网站，已不再是那么遥不可及（虽然，在这之前，个人也是可以搭建起网站的），毕竟，云服务器费用相比于IDC服务器费用不知便宜了多少（至少在搭建网站的预算降低），促使大多数人蜂拥而上云。
国内的云厂商，诸如，阿里云、腾讯云、华为云、京东云、百度云等（还有很多没列出来的小众云厂商），对新用户都有优惠活动（毕竟，他们为了抢用户，豁出去了），反之，老用户就享受不了那优惠活动了，虽然有吧！但显然优惠力度不是很大。
也正是由于国内各大云厂商领进新用户，而在该云厂商平台但凡购买了新用户优惠活动的云计算产品（如：云服务器）之后，你的身份自然而然地由新用户转变成老用户。可当你云服务器到期时（云服务器到期是指：云计算产品分 按时计费、按量计费，而云服务器是属于按时计费，它又细分为按月、按年），想要续费，那费用瞬间翻了好几倍啊！你一度怀疑，同等配置的云产品为什么在续费时会如此高昂呢？该不会是云厂商想要从新用户变为老用户身份的你，补足当初以优惠力度让入驻该云厂商平台的款项呢？
这也就是为什么，你常常点开一个个人网站（个人博客网站）时，不是出现了网站正在维护中……，便是该网站无法访问的情形。无非是数据迁移到新的服务器上去，或是不再为服务器续费，也不去其他新的云厂商购买云服务器了。
云服务器续费让人望而兴叹，纵使在其他云计算厂商以新用户的优惠价格买到了心仪的云服务器，将网站数据迁移到新服务器上，使得网站得以续命生存下去，虽然这不失为一种办法（薅云厂商的羊毛）。
但绝大多数人的做法是，云服务器到期了，便不再续费了（当然咯，这其中就包括 秋码记录），也没到新的云计算厂商购买新云服务器。而是去购买价格低廉的VPS（虚拟主机）。
由于VPS配置不高，空间不大等，在价格方面，足以碾压云服务器。故而成了很多站长的“首选”，从而解决了站长在云服务器续费与不续费之间、不续费与到其他云计算厂商购买新云服务器之间左右摇摆的困惑。（国内VPS有 帮瓦工……，国外倒是有很多，Hosting、freehost，还可以申请免费的VPS）。
虚拟主机的低配置、小空间，迫使了它只能运载些体量不是很大的网站程序（诸如个人博客、论坛、社区等）。
serverless 谈到serverless或许你会陌生，可一讲到github pages，想必你是知道的了。（github pages可以托管你的静态网站，如 秋码记录 )。
serverless相对于服务器而言，它便是无需服务器。
纵使github在国内访问速度不佳，也鲜有人去使用国内gitee pages（gitee.com提供的pages服务）、coding.net pages(腾讯旗下的代码托管平台)等，这其中的原因，不用我说，你自然也会懂得，这就好比，家楼下有生鲜超市，可你却不愿在那里买，宁愿去十公里外的大型商场买（这里包括但不限于顾客的口碑、以及以次充好等小伎俩，蒙骗顾客）。
网站程序 无论你是买了云服务器，还是选择了低廉的VPS，亦或是采用了serverless这种模式，搭建网站的程序你总该要有的吧（这时你迫不及待的大声嚷道：”谁说搭建网站，就非得需要程序了，一键云建站了解下，不但不需要什么网站程序，就连部署网站的运维人员也省了……“。这里我不禁打断你的话，指出了其中要害，”没错，一键云建站确实给你带来了便利，但你有没去考察过，使用云模板一键建站的都是些企业门户网站，个人博客、论坛、社区是不能用这个，第一，模板风格老套、重叠，第二，在费用方面觉不亚于云服务器“）
也不是说云模板建站有什么不好，可千篇一律的模板终将不适合来搭建个人博客、论坛、社区网站，虽说这些网站也在套用同一个程序，而使得网站又是千人一面，但他们却都不去使用云模板一键建站（其中缘由你该是懂得，若你不懂，执意要云模板一键建站，那就去试一试吧，也只有在试过了，你才会长大、明白）。或许你会问，”为什么你知道这些呢？你是不是使用过云模板一键建站呢？“在这里，我可以很肯定的对你说，”有些事情，并不是需要去试验才会明白的，而是靠理性的判断，以及绝大多数人为何不去使用它的思虑“。
即便网上充斥着大量的个人博客、论坛、社区等的开源程序，然而身为Coder（码农或程序员）的你，总是喜欢使用自己常用的编程语言（program language）从头开始编写，或是在开源程序的基础上进行二次开发，增加些自己独特的想法。
网站程序从头开始编写，不单单是Coder为了在他人面前炫技外，更重要的是Coder想把编程知识巩固起来。
而那些非Coder的外行人，是不会什么编程的，也就谈不上什么从头开始编写网站程序了，他们大多去找些既好看又开源的主题（theme）来构建自己的网站。
闻名于海内外的wordpress就是一个强大的开源程序，使用它可以任何形式的网站，如：电商网站、视频网站、企业门户、新闻网站、个人博客、论坛、社区等，主要还是取决于主题（theme）的搭配。
除了大名鼎鼎的wordpress外，还有国内的typecho、Zblog等，都是可以搭配主题（theme)。
无独有偶，秋码记录 则是使用海外知名的Hugo构建，而主题（theme）则是使用了开源的 Hugo-theme-kiwi ,托管于github pages上。
域名 其实，搭建一个网站，域名并不是必选项，那是因为可以使用ip进行访问，可一大推数字总没有 qiucode.cn 来的好记吧，这使得域名作为公网ip的别名而存在。
在上面讲诉了服务器、网站程序都有免费方案，那么域名是否也有呢？没错，域名也是有的，但都是些二级域名，诸如海外的js.org、eu.org等（如你网站想叫qiucode，那么免费二级域名便是qiucode.js.org`qiucode.eu.org`)。
国内免费的二级域名也是有的，同样也是很少人去使用的，正如serverless一样，人们宁愿去使用github pages，也不肯去国内那些serverless上。
也不是刻意的贬低国内这些互联网，而是他们的那些做法寒了人们的心。就拿百度搜索来说吧，先前我可是百度搜索的忠实用户啊！然而现在却再也不用百度搜索了，改用必应。（其中原有不细说，你总该是明白的）。
综上所诉，想要搭建一个网站，低成本甚至免费的方案都有的。
低成本方案一：虚主机（VPS) + 开源程序 + 免费的二级域名，费用用在了租用虚拟主机（VPS)上。
低成本方案二：虚拟主机（VPS）+ 开源程序 + 顶级域名，费用花在了虚拟主机（VPS）和购买域名上。
低成本方案三： serverless + 开源程序 + 顶级域名，费用花在了购买顶级域名上（秋码记录 就是选用这个方案）。</description></item><item><title>腾讯云COS托管静态网站，以及如何解决访问出现了下载网页的情况</title><link>https://qiucode.cn/article/203/</link><pubDate>Fri, 19 Jul 2024 19:46:43 +0800</pubDate><guid>https://qiucode.cn/article/203/</guid><description>腾讯云对象存储（Cloud Object Storage，简称COS），与其他云厂商所提供的云对象存储都是面向非结构化数据，只是每个云厂商的叫法有别于他家，或许是更能彰显厂商的品牌吧！
但不管云厂商怎么给云对象存储起名，最终客户关心的还是性价比。
使用云对象存储，无非是存放些静态资源（javascript 第三方库、项目中内部的javascript文件、样式文件css、字体文件、小图标等），以此来减轻服务器所承载的压力，从而使得整个站点让用户体验效果显著提升了。
然而，本文要讲的是，怎么样在云对象存储中托管静态网站（这虽然听起来有点可笑，这年头，谁还玩静态网站啊。你也别笑，秋码记录 就是一个很好的静态网站的例子，它也的确是静态网站，可它却具有了与用户交流的文章评论`功能！）
当然咯，云对象存储用来托管静态网站，也只是在开发、测试阶段，毕竟大流量的情况下，费用那是不可估量的！
创建存储捅 对于存储捅这个名词，刚刚说了，每个云厂商的叫法不同而已。
首先，进入腾讯云-》控制台（在这之前，你当然得购买了腾讯云 COS），创建存储捅，名称随便填写，在访问权限选择公共读私有写。
而后，服务端加密这一项，选择SSE-COS（看着名称，估计是腾讯云又仿造他人什么的吧！）
就这样，腾讯云COS就创建成功了，之后便可以上传你的静态资源到这个对象捅里了。
配置静态网站 既然，我们使用COS来托管静态网站，那么是少不了些必要的配置，比如开启静态网站`开关等等。
在左侧导航栏中找到基础配置，随后在其子项的静态网站开启静态网站的配置。（感觉在绕口令似的，其实，不关你是这么觉，我也这么觉得。）
绑定自定义域名 同样的，还是在左侧导航栏，找到域名与传输管理这一泪目，点开它底下的自项，点击自定义绑定域名。
在绑定自定义域名之前，你得先确认你刚购买的COS区域是国内的，还是非国内的，若是国内区域的COS，那么你绑定自定义域名时，这个自定义域名是需要备案的。当然咯，COS购买时选择的是香港区域，自定义域名是不需要备案的哦！
浏览器访问托管的静态网站却下载了文件 很不辛，在你配置了存储捅的静态网站，上传了所有的静态资源后，兴致勃勃地打开浏览器，你以为页面能够如期的展示你所希望的样子，然而，历史性的一刻，让你瞬间愕然，这是怎么回事呢？怎么就直接下载了页面文件（也就是下载当前的index.html`文件）？这到底是哪个环节出了问题？
然而，你是按着官方文档来着，并且文档上也是这么做的，中间也没有遗漏些什么重要配置啊！（关键是也没什么重要配置，充其量就是开启了静态网站的开关）。
于是，你借助搜索引擎的强大搜寻功能，找找看，到底有没有解决办法（也就是别人在COS托管静态网站时，对于访问时出现下载文件`是怎么处理的）。
不搜不知道，一搜可谓是天下知。使用COS（也有其他云厂商的）托管静态网站的博文、帖子、论坛还真不少，你点开一看，他们与你的静态网站配置如出一辙，他们也同样出现了你所出现的问题（没把你绕进去吧，也就是他们跟你一样，在浏览器访问也出现了下载index.html文件。）
最终，解决办法便是在刚刚上传的index.html,点击右上角的...，在上弹出的列表项中，再次点击自定义头部
当你看到这个对话框，你或许就该恍然大悟了，也总算明白了，为什么浏览器访问会出现下载 index.html的情况了吧！毕竟，腾讯云默认将你上传的文件头部定义为text/html。
我们点击编辑来修改这个index.html文件表头。
在参数选择下拉框中选中Content-Disposition,值是手动输入inline.
现在，你再次打开浏览器进行访问，这回，展现在你眼前的，便是你所期望的页面展示了。
可当你回过头，再去查看index.html头部信息时，却发现它自动的加上初始的那个Header信息，这时，你不禁啐了一口，“腾讯云，真TMD恶心，哦！不，国内的这些云厂商都TMD超恶心”。
当然咯，不管是腾讯云COS，还是其他国内云厂商，想要使用云对象存储来托管静态网站还是比较，怎么说呢！用来开发、测试勉强还凑合吧！</description></item><item><title>错误分析 （Machine Learning 研习十九）</title><link>https://qiucode.cn/article/199/</link><pubDate>Wed, 10 Apr 2024 11:12:43 +0800</pubDate><guid>https://qiucode.cn/article/199/</guid><description>错误分析 您将探索数据准备选项，尝试多个模型，筛选出最佳模型，使用 Grid SearchCV微调其超参数，并尽可能实现自动化。在此，我们假设您已经找到了一个有前途的模型，并希望找到改进它的方法。其中一种方法就是分析它所犯的错误类型。
首先，查看混淆矩阵。为此，首先需要使用 cross_val_predict() 函数进行预测；然后可以像之前一样，将标签和预测值传递给 confusion_matrix()函数。不过，由于现在有 10 个类别而不是 2 个，混淆矩阵将包含大量数字，可能难以读取。
混淆矩阵的彩色图更容易分析。要绘制这样的图表，请使用ConfusionMatrixDisplay.from_predictions() 函数，如下所示：
from sklearn.metrics import ConfusionMatrixDisplayy_train_pred = cross_val_predict(sgd_clf, X_train_scaled, y_train, cv=3) ConfusionMatrixDisplay.from_predictions(y_train, y_train_pred) plt.show() 这就产生了 图1 中的左图。这个混淆矩阵看起来相当不错：大多数图像都在主对角线上，这意味着它们被正确分类了。请注意，对角线上第 5 行第 5 列的单元格看起来比其他数字略暗。这可能是因为模型对 5 的错误较多，也可能是因为数据集中 5 的数量比其他数字少。这就是为什么要对混淆矩阵进行归一化处理，将每个值除以相应（真实）类别中的图像总数（即除以行的总和）。只需设置 normalize=&amp;quot;true &amp;quot;即可。我们还可以指定 val ues_format=&amp;quot;.0%&amp;quot;参数来显示不带小数点的百分比。下面的代码将生成 图1 右侧的图表：
ConfusionMatrixDisplay.from_predictions(y_train, y_train_pred, normalize=&amp;#34;true&amp;#34;, values_format=&amp;#34;.0%&amp;#34;) plt.show() 现在我们不难发现，只有 82% 的 5 图像被正确分类。模型在处理 5 的图像时最常见的错误是将其误判为 8：在所有 5 的图像中，有 10%的图像被误判为 8。但只有 2% 的 8 被误判为 5；混淆矩阵通常不是对称的！如果你仔细观察，就会发现很多数字都被错误地分类为 8，但从这张图上并不能一眼看出。如果想让错误更明显，可以尝试将正确预测的权重设为零。下面的代码就是这样做的，并生成了图2 左侧的图表：
sample_weight = (y_train_pred !</description></item><item><title>多类别分类器（Machine Learning 研习十八）</title><link>https://qiucode.cn/article/198/</link><pubDate>Wed, 03 Apr 2024 15:43:43 +0800</pubDate><guid>https://qiucode.cn/article/198/</guid><description>多类别分类器 二元分类器可以区分两个类别，而多类别分类器（也称为多叉分类器）可以区分两个以上的类别。
一些 Scikit-Learn 分类器（如 LogisticRegression、RandomForestClassifier 和 GaussianNB）能够原生处理多个类别。其他分类器则是严格的二进制分类器（如 SGDClassifier 和 SVC）。不过，您可以使用多种策略来使用多个二进制分类器执行多类分类。
要创建一个能将数字图像分为 10 类（从 0 到 9）的系统，一种方法是训练 10 个二进制分类器，每个数字一个（0-检测器、1-检测器、2-检测器，以此类推）。然后，当您想对一幅图像进行分类时，您可以从每个分类器中得到该图像的判定分数，然后选择分类器输出分数最高的类别。这就是所谓的 &amp;ldquo;以一敌百&amp;rdquo;（OvR）策略，有时也称为 &amp;ldquo;以一敌众&amp;rdquo;（OvA）策略。
另一种策略是为每一对数字训练一个二元分类器：一个用于区分 0 和 1，另一个用于区分 0 和 2，还有一个用于区分 1 和 2，以此类推。这就是所谓的一对一（OvO）策略。如果有 N 个类别，则需要训练 N × (N - 1) / 2 个分类器。对于 MNIST 问题，这意味着要训练 45 个二进制分类器！当你想对一幅图像进行分类时，你必须让图像通过所有 45 个分类器，看看哪个分类器赢得了最多的对决。OvO 的主要优势在于，每个分类器只需在训练集中包含其必须区分的两个类别的部分进行训练。
有些算法（如支持向量机分类器）随训练集的大小而缩放，效果不佳。对于这些算法，OvO 是首选，因为在小训练集上训练多个分类器比在大训练集上训练少数分类器更快。不过，对于大多数二元分类算法来说，OvR 是首选。
Scikit-Learn 会检测你是否尝试在多分类任务中使用二元分类算法，并根据算法自动运行 OvR 或 OvO。让我们使用 sklearn.svm.SVC 类支持向量机分类器来尝试一下。我们只对前 2,000 张图像进行训练，否则会耗费很长时间：
from sklearn.svm import SVC svm_clf = SVC(random_state=42) svm_clf.fit(X_train[:2000], y_train[:2000]) # y_train, not y_train_5 我们使用从 0 到 9 的原始目标类别（y_train），而不是 5 对其余目标类别（y_train_5）来训练 SVC。由于有 10 个类别（即多于 2 个），Scikit-Learn 使用 OvO 策略训练了 45 个二元分类器。现在，让我们对一幅图像进行预测：</description></item><item><title>使用CSS计数器，在目录名称前加上了序号，让目录看起来更加井然有序</title><link>https://qiucode.cn/article/202/</link><pubDate>Mon, 01 Apr 2024 15:46:43 +0800</pubDate><guid>https://qiucode.cn/article/202/</guid><description>目录（Text of Contents缩写为TOC），其实就是一篇文章的概要或简述。这好比，去书店买书，先是被这本书的标题所吸引，而后我们才会，翻开这本书目录，看看这本书主要是在讲些什么？我们在看目录的同时，脑中也在不停的思衬，”这本书到底值不值得买呢？但是没有什么实战内容耶！“
文章目录 其实，一篇文章也不非要目录的，只要段落分的好，就算是长篇大论也是无关紧要的！
只是文章有了目录，让人一眼就能瞧出这篇文章到底讲了什么？虽然标题上有说，但还是得为哪几个段落起个副标题。
再说了，文章目录可以让用户在页面上，点击到达指定目录名称下进行浏览。虽然这在很大层度上是可以通过鼠标滑动，滚动到想要浏览的位置。
Hugo-theme-kiwi开源博客主题已然有了文章目录这一功能，也就是 秋码记录 站点正在使用的博客主题（由于 秋码记录 托管于 Github.com Pages，故而国内的友人在访问时，比较缓慢，甚至有时可能出现无法打开该网站）。
对目录名称前添加序号，我们首先想到的当然是使用Hugo模板渲染去实现。
序号，顾名思义，就是有顺序的号码，通俗来讲，便是1、，2、，3、，4、，……。可在Hugo模板渲染中使用计数器来实现。
css计数器 或许也只有在使用了CSS 计数器后，你就会摒弃代码中使用Hugo模板渲染的那部分又长又拖代码了。
在CSS计数器中，counter-reset和counter-increment属性是必不可少的。counter-reset在每次新的列表开始时重置计数器，而counter-increment在每个列表项上增加计数器。
需要注意的是：counter-reset 是需要计数的父标签上的！
那么，就将 counter-reset设置在ol标签上即可，即便是某一项有子目录，那也还是在ol标签内的！
.toc-content ol{ list-style-type: none; counter-reset: item } 现在，我们就可以对目录名称设置伪选择器了。
在编写CSS样式之前，有必要说下counters()函数，在CSS中，它返回一个计数器的列表值，这个列表可以包含一个或者多个嵌套的计数器。
函数counters()有两个参数：
第一个参数是你要访问的计数器的名称，在你的例子中，该名称就是 item。 第二个参数是字符串，用来分隔计数器的各个级别。在你的例子中，这个分隔符是英文的句点 . .toc-content ol li a:first-of-type::before{ counter-increment: item; content: counters(item,&amp;#34;.&amp;#34;)&amp;#34;、&amp;#34;; font-weight: 700; margin-right: 1px; } 比如在多级嵌套的列表中，如果在第一级的第二个项中的第三个小项，那么 counters() 的值就会是 2.3、。
字符串、 紧接着 counters(item, &amp;quot;.&amp;quot;) 的作用是将结果后面添加一个顿号，使其格式化输出更美观。
所以 counters(item, &amp;quot;.&amp;quot;) &amp;quot;. &amp;quot; 的作用就是生成并显示一个根据当前嵌套列表项的层级和序号构成的数字序列，每一级数字之间用句点分隔，并在最后跟着一个顿号。例如输出1、，2.1、，2.2、，等等。
最终效果可查看秋码记录文章详情页，右侧侧边栏目录。</description></item><item><title>使用 golang 以及 Gin 框架，将上传的图片在不保存至本地的情况下添加水印，并上传至阿里云 OSS</title><link>https://qiucode.cn/article/201/</link><pubDate>Sat, 30 Mar 2024 20:46:43 +0800</pubDate><guid>https://qiucode.cn/article/201/</guid><description>正如标题所述，使用golang对上传图片添加水印，以及将图片上传到阿里云OSS，网上一搜索，便有你想要的结果了，可是，他们却先将上传图片添加水印后保存在本地，而后再将添加了水印的图片上传到阿里云OSS。
这无疑是暂时占用了你电脑的磁盘空间（这里说是暂时，因为你可以通过程序对上传到阿里云OSS成功的图片进行删除），即便是这样，它也是消耗了磁盘读写操作，虽然人类是察觉不到这么细微的变化。
然而，作为技术人员的我们（不介意我这么称呼自己吧！），使能够Review出这段程序的问题。很显然，本地图片是要通过程序处理，添加水印，而后最终储存到阿里云OSS中，而不是又要在本地多存了一张比原图多了些水印的图片。
图像处理库 既然我们的目的明确了，那么就卷起柚子加油干吧！
虽然，使用golang对上传图片添加水印，以及如何将图片上传到阿里云OSS中，是两个独立分开的。但是，这两步看似分而食之的程序，其实是可以合二为一的！（我想，正在浏览本文的你，也是这么想的！）
这是可行的方案，毕竟先前的秋码记录 就是这么做的（那是使用Java构建的那些年！当然现在的 秋码记录 改用 ```Hugo·``搭建了）。
既然，java能实现对上传图片添加水印，而不暂时保存在本地，立马即可上传到阿里云OSS中。想必，golang也是可以完成的！
然而，网上相关的资料有限，才能铸就本文的诞生！
首先，我是用golang的版本是1.19，虽然不是最新的，但却不妨碍我们继续对本文的讲解。
虽然，人类总是对新鲜事物充满好奇，从而萌生了猎奇心。但也只有在旧事物的烘衬下，人们才能对新事物寄以最大的希望！这就好比，老婆总是别人的好看（当然，别人的老婆也有没有自己老婆好看的），这才造就了黄脸婆这一全国男人在没有老婆在身旁统一叹息声！
你得在你电脑任一磁盘下，新建一空文件夹，随后打开黑窗口（Terminal），输入以下命令，说明是modules进行管理的（毕竟我使用的是golang 1.19）：
go mod init qiucode.cn/uploadImage 对于以上这行命令，就是初始化golang模块（module），在golang的世界是```万物皆可模块``（我说的如果不对，那么说出你的想法）。
初始化项目后，我们会发现文件夹下多了个go.mod文件（这个就是用来管理第三方依赖库的管理文件，不需要操作！），在该同级目录下新建main.go文件。
既然本文是探讨如何实现图片添加水印的，那么引入图像库那是必不可少的！
go get github.com/fogleman/gg 本文不会对这个图像库进行深层次的讲解！毕竟本文的核心内容是介绍如何对图片添加水印，而不是避重就轻、本末倒置讲起了本该一笔带过的东西，却花了浓墨重彩去着重的描绘刻画它，到头来，却失了初心，乱了本文的主旨，实属不该。（实在不清楚的，可以去查看其文档）
很显然，将图片上传到阿里云OSS上，引入其SDK，那是必不可少的（关于这一点，应该不需要我多费口舌了吧）
go get github.com/aliyun/aliyun-oss-go-sdk/oss 接下来的这个依赖库，并不是必须的（那就是可选的），毕竟，有它没有它，本文都可以实现！
go get github.com/gin-gonic/gin 是啊！都说了，不引入它，本文也可以实现，那么我为什么还引入了呢？（关于这一点，欢迎你能在评论中留下你的只言片语，请不要吝啬你的文字！）
用代码实现标题的需求 前提准备工作就绪，我们该正式进入编码环节了。到了这里，正处于屏幕前的你，想必早就迫不及待了吧！毕竟，你就是与我有同样的需求，才会浏览本文的（当然也有那种，鼠标不小心点到了，但那种几率是很小的，我相信你不是属于那一类的）
首先，我们使用VS Code（你也可以使用其他你平时常用的IDE，不必非要使用与我一样的VS Code，然而，作为一款开源免费的IDE，你还有什么理由不去使用它呢？哦，差点忘记了，都说了，使用IDE是个人的自由，可我这么一说，倒有了让你使用VS Code之嫌。虽然，或许你比较喜欢使用收费软件，但你都是找的破解方法来破解软件，从而使用它们）
打开刚刚新建的main.go文件，开始逐步实现标题的需求。
package main import ( &amp;#34;bytes&amp;#34; &amp;#34;image&amp;#34; &amp;#34;image/png&amp;#34; // &amp;#34;image/jepg&amp;#34; //用于对 jpg 格式的图片进行处理 本文暂时不对 jpg 图片做处理 &amp;#34;github.com/gin-gonic/gin&amp;#34; //web 框架 &amp;#34;github.com/fogleman/gg&amp;#34; // 图像处理哭 &amp;#34;github.com/aliyun/aliyun-oss-go-sdk/oss&amp;#34; //阿里云OSS SDK ) 随后，我们在main函数中实现标题中的需求。</description></item><item><title>绘制特征曲线-ROC（Machine Learning 研习十七）</title><link>https://qiucode.cn/article/197/</link><pubDate>Fri, 29 Mar 2024 11:43:43 +0800</pubDate><guid>https://qiucode.cn/article/197/</guid><description>接收者操作特征曲线（ROC）是二元分类器的另一个常用工具。它与精确度/召回率曲线非常相似，但 ROC 曲线不是绘制精确度与召回率的关系曲线，而是绘制真阳性率（召回率的另一个名称）与假阳性率（FPR）的关系曲线。FPR（也称 &amp;ldquo;下降率&amp;rdquo;）是阴性实例被错误归类为阳性实例的比率。它等于 1 - 真阴性率 (TNR)，即正确分类为阴性的阴性实例的比率。TNR 也称为特异性。因此，ROC 曲线是灵敏度（召回率）与 1 - 特异性的关系图
要绘制 ROC 曲线，首先要使用 roc_curve() 函数计算不同阈值的 TPR 和 FPR：
from sklearn.metrics import roc_curve fpr, tpr, thresholds = roc_curve(y_train_5, y_scores) 然后可以使用 Matplotlib 绘制 FPR 与 TPR 的对比图。下面的代码可以绘制出 见下图 所示的图形。要找到与 90% 精度相对应的点，我们需要查找所需阈值的索引。由于在这种情况下阈值是按递减顺序排列的，因此我们在第一行使用 &amp;lt;= 而不是 &amp;gt;=：
idx_for_threshold_at_90 = (thresholds &amp;lt;= threshold_for_90_precision).argmax() tpr_90, fpr_90 = tpr[idx_for_threshold_at_90], fpr[idx_for_threshold_at_90] plt.plot(fpr, tpr, linewidth=2, label=&amp;#34;ROC curve&amp;#34;) plt.plot([0, 1], [0, 1], &amp;#39;k:&amp;#39;, label=&amp;#34;Random classifier&amp;#39;s ROC curve&amp;#34;) plt.plot([fpr_90], [tpr_90], &amp;#34;ko&amp;#34;, label=&amp;#34;Threshold for 90% precision&amp;#34;) [.</description></item><item><title>网站引入 Prism，使得代码高亮显示，并一键复制代码块</title><link>https://qiucode.cn/article/200/</link><pubDate>Sat, 23 Mar 2024 15:06:43 +0800</pubDate><guid>https://qiucode.cn/article/200/</guid><description>曾几何时，苦恼如何将本地写好的博文，更好的展示读者屏幕前？若只是简简单单的文章，其实还是很好的解决它的！可是，像我们这样写技术文章（有点牵强）的，在文章内容嵌入部分代码是在所难免的。
然而，由于没能将代码与文本区分开来，致使两者混在一起，分不出彼此。由此给读者带来了视觉上得不适，它并没有很好的像代码编辑器那样高亮。
下载 Prism 虽然市面上能让代码块高亮显示，远不止Prism这一款，而我又为什么选择这一款呢？这的确是个好问题，然而我只能回答您的是，它功能比较强大吧！（或许您还不能信服），这就好比是情人眼里出西施，您的老婆/老公或女朋友/男朋友长得不是那么美/那么帅（或许您在某一瞬间也是这么觉得），但是，您不还是选择了她/他吗？即便是，您和伴侣在逛街时，迎面走来一位身材高挑的美女/帅哥，想必您的伴侣是在您不经意间，偷瞄了一眼。
进入prism官网下载：
https://prismjs.com/download.html#themes=prism&amp;amp;languages=markup+css+clike+javascript
随后，我们在项目中引入Prism.css样式文件。
&amp;lt;link href=&amp;#34;themes/prism.css&amp;#34; rel=&amp;#34;stylesheet&amp;#34; /&amp;gt; 以及Prism.js文件。
&amp;lt;script src=&amp;#34;prism.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt; 当然咯，您的代码块是需要使用&amp;lt;pre&amp;gt;和&amp;lt;code class=&amp;quot;language-*&amp;quot;标签。
&amp;lt;pre&amp;gt;&amp;lt;code class=&amp;#34;language-html&amp;#34;&amp;gt; &amp;lt;link href=&amp;#34;themes/prism.css&amp;#34; rel=&amp;#34;stylesheet&amp;#34; /&amp;gt; &amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt; 添加 clipboard 复制代码按钮 若是有一点按钮就可以复制这段代码，想必应该是没有人会再去用鼠标去滑动选择代码，然后右键，选择复制选项，或者直接按住键盘上的Ctrl + C。
首先，想要在项目中添加clipboard功能，那么，就显得下载它，这是毋庸置疑的！
当然，我们还是到Prism官网下载它，
在项目中引入：
&amp;lt;script src=&amp;#34;plugins/clipboard.js&amp;#34;&amp;gt;&amp;lt;/script&amp;gt; Hugo-theme-kiwi 中引入 Prism 首先，我们在Hugo-theme-kiwi主题的head.html文件引入blackmac.css样式文件。
&amp;lt;link rel=&amp;#34;stylesheet&amp;#34; href=&amp;#34;{{ .Site.BaseURL }}css/blackmac.css&amp;#34;&amp;gt; blackmac.css文件内容如下：
code[class*=&amp;#34;language-&amp;#34;],pre[class*=&amp;#34;language-&amp;#34;]{color:#f8f8f2;background:#313238;text-shadow:0 1px rgba(0,0,0,.3);font-family:Consolas,Monaco,&amp;#39;Andale Mono&amp;#39;,&amp;#39;Ubuntu Mono&amp;#39;,monospace;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:2;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}pre[class*=&amp;#34;language-&amp;#34;]{padding:.5em;margin:.5em 0;overflow:auto;}:not(pre)&amp;gt;code[class*=&amp;#34;language-&amp;#34;],pre[class*=&amp;#34;language-&amp;#34;]{background:#21252a}:not(pre)&amp;gt;code[class*=&amp;#34;language-&amp;#34;]{padding:.1em;border-radius:.3em;white-space:normal}.token.comment,.token.block-comment,.token.prolog,.token.doctype,.token.cdata{color:#999;}.token.punctuation{color:#ccc;}.token.tag,.token.attr-name,.token.namespace,.token.deleted{color:#e2777a;}.token.function-name{color:#6196cc;}.token.boolean,.token.number,.token.function{color:#f08d49;}.token.property,.token.class-name,.token.constant,.token.symbol{color:#f8c555;}.token.selector,.token.important,.token.atrule,.token.keyword,.token.builtin{color:#cc99cd;}.token.string,.token.char,.token.attr-value,.token.regex,.token.variable{color:#7ec699;}.token.operator,.token.entity,.token.url{color:#67cdcc;}.token.important,.token.bold{font-weight:bold;}.token.italic{font-style:italic;}.token.entity{cursor:help;}.token.inserted{color:green;}pre.line-numbers{padding-bottom:.8em;padding-left:3.3em;counter-reset:linenumber}pre.line-numbers&amp;gt;code{white-space:inherit font-size:15px}.line-numbers .line-numbers-rows{position:absolute;pointer-events:none;top:3em;font-size:100%;left:-0.1em;width:3em;letter-spacing:-1px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.line-numbers-rows&amp;gt;span{pointer-events:none;display:block;counter-increment:linenumber}.line-numbers-rows&amp;gt;span:before{content:counter(linenumber);color:#999;display:block;padding-right:.9em;text-align:right;background:#272c33}div.code-toolbar{font-size:100%;border-radius:4px;position:relative;box-shadow:0 0 20px 5px rgba(0,0,0,.4);padding-top:30px;background-color:#161616;margin:20px 0 20px 0}.code-toolbar:before{content:&amp;#34; &amp;#34;;position:absolute;-webkit-border-radius:50%;border-radius:50%;background:#fc625d;width:11px;height:11px;left:10px;top:10px;-webkit-box-shadow:20px 0 #fdbc40,40px 0 #35cd4b;box-shadow:20px 0 #fdbc40,40px 0 #35cd4b;z-index:2}div.code-toolbar&amp;gt;.toolbar{padding-right:.4em;position:absolute;top:.09em;right:.2em;width:100%;text-align:center;}div.code-toolbar:hover&amp;gt;.toolbar{opacity:1}div.code-toolbar&amp;gt;.toolbar .</description></item><item><title>精确率（召回率）的权衡（Machine Learning 研习十六）</title><link>https://qiucode.cn/article/196/</link><pubDate>Thu, 21 Mar 2024 19:43:43 +0800</pubDate><guid>https://qiucode.cn/article/196/</guid><description>精确率（召回率）的权衡 为了理解这种权衡，让我们看看 SGDClassifier 如何做出分类决策。 对于每个实例，它根据决策函数计算分数。 如果该分数大于阈值，则将该实例分配给正类； 否则它会将其分配给负类。 图 3-4 显示了从左侧最低分数到右侧最高分数的几个数字。 假设决策阈值位于中心箭头（两个 5 之间）：您会在该阈值右侧发现 4 个真阳性（实际为 5），以及 1 个假阳性（实际上为 6）。 因此，使用该阈值，精度为 80%（5 分之 4）。 但在 6 个实际的 5 中，分类器仅检测到 4 个，因此召回率为 67%（6 中的 4）。 如果提高阈值（将其移动到右侧的箭头），假阳性（6）会变成真阴性，从而提高精度（在本例中高达 100%），但一个真阳性会变成假阴性 ，将召回率降低至 50%。 相反，降低阈值会增加召回率并降低精确度。
Scikit-Learn 不允许您直接设置阈值，但它允许您访问它用于进行预测的决策分数。 您可以调用其decision_function()方法，而不是调用分类器的predict()方法，该方法返回每个实例的分数，然后使用您想要根据这些分数进行预测的任何阈值：
SGDClassifier 使用等于 0 的阈值，因此前面的代码返回与 Predict() 方法相同的结果（即 True）。 让我们提高门槛：
这证实了提高阈值会降低召回率。 该图像实际上代表的是 5，当阈值为 0 时分类器会检测到它，但当阈值增加到 3,000 时分类器会错过它。
y_scores = cross_val_predict(sgd_clf, X_train, y_train_5, cv=3, method=&amp;#34;decision_function&amp;#34;) 有了这些分数，使用 precision_recall_curve() 函数计算所有可能阈值的精度和召回率（该函数添加最后精度 0 和最后召回率 1，对应于无限阈值）：
from sklearn.</description></item><item><title>对模型性能进行评估（Machine Learning 研习十五）</title><link>https://qiucode.cn/article/195/</link><pubDate>Fri, 15 Mar 2024 18:26:43 +0800</pubDate><guid>https://qiucode.cn/article/195/</guid><description>在上一篇我们已然训练了一个用于对数字图像识别的模型，但我们目前还不知道该模型在识别数字图像效率如何？所以，本文将对该模型进行评估。
使用交叉验证衡量准确性 评估模型的一个好方法是使用交叉验证，让我们使用cross_val_score()函数来评估我们的 SGDClassifier 模型，使用三折的 k 折交叉验证。k-fold 交叉验证意味着将训练集分成 k 个折叠（在本例中是三个），然后训练模型 k 次，每次取出一个不同的折叠进行评估：
当您看到这组数字，是不是感到很兴奋？毕竟所有交叉验证折叠的准确率（预测准确率）均超过了 95%。然而，在您兴奋于这组数字前，还是让我们来看看一个假分类器，它只是将每张图片归入最常见的类别，在本例中就是负类别（即非 5）：
from sklearn.dummy import DummyClassifier dummy_clf = DummyClassifier() dummy_clf.fit(X_train, y_train_5) print(any(dummy_clf.predict(X_train))) # prints False: no 5s detected 您能猜出这个模型的准确度吗？让我们一探究竟：
没错，它的准确率超过 90%！这只是因为只有大约 10% 的图片是 5，所以如果你总是猜测图片不是 5，你就会有大约 90% 的时间是正确的。比诺斯特拉达穆斯还准。
这说明了为什么准确率通常不是分类器的首选性能指标，尤其是在处理偏斜 数据集时（即某些类别的出现频率远高于其他类别）。评估分类器性能的更好方法是查看混淆矩阵(CM)。
实施交叉验证 与 Scikit-Learn 现成提供的功能相比，您有时需要对交叉验证过程进行更多控制。在这种情况下，你可以自己实现交叉验证。下面的代码与 Scikit-Learn 的 cross_val_score() 函数做了大致相同的事情，并会打印出相同的结果：
from sklearn.model_selection import StratifiedKFold from sklearn.base import clone skfolds = StratifiedKFold(n_splits=3) # add shuffle=True if the dataset is # not already shuffled for train_index, test_index in skfolds.</description></item><item><title>图像识别之入门案例之数字识别（Machine Learning 研习十四）</title><link>https://qiucode.cn/article/194/</link><pubDate>Fri, 15 Mar 2024 17:48:03 +0800</pubDate><guid>https://qiucode.cn/article/194/</guid><description>在前面的文章中，我们曾提到最为常见的监督学习任务是回归（预测价值）和分类（预测类别）。我们使用线性回归、决策树和随机森林等各种算法探讨了回归任务，即预测房屋价值。现在，我们将把注意力转向分类系统。
MNIST数据集 我们将使用 MNIST 数据集，这是一组由人类手写的 70,000 张小数字图像。每张图片都标注了所代表的数字。人们对这个数据集的研究非常深入，以至于它经常被称为机器学习的 &amp;ldquo;hello world&amp;rdquo;：每当人们提出一种新的分类算法时，他们都会好奇地想看看这种算法在 MNIST 上的表现如何，而且任何学习机器学习的人迟早都会用到这个数据集。
Scikit-Learn 提供了许多下载流行数据集的辅助函数。MNIST 就是其中之一。以下代码从 OpenML.org 获取 MNIST 数据集：
from sklearn.datasets import fetch_openml mnist = fetch_openml(&amp;#39;mnist_784&amp;#39;, as_frame=False) sklearn.datasets 包主要包含三种类型的函数：fetch_* 函数（如 fetch_openml()）用于下载现实生活中的数据集；load_* 函数用于加载 Scikit-Learn捆绑的小型玩具数据集（因此无需通过互联网下载）；make_* 函数用于生成假数据集，对测试非常有用。生成的数据集通常以 (X, y) 元组的形式返回，其中包含输入数据和目标数据，两者都是 NumPy 数组。其他数据集以 sklearn.utils.Bunch 对象的形式返回，这是一个字典，其条目也可以作为属性访问。它们通常包含以下条目：
&amp;ldquo;DESCR&amp;rdquo;
​ 数据集描述
“data”
​ 输入数据，通常为Numpy二维数组
“target”
​ 标签，通常为Numpy一维数组
fetch_openml() 函数有点不寻常，因为默认情况下，它以 Pandas DataFrame 的形式返回输入，以 Pandas Series 的形式返回标签（除非数据集很稀疏）。但 MNIST 数据集包含图像，而 DataFrame 并不适合图像，因此最好设置 as_frame=False，以 NumPy 数组的形式获取数据。让我们来看看这些数组：
共有 70,000 幅图像，每幅图像有 784 个特征。这是因为每幅图像都是 28 × 28 像素，每个特征只代表一个像素的强度，从 0（白色）到 255（黑色）。让我们来看看数据集中的一个数字（图 3-1）。我们需要做的就是抓取一个实例的特征向量，将其重塑为 28 × 28 数组，然后使用 Matplotlib 的 imshow() 函数显示出来。我们使用 cmap=&amp;quot;binary&amp;quot; 来获取灰度颜色图，其中 0 代表白色，255 代表黑色：</description></item><item><title>微调模型——续（Machine Learning 研习之十三）</title><link>https://qiucode.cn/article/193/</link><pubDate>Sat, 09 Mar 2024 17:45:01 +0800</pubDate><guid>https://qiucode.cn/article/193/</guid><description>集成方法 微调系统的另一种方法是尝试组合性能最佳的模型。 群体（或“整体”）通常会比最好的单个模型表现得更好，就像随机森林比它们所依赖的单个决策树表现更好一样，特别是当各个模型犯下不同类型的错误时。 例如，您可以训练和微调 k 最近邻模型，然后创建一个仅预测随机森林预测和该模型预测的平均值的集成模型。
分析最佳模型及其错误 通过检查最佳模型，您通常会获得对问题的深入见解。 例如，RandomForestRegressor可以指示每个属性对于做出准确预测的相对重要性：
让我们按降序对这些重要性分数进行排序，并将它们显示在相应的属性名称旁边：
有了这些信息，您可能想尝试删除一些不太有用的功能（例如，显然只有一个ocean_proximity类别真正有用，因此您可以尝试删除其他功能）。
您还应该查看系统所犯的具体错误，然后尝试了解为什么会犯这些错误，以及如何解决问题：添加额外的功能或删除无信息的功能，清理异常值等。
现在也是一个好时机，可以确保您的模型不仅平均运行良好，而且适用于所有类别的地区，无论是农村还是城市、富裕还是贫穷、北部还是南部、少数民族还是非少数民族等。 每个类别的验证集需要一些工作，但这很重要：如果您的模型在整个地区类别上表现不佳，那么在问题解决之前可能不应该部署它，或者至少不应该使用它 对该类别进行预测，因为它可能弊大于利。
在测试集上评估您的系统 对模型进行一段时间的调整后，您最终会得到一个性能足够好的系统。 您已准备好在测试集上评估最终模型。 这个过程没有什么特别的； 只需从测试集中获取预测变量和标签并运行Final_model来转换数据并进行预测，然后评估这些预测：
X_test = strat_test_set.drop(&amp;#34;median_house_value&amp;#34;, axis=1) y_test = strat_test_set[&amp;#34;median_house_value&amp;#34;].copy() final_predictions = final_model.predict(X_test) final_rmse = mean_squared_error(y_test, final_predictions, squared=False) print(final_rmse) # prints 41424.40026462184 在某些情况下，这样的泛化误差点估计不足以说服您启动：如果它只比当前生产的模型好 0.1% 怎么办？ 您可能想了解这个估计的精确度。 为此，您可以使用 scipy.stats.t.interval() 计算泛化误差的 95% 置信区间。 您会得到从 39,275 到 43,467 的相当大的区间，而您之前的点估计值 41,424 大致位于中间：
如果您进行了大量的超参数调整，性能通常会比使用交叉验证测量的性能稍差。 这是因为您的系统最终经过微调以在验证数据上表现良好，但在未知数据集上可能表现不佳。 本示例中的情况并非如此，因为测试 RMSE低于验证 RMSE，但当发生这种情况时，您必须抵制调整超参数以使数字在测试集上看起来不错的诱惑； 这些改进不太可能推广到新数据。
现在是项目预启动阶段：您需要展示您的解决方案（突出显示您所学到的内容、有效的内容和无效的内容、做出的假设以及系统的局限性），记录所有内容，并使用以下内容创建精美的演示文稿： 清晰的可视化和易于记忆的陈述（例如，“收入中位数是房价的第一预测指标”）。 在这个加州住房示例中，系统的最终性能并不比专家的价格估计好多少，专家的价格估计通常会下降 30%，但启动它可能仍然是一个好主意，特别是如果这样可以释放更多资金 给专家一些时间，以便他们可以从事更有趣、更有成效的任务。
启动、监控和维护您的系统 您现在需要准备好用于生产的解决方案（例如，完善代码、编写文档和测试等）。 然后您可以将模型部署到生产环境。 最基本的方法就是保存您训练的最佳模型，将文件传输到您的生产环境并加载它。 要保存模型，您可以使用 joblib 库，如下所示：</description></item><item><title>微调模型（Machine Learning 研习之十二）</title><link>https://qiucode.cn/article/192/</link><pubDate>Sat, 09 Mar 2024 14:59:44 +0800</pubDate><guid>https://qiucode.cn/article/192/</guid><description>现在正处于百模乱战的时期，对于模型微调，想必您是有所了解了，毕竟国外的大语言模型一开源，国内便纷纷基于该模型进行微调，从而开始宣称领先于某某、超越了谁。可到头来，却让人发现他们套壳了国外大语言模型对外开放的API。
好了，我们不说国内各种大模型宣称超过了谁，毕竟，嘴巴长在别人脸上，我们管不了，也管不着，吹牛终将是会露馅的！
当我们需要对开源大模型进行微调时，看看有几种方法可以做到这一点的！
网格搜索 手动调整超参数，直到找到超参数值的完美组合。 这将是一项非常乏味的工作，而且您可能没有时间去探索多种组合。
相反，您可以使用 Scikit-Learn 的 GridSearchCV 类来搜索您。 您需要做的就是告诉它您希望它试验哪些超参数以及要尝试哪些值，它将使用交叉验证来评估超参数值的所有可能组合。 例如，以下代码搜索 RandomForestRegressor 的最佳超参数值组合：
from sklearn.model_selection import GridSearchCV full_pipeline = Pipeline([ (&amp;#34;preprocessing&amp;#34;, preprocessing), (&amp;#34;random_forest&amp;#34;, RandomForestRegressor(random_state=42)), ]) param_grid = [{&amp;#39;preprocessing__geo__n_clusters&amp;#39;: [5, 8, 10], &amp;#39;random_forest__max_features&amp;#39;: [4, 6, 8]}, {&amp;#39;preprocessing__geo__n_clusters&amp;#39;: [10, 15], &amp;#39;random_forest__max_features&amp;#39;: [6, 8, 10]}, ] grid_search = GridSearchCV(full_pipeline, param_grid, cv=3, scoring=&amp;#39;neg_root_mean_squared_error&amp;#39;) grid_search.fit(housing, housing_labels) 请注意，您可以引用管道中任何估计器的任何超参数，即使该估计器嵌套在多个管道和列转换器的深处。 例如，当 Scikit-Learn 看到“preprocessing__geo__n_clusters”时，它会在双下划线处分割该字符串，然后在管道中查找名为“preprocessing”的估计器并找到预处理 ColumnTransformer。 接下来，它在此 ColumnTransformer 中查找名为“geo”的转换器，并找到我们在纬度和经度属性上使用的 ClusterSimilarity 转换器。 然后它找到该变压器的n_clusters超参数。 同样，random_forest__max_features指的是名为“random_forest”的估计器的max_features超参数，这当然是RandomForest模型。
这个param_grid中有两个字典，因此GridSearchCV将首先评估第一个字典中指定的n_clusters和max_features超参数值的所有3×3=9个组合，然后它将尝试第一个字典中指定的所有2×3=6个超参数值组合 第二个字典。 因此，网格搜索总共将探索 9 + 6 = 15 种超参数值组合，并且每个组合都会对管道进行 3 次训练，因为我们使用的是 3 折交叉验证。 这意味着总共将有 15 × 3 = 45 轮训练！ 这可能需要一段时间，但是完成后您可以获得如下参数的最佳组合：</description></item><item><title>解决 github.com port 443: Timed out 的问题</title><link>https://qiucode.cn/article/191/</link><pubDate>Sat, 27 Jan 2024 19:39:19 +0800</pubDate><guid>https://qiucode.cn/article/191/</guid><description>国内访问github.com总是那么不竟如人意，时而无法加载网页，时而等我们抽完了一根烟后，它还处于转圈的状态。
虽然国内有gitee.com等诸多的代码托管平台，但却鲜有国人愿意去呢？其中的缘由，想必也不用我多说，大伙也都心知肚明了吧！
即便github.com在国内访问慢，或是加载不出来，我们也宁愿等它慢慢地加载出来，却不愿将代码托管于境内的平台。
github.com 托管了 qiucode.cn 站点 由于将 秋码记录 托管于 github.com上后，写些文章就得push上去，然而当我push上去时，却十有八九都会出现 github.com port 443: Timed out的错误，代码显然是无法push上去的了！
难道在国内，现在push或是pull github.com，都是要靠运气吗？偶尔可以，大多数都是报错。
可是，“运气”总不能实时来关顾我们，要是那样的话，我早去买彩票了，虽然有运气，买了彩票，它也不一定中奖，毕竟古话早就有言：朝里有人好当官。
然而，有没有一劳永逸的解决之道呢？答案那是肯定有的，要不然，也就不会有这么一篇文章了，您也就不会花费您宝贵的时间来浏览本文，寻求与我遇到同样问题的解决方案了。
当我们想要clone github.com上的一个项目时，出现以下错误，那都是家常便饭了。
从报错信息来看，很显然这是https请求超时，这是毋庸置疑的，毕竟我们访问github.com都是是好是坏的！您在terminal端不还是一样的请求超时嘛！
解决国内 push/pull github.com 项目出现 Timed out 的问题 毕竟，秋码记录 是托管于 github.com上，总不可能写了一篇文章，想要push到 github.com，这次出现Timed out的错误，就不push，而是等到下次再写文章时，再push，这显然不是我要的，毕竟，技术文章（在这里，我也就王婆卖瓜，自卖自夸咯）是有时效性的！说是这么说，但并不妨碍的。
能出现Timed out的问题，我们第一想到便是网络问题（有些事我们自己心里清楚就好了），其次才是本地git配置问题。
那么，我们暂且略过网络问题这一客观事实不谈，来说说本地git的配置是哪里出现问题，而导致了出现Timed out的问题呢？
我们还是回到 terminal，输入以下命令测试ssh是否成功？
ssh -T git@github.com 如果，您也出现了上图的结果，那显然是配置的问题了。
我们再次测试下port 443是否也出现超时的问题？
ssh -T -p 443 git@ssh.github.com 可以看出，端口 443 请求是没问题，那么，为什么clone项目时，却报出了port 443请求超时的错误呢？
我们大致从上面的ssh测试报错便可以得出结论了，那便是ssh连接超时了。
而要想解决ssh请求超时的问题，那就要从配置着手了，还是一样的在terminal输入以下命令。
vim ~/.ssh/config 而后在进入编辑状态，填写以下内容
# Add section below to itHost github.comHostname ssh.</description></item><item><title>选择和训练模型（Machine Learning 研习之十一）</title><link>https://qiucode.cn/article/190/</link><pubDate>Sun, 14 Jan 2024 15:50:17 +0800</pubDate><guid>https://qiucode.cn/article/190/</guid><description>当您看到本文标题时，不禁感叹，总算是到了训练模型这一节了。
是啊，在之前的文章中，我们对数据进行了探索，以及对一个训练集和一个测试集进行了采样，也编写了一个预处理管道来自动清理，准备您的数据用于机器学习算法，然而现在，我们可以选择并训练模型了。
训练集的训练与评估 我们从一个最基本的线性回归模型开始：
from sklearn.linear_model import LinearRegression lin_reg = make_pipeline(preprocessing, LinearRegression()) lin_reg.fit(housing, housing_labels) 很好，至此，我们现在算是有了一个有效的线性回归模型，可以在训练集上试用它，查看前五个预测，并将它们与标签进行比较:：
第一个预测偏差很大(超过200,000美元!)，而其他预测则更好，两个预测偏差约25%，还有两个预测 偏差不到10%。请记住，您选择使用RMSE作为性能测度，因此您希望使用Scikit-Learn的mean_squared_error()函数在整个训练集上测量该回归模型的RMSE，并将平方参数设置为False。
这总比没有好，但显然不是一个很好的分数，大多数地区的房屋价值中位数在120,000美元和26.5万美元之间，所以一个典型的68628美元的预测误差真的不是很令人满意。这是一个模型拟合训练数据不足的示例。当这种情况发生时，可能意味着这些特征没有提供足够的信息来做出好的预测，或者模型不够强大。
正如我们在上一章中看到的，修复欠拟合的主要方法是选择一个更强大的模型，为训练算法提供更好的特征，或者减少对模型的约束。这个模型没有正规化，这就排除了最后一个选项。您可以尝试添加更多功能，但首先您要尝试更复杂的模型，看看它是如何工作的。
您决定尝试DecisionTreeRegressor，因为这是一个相当强大的模型，能够在数据中找到复杂的非线性关系(后续篇章将更详细地介绍决策树)：
from sklearn.tree import DecisionTreeRegressor tree_reg = make_pipeline(preprocessing, DecisionTreeRegressor(random_state=42)) tree_reg.fit(housing, housing_labels) 现在模型已训练完毕，您可以在训练集中对其进行评估：
等等，难道这个模型真的很完美吗？当然咯，更有可能的是模型严重地过度拟合了数据。您怎么能确定正如你前面看到的，在您准备好启动一个您有信心的模型之前，您不想碰测试集，所以您需要使用一部分训练集进行训练，另一部分用于模型验证。
使用交叉验证进行更好的评估 评估决策树模型的一种方法是使用train_test_split()函数将训练集拆分为较小的训练集和验证集，然后针对较小的训练集训练您的模型，并针对验证集对其进行评估。这是一点努力，但没有太难，它会工作得相当不错。
一个很好的替代方法是使用Scikit-Learn的k_-fold交叉验证特性。下面的代码随机地将训练集分成10个不重叠的子集，称为fold，然后训练和评估决策树模型10次，每次选择不同的fold进行评估，并使用其他9个fold进行训练。结果是一个包含10个评价分数的数组：
from sklearn.model_selection import cross_val_score tree_rmses = -cross_val_score(tree_reg, housing, housing_labels, scoring=&amp;#34;neg_root_mean_squared_error&amp;#34;, cv=10) ```Scikit-Learn```的交叉验证功能期望的是效用函数(越大越好)而不是成本函数(越低越好)，所以评分函数实际上是RMSE的反面。它是一个负值，所以您需要切换输出的符号来获得RMSE分数。让我们来看看结果吧：
现在决策树看起来不像以前那么好了。事实上，它的表现几乎和线性回归模型一样差！请注意，交叉验证不仅允许您获得模型性能的估计值，还允许您测量该估计值的精确度(即其标准差)。决策树的均方根误差约为66，868，标准差约为2,061。如果只使用一个验证集，则不会有此信息。但是交叉验证是以多次训练模型为代价的，所以它并不总是可行的。
如果您为线性回归模型计算相同的度量，您将发现平均RMSE为69，858，标准差为4,182。因此，决策树模型的性能似乎比线性模型稍微好一点，但由于严重的过拟合，差异很小。我们知道存在过拟合 问题，因为训练误差很低(实际上为零)，而验证误差很高。
现在让我们尝试最后一个模型:随机森林调节器，随机森林的工作原理是在特征的随机子集上训练许多决策树，然后平均出它们的预测值。这样的模型组成的许多其他模型被称为合奏:他们能够提高性能基础模型(在本例中为决策树)。代码与前面的代码大同小异：
from sklearn.ensemble import RandomForestRegressor forest_reg = make_pipeline(preprocessing, RandomForestRegressor(random_state=42)) forest_rmses = -cross_val_score(forest_reg, housing, housing_labels, scoring=&amp;#34;neg_root_mean_squared_error&amp;#34;, cv=10) 随机森林真的看起来非常有前途的任务！但是，如果您训练一个RandomForest并测量训练集上的RMSE，您将发现大约17，474:这要低得多，这意味着仍然存在大量的过度拟合。可能的解决方案是 简化模型，约束它(即，规则化它)，或得到更多的训练数据。但是，在深入研究随机森林之前，您应该尝试来自各种类别机器学习算法的许多其他模型(例如，具有不同内核的多个支持向量机，可能还有一个神经网络)，而无需花费太多时间调整超参数。目标是列出几个(两到五个)有前途的模型。</description></item><item><title>回望这风雨飘摇的一年过后，我们终将要整束行囊继续前行</title><link>https://qiucode.cn/article/184/</link><pubDate>Sat, 30 Dec 2023 11:47:17 +0800</pubDate><guid>https://qiucode.cn/article/184/</guid><description>2023 这一年 时间倏忽而过，纵有再多的不甘，2023 这一年的日历终要翻过去了。这一年，或许还对很多事保持着一种执念，然而，随着 2023 年如东逝水一去不复返，也该放下那份执着，让我们挥手告别那处于风雨飘摇的 2023 年，毕竟，未来还很长，我们还得背上行囊踏上那远方的路，否则，赶不上停靠在路边的二路汽车了都！
2023 年年初为这一年预先设定的规划，实现了吗？然而，回答我们自己，是那无声的摇头。年初预定的规划，大抵也只有到了年末，我们对这一年复盘时，方觉得年初列出的计划清单，还是有那么多没有完成，更有甚者，清单上一项都没能实现，或许，此刻，我们会对自己发出一声苦笑，长吁责问自己，“一年的时间，竟然空不出一点时间来完成那年初既定的规划！”
无论是长吁短叹，还是责怪自己，我们总得为未来、新的一年起一份未来规划列表，顺带 2023 年还未完成的计划。
风雨过后，总能遇见太阳，只是自然界的现象，当然，也有例外，太阳有时让那厚实的云朵遮蔽了，日光便无法照耀大地，那阴郁之气却布满了上空，使这座城市处于压抑的一天，但我们相信，云朵总是会散开的，迟来的阳光，也会照射这片土地，用那光芒的温度去蒸发昨日的阴郁之气。
或许，用【风雨飘摇】这个成语来形容 2023 这一年，总觉得还不是那么恰当，因为 2023 这一年，并不像【风雨飘摇】这个词轻描淡写、一词带过，这四个字并不足以恰如其分地述说 2023 这一年。
这一年，承载着太多人的不甘；这一年，也让大部分撤离了那份职业；这一年，也让很大一部分人彻夜逃离了大城市，终将回到了可以安放灵魂的故乡。
然而，在 2023 这一年所积攒下来的诸多不甘、不忿、怨愤等阴郁之气，我们希望能借未来之光芒来吹散、蒸发那股消极、惨淡、压抑之气，在我们寄托于未来之光的时刻，我们也必须时刻充实自己，也只有这样，未来之光方能光顾到我们自己。
2023 年的既定计划 说来忏愧，2023 年年初既定要完成的计划，用这一年的时间，本是完成那份计划清单，绰绰有余，然而，一年到头了，回首这一年，却发觉，计划清单上竟然还有那么多未能实现的。或许，我们会长叹一声，“时间都去哪儿了？”
时间并没有去哪里游玩，而是一直傍我们左右，只是我们生活节奏快了，顺带也把时间扯上了。那一声，“时间都去哪儿了？”的感慨，是没来由的长吁短叹！
2023 年既定的计划：
编写一套具有 秋码记录 风格的 Wordpress主题 编写一套具有 秋码记录 风格的Typecho主题 更新基于Vue.js 2.X的开源 UI组件库 qiucode-ui 组件库 编写一套基于 React的开源UI组件库 让 秋码记录 全站使用自己开源的UI组件库 然而，到了 2023 年年末，回望计划清单时，发觉虽但没能全部完成，却在意料之外增添一项计划，实属难料的惊喜：
开源了一套由 Hugo驱动的 hugo-theme-kiwi主题 一套由 Hugo 驱动的博客主题 hugo-theme-kiwi 开源啦 实践多个Web3项目 研习人工智能领域 2023 年所欠下的计划，我们也只能将它们寄托于新的一年，希冀未来能够逐一地实现它们，以不负昨日之约。
我们将 2023 年所搁浅的计划，整理好，装进背囊，踏上远方之路，让未来之光吹散因在 2023 年所沾满了满身泄气、不甘、愤懑地压抑之气。
展望未来 昨日之事，已成定局，断然不可挽回，该是放下那份执念，去迎接明日的阳光。</description></item><item><title>机器学习中的 Transformation Pipelines（Machine Learning 研习之十）</title><link>https://qiucode.cn/article/189/</link><pubDate>Mon, 11 Dec 2023 19:50:17 +0800</pubDate><guid>https://qiucode.cn/article/189/</guid><description>Transformation Pipelines 有许多数据转换步骤需要以正确的顺序执行。幸运的是，Scikit-Learn提供了Pipeline类来帮助处理这样的转换序列。下面是一个用于数值属性的小管道，它首先对输入特性进行归并，然后对输入特性进行缩放:
from sklearn.pipeline import Pipeline num_pipeline = Pipeline([ (&amp;#34;impute&amp;#34;, SimpleImputer(strategy=&amp;#34;median&amp;#34;)), (&amp;#34;standardize&amp;#34;, StandardScaler()), ]) Pipeline构造函数采用名称/估算器对(2元组)的列表，定义了一系列步骤。名称可以是您喜欢的任何名称，只要它们是唯一的，并且不包含双下划线(__)。以后我们讨论超参数调优时，它们会很有用。估计器必须都是转换器(即，它们必须有一个fit_transform()方法)，除了最后一个，它可以是任何东西:转换器、预测器或任何其他类型的估计器。
如果你不想命名transformers你可以使用 make_pipeline() 函数； 它将transformers作为位置参数，并使用transformers类的名称（小写且不带下划线）创建管道（例如，“simpleimputer”）：
from sklearn.pipeline import make_pipeline num_pipeline = make_pipeline(SimpleImputer(strategy=&amp;#34;median&amp;#34;), StandardScaler()) 如果多个transformers具有相同的名称，则会在其名称后附加索引（例如“foo-1”、“foo-2”等）。
当您调用管道的 fit() 方法时，它会在所有transformers上顺序调用 fit_transform()，将每个调用的输出作为参数传递给下一个调用，直到到达最终估计器，为此它只调用 fit() 方法。
该管道公开与最终估计器相同的方法。 在此示例中，最后一个估计器是 StandardScaler，它是一个transformers，因此管道也充当transformers。 如果您调用管道的transform()方法，它将按顺序将所有转换应用于数据。 如果最后一个估计器是预测器而不是变换器，那么管道将具有 Predict() 方法而不是 Transform() 方法。 调用它会按顺序将所有转换应用于数据并将结果传递给预测器的 Predict()方法
让我们调用管道的 fit_transform() 方法并查看输出的前两行，四舍五入到小数点后两位：
如前所述，如果要恢复一个漂亮的DataFrame，可以使用管道的get_feature_names_ out()方法:
df_housing_num_prepared = pd.DataFrame( housing_num_prepared, columns=num_pipeline.get_feature_names_out(), index=housing_num.index) 管道支持索引;例如，管道[1]返回管道中的第二个估计值，管道[:-1]返回一个包含除最后一个估计值以外的所有估计值的管道对象。您还可以通过steps属性(它是名称/估算器对的列表)或named_steps字典属性(它将名称映射到估算器)访问估算器。例如，num_line[“ simpleimputer”]返回名为“simpleimputer”的估计器。
到目前为止，我们已经分别处理了分类列和数值列。如果有一个能够处理所有列的转换器，将适当的转换应用到每一列，那会更方便。为此，您可以使用olumnTransformer。例如，下面的ColumnTransformer将把num_pipeline(我们刚刚定义的那个)应用于数字属性，把cat_pipeline应用于类别属性:
from sklearn.compose import ColumnTransformer num_attribs = [&amp;#34;longitude&amp;#34;, &amp;#34;latitude&amp;#34;, &amp;#34;housing_median_age&amp;#34;, &amp;#34;total_rooms&amp;#34;, &amp;#34;total_bedrooms&amp;#34;, &amp;#34;population&amp;#34;, &amp;#34;households&amp;#34;, &amp;#34;median_income&amp;#34;] cat_attribs = [&amp;#34;ocean_proximity&amp;#34;] cat_pipeline = make_pipeline( SimpleImputer(strategy=&amp;#34;most_frequent&amp;#34;), OneHotEncoder(handle_unknown=&amp;#34;ignore&amp;#34;)) preprocessing = ColumnTransformer([ (&amp;#34;num&amp;#34;, num_pipeline, num_attribs), (&amp;#34;cat&amp;#34;, cat_pipeline, cat_attribs), ]) 首先导入ColumnTransformer类，然后定义数字和分类列名的列表，并为分类属性构造一个简单的管道。最后，我们构造了一个列变换器。它的构造函数需要一个三元组(3-tuple)列表，每个三元组包含一个名称(必须是唯一的且不包含双下划线)、一个转换器和一个应该应用转换器的列的名称(或索引)列表。</description></item><item><title>特征缩放和转换以及自定义Transformers（Machine Learning 研习之九）</title><link>https://qiucode.cn/article/187/</link><pubDate>Sat, 18 Nov 2023 20:53:29 +0800</pubDate><guid>https://qiucode.cn/article/187/</guid><description>特征缩放和转换 您需要应用于数据的最重要的转换之一是功能扩展。除了少数例外，机器学习算法在输入数值属性具有非常不同的尺度时表现不佳。住房数据就是这种情况:房间总数约为6至39320间，而收入中位数仅为0至15间。如果没有任何缩放，大多数模型将倾向于忽略收入中位数，而更多地关注房间数。
有两种常见的方法使所有属性具有相同的尺度:最小-最大尺度和标准化。
与所有估计器一样，重要的是仅将标量拟合到训练数据:永远不要对训练集以外的任何对象使用fit()或fit_transform()。一旦你有了一个训练好的定标器，你就可以用它来变换()任何其他的集合，包括验证集、测试集和新的数据。请注意，虽然培训集值将始终缩放到指定的范围，但如果新的数据包含异常值，则这些值最终可能会缩放到该范围之外。如果要避免这种情况，只需将剪辑超参数设置为True即可。
最小-最大缩放(许多人称之为标准化)是最简单的:对于每个属性，值被移位和重新缩放，以便它们最终的范围从0到1。这是通过减去最小值并除以最小值和最大值之间的差来实现的。Scikit-Learn为此提供了一个名为MinMaxScaler的转换器。它有一个feature_range超参数，如果出于某种原因，不希望0-1(例如，神经网络在零均值输入下工作得最好，所以最好在-1到1的范围内工作)。是相当好用的:
from sklearn.preprocessing import MinMaxScaler min_max_scaler = MinMaxScaler(feature_range=(-1, 1)) housing_num_min_max_scaled = min_max_scaler.fit_transform(housing_num) 标准化是不同的:首先它减去平均值(所以标准化值有一个零均值)，然后它除以标准差(所以标准-化值的标准差等于1)。不像最小最大缩放，标准化化不会将值限制在特定的范围内。然而，标准化受到离群值的影响要小得多。例如，假设一个地区的收入中位数等于100(误打误撞)，而不是通常的0-15。将最小最大值缩放到0-1范围会将这个离群值映射到1并将所有其他值压缩到0-0.15，而标准化不会受到太大影响。Scikit-Learn提供了一个名为StandardScaler的转换器用于标准化:
from sklearn.preprocessing import StandardScaler std_scaler = StandardScaler() housing_num_std_scaled = std_scaler.fit_transform(housing_num) 如果你想缩放一个稀疏矩阵而不首先将其转换为稠密矩阵，你可以使用一个标准缩放器，它的with_mean超参数设置为False它只会除以标准差，而不会减去均值(因为这会破坏稀疏性当特征的分布具有重尾时（即，当远离平均值的值不是指数罕见时），最小-最大缩放和标准化都会将大多数值压缩到一个小范围内。 机器学习模型通常根本不喜欢这种情况，因此，在缩放特征之前，您应该首先对其进行变换以缩小重尾，并且如果可能的话，使分布大致对称。 例如，对于右侧有重尾部的正特征，执行此操作的常见方法是用其平方根替换特征（或将特征提高到 0 到 1 之间的幂）。 如果该特征具有非常长且重的尾部，例如幂律分布，则用其对数替换该特征可能会有所帮助。 例如，人口特征大致遵循幂律：拥有 10,000 名居民的地区的出现频率仅比拥有 1,000 名居民的地区低 10 倍，而不是呈指数级下降。 下图 显示了当你计算它的对数时这个特征看起来有多好：它非常接近高斯分布（即钟形）。
另一种处理重尾特征的方法是对特征进行反向转换。这意味着将其分布切割成大致相等大小的桶，并将每个特征值替换为它所属的桶的索引，就像我们创建收入猫特征一样(尽管我们只在分层抽样时使用它)。例如，您可以将每个值替换为其百分位数。使用相同大小的bucket处理会产生一个几乎均匀分布的特性，因此不需要进一步的缩放，或者您可以只除以bucket的数目来强制值到0-1的范围。
当一个特征具有多峰分布(即，有两个或两个以上清晰的峰值，称为模式)时，例housing_median_age特征，对它进行bucket ization也是有帮助的，但这次将bucket ID作为类别处理，而不是作为数值。这意味着必须对桶索引进行编码，例如使用OneHotEncoder(所以你通常不想用太多桶)。这种方法将允许回归模型更容易地为该特征值的不同范围学习不同的规则。例如，也许35年前建造的房子有一种独特的风格，已经过时了，因此它们比它们的年龄更便宜。
转换多峰分布的另一种方法是为每个模式(至少是主要模式)添加一个特征，表示住房中位年龄和该特定模式之间的相似性。相似性度量通常使用径向基函数(RBF)来计算&amp;ndash;任何只依赖于输入值与不动点之间距离的函数。最常用的RBF是高斯RBF，其输出值随着输入值远离固定点而呈指数衰减。例如，高斯RBF相似度与房龄x和35由方程exp (-y (x-35)2)给出。超参数y(gamma)确定当x远离35时相似性度量衰减的速度。使用Scikit-Learn的rbf_kernel()函数，您可以创建一个新的高斯RBF特征来测量房屋中位年龄和35:
from sklearn.metrics.pairwise import rbf_kernel age_simil_35 = rbf_kernel(housing[[&amp;#34;housing_median_age&amp;#34;]], [[35]], gamma=0.1) 下图显示了这一新特征作为住房中位数年龄的函数(实线)。它还显示了如果使用较小的gamma值，该功能将是什么样子。如图所示，新的年龄相似性特征在35岁时达到峰值，正好在住房中位年龄分布的峰值附近:如果这个特定的年龄组与较低的价格有很好的相关性，那么这个新特征将有很好的机会发挥作用。
到目前为止，我们只看了输入特性，但是目标值可能也需要转换。例如，若目标分布具有较重的尾部，您可以选择将目标替换为其对数。但是，如果你这样做，回归模型现在将预测的房屋价值中位数的对数，而不是房屋价值中位数本身。如果您想要预测的房屋中值，则需要计算模型预测的指数值。
幸运的是，大多数Scikit-Learn的转换器都有一个inverse_transform()方法，这使得计算转换的逆运算变得很容易。例如，下面的代码示例显示了如何使用StandardScaler缩放标签(就像我们对输入所做的那样)，然后在缩放后的标签上训练一个简单的线性回归模型，并使用它对一些新数据进行预测，然后使用经过训练的缩放器的inverse_transform()方法将这些数据转换回原始尺度。请注意，我们将标签从Pandas Series转换为DataFrame，因为标准Scaler期望2D输入。此外，为了简单起见，在本示例中，我们仅使用单个原始输入特征(中值收入)对模型进行训练:
from sklearn.linear_model import LinearRegression target_scaler = StandardScaler() scaled_labels = target_scaler.</description></item><item><title>为机器学习算法准备数据（Machine Learning 研习之八）</title><link>https://qiucode.cn/article/186/</link><pubDate>Sun, 05 Nov 2023 11:30:06 +0800</pubDate><guid>https://qiucode.cn/article/186/</guid><description>本文还是同样建立在前两篇的基础之上的！
属性组合实验 希望前面的部分能让您了解探索数据并获得洞察力的几种方法。您发现了一些数据怪癖，您可能希望在将数据提供给机器学习算法之前对其进行清理，并且发现了属性之间有趣的相关性，特别是与目标属性 之间的相关性。您还注意到一些属性具有向右倾斜的分布，因此您可能需要转换它们(例如，通过计算它们的对数或平方根)。当然，你的里程会因每个项目而有很大的不同，但大致的想法是相似的。
在为机器学习算法准备数据之前，您可能需要做的最后一件事是尝试各种属性组合。例如，如果你不知道一个地区有多少住户，那么这个地区的房间总数就不是很有用。你真正想要的是每个家庭的房间数量。同样，卧室总数本身也不是很有用:你可能想对比一下房间的数量。每个家庭的人口似乎也是一个有趣的属性组合。创建这些新属性如下:
housing[&amp;#34;rooms_per_house&amp;#34;] = housing[&amp;#34;total_rooms&amp;#34;] / housing[&amp;#34;households&amp;#34;] housing[&amp;#34;bedrooms_ratio&amp;#34;] = housing[&amp;#34;total_bedrooms&amp;#34;] / housing[&amp;#34;total_rooms&amp;#34;] housing[&amp;#34;people_per_house&amp;#34;] = housing[&amp;#34;population&amp;#34;] / housing[&amp;#34;households&amp;#34;] 然后你再看一遍相关矩阵:
!新的bedrooms_ratio属性与房屋中值的相关性要比与房间或卧室总数的相关性大得多。显然，卧室/房间比率较低的房子往往更贵。每个家庭的房间数量也比一个地区的房间总数更能说明问题-很明显，房 子越大，就越贵。
这一轮的探索不需要绝对彻底;关键是从正确的角度出发，并迅速获得见解，这将帮助您获得第一个相当好的原型。但是这是一个迭代的过程:一旦你建立并运行了一个原型，你就可以分析它的输出以获得更多的见解，然后再回到这个探索步骤。
为机器学习算法准备数据 是时候为您的机器学习算法准备数据了。你应该为此编写函数，而不是手工操作，这有几个很好的理由:
这将允许您在任何数据集上轻松重现这些转换(例如，下次获得新数据集时)。 您将逐步构建一个转换函数库，以便在未来的项目中重用。 您可以在实时系统中使用这些函数来转换新数据，然后再将其输入到您的算法中。 这将使您能够轻松地尝试各种转换，并查看哪种转换组合效果最好。 但首先，恢复到一个干净的训练集(通过再次复制strat_train_set)。您还应该将预测变量和标签分开，因为您不一定希望对预测变量和目标值应用相同的转换(请注意，drop()创建数据的副本，并且不影响strat_train_set):
housing = strat_train_set.drop(&amp;#34;median_house_value&amp;#34;, axis=1) housing_labels = strat_train_set[&amp;#34;median_house_value&amp;#34;].copy() 清除数据 大多数机器学习算法无法处理缺失的功能，因此您需要处理这些功能。例如，您之前注意到total_bedrooms属性有一些缺失值。你有三个选项可以解决这个问题:
去掉相应的区。
去掉整个属性。
将缺失值设置为某个值(零、均值、中位数等)。这就是所谓的归罪。
您可以使用PandasDataFrame的dropna () 、drop () 和fillna ()方法轻松完成这些任务:
housing.dropna(subset=[&amp;#34;total_bedrooms&amp;#34;], inplace=True) # option 1 housing.drop(&amp;#34;total_bedrooms&amp;#34;, axis=1) # option 2 median = housing[&amp;#34;total_bedrooms&amp;#34;].median() # option 3 housing[&amp;#34;total_bedrooms&amp;#34;].fillna(median, inplace=True) 您决定使用选项3，因为它的破坏性最小，但是您将使用一个方便的Scikit-Learn类:Simplelmputer，而不是前面的代码。这样做的好处是，它将存储每个特征的中值:这将使得它不仅可以估算训练集上的缺失值，还可以估算验证集、测试集和输入到模型的任何新数据上的缺失值。要使用它，首先需要创建一个Simplelmputer实例，指定要将每个属性的缺失值替换为该属性的中位数:
from sklearn.</description></item><item><title>端到端的机器学习项目之探索数据（Machine Learning 研习之七）</title><link>https://qiucode.cn/article/188/</link><pubDate>Tue, 24 Oct 2023 19:30:00 +0800</pubDate><guid>https://qiucode.cn/article/188/</guid><description>本篇其实是承接上一篇内容，之所以没在上一篇将它写完，那是有原因的，毕竟，本着学习的态度，篇幅不应过长，方能使你有学习的欲望！
探索数据 首先，确保你已经把测试放在一边，你只是在探索训练集。此外，如果训练集非常大，您可能希望对探索进行采样设置，使操作在勘探阶段变得容易和快速。在这种情况下，培训集非常小，所以您可以直接处理完整集。由于你要试验完整训练集的各种变换，你应该制作一份原始的所以你可以在之后恢复它:
housing = strat_train_set.copy() 可视化地理数据 因为数据集包括地理信息(纬度和经度)，所以创建一个所有地区的散点图来可视化数据是一个好主意(见下图):
housing.plot(kind=&amp;#34;scatter&amp;#34;, x=&amp;#34;longitude&amp;#34;, y=&amp;#34;latitude&amp;#34;, grid=True) plt.show() 这看起来很像加州，但除此之外，很难看到任何特别的模式。将alpha选项设置为0.2可以更容易地显示数据点密度高的位置(见下图):
housing.plot(kind=&amp;#34;scatter&amp;#34;, x=&amp;#34;longitude&amp;#34;, y=&amp;#34;latitude&amp;#34;, grid=True, alpha=0.2) plt.show() 现在的情况要好得多:你可以清楚地看到高密度地区，即海湾地区、洛杉矶和圣地亚哥周围，再加上中央山谷(特别是萨克拉门托和弗雷斯诺)的一长排高密度地区。
我们的大脑非常善于发现图片中的模式，但你可能需要玩弄可视化参数，使模式脱颖而出。
接下来，你再看看房价(见下图)。每个圆圈的半径代表该地区的人口(选项s)，颜色代表价格(选项c)。这里使用了一个名为jet的预定义颜色映射(选项cmap)，其范围从蓝色(低值)到红色(高价):s
housing.plot(kind=&amp;#34;scatter&amp;#34;, x=&amp;#34;longitude&amp;#34;, y=&amp;#34;latitude&amp;#34;, grid=True, s=housing[&amp;#34;population&amp;#34;] / 100, label=&amp;#34;population&amp;#34;, c=&amp;#34;median_house_value&amp;#34;, cmap=&amp;#34;jet&amp;#34;, colorbar=True, legend=True, sharex=False, figsize=(10, 7)) plt.show() 这张图告诉你，房价与地理位置(例如，靠近大海)和人口密度密切相关，你可能已经知道了。聚类算法对于检测主集群和添加测量与集群中心的邻近性的新特性应该是有用的。海洋邻近属性也可能是有用的，尽管在北加州沿海地区的房价不是太高，所以这不是一个简单的规则。
寻找相关性 由于数据集不是太大，你可以很容易地使用corr()方法计算每对属性之间的标准相关系数(也称为皮尔逊相关系数):
corr_matrix = housing.corr() 现在您可以查看每个属性与房屋中值的相关性:
相关系数从-1到1。当它接近1时，意味着有很强的正相关关系，例如，当收入中位数上升时，房屋价值中位数往往会上升。当系数接近-1时，意味着有很强的负相关性;你可以看到纬度和房屋价值中间值之间有一个很小的负相关性(即往北走，房价有轻微的下降趋势)。最后，系数接近0意味着不存在线性相关关系。
检查属性之间相关性的另一种方法是使用Pandas scatter_matrix ()函数，该函数将每个数值属性与其他每个数值属性进行绘图。由于现在有11个数字属性，您将得到112=121幅不适合页面的地块，所以您决定将重点放在一些看起来与住房中值最相关的有前途的属性上(见下图):
如果Pandas将每个变量相对于自身绘制，那么主对角线将充满直线，这将不是很有用。因此，Pandas显示每个属性的直方图(其他选项可用;请参阅Pandas文档以获取更多详细信息)。
查看相关散点图，似乎最有希望预测房屋价值中位数的属性是收入中位数，所以你放大他们的散点图(见下图):
housing.plot(kind=&amp;#34;scatter&amp;#34;, x=&amp;#34;median_income&amp;#34;, y=&amp;#34;median_house_value&amp;#34;, alpha=0.1, grid=True) plt.show() 这个情节揭示了一些事情。首先，相关性确实很强;你可以清楚地看到上升的趋势，而且点也不太分散。第二，你之前注意到的价格上限在500，000美元的水平线上明显可见。但这个情节也揭示了其他不那么明显的直线:一条水平线在45万美元左右，另一条大约35万美元左右，也许还有一条大约28万美元，还有几条低于这一点。您可能希望尝试删除相应的区域，以防止您的算法学习重现这些数据怪癖。
警告：
相关系数只测量线性相关性(“当x上升时，y通常上升/下降”)。它可能会完全忽略非线性关系(例如，“当x接近0时，y通常会上升”)。图2-16显示了各种数据集及其相关系数。请注意，尽管它们的轴线显然不是独立的，但底部行的所有图都具有等于0的相关系数:这些都是非线性关系的例子。另外，第二行显示了相关系数等于1或-1的示例;注意，这与斜率无关。例如，以英寸为单位的身高与以英尺或纳米为单位的身高的相关系数为1。</description></item><item><title>端到端的机器学习项目（Machine Learning 研习之六）</title><link>https://qiucode.cn/article/183/</link><pubDate>Sat, 14 Oct 2023 17:02:17 +0800</pubDate><guid>https://qiucode.cn/article/183/</guid><description>&lt;p>Scikit-Learn提供了一些函数，以各种方式将数据集拆分为多个子集。最简单的函数train_test_split()，它的功能与我们前面定义的shuffle_and_split_data ()函数非常相似，只是增加了几个特性。首先，有一个random_state参数，它允许您设置随机生成器种子。其次，您可以向它传递具有相同行数的多个数据集，它将按照相同的索引将它们拆分(这是非常有用的，例如，如果你有一个单独的DataFrame标签)&lt;/p></description></item><item><title>机机器学习的测试和验证（Machine Learning 研习之五）</title><link>https://qiucode.cn/article/182/</link><pubDate>Sun, 27 Aug 2023 16:32:17 +0800</pubDate><guid>https://qiucode.cn/article/182/</guid><description>&lt;p>在此保留验证过程之后，您可以在完整的训练集（包括验证集）上训练最佳模型，这将为您提供最终模型。在这种情况下，需要记住的最重要的规则是，验证集和测试集都必须尽可能具有生产中预期使用的数据的代表性，因此它们应该完全由有代表性的图片组成:您可以对它们进行洗牌，将一半放在验证集中，另一半放在测试集中(确保在这两个集合中都没有重复或接近重复的数据)。在网络图片上对模型进行培训之后，如果您观察到模型在验证集上的性能令人失望，您将不知道这是因为您的模型超出了培训集，还是仅仅是由于网络图片和移动应用程序图片之间的不匹配。&lt;/p></description></item><item><title>机器学习的主要挑战和任务（Machine Learning 研习之四）</title><link>https://qiucode.cn/article/181/</link><pubDate>Sun, 13 Aug 2023 15:12:38 +0800</pubDate><guid>https://qiucode.cn/article/181/</guid><description>&lt;p>对于一个蹒跚学步的孩子来说，要知道什么是苹果，您只需要指着一个苹果说“苹果”(可能会重复这个过程几次)。现在孩子能够识别各种颜色和形状的苹果。&lt;/p></description></item><item><title>对于大量数据集的解决方案便是在线学习或是增量学习（Machine Learning 研习之三）</title><link>https://qiucode.cn/article/180/</link><pubDate>Fri, 28 Jul 2023 21:12:38 +0800</pubDate><guid>https://qiucode.cn/article/180/</guid><description>&lt;p>随着时间的推移，模型也需做出相应的变化。但就采用新数据与旧数据一起训练，势必需要耗费更多的资源，为了解决这一状况，本文带您了解，关于新数据该如何训练？&lt;/p></description></item><item><title>现实生活中机器学习的具体示例（Machine Learning 研习之二）</title><link>https://qiucode.cn/article/179/</link><pubDate>Mon, 17 Jul 2023 21:22:38 +0800</pubDate><guid>https://qiucode.cn/article/179/</guid><description>&lt;p>在上一篇，我们初步了解什么是机器学习，以及它能给我们带来，相对于传统编程解决更为优先、易于维护的一套解决方案。那么，本文将继续为您举例，机器学习给我们生活上带来哪些便捷。&lt;/p></description></item><item><title>让机器学习不再是过门不入，带您一起详解机器学习（机器学习 Machine Learning 研习之一）</title><link>https://qiucode.cn/article/178/</link><pubDate>Sat, 15 Jul 2023 10:18:38 +0800</pubDate><guid>https://qiucode.cn/article/178/</guid><description>&lt;p>让机器学习不再是过门不入，跟着【秋码】一起研习机器学习（&amp;ldquo;Machine Learning&amp;rdquo;），探究什么是机器学习？以及为何我们要去使用机器学习呢？毕竟未来是属于人工智能（Ai）的，引领潮流的往往是新事物，这一次，您可不要再错过了！抓住它，就等于握住了穿梭未来的时光机。&lt;/p></description></item><item><title>把握住golang中的template，方能驾驭得了Hugo主题的template</title><link>https://qiucode.cn/article/177/</link><pubDate>Sat, 08 Jul 2023 15:18:38 +0800</pubDate><guid>https://qiucode.cn/article/177/</guid><description>&lt;p>不置可否，&lt;code>Hugo&lt;/code>的&lt;code>template&lt;/code>同样是使用&lt;code>golang&lt;/code>的标准库&lt;code>html/template&lt;/code>。为了能实现一个属于自己独特的&lt;code>Hugo theme&lt;/code>，或是修改他人的主题，都得对其&lt;code>模板语法&lt;/code>有所知晓，方能改的称心如意，亦或是制作出一套即简约，又不失典雅的&lt;code>Hugo theme&lt;/code>。&lt;/p></description></item><item><title>云服务器到期，站点迁移，Nginx配置SSL以备后续只需！</title><link>https://qiucode.cn/article/176/</link><pubDate>Tue, 20 Jun 2023 20:46:20 +0800</pubDate><guid>https://qiucode.cn/article/176/</guid><description>&lt;p>三年前（2020-06-20 上午11点左右），各大云厂商&lt;code>6.18&lt;/code>活动还在进行中。一番对比下来，最终还是选择了&lt;code>腾讯云&lt;/code>。然而三年的期限，犹如电光火石一般，眨眼间就过去了。可云服务器到期了，却没有了续费的打算，其中缘由说与谁人听呢？&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（内联汇编 [inline assembly]-Solidity之旅十八）</title><link>https://qiucode.cn/article/175/</link><pubDate>Wed, 28 Dec 2022 20:21:06 +0800</pubDate><guid>https://qiucode.cn/article/175/</guid><description>&lt;p>在 Solidity 中使用 &lt;code>Assembly&lt;/code> 的主要好处之一是节省 gas。 让我们尝试通过创建一个将 2 个值 x 和 y 相加并返回结果的函数来比较 Solidity 和 Assembly 之间的 gas 成本。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（库 [library]-Solidity之旅十七）</title><link>https://qiucode.cn/article/174/</link><pubDate>Sat, 24 Dec 2022 21:21:05 +0800</pubDate><guid>https://qiucode.cn/article/174/</guid><description>&lt;p>最后，当库函数成为数据类型本身的一部分时，我们可以在其对象上调用该方法，如我们上面的契约所示，即&lt;code>firstNumber.add(secondNumber);&lt;/code> 。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（Constant 和 Immutable 状态变量-Solidity之旅十六）</title><link>https://qiucode.cn/article/173/</link><pubDate>Fri, 23 Dec 2022 22:04:32 +0800</pubDate><guid>https://qiucode.cn/article/173/</guid><description>&lt;p>编译器生成的合约创建代码将在返回合约之前修改合约的运行时代码，方法是将对不可变量的所有引用替换为分配给它们的值。 如果要将编译器生成的运行时代码与实际存储在区块链中的代码进行比较，则这一点很重要。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（修改器 [modifier]-Solidity之旅十五）</title><link>https://qiucode.cn/article/172/</link><pubDate>Fri, 23 Dec 2022 09:47:58 +0800</pubDate><guid>https://qiucode.cn/article/172/</guid><description>&lt;p>&lt;code>修改器（modifier）&lt;/code>在 Solidity 中是一种特殊类型的函数，用于修改其它函数的行为。例如，开发人员可以使用修改器来检查在允许函数执行之前是否满足某个条件。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（错误处理以及异常-Solidity之旅十四）</title><link>https://qiucode.cn/article/171/</link><pubDate>Wed, 21 Dec 2022 20:42:36 +0800</pubDate><guid>https://qiucode.cn/article/171/</guid><description>&lt;p>它有许多功能来解决在编译时或运行时可能发生的潜在问题。即使语法错误检查发生在编译时，运行时错误也很难捕捉，主要发生在合约执行过程中。一些运行时错误的例子包括除以0的类型错误，数组超出索引错误，等等。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（函数及其可见性和状态可变性-Solidity之旅十三）</title><link>https://qiucode.cn/article/170/</link><pubDate>Mon, 19 Dec 2022 20:30:23 +0800</pubDate><guid>https://qiucode.cn/article/170/</guid><description>&lt;p>对于 public 状态变量会自动生成一个，与状态变量同名的 &lt;code>public&lt;/code>修饰的函数。 以便其他的合约读取他们的值。 当在用一个合约里使用是，外部方式访问 (如: &lt;code>this.x&lt;/code>) 会调用该自动生成的同名函数，而内部方式访问 (如: &lt;code>x&lt;/code>) 会直接从存储中获取值。 Setter函数则不会被生成，所以其他合约&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（事件-Solidity之旅十二）</title><link>https://qiucode.cn/article/169/</link><pubDate>Sun, 18 Dec 2022 20:59:44 +0800</pubDate><guid>https://qiucode.cn/article/169/</guid><description>&lt;p>由于交易日志只存储事件数据而不存储类型。你必须知道事件的类型，包括哪个参数被索引，以及该事件是否是匿名的，以便正确解释数据。 尤其是，有可能使用一个匿名事件来”伪造”另一个事件的签名。由于交易日志只存储事件数据而不存储类型。你必须知道事件的类型，包括哪个参数被索引，以及该事件是否是匿名的，以便正确解释数据。 尤其是，有可能使用一个匿名事件来”伪造”另一个事件的签名。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（OOP-接口-Solidity之旅十一）</title><link>https://qiucode.cn/article/168/</link><pubDate>Sun, 18 Dec 2022 15:44:31 +0800</pubDate><guid>https://qiucode.cn/article/168/</guid><description>&lt;p>我们知道在&lt;code>Java&lt;/code>里&lt;code>接口&lt;/code>是&lt;code>特殊的抽象类&lt;/code>，限制多于&lt;code>抽象类&lt;/code>，但随着&lt;code>Java&lt;/code>版本的更新，&lt;code>Java&lt;/code>中的&lt;code>接口&lt;/code>是越来越趋于&lt;code>抽象类&lt;/code>了（这样说，可能有点不妥，因为&lt;code>接口&lt;/code>本就是&lt;code>特殊的抽象类&lt;/code>，只是&lt;code>接口&lt;/code>中不能有方法具体实现，而&lt;code>抽象类&lt;/code>还是可以有的！然而随着&lt;code>Java&lt;/code>版本的&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（OOP-抽象合约-Solidity之旅十）</title><link>https://qiucode.cn/article/167/</link><pubDate>Sat, 17 Dec 2022 14:59:55 +0800</pubDate><guid>https://qiucode.cn/article/167/</guid><description>&lt;p>即假使合约中至少有一个函数没有实现（没有方法体，只有方法签名的方法），那么便将该合约定义为&lt;code>抽象合约（abstract contract）&lt;/code>。当然咯，前文说到&lt;code>继承&lt;/code>提到的，&lt;code>派生合约&lt;/code>未能给其&lt;code>基合约&lt;/code>的构造函数传递指定参数，这时，该合约便只能声明为&lt;code>抽象&lt;/code>的。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（OOP-合约继承-Solidity之旅九）</title><link>https://qiucode.cn/article/166/</link><pubDate>Fri, 16 Dec 2022 20:15:16 +0800</pubDate><guid>https://qiucode.cn/article/166/</guid><description>&lt;p>创建合约时， 合约的 构造函数 (一个用关键字 &lt;code>constructor&lt;/code> 声明的函数)会执行一次。 构造函数是可选的。只允许有一个构造函数，这意味着不支持&lt;code>重载&lt;/code>。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（流程控制-Solidity之旅八）</title><link>https://qiucode.cn/article/165/</link><pubDate>Wed, 14 Dec 2022 22:21:38 +0800</pubDate><guid>https://qiucode.cn/article/165/</guid><description>&lt;p>今天我们不讲三国，来讲讲 流程控制 关于什么是&lt;code>流程控制&lt;/code>，想来您是知道的吧！可若您确实不晓得，那您看了这篇文或许对&lt;code>流程控制&lt;/code>有了初步的了解。 Solidity 和其他语言一样，支持大部分&lt;code>流程控制&lt;/code>语句，除了&lt;code>switch&lt;/code>和被&lt;code>程序员界&lt;/code>谈虎色变而其他语言又保留的&lt;code>goto&lt;/code>。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（单位以及全局变量-Solidity之旅七）</title><link>https://qiucode.cn/article/164/</link><pubDate>Wed, 14 Dec 2022 09:31:48 +0800</pubDate><guid>https://qiucode.cn/article/164/</guid><description>&lt;p>时间戳和区块哈希在一定程度上都可能受到挖矿矿工影响。例如，挖矿社区中的恶意矿工可以用某个给定的哈希来运行赌场合约的 payout 函数，而如果他们没收到钱，还可以用一个不同的哈希重新尝试。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（基本类型转换以及推断-Solidity之旅六）</title><link>https://qiucode.cn/article/163/</link><pubDate>Mon, 12 Dec 2022 22:08:10 +0800</pubDate><guid>https://qiucode.cn/article/163/</guid><description>&lt;p>某些情况下，编译器不支持&lt;code>隐式转换&lt;/code>，而这时，作为开发人员的您就不得不使用&lt;code>强硬手段&lt;/code>了。&lt;code>显式转换&lt;/code>可能会发生些您无法预料的状况，所以您需要繁琐的测试，看最终是否能达到您的要求。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（变量作用域-Solidity之旅五）</title><link>https://qiucode.cn/article/162/</link><pubDate>Sun, 11 Dec 2022 21:12:12 +0800</pubDate><guid>https://qiucode.cn/article/162/</guid><description>&lt;p>局部变量（Local Variable）的范围仅限于它们被定义的函数，但 状态变量（State Variable） 可以有三种范围。 public - public 修饰的 状态变量（State Variable） 可以在内部以及通过消息进行访问，对于一个公共状态变量，会自动生成一个getter函数。&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（类型-映射类型-Solidity之旅四）</title><link>https://qiucode.cn/article/161/</link><pubDate>Sat, 10 Dec 2022 20:49:38 +0800</pubDate><guid>https://qiucode.cn/article/161/</guid><description>&lt;p>说到&lt;code>映射（Mapping）&lt;/code>，有过其它编程语言经验的您，对这是再熟悉不过了。Solidity 中的&lt;code>映射（Mapping）&lt;/code> 与&lt;code>Java&lt;/code>的&lt;code>Map&lt;/code>、&lt;code>Go&lt;/code>里的&lt;code>Map&lt;/code>以及&lt;code>javascript&lt;/code>的&lt;code>JSON&lt;/code>等众多编程语言中的&lt;code>Map&lt;/code>一样，是用来存储一组&lt;code>键（Key）&lt;/code> &lt;code>值（Value）&lt;/code>，可通过&lt;code>键（Key）&lt;/code>来获取对应&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（类型-引用类型-Solidity之旅三）</title><link>https://qiucode.cn/article/160/</link><pubDate>Fri, 09 Dec 2022 20:56:45 +0800</pubDate><guid>https://qiucode.cn/article/160/</guid><description>&lt;p>数组元素可以是任何类型，包括映射或结构体。对类型的限制是映射只能存储在 存储storage 中，并且公开访问函数的参数需要是 ABI 类型。 状态变量标记 &lt;code>public&lt;/code> 的数组，Solidity创建一个 getter函数 。 小标数字索引就是 getter函数 的参数。&lt;/p></description></item><item><title>花了不到1块5，玩了下全网最火的ChatGPT</title><link>https://qiucode.cn/article/159/</link><pubDate>Thu, 08 Dec 2022 20:59:39 +0800</pubDate><guid>https://qiucode.cn/article/159/</guid><description>这一周来，要说 AI 界最为热闹的莫过于 ChatGPT 了。刚推出一周的时间，注册用户竟然达到了 100 万。自 ChatGPT 推出后，不过短短几天，用户如蜂拥般地去注册，把玩这个能在一周左右吸粉 百来万的现下5网红。
前提准备 由于种种原因，访问 openAI 需要使用科学上网。
具备科学上网的工具，注意：香港 ip 是 100% 无效的，当然最好是 美国 ip。 有一个能接受验证码的国外手机号码，这一点，并不是所有都有的，我就没有，那该怎么办呢？关于这一点，可接着往下看注册虚拟号码，您也就慢慢清楚标题中的1块5是花在这里了。 注册虚拟号码 首先打开 https://sms-activate.org/ 进行注册虚拟号码。
我们先注册个账号，需通过填写的邮箱进行验证账号。
这时，我们在该页面左侧选择服务下的输入框，输入op，即会出现自动补全下拉框，毫无疑问，我们选择第一个OpenAI。
在我们选择了OpenAI后，也就是点选了OpenAI，下面出现所有国家的，当然，我们还是选择第一个，原因嘛，那就是它便宜啊，只需10.5P（10.5卢布）。
而在我们点击了那个 购物车 图标时，出现错误提醒，那便是，你的 余额是 0，需要充值，才能购买。
点击 左上角 人头图标，再列出的下拉框，再次点击充值。
在点击 充值 选项时，这时，页面列出很多 支付方式，往下滚动直找到 支付宝。
由于后续人流量的剧增，该平台所产生的费用，已不是本文发稿时那个价位了，还请你知悉！这里是使用 美元 做为单位，我们充0.2美元足够了，而 0.2 美元在当下当时兑换成人民币是 1.47 元，1块5还不到。
支付宝 扫码支付。
注册 OpenAI 账号 如果在注册OpenAI 账号时，出现了以下提示，那么说明科学上网是局部，需 全局 科学上网。
注册OpenAI一部分是通过 邮箱 进行验证，另一部分则是通过 手机号码 接受验证 再次验证。
填写接收的邮箱验证，进入下一步 手机号码 验证。
我们拷贝刚刚购买的虚拟手机号码。
我们将`虚拟号码`平台上购买的号码拷贝填入`OpenAI`，用于接收短信验证码，而这里需要注意将国家区号去掉，因为我们在`OpenAI`平台选择国家时，带有国家区号，然而，我们在`虚拟平台`上购买的虚拟号码包括国家区号。回到虚拟号码平台，若是没看到验证码，可以刷新下页面就出来了。</description></item><item><title>玩以太坊链上项目的必备技能（类型-值类型-Solidity之旅二）</title><link>https://qiucode.cn/article/158/</link><pubDate>Tue, 06 Dec 2022 21:52:25 +0800</pubDate><guid>https://qiucode.cn/article/158/</guid><description>&lt;p>以下这些类型在 Solidity 中都属于 值类型： * 布尔类型（bool）：字面常量值 &lt;code>true&lt;/code>和 &lt;code>false&lt;/code> * 整型（int/uint）：分为有符号整型&lt;code>int&lt;/code>和无符号整形&lt;code>uint&lt;/code>，这一点倒是和 c++、golang很相像。不管是无符号还有符号整数，它们都是以 8 位递增到 256 位，而&lt;code>int&lt;/code>&lt;/p></description></item><item><title>玩以太坊链上项目的必备技能（初识智能合约语言-Solidity之旅一）</title><link>https://qiucode.cn/article/157/</link><pubDate>Mon, 05 Dec 2022 22:34:42 +0800</pubDate><guid>https://qiucode.cn/article/157/</guid><description>&lt;p>Solidity是静态类型的，支持继承、库和复杂的用户定义类型以及其他功能。 使用Solidity，您可以为投票、众筹、盲目拍卖和多签名钱包等用途创建合约。 在部署合约时，你应该使用最新发布的 Solidity 版本。除了特殊情况外，只有最新版本才会收到安全修复。此外，突破性的变化以及新的&lt;/p></description></item><item><title>在构建 Web3 前，需先知道什么是区块链，毕竟 Web3 是基于区块链</title><link>https://qiucode.cn/article/156/</link><pubDate>Thu, 01 Dec 2022 20:30:51 +0800</pubDate><guid>https://qiucode.cn/article/156/</guid><description>&lt;p>通俗来说，&lt;code>区块链&lt;/code>本质上是一个去中心化的数据仓储，也就是每个人都保留着这个账本，可以认为它是一套加密的分布式超级账本。 比特币是基于区块链技术的第一个应用，也是目前最成功的一个应用。&lt;/p></description></item><item><title>Web3 来了，让我们展开双手拥抱它吧！</title><link>https://qiucode.cn/article/155/</link><pubDate>Wed, 30 Nov 2022 20:28:25 +0800</pubDate><guid>https://qiucode.cn/article/155/</guid><description>&lt;p>Web3 以前所未有的方式赋予你数字资产的所有权。 例如，假设您正在玩一个 Web2 游戏。 如果您购买游戏内物品，它会直接与您的帐户绑定。 如果游戏创建者删除您的帐户，您将丢失这些物品。 或者如果您停止玩游戏，您将失去投资到游戏内物品的价值。&lt;/p></description></item><item><title>Go 语言中的 Moduels 管理（Let's Go 三十四）</title><link>https://qiucode.cn/article/154/</link><pubDate>Fri, 11 Nov 2022 21:45:59 +0800</pubDate><guid>https://qiucode.cn/article/154/</guid><description>&lt;p>在 &lt;code>Go 1.11&lt;/code>以前使用包管理一直被开发者所诟病。既然&lt;code>GOPATH&lt;/code>这种包管理引起了一线开发者的一片骂声，所以，&lt;code>Go&lt;/code>官方体恤一线开发者对&lt;code>GOPATH&lt;/code>这种包管理的情绪，一直致力努力提供对一线开发者友好的包管理解决方法而奋斗。从最初的&lt;code>GOPATH&lt;/code>到&lt;/p></description></item><item><title>Go 语言中的包（Let's Go 三十三）</title><link>https://qiucode.cn/article/153/</link><pubDate>Mon, 07 Nov 2022 20:41:53 +0800</pubDate><guid>https://qiucode.cn/article/153/</guid><description>&lt;p>Go语言的包借助了目录树的组织形式，一般包的名称就是其源文件所在目录的名称，虽然Go语言没有强制要求包名必须和其所在的目录名同名，但还是建议包名和所在目录同名，这样结构更清晰。&lt;/p></description></item><item><title>Go 语言中的错误处理（Let's Go 三十二）</title><link>https://qiucode.cn/article/152/</link><pubDate>Thu, 03 Nov 2022 11:10:28 +0000</pubDate><guid>https://qiucode.cn/article/152/</guid><description>&lt;p>除了上面的 errors.New 用法之外，我们还可以实现 error 接口自定义一个 Error() 方法，来返回自定义的错误信息。&lt;/p></description></item><item><title>Go 语言中的带有缓冲 Channel（Let's Go 三十一）</title><link>https://qiucode.cn/article/151/</link><pubDate>Mon, 31 Oct 2022 11:27:56 +0000</pubDate><guid>https://qiucode.cn/article/151/</guid><description>&lt;p>无缓冲信道 Channel 是无法保存任何值的，该类型信道要求 发送 goroutine 和 接受 goroutine 两者同时准备好，这样才能完成发送与接受的操作。&lt;/p></description></item><item><title>Go 语言中的单向 Channel（Let's Go 三十）</title><link>https://qiucode.cn/article/150/</link><pubDate>Sat, 29 Oct 2022 10:53:15 +0000</pubDate><guid>https://qiucode.cn/article/150/</guid><description>&lt;p>通过上篇文章，我们知道该怎么声明信道 Channel，以及发送和读取数据。然而本文要讲的是&lt;code>单向Channel&lt;/code>，可单向信道Channel到底是怎样的呢？&lt;/p></description></item><item><title>Go 语言中的 Channel（Let's Go 二十九）</title><link>https://qiucode.cn/article/149/</link><pubDate>Thu, 27 Oct 2022 12:43:09 +0000</pubDate><guid>https://qiucode.cn/article/149/</guid><description>&lt;p>Channel 是进程内的通信方式，因此通过 channel 传递对象的过程和调用函数时的参数传递行为比较一致，比如也可以传递指针等。如果需要跨进程通信，我们建议用分布式系统的方法来解决，比如使用 Socket 或者 HTTP 等通信协议。Go 语言对于网络方面也有非常完善的支持。&lt;/p></description></item><item><title>Go 语言中的并发编程（Let's Go 二十八）</title><link>https://qiucode.cn/article/148/</link><pubDate>Mon, 24 Oct 2022 11:13:34 +0000</pubDate><guid>https://qiucode.cn/article/148/</guid><description>&lt;p>并发与并行并不相同，并发主要由切换时间片来实现“同时”运行，并行则是直接利用多核实现多线程的运行，Go程序可以设置使用核心数，以发挥多核计算机的能力。&lt;/p></description></item><item><title>Go 语言中的空接口（Let's Go 二十七）</title><link>https://qiucode.cn/article/147/</link><pubDate>Sun, 23 Oct 2022 13:25:50 +0000</pubDate><guid>https://qiucode.cn/article/147/</guid><description>&lt;p>所谓空接口就是没有方法集，以至于任何类型都可实现它，换言之，也就是空接口可以保存任意类型的值。&lt;/p></description></item><item><title>Go 语言中的类型断言（Let's Go 二十六）</title><link>https://qiucode.cn/article/146/</link><pubDate>Sat, 22 Oct 2022 13:26:16 +0000</pubDate><guid>https://qiucode.cn/article/146/</guid><description>&lt;p>如果&lt;code>Type&lt;/code>是具体某个类型，类型断言会检查 &lt;code>varl&lt;/code>的动态类型是否等于具体类型 &lt;code>Type&lt;/code>。如果检查成功，类型断言返回的结果是 &lt;code>varl&lt;/code> 的动态值，其类型是 &lt;code>Type&lt;/code>。 - 如果 &lt;code>Type&lt;/code> 是接口类型，类型断言会检查 &lt;code>varl&lt;/code> 的动态类型是否满足&lt;/p></description></item><item><title>Go 语言中的接口（Let's Go 二十五）</title><link>https://qiucode.cn/article/145/</link><pubDate>Fri, 21 Oct 2022 12:20:28 +0000</pubDate><guid>https://qiucode.cn/article/145/</guid><description>&lt;p>要想实现&lt;code>Go&lt;/code>中的接口，类型实现接口方法集的方法，其类型实现的方法签名必须要与接口中的方法集中方法签名一样。 类型不需要显式声明它实现了某个接口：接口被隐式地实现。多个类型可以实现同一个接口。&lt;/p></description></item><item><title>Go 语言中的方法（Let's Go 二十四）</title><link>https://qiucode.cn/article/144/</link><pubDate>Wed, 19 Oct 2022 13:31:31 +0000</pubDate><guid>https://qiucode.cn/article/144/</guid><description>&lt;p>Go中的方法是一种特殊的函数，以实现类型与函数进行绑定&lt;/p></description></item><item><title>原创 Go 语言中的结构体（Let's Go 二十三）</title><link>https://qiucode.cn/article/143/</link><pubDate>Fri, 14 Oct 2022 13:33:44 +0000</pubDate><guid>https://qiucode.cn/article/143/</guid><description>&lt;p>&lt;code>Go&lt;/code>中的结构体与&lt;code>c/c++&lt;/code>语言中是差不多，然而对没有接触过&lt;code>c/c++&lt;/code>语言的话，对在看到结构体这一&lt;code>复合类型&lt;/code>是新鲜事物。&lt;/p></description></item><item><title>Go 语言中的延迟执行【defer】（Let's Go 二十二）</title><link>https://qiucode.cn/article/142/</link><pubDate>Wed, 12 Oct 2022 12:07:27 +0000</pubDate><guid>https://qiucode.cn/article/142/</guid><description>&lt;p>函数作为另一个函数的形参，这就是Go当中的回调函数。&lt;/p></description></item><item><title>Go 语言中的闭包和可变参数（Let's Go 二十一）</title><link>https://qiucode.cn/article/141/</link><pubDate>Wed, 05 Oct 2022 13:10:40 +0000</pubDate><guid>https://qiucode.cn/article/141/</guid><description>&lt;p>在前面几篇文章，我们一直在使用&lt;code>Println、Printf&lt;/code>函数，你可能没有特别注意到，就是我们可以传入任意参数。而这种可以接受任意实参的函数，函数的形参极有可能是&lt;code>可变参数&lt;/code>，使用&lt;code>...type&lt;/code>可声明&lt;code>可变参数&lt;/code>，但必须是形参列表的最后&lt;/p></description></item><item><title>Go 语言中的函数变量与匿名函数（Let's Go 二十）</title><link>https://qiucode.cn/article/140/</link><pubDate>Tue, 04 Oct 2022 12:50:36 +0000</pubDate><guid>https://qiucode.cn/article/140/</guid><description>&lt;p>一上来乍一看，函数变量？这究竟是什么意思呢？你函数就函数，变量便是变量，这两者搞在一块，到底是几个意思呢？ 其实啊，在&lt;code>Go&lt;/code>当中，&lt;code>函数&lt;/code>也是一种类型，既然是类型，那就可以向其它类型一样，给变量定义类型啊！而这个类型是&lt;code>函数&lt;/code>，所以&lt;code>函数类型&lt;/code>&lt;/p></description></item><item><title>Go 语言中的函数详解（Let's Go 十九）</title><link>https://qiucode.cn/article/139/</link><pubDate>Mon, 03 Oct 2022 11:28:50 +0000</pubDate><guid>https://qiucode.cn/article/139/</guid><description>&lt;p>在前面几篇文章，接触到的最多的是&lt;code>main&lt;/code>函数。&lt;code>Go&lt;/code> 如同&lt;code>c/c++&lt;/code>语言一样，对于声明函数也有属于自己的一套规则。&lt;/p></description></item><item><title>Go 语言中的 goto、break 以及 continue 语句（Let's Go 十八）</title><link>https://qiucode.cn/article/138/</link><pubDate>Sat, 01 Oct 2022 11:29:09 +0000</pubDate><guid>https://qiucode.cn/article/138/</guid><description>&lt;p>在提到关键字&lt;code>goto&lt;/code>，想必很多人都心有余悸吧，毕竟&lt;code>goto&lt;/code>可是编程语言界破坏代码可读性的罪魁祸首啊！以至于像&lt;code>c/c++&lt;/code>或类 c 的编程语言，都将&lt;code>goto&lt;/code>作为保留关键字，不建议使用，但如果你非要使用，谁人可阻止呢？&lt;/p></description></item><item><title>Go 语言中的 switch 结构（Let's Go 十七）</title><link>https://qiucode.cn/article/137/</link><pubDate>Fri, 30 Sep 2022 12:54:56 +0000</pubDate><guid>https://qiucode.cn/article/137/</guid><description>&lt;p>相较于&lt;code>c/c++&lt;/code>等的&lt;code>switch case&lt;/code>，&lt;code>Go&lt;/code>对&lt;code>switch&lt;/code>做了很大改进，&lt;code>case&lt;/code>与&lt;code>case&lt;/code>之间是不需要写上&lt;code>break&lt;/code>，也能跳出当前&lt;code>case&lt;/code>语句，而且，&lt;code>switch&lt;/code>表达式可以是任何类型的噢！&lt;/p></description></item><item><title>Go 语言中的 for 循环结构（Let's Go 十六）</title><link>https://qiucode.cn/article/136/</link><pubDate>Thu, 29 Sep 2022 12:03:10 +0000</pubDate><guid>https://qiucode.cn/article/136/</guid><description>&lt;p>&lt;code>Go&lt;/code>当中只有&lt;code>for&lt;/code>循环结构，可没有像&lt;code>c/c++&lt;/code>语言有&lt;code>while&lt;/code>、&lt;code>do ... while&lt;/code>的。&lt;code>for&lt;/code>循环结构与&lt;code>if&lt;/code>分支结构一样，可以省略&lt;code>()&lt;/code>，左大括号&lt;code>{&lt;/code>必须与&lt;code>for&lt;/code>在同一行。&lt;/p></description></item><item><title>Go 语言中的 if 分支结构（Let's Go 十五）</title><link>https://qiucode.cn/article/135/</link><pubDate>Wed, 28 Sep 2022 22:12:00 +0800</pubDate><guid>https://qiucode.cn/article/135/</guid><description>&lt;p>&lt;code>Go&lt;/code>当中的&lt;code>if&lt;/code>分支与&lt;code>c/c++&lt;/code>大致相同，只是可以省略&lt;code>条件表达式&lt;/code>的小括号&lt;code>()&lt;/code>，真的是，```G哦·``就是要特立独行。&lt;/p></description></item><item><title>Go 语言中的列表（Let's Go 十四）</title><link>https://qiucode.cn/article/134/</link><pubDate>Tue, 27 Sep 2022 14:05:01 +0000</pubDate><guid>https://qiucode.cn/article/134/</guid><description>&lt;p>列表插入函数的返回值会提供一个 *list.Element 结构，这个结构记录着列表元素的值以及与其他节点之间的关系等信息，从列表中删除元素时，需要用到这个结构进行快速删除。&lt;/p></description></item><item><title>Go 语言中的字典【map】（Let's Go 十三）</title><link>https://qiucode.cn/article/133/</link><pubDate>Tue, 27 Sep 2022 12:40:09 +0000</pubDate><guid>https://qiucode.cn/article/133/</guid><description>&lt;p>其实，&lt;code>map&lt;/code>是一对&lt;code>key（键）&lt;/code>与&lt;code>value（值）&lt;/code>对应的无序集合，又称为&lt;code>关联数组&lt;/code>或&lt;code>字典&lt;/code>。&lt;/p></description></item><item><title>Go 语言中的数组（Let's Go 十二）</title><link>https://qiucode.cn/article/132/</link><pubDate>Mon, 26 Sep 2022 12:32:58 +0000</pubDate><guid>https://qiucode.cn/article/132/</guid><description>&lt;p>其实啊，切片就好像一个完整的蛋糕，你用刀切了一小块，而这一块就是从那完整的蛋糕切了下来。&lt;/p></description></item><item><title>Go 语言中的数组（Let's Go 十一）</title><link>https://qiucode.cn/article/131/</link><pubDate>Sun, 25 Sep 2022 12:51:06 +0000</pubDate><guid>https://qiucode.cn/article/131/</guid><description>&lt;p>与&lt;code>c/c++&lt;/code>语言一样，数组的每个元素可以通过&lt;code>索引下标&lt;/code>进行访问，&lt;code>索引下标&lt;/code>是从&lt;code>0&lt;/code>开始到数组长度减去1的位置。&lt;code>内置函数 len()&lt;/code>可以返回数组中元素的个数。&lt;/p></description></item><item><title>Go 语言中的类型定义与类型别名（Let's Go 十）</title><link>https://qiucode.cn/article/130/</link><pubDate>Sun, 25 Sep 2022 11:18:22 +0000</pubDate><guid>https://qiucode.cn/article/130/</guid><description>&lt;p>类型别名顾名思义就是给类型起个别名。就像上学时候，同学间开玩笑，给人以某种特征起了个外号，又或是英语老师给你起个英文名字，不管是外号、小名还是英文名字，最终都是指向你。&lt;/p></description></item><item><title>Go 语言中的指针（Let's Go 九）</title><link>https://qiucode.cn/article/129/</link><pubDate>Sun, 25 Sep 2022 07:34:56 +0000</pubDate><guid>https://qiucode.cn/article/129/</guid><description>&lt;p>&lt;code>*&lt;/code>操作符作为&lt;code>右值&lt;/code>时，意义是&lt;code>取指针的值&lt;/code>，作为&lt;code>左值&lt;/code>时，也就是放在&lt;code>赋值操作符的左边&lt;/code>时，表示 &lt;code>a 指针指向的变量&lt;/code>。其实归纳起来，&lt;code>*&lt;/code>操作符的根本意义就是操作&lt;code>指针指向的变量&lt;/code>。当操作在&lt;code>右值&lt;/code>时，就是&lt;code>取指向变量的值&lt;/code>，当操作&lt;/p></description></item><item><title>Go 语言中的关键字与标识符（Let's Go 八）</title><link>https://qiucode.cn/article/128/</link><pubDate>Sat, 24 Sep 2022 12:34:00 +0000</pubDate><guid>https://qiucode.cn/article/128/</guid><description>&lt;p>标识符是指&lt;code>Go语言&lt;/code>对各种变量、方法、函数等命名时使用的&lt;code>字符序列&lt;/code>，&lt;code>标识符&lt;/code>由若干个&lt;code>字母&lt;/code>、&lt;code>下划线 _ &lt;/code> 、和&lt;code>数字&lt;/code>组成，&lt;code>且第一个字符必须是字母&lt;/code>。通俗的讲就是凡可以自己定义的名称都可以叫做&lt;code>标识符&lt;/code>。&lt;/p></description></item><item><title>Go 语言中的常量定义（Let's Go 七）</title><link>https://qiucode.cn/article/127/</link><pubDate>Sat, 24 Sep 2022 11:34:30 +0000</pubDate><guid>https://qiucode.cn/article/127/</guid><description>&lt;p>&lt;code>Go&lt;/code>中定义常量与&lt;code>C语言&lt;/code>一样，也是使用&lt;code>const&lt;/code>关键字来定义常量的。常量声明语法：&lt;code>const name [typeName] = value&lt;/code>，其中&lt;code>typeName&lt;/code>（类型）可省略！ 常量可以是字符、字符串、布尔值或数值。 常量不能用 &lt;code>:=&lt;/code> 语法声明。&lt;/p></description></item><item><title>Go 语言中的类型转换以及类型推导（Let's Go 六）</title><link>https://qiucode.cn/article/126/</link><pubDate>Sat, 24 Sep 2022 07:50:28 +0000</pubDate><guid>https://qiucode.cn/article/126/</guid><description>&lt;p>在声明一个变量而不指定其类型时（即使用不带类型的 &lt;code>:=&lt;/code> 语法或 &lt;code>var =&lt;/code> 表达式语法），变量的类型由右值推导得出。&lt;/p></description></item><item><title>Go 语言中的字符串（Let's Go 五）</title><link>https://qiucode.cn/article/125/</link><pubDate>Sat, 24 Sep 2022 06:15:40 +0000</pubDate><guid>https://qiucode.cn/article/125/</guid><description>&lt;p>字符串想必是所有编程语言最为基础的类型，当然，Go中也不另外，字符串可根据需要会占用&lt;code>1&lt;/code>到&lt;code>4&lt;/code>个字节内存，由于&lt;code>Go&lt;/code>采用的是&lt;code>UTF-8&lt;/code>字符集编码格式，所以&lt;code>Go&lt;/code>不需要像其他编程语言那样对使用UTF-8字符集的文本进行编码与解码。&lt;/p></description></item><item><title>Go 语言中的多变量同时赋值、匿名变量以及变量作用域（Let's Go 四）</title><link>https://qiucode.cn/article/124/</link><pubDate>Thu, 22 Sep 2022 13:54:28 +0000</pubDate><guid>https://qiucode.cn/article/124/</guid><description>&lt;p>在函数体外声明的变量称之为全局变量，全局变量只需要在一个源文件中定义，就可以在所有源文件中使用，当然，不包含这个全局变量的源文件需要使用“import”关键字引入全局变量所在的源文件之后才能使用这个全局变量。&lt;/p></description></item><item><title>Go 语言中的基本类型以及变量声明与初始化（Let's Go 三）</title><link>https://qiucode.cn/article/123/</link><pubDate>Wed, 21 Sep 2022 13:39:14 +0000</pubDate><guid>https://qiucode.cn/article/123/</guid><description>&lt;p>刚才只是声明了变量，并没有给他赋值，虽然可以只是只声明变量，而后赋值也是可以的。但可以在声明变量是并初始化变量，也就是给变量赋初始值。&lt;/p></description></item><item><title>使用集成开发环境来开发Go项目</title><link>https://qiucode.cn/article/122/</link><pubDate>Tue, 20 Sep 2022 12:59:15 +0000</pubDate><guid>https://qiucode.cn/article/122/</guid><description>&lt;p>工欲善其事，必先利其器。好的集成开发环境（IDE）能让你事倍功半，好了，废话少扯，下来介绍几种能开发Go项目的IDE。&lt;/p></description></item><item><title>window下安装 Go 语言开发包</title><link>https://qiucode.cn/article/121/</link><pubDate>Mon, 19 Sep 2022 15:11:00 +0000</pubDate><guid>https://qiucode.cn/article/121/</guid><description>&lt;p>在window下安装最新Go语言开发包&lt;/p></description></item><item><title>ag-grid 右键单元格动态改变单元格样式</title><link>https://qiucode.cn/article/120/</link><pubDate>Tue, 14 Jun 2022 11:57:17 +0000</pubDate><guid>https://qiucode.cn/article/120/</guid><description>&lt;p>在window下安装最新Go语言开发包自定义单元格单击或右键时，给单元格添加不一样的样式而苦苦搜寻，可找了好久却好像都没有呢？巧了，笔者已经实现了这一看似很简单地功能！&lt;/p></description></item><item><title>自定义vxe-table表头标题文字过多，显示两行多余省略号并给出tooltip</title><link>https://qiucode.cn/article/119/</link><pubDate>Sat, 11 Jun 2022 02:57:48 +0000</pubDate><guid>https://qiucode.cn/article/119/</guid><description>&lt;p>自定义vxe-table表头标题文字过多，显示两行多余省略号并给出tooltip&lt;/p></description></item><item><title>vue vxe-table表格标题根据内容宽度自动换行</title><link>https://qiucode.cn/article/117/</link><pubDate>Thu, 02 Jun 2022 15:58:34 +0000</pubDate><guid>https://qiucode.cn/article/117/</guid><description>&lt;p>表格标题内容过多时，换行显示且多余部分以省略号显示。&lt;/p></description></item><item><title>Chrome扩展程序开发入门（基于 V3）</title><link>https://qiucode.cn/article/113/</link><pubDate>Tue, 08 Mar 2022 06:05:48 +0000</pubDate><guid>https://qiucode.cn/article/113/</guid><description>&lt;p>Chrome扩展指的是通过调用 Chrome 提供的 Chrome API 来扩展浏览器功能的一种组件，工作在浏览器层面，使用 HTML + Javascript 语言开发[*]。比如著名的 Adblock plus。&lt;/p></description></item><item><title>Ubuntu 16.04LTS 安装 redis-6.2.6（源码安装）</title><link>https://qiucode.cn/article/112/</link><pubDate>Mon, 10 Jan 2022 10:26:44 +0000</pubDate><guid>https://qiucode.cn/article/112/</guid><description>&lt;p>Ubuntu 16.04LTS 安装 redis-6.2.6（源码安装）&lt;/p></description></item><item><title>Navicat Premium 12连接Oracle时提示oracle library is not loaded的问题解决</title><link>https://qiucode.cn/article/111/</link><pubDate>Sun, 22 Aug 2021 02:42:26 +0000</pubDate><guid>https://qiucode.cn/article/111/</guid><description>&lt;p>解决Navicat12连接Oracle报oracle library is not loaded的提示问题&lt;/p></description></item><item><title>Git版本控制教程之在Visual Studio Code中如何使用（四）</title><link>https://qiucode.cn/article/109/</link><pubDate>Sat, 24 Jul 2021 07:27:10 +0000</pubDate><guid>https://qiucode.cn/article/109/</guid><description>&lt;p>在前面几篇讲解了git命令行的基本操作后，本篇将持续讲解git在VS code编辑器中是如何工作的？&lt;/p></description></item><item><title>Git版本控制教程之分支（三）</title><link>https://qiucode.cn/article/108/</link><pubDate>Sat, 17 Jul 2021 09:41:13 +0000</pubDate><guid>https://qiucode.cn/article/108/</guid><description>&lt;p>几乎所有的版本控制系统都以某种形式支持分支。 使用分支意味着你可以把你的工作从开发主线上分离开来，以免影响开发主线。 在很多版本控制系统中，这是一个略微低效的过程——常常需要完全创建一个源代码目录的副本。对于大项目来说，这样的过程会耗费很多时间。&lt;/p></description></item><item><title>Git版本控制教程之为项目打上标签（二）</title><link>https://qiucode.cn/article/107/</link><pubDate>Sun, 11 Jul 2021 07:14:55 +0000</pubDate><guid>https://qiucode.cn/article/107/</guid><description>&lt;p>git为项目打上标签，例如，可以在项目稳定阶段或测试阶段，都可以打上一个版本号作为标签名。&lt;/p></description></item><item><title>Git版本控制入门教程（一）</title><link>https://qiucode.cn/article/106/</link><pubDate>Sat, 10 Jul 2021 06:52:05 +0000</pubDate><guid>https://qiucode.cn/article/106/</guid><description>&lt;p>重新整理关于git版本控制的操作教程，相信你在看了这篇文章，你会更加清晰的认识git，和熟练的使用git&lt;/p></description></item><item><title>PHP 处理数据为树状结构</title><link>https://qiucode.cn/article/105/</link><pubDate>Sun, 04 Jul 2021 08:27:52 +0000</pubDate><guid>https://qiucode.cn/article/105/</guid><description>&lt;p>PHP处理没有父子级关系的数据为树状结构数据，对二维数组以某个键值相同的分组合并，最终形成树状结构数据&lt;/p></description></item><item><title>BootstrapTable 动态显示/隐藏某一行</title><link>https://qiucode.cn/article/103/</link><pubDate>Sun, 23 May 2021 03:05:04 +0000</pubDate><guid>https://qiucode.cn/article/103/</guid><description>&lt;p>手写实现自动隐藏/显示BootstrapTable表格行&lt;/p></description></item><item><title>xhr模拟表单下载文件</title><link>https://qiucode.cn/article/97/</link><pubDate>Sun, 25 Apr 2021 03:56:09 +0000</pubDate><guid>https://qiucode.cn/article/97/</guid><description>&lt;p>使用javascript原生XHR下载流文件，可进行计时下载，当然也是可以通过from表单进行下载文件的，但页面可能会有跨域问题，索性就在PHP做个桥接处理了。&lt;/p></description></item><item><title>SpringBoot使用FreeMarker模板发送邮件</title><link>https://qiucode.cn/article/96/</link><pubDate>Sat, 17 Apr 2021 13:38:07 +0000</pubDate><guid>https://qiucode.cn/article/96/</guid><description>&lt;p>Springboot2.x结合FreeMarker使用模板定制属于自己的邮件，瞬间是不是觉得很炫酷啊，那还不赶快去试试看啊&lt;/p></description></item><item><title>PHP使用curl上传文件到远程服务器接口</title><link>https://qiucode.cn/article/94/</link><pubDate>Sun, 11 Apr 2021 06:27:44 +0000</pubDate><guid>https://qiucode.cn/article/94/</guid><description>&lt;p>PHP使用CURL上传文件到远程服务接口&lt;/p></description></item><item><title>docker 安装[7.2-fpm-alpine]与nginx-1.13.0-alpine</title><link>https://qiucode.cn/article/93/</link><pubDate>Sun, 11 Apr 2021 03:33:51 +0000</pubDate><guid>https://qiucode.cn/article/93/</guid><description>&lt;p>docker 容器安装php-fpm和nginx&lt;/p></description></item><item><title>Ubuntu 16.04 LTS 安装redis</title><link>https://qiucode.cn/article/92/</link><pubDate>Sun, 28 Mar 2021 08:02:23 +0000</pubDate><guid>https://qiucode.cn/article/92/</guid><description>&lt;p>redis缓存替换为最新版本，所以记录一下安装过程，【秋码记录】redis缓存也做了相应更换，故而微信小程序就没空写了&lt;/p></description></item><item><title>微信小程序电商实战—首页篇（上）</title><link>https://qiucode.cn/article/91/</link><pubDate>Sat, 20 Mar 2021 11:47:53 +0000</pubDate><guid>https://qiucode.cn/article/91/</guid><description>&lt;p>本文将接上一篇，实现首页上半部分，导航滚动与首页轮播图，首页部分分为两篇来讲解&lt;/p></description></item><item><title>微信小程序电商实战—环境搭建篇</title><link>https://qiucode.cn/article/90/</link><pubDate>Sat, 06 Mar 2021 06:55:30 +0000</pubDate><guid>https://qiucode.cn/article/90/</guid><description>&lt;p>微信小程序电商实战之环境搭建篇，首先先去微信公众号—小程序下载微信开发者工具。&lt;/p></description></item><item><title>Fastadmin后台管理之表格行内编辑requireJS加载x-editable.js</title><link>https://qiucode.cn/article/89/</link><pubDate>Sun, 28 Feb 2021 14:12:52 +0000</pubDate><guid>https://qiucode.cn/article/89/</guid><description>&lt;p>由于Fastadmin官方只有安装表格可编辑的插件才有这个功能，但笔者是一个爱折腾的人，所以也就有了本文，requireJS加载BootstrapTable扩展功能，表格可编辑，基于x-editable.js扩展库&lt;/p></description></item><item><title>Centos7 安装配置 PHP7 Nginx 并部署开源后台系统Fasadmin</title><link>https://qiucode.cn/article/88/</link><pubDate>Sun, 21 Feb 2021 03:34:16 +0000</pubDate><guid>https://qiucode.cn/article/88/</guid><description>&lt;p>由于Fastadmin官网文档没有关于Centos7的部署文档，其实与Ubuntu安装部署差不了多少，故而笔者在Centos7部署了Fastadmin。&lt;/p></description></item><item><title>git使用教程之创建本地库并关联远程库（笔记整理篇一）</title><link>https://qiucode.cn/article/85/</link><pubDate>Sun, 06 Dec 2020 11:14:01 +0000</pubDate><guid>https://qiucode.cn/article/85/</guid><description>&lt;p>Git是分布式版本控制系统，那么它就没有中央服务器的，每个人的电脑就是一个完整的版本库，这样，工作的时候就不需要联网了，因为版本都是在自己的电脑 上。既然每个人的电脑都有一个完整的版本库，那多个人如何协作呢？比如说自己在电脑上改了文件A，其他人也在电脑上改了文件A，这时，你们两之间只需把各 自的修改推送给对方，就可以互相看到对方的修改了。&lt;/p></description></item><item><title>Springboot对上传图片添加水印后存储到阿里云OSS对象存储中</title><link>https://qiucode.cn/article/79/</link><pubDate>Sat, 05 Sep 2020 09:14:24 +0000</pubDate><guid>https://qiucode.cn/article/79/</guid><description>&lt;p>好些时候没发表文章了，由于最近有点忙，又更兼&lt;code>qiucode&lt;/code>站点页面大改，新版页面也较旧版整洁多了！那具体该是如何实现呢？（言外之意无非就是程序怎么实现的），其实无非就是将&lt;code>MultipartFile&lt;/code>对象进行二次处理（这里所说的处理就是在上传的原图的基础上添加水印），二次处理好了的图片远程存储到阿里云oss存储对象中。&lt;/p></description></item><item><title>池塘中鱼的困惑</title><link>https://qiucode.cn/article/118/</link><pubDate>Sun, 18 Aug 2019 20:43:15 +0000</pubDate><guid>https://qiucode.cn/article/118/</guid><description>&lt;p>盛夏，多云，晌午时分。一群隐蔽于桥底下乘凉地鱼正往池边四处游来游去，从东边游到西边，游速不是很快，大家在游的过程，都在望着从池塘边路过的人，似乎在期待人们施舍食物。为什么这么说呢？且听当事鱼讲述这池塘的生活经历。&lt;/p></description></item><item><title>Java8四大核心内置函数式接口</title><link>https://qiucode.cn/article/1/</link><pubDate>Sun, 23 Jun 2019 13:30:15 +0000</pubDate><guid>https://qiucode.cn/article/1/</guid><description>&lt;p>在前面简单介绍了一些Lambda表达式得好处与语法，我们知道使用Lambda表达式是需要使用函数式接口得，那么，岂不是在我们开发过程中需要定义许多函数式接口，其实不然，java8其实已经为我们定义好了4类内置函数式接口，这4类接口其实已经可以解决我们开发过程中绝大部分的问题，只有一小部分比较特殊得情况需要我们自己去定义函数式接口，本文就简单来学习一下java8内置得4大核心函数式接口。&lt;/p></description></item><item><title>Java 8 函数式接口编程</title><link>https://qiucode.cn/article/78/</link><pubDate>Sat, 22 Jun 2019 03:18:26 +0000</pubDate><guid>https://qiucode.cn/article/78/</guid><description>&lt;p>Java8与2014年9月份发布的，经过多年市场体验，俨然已有很多开源框架和企业在使用Java8了。介于于此，也该回顾下Java8的新特性了，这样也便于后面看开源框架源码也不至于不知其新语法。&lt;/p></description></item><item><title> Extjs 3.3 tree以下的版本在IE10无法点击的解决办法</title><link>https://qiucode.cn/article/114/</link><pubDate>Wed, 24 Apr 2019 21:06:11 +0000</pubDate><guid>https://qiucode.cn/article/114/</guid><description>&lt;p>距上篇文章已过去好几天了，说好的一周发表1到3篇文章，难道都让狗吃了吗？现在才发布一篇而且还是转载的文章。好了，闲话少叙，切入正题，Extjs前端框架是比较早的前端mvc框架了，可能很多人都没接触过，而且现在也很少有项目用Extjs框架搭建了，原因是什么？那就不得而知了，有人说是Extjs比较重……&lt;/p></description></item><item><title>Ztree整合SpringMVC实现异步加载树</title><link>https://qiucode.cn/article/116/</link><pubDate>Fri, 05 Apr 2019 19:17:36 +0000</pubDate><guid>https://qiucode.cn/article/116/</guid><description>&lt;p>正值清明时节，天气也将开始升温了，夏天即将到来，你做好准备了吗？好了，废话少扯，切入正题，本文笔者将要讲解的是JQuery的树插件Ztree。现在web项目基本上也都是使用Ztree作为树组件进行实现的。&lt;/p></description></item><item><title>在npm上发布基于Vue2.x开发的UI组件库（记录篇）</title><link>https://qiucode.cn/article/104/</link><pubDate>Mon, 25 Feb 2019 01:24:32 +0000</pubDate><guid>https://qiucode.cn/article/104/</guid><description>&lt;p>解决Navicat12连接Oracle报oracle library is not loaded的提示问题基于Vue开发的UI组件库肯定是要公用的，虽然可以在每创建一个Vue项目时可以复制这些组件，如果组件比较大的情况下呢？是不是很不方便呢？&lt;/p></description></item><item><title>开发一套基于Vue2.x的UI组件库（环境搭建篇《一》）</title><link>https://qiucode.cn/article/83/</link><pubDate>Sat, 16 Feb 2019 23:37:45 +0000</pubDate><guid>https://qiucode.cn/article/83/</guid><description>&lt;p>基于Vue2.x开发的UI 组件库有很多，诸如 iView UI组件库、Element UI组件库 等等，既然有这么优秀的UI组件，我们干嘛非要自己开发一套组件呢？&lt;/p></description></item><item><title>这条路，看似很远，望不见的路的“尽头</title><link>https://qiucode.cn/article/115/</link><pubDate>Wed, 06 Feb 2019 19:44:25 +0000</pubDate><guid>https://qiucode.cn/article/115/</guid><description>&lt;p>今天天气很好，午后遂与家人去登山，天是那么的蓝，空气是那么的清新，虽然路是崎岖的，但笔者走的还是很开心的！&lt;/p></description></item><item><title>Nexus 2.14.x本地仓库安装与maven配置</title><link>https://qiucode.cn/article/87/</link><pubDate>Sun, 20 Jan 2019 11:47:05 +0000</pubDate><guid>https://qiucode.cn/article/87/</guid><description>&lt;p>Nexus私服是架设在局域网的一种特殊的远程仓库，目的是代理远程仓库及部署第三方构件。有了私服之后，当 Maven 需要下载构件时，直接请求私服，私服上存在则下载到本地仓库；否则，私服请求外部的远程仓库，将构件下载到私服，再提供给本地仓库下载。&lt;/p></description></item><item><title>MPVue开发微信小程序（一）</title><link>https://qiucode.cn/article/84/</link><pubDate>Sun, 02 Dec 2018 11:17:26 +0000</pubDate><guid>https://qiucode.cn/article/84/</guid><description>&lt;p>跟着笔者使用mpvue快速开发微信小程序，徐循渐进地开发微信小程序，使用html构建你想要的界面布局&lt;/p></description></item><item><title>双十一抢购云服务器，总有一款适合您</title><link>https://qiucode.cn/article/82/</link><pubDate>Mon, 29 Oct 2018 23:26:20 +0000</pubDate><guid>https://qiucode.cn/article/82/</guid><description>&lt;p>深夜发表文章，只为阿里云云服务器双十一搞活动，1核2G 云服务器 1年 84元。如果你错过了上次阿里云拼团的机会，那就在双十一这次拼团不要再错过了，这次拼团也是相对来说性价比也是比较优惠的！&lt;/p></description></item><item><title>ThinkPHP5.x入门（重拾知识篇）</title><link>https://qiucode.cn/article/110/</link><pubDate>Sat, 27 Oct 2018 21:50:47 +0000</pubDate><guid>https://qiucode.cn/article/110/</guid><description>&lt;p>由于这段时间可能会不怎么有空，但基本上每周写一篇吧！看到重拾知识篇就应该知道了吧！笔者肯定对PHP也是了解的，没错，是的，笔者是懂得PHP，那你是不是也跟笔者一样啊？是否也熟知PHP这门号称“世界上最好用的语言”呢？ 是不是曾几何时，有过从事PHP方面的工作呢？&lt;/p></description></item><item><title>CentOS 7安装Nginx反向代理服务器（云服务器篇）</title><link>https://qiucode.cn/article/102/</link><pubDate>Sun, 21 Oct 2018 15:21:50 +0000</pubDate><guid>https://qiucode.cn/article/102/</guid><description>&lt;p>距上一篇在CentOS 7 安装mysql也已经过去好几天了，正值云服务器试用结束之际，要把原在试用机的配置重新再新服务器安装一遍，在此借这个机会（也正值周日）记录一下Nginx反向代理服务器的配置。&lt;/p></description></item><item><title>cocos2d-x实现跑酷游戏之一（重拾知识篇）</title><link>https://qiucode.cn/article/101/</link><pubDate>Thu, 11 Oct 2018 22:47:03 +0000</pubDate><guid>https://qiucode.cn/article/101/</guid><description>&lt;p>好久没去关注cocos2d-x游戏引擎了！时隔多久，我是记不太清楚了，本篇属于温习知识吧，毕竟笔者最初的梦想是开发一个像现在大家平时没事就爱消磨时间的游戏，然而，事与愿违，没能成为一个游戏开发者，竟成了一个Java开发者（请允许我也可以在你们这些Java大佬面前自称为Java开发者）。&lt;/p></description></item><item><title>CentOS 7 安装mysql5.6 （云服务器篇）</title><link>https://qiucode.cn/article/100/</link><pubDate>Sun, 07 Oct 2018 21:18:11 +0000</pubDate><guid>https://qiucode.cn/article/100/</guid><description>&lt;p>无论是互联网行业，还是其他任何行业，数据对于一个公司来讲是至关重要的，也是企业维系用户的得以持续发展的重要资源！\n对于前两篇文章已经讲解了在CentOS 7如何安装JDK8 和Tomcat7，那么作为JavaWeb开发，显然数据库是必不可少的，至少目前来说是这样的。那好，那就跟笔者循序渐进地开始下去吧！&lt;/p></description></item><item><title>CentOS 7 安装 Tomcat 7（云服务器篇）</title><link>https://qiucode.cn/article/98/</link><pubDate>Sun, 07 Oct 2018 16:26:14 +0000</pubDate><guid>https://qiucode.cn/article/98/</guid><description>&lt;p>在前一篇介绍在CentOS 7如何安装 JDK，而这一篇可以说是开发Javaweb所需的web容器可选之一，如果你在浏览上一篇时已是得心应手了，相信你在CentOS 7安装Tomcat 已经不是什么事了！虽然有点傲慢，但还是可以窃喜的！&lt;/p></description></item><item><title>CentOS 7 安装JDK 8（云服务器篇）</title><link>https://qiucode.cn/article/99/</link><pubDate>Sun, 07 Oct 2018 11:28:43 +0000</pubDate><guid>https://qiucode.cn/article/99/</guid><description>&lt;p>云服务器Centos 7 如何安装JDK？这一篇文章你不容错过！它将介绍你在云服务器CentOS 7 如何安装JDK 8，图文并茂，通俗易懂，新手也能搭配！更何况你呢？如果你正在为如何在云服务器 CentOS 7 中如何安装JDK？那这篇文章再合适不过了！相信我，当你阅读完这篇文章后，云服务器CentOS 7 安装 JDK已不是什么触不可及了，让人望而却步了！&lt;/p></description></item><item><title>关于 本站点 的一些秘闻</title><link>https://qiucode.cn/about/</link><pubDate>Sat, 06 Oct 2018 20:12:52 +0800</pubDate><guid>https://qiucode.cn/about/</guid><description>关于博主
这该怎么介绍呢？按简介说是‘一个游离于山间之上的Java爱好者’，其实这样说也不为过， 的确是一个Java从业者。然这只是他爱好之一，他对中国历史很是推崇备至，尤其是先秦时期， 特别是春秋战国那段历史，那时候诸子百家，思想空前。而此后便从未有过像春秋战国这样的思想辩论了， 虽说春秋战国时期也有过勾心斗角，但这段历史却没有像后续各个王朝内的奸佞小人与忠臣间的攻于心计来的凶狠。 他还偏爱书法，优爱草书，但苦于无闲暇之余，故许久未曾研习书法，待他日得空，必当重习书法，书体不限！ 除了历史、书法，他还是个文字控，尤其是对古文、古诗词特喜好，每每读到绝佳好词、好诗，他都会将其抄录下来。 当然抛去以上种种爱好，他还想立志成为一个小说家呢，这都是后话了……
秋码记录
其实很早之前就有想弄一个属于自己的网站，但由于种种原因吧，最终也就没建成。时间追溯到2018年10月初， 国庆期间，放假闲暇之余偶然浏览了Layui官网，在其案例页面内浏览了 诸多使用Layui快速搭起了个人博客，在浏览之余，觉得使用Layui 搭建的个人博客界面看上去很是优美，故而自己便马上着手准备开干起来。说干就干，先买了个服务器。而后又注册了 qiucode.cn域名，随后一个基于Springboot2.x+Mybatis+Mysql5.7，前端使用Layui 的个人博客便部署到了服务器上。现在从某种意义上来说，暂且称为【秋码记录】第一版吧！这一版的博客源码也已于 2019年06月27日开源了，源于开源，回馈于开源！
Github地址： https://github.com/zhenqicai/qiucodeBlog
码云地址： https://gitee.com/zhenqi/qiucodeBlog
qiucode-ui
基于Vue2.x开发的一套UI组件库，主要是学习Vue2.x。
github地址： https://github.com/zhenqicai/qiucodeUI
qiucode-ui在线文档地址： https://zhenqicai.github.io/qiucodeUI-docs
同一地方
首部文学作品发表起点中文网，笔名：上官江南。初写或许可能并不是写的那么的好，但既然写了，就会把它写好，写完， 不管怎样都会坚持写下去的。更多的是以起点中文网作为锻炼文学功底的平台。
联系方式
公众号：你我杂志刊
QQ： 2834491983</description></item><item><title>友情链接</title><link>https://qiucode.cn/flinks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://qiucode.cn/flinks/</guid><description> 如想交换本站友情链接，请在评论区留下你的站点信息，格式参考如下：</description></item><item><title>秋码记录大事件</title><link>https://qiucode.cn/timeline/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://qiucode.cn/timeline/</guid><description/></item></channel></rss>