Technical

Possible technical question

General

Front-end coding challenges

Practice front-end coding here

Web

Server-side Rendering Vs Client-side Rendering

HTTP Status Codes

  • 1XX - Informational (We don't use much)

  • 2XX - Success codes

  • 3XX - Redirection codes

  • 4XX - Client-side error codes

  • 5XX - Server-side error codes

2XX Codes

  • 200 OK - General success status code, meaning everything was okay and we might receive back some content

  • 201 Created - All of our post requests - When we create a new resource on our server and was successful

  • 204 No Content - Everything was okay but the server has nothing to return. For example, when we delete a user/resource, we don't have to get back any info and that is ok. So we can use 204 for that type

3XX Codes - If we visit a URL and it redirects to another URL, the first URL would return us 3XX

  • 304 Not modified - This is not much to do with redirecting, but it is related to caching. When we call an API, maybe we don't want to get all the results every time because the results might not change that often but they might change every few days but we constantly want to check if something changed. So we send a request asking, "Has anything been changed since x date" and the server returns 304 if nothing has been changed.

4XX Codes - Error from the client-side. A person using API either sent bad info to the server or they are not authorized and so on

  • 400 Bad request - Server says "Something you sent was bad". Don't know the specific reason for something being bad or the user just send bad parameters (when email and name was expected, the server got only the name)

  • 401 Unauthorized - You're trying to access that requires authentication but your API key or some credentials are bad so I don't know who you are

  • 403 Forbidden - The client is authenticated with the right API but doesn't have permission to access that resource he's requesting

  • 404 Not found - API endpoint not found. /cart doesn't exist

5XX Codes

  • 500 Internal Server Error - Generic error which says something went wrong on the server. When server-side code has a bug generally

JavaScript

0. Why do you like Javascript?

JS is one of the best languages out there according to me, not because of it's syntax or working, but because the way it is designed keeping in mind about old and modern feature implementations. It should keep in mind while designing not to introduce breaking changes while supporting so many browsers out there. Hats off to the developers who should spend more time on taking care of each and every detail not to break anything before actually implementing it.

The second reason I love it because, even though it's so complex to develop Js, it has let more modern way of web based on which all the new libraries and frame works like react, angular and vue are built upon. In today's world, everything is Javscript in the web. Even JS started supporting mobile (react native and ionic frameworks).

Though JS is dynamically typed, we now have TS which adds upon JS for catering static typing which is again appreciable.

This way, JS basically encourages developers of any language to pick up JS soon. JS is in front-end, back-end, mobile and soon I believe it takes up the space of Machine learning and Artificial intelligence.

This is all possible because of huge community support where we have over a million modules on npm today.

1. Iterables and Iterators - ES6

1. Why Iterables and Iterators were introduced?

2. What is iterable & iterator?

3. Implement your own iterable and iterator.

1. Why Iterable and Iterator were introduced?

Iteration in JS was done using for, while, and do-while loops before the Iterators and Iterables concept was introduced.

So we wanted a way to iterate over different data structures in the same way/uniform way. This was the reason for introducing iterator and iterable.

They were introduced to process the sequence of data more efficiently. It will make us access one element at a time so we can focus on what to do with the data rather than how to get individual data

2. What is Iterator and Iterable?

An object that implements the iterable protocol is called ITERABLE and an object that implements the iterator protocol is called ITERATOR

An iterable is a data structure that wants to make its elements accessible to the public (we can loop through elements easily)

An iterator is an object that knows how to access elements from iterable one at a time keeping track of the current position in the sequence.

JS in ES6 decided to implement iterable to built-in data structures like - string, array, map, set. This means there is a way to access elements from these one at a time.

Now ES6 thought about iterators. They can't modify the existing for, while and do-while to improve the iterators because every existing code containing these loops must be modified.

for-of loop for different data structures implementing iterable

Iterable protocol - Technical details

  • This protocol decides if an object is iterable

  • For an object to be iterable, it should implement a method called [Symbol.iterator] at the key

  • This method should not accept any argument and should return an object that conforms/complies with the rules of iterator protocol. Note: Symbo.iterator guarantees a unique value for the key of the iterable object

Iterator protocol - Technical details

  • This protocol decides if an object is an iterator or not

  • An object is an iterator when it satisfies the following rule. The object must have a

    method called next() and this method must return two properties

    • value - which gives the current value

    • done - which is a boolean to indicate if there are any more elements remaining to iterate upon

  • Each time when next() is called, it returns the next value in the collection.

{value : 'next val' , done: 'false' } // it has more values

{value : 'undefined' , done: 'true' } // it has no more values

3. Implementing our own Iterable and Iterator.

As I said, the map, set, string, and array all are iterable as they implement,[Symbol.iterator] at the key. But the object is not a builtin iterable as it doesn't implement [Symbol.iterator]

array and string are iterable
objects are not iterable

Implementing Iterable protocol to an object
Implementing iterator protocol but not yet returning the object containing value and done
Returning the value from iterator function
When for of is called, iterator is returned as the Symbo.iterator is called. This gives access to next()
Using next() directly on object that implements iterator protocol

Summary

  1. JS didn't have a better iteration protocol so Iterator and Iterable was introduced

  2. Accessing the data is always the first part before using it and it wasn't uniform among various Data Structures and was confusing

  3. Then iterable and iterator protocols were introduced in ES6

  4. Data Structures like String, Map, Array, etc. implemented them so that the data could be iterated using for of loop and other operators like spread

  5. A data structure becomes iterable when it implements, [Symbol.iterator] as a key and have a method assigned to it

  6. This method doesn't take any argument but returns an object that complies with the iterator protocol

  7. Iterator protocol dictates that the object should implement a key called next and have a method assigned to it

  8. This method should return an object having {value, done} that indicates the next value and if that exists or not

  9. After implementing iterable and iterator protocols like told above, we can now use for of loop to iterate over this data structure

  10. The spread syntax, promise.all, for of loop all implement these 2 protocols

Challenges

  1. Make an object iterable and use for of loop and spread to print 1 to 50

const range = {
    [Symbol.iterator]: function() {

        let counter = 1;

        const iterator = {

            next: function() {
                const keyValPair = {
                    value: counter,
                    done: false
                };
                if (counter <= 50) {
                    counter++;
                    return keyValPair

                }
                return {
                    done: true
                }
            }
        };
        return iterator
    }
};

// for of loop. Logs 1 to 50
for (let ele of range) {
    console.log(ele)
}

// spread operator. Logs 1 to 50
console.log([...range])

// Iterator is returned and when called next() on it, it logs the {value,done}
const iterator = range[Symbol.iterator]()
console.log(iterator.next())

2. Customize the above behavior by giving a start value, interval, and end value functionality

const customRange = {
	[Symbol.iterator]: function (start = 1, interval = 2, end = 20) {
		let counter = start;

		const iterator = {
			next: function () {
				const keyValPair = {
					value: counter,
					done: false
				};
				if (counter <= end) {
					counter = counter + interval;
					return keyValPair;
				}
				return {
					done: true
				};
			}
		};
		return iterator;
	}
};

// for of loop. Logs 1 to 50
for (let ele of customRange) {
	console.log(ele);
}

// spread operator. Logs 1 to 50
console.log([...customRange]);

// Iterator is returned and when called next() on it, it logs the {value,done}
const iterator = customRange[Symbol.iterator]();
console.log(iterator.next()); // {value: 1, done : false}
console.log(iterator.next()); // {value: 3, done : false}
console.log(iterator.next()); // {value: 5, done : false}

// using a while loop to iterate the iterator
while (!iterator.next().done) {
	console.log(iterator.next().value); // logs 1 to 19
}

In the iterator method, we not only can have the method, next() but also has can define a return() method. This method is called when the iteration is stopped prematurely.

return() inside iterator is called when it is stopped prematurely

2. Generators - ES6

Creating Iterators ourselves involves implementing, [Symbol.itertor],next() function, and so on. It's a bit verbose to create the iterator functions ourselves.

Generators are the special class functions that simplify the task of writing iterators.

// creating a generator function

function* generatorFunction(){
  yield 'Hello'
  yield 'World'
}

const generatorObject = generatorFunction() // generatorObject is an iterator

// this object can now be used to iterate
for (const word of generatorObject){
  console.log(word)
} 

// it also contains next method
generatorObject.next() - Returns {value:'Hello', done:false}
generatorObject.next() - Returns {value:'World', done:false}
generatorObject.next() - Returns {value:undefined, done:true}

Normal Function

Generator Function

It's a run-to-completion model

It is a stoppable model

It can't be stopped until it hits the end of the block

It can stop the midway and continue from where had stopped

The only way to exit the function is by return statement or by throwing and error

It can pause its execution

On calling the function again, it will execute it from the top

We use the "yield" keyword to achieve that behavior.

returns a value

returns an object known as 'generator object'. This object is an iterator.

Since this returned object is an iterator, we can iterate over that object using for-of loop, array destructuring

Advantages of using generators over defining our own iterators (4 points to remember)

More on generators

  • In generators, we can usereturn. However, return sets done to true after which generator cannot generate any more values

  • If you return a value rather than yield the value, the returned value will not iterate over for loop or spread syntax

  • The Generator function cannot rerun after it has yielded values or returned. We will have to make another generator object to run the generator again.

Summary

  • Generators were introduced in ES6 and allow execution which is not continuous. This allows you to implement iterative behaviour.

  • Generator functions are written using function* syntax

  • When called, they return a special object called generator object

  • Generator object's value can be consumed by calling next() method on it and it runs until it encounters the yield keyword

3. What is Web Worker?

JS Web Worker

4. What are service workers? Service workers vs web workers.

Worklets are hooks into the browser’s rendering pipeline, enabling us to have low-level access to the browser’s rendering processes such as styling and layout.

Service workers are a proxy between the browser and the network. By intercepting requests made by the document, service workers can redirect requests to a cache, enabling offline access.

Web workers are general-purpose scripts that enable us to offload processor-intensive work from the main thread.

Drawbacks of Service Workers

  • It has to have SSL certificate (it has to run over https and not http except local host)

  • It cannot be used in old version of browsers like IE

5. What Happens When You Type in a URL?

This is how I would explain it:

  1. You enter a URL into a web browser

  2. The browser looks up the IP address for the domain name via DNS

  3. The browser sends a HTTP request to the server

  4. The server sends back a HTTP response

  5. The browser begins rendering the HTML

  6. The browser sends requests for additional objects embedded in HTML (images, css, JavaScript) and repeats steps 3-5.

  7. Once the page is loaded, the browser sends further async requests as needed.

CSS

1. CSS Selectors

Basic Selectors

We have 5 types of basic selectors

  1. Universal Selector

  2. Type Selector

  3. Class Selector

  4. ID Selector

  5. Attribute Selector

Basic CSS Selectors

Advance/Complex Selectors

We have 5 types of complex selectors

  1. Selector List

  2. Descendent Combinator

  3. Child Combinator

  4. General Sibling Combinator

  5. Immediate Sibling Combinator

complex selectors
complex selectors

Pseudo Selectors

  1. Pseudo Classes (:)

  2. Pseudo Elements (::)

pseudo selectors

2. CSS Specificity

Sometimes, the style we apply doesn't work but still gets some kind of style which we specified in another file or inline style. Basically, two or more styles defined on an element can lead to confusion and provokes us to think about which one might get applied. This is where we need to know CSS specificity.

Specificity is a weight that is applied to given CSS declaration. Let's visualize the specificity as a 4 digit no.

CSS Specificity

3. CSS Box Modal

Content-Box Vs Border-Box

4. CSS Positions

There are 5 positions

  1. Static position (Default position) - This represents elements exactly the way you put in HTML markup. You can use width, height, margin, padding, and so on, but you can't use top, left, bottom, right props. It doesn't add any effect.

  2. Relative position - This also represents the way you put in HTML markup but you can position this element relative to other elements unlike static and can use top, left, right, and bottom to do that.

  3. Fixed position - The position is fixed at that particular place and doesn't move even on the scroll. It doesn't occupy any space, so the elements might be hidden behind it.

  4. Sticky position - The position is static until it is scrolled. When its position hits the bottom of the screen during the scroll then it becomes fixed. Unlike fixed, it occupies some space so the elements will not be hidden behind it.

  5. Absolute position - An element with position: absolute; is positioned relative to the nearest positioned ancestor (instead of positioned relative to the viewport, like fixed).

    However; if an absolute positioned element has no positioned ancestors, it uses the document body, and moves along with page scrolling.

    Note: A "positioned" element is one whose position is anything except static.

Last updated

Was this helpful?