V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  lesismal  ›  全部回复第 15 页 / 共 60 页
回复总数  1200
1 ... 11  12  13  14  15  16  17  18  19  20 ... 60  
@iseki #151

跟线程、goroutine 相比还是不够直观。
另外,这种临时起多个并发去处理一组事情并等待所有并发执行完再继续,并不是最主要场景。
最主要场景:
例如服务器,处理每个连接,为每个连接起单独协程然后写同步代码;
例如爬虫,爬很多 url ,每个站一个协程然后递归去爬子 url ;
这些都是通常具有不确定数量和不确定执行完成节点的任务。

休想骗我学 kotlin ,要学也是 rust 🤣🤣
@totoro52 #21
说句公平话,b 站炸的好像都不是直接因为 go 吧,有次我记得是 nginx lua 里的 cpu 100%
所以这个锅 go 可不背
@iseki 搞起🤣
@iseki #146
不怕你笑话,你要不说,我还不知道有 errgroup 这玩意,刚搜了下,看样子不错,以后可以考虑用下。。。
我会的不多,用到的时候才会去查,很多用不到的干脆不懂。。。
一些 golang 公众号里经常发 golang 面试题,我偶尔看一眼就是一堆的不确定不会做。。。
你 github 账号是什么啊,我来 follow 一下
@iseki #144

我不听我不听🤣🤣🤣,就你这个这个 async await 的解释我就看的累心,比起传统进程线程比起 go 协程也太不直观了,而且还有你说的一大堆什么捕获报错父子兄弟控制流一大堆,我学不动。。。
@iseki
> 但是编程时如果每次自己去搬这一个个砖头这既不符合 DRY 的原则也不够“少”。

这个完全赞同,所以我选了 go 之后基本没再回头写多少 c/cpp 了,因为没必要,go 太省事了,而且绝大多数场景也不需要极致的性能、反而更需要开发效率

> async await 算是结构化并发的一种落地形式。

但这比起 go func()来,便利性可读性还是差得多

> 你不能说封装的程度高就一定是不好的,软件工程是权衡和妥协,君不见 Go 相比 C 不是也隐藏了许多细节吗,每个函数开头插入栈空间检查未必是个多么高效的选择,当年也有人因为用了“高级语言”就被喷浪费了机器性能。
> systemd 出现之前,如今一个 .service 文件搞定的事情要一位 bash 熟练工写上成吨的 .sh 还不一定好好解决问题。看上去 shell 里的每一个命令都好简单啊,但是组合起来的结果你能说这是“简洁”的吗。当然这个我不多说,我相信每一个工程师都很清楚。

我当然不是反对封装程度高,而是反对不必要的过度封装。
而且要分开不同的层次,一个是语言级的,一个是框架级的。
go 也好 java 也好,它们在 runtime 内的实现,都是语言级、不需要使用者去关心太多内部细节。
而框架这一层,至少我觉得 Java 是属于过度封装的,比千层饼的层数还多。。好处是更可靠,坏处当然是牺牲性能、以及真遇到问题时使用者难于深入到一层一层内部去发现和解决问题。

> 此外 Java 的轻量级线程和 Go 的 goroutine 差不多一回事,当然 syscall 该卡还是卡,go 也是在 IO 等等地方特殊处理掉的,这个不是应用程序自己做点什么就能解决的。(其它关于 Java 的内容我就不评论了,这个看场合见仁见智

这个 `当然 syscall 该卡还是卡` 要看是怎么个卡的方式,是卡协程但协程会被调度、还是卡了系统线程。
我前面 #135 里提到的 `系统调用之类的接口` 其实没说完整,准确点讲应该是 `把系统调用那些封装起来然后提供给用户的接口`,例如 go 标准库 net.Conn.Read:虽然它是阻塞的,但它不会阻塞系统线程,实现方式就是当前读不到数据时就调度了并且等待可读,runtime 里的 iocp/epoll/kqueue 等待可读事件到来再唤起。go 里直接去调用可能阻塞的 syscall 也还是可能阻塞,但标准库对于 socket fd 封装出来的 net.Conn 之类的接口都是被 poller+调度这样搞定了的,所以使用标准库的这些是真的可以写同步代码也不会导致线程池阻塞耗尽之类的。
Java 的轻量级线程如果没有配套实现全套的类似 go net.Conn 这些的话,那可能还是没有解决阻塞系统线程的问题,那至少从语言级上,就不是一个类型、不是同一可用级别的协程系统、是没有可比性的
#137
> 我们做架构、框架,最头疼的往往就是进程线程模型、并发之间的通信和一致性这些基本点的设计。

补充:
我们做架构、框架,最头疼的往往就是进程线程模型、并发之间的通信和一致性这些基本点的设计;
我们做业务写逻辑,最头疼的就是写回调,不写回调性能不给力。
语言上大概有学院派、工程派这些不同种类的人,工程上又有 CURD 派、架构派这些不同种类的人。
每个角度上的不同派别,各自的着重点都不一样。
多数学院派讲究茴字的写法是否优雅却忽略了性能之类的指标考量,所以我经常看到这类人概念大把大把地往外掏,经常让我自愧不如、因为不知道他们在说什么,但多数时候等我缓过神来,探究这些概念、优雅的玩意背后真正的实用主义,都觉得似乎并没有什么卵用,然后也就不用耿耿于怀;
工程派追求写法与实用的平衡,当然,实用的基础上也能非常优雅是最好的,但鱼和熊掌难两全,踏实做事情的人,我更倾向于实用主义;
CURD 派,就如我前面所说,能让他们自己舒服的才是最好的,什么性能优雅完全不 care 的感觉,就比如异常处理这档子事,java 的社区惯性用法就真优雅吗?审美可是没有统一标准的,怕是中尉 javaer 自娱自乐自封这样最好罢了;
架构派要考虑好多细节,但凡好点的,也都是工程派,讲求实用主义,多数 java 社区的所谓架构师,我个人都是不认同的,八成就是社区方案一把梭,什么东西适合什么场景都未必去思考过,学以致用,至于用得对不对,反正社区都是用这些东西。。。

当然,业务大了都是堆屎山,大家都是混口饭吃,能挣钱就行。世界本就复杂、好的和不好的共存,大势所趋,被下一阶段的事物取代,代码这档子智慧进化进程中的一个阶段性技术,早晚是 AI 的天下
而除去 erlang ,在 golang 之前:
我们做架构、框架,最头疼的往往就是进程线程模型、并发之间的通信和一致性这些基本点的设计。c/cpp 也好,java 也好,虽然不是什么难事,但代码仍然都相对麻烦。而 golang 里,go 、chan 、mutex 这三个关键字,几乎就搞定了这一切,绝大多数场景也不用去为 callback hell 头疼。

c/c++的一些协程库,还有一些脚本语言的手动档 yield 协程,包括现在那些 async await ,相比于 go 都显得更加难于理解。所以我完全不觉得它们有资格用来跟 go 比较,如果没有 go ,相比于它们,我宁愿回头自己写系统线程、IPC 那些逻辑。
在 go 之前,erlang 的”进程“就已经存在多年,它的并发友好是真的挺不错,但主要还是在连接之间、模块之间不需要复杂交互的场景下更简单易用。涉及到复杂内部交互的,我觉得 actor 也并不算是友好。至于函数式更不知道说什么好,喜欢它的人也基本上都不怎么关心性能,而且类似“代码量少就是美”的这种审美看上去很好,代码少的前提式隐藏了大量细节,几种不同的简单写法之间就可能存在由于拷贝带来的很大的性能差异,所以美倒是“美”了,工程上的更重要的东西却被忽略抛弃了。erlang 的指令性能也不强。整体下来,我觉得 erlang 作者当初发明它用来做电信业务这种“进程”间不需要太多交互、并且主要处理 IO 的业务式很 ok 的,但并不适合拿出来普及到所有业务,所以它手持一代目语言级“进程”(本质是协程)却没有大火起来,很是理所当然。
@iseki
> 我似乎并没有鄙视 Go 这种 panic 即退出的设计,我只是说下这个设计在没有结构化并发时几乎是必然的,不知道你在激动什么……

可能是顺着你前面几层楼看下来,感觉整体上是个对 go 不屑或者其他非积极的语气。有些词严格考究那确实算是中性,但是组合到一块就会让人觉得是在说“g 不咋地、也就那样、很多缺陷”的样子。

> Go 的 goroutine 本身设计我不认为太大问题,但它的暴露形式就值得商榷了。难以直接被使用的 "go" 变成了关键字

我没 get 到 "go 难以直接被使用" 的点在哪里,当年就是看到了"go"、"chan"这两个大杀器我才义无反顾开始写写 go ,写了一些后,就再也不想碰 c/cpp 和其他一些脚本了,更不要提 java 这种臃肿的丑八怪

> errgroup 这种东西反而变成了 x 库。

标准库的严格新增导致了特性的缓慢,但这也恰恰把很多垃圾挡在了标准库之外,各有利弊吧。而且这也不是什么难度很大的必须由标准库提供才行的功能,所以倒还好。
至少,相比于 node module 的肆意泛滥,go 社区不至于这么乱七八糟

> “标准库没有就值得一喷”,标准库什么都半残那还叫什么标准库?我也没说标准库必须要带一套结构化并发,毕竟 go 出现的相对来说还是比较早的,但是 go 关键字的存在,除了更好打广告外,几乎看不到什么必要性。

我不知道什么是结构化并发,我觉得多进程多线程以及语言及协程这些,加上进程间通信线程同步或者其他各种用于并发的机制,这些是大厦的基础。从 c 到各种语言,这些程序架构/结构设计,本质上都是这些东西在搭积木。
本来我自己对这些基础的东西比较熟,设计个架构、结构大概都能了然于胸,然而当我刚刚搜了下结构化并发,看得我更懵逼了,又是一堆概念机制需要学习,然而并没有让我觉得变得方便了。golang 的 go 、chan 两个关键字可以弄各种组合,时序的一致性的东西也都能保障,即使退回到 c/cpp ,多进程多线程、锁、各种 IPC 、以及 socket 各种也是类似的足够实现业务所需。c/cpp 这些老牌强者主要的劣势是开发效率,go 牺牲性能提高开发效率做的已经非常好了,go+chan 的组合,足以让我省去很多不必要的麻烦。

> 事实上如果 Java 在绿色线程出现之后不能及时安排好结构化并发,我敢说 unhandled exception 可以被静默忽略的特性一定会成为灾难。

这些非系统线程的语言级协程方案,都需要语言级上支持各种系统调用之类的接口与语言 runtime 调度的结合,否则任意一个调用可能直接阻塞住一个系统线程的行为都会造成大量的 cpu 闲置,如果各个线程都被这种阻塞占了,系统效率可就太低下了。我不知道 java 绿色线程出现后有没有解决这个问题,如果也像 go 一样都支持了,那还有得对比,否则仍然是不适合普及,否则估计很大比例的开发者分辨不出来哪里可能会导致问题。
然而即使支持了又如何,java 的臃肿、吃内存,就足以让人生厌。
@iseki
其他语言里但凡哪个语言的协程或者绿色线程之类的能像 erlang 或者 golang 这么方便的,再对比也行。我暂时还没看到一个其他语言有 erlang 、golang 这么并发友好的

panic 导致整个程序退出这也能算问题吗,入门级的新手 go func 不 defer recover 那是写着玩,但凡正规点的公司稍微封装下框架脚手架都不至于,如果是用协程池也通常自带了一层 recover wrap ,或者知名 web 框架那些 recover 、logger 都是最基础的中间件、通常都要加的

所以我建议,摒弃那种“但凡标准库没有就值得一喷”的思想,做工程可没人强制大伙只能使用标准库并且不要做任何封装。如果是那样要求,那也请先把 java 社区的各种轮子都拿掉再来对比,看看裸奔的时候谁更优雅,但这显然毫无意义
@yannxia #82

或许 panic 的时候自动包装一层 stack 或许就没人这么喷 go 了,毕竟小白们好些人只看标准库没有就一顿喷,好像即使额外封装下(虽然封装也很简单)也实现不了他们说的这些似的。
众多 CURDer 在某些垃圾语言的舒适区里呆的久了,但凡让他们自己亲自去上厕所、他们都嫌累,殊不知自己亲自上厕所可以舒筋活血。

go 的标准库定位简单点挺好的
> java 也可以用处理错误的方式处理错误的. java 没限制你的返回类型, 你可以返回一个 result<err, data>, 然后再处理就是.

@bthulu 我也没说 java 不能,我的意思是 java 非要用异常处理的方式去处理错误,社区这样用习惯了就继续习惯用就是了,但是拿这个来喷别的语言不这样做,就有点自以为是了,而且 go 也不是不能那样做、稍微封装下就可以了。
go 这块的本质就是:
用错误处理的方式处理错误
用异常处理的方式处理异常

java 那些:
用异常处理的方式处理错误
用异常处理的方式处理异常

好奇你们哪里来的自信喷 go
看名字就知道了,一个是错误处理,一个是异常处理。

go 用 panic 照样能像 java 那样处理异常,但本来就是为了处理错误所以用 if error 怎么了?而且哪里有错就现场处理、代码的可读性更好。只是那些其他语言习惯了用异常的人一直不这样搞才会觉得别扭。你看写 c 的人有几个说 go 错误处理垃圾的?即使 cpp ,也少有项目把错误处理都搞成 java 那种用异常处理的方式

反倒是 java 和一些其他语言,错误处理的场景和异常处理的场景,都用处理异常的方式来处理。习惯了自己的这种用异常处理去处理错误的方式,然后来鄙视 go 的该用啥用啥的鲁棒性,这帮人可真逗
337 天前
回复了 wuxidixi 创建的主题 职场话题 大家都是工作多久后达到的月入 2 万
没被降过薪,所以还没到
340 天前
回复了 RedBeanIce 创建的主题 Go 编程语言 golang 应该如何选择 api 网关呢
@coderxy 嗯嗯,也祝你成功,并且欢迎来体验下我的库 ~
340 天前
回复了 RedBeanIce 创建的主题 Go 编程语言 golang 应该如何选择 api 网关呢
> 比如 server 也可以直接推送数据给 client 、client 也可以只推送数据不需要 server response
> -grpc 的双向数据流模式
> -grpc 一样做吧,这个业务场景跟协议没啥关系。IM 都可以用 grpc 的双向数据流模式写,如果你想的话。

@coderxy
这么说吧,grpc 双向流之上封装也能搞定这些,但双向流就相当于 TCP 之于 arpc ,双向流只是支持了基础的网络交互方式、相当于网络传输层相当于 TCP ;
对于复杂场景的协议交互、应用层仍然需要很多 Cmd/Method/Router 所以对于这些场景,用户仍然需要额外的协议封装,arpc 开箱即用的双向 Call 、Notify 都已经封装好了;
双向流太难用了,性能也一般
340 天前
回复了 RedBeanIce 创建的主题 Go 编程语言 golang 应该如何选择 api 网关呢
@coderxy 闭门造车这个词可能不对,但闭门这个词还算是比较准确,因为我造车的时候确实没有参考它们、主要是按照自己的设计来做的
兄弟如果你的从业经验主要是应用层的工作、公司里头不需要你造轮子、那你可能只要有轮子并且够用就可以了也不关心轮子好坏,但你可能就 get 不到这些造轮子的重点、也不太能够对轮子之间的重点进行合理的对比,这没错,大多数人都是这样工作的,但请不要以为自己用的就是最好的、其他的就都是闭门造车了,这样就有点一叶障目了
1 ... 11  12  13  14  15  16  17  18  19  20 ... 60  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2668 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 21ms · UTC 04:18 · PVG 12:18 · LAX 20:18 · JFK 23:18
Developed with CodeLauncher
♥ Do have faith in what you're doing.