Published on : Apr 06, 2026

What is String ?

The Complete Guide to Strings: From Characters & Memory to Functions & Real-World Uses.

8 Minutes Read
Gradient

Asish Gambhir

Engineering Lead Winzo

What is String

Why Every Programmer Needs to Master Strings

1.png

Think about the last app you used. You typed a username, received a welcome message, searched for something, got an error notification, or read a post. Every single one of those interactions involved a string. Every username, every error message, every search query, every piece of text that a program processes, stores, or displays is a string.

Now think bigger. Every webpage you visit is a massive string of HTML that your browser parses. Every email you send travels across the internet as formatted text. Every programming language you will ever write code in is itself stored and processed as strings. Google’s search engine processes billions of string queries every day. The code your IDE highlights and autocompletes is a string being analysed in real time.

Strings are not a beginner concept you learn and move past. They are the universal data type of programming, present in every language, every application, and every system.

Yet most beginners treat strings as trivial. They learn how to print “Hello, World!” and move on, without ever understanding how a string is actually stored in memory, why some string operations are slow, or which functions to reach for in complex situations.

This blog fixes that. We will go from the very basics all the way to how strings work at the memory level, the algorithm patterns built on top of them, and the subtle mistakes that even experienced developers make.


What is a String?

A string is a sequence of characters used to represent text. It can be a single letter, a word, a sentence, or even an entire document stored as one unit of data.

image (9).png

Break that definition apart:

  • Sequence: Characters are ordered and indexed, the first character has a fixed position and so does the last

  • Characters: A character is any symbol your keyboard can produce: letters, digits, spaces, punctuation, symbols

  • Representing text: Strings bridge the gap between raw binary data inside a computer and the human-readable text we see on screen

Key Analogy:

Think of a string like a necklace of beads, where each bead is a single character. The necklace has a definite start and a definite end. You can look at any bead by its position, add more beads to the chain, or cut the chain and rejoin it somewhere else. The whole necklace is what you hand to someone when you want to give them a message.

Visualising a Simple String

The word "Hello"stored as a string looks like this in memory:

Index

0

1

2

3

4

Char

H

e

l

l

o

Each character sits at a specific index, starting from 0. This indexing is the foundation of almost every string operation you will ever perform.

Creating a Basic String

message = "Hello, World!"
print(message)

How Strings Work Under the Hood

This is the section most tutorials skip, and it is the key to understanding why some string operations are fast and others are surprisingly slow.

Characters and ASCII

At the hardware level, computers only understand numbers. Every character you see on screen is stored as a number internally, using a standard called ASCII (American Standard Code for Information Interchange) or its modern extension, Unicode.

For example:

  • 'A' is stored as 65

  • 'a' is stored as 97

  • '0' is stored as 48

  • ' ' (space) is stored as 32

When you write "Hello", the computer stores the sequence 72, 101, 108, 108, 111 in a block of memory. When it needs to display those characters, it looks up each number in the ASCII/Unicode table and renders the corresponding symbol.

Memory Layout of a String

In most languages, a string is stored as a contiguous block of memory, meaning all the characters sit next to each other with no gaps. This is why accessing any character by its index is instantaneous, the computer calculates the exact memory address using simple arithmetic.

image (10).png

Base address: 1000

Address 1000 → 'H'

Address 1001 → 'e'

Address 1002 → 'l'

Address 1003 → 'l'

Address 1004 → 'o'

Address 1005 → '\0' (C only: null terminator)

To get character at index i, the computer computes: base address + i. No searching required.

Performance Insight: Accessing a character by index is O(1), it takes the same amount of time regardless of how long the string is. However, finding the length of a C string is O(n) because the program must scan character by character until it finds \\0. Modern languages like Python and Java store the length separately, making len() instant.

The Null Terminator in C

C is unique among common languages in how it marks the end of a string. Instead of storing the length separately, it places a special null character \\0 (a byte with value zero) at the end of every string. This tells every string function where the string ends.

char name[] = "Hello";
// Stored as: 'H', 'e', 'l', 'l', 'o', '\0'
// Length in memory: 6 bytes (5 characters + 1 null terminator)

Declaring and Initialising Strings

In Python

Python makes string handling effortless. Strings are a built-in type, and you can use single quotes, double quotes, or triple quotes interchangeably.

# Single and double quotes work the same
name = 'Alice'
greeting = "Hello, World!"

# Triple quotes allow multi-line strings
paragraph = """This is
a multi-line
string."""

# Strings are immutable in Python
# You cannot change a character in place

Note: Python strings are immutable. Once created, you cannot change an individual character. Every “modification” creates a new string object behind the scenes.

// Three ways to create strings
let single = 'Hello';
let double = "Hello";
let template = `Hello,${name}!`;  // Template literals (ES6+)

// Template literals allow embedded expressions
let a = 5, b = 3;
console.log(`Sum:${a + b}`);  // Output: Sum: 8

Warning: You cannot assign a new value to a C string after declaration using =. Use strcpy() instead.

char c[100];
c = "Hello";           // ERROR: not allowed
strcpy(c, "Hello");    // Correct approach

Reading Strings from the User

name = input("Enter your name: ")
print("Hello,", name)

JavaScript (Browser)

import java.util.Scanner;

Scanner sc = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = sc.nextLine();
System.out.println("Hello, " + name);

C: scanf() vs fgets()

C gives you two main options for reading strings, and choosing the right one matters.

Using scanf() — reads a single word only:

#include<stdio.h>

int main() {
    char name[20];
    printf("Enter name: ");
    scanf("%s", name);
    printf("Hello,%s\n", name);
    return 0;
}

Output:

Enter name: Tom Hanks
Hello, Tom

scanf() stops reading at the first whitespace, so it captures only the first word. Notice we use name instead of &name because an array name already acts as a pointer to its first element.

Using fgets() — reads the full line:

#include<stdio.h>

int main() {
    char name[50];
    printf("Enter name: ");
    fgets(name, sizeof(name), stdin);
    printf("Hello,%s", name);
    return 0;
}

Output:

Enter name: Tom Hanks
Hello, Tom Hanks

Always use fgets() over scanf() for strings in C. fgets() limits how many characters it reads (using sizeof(name)), protecting against buffer overflow. The old gets() function has been completely removed from modern C because it allowed unlimited input and caused serious security vulnerabilities.

String Length

Finding the number of characters in a string is one of the most common operations in programming.

image (11).png
txt = "Hello"
print(len(txt))  # Output: 5

Key Difference: In Python, len() is O(1) because Python stores the length separately. In C, strlen() is O(n) because it must scan every character until it finds \\0. If you call strlen() inside a loop in C, store the result in a variable first to avoid scanning the string repeatedly.

int len = strlen(str);  // Compute once
for (int i = 0; i < len; i++) {
    // Use len here, don't call strlen() again
}

Accessing Characters in a String

Because strings are sequences, every character has an index starting from 0. You can read any individual character using that index.

txt = "Hello"
print(txt[0])   # H
print(txt[1])   # e
print(txt[-1])  # o  (Python supports negative indexing from the end)

Off-By-One Warning: A string of length

n has valid indices from 0 to n-1. Accessing index n is out of bounds. In C, this causes undefined behaviour. In Python and Java, it throws an index error. Always check your index boundaries.

String Concatenation

Concatenation means joining two or more strings together to form a longer one.

image (12).png
first = "Hello"
last = "World"
message = first + ", " + last + "!"
print(message)  # Hello, World!

# Faster for many strings: use join()
words = ["Hello", "World", "from", "Python"]
sentence = " ".join(words)
print(sentence)  # Hello World from Python

Performance Warning: In Java and Python, repeatedly concatenating strings with + inside a loop creates a new string object on every iteration, which is very slow for large numbers of concatenations. Use StringBuilder in Java and "".join() in Python instead.

// SLOW: creates a new String object every iteration
String result = "";
for (int i = 0; i < 10000; i++) {
    result += "a";  // Bad practice
}

// FAST: modifies the same object in place
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append("a");  // Good practice
}
String result = sb.toString();

String Comparison

Comparing strings is trickier than it looks, especially because the ==operator behaves differently across languages.

a = "apple"
b = "apple"

print(a == b)         # True (compares content)
print(a == "banana")  # False
print(a < b)          # False (alphabetical comparison)
print("apple" < "banana")  # True (a comes before b)

The most common string bug across all languages: Using == to compare strings when you should be using .equals() or strcmp(). In Java, == compares whether two variables point to the exact same object in memory, not whether their content is the same. Always use .equals() in Java and strcmp() in C.


Common String Functions

Every language provides a standard library of string functions. Here are the most important ones across languages.

image (13).png

Changing Case

txt = "Hello World"
print(txt.upper())   # HELLO WORLD
print(txt.lower())   # hello world
print(txt.title())   # Hello World

Searching Within a String

txt = "Hello World"
print("World" in txt)           # True
print(txt.find("World"))        # 6 (index where it starts)
print(txt.find("Python"))       # -1 (not found)

Replacing Text

txt = "Hello World"
new = txt.replace("World", "Python")
print(new)  # Hello Python

Extracting a Substring

txt = "Hello World"
print(txt[6:11])   # World  (start inclusive, end exclusive)
print(txt[:5])     # Hello
print(txt[6:])     # World

Trimming Whitespace

txt = "   Hello World   "
print(txt.strip())   # "Hello World"
print(txt.lstrip())  # "Hello World   "
print(txt.rstrip())  # "   Hello World"

Quick Reference Table

Operation

Python

JavaScript

Java

C

Length

len(s)

s.length

s.length()

strlen(s)

Uppercase

s.upper()

s.toUpperCase()

s.toUpperCase()

toupper() (loop)

Lowercase

s.lower()

s.toLowerCase()

s.toLowerCase()

tolower() (loop)

Find

s.find(x)

s.indexOf(x)

s.indexOf(x)

strstr(s, x)

Replace

s.replace(a, b)

s.replace(a, b)

s.replace(a, b)

Manual or regex

Substring

s[i:j]

s.slice(i, j)

s.substring(i, j)

strncpy()

Trim

s.strip()

s.trim()

s.trim()

Manual loop

Split

s.split(x)

s.split(x)

s.split(x)

strtok()

Join

x.join(list)

arr.join(x)

String.join(x, arr)

strcat() in loop

Compare

==

===

s.equals(t)

strcmp(s, t)

Copy

Assignment

Assignment

Assignment

strcpy(d, s)

Concatenate

+ or join()

+or template

+ or StringBuilder

strcat()

Strings and Pointers (C)

This section is specific to C and is one of the most important concepts for C programmers to understand.

In C, a string’s name is actually a pointer to the first character of the array. This means you can use pointer arithmetic to navigate through a string.

#include<stdio.h>

int main() {
    char name[] = "Harry Potter";

    // Pointer arithmetic to access characters
    printf("%c\n", *name);        // H  (first character)
    printf("%c\n", *(name + 1));  // a  (second character)
    printf("%c\n", *(name + 6));  // P  (seventh character)

    // Using a pointer variable
    char *ptr = name;
    printf("%c\n", *ptr);         // H
    printf("%c\n", *(ptr + 1));   // a

    // Walking through the string with a pointer
    while (*ptr != '\0') {
        printf("%c", *ptr);
        ptr++;
    }
    // Output: Harry Potter

    return 0;
}

Key Insight: When you write *(name + i), the compiler translates this to name[i]. Both notations are identical at the machine level. Array indexing is just pointer arithmetic in disguise.

String Literals vs Character Arrays

// Character array: stored in stack memory, can be modified
char arr[] = "Hello";
arr[0] = 'J';       // OK: arr is now "Jello"

// Pointer to string literal: stored in read-only memory, cannot be modified
char *ptr = "Hello";
ptr[0] = 'J';       // CRASH: undefined behaviour

Warning: Always use char arr[] = "..." when you need to modify the string. Use const char *ptr = "..." when you only need to read it, the const keyword protects you from accidental modification.

[ Insert image: Memory diagram showing a character array on the stack vs a string literal pointer pointing to read-only memory ]

Passing Strings to Functions

In Python, JavaScript, and Java

In these languages, strings are passed by reference (or by value of the reference). The function receives access to the same string.

def greet(name):
    print("Hello, " + name + "!")

greet("Alice")  # Hello, Alice!

In C

In C, passing a string to a function means passing a pointer to its first character. The function receives the address of the array, not a copy of it.

#include<stdio.h>

void displayString(char str[]) {   // Equivalent to: void displayString(char *str)
    printf("String:%s\n", str);
}

int main() {
    char message[50];
    printf("Enter a message: ");
    fgets(message, sizeof(message), stdin);
    displayString(message);
    return 0;
}

Practical Tip: Since C passes strings as pointers, a function can modify the original string. If you want to protect the original, declare the parameter with const : void displayString(const char *str). This prevents the function from modifying the string content.

Strings Across Programming Languages

Feature

Python

JavaScript

Java

C

String type

Built-in str

Primitive + String

String class

char[] array

Mutable?

No (immutable)

No (immutable)

No (immutable)

Yes (char array)

Null terminator?

No

No

No

Yes (\\0)

Negative indexing

Yes (txt[-1])

No

No

No

Length function

len(txt)

txt.length

txt.length()

strlen(txt)

Length complexity

O(1)

O(1)

O(1)

O(n)

Multi-line strings

"""..."""

Template literals

Text blocks (Java 15+)

\\ at line end

String formatting

f-strings

Template literals

String.format()

printf() / sprintf()

Safe comparison

==

===

.equals()

strcmp()

Mutable alternative

List of chars

Array

StringBuilder

Direct array modification

Unicode support

Full (UTF-8 by default)

Full (UTF-16)

Full (UTF-16)

Requires wide chars

Raw strings

r"path\\to\\file"

Not native

Not native

Not native

String Formatting Deep Dive

Each language has its own way to embed variables inside strings.

Python (f-strings, recommended since Python 3.6):

name = "Alice"
age = 25
print(f"My name is{name} and I am{age} years old.")

JavaScript (Template Literals):

const name = "Alice";
const age = 25;
console.log(`My name is${name} and I am${age} years old.`);

C (printf()/ sprintf()):

char name[] = "Alice";
int age = 25;
printf("My name is%s and I am%d years old.\n", name, age);

// sprintf stores the result in a string instead of printing it
char result[100];
sprintf(result, "My name is%s and I am%d years old.", name, age);

Java (String.format()):

String name = "Alice";
int age = 25;
String msg = String.format("My name is%s and I am%d years old.", name, age);
System.out.println(msg);

Real-World Use Cases of Strings

Strings are not just a textbook concept. They are baked into every piece of software you use daily.

Web Development: HTML, JSON, and APIs

Every webpage is a string of HTML that the browser parses. When your app communicates with a server, it sends and receives data formatted as JSON strings. Every URL you type in a browser is a string that gets parsed into protocol, domain, path, and query components.

import json

# API response as a JSON string
response = '{"name": "Alice", "age": 25, "city": "London"}'

# Parse JSON string into a Python dictionary
data = json.loads(response)
print(data["name"])  # Alice

Search Engines: Pattern Matching at Scale

When you search for something online, the search engine runs string matching algorithms across billions of documents to find pages containing your query. Every autocomplete suggestion you see is generated by finding strings that start with what you have typed so far.

User Authentication: Password and Input Validation

Any time you create an account, the app validates your password as a string: checking length, looking for special characters, verifying it matches the confirmation field. Input sanitisation, removing dangerous characters from user input to prevent security attacks, is entirely string manipulation.

function validatePassword(password) {
    if (password.length < 8) return "Password too short";
    if (!/[A-Z]/.test(password)) return "Must contain uppercase letter";
    if (!/[0-9]/.test(password)) return "Must contain a number";
    return "Password is valid";
}

Compilers and Interpreters: Parsing Code

The programming language you write code in is itself processed as a string. A compiler reads your source code file as a string, breaks it into tokens (keywords, variable names, operators), and then analyses the structure. Every syntax error message you have ever seen was produced by a string comparison failing.

Data Science: Text Analysis

Natural language processing (NLP) tasks like sentiment analysis, spam detection, and language translation are all string manipulation at massive scale. The model that decides whether a movie review is positive or negative is trained on millions of text strings.

reviews = [
    "This movie was absolutely fantastic!",
    "Terrible film, complete waste of time.",
    "Pretty good, I enjoyed it overall."
]

for review in reviews:
    word_count = len(review.split())
    print(f"{word_count} words:{review[:30]}...")

File Systems and Paths

Every file on your computer has a name stored as a string. Every folder path (/home/user/documents) is a string. Operations like checking if a file has a .txt extension or extracting the filename from a full path are all string operations.

import os

path = "/home/user/documents/report.pdf"
filename = os.path.basename(path)    # report.pdf
extension = os.path.splitext(path)[1]  # .pdf
directory = os.path.dirname(path)    # /home/user/documents

Advanced Concepts and Algorithm Patterns

String Immutability and Why It Matters

In Python, Java, and JavaScript, strings are immutable: once created, the content cannot be changed. What looks like “modifying” a string actually creates a brand new string object.

s = "Hello"
s = s + " World"   # A NEW string is created, "Hello" still exists in memory
                   # The variable s now points to the new string

This has a major performance implication. Concatenating n strings with + in a loop creates n intermediate string objects and runs in O(n²) time. The fix is to collect parts and join once.

# SLOW: O(n^2) due to repeated object creation
parts = ["Hello", " ", "World", " ", "from", " ", "Python"]
result = ""
for part in parts:
    result += part

# FAST: O(n)
result = "".join(parts)

The Sliding Window Technique for Strings

One of the most powerful string algorithm patterns. You maintain a “window” (a substring) and slide it across the string, which reduces many O(n²) problems to O(n).

Problem: Find the length of the longest substring without repeating characters.

Naive approach (O(n²)):

def longest_unique_naive(s):
    max_len = 0
    for i in range(len(s)):
        seen = set()
        for j in range(i, len(s)):
            if s[j] in seen:
                break
            seen.add(s[j])
            max_len = max(max_len, j - i + 1)
    return max_len

Sliding Window (O(n)):

def longest_unique(s):
    seen = {}
    left = 0
    max_len = 0

    for right in range(len(s)):
        if s[right] in seen and seen[s[right]] >= left:
            left = seen[s[right]] + 1   # shrink window from left
        seen[s[right]] = right
        max_len = max(max_len, right - left + 1)

    return max_len

print(longest_unique("abcabcbb"))  # Output: 3 (the window "abc")

The Two-Pointer Technique for Palindrome Checking

Two pointers start at opposite ends of the string and move toward each other, comparing characters. This solves the palindrome check in O(n) time and O(1) space.

def is_palindrome(s):
    s = s.lower().replace(" ", "")   # normalise: lowercase, remove spaces
    left, right = 0, len(s) - 1

    while left < right:
        if s[left] != s[right]:
            return False
        left += 1
        right -= 1

    return True

print(is_palindrome("racecar"))        # True
print(is_palindrome("A man a plan a canal Panama"))  # True
print(is_palindrome("hello"))          # False

KMP String Search Algorithm

The naive way to search for a pattern inside a string checks every position and runs in O(n * m) time, where n is the text length and m is the pattern length. The Knuth-Morris-Pratt (KMP) algorithm uses a preprocessed “failure function” to skip comparisons intelligently, achieving O(n + m).

def kmp_search(text, pattern):
    # Build failure function
    m = len(pattern)
    fail = [0] * m
    j = 0
    for i in range(1, m):
        while j > 0 and pattern[i] != pattern[j]:
            j = fail[j - 1]
        if pattern[i] == pattern[j]:
            j += 1
        fail[i] = j

    # Search
    j = 0
    results = []
    for i in range(len(text)):
        while j > 0 and text[i] != pattern[j]:
            j = fail[j - 1]
        if text[i] == pattern[j]:
            j += 1
        if j == m:
            results.append(i - m + 1)
            j = fail[j - 1]

    return results

positions = kmp_search("ababcababcabc", "abc")
print(positions)  # [2, 7, 9]

Anagram Detection

Two strings are anagrams if they contain the same characters with the same frequencies. A character frequency count using a dictionary runs in O(n) time.

def are_anagrams(s1, s2):
    if len(s1) != len(s2):
        return False

    count = {}
    for char in s1:
        count[char] = count.get(char, 0) + 1
    for char in s2:
        count[char] = count.get(char, 0) - 1
        if count[char] < 0:
            return False

    return True

print(are_anagrams("listen", "silent"))  # True
print(are_anagrams("hello", "world"))    # False

Advantages and Disadvantages

Advantages of Strings

  • Universal data type: Present in every programming language; the skill of string manipulation transfers directly across languages

  • Human-readable: Strings bridge the gap between binary machine data and text humans can read and write

  • Rich standard libraries: Every language provides dozens of built-in functions covering the most common operations, so you rarely need to write low-level character manipulation yourself

  • Flexible: A string can represent anything from a single character to an entire document, from a simple name to a complex JSON payload

  • Foundation of communication: All network communication, file I/O, and user interaction ultimately flows through strings

Disadvantages and Risks

  • Immutability overhead: In Python, Java, and JavaScript, naive string concatenation inside loops creates many temporary objects and runs slowly; requires conscious use of StringBuilder or join()

  • Off-by-one errors: Substring indices, character access, and loop boundaries over strings produce subtle bugs if the boundary conditions are wrong

  • Buffer overflow in C: Writing more characters into a fixed-size char array than it can hold is a critical security vulnerability and one of the most historically exploited bugs in software history

  • Encoding issues: Mixing UTF-8, UTF-16, and ASCII encodings across systems causes garbled text and is a common source of bugs in international software

  • Comparison traps: Using == instead of .equals() in Java or strcmp() in C compares references or addresses, not content, causing silent bugs that are hard to track down

  • SQL and command injection: Inserting user-supplied strings directly into database queries or system commands without sanitisation is the most common web security vulnerability


Conclusion

Strings look simple on the surface but go surprisingly deep once you understand how they actually work. Here is a recap of what we covered:

  • A string is a sequence of characters representing text, stored in memory as a contiguous block of numeric values using ASCII or Unicode

  • In C, strings end with a null terminator \\0; other languages store the length separately, making length lookups O(1)

  • Declaring a string differs across languages: Python and JavaScript are effortless, Java uses the String class, and C requires careful array management with room for \\0

  • Use fgets() in C instead of scanf() or the removed gets() to safely read strings with spaces

  • Accessing characters by index is O(1) in all languages; always remember indices start at 0 and end at length minus 1

  • Concatenating strings with + in a loop is slow in immutable-string languages; use join() in Python and StringBuilder in Java

  • Comparing strings requires .equals() in Java and strcmp() in C; == compares references, not content, in those languages

  • Strings and pointers in C are deeply linked: a string’s name is a pointer to its first character, enabling pointer arithmetic

  • Advanced patterns like the sliding window, two-pointer technique, and KMP search use loops over strings to solve complex problems efficiently

  • The biggest risks are buffer overflow in C, encoding mismatches, and injection attacks from unsanitised string input

Strings are the universal currency of programming. Mastering them, truly mastering them and not just knowing len() and +, is the gateway to building real applications, understanding security, and writing code that works correctly with any input a user might provide.

FAQ

FREQUENTLY ASKED QUESTIONS

A character is a single symbol: one letter, one digit, one punctuation mark. A string is a sequence of zero or more characters. In Python, there is no separate character type: a “character” is just a string of length one. In Java and C, char is a distinct type that holds exactly one character, while String or char[] holds many.
Immutability provides several benefits. It makes strings safe to share across multiple parts of a program without risk of one part unexpectedly changing the value another part is relying on. It also enables performance optimisations: Java’s String Pool can store one copy of a commonly used string literal and share it across many variables. The trade-off is that “modifying” a string always creates a new object.
A buffer overflow happens when you write more data into a fixed-size character array than it was allocated to hold. The extra characters overwrite adjacent memory, which can corrupt program state or, in the worst case, allow an attacker to inject malicious code. This is one of the oldest and most exploited security vulnerabilities in software history. Using fgets() with a size limit instead of gets() or unchecked scanf() is the primary defence.
In Java, String is an object. The == operator compares whether two variables point to the exact same object in memory. Two different String objects with identical content will fail a == check because they are stored at different memory addresses. The .equals() method compares the actual character content, which is always what you want when comparing strings. Use == only when you specifically need to check object identity.
scanf("%s", str) reads characters until it encounters whitespace, so it only captures one word at a time. It also does not limit how many characters it reads, making it vulnerable to buffer overflow. fgets(str, size, stdin) reads an entire line including spaces, and takes a size argument that prevents reading more characters than the buffer can hold. Always prefer fgets() for reading strings in C.
ASCII only covers 128 characters, which is sufficient for English but not for the world’s languages. Unicode is a universal standard that assigns a unique number to over 140,000 characters covering virtually every language, plus emoji, symbols, and special characters. Python 3 uses UTF-8 (a Unicode encoding) by default. Java uses UTF-16 internally. C requires explicit use of wide character types (wchar_t) for full Unicode support. Understanding encoding becomes essential when building applications used by people around the world.
String interpolation means embedding variable values directly inside a string template. In Python, f-strings (f"Hello, {name}") are the modern recommended approach: readable, fast, and flexible. In JavaScript, template literals (`Hello, ${name}`) serve the same purpose. In Java, String.format() or text blocks work well. In C, printf() and sprintf() use format specifiers like %s and %d. F-strings and template literals are the most readable options in their respective languages.
Use StringBuilder whenever you are building a string through repeated concatenation, especially inside a loop. Each + operation on a String creates a new immutable object, which is O(n) work repeated n times for a total of O(n²). StringBuilder maintains a mutable internal buffer and appends in amortised O(1) time per operation, making the whole loop O(n). For simple one-time concatenations outside loops, regular + with String is perfectly fine.