V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lxdlam  ›  全部回复第 3 页 / 共 7 页
回复总数  121
1  2  3  4  5  6  7  
297 天前
回复了 wyhaya 创建的主题 分享创造 Dataflare: 一款简单轻量的数据库管理器
非常好看,用了下也挺轻量级的,支持了一波。提一个功能建议,可以增加 intergrate db shell 的支持,类似于 mongo compass 和 redis insight 下面的 integrated shell
用 Windows 10 专业电竞战斗版 1.5 。

https://www.v2ex.com/i/z8Tz1085.jpeg

图源来自网络。
300 天前
回复了 darkbread 创建的主题 游戏 游戏玩到一半玩不下去需要坚持吗?
我一向觉得游戏的目的是找到快乐,如果找不到快乐了,就可以不玩。
一方面我同意 #3 ,更像是编译器的 bug ,另一方面我本地似乎复现不了这个差距如此巨大的结果,估计可以看下 1.21rc 到现在( go 1.21.6 ) 的差异。

而对于一定程度上的差异( 100000ns per op ),单纯从生成代码上来看,f 生成的函数直接对 r 做了修改,所以需要一次对 r 的 load ,而 g 是对一个临时变量做修改,虽然二者都是一次 load 跟一次 store ,但是 r 毕竟不好说分配在哪儿(也许在 heap 上,也许在 register ,看编译器优化),那么 r 确实可能比起临时变量( go 倾向于分配在 register 上)的读写要更慢。至于为什么会有如此差异,实际上应该是因为编译器识别出来了这个累加 pattern ,而在 f 里因为没有额外操作,所以直接对 r 进行操作,把加数这些都当 immediate value 优化成单次 INCQ 了;而在 g 中,由于又读到了 r + 0 ,编译器首先优化成了将其写入中间变量的操作,又在后续 pass 中发现其实对 r 基本无操作,去掉了这里面所有 r 的主动 reference ,将其完全优化到了完全只读写中间变量,所以生成了这个样子的代码。

以上仅抛砖引玉,我不是 plan9 和 go compiler 专家,只能看个大概,这里面同样可能会有很多说不清的其他因素影响。但是我仍然同意,这种 case 应该 report 给官方去修改,而不是当新时代的语言律师模拟考题,同样,如果在乎这个粒度的性能差距,可能我们会选择更精细的语言和优化方式了,而不是在这继续抄写茴字剩下的写法。
日区 Spotify 已经两年+。

从体验上来说,AM 跟 Spotify 的算法都很不错,冷启动到符合我的喜好学习速度很快,也不会跟 Youtube 一样,播放列表只会循环推完全特定的歌,基本零探索性(比如推一些可能会喜欢可能不喜欢的)。

但是 AM 缺了一些关键功能,比如必须苹果全家桶才能用上比较好的远程控制,但也仅限是手机/电脑 -> HomePod ,诸如 Spotify 的所有端都可以跨端控制有很大距离。同时,除了苹果之外,Android 上的体验也不尽如人意,最终放弃。

从音质上来说,流媒体我完全不在意音质,确实非常喜欢的歌我都会去 mora ,ototoy 买 Hi-Res 或者直接收实体 CD 抓一份,我对流媒体的核心要求还是方便+曲库+算法。

特别补一个,Apple 的 iTunes Match ,就是所谓的“云盘”,其实非常难用。iTunes 的标签修复有非常大的苹果延迟,就是你并不能完全知道到底这个 tag 修复有没有被正常推到音乐库里面,有可能在 mac 上看起来修了,换个设备发现压根没变化。同时,上传音乐的时候苹果会去自己的音乐库 match ,如果有就会用自己的替代,这样如果你抓了 44.1khz 16bit 的 flac ,但是苹果并没有这个音质的版权,他会给你 match 回 aac 版本,音质倒退。
@ShadowPower 上面 #67 老哥也提到了,其实这个范式在函数式社区很常见,我们重点不关注你是不是所谓的“错误”,而关注类型本身,考虑用类型做 matcher 去配合值做 transformation 。这些年一些工业界的看起来很新的方法都来源于此,比如经典的 parser combinator ,如果你把 `Result<T>` 这个二元类型异构容器思考成 `Pair<&str /* remain input */, Result<T /* Token type */>>`,其实这里面的函数组合跟我上面说的 error monad 是一致的。更进一步来说,函数式的底层数学抽象 lambda calculus ,其实就是一种 combinatory logic ,天生以组合为主。在这种背景下,函数式语言采用这种思考是非常直接的。
@lxdlam typo:这种双类型语言 => 这种支持双类型(甚至更多类型)组成异构容器的语言
单从两种范式上来说,值类型跟异常类型错误直接比较很难比较清楚:

- 值类型还是将错误当作值,本身没有控制流操作,所以当作值处理可以轻松当作比如 data 的一部分到处传递处理等等,缺点就是缺乏强制力,简单把值 ignore 掉就可以丢掉错误,而大家都倾向于懒一点;
- 异常类型可以打断并接管控制流,更加强大,guarantee 也更好,如果 runtime 实现得不错(比如 Java )那用起来其实还是很舒服的,缺点就是这个特性很容易被误用(相信大家都听说过或者见过用 exception 传值的业务代码)。

两种范式各有优劣,其实没有直接关系,语言风格而已。

而单纯讨论值类型错误,Go 的实现有自己的优势。错误这个东西本身就是很容易产生很多 concrete type 的,基于 duck typing 的 interface 化,其实大大简化很多操作,比如直接把已有 error wrap 起来,然后实现一下 `Error` 和一些 helper function ,就能快速搞一个新的错误出来,开发效率是很高的(没有 thiserror 和 anyhow 之前,Rust 搞个自定义错误有多痛苦,相信很多朋友深有体会)。
Go 最大的问题其实在于,他采用了值类型错误,但是类型系统支持非常 basic ,导致大家处理错误非常痛苦。比如在类型系统比较现代的语言中,这种双类型语言或多或少能实现一定程度的 monad ,这样我们就可以写出类似于:
```
let val = some_function().map(fun).map(foo).map(bar);

match val {
Ok(v) => println!("Value is: {}", v),
Error(e) => println!("Failed! error: {}", e),
}
```
在这里面,我们我们确实不关心中间错误,直接 chain 起来,处理最后错误就行,而如果我们关心比如到某一步的错误,我们单独接一下这一步的结果就可以拿到中间结果再做处理。无论是看起来还是读起来,其实都非常清晰明了。而可惜的是,Go 因为一开始设计压根没想这个问题,导致现在的打补丁的 generics ,很长线看起来都很难支持这种比较完备的 monad 特性。所以,我们只能一步步 if-else ,或者将这三个函数塞到一个 slice 里面,用 `reflect` 循环每个函数 apply 去每一步拿一下 type 信息做一些非常丑的补丁。
稍微补一句:为啥这里需要比较好的类型系统才能实现?在上面的流程中,实际上 `map` 接到的函数签名类型是各不一样的,有比较好类型系统的编译器在这里可以做非常好的静态推断;或者我们完全交给动态类型,损失一定 runtime 性能也能做到。而可惜的是,Go 既要选择尽量静态类型,又没把静态类型做很好,就卡在这了。
339 天前
回复了 lear7 创建的主题 问与答 为什么现在软件质量不如以前?
一个角度,其实是优胜劣汰:只有以前稳定、优秀的软件才能在现在才会被多次提及,一种幸存者偏差。
巴别塔圣歌。

作者对语言系统有一定理解,对语言、文化氛围的塑造有出色的把控能力,唯一缺点就是结尾略显机械降神,缺点意思。
2023-11-24 13:42:03 +08:00
回复了 lxdlam 创建的主题 酷工作 [北京] 3D AIGC 明星企业持续招聘技术实习生
@northbrunv 会一个即可,如果会 Vue 更好。
单纯只看的话确实 Sumatra PDF 最好用,也是 Windows 平台上个人体验 LaTeX 预览配合最好的 previewer
- 宏:基本上来说宏就是把编译器当做自己的预处理器来做 codegen ,从提案和实现上来看,Swift 的实现还是比较累赘,简化宏的构建和未来使用上,应该还有些工作可以做。
- 跟 C++ interop:本身也是把脏活累活交给 LLVM ,编译器多做一步 parsing ,然后做 codegen ,生成另一边的 binding ,重点看易用性,这一块做的比较好的是 Julia ,不仅可以直接 call C/C++(需要用 Cxx.jl 包)函数,更可以直接在 Julia 里面写对应代码,下面直接调用。Swift 的易用性目前看起来还是不错,期待明天的演讲。至于 CMake 编译工具的整合,是一个很 intuitive 的结果,Swift 支持编译器插件之后,这种加 custom pass 的工作就变得很简单了,比如 zig 也支持直接混合编译 C/C++/zig 代码库。
2023-06-06 15:02:31 +08:00
回复了 zhangsimon 创建的主题 Apple Apple Vision Pro 讨论贴
苹果这次硬件跟技术还都挺成熟的。
- 技术:Vision Framework 做人体识别+骨骼绑定,ARKit 6 和 Reality Kit 都已经在去年 WWDC 布局好了,R1 芯片专门一个 rendering 和传感器的 RTOS subsystem 处理,M2 带来的够用的算力等等,可以认为他发布的东西基本都是真实的;
- 硬件:专门定制的双 4K 镜片,眼动+虹膜识别摄像头,其他的一些环境捕获的摄像头现有的 VR 方案也都基本搞过了。

从产品角度上来说,Vision Pro 的价格和配置算是合理的,电池这种本身就是被物理极限限制住的东西,在相应的新材料取得突破之前,也算是可以接受。

但是苹果始终没解决最核心的问题:内容产出和供应门槛问题。
- 发布会上苹果给出的解决方案还是自己的 3D scene 构建工具 Reality Composer 以及跟 Unity 合作,这些都是业界现有的链路,仍然是学习门槛比较高:假定只比较凑合能看,视频跟音频领域现在要做一个凑合能看的产物难度很低,但是 3D 领域还是需要基础知识+软件操作的复杂学习;苹果自己也没想好这个东西的 killer app 是啥,现在这个头显能做的事情,其他头显不管做得好还是不好,但是看上去都能做,而且价格远低于苹果的方案。这部分没有解决的话,生态是后继乏力的。
- 另一个问题就是价格,根据现在的价格,开发者更可能选择开发一个 ios 应用并将其发布到 Vision Pro App Store ,而不是专门做 Vision Pro 的 killer app ,因为价格的问题导致市场较小,ROI 其实并不高。

我的态度:会购买,会尝试,但是不太看好。苹果押了注,但是能否成功,任重道远。
2023-05-22 13:47:17 +08:00
回复了 nkchn 创建的主题 分享发现 C++支持 import 了
从 P1103R3 之后,Module 在标准化上就通过了一个比较重要的提案 P2465R3 (将标准库 module 化),而之前听过一个大佬的分享,实际上从有到能用到堪用再到好用,还有很长的路径要走。

比如,随便可以举出来好几个问题:
1. 最基本的,编译时间、增量编译和宏的兼容方案?
2. Module 的 cache 产物统一:目前 gcc (gcm) 跟 clang (pcm) 跟 MSVC 是完全三套,先不提如何兼容,这离 Module 想达到的目标还很远;
3. 如何分发产物?如果分发 .so ,跟现在的情况有什么改变?如果分发编译 cache ,怎么在经典的 ABI 、Linking 等等问题下保持可用?如果需要用户单独编译,那为什么不直接分发源码?
5. 现有的工具链如何兼容适配?编译优化( ccache 等),包管理( conan 等)以及相关的 module 生态等,目前都没有一个明确说法。

至少在我看来+乐观估计,得等 5~10 年,等到这些问题有一个解决方案,才能达到堪用水平,我们才能说“C++ 有了 Module”。
2023-04-21 16:49:50 +08:00
回复了 0littleboy 创建的主题 程序员 剪切粘贴得来的文件还是原来的文件吗?
意识拷贝(意识上传)——容器不同,但是内容相同,是否认为跟原始个体相同? https://www.wikiwand.com/en/Mind%20uploading#Philosophical_issues

忒修斯之船——容器相同,但是内容物使用相同的替换件进行替换,是否认为跟原始个体相同? https://www.wikiwand.com/en/Ship%20of%20Theseus

都是比较经典的哲学问题,才疏学浅,只提供 Reference 。
2023-03-23 17:11:42 +08:00
回复了 killva4624 创建的主题 问与答 为什么 π 会比 3.2 大?
2023-02-17 15:46:11 +08:00
回复了 DengSven 创建的主题 问与答 关于个人养老金大家怎么看
Netflix 关于 IRA 和 401k 的纪录片,《 Money, Explained 》 E05 ,Retirement: https://www.bilibili.com/video/BV1964y127ZC?p=5
2023-02-08 20:35:31 +08:00
回复了 GopherDaily 创建的主题 Go 编程语言 Go 的特色不是语法的便捷,而是在工程
@GeruzoniAnsasu

刚注意到有个 context miss 了,我也补充几个点:

- 使用 mpsc 跟 spsc 是非常简单的,一个基于 token 的 bucket 可以简单控制好 task 的数量,共用 token bucket 就可以控制每个 spawner 的数量。注意到这里也可以简单地基于 chan 封装一个,不需要所谓的阻塞队列。
- spawner/worker 基于 message passing 的 channel 可以解决所有 promise 的场景,包括超时等待等。
- 所谓的全局 channel ,js 的 microtask queue 和 marcotask queue 同样是全局的,甚至基于这两个场景你如果需要定制化 queue 的调度逻辑你需要对 runtime 有更加深入地理解,而 go 基于 token bucket 做定制可以做更多的事情。
1  2  3  4  5  6  7  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5391 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 50ms · UTC 05:53 · PVG 13:53 · LAX 21:53 · JFK 00:53
Developed with CodeLauncher
♥ Do have faith in what you're doing.