V2EX kuanat 的所有回复 第 1 页 / 共 17 页
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX    kuanat    全部回复第 1 页 / 共 17 页
回复总数  335
1  2  3  4  5  6  7  8  9  10 ... 17  
@oblax #31

x390 不知道你说的哪一代,无论是整机功耗还有电池容量,和现在的机器都没法比了。

只有比较新的平台( 7nm 之后)才能做到我说的效果,最起码进入待机之后要在 0.5w 以内,这样才能做到 60Wh 常规容量还能待机比较长。之前 14/22 工艺的平台,cpu 可能待机不会差太多,但是主板等外围设备进入低功耗状态之后耗电太高了。这里主要是强调平台要新,比如 intel 12/13 代移动版 cpu 能效比很差,但不妨碍这些平台的笔记本盒盖待机依然能有很长时间。
是不是该用跨平台框架来写 ui 是个哲学问题,即便你的立场为是,还是要继续抉择,要每个平台都用相同的(非原生风格)自定义 ui ,还是要每个平台上用原生的 ui 。基本上后者都是走浏览器了,因为没人或者团队能承担得起这样的维护成本。

在跨平台、自绘 ui 这个场景中,本质上要看在各个平台上底层用的什么 api ,楼上有人提到 go 的 goroutine 与系统线程 pinning 相关的硬伤,个确实无解,因为现在的操作系统都是同样的 ui 线程逻辑。

这种项目最大的困难是长期稳定地维护下去。而且通常来说好看、小巧和兼容性强是不可兼得的。以 win 为例,想要小就必然对接 win32 api ,用这个写现代界面,光一个 dpi 自适应就头大。到了 linux 又会面临是 gtk/qt 还是协议层造轮子,qt 因为授权大部分时间会被排除在外,如果是直接 wayland 协议开始写,且不说什么消息循环都要手动,就天天跟着上游更新都是很大的工程量。

当然如果写的项目不需要长期维护,这类 ui 框架还是很有市场的。
64g 内存是个不太好达成的条件,多数都要上顶配或者定制款,加上 16 寸也是个小众品类,能选的不多。

我是 16 寸 linux 多年的用户了,按照条件来匹配的话,thinkbook 16+ 是符合预算的,插槽内存,而且我确认主流新版本 linux 是开箱即用的,包括指纹这种设备都正常。发售的时候 libinput 没更新 quirks 会用不了触摸板,现在没问题了。

另外我说几个不太容易注意的点,现在大多数设计上看上去比较好的笔记本,都为了减重或者造型选择了 oled 屏幕。作为开发者来说,我更推荐 lcd 的型号,主要是 oled 的防烧屏功能 linux 基本上不可用。

另外你是 mac 用户过来的,肯定习惯了高 dpi 屏幕。我是更建议分辨率在 3200x2000 即整数缩放 1600x1000 以上的,因为 linux 生态的问题,分数缩放并没有那么理想。2880x1800 也可以接受,但 1440 水平有效宽度很多时候对于开发来说不够用,如果是前端这个问题会更明显。

之前我在别的帖子里回复过如何用 live usb 安装盘配合 来测试 linux 兼容性 https://v2ex.com/t/1128164
这个话题站里出现过挺多次了,我之前大概说过结论,越公版设计越稳定,intel 集显型号比较容易达成。

Windows 是不是有什么负优化我不知道,至少我个人用 linux 来说,从 2011 年之后我手上的笔记本就是随用随开,modern standby 或者叫 s0ix 待机,满电可以稳定一周以上,从来没有过放包里异常发热的情况。

这个主要是看硬件平台,前些年 intel evo 认证的几乎都可以,现在这个东西也没了。
这个话题属于懂行的不愿意讲(毕竟多数都会涉及黑灰产),而不懂的基本说不到重点的那种。我就简单总结下算是抛砖引玉了。

浏览器从来都不是可信环境,理论上没有任何办法可以稳定 100% 准确区分真人和机器。

对抗爬虫或者 bot 的基本思路就是提高攻击成本。比如登录之后才能看的,就有帐号成本,限制访问频率的,就有 ip 成本,甚至 cf 五秒盾也可以理解为采集时间成本。

想要提高攻击者的成本,那防御方也要付出代价,比如设想个极端场景,防御方要求所有请求都过一遍 recaptcha ,那防御方确实提高了攻击方的打码成本,但自己也付出了带宽成本,以及造成不便损失正常客户的成本。所以防御方更希望的是,有纯软件的方案,只付出开发成本和少量的运营成本,就能大幅提高攻击者成本的方法。于是就有了各种检测技术。

我这里随便列举一些常见的技术,以及攻击方的应对策略:

1. tls 指纹检测

因为浏览器和常见 python/go 等编程语言的底层 tls 库是不一样的,通过在流量入口做 ssl offloading 的时候,顺便检测一下请求中的 kex (密钥交互)配置,就能起到很好的筛选作用。

应对方式也比较简单,替换 tls 库或者伪装成特定的指纹配置即可。

2. 额外校验字段

同样是针对看请求直接构造接口数据的。在常规业务字段之外增加校验字段,一般由 js 代码执行后产生。

这种可以通过 cdp 控制浏览器或者跑无头等方式绕过。

3. 浏览器环境检测

基本上是前一种方法的增强版。既然攻击者能用真浏览器来伪装,那就检测那些不合理的参数,比如窗口 viewport 大小,一些特定的全局对象等等。到了这一步,基本上标配都是 js 混淆了。

对于水平不高的检测,有经验的攻击者大部分能根据调用栈定位到关键函数方法,绕开检测逻辑直接生成校验字段。

4. js vmp 混淆

基本上这就是最后的防线。把前面各种检测技术打包起来放到 js 中,然后用 js 代码写个虚拟机,再把原始的代码编译成虚拟机指令。这个对抗手段是针对人的,就是拉高对攻击者的技术门槛要求,逆向 vmp 类混淆是要比前面都难的。

从攻击者的角度来看,硬怼 vmp 还原 ast 指令也不是不行,就是累,而且没办法保证这次逆向出来了能用多久。毕竟防守方的策略是,换个混淆参数就是新虚拟机了。

所以多数情况下都是把 js 代码完整扒出来,把它当黑盒来调用。因为外部 js 环境和浏览器不一样,缺少浏览器的很多对象,所以有个专门的说法叫“补环境”,让 js 代码能正常运行。想要知道 js 代码都检测了哪些环境信息,又有一些插桩、自吐的应对策略。

就算实在搞不定,专门搞一个浏览器,就真实地跑校验字段生成,然后把结果给其他自动化的部分用也可以。


大致上就是这样了。对抗的路线最终都会转换成为“对抗成本”的问题。而且从技术原理上说,攻击方是永远可以看到代码的(尽管可能是混淆版本),所以根本藏不住。
https://pkg.go.dev/log/slog@master#example-LogValuer-Secret

这是 golang slog 官方示例写法,和一楼给的思路是一样的。需要通用性做成接口就好了。
@liyafe1997 #5

感谢指正,我确实说错了。
这里用技术语言来描述:S0 正常状态,S3 睡眠(持久化到内存),S4 休眠(持久化到硬盘)。

原始问题是,S3->S4 ,中间要经过 S0 吗?技术层面答案是要,但一般语境中认为不需要。操作系统在进入 S3 的时候,会注册一个目标时长的 wake event 回调,即特定时长之后转睡眠。当硬件到达特定时间点,就会 S3->S0 ,此时操作系统会检查唤醒原因,如果是用户的操作,那就继续完全恢复至 S0 ,如果是自己注册的睡眠回调,那就在只唤醒硬盘等必要设备,然后完成休眠准备进入 S4 。

排查故障先看是否能手动进入休眠,很多支持 Modern Standby 的新设备都不支持休眠了。

如果能手动休眠,大概率是 bios 问题,可以反编译 acpi 看哪里出了问题。
17 天前
回复了 kuanat 创建的主题 Zed Zed Linux vim 模式输入法切换
unbind key 的语法类似于

```
[
{
"context": "Editor",
"bindings": {
"ctrl-space": null,
}
}
]
```

回复里可能排版不正常,你可以看一下默认 key bindings 的写法,context 是上下文状态,将对应按键设置成 null 就可以。


插件我没有做,执行 `fcitx5-remote -s keyboard-us` 切换是很容易的,官方扩展 api 里面有个 process 模块。但是没有一个好的切入点让这个插件版的命令在 vim 退出插入模式的时候自动执行,最后还要回到 task 上面来。跟我这个方案没别。

另外 zed 在某个版本之后修改了底层 key handling 的逻辑,比较接近 DirectX 这样从底层取按键状态,而不是取窗口管理器传递的按键消息,所以对输入法造成了很大影响,特别是在 pre-edit 状态下,输入法和 zed 本身在按键处理上可能产生混乱。开发者明显是不懂 ime 的,所以 cjk 用户提的方案很难被接受,尽管开发者很努力地尝试理解,但在这个底层处理机制之上做修改还是太难了。现在什么情况我不太清楚。
实践中所有这种需求场景几乎都采用人工复核的方式,倒不是因为人一定对,而是因为人可以担责。如果你的方案里要求去掉人,那这个问题就无解,除非你能为出错的数据兜底。你能兜底的程度越低,相应的置信度阈值就要拉得越高,实践中能够自动化识别的样本比例就越低。

另外单据 ocr 识别是个多少年的需求了,做这个的外包公司或者团队怕不是遍地走。这事根本没必要上大模型,传统 ocr 算法完全够用。

各种 ocr 算法方案在归一化之后的性能表现差距很小。差别大的方面是,在没有前置信息的情况下,先识别出哪里有文字,字符间如何分隔,以及判断文字可能的语言的阶段,以及整体的识别速度。

对 2000 年前后基于传统算法的方案来说,ocr 识别能力属于有多少人工就有多少智能的水平。只要是标准化印刷单据加手写的识别场景,几乎都可以暴力解决。算法判定不准文字位置、字符集,但是人知道啊,提前对单据照片或者扫描图进行畸形校正、裁切和二值化,再把手写的部分抠出来切分,最后只把识别的过程交给 ocr 。这个流程差不多是过去 20 年最主要的方案,基本上只看你归一化做得是不是细致。据我了解有些团队做久了,积攒下几千种不同的单据模板。

2010 年之后 ocr 算法过渡到了 cnn 为主,但相对于之前的暴力解法来说,没什么差别。原来甲方用了 ocr 还是要有个人负责复核,现在一样需要这个人,就算用上了什么大模型,即便出错概率极低,还是需要一个人来兜底。
如果是同一个语言的微服务,最起码还可以直接引入代码。如果是不同语言的项目混用,那几乎就只有 dsl 代码生成这一条路了。

抽象出来 common 包存放数据结构之类的定义,这个思路是对的。我大概几年前也经历过类似改造,尽管项目本身不大,但这个过程挺痛苦的,因为这个改造看的其实是自动化的水平。

我印象当时选定的方案是 git submodules ,因为这个功能在之前的工作流中几乎用不到,还专门开会做团队培训……然后是几个人花了几天抽象了一个公共数据结构定义,写了个 common 包,准备一个一个微服务重构。

这个过程中发现的各种不一致的 bug 就不提了,最大的障碍是没人敢直接用新实现替代旧的版本,尽管初期改的几个包都是挑的代码少的软柿子。而且 submodules 方案也增加了开发人员的心智负担,因为一般的特性分支工作流,需要经常在维护旧代码和开发新功能上来回切换,用 submodules 就要注意每个分支和 common 依赖版本的对应。最后是自动化运维的部门出了大力,在生产环境做了个流量镜像,复制了一部分请求到新版本部署的测试服务器上,然后看执行结果和原版是否一致。

在这之后又增加了一个人为规定,就是所有项目 repo 都必须包含构建脚本,其实就是几个 hooks 检查 submodules 是否更新或者版本对应正确。因为我们用的是特性分支工作流,只要核心的 master/dev/staging 几个分支提前做好与 common 分支的对应(技术上是对应到 commit ),common 的更新就可以通过特性分支简单合并到每个项目中,实现由上至下的传播,开发人员只要知道在当前项目的哪个分支上工作即可,不需要关心依赖的手动更新。

这样改完了效果还是挺明显的,没有各种重复、不一致的定义,ide 补全也可用。只是增加管理成本,特别是负责 common 维护的。因为基础数据结构的改变,可能影响 API ,还可能影响 ABI ,即便是结构体增加一个字段,都有可能不兼容。同时 common 的改动要伴随所有微服务模块的改动,测试一定要跟得上才行。

至于常量的部分,我认为需要根据常量本身来区分。如果是那种界面上的文字肯定是放到直接使用的包比较好,剩下大部分常量,比如服务器地址这些,我认为还是在环境变量中设置比较好。体现到项目中就是 dotenv 这种,环境不同设置也不同。这个方案需要额外处理两个细节,一个是如何集中管理或者持久化,二是一些类似密钥的不适合用明文的要如何处理。

对于单语言项目,简化处理可以用公共 constant 包,对于多语言项目来说,一般是集中定义,然后通过 sed 之类的工具在源码级别上做替换。
我的话一般会停止服务,不过这个行为取决于备份粒度。一般来说我不会把很多服务的数据放在一起备份,而是单独处理。

从应用或者服务的层面看,大多数写入行为都是非同步的,像数据库一般会设计成 WAL 同步写,主库带缓冲的形式,暂停服务可以降低不一致的“来源”。

如果备份行为是复制,还要多考虑同一批文件由于备份这个行为的造成的时间差异,这也是不一致(匹配)的来源。如果是在 CoW 系统上,先创建快照,再将快照持久化备份会好一些。

当然这个事情还是看需求场景,只是一般来说,维护一个高可用系统的备份和恢复机制更麻烦一些,停止备份再恢复相对来说更容易自动化。
@codehz #8 感谢解释。

我这边检查了一下,是我之前拦截了对 localhost 的访问,我还以为之前的 PNA 通过了呢。

我又回头确认了一遍,RCE 是两部分共同实现的,通过 api 控制是 POST/json ,本身是需要跨域的,但 clash 默认允许……第二个漏洞是配置项在 unmarshalling 的时候,解析的路径没有检查就直接使用,所以可以下载任意文件并执行。
现在 chrome/firefox 应该都会默认阻止对 localhost 端口的非直接访问,这个第一步应该就执行不下去。
我之前在关于 go 的一些帖子里提到过一个观点,因为 go 的依赖注入太普遍,也太简单了,所以 go 的依赖注入“框架”是非常不流行的。而 google/wire 也不是其他语言一般意义上的依赖注入框架,更准确地说它是自动生成初始化代码的框架,解决的是自动化的需求问题,而非解决注入依赖的问题。还有一个原因是,go 语言提倡显式控制流,所以类似 try...catch 的跳转机制,包括基于中心注册的注入依赖框架(通过运行时反射匹配),都不容易被 go 社区接受。

造成这种现象的更深层的原因,我认为在于 go 对于面向对象的抽象有两个重要的思想转变,一个是接口由需求方定义,另一个是用组合代替继承。前者就是所谓的 duck typing ,实现接口并不需要显式声明,后者是 struct embedding/receiver method ,两者结合,go 可以用极其简单的方式实现 mock 功能以及对第三方代码的复用。

作为对比,Java/C# 在设计思想上还停留在供给方定义接口的层面上,而需求方通常又不会主动 fork 修改供给方的代码,所以要“实现”一个接口,往往是通过所谓的适配器 Adapter 模式。相比于 struct embedding ,这种适配器模式尽管达到了在不修改第三方代码的前提下“实现”接口的目的,但它要求适配器要持有原始类的实例对象。

如果是 1:1 的接口转换,这种模式还勉强够用,如果是比较复杂的接口转换场景,receiver method 的优势就体现出来了,既可以对自定义的结构增加实例方法,也可以通过别名对第三方或者内置类型添加方法。C# 为此增加了 Extension Methods ,使得它能做到和 go 一样的效果。但是 Java 是没有办法在不修改代码的前提下,为已有类型添加方法的。

所以你会看到 Java 生态中,大部分的供应者在编写代码时,会首先编写接口,毕竟测试与 Mock 场景极其依赖接口。同时适配器模式不是复用数据结构,而是间接持有实例,所以会导致需要管理(相对于 go )更多的对象实例。于是,很多大型项目会直接使用 mocking 框架来简化对于大量实例的管理。由此可以看出,go 多数时间是只需要管理自己编写的(或者封装的)实例的,这极大简化了开发者的心智负担,也减少了对使用工具管理实例的需求。

这种对于大量对象的管理需求,才是依赖注入框架的意义所在。对于实例的管理,除了初始化构造,还包括生命周期。现在无论让谁来设计一套通用的依赖注入框架,它对于对象实例本身的管理一定是全局的,也就有了所谓的 DI 容器,另一方面它对于对象实例声明周期的管理一定是隐式的,开发者可以声明 transient/scoped/singleton 之类的意图,但框架并不允许开发者自己手动管理。

回到 go 的生态来看,一方面既没有管理那么多对象实例的需求,另一方面也不提倡隐式控制流,加上 go 生态中显式传递 context 是事实上的标准,所以 DI 的存在空间就非常小了。如果非要在 go 中实现依赖注入,就好比手持锤子看什么都是钉子,解决一个不存在的问题。
我也是常年只用 wm 而不用 de 的,但事实求是地说,wm 和 de 之间的差距还是挺大的。

这几天讨论 linux 桌面的帖子里,我感觉用户分化的主因是心态,而不是技术方案。能接受的人看重的是 linux 的长处,发挥优势。不能接受的人看重的是全面,不能有短板。所以接受不了 linux 就更接受不了 wm 。
我用过一段时间的 plantuml ,不过画架构图的话元素定位比较蛋疼,各种隐藏线,还控制不准。

蹲个解决方案。
119 天前
回复了 wuruxu 创建的主题 Linux zed 这个编辑器值得关注
站里有 zed 节点,不过讨论不多。

现在有几个项目在用它的 gui ,印象还有国人开发的。

https://v2ex.com/t/1056672 这个帖子里我有比较详细的评论。
我用了四五年了,作者 dnkl 的其他项目也都很优秀。

我感觉作者对于很多底层技术了解非常透彻,随便列举一下 foot 的优秀之处:

- 基于作者自己开发的 fcft 做文字渲染,fcft 的代码也非常值得一看,简单、可靠

- 基于 damage tracking 的渲染架构,速度和很多基于 gpu 实时渲染的不相上下

- 正确实现控制序列,支持 kitty keyboard 协议,主要是用于正确传递键盘事件,比如 gui->vte->multiplexer->app ,另外就是支持 OSC52 远程复制之类的指令,做 shell 交互集成

- 正确实现 wayland 分数缩放协议,text-input-v3 输入法协议

上面随便拿出来一条能做好了都非常难得。

另外还有一些可能不属于技术,但符合我技术审美的选择:

- ini 风格的配置文件

- server/client 架构的 daemon 模式

- 自带自身的 bash/zsh/fish 补全

- 很少见做对了 alpha blending (虽然方式是基于 hsl 转换)



PS

关于 alpha blending 解释:

这个过程几乎无处不在,但是由于历史遗留问题,加上又是基础组件中的实现,所以直到今天都存在大量且普遍的错误实现。

由于人眼对于暗部比亮部更敏感的特性,sRGB 之类的色彩空间是经过 gamma 矫正的,更多的编码精度留给了暗部。所以对 sRGB 来说,数值翻倍不代表亮度翻倍。所谓 alpha blending 就是模拟真实世界中光线混合,在一个背景色上显示一个前景色文字的过程,需要先将 gamma 矫正过的 sRGB 还原为线性空间,两种颜色在线性空间中混合之后,重新映射回 sRGB 空间来渲染。

如果 vte 或者其他任何应用不能正确处理 alpha blending 很容易出现混合区域变暗的情况,这一点在字符光栅化抗锯齿方面提现很明显。对于 vte 类应用可以观察一下在各种配色主题下的表现。
Fedora 也把 kde 从 spin 提升至和 gnome 版一样的官方支持的 edition 了。

我很好奇,有没有人现身说法一下日常使用 freebsd 是什么体验,毕竟相比 linux 生态还是弱了点。
1  2  3  4  5  6  7  8  9  10 ... 17  
关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1051 人在线   最高记录 6679       Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 35ms UTC 23:03 PVG 07:03 LAX 16:03 JFK 19:03
Do have faith in what you're doing.
ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86