This is really untrue. On the surface, code might look the same between a beginner and a senior developer, but the decisions underlying the code will be night and day. Beginners will solve the problem of the day directly, with no care for introducing complexity and no willingness to reconsider past decisions.
Coming from the other direction, just because it's straightforward to you doesn't mean it's obvious to everybody else. Try to be patient.
Experience certainly shines bright in architectural and design decisions.
I think the parent's point is that no one's code should be considered sacrosanct; all of us can make mistakes, and all of us, even the senior guys, will end up writing some ugly hacks just to get something out the door on time.
More junior programmers should not be afraid to make a pass at improving something, nor should they try to emulate their peers' styles or behaviors without thinking about and processing them, lest they internalize bad habits. If a junior dev notices an error, they should point it out, instead of assuming the senior developer's code is beyond reproach. They should understand that once they get added to the resident Wizard's project, they're still going to have to deal with the reality of a production application, which means shortcuts, impurities, bugs, and mistakes. The principle of Linus's Law depends on developers who are willing to call out mistakes and at least prompt a discussion about the tradeoffs.
This doesn't mean that senior developers won't be much better at writing maintainable code on a macro level. This is especially true because I've found it usually takes until upper-mid-level for developers to really get an appreciation for simplicity and avoidance of technical debt, and to register that you're actually better if you can do more with less. (n.b.: speeding up a computer program is just making it do less)
It pisses me off how I keep having to rewrite/resolve this particular problem I have of deploying a photo sharing site based in a poor network area.
One day I feel satisfied with the work I've just done, the next day it is garbage and I do it again a different way.
Faster but not fast enough.
Then you get this huge block of code and feel this heavy weight like ahhh.... Slash and burn...
Am I doing this the right way? What is the right way? Look at other major sites, why don't I achieve that same performance?
It is nicer to start over but is it a waste?
Answering this really depends. I think I would start with "what do I hope to get out of this process". Are you doing this to learn? Are you doing it to grow a user-base? If it's a user-base, is this the biggest problem preventing your growth? If it's learning, is this the most interesting problem for you to solve?
The Dom loads just over 1 second, but things are still waiting to show up(js?) So I'm thinking of building empty templates like "Hey something is here don't worry."
I don't know. I'm actually not sure what progressive loading is. I currently use that blur-up method but I've seen those sites that use a technique where the photo is super pixelated (large pixels about a quarter of an inch or 1/8) before loading the high res. I think that is true progressive loading but don't know what it means with code.
I do build a template and spit it out according to what is requested, but then a JS function runs to "fill in the blanks" with a secondary call for the missing data. I should probably get rid of the images formatting (based on aspect ratio) to fit into the tiles. I don't know...
I'll add to the chorus here and say this is not only untrue, but so untrue as to be absurd. By all means caution against hero worship and remember that even those with exceptional talents are human, but don't misinterpret that lesson to mean there are not vast differences in quality between a beginner and an expert.
I respectfully disagree. My experience says the difference between a beginner and a really good, experience coder, is HUGE, and not only on fields like "machine learning" but in everyday commercial systems.
Unless, of course, your platform is something like Java where everybody is crippled to an extreme degree.
That is, if you get 400 people on a room, tie their hands and their feet, they most likely dance with the same skill, their dancing experience notwithstanding ...
You just proved this by picking on Java.
Which is why I'd say, unit-test your code, or TDD, or something. When you look at that crap months later, your mental model of how it all works has completely eroded, and only the test suite is left to preserve your expectations as they existed back then, preventing you from wasting a lot of time stepping on your own toes while you re-grok the big picture, if you have to make a change.
> The boundary between a beginner and a coding rockstar really isn't very great unless you are getting into the realm of computer sciences, like machine learning.
I don't agree with this. I didn't spend 20 years learning nothing, as it were.
My main thing with TDD right now is - how do I avoid writing tests that are too tightly coupled? I've gotten burned in the past, not even doing TDD, with tests that "know too much" and end up being more hassle than help.
Any good resources on TDD and general testing strategy that anyone can recommend?
You aren't wrong, the state of unit tests in the wild is dreadful. Many were forced into creating tests by management decry, others just think they know what unit testing is. Sometimes the latter are even unit testing advocates.
Remember what a unit is, it's not a class or the method, it's the unit of behavior you are testing. In practice this basically means whatever you are asserting.
Stick to the single assert principle and keep tests small. This doesn't mean only one assert statement, but only one behavior. Often asserting that a function returns an object will one test (it didn't return null), the details of the fields that object contains (like did we format "LastName, FirstName" properly) will be different tests. If you are asserting "LastName, FirstName" in 10 tests then 10 tests will break when that behavior changes. Only one test should break.
Always have a setup method that creates the owner of the unit and any of it's (mocked) dependencies. When a behavior is added it should take less than a minute to add the test for that behavior (assuming the test fixture already exists).
Do that and you're writing better tests than 95%+ of the industry.
1) Just keep going. Experiencing the pain of less-than-ideal tests is pretty much the best way to learn. It also frees you from outdated dogma about testing.
2) Maybe try testing at different levels? I got into testing by learning to write big slow acceptance tests for a particular user experience and small fast unit tests for a particular module. This helped me see what each kind of test was best for. (Maybe your "big tests" are written in Cucumber and automate a web browser, maybe they test an HTTP API, that's up to the kind of work and environment you're in.)
3) Watch this video "Boundaries" by Gary Bernhardt: https://www.destroyallsoftware.com/talks/boundaries
The trick is to omit implementation details from testing, because implementation can change, but after all fact(4) should return 24 no matter what.
So it's useful to think in categories of contract given unit should fulfill instead of testing everything for the sake of testing.
Automate that and you have a unit test.
Do it right before you write the implementation (forcing you to first consider how it might work, not a terrible exercise), and you have TDD.
Every unit of code should be smallish, focused, and with the absolute minimum of external dependencies. That will make it easily unit-testable and far more maintainable long-term.
There's finally empirical data emerging that TDD is a labor-saving device... Look up the Nagappan paper. (There's more than that now, though, that's just the most famous one.)
Also, as someone else mentioned, watch the Boundaries talk by Gary Bernhardt. Amazing.
I view TDD as a workaround for a lack of a REPL.
When the code is finished, the tests can be written or polished but writing them before any code is just one variation of testing.
def test_sum():
assert sum(1, 2, 3) == 6
def test_sum_no_args():
assert sum() == 0
def test_sum_negatives():
assert sum(-1, -2) == -3
etc, and then you write the function.This means you only do the "REPL" testing once ever for each case - and you can rerun the tests for all future changes. If ever type the same function + args into the REPL more than once - you have done redundant work and are wasting your time.
Likewise if you're in the habit of writing tests after your function is made - it shows you haven't put much thought, which means you haven't done the proper analysis of why the function exists, if the function is really one function or should be two functions, what arguments it can take, what it should return etc.
I'd say that's a pretty broad brush you're painting there with
But testing is important, for sure.
Every manual test you do of your code in a REPL is literally a unit test screaming out at you that it wants to live in your suite.
Same general quantity of perspiration either way.
For me that's the craftsmanship in software development - shipping something I'm proud of.
Programming talent is useless if you can't communicate. Because your main job as a company grows is to grow the people around you, not cranking out more code. Communication overtakes pure coding skill the moment more than one person works on a project.
It's not about "trumping talent", it's about the fact that communication is part of the talents you need.
I've never understood why more people don't ask for the interesting, fun, challenging stuff. I've always done that, and been glad I did.
This is all in the presentation. The point of putting in extra hours is not to get more work done, but to appear at least as busy as (but preferably busier than) your peers.
Most people can't tell if your work is good or not. They can only tell if it looks like you're working hard, and if they like you/find you personable. For most people, "butt in chair time" becomes the biggest factor in their perception of how hard you're working.
Since you're providing good advice about appearance, politics, and popularity, I'm sure you've registered this. We should just clarify for the people who are "4 years in" that "don't overwork" means "don't actually overwork", but do take care to ensure everyone in your office thinks you're a hard worker.
Pushing that hate for legacy code to your own self is important, as it as a good motivation to improve (for us narcissists at least).
Don't overwork. Seems obvious, though it's not only still prevalent in America, but more important for our field. Working extra hours has rarely benefitted me either in quality of work or in company treatment. Nobody cares that you put in extra hours. In fact, don't expect your boss to care about anything you are doing even if they are generally benevolent.
Your success is mostly dependent on your personality with appearance as a close second. That's not to say you won't have big wins with the projects you work on, but a lousy programmer won't get fired if they are charming and everyone likes them. The more I refined my social skills, as well as my grooming, the more my minor achievements would get overinflated by my peers and the more they would overlook my mistakes. It's just a cruel fact of life, but at least it's something most people can actually address.