V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 34 页 / 共 60 页
回复总数  1200
1 ... 30  31  32  33  34  35  36  37  38  39 ... 60  
2022-07-21 19:40:11 +08:00
回复了 wenjie0032 创建的主题 Go 编程语言 Gopher 我们一起来造个 ORM 吧!
我不信有哪个比我这个 rawsql 好用:
https://github.com/lesismal/sqlw

@join 试试我这个
2022-07-12 12:20:42 +08:00
回复了 JoseGuo 创建的主题 Redis 有一个 Redis 通知的问题想问一下大家
redis 通知是存在的问题,比如通知的瞬间,刚好你监听事件的这个服务与 redis 断线了、没收到通知。
时间+定时任务判断处理订单状态就行了。

这里的时间与隔壁帖子根据当前时间计算当前体力、而不是定时去计算更新增加后的体力的玩法其实是类似的。
可以考虑记下这个词:COW(copy on write),其实本质就是只在真正需要的时候才去触发实际操作、尽量减少成本的浪费。
2022-07-09 11:30:42 +08:00
回复了 guanqian 创建的主题 程序员 写了一篇 KCP 的协议分析, 求老哥们点 star
赞了
2022-07-08 23:02:24 +08:00
回复了 vvhhaaattt 创建的主题 Go 编程语言 fmt.Sprintf 方法的%q 是否可以防止 mysql 注入?
标准库应该是默认对 query string 做了 Prepare 的,所以预期 Sprintf 拼接,还是不如都使用 place holder 来避免比较好。
我新搞的 sqlw 就没像 sqlx 那样去支持一些 query 配合 Named() 的解析,保持最简单、最实用的东西,其他那些华而不实的花哨,能少整就少整
2022-07-07 20:28:25 +08:00
回复了 yousabuk 创建的主题 京东 京东上全是二手商品啊,他妈的……
小明娶了小红,因为 x 国 x 教育落后,二人知识匮乏,结婚三年了也一直没怎么深入交流过。偶尔有次去体检,体检结果暗示媳妇竟然已经不是处了。。。
2022-07-07 11:17:05 +08:00
回复了 gowk 创建的主题 程序员 用 Go 开发公司内部的业务系统,后端该如何选型?
@gowk web 的话,可能众人用 http 的多、ws 的少,如果考虑技术栈与职业发展,用 echo gin fiber 那些都可以,如果不考虑自己技术栈与社区、未来面试的匹配,arpc 应该是一把梭能处理各种业务,tcp/http/ws/kcp 之类的都可以,但是后端只支持了 go 、前端支支持 js http/ws ,自己精力有限,这也是个局限。。。
对于 sql ,go 的 ORM 和其他 rawsql 确实太难用了,所以我才搞了 sqlw 简化所有。。。
2022-07-06 10:43:03 +08:00
回复了 gowk 创建的主题 程序员 用 Go 开发公司内部的业务系统,后端该如何选型?
得嘞,明珠暗投,祝 OP 好运
2022-07-05 12:00:03 +08:00
回复了 gowk 创建的主题 程序员 用 Go 开发公司内部的业务系统,后端该如何选型?
@licoycn #44
同学,求 orm 使用者试玩我的 sqlw 一下给个体验反馈。
另外对于协程池,我这里有份 benchmark 请查收,包括标准库、ants 、字节的、我自己的库里带的,可以在自己机器上 linux 系统跑下试试不同的 cpu:

```sh
# sleep 0ns
ubuntu@ubuntu:~/test$ go test -v -bench=.
goos: linux
goarch: amd64
pkg: test
cpu: AMD Ryzen 7 5800H with Radeon Graphics
BenchmarkGo
BenchmarkGo-8 6322 178909 ns/op 16413 B/op 1025 allocs/op
BenchmarkBytedanceGopool
BenchmarkBytedanceGopool-8 2714 427975 ns/op 39506 B/op 2045 allocs/op
BenchmarkAnts
BenchmarkAnts-8 3746 315216 ns/op 16418 B/op 1025 allocs/op
BenchmarkMixedPool
BenchmarkMixedPool-8 4759 253604 ns/op 49168 B/op 3073 allocs/op
PASS
ok test 4.821s

# sleep 10ns
ubuntu@ubuntu:~/test$ go version
go version go1.18 linux/amd64
ubuntu@ubuntu:~/test$ go version
go version go1.18 linux/amd64
ubuntu@ubuntu:~/test$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.6 LTS
Release: 18.04
Codename: bionic
ubuntu@ubuntu:~/test$ go test -bench=. -v
goos: linux
goarch: amd64
pkg: test
cpu: AMD Ryzen 7 5800H with Radeon Graphics
BenchmarkGo
BenchmarkGo-8 4406 274001 ns/op 98522 B/op 2051 allocs/op
BenchmarkBytedanceGopool
BenchmarkBytedanceGopool-8 2404 486601 ns/op 55419 B/op 2212 allocs/op
BenchmarkAnts
BenchmarkAnts-8 3147 396720 ns/op 16437 B/op 1025 allocs/op
BenchmarkMixedPool
BenchmarkMixedPool-8 3530 346933 ns/op 131111 B/op 4097 allocs/op
PASS
ok test 5.021s
```

```golang
package test

import (
"sync"
"testing"
"time"

"github.com/bytedance/gopkg/util/gopool"
"github.com/lesismal/nbio/taskpool"
"github.com/panjf2000/ants/v2"
)

const testLoopNum = 1024
const sleepTime = time.Nanosecond * 0

func BenchmarkGo(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
wg := sync.WaitGroup{}
wg.Add(testLoopNum)
for j := 0; j < testLoopNum; j++ {
go func() {
if sleepTime > 0 {
time.Sleep(sleepTime)
}
wg.Done()
}()
}
wg.Wait()
}
}

func BenchmarkBytedanceGopool(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
wg := sync.WaitGroup{}
wg.Add(testLoopNum)
for j := 0; j < testLoopNum; j++ {
gopool.Go(func() {
if sleepTime > 0 {
time.Sleep(sleepTime)
}
wg.Done()
})
}
wg.Wait()
}
}

func BenchmarkAnts(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
wg := sync.WaitGroup{}
wg.Add(testLoopNum)
for j := 0; j < testLoopNum; j++ {
ants.Submit(func() {
if sleepTime > 0 {
time.Sleep(sleepTime)
}
wg.Done()
})
}
wg.Wait()
}
}

func BenchmarkMixedPool(b *testing.B) {
p := taskpool.NewMixedPool(1024*4, 1, 1024)
defer p.Stop()

b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
wg := sync.WaitGroup{}
wg.Add(testLoopNum)
for j := 0; j < testLoopNum; j++ {
p.Go(func() {
if sleepTime > 0 {
time.Sleep(sleepTime)
}
wg.Done()
})
}
wg.Wait()
}
}
```
2022-07-05 11:45:35 +08:00
回复了 gowk 创建的主题 程序员 用 Go 开发公司内部的业务系统,后端该如何选型?
@BeijingBaby
非常同意,那些搞了一大套微服务的各种、或者集成 ORM 之类的,都是适合他们自家业务而已。而且很多集成别人的库的项目,说句不好听的,都不应该叫框架
2022-07-05 11:34:53 +08:00
回复了 gowk 创建的主题 程序员 用 Go 开发公司内部的业务系统,后端该如何选型?
@gowk #55
sqlw

OP 你瞅一眼试一下,还有比我这个好用的吗。。。

```golang
result, err := db.Insert("insert into sqlw_test.sqlw_test", &m)
if err != nil {
log.Panic(err)
}

result, err := db.Delete("delete from sqlw_test.sqlw_test where id=?", deleteId)
if err != nil {
log.Panic(err)
}

m := Model{
I: 1,
S: "str_1",
}
updateId := 1
result, err := db.Update("update sqlw_test.sqlw_test set i=?, s=? where id=?", &m, updateId)
if err != nil {
log.Panic(err)
}

var model Model
selectId := 1
result, err := db.Select(&model, "select * from sqlw_test.sqlw_test where id=?", selectId)
// result, err := db.SelectOne(&model, "select (i,s) from sqlw_test.sqlw_test where id=?", selectId) // select some fields
if err != nil {
log.Panic(err)
}

var models []*Model // type []Model is also fine
result, err = db.Select(&models, "select * from sqlw_test.sqlw_test")
// result, err = db.SelectOne(&models, "select (i,s) from sqlw_test.sqlw_test") // select some fields
if err != nil {
log.Panic(err)
}
```
2022-07-04 19:35:53 +08:00
回复了 gowk 创建的主题 程序员 用 Go 开发公司内部的业务系统,后端该如何选型?
直接用我出品的库吧,用 RPC 的接口方式交互,既支持普通的 HTTP RPC CALL 请求,也支持 Websocket 长连接 RPC CALL ,可以 Server 端主推送,中间件都可以定制,协议交互的各种业务类型都方便支持:
github.com/lesismal/arpc
web 的例子看这里:
github.com/lesismal/arpc/tree/master/examples/webchat

数据库也用我这个,比什么 ORM 或者其他的 RawSql 库都简单易用方便得很(隔壁帖子前阵子刚有人喷 go 的 ORM 呢):
github.com/lesismal/sqlw
例子看这里:
github.com/lesismal/sqlw_examples
前几天刚发过帖子:
www.v2ex.com/t/861739

不要以为 star 少不好用,那是因为做得晚、现在几个国内 go 站长都忙着卖课程挣钱所以论坛没人看了推广不起来、我也不屑于去加那些互相捧臭脚的技术饭圈,有不少项目 KPI 搞假玩意忽悠人呢、氛围太恶心

吹个牛说,我提供的都是最强方案,如果哪位不服,来看看试用下欢迎来跟我 battle 。
2022-06-27 16:41:46 +08:00
回复了 oyp 创建的主题 程序员 在 jQuery 环境下,怎么开发 SPA 应用程序,怎么配置路由?
试试我这个:
github.com/lesismal/pmjs

本人非专业前端,主要原理就是多个页面共存,当前显示谁就把 i 其他的隐藏,纯原生、如果你控场能力强、性能可以做到最强。
代码也不多,有需要的话 OP 可以随便改。
2022-06-27 12:21:04 +08:00
回复了 F4NNIU 创建的主题 程序员 你为什么做开源软件?
为了日常能使用简单方便又高性能的框架,为了去解决实际的工程问题,为了给自己留个念想

1. 除了性能高,这可比其他只有 RPC 功能的 RPC 框架好用太多了,缺点是只支持 go/js ,精力有限,照顾不到太多语言
https://github.com/lesismal/arpc
2. go 全网唯一支持 tls/http1.x/websocket 的 poller 网络框架,底层异步,应用层仍然同步,基本兼容标准库,方便与其他知名库结合比如 gin/echo ,性能>=目前已知的同类 poller 库
https://github.com/lesismal/nbio
3. 这几天刚造的,标准库的 sql 确实大道至简但应用层被迫繁冗,而且市面上的所有 go ORM 和 rawsql 库都没能达到我对简洁的定义的标准:
https://github.com/lesismal/sqlw

有兴趣的同学欢迎看我历史主题
@lesismal #31

"Select/Delete 都只是 Query/Exec 的简单封装"
——这里的 Select 简单封装是只 sqlw.Select 是对 sqlw.Query 的封装,不是指对标准库的简单封装
2022-06-27 12:07:44 +08:00
回复了 fstar 创建的主题 程序员 如何看待封闭开发?
钱到位的话可以,多少算到位自己衡量。
当年史玉柱做《征途》好像就搞封闭开发,他的兄弟们也都跟着发达了。
但现在时代变了,这种机会很少了,不行就 Move 甚至 Run 。
@yiplee 其实最开始只是想把 Query 做下映射的、免去了 for rows.Next scan 的麻烦,但是自己写点示例的时候使用 Exec 还是不够方便,所以这两天又加了其他三个
@yiplee
使用 Query/Exec 可以实现所有操作,毕竟标准库就是这样的。

Select/Delete 都只是 Query/Exec 的简单封装,主要是为了用户层使用时的语义更加明了,Insert/Update 同样也可以更明了一些。

单独提供 Update 的另一个原因,是由于直接使用 Exec 不知道是增删改查哪种操作,所以不方便处理结构体与 sql 字段的映射,比如 Exec 的方式我用当前的一个 Model Obj 字段去 Update ,还是得像标准库一样把 Obj 每个字段都列出来,而现在可以只传一个 Obj 。如果是想把 Exec 也支持结构体映射,则需要再去做一层 sql 语句类型判断,一是又多浪费了一点性能二是复杂语句判断逻辑实现起来也吃力,比如 select for update 、多条语句全都有之类的,所以单独提供了 Update ,复杂的需求才去用 Exec 。

总结下来就是 业务层更简洁明了+降低实现复杂度。
@yiplee
sqlc 用着还是有点麻烦的,我昨天更了一版直接增删改查也都提供了,应该是比 sqlc/sqlx 省事多了,不信你看下。。。
github.com/lesismal/sqlw
@liaohongxing 想了下,还是不应该自动 Rollback ,比如一个事务多个语句,其中一个语句 duplicate key 了,但是业务层自己会判断 duplicate key 并继续执行事务其他逻辑,如果框架自动判断 err 回滚了,业务层就没法继续了
@liaohongxing 也可以做自动 Rollback ,sqlw.Tx 再把 sql.Tx 的 Exec 包装一道,然后 Query/Exec 里都先判断下 sql.Tx 执行是否有 err ,有就回滚。但是这样的话,与标准库用法又有差异了,用户外面如果也写了 if err rollback 倒是影响不大。
我先琢磨琢磨看要不要加自动回滚
1 ... 30  31  32  33  34  35  36  37  38  39 ... 60  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   936 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 32ms · UTC 21:07 · PVG 05:07 · LAX 13:07 · JFK 16:07
Developed with CodeLauncher
♥ Do have faith in what you're doing.