TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

One year after switching from Java to Go

257 点作者 pmig3 个月前

44 条评论

time4tea3 个月前
The jvm is a pretty insane beast. It will do usage based recompilation, escape analysis for memory, so non heap allocation is super fast, has great memory safety... But a lot of people use it with spring&#x2F;spring boot, a technology designed to work around the complexities of a particular type of middleware software in the late 90s and early 2000s. It&#x27;s cargo cult programming of the highest order. In the OP, the author is comparing apples with oranges, with a bit of misunderstanding that java&#x2F;jvm means spring boot, and while that is true for a lot of people and certainly a lot of stuff on the internet implies that &#x27;this is the way&#x27;, it&#x27;s not required. Startup times of ~100ms are absolutely standard for a big program, similarly unit tests taking 1ms. I prefer to write kotlin rather than java, as it&#x27;s a nicer language ,IMHO, but still those bytecodes run on Jvm and same stuff applies.<p>Edit: im not advocating writing &#x27;ls&#x27; in java, and I would also agree that java uses more memory for small programs, so its not a systems programming language probably.<p>Just use new() it&#x27;s pretty fast.
评论 #43101034 未加载
评论 #43100330 未加载
评论 #43100071 未加载
评论 #43101914 未加载
评论 #43099935 未加载
评论 #43100562 未加载
评论 #43102326 未加载
评论 #43143349 未加载
评论 #43102666 未加载
评论 #43101071 未加载
评论 #43101189 未加载
评论 #43099426 未加载
bryancoxwell3 个月前
&gt; But there are obviously work around solutions in the Go ecosystem. It uses the Context ctx, which we pass around functions in order to juggle data around in the application.<p>Man. This works. The context API allows&#x2F;enables it. But I’d really recommend against passing data to functions via context. The biggest selling point of Go to me is that I can usually just look at anyone’s code and know what it’s doing, but this breaks down when data is hidden inside a context. Dependency injection is entirely possible without using the context package at all, interfaces are great for it.
评论 #43096604 未加载
评论 #43096796 未加载
评论 #43096956 未加载
评论 #43098179 未加载
评论 #43099616 未加载
评论 #43097757 未加载
评论 #43099625 未加载
评论 #43098205 未加载
philipwhiuk3 个月前
As a Java developer...<p>If the entire problem domain space is written in a language it&#x27;s dumb not to follow suit. Libraries that solve problems reduce your work to your own specific issues, rather than &#x27;building an apple pie from scratch&#x27;.<p>Java is good right now because most problems have libraries to do what you want. Most formats have APIs.<p>It&#x27;s not perfect in any area - the start-up time is a bit lame, you have to write &#x27;anti-Java&#x27; to really get close to native performance. But it&#x27;s quick to build in, the toolchain is solid, the dependency framework works better than all the alternatives. It&#x27;s a 95% language that&#x27;s been made development friendly.<p>(Golang somehow added versioning late and is &#x27;Git+&#x27; at best, NPM unpublished stuff, C++ is hell, etc. Rust crates just doesn&#x27;t have much but seems to have been built properly).<p>But if you&#x27;re working in a new space (crypto, AI, cloud) then you should definitely look at what the state-of-the-art libraries are written in.<p>And you should think <i>real hard</i> before you implement your app in anything else. Because there will be a real, long term, painful penalty unless you get VERY lucky and the entire ecosystem pivots to your language.
评论 #43097402 未加载
评论 #43099533 未加载
评论 #43098224 未加载
pjmlp3 个月前
This looks like one of the typical <i>&quot;we switched from A to B, whithout actually mastering A, so B is alright&quot;</i> kind of posts.<p>Just on the monitoring part, Go has nothing even close to VisualVM, Flight Recorder, JRebel, VM agents, JMX.<p>No mention of AOT compilers, JIT caches, and so forth.
评论 #43100755 未加载
评论 #43099839 未加载
评论 #43101164 未加载
评论 #43100882 未加载
评论 #43099850 未加载
评论 #43101267 未加载
评论 #43102655 未加载
评论 #43101355 未加载
评论 #43102589 未加载
owlstuffing3 个月前
Going back to first principles, nominal typing is what I miss most with Go. I get the utility of structs + interfaces + structural typing, but most of the time there is more benefit in declaring that a type nominally implements an interface when that is the intention. Code is far easier to read and understand that way, both for developers and tooling.<p>I suppose exclusively structural typing would be more acceptable if Go supported _real_ interface composition, like Scala with traits or true delegation via the manifold project[1] for Java. But that&#x27;s missing as well e.g., does not inherently fix the Self problem, etc.<p>Considering Go&#x27;s initial goal, which was IIRC a better systems language, then yeah, sure it&#x27;s an improved C. But now that Go is routinely compared with Java&#x2F;Kotlin and friends, I personally don&#x27;t see it, particularly wrt the type system, to be taken seriously as a Java contender. Shrug.<p>1. <a href="https:&#x2F;&#x2F;github.com&#x2F;manifold-systems&#x2F;manifold&#x2F;blob&#x2F;master&#x2F;manifold-deps-parent&#x2F;manifold-delegation&#x2F;README.md">https:&#x2F;&#x2F;github.com&#x2F;manifold-systems&#x2F;manifold&#x2F;blob&#x2F;master&#x2F;man...</a>
评论 #43097336 未加载
评论 #43100109 未加载
评论 #43100050 未加载
评论 #43098207 未加载
heluser3 个月前
I long for a deep article about the same topic. The real, core difference between Java and Go for backend is declarative vs imperative coding styles.<p>This one, as typical for such articles, repeats typical secondary talking points and even makes similar mistakes. For example it conflates the concept of DI with specifics of implementation in some frameworks.<p>Yes there are older Java frameworks that do runtime magic. But both new Java apps and well designed Go services use compile time dependency injection as a way of achieving dependency inversion.
评论 #43096495 未加载
评论 #43098968 未加载
blindriver3 个月前
I&#x27;ve been using Go for a while now. The biggest headache is error handling. I don&#x27;t care what the &quot;experts&quot; say, having exception handling is so, so, so much cleaner in terms of error handling. Checking for err is simply bad, and trickling errors back up the call stack is one of the dumbest experiences in programming I&#x27;ve endured in multi-decades. If they are willing to add generics, they should add exception handling as well.
评论 #43097025 未加载
评论 #43097105 未加载
评论 #43098949 未加载
评论 #43097710 未加载
ed_blackburn3 个月前
The real win for this team isn’t just switching from Java to Go. It’s breaking free from the heavyweight framework ecosystem that the JVM all but forces on you.<p>It’s not that the JVM is bad or that Go is a silver bullet, but Go does act as a forcing function, pushing teams to write simpler, more efficient code without layers of boilerplate, indirection, and unnecessary IO.<p>You can still do inversion of control without an IoC container—instantiation works just fine! Look at Go’s HTTP middleware pattern with structural typing and first-class functions. No config files, no annotation magic, just composition, testability, and code small enough to hold in your head.
评论 #43099997 未加载
评论 #43100954 未加载
评论 #43100043 未加载
评论 #43101873 未加载
评论 #43100230 未加载
评论 #43100886 未加载
codr73 个月前
I&#x27;m pretty fond of Java; it&#x27;s definitely a superior language to Go if you ask me, which I&#x27;ve also written a ton of code in.<p>But I stay away from Spring Boot, end the entire EE stack of crap that came before it, if at all possible.<p>I&#x27;ve had more success adding whatever I need on top of embedded Jetty.<p>It&#x27;s mostly a cultural problem, no one is forcing you to go the AdapterFacadeInjectionBuilderWhatever way.<p>I&#x27;ve been working on a library to simplify interfacing with relational databases for a while now. With several implementations in Go and other languages. And the java version looks at least as nice as the rest to my eyes:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;codr7&#x2F;tyred-java">https:&#x2F;&#x2F;github.com&#x2F;codr7&#x2F;tyred-java</a>
评论 #43098280 未加载
评论 #43097654 未加载
MarkMarine3 个月前
I work with a brownfield go monorepo with a couple different styles and lesser known “frameworks” in it. It sucks to work in, one of the previous devs was a huge fan of clean code, so every function with more than a couple inputs has its own struct, pointers are used everywhere just by default (and basically never nil checked) and the AI generated tests are so plentiful that changing a small thing quickly explodes into thousands of lines in of changes.<p>Because it’s go and not really following a framework or pattern, the LLMs just can’t get the style right, so everything is brute force. Know what is easy to build with an LLM? A spring boot app. You can work on the hard logic while your little automated friend works on all the boiler plate and wiring.
评论 #43098910 未加载
epolanski3 个月前
Very ignorant about Go, is dependency injection not a thing there?<p>E.g. I like declaring interfaces in other languages that model some service (e.g. the database), focus on the API, and then be able to provide different implementations that may use completely different technologies behind them.<p>I know that some people don&#x27;t see the point, but I&#x27;ll make an example. At my primary client the database layer is abstracted and provided at runtime (or compile time, depends) with the repository pattern. How&#x27;s that useful? Developers can use a filesystem-based database when working, and don&#x27;t need to setup docker images that provide databases, anything they do is saved on their machine&#x27;s filesystem. E2Es can run against an in-memory database, which makes it very simple to parallelise tons of different tests as there are no race conditions. And yes, the saved formats are the same and can be imported in the other databases, which is very useful for debugging (you can dump the prod database data you need and run it against your implementation).<p>There&#x27;s many other situations where this is useful, one of the core products I work on interfaces with different printing systems. Developers don&#x27;t have printers at home and my clients have different printing networks. Again, abstracting all of it through DI makes for a very sane and scalable experience.<p>I don&#x27;t see how can this be achieved as easily without DI. It&#x27;s a very nice tool for many use cases.
评论 #43096738 未加载
评论 #43096799 未加载
评论 #43097708 未加载
评论 #43096998 未加载
评论 #43096619 未加载
评论 #43096645 未加载
deepsun3 个月前
Seems like they wrote slow memory hogging software and didn&#x27;t make any attempt at optimizing it.<p>E.g. there&#x27;s no mention of AOT compilation for Java. No hints at what actually consumed 2GB of RAM.<p>Greenfield projects are always more fun.
评论 #43097767 未加载
TheCycoONE3 个月前
We run mostly Java apps with a few Go apps. What I miss with Go, maybe just because I&#x27;m not as familiar and don&#x27;t know where to look, is all the runtime analysis that&#x27;s built in. Thread dumps, heap dumps, and even flight recorder profiling is all built in to the JVM so it works with all apps everywhere. When a Go app suddenly slows down it&#x27;s very difficult to determine why unless the app was coded to provide the right metrics.
评论 #43097850 未加载
DeathArrow3 个月前
I am sure Go has many benefits, but coming from .NET I don&#x27;t see a big improvement in switching to Go.<p>.NET feels less verbose, it&#x27;s batteries included, has an AOT compiler, tons of libraries, starts fast, has very good tooling and performance wise it compares well to Go. Also, it can be used for more than web apps and command line tools.<p>Where I see a benefit, though, is using go in a large greenfield project because Go is very easy to learn and you can attract Java, .NET, Python, Javascript and even C and C++ developers so you can assemble a team fast.<p>Though in a microservice context it might not be a large benefit.
评论 #43101104 未加载
jayd163 个月前
Is it wrong that I judge anyone that calls DI &quot;black magic&quot;? Clearly it&#x27;s just computers all the way down and even spring DI isn&#x27;t that hard to follow.<p>It&#x27;s one thing to call it bloated or annoying or tedious but why are we proud to announce we didn&#x27;t do the work to figure it out?
评论 #43100863 未加载
评论 #43099537 未加载
evil-olive3 个月前
it&#x27;s really weird to see a &quot;Dependency Injection &amp; Context&quot; section as if Golang&#x27;s context has anything at all to do with DI.<p>in particular, reading between the lines here:<p>&gt; But there are obviously work around solutions in the Go ecosystem. It uses the Context ctx, which we pass around functions in order to juggle data around in the application.<p>suggests to me that they&#x27;ve implemented one of the Golang anti-patterns that I find most annoying - overloading the context and using it as &quot;grab bag of pseudo-global variables&quot;<p>in this anti-pattern, you have an HTTP request handler, and want to make a database query, so you need access to the database connection pool. having a global variable for the connection pool feels wrong...so what many people do instead is call context.WithValue in their server startup code to put the connection pool into the grab bag, and then in the request handler call ctx.Value to pull the connection pool out of the grab bag.<p>the Golang docs [0] explicitly say not to do this:<p>&gt; Use context Values only for request-scoped data<p>the much better way, in my experience, is to make the request handler a method on a struct, and then the struct holds references to things like the connection pool. this can also be done with closures and captured variables, of course, but that tends to get unwieldy for non-trivial usage.<p>if you do this, then your &quot;dependency injection&quot; in Golang tends to look pretty much identical to how it would look in Java, if you wired everything up by hand rather than using a framework&#x2F;library. and then if you want, you can use a library such as Fx [1] for automatic Dependency Injection along the lines of Spring Boot.<p>0: <a href="https:&#x2F;&#x2F;pkg.go.dev&#x2F;context#WithValue" rel="nofollow">https:&#x2F;&#x2F;pkg.go.dev&#x2F;context#WithValue</a><p>1: <a href="https:&#x2F;&#x2F;github.com&#x2F;uber-go&#x2F;fx">https:&#x2F;&#x2F;github.com&#x2F;uber-go&#x2F;fx</a>
评论 #43097121 未加载
ninetyninenine3 个月前
God I hate working with Java developers on go projects. They try to introduce “design patterns” into the whole ecosystem and twist golang into doing something it wasn’t designed to do.<p>It’s a bit too late because tons of golang libraries are like this now.
staticelf3 个月前
I work at a company that is based on a large java application. The main app takes around 20-30 seconds to startup and while it probably does a lot of stupid shit that have accumulated over the years I believe this is more common in javaland.<p>The culture around java is kind of enterprise, do everything unnecessary complex with strange patterns you&#x27;ve never heard of etc etc which makes the everything unnecessary slow and complex. Where as other languages like node or go small libraries is the culture so it&#x27;s not weird that it is what it is. I have many times suggested to use simpler tools or frameworks like Javalin but to no avail. Java devs love their spring.<p>Instead of just doing the thing you want to to, with java devs, you have to follow pattern that makes you create a several classes and interfaces when in reality it could be a couple of lines.
评论 #43101648 未加载
DrScientist3 个月前
Never quite understood the attraction of dependency injection frameworks.<p>Sure pass in your dependencies as an interface via some sort of constructor, but why all the frameworks to do so?<p>Why all the complexity with hard to debug magic strings, annotations and finding out what&#x27;s missing from the classpath at runtime?<p>Just seems as a very complicated way to avoid creating package c that brings together package a and dependency b in a simple class that creates b and passes it into a.<p>What am I missing?
评论 #43113106 未加载
评论 #43100842 未加载
评论 #43102999 未加载
评论 #43100728 未加载
blibble3 个月前
seems to be mostly criticism of spring rather than java<p>the company behind spring should ruin go by porting their crappy library to it<p>(oh look, it&#x27;s broadcom....)
评论 #43096565 未加载
评论 #43097365 未加载
darkhorse2223 个月前
I have never been able to rid myself of my earlier career instincts that people who spend time debating the pros and cons of languages are not really builders. I am a computer engineer, I have very little respect for coding languages since ultimately they always come down to the same fundamental computing mechanisms: processors and memory.<p>Perhaps when efficiency is needed I can understand. But most of the time seeking efficiency is yet another non-builder priority. I have always found efficiency comes from good thought, not good tooling.
pseudoramble3 个月前
I’ve been out of the Java scene for a really long time, but will be coming back to it soon. I’m curious - these performance issues described here, are they inherit to how Java itself? Is it baggage from Spring&#x2F;Boot? Are there ways to get more bang for the buck with some careful choices in a system like this?<p>The closest I’ve done to Java recently is C#, which I think may have similar challenges, but overall didn’t seem quite as bad if you avoided lots of framework extras. It also wasn’t something I was digging into deeply though, so perhaps I’m mistaken.
评论 #43096314 未加载
评论 #43096318 未加载
评论 #43096295 未加载
评论 #43100389 未加载
评论 #43096420 未加载
评论 #43096427 未加载
pshirshov3 个月前
1) There is a perfectly working AOT compiler for JVM, namely Graal Native. Sub-second startup times are easily achieavble. 2) Dependency Injection does not require run-time reflection, I made one reflectionless DI for Scala and one for C# 3) Spring is not the best DI in the Java ecosystem
评论 #43101488 未加载
mrbonner3 个月前
Start up time of the JVM is 8s? I would definitely say that it depends on how their service initialization work. I have seen service accesses database to warm cache, calling other services to initialize their configuration, or simply reading config files before fully serving. And all that take time! There is no way against that regardless of your PL or runtime.<p>A typical no network initialized service in Java would start under 500ms (a p90, give or take).
anthonybsd3 个月前
Larger than 2GB RAM JVM containers? It sounds like the author didn&#x27;t really explore any of modern container-ready frameworks and blamed the ecosystem. Move from Spring Boot -&gt; Micronaut or Quarkus and compile your code into into GraalVM image and you get sub-100MB containers.
cs02rm03 个月前
I really liked Dropwizard. It had a philosophy of picking a set of tools that could help people get up and running with a java web application quickly and that would serve them well for a long time, choosing the best tool for the job.<p>Then Spring boot came along where they defaulted to the much fatter Tomcat, apparently just to be different, and then went down the list of libraries and instead of picking the best one, they picked the Spring one.<p>I never understood that philosophy, but it won out. It looked at lot to me like no one ever got fired for choosing IBM&#x2F;Microsoft. But it was so much worse. Other frameworks have improved on what Dropwizard offered for startup times, etc. but still don&#x27;t seem to have gained the traction to unsettle Spring.
rr8083 个月前
The best thing about Go is no Spring framework. I like Java but finding Java projects without Spring is difficult.
评论 #43097872 未加载
wiseowise3 个月前
I wish this “DI black magic” meme would die. If you’re afraid of runtime DI, then use Dagger 2.
评论 #43100338 未加载
honkycat3 个月前
After dealing with constant build issues between Java and Typescript and Node and Python: I love go so much. The package management alone makes it worth it.
评论 #43096583 未加载
rvz3 个月前
Agree. Go is a joy to use. Java is okay but struggles with scaling unless you have the money to burn for this.<p>To scale up servers in Java requires spinning up highly priced servers with lots of RAM, which that is a lot of money. Using a low spec server is cheaper but you will get more JVM crashes and have to waste time doing more JVM tuning to prevent them. This is not even talking about having lots of &#x27;microservices&#x27; to scale which that also means more money spent per month.<p>Using Go just reduces all of that and saves lots of money and is extremely efficient enough to rely on and it directly compiles to a single binary for deployment.<p>From a cost and efficiency perspective, Java is just not the answer even though it is a sound language, unlike JavaScript or TypeScript. Given a choice I&#x27;d rather use Java or even Kotlin or JS&#x2F;TS. But the cost reduction, performance gains and onboarding experience with Golang is hard to beat for backend.<p>Would stay really far away from JavaScript or TypeScript for anything backend.
评论 #43096458 未加载
Mekoloto3 个月前
This doesn&#x27;t give me any clue how it would really feel like to switch a big webapp&#x2F;enterprise webapp from Java to Go.<p>How is the handling of database and entities? How is the security model and support for api endpoints?<p>etc.<p>I have had very little issue with java startup time. Hot code replacement exists for decades
monksy3 个月前
There are some arguements that were made in this post that don&#x27;t matter at all.<p>One of those is: Cold start time<p>This isn&#x27;t a big deal in the context of a web app. 8s vs 100ms. If you&#x27;re scaling up a service. 8s is not a big deal in the scope of fixing a horizontal scaling issue.<p>Additionally, what it&#x27;s considers bloat: Yes, you should optmize your app. It depends on the context of your application. Brining up a rest app that needs to stay up..who cares if it takes .5-1gb of ram.<p>Also, I didn&#x27;t see it pointed out about the concerns of the lack of 3rd party frameworks. I find this disjointed and sparse frameworks to be more of a concern for a language&#x2F;ecosystem than what the author pointed out.
invalidname3 个月前
All k8s operators are written in Go. It&#x27;s really unsurprising that Java doesn&#x27;t fit there. Java has huge advantages for typical web applications (observability, deployment flexibility, deep toolchain beyond IDE etc.). I&#x27;ve seen companies trying to use Go in the environment where the JVM excels, then breaking down the problem to thousands of small microservices which end up making something simple into shards of complexity.<p>Java is a general purpose application development language. Go is a system language that isn&#x27;t as deep as Rust. They are very different things and comparing them doesn&#x27;t make any sense. Like the people comparing Rust to JavaScript, these are not interchangeable.
评论 #43099693 未加载
rzz33 个月前
A coworker once claimed that Go is the new Java, and I haven’t really been able to refute it.
newAccount20253 个月前
&gt; In the course of a developer&#x27;s years, if I only restart the server two times an hour, this saves me an additional day (!) of development time per year.<p>You are working too much.
smrtinsert3 个月前
I thought we had moved on from flame bait articles as a species
DeathArrow3 个月前
Depending on how Java application was devoped, the real benefit might be breaking free from the kingdom of nouns, land of design patterns, country of OOP.
pm903 个月前
The startup time comparisons may not seem like a big deal but having an app take several seconds just to start up can burn you really bad in incidents where you want to roll new application versions. And yes, it is possible to engineer around it but I think a better question to ask is why these apps take so goddamn long to start in the first place. There should be some kind of compile or runtime flag to speed this up.
评论 #43096586 未加载
评论 #43099206 未加载
yodon3 个月前
Has anybody spotted a similar story of switching from C# to go?<p>As someone who is very fond of C#, I&#x27;m definitely curious what I&#x27;m missing out on.
评论 #43101407 未加载
评论 #43099359 未加载
评论 #43099560 未加载
raffraffraff3 个月前
&gt; We even went so far as writing infrastructure code for Kubernetes clusters that automatically provision apps in Kotlin.<p>Dear <i>god</i>. Compared to the go code required to do the same thing, this is crazy.<p>Edit: I removed reference to terraform, seems like there&#x27;s no infrastructure code here, it&#x27;s helm + operator.
TheSmoke3 个月前
I wonder how a migration to for example Micronaut from Spring would look like in their case. It is optimised for startup time, performs the dependency injection and annotation processing in compile time as well.
user99999999993 个月前
Any suggestions for how to store request scoped data without context? Specifically when using middlewares, like in the example of an auth middleware, needs store isAdmin or isLoggedIn or UserId
评论 #43099200 未加载
zwnow3 个月前
There&#x27;s one simple argument to never touch Java: FactoryFactory produce ArgumentFactory, ArgumentFactory.builder().build(argument)
anta403 个月前
&gt;&gt; Of course, Java still has its strengths, and for certain projects, it remains a solid choice. But for cloud-native applications, Kubernetes tooling, and our self-hostable software distribution platform, Go just feels like the right tool for the job.<p>Yeah. I see Android app development is still mostly dominated by Java&#x2F;Kotlin. Of course you can do it with Go, e.g: <a href="https:&#x2F;&#x2F;fyne.io" rel="nofollow">https:&#x2F;&#x2F;fyne.io</a>. Never try to write something serious with it, just messing around with the examples.