sudo in Ubuntu

What is sudo ?

  • The sudo command gives some admin privileges to non-admin users
  • SUDO is similar to UAC in Windows

Why sudo ?

  • Certain Linux applications require elevated privileges to run. 
  • So either the user can switch user using su command or perform sudo and run the command
  • Linux uses the sudo command as a wall between normal tasks and administrative ones

Configuration of sudo is saved inside :

  • /etc/sudoers file
  • This file can be edited using visudo editor only

VISUDO

Configuration file :

vi /etc/sudoers
cd /etc/sudoers.d/

Configuration stuff Read more :

https://www.youtube.com/watch?v=FGRtNvKdtbk

NPX – npm package runner

  • npx is a tool intended to help round out the experience of using packages from the npm registry.
  • It greatly simplifies a number of things that, until now, required a bit of ceremony to do with plain npm
  • Since npm version 5.2.0 npx is pre-bundled with npm. So it’s pretty much a standard nowadays.

Advantages :

  • Run commands with different Node.js versions
  • Run a locally installed package easily (npx will check whether <command> or <package> exists in $PATH, or in the local project binaries, and if so it will execute it.)
  • Execute packages that are not previously installed locally.
  • Run code directly from GitHub
  • npx helps us avoid versioning, dependency issues and installing unnecessary packages that we just want to try out.
  • It also provides a clear and easy way of executing packages, commands, modules and even GitHub gists and repositories.

Reference :

Advantages : 
https://www.freecodecamp.org/news/npm-vs-npx-whats-the-difference/

JMH – Modes of Benchmarking

  • Throughput
    • Continuously call benchmark method until expiry time, count total over all worker threads Throughput
    • Measures the number of operations per second, meaning the number of times per second your benchmark method could be executed.
    • Note : Throughput and Average time output are exact opposite of each other i.e Throughput shows how many times a method can be called and Average time shows how much time we would need in an average to execute the method.
    • Output will look like below
  • AverageTime
    • Continuously call benchmark method until expiry time, count average over all worker threads
    • Measures the average time it takes for the benchmark method to execute (a single execution).
    • Note : Throughput and Average time output are exact opposite of each other i.e Throughput shows how many times a method can be called and Average time shows how much time we would need in an average to execute the method.
    • Output will look like below
  • SampleTime
    • Continuously call benchmark method until expiry time, automatically adjusts the sampling frequency, but may omit some pauses which missed the sampling measurement.
    • Measures how long time it takes for the benchmark method to execute, including max, min time etc.
    • Output will look like below
This image has an empty alt attribute; its file name is image-2.png
  • SingleShotTime
    • Calls only one time until iterations and timeout
    • Measures how long time a single benchmark method execution takes to run. This is good to test how it performs under a cold start (no JVM warm up).
    • Output will look like below
  • All Modes
    • Calls all the modes together
    • Lesser the Score, faster is the method execution but do consider error as well
    • Output will look like below

Below Code was used to get above outputs, not we need to do a maven clean and install after everychanges are made to the code :

package com.demo;
 
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Timeout;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@BenchmarkMode(Mode.All) //Mode
@OutputTimeUnit(TimeUnit.MILLISECONDS) //Outputs should be displayed in which TimeUnit
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx2G"}) //Number of JVM instances, under which warmup and iterations should be executed
@Warmup(iterations = 3, time = 100, timeUnit = TimeUnit.MILLISECONDS) //Warmup parameters
@Measurement(iterations = 3, time = 100, timeUnit = TimeUnit.MILLISECONDS) //Iterations parameters
@Timeout(time = 10, timeUnit = TimeUnit.MINUTES) //Time in which all the executions should be completed
public class BenchmarkList {
    public static void main(String[] args) throws RunnerException {

        Options opt = new OptionsBuilder()
                .include(BenchmarkList.class.getSimpleName())
                .build();

        new Runner(opt).run();
    }
    
    @State(Scope.Thread)
    public static class MyState {
        public int output = 10000;
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
    }
    
    @Benchmark
    public void arrayListAdd(MyState state) throws InterruptedException {
    	for(int i=0; i<state.output; i++) {
    		state.arrayList.add("Hello"+i);
    	}
    }
    
    @Benchmark
    public void linkListAdd(MyState state) throws InterruptedException {
    	for(int i=0; i<state.output; i++) {
    		state.linkedList.add("Hello"+i);
    	}
    }
}

Compare the ArrayList with LinkedList on iterating new objects

Code :

package com.demo;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@BenchmarkMode(Mode.AverageTime)
//@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
//@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx2G"}) //clean JVM
//@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
//@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
public class BenchmarkList {
    public static void main(String[] args) throws RunnerException {

        Options opt = new OptionsBuilder()
                .include(BenchmarkList.class.getSimpleName())
                .warmupIterations(2)
                .measurementIterations(3)
                .build();

        new Runner(opt).run();
    }
    
    @State(Scope.Thread)
    public static class MyState {
        public int output = 1000;
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
        @Setup
        public void prepare(){
        	for(int i=0; i<output; i++) {
        		arrayList.add("Hello"+i);
        	}
        	for(int i=0; i<output; i++) {
        		linkedList.add("Hello"+i);
        	}
        }
    }
    
    @Benchmark
    public void arrayList(MyState state,Blackhole bh) throws InterruptedException {
    	for(int i=0; i<state.output; i++) {
    		bh.consume(state.arrayList.get(i));
    	}
    }
    
    @Benchmark
    public void linkList(MyState state,Blackhole bh) throws InterruptedException {
    	for(int i=0; i<state.output; i++) {
    		bh.consume(state.linkedList.get(i));
    	}
    }
}

Output :

Note : For Iterating elements the time complexity of LinkedList and ArrayList is O(n) i.e but there is a significant difference between iterating a arraylist and a linkedlist

ArrayList is what you want. LinkedList is almost always a (performance) bug.

Why LinkedList sucks:

  • It uses lots of small memory objects, and therefore impacts performance across the process.
  • Lots of small objects are bad for cache-locality.
  • Any indexed operation requires a traversal, i.e. has O(n) performance. This is not obvious in the source code, leading to algorithms O(n) slower than if ArrayList was used.
  • Getting good performance is tricky.
  • Even when big-O performance is the same as ArrayList, it is probably going to be significantly slower anyway.
  • It’s jarring to see LinkedList in source because it is probably the wrong choice.

Compare the ArrayList with LinkedList on adding new objects

package com.demo;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@BenchmarkMode(Mode.AverageTime)
//@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx2G"}) //clean JVM
//@Warmup(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
//@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
public class BenchmarkList {
    public static void main(String[] args) throws RunnerException {

        Options opt = new OptionsBuilder()
                .include(BenchmarkList.class.getSimpleName())
                .warmupIterations(1)
                .measurementIterations(1)
                .build();

        new Runner(opt).run();
    }
    
    @State(Scope.Thread)
    public static class MyState {
        public int output = 100;
        List<String> arrayList = new ArrayList<>();
        List<String> linkedList = new LinkedList<>();
    }
    
    @Benchmark
    public void arrayList(MyState state) throws InterruptedException {
    	for(int i=0; i<state.output; i++) {
    		state.arrayList.add("Hello"+i);
    	}
    }
    
    @Benchmark
    public void linkList(MyState state) throws InterruptedException {
    	for(int i=0; i<state.output; i++) {
    		state.linkedList.add("Hello"+i);
    	}
    }
}

Output :

Stack in Java

  • The stack is a linear data structure that is used to store the collection of objects.
  • It is based on Last-In-First-Out (LIFO)
  • Stack class provides different operations such as push, pop, search, etc.
  • Stack extends Vector i.e Stack is Threadsafe and underlying data structure is ArrayList(Array)

Example :

package java8;

import java.util.Stack;

public class StackDemo {
	public static void main(String[] args) {
		Stack<String> animals= new Stack<>();
		animals.push("Dog");
        animals.push("Horse");
        animals.push("Cat");

        System.out.println("Stack: " + animals);
        // Remove element stacks
        String element1 = animals.pop();
        System.out.println("Removed Element: " + element1);
        
     // Access element from the top
        String element2 = animals.peek();
        System.out.println("Element at top: " + element2);
        
     // Search an element
        int position = animals.search("Horse");
        System.out.println("Position of Horse: " + position);
        
        // Check if stack is empty
        boolean result = animals.empty();
        System.out.println("Is the stack empty? " + result);
	}
}

Use ArrayDeque Instead of Stack

The Stack class provides the direct implementation of the stack data structure. However, it is recommended not to use it. Instead, use the ArrayDeque class (implements the Deque interface) to implement the stack data structure in Java.

Vectors in Java Collections

  • Vector is like the dynamic array which can grow or shrink its size. 
  • Vector is similar to ArrayList but threadsafe
  • It is recommended to use the Vector class in the thread-safe implementation only else use ArrayList
  • Iterator returned by Vector is fail-fast. Means any structural modification made to Vector like adding or removing elements during Iteration will throw java.util.ConcurrentModificationException.

It is similar to the ArrayList, but with two differences-

  • Vector is synchronized.
  • Java Vector contains many legacy methods that are not the part of a collections framework.

Example :

package java8;

import java.util.Vector;

public class VectorDemo {
	public static void main(String[] args) {
		 Vector<String> vec = new Vector<String>();  
         //Adding elements using add() method of List  
         vec.add("Tiger");  
         vec.add("Lion");  
         vec.add("Dog");  
         vec.add("Elephant");  
         //Adding elements using addElement() method of Vector  
         vec.addElement("Rat");  
         vec.addElement("Cat");  
         vec.addElement("Deer");  
           
         System.out.println("Elements are: "+vec);  
	}
}

Since it is similar to arraylist, the complexity of Vector is same

Complexity of Vector

VectorTime ComplexitySpace Complexity
Adding ElementO(1) – resize O(log(n))
Removing ElementO(n)
Iterating ElementsO(n)
Retreving Element at PositionO(1)

Reference :

https://www.interviewsansar.com/java-vector-time-complexity-and-how-vector-grows-in-java/

JMH Project in Maven

Execute below command to create a maven jmh archetype

mvn archetype:generate \
          -DinteractiveMode=false \
          -DarchetypeGroupId=org.openjdk.jmh \
          -DarchetypeArtifactId=jmh-java-benchmark-archetype \
          -DgroupId=com.demo \
          -DartifactId=JMHDemo \
          -Dversion=1.0

You can import this project into eclipse. File > Import > Existing Maven Project

Lets create a JMH benchmark to compare looping of array list. Example below

package com.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

/*
http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
*/
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@State(Scope.Benchmark)
@Fork(value = 2, jvmArgs = {"-Xms2G", "-Xmx2G"})
//@Warmup(iterations = 3)
//@Measurement(iterations = 8)
public class BenchmarkLoop {

    @Param({"10000000"})
    private int N;

    private List<String> DATA_FOR_TESTING;

    public static void main(String[] args) throws RunnerException {

        Options opt = new OptionsBuilder()
                .include(BenchmarkLoop.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }

    @Setup
    public void setup() {
        DATA_FOR_TESTING = createData();
    }

    @Benchmark
    public void loopFor(Blackhole bh) {
        for (int i = 0; i < DATA_FOR_TESTING.size(); i++) {
            String s = DATA_FOR_TESTING.get(i); //take out n consume, fair with foreach
            bh.consume(s);
        }
    }

    @Benchmark
    public void loopWhile(Blackhole bh) {
        int i = 0;
        while (i < DATA_FOR_TESTING.size()) {
            String s = DATA_FOR_TESTING.get(i);
            bh.consume(s);
            i++;
        }
    }

    @Benchmark
    public void loopForEach(Blackhole bh) {
        for (String s : DATA_FOR_TESTING) {
            bh.consume(s);
        }
    }

    @Benchmark
    public void loopIterator(Blackhole bh) {
        Iterator<String> iterator = DATA_FOR_TESTING.iterator();
        while (iterator.hasNext()) {
            String s = iterator.next();
            bh.consume(s);
        }
    }

    private List<String> createData() {
        List<String> data = new ArrayList<>();
        for (int i = 0; i < N; i++) {
            data.add("Number : " + i);
        }
        return data;
    }

}
  • Eclipse Maven Clean
  • Eclipse Maven Install
  • Run as a Java Application