Swift
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Optionals
-
Section 4: Object-Oriented and Value Types
-
Section 5: Memory Management
-
Section 6: Generics and Error Handling
-
Section 7: Concurrency
-
Section 8: Working with Collections
-
Section 9: Codable and Data Handling
-
Section 10: Protocol-Oriented Programming
-
Section 11: Testing and Tooling
-
Section 12: Practical Projects
-
Section 13: Interview Practice
-
Section 14: More Practice Exercises
-
Section 15: More Standard Library
-
Section 16: Advanced Concurrency
-
Section 17: Foundation Framework Deep Dive
-
Section 18: URLSession and Networking Deep Dive
-
Section 19: Combine Framework
-
Section 20: SwiftUI Fundamentals for Swift Developers
-
Section 21: Server-Side Swift with Vapor
-
Section 22: Swift Package Manager Deep Dive
-
Section 23: Swift Concurrency Deep Dive
-
Section 24: More Language Features
-
Section 25: Error Handling Deep Dive
-
Section 26: Testing Deep Dive
-
Section 27: Data Structures and Algorithms in Swift
-
Section 28: More Practice Exercises
-
Section 29: More Interview Practice
-
Section 30: Swift Macros (Swift 5.9+)
-
Section 31: Property Wrappers Ecosystem
-
Section 32: Swift Interop Deep Dive
-
Section 33: iOS App Architecture Patterns
-
Section 34: Performance and Debugging
-
Section 35: App Distribution and CI/CD
-
Section 36: More Practical Projects
-
Section 37: SwiftData and Persistence
-
Section 38: More Design Patterns
-
Section 39: More Review and Practice
-
Section 40: More Foundation Deep Dive
-
Section 41: Advanced Collections in Swift
-
Section 42: Advanced Generics Practice
-
Section 43: UIKit for Legacy and Hybrid Apps
-
Section 44: watchOS and visionOS Development Basics
-
Section 45: More Networking Patterns
-
Section 46: More Testing Practice
-
Section 47: Accessibility in Swift Apps
-
Section 48: Localization
-
Section 49: More Practical Projects Round 2
-
Section 50: Swift Charts Framework
-
Section 51: More Interview and Algorithm Practice
-
Section 52: Final Practice and Mastery
-
Section 53: Swift Compiler and Build System
-
Section 54: More Concurrency Practice
-
Section 55: App Store Guidelines and Review
-
Section 56: More Design and Architecture
225: Mock Coding Interview Walkthrough in Swift
When you're sitting in a coding interview, the pressure often pushes you toward the first solution that comes to mind. That's usually the "naive" approach—the one that solves the problem but does so inefficiently. In a real interview, getting a working solution is great, but the magic happens when you can look at your own code and say, "This works, but it's slow; here is how I'd actually build it for production."
Let's walk through a classic: Grouping Anagrams. Given an array of strings, we need to group the ones that are anagrams of each other (meaning they use the exact same letters in a different order) into separate lists.
The "Just Make it Work" Approach
If I'm nervous and just trying to get something on the screen, I might start with a brute-force method. I'd probably iterate through the list, pick a word, and then scan the rest of the list to see if any other words match it. To check if two words are anagrams, I'd sort both strings and see if they're equal. It looks something like this:
func groupAnagramsNaive(_ strings: [String]) -> [[String]] {
var result = [[String]]()
var visited = Set<Int>()
for i in 0..
Now, if you write this, the interviewer won't tell you it's "wrong" because it produces the correct output. But they are waiting for you to realize that this is an $O(N^2 \cdot K \log K)$ disaster, where $N$ is the number of strings and $K$ is the average length of a string. We are sorting strings inside a nested loop. If the input list has 10,000 words, this code is going to hang. I've seen candidates get stuck here because they're too afraid to admit their first attempt is inefficient.
Trading Space for Speed
The way to fix this is to stop comparing every word to every other word. Instead, we can use a Dictionary to act as a lookup table. The trick is to realize that every anagram, once sorted, results in the exact same string. That sorted string becomes our "canonical key."
By using the sorted string as a key and an array of original strings as the value, we only have to iterate through the list once. We've traded a bit of memory (the dictionary) for a massive gain in speed. We've moved from quadratic time to linear time relative to the number of strings.
func groupAnagramsOptimized(_ strings: [String]) -> [[String]] {
var groups = [String: [String]]()
for word in strings {
let key = String(word.sorted())
groups[key, default: []].append(word)
}
return Array(groups.values)
}
Notice the use of groups[key, default: []]. In Swift, this is much cleaner than checking if the key exists and then initializing an empty array. It's a small detail, but it shows the interviewer you actually know the language idioms.
The "Senior Engineer" Swift Shortcut
If you really want to impress, you can point out that Swift has a built-in initializer for dictionaries specifically for this purpose: Dictionary(grouping:by:). This is essentially a functional way of doing exactly what we did above. It tells the compiler, "Take this collection and group the elements based on the result of this closure."
func groupAnagramsSwiftWay(_ strings: [String]) -> [[String]] {
let grouped = Dictionary(grouping: strings) { String($0.sorted()) }
return Array(grouped.values)
}
I usually suggest presenting the Dictionary loop first, then mentioning the grouping initializer as a "Swift-specific optimization." It proves you understand the underlying data structure (the hash map) while also demonstrating that you're up-to-date with the Standard Library. It turns the conversation from "Can this person code?" to "How can this person help us write more concise Swift?"
📋 Practical Task
Implement a High-Frequency Word Finder
To practice the pattern of using a dictionary to group and count data—similar to the anagram problem—write a function called findFrequentWords(in text: String, threshold: Int).
Your function should:
- Take a long string of text and a minimum frequency count (threshold).
- Clean the text by removing punctuation and converting it to lowercase.
- Identify all words that appear more than the threshold number of times.
- Return these words as an array of strings.
There are no comments for now.