V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Ketteiron  ›  全部回复第 1 页 / 共 26 页
回复总数  503
1  2  3  4  5  6  7  8  9  10 ... 26  
笑死了🤣可以评选今年最佳
@Chuckle 这些都可以用中间件实现,我感觉不到太大好处,还丢了类型安全。
当然,没有非常通用的库,对于不同场景下的用例可能需要手搓。
对象和参数就应该是不可变的,装饰器这套隐藏的风险太大,太过依赖"约定大于配置"。

而且这取决于底层用的框架是什么,nestjs 没得选,hono 之类的框架也没得选。

如果不用框架,我觉得显式编程对比装饰器多数情况下代码行数会更少,除非项目/库架构基于对象可变性。
@shakaraka #13 你都用 bun 了,没试过 hono/elysia 之类的框架吗。它们更加激进地采用函数式路由+中间件+RPC ,不使用 FP 去开发会极其别扭。它们的代码库本身也是实用性函数式实践的一个良好示范。
nestjs 等项目依赖装饰器和类来定义结构,而这些较为新颖的框架是 schema 第一,类型第一,函数优先。它们推荐你使用 schema ,配合 prisma/drizzle/kysely 等 ORM 可以得到最良好的体验。
以 drizzle-orm 举例,定义好表结构,使用 drizzle-zod 可以派生出相应类型,例如一个表字段定义为 varchar({ length: 50 }),派生出的 schema 会自动生成 z.string().max(50),其运行时检验保证错误参数绝不会到达 sql 层,并且建议这份 schema 同时应用在前端表单校验和路由参数校验上,而前端使用框架提供的 RPC 获得与后端接口完全一致的类型,类型是框架反射 schema 类型和当前路由返回值提取出来的,不需要开发者重新写一遍,这套做法极致地实现了 DRY 理念,只需定义一份契约,保障全链路的运行时安全和 typescript 类型安全,并且减少了一堆冗余文件。
当使用这些框架去开发,已经没必要再分什么层了,分无可分,直接在路由编写业务代码就行。
而在此之上还有一堆优化空间,多用函数式,理想情况下可以压缩 75%以上代码,并且 bug 更少类型更安全且一致。
当然要践行起来坑也是不少的,例如我正在考虑把 zod 和 drizzle 换成 arktype 和 kysely 。
@dolorain 不用全开一遍,IDEA 装上特定语言的插件就行了,据我所知没有任何区别。
不过除了写 Java 我不会打开 IDEA
@shakaraka #9 差不多这个意思,但它写的例子不对
export async function getUserById(id: string, repo: UserRepo) {
return repo.findById(id);
}
这种做法只是另一种脱裤子放屁的实现

当我们用面向对象思想组织代码,会将变量与函数实现放在 class 中,没有全局作用域的语言必须这么做。
这会导致一个问题,我必须先有一个对象,然后才能调用这个函数,这导致一句著名的话:"你想要得到一根香蕉,但结果却得到了一个拿着香蕉的大猩猩,以及整片丛林",那七八百行就是当前上下文的丛林。

如果换成偏向函数式的 js 来写,import domain/server/repository 等方式是冗余甚至有害的,因为这些对象有着依赖关系。
我通常不会主动创建任何不必要对象,函数只是函数,它们可以有一个主人,例如当前的 js 文件本身,等待其他文件对它进行调用,不需要特地装进一个箱子,或者大中小三个箱子。

像 userService.getUserById() 之类的写法完全没必要,userService 是一个冗余的命名空间
import { getUserById } from '@/xxx/user' 就行
绝大多数情况下分层也是没必要的,这反而加大了业务理解难度
不需要得到这个函数后面的所有隐式依赖对象,简单地得到这个函数本身然后调用它就行
要得到一根香蕉,只需要执行一个能获得一根香蕉的函数。
那么所有的依赖关系就只留在互相调用之中,没必要特地去管,尝试无意义的解耦没有太明显的好处。

一直以来用不用 DI 有争议,我是选择了不使用 DI 的阵营,并且应用于大型项目。
https://stackoverflow.com/questions/9250851/do-i-need-dependency-injection-in-nodejs-or-how-to-deal-with
喜欢 DI 的人会使用面向接口而非面向实现更好这个理由,但我一直认为是坏处,面向函数、面向类型/契约编程,需要编写的代码更少且更安全。
@EscYezi #31 schema 优先的 ts 暂时是不错的选择,没有大量类型传来传去,但还是能够保证严格的类型检查,lint 检查比其他语言强很多。
> 结果光是各种组装和传参就写了七八百行
这就是 nestjs 等框架带来的危害
DI 本质上是倒转依赖方向,由人工处理拓扑结构转为框架底层去处理,而这样的意义是为了方便地把"函数"注入进来,因为函数必须在一个对象中,DI 的思想是为了 OOP 服务的

清醒点,你写的是 js/ts ,你可以在任何时候 import 可复用的函数,无需注入"包罗万象"的对象进来
我一直觉得,js 的依赖注入完全没必要,除非项目整体是用 oop 思想开发的,例如明明写 js/ts 非要搞一堆 class 。

装饰器本质上是高阶函数,或者用 oop 的话来说是元编程,但都一样。

oop 语言渴望函数式,于是它们发明了基于 AOP/动态代理的各种特性,我就不报菜名了,但它们本质上都是同一个东西——高阶函数的仿制品。

go 的 wire 很微妙地处在可用可不用的位置,是由于语言本身的问题。
但是 js/ts 是可以完全不使用 class/装饰器/依赖注入等 oop 专属概念的语言。
你明明提到了函数,但却没把它当一等公民。

我经常听到的依赖注入的优点之一是便于 mock ,这个在 go 是成立的,在 js/ts 是不成立的。
为什么要 mock?是为了暂时排除依赖影响,去测试"函数"是否符合预期,那么对于 ts 来说,请直接测试函数本身。如果有外部依赖必须注入,例如数据库连接池、logger ,用工厂函数。
3 天前
回复了 reavid 创建的主题 Java 能不能别用那烦人的 MyBatis-Plus 了!
这段代码确实很垃圾,明明一行链式就搞定。
mybatis-plus 我觉得没什么问题,在复杂动态条件拼接与类型安全上远胜 xml 。
但受困于 java 的表达能力,写起来确实有点折磨。
只能尽量不使用闭源脚本。但是开源脚本同样存在潜在风险,并不能知道开发者什么时候把号卖了。
说白了,还是免费插件本身无法给开发者带来稳定利益,那么被人买走投毒很正常,我觉得根源上就没法解决。
4 天前
回复了 miscnote 创建的主题 程序员 node.sql 咨询
有的,这叫 BAAS ,数据库即服务,可以看看 postgrest 。
创建一张表就自动生成这张表的 CURD 接口,通过编写 sql 来编写服务。理念是好的,但写起来不比重新学一门编程语言好多少。
@shendaowu #8 别考虑太多,随便哪个都能用。
世界上最强大、使用人数最多的标签系统,莫过于 ehentai 附带的标签系统
早在十多年前它就支持各种复杂查询
https://ehwiki.org/wiki/Gallery_Searching
php+mysql5 都能撑得起全世界的流量,技术、架构无足轻重,先付诸想法才最重要

而且你整天问 deepseek 怕是对技术提升没有多大帮助,deepseek 基本上只会顺着你的话瞎编,你的任何预设都会成为它的边界
你发的这几个 deepseek 分享链接要么充满正确的废话,要么在瞎编,对于你写代码没有任何帮助

我简单说一点,就算你有三百万个标签,支持所有复杂组合查询(命名空间、与或非、精确/模糊匹配),就算用 mysql 也没关系,你先找到六位数以上的用户再说。
9 天前
回复了 Asakijz 创建的主题 问与答 115 网盘是不支持增量下载吗?
偷懒。
一些网盘下载时如果有同名文件夹会重建一个新的文件夹 (2) (3) (...)
实际上只需要比较一下本地文件哈希过滤一下下载项就行了
可能是后端懒得改前端也懒得改,或者这需求内部重来没人提过,也可能提过但不当一回事,毕竟他们不使用自己编写的产品。
可能会更加深入地探索软件世界,但这并不是优势,反而可能会耗费更多的时间精力,娱乐时间变少了
@shendaowu #3 如果是单标签,b-tree 可能会比 GIN 快,但取多标签交集复合索引需要多次索引扫描,GIN 只是位运算会快很多,千万量级配合 intarray 只需要几毫秒。如果数据量太少,可能会走全表扫描。另外不知道你是否使用了 intarray 。
GIN 比 RBM 稍慢,原因是 GIN 支持事务一致性。RBM 适合复杂查询,例如 (Tag A OR Tag B) AND (Tag C) AND NOT (Tag D)。如果你的测试只是 count(*) 的话是不公平的,少掉了回表。
如果想要根据 Bitmap 里的内容来过滤行,会碰到这个问题:
https://github.com/ChenHuajun/pg_roaringbitmap/issues/36
RBM 还有个问题,如果标签太多了,如果标签还支持打分、顶/踩,写操作会成为瓶颈。

综合比较的话,RBM 用算法换来了极致的读取速度,适合用在复杂读多、写少的场景
其余场景用 GIN 更好
过度设计(或更可能是错误设计)。deepseek 没有理解标签搜索是倒排,当然很大程度上被你的第一个提问给误导了。

tag_content_bitmaps 这是倒排索引
content_tag_bitmaps 这是正排索引
你打算通过高频标签 ID 映射解决性能问题,但表一的性能几乎没有改进,影响表一查询的是 content_bitmap 之中的 content_id ,与 tag_id 无关;优化表二没有实际意义。比较有意义的优化,可能是保证 content_id 得是连续的。

性能上限由数据结构决定,如果你想要真正高的性能,需要为特定量级和场景重新设计结构和算法。
为什么要用 roaringbitmap ?因为可以节省下处理高频低频的开发时间拿去做别的事,我觉得你的问题是 XY 问题。

如何保证 ID 映射表的缓存一致性,当一个标签从高频变低频或者反过来,需要迁移数据吗,我觉得你还没想过这些问题。

看了下过往帖子,你应该用 GIN 。先别幻想"如何优化亿级数据",先把你的程序跑起来。
10 天前
回复了 chevalier 创建的主题 程序员 一夜之间回归古法手工编程
@sankooc 离谱,因废噎食,人会出错干脆严禁人类程序员
1  2  3  4  5  6  7  8  9  10 ... 26  
关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   775 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 37ms · UTC 21:12 · PVG 05:12 · LAX 13:12 · JFK 16:12
♥ Do have faith in what you're doing.