V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 3 页 / 共 66 页
回复总数  1308
1  2  3  4  5  6  7  8  9  10 ... 66  
20 天前
回复了 ugpu 创建的主题 Go 编程语言 Golang 游戏开发框架选型
@guanzhangzhang 游戏客户端跟 golang 没太大直接关系了, 一些开源项目客户端和服务端都提供了, 但都是游戏功能本身比较多, 游戏业务逻辑本身并不算是通用的框架部分. 游戏客户端引擎是框架的主要部分, 其他的加上网络和热更之类的就算足够做普通项目的脚手架了能对标 golang 这些忽悠人的脚手架项目, 复杂游戏的也是业务类的特殊需求也是不同类型不一样, 大型的多人海量元素同屏动作类之类的优化也是一大坨, 特效需求多的各种技术美术的需求 shader 优化.
不管是客户端还是服务端, 除了通用的简单脚手架的部分, 没有统一的框架, 各种类型游戏的特殊需求都加上的话就显得太重了不适合中小游戏, 比如 bigworld 去做卡牌和简单 arpg 完全是杀鸡用牛刀, 客户端服务端用这种大框架都很浪费反而开发效率和维护成本低. 如果特殊的不加上吧, 那些业务需求复杂的功能又都得自己造轮子, 简单脚手架提供的这点功能微不足道用处不大
21 天前
回复了 ugpu 创建的主题 Go 编程语言 Golang 游戏开发框架选型
@asuraa 补充 #12

timer 里这个 IDGen 是存在溢出可能性的, 运气不好的话可能遇到任务丢了或者相关的:
https://github.com/aceld/zinx/blob/master/ztimer/timerscheduler.go#L69
https://github.com/aceld/zinx/blob/master/ztimer/timerscheduler.go#L32
而且 addTimer 相关的逻辑的锁粒度比较大, 这个锁完全可以在操作数据结构的小范围加上, 其他的那些时间计算与判断的应该放在锁的范围外边并发竞争的 cpu 浪费
21 天前
回复了 ugpu 创建的主题 Go 编程语言 Golang 游戏开发框架选型
@asuraa #6
zinx 属于脚手架, 和其他几个早期开源的游戏框架类似, 都是比较简单的封装, 而且有些封装其实是垃圾封装, 既没必要, 又可能浪费性能.

刚简单扫了几眼 zinx, 举下例子:
比如 timer, 标准库 time 包足够用了, 四叉堆性能足够好, 而且精确度最高, zinx 里面自己用时间轮自己搞个没必要, 而且时间轮一是精度低, 二是如果想精度高就要更小的轮间隔, 则 tick 频率高空转有点浪费 cpu. 另外, 看代码实现, 作者并不太注意性能细节, 例如创建一个新的定时器, 多次调用 time.Now(), 而这本是可以只 time.Now()一次复用的:
https://github.com/aceld/zinx/blob/master/ztimer/timerscheduler.go#L79
https://github.com/aceld/zinx/blob/master/ztimer/timer.go#L71
https://github.com/aceld/zinx/blob/master/ztimer/timewheel.go#L137
https://github.com/aceld/zinx/blob/master/ztimer/timewheel.go#L96
https://github.com/aceld/zinx/blob/master/ztimer/timer.go#L58

再看下异步任务协程的吧, 讲真, 刚看了几眼, 之前没看过, 都没想到能写这么差.
固定 2048 个, 够不够用另说, 写死这个本身就是挺不可思议的设计了:
https://github.com/aceld/zinx/blob/master/zasync_op/async_op.go#L45
按 opId 取模作 index 取对应 worker, 业务层对 opId 可以各种定义, 模块 id userId 之类的, 如果大量任务的 hash 不均匀则会导致单个 worker 协程忙死其他的 worker 闲着, 任务调度分配不均衡, cpu 利用率和性能存在不稳定的可能:
https://github.com/aceld/zinx/blob/master/zasync_op/async_op.go#L53
https://github.com/aceld/zinx/blob/master/zasync_op/async_op.go#L67
而且就这个 getCurWorker()方法, 你都 array 了, 抛开上面说的调度分配不均衡问题, 考虑到满载性能利用, 还不如启动阶段创建好都跑起来, getCurWorker()直接就 index, 连锁都不用加

更多的不看了, 这是属于造屎山的项目, 但作者是作技术培训, 用于简单教学之类的也无可厚非.
如果是游戏小白, 或者做中小项目的团队拿来用, 可以拿来用用图个省事, 也算凑合吧, 毕竟解决了一些人的轮子问题.
如果是对自己技术有追求的, 或者规模大点的项目对代码性能有要求的, 就不建议用了, 也不建议推荐给其他人用.
21 天前
回复了 ugpu 创建的主题 Go 编程语言 Golang 游戏开发框架选型
> 主要是网络 & 日志 & orm & 分布式. 这几个点 不知道有啥可以匹配的.

@ugpu

网络部分可以试试我的这个, 本质是个网络库, 游戏行业缺少统一的技术规范, 所以蹭热度用来 rpc 的名字:
https://github.com/lesismal/arpc
性能应该也足够用:
https://colobu.com/2022/07/31/2022-rpc-frameworks-benchmarks/
网络协议随便你选, tcp,websocket,kcp,quic 各种, 只要实现 net.Listener 和 net.Conn 就可以了
client 只有 go 和 javascript, 其他语言如果自己熟悉这块自己实现一份也不难

golang 没有好用的 orm, 游戏业务的 sql 需求也不是特别大所以 raw sql 足够了, raw sql 确实有点麻烦, 可以试试我这个:
https://github.com/lesismal/sqlw
能省掉字段绑定的很多麻烦

日志:
随便选哪个知名的都可以, zap zerolog 之类的各种, 功能和性能都足够, 自己根据自己喜好稍微封装下细节就可以了

分布式:
除了 bigworld 那种大型游戏有相对固定的框架体系, 其他多数游戏都没有个固定的, 以上所述的几个点, 其实都算是脚手架. 但 bigworld 这种, 单位太多, gc 压力太大了, golang 并不适合.
其他的 fps moba 之类的, 都算是比较容易对房间扩容的, 匹配服调度下然后战斗服堆机器就可以了.
还有一些类型, 大型全球同服 slg, 一些 arpg 之类的挂机游戏, 或者其他一些依赖服务端做大量数学计算的或者服务端渲染的, 也都是需要自家定制优化.
而分布式本身, 抛开这些特殊的业务优化需求, 分布式主要是通信, 仍然是网络库在不同服务之间建立连接收发指令处理逻辑就可以了. 至于大概 10 年前一些 web 领域渗透到游戏里的技术, 例如服务注册与发现, 这至少二十年前游戏行业就有了, 集群里通常都有特定的服务承担特定的集群管理角色, 只是不像 web 领域那样技术栈通用和用户广泛所以没有那么被人熟知.
OP 没有提到我上面说的几种特殊业务类需要, 所以对于 OP 而言, 分布式的需求其实自己随便搞搞就行了, 比如用 arpc 随便写写就好了.
@SeleiXi #7 嗯嗯, 那就完全没问题了
> 然后因为 score 不会动态更新所以就想着用其他方案了

@SeleiXi 更新用 pipeline zrem+zad, 先删再重新添加, 就可以了 🤣
zset 足够了, timestamp 做 score, 没必要用其他的, 别想多了

> 要用键查询对应的值 & 知道前面还有多少个键值对是先于他创建且没有被删除的

zrank 查询对应的值的时候就会返回这个值的排序下标(整个 zset 排序下标从 0 开始), 默认 timestamp 升序, zrank 返回的值减 1 就知道前面有多少个是先于它了.
你保证每组操作原子性, 比如单次如果需要多个操作就 pipeline, 这样就能保证你每组操作在 redis 里是串行执行的, 所以你当前能查到的所有结果肯定就是对应的存在的未被删除的数据集的

> 所以数据结构需要是有序的),只需要先入先出(不需要从中间删元素)

zset 就是按 score 排序的, 你只要自己处理每次先删除第一个就行了
> 为什么两个加起来一个 issue 都没有?

@stabc
不是一个 issue 都没有, 而是一个 Open 状态的都没有. 兄弟你查 Closed 状态的, 到目前 arpc 有 47 个, nbio 有 242 个.
一个 Open 状态的都没有有两个原因:
1. 作者个人形单影只, 宣传力度不够, 吹个牛说, 虽然功能性能个方面都算是同领域 Top 级的, 但知名度太低, 知道的人少, 来 issue 的人也就少. 看看其他一些同领域的, 功能比这个少, 性能不比这个强, 但是 star 比这多的多, issue 不解决比这多的多
2. 每次有 issue, 作者都尽量迅速答复和解决, 所以除了极个别迷案无果而终, 绝大多数都已经解决了然后就关闭了
@prosgtsr 这算是我职业生涯里的最佳命名了

@spritecn 末期末期, 还没全退, 但是准备中...

@kingcanfish "激情探讨", 做清醒的自己~

@huig 来来来, 兄弟一起干 BA
@gongquanlin #2 感谢支持! 欢迎多来交流!
这个同事问题很大, 但是 OP 自己作为管理者也有问题, 基本没看到培训流程和方法, 只是东西丢过去让别人自由发挥.

例如生产环境, 权限不是随便就能给的, 至少要带一段时间非生产环境熟悉了之后才可以, 并且刚上手生产最好是每个操作也一块看下, 确实手稳再给他自由发挥的空间, 否则就容易挖坑. 我自己部门的新人, 至少要培养观察两三个月才会给生产, 观察期间如果觉得这人性格和做事方式不稳, 那尽量不给, 甚至直接就试用期过不来辞退了.

OP 可以如何改进?
先根据自己这块的实际情况, 梳理下工作内容工作流程和新人的培训流程, 比如新人培养至少多少时间, 需要熟悉哪些环境和业务和操作流程, 需要进行答辩, 需要非生产环境安排任务操作看看性格和做事风格是否会带来乱子, 基本每周都一个章节每个章节一个考核这种.
非生产环境都 ok 了再给生产环境, 谨慎带一段时间.

OP 可以如何自保?
做到上面改进的部分, 物竞天择适者生存, 能通过考核的人问题不大, 不需要你担忧自保.
如果改进的培训部分他做不到, 可以根据培训过程中对他的能力给出你的合理评估, 如实报告给你的领导, 即使是说他的不好也尽量委婉而且对事不对人不要牵扯人品, 说话也要自己谦虚并且委婉些面的打老板和领导的脸让他们以为他们自己不靠谱, 而且把决定权丢给老板和领导, 比如委婉建议是否安排他转个部门之类的(甚至辞退).


合理的方法和流程, 自己做的都是阳光下的, 再把话术整理好, 决定权和面子给老板和领导留着, 其他的不需要太在意, 除非是老板和领导故意想整你否则不太需要考虑自保的问题, 如果是老板和领导要整你, 自保也保不了, 而且从 OP 内容看至少现在不涉及整人的事情
拆一拆说不定还能做点器官移植或者有偿器官捐献......
3000 多的东西, 他才赚了你 2000 多

单方面经济关系的人, 通常都不是真正的朋友关系, 你打游戏开黑不会找他, 你去桑拿洗脚泡妞不会找他. 这种是经济上的熟人罢了

真正的铁子朋友就是常见那几句:
一起同过窗
一起扛过枪
一起嫖过娼
一起分过脏
...
48 天前
回复了 dcy7287 创建的主题 生活 找老婆最重要的就是情绪稳定,你们认可吗
双人运动的时候对方情绪稳定
给她惊喜的时候对方情绪稳定
男人临终的时候对方情绪稳定
......
53 天前
回复了 asanelder 创建的主题 问与答 有没有觉得“延迟满足”就是扯淡!
小伙子你这不叫延迟满足, 你这叫:

少年不知 X 珍贵, 老来没 X 空流泪
53 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
> 如果拿 js 来做对比的话,很明显 js 努力的方向一直是用同步的方式写异步逻辑,经过了 promise 到 async/await 的迭代,但 go 这边就很符合直觉。

对对, 非常同意. promise 对于很多人都是个坑, 因为看着是顺序的实际上不是本次 eventloop, 所以遇到 for 循环里的 promise 或者 promise 后面的逻辑, 其实都是违反时序直觉的, 很多新手遇到了 bug 都仍然难搞懂这个. async/await 虽然提供了, 但也是难于理解难于使用, 比 goroutine 自动档差远了
这么有毅力不容易, 加油 OP!
53 天前
回复了 kuanat 创建的主题 Go 编程语言 基于 Go 语言谈软件开发效率
> Go 最重要的贡献之一是基于 chan 的思维模型:Share memory by communication 。
> 日常反复被强调的 goroutine 其实不重要,很多语言也可以有样学样。

chan 挺好, 但本质上相当于个阻塞队列, 即使没有 golang, pipe/cond_t+mutex/sem 之类的传统的进程间通信/线程同步的这些也都能实现类似的阻塞队列组件. 但多进程多线程和这些 syscall 要么阻塞线程要么异步.

Share memory by communication 更像是从 erlang/actor 拿来的, 但 golang 整个语言本身没有像 erlang 那样纯 actor.
actor 是个太监模型, actor 之父是为了他们自家电信业务造的 erlang, 电信的那种每个 erlang 进程处理一个连接, 设备进行管理功能也不算复杂不需要连接之间有复杂的交互, 这种场景用 erlang 的进程通信比较简单.
但纯 actor 并不适合于复杂的业务, 例如连接之间有复杂的交互.
而且不管哪种 actor, 让一些即使很简单的交互, 或者一些用普通的逻辑处理比较简单的交互, 也都强制必须用通信的方式, 都是需要数据拷贝/调度或者切栈上下文之类的, 这些都带来了额外的性能损失. 性能损失这一点, chan 也是类似的, 简单的有性能需要的功能, 用 chan 未必见得划算.

runtime 基础之上:
goroutine 让大家绝大多数时候能写同步代码, 这个解决了传统高并发高性能的 c/c++/java netty/nodejs 等语言的 callback 逻辑不直观和 callback hell 的问题.
传统的进程间通信/线程同步 syscall 封装组件, 即使实现同步组件, 但阻塞的是进程/线程, 所以不能用 goroutine 与这些 syscall 结合来让大家写同步代码, 所以需要 chan 这种基于 runtime 的轻量阻塞队列实现.

golang 标准库提供了个基于 runtime 的 cond_t 也可以自己封装下实现 chan 或者类似的组件, 但 chan 已经足够方便了, 我暂时想不到有需要自己搞这个的需要.
从这些角度讲, 我觉得 goroutine 仍然是最重要的; chan 很好, 但是次之, 因为也有很多场景是不需要甚至不适合用 chan 的.
54 天前
回复了 iintothewind 创建的主题 程序员 golang, 开发效率低执行效率高的语言?
我个人觉得 Java 开发效率是最低的.
—— 但这只是我个人对我个人用 Java 的感觉, 而不是我认为所有人用 Java 都如此.
—— 至于原因: 我个人不喜欢 Java 的臃肿, 所以一直抵触用 Java, 所以也没有学习过 Java 的那些框架.

很多说 Golang 开发效率低的人, 其实跟我类似, 首先他们嫌弃 Golang 提供的语法糖/特性太少, 其次他们也不熟悉 Golang 社区的成熟框架/解决方案. 而且这些人绝大多数都是做 CURD 对性能没太大需求, 所以带来的性能提升他们是睁眼瞎一样完全忽视.
他们从来没考虑过是不是因为他们自己都不够熟悉 Golang 的正确姿势和成熟方案, 而仅因为 Golang 没有其他语言的那些姿势和方案, 就来无脑喷 Golang 开发效率低.
这种类似的观点言论, 可以反映出他们自己的水平还不够高, 但我这里说他们水平不够高并不是贬义, 因为这些人很大一部分是经验年限比较少的, 多数人年轻时候都菜, 慢慢成长吧, 等自己真正脱离了 CURD 这个 Level 的时候, 真正懂得去思考系统和工程的时候才能给出客观评价.
设计模式的糟粕害人挺多的, 观察者是少数实用的之一, 和发布订阅本质上是类似的.
没必要把自己陷在某个语言的实现方式上, 理解它的用途, 融会贯通的实际运用就可以了. 我当年写 C 为了模块之间解耦自己就搞了个出来, 当时都不知道这玩意是个设计模式, 后来看设计模式的书才知道原来这叫做观察者.

BTW, 至今设计模式我也没记住几个, 反倒让自己代码通常比多数人更简洁一点.
1  2  3  4  5  6  7  8  9  10 ... 66  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1314 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 28ms · UTC 23:48 · PVG 07:48 · LAX 15:48 · JFK 18:48
Developed with CodeLauncher
♥ Do have faith in what you're doing.