duangsuse::Echo
583 subscribers
4.12K photos
118 videos
579 files
6.13K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
#security 回顾 regreSSHion: RCE in OpenSSH server<9.8 https://www.bilibili.com/video/BV11U411U78q 这一漏洞的描述听起来像是 WannaCry(SMB) 和 Log4Shell 级别的。实际上,该漏洞的利用不太可能。 2014年,OpenSSL加密库中的一个缓冲区溢出漏洞被公开。该缺陷被称为“心脏出血”,这次是它的回归 由glibc free() 数据竞争,导致heap链表 use-after-free 而使得glibc…
#os #design 作为编程语言爱好者,谈谈RCE这些bug的根源吧: 程序员没做错, Dennis Ritchie 们错了 😅

为什么“溢出”基本上是C的专属呢?因为老冯的时代,“汇编器是在浪费 CPU cycle” 这种反人性的设计,被推崇为《程序员的自我修养》 (x86汇编的应用与骇客少,不讨论单片机界的情况) #recommend

就像JS人不懂 1+"1", 1-"1" 为啥会不同,
初学C的人很奇怪为啥 1+1 可以而 "a"+"b" 却不行(还必须 strcat 或 sprintf), 'a'+'a' 更是居然==194!厘清 return struct{} 与*alloc、class Reader{}与UTF16编码,以及它们在C++的平替,就需要更久了
不过,随着对 x=1; (X==1) 以及从0开始数 for(i=0) use(a[i]) 的区分,常量级语法和"基础类型" 就不再是问题,转而学习函数对象、链表、fopen()、KV 这些有语意的类型了

但我们先回到"基础类型"。C的 struct,union,[] 是有严重安全隐患的,「这只是性能的牺牲品」?
#rust 已经告诉我们 redox-os.org/ 这样复杂的系统也能默认内存安全, Python 则证明了仅仅靠运算符重载、Rc<T> 这样幼稚的引用计数,就能组装出了不起的AI应用

struct{} 的问题是“地址相关性”。就为了与x86的一些硬件地址对接(1% cases),C让一切数据类型都与 bytes(char*) 直接对应,以便映射到某个内存页位置、通过 malloc(N) free(obj) 链表来瓜分glibc mmap(brk)到的进程内存
(alloc相当于单实例版的现代 memScoped{} 即 zig ArenaAllocator 。C的"弱类型"设计错误有多深远?直到2004 Linux 2.6.8 才支持Nx 即heap默认不可执行的"保护"..)
这就造成了 memleak, segfault(空指针和类型错误的cast, 例如把小结构cast成大结构) 甚至 "更适合C语言体制的SQL注入"

这里说的,就是子类型里的 Animal() as Duck, Rect(1,2) as Square ,要么是表格验证的语意错误,要么从语法上就不该对
struct Animal {
enum Tag{Duck,Cat}
union v {
struct Duck{int beck} //实现上会移到外部且把继承的项前置(便于在Animal{}外扩充),以及有virtual vs final 的虚表双指针,顺便用于实现闭包
}
}

并且,哪怕你能够通过一些信息压缩掉int Tag ,用 rawtypeof<Animal> xx; xx(1).beck 也比默认强转好太多了。 "默认行为"的重要性被严重轻视了
比如,为什么ES6要推荐一个“凑字数”的 const x= 而不是 let+let mut x? 为啥 Java 到处都是 public final 🔘 Str wtf() ?

你可能是第一次意识到“subtyping” 保存着type tag,但这些真的是编程里的基础(你设计任何"前后端"时都应该考虑的),或许,只是在像XML那样复杂的上层框架里这并不直观。
int a[]={1,2}; 这样的“数组”,它的长度只能用静态的sizeof得知,也就是 a[N] 里N必须是个常数,对它的求值才是安全的。

C99(ISO9899,P61)甚至专门定义了“退化到指针” 和'\0'结尾字符串的行为-它还好意思把这当特性! gcc 实现了常量区间的越界检查,这是说谎:
range(A=0,B) 类型的缺失从一开始就是个错误。实际上,2int=1long ,区间slice有的内存开销,与它能带来的软件安全是不成比例的。
gcc的"静态检查"只是对stdlib的缺陷涂脂抹粉,并没有消除过度追求低内存,所带来的隐患

并且,只要区分定义 a[int32_t], a[index_t] 的实现,对后者只定义一些编译期检查(private constructor),就既安全又高效。
连Ruby 💎和WebKit的作者们都知道可以这样("污点值" taint 和 TrustedTypes),今天有人称其为 contract{}.. 也行吧

然而,即便有了OS的ASLR/Nx保护,stack/heap overflow 今天还是个问题。如果你写 sprintf(buf, "%d",0) 编译器会提醒你改用 sprintf_s 或cout,sstream<<
所以 main(int narg, char** aarg){} 用什么替换? main(vector<str>) 吗? 恭喜你重新发明了“很慢的” Python,只是还没有它好用

与for和if 对应的数据结构!!它们的重要性无需多言: 如果数据能随意纂改,fn{} 这些代码块、甚至只是算式 的正确语意就无法得到保障。
至少你还能庆幸,与 main(..) 等调用对应的 cli_args a0={.raw = new string[]{"/bin/echo",}} "构造器"只是不太好写🥰,没有RCE那么严重的缺陷

OOP只不过是把C的病态类型修了一修,它自己还有“读json都要搞反射,但Class对象被认为性能低”所造成的一堆问题
log4j 们是把bug的产生从“代码的语法” “内存结构的语法”往上提高了一层,并没有消灭问题。 能消灭问题的,恐怕只有少写代码,多思考吧。

从某种意义上,缓冲区溢出、反射低性能、线程(ret2调用栈)与 async(ret2回应函数)间的鸿沟,都是『两种语言问题』,即C,Java,JS 这样的语言为了解决框架们的需求
它们原来的心智模型,无法跨越 编译期/运行期、 堆内存/栈内存/json、本机/远程、可信数据/需验证数据,甚至仅仅是 正确/错误 (Object/Error和null) 而一致地存在,就产生了许多需要学习的class libs,以及与它们的宣传不相称的复杂性和log4j那种bug

我最近在设计的逻辑式编程范式,就是为了从心智模型的层面统一这所有的『两种语言」。 祝我成功吧 🌚
实际上呢, linux 这些内核所提供的虚拟内存段(vma https://tttttt.me/dsuse/19844) 实现,通过把内存解释为对象图,这种4K页隔离也完全能删掉, ELF, SHM, CRIU.org 那些高深的结构也就会和普通的JVM对象(对比下"class" PATH?)、多线程、序列化 一样朴素
因为C会和WASM那样安全,没有驱动程序的“引用”,就不能越过内核调用rm -rf 那种事情(yinwang 2013)。 所以fd,socketfd 这些“RPC对象号” 也就不必存在; 线程就只是让while(1) 每隔几千次暂停1次的协程,调度器、主循环evpoll 也可以消失。
eBPF 的人都知道我在说什么,现在有足够多的中间表示比x86指令集更优秀,甚至更简单,完全能从汇编上来做“虚拟化”

学内核本质上就是学"4件套",而这4项任何一个普通极客都有所认识: 👀
byte format: ELF,EXT4,boot process(cpio), .. 这是用户最关心的: exe,so,apk 互不兼容,尽管他们的系统“一样高级”,C盘D盘容量一大一小,哪怕你的SSD是512G的
net: AP, Bluetooth Peering, tcp实现, 自然需要多线程和管道, 要考虑"异步" 也就是回调地狱的解决;最重要的是,Web的API和格式(FTP..)是超越运行时差异的存在,它比加了私货的SDK文档更能体现问题的本质
usb: hid键鼠触摇, hdi显示与摄像, 声音, ACPI SMART, 各种传感器.. 或许它们的“设备总线”不是USB,但我们只关心硬件的性能 而非接口!
vm: 内存和CPU的分时复用,按上面的说法,这是专门为掩饰C语言的缺陷所设计的。 难道Linux所提供的功能,比JS靠WebKit能利用的还多吗?为什么vscode只需要单线程,一些服务却总爱“加塞”,这其实就是C语言没办法“注册回调闭包” 导致的卡线程与线程池优化.. 全是与IO的业务逻辑无关的东西!

不过编程本身是无关于计算机的,就像天文无关于望远镜。
“编程赞歌是组合搭配的赞歌,框架伟大是拆分置换的伟大。代码是流动的数据,内存是暂停的程序——感想”
3
duangsuse::Echo
#linux #design #statement 最近在设计OSon(一个基于JSON的类lisp计算图语言) 的一种强类型根rootfs 标准,打算用cbor(json zip),flatbuf 作为sysfs和etc的标准编码,它们的标准很简洁, cbor甚至只用0b111(7)种情况编码了可变结构 https://cstriker1407.info/blog/cbor-simple-note/ https://flatbuffers.dev/flatbuffers_internals.html#…
https://blog.csdn.net/dog250/article/details/100998838 #net #os #design

POSIX 中实际上有3种类型的文件: hex=block=buffer读写, ktty=char=内核终端文件, ptty=基于pid的终端文件, syn=socket=分pid/fd生成的文件
分别用于管理磁盘和内存(/dev/mem)、kmodule(ioctls)、虚拟终端(就是有width的,能控速的hex, $ stty)、socket(tcp/udp)

“一切皆文件”和其它的原则比如“组合小程序”等是相辅相成的。如果“一切皆文件”被破坏,那么便很难简单串接小程序实现复杂逻辑

socket没有标准文件的open和close操作,不能cat一个socket,也没法向一个socket里echo数据。因此就出现了socat,netcat这种大家都说好,但实际上没有必要的微型网络程序。

系统内核,其实就是会用MMU 4K页表保护自己的libc。
这就像,js要用 eval() import PATH 里的模块对象,同时需要沙箱技巧(setInterval..) 保证自身的设备和CPU不被独占
但因为C的代码都是unsafe{}, 需要用一种丑陋的方法隔离"syscall, ioctl" 这些类似于HTTP的调用,不能像WASM那样,内核和PATH里的代码存在一个地方。

你们可能听说过 gopkg/mvn 和 goroutine/jvm线程 ,那就是safe的PATH/函数对象和线程(池)调度器,这些虚拟机都有等同于操作系统的功能
而且更快速,例如, Looper() 调度不同的 ()=>函数 不需要保存和恢复>4K调用栈, 仅仅=闭包.call(返回地址在回调里)
这也是为什么有libuv这些东西
#os #rust struct/union不能实现的短字符串(16byte)优化?
https://duanmeng.github.io/2023/12/14/umbra/#:~:text=包含12个或更少字符的短字符串直接存储在字符串头部的剩余12个字节中,从而避免了昂贵的指针间接寻址
https://nan01ab.github.io/2020/12/Umbra.html

可以类比 x32 ABI (指针范围压缩为4GB, 因为大部分单线程不会超过这个数, 就像 int 在x64和x86默认宽度相同)
https://lantian.pub/article/modify-website/x32-abi-docker-containers.lantian/ #dalao

同样,在JDK8+ 默认开启有对象头压缩 -XX:+PrintCompressedOopsMode , 指针压缩后,并不是所有引用都保存在堆中,而是以8个字节为间隔保存引用。
装箱的Int@List.. 即占用 16bytes=64(Mark Word,主要是hashcode)+32(Compressed oops)+32(int)=128bits

CBOR.me 的 cborseq 选项,可以可视化这样的位运算压缩,不过,unaligned read 在一些CPU架构上会报错
#os 为什么 #js #java 选择了 UTF-16 (emoji 占2 codePoint)作为默认编码?
答:UTF-8 codec 要处理的情况大两百行
https://www.fxzhihu.com/question/652839772/answer/3472123259

- UNIX ASCII-7bit 现在一般被扩展为 Latin-1 (EASCII, 8bit), 均可包含 base64 z85
- utf8的兼容ascii只是伪兼容,例如strstr("abc","a")。很多情况utf8根本不能用ascii api? 不。 UTF-8 保证了同一码元,不同字节二进制前缀不同,不会混淆。

- UTF-16比int32(unicode scalar)有啥问题?比如国旗都是用两个 code point 表示的,存储成整数要 8 字节;有些 emoji 还是一个 ZWJ 序列(grapheme clusters), Family 就是七个 code point
#dalao #os #hack #tw https://jasonblog.github.io/note/fcamel/05.html
这个是真懂
$ ltrace getent hosts 127.0.0.1 2>&1 | grep gethostby
gethostbyaddr("\177", 4, 2) = 0xb7ed0aa0
$ strace getent hosts 127.0.0.1 2>&1 | grep "/etc/hosts"
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3
duangsuse::Echo
纯sdf, 顺手移植了一个给 numpy+tty 花了1小时吧: cv2.open(mode=HSL亮L).降采样为(stty size) mix(256色到" .*#"色) .追加\n列 .光标到(0,0)print 我用了比yes命令内存效能低的join'',但也不打紧 #performance fwrite() 就像CtrlV,要打'y'*500你是粘贴五百次还是多复制、缓冲? 把rows('<U1').buf分隔复制到 int8(w*h+1h),按帧yield给/dev/pts/0管道更省 若一开始就…
看最近几条逆天,我要聊哲学 #CS
操作系统不就是4片3口虚拟化么
时间内存存储程序,网口线口板口 #os #plt #embed #recommend
win,*nix,mac, aosp ios ;哪个不是只有这么点API和差异化 🦄?为了音视频和回应事件弄那么多框架外链新语法,不如3行 #web js。
bellard.org 那样的通才终究少数,搞出\0结尾无长度字串,连{}[]{type:}都没建模的libc算什么API啊?在位运算位flag上都被人打败 也配教人数据结构算法? 。 为这撒手掌柜的「千年虫哲学」服务的「编译器和OS」……

"It works"的「千年虫哲学」出现在4byte的13位时间戳、在'\0'结尾的CStr、在argc和snprintf等“最佳实践”、在将'❤️'算作2字符的JS和JVM(UCS-2的伪utf16)、在线程被窄化为while(1);join和各种设备信号的“同步IO”里 —evpoll为何不是默认呢,就因为C没“回调值”,轮询pull>推送onpush? 千年虫在几乎所有让你不分昼夜却不得要领的「术语」里……

时间片sched - 变通while(true)的死机, kotlin/go func 怎么不需要这些? numpy,GL 为啥不需要循环向量化?
内存片vm - 缝补struct{{}} Rc状态树, 缓解(编译期)检查缺位的骇客 enum { A(int) B(str) }, for(i:0~9)a[i], sql select${x}+1, scanf%s
存储片fs - 分簇存bytes&CoW复制断电不断写
程序设置依赖片elf,apt,regedt - 硬编码各种rc,ini和/lib/.so.版本 🤮,各发行版树格式不通,make系统ld.so优化一堆,却连 live compile/fatJar/minify 抖树都不懂……

网口tcp,ssh 双管道(socket), pipe闪存读写(等buffer就是等yield)
线口usb 注意方口圆口转接,通用的
主板口pciBus 安卓的dts
>__线程调度内存隔离、文件设备(fat32,ext4,IRQ)、 IP网络和并发工具(IPC,sem,mutex)__
>如果一个人写了线程池或malloc()或ELF文件链接器,声称自己写了操作系统 是可以的(GNU不就是)……

凑以上这些字数干嘛? 时间内存存储程序--片,网线板--口,就这么简单。 把双管道快取翻译成「套接字缓存」是啥逆天专家
OOP封装/多态实际上解决了 libc vm 化进程的问题,JVM,NET只需要查数组或union的越界,没有“syscall给驱动”,因此跨平台,何来segfault?顶多送个内存片swap和热更新热迁移(混合睡眠/分布式fork),做好函数间互相jump; yield(闪存或typed)的“IPC”。

IO? 直接说ip+fs 分片传输吧,检测点击长按、解码HDav到PCM也没见内核态自带啊,外设和性能也不必突破一切皆文件。
ip实际上靠http。纯socket没?args长度没返回MIME类型 ,URL就平替了 env key=v PATH/git/add-command?k1=v1#.mp4 .wav; 实现共享
ip和sh命令一样,带参数单文件而已。ip还附赠跨语言扁平读写(REST序列化)。 stdout本该可直接 print Blob(bytes,MIME);而stderr是loglevel变量,没意识到这让log4j竖子成名
用过 nc;curl 管道和GET,PUT都知道,http函数模型比sh优秀,实际上WebAPI/py调包远胜于UNIX。PJAX调用/PWA就是一种“上文切换”、IPC、/{etc,usr}软件格式

时间内存存储程序,网口线口板口,4片3口虚拟化 😊
逗号左半,pyjs javacs rust 包括C作者自己写的Go啊 Docker啊,哪个不比libc+Linux强, uv(vs ^CSIGINT或evpoll?) jemalloc(闪存0copy和0flush) psql redis/flatpak
逗号右半,Bun.js ip栈封装; WebUSB; Arduino; 各种图形界面设定,很简洁,一到hwinfo“元数据”就乱搞,像fastjson大师修注入似的。凑字数?给骇客留空间!
包括那个 ld.so 可绕过的chmod +x ,多用户真的比多app容器+人均root有用么? OS竟敢不按devs的喜好来部署。
《程序员的自我修养》大概比较了COFF对象的这几种分支,PE,ELF,甚似于apk。常量池.rodata、全称名mangle、字节码动态链接、菜单图标、自带资源树和签名,比之C++ 对象,不能复制修改,无虚表原型,无双指针框定类型,不线程局部而。

也就是缺个二进制 databind 写冷门硬件的“驱动”,不过那也无所谓,ASN1式的屎山只能像zig那样,自动C2zig
有人说用户态不够,memsafe 后还需要调度器呢。 谁要那个巨无霸4K起步的 struct task/PCB{} 啊,还有上文切换开销。画蛇添足? Lua, 2KGo, NTFS和安卓的FUSE, numpy 真多核……从API从源码开始做优化,删掉无意义的设计模式,四海皆效仿,才配叫编译器和OS!

我半年前1k阅读的稿,也是这样 libC sucks 的观点 https://tttttt.me/dsuse/19854
淫王也这么想 https://www.yinwang.org/blog-cn/2019/08/19/microkernel#:~:text=一个操作系统本应该
1🦄1
#os #go #py 协程 https://lucumr.pocoo.org/2024/11/18/threads-beat-async-await/
作者似乎想用Scratch里没有await传染性的例子,说明return的自动回调化是骗局。 说真的,JVM和QuickJS应该有「有栈协程」,但程序员对它的控制太低。
IO异常耗时,应当被最小化、隔离,是很难理解的事情吗?

https://editor.p5js.org/p5/sketches/Image:_Load_and_Display_Image #code
setup=(
cat=loadImage('assets/moonwalk.jpg'),
P=createVector(width,height).div(2)
)=> {
createCanvas(720, 400);
draw=async()=>{
for(; P.x<2000; P.x+=5, await sec(.1)) {
clear(); image(cat, P.x%width,P.y);
}
}
'BAD'?? (draw=()=>{
if(P.x<2000) P.x+=5, setTimeout(draw,100)
clear(); image(cat, P.x%width,P.y);
//如果用伪递归做 for x in range(0,2k) 这很自然!其实
})
}
wait4=f=>(...a)=>new Promise(ok=>f(...a, ok))
sec=wait4((n,ok)=>setTimeout(ok,n*1000))


回应式(Reactive)只是给你自己管理单核while(1)的机会,挂起到函续是为了灵活复用触屏鼠标等流资源,调用栈=函续链表,yield=将caller的(retAddr捕获到.then)的空函数。 前者是魔法是驱动,后者是回调,是数据值。
回应式>卡线程,就像@装饰器>C宏 ,默认final>默认mut ,理所当然的严谨,不留模糊的余地。 trust me, Thread.ofVirtual() 和点号前面那货有代沟! 60年代为编译器的,竟比y2k为UNIX的API强。

至于async所“严重”缺乏的waitGroup,实际轻得多,而且 Promise.all([]) 能返回[], try{} 可以捕获内部await, Thread.join() 却啥都没定义,这安全吗!
他们只是看不惯JSer们对「OS后端的专利」有所突破,打破了NonlocalJump的魔法次元壁,把IO、设备流信号、缓冲区为己所用,突破了轮询+回调地狱的框架而已。
作者似乎想用 neverSettle = wait4(f=> 'never f!') 证明回调的依赖倒置是错误的,是泄漏的,但谁都知道 longjmp()和fork() 坑更多、更慢。不知哪天设备信号或驱动syscall就把UI卡死了!

因为就连Linux长年的八股“非惊群”evpoll,也是DOM「Reactive富二代」玩剩下的。
他应该想说 https://lotabout.me/2020/Back-Pressure

60fps达不到,是卡帧or丢帧; 网卡流丢了几个包,是等待TCP or 佛系UDP; cat|less 的端点SIGHUP了,由谁持有cat已print\n的行?或是让cat卡在SYS_write(),甚至直接panic?
对N:M task来说,线程池里每个Worker,比如它们的write/sendto(),都有瓶颈。这就像在2核CPU上 make -j8 ,最终不是慢在切来还去,就是内存占满。 用户态调用栈(async回调) 忽视了N资源M监听反会变慢。

作者批评了 asyncio writer.drain() 的不默认,和超过SQL瓶颈数量的并发(缺乏 CapacityLimiter API)
作者建议,在 HTTP 中,您可以发出 503,它还可以携带retry-after标头,告诉客户端何时重试
其实,受到速率异步问题困扰的不仅仅是 async await 代码。 例如, Dask是数据科学程序员使用的非async Python 并行库,仍有因拥塞而缓冲区耗尽的例子

值得一提的是,作者引用这篇把 go func() 证明为goto的Rustacean文。 这种思想(其实就是 Thread.join)也在 py async with: 和 kt coroutineScope{} 里
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
https://docs.rs/async_nursery/latest/async_nursery/#basic-example
https://zhuanlan.fxzhihu.com/p/713341244 #os #dev
这个世界上真实存在着很多 10x 的天才,他们以一己之力完成了普通人 10 倍甚至百倍的贡献。比如 Linus Torvalds、Fabrice Bellard、Alan Kay 等等。需要明确的是,这里的 10x,并不是以 10x 速度完成原本的事情(在这方面任何人都不是计算机的对手),

而是有能力解决 10x 复杂度的问题、完成 10 个人也干不成的事情。

为什么穷人大多都很自卑?
>
穷人孩子的耳朵边很少听到:
“自由 艺术 快乐 幸福 享受 平等 爱“这种字眼”

从小到大听到的都是:
“平安 看得起 看不起 努力 老实 听话 笑话 忍耐 吃得苦中苦方为人上人 一分杀千人 抢着上进”

成绩永远都是跟最好的比,物质跟更差的比
🦄1
https://zhuanlan.fxzhihu.com/p/12834699352 #os #cpp #rust #learn 协程 云风

>在知乎上看到两篇 吹嘘 云风的 coroutine 库的文章。

人啊就是这样的,出名了以后,就是垃圾也有人吹捧。

🤔 回头我可以科普下非阻塞(异步)、调度器、C++赝品Promise、 所有的协程都是使用的同一条栈(单一调度器) 有什么不对

https://www.zhihu.com/question/524369963/answer/21981903209
为调用 atexit(cb, cbarg0) 这人还写了个 GCC 实现 new lambda ,其实都很简单: up=1; f=(A)=>A+up 弄成 _f=(A,v)=>A+v.up ,再生成个 A=>_f(A, (captured_data*)x86_get_eip()[code_size])
被称为 trampoline 代码模板

整的我不会了,函数是穷人的对象,new个虚表或双指针挺直白的玩意这么麻烦,这是为啥呢?
因为 obj->call() == (obj.call) (obj,) ,是thiscall 1静1动,双指针则是 (*to_trait).call(obj,) 1静2动,而 CDEF f() 就是直接jmp过去,f肯定要在堆上,不能是static,但是又不能把f[code_size]到处复制粘贴,只好让 f.bind()=new 固定大小的可调用指针+data ,这还要求 “堆内存可执行”

结论:CDEF 的函数指针,危险危险危险。 UNIX 不以 addCb( any cb(any data), any data) 暴露回调API,坏; Python thread 暴露data参数,更坏! (py 都支持 fnptr.f_lasti 协程了还在用老思想编程啊)

CDEF 支持非阻塞编程的正确做法是: 在 dlopen() 外支持 dlnew(template_so, {statics...}) ,就像 ThreadLocal 那样。 硬是要把static重绑定为参数,才能安全兼容C++的 [](){return} 字面
duangsuse::Echo
码聋魅力时刻|面向运气编程
#os #fp #statement
从脚本单步,组合到程序,本来就可以实现为调用堆叠、回调链表 两种形式,和浏览器的历史栈一样,都是记得结果赋值到哪,组合数据结构 来解耦程序的“菜系”,形成API,提高表达力。

如果说 inc (Box n)=(Box n+1) 就是纯函数,而 box -inc; 隐藏了致命细节,这就是因小失大。FP不过是把赋值写入了栈上,还模糊了改写时复制/useMemo的时机。修语法=修语意?

js流行的 Reactive 不过是把 let [A,B]=match_XML(..) 从栈上拷下来,支持自定解构脚本,不是什么发明。类似这样狭窄的理解能力在做infra/做原理的人里比比皆是。

为什么要区分调用和回调? 只是Stack内存和变量树的减枝,GC 绑定得太深,必须用 new SAM_POJO(..) 把 vars(let-locals+栈上临时cell) 甚至回调的行号(yield),外提为this,能跨越的范围才足够广,
比如能 JSON.load/dump,能放在IO轮询队列(甚至SQL)里,而不必元编程。 闭包和 Java 的 int vs Integer 装箱,完全一样。

例如把while(1)预处理成隔1毫秒yield一次的那种,和stdio行缓冲一个样,就要"pid"这个this了。毕竟……Linux-ELF就是个段错误版的.class,还不如WebAPI和esp32生态诚实。


因此,区分模块、功能点所必须的vars()树是绑定局部、参数、this、inline #def、模块KV/全局KV表? 都没有意义,前三者本来就是封装简化的核心,所以()=>和enum{Ok(), Err()}可能是对的,跨越了堆栈,没有boilerplates,但也可能是难以二次开发、层叠的元凶。

唯一的方法是从语意解构APIs,诚实的描述用户和开发者需要的模型,而不是生搬硬套拉丁文。

例如,能够热迁移一个pid,像老式游戏机一样存读档的 CRIU Docker 和真正的操作系统plan9,就很理所当然。 是硬件和二进制在拖后腿

那群家伙至今也不想承认没人真正在乎 i32 i64 的极值是多大,u32比i32好多少,对,就是搞出千年虫的那群nerd。为啥不叫 byte4 byte8 char4 好了? who cares?

或许这才是OOP和FP间选不出最优的最大原因:人群不同。
Forwarded from Solidot
苹果无意统一桌面和平板的操作系统

2025-06-20 16:54 by 帽子里的天空

负责苹果软件工程的高级副总裁 Craig Federighi 接受采访时表示无意统一桌面和平板的操作系统,不会将
macOS 引入到 iPad。他解释说,苹果不想设计不伦不类的东西,如创造出一种船与车的结合体,或者勺子和叉子的结合体叉勺。以叉勺为例,它既不是一把好的勺子也不是一柄好的叉子。苹果的平板电脑 iPad Pro 被认为已经模糊了平板和笔记本电脑之间的界限,但 Craig Federighi 坚称,Mac 和 iPad 的用途截然不同,苹果为 iPad 引入 Mac 上的部分元素不是为了让 iPad 变成 Mac,而是互相借鉴同时保持独立。

apple.slashdot.org/story/25/06/19/084215/apple-software-chief-rejects-macos-on-ipad

#OS X
#rust #os yinwang 说的道理 😅😅
https://www.yinwang.org/blog-cn/2013/04/14/os-design

dnaugsuz:
诶,要是在libc或操作系统的程度把 unsafe ban 掉就好了

内存r/w都有struct可言

我能想到一个例子

比如对授信代码, union+tag, ptr+length 可以间接计算出来

其他的只允许用fatPtr双指针验证后调用

总之就是不允许用值类型+Maybe 以外的东西

不允许硬编码堆/栈地址,不允许自己捏造虚表来调用,不允许越界读写, 不允许通过addr缓存deepEq ID,并且造成一些无聊的误解

本来就不该信任的代码注入,就不该有虚拟机,而是靠沙箱, 就像 eBPF 用setInterval取代while(1)那样

哦,所以这又是一个C经验问题……

我看到过bpf插件在heap上搞 struct 不={} 的

应该是 .bss 的问题吧,不是new的
calloc 才是C喜欢的🥰
所有人都只用 malloc ,默认必须有构造器赋值码😂

C自己的对象结构(.so segments) 也是个神人

在我看来,这和JVM的OOP对象没区别, 只是更加难以创建

ld-linux 不该叫 dlopen(),该叫 new("xx.so") , PATH 或许也该叫classpath😂 ,只是它的API只支持换汇符流,没有json……

这玩意和线程vs携程一样, 基本上就是 Ring0/ userspace 的区别

结果却是,整个编程界重复造轮子 。

如果从C的程度就把这些 hack 视为 unsafe 的

根本就不会有把所有对象按 r/w/x 分割出堆/栈/静态/类型区 的做法

有 .so ELF 的时候他们就知道需要 constructor ,但是最后C还是只有全局按sizeof分配

而不是细粒度管理

就像 React vs Svelte 一样,没有人会蠢到用60fps检测一下“山寨DOM”更新了多少,然后去patch, 而是你点了1次,它就知道有2个text要刷新, 本该如此

一开始,该就分治好

Rust虽然语法挺原神的,API设计也没革命性, 在我看来它至少懂怎么规划变量树

而且UIUX做的不错
Please open Telegram to view this post
VIEW IN TELEGRAM
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字节,段+地址),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]; 或者直接枪毙