[{"content":"The Java Collections API provide Java developers with a set of classes and interfaces that makes it easier to work with collections of objects, e.g. lists, maps, stacks etc.\nclassDiagram direction TB Iterable \u003c|-- Collection Collection \u003c|-- List Collection \u003c|-- Set Collection \u003c|-- Queue List \u003c|-- ArrayList List \u003c|-- LinkedList List \u003c|-- Vector Set \u003c|-- HashSet Set \u003c|-- LinkedHashSet Set \u003c|-- TreeSet Queue \u003c|-- PriorityQueue Queue \u003c|-- Deque Deque \u003c|-- ArrayDeque Deque \u003c|-- LinkedList classDiagram Map \u003c|-- HashMap Map \u003c|-- LinkedHashMap Map \u003c|-- TreeMap Map \u003c|-- Hashtable Java Iterator # The Java Iterator interface represents an object capable of iterating through a collection of Java objects, one object at a time. To use a Java Iterator you will have to obtain an Iterator instance from the collection of objects you want to iterate over. The obtained Iterator keeps track of the elements in the underlying collection to make sure you iterate through all of them.\nJava Iterable # The Java Iterable interface represents a collection of objects which is iterable, meaning which can be iterated. This means, that a class that implements the Java Iterable interface can have its elements iterated.\nJava Collections Class # The Java Collections class, java.util.Collections, contains a long list of utility methods for working with collections in Java.\nJava List # The Java List interface, java.util.List, represents an ordered sequence of objects. The elements contained in a Java List can be inserted, accessed, iterated and removed according to the order in which they appear internally in the Java List.\nThe following List implementations in the Java Collections API are available:\njava.util.ArrayList java.util.LinkedList java.util.Vector java.util.Stack Java Set # The Java Set interface, java.util.Set, represents a collection of objects where each object in the Java Set is unique. The Set interface does not gurantee insertion order.\nThe following Set implementations in the Java Collections API are available:\njava.util.EnumSet java.util.HashSet java.util.LinkedHashSet java.util.TreeSet ","date":"24 December 2025","externalUrl":null,"permalink":"/posts/java/java-collections-api/","section":"Welcome to my Blog!","summary":"","title":"Introduction to Java Collection API","type":"posts"},{"content":"","date":"24 December 2025","externalUrl":null,"permalink":"/posts/java/","section":"Welcome to my Blog!","summary":"","title":"Java","type":"posts"},{"content":"","date":"24 December 2025","externalUrl":null,"permalink":"/posts/","section":"Welcome to my Blog!","summary":"","title":"Welcome to my Blog!","type":"posts"},{"content":"Welcome to my website! I\u0026rsquo;m really happy you stopped by.\n","date":"24 December 2025","externalUrl":null,"permalink":"/","section":"Welcome!","summary":"","title":"Welcome!","type":"page"},{"content":"","date":"24 December 2025","externalUrl":null,"permalink":"/posts/spring/","section":"Welcome to my Blog!","summary":"","title":"Spring","type":"posts"},{"content":"","date":"18 December 2025","externalUrl":null,"permalink":"/posts/virtualization/","section":"Welcome to my Blog!","summary":"","title":"Virtualization","type":"posts"},{"content":" Dockerfile Commands # ARG # Use build-time variables. The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg \u0026lt;varname\u0026gt;=\u0026lt;value\u0026gt;flag. ARG variables are not persisted into the built image An ARG variable comes into effect from the line on which it is declared in the Dockerfile. Predefined ARG variables that you can use without a corresponding ARG instruction in the Dockerfile:\nHTTP_PROXY http_proxy HTTPS_PROXY https_proxy FTP_PROXY ftp_proxy NO_PROXY no_proxy ALL_PROXY all_proxy BuildKit also provides some global and inbuild arguments, refer: https://docs.docker.com/reference/dockerfile/#automatic-platform-args-in-the-global-scope\nENV # Set environment variable The ENV instruction sets the environment variable \u0026lt;key\u0026gt; to the value\u0026lt;value\u0026gt;. Unlike an ARG instruction, ENV values are always persisted in the built image. The environment variables set using ENV will persist when a container is run from the resulting image. #ENV Key Value ENV NAME World FROM # Create a new build stage from a base image. The FROM instruction initializes a new build stage and sets the base image for subsequent instructions. Specifies the base image to build upon. FROM [--platform=\u0026lt;platform\u0026gt;] \u0026lt;image\u0026gt; [AS \u0026lt;name\u0026gt;] FROM [--platform=\u0026lt;platform\u0026gt;] \u0026lt;image\u0026gt;[:\u0026lt;tag\u0026gt;] [AS \u0026lt;name\u0026gt;] FROM [--platform=\u0026lt;platform\u0026gt;] \u0026lt;image\u0026gt;[@\u0026lt;digest\u0026gt;] [AS \u0026lt;name\u0026gt;] HEALTHCHECK # Check a container\u0026rsquo;s health on startup. The HEALTHCHECK instruction tells Docker how to test a container to check that it\u0026rsquo;s still working. Example for health check: A web server stuck in an infinite loop and unable to handle new connections should show unhealthy. There can only be one HEALTHCHECK instruction in a Dockerfile. The HEALTHCHECK instruction has two forms: HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container) HEALTHCHECK NONE (disable any healthcheck inherited from the base image) #check every five minutes or so that a web-server is able to serve the site\u0026#39;s main page within three seconds HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1 LABEL # Add metadata to an image. The LABEL instruction adds metadata to an image. A LABEL is a key-value pair. LABEL \u0026lt;key\u0026gt;=\u0026lt;value\u0026gt; [\u0026lt;key\u0026gt;=\u0026lt;value\u0026gt;...] ONBUILD # Specify instructions for when the image is used in a build. The ONBUILD instruction adds to the image a trigger instruction to be executed at a later time, when the image is used as the base for another build. The trigger will be executed in the context of the downstream build, as if it had been inserted immediately after the FROM instruction in the downstream Dockerfile. Use case: An application build environment or a daemon which may be customized with user-specific configuration. ONBUILD \u0026lt;INSTRUCTION\u0026gt; WORKDIR # Change working directory. The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn\u0026rsquo;t exist, it will be created even if it\u0026rsquo;s not used in any subsequent Dockerfile instruction. Sets the working directory inside the container. WORKDIR /path/to/workdir Example of WORKDIR\nWORKDIR /a WORKDIR b WORKDIR c RUN pwd #will result in a/b/c COPY # Copy files and directories. The COPY instruction copies new files or directories from \u0026lt;src\u0026gt; and adds them to the filesystem of the image at the path \u0026lt;dest\u0026gt;. All files and directories copied from the build context are created with a UID and GID of 0 COPY [OPTIONS] \u0026lt;src\u0026gt; ... \u0026lt;dest\u0026gt; COPY [OPTIONS] [\u0026#34;\u0026lt;src\u0026gt;\u0026#34;, ... \u0026#34;\u0026lt;dest\u0026gt;\u0026#34;] The COPY --from flag lets you copy files from an image, a build stage, or a named context instead. The --chown and --chmod features are only supported on Dockerfiles used to build Linux containers. Use --link to reuse already built layers in subsequent builds with --cache-from even if the previous layers have changed. The --exclude flag lets you specify a path expression for files to be excluded. ADD # Add local or remote files and directories. The ADD instruction copies new files or directories from \u0026lt;src\u0026gt; and adds them to the filesystem of the image at the path \u0026lt;dest\u0026gt;. Files and directories can be copied from the build context, a remote URL, or a Git repository. If the source is a directory, the contents of the directory are copied, including filesystem metadata. The directory itself isn\u0026rsquo;t copied, only its contents. If it contains subdirectories, these are also copied and merged with any existing directories at the destination. If the destination path begins with a forward slash, it\u0026rsquo;s interpreted as an absolute path ADD [OPTIONS] \u0026lt;src\u0026gt; ... \u0026lt;dest\u0026gt; ADD [OPTIONS] [\u0026#34;\u0026lt;src\u0026gt;\u0026#34;, ... \u0026#34;\u0026lt;dest\u0026gt;\u0026#34;] --checksum flag lets you verify the checksum of a remote resource. The --chown and --chmod features are only supported on Dockerfiles used to build Linux containers.--chown=myuser:mygroup --chmod=644 files* /somedir/ --link files remain independent on their own layer and don\u0026rsquo;t get invalidated when commands on previous layers are changed. --exclude flag lets you specify a path expression for files to be excluded. COPY supports basic copying of files into the container, from the build context or from a stage in a multi-stage build. ADD supports features for fetching files from remote HTTPS and Git URLs, and extracting tar files automatically when adding files from the build context.\nRUN # Execute build commands. The RUN instruction will execute any commands to create a new layer on top of the current image. The cache for RUN instructions isn\u0026rsquo;t invalidated automatically during the next build. The cache for RUN instructions can be invalidated by using the --no-cacheflag, for example docker build --no-cache The cache for RUN instructions can be invalidated by ADD and COPY instructions. # Shell form: RUN [OPTIONS] \u0026lt;command\u0026gt; ... # Exec form: RUN [OPTIONS] [ \u0026#34;\u0026lt;command\u0026gt;\u0026#34;, ... ] RUN --mount allows you to create filesystem mounts that the build can access. This can be used to: Create a bind mount to the host filesystem or other build stages Access build secrets or ssh-agent sockets Use a persistent package management cache to speed up your build Different mount type: bind This mount type allows binding files or directories to the build container. A bind mount is read-only by default. cache This mount type allows the build container to cache directories for compilers and package managers. tmpfs This mount type allows mounting tmpfs in the build container secret This mount type allows the build container to access secret values, such as tokens or private keys, without baking them into the image. ssh This mount type allows the build container to access SSH keys via SSH agents, with support for passphrases. Refer to other optional parameters https://docs.docker.com/reference/dockerfile/#run---mount RUN --network allows control over which networking environment the command is run in. The supported network types are: default Equivalent to not supplying a flag at all, the command is run in the default network for the build. none The command is run with no network access (lo is still available, but is isolated to this process) host The command is run in the host\u0026rsquo;s network environment (similar to docker build --network=host, but on a per-instruction basis) SHELL # Set the default shell of an image. The SHELL instruction allows the default shell used for the shell form of commands to be overridden. SHELL [\u0026#34;executable\u0026#34;, \u0026#34;parameters\u0026#34;] STOPSIGNAL # Specify the system call signal for exiting a container. The STOPSIGNAL instruction sets the system call signal that will be sent to the container to exit. STOPSIGNAL signal USER # Set user and group ID. The USER instruction sets the user name (or UID) and optionally the user group (or GID) to use as the default user and group for the remainder of the current stage. The specified user is used for RUN instructions and at runtime, runs the relevant ENTRYPOINT and CMD commands. When the user doesn\u0026rsquo;t have a primary group then the image (or the next instructions) will be run with the root group. USER \u0026lt;user\u0026gt;[:\u0026lt;group\u0026gt;] USER \u0026lt;UID\u0026gt;[:\u0026lt;GID\u0026gt;] VOLUME # Create volume mounts. Volumes are persistent data stores for containers, created and managed by Docker. The VOLUME instruction creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers. They retain data even after the containers using them are removed. This is similar to the way that bind mounts work, except that volumes are managed by Docker and are isolated from the core functionality of the host machine. Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. VOLUME [\u0026#34;/data\u0026#34;] CMD # Specify default commands. The CMD instruction sets the command to be executed when running a container from an image. There can only be one CMD instruction in a Dockerfile. The purpose of a CMD is to provide defaults for an executing container. These defaults can include an executable, or they can omit the executable, in which case you must specify an ENTRYPOINT instruction as well. If the user specifies arguments to docker runthen they will override the default specified in CMD, but still use the default ENTRYPOINT. #exec form CMD [\u0026#34;executable\u0026#34;,\u0026#34;param1\u0026#34;,\u0026#34;param2\u0026#34;] #exec form with default parameters to ENTRYPOINT CMD [\u0026#34;param1\u0026#34;,\u0026#34;param2\u0026#34;] #shell form; avoid this CMD command param1 param2 ENTRYPOINT # Specify default executable. An ENTRYPOINT allows you to configure a container that will run as an executable ENTRYPOINT should be used when you want to define a container’s main application or command, ensuring it always runs regardless of additional CMD parameters ENTRYPOINT should be defined when using the container as an executable. CMD should be used as a way of defining default arguments for an ENTRYPOINT command or for executing an ad-hoc command in a container. #exec form ENTRYPOINT [\u0026#34;executable\u0026#34;, \u0026#34;param1\u0026#34;, \u0026#34;param2\u0026#34;] #shell form ENTRYPOINT command param1 param2 Dockerfile should specify at least one of CMD or ENTRYPOINT commands. -ENTRYPOINT should be defined when using the container as an executable. EXPOSE # Describe which ports your application is listening on. The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. When creating a container image, the EXPOSE Instruction is used to indicate that the packaged application will use the specified port. These ports aren\u0026rsquo;t published by default. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published. The following flags can be used with docker run With the -P or --publish-all flag, you can automatically publish all exposed ports to ephemeral ports. -p or --expose Publish port. -P or --publish-all Publish all exposed ports. Without EXPOSE command in Dockerfile and running docker run without specifying -p HOST_PORT:CONTAINER_PORT The Docker container is not accessible. The docker container ps -a does not show any port mapping. With EXPOSE command in Dockerfile and running docker run without specifying -p HOST_PORT:CONTAINER_PORT The Docker container is not accessible. The docker container ps -a shows the port specified on EXPOSE It should be accessible internally. Without EXPOSE command in Dockerfile and running docker run with specifying -p HOST_PORT:CONTAINER_PORT The Docker container is accessible on the host port HOST_PORT Specifying -p port Docker assigns a randomly generated host port. The mapping is random host post -\u0026gt; port found in the docker container ps -a . The -p port should be the port the underlying service is listening on. The Docker container is accessible. Specifying -P the docker container ps -a does not specify any port since EXPOSE command is not used in the Dockerfile. The Docker container is not accessible. With EXPOSE command in Dockerfile and running docker run with specifying -p HOST_PORT:CONTAINER_PORT Specifying the same port on EXPOSE HOST_PORT and a host port in docker run -p HOST_PORT:CONTAINER_PORT . The container is accessible on the host port HOST_PORT Specifying a different port on EXPOSE **SOME_PORT** and a host port in docker run -p HOST_PORT:CONTAINER_PORT . The container is accessible on the host port HOST_PORT Specifying -P the docker service is accessible on a random port which can be gotten from docker container ps -a When mapping with -p HOST_PORT:CONTAINER_PORT it is important to note that the underlying service is running on the CONTAINER_PORT . If the underlying service is listening on port 90 but the docker run command specifies -p 8080:80 you cannot access the service the mapping should be -p 8080:90 .\nEXPOSE \u0026lt;port\u0026gt; [\u0026lt;port\u0026gt;/\u0026lt;protocol\u0026gt;...] ","date":"18 December 2025","externalUrl":null,"permalink":"/posts/virtualization/what-is-docker/","section":"Welcome to my Blog!","summary":"","title":"What Is Docker","type":"posts"},{"content":"","date":"17 December 2025","externalUrl":null,"permalink":"/posts/python/","section":"Welcome to my Blog!","summary":"","title":"Python","type":"posts"},{"content":"In this blog post we look at the common Java code snippets that are useful during interview preperation.\n1. # public class Learn { public static void main(String[] args) { // adds ascii int of characters System.out.println(\u0026#39;a\u0026#39; + \u0026#39;b\u0026#39;); } } Output\n195 2. # public class Learn { public static void main(String[] args) { // concats as string System.out.println(\u0026#34;hello\u0026#34; + 90 + 100); } } Output\nhello90100 3. # public class Learn { public static void main(String[] args) { // adds the integer and then concats System.out.println(90 + 100 + \u0026#34;hello\u0026#34;); } } Output\n190hello 4. # 4.1 Reverse a string using charAt # public class Learn { public static void main(String[] args) { String s = \u0026#34;abcdef\u0026#34;; String r = \u0026#34;\u0026#34;; for (int i = 0; i \u0026lt; s.length(); i++) { // prepend each character r = s.charAt(i) + r; } System.out.println(r); } } Output\nfedcba 4.2 Reverse a string using character array # public class Learn { public static void main(String[] args) { String s = \u0026#34;abcdef\u0026#34;; // using toCharArray to copy elements to char array char[] arr = s.toCharArray(); for (int i = arr.length - 1; i \u0026gt;= 0; i--) System.out.print(arr[i]); } } Output\nfedcba 4.3 Reverse a string using Collections API # import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class Learn { public static void main(String[] args) { String s = \u0026#34;abcdef\u0026#34;; // copying elements to character array char[] arr = s.toCharArray(); // creating new ArrayList List\u0026lt;Character\u0026gt; l = new ArrayList\u0026lt;\u0026gt;(); // adding char elements to ArrayList for (char c : arr) l.add(c); // Reversing the ArrayList Collections.reverse(l); // converting ArrayList to string String res = l.stream().map(String::valueOf).collect(Collectors.joining()); System.out.println(res); } } Output\nfedcba 4.4 Reverse a string using Stack data type # import java.util.Stack; public class Learn { public static void main(String[] args) { String s = \u0026#34;abcdef\u0026#34;; // initializing a stack of type char Stack\u0026lt;Character\u0026gt; stack = new Stack\u0026lt;\u0026gt;(); for (char c : s.toCharArray()) { // pushing all the characters stack.push(c); } String res = \u0026#34;\u0026#34;; while (!stack.isEmpty()) { // popping all the chars and appending to temp res += stack.pop(); } System.out.println(res); } } Output\nfedcba 5. # import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Employee\u0026gt; em = new ArrayList\u0026lt;\u0026gt;(Arrays.asList(new Employee(\u0026#34;Raj\u0026#34;, 30), new Employee(\u0026#34;Anthony\u0026#34;, 45), new Employee(\u0026#34;Zeba\u0026#34;, 29), new Employee(\u0026#34;Philip\u0026#34;, 30), new Employee(\u0026#34;Anish\u0026#34;, 25))); List\u0026lt;Employee\u0026gt; sorted = em.stream() .sorted(Comparator.comparing(Employee::getName).thenComparing(Employee::getAge)).toList(); System.out.println(sorted); } } class Employee { private String name; private int age; public Employee() { } public Employee(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return \u0026#34;(\u0026#34; + name + \u0026#34;, \u0026#34; + age + \u0026#34;)\u0026#34;; } } Output\n[(Anish, 25), (Anthony, 45), (Philip, 30), (Raj, 30), (Zeba, 29)] 6. # public class Learn { public static void main(String[] args) { String str1 = \u0026#34;Scaler\u0026#34;; String str2 = \u0026#34;Scaler\u0026#34;; String str3 = new String(\u0026#34;Scaler\u0026#34;); // str1 and str2 refer to same literal in the string pool System.out.println(str1 == str2); // str1 and str3 have same content but refer to different literal in the heap memory System.out.println(str1 == str3); // checks if the content is same System.out.println(str1.equals(str3)); } } Output\ntrue false true 7. # public class Learn { public static void main(String[] args) { Integer num1 = 100; Integer num2 = 100; Integer num3 = 500; Integer num4 = 500; if (num1 == num2) { System.out.println(\u0026#34;num1 == num2\u0026#34;); } else { System.out.println(\u0026#34;num1 != num2\u0026#34;); } // Java specification states values between -127 and 127 are cached. Since 500 // is outside this range they refer to two different objects. Compare with // intValue(). if (num3 == num4) { System.out.println(\u0026#34;num3 == num4\u0026#34;); } else { System.out.println(\u0026#34;num3 != num4\u0026#34;); } } } Output\nnum1 == num2 num3 != num4 8. # public class Learn { public static void main(String[] args) { try { System.out.println(\u0026#34;try block executed\u0026#34;); System.exit(0); } catch (Exception exception) { System.out.println(\u0026#34;catch block executed\u0026#34;); } finally { System.out.println(\u0026#34;finally block executed\u0026#34;); } } } Output\nTry block executed 9. # public class Learn { public static void main(String[] args) { Execute e = new Execute(); System.out.println(e.run()); } } class Execute { String run() { try { System.out.println(\u0026#34;in try\u0026#34;); return \u0026#34;data from try\u0026#34;; } catch (Exception exception) { System.out.println(\u0026#34;in catch\u0026#34;); return \u0026#34;data from catch\u0026#34;; } finally { System.out.println(\u0026#34;in finally\u0026#34;); return \u0026#34;data from finally\u0026#34;; } } } Output\nin try in finally data from finally 10. # public class Learn { public static void main(String[] args) { PersonDto person = new PersonDto(\u0026#34;Alice\u0026#34;, 30); System.out.println(\u0026#34;Name: \u0026#34; + person.name()); System.out.println(\u0026#34;Age: \u0026#34; + person.age()); System.out.println(person); } } record PersonDto(String name, int age) { } Output\nName: Alice Age: 30 PersonDto[name=Alice, age=30] Group Anagram import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { String[] one = new String[] { \u0026#34;eat\u0026#34;, \u0026#34;tea\u0026#34;, \u0026#34;tan\u0026#34;, \u0026#34;ate\u0026#34;, \u0026#34;nat\u0026#34;, \u0026#34;bat\u0026#34; }; String[] two = new String[] { \u0026#34;act\u0026#34;, \u0026#34;god\u0026#34;, \u0026#34;cat\u0026#34;, \u0026#34;dog\u0026#34;, \u0026#34;tac\u0026#34; }; String[] three = new String[] { \u0026#34;listen\u0026#34;, \u0026#34;silent\u0026#34;, \u0026#34;enlist\u0026#34;, \u0026#34;abc\u0026#34;, \u0026#34;cab\u0026#34;, \u0026#34;bac\u0026#34;, \u0026#34;rat\u0026#34;, \u0026#34;tar\u0026#34;, \u0026#34;art\u0026#34; }; Learn l = new Learn(); l.findGroupAnagram(one); l.findGroupAnagram(two); l.findGroupAnagram(three); } public void findGroupAnagram(String[] arr) { // this integer array keeps tract of string in a group int[] arrbuff = new int[arr.length]; List\u0026lt;List\u0026lt;String\u0026gt;\u0026gt; result = new ArrayList\u0026lt;\u0026gt;(); for (int i = 0; i \u0026lt; arr.length; i++) { // result from a group List\u0026lt;String\u0026gt; subRes = new ArrayList\u0026lt;\u0026gt;(); // if a string is already part of a group if (arrbuff[i] == 1) { continue; } char[] prim = arr[i].toCharArray(); for (int j = 0; j \u0026lt; arr.length; j++) { char[] sec = arr[j].toCharArray(); // if a string is already part of a group if (arrbuff[j] == 1) { continue; } Arrays.sort(prim); Arrays.sort(sec); // check if strings are anagram if (Arrays.equals(prim, sec)) { subRes.add(arr[j]); // ensures that anagram string is alread check to skip loop arrbuff[j] = 1; } } result.add(subRes); } System.out.println(result); } } Output\n[[eat, tea, ate], [tan, nat], [bat]] [[act, cat, tac], [god, dog]] [[listen, silent, enlist], [abc, cab, bac], [rat, tar, art]] 12. # Java find sum of integers in array\nimport java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); // using mapToInt int res = list.stream().mapToInt(i -\u0026gt; i.intValue()).sum(); System.out.println(res); } } Output\n405 13. # Java find sum of integers in array with reduce()\nimport java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); int res = list.parallelStream().reduce(0, (a, b) -\u0026gt; a + b); System.out.println(res); } } Output\n405 14. # Java find average of integers in array\nimport java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); double res = list.stream().mapToInt(a -\u0026gt; a).average().orElse(0); System.out.println(res); } } Output\n33.75 15. # Given a list of numbers, square them and filter the numbers which are greater 100 and then find the average of them.\nimport java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); double res = list.stream().map(e -\u0026gt; e * e).filter(e -\u0026gt; e \u0026gt; 100).mapToInt(e -\u0026gt; e).average().orElse(0); System.out.println(res); } } Output\n14310.0 16. # Given a list of numbers, return the even and odd numbers separately.\nimport java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); // the condition true (number is even) is mapped to true Map\u0026lt;Boolean, List\u0026lt;Integer\u0026gt;\u0026gt; result = list.stream().collect(Collectors.partitioningBy(n -\u0026gt; n % 2 == 0)); // even numbers System.out.println(result.get(true)); System.out.println(result.get(false)); } } Output\n[8, 2, 36, 4, 78, 222, 24] [1, 7, 9, 5, 9] 17. # Given a list of numbers, find out all the numbers starting with 2.\nimport java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); List\u0026lt;Integer\u0026gt; res = list.stream().map(e -\u0026gt; String.valueOf(e)).filter(e -\u0026gt; e.startsWith(\u0026#34;2\u0026#34;)) .map(e -\u0026gt; Integer.valueOf(e)).collect(Collectors.toList()); System.out.println(res); } } Output\n[2, 222, 24] 18. # Given a list of numbers, print the duplicate numbers.\nimport java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.stream.Collectors; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); Set\u0026lt;Integer\u0026gt; res = list.stream().filter(e -\u0026gt; Collections.frequency(list, e) \u0026gt; 1).collect(Collectors.toSet()); System.out.println(res); } } Output\n[9] 19. # Given a list of numbers, print the maximum and minimum values.\nimport java.util.Arrays; import java.util.IntSummaryStatistics; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); IntSummaryStatistics stats = list.stream().mapToInt(e -\u0026gt; e).summaryStatistics(); System.out.println(\u0026#34;max \u0026#34; + stats.getMax()); System.out.println(\u0026#34;min \u0026#34; + stats.getMin()); } } Output\nmax 222 min 1 20. # Given a list of numbers, sort them in ASC order and print.\nimport java.util.Arrays; import java.util.Comparator; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); List\u0026lt;Integer\u0026gt; res = list.stream().sorted(Comparator.naturalOrder()).toList(); System.out.println(res); } } Output\n[1, 2, 4, 5, 7, 8, 9, 9, 24, 36, 78, 222] 21. # Given a list of numbers, sort them in DESC order and print.\nimport java.util.Arrays; import java.util.Comparator; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); List\u0026lt;Integer\u0026gt; res = list.stream().sorted(Comparator.reverseOrder()).toList(); System.out.println(res); } } Output\n[222, 78, 36, 24, 9, 9, 8, 7, 5, 4, 2, 1] 22. # Given a list of numbers, return the first 5 elements and their sum.\nimport java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); int res = list.stream().limit(5).mapToInt(e -\u0026gt; e).sum(); System.out.println(res); } } Output\n30 23. # Given a list of numbers, skip first 5 numbers and return the sum of remaining numbers.\nimport java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); int res = list.stream().skip(5).reduce(0, (subRes, e) -\u0026gt; subRes + e); System.out.println(res); } } Output\n375 24. # import java.util.Arrays; import java.util.List; public class Learn { public static void main(String[] args) { List\u0026lt;Integer\u0026gt; list = Arrays.asList(1, 7, 8, 9, 5, 2, 36, 4, 78, 222, 24, 9); List\u0026lt;Integer\u0026gt; res = list.stream().map(e -\u0026gt; Math.powExact(e, 3)).toList(); System.out.println(res); } } Output\n[1, 343, 512, 729, 125, 8, 46656, 64, 474552, 10941048, 13824, 729] ","date":"16 December 2025","externalUrl":null,"permalink":"/posts/java/java-code-snippets/","section":"Welcome to my Blog!","summary":"","title":"Getting Familiar with Common Java Code Snippets","type":"posts"},{"content":"In this blog post we look at the fundamental concepts relatied to Java such as data types, keywords, operators, control statements, OOPs concepts.\nWhat is Java? # Java is a programming language and computing platform first released by Sun Microsystems in 1995. Its core principle is “Write Once, Run Anywhere” (WORA), meaning Java code can run on any device or operating system that has a Java Virtual Machine (JVM).\nWhat is Java Virtual Machine (JVM)? # Java Virtual Machine or JVM, loads, verifies, and runs Java bytecode. JVM is responsible for converting bytecode to machine-specific code and is necessary in both JDK and JRE.\nJVM consists of three main components or subsystems:\nClass Loader Subsystem is responsible for loading, linking, and initializing a Java class file, otherwise known as dynamic class loading. Runtime Data Areas contain method areas, PC registers, stack areas, and threads. Execution Engine contains an interpreter, compiler, and garbage collection area. What is Java Runtime Environment (JRE)? # The Java Runtime Environment, or JRE, is a software layer that runs on top of a computer’s operating system software and provides the class libraries and other resources that a specific Java program requires to run.\nIf a you would like to run a Java program and not develop or compile code then only JRE is needed.\nWhat is Java Development Kit (JDK)? # Java Development Kit, or JDK, is a software development kit that is a superset of JRE. It is the foundational component that enables Java application and Java applet development. It is platform-specific, so separate installers are needed for each operating system\nWhat is Just-in-time Compiler (JIT) # JIT is part of JVM and optimizes the conversion of bytecode to machine code. It selects similar bytecodes to compile at the same time, reducing the overall duration of bytecode to machine code compilation.\nUnderstanding few command line tools # To understand the various command line tools available with the JDK, we assume the following simple program:\npublic class Learn { public static void main(String[] args) { System.out.println(\u0026#34;Hello World\u0026#34;); } } The javac command is used to compile Java programs, it takes .java file as input and produces bytecode. # command javac Learn.java After running the javac command a new file with .class extension is created.\n# command ls # output Learn.java Learn.class \u0026lt;-- created after running javac The java command is used to execute the bytecode of java. It takes byte code as input and runs it and produces the output. # command java Learn # output Hello World In case a package exists such as package com.example then the java command should be executed from the folder root and pass java com.example.Learn\n# folder structure project_folder \u0026lt;-- run java command from here when package is com.example |__com\\ |__example\\ |__Learn.java |__Learn.class The javap command is used to disassemble one or more class files. # command javap Learn # output Compiled from \u0026#34;Learn.java\u0026#34; public class Learn { public Learn(); public static void main(java.lang.String[]); } Understanding classpath and JAVA_HOME # classpath # The classpath is an environment variable used by the Java Virtual Machine (JVM) to locate and load classes when running a Java program. It specifies a list of directories, JAR files, and ZIP files where the JVM should look to find and load class files.\nTo set the classpath via the command line, we use the -classpath option when running the java command:\njava -classpath /path/to/class/files Learn\nJAVA_HOME # The JAVA_HOME environment variable points to the JDK installation directory. Subsequently, other Java-dependent programs can use this variable to access the JDK/JRE path\nData Types in Java # Data types specify the type of values a variable can hold. They define the size, range and nature of data stored in memory. Java has two main categories of data types:\nPrimitive: byte, short, int, long, float, double, char, boolean Non-Primitive: String, Arrays, Classes, Interfaces, Objects Primitive Data Types # There are eight primitive data types in Java:\nbyte: The byte data type is an 8-bit signed two\u0026rsquo;s complement integer. It has a minimum value of -128 and a maximum value of 127 (inclusive). byte b = 100; short: The short data type is a 16-bit signed two\u0026rsquo;s complement integer. It has a minimum value of -32,768 and a maximum value of 32,767 (inclusive). short s = 30000; int: By default, the int data type is a 32-bit signed two\u0026rsquo;s complement integer, which has a minimum value of -2^31 and a maximum value of 2^31-1. In Java SE 8 and later, you can use the int data type to represent an unsigned 32-bit integer, which has a minimum value of 0 and a maximum value of 2^32-1. int i = 100000; long: The long data type is a 64-bit two\u0026rsquo;s complement integer. The signed long has a minimum value of -2^63 and a maximum value of 2^63-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 2^64-1. long l = 10000000000L; float: The float data type is a single-precision 32-bit IEEE 754 floating point. Sufficient for storing 6 to 7 decimal digits. This data type should never be used for precise values, such as currency. float f = 3.14f; double: The double data type is a double-precision 64-bit IEEE 754 floating point. Sufficient for storing 15 to 16 decimal digits. This data type should never be used for precise values, such as currency. double d = 3.14159265359; char: The char data type is a single 16-bit Unicode character. It has a minimum value of \u0026lsquo;\\u0000\u0026rsquo; (or 0) and a maximum value of \u0026lsquo;\\uffff\u0026rsquo; (or 65,535 inclusive). char c = \u0026#39;A\u0026#39;; boolean: The boolean data type has only two possible values: true and false. This data type represents one bit of information, but its \u0026ldquo;size\u0026rdquo; isn\u0026rsquo;t something that\u0026rsquo;s precisely defined. boolean flag = true; Non-Primitive Data Types # Non-primitive data types, also known as reference types, represent complex data and more sophisticated structures than primitive types.\nClass and Objects Class is a user-defined data type that is used to create objects. A class contains a set of properties and methods that are common and exhibited by all the objects of the class.\nA static method is a method that is associated with the class in which it is defined rather than with any object. Every instance of the class shares its static methods.\nYou can create several different types of nested classes in Java. The different Java nested class types are:\nStatic nested classes Non-static nested classes Local classes Anonymous classes // define a single public class in a .java file public class Learn { public static void main(String[] args) { System.out.println(\u0026#34;Hello World\u0026#34;); } } Static inner class\npublic class Outer { void display() { System.out.println(\u0026#34;method on outer class\u0026#34;); } // static inner class static class Inner { // cannot access display() method since inner class is static void show() { System.out.println(\u0026#34;method inside static inner class\u0026#34;); } } public static void main(String[] args) { Outer o = new Outer(); o.display(); // static inner class instantiation Outer.Inner i = new Outer.Inner(); i.show(); } } Output\nmethod on outer class method inside static inner class Non-static inner class\npublic class Outer { void display() { System.out.println(\u0026#34;method on outer class\u0026#34;); } void close() { System.out.println(\u0026#34;close method from outer class\u0026#34;); } class Inner { void show() { System.out.println(\u0026#34;method inside static inner class\u0026#34;); // accessed from Outer class. possible since Inner class is not static close(); } } public static void main(String[] args) { Outer o = new Outer(); o.display(); // non-static inner class instantiation Outer.Inner i = new Outer().new Inner(); i.show(); } } Output\nmethod on outer class method inside static inner class close method from outer class Inner Class Shadowing\npublic class Learn { void main() { Outer o = new Outer(); System.out.println(o.getText()); Outer.Inner i = o.new Inner(); i.printText(); } } class Outer { private String text = \u0026#34;I am Outer private!\u0026#34;; public class Inner { private String text = \u0026#34;I am Inner private\u0026#34;; public void printText() { System.out.println(text); System.out.println(Outer.this.text); } } public String getText() { return text; } } Output\nI am Outer private! I am Inner private I am Outer private! Anonymous classes in Java are nested classes without a class name. They are typically declared as either subclasses of an existing class, or as implementations of some interface.\nInterface implemented as anonymous class\npublic class Learn { public static void main(String[] args) { // anonymous class implementation VerifyAge a = new VerifyAge() { @Override public boolean above18(int age) { return (age \u0026gt;= 18) ? true : false; } }; System.out.println(a.above18(20)); } } interface VerifyAge { boolean above18(int age); } Output\ntrue Anonymous Class Extends Example\npublic class Learn { public static void main(String[] args) { SuperClass anom = new SuperClass() { public void disp() { System.out.println(\u0026#34;Anonymous class\u0026#34;); } public void newDisp() { System.out.println(\u0026#34;new impl\u0026#34;); } }; // anonymous class prints extended overriden method output // according to java \u0026#39;class Learn$1 extends SuperClass {} anom.disp(); // anom.newDisp(); gives compile error as anom variable is of type SuperClass } } class SuperClass { public void disp() { System.out.println(\u0026#34;SuperClass\u0026#34;); } } String Strings are capable of containing sequences of characters within a single variable, unlike character arrays where each character is stored separately. When a String is formed as a literal with the assistance of an assignment operator, it makes its way into the String constant pool so that String Interning can take place. This same object in the heap will be referenced by a different String if the content is the same for both of them.\nString pool is a subset of the heap memory.\n// Both a and b refer to the same string in the pool area String a = \u0026#34;Hello\u0026#34;; String b = \u0026#34;Hello\u0026#34;; // Both a and b refer to two different memory address in the heap String a = new String(\u0026#34;World\u0026#34;); String b = new String(\u0026#34;World\u0026#34;); Array Arrays are non primitive data types in Java that are used to store elements of the same data type in a contiguous manner. Arrays have a unique reference name by which all their elements are accessed. Elements are stored in an indexed manner where the index starts from 0.\nint[] arr = new int[5]; int arr[] = {1,2,3,4,5}; // Declaration \u0026amp; Initialization as well Interface Interace in Java is a tool to achieve abstraction. Interface can contain non-implemented methods (without the method body) also known as abstract methods. All method declarations in an interface are implicitly public.\nDefault methods in Interfaces enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces. If you don’t want the implementation to be overridden in the implementing class, then you can declare the method as static.\ninterface Vehicle { default void start() { System.out.println(\u0026#34;Starting vehicle\u0026#34;); } void stop(); static int add(int a, int b) { return a + b; } } class Car implements Vehicle { @Override public void stop() { System.out.println(\u0026#34;Stoping vehicle\u0026#34;); } } public class Learn { public static void main(String[] args) { Car c = new Car(); // default method c.start(); // implemented in Car class c.stop(); // static method is not accessible from implementation class System.out.println(Vehicle.add(1, 5)); } } Output:\nStarting vehicle Stoping vehicle 6 An interface with exactly one abstract method is called Functional Interface. @FunctionalInterface annotation is added so that we can mark an interface as functional interface.\n@FunctionalInterface interface Calculator { int calculate(int a, int b); } public class Learn { public static void main(String[] args) { Calculator c = (a,b)-\u0026gt;{ return a+b; }; int res = c.calculate(10, 15); System.out.println(res); } } Output\n25 Interfaces are able to use private methods to hide details on implementation from classes that implement the interface. As a result, one of the main benefits of having these in interfaces is encapsulation.\ninterface Building { static void structure() { System.out.println(\u0026#34;creating structure\u0026#34;); walls(); } private static void walls() { System.out.println(\u0026#34;generating walls!\u0026#34;); } default void paint() { System.out.println(\u0026#34;starting paint\u0026#34;); decoration(); } private void decoration() { System.out.println(\u0026#34;adding decoration!\u0026#34;); } } class MyHome implements Building { } public class Learn { public static void main(String[] args) { // not accessible via MyHome as method is static Building.structure(); MyHome h = new MyHome(); // h.decoration() is not accessible as its private h.paint(); } } Output\ncreating structure generating walls! starting paint adding decoration! Sealing allows classes and interfaces to define their permitted subtypes. In other words, a class or interface can define which classes can implement or extend it. It’s a useful feature for domain modeling, and increasing the security of libraries.\nnon-sealed just \u0026ldquo;breaks the seal\u0026rdquo;, so the effect doesn\u0026rsquo;t have to be carried on down the hierarchy. The extending class is open for being extended by unknown subclasses itself. final is effectively the same as sealed without any class specified after the permits clause. Notice that specifying nothing after permits is not possible, so sealed cannot replace final.\n// Car and Truck class should be available during compile time // with sealed keyword permits should be used sealed interface Service permits Car, Truck { int getMaxServiceIntervalInMonths(); default int getMaxDistanceBetweenServicesInKilometers() { return 100000; } } // no class can inherit Car class final class Car implements Service { @Override public int getMaxServiceIntervalInMonths() { return 10; } } // non-sealed allows any unknown class to extend Truck class non-sealed class Truck implements Service { @Override public int getMaxServiceIntervalInMonths() { return 150; } } Operators in Java # Arithmetic Operators # public class Learn { public static void main(String[] args) { int a = 10; int b = 3; System.out.println(\u0026#34;a + b = \u0026#34; + (a + b)); System.out.println(\u0026#34;a - b = \u0026#34; + (a - b)); System.out.println(\u0026#34;a * b = \u0026#34; + (a * b)); // / returns the quotient System.out.println(\u0026#34;a / b = \u0026#34; + (a / b)); // % returns the reminder System.out.println(\u0026#34;a % b = \u0026#34; + (a % b)); } } Output\na + b = 13 a - b = 7 a * b = 30 a / b = 3 a % b = 1 Relational Operators # public class Learn { public static void main(String[] args) { int a = 10; int b = 3; // return false System.out.println(\u0026#34;a == b : \u0026#34; + (a == b)); // return true System.out.println(\u0026#34;a != b : \u0026#34; + (a != b)); // return true as 10 is greater than 3 // when both a=b then a \u0026gt; b is false System.out.println(\u0026#34;a \u0026gt; b : \u0026#34; + (a \u0026gt; b)); // return false as 3 is not greater than 10 // when both a=b then a \u0026gt; b is false System.out.println(\u0026#34;a \u0026lt; b : \u0026#34; + (a \u0026lt; b)); // return true System.out.println(\u0026#34;a \u0026gt;= b : \u0026#34; + (a \u0026gt;= b)); // return false System.out.println(\u0026#34;a \u0026lt;= b : \u0026#34; + (a \u0026lt;= b)); } } Output\na == b : false a != b : true a \u0026gt; b : true a \u0026lt; b : false a \u0026gt;= b : true a \u0026lt;= b : false Logical Operator # public class Learn { public static void main(String[] args) { boolean x = true; boolean y = false; // logical \u0026amp;\u0026amp; System.out.println(\u0026#34;x \u0026amp;\u0026amp; y : \u0026#34; + (x \u0026amp;\u0026amp; y)); // logical or System.out.println(\u0026#34;x || y : \u0026#34; + (x || y)); // logical not System.out.println(\u0026#34;!x : \u0026#34; + (!x)); } } Output\nx \u0026amp;\u0026amp; y : false x || y : true !x : false Assignment Operator # public class Learn { public static void main(String[] args) { int c = 5; // c = c + 3 // c =+ 3 is not the same. It is assignment of +3 to c. c += 3; System.out.println(\u0026#34;c += 3: \u0026#34; + c); // c = c - 2 c -= 2; System.out.println(\u0026#34;c -= 2: \u0026#34; + c); // c = c * 4 c *= 4; System.out.println(\u0026#34;c *= 4: \u0026#34; + c); // c = c / 2 c /= 2; System.out.println(\u0026#34;c /= 2: \u0026#34; + c); // c = c % 3 c %= 3; System.out.println(\u0026#34;c %= 3: \u0026#34; + c); } } Output\nc += 3: 8 c -= 2: 6 c *= 4: 24 c /= 2: 12 c %= 3: 0 Unary Operator # public class Learn { public static void main(String[] args) { int x = 1; // unary + System.out.println(\u0026#34;+x: \u0026#34; + (+x)); // unary - System.out.println(\u0026#34;-x: \u0026#34; + (-x)); // value of x is 1 System.out.println(\u0026#34;x: \u0026#34; + x); // value of x++ returns the same value that is 1 but it increment the value of x by 1 System.out.println(\u0026#34;x++: \u0026#34; + (x++)); // value of x is 2 System.out.println(\u0026#34;x: \u0026#34; + x); // value of ++x return the incremented value of x that is 3 System.out.println(\u0026#34;++x: \u0026#34; + (++x)); // value of x is still 3 System.out.println(\u0026#34;x: \u0026#34; + x); } } Output\n+x: 1 -x: -1 x: 1 x++: 1 x: 2 ++x: 3 x: 3 Ternary Operator # public class Learn { public static void main(String[] args) { int a = 10; int b = 3; int max = (a \u0026gt; b) ? a : b; System.out.println(\u0026#34;max of a and b = \u0026#34; + max); } } Output\nmax of a and b = 10 Bitwise Operator # public class Learn { public static void main(String[] args) { int p = 5; // 0101 int q = 3; // 0011 // 0101 AND 0011 = 0001 System.out.println(\u0026#34;p \u0026amp; q: \u0026#34; + (p \u0026amp; q)); // 0101 OR 0011 = 0111 System.out.println(\u0026#34;p | q: \u0026#34; + (p | q)); // 0101 XOR 0011 = 0110 System.out.println(\u0026#34;p ^ q: \u0026#34; + (p ^ q)); // COMPLEMENT 0000 0101 = 1111 1010 // left most bit is 1 means number is negative // to get actual value take 2\u0026#39;s complement and add 1 // 2\u0026#39;s complement 1111 1010 = 0000 0101 +1 is 0000 0110 // 0000 0110 is -6 // it’s equivalent to the ! operator. System.out.println(\u0026#34;~p: \u0026#34; + (~p)); // signed Left Shift \u0026lt;\u0026lt; by 1 System.out.println(\u0026#34;p \u0026lt;\u0026lt; 1: \u0026#34; + (p \u0026lt;\u0026lt; 1)); // signed right Shift \u0026gt;\u0026gt; by 2 System.out.println(\u0026#34;p \u0026gt;\u0026gt; 2: \u0026#34; + (p \u0026gt;\u0026gt; 2)); // unsigned right shift [\u0026gt;\u0026gt;\u0026gt;] System.out.println(\u0026#34;p \u0026gt;\u0026gt;\u0026gt; 1: \u0026#34; + (p \u0026gt;\u0026gt;\u0026gt; 1)); } } Output\np \u0026amp; q: 1 p | q: 7 p ^ q: 6 ~p: -6 p \u0026lt;\u0026lt; 1: 10 p \u0026gt;\u0026gt; 2: 1 p \u0026gt;\u0026gt;\u0026gt; 1: 2 Java Control Flow Statements # If Statement # public class Learn { public static void main(String[] args) { int score = 75; char grade; if (score \u0026gt;= 90) { grade = \u0026#39;A\u0026#39;; } else if (score \u0026gt;= 80) { grade = \u0026#39;B\u0026#39;; } else if (score \u0026gt;= 70) { grade = \u0026#39;C\u0026#39;; } else { grade = \u0026#39;D\u0026#39;; } System.out.println(\u0026#34;Your grade is \u0026#34; + grade); } } Output\nYour grade is C Switch Statement # public class Learn { public static void main(String[] args) { int score = 75; char grade; switch (score / 10) { case 10: case 9: grade = \u0026#39;A\u0026#39;; break; case 8: grade = \u0026#39;B\u0026#39;; break; case 7: grade = \u0026#39;C\u0026#39;; break; default: grade = \u0026#39;D\u0026#39;; break; } System.out.println(\u0026#34;Your grade is \u0026#34; + grade); } } Output\nYour grade is C With Java 14 and above\npublic class Learn { public static void main(String[] args) { int score = 75; char grade; switch (score / 10) { case 10, 9 -\u0026gt; grade = \u0026#39;A\u0026#39;; case 8 -\u0026gt; grade = \u0026#39;B\u0026#39;; case 7 -\u0026gt; grade = \u0026#39;C\u0026#39;; default -\u0026gt; grade = \u0026#39;D\u0026#39;; } System.out.println(\u0026#34;Your grade is \u0026#34; + grade); } } Output\nYour grade is C Java Loop Statements # public class Learn { public static void main(String[] args) { for (int i = 0; i \u0026lt; 10; i++) { System.out.print(i + \u0026#34; \u0026#34;); } } } Output\n0 1 2 3 4 5 6 7 8 9 While Loop # public class Learn { public static void main(String[] args) { int i = 0; //While loop is used when the number of iterations is unknown and depends on a condition that changes during execution while (i \u0026lt; 10) { System.out.print(i + \u0026#34; \u0026#34;); i++; } } } Output\n0 1 2 3 4 5 6 7 8 9 Do-While Loop # public class Learn { public static void main(String[] args) { int i = 0; // The do-while loop ensures that the code block executes at least once before checking the condition. do { System.out.print(i + \u0026#34; \u0026#34;); i++; } while (i \u0026lt; 10); } } Output\n0 1 2 3 4 5 6 7 8 9 Modifying the same with i = 11\npublic class Learn { public static void main(String[] args) { int i = 11; // The do-while loop ensures that the code block executes at least once before checking the condition. do { System.out.print(i + \u0026#34; \u0026#34;); i++; } while (i \u0026lt; 10); } } Output\n11 Continue and Break in Loop Statements # Break in loop statement\npublic class Learn { public static void main(String[] args) { for (int i = 0; i \u0026lt; 10; i++) { // prints upto 3 and exits out of loop at 4 if (i == 4) { break; } System.out.print(i + \u0026#34; \u0026#34;); } } } Output\n0 1 2 3 Continue in loop statement\npublic class Learn { public static void main(String[] args) { for (int i = 0; i \u0026lt; 10; i++) { // skips 4 and prints every other numner between 0 and 9 if (i == 4) { continue; } System.out.print(i + \u0026#34; \u0026#34;); } } } Output\n0 1 2 3 5 6 7 8 9 Java Object Oriented Programming Concepts # Object-Oriented Programming or OOPs refers to languages that use objects in programming. Object-oriented programming aims to implement real-world entities like inheritance, hiding, polymorphism, etc in programming.\nClass # A Class is a user-defined blueprint or prototype from which objects are created. It represents the set of properties or methods that are common to all objects of one type.\n// A simple class example having two private instance, a constructor and public getter and setter class Person { private String name; private int age; public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } Object # An Object is a basic unit of Object-Oriented Programming that represents real-life entities. A typical Java program creates many objects, interact by invoking methods.\n// creating an object of class Person Person p = new Person(\u0026#34;Raj\u0026#34;, 25); Abstraction # Objects only reveal internal mechanisms that are relevant for the use of other objects, hiding any unnecessary implementation code. Abstraction in Java is the process of hiding the implementation details and only showing the essential details or features to the user. Abstraction is achieved by interfaces and abstract classes.\nclass Dog extends Animal { public void animalSound() { System.out.println(\u0026#34;The dog says: woof woof\u0026#34;); } } abstract class Animal { public abstract void animalSound(); public void sleep() { System.out.println(\u0026#34;Zzz\u0026#34;); } } public class Learn { public static void main(String[] args) { Dog d = new Dog(); d.animalSound(); // sleep method is not defined in the Dog class // a simple example of abstraction d.sleep(); } } Output\nThe dog says: woof woof Zzz Encapsulation # The encapsulation principle states that all important information is contained inside an object and only select information is exposed. Encapsulation is defined as the process of wrapping data and the methods into a single unit, typically a class. It is the mechanism that binds together the code and the data.\nThe Person class shows an example of encapsulation where the instance variables are private and these variable are accessiable through public getter and setter methds.\nInheritance # Classes can reuse code and properties from other classes. It is the mechanism in Java by which one class is allowed to inherit the features (fields and methods) of another class. We are achieving inheritance by using extends keyword. Inheritance is also known as \u0026ldquo;is-a\u0026rdquo; relationship.\nPolymorphism # Objects are designed to share behaviors, and they can take on more than one form.\nPolymorphism in Java is mainly of 2 types as mentioned below:\nCompile-Time Polymorphism (Method overloading) Compile-Time Polymorphism in Java is also known as static polymorphism and also known as method overloading.\npublic class Learn { public static void main(String[] args) { // method overloading by have same method name but different argument data type System.out.println(Helper.Multiply(2, 4)); System.out.println(Helper.Multiply(5.5, 6.3)); } } class Helper { static int Multiply(int a, int b) { return a * b; } static double Multiply(double a, double b) { return a * b; } } Output\n8 34.65 Runtime Polymorphism (Method Overriding) Runtime Polymorphism in Java known as Dynamic Method Dispatch. It is a process in which a function call to the overridden method is resolved at Runtime. This type of polymorphism is achieved by Method Overriding.\npublic class Learn { public static void main(String[] args) { Apartment a = new Apartment(); a.Print(); // dynamically replace Print method of parent with child a = new DinnerRoom(); a.Print(); a = new LivingRoom(); a.Print(); } } class Apartment { void Print() { System.out.println(\u0026#34;Apartment structure\u0026#34;); } } class DinnerRoom extends Apartment { @Override void Print() { System.out.println(\u0026#34;Dinner room\u0026#34;); } } class LivingRoom extends Apartment { @Override void Print() { System.out.println(\u0026#34;Living room\u0026#34;); } } Output\nApartment structure Dinner room Living room Java Records # A Java Record is a special kind of Java class which has a concise syntax for defining immutable data-only classes. Java Record instances can be useful for holding records returned from a database query, records returned from a remote service call, records read from a CSV file, or similar types of use cases.\nThe Java compiler auto generates getter methods, toString(), hashcode() and equals() methods for these data fields, so you don\u0026rsquo;t have to write that boilerplate code yourself. Since a Java Record is immutable, no setter methods are generated.\nExample of record class\npublic class Learn { public static void main(String[] args) { DataUnit du = new DataUnit(1, \u0026#34;Apple\u0026#34;); System.out.println(du.id()); System.out.println(du.type()); } } record DataUnit(int id, String type) { } Output\n1 Apple A record class can have multiple constructors\npublic class Learn { public static void main(String[] args) { DataUnit du = new DataUnit(1, \u0026#34;Apple\u0026#34;); System.out.println(du.id()); System.out.println(du.type()); DataUnit du1 = new DataUnit(2); System.out.println(du1.id()); System.out.println(du1.type()); } } record DataUnit(int id, String type) { // canonical constructor performing a check on the arguments public DataUnit { if (id \u0026lt;= 0 || type == null) { throw new java.lang.IllegalArgumentException(\u0026#34;invalid\u0026#34;); } } // new constructor accepting only one argument public DataUnit(int id) { this(id, \u0026#34;AUTO\u0026#34;); } } Record class support adding instance and static methods\npublic class Learn { public static void main(String[] args) { DataUnit du = new DataUnit(1, \u0026#34;Apple\u0026#34;); System.out.println(du.id()); System.out.println(du.type()); System.out.println(du.typeAsLowerCase()); DataUnit du1 = new DataUnit(2); System.out.println(du1.id()); System.out.println(du1.type()); System.out.println(DataUnit.brandAsUpperCase(du1)); } } record DataUnit(int id, String type) { // canonical constructor performing a check on the arguments public DataUnit { if (id \u0026lt;= 0 || type == null) { throw new java.lang.IllegalArgumentException(\u0026#34;invalid\u0026#34;); } } // new constructor accepting only one argument public DataUnit(int id) { this(id, \u0026#34;AUTO\u0026#34;); } // instance method public String typeAsLowerCase() { return type().toLowerCase(); } // static method public static String brandAsUpperCase(DataUnit unit) { return unit.type.toUpperCase(); } } Output\n1 Apple apple 2 AUTO AUTO Java Lambda Expressions # Java lambda expressions are new in Java 8. Java lambda expressions are Java\u0026rsquo;s first step into functional programming. A Java lambda expression is thus a function which can be created without belonging to any class. A Java lambda expression can be passed around as if it was an object and executed on demand.\nJava lambda expression example\npublic class Learn { public static void main(String[] args) { // lambda expression Printer p = a -\u0026gt; System.out.println(a); // calling the lambda expression p.print(\u0026#34;hello world\u0026#34;); } } interface Printer { public void print(String value); } Output\nhello world Another example of lambda expressions\npublic class Learn { public static void main(String[] args) { // lambda expression to find sum Calculator add = (a, b) -\u0026gt; a + b; // lambda expression to find difference Calculator subtract = (a, b) -\u0026gt; a - b; // result: 8 int resultAdd = add.calculate(5, 3); // result: 2 int resultSubtract = subtract.calculate(5, 3); System.out.println(\u0026#34;Addition: \u0026#34; + resultAdd); System.out.println(\u0026#34;Subtraction: \u0026#34; + resultSubtract); } } interface Calculator { int calculate(int a, int b); } Output\nAddition: 8 Subtraction: 2 Even though lambda expressions are close to anonymous interface implementations, there are a few differences that are worth noting. The major difference is, that an anonymous interface implementation can have state (member variables) whereas a lambda expression cannot.\nIn an anonymous class, this keyword refers to the anonymous class itself. But in the case of a lambda expression, this refers to its enclosing class.\nWe can also declare member variables in an anonymous class, which isn’t possible in the case of a lambda expression. Thus, an anonymous class can have a state. Variables declared inside the lambda expression act as local variables. Both of them, though, have access to member variables of the enclosing class.\nAn example of state with anonymous and lambda expression:\nAnonymous public class Learn { public static void main(String[] args) { SimpleInterface impl = new SimpleInterface() { // count variable is the instance variable (field variable) private int count = 0; @Override public int func() { return ++count; } }; System.out.println(impl.func()); System.out.println(impl.func()); } } interface SimpleInterface { int func(); } Output\n1 2 Lambda expression public class Learn { public static void main(String[] args) { SimpleInterface impl = () -\u0026gt; { // the count variable in the lambda expression is local variable int count = 0; return ++count; }; System.out.println(impl.func()); System.out.println(impl.func()); } } interface SimpleInterface { int func(); } Output\n1 1 Java Access Modifiers # A Java access modifier specifies which classes can access a given class and its fields, constructors and methods. Classes, fields, constructors and methods can have one of four different Java access modifiers:\nprivate default (package) protected public References # https://www.ibm.com/think/topics/jvm-vs-jre-vs-jdk https://www.baeldung.com/java-classpath-vs-build-path https://www.scaler.com/topics/non-primitive-data-types-in-java/ https://stackoverflow.com/questions/63972130/what-is-the-difference-between-a-final-and-a-non-sealed-class-in-java-15s-seale https://www.geeksforgeeks.org/java/object-oriented-programming-oops-concept-in-java/ https://jenkov.com/ ","date":"15 December 2025","externalUrl":null,"permalink":"/posts/java/java-basics/","section":"Welcome to my Blog!","summary":"","title":"Introduction to Java Fundamentals Concepts","type":"posts"},{"content":"","date":"10 December 2025","externalUrl":null,"permalink":"/posts/algorithms/","section":"Welcome to my Blog!","summary":"","title":"Algorithms","type":"posts"},{"content":"The article explores multi-threading concepts in to Java.\nMultithreading means that you have multiple threads of execution inside the same application. A thread is like a separate CPU executing your application. Thus, a multithreaded application is like an application that has multiple CPUs executing different parts of the code at the same time. A thread is not equal to a CPU though. Usually a single CPU will share its execution time among multiple threads, switching between executing each of the threads for a given amount of time. It is also possible to have the threads of an application be executed by different CPUs.\nConcurrency means that an application is making progress on more than one task at the same time or at least seemingly at the same time (concurrently).\nParallel execution is when a computer has more than one CPU or CPU core, and makes progress on more than one task simultaneously. However, parallel execution is not referring to the same phenomenon as parallelism.\nThe term parallelism means that an application splits its tasks up into smaller subtasks which can be processed in parallel, for instance on multiple CPUs at the exact same time.\nA race condition is a concurrency problem that may occur inside a critical section. A critical section is a section of code that is executed by multiple threads and where the sequence of execution for the threads makes a difference in the result of the concurrent execution of the critical section.\nRace conditions can occur when two or more threads read and write the same variable according to one of these two patterns:\nRead-modify-write Check-then-act The read-modify-write pattern means, that two or more threads first read a given variable, then modify its value and write it back to the variable.\nThe check-then-act pattern means, that two or more threads check a given condition, for instance if a Map contains a given value, and then go on to act based on that information\nThread # A Java Thread is like a virtual CPU that can execute your Java code.\nTwo ways to create threads\nCreate a subclass of Thread and override the run() method. Two ways to implement Thread subclass:\nextends Thread class public class ThreadExample { public static void main(String[] args) { MyThread threadExample = new MyThread(); threadExample.start(); System.out.println(\u0026#34;run by main thread. thread name: \u0026#34; + Thread.currentThread().getName()); } } class MyThread extends Thread { public void run() { System.out.println(\u0026#34;class extends thread example. thread name: \u0026#34; + getName()); } } Output\nclass extends thread example. thread name: Thread-0 run by main thread. thread name: main Anonymous Thread class public class AnonymousThreadExample { public static void main(String[] args) { Thread thread = new Thread() { public void run() { System.out.println(\u0026#34;anonymous thread example. thread name: \u0026#34; + getName()); } }; thread.start(); System.out.println(\u0026#34;run by main thread. name: \u0026#34; + Thread.currentThread().getName()); } } Output\nrun by main thread. name: main anonymous thread example. thread name: Thread-0 Pass an object that implements Runnable (java.lang.Runnable, method run()) to the Thread constructor. Three ways to implement Runnable:\nCreate a Java class that implements the Runnable interface. public class RunnableThreadExampl { public static void main(String[] args) { Runnable runnable = new RunnableThread(); Thread thread = new Thread(runnable); thread.start(); System.out.println(\u0026#34;run by main thread. name: \u0026#34; + Thread.currentThread().getName()); } } class RunnableThread implements Runnable { @Override public void run() { System.out.println(\u0026#34;class implements runnable. thread name: \u0026#34; + Thread.currentThread().getName()); } } Output\nclass implements runnable. thread name: Thread-0 run by main thread. name: main Create an anonymous class that implements the Runnable interface. public class AnonymousRunnableThreadExample { public static void main(String[] args) { Runnable myRunnable = new Runnable() { public void run() { System.out .println(\u0026#34;anonymous runnable thread example. thread name: \u0026#34; + Thread.currentThread().getName()); } }; Thread thread = new Thread(myRunnable); thread.start(); System.out.println(\u0026#34;run by main thread. name: \u0026#34; + Thread.currentThread().getName()); } } Output\nrun by main thread. name: main anonymous runnable thread example. thread name: Thread-0 Create a Java Lambda that implements the Runnable interface. public class LambdaRunnableThreadExample { public static void main(String[] args) { Runnable runnable = () -\u0026gt; System.out .println(\u0026#34;lambda runnable thread example. thread name: \u0026#34; + Thread.currentThread().getName()); Thread thread = new Thread(runnable); thread.start(); System.out.println(\u0026#34;run by main thread. name: \u0026#34; + Thread.currentThread().getName()); } } Output\nrun by main thread. name: main lambda runnable thread example. thread name: Thread-0 When creating and starting a thread a common mistake is to call the run() method of the Thread instead of start(). Always start a thread with start().\nThe Thread.currentThread() method returns a reference to the Thread instance executing currentThread() . The JVM and/or operating system determines the order in which the threads are executed. This order does not have to be the same order in which they were started. (Pause a Thread) A thread can pause itself by calling the static method Thread.sleep() . The sleep() takes a number of milliseconds as parameter. A daemon thread in Java is a thread that does not keep the Java Virtual Machine (JVM) running if the main thread exits the application. A non-daemon thread will keep the JVM running even if the main thread exits the application.\nYou tell a Thread to be a daemon thread via its setDaemon() method. Virtual Thread # Java virtual threads are different from the original platform threads in that virtual threads are much more lightweight in terms of how many resources (RAM) they demand from the system to run. Java virtual threads are executed by platform threads. A platform thread can only execute one virtual thread at a time. While the virtual thread is being executed by a platform thread - the virtual thread is said to be mounted to that thread.\nA platform thread is implemented as a thin wrapper around an operating system (OS) thread. A platform thread runs Java code on its underlying OS thread, and the platform thread captures its OS thread for the platform thread\u0026rsquo;s entire lifetime. This platform thread is called a carrier.\nThere is no time slicing happening between virtual threads. In other words, the platform thread does not switch between executing multiple virtual threads, except in the case of blocking network calls. As long as a virtual thread is running code and is not blocked waiting for a network response, the platform thread will keep executing the same virtual thread.\npublic class VirtualThreadsExample { public static void main(String[] args) { Runnable runnable = () -\u0026gt; System.out .println(\u0026#34;virtual thread example. thread name: \u0026#34; + Thread.currentThread().getName()); Thread vThread = Thread.ofVirtual().name(\u0026#34;this-is-virtual-thread\u0026#34;).start(runnable); try { vThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(\u0026#34;run by main thread. name: \u0026#34; + Thread.currentThread().getName()); } } Output\nvirtual thread example. thread name: this-is-virtual-thread run by main thread. name: main Executor Service # The Java ExecutorService interface, java.util.concurrent.ExecutorService, represents an asynchronous execution mechanism which is capable of executing tasks concurrently in the background\nThe implementation of the ExecutorService interface present in the java.util.concurrent package is a thread pool implementation.\nSince ExecutorService is an interface, you need to its implementations in order to make any use of it. The ExecutorService has the following implementation in the java.util.concurrent package:\nThreadPoolExecutor ScheduledThreadPoolExecutor An Executor is an interface in Java that provides a way of decoupling task submission from the mechanics of how each task will be run. Instead of manually creating and managing threads, you can delegate tasks to an Executor, which handles the details of executing tasks in the background.\nTask Submission Simplified: Instead of manually starting threads, you submit tasks (usually in the form of Runnable or Callable) to the Executor and let it decide when to execute them.\nThread Management: Executors handle the creation, reuse, and management of threads internally, allowing you to focus on the logic of your tasks.\nThe Runnable interface is very similar to the Callable interface. The Runnable interface represents a task that can be executed concurrently by a thread or an ExecutorService.\nThe Callable can only be executed by an ExecutorService.\nThe java.util.concurrent.ThreadPoolExecutor is an implementation of the ExecutorService interface. The ThreadPoolExecutor executes the given task (Callable or Runnable) using one of its internally pooled threads.\nThe java.util.concurrent.ScheduledExecutorService is an ExecutorService which can schedule tasks to run after a delay, or to execute repeatedly with a fixed interval of time in between each execution. Tasks are executed asynchronously by a worker thread, and not by the thread handing the task to the ScheduledExecutorService.\nExecutor Shutdown # If your application is started via a main() method and your main thread exits your application, the application will keep running if you have an active ExexutorService in your application. The active threads inside this ExecutorService prevents the JVM from shutting down.\nSynchronized Keyword # A piece of logic marked with synchronized becomes a synchronized block, allowing only one thread to execute at any given time.\nWe can use the synchronized keyword on different levels:\nInstance methods Static methods Code blocks Volatile Keyword # To ensure that updates to variables propagate predictably to other threads, we should apply the volatile modifier to those variables. The synchronized methods and blocks provide both Mutual Exclusion and Visibility (changes made by one thread to the shared data are visible to other threads to maintain data consistency) properties at the cost of application performance. The volatile field is quite a useful mechanism because it can help ensure the visibility aspect of the data change without providing mutual exclusion.\nA shared variable that includes the volatile modifier guarantees that all threads see a consistent value for the shared variable. Any update to a volatile field updates the shared value of the field immediately. In other words, a different thread cannot get an inconsistent value of the shared variable after its value is updated.\nReferences # https://jenkov.com/tutorials/java-concurrency/creating-and-starting-threads.html https://www.baeldung.com/java-synchronized ","date":"10 December 2025","externalUrl":null,"permalink":"/posts/java/java-multithreading/","section":"Welcome to my Blog!","summary":"","title":"Introduction to Multi-threading in Java","type":"posts"},{"content":"","date":"18 November 2025","externalUrl":null,"permalink":"/posts/databases/","section":"Welcome to my Blog!","summary":"","title":"Databases","type":"posts"},{"content":" 1. About # A database is an organized collection of structured information, or data, typically stored electronically in a computer system. A database is usually controlled by a database management system (DBMS). Together, the data and the DBMS, along with the applications that are associated with them, are referred to as a database system, often shortened to just database.\n1.1 Character Set # A character set is a set of characters. A character set can have many collations associated with it, while each collation is only associated with one character set.\n1.2 Collations # A collation comprises the rules for comparing and sorting a particular character set. For example, a subset of a character set could consist of the letters A, B, and C. A default collation could define these as appearing in an ascending order of A, B, and C.\n1.3 Storage Engine # A database transaction symbolizes a unit of work, performed within a database management system (or similar system) against a database, that is treated in a coherent and reliable way independent of other transactions. A transaction generally represents any change in a database.\nThere are two types of database engines:\nTransactional: A transactional database is a DBMS that provides the ACID properties for a bracketed set of database operations (begin-commit). Transactions ensure that the database is always in a consistent state, even in the event of concurrent updates and failures. InnoDB is a storage engine for the database management system MySQL and MariaDB. Non-Transaction: A \u0026ldquo;no transaction\u0026rdquo; database engine refers to a database system that does not support the ACID (Atomicity, Consistency, Isolation, Durability) properties of transactions, often to achieve higher performance or scalability. MyISAM engine was used before MySQL 5.5 and it was replaced by InnoDB. 1.4 Database Management Systems # A database management system (DBMS) is a software system for creating and managing databases. A DBMS enables end users to create, protect, read, update and delete data in a database. It also manages security, data integrity and concurrency for databases. The DBMS essentially serves as an interface between databases and users or application programs, ensuring that data is consistently organized and remains easily accessible.\n1.4.1 Components of a DBMS # Hardware Software Data Procedures Database access query language Users 1.5 Types of DBMS # Relational Database Management Systems (RDBMS) MySQL Oracle Microsoft SQL Server MariaDB NoSQL DBMS MongoDB Cassandra Couchbase 1.6 Data Types # CHAR(n): CHAR is a fixed-length data type. When you define a column as CHAR(n), it reserves n bytes of storage, padding shorter strings with spaces to meet the defined length. Use Case: Ideal for storing data where entries are of consistent length, such as fixed-length codes or identifiers. VARCHAR(n): VARCHAR is a variable-length data type. Defining a column as VARCHAR(n) allows storage of strings up to n characters, using only as much space as needed for each entry, plus additional bytes for length information. Use Case: Suitable for storing data with variable lengths, such as names or addresses. 2. Relational Databases # A relational database is a type of database that stores and provides access to data points that are related to one another. Relational databases are based on the relational model, an intuitive, straightforward way of representing data in tables. In a relational database, each row in the table is a record with a unique ID called the key. The columns of the table hold attributes of the data, and each record usually has a value for each attribute, making it easy to establish the relationships among data points.\nThe relational model means that the logical data structures, the data tables, views, and indexes, are separate from the physical storage structures. This separation means that database administrators can manage physical data storage without affecting access to that data as a logical structure. For example, renaming a database file does not rename the tables stored within it.\nA database typically requires a comprehensive database software program known as a database management system (DBMS). A DBMS serves as an interface between the database and its end users or programs, allowing users to retrieve, update, and manage how the information is organized and optimized. A DBMS also facilitates oversight and control of databases, enabling a variety of administrative operations such as performance monitoring, tuning, and backup and recovery.\nSome examples of popular database software or DBMSs include MySQL, Microsoft Access, Microsoft SQL Server, FileMaker Pro, Oracle Database, and dBASE.\n3. Relational Databases # A relational database is a type of database that stores and provides access to data points that are related to one another. Relational databases are based on the relational model, an intuitive, straightforward way of representing data in tables. In a relational database, each row in the table is a record with a unique ID called the key. The columns of the table hold attributes of the data, and each record usually has a value for each attribute, making it easy to establish the relationships among data points.\nThe relational model means that the logical data structures, the data tables, views, and indexes, are separate from the physical storage structures. This separation means that database administrators can manage physical data storage without affecting access to that data as a logical structure. For example, renaming a database file does not rename the tables stored within it.\nA database typically requires a comprehensive database software program known as a database management system (DBMS). A DBMS serves as an interface between the database and its end users or programs, allowing users to retrieve, update, and manage how the information is organized and optimized. A DBMS also facilitates oversight and control of databases, enabling a variety of administrative operations such as performance monitoring, tuning, and backup and recovery.\nSome examples of popular database software or DBMSs include MySQL, Microsoft Access, Microsoft SQL Server, FileMaker Pro, Oracle Database, and dBASE.\n3.1 Data Definition Language # CREATE CREATE TABLE table_name ( column_1 datatype, column_2 datatype, ..., column_n datatype ); ALTER ALTER TABLE table_name ADD column_name datatype; DROP ALTER TABLE table_name DROP COLUMN column_name; DROP TABLE table_name; RENAME ALTER TABLE table_name RENAME COLUMN old_column_name TO new_column_name; TRUNCATE (The result would be a table with only column names and no values.) TRUNCATE TABLE table_name; COMMENT CREATE TABLE actor ( actor_id String(32767), --unique identifier first_name String(32767), last_name String(32767), last_update String(32767)--datetime of last update ); 3.2 Data Manipulation Language # INSERT INSERT INTO friends (name, birthday) VALUES (‘Billy Joel’, ‘05-09-1949’) UPDATE UPDATE friends SET birthday = \u0026#39;09-16-1992\u0026#39; WHERE name = \u0026#39;Nick Jonas\u0026#39; AND birthday = \u0026#39;08-15-1992\u0026#39;; DELETE DELETE FROM friends WHERE name = \u0026#39;Theresa Guidice\u0026#39; AND birthday = \u0026#39;05-18-1972\u0026#39;; MERGE (MERGE statement in SQL is used to perform insert, update, and delete operations on a target table based on the results of JOIN with a source table.) /* Selecting the Target and the Source */ MERGE PRODUCT_LIST AS TARGET USING UPDATE_LIST AS SOURCE /* 1. Performing the UPDATE operation */ /* If the P_ID is same, check for change in P_NAME or P_PRICE */ ON (TARGET.P_ID = SOURCE.P_ID) WHEN MATCHED AND TARGET.P_NAME \u0026lt;\u0026gt; SOURCE.P_NAME OR TARGET.P_PRICE \u0026lt;\u0026gt; SOURCE.P_PRICE /* Update the records in TARGET */ THEN UPDATE SET TARGET.P_NAME = SOURCE.P_NAME, TARGET.P_PRICE = SOURCE.P_PRICE /* 2. Performing the INSERT operation */ /* When no records are matched with TARGET table Then insert the records in the target table */ WHEN NOT MATCHED BY TARGET THEN INSERT (P_ID, P_NAME, P_PRICE) VALUES (SOURCE.P_ID, SOURCE.P_NAME, SOURCE.P_PRICE) /* 3. Performing the DELETE operation */ /* When no records are matched with SOURCE table Then delete the records from the target table */ WHEN NOT MATCHED BY SOURCE THEN DELETE /* END OF MERGE */ CALL: Runs a stored procedure that returns a void either in the current scope or optionally on a specified cube. A stored procedure is a prepared SQL code that you can save, so the code can be reused over and over again. --create a procedure DELIMITER // Create procedure InsertData ( IN name VARCHAR(30), IN sal INT, IN loc VARCHAR(45)) BEGIN INSERT INTO Emp(Name, Salary, Location) VALUES (name, sal, loc); END // DELIMITER ; CALL InsertData (\u0026#39;Raju\u0026#39;, 35000, \u0026#39;Bangalore\u0026#39;); CALL InsertData (\u0026#39;Raman\u0026#39;, 45000, \u0026#39;Vishakhapatnam\u0026#39;); CALL InsertData (\u0026#39;Rahman\u0026#39;, 55000, \u0026#39;Hyderabad\u0026#39;); EXPLAIN EXPLAIN SELECT * FROM user WHERE name = \u0026#39;van 2\u0026#39;; LOCK LOCK TABLE emp IN ROW SHARE MODE NOWAIT; 3.3 Data Control Language # GRANT GRANT SELECT, INSERT, DELETE ON mydb TO \u0026#39;user1\u0026#39;@\u0026#39;localhost\u0026#39;; REVOKE REVOKE INSERT ON mydb FROM \u0026#39;user1\u0026#39;@\u0026#39;localhost\u0026#39;; 3.4 Transaction Control Language # COMMIT (BEGIN: Starts a transaction. It marks the beginning of a series of operations that should be treated as one unit. COMMIT: Used to save all the changes you made during a transaction permanently.) BEGIN; -- SQL statements COMMIT; ROLLBACK (ROLLBACK: Used to undo changes you made during a transaction if something went wrong.) BEGIN; -- SQL statements ROLLBACK; SAVEPOINT (SAVEPOINT: It lets you set a point inside a transaction to which you can roll back if needed.) BEGIN; -- SQL statements SAVEPOINT my_savepoint; -- More SQL statements ROLLBACK TO my_savepoint; SET TRANSACTION (You use the SET TRANSACTION statement to begin a read-only or read-write transaction, establish an isolation level, or assign your current transaction to a specified rollback segment. Read-only transactions are useful for running multiple queries while other users update the same tables.) SET TRANSACTION ISOLATION LEVEL SERIALIZABLE; --example DECLARE daily_sales REAL; weekly_sales REAL; monthly_sales REAL; BEGIN COMMIT; -- ends previous transaction SET TRANSACTION READ ONLY NAME \u0026#39;Calculate sales figures\u0026#39;; SELECT SUM(amt) INTO daily_sales FROM sales WHERE dte = SYSDATE; SELECT SUM(amt) INTO weekly_sales FROM sales WHERE dte \u0026gt; SYSDATE - 7; SELECT SUM(amt) INTO monthly_sales FROM sales WHERE dte \u0026gt; SYSDATE - 30; COMMIT; -- ends read-only transaction END; 4. Types of Keys # Super key Alternate key Foreign key Surrogate key Nature key Simple key Composite key Compound key Intelligent key Primary key Candidate key 4.1 Primary key # A primary key is a column or columns in a database table with values that uniquely identify each row or record. For example, an employee ID column could be a primary key in a table of employee information.\nA primary key is a special type of a unique key. ALTER TABLE table_name PRIMARY KEY (candidate_key); 4.2 Candidate Key # A Candidate Key is a set of one or more fields/columns that can identify a record uniquely in a table. There can be multiple Candidate Keys in one table. Each Candidate Key can work as a Primary Key.\nWhen we are deciding which column should be primary key the columns that can be primary key are refereed to as candidate keys. Candidate key should exhibit uniqueness across time.\n4.3 Super Key # A super key is a set of one or more than one key that can be used to identify a record uniquely in a table. Super Key can contain multiple attributes that might not be able to identify tuples in a table independently, but when grouped with certain keys, they can identify tuples uniquely.\nA super is something that consists all the attributes of a candidate key plus potentially some additional attributes. Practically not useful only in theory.\n4.4 Alternate Key # An Alternate key is a key that can work as a primary key. It is a candidate key that is currently not a primary key. It is also called a secondary key.\nALTER TABLE table_name ADD UNIQUE (another_candidate_key_that_is_not_primary_key); 4.5 Foreign Key # A foreign key is an attribute that is a Primary key in its parent table but is included as an attribute in another host table. The relation that is being referenced is called the referenced relation, and the corresponding attribute is called the referenced attribute. The relation that refers to the referenced relation is called a referencing relation, and the corresponding attribute is called a referencing attribute. The referenced attribute of the referenced relation should be the primary key to it.\nALTER TABLE child_table_name ADD FOREIGN KEY (column_on_child_table) REFERENCES parent_table_name (primary_key); 4.6 Surrogate Key # A surrogate key on a table is a column with a unique identifier for each row. The key isn\u0026rsquo;t generated from the table data. A surrogate key is a single column that has been artificially added, typically during ETL, and which also contains values that are unique across the table. Because surrogate keys are made up of technical values, they are sometimes also known as synthetic keys.\nSurrogate key stands in for something else. For example we have have state codes as the primary key and the codes can be identified in the real world but lets say we have a state id (a random generated value but unique) as surrogate key. This surrogate key (state id) is not identified in the real world but is understood in the context the database or the application. Surrogate key have real world meaning within the context of our database.\nThe idea of using a surrogate key not to uniquely identify a record but also to ensure that uniqueness is maintained. In the case of stat id, we cannot have different state id referring to same state code.\n4.7 Natural Key (Business key) # A natural key (also known as a business key or domain key) is a type of unique key in a database formed of attributes that exist and are used in the external world outside the database (i.e., in the business domain or domain of discourse).\nReferring back to surrogate key example, we say that the state code is the natural key while the state id is the surrogate key. Example of natural key: your email, bank of mail customer id, insurgence number, ISBN for physical books (e-books have not ISBN) etc. Surrogate key are not shared in the real world.\n4.8 Composite Key # A composite key in SQL combines two or more columns to uniquely identify each record in a table. Database designers use composite keys when a single column cannot ensure uniqueness. The combination of multiple columns provides a unique identifier for each row, enhancing data integrity and retrieval efficiency.\nALTER TABLE table_name PRIMARY KEY (candidate_key_1, candidate_key_2); A key is called composite if it contains more than one attribute.\n4.9 Simple Key # A simple key is just a key using only one attribute in the table. With reference to a composite key, if a key contains only one attribute, it is called a simple key.\n4.10 Compound Key # A compound key is similar to a composite key in that two or more fields are needed to create a unique value. However, a compound key is created when two or more primary keys from different tables are present as foreign keys within an entity. The foreign keys are used together to uniquely identify each record.\nCompound keys are always made up of two or more primary keys from other tables. In their own tables, both of these keys uniquely identify data but in the table using the compound key, they are both needed to uniquely identify data.\nConsider a table Customers with primary key {customer id} and another table Accounts with primary key {account id}. Another table called Customer_Account has a primary key {customer id, account id} where both the columns are a foreign key to their respective table reference. The primary key is called a compound key.\n4.11 Intelligent Key # An intelligent key is a natural key with multiple parts stuck together where each of the part have its own meaning.\n5. Databases Indexes # Types of database indexes:\nStructure Clustered Index Non-Clustered Index Storage Rowstore Index Columnstore Index Function Unique Index Filter Index A heap is a table without a clustered index. Without a cluster index, the writes are fast but reads are slow.\nPage: The smallest unit of data storage in a database. It stores anything: data, metadata, indexes, etc.\nFull Table Scan: SQL scans the entire table, page by page, row by row, searching for data.\n5.1 Clustered Index # Determines the order in which data is physically stored in the table. A clustered index is most useful when we’re searching in a range. Only one clustered index can exist per table (Since data is physically sorted and stored once).\nClustering indexing is a database indexing technique that is used to physically arrange the data in a table based on the values of the clustered index key. This means that the rows in the table are stored on disk in the same order as the clustered index key.\nCREATE CLUSTERED INDEX index_name ON table_name (column1, column2,..); 5.2 Non-Clustered Index # This index does not store data in the order of the index. Instead, it provides a list of virtual pointers or references to the location where the data is actually stored. A non-clustered index won’t reorganize or change anything on the data page.\nThe non-cluster index B-Tree does not have the data within its structure as opposed to a cluster index. Multiple non-cluster index can exist.\nCREATE NONCLUSTERED INDEX index_name ON table_name (column1, column2,..); -- default is non clustered index CREATE INDEX index_name on table_name (column1); -- will create a non clustered index -- on composite index CREATE NONCLUSTERED INDEX index_name ON table_name (column1 DESC, column2 ASC); -- example -- create index as CREATE INDEX ix_index ON mytable (col1, col2 DESC); -- use in query as SELECT * FROM mytable ORDER BY col1, col2 DESC With composite index the order is important. The order provided in the index creation should be used in the query as well to fully utilize the query optimizer. Leftmost Prefix Rule: Index works only if your query filters start from the first column in the index and follows its order.\n5.3 Rowstore Index # A row-oriented database organizes data by rows, with each row containing information about a single entity or record. This is the default. We have the whole record in the data page, and each data page can have multiple records.\nCREATE NONCLUSTERED INDEX index_name ON table_name (column_name, ..);-- by default its rowstore CREATE CLUSTERED INDEX index_name ON table_name (column_name,..); 5.4 Columnstore Index # A columnar database stores data grouped by columns rather than by rows, optimizing performance for analytical queries. Each column contains data of the same type, allowing for efficient compression. And because a query needs to access only relevant columns, the design enhances data retrieval speed.\nCREATE NONCLUSTERED COLUMNSTORE INDEX index_name ON table_name (column_name); CREATE CLUSTERED COLUMNSTORE INDEX index_name ON table_name; 5.4.1 Process of Building Columnstore # The table starts as a normal rowstore heap table.\nRow Group: The data is split. (to allow parallel processing) Column Segment: For each row group, split the data by column Compression: compress common data types Store: store as LOB (large object page) When saving to the disk the column store can be saved as either clustered columnstore or non-clustered columnstore (in either, B-Tree structure is not used). Clustered columnstore: The row based table is completeley replaced with the new columnstore structure. Non-Clustered columnstore: It is an additional structure and does not replace the original table. Therefore, the rowstore heap table is preserved while a new structure for the columnstore is also maintained. With non-clustered columnstore only one column can be selected during the index creation. You cannot have multiple columns stores. It can either be a clustered or non-clustered. Contrasting it to rowstore we can have one clustered index and multiple non-clustered indexes (in sql server this limitation).\nStorage Efficiency: For a table with 60K records\nClustered Columnstore: table size: 1.9MB, index space: 0MB Clustered Rowstore: table size: 9.6MB, index space: 0.055MB Heap table (no index): table size: 9.6MB, index space: 0.008MB 5.5 Unique Index # Ensures no duplicate values exist in a specific column.\nCREATE UNIQUE INDEX index_name ON table_name (column_name);-- creates a unique index. --default is non-unique index CREATE INDEX index_name ON table_name (column_name);-- this allows duplicates. --syntax CREATE [UNIQUE] [CLUSTERED | NONCLUSTERED] [COLUMNSTORE] INDEX index_name on table_name (column1,colum2,..); It is important to understand that there exists no significant difference between a primary key or unique key constraint and a unique index. To implement the concept of primary and unique key constraints, the database manager uses a combination of a unique index and the NOT NULL constraint. Therefore, unique indexes do not enforce primary key constraints by themselves because they allow null values.\n5.6 Filtered Index # An index that includes only rows meeting the specific condition. Such as, We have a material table and the web application only requests the active material data. In this case, create an index for the only active material rows is very reasonable than creating an index for whole rows of the table.\nSQL server allows filtered index only on non-clustered index.\nyou cannot create a filtered index on clustered index. you cannot create a filtered index on a columnstore index. CREATE [UNIQUE] [NONCLUSTERED] INDEX index_name on table_name (column1,colum2,..) WHERE [condition]; 5.7 Data Structures Used in Index # 5.7.1 B-Tree (Balance Tree) # B-trees have a hierarchical structure consisting of a root node, internal nodes (also known as index nodes), and leaf nodes. Each node in a B-Tree contains a sorted array of keys and pointers to child nodes.\nB-Trees are:\nSelf balancing Ordered Disk Friendly In a B+ tree, all data values are stored only in the leaf nodes, which can further improve performance for certain use cases like range queries.\n5.8 Types of Indexes: Comparison # Cluster Index Non-Cluster Index Rowstore Index Columnstore Index Unique Index Filtered Index Def: Physically sort and store rows Def: Separate structure with pointer to the data Def: Organize and store data row by row Def: Organize and store data column by column Def: no duplicate values exist in a specific column One Index per table Multiple indexes per table One Index per table Multiple indexes per table Only one index type i.e. cluster columnstore or nonclustered columnstore If data in each column is unique, both unique clustered index and multiple unique nonclustered indexes can be created Read performance: fast Read performance: slow Read performance: balanced Read performance: fast Read performance: fast than reading from a non-unique index Write performance: slow (due to potential data reordering) Write performance: fast (physical data order is unaffected) Write performance: balanced Write performance: slow Write performance: slow than writing to a non-unique index Storage efficiency: efficient Storage efficiency: requires additional space Storage efficiency: less efficient in storage Storage efficient: highly efficient with compression Use case: Unique columns No frequent column updates (generally primary key are better candidates for this since they are unique and not modified after creation) Improve range query performance | Use case: Columns frequently used in search conditions and joins Exact match queries | Use case: OLTP (online transaction processing): commerce, banking, financial systems, order processing. high frequency transaction applications quick access to complete record | Use case: OLAP (online analytical processing): dataware house, business intelligence, reporting, analytics. big data analytics scanning of large documents fast aggregation | | Uses case: Target optimization less storage in index | | | | I/O : higher. retrieves all columns | I/O : lower. retrieves specificl columns | | | | When to use: for primary keys, if not then for date columns | When to use: For non-primary columns. Foreign keys, joins, filters. | | When to use: For analytical purpose. reduce size of large table | When to use: Enforce uniqueness. Improve query speed. | When to use: Target subset of data. reduce size of index | 5.9 Index Management # The commands are in reference to SQL Server\nMonitor Index Usage: ‘sys’ - system tables that store table, view, index, etc metadata. ‘sys.indexes’ tables contain metadata for indexes. The object_id on the ‘sys.indexes’ tables can be joined with ‘sys.tables’ object_id to get the names of the table.\nDynamic management views (DMVs) and dynamic management functions (DMFs) return server state information that can be used to monitor the health of a server instance, diagnose problems, and tune performance. Table name: ‘sys.dm_db_index_usage_stats’. The query displays the read, update etc usage by the query optimizer this way we can understand when an index was last used and for what operation. SELECT tbl.name AS TableName, ide.name AS IndexName, ide.type_desc AS IndexType, ide.is_primary_key AS IsPrimayKey, idx.is_unique AS IsUnique, idx.is_disabled AS IsDisabled, s.user_seeks AS UserSeeks, s.user_scans AS UserScans, s.user_lookups AS UserLookups, s.user_updates AS UserUpdates, COALESCE(s.last_user_seek,\ts.last_user_scan) LastUpdate FROM sys.indexes idx JOIN sys.tables tbl ON idx.object_id = tbl.object_id LEFT JOIN sys.dm_db_index_usage_stats s ON s.object_id = idx.object_id AND s.index_id = idx.index_id ORDER BY tbl.name, idx.name Monitor Missing Indexes: Table: ‘sys.dm_db_missing_index_details’. After running a query check this table to see the recommendations by the SQL server.\nMonitor Duplicate Indexes: The query displays the index by each table and shows the count of index that have same column.\nSELECT tbl.name AS TableName, col.name AS IndexColumn, idx.name AS indexName, idx.type_desc AS IndexType, COUNT(*) OVER (PARTITION BY tbl.name, col.name) COlumnCOunt FROM sys.indexes idx JOIN sys.tables tbl ON idx.object_id = tbl.object_id JOIN sys.index_columns ic ON idx.object_id = ic.object_id AND idx.index_id = ic.index_id JOIN sys.columns col ON ic.object_id = col.object_id AND ic.column_id = col.colum_id ORDER BY ColumnCount DESC Updating statistics: SQL Server statistics are one of the key inputs for the query optimizer during generating a query plan. Statistics are used by the optimizer to estimate how many rows will return from a query so it calculates the cost of a query plan using this estimation.\nBehind the scenes the database engine creates the statistics which is basically a metadata about the table such as number of rows, distribution of data, patterns etc. When executing a query the database engine creates an ‘execution plan’. The statistics are used in the execution plan. When to do: weekly automated jobs. After major database migration. --to view the statistics SELECT SCHEME_NAME (t.schem_id) AS SchemaName, t.name AS TableName, s.name AS StatisticName, sp.last_updated As LastUpdated, DATEDIFF(day, sp.last_updated, GETDATE()) AS LastUpdateDay, sp.rows AS \u0026#39;ROWS\u0026#39;, sp.modification_counter AS ModificationsSinceLastUpdate FROM sys.stats AS s JOIN sys.tables t ON s.object_id = t.object_id CRROSS APPLY sys.dm_db_stats_properties(s.object_id,s.stats_id) AS sp ORDER BY sp.modification_counter DESC; -- update statistics by statistic name UPDATE STATISTICS table_name statistics_name -- update statistics on whole table UPDATE STATISTICS table_name -- update statistics on whole database EXECUTE database_name Monitor Fragmentation: In SQL Server, fragmentation occurs when data in your database is not stored contiguously, resulting in disorganized pages and inefficient query executions.\nInternal Fragmentation: happens when data pages in SQL Server have unnecessary data storage space or capacity. External Fragmentation: occurs when the logical order of index pages varies from their physical organization in the data file. When you insert or update a record or data row in an already full table or index, SQL Server performs a page split and creates a new data page for storing the additional data. It moves some part of the information from the existing page to the new page. Fragmentation Methods: Reorganize: Defragment leaf nodes to keep them sorted ‘Light’ Operation Rebuild: Recreate Index from scratch ‘Heavy’ Operation When to defragment: \u0026lt; 10%: no action 10% to 30%: Reorganize 30%: Rebuild\n-- to check the degree of fragmentation SELECT * FROM sys.dm_db_index_physical_stats (DB_ID(),NULL,NULL,NULL,\u0026#39;LIMITED\u0026#39;); SELECT tbl.name AS TableName, idx.name AS IndexName, s.avg_fragmentation_in_percent, s.page_count FROM sys.dm_db_index_physical_stats(DB_ID(),NULL,NULL,NULL,\u0026#39;LIMITED\u0026#39;) AS a INNER JOIN sys.tables tbl ON s.object_id = tbl.object_id INNER JOINN sys.indexes AS ids ON idx.object_id = s.object_id AND idx.index_id = s.index_id ORDER BY s.avg_gragmentation_in_percent DESC; -- fragmentation Reorganize ALTER INDEX index_name ON table_name REORGANIZE -- fragment rebuild ALTER INDEX index_name ON table_name REBUILD 6. Combining Tables in SQL # 6.1 Why use SQL JOIN # Recombine data (Big Picture) Data Entrenchment (Extra Info) Check Existence (Filtering) 6.2 INNER JOIN # Returns only matching tables from both tables SELECT * FROM table_a INNER JOIN table_b ON A.key = B.key;-- default is inner join -- order does not matter. below query will give same result SELECT * FROM table_b INNER JOIN table_a ON A.key = B.key; 6.3 LEFT JOIN # Returns all rows from the left table and only matching from the right The left table is the primary source of data. The right table is additional, and only adds extra information. -- order matters -- table_a is left -- table_b is right SELECT * FROM table_a LEFT JOIN table_b ON A.key = B.key; 6.4 RIGHT JOIN # Return all rows from the right table and only matching from the left. -- order matters -- table_a is left -- table_b is right SELECT * FROM table_a RIGHT JOIN table_b ON A.key = B.key; -- same can be achieved with LEFT JOIN -- order matters -- table_a is right -- table_b is left SELECT * FROM table_b LEFT JOIN table_a ON A.key = B.key; 6.5 FULL JOIN # Return all rows from both tables. --order of tables does not matter SELECT * FROM table_a FULL JOIN table_b ON A.key = B.key; 6.6 LEFT ANTI JOIN # Return rows from left table that has no matches on the right The left table is primary source and the right table acts as filter. -- the order of the table is important SELECT * FROM table_a LEFT JOIN table_b ON A.key = B.key WHERE B.key IS NULL; 6.7 RIGHT ANTI JOIN # Return rows from the right table that has no matches on the left. -- the order of the table is important SELECT * FROM table_a RIGHT JOIN table_b ON A.key = B.key WHERE A.key IS NULL; -- can be done similarly with left join -- the order of the table is important SELECT * FROM table_b LEFT JOIN table_a ON A.key = B.key WHERE A.key IS NULL; 6.8 FULL ANTI JOIN # Return only the rows that dont match in either tables. -- the order of the tables does not matter SELECT * FROM table_a FULL JOIN table_b ON A.key = B.key WHERE A.key IS NULL OR B.key IS NULL; 6.9 CROSS JOIN # Combine every row from the left with every row from the right. All possible combinations: Cartesian join. Example: if we have two tables called products and colors then we can see the combination of both tables. When combining table with columns we use JOIN and when combining with rows we use SET operators. -- order does not matter SELECT * FROM A CROSS JOIN B 7. MongoDB # MongoDB is a cross platform, document oriented database that provides, high performance, high-availability, and easy scalability. MongoDB works on the concept of collection and document.\nDatabase: Database is a physical container for collection. Each database gets its own set of files on the file system. A Single MongoDB server typically has multiple databases.\nCollection: Collection is a group of MongoDB documents. It is the equivalent of an RDBMS table. Collections do not enforce a schema. Documents within a collection can have different fields. A record in MongoDB is a document, documents are similar to JSON objects.\nDocument: A document is a set of key-value pair. Documents have dynamic schema. Dynamic schema means that documents in the same collections do not need to have the same set of fields or structure, and common fields in a collections documents may hold different types of data.\n_id is a 12 bytes hexadecimal number which assures the\n7.1 Create Database # In MongoDB, databases hold one or more collections of documents.\nRun commands in mongosh\nIf a database does not exist, MongoDB creates the database when you first store data for that database.\nuse employeeDb db.employeeDepartment.insertOne( { x : 1} ) The above commands once executed will create a database \u0026rsquo;employeeDb\u0026rsquo; and a collection \u0026rsquo;employeeDepartment'.\n7.2 Drop a Database # use employeeDb db.dropDatabase() 7.3 Create a Collections # MongoDB stores documents in collections. Collections are analogous to tables in relational databases.\nIf a collection does not exist, MongoDB creates the collection when you first store data for that collection.\ndb.myNewCollection2.insertOne( { x: 1 } ) db.myNewCollection3.createIndex( { y: 1 } ) 7.4 Explicit Creation # db.createCollection(name,options) Can be used to explicitly create a collection\n7.5 Show Collections # show collections (or) db.getCollectionInfos() 7.6 Drop a Collection # After selecting the database, assuming \u0026lsquo;myCollection\u0026rsquo; is the collection to delete\ndb.myCollection.drop() ","date":"18 November 2025","externalUrl":null,"permalink":"/posts/databases/about/","section":"Welcome to my Blog!","summary":"","title":"Introduction to Databases","type":"posts"},{"content":" About # In this article we explore concepts related to container technology. We start from the basic by understanding what are containers and virtual machines. Then we explore the open container initiative (image-spec and runtime-spec) and later explore Docker and Podman specific concepts.\nIntroduction # What are Virtual Machines? # Applications are generally deployed in a virtual machine. A Virtual Machine (VM) is a compute resource that uses software instead of a physical computer to run programs and deploy apps. Each virtual machine runs its own operating system and functions separately from the other VMs, even when they are all running on the same host. What are Containers? # Containers are a technology that allows applications to be packaged and isolated with their entire runtime environment.\nWhy use Containers? # The computational overhead spent virtualizing hardware for a guest OS to use is substantial. They make it easier to maintain consistent behavior and functionality while moving the contained application between environments. Containers share the machine’s OS system kernel and therefore do not require an OS per application, driving higher server efficiencies. What is the Open Container Initiative (OCI)? # The Open Container Initiative (OCI) is a lightweight, open governance structure (project) for the express purpose of creating open industry standards around container formats and runtimes.\nThe OCI currently contains three specifications:\nThe Runtime Specification (runtime-spec). The Image Specification (image-spec). The Distribution Specification (distribution-spec). Runtime Specification # The Open Container Initiative Runtime Specification aims to specify the configuration, execution environment, and lifecycle of a container. The Runtime Specification outlines how to run a \u0026ldquo;filesystem bundle\u0026rdquo; that is unpacked on disk.\nA container\u0026rsquo;s configuration is specified in the config.json for the supported platforms and details the fields that enable the creation of a container. The execution environment is specified to ensure that applications running inside a container have a consistent environment between runtimes, along with common actions defined for the container\u0026rsquo;s lifecycle.\nApplication bundle builders can create a bundle directory that includes all the files required to launch an application as a container. The bundle contains an OCI configuration file (config.json) where the builder can specify host-independent details such as which executable to launch (process object defined in the config.json file) and host-specific settings such as mount locations, hook paths, Linux namespaces and cgroups.\nWhat is a file system bundle? # A set of files organized in a certain way and containing all the necessary data and metadata for any compliant runtime to perform all standard operations against it.\nA container is encoding as a filesystem bundle on disk. The definition of a bundle is concerned only with how a container and its configuration data are stored on a local filesystem so that they can be consumed by a compliant runtime.\nA Standard Container bundle contains all the information needed to load and run a container. This includes the following artifacts:\nconfig.json containing all configuration data. (File is mandatory) The container\u0026rsquo;s root filesystem, referred to by root.path in the config.json file. (Optional but mandatory in Windows) Scope of a Container # The entity using a runtime to create a container MUST be able to use the operations defined in this specification against that same container. Whether other entities using the same, or other, instance of the runtime can see that container is out of scope of this specification.\nState of a Container # The state of a container includes the following properties:\nociVersion id status (Additional values MAY be defined by the runtime, however, they MUST be used to represent new runtime states not defined below.) creating: The container is being created. created: The runtime has finished the create operation, and the container process has neither exited nor executed the user-specified program. running: The container process has executed the user-specified program but has not exited stopped: The container process has exited pid bundle annotations //Example of state { \u0026#34;ociVersion\u0026#34;: \u0026#34;0.2.0\u0026#34;, \u0026#34;id\u0026#34;: \u0026#34;oci-container1\u0026#34;, \u0026#34;status\u0026#34;: \u0026#34;running\u0026#34;, \u0026#34;pid\u0026#34;: 4422, \u0026#34;bundle\u0026#34;: \u0026#34;/containers/redis\u0026#34;, \u0026#34;annotations\u0026#34;: { \u0026#34;myKey\u0026#34;: \u0026#34;myValue\u0026#34; } } Runtime Lifecycle # The lifecycle describes the timeline of events that happen from when a container is created to when it ceases to exist.\nOCI create operation command is invoked. The container\u0026rsquo;s runtime environment MUST be created according to the configuration in config.json. While the resources requested in the config.json MUST be created, the user-specified program MUST NOT be run at this time. Any updates to config.json after this step MUST NOT affect the container. prestart hook createRuntime hook createContainer hook Runtime\u0026rsquo;s start command is invoked with the unique identifier of the container. startContainer hook The runtime MUST run the user-specified program, as specified by process . (process object is defined in the config.json) postStart hook The container process exits. This MAY happen due to erroring out, exiting, crashing or the runtime\u0026rsquo;s kill operation being invoked. Runtime\u0026rsquo;s delete command is invoked with the unique identifier of the container. The container MUST be destroyed by undoing the steps performed during create phase (step 2). postStop hook Operations # Unless otherwise stated, runtimes MUST support the following operations. (These operations are not specifying any command-line APIs, and the parameters are inputs for general operations.)\nContainer tools provide CLI tools which may have a different name but the underlying operation should support these, that are consistent with OCI runtime-spec.\nquery state: This operation MUST return the state of a container as specified in state create: This operation MUST create a new container. Any changes made to the config.json file after this operation will not have an effect on the container. start: This operation MUST run the user-specified program as specified by process . kill: This operation MUST send the specified signal to the container process. delete: Attempting to delete a container that is not stopped MUST have no effect on the container and MUST generate an error. Deleting a container MUST delete the resources that were created during the create step. Note that resources associated with the container, but not created by this container, MUST NOT be deleted. Volumes or mounts etc, are not deleted. Configuration # This configuration file contains metadata necessary to implement standard operations against the container. This includes the process to run, environment variables to inject, sandboxing features to use, etc.\nRefer https://github.com/opencontainers/runtime-spec/blob/main/config.md#platform-specific-configuration to the full configuration details. Image Specification # This specification defines an OCI Image, consisting of an image manifest, an image index (optional), a set of filesystem layers, and a configuration.\nImage Manifest # At a high level, the image manifest contains metadata about the contents and dependencies of the image, including the content-addressable identity of one or more filesystem layer changeset archives that will be unpacked to make up the final runnable filesystem.\nImage Configuration # The image configuration includes information such as application arguments, environments, etc.\nImage Index # The image index is a higher-level manifest that points to a list of manifests and descriptors. Typically, these manifests may provide different implementations of the image, possibly varying by platform or other attributes.\nContent Descriptors # An OCI image consists of several different components arranged in a Merkle Directed Acyclic Graph (DAG). References between components in the graph are expressed through Content Descriptors. A Content Descriptor, or simply Descriptor, describes the disposition (the way in which something is placed or arranged, especially in relation to other things) of the targeted content. The content identifier is the digest. The media type defining the descriptor is: application/vnd.oci.descriptor.v1+json A canonical form is a representation such that every object has a unique representation. Thus, the equality of two objects can easily be tested by testing the equality of their canonical forms. Canonicalization being the process through which a representation is put into its canonical form. For example, the content {’a’:1, ‘b’:2} and {’b’:2,’a’:1} although being same can show different digests. Therefore, canonicalization is used when saving content in OCI.\necho -n {\u0026lsquo;a\u0026rsquo;:1,\u0026lsquo;b\u0026rsquo;:2} | sha256sum d8766531781e268ee6fe73b2333041ca231ac61f059874afe0d10c395421b388\necho -n {\u0026lsquo;b\u0026rsquo;:2,\u0026lsquo;a\u0026rsquo;:1} | sha256sum d644ddd8c7d5668b270da1e1d8a51a3c8b0a4c7458513a85cbf056b4414f4b65\nImage Layout Specification # The OCI Image Layout is the directory structure for OCI content-addressable blobs and location-addressable references (refs). Given an image layout and a ref, a tool can create an OCI Runtime Specification bundle by:\nFollowing the ref to find a manifest, possibly via an image index Applying the filesystem layers in the specified order Converting the image configuration into an OCI Runtime Specification config.json Structure # The image layout is as follows:\nblobs directory: Contains content-addressable blobs A blob has no schema and SHOULD be considered opaque Directory MUST exist and MAY be empty oci-layout file: It MUST exist and be a JSON object. It MUST contain an imageLayoutVersion field index.json file It MUST exist and be an image index JSON object. Blobs # Object names in the blobs subdirectories are composed of a directory for each hash algorithm, the children of which will contain the actual content. The content of blobs/\u0026lt;alg\u0026gt;/\u0026lt;encoded\u0026gt; MUST match the digest \u0026lt;alg\u0026gt;:\u0026lt;encoded\u0026gt; (referenced per descriptor). For example, the content of blobs/sha256/da39a3ee5e6b4b0d3255bfef95601890afd80709 MUST match the digest sha256:da39a3ee5e6b4b0d3255bfef95601890afd80709. oci-layout file # This JSON object serves as a marker for the base of an Open Container Image Layout and to provide the version of the image-layout in use. The media type defining the image layout specification is: application/vnd.oci.layout.header.v1+json index.json file # It is the entry point for references and descriptors of the image layout. The image index is a multi-descriptor entry point. This index provides an established path (/index.json) to have an entry point for an image-layout and to discover auxiliary descriptors. In general the mediaType of each descriptor object in the manifests field will be either application/vnd.oci.image.index.v1+json or application/vnd.oci.image.manifest.v1+json. An encountered mediaType that is unknown MUST NOT generate an error. Image Index Specification # The image index is a higher-level manifest that points to specific image manifests, ideal for one or more platforms. While the use of an image index is OPTIONAL for image providers, image consumers SHOULD be prepared to process them. This section defines the application/vnd.oci.image.index.v1+json media type. Image Manifest Specification # There are three main goals of the Image Manifest Specification. The media type defined by this section is application/vnd.oci.image.manifest.v1+json\ncontent-addressable images: by supporting an image model where the image\u0026rsquo;s configuration can be hashed to generate a unique ID for the image and its components. To allow multi-architecture images, through a \u0026ldquo;fat manifest\u0026rdquo; which references image manifests for platform-specific versions of an image. In OCI, this is codified in an image index. To be translatable to the OCI Runtime Specification. An image manifest provides a configuration and set of layers for a single container image for a specific architecture and operating system.\nImage Configuration # An OCI Image is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime. This specification outlines the JSON format describing images for use with a container runtime and execution tool and its relationship to filesystem changesets. The media type application/vnd.oci.image.config.v1+json defines the image configuration. Terminology # Layer # Image filesystems are composed of layers. Each layer represents a set of filesystem changes in a tar-based layer format, recording files to be added, changed, or deleted relative to its parent layer. Layers do not have configuration metadata such as environment variables or default arguments, these are properties of the image as a whole rather than any particular layer. Using a layer-based or union filesystem such as AUFS, or by computing the diff from filesystem snapshots, the filesystem changeset can be used to present a series of image layers as if they were one cohesive filesystem. One or more layers are applied on top of each other to create a complete filesystem. The media type application/vnd.oci.image.layer.v1.tar+gzip represents an application/vnd.oci.image.layer.v1.tar payload which has been compressed with gzip. The media type application/vnd.oci.image.layer.v1.tar+zstd represents an application/vnd.oci.image.layer.v1.tar payload which has been compressed with zstd. Layer Changesets for the media type application/vnd.oci.image.layer.v1.tar MUST be packaged in tar archive. Change Types # Types of changes that can occur in a changeset are:\nAdditions Modifications Removals JSON # Each image has an associated JSON structure that describes some basic information about the image, such as date created, author, as well as execution/runtime configuration like its entrypoint, default arguments, networking, and volumes.. The JSON structure also references a cryptographic hash of each layer used by the image, and provides history information for those layers. This JSON is considered to be immutable because changing it would change the computed ImageID. Changing it means creating a new derived image, instead of changing the existing image. Layer DiffID # A layer DiffID is the digest over the layer\u0026rsquo;s uncompressed tar archive and serialized in the descriptor digest format. Chain ID # It is sometimes useful to refer to a stack of layers with a single identifier. While a layer\u0026rsquo;s DiffID identifies a single changeset, the ChainID identifies the subsequent application of those changesets. Image ID # Each image\u0026rsquo;s ID is given by the SHA256 hash of its configuration JSON. Properties # created A combined date and time at which the image was created author Gives the name and/or email address of the person or entity that created and is responsible for maintaining the image. architecture The CPU architecture on which the binaries in this image are built to run. os The name of the operating system on which the image is built to run. os.version This property specifies the version of the operating system targeted by the referenced blob. os.features This property specifies an array of strings, each specifying a mandatory OS feature. variant The variant of the specified CPU architecture. config The execution parameters that SHOULD be used as a base when running a container using the image. User The username or UID which is a platform-specific structure that allows specific control over which user the process runs as. ExposedPorts A set of ports to expose from a container running this image. Its keys can be in the format of:port/tcp, port/udp, port With the default protocol being tcp if not specified. Env Entries are in the format of VARNAME=VARVALUE. These values act as defaults and are merged with any specified when creating a container. Entrypoint A list of arguments to use as the command to execute when the container starts. These values act as defaults and may be replaced by an entrypoint specified when creating a container. Cmd Default arguments to the entrypoint of the container. If an Entrypoint value is not specified, then the first entry of the Cmd array SHOULD be interpreted as the executable to run. Volumes A set of directories describing where the process is likely to write data specific to a container instance. WorkingDir Sets the current working directory of the entrypoint process in the container. This value acts as a default and may be replaced by a working directory specified when creating a container. Labels This field contains arbitrary metadata for the container. StopSignal This field contains the system call signal that will be sent to the container to exit. rootfs The rootfs key references the layer content addresses used by the image. This makes the image config hash depend on the filesystem hash. type MUST be set to layers. diff_ids An array of layer content hashes (DiffIDs), in order from first to last. history Describes the history of each layer. The array is ordered from first to last. created A combined date and time at which the layer was created. author The author of the build point. created_by The command that created the layer. comment A custom message set when creating the layer. empty_layer This field is used to mark if the history item created a filesystem diff. It is set to true if this history item doesn\u0026rsquo;t correspond to an actual layer in the rootfs section Conversion to OCI Runtime Configuration # When extracting an OCI Image into an OCI Runtime bundle, two orthogonal components of the extraction are relevant:\nExtraction of the root filesystem from the set of filesystem layers. Conversion of the image configuration blob to an OCI Runtime configuration blob. All the necessary system libraries and dependencies of the application are referenced as layers. image manifest, specifies the CPU architecture for which the previous two elements are suitable. image index, which contains information about a set of images that can span a variety of architectures and operating systems\nA file system is a structure used by an operating system to organise and manage files on a storage device such as a hard drive, solid state drive (SSD), or USB flash drive. It defines how data is stored, accessed, and organised on the storage device. Common File Systems:\nFAT (File Allocation Table), FAT16, FAT32 exFAT (Extended File Allocation Table) NTFS (New Technology File System) APFS (Apple File System) HFS, HFS+ (Hierarchical File System) Ext4 (Fourth Extended File System) BLOB stands for a “Binary Large Object,” a data type that stores binary data. Binary Large Objects (BLOBs) can be complex files like images or videos, unlike other data strings that only store letters and numbers. A BLOB will hold multimedia objects to add to a database.\nAn archive file stores the content of one or more computer files, possibly compressed and/or encrypted, with associated metadata such as file name, directory structure, error detection and correction information, and commentary. In computing, tar is a shell command for combining multiple computer files into a single archive file. A tarball contains metadata for the contained files including the name, ownership, timestamps, permissions and directory organization.\nA changeset describes the exact differences between two successive versions in the version control system\u0026rsquo;s repository of changes.\nReferences # https://spacelift.io/blog/docker-entrypoint-vs-cmd https://docs.docker.com/reference/dockerfile/ https://docs.docker.com/reference/api/engine/version/v1.51/ https://spacelift.io/blog/docker-commands-cheat-sheet https://spacelift.io/blog/docker-entrypoint-vs-cmd https://docs.docker.com/reference/dockerfile/ https://docs.docker.com/reference/api/engine/version/v1.51/ https://docs.docker.com/reference/cli/dockerd#description https://docs.docker.com/build/concepts/context/#what-is-a-build-context https://spacelift.io/blog/docker-commands-cheat-sheet https://docs.docker.com/engine/storage/ https://docs.docker.com/engine/storage/volumes/ https://pythonspeed.com/articles/multi-stage-docker-python/ https://www.vmware.com/topics/virtual-machine https://www.redhat.com/en/topics/containers https://www.docker.com/resources/what-container/ https://opencontainers.org/about/overview/ https://github.com/opencontainers/runtime-spec https://github.com/opencontainers/runtime-spec/blob/main/schema/config-schema.json ","date":"17 November 2025","externalUrl":null,"permalink":"/posts/virtualization/what-are-containers/","section":"Welcome to my Blog!","summary":"","title":"What are Containers","type":"posts"},{"content":"","externalUrl":null,"permalink":"/authors/","section":"Authors","summary":"","title":"Authors","type":"authors"},{"content":"","externalUrl":null,"permalink":"/categories/","section":"Categories","summary":"","title":"Categories","type":"categories"},{"content":"","externalUrl":null,"permalink":"/series/","section":"Series","summary":"","title":"Series","type":"series"},{"content":"","externalUrl":null,"permalink":"/tags/","section":"Tags","summary":"","title":"Tags","type":"tags"}]