1. Establish trust by questioning to get real data
  2. Understand high-level pain points and differentiators
  3. Document domain-driven architecture and models
  4. Write failing tests for functions
  5. Pseudocode functions
  6. Make it workable
  7. Make it maintainable with conventions and modular interfaces
  8. Make it scalable/efficient, if needed
  9. Focus on restarting regularly to adapt incrementally, inexpensively, and continuously

  10. Check-in relationship, short-term concerns, long-term objectives
  11. Time-box tasks throughout lifecycle
  12. Break down goal into atomic components
  13. Isolate Model-View-Controller structure
  14. Isolate Class composition
  15. Isolate singular-task, functions with inputs/outputs
  16. Write tests for Behavior-Driven Development
  17. Pseudocode
  18. Get to Minimum Viable Product
  19. Make it maintable
  20. Optimize
  21. Repeat

The point is to show progress, strategies, and optimization just like real life, not “knowing the answer” which isn’t possible for new problems. Drive the process like you’re the senior person, but be a great teammate too!

  1. Understand the problem
    • Think aloud
    • Ask questions
      • Scope the problem
      • Get clues
      • Express what you’re considering or not
    • Listen for clues carefully
    • Read carefully
    • Write down notes for givens like inputs and outputs
  2. Manually test out a simple, but realistic example
    • Reasonably big/realistic breadth
    • Include special cases so you don’t miss edge cases
    • Reverse engineer and breakdown thoughts
  3. State brute-force algorithm MVP; maybe pseudocode
    • Talk about tradeoffs like time and space complexity
  4. Optimize
    • Bottlenecks
    • Unnecessary complexity
    • Duplicated work
    • Edge cases
    • Consider time and space complexity tradeoffs
      • Data structures
        • Hash tables
      • Recursion
        • Bottom-up, vs. top-down
        • Memoization
        • Dynamic programming
  5. Walk through in detail; check against problem
  6. Write beautiful code
    • Modularize with top-down functions first
      • May save you from writing smaller helper utility functions that aren’t that important to logic
    • Refactor
    • Add arrows to insert new code instead of rewriting to save time
  7. Test your code (not the algorithm)
    • Code review
      • Logic
      • Areas vulnerable to errors
    • Small test cases
    • Special edge cases
    • Big test cases (like realistic example you made above)
    • Bugs
      • Think about root causes
      • Fix them

Good luck and bring your own thin whiteboard markers if you like!