Preparation for Priceline Interview
- list of anecdotes showing capability to be a senior dev using STAR method
- Situation, Task, Action, Result
- Try two methods:
- review job description, list behavioural requirements, then think of examples that demonstrate fullfillment
- think of your accomplishments and notable situations, and then list the qualities they show
- in either case, write a STAR outline for the example
Job Description Behavioural Requirements:
- agile, experimental, iterative
- collaborate with team
- speak up for your opinions
- converse respectfully and compromise
- ethics, honesty, transparency, compliance
- Customer, Innovation, Team, Accountability, Trust
- mentorship
Situations:
-
process improvement
- dynamo access module for longstanding billing bug
- experimentation, collaboration, transparency, innovation
- adopting typescript with metrics
- compromise on timeline, base conversation in facts, stand up for opinion, be open to difference perspectives, compromise as opportunity to improve ideas
- repo metrics, discovering consistent caching bug, adopting React Query
- innovation, collaboration by accepting suggestions (from among TS, increasing testing), team player, Accountability
- various scripts
- team player, innovation
- dynamo access module for longstanding billing bug
-
billing project
- adopting CDK
- building pipeline
- building typesafe API
- disagreement over frontend framework
- conflict over priority between new and old projects
-
architecture
- client cooperation to address performance
- security flaws
- lambda rework
- collaboration to gather requirements
- customer focus by improving dev speed and reliability
- initiative & speaking up
-
cooperation
- appointments
- brainstorm
- introduction of automated testing
Examples
Adopting Typescript
Situation:
- React/JS and nodejs lambda microservices function applications
- frequent typesafety production bugs and slow development
Task:
- convince team to increase developer efficiency and reliability by migrating to typescript
Action:
- discuss it in a meeting, got pushback, others justifiably were concerned with adoption time, migration, learning, delays to other efforts
- gathered repo metrics to show that 20% of dev time went to typesaftey bugfixes
- learned about efficacy of metric-driven decision making
Result:
- did encounter several setbacks that slowed adoption, I was able to address them and the adoption was more effective as a result
- process was smoother as a result of the compromise
- compromise by focusing efforts on frontend transition, starting with a few components, eventually moving to api code and lambdas
Scripting & Backend Redesign
Situation:
- backend development is slow and error prone, all changes are tested exelusively by editing in the lambda function embedded editor, then copying locally for a PR.
- results in bulky frontend, and unreliable, difficult to maintain backend
Task:
- improve developer experience of backend development, and redesign to improve dev efficiency, maintainability, and reliability
Action:
- write a set of scripts that would accept a function name, and would compare the local code of the function and its layers to the cloud state, and directly upload the state to the dev environment
- designed a module to handle routing, authentication & authorization, and error handling through a simple interface, and decomposed several lambda functions into modules to promote maintainability and code reuse
Result:
- developers became much more comfortable with backend development, and my scripts were used constantly by the whole team, backend reliability was increased.
Longstanding Billing Bug
Situation:
- Doctors were complaining that some payment record inconsistencies. Some tariffs they had already been paid for were marked 0 on their personal payment leger
Task:
- determine the cause, fix the old data
- do it quickly, because of trust
Action:
- investigated the problem, found that the bug had been active for 2.5 years, and many, many records were affected that needed to be fixed.
- developed a new query module, and took input from the team about features
- used it to thoroughly investigate the issue, understand its scope, develop a script, and a reversal script, test it on a small number of cases
Result:
- Dave was pleased, but Nate was angry that I executed the script without his approval. I thought that I was being accountable to my boss, but real accountability is understanding everyone who can be affected by an action, and getting their input.
- Trust - need customers to know that we're consistent and reliable, especially when money is involved
Conflict over project priority
Situation:
- two team leads, two team priorities, each lead in charge of one project
- while I was on paternity leave, only the other priority's tickets were assigned and worked on
Developer Brainstorm
Situation:
- everyone works hard, but in a flawed development process, and time isn't made to encourage critique and improvement of that process
- I had my own criticisms, but development is a collective effort, and any major change requires buy-in, which usually also requires discussion and compromise
Task:
- find a way to improve our development practices and get buy-in for changes
Action:
- with the permission of the CTO, I started holding a weekly "Developer Brainstorm" meeting every friday afternoon.
- In it we would discuss what people were working on, what parts of the development process were annoying, painful, or time consuming, and brainstorm what could be done to improve.
- I would record what people's objections were, and they tended to be the applications unreliability, the lack of automated testing
- based on these conversations, we were able to make some progress, such as by writing more unit and integration tests, refactoring the most unmaintainable modules
Result:
- automated testing did increase, and people tended to adopt a more critical approach to the development process
- however, in hindsight, we could have made more progress by adopting a more formal retrospective process, with buy-in from the top, and actual action plans
- what we had was too informal. For example, we wrote more automated tests, but we still had not adopted TDD, and extra time was not allocated during sprint planning to account for writing tests.
QBilling
Situation:
- company decided to open a new line of revenue by bidding on a government RFP, the CTO had it on good authority that we were the only company in a position to bid successfully, so we began work, and I was authorized to hire developers in anticipation of winning the contract
- I was put in charge of the project, and I wanted to avoid some of the inefficiencies that I had seen in the core project. These include unreliable software with routine and recurring production bugs, and heavy manual testing component, infrequent deployments
Task:
- Hire competent developers, architect the app, build a demo, design db schema
- all while balancing maintaining the biling features on the existing app
Action:
- adopted TDD, using automated tests as the formal specification for the software
- built a new deployment pipeline using AWS CDK instead of amplify, which allowed fine-grained control of infrastructure, and its static validation. The app was fully TS, from React, and included a typesafe API using TS-rest, though I had to build a plugin for it so that it would work with lambda functions triggered by API gateway.
- evaluate, hire, and mentor candidates
Results:
- the development process was faster and more reliable, I found that using test driven development meant that we had to deeply think about the interface of modules before implementation, and the result was that code was more maintainable, test cases more reliable, and manual testing a minor component of the development cycle.
- the effect of using CDK was that it was easier to make more complex infrastructure, although the initial setup took a lot longer.
Computer Cluster
Storm
Mapped Futures
- was using futuresUnordered, but wanted to mutate & remove futures by their key
- found other people wanted the same feature
- so I forked the library
- learned a lot about unsafe rust
Rust Development Experience
Technical aspects of development
-
labraries for various purposes
- logging: log
- data structures:
- indexSet, indexMap, hashSet, hashMap
- collections, BinaryHeak, BTree, VecDeque, Vec
- error handling:
- thiserror
- async:
- tokio, futuresUnordered, MappedFutures
- futures (channels, BoxFuture, Fuse)
- Arc, Mutex
- database:
- rusqlite, seaORM, diesel, r2d2
- api:
- axum, rspc, specta
- tauri
-
design techniques
- async tasks communicate either through shared ownership and interior mutability, or through channels
- the former if there are a set of operations and one-directional communication, the latter if you are sharing data that each task will decide what to do with
-
tooling available
- miri
- cargo test
- cargo watch
- rust-analyzer, clippy, rustfmt
Interesting features
- pattern matching with exhaustive cases
- newtypes
- typestates