ECS160-MT1
Info
The syllabus will include everything covered until today (2/4). The focus will be on design patterns and reflections/annotations/dynamic proxies. Microservice-related questions will have quite low weightage.
The exam will be closed book and on paper. You’re allowed a single-sided, hand-written, A4/US letter-sized cheat sheet. You may handwrite your notes on a tablet and get a print out of that.
Specific:
The course content and exam difficulty level has changed a lot since the last two iterations.
Design patterns were in the second half of the course, previously. So you’d have to check the final exams to find the design patterns questions.
There are a few Java-specific questions in these previous midterms and finals. We will not have Java-specific questions in the midterm or final.
Please ignore all security/Rust-related questions, since we’ll not cover those topics in the class this quarter.Midterm Content
Midterm focused on:
- Design Patterns and Reflections/annotations/dynamic proxies
also slightly on microservicesReviewing primarily in:
Link to original
- ECS160-LS1 (Course Intro)
- ECS160-LS2 (Design Patterns)
- ECS160-LS3 (Annotations and Reflections)
- ECS160-LS4 (Microservices)
- By midterm, got to about slide 65
Final also includes:
- ECS160-LS5 (SQL)
- ECS160-LS6 (Kafka)
- ECS160-LS7 (Kubernetes)
- ECS160-LS8 (Software Testing)
Final Exam Topics
Design Patterns - ECS160-LS2
Creational
- Singleton, abstract
Structural: - Adapter, proxy, decorator
Behavioral: - Template, state, observer, visitor
Sample Questions:
- When to use template method?
- Difference between proxy vs. decorator
- Integreating different design patterns
Wont ask:
- Specific programming-level concepts
Reflection and Annotations
Reflection for introspection
Bytecode generation for instrumentation and dynamic proxies
Annotations for adding metadata to objects, methods
Sample Questions:
- When to use static proxy vs dynamic proxies
- Annotations for applying proxy logic or reflection logic selectiveyl to a field or method
Microservices
For all of the following, understand: What are they? Why use them? What are their pros and cons? Resulting challenges?
- Microservice
- Data denormalization
- Eventual consistency
- Caching (KV stores e.g. Redis/Memcached)
- DB storage engines
- B+ trees vs. LSM trees
- Tradeoffs (read vs write workloads, sequential vs random reads)
Communication styles:
- RPC
- Message-queues
- Kafka
Sample Questions:
- Design questions where you’d have to pick the best:
- DB storage engine
- Choose between RPC, MQs, Kafka
- Decide if a caching layer will be helpful
Wont ask:
- Spring Boot
- gRPC
- JSON
- MongoDB API
- Network layers
- HTTP methods
- Protobuf encodings
- SQL commands
- etc.
Kafka
Push vs pull based system
Kafka logs vs LSM tree logs
- Does not support random reads at all; stores events instead of records
Why is the partitioning key important? (ordering)
Kafka consumer committed state and crash recovery - At most once vs at least once
Kafka replication - acks=0/1/all
Sample Questions:
- Imagine we see a message being delivered twice after a Kafka consumer rebooted after a crash - how could this happen
- If we tolerate N nodes going down, what should the replication factor be?
- Use cases where acks=0/1/all is appropriate
Wont ask:
- Kafka commands
- Details of Raft
- Metadata coordination
K8s
Container vs. virtual machine
What benefits do the pod abstraction provide over containers?
Label based scheduling; pod affinity
Fault tolerance and liveness probes
Sample Questions:
- Use cases for deploying chatty microservices on same pod, label based scheduling
- Use cases for picking the right liveness probe type
Wont ask:
- Docker commands
- Dockerfile format
- App descriptor format
- Exact config option names
- etcd details
- K8s networking details
Testing
The gradient of ‘smart’ testing:
- Blackbox testing
- Greybox testing (coverage-guided)
- Whitebox testing (symbolic execution)
Input generators and mutators, and when to use them
- Random generation
- Byte level mutators
- Dictionaries
- Grammar aware mutators
Coverage types:
- Edge based
- Value profile
- Path based
Benefits and challenges of each mutation/coverage type (throughput vs. valid input, etc.)
DGF (its usecase/need, distance metric)
Silent bugs and undefined behavior
Sanitizers concepts
- ASAN implementation tradeoffs
Symbolic execution benefits and challenges
Sample Questions:
- Which mutation strategy and coverage metric is best to find bugs in a particular app/program
- Do we need DGF for a particular use case
- Can symbolic execution find a particular bug in a piece of code - why or why not?
Wont ask:
- Details of buffer overflow / use-after-free / double-free
- AFL / clang / gcc comands
- KLEE API