
An experienced Associate Architect with a passion for multi-tenant platforms, providing solutions to business problems. Extensive hands-on experience with great passion in Defining, Designing, and Implementing highly scalable, available, flexible solutions. Managed multiple technical programs and projects, and developed winning proposals. Have extensive experience interacting with corporate clients and company executives.
Lead Java Architect
UshurAssociate Software Architect
SyndigoLead Member Of Technical Staff
athenahealthSDE
Amazon IndiaSr. Associate - Projects
PhilipsSenior Associate
JPMorganChaseSSE
Hindustan UniliverPA
Cognizant Technology Solutions
Eclipse

STS

IBM RAD

Git

SVN

IntelliJ IDEA
.png)
Jenkins

Maven
Jira

Nginx

Kibana

Elastic APM

Ubuntu
.jpg)
Grafana

Postman

Gradle

Terraform

Bitbucket

RabbitMQ

New Relic

SoapUI

Confluence

SQL Developer

Nginx

Kibana

STS
Hi, y'all. So this is Sameer Saram. I completed my MCA from CGNI University, Chennai in 2009, and I started my career as a back-end Java developer. And I have overall around 14.5 years of experience currently, mostly into Java and its related technologies, like Java, microservices, RESTful API, web services, then cloud, AWS, Azure, both, then Hibernate, Spring, SQL, NoSQL DB, then messaging queue like Kafka, RabbitMQ, then a container service like Kubernetes, Docker. So yeah. And as well as I have different domain experiences, like working in banking, e-commerce, and healthcare companies. And currently, I'm associated with a PMMDM domain company called Zendigo, working as an associate architect. And here, mostly my technology is similar back-end technology, like Java, Apache, Storm, you can say microservices, Azure, mostly we use here as a cloud, Kafka, streaming. We have Docker, Kubernetes as part of that for monitoring, and tools like ELK Stack, and Akiva, Prometheus, Grafana, for log logging and monitoring, this thing. And, yeah, apart from that, like, I do have exposure to some UI from ten technologies like React. And, yeah, I have also worked in mobile application development. Yeah. That's it from my end. Thank you.
Okay, so here is the situation if there are 2 microservices, which is trying to modify the shared resources or, for example, a shared database. So, there are 3 things we can do here. The first approach is generally to have a single separate service for each of the microservices. But let's say for this situation, if we have a common DB or common resources that is getting modified by both of the services. So here we can take an optimistic locking approach. So this locking technique is where you will have a time stamp and version of the record. Once you go and try to take the record from the DB, your process will read that version that is associated with that row. And while committing after changing while committing, it will check that whether that record is having the same version. If there is a change in version, it will correlate that the record has been modified by some other process. So that will not process it. Apart from that, distributed locking, we can take any external locking through Redis or any other locking mechanic to lock the record. Also, setting up a database-level isolation level can also help us to take a log of that DB row. And if any process is going and modifying, other processes have to wait until the lock has been released by the first process. So, yeah, there are 3 ways to control that Spring Boot microservice if they are trying to access the shared resources.
So the best way to implement a globally thread-safe configuration accessible by all components in Spring Boot is to use a configuration service, which is outside of our application, per environment. Let's say we have a developer environment, a QA environment, and a prod environment. Whatever configuration we are giving would be based on our environment. Each environment might have different configurations. The dev environment would have different configurations, the QA environment would have different configurations, and production would definitely have different configurations. At runtime, when the application is deployed and running, it will fetch the configuration from the config files. In our application, we can say, "Based on your configuration, you can use the dev config, the QA config, or the prod config." Those files, with the Spring configuration, can be given per environment, and at runtime, our application will fetch the configuration and work accordingly.
Okay, so Memorial Legal, that major issue for our application. So, generally, before committing the code or in our application, if memory is not managed properly or an object we are creating is not getting claimed back by our garbage collector, there will be a memory leak. Okay? So here, the question is to suggest a solution to reduce the memory leak in a long-running Java Spring Boot application. So here, I can say based on your application, no size or behavior, we can choose different garbage collection algorithms that we have currently. So, currently, either all our garbage collector works on the young gen or old gen space that we have in our memory. Okay. So the garbage collector algorithms also work on how we are cleaning our allocated memory from the old generation to the newer generation, how they are moving. This newer generation will be a new memory location, and once it becomes old, it is moved to the old gen space. Okay? So choosing the garbage collection is important. Nowadays, we have G1 GC or G1C algorithm, which you can configure or choose that garbage collector, which will not disturb your application. If you have a scheduled application, you do not need any downtime for that one. So you can use that garbage collector. That is one solution. The next solution I can say is that any memory leak if you have, then use some tool. Like we have New Relic or JMeter. So just to test your performance, that will tell you what was your memory before running your application and what is the memory after running that application. Okay. So with the help of that tool, we can detect a memory leak. If there is a memory leak, it will say which of the modules from your code will have that memory leak. Then as a developer, we can go and analyze that code. Okay? So that piece of code, where is the memory leak happening? So if you see that some resources are being allocated and not released, that kind of best practices we can adopt or modify that code. But on top of that, we can choose the best garbage collector algorithm that fits our situation.
So what method would you recommend for securing RESTful endpoints in a Spring Boot application? Generally, RESTful endpoints have a stateless nature. So securing the application is also something which will work stateless. Like, if you see that maintaining a session or user authentication through the session, that might not work in an async environment. So the server, which is running asynchronously, token validation or session tracking through session or package tracking might not work, or you will not be able to scale your application. For RESTful endpoints, we are going for the stateless, you can say, authentication, which is recommended now. A popular technology that I have used is OAuth with JWT tokens. So by using OAuth and JWT tokens, the client will generate some token with the help of a secret key. And then it will attach that token along with the request, and that will be sent to the server. Or let's say your microservice endpoint, the service will get that token from the client. Now, it will verify the token payload, header, everything, so that the server will have the public key. So along with the public key, it will generate the token based on that payload, whatever the URL and with the public key, it will generate the test signature. If the signature is matching the request coming from the client, if it's matching, then you can say that no URL tampering has happened or your API was accessed by the only granted set of clients. So you can forward your request to your controller further. So the best way to use this technique, OAuth and JWT tokens, for stateless authentication.
Okay. So next question is let's discuss what step would you take to refactor a monolith Java application into a Spring Boot microservice architecture. Okay. So the most, generally, I have done is, like, domain-driven design. It's a very popular way of breaking that monolith into microservice architecture. Okay. So let's say, take one example. Let's say we have an ecommerce company. Let's say that I am moving it to the microservice architecture. So the domain is something you can say is the order processing domain. K. So that order processing, let's say, if you have the order or payment, this thing you can identify your domain. And within the domain, there is some bounded context. Okay. So the bounded context is, like, let's say, maintaining the product catalog or order or user base. So these things you can convert into a microservice. Okay. So that's why the main idea about that microservice is to develop a service with a single responsibility. Like, here, you can think of the solid principle, okay, that we do. So each microservice is to handle a single responsibility. Okay? So let's say, a user management service we have or order service we have or product catalog service. So each service will be within that particular domain, and these are you can consider as a bounded context. Okay. So this bounded context, we can implement as a service. And now on top of that, like, the second thing is how to communicate. Okay. This bounded context will have to communicate with each other. So here, communication, we can do two types, like, sync and async communication. For sync communication, you can use any REST template by calling one service to another service if required, k, or gRPC, that you can use to call different services directly, okay, through their endpoint. But let's say for high scalability, we are choosing to have async communication through a message broker. Okay. So we have introduced a message broker like RabbitMQ or Kafka. That will be used to communicate between these services. So these will be the after that, you have to consider any distributed locking if that is required or request tracking from one service to another service. Here, we can use some of our existing design patterns like saga or CQRS. That kind of design pattern for microservices, we can use. Apart from that, like, you can think of DV. Like, here, you can implement DV for each service. Okay. So that will be independently managed and deployed. Okay. And, yeah, definitely for monitoring and logging, we can use either ELK Stack or any logging or monitoring tool.
In light of the below code snippet, can you find what might be the potential issue with this singleton implementation in Java when it comes to multithreading environment? Okay, so singleton class where single instance of that your class will be maintained throughout that application. And whenever any requirement will happen, that instance only will be served through the your application. Let's say, for example, like logging. Okay. So we are one logger class, and that logger instance only will be used to log different logging throughout the application. So that's the that's the example, singleton. So here, I can say for making the singleton class, like private static singleton instance. So here, I've taken one instance of this singleton class. Now private constructor is there. Okay? So it will not be visible. Now we have one public static singleton get instance. And here, if we are checking instance is equal to is equal to null, then we are creating the new single instance. Okay. And then returning the instance. So here I can see that for the multithreaded environment, let's say we are not here taking the lock of that instance creation. Okay. So for the multithread environment, it is mandatory to have locking mechanic. So one thread, let's say, coming and creating the instance. And by that time, other thread will also come and check that, okay, instance is null. It will also create that instance of your class. Okay. So here, it is mandatory for you to create or take a lock of that instance before lock of the class before you are creating the new instance. Okay. So the modification here I can suggest is you just implement that double check locking mechanic and lock that singleton dot class, synchronize singleton dot class, then you can inside that locking, you can check again that if instance is null, still null, then only you can create that one. Otherwise, you can just close then and return the instance. Okay. So here, modification is that inside this first if instance is called null, check that. Okay. Now check the log, synchronize, singleton dot class or this. Okay. And then you can check again if instance is called is equal to null, still after taking the taking the lock, then you can create the instance and return that instance. Otherwise, whatever the existing instance, you can return. Okay. So here, for multithreaded, we can implement the double check locking. Thank you.
The API endpoint looks little weird over here. Now the thing is, the response entity, create item. Okay. API endpoint should look something like this: POST /items Request body, we are taking the item then response entity dot okay then build. Okay. So okay. What is the thing? Twin point and let's see. The issue might be that the response entity, a int response entity that, we are building might be some logic here. But here I can say, request body, that is coming. We should, use that request body, and then, we should process. Another modification I can say that, if you if it's that, let's say, create item, you just take it in point as a item over here and, do a post request and send that, item body. Okay. And it will, create that item based on that. Okay. So no need to, give that API like a create item over here. And then once you are receiving that item, that, POJO class or a request body, that you can process it and, go to your, other layers. Like, if you have business layers or your DOL layer over here and persist that item, then you can, respond to this method and return to the caller. Okay? So those things, you have to do over here inside this, body. The correct Spring endpoint should be: ```java @PostMapping("/items") public ResponseEntity<Integer> createItem(@RequestBody Item) { // process the item and return the response } ```
What technique would you employ to streamline the processing of massive dataset using a spring and hibernate while avoiding out of memory errors? To handle that, I would recommend using bulk data or something. Use Spring Batch instead of a simple application. So, if your data is really huge, Spring Batch will help you clear the batch of the data and process it. With Java 21, you can use the virtual thread to process a stream of a massive dataset. This virtual thread can be used to process requests within a screen. And to update, let's say, I'm using an ORM to save my request or do any database operations. For each request, we can create one virtual thread and give the task to that. In Java 21, we can create as many virtual threads as needed for operations, and that will be done. And that will be kind of non-blocking. And it has no impact on the OS. Virtual thread is a newer way of creating a thread that does not have an impact on the OS. So, with little memory, we can create virtual threads, and it is non-blocking. Your runtime environment will suspend the virtual thread until it gets a callback. So, it will not have the overhead on the OS. So, for streaming of massive datasets, we can use the newer framework available with the virtual thread. And, yeah, definitely, it will not go out of memory error because we are not using that memory at all, here. In comparison to older threads, we had to know that is the platform thread or let's say OS thread. So as much as you create threads, so that thread has a direct impact on your OS, and it is taking your OS resources. But this new virtual thread is based on your JVM. So, their life cycle will be managed by the JVM, and it is not a heavy resource utilized thread. So, it is very less in memory, and also it's non-blocking. So, I would suggest using virtual threading with that newer technology. If you are not migrated to Java 21 or something, use Spring Batch or batch processing for any massive dataset.
If you ask to improve test coverage for the springboard project, how would you go about prioritizing test cases for critical areas? Okay, so we can use some framework definitely to give us code coverage, such as Cucumber or JACOCO, or even SonarCube to check which areas are critical or per module, and what is our core coverage? So, the code coverage is definitely based on your organization's goals, like how much percentage are you looking for code coverage. In general, we would like to go for 70% and above for all our classes and models. I would suggest using those tools to see where our code coverage is lacking. It's mandatory to write test classes for at least critical areas or critical functionality of your application, so that any changes in the future will be detectable. If you're running regression, deploying, or making changes, any code breaks will be detected, or it will help you detect any code issues in the future if someone modifies that code. For critical sections, we should write test cases and cover at least the critical sections of our project so that our application won't break or lose existing functionality if a user adds a new module or feature. We should cover more than 70%, but at least for critical areas, we should prioritize and do test coverage for that.
What tech would you suggest for ensuring the integrity of a Spring Boot microservice ecosystem communicating over a mix of synchronous and asynchronous channels? Okay, so synchronous channel generally, if we are communicating, then we are using either REST template or gRPC for service to service communication. One service is directly calling the other service, so we can use that directly through the API calling, so that through REST template or just the RPC, we can do that for the sync request. Okay. So another communication, that's async communication, that we can do through message brokers. The message broker is in between the services. One service is done, let's say, their job. It can generate the event and put it into the message broker. Then next service will take the data from that message broker, and it can process that, their part of the job. Let's say I have two services. One service will do some, let's say I'm creating one entity. Okay. So one service will create the entity, and it will after creation or persisting to our DB, it generates the event and puts it to, let's say, a message broker. Let's say, I'm taking Kafka. So it will put that thing into Kafka. Okay? And from Kafka, let's say, our next service, let's say, validation service. So it will fetch the things from Kafka, and it will process that event. Okay. So that event, like, it will be processed, like, their own thing. Like, since this is the validation service, it will validate that persisted data, and it will again further, it can generate the event and forward to the next service. Okay. So for async, we can go as a message broker based communication.