Tuesday, May 3, 2016

Hello, Startup



Hello, Startup
MVP: a version of a new product which allows a team to collect the maximum amount of validated learning about customers with the least effort. The point of an MVP is learning. The goal is to find the cheapest way to validate a hypothesis with real customers.
Landing page
Explainer video
Crowdfunding
Wizard of Oz
Piecemeal MVP

Richard Hamming did important work at Bell Labs because he intentionally sought out important problems, and not just comfortable ones
Do things that don’t scale

Good names should answer all the big questions, be precise and thorough, reveal intent, and follow conventions.

Answer all the big questions
The name of a variable, function, or class should answer all the big questions. It should tell you why it exists, what it does, and how it is used.

You should also avoid vague variable names like tmp, data, and parts.
Instead of subtotal1 and subtotal2, use names that make it clear what the values represent, such as subtotalWithShipping and subtotalWithShippingAndTax.

Be thorough
String csvLine, json = "[";
String[] csvFields;
Names that are more thorough not only make it easier to read the code, but also help prevent bugs.

double totalWeightInLbs = packagingWeightInLbs +
                          (itemWeightInKgs * numberOfItems);
By being thorough, you can encode information in variable names that makes wrong code look wrong.1 Including units in a variable name is one example (e.g., lengthInMeters is better than just length), but anything that encodes how a variable should be used is helpful (e.g., csvLine is better than just line).

Reveal intent
Follow conventions

If I look at a single file and it’s written by 10 different engineers, it should be almost indistinguishable which part was written by which person. To me, that is clean code. The way you do that is through code reviews and publishing your style guide, your patterns, and your language idioms. Once you learn them, everybody is way more productive because you all know how to write code the same way. At that point, it’s more about what you’re writing and not how you write it.

Clear error messages are a hallmark of clean code. You can throw exceptions, make error messages a part of the return value, or log errors. Just don’t fail silently

Don’t Repeat Yourself (DRY)
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.

Duplication can arise in any part of your technology, including the architecture, code, tests, process, requirements, and documentation,
Lack of awareness, such as multiple developers creating their own StringUtil classes in a large codebase because they didn’t know a similar one already existed (and because they didn’t know there was an even better version available as an open source library).

Reinventing the wheel is one of the most common and unnecessary forms of duplication. Whenever possible, you should use open source libraries instead.

Single Responsibility Principle (SRP)
Loose coupling
High-level modules should not depend upon low-level modules. Both should depend upon abstractions.

Abstractions should not depend upon details. Details should depend upon abstractions.
A long chain of method calls and field lookups is usually a sign of tight coupling.

you should prefer an injected abstraction over a concrete implementation for libraries that:
Have side effects.
Behave differently in different environments.

public interface PassthroughCache<K, V> {
  V getOrElseUpdate(K key, Supplier<V> valueIfMissing);
}
return cache.getOrElseUpdate(
  user.getId(),
  () -> articleStore.getArticlesForUserSince(user.getId(),
                                             since));
High cohesion
The word “util” in the name of a class is a classic sign of low cohesion.
Don’t comment bad code—rewrite it.

technical debt begets technical debt. Once you allow a small amount of ugly code into your system and do nothing to fix it, a whole lot more is likely to follow, until the whole structure begins to crumble. This is typically known as the parable of the broken window.

Scaling coding practices
Automated tests
Split up the code
Code reviews
Documentation

Scaling performance
make it work, make it right, make it fast

Optimize
Divide and conquer
Divide a problem into many smaller problems and solve the problems across many CPUs or servers so that each one has to do less work. Examples: multiple web servers, replicating or shading a database, MapReduce.

Caching
Laziness
Avoid doing work by putting it off until it’s absolutely necessary. Examples: lazy-loading parts of a web page only when you scroll to it, optimistic locking in a database.
Approximate correctness
In many cases, it takes less work to get an answer that is “close enough” than to get one that’s exactly correct.

Asynchrony
Instead of locking or blocking while waiting on the result of a computation, continue to do work and have the computation notify you when it’s done.
Examples: non-blocking I/O, event loops, lock-free data structures.

Jitter and randomization
Avoid spikes and hot spots by trying to spread the load out evenly. Examples: randomizing cache expiration dates.

Throttling
Reject certain computations so that they don’t slow down other ones.
Examples: rate-limiting requests on a server or removing slow servers from the request path.

Redundancy
Kick off the same computation more than once and return the one that finishes fastest.
Examples: backup or hedged requests in distributed systems [Dean and Barroso 2013], redundant servers in case of failure (e.g., hot-standby for a database).

Co-location
Move things physically closer together to reduce latency.
Examples: CDNs, multiple data centers around the world, putting related servers in the same server rack.

Faster hardware
Faster algorithms
public static String reverseWordsInSentence(String sentence) {
  return Arrays
    .stream(sentence.trim().split("\\s+"))
    .map(word -> new StringBuilder(word).reverse())
    .collect(Collectors.joining(" "));
}

WRITE GOOD COMMIT MESSAGES
COMMIT EARLY AND OFTEN
Aim for each commit to be a reasonably sized unit that fully implements a single purpose.
Single purpose means you shouldn’t fix two bugs in one commit, implement two features in one commit, or refactor existing code and implement new code in one commit. Fully implements means you shouldn’t commit code that breaks the build or allows a user to see an unfinished feature. Reasonably sized means you should break your work up into small, incremental steps.

TRUNK-BASED DEVELOPMENT
In a trunk-based development model, developers do all of their work on the same branch—typically trunk. There are no feature branches.
A self-testing build is a fully automated build process (i.e., you can run it with a single command) that has enough automated tests so that, if they all pass, you can be confident the code is stable.

BRANCH BY ABSTRACTION
FEATURE TOGGLES
The idea behind a feature toggle is that unfinished or risky code should be disabled by default, and that you have an easy way to enable it when it’s ready. This approach allows you to break up large features into small, incremental pieces and check in each one as soon as it’s stable as opposed to completely finished.

If you do use a feature toggle, you have to be disciplined about cleaning it up once the feature has been enabled, or your codebase will be littered with branches of code that are no longer executed. At the minimum, put a TODO above each feature toggle as a reminder.

You can make deployments and rollbacks even safer by following a canary deployment model.
When deploying a new version of your code, you first deploy it to just a single server, called the canary. All the other servers continue to run the old code. You can then compare the canary server with an old server (as a baseline) to see if there are any bugs or performance problems.

BACKWARD COMPATIBILITY
As a service, you cannot delete anything in your public API without a feature toggle.
As a client, you cannot depend on anything new in a public API without a feature toggle.
The only way to remove something from a public API is to wrap the removal in a feature toggle and only enable it after usage goes to zero. 
For a client, rule #2 means that any call to a new API in another service must be wrapped in a feature toggle, and only enabled after the new API has been deployed.

If you can’t measure it, you can’t fix it.

private final Logger logger = LogManager.get(this.getClass());
The fully qualified class name appears in every log message, making it easy to figure out where that message came from.
Include a unique id
Make the text grep friendly
Log the full stack trace
The only exception to the “single line” rule is for stack traces.

Metrics
AVAILABILITY LEVEL
BUSINESS LEVEL
APPLICATION LEVEL
CODE LEVEL
PROCESS LEVEL

Alerting

Mastery
Most programmers will jump at the opportunity to learn a new technology or hone their skills. We’re naturally attracted to hard problems because we know they will challenge us and force us to get better.

Purpose
The key is to avoid using contingent rewards—that is, rewards based on an if-then condition, such as “if you do X, I’ll give you Y”

Rule #1: Use your good judgment in all situations.

Discuss and document what went wrong and move on with your life.
Build an automated solution to prevent this problem in the future.
Introduce a manual process to prevent this problem in the future.

For small projects, prototypes, and experimentation, a minimal framework can be great. For example, the “Hello, World” for Sinatra is just five lines of Ruby code:

require 'sinatra'

get '/hi' do
  "Hello, World!"
end
https://en.wikipedia.org/wiki/Peter_principle
The Peter principle is a concept in management theory formulated by Laurence J. Peter in which the selection of a candidate for a position is based on the candidate's performance in their current role, rather than on abilities relevant to the intended role. Thus, employees only stop being promoted once they can no longer perform effectively, and "managers rise to the level of their incompetence."

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts