Eskiz 1. “Sadə görünən üsul”
a rəqəminin b ədədinə bölünməsinin nəticəsini qaytaran metodu necə həyata keçirəcəyinizi yazın. Müsahibi kağız parçasına yazır.int divide(int a, int b) {
}
*Üsul imzası olan vərəqə inamsızcasına nəzər saldım. Nədir?* Mən yazıram:
int divide(int a, int b) {
return a/b;
}
Bu üsulla bağlı hər hansı problem varmı? *Mən həqiqətən axmaq bir axmaqlığı tuturam* Görünür, yox.. Sonra qanuni bir sual gəlir: əgər b=0 olarsa? *Vay, belə davam etsəm, bu ofisdən qovulmaq üzrəyəm!* Hə, əlbəttə. Burada int tipli arqumentlərimiz var, ona görə də Arifmetik İstisna atılacaq. Arqumentlər float və ya double tipli olsaydı, nəticə Sonsuzluq olardı. Bununla bağlı nə edəcəyik? Mən cəhd/tutmaq yazmağa başlayıram
int divide(int a, int b) {
try {
return a/b;
} catch (Exception e) {
e.printStackTrace();
return ... // ??? what the hack?
}
}
*Mən qayıdıram və dondururam: xəta baş verərsə, nəyisə qaytarmaq lazımdır. Bəs bu “nəyisə” hesablamanın nəticəsindən necə fərqləndirmək olar?* Nə qaytaracağıq? Hm... Mən qaytarılan dəyişənin tipini Tam ədədə dəyişərdim və istisna halında null qaytarardım. Təsəvvür edək ki, növü dəyişdirə bilmərik. Birtəhər çıxa bilərik? Bəlkə istisna ilə başqa bir şey edə bilərik? *Budur gəlir* Biz də onu zəng metoduna yönləndirə bilərik! Sağ. Nə kimi görünəcək?
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();
}
}
İstisna ilə məşğul olmaq lazımdırmı? Bəli, çünki biz onu bölmə metodundan açıq şəkildə irəliləyirik. (*Burada səhv etdim! Müsahibənin düzgün cavaba çatmasına səbəb olan suallar aşağıdakılardır*) Və Arifmetik İstisna - bu hansı istisnadır - yoxlanılır, yoxsa yoxlanılır? Bu Runtime istisnasıdır, yəni işarələnməmişdir. *Budur, qatil sualı gəlir* Beləliklə, sizin sözlərinizlə belə çıxır ki, əgər metod imzasında Arifmetik İstisna atdığını qeyd etsək, o, yoxlanılan istisna oldu? *Uf!* Yəqin ki... yox. Bəli, getdi. İmzada throws /checked exception/ işarəsini göstərsək, yalnız metodun istisna ata biləcəyini xəbərdar edirik, lakin onu çağırış metodunda idarə etmək lazım deyil. Bu sıralanır. Səhvlərdən qaçmaq üçün edə biləcəyimiz başqa bir şey varmı? *Bir qədər fikirləşdikdən sonra* Bəli, biz də yoxlaya bilərik (b==0). Və bir az məntiq həyata keçirin. Sağ. Beləliklə, 3 yolla gedə bilərik:
- cəhd/tutmaq
- atır – çağırış metoduna yönləndirmə
- arqument yoxlanışı
divide
sizcə hansı üsula üstünlük verilir? İstisnanı çağırış metoduna yönləndirməyi seçərdim, çünki... int
bölmə metodunda bu istisnanın necə işlənəcəyi və xəta baş verdikdə hansı növ nəticənin qaytarılacağı aydın deyil . Çağırış metodunda isə onun sıfıra bərabər olub olmadığını yoxlamaq üçün b arqumentindən istifadə edərdim. Deyəsən bu cavab müsahibini qane etdi, amma düzünü desəm bu cavabın birmənalı olduğuna əmin deyiləm))
Eskiz 2. “Kim daha sürətli?”
Standart sualdan sonra, ArrayList-in LinkedList-dən nə ilə fərqləndiyi ortaya çıxdı: Nə daha tez baş verəcək - elementin ortasınaArrayList
və ya ortasına daxil edilməsi LinkedList
? *Budur, atladım, hər yerdə “ siyahının ortasına elementləri daxil etmək və ya silmək üçün istifadə edin” kimi bir şey oxuduğumu xatırladım . LinkedList
Evdə hətta JavaRush mühazirələrini iki dəfə yoxladım, belə bir ifadə var: “Əgər kolleksiyanın ortasına çoxlu elementlər daxil etmək (və ya silmək) istəyirsənsə, onda LinkedList
. Bütün digər hallarda - ArrayList
.” Avtomatik olaraq cavablandırılır* ilə daha sürətli olacaq LinkedList
. Zəhmət olmasa aydınlaşdırın
- Ortaya bir element daxil etmək üçün
ArrayList
biz siyahıdakı elementi sabit zamanda tapırıq və sonra daxil edilmiş elementin sağındakı elementlərin indekslərini xətti vaxtda yenidən hesablayırıq. - Üçün
LinkedList
.. Biz əvvəlcə xətti vaxtda ortaya çatırıq və sonra qonşu elementlər üçün keçidləri dəyişdirərək sabit zamanda element daxil edirik.
LinkedList
? Belə çıxır ki, onu siyahının birinci yarısına daxil etdikdə. Məsələn, onu ən başlanğıcda daxil etsəniz, ArrayList
quyruğa qədər bütün indeksləri yenidən hesablamalı olacaqsınız, ancaq LinkedList
birinci elementin istinadını dəyişdirməlisiniz. Əxlaq: hətta JavaRush-da yazılanların hamısına sözün həqiqi mənasında inanmayın!)
Eskiz 3. “Bərabərlər və hashcode olmasaydı, biz harada olardıq!”
Bərabərlər və hashcode haqqında söhbət çox uzun idi - onu necə ləğv etmək olar, hansı tətbiqetməObject
, başlıq altında nə baş verir, element daxil edildikdə HashMap
və s. Sadəcə fikrimcə maraqlı olan bir sıra məqamları qeyd edəcəyəm* Təsəvvür edin ki, biz sinif yaratmışıq
public class A {
int id;
public A(int id) {
this.id = id;
}
}
Və onlar ləğv etmədilər equals
və hashcode
. Kod icra edildikdə nə baş verəcəyini təsvir edin
A a1 = new A(1);
A a2 = new A(1);
Map<A, String> hash = new HashMap<>();
hash.put(a1, "1");
hash.get(a2);
*Yaxşı ki, müsahibədən əvvəl mən əsas alqoritmləri, onların mürəkkəbliyini və məlumat strukturlarını başa düşmək üçün xüsusi olaraq bir neçə gün sərf etdim - bu, çox kömək etdi, təşəkkürlər CS50!*
-
A sinfinin iki nümunəsini yaradın
-
Varsayılan olaraq 16 səbət olan boş bir xəritə yaradırıq. Açar A sinifinin obyektidir, burada
equals
və metodları ləğv edilmirhashcode
. -
a1
Xəritəyə qoyun . Bunu etmək üçün əvvəlcə hashı hesablayırıqa1
.Haş nəyə bərabər olacaq?
Yaddaşdakı hüceyrənin ünvanı bir sinifdən metodun həyata keçirilməsidir
Object
-
Hash əsasında biz səbət indeksini hesablayırıq.
Bunu necə hesablaya bilərik?
*Təəssüf ki, burada dəqiq cavab vermədim. Sizin uzun nömrəniz var - hash və 16 vedrə var - indeksi necə təyin etmək olar ki, müxtəlif hashlərə malik obyektlər vedrələr arasında bərabər paylansın? Təsəvvür edə bilərdim ki, indeks belə hesablanır:
int index = hash % buckets.length
Artıq evdə mən mənbə kodundakı orijinal tətbiqin bir qədər fərqli olduğunu gördüm:
static int indexFor(int h, int length) { return h & (length - 1); }
-
Toqquşmaların olmadığını yoxlayırıq və a1 daxil edirik.
-
Gəlin üsula keçək
get
. a1 və a2 nümunələrinin fərqli (yaddaşda fərqli ünvan) olacağına zəmanət verilirhash
, ona görə də bu açar üçün heç nə tapa bilməyəcəyik.Əgər biz onu yalnız
hashcode
A sinfində yenidən təyin etsək və heşmapa əvvəlcə a1 açarı, sonra isə a2 ilə cüt daxil etməyə çalışsaq necə olar?Sonra əvvəlcə istədiyiniz səbəti tapacağıq
hashcode
- bu əməliyyat düzgün yerinə yetiriləcəkdir.Entry
Sonra, səbətə əlavə edilmiş LinkedList-dəki obyektləri nəzərdən keçirməyə başlayaq və açarları ilə müqayisə edəkequals
. Çünkiequals
ləğv edilmir, sonra əsas icra sinifdən götürülürObject
- istinadla müqayisə. a1 və a2-nin fərqli keçidlərə malik olacağına zəmanət verilir, ona görə də daxil edilmiş a1 elementini “qaçıracağıq” və a2 LinkedList-ə yeni qovşaq kimi yerləşdiriləcək.Nəticə nədir?
HashMap
Qeyri-aşkar edilmiş obyektdə açar kimi istifadə etmək mümkündürmüequalshashcode
?Yox bacarmazsan.
Eskiz 4. “Gəlin onu qəsdən sındıraq!”
Xəta və İstisna ilə bağlı suallardan sonra aşağıdakı sual gəldi: Funksiyanın StackOverflow atacağı sadə bir nümunə yazın. *Sonra bəzi rekursiv funksiyanı yazmağa çalışarkən bu xətanın mənə necə əziyyət verdiyini xatırladım* Bu, rekursiv çağırış zamanı, əgər rekursiyadan çıxmaq şərti düzgün göstərilməyibsə, yəqin ki, baş verəcək. *Sonra bir az ağıllılaşmağa başladım, axırda müsahibim kömək etdi, hər şey sadə oldu*void sof() {
sof();
}
Bu səhv nə ilə fərqlənir OutOfMemory
? *Burada cavab vermədim, yalnız sonradan başa düşdüm ki, bu, Java yaddaşını bilməklə bağlı sualdır Stack
( Heap
obyektlərə edilən zənglər və istinadlar Stack-də, obyektlərin özləri isə Heap yaddaşında saxlanılır). Stack
Müvafiq olaraq, növbəti metod çağırışı üçün yaddaşda yer qalmadıqda və OutOfMemory
obyektlər üçün yer yaddaşda tükəndikdə StackOverflow atılır Heap
*
Müsahibədən yadımda qalan anlardır. Sonda təcrübə keçməyə qəbul olundum, ona görə də qarşıda 2,5 aylıq təlim və hər şey yolunda getsə şirkətdə bir iş var) Maraq olarsa, bu dəfə daha kiçik bir məqalə yaza bilərəm. başqa bir şirkətdə müsahibə aldığım sadə, lakin illüstrativ problemin təhlili. Hamısı mənim üçün budur, ümid edirəm ki, bu məqalə kiməsə biliklərini dərinləşdirməyə və ya təşkil etməyə kömək edəcək. Hər kəsə xoş öyrənmə!
GO TO FULL VERSION