JavaRush /Java Blog /Random-TL /Ang kwento ng isang panayam: mga kawili-wiling tanong
GuitarFactor
Antas
Санкт-Петербург

Ang kwento ng isang panayam: mga kawili-wiling tanong

Nai-publish sa grupo
Kamakailan lamang ay nagkaroon ako ng pagkakataong dumalo sa isang panayam para sa isang intern na posisyon sa isa sa mga malalaking kumpanya ng IT. Ang kwento ng isang panayam: mga kawili-wiling tanong - 1Ito ang aking unang panayam sa IT at, sa aking palagay, naging kawili-wili ito. Sa kabuuan, ako ay "interogado" nang higit sa 3 oras (ito ay nauna sa takdang-aralin at pagsusulit sa opisina sa isang computer). Gusto kong bigyang pugay ang tagapanayam, na hindi sumuko nang mali ang sagot ko sa tanong, ngunit sa tulong ng kanyang mga nangungunang tanong ay pinilit akong mag-isip tungkol dito at makarating sa tamang sagot. Sa ibaba ay magpapakita ako ng ilang "sketch" - sa aking opinyon, medyo kawili-wiling mga katanungan, ang ilan ay nagbigay sa akin ng mas malalim na pag-unawa sa ilang mga aspeto sa Java. Marahil ang mga bagay na ito ay mukhang halata sa ilan, ngunit sa palagay ko ay magkakaroon ng mga para kanino ito ay magiging kapaki-pakinabang. Sa ibaba ng mga parirala ay naka-highlight sa mga sumusunod na font: Interviewer - sa naka-bold Voice-over na mga paliwanag at sa aking mga saloobin - sa italics Aking mga sagot - sa regular na font Tapos na tayo sa background, mag-negosyo na tayo)

Sketch 1. "Isang tila simpleng paraan"

Isulat kung paano mo ipapatupad ang isang paraan na nagbabalik ng resulta ng paghahati ng numero a sa numero b. Ang tagapanayam ay nagsusulat sa isang piraso ng papel
int divide(int a, int b) {
}
*Napatingin ako ng hindi makapaniwala sa papel na may method signature. Ano ang catch?* Sumulat ako:
int divide(int a, int b) {
    return a/b;
}
Mayroon bang anumang mga problema sa pamamaraang ito? *I'm catching a really stupid dumbass* Apparently not.. Next comes a legitimate question: Paano kung b=0? *Whoa, malapit na akong ma-kick out sa opisinang ito kapag nagpatuloy ako sa ganito!* Ay oo nga pala. Narito mayroon kaming mga argumento ng uri ng int, kaya isang Arithmetic Exception ang itatapon. Kung ang mga argumento ay nasa uri ng float o double, ang magiging resulta ay Infinity. Ano ang gagawin natin dito? Nagsisimula na akong magsulat ng try/catch
int divide(int a, int b) {
    try {
        return a/b;
    } catch (Exception e) {
        e.printStackTrace();
        return ... // ??? what the hack?
    }
}
*Nakabalik ako at nag-freeze: may kailangang ibalik kung sakaling magkaroon ng error. Ngunit paano makikilala ang “isang bagay” na ito sa resulta ng pagkalkula?* Ano ang ibabalik natin? Hm... Babaguhin ko ang uri ng return variable sa Integer at sa kaso ng exception ay ibabalik ko ang null. Isipin natin na hindi natin mababago ang uri. Makakalabas ba tayo kahit papaano? Baka may magagawa pa tayo with the exception? *Here it comes* Maaari din natin itong ipasa sa paraan ng pagtawag! Tama. Ano ang magiging hitsura nito?
int divide(int a, int b) throws ArithmeticException{
    return a/b;
}

void callDivide(int a, int b) {
    try {
        divide(a, b);
    } catch (ArithmeticException e) {
        e.printStackTrace();
    }
}
Kailangan bang pangasiwaan ang exception? Oo, dahil tahasan namin itong ipinapasa mula sa paraan ng paghahati. (*Nagkamali ako dito! Ang mga sumusunod ay ang mga nangungunang tanong mula sa tagapanayam upang makarating sa tamang sagot*) At Arithmetic Exception - anong uri ng exception ito - may check o walang check? Isa itong Runtime exception, na nangangahulugang hindi naka-check. *Here comes the killer question* Kaya lumalabas, sa iyong mga salita, kung tinukoy namin ang mga throws Arithmetic Exception sa method signature, kung gayon ito ay naging checked exception? *Ugh!* Malamang... hindi. Oo, hindi. Kung nagsasaad kami ng mga throws /unchecked exception/ sa signature, nagbabala lang kami na ang method ay maaaring magtapon ng exception, ngunit hindi ito kailangang pangasiwaan sa calling method. Naayos na yan. Mayroon pa ba tayong magagawa upang maiwasan ang mga pagkakamali? *Pagkatapos ng ilang pag-iisip* Oo, maaari din nating suriin kung (b==0). At magsagawa ng ilang lohika. Tama. Kaya maaari tayong pumunta sa 3 paraan:
  • subukan/huli
  • throws – pagpapasa sa paraan ng pagtawag
  • pagsusuri ng argumento
Sa kasong ito, dividealing paraan sa tingin mo ang mas mainam?
Pipiliin kong ipasa ang exception sa paraan ng pagtawag, dahil... sa paraan ng paghahati ay hindi malinaw kung paano iproseso ang pagbubukod na ito at kung anong uri ng resulta intang ibabalik sa kaso ng isang error. At sa paraan ng pagtawag, gagamitin ko ang argumentong b upang suriin kung ito ay katumbas ng zero. Tila ang sagot na ito ay nasiyahan sa kinapanayam, ngunit sa totoo lang, hindi ako sigurado na ang sagot na ito ay hindi malabo))

Sketch 2. "Sino ang mas mabilis?"

Pagkatapos ng karaniwang tanong, paano naiiba ang isang ArrayList sa isang LinkedList, dumating ito: Ano ang mas mabilis na mangyayari - pagpasok ng isang elemento sa gitna ArrayListo sa gitna LinkedList? *Dito ako tumalon, naalala ko na kahit saan may nabasa ako tulad ng "gamitin LinkedListupang magpasok o magtanggal ng mga elemento sa gitna ng listahan." Sa bahay ay na-double check ko pa ang mga lektura ng JavaRush, mayroong isang parirala: "kung maglalagay ka (o magde-delete) ng maraming elemento sa gitna ng isang koleksyon, mas mabuting gamitin mo ang LinkedList. Sa lahat ng iba pang kaso - ArrayList." Awtomatikong sinagot* Ito ay magiging mas mabilis sa LinkedList. Pakilinaw po
  1. Upang magpasok ng isang elemento sa gitna ArrayList, makikita namin ang elemento sa listahan sa pare-parehong oras, at pagkatapos ay muling kalkulahin ang mga indeks ng mga elemento sa kanan ng ipinasok, sa linear na oras.
  2. Para LinkedList.
Kaya lumalabas, alin ang mas mabilis? Hm... Ganun din pala. Ngunit kailan ito LinkedListmas mabilis? Lumalabas na kapag ipinasok natin ito sa unang kalahati ng listahan. Halimbawa, kung ipasok mo ito sa pinakadulo simula, ArrayListkakailanganin mong kalkulahin muli ang lahat ng mga indeks hanggang sa pinakabuntot, ngunit LinkedListkailangan mo lamang baguhin ang sanggunian ng unang elemento. Moral: huwag maniwala nang literal sa lahat ng nakasulat, kahit na sa JavaRush!)

Sketch 3. "Saan tayo walang katumbas at hashcode!"

Ang pag-uusap tungkol sa equals at hashcode ay napakahaba - kung paano ito i-override, kung ano ang pagpapatupad sa Object, kung ano ang mangyayari sa ilalim ng hood, kapag ang isang elemento ay ipinasok sa HashMap, atbp. Magbibigay lang ako ng ilang puntos na kawili-wili sa aking opinyon* Isipin na nakagawa tayo ng isang klase
public class A {
    int id;

    public A(int id) {
        this.id = id;
    }
}
At hindi nila pinalampas equalsat hashcode. Ilarawan kung ano ang mangyayari kapag ang code ay naisakatuparan
A a1 = new A(1);
A a2 = new A(1);
Map<A, String> hash = new HashMap<>();
hash.put(a1, "1");
hash.get(a2);
*Mabuti na bago ang panayam ay partikular akong gumugol ng ilang araw sa pag-unawa sa mga pangunahing algorithm, kanilang pagiging kumplikado at mga istruktura ng data - nakatulong ito nang malaki, salamat CS50!*
  1. Lumikha ng dalawang pagkakataon ng klase A

  2. Lumilikha kami ng isang walang laman na mapa, na bilang default ay mayroong 16 na basket. Ang susi ay isang bagay ng klase A, kung saan ang equalsat mga pamamaraan ay hindi na-override hashcode.

  3. Ilagay ito a1sa mapa. Upang gawin ito, kalkulahin muna namin ang hash a1.

    Ano ang magiging katumbas ng hash?

    Ang address ng isang cell sa memorya ay isang pagpapatupad ng isang pamamaraan mula sa isang klaseObject

  4. Batay sa hash, kinakalkula namin ang index ng basket.

    Paano natin ito makalkula?

    *Sa kasamaang palad, hindi ako nagbigay ng malinaw na sagot dito. Mayroon kang mahabang numero - isang hash, at mayroong 16 na bucket - kung paano tukuyin ang isang index upang ang mga bagay na may iba't ibang mga hash ay pantay na ibinahagi sa mga bucket? Maaari kong isipin na ang index ay kinakalkula tulad nito:

    int index = hash % buckets.length

    Nasa bahay na nakita ko na ang orihinal na pagpapatupad sa source code ay bahagyang naiiba:

    static int indexFor(int h, int length)
    {
        return h & (length - 1);
    }
  5. Sinusuri namin na walang mga banggaan at nagpasok ng a1.

  6. Lumipat tayo sa pamamaraan get. Ang mga pagkakataong a1 at a2 ay garantisadong may magkaiba hash(magkaiba ang address sa memorya), kaya wala kaming mahahanap para sa key na ito

    Paano kung muling tukuyin natin ito hashcodesa klase A lamang at subukang ipasok muna sa hashmap ang isang pares na may key na a1, at pagkatapos ay may a2?

    Pagkatapos ay makikita muna natin ang nais na basket sa pamamagitan ng hashcode- ang operasyong ito ay isasagawa nang tama. Susunod, simulan natin ang pagpunta sa mga bagay Entrysa LinkedList na naka-attach sa cart at ihambing ang mga susi sa pamamagitan ng equals. kasi equalsay hindi na-override, pagkatapos ay ang batayang pagpapatupad ay kinuha mula sa klase Object- paghahambing sa pamamagitan ng sanggunian. Ang a1 at a2 ay garantisadong may magkaibang mga link, kaya't "makaligtaan" namin ang ipinasok na elementong a1, at ang a2 ay ilalagay sa LinkedList bilang isang bagong node.

    Ano ang konklusyon? Posible bang gamitin ito bilang isang susi sa HashMapisang bagay na may hindi na-override equalshashcode?

    Hindi hindi mo kaya.

Sketch 4. "Kusa nating sirain ito!"

Pagkatapos ng mga tanong tungkol sa Error at Exception, sumunod ang sumusunod na tanong: Sumulat ng isang simpleng halimbawa kung saan itatapon ng isang function ang StackOverflow. *Pagkatapos ay naalala ko kung paano ako sinaktan ng error na ito noong sinusubukan kong magsulat ng ilang recursive function* Ito ay malamang na mangyayari sa kaso ng isang recursive na tawag, kung ang kundisyon para sa pag-alis sa recursion ay hindi wastong tinukoy. *Pagkatapos ay nagsimula akong sumubok ng matalino, sa huli ay tumulong ang tagapanayam, ang lahat ay naging simple*
void sof() {
    sof();
}
Paano naiiba ang error na ito sa OutOfMemory? *Hindi ako sumagot dito, mamaya ko lang napagtanto na ito ay isang tanong tungkol sa kaalaman Stacksa Heapmemorya ng Java (ang mga tawag at reference sa mga bagay ay naka-imbak sa Stack, at ang mga bagay mismo ay nakaimbak sa Heap memory). Alinsunod dito, ang StackOverflow ay itinatapon kapag wala nang espasyo sa Stackmemorya para sa susunod na tawag sa pamamaraan, at OutOfMemoryang espasyo para sa mga bagay ay naubos na sa Heapmemorya*
Ito ang mga sandali mula sa panayam na naaalala ko. Sa huli, natanggap ako para sa isang internship, kaya mayroon akong 2.5 buwan na pagsasanay sa unahan ko at, kung maayos ang lahat, isang trabaho sa kumpanya) Kung may interes, maaari akong magsulat ng isa pang artikulo, sa pagkakataong ito ay mas maliit, na may isang pagsusuri ng isang simple ngunit naglalarawang problema na binigyan ako ng panayam sa ibang kumpanya. Iyon lang po para sa akin, sana ay makatulong ang artikulong ito sa isang tao na mapalalim o maisaayos ang kanilang kaalaman. Maligayang pag-aaral sa lahat!
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION