Эскиз 1. «Бір қарағанда қарапайым әдіс»
а санын b санына бөлудің нәтижесін беретін әдісті қалай орындайтыныңызды жазыңыз.Интервьюер қағазға жазадыint divide(int a, int b) {
}
*Әдіс қолтаңбасы бар қағазға сенбей қарадым. Бұл не?* Мен жазамын:
int divide(int a, int b) {
return a/b;
}
Бұл әдіспен проблемалар бар ма? *Мен шынымен ақымақ ақымақты ұстап жатырмын* Жоқ сияқты.. Келесі заңды сұрақ туындайды: b=0 болса ше? *Ой, осылай жүре берсем, мені кеңседен қуып жіберетін шығармын!* Иә, әрине. Мұнда int түріндегі дәлелдер бар, сондықтан арифметикалық ерекшелік тасталады. Егер аргументтер float немесе double типті болса, нәтиже Infinity болар еді. Бұл туралы не істейміз? Мен try/catch деп жаза бастадым
int divide(int a, int b) {
try {
return a/b;
} catch (Exception e) {
e.printStackTrace();
return ... // ??? what the hack?
}
}
*Мен оралып, қатып қалуым керек: қате болған жағдайда бір нәрсені қайтару керек. Бірақ бұл «бірдеңені» есептеу нәтижесінен қалай ажыратуға болады?* Біз не қайтарамыз? Мм... Мен қайтарылатын айнымалының түрін Integer деп өзгертетін едім және ерекше жағдайда нөлді қайтаратын едім. Түрін өзгерте алмаймыз деп елестетейік. Біз қандай да бір жолмен шыға аламыз ба? Мүмкін біз ерекшеліктен басқа бірдеңе жасай аламыз ба? *Міне, келді* Біз оны шақыру әдісіне де жібере аламыз! Дұрыс. Ол қандай болады?
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();
}
}
Ерекше жағдайды өңдеу қажет пе? Иә, өйткені біз оны бөлу әдісінен анық жібереміз. (*Мен бұл жерде қателесіппін! Төменде сұхбат алушының дұрыс жауапқа әкелетін жетекші сұрақтары берілген*) Ал арифметикалық ерекшелік - бұл қандай ерекшелік - тексерілген немесе белгіленбеген? Бұл Орындалу уақытының ерекше жағдайы, яғни құсбелгі алынбаған. *Міне, өлтіруші сұрақ туындайды* Сонымен, сіздің сөзіңізше, егер біз әдіс қолтаңбасында арифметикалық ерекшелік тастайтынын көрсетсек, онда ол тексерілген ерекшелік болды ма? *Уф!* Мүмкін... жоқ. Иә, кетті. Қолтаңбада тастауларды /тексерілмеген ерекшелік/ көрсетсек, әдіс ерекше жағдайды шығара алатынын ғана ескертеміз, бірақ оны шақыру әдісінде өңдеу қажет емес. Бұл реттелді. Қателіктерді болдырмау үшін біз жасай алатын тағы бір нәрсе бар ма? *Біраз ойланғаннан кейін* Иә, біз де (b==0) тексере аламыз. Және біраз логиканы орындаңыз. Дұрыс. Сондықтан біз 3 жолмен жүре аламыз:
- көріңіз/ұстаңыз
- throws – шақыру әдісіне бағыттау
- аргументтерді тексеру
divide
қай әдіс артықшылықты деп ойлайсыз? Мен ерекше жағдайды шақыру әдісіне жіберуді таңдар едім, себебі... int
бөлу әдісінде бұл ерекшелікті қалай өңдеу керек және қате болған жағдайда қандай нәтиже түрі қайтарылатыны анық емес . Ал шақыру әдісінде мен оның нөлге тең екенін тексеру үшін b аргументін қолданар едім. Бұл жауап сұхбат берушіні қанағаттандырған сияқты, бірақ шынымды айтсам, бұл жауаптың бір мәнді екеніне сенімді емеспін))
Эскиз 2. «Кім жылдам?»
Стандартты сұрақтан кейін ArrayList LinkedList-тен қалай ерекшеленеді: Не тезірек болады - элементті ортағаArrayList
немесе ортаға кірістіру LinkedList
? *Осы жерде мен секірдім, мен барлық жерде « LinkedList
тізімнің ортасына элементтерді енгізу немесе жою үшін пайдаланыңыз» сияқты нәрсені оқығанымды есіме түсірдім. Үйде мен JavaRush лекцияларын екі рет тексердім, мынадай сөз тіркесі бар: «Егер сіз топтаманың ортасына көптеген элементтерді кірістіргіңіз (немесе жойғыңыз) болсаңыз, онда LinkedList
. Барлық басқа жағдайларда - ArrayList
. Автоматты түрде жауап береді* Ол арқылы жылдамырақ болады LinkedList
. Түсіндіріңізші өтінемін
- Элементті ортаға енгізу үшін
ArrayList
біз тізімдегі элементті тұрақты уақытта табамыз, содан кейін кірістірілгеннің оң жағындағы элементтердің индекстерін сызықтық уақытта қайта есептейміз. - Үшін
LinkedList
.. Біз алдымен ортасына сызықтық уақытта жетеміз, содан кейін көрші элементтердің сілтемелерін өзгерте отырып, тұрақты уақытта элементті енгіземіз.
LinkedList
жылдамырақ? Оны тізімнің бірінші жартысына енгізгенімізде шығады. Мысалы, егер сіз оны ең басында кірістірсеңіз, сіз ArrayList
ең құйрығына дейін барлық индекстерді қайта есептеуіңіз керек, бірақ LinkedList
бірінші элементтің сілтемесін өзгертуіңіз керек. Моральдық: тіпті JavaRush-те жазылғанның бәріне сенбеңіз!)
Эскиз 3. «Теңдерсіз және хэшcodeсыз біз қайда болар едік!»
Теңдіктер және хэшcode туралы әңгіме өте ұзақ болды - оны қалай қайта анықтау керек, ішінде қандай іске асыруObject
, қалпақ астында не болады, элемент ішіне енгізілгенде HashMap
және т.б. Мен өзімнің ойымша қызықты бірнеше жайттарды ғана келтіремін* Біз сыныпты құрдық деп елестетіңіз
public class A {
int id;
public A(int id) {
this.id = id;
}
}
Және олар жоққа шығарған жоқ equals
және hashcode
. Код орындалғанда не болатынын сипаттаңыз
A a1 = new A(1);
A a2 = new A(1);
Map<A, String> hash = new HashMap<>();
hash.put(a1, "1");
hash.get(a2);
*Сұхбат алдында мен негізгі алгоритмдерді, олардың күрделілігін және деректер құрылымдарын түсінуге арнайы екі күн жұмсағаным жақсы болды - бұл көп көмектесті, CS50-ге рахмет!*
-
А класының екі данасын жасаңыз
-
Біз бос картаны жасаймыз, ол әдепкі бойынша 16 себетке ие. Кілт А класының an objectісі болып табылады, онда
equals
және әдістері қайта белгіленбейдіhashcode
. -
Оны
a1
картаға салыңыз. Ол үшін алдымен хэшті есептеймізa1
.Хэш неге тең болады?
Жадтағы ұяшықтың addressі сыныптағы әдісті жүзеге асыру болып табылады
Object
-
Хэш негізінде біз себет индексін есептейміз.
Оны қалай есептей аламыз?
*Өкінішке орай, мен бұл жерде нақты жауап бермедім. Сізде ұзын сан бар - хэш және 16 шелек бар - әртүрлі хэштері бар нысандар шелектерге біркелкі таралатындай индексті қалай анықтауға болады? Мен индекстің келесідей есептелгенін елестете аламын:
int index = hash % buckets.length
Үйде мен бастапқы codeтағы бастапқы енгізудің сәл өзгеше екенін көрдім:
static int indexFor(int h, int length) { return h & (length - 1); }
-
Біз соқтығыстардың жоқтығын тексереміз және a1 енгіземіз.
-
Әдіске көшейік
get
.hash
a1 және a2 даналарының басқа (жадтағы басқа мекенжай) болуы кепілдендірілген , сондықтан біз бұл кілт үшін ештеңе таба алмаймыз.Егер біз оны тек
hashcode
А класында қайта анықтасақ және хэшмапқа алдымен a1 пернесі бар жұпты, содан кейін a2 пернесін енгізуге тырыссақ ше?Содан кейін алдымен біз қажетті себетті табамыз
hashcode
- бұл операция дұрыс орындалады.Entry
Әрі қарай, арбаға тіркелген LinkedList ішіндегі нысандарды қарап шығуды және кілттерді арқылы салыстыруды бастаймызequals
. Өйткеніequals
қайта белгіленбейді, содан кейін базалық іске асыру сыныптан алынадыObject
- сілтеме бойынша салыстыру. a1 және a2 әр түрлі сілтемелерге кепілдік береді, сондықтан біз енгізілген a1 элементін «жіберіп аламыз», ал a2 LinkedList тізімінде жаңа түйін ретінде орналастырылады.Қорытынды қандай?
HashMap
Қайта анықталмаған нысанда кілт ретінде пайдалануға болады маequalshashcode
?Жоқ болмайды.
Эскиз 4. «Әдейі бұзайық!»
Қате және Ерекшелік туралы сұрақтардан кейін келесі сұрақ туындады: Функция StackOverflow жіберетін қарапайым мысалды жазыңыз. *Содан кейін мен кейбір рекурсивті функцияны жазуға тырысқанда бұл қатенің мені қалай қиналғанын есіме түсірдім* Бұл рекурсивті шақыру жағдайында, егер рекурсиядан шығу шарты дұрыс көрсетілмесе, орын алуы мүмкін. *Сосын мен аздап ақылды бола бастадым, соңында сұхбат беруші көмектесті, бәрі қарапайым болып шықты*void sof() {
sof();
}
Бұл қатенің айырмашылығы неде OutOfMemory
? *Мен бұл жерде жауап бермедім, кейінірек бұл Java жады туралы сұрақ екенін түсіндім Stack
( Heap
an objectілерге қоңыраулар мен сілтемелер Стекте сақталады, ал нысандардың өзі үйме жадыда сақталады). Stack
Тиісінше, келесі әдісті шақыру үшін жадта бос орын болмаған кезде және OutOfMemory
жадта нысандарға арналған орын таусылғанда, StackOverflow жойылады Heap
*
Сұхбаттан есте қалған сәттері осылар. Соңында тағылымдамадан өтуге қабылдандым, сондықтан менде 2,5 ай оқу, егер бәрі ойдағыдай болса, компанияда жұмыс бар) Қызығушылығы болса, осы жолы кішірек, басқа мақала жаза аламын. маған басқа компанияда сұхбат берілген қарапайым, бірақ көрнекі мәселенің талдауы. Мұның бәрі мен үшін, бұл мақала біреуге білімін тереңдетуге немесе жүйелеуге көмектеседі деп үміттенемін. Барлығына оқуға сәттілік!
GO TO FULL VERSION