Hit the ground running in software engineering .

As a member of the Microsoft ADC student league at my university, I had the privilege to take some courses to ground myself properly in programming. These courses enabled me to understand the fundamentals of programming and software engineering. I am writing this article as a guide for anyone starting out as a software engineer looking for the best route to follow as I believe these courses helped me understand the trajectory for becoming a software engineer.

The Courses are :

  1. Programming Foundations: Fundamentals

This course made me understand the basics of programming and programming languages, it taught the fundamentals which are common amongst several languages like variables, strings and conditional code, You also get to learn how to work with several types of data, properly commenting your code and troubleshooting several errors. One core thing I also learned was how to make the right choices when picking a programming language to use. This course made me understand that programming enables you to tell the computer what to do, and how to do it.

  1. Programming Foundations: Algorithms

Algorithms are the foundation of programming. They are the logic / step-by-step procedures you follow to solve any problem, this course made me understand how algorithms offer a way to think about programming challenges, and it also made me understand and see the most common algorithms for searching and sorting information. I also got to see looping and recursion in action, and how they can be used in programming and understanding common data structures. I also learned how to evaluate the performance of a given algorithm, and how to uniquely filter && count values with hash tables. Below is a code snippet of some implementations of what I learned using python

# Loops

# For loop to iterate over a list
my_list = [1, 2, 3, 4, 5]
for num in my_list:
    print(num)

# Recursion

# Recursive function to calculate the factorial of a number
def factorial(n):
    if n == 0 or n == 1:
        return 1
    else:
        return n * factorial(n-1)

print(factorial(5))  # Output: 120


# Filtering and Counting Unique Values with Hash Tables

# Using a hash table (dictionary) to filter and count unique values
my_list = [1, 2, 2, 3, 4, 4, 5, 5, 5]
unique_values = {}
for num in my_list:
    if num in unique_values:
        unique_values[num] += 1
    else:
        unique_values[num] = 1

print(unique_values)  # Output: {1: 1, 2: 2, 3: 1, 4: 2, 5: 3}
  1. Programming Foundations: Data Structures

This course guides you to understand data structures, it provided me with an introduction to data structures and further gave an in-depth overview of several data structures like arrays, stacks-and-queues, lists, trees-and-graphs, and hash-based data structures. I got to see how they can be implemented in several languages and how they impact the performance and efficiency of applications. Below is an implementation of each of these data structures using Python.

# Arrays

# Creating an array
my_array = [1, 2, 3, 4, 5]

# Accessing elements in the array
print(my_array[0])  # Output: 1

# Modifying an element in the array
my_array[2] = 10

# Printing the modified array
print(my_array)  # Output: [1, 2, 10, 4, 5]


# Stacks and Queues

# Stack implementation using a list
my_stack = []

# Pushing elements onto the stack
my_stack.append(1)
my_stack.append(2)
my_stack.append(3)

# Popping elements from the stack (last-in, first-out)
popped_element = my_stack.pop()
print(popped_element)  # Output: 3

# Queue implementation using a list
my_queue = []

# Enqueuing elements into the queue
my_queue.append(1)
my_queue.append(2)
my_queue.append(3)

# Dequeuing elements from the queue (first-in, first-out)
dequeued_element = my_queue.pop(0)
print(dequeued_element)  # Output: 1


# Lists

# Creating a list
my_list = [1, 2, 3, 4, 5]

# Appending an element to the list
my_list.append(6)

# Inserting an element at a specific index
my_list.insert(2, 7)

# Removing an element from the list
my_list.remove(3)

# Printing the modified list
print(my_list)  # Output: [1, 2, 7, 4, 5, 6]


# Trees and Graphs

# Tree node class
class TreeNode:
    def __init__(self, value):
        self.value = value
        self.left = None
        self.right = None

# Creating a binary tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)

# Graph implementation using a dictionary
my_graph = {
    'A': ['B', 'C'],
    'B': ['D', 'E'],
    'C': ['F']
}

# Printing the tree and graph
print(root.value)  # Output: 1
print(my_graph['A'])  # Output: ['B', 'C']


# Hash-based Data Structures

# Dictionary implementation
my_dict = {'key1': 1, 'key2': 2, 'key3': 3}

# Accessing values using keys
print(my_dict['key2'])  # Output: 2

# Modifying values
my_dict['key3'] = 10

# Printing the modified dictionary
print(my_dict)  # Output: {'key1': 1, 'key2': 2, 'key3': 10}
  1. Programming Foundations: Databases

Databases as the name implies store data. Programs need where to store data generated from either the user or the program itself. This course helped me understand the need for databases and the role they play in the building of complex applications. I got introduced to several terminologies like

i. Normal Forms: Normal forms are rules for database design that eliminate data redundancy and ensure data integrity by defining relationships and dependencies between tables.
ii. ACID: ACID is a set of properties (Atomicity, Consistency, Isolation, Durability) that guarantee reliability and consistency in database transactions.
iii. CRUD: CRUD represents the four basic operations (Create, Read, Update, Delete) used to manage data in a database.
iv. Referential Integrity: Referential integrity ensures that relationships between tables are maintained accurately by enforcing consistency and preventing data anomalies.
v. Transactions: Transactions are logical units of work consisting of multiple database operations, ensuring reliable and consistent changes to the database.
vi. Records: Records are collections of related data items stored as a single unit, representing a row in a database table.
vii. Tables: Tables organize and store data in a structured manner, consisting of columns representing attributes and rows representing records or data entries, forming the foundation of relational databases.

I also learned how to write queries needed to extract data and how to pick between the different demands of storage, access, performance, and security.

  1. Programming Foundations: Object-Oriented Design

“All good software starts with great design ”. One of the core things I learned from this course is the importance of object-oriented thinking and object-oriented design principles necessary for the building of software. This course introduced me to concepts like objects, classes, abstraction, inheritance, and polymorphism. I also learned how to take the requirements for an app, identify use cases, and map out classes using the Universal Modeling Language (UML). I got to know why it is important to do this before writing code. Below is a code snippet of the various OOP concepts I learned in this course using python

# Define the abstract base class 'Shape'
class Shape:
    def area(self):
        # Abstract method to calculate the area of a shape
        pass

    def perimeter(self):
        # Abstract method to calculate the perimeter of a shape
        pass

# Define a concrete class 'Rectangle' that inherits from 'Shape'
class Rectangle(Shape):
    def __init__(self, length, width):
        self.length = length
        self.width = width

    def area(self):
        # Calculate the area of the rectangle
        return self.length * self.width

    def perimeter(self):
        # Calculate the perimeter of the rectangle
        return 2 * (self.length + self.width)

# Define another concrete class 'Circle' that inherits from 'Shape'
class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        # Calculate the area of the circle
        return 3.14 * (self.radius ** 2)

    def perimeter(self):
        # Calculate the circumference of the circle
        return 2 * 3.14 * self.radius

# Create instances of the classes and demonstrate polymorphism
rectangle = Rectangle(4, 6)
circle = Circle(5)

# Call the 'area()' and 'perimeter()' methods on the objects
print("Rectangle:")
print("Area:", rectangle.area())           # Output: Area: 24
print("Perimeter:", rectangle.perimeter()) # Output: Perimeter: 20

print("\nCircle:")
print("Area:", circle.area())              # Output: Area: 78.5
print("Perimeter:", circle.perimeter())    # Output: Perimeter: 31.4
  1. Programming Foundations: APIs and Web Services

An API (Application Programming Interface) is a set of rules and protocols that allows different software applications to communicate and interact with each other. APIs enable applications to access certain features or functionalities of other software systems, such as web services, libraries, operating systems, or databases, without having to understand the internal workings of those systems. Web services allow applications to expose their functionalities or data through well-defined APIs (Application Programming Interfaces) that can be accessed by other applications over the internet. This course introduced me to what web services are and how to secure them, it further explained several web services like :

REST: Representational State Transfer (REST) is an architectural style for designing web services that leverage standard HTTP methods and resources to create scalable and stateless APIs, allowing clients to interact with server-side resources efficiently.

SOAP: Simple Object Access Protocol (SOAP) is a protocol that defines a set of rules for structuring messages in web services, utilizing XML for data representation and providing a more robust and standardized approach for inter-application communication.

GraphQL: GraphQL is a query language and runtime for APIs that enables clients to request specific data requirements and receive only the data they need, reducing over-fetching and under-fetching, and providing a more efficient and flexible approach to data retrieval in web services.

It further showed how APIs are developed on several of these services and the need for APIs and web services in software development.

  1. Programming Foundations: Software Testing/QA

This course introduced me to what quality assurance is and what testing is about, I got to learn the role of QA in software development and the importance of testing when developing software. I got to see the different kinds of testing and how testing fits in the software development life cycle. I also learned the several mechanisms used in determining the overall health of a product, this course further grounded my ability to look at whatever I am working on, think critically about how the pieces fit together, and identify ways to help my team meet quality goals with every release.

CONCLUSION

In all, these courses were very beneficial to my growth as a software engineer. I got to understand several key components involved in the development of software and also see several implementations of useful concepts. Programming is fun and deals with spinning creative solutions to problems. The more you learn and experiment, the more you’ll be able to spin up smarter ways to solve problems.

Embrace the joy of learning and enjoy every step of it. It gets challenging every now and then but you can only get better after every challenge.

En route, to this journey to becoming a software engineer, curiosity and consistency are your trusted companions. Curiosity fuels your thirst for knowledge and exploration, propelling you to ask questions, seek answers, and dive deep into the intricate workings of software development. It drives you to understand not only how things work but also why they work that way.

In summary, curiosity and consistency are indispensable qualities on your journey to becoming a software engineer. Cultivate your curiosity by asking questions, exploring new technologies, and staying curious about the inner workings of software. Support your curiosity with consistency, dedicating time each day to learn, practice, and improve. With curiosity and consistency as your trusted companions, you will navigate the path of software engineering with enthusiasm, growth, and success.