Kezdő kér tanácsokat, plusz álláskeresés

Fórumok

Sziasztok!

Pár dolgot szeretnék kérdezni, illetve kérni.

1.: Az volna a kérdésem, hogy egy tapasztalt programozó szerint milyen a programom? Most kezdek újra "programozgatni". Írtam egy kezdő szintű programot, amit felraktam a sourceforge.net -re. Mielőtt teljesen hülyének néztek, nem magamnak csináltam, hanem az unokaöcsémnek.

2.: Szerintetek lehet-e esélyem java programozóként elhelyezkedni? Tudom még rengeteget kell tanulnom (fogok is). Egyébként főleg a programozás ami érdekel és a Linux. Linuxot már elég régóta használok, viszont abban sem érzem magam elég jónak, mivel nem tudom milyen a mérce.

3.: Ha valaki tud nekem írni, vagy küldeni olyan tesztet amin lemérhetem a linux és/vagy java tudásomat, azt megköszönném. :)

Egyelőre ennyi. :)

Ja a link: http://sourceforge.net/projects/mcversioonchoos/

Hozzászólások

hello. regisztralj az https://www.odesk.com -on es ott vannak tesztek, java es linux is.

ha komoly programozo akarsz lenni, akkor vagj bele egy projektbe vagy csatlakozz letezohoz, keress hibakat es submitolj bugfixeket.

amugy a program basic awt meg file io. errol nem tudok velemenyt mondani, ezt nem tul bonyolult osszerakni.

A kododrol.

1. Hasznalj valami IDE-t (Eclipse, Netbeans, Intellij,...). Vagy ha hasznalsz, akkor kapcsold be/futtasd az autoformazast (be lehet kapcsolni, hogy minden menteskor formazzon). Az egyseges kinezetu kod szebb es profibb benyomast tesz. Most ugy tunik az indentalas eleg vegyes.

2. Tagold jobban a kodot.
- Ha tobb nagy classod van, akkor tedd oket kulon fajlba (nem feltetlen minden egyes darabot, de itt mar boven lenne ok elkuloniteni nehanyat).
- Nehany classnak rengeteg fieldje van. Tagold oket tobb classba, logikai csoportokat kialakitva. Pl.: az MCPanel classon belul lehetne egy inner class (Menu), es abba mehetnenek a "JMenuBar mb; JMenu mFile, mSettings, mHelp, mLanguage; JMenuItem miExit, miAuthor, miHelp, miSkins" mezok
- Nehany metodus nagy. Okol szabaly, hogy egy metodus ne legyen egy kepernyonel nagyobb, ne legyen sok egymasba agyazott ciklus, mert az rontja az atlathatosagot. Tagold oket tobb metodusba.

3. A swinges reszrol nem mondok semmit, mar nagyon reg nem kodoltam benne.

4. Ezeket szerintem keruld: "System.out.println("Fuck you windows");"

Ne nyeld el bármiféle jelzés nélkül az Exceptionöket. Rémálommá teszi a debugolást.

Sorban mondom, ahogy észreveszem.

Az importoknál sose csináld ezt:

import javax.swing.*;
import java.io.*;

Feleslegesen szennyezi a látható szimbólumok listáját, rossz esetben ilyeneket kell csinálni: org.bla.File, com.blahh.File, mert mindkét csomagból beimportálódhat azonos class. Ha rendes IDE -t használsz, akkor ott egy gombnyomással rendet lehet tenni az importok között (pl. Eclipse: organize imports, van rá shortcut is). Mindig csak a szükséges minimálisat importáld.

Így IDE nélkül teljesen áttekinthetetlenek a class -ek, az összes egy darab toplevel classba van belesűrítve (ez rögtön god of classes antipattern) mindig mindegyik külön .java fájlban legyen, használj saját package struktúrát.

Az egész kódodban egy darab final kulcsszó nincs. A final többcélú: class -oknál a tovább nem örökíthetőséget jelenti, metódusoknál az @Override -al felül nem definiálhatóakat (ha class a final, akkor minden metódusa is az lesz). Ezt azért kell használni, hogy magadnak vagy a többi fejlesztőnek világosan jelezd, hogy melyik class -eket szánod továbbörökítésre, melyeket nem. A másik célja a class member-ek és lokális változók esetén az, hogy hozzárendelés operátorral (final Object bla = expression) csakis egyszer rendelhetsz hozzá értéket. Member field -eknél további jelentése, hogy a konstruktorban kötelezően inicializálni kell ezeket a member -eket, ha nem teszed, nem fordul le a kód. Én azt szoktam mondani, hogy minél több final, annál jobb. De használható paraméterekre is:

public void actionPerformed(ActionEvent ev){}
helyett
public void actionPerformed(final ActionEvent ev){

A második azért jobb, mert biztosan nem tudod felüldefiniálni (ignorálni) a bejövő paramétert, azt kell használni, amit a hívó beletesz. A final ezen második része a debugolhatóságot nagyban növeli.

Ahogy mondták fentebb, elnyeled az Exception -öket:
try {
htmlPane.setPage(event.getURL());
} catch(IOException ioe) {
// Some warning to user
}

Ez súlyos antipattern. Bár a programod elég egyszerű (nincsenek benne rétegek), az Exception -öket sosem szabad elnyelni. Kétfajta Exception van: ellenőrzött és nem ellenőrzött. A másodikba olyanok tartoznak mint pl. a NullPointerException. Ezeket nem kell elkapni (nem kell try-catch-be tenni azt a kódrészt ami dobhatja, sem a metódusba nem kell beleírni a throws -t), mert programozói hibát jelent, ha mégis dobódik. Az ellenőrzött kivételek a normál működés során lépnek fel. Például nem programozói hiba, ha egy beolvasandó fájl nem létezik, vagy nullával próbálsz meg osztani. Ezt el kell kapni és foglalkozni kell vele (például kiírni hogy nem létezik a fájl vagy ne nullával ossz). Nagyobb alkalmazásokban, ahol a program rétegekre van osztva, előfordul az Exception chaining pattern, ahol a dobott Exceptiont beleteszik a felette levő réteg által ismert exception -ba, és tovább dobjuk, hogy ő foglalkozzon vele.

Ahogy mondták, a formázás teljesen össze-vissza van, használj IDE -t, és commit (vagy másoknak megmutatás) előtt formázd be a kódot.

Látok egy ilyet:

public HelpDialog(JFrame owner, String title, int lang){
...
...
...
String url = (lang==1)?this.getClass().getResource("ReadMe.html").toString():this.getClass()

A lang gondolom valami aktuális nyelvet jelent, ezt sose kódold be valami számozott rendszerbe, hanem csinálj rá egy enum -ot. Hol tartod nyilván, hogy melyik lang hányas számot jelenti? És ha valahol összekevered, akkor a progi néha angol, néha magyar lesz? Szóval csinálj egy enumot rá, azzal sokkal könnyebb és egyértelműbb dolgozni.

A metódusok hosszúak, ami nem fér bele 1-2 képernyőbe, azt fel kell darabolni.

Nagyon sok sor ki van kommentezve, ez csúnya. Ha nem kell, töröld ki.

Hát így első blikkre kábé ennyi, többet azért nem mondok, mert nem nagyon programoztam Swing -ben, így nemigen tudom pontosan mi mit csinál.

Az állás dologról annyit mondanék, hogy ha mostanában kezdted (szóval mondjuk nem 1-2 éve nyomatod), akkor egy gyakornoki vagy junior helyet tulajdonképpen megpályázhatsz, de sokat kell még tanulni.

--
http://neurogadget.com/

Sok mindent lemondtak már előttem, amiket én kiemelnék:

- IDE használat

- SOLID patterns/principles használata (http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29)

- formázás, importok rendezése

- használj saját package-et, ne csak úgy ott legyen a struktúra gyökerében az osztályod

- egy nagy forrásfájl helyett tagold több részre a kódot (persze nem kell feltétlenül minden osztálynak)
pl.: a main-ben gyakorlatilag két különböző programot indítasz (ok, SetupFrame-ből aztán elindítod a másikat, de akkor is két különböző), lehetne egy osztály csak a main-nek, a két külön ablak (MCPanel, SetupFrame) meg külön fájlokba.
(http://en.wikipedia.org/wiki/Single_responsibility_principle)

- túl hosszúak a metódusaid, legyenek rövidebbek, átláthatóbbak

- ne használj a kódba beégetett String-eket,
ha ez egy felirat, tedd ki külön fájlba (egyes IDE-k (pl. NetBeans) elég jól támogatják ezt, ezzel megkönnyíted a programod többnyelvűvé tetelét) pl.: http://docs.oracle.com/javase/6/docs/api/java/util/ResourceBundle.html
ha ez egy konstans, akkor legyen class konstans: public static final String MY_CONST= "blabla";

- ha már java7-et használsz, akkor használd a try-nál az AutoCloseable-t http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResource…

- ilyet ne:

File f;
String [] mcV;
f=new File(mcVersions);
mcV = f.list();

a java nem C, ott deklaráld a lokális változódat, ahol elkezded használni (kivéve persze try, vagy if szerkezet előtt stb.), tehát:

File f = new File(mcVersions);
String [] mcV = f.list();

- lang = 1, lang = 2 : használj inkább enum-ot, jobban átlátható

- ActionListener-ek: én jobban szeretek anonymous inner class-t használni, de ez ízlés kérdése, pl.:

button.addActionListener(new ActionListener() {
public void actionPerfored(ActionEvent e)
{
//vagy itt lekezeled, de szebb, ha innen hívsz egy metódust, ami lekezeli
}
});

- általában nem szokás EventDispatchThread-ben Process-t indítani (ha meg akarod várni a lefutását), használj SwingWorker-t

- használj verzió követőt (akár lokálisan is, pl.: git, mercurial), a kikommentezett kódokat így nyugadtan törölheted, hisz vissza tudod állítani a korábbi állapotot

- fontold meg valamilyen logger használatát, ekkora kódnál még lehet, hogy nem olyan fontos, de nagyobbnál hasznos tud lenni, hogy pl. ki/be tudod kapcsolni a debug üzeneteket

- ajánlott olvasmányok: Robert C. Martin: Clean Code / The Clean Coder ; Joshua Bloch: Effective Java

Gyors átfutás után röviden ennyi.

Változók nevei lehetnek nyugodtan beszédesek. (csak bele néztem)
pl:
String str1 = localScanner.nextLine();
String str2 = localScanner.nextLine();
String str3 = localScanner.nextLine();
int i = localScanner.nextInt();
System.out.println(str1 + "\n" + str2 + "\n" + str3);
File localFile = new File(str1);
String[] arrayOfString = localFile.list();
new MCPanel(arrayOfString, str1, str2, str3, i);

Illetve a kódba égetett String se életbiztosítás hoszútávon... pl: interface-be kiemelt konstansok vagy enumok használata, egy helyre gyűjtve. :)

Ha mar ilyen szepen osszejott a tarsasag, velemenyeznetek az en kodomat is? Itt van, nem tul nagy kod. Szinten kezdo vagyok, vagy legalabbis annak tartom magam.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

A teljesség igénye nélkül:

- A unit-teszteknél pl. GoogleTranslationServiceTest.java ha Exception-t vársz, akkor azt inkább rakd bele a @Test annotációba (pl.: @Test(expected=IllegalArgumentException.class))

- felesleges importokat szedd ki

- személyes vélemény (ízlés kérdése): ne legyen semmilyen warning sem a kódban. Ha tudod valamiről, hogy nem hiba, akkor inkább @SuppressWarning

- GoogleTranslationService.java:
* StringBuffer helyett StringBuilder
* a translate metódusnál simán lehetne BASEURL+PARAMS stb. a new URL előtt (vagy benne) , StringBuilder-t akkor szokás explicit használni (mivel a String+String is gyk. StringBuilder-re fordul), ha pl. ciklusban rakod össze a String-et.
* (text == null || text.isEmpty()) helyett lehet, hogy érdemes Google Guava (vagy Apache Commons) Strings.isNullOrEmpty-t használni (ha több helyen is van ilyen). Persze ekkor már lehet, hogy érdemes a Preconditions-t használni
* ha a metódusaidba már úgyis fail-early (precondition) ellenőrzéseket csinálsz, akkor a lokális változó-deklarációkat (és az esetleges inicializálásukat) inkább rakd az ellenőrzés utánra
* detect: biztos vagy benne, hogy Throwable-t akarsz elkapni?
* java foreach sokszor hasznos tud lenni (a többi osztályban használtad is)

- TranslationServiceFactory.getService(String):
translationServices.containsKey(name) ? translationServices.get(name) : null; : ez ellen nem véd a ConcurrentHashMap, de elég is simán a translationServices.get(name)

- FindBugs hasznos tud lenni, nem tudom, hogy használod-e.

Javitgatom ki a dolgokat, nehany dolog:

- StringBuilder: azert hasznalom, mert nekem tisztabb igy, hogy mi tortenik a stringgel. Ha csak siman pluszoznam, hajlando vagyok (es az IDE meg inkabb az) osszevonni egy-ket sorba, ekkor attekinthetetlen lesz az egesz. Inkabb appendelek, es akkor marad minden szep folyamatos. Mivel ugyis kb. erre a kodra fordulna, igy performanciaveszteseg nem igazan van (plusz, mivel altalaban a forditasi szolgaltatokraa _nagyon_ sokat kell varni, amit itt vesztek, az ahhoz kepest minimalis).
- Guava-t azert nem hasznalok, mert minel kevesebb fuggest szeretnek. Csak azert, mert 1 db feltetelt megkonnyitene meg nem akarok 2M tomeny kodot hozzaadni a projekthez fuggeskent
- Throwable: megmondom oszinten, ez egy randa workaround volt egy IDE bugra. Ha itt Exception volt, akkor nem engedett rendesen dolgozni a koddal. Biztos szepen is meg lehetett volna oldani, de pont nem erdekelt annyira. Azert javitottam, ugy nez ki, az uj verzioban mar nincs meg ez a bug.
- Foreach: A JsonArray (legalabbis a Gson verzio) nem tamogatja a foreach-et. Legalabbis en nem talaltam meg, hogyan tamogatna. En is jobban szeretem a foreach-et, itt nem mukod.

- FindBugs: tervben van a kod Sonar-ba kotese, de jelen pillanatban a Sonar szerverem gyengelkedik.
- Warningok: te hol talaltal warningot? Nekem nem dobott sehol.

--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

"StringBuilder: azert hasznalom, mert nekem tisztabb igy, hogy mi tortenik a stringgel. Ha csak siman pluszoznam [...]"

Nem azt írta, hogy operátorral konkatenálj helyette. A StringBuffer szinkronizált, a StringBuilder nem, így a teljesítménye is jóval nagyobb. Az esetek túlnyomó többségében elég a StringBuilder.

Erre reagaltam:

"a translate metódusnál simán lehetne BASEURL+PARAMS stb. a new URL előtt (vagy benne) , StringBuilder-t akkor szokás explicit használni (mivel a String+String is gyk. StringBuilder-re fordul), ha pl. ciklusban rakod össze a String-et."
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

- A warning dolgot úgy általánosságban írtam, konkrétan az Eclipse pár dologra warningolt csak, pl.:
TranslateController.translate(Model, TranslationRequest, BindingResult)-> finally részben van a return
illetve nem használt import/változó és serialVersionID.

- Sonar +1 , hasznos tud lenni :)

- foreach GoogleTranslationService.jsonStringsToList(JsonArray): hm, nálam ez fordul (nem kötözködni akarok ;)):

for (JsonElement elem : array) {
elem.isJsonPrimitive();
}
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>

- serialVersionID: meg fogom nezni
- finally: megnezem, en nem kaptam forditas kozben warningot, es nem Eclipse-t hasznalok, az IDEA meg nem szol.
- foreach: megnezem, koszi. Nekem nem akart fordulni ugy, ahogy probaltam...
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

A FindBugs 1 hibat talalt a kodban, de fogalmam sincs, mit kezdhetnek vele.

Azt mondja, hogy a TranslationUtilities-ben fuggok az alapertelmezett encoding-tol. Magat a hibat ertem, hogy mit jelent, probaltam ugy fixalni, hogy az InputStreamReader-nek fixen atpasszolok egy UTF-8 -as encodingot (amugy is ebbe vannak lekerve a cuccok joreszt), a FindBugs megis sir.

Szerk: francba. Nem tudom miert, de nem ellenorizte ujra a kodot addig, amig ki nem adtam egy mvn clear parancsot.
--

Ki oda vagyik, hol szall a galamb, elszalasztja a kincset itt alant. | Gentoo Portal 

Raneztem a kodra, a hosszu metodusok es xar formazas miatt a hanyinger kerulgetett, nem nezelodnek tovabb benne, amugy is mar eleg jol kiveseztek, csak par dolgot tennek hozza / emelnek ki:

1. Futtass rajta valami statikus kodanalizalot es ertelmezd a figyelmezteteseit - PMD, FindBugs, stb.
2. Probald dokumentalni. Ha mar felrakod SF-re, irhatnal rola par sort, mirol szol, mire jo.
3. Ha javaval akarsz elhelyezkedni, szerintem celozd meg az OCJP vizsgat, rengeteg felkeszito anyag es probavizsga van hozza a neten. A Sierra-Bates konyv pl. alaposan atveszi a nyelv alapjait, es tartalmaz par probavizsgat. "OCJP mock exam"-re keresve talalsz vizsga szimulatorokat. Ha van ra penzed, vasarolhatsz is ilyent pl. a Whizlabs-nel!

----------------------
"ONE OF THESE DAYS I'M GOING TO CUT YOU INTO LITTLE PIECES!!!$E$%#$#%^*^"
--> YouTube csatornám