Things I Learnt from a Senior Software Engineer
neilkakkar.com
neilkakkar.com
Agh, I'd hate that. In fact if anything interesting had been going on on my screen it would immediately stop, no way I could work with someone watching.
I struggle enough at desks with my back to a door or where people walk by, just can't stop myself from being distracted and looking.
(It's not that I'm not working, or otherwise doing anything I shouldn't be, it's just.. distracting is the best word I have. It's not where I'd sit in a restaurant, and I've despised not having a choice but to sit at such a desk at work.)
https://hbr.org/ideacast/2019/08/how-robots-and-ai-are-chang...
I'm not able to work with my back to a crowd. That's a recipe for anxiety. I quit a company when they moved my desk so my back was to a hallway, and refused to compromise on this issue in any way.
In a "normal" situation where your desk faces the rest of the room, you would become aware (in an "ambient" way) of people wandering into your field of view.
But with your back to the room/hallway/whatever, you need to explicitly scan the mirror (sort of like polling, in computer terms) with frequency to know if somebody is approaching.
It's like trying to work while also focused on a video playing in a desktop window or something.
Of course, as with anything, some people are not bothered by this. (And, of course, some of those people are fooling themselves into thinking there's zero impact on their focus/productivity)
I improved exponentially my concentration and quality of work while he showed up that previously he was spending large amount of time watching YouTube/news websites/shows instead of doing work and he is frustrated that he has to do real work now.
The upper bezel of your monitor is likely shiny black. It makes a great mirror to know when someone behind you is taking interest in you. It is also completely inconspicuous and you do not need to move your head from your monitor to use it.
She would audibly be surprised and distract others.
I have had private offices, two person offices, cubicles, and once in a bull pen with a glass wall. (we called it 'the fish bowl').
Private office comes in first! Cubicle (as long as the walls are at least five feet) comes in a close second.
Open floor plan (or a bull pen) comes in far far far last.
The place had no open desks for us, so they decided to turn the small conference room (we had interviewed in) into our shared "office". Trouble was, it had no A/C vent in it. Hence, with four people and four computers and four monitors - it became "the oven" (there were other reasons we named it what we did, but they aren't relevant here).
But the camaraderie we built in a short amount of time as a team was beyond anything I had experienced before. We'd keep the lights off, a fan running, and a spotify playlist cranking out weird music (our lead controlled it, he was younger than me by many years - as an older person just turning 40 - his choice of music was both odd, and interesting - I'm glad for this, as I discovered new music genres I never knew existed - like Pirate Metal - yes, Alestorm was one such band).
Eventually we got a portable A/C unit, which made things more tolerable.
Ultimately, though, that room helped to form a team that cranked out some interesting code in a very short period, which I think helped to lead the company to be sold to a larger competitor about a year or so later. I ended up leaving the company (the new owners did a "rehiring" process in which they offered me my position at a 25% pay cut - yeah, sure, let me get right on that).
Thanks - now you say it, I think I've heard that before. (Perhaps from my father, who I know 'suffers' from the same.)
And in fact, when working from home (nobody around so it's not about being in 'command' of others at all, as a quick search tells me it isn't in feng shui either) I often prefer to sit at a table where I can see down the corridor to the front door.
Or when it's hot, on the balcony (as I am now) sitting back from the table such that my back's to the corner and my peripheral vision covers both out over the balcony to outside, and through the windows into my flat.
...interesting. It's totally sub-conscious - I always know where I want to sit in a room, or at a table in a restaurant, etc. it doesn't require thought but it certainly isn't random. I don't think about it while sitting down, but I'm sure if you asked me afterwards why I was sitting there I could tell you.
Interestingly, I can share my screen with people that have different tasks than mine. I just can't make it work when both people have the same state of mind.
Bad definition (the one I encountered in school): two people of about the same skill level sitting at one computer and programming together. I hated it, akin to my hate of backseat drivers.
Good definition (the one I encountered at my workplace): as a junior engineer, I was tasked with implementing this tricky caching thing in one of our systems that I had zero previous experience with. One of our senior engineers was tasked with helping me with that. I would implement as much as I could myself, and when I get stuck, the senior would either give me hints on how to get unstuck or program some parts himself while explaining to me how and why he did things a certain way. This helped me out tremendously in my skill development and got me running confidently in our codebase really quickly.
I will fumble the keys and be much slower if I'm the one being watched, but I'm fine with that because I know they're there and they asked.
I'd still be bothered by others walking past behind us while the person who came over to 'pair program' (if I can call what we're doing that) watches and doesn't bother me.
It's helpful if pair programming is the default mode (i.e. a dev will only go solo when there's a consensus that pairing would be counter-productive).
If you pair-off at the morning standup, so that ongoing tasks retain one dev from yesterday and gain one fresh dev, then after a couple of weeks everyone on the team can cover for anyone else, and everyone has a birds-eye view of the whole system. This was a revelation to me; prior to my encounters with pairing, I'd never worked on a team where anyone had a good overview of the whole system, including the leader. Morning standups help, but pairing-with-rotation does a much better job of knowledge-distribution.
Re. Sociability: I've paired with some very nerdy, shy people. It generally worked out well; most nerds are just fine when they are explaining what they are currently nerding about.
I've paired with people who were much brighter and more knowledgeable than me, and the other way round. Either way, it worked out fine (as long as you don't develop a Master-Apprentice syndrome).
Pairing involves quite a lot more mental effort than solo coding. I was always dog-tired after a day of pairing. Keeping track of what your pair is up to (or making sure your pair is keeping up) requires attention. And IME breaks are generally shorter.
I only had a problem when I had to pair with someone quite far along the aspie continuum; he was bright, but he was completely unable to explain what he was doing, and his code was far from self-explanatory. If you see coding as a way of communicating with programmers, rather than with machines, strongly aspie types become a workplace hazard.
get_msg('fail_add_address')
vs. 'I\'m sorry, we\'ve been unable to add the address %s at this time,' \
' please try again later.'
(... but that's an ideal I have without ever having worked with it, so what do I know, and ymmv, etc.)We do have a constants file which has all the messages but a PM does not access to code/commit and has to go via a Dev.
To borrow from that cringeworthy scene in The Social Network: He's wired in!
He's a nice person, and I understand not all people are wired to realize this is a problem for some others, but this is reallocating too many IQ points, away from designing and coding and writing, to social interaction/awareness modes. Plus the other distractions. There was no way I could immerse enough in some of the work, and stay immersed.
(I'm happy to do group brainstorming and problem-solving around a whiteboard, etc., as well as to mentor. But most of my time is spent programming, designing, and writing, which I usually do best solo and focused. Nor do I want to be working all day, every day, almost breathing down each others' necks. For many introverts, and people who like to focus fully on a problem, being packed up against other people is taxing, not energizing.)
In the end, I brought in a laptop from home, and worked every day, cafe-style from the lunch tables in the elevator lobby area of our building floor. Which was suboptimal, but something I could make work. People would come over when necessary, but we weren't sitting on each other's laps. I also got good at quickly cleaning lunch tables without interrupting my thoughts. When my PI renewed my appointment another year, I declined, mainly for a different reason, but the physical work environment made the decision easier.
This is covered by RFC 1178¹, Choosing a Name for Your Computer (from 1990):
Don't choose a name after a project unique to that machine.
A manufacturing project had named a machine "shop" since it was going to be used to control a number of machines on a shop floor. A while later, a new machine was acquired to help with some of the processing. Needless to say, it couldn't be called "shop" as well. Indeed, both machines ended up performing more specific tasks, allowing more precision in naming. A year later, five new machines were installed and the original one was moved to an unrelated project. It is simply impossible to choose generic names that remain appropriate for very long.
Of course, they could have called the second one "shop2" and so on. But then one is really only distinguishing machines by their number. You might as well just call them "1", "2", and "3". The only time this kind of naming scheme is appropriate is when you have a lot of machines and there are no reasons for any human to distinguish between them. For example, a master computer might be controlling an array of one hundred computers. In this case, it makes sense to refer to them with the array indices.
While computers aren't quite analogous to people, their names are. Nobody expects to learn much about a person by their name. Just because a person is named "Don" doesn't mean he is the ruler of the world (despite what the "Choosing a Name for your Baby" books say). In reality, names are just arbitrary tags. You cannot tell what a person does for a living, what their hobbies are, and so on.
my beefy desktop may be the whale, the nas is the rhino, the notebooks are roughly dogs, the raspberry pis are small animals like mice, the chromecast is e coli.
plus good: i'm never going to run out of animal names.
Also have used Simpson's for test data. There is some built in structures that can be used Abe-> Homer == Marge > Bart, Maggie, Lisa. Lots of people mostly remember them.
It’s like having a little family.
There are some really small animals, though:
The last time this happened, I happened to be in a position of influence for the final decision for naming standards. We took an approach designed to piss off everyone... license plates. We used sequential numbers prepended by a pronounceable string, and random words, selected by a system, for internal services.
Overall, everyone is pretty happy with it. YMMV.
Is there a name for this kind of anti-consensus decision making?
It’s a weird scenario as people are very emotional about their chosen position during the discussion, but literally nobody gives a hoot once a decision was made.
In our case, multiple organizations were merged, so the perception one camp “winning” was important to avoid.
https://en.m.wikipedia.org/wiki/Coordinated_Universal_Time#E...
You see this word in many English roots, such as isotropic, isometric, isomer, etc.
But I'd tend to call BS - if it wasn't ever an acronym, why capitalize all three letters?
The google ngrams are also suggestive:
https://books.google.com/ngrams/graph?content=international+...
It's like you're dividing an 8-piece pizza between 3 people. Everyone's minimum desire is 2 pieces, compromise solution would be 2 and 2/3 split, and people keep arguing why they deserve more. However you - the decision maker - decide instead to give everyone 2 pieces and throw the remaining 3 pieces into the bin, because shut up and get back to work.
So, throwing away 2 slices, because there is 8 total, is fine, as you stated that is everybody’s agreed minimum desired amount.
And there is no knife, nor protractor.
What is the difference between the worst and best compromise? If it is a compromise, it is a compromise.
Compromise: A solution which pleases the most parties possible while still meeting each party’s needs.
Different experience in English academia, where I encountered random names (e.g. 'mira' for a shell server and 'laplace' for a Physics Dept server). The acronyms could at times be interesting. Particular favourite was a 'central university network time' server. That was later renamed to ntp.*.ac.uk, after stern recommendations.
I hope you never write a single line of code with this mentality...
Of course, the other thing you can do is name server roles rather than specific hardware, so all of your servers are immortal, Ship-of-Theseus style.
Now when name them by physical position in the rack/bladecenter.
Problems with Ginger were being discussed at one stand-up, and an engineer who didn't care about that quietly said, "Blah blah blah Ginger, blah blah blah Ginger." I almost fell over laughing.
(https://desertdemocrat.files.wordpress.com/2015/03/gary-lars...)
NB: Yes, I know that the Wikipedia list of "people with many children" makes 50 look like a record-breaking number. That list is Western-centric. Though 50 is a huge number of children even by Arab standards, it is not unheard of.
Now renaming the machine is a multi-day thing involving configuration changes (and that assumes it's not hard coded anywhere) to a whole bunch of software; inevitably you'll miss some and it'll break. Easier not to bother.
Changing the name might imply changing references in other services that make reference to this server for the current services that are still running. It might also imply changing bookmarks in the machines of the users of the services still running on this server.
The bookmarks are a concern because many users don't know how to do anything with bookmarks other than clicking on them, so you can't depend on them understanding how to edit the URLs of these bookmarks. Yes, that's depressing.
However, let me add that if you later decide to change a name (to something sensible like you should have chosen in the first place), you are going to be amazed at the amount of pain awaiting you. No matter how easy the manuals suggest it is to change a name, you will find that lots of obscure software has rapidly accumulated which refers to that computer using that now-ugly name. It all has to be found and changed. People mailing to you from other sites have to be told. And you will have to remember that names on old backup media labels correspond to different names.
Pets Service Model
In the pets service model, each pet server is given a loving names like zeus, ares, hades, poseidon, and athena. They are “unique, lovingly hand-raised, and cared for, and when they get sick, you nurse them back to health”. You scale these up by making them bigger, and when they are unavailable, everyone notices.
Examples of pet servers include mainframes, solitary servers, load balancers and firewalls, database systems, and so on. Cattle Service Model
In the cattle service model, the servers are given identification numbers like web-01, web-02, web-03, web-04, and web-05, much the same way cattle are given numbers tagged to their ear. Each server is “almost identical to each other” and “when one gets sick, you replace it with another one”. You scale these by creating more of them, and when one is unavailable, no one notices.
Examples of cattle servers include web server arrays, no-sql clusters, queuing cluster, search cluster, caching reverse proxy cluster, multi-master datastores like Cassandra, big-data cluster solutions, and so on.
[1] https://medium.com/@Joachim8675309/devops-concepts-pets-vs-c...
Ideally, none of our servers are special.
Your code doesn't directly call a service, you'd use a service discovery framework (eg AWS Cloud Map) to lookup a location that can handle a particular type of request. It doesn't even matter to the caller whether the request is handled by an instance (eg EC2), a container (eg Fargate), or a function (eg Lambda).
End user requests are handled by an application loadbalancer (eg ELB) that accepts the requests and routes them to an available location, which again doesn't need to be any particular machine (and it can also spawn/destroy instances as needed) or type.
With serverless computing (eg AWS Lambda), there's not even machine for you to SSH into, the cloud takes care of executing functions "somewhere" to handle your work. Work could mean serving an HTTP request - however there doesn't even need to be a client making a call; the lambda could e.g. run in response to an event on an S3 bucket.
Of course AWS can also handle your pets; ie you can name your EC2 instances (and either manage DNS outside, or use Route 53 to let AWS handle it). But that's not what AWS is about; there are way cheaper options for vServers. And of course there are real computers below this, and DNS is being used in the middle of this (with auto-generated names that you don't care about). But you don't deal with that.
One set of systems I worked on, a team had names based on islands. Two of the test machines were Trinidad and Tobago. Upon hearing the first syllable, it was clear that these were the test machines. Every additional bit beyond tri or tƏ was distinct and reinforcing that the first bit was heard correctly.
They also had boring names like dc2f1a3r1s4 and foo-test1 (depending on who was interested in the machine).
The problem that I've found with names like asfcap1234 is that one has to listen to every piece of information and remember it to properly identify the machine. With every character being important and distinct, there isn't any reinforcement or mnemonic checksum to make sure you've got it right.
I will note that this is from the era of servers (and even before VMs started being the thing).
It is very true that once humans no longer reference the machines by name, the ability to name them becomes less important.
As a counterpoint to RFC 1178, consider RFC 2100 - The Naming of Hosts https://tools.ietf.org/html/rfc2100
Everything else is named based on it's purpose.
www, webapps, data, acccounting, mail, things like that.
But, mail is actually named mailV3 (it's the third hardware the mail server has been on). Why it wasn't just named mail, and if the old one was kept around, it could be mail-old, I don't know.
Then we have our development servers. devel, develv2, www-devel, that kind of stuff. I'd personally prefer devel-whatever the name of the production version is called. Instead we have to thing 'develv2 is actually the development version of dp2950....'
Probably because mail system hostnames end up hardcoded in configuration files all over the place, and it's easier to add one and mirror onto it than to migrate the hardware while keeping the name.
a) I am, in fact, named after my father.
b) This does, indeed, cause trouble for other people trying to differentiate us.
Teaching people to spell yggdrasil correctly in order to get a database connection is fun. For some values of fun.
> Nobody expects to learn much about a person by their name.
This is wrong. If I tell you that I just hired a mathematician, a farmhand, and a nurse, you could probably guess which person was which when I introduce you to Vladimir, Jebbediah, and Sofia.Names are a reflection of culture, and certain cultures tend towards certain professions. No politically-correct dreams will change that unless we instill a universal monoculture throughout the world. I'm sure that Disney and Coca Cola would love that, but most people would probably prefer to protect their heritage and culture.
They key word there is “tend”. Since it’s not an absolute, it would be unfair and ultimately disadvantageous of anyone to pre-judge individual people based on their name, since it is not a guarantee.
We do forbid it, though: https://en.wikipedia.org/wiki/List_of_anti-discrimination_ac...
It seems that we have decided as a society that we gain more from the cumulative effect of all people gaining a equal and fair chance, than we would save by allowing people to use whatever branch predictors they like.
It looks like branch predictors in general tend to have unforeseen problems; see also https://en.wikipedia.org/wiki/Spectre_(security_vulnerabilit...
- Dr. Sofia Cerny, the brilliant Czech topologist
- Vlad, a fifth-generation Ukrainian dairy farmer
and
- Jeb, a favorite of the patients at his clinic, who is not on speaking terms with his Southern Baptist pastor father
The advice above is probably one of the things which would have the most impact across all your activities as a developer. When people talk about simplicity in software, they don’t necessarily refer to ease of use or number of lines of code, but instead it’s about how understandable a solution is given their shared knowledge.
Rich Hickey gave a great talk on the topic of "simple" vs "easy": https://www.youtube.com/watch?v=rI8tNMsozo0
I worked in VFX and film post production and this spirit usually saves yourself a lot of hassle in day to day actions and even more so if you get ill, can’t do the job anymore or decide to split it up.
The way I worked in VFX certainly had a big impact on my programming. Some work ethics just make sense.
by far. What's missing is:
> easier to understand by others.
And by yourself, 6 months later.
Anytime a "senior" dev complains to me about "junior" devs, I tell them to review their own code from 6 months ago.
I encourage anyone to take 10 minutes(or 30...) at the end of the day to write up what they've done. Just a text file with minimal formatting has scaled to 2.6MB of hand-typed text. Though, after a bit, I've tended to shard out specific long-running topics into their own files.
I think it's been the top productivity hack in my life.
Not only did it help me keep my thoughts in check, but it became a solid base for me to bundle other habits on top. If I keep a daily log of stuff (one I look forward to because it's super useful - not just a calendar) , all I have to do is add a new column for a new habit I'm tracking, and everyday I'm forced to put in a Yes or a No, which then snowballs into the "Don't break the chain!".
I usually recap what I worked on, conversations I had, other project / teammate updates, where I left off, stuff I learned or fixed, and where I need to pick up the next day.
I used RedNotebook for the first few years, then switched to Boostnote because of its Markdown support and snippet syntax highlighting. One note per day, organized into folders by month.
It also is hugely valuable when performance review season rolls around. I can go through the whole year in a few minutes and remind myself of all the tasks I worked on, then summarize those in the "what I did" section.
https://whatgotdone.com/michael
I tried for a few months to make a business out of it, but there wasn't much interest, so I'm planning to open source the code in the next couple weeks.
A bit more about my motivation in creating this: https://mtlynch.io/status-updates-to-nobody/
I use Day One as I also use it for my personal journal. Plain text is great but I do like being able to add rich content (screenshots for example).
As you say being able to look back and know exactly what you were doing on a particular day is a powerful thing.
I've found that over time I have become a lot better at succinctly explaining the problems I faced and how I made progress with them. It is invaluable, even just over the weekend, in helping me 'reload' my brain when I return to work. It also helped me in communicating more technical subjects to others less technical.
It's a brilliant way to unwind and finish the day. I usually only have to spend 5 minutes on it so it isn't like it is a huge commitment.
I highly recommend everyone at least give it a go for a month and see if it works for you.
I believe everyone has times of marginal productivity in their lives, maybe some more than others. But if you can average out ahead of the curve, what does it matter? Showing the fact that you've had a slow week but finished the month on a high note seems like a great capability.
And if an employer doesn't recognize this and can't measure your net output, then hopefully another employer can.
I completely agree with taftster in a sibling comment.
I've had a lot of stress at work. Here's how I dealt with it:
I was once working for a boss who was really infuriating to deal with. To prevent myself from exploding at him, I would take a break, step outside in the beautiful sunlight, put in my earbuds, turn on some good music, and run. I channeled my frustration into exercise. I'd especially make a habit of doing this just before I ate lunch, which would stimulate muscle growth and make me happier and healthier. Somehow that stressful job got me into great shape.
I was once working at a place where all the policies were dysfunctional and things were constantly on fire. I dealt with this by pulling out my phone and using the Headspace app to think about nothing for a moment and calm myself down. When I got back to the work, I'd put on some "focus" music (music for programming, studying, etc) that would help me maintain my calm mood when implementing the fixes. I learned to distance myself from the problem and get people to talk to each other to work it out instead of having proxy arguments on other peoples' behalf.
I've had some pretty bad sleep problems as well. I got into the habit of playing videogames late at night, which really destroyed my sleep. It's really hard to sleep right after staring at bright screens and experiencing intense action. Now I have F.Lux or Night Shift enabled on all my machines and I avoid playing console games at night without wearing yellow safety glasses. Also, I've started adding concentrated lake water to my drinking water since a magnesium deficiency can make it difficult to sleep.
For depression, perhaps learn about Taoism?
If you really can't cope with the job, quit. It'll be even more stressful to try to find a new job while you're already working one. You can search for a new job using TripleByte, which saves a lot of time since you just have to do one coding test instead of 20.
Hope this helps. Good luck.
But burnout is an awful feeling. You aren't able to work. For me, I would stare at the screen for hours on end without being able to get started.
I found that 2 things helped me the most. First the pomodoro system. You are probably familiar with it, but just in case: you have a 25 minute session, where you devote yourself to nothing but concentrating on work. For me, it's unbelievably important to get my first pomodoro in as early in the day as possible. I also found that it is just as important that this pomodoro is coding: not reading mail. Not doing a status update. Not having a standup meeting. Not investigating some bug. I've got to write code as soon as I can in the day. That flips a switch for me. Very important, especially if you are burned out: show up for work significantly before your fist meeting of the day -- the meeting will suck the life out of you and you need some life to suck.
The next thing, strangely, is a TODO/log of what I'm doing. Being burned out means that everything is a barrier. Usually the barrier is too high, so you are stuck staring at it with no idea how to get over it (because normally you would just step over it).
When I first start a pomodoro, I write a TODO of what I'm going to do for the next 25 minutes. I find it's best to spend as little time as possible doing it. Just write down the first thing that comes to your mind about what you need to do. Write 3-4 items at least. Then start tackling the first one. Inevitably, you will find that your TODO was not good -- because you didn't spend time thinking about it. As soon as you realise what you need to do, update your TODO and then do it.
It's tempting to write the code and then write down what you did. I find that it works best to do it the other way around even though it breaks the flow. When you are burned out, flow is quite hard to maintain and any distraction is going to grab you hard. By focussing on making sure your TODOs are correct, it means that you can easily jump back in.
The biggest thing to realise is that you will often be punted out of the zone and will be staring at your screen. What you need to do is to say to yourself, "Just one more" -- which means, making an easy TODO for yourself and writing the code to fullfil it. Then "Just one more". Eventually you will get distracted. When you finish being distracted, turn on the pomodoro timer and say, "Just one more".
At first you may find it hard to do more than 4 pomodoros in a whole day. Don't worry about it. Just try to do as many as you can. Then the next day try to do more than the previous day. I have found that I can claw my way out of burnout pretty quickly like this. It doesn't take long before I'm enjoying my work again. After that, the productivity starts coming back and things start to feel easy again.
Hope this helps.
Write down everything you do and honor it as an accomplishment.
Getting out of bed. Reading an article about your craft. Brushing your teeth. Showering. Dressing. Reading somebody else's PR. Commenting on somebody else's PR.
Every. Single. Thing.
Attending a meeting. Having a hallway conversation. Answering an email or ten.
Not taking your own life. Surviving. Not doing other self-destructive things.
Chances are, if you are able to get out of bed (not always a given) you probably did a lot of "little" things. Those are achievements. And in your depression those things may have taken more effort than running a 5-minute mile.
Sure, the goal is to eventually accomplish more. That's fine. But honor the things you're doing.
And hey... good luck.
Ended up just adding a new "Work Journal" calendar to my google calendar.
Now, 5 minutes seems an impossibly small amount of time, and admittedly this is a difficult technique. It's also very tiring (I can't do it day after day), but once you get good at it, it's surprising what you can get done in 5 minutes. You don't necessarily need to have written code -- just made some progress towards understanding something, etc.
Later, I'll go over my notes. I've got everything annotated every 5 minutes which means that it's ripe for thinking about how I can improve. Did I make a wrong turn somewhere that wasted me time? Was there a way I could have detected that? Did I decide not to do something test first when it would have been better to do so? Etc, etc.
I should point out that while I have a timer, I only use it as a suggestion -- I don't have any notifications for instance. It's just that if I glance down and notice my timer has gone (or is close), then I wrap up what I'm doing to get to the reflection stage. Similarly, if I'm writing TODOs and it's being productive, I don't mind doing it for 5 minutes or so. Finally, if I run into something really puzzling, then I just turn off the timer. Some problems need thinking time (though I have found that having only a few minutes to make progress often forces me to try something in order to get more information and that will crack the nut -- indeed, far more often than I would have ever suspected).
It's the only tool I've found that really helps me improve my technique. The other pretty cool thing about it is that I've found that this log helps me get in and out of the zone extremely quickly. Even if I've put it down overnight, I'm right back into it within a minute or so.
I am measurably much more productive with this method (like 2 or 3 times more productive), which surprised me initially (I thought I would be much less productive). The real downside is that it's draining. I can't keep it up for more than a couple of days at a time.
Anyway, very dissimilar to what you were talking about, but I highly recommend it for those interested understanding what they are doing and how to improve.
I currently journal my day at the end, noting when I worked on the wrong thing and why.
It would be interesting to record the screen for a whole week day and then review and annotate for insight.
Some day traders used to do this. Athletes do it all the time.
I can both back date and future date entries.
I keep a tag called "Daily Entries" with a timestamp on the day of what I use, I can automatically add a timestamp with the shortcut "CTRL + T"
Future dating allows me to plan ahead as well.
I write an entry about a future event (ie a meeting) and prefill some information. Then when the meeting happens, I just open up the entry and start entering.
I've been using Logbook since 1st May, and personally now have 1139 entries, and 576 tags.
I've been recording:
- Recipes - Meeting notes - Shower Thoughts - Career timeline - Car maintenance - "Best Practices" on a variety of subjects - Many more
I also use timestamps a lot, and have a preference for how they are formatted so I created https://timestamps.aizatto.com
I hope some of these may help people here
[0] Oh, in case anyone is curious. My logs stay with the company when I leave. I don't take any IP with me.
I'd really encourage anyone to give it a try.
The best time to write a tutorial is as you learn a thing yourself. You learn it better for doing it and others benefit from it more because it automatically comes from a beginners perspective.
No. Just no. Do not ever be funny in code. No one else likes your humor, and it's distracting. (Ignoring the other reasons "GodComponent" is a bad name.)
Two things came from that: I have gotten a chuckle from all the developers I introduced to that code, and no one has forgotten about it.
Some humor is useful.
This is different from insisting that helper functions in brains.c be of type pinkyfunc_t.
[0] I was tempted to undercut my own point and write cromulent there instead.
(a) You're not supposed to tell anybody what they are.
(b) Offensive passphrases are easier to remember.
On the other hand if you're protecting secrets actually worth something...
"Jmpeax's Law" doesn't really roll off the tongue though...
I'm going to continue injecting some light humor into my code and it'll be fine (especially unit test code).
I avoid humor in main code, but in unit test code when you have to come up with dummy bits of test data or variable names, I love getting funky there :)
Just googled it and, ... nah, I wouldn't approve that PR!
(Have never heard it used down here in Australia. We've got plenty of other sayings that are local to us though.)
I suspect there are a lot of words that used to be safe that are less so now :P
Namings should be descriptive not idiosyncratic.
It might be just like the guy I spoke to last month that said he just makes everything public when writing Java. Some people can have opinions that differ from best practice, it doesn't justify them, however.
Express your personality when you speak to people face to face, tell a joke, make witty observations at lunch, or in a code review meeting, don't express your personality in manifest idiosyncracies in your comments and code.
try {
...
} catch (Exception up) {
...
throw up; //hehe
}
The GodComponent as a name is not.We have one in our company named right now named Harbinger, neat name... but wtf is it? Boring names are boring, but they tell other people, and future you, what they are or do.
My 2 cents: There are two things to consider:
1. reviewability
2. deployment risk
If it takes a colleague 3 days to review your code, your PR is too big. If you panic, on the thought of deploying this ever, your PR is too big.
On the other side:
- Huge PRs that only change formatting are fine. Easy review. Low risk if properly automated/tested.
- Largs PRs that are feature neutral are acceptable as long as they are reviewable.
- PRs that refactor 2000LOC, fix 2 bugs and add 3 features are not a good idea.
1. Some people balk at you making lots of small PRs, because it feels like noise to them. 2. Some people/organizations make you do a lot of work on a separate branch and then want you to PR just once for the final feature you're implementing.
2. That's fine, your branch has the series of small PRs that people can review.
- if a large refactor moves code around in addition to changing logic, omit the pure moves from the diff and provide a list of files moved in a description
- if a large refactor involves a lot of renaming, or other mechanical manipulation, in addition to a little bit of logic changes, split those apart. That way there will be one large mechanical diff, where you can state in the description, "Yes I changed 500 files and there are 20 pages of diffs but the nature of changes is the same as in the first file." This is vastly easier to review for your peers.
- A useful safe deployment trick, when feasible: guard new functionality with a kill switch, as well as some kind of sampling gate (e.g. use new logic only where customer id % 31 == 0). Then when proved remove old code in a followup.
Unit tests are for refactoring and declaring behaviour. Additionally, a lot of people have made the same observation: Code that is easy to unit test tends to be more modular and have better architecture. If you are struggling to test a function, think about how you can change your design to make testing easier. It will probably improve your code quality.
Integration tests are for finding bugs and exceptions and should be a part of CI/CD.
You want both. The more testing the better.
Comments: I find comments, outside of docstrings, a smell. Even then: Docstrings often become a substitution for a decent type system, so maybe think about what is happing there as well.
Documentation should be generated from your codebase. Otherwise, it will inevitably become out of date as people forget to update it. If you need to comment on what something is doing, usually you can move that behaviour into a function and test that function.
But I'm not sure everything fits in there. Where do you document processes like how to test stuff that isn't possible to test in a local-dev environment?
Or .. what the IDs that have some business meaning, mean.
I feel like that would go into the README or an attached wiki page.
It is funny, after writing my MILLIONTH validation library, I've been thinking OpenAPI or APIBlueprint driving my validation and parsing library at my web application boundaries is the way to go... which is kind of the opposite. Documentation driving my software xD
That's the usual argument, and the counter-argument is always the same: you shouldn't comment the what (though I'll argue there's always exceptions), you should comment the why.
Why are you doing this processing here rather than there? Why do you not apply the usual pattern in this specific case? Why does this code, that will make you want to refactor, has been written like this?
> Comments: I find comments, outside of docstrings, a smell.
But is this really the case? I find comments like these invaluable:
/*
* Mark walreceiver as running in shared memory.
*
* Do this as early as possible, so that if we fail later on, we'll set
* state to STOPPED. If we die before this, the startup process will keep
* waiting for us to start up, until it times out.
*/
SpinLockAcquire(&walrcv->mutex);
https://github.com/postgres/postgres/blob/master/src/backend...Part of the job of a developer is to communicate
- domain model (Concepts, Relations between them)
- intention behind the code (Why is this code here?)
- possible pitfalls (I tried this, it does not work because ...)
- limitations (TODO: This special case does not really work, yet)
for your colleagues and future heirs.
How would you ever cramp information like this into variable names and types? (... without introducing so much abstractions that the code becomes unreadable).
Extremely high-performance database code is not what most of us are doing, however. We are doing enterprise software development to send emails and scrape money out of people.
I would want that function to be multiple smaller functions with docstrings and such, but obviously, that would add stackframes to the call stack and be slower.
Additionally, many modern compilers have an easier time reasoning about and optimizing multiple smaller functions as opposed to huge functions with a ton of variables and logic. Plus large functions have an impact on garbage collection etc. etc.
That's true. But look at the overall coding style in that file:
Code is structured into cohesive blocks, which are prefixed by a comment which explains in english language the intention, pitfalls, limitations of the following code.
I find this quite elegant and readable. An ideal to aspire to.
I am not advocating nonsensical JavaDoc:
// Get's foo from bar
private Foo get_foo(Bar bar);
If you are able to just use names and types to document your intentions, pitfalls etc ... then by all means, do just this.
E.g. for( person in address_book ) {
body = template.render( name => person.name, ... )
mail = Mail.new(person.email, body)
mailgun.queue(mail)
}
However, if stuff get's more nuanced don't be afraid to use english language to explain what you are doing.
You future self will thank you : )That's sort of the point. Step 1, your code should be self explanatory. When the natural interpretation a reasonable person would have from reading the code differs from reality: that's when you add Step 2: add comments to "fix" the gap between perception and reality. The less Step 2 is necessary the better.
I have tried that style in the past, and have reverted to writing longer functions with intermittent comments. I now consider "single caller functions" a smell.
If logic is serial (do A, then B, then C) it's fine to have serial code:
main() {
... A ...
... B ...
... C ...
}
The issue with splitting out the intermediate steps into functions is, that the serial flow is broken.
Instead of the logic now looks something like A(...){ ... }
C(...){ ... }
main() {
A(...)
... B ...
C(...)
}
Where B might have been a tiny task, that is not worth splitting out.
In effect:- The ordering of the logic is broken.
- Passing arguments can be a pain, if a lot of pieces are touched.
And what have you gained? Not sure there are many upsides besides debatable aesthetics of avoiding inline code comments.
// foo = 12345
doThing1(12345, 5) // foo
doThing2(12345, 8) // foo
Preferring self-descriptive code instead of comments helps stop them from doing things like this.Neither function/type/whatever names, nor unit tests document architecture, concurrent behaviour, locking, ... to a significant degree. For simpler stuff that's fine, but it doesn't take that complicated a problem that some interdependencies aren't obvious anymore.
Even in the simpler cases that then often leads to APIs/Architecture that appears "fractured". Because the intent from the time the code was originally written isn't visible enough, subsequent work is designed differently, rebuilds parts of infrastructure, ... That leads to harder to maintain code over time.
IME there's a significant difference in how much effort is worthwhile to put into comments and understandable code depending on the expected lifetime, staff turnover, total size of a project.
Test as little as possible/responsible.
I think it was Kent Beck who first articulated that, though it was something many people converged on in the early 2000s in the XP world. Of course it doesn't mean test nothing, it's recognizing tests are liabilities (as all code is) and we need to make sure they are serving a purpose otherwise delete them / refactor them to get rid of duplication of testing and overly verbose long winded tests that keep repeating things over and over again and again, saying the same thing repeatedly, doubling up on testing :)
"Unit tests are one of the CORNER STONES of Extreme Programming (XP)"
http://www.extremeprogramming.org/rules/unittests.html
Also see: https://hygger.io/blog/tests-in-extreme-programming/
If development is tests-driven and you should minimize the amount of tests then doesn't that also mean you should minimize the amount of development?
Well of course, do not develop more than is needed. But that kind of trivializes the whole agile ideology: "Develop As Little As Possible, that allows you to remain the most Agile"
Minimizing the amount of development also minimizes the number of bugs. Sounds like a great concept.
this is his SO answer where he talks about it... https://stackoverflow.com/questions/153234/how-deep-are-your...
In the above link I don't see anything about "delete your tests when not needed anymore", or did I miss it?
How do you know when some tests are "not needed any more"? Isn't the idea of regression-testing to keep tests around so you know if any new code will break them? That should give you the "agility" to refactor your code, I think, is what the proponents of XP would say.
Strong disagree. As a general principle, a refactoring that changes no behavior should break no tests. It's all well and good to factor out a chunk of code into a separate internal function for code clarity, but don't go writing a test for it. Don't plumb your tests through the internals of the code. If you're factoring that piece of functionality out into the public interface of another component, sure, you should test the public interface of that component. But if you're factoring it out into an implementation detail of the same component it was originally part of don't write a test that cares about the details of you implementation. The functionality it provides should already be testable via calling the function it was originally factored out of.
I would say that unit tests impede refactoring. If your refactoring changes classes interfaces or API, you are likely to have to change your unit tests as well.
> Code that is easy to unit test tends to be more modular and have better architecture. If you are struggling to test a function
Same goes with documentation. If you can't explain simply what a function does, you may want to rewrite it.
Strongly disagree. How do you modify a function or interface if you do not know what breaks when you use that function?
Personally, I do not like to have to grok the entire codebase and keep a map of it in my brain at all times. I like to concentrate on the behaviour I am currently implementing and be VERY sure that the changes I am making are not breaking elsewhere.
If changing a function breaks a bunch of tests: Good. Otherwise, all of those broken tests would have been bugs I get to find in production and explain to my boss.
I'm not saying unit tests don't have their use, but as far as refactoring goes, I think they are a hindrance. Unless we talk about rewriting just a function.
As a pretty senior dev myself I always tell people to have an actual design in mind. Know what you are trying to achieve and when something goes wrong you should be able to explain what you expected the system to do on that situation . A lot of people don’t seem to have a clear mental image of the end goal but are overwhelmed .
Of course you should be flexible but you need to know where you want to be in order to make good decisions.
Don't agree with this at all. If you're relying on people to maintain knowledge then you're doing it wrong and setting yourself up for failure. Document the why.
I suggest the opposite: if they take their own words seriously and this knowledge is the main value than I’d assume they grow in great lenghts documenting that main value — because it would be (as you rightly noticed) lost.
To me that is one of the major goals of any code writing. Some new hire I've never met should have a fair chance of working with this in 6 months.
I would argue that to any experienced software person, in the context of a project the code means "code and documentation" (containing domain knowledge, implementation history and intent inexorably bound together as one unit). Whereas, the quoted phrase suggests a dichotomous perception.
Good luck documenting all that. Good luck making that document discoverable and readable.
Have they tried something else ? Was it the best solution chosen after a review or something quickly put together ? Likely you'll never know.
There's nothing in their point that refers to documentation.
"Programming as Theory Building":
https://web.archive.org/web/20150224214427/http://www.dc.uba...
(Hint... it's me.)
I've updated the website :)
"The best way to get the right answer on the Internet is not to ask a question, it's to post the wrong answer."
https://en.wikipedia.org/wiki/Ward_Cunningham#Cunningham%27s...
What all steps can you take to reduce the risk of disaster?”
Honestly, I talk about derisking most in two contexts in our projects: schedule, invention.
Normally this means that derisking is about frontloading unknowns and finding pivot decisions that reduce the likelihood of getting too far in the wrong direction or accumulating too much uncertainty.
I don’t use “risk” too often when talking about fault tolerant code or system design. If you’re taking on “risk” in code, like the chance of a lost message, a race condition, or corrupted data, I’m going to take away the keys.
Note: I encounter shoddy “we can go hours without a crash, so it’s good” work more than I’d like to admit. It is possible to know why code and systems fail (and account for it) much more than has become industry norm these days.
https://podcasts.apple.com/de/podcast/team-human/id114033181...
How does the code get access to the database?
I've lived in AWS-land for so long, I don't know how the non-cloud world manages secrets.
All source code eventually "wears out" and has to be rewritten.
This person became a good engineer in only one year! :)
https://www.reddit.com/r/programming/comments/cv6tnu/self_po...
I guess spelling wasn't one of them?
But other than that, it's a nice blog post. I like the "human log" suggestion - should really pick that one up. I've been doing that already, but only for my servers...
What I do is I commit to Git every day and I enter a commit-comment
"There are two hard things in computer science: cache invalidation, naming things, and off-by-one errors. - Jeff Atwood"
This is not novel, nor insightful.
"Premature Optimization Is the Root of All Evil". I've reached a point where every time I hear someone say this, I legitimately ignore everything else they say.