Tom's Notes for Software Wizards
# General advice **Studying and working basics** - Eliminate distractions, don't keep checking email, switching songs on youtube etc. - Don't overwork yourself - recognize when you need to take breaks. - Simplify things as much as you can - When you're working through a book, type out the example code and do all the exercises. - if you build something document it! take notes about what you have learned. - Know what your code does and why it does it. Do not commit guesswork into your repository. - On a bigger projects include a build process, automated tests, a README.md file that clearly explains the project, and practice using meaningful commit messages. Use each project to demonstrate that you can deliver an optimized product. Implement tests, use your build process to minimize assets, use a linter, use style guides and naming conventions etc **Time** - Slicing. Take a big project, cut it into thin slices, and rearrange the slices to suit your context. I can always slice projects finer and I can always find new permutations of the slices that meet different needs. - One thing at a time. We’re so focused on efficiency that we reduce the number of feedback cycles in an attempt to reduce overhead. This leads to difficult debugging situations whose expected cost is greater than the cycle overhead we avoided. - Make it run, make it right, make it fast. (Example of One Thing at a Time, Slicing, and Easy Changes) - Easy changes. When faced with a hard change, first make it easy (warning, this may be hard), then make the easy change. (e.g. slicing, one thing at a time, concentration, isolation). Example of slicing. - Concentration. If you need to change several elements, first rearrange the code so the change only needs to happen in one element. - Isolation. If you only need to change a part of an element, extract that part so the whole subelement changes. - Baseline Measurement. Start projects by measuring the current state of the world. This goes against our engineering instincts to start fixing things, but when you measure the baseline you will actually know whether you are fixing things. **Learning** - Call your shot. Before you run code, predict out loud exactly what will happen. - Concrete hypotheses. When the program is misbehaving, articulate exactly what you think is wrong before making a change. If you have two or more hypotheses, find a differential diagnosis. - Remove extraneous detail. When reporting a bug, find the shortest repro steps. When isolating a bug, find the shortest test case. When using a new API, start from the most basic example. “All that stuff can’t possibly matter,” is an expensive assumption when it’s wrong. E.g. see a bug on mobile, reproduce it with curl - Multiple scales. Move between scales freely. Maybe this is a design problem, not a testing problem. Maybe it is a people problem, not a technology problem [cheating, this is always true]. **Transcend Logic** - Symmetry. Things that are almost the same can be divided into parts that are identical and parts that are clearly different. - Aesthetics. Beauty is a powerful gradient to climb. It is also a liberating gradient to flout (e.g. inlining a bunch of functions into one giant mess). - Rhythm. Waiting until the right moment preserves energy and avoids clutter. Act with intensity when the time comes to act. - Tradeoffs. All decisions are subject to tradeoffs. It’s more important to know what the decision depends on than it is to know which answer to pick today (or which answer you picked yesterday). **Risk** - Fun list. When tangential ideas come, note them and get back to work quickly. Revisit this list when you’ve reached a stopping spot. - Feed Ideas. Ideas are like frightened little birds. If you scare them away they will stop coming around. When you have an idea, feed it a little. Invalidate it as quickly as you can, but from data not from a lack of self-esteem. - 80/15/5. Spend 80% of your time on low-risk/reasonable-payoff work. Spend 15% of your time on related high-risk/high-payoff work. Spend 5% of your time on things that tickle you, regardless of payoff. Teach the next generation to do your 80% job. By the time someone is ready to take over, one of your 15% experiments (or, less frequently, one of your 5% experiments) will have paid off and will become your new 80%. Repeat. **On achieving peak performance** - Turn off the computer. Grab a pencil and some paper. Sketch out your design. Review it with your peers. Then write the code. - Avoid gold plating - do only what is asked of you (in terms of requirements) - Understand business requirements and do it right the first time - Thoroughly understand your environment and tools - Become a fantastic typist, use keyboard shortcuts instead of the mouse - Take an iterative approach and build in sanity checks to ensure you are on the right path - Don't reinvent the wheel, consider reusing past work and the work of others - Eliminate distractions, don't keep checking email, looking outside, talking to coworkers, etc. - Don't overwork yourself - recognize when you need to take breaks - Do a postmortem on the last project estimates vs. actual time taken and figure out where the extra time went. - simplify what you are doing so that it is absolutely as simple as possible **Traits of an experts** - Identify patterns faster and successfully predict future events - Recognize anomalies - especially negative anomalies i.e. something didn't happen that should - quickly take appropriate actions. - Identify leverage points within their architecture to solve new problems and deliver new features. - Make fine discriminations of events and data - Understand the tradeoffs and consequences of an option. - Recognize expertise in others and defer as many decisions as possible to that expertise. - Their ability to "context switch" when describing a situation to other experts vs novices vs non-participants. - Skate where the puck is going, not where it is. - Rapidly Climb Learning Curves The ability to quickly learn enough about new subjects to be useful. New technologies or APIs; new algorithms; mathematical or statistical subjects; and most importantly, your problem domain. Some of this ability is a skill, "knowing how to learn", which covers google-fu, reading comprehension, prioritization, time management, etc. Some of this ability comes from having enough aggregate experience that new information just clicks into place like jigsaw puzzle pieces. Some of this ability comes from the confidence of having climbed enough seemingly insurmountable learning curves that this next one is "just another day at the office". - Understand The Customer The best engineers are half product managers. You can easily get a 10X improvement in productivity by building the right features and not building the wrong ones. Yes, professional product managers are great, but technical limitations often impact product design. A great engineer knows when to push back or suggest alternatives. This requires empathy not only for the customer, but for the product management team. This ability is also tightly coupled with #1 - you need to quickly come up to speed on the problem domain, whatever that may be. If you wan't to be a great engineer, don't study algorithms (until you need an algorithm, of course), study the particular business that you're in. # Software development Comment your code well. That doesn’t simply mean “Add a lot of comments.” You don’t say in English what is better said in code. Rather, you say in the comments — as clearly and briefly as you can — what can’t be said clearly in code. ## Notes on Testing Testing now will help prevent weird surprises later. **TDD** - Design/write the interface for your class - Write tests that exercise that interface... giving fixed input and expecting fixed output. - All tests will initially fail because the class was not written yet... you only have the interface. - Begin writing class implementation. - More and more tests gradually pass as the functionality gets added - Once all tests pass, you know the class is complete and functional (assuming you have tests which exercise all functionality) **Development-driven testing** - First, I think carefully about the specification, and write an implementation to handle every conceivable corner case. This usually compiles and works on the first try, except when I encounter compiler bugs (which is a frequent occurrence, working on the frontier of C++). - Then I go back to the specification, and write careful tests, trying to exercise every corner case. Generally I can't be quite as exhaustive about this (the universe of possible inputs to template code is extremely infinite). This usually passes on the first try too, but sometimes reveals more compiler bugs, or occasionally some interaction with the language that I didn't think of. - The important thing is not the order in which I write tests, but the deep thinking about the specification. The reverse order with equal thought would be okay, I just don't work like that. What I am allergic to is the notion that a few test cases can be written up front, then anything that passes those tests is good. It is rarely possible to actually write tests that cover every conceivable boundary condition, whereas it is far easier to write code that handles them. **Links** - https://martinfowler.com/bliki/TestPyramid.html - https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html - https://www.mountaingoatsoftware.com/blog/the-forgotten-layer-of-the-test-automation-pyramid - https://martinfowler.com/articles/practical-test-pyramid.html - http://blog.codepipes.com/testing/software-testing-antipatterns.html ## Notes on Debugging **Practical debug advice** - The name of the program - The purpose of the program - Who wrote this code and when - Version numbers - What complicated code fragments are supposed to do - What the general design ideas are - How the source code is organized - What assumptions are made about inputs - What parts of the code are still missing and what cases are still not handled - Use meaningful names - That doesn’t simply mean “Use long names.” - Use a consistent layout of code. - Break code into small functions, each expressing a logical action. + Try to avoid functions longer than a page or two; most functions will be much shorter. - Avoid complicated code sequences. + Try to avoid nested loops, nested if statements, complicated conditions, etc. Unfortunately, you sometimes need those, but remember that complicated code is where bugs can most easily hide. - Use library facilities rather than your own code when you can. + A library is likely to be better thought out and better tested than what you could produce as an alternative while busily solving your main problem. **Conducting Experiments** - Testing systems with small examples to verify that they conform to the documentation or to understand their response when there is no documentation, - Testing small code changes to see if they actually fix a bug, - Measuring the performance of a system under two different conditions due to imperfect knowledge of their performance characteristics, - Checking the integrity of data, and - Collecting statistics that may hint at the solution to difficult or hard-to-repeat bugs. ## Notes on Optimization **How to Optimize Loops** - Remove floating point operations. - Don't allocate new memory blocks unnecessarily. - Fold constants together. - Move I/O into a buffer. - Try not to divide. - Try not to do expensive typecasts. - Move a pointer rather than recomputing indices. **Dealing with I/O expense** - caching (avoiding I/O) - representation (making I/O cheaper by representing data more efficiently) - locality (push the computation closer to the data.) ## Classic Software Development Mistakes If you're not actively scanning through the list of Classic Software Development Mistakes as you run your software project, you have no idea how likely it is you're making one of these mistakes right now. **People Mistakes ** - Undermined motivation - Weak personnel - Uncontrolled problem employees - Heroics - Adding people to a late project - Noisy, crowded offices - Friction between developers and customers - Unrealistic expectations - Lack of effective project sponsorship - Lack of stakeholder buy-in - Lack of user input - Politics placed over substance - Wishful thinking **Process Mistakes** - Overly optimistic schedules - Insufficient risk management - Contractor failure - Insufficient planning - Abandonment of planning under pressure - Wasted time during the fuzzy front end - Shortchanged upstream activities - Inadequate design - Shortchanged quality assurance - Insufficient management controls - Premature or too frequent convergence - Omitting necessary tasks from estimates - Planning to catch up later - Code-like-hell programming **Product Mistakes ** - Requirements gold-plating - Feature creep - Developer gold-plating - Push me, pull me negotiation - Research-oriented development **Technology Mistakes** - Silver-bullet syndrome - Overestimated savings from new tools or methods - Switching tools in the middle of a project - Lack of automated source control # Finding a job Anecdote: Finding c++ job: In the end the company I work for seemed really cool, but they had no "careers" or "work here" section on their web site. So I cold called their sales department and asked if I could talk to an engineer just to ask some questions as a student. Got an email back a few days later from the head of engineering and the rest is history. Most of the companies in the industry are small and don't actively recruit as far as I can tell. Makes the networking/cold call part that much more necessary. ## How to find F# jobs (author Scott Wlaschin (@swlaschin)) People often ask me how to find F# jobs. I don't have any special connections to companies using F#, and I don't have any special tricks either. I wish I did! So, given that, here's my take on F# jobs. **Job hunting** For job hunting my suggestions are: * You could contact [some of the companies known to be using F#](https://github.com/Kavignon/fsharp-companies). * Follow [the #fsharp tag on Twitter](https://twitter.com/search?q=%23fsharp&src=typed_query&f=live) -- people sometimes post jobs there. * The [F# slack](https://fsharp.slack.com/) has a #jobs channel. If you've not already joined, you can join using the guide here https://fsharp.org/guides/slack/ * Look on the usual job boards. For example: [Indeed.com](https://www.indeed.com/jobs?q=F%23), [StackOverflow Jobs](https://stackoverflow.com/jobs?q=f%23), and [FunctionalJobs.com](https://functionaljobs.com/jobs/search/?q=F%23). Also the "HN Who's Hiring" posts (https://hnhiring.com/). In some cases F# is sometimes mentioned as a "nice to have" but even if you have to code in C# it means the company should be "functional-friendly" and open to change. **Increase your visibility** Most of the best jobs are found by word of mouth rather than being advertised. So in addition to job hunting, I strongly suggest networking and making people aware of you. For example: * Participate in the F# slack, twitter, and other F# forums * Create F# tools or projects that are useful to the F# community * Make blog posts or videos about F# These things will all make you better known in the F# community. That way, you will be first to find out about opportunities, and people might contact you directly if they need help. **Expand your horizons** Also, consider expanding to other functional languages. F# is great, but so is OCaml, Elm, ReasonML, Scala, Haskell, etc. If you know one of them, you can normally pick up the others reasonably quickly. Some people are even doing heavily functional C# and Typescript, so that might be an alternative as well. **Pick a job based on the challenge not the programming language** If you're bored at your job, it's easy to think that using a new programming language will help. That will be true in the short term, and it's good for your resume/CV! But instead, think about finding a job where there is an interesting challenge that appeals to you, or where the culture is good. If you enjoy your day job, you can still play with F# in your free time. On the other hand, if your day job is boring, then being bored and writing F# is not much better than being bored and writing C#! ## Job sources **Companies to look at** - [companies.txt](./companies.txt) **Remote jobs** - https://github.com/lukasz-madon/awesome-remote-job - https://github.com/remoteintech/remote-jobs - https://docs.google.com/spreadsheets/d/1TLJSlNxCbwRNxy14Toe1PYwbCTY7h0CNHeer9J0VRzE/edit#gid=1279011369 - http://telecommunity.net/companies-that-are-always-hiring-telecommuters/ - https://weworkremotely.com/ - https://www.wfh.io/ - https://remoteok.io/ - https://jobspresso.co/ - https://remotive.io/ - https://www.workingnomads.co/jobs - http://remoteinternships.co/ - https://github.com/lukasz-madon/awesome-remote-job - https://www.reddit.com/r/jobbit/ - https://bestremotejob.com - https://www.remotepython.com/ - https://www.python.org/jobs/ ## Interview Prep - Competitive programer handbook: https://cses.fi/book/book.pdf - Neetcode 150, Blind/Grind 75, alphabet150.com - [awesome leetcode github](https://github.com/ashishps1/awesome-leetcode-resources?tab=readme-ov-file) - General Software Engineer Interview Guide (How to get into FAANGs) [link](https://colacap.github.io/software-engineer-interview-guide.html) - [Top Interview 150 leetcode](https://leetcode.com/studyplan/top-interview-150/) - [Leetcode 75 by neetcode on yt](https://docs.google.com/spreadsheets/d/1A2PaQKcdwO_lwxz9bAnxXnIQayCouZP6d-ENrBz_NXc/edit?gid=0#gid=0) - [Leetcode study guides](https://www.piratekingdom.com/leetcode/study-guide) - [Software Engineering Interview Study Guide - Outline ](https://docs.google.com/spreadsheets/d/19vhVZ18LAvZTtKWn-cuJzto3AMpJ1npYK4vDWppDnrQ/edit?gid=0#gid=0) - [LEETCODE STRATEGY FOR 2024 yt](https://www.youtube.com/watch?v=ZBmQlFeyEYI&t=337s) - [Mastering leetcode blog post](https://www.pablomusumeci.com/p/mastering-leetcode?open=false#%C2%A7free-vs-premium) - [labuladong/fucking-algorithm](https://github.com/labuladong/fucking-algorithm/tree/english) - Algorithms, 4th Edition - https://www.designgurus.io/course/grokking-data-structures-for-coding-interviews - fang prep and general study approach: https://www.reddit.com/r/leetcode/comments/1f29lfj/signed_my_faang_offer_heres_what_i_did/ - fang study approach: https://www.reddit.com/r/leetcode/comments/1av4jlw/comment/kr8doy9/ - more fang prep: https://www.reddit.com/r/leetcode/comments/1e9rnmy/how_i_went_from_lowlevel_startup_to_faang_in_3/ - note: Cracking the Coding Interview is a sub par resource at this stage. You need a combo of an in depth algorithm textbook/course and a plethora of leetcode **Leetcode Patterns/Templates** - LC but filter based on patterns - https://seanprashad.com/leetcode-patterns/ - Substring problem patterns - https://leetcode.com/problems/minimum-window-substring/solutions/26808/Here-is-a-10-line-template-that-can-solve-most-'substring'-problems/ - Maximum Sliding window pattern - https://leetcode.com/problems/frequency-of-the-most-frequent-element/solutions/1175088/C++-Maximum-Sliding-Window-Cheatsheet-Template/ - 2 Pointer problems - https://leetcode.com/discuss/study-guide/1688903/Solved-all-two-pointers-problems-in-100-days - Backtracking patterns - https://medium.com/leetcode-patterns/leetcode-pattern-3-backtracking-5d9e5a03dc26 - Backtracking Template - https://gist.github.com/RuolinZheng08/cdd880ee748e27ed28e0be3916f56fa6 - Binary Search Template - https://leetcode.com/discuss/study-guide/786126/Python-Powerful-Ultimate-Binary-Search-Template.-Solved-many-problems - Tree Traversals - https://leetcode.com/discuss/study-guide/937307/Iterative-or-Recursive-or-DFS-and-BFS-Tree-Traversal-or-In-Pre-Post-and-LevelOrder-or-Views - Graph Patterns - https://leetcode.com/discuss/study-guide/655708/Graph-For-Beginners-Problems-or-Pattern-or-Sample-Solutions - All Types of String Questions for practice - https://leetcode.com/discuss/study-guide/2001789/Collections-of-Important-String-questions-Pattern - Learn BFS DFS for Trees (Part 1) - https://medium.com/leetcode-patterns/leetcode-pattern-1-bfs-dfs-25-of-the-problems-part-1-519450a84353 - Learn BFS DFS for Trees (Part 2) - https://medium.com/leetcode-patterns/leetcode-pattern-2-dfs-bfs-25-of-the-problems-part-2-a5b269597f52 - P.S. - FREE Company Tagged Question List - https://leetracer.com/screener **dynamic programing** - https://www.youtube.com/watch?v=oBt53YbR9Kk - https://leetcode.com/discuss/general-discussion/458695/dynamic-programming-patterns - https://leetcode.com/discuss/study-guide/1437879/Dynamic-Programming-Patterns - https://codeforces.com/blog/entry/43256 **system design** - https://www.hellointerview.com/learn/system-design/in-a-hurry/introduction - https://github.com/donnemartin/system-design-primer - https://github.com/preslavmihaylov/booknotes/tree/master/system-design/system-design-interview **youtube channels** - https://www.youtube.com/@GregHogg/playlists - https://www.youtube.com/playlist?list=PLliXPok7ZonmkC28ThsH6xrCQY1jbziro - https://www.youtube.com/@crackfaang/playlists - striver - system design - https://www.youtube.com/@jordanhasnolife5163 ### Advice and notes Grind leetcode, practice talking through solutions, practice behavioral questions, reach out to recruiters, believe in yourself. I started waking up at 5am to leetcode for 2-3 hours before work. It was completely miserable but I really wanted that sweet FAANG comp and was motivated enough to stick to it. For me at least, I could not force myself to grind LC after work since my brain had clocked out. Morning grind worked amazingly for me because I felt my mind was completely focused and receptive to new ideas. You should try it and see how it goes for you. Use a temp agency. They'll do all the looking for you. LinkedIn isn’t worth your time, honestly. Try focusing on other job search channels instead. - Check company websites weekly: Many companies post genuine job openings on their own /careers pages, so compile a list of target employers and keep an eye on these pages for direct applications. - Use job listing sites that pull positions from company websites: Some platforms automatically collect job postings straight from company sites. - For remote job searches, use Google Maps globally: This unique approach involves searching for companies worldwide in your industry and applying directly. - Consider recruitment services on Fiverr: Some freelancers specialize in job hunting for $20-$80, offering two options: - They locate and apply to job listings in your field on your behalf. - They gather contacts from relevant departments within your industry, providing names, email addresses, and more in an Excel sheet (pricing may vary per contact). # Career Advice **90% of programming jobs are in creating Line of Business software**: Economics 101: the price for anything (including you) is a function of the supply of it and demand for it. Let’s talk about the demand side first. Most software is not sold in boxes, available on the Internet, or downloaded from the App Store. Most software is boring one-off applications in corporations, under-girding every imaginable facet of the global economy. It tracks expenses, it optimizes shipping costs, it assists the accounting department in preparing projections, it helps design new widgets, it prices insurance policies, it flags orders for manual review by the fraud department, etc etc. Software solves business problems. Software often solves business problems despite being soul-crushingly boring and of minimal technical complexity. For example, consider an internal travel expense reporting form. Across a company with 2,000 employees, that might save 5,000 man-hours a year (at an average fully-loaded cost of $50 an hour) versus handling expenses on paper, for a savings of $250,000 a year. It does not matter to the company that the reporting form is the world’s simplest CRUD app, it only matters that it either saves the company costs or generates additional revenue. There are companies which create software which actually gets used by customers, which describes almost everything that you probably think of when you think of software. It is unlikely that you will work at one unless you work towards making this happen. Even if you actually work at one, many of the programmers there do not work on customer-facing software, either. **Engineers are hired to create business value, not to program things**: Businesses do things for irrational and political reasons all the time (see below), but in the main they converge on doing things which increase revenue or reduce costs. Status in well-run businesses generally is awarded to people who successfully take credit for doing one of these things. (That can, but does not necessarily, entail actually doing them.) The person who has decided to bring on one more engineer is not doing it because they love having a geek around the room, they are doing it because adding the geek allows them to complete a project (or projects) which will add revenue or decrease costs. Producing beautiful software is not a goal. Solving complex technical problems is not a goal. Writing bug-free code is not a goal. Using sexy programming languages is not a goal. Add revenue. Reduce costs. Those are your only goals. Peter Drucker — you haven’t heard of him, but he is a prophet among people who sign checks — came up with the terms Profit Center and Cost Center. Profit Centers are the part of an organization that bring in the bacon: partners at law firms, sales at enterprise software companies, “masters of the universe” on Wall Street, etc etc. Cost Centers are, well, everybody else. You really want to be attached to Profit Centers because it will bring you higher wages, more respect, and greater opportunities for everything of value to you. It isn’t hard: a bright high schooler, given a paragraph-long description of a business, can usually identify where the Profit Center is. If you want to work there, work for that. If you can’t, either a) work elsewhere or b) engineer your transfer after joining the company. Engineers in particular are usually very highly paid Cost Centers, which sets MBA’s optimization antennae to twitching. This is what brings us wonderful ideas like outsourcing, which is “Let’s replace really expensive Cost Centers who do some magic which we kinda need but don’t really care about with less expensive Cost Centers in a lower wage country”. (Quick sidenote: You can absolutely ignore outsourcing as a career threat if you read the rest of this guide.) Nobody ever outsources Profit Centers. Attempting to do so would be the setup for MBA humor. It’s like suggesting replacing your source control system with a bunch of copies maintained on floppy disks. **Don’t call yourself a programmer**: “Programmer” sounds like “anomalously high-cost peon who types some mumbo-jumbo into some other mumbo-jumbo.” If you call yourself a programmer, someone is already working on a way to get you fired. You know Salesforce, widely perceived among engineers to be a Software as a Services company? Their motto and sales point is “No Software”, which conveys to their actual customers “You know those programmers you have working on your internal systems? If you used Salesforce, you could fire half of them and pocket part of the difference in your bonus.” (There’s nothing wrong with this, by the way. You’re in the business of unemploying people. If you think that is unfair, go back to school and study something that doesn’t matter.) Instead, describe yourself by what you have accomplished for previously employers vis-a-vis increasing revenues or reducing costs. If you have not had the opportunity to do this yet, describe things which suggest you have the ability to increase revenue or reduce costs, or ideas to do so. There are many varieties of well-paid professionals who sling code but do not describe themselves as slinging code for a living. Quants on Wall Street are the first and best-known example: they use computers and math as a lever to make high-consequence decisions better and faster than an unaided human could, and the punchline to those decisions is “our firm make billions of dollars.” Successful quants make more in bonuses in a good year than many equivalently talented engineers will earn in a decade or lifetime. Similarly, even though you might think Google sounds like a programmer-friendly company, there are programmers and then there’s the people who are closely tied to 1% improvements in AdWords click-through rates. (Hint: provably worth billions of dollars.) I recently stumbled across a web-page from the guy whose professional bio is “wrote the backend billing code that 97% of Google’s revenue passes through.” He’s now an angel investor (a polite synonym for “rich”). **You are not defined by your chosen software stack**: I recently asked via Twitter what young engineers wanted to know about careers. Many asked how to know what programming language or stack to study. It doesn’t matter. There you go. Do Java programmers make more money than .NET programmers? Anyone describing themselves as either a Java programmer or .NET programmer has already lost, because a) they’re a programmer (you’re not, see above) and b) they’re making themselves non-hireable for most programming jobs. In the real world, picking up a new language takes a few weeks of effort and after 6 to 12 months nobody will ever notice you haven’t been doing that one for your entire career. I did back-end Big Freaking Java Web Application development as recently as March 2010. Trust me, nobody cares about that. If a Python shop was looking for somebody technical to make them a pile of money, the fact that I’ve never written a line of Python would not get held against me. Talented engineers are rare — vastly rarer than opportunities to use them — and it is a seller’s market for talent right now in almost every facet of the field. Everybody at Matasano uses Ruby. If you don’t, but are a good engineer, they’ll hire you anyway. (A good engineer has a track record of — repeat after me — increasing revenue or decreasing costs.) Much of Fog Creek uses the Microsoft Stack. I can’t even spell ASP.NET and they’d still hire me. There are companies with broken HR policies where lack of a buzzword means you won’t be selected. You don’t want to work for them, but if you really do, you can add the relevant buzzword to your resume for the costs of a few nights and weekends, or by controlling technology choices at your current job in such a manner that in advances your career interests. Want to get trained on Ruby at a .NET shop? Implement a one-off project in Ruby. Bam, you are now a professional Ruby programmer — you coded Ruby and you took money for it. (You laugh? I did this at a Java shop. The one-off Ruby project made the company $30,000. My boss was, predictably, quite happy and never even asked what produced the deliverable.) **Co-workers and bosses are not usually your friends**: You will spend a lot of time with co-workers. You may eventually become close friends with some of them, but in general, you will move on in three years and aside from maintaining cordial relations you will not go out of your way to invite them over to dinner. They will treat you in exactly the same way. You should be a good person to everyone you meet — it is the moral thing to do, and as a sidenote will really help your networking — but do not be under the delusion that everyone is your friend. For example, at a job interview, even if you are talking to an affable 28 year old who feels like a slightly older version of you he is in a transaction. You are not his friend, you are an input for an industrial process which he is trying to buy for the company at the lowest price. That banter about World of Warcraft is just establishing a professional rapport, but he will (perfectly ethically) attempt to do things that none of your actual friends would ever do, like try to talk you down several thousand dollars in salary or guilt-trip you into spending more time with the company when you could be spending time with your actual friends. You will have other coworkers who — affably and ethically — will suggest things which go against your interests, from “I should get credit for that project you just did” (probably not phrased in so many words) to “We should do this thing which advances my professional growth goals rather than yours.” Don’t be surprised when this happens. **You radically overestimate the average skill of the competition because of the crowd you hang around with**: Many people already successfully employed as senior engineers cannot actually implement FizzBuzz. Just read it and weep. Key takeaway: you probably are good enough to work at that company you think you’re not good enough for. They hire better mortals, but they still hire mortals. “Read ad. Send in resume. Go to job interview. Receive offer.” is the exception, not the typical case, for getting employment: Most jobs are never available publicly, just like most worthwhile candidates are not available publicly (see here). Information about the position travels at approximately the speed of beer, sometimes lubricated by email. The decisionmaker at a company knows he needs someone. He tells his friends and business contacts. One of them knows someone — family, a roommate from college, someone they met at a conference, an ex-colleague, whatever. Introductions are made, a meeting happens, and they achieve agreement in principle on the job offer. Then the resume/HR department/formal offer dance comes about. This is disproportionately true of jobs you actually want to get. “First employee at a successful startup” has a certain cachet for a lot of geeks, and virtually none of those got placed by sending in a cover letter to an HR department, in part because two-man startups don’t have enough scar tissue to form HR departments yet. (P.S. You probably don’t want to be first employee for a startup. Be the last co-founder instead.) Want to get a job at Google? They have a formal process for giving you a leg up because a Googler likes you. (They also have multiple informal ways for a Googler who likes you an awful lot to short-circuit that process. One example: buy the company you work for. When you have a couple of billion lying around you have many interesting options for solving problems.) There are many reasons why most hiring happens privately. One is that publicly visible job offers get spammed by hundreds of resumes (particularly in this economy) from people who are stunningly inappropriate for the position. The other is that other companies are so bad at hiring that, if you don’t have close personal knowledge about the candidate, you might accidentally hire a non-FizzBuzzer. Networking: it isn’t just for TCP packets: Networking just means a) meeting people who at some point can do things for you (or vice versa) and b) making a favorable impression on them. There are many places to meet people. Events in your industry, such as conferences or academic symposia which get seen by non-academics, are one. User groups are another. Keep in mind that user groups draw a very different crowd than industry conferences and optimize accordingly. Strive to help people. It is the right thing to do, and people are keenly aware of who have in the past given them or theirs favors. If you ever can’t help someone but know someone who can, pass them to the appropriate person with a recommendation. If you do this right, two people will be happy with you and favorably disposed to helping you out in the future. You can meet people over the Internet (oh God, can you), but something in our monkey brains makes in-the-flesh meeting a bigger thing. I’ve Internet-met a great many people who I’ve then gone on to meet in real life. The physical handshake is a major step up in the relationship, even when Internet-meeting lead to very consequential things like “Made them a lot of money through good advice.” Definitely blog and participate on your industry-appropriate watering holes like HN, but make it out to the meetups for it. Academia is not like the real world: Your GPA largely doesn’t matter (modulo one high profile exception: a multinational advertising firm). To the extent that it does matter, it only determines whether your resume gets selected for job interviews. If you’re reading the rest of this, you know that your resume isn’t the primary way to get job interviews, so don’t spend huge amount of efforts optimizing something that you either have sufficiently optimized already (since you’ll get the same amount of interviews at 3.96 as you will at 3.8) or that you don’t need at all (since you’ll get job interviews because you’re competent at asking the right people to have coffee with you). Your major and minor don’t matter. Most decisionmakers in industry couldn’t tell the difference between a major in Computer Science and a major in Mathematics if they tried. I was once reduced to tears because a minor academic snafu threatened my ability to get a Bachelor of Science with a major in Computer Science, which my advisor told me was more prestigious than a Bachelor of Science in Computer Science. Academia cares about distinctions like that. The real world does not. Your professors might understand how the academic job market works (short story: it is ridiculously inefficient in engineering and fubared beyond mortal comprehension in English) but they often have quixotic understandings of how the real world works. For example, they may push you to get extra degrees because a) it sounds like a good idea to them and b) they enjoy having research-producing peons who work for ramen. Remember, market wages for people capable of producing research are $80~100k+ in your field. That buys an awful lot of ramen. The prof in charge of my research project offered me a spot in his lab, a tuition waiver, and a whole $12,000 dollars as a stipend if I would commit 4~6 years to him. That’s a great deal if, and only if, you have recently immigrated from a low-wage country and need someone to intervene with the government to get you a visa. If you really like the atmosphere at universities, that is cool. Put a backpack on and you can walk into any building at any university in the United States any time you want. Backpacks are a lot cheaper than working in academia. You can lead the life of the mind in industry, too — and enjoy less politics and better pay. You can even get published in journals, if that floats your boat. (After you’ve escaped the mind-warping miasma of academia, you might rightfully question whether Published In A Journal is really personally or societally significant as opposed to close approximations like Wrote A Blog Post And Showed It To Smart People.) How much money do engineers make? Wrong question. The right question is “What kind of offers do engineers routinely work for?”, because salary is one of many levers that people can use to motivate you. The answer to this is, less than helpfully, “Offers are all over the map.” In general, big companies pay more (money, benefits, etc) than startups. Engineers with high perceived value make more than those with low perceived value. Senior engineers make more than junior engineers. People working in high-cost areas make more than people in low-cost areas. People who are skilled in negotiation make more than those who are not. We have strong cultural training to not ask about salary, ever. This is not universal. In many cultures, professional contexts are a perfectly appropriate time to discuss money. (If you were a middle class Japanese man, you could reasonably be expected to reveal your exact salary to a 2nd date, anyone from your soccer club, or the guy who makes your sushi. If you owned a company, you’d probably be cagey about your net worth but you’d talk about employee salaries the way programmers talk about compilers — quite frequently, without being embarrassed.) If I were a Marxist academic or a conspiracy theorist, I might think that this bit of middle class American culture was specifically engineered to be in the interests of employers and against the interests of employees. Prior to a discussion of salary at any particular target employer, you should speak to someone who works there in a similar situation and ask about the salary range for the position. It is <%= Date.today.year %>; you can find these people online. (LinkedIn, Facebook, Twitter, and your (non-graph-database) social networks are all good to lean on.) Anyhow. Engineers are routinely offered a suite of benefits. It is worth worrying, in the United States, about health insurance (traditionally, you get it and your employer foots most or all of the costs) and your retirement program, which is some variant of “we will match contributions to your 401k up to X% of salary.” The value of that is easy to calculate: X% of salary. (It is free money, so always max out your IRA up to the employer match. Put it in index funds and forget about it for 40 years.) There are other benefits like “free soda”, “catered lunches”, “free programming books”, etc. These are social signals more than anything else. When I say that I’m going to buy you soda, that says a specific thing about how I run my workplace, who I expect to work for me, and how I expect to treat them. (It says “I like to move the behavior of unsophisticated young engineers by making this job seem fun by buying 20 cent cans of soda, saving myself tens of thousands in compensation while simultaneously encouraging them to ruin their health.” And I like soda.) Read social signals and react appropriately — someone who signals that, e.g., employee education is worth paying money for might very well be a great company to work for — but don’t give up huge amounts of compensation in return for perks that you could trivially buy. How do I become better at negotiation? * a) Remember you’re selling the solution to a business need (raise revenue or decrease costs) rather than programming skill or your beautiful face. * b) Negotiate aggressively with appropriate confidence, like the ethical professional you are. It is what your counterparty is probably doing. You’re aiming for a mutual beneficial offer, not for saying Yes every time they say something. * c) “What is your previous salary?” is employer-speak for “Please give me reasons to pay you less money.” Answer appropriately. * d) Always have a counteroffer. Be comfortable counteroffering around axes you care about other than money. If they can’t go higher on salary then talk about vacation instead. * e) The only time to ever discuss salary is after you have reached agreement in principle that they will hire you if you can strike a mutually beneficial deal. This is late in the process after they have invested a lot of time and money in you, specifically, not at the interview. Remember that there are large costs associated with them saying “No, we can’t make that work” and, appropriately, they will probably not scuttle the deal over comparatively small issues which matter quite a bit to you, like e.g. taking their offer and countering for that plus a few thousand bucks then sticking to it. * f) Read a book. Many have been written about negotiation. I like Getting To Yes. It is a little disconcerting that negotiation skills are worth thousands of dollars per year for your entire career but engineers think that directed effort to study them is crazy when that could be applied to trivialities about a technology that briefly caught their fancy. How to value an equity grant: Roll d100. (Not the right kind of geek? Sorry. rand(100) then.) 0~70: Your equity grant is worth nothing. 71~94: Your equity grant is worth a lump sum of money which makes you about as much money as you gave up working for the startup, instead of working for a megacorp at a higher salary with better benefits. 95~99: Your equity grant is a lifechanging amount of money. You won’t feel rich — you’re not the richest person you know, because many of the people you spent the last several years with are now richer than you by definition — but your family will never again give you grief for not having gone into $FAVORED_FIELD like a proper $YOUR_INGROUP. 100: You worked at the next Google, and are rich beyond the dreams of avarice. Congratulations. Perceptive readers will note that 100 does not actually show up on a d100 or rand(100). Why are you so negative about equity grants? Because you radically overestimate the likelihood that your startup will succeed and radically overestimate the portion of the pie that will be allocated to you if the startup succeeds. Read about dilution and liquidation preferences on Hacker News or Venture Hacks, then remember that there are people who know more about negotiating deals than you know about programming and imagine what you could do to a program if there were several hundred million on the line. Are startups great for your career as a fresh graduate? The high-percentage outcome is you work really hard for the next couple of years, fail ingloriously, and then be jobless and looking to get into another startup. If you really wanted to get into a startup two years out of school, you could also just go work at a megacorp for the next two years, earn a bit of money, then take your warchest, domain knowledge, and contacts and found one. Working at a startup, you tend to meet people doing startups. Most of them will not be able to hire you in two years. Working at a large corporation, you tend to meet other people in large corporations in your area. Many of them either will be able to hire you or will have the ear of someone able to hire you in two years. So would you recommend working at a startup? Working in a startup is a career path but, more than that, it is a lifestyle choice. This is similar to working in investment banking or academia. Those are three very different lifestyles. Many people will attempt to sell you those lifestyles as being in your interests, for their own reasons. If you genuinely would enjoy that lifestyle, go nuts. If you only enjoy certain bits of it, remember that many things are available a la carte if you really want them. For example, if you want to work on cutting-edge technology but also want to see your kids at 5:30 PM, you can work on cutting-edge technology at many, many, many megacorps. (Yeah, really. If it creates value for them, heck yes, they’ll invest in it. They’ll also invest in a lot of CRUD apps, but then again, so do startups — they just market making CRUD apps better than most megacorps do. The first hour of the Social Network is about making a CRUD app seem like sexy, the second is a Lifetime drama about a divorce improbably involving two heterosexual men.) **Your most important professional skill is communication**: Remember engineers are not hired to create programs and how they are hired to create business value? The dominant quality which gets you jobs is the ability to give people the perception that you will create value. This is not necessarily coextensive with ability to create value. Some of the best programmers I know are pathologically incapable of carrying on a conversation. People disproportionately a) wouldn’t want to work with them or b) will underestimate their value-creation ability because they gain insight into that ability through conversation and the person just doesn’t implement that protocol. Conversely, people routinely assume that I am among the best programmers they know entirely because a) there exists observable evidence that I can program and b) I write and speak really, really well. (Once upon a time I would have described myself as “Slightly below average” in programming skill. I have since learned that I had a radically skewed impression of the skill distribution, that programming skill is not what people actually optimize for, and that modesty is against my interests. These days if you ask me how good of a programmer I am I will start telling you stories about how I have programmed systems which helped millions of kids learn to read or which provably made companies millions. The question of where I am on the bell curve matters to no one, so why bother worrying about it?) Communication is a skill. Practice it: you will get better. One key sub-skill is being able to quickly, concisely, and confidently explain how you create value to someone who is not an expert in your field and who does not have a priori reasons to love you. If when you attempt to do this technical buzzwords keep coming up (“Reduced 99th percentile query times by 200 ms by optimizing indexes on…”), take them out and try again. You should be able to explain what you do to a bright 8 year old, the CFO of your company, or a programmer in a different specialty, at whatever the appropriate level of abstraction is. You will often be called to do Enterprise Sales and other stuff you got into engineering to avoid: Enterprise Sales is going into a corporation and trying to convince them to spend six or seven figures on buying a system which will either improve their revenue or reduce costs. Every job interview you will ever have is Enterprise Sales. Politics, relationships, and communication skills matter a heck of a lot, technical reality not quite so much. When you have meetings with coworkers and are attempting to convince them to implement your suggestions, you will also be doing Enterprise Sales. If getting stuff done is your job description, then convincing people to get stuff done is a core job skill for you. Spend appropriate effort on getting good at it. This means being able to communicate effectively in memos, emails, conversations, meetings, and PowerPoint (when appropriate). It means understanding how to make a business case for a technological initiative. It means knowing that sometimes you will make technological sacrifices in pursuit of business objectives and that this is the right call. Modesty is not a career-enhancing character trait: Many engineers have self-confidence issues (hello, self). Many also come from upbringings where modesty with regards to one’s accomplishments is culturally celebrated. American businesses largely do not value modesty about one’s accomplishments. **The right tone to aim for in interviews, interactions with other people, and life is closer to “restrained, confident professionalism.”** If you are part of a team effort and the team effort succeeds, the right note to hit is not “I owe it all to my team” unless your position is such that everyone will understand you are lying to be modest. Try for “It was a privilege to assist my team by leading their efforts with regards to $YOUR_SPECIALTY.” Say it in a mirror a thousand times until you can say it with a straight face. You might feel like you’re overstating your accomplishments. Screw that. Someone who claims to Lead Efforts To Optimize Production while having the title Sandwich Artist is overstating their accomplishments. You are an engineer. You work magic which makes people’s lives better. If you were in charge of the database specifically on an important project involving people then heck yes you lead the database effort which was crucial for the success of the project. This is how the game is played. If you feel poorly about it, you’re like a batter who feels poorly about stealing bases in baseball: you’re not morally superior, you’re just playing poorly All business decisions are ultimately made by one or a handful of multi-cellular organisms closely related to chimpanzees, not by rules or by algorithms: People are people. Social grooming is a really important skill. People will often back suggestions by friends because they are friends, even when other suggestions might actually be better. People will often be favoritably disposed to people they have broken bread with. (There is a business book called Never Eat Alone. It might be worth reading, but that title is whatever the antonym of deceptive advertising is.) People routinely favor people who they think are like them over people they think are not like them. (This can be good, neutral, or invidious. Accepting that it happens is the first step to profitably exploiting it.) Actual grooming is at least moderately important, too, because people are hilariously easy to hack by expedients such as dressing appropriately for the situation, maintaining a professional appearance, speaking in a confident tone of voice, etc. Your business suit will probably cost about as much as a computer monitor. You only need it once in a blue moon, but when you need it you’ll be really, really, really glad that you have it. Take my word for it, if I wear everyday casual when I visit e.g. City Hall I get treated like a hapless awkward twenty-something, if I wear the suit I get treated like the CEO of a multinational company. I’m actually the awkward twenty-something CEO of a multinational company, but I get to pick which side to emphasize when I want favorable treatment from a bureaucrat. At the end of the day, your life happiness will not be dominated by your career. Either talk to older people or trust the social scientists who have: family, faith, hobbies, etc etc generally swamp career achievements and money in terms of things which actually produce happiness. Optimize appropriately. Your career is important, and right now it might seem like the most important thing in your life, but odds are that is not what you’ll believe forever. Work to live, don’t live to work. ## Salary negotiation Rich, successful people negotiate. Get into the habit of seeing employees like employers see them: in terms of fully-loaded costs. To hire someone you need to pay for their salary, true, but you also have taxes, a benefits package, employer contributions to retirement, healthcare, that free soda your HR department loves mentioning in the job ads, and what have you. The fully-loaded costs of employees are much higher than their salary: exactly how much higher depends on your locality’s laws, your benefits package, and a bunch of other HR administrivia, but a reasonable guesstimate is between 150% and 200% of their salary. Companies are not sensitive to small differences in employee wages because employees are so darned expensive anyhow. You see $5,000 and think “Holy cow, even after taxes that’s a whole new vacation. Five thousand dollars. Five thousand dollars. It would be so very, very greedy of me to ask for five thousand whole dollars.” The HR department sees $5,000 and thinks “Meh, even after we kick in the extra taxes, that is only about 3% of their fully-loaded cost for this year anyhow, or seven hundredths of one percent of that team’s hiring budget. I wonder if the cafeteria has carrot cake today?” Keep in mind that in startup world making a new hire is a big commitment, but they still have a lot of flexibility on the details because the details do not shave months off of their runway, think equity. Internalize this: everyone in this discussion is a businessman. Bob, the HR person is just spending a part of hiring budget, he doesn't really care about you or the company. If the deal makes economic sense, it will happen. If it doesn’t, firm handshakes will be exchanged, non-specific promises will be uttered, and everyone will forget about this discussion in a matter of hours. You will not be blackballed for negotiating. Bob couldn’t care less and, even if he did care, he has better things to do with his time than worry about a candidate he didn’t hire. Bob is working through a list of a dozen people right now, and his manager Dave is being such a hard case about that project’s schedule, and he’s not sure he can make his daughter’s piano recital, and the cafeteria’s carrot cake was a little dry. **Bob is far, far less invested in this negotiation than you are.** Many people think job searches go something like this: . See ad for job on Monster.com . Send in a resume. . Get an interview. . Get asked for salary requirements. . Get offered your salary requirement plus 5%. . Try to negotiate that offer, if you can bring yourself to. This is an effective strategy for job searching if you enjoy alternating bouts of being unemployed, being poorly compensated, and then treated like a disposable peon. (I served three years as a disposable peon in a Japanese megacorp and might be projecting a tad bit here. Regardless, my loss is your gain.) You will have much, much better results if your job search looks something more like: . (Optional but recommended) Establish a reputation in your field as someone who delivers measurable results vis-a-vis improving revenue or reducing costs. . Have a hiring manager talk with you, specifically, about an opening that they want you, specifically, to fill. . alk informally (and then possibly formally) and come to the conclusion that this would be a great thing if both sides could come to a mutually fulfilling offer. . Let them take a stab at what that mutually fulfilling offer would look like. . Suggest ways that they could improve it such that the path is cleared for you doing that voodoo that you do so well to improve their revenue and/or reduce their costs. . (Optional) Give the guy hiring you a resume to send to HR, for their records. Nobody will read it, because resumes are an institution created to mean that no one has to read resumes. Since no one will read it, we put it in the process where it literally doesn’t matter whether it happens or not, because if you had your job offer contingent on a document that everyone knows no one reads, that would be pretty effing stupid now wouldn’t it. Only negotiate salary after you have agreement in principle from someone with hiring authority that, if a mutually acceptable compensation can be agreed upon, you will be hired. The second implication is that the inner serf worrying “If I even attempt to negotiate this, the deal will fall through” is worrying for nothing. They’ve got thousands invested in this discussion by this point. They want you. The absolute worst outcome of negotiating an offer in good faith is that you will get exactly the contents of that offer. Let me say that again for emphasis: **negotiating never makes (worthwhile) offers worse.** In this wide world I’m sure you can find a company who still makes exploding offers, where you get one yay-or-nay and then the offer is gone. You have a simple recourse to them: refuse them and deal with people who are willing to be professionals. You’re not a peasant. Don’t act like one. This also means you do not start negotiating until you already have a Yes-If. (Yes-If we agree on terms.) Do not start negotiating from No-But. (No-But we might hire you anyway if you’re really, really effing cheap.) The ideal resolution to the job interview is for both sides to be optimistic about the arrangement, and then you close with a warm handshake and “I look forward to receiving your offer by, oh, would tomorrow be enough time for you to run the numbers?” You then have a high likelihood of doing your salary negotiation over email, which is likely to your advantage versus doing it in real time. Email gives you arbitrary time to prepare your responses. Especially for engineers, you are likely less disadvantaged by email than you are by having an experienced negotiator talking to you. **The First Rule Is What Everyone Tells You It Is: Never Give A Number First** .Case 1 Bob: “I really need a number to move the process forward.” What you should think: “You’re lying to me to attempt to get me to compromise my negotiating position.” What you should say: “I’m more concerned at the moment with talking to you about discovering whether we’re a mutual fit. If we’re a great fit, then I can be flexible on the numbers with you and you can be flexible on the numbers with me. If we’re not a great fit, then the numbers are ultimately irrelevant, because your company only hires A players and I only work at roles I would be an A player at.” .Case 2 Bob: “This form needs a number.” What you should think: “You’re lying to me to attempt to get me to compromise my negotiating position.” What you should say: “Give me git access and I’ll fix it in a jiffy! both people laugh No, seriously, speaking, I’m more concerned at the moment with discovering whether we’re a mutual fit… Oh, it’s physically impossible? Put in $1 then to get the ball rolling, and we’ll circle back to this later.” .Case 3 Bob: “We want to figure out whether you’re an appropriate candidate for the position.” What you should think: “You’re lying to me to attempt to get me to compromise my negotiating position.” What you should say: “It’s so important to me that this is a good mutual fit for us. Let’s talk about why I’m a great fit for this position: I know you’re concerned about $FILL_IN_THE_BLANK. In addition to my previous successes doing it, I have some great ideas for what I’d do about that if I was working at your company. Would you like to drill into those or is there another job area you’re more concerned about to start with?” .Case 4 Bob: “I’m sorry, great try at a dodge there, but I just can’t go forward without a number.” What you should think: “You’re lying to me to attempt to get me to compromise my negotiating position.” What you should say (if you’re an engineer): “Well, you know, I would hate to have to walk away from the negotiation over this. Working with your company looked it would have been such a wonderful opportunity. I hear the hiring market is super-tight right now, would you like me to introduce you to other candidates? Maybe we can shave a couple of months off of you filling this position.” What you should say (if you’re not an engineer): “Damn, I guess I should have studied engineering.” What you should say (if you’re a little put out by that comment): “Well, you know, salary is only one component of the total compensation package. In terms of total compensation, we’re probably looking at something like $FILL_IN_NUMBER_HERE.” (Suggested calculation: take the package value from your last company and add 5~10%. If you don’t know how to calculate the value of your compensation package, learn that, but as a rough guesstimate salary + 30 ~ 50% for full-time employees in professional roles and the multiplier tends to scale up as your base salary scales up.) **Listen To What People Tell You. Repeat It Back To Them.** You know what people find persuasive? Their own words. People love their own words. When you talk to them, you should use their own words. Seriously, watch the eyes light up. Did the solicitation for the job say “We are seeking someone with strong skills at scaling traffic in a fast-moving environment”? Pick out the key words. Scaling traffic. Fast-moving environment. “Scaling traffic” doesn’t sound like how I’d phrase it if I were writing or speaking for myself, but if you’ve just described your need to me as scaling traffic, by golly I will tell you how great I am at scaling traffic. Reinterpret or rephrase the (true!) bits of your own story such that it fits the narrative framework which they have conveniently told you that they are going to respond to. Did you previously work at a small business which was unencumbered by lots of process? Sounds like a fast-moving environment, right? Call it exactly that, then. Take notes during job interviews and salary negotiations. It’s easy: go to the convenience store before the job interview, buy a writing instrument and a $1 notebook, jot down occasional notes when appropriate. Do you know anyone who you’ve ever thought “Man, I thought they were competent, but then it turned out they had a notebook so I had to write them off?” No. Taking notes says “I’m attentive and detail-oriented and I care about what you say.” (Make sure you can take notes without playing with your pen or otherwise appearing to fidget.) In terms of specific things that should get your pen moving, among others, I would focus on specific words they use and concerns they have so that you can come back to them later in the conversation. Numbers are another good thing to hit the notebook, because numbers should only ever trend in a direction of “Better to you,” so you don’t want to do something stupid like saying “So how many days of vacation was that again?” and let a 24 suddenly become a 20. Don’t say stupid things during job interviews such as “I need this job because…” You never need a job. Being needy means that the party who is not needy has automatic leverage over you. Instead of being needy, aim for “I’m enthusiastic about the opportunity with working with you, assuming we can come to mutually satisfactory terms.” Micro-tip: Notice how often I say “We” and variations on “mutual win.” Those work pretty well. The only thing better than “We” is “You” (and variants), because people care a heck of a lot more about their problems than about your problems. This means that a) you should talk about their problems, concerns, and wishes and b) you should guard against your own natural tendency to bring up irrelevant things like your own problems, which typically will not help you sell the decisionmaker on adopting the mutual win you’re proposing. Similarly, I generally try to phrase things positively rather than score debating points. (“You just said X, but that was contradicted by your earlier statement Y, which means…” wins debating points but does not win friends and influence people. You might try something like “Good good, but taking into account your earlier concerns about Y…”) You should, before any job interview, have intimate knowledge of the target company. Prospective peers within the company are one obvious way to get it. So are ex-employees, folks who’ve had dealings with them professionally, etc. Key things you want to learn: * What do they value? * Who do they value within the company? (Roles? Titles? Groups?) * What does the career path look like for successful people within the company? * Roughly speaking, how generous are they with regard to axes that you care about? * Do they have any compensation levers which are anomalously easy to operate? (For example, if you asked around, you might hear a few people say that a particular firm pushes back modestly on out-of-band increases in salary but they’ll give in-the-money option grants like candy.) * All the fuzzy stuff: what’s the corporate culture like? Yadda yadda. You can even bring a lot of these questions to the job interview, which is (again) prior to the negotiation. (Maybe not “So are you guys tightwads?” but culture-esque questions like “What are the projects this company thinks are really key to its future and how would a motivated person go about getting on them?” are both a) totally fair game and b) will win you brownie points just for asking. Similarly, a lot of employees will, out of company loyalty, attempt to sell you on taking the job with the company by trading you very useful information.) .Case 5 **Company:** We can’t see our way to $88,000. **Applicant:** Well, I know you do a significant amount of business with your online store. At my last company, I increased sales by 3% by $YADDA_YADDA. What would a 1% increase in sales be worth to you? **Company:** Well, I don’t have that figure in front of me, but… **Applicant:** Would it be safe to say “millions of dollars”? **Company:** That sounds about right, yeah. **Applicant:** Great, I can’t wait to get started. Getting me that extra $4,000 would make this a much easier decision. Considering that this is conceivably worth millions to you, we’d be silly not to do business with each other. .Case 6 **Employer:** “We were thinking $80,000.” **Applicant:** “$80,000 is interesting (*) but not quite where we need to be to get this done. Do you have any flexibility on that number?” **Employer:** “I think I can convince HR to approve $84,000 but that is the best I can do.” **Applicant:** “I appreciate that. $84,000, huh. Well, it isn’t quite what I had in mind, but the right package offer could make that attractive. How much vacation comes with the package?” **Employer:** “20 days a year.” **Applicant:** “If you could do 24 days a year, I could compromise on $84,000.” **Employer:** “I think I can do that.” “Interesting” is a wonderful word: it is positive and non-commital at the same time. If they tell you a number, tell them it is an “interesting” number, not a “wonderful” number. Hoping around the offer also helps you defuse common negotiating tactics like “I have to go to $EXTERNAL_AUTHORITY to get approval of that.” (This is in the negotiation playbook, because it works well: it injects an automatic delay in the process, and gives you a scapegoat for refusing a request while not being guilty of the refusal yourself. You should strongly consider having an $EXTERNAL_AUTHORITY of your own. Significant others work well. Note that in the US your would-be employer is legally prohibited from breathing about the subject of your marital status, so something like “We’ll have to talk that over” or “That sounds reasonable, but I’ll have to run it by the family” has the dual virtues of being a socially acceptable reason to delay any major decision. ## Consulting and freelance - https://training.kalzumeus.com/newsletters/archive/consulting_1 - https://training.kalzumeus.com/newsletters/archive/services_vs_products - https://training.kalzumeus.com/newsletters/archive/dissecting_sales_copy - https://draft.nu/revise/ - https://www.gkogan.co/blog/how-i-learned-to-get-consulting-leads/ - https://www.kalzumeus.com/2012/09/17/ramit-sethi-and-patrick-mckenzie-on-getting-your-first-consulting-client/ - https://www.kalzumeus.com/2012/09/21/ramit-sethi-and-patrick-mckenzie-on-why-your-customers-would-be-happier-if-you-charged-more/ - https://news.ycombinator.com/item?id=21191906 - https://news.ycombinator.com/item?id=21189801 - https://news.ycombinator.com/item?id=21473265 - https://news.ycombinator.com/item?id=21954581 - https://news.ycombinator.com/item?id=21728436 - https://bek.is/ - https://www.julian.com/ - https://rafaltomal.com/ - https://thalida.me - https://www.designolog.com/ - https://moeamaya.com/ - https://kalzumeus.com/ - https://news.ycombinator.com/item?id=21728436 ## Working from home/remotely I have been working remotely for a while now. Over those years I wasted a lot of time "working" without real focus, with constant interruptions and breaks. Over time I managed to tenfold my productivity and work effectiveness. Following is my advice: 1. Have an office 2. Keep regular schedule 3. Track your work Remote work while traveling is tricky and I would not recommend spending longer periods of time without the above three items. **1. Have an office** In the beginning my office used to be my bedroom. My general advice is **don't work where you rest or do anything unrelated to work**. If you don't have any place in your house/apt to spare for a makeshift office consider going to library, quiet caffee, coworking space etc. My office is separate room that I visit just when I am at work and which I can access only by leaving the house. My family is not allowed to come in unless its urgent or they want to work there in peace. In the office I have a custom built wide desk with two monitors on one side and blank desk for design work and writing on the other side. On my right there is a window and behind my back are glass doors which let in natural light. A good chair is a must for every office. **2. Keep regular schedule** I am in the office at 9:00 without exception. If I go to sleep early I ll get up at 7:00, go for a run, workout, take a shower and have a good breakfast before I start working. If I stayed up late I might get up at 8:50 but I'll still make sure I'm dressed up and in the office by 9:00. I'll usually work until 13:00 when I'll go and make/eat lunch in the kitchen with my SO. I'm back in the office by 14:00 and I'll work until 18:00 when I leave my office for the day. When and how I work is important, however my primary goal for such strict schedule is to leave work at work and not "bring it home" with me. It's all too easy to slip into everyday - all day "working" where you have short productivity bursts between rounds of procrastinating and spending all your day on the computer. **3. Track your work** Tracking your work is important. If you work for someone else you have a work log to show them, if you're your own boss you have a log to analyze and find where the time went, if you're working on multiple projects you have time log to check and see if you're giving appropriate amount of time to each project, etc. Tracking time and analyzing results forces you to be conscious of work and not-work activities. When you're in the office you can do two types of activities - work activities that bring you closer to your work goals and all the other activities. Checking your personal email, chatting with your friend, switching songs etc. can eat a huge chunk of your work time. By tracking time you can make sure you're spending your time in the office for work only. If you cant make yourself work for 4 hours straight, break your work hours into smaller chunks. The goal is to either work or not work. Mixing work, fun, family or other activities will end up bad for everyone involved. ## Networking ### Attending talks and conferences - Meeting people is more important than the talks. - Use shirt color to meet a diverse set of people. - Don't eat alone, eat with strangers not friends. - Freely hand out your business card. - Remember people you've met and follow up. - Twitter is great for followup. - The Goal of a Conference is to Meet People If you haven't met anyone (and followed up with them), you're doing conferences wrong. Remember people's names. Make the effort to remember them, and soon after the conversation, write it down somewhere. Add them to your social db. **Shirt Color Trick** Avoid people bias and talk to random people. A cool technique is shirt color trick. Pick a color besides black, grey, or blue and find the closest person wearing a shirt of that color. Go up and talk to them, no matter who they are. So if you pick green, find the closest person in a green shirt. If there's nobody wearing a green shirt, pick a new color. Picking an uncommon color limits your choice of people to talk to, which limits how much your bias can influence you. **Ditch Your Friends** Talk to strangers. It's comfortable to hang out with friends, but resist the temptation. When you show up for a lunch or dinner, find a table with people you know and sit at another table. If you are with your friends, try to include strangers who are standing/sitting nearby. **Don't Eat Alone** Each at the conference's lunches and talk to other people. Don't sit with your friends, but join tables with people you don't know. If you don't have Sponsor booths in the expo halls will have fliers for after-party events as well. **Ditch the Talks** You don't have to attend the talks. In fact, ditch them so you can meet people in the hallway. The talks will be posted online. If there is a speaker you want to meet, go to their talk, and sit front and center. (Attend talks that you like, but don't feel like you have to fill up your entire time with talks. And the keynotes are great to see in person rather than in a web browser.) **Business Cards** Get business cards printed, and bring a large amount of them with you. It's better to have extras left over than run out halfway through the conference. They're good parting gifts to exchange at the end of a conversation. If you are buying cards for yourself, order the minimum quantity of cards. Ordering a 1000 cards might be cheapest per card, but you'll want to change the design or the information on them far before you finish handing them out. Here's what I have on my card: - My name, using the first name that I want people to call me by (Tom, not Tomislav). - My email address. - My Twitter handle. (@frainfreeze) - My website. Not my phone number. Not my address. (You should feel comfortable if someone posted your business card online.) You can write this info on the card if they need it. When you receive someone else's card, on the back write the details of how you met them and what you talked about. Write “XCon {{date.year}}” on the card for when you find their card several months from now. **Twitter Account & Followup** Writing a direct email is time consuming and direct. But replying to a tweet they post is a great, low-commitment way to enter a conversation with them. # Book notes ## The Clean Coder ``` ISBN: 978-0137081073 Tags: Software Date read: Rating: ``` *Description:* Great software isn’t written by machines. It is written by professionals with an unshakable commitment to craftsmanship. The Clean Coder will help you become one of them-and earn the pride and fulfillment that they alone possess.
Notes & Quotes ⁽ᶜˡᶦᶜᵏ ᵗᵒ ᵉˣᵖᵃⁿᵈ⁾ **Chapter 1: Professionalism** * Do no harm to function or structure of the code: don’t introduce bugs, make sure you code is tested. If it can’t be tested, write it in a way that is testable. If testing is too cumbersome, automate the testing. * A true professional knows that delivering function at the expense of structure is a fool’s errand. * Every time you look at a module you should look for ways to make small, lightweight changes to make it better. AKA, leave code better than you found it even if you didn’t write it. * Your career is YOUR responsibility, not your employer’s. You owe your employer 40 hours a week, make sure you put in an extra some hours for yourself (reading, practicing, learning) to hone your skills and make sure you are developing in the areas you want to be developing in. * Know your field and know it well. Know design patterns and principles, methods, practices. * Practice. Practice. Practice. True professionals keep their skills sharp and ready. Musicians don’t get better by performing (doing your job), they get better by practicing (outside of work). That same rule applies to engineers. **Minimal list of the things that every software professional should be conversant with** * Design patterns. You ought to be able to describe all 24 patterns in the GOF book and have a working knowledge of many of the patterns in the POSA books. * Design principles. You should know the SOLID principles and have a good understanding of the component principles. * Methods. You should understand XP, Scrum, Lean, Kanban, Waterfall, Structured Analysis, and Structured Design. * Disciplines. You should practice TDD, Object-Oriented design, Structured Programming, Continuous Integration, and Pair Programming. * Artifacts: You should know how to use: UML, DFDs, Structure Charts, Petri Nets, State Transition Diagrams and Tables, flow charts, and decision tables. When starting a project in a new domain, read a book or two on the topic. Interview your customer and users about the foundation and basics of the domain. Spend some time with the experts, and try to understand their principles and values. It is the worst kind of unprofessional behavior to simply code from a spec without understanding why that spec makes sense to the business. Rather, you should know enough about the domain to be able to recognize and challenge specification errors. **Chapter 2: Saying NO** * True professionals have the courage to say no to their managers. Pursue and defend your objectives as aggressively as you can. If you know full well that getting the job done by X date is not doable, but you still say "`I’ll try`" then you are not doing your job right. * Your manager is counting on you to defend your objectives and not just agree with everything that she says. Be assertive. Both you and your manager need to get to the best possible outcome through negotiation. * Conversations might be adversarial and uncomfortable — but that’s all in the pursuit of a mutually agreeable solution and the best possible outcome (the ultimate goal). * When it comes not being able to meet the deadline, the WHY is less important than the FACT that you can’t meet it. * Make sure you have documentation (memos) for high stake deliverables/situations (CYA) **Chapter 3: Saying YES** * Three parts to making a commitment: Say you’ll do it, mean it, actually do it. * Recognize lack of commitment phrases and words in others and yourself. They include: "`need/should`", "`hope/wish`", "`Let’s meet sometime/Let’s finish this thing.`". * The secret ingredient to recognizing what a sincere commitment sounds like is to look for phrases that resemble "`I will do something… by this certain date…`" * If you rely on someone else to get your job done, do what you can to get what you need to move forward. Don’t let them be a blocker. * Bring up blockers or red flags as soon as they come up — communicate. If you don’t tell anyone about the potential problem as soon as possible, you’re not giving anyone a chance to help you follow through on your commitment. * Professionals are not required to say "`yes`" to everything that is asked of them. However, they should work hard to find creative ways to make the "`yes`" possible (e.g., reducing scope) **Chapter 4: Coding** * Coding "requires a level of concentration and focus that few other disciplines require." A clean coder codes only if s/he can guarantee enough focus. Distractions (personal, environmental, or whatever) are a problem. Over-time is a problem. * Flow ("the Zone") is not as good as people think: You will be locally productive, but will often lose sight of the bigger picture and possibly produce not-so-good designs. * Music may be a distraction (even if you don't think so). * Interruptions are bad distractions. Pair programming is helpful to cope with them. TDD helps to make the pre-interruption context reproducible. * If you have writer's block, start pair programming. * Make sure you take in enough creative input, e.g. reading fiction books. * You have to find ways to minimize the time spent debugging - TDD. * Coding is a marathon, not a sprint, so conserve your energy and creativity. Go home when it's time, even in the middle of some-thing important. Showers and cars are prob-lem-solving resources, too! * Continuously re-estimate your best/likely/worst completion time and speak up as soon as you recognize you will likely be late. Do not allow anyone to rush you (see above). Consider overtime only for a short stretch (2 weeks max.) and only if there is a fallback plan as well. Use a proper definition of "done", with sufficiently high quality requirements. **Chapter 5: Test-driven Development** ...
## The Passionate Programmer ``` ISBN: 978-1934356340 Tags: Software, Self-help, Business Date read: 17.5.2019. Rating: 3/5 ``` *Description:* Success in today’s IT environment requires you to view your career as a business endeavor. In this book, you’ll learn how to become an entrepreneur, driving your career in the direction of your choosing. You’ll learn how to build your software development career step by step, following the same path that you would follow if you were building, marketing, and selling a product. After all, your skills themselves are a product.
Notes & Quotes ⁽ᶜˡᶦᶜᵏ ᵗᵒ ᵉˣᵖᵃⁿᵈ⁾ **Intro** - Chose your market: Pick the tech and business domains you focus on consistently and deliberately - Invest in your product(tools): expand your knowledge and skills - Execute: utilize your skills to *deliver* - Market: build a personal brand Make a list of early, middle, and late adoption technologies based on today’s market. Map them out on paper from left to right; the left is bleeding edge, and the right is filled by technologies that are in their sunsets. Push yourself to find as many technologies in each part of the spectrum as possible. Be as granular as possible about where in the curve they fall in relation to one another. When you have as many technologies mapped out as you can think of, mark the ones that you consider yourself strong in. Then, perhaps in a different color, mark the ones that you have some experience with but aren’t authoritative on. Where are most of your marks on the adoption curve? Do they clump? Are they spread evenly across? Are there any technologies around the far edges that you have some special interest in? Exploit market imbalances. Aquire trade magazines, websites etc for your company industry - watch out for big news. (industry != software but rather industry youre writting software for, ie. cattle) Make mindmaps - one draft and then one finished Talk to the duck. We build to learn, not learn to build. Find a "`be worst`" situation for yourself - meetups, workshops, open source projects etc. Generalists are rare and therefore precious. Do same thing in two different ways, for example small project in both list and python, or c# and java, or with and without stl. Keep log - for eg. not in the morning on 1-10 scale how you feel and plan how to make it 10 next morning. Find what you dont know and learn. Disect things. Be a mentor. Practice your limits - competitive programming, topcoder, kata’s etc PM methodologies: PMBoK, SixSigma Mine existing code for insights Code reviews every week - your company’s code, open source code segments If you treat your projects as a race you'll finish them fast (thin weekend hackaton). Parkinson's law. Turn multimonth project into a week task. The mindreading trick if done well leads to people depending on you. If you do what your customers ask for, they'll be happy. If you mae things before they even ask for them, you will delight them. however thread carefully, you can fuck up easily. Have an accomplishment to report every day. This becomes a habit, rather than a major production. Be ambitious but dont wear it on your sleeve. Implement self checking systems. ie make team compete between themself but as all vs 1, for every teammate. Constructive spiral. beware of being blinded by your own success. Keep system components standalone to be able to swap servers, users, team... as you wish. Eight hour burn: work so hard you cant continue after 8 hours. Budget yout work hours - work less to do more. Work intensivly, then take a lunch or nap or exercise, then work some more. Defensive planing and programming. (stability and security in the first plan, then rest) Saying "yes" is addictive and destructive habit. Note down your commitments list and examinate it daily. Never panic. No matter how bad it is try to keep clear head. When you start panicing think of that old computer illiterate lady. Analyse situation from third persons perspective, just as you were helping someone. Log your panics and progress on them. Write status reports daily, weekly, monthly, yearly. Take different groups and list them. Next to each, write down which of your attributes is most likely to drive that group’s perception of you. Here’s an example: image::res/groups.png[] Be understanding of people who dont know or understand yet. Dont make them fear you. You are what you can explain. Learn how to write and how to talk. (touch typing, logbook, diary) Face to face communication is important. Have an office, buisness is personal. Second best is calls, dont email what you can call. Businesses are interested in business results. Show what you did with focus on why it matters (for business). Write a textfile full of possible weblog topics. These are your future articles that you are going to write. Shoot for ideas that you can write about in 10-20min. In articles link to relevant stuff. Write daily for 3 weeks. Now cherry pick and tidy and publish best on usermoderated pages such as reddit or digg. Build your brand. Make google searches say good things about you. Dont be a jerk online or offline. Commit to open source. "Im contributor to python software" is so much better than listing python as a skill on CV. Think of someone local you adore, try to find a way to start conversation (their speech, meetup, ...), *especially* if it makes you uncomfortable. Your shiny new skills are already obsolete. Make room for at least two hours each week in order to research new technologies and to start to develop skills in them. Do hands-on work with these new technologies. Build simple applications. Prototype new-tech versions of the hard bits of your current-tech projects to understand what the differences are and what the new technologies enable. Put this time on your schedule. Don’t let yourself miss it. If you’re a programmer, try a day or two of doing your job as if you were a tester or a project manager. What are the many roles that you might play from day to day that you have never explicitly considered? Make a list, and try them on for size. Spend a day on each. You might not even change your actual work output, but you’ll see your work differently. Focus on doing, not on being done. In his book The Miracle of Mindfulness Thich Naht Hanh presents a suggestion: the next time you have to wash the dishes, don’t wash them to get them done. Try to enjoy the experience of washing the dishes. Don’t focus on finishing them. Focus on the act of washing them itself. Doing the dishes is a mundane task that almost nobody savors. Software developers have a lot of similar drudgery to get through in the average day, such as time tracking and expense reporting, for example. The next time you have to do a task like this, see whether you can find a way to focus on the task as you do it instead of anxiously rushing to finish it. A personal product road map not only can help you stay on track, constantly evolving, but it can also show you the bigger picture of what you have to offer. It can show you that no single feature stands alone. Each new investment is part of a larger whole. Some work fabulously well together. Others require too much of a mental leap for potential employers. Is he a system administrator or a graphic designer? Is she an application architect or a QA automation guru? Although it’s definitely OK to learn diverse skills — it expands your thinking — it’s also a good idea to think about the story your skillset tells. Without a road map, your story might look more like a Jack Kerouac novel than a cohesive set of logically related capabilities. Without a road map, you might even actually get lost. Adjust roadmap/cv/experiences you shard based on person you are conversing with. If you sit and watch a flower bloom, it will take a long time to notice that anything has happened. However, if you leave and come back in two days, you’ll see something very noticeably different from when you left. You might look at yourself in the metaphorical mirror each day and not see an ounce of change. Keep a journal and ask people around you for feedback. Make a list of the difficult or complex improvements you’d like to make; they can be personal or professional. It’s OK if you have a fairly long list. Now, for each item in the list, think about what you could do today to make yourself or that item better than yesterday. Tomorrow, look at the list again. Was yesterday better than the day before? How can you make today better? Do it again the next day. Put it on your calendar. Spend two minutes thinking about this each morning.
## Patterns of Software ``` ISBN: 978-0195102697 Tags: Autobiography, Software Date read: Rating: ``` *Description:* Collection of essays. Book can be divided into two parts: author's views on software engineering issues, and his biography. Not useful from software engineering point, out dated, but its quick read that provides few interesting thoughts and anecdotes.