Accreditation Bodies
Accreditation Bodies
Accreditation Bodies
Supercharge your career with our Multi-Cloud Engineer Bootcamp
KNOW MOREAn interview for the role of developer always includes coding questions. No matter the programming language you learn, it's always expected of you to be familiar with the fundamentals of programming. If you are looking for coding interview questions, this article covers the basic programming questions and advanced coding questions required for cracking the coding interview. The basic coding questions cover the coding questions for placement and the coding questions asked in interviews.
Filter By
Clear all
In computer systems, a data structure is a method that helps to store and efficiently retrieve data. Data can take many different forms, and to store and retrieve it effectively, we must have a solid grasp of data structures. Data structures come in a variety of formats, and we must choose the best one for the task at hand. For instance, you would utilise the appropriate data structure type if you needed to store data that was ordered or unordered, had a fixed length or variable length, or both. Some of the most common data structures used by programmers are:
Programmers are responsible for solving logical problems through critical thinking. They are not required to know any programming language or syntax. Their responsibility is to prepare the algorithm or even the pseudo-code. On the other hand, coders are responsible to write the logic or algorithm in a specific programming language. They can understand the syntaxes, optimize the code, debug and run test cases, and use different libraries and modules. You can consider that defining an algorithm for a data structure is the task of a programmer while implementing the data structure in a specific programming language like Java, C++, Python, etc. is the task of the coder. It is generally preferred that a coder should be a good programmer.
Arrays are the simplest data structures. Almost all the programming languages have an in-built implementation of an array (it might come with slight modification). An array can be understood as a box of cookies placed in a single row one after the other. Each cookie is an element or item. Each cookie in the box is next to the other just like elements in an array. Each cookie can be identified with a unique location and so the items are in an array. However, the position of the items in an array starts with index 0 followed by 1, 2, 3, and so on. The size of the array is fixed just like the cookie box. You cannot add more cookies once the box is full. Therefore, arrays have static memory allocation but however one can also implement a dynamic array as per the usage. A cookie box will only contain cookies and not cake or another item. Similarly, an array contains a single data type i.e., it is homogeneous. However, we can also have heterogeneous array types as well. For example, python lists mimic an array data structure but come with variable length and the ability to store a variety of data types making it heterogeneous. The below image demonstrates an array of lengths equal to 10 and therefore, the index position ranges from 0 to 9.
LIFO stands for Last In First Out. The idea follows from the stack of items. For example, a stack of books is placed on a table. Considering you want to add a new book to the stack, the ideal way will be to place the book on top of the stack. Now, to access the stack you have to first remove the top-most book which is nothing but the most recent addition to the stack. Hence, the stack follows the last in first out order. Stack is a widely used data structure that provides a way of accessing, storing and retrieving data.
The FIFO or First In First Out order comes from the idea of queues. A queue of people standing in line means that the person at the start of the line will be the first one to leave the queue. There are a lot of real-life examples of queues like the queue during the security check in an airport. Similarly, in a queue data structure, the data that is stored first is retrieved first. This is in contrast to a stack where the first item is the last to leave the stack during retrieval.
An algorithm is a set of steps taken to accomplish a task. For example, if you are preparing vegetable soup, you will follow certain steps to ensure your food is prepared just right. You might first chop vegetables, then heat oil in a pot, followed by placing all the vegetables in the pot and frying it, then finally adding some water and waiting for some time. So here we performed a series of tasks to arrive at an outcome, Similarly, in computer science, learning about different types of algorithms and knowing when to apply them allows us to write time and memory-efficient programs. For example, Google maps use an algorithm to find the fastest path to reach the destination, compression software uses certain algorithms to reduce the memory consumption of files, and logistics and supply chain solutions use optimization algorithms to efficiently manage the movement of their goods. There is no best algorithm. Each of these algorithms is designed keeping specific use cases in mind and therefore, one must be aware of when to use them.
Recursion is a process in which a solution (implemented in the form of a function) calls itself recursively to solve sub-parts of the same problem. Therefore, the function is calling itself recursively to arrive at the final solution. One point to be noted here is that one needs to provide a condition to terminate the recursion cycle. Using recursion results in a reduced length of the code since we are using the same code recursively. Algorithms like DFS of Graph, Towers of Hanoi (TOH), etc., use recursion for their implementation. The prime example of a recursion problem is the factorial of a number. During the calculation of the factorial of a number, we call the same function recursively with an input number lesser than the previous one so that eventually we multiply all the natural numbers lesser than the provided number. The program terminates when the number is equal to 1 or 0.
Linear data structures are the ones which follow a sequential structure. Each element in a sequence is attached to the previous and (or) next element forming a linear structure. It follows a single-level hierarchy and therefore, we can iterate through each of the elements in a single loop. Also, the elements are sequentially organized in the computer memory. Some examples of a linear data structure are arrays, linked lists, stacks, queues, etc.
Unlike linear data structures, non-linear data structures follow a multi-level hierarchical structure. Since more than one level is involved, traversing through them requires more than one run or loop. Due to this complexity, they are difficult to implement in comparison to linear data structures. However, they are known to utilize computer memory efficiently compared to their linear counterparts. Some examples of non-linear data structures are binary trees, graphs, etc.
IDE or Integrated Development Environment provides a software or application development environment. There are tons of IDE available on the internet with each of them providing its own set of features. IDE is meant to provide a fluid UI, an effortless coding environment for one or more programming languages, and other third-party add-ons like themes, tools, etc. According to Google trends, Visual Studio Code and Visual Studio (popular for Visual Basic) are the most searched IDE on the internet. Visual Studio Code has increasing popularity due to its user-friendly UI, faster loading, git integration, rich marketplace, and freeware, and is backed by Microsoft. However, IDEs like PyCharm, and Eclipse help to effortlessly work on a particular programming language or framework due to their intelligence engine which can identify errors and also provide suggestions in real-time. However, one can also use online compiler for any quick check of their code.
A binary tree data structure is a non-linear tree-like structure observed in a tree data structure. While tree data structure has no restrictions on the number of child nodes, binary tree data structures have only 2 child nodes. Therefore, each node has a value and reference to its right and left child nodes. It is suitable for tasks like searching and sorting. It is easier to traverse in a binary tree structure as compared to other tree structures.
The pseudocode to find the missing number in an array that contains the first ‘n’ integers are –
In a python programming language, the same can be implemented as –
# Initialize the array arr = [1, 2, 3, 4, 5, 6, 7, 9, 10] # Compute the sum of first n natural numbers n = len(arr) + 1 sum_n = n * (n + 1) / 2 # Compute the sum of the integers in the array sum_arr = 0 for num in arr: sum_arr += num # Subtract sum_arr from sum_n missing_num = sum_n – sum_arr missing_num = int(missing_num) print(‘The missing number is’, missing_num)
The output of the above program will be “The missing number is 8”.
The pseudocode to reverse a string is –
In a python programming language, the same can be implemented as –
# Initialize the input string input_string = “Hello World” # Initialize an empty string output_string = “” # Loop through the input string for char in input_string: output_string = char + output_string print(output_string)
The output of the above program will be “dlroW olleH”.
The pseudocode to find the largest element in an integer array is –
In a python programming language, the same can be implemented as –
# Initialize the input array arr = [56, 63, 84, 90, 15, 38, 22, 5, 71, 49] # Assign a random element as the largest number largest_element = arr[0] # Loop through each element in the array for ele in arr: # Check if the element is greater than the assigned largest if ele > largest_element: # Re-assign the largest to the current element largest_element = ele print(‘Largest element:’, largest_element)
The output of the above program will be ‘Largest element: 90’.
A palindrome string reads the same when reversed. For example, ‘radar’ is a palindrome string which reads as ‘radar’ even when reversed. The word ‘rider’ is not a palindrome string since it does not read the same when reversed (‘redir’). While implementing a palindrome string, we will check the first character with the last one if they are the same, followed by the second character and second last character, and so on until we reach the centre of the string. The equivalent code for this can be implemented in python as –
# Initialize the input string input_string = “radar” input_string = input_string.lower() str_length = len(input_string) # Assign a palindrome flag to True palindrome_flag = True for idx in range(0, int(str_length / 2)): if input_string[idx] != input_string[str_length – idx - 1]: palindrome_flag = False break if palindrome_flag: print(f‘{input_string} is a palindrome string’) else: print(f‘{input_string} is not a palindrome string’)
The output of the above program will be “radar is a palindrome string”.
There are 5 alphabets representing vowels while the rest of the alphabets among the 26-letter alphabets are called consonants. We will iterate through each character in the input string. A counter needs to be initialized which will increment every time it iterates through a vowel. This will give us the count of the number of vowels in a string. The count of number of consonants can be derived from the vowel count and the length of the string. This can be implemented in python as –
input_string = 'assembly language' input_string = input_string.lower() vowel_list = ['a', 'e', 'i', 'o', 'u'] str_length = len(input_string) vowel_count = 0 for idx in range(0, str_length): if input_string[idx] in vowel_list: vowel_count += 1 print(f'There are {vowel_count} vowels and {str_length - vowel_count} consonants in the string')
The output of the above program will be “There are 6 vowels and 11 consonants in the string”.
A queue is a linear data structure that is based on the FIFO (First In First Out) order. Enqueue and dequeue are two of the basic operations that can be performed on a queue along with another set of operations. An enqueue operation will insert a new element at the end of the queue while a dequeue operation removes (pops) and returns the element that has occupied the start (front) of the queue.
A linked list is a linear data structure that consists of nodes in sequence to store a collection of data elements dynamically. Each node contains a value and a reference pointer (link) to the next node. Unlike arrays, linked lists are not stored in contiguous memory locations. Therefore, these reference pointers are required to direct to the next node value. The size of a linked list can grow and shrink dynamically, thus, avoiding any wastage of memory space. The reference pointer of the last node in the sequence is null since it does not point to any further node in the sequence.
To find the number of occurrences of a character in a given string, we will iterate through the string and create a counter for the character. Whenever the iteration results in a match with the character, we will increment this counter by 1. This can be implemented in python as –
input_string = “coding interview preparation” input_string = input_string.lower() character = ‘i’ str_length = len(input_string) char_count = 0 for idx in range(0, str_length): if input_string[idx] == character: char_count += 1 print(f‘There are {char_count} occurrences of {character} in the input string’)
The output of the above program will be “There are 4 occurrences of i in the input string”.
Reversing an array through swapping requires the interchange of the values of two different locations (placed symmetrically) in an array with the help of a temp variable. The pseudocode can be written as –
This can be implemented in python as –
input_arr = [1, 2, 3, 4, 5] arr_length = len(input_arr) start = 0 end = arr_length - 1 while start < end: temp = input_arr[start] input_arr[start] = input_arr[end] input_arr[end] = temp start += 1 end -= 1 print(‘Reversed Array:’, input_arr)
The output of the above python program is “Reversed Array: [5, 4, 3, 2, 1]”
A library is a set of pre-defined functions that can be used to achieve a task. The tasks that otherwise would require writing multiple lines of code can be accomplished with just a fraction of code lines. For example, the python Pandas library is capable of performing a lot of operations on tabular data like CSV, such as ordering, grouping, sorting, imputing values, deleting records, performing complex calculations, creating charts and graphs, etc. There are also libraries which can perform tasks like rgb to hex code conversion, qrcode creation, convert binary code to ascii code, etc. If we tried implementing these operations without using the library, it will multiply the implementation time by a big number and most importantly it is not required. We can save this time and focus on the specific logic designed for the application. Therefore, to perform the common operations with fewer lines of code and avoid unnecessary development time, we can prefer using available libraries.
A framework can be considered a superset of libraries. In computer programming, a framework is a basic structure based on a concept that helps to build software quickly and efficiently. It consists of pre-defined functions, methods, classes, and variables that can be utilized to build the application. A framework serves a specific purpose for development. For example, Django and Flask are Python frameworks that help to build server-side applications while React JS and Angular are JavaScript frameworks that help with frontend application development.
Numerous high-level programming languages are based on interpreters, compilers, or a combination of the two. The work of translating machine code from high-level language to low-level language is carried out by both the compiler and the interpreter, but they approach it in different ways. The complete high-level program is translated at once by the compiler from high-level language to machine code. Due to this, there may be some translation time, but the execution follows quickly. Unfortunately, the program will not function if there is a bug in it. On the other hand, the interpreter will translate each command in the high-level language code before executing it on its own. In this case, the translation is quick but the actual execution is slow. The main benefit of interpreters is that output is produced after each instruction and they continue running until an error occurs.
We know that, a number (natural numbers excluding 1) is said to be prime number if it is only divisible by 1 and itself. The pseudocode for the program is –
This can be implemented in python –
# Take input from user num = int(input("Enter a number: ")) # Assign the flag flag = False if num > 1: # Check if the number is divisible # by another number except 2 and itself. for i in range(2, num): if num % i == 0: # Set the flag to True i.e. not prime flag = True # Break the loop break if flag: print(num, "is a prime number") else: print(num, "is not a prime number")
The output of the program is –
Enter a number: 29
29 is not a prime number
The pseudocode for finding the prime factors of an integer –
The python program for the same is –
# Take input from user num = int(input("Enter a number: ")) for i in range(2, int(num**0.5)): while num % i == 0: print(i, end = " ") num //= i print(num)
The output of the program is –
Enter a number: 153
3 3 17
In case of an Armstrong number of 3 digits, the sum of cubes of each digit is equal to the number itself. For example, 153 is an Armstrong number (1 x 1 x 1 + 5 x 5 x 5 + 3 x 3 x 3 = 153). To implement this, we need to iterate every digit and calculate its cube and add it to the resultant. The pseudocode is given as –
The python implementation for the same is –
# Take input from user num = int(input("Enter a number: ")) # Assign the sum to 0 sum_ = 0 # Assign temp as num temp = num while temp > 0: # Get the last digit digit = temp % 10 # Add its cube to the resultant sum_ += digit * digit * digit # Perform integer division by 10 temp //= 10 if num == sum_: print(num,"is an Armstrong number") else: print(num,"is not an Armstrong number")
The output of the program is –
Enter a number: 153
153 is an Armstrong number
A year is a leap year if it is divisible by 400 or divisible by 4 but not by 100 since every 4th century year is a leap year. The pseudocode can be given as –
The python implementation for the same is –
# Take input from user year = int(input("Enter a number: ")) if year % 400 == 0: print(year, 'is a leap year') elif year % 100 != 0 and year % 4 == 0: print(year, 'is a leap year') else: print(year, 'is not a leap year') The output of the program is –
Enter a number: 2100
2100 is not a leap year
The bubble sort is the simplest way of sorting which is sometimes called sinking sort. In a bubble sort, we repeatedly compare each pair of adjacent elements and swap them if they are in the wrong order. We repeat this process until all elements get sorted. Let us use an example to understand this example clearly. Consider the following array.
We will compare the first two elements in the array, i.e., 56 (index 0) and 63 (index 1). If the left element (at a lesser index) is greater than the right element (at a greater index), we will swap the numbers otherwise ignore them. So, in the first comparison between 56 and 63, we ignore them. During the second comparison, we compare 63 (index 1) and 84 (index 2). Again, the element at the lower index, that is, 63 is smaller than the element at the higher index, 84, so we ignore them. During the comparison of 22 (index 2) and 84 (index 3), we notice that the element at index 2 is greater than the element at index 3 so we swap the two numbers. The below image represents the complete first iteration during the bubble sorting of the above array. The coloured elements are the ones which are taken into consideration during the comparison. The elements coloured in light blue represent that the items are not swapped after comparison. The elements coloured in orange represent that the element was swapped after comparison. Finally, we get an array in which the last item (84 coloured in red) is frozen and it won’t be considered for any further sorting operation.Now, during the second set of iterations, the second highest number will get sorted. During each successive iteration, it will not consider the frozen elements from previous iterations. The further iterations for the sorting are –
The pseudocode to implement a bubble sort algorithm is –
input_arr = [56, 63, 84, 22, 71, 49] arr_length = len(input_arr) for i in range(0, arr_length – 1): for j in range(0, arr_length – i – 1): if input_arr[j] > input_arr[j+1]: temp = input_arr[j] input_arr[j] = input_arr[j+1] input_arr[j+1] = temp print(‘Sorted Array:’, input_arr)
The output of the above program is “Sorted Array: [22, 49, 56, 63, 71, 84]”.
A stack data structure can be imagined as a pile of objects stacked vertically. When we make an addition to the stack, it is added to the top and while accessing the stack, the last added object to the stack is the first to be accessed. The common stack operations are:
The stack can be implemented in python using the code –
class Stack: # Initialize the stack with the provided length def __init__(self, length): self.stack = [] self.length = length self.__size = 0 def size(self): ''' Returns the current size of the stack ''' return self.__size def isEmpty(self): ''' Returns True if the stack is empty, else False ''' return self.__size == 0 def isFull(self): ''' Returns True if the stack is full, else False ''' return self.length == self.__size def push(self, element): ''' Adds a new element to the stack if there is a space. ''' if not self.isFull(): self.stack.append(element) self.__size += 1 print(f'Successfully added {element} to the stack.') else: print('Stack is full. New element cannot be added to the stack.') def pop(self): ''' Removes and returns the value of an element present at top of the stack, if the stack is not empty. ''' if not self.isEmpty(): element = self.stack.pop(-1) self.__size -= 1 print('Successfully removed element from top of the stack.') return element print('Stack is empty. Nothing to pop from the stack.') def peek(self): ''' Returns the value of the element present at the top of the stack if the stack is not empty. ''' if not self.isEmpty(): return self.stack[-1] print('Stack is empty. Nothing to peek in the stack.') def delete(self): ''' Deletes the stack ''' self.stack = None # Create a new stack with length = 5 s = Stack(length = 5) # Pop item from the stack print(s.pop()) # Check if the stack is empty print(s.isEmpty()) # Peek item from the stack print(s.peek()) # Push 3 items to the stack s.push(30) s.push(40) s.push(55) # Check the size of the stack print(s.size()) # Push two more elements to the stack s.push(60) s.push(85) # Peek in the stack and print the response print(s.peek()) # Add one more item to the stack s.push(100) # Check if the stack is full print(s.isFull()) # Pop an item from the stack print(s.pop())
The output of the program is –
Stack is empty. Nothing to pop from the stack. None True Stack is empty. Nothing to peek in the stack. None Successfully added 30 to the stack. Successfully added 40 to the stack. Successfully added 55 to the stack. 3 Successfully added 60 to the stack. Successfully added 85 to the stack. 85 Stack is full. New element cannot be added to the stack. True Successfully removed element from top of the stack. 85
A queue is a data structure that stores items in a first-in-first-out (FIFO) order just like a queue of persons standing. The common queue operations are:
The queue can be implemented in python using the code –
class Queue:
# Initialize the queue with the provided length def __init__(self, length): self.queue = [] self.length = length self.__size = 0 def size(self): ''' Returns the current size of the queue ''' return self.__size def isEmpty(self): ''' Returns True if the queue is empty, else False ''' return self.__size == 0 def isFull(self): ''' Returns True if the queue is full, else False ''' return self.length == self.__size def enqueue(self, element): ''' Adds a new element to the queue if there is a space. ''' if not self.isFull(): self.queue.append(element) self.__size += 1 print(f'Successfully added {element} to the queue.') else: print('Queue is full. New element cannot be placed in the queue.') def dequeue(self): ''' Removes and returns the value of an element present in the front of the queue, if the queue is not empty. ''' if not self.isEmpty(): element = self.queue.pop(0) self.__size -= 1 print('Successfully removed element from front of the queue.') return element print('Queue is empty. Nothing to dequeue.') def peek(self): ''' Returns the value of the element present in the front of the queue if the queue is not empty. ''' if not self.isEmpty(): return self.queue[0] print('Queue is empty. Nothing to peek in the queue.') def delete(self): ''' Deletes the stack ''' self.queue = None print('Queue deleted successfully.') # Create a new queue with length = 5 q = Queue(length = 5) # dequeue an item from the queue print(q.dequeue()) # Check if the queue is empty print(q.isEmpty()) # Peek item from the front of the queue print(q.peek()) # Enqueue 3 items to the queue q.enqueue(30) q.enqueue(40) q.enqueue(55) # Check the size of the queue print(q.size()) # Enqueue two more elements to the queue q.enqueue(60) q.enqueue(85) # Peek in the front of the queue and print the response print(q.peek()) # Equeue one more item to the queue q.enqueue(100) # Check if the queue is full print(q.isFull()) # Enqueue an item from the queue print(q.dequeue()) # Delete the queue q.delete()
The output of the program is –
Queue is empty. Nothing to dequeue. None True Queue is empty. Nothing to peek in the queue. None Successfully added 30 to the queue. Successfully added 40 to the queue. Successfully added 55 to the queue. 3 Successfully added 60 to the queue. Successfully added 85 to the queue. 30 Queue is full. New element cannot be placed in the queue. True Successfully removed element from front of the queue. 30 Queue deleted successfully.
An anagram is a word or phrase that is created by rearranging the letters of another word or phrase, usually utilizing every letter exactly once. Examples include rearranging the words care to become race, binary to become brainy, and heart to become earth. To prove whether two strings are anagrams or not, we can perform sorting on both strings and if the sorted strings match each other then we can consider the strings to be anagrams of each other. The pseudocode can be given as –
The python program for this is given as –
string_1 = 'care' string_2 = 'race' len_str1 = len(string_1) len_str2 = len(string_2) anagram_flag = True if len_str1 != len_str2: anagram_flag = False else: string_1 = ''.join(sorted(string_1)) string_2 = ''.join(sorted(string_2)) for idx in range(0, len_str1): if string_1[idx] != string_2[idx]: anagram_flag = False if anagram_flag: print('The strings are anagrams') else: print('The strings are not anagrams')
In the case of the insertion sort algorithm, we divide the array into two parts: sorted array and unsorted array. Then from the unsorted array, we pick the first element and find its correct position in the sorted array. We repeat the process until there are no items left in the unsorted part of the array. The pseudocode for the insertion sort algorithm is –
The python program for the insertion sort is –
arr = [56, 63, 84, 90, 15, 38, 22, 5, 71, 49] arr_length = len(arr) for i in range(1, arr_length): key = arr[i] j = i - 1 while key < arr[j] and j >= 0: arr[j+1] = arr[j] j -= 1 arr[j+1] = key print('Sorted array:', arr)
The output of the program is “Sorted array: [5, 15, 22, 38, 49, 56, 63, 71, 84, 90]”.
OOP stands for Object Oriented Programming. It is a way of writing code which involves classes, methods, attributes, and objects instead of traditional functions. Large, sophisticated, and actively updated or maintained programs are best fit for this method of development. The use of objects allows the creation of multiple unique instances of a class and the reuse of the methods and attributes of the class, thereby, improving code efficiency, reusability, and readability. The building blocks of OOP are –
The main concepts of OOP include –
Method overriding is an example of runtime polymorphism. Method overriding is implemented during inheritance that involves declaring the same method in the child class which can be found in the parent class. By doing this, we can use the method of the child class instead of the parent class whenever the object of the child class calls the method. Let us understand this with the help of an example.
class Parent: def foo(self): print(‘Parent foo called’) class Child1(Parent): def foo(self): print(‘Child1 foo called’) class Child2(Parent): pass c1 = Child1() c1.foo() c2 = Child2() c2.foo()
In the code, we have implemented three classes – one parent class and two child classes. In the parent class, we have a method named ‘foo’. Both the child classes – Child1 and Child2 inherit from the parent class. The Child1 class has its implementation of the ‘foo’ method. The Child2 class does not have its own ‘foo’ method. After we run the program, we will see that if the child class has its implementation of the parent class methods, then it will override it. Therefore, calling the ‘foo’ method using the Child1 class object will result in overriding the parent class method and calling the ‘foo’ method using the Child2 class object will call the parent class ‘foo’ method since it has not overridden the method. The output of the program is –
Child1 foo called Parent foo called
A thread is a lightweight process that is responsible to run a single sequential program. A sequential program has a beginning, a sequence, and an end. For example, consider a sorting program which has a beginning, an execution sequence, and an end which indicates that the sorting is complete. A thread runs within a program and shares its resources for execution. However, most applications like to take advantage of the multithreading architecture which is capable of running multiple threads at the same time and performing different tasks in the same program. For example, when you are working with MS Word, you can see the highlights which lets you quickly look at your typing errors. It can even run 3rd party add-ons that can help you with other tasks such as identifying grammatical mistakes, inserting pictures, etc. While working with resource-intensive applications, it is recommended to use the concepts of multi-threading to take advantage of the resources, thereby, allowing your application to run smoothly. However, multi-threading is a diverse topic and a tricky one to implement, therefore, one needs to consider using the right set of available libraries to implement it.
Time complexity refers to the time taken by a program to complete its execution. It is measured using the Big O notation. Big O notation is a language and a metric that is used to describe the efficiency of algorithms. Without understanding Big O notations, it is not possible to create efficient algorithms. If we don’t know when our algorithm gets faster or slower, we’ll struggle to judge our program performance. This concept gives us one way of describing how the time it takes to execute our program grows as the size of input grows. For example, a sorting algorithm might be quicker to sort a smaller array but as the size of the array increases, the time taken to sort the array using the same algorithm might increase drastically. In such cases, other sorting algorithms might turn out to be useful.
Time is not the only thing that matters in an algorithm. We might also care about the amount of memory or the space that is being consumed by the algorithm or the program. It is a parallel concept to time complexity. Space complexity is the measure of the amount of working storage that a program needs. As with time complexity, here we are concerned with how the space that is needed grows as the size of the input grows. For example, a smaller array will consume a lesser space than compared to a larger array. If you are using too many variables to store intermediate computations in your program then you might end up consuming more space.
Fibonacci sequence is the sequence of whole numbers 0,1, 1, 2, 3, 5, 8, ... which starts with 0 and 1, and where every number thereafter is equal to the sum of the previous two numbers.
The pseudocode for the program is –
The python implementation for the same is –
def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2) print('Fibonacci for n=8 is', fib(8))
The output of the program is “Fibonacci for n=8 is 21”.
Inheritance is a way to form new classes using classes that have already been defined. Important benefits of inheritance are the ability to reuse code and make the program more readable. To further understand inheritance consider the following example:
class Vehicle:
def __init__(self, mileage, no_of_wheels): self.mileage = mileage self.no_of_wheels = no_of_wheels def apply_brakes(self): print('Brakes applied.') def press_horn(self): print('Honkingggg!!!!!')
class Bike(Vehicle):
def __init__(self, mileage): super().__init__(mileage, no_of_wheels = 2) # Creating an instance of a Bike class bike_obj = Bike(mileage = 60) # Accessing attributes instantiated in Parent class print('Mileage:', bike_obj.mileage) print('No of wheels:', bike_obj.no_of_wheels) # Accessing methods instantiated in Parent class bike_obj.apply_brakes() bike_obj.press_horn()
The output of the program is –
Mileage: 60 No of wheels: 2 Brakes applied. Honkingggg!!!!!
In the python code, we have created a parent class, Vehicle, and a child class, Bike (inheriting from the parent class). The parent class, Vehicle, has two attributes, namely, ‘mileage’ and ‘no_of_wheels’. It also has two methods, namely, ‘apply_brakes()’ and ‘press_horn()’. In the child class, Bike, there are no attributes or methods defined but since we are inheriting the parent class, we can use all the methods and attributes of the parent class. We have created the attribute of the child class and accessed the above-mentioned attributes and methods as seen in the output.
A regular expression, or simply regex, allows us to look for general patterns in text data. For example, if we are looking for an email or phone number in a large document then we can define the pattern and extract all the available emails and phone numbers present in the document using regex. Regular expressions have a standardized set of rules for defining the pattern irrespective of the programming language. They are used widely and are an extremely powerful way to work with text data. Using some of these rules, we can define the phone pattern in regular expression as –
^[6-9]\d{9}$
The ‘^’ marks at the beginning should be with the characters present in the square bracket where 6-9 means any number out of 6, 7, 8, and 9. These four numbers should be present in just one. Following this ‘\d’ means any digit and ‘{9}’ means repeated exactly 9 times. Therefore, the complete pattern describes that the matching string should start with a number 6, 7, 8, or 9 followed by 9 other digits, totalling 10 digits of a phone number.
Tree data structures are a form of non-linear data structure. With an increase in the number of data points, linear data structures are found to be more time-consuming. To avoid this time complexity, tree data structures can play a role. These are tree-like structures formed using nodes, roots, and edges. Since it is a non-linear data structure type, it has a multi-level hierarchy as shown below –
In essence, a binary search tree is just a binary tree with extra features. The first characteristic is that the value of the node in the left subtree is lower than or equal to the value of its parent node. The value of the node in the right subtree exceeds the value of its parent node. Here is an illustration of a binary tree.
The root node of the example binary tree is node 56. For the first property, we stated that the value of the node in the left subtree is less than or equal to the root node. You can see that in this instance, 49 is less than 56. Now, we should have a node in the right subtree that is higher than the value of the root node. You can see that 63 is greater than 56 in this situation. We can observe that this attribute follows the same pattern down to the leaf node if we continue to assess it farther into the tree.
There is no index of the data elements stored in the binary search tree. As a substitute, it uses an implicit structure to keep track of each element's location. The addition and deletion of nodes may be accomplished fast due to this structure. In contrast to how we operate with arrays, where we must progressively tour each element until the correct one is located, in this case, we only need to walk the half tree. Next, we go on to the other tree's half. This produces the desired effect considerably more quickly than a straight loop would. Because a binary search tree is quicker than a binary tree, we could need one while sorting data.
The binary search algorithm searches the required element in the array by dividing the array into two parts. The algorithm can only be applied to an array which is already sorted. It can be implemented using two different approaches, namely, the iterative method and the recursive method. The underlying algorithm remains the same in both methods which work on the principle of ‘divide and conquer’. The iterative method has a complexity of O(1) whereas the recursive method has a complexity of O(log n) which makes the iterative method more efficient.
The pseudocode for implementing a binary search algorithm is –
The python implementation for the same is –
# Initialize the array arr = [5, 15, 22, 38, 49, 56, 63, 71, 84, 90] # Define the search element x = 22 # Calculate the length of the array arr_length = len(arr) # Assign start and end index positions start = 0 end = arr_length - 1 while start <= end: # Compute the middle index position mid = start + (end - start)//2 # Check if the element is in the middle position # Else reassign new start and end index positions if arr[mid] == x: idx = mid break elif arr[mid] < x: start = mid + 1 else: end = mid - 1 print(f"Index position for element {x} is", idx)
The output of the program is “Index position for element 22 is 2”.
The flowchart to find the smallest number in an integer array can be given as –
The python implementation for the same is –
# Initialize the array arr = [56, 63, 84, 90, 15, 38, 22, 5, 71, 49] # Calculate the length of the array N = len(arr) i = 0 # Assign the random smallest number at the start of the index position result = arr[0] while i < N: # Check if the current element is smaller than the result if arr[i] < result: result = arr[i] # Increment the current index position i += 1 print("Smallest element in the array is", result)
The output of the program is “Smallest element in the array is 5”.
The flowchart to find the missing number in an integer array can be given as –
# Initialize the array arr = [1, 1, 2, 2, 4, 5, 8, 9] # Sort the array arr.sort() # Calculate the length of the array N = len(arr) # Initialize a new array with length N and 0 elements narr = [0]*N # Mark the indexes as 1 if the item is present for i in range(0, N): if i + 1 in arr: narr[i] = 1 print('The missing elements are:') # Print the indexes where the element is still 0 for i in range(0, N): if narr[i] == 0: print(i + 1)
The output of the program is –
The missing elements are: 3 6 7
Multiplication of two matrices is only possible if the number of columns of the first matrix matches the number of rows of the second matrix. That means we can multiply the i x j matrix with j x k. The pseudocode for multiplying two matrices is given as (assuming we are multiplying i x j matrix with j x k) –
The implementation in python language for the same is –
# Initialize matrix A A = [ [22, 18, 5], [9, 15, 31], [12, 14, 25], ] # Initialize matrix B B = [ [16, 8], [3, 0], [9, 11], ] # Initialize i, j, k i = len(A) j = len(A[0]) k = len(B[0]) # Initialize resultant matrix result = [[0,0], [0,0], [0,0]] for x in range(0, i): for y in range(0, k): for z in range(0, j): result[x][y] += A[x][z] * B[z][y] for row in result: print(row)
The output of the program is –
[451, 231] [468, 413] [459, 371]
To swap two integer variables, we can use the addition (+) and subtraction (-) operators between the variables. Consider the two integer variables are x and y then we can swap them using –
x = x + y y = x – y x = x - y
In this case, we first added the two integers x and y, and then stored them in x. We then assign x – y to y but x here is equal to x + y which means that we are assigning y = x – y = (x + y) – y = x. Next, we assign x as x – y where we are performing x = x – y = (x + y) – (x) = y. Therefore, by using some mathematical calculations we can swap two integer variables without using a temporary variable.
The merge sort algorithm is a ‘divide and conquer’ algorithm. In the "divide and conquer algorithm," a large problem is divided into smaller chunks, and when those chunks are so small that more division is impossible, we start merging them to find the solution. The input array is split in half and then repeatedly halved until no further division is possible. We begin merging them with sort order once the halving is complete. Finally, we reach the final answer in which we sort all elements. For example, let us consider the array [56, 63, 84, 90, 15, 38, 22, 5, 71, 49]. The split can be performed as –
After splitting the array in half, we divided the two resulting chunks in half once more to create four chunks. We continued splitting these chunks until we ran out of methods to do so. The next step is to merge these chunks (starting from the bottom) which are nothing but arrays consisting of a single item. We'll make sure that each split array is now ordered during merging.The items were placed differently from the prior merge, as indicated by the orange places. Only the components with values 22 and 38 were shuffled during the initial merge. Three of the four arrays underwent shuffling during the second merge. During the third merge, one of the two arrays underwent shuffling. The sorted array is created by the last merge.
Sorting algorithms are divided into two categories based on the space they use and the stability of the algorithms. Based on stability, algorithms can further be classified into stable or unstable.
Stable sorting is the term for a sorting algorithm that does not alter the order in which related pieces of content appear after the content has been sorted. Consider an array with the repeating element "22," where the first instance is stored at memory address "x0001" and the second instance is placed at location "x0002" in the memory. The element "22" will preserve this order in stable sorting, meaning that the first instance of 22 in the sorted array is the one that occupied location "x0001," and the second instance is at position "x0002." In this case, memory is only being taken into account to discriminate between these two items that share the same value.
On the other hand, a sorting algorithm is said to be unstable if, after sorting the content, it changes the order in which related content appears. Therefore, if we use the same array, sorting will place the element "22" at position "x0002" ahead of the similar element at position "x0001" in the sequence.
The algorithms can be classified into –
We need to first check if the lines are parallel or not. If they are parallel then there is no point of intersection. If they are not parallel, we can find their intersection points. The pseudocode for the program is given by –
The implementation in python language for the same is –
# Assign coordinates for line AB and CD A = (-5, -1) B = (3, 3) C = (1, 2) D = (-2, -3) # Generate the line equation for line AB a1 = B[1] - A[1] # y2 - y1 b1 = A[0] - B[0] # x1 - x2 c1 = a1*A[0] + b1*A[1] # Generate the line equation for line CD a2 = D[1] - C[1] # y2 - y1 b2 = C[0] - D[0] # x1 - x2 c2 = a2*C[0] + b2*C[1] # Calculate the determinant det = a1 * b2 - a2 * b1 if det == 0: # Alternatively, check for a1/b1 == a2/b2 print('Lines AB and CD are parallel') else: # Calculate x x = (b2 * c1 - b1 * c2) / det # Calculate y y = (a1 * c2 - a2 * c1) / det print(f'Points AB and CD are intersecting at ({x}, {y})', )
The output of the program is “Points AB and CD are intersecting at (1.0, 2.0)”.
We must comprehend the ideas of backtracking and recursion to put this programme into practice. Recursion plays a crucial role in backtracking. Backtracking is a general algorithm approach that takes into account looking through every potential combination to solve the computing problem and its type of recursion. A backtracking algorithm is a problem-solving algorithm that finds the desired result by applying a brute force method. The brute force method tests every potential solution before selecting the ideal one. But take note that it can often exclude a huge number of candidates with a single test, making it much faster than the brute force enumeration of all complete candidates. Backtracking is done when there are several solutions and we want all of them so we can eliminate several undesirable states in a single iteration.
Enumeration, optimization, and decision problems can all be solved through backtracking.
The implementation of the program to find all permutations of a string is a classic example of backtracking and can be implemented in python as –
# Convert the array to a string def arr_to_str(arr): return ''.join(arr) # Convert string to an array def str_to_arr(string): return list(string) # Function to find all permutations of an array def permute(arr, idx, length): if idx == length: print(arr_to_str(arr)) for i in range(idx, length): # Performing swapping temp = arr[idx] arr[idx] = arr[i] arr[i] = temp # Recursively calling the function permute permute(arr, idx + 1, length) # Performing swapping (Backtracking) temp = arr[idx] arr[idx] = arr[i] arr[i] = temp string = "cat" arr = str_to_arr(string) arr_length = len(arr) permute(arr, idx = 0, length =arr_length)
The output of the program is –
cat cta act atc tac tca
In computer systems, a data structure is a method that helps to store and efficiently retrieve data. Data can take many different forms, and to store and retrieve it effectively, we must have a solid grasp of data structures. Data structures come in a variety of formats, and we must choose the best one for the task at hand. For instance, you would utilise the appropriate data structure type if you needed to store data that was ordered or unordered, had a fixed length or variable length, or both. Some of the most common data structures used by programmers are:
Programmers are responsible for solving logical problems through critical thinking. They are not required to know any programming language or syntax. Their responsibility is to prepare the algorithm or even the pseudo-code. On the other hand, coders are responsible to write the logic or algorithm in a specific programming language. They can understand the syntaxes, optimize the code, debug and run test cases, and use different libraries and modules. You can consider that defining an algorithm for a data structure is the task of a programmer while implementing the data structure in a specific programming language like Java, C++, Python, etc. is the task of the coder. It is generally preferred that a coder should be a good programmer.
Arrays are the simplest data structures. Almost all the programming languages have an in-built implementation of an array (it might come with slight modification). An array can be understood as a box of cookies placed in a single row one after the other. Each cookie is an element or item. Each cookie in the box is next to the other just like elements in an array. Each cookie can be identified with a unique location and so the items are in an array. However, the position of the items in an array starts with index 0 followed by 1, 2, 3, and so on. The size of the array is fixed just like the cookie box. You cannot add more cookies once the box is full. Therefore, arrays have static memory allocation but however one can also implement a dynamic array as per the usage. A cookie box will only contain cookies and not cake or another item. Similarly, an array contains a single data type i.e., it is homogeneous. However, we can also have heterogeneous array types as well. For example, python lists mimic an array data structure but come with variable length and the ability to store a variety of data types making it heterogeneous. The below image demonstrates an array of lengths equal to 10 and therefore, the index position ranges from 0 to 9.
LIFO stands for Last In First Out. The idea follows from the stack of items. For example, a stack of books is placed on a table. Considering you want to add a new book to the stack, the ideal way will be to place the book on top of the stack. Now, to access the stack you have to first remove the top-most book which is nothing but the most recent addition to the stack. Hence, the stack follows the last in first out order. Stack is a widely used data structure that provides a way of accessing, storing and retrieving data.
The FIFO or First In First Out order comes from the idea of queues. A queue of people standing in line means that the person at the start of the line will be the first one to leave the queue. There are a lot of real-life examples of queues like the queue during the security check in an airport. Similarly, in a queue data structure, the data that is stored first is retrieved first. This is in contrast to a stack where the first item is the last to leave the stack during retrieval.
An algorithm is a set of steps taken to accomplish a task. For example, if you are preparing vegetable soup, you will follow certain steps to ensure your food is prepared just right. You might first chop vegetables, then heat oil in a pot, followed by placing all the vegetables in the pot and frying it, then finally adding some water and waiting for some time. So here we performed a series of tasks to arrive at an outcome, Similarly, in computer science, learning about different types of algorithms and knowing when to apply them allows us to write time and memory-efficient programs. For example, Google maps use an algorithm to find the fastest path to reach the destination, compression software uses certain algorithms to reduce the memory consumption of files, and logistics and supply chain solutions use optimization algorithms to efficiently manage the movement of their goods. There is no best algorithm. Each of these algorithms is designed keeping specific use cases in mind and therefore, one must be aware of when to use them.
Recursion is a process in which a solution (implemented in the form of a function) calls itself recursively to solve sub-parts of the same problem. Therefore, the function is calling itself recursively to arrive at the final solution. One point to be noted here is that one needs to provide a condition to terminate the recursion cycle. Using recursion results in a reduced length of the code since we are using the same code recursively. Algorithms like DFS of Graph, Towers of Hanoi (TOH), etc., use recursion for their implementation. The prime example of a recursion problem is the factorial of a number. During the calculation of the factorial of a number, we call the same function recursively with an input number lesser than the previous one so that eventually we multiply all the natural numbers lesser than the provided number. The program terminates when the number is equal to 1 or 0.
Linear data structures are the ones which follow a sequential structure. Each element in a sequence is attached to the previous and (or) next element forming a linear structure. It follows a single-level hierarchy and therefore, we can iterate through each of the elements in a single loop. Also, the elements are sequentially organized in the computer memory. Some examples of a linear data structure are arrays, linked lists, stacks, queues, etc.
Unlike linear data structures, non-linear data structures follow a multi-level hierarchical structure. Since more than one level is involved, traversing through them requires more than one run or loop. Due to this complexity, they are difficult to implement in comparison to linear data structures. However, they are known to utilize computer memory efficiently compared to their linear counterparts. Some examples of non-linear data structures are binary trees, graphs, etc.
IDE or Integrated Development Environment provides a software or application development environment. There are tons of IDE available on the internet with each of them providing its own set of features. IDE is meant to provide a fluid UI, an effortless coding environment for one or more programming languages, and other third-party add-ons like themes, tools, etc. According to Google trends, Visual Studio Code and Visual Studio (popular for Visual Basic) are the most searched IDE on the internet. Visual Studio Code has increasing popularity due to its user-friendly UI, faster loading, git integration, rich marketplace, and freeware, and is backed by Microsoft. However, IDEs like PyCharm, and Eclipse help to effortlessly work on a particular programming language or framework due to their intelligence engine which can identify errors and also provide suggestions in real-time. However, one can also use online compiler for any quick check of their code.
A binary tree data structure is a non-linear tree-like structure observed in a tree data structure. While tree data structure has no restrictions on the number of child nodes, binary tree data structures have only 2 child nodes. Therefore, each node has a value and reference to its right and left child nodes. It is suitable for tasks like searching and sorting. It is easier to traverse in a binary tree structure as compared to other tree structures.
The pseudocode to find the missing number in an array that contains the first ‘n’ integers are –
In a python programming language, the same can be implemented as –
# Initialize the array arr = [1, 2, 3, 4, 5, 6, 7, 9, 10] # Compute the sum of first n natural numbers n = len(arr) + 1 sum_n = n * (n + 1) / 2 # Compute the sum of the integers in the array sum_arr = 0 for num in arr: sum_arr += num # Subtract sum_arr from sum_n missing_num = sum_n – sum_arr missing_num = int(missing_num) print(‘The missing number is’, missing_num)
The output of the above program will be “The missing number is 8”.
The pseudocode to reverse a string is –
In a python programming language, the same can be implemented as –
# Initialize the input string input_string = “Hello World” # Initialize an empty string output_string = “” # Loop through the input string for char in input_string: output_string = char + output_string print(output_string)
The output of the above program will be “dlroW olleH”.
The pseudocode to find the largest element in an integer array is –
In a python programming language, the same can be implemented as –
# Initialize the input array arr = [56, 63, 84, 90, 15, 38, 22, 5, 71, 49] # Assign a random element as the largest number largest_element = arr[0] # Loop through each element in the array for ele in arr: # Check if the element is greater than the assigned largest if ele > largest_element: # Re-assign the largest to the current element largest_element = ele print(‘Largest element:’, largest_element)
The output of the above program will be ‘Largest element: 90’.
A palindrome string reads the same when reversed. For example, ‘radar’ is a palindrome string which reads as ‘radar’ even when reversed. The word ‘rider’ is not a palindrome string since it does not read the same when reversed (‘redir’). While implementing a palindrome string, we will check the first character with the last one if they are the same, followed by the second character and second last character, and so on until we reach the centre of the string. The equivalent code for this can be implemented in python as –
# Initialize the input string input_string = “radar” input_string = input_string.lower() str_length = len(input_string) # Assign a palindrome flag to True palindrome_flag = True for idx in range(0, int(str_length / 2)): if input_string[idx] != input_string[str_length – idx - 1]: palindrome_flag = False break if palindrome_flag: print(f‘{input_string} is a palindrome string’) else: print(f‘{input_string} is not a palindrome string’)
The output of the above program will be “radar is a palindrome string”.
There are 5 alphabets representing vowels while the rest of the alphabets among the 26-letter alphabets are called consonants. We will iterate through each character in the input string. A counter needs to be initialized which will increment every time it iterates through a vowel. This will give us the count of the number of vowels in a string. The count of number of consonants can be derived from the vowel count and the length of the string. This can be implemented in python as –
input_string = 'assembly language' input_string = input_string.lower() vowel_list = ['a', 'e', 'i', 'o', 'u'] str_length = len(input_string) vowel_count = 0 for idx in range(0, str_length): if input_string[idx] in vowel_list: vowel_count += 1 print(f'There are {vowel_count} vowels and {str_length - vowel_count} consonants in the string')
The output of the above program will be “There are 6 vowels and 11 consonants in the string”.
A queue is a linear data structure that is based on the FIFO (First In First Out) order. Enqueue and dequeue are two of the basic operations that can be performed on a queue along with another set of operations. An enqueue operation will insert a new element at the end of the queue while a dequeue operation removes (pops) and returns the element that has occupied the start (front) of the queue.
A linked list is a linear data structure that consists of nodes in sequence to store a collection of data elements dynamically. Each node contains a value and a reference pointer (link) to the next node. Unlike arrays, linked lists are not stored in contiguous memory locations. Therefore, these reference pointers are required to direct to the next node value. The size of a linked list can grow and shrink dynamically, thus, avoiding any wastage of memory space. The reference pointer of the last node in the sequence is null since it does not point to any further node in the sequence.
To find the number of occurrences of a character in a given string, we will iterate through the string and create a counter for the character. Whenever the iteration results in a match with the character, we will increment this counter by 1. This can be implemented in python as –
input_string = “coding interview preparation” input_string = input_string.lower() character = ‘i’ str_length = len(input_string) char_count = 0 for idx in range(0, str_length): if input_string[idx] == character: char_count += 1 print(f‘There are {char_count} occurrences of {character} in the input string’)
The output of the above program will be “There are 4 occurrences of i in the input string”.
Reversing an array through swapping requires the interchange of the values of two different locations (placed symmetrically) in an array with the help of a temp variable. The pseudocode can be written as –
This can be implemented in python as –
input_arr = [1, 2, 3, 4, 5] arr_length = len(input_arr) start = 0 end = arr_length - 1 while start < end: temp = input_arr[start] input_arr[start] = input_arr[end] input_arr[end] = temp start += 1 end -= 1 print(‘Reversed Array:’, input_arr)
The output of the above python program is “Reversed Array: [5, 4, 3, 2, 1]”
A library is a set of pre-defined functions that can be used to achieve a task. The tasks that otherwise would require writing multiple lines of code can be accomplished with just a fraction of code lines. For example, the python Pandas library is capable of performing a lot of operations on tabular data like CSV, such as ordering, grouping, sorting, imputing values, deleting records, performing complex calculations, creating charts and graphs, etc. There are also libraries which can perform tasks like rgb to hex code conversion, qrcode creation, convert binary code to ascii code, etc. If we tried implementing these operations without using the library, it will multiply the implementation time by a big number and most importantly it is not required. We can save this time and focus on the specific logic designed for the application. Therefore, to perform the common operations with fewer lines of code and avoid unnecessary development time, we can prefer using available libraries.
A framework can be considered a superset of libraries. In computer programming, a framework is a basic structure based on a concept that helps to build software quickly and efficiently. It consists of pre-defined functions, methods, classes, and variables that can be utilized to build the application. A framework serves a specific purpose for development. For example, Django and Flask are Python frameworks that help to build server-side applications while React JS and Angular are JavaScript frameworks that help with frontend application development.
Numerous high-level programming languages are based on interpreters, compilers, or a combination of the two. The work of translating machine code from high-level language to low-level language is carried out by both the compiler and the interpreter, but they approach it in different ways. The complete high-level program is translated at once by the compiler from high-level language to machine code. Due to this, there may be some translation time, but the execution follows quickly. Unfortunately, the program will not function if there is a bug in it. On the other hand, the interpreter will translate each command in the high-level language code before executing it on its own. In this case, the translation is quick but the actual execution is slow. The main benefit of interpreters is that output is produced after each instruction and they continue running until an error occurs.
We know that, a number (natural numbers excluding 1) is said to be prime number if it is only divisible by 1 and itself. The pseudocode for the program is –
This can be implemented in python –
# Take input from user num = int(input("Enter a number: ")) # Assign the flag flag = False if num > 1: # Check if the number is divisible # by another number except 2 and itself. for i in range(2, num): if num % i == 0: # Set the flag to True i.e. not prime flag = True # Break the loop break if flag: print(num, "is a prime number") else: print(num, "is not a prime number")
The output of the program is –
Enter a number: 29
29 is not a prime number
The pseudocode for finding the prime factors of an integer –
The python program for the same is –
# Take input from user num = int(input("Enter a number: ")) for i in range(2, int(num**0.5)): while num % i == 0: print(i, end = " ") num //= i print(num)
The output of the program is –
Enter a number: 153
3 3 17
In case of an Armstrong number of 3 digits, the sum of cubes of each digit is equal to the number itself. For example, 153 is an Armstrong number (1 x 1 x 1 + 5 x 5 x 5 + 3 x 3 x 3 = 153). To implement this, we need to iterate every digit and calculate its cube and add it to the resultant. The pseudocode is given as –
The python implementation for the same is –
# Take input from user num = int(input("Enter a number: ")) # Assign the sum to 0 sum_ = 0 # Assign temp as num temp = num while temp > 0: # Get the last digit digit = temp % 10 # Add its cube to the resultant sum_ += digit * digit * digit # Perform integer division by 10 temp //= 10 if num == sum_: print(num,"is an Armstrong number") else: print(num,"is not an Armstrong number")
The output of the program is –
Enter a number: 153
153 is an Armstrong number
A year is a leap year if it is divisible by 400 or divisible by 4 but not by 100 since every 4th century year is a leap year. The pseudocode can be given as –
The python implementation for the same is –
# Take input from user year = int(input("Enter a number: ")) if year % 400 == 0: print(year, 'is a leap year') elif year % 100 != 0 and year % 4 == 0: print(year, 'is a leap year') else: print(year, 'is not a leap year') The output of the program is –
Enter a number: 2100
2100 is not a leap year
The bubble sort is the simplest way of sorting which is sometimes called sinking sort. In a bubble sort, we repeatedly compare each pair of adjacent elements and swap them if they are in the wrong order. We repeat this process until all elements get sorted. Let us use an example to understand this example clearly. Consider the following array.
We will compare the first two elements in the array, i.e., 56 (index 0) and 63 (index 1). If the left element (at a lesser index) is greater than the right element (at a greater index), we will swap the numbers otherwise ignore them. So, in the first comparison between 56 and 63, we ignore them. During the second comparison, we compare 63 (index 1) and 84 (index 2). Again, the element at the lower index, that is, 63 is smaller than the element at the higher index, 84, so we ignore them. During the comparison of 22 (index 2) and 84 (index 3), we notice that the element at index 2 is greater than the element at index 3 so we swap the two numbers. The below image represents the complete first iteration during the bubble sorting of the above array. The coloured elements are the ones which are taken into consideration during the comparison. The elements coloured in light blue represent that the items are not swapped after comparison. The elements coloured in orange represent that the element was swapped after comparison. Finally, we get an array in which the last item (84 coloured in red) is frozen and it won’t be considered for any further sorting operation.Now, during the second set of iterations, the second highest number will get sorted. During each successive iteration, it will not consider the frozen elements from previous iterations. The further iterations for the sorting are –
The pseudocode to implement a bubble sort algorithm is –
input_arr = [56, 63, 84, 22, 71, 49] arr_length = len(input_arr) for i in range(0, arr_length – 1): for j in range(0, arr_length – i – 1): if input_arr[j] > input_arr[j+1]: temp = input_arr[j] input_arr[j] = input_arr[j+1] input_arr[j+1] = temp print(‘Sorted Array:’, input_arr)
The output of the above program is “Sorted Array: [22, 49, 56, 63, 71, 84]”.
A stack data structure can be imagined as a pile of objects stacked vertically. When we make an addition to the stack, it is added to the top and while accessing the stack, the last added object to the stack is the first to be accessed. The common stack operations are:
The stack can be implemented in python using the code –
class Stack: # Initialize the stack with the provided length def __init__(self, length): self.stack = [] self.length = length self.__size = 0 def size(self): ''' Returns the current size of the stack ''' return self.__size def isEmpty(self): ''' Returns True if the stack is empty, else False ''' return self.__size == 0 def isFull(self): ''' Returns True if the stack is full, else False ''' return self.length == self.__size def push(self, element): ''' Adds a new element to the stack if there is a space. ''' if not self.isFull(): self.stack.append(element) self.__size += 1 print(f'Successfully added {element} to the stack.') else: print('Stack is full. New element cannot be added to the stack.') def pop(self): ''' Removes and returns the value of an element present at top of the stack, if the stack is not empty. ''' if not self.isEmpty(): element = self.stack.pop(-1) self.__size -= 1 print('Successfully removed element from top of the stack.') return element print('Stack is empty. Nothing to pop from the stack.') def peek(self): ''' Returns the value of the element present at the top of the stack if the stack is not empty. ''' if not self.isEmpty(): return self.stack[-1] print('Stack is empty. Nothing to peek in the stack.') def delete(self): ''' Deletes the stack ''' self.stack = None # Create a new stack with length = 5 s = Stack(length = 5) # Pop item from the stack print(s.pop()) # Check if the stack is empty print(s.isEmpty()) # Peek item from the stack print(s.peek()) # Push 3 items to the stack s.push(30) s.push(40) s.push(55) # Check the size of the stack print(s.size()) # Push two more elements to the stack s.push(60) s.push(85) # Peek in the stack and print the response print(s.peek()) # Add one more item to the stack s.push(100) # Check if the stack is full print(s.isFull()) # Pop an item from the stack print(s.pop())
The output of the program is –
Stack is empty. Nothing to pop from the stack. None True Stack is empty. Nothing to peek in the stack. None Successfully added 30 to the stack. Successfully added 40 to the stack. Successfully added 55 to the stack. 3 Successfully added 60 to the stack. Successfully added 85 to the stack. 85 Stack is full. New element cannot be added to the stack. True Successfully removed element from top of the stack. 85
A queue is a data structure that stores items in a first-in-first-out (FIFO) order just like a queue of persons standing. The common queue operations are:
The queue can be implemented in python using the code –
class Queue:
# Initialize the queue with the provided length def __init__(self, length): self.queue = [] self.length = length self.__size = 0 def size(self): ''' Returns the current size of the queue ''' return self.__size def isEmpty(self): ''' Returns True if the queue is empty, else False ''' return self.__size == 0 def isFull(self): ''' Returns True if the queue is full, else False ''' return self.length == self.__size def enqueue(self, element): ''' Adds a new element to the queue if there is a space. ''' if not self.isFull(): self.queue.append(element) self.__size += 1 print(f'Successfully added {element} to the queue.') else: print('Queue is full. New element cannot be placed in the queue.') def dequeue(self): ''' Removes and returns the value of an element present in the front of the queue, if the queue is not empty. ''' if not self.isEmpty(): element = self.queue.pop(0) self.__size -= 1 print('Successfully removed element from front of the queue.') return element print('Queue is empty. Nothing to dequeue.') def peek(self): ''' Returns the value of the element present in the front of the queue if the queue is not empty. ''' if not self.isEmpty(): return self.queue[0] print('Queue is empty. Nothing to peek in the queue.') def delete(self): ''' Deletes the stack ''' self.queue = None print('Queue deleted successfully.') # Create a new queue with length = 5 q = Queue(length = 5) # dequeue an item from the queue print(q.dequeue()) # Check if the queue is empty print(q.isEmpty()) # Peek item from the front of the queue print(q.peek()) # Enqueue 3 items to the queue q.enqueue(30) q.enqueue(40) q.enqueue(55) # Check the size of the queue print(q.size()) # Enqueue two more elements to the queue q.enqueue(60) q.enqueue(85) # Peek in the front of the queue and print the response print(q.peek()) # Equeue one more item to the queue q.enqueue(100) # Check if the queue is full print(q.isFull()) # Enqueue an item from the queue print(q.dequeue()) # Delete the queue q.delete()
The output of the program is –
Queue is empty. Nothing to dequeue. None True Queue is empty. Nothing to peek in the queue. None Successfully added 30 to the queue. Successfully added 40 to the queue. Successfully added 55 to the queue. 3 Successfully added 60 to the queue. Successfully added 85 to the queue. 30 Queue is full. New element cannot be placed in the queue. True Successfully removed element from front of the queue. 30 Queue deleted successfully.
An anagram is a word or phrase that is created by rearranging the letters of another word or phrase, usually utilizing every letter exactly once. Examples include rearranging the words care to become race, binary to become brainy, and heart to become earth. To prove whether two strings are anagrams or not, we can perform sorting on both strings and if the sorted strings match each other then we can consider the strings to be anagrams of each other. The pseudocode can be given as –
The python program for this is given as –
string_1 = 'care' string_2 = 'race' len_str1 = len(string_1) len_str2 = len(string_2) anagram_flag = True if len_str1 != len_str2: anagram_flag = False else: string_1 = ''.join(sorted(string_1)) string_2 = ''.join(sorted(string_2)) for idx in range(0, len_str1): if string_1[idx] != string_2[idx]: anagram_flag = False if anagram_flag: print('The strings are anagrams') else: print('The strings are not anagrams')
In the case of the insertion sort algorithm, we divide the array into two parts: sorted array and unsorted array. Then from the unsorted array, we pick the first element and find its correct position in the sorted array. We repeat the process until there are no items left in the unsorted part of the array. The pseudocode for the insertion sort algorithm is –
The python program for the insertion sort is –
arr = [56, 63, 84, 90, 15, 38, 22, 5, 71, 49] arr_length = len(arr) for i in range(1, arr_length): key = arr[i] j = i - 1 while key < arr[j] and j >= 0: arr[j+1] = arr[j] j -= 1 arr[j+1] = key print('Sorted array:', arr)
The output of the program is “Sorted array: [5, 15, 22, 38, 49, 56, 63, 71, 84, 90]”.
OOP stands for Object Oriented Programming. It is a way of writing code which involves classes, methods, attributes, and objects instead of traditional functions. Large, sophisticated, and actively updated or maintained programs are best fit for this method of development. The use of objects allows the creation of multiple unique instances of a class and the reuse of the methods and attributes of the class, thereby, improving code efficiency, reusability, and readability. The building blocks of OOP are –
The main concepts of OOP include –
Method overriding is an example of runtime polymorphism. Method overriding is implemented during inheritance that involves declaring the same method in the child class which can be found in the parent class. By doing this, we can use the method of the child class instead of the parent class whenever the object of the child class calls the method. Let us understand this with the help of an example.
class Parent: def foo(self): print(‘Parent foo called’) class Child1(Parent): def foo(self): print(‘Child1 foo called’) class Child2(Parent): pass c1 = Child1() c1.foo() c2 = Child2() c2.foo()
In the code, we have implemented three classes – one parent class and two child classes. In the parent class, we have a method named ‘foo’. Both the child classes – Child1 and Child2 inherit from the parent class. The Child1 class has its implementation of the ‘foo’ method. The Child2 class does not have its own ‘foo’ method. After we run the program, we will see that if the child class has its implementation of the parent class methods, then it will override it. Therefore, calling the ‘foo’ method using the Child1 class object will result in overriding the parent class method and calling the ‘foo’ method using the Child2 class object will call the parent class ‘foo’ method since it has not overridden the method. The output of the program is –
Child1 foo called Parent foo called
A thread is a lightweight process that is responsible to run a single sequential program. A sequential program has a beginning, a sequence, and an end. For example, consider a sorting program which has a beginning, an execution sequence, and an end which indicates that the sorting is complete. A thread runs within a program and shares its resources for execution. However, most applications like to take advantage of the multithreading architecture which is capable of running multiple threads at the same time and performing different tasks in the same program. For example, when you are working with MS Word, you can see the highlights which lets you quickly look at your typing errors. It can even run 3rd party add-ons that can help you with other tasks such as identifying grammatical mistakes, inserting pictures, etc. While working with resource-intensive applications, it is recommended to use the concepts of multi-threading to take advantage of the resources, thereby, allowing your application to run smoothly. However, multi-threading is a diverse topic and a tricky one to implement, therefore, one needs to consider using the right set of available libraries to implement it.
Time complexity refers to the time taken by a program to complete its execution. It is measured using the Big O notation. Big O notation is a language and a metric that is used to describe the efficiency of algorithms. Without understanding Big O notations, it is not possible to create efficient algorithms. If we don’t know when our algorithm gets faster or slower, we’ll struggle to judge our program performance. This concept gives us one way of describing how the time it takes to execute our program grows as the size of input grows. For example, a sorting algorithm might be quicker to sort a smaller array but as the size of the array increases, the time taken to sort the array using the same algorithm might increase drastically. In such cases, other sorting algorithms might turn out to be useful.
Time is not the only thing that matters in an algorithm. We might also care about the amount of memory or the space that is being consumed by the algorithm or the program. It is a parallel concept to time complexity. Space complexity is the measure of the amount of working storage that a program needs. As with time complexity, here we are concerned with how the space that is needed grows as the size of the input grows. For example, a smaller array will consume a lesser space than compared to a larger array. If you are using too many variables to store intermediate computations in your program then you might end up consuming more space.
Fibonacci sequence is the sequence of whole numbers 0,1, 1, 2, 3, 5, 8, ... which starts with 0 and 1, and where every number thereafter is equal to the sum of the previous two numbers.
The pseudocode for the program is –
The python implementation for the same is –
def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2) print('Fibonacci for n=8 is', fib(8))
The output of the program is “Fibonacci for n=8 is 21”.
Inheritance is a way to form new classes using classes that have already been defined. Important benefits of inheritance are the ability to reuse code and make the program more readable. To further understand inheritance consider the following example:
class Vehicle:
def __init__(self, mileage, no_of_wheels): self.mileage = mileage self.no_of_wheels = no_of_wheels def apply_brakes(self): print('Brakes applied.') def press_horn(self): print('Honkingggg!!!!!')
class Bike(Vehicle):
def __init__(self, mileage): super().__init__(mileage, no_of_wheels = 2) # Creating an instance of a Bike class bike_obj = Bike(mileage = 60) # Accessing attributes instantiated in Parent class print('Mileage:', bike_obj.mileage) print('No of wheels:', bike_obj.no_of_wheels) # Accessing methods instantiated in Parent class bike_obj.apply_brakes() bike_obj.press_horn()
The output of the program is –
Mileage: 60 No of wheels: 2 Brakes applied. Honkingggg!!!!!
In the python code, we have created a parent class, Vehicle, and a child class, Bike (inheriting from the parent class). The parent class, Vehicle, has two attributes, namely, ‘mileage’ and ‘no_of_wheels’. It also has two methods, namely, ‘apply_brakes()’ and ‘press_horn()’. In the child class, Bike, there are no attributes or methods defined but since we are inheriting the parent class, we can use all the methods and attributes of the parent class. We have created the attribute of the child class and accessed the above-mentioned attributes and methods as seen in the output.
A regular expression, or simply regex, allows us to look for general patterns in text data. For example, if we are looking for an email or phone number in a large document then we can define the pattern and extract all the available emails and phone numbers present in the document using regex. Regular expressions have a standardized set of rules for defining the pattern irrespective of the programming language. They are used widely and are an extremely powerful way to work with text data. Using some of these rules, we can define the phone pattern in regular expression as –
^[6-9]\d{9}$
The ‘^’ marks at the beginning should be with the characters present in the square bracket where 6-9 means any number out of 6, 7, 8, and 9. These four numbers should be present in just one. Following this ‘\d’ means any digit and ‘{9}’ means repeated exactly 9 times. Therefore, the complete pattern describes that the matching string should start with a number 6, 7, 8, or 9 followed by 9 other digits, totalling 10 digits of a phone number.
Tree data structures are a form of non-linear data structure. With an increase in the number of data points, linear data structures are found to be more time-consuming. To avoid this time complexity, tree data structures can play a role. These are tree-like structures formed using nodes, roots, and edges. Since it is a non-linear data structure type, it has a multi-level hierarchy as shown below –
In essence, a binary search tree is just a binary tree with extra features. The first characteristic is that the value of the node in the left subtree is lower than or equal to the value of its parent node. The value of the node in the right subtree exceeds the value of its parent node. Here is an illustration of a binary tree.
The root node of the example binary tree is node 56. For the first property, we stated that the value of the node in the left subtree is less than or equal to the root node. You can see that in this instance, 49 is less than 56. Now, we should have a node in the right subtree that is higher than the value of the root node. You can see that 63 is greater than 56 in this situation. We can observe that this attribute follows the same pattern down to the leaf node if we continue to assess it farther into the tree.
There is no index of the data elements stored in the binary search tree. As a substitute, it uses an implicit structure to keep track of each element's location. The addition and deletion of nodes may be accomplished fast due to this structure. In contrast to how we operate with arrays, where we must progressively tour each element until the correct one is located, in this case, we only need to walk the half tree. Next, we go on to the other tree's half. This produces the desired effect considerably more quickly than a straight loop would. Because a binary search tree is quicker than a binary tree, we could need one while sorting data.
The binary search algorithm searches the required element in the array by dividing the array into two parts. The algorithm can only be applied to an array which is already sorted. It can be implemented using two different approaches, namely, the iterative method and the recursive method. The underlying algorithm remains the same in both methods which work on the principle of ‘divide and conquer’. The iterative method has a complexity of O(1) whereas the recursive method has a complexity of O(log n) which makes the iterative method more efficient.
The pseudocode for implementing a binary search algorithm is –
The python implementation for the same is –
# Initialize the array arr = [5, 15, 22, 38, 49, 56, 63, 71, 84, 90] # Define the search element x = 22 # Calculate the length of the array arr_length = len(arr) # Assign start and end index positions start = 0 end = arr_length - 1 while start <= end: # Compute the middle index position mid = start + (end - start)//2 # Check if the element is in the middle position # Else reassign new start and end index positions if arr[mid] == x: idx = mid break elif arr[mid] < x: start = mid + 1 else: end = mid - 1 print(f"Index position for element {x} is", idx)
The output of the program is “Index position for element 22 is 2”.
The flowchart to find the smallest number in an integer array can be given as –
The python implementation for the same is –
# Initialize the array arr = [56, 63, 84, 90, 15, 38, 22, 5, 71, 49] # Calculate the length of the array N = len(arr) i = 0 # Assign the random smallest number at the start of the index position result = arr[0] while i < N: # Check if the current element is smaller than the result if arr[i] < result: result = arr[i] # Increment the current index position i += 1 print("Smallest element in the array is", result)
The output of the program is “Smallest element in the array is 5”.
The flowchart to find the missing number in an integer array can be given as –
# Initialize the array arr = [1, 1, 2, 2, 4, 5, 8, 9] # Sort the array arr.sort() # Calculate the length of the array N = len(arr) # Initialize a new array with length N and 0 elements narr = [0]*N # Mark the indexes as 1 if the item is present for i in range(0, N): if i + 1 in arr: narr[i] = 1 print('The missing elements are:') # Print the indexes where the element is still 0 for i in range(0, N): if narr[i] == 0: print(i + 1)
The output of the program is –
The missing elements are: 3 6 7
Multiplication of two matrices is only possible if the number of columns of the first matrix matches the number of rows of the second matrix. That means we can multiply the i x j matrix with j x k. The pseudocode for multiplying two matrices is given as (assuming we are multiplying i x j matrix with j x k) –
The implementation in python language for the same is –
# Initialize matrix A A = [ [22, 18, 5], [9, 15, 31], [12, 14, 25], ] # Initialize matrix B B = [ [16, 8], [3, 0], [9, 11], ] # Initialize i, j, k i = len(A) j = len(A[0]) k = len(B[0]) # Initialize resultant matrix result = [[0,0], [0,0], [0,0]] for x in range(0, i): for y in range(0, k): for z in range(0, j): result[x][y] += A[x][z] * B[z][y] for row in result: print(row)
The output of the program is –
[451, 231] [468, 413] [459, 371]
To swap two integer variables, we can use the addition (+) and subtraction (-) operators between the variables. Consider the two integer variables are x and y then we can swap them using –
x = x + y y = x – y x = x - y
In this case, we first added the two integers x and y, and then stored them in x. We then assign x – y to y but x here is equal to x + y which means that we are assigning y = x – y = (x + y) – y = x. Next, we assign x as x – y where we are performing x = x – y = (x + y) – (x) = y. Therefore, by using some mathematical calculations we can swap two integer variables without using a temporary variable.
The merge sort algorithm is a ‘divide and conquer’ algorithm. In the "divide and conquer algorithm," a large problem is divided into smaller chunks, and when those chunks are so small that more division is impossible, we start merging them to find the solution. The input array is split in half and then repeatedly halved until no further division is possible. We begin merging them with sort order once the halving is complete. Finally, we reach the final answer in which we sort all elements. For example, let us consider the array [56, 63, 84, 90, 15, 38, 22, 5, 71, 49]. The split can be performed as –
After splitting the array in half, we divided the two resulting chunks in half once more to create four chunks. We continued splitting these chunks until we ran out of methods to do so. The next step is to merge these chunks (starting from the bottom) which are nothing but arrays consisting of a single item. We'll make sure that each split array is now ordered during merging.The items were placed differently from the prior merge, as indicated by the orange places. Only the components with values 22 and 38 were shuffled during the initial merge. Three of the four arrays underwent shuffling during the second merge. During the third merge, one of the two arrays underwent shuffling. The sorted array is created by the last merge.
Sorting algorithms are divided into two categories based on the space they use and the stability of the algorithms. Based on stability, algorithms can further be classified into stable or unstable.
Stable sorting is the term for a sorting algorithm that does not alter the order in which related pieces of content appear after the content has been sorted. Consider an array with the repeating element "22," where the first instance is stored at memory address "x0001" and the second instance is placed at location "x0002" in the memory. The element "22" will preserve this order in stable sorting, meaning that the first instance of 22 in the sorted array is the one that occupied location "x0001," and the second instance is at position "x0002." In this case, memory is only being taken into account to discriminate between these two items that share the same value.
On the other hand, a sorting algorithm is said to be unstable if, after sorting the content, it changes the order in which related content appears. Therefore, if we use the same array, sorting will place the element "22" at position "x0002" ahead of the similar element at position "x0001" in the sequence.
The algorithms can be classified into –
We need to first check if the lines are parallel or not. If they are parallel then there is no point of intersection. If they are not parallel, we can find their intersection points. The pseudocode for the program is given by –
The implementation in python language for the same is –
# Assign coordinates for line AB and CD A = (-5, -1) B = (3, 3) C = (1, 2) D = (-2, -3) # Generate the line equation for line AB a1 = B[1] - A[1] # y2 - y1 b1 = A[0] - B[0] # x1 - x2 c1 = a1*A[0] + b1*A[1] # Generate the line equation for line CD a2 = D[1] - C[1] # y2 - y1 b2 = C[0] - D[0] # x1 - x2 c2 = a2*C[0] + b2*C[1] # Calculate the determinant det = a1 * b2 - a2 * b1 if det == 0: # Alternatively, check for a1/b1 == a2/b2 print('Lines AB and CD are parallel') else: # Calculate x x = (b2 * c1 - b1 * c2) / det # Calculate y y = (a1 * c2 - a2 * c1) / det print(f'Points AB and CD are intersecting at ({x}, {y})', )
The output of the program is “Points AB and CD are intersecting at (1.0, 2.0)”.
We must comprehend the ideas of backtracking and recursion to put this programme into practice. Recursion plays a crucial role in backtracking. Backtracking is a general algorithm approach that takes into account looking through every potential combination to solve the computing problem and its type of recursion. A backtracking algorithm is a problem-solving algorithm that finds the desired result by applying a brute force method. The brute force method tests every potential solution before selecting the ideal one. But take note that it can often exclude a huge number of candidates with a single test, making it much faster than the brute force enumeration of all complete candidates. Backtracking is done when there are several solutions and we want all of them so we can eliminate several undesirable states in a single iteration.
Enumeration, optimization, and decision problems can all be solved through backtracking.
The implementation of the program to find all permutations of a string is a classic example of backtracking and can be implemented in python as –
# Convert the array to a string def arr_to_str(arr): return ''.join(arr) # Convert string to an array def str_to_arr(string): return list(string) # Function to find all permutations of an array def permute(arr, idx, length): if idx == length: print(arr_to_str(arr)) for i in range(idx, length): # Performing swapping temp = arr[idx] arr[idx] = arr[i] arr[i] = temp # Recursively calling the function permute permute(arr, idx + 1, length) # Performing swapping (Backtracking) temp = arr[idx] arr[idx] = arr[i] arr[i] = temp string = "cat" arr = str_to_arr(string) arr_length = len(arr) permute(arr, idx = 0, length =arr_length)
The output of the program is –
cat cta act atc tac tca
The deciding aspect of any programming interview is always coding proficiency. Programmers are central to the success of a product or a solution that businesses build. As a successful programmer, you are expected to not just know how to code, but also understand the root of a problem. Having this perspective ensures that you’re coding and testing skills come in handy when you build the solution and find its shortcomings. The top 40 must do coding questions you would want to know are covered in this post so you can ace your interviews and land the job of your dreams. The questions include coding round questions for freshers as well as experienced professionals. We have covered theory questions, algorithms, pseudocodes, flowcharts, and even code blocks so that you do not miss out on your preparation journey. To know more, you can check out the Programming courses offered by Knowledgehut which helps you become a skilled programmer. They also have a dedicated C# Certification Course to learn the versatile language developed by Microsoft through immersive hands-on training, live sessions, real-life case studies, and much more. You need to keep updated with changes to ensure that your abilities remain useful given the nearly continual development and advancements in technology. The Coding classes by KnowledgeHut take care of this. With more than 400,000+ professionals trained by 650+ expert trainers in 100+ countries, it is the right choice to achieve high growth in your career and journey as a programmer or coder.
Submitted questions and answers are subjecct to review and editing,and may or may not be selected for posting, at the sole discretion of Knowledgehut.
Get a 1:1 Mentorship call with our Career Advisor