Concept Discussion II - Neethahiremath/Wiki GitHub Wiki
Class can be made immutable:
-
Make your class final, so that no other classes can extend it.
-
Make all your fields final, so that they’re initialised only once inside the constructor and never modified afterward.
-
Don’t expose setter methods.
-
When exposing methods which modify the state of the class, you must always return a new instance of the class.
-
If the class holds a mutable object:
- Inside the constructor, make sure to use a clone copy of the passed argument and never set your mutable field to the real instance passed through constructor, this is to prevent the clients who pass the object from modifying it afterwards.
- Make sure to always return a clone copy of the field and never return the real object instance.
Fail Fast and Fail safe:
Different blocks and their order of execution in Java Class
Static Block Init Block(Anonymous Block) Constructor
public class test1 {
{
System.out.println("parent Inside Ananymous Block");
}
static {
System.out.println("parent Inside Static Block");
}
test1() {
System.out.println("parent Inside Constructor of Class");
}
}
public class test extends test1{
{
System.out.println("child Inside Ananymous Block");
}
/*
* Now Creating the Static Block in Class
*/
static {
System.out.println("child Inside Static Block");
}
/*
* Here Creating the Constructor of Class
*/
test() {
System.out.println("child Inside Constructor of Class");
}
public static void main(String[] args) {
test obj = new test();
}
}
output:
parent Inside Static Block
child Inside Static Block
parent Inside Ananymous Block
parent Inside Constructor of Class
child Inside Ananymous Block
child Inside Constructor of Class
Comparable and Comparator both are interface:
class should implement comparable and override comapreTo -> this takes single parameter and compare with "this" class should implement Comparator and override compare -> takes two parameter
priority Queue:
use poll or peek to see the data in sorted form. if you use object, use the comparator
public static void main(String[] args) {
PriorityQueue<Integer> ob = new PriorityQueue<>(10, Integer::compareTo);
ob.add(8);
ob.add(5);
ob.add(3);
while (ob.iterator().hasNext()) {
System.out.print(ob.poll());
}
}
Executor Services: Java Thread Pool Framework
https://pramodshehan.medium.com/executor-service-java-thread-pool-framework-d314b12ca043
This is collection of threads on which task can be scheduled. Instead of creating new threads for each task, select a thread from the thread pool and execute that task.
ThreadPoolExecutor is actual implementation of ThreadPool. You can create ThreadPoolExecutor from factory methods of Executor class.
There are four factory methods of Executor class.
- newFixedThreadPool
- newCachedThreadPool
- newSingleThreadedExecutor
- newScheduledThreadPool
When we create FixedThreadPool, it has fixed number of threads. In here we submit the tasks to exector. All the submitted tasks are stored in particular queue. This queue is thread safe(blocking queue). All the threads fetch tasks from the queue. If one thread is finished task, it fetch next task from the queue and execute it.
If you need to schedule the task after certain delay, this is the thread pool for it. If you need a check security check, login check within every 10 seconds, we can use scheduled thread pool. There are three methods to schedule a task, schedule scheduleAtFixedRate scheduleAtFixedDelay
Single Threaded Executor Here, only one thread is using in the thread pool. All the tasks are keeping in blocking queue. After finishing task, it fetch new task from the queue and execute it.
https://medium.com/codex/executorservice-internal-working-in-java-7b286882f54e
CorePoolSize MaximumPoolSize
So the Rules when a new task arrives is: a. If fewer than CorePoolSize threads are running, the Executor always prefers creating a new thread rather than queuing. b. If CorePoolSize or more threads are running, the Executor always prefers queuing a request rather than creating a new thread. c. If a request cannot be queued, a new thread is created unless this would exceed maximumPoolSize, in which case, the task will be rejected.
forkJoinPool:
@Bean(name = UtilityConstants.CUSTOM_THREADPOOL_NAME)
public ExecutorService forkJoinPool() {
return Executors.newWorkStealingPool(commonPoolSize);
}
https://www.geeksforgeeks.org/producer-consumer-solution-using-threads-java/
linkedHashMap use doublyLinkedList for maintaining the order.
Docker:
FROM (base jdk image path)
WORKDIR /app
# The application's jar file
#The application's jar file
ARG microServName
ARG version
ARG packaging
ARG JAR_FILE=target/${microServName}-${version}.${packaging}
# Add the application's jar to the container
ADD ${JAR_FILE} inventory-reservation-service.jar
COPY src/main/resources/folder/* /app/folder/dev/
RUN apk update && apk add libc6-compat
RUN adduser -u 10001 -S eihadm
RUN chown -R 10001 /app/
USER 10001
EXPOSE 8080
ENTRYPOINT java -jar -Djava.security.egd=file:/dev/./urandom /app/service.jar
Kubernetes:
- master slave architecture
- worker nodes having kubelet for communicating between k8 cluster
master has below components:
-
API server: entry point for (UI,CLI,API) request will be in YML or json format
-
Controller manager: managing if any container goes down, restart
-
Scheduler: this schedules the container run in worker thread
-
etcd: k8 current status and all the activities so that we can take backup
-
worker thread and master connects with virtual network
-
pod: smallest unit like a virtual server contains multiple container inside
-
1 pod per application
-
each pod have IP address and they can interact with each other (diff pod)
-
if pod dies, new will be replaced and it gets new IP address. this will create issue if IP is hard coded, service is introduced. this will have permanent IP and load balance URL that can be used to communicate between the pods.
-
container inside pod will be handled by k8 without our intervention. if container dies it gets automatically restarted.
auto configure data from k8 maps:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-config</artifactId>
</dependency>
in bootstrap.yml
spring:
application:
name: service
profiles:
include: kubernetes
cloud:
kubernetes:
config:
enabled: true
namespace: ns
sources:
- name: configmap
reload:
enabled: true
strategy: refresh
property that is annotated with @ConfigurationProperties()
prometheus:
https://www.youtube.com/watch?v=h4Sl21AKiDg
management:
endpoints:
web:
base-path: /actuator
exposure:
include: ["configprops", "env", "metrics", "prometheus", "health", "info", "threaddump"]
info:
git:
mode: full
metrics:
enabled: true
export:
prometheus:
enabled: true
web:
server:
auto-time-requests: false
distribution:
percentiles:
all: 0.9, 0.95, 0.99
prometheus:
enabled: true
prometheus server consist of 3 things: Data Retrieval workers pulls metrics data store data in time series DB accepts the promQL queries and give the results.-> used by UI, grafana
human readable format of TYPE and HELP TYPE -> counter, gauge and histogram
when we expose /metrics data that might not be in the proper format which data retrieval workers read. you can use the exporters that will read the data from /metrics and expose own set of /metrics that can be directly read by workers.