Log In
Or create an account ->
Imperial Library
Home
About
News
Upload
Forum
Help
Login/SignUp
Index
inside front cover
Street Coder
Copyright
dedication
contents
front matter
preface
acknowledgments
about this book
Who should read this book
How this book is organized: A road map
About the code
liveBook discussion forum
about the author
about the cover illustration
1 To the streets
1.1 What matters in the streets
1.2 Who’s a street coder?
1.3 Great street coders
1.3.1 Questioning
1.3.2 Results-driven
1.3.3 High-throughput
1.3.4 Embracing complexity and ambiguity
1.4 The problems of modern software development
1.4.1 Too many technologies
1.4.2 Paragliding on paradigms
1.4.3 The black boxes of technology
1.4.4 Underestimating overhead
1.4.5 Not my job
1.4.6 Menial is genial
1.5 What this book isn’t
1.6 Themes
Summary
2 Practical theory
2.1 A crash course on algorithms
2.1.1 Big-O better be good
2.2 Inside data structures
2.2.1 String
2.2.2 Array
2.2.3 List
2.2.4 Linked list
2.2.5 Queue
2.2.6 Dictionary
2.2.7 HashSet
2.2.8 Stack
2.2.9 Call stack
2.3 What’s the hype on types?
2.3.1 Being strong on the type
2.3.2 Proof of validity
2.3.3 Don’t framework hard, framework smart
2.3.4 Types over typos
2.3.5 To be nullable or non-nullable
2.3.6 Better performance for free
2.3.7 Reference types vs. value types
Summary
3 Useful anti-patterns
3.1 If it ain’t broke, break it
3.1.1 Facing code rigidity
3.1.2 Move fast, break things
3.1.3 Respecting boundaries
3.1.4 Isolating common functionality
3.1.5 Example web page
3.1.6 Leave no debt behind
3.2 Write it from scratch
3.2.1 Erase and rewrite
3.3 Fix it, even if it ain’t broke
3.3.1 Race toward the future
3.3.2 Cleanliness is next to codeliness
3.4 Do repeat yourself
3.4.1 Reuse or copy?
3.5 Invent it here
3.6 Don’t use inheritance
3.7 Don’t use classes
3.7.1 Enum is yum!
3.7.2 Structs rock!
3.8 Write bad code
3.8.1 Don’t use If/Else
3.8.2 Use goto
3.9 Don’t write code comments
3.9.1 Choose great names
3.9.2 Leverage functions
Summary
4 Tasty testing
4.1 Types of tests
4.1.1 Manual testing
4.1.2 Automated tests
4.1.3 Living dangerously: Testing in production
4.1.4 Choosing the right testing methodology
4.2 How to stop worrying and love the tests
4.3 Don’t use TDD or other acronyms
4.4 Write tests for your own good
4.5 Deciding what to test
4.5.1 Respect boundaries
4.5.2 Code coverage
4.6 Don’t write tests
4.6.1 Don’t write code
4.6.2 Don’t write all the tests
4.7 Let the compiler test your code
4.7.1 Eliminate null checks
4.7.2 Eliminate range checks
4.7.3 Eliminate valid value checks
4.8 Naming tests
Summary
5 Rewarding refactoring
5.1 Why do we refactor?
5.2 Architectural changes
5.2.1 Identify the components
5.2.2 Estimate the work and the risk
5.2.3 The prestige
5.2.4 Refactor to make refactoring easier
5.2.5 The final stretch
5.3 Reliable refactoring
5.4 When not to refactor
Summary
6 Security by scrutiny
6.1 Beyond hackers
6.2 Threat modeling
6.2.1 Pocket-sized threat models
6.3 Write secure web apps
6.3.1 Design with security in mind
6.3.2 Usefulness of security by obscurity
6.3.3 Don’t implement your own security
6.3.4 SQL injection attacks
6.3.5 Cross-site scripting
6.3.6 Cross-site request forgery
6.4 Draw the first flood
6.4.1 Don’t use captcha
6.4.2 Captcha alternatives
6.4.3 Don’t implement a cache
6.5 Storing secrets
6.5.1 Keeping secrets in source code
Summary
7 Opinionated optimization
7.1 Solve the right problem
7.1.1 Simple benchmarking
7.1.2 Performance vs. responsiveness
7.2 Anatomy of sluggishness
7.3 Start from the top
7.3.1 Nested loops
7.3.2 String-oriented programming
7.3.3 Evaluating 2b || !2b
7.4 Breaking the bottle at the neck
7.4.1 Don’t pack data
7.4.2 Shop local
7.4.3 Keep dependent works separated
7.4.4 Be predictable
7.4.5 SIMD
7.5 1s and 0s of I/O
7.5.1 Make I/O faster
7.5.2 Make I/O non-blocking
7.5.3 The archaic ways
7.5.4 Modern async/await
7.5.5 Gotchas of async I/O
7.6 If all else fails, cache
Summary
8 Palatable scalability
8.1 Don’t use locks
8.1.1 Double-checked locking
8.2 Embrace inconsistency
8.2.1 The dreaded NOLOCK
8.3 Don’t cache database connections
8.3.1 In the form of an ORM
8.4 Don’t use threads
8.4.1 The gotchas of async code
8.4.2 MULTITHREADING with async
8.5 Respect the monolith
Summary
9 Living with bugs
9.1 Don’t fix bugs
9.2 The error terror
9.2.1 The bare truth of exceptions
9.2.2 Don’t catch exceptions
9.2.3 Exception resiliency
9.2.4 Resiliency without transactions
9.2.5 Exceptions vs. errors
9.3 Don’t debug
9.3.1 printf() debugging
9.3.2 Dump diving
9.3.3 Advanced rubber-duck debugging
Summary
index
inside back cover
← Prev
Back
Next →
← Prev
Back
Next →