Kako diplomac može ući u Tencent, Alibaba i druge vrhunske internet kompanije?
Predgovor
Već dugi niz godina jedno stalno radim: vodim beleške i pišem blog.
Beleške podrazumevaju beleženje svih mogućih stvari iz učenja — to mogu biti pitanja sa razgovora za posao, sedmični plan učenja, ili samo jedan pojam — svejedno je vredno zapisivanja; za mene je to oblik akumulacije. Što se tiče bloga, od samog početka, kada sam pomoću njega samo beležio projekte, preko prepričavanja tuđih članaka, sve do pisanja originalnih tekstova i uređivanja serija članaka — to je više jedna vrsta taloženja.
Ali u periodu neposredno nakon završetka prolećnog ciklusa zapošljavanja otkrio sam jedan problem: dosta toga što sam ranije naučio sam zaboravio, posebno one pojmove koje nisam dovoljno duboko razumeo — njih je najlakše zaboraviti. Takođe sam otkrio da, iako sam u beleškama zapisao mnogo pojmova i pitanja za razgovore, obično sam ih pročitao samo jednom i nikad se nisam vratio njima.
To znači da, iako je zabeležena količina sadržaja velika, ono što je stvarno usvojeno je vrlo malo; u glavi su mi stalno samo iseckani pojmovi i pitanja za razgovore, dok o celovitom sistemu znanja znam veoma malo. Ovi problemi su mi se tokom prolećnog ciklusa stalno ispoljavali i naterali su me da dugo razmišljam.
Suočen sa takvom situacijom, želim da napravim promenu. Dokle god imam obilje vremena, želim da napravim redukciju ovog sadržaja, i prilikom toga da srušim svoj stari sistem znanja i izgradim nov okvir. Prosto rečeno, to znači krenuti ispočetka sa učenjem Java backend-a, ali ovaj put na mnogo efikasniji način, izbegavajući ranije greške, koristeći najefikasniji i najracionalniji pristup obnovi gradiva. Pošto već imam osnove, ubeđen sam da mogu ostvariti taj cilj, i shodno tome sam napravio jasan i detaljan plan učenja.
„Konkretan i pouzdan plan učenja"
Tokom tri meseca, prvo sam prema mapi puta za Java backend sastavio plan obnove; za svaki pojmovni segment odvojio sam određeni period. Na primer, mogao sam da potrošim jedan dan na obnovu „Java refleksije", dva dana na „obrasce dizajna", i nedelju dana na „JVM virtuelnu mašinu". Obično početkom meseca sastavim plan za ceo mesec, a zatim, u skladu sa napretkom, pravim manje korekcije, ali u suštini uvek pratim tempo, i to uz osiguravanje da je obnova temeljna.
Zato smatram da je za jesenji ciklus zapošljavanja — koji je jedna teška bitka — sastavljanje plana od posebnog značaja. Kada je plan utvrđen, strateški cilj postaje jasan, pa i odgovarajuće taktičke odluke postaju jasnije, a izvršna moć raste zajedno sa njima.
„Blog kao alatka za integraciju gradiva"
Što se tiče načina obnove, uglavnom čitam kvalitetne blogove i kombinujem ih sa praksom u kodu kako bih utvrdio taj deo gradiva. Na primer, kada danas učim o „concurrenthashmap", potražim dva-tri dobra bloga i prvo ih pročitam — uglavnom one koji tumače izvorni kod — a zatim ih objedinim. Ako neki pojmovi nedostaju, dodam ih; ponekad i sam pogledam JDK izvorni kod kako bih bolje razumeo sadržaj bloga. Kada završim integraciju znanja, sastavim odgovarajući blog i objavim ga na svom ličnom blogu.
Pored toga, kada završim obnovu cele teme, te tekstove organizujem u jednu seriju. Na primer, gore pomenuti „concurrenthashmap" zapravo pripada Java paketu za konkurenciju, pa otvaram posebnu kolumnu na blogu za seriju članaka o Java konkurenciji. Za svaku seriju članaka prvo razjasnim od čega se sve sastoji ta tema, a tek onda krenem sa sređivanjem. Tako za Java paket konkurencije prvo napišem o osnovama Java višenitnog programiranja, zatim o JMM modelu memorije, pa korak po korak prelazim na bazen niti, blokirajuće redove, pomoćne klase, atomske klase i tako dalje. Na taj način taj deo gradiva bude obnovljen, a prednost serije članaka je u tome što mogu od početka do kraja razjasniti tok i dobro sumirati pojmove iz svakog dela.
Pri izboru blogova sam povukao pouku iz ranijih iskustava: radije ću potrošiti pola sata na čitanje jednog kvalitetnog članka, nego deset minuta na pet loših. Dobrobit dubokog čitanja je u tome što taj sadržaj može bolje da se uklopi u sistem znanja u tvojoj glavi, umesto da, kao ostali „brzi" članci, nestane u trenu.
„Projekti za utvrđivanje praktičnih sposobnosti"
Pošto sam tokom stažiranja učestvovao u prilično velikim projektima, ali sam na njima dodirivao samo uske module, nisam imao dobar uvid u celokupan projekat. Zato sam odlučio da u ovom periodu još jednom ojačam svoje projektantske sposobnosti — pre svega osećaj za arhitekturu projekta, zatim rutinu u razvoju poslovnih funkcija, a naravno i upoznatost sa raznim uobičajenim backend tehnologijama.
Potrošio sam oko mesec dana na razvoj dva projekta — naravno, uglavnom imitirajući dva projekta otvorenog koda. Oba projekta su razvijena brzo pomoću SpringBoot-a, sa korišćenjem nekih uobičajenih backend tehnologija kao što su redis, skladište u oblaku i poznati veb okviri; pored toga, zahvatili su i tehnologije poput solr i crawler-a. Iako projekti nisu bili previše teški, u tom periodu sam brzo upoznao tok celokupnog razvoja projekta, svakodnevno sam radio iteracije, pratio verzije pomoću Git-a, i za svaku verziju jasno zapisivao šta je urađeno — što mi je dalo vrlo dobro poznavanje arhitekture projekta.
Van samog projekta, takođe sam tražio i pokretao demo-e sa uobičajenim backend komponentama, kako bih stekao neposredan uvid u te tehnologije — na primer sa dubbo, zookeeper, redovima poruka i sl. Ta iskustva su mi pomogla da njihove principe razumem sa više lakoće.
„Upornost u rešavanju zadataka, uz pažnju na metod"
Algoritamski zadaci su glavni deo pismenih testova i razgovora za posao u jesenjem ciklusu; svaki kandidat za poziciju u razvoju mora proći kroz to mučenje algoritamskim zadacima, a za mene, koji nisam iz formalnog IT smera, bilo je još više glavobolje. Baš zato sam odustao od pristupa rešavanja velikog broja LeetCode zadataka i izabrao efikasniji način vežbanja.
Prvo sam ponovo rešio sve zadatke iz zbirke „Mač koji pokazuje na offer" (Sword to Offer), uz sažetak za svaki zadatak, nastojeći da svaki zapamtim; poznato je da se zadaci iz te zbirke često pojavljuju na razgovorima, pa je njihovo savladavanje ključno.
Nakon savladavanja te zbirke, naravno, prešao sam na LeetCode. S obzirom da zadataka ima mnogo, kako ih odabrati? Nisam ih radio ni po tagovima ni redom, već prema vodiču za LeetCode jednog iskusnog majstora, koji je za svaku kategoriju zadataka izdvojio samo nekoliko klasičnih. Tako sam ukupno rešio više od 100 LeetCode zadataka, a pri drugom prolasku sam za te zadatke napravio i sažetak.
Pored ove dve klasične zbirke, posebno sam vežbao i stare zadatke sa razgovora velikih kompanija, uglavnom preko arhive starih zadataka na sajtu NowCoder. Iskreno, stari zadaci su jako važni, jer pitanja koja kompanije postavljaju nisu kao obični algoritamski zadaci — mogu biti prilično neobična, i bez prethodne navike se nađeš u nezgodnom položaju. Pošto sam završio taj deo, moja obnova algoritamskih zadataka je u suštini privršena.
Kada sam završio obnovu svega, rani ciklus je već počeo. Konačno na bojište. Pošto sam se pre bitke temeljno pripremio, prilično sam optimističan u pogledu jesenjeg ciklusa. Ali u stvari, jesenji ciklus je i rovovska bitka i maraton; doći do kraja i pobediti zaista nije lako.
Rekonstrukcija sistema znanja — redukcija onoga što si naučio
Ranije sam pomenuo da sam pre jesenjeg ciklusa završio rekonstrukciju sistema znanja, pa bih želeo da sa vama podelim njegov tadašnji okvirni sastav. Kao što sam rekao, izabrao sam da ponovo prođem kroz Java backend tehnologije; pošto sam znao okvirni pravac i imao osnovu, čitanje mnogih članaka postalo je lakše, a i pisanje tekstova i sažetaka dobilo je na samopouzdanju.
Prvo, u oblasti osnova Jave, napisao sam više od 20 originalnih blogova, uglavnom analiza ključnih Java tehnologija — na primer „Java refleksija", „Java serijalizacija i deserijalizacija", „Java sistem izuzetaka" i tako dalje.
Za Java klase kolekcija, deo tekstova sam napisao sam, a deo sam integrisao iz dobrih tehničkih članaka; od njih su najznačajniji oni o hashmap-i — u tadašnjoj integraciji nisam propustio nijedan pojam.
U oblasti Java konkurentnog programiranja, uglavnom sam se oslanjao na sajt za konkurentno programiranje i na nekoliko kvalitetnih blogova: prvo sam razumeo principe Java konkurencije, a zatim korak po korak proučavao komponente JUC paketa — sa posebnim fokusom na tumačenja chm, konkurentnih alatki, blokirajućih redova i drugog izvornog koda JDK; pored toga, u IDE-u sam pokretao demo-e vezane za JUC, jer ova oblast zahteva mnogo prakse.
Za Java mrežno programiranje, počeo sam od najosnovnijeg socket-a, zatim prešao na NIO i AIO, dodao i nekoliko članaka o modelima Linux IO, čime je sistem znanja postao potpuniji (jer je NIO zasnovan na Linux Epoll implementaciji); zatim sam dodao razmatranje Netty-ja i NIO primene u Tomcat-u — tako su obuhvaćeni gotovo svi važniji delovi Java mrežnog programiranja. Da bih bolje razumeo ovaj deo, na internetu sam tražio dosta demo klijent-server komunikacija; i najzad sam pomoću Socket-a, NIO, AIO i Netty napisao sopstvene C/S komunikacione demo-e.
Za JVM virtuelnu mašinu, tekstove sam uređivao prema nitima izlaganja knjige „Duboko razumevanje JVM virtuelne mašine". Nakon savladavanja osnovnih principa JVM-a, posebno sam se posvetio optimizaciji JVM-a i pitanjima koja se često javljaju u praksi, sredivši uobičajene alatke za optimizaciju, problemske scenarije i primere iz prakse — jer razgovori za posao sve više cene iskustvo sa optimizacijom JVM-a.
Za JavaWeb, krenuo sam od razvoja JavaWeb tehnologija i korak po korak upoznao razlog postojanja svake od njih — JSP, Servlet, JDBC, Spring itd.; zatim sam svaku prilično detaljno proučio, sa posebnim naglaskom na članke o analizi izvornog koda Spring i SpringMVC; sa druge strane, mnogo vremena sam posvetio proučavanju principa rada Tomcat-a. Pored toga, maven, komponente za logovanje, pa čak i komponente za jedinično testiranje, koje su česte u JavaWeb projektima, našle su mesto u mojoj seriji članaka.
U oblasti baza podataka i keširanja, uglavnom sam učio o MySQL i Redis, dvema najčešće korišćenim bazama. Za MySQL, krenuo sam od jednostavnog SQL-a, zatim prelazio na optimizaciju SQL-a, storage engine i indekse MySQL-a, transakcije i brave, pa sve do složenijih tema poput master-slave replikacije i particionisanja baze i tabela. Za Redis, takođe sam krenuo od jednostavnih API-ja, zatim proučavao principe implementacije svake strukture podataka, a onda učio o načinima perzistencije Redis-a i tehničkim pitanjima koja treba imati na umu kada se koristi kao keš — uključujući i implementaciju distribuiranih brava u Redis-u i njegova rešenja za distribuirane klastere.
Poslednja oblast su teorije i tehnologije vezane za distribuirane sisteme — deo koji me je dugo mučio. Sadržaj sam podelio u dva dela: distribuiranu teoriju i distribuirane tehnologije. U teoriji, prvo sam upoznao CAP, BASE i osnovne pojmove, zatim prelazio na protokole i algoritme konsistentnosti, pa na distribuirane transakcije. U distribuiranim tehnologijama obuhvaćeno je još više — distribuirana sesija, balansiranje opterećenja, distribuirane brave i sl.; svaku od ovih tema sumirao sam u jednom ili dva članka. Za distribuirani keš, redove poruka i distribuirane servise posvetio sam više vremena celovitom učenju, a onda sam napravio seriju članaka. Naravno, učenje ovih tehnologija uglavnom je ostalo na teorijskom nivou, jer ih u sopstvenim projektima retko gde koristim.
Time je moj sistem znanja u suštini izgrađen — i upravo je to razlog što sam na jesenjem ciklusu uspeo da prođem tolike razgovore za posao.
Put kroz jesenji ciklus — uporno napred
Koliko god se prethodno pripremio, u samom ciklusu ne smeš biti nemaran; od kraja jula i prvog razgovora do septembra kada sam prešao u miran, „budistički" režim, prošao sam kroz razgovore velikih i malih razmera.
Pošto sam završio rekonstrukciju sistema znanja, fokus sam prebacio na još nekoliko stvari: prvo, na doterivanje i upoznavanje sa svojim CV-jem, kako bih se na razgovoru što bolje predstavio; drugo, na stalno rešavanje zadataka, radi održavanja osećaja i rutine za algoritamske zadatke i pismene testove; treće, na čitanje izveštaja sa razgovora radi popunjavanja rupa — uvek sam smatrao da je to važan deo obnove.
Tako sam istovremeno nastavio sa obnovom i krenuo u niz razgovora jedan za drugim.
U početku sam, radi vežbe, odradio razgovore u nekoliko malih kompanija; zatim je stigao rani ciklus Alibabe. Sa strepnjom sam učestvovao u razgovoru za odeljenje za middleware; težina pitanja bila je umerena — ukupno četiri runde, a moj nastup bio prilično dobar, odgovorio sam na skoro sva pitanja. Manje od nedelju dana kasnije stigla je vest da sam prošao; u tom trenutku sam još uvek bio u čudu. Nisam očekivao da će prvi offer doći toliko brzo.
Tokom tog perioda, dva odeljenja Ant Grupe takođe su mi ponudila razgovor, oba sam odradio i uspešno dobio offer iz jednog od njih. Pošto me je posao te grupe posebno zanimao, konačno sam izabrao offer Ant Grupe.
Pobeda u ranom ciklusu Alibabe zaista je bilo prijatno iznenađenje, ali mi je dala veliki podsticaj, pa sam pristupio i ranom ciklusu Baidu-a i Tencent-a. Pošto Baidu u ranom ciklusu ne ide kroz standardnu proceduru, razgovarala su sa mnom ukupno četiri odeljenja, sa po dve do tri runde svako — ukupno oko 12 razgovora; kasnije sam već bio na ivici da se onesvestim, i jedva sam čekao da vidim broj Baidu-a na telefonu. Zbog velikog broja razgovora, ponekad moj nastup zaista nije bio sjajan, ali nisam tome pridavao preveliki značaj — doživeo sam to kao vežbu.
Težina razgovora u Baidu razlikovala se od odeljenja do odeljenja, ali u svakom razgovoru obavezno se pisao algoritamski zadatak — a jedan zadatak znači najmanje sat vremena; nakon svake runde osećao sam se kao da mi je telo ispražnjeno.
Nakon torture u Baidu razgovorima, brzina pisanja algoritama rukom mi se znatno povećala, a mnoge zamke sam popunio. Zatim, pred razgovor sa Tencent-om, bio sam i uzbuđen i zabrinut: razgovori u Tencent-u su teži, vole da duboko zaviruju u sisteme operacije i mreže, i pitanja su im vrlo duboka. Nakon prve tri runde, četvrta je usledila tek nakon tri nedelje; tadašnji ocenjivač iz treće runde dao mi je prilično dobru ocenu, što mi je dugo podizalo samopouzdanje.
Dok sam čekao završni razgovor sa Tencent-om, učestvovao sam u razgovoru za ByteDance; tada sam imao sreće da dobijem „platinski kod", koji me oslobađa pismenog testa, i ispostavilo se da on zaista mnogo znači. Težina razgovora u ByteDance-u bila je slična onoj u Tencent-u: tri runde, opet sa pisanjem raznih algoritama; pošto je razgovor bio preko videa, jasno sam mogao da vidim da su intervjueri iz ByteDance-a zaista vrlo distantni. Nakon razgovora, moj prvi utisak bio je da sam verovatno pao. Na moje iznenađenje, ipak su mi dali offer.
Pošto sam završio razgovore sa ovim velikim kompanijama, smatrao sam da je moj jesenji ciklus blizu kraja; ali pošto sam ranije prijavio mnogo firmi, odradio sam još razgovore u nekoliko velikih kompanija poput NetEase, Huawei, Kuaishou i dr. Početkom septembra, uzastopno sam dobijao ponude od BAT-a (Baidu, Alibaba, Tencent), ByteDance-a i NetEase-a — Alibaba najranije, Tencent najkasnije; svaka ponuda me je obradovala. Nisam očekivao da ću zaista uspeti da skupim offer-e velikih kompanija kao što je BAT.
Od septembra pa nadalje, osim što sam povremeno sa kolegama odradio po koji pismeni test velikih kompanija, uglavnom sam bio u mirnom režimu. Tek kada su kasnije neke strane kompanije poput Amazon-a i Morgan Stanley-ja počele sa testovima i razgovorima, vratio sam se u formu.
Do sada sam u suštini odbio sve offer-e koje sam nameravao da odbijem; na osnovu svih faktora, najverovatnije ću potpisati sa Alibaba-om — razlog je što mi se to odeljenje sviđa, a i ocena koju su mi dali je prilično visoka. Iako mi je i Tencent dao SP (special offer), ipak sam sa bolom odustao od njega. Što se tiče Baidu-a i ByteDance-a, ponude nisu bile naročito zadovoljavajuće, pa ih nisam ni razmatrao.
Time je moj jesenji ciklus konačno uspešno završen.
Nadam se da ćete i vi jednog dana dobiti offer svojih snova!
Izvor: https://www.zhihu.com/question/26406260/answer/569976835
