Milliseid vigu tuleks Java keeles programmeerimisel vältida? Järgnevas teoses vastame sellele küsimusele.
Java on populaarne keel, millel on väljakujunenud positsioon maailma tarkvaraarendus. See on tugev ja mitmekülgne programmeerimiskeel. Ligikaudu 3 miljardit seadet maailmas töötavad Java ja seetõttu tehti selle kasutamisel vähemalt 3 miljardit viga. Selles artiklis keskendume sellele, kuidas mitte enam ühtegi teha.
1. Samaaegse muutmise erandi saamine
See on kaugelt kõige levinum viga, millega ma kokku puutusin. Oma karjääri algusaegadel tegin ka mina seda mitu korda. See viga tekib siis, kui te üritate kollektsiooni muuta, kui te seda läbi itereerite. . ConcurrentModificationException võib tekkida ka siis, kui töötate mitme niidiga, kuid keskendume praegu põhistsenaariumile.
Oletame, et teil on Kollektsioon kasutajatest, kellest osa on täiskasvanud ja osa mitte. Teie ülesanne on filtreerida välja lapsed.
for (User : users) {
if (!user.isAdult()) {
users.remove(user);
}
}
Eespool nimetatud programmi käivitamine kood lõpeb saamisega ConcurrentModificationException. Kus me läksime valesti? Enne iteratsiooni lõpetamist proovisime eemaldada mõned elemendid. See ongi see, mis tekitab erandi.
Kuidas ma saan seda vältida?
Sellisel juhul võib abi olla mitmest lähenemisviisist. Kõigepealt kasutage ära Java 8 headus - Stream.
List adults = users.stream()
.filter(User::isAdult)
.toList();
Kasutades Predikaat filtri abil oleme teinud eelmise tingimuse pöördvõrdluse - nüüd määrame elemendid, mida lisada. Sellise lähenemise eelis on see, et pärast eemaldamist on lihtne ahelata teisi funktsioone, nt. kaart. Aga jumala pärast. palun ärge püüdke teha midagi sellist nagu allpool:
Samuti võib see sattuda ConcurrentModificationException sest te muudate voo allikat. Samuti võib see anda teile rohkem erandeid, mida ei ole lihtne kõrvaldada.
Lahendada ConcurrentModificationException ühe niidi stsenaariumis. te võite ka minna üle otse kasutamisele Iteraator ja selle remove() meetodi abil või siis lihtsalt ei eemalda elemente iteratsiooni ajal. Minu soovitus on siiski kasutada Voolud - see on 2022.
2. Paroolide salvestamine stringidena
Kuna ma tegelen üha enam küberturvalisusega, ei oleks ma enda vastu tõene, kui ma ei mainiks vähemalt ühte Java viga mis võib viia turvaprobleemini. Kasutajatelt saadud paroolide salvestamine String objekt on just see, mida te peaksite kartma.
Küsimus (või võib-olla eelis) String on see, et see on muutumatu. Küberseedis loob see potentsiaalse ohu, kuna te ei saa kustutada kord loodud väärtust. String objekt. Ründaja, kes saab juurdepääsu teie arvuti mälule, võib sealt leida lihtsa tekstiga paroole.
Teiseks, stringid Java on JVM-i poolt interneeritud ja salvestatud PermGen ruumi või kuhja ruumi. Kui te loote String objekt, siis see salvestatakse vahemällu ja see eemaldatakse alles siis, kui prügikoristaja hakkab oma tööd tegema. Te ei saa olla kindel, millal teie parool String-poolsest kustutatakse, kuna Garbage Collector töötab mittedeterministlikult.
Kuidas seda vältida?
Soovitatav lähenemisviis on kasutada char[] või veel parem, raamatukogu, mis toetab paroolide salvestamist kui char[], nt.Password4j. . char[] massiiv on muutuv ja seda saab pärast initsialiseerimist muuta. Pärast salasõna töötlemist saab lihtsalt kustutada char[] salasõna massiivi, kirjutades sinna juhuslikke tähti. Kui ründajad saavad juurdepääsu arvuti mälule, näevad nad ainult juhuslikke väärtusi, millel ei ole midagi pistmist kasutajate paroolidega.
3. Erandite (mitte)käsitlemine
Algajad ja ka edasijõudnud programmeerijad ei tea, kuidas erandeid õigesti käsitleda. Nende peamine patt selles küsimuses on lihtsalt nende ignoreerimine. SEE EI OLE KUNAGI HEA LÄHENEMINE.
Kahjuks ei saa me anda teile hõbedast lahendust, mis sobiks igasse Erands" stsenaarium, millega te kokku puutute. Te peate mõtlema igale juhtumile eraldi. Siiski saame teile anda mõned nõuanded, kuidas selle teemaga alustada.
Kuidas ma saan seda vältida?
Ignoreerimine Erands ei ole kunagi hea tava. Erands on mingil põhjusel sisse visatud, nii et te ei tohiks neid ignoreerida.
try {...} catch(Exception e) { log(e); } on harva õige lähenemine Erand käitlemine.
Rethrow Erandnäidata kasutajale veadialoogi või vähemalt lisada logisse põhjalik teade.
Kui te jätsite oma erandid käsitlemata (mida te ei peaks tegema), siis selgitage vähemalt kommentaaris.
4. Kasutades null
Kahjuks on üsna tavaline, et Java funktsioon, mis mõnel juhul tagastab null. Probleem seisneb selles, et selline funktsioon sunnib oma klienti kontrollima tulemuse nulli. Ilma selleta on NullPointerException visatakse.
Teine asi on läbida null väärtus. Miks sa üldse selle peale mõtlesid? Sellisel juhul peab funktsioon teostama null-kontrolli. Kolmandate osapoolte raamatukogusid kasutades ei saa funktsioonide sisemust muuta. Mis siis?
Veelgi olulisem on see, et teised arendajad, kes teie koodi loevad ja näevad, et te läbite null on tõenäoliselt segaduses, miks te valisite oma funktsiooni rakendamiseks sellise veidra viisi.
Kuidas ma saan seda vältida?
Ärge tagastage null väärtus! Kunagi! Juhul, kui teie funktsioon tagastab mingi Kollektsioon, võite lihtsalt tagastada tühja Kollektsioon. Kui tegelete üksikute objektidega, saate kasutada null-objekti disainimustrit. Kuna Java 8, seda rakendatakse järgmiselt Valikuline. Muidu on kõige vähem soovitatav lähenemisviis, mis hõlmab tõstmist Erand.
5. Raske stringide ühendamine
Loodetavasti ei ole see viga, mida teete, sest see on kõige populaarsem (või võib-olla teine kõige populaarsem pärast FizzBuzz'i) intervjuuküsimus. Nagu te juba peaksite teadma, on String objekt on muutumatu Java - kui see on loodud, ei saa seda enam muuta. Nii et aheldamine String literaalide kasutamine tähendab palju tarbetut mälu eraldamist. Kontsateerimine String objektid nõuavad iga kord ajutise StringBuilder objekti ja muutes selle tagasi stringiks. Seetõttu ei ole see lahendus absoluutselt sobiv, kui tahame kombineerida suurt arvu sümboleid.
Kuidas ma saan seda vältida?
Selle probleemi lahendamiseks kasutage StringBuilder. See loob muutuva objekti, mida saab kergesti manipuleerida. Loomulikult võite alati kasutada StringBuffer kui teie projekt kasutatakse samaaegses kontekstis.
6. Olemasolevate lahenduste mittekasutamine
Tarkvara arendamisel on vaja tunda selle keele põhitõdesid, milles te kirjutate, kuid sellest ei piisa. Paljud algoritmilised probleemid, millega te uue funktsiooni rakendamisel kokku puutute, on juba keegi teine lahendanud. Liiga palju kordi olen näinud, kuidas keegi rakendab turvaalgoritmi nullist. Selline lähenemine on vigade ohtlik. Üks inimene ei suuda sellist keerulist lahendust põhjalikult testida. Kollektiivsed teadmised meeskond mis koosneb keskmiselt edasijõudnud programmeerijatest, on peaaegu alati parem kui ühe imelapse suursugusus Java arendaja. Teil ei ole vaja ratast uuesti leiutada - te peate lihtsalt olemasolevat lahendust oma vajadustele vastavaks kohandama.
Kuidas ma saan seda vältida?
Proovige otsida raamatukogusid, mis tegelevad teie poolt käsitletava probleemiga. Proovige leida sarnaseid lahendusi. Paljud veebis saadaval olevad raamatukogud on tasuta ning neid on kogenud arendajad ja kogu Java-kogukond lihvinud ja testinud. Ärge kartke neid kasutada.
7. Ei leia piisavalt aega testide kirjutamiseks
On ahvatlev uskuda, et meie kood töötab alati ideaalselt. Koodile testide kirjutamata jätmine on kõige hullem patt. Java tarkvaraarendajad. Paljud meist eelistavad ühiktestide asemel manuaalseid ja uurimuslikke teste, mis on hullumeelsus. Miks raisata aega testide kirjutamisele, kui saab keskenduda sellele, et pakkuda oma projektile maailma parimat koodi, milles EI OLE VIGAID?" <nalja>. Tuleb välja, et reaalsus on jõhker ja me ei saa pakkuda kvaliteetset koodi ilma teste kirjutamata.
Kuidas ma saan seda vältida?
Te peaksite alati oma koodi jaoks teste ette valmistama. Ma tean, et TDD lähenemist ei ole nii lihtne hooldada, kuid te peaksite vähemalt esitama testid, mis hõlmavad kõiki tingimusi, mille korral teie koodi saab käivitada. See hõlmab ka erandlike olukordade testimist. Ühiktestid on vajalikud. Te peate neid esitama oma projekti iga funktsiooni jaoks, kui soovite tagada, et teie koodi on lihtne refaktorida ja laiendada edasise arenduse käigus.
Veel üks asi. Hoidke oma testkoodi kõrget taset - see on seda väärt. See on onu Bobi nõuanne ja ma olen sellega täiesti nõus.
Ärge unustage ka muud liiki teste. Integratsioonitestid on asi, mida peaksite igas projektis arvesse võtma.
8. Juurdepääsu modifitseerijate unustamine
Era- ja avalik, eks ole? Kuidas me saame neid unustada. Tuleb välja, et neid on rohkem. Kui sa hakkasid esimest korda õppima Java, siis kindlasti õppisid sa kaitstud juurdepääsu modifikaatorite kohta. Need võivad mõnel juhul olla kasulikud, seega tasub nende olemasolust teada.
Java arendajad näivad sageli unustavat paketi ulatuse. Selle kasutamisest on lihtne mitte mäletada, kuna see on kaudne ja ei nõua mingit Java märksõnad. Paketi ulatus on oluline. See võimaldab teil testida kaitstud meetodit. Kaitstud elemendid on kättesaadavad testklassi tee kaudu, kui pakett on sama.
Kuidas ma saan seda vältida?
Pidage meeles kaitstud modifikaatorit ja seda, et paketi ulatus võimaldab teil seda testida.
9. Puhta JavaEE kasutamine Springi asemel
Järgmine samm pärast õppimist Java SE on õppida, kuidas juhtida Java serverites, kuidas teha ettevõtte tasandi rakendust.
Algajad satuvad sageli JavaEE õppimise lõksu, kuna selle kohta on olemas suur hulk õpetusi. Isegi "Thinking in Java", mis on Java programmeerijad' piibel, mainib JavaEE-d ja ei ütle midagi teiste võimaluste kohta.
Kuidas ma saan seda vältida?
JavaEE on mineviku laul. Tänapäeval on Springi asi ja Java EE on lihtsalt tore, et see on olemas. Iga kaasaegne ettevõtte tasemel rakendus kasutab Springi, seega tuleks tungivalt kaaluda õppimist seda siin.