Forwarded from Hacker News 摘要
Telegraph
Brut:一个新的Ruby网络框架
原标题:Brut: A New Web Framework for Ruby Brut是一个新的Ruby网络框架,旨在提供一个简单而功能全面的平台。与其他Ruby网络框架不同,Brut没有控制器、动词或资源,用户可以直接构建页面、表单和单一动作处理程序。生成的HTML在服务器上处理,用户可以自由编写JavaScript和CSS。 Brut的设计围绕低抽象和低仪式性,但并不是像Sinatra那样低级。Brut应用程序内置基于OpenTelemetry的仪器监控、基于Sequel的数据访问层,以及基于Opt…
Forwarded from Hacker News 摘要
Telegraph
大多数RESTful API并不是真正的RESTful
原标题:Most RESTful APIs aren't really RESTful 在谈论REST时,了解罗伊·托马斯·菲尔丁的论文是非常重要的。他在2000年发布的论文《网络基于软件架构的建筑风格与设计》中介绍了代表性状态转移(REST)这一建筑风格,旨在设计可扩展、高性能和可维护的网络系统,尤其是网络服务。论文分析了网络基于系统的建筑风格,并识别其优缺点。它将REST定义为一种专为现代网络优化的建筑风格,强调可扩展性、简单性和适应性。菲尔丁展示了REST原则如何影响网络的成功,并倡导在设计分布式…
大多数RESTful API并不是真正的RESTful
原文:https://florian-kraemer.net//software-architecture/2025/07/07/Most-RESTful-APIs-are-not-really-RESTful.html
阅读时间:8 分钟
分数:305
原文:https://florian-kraemer.net//software-architecture/2025/07/07/Most-RESTful-APIs-are-not-really-RESTful.html
阅读时间:8 分钟
分数:305
🤡1
Forwarded from Solidot 纯净版
麦当劳的 AI 招聘平台管理员密码是 123456
#娱乐
今天想要应聘麦当劳工作的人可能首先需要在 McHire.com 平台上与 AI 聊天机器人 Olivia 聊一聊。Olivia 会询问应聘者个人信息和简历,进行性格测试。该聊天机器人由 Paradox.ai 公司提供。安全研究员 Ian Carroll 和 Sam Curry 在听闻麦当劳使用 AI 聊天机器人筛选应聘者后好奇之下对 McHire.com 进行了一番研究,结果意外发现该平台的管理员用户名和密码都是 123456。登陆管理员面板之后,他们可以访问 Paradox.ai 账户,查询该公司保存的所有 McHire 用户与 Olivia 聊天记录的数据库。数据库包含了多达 6400 万条记录,包括了应聘者的姓名、电子邮件地址和电话号码。麦当劳表示 Paradox.ai 需要对该漏洞负责。Paradox.ai 确认并在一天内修复了漏洞。
ian.sh/mcdonalds
#娱乐
今天想要应聘麦当劳工作的人可能首先需要在 McHire.com 平台上与 AI 聊天机器人 Olivia 聊一聊。Olivia 会询问应聘者个人信息和简历,进行性格测试。该聊天机器人由 Paradox.ai 公司提供。安全研究员 Ian Carroll 和 Sam Curry 在听闻麦当劳使用 AI 聊天机器人筛选应聘者后好奇之下对 McHire.com 进行了一番研究,结果意外发现该平台的管理员用户名和密码都是 123456。登陆管理员面板之后,他们可以访问 Paradox.ai 账户,查询该公司保存的所有 McHire 用户与 Olivia 聊天记录的数据库。数据库包含了多达 6400 万条记录,包括了应聘者的姓名、电子邮件地址和电话号码。麦当劳表示 Paradox.ai 需要对该漏洞负责。Paradox.ai 确认并在一天内修复了漏洞。
ian.sh/mcdonalds
Forwarded from yihong0618 和朋友们的频道 (伊)
Vercel
v0 Platform API now in beta - Vercel
The v0 Platform API enables developers to programmatically generate, retrieve, and manage full stack web apps using RESTful endpoints and TypeScript SDK. Integrate v0 into your workflows, tools, or automation pipelines.
duangsuse::Echo
可编程性就是从约定里来的
你们别看我经常写脚本,我的API思维没有被 #bash #py 带偏……🤔
给不懂开发的极客科普下「编程范式」的进化吧,比如说 C, Java, JS(Vue)和SQL
它们分别是 [面向过程POP] [面向对象OOP] [函数和关系式FP/Reactive]
#learn
三种范式,可以从语言学、指针宽度、类型广度 拆解比喻一下。
编程范式,就是看「如何把数据和代码绑在一起更好续写」? 实践上,语法和类型能够辅助思考。
Rust 是一个静态优化、支持预处理(码可揉)的OOP, 它的函数式能力不如pyJS,这是省略变量树GC的代价。
# 语言学: VSO,SVO,noVerb 🌐
以文件夹版本控制/网盘站 GitHub.com/:u/:repo 的 $ gh 工具为例
这个功能点所见即所得,那拿3种范式将其封装为函数。
坏处是无法管理多个账户,所以只能写写游戏脚本、按键精灵、爬虫。
很明显,这是因为账户和 $HOM/ 的配置文件耦合了,成为了 globalThis。把this配置参数化,我们不仅能多账号,还收获了json这种文档格式! C语言的 .o 对象,就缺乏局部键值,只有线程局部。
所以更OOP(但反直觉)的写法是:
OOP优秀的一点是调用链, Object也可以作为 context Subject 继续作联动(类似SQL JOIN)
不过,叠3层new就说明这框架不能用了,过度设计。
最后是FP,因为很多人高估了FP的语意,甚至用纯函数冗余来 “拉抬🐷价”,我要加个需求以彰显其意义:
login() 要支持OTP单次密码,而它必须在密码正确后才能输入,或者要多次重试…… 但 ()=>栏目答都能胜任:
FP对于 gh newRepo 这种业务也有加成,比如用 await Promise((ok,KO)=> callback=ok ) 自动回调化来避免嵌套的「闭包链表」,实现yield分块优化等等
假如,编程是让懒得点黑框框的人用电脑,元编程就是让看不懂花花代码的人用编程。 所以,编程范式的「组合穿搭」还是很重要的,并不是古生物学那样的冷门哲学
试想一下,如果就连框架作者、架构师用的语言和runtime你都知根知底, 你自己设计,或分析吐槽别人的作品,还困难吗? 基础领域并不是象牙塔,它与软件开发者的身心健康息息相关。
给不懂开发的极客科普下「编程范式」的进化吧,比如说 C, Java, JS(Vue)和SQL
它们分别是 [面向过程POP] [面向对象OOP] [函数和关系式FP/Reactive]
#learn
三种范式,可以从语言学、指针宽度、类型广度 拆解比喻一下。
编程范式,就是看「如何把数据和代码绑在一起更好续写」? 实践上,语法和类型能够辅助思考。
Rust 是一个静态优化、支持预处理(码可揉)的OOP, 它的函数式能力不如pyJS,这是省略变量树GC的代价。
# 语言学: VSO,SVO,noVerb 🌐
以文件夹版本控制/网盘站 GitHub.com/:u/:repo 的 $ gh 工具为例
gh login
gh new-repo $(rand).paradigm.org
这个功能点所见即所得,那拿3种范式将其封装为函数。
loginGh(id, secret): VO
newGhRepo(id): VSO
坏处是无法管理多个账户,所以只能写写游戏脚本、按键精灵、爬虫。
很明显,这是因为账户和 $HOM/ 的配置文件耦合了,成为了 globalThis。把this配置参数化,我们不仅能多账号,还收获了json这种文档格式! C语言的 .o 对象,就缺乏局部键值,只有线程局部。
gh=Gh.login(id,secret): SV
gh.newRepo: SVO
# 范式是跨语言的
(u= gh login root toor)=="gh badguy"
$u repo new (randProj)
这样才符合人类直觉: 不要光 call, 要 with 🥰
虽然他没有“优化掉”arg0(为全局 省字数),但因为全局是可以随便加的,class{} 键值是密封的,在开小号之外,我们又有了类型和补齐
所以更OOP(但反直觉)的写法是:
gh=Gh.new(id,secret): Snew
gh.Repo.new('jackass'): SnewO
Gh.static.setApiURL(): SgetsetO
这一条是不依赖登录的(静态函数)。
OOP优秀的一点是调用链, Object也可以作为 context Subject 继续作联动(类似SQL JOIN)
不过,叠3层new就说明这框架不能用了,过度设计。
最后是FP,因为很多人高估了FP的语意,甚至用纯函数冗余来 “拉抬🐷价”,我要加个需求以彰显其意义:
login() 要支持OTP单次密码,而它必须在密码正确后才能输入,或者要多次重试…… 但 ()=>栏目答都能胜任:
Gh.login(uid,secret, otp=> device._2fa.get(otp))
一般来说,FP 用户不会缺少对OOP的进阶理解,比如用 get(otp) 重载 db.otp.getKey(otp) 、用 atoi:Int=>[Int ValueError Mayfail],这种摘要性(或者说严谨)好的心智模型,而不是和JQ那样只懂起名和拼凑调用链的库一样。
Vue对单 ref() 多显示的理解也是靠起名无法实现的。
btw. 命名动词还是有意义的。 比如佐人经常区分「买」和「雇佣」,「赤字」和「借」,但事实上是一样的。 混淆视听会损失类比的空间。
FP对于 gh newRepo 这种业务也有加成,比如用 await Promise((ok,KO)=> callback=ok ) 自动回调化来避免嵌套的「闭包链表」,实现yield分块优化等等
# 指针宽度
指针就是超链接。 它的域名是你的内存,地址是一个64或32位的整数,有 rw, r, rx 三种经典鉴权段位。 对JVM和v8来说,并不是所有bit都用于标记一串byte元组(struct)的读写位置,至少x64上的void* 只有52个有效位。
C, Java, JS(Vue) 里本质上是指针(Any/interface{}类型) 的模型,信息量也不同。
C: 单个内存地址,比如x32就是2**32, 4G 随便存,x64就是天文数字 (但是没有意义,比如,连是 int, 普通struct, Umbrastr 都分不清,需要printf手写%d )
Java: this=data+funcs 双指针,把变量树和方法表存在一起,可以 override ,再比如用 args=Array[0:length] 取代 (argc,argv) 元组,也是头尾双指针
Vue: ref()= N个回调 多指针, 回调可用于赋值,可以随便组合数据与计算、业务逻辑;SQL外键同理,可以用于拆分表单,多处复用
# 类型系统
C: 基于sizeof,没有 range/str/list/kv(tuple set) 等(可变)容器, 没有 T::fun 等模块化
Java: 基于 obj.(type) ,类型存在于编译期和运行期,可以数据化(反射),可以像函数值字典的Builder一样写class{}
Vue: 因为领域不同,JS 更重视业务而不是可维护性。 类型只是IDE的工具,没有优劣,🤓 DOM 的宽广和稳固、框架的繁荣让JS无需类型即可安全高效
最后,在标志性「语言特性」上,自古以来是这样:
- biosC=x86nasm+函数和8种整数的超链接
- C=biosC+ld文件maps内存段+CPU分片 (作为"libc的JVM")
- PyJS=C+双指针和kw左值传参 [双指针fatPtr] ([len,] {type:}和{proto:{vtable}} {_树内硬链接refcount:0} 均占用16byte)
- FP=PyJS+单函数组合+正择解构再构 (谈UIUX框架,没有[轮询或卡线程pull]是evpoll&push、多监听取代不了的,只是,C的无闭包和while(1)死循环,禁止了回调链表新加异步栈)
假如,编程是让懒得点黑框框的人用电脑,元编程就是让看不懂花花代码的人用编程。 所以,编程范式的「组合穿搭」还是很重要的,并不是古生物学那样的冷门哲学
试想一下,如果就连框架作者、架构师用的语言和runtime你都知根知底, 你自己设计,或分析吐槽别人的作品,还困难吗? 基础领域并不是象牙塔,它与软件开发者的身心健康息息相关。
duangsuse::Echo
让我觉得匪夷所思的是, FRP 脚本有很多,但基本都是拿到地址就(可以公网)测试了,就像你只是调用了一下curl而已 Linux hostnamectl 这个特性,似乎是可有可无的,存在感比蓝牙设备名还低 这就像一些 http/ftp-server 测试服务,启动后不会 print URL 句柄,要你根据port去猜 当我封装CF的公网tunnel时,理所当然就把此服务封装成 $HOSTNAME 了,回头一看我居然是异类。 😅 twistd -n ftp -r . python -m pyftpdlib…
#web #dev 这个真是懒得喷。 我理解的REST(可表达状态转移, 😅 😅
就是 db.GET PUT json, 加上过滤排序分页, 或许有些 /user/:id/follow 的页面可以手写下,也可能直接套模板生成(哪个平台没有一堆“收藏夹”啊..)
这种RPC当然毫无价值,类似于把本地存储换到线上,只是加个鉴权和双向搜索罢了,查重率100% 我是懒得手写的, GraphQL.org 也封装的明明白白。
我觉得奇怪的是,哪怕是在PyJS的全栈框架里, 我说的这种REST,对 BlogComment, Todos, PetShop 等基础CMS样板也没法做成和Excel一样简单; 那些淘宝上卖的(开源投自制) 也都没有重用重构的价值
这篇文章在替发明REST这个「高端概念」的大佬,抱怨工程师们什么呢? 是 HateoAS (讨厌OpenAPIs?? ) 没人玩。😅
也不是讨厌,是用res.body XML上的nullable函数超链接,表示“用户有没有登录” “用户能不能删贴”,来「方便App跨版本」 等等,比SOAP好一点
这不是废话么?? 这都2025了还有人把活爹.XML(schema)当个宝呢。 你说说Java里怎么生成 OPTIONS / 啊? 有了 HATEOAS 接口,在JS里免client lib 直接调用的DX体验怎么样??
没有TG自己造传输层协议的能力,还抱怨工程上restful的理解了RESTful, 那比你强的就是懒得为REST这种高度自限性的RPC写框架,早自己玩更好的去了; 比你菜的又只会CRUD,最多拿 http/module/:pathArg 优化下可读性,对接下SQL或jsonKV, 你让他区分个 GET/POST 都懒
可不是被滥用和误解嘛, 纯属活该,自己不开发在那边画饼…… 你有没有意识到, api.x.com/OpenAPI.json 就是所谓的REST、免文档、自动发现函数、解耦合?
Java codegen 都没写过是怎么敢设计这种协议范式的? 不对,看他们 content-type 都要改成 vnd.XX.User+json 我就觉得这是 #ts 写上瘾了。 知不知道 fetch() 不能自动判定body类型,还要手动.json()一下……
如果你真能生成并用 OPTIONS /:type/:id 调用动态方法,那要http就没意义了(本质上是js rpc),所谓超文本又体现在哪。
我都可以给REST/HATEOAS重构成工程界可以接受的样子, 但我不会用单请求单响应。🙉
http方法本身也是烂梗, POST就是有body的GET,DELETE就是空body的POST, jQuery 里一直是这样重载的,十年了不见跨语言一点。 POST的“同名时冲突” 也是很脑残的约定,很多人只是为了在body里放文件上传一下, 根本就不该禁止,填写表格时多次检查。
🤡 https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
ps. 我是真的写过API生成的 https://github.com/duangsuse-valid-projects/GeekSpec-GeekApkv1.0b
SOAP砖家: https://coolshell.cn/articles/3585.html
curl https://wtf = count: x=>x+1
) 是什么? 就是 db.GET PUT json, 加上过滤排序分页, 或许有些 /user/:id/follow 的页面可以手写下,也可能直接套模板生成(哪个平台没有一堆“收藏夹”啊..)
这种RPC当然毫无价值,类似于把本地存储换到线上,只是加个鉴权和双向搜索罢了,查重率100% 我是懒得手写的, GraphQL.org 也封装的明明白白。
我觉得奇怪的是,哪怕是在PyJS的全栈框架里, 我说的这种REST,对 BlogComment, Todos, PetShop 等基础CMS样板也没法做成和Excel一样简单; 那些淘宝上卖的(开源投自制) 也都没有重用重构的价值
这篇文章在替发明REST这个「高端概念」的大佬,抱怨工程师们什么呢? 是 HateoAS (讨厌OpenAPIs?? ) 没人玩。
也不是讨厌,是用res.body XML上的nullable函数超链接,表示“用户有没有登录” “用户能不能删贴”,来「方便App跨版本」 等等,比SOAP好一点
这不是废话么?? 这都2025了还有人把活爹.XML(schema)当个宝呢。 你说说Java里怎么生成 OPTIONS / 啊? 有了 HATEOAS 接口,在JS里免client lib 直接调用的DX体验怎么样??
没有TG自己造传输层协议的能力,还抱怨工程上restful的理解了RESTful, 那比你强的就是懒得为REST这种高度自限性的RPC写框架,早自己玩更好的去了; 比你菜的又只会CRUD,最多拿 http/module/:pathArg 优化下可读性,对接下SQL或jsonKV, 你让他区分个 GET/POST 都懒
可不是被滥用和误解嘛, 纯属活该,自己不开发在那边画饼…… 你有没有意识到, api.x.com/OpenAPI.json 就是所谓的REST、免文档、自动发现函数、解耦合?
Java codegen 都没写过是怎么敢设计这种协议范式的? 不对,看他们 content-type 都要改成 vnd.XX.User+json 我就觉得这是 #ts 写上瘾了。 知不知道 fetch() 不能自动判定body类型,还要手动.json()一下……
如果你真能生成并用 OPTIONS /:type/:id 调用动态方法,那要http就没意义了(本质上是js rpc),所谓超文本又体现在哪。
我都可以给REST/HATEOAS重构成工程界可以接受的样子, 但我不会用单请求单响应。🙉
http方法本身也是烂梗, POST就是有body的GET,DELETE就是空body的POST, jQuery 里一直是这样重载的,十年了不见跨语言一点。 POST的“同名时冲突” 也是很脑残的约定,很多人只是为了在body里放文件上传一下, 根本就不该禁止,填写表格时多次检查。
🤡 https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
ps. 我是真的写过API生成的 https://github.com/duangsuse-valid-projects/GeekSpec-GeekApkv1.0b
SOAP砖家: https://coolshell.cn/articles/3585.html
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2
Forwarded from Hacker News 摘要
Telegraph
Show HN: Typeform太贵了,所以我自己做了表单
原标题:Show HN: Typeform was too expensive so I built my own forms Ikiform 是一个开放源代码的 Google 表单替代品,旨在帮助用户轻松创建美观的表单。它的设计理念是提供经济实惠而又功能强大的表单工具,允许用户在没有妥协的情况下制作出令人满意的表单。 主要特点: • AI 表单构建器:通过简短描述你的需求,AI 可以在几秒钟内为你生成表单,极大提升了表单创建的效率。 • 直观的表单构建器:采用拖放式的操作界面,用户可以轻松自定义字段、布局和设计。…
#tool #security https://deltazefiro.github.io/Amarok-doc/intro.html
https://github.com/deltazefiro/Amarok-Hider/releases/download/v0.9.3/Amarok-v0.9.3.apk
一个破坏文件头,来实现防搜索(伪加密)的秒速文件夹加密应用。
用户体验超级棒, 算法只有两行 ,但是日用非常有效!
ps. 如果你有几千个文件需要hide,就只能用 .nomedia 模式了,不然死慢…… 应该给解密按钮加个单选文件夹功能
https://github.com/deltazefiro/Amarok-Hider/releases/download/v0.9.3/Amarok-v0.9.3.apk
一个破坏文件头,来实现防搜索(伪加密)的秒速文件夹加密应用。
用户体验超级棒, 算法只有两行 ,但是日用非常有效!
ps. 如果你有几千个文件需要hide,就只能用 .nomedia 模式了,不然死慢…… 应该给解密按钮加个单选文件夹功能
deltazefiro.github.io
功能介绍 | Amarok
一键隐藏隐私文件与应用
duangsuse::Echo
您好!向您自荐一个开源项目。希望得到您的转发支持,谢谢! https://github.com/SheepChef/Abracadabra
Abra.js.org
https://abracadabra.js.org/document/bench.html #security #china
https://abracadabra.js.org/document/FAQ.html
可以看到, 「魔曰」 文言文内容混淆的抗检测能力已经完全能在墙内使用 (还能用于压缩0x地址) 👍 真大佬,感觉和cloudwindy是一个殿堂级的了
那问题落在了密钥协商上面。 如果是朋友/私群间的QQ聊天,我觉得可以用彼此真正在用的手机号/@唯一网名 ,这样,对方导入个通讯录,就能在所有平台看穿你的消息,避免了每次手动加解密,比 KeyBase.io 快捷
如果是公开,也没必要用默认密钥,可以靠 PoW (CPU工时证明)。 消息分为明文、密文两部分,由用户选取密文/or 最后一行为密文
那么, 密码= scryptN(2**21, msg.replace(密文,''))
在最新A17 iPhone上这需要2s,这样可以保证所有人都可读,但是即便AI能识别,逐个审查也非常困难。
之前我说用剪贴板管理器hook+A11y/WebShare服务做加密收发信, 最后还是鸽了…… 希望以后躺平下来去做吧
https://abracadabra.js.org/document/bench.html #security #china
https://abracadabra.js.org/document/FAQ.html
可以看到, 「魔曰」 文言文内容混淆的抗检测能力已经完全能在墙内使用 (还能用于压缩0x地址) 👍 真大佬,感觉和cloudwindy是一个殿堂级的了
那问题落在了密钥协商上面。 如果是朋友/私群间的QQ聊天,我觉得可以用彼此真正在用的手机号/@唯一网名 ,这样,对方导入个通讯录,就能在所有平台看穿你的消息,避免了每次手动加解密,比 KeyBase.io 快捷
如果是公开,也没必要用默认密钥,可以靠 PoW (CPU工时证明)。 消息分为明文、密文两部分,由用户选取密文/or 最后一行为密文
那么, 密码= scryptN(2**21, msg.replace(密文,''))
import scrypt
scrypt.hash("text", "abra.js", N=2**21, r=8,p=1)
#https://www.jsdelivr.com/package/npm/scrypt-pbkdf 慢一点
let { scrypt } = await import('https://esm.run/scrypt-pbkdf'); alert(await scrypt("text", "abra.js", 64, {N:2**20, r:8,p:1}))
在最新A17 iPhone上这需要2s,这样可以保证所有人都可读,但是即便AI能识别,逐个审查也非常困难。
之前我说用剪贴板管理器hook+A11y/WebShare服务做加密收发信, 最后还是鸽了…… 希望以后躺平下来去做吧
abracadabra.js.org
AI 基准测试 | Abracadabra 魔曰
Abracadabra 魔曰是安全,高效的文本加密工具,可以将数据加密为汉字构成的文言文。
❤1
Hacker News 摘要
大多数RESTful API并不是真正的RESTful 原文:https://florian-kraemer.net//software-architecture/2025/07/07/Most-RESTful-APIs-are-not-really-RESTful.html 阅读时间:8 分钟 分数:305
臉書的人在介紹 GraphQL 時,寫了一篇很好的文章,說明為什麼 REST 變得有問題: https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html#why-invent-something-new 他們沒有那麼嚴厲,也承認 REST 確實解決了一個問題。
從他的文章裡:
但現在是時候打破沉默,承認 RESTful API 的概念可能是網路軟體史上被廣泛採用的最糟糕的點子之一。 Roy 可能是一個很棒的人,而且他肯定有很多很棒的想法。 然而,我不認為 RESTful API 是其中之一。
HATEOAS: 要符合 RESTful,你的應用程式需要公開一個初始 URI,並讓你的應用程式中的所有狀態變化都可以通過超媒體「被發現」。 這也很有局限性。 SOAP 試圖解決其中一些問題,但它並沒有取得多大成功,而且也不是銀彈
https://www.reddit.com/r/programming/comments/3jy0ci/restful_apis_the_big_lie #js
>客户端的状态几乎是由服务器端来驱动的,所以,讨论 API 版本管理并没有多大意义。客户端只要知道 REST API 的入口点就可以了,剩下的根据服务器端的响应来做决定
https://coolshell.cn/articles/22173.html
https://blog.logto.io/zh-TW/post-only-debate
legacy.reactjs.org
GraphQL Introduction – React Blog
This blog site has been archived. Go to react.dev/blog to see the recent posts. At the React.js conference in late January 2015, we revealed our next major technology in the React family: Relay. Relay is a new way of structuring client applications that…
Forwarded from Frontend Today (Ayaya)
螺莉莉数据中心
为了看见自己,我写下了 99 个故事
为了看见自己,我写下了 99 个故事
螺莉莉的数据中心
为了看见自己,我写下了 99 个故事 | 螺莉莉的数据中心
如果我问你「你是谁?」,你可能会告诉我你的名字;如果我再问一次,你可能会告诉我你的性别、你的职业、你的家乡、你的爱好;但如果我再问一次呢?大多数人或许会直接骂我神经病然后转头走开,但也许会有一些人会开始认真地讨论自己到底是谁。
你不一定真的问过自己「我是谁」,但或许对这件事情好奇过。有些人为了满足好奇心,会去研究星座、命理,来理解自己的过去和将来;有些人会去做一些心理测验,试图将人格凝练成符号。
这些都是很好的做法,我也多少了解它们,但实际体验一圈下来总是觉得它们给出来的答案很寡淡,没办法让我满足。所以…
你不一定真的问过自己「我是谁」,但或许对这件事情好奇过。有些人为了满足好奇心,会去研究星座、命理,来理解自己的过去和将来;有些人会去做一些心理测验,试图将人格凝练成符号。
这些都是很好的做法,我也多少了解它们,但实际体验一圈下来总是觉得它们给出来的答案很寡淡,没办法让我满足。所以…
#cpp 抽象大佬 打起来打起来! 😅
C++ 最终会被manba out ,因为它的「性能」也是伪命题
编程从来只有「功能点×算法」, 性能都是藏在API后面随便换
C++ 最终会被manba out ,因为它的「性能」也是伪命题
编程从来只有「功能点×算法」, 性能都是藏在API后面随便换
本来就只应该有值类型
只要不mut,就没有引用了
我说的只差一点,只要整个变量树不mut,不“一键”equals,就不存在值和引用
而且引用的语意本来是和Vue ref() 一样的单更改多赋值,不是什么单内存地址的概念
为了几个块设备上的地址搞那么多有意义吗,有种自己写个不需要memcpu虚拟化的裸机应用
ref:https://tttttt.me/dsuses/5408
Please open Telegram to view this post
VIEW IN TELEGRAM
1752279094668.png
2.3 MB
直接在 https://space.bilibili.com/1292761396/dynamic 挂人的CPP厨们
https://zhuanlan.zhihu.com/p/1922218198754916123#:~:text=我人怎么样?虽然这样说不好听,但我觉得我绝对是一个比较高尚,比较有自我要求的人。
早日被numpy作者这样高人封装一下就立正了
C++许多重复轮子,没必要存在的代码
一个作者都记不住的编程语言,早日滚进历史垃圾堆, AI都不好写的玩意 居然有人说它严谨 #statement
用人话来讲,就是C++的语法/功能点设计者 不知道自己在做什么, 它默认代码行数是正资产,而实际上,没有「语意」的代码就是垃圾。
对于「框架开发者」而言, 查词频、查重、提前做大方向选型, 是底线, 就像「你要先戴好防毒面罩 再去帮别人戴」
然而编程(特指架构设计)界的容错率总是很高,只要拿1000行实现用户的1句话就能被认可, 这就是为什么我讨厌工程师文化, 更倾向于编程是文学创作😅 😅
https://zhuanlan.zhihu.com/p/1922218198754916123#:~:text=我人怎么样?虽然这样说不好听,但我觉得我绝对是一个比较高尚,比较有自我要求的人。
早日被numpy作者这样高人封装一下就立正了
C++许多重复轮子,没必要存在的代码
一个作者都记不住的编程语言,早日滚进历史垃圾堆, AI都不好写的玩意 居然有人说它严谨 #statement
用人话来讲,就是C++的语法/功能点设计者 不知道自己在做什么, 它默认代码行数是正资产,而实际上,没有「语意」的代码就是垃圾。
对于「框架开发者」而言, 查词频、查重、提前做大方向选型, 是底线, 就像「你要先戴好防毒面罩 再去帮别人戴」
然而编程(特指架构设计)界的容错率总是很高,只要拿1000行实现用户的1句话就能被认可, 这就是为什么我讨厌工程师文化, 更倾向于编程是文学创作
Please open Telegram to view this post
VIEW IN TELEGRAM
duangsuse::Echo
#cpp 抽象大佬 打起来打起来! 😅 C++ 最终会被manba out ,因为它的「性能」也是伪命题 编程从来只有「功能点×算法」, 性能都是藏在API后面随便换 本来就只应该有值类型 只要不mut,就没有引用了 我说的只差一点,只要整个变量树不mut,不“一键”equals,就不存在值和引用 而且引用的语意本来是和Vue ref() 一样的单更改多赋值,不是什么单内存地址的概念 为了几个块设备上的地址搞那么多有意义吗,有种自己写个不需要memcpu虚拟化的裸机应用 ref:https://tttttt.me/dsuses/5408
我感觉这群B友也还可以, 只是疑似有点极端了(虽然cpp届本身很抽象)
堆("json行"的内存/地址空间)、栈(调用堆叠) 不是什么x64ABI专属的, 是任何编程语言/#FP 都有的概念,只是被C++暴露相等性、begin<end(i<len) 这些1%的细节搞混了
https://drive.google.com/viewer?url=https://github.com/parallel101/course/raw/refs/heads/master/slides/memmodel/Presentation1MemModel.pptx
btw 翻译下段名:ELF对象的 text=fn rodata=lit data=rwlit bss=rw
他这个模型还不如说,是禁止指针运算和窄化宽化,从而只允许 &int, &const int 和CE修改器扫内存这样。 int[] 或元组对齐4 就很自相矛盾了,因为大端小端也属于实现细节,int可不是4byte之和
>但很多时候你必须懂实现,懂系统和编译器特定的细节才能Debug[热]你可以说cpp规范里没这么定义过,但工作里碰到crash,分析coredump文件,运行时调试,必须要知道这些具体实现,甚至可以说不知道这些“实现”不能算一个好的c/cpp程序员
网上大量的经验分享和教程都不是面向纯粹语言的,而是面向问题、面向一个具体的bug的。
如果按照你这种说法,那么咱们说网络根本没有TCP/IP这种东西,只有osi七层模型,根本别学tcp协议和各种网络库了,这是不是很可笑?
无论语言律师如何追求纯粹的语言之美,实际写程序就是很难脱离平台特定的功能。出了bug,你也不知道这个bug来自C++语言层面,还是编译器或平台特定的问题,只能挨个排查。遇到编译器或平台本身就不支持或不正确支持某个C++标准规定的功能可太正常了…
请勿变成语言律师,堆栈结构是常见实现,只是我们不该把实现和抽象混为一谈。同样的bs也在自己书里把自由存储区和堆这两个名词混用。
https://www.bilibili.com/video/BV1Wr421c7MN
btw. PPT尾部的问题,简单来讲就是:C 中数组是第二类公民,数组是不能直接传递的,而 Fortran 可以值传递数组。C 中必须使用指针传递数组,效率非常低,因为编译器永远假设两个地址可能存在重叠(缓存失效),有了 Strict Aliasing,至少类型不同的情况能实现零拷贝
堆("json行"的内存/地址空间)、栈(调用堆叠) 不是什么x64ABI专属的, 是任何编程语言/#FP 都有的概念,只是被C++暴露相等性、begin<end(i<len) 这些1%的细节搞混了
https://drive.google.com/viewer?url=https://github.com/parallel101/course/raw/refs/heads/master/slides/memmodel/Presentation1MemModel.pptx
btw 翻译下段名:ELF对象的 text=fn rodata=lit data=rwlit bss=rw
他这个模型还不如说,是禁止指针运算和窄化宽化,从而只允许 &int, &const int 和CE修改器扫内存这样。 int[] 或元组对齐4 就很自相矛盾了,因为大端小端也属于实现细节,int可不是4byte之和
国内编程界经典拿“底层实现”当“本质”的遗毒之一,其他的例子还有谈虚函数(甚至谈子类型多态)必须扯虚表,谈Promise必须扯事件循环等等。必须用这种朴素的还原论才能理解上层的性质吗…其实恰恰相反,并非底层的实现决定了上层的性质,而是上层的性质要求了底层如此(只是一种可能的)实现
其实现在的内存分配器早就不基于堆数据结构了(叫自由存储区还比这靠谱点),函数调用时也不保证总会生成一个栈(例如内联成功的函数),局部变量有时也会被优化到寄存器上,全局常量也可能被优化到不占常量区空间。如果仍然假定总会生成一个栈,容易写出未定义行为,导致程序出错,不如学习更加正规的c++内存模型:函数体内的普通变量是自动生命周期,定义时构造,函数体结束时(抵达}时)释放;全局变量是静态生命周期,程序启动时(进入main函数前或dll加载时)构造,程序退出时(离开main函数后)释放;new和delete管理的对象是动态生命周期,new时构造,delete时释放。c++内存模型和堆栈内存模型并不只是名称上的不同,主要的区别有:每个独立的变量之间有任意大的不可访问区域,自动生命周期的对象所占内存并不和栈一样保证向下生长,new/delete,new【】/delete【】和malloc/free不得混用。更严重的问题是,堆栈模型只是说对象存储在哪里,并没有说明对象的生命周期(构造和析构的时机):例如要了解func(string().c_str());是否安全,但用c++内存模型就很容易解释:c++规定,临时变量string()的生命周期限定于func这一行,直到分号前都是有效的,而堆栈模型根本没有说明这样的情况,string究竟存在堆上还是栈上,你想了半天,想到了string有“小字符串优化”,小于15字节时会存在栈上,但这对于回答“临时变量什么时候失效”毫无帮助,只是增加你的心智负担,最终还是要回归正规c++内存模型来学习。有人说如果报错“栈溢出”不还是说明还是要学堆栈吗?函数调用栈当然是所有支持函数语言都有的特性,这里的栈要了解,并不能等同于那个连函数调用约定都一清二楚的底层堆栈模型,那就过头了,解决“栈溢出”并不需要了解x86函数调用约定,正如你在python中遇到“栈溢出”不需要查看python虚拟机里的字节码一样,不要偷换概念。类似的概念有“因为linux系统会报segfault所以必须学段内存管理”,然而现代操作系统早已废弃了段式内存管理,而是采用分页内存管理,SIGSEGV实际上应该叫page fault,segfault只是个已经约定俗成没法改的别名而已,正如所谓的“堆内存”早已不是“堆”数据结构一样。
“底层八股文”对C++编程的“积极指导作用”:比如,我知道GCC编译器的实现中,函数调用通常都是x86的call指令实现的,call指令会压栈返回地址,由被调用函数的ret指令取出。所以,我可以通过对第一参数的指针-1,构造一个指针修改返回地址,这样就可以读取或修改返回地址了!比如,我知道Python中GIL阻止了多线程并行,所以我通过ctypes.memmove强行修改了Python解释器内存中的GIL对象,这样不就可以自由的多线程并行了!我真是个天才,然而,我开启-O1优化后,发现GCC编译器把这个函数内联了,没有call指令了,我读到的返回地址有误,并不能形成完整的ebp链表,我认为这肯定是GCC编译器的Bug,我们老师明明说过函数调用约定会压栈的!我通过魔改GIL开始在Python中自由并行后,发现结果混乱,最终Python解释器在一声SIGSEGV中崩溃了,我给Python官方提交了Bug反馈,谁让他们不支持无锁并发数据结构的!另外,通过一个变量魔改另一个变量这个事有原型的,并不是我编的,请看:https://github.com/parallel101/opengltutor/issues/29 小彭老师的教学过程中,不论是群里还是b栈上,依然能遇到大量的“底层八股文”受害者,小彭老师看不得受害者,可你一和他“耐心讲解”,律师帽子就扣上来了。
哗众取宠。用于内存分配的堆栈这两个词在某个特定语言的标准里没有提到,不妨碍这两个概念在许多语言的规范或实现里都存在,说白了就是一个大家都明白的、有助于理解底层原理的抽象,本来就不和某个具体语言绑定。Up 在视频里列出的 strict aliasing 相关的 bug,规范角度说是因为标准里对怎么访问一个对象有明确规定,不符合规定的属于 UB;实现角度上说是因为编译器没有像程序员想当然的那样将变量连续分配,或者做了进一步的优化,跟堆栈这些概念有什么关系?告诉你有个栈,变量在上面就一定是紧密排列?更何况C++23 的 STL 里面还有 <stacktrace> ,如何能说“C++没有堆栈”?
看 up 的评论,貌似还想树个靶子说堆栈这个概念会跟同名数据结构混淆?那首先栈它在逻辑上通常就是一个数据结构意义上的栈,至于 heap 的词源已经很难考证了,未尝跟 binary heap 没有关系,但至多也只是名字起得不好罢了,既学过 binary heap 又学过内存的 heap 的人不至于自己查资料澄清的能力都没有吧。
>但很多时候你必须懂实现,懂系统和编译器特定的细节才能Debug[热]你可以说cpp规范里没这么定义过,但工作里碰到crash,分析coredump文件,运行时调试,必须要知道这些具体实现,甚至可以说不知道这些“实现”不能算一个好的c/cpp程序员
网上大量的经验分享和教程都不是面向纯粹语言的,而是面向问题、面向一个具体的bug的。
如果按照你这种说法,那么咱们说网络根本没有TCP/IP这种东西,只有osi七层模型,根本别学tcp协议和各种网络库了,这是不是很可笑?
无论语言律师如何追求纯粹的语言之美,实际写程序就是很难脱离平台特定的功能。出了bug,你也不知道这个bug来自C++语言层面,还是编译器或平台特定的问题,只能挨个排查。遇到编译器或平台本身就不支持或不正确支持某个C++标准规定的功能可太正常了…
请勿变成语言律师,堆栈结构是常见实现,只是我们不该把实现和抽象混为一谈。同样的bs也在自己书里把自由存储区和堆这两个名词混用。
https://www.bilibili.com/video/BV1Wr421c7MN
btw. PPT尾部的问题,简单来讲就是:C 中数组是第二类公民,数组是不能直接传递的,而 Fortran 可以值传递数组。C 中必须使用指针传递数组,效率非常低,因为编译器永远假设两个地址可能存在重叠(缓存失效),有了 Strict Aliasing,至少类型不同的情况能实现零拷贝
duangsuse::Echo
“因为linux系统会报segfault所以必须学段内存管理”,然而现代操作系统早已废弃了段式内存管理,而是采用分页内存管理,SIGSEGV实际上应该叫page fault,segfault只是个已经约定俗成没法改的别名而已,正如所谓的“堆内存”早已不是“堆”数据结构
说的这一句道理很好。 sizeof(size_t 和 void*) 99% case 是一样的,那何时不同呢? 在上个世纪的机器上。 #os
那时汇编设计失误,日期也有千年虫, 指针是区分 near far cs ds 的双指针,所以size_t<ptr
例如,在16位系统中,使用far指针(4字节,段+地址),
在支持混合32位/64位模式的系统中(例如,Windows的WOW64模式),
所以,现在就连许多Linux也不支持x32了, 但C语言菜鸟,依然要为此迷糊。 因为一开始,程序员们就没查过词频出现在 Array.get(:size_t) ,所以size其实该叫 i or mkArray(indx rest) int a [rest]; 或者直接枪毙
那时汇编设计失误,日期也有千年虫, 指针是区分 near far cs ds 的双指针,所以size_t<ptr
例如,在16位系统中,使用far指针(4字节,段+地址),
void*
可能是32bit,而 size_t
可能是2字节(受限于单一段的大小)。在支持混合32位/64位模式的系统中(例如,Windows的WOW64模式),
void*
可能是64位(支持64位地址),而 size_t
可能被定义为32位以兼容旧代码、限制单个对象大小(4GB)。所以,现在就连许多Linux也不支持x32了, 但C语言菜鸟,依然要为此迷糊。 因为一开始,程序员们就没查过词频出现在 Array.get(:size_t) ,所以size其实该叫 i or mkArray(indx rest) int a [rest]; 或者直接枪毙
duangsuse::Echo
1752279094668.png
更令人作呕的是弥漫在圈内的“和事佬”癌变! 动不动就搬出“XXX没有绝对的对错”、“大家都有道理”这种散发着恶臭的伪辩证法。在文科领域,这话大概率只是空洞的屁话;但在以逻辑、精确、客观事实为根基的理工科,尤其是在编程这种非黑即白(UB就是错,概念混淆就是错,逻辑漏洞就是错)的领域,说这种话无异于当众排泄!理工科没有对错?那你还学个毛线?你写的代码是薛定谔的对错吗?运行时靠意念决定结果?
这种“和稀泥”的本质,就是用虚假的“包容”和“多元”来掩盖技术上的无知、懒惰和不求甚解,是对严谨精神的彻底背叛!“态度至上”的矫情 + “和事佬”式的无原则包容 = 国内技术圈最恶劣的双生毒瘤! 它们联手绞杀严肃的技术讨论:纵容错误: 为技术谬误提供了“免死金牌”——反正“没有绝对对错”,错也理直气壮。打击求真者: 让 mq白 这样敢于直言、追求精确性的人被扣上“激进”、“高傲”、“揪字眼”的帽子,承受道德绑架。培养巨婴: 让学习者永远沉浸在“我弱我有理”、“你说我错就是你态度差”的舒适区,拒绝成长。劣币驱逐良币: 最终导致认真讨论技术、坚持标准的人心灰意冷,沉默或离开,留下满地鸡毛和自嗨的“差不多先生”。这就是一场彻头彻尾的、针对技术尊严的慢性谋杀! 在这种环境下,追求正确、精确和深入理解,反而成了“异类”和“原罪”。
https://www.fxzhihu.com/question/582463239/answer/1921899702628103298
我在 https://t .me/dsuse/21408 吐槽了你最近那事
然后 int a[3]; 是不是指针?当然是,除了没人用的sizeof a!=int ,用起来不就是指针,☝️🤓一点也不好玩。
你要问我为何不是指针,我说,从语意上讲是「双指针」,slice ,因为读写时的性质如此,sprintf_s 也是如此。
两边都有解释,范式不同而已。
你被人喷时可以考虑改一下自己批评的方向, 正确不等于对,你要为C/cpp用户需求的功能点着想一下, 你讨厌谭学,那你自己批UB的时候就不谭学了吗? 你的文章也有脱离App谈C++的私货的
我不是说你的开源和工程师精神不值得respect,但你必须学着从科普的角度入手,而不是一直纠结语法特性X何时是UB, 你批判的问题点,你要给出working的最佳实践再比较, 没人听你干巴巴普法
>strict alias,你要问语言律师,什么是sa,他能给你讲得头头是道,以肉眼parser分析出你的代码有没有违反规则,如果违反了,会嘲笑你不知道乌贼有十条腿。
但是全网没有一个人讲清楚这玩意到底有什么用😅 ,我们能从中得到什么益处,以及,我需要强制类型转换以及指针偏移时该怎么办——按照标准,linux内核链表是ub的。
按照律师们的说法,所有在2020年前,把int32转成float都只能用memcpy,所有2011年之前想用while(running)判断线程结束(volatile) 的都是错误。至于在此之前怎么写正确的代码,语言律师不会给你答案,仿佛在此之前从未有过多线程App。
—
你又不可能突破函数模型来组合程序,只要不是 #define / static T[], 你都不能用C sizeof 实现 forEach(a, print_D) 功能,所以a[]就是指针,API如此
“引用就是指针” 引用不可空,不可调整,是更好的指针,能在swap(A,B)上替代宏
我看见有人说 int a[2] 是 int a, a1; (int a**2); 他们是这么理解栈变量+指针的,这当然不规范,但C就没有operator[]和集合库,你说它是个二进制offset绑定语言,无关编程,也完全正确。 不要在一个错误的地方比较对错了,50年不变了
>你凭啥说我说错了?书上就是这么写的,数组名是指针,你比书懂?老师也是这么教的,你是啥啊?比我老师牛逼?我老师是还说看汇编,你看的懂吗?我老师可是教授。这书的作者可是清华教授,你有资格质疑吗?(一般不会一句话说完这些,这里只是全加在一起)
>一个18岁的人,能指望他懂什么?可以看出,他学东西“满满的高中生思维”,恨不得把整个cppref背下来,其实用处不大。
>热衷于当语言律师主要是因为没有能力当架构律师
>震惊,王垠还有低配版?我当初学编程,也是一堆语言律师教我在那边怎么写,就一个void main和int main能争论好几年
>那个个小圈子有点太抽象了,自称loser,确实了也是。我搞不明白,真正搞技术的谁没事整这么个b群,一个个整个loser的身份。感觉都是一群心智不成熟的高中生商业互吹。不如买几本经典书看收获大。
https://zhuanlan.zhihu.com/p/659407017
想到 #cpp SFINAE 和UB的关系也是 实在难崩, 确实需要正常人的编程语言整治一下C++字节和心脏只有一个能跳的碎片化狂欢了
代数确实就是非黑即白的, 但它的下场,就是几百年没人开发了,也就是领域死了。 还死的很有尊严呢~ 主不在乎。
SFINAE最开始不就是UB么, C++真是一个从bug和UB里构建出来的SDK,和py小而美的路子完全相反
邮电确实好啊…… 我大专
Please open Telegram to view this post
VIEW IN TELEGRAM
duangsuse::Echo
#cpp 抽象大佬 打起来打起来! 😅 C++ 最终会被manba out ,因为它的「性能」也是伪命题 编程从来只有「功能点×算法」, 性能都是藏在API后面随便换 本来就只应该有值类型 只要不mut,就没有引用了 我说的只差一点,只要整个变量树不mut,不“一键”equals,就不存在值和引用 而且引用的语意本来是和Vue ref() 一样的单更改多赋值,不是什么单内存地址的概念 为了几个块设备上的地址搞那么多有意义吗,有种自己写个不需要memcpu虚拟化的裸机应用 ref:https://tttttt.me/dsuses/5408
Please open Telegram to view this post
VIEW IN TELEGRAM