Subscribe To Our Newsletter
You will receive our latest post and tutorial.
Thank you for subscribing!

required
required


Url Shortener

Here we are going to design a url shortener system.

Questions for clear scope

Can you give an example of how a URL shortener work? – https://www.systeminterview.com/q=chatsystem&c=loggedin&v=v3&l=long

What is the traffic volume? – 100 million URLs are generated per day.

How long is the shortened URL? – as short as possible

What characters are allowed in the shortened URL? – Shortened URL can be a combination of numbers (0-9) and characters (a-z, A- Z).

Can shortened URLs be deleted or updated? – For simplicity, let us assume shortened URLs cannot be deleted or updated.

Here are the basic use cases:

  1. URL shortening: given a long URL => return a much shorter URL
  2. URL redirecting: given a shorter URL => redirect to the original URL
  3. High availability, scalability, and fault tolerance considerations

Solution with Base 62 conversion

Base conversion is an approach commonly used for URL shorteners. Base conversion helps to convert the same number between its different number representation systems. Base 62 conversion is used as there are 62 possible characters for hashValue.

Conversion of 11157 to base 62

The short url is https://tinyurl.com/2TX

  1. longURL is the input.
  2. The system checks if the longURL is in the database.
  3. If it is, it means the longURL was converted to shortURL before. In this case, fetch the shortURL from the database and return it to the client.
  4. If not, the longURL is new. A new unique ID (primary key) Is generated by the unique ID generator.
  5. Convert the ID to shortURL with base 62 conversion.
  6. Create a new database row with the ID, shortURL, and longURL.

To make the flow easier to understand, let us look at a concrete example.

  • Assuming the input longURL is: https://en.wikipedia.org/wiki/Systems_design • Unique ID generator returns ID: 2009215674938.
  • Convert the ID to shortURL using the base 62 conversion. ID (2009215674938) is converted to “zn9edcu”.
  • Save ID, shortURL, and longURL to the database

Comparison of Hash solution vs Base 62 conversion

As you can see Base 62 conversion is the clear winner.

 

March 14, 2019

Java For Loop

 

For loop is used to execute a statement or a set of statements repeatedly until a certain condition is met.

for(initialization ; condition ; logic for condition){
    // statement(s);
}

First Step: The initialization part of the loop happens first and only executes once.
Second Step: The condition is evaluated on each iteration and if it’s true the statement(s) is executed and if it’s false then the iteration will stop.
Third Step: After every statement execution, the logic for condition is executed which purpose is to make condition meet a limit.

for(int i = 0 ;i < 5 ; i++){
    System.out.println("i is "+i);
}

Output:
i is 0
i is 1
i is 2
i is 3
i is 4

If the condition never becomes false then it’s an infinite loop. Infinite loop is not an expected behavior is Software.

// infinite loop
for(int i = 1 ;i >= 1 ; i++){
    System.out.println("i is "+i);
}
for( ; ; ){
   // statement(s);
}

Using for loop to loop through an array

int[] numbers = {1,2,3,4,5};
for(int i=0;i<numbers.length;i++){
   System.out.println("i is "+numbers[i]);
}

Output:
i is 1
i is 2
i is 3
i is 4
i is 5

Foreach Loop

int[] numbers = {1,2,3,4,5};
for(int i : numbers){
   System.out.println("i is "+i);
}

i is 1
i is 2
i is 3
i is 4
i is 5

 

 

March 12, 2019

Java Conditional Statements

 

Just like the decisions we make in life such as for example buying a car. If the car we are looking for is higher than our searching price then that car is too expensive and we won’t buy it. Else if the car is at our searching price or less we will buy it. In Java and programming in general, we use conditional statements to evaluate our decision.

We use the comparison operators to evaluate our condition.
1. Less than (x < y)
2. Less than or equal to (x <= y)
3. Greater than (x > y)
4. Greater than or equal to (x >= y)
5. Equal (x == y)
6. Not equal (x != y)

If - one if

if (condition) statement;

if (condition) {
  statement;
  statement;
}

 


It is recommended to use {} to specify where the block code ends. It is for readability.

if(10 > 5){
  System.out.println("10 is greater than 5");
}

(10 > 5) – condition
System.out.println(“10 is greater than 5”); – statement

If Else – one if else
if(condition){
        statement;
}else{
        statement;
}

if(5 < 10){
  System.out.println("5 is less than 10");
}else{
  System.out.println("10 is greater than 5");
}
If ElseIf ElseIf Else - multiple if else

if (condition1) {
     //block of code to execute if condition1 is true ;
}else if(condition2){
     //block of code to execute if condition2 is true ;
}else if(condition3){
     //block of code to execute if condition3 is true ;;
}else{
     //block of code to execute if none of the above conditions are true;
}

 

int age 30;
if(age < 19){
  System.out.println("You are a baby.");
} else if (age < 30){
  System.out.println("You are an adult.");
} else {
  System.out.println("You are old.");
}

Switch Statement
Switch statement provides better readability when they are too many if else statements.

String gender = "MALE";
switch(gender){
   case:"MALE";
   System.out.println("You are a man");
   break;
   case:"FEMALE";
   System.out.println("You are a woman");
   break;
   default:
   System.out.println("You are bisexual");
   break;
}

Notice a few key differences:

Arrow (->) vs. Colon (:): The new syntax uses -> for cases instead of :

Multiple Labels: Multiple case labels can be grouped together, separated by commas, as shown with MONDAY, FRIDAY, SUNDAY. No fallthrough: The new switch expression eliminates the notorious “fallthrough” behavior of the traditional switch statement, thus reducing errors.

Returning values: The switch expression returns a value, allowing it to be used in more expressive ways, like assigning a value to a variable. Yield for returning values in a block: If a case needs to execute a block of code, you can use yield to return a value from that block:

Benefits:

Readability: The code becomes concise and easier to understand.

 Safety: Avoids accidental fallthrough.

Expressiveness: Switch can now be used in more contexts due to its ability to return values.

 Considerations:

Always have a default case or cover all possible cases to ensure exhaustive handling.

When using the new switch expressions, always ensure that each case is exhaustive and handles all scenarios. The compiler will help in this by throwing an error if you’ve missed a case for a known set of inputs.

Remember that switch expressions were introduced in Java 12 as a preview feature. If you’re using a version prior to Java 14, you’ll need to enable preview features to use switch expressions. Starting from Java 14, they are a standard feature.

DayOfWeek dayOfWeek = DayOfWeek.WEDNESDAY;

        // you can return a value from the switch
        String dayType = switch (dayOfWeek) {
            case FRIDAY, SATURDAY, SUNDAY -> "End of week";
            case MONDAY, TUESDAY -> "Start of week";
            case WEDNESDAY, THURSDAY -> "Midweek";
            default -> throw new IllegalArgumentException("Invalid day");
        };

        System.out.println("dayType: " + dayType);

        Random random = new Random();
        int number = random.nextInt(1, 11);

        String message = switch (number) {
            case 1, 2, 3 -> "End of week";
            case 4, 5, 6 -> "Start of week";
            case 7, 8, 9 -> {
                /**
                 * if you want to execute lines of code, this is how to do it.
                 * 
                 * Yield for returning values in a block: If a case needs to execute a block of code, you can use yield
                 * to return a value from that block:
                 */
                String result = "Midweek";
                yield result; // 'yield' returns the value for this case
            }
            default -> "no idea";
        };

        System.out.println("number: " + number + ", message: " + message);

 

 

IF, IF ELSE, and ELSE

double amount = 0;

if(amount>0) {
    System.out.println("amount>0");
}else if(amount<0) {
    System.out.println("amount<0");
}else {
    System.out.println("amount=0");
}

// output
amount=0
double amount = -0.60;

if(amount < -0.50) {
    System.out.println("amount < -0.50");
}else {
    System.out.println("amount > -0.50");
}

//output
amount < -0.50

 

 

March 12, 2019

Python Advanced – Machine Learning

 

March 11, 2019

Regex

Regex for social security number validation

United States Social Security numbers are nine-digit numbers in the format AAA-GG-SSSS with following rules.

  • The first three digits called the area number. The area number cannot be 000, 666, or between 900 and 999.
  • Digits four and five are called the group number and range from 01 to 99.
  • The last four digits are serial numbers from 0001 to 9999.

Regex : ^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$

^            # Assert position at the beginning of the string.
(?!000|666)  # Assert that neither "000" nor "666" can be matched here.
[0-8]        # Match a digit between 0 and 8.
[0-9]{2}     # Match a digit, exactly two times.
-            # Match a literal "-".
(?!00)       # Assert that "00" cannot be matched here.
[0-9]{2}     # Match a digit, exactly two times.
-            # Match a literal "-".
(?!0000)     # Assert that "0000" cannot be matched here.
[0-9]{4}     # Match a digit, exactly four times.
$            # Assert position at the end of the string.

static String regex = "^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$";
private static Pattern emailPattern = Pattern.compile(regex);
    
public static Boolean isValidSSNFormat(String ssn) {
        if(ssn==null || ssn.length()==0) {
            return false;
        }
        return emailPattern.matcher(ssn).matches();
}

 

Regex for email validation

public class EmailRegex {
    static String regex = "^[a-zA-Z0-9_!#$%&’*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$";
    private static Pattern emailPattern = Pattern.compile(regex);
    
    public static Boolean isValidEmailFormat(String email) {
        if(email==null || email.length()==0) {
            return false;
        }
        return emailPattern.matcher(email).matches();
    }
}
public class EmailRegexDemo {
    public static void main(String[] args) {
        String email = "folau@gmail.com";
        
        boolean valid = EmailRegex.isValidEmailFormat(email);
        
        System.out.println(email+" is a valid email = "+valid);
    }
}

Regex for password validation

Password validation is the need for almost all the applications today. There are various ways to do validate passwords from writing everything manually to use third party available APIs.

static String regex = "((?=.*[a-z])(?=.*d)(?=.*[@#$%])(?=.*[A-Z]).{6,16})";
  
  /*
   * (?=.*[a-z])     : This matches the presence of at least one lowercase letter.
   * (?=.*d)         : This matches the presence of at least one digit i.e. 0-9.
   * (?=.*[@#$%])    : This matches the presence of at least one special character.
   * ((?=.*[A-Z])    : This matches the presence of at least one capital letter.
   * {6,16}          : This limits the length of password from minimum 6 letters to maximum 16 letters.
   */
  public static Boolean isValidPasswordFormat(String password) {
      if(password==null || password.length()==0) {
          return false;
      }
      return Pattern.compile(regex).matcher(password).matches();
  }

 

US zipcode regex validation 

/*
* ^         # Assert position at the beginning of the string.
* [0-9]{5}  # Match a digit, exactly five times.
* (?:       # Group but don't capture:
* -         # Match a literal "-".
* [0-9]{4}  # Match a digit, exactly four times.
* )         # End the non-capturing group.
* ?         # Make the group optional.
* $         # Assert position at the end of the string.
*/
static String US_ZIPCODE_REGEX = "^[0-9]{5}(?:-[0-9]{4})?$";
public static Boolean isValidUSZipcodeFormat(String zipcode) {
    if(zipcode==null || zipcode.length()==0) {
        return false;
    }
    return Pattern.compile(US_ZIPCODE_REGEX).matcher(zipcode).matches();
}

public class ZipcodeDemo {
    public static void main(String[] args) {
        
        List<String> zips = new ArrayList<String>();
           
        //Valid ZIP codes
        zips.add("12345"); 
        zips.add("12345-6789"); 
         
        //Invalid ZIP codes
        zips.add("123456"); 
        zips.add("1234"); 
        zips.add("12345-678");
         
        zips.add("12345-67890");
         
        for (String zip : zips)
        {
            boolean valid = ZipcodeRegex.isValidUSZipcodeFormat(zip);
            System.out.println(zip+" is a valid US zipcode? "+valid);
        }
         
        
        
    }
}

12345 is a valid US zipcode? true
12345-6789 is a valid US zipcode? true
123456 is a valid US zipcode? false
1234 is a valid US zipcode? false
12345-678 is a valid US zipcode? false
12345-67890 is a valid US zipcode? false

UK zipcode regex validation 

static String UK_ZIPCODE_REGEX = "^[A-Z]{1,2}[0-9R][0-9A-Z]? [0-9][ABD-HJLNP-UW-Z]{2}$";
    
    
public static Boolean isValidUKZipcodeFormat(String zipcode) {
    if(zipcode==null || zipcode.length()==0) {
        return false;
    }
    return Pattern.compile(UK_ZIPCODE_REGEX).matcher(zipcode).matches();
}

Regex for number of lines

StringBuilder line = new StringBuilder();
line.append("Hey man");
line.append("\n");
line.append("I like Java");
line.append("\n");
        
boolean valid = StringRegex.isValidLines(line.toString(), 2);
System.out.println("does \n===\n" + line.toString() + "===\nhas 2 lines? " + valid);

Regex for number of words

public static Boolean isValidLength(String str, int length) {
        String regex = "^\\W*(?:\\w+\\b\\W*){1,"+length+"}$";
        return Pattern.compile(regex).matcher(str).matches();
}
public class StringRegexDemo {
    public static void main(String[] args) {
        List<String> inputs = new ArrayList<String>();
        inputs.add("Folaulau");
        inputs.add("JAVA is great");
        inputs.add("I love java programming");
        
        inputs.forEach((input) -> {
            int length = 10;
            boolean valid = StringRegex.isValidLength(input, length);
            System.out.println("is " + input + " " + length + " in length? " + valid);
        });
    }
}

# output
is Folaulau 10 in length? true
is JAVA is great 10 in length? true
is I love java programming 10 in length? true

Regex for ISBN

ISBN-10 or ISBN-13 : ^(?:ISBN(?:-1[03])?:? )?(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})
[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)
(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]$

public class RegexISNBDemo {
    public static void main(String[] args) {
        List<String> isbns = new ArrayList<String>();
           
        //Valid ISBNs
        isbns.add("0-596-52068-9"); 
        isbns.add("0 512 52068 9"); 
        isbns.add("ISBN-10 0-596-52068-9");
        isbns.add("ISBN-10: 0-596-52068-9");
         
        //Invalid ISBNs
        isbns.add("0-5961-52068-9"); 
        isbns.add("11 5122 52068 9"); 
        isbns.add("ISBN-13 0-596-52068-9");
        isbns.add("ISBN-10- 0-596-52068-9");
        
        isbns.forEach((isbn)->{
            boolean valid = RegexISNB.isValidISBNFormat(isbn);
            System.out.println("is "+isbn+" a valid ISBN? "+valid);
        });
    }
}
is 0-596-52068-9 a valid ISBN? true
is 0 512 52068 9 a valid ISBN? true
is ISBN-10 0-596-52068-9 a valid ISBN? true
is ISBN-10: 0-596-52068-9 a valid ISBN? true
is 0-5961-52068-9 a valid ISBN? false
is 11 5122 52068 9 a valid ISBN? false
is ISBN-13 0-596-52068-9 a valid ISBN? true
is ISBN-10- 0-596-52068-9 a valid ISBN? false

Remove special characters from file name

 /*
 * Only alphabets[a-z] and digits[0-9], dot, underscore, dash
 */
String alphaAndDigits = "[^a-zA-Z0-9.-_]+";
String newFileName = fileName.replaceAll(alphaAndDigits, "");


@Test
public void test_replace_invalid_characters() {
    String fileName = "test .jpg";
    String newFileName = FileUtils.replaceInvalidCharacters(fileName);
    System.out.println("newFileName=" + newFileName);
    fileName = "test]&.jpg";
    newFileName = FileUtils.replaceInvalidCharacters(fileName);
    System.out.println("newFileName=" + newFileName);
    fileName = "test$.jpg";
    newFileName = FileUtils.replaceInvalidCharacters(fileName);
    System.out.println("newFileName=" + newFileName);
    fileName = "test@=`.jpg";
    newFileName = FileUtils.replaceInvalidCharacters(fileName);
    System.out.println("newFileName=" + newFileName);
}
newFileName=test.jpg
newFileName=test.jpg
newFileName=test.jpg
newFileName=test.jpg

 

March 11, 2019