Saturday, June 22, 2019

Cracking Java8 Stream Interview Question

Greetings!

I have faced many interviews (too many to be frank) in my career as a software developer. In most of those interviews I have been asked to write a pseudo code for a given problem and implement it in Java. With Java8, this implementation mostly should be in Java8.
When I look back all those questions it can be simplified as below. (difficulty may be vary though).

  • Iterate over a given collection (stream)
  • Filter the given data (filter)
  • Transform into another format (map, reduce)
  • Collect data into a collection (collect)
  • or End the stream (forEach, min, etc)

Is this familiar to you? This should be. This is what we do in our daily work. But, if you are blindly using it you will see it as a difficult question to answer.
You need to have good understanding about intermediate and terminal operations. And, you need to really practise and use in daily work. It is meaningless to pass an interview without knowing these.
java-8-streams-intermediate-operations
java-8-streams-terminal-operations

Let's dive into some real questions.

Find the youngest male student by given list

Let's divide this into smaller parts.
- youngest -> min
- male -> filter
- list -> iterate
Student youngestmale = students.stream()
        .filter(student -> student.gender.equals("male"))
        .min((s1, s2) -> s1.age - s2.age) //.min(Comparator.comparingInt(s -> s.age))
        .get();

Find all numbers divisible by 3

This is an easy question. But you may remember IntStream. And also if you are asked to how to collect the result into a list you need to remember to convert int to Integer. For this IntStream has boxed operation. Let's break down it.
- divisible -> filter
IntStream.rangeClosed(0, 25)
        .filter(number -> number % 3 == 0)
        .forEach(System.out::println);

// collect the result
List result = IntStream.rangeClosed(0, 25)
        .filter(number -> number % 3 == 0)
        .boxed()
        .collect(Collectors.toList());


Find the sum of even number's power of two

This has multiple answers. It gets little tricky when you asked not to use sum operation. But still we have the same format.
- even numbers -> filter
- power of two -> map
- sum -> sum (doesn't exist in Stream but in IntStream)
or
- power of two and sum -> reduce
// method 1
int sum = IntStream.rangeClosed(0, 5)
        .filter(number -> number % 2 == 0)
        .map(number -> number * number)
        .sum();
System.out.println(sum);

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// method 2
int sum2 = numbers.stream()
        .filter(number -> number % 2 == 0)
        .mapToInt(number -> number * number) // convert to IntStream
        .sum();
System.out.println(sum2);

// method 3
int sum3 = numbers.stream()
        .filter(i -> i % 2 == 0)
        .reduce(0, (result, number) -> result + number * number);
System.out.println(sum3);

Find the average marks of a student

This looks difficult at first but very simple. It is because IntStream has average operation. We need to covert Stream into IntStream because;
- Autoboxing has a performance impact.
- sum, average operations are not in normal stream.
OptionalDouble average = subjects.stream()
        .mapToInt(Subject::getMarks)
        .average();

What do you think? Do you have any interesting interview question.



Friday, June 21, 2019

Angular - Let's create a starter project

Greetings!

Angular has many things to learn though we can skip those and directly create simple project. It will be harder to study all the features first. So here, i'm going to directly create a simple starter project.

This is the end result of this tutorial.



Install Angular CLI

npm install -g @angular/cli
ng version

Create a project

ng new angular-store --routing --style=scss
cd angular-store
npm install

This will create a basic app structure.

Run the project

ng serve --open

# short form
ng s -o

With zero code, we have a running template. That's some power.

Angular Material

Let's add material UI design into our project. For more information visit https://material.angular.io/
Below command will add angular material into our project and update neccessary files.
ng add @angular/material

We want to use material design component in our project. To add material components in a single place let's create a separate module named material and update it with neccessary materaial modules.
ng generate module material --flat

Now, we need to update app.module.ts to import our module.
import { MaterialModule } from './material.module';

  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MaterialModule
  ]

Making responsive UI

I'm going to use bootstrap css grid to create resposive user interface.
npm install --save bootstrap

Update angular.json file's style section to include bootstrap grid.
"styles": [
  "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
  "./node_modules/bootstrap/dist/css/bootstrap-grid.css",
  "src/styles.scss"
]

Create an app component

ng generate component home --module=app --spec=false

# short form
ng g c home --module=app --spec=false
ng g c about --module=app --spec=false

Adding a menu

Update app.component.html with below code. You can visit https://material.angular.io/components/toolbar/overview for more information.
<mat-toolbar color="primary">
  <span>Angular Store</span>
  <span class="spacer"></span>
  <button mat-button>Home</button>
  <button mat-button>About</button>
</mat-toolbar>

<router-outlet></router-outlet>

We need to import related modules in our material module.
import { MatButtonModule } from '@angular/material/button';
import { MatToolbarModule } from '@angular/material/toolbar';

Adding routes

When we create the project with --routing option, app-routing.module.ts is already created. What we need to do is specify our routes.
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';

const routes: Routes = [
  {
    path: '',
    component: HomeComponent
  },
  {
    path: 'about',
    component: AboutComponent
  }
];

Then, we need to update our menu bar to our routes.
  <button mat-button [routerLink]="['/']">Home</button>
  <button mat-button [routerLink]="['/about']">About</button>

Showing products

This will be just hard coded for loop. We are going to use material card to show our content. https://material.angular.io/components/card/overview
Update home.component.js with below variable.
items = new Array(10);

Update home.component.html with below content.
<div class="row">
  <div class="col-xs-12 col-sm-6 col-md-4 col-lg-3 mt-10" *ngFor="let item of items">
    <mat-card>
        <img mat-card-image src="/assets/icon.png" alt="" />
      <mat-card-header>
        <mat-card-title>Lorem, ipsum dolor.</mat-card-title>
      </mat-card-header>
      <mat-card-content>
        <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Aliquid, sapiente?</p>
      </mat-card-content>
      <mat-card-actions>
        <button mat-button color="primary">Add To Cart</button>
        <button mat-button color="primary">Read More</button>
      </mat-card-actions>
    </mat-card>
  </div>
</div>

Update styles.scss with mt-10 class.
.mt-10 {
    margin-top: 10px;
}

That's end of it. Even though we didn't touch deeper into Angular, this will give you something to play with.