Google News
logo
Full Stack Developer Interview Questions
A Full-stack web developers are skilled programmers who can work with both the front-end and back end (client side and server side) of a website and applications.
 
They are responsible for developing and designing front/ back ends web architecture, server-side applications, design databases, server-side applications, working alongside graphic designers to create web design elements, developing APIs and RESTful services, testing, and debugging software, ensuring cross-platform compatibility and optimization, etc. In addition to mastering HTML and CSS, he/she also knows how to :
 
* Program a browser (like using JavaScript, jQuery, Angular, or Vue)
* Program a server (like using PHP, ASP, Python, or Node)
* Program a database (like using SQL, SQLite, or MongoDB).
Full-stack developer must introduce with the following:
 
Programming Languages : A full-stack developer must have proficient in more than one programming language like Java, Python, Ruby, C++, etc. One must familiar with different ways to structure design, implement and test the project based on the programming language.
 
Front End : One must familiar with the front-end technologies like HTML5CSS3, BootStrap, AngularJS, VueJS, ReactJS, JavaScriptAngular, etc. The understanding of third-party libraries like jQuery, Ajax, SASS, adds more advantages.
 
Frameworks : Proficiency in words that are accompanied by development frameworks like Spring, Spring Boot, MyBatis, Django, PHP, Hibernate, js, yin, and more.
 
Databases : One must be familiar with at least one database. If you are familiar with MySQL, Oracle, SQLite, Postgres, MongoDB, Cassandra, Apache storm, Sphinx, etc,.
 
Design Ability :The knowledge of prototype design like UI and UX design is also necessary.
 
Server : Experience with Apache or NGINX would be beneficial. Good knowledge of Linux helps enormously when administering servers.
Some of the popular tools used by full-stack developers to make development more accessible and efficient are :
 
* Backbone
* Visual Studio Code
* GitHub
* CodePen
* TypeScript
* WebStorm
* Slack
* Electron
 
As the name suggests, Pair Programming is where two programmers share a single workstation. Formally, one programmer at the keyboard called the "driver" writes the code. The other programmer is the "navigator" views each line of the code written, spell check, and proofread it. Also, programmers will swap their roles every few minutes and vice-versa.
CORS refers to Cross-Origin Resource Sharing. It's a browser mechanism that allows web pages in one domain to have controlled access to resources in other domains (cross-domain requests). This allows scripts that are run on a browser client to interact with and access resources from other origins. In doing so, it extends and provides greater flexibility to the SOP (Same-Origin Policy). Same-origin policies restrict the ability of a website to access resources outside of its source domain. 
 
For example, a JavaScript app that wants to make a call to an API (Application Programming Interface) that runs on another domain will be blocked due to the SOP. A CORS policy was implemented to circumvent restrictions caused by same-origin policies.
 
In addition, if a website's CORS policy is not configured properly, it may be vulnerable to cross-domain attacks. This means that it cannot stop cross-origin attacks like  CSRF (Cross-Site Request Forgery).
Inversion of Control (IoC) is a broad term used by software developers for defining a pattern that is used for decoupling components and layers in the system. It is mostly used in the context of object-oriented programming. Control of objects or portions of a program is transferred to a framework or container with the help of Inversion of Control. It can be achieved using various mechanisms such as service locator pattern, strategy design pattern, factory pattern, and dependency injection.
MVC : MVC stands for Model View Controller. It is an architectural pattern that is used to develop Java Enterprise Applications. It splits an application into three logical components i.e. Model, View, and Controller. It separates the business-specific logic (Model component) from the presentation layer (View component) from each other.
 
The model components contain data and logic related to it. The View component is responsible for displaying model objects inside the user interface. The Controller receives the input and calls model objects based on handler mapping. It also passes model objects to views in order to display output inside the view layer.

MVC
 
MVP : MVP stands for Model View Presenter. It is derived from the MVC architectural pattern. It adds an extra layer (known as indirection) to the architectural pattern that splits the View and Controller into View and Presenter. The role of Controller is replaced with a Presenter. It exists at the same level as View in MVC. It contains UI business logic for the View. The invocations received from the View directly sends to the Presenter. It maintains the action (events) between View and Model. The Presenter does not directly communicate with the View. It communicates through an interface.
MVP

The major difference between MVC and MVP architectural pattern is that in MVC architectural pattern Controller does not pass the data from the Model to the View. It only notifies the View to get the data from the Model itself.
 
While in MVP architectural pattern the View and Model layers are connected with each other. The presenter itself receives the data from the Model and sends it to the View to show.
 
Another difference is that MVC is often used in web-frameworks while MVP is used in app development.

MVC and MVP
We can use the following ways to optimize the scalability and efficiency of a website :
 
* Reducing DNS lookup
* Avoiding URL redirects
* Avoiding duplicate codes
* Avoiding unnecessary images
* Leveraging browser caching
* Deferring parsing of JavaScript
* Avoiding inline JavaScript and CSS
* Using srcset for responsive images
* Placing all assets on a cookie-free domain, preferably using a CDN.
Callback Hell, or Pyramid of Doom, is a common anti-pattern seen in asynchronous programming code (multiple functions running at the same time). This slang term describes a large number of nested "if" statements or functions. In simple terms, Callback hell is a situation where you have multiple asynchronous functions. Those functions depend on one another, so it could get quite messy with so many callback functions nested in so many layers. The use of callback functions leaves you with code that is difficult to read and maintain, and looks like a pyramid as shown below:
 
This also makes it more difficult to identify the flow of the application, which is the main obstacle to debugging, which is the reason for the famous name of this problem : Callback Hell.
Long polling is defined as a web application development technique used to push information/data from servers to clients as quickly as possible. When a request is made from the client to the server, long-polling maintains the connection between the two.

This connection is maintained until the information is ready to be sent from the server to the client.  Once a server receives a request from a client, the connection does not close immediately; the connection is only closed once the server has sent the data back to the client or when a timeout threshold has been reached (connection timeout).

Long Polling
The Dependency Injection (DI) pattern is a design pattern for implementing the Inversion of Control (IoC). Dependent objects can be created outside of classes and made available to classes in different ways. Three types of classes are involved in Dependency Injection as follows :
 
Client Class : It depends on the service class.

Service Class : It provides service to the client class.

Injector Class : It injects service class objects into the client class.
When recruiters ask this question, they’re looking to find out if you have the discipline to debug code. You can demonstrate this by talking about a specific project which started off with erroneous code or malfunctioning features. Then, explain how you identified the code and debugged it.
Let’s first look at an example of each :
// ES5 Function Constructor
function Person(name) {
  this.name = name;
}

// ES6 Class
class Person {
  constructor(name) {
    this.name = name;
  }
}
For simple constructors, they look pretty similar.
 
The main difference in the constructor is observed when the effect of inheritance comes into the play. If we want to create a Student class that subclasses Person and add a studentId field, this is what we have to do in addition to the above.
// ES5 Function Constructor
function Student(name, studentId) {
  // Call constructor of superclass to initialize superclass-derived members.
  Person.call(this, name);

  // Initialize subclass's own members.
  this.studentId = studentId;
}

Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// ES6 Class
class Student extends Person {
  constructor(name, studentId) {
    super(name);
    this.studentId = studentId;
  }
}
It’s much more verbose to use inheritance in ES5 and the ES6 version, here it is easier to understand and remember.
Continuous Integration is the process of implementation of codes that are specially designed & automated for testing. During the time of production, it helps the developers to apply the codes simply. Web developers prefer this process for the integration of codes many times a day. Continuous Integration helps in detecting errors quickly and locating them more easily.
If several objects are tied together in one-to-many relationships, the observer pattern is used. Every time one object is modified, then all of its dependent objects are automatically notified and updated. It falls under the behavioural pattern category. It describes the coupling between the objects and the observer and provides support for broadcast-type communication. The object that observes the state of another object is known as the observer, and the object that is being observed is known as the subject.
S.N. Basis of Comparison Get Post
1 Purpose The Get request is designed for getting data from the server. The Post request is designed for sending the data to the server.
2 Post Mechanism The request is sent via URL. The request is sent via an HTTP request body.
3 Parameter Passing The request parameters are transmitted as a query string appended to the request. The request parameters are transmitted with the body of the request.
4 Default It is the default method hence it implements automatically. We need to specify manually.
5 Capacity We can send limited data with the Get request. We can send a large amount of data with the Post request.
6 Data Type It always submits data as text. We can send any type of data.
7 Security The use of Get is safe because it is idempotent. The use of Post unsafe because it is non-idempotent.
8 Visibility of Data The data is visible to the user as it puts the data in the URL. The data is not visible to the user as it puts the data in the message body.
9 Bookmark and Caching The Get request can be bookmarked and caching. The post request cannot be bookmarked and caching.
10 Efficiency It is more efficient than post. It is less efficient.
11 Example Search is the best example of Get request. Login is the best example of a Post request.
The main purpose of multithreading is to provide multiple threads of execution concurrently for maximum utilization of the CPU. It allows multiple threads to exist within the context of a process such that they execute individually but share their process resources.
If someone is new to GraphQL, it will be challenging for them to set it up as its ecosystem and processes are still advancing and maturing. But once one has a good understanding of GraphQL, they can send simple string queries from the client application to fetch data from remote server-side applications to do the required job. On top of that, libraries such as Apollo, give ease to caching and API development. It handles the scenarios about caching on its own, without a need for custom code to enable it. On the other hand, file or image uploading in GraphQL is still not tremendously evolved, and one needs a REST API to better perform this job.
Multitasking is an important skill for full-stack developers because your diverse skills might translate to working on multiple projects that are in different phases of the development cycle. 
 
Here are a few ways to manage multiple projects happening simultaneously : 
 
* Plan your work before you start
* Prioritize tasks from different projects 
* Work only on one thing at a time 
* Communicate with your manager if you’re facing any challenges
Full stack developers and software engineers both work to achieve project goals and meet client objectives. However, full stack developers often hold leadership roles, while software engineers may work under the supervision of full stack developers and use their expertise to develop specific project features. Although these professionals often work as part of a team, many full stack developers and software engineers work as freelancers or contractors.
 
Here is a list of some tasks full stack developers perform :
 
* Consulting with clients
* Developing software prototypes
* Designing applications
* Leading product development teams
* Writing code for back-end operations
* Writing and optimizing code for front-end operations
* Testing code to meet clients' expectations
* Monitoring performance of web architectures
* Troubleshooting and resolving issues with web applications
 
Here is a list of some tasks software engineers perform :
 
* Developing and directing software system testing
* Managing software development cycles
* Communicating project details with clients and team members
* Applying engineering and mathematic principles to software development
* Monitoring system performance
* Developing project plans and proposals
* Analyzing data to improve existing systems
* Working alongside team members
* Designing and implementing systems.
"use strict" is a statement that is used to enable strict mode to entire scripts or individual functions. Strict mode is a way to opt in to a restricted variant of JavaScript.
 
Advantages :
 
* It makes it impossible to create global variables by mistake.
* Makes assignments that would otherwise silently fail to throw an exception.
* Makes attempts to delete undeletable properties throw (where before the attempt would simply have no effect).
* It is mandatory that the function parameter name should be unique.
* this is undefined in the global context.
* It catches some common coding bloopers, throwing exceptions.
* It stops the functioning of features that are confusing.

Disadvantages :
 
* A lot of features that most of the developers might be used to are absent.
* No more access to function.caller and function.arguments.
* The concatenation of scripts written in different strict modes might cause issues.
Full stack developers and software engineers may have different levels of access to program resources for a project. Here are the differences in the level of program accessibility for full stack developers and software engineers:
 
Full stack developer program accessibility : Since full stack developers oversee most, if not all, parts of a project, they often have access to all program resources. Having full access to every aspect of a project allows full stack developers to assist team members when solving problems. This access may reduce time spent troubleshooting from those who don't have the same access.
 
Software engineer program accessibility : Software engineers often don't possess full access to all of a program's resources. They typically only require access to programs that apply to their particular stage in the software development cycle. However, when working with team members, software engineers may gain access to relevant program resources.
23 .
Explain the difference between REST and GraphQL
GraphQL does not deal with allocated resources, which is the most significant distinction between REST and GraphQL. Instead, everything is viewed as a graph, which is linked and can be searched to meet specific requirements.
Node.js is a single-threaded application but it supports concurrency via the concept of event and callbacks. As every API of Node js is asynchronous and a single thread, it uses async function calls to maintain the concurrency. Node uses an observer pattern. Node thread keeps an event loop and whenever any task gets completed, it fires the corresponding event which signals the event listener function to get executed.
Docker is a lightweight virtualization platform that may be used on your local system or in the cloud. Despite the fact that they aren't technically separate devices, they provide many of the same advantages. Docker may encapsulate ancient programmes, making it possible to deploy them on servers that would be difficult to set up with older packages and software versions.
* You'll need to learn how to use GraphQL to get started. You must keep up with the ecosystem's fast evolution.

* You need to send the queries from the client, you can just send strings but if you want more comfort and caching you’ll use a client library -> extra code in your client.

* You need to define the schema beforehand => extra work before you get results.

* You need to have a GraphQL endpoint on your server => new libraries that you don’t know yet.

* Graphql queries are more bytes than simply going to a REST endpoint.

* The server needs to do more processing to parse the query and verify the parameters.
Today, the software is rapidly created and features are often changed based on customer needs, and then it is deployed into production. Each organization has its unique way of getting new applications into the production environment. Most organizations follow the standard deployment and release strategies such as Blue-Green and Rolling Deployment.
 
Blue-Green Deployment Strategy : A deployment strategy like this creates two separate infrastructure environments i.e., blue and green. A blue environment contains older code (old version), while a green environment (production) contains the latest code (new version). There is only one live production environment at any given time.
 
Example : For instance, the green environment is live and is receiving all user traffic, while the clone (blue) is idle. Once a new version of an application is ready for release, it can be deployed to the blue environment for testing. As soon as the new release passes testing, application traffic is switched from green to blue. Blue then becomes the live production environment, and Green becomes idle, ready for testing the next release.
 
Rolling Deployment Strategy : Using this deployment strategy, old versions of an application are completely replaced with the new versions by completely replacing the infrastructure on which they run.
 
Example : When a new version must be deployed to all nodes, the new version is deployed to the first node while all other nodes handle end-user traffic. As soon as the new version is successfully installed on the first node, it will begin managing end-user traffic while the new version is being installed on the second node. The process is repeated until all nodes have been successfully upgraded to the new version.
A program may have the property of referential transparency if any two expressions in the program that have the same value can be substituted for one another anywhere in the program without changing the result of the program. It is used in functional programming. For example, consider the following code snippet:
count1 = (fun(x) + y) * (fun(x) - z);  
temp = fun(a);  
count2 = temp + y * temp - z;  
The variables count1 and count2 will be equal if the value of fun(x) is not reflected. If the variable count1 is not equal to the variable count2, the referential transparency is violated.
Normalization Denormalization
Normalization involves removing redundant data (multiple copies of data) from a database and storing consistent, non-redundant data. It involves combining data from multiple tables into a single so that it can be queried quickly.
It primarily focuses on clearing out unused data and reducing duplicate data and inconsistencies from a database. On the other hand, denormalization aims to achieve faster query execution by adding data redundancy.
During normalization, tables are reduced in number due to the reduction of data in the database. Denormalization, on the other hand, involves integrating data into the same database and therefore the number of tables to store the data increases.
Data integrity is maintained by normalization. A change to the data in the table will not impact its relationship with the other table. Data integrity is not maintained by denormalization.
It optimizes the use of disk space. It does not optimize disk space.
A promise is an object that can be returned synchronously from an asynchronous function. It may be in the following three states:
 
Fulfilled : If a promise called the onFulfilled() method, a promise will be in fulfilled state.

Rejected : If a promise called the onRejceted() method, a promise will be in rejected state.

Pending : If a promise is not yet fulfilled or rejected, a promise will be in pending state.

A promise will be settled if and only if it is not pending.
There are the following ways to optimize the load time of a web application:
 
* Optimize image size.
* Avoid redirects.
* Minimize the HTTP requests.
* Put stylesheet reference at the top.
* Place script reference at the bottom.
* Put CSS and JavaScript externally.
* Compress (or) Minify JavaScript & Style Sheets.
* Compress (or) Minify and optimize the content.
* Utilize CDNs and remove unused files/scripts.
* Browser caching. 
* Clear Cache the web page (or) Hosting Location.
Abstract Interface
An abstract class can have abstract and non-abstract methods The interface can have only abstract methods.
An abstract class can have static, non-static, final, non-final variables. The interface has only static and final variables.
An abstract class can provide the implementation of the interface.  Interface can’t provide the implementation of an abstract class.
An abstract class can be extended using the keyword "extends". An interface can be implemented using the keyword "implements".
A Java abstract class can have class members like private, protected, etc. Members of a Java interface are public by default.
As long as the data within the API is accessible to the public, it will technically not be possible to completely prevent data scraping. It is possible, however, to minimize bot activity (automated computer programs on the internet that perform certain tasks) by throttling or rare limiting. Rare limiting will be able to prevent a certain device from making an unlimited number of requests within a defined time.

If too many requests are made beyond the defined limit, a 429 Too Many Attempts HTTP error is thrown. It is vital to record more than just the IP address of the device since the IP address is not unique to each device and can stop the whole network from accessing the API.
Before ES6, variable declarations were only possible using var. With ES6, we got let and const. Both let and const declarations are block-scoped, i.e., they can only be accessed within the " { } " surrounding them. On the other hand, var doesn't have such a restriction.

Unlike var, which can be accessed before its declaration, you cannot access the let or const variables until they are initialized with some value. Temporal Dead Zone is the time from the beginning of the execution of a block in which let or const variables are declared until these variables are initialized. If anyone tries to access those variables during that zone, Javascript will always throw a reference error as given below.
console.log(varNumber); // undefined
console.log(letNumber); // Throws the reference error letNumber is not defined
var varNumber = 3;
let letNumber = 4;
Both let and const variables are in the TDZ from the moment their enclosing scope starts to the moment they are declared.
One of the most popular features of ES6 is the "arrow functions" (also known as "fat arrow functions"). Arrow functions are a new way to write concise functions. Arrow functions offer a compact alternative to traditional function expressions, but they have limitations and cannot be used in every case.
 
The following is an ES5 function :
function timesTwo(params) {
        return params * 2
     }
timesTwo(5);  // 10
The same function can also be expressed as an arrow function in ES6 as follows :
var timesTwo = params => params * 2
timesTwo(5);  // 10
Differences & Limitations :
* Has no bindings to 'this' or 'super', so it shouldn't be used as a method.
* Has no new.target keyword.
* The call, apply, and bind methods are not suitable since they rely on establishing scope.
* Not suitable for use as constructors.
* Not possible for an arrow function to use the yield keyword within its body, etc.
CI/CD is a best practice to develop applications in which code changes more frequently and rapidly. Sometimes, it is also known as CI\CD pipeline. It is widely used in DevOps and also an agile methodology.
 
Continuous integration is a coding philosophy or deployment practice in which developers integrate their code in a shared repository several times a day. Because modern application requires developing code in different platforms. The goal of continuous integration is to establish an automated mechanism that builds, test, and package the application.
 
Continuous delivery starts where CI ends. It automatically delivers the application to the selected infrastructure. CD ensures the automated delivery of code if any changes are made in the code.
Null : Null means a variable is assigned with a null value. If we use it with typeof operator it gives result as an object. We should never assign a variable to null because the programmer uses it to represent a variable that has no value. Note that JavaScript will never automatically assign the value to null.
 
Undefined : Undefined means the variable is declared but not assigned any value to it. It may be a variable itself does not exist. If we use it with typeof operator it gives the result undefined. It is not valid in JSON.
 
Let's understand it through an example.
var var1  
var var2 = null //assigning null value to the variable var2  
console.log(`var1 : ${var1}, type : ${typeof(var1)}`)  
console.log(`var2 : ${var2}, type : ${typeof(var2)}`)  
When we execute the above code, it generates the following output :
Var1 : undefined, type : undefined  
var2 : null, type : object  
From the above output, we can observe that the value of var1 is undefined also its type is undefined. Because we have not assigned any value to the variable var1. The value null is assigned to the variable var2. It prints its type as abject. Since null is an assignment value and we can assign it to a variable. Therefore, JavaScript treats null and undefined relatively equally because both represent an empty value.
GraphQL REST
GraphQL is an API design architecture, but with a different approach that is much flexible. REST is a robust methodology and API design architecture used to implement web services.
It follows client-driven architecture. It follows server-driven architecture.
It does not deal with the dedicated resources. It deals with the dedicated resources.
It has a single endpoint that takes dynamic parameters. It has multiple endpoints.
It provides stateless servers and structured access to resources. It provides stateless servers and flexible controlled access to resources.
It is elastic in nature. It is not rigid in nature.
It supports only JSON format. It supports XML, JSON, HTML, YAML, and other formats also.
The client defines response data that it needs via a query language. Data represented as resources over HTTP through URI.
It provides synchronous and asynchronous communication in multiple protocols such as HTTP, MQTT, AMQP. It provides synchronous communication through HTTP only.
Its design based on HTTP (status, methods, and URI). Its design based on message exchange.
It provides high consistency across all platforms. It is difficult to achieve high consistency across all platforms.
Development speed is fast. Development speed is slow.
Resetting Normalizing
Removes all the built-in browser styling. Normalizing makes elements render consistently across browsers.
Provides bug fixes Includes bug fixes
In a language implementing classical inheritance like Java, C#, or C++ you start by creating a class–a blueprint for your objects – and then you can create new objects from that class or you can extend the class, defining a new class that augments the original class.
 
In JavaScript you first create an object (there is no concept of class), then you can augment your own object or create new objects from it.
 
Every object in Javascript has a prototype. JavaScript’s inheritance system is based on prototypes, and not class-based. When a message reaches an object, JavaScript will make an attempt to find a property in that object first. If it cannot find it, then the message will be sent directly to the object’s prototype, and so on. That behavior called prototype chain or in many places, prototype inheritance.
 
Constructor functions are the most preferred way in JavaScript when it comes to constructing prototype chains. When we use new, JavaScript injects an implicit reference to the new object being created in the form of this keyword. It also returns this reference completely at the end of the function.
function Foo() {
  this.kind = ‘foo’
}

var foo = new Foo(); 
foo.kind //=> ‘foo’
* The clear CSS property specifies whether an element can be next to floating elements that precede it or must be moved down (cleared) below them.
 
* Clearing floats (or clear fixing) basically force the containing element to expand to contain its child elements. Thus, it forces the subsequent elements to appear below it.
The propagation of events inside the DOM (Document Object Model) is known as 'Event Flow' in JavaScript. The event flow defines the order or sequence in which a particular web page receives an event. Accordingly, event flow (propagation) in JS is dependent on the following aspects:
 
Event Bubbling : With Event Bubbling, the event is captured and handled first by the innermost element, and then propagates to the outermost element. Events propagate up the DOM tree from child elements until the topmost element is handled.

Event Capturing : With Event Capturing, the event is captured and handled first by the outermost element, and then propagates to the innermost element. Event cycles propagate starting with the wrapper elements and ending with the target elements that initiated the event cycle.
Basis of Comparison Fail Fast Iterator Fail Safe Iterator
Operates It operates directly on the collection itself. It operates on a cloned copy of the collection.
Exception It throws a ConcurrentModificationException in modifying the object during the iteration process. It does not throw Exception.
Clone Object No clone object is created during the iteration process. A copy or clone object is created during the iteration process.
Memory utilization It requires low memory during the process. It requires more memory during the process.
Modification It does not allow modification during iteration. It allows modification during the iteration process.
Performance It is fast. It is slightly slower than Fail Fast.
Examples HashMap, ArrayList, Vector, HashSet, etc. CopyOnWriteArrayList, ConcurrentHashMap, etc.
ServletContext ServletConfig
ServletContext represents the whole web application running on a particular JVM and common for all the servlet. ServletConfig object represents single servlet.
It is just like a global parameter associated with the whole application. It is the same as the local parameter associated with a particular servlet.
It has application-wide scope so define outside servlet tag in the web.xml file. It is a name-value pair defined inside the servlet section of web.xml files so it has servlet wide scope.
getServletContext() method is used to get the context object. getServletConfig() method is used to get the config object.
To get the MIME type of a file or application session related information is stored using a servlet context object. The shopping cart of a user is a specific to particular user so here we can use servlet config.
In Java, SOLID principles are an object-oriented approach that are applied to software structure design. It is conceptualized by Robert C. Martin (also known as Uncle Bob). These five principles have changed the world of object-oriented programming, and also changed the way of writing software. It also ensures that the software is modular, easy to understand, debug, and refactor.
 
The word SOLID acronym for :
 
* Single Responsibility Principle (SRP)
* Open-Closed Principle (OCP)
* Liskov Substitution Principle (LSP)
* Interface Segregation Principle (ISP)
* Dependency Inversion Principle (DIP)
Avoid Unnecessary Locks : We should use locks only for those members on which it is required. Unnecessary use of locks leads to a deadlock situation. It is recommended that use a lock-free data structure. If possible, keep your code free from locks. For example, instead of using synchronized ArrayList use the ConcurrentLinkedQueue.
 
Avoid Nested Locks : Another way to avoid deadlock is to avoid giving a lock to multiple threads if we have already provided a lock to one thread. Since we must avoid allocating a lock to multiple threads.
 
Using Thread.join() Method : We can get a deadlock if two threads are waiting for each other to finish indefinitely using thread join. If a thread has to wait for another thread to finish, it's always best to use join with the maximum time you want to wait for the thread to finish.
 
Use Lock Ordering : Always assign a numeric value to each lock. Before acquiring the lock with a higher numeric value, acquire the locks with a lower numeric value.
 
Lock Time-out : We can also specify the time for a thread to acquire a lock. If a thread does not acquire a lock, the thread must wait for a specific time before retrying to acquire a lock.
Constructor Injection Setter Injection
There is no partial injection of dependencies. There can be a partial injection of dependencies.
It does not override the setter injection value. It overrides the constructor injection value if both are defined.
It always creates a new instance if any modification occurs. It does not create a new instance if we made any changes to it.
Using constructor injection is better for too many properties. Using setter injection is better for few properties.
It makes bean class objects as immutable. It makes bean class objects as mutable.
In Java, double brace initialization is a combination of two separate processes. The two consecutive curly braces {{ involved in it.
 
The first curly brace represents the creation of an anonymous inner class. Remember that the second curly brace will not be considered in such a case. It is just like creating an anonymous inner class.
 
The second curly brace represents an initialization block that we have seen in it as a class for initialization. When we use the initialization block for an anonymous inner class it becomes Java double brace initialization. The inner class has a reference to the enclosing outer class. We can use the reference by using this pointer.
 
It is used to initialize collections because it is easier to initialize a constant collection using double brace initialization. The example of double brace initialization is as follows :
import java.util.*;  
public class Demo  
{  
public static void main(String args[])  
{  
-------------------  
-------------------  
Map<String, Map<String, Integer>> map = new HashMap <String, Map<String, Integer>> {{  
put ("VEGETABLES", new HashMap<String, Integer>() {{  
put("Tomato", 300);  
put("Onion", 50);  
put("Carrot", 100);  
put("Beetroot", 40);  
}}  
--------------------  
-------------------  
);  
}};  
System.out.println(map);  
}  
}​