我先声明啊,我不是来吹捧 java 的,我只是想说一个事实,编程语言 没有谁绝对的碾压谁,真遇到了实际业务需求,写出来的代码量绝对是半斤八两。
我希望大家 在 吐槽一门语言的时候,可以理性一点,不要瞎喷。这篇文章的用意就在于此。
还有一点,我用 go 来比较,是因为 go 擅长的场景,跟 java 有一定的重叠,有很多公司都用 go 开发 web 。绝对没有对 go 不敬的意思。
总结下来,从工作量的角度来看,就是多了一个倒置的域名而已,而且只需要花建一层目录的时间,并且这个倒置的域名 是有他的意义在里面的,你们可以把他看做是这个
// go 语言里的 import ,前面也有一个域名+项目名 来确定唯一性,包名里的倒置域名就是起这个作用的
import "github.com/scan-util/xxx/xxx"
还有很重要的一点,你们喷来喷去的那些多余的目录结构,在我们的观念里 根本就不存在,因为从来没有手工去创建过,要不是你们来吐槽,我们还真想不到这一点。
不是因为 习惯了,而是真的从来没有为他们花过 5 秒钟以上的时间。有的连一毫秒都没花过。
go
func BytesToString(val []byte) string
java
public String BytesToString(byte[] val)
我真没看出来多了什么东西
go
name := "张三";
var map = make(map[string]interface{})
var array = make(string[], 10);
java
String name = "张三";
Map<String, Object> map = new HashMap<>();
String[] array = new String[10];
好像多了点东西,又好像没多什么。
go
for(i:=0;i<100;i++){
}
for(i<100){
}
java
for(int i=0;i<100;i++){
}
while(i<100){
}
确实多了几个字母。
go
我知道这叫结构体,跟类是两码事,但是 go 就是用它来兼容 oop 的,所以我只能用它来举例子,因为没有其他语法可以实现 oop 了
type DemoParam struct {
name string
}
func (demoParam *DemoParam) FormValues(key string) []string {
}
java
class DemoParam {
public String name;
public String[] FormValues(String key){
}
}
字数上相差多少,我是懒得数了,但是你们真的不觉得 java 的结构更清晰吗? 其他的继承,多态 我就不拿出来说了,go 基本上是 用的 c 的编程思想,oop 只是个兼容, 所以用 java 来跟他比 oop 没什么可比性。因为是两个方向。
go
func testFunction(paramStr string) (string, error) {
if xxx {
return Errors.New("xxxx");
}
}
paramStr, err := testFunction("ok")
if err != nil {
log.Println(err.Error())
}
java
public String testFunction(String paramStr){
if (xxx) {
throw new Execption("xxx");
}
}
try {
String paramStr = testFunction("ok");
} catch(Execption e){
log.Println(e.getMessage);
}
这个看起来 go 好像 舒服一点,但是,实际场景下 go 经常是这种姿势
paramStr, err := testFunction("ok")
if err != nil {
log.Println(err.Error())
}
paramStr, err := testFunction2("ok")
if err != nil {
log.Println(err.Error())
}
paramStr, err := testFunction3("ok")
if err != nil {
log.Println(err.Error())
}
而 java 还是只需要这样
try {
String paramStr = testFunction("ok");
String paramStr = testFunction2("ok");
String paramStr = testFunction3("ok");
} catch(Execption e){
log.Println(e.getMessage);
}
并且这是 经过人为判断后,返回的错误提示,如果是意外的异常呢? go 里面叫 panic ,java 只要用 try catch 包住了 就可以捕获,但是 go 需要用 defer ,而且一旦抛出异常就意味着这个函数结束了,你如果想在出异常后,处理一下 然后继续往下走,go 会非常的麻烦。
go
// 如果有一个 interface{} 类型的变量 a ,想转成 int
// 你必须明确的知道,他装箱前就是 int ,不然根本没法拆,必须做一下类型判断。
// 我之前在写框架的时候 就被折磨的够呛,一大堆不必要的 if
java
// 不管装箱前是什么,只要他的值是一个整数
// 无论是 1 , 还是 "1", 都可以这么转
Integer aInt = Integer.parseInteger(a.toString());
// 也可以直接拆成 String
a.toString();
你们出一个需求给我,我用 java ,你们用 go ,nodejs ,python ,php 随便什么语言,最后来比比 谁的代码少一些。 我敢说,绝对半斤八两,不可能有谁碾压谁的。
而且还有一定的概率,java 在 丰富的生态+强大官方库的 加持下,可以更快完成。
202
BigDogWang 2022-05-13 08:35:31 +08:00
kotlin 表达力真的强?项目里有人写代码 kotlin 特性全用上了,在哪返回一眼都看不清楚
|
203
yazinnnn 2022-05-13 08:49:36 +08:00
return 处返回啊,这有什么看不清的
|
204
Ziyue 2022-05-13 08:49:52 +08:00
哈哈,喜闻乐见,就喜欢看这种无聊的帖子了.想起郭德纲的相声,喝咖啡高雅,吃大蒜低俗.
|
205
fyxtc 2022-05-13 09:35:12 +08:00
这种贴当娱乐贴看就行了,吵语言,和炒币一样,十年前 csdn 就吵这个,没啥意义
|
206
Loku 2022-05-13 09:40:28 +08:00
喜闻乐见
这真的没必要争论。 每个语言出现的初衷都是针对问题提出的解决方案,肯定是有偏向性的。 |
207
xjay 2022-05-13 09:42:18 +08:00
以前是哪个项目适合哪个语言就用哪个,现在是哪个老板给钱要用哪个就哪个。
|
208
AItsuki 2022-05-13 09:46:53 +08:00 1
啰嗦还真有一点点啰嗦,但拿来喷就有点刻意了……
而且 Java 也是一直有在优化了,例如 Jdk7 可以<>省略泛型。Jdk8 的隐式 final 、lambda 、stream ,Jdk11 的类型推导和字符串扩展方法。 而且选择 go 开发 web 的话,原因根本不是啰嗦不啰嗦的问题…… |
209
fredli 2022-05-13 09:55:10 +08:00
继续:
withContext(IO) { val okhttpclient = buildOkhttpclient() val request = buildRequest() val response = okhttpclient.newCall(request).execute() if (response.isSuccessful()) { withContext(Main) { notifyUI() startActivity() } } else { doLog() } } |
210
Lancer777 2022-05-13 10:04:32 +08:00
@xsen 请问你的数据从哪里得到的,广州 Go 的职位连 Java 的十分之一都没有,就这十分之一里面还有一大半是大厂贡献的,小公司连 Java 的待遇都给不好,更何况给 Go 的了,招人就是小公司最大的难点。
|
213
vikaptain 2022-05-13 10:59:26 +08:00
我是写 C#的,也写过一小段时间 java 。相比来说 java 啰嗦是有的,但是两者差别不大。同部门的 C#去写 java 都是一样的感觉。
我想说 C#比 java 的优势在于加班少 |
214
qbmiller 2022-05-13 11:18:35 +08:00 via Android
go 泛型出来了,加上一些工具包,应该会更好吧。虽然我是个 java…
不过 java 也在逐渐优化云原生这块 |
215
agileago 2022-05-13 11:28:18 +08:00 via iPhone
@sciel 你别用 goto,goto 本来就是强烈不建议使用的,再说 js 里面就没有 goto, 你写一个无 goto 的版本看看
|
217
pkupyx 2022-05-13 11:50:47 +08:00
@xsen 很多这个词,和你自己下面讲的人是难找、还得靠其他语言转,不觉得逻辑上是冲突的么?你这个很多翻译过来,其实叫比例很低但有一定数量。
|
218
sciel 2022-05-13 12:59:30 +08:00
@agileago
``` func fetchData2(ctx context.Context, url string) (*gjson.Json, error) { d, err := gclient.New().Timeout(time.Second*3).Retry(5, time.Second*3).Get(ctx, url) // 重试 5 次,每次间隔 3 秒 if err != nil { glog.Error(ctx, err) return nil, err } json, err := gjson.DecodeToJson(d.ReadAll()) if err != nil { return nil, err } switch json.Get("code").Int() { case 0, 1: return json.GetJson("data"), nil default: return nil, errors.New("获取数据失败,请稍后重试") } } ``` 才发现,框架自带了重试机制。。 |
220
incompatible 2022-05-13 14:39:43 +08:00 1
@ColinZeb 你列举的这个模式匹配跟 java 8 里引入的 stream 、function 没什么本质区别啊。而且说句不客气的,你写的这玩意儿看起来蛮丑的🤷🏻♀️
另外属性和泛型难道 java 没有? |
221
Leviathann 2022-05-13 15:19:43 +08:00
@incompatible pattern matching 就别洗了,java17-21 的对代码编写改变最大的核心特性就是加 pattern matching 和虚拟线程
建议学习 oracle 的 java 官方视频看 pattern matching 有什么用以及为什么要加 |
222
cenbiq 2022-05-13 19:33:11 +08:00 via iPhone
C#的灵魂:
1.早期就加入的 Lambda 。 2.针对 IEnumerable 接口设计的 Linq 库,任何可枚举对象都可以直接开始 Linq 链式操作,而无需多余操作。 3.搭配 async/await 的 TPL 库,以及全异步支持,简单好用,协程也不错但学习成本明显高很多。 4.最重要的,运行时泛型。 5.property ,代替了 getter/setter 方法。 6.struct ,只在栈内存中的对象。 Java 的优势: 1.生态更佳。 2.容易且自然的 AOP 编程。 3.更好找工作。 |
223
xsen 2022-05-13 19:57:44 +08:00
|
224
xsen 2022-05-13 20:04:01 +08:00
@pkupyx #217 也不算冲突,人难找的意思是因为 go 本身用的人不算多(相对 java 来说),所以出来的人更少。也跟我们要招的前端,还有 c++的一样(其实 c++更少)
但 go 来说有个好处,就是别的语言的真的很容易转。比如我看到的,包括应届、毕业 1-2 年,或毕业多年( 3 年以上)别的语言开发经验的,如原来做 web 前端的、ios 的、java 的、c++的,都很容易就转过来做 go 从我看到的数据来说,经验丰富的 2 周左右,不太丰富的 1-2 个月左右 |
225
leaveOnTime 2022-05-13 22:17:03 +08:00 via Android
@xsen 没错,字节里面给新人学习 go 的时间就是一两周,然后就开始做一些小需求慢慢就上手了,go 的学习成本或者叫入门成本是比较低的
|
226
pkupyx 2022-05-13 23:31:02 +08:00
@xsen 我在说的观点是对小厂而言 go 的整体生态是劣势,你给的论据翻译成伪代码是这样的:
func 恰恰相反,go 比 java 对小厂好(goInfo, javaInfo) int { if goInfo.go 人难找 { if 其他语言很容易转 go {return 1} } } 难道不应该是这个逻辑么? if 只要 go 人比 java 难找 {return -1} 语言对超大厂的候选人才来讲,切换确实不大是问题,但仍然是小问题。而对小厂对标的人才群体来说则是不太小的问题。 |
227
stuazt 2022-05-13 23:43:56 +08:00 via iPhone
就不说其他的语言,楼主哪怕稍微试试 kotlin 呢?你试试,就不会发这个帖了。Java 语言能力没啥问题啊,但确实写起来很麻烦,相对于一些比它新的语言。
|
228
hepin1989 2022-05-14 00:52:57 +08:00
Scala 可以秒杀 Golang 的抽象能力
|
230
incompatible 2022-05-14 03:52:58 +08:00
@Leviathann 为什么加啊?为了把代码写得像我引用的那坨一样丑吗? 笑
|
231
msg7086 2022-05-14 07:11:41 +08:00 via Android
我厂,我之前碰的代码,原本是 JDK7 ,没有 var ,没有 lambda ,没有 map reduce ,写异步并行需要用 future 。
过了一年,经过层层老板研究决定,批准升到 JDK8 。 有 map reduce 了,有 lambda 了,有 parallel stream 了,还是没有 var 。 然后过几个月我就接到了个 JDK1.6 的项目。 |
232
jy02201949 2022-05-14 10:36:38 +08:00
结合上一个《 java 很重》的帖子,让我联想到了那个笑话:
|
233
jy02201949 2022-05-14 10:38:41 +08:00
女:如果你能让这个论坛里的人吵起来我就跟你睡
男:发帖“PHP 是最好的语言” 女:我先去洗澡我会兑现我的承诺 20 分钟后 女:我洗好了,你怎么还在电脑前 男:我今天非得说服这帮人,PHP 就是最好的语言 |
235
Xrtero 2022-05-14 14:08:39 +08:00
后排吃瓜🍉
|
236
nnegier 2022-05-14 14:52:30 +08:00 via Android
我以为是 jvm 党呢,原来是 java 党,kotlin 这种几乎一样也能回复争论一把
|
237
v2vTZ 2022-05-14 15:44:17 +08:00 via Android
我也觉得这么多少争赢了也意义不大,在我看来 Java 的啰嗦反倒是个好处,作为第一门语言学习挺规范的
|
238
FrankHB 2022-05-14 17:35:27 +08:00 1
半斤八两?你直说吧,就是欺负人家在有选择的前提下懒得写啰嗦业务代码罢了。真写得写不出来明显两码事好不。
比如就实现操作系统这个业务,真有人汇编写出来比你 C 写得啰嗦得多,你还能咋地,批判不够半斤八两?(别忘了 C 之前基本都用汇编写操作系统。) @Macolor21 > Java 不断被喷的原因就是,每一行代码都必须清晰的表达用什么类型,做了什么事情,看起来像个啰嗦老太婆,但实际上每一行代码都特别清晰。 每一行代码都必须清晰的表达用什么类型 × 清晰地自以为是 √ 比如 Java 10 之前死皮赖脸不肯加 var ,因为一些人自以为没声明显式类型就是“不够清晰”(甚至加了之后还有人想反攻倒算的)。 殊不知有的场景的详细设计就明确要求这里对具体类型进行关注点分离,强调符合设计的类型是满足某特定约束的“任意一种”,而 Java 的类型系统甚至还没能力描述清楚 sum type ;还要求写清楚具体类型那就是妥妥地扯可修改性后腿,反过来毒害设计。 这里被喷的主力就是类似这样的脑补他人合理实际需求不存在,又不懂替代解决方法的自以为是的用户。在某些领域,这些用户被称为民科。 (当 Benjamin C. Pierce 都在反思 more typed 是不是 more expressive 的时候,又哪来这些民科误导舆论的空间呢?) > 可能一部分人为了显得自己与众不同,高人一等,所以它们倾向于学习成本更高,看起来更简练的语言。 不巧的是,Java 用户中,这类人相对别的语言的用户特别多。于是对剩下的不少用户来讲,与其一个个纠正,还不如先润为敬,反正就是 JVM 生态也有不少别的替代。这样,黑起来就更容易了,不怕误伤友军。 从一开始就不依赖 Java 的旁观者来看,你们这点破事还是省省的好。非得站队,那自然是优先消灭妄图按闹分配的老古董的,免得还有来不及补课基础不牢靠的死硬分子找到借口反智,故意拎不清楚到底是谁在与众不同。——麻烦记住,没人逼你编程来搅乱市场。 |
239
xsen 2022-05-14 18:56:05 +08:00
@pkupyx #226 go 而言呢
1. 对应届或毕业 1-2 年的新手友好,极易上手 2. 对有多年别的语言经验的切换成本极低,不会有任何难度;单纯就是意愿的问题 所以采用 go 技术栈,对说不上名字的中小微厂来说是极其划算的 |
241
pkupyx 2022-05-15 13:42:23 +08:00
@xsen java 现在同样对新手友好极易上手啊。
而且你一直回避我说的逻辑问题: go 对中小厂好坏得分 = 0 if go 人少,招聘成本高 { 得分 -= 10 // 这是我的逻辑 if 其他语言很容易切到 go { 得分 += 20 // 如果+=5 我认同,但不等于恰恰相反,并且仍然是 go 的劣势。如果你要+=20 那我只能 reject ,先实现思维与价值判断的正确逻辑吧。。。 } } |
242
Aloento 2022-05-15 18:14:02 +08:00
你们在那聊什么托管类语言的代码行数有意义吗?你当你在写 JS 呢?
托管类代码写多少都不重要,重要的是 IL 出来的操作指令数,和实际执行的 CPU 周期 C# 有一个 Bug https://github.com/dotnet/runtime/issues/4207 你写短的代码,ASM 有可能还更长 而且 Java18 才干了一件在.NET 里面干就会被社区炎上的事情 https://openjdk.java.net/jeps/410 然后我才知道 OpenJDK 没有 AOT 和 JIT... |
243
Aloento 2022-05-15 18:21:44 +08:00
而且 OP 你拿一个完全托管类语言( JVM )跟 Native ( Go ,虽然它也有简易 GC )语言比
虽然它们都可以实现同一个需求,但这俩本就不在一个世界里,这不是自讨苦吃和引战么... |
244
Inf1nity 2022-05-15 19:59:29 +08:00
@Aloento #242 JEP 410 只是说移除 Graal 项目引入的实验性 AOT 和 JIT Compiler ,而不是 “OpenJDK 没有 AOT 和 JIT”。OpenJDK 是有 JIT 的,被移除的 AOT Compiler 是 Graal 项目的产物。
|
246
Inf1nity 2022-05-15 22:31:50 +08:00
@Aloento #245 AOT 编译器是 JDK 9 从 Graal 项目中引入的,这些在你之前的回复中提到的 JEP 410 里面讲的很清楚,里面提到了 JDK 的 AOT 编译器是什么时候引入的,又是为什么移除了。
|
247
Aloento 2022-05-16 03:05:57 +08:00
@Inf1nity 学到了,我还以为它也有另外的 AOT ,因为按它那么说 JIT 是有两个,一个是从 Graal 来的,对吧
|
248
mmdsun 2022-05-16 09:08:14 +08:00 via iPhone
go 语言语法最拉了完全比不过 Java 。。
但 C sharp 是比 Java 语法好,首创 async/await 方案被多个语言采纳认可。还有 Rx 扩展库,现在的 Rxjava 和 Java 的反应式编程 Reactor Projects 都是吸纳的.NET 库方案。C#的 Linq 语法,把 SQL 语言都弄成关键字了,select from join 都能直接写代码里面不用字符串引号当然有对应的成链式函数 API 。C#还有各种扩展函数,?空安全这几个都被 kotlin 借鉴去了。 说到 Java 语法,我想说 Java 的事件、接口回调 Java 很麻烦要各种 new 和 setListener 。C#有事件的关键字和类型。+=可以添加删除事件和多播事件。比如: public event EventHandler<EventArgsType> EventName; EventName += (obj, args) => { /* Handler logic */ }; |
249
golangLover 2022-05-16 09:10:47 +08:00 via Android
@aragakiyuii 请问这是什么主题,挺漂亮
|
251
aragakiyuii 2022-05-16 11:37:03 +08:00 1
|
252
dsggnbsp 2022-10-28 11:21:15 +08:00
对对对对对对哈哈哈,学前端的来报道,要 比就比谁早下班呀~
|
253
jinsongzhao 2022-10-28 17:26:57 +08:00
@ColinZeb 拿 kotlin 这些来证明作用不大,java 核心设计团队总是,等社区考验新特性后,把确定成熟的特性加入 java 。这个思路也是 C++使用的。这种完美主义思想导致它们曾经升级非常慢,然后领先的技术慢慢被追上,各种新语言起来了,它们似乎才放弃了完美主义,积极加入新特性,版本升级提速。
|
255
ColinZeb 2022-10-30 20:33:19 +08:00
@jinsongzhao 属性替代 get setter 似乎没有提上日程,这也不是什么实验特性吧
|
256
jinsongzhao 2022-11-05 08:44:11 +08:00
@ColinZeb 手动写 get set ,也是洁癖一种,OO 思想里,通过 get 和 set 方便加入其他操作,于是方便改造老系统,如果只是纯粹为了取值赋值,可以不存在
|
257
ColinZeb 2022-11-07 09:49:48 +08:00
@jinsongzhao 可以不存在为什么 java 里一大堆空 getField setField 方法。
|
258
jinsongzhao 2022-11-14 13:32:01 +08:00
@ColinZeb 因为 OO 思想曾经非常泛滥,曾经到处都在用 24 设计模式,但热潮总会退去,OO 的啰嗦解决的是多人团队开发和后期迭代,但是代码也需要简洁和文档化。个人觉得曾经科班出身和非科班最大区别就是,科班的会用一套 OO 架构设计较大的软件,这样方便团队开发,后期迭代和改造。然而我觉得 Linus 说一句话很对,OO 设计出来架构总能有更好的设计出现,目前还没有完美的 OO 设计,所以他更喜欢 C ,而不是 C++。
|