Top 10 Letlands-baserede softwareudviklingsvirksomheder
Læs om Letlands bedste softwareudviklingsvirksomheder og deres innovative løsninger i vores seneste artikel. Find ud af, hvordan disse teknologiledere kan hjælpe med at løfte din virksomhed.
Hvilke fejl bør man undgå, når man programmerer i Java? I det følgende afsnit besvarer vi dette spørgsmål.
Java er et populært sprog med en etableret position i verden af softwareudvikling. Det er et stærkt og alsidigt programmeringssprog. Omkring 3 milliarder enheder på verdensplan kører på Java og derfor blev der begået mindst 3 milliarder fejl, da den blev brugt. I denne artikel vil vi fokusere på, hvordan man undgår at lave flere.
Det er langt den mest almindelige fejl, jeg er stødt på. I begyndelsen af min karriere begik jeg den også mange gange. Fejlen opstår, når man forsøger at ændre samlingen, mens man itererer gennem den. Den ConcurrentModificationUdtagelse
kan også opstå, når du arbejder med flere tråde, men lad os nu fokusere på et basisscenarie.
Antag, at du har en Samling
af brugere, hvor nogle af dem er voksne, og andre ikke er. Din opgave er at filtrere børnene fra.
for (Bruger : brugere) {
if (!user.isAdult()) {
users.remove(user);
}
}
Når man kører den førnævnte kode, får man ConcurrentModificationUdtagelse
. Hvor gik vi galt i byen? Før vi afsluttede vores iteration, forsøgte vi at fjerne nogle elementer. Det er det, der udløser undtagelsen.
Der er et par tilgange, der kan hjælpe i det tilfælde. Først og fremmest skal du drage fordel af Java 8's godhed - Strøm
.
List adults = users.stream()
.filter(User::isAdult)
.toList();
Brug af en Prædikat
filter har vi gjort det omvendte af den tidligere betingelse - nu bestemmer vi, hvilke elementer der skal inkluderes. Fordelen ved en sådan tilgang er, at det er nemt at kæde andre funktioner sammen efter fjernelsen, f.eks. kort
. Men prøv for guds skyld ikke at gøre noget i stil med nedenstående:
users.stream()
.filter(v -> !v.isAdult())
.forEach(users::remove);
Det kunne også ende i ConcurrentModificationUdtagelse
fordi du ændrer strømkilden. Det kan også give dig nogle flere undtagelser, som ikke er nemme at fejlfinde.
At løse ConcurrentModificationUdtagelse
i et single-thread-scenarie. Du kan også skifte til at bruge direkte Iterator
og dens fjern()
metoden, eller du kan simpelthen lade være med at fjerne elementer under iterationen. Min anbefaling er dog at bruge Vandløb
- Det er 2022.
Da jeg bliver mere og mere involveret i cybersikkerhed, ville jeg ikke være tro mod mig selv, hvis jeg ikke nævnte mindst én Java-fejl der kan føre til et sikkerhedsproblem. Lagring af adgangskoder modtaget fra brugere i en Streng
objekt er netop noget, du skal være bange for.
Problemet (eller måske fordelen) ved Streng
er, at den er uforanderlig. I cyberverdenen skaber det en potentiel trussel, da du ikke kan slette værdien af en engang oprettet Streng
objekt. Den angriber, der får adgang til din computers hukommelse, kan finde adgangskoder i klartekst der.
For det andet er strenge i Java internaliseres af JVM'en og gemmes i PermGen-rummet eller i heap-rummet. Når du opretter en Streng
objektet, bliver det cached, og det bliver først fjernet, når Garbage Collector begynder at gøre sit arbejde. Du kan ikke være sikker på, hvornår din adgangskode bliver slettet fra String-poolen, da Garbage Collector arbejder på en ikke-deterministisk måde.
Den anbefalede tilgang er at bruge char[]
eller, endnu bedre, et bibliotek, der understøtter lagring af adgangskoder som char[]
f.eks.Password4j. Den char[]
er foranderlig og kan ændres, efter at den er blevet initialiseret. Når du har behandlet en adgangskode, kan du bare slette char[]
password-array ved at skrive tilfældige tegn i det. Hvis angriberne får adgang til din computers hukommelse, vil de kun se nogle tilfældige værdier, som ikke har noget at gøre med brugernes adgangskoder.
Nybegyndere og også mere avancerede programmører ved ikke, hvordan de skal håndtere undtagelser korrekt. Deres største synd i den forbindelse er bare at ignorere dem. DET ER ALDRIG EN GOD TILGANG.
Desværre kan vi ikke give dig en universalløsning, der passer til alle. Undtagelse
s' scenarie, du støder på. Du skal tænke på hvert enkelt tilfælde. Men vi kan give dig nogle råd om, hvordan du kommer i gang med det emne.
Ignorerer Undtagelse
er aldrig en god praksis. Undtagelse
s er smidt ind af en eller anden grund, så du bør ikke ignorere dem.
try {...} catch(Exception e) { log(e); }
er sjældent den rigtige tilgang til Undtagelse
håndtering.
Kast Undtagelse
vise en fejldialog til brugeren eller i det mindste tilføje en omfattende besked til loggen.
Hvis du ikke har håndteret dine undtagelser (hvilket du ikke bør), så forklar dig i det mindste i kommentaren.
Desværre er det ret almindeligt at finde en Java-funktion, der i nogle tilfælde returnerer en nul
. Problemet er, at en sådan funktion tvinger sin klient til at udføre et null-tjek på resultatet. Uden det vil NullPointerUdtagelse
bliver kastet.
Den anden ting er at sende en nul
værdi. Hvorfor tænkte du overhovedet på det? I et sådant tilfælde skal funktionen udføre et null-check. Når man bruger tredjepartsbiblioteker, kan man ikke ændre funktionernes inderside. Hvad gør man så?
Endnu vigtigere er det, at andre udviklere, der læser din kode og ser, at du passerer nul
vil nok være forvirret over, hvorfor du vælger en så bizar måde at implementere din funktion på.
Returner ikke en nul
værdi! Nogensinde! Hvis din funktion returnerer en eller anden form for Samling
kan du bare returnere en tom Samling
. Hvis du arbejder med enkeltobjekter, kan du bruge designmønsteret for null-objekter. Siden Java 8, er det implementeret som Valgfrit
. Bortset fra det er den mindst anbefalede fremgangsmåde at rejse en Undtagelse
.
Forhåbentlig er det ikke en fejl, du begår, da det er det mest populære (eller måske næstmest populære efter FizzBuzz) interviewspørgsmål. Som du burde vide nu, er en Streng
objektet er uforanderligt i Java - Når den først er oprettet, kan den ikke ændres. Så sammenkædning af Streng
bogstaver betyder en masse unødvendig hukommelsesallokering. Sammenkædning af Streng
objekter hver gang kræver oprettelse af en midlertidig StringBuilder
objekt og ændre det tilbage til en streng. Derfor er denne løsning absolut ikke egnet, hvis vi ønsker at kombinere et stort antal tegn.
For at løse det problem skal du bruge StringBuilder
. Det skaber et foranderligt objekt, som let kan manipuleres. Du kan selvfølgelig altid bruge StringBuffer
hvis din projekt bruges i en samtidig kontekst.
Når man udvikler software, er det et must at kende det grundlæggende i det sprog, man skriver i, men det er ikke nok. Mange algoritmiske problemer, du støder på, når du implementerer en ny funktion, er allerede blevet løst af en anden. Alt for mange gange har jeg set nogen implementere en sikkerhedsalgoritme fra bunden. En sådan tilgang er fejlbehæftet. En person kan ikke teste en så kompleks løsning grundigt. Den kollektive viden hos hold der består af middelgode programmører, er næsten altid bedre end et enkelt vidunderbarns storhed. Java-udvikler. Du behøver ikke at opfinde den dybe tallerken igen - du skal bare tilpasse den eksisterende løsning, så den passer til dine behov.
Prøv at søge efter biblioteker, der behandler det problem, du arbejder med. Prøv at finde lignende løsninger. Mange af de biblioteker, der er tilgængelige på nettet, er gratis og er blevet finpudset og testet af erfarne udviklere og hele Java-community'et. Vær ikke bange for at bruge dem.
Det er fristende at tro, at vores kode altid vil køre perfekt. Ikke at skrive test til kode er den værste synd i Java softwareudviklere. Mange af os foretrækker manuelle og udforskende tests i stedet for enhedstests, hvilket er skørt. Hvorfor spilde tid på at skrive tests, når du kan fokusere på at levere verdens bedste kode til dit projekt, som SLET ikke har nogen bugs?<joke>. Det viser sig, at virkeligheden er brutal, og vi kan ikke levere kode af høj kvalitet uden at skrive tests.
Du bør altid forberede tests til din kode. Jeg ved godt, at TDD-tilgangen ikke er så nem at vedligeholde, men du bør i det mindste lave tests, der dækker alle de situationer, hvor din kode kan køre. Det inkluderer test af ekstraordinære situationer. Unit-tests er nødvendige. Du er nødt til at lave dem for hver funktion i dit projekt, hvis du vil sikre dig, at din kode er nem at refaktorere og udvide i den videre udvikling.
En ting mere. Oprethold en høj standard for din testkode - det er det hele værd. Det er onkel Bobs råd, og jeg er helt enig i det.
Glem heller ikke andre typer af tests. Integrationstest er en ting, du bør overveje i alle dine projekter.
Privat og offentligt, ikke sandt? Hvordan kan vi glemme dem? Det viser sig, at der er flere. Da du først begyndte at lære Javahar du helt sikkert lært om beskyttede adgangsmodifikatorer. De kan være nyttige i nogle tilfælde, så det er værd at kende til deres eksistens.
Java-udviklere synes ofte at glemme pakkeomfanget. Det er let ikke at huske at bruge det, da det er implicit og ikke kræver nogen Java nøgleord. Pakkeomfanget er vigtigt. Det giver dig mulighed for at teste en beskyttet metode. Beskyttede elementer er tilgængelige fra testklassens sti, så længe pakken er den samme.
Husk den beskyttede modifikator, og at pakkens omfang giver dig mulighed for at teste den.
Det næste skridt efter læring Java SE er at lære at køre Java på servere, hvordan man laver en applikation på virksomhedsniveau.
Nybegyndere falder ofte i en fælde, når de skal lære JavaEE, da der findes et stort antal tutorials om det. Selv 'Thinking in Java', den Java-programmører' nævner JavaEE og siger ikke noget om de andre muligheder.
JavaEE er en sang fra fortiden. I dag er Spring en go-to-ting, og Java EE er bare rart at have. Alle moderne applikationer på virksomhedsniveau bruger Spring, så du bør kraftigt overveje at lære det her.
Læs mere om det:
Den rigtige måde at finde de bedste Java-udviklere på