Sunday, 24 August 2025

Frontend Interview Preparation - Q&A

Q1. How can you define a selector that only works for a screen for more than 700px?

You can use **CSS media queries**:

css
@media screen and (min-width: 700px) {
  selector {
    /* styles */
  }
}


This ensures styles only apply when the screen width is more than 700px. Useful for responsive design.

Q2. What is difference between let, const and var

-In JavaScript, let, const, and var are all used to declare variables, but they differ in scope, reassignment rules, and hoisting behavior

1. var

  • Scope: Function-scoped (or global if declared outside a function) — not block-scoped.
  • Reassignment: Can be reassigned and redeclared.
  • Hoisting: Hoisted to the top of the scope, initialized with undefined.
  • Use today: Rarely used now because it can cause bugs due to lack of block scope.

function testVar() {
    if (true) {
        var x = 10;
    }
    console.log(x); // 10 ✅ (var ignores block scope)
}


2. let

  • Scope: Block-scoped ({}), meaning it’s only accessible inside the block where it’s declared.
  • Reassignment: Can be reassigned but not redeclared in the same scope.
  • Hoisting: Hoisted but not initialized — accessing it before declaration causes a ReferenceError (Temporal Dead Zone).
  • Use: For variables whose values may change.

function testLet() { if (true) { let y = 20; } console.log(y); // ❌ ReferenceError }

3. const

  • Scope: Block-scoped.
  • Reassignment: Cannot be reassigned.
  • Hoisting: Same as let — hoisted but not initialized (Temporal Dead Zone).
  • Use: For variables whose values should not change (constants).
  • Note: For objects/arrays, the reference can’t change, but the contents can be modified.

const z = [1, 2, 3]; z.push(4); // ✅ Allowed (array contents can change) z = [5, 6]; // ❌ TypeError (reference change not allowed)


Q. What is hoisting?

Hoisting in JavaScript means that variable and function declarations are moved to the top of their scope (global or function) during the compilation phase, before the code is executed.

But there’s a catch — only declarations are hoisted, not initializations.

1️⃣ Hoisting with var

  • var is hoisted and initialized with undefined.
  • That’s why you can use a var variable before its declaration without getting an error (though it’s bad practice).

console.log(a); // undefined ✅ var a = 10; // Declaration is hoisted, initialization happens later

2️⃣ Hoisting with let and const

  • These are hoisted but not initialized.
  • They stay in the Temporal Dead Zone (TDZ) from the start of the scope until their declaration line.
  • Accessing them before declaration throws a ReferenceError.

console.log(b); // ❌ ReferenceError let b = 20;

3️⃣ Hoisting with Functions

  • Function declarations are fully hoisted — both their name and body.
  • You can call them before their definition.

sayHello(); // ✅ Works function sayHello() { console.log("Hello!"); }
  • Function expressions (assigned to var, let, const) behave like variables — only the variable declaration is hoisted, not the function value.

sayHi(); // ❌ TypeError: sayHi is not a function var sayHi = function() { console.log("Hi!"); };


Q3. How could you add an element to the end and beginning of the array?

- Add at end: `arr.push(element)`
- Add at beginning: `arr.unshift(element)`

Example:

let arr = [2,3];
arr.push(4); // [2,3,4]
arr.unshift(1); // [1,2,3,4]

Q4. How to validate a type of a variable in JS?

Use `typeof` operator:

typeof 123; // 'number'
typeof 'abc'; // 'string'
typeof true; // 'boolean'


Q5. Few examples of typeof in TypeScript?

TypeScript enhances `typeof` for type queries.

let msg = "Hello";
let len: typeof msg; // string

function fn(x: number) { return x; }
let y: ReturnType<typeof fn>; // number

Q6. How to define a parameter as an Option?

In TypeScript, mark it as optional using `?`:

function greet(name?: string) {
  console.log(name ? `Hello, ${name}` : "Hello");
}


Q7. How to define the constant inside of a class?

Use `static readonly`:

class MyClass {
  static readonly PI = 3.14;
}
console.log(MyClass.PI);


Q8. Few examples of main building blocks in Angular

- **Modules**: Organize code.
- **Components**: UI building blocks.
- **Templates**: HTML with Angular syntax.
- **Services**: Business logic.
- **Directives**: Modify DOM behavior.
- **Dependency Injection**: Provides services.

Q9. What is the difference between @Input and @Output, and where should they be used?

- @Input: Pass data **from parent to child**.
- @Output: Send events/data **from child to parent**.

Example:

// child.component.ts
@Input() title: string;
@Output() clicked = new EventEmitter<string>();

Q10. Promises Vs Observables

- **Promise**: Single value, eager, no cancellation.
- **Observable**: Multiple values over time, lazy, supports cancellation.

Example: Use Promise for one-time HTTP call, Observable for streaming data (like WebSockets).

Q11. Whats @ViewChild

Decorator to access child components, directives, or DOM elements directly.

@ViewChild('inputRef') input: ElementRef;
ngAfterViewInit() { this.input.nativeElement.focus(); }

Q12. What is HostListener

@HostListener listens to events on the host element.


@Directive({selector: '[hoverHighlight]'})
class HoverDirective {
  @HostListener('mouseenter') onEnter() { ... }
}

Q13. Subject Vs BehaviourSubject

- **Subject**: Emits values only to subscribers after subscription.
- **BehaviorSubject**: Stores last value and immediately sends it to new subscribers.

Use BehaviorSubject when you want subscribers to always have the latest state.

Q14. JS synchronous or async?

JS is **single-threaded synchronous** but uses **event loop** for async operations.
- Synchronous: Code runs line by line.
- Asynchronous: `setTimeout`, Promises handled via event loop.

Q15. Lifecycle hooks in Angular

- ngOnInit: Init logic.
- ngOnChanges: When @Input changes.
- ngAfterViewInit: After view init.
- ngOnDestroy: Cleanup.


Helps manage component lifecycle.

Q16. console.log(1=='1') and console.log(1==='1')

- '==': true (because it coerces types).
- '===`': false (strict comparison).

Q17. So (4 == '5') will be false?

Yes, because type coercion converts `'5'` to number, and `4 != 5`. So result is **false**.

Q18. Anonymous functions

Functions without a name. Often used in callbacks.

setTimeout(function(){ console.log('Hi'); }, 1000);

Q19. Calling Nested function func()()

If a function returns another function, you can call it immediately:

function outer() {
  return function inner() { console.log('Hi'); }
}
outer()(); // Hi

Q20. Engine Execution: setTimeout and console.log

`console.log` executes first (synchronous).
`setTimeout` goes to Web API, then callback queue, then event loop executes it **after main stack is empty**.

Q21. Global Context in JS

The default execution context: In browsers it's the **window object**, in Node.js it's **global**.

Q22. GET and POST Security aspects

- **GET**: Params visible in URL (less secure).
- **POST**: Params in body (more secure).

Never send password in GET; risk of logging, bookmarking, caching.

Q23. Real time example where you can use ViewChilds

Example: Auto-focusing an input field after loading a component.

@ViewChild('searchBox') search: ElementRef;
ngAfterViewInit(){ this.search.nativeElement.focus(); }


Q24. Parent/Child Component with @Input and @Output

Parent passes data to child via `@Input`, child emits events to parent via `@Output`.


// parent.html
<child [title]="parentTitle" (notify)="onNotify($event)"></child>


This enables component communication.

Q26. How to expose REST web services to frontend in Spring

🔹 1. Create a REST Controller in Spring Boot

In Spring, you expose REST endpoints using @RestController and @RequestMapping (or @GetMapping, @PostMapping, etc.).

import org.springframework.web.bind.annotation.*;
import java.util.*;

@RestController
@RequestMapping("/api/users")

public class UserController {

    // Example GET API
    @GetMapping
    public List<String> getAllUsers() {
        return Arrays.asList("Aamir", "John", "Maria");
    }

    // Example POST API
   @PostMapping
    public String createUser(@RequestBody String userName) {
        return "User " + userName + " created successfully!";
    }
}

👉 This exposes endpoints:

  • GET http://localhost:8080/api/users
  • POST http://localhost:8080/api/users

🔹 2. CORS (Cross-Origin Resource Sharing)

Frontend (Angular/React) usually runs on a different port (e.g., Angular: http://localhost:4200).
To allow frontend calls, enable CORS:

Option A: At Controller Level

@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "http://localhost:4200")  // Allow Angular app

public class UserController {
    // ...
}

Option B: Global Configuration

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

 @Configuration
public class WebConfig {

    
@Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {

            
@Override     
            
public void addCorsMappings(CorsRegistry registry) {
           registry.addMapping("/api/**")
                        .allowedOrigins("http://localhost:4200")
                        .allowedMethods("GET", "POST", "PUT", "DELETE");
            }
        };
    }
}


🔹 3. Consume API from Frontend

Angular Example (using HttpClient)

// user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

 @Injectable({
 providedIn: 'root'
})

export class UserService {
  private apiUrl = 'http://localhost:8080/api/users';

  constructor(private http: HttpClient) {}

  getUsers(): Observable<string[]> {
   return this.http.get<string[]>(this.apiUrl);
  }

   addUser(userName: string): Observable<string> {
   return this.http.post<string>(this.apiUrl, userName);
  }
}


🔹 4. Security Aspect

  • If using Spring Security, you need to configure allowed endpoints for frontend.
  • Example (permit /api/** without auth):

http.csrf().disable()
  .authorizeRequests()
    .antMatchers("/api/**").permitAll()
    .anyRequest().authenticated();


 Summary (Interview Answer):
To expose REST web services to frontend in Spring Boot:

  1. Create endpoints using @RestController.
  2. Handle cross-origin requests with @CrossOrigin or WebMvcConfigurer.
  3. Frontend calls these endpoints using HTTP clients (e.g., Angular HttpClient, React fetch).
  4. If Spring Security is enabled, configure access rules for APIs.

Q27. URL Shortening using TinyURL

You generate a unique key for a long URL and store mapping in DB. When user hits tiny URL, backend redirects to original.

Can use hashing + base62 encoding.

Q28. AuthGuard & Interceptor in Angular

- **AuthGuard**: Protects routes (checks if user logged in).
- **Interceptor**: Intercepts HTTP requests, adds JWT, handles errors.

Together they ensure security in Angular apps.

 

No comments:

Post a Comment