Recent Updates Toggle Comment Threads | Keyboard Shortcuts

  • Collin Anderson 10:52 am on May 5, 2017 Permalink | Reply  

    Fewer Features is better 

    Keep it simple.

  • Collin Anderson 2:16 pm on March 6, 2017 Permalink | Reply  

    GitLab Values 

    Collaboration: Helping others is a priority, even when it is not related to the goals that you are trying to achieve. You are expected to ask others for help and advice. Anyone can chime in on any subject, including people who don’t work at GitLab. The person who has to do the work decides how to do it but you should always take the suggestions seriously and try to respond and explain.

    • Kindness: We don’t want jerks in our team. Some companies say Evaluate People Accurately, Not “Kindly”. We’re all for accurate assessment but we think it must be done in a kind way. Give as much positive feedback as you can and do it in a public way.
    • Negative is 1-1: Give negative feedback in the smallest setting possible, one-on-one video calls are preferred.
    • Say thanks: Recognize the people that helped you publicly, for example in our #thanks chat channel.
    • Feedback is always about the work: Clearly make negative feedback about the work itself, not the person. When giving feedback always provide at least one clear and recent example. If a person is going through a hard time in their personal life, then take that into account. An example of giving positive feedback is our thanks chat channel.
    • Get to know each other: We use a lot of text based communication and if you know the person behind the text it will be easier to prevent conflicts. So encourage people to get to know each other on a personal level through our team calls, virtual coffee breaks, and during our summit.
    • Don’t pull rank: If you have to remind someone of the position you have in the company you’re doing something wrong, people already know we have a hierarchical decision making process. Explain why you’re making the decision and respect everyone irrespective of their function.
    • Say sorry: If you made a mistake apologize. Saying sorry is not a sign of weakness but one of strength. The people that do the most will likely make the most mistakes.
    • No ego: Don’t defend a point to win an argument or double-down on a mistake. You are not your work, you don’t have to defend your point, you have to search for the right answer together.
    • See others succeed: An applicant that talked to a lot of people inside GitLab mentioned that compared to other companies one thing stood out the most. Everyone at GitLab mentioned wanting to see each other succeed.

    Efficiency: We care about working on the right things, not doing more than needed, and not duplicating work. This enables us to achieve more progress which makes our work more fulfilling.

    • Boring solutions: Use the most simple and boring solution for a problem. You can always make it more complex later if that is needed. The speed of innovation for our organization and product is constrained by the total complexity we have added so far, so every little reduction in complexity helps. Don’t pick an interesting technology just to make your work more fun, using code that is popular will ensure many bugs are already solved and its familiarity makes it easier for others to contribute.
    • Be respectful of other’s time: Consider the time investment you are asking others to make with meetings and a permission process. Try to avoid meetings and if one is needed make attendance optional by making the invite optional, by having a clear agenda linked from the invite, and by documenting the outcome. Instead of having people ask permission trust their judgment and offer a consultation process if they have questions.
    • Spend company money like it’s your own: Every dollar we spend will have to be earned back, be as frugal with company money as you are with your own.
    • Freedom: You should have clear objectives and the freedom to work on them as you see fit.
    • Frugality: Amazon states it best with: “Accomplish more with less. Constraints breed resourcefulness, self-sufficiency and invention. There are no extra points for growing headcount, budget size or fixed expense.”.
    • ConvDev: We work according to the principles of conversational development.
    • Short verbal answers: Give short answers to verbal questions so the other party has the opportunity to ask more or move on.
    • Keep broadcasts short: Keep 1 to many written communication short, as mentioned in this HBR study: “A majority say that what they read is frequently ineffective because it’s too long, poorly organized, unclear, filled with jargon, and imprecise.”.
    • Managers of one: We want team members to be a manager of one who doesn’t need daily check-ins to achieve their goals.
    • Responsibility: Over rigidity when possible we give people the responsibility to make a decision and hold them accountable for that instead of imposing rules and approval processes.
    • Accept mistakes: Not every problem should lead to a new process to prevent them. Additional process make all actions more inefficient, a mistake only affects one.

    Iteration: We do the smallest thing possible and get it out as quickly as possible. If you make suggestions that can be excluded from the first iteration turn them into a separate issue that you link. Don’t write a large plan, only write the first step. Trust that you’ll know better how to proceed after something is released. You’re doing it right if you’re slightly embarrassed by the minimal feature set shipped in the first iteration. This value is the one people underestimate when they join GitLab, the impact both on your work process and on how much you achieve is greater than anticipated. In the beginning it hurts to make decisions fast and to see that things are changed with less consultation. But frequently the simplest version turns out to be the best one.

    • Reduce cycle time: Short iterations reduce our cycle time.
    • Work as part of the community small iteration make it easier to work with the wider community. Their work looks more like our work and our work is quicker to give feedback too.
    • Minimum Viable Change (MVC): Always look to make the quickest change possible to improve the outcome. If you think it is better than what is there now do it, no need to wait for something polished.
    • Make a proposal: If you need to decide something as a team make a proposal instead of calling a meeting to get everyone’s input. Having a proposal will be a much more effective use of everyone’s time. The people that receive the proposal should not feel left out, the person making it should not feel bad if a completely different proposal is implemented. Don’t let your ego to be involved early or to see your solution implemented stand in the way of getting to the best outcome.
    • Everything is in draft: At GitLab we rarely put draft on any content or proposals. Everything is always in draft an subject to change.
    • Under construction: As we get more users they will ask for stability, especially in our UX. We should always optimize for the long term. This means that users will be inconvenienced in the short term, but current and future users will enjoy a better product in the end.

  • Collin Anderson 9:10 pm on March 1, 2017 Permalink | Reply  

    Qualities that make the most difference in programmers productivity 

    • Bare programming abilities: getting sub-tasks done

    Surprisingly the ability to use basic imperative programming constructs very efficiently in order to implement something is, in my experience, not as widespread as one may think.

    • Experience: pattern matching

    An experienced programmer eventually knows how to deal with a variety of sub tasks. This avoids both a lot of design work, but especially, is an extremely powerful weapon against design errors, that are in turn among the biggest enemies of simplicity.

    • Focus: actual time VS hypothetical time

    Internal factors are procrastination, lack of interest in the project at hand (you can’t be good doing things you do not love), lack of exercise / well-being, poor or little sleeping.
    External factors are frequent meetings, work environments without actual offices, coworkers interrupting often and so forth.

    • Design sacrifice: killing 5% to get 90%

    Often complexity is generated when there is no willingness to recognized that a non fundamental goal of a project is accounting for a very large amount of design complexity… A project that is executed in order to maximize the output, is going to focus exactly on the aspects that matter and that can be implemented in a reasonable amount of time.

    • Simplicity

    the two main drivers of complexity are the unwillingness to perform design sacrifices, and the accumulation of errors in the design activity.
    An initial design error, in the wrong hands, will not generate a re-design of the same system, but will lead to the design of another complex solution in order to cope with the initial error. The project, thus, becomes more complex and less efficient at every wrong step.
    each time a complex solution is needed, it’s important to reason for a long time about how the complexity can be avoided, and only continue in that direction if no better possibility is found even considering completely different alternatives.

    • Perfectionism, or how to kill your productivity and bias your designs

    things like robustness, simplicity, ability to deliver in time, are often never accounted for.

    • Knowledge: some theory is going to help

    To be a super expert of everything is not required, but to be at least aware of a multitude of potential solutions for a problem certainly is.

    • Low level: understanding the machine

    Good competence of C, the understanding of how CPUs work and clear ideas about how the kernel operates and how system calls are implemented, can save from bad late-stage surprises.

    • Debugging skills

    The sum of being good at gaining state about a bug, incrementally, in order to fix it with a rational set of steps, and the attitude of writing simple code that is unlikely to contain too many bugs, can have a great effect on the programmer efficiency.

  • Collin Anderson 7:59 am on February 2, 2017 Permalink | Reply  

    DSLreports Speed Test is the best 

    It measures “bufferbloat”, which tests latency during peak bandwidth usage.

    My comcast connection gets a D or F rating :)

  • Collin Anderson 7:33 pm on December 21, 2016 Permalink | Reply  

    One Sure-Fire Way to Improve Your Coding

    The most obvious way to improve your coding is to write more code. Everybody knows that. However, another activity which I guarantee will improve your coding is the complete opposite of writing. I will state this as plainly as I possibly can:

    If you want to dramatically increase your programming skills you need to be reading other people’s code.

  • Collin Anderson 5:19 pm on November 18, 2016 Permalink | Reply  

    You Are Not Paid to Write Code 

    You Are Not Paid to Write Code

    Every time you write code or introduce third-party services, you are introducing the possibility of failure into your system.
    I think the same can safely be said of code—more code, more problems.

    almost anything is easier to get into than out of. When we introduce new systems, new tools, new lines of code, we’re with them for the long haul. It’s like a baby that doesn’t grow up.

    We’re not paid to write code, we’re paid to add value (or reduce cost) to the business. Yet I often see people measuring their worth in code, in systems, in tools—all of the output that’s easy to measure.

    the siloing of responsibilities. Product, Platform, Infrastructure, Operations, DevOps, QA—whatever the silos, it’s created a sort of responsibility lethargy. “I’m paid to write software, not tests” or “I’m paid to write features, not deploy and monitor them.” Things of that nature.

    I think this is only addressed by stewarding a strong engineering culture and instilling the right values and expectations.

  • Collin Anderson 11:16 am on October 17, 2016 Permalink | Reply  

    10 Modern Software Over-Engineering Mistakes 

    View story at

    if we plan for 100 things, Business will always come up with the 101st thing we never thought of…we have no clue what’s headed our way.

    In my 15 year involvement with coding, I have never seen a single business “converge” on requirements. They only diverge. Its simply the nature of business and its not the business people’s fault.

    • Prefer Isolating Actions than Combining
    • Duplication is better than the wrong abstraction
    • Wrappers are an exception, not the norm. Don’t wrap good libraries for the sake of wrapping
    • Blindly applying Quality concepts (like changing all variables to “private final”, writing an interface for all classes, etc) is NOT going to make code magically better.
    • In House “Inventions” – It feels cool in the beginning. But these are most common sources of Legacy in few years… There is a constant effort required to keeping this going. Even a tiny open source library takes a lot of time to maintain.
    • Refactoring is part of each and every story. No code is untouchable
    • Quality needs time and not just skill. And smart developers frequently overestimate their capability. Finally they end up taking ugly hacks to finish stuff on a self-committed suicide timeline. TL;DR — Bad Estimation destroys Quality even before a single line of code is written
  • Collin Anderson 12:31 pm on October 16, 2016 Permalink | Reply  

    must protect the technology team from becoming a pure execution arm 

    I hate environments where the technology department is simply implementing what was envisioned by others. It might as well be an outsourced development team because it becomes independent of the decision making process. As Camille Fournier puts it in ‘On the role of CTO,’ “The CTO must protect the technology team from becoming a pure execution arm for ideas without tending to its own needs and its own ideas.”

  • Collin Anderson 1:34 pm on August 8, 2016 Permalink | Reply  

    Working Software 

    “there is nothing like a tested, integrated system for bringing a forceful dose of reality into any project. Documents can hide all sorts of flaws. Untested code can hide plenty of flaws. But when people actually sit in front of a system and work with it, then flaws become truly apparent: both in terms of bugs and in terms of misunderstood requirements.”

  • Collin Anderson 1:19 pm on July 19, 2016 Permalink | Reply  

    John Carmack on Inlined Code

    The way we have traditionally measured performance and optimized our games encouraged a lot of conditional operations – recognizing that a particular operation doesn’t need to be done in some subset of the operating states, and skipping it. This gives better demo timing numbers, but a huge amount of bugs are generated because skipping the expensive operation also usually skips some other state updating that turns out to be needed elsewhere.

    We definitely still have tasks that are performance intensive enough to need optimization, but the style gets applied as a matter of course in many cases where a performance benefit is negligible, but we still eat the bugs. Now that we are firmly decided on a 60hz game, worst case performance is more important than average case performance, so highly variable performance should be looked down on even more.

    It is very easy for frames of operational latency to creep in when operations are done deeply nested in various subsystems, and things evolve over time. This can lay hidden as a barely perceptible drop in input quality, or it can be blatantly obvious as a model trailing an attachment point during movement. If everything is just run out in a 2000 line function, it is obvious which part happens first, and you can be quite sure that the later section will get executed before the frame is rendered.

    Besides awareness of the actual code being executed, inlining functions also has the benefit of not making it possible to call the function from other places. That sounds ridiculous, but there is a point to it. As a codebase grows over years of use, there will be lots of opportunities to take a shortcut and just call a function that does only the work you think needs to be done. There might be a FullUpdate() function that calls PartialUpdateA(), and PartialUpdateB(), but in some particular case you may realize (or think) that you only need to do PartialUpdateB(), and you are being efficient by avoiding the other work. Lots and lots of bugs stem from this. Most bugs are a result of the execution state not being exactly what you think it is.

    In almost all cases, code duplication is a greater evil than whatever second order problems arise from functions being called in different circumstances, so I would rarely advocate duplicating code to avoid a function, but in a lot of cases you can still avoid the function by flagging an operation to be performed at the properly controlled time.

    To sum up:

    If a function is only called from a single place, consider inlining it.

    If a function is called from multiple places, see if it is possible to arrange for the work to be done in a single place, perhaps with flags, and inline that.

    If there are multiple versions of a function, consider making a single function with more, possibly defaulted, parameters.

    If the work is close to purely functional, with few references to global state, try to make it completely functional.

    Try to use const on both parameters and functions when the function really must be used in multiple places.

    Minimize control flow complexity and “area under ifs”, favoring consistent execution paths and times over “optimally” avoiding unnecessary work.

Compose new post
Next post/Next comment
Previous post/Previous comment
Show/Hide comments
Go to top
Go to login
Show/Hide help
shift + esc