OSI Reference Model

OSI (Open Systems Interconnection) is a reference model to define application communication flow over a network and is also defined as conceptual framework for understanding relationships.

In other words, to divide the interrelated aspects of Network operation into less complex operations and to defines standard interfaces to achieve compatibility and multi vendor integration.

Layer 7 Application
Layer 6 Presentation
Layer 5 Session
Layer 4 Transport
Layer 3 Network
Layer 2 Data Link
Layer 1 Physical


Application Layer:

  • Provides interface between OSI RM and end user application.
  • Provides network services to user client/server-based application.
  • Establishes and defines program-to-program communication.
  • Identifies availability of intended communication partner.
  • Examples include ftp, tftp, http, www browsers, DNS, SMTP, telnet.

Presentation Layer

  • Defines data format for transmission.
  • Ensures arriving data from the network can be transmitted by the application and information sent by the application can be transmitted on the network.
  • Performs encryption and decryption.
  • Example representation includes ASCII, JPEG, HTML etc.

Session layer

  • Defines how to strat, control and end session.
  • RPCs (Remote Procedure Call) operate at this layer.
  • Logon validation happens at this layer.
  • Named Pipes defined at this layer – Named Pipes use TCP to guarantee communication.
  • Session layer organizes communication through simple, half-duplex or full-duplex.
  • Example protocols include SQL, RPC, Named Pipes etc.

Transport Layer

  • Segmented data to be passed down to Network layer and reassembles data for session and upper layers.
  •  Provide the choice of connection-oriented and guaranteed (TCP) or connectionless and non-guaranteed(UDP) delivery of data .
  • Provides end to end transport services.
  • Provides flow control to overcome congestion in network.
  • Provides 3 flow control mechanism:
  1. Buffering: Each computer has enough buffer space to hold data before it os processed.
  2. Congestion Avoidance: Receiving computer notices its buffers are filling quickly and sends a stop message to the sending host to temporarily stop transmitting while it processes data already received. Then signals that it is ready for more data. Eg. Protocols – Synchronous Data Link Control (SDLC), Link Access Procedure, Balanced (LAPB), ICMP Source Quench (slows down rate instead of stopping it).
  3. Windowing: Defines maximum number of bytes it is willing to send at one time before an acknowledgement is expected.

Network Layer

  • Defines the network address.
  • Routers operate at this layer.
  • Segments from the transport layer are placed into and passed down to Data Link Layer.
  • Network layer routes data from one node to another.
  • Determines the best path/ route to destination device to use for routing data on the inter network- this is done using hop count or tick where 1 tick = 1/18th of a second.
  • Network layer maintains routing table.

Data Link Layer

  • Provides error- free link between 2 devices- CRC used for error checking.
  • Packets from the Network layer are placed into frames.
  • Data Link layer handles physical transmission of data from one node to another.
  • Handles error notification.
  • IEEE subdivided this layer into 2 sub layers
  1. Logical Link Control (LLC): Uses destination Service Access Point (DSAP) and Source Service Access Points (SSAP) to help lower protocols access Network layer protocols.
  2. Media Access Control (MAC) : build frames from bits performs CRC Handles MAC address- first digits of 12 hex defines vendor Id, next 6 defines serial no of that vendor Id.

Physical Layer

  • Defines connections – RJ-45, RJ-11, BNC etc.
  • Places Frames, represented as bits, onto media as electric signals or pulses of light.
  • Hubs are repeaters operate at this layer.

Synchronization in Multithreading

When two or more threads need access to a shared resource, they need some way to ensure that the resource will be used by only one thread at a time. The process by which this is achieved is called synchronization.

In other words,

Thread Synchronization is defined as a mechanism which ensures that two or more concurrent processes or threads do not simultaneously execute some particular program segment known as critical section.

Key to synchronization is the concept of the monitor. A monitor is an object that is used as a mutually exclusive lock. Only one thread can own a monitor at a given time. When a thread acquires a lock, it is said to have entered the monitor. All other threads attempting to enter the locked monitor will be suspended until the first thread exits the monitor. These other threads are said to be waiting for the monitor. A thread that owns a monitor can reenter the same monitor if it so desires.

You can synchronize your code in either of two ways. Both involve the use of the synchronized keyword, and both are examined here.

Real Life example of thread safe

If you are having a bank account and you have two debit cards. Consider one card is being used by you and another is used by your wife. Your bank account balance is 5000. One day you need money and you go to ATM and at the same time your wife is also going to use their ATM. Now, if you both make transaction at same time for 2000 out of whole money. Now, what should happen? Should it show the remaining balance 3000?

Turns out, No!

Because, if you are allowed to do so at the same time without taken care your account will not be then synchronized with number of transactions you made.

To do so we should have taken care of synchronization.

Now let’s see a case when synchronization is not there:

// This program is not synchronized.

class Callme {

    void call(String msg) {

        System.out.print("[" + msg);

        try {


        } catch(InterruptedException e) {





//creating a thread class implementing Runnable interface

class Caller implements Runnable {

    String msg;

    Callme target;

    Thread t;

    public Caller(Callme targ, String s) {

        target = targ;

        msg = s;

        t = new Thread(this);

       //starting thread



    // implementing runnable method.

    public void run() {



//creating main class

class SynchController {

    //main method

    public static void main(String args[]) {

        Callme target = new Callme();

        Caller ob1 = new Caller(target, "Hello");

        Caller ob2 = new Caller(target, "Synchronized");

        Caller ob3 = new Caller(target, "World");

        // wait for threads to end

        try {




        } catch(InterruptedException e) {





Here is the output produced by this program:

#Output : [Hello[Synchronized[World]



Note:   join( ) method wait for a thread to finish .This method waits until the thread on which it is called terminates. Its name comes from the concept of the calling thread waiting until the specified thread joins it. By calling join method our currently running thread waits for the joined thread to complete.

As you can see, by calling sleep( ), the call( ) method allows execution to switch to another thread. This results in the mixed-up output of the three message strings. In this program, nothing exists to stop all three threads from calling the same method, on the same object, at the same time. This is known as a race condition, because the three threads are racing each other to complete the method which can cause a program to run right one time and wrong the next.

To fix the preceding program, you must serialize access to call( ). That is, you must restrict its access to only one thread at a time. To do this, you simply need to precede call( )’s definition with the keyword synchronized, as shown here:

class Callme {

synchronized void call(String msg) {


This prevents other threads from entering call( ) while another thread is using it. After

synchronized has been added to call( ), the output of the program is as follows:

#output : [Hello]




Table Variables

Table variables are table type variables which are used to create table like structure. They are partially stored in both memory and in tempdb database of a database server. Once the execution is finished, table variables are dropped automatically.

Why we need Table variables

When you are executing code in T-SQL, tables are necessary to store data temporarily to smooth your development, raise code maintainability and re usability.


As other variables, table variables are declared inside the code block of batch or stored procedures. Table variable store a set of records, so naturally the declaration syntax looks very similar to create table statement, as you can see in following example:



Id int,

Name varchar(200)


Insert, update, delete in table variable is same as we do with normal Table.

  • INSERT INTO @usersTblVar(id, name) values(1,’raam’)
  • UPDATE @usersTblVar SET name =’shyam’ where id =’1’
  • DELETE FROM @usersTblVar where id =’1’

You might think table variable work just like temporary tables, there are differences.

Note: you cannot use table variable like input and output parameter but you can return a table variable from a user defined function. The restricted scope of a table variable gives are database server some liberty to perform optimization.


Because of scope definition concept, a table variable use fewer resources than a temporary table. Table variables only last only duration of update on table variable which reduces locking and logging overhead. It also reduces the problem of recompilation of stored procedures which occurs with temporary tables.


You can also insert into a table variable in bulk as well for example:

INSERT INTO @usersTblVar

SELECT * FROM usersBackup

It will insert data into table variable in bulk from usersBackup table.

Note: use table variable without @ in case of MySql.

Disadvantages of using table variables

  • You cannot create a non-cluster index on a table variable.
  • database server does not maintain statics on table variable.
  • Table definition of table variable cannot be changed after declaration.


Multithreading is a widespread programming and execution model that allows multiple threads to exist within the context of one process. These threads share the common resources of a single process and are able to execute independently. The threaded programming model provides developers with a useful abstraction of concurrent execution. Multithreading is widely used in processes which require one process to enable parallel execution on a multiprocessing system.

Where a thread of execution is a smallest sequence of programmed instruction that can be managed independently, typically the part of platform on which they are running either on JVM or on operating system itself.

Each of the threads can run in parallel. The OS divides processing time not only among different applications, but also among each thread within an application.

For example, the transmission rate of data over a network is much slower than the rate at which the computer can process it. Even local file system resources are read and written at a much slower pace than they can be processed by the CPU. And, of course, user input is much slower than the computer. In a single-threaded environment, your program has to wait for each of these tasks to finish before it can proceed to the next one—even though most of the time the program is idle, waiting for input. Multithreading helps you reduce this idle time because another thread can run when one is waiting.

Multithreading in java can be achieved via two ways:

  1. Via extending Thread class:
class MultithreadingDemo extends Thread{

//run method of Thread class is overridden here

    public void run(){

        System.out.println("hi, I am running");


    public static void main(String[] args){

       MultithreadingDemo multiThreadingObj = new MultithreadingDemo();

       //start method of Thread class starts the current tread



//##output :  hi, I am running

Thread class provides constructor and method to create and perform operation on a Thread.

2  Via implementing Runnable interface:

class MultithreadingDemo implements Runnable{

//implement run method of Runnable interface

    public void run(){

        System.out.println("hi, I am running");


    public static void main(String[] args){

        MultithreadingDemo multiThreadingObj = new MultithreadingDemo();

        //create object of Thread class

        Thread threadObj = new Thread(multiThreadingObj);



//##output :  hi, I am running

Class implementing Runnable interface, need to provide definition of run method of Runnable interface.

Note: when start method of newly created thread is called then it enters into runnable states.

Merits of Multithreading

  1. Threads work independently and if any exception occurs it affects only that thread.
  2. Threads are light weight.
  3. Cost of communication is low between treads.
  4. It saves time of achieving multiple tasks done.

Demerits of Multithreading

  1. It is complex to debug and test the program while using Multithreading.
  2. Chances of deadlock to occur, increases.
  3. Need to replace those functions which are not thread safe.
  4. Need to remove static variables.
  5. Not easy to port existing code into Multithreading.