从业时间越久,发现互联网很多知识都是错的, 对小白误导有多深?

2022-04-18 22:04:26 +08:00
 jeesk
说说我自己的看法, 无论是 csdn 还是知乎, 在我最开始从业 java 的时候,觉得他们说得没有毛病? 从业几年后,发现很多都是在鬼扯。 就拿 BIO 和 NIO 谁性能好, 知乎上面竞争激烈,下面我粘贴一个知乎的回答。

回答 1:

首先要明确一点:nio 的适用于 io 高并发场景线程开销包括:内存开销(创建一个线程需要为其分配和维护一个 tcb 线程控制块保存上下文,一个线程私有的栈)、线程上下文切换的时间开销(保存上下文,加载下一个线程的上下文),在高并发环境下多出来的这一点点开销积累起来是非常可观的。若使用 bio ,高并发必然引起激烈 contention ,导致大量的上下文切换,若采用一个 io 一个线程模型,一个线程 M 级的空间消耗,内存消耗不起。而 netty 采用 nio 加 selector 加线程池基本上解决了上述问题:一是线程池限制了内存消耗,二是采用 selector 使得只有处于活动状态的 io 才会去占用线程,不会使线程白白因为 io 而阻塞,提高了线程利用率。

说说他们的谬论:
1. 使用 BIO 上下文切换厉害, 如果是相同 4 核 cpu , 无论我是用 bio 还是 nio ,都用 200 个线程, 这个时候对 cpu 的竞争到底有多剧烈? 我个人觉得差不了多少。 所以这个说法是错的。

2. 若采用一个 io 一个线程模型,一个线程 M 级的空间消耗。 这个就更扯淡了。 即使是 tomcat 在 8.5 以前也是 BIO 200 个线程, 都没有用到 1w 个线程? 为什么非要扯开大量线程呢? 并且 tomcat 在 8.5 以后才默认 nio.

3. 一是线程池限制了内存消耗,二是采用 selector 使得只有处于活动状态的 io 才会去占用线程. 那我 tomcat 用 BIO 没有内存限制? 没有内存限制岂不是早就宕机了? 再说说 selector 的问题, 我 NIO 在 readSelector 开 10 个线程去调用 select, 不都是阻塞的吗? 怎么会说在活动状态才占用线程?

然后你会发现这些错误的回答有很多,下面还有大量的小白点赞,觉得说得很对。 但是一经脑子思考就发现, 这绝对是坑 B.

如果有不同意见的小伙伴可以留言,我觉得这个可以作为一个面试题。
17139 次点击
所在节点    Java
154 条回复
jeesk
2022-04-19 07:44:30 +08:00
@medivh 看清标题再说, 我只是想讨论关于网上有很多错误的言论。
jeesk
2022-04-19 07:53:02 +08:00
@wtdd 一切皆有可能
jeesk
2022-04-19 08:05:53 +08:00
@gtx990 你说得没问题, 但是 netty 并不是全异步的,select 还是会阻塞, 真下的异步是 aio 。 既然 selct 都是阻塞的? 我看网上没也人亲自做过测试来证明一下相同线程下处理 seletor 事件,bio 上下文竞争比 nio 强烈, 我反驳的是这个观点。
Jekins
2022-04-19 09:15:48 +08:00
我干了快两年 Java 。。还没遇到过要考虑用 netty 这些。。一直没想过 netty 会用在什么业务场景? lz 方便说下吗哈哈
MoYi123
2022-04-19 09:23:13 +08:00
2022 年的 mysql 真的超过 1000 万行就要分表吗? 不太用 mysql, 有没有人说一下.
lap510200
2022-04-19 09:23:19 +08:00
正常,国内粪坑文章太多,只谈性能测试,脱离业务实践就是很鸡肋
cheng6563
2022-04-19 09:31:10 +08:00
@MoYi123 3 亿数据照样用
misaka19000
2022-04-19 09:31:16 +08:00
看书就行了,而且不要看中国人写的书
jeesk
2022-04-19 09:34:45 +08:00
@Jekins 可以看看一些 rpc 源码里面通信大多用 netty
jeesk
2022-04-19 09:36:46 +08:00
@MoYi123 一般公司用不了, 国内很多面试分库分表的 都是瞎搞。
james122333
2022-04-19 09:38:01 +08:00
@jeesk

楼主还在纠结同样线程并且是大量线程
jeesk
2022-04-19 09:38:59 +08:00
@lap510200 性能测试也是假的, 就拿 fastjson 来说 , 他们自己测试出来比 gson jackson 快。 但是我自己测试出来 fastjson 速度最慢 。
Goooler
2022-04-19 09:41:17 +08:00
不如 okio 好用
trivisa
2022-04-19 09:41:23 +08:00
这个不需要从业久也能发现吧哈哈哈,而且是各行各业,甚至生活知识都是这样
只能说中文互联网内容确实还不够好,大家继续努力吧
nothingistrue
2022-04-19 09:51:32 +08:00
你的标题是对的,但你下面说得谬论好些不是谬论。

1. 抛开剂量来说影响,那是耍流氓,线程切换的消耗跟线程的数量,是指数对比,200 个线程你看不出来区别,但是一千一万呢,不要说物联网服务器,就是面向公众的普通 Web 服务,那都是一万起步的。

2. 请参见一,在 tomcat 改成 NIO 之前,它要么只应用在不到百人的企业内部,要么躲在 IIS/Apache 后面,压根不会直接面向公众(早期确实有不负责任的人那 tomcat 当前台服务器的页游,那响应速度是相当感人的)。

3. 这么貌似确实是谬论,我也没看懂。Netty 本质上只是对 Java nio 的易用性封装,并没有动 NIO 的原理。至于你的阻塞疑问,IO ,不管是本地 IO 还是网络 IO ,并不是总是在传输的,他经常是在等待输入源 /输出目的可用的等待过程,这期间它是不工作的,这个时候,如果是 BIO ,不管是否工作它都要占用线程,如果是 NIO ,不工作期间是不占用线程的。
NXzCH8fP20468ML5
2022-04-19 09:52:19 +08:00
本来 Java 就很搞笑啊,归根结底在于只提供了 NIO ,却没提供协程,异步运行时等基础设施,导致出现了 NIO 要开 200 个线程的荒谬的事情。
正确的多路复用,比如 C#,Go ,Rust ,都是开了异步,就只提供 CPU 核心数量级的线程,一个 io 一个 task ,那些 task 就留着协程慢慢调度去。
NXzCH8fP20468ML5
2022-04-19 09:55:30 +08:00
@MoYi123 正确做法是亿级分表,但千万级时肯定就要考虑分表的事宜了。
aguesuka
2022-04-19 09:58:18 +08:00
nio 不初学者了, 我来说两个: 字符串拼接最佳实践和什么时候用 LinkedList
nothingistrue
2022-04-19 10:03:38 +08:00
还有,NIO 200 个线程是应对五万并发连接的(一个 Linux 单机最高就能开这么多连接,没这个限制它能应对更多),实际上压根也用不到 200 个线程,物联网或者没有文件上传下载场景的接口服务器场景下,10 个线程就能轻松应对五万并发连接。请注意这里的并发连接是指可以毫秒级别同时响应的连接。

后面你提到 RPC 大多用 NETTY ,那是因为 RPC 服务器是至少上千通常上万的并发量(没到这个并发量也没必要开 RPC )。
aguesuka
2022-04-19 10:06:44 +08:00
除非不用 JDBC, 否则 Java 就活在多线程的阴影里

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/847761

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX