Zoals je weet, raden we beginnende codeerders aan om programmeertalen te leren met Java, en CodeGym heeft alles om het leerproces van Java verteerbaar te maken, zelfs voor de meest onvoorbereide studenten. Maar hoewel gamificatie-elementen, een gemakkelijk verhaal en grappige personages dit proces helpen vergemakkelijken, gaat het leren van de basisprincipes van Java zelden zonder uitdagingen voor de meeste nieuwe leerlingen.
Vandaag gaan we kijken naar enkele van de moeilijkste gebieden in de basisprincipes van Java-programmeren, proberen te begrijpen waarom veel mensen ze moeilijk vinden en of er iets voor u aan te doen is.
1. Generieke geneesmiddelen
Generics in Java zijn typen die een parameter hebben. Wanneer u een generiek type maakt, geeft u niet alleen een type op, maar ook het gegevenstype waarmee het zal werken. Generics worden door Java-leerlingen vaak genoemd als een van de moeilijkste onderdelen van Java voor hen om te begrijpen. “Mijn belangrijkste probleem is nog steeds het omgaan met Generics. Het is veel gemakkelijker als je methoden hebt met parameters die je moet volgen, maar het wordt verwarrend als je je eigen methoden moet schrijven', zei een anonieme Java-leerling.
Tips en aanbevelingen
Hier is
een mening over Generics in Java van Ravi Reddy, een ervaren programmeur en universiteitsprofessor: “Java Generics doen één ding dat C++-templates niet doen: typeveiligheid implementeren. De implementatie van C++-sjablonen is een eenvoudige pre-processortruc en garandeert geen typeveiligheid. Generics in Java zijn als C ++ -sjablonen, maar met extra typebeveiliging. En IMHO, typeveiligheid is een essentieel kenmerk van elke goede ontwikkelomgeving. En ja! Ze kunnen verwarrend zijn vanwege onze mentale verschuivingen tussen de parameters en de typen. Maar ik geloof dat het de moeite waard is om tijd te besteden om ze onder de knie te krijgen. Omdat ik merkte dat ik veel beter 'nadacht' in Java toen ik interfaces en generieke codes eenmaal had begrepen."
2. Multithreading
Multithreading in Java is een proces waarbij twee of meer threads gelijktijdig worden uitgevoerd om een maximaal gebruik van de CPU door de toepassing te bereiken. Multithreading lost zeer belangrijke taken op en kan onze programma's sneller maken. Vaak vele malen sneller. Maar het wordt beschouwd als een van de onderwerpen waar veel nieuwe Java-studenten de neiging toe hebben vast te lopen. Allemaal omdat multithreading ook problemen kan veroorzaken in plaats van ze op te lossen. Er zijn twee specifieke problemen die multithreading kan veroorzaken: impasse en race-omstandigheden. Deadlock is een situatie waarin meerdere threads wachten op bronnen die door elkaar worden vastgehouden en geen van hen kan blijven draaien. Een raceconditie is een ontwerpfout in een multithreaded systeem of applicatie, waarbij de werking van het systeem of de applicatie afhangt van de volgorde waarin delen van de code worden uitgevoerd.
Tips en aanbevelingen
Hier is een goede
aanbevelingover hoe om te gaan met multithreading van S.Lott, een software-architect en actieve gebruiker van StackExchange, een populaire Q&A-website: “Multithreading is eenvoudig. Het coderen van een applicatie voor multi-threading is heel, heel eenvoudig. Er is een simpele truc, en deze is om een goed ontworpen berichtenwachtrij te gebruiken (niet je eigen wachtrij) om gegevens tussen threads door te geven. Het moeilijkste is om meerdere threads op een of andere manier op magische wijze een gedeeld object te laten bijwerken. Dat is wanneer het foutgevoelig wordt omdat mensen geen aandacht besteden aan de aanwezige raceomstandigheden. Veel mensen gebruiken geen berichtenwachtrijen en proberen gedeelde objecten bij te werken en problemen voor zichzelf te creëren. Wat moeilijk wordt, is het ontwerpen van een algoritme dat goed werkt bij het doorgeven van gegevens tussen verschillende wachtrijen. Dat is moeilijk.
3. Classpath-problemen
Classpath-fouten worden ook beschouwd als een van de meest geklaagde problemen waarmee Java-ontwikkelaars in hun dagelijkse werk worden geconfronteerd. “Classpath-problemen kunnen tijdrovend zijn om te debuggen en hebben de neiging om op de slechtst mogelijke tijden en plaatsen op te treden: vóór releases en vaak in omgevingen waar het ontwikkelingsteam weinig tot geen toegang heeft. Ze kunnen ook op IDE-niveau plaatsvinden en een bron van verminderde productiviteit worden”,
zegt Vasco Ferreira, een ervaren Java/Javascript-ontwikkelaar en auteur van tutorials over programmeren.
Tips en aanbevelingen
“Classpath-problemen zijn niet zo laag of ongenaakbaar als ze in eerste instantie lijken. Het draait allemaal om zip-bestanden (jars) die wel of niet aanwezig zijn in bepaalde mappen, hoe je die mappen kunt vinden en hoe je het klassenpad kunt debuggen in omgevingen met beperkte toegang. Door een beperkte set concepten te kennen, zoals Class Loaders, de Class Loader Chain en Parent First / Parent Last-modi, kunnen deze problemen effectief worden aangepakt”, legt de expert uit.
4. Polymorfisme en correct gebruiken
Als het gaat om de principes van OOP, zeggen veel mensen dat ze polymorfisme moeilijk konden begrijpen. Polymorfisme is het vermogen van een programma om objecten met dezelfde interface op dezelfde manier te behandelen, zonder informatie over het specifieke type van het object. Ondanks dat polymorfisme een vrij basaal onderwerp is, is het vrij uitgebreid en vormt het een groot deel van de basis van Java. Voor veel studenten is polymorfisme een eerste moeilijkheid bij het leren van Java. Allemaal omdat er verschillende vormen van polymorfisme worden gebruikt in verschillende contexten, wat verwarrend kan zijn.
Tips en aanbevelingen
Er is geen andere manier om met polymorfisme om te gaan dan het te leren. Dit is hoe Torben Mogensen, die programmeerleraar is aan de Universiteit van Kopenhagen,
uitlegtdit concept: “Eenvoudige overbelasting: + kan zowel optelling van gehele getallen, optelling met drijvende komma als (in sommige talen) aaneenschakeling van tekenreeksen betekenen. Subtypepolymorfisme: Als B een subtype is van (erft van) A, kan elke waarde van type B worden gebruikt in een context die een waarde van type A verwacht. Parametrisch polymorfisme: Een type kan worden geparametriseerd met typeparameters, zodat u in verschillende contexten kunnen verschillende type-argumenten leveren, dus concretiseer je het geparametriseerde type naar verschillende concrete typen. Dit wordt ook wel "templates" of "generics" genoemd en wordt in OO-talen doorgaans gespecificeerd met punthaken (zoals T<A>). Interface-polymorfisme. Dit is eigenlijk een mechanisme waarbij je subtypepolymorfisme beperkt tot subtypes die een bepaalde interface implementeren of parametrisch polymorfisme tot typeparameters die een bepaalde interface implementeren.”
5. Reflectie
Reflectie is een mechanisme om gegevens over een programma te onderzoeken terwijl het draait. Met Reflectie kunt u informatie verkennen over velden, methoden en klassenbouwers. Het stelt je ook in staat om te werken met typen die niet aanwezig waren tijdens het compileren, maar die tijdens runtime beschikbaar kwamen. Reflectie en een logisch consistent model voor het afgeven van foutinformatie maken het mogelijk om correcte dynamische code te creëren. Maar voor veel mensen is het niet zo eenvoudig om erachter te komen hoe ze Reflectie moeten gebruiken.
Tips en aanbevelingen
“In het geval van reflectie en Java, zorgt reflectie ervoor dat Java, dat is ontworpen om statisch te worden getypt, dynamisch kan worden getypt. Dynamisch typen is niet inherent slecht. Ja, het stelt de programmeur in staat om bepaalde OOP-principes te doorbreken, maar tegelijkertijd zijn er veel krachtige functies mogelijk, zoals runtime-proxying en afhankelijkheidsinjectie. Ja, met Java kun je jezelf in de voet schieten met reflectie. Je moet echter heel expliciet het pistool op je voet richten, de veiligheid uitschakelen en de trekker overhalen”, legt Jayesh Lalwani uit, een ervaren Java-programmeur en applicatie-architect
.
6. Input/Output-stromen
Met Streams kunt u met elke gegevensbron werken: internet, het bestandssysteem van uw computer of iets anders. Streams zijn een universeel hulpmiddel. Ze stellen een programma in staat om overal vandaan gegevens te ontvangen (invoerstromen) en deze overal te verzenden (uitvoerstromen). Hun taak is hetzelfde: gegevens van de ene plaats halen en naar een andere sturen. Er zijn twee soorten stromen: invoerstromen (gebruikt om gegevens te ontvangen) en uitvoerstromen (voor het verzenden van gegevens). Wat het voor veel mensen moeilijk maakt om het gebruik van streams te begrijpen, is het feit dat Java meerdere I/O-streamklassen heeft.
Tips en aanbevelingen
“Java heeft zoveel I/O-streamklassen, voornamelijk vanwege twee bijdragende factoren. De eerste is erfenis. Sommige klassen zijn er nog steeds om historische redenen en ze zijn niet verouderd omdat ze niet als schadelijk worden beschouwd. Ten tweede, flexibiliteit. Verschillende toepassingen hebben verschillende vereisten en daarom heeft u meerdere opties, afhankelijk van uw vereisten. Handige abstracties zorgen voor duidelijkheid als je het leest en met weinig regels code kun je veel doen”,
zegt Jonas Mellin, een Java-expert uit Zweden. Welke aspecten van Java vond je het moeilijkst te begrijpen of bleef je een tijdje hangen? Deel je ervaringen in de comments.
GO TO FULL VERSION