Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How Yahoo Finance Android scales (AnDevCon 2017...

How Yahoo Finance Android scales (AnDevCon 2017, DC)

I spoke about the various techniques we employ around understanding our users, planning, CI/CD, experimentation, coding, culture and performance to deliver high quality software to our users at AnDevCon 2017 Washington DC.

Vikram Bodicherla

July 18, 2017
Tweet

More Decks by Vikram Bodicherla

Other Decks in Technology

Transcript

  1. • Be ready to pivot • Spend only as much

    effort as you need for the given iteration
  2. Agenda • What does a good feature definition look like?

    • Practicing good scrum • CD all the way • Culture for winning • Architect for awesomeness
  3. Meet John • Joined last minute because a friend dropped

    out • Knows nothing about football. Probably cares even less. • Drafts Roberto Aguayo in the 2nd round because Tom told him he’s good (screw Tom) • 12% of fantasy football players. Over 60% are in their first season
  4. Building personas • Important attributes of your users • Personas

    define the user at the center of the cluster • Focusing on fewer personas help create focus • Cluster as a means to explanation
  5. Know when you have succeeded • You need to know

    where the goal post is • Vanity metrics – DAUs/Downloads etc. won’t tell you how your feature is doing • Clarity metrics – engagement of the feature – how your feature is doing • http://firstround.com/review/im-sorry-but-those-are-vanity-metrics/
  6. Data, not opinions • Wrong decisions invalidated quickly > no

    decisions • Ward off HiPPO attacks • An experiment should have • a hypothesis • an owner • a deadline
  7. Plan • Get a sense of time, scale and complexity

    • Identify blockers and dependencies • Establish owners • Aids distribution and parallelization of work
  8. Many ways to plan • Waterfall • rigorous planning •

    sequential • Agile • working software • people-centric • iterative, not change-averse • Read the agile manifesto (http://agilemanifesto.org)
  9. What’s a good scrum story? • A part of a

    feature that adds user value • A feature is a collection of stories Ex: add stock to watchlist by tapping on star • User story: Value is perceivable to the user • Engineering story: Value not directly perceivable to the user
  10. What’s a good scrum story? Story: A user should be

    able to add a stock to their watchlist by tapping on the star on a quote page Acceptance criterion • If a stock is not in the watchlist, tapping should add it • If a stock is in the watchlist, tapping should remove it • Add the following analytics event for star tap • Add the necessary Material-design compliant animations
  11. Grooming • Familiarize yourself with the backlog • Ensure stories

    are clear • Point using poker • Ensure >1 sprint’s worth stories are available
  12. Grooming Best practices • User stories with reasonable detail •

    Stories have acceptance criterion • Planning poker to point • More stories, the better • Timebox at 1 hour Anti-patterns • Rushing to story point • Writing stories in the meeting • “I know we don’t have all details, but let’s point it anyways”
  13. Sprint planning Best practices • Tasks < 1 day •

    Have a goal for the sprint • Plan to release at end of sprint • Discuss so product/design/UX can get out of the room first Anti-patterns • Team struggles to identify tasks • Tasks > 1 day • Discussions around what a story means
  14. Standups • Ensure team on track • Share impediments to

    blockers • This is NOT a status updates/knowledge sharing meeting
  15. Standups Best practices • Everyone updates stories prior • Be

    explicit – what’s done, what’s coming up, blockers • Parking lot for long discussions • Agree on defn. of ‘Done’ • Focus of accomplishing everything Anti-patterns • Debate product functionalities • Doing involved demos • Providing a lot of detail • Trying to resolve issues/blockers • Standups > 10 min • “This story is done, except for code review and testing”
  16. Standups Best practices • Everyone updates stories prior • Be

    explicit – what’s done, what’s coming up, blockers • Parking lot for long discussions • Agree on defn. of ‘Done’ • Focus of accomplishing everything Anti-patterns • The big boss needs some clarifications
  17. Scrum • Grooming • Sprint planning • Standup • Demo

    • Retrospective • Wins • Improvments
  18. Demos and retrospective • Demo all stories that are done

    • Celebrate wins • Updates on experiments • What can be better?
  19. Demo and retrospective Best practices • 2 action items for

    what should change • Demo only fully complete stories; no partial credit • Prepare upfront – projector, emulators, building your code Anti-patterns • The “What didn’t go well” list repeats i.e. no follow through • The team obsesses over the negatives • “This is not complete, but let me show what I’ve done”
  20. Demo and retrospective Best practices • 2 action items for

    what should change • Demo only fully complete stories; no partial credit • Prepare upfront – projector, emulators, building your code Anti-patterns • Wasting time setting up for the demo
  21. Continuous Delivery is • Minimizing time between “code complete” →

    “deployable” • deployable ≠ deploy • Based on a solid Continuous Integration (CI) pipeline
  22. Continuous Delivery is • Deploying right away • will get

    us instant feedback • you won’t accumulate debt • Not the best thing for your users • Find your sweet spot
  23. Continuous Delivery • Code is deployed to a pre-production user

    base • Internal users • Playstore alpha/beta testing
  24. Merging code • Reviewing code is very important • You

    don’t want your developer performing tasks that can be outsourced • Find the ‘best’ reviewer – facebook/mention-bot
  25. Merging code • Android test results • Make sure you

    run tests across all your variants! • CodeCov (http://codecov.io) • Ensure code coverage stays up to bar
  26. Merging code • Danger (http://danger.systems) • Automate your code review

    chores • Keep PRs to <500 lines • Good descriptive messages/ticker number for your history
  27. # Ensure a descriptive PR body if (github.pr_body == nil

    || github.pr_body.length < 25) warn(’PR message not descriptive enough (should be >25 chars)') end
  28. Merging code • Appetize (http://appetize.io) • Emulator in an iframe

    on the pull request • Removes the need to compile and install
  29. APK storage and deployment • Use an artifact repository •

    Publish artifacts from either every commit/nightly builds • Bitnami has an AWS image for Artifactory • Automate your playstore updates • fastlane/fastlane provides excellent tools to automate screenshot capture and APK publishing
  30. Team rules of engagement • Not how a result is

    to be achieved, but will indicate what is acceptable and what is not • Setting expectations upfront
  31. Team rules of engagement Own and drive plan Ex: Always

    Communicate the deviations/compromises. Never be in a state where someone learns about something, especially bad, from someone else or by chance
  32. Team rules of engagement Maintain high quality product Ex: Proactively

    address app quality issues. Ex: if there’s an outage, check, triage, announce and work towards resolving it
  33. Team rules of engagement Be a great team player Ex:

    if you are coming in late, let people know and mark it on your calendar; if you need to run an errand, mark it on your calendar
  34. Goals • Build a new search experience to increase engagement

    by 10% • Increase ad revenue by showing more ads by 3%
  35. Goals • Decrease app startup time to 2000 ms •

    Refactor query poller and increase test coverage to 100%
  36. Objectives and Key Results • Objective: Increase ad revenue by

    showing more ads by 3% • Key results • Identify slots for ad placement • Devise ad unit to place at each ad slot • Implement the top ad placements to achieve expected revenue increase • Deploy experience to beta users and compute run rate over 1 month Target 70%
  37. Meeting etiquette • Everyone needs to derive value • It’s

    OK to reject meeting invites • Enter with an agenda and goals, step out with action items • Start and end on time
  38. Code is a liability • Value = user revenue; cost

    = code • Writing, changing and reading code is expensive • Some components stabilize, some don’t • Building on bad code goes into a death spiral Stabilize or kill!
  39. yahoo-finance ~ 5 months angular ~ 4 months kubernetes~ 5

    months httpd ~ 5.4 years git ~ 6 years linux ~ 6.6 years Rapidly evolving components Stable components https://erikbern.com/2016/12/05/the-half-life-of-code.html
  40. Component design considerations • Investing time in stabilizing • Write

    clean, replaceable components • Capture history & knowledge
  41. Architecture Documentation Records (ADRs) • Capture significant architectural decisions and

    the whys • Each significant component has a ADR file in git Ex: adrs/database.MD • Capture the what and the why of the change
  42. Do you really need • Fragments over Activityes? • That

    fancy DI framework? • Annotation with JSON parser? • Optimize what matters • Do not prematurely optimize
  43. Prefer robustness over simplicity public class Application { public void

    onCreate() { WeatherSDK.initialize(true, "Washington DC"); } }
  44. Prefer robustness over simplicity public class Application { public void

    onCreate() { WeatherSDK sdk = new WeatherSDK(); sdk.cacheWeather(true); sdk.trackWeather("Washington DC"); } }
  45. Provide a way to accept shared resources public class Application

    { public void onCreate() { WeatherSDK sdk = new WeatherSDK.Builder() .withOkHttpClient(okHttpClient).build(); sdk.trackWeather("Washington DC"); } }
  46. All AsyncTasks share a single thread pool private static final

    int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4)); private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
  47. Actively report errors and crashes back FlurryAgent.onError("API_Resp", "FetchWeatherCallMissingKey: " +

    key, null); FlurryAgent.onError("GenCrash", "ConvertFtoCFor:" + city, exception); FlurryAgent.onError(”CacheFail", ”LoadFailed:" + key, null);
  48. Have feature flags ready Always have a local feature flag

    buildTypes { debug { buildConfigField ”boolean", "ENABLE_AWESOME_FEATURE_1", "true" } release { buildConfigField ”boolean", "ENABLE_AWESOME_FEATURE_1", "false" } }
  49. Have feature flags ready Always have a local feature flag

    buildTypes { debug { buildConfigField ”boolean", "ENABLE_AWESOME_FEATURE_1", "true" } release { buildConfigField ”boolean", "ENABLE_AWESOME_FEATURE_1", "false" } }
  50. Have feature flags ready And a remote feature flag while

    a feature stabilizes GET /features?versionCode=3.8.0&flavor=android { "ENABLE_AWESOME_FEATURE_1": false }
  51. Have feature flags ready And a remote feature flag while

    a feature stabilizes GET /features?versionCode=3.8.0&flavor=android { "ENABLE_AWESOME_FEATURE_1": false }
  52. Feature flags and experiments Don’t hesitate to duplicate code for

    experiments if (isFeatureEnabled(FeatureManager.Feature.SEARCH_IMPROVEMENTS)) { searchPresenter = new SearchPresenter(); } else { searchPresenter = new OldSearchPresenter(); }
  53. Performance • Memory usage and leaks • Use leakcanary •

    Make a habit of looking at MAT regularly • Buttery smooth performance • Keep an eye on Android vitals • Find The road to 60 FPS by Jason Sendros
  54. Performance - Startup time • Optimize data management • Prefetch

    and preload • Try to avoid data joins for your initial layout • Optimize code • Lots of knowledge on the Internet • Optimize your UX • Optimize your UX to enable faster startup • Consider using nimbledroid
  55. What next? • Give yourself a couple of quarters •

    Capture what you want to change in goals • Any change you want needs mindset shift, so get people buy-in • These are guidelines – don’t aim for 100% If you want to help Yahoo Finance get there, come talk to me!