One of the things I really appreciate about golang (from a completely different field) is how quic teh builds are, and how fast binaries start up (it's like I wrote it in C).
The startup time is negligible in my experience (few seconds for JVM or python imports). I have to take over slow starting applications from time to time and it's always because of loading data and doing stupid shit on startup, irrelevant of the language. It's not a problem for production because server application only reboot once in forever.
Also, JIT languages have a very poor habit of doing a terrible first impression because of the warm-up time, especially in Java. If you are delivering applications to customers, that becomes a real burden - the very first time they use your shiny new application, everything is moving like molasses, until the JVM decides it's JIT time...
But I understand that that's what most people out there are doing. But they should also not delude theirselves that the toolsets appropriate for that environment are appropriate every where else. I see this bias a lot, on HN even, that everyone now is a "full stack developer" doing this kind of development.
Many of us work in entirely different stacks.
And I don't think web development is where Go is getting traction. More in back end services and infrastructure.
> Java/Spring dependency injection is jumping through hoops just to provide a testable framework I find it hard to believe it's any easier.
As someone who develops with Spring everyday, I don't think it's the best solution for anything.
Having the code execution paths radically change by adding an annotation to a method or a class makes it very difficult to reason about what it will do when deployed.
If that annotation you found through Google does what you want and expect, that's great. But if it doesn't, or fails in unexpected ways, debugging it can be a nightmare.
The whole original point of dependency injection was to decouple dependency management from the code, to make it easier to test, and easier to reason about and analyze.
DI via annotations goes ahead and sticks them right back in there. And now we have, like you say, magic code that is difficult to reasona bout.
XML sucked, but annotations sucked more.
When you have an expectation from the exchange that you respond in under 80ms, and 25-50ms of that is eaten up by transport, you don't have a lot of time to mess around.
So you spend the first chunk of time optimizing I/O and how you're accessing it.
Then you start looking at computation -- improving caching, etc.
At a certain point you start noticing in your graphs that you're on average doing quite well. But there's those hiccups every Nth request...
And now you're in the game of fighting with your language's garbage collection algorithm...
Try to improve allocations where possible. There's often plenty of small allocations happening in Java that can be avoided (string usage is one major driver). Less allocations means less frequent garbage collections.
Then one hack is to disable the garbage collection. Let the software run up to consume all the 100 GB of memory of the server and crash and restart. There is no pause of garbage collection when there is no garbage collection.
If it's not enough, the last resort is to write native code or switch to C++.
*sync.Pool, arena allocation strategies
What did you do? You wrote servers in C? you wrote a Redis for instance?
My successor at the original startup rewrote everything in Python. And I watched from the exchange side as they struggled for two months to meet basic performance constraints. They eventually got it though. It certainly can be done.
It's worth pointing out this was 10 years ago. And in the meantime we've had the usual improvements in machine performance, and SSDs are a thing in data centres, etc.
a) Lack of static analysis tools means having to do more testing (manual or automated) for simple mechanical errors.
b) For super high throughput low latency systems, they are not up to snuff. When I worked in real time bidding in ad-tech this was actually a serious concern. I'd reach for Rust (or C/C++) in this scenario now.