Hacker News new | comments | ask | show | jobs | submit login

Everyone's code basically sucks, including yours. 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. Learn from your seemingly smarter peers, but don't idolize them. Chances are they will leave the company long before you do, and you will figure out that their coding skills aren't all they are cracked up to be, especially if their code is poorly documented. You will soon understand that they were focusing on getting the job done, while you were expending all that effort to be clever. In that sense, they were totally right.

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.

> 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.

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.

In many fields, it takes a master to make everything look easy. It really seems to be the same with programming.

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.

My interpretation is that most of this disagreement is just from ambiguity left by the parent's brevity.

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)

That's why comments should mostly indicate the why of a design/architecture choice that was made, not what the code is doing.

Probably unrelated

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?

Ahh, rewrite vs letting it stay! The classic maintainer dilemma!

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?

I'm doing it because the site is too slow where people don't stay/staring at a loading icon. 0.5Mbps and lower is really annoying to deploy a photo-based site gee who would have known.

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.

server side render or put in HTML as placeholder. I've wanted to placeholder images with the primary color or some gradient that can be made in canvas but never got around to it for a project.

I never really understood what that meant. Server-side render it's not template generation? Time to learn how to read.

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...

> The boundary between a beginner and a coding rockstar really isn't very great

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.

One thing I know for sure is the enormous difference between myself as a beginner and today!

> The boundary between a beginner and a coding rockstar really isn't very great

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 ...

I think an important piece of advice to take from this (and something that I learned early on) is to favor tools that reward mastery. In this respect Java isn't actually that bad, even if there are better options available. What's worse is the culture of many organizations that happen to use Java.

Misapplied Java design patters are the root of all AbstractWordFactoryFactory("evil").

The point he was making is that most experienced coders are focused on delivering, regardless of how slick their code could potentially be and eventually all code will suck.

You just proved this by picking on Java.

Also it makes a huge difference for the next person who'd work on that codebase to add a new feature. Doing that could be anything between a breeze to a blazing nightmare depending on who wrote those codes earlier.

> Everyone's code basically sucks, including yours.

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.

TDD seems to be mentioned in a lot of responses here. I'm warming up to the idea but frankly not many folks I've come across in my (short, 3 year) career seem to understand tests really, definitely not TDD. So I've been having to learn the hard way.

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?

> I'm warming up to the idea but frankly not many folks I've come across in my (short, 3 year) career seem to understand tests really, definitely not TDD. So I've been having to learn the hard way.

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.

Three answers:

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

You could divide (in your head) contract and implementation details. Contract - what "unit" should do, e.g. factorial function should compute factorial for given numbers. But how exactly this is done is implementation detail (will be used recursion? do/while loop? will there be result caching?)

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.

You know how you manually test code sometimes in a console, like a REPL?

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.

Tests and TDD are different things.

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.

The point of TDD is you can define the behavior before writing the code. ie. you define the expected result:

  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.

> 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

I'm not wrong.

I would say that you are, but you've convinced yourself otherwise.

But testing is important, for sure.

> I view TDD as a workaround for a lack of a REPL.

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.

Yeah, I started using TDD, and now I sweat over my tests instead of my code.

Same general quantity of perspiration either way.

I agree with your sentiment. I also think of TDD as a way of trying to overcome confirmation bias. I actively try and write tests that might prove my code has bugs. When they don't fail I feel more confident about what I'm shipping.

For me that's the craftsmanship in software development - shipping something I'm proud of.

I'm.just now getting to the point where I'm finding this necessary. Any resources you can point to for a beginner in testing (python)?

Totally agree on the personality and grooming points you made. You need to be good at making people know exactly what you have achieved. Shout about it on slack, fire up google docs and write some brief documentation on a new feature you implemented. Others within the company won't be actively looking at your contributions. They will notice who stands out, who is taking initiative and touching base regularly. Unfortunately this trumps true programming talent in startups - EVEN if you are one of the gods.

If you believe you're one of the gods, you're likely delusional. If you don't communicate well and hold that belief, you're certainly delusional.

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.

Also, ask for the new, interesting work, make designs, talk to others about your ideas - don't just show up with a complex multi week/month solution.

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.

I agree. Its also worth noting that the need to publicise your work should not be taken so far that people perceive you as boastful. So there is a balance, but you definitely can't just be quiet all the time.

A corollary of your first point is that it is code that is bad, and not your coworkers. Code is complex and nobody really knows how to program. (Proof: If folks did know how to program, then we wouldn't fight over which programming language is the right one; it'd be obvious.) So don't ever blame your coworkers unless they're deliberately malicious; instead, have compassion for them and for yourself as well.

>Nobody cares that you put in extra hours.

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.

I tell my teams this regularly: you'll hate all legacy code you work with, especially your own. This means, in essence, that you always hate your past self.

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).

After having worked in a legacy javascript codebase, I can say it is very much possible to discern between sucky code and code that is maintainable.

That seems like a lesson in corporate culture, not programming. Nothing that you do really matters more than how good you look doing it?

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact