The default method in Interfaces was introduced in Java 8. It allows the interface to implement a method in the interface which is inherited by implementing classes.
The default method in Interfaces was introduced in Java 8. It allows the interface to implement a method in the interface which is inherited by implementing classes.
What are default methods?
Before Java 8 methods in the interface could have only public and abstract modifiers for methods and public, static
and for fields public and static or blank (blank means public and static field).
Java 5
Following are two interfaces in Java 5, the first one is valid and the second one is not.
Valid Interface in Java 5
interface Java5Interface {
public static int four = 4;
int five = 5; // implicitly public static
public abstract void welcome();
public void sayHi();
void bye();
}
Invalid Interface in Java 5
interface Java5Invalid {
private int six = 6; //illegal only public static and final is permitted
private void cleanuup(); // illegal only public and abstract is permitted
}
As you can see for fields only public, static, and final modifiers are allowed. If nothing is mentioned then also all fields in Java 5 is public static and final implicitly.
For methods, we can have only public and abstract as modifiers.
Java 8 and onwards
Starting Java 8 methods in the interface can have the following modifiers public, private, abstract, default, static, strictfp.
Nothing changes for fields, fields can still have public, static, final modifiers.
In the following example, we have a Greetings Interface with two default methods greet and openDoor respectively. This interface also has one static method lockdoor.
Interface Greetings in Java 8
interface Greetings {
public default void greet() {
openDoor();
sayHi();
sayBye();
closeDoor();
}
default void openDoor() {
//open the door
}
void sayHi();
void sayBye();
private void closeDoor() {
lockDoor();
}
static void lockDoor() {
//lock door implementation
}
}
The benefit of having a default method is that now the interface can provide a default implementation of methods through the default modifier. For instance, the interface Greetings provided a default implementation for method greet().
Also the later we can add more default, private or static methods to the Interface without breaking binary compatibility meaning implementing classes don't need to do any modification to be able to compile and run successfully.
Importat Points
default methods are public.
default methods are inherited by implementation classes.
default methods can be overridden by implementation classes.
a default method can add more functionality to the Interface without breaking binary compatibility.
static methods are also allowed which are Interface level methods and cannot be overridden by subclasses.
Java 8 methods can have public, private, abstract, default, static, and strictfp.
In this article, we will examine different ways to write Comparators in java to sort the multidimensional arrays. Comparator is a functional interface in java.
In this article, we will examine different ways to write Comparators in java to sort the multidimensional arrays. Comparator is a functional interface in java.
java.util.Arrays class contains various utility methods to manipulate arrays one of the important methods is Sort.
This method takes two parameters the array that needs to be sorted and the optional Comparator. If we don't pass the Comparator then the array will be sorted based on the natural ordering of the elements.
Sorting Array
Our Array
Let's say we want to represent multiple points with x,y coordinates in an array. The following represents one such example.
{ { 20, 25 },{ 10, 15 }, { 10, 25 }, { 20, 15 }}
We want to sort the array based on x and y-axis values.
Comparators
Comparator Implementation as a Class
Here we are implementing a Comparator called MultiDimArrayComparator and then we can use this comparator to sort Array
class MultiDimArrayComparator implements Comparator {
@Override
public int compare(int[] m, int[] n) {
return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
}
}
Arrays.sort(arr, new MultiDimArrayComparator());
Comparator as an anonymous class
Here we are implementing Comparator as an anonymous class and providing a definition of compare method.
Arrays.sort(arr, new Comparator() {
@Override
public int compare(int[] m, int[] n) {
return m[0] == n[0] ? m[1] - n[1] : m[0] - n[0];
}
});
Comparator as lambda expression (Java 8+)
Here we are implementing Comparator as a lambda function.
While implementing AWS lambda functions in java we need to implement a Handler interface . The lambda environment will invoke the implementation of the Handler interface.
While implementing AWS lambda functions in java we need to implement a Handler interface . The lambda environment will invoke the implementation of the Handler interface.
The Handler interface is a functional interface It has just one method that needs to be implemented. Broadly speaking AWS supports two different types of handlers.
Following are the two interfaces that can be chosen to implement the handler.
The aws-lambda-java-core library defines two interfaces for handler methods.
com.amazonaws.services.lambda.runtime.RequestHandler
com.amazonaws.services.lambda.runtime.RequestStreamHandler
Choosing the right handler
Choosing the right Handler depends on the use cases. If we are working with simple Objects as input like String, Integer, Map, etc then RequestHandler is a good choice. If we want to work with more complicated input/output objects or we want to control the way the input and output get converted to String then RequestStreamHandler is the option.
RequestHandler
This interface is a generic interface. The handleRequest method takes two objects as input and also returns an object. The java runtime in the lambda environment deserializes and serializes input event and returned object from the method
public interface RequestHandler {
/**
* Handles a Lambda Function request
* @param input The Lambda Function input
* @param context The Lambda execution environment context object.
* @return The Lambda Function output
*/
public O handleRequest(I input, Context context);
}
RequestStreamHandler
This handler works with InputStream and OutputStream. It gives more control over how we want to perform the serialization/deserialization etc.
public interface RequestStreamHandler {
/**
* Handles a Lambda Function request
* @param input The Lambda Function input stream
* @param output The Lambda function output stream
* @param context The Lambda execution environment context object.
* @throws IOException
*/
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException;
}
Summary
RequestStreamHandler : If we need to customize the serialization and deserialization process then RequestStreamHandler is the choice.
RequestHandler: It is the most suitable handler in most cases.
Maven builds a project using its project object model (POM) and a set of plugins. Dependencies used by the project are mentioned in the pom.xml file. We can also get the dependencies artifact from maven along with source codes.
How to download source for maven artifacts
Maven builds a project using its project object model (POM) and a set of plugins. Dependencies used by the project are mentioned in the pom.xml file. We can also get the dependencies artifact from maven along with source codes.
In the following section, we will cover two use cases
1) How to generate source code for third-party artifacts that my project is using
2) How to generate source code for my project
Download sources for third party artifacts
Executing the following command from the terminal will download the sources for all the artifacts for the project and will attach it to Eclipse IDE.
mvn eclipse:eclipse -DdownloadSources=true
Executing the following command from the terminal will download the sources for all the artifacts only, attaching the sources in the IDE with the binaries needed to be done seperately..
mvn dependency:sources -Dsilent=true
Generate source code for project
This command will generate the sources jar under the target folder for the project.
This article summarizes different ways to use the Random() class in java to generate bounded or unbounded random numbers. It also shows another important feature of the class that is using seed to generate same set of random numbers.
Generating Random Number in Java
This article summarizes different ways to use the Random() class in java to generate bounded or unbounded random numbers. It also shows another important feature of the class that is using seed to generate same set of random numbers.
java.util.Random used used to generate bounded or unbounded random numbers. It supports specifying a seed which is used to set the internal state of the pseudorandom number generator.
Random(): creates new random generator
Random(long seed): creates new random generator using specified seed
Unbounded generate 5 random numbers
Following code prints 5 random numbers unbounded without any seed
public static void generateRadom() {
System.out.println("\nPrinting 10 Random Numbers");
Random generator = new Random();
for (int i = 0; i < 5; i++) {
System.out.print(generator.nextInt() + " ");
}
}
Invocation 1
Printing 5 Random Numbers
-1937915077 75383412 -901884443 1725835531 1371480362
Invocation 2
Printing 5 Random Numbers
-1261854044 328673857 -1787159304 446964878 -283294822
Notice that in both the invocations the generated numbers are different. This is because we have not set any seed in the Random Class.
Random Bounded Number
Following method will generate 5 random numbers between 0 and 99
public static void generateRadomBounded() {
System.out.println("\nPrinting 5 Random Numbers Between 0 and 99");
Random generator = new Random();
for (int i = 0; i < 5; i++) {
System.out.print(generator.nextInt(100) + " ");
}
}
Invocation 1
Printing 5 Random Numbers Between 0 and 99
25 95 13 60 67
Invocation 2
Printing 5 Random Numbers Between 0 and 99
17 10 21 96 15
Generate Random number bounded with a seed
Bellow function will generate bounded 5 random numbers but since we are setting a seed, if the seed is same on multiple invocation then each invocation will generate the same set of random numbers.
public static void generateRadomWithSeed(long seed) {
System.out.println("\nPrinting 5 Random Numbers Between 0 and 99 with seed");
Random generator = new Random(seed);
for (int i = 0; i < 5; i++) {
System.out.print(generator.nextInt(100) + " ");
}
}
Invocation 1
Printing 5 Random Numbers Between 0 and 99 with seed 4
62 52 3 58 67
Invocation 2
Printing 5 Random Numbers Between 0 and 99 with seed 4
62 52 3 58 67
Summary
If we want to generate the same set of random numbers, we can set seed.
Test cases can use seed to make sure it gets same set of random numbers.
Sometimes we want to remove the reference to existing repository details, such as cloned from github so that we can check the code in a different git repository or a different version control system. This article covers the steps that we can take to remove git references.
If we clone a repo or fork a repo from git, the newly created repository will have git references as version control. If we want to remove the git references from the new repository then we need to delete all the git references. Once we remove the git references then it will not have any reference to old repository and we can use this project folder to create a brand new repository in git or any other version control system. This article talks about how to remove
Sometimes we want to remove the reference to existing repository details, such as cloned from github so that we can check the code in a different git repository or a different version control system. This article covers the steps that we can take to remove git references.
If we clone a repo or fork a repo from git, the newly created repository will have git references as version control. If we want to remove the git references from the new repository then we need to delete all the git references. Once we remove the git references then it will not have any reference to old repository and we can use this project folder to create a brand new repository in git or any other version control system. This article talks about how to remove
The good thing is that all the git related information is stored in a folder .git . Normally we would have only one .git folder in the root of the repository, but we might have more than one .git folder based on how the repository is configured. Apart from .git folder we might have following git specific files,
.gitignore: allows to include/exclude files to be synced to git remote server
.gitkeep: allows us to include an empty directory to be synced to git remote server
. gitattributes: allows us to ensure consistent git settings across the machine.
Essentially we need to delete all these git related folder/files that will make our repository clean and without any git version details. The following sections show how to achieve the same in a Windows environment and Mac environment
Windows
The rmdir or rd command will not delete/remove any hidden files or folders within the directory you specify, so we should use the del command to be sure that all files are removed from the .git folder.
Open the command prompt
Navigate to the project directory, i.e. - cd path_to_your_repository
del /F /S /Q /A .git
rmdir .git
Mac
Open a terminal and navigate to the directory of your project, i.e. - cd path_to_your_repository. And run the following commands
Go to the directory of your project and run the following command which finds the only the folder with the name .git and prints its path in the console.
This blog post drives though an implementation pattern and a working setup with multiple microservices where they get registered with Eureka and the client can discover them and invoke them
Microservices Registration and Discovery using Spring Cloud, Eureka
This blog post drives though an implementation pattern and a working setup with multiple microservices where they get registered with Eureka and the client can discover them and invoke them
What is Eureka
Eureka is a REST-based service that provides support for discovering other services so that clients can use the Eureka service to discover services and calling those services.
Why we need Discovery Service
In a Microservices architecture where we have multiple services running, we need a mechanism to know what are the services and how to invoke them. Each service typically will have a different URL or IP address to reach out to. Also, clients of those microservices need to know when a new
microservice is added or an existing microservice was taken down for maintenance. Discovery service provides that mechanism, where services can register themself in the discovery service and clients, can query the discovery service to know more about the available microservices.
Project achievement
In this project, we will go through an end to end use case where we will have a client microservice calling another microservice utilizing Eureka discovery service. Essentially we want to find existing services by looking up in discovery service and then invoking the target service without knowing about their whereabouts like URL, or IP or port, etc. For that, we will build a discovery server one service microservice and one client microservice.
Project Contents
Eureka Discovery Service: Provides the registration and discovery
Article Microservice: Provides REST services for Article CRUD operation
Client Microservice: Invokes the article microservice
Above pictures show what we are going to achieve in very high level
1) We will deploy a Discovery service
2) We will deploy Article Service which registers itself with discovery service with a unique name.
3) We will deploy a consumer application which is another spring boot application which will invoke the
Article Service by its name.
Technology Used
Java 11
Apache Maven 3.5.0
Spring Boot 2.2.6
Spring Cloud Hoxton.SR1
Netflix Ribbon 2.3.0
Open Feign
JSON
Discovery Server
The following section highlights the important code related to Eureka Server. The details can be looked into in the git repo. Mainly we need to add the maven dependency for Eureka Discovery Server, in the spring boot properties file add the server port and defaultZone and annotate the SpringBoot Application class with @EnableEurekaServer.
We need to include the Netflix Eureka Server dependency in the maven pom file.
server.port=8761
##Eureka Related
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
eureka.client.healthcheck.enabled=true
The Eureka Discovery Server is a Spring Boot application that is very simple. We need to annotate the application with @EnableEurekaServer.
@EnableEurekaServer allows this application to run as a Eureka server, aided by Spring Boot to instantiate Eureka-related beans based on configuration properties.
ServiceDiscovery.java
package com.bootng.service;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class ServiceDiscovery {
public static void main(String[] args) {
SpringApplication.run(ServiceDiscovery.class, args);
}
}
Now when we build and start the discovery server and access the server through http://localhost:8761 we would see something like bellow. Notice the following screenshots shows no entries under applications because no other services are up yet.
Discovery Service UI
Article Service
Now we will build and deploy the Article microservice which is another spring boot application that registers itself with the discovery service.
The name with which this service is registered is "article-service" and is defined in bootstrap.properties file.
## Server Related
server.port=9051
## Eureka Related
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:8761/eureka/
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=false
eureka.vipAddress=article-service
bootstrap.properties
spring.application.name=article-service
Following is the main application class representing Article Microservice.
ArticleMicroservice
@ComponentScan({ "com.siddb" })
@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public class ArticleMicroservice {
public static void main(String args[]) {
SpringApplication.run(ArticleMicroservice.class, args);
}
}
This Spring Boot Application exposes the following REST endpoints through the ArticleController.java class.
And registers itself with the service discovery with the name "article-service"
ArticleController.java
@RestController
@RequestMapping("/api")
public class ArticleController {
private static final Logger log = LoggerFactory.getLogger(ArticleController.class);
@Autowired
ArticleService articleService;
@RequestMapping(value = {"/articles"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<List<Article>> getArticles() throws AppException {
List<Article> articles = articleService.getArticles();
return new ResponseEntity<List<Article>>(articles, HttpStatus.OK);
}
@RequestMapping(value = {"/articles/{id}"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Article> getArticle(@PathVariable(value = "") String id)
throws AppException, NotFoundException {
Article articles = articleService.getByID(id);
return new ResponseEntity<Article>(articles, HttpStatus.OK);
}
//other methods for POST and Deleted removed from here for readability.
}
[
{
"id": "America-Travel",
"name": "America Travel",
"description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum",
"category": "Travel"
}
]
GET http://localhost:9051/api/articles
Sample Response:
[
{
"id": "America-Travel",
"name": "America Travel",
"description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum",
"category": "Travel"
}
]
[
{
"id": "America-Travel",
"name": "America Travel",
"description": "Places to travel in AmericaLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum",
"category": "Travel"
}
]
Article Client Service
Now we will build and deploy the Client Service application which is another Spring Boot application that consumes the REST services deployed by Article Service. Most interesting part
Following is the Consumer Application Class. We have annotated it with @EnableDiscoveryClient so that it can discover other services registered with the Discovery Server.
ConsumerApplication
@ComponentScan({"com.siddb", "com.siddb.controller"})
@SpringBootApplication
@EnableDiscoveryClient
public class ConsumerApplication {
public static void main(String args[]) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
Following is the main controller which uses the discovery service internally and invokes services on the service article-service using ribbon. From the ribbon configuration in (application.properties), it knows article-service-consumer is tied to a service with VIP Address (name) article-service.
RibbonController.java
@RestController
public class RibbonController {
@Autowired
private RestTemplate restTemplate;
/**
* This method calls the microservice GET article-service/api/articles using Ribbon to get a list of
* Articles and returns the same. it uses RestTemplate to make the API calls.
* @return
* @throws Exception
*/
@RequestMapping(value = {"render"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> renderArticles() throws Exception {
JsonNode repos =
restTemplate.getForObject("http://article-service-consumer/api/articles", JsonNode.class);
int counter = 1;
StringBuilder result = new StringBuilder("\n List of Articles");
if (repos.isArray()) {
for (JsonNode jsonNode : repos) {
result.append("\n Repo ").append(counter++).append("::");
result.append(jsonNode.get("name").asText());
}
}
return new ResponseEntity<String>(result.toString(), HttpStatus.OK);
}
}
The Consumer Controller uses the ribbon configuration that we have added in the property file to invoke the article service by the ribbon name "article-service-consumer". This is where the Consumer controller will discover the actual API for the corresponding service name.
And call GET http://article-service-consumer/api/articles will be actually to http://localhost:9051/api/articles. This is how using the Eureka Discovery service the client becomes independent of the service (IP address, port, etc.). The client simply can refer to the service with its published name.
Start Microservices
Now the fun part, start all the microservices and invoke the /render REST API. We need to start all services (discovery service, article service, consumer service).
For that, we first need to check out the repo from git and build/run each project.
1) git clone https://github.com/siddharthagit/spring-boot-sdc.
2) go to the root folder that contains this repo.
3) open 3 Terminals one for each subproject (eureka-service-discovery, ms-article-service, ms-consumer-service).
4) build each project and start the services.
mvn clean install
mvn spring-boot:run
5) Check the status of each service on the discovery server http://localhost:8761
6)Invoke the REST API on consumer service http://localhost:9053/render
This API internally will use the discovery server to resolve the service and will route the call to http://localhost:9051/api/articles.
In this article, we've covered how to use Spring Cloud Eureka for service discovery in the microservice/cloud environment. We created two simple REST services that communicate with each other without hardcoding any hostname/port while making REST calls. Though in this article we have shown how the client can invoke the article service with ribbon, the git repo also contains a Feign client that uses Feign and will be covered in a different article.
In This Article we will see how we can convert Integer to Binary number. We will see some built in options that Java provides as well as two different custom implementation.
In This Article we will see how we can convert Integer to Binary number. We will see some built in options that Java provides as well as two different custom implementation.
Using Integer.toBinaryString
Using Integer.toBinaryString() method we can convert a integer to Binary String very easily
We can also use Integer.toString() and pass the number and radix to convert the integer to String. In this case we pass 2 as radix to convert the Integer to Binary Number String.
Following code is a custom method to convert an Integer to Binary.
private static String toBinary_divide(Integer i) {
StringBuilder ret = new StringBuilder();
while (i > 0) {
if (i % 2 == 1) {
ret.insert(0, "1");
}
else {
ret.insert(0, "0");
}
i = i / 2;
}
return ret.toString();
}
By using Bit masking
This is another custom method to convert Integer to Binary String. This Algorithm works by masking each bit in the original number and creating a char array.
And finally converting the char array to String.
private static String toBinary_mask(Integer num) {
char ret[] = new char[32];
for (int i = 0; i < 32; i++) {
int mask = 1 << i;
ret[31 - i] = (num & mask) != 0 ? '1' : '0';
}
return new String(ret);
}
Full Code
IntegerToBinaryConverter.java
import java.math.BigInteger;
public class IntegerToBinaryConverter {
public static void main(String[] args) {
System.out.println("Convert to Binary 2020 = " + toBinary1(2020));
System.out.println("Convert to Binary 2020 = " + toBinary2(2020));
System.out.println("Convert to Binary 2020 = " + toBinary3(2020));
System.out.println("Convert to Binary 2020 = " + toBinary_divide(2020));
System.out.println("Convert to Binary 2020 = " + toBinary_mask(2020));
}
private static String toBinary1(Integer i) {
return Integer.toBinaryString(i);
}
private static String toBinary2(Integer i) {
return Integer.toString(i, 2);
}
private static String toBinary3(Integer i) {
BigInteger bigInt = new BigInteger(String.valueOf(i));
return bigInt.toString(2);
}
private static String toBinary_divide(Integer i) {
StringBuilder ret = new StringBuilder();
while (i > 0) {
if (i % 2 == 1) {
ret.insert(0, "1");
}
else {
ret.insert(0, "0");
}
i = i / 2;
}
return ret.toString();
}
private static String toBinary_mask(Integer num) {
char ret[] = new char[32];
for (int i = 0; i < 32; i++) {
int mask = 1 << i;
ret[31 - i] = (num & mask) != 0 ? '1' : '0';
}
return new String(ret);
}
}
Console Output
Convert to Binary 2020 = 11111100100
Convert to Binary 2020 = 11111100100
Convert to Binary 2020 = 11111100100
Convert to Binary 2020 = 11111100100
Convert to Binary 2020 = 00000000000000000000011111100100
Summary
This article shows different ways to convert the Integer to Binary String. The Bit masking is very efficient and in fact the builtin methods like Integer.toString() uses Bit masking internally.
For more information on Bit masking the links provided in Reference section is very useful.
This article covers the datatypes available for JavaScript. The latest ECMAScript standard defines nine types: 7 Primitive types and 2 Structural Types.
This article covers the datatypes available for JavaScript. The latest ECMAScript standard defines nine types: 7 Primitive types and 2 Structural Types.
Primitive Types
The six primitive types are Boolean, Null, Undefined, String, Number, BigInt, and Symbol.
Boolean type
Boolean represents a logical entity and can have two values: true and false.
The Boolean object will be with the initial true only if the parameter passed is an object, array, or true. Else the Boolean object will be false.
Following code shows the different values the Boolean object will have when passed different parameters.
var b1 = new Boolean();
console.log(b1); //false
var b2 = new Boolean(false);
console.log(b2);//false
var b3 = new Boolean(0);
console.log(b3);//false
var b4 = new Boolean(NaN);
console.log(b4);//false
var b5 = new Boolean(undefined);
console.log(b5);//false
var b6 = new Boolean(null);
console.log(b6); //false
var b7 = new Boolean({});
console.log(b7);//true
var b8 = new Boolean(true);
console.log(b8);//true
var b9 = new Boolean([]);
console.log(b9);//true
Null type
The Null type has exactly one value: null.
Every Object is derived from null value, and therefore typeof operator returns object for it.
The following code shows one important feature of null, it is of type object.
var n1 = null;
console.log(n1); //null
console.log(typeof n1); //object
Undefined type
A variable that has not been assigned a value has the value undefined.
The following code shows one example where a variable u1 is defined but not assigned any value.
var u1 ;
console.log(typeof u1);//undefined
console.log(u1);//undefined
String
The string type is used to represent textual data. JavaScript strings are immutable. This means that once a string is created, it is not possible to modify it
Strings can be created as primitives, from string literals, or as objects, using the String() constructor. In case of primitive typeof returns "string" otherwise it returns "object". String object can be converted to string primitives using valueOf() method on the String object.
The Number type is a double-precision 64-bit binary format IEEE 754 value (numbers between -(2^53 − 1) and 2^53 − 1). In addition to representing floating-point numbers, the number type has three symbolic values: +Infinity, -Infinity, and NaN ("Not a Number").
Number.MAX_VALUE or Number.MIN_VALUE represents the maximum and minimum values possible using numbers.
The BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision.
A BigInt is created by appending n to the end of an integer or by calling the constructor.
BigInts cannot be operated on interchangeably with Numbers. Instead, a TypeError will be thrown.
Following code shows how to find the value of 2^53, we have choosen 53 because then the product value will be beyond the capacity of numbers. If you