Skip to content

Commit 8f2a8e6

Browse files
Merge pull request learning-zone#18 from shreeram09/master
updated: answered few questions in top readme
2 parents e8df17f + f5069e8 commit 8f2a8e6

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed

README.md

Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3320,18 +3320,308 @@ The Object class is the parent class of all the classes in java by default.
33203320
</div>
33213321

33223322
#### Q. What is copyonwritearraylist in java?
3323+
* `CopyOnWriteArrayList` class implements `List` and `RandomAccess` interfaces and thus provide all functionalities available in `ArrayList` class.
3324+
* Using `CopyOnWriteArrayList` is costly for update operations, because each mutation creates a cloned copy of underlying array and add/update element to it.
3325+
* It is `thread-safe` version of ArrayList. Each thread accessing the list sees its own version of snapshot of backing array created while initializing the iterator for this list.
3326+
* Because it gets `snapshot` of underlying array while creating iterator, it does not throw `ConcurrentModificationException`.
3327+
* Mutation operations on iterators (remove, set, and add) are not supported. These methods throw `UnsupportedOperationException`.
3328+
* CopyOnWriteArrayList is a concurrent `replacement for a synchronized List` and offers better concurrency when iterations outnumber mutations.
3329+
* It `allows duplicate elements and heterogeneous Objects` (use generics to get compile time errors).
3330+
* Because it creates a new copy of array everytime iterator is created, `performance is slower than ArrayList`.
3331+
* We can prefer to use CopyOnWriteArrayList over normal ArrayList in following cases:
3332+
- When list is to be used in concurrent environemnt.
3333+
- Iterations outnumber the mutation operations.
3334+
- Iterators must have snapshot version of list at the time when they were created.
3335+
- We don’t want to synchronize the thread access programatically.
3336+
```java
3337+
import java.util.concurrent.CopyOnWriteArrayList;
3338+
CopyOnWriteArrayList<String> copyOnWriteArrayList = new CopyOnWriteArrayList<String>();
3339+
copyOnWriteArrayList.add("captain america");
3340+
Iterator it = copyOnWriteArrayList.iterator(); //iterator creates separate snapshot
3341+
copyOnWriteArrayList.add("iron man"); //doesn't throw ConcurrentModificationException
3342+
while(it.hasNext())
3343+
System.out.println(it.next()); // prints captain america only , since add operation is after returning iterator
3344+
3345+
it = copyOnWriteArrayList.iterator(); //fresh snapshot
3346+
while(it.hasNext())
3347+
System.out.println(it.next()); // prints captain america and iron man,
3348+
3349+
it = copyOnWriteArrayList.iterator(); //fresh snapshot
3350+
while(it.hasNext()){
3351+
System.out.println(it.next());
3352+
it.remove(); //mutable operation 'remove' not allowed ,throws UnsupportedOperationException
3353+
}
3354+
3355+
ArrayList<String> list = new ArrayList<String>();
3356+
list.add("A");
3357+
Iterator ait = list.iterator();
3358+
list.add("B"); // immediately throws ConcurrentModificationException
3359+
while(ait.hasNext())
3360+
System.out.println(ait.next());
3361+
3362+
ait = list.iterator();
3363+
while(ait.hasNext()){
3364+
System.out.println(ait.next());
3365+
ait.remove(); //mutable operation 'remove' allowed without any exception
3366+
}
3367+
```
3368+
33233369
#### Q. How do you test static method?
33243370
#### Q. How to do you test a method for an exception using JUnit?
33253371
#### Q. Which unit testing libraries you have used for testing Java programs?
33263372
#### Q. What is the difference between @Before and @BeforeClass annotation?
33273373
#### Q. Can you explain Liskov Substitution principle?
3374+
Liskov Substitution principle (LSP) states that **sub/child/derived-classes should be substitutable for their base/parent-classes.**
3375+
3376+
Given a class B is subclass of class A , we should be able to pass an object of class B to any method that expects(takes as an argument/parameter) an object of class A and the method should not give any weird output in that case.
3377+
3378+
`ClientTestProgram` class has a method `playVideoInAllMediaPlayers()` which accepts list of all `MediaPlayer` objects and plays video for each , but method fails at `WinampMediaPlayer` ? Let's check whether it satisfies **LSP**.
3379+
```java
3380+
public class MediaPlayer {
3381+
3382+
// Play audio implementation
3383+
public void playAudio() {
3384+
System.out.println("Playing audio...");
3385+
}
3386+
3387+
// Play video implementation
3388+
public void playVideo() {
3389+
System.out.println("Playing video...");
3390+
}
3391+
}
3392+
3393+
public class VlcMediaPlayer extends MediaPlayer {}
3394+
3395+
public class WinampMediaPlayer extends MediaPlayer {
3396+
3397+
// Play video is not supported in Winamp player
3398+
public void playVideo() {
3399+
throw new VideoUnsupportedException();
3400+
}
3401+
}
3402+
3403+
public class VideoUnsupportedException extends RuntimeException {
3404+
3405+
private static final long serialVersionUID = 1 L;
3406+
3407+
}
3408+
3409+
public class ClientTestProgram {
3410+
3411+
public static void main(String[] args) {
3412+
3413+
// Created list of players
3414+
List < MediaPlayer > allPlayers = new ArrayList < MediaPlayer > ();
3415+
allPlayers.add(new VlcMediaPlayer());
3416+
allPlayers.add(new DivMediaPlayer());
3417+
3418+
// Play video in all players
3419+
playVideoInAllMediaPlayers(allPlayers);
3420+
3421+
// Well - all works as of now...... :-)
3422+
System.out.println("---------------------------");
3423+
3424+
// Now adding new Winamp player
3425+
allPlayers.add(new WinampMediaPlayer());
3426+
3427+
// Again play video in all players & Oops it broke the program... :-(
3428+
// Why we got unexpected behavior in client? --- Because LSP is violated in WinampMediaPlayer.java,
3429+
// as it changed the original behavior of super class MediaPlayer.java
3430+
playVideoInAllMediaPlayers(allPlayers);
3431+
}
3432+
3433+
/**
3434+
* This method is playing video in all players
3435+
*
3436+
* @param allPlayers
3437+
*/
3438+
public static void playVideoInAllMediaPlayers(List < MediaPlayer > allPlayers) {
3439+
3440+
for (MediaPlayer player: allPlayers) {
3441+
player.playVideo();
3442+
}
3443+
}
3444+
}
3445+
```
3446+
Let's refactor the code to make "good" design using **LSP**?
3447+
- `MediaPlayer` is super class having play audio ability.
3448+
- `VideoMediaPlayer` extends `MediaPlayer` and adds play video ability.
3449+
- `DivMediaPlayer` and `VlcMediaPlayer` both extends `VideoMediaPlayer` for playing audio and video ability.
3450+
- `WinampMediaPlayer` which extends `MediaPlayer` for playing audio ability only.
3451+
- so client program can substitute `DivMediaPlayer` or `VlcMediaPlayer` for their super class `VideoMediaPlayer`
3452+
3453+
lets reimplement the refactored code
3454+
```java
3455+
public class MediaPlayer {
3456+
3457+
// Play audio implementation
3458+
public void playAudio() {
3459+
System.out.println("Playing audio...");
3460+
}
3461+
}
3462+
3463+
//separated video playing ability from base class
3464+
public class VideoMediaPlayer extends MediaPlayer {
3465+
3466+
// Play video implementation
3467+
public void playVideo() {
3468+
System.out.println("Playing video...");
3469+
}
3470+
}
3471+
3472+
public class DivMediaPlayer extends VideoMediaPlayer {}
3473+
3474+
public class VlcMediaPlayer extends VideoMediaPlayer {}
3475+
3476+
//as Winamp expects only audio playing ability, so it must only extend relative base class behaviour, no need to inherit unnecessary behaviour
3477+
public class WinampMediaPlayer extends MediaPlayer {}
3478+
3479+
/**
3480+
* This method is playing video in all players
3481+
*
3482+
* @param allPlayers
3483+
*/
3484+
public static void playVideoInAllMediaPlayers(List <VideoMediaPlayer> allPlayers) {
3485+
3486+
for (VideoMediaPlayer player: allPlayers) {
3487+
player.playVideo();
3488+
}
3489+
}
3490+
```
3491+
Now, in `ClientTestProgram` , instead of creating list of type `MediaPlayer`, we will create list of `VideoMediaPlayer` type that should give us compile time error at statement `allPlayers.add(new WinampMediaPlayer()); ` as `WinampMediaPlayer` isnt subclass of `VideoMediaPlayer`.But in case of `DivMediaPlayer` and `VlcMediaPlayer` they are substitutable for their parent class as seen in `playVideoInAllMediaPlayers()` method
3492+
that satisefies *Liskov's substitution principle*.
3493+
33283494
#### Q. Give me an example of design pattern which is based upon open closed principle?
33293495
#### Q. What is Law of Demeter violation? Why it matters?
33303496
#### Q. What is differences between External Iteration and Internal Iteration?
3497+
33313498
#### Q. What are the different access specifiers available in java?
3499+
* access specifiers/modifiers helps to restrict the scope of a class, constructor, variable, method, or data member.
3500+
* There are four types of access modifiers available in java:
3501+
1. `default` – No keyword required, when a class, constructor,variable, method, or data member declared without any access specifier then it is having default access scope i.e. accessible only within the same package.
3502+
2. `private` - when declared as a private , access scope is limited within the enclosing class.
3503+
3. `protected` - when declared as protocted, access scope is limited to enclosing classes, subclasses from same package as well as other packages.
3504+
4. `public` - when declared as public, accessible everywhere in the program.
3505+
```java
3506+
... /* data member variables */
3507+
String firstName="Pradeep"; /* default scope */
3508+
protected isValid=true; /* protected scope */
3509+
private String otp="AB0392"; /* private scope */
3510+
public int id = 12334; /* public scope */
3511+
...
3512+
... /* data member functions */
3513+
String getFirstName(){ return this.firstName; } /* default scope */
3514+
protected boolean getStatus(){this.isValid;} /* protected scope */
3515+
private void generateOtp(){ /* private scope */
3516+
this.otp = this.hashCode() << 16;
3517+
};
3518+
public int getId(){ return this.id; } /* public scope */
3519+
...
3520+
.../* inner classes */
3521+
class A{} /* default scope */
3522+
protected class B{} /* protected scope */
3523+
private class C{} /* private scope */
3524+
public class D{} /* public scope */
3525+
...
3526+
```
3527+
33323528
#### Q. What is runtime polymorphism in java?
3529+
**Runtime polymorphism** or **Dynamic Method Dispatch** is a process in which a call to an overridden method is resolved at runtime rather than compile-time.
3530+
3531+
An overridden method is called through the reference variable of a superclass. The determination of the method to be called is based on the object being referred.
3532+
```java
3533+
class Bank{
3534+
public float roi=0.0f;
3535+
float getRateOfInterest(){return this.roi;}
3536+
}
3537+
class SBI extends Bank{
3538+
float roi=8.4f;
3539+
float getRateOfInterest(){return this.roi;}
3540+
}
3541+
class ICICI extends Bank{
3542+
float roi=7.3f;
3543+
float getRateOfInterest(){return this.roi;}
3544+
}
3545+
class AXIS extends Bank{
3546+
float roi=9.7f;
3547+
float getRateOfInterest(){return this.roi;}
3548+
}
3549+
3550+
Bank b;
3551+
b=new SBI();
3552+
System.out.println("SBI Rate of Interest: "+b.getRateOfInterest());
3553+
3554+
b=new ICICI();
3555+
System.out.println("ICICI Rate of Interest: "+b.getRateOfInterest());
3556+
3557+
b=new AXIS();
3558+
System.out.println("AXIS Rate of Interest: "+b.getRateOfInterest());
3559+
3560+
System.out.println("Bank Rate of Interest: "+b.roi);
3561+
3562+
/**output:
3563+
SBI Rate of Interest: 8.4
3564+
ICICI Rate of Interest: 7.3
3565+
AXIS Rate of Interest: 9.7
3566+
Bank Rate of Interest: 0.0
3567+
3568+
//you might think it should be 9.7 , as recent object being refered to is of AXIS but method is overridden, not the data members, so runtime polymorphism can't be achieved by data members/instance variables.
3569+
**/
3570+
```
33333571
#### Q. What is a private constructor?
3572+
* A constructor with private access specifier/modifier is private constructor.
3573+
* It is only accessible inside the class by its data members(instance fields,methods,inner classes) and in static block.
3574+
* Private Constructor be used in **Internal Constructor chaining and Singleton class design pattern**
3575+
```java
3576+
public class MyClass {
3577+
3578+
static{
3579+
System.out.println("outer static block..");
3580+
new MyClass();
3581+
}
3582+
3583+
private MyInner in;
3584+
3585+
{
3586+
System.out.println("outer instance block..");
3587+
//new MyClass(); //private constructor accessbile but bad practive will cause infinite loop
3588+
}
3589+
3590+
private MyClass(){
3591+
System.out.println("outer private constructor..");
3592+
}
3593+
3594+
public void getInner(){
3595+
System.out.println("outer data member function..");
3596+
3597+
new MyInner();
3598+
}
33343599

3600+
private static class MyInner{
3601+
{
3602+
System.out.println("inner instance block..");
3603+
new MyClass();
3604+
}
3605+
3606+
MyInner(){
3607+
System.out.println("inner constructor..");
3608+
}
3609+
}
3610+
3611+
3612+
public static void main(String args[]) {
3613+
System.out.println("static main method..");
3614+
MyClass m=new MyClass();
3615+
m.getInner();
3616+
}
3617+
}
3618+
3619+
class Visitor{
3620+
{
3621+
new MyClass();//gives compilation error as MyClass() has private access in MyClass
3622+
}
3623+
}
3624+
```
33353625
*ToDo*
33363626

33373627
<div align="right">

0 commit comments

Comments
 (0)