python3.12安装numpy1.25.2不兼容问题

• Installing numpy (1.25.2): Failed ChefBuildError Backend 'setuptools.build_meta:__legacy__' is not available. Traceback (most recent call last): File "/opt/homebrew/Cellar/poetry/1.7.1/libexec/lib/python3.12/site-packages/pyproject_hooks/_in_process/_in_process.py", line 77, in _build_backend obj = import_module(mod_path) ^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/homebrew/Cellar/python@3.12/3.12.1_1/Frameworks/Python.framework/Versions/3.12/lib/python3.12/importlib/__init__.py", line 90, in import_module return _bootstrap._gcd_import(name[level:], package, level) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "<frozen importlib._bootstrap>", line 1387, in _gcd_import File "<frozen importlib._bootstrap>", line 1360, in _find_and_load File "<frozen importlib._bootstrap>", line 1310, in _find_and_load_unlocked File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed File "<frozen importlib._bootstrap>", line 1387, in _gcd_import File "<frozen importlib....

February 4, 2024 · 2 min

vscode-godot-配置

.vscode/lanch.json { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "GDScript Godot", "type": "godot", "request": "launch", "project": "${workspaceFolder}", "port": 6007, "address": "tcp://127.0.0.1", "launch_game_instance": true, "launch_scene": false } ] } .vscode/settings.json { "godot_tools.editor_path": "/Applications/Godot.app/Contents/MacOS/Godot", "godot_tools.gdscript_lsp_server_port": 6005, }

January 14, 2024 · 1 min

海的信徒

我生在海边 但一生只见过一次大海 我的母亲提醒我 “不要开口” 推开车门海边的喧嚣闯入我被匆匆挤出 海浪扑打瞳孔中蓝色沸腾我匆忙捂住嘴巴 不要 开口 堤坝空荡没有过客 世界很大,呼啸的海风将每个人隔绝 海在轰鸣 我松开双手,向海吼叫 海风带走我发出的每一句声响

January 7, 2024 · 1 min

双十一线上事故复盘

事故一 背景: 服务old一个前后端不分离的老项目,服务new是一个前后端分离的新服务。部分功能从服务old迁移到服务new,采用了请求重定向的方式,前端请求服务old的老接口后重定向到新服务。 现象: 大促前5分钟,应用tp99,tp999开始有个别报警超时,tp999响应时间超过20s。 事故二 经验: 永远不相信任何服务提供方,永远不强依赖服务提供方。 熔断、降级 熔断机制: 对R2M依赖过强,当R2M出现不可用了,实名没有熔断机制。 合理的设计应该是,假如分布式缓存服务不可用,则启用本地缓存并使用LRU机制,放弃峰值TPS和一定的成功率保证服务可用。 降级: 任何一个服务都要提供日志降级方式(这里又要引入熔断机制,假如依赖的动态配置服务挂了,那么所有的配置项应该启用默认配置,并且该配置应该是优先保证服务可用,可以牺牲可观察性,牺牲服务能力)

November 4, 2023 · 1 min

软件工程实践指南

本文记载我在软件工程实践过程中总结的经验 1、在生产环境为测试环境的凭证设置特殊报错 在实际开发过程中,我们可能会有各种各样的环境,这些环境可能会提供给业务方使用。我们的工程中经常会有权限校验操作,在测试环境为了方便可能会给业务方分配一个统一的凭证,而生产环境会分配单独的凭证。如果是这样,那么建议生产环境校验时为这个特殊凭证单独设置错误提示,以通知用户错误的将测试环境的凭证用于生产环境。 2、不要为pin等字段设置默认值 用户会使用pin,而有的时候我们会想要获取这些pin做日志等分析处理,如果获取不到这些pin应该使用null标记这些字段,而不是设置“unknown”等默认字段,因为客户可能会使用这些字段作为pin。 3、预防型捕获异常可以有,但是一定要在日志中指出是意料之外的异常 在业务导向比较强的代码中,可以在一些不必加try catch的地方显示捕获异常。因为一些代码在业务导向强的项目中属于边缘代码,比如埋点、日志等,对于一些业务比如个人实名来说这些代码可以失败但不能阻塞流程。预防性try catch能保证这部分代码不出问题,但是我无法保证同事或者其他中间件等

October 13, 2023 · 1 min

使用Spring自动注入时必须使用构造函数注入方式!

https://docs.spring.io/spring-framework/docs/5.3.25/reference/html/core.html#spring-core The Spring team generally advocates constructor injection, as it lets you implement application components as immutable objects and ensures that required dependencies are not null. Furthermore, constructor-injected components are always returned to the client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should 技术角度上说,依赖注入可以有field注入,setter注入方式和构造函数注入方式。技术角度上看,构造函数的优势在于保证返回的bean是完整的,且bean中依赖的其他类不为空。 然而在实际生产过程中,spring官方给的技术优势大部分开发并不关注,还是直接写一个域然后标一个autowired。...

September 19, 2023 · 1 min

翻译】每个开发者都必须了解的unicode和character sets(字符集)知识点

原文地址:https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ 你有没有想过content-type这个Tag是做什么的?就是当你写HTML时应该写的但是你从来不知道应该填什么的content-type。 Content-Type: text/html; charset=utf-8 Content-Type: multipart/form-data; boundary=something 你有没有收到过一份邮件里面有一行“????????????“ 我惊讶地发现有太多的开发者并不了解character sets, encodings, Unicode这些东西。 几年前,一个测试问我FogBUGZ(译者注:可能是原作者开发的一个软件)能不能用日语处理收到的邮件。日语?他们有用日语写的邮件?我完全没想过这回事。当我们仔细检查用来解析MIME邮件的商用版ActiveX control时,我们发现它确实错误处理了字符集(character sets),所以我们不得不写了一份代码去回滚它的错误并且重新对邮件进行解析。当我去看另一个商用版库的源代码时,我发现它的字符代码实现也非常差劲。我联系了这个包的开发者,他说他“对这个包也做不了更多的事“。就像很多程序员一样,他只想这件事就这样过去得了。 但是这件事不会就这样过去!当我发现主流的web开发工具PHP竟然有一个完全忽视字符集编码的issue(complete ignorance of character encoding issues),blithely使用了8个bit处理字符(characters),导致他妈的几乎不可能拿php开发出好的互联网应用。我觉得,这一切都该结束了。 在此我宣誓:如果你是一个在2003年工作的程序员,而你不知道characters, character sets, encodings和Unicode的基础知识。假设你被我逮着了,那我就要惩罚你在潜艇里切6个月洋葱。我发誓我会这样做的。 还有一件事: 它没有那么难。 在本文我将告诉你每一个在职程序员都应该知道的基础知识。“普通文本等于ASCII等于字符(characters)都是8比特的”这种想法,不仅是错误的,而且是非常错误的。如果你还带着这种想法编程,那你差不多相当于一个不懂细菌的医生。求你在没读完这篇文章前不要再写任何一行代码了。 在开始之前,我有一个提醒,如果你是那种比较罕见的懂国际化(internationalization)的人,你会发现我接下来的讨论有点过于简单了。我只想把最简单的教给大家,这样每个人都知道发生什么事了,并且能编写可以处理各种语言的代码而不是只有英语(甚至不能带重读符号)。我还要提醒你,字符处理知识创建国际化软件的一小部分,我有时间可以写点其他方面的,但今天我们只讲字符集(character sets)。 历史角度 了解一件事情最简单的方式就是跟着时间了解它。 你可能认为我会讲一些上古时期的字符集(character sets)比如EBCDIC。但是我不会。EBCDIC跟你的生活一点关系也没有。我们不会讲这么远的事。 在中古时期,当Unix被发明出来而K&R正在写《The C Programming Language》的时候,一切都很简单。EBCDIC正在退出历史舞台了。唯一需要处理的字符是哪些不带重音的英文字母。我们有一套叫做ASCII的编码可以用32到127之间的数据代表每一个字符。空格是32,字母‘A’是65,诸如此类。这些数字可以很方便地用7个比特存储下来。那时候大部分电脑都是用8bit的字节(8-bit bytes), 所以你不仅可以存下每一个ASCII字符,你还多出来整整1个bit。如果你耍点小聪明,这1个比特可以用于自己的目的。WordStar中的那群傻瓜就把最高位用于表示每个单词的最后一个字母,导致WordStar只能打印英语。用小于32的数字表示的字符是无法打印的(unprintable),被用于诅咒别人。开个玩笑。它们被当作控制字符使用(control characters),比如7会让计算机蜂鸣,12会导致打印机上的当前纸张飞出,让新纸填入。 这一切都很美好,如果你是一个英语使用者的话。 因为每个字节使用了8个比特,许多人就想到,“我们可以把128-255的数字给自己用”。问题在于很多人同时有了相同的想法,而且他们对于128到255的数字的用法都有自己独特的想法。IBM-PC 有一些后来被称为 OEM 字符集的东西,它为欧洲语言提供了一些重音字符和一系列线条绘制字符… … 水平条、垂直条、右边有小铃铛悬挂的水平条等等。 你可以用这些线条字符在屏幕上画好看的盒子和直线,用这些字符集画的画你仍然能在你的干洗机上的8088电脑上看到。事实上,当人们开始在美国以外购买个人电脑时,各种不同的OEM字符集就被设想出来了,这些字符集都是为了自己的目的而使用前128个字符。比如130在一些电脑上会被显示为é,但是在以色列售卖的电脑会将130显示为希伯来语Gimel(译者注:原文的字符打不出来),所以当美国人发送résumés到以色列时,以色列人会收到r(Gimel)sum(Gimel)s。在很多情况下,比如在俄罗斯,关于如何使用前128个字符有非常多的想法,所以交换两个俄语文档都是可能有问题的。 这种OEM混战的情况最终被ANSI标准敲定下来。在ANSI标准中,大家对小于128的数字该做什么都取得了一致认知,这点很像ASCII,但是从128开始的数字根据你所在的地区不同就有很多不同的方式处理了。这些不同的处理系统叫做*code pages。*比如以色列的DOS用的code page叫做862, 而希腊人使用的是737。小于128都是一样的,但是从128开始都完全不同了,而很多有趣的字母就出现在128之上(包括128)。MS-DOS的国际化版本有许多code page, 这些code page能处理各种语言,从英语到冰岛语,它们甚至还有一些多语言(multilingual)的code page可以同时在一台电脑上处理世界语和加利西亚语。哇!但是,在同一台计算机上同时显示希伯来语和希腊语是完全不可能的,除非你编写自己的自定义程序,使用位图图形显示所有内容,因为希伯来语和希腊语需要不同的代码页,对大数有不同的解释。 与此同时,亚洲的有成千上万的文字(letter),这些文字用8个比特是不可能装的下的。有一种糟糕的系统叫做DBCS(double byte character set)用来解决这类问题。在DBCS中,一些文字用1个字节存储,而另一些则使用两个字节存储。在字符串中向前移动很容易,但向后移动却几乎不可能。我们鼓励程序员不要使用 s++ 和 s- 来前后移动字符串,而是调用 Windows 的 AnsiNext 和 AnsiPrev 等函数,它们知道如何处理整个混乱的字符串。...

August 1, 2023 · 2 min

最近遇到的一些比较坑的bug

Bug:读取两个文件,然后输出这两个文件的内容。第一个文件输出始终为空,第二个文件可以正常输出。 解决:第一个文件损坏了(具体是什么原因未知),我将第一个文件的内容复制到一个文件中就可以正常使用了。 教训:永远要质疑输入的合法性 Bug:使用Gradio,按钮绑定了一个回调方法,这个方法内部调用了OpenAI做了对输入的两个文件进行处理。结果总是第一个文件处理完之后就停止了。 解决:实际上不是在第一个文件处理完之后停止,而是LLM处理第一个文件花费了大约1分钟,而Gradio默认一分钟回调方法没返回结果就超时失败。所以,设置Gradio应用启动为queue模式,取消超时等待。 教训:任何一个方法执行时间很长就得考虑是否存在超时失败 Bug:测试人员测试我写的的一套上传下载照片逻辑时,同时在测试环境测试了我的上传和下载接口,结果是下载下来的照片无法识别。 解决-1:这里有一个关键点,下载下来的照片无法识别这个问题,我一开始以为是加解密错误导致照片出现问题。但是加解密如果异常应该在程序中就报错。最后发现,下载下来的图片大小是0kb,但是Windows自带的照片预览会直接说无法识别该类型。 教训-1: 对于存储在磁盘上的文件一定首先检查文件大小(这让我想起来实习期的一个问题是因为文件本质是个软连接,如果第一时间查看大小就能看出问题) 解决-2: 代码中的上传下载逻辑我都有详细覆盖性很强的单元测试,本地都上传下载过,不应该出问题。遂回滚代码尝试,发现旧的代码也下载不了,经排查发现是测试环境的host配置错误了。 教训-2: 涉及到这种代码改造(不修改旧逻辑)的测试,在测试之前应该第一步先校验旧代码的可用性,我给它取个名字叫基准测试。 解决-3: 测试过程中,测试使用了另一个服务的接口间接调用了本服务的上传接口,结果走不通。在一开始,下意识认为是本服务的问题,因为另一个服务被使用的接口没有被改造。但排查后发现是另一个服务挂了(挂的原因是我在该服务上做了其他修改,导致服务没启动的了) 教训-3: 间接调用优先确保服务可用性 解决-4: 另一个服务挂掉的原因,是外部依赖更换了服务地址,所以代码中需要修改,而修改的点是另一位同事在改,今天上线并没有合并到master分支,导致我合并master分支时没有合到这部分代码。 教训-4: 如果代码有意料之外的问题,第一时间先看一下其他同事的开发分支有没有一些关键操作没有合并到master。同时也知道了合并master,以及branch命名,commit规范的重要性(要是都糊写一通,根本就没法快速排查)

July 11, 2023 · 1 min

钢铁之躯(片段)

“砰”,远处庭院中,泳池边,遮阳伞旁。在亚那州海滨的繁星下,复制器在完成最后的制造工作,打印一位计算机科学家的头颅。身体已经打印完成,挂在复制器三面体的一面上。 “如果我死去,不要打印我的头颅。”科里的旧语再一次在张博士脑中闪过。 “你知道对科学家来说,最大的耻辱是什么吗?”张博士询问身边一起前来的智宇,智宇被复制器的制造过程震惊到了,并没有留意张博士的提问。 “保存他的头颅。”博士自顾自地回答起来。 复制器最后的打印步骤完成,钢铁制的头颅上反射出星空璀璨。复制器的三面体开始旋转,将头颅扭转到躯体之上,随后发出一声闷响,头颅与躯体拼接完成。 复制器复制出的人低垂着头,复制器托着他双臂的支架唰地收起,复制人猛然落下,发出重重的落地声。 复制器的产物在诞生后的最初五分钟会重复主人生命中最后一天早上的行为,这个时候他们是记忆模糊的,或许是威本科技的技术限制导致,这五分钟威本科技并不能完全控制复制人。这五分钟或许也算是本体生命的延续。智宇这样想着,庭院中的复制人身体亮出隐隐的蓝光,缓缓抬起了头颅。 复制人向前走了几步,走到了一张吊床前,俯下身亲吻空气。接着他转身向另一处方桌走去,他在桌子上盘弄着空气,打翻了方桌上本来摆放的各类实验试剂以及子弹。盘弄了一两分钟,他左手托着一枚TR86杀人蜂微型导弹走到吊床旁,把托盘递了出去后,他松手,托盘摔碎,他坐在空气上,望着空空的吊床谈笑着。而后,他走到泳池边,对着博士和智宇的位置,开始梳妆打扮。 刷牙,洗脸,似乎摸了一些护肤品,最后当他开始梳理头发时,已经过了四分钟了。复制人的手在摸到自己的金属制头发时停顿了下,随后开始上下摸索。几秒钟后,他伸出双手,狠狠的掰断了自己的小拇指,他伸出手看向自己的手,似乎是在判断自己没有疼痛感,这也能解释为什么在宾西州的另一个科里也没有小拇指了。复制人望向泳池中的自己,突然崩溃的吼叫了一声,然后他的目光转向远处的博士和智宇。 远处的红色亮光闪过,智宇知道大事不好了,双眼的红光代表复制人进入了战斗模式。但没等他躲开,空中一个庞然大物已经落地,冲击波将智宇直接整飞到一旁的花圃中,尘土弥散过后,博士已经被复制人科里卡住脖子举了起来。 博士的紧紧抓住复制人科里的手,给自己争取一点点呼吸空间,他努力转头看向一旁落在地上的手机,屏幕碎裂,但是计时器的数字还在不断跳跃。 “5月18日,5月18。”复制人科里听到这个时间,扣住博士的手稍松了些劲。 “2034年5月18日16点08分,你认识梓萌,现在距离你们认识过去了68天,你们单独相处15天。” “梓。。。萌”,复制人科里缓缓地说出这个名字,抬起了头,松开了博士,跪倒下去,红色消失,复制人垂下了头。 五分钟到了,复制人科里身体冒出绿光,“威本科技为您服务,正在启动中。。。”复制人科里说到。

June 23, 2023 · 1 min

博客版面更新

今天,把博客的版面更新了一版本。最早的时候,我只想在此博客写技术文章。生活感想之类的还是在QQ空间里面写,而微信主要就发事业上相关的事情。在屡次被QQ空间删除说说,照片被屏蔽之后,我还是决定彻底放弃国内的社交平台。将日常的所思所想也搬运到本博客。加上之前写的散文,诗,小说等都散落在各个平台不方便管理,遂也统一搬运到本博客。这样一来一回,博客里的文章就不单单是技术文章了,以至于到此时,技术文章的占比已经成为很小的一部分内容了。博客的内容杂乱,各种分类混杂在一起,十分不好阅读。 因为我的原始资料使用的是Notion,通过notablog这个工具,将Notion的文章生成静态网页在部署在github上,所以版面功能限制于notablog这个工具以及notion的能力。没有自动分类,没有索引,没有数据统计功能。文章的管理,分类都得我手工做,之前一直没有好好梳理博客,最近终于抽出时间,将凌乱的博客梳理清楚。将首页做成内容分流,标签栏只放几个重点标签。 倒是有一种杂志社编辑的感觉,本身极度推崇自动化工作的我,在手动梳理了整个博客之后,放弃了自动化管理博客的想法,这种个人报刊式的博客,倒是让我非常享受,嗯,看来是可以再创办一个栏目叫做《读者投稿》了。

June 18, 2023 · 1 min