我先声明啊,我不是来吹捧 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 在 丰富的生态+强大官方库的 加持下,可以更快完成。
101
clownpiece 2022-05-12 14:52:09 +08:00
@lisongeee 那就这样呗,假设项目里有 100 个类都是这样 setter 里有通知变更逻辑的,java 和 kotlin 分别按各自的写法写好了,内部也是正常的通过 setter 修改。 现在新来了一个需求 也要新增 100 个类(这些类的名字和上面 100 个几乎一样,很容易混淆),也是有通知变更逻辑,但是他们都需要有内部修改字段不触发变更的逻辑。
那么 java 和 kotlin 来比较一下大家代码的 diff 量?记得要考虑之后的维护 |
103
AoEiuV020CN 2022-05-12 14:52:52 +08:00
很明显你是把第三库封装起来的行数给无视了,
第三方封装了一千行,你只要一行就能调用,对你来说 java 只要一行就能完成工作,简洁,不啰嗦, 但别人会看到这啰嗦的一千行代码, |
104
lisongeee 2022-05-12 14:54:52 +08:00
@silentsky 那你是否承认 kotlin 语法产生的代码量平均少于 java ?,另外我不应该拿 kotlin 碰瓷高贵的 java 行了吧
|
105
Leviathann 2022-05-12 14:55:39 +08:00
@Buges 快排的精髓在于各种优化,而不是这个基本思想,不然的话干嘛不用归并,稳定且上界低
|
106
Kaiv2 2022-05-12 14:56:54 +08:00
在 Java 8 之前确实是有点费劲。
场景: 用户选择不同支付方式付款 interface IUserService { User find(); } class UserServiceImpl { User find() { } } interface IOrderService { void pay(); } |
107
tomolo 2022-05-12 15:01:36 +08:00
一门语言用成死忠,争着争那的,只能说技术视野太狭窄了
|
108
lisongeee 2022-05-12 15:03:55 +08:00
@clownpiece
https://stackoverflow.com/questions/61459289/how-to-skip-defined-getters-or-setters-in-kotlin 另外人家题主明确说明了《最后来比比 谁的代码少一些。 我敢说,绝对半斤八两,不可能有谁碾压谁的。》 佛了,我说了这么多优点,你是一个都不看呐,光顾着鸡蛋里挑骨头了是吧 和你这种人还有什么讨论的必要呢,你是对的,我是错的,谢谢 |
109
Oktfolio 2022-05-12 15:05:33 +08:00
@lisongeee Kotlin 本来就是解决 Java 甜度不够的问题的,OP 很明细不是来杠 Kotlin 的。Kotlin 对我来说存在 Int 兼容,没有无参构造,Data Class 类和成员是 Final 且没法用注解的问题,虽然可以用 noargs 和 allopen 解决,但总觉得不优雅,所以写 Kotlin ,我依旧会用 Java 来写数据实体类。
|
110
fgwmlhdkkkw 2022-05-12 15:11:09 +08:00
NIO
|
111
lisongeee 2022-05-12 15:11:56 +08:00 1
我发现某些单一语言的程序员都很固步自封,不肯接受新事物,我现在正式承认我是个傻逼,别来和我讨论了,我承认 java 在语法和生态都是最牛逼的语言,任何一门语言和它比都是垃圾,在它的光芒下都暗淡无光。用 java 的人的生活是完美的,只用 java 的人保持了他对 java 的忠贞,我多么想给这些里面的某些人发一个贞节牌坊。此贴终结,java 完胜。
|
113
lisongeee 2022-05-12 15:16:50 +08:00 1
@xiangyuecn
《 js 这样写够简洁了吧: (((json.obj1||{}).obj2||{}).obj3||{}).abc 》 js 其实可以这样写,得益于 js 有 babel 的存在,可以把高版本语法糖转换为低版本语法 json.obj1?.obj2?.obj3?.abc , 如果你想给一个缺省值,还可以 json.obj1?.obj2?.obj3?.abc ?? defaultValue |
114
ychost 2022-05-12 15:18:22 +08:00
@Alexliu 你这个还真的很好解决,有 JSONPath ,无视空指针,
JSONObject origin = JSONObject.parseObject("..."); boolean isEqual = Objects.equals(JSONPath.eval(origin,"$.data.nation"),"印度尼西亚"); |
115
yannxia 2022-05-12 15:18:28 +08:00
@timpaik 因为 go mod 只是一个包管理 ··· Gradle 是一个 Build System ··· 不太好比
|
116
jsdi 2022-05-12 15:18:45 +08:00
一看到这种帖子就知道肯定有人要吵起来😐
|
117
fredli 2022-05-12 15:19:00 +08:00
还不用函数式,我认为就是落伍了,swift kotlin flutter...
|
118
zmal 2022-05-12 15:20:40 +08:00
转自邓草原大佬的说法:
我为什么从 Scala 转回 Java 。1 、Java 已经吸收和实现了大部分类 Scala 的语法,而且还在继续; 2 、Java 的语法虽然没有 Scala 精炼但也更严格些 (也就是没那么灵活),但有成熟 IDE 的帮助,写起来也不慢和少错; 3 、能招到更多的程序员。最后,现在的 Java 已经足够好了,成为各种因素下最均衡的。 |
120
yannxia 2022-05-12 15:22:52 +08:00
@lisongeee 这就是一个月经帖,部分 Java 爱好者 和 Go 爱好者互喷,然后有个轴的人来了开战了,这事情本质上没啥意义,毕竟如果脱糖了,大家没啥区别,爱用啥用啥呗。比较烦那些总是来挑事情的人
|
121
oneisall8955 2022-05-12 15:26:03 +08:00 via Android
天天吵天天吵,后端娱乐圈?
|
122
zmal 2022-05-12 15:26:09 +08:00
即使新出的语言比发展了几十年的语言更优秀一些也很正常,世界在进步嘛。
不过语法糖这个东西,并不是越多越香。开发一时爽,维护火葬场。要不要加糖是一种取舍。 |
123
storyxc 2022-05-12 15:26:34 +08:00
此贴有望热榜 top1
|
124
lisongeee 2022-05-12 15:26:44 +08:00
@Oktfolio
《 Data Class 类和成员是 Final 且没法用注解的问题》 1.Data Class 类和成员是 Final 这我知道,但是 data class 只是自动重写了一些方法而已,想继承不用就行了 2.没法用注解的问题 dataclass 不能用注解吗?,我现在就是一直在用啊 这有个例子 https://developer.android.google.cn/training/data-storage/room?hl=zh-cn#data-entity |
125
yaott2020 2022-05-12 15:27:16 +08:00 via Android 1
外个楼,我不用 java 而用 golang 的原因只是因为需要安装 java 环境才能运行 java 代码,golang 编译出来就是二进制文件
|
126
fredli 2022-05-12 15:33:11 +08:00
|
127
J2ephyr 2022-05-12 15:35:44 +08:00
来说一下关于我的瓜吧。1.首先谢谢大家对这件事情的关心。我事先根本没有想到会这样既然已经出这件事情了,那我不如直接讲清楚吧。也不是博得大家的同情什么的,只是回应一下。2.那人所发出来的聊天记录、照片、视频、甚至那些亲昵称呼都是真的,无一造假。可我从未将这些东西流传在任何网络平台上面,至于那个人是怎么有的,我也不清楚。3.虽然这事出了,但我没有不尊重任何人,我不认为我有错,所以我不会认错。4.最后,想知道到底发生了什么的,转我 88 肯德基疯狂星期四,我把故事从头到尾给你编一遍
|
128
libook 2022-05-12 15:39:29 +08:00 1
我不参与,我就吃瓜,另外可以考虑开个 git repo ,每种需求每种技术栈的实现方案可以 pr ,然后收集起来。
|
129
Leviathann 2022-05-12 15:40:24 +08:00
|
130
Leviathann 2022-05-12 15:41:55 +08:00
@fredli 看错了 好像不是 kotlin 无视第一句吧
|
131
0312birdzhang 2022-05-12 15:44:00 +08:00 1
@frisktale 1 行
Microsoft Windows [版本 10.0.22000.675] (c) Microsoft Corporation 。保留所有权利。 F:\Program Files\Java\jdk-11.0.2\bin>.\jshell.exe | 欢迎使用 JShell -- 版本 11.0.2 | 要大致了解该版本, 请键入: /help intro jshell> System.out.println("Hello World"); Hello World jshell> |
133
LeegoYih 2022-05-12 16:04:06 +08:00 2
@fredli
userList.stream() .peek(u -> u.setLocation("sh")) .filter(u -> u.getAge() > 50) .map(User::getId) .toList(); |
134
oneisall8955 2022-05-12 16:07:45 +08:00
@Alexliu #16
@aragakiyuii #65 @ychost #114 仅仅 Jackson 也可以,性能未知,at 这个 api ,路径写法用 /xxx 开头,不像 JSONPath 的 $.xxx 好看吧 ![]( https://cdn.liuzhicong.cn/img/20220512160406.png) |
135
justin2018 2022-05-12 16:10:31 +08:00 1
学了 2 个月的 Java 喜欢这种“啰嗦”的语言
写前端 感觉“累” 可能我是菜鸡~~ 在逃避它~~~ o(╥﹏╥)o |
137
yohole 2022-05-12 16:13:35 +08:00 4
为楼主这种实践出真知的精神点赞,看到太多人贬低或者批判一个语言,多数都是停留在嘴炮,但是一旦到了上代码和需求的,都是不见人,不管怎样,这种精神和有理有据的回复点赞
|
138
zzl22100048 2022-05-12 16:17:34 +08:00
@xiangyuecn json?.obj1?.obj2?.obj3 js 可以这样取,java 也可以用 optional 取
|
139
sky857412 2022-05-12 16:17:51 +08:00
@lisongeee 无语了,封装性为什么不能违反?这只是一个中规范建议,明明可以简单解决,非要加个变量,然后再去维护一个变量的值?
|
140
cnbatch 2022-05-12 16:18:01 +08:00
@LotusChuan 不止语言宗教战争,还有框架宗教战争、IDE 宗教战争、操作系统宗教战争、许可证宗教战争。
v 站稍微好一点,只是用户自发聊起来。 某个 O 开头的开源资讯站(同时也是国内 git 托管公司)那边就不一样了,是由内部员工亲自发起这类宗教大战,不止发布开源软件新闻、行业新闻时会有意无意地这样做,甚至会以编辑部的名义亲自撰写这类大战文章,生怕没人吵架带不来流量。我原本打算单独发贴说 oschina 的事情的,结果刚发出来没多久就被一个疑似 o 站的员工 at 了下站长,要站长转水。于是我索性自己移到“水”算了,免得以后被人搞针对。接下来我特意搜了下,原来 o 站在这里有专门的官方号,不知道是不是相互有合作,所以不让说。 |
141
luqingliang 2022-05-12 16:20:26 +08:00
兄弟们,冲!
|
143
Nicklove 2022-05-12 16:28:30 +08:00
你有运行时
|
144
aliensb 2022-05-12 16:30:21 +08:00
接 OP 的代码说一下
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 会一直执行下去,但是 java 中任意一个 function 异常了就会直接走到 catch 块中去了 |
145
yazinnnn 2022-05-12 16:31:12 +08:00
能不能多回一些建设性的贴子....
|
146
sky857412 2022-05-12 16:41:58 +08:00 1
居然有些菜逼踩 spring ,至少围绕 spring 这个生态,大家玩的很开心。vertx 就从来没人吵,vertx 性能比 spring 好,不还是用的人很少。
|
147
sky857412 2022-05-12 16:47:39 +08:00
@lisongeee jetbrains 限制了再 setter 方法中写通知了?
封装性是指一种将抽象性函式接口的实现细节部分包装、隐藏起来的方法。这个跟 setter 方法有什么关系? |
148
sciel 2022-05-12 16:48:20 +08:00
我想看一下,java ,nodejs ,python ,php 实现下面的这个方法,可以吗 ^_^
``` // 获取接口数据 接口超时 3 秒,超时后重试 5 次 , 成功则获取返回状态为 0 和 1 时的数据 /* 接口返回数据格式 { "code":0 // -1 失败 0 成功 1 预警 "msg":"" "data":{} } */ func (s *rss) fetchData(ctx context.Context, url string) (*gjson.Json, error) { num, max := 0, 5 retry: d, err := gclient.New().Timeout(time.Second*3).Get(ctx, url) if err != nil { num++ if num > max { return nil, errors.New(fmt.Sprintf("获取数据失败,已重试%d 次,请稍后重试", max)) } glog.Infof(ctx, "获取失败,重试中...%d", num) goto retry } 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("获取数据失败,请稍后重试") } } ``` |
149
anonydmer 2022-05-12 16:49:28 +08:00
不知道我一个工作中既用 java 也用 go 的进来凑什么热闹
|
153
122006 2022-05-12 17:01:24 +08:00
来试试我的 java 语法糖,模板字符串,https://github.com/122006/Zircon
|
155
Leviathann 2022-05-12 17:03:38 +08:00
@sciel 这不就是 labeled break
|
156
Suntz 2022-05-12 17:09:15 +08:00 1
切莫眼高手低踩一捧一,编程语言本质上就是一门工具,程序员生来就是解决需求的,任何技术都不分高低贵贱,任何一门技术都有他所适合的应用场景
|
157
ychost 2022-05-12 17:12:46 +08:00
@oneisall8955 FastJSON 的 JSONPath https://github.com/alibaba/fastjson/wiki/JSONPath
当然如果了解 Groovy 4.0 目前也有 GINQ 了(对比 C# 的 Linq ) |
158
danhahaha 2022-05-12 17:15:47 +08:00
得了吧,大部分人还在乎多写几个字符?不就是 ctrl+c, ctrl+v 么
茴香的茴怎么写最快?来辩论下? |
159
chenyu0532 2022-05-12 17:16:55 +08:00
本来以为前端是娱乐圈,后端也要慢慢向前端发展么。
麻烦你们尊重下楼主好不好,不服的跟楼主 battle 啊,piapia 打他脸啊,开新帖子啊。 |
160
Uplay 2022-05-12 17:17:09 +08:00
摸鱼时最开心看到这种东东了,悄悄说一句 kotlin 好爽
|
161
122006 2022-05-12 17:23:20 +08:00 1
快下班了摸摸鱼,来试试我的 java 语法糖
[模板字符串],0 侵入接入已有项目,和其他语言的模板字符串比更加强大。 java 有什么不好的地方,与其怨天尤人,不如自己写语法糖接入就行了啊,多大点事。 原生是不支持模板字符串的,动辄一堆加号和 format 看起来就很乱,这个库引入了模板字符串的写法。 项目地址:github.com/122006/Zircon 欢迎 star |
162
crazycarry 2022-05-12 17:26:19 +08:00
这么菜怎么有脸问这个问题。
|
163
Chinsung 2022-05-12 17:33:19 +08:00
其实一般用 Kotlin 的真没啥好喷 Java 的,我把所有你觉得复杂的语法写法功能写一个类只提供一个函数做到,不也简洁了? Kotlin 就是 Java 的糖衣。
其实我发现拿语法喷 Java 的,写 Go 的很多 另外,都 21 世纪了,有 IDE 的辅助,除非某个语言对某个模式或者某种实现达到了毁灭性的不支持,否则你按下回车出来的是 10 个字符还有 20 个字符,差距很大吗? |
164
clf 2022-05-12 17:56:11 +08:00
我现在是 kotlin 和 java 都用,当然主要是开发 Web 或者 IDEA 插件 或者 android app 。
偶尔还写前端的 js/ts 。 写小工具一般用 python 。 像 go 、R 、php 等等都有涉猎,合适的场景选择合适的语言就行了,这是程序员应该有的基本能力。 |
165
Nazz 2022-05-12 18:01:44 +08:00
java 没有匿名函数, 没有裸函数
|
166
fanxasy 2022-05-12 18:10:57 +08:00
塔塔开!(偷偷顶一顶 kotlin 和 c#)
|
167
cmdOptionKana 2022-05-12 18:25:20 +08:00
Go 把一个函数直接当作参数喂给另一个函数(即 higher order function )是很常见的操作,这在 Java 里一般怎么做?
|
168
Mexion 2022-05-12 18:31:41 +08:00
@xiangyuecn js 读取不是这样吗? json?.obj1?.obj2?.obj3?.abc
|
172
micean 2022-05-12 18:47:51 +08:00
java 的生命力真强,已经没有人为 php 争吵了
|
173
ojh 2022-05-12 18:55:24 +08:00
@cmdOptionKana 在 Java 叫函数式接口,简化一下就是 lamda 了,顺便问下 Go 有尾随闭包吗,多尾随闭包呢(开玩笑)
|
174
spicecch 2022-05-12 19:03:59 +08:00
莫多莫多!
|
175
TAFMT 2022-05-12 19:04:47 +08:00
来吃个瓜👀
|
176
james122333 2022-05-12 19:22:54 +08:00
@Joker123456789
"字数上相差多少,我是懒得数了,但是你们真的不觉得 java 的结构更清晰吗? 其他的继承,多态 我就不拿出来说了,go 基本上是 用的 c 的编程思想,oop 只是个兼容, 所以用 java 来跟他比 oop 没什么可比性。因为是两个方向。" => 没觉得比较清晰 java 是 field 与 method 混在一起 东西多了会很乱 go 的反而清晰多了 "但是 go 需要用 defer ,而且一旦抛出异常就意味着这个函数结束了,你如果想在出异常后,处理一下 然后继续往下走,go 会非常的麻烦。" => 你封装一个函数以后都用那个函数 以结果来讲一模一样 封装也不麻烦 而且还不用注意哪些要抛出哪些不用 "// 不管装箱前是什么,只要他的值是一个整数 // 无论是 1 , 还是 "1", 都可以这么转" => 你用了 Integer.parseInt 然而你 go 自己写个函数里面 switch type 判断是更佳的 如果你确定就是 int 那直接转就可以 |
177
xsen 2022-05-12 19:25:02 +08:00 2
如何把一段简单的代码变复杂?
https://www.zhihu.com/question/277243683/answer/393676961 换个人话的说话就是,Java 为什么越来越啰嗦、越来越重——过度设计 —————————————————————————————— 作者:Damon DanceForMe 链接: https://www.zhihu.com/question/277243683/answer/393676961 来源:知乎 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 这问题你应该去问企业级 Java 架构师。就比如 print 一句 hello world 吧。main 函数里 print 一下?太面向过程,太 low 了。得封装一个类。叫 Printer. Printer 有个成员方法,叫 print 。但是!光一个类太 low 了,以后要是有不同的实现怎么办?所以得加一个接口。PrinterInterface 。但是! interface 是没有实现的,还是要有默认实现才行。所以得加个虚拟类,AbstractPrinter 实现 PrinterInterface ,然后 Printer 继承 AbstractPrinter 。但是!你有了那么一套,该怎么创建实例呢?直接 new Printer()?太 low 了,那叫实现依赖。肯定不行的,所以要搞一个工厂类,PrinterFactory ,PrinterFactory 用 PrinterInterface 返回实例,这样就隐藏了实现细节了。但是! PrinterFactory 本身也是实现类啊,太 low 了,所以得有 PrinterFactoryInterface, AbstractPrinterFactory. 而且在 PrinterFactory 里面该怎么写呢?直接 new Printer()? 太 low 了。还是实现依赖。最后,你要把这一堆玩意在代码里组装起来,也太难看了,各种 new 实现类。太 low !好在我们有个高级玩意,叫依赖注入!把程序对象结构全写到配置文件里面。这一套当然是不能自己造轮子的。配置 Spring 吧。搞了那么多 lib ,靠命令行或者 IDE 的项目管理肯定不够啊,得有依赖管理。Maven 啊 Gradle 啊使劲上。最最后,要 print 的东西怎么传给程序呢?硬编码?命令行传参数?太 low !当然得写在 XML 里头。光是 XML 当然还不够企业级,再加上 DTD 验证吧。然后就涉及到了 XML 解析的问题了。代码里直接操起 parser 吗?太 low! 当然要写个 parser 的包装类,interface, abstract class, implementation class, factory class 再来一套。毕竟,不能依赖实现啊,以后我要是换 parser 了怎么办。所以最后是成品是一堆配置文件,一堆 jar ,compile 出来的程序 200MB 。IDE 得装上 300 个插件,打开项目硬盘响老半天吃掉 2GB 内存,然后一堆插件弹提示要求升级。哦对了,在这一切发生之前,还得画 UML 图呢。三年后项目完工了,部署到客户的服务器上一跑,立马崩溃,一地的 stack trace 。原来客户服务器上用的是 JDK 5 而新项目需要 JDK 6. 然后问客户你们不能升级吗,答案是不行,因为另外一个企业级开发组给做的企业级解决方案只支持 JDK 5 。接着客户把你们的架构师臭骂了一顿,你搞了那么多设计就没有想过可能会换 JDK 吗? |
178
james122333 2022-05-12 19:48:57 +08:00
@Macolor21
因为类型所以全代码都很清晰?... 类型清晰了但代码乱在其他也没用... 而且 go 也是类型 go 主要是比较容易强迫你写出比较工整的代码 外加语法简单 这样来讲就是更清晰 我都写 java 但很多 javaer 其实就习惯了 满足于现状 不能意识到这堆山堆的有多高 如果没有网路资源 又要花多少时间除错... |
179
ychost 2022-05-12 20:07:32 +08:00
@sciel java 也有 label 语法不过只能用在 break 不能 goto (有语法,没实现),goto 设计上并不优雅,建议用闭包好点
|
181
luzemin 2022-05-12 20:22:55 +08:00
|
182
lbp0200 2022-05-12 20:29:27 +08:00
启动 50 万个工作者 worker ,也不用干什么,内存不爆就可以
go 和 kotlin 很简单,Python 比较麻烦,Java 看水平 func TestName2(t *testing.T) { for i := 0; i < 500000; i++ { go func(index int) { fmt.Println(index) for { time.Sleep(time.Second) } }(i) } select {} } |
183
bybyte 2022-05-12 20:31:34 +08:00
吃瓜,留个位置
|
184
eote 2022-05-12 20:51:27 +08:00
@lbp0200
void testName2() { IntStream.range(0, 50000).forEach(i -> new Thread(() -> { System.out.println(i); for (;;) { try { Thread.sleep(1); } catch (InterruptedException ignored) {} } })); } |
185
eote 2022-05-12 20:52:11 +08:00
@lbp0200 更正
void testName2() { IntStream.range(0, 50000).forEach(i -> new Thread(() -> { System.out.println(i); for (;;) { try { Thread.sleep(1); } catch (InterruptedException ignored) {} } }).start()); } |
186
cocong 2022-05-12 21:01:42 +08:00 2
代码写得再漂亮,也无法摸出业务的复杂性。
在复杂业务逻辑下,哪种语言写出来的代码都一样。 与其纠结代码优雅,不如思考如何简化业务。 |
187
Seanfuck 2022-05-12 21:01:43 +08:00
居然还有想挑战 php 的,php 不用写一个 import 或 class 或 function 就能快速达成目标,而且还不用开笨重编辑器,不用编译。
|
188
ikas 2022-05-12 21:26:06 +08:00
贴一个目前在用的 java 脚本..更新 mc 服务器的 ipv6 地址到 hosts
利用 git 推送 ipv6 地址到 github,然后其它机器同步写入 host UpdateIp.java ----------------------- import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; public class UpdateIp { public static void main(String[] args) throws IOException { var hosts = Paths.get("C:\\Windows\\System32\\drivers\\etc\\hosts"); var lines = Files.readAllLines(hosts, StandardCharsets.US_ASCII); lines.removeIf(line -> line.endsWith("#yuki-mc-server")); var ip = Files.readString(Paths.get("your-ip\\ip"), StandardCharsets.UTF_8); lines.add("%s yuki-mc #yuki-mc-server".formatted(ip)); Files.write(hosts, lines, StandardCharsets.US_ASCII, StandardOpenOption.TRUNCATE_EXISTING); } } update-ip.bat ----------------------- cd your-ip git pull cd.. java UpdateIp.java |
190
agileago 2022-05-12 21:56:20 +08:00
@sciel 来个 js 版的
<script src="https://gist.github.com/agileago/b96cb1e5c52a66f75b093c8dd3ffd337.js"></script> |
191
zhuangzhuang1988 2022-05-12 22:35:14 +08:00 3
给 Java 说句公道话
http://www.yinwang.org/blog-cn/2016/01/18/java |
194
sciel 2022-05-13 00:17:54 +08:00 via iPhone
@Seanfuck 可以写一个,从来没用过 php,如果不错,后面去探索一下,我知道一个很厉害的大神也是用 php
|
195
Guaidaodl 2022-05-13 00:26:46 +08:00
@clownpiece 其实 Kotlin 的 Property 可以变成 Java 的 Field, 加一个 @JvmField 的 Annotation 就行. 你说的对内部调用不走 setter 很容易实现的. 在绝大多数情况下, 内部调用 setter 都是正确地做法. 少数特例也很容易实现.
另外 Java 也在积极吸收 Kotlin 语法, record 了解一下. |
197
pkupyx 2022-05-13 01:20:57 +08:00
语法层面的比较其实没意义,核心还是生态。
java 的优势是 web 工程和 android 生态太好了。 国内除了超大厂敢上 go ,flutter 之类的,中小厂这么玩很容易坑自己。轮子少,招人难,遇到问题也不容易 google 到。 |
199
xsen 2022-05-13 07:43:17 +08:00
@pkupyx #197 恰恰相反,你不知道的是:
很多连中小厂都算不上的中小企业,很多还是传统行业的,都在选择用 go 这个技术栈 人是难找,轮子是少,但是, 1. 别的语言转 go 容易,有经验的 2 周左右;刚毕业 1-2 年的 1-2 个月左右 2. 大多数轮子都有。部分轮子自己造——不能造,反正都面向接口、服务变成,换 Java 写个服务也不是那么难 |
200
sciel 2022-05-13 07:51:25 +08:00
@agileago 仔细看一下 request 方法定义的 i ,和 isRetry,不太能直接看出其用意吧,
while 里面 else 每次都给 i 重新赋值 5 可能会造成死循环 41 行 res.code res 也可能会 undefined ,应该先判断一下 res 哇 getData 里面 没有实际发出 http 请求。。 |