Story Practice Scripts — full sample answers

Read these out loud. Time yourself. Aim for 2 to 2.5 minutes per story.

These scripts use simple words and short sentences on purpose — easier to remember, easier to deliver, easier to recover from if you lose your place.

Each script follows STAR (Situation / Task / Action / Result / Lesson). The story summaries with anchors are in 02-experience.md. Use these scripts for practice; use the summaries in the actual interview as memory hooks.


Practice rules

  1. Read out loud first. Silent reading is not practice. Your mouth needs to learn the words.
  2. Time yourself. If you're under 90 seconds, you're rushing. If over 3 minutes, you're rambling.
  3. Pause where there are paragraph breaks. Breathing space lets the listener absorb numbers.
  4. Don't memorize word for word. Memorize the shape — the order of points and the key numbers. The exact words can change.
  5. Practice the lesson last. That's the line they'll remember. Land it slowly.

Script 1 — Doze mode server spike (~2 min)

At LINE, I was working on the Home tab — the main tab in the LINE app, with around 200 million users. One day, the server team came to us with a problem. The recommendation API was getting big traffic spikes at midnight and 5 to 6 AM every day. I owned the Home tab. That's where the API was called from. But when I looked at the code, it was fine. No bug. No retry loop. The code was correct.

So I started with data. I asked the server team for the traffic numbers. The pattern was very clear: spikes happened only at the 0-minute mark of each hour. And the biggest spikes were at midnight and 5 to 6 AM.

I thought about what's special about those times. Midnight is when many people plug in their phones to charge. 5 to 6 AM is when alarms start waking phones up. So I read about Android Doze mode. Doze blocks WorkManager jobs when the phone is sleeping. When the phone wakes up — through charging or alarm — Doze releases all the queued jobs at the same time. That's why we saw spikes at exact minute marks. The system was syncing all phones together.

So the code was correct. The real problem was the interaction between WorkManager and Doze. I changed the approach: only sync when the user actually opens the app. Users open LINE at different times, so traffic spreads out by itself.

The result was a 90% reduction in nighttime requests. No UX impact. I also wrote a document about Doze for the team, so we don't hit the same trap again.

The lesson I keep with me: the hardest bugs are not in the code you wrote. They are in how your code interacts with the system around it.

Delivery notes:

  • Pause after "The code was correct." That sentence is the hook.
  • The "midnight = charging, 5-6 AM = alarms" line is the 'aha' moment. Slow down there.
  • End with the lesson clearly. That's the line a senior interviewer will remember.

Script 2 — APNG memory crisis (~2.5 min)

Right after we launched Event Effect — full-screen birthday animations on LINE Home — Android crashes started. Even high-end phones crashed if many other apps were running. The Design team and PM had just announced this feature, so the pressure was very high.

Within a few hours, I confirmed the pattern: Android-only, and memory-related. I called an emergency meeting and made a hard call. I proposed: "Disable Event Effect on Android with a feature flag, while we fix it properly." The team agreed. The crashes stopped that day.

With users protected, I started the real investigation. I profiled the APNG library we used. I found the problem. It decoded all frames at the same time. So a 4-second full-screen animation took about 500MB of memory. On test devices it was fine — they were clean. But real users have 30 to 50 apps running. They had no memory left.

I evaluated three options: fix the in-house C++ library, find an open source library with just-in-time decoding, or build a new one from scratch. I picked the open source one. I benchmarked it: from 500MB down to 5MB. A 100x improvement. Same visual quality. Less battery.

First, I rolled it out to my feature. Then app-wide, through a Glide loader and a migration guide. After that, Stickers used 80% less memory too. Other features moved over.

The crisis was solved the same day. The proper fix shipped in 2 weeks. The feature came back with zero crashes. We also added a new testing standard: simulate 30 or more apps running, plus memory pressure, before launch.

Two lessons. First: test in real-world conditions, not lab ideals. Second: temporary mitigation plus a proper fix beats rushing under pressure.

Delivery notes:

  • The "500MB" and "5MB" numbers must land. Pause around them.
  • Frame the disable-Android decision as the senior call: protect users first, fix second.
  • Mention "app-wide benefit" — Stickers and others. That's what makes this a foundation story, not just a feature fix.

Script 3 — Event Effect end-to-end (~2.5 min)

I was assigned Event Effect for the LINE Home tab. The idea was full-screen celebration animations for birthdays and holidays. 200 million users, 200+ countries. The initial requirement was one sentence: "Show a special animation during the user's birthday or a holiday." It looked simple. But it wasn't.

First, I mapped the user journey. Then I listed every unclear case. For example: what if the user opens the app at 23:59:50 on their birthday? What if their birthday is February 29 and this year is not a leap year? What if a birthday and a holiday fall on the same day? What if the animation download fails?

Then I ran an alignment meeting with PM, Design — based in Korea — QA, and the Server team. But instead of just asking "what should we do?", I brought a proposal for each case. For 23:59 — let the animation play to the end. For Feb 29 — celebrate on Feb 28. For the conflict — personal moments win. For download failure — pre-fetch 5 days ahead and retry with backoff.

The meeting uncovered 15+ cases the original requirement did not cover.

After alignment, I designed the system as 4 independent phases: Discovery, Resource Acquisition five days early, Showtime — using Flow and Room reactive queries, no polling — and Cleanup with a one-day grace period. Each phase fails on its own. Each phase survives app kill or device reboot through WorkManager.

I also wrote a tech blog about the pattern, so other teams could reuse it.

The result: launched on time. Zero bugs caused by unclear requirements. No missed celebrations. The blog became a reference. PM and Design started involving me earlier in future projects.

The lesson: owning a project means making the requirements right and designing for real-world complexity. Not just coding what is written.

Delivery notes:

  • Lead with scale — 200 million users, 200+ countries — early.
  • The "instead of asking, I proposed defaults" line is the senior signal. Hit it clearly.
  • "Zero bugs caused by unclear requirements" is the headline number. Don't bury it.

Script 4 — Home tab / Smart Channel redesign (~2.5 min)

Home tab and Smart Channel are two different features in the LINE app. From the outside they look different. But inside, they had the same problems. Tangled data flow. Unclear layers. No single source of truth. And many ad-hoc shims piled up over years to translate old data into new formats. Every new feature was slow and risky to add. Nobody could predict what would break.

My task was to untangle the code. Define clear layers, one-direction data flow, and one source of truth. All without freezing feature delivery — the team had to keep shipping during the migration.

The first thing I did was important: I noticed the same root cause across both features. So instead of fixing them separately, I designed one solution that worked for both.

I designed a target architecture with clear layers. Each layer has one job. State lives in one place per screen. I pushed back on over-design — when someone proposed a custom DSL, I said: "we don't need that." I migrated step by step. Old and new code lived together for one release. New features used the new pattern. Old code got migrated when we touched it.

The first proof came right after we shipped. The Home tab redesign was the first feature built on the new architecture, and I delivered Android one week after iOS — with one engineer against their two. That gap usually goes the other way.

Longer term: 40% faster onboarding for new engineers. 60% fewer bug reports on those features. And — this is the most important part — other teams across the LINE app started using the same architecture. They saw it working in our features and adopted it.

The lesson: senior-IC impact comes from patterns other teams adopt, not just code I ship. The real win was naming the shared root cause across two features that looked different on the surface.

Delivery notes:

  • The four problems (tangled flow / unclear layers / no SSoT / shims) come fast — list them, don't explain each.
  • The "same root cause across both features" line is what makes this a senior story. Slow down there.
  • The "1 week behind iOS, 1 engineer vs 2" line is the strongest concrete number. Hit it clearly. The aside "that gap usually goes the other way" is the punchline — pause after it.
  • End on "other teams adopted it" — that's the foundation-work signal.

If they probe — "what do you mean by tangled?":

"Two patterns in particular. First, the UI was calling the database or network directly, then handing the result to the ViewModel, which sent it back to the UI — so the data path looped instead of flowing one way. Second, the ViewModel reached into the data layer's flow and mutated its state based on what the UI was showing — so the data layer's emissions depended on the screen state. That's why nobody could predict what would break: a change in one place could ripple anywhere."

If they probe — "what did the architecture look like?":

"Standard layered — data, ViewModel, UI — plus one piece worth calling out: I introduced a layer I called ViewDataController. It sits between the ViewModels and the UI. Its job is to gather state from multiple ViewModels and from the UI, and produce the UI-ready state.

Two reasons it exists. First, lifetime: Android ViewModels survive configuration changes. UI-ready state shouldn't — if you store it on a ViewModel, you get stale state when the UI rebuilds. The ViewDataController has the same lifetime as the UI, so the combined state dies with the UI.

Second, composition: you can't construct a ViewModel directly — Jetpack hands them out through a factory — so a ViewModel can't depend on another ViewModel. When a screen needs state from multiple ViewModels, you need a layer that can depend on them. That's what ViewDataController does."


Script 5 — TLA Architecture Committee (~2.5 min)

At LINE, we have an architecture committee called TLA — The Layer Architecture. It sets Android architecture standards across 150+ engineers. When I joined, the iOS guidelines were already written. The Android discussions had been running for months. The senior engineers and managers in the committee were already aligned on a direction.

I read the docs and felt the direction was wrong. Too theoretical. Too much abstraction. The architecture was designed for big features. But in reality, 50% of LINE's features stay small. So most teams would carry a heavy framework for no benefit.

I had no formal authority. I was joining a group of seniors who already agreed.

So I gathered data, not opinions. I wrote a bash script to count files and lines per module across the LINE Android codebase. The result: 50% of features are small. 75% are considerably small. Only Home and Smart Channel are truly large.

Then I drafted specific feedback with proposed changes — designed to save the prior work and still hit the Phase 1 target. I suggested Google's Android architecture as a more practical reference. When my written feedback wasn't landing, I organized a face-to-face meeting. I showed the data. I walked through the trade-offs. I made my intent clear: this is for the product, not for ego.

The committee accepted my proposals. Phase 1 finished on time. The TLA iOS author told me later that he saw my view, and respected the data and compromise approach. My manager — who was not happy with me at first — was happy with the outcome.

The lesson: influencing without authority needs three things. Data. Respect for prior work. And a clear path forward — not just criticism.

Delivery notes:

  • The "50% / 75%" data point is the anchor. Without it, the story has no weight.
  • "This is for the product, not for ego" — say this slowly. It's the line that shows maturity.
  • Acknowledge that the manager wasn't happy at first. Don't hide that. It makes the result land harder.

Script 6 — Junior iOS mentor (~2 min)

My manager assigned me and a junior iOS engineer to a video autoplay feature — similar to the auto-playing videos on Facebook or X feed. Normally the junior was given simple tasks only. His direct iOS mentor didn't believe in him. My manager focused on results, not growth.

Instead of taking the lead myself, I proposed something different. I told my manager: "Let him be the main person in charge. If the project fails, I take responsibility." My manager agreed.

I set up a checkpoint system. If he missed a checkpoint, I would step in. But I gave him real ownership. He wrote the design doc. He identified edge cases. He drove communication with the PM.

I focused my coaching on structure and clean code — not implementation details. The iOS seniors guided him on platform-specific things. I asked questions that helped him design first, instead of telling him what to write.

The first checkpoint had a 2-week deadline. He delivered in under 1 week — with deeply observed patterns from other apps, and thoughtful edge case handling. That moment changed how the team saw him.

The result: the project shipped successfully with very few bugs, especially on iOS. The junior was promoted to mid-level after this project. The manager and the iOS senior changed their view about him.

The lesson: people often have more capability than they are given credit for. The key is structured support — not throwing them in without a safety net, and not blocking them with too much oversight.

Delivery notes:

  • "If the project fails, I take responsibility" — say this confidently. Senior engineers absorb risk for juniors.
  • The "1 week instead of 2 weeks" moment is small but important. It shows the system worked.
  • The lesson is the heart of the story. Land it.

Script 7 — Chat menu rewrite — the failure (~2.5 min)

This is a story I'm not proud of, but I learned a lot from it.

In 2019 at LINE Hanoi, just two of us — me and one teammate — worked on a chat menu redesign. Early on, we made an architectural shortcut. Instead of building a separate screen, we decided to overlay the new menu on top of the existing Chat screen. The reason was: reuse APIs, save work. We didn't deeply assess what the overlay would break.

After 5 months of work, we found the bug. When the new menu covered the screen, incoming messages were marked as read — even though the user never saw them. This was a serious problem. The only real fix was to rewrite the menu as a separate screen.

The hard part: we had 3 weeks left, and 2 of those weeks were during the company holiday. My teammate was off, and most of the regular reviewers were off too.

I sat down and made an honest plan. I reached out to engineers in Tokyo, Korea, and Taiwan who were still working through the holiday. Korea and Taiwan helped with implementation. Tokyo helped with reviews. I prepared small, self-contained tasks that didn't need deep system knowledge — so they could pick them up easily. I worked top-down and bottom-up at the same time, so I was never blocked waiting for a review. I worked 8 AM to 10 PM every day, including weekends. 100+ commits per day for 2 weeks. Not something I want to repeat.

We delivered on time. The chat menu shipped before the deadline.

But the real value of this story is the lessons. There are three.

First: prepare more before committing to an approach. The overlay saved time on paper but cost much more later. A short design review upfront would have caught this.

Second: match risk to team size. With only 2 people, there's no safety net. A risky architecture in that situation made no sense.

Third: pull in others earlier on architecture decisions. Someone with more experience would likely have flagged the read-state coupling. I tried to be self-sufficient, but I should have asked.

Delivery notes:

  • Open with the honest framing: "I'm not proud of, but I learned a lot." Sets the tone.
  • Don't celebrate the heroics ("100+ commits a day"). Mention it once. The lessons are the point.
  • Spend the most time on the three lessons — that's what they want from a failure story.
  • If they ask "what would you do differently?" — your answer is already the three lessons.

Script 8 — MonoSketch (~1.5-2 min)

MonoSketch is my side project. It's an ASCII diagram editor that runs in the browser, written in Kotlin/JS. Today it has around 1800 stars on GitHub, 1000+ monthly active users, and was featured once on Hacker News.

I started it because I needed a way to make ASCII diagrams for tech docs. The existing tools were either too simple, or web-based but slow. I wanted something that felt like a real editor — fast, with infinite canvas, undo and redo, and shape connections that snap properly.

Even though I'm a single developer, I designed it carefully. Module separation. Architecture layers. Backward and forward compatibility for the save format — so old diagrams don't break when I add new features. Even commit log discipline. I sometimes don't follow my own rules. But the discipline is what keeps the project healthy in the long run.

The interesting technical parts: tile-based viewport rendering — only drawing what's visible — so it stays at 60 fps with 500+ shapes. Dirty-region invalidation. Custom Canvas API rendering. Auto-save with version history. Full CI/CD pipeline through GitHub Actions.

The Hacker News feature happened naturally. Someone shared it, and the front page brought new users. The project is still alive after years.

The lesson: shipping a side project end to end teaches you what frameworks hide from you. And — even on a small project, the standards I apply are the same as at work. Project size doesn't matter. The standards stay.

Delivery notes:

  • Lead with the numbers (1800 / 1000+ MAU / HN). They do the work.
  • "I sometimes don't follow my own rules" — say this honestly. Self-aware engineers are trusted more.
  • The "standards stay" line connects to your career arc (foundation work). Worth using even if they only know LINE stories.

How to use these scripts

When What to do
Week before interview Read each script aloud once. Time it. Note where you stumble.
Three days before Practice the 4 highest-priority stories twice each: 1 (Doze), 2 (APNG), 3 (Event Effect), 5 (TLA).
Day before One full read-through. Don't memorize. Re-read the delivery notes, not the script.
Hour before Read the lessons only — one sentence per story. That's the closing line that lands.
In the interview Don't recite. The summaries in 02-experience.md are your memory hooks. The script shape is in your head. The exact words come naturally.

Key lines to memorize

These are the lines that land hardest. Memorize these word-for-word — the rest can be improvised.

Story Memorized line
1 "The hardest bugs are not in the code you wrote. They are in how your code interacts with the system around it."
2 "Test in real-world conditions, not lab ideals."
3 "Owning a project means making the requirements right, not just coding what is written."
4 "Senior-IC impact comes from patterns other teams adopt, not just code I ship."
5 "Influencing without authority needs data, respect for prior work, and a clear path forward — not just criticism."
6 "People often have more capability than they are given credit for."
7 "Match risk to team size." (the most actionable lesson from this one)
8 "Shipping a side project end to end teaches you what frameworks hide from you."

results matching ""

    No results matching ""