Inizialmente ho creato questo progetto come una sorta di "to-do list" degli argomenti da studiare per diventare un software engineer,
ma è cresciuta fino a diventare ciò che potete vedere oggi. Dopo aver seguito questo percorso di studio, Sono stato preso
come Software Development Engineer ad Amazon!
Probabilmente non hai bisogno di studiare tanto quanto ho studiato io. Comunque, tutto ciò di cui hai bisogno è qua.
Nota Bene: Non avrai bisogno di studiare tanto quanto ho studiato io. Ho sprecato un sacco di tempo su argomenti evitabili. Più informazioni riguardo questo qua sotto. Ti aiuterò ad arrivare ai tuoi obiettivi senza sprecare il tuo prezioso tempo.
La lista proposta qua sotto ti preparerà egregiamente per un colloquio tecnico e per qualsiasi azienda di informatica,
anche per le quelle Big come Amazon, Facebook, Google e Microsoft.
Questo è il mio piano di studio distribuito su più mesi per diventare un software engineer per una grande azienda.
Requisiti:
Una minima esperienza con la programmazione (variabili, cicli, metodi/funzioni, etc)
Pazienza
Tempo
Ricorda che questo è un piano di studio per software engineering, non per web development. Grandi aziende come Google, Amazon,
Facebook e Microsoft considerano il software engineering molto diverso dal web development. Per esempio, Amazon ha dei
Frontend Engineers (FEE) e dei Software Development Engineers (SDE). Questi sono due ruoli separati e i colloqui per queste posizioni
non saranno gli stessi, dato che ogni reparto ha le sue peculiarità. Queste aziende esigono conoscenza in ambito
software development/ruoli dell'engineering.
Se vuoi trovare lavoro come software engineer per una grande azienda, questi sono i concetti che devi sapere.
Se hai perso l'occasione di prendere una laurea in informatica, come io ho fatto, tutto questo ti aiuterà a recuperare 5 anni della tua vita.
Quando ho iniziato questo progetto, non sapevo nulla, dallo stack fino all'heap, non conoscevo O-Grande o nulla riguardo gli alberi e i grafi.
Se avessi dovuto scrivere un algoritmo di ordinamento da zero, ti assicuro che sarebbe stato terribile.
Ogni struttura dati che avevo usato era già integrata nel linguaggio e non sapevo assolutamente come fossero implementate.
Non ho mai dovuto gestire la memoria tralasciando i momenti in cui un programma returnava un errore del tipo "Out of Memory",
che avrei poi risolto, cercando una soluzione.
Nella mia vita ho usato alcuni array multidimensionali e migliaia di array associativi, ma non ho mai creato strutture dati da zero.
Il piano è lungo. Potrebbe richiedere mesi, ma se si ha un po' di familiarità con queste cose già partirete avvantaggiati.
Come usarlo
Tutto ciò che segue rappresenta la cornice degli attuali argomenti, che si dovrebbero affrontare dall'alto verso il basso.
Sto usando le funzionalità del Markdown di Github, comprese le task-liste per monitorare i propri progressi.
lcuni video sono disponibili solo iscrivendosi a un corso Coursera o Edx. Questi vengono chiamati MOOCs.
A volte le lezioni non saranno disponibili immediatamente,
quindi dovrai aspettare un paio di mesi senza averne accesso.
Sarebbe bello sostituire le risorse dei corsi online con fonti pubbliche gratuite e sempre disponibili, come i video di Youtube
(preferibilmente lezioni universitarie), in modo che le persone possono studiare in qualsiasi momento
e non solo quando un determinato corso online è disponibile.
Scegli un Linguaggio di Programmazione
Avrete bisogno di scegliere un linguaggio di programmazione per i colloqui che farete,
ma sarà necessario trovare anche un linguaggio da utilizzare per studiare i concetti di informatica.
Sarebbe perfetto se il linguaggio fosse lo stesso per entrambi gli scopi così da poter essere costante solo su un linguaggio.
Per Questo Piano di Studio
Quando ho fatto questo piano di studio, ho usato principalmente due linguaggi: C e Python
C: Bassissimo Livello. Permette di gestire puntatori e allocazione/deallocazione della memoria, cosicché si possano toccare gli algoritmi
e le strutture dati con le proprie mani.
In linguaggi di alto livello, come Python o Java, tutto questo viene mascherato dal linguaggio stesso. Nel lavoro di tutti i giorni,
un linguaggio di basso livello è terrificante, ma quando si stanno imparando le basi è utilissimo sentirsi vicini al cuore di tutto ciò.
C è ovunque. Vedrai esempi nei libri, nelle lezioni, nei video, OVUNQUE durante il tuo corso di apprendimento.
Questo è un libro abbastanza corto, ma ti darà una grande mano riguardo il linguaggio C e, se ti allenerai un po',
diventerai velocemente un esperto. Capire C aiuta a comprendere il funzionamento dei programmi e della memoria.
Non c'è bisogno di studiare in profondita il libro (o comunque finirlo). Basterà arrivare al punto dove sarai a tuo agio
nel leggere e nello scrivere in C.
Non è necessario comprare molti libri. Onestamente, "Spaccare il Colloquio Pratico di Coding (Libro in Inglese)" è sufficiente,
però io ne ho comprati altri per fare più pratica, ma faccio sempre troppo.
Io li ho comprati entrambi e mi hanno permesso di impratichirmi molto:
Questa lista è cresciuta esponenzialmente negli ultimi mesi, e sì, la situazione è sfuggita di mano.
Questi sono alcuni dei miei errori, così che tu possa evitarli, risparmiando mesi di tempo.
1. Non ti Ricorderai Tutto
Ho guardato ore e ore di video, preso tanti appunti, ma mesi dopo ricordavo davvero poco.
Ho speso 3 giorni a leggere i miei appunti e a farmi flash-cards affinchè le potessi revisionare. Non mi serviva tutta quella conoscenza.
Perfavore leggilo, così da non fare il mio stesso errore:
Per risolvere questo problema, ho creato un piccolo sito web di flashcards dove è possibile trovare 2 tipologie di carte: generali e codice.
Ognuna ha una formattazione diversa. Il sito è ottimizzato per telefono e tablet, affinché potessi revisionare da lì.
Tieni a mente che ho creato carte per qualsiasi argomento, dall'assembly alle curiosità su python, fino al machine learning e alla statistica.
Tutto ciò è molto più di quanto è veramente necessario.
Riguardo le Flash-Cards: La prima volta che comprendi la domanda e rispondi correttamente, non mettere via la card.
Devi rispondere più volte alla stessa carta prima di considerarla appresa.
La ripetizione farà penetrare la vostra conoscenza nei meandri del nostro cervello.
Un alternativa al mio sito di è Anki, sito che è stato consigliatomi parecchie volte.
Usa un sistema di ripetizione che aiuta a memorizzare meglio. Facile da usare, disponibile su qualsiasi piattaforma
e auto-sincronizzato con altri tuoi dispositivi, ha un costa di $25 su iOS, ma è disponibile su altre piattaforme.
Alcuni studenti mi hanno fatto notare problemi di formattazione con degli spazi vuoti, facilmente risolvibili così:
apri un mazzo, modifica il mazzo, clicca sulle carte, seleziona "styling" e aggiungi "white-space: pre;" alla classe "Card".
3. Esercitati con delle Domande da Colloquio Durante lo Studio
QUESTO È MOLTO IMPORTANTE.
Comincia ad esercitarti con delle possibile domande da colloquio durante lo studio delle strutture dati e degli algoritmi.
Dovrai applicare tutto ciò che stai imparando per risolvere i problemi, o ti dimenticherai tutto. Io ho fatto questo errore.
Appena hai imparato un argomento e pensi di saperlo padroneggiare bene (come ad esempio le linked lists):
Dopo, torna indietro e rispondi ad altre 2 o 3 domande sulle linked list.
Fai questo con ogni nuovo argomento che dovrai affrontare.
Continua ad esercitarti con i problemi durante la tua fase di studio, non dopo.
Non verrai assunto per la tua conoscenza, ma per come applicherai la tua conoscenza.
Ci sono molte risorse da consultare, riportate poi sotto.
4. Concentrazione
Ci sono un sacco di distrazioni che potrebbero toglierti tempo prezioso. Focalizzarsi e concentrarsi è difficile. Metti un po' di musica
senza lyrics e ti saprai concentrare molto bene.
Cosa Non Sara' Trattato
Queste tecnologie sono fondamentali, ma non fanno parte di questo piano di studio:
SQL
Javascript (JS)
HTML, CSS e altre tecnologie front-end
Il Piano Giornaliero
Questo corso tratta moltissimi argomenti. Ognuno di questi ti terrà impegnato per qualche giorno, o addirittura per settimane. Dipende dal tuo programma.
Ogni giorno, guarda il prossimo argomento nella lista, guarda video a riguardo e implementa degli appunti
di quelle strutture dati o algoritmi del linguaggio a tua scelta per il corso.
Ricognizione del problema e come le strutture dati ed algoritmi possono essere utilizzate
Raccolta dei requisiti per risolvere il problema
Mentre programmi, spiega il problema e la soluzione, proprio come succederebbe durante il colloquio
Programma su foglio di carta o su una lavagna, non al computer
Trova la complessità temporale e spaziale delle tue soluzioni (vedi O-Grande sotto)
Testa le tue soluzioni
C'è una bellissima introduzione per la metodica della comunicazione nei colloqui di problem-solving. Lo scoprirai anche nei libri di preparazione,
ma ho trovato questo articolo fatto molto bene:
Design degli Algoritmi (Articolo in Inglese)
Scrivi il codice su carta o su una lavagna, non su un computer. Provalo con qualche input di prova. Poi riscrivilo e testalo su un computer.
Se non hai una lavagnetta a casa, prendi un quadernone per fogli da disegno in una qualsiasi cartolibreria. Puoi metterti comodo sul divano e programmare.
Questa è la mia "lavagnetta da divano". Ho aggiunto la penna nella foto per far capire le dimensioni. Se usi una penna, vorrai poter cancellare.
Diventa subito un casino. Io uso una matita e una gomma.
Risolvere questi problemi di coding non serve a memorizzare.
Quando leggerai la parte di "Spaccare il Colloquio Pratico di Coding", c'è un capitolo riguardo questo e alla fine c'è un quiz
per testare la tua capacità nell'identificare la complessità del runtime di diversi algoritmi.
Ti aiuto un po': hai bisogno della conoscenza riguardo puntatori di puntatori:
(per quando passi un puntatore ad una funzione che potrebbe cambiare l'indirizzo a cui il puntatore punta)
Questa pagina serve solo ad avere un assaggio dei puntatori ai puntatori. Non consiglio di seguire l'ordine di questa lista.
La scorrevolezza nel leggere viene persa per colpa di una mancanza di intelligenza.
Implementazione usando le linked list, con puntatore alla coda:
enqueue(value) - aggiunge un valore alla posizione della coda
dequeue() - returna il valore aggiunto per ultimo e lo rimuove
empty() - controlla se è vuota o meno
Implementazione usando gli array con memoria allocata fissa:
enqueue(value) - aggiunge un item alla fine
dequeue() - returna il valore aggiunto per ultimo e lo rimuove
empty() - controlla se la queue è vuota
full() - controlla se la queue è piena
Costi:
una implementazione sbagliata usando le linked list dove aggiungi alla queue dalla testa e togli dalla coda porterebbe ad O(n)
perché avrai bisogno dal prossimo elemento fino alla fine, causando una dequeue trasversale per tutta la lista.
enqueue: O(1) (ammortizzata, linked list e array [approfondendo])
I grafi possono essere usati per rappresentare molti problemi in informatica, perciò questo paragrafo sarà lungo, come quello degli alberi e dell'ordinamento.
Appunti:
Esistono 4 modi basici per rappresentare un grafo in una memoria:
oggetti e puntatori
matrice delle adiacenze
lista delle adiacenze
mappa delle adiacenze
Mettiti alla prova con ogni rappresentazione e imparane i pro e i contro
BFS e DFS - impara la loro complessità computazionale, i loro trade-offs e come implementarli tramite codice
Quando ti viene posto un problema, pensa subito ad una soluzione con i grafi, altrimenti trova un'altra strada
Probabilmente non vedrai problemi di programmazione dinamica durante il tuo colloquio, ma è importante sapere classificare un problema come tale.
Questo argomento può essere complesso, dato che ogni soluzione per problemi di programmazione dinamica (DP) va realizata tramite ricorsione
e questo potrebbe ingannare.
Consiglio di guardare molti esempi riguardo i problemi DP fino a che non comprenderai il meccanismo.
So che il libro canonico sarebbe "Design Patterns: Elements of Reusable Object-Oriented Software", ma questo proposto è migliore per i nuovi programmatori OO.
Impara le classi più famose dei problemi NP-Completi, come il problema del commesso viaggiatore e il problema dello zaino,
e impara a riconoscere un problema NP quando ti viene proposto durante il colloquio.
This section will have shorter video that you can watch pretty quickly to review most of the important concepts.
It's nice if you want a refresher often.
Series of 2-3 minutes short subject video (23 video)
Note by the author: "This is for a US-focused resume. CVs for India and other countries have different expectations, although many of the points will be the same."
Get hands-on practice with over 100 data structures and algorithm exercises and guidance from a dedicated mentor to help prepare you for interviews and on-the-job scenarios.
Think of about 20 interview questions you'll get, along with the lines of the items below. Have at least one answer for each.
Have a story, not just data, about something you accomplished.
Why do you want this job?
What's a tough problem you've solved?
Biggest challenges faced?
Best/worst designs seen?
Ideas for improving an existing product
How do you work best, as an individual and as part of a team?
Which of your skills or experiences would be assets in the role and why?
What did you most enjoy at [job x / project y]?
What was the biggest challenge you faced at [job x / project y]?
What was the hardest bug you faced at [job x / project y]?
What did you learn at [job x / project y]?
What would you have done better at [job x / project y]?
If you find it hard to come up with good answers of these types of interview questions, here are some ideas:
Some of mine (I already may know the answers, but want their opinion or team perspective):
How large is your team?
What does your dev cycle look like? Do you do waterfall/sprints/agile?
Are rushes to deadlines common? Or is there flexibility?
How are decisions made in your team?
How many meetings do you have per week?
Do you feel your work environment helps you concentrate?
What are you working on?
What do you like about it?
What is the work life like?
How is the work/life balance?
Once You've Got The Job
Congratulations!
Keep learning.
You're never really done.
*****************************************************************************************************
*****************************************************************************************************
Everything below this point is optional. It is NOT needed for an entry-level interview.
However, by studying these, you'll get greater exposure to more CS concepts, and will be better prepared for
any software engineering job. You'll be a much more well-rounded software engineer.
*****************************************************************************************************
*****************************************************************************************************
Additional Books
These are here so you can dive into a topic you find interesting.
Important: Reading this book will only have limited value. This book is a great review of algorithms and data structures, but won't teach you how to write good code. You have to be able to code a decent solution efficiently
AKA CLR, sometimes CLRS, because Stein was late to the game
For a richer, more up-to-date (2017), but longer treatment
System Design, Scalability, Data Handling
You can expect system design questions if you have 4+ years of experience.
Scalability and System Design are very large topics with many topics and resources, since
there is a lot to consider when designing a software/hardware system that can scale.
Expect to spend quite a bit of time on this
For even more, see "Mining Massive Datasets" video series in the Video Series section
Practicing the system design process: Here are some ideas to try working through on paper, each with some documentation on how it was handled in the real world:
I added them to help you become a well-rounded software engineer, and to be aware of certain
technologies and algorithms, so you'll have a bigger toolbox.
Know at least one type of balanced binary tree (and know how it's implemented):
"Among balanced search trees, AVL and 2/3 trees are now passé, and red-black trees seem to be more popular.
A particularly interesting self-organizing data structure is the splay tree, which uses rotations
to move any accessed key to the root." - Skiena
Of these, I chose to implement a splay tree. From what I've read, you won't implement a
balanced search tree in your interview. But I wanted exposure to coding one up
and let's face it, splay trees are the bee's knees. I did read a lot of red-black tree code
Splay tree: insert, search, delete functions
If you end up implementing red/black tree try just these:
Search and insertion functions, skipping delete
I want to learn more about B-Tree since it's used so widely with very large data sets
In practice:
From what I can tell, these aren't used much in practice, but I could see where they would be:
The AVL tree is another structure supporting O(log n) search, insertion, and removal. It is more rigidly
balanced than red–black trees, leading to slower insertion and removal but faster retrieval. This makes it
attractive for data structures that may be built once and loaded without reconstruction, such as language
dictionaries (or program dictionaries, such as the opcodes of an assembler or interpreter)
In practice:
Splay trees are typically used in the implementation of caches, memory allocators, routers, garbage collectors,
data compression, ropes (replacement of string used for long text strings), in Windows NT (in the virtual memory,
networking and file system code) etc
These are a translation of a 2-3 tree (see below).
In practice:
Red–black trees offer worst-case guarantees for insertion time, deletion time, and search time.
Not only does this make them valuable in time-sensitive applications such as real-time applications,
but it makes them valuable building blocks in other data structures which provide worst-case guarantees;
for example, many data structures used in computational geometry can be based on red–black trees, and
the Completely Fair Scheduler used in current Linux kernels uses red–black trees. In the version 8 of Java,
the Collection HashMap has been modified such that instead of using a LinkedList to store identical elements with poor
hashcodes, a Red-Black tree is used
In practice:
For every 2-4 tree, there are corresponding red–black trees with data elements in the same order. The insertion and deletion
operations on 2-4 trees are also equivalent to color-flipping and rotations in red–black trees. This makes 2-4 trees an
important tool for understanding the logic behind red–black trees, and this is why many introductory algorithm texts introduce
2-4 trees just before red–black trees, even though 2-4 trees are not often used in practice.
Fun fact: it's a mystery, but the B could stand for Boeing, Balanced, or Bayer (co-inventor).
In Practice:
B-Trees are widely used in databases. Most modern filesystems use B-trees (or Variants). In addition to
its use in databases, the B-tree is also used in filesystems to allow quick random access to an arbitrary
block in a particular file. The basic problem is turning the file block i address into a disk block
(or perhaps to a cylinder-head-sector) address
I added these to reinforce some ideas already presented above, but didn't want to include them
above because it's just too much. It's easy to overdo it on a subject.
You want to get hired in this century, right?