0% found this document useful (0 votes)
4 views

How to Write Clean Code – Tips for Developers With Examples

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

How to Write Clean Code – Tips for Developers With Examples

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

Forum Donate

Learn to code — free 3,000-hour curriculum

NOVEMBER 5, 2024 / #JAVASCRIPT

How to Write Clean Code –


Tips for Developers with
Examples
Programming with Shahan

Imagine a messy room with clothes, books, and other


items scattered everywhere. Finding something in
that room would be tough, right?

Now, think about writing messy code – it’s just as confusing, if not
more!
On the other hand, clean code is like an organized room: you can Donate
Forum
easily find what you need, understand what’s happening, and get
Learn to code — free 3,000-hour curriculum
things done faster.

Let’s have a look at this graph. It shows two different ways of writing
code and how they affect the time it takes to add more lines:

1. ⚠️ Quick & Dirty Code (Red line): This is when you write
code quickly without planning or organizing it well. At first, it
may seem faster, but as more lines are added, it becomes
harder to understand and fix. So, over time, it takes longer
and longer to add each new line.

2. ⚡ Thoughtful & Clean Code (Blue line): This is when you


write code carefully, making it easy to understand and
change. At first, it might take a bit longer, but over time, it
remains easy to work with. This way, adding new lines
doesn't become more difficult.

In simple terms, writing clean code might seem slower at the


beginning, but in the long run, it saves a lot of time and makes work
easier. It also leads to more reliable software and better products. Donate
Forum

Learn to code — free 3,000-hour curriculum


Writing clean code is a habit that professional developers cultivate,
showing dedication to quality and a strong work ethic. And in this
article, I’ll walk you through some best practices for keeping your
code clean.

What we’ll cover:


1. Use Meaningful Names

2. Follow the Single Responsibility Principle (SRP)

3. Avoid Unnecessary Comments

4. Make Your Code Readable

5. Write Unit Tests

6. Be Careful with Dependencies

7. Organize Your Project

8. Use Consistent Formatting

9. Avoid Hardcoding Values

10. Limit Function Length

11. Conclusion

10 Essential Tips for Writing Clean


Code
To help you get started on your clean code journey, here are 10
practical tips to keep your code readable, organized, and efficient.

1. Use Meaningful Names


When naming variables, functions, and classes, pick names that
clearly describe their purpose.
Forum Donate
Instead of calling a variable b , try numberOfUsers . This way, anyone
Learncan
reading your code to code —understand
easily free 3,000-hour curriculum
its purpose without
needing additional comments. A meaningful name eliminates
guesswork and avoids confusion.

Example:

// Good
let numberOfUsers = 5; // Clear and easy to understand

// Bad
let b = 5; // Vague and unclear

💡 Naming Tips
Variables: Use nouns that describe the data, like userAge or
totalAmount .

Functions: Use action words, like calculateTotal() or


fetchUserData() .

Classes: Use singular nouns, like User or Order , to


represent what they are.

// Variable: Describes the data it holds


let userAge = 25;

// Function: Uses an action word to describe what it does


function calculateTotal(price, quantity) {
return price * quantity;
}

// Class: Singular noun representing a type of object


class User {
constructor(name, age) {
this.name = name;
this.age = age;
Forum Donate
}
}
Learn to code — free 3,000-hour curriculum

2. Follow the Single Responsibility Principle


(SRP)
The Single Responsibility Principle means that each function or
method should have one specific job.

This keeps your functions short and focused which makes them
easier to read, test, and maintain.

Imagine a toolbox where each tool has a unique purpose—clean


code functions should work the same way.

For instance, if you have a function called calculateTotal , it should


only handle calculating the total. If you add extra tasks, it can lead to
confusing code that’s hard to maintain. Forum Donate

Learn to code — free 3,000-hour curriculum


Here's an example to show why it's important to keep functions
focused:

Let’s say you want to calculate a total and return an object with
extra information, like who calculated it and when. Instead of adding
these directly into calculateTotal , we can use a second function.

1. Good Example (Separate Tasks)

// This function only calculates the total


function calculateTotal(a, b) {
return a + b;
}

// This function creates an object with extra details


function createCalculationRecord(a, b, user) {
let sum = calculateTotal(a, b); // Calls the calculat
return {
user: user,
total: sum,
timestamp: new Date()
};
}

let record = createCalculationRecord(5, 10, "Shahan");


console.log(record);

👍 Why this is good: Each function has a clear, focused task.


calculateTotal only does the math, while
createCalculationRecord adds the extra details. If you want
to change how the total is calculated, you only update
calculateTotal , and if you want to change the record
format, you only update createCalculationRecord .

2. Bad Example (Mixed Tasks in One Function)


Forum
// This function calculates the total and creates an obje
Donate
function calculateTotalAndReturnRecord(a, b, user) {
Learn to code — free 3,000-hour curriculum
let sum = a + b;
return {
user: user,
total: sum,
timestamp: new Date()
};
}

let record = calculateTotalAndReturnRecord(5, 10, "Shahan


console.log(record);

👎 Why this is bad: The function name


calculateTotalAndReturnRecord shows that it’s trying to do
multiple things. If you want to use just the calculation, you
can’t reuse this function without the record part. It’s also
harder to update and test each task separately.

3. Avoid Unnecessary Comments


Good code should be self-explanatory without needing excessive
comments. Focus on writing code that’s clear and understandable
on its own.

Comments are helpful when explaining complex logic or a unique


approach, but too many comments can clutter your code and make
it hard to follow.

💬 When to Use Comments:


To clarify why something is done in a particular way.

When working with complex algorithms or calculations.

To add notes about potential limitations.


Example: Forum Donate

Learn to code — free 3,000-hour curriculum

// Clear name, no comment needed


let userAge = 25;

// Unclear name, comment needed


let a; // age of the user

4. Make Your Code Readable


Readable code uses indentation, line breaks, and spaces to keep
everything neat and organized.

Think of it like writing a story: paragraphs make reading easier by


breaking up large chunks of text. In coding, line breaks serve the
same purpose.

Example:

// Good Code
if (isLoggedIn) {
console.log("Welcome!");
} else {
console.log("Please log in.");
}

// Bad Code
if(isLoggedIn){console.log("Welcome!");}else{console.log("Please

In VS Code, Prettier and Black are popular formatters that


automatically apply clean code styling for multiple languages.

PyCharm and IntelliJ have powerful built-in formatters with


customizable rules, supporting PEP 8 for Python and other standard
guides. These tools ensure consistent, readable code across
Forum projects
Donate
with minimal manual effort.
Learn to code — free 3,000-hour curriculum

5. Write Unit Tests


Unit tests help make sure each part of your code works as expected.

By testing small, individual parts (like functions), you can catch bugs
early and prevent them from spreading to other parts of the code.

Concretely, unit tests are actually mini quality checks for each part
of your code to ensure they’re working as intended.

🍎 Real-world Example:
Let’s look at how to test a complex JavaScript object with multiple
methods, using a Calculator class as an example.

This approach will help you see why it’s important to keep each
method focused on one task and ensure each one works correctly
through unit testing.

Here is the Calculator class that includes methods for basic


arithmetic operations: addition, subtraction, multiplication, and
division.

class Calculator {
constructor() {
this.result = 0;
}

add(a, b) {
return a + b;
}

subtract(a, b) {
return a - b;
}
Forum Donate
multiply(a, b) {
Learn to code — free 3,000-hour curriculum
return a * b;
}

divide(a, b) {
if (b === 0) throw new Error("Cannot divide by zero");
return a / b;
}
}

As you can see, each method performs one specific operation. The
divide method has additional logic to handle division by zero,
which would otherwise cause an error.

Now, we’ll write unit tests to confirm that each method behaves as
expected. 🔬
🧪 Writing Unit Tests for Each Method
To test our Calculator class, we can write unit tests that cover
normal cases as well as edge cases. Here’s how we would set up
tests for each method:

// Initialize the Calculator instance


const calculator = new Calculator();

// Test add method


console.assert(calculator.add(2, 3) === 5, 'Test failed: 2 + 3 sh
console.assert(calculator.add(-1, 1) === 0, 'Test failed: -1 + 1

// Test subtract method


console.assert(calculator.subtract(5, 3) === 2, 'Test failed: 5 -
console.assert(calculator.subtract(0, 0) === 0, 'Test failed: 0 -

// Test multiply method


console.assert(calculator.multiply(2, 3) === 6, 'Test failed: 2 *
console.assert(calculator.multiply(-1, 2) === -2, 'Test failed: -
// Test divide method
Forum Donate
console.assert(calculator.divide(6, 3) === 2, 'Test failed: 6 / 3
try {
Learn to code — free 3,000-hour curriculum
calculator.divide(1, 0);
console.assert(false, 'Test failed: Division by zero should t
} catch (e) {
console.assert(e.message === "Cannot divide by zero", 'Test f
}

🫧 Explanation of the tests:


1. Addition ( add method): We test that add(2, 3) returns 5 ,
and add(-1, 1) returns 0 . If these tests pass, we know that
the addition logic is working correctly.

2. Subtraction ( subtract method): We verify that subtract(5,


3) returns 2 , and subtract(0, 0) returns 0 . These checks
confirm that subtraction is accurate.

3. Multiplication ( multiply method): We test the


multiplication function with both positive and negative
values, ensuring that multiply(2, 3) returns 6 , and
multiply(-1, 2) returns -2 .

4. Division ( divide method): We verify that dividing 6 by 3


returns 2 . For division by zero, we use a try...catch block
to confirm that an error is thrown with the correct message.
This test make sure the method handles errors properly.

You can see that if any method fails, the test will produce a clear
error message, allowing us to quickly identify and fix the issue.
Testing methods individually helps us catch bugs early and maintain
reliable, clean code as the project grows.

6. Be Careful with Dependencies


Dependencies are pieces of software that your code relies on. 🔌
Imagine you’re building a web app that sends emails. Instead
Forum of Donate
writing the email-sending code yourself, you use an external library
Learn to code — free 3,000-hour curriculum
like Nodemailer. Here, Nodemailer is a dependency—your app
relies on it to handle the email-sending functionality.

Example:

const nodemailer = require('nodemailer');

function sendEmail(to, subject, message) {


const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: '[email protected]',
pass: 'your-email-password'
}
});

const mailOptions = {
from: '[email protected]',
to: to,
subject: subject,
text: message
};

return transporter.sendMail(mailOptions);
}

In this code, nodemailer is imported and used to create a


transporter for sending emails. Without it, you’d need to build all the
email functionality from scratch, which would be complex and time-
consuming. By using Nodemailer as a dependency, your app can
send emails easily.

Even though dependencies are useful, you should try to avoid over-
dependence on external software or libraries. Use dependencies
only when they simplify your work or add important functionality.
Managing dependencies effectively is key to writing clean
Forumcode. Donate
Here are some tips:
Learn to code — free 3,000-hour curriculum

Limit Dependencies: Only include libraries or modules that


are essential for your project.

Keep Versions Updated: Use updated versions of libraries to


avoid security risks.

Separate Logic: Write core functions yourself whenever


possible. This way, if you ever need to remove a dependency,
it won’t break your code.

Let me give you an example with our previous Nodemailer code to


implement the concept of separating logic in your code.

You can create a wrapper function that abstracts away the details of
email sending. This way, you can change the underlying email
service or remove the dependency on Nodemailer without affecting
the rest of your code.

Here's how you can structure your code to accomplish this:

const nodemailer = require('nodemailer');

// Core function to send email


function sendEmail(to, subject, message) {
const transporter = createTransporter();
const mailOptions = createMailOptions(to, subject, message);
return transporter.sendMail(mailOptions);
}

// Function to create the transporter


function createTransporter() {
return nodemailer.createTransport({
service: 'gmail',
auth: {
user: '[email protected]',
pass: 'your-email-password'
}
});
Forum Donate
}
Learn to code — free 3,000-hour curriculum
// Function to create mail options
function createMailOptions(to, subject, message) {
return {
from: '[email protected]',
to: to,
subject: subject,
text: message
};
}

// Example usage
sendEmail('[email protected]', 'Test Subject', 'Hello, this i
.then(() => {
console.log('Email sent successfully!');
})
.catch((error) => {
console.error('Error sending email:', error);
});

🗝️ Key points:
1. Core Functions: The sendEmail , createTransporter , and
createMailOptions functions are separate, allowing you to
modify one without affecting the others.

2. Easy Modifications: If you want to switch to another email


service in the future, you can simply modify the
createTransporter function.

3. Maintainability: This structure makes your code more


maintainable and easier to understand.

7. Organize Your Project


A well-organized project structure is as important as the code itself.
Think of this like organizing your workspace—you need designatedDonate
Forum
places for everything so that you can find them easily. For coding
Learn to code — free 3,000-hour curriculum
projects, create folders for specific parts, like components , utils ,
and services .

📂 How to Organize Your Project


To set up a clean and organized project, you should categorize
different parts of your code into designated folders. Here’s a simple
example of what a well-organized project structure might look like:

myProject
├── src
│ ├── components
│ ├── services
│ ├── utils
└── tests

Breakdown of the project structure:


1. myProject: This is the root folder of your project. It contains
everything related to your application.

2. src (Source): This folder holds all the source code for your
project. It’s where you’ll spend most of your time coding.

3. components: This subfolder contains reusable UI


components. For example, if you're building a web app, you
might have individual files for buttons, headers, or forms
here. Each component can be in its own file to keep things
modular.

Example structure within components :


components
Forum Donate
├── Button.js
Learn to code — free 3,000-hour curriculum
├── Header.js
└── Form.js

4. services: This folder includes functions that perform specific


tasks or handle business logic. For example, if you're sending
emails, you could have a file here with all the email-related
functions.

Example structure within services :

services
├── emailService.js
├── userService.js
└── productService.js

5. utils (Utilities): Here, you place helper functions that can be


used across your project. These might include functions for
formatting dates, validating inputs, or any other common
tasks that don't belong to specific components or services.

Example structure within utils :

utils
├── formatDate.js
├── validateEmail.js
└── generateId.js

6. tests: This folder is dedicated to your testing files. Keeping


your tests organized helps ensure that as you build new
features, you can easily test them without diggingForum
through Donate
your codebase.
Learn to code — free 3,000-hour curriculum
Example structure within tests :

tests
├── emailService.test.js
├── userService.test.js
└── component.test.js

📨 Real-World Example: Working with Nodemailer


Let's say you are building an application that sends emails to users.
You might structure your project like this:

myEmailApp
├── src
│ ├── components
│ │ ├── EmailForm.js
│ │ └── SuccessMessage.js
│ ├── services
│ │ └── emailService.js
│ ├── utils
│ │ └── validateEmail.js
└── tests
├── emailService.test.js
└── EmailForm.test.js

EmailForm.js: This component handles the user interface for


sending an email, like the input fields for the recipient,
subject, and message.

SuccessMessage.js: This component displays a success


message once the email has been sent.
emailService.js: This service contains the logic forForum
sending Donate
emails using Nodemailer, keeping your code modular and
Learn to code — free 3,000-hour curriculum
clean.

validateEmail.js: A utility function that checks if an email


address is formatted correctly.

tests: Here, you would write tests to ensure your email


service and components are functioning as expected.

🍱 Benefits of a Well-Organized Project


1. Ease of Navigation: Anyone looking at your project can
quickly understand where to find specific parts of the code.

2. Better Collaboration: If you’re working with others, a clear


structure helps everyone know where to contribute without
stepping on each other’s toes.

3. Scalability: As your project grows, maintaining a clear


structure helps manage the complexity and keeps your
codebase clean.

4. Improved Maintenance: When you need to update or fix


something, you can find the relevant files quickly, which
saves time and reduces errors.

8. Use Consistent Formatting


Consistency in formatting improves readability.

Establish a pattern for how you write your code, such as using two
spaces for indentation or always including a line break before
comments.

Following consistent formatting makes your code look clean and


well-organized.
🛠️ Tools for Formatting Forum Donate

Learn to code — free 3,000-hour curriculum


Prettier: Automatically formats code based on a set of rules.
Here’s a tutorial that explains how to set up and use Prettier
in VSCode.

ESLint: Helps enforce coding standards by highlighting


issues. Here’s a tutorial that includes a helpful and in-depth
section on setting up ESLint for your projects.

9. Avoid Hardcoding Values


Hardcoding is directly embedding data values in code, like setting a
user ID as 123 instead of using a variable.

Avoiding hardcoded values allows you to reuse code without making


constant changes. Store values in variables, constants, or
configuration files instead.

Here’s a scenario where hardcoding can lead to issues:

// Bad: Hardcoding user limit


function createUser(name) {
let numberOfUsers = 100; // Hardcoded value
if (numberOfUsers >= 100) {
return 'User limit reached.';
}
// Code to create the user
return 'User created.';
}

In this example, numberOfUsers is hardcoded to 100 . If you want to


change the user limit, you have to find and modify this value in the
code. If it appears in multiple places, this task becomes cumbersome
and error-prone.
🏗️ Improved Example Using Constants
Forum

Learn to code — free 3,000-hour curriculum


Donate

Now, let’s refactor this code to use a constant instead:

// Good: Using a constant


const MAX_USERS = 100; // Store the limit in a constant

function createUser(name) {
let numberOfUsers = getCurrentUserCount(); // Get the current
if (numberOfUsers >= MAX_USERS) {
return 'User limit reached.';
}
// Code to create the user
return 'User created.';
}

// Example function to get current user count


function getCurrentUserCount() {
// Simulate fetching the current count, e.g., from a database
return 90; // Example count
}

🥣 Breakdown of the improved example:


1. Using Constants: The MAX_USERS constant is defined at the
top. This way, if you ever need to change the maximum
number of users, you only have to update it in one place.

2. Dynamic Values: The getCurrentUserCount() function


dynamically retrieves the current user count from a
database or any other source. This approach prevents
hardcoding the count and allows for easy changes.

3. Maintainability: By storing values in constants, your code


becomes more maintainable. If the business requirement
changes and you need to increase the user limit to 150 , you
can simply change MAX_USERS from 100 to 150 , and the
change will reflect throughout your application.
4. Clarity: Using descriptive names for your constants (like
Forum Donate
MAX_USERS ) improves the readability of your code. Anyone
Learn to code — free 3,000-hour curriculum
looking at your code can quickly understand what this value
represents.

🤐 When to Use Configuration Files


In larger applications, you might also consider using configuration
files (like JSON, YAML, or environment variables) to store values
that may change between environments (development, staging,
production).

For instance in your config.json file you can hardcode maxUsers as


follows (keep in mind that in config.json, its recommended to use
camelCase as it follows consistent formatting):

{
"maxUsers": 100,
"emailService": {
"service": "gmail",
"user": "[email protected]",
"pass": "your-email-password"
}
}

🪴 Using Configuration in Your Code:


const config = require('./config.json');

function createUser(name) {
let numberOfUsers = getCurrentUserCount();
if (numberOfUsers >= config.maxUsers) {
return 'User limit reached.';
}
// Code to create the user
return 'User created.';
}
Forum Donate

Learn to code — free 3,000-hour curriculum

10. Limit Function Length


Long functions are harder to understand and maintain.

There’s no strict rule, but in general, functions should ideally be no


more than 20-30 lines. If a function has multiple responsibilities or
contains many steps, that’s a good indication it might be too long.
Breaking down these functions into smaller "helper" functions can
make them more manageable and understandable.

Here’s what a long, complex function might look like:

function updateCart(cart, item, discountCode) {


// Add the item to the cart
cart.items.push(item);

// Calculate the new total


let total = 0;
cart.items.forEach(cartItem => {
total += cartItem.price * cartItem.quantity;
});

// Apply discount if available


if (discountCode) {
total = applyDiscount(total, discountCode);
}

// Log the transaction


console.log(`Item added: ${item.name}, New total: $${total}`)

return total;
}

⚠️ This function does multiple things:


1. Adds an item to the cart. Forum Donate
2. CalculatesLearn
the total price.
to code — free 3,000-hour curriculum

3. Applies a discount if there’s a code.

4. Logs the transaction.

While this function might look manageable now, it can quickly grow
if more tasks are added, making it harder to debug and maintain.

Let’s break this long function into smaller, single-purpose functions:

function updateCart(cart, item, discountCode) {


addItemToCart(cart, item);
let total = calculateTotal(cart);

if (discountCode) {
total = applyDiscount(total, discountCode);
}

logTransaction(item, total);
return total;
}

function addItemToCart(cart, item) {


cart.items.push(item);
}

function calculateTotal(cart) {
return cart.items.reduce((total, cartItem) => total + cartIte
}

function logTransaction(item, total) {


console.log(`Item added: ${item.name}, New total: $${total}`)
}

🧩 Let me explain:
1. addItemToCart : This function is now responsible only for
adding an item to the cart. It’s simple, with a clear purpose.
2. calculateTotal : This function calculates the totalForum
price of Donate
all items in the cart. It’s easier to read and understand, and if
Learn to code — free 3,000-hour curriculum
you need to update the way totals are calculated, you only
have to modify this function.

3. logTransaction : Handles the responsibility of logging


details. If you ever need to change what gets logged (for
example, adding a timestamp), you can do so in this function
without touching the rest of the code.

4. updateCart : The main function now reads more like a


summary of the actions being taken: add an item, calculate
the total, apply discounts, and log the result. It’s easier to
follow and understand at a glance.

📒 Let’s summarize limiting function length:


1. 🎯 Focus on One Task: Each function should ideally perform
just one task. If a function seems to be doing multiple tasks,
consider breaking it up.

2. 🩼 Use Helper Functions: Helper functions are small,


focused functions that assist a main function by performing a
specific task. In the example above, addItemToCart ,
calculateTotal , and logTransaction are helper functions.

3. 🪦 Descriptive Names: Name your functions based on their


tasks (for example, addItemToCart ), which helps make the
code self-explanatory.

Best Practices for Clean Code


Now that we’ve covered some important tips, let’s look at some
overarching principles that make up the philosophy behind clean
code:
1. 🎏 Simplicity: Always aim to make your code as simple as Forum Donate
possible.

2. 🧂 Consistency: Keep your code uniform in style and


Learn to code — free 3,000-hour curriculum

structure.

3. 🌾 Clarity: Your code should clearly communicate what it


does.

4. ⛽ Efficiency: Write code that’s optimized for performance


without sacrificing readability.

These principles make coding less about writing and more about
designing solutions. Writing clean code is a skill that grows with
practice, so keep learning and improving over time.

🔌 A Note on Dependencies
Instead of hardcoding dependencies directly into your code, use
package managers like npm (for JavaScript) or pip (for Python) to
manage them. This way, you can easily update or remove them when
needed.

Conclusion 🏁
Writing clean code is like building a strong foundation for a house. It
keeps everything in order, making it easy to add new features or fix
issues as your project grows.

With these tips, you can start developing habits that will make your
code more readable, maintainable, and enjoyable to work on.

Recommended Next Steps 📘


For a structured guide to becoming a backend developer in six
months, you can check out my backend developer roadmap. It’s
designed to help beginners stay on track with weekly Forum
goals, covering
Donate
the essential skills, tools, and technologies. This roadmap can keep
Learn to code — free 3,000-hour curriculum
you motivated and make learning more manageable.

You can follow me on 𝕏 for instant updates.

Hope to see you next time!

Programming with Shahan


I train people how to program in a fun and easy way </> Software
Developer • FreeCodeCamp.org Writer ⌐╦╦═─ #JavaScript #Python
#Next.js ಠ‿↼ alert("You can follow for programming news!")

If you read this far, thank the author to show them you care.
Say Thanks

Learn to code for free. freeCodeCamp's open source curriculum has


helped more than 40,000 people get jobs as developers.
Get started

freeCodeCamp is a donor-supported tax-exempt 501(c)(3) charity organization (United States


Federal Tax Identification Number: 82-0779546)

Our mission: to help people learn to code for free. We accomplish this by creating thousands of
videos, articles, and interactive coding lessons - all freely available to the public.

Donations to freeCodeCamp go toward our education initiatives, and help pay for servers,
services, and staff.

You can make a tax-deductible donation here .


Forum Donate

Learn to code — free 3,000-hour curriculum


Trending Books and Handbooks

Learn CSS Transform Build a Static Blog Build an AI Chatbot


What is Programming? Python Code Examples Open Source for Devs
HTTP Networking in JS Write React Unit Tests Learn Algorithms in JS
How to Write Clean Code Learn PHP Learn Java
Learn Swift Learn Golang Learn Node.js
Learn CSS Grid Learn Solidity Learn Express.js
Learn JS Modules Learn Apache Kafka REST API Best Practices
Front-End JS Development Learn to Build REST APIs Intermediate TS and React
Command Line for Beginners Intro to Operating Systems Learn to Build GraphQL APIs
OSS Security Best Practices Distributed Systems Patterns Software Architecture
Patterns

Mobile App

Our Charity

About Alumni Network Open Source Shop Support Sponsors Academic Honesty

Code of Conduct Privacy Policy Terms of Service Copyright Policy

You might also like