21. Design the frontend for a bike-sharing application.
Design the reported bike-sharing frontend. The browser should help a rider discover stations, inspect current bike and dock availability, select a station, and understand an active trip. Discuss map and list views, geolocation permission, freshness of availability data, route and state ownership, weak-network behavior, accessible alternatives to the map, and how the UI prevents duplicate rental actions.
At a high level, the frontend helps riders find stations, check live bike and dock availability, select a station, start or end a rental, and follow an active trip. I would use a React single-page application with client-side rendering and route-based code splitting. URL state owns routes and filters, while shared client state owns auth, stations, trip, and UI data. A service worker and browser cache help on weak networks. The main trade-off is more browser complexity for faster navigation and better resilience.
The goal is to give riders a fast and reliable bike-sharing experience on mobile and desktop. A rider should discover nearby stations, see current bikes and docks, open a station, start or end a rental, and understand an active trip. The hard part is keeping availability fresh while mobile networks may be slow or unstable. I would organize the frontend around delivery, routes and components, state ownership, remote data, weak-network behavior, and accessible interaction.
- How fresh must bike and dock availability be?
- Should the app remain useful when the rider is offline?
- Which mobile and desktop browsers must we support?
- Must every map action also be available through the station list?
- Does the Bike-sharing Backend API support idempotent start and end rental requests?
- How many languages must the frontend support?
The rider downloads the frontend from the CDN. It serves the static site, JavaScript and CSS bundles, images, fonts, and map tiles. Long cache times can be used for versioned static files.
The browser runs a React single-page application using client-side rendering. This works well because the experience is highly interactive. Code splitting means each route loads only the JavaScript it needs.
The App Shell contains the Header, Main area, and mobile Bottom Nav. It gives all routes one responsive layout.
The main routes are /map, /station/:id, /trip, and /profile. The Map View helps riders explore nearby stations. The Station Detail route shows live bikes and docks and provides rent or return actions. The Active Trip route shows the trip timer and route.
Important reusable components include Map, StationList, StationCard, RentButton, and TripBanner. The StationList is also the accessible alternative to the map. A rider can use it with a keyboard or screen reader without depending on map interaction.
URL state owns the current route and filters. This makes navigation and filtered views shareable and predictable.
Shared client state, such as Context or Redux, owns auth, stations, trip information, and shared UI data. Local UI state owns short-lived values such as dialogs, forms, and modal state. Persisted state can use browser storage and cached data for useful information that should survive reloads.
Geolocation is a browser capability. The app asks for permission before using the rider's location to find nearby stations.
The browser sends HTTPS and JSON requests to the Bike-sharing Backend API. That external service provides stations, availability, rental actions, and trip status. The Identity Provider handles sign-in through OAuth or OIDC. The Maps Provider supplies map tiles, directions, and geocoding.
Availability can change quickly. The frontend can use polling or a WebSocket for fresh bike and dock counts. Shared Stations State then updates the Map View, StationList, and Station Detail from the same data.
The UI has clear loading, empty, partial or stale, error, and offline states. Stale means the displayed information may be older than the latest remote result. The app should show this state instead of presenting old availability as current.
The browser cache speeds up assets and useful responses. The service worker supports cached application files and offline behavior. This helps the shell remain usable when connectivity is poor.
To prevent duplicate rentals, the RentButton becomes disabled after the first click while the request is pending. The request also carries an idempotency key so repeated submissions can represent the same operation. The backend remains responsible for enforcing the real rental rule.
The layout adapts to mobile and desktop screens. The frontend uses semantic HTML, ARIA where needed, keyboard support, and screen-reader friendly controls. Localization, or i18n, lets the same interface support different languages.
The main trade-off is complexity. Shared state, live updates, browser caching, and a service worker make the client harder to build and test. The benefit is faster navigation and a more dependable experience on real mobile networks.
The benefit of a client-rendered single-page app is fast navigation after the first load. The downside is that the browser must download and run more JavaScript. Code splitting reduces this by loading JavaScript only for the current route. Live availability gives riders better information, but frequent polling or a WebSocket uses more network and battery. Browser caching and a service worker help on weak networks, but cached information can become stale. Shared state keeps station and trip data consistent across pages, but too much shared state makes the frontend harder to maintain.
The interviewer wants to see whether the candidate can turn a real rider journey into a clear frontend design. They are testing judgment about routes, component boundaries, state ownership, fresh remote data, weak networks, accessibility, and duplicate actions. They also want to see whether the candidate understands the browser's responsibilities and keeps trusted rental and authorization rules inside the remote systems.



