Java Interview Prep
Java Interview Prep
Lambda Expressions
Abstract method ==> a method that has no implementation
Functional interface ==> it's the interface that has only one abstract method | it can have default or static methods
Simplifies the implementation of functional interfaces and provide a cleaner, concise syntax for anonymous classes
**lambda defines the implementation of one method when the interface has only one abstract method it works fine
because java knows exactly the method that you're implementing in your lambda because there's only one
**
A feature that allows you to write anonymous methods using expressions. They provide a short way to
represent a functional interface.
EXAMPLES:
interface FuncInterface
{
// An abstract function
void abstractFun(int x);
// A non-abstract (or default) function
default void normalFun()
{
System.out.println("Hello");
}
}
class Test
{
public static void main(String args[])
{
// lambda expression to implement above
// functional interface. This interface
// by default implements abstractFun()
FuncInterface fobj = (int x)->System.out.println(2*x);
// This calls above lambda expression and prints 10.
fobj.abstractFun(5);
}
}
Streams API
Streams is a set of functions that we can perform on a certain data structure. It enables us to perform operations like filtering,
mapping, reducing, and sorting.
It allows to process sequences of elements (like collections) in a functional style (functional-style operations)
b. map()
Transforms each element in the stream.
c. sorted()
Sorts the elements, either naturally or using a comparator.
d. distinct()
Removes duplicate elements.
2. Terminal Operations
These produce a result or a side-effect and end the pipeline.
a. collect()
Converts the elements of the stream into a collection or other data structure.
b. forEach()
Performs an action on each element.
d. count()
Counts the number of elements in the stream.
Optional class
It's a container object which may or may not contain a non-null value. Helping to avoid NullPointerExceptions.
Is a container object used to represent the presence or absence of a value.
If a value is present, isPresent() will return true and get() will return the value.
1. Creating an Optional
a. Optional.of(value)
Creates an Optional with a non-null value. Throws NullPointerException if the value is null.
Example:
b. Optional.ofNullable(value)
Creates an Optional that can hold a null value.
Example:
c. Optional.empty()
b. isEmpty()
Returns true if the Optional is empty; otherwise, false. Introduced in Java 11.
Example:
b. orElse(defaultValue)
Returns the value if present; otherwise, returns the provided default value.
Example:
c. orElseGet(Supplier)
Returns the value if present; otherwise, invokes the supplier and returns its result.
Example:
6. Performing Actions
a. ifPresent(Consumer)
Performs the given action if a value is present.
Example:
b. ifPresentOrElse(Consumer, Runnable)
Performs the given action if a value is present; otherwise, runs the given runnable. Introduced in Java 9.
Example:
just() is typically used to start a reactive stream with some predefined values.
b. flatMap()
• Purpose: Similar to map(), but the transformation function returns a new publisher (like Mono or Flux) for each
item.
• Behavior: Emits the items from these new publishers as a single, merged stream.
Example:
d. zip()
• Purpose: Combines items from two or more publishers into a single publisher.
• Behavior: Combines items in a pairwise fashion (e.g., the first item from each stream, the second item, and so on).
Example:
e. merge()
• Purpose: Combines multiple publishers into a single stream, emitting items as soon as they arrive.
• Behavior: Order is not guaranteed because it emits items as soon as they are available.
Example:
f. concat()
Java interview prep Page 10
f. concat()
• Purpose: Concatenates multiple publishers into a single stream.
• Behavior: Ensures that the first stream completes before starting the next.
Example:
g. doOnNext()
• Purpose: Executes a side effect (logging, monitoring, etc.) when an item is emitted.
• Behavior: Does not modify the stream.
Example:
h. subscribe()
• Purpose: Subscribes to the publisher and starts consuming the stream.
• Behavior: Can handle different types of events (data, errors, or completion signals).
Example:
SOLID principles
A set of design principles, to create well-structured, maintainable, and scalable software. These
principles help in building robust object-oriented designs by improving code readability, reusability, and
flexibility.
Example:
Example:
Example:
Example:
Design Patterns
Reusable solutions for typical software design challenges
Expert object-oriented software engineers use these best practices to write more structured, manageable, and scalable code.
Singleton:
Ensures that a class has only one instance
All objects that use an instance of this class, use the same instance
Singleton ensures the uniqueness of a class instance and obviously the way to access that instance is unique.
Factory:
it is one of the best ways to create an object.
In the Factory model, we create an object without exposing the creation logic to the client and refer to the newly
created object using a common interface.
• Structural Design Pattern: Focus on the structure and composition of classes and objects.
Decorator:
The Decorator pattern allows a user to add new functionality to an existing object without changing its structure.
This pattern creates a Decorator class that wraps around the original class and provides additional functionality by
keeping the signature of the class methods intact.
• Behavioral Design Pattern: Focus on the interactions and responsibilities between objects.
Observer:
Defines a one-to-many dependency so that when one object changes state, all its dependents are notified.
Bad:
Good:
These names are so much better. They tell you what is being measured and the unit of that measurement.
Avoid Disinformation
Be careful about words that mean something specific.
Bad:
Good:
Good:
Java interview prep Page 19
Good:
Bad:
Good:
It is checking the password, but when the password is valid, it is also initializing the session which is a side-effect.
You can change the name of the function to something like checkPasswordAndInitializeSession to make this effect
explicit. But when you do that, you should notice that your function is actually doing two things and you should not
initialize the session here.
00:00:29 Today, the most popular music company is also a software company, Spotify. Today's
fastest growing entertainment companies are video game creators, again, software. You get the point.
Basically, every successful company today is a software company. And the quality of the software
matters.
00:00:53 In the context of software engineering, software quality refers to two related but
distinct concepts. Software functional quality reflects how well it complies with a given design, based
on the functional requirements. It is the degree to which the correct software was produced. Software
structural quality refers to how it meets non-functional requirements that supports the delivery of the
functional requirements
00:01:22 such as maintainability. It has a lot more to do with the degree to which the software
works as needed. There are two main approaches to software quality. Defect management and quality
attributes. A software defect can be regarded as any failure to address the end user requirements.
00:01:57 There is also the Quality Model Standard of ISO 25010, which contains eight different
quality characteristics, each composed of a sub-characteristic. Additionally, the standard defines a
quality in-use model with five characteristics.
00:02:18 One of the popular methods of analyzing and determining the quality of the code is by
using static and dynamic code reviews. Static code analysis is done without executing the code. Dynamic
code analysis relies on analyzing how the code behaves during execution.
00:02:38 Static analysis involved no dynamic execution of the software under review and it can
detect possible defects in an early stage before running the program and even during programming
directly in the development environment.
00:02:54 Static analysis can be done by a machine to automatically analyze the source code and
detect non-complying rules to ensure proper coding standards and conventions are used.
00:03:10 Technical depth is a metaphor. Let's imagine you are buying a shiny new kitchen sink.
From your perspective as a customer, you have a romanticized image of how this would look. You now
sign off on the construction. You have your new sink ready. But wait, there is not much water coming.
You go down into the basement and you see water has leaked and repairs will be very costly. How
would you react towards the supplier?
00:03:41 In a similar way, some software today are created as poor and low quality solutions to
create an illusion as shiny objects that on the surface looks fine but may have dark and shady
construction. The metaphor was coined by Ward Cunningham back in 1992 and it can be compared to a
financial debt.
00:04:07 Just as financial debt, you can get your money now, and you can pay interest, and if
you're not able to pay, you go bankrupt. Same with the technical debt, you get early access to the
market,
00:04:20 If you don't do the refactoring, you're unable to maintain your software. The metaphor
is used today in several different ways, both as an estimate of how much you have in your technical
debt, but also to calculate the total cost of ownership and also assessing various business risks and
00:04:47 And also in a portfolio and quality perspective it's very useful to use this metaphor. In
the 1870s a ship named HMS Challenger set about the oceans to map the ocean floor. For several years
the ship sailed around the world measuring how deep the sea was, using only ropes and lead weights.
00:05:13 At the time, it was the only way to measure the ocean floor. When measuring over the
Pacific, the scientists were amazed. How deep could the sea be? Is it a hole? A thin hole? What type of
feature has it? So many questions. Many years later comes a new invention, sonar. Using submarine
hunting technology for scanning the seas makes it much easier, faster and more detailed than ever
before.
00:05:44 In a similar way, SonarQube makes the probing of large codebases much easier and
faster than ever before. SonarQube is an open-source solution developed by SonarSource for
continuous inspection of code quality by performing automatic reviews with static code analysis to
detect bugs, code smells and security vulnerabilities in many, many different programming languages.
00:06:15 SonarQube can record metric history and provide evolution graphs. SonarQube offers
reports on duplicate code, coding standards, unit tests, code coverage, code complexity, comments,
bugs, and security vulnerabilities.
00:06:33 Sonar Source has the ambition to solve problems that virtually every company
developing software is facing, with statements like code quality should be the concern of every
developer, not just a few experts. Unless you enforce a quality gate at release time, you don't have code
quality practice in place. Managers should be able to make decisions on existing risks in their portfolios.
00:07:00 SonarSource created SonarCube and also offers a cloud solution that integrates code
stored in Bitbucket, GitHub or Azure DevOps repos called SonarCloud. In SonarCloud, there is many
different types of projects, more than 80,000. You can also have lots of different filters. For example,
this is useful for checking out various specific programming languages.
00:07:25 You can also have different perspectives. You can look at the risks, for example, or you
can look at maybe maintainability and see the size of the various projects. You can sort by size and you
can see which is the largest. Here we have an example of 11 million lines of code.
00:07:44 It's something with Android or kernel of Android. You can see here you have the
reliability and you have the maintainability. You have 7000 days of technical depth. You can dig into this
and find out more. You can find specific bugs that are not complying with the given rule set.
00:08:05 You can even step down into the specific code line. You can see which rule and how you
really should be doing it according to your coding standard. Well, that's all for today, folks. I hope this
was useful. If you do like this type of content, then hit that like button below. And you can also subscribe
to my YouTube channel. So until next time, have a great one.
SonarQube
SonarQube is an open-source platform for continuous code quality inspection. It performs static code analysis
to detect bugs, vulnerabilities, and code smells in your codebase. By integrating SonarQube into your
development pipeline, teams can ensure high-quality code and improve maintainability, reliability, and security.
Is a Code Quality Assurance tool that collects and analyses source code, and provides
reports for the code quality of your project. It combines static and dynamic analysis tools and
enables quality to be measured continually over time.
SonarQube reduces the risk of software development within a very short amount of time . It
detects bugs in the code automatically and alerts developers to fix them before rolling it out for production.
SonarQube also highlights the complex areas of code that are less covered by unit tests
Advantages of SonarQube
Improves Code Quality:
○ Detects potential bugs and code smells.
○ Ensures adherence to coding standards and best practices.
Supports Multiple Languages:
○ Offers support for 30+ programming languages, including Java, Python, JavaScript, C++, and more.
Continuous Integration:
○ Easily integrates with CI/CD pipelines like Jenkins, GitHub Actions, and GitLab CI.
Enhanced Security:
○ Identifies security vulnerabilities in the code.
○ Helps developers address potential threats like SQL injection and XSS.
Improves Collaboration:
○ Developers can see issues in their code in real-time, encouraging a culture of accountability.
○ Reports and dashboards foster communication among teams.
Customizable Rules:
○ Allows you to define custom rules and thresholds to suit your project's needs.
Comprehensive Reports:
○ Provides detailed reports on code coverage, complexity, and issue trends.
Code smells are specific characteristics or patterns in your code that indicate potential problems or areas
for improvement. They are not necessarily bugs or errors, but they can make your code harder to understand,
maintain, or extend over time.
Quality Gates:
Quality Gates are a set of predefined conditions that must be met for the code to be considered of high
quality. Quality Gates are defined on the SonarQube server and can be customized based on the
project’s requirements. If the Quality Gates are not met, the SonarQube server fails the analysis, and the
code is flagged as problematic.
Example:
A Quality Gate can be defined to ensure that the code coverage is above 80% and that there are
no critical vulnerabilities. If the analysis report shows that the code coverage is below 80% or that
there are critical vulnerabilities, the analysis fails, and the code is flagged as problematic.
Adopting CI will help to improve code and software quality in a phase wise manner.
By automating the CI software developers can spend more time on tasks related to new code additions
and fixing bugs rather than focusing on infrastructure deployment.
By adopting CI developers or teams can identify and fix bugs before they are merged into the main
codebase and released to production. This will also reduce the time it takes to release new updates by
automating the build and test process.
With implementation of CI you or your team member can have the complete visibility and transparency
of the development process. Anyone who has access on the CI can identify and track the process of build
and test. With that information team users can identify bottlenecks and can find areas for improvement.
GIT
Git is a distributed version control system that is used for tracking changes in source code during the
development process. It is used to coordinating work among programmers.
and version control is a system that tracks changes to files over a period of time.
Git Areas:
There are 3 main areas:
Working directory, Staging area, and repository
Working Directory
Is the area where you are currently working. It is where your files live.
This area is the “untracked” area of git. Any changes to files will be seen in this area marked. If you don't explicitly
save these changes to git, you will lose it. It happened because git is not aware of changes in the working
directory until you tell git to pay attention to them.
If you make changes in the working directory, git will recognized that they are changed, but it won't save anything
until you use git add command to make git start tracking all your changes in staging area.
You can see what files are in your working directory by using command git status. This command will show you
files in the working directory (untracked files) and files in the staging area (tracked files)
Staging Area
This is the area when git starts to track all the changes that occur in files. In this area too, git will save the changes
that happen that are reflected in .git directory. In this area, git will track all the changes that are happening to all
the files that are added, but, git won’t know track all the changes that are happening to a new file that you add
unless you explicitly add them too.
Local Repository
This area is everything that is in your .git directory. To add items from the staging area to this area, you can use git
command. A commit is simply checkpoint telling git to track all the changes that are happened based on our last
commit as a comparison. After you commit, your staging area will be empty.
Git vs GitHub/GitLab
• Git: A version control system for tracking changes.
• GitHub/GitLab: Cloud-hosted platforms that provide Git repositories with additional collaboration features
like pull requests, CI/CD, and project management.
Basic Commands
1. Initialize a repository:
4. Commit changes:
Branching Strategy
It's a strategy that the software development teams adopt for(writing, merging and deploying code)
It lays down a set of rules to follow in the development process and how to interact with a shared
codebase
1. Git Flow
Best for: Large projects with scheduled releases.
Structure:
• Main branch: Holds the stable production-ready code.
• Develop branch: Used for integrating new features.
• Feature branches: Created for specific features based on the develop branch.
• Release branches: Staging area before release.
• Hotfix branches: For urgent production fixes.
Example:
• A developer creates a feature branch:
This strategy provides clear roles for branches but can be complex for small teams.
This strategy minimizes merge conflicts but requires strong CI/CD pipelines.
To learn more about Git Areas You can check this Blog below:
4. Feature Branching
What is Git? How does it work? (part 1) | by Farhan Amin | Medium
Best for: Teams working on isolated features. (Small projects or isolated features)
Structure:
• Each feature or bug fix gets its own branch.
• Merges happen only after thorough testing and reviews.
Example:
• Start working on a new feature:
Fetch vs Pull
• git fetch: Downloads updates from the remote repository but doesn't merge them into your local
branch.
• git pull: Combines fetch and merge, automatically merging remote changes into your branch.
Merge
Combines two branches without changing their history.
It creates a new commit that shows where the two branches came together.
Rebase
Moves your branch to start from the latest changes of another branch.
It rewrites the commit history to make it linear and clean.
Cherry-Picking
Cherry-picking in Git allows you to apply a specific commit from one branch onto another, without
Stashing:
Definition: Stashing in Git allows you to temporarily save your uncommitted changes, providing a clean
working directory.
You're working on a new feature but need to switch to another branch to address a critical bug. Your
current changes aren't ready to commit, so you decide to stash them.
What is Maven?
Maven is a build automation and project management tool primarily used in Java development. It
simplifies the process of managing a project's build, reporting, and documentation through the Project
Object Model (POM).
POM
The Maven Project Object Model (POM) is a fundamental concept in Apache Maven.
The POM is an XML file that contains information about project configuration and project dependencies,
including their versions, which are used by Maven to build the project.
The POM file specifies dependencies, build plugins, and other project-related settings.
Maven uses the POM to manage the project's dependencies and build lifecycle, and plugins.
When you run Maven commands, it reads the pom.xml file to understand how to compile, test, and
package the code. It also resolves and downloads the necessary dependencies specified in the POM
from remote repositories.