Komentáře k projektům z roku 2014/15
Zakladam svuj blog na dobu hodnoceni vasich projektu. Cilem je vam promluvit do duse odlehcenou formou ;-)
Projekty okruhu 1 vypadaji, jako by je psal jeden clovek, ktery ke vsemu odmita prijmout C++ v jeho tradicni podobe. Pokud mate dojem, ze se ve sve programatorske praxi C++ vyhnete (da se seriozne, ale opravdu seriozne, pracovat v Jave?), tak to daleko nedotahnete. Do duchodu mame vsichni fakt daleko ;-)
Programovani je kreativni prace. Ale kazda kreativni prace je hlavne remeslo; je treba nad tim remeslem premyslet a trenovat, trenovat, trenovat. Zadani okruhu 1 vyzaduje sestavit trivialni program s nekolika seznamy a promenlivym poctem objektu. Student FIT v 5. semestru by s tim nemel mit potize. Presto ma.
1) Pretypovani neni zadna legrace
Nasledujici ukazka dava zcela jasny dukaz o tom, ze autor odmitl provest smysluplny navrh svych datovych struktur.
Port \)((Element)((Object )((Object )_sPort)));
{
((Port )getPar())->foreignShipping(_ePort);
}
2) Neni treba vracet pamet
Spousta new, zadny delete. Studenti se boji dealokovat, ponevadz nikdy nemaji jasno o dobe zivota objektu. Bez korektni spravy pameti nikdy neudelate poradny program.
Pri kazdem new si uvedomte, kdo je vlastnikem objektu a kdo ho ma casem dealokovat. Zkuste rozlisovat strong referenci (objekt zije tak dlouho jako jeho vlastnik nebo drzitel reference; vlastnik ho dealokuje ve svem destruktoru) a weak referenci (nemusi byt platna na porad; drzitel reference neprovadi dealokaci).
Pokud chcete bez-deletovy program v C++, piste se shared_ptr. Ja na to pred lety presel a jsem programatorsky spokojeny.
3) Facility seize podminecne
Konstrukce: transakce naplanuje zaznam modelujici praci na zarizeni do kalendare a skoci do seize, tj. az potom vlastne zada o prideleni linky. Pokud neni volno, seize zrusi zaznam v kalendari, tj. seize ocekava takove chovani ;-) Pri release ho nejak prehodnoti...
Veci maji v zivote mit nejake poradi:
- pozadam o linku,
- kdyz ji mam, rozvrhnu praci,
- pak ji vratim.
4) Objekty simulace a jadro si predavaji zpravy pomoci nastavovani globalni promenne
Uvazujme promennou KILL (bool). Jadro simulatoru aktivuje zaznam z kalendare. Pokud po dokonceni bloku zaznamu je KILL==true, pak jadro dealokuje objekt transakce svazany se zaznamem o udalosti. Je to dost nebezpecna promenna. Kazdy objekt by si ji mel hlidat.
5) Objekt provadejici release to vi nejlepe
Transakce provadejici release obdrzela referenci na transakci vytazenou z fronty a potom ji urcila nasledujici stav. Kdyz vas nekdo vytahne z fronty, tak tim i rozhodne za vas, co mate pak delat?
6) Static je vseobjimajici
Vsechny metody a vsechny datove atributy tridy jednoho z autoru jsou static. Presto autor tridu instancuje a ma pocit, ze vysledkem jsou objekty (dokonce na static atributy pristupuje s pocitem, ze jsou u kazde instance unikatni). Trida se static atributy je v podstate namespace, ze. Jiny smysl to davat nemuze.
Static je v poslednich letech u OOP dost moda. Premyslim, kdo to sem zavlekl.
7) Komu posilam zpravu a lezu do dat? this to vi nejlip
Dalsim modnim prvkem zavedenym v lonskem roce je prefix this- pred pristupem na libovolny prvek objektu. Neni to chyba, jenom to vypada srandovne. Piste tak a starsi kolegove z vas budou mit srandu.
8) Transakce se nazyva Event
Transakce je pojem z teorie kolem SHO. Je to typ procesu, jehoz pruchod systemem hromadne obsluhy sledujeme. Proces je posloupnost udalosti. V mnoha projektech je kladeno rovnitko Transakce==Proces==Udalost. Program sice funguje, ale muze u jinych vytvaret chaos. Verte, vy nechcete tvorit necitelne zdrojaky.
Zacalo to pozvolna a k veceru to gradovalo ;-) Nasledujici text berte s humorem a pokuste se nad nim zamyslet.
9) if - posloupnosti zdlouhavych if, else if, else if...
Program nam pekne narusta v poctu radku. Je krasne necitelny a neflexibilni. Kolikrat musite napsat If-Else-If-Else-If-Else, abyste usek programu prepsali do neceho lepsiho?
10) pole identifikatoru nefrci, lepsi je deklarovat jez1, jez2, jez3, ., jez10
a nasledne kopirovat bloky kodu pro jez1 na jez2, na jez3 a podobne. Copy-paste je casty duvod zaneseni chyby do programu. Prodluzuje to kod a snizuje jeho flexibilitu. Kdyz potrebujete upravit blok, tak to musite provest na deseti mistech. Rozdil mezi bloky je pouze v konkretni promenene jezX. To se snad da prepsat do cyklu s polem jez[].
11) waituntil - muj vypocet trva dlouho
Minuly rok jsem zadal dr. Peringera, at vyhodi ze SIMLIBu prikaz waituntil. Nejak to zapadlo a letos waituntil opet vyrazil do vasich projektu.
Prikazem waituntil(podminka) registrujete proces v kolekci jadra simulatoru. SIMLIBovske diskretni simulacni jadro (aneb kalendar) v kazdem kroce prochazi tuto kolekci a u vsech registrovanych testuje podminku. Kdyz jich je tam registrovano 1000, tak s kazdou udalosti projde 1000 podminek. Pak vam to bezi pomalu.
12) vkladani URL do textu
Vlozena URL ma typicky delku jednoho celeho radku textu. Text prolozeny URL je prijemny na pohled a krasne to rozklada odstavce. Obvzlast krasne je referovat jednu URL na strance vicekrat.
Kdyz uz odmitate sekci literatury v zaveru textu, tak URL davejte do poznamky pod carou a v textu odkazujte cislem poznamky pod carou.
13) Gramatika naseho jazyka
Internet devastuje uroven psaneho projevu lidi. Ctenari blogu a diskuznich for prebiraji nespravne navyky, ktere obvzlast rezonuji ve dvou fenomenech:
- nahodne rozmisteni carek v textu,
- shoda podmetu s prisudkem.
Ten prvni fenomen si predstavuju tak, ze pisatel napise dlouhou vetu, pak se mu zachce dat do ni carky (asi by tam nejake byt mely, ze) a vlozi je tam naprosto nahodne. Taky se carkou spojuji dve nespojitelne vety, jako napr. "Vcely se rozmnozuji nejvice na jare, zitra pujdu na pivo.". Ctenar tam hleda souvislost. Pokud napisete "Vcely se rozmnozuji nejvice na jare. Zitra pujdu na pivo.", pak ctenar stale nechape smysl, ale aspon vi, ze nemusi chybu hledat u sebe ;-)
Celkem pomuze, kdyz se zamyslite nad kazdou vetnou spojkou. Pred ni se typicky dava carka. V kazde vete souveti taky typicky byva sloveso (pro jazykovedce: prisudek). Proto nelze psat vetu "To je, ale pekny pejsek!". To "ale" tu neni spojka. Navic je ve vete pouze jedno sloveso.
Chybne psana shoda podmetu s prisudkem je jednak gramaticka chyba, ale hlavne muze ctenare uvest v omyl. Pro koncove i/y u slovesa je totiz urcujici rod podmetu:
- Muzi psali projekt. (Ti muzi).
- Zeny psaly projekt. (Ty zeny).
Pokud mame genderovy mix podmetu, pak piseme "Muzi a zeny psali projekt". Delali to ONI, ne ONY. Dva studenti pak pisou svou zpravu v zenskem rode a to ctenare mate, ze. Berte, prosim, na ctenare ohled ;-)
14) Vceli matce trva kopulace nulovy cas a neni k tomu treba ucasti absolutne zadne vcely
Autori modelovali proces matky a oddelene proces jejiho pareni (byl nazvan kopulace). Proces pareni se nesynchronizoval se zadnym ucastnikem modelu a trval nulovou dobu. Podobne vypadaly vsechny ostatni procesy - v modelu nebyl ani jednou prikaz Wait.
15) Kazda narozena vcela muze nastartovat nove rojeni
Predpokladejme metodu pro obsluhu udalosti narozeni nove vcely:
vcely.add(novaVcela);
if (vcely.size()=MAXVCEL) {
(new Rojeni)-Activate();
}
Zda se mi, ze rojeni muze probihat v jakemsi obdobi pouze jedno. Tj., nove prichozi vcela muze nastartovat rojeni, ale pokud je rojeni uz nastartovano, dalsi se nestartuje. Navic modelovane rojeni trvalo nulovou dobu - proste v nulovem case zmizla kralovna a pulka vcelstva.
Lepe:
if (vcely.size()=MAXVCEL) {
if (neprobiha aktualne rojeni)
(new Rojeni)-Activate();
}
16) Sebevrazda je spatna
Proces provadi:
// zavola si zabijaka
(new Zabij(this))-Activate();
// ceka, az to prijde
Passivate();
class Zabij : public Event {
public:
Vcelavcela;
Zabij(Vcela p) : vcela(p)
{
}
void Behavior(){
// kdyz to ta vcela chtela, at to ma
vcela->Cancel();
Cancel();
}
};
Ukonceni procesu lze udelat i jednodussim zpusobem, napr. opustenim metody Behavior. Vyskocit z procedury snad zvladne kazdy.
17) Stavovy automat nove generace (videno v nekolika projektech)
Process:
while (1) {
switch (state) {
case 1: // cosi
case 2: // cosi
case 3: while (1) {
// cosi
}
}
}
Tohle se vam jednou v praxi dost vymsti.
18) Po libovolne praci 24 hodin na spanek
Vcely delaly ruzne pracovni a jine ukony (napr. kopulovaly ;-)). Veskera aktivita byla provedena v nulovem case a pak nasledoval 24 hodin dlouhy spanek.
Nejlepsi byla ovsem pracovni napln trubce:
while (Time = Okamzik_me_smrti) {
WaitUntil(!Prsi);
Registruj se do fronty na pareni s matkou;
Wait(24 hodin);
}
Vsimnete si, ze kdyby porad prselo, tak si trubec muze solidne protahnout zivot (a pak jeste nad ramec delky sveho zivota muze jeste stihnout vceli matku).
19) Rozkouskovane procesy podle stavu objektu
Proces je prerusitelna posloupnost udalosti. Muzete modelovat udalostne (proc se to teda tem v projektu #1 tak silene nedarilo?!), ale jaksi to neodpovida vyvoji programovacich a simulacnich jazyku ( nasi predkove vymysleli procesne orientovane jazyky zbytecne).
ObjektStavA::Behavior() {
// neco udelej v nulovem case
(new ObjektStavB)-Activate(Time+X);
}
ObjektStavB::Behavior() {
// neco udelej v nulovem case
(new ObjektStavC)-Activate(Time+Y);
}
Je to fakt lepsi nez nasledujici kod?
MujProcess::Behavior()
{
// cosi
Wait(X);
// cosi
Wait(Y);
// ...
}
20) Prikazu goto se sice nebojime, ale nic se nema prehanet
Nekonecny cyklus je vseobecne uznavany koncept. Mozna ho autor z nejakych moralnich pohnutek odmita:
procedura cosi()
{
zacatek:
// cosi delej
goto zacatek;
}
Nebo goto miluje a s dojetim vzpomina na osmdesata leta s jazykem Basic.
bool PROM;
switch (PROM) {
case true:
// cosi
B:
if (cosi) goto A;
// cosi
case false:
// cosi
A:
// cosi
goto B;
// cosi;
default:
break;
}
Autoruv switch mel v sobe celych 5 navesti A,B,C,D,E! Dale si muzeme povsimnout, ze switch je nad promennou typu BOOL. Ma case-navesti pro hodnoty true, false a DEFAULT. Nahoda je pekna potvora; nekde prolitne neutrino, cosi v pocitaci preskoci a BOOL dosahne treti mozne hodnoty!
Mozna bylo autorovi trapne umistit 5 navesti do kodu
if (PROM) {
A:
B:
C:
} else {
D:
E:
}
a napric bloky pro true a false skakat prikazem goto.
Dokonce jeho vceli matka uvizla v nekonecnem label-wait-goto cyklu:
tady:
Wait(DEN);
goto tady;
Autorum se uplne nezdaly vysledky experimentu. Proto pripustili nevaliditu sveho modelu, ale to pouze z toho duvodu, ze "vcely jeste nebyly zcela prostudovany jako zivocisny druh". Rozhodne nevalidita modelu nesouvisela s jejich silenym kodem. Goto by meli brat do ruky jenom pokrocilejsi programatori.
Ty vcely mi davaji dost zabrat.
21) Nikdo nechce znat datum sve smrti, ale vcela ano ;-)
V mnoha projektech se potykate s zivotnosti objektu modelu. Na abstraktni urovni resime delku zivota vlakna ve vypoctu a zpusob jeho ukonceni. Ukonceni vlakna se ve vsech knihovnach a operacnich systemech (ktere jsem za 20 let videl) resi vyskocenim z metody Behavior (nebo ekvivalentu). Neni typicke vlaknu posilat nejaky kill-signal. Kdyz uz vnejsi okoli chce dat vlaknu padaka, tak mu posle nejakou uzivatelskou zpravu a vlakno na zpravu reaguje vyskocenim ze sveho Behavior.
Doba zivota objektu/vlakna:
Vidam u vas promennou lifetime obsahujici dobu zivota objektu. Z ni se postupne odebira za jednotlive ukony. Vse ale v casove ose modeloveho casu. Tento postup neni koncepcni. Musite totiz hlidat kazdy ukon a jednou na nejaky zapomenete. Uvazujme radeji:
double startTime, endTime; // nastavi se okamzik narozeni a predem urcene smrti
bool jesteZiju()
{
return Time endTime;
}
double kolikMiZbyva()
{
return endTime - Time;
}
22) Zkratkovite logicke podminky
C/C++ sice umoznuje konvertovat cislo na bool v prikazech if a while, ale jak dopadne programator, ktery pise:
int lifetime;
while (lifetime) {
///
lifetime -= X;
}
Takovy programator si koleduje o neocekavane chovani programu pri lifetime 0. Je tak sileny problem psat while (lifetime 0) ?? Podobne, jenom silenec testuje double na rovnost s konstantou nebo jinym doublem ;-)
23) zatemnovaci soutez
21-krat pockat 1 casovou jednotku - to vypada angazovane a vedecky ;-)
// wait for larva growth
for(int i = 0; i 21; i++)
{
Wait(1);
}
24) na kralovsky trun se ceka fronta
Seize(queenActive);
Statistika fronty bohuzel chybela.
25) co muze znamenat, ze kalendarni mesic je Busy() ?
Autori maji 12 Facility linek. Aktualni mesic poznaji podle dotazovani, ktera z linek je Busy(). Pochopitelne sekvenci 12x if (mesic[0].Busy()), if, if, if, if, ...
26) vedeni skladoveho hospodarstvi vcelstva - vcely maji KONTOKORENTNI uver !
Nekolikrat pozorovano. Autori maji citac vyrobene produkce potravy a jiny citac spotreby potravy. Casovy prubeh skladove polozky "potrava" = vyroba - spotreba je nezajima. Takze, pokud je na konci roku vyroba = spotreba, tak je priroda spokojena. Vcelky se pochopitelne pri navysovani citace spotreba nezajimaji o aktualni stav skladovych zasob. Jini autori zaporny stav skladu publikuji v grafech bez jakehokoliv komentare. Jejich vcely se proste cpou medem i pri jeho zaporne skladove zasobe! Pochopitelne vsichni autori prisahaji na validitu sveho modelu ;-)
27) nikdo vas neprerusi, zadny strach
Seize(bees_curr_count_acces);
bees_curr_count–;
Release(bees_curr_count_acces);
A kdyz dojde med, stejne zdechnou vsichni. Tenhle krasny goto skok uz linku neuvolni, takze nasledujici vcely se ocitnou ve fronte na linku-citac. Jejich duse neprijdou do vceliho nebe, ale zustanou ve fronte.
Seize(honey_store_acces);
if (honey_store=0)
goto Death;
Release(honey_store_acces);
Death:
28) for-while podminka cyklu
Jak ctete nasledujici program? Jak ho asi cte kompilator a jak dopadne vysledny kod? Je to validni a prenositelne?
for (int i=0; i( (int)Exponential(breed_ratio) );i++) {
(new _100_Short_age_workers)-Activate();
}
Tento for-cyklus ma byt ekvivalentem:
i=0;
while (i ( (int)Exponential(breed_ratio) )) {
// cosi
}
Kolikrat se to asi provede?
Promenna "i" je asi autorova oblibena. Uvazte, ze mel dva vnorene cykly a kazdy byl rizen promennou "i". Jednou byla double a jednou int. Fenomenalni!
double i = 0;
while (i cosi) {
for (int i=0; cosi rizene nahodnym generatorem s totalne nahodnym chovanim; i++) {
// "i" tu znamena ten int
}
// tenhle "i" je ten double
i++;
}
Autor je adept na kvazi-prestizni oceneni "Perla IMS 2014/15". Lonske vitezstvi se deli mezi dva projekty:
Prvni je 4-hvezdickovy general:
FacilityError: this should not happenError: this should not happenF;
Druhy je zivot po smrti:
delete this;
this->Activate();
Mam fakt obavu o vase profesni kariery.
29) musim se aspon zeptat (pro lepsi pocit)
Podotkneme, ze funkce FoodInPlace nema zadny vedlejsi efekt, nic nepocita, pouze vraci true/false. Nasledujici kod nema zadny efekt na stav systemu.
for (i = 0; i 4; i++) {
if (FoodInPlace(places[i].placeID))
break; // v promenne i ulozen pozadovany index
}
30) while-while-while
Mejme promennou int month;
Doufejme, ze jeji hodnota bude vzdy v ramci ocekavani, protoze chceme delat BEZPECNY KOD.
while (true) {
while (month == 1) // cosi
while (month == 2) // cosi
while (month == 3) // cosi
...
}
31) kral je mrtvy, at zije kral!
Proces kralovny zadava periodicky do vyroby balik larev. Potom proces kralovny zkouma, zda-li uz nezije prilis dlouho. Pokud ano, proces zanika a z posledniho baliku zadaneho do vyroby se v zapeti rodi nova kralovna hned z prvni larvy.
Uplne vidim, jak se ta larva vyklube ven a okolni vcelky ji reknou: "neda se nic delat, jses prvni narozena larva po smrti kralovny, musis to po ni vzit".
32) piste v logickych vyrazech zavorky, setri to nervy
if (letavka && Random() 0.4f && !dlouhoveka) {
vek–;
}
33) Vcela je trida odvozena od Event
Jeji Behavior ovsem nema v sobe reaktivaci. Objekt se zda byt na jedno pouziti, ale ma svoje instancni data. Takze ma asi delsi trvanlivost. Vysvetleni se najde na konci programu, kde je kolekce objektu Vcela a v cyklech se tyto aktivuji. To Event tam bylo naprosto zbytecne, ze. Pouze se to ma tvarit jako model v SIMLIB.
34) Recyklace zivota!
Objekt kralovna si pocita sve prozite dny a po nejake dobe se stane "mrtva". Jako mrtva se pak nekolik dni periodicky aktivuje a pocita si sve dny smrti. Az si "prozije" prilis mnoho mrtvych dni, zase se stana ne-mrtvou, doslova mrtva := false.
Tohle je masivni utok na muj zdravy rozum! ;-)
35) zivot zacina az ve stavu delnice-letavka
Objekt vcely prochazi ruznymi etapami vyvoje. Jeho zivotnost se pocita az po dosazeni stavu letavka. Do te doby je vcela nesmrtelna.
Pojdme si navic dekodovat nasledujici kod:
while(pocitadlo)
{
if(pocitadlo = 1 && med_poc 35000) (new trubec)-Activate();
else (new vajicko)-Activate();
pocitadlo–;
if(pocitadlo = 0) Wait(1);
}
Predem urceny pocet iteraci delejme lepe cyklem typu for. Tu logickou podminky cyklu uz jsem tu jednou komentoval.
36) co chcete vypocitat? Rec programu ma byt jasna a prima
// Upraveni varky tak, aby linkou prochazelo maximalne cislo MAXVEVARCE
do {
Varka = pocetKusu / pocetVelikosti;
if(VarkaMAXVEVARCE) pocetVelikosti++;
} while (VarkaMAXVEVARCE);
37) ktera informace je dulezitejsi?
Zadny test na neprazdnost fronty.proste count2-krat neco vytahnu
while (count2 0){
(NaKysnutie.GetFirst())-Activate(); // aktivivanie procesov
count2–;
}
38) kdyz je noc, tak se jde spat (!!!)
Uvazujme SHO a proces:
if (je noc) {
registruj se v kolekci;
Passivate();
} else {
pracuj;
}
Kdyz skonci noc, tak se vsechny procesy z kolekce aktivuji. Ovsem uz NEVLEZOU do bloku "pracuj". Pokracuji za if-elsem dal. Tato konstrukce byla v modelu trikrat. Porad ovsem premyslim, jak muze ve fabrice tohoto typu vzniknout pracovni proces v noci, kdyz v noci se nepracuje.
Validitu modelu dle autoru nebylo mozne overit, protoze to proste u tohoto typu podniku NEJDE. Autori pisou, ze vysledky prvnich zkousek modelu ukazaly model jako "prekvapive nevalidni". Pravou pricinu vsak nenasli. Program ma necelych 300 radku.
39) abstraktni vyrobek
Mame naprosto presne udaje z tabulek a zkusenosti nabyte praxi. Vyrabime vyrobek. Jaky? Zadny konkretni, proste vyrobek. Brousi se, vrta se a je hotovy.
40) bariera jako synchronizacni prvek
V nekolika projektech jsem narazil na obskurni pokus o implementaci bariery. Vsude stejne, coz jasne dokumentuje vazby mezi autory projektu.
Mejme proces a jeho Behavior:
// neco delam
// uz to mam dodelano
// musi nas byt X, aby se nastartoval nasledujici proces
if (nejsem posledni) {
vlezu do fronty a pasivuju se;
} else {
// jsem teda posledni
vytahnu vsechny z fronty a AKTIVUJU je
spustim navazujici proces
}
Vsimnete si laskave, ze ti probuzeni uz NIC dalsiho NEUDELAJI. Snad se da jednoduseji napocitat pocet procesu prolezlych urcitym mistem.
41) bojuji spolu dva pozadavky
Opet jedna logicka podminka k zamysleni.
while(this-count != 0){
for(int i = 0 ; i DIVIDER_LINES && this-count != 0; i++){
(new Croissant())-Activate(Time);
this-count–;
}
//
}
Autori meli nejspis na mysli rozklad do varek. Srovnejte komfort vnimani nasledujiciho kodu s originalem.
while (count 0) {
int kolikVeVarce = std::min(count, DIVIDER_LINES);
// generuj kolikVeVarce
count = count - kolikVeVarce;
}
42) trefte se do konkretniho realneho cisla
Nasledujici podminka bude mit hodnotu false s teoretickou pravdepodobnosti 0. Modelove casy byly ovsem komplet v celych cislech. Jinak by autor musel doufat, ze ve stochastickem systemu dojde k udalosti presne v okamzik SimTime. Program skoncil diky nastaveni casoveho ramce simulace Init(o, SimTime). Z toho pohledu je navic podminka redundantni.
void Behavior() {
while(Time != SimTime){
// cosi
}
}
Vsimam si, ze vetsinou odmitate operatory mensi a vetsi. Kdo vas to naucil?! Co vam brani napsat smysluplnou podminku while (Time SimTime) ???
43) dojde jednou za cas k poruse, ale ceho?
Autori modelovali poruchu. Z modelu nebylo patrne, ktere zarizeni ma byt v te poruse. Behem poruchy pry pracoval nejaky opravar, ale buhvi co opravoval.
44) generator cehosi
Co to muze znamenat? Jaky stochasticky proces to modeluje?
while((value = Random() v) == 0);
Random vraci double tusim z intervalu <0,1>
Ma to byt Uniform(0.001, v) ? Kdy bude Random() == 0 ? Jak casto se to stava? ;-)
45) Hadanka - kolik je vysledna hodnota promenne?
Obj->PocetKusuZbyva = Obj->PocetKusuZbyva–;
Aby to bylo zcela zjevne:
int a = X;
a = a–;
Semantika C/C++ rika, ze tento prikaz vede na nedefinovane chovani (potvrzeno znalcem dr. Peringerem). Vyraz "a–" vraci hodnotu "a" a pak objekt "a" dekrementuje. Vracena hodnota se nacpe na levou stranu, tj. do promenne "a". Ovsem bude to tedy "a" nebo "puvodni a minus 1"??
Autor je horkym kandidatem na perlu roku.
46) Jak dlouho se ceka?
Wait( 1 / 60);
Vyraz 1 / 60 se vycisli na 0 a AZ PAK konvertuje na double parametr procedury Wait. Podobnych vyrazu meli autori v modelu nekolik (generatory). Model byl pochopitelne dle slov autoru "validni".
Reseni: 1.0 / 60.0
47) kolik je kurat ve skladisti?
pokus:
if (pocetKuratNaSklade > 0){
Enter(skladKurat, 1);
pocetKuratNaSklade–;
}
else{
//pauza 15 minut kdyz neni na sklad kue
Wait(15);
goto pokus;
}
Se mi zda, ze letosek je ve znameni goto. Na to this-> si pomalu uz zvykam.
Autor zrejme myslel:
while (pocetKuratNaSklade = 0) {
Wait(15);
}
Enter(skladKurat, 1);
pocetKuratNaSklade–;
Ale tenhle kod neni tak cool ;-) Jsem holt stara konzerva, co programuje uz prilis dlouho ;-)
48) masivni paralelismus
Transakce Balik pri aktivaci vygenerovala a spustila procesy pro prijeti baliku, jeho nalozeni, prevezni, vylozeni, zpracovani, atd. Celkem jich bylo 8. Tyto paralelne pracovaly na transakci a jaksi chaoticky se synchronizovaly s procesem pobocky a buhviceho dalsiho. Mam dojem, ze tam mohly vznikat necekane paralelismy a dokonce dead-locky.
49) stesk po Jave
Autori tak tesknili po Jave, ze pred kazdy atribut tridy (konstruktor, instancni promennou, metodu) napsali demonstrativne "public:" ;-)
50) chyba v Matrixu
Predstavte si zjevne nevalidni model. Na nekolika mistech jsou fatalni chyby. Presto autori pisi, ze jeho vysledky se SHODUJI s udaji z vyrocni zpravy modelovaneho podniku. Jak si to vysvetlit?
51) studenti miluji rebusy
Posudte sami. Dejte tomu minutku a zkuste prijit na smysl nasledujiho kodu procesu:
while (1) {
unsigned zam = 10;
while(zam > zamestnanci.Free() & zam > 0)
zam–;
if(zam == 0) {
WaitUntil(zamestnanci.Free() > 0);
continue;
}
Enter(zamestnanci, zam);
// dale...
}
Mate to? Smysl je prostinky: proces chce zabrat aktualni dostupnou nenulovou kapacitu skladu. Je mu jedno, kolik zamestnancu si vezme, chce proste vsechny volne (nejvyse vsak 10). Pokud tento kod provadi vice procesu, tak se nejspis sesynchronizuji na WaitUntil a nasledne jeden vstoupi do Enter. Dalsi budou znova wait-untilovat.
Zapis "zam = std::min(zamestnanci.Free(), 10)" je prilis nudny, takovy bez fantazie ;-)
52) Model spanku zakaznika
wakeUp:
if(((int)Time)%(2460)){
if (verbose) std::cout "Customers sleeping" std::endl;
Wait(10);
goto wakeUp;
}
// uz je den
Vsimnete si, ze zakaznik ma hodne trhany spanek ;-) Podobne v modelu spi i auta ;-) Snad se da vypocitat okamzik zacatku pracovni doby a na ten dat jeden Wait.
Link to this Page