1/139
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced |
---|
No study sessions yet.
Spring Security uses a filter chain to intercept requests and apply authentication and authorization logic. When using JWT, I typically implement a custom OncePerRequestFilter that intercepts each request, extracts the token from the Authorization header, validates it using a JWT library (like jjwt), and then sets the authenticated user in the SecurityContextHolder. This allows downstream components to recognize the authenticated principal without session state. I also configure secured routes via HttpSecurity using antMatchers.
All three are Spring-managed beans, but they communicate intent and layer responsibility.
@Component is a generic stereotype for any bean.
@Service indicates a service layer class that holds business logic.
@Repository marks persistence-layer classes and provides exception translation for database operations.
These annotations help improve clarity and enable auto-detection in component scanning.
I use application-{profile}.yml files for environment-specific settings like dev, test, and prod. Each profile contains different DB URLs, credentials, logging levels, etc. I activate a profile using SPRINGPROFILESACTIVE in the environment or as a command-line argument. I also annotate beans with @Profile when I want to register them only under specific conditions.
Spring Boot uses @EnableAutoConfiguration and scans for spring.factories or META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports entries. It conditionally loads beans based on classpath presence or property values, using annotations like @ConditionalOnClass, @ConditionalOnProperty, etc. This enables opinionated defaults but still allows overriding.
I use @ControllerAdvice to handle exceptions globally across all controllers. Inside it, I define methods with @ExceptionHandler for specific exception types, returning structured ResponseEntity objects. For example, I might return a 404 for EntityNotFoundException with a JSON payload containing the timestamp, message, and status.
I created custom service accounts with minimal IAM roles, such as Cloud Run Invoker or Cloud SQL Client, and assigned them to my Cloud Run service. I avoided default accounts to follow the principle of least privilege. I also ensured that authentication between services used Workload Identity or signed tokens.
Cloud Run is fully serverless and designed for stateless containerized apps. It auto-scales down to zero and charges per request. App Engine is also serverless but tied to specific runtimes and more opinionated. GKE gives full control of Kubernetes clusters but requires managing pods, deployments, and nodes manually. I chose Cloud Run for its simplicity and fast CI/CD integration.
I use a multi-stage Dockerfile. The first stage builds the app using Maven or Gradle in an OpenJDK image. The second stage uses a slim JDK or even a JRE base image and copies the built .jar. This reduces the image size and speeds up deployments. I also specify HEALTHCHECK instructions and include .dockerignore to keep builds clean.
Cloud Run will restart failed containers automatically, but since it's stateless, crash loops usually signal a config or code issue. I use Cloud Logging and Error Reporting to detect failures, and I set up alerts in Google Cloud Monitoring to notify when a service exceeds error thresholds or request latency.
I store shared data like bills or user in the Redux store and create memoized selectors for read access. I use slices to separate logic, and createAsyncThunk for API interactions. Redux helps me avoid unnecessary re-fetching across routes by centralizing data and updating the UI reactively based on global state.
Redux Thunks are middleware that lets you write async logic inside action creators using promises. NgRx Effects, on the other hand, use RxJS observables to react to dispatched actions and perform side effects (like HTTP requests). Effects are more declarative and powerful for handling streams of actions, retries, and complex flow.
I use optimistic updates when appropriate — updating the Redux state immediately, and then reverting if the API call fails. Otherwise, I refetch or invalidate cache entries using thunks or RTK Query. After deletes or adds, I ensure components relying on that data are updated through selectors.
Each major feature gets its own module, route config, and NgRx store slice. I apply lazy loading via Angular’s router to reduce initial bundle size. Shared logic like services and pipes are put in a shared module. This setup allows teams to work independently on features and improves testability.
Selectors are pure functions that access and transform state from the store. They are memoized, so they prevent unnecessary re-renders when the output doesn’t change. I use them to encapsulate derived data logic and keep components clean and declarative.
In unit tests, I mock external dependencies like API services, repositories, or components using jest.mock or @MockBean. In integration tests, I use real components but fake external systems. For backend tests, I might use an in-memory database like H2 or Testcontainers to simulate real DB behavior.
I mock the fetch call using jest.fn() or jest-fetch-mock, render the component with React Testing Library, and use waitFor or findBy queries to assert on async behavior. I test both loading and error states to ensure full coverage.
A big challenge was managing state between tests — I used @DirtiesContext sparingly and set up data using @Sql or a test factory. Dependency injection setup could be tricky with multiple profiles. I also had to carefully isolate test databases using embedded MySQL or test containers.
I used: Singleton for global configuration (e.g., tokens, base URLs),
Factory for creating service instances or API clients, Adapter to translate backend models into frontend-usable formats. These patterns improved reusability and decoupled the SDK from implementation details.
RabbitMQ is great for async, decoupled communication. It handles routing via exchanges and supports durability with message persistence. I chose it over Kafka for simpler routing and easier setup in smaller systems. Compared to REST, it avoids tight coupling and enables retries or delayed processing.
I followed SOLID principles, limited functions to a single responsibility, and used meaningful names. I practiced TDD for critical services, paired often during refactors, and automated formatting and linting in CI. I also advocated for short iterations and feedback cycles to keep the codebase flexible.
I’d say: An interface is like a job contract — it tells you what methods must exist but not how they work. An abstract class is like a partially built house — it gives you a foundation and some rooms, but you have to finish it. Interfaces are for capability; abstract classes provide structure and shared logic.
In React: overusing state instead of props, not using keys in lists, or misusing useEffect.
In Angular: skipping the async pipe, putting too much logic in templates, or forgetting to unsubscribe from observables. I helped them learn to separate concerns and adopt consistent patterns.
What is JSX and how does it work under the hood?
(JSX is syntactic sugar that compiles to React.createElement.)
What are functional components vs class components?
(Functional components use hooks and are the modern standard.)
How does the virtual DOM work in React?
(It compares a diff of the current and previous tree before updating the actual DOM.)
What is a key prop and why is it important?
(Keys help React identify which elements changed, preventing unnecessary re-renders.)
What are controlled vs uncontrolled components?
(Controlled: state lives in React. Uncontrolled: state lives in the DOM.)
How does useState work and why can’t you call it conditionally?
(Hooks rely on a consistent call order. Conditional calls break that.)
What does useEffect do and how is the dependency array used?
(It runs side effects — the array determines when it re-runs.)
What is the difference between useEffect and useLayoutEffect?
(useLayoutEffect fires synchronously after DOM mutations, before paint.)
When and why would you use useMemo or useCallback?
(Memoize values/functions to avoid expensive recalculations or re-renders.)
What problem does useRef solve?
(Accessing DOM nodes, storing mutable values without triggering re-renders.)
How do props differ from state?
(Props are passed from parent; state is managed locally.)
What is prop drilling and how can you solve it?
(Passing props through many layers; solve with context or global state.)
What is lifting state up?
(Moving shared state to a common parent component.)
What happens when you update state in React?
(Triggers a render cycle; React compares new virtual DOM and updates real DOM.)
Why is state updated asynchronously?
(To batch updates for performance and avoid unnecessary renders.)
What are the phases of a React component's lifecycle?
(Mounting, updating, unmounting — hooks now handle lifecycle.)
What happens during the mounting phase?
(Initial render → useEffect runs after paint.)
How do you clean up in useEffect?
(Return a function from the effect: return () => { … }.)
What causes unnecessary re-renders in React?
(New props/state, non-memoized functions, context changes.)
How can you optimize performance in large lists?
(Use React.memo, useMemo, virtualization tools like react-window.)
What is reconciliation and how does React use it?
(React compares virtual DOM trees to determine minimal changes.)
How does React handle event delegation?
(It uses a synthetic event system that delegates at the root.)
How do you test a component that fetches data?
(Mock fetch, use jest, and assert async results with React Testing Library.)
What is the role of data-testid and how does RTL encourage better queries?
(It’s fallback; RTL prefers queries that simulate real user interaction.)
How does react-router-dom work?
(It maps URL paths to React components using client-side routing.)
What’s the difference between link and a ?
( avoids full page reloads and uses history API.)
How do you handle 404s and nested routes?
(Use Route path="*" and Outlet for nested routes.)
What are the benefits of using fetch vs axios?
(fetch is built-in but lacks features like interceptors; axios is more feature-rich.)
What is the Context API and when would you use it?
(For lightweight global state — theme, auth, etc.)
When should you use Redux vs local state or Context?
(Redux: large-scale apps, complex data flows, need for middleware or persistence.)
What is JSX and how does it work under the hood?
JSX is a syntax extension that looks like HTML but is actually JavaScript. Under the hood, it gets compiled to React.createElement() calls, which return objects that describe the UI (virtual DOM nodes). These are later used by React to render and update the actual DOM efficiently.
What are functional components vs class components?
Class components use ES6 classes and lifecycle methods (componentDidMount, etc.), while functional components are just functions that return JSX. With React 16.8+, functional components became the standard because hooks allowed them to manage state and side effects, making them simpler and more modular.
How does the virtual DOM work in React?
React creates a lightweight in-memory tree (virtual DOM) that mirrors the real DOM. When state or props change, React re-renders the virtual DOM, compares it to the previous version (diffing), and calculates the minimal set of changes needed to update the real DOM efficiently.
What is a key prop and why is it important?
key is a special prop used when rendering lists. It helps React identify which items have changed, been added, or removed. Without unique keys, React might incorrectly reuse components, leading to bugs and performance issues during reconciliation.
What are controlled vs uncontrolled components?
Controlled components have form data managed by React state (value={input}), giving full control. Uncontrolled components use the DOM as the source of truth via ref. Controlled is preferred when validation or interaction with other state is required.
How does useState work and why can’t you call it conditionally?
useState adds state to functional components. Hooks must be called in the same order every render. Calling it conditionally breaks that order, and React can’t map state updates to the right hook call, leading to bugs.
What does useEffect do and how is the dependency array used?
useEffect lets you perform side effects (like fetches, subscriptions). It runs after render. The dependency array determines when it should re-run — when any listed value changes. An empty array means it runs once on mount.
What is the difference between useEffect and useLayoutEffect?
Both run after render, but useLayoutEffect runs synchronously before the browser paints. It blocks visual updates, which can be useful when measuring DOM size or performing layout reads/writes before the user sees anything.
When and why would you use useMemo or useCallback?
useMemo memoizes the result of a computation (like filtering a large list). useCallback memoizes a function so it doesn’t get re-created unless its dependencies change. This helps prevent unnecessary re-renders, especially in child components.
What problem does useRef solve?
useRef gives you a persistent value across renders that doesn't trigger re-renders when changed. It's useful for accessing DOM elements (ref={myRef}) or storing mutable state (like tracking previous props or timers).
How do props differ from state?
Props are read-only and passed from parent to child. State is internal and managed by the component itself. Props are used for configuration; state is used for data that changes over time in response to user actions or data flow.
What is prop drilling and how can you solve it?
Prop drilling is passing data through many intermediate components that don't need it, just to get it to a deeply nested child. You can solve this with the Context API or state management tools like Redux or Zustand.
What is lifting state up?
Lifting state means moving state to the nearest common ancestor when two or more components need access to it. This promotes a single source of truth and keeps components in sync by sharing state via props.
What happens when you update state in React?
State updates are batched and asynchronous. When you call setState or setValue, React schedules a re-render and performs a diff between the new and previous virtual DOM to update the UI efficiently.
Why is state updated asynchronously?
React batches state updates to optimize performance. Synchronous updates would cause frequent, unnecessary renders. Asynchronous updates let React group updates and render only once, reducing work.
What are the phases of a React component's lifecycle?
There are three phases:Mounting (component is inserted) Updating (state/props change) Unmounting (component is removed) Hooks like useEffect unify lifecycle behavior in functional components.
What happens during the mounting phase?
The component is created, state and props are initialized, and it renders for the first time. useEffect(() => { … }, []) runs after the DOM is painted.
How do you clean up in useEffect?
Return a cleanup function inside the effect:
useEffect(() => {
What causes unnecessary re-renders in React?
New props (even if same value), inline functions, or global context changes can trigger re-renders. React compares references, so even function identity matters.
How can you optimize performance in large lists?
Use windowing (e.g. react-window), React.memo to prevent unnecessary re-renders, and pagination. Avoid re-calculating derived data during render.
What is reconciliation and how does React use it?
Reconciliation is React’s process of comparing the new virtual DOM with the old one to calculate the smallest set of changes (diffing). It uses keys and tree structure to do this efficiently.
How does React handle event delegation?
React uses a synthetic event system. Instead of attaching listeners to every element, it attaches one listener per event type to the root, then dispatches events through a virtual hierarchy.
How do you test a component that fetches data?
Mock the fetch call (using jest.mock or msw), render the component with RTL, and use findBy* or waitFor to assert after the async call completes. Also test loading and error states.
What is the role of data-testid and how does RTL encourage better queries?
data-testid is a last resort for querying. RTL encourages queries by role, label, placeholder, etc., to better reflect real user interactions and improve test resilience.
How does react-router-dom work?
It uses client-side routing with the History API. matches paths to components. changes the path without a page reload. It allows nested routes and dynamic segments.
uses JavaScript to update the URL and avoid full page reloads. reloads the page. React Router uses for smooth SPA navigation.
How do you handle 404s and nested routes?
Use a catch-all route: } /> for 404s. Use in parent routes for nested routing where children get injected.
What are the benefits of using fetch vs axios?
fetch is native and simple but lacks interceptors and request cancellation. axios supports interceptors, auto JSON parsing, and request timeouts, making it better for complex needs.
What is the Context API and when would you use it?
Context lets you pass global state like auth or theme without prop drilling. It's ideal for low-frequency updates. For high-frequency updates (like form fields), use local state or Redux.
When should you use Redux vs local state or Context?
Use Redux when your app has:Complex state logic Global shared state (like cart, user data) Middleware needs (logging, async thunks) Local state is best for isolated concerns; Context is great for light global values.
What is the difference between == and .equals() in Java?
(Reference comparison vs logical equality.)
Explain the four pillars of OOP in Java.
(Encapsulation, Abstraction, Inheritance, Polymorphism.)
What is method overloading vs method overriding?
(Overloading = same method name, different signatures; Overriding = redefinition in subclass.)
What is the difference between abstract class and interface?
(Abstract classes can have state and constructors; interfaces are contracts with default/static methods.)
What is the purpose of the final, finally, and finalize() keywords?
(final: constant, finally: always executes after try/catch, finalize(): legacy garbage collection hook.)
What is the Java heap vs stack?
(Heap = objects and dynamic memory; Stack = method calls and local variables.)The Java heap is where objects and dynamic memory allocation occurs, while the stack stores method calls and local variables in a last-in, first-out order.
How does garbage collection work in Java?
Definition: The JVM automatically reclaims memory for objects that are no longer reachable. It uses algorithms to determine which objects are safe to collect, freeing up memory. Key aspects include:
Mark and Sweep: Identifies reachable objects (marking) and reclaims the rest (sweeping).
Generational GC: Divides the heap into generations (young, old) and collects the young generation more frequently.
Garbage Collectors:
Serial GC: Single-threaded, for small applications.
Parallel GC: Uses multiple threads to speed up collection.
CMS (Concurrent Mark Sweep): Minimizes pause times by performing most of the work concurrently.
G1 (Garbage-First): Balances throughput and pause times, dividing the heap into regions.
ZGC (Z Garbage Collector): Aims for very low latency, suitable for large heaps.
Developers don’t manually free memory but should avoid creating memory leaks by holding unnecessary references.
what is garbage collection?
Garbage collection in Java refers to the process where the Java Virtual Machine (JVM) automatically reclaims memory by identifying and collecting objects that are no longer reachable. Key algorithms include G1, CMS, and Serial GC, each with different approaches to optimizing memory management.
What are memory leaks in Java and how do they happen?
Memory leaks in Java occur when objects are no longer used but remain referenced, preventing the garbage collector from reclaiming their memory. This can happen due to static references, unintentional object retention in collections, or improper listeners.
(Holding references longer than needed, especially in static structures or caches.)
Memory leaks occur when objects are not garbage collected due to lingering references, typically in static data structures or caches, leading to increased memory usage.
What is the difference between strong, weak, and soft references?
Strong references prevent garbage collection, weak references allow the garbage collector to reclaim memory when necessary, and soft references are cleared only when memory is low.
(Strong = default, GC won’t remove; Weak = GC clears when memory is low; Soft = more flexible caching.)
How does the volatile keyword work?
The volatile keyword in Java is used to indicate that a variable's value will be modified by different threads, ensuring that all threads see the most recent value and preventing caching of the variable in registers or CPU caches.
What is the difference between ArrayList and LinkedList?
(ArrayList = fast random access; LinkedList = faster inserts/removes at ends.)
How does a HashMap work internally?
(Uses a hash function to index a bucket array; handles collisions via chaining.)
What is the difference between HashMap, TreeMap, and LinkedHashMap?
(HashMap = unordered, TreeMap = sorted by key, LinkedHashMap = insertion order.)
What are the differences between Set, List, and Map?
(Set: no duplicates, List: ordered, Map: key-value pairs.)
What is the difference between synchronizedList and CopyOnWriteArrayList?
(synchronizedList: locks on access; CopyOnWrite: duplicates on write, better for reads.)
What is the difference between checked and unchecked exceptions?
(Checked = must handle or declare; Unchecked = runtime, may be skipped.)