Q1.Difference between Concurrency and Parallelism
Concurrency is when two or more tasks can start, run, and complete in overlapping time periods. It doesn’t necessarily mean they’ll ever both be running at the same instant. For example, multitasking on a single-core machine.In Concurrency Interruptability exists

Parallelism is when tasks literally run at the same time, e.g., on a multicore processor.In Parallelism Independabality exists.

Concurrency                 Concurrency + parallelism
(Single-Core CPU)           (Multi-Core CPU)
 ___                         ___ ___
|th1|                       |th1|th2|
|   |                       |   |___|
|___|___                    |   |___
    |th2|                   |___|th2|
 ___|___|                    ___|___|
|th1|                       |th1|
|___|___                    |   |___
    |th2|                   |   |th2|

In both cases we have concurrency from the mere fact that we have more than one thread running.If we ran this program on a computer with a single CPU core, the OS would be switching between the two threads, allowing one thread to run at a time.If we ran this program on a computer with a multi-core CPU then we would be able to run the two threads in parallel – side by side at the exact same time.

Q2.What is the difference between process and threads
Process:

  1. An executing instance of a program is called a process.
  2. Some operating systems use the term ‘task‘ to refer to a program that is being executed.
  3. A process is always stored in the main memory also termed as the primary memory or random access memory.
  4. Therefore, a process is termed as an active entity. It disappears if the machine is rebooted.
  5. Several process may be associated with a same program.
  6. On a multiprocessor system, multiple processes can be executed in parallel.
  7. On a uni-processor system, though true parallelism is not achieved, a process scheduling algorithm is applied and the processor is scheduled to execute each process one at a time yielding an illusion of concurrency.
  8. Example: Executing multiple instances of the ‘Calculator’ program. Each of the instances are termed as a process.

Thread:

  1. A thread is a subset of the process.
  2. It is termed as a ‘lightweight process’, since it is similar to a real process but executes within the context of a process and shares the same resources allotted to the process by the kernel.
  3. Usually, a process has only one thread of control – one set of machine instructions executing at a time.
  4. A process may also be made up of multiple threads of execution that execute instructions concurrently.
  5. Multiple threads of control can exploit the true parallelism possible on multiprocessor systems.
  6. On a uni-processor system, a thread scheduling algorithm is applied and the processor is scheduled to run each thread one at a time.
  7. All the threads running within a process share the same address space, file descriptors, stack and other process related attributes.
  8. Since the threads of a process share the same memory, synchronizing the access to the shared data within the process gains unprecedented importance.

Q3.Why should I prefer Thread over process?
Inter-thread communication (sharing data etc.) is significantly simpler to program than inter-process communication.
Context switches between threads are faster than between processes. That is, it’s quicker for the OS to stop one thread and start running another than do the same with two processes.

Example:
Applications with GUIs typically use one thread for the GUI and others for background computation. The spellchecker in MS Office, for example, is a separate thread from the one running the Office user interface. In such applications, using multiple processes instead would result in slower performance and code that’s tough to write and maintain.

It entirely depends on the design perspective whether to go for a thread or process. When I want to set of logically co-related operations to be carried out parallel. For example, if you run a Notepad++ there will be one thread running in the foreground as an editor and other thread running in background auto saving the document at regular intervals so no one would design a process to do that autosaving task separately.

Q4.What is the difference between Asynchronous vs synchronous execution?
synchronous – When you execute something synchronously, you wait for it to finish before moving on to another task. You are in a queue to get a movie ticket. You cannot get one until everybody in front of you gets one, and the same applies to the people queued behind you.

asynchronous -When you execute something asynchronously, you can move on to another task before it finishes. i.e. You are in a restaurant with many other people. You order your food. Other people can also order their food, they don’t have to wait for your food to be cooked and served to you before they can order. In the kitchen, restaurant workers are continuously cooking, serving, and taking orders. People will get their food served as soon as it is cooked.

Synchronous (one thread):

Single Thread  |--------A--------||--------B--------|                  

Synchronous (Multi-Threaded):

Thread A |--------A--------|
Thread B                   |--------B--------|
Thread C                                     |--------C--------|

ASynchronous (One thread):

           A-Start ------------------------------------------ A-End   
               | B-Start -----------------------------------------|--- B-End   
	       |    |      C-Start ------------------- C-End      |      |   
	       |    |       |                           |         |      |
  	       V    V       V                           V         V      V      
Single thread->|--A-|---B---|--C-|-A-|-C-|--A--|-B-|--C---|---A---|--B-->|

Asynchronous (Multi-Threaded):

Thread A ->     |----A-----|
Thread B ----->     |-----B-----------| 
Thread C --------->     |-------C----------|

Q5.What is Difference between thread, process and Tasks?
Process
A process is an instance of a computer program that is being executed.a process may be made up of multiple threads of execution that execute instructions concurrently.Process-based multitasking enables you to run the Java compiler at the same time that you are using a text editor. In employing multiple processes with a single CPU,context switching between various memory context is used. Each process has a complete set of its own variables.

Process
A thread is a basic unit of CPU utilization, consisting of a program counter, a stack, and a set of registers. A thread of execution results from a fork of a computer program into two or more concurrently running tasks. The implementation of threads and processes differs from one operating system to another, but in most cases, a thread is contained inside a process. Multiple threads can exist within the same process and share resources such as memory, while different processes do not share these resources.

Tasks
A task is a set of program instructions that are loaded in memory.

Q6.What is Interprocess Communication?
Interprocess communication (IPC) is a set of programming interfaces that allow a programmer to coordinate activities among different program processes that can run concurrently in an operating system. This allows a program to handle many user requests at the same time. Since even a single user request may result in multiple processes running in the operating system on the user’s behalf, the processes need to communicate with each other. The IPC interfaces make this possible. Each IPC method has its own advantages and limitations so it is not unusual for a single program to use all of the IPC methods.

Java interprocess communication is based at the lowest level on turning state, requests, etc into sequences of bytes that can be sent as messages or as a stream to another Java process. You can do this work yourself, or you can use a variety of “middleware” technologies of various levels of complexity to abstract away the implementation details. Technologies that may be used include, Java object serialization, XML, JSON, RMI, CORBA, SOAP / “web services”, message queing, and so on.

Q7.Interprocess Communication vs Inter-Thread Communication?
The fundamental difference is that threads live in the same address spaces, but processes live in the different address spaces. This means that inter-thread communication is about passing references to objects and changing shared objects, but processes is about passing serialized copies of objects.In practice, Java interthread communication can be implemented as plain Java method calls on a shared object with appropriate synchronization thrown in.

Inter-Thread Communication = threads inside the same JVM talking to each other.Threads inside the same JVM can use pipelining through lock-free queues to talk to each other with nanosecond latency.

Inter-Process Communication (IPC) = threads inside the same machine but running in different JVMs talking to each other.Threads in different JVMs can use off-heap shared memory (usually acquired through the same memory-mapped file) to talk to each other with nanosecond latency.

Q8.What is Starvation?
Starvation describes a situation where a thread is unable to gain regular access to shared resources and is unable to make progress. This happens when shared resources are made unavailable for long periods by “greedy” threads. For example, suppose an object provides a synchronized method that often takes a long time to return. If one thread invokes this method frequently, other threads that also need frequent synchronized access to the same object will often be blocked.

Q9.What is Livelock?
A thread often acts in response to the action of another thread. If the other thread’s action is also a response to the action of another thread, then livelock may result. As with deadlock, livelocked threads are unable to make further progress. However, the threads are not blocked — they are simply too busy responding to each other to resume work. This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. Seeing that they are still blocking each other, Alphone moves to his right, while Gaston moves to his left. They’re still blocking each other, so…

Q10.Preemptive vs Non-Preemptive Scheduling
Scheduling is order of executuion of threads. JVM would simply use the underlying threading mechanism provided by the OS.
Non-preemptive Scheduling: The current process releases the CPU either by terminating or by switching to the waiting state. (Used in MS Windows family)

Advantages are Decreases turnaround time and Does not require special HW (e.g., timer)
Disadvantages are Limited choice of scheduling algorithm

Preemptive Scheduling: The current process needs to involuntarily release the CPU when a more important process is inserted into the ready queue or once an allocated CPU time has elapsed. (Used in Unix and Unix-like systems).This is determined by priority assigned to thread.Despite priority JVM may decide to execute thread of lower priority inorder to avoid starvation.

Advantages are No limitation on the choice of scheduling algorithm
Disadvantages are Additional overheads (e.g., more frequent context switching, HW timer, coordinated access to data, etc.)

Q10.
Q11.
Q12.
Q13.
Q14.

Spring MVC uses HttpMessageConverter to convert the Http request to an object representation and back.Spring Framework then uses one of the Jackson message converters to marshall and unmarshall Java Objects to and from JSON over HTTP.Spring will use the “Accept” header to determine the media type that it needs to respond with and uses the “Content-Type” header to determine the media type of the request body.

Default Message Converters in Spring MVC
StringHttpMessageConverter: it converts Strings from the HTTP request and response.
FormHttpMessageConverter: it converts form data to/from a MultiValueMap.
ByteArrayHttpMessageConverter: it converts byte arrays from the HTTP request and response.
MappingJackson2HttpMessageConverter: it converts JSON from the HTTP request and response.
Jaxb2RootElementHttpMessageConverter: it converts Java objects to/from XML.
SourceHttpMessageConverter: it converts javax.xml.transform.Source from the HTTP request and response.
AtomFeedHttpMessageConverter: it converts Atom feeds.
RssChannelHttpMessageConverter: it converts RSS feeds.

Customizing HttpMessageConverters with Spring MVC

Annotation Usage
@RequestMapping
@RequestMapping(value = "/{name}", 
                method = RequestMethod.GET, 
                consumes="application/json"
                produces ="application/json",
                headers={"name=pankaj", "id=1"})
path (or) (or) name (or) and value: which URL the method is mapped to
method: compatible HTTP methods
params: filters requests based on presence, absence, or value of HTTP parameters
headers: filters requests based on presence, absence, or value of HTTP headers
consumes: which media types the method can consume in the HTTP request body
produces: which media types the method can produce in the HTTP response body
@RequestBody
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public HttpStatus something(@RequestBody MyModel myModel) 
{
    return HttpStatus.OK;
}
with @RequestBody, Spring will bind the incoming HTTP request body(for the URL mentioned in @RequestMapping for that method) to that parameter. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the HTTP request body into domain object [deserialize request body to domain object], based on Accept header present in request.
@ResponseBody
@RequestMapping(value = "/user/all", method = RequestMethod.GET)
public @ResponseBody List<User> listAllUsers() {
    return userService.findAllUsers();
}
with @ResponseBody, Spring will bind the return value to outgoing HTTP response body. While doing that, Spring will [behind the scenes] use HTTP Message converters to convert the return value to HTTP response body [serialize the object to response body], based on Content-Type present in request HTTP header
@RequestParam
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20

public String getDetails(
    @RequestParam(value="param1", required=true) String param1,
        @RequestParam(value="param2", required=false) String param2){
...
}
@RequestParam is to obtain an parameter from the URI as well.@RequestParam annotation used for accessing the query parameter values from the request
defaultValue – This is the default value as a fallback mechanism if request is not having the value or it is empty.
name – Name of the parameter to bind
required – Whether the parameter is mandatory or not. If it is true, failing to send that parameter will fail.
value – This is an alias for the name attribute
@PathVariable
'http://localhost:8080/springmvc/hello/101?param1=10&param2=20

@RequestMapping("/hello/{id}")    public String getDetails(@PathVariable(value="id") String id,
    @RequestParam(value="param1", required=true) String param1,
    @RequestParam(value="param2", required=false) String param2){
.......
}

@GetMapping("/user/{firstName}/{lastName}")
   @ResponseBody
   public String handler(@MatrixVariable("firstName") String firstName,
         @MatrixVariable("lastName") String lastName
         ) {

      return "<br>Matxrix variable <br> "
            + "firstName =" + firstName +"<br>"
            + "lastName =" + lastName;
   }
@PathVariable is to obtain some placeholder from the URI
@MatrixVariable – a name-value pair within a path segment is referred as matrix variable. Matrix variables can appear in any path segment, each variable separated with a semicolon (;) and multiple values are separated by comma (,)
i.e.
http://www.example.com/employee/Mike;salary=45000;dept=HR
http://www.example.com/car/Audi;color=RED,BLACK,WHITE

@RequestHeader
@Controller
public class HelloController {
 @RequestMapping(value = "/hello.htm")
 public String hello(
   @RequestHeader(value="Accept") String accept,
   @RequestHeader(value="Accept-Language") String acceptLanguage,
   @RequestHeader(value="User-Agent", defaultValue="foo") String userAgent,
   HttpServletResponse response) {

  System.out.println("accept: " + accept);
  System.out.println("acceptLanguage: " + acceptLanguage);
  System.out.println("userAgent: " + userAgent);
  
  return null;
 }
}
Reading http requestheader is written in HelloController
The advantage of using Spring @RequestHeader is that it will automatically throw an exception like HTTP Status 400 – Missing request header ‘X’ for method parameter of type, if the header is NOT sent in the input request (by setting required=true)

@RequestHeader for facilitating use to get the header details easily in our controller class

GET

  1. GET is idempotent and can be requested any number of times
  2. GET requests can be cached, can be distributed & shared
  3. GET request is less secured compared to POST.

POST

  1. Used to Create a resource
  2. Post is not idempotent.x++ is not idempotent
  3. POST is NOT idempotent. So if you retry the request N times, you will end up having N resources with N different URIs created on server.

PUT

  1. Used to Create or Modify a resource
  2. PUT is idempotent, so if you PUT an object twice, it has no effect.
  3. x=5 is idempotent.You can PUT a resource whether it previously exists, or not (eg, to Create, or to Update)!

When to use Put and Post
You can use both PUT or POST for creating the resource until the client decides the resource location in the Server.But if the server decides the resource location using

POST /questions/ HTTP/1.1
Host: www.example.com/

Note that the following is an error:

POST /questions/ HTTP/1.1
Host: www.example.com/

If the URL is not yet created, you should not be using POST to create it while specifying the name. This should result in a ‘resource not found’ error because does not exist yet. You should PUT the resource on the server first.

You could though do something like this to create a resources using POST:

POST /questions HTTP/1.1
Host: www.example.com/

Note that in this case the resource name is not specified, the new objects URL path would be returned to you.

PUT is Used to create a resource, or overwrite it. While you specify the resources new URL.

PUT /questions/ HTTP/1.1
Host: www.example.com/

To overwrite an existing resource:

PUT /questions/ HTTP/1.1
Host: www.example.com/

PATCH
Patch request says that we would only send the data that we need to modify without modifying or effecting other parts of the data. Ex: if we need to update only the first name, we pass only the first name.PATCH – HTTP.PATCH can be used when the client is sending one or more changes to be applied by the server. The PATCH method requests that a set of changes described in the request entity be applied to the resource identified by the Request-URI. The set of changes is represented in a format called a patch document.

In PUT request, the enclosed entity would be considered as the modified version of a resource which residing on server and it would be replaced by this modified entity.

In PATCH request, enclosed entity contains the set of instructions that how the entity which residing on server, would be modified to produce a newer version.

DELETE

DELETE is pretty easy to understand. It is used to delete a resource identified by a URI.On successful deletion, return HTTP status 200 (OK) along with a response body, perhaps the representation of the deleted item (often demands too much bandwidth), or a wrapped response (see Return Values below). Either that or return HTTP status 204 (NO CONTENT) with no response body. In other words, a 204 status with no body, or the JSEND-style response and HTTP status 200 are the recommended responses.

  1. Caching is the ability to store copies of frequently accessed data in several places along the request-response path. When a consumer requests a resource representation, the request goes through a cache or a series of caches (local cache, proxy cache or reverse proxy) toward the service hosting the resource.
  2. If any of the caches along the request path has a fresh copy of the requested representation, it uses that copy to satisfy the request. If none of the caches can satisfy the request, the request travels all the way to the service (or origin server as it is formally known).
  3. Using HTTP headers, an origin server indicates whether a response can be cached and if so, by whom, and for how long. Caches along the response path can take a copy of a response, but only if the caching metadata allows them to do so.
  4. Few are the advantages of Caching
    • Reduce bandwidth
    • Reduce latency
    • Reduce load on servers
    • Hide network failures
  5. GET requests are cachable by default – until special condition arises. Usually, browsers treat all GET requests cacheable.
  6. POST requests are not cacheable by default but can be made cacheable if either an Expires header or a Cache-Control header with a directive, to explicitly allows caching, is added to the response. Responses to PUT and DELETE requests are not cacheable at all.

There are two main HTTP response headers that we can use to control caching behavior:
Expires : The Expires HTTP header specifies an absolute expiry time for a cached representation. Beyond that time, a cached representation is considered stale and must be re-validated with the origin server. To indicate that a representation never expires, a service can include a time up to one year in the future.

Expires: Wed, 6 March 2019 15:09:49 IST

Cache-Control:
The header value comprises one or more comma-separated directives. These directives determine whether a response is cacheable, and if so, by whom, and for how long e.g. max-age or s-maxage directives.

Cache-Control: max-age=3600
ETag: "abcd1234567n34jv"
(or)
Last-Modified: Fri, 10 May 2016 09:17:49 IST

Cacheable responses (whether to a GET or to a POST request) should also include a validator — either an ETag or a Last-Modified header.

ETag
An ETag value is an opaque string token that a server associates with a resource to uniquely identify the state of the resource over its lifetime. When the resource changes, the ETag changes accordingly.

Last-Modified
Whereas a response’s Date header indicates when the response was generated, the Last-Modified header indicates when the associated resource last changed. The Last-Modified value cannot be later than the Date value.

Supplier Accounts.java

@FunctionalInterface
public interface Accounts{
  abstract String showAccountType(); 
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = () -> "Hi there";
  System.out.println(squareRoot.showAccountType());
 }
}
public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public String showAccountType() {
    return "Hi there";
   }
  };
  System.out.println(squareRoot.showAccountType());
 }
}
Consumer Accounts.java

@FunctionalInterface
public interface Accounts {
 abstract void showAccountType(String strAccType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = (strAccType) -> System.out.println(strAccType);
  squareRoot.showAccountType("Savings");
 }
}

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public void showAccountType(String strAccType) {
    System.out.println(strAccType);
   }
  };
 }
}
Predicate Accounts.java

@FunctionalInterface
public interface Accounts{
  abstract boolean showAccountType(String accountType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = (accountType) -> {
   if ("Savings" == accountType)
    return true;
   else
    return false;
  };

  if (squareRoot.showAccountType("Savings"))
   System.out.println("Savings");
  else
   System.out.println("Invalid Account");
 }
}
public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public boolean showAccountType(String accountType) {
    if ("Savings" == accountType)
     return true;
    else
     return false;
   }
  };

  if (squareRoot.showAccountType("Savings"))
   System.out.println("Savings");
  else
   System.out.println("Invalid Account");   
 }
}
Function Accounts.java

@FunctionalInterface
public interface Accounts  
{
 abstract String showAccountType(String accountType, String returnAccType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = (accountType, returnType) -> {
   if (accountType == "Savings")
    return "Credit";
   else
    return "Debit";
  };

  System.out.println(squareRoot.showAccountType("Savings", null));
 }
}
public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public String showAccountType(String accountType, String returnAccType) {

    if (accountType == "Savings")
     return "Credit";
    else
     return "Debit";
   }
  };

  System.out.println(squareRoot.showAccountType("Savings", null));
 }
}
Urnary Operator Accounts.java

@FunctionalInterface
public interface Accounts{
 abstract String showAccountType(String accountType);
}

AccountImpl.java

public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = (accountType) -> {
   return "AccountType is " + accountType;
  };
  squareRoot.showAccountType("Savings");
 }
}
public class AccountImpl {
 public static void main(String[] args) {
  Accounts squareRoot = new Accounts() {
   @Override
   public String showAccountType(String accountType) {
    return "AccountType is " + accountType;
   }
  };

  System.out.println(squareRoot.showAccountType("Savings"));
 }
}
  1. Optional is a wrapper class which makes a field optional which means it may or may not have values.
  2. ptional as a single-value container that either contains a value or doesn’t (it is then said to be “empty”)
  3. The advantage compared to null references is that the Optional class forces you to think about the case when the value is not present. As a consequence, you can prevent unintended null pointer exceptions.
  4. The intention of the Optional class is not to replace every single null reference. Instead, its purpose is to help design more-comprehensible APIs so that by just reading the signature of a method, you can tell whether you can expect an optional value. This forces you to actively unwrap an Optional to deal with the absence of a value.

Lets take the below code

String version = computer.getSoundcard().getUSB().getVersion();

In the above piece of java code if any of the 3 values other the Version is NULL will throw a null pointer exception. To prevent this lets add a null check

String version = "UNKNOWN";
if(computer != null){
  Soundcard soundcard = computer.getSoundcard();
  if(soundcard != null){
    USB usb = soundcard.getUSB();
    if(usb != null){
      version = usb.getVersion();
    }
  }
}

Now the above code has become Clumsy with less readability and lot of boilerplate code has been added.
In languages like Groovy these conditions could be handles like one below

String version = computer?.getSoundcard()?.getUSB()?.getVersion();
(or)
String version = 
    computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";

Now lets replace the above code with new Optional in Java 8

public class Computer {
  private Optional<Soundcard> soundcard;  
  public Optional<Soundcard> getSoundcard() { ... }
  ...
}

public class Soundcard {
  private Optional<USB> usb;
  public Optional<USB> getUSB() { ... }

}

public class USB{
  public String getVersion(){ ... }
}

The advantage compared to null references is that the Optional class forces you to think about the case when the value is not present. As a consequence, you can prevent unintended null pointer exceptions.

What is the Point of Optional when the same could be done using NULL Check?
If you are doing NULL check the traditional way there would be no much difference. However, the difference is felt when you are carrying out chaining operations in streams and the datatypes returned are optional.The difference may not be significant in this case but as the chain of objects increases e.g. person.getAddress.getCity().getStreet().getBlock(),

Methods in Optional
get()
If a value is present in this Optional, returns the value, otherwise throws NoSuchElementException

void ifPresent(Consumer consumer)
If a value is present, it invokes the specified consumer with the value, otherwise does nothing.

boolean isPresent()
Returns true if there is a value present, otherwise false.

static Optional ofNullable(T value)
Returns an Optional describing the specified value, if non-null, otherwise returns an empty Optional.

T orElse(T other)
Returns the value if present, otherwise returns other.

T orElseGet(Supplier other)
Returns the value if present, otherwise invokes other and returns the result of that invocation.

orElseThrow(Supplier exceptionSupplier)
Returns the contained value, if present, otherwise throws an exception to be created by the provided supplier.

Lets take a simple example where Optional returns Empty or Value based on some Condition

package com.example.demo;
import java.util.Optional;
public class Test {

 public static void main(String[] args) {
  //IfPresent
  Optional < String > strOpt = getName(" Piggy");
  System.out.print("First Call -");
  strOpt.ifPresent(System.out::println);


  Optional < String > strOpt2 = getName("");
  System.out.print("Second Call -");
  strOpt2.ifPresent(System.out::println);

  System.out.println();

  //IsPresent and get
  Optional < String > strOpt3 = getNewName(" Biggy");
  System.out.print("Third Call -");

  if (strOpt3.isPresent())
   System.out.println(strOpt3.get());


  //orElse
  Optional < String > strOpt4 = getNewName(null);
  System.out.print("Fourth Call -");
  System.out.println(strOpt4.orElse(" Hippi"));


 }

 public static Optional < String > getName(String strName) {
  if (strName.length() > 0)
   return Optional.of(strName);
  else
   return Optional.empty();
 }

 public static Optional < String > getNewName(String strName) {
  //Optional strNewName = (strName!=null)?Optional.of(strName):Optional.empty();
  return Optional.ofNullable(strName);
 }
}

Output

First Call - Piggy
Second Call -
Third Call - Biggy
Fourth Call - Hippi

@RequestBody, spring will try to convert the content of the incoming request body to your parameter object on the fly.@ResponseBody, spring will try to convert its return value and write it to the http response automatically

@Controller
@RequestMapping(value = "/bookcase")
public class BookCaseController 
{ 
    private BookCase bookCase;
 
    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public BookCase getBookCase() {
        return this.bookCase;
    }
 
    @RequestMapping(method = RequestMethod.PUT)
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void setBookCase(@RequestBody BookCase bookCase) {
        this.bookCase = bookCase;
    } 
}

Depending on your configuration, spring has a list of HttpMessageConverters registered in the background. A HttpMessageConverters responsibility is to convert the request body to a specific class and back to the response body again, depending on a predefined mime type. Every time an issued request is hitting a @RequestBody or @ResponseBody annotation spring loops through all registered HttpMessageConverters seeking for the first that fits the given mime type and class and then uses it for the actual conversion.

Refer here

A Bean definition contains the following piece of information called configuration metadata, which helps the container know the following things.

• The way a bean should be created.
• Life cycle details of a bean.
• Associated Bean dependencies.

The above metadata for the bean configuration is provided as a set of properties or attributes in an XML file (configuration file) which together prepare a bean definition. The following are the set of properties.

Properties Usage
class In a bean definition, it is a mandatory attribute. It is used to specify the bean class which can be used by the container to create the bean.
name In a bean definition, this attribute is used to specify the bean identifier uniquely. In XML based configuration metadata for a bean, we use the id and/or name attributes in order to specify the bean identifier(s).
scope This attribute is used to specify the scope of the objects which are created from a particular bean definition.
constructor-arg In a bean definition, this attribute is used to inject the dependencies.
properties In a bean definition, this attribute is used to inject the dependencies.
autowiring mode In a bean definition, this attribute is used to inject the dependencies.
lazy-initialization mode In a bean definition, a lazy-initialized bean informs the IoC container to create a bean instance only when it is first requested, instead of startup.
initialization method In a bean definition, a callback to be called after all required properties on the bean have been set up by the container.
destruction method In a bean definition, a callback to be used when the container that contains the bean is destroyed.

In the following example, we are going to look into an XML based configuration file which has different bean definitions. The definitions include lazy initialization (lazy-init), initialization method (init-method), and destruction method (destroy-method) as shown below. This configuration metadata file can be loaded either through BeanFactory or ApplicationContext

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- A simple bean definition -->
   <bean id = "..." class = "...">
      <!— Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has lazy init set on -->
   <bean id = "..." class = "..." lazy-init = "true">
      <!-- Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has initialization method -->
   <bean id = "..." class = "..." init-method = "...">
      <!-- Here will be collaborators and configuration for this bean -->
   </bean>

   <!-- A bean definition which has destruction method -->
   <bean id = "..." class = "..." destroy-method = "...">
      <!-- collaborators and configuration for this bean go here -->
   </bean>

   <!-- more bean definitions can be written below -->
   
</beans>

Method reference is used to refer method of functional interface. It is compact and easy form of lambda expression. Each time when you are using lambda expression to just referring a method, you can replace your lambda expression with method reference.

3 types of method references:

  1. Reference to a static method
  2. Reference to an instance method
  3. Reference to a constructor

Reference to a static method
Syntax

  ClassName::MethodName
import java.util.function.BiFunction;
class Arithmetic 
 {
 public static int add(int a, int b) 
 {
  return a + b;
 }
}
public class MethodReference 
{
 public static void main(String[] args) 
 {
  BiFunction < Integer, Integer, Integer > adder = Arithmetic::add;
  int result = adder.apply(10, 20);
  System.out.println(result);
 }
}

Reference to an instance method
Syntax

Object::methodName
import java.util.function.BiFunction;
class Arithmetic 
 {
 public int add(int a, int b) 
 {
  return a + b;
 }
}
public class MethodReference 
{
 public static void main(String[] args) 
 {
  Arithmetic objArithmetic = new Arithmetic();
  BiFunction < Integer, Integer, Integer > adder = objArithmetic::add;
  int result = adder.apply(10, 20);
  System.out.println(result);
 }
}

Reference to a constructor
Syntax

ClassName::new  
interface Messageable {
 Message getMessage(String msg);
}
class Message {
 Message(String msg) {
  System.out.print(msg);
 }
}
public class ConstructorReference {
 public static void main(String[] args) {
  Messageable hello = Message::new;
  hello.getMessage("Hello");
 }
}