V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  kuanat  ›  全部回复第 1 页 / 共 12 页
回复总数  232
1  2  3  4  5  6  7  8  9  10 ... 12  
11 天前
回复了 17681880207 创建的主题 程序员 macOS VS Code 窗口透明怎么实现?
技术层面窗口透明是合成器( compositor )的功能,应用自己并不能决定自己是否透明。或者换个思路,窗口合成器提供给应用一个抽象的渲染区域,这个区域出现在屏幕的什么地方,以多少透明度显示都是要窗口合成器控制的。

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

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

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

没有关系,多链路的数据包也可以经过多网卡发送。多线程的情况下可以在不支持 rr 平衡模式的时候提供更好的带宽利用率,只是每个线程都无法超过单个网卡的最大带宽。
12 天前
回复了 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!

赞一个!
妙哉!
19 天前
回复了 IIInsomnia 创建的主题 Go 编程语言 从 0 到 1 手撸一个协程池
@yuan1028 #22

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

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

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

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

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

也许我这样说有点暴论,但我认为,一个承载能力为 N 的系统和一个承载能力在 0~N 之间变动的系统在生产环境是没有区别的,而前者的复杂度耕地,可维护性更高。
19 天前
回复了 wjpauli 创建的主题 Amazon Web Services 求助: AWS 的 SES 不给出 Sandbox?
这个审核很迷,年初帮朋友做个项目申请没过就改用第三方的了。然后过了大概半年突然发邮件说违规把 ses 停了,又过了几天说封错了,结果 ses 权限就莫名其妙开了。
19 天前
回复了 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 的进步演化一直在发生,但几乎不存在相互替代的基础。作为工具的编程语言,以当下的视角来看,能够成为主流的一定是具有工程化能力基础的,只有解决问题的范畴和效率提升才会带来工具的替代。
144 天前
回复了 june4 创建的主题 编辑器 未来最牛编辑器 zed 的 Linux 版终于出来了
@lysShub #71

没有说怎么测的,我也没细看,就假定它用的一致的测试方法好了。延迟测试包含了语法分析,但是因为它只是在新的一行里反复按了 10 次 z ,所以这个语法分析的时间可以忽略不计了。
145 天前
回复了 june4 创建的主题 编辑器 未来最牛编辑器 zed 的 Linux 版终于出来了
我这里简单就 Zed 官网宣传的一些特性简单做个总结,同时与 VS Code 对应的部分做个对比。


1. 输入延迟

Zed 在性能方面有个对比,强调的是 Insertion latency ,58ms 相对 VS Code 97ms 算是非常优秀了。这个测试反映的是输入状态下按下按键,到字符出现在屏幕上的时间,如果你玩游戏的话,很容易理解这个就是所谓的输入延迟。

你可能觉得 40ms 影响不大,但这个特性属于有对比才有伤害、或者说像高刷屏用了就回不去那种。不仅仅是在文本编辑器领域,像终端( vte )领域一样对于输入延迟有追求,所以你会看到像 kitty/alacritty 这样通过 GPU 加速绘制的终端模拟器。再比如很多人会觉得 oh-my-zsh 之类的框架会拖慢 shell 的启动,考虑换成 fish 之类作为替代。

2. 渲染模式

也许你会认为 Zed 渲染快延迟小是得益于原生应用相对于 electron 的优势,是有这方面的原因,但是不够全面。同样是输入延迟部分,Sublime Text 4 大概是 75ms ,可以粗略的认为,Sublime 相对 VS Code 的优势来源于原生,但 Zed 相对于 Sublime 的优势有一部分是来自于渲染模式。

包括各种终端模拟器在内的应用,所谓的 GPU 加速更多的是使用 immediate 模式,相对于 retained 模式。前者就是把应用当作 3D 游戏,自己负责渲染每一帧。后者就是一般意义上的原生应用,使用系统控件,只有在状态发生变化时才通知系统,由系统负责渲染。

Zed 使用的是 Vulkan 后端,其 UI 界面就是基于 immediate 模式自渲染的。(技术上说,应用 GPU 加速通常更快,但不总是更快,这一点放到后面说)

3. 语法分析

如果增加一个 Deletion latency 的测试,我相信 Zed 会胜出更多的。原因是无论插入还是删除,后台都要做语法分析,从而提供高亮、补全等等功能。删除相比插入更能反应语法分析器的性能,特别是跨多行或者代码存在语法错误的时候。

Zed 的开发团队的前身就是做 Atom 的团队,而 Atom 当年之所以有底气做编辑器,是因为他们写了 Tree-sitter 这个通用的 parser 生成器。现在 Tree-sitter 是事实上最通用、也是效率最高的语法解析器的“生成器”。不是 parser 而是 parser 的生成器,这一点尤为重要。

在 Tree-sitter 之前,通用的语法解析主要是 TextMate 的,后续包括 VS Code 在内也都沿用了下来。连 VS Code 的开发都说,用 TextMate 这套的原因就是不用为每一门语言都写规则,然后他们也发现很多语言的规则都多年没人维护了。当初 TextMate 设计这个功能的时候想的是,尽可能在不用写 parser 的情况下完成 parser 的主要功能,所以实现方式是正则匹配。放到二十年后的今天来看,这个做法就跟不上时代了。

一方面现在的性能和软件实践来说,写 parser 和实时处理都相对简化了,既然都能完整实现和运行 parser 了,那就没必要用弱化版的了。另一方面,基于正则的弱 parser 实现只能处理一行,也不能支持像是“增量”处理,或者在代码被修改乱了,存在语法错误的时候还能正确输出尽可能有用的信息。

我个人认为,Tree-sitter 在这方面对于写代码的改善是非常明显的,不仅速度快结果还准确,特别是错误状态下依然有用这点十分好用。想要尝试的话可以用 neovim 或者其他基于 Tree-sitter 的编辑器感受一下。

4. 协同

现在没有什么编辑器能做到像 VS Code 的 Remote 功能一样彻底颠覆开发的工作流。即便 JetBrains 这样也算财大气粗的专业开发,照着现有的方案模仿都做得一塌糊涂。所以也不要对 Zed 有什么不切实际的期待。

Zed 目前能做到的是还是本机做 host ,然后可以编辑 remote 的文件而已,对用户隐藏了拉取和推送文件的细节。

所以 Zed 就专注做了协同功能,在本地编辑器上实现了多人实时编辑同一文档的在线编辑器体验。这个功能基于 CRDT 思路,有兴趣可以去看看。



关于“GPU 渲染为什么不会总是更快”这个说法的解释:

一般来说,GPU 渲染会更快一点,但就文本编辑器(或者终端 vte )这个场景来说,GPU 渲染不一定比 CPU 更快。这是因为 GPU 更快是建立在全渲染的前提之上的,而文本编辑这个场景很多时间并不需要全渲染。

比如输入的时候,发生变化的一般只有当前行。浏览代码的时候,代码内容不变只是显示位置变了。这样的场景里,使用 damage tracking 类算法,就是类似 vnc/xdp 那种检测改变部分的算法,可以极大降低渲染的工作量。以游戏渲染的思路来看,无非就是 framebuffer 的手动控制更新。

所以我个人并不喜欢使用 GPU 渲染的文本编辑器或者终端模拟器。当然,如果它像浏览器那样,将字体渲染过程中的处理交由 GPU 完成,我还是很支持的。
145 天前
回复了 june4 创建的主题 编辑器 未来最牛编辑器 zed 的 Linux 版终于出来了
虽然“未来最牛”这个说法值得商榷,Zed 作为一个编辑器还是有很多亮点的。目前来说想挑战 VS Code 的生态地位不太可能,但作为一个有潜力的(部分)替代说句未来可期不过分。至少从执行力上(当初说要做就真做了),还有第一个算是 public beta 的成品质量都是很靠谱的。

晚一点我写一下 Zed 相对比较优秀的特性,然后和 VS Code 做个简单的对比。

另外 Linux 用户应该不用担心中文输入的问题,目前只有 sway 存在不显示候选词的 bug ,其他支持 text_input_v3 的主流桌面都正常。sway 主要是维护上游 wlroots 所以发版慢,实际上自身早就支持了。
147 天前
回复了 barathrum 创建的主题 NAS 到底还是 all in boom 了
尴尬,总是一半就发出去……

如果非常在意的话,可以借鉴风险管理的思维,你能承受的损失有多大,能够接受的恢复周期有多久,由此来制定 rto rpo 策略,进而指导架构的方针。

举个例子,比如我不能接受 all in boom 带来的断网,那就把网络单独拿出来,做个硬件备份,以应对和切换。如果是不能接受存储文件的损失,那就把存储后端独立出来。凡是没有高可用需求的大可放心地集成到一起。
147 天前
回复了 barathrum 创建的主题 NAS 到底还是 all in boom 了
如果非常在意的话,可以借鉴风险管理的思维,你能承受的损失有多大,能够接受的恢复周期有多久,由此来制定 rto rpo 策略,进而指导架构的方针。

举个例子,比如我不能接受 all in boom 带来的断网,那就把网络
147 天前
回复了 barathrum 创建的主题 NAS 到底还是 all in boom 了
备份是个小事情,能不能从备份中恢复才是大事情。
这一套跑起来要多少内存属于常识性问题,不是说那遇到过才知道的。另外企业级代码也要有企业级的运行环境做支撑啊,没有配套的环境谈什么企业级。

不如反过来你尝试回答这样一个问题,这个需求你还能用别的方式熟练的完成么?不能的话那你没得选,能的话说明决策有问题。

比如这个需求 mysql 换成 sqlite 不行么,裸写 sql 不行么,甚至说存自定义格式不行么?既然都是 http 请求加 json 解析,换成 Python 不行么,如果 python 不方便部署,换成 go 之类的不行么。

特别当你知道运行环境就是 1c1g 的时候,更应该考虑这些变通的手段啊。如果换成我的话这个需求我连 self host 都不会用,免费的 cf worker 比你的小主机可用性高太多了。也许你都没考虑过长期维护的事情。这种需求要的是省心,但你现在的选型和实施都没自动化的考量,配置一个简单的 cd/ci 之后这个差距会更大。

说这么多其实是想表达,不要把完成需求仅仅局限在写代码的层面上,当成项目来管理运营会更容易做出整体上更合理的决策。
152 天前
回复了 d0x0b 创建的主题 程序员 我至今仍感到羞愧的代码
大概十多年前约 2013 年前后,我写过很多用于设备追踪和用户识别相关的代码,那个时候收集用户隐私几乎是稀松平常的存在。现在相关的技术一般叫做指纹。

如果现在让我评价,我认为这些代码属于作恶性质的。丝毫没有对用户隐私的尊重,收集的信息数据最终都变成了商品。我有的时候会宽慰自己,即使我不做也有别人去做。这么说确实没错,但是放到十多年后的今天,别人可能只会抱怨环境恶劣,而作为曾经参与其中并推波助澜的一员,我会有种非常微妙的感受,就是恶心别人到头来终究恶心到了自己。

我个人认为在当时我这里“研发”的一些技术属于思想和实现都比较领先的,甚至有些技术在十年后依旧被广泛应用。

随便举个例子,当时大概是 iOS 7 的样子,我这里就在使用 url scheme 去判断用户安装了哪些应用。当然系统是不会提供这样的 api 接口了,让应用可以直接查询到哪些 url scheme 被注册。于是我就把当时软件商店按下载量拉回来主流应用并解包,获得相关的 url scheme 。通过这样的方式,可以在静默的状态下获得已知应用(有注册 url scheme )列表中应用的安装状态。一两年之后,iOS 才对访问 url scheme 的行为增加 UI 提示。

这个方法看起来很粗糙,但是它的思想是很深刻的,实际上行业内普遍应用都是好几年之后的事情了。甚至同样的技术手段,三年前还在用于桌面浏览器的指纹识别,桌面浏览器封堵相关漏洞也是很晚的事情。

说它粗糙是因为在十多年前,使用 url scheme 的应用数量有限,即便如此,十个应用即可获得 10bit 信息,16bit 就足够识别 65536 个用户了,这在当时已经超过了大多数用广告 sdk 的客户的用户数量。(实际的有效信息量会有损失,因为像微信支付宝这样的国民应用基本不具有可辨识度)

说它深刻是因为现如今所有的指纹技术,核心思想都是通过多渠道手段,采集在统计意义上独立的特征信息,大概 32bit 在实际应用中足够非常精准的识别了。当然现如今 app 根本不用这么麻烦,因为它们几乎都是随意采集。
1  2  3  4  5  6  7  8  9  10 ... 12  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1263 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 42ms · UTC 18:05 · PVG 02:05 · LAX 10:05 · JFK 13:05
Developed with CodeLauncher
♥ Do have faith in what you're doing.