How to go from good software engineer to God of the Code?
February 13, 2013 10:32 PM   Subscribe

(Java-flavored question) I have work colleagues who can explain how and when the JVM inlines code, or when implicit constructors are made / called based on the access level of global variables. They can think through code like the compiler thinks. How do I get to that level?

I consider myself a good developer. I read Stack Overflow, java blogs, and I have a virtual shelf of pro java books. I have well-honed design instincts, and am comfortable with a wide range of java libs. I've been developing software professionally for 10+ years.

However, I never seem to get to that highest echelon of coding nirvana that some of my peers do, where I can really talk about the lowest underpinnings of [Java in this example]. I think the problem is that I can do my job really well without having to know that level of detail, so what can I do to integrate those details into my nightly readings or daily work?

Where are these resources that explain what the JVM is doing under the hood? What else should I be doing to raise my designing and coding game to the next level? E.g. when I turn to a well-reviewed pro java book, all I get is an in-depth explanation of language constructs and libraries. There's never a section called, "From source code to byte code to JVM runtime - the nitty gritty of runtime execution."

I feel like I'm on the cusp; I'm ready to move to that next level. If I have to I'll just read every single Java-tagged post on Stack Overflow, or keep looking through books. I can if see maybe there are some Java architecture online courses available, or do a google search for "inside jvm," etc.

My point is - I'm motivated to learn, and I think I have a foundation to build upon. I ask you, my dear hive mind, in case you have some resources or insights that will lessen the learning curve or otherwise help me develop the habits to learn, process, think, and code at a more holistic level.
posted by blahtsk to Computers & Internet (15 answers total) 22 users marked this as a favorite
Write a compiler. Build an interpreter. Implement a metacircular evaluator. Learn another language. Then another. Choose languages from different families. Now ask your question again. You will know the answer.
posted by Combat Wombat at 10:47 PM on February 13, 2013 [7 favorites]

A lot of it comes from looking at the compiler output compared to the source code. In the case of Java that means you need to be able to read the PCode.

Some of it comes from knowing how compilers work. That you can get from studying books and/or taking a college level course on compiler theory.

I can't do this for Java, but I used to be able to do it easily for C.
posted by Chocolate Pickle at 10:55 PM on February 13, 2013

To better understand the JVM, write a JVM. Even a toy one. Full understanding of the level on which you're working comes, in part, from going one level deeper than you need to.
posted by pont at 10:56 PM on February 13, 2013 [3 favorites]

Perhaps you should port a favorite language of yours (or parts of it) to the JVM? That seems like it would be a nice combination of learning about Java internals + working on something that might please you.
posted by value of information at 11:31 PM on February 13, 2013

Seconding the Java Language Spec. It's not you, it's the language, as good as it is. That will get you going as far as learning important things like when constructors are ran, etc.

Also, your colleagues are probably completely wrong about when Java will inline code, or garbage collect, or whatever, and really, it's one of those things that just doesn't matter. I suppose you could learn about how a JVM works at the implementation level, but I wonder where the value added is.
posted by Yowser at 12:21 AM on February 14, 2013

That's because "pro java books" are aimed at professionals - people who need to Get Stuff Done.

I'm not a professional software engineer and as a hobbyist I have the time to do this kind of thing. It's because I don't have to deliver working projects to customers to deadlines that I have time to write my own C compiler, mess around with hobby operating systems, and play with the internals of unusual things like Erlang.
posted by atrazine at 3:24 AM on February 14, 2013

Usually when I get a "wow how the hell do you know that" response, it comes from my experience with low-level programming - Although (like many people) I learned Basic (as in "GW", not "VB") as my first language, I quickly moved on to assembly when I found Basic's performance abysmal. I started writing "firmware" in the device driver sense (RS232, VESA2), before graduating highschool largely for the same reason, because old machines ran slow slow slow, and that just plain annoyed me. When I started working in the real world, I moved on to "real" firmware, writing the code for embedded uCs that actually runs the hardware itself. Satisfying but tiring. :)

All of that set my world-view for looking at a highly abstract platform like the JVM or SQL. The language itself, I consider almost trivial - I can Google the details of whatever class libraries or APIs I need to use, the order of parameters to this version of "compare two strings", trivia of that nature; but when I learn a new language, I want to know how it turns an inner join on an indexed field into actual CPU instructions and data access patterns.

Perhaps what you want just amounts to a "tip of the iceberg" issue, and only a great many years of experience can really get you where you want to go - If you barely understand object scope and dirty page detection, reading up on realtime garbage collection strategies won't really give you that warm and fuzzy intuitive understanding of when your program will "randomly" decide to thrash for 5-10 seconds cleaning up after itself.

I don't think I've properly answered your question, except to say "give it time", but anyway, I've said how I view the situation. And FWIW, don't take this as bragging - I come across guys all the time who blow me away with pretty much what you describe. Always keep in mind that knowing just 1% more than everyone around you makes you the awe-inspiring expert.
posted by pla at 4:21 AM on February 14, 2013 [1 favorite]

"When you have snatched the error number from the trap frame, you will know it is time to leave."

Programming mastery comes not from knowing what things do. Nor from knowing how things work. It comes from knowing what the available options were when the decision to do things a certain way was made, and why that particular option was selected, and whether or not it was a justifiable decision at the time, and whether or not it is still a justifiable decision. Okay, and now you do this for every level of process, from hardware choices to system API development to application programming language choice to UI interaction schemes to how the project fits into the realm of the world it inhabits.

So, in order of mastery, we might say

1) what does it do?
2) how does it do that?
3) why does it work that way?
4) what other approaches are available?
5) where does this process fit into the scheme of things?
6) when the time comes to respecify, what should/should not be done differently?

To echo what others have said, you cannot become a true programming master if all you ever use or think about is Java itself. You must understand everything that affects Java, and everything that Java affects. And then the context around that....

It never ends, really.
posted by seanmpuckett at 4:45 AM on February 14, 2013 [1 favorite]

I theorize that being forced to learn to read/write assembly code helped me to understand the JVM later on. But there are fewer practical reasons to learn assembly nowadays unless you are working on some sort of emulator or niche application, or just have time to fool around with it.

Probably writing some JVM bytecode would be a good start, using the Jasmin assembler or dynamically using one of the many Java runtime code generation libs. BTW Eclipse will show you bytecode if you double-click on the class file in Package Explorer; this helps me visualize what the compiler's doing.

Also -- learning certain bits of knowledge like specific compiler internals may be intellectually rewarding and useful in a pissing match, but I'd wager that the person that goes further in their career will be the person who has practical high-level knowledge and gets along with others. Just sayin'.
posted by RobotVoodooPower at 5:15 AM on February 14, 2013

I was once like you. I learned lots of stuff like others above have suggested but it never seemed enough. After a lot of time, I had more of an overview of the field and discovered that it is constantly changing, not only because of economics and hardware improvements, but because of fads and fashion. I had detailed knowledge of obsolete systems and was always behind those just graduating who had learned the Next Big Thing. Learning current implementation details, though good for impressing others, is a short run solution.
posted by Obscure Reference at 5:42 AM on February 14, 2013 [1 favorite]

Spend a lot of time (thousands of hours) single-stepping through compiler output with a debugger. Doesn't matter what source language or what target machine; in fact the more different ones you can find, the better.
posted by flabdablet at 7:16 AM on February 14, 2013

Others have given good pointers on how to achieve that depth of knowledge, but I sense that you don't have a burning urge to go that deep. This is okay. Maybe it is reflective of the subject domains I worked in, but I never had the need to go this deep to get things done well. I periodically had to know how the garbage collection mechanism worked.

In my experience a deeper knowledge of data structures and knowing how to structure the OO code goes a lot further. In other words, I see more gain from getting more abstract up the hierarchy than going the low level route.
posted by dgran at 10:51 AM on February 14, 2013 [1 favorite]

Also, your colleagues are probably completely wrong about when Java will inline code, or garbage collect, or whatever, and really, it's one of those things that just doesn't matter.

Just wanted to second this. People who talk about how "the" JVM is going to behave are usually vastly underrating how different JVM implementations can be, and this can be a very bad habit if it leads to attempts at premature optimization. Coding to a specific JVM's behavior is a really bad idea — that's the whole point of writing to a virtual machine in the first place, that it allows an additional layer of abstraction. Low-level implementation details aren't the "highest echelon of coding nirvana" unless the code you're writing is low-level code; otherwise, high-level abstraction is the nirvana you should seek.
posted by RogerB at 11:47 AM on February 14, 2013

Knowing how a shovel is made won't necessarily help you dig better ditches. But knowing what influenced the design of the shovel, and the alternative shovels available, all will help you make better choices when digging ditches.

But are you really interested in improving your digging, or are you interested in improving the ditches that you dig?

In most most of my work (10+ yrs of software), I've benefited more from studying ditch design than I have by worrying about how the shovel was built. Obviously choosing the right shovel makes a difference, but it's one part of a larger picture.

As others have said, I think you'll benefit more in your pursuit of coding knowledge if you go higher-level rather than lower-level in your knowledge, unless your interests really are in low-level systems and those are the jobs you wish to pursue.
posted by jpeacock at 12:17 PM on February 14, 2013 [2 favorites]

Echoing pia above to some extent. Check out this post about great code:
posted by PickeringPete at 12:47 PM on February 23, 2013

« Older Difficult cooking techniques or recipes   |   Germany intern visas Newer »
This thread is closed to new comments.