V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  kuanat  ›  全部回复第 8 页 / 共 19 页
回复总数  379
1 ... 4  5  6  7  8  9  10  11  12  13 ... 19  
2024-12-10 14:22:36 +08:00
回复了 moyuman 创建的主题 程序员 最“流畅”的终端模拟器是什么?
@moyuman #13

平滑滚动是靠视觉残留形成的错觉,所以平滑滚动光标很容易做,但是平滑滚动内容本身是很难的。

由于终端里的内容基本不存在关联性,平滑滚动这个事情在不牺牲速度的前提下我个人认为不可行。
2024-12-10 14:19:43 +08:00
回复了 moyuman 创建的主题 程序员 最“流畅”的终端模拟器是什么?
@adoal #16

OSC 52 确实是非常好的,终端里也不区分本地和远程。

当然我觉得这事属于历史问题,特别是 linux 环境。clipboard 是个桌面层面的实现,x11/wayland 还不一样,所以 vim 与系统剪贴板的交互是比较低效的 ipc ,而且需要编译期增加支持。理论上如果把 * 寄存器与系统寄存器关联也可以,但 vim 的设计 delete 会和 yank 同样使用 * 寄存器,这就导致按一下 x 也会触发一次 ipc ,一方面造成卡顿,另一方面用户也不想删除的内容进系统剪贴板。
2024-12-10 13:33:12 +08:00
回复了 moyuman 创建的主题 程序员 最“流畅”的终端模拟器是什么?
我推荐 foot https://codeberg.org/dnkl/foot 另外这个作者其他项目也都非常好。


设计哲学层面我不是很认可 kitty/alacritty 的路线,恰好这个话题我在之前的讨论 zed 编辑器的帖子里提到过 https://v2ex.com/t/1056672 可以做参考。

foot 的作者也有专门写过文章论述 https://codeberg.org/dnkl/foot/wiki/Performance


除开渲染层面,foot 的作者同时维护 fcft 一个 rasterization 的库,这个库对于字符的处理我认为是目前最好的,foot 的字符显示就是基于 fcft 。

还有 foot 对于 OSC/escape sequence 的支持非常标准化,很方便做定制或者与其他应用交互。
2024-12-06 15:13:14 +08:00
回复了 chopin1998519 创建的主题 程序员 调整 bios, chrome 会失去 session
我没有搜到 chromium 关于“机器码”相关的代码,而且常理上这个设计也很不合理。

我更倾向于认为是与 PAM 相关的原因导致的。登录凭证比如 cookies 这些是加密存储的,而 chromium 的加密密钥是存储各个平台的 keyring 的,mac/win/linux 都一样。Linux 环境解锁 keyring 与 PAM 相关,一般是登录桌面的同时解锁。

升级 bios 或者某些行为可能会导致 PAM 策略下 keyring 未能正常解锁。
2024-12-06 14:56:45 +08:00
回复了 assiadamo 创建的主题 Go 编程语言 被 Java 毒害的脑子想在 Go 中实现一个操作,望打醒
至于是不是符合 Go 哲学的问题,我看不出这样做的意义。正常使用接口就可以了。
2024-12-06 14:41:20 +08:00
回复了 assiadamo 创建的主题 Go 编程语言 被 Java 毒害的脑子想在 Go 中实现一个操作,望打醒
我有两个想法:

- 编译时方案,可以交给外部 preprocessor 当作模板来处理,后续代码生成之后再用 Go 编译,当然这个外部工具也可以用 go 写。目前来看基本上都要用特定的模板写法,而不是 Go 代码。

- 运行时方案,理论上这个需求和 hot reloading 应该差不多,对于 JIT 来说是比较好实现的,对于 Go 应该比较难。像 C 没有 runtime 是可以做到的,如果 Go 要实现类似的功能我估计需要魔改 runtime 才行。
2024-12-04 13:49:29 +08:00
回复了 matrix1010 创建的主题 Go 编程语言 大家有没有见过没有使用依赖注入的复杂 Go 开源项目
我觉得需要重新描述一下,区分依赖注入和依赖注入框架。对 Go 来说,依赖注入几乎无处不在,但没有使用任何依赖注入框架的必要。

一时半会想不到特别合适的开源项目,我就尝试描述一下做法。正文里提到了依赖注入的两个场景,一个是被动初始化,另一个是单元测试。这两个都可以用接口 Interface 来完成,方法也是一样的。

标准库里有非常多传递实例的写法,比如传一个 *http.Client 这样。如果需要多个不同组件按照特定顺序初始化,可以直接用 struct embedding 把各个实例封装起来,然后就可以传递 struct 了。

因为我的组里有很多其他背景的开发者转型而来,对于传递 struct 的做法不认可,主要的理由是他们都有要初始化几十个依赖的经历。我对此的观点是,某个组件依赖几十个其他组件这件事本身就有问题,即便是真的有很多依赖,也只是依赖其中非常小的功能而非全部。我个人认为造成这种结果的原因是用基于 class 实现的继承去套用 Go ,而 Go 的做法是完全不实现继承功能,通过组合来抽象 OO 。

第二个需求单元测试需要对代码做调整,或者说对编程思路做调整。之前我在别的 Go 语言讨论帖子里反复引用过 Accept interfaces 这个说法,如果将调用方的代码依赖从实例改成接口,就可以非常简单地实现 mocking 来做单元测试。

因为调用方无须关心调用的是哪个实例,只要这个实例实现了特定的接口即可。将调用方的方法改写为接收接口,就可以用任意的实现来 mocking 对应的功能。

如果把接口当作继承来用,那自然就会觉得依赖是个复杂的事情,因为这个接口会越来越大,最终变成了模块之间的强耦合。实际上 Go 的思维里,接口越小越好,这里的思想是组合而非继承。一个非常小的接口是很容易 mocking 的。

另外如果观察一下 github 上 Go 的 DI/mocking 相关的项目也能发现一个趋势,相比其他语言这两种框架几乎都不流行。因为真的没有必要。不过反过来说,接口就是依赖注入。
2024-11-22 21:28:13 +08:00
回复了 17681880207 创建的主题 程序员 macOS VS Code 窗口透明怎么实现?
技术层面窗口透明是合成器( compositor )的功能,应用自己并不能决定自己是否透明。或者换个思路,窗口合成器提供给应用一个抽象的渲染区域,这个区域出现在屏幕的什么地方,以多少透明度显示都是要窗口合成器控制的。

所以需要一个能控制窗口合成器行为的应用,插件起到了告诉这个应用把什么颜色当作透明色的作用。楼上 issue 链接里的插件就是这样。
2024-11-22 21:10:16 +08:00
回复了 godFree 创建的主题 Android 求助 安卓 apk 逆向相关问题
frida-trace 看调用栈。
2024-11-22 13:35:29 +08:00
回复了 creeeeezy 创建的主题 NAS 请教网络聚合失败的问题
@shika #26

balance-rr 还有 tlb/alb 都不需要特定交换机支持,具体可以看 linux bonding 的文档。

但这个行为确实与交换机有关,当启用 balance-rr 的时候,在交换机看来多个端口对应设备的 MAC 地址在反复切换,交换机会有异常的表现。一般来说管理功能越高级的越可能出问题,傻瓜型的往往没有影响。
2024-11-22 13:29:18 +08:00
回复了 creeeeezy 创建的主题 NAS 请教网络聚合失败的问题
@porrt8 #22

没有关系,多链路的数据包也可以经过多网卡发送。多线程的情况下可以在不支持 rr 平衡模式的时候提供更好的带宽利用率,只是每个线程都无法超过单个网卡的最大带宽。
2024-11-21 23:19:36 +08:00
回复了 creeeeezy 创建的主题 NAS 请教网络聚合失败的问题
OP 描述的现象的实质与单链路和多链路没有关系,我这里简单解释一下,就以 OP 的环境为例,L2 交换机没有端口聚合的功能。

L2 交换机的工作原理是根据 MAC 将数据包发送到特定的物理端口上,物理端口对应设备的 MAC 是通过记忆或者 arp 协议来更新的。L2 链路聚合会使聚合的 NIC 设备共享相同的 MAC 。

设想客户端 MacBook 通过 smb 协议访问 Win/Linux 资源,这是个单链路的请求,到达交换机端口的时候,不同交换机可能有不同处理方式,不管怎么样,都只会通过一个口到达 Win/Linux 。

由于 Win 不支持 round robin 的平衡模式,所以返回数据一样只会走聚合链路中的一个。这是常说的单链路无法超过单一接口最大速率的情况。Linux bonding 的区别在于,返回数据(包)会轮流经由两个网卡发送,所以可以同时利用两个 NIC 的带宽。当这些数据包到达交换机的时候,又会被交换到客户端的那一个端口上。

能够实现这个效果的原理就在于 linux bonding balance-rr 这个实现。其他的负载平衡方式主要看 hash 参数,也有些自适应的模式能达到类似效果。更底层的原因是 linux 网络栈是内核实现,来源不同的包只要具有相同的元组就可以被内核转交给应用程序正常处理,而应用程序构造的数据包交由内核之后,经由什么途径发出与应用程序无关。

这个实现对交换机没有要求,如果交换机可以对两个端口做聚合会更好一些,这样就不需要反复更新 MAC 与端口的绑定。可能存在的问题是乱序,即顺序包经由两个 NIC 到达交换机时先后顺序错乱了。双 NIC 聚合可能还好,数量越多 rr 模式越可能产生乱序。


PS

上面说得可能有些抽象,如果有 socket 编程经验可能更容易理解一些。

关键点是网络栈是内核实现,协议/IP/端口这些都是属于内核的,而不是属于某个应用的,同样也不属于某个网络设备。应用只能通过 bind 之类的方法获得 IP 端口的使用权,内核收到的数据包,把内部应用层的部分交给应用程序。应用程序处理完毕后,发出的数据包实际还要回内核,由内核包装上外层协议并完成路由(一般说的四表五链),最终到达网络设备 NIC 的时候,再做 L2 层封装上 MAC 等等发送出去。

所以本质上应用层面上的单链路是否经由物理层面的单通道发送是不相关的两件事,正因为这种架构上的解耦,最终才能够实现单链路带宽翻倍的效果,同时还不需要特定的交换机支持。
eBPF ftw!

赞一个!
2024-11-14 22:28:16 +08:00
回复了 RiverRay 创建的主题 分享创造 发现了一款超有意思的 AI whisper 语音输入法 哈哈
妙哉!
2024-11-14 22:18:00 +08:00
回复了 IIInsomnia 创建的主题 Go 编程语言 从 0 到 1 手撸一个协程池
@yuan1028 #22

我一样很少用到,过去几年里都是如此。你可以看 #24 的回复,我跟你的观点是一致的,动态扩容是实例层面的事情,go 应用单体不应该考虑。这里讨论的是真正存在压力的生产环境。

性能指标这方面,还是要具体情况具体分析。我是极其反对单纯以 cpu 或内存占用作为性能指标的,除非它是真正的瓶颈。笼统地说我一般会跑一下火焰图和计时任务,观察一下可能的热点或者瓶颈在哪里,只有确认了瓶颈存在才会考虑优化。网络编程这个领域,多数时候加钱( cpu 和内存)比加人工更有效。

具体到并发相关的参数,考虑一般有限资源环境中的调度问题,调度行为一定会产生损耗,根据特定的业务场景,追求低延迟就看前 5%的耗时,追求高吞吐就看 95% 的完成时间。看统计分布比看单一指标更有意义。
2024-11-14 22:05:15 +08:00
回复了 IIInsomnia 创建的主题 Go 编程语言 从 0 到 1 手撸一个协程池
@lesismal #18

我遇到需要极大协程池的只有一个负载平衡路由的 dispatcher ,然而“通用”协程池动态调节对于这个场景也是没有意义的,一次性预热分配好常驻就可以了。

我这里很多资深(职级)程序员都有一种对于 universal/variable/dynamic 方案的迷思,反倒需要我经常强调动态可变实现带来的不可预测性才是大忌。即便是一个理想的动态实现,使用的时候还是会根据硬件、网络实测一个并发上限并一直沿用下去,那这和写一个固定的实现没有什么区别。且不说真正业务产生的 cpu 和内存消耗数量级层面就高于调度器的损耗,即便节省出来资源,也不可能在这种有关键性能的位置搞 cpu 或者内存共享。

也许我这样说有点暴论,但我认为,一个承载能力为 N 的系统和一个承载能力在 0~N 之间变动的系统在生产环境是没有区别的,而前者的复杂度耕地,可维护性更高。
2024-11-14 17:53:24 +08:00
回复了 wjpauli 创建的主题 Amazon Web Services 求助: AWS 的 SES 不给出 Sandbox?
这个审核很迷,年初帮朋友做个项目申请没过就改用第三方的了。然后过了大概半年突然发邮件说违规把 ses 停了,又过了几天说封错了,结果 ses 权限就莫名其妙开了。
2024-11-14 17:29:31 +08:00
回复了 IIInsomnia 创建的主题 Go 编程语言 从 0 到 1 手撸一个协程池
大概三年半前,由于众所周知的原因,各种会议特别多。团队有过一次讨论,就是要不要引入外部、通用协程池实现。现在我把当初讨论的重点摘录出来,权当抛砖引玉,看看这些观点能否经得起时间的考验。

1.
工程管理层面,我的观点是所有引入第三方依赖的行为都要慎重,当然我并不反对引入依赖,完全自己造轮子的工程量和实现质量都是更大的问题。那这个引入的平衡点在哪里?有几个考量因素:第三方库的规模以及项目中实际用到的功能占比,第三方项目的生产环境成熟度,团队内部 review/debug 甚至换人重写的成本代价。

无论从哪方面看,协程库这种功能单一、实现简单的组件都应该内部实现。额外的初期开发成本,相比维护 debug 甚至人员调整、供应链风险等等方面的收益简直不值一提。

2.
实际上就我个人观点,我认为要不要引入三方协程池实现这件事本身根本不需要上会讨论,之所以拿出来讨论是为团队建设服务的。团队协作的困难在于成员之间建立共识,考虑到团队成员背景、能力和经验不同,最常见的情况就是以为是共识但实际上不是,所以就需要反复沟通交流。还有更常见的情况,技术路线的决策结果很容易自上而下传达,而支撑决策的论据在传递过程中就缺失了,项目成员工作在不知所以然的状态。我更倾向于让成员建立更多的共识,这样可以减少后续的沟通成本。

支持引入一方的核心论据是三方库的性能高,并且辅以 cpu 内存占用等等数据。其实以最朴素的科研思维来看,测试数据集特征、测试方法以及因果相关性匹配程度,都比单纯的跑分结果重要。

补充一点关于网络并发的历史发展,很多年前有过 c1k/c10k 之类的说法,但是之后很少有说 c100k/c1m 的,因为这个过程主要依赖的是横向扩展而非单体。单体应用并发 1m 协程是个极其小众的场景。再就是需要用到协程/线程池这个技术,有一个隐含的前提就是协程/线程昂贵,是事实上的瓶颈。放到二十年前这个前提是成立的,然而随着软硬件的发展,cpu 核心数、内存大小甚至带宽都可能是瓶颈,唯独 golang 协程很难成为瓶颈。

3.
回归技术层面,“通用”协程库的问题有哪些?调度逻辑是个与业务特性强相关的功能,通用实现的性能指标和业务需求很可能不匹配。

再具体到实现细节,“通用”库为了实现其通用性,对于“任务”这个概念的定义实际上被抽象成了“可以执行任务的函数方法”,作为调用方,不得不去匹配一个特定形式的签名,与之相关的超时、重试逻辑和异常处理都要做出调整。继续思考下去会发现,如果要完成与协程的通信,加入 chan 管理又是大工程。这一切的根源都是“通用”协程库对于“任务”这一概念特殊抽象的结果,选择了这样的抽象就注定了这样的处理方式。既然通用库侵入性这么大,实现难度又低,为什么不自己写呢。放弃通用性,可维护性


PS
如果让现在的我来评论,观点会更加极端。“协程池”之类技术的核心是任务调度,而池化是有时代局限性的妥协。Go 语言设计出低心智负担的并发模型,就是为了让开发者不用费尽心力去管理什么协程池。当你觉得有什么需求是非协程池不可的时候,不妨重新思考一下“任务”的本质。在 Go 的思维模型里,任务的本质是数据,任务调度就是数据的流动,完成调度这个行为有太多更简洁的做法,过去把任务理解成执行动作的思路是低效的。
稍微偏个题。

编程这件事的本质是什么?我个人有个粗糙的定义,就是用语言对某种事物、行为或过程做出无歧异的抽象描述。用自然语言给人指路、教人下棋或者介绍产品都是编程,只是这种程序的执行者不是自动化的机器。

从计算理论上说,图灵完备的编程语言之间不存在表达能力的差别。语言特性和编程范式百花齐放,表面上是工具特化的结果,深层次是反映编程者对于现实的认知逻辑和思维方式。

FP 是数学上优美的,非常适合解决真空中球形鸡的问题,现实大多数问题仍旧需要传统经验公式和手段来应对。OOP 是有效解构对世界认知的哲学,但实现 OOP 的方式却不一定。组合( composition )替代继承( inheritance )就是认知层面的进步。

从过去二十年编程语言的发展来看,语言特性 FP/OOP 的进步演化一直在发生,但几乎不存在相互替代的基础。作为工具的编程语言,以当下的视角来看,能够成为主流的一定是具有工程化能力基础的,只有解决问题的范畴和效率提升才会带来工具的替代。
2024-07-12 21:14:42 +08:00
回复了 june4 创建的主题 编辑器 未来最牛编辑器 zed 的 Linux 版终于出来了
@lysShub #71

没有说怎么测的,我也没细看,就假定它用的一致的测试方法好了。延迟测试包含了语法分析,但是因为它只是在新的一行里反复按了 10 次 z ,所以这个语法分析的时间可以忽略不计了。
1 ... 4  5  6  7  8  9  10  11  12  13 ... 19  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   970 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 33ms · UTC 19:27 · PVG 03:27 · LAX 11:27 · JFK 14:27
♥ Do have faith in what you're doing.