Още една причина поради която избягвам използването на NodeJS

Не, няма да хейтя, въпреки че NodeJs има толкова матял за хейт и сърказъм.

Проблемът за който искам да споделя не е бъг, а е фундаментална грешка в NodeJS, която едва ли някога ще се оправи. Говоря за асинхронността, и най-вече, че според NodeJS религията всичко трябва да бъде асинхронно.

Тази псевдо асинхронност (nodejs работи само на една нишка) често помага и много процеси са изградени и модифицирани за да се „възползват“ максимално от нея, обаче има едни ситуации в които става кошмарно. Нека да ви дам реалистична постановка.

Да приемем, че имаме библиотека, която има метода addAgent(). На този метод трябва да се подаде външен обект, писан от мен, който има метода invoke(param1,param2). Библиотеката в даден момент ще извика този мой метод с тези параметри и очаква отговор от него. Важното в случая е, че библиотеката очаква точно определен отговор (обект) с който да може да работи веднага.

До тук всичко е прекрасно, нали? Обаче аз искам в метода invoke() да направя мрежова заявка за да мога да си свърша работата. Обаче в NodeJs мрежата е асинхронна, което означава, че метода invoke() връща веднага с null, което чупи всичко. Отново казвам, че библиотеката чака отговор и иска да работи веднага с него. NodeJS няма решим на синхронна мрежова заявка, така в която метода чака или както е правилно да се каже „да блокира“.

Естествено, аз не съм експерт в NodeJS и започнах да разпитвам хората които уж го разбират. Много е интересна демографията на NodeJS програмистите, това си е за отделна тема, но всеки започна да ми обяснява, че не трябва да го правя синхронно, това било много грешно.

Отне ми доста усилия да обясня, че самата библиотека, алгоритъма и целия процес които правя фундаментално е синхронен и НЕ може да се направи асинхронно. Ако успея да го направя най-вероятно ще съм решил Halting problem, само че е доказано, че това е невъзможно.

Разбира се, предложиха се опции. Едната е да се използват Promises, проблема обаче е, че метода ще върне Promise а не обект с който библиотеката да може да работи веднага. Не става.

Предложиха да се използва yield, само че yield ще върне генератор, а не отговора. Имаше и други забавни, креативни и умни предложения, но нито едно не става, просто защото проблема е в това, че фундаментално синхронна операция се опитваме да я изпълним асинхронно.

Накрая ми казаха да пренапиша библиотеката – сериозно? Да пренаписвам библиотека заради това? Ок, да приемем, че реша да го направя, тогава ще трябва да почна да работя с Promise, което значи, че аз трябва да пренапиша абсолютно цялата библиотека почти от 0 и резултата ще бъде, че тя ще изпълнява последователни операции, ама всяка една от тях ще е асинхронна, и докато асинхронната операция върви, всичко ще чака тя да свърши. Сериозно?

Естествено започнаха да ми обясняват, че този който е писал библиотеката нищо не разбира от програмиране и целия и дизайн явно е объркан, щом не я е предвидим да работи асинхронно. Не знам защо, ама това е много типично поведение за NodeJS програмист, щом не става по неговия начин значи е грешния начин. Само че тази библиотека и реализацията и е синхронна защото решава синхронен проблем. Не ми се мисли колко комплексно ще стане всичко с Promises или callbacks, предвид факта, че има и динамично програмиране в нея. А и имам сериозни основания да смятам авторите на библиотеката за доста сериозни и кадърни хора, много по-добри програмисти от мен.

Накратко – асинхронността на NodeJS може да е полезна в много случай, но не и във всички случай, и когато човек удари такъв случай няма оправяне. Идеално би било да дадат възможността на програмиста да решава дали да изпълнява нещо по асинхронен или синхронен начин. Има синхронни файлови операции, нали? Защо са ги направили? Ами нали искат всичко да е асинхронно, да ги махнат, пък да видим тогава реване и гимнастика как ще пишат елементарни програми за работа с файлове…

Един от отговорите които получих на този въпрос бе „Ами като не им даваме възможност програмистите се учат да пишат асинхронно и не правят глупости и не се карат кое как да е“. На това аз ще отговоря следното – NodeJS има претенции да е general purpuse mature programing language. Ако иска да е такъв трябва да позволява да се правят general purpose неща, а не да ограничава практики доказвани над 60 години от академици.

Накрая намерих решение, на някой му е писнало от тези простотии и е написал nodejs модул на C++, който прави синхронни мрежови заявки. Казва се netlinkwrapper.

След приключването на този proof of concept по който работя се махам от nodejs и не искам и да го погледна повече. 4 дни прекарах в търсене на начин за една шибана синхронна операция…

Дори и хората които правят CUDA оставят възможност за синхронност, а те са водещите в момента по отношение на паралелизъм и асинхронност.

 

 

 

Когато популизмът стане наистина опасен

Рядко пиша за политика и гледам да седя далеч от тези теми в този блог – политиката си е за политиците. Обаче великият неповторим стожер на България, единственият и ненадминат вокален експериментатор, завършил колеж за непорочни девици, винаги правият Слави Трифонов, започва да бута нещата към много, ама много опасна пропаст.

Естествено говоря за прочутия му референдум и най-вече факта, че част от въпросите ще бъдат изпратени за тълкуване от Конституционния съд. И този господин с цялата си медийна власт обяснява колко ужасно лошо е това и как цялото управление (включително и опозицията) се опитвали да пренебрегнат „желанието на народа“.

Нека да изясним няколко неща – първо, не народът е измислил тези въпроси, а някой от неговия екип (надявам се). Референдум ще има, това е ясно, даже и датата е ясна. Никой не прескача никого и нищо. Не съм психиатър или психолог, но нещата малко ми приличат на шизофренична параноя. 20+ години този господин само обяснява как някой го мачка, респективно народа, как все има конспирация срещу него, следователно срещу народа, как все някой нещо нередно прави, разглеждайки частни случаи, махайки контекста на глобалното… Как един път не похвали някого…

Обаче този господин, който, както предполагам се досещате, не уважавам, излиза с тежки тези и тълкувания и цитира чл. 1 на Конституцията, който гласи:

Цялата държавна власт произтича от народа. Тя се осъществява от него непосредствено и чрез органите, предвидени в тази Конституция.

Неговото тълкование е, че щом властта произлиза от народа, народът може да си прави каквото си иска, обаче обърнете внимание на второто изречение:

Тя се осъществява от него непосредствено и чрез органите, предвидени в тази Конституция

Тоест, най-важният закон казва ясно, че властта на народа НЕ е абсолютно директна, а преминава през органите, които спазват правилата на тази конституция. И в същата тази конституция (и законите произтичащи от нея) пише много ясно, че референдум НЕ може да се свиква по въпроси от компетенцията на Велико народно събрание. Следователно, ако трябва да се спазва закона, за което този господин непрекъснато реве, референдум по някои от въпросите не може да се проведе, защото самият референдум ще наруши конституцията и всеки българин гласувал по тези въпроси ще наруши Закона.

Ето за това има конституционен съд, съставен от юристи с достатъчно опит и разбиране, за да могат да решават да или не. Не разбирам как сезирането на законен орган по въпрос от компетенцията му, може да се интерпретира като опит за манипулация.

Какво толкова ще си кажете, някой си реве, кое му е опасното, референдумите са хубаво нещо. Ами конкретно 3 въпроса са изключително опасни, и ще се опитам да ви обясня моето лаишко виждане на на нещата.

Въпрос 1

Подкрепяте ли народните представители да се избират с мажоритарна избирателна система с абсолютно мнозинство в два тура?

Ох боже, даже не знам от къде да започна. Може би като обясня какво ще стане, ако това се приеме – това означава (най-грубо), че ще се гласува за конкретни хора а не за партии. Това е най-краткият път за създаване на феодално управление. Някой „богаташ“ в по-малък град ще „помогне“ на някоя „личност“ да бъде избрана и тази личност, която в никакъв случай няма да бъде в зависимост и конфликт на интереси, директно заминава за парламента, без значение от коя партия е. Прекрасно, и в един момент ще имаме 240 човека, които обслужват директно интересите на някой местен батка с авангардни маниери и съмнителни интереси. Не всички са такива, но проблемът е, че се разбива едно основно звено в сегашната политическа система – политическите партии и тяхната сила да взимат единно решение.

В момента партията излиза с политики, единна позиция и лидери. Представете си консенсус между 240 човека, които директно обслужват интересите на точно определени хора в различни части на страната? Е, аз не виждам как ще стане.

Но нали все пак това е идеята? Тези хора да се грижат за интересите на народа и районите, от които са избрани? Така е, само че понякога има форсмажор, външна политика, приоритети и какво ли още не, което изисква ЕДИННОСТ.

На една сграда пише „Съединението прави силата„. Приемането на този въпрос няма да доведе до съединение, а до дърпане и късане на малки парчета от това, което е останало. Опитайте се да разберете колко фундаментална промяна е това, погледнете малко историята. Доста по-малки промени в управлението са водели до ужасни последствия.

Въпрос 2

Подкрепяте ли броят на народните представители да бъде намален на 120

Не, не, и НЕ. Намалянето на броя на депутатите ще доведе до по-трудно формиране на мнозинство, колкото и противоречиво да ви звучи. Помислете си само, при 240 депутата един пръст обърна цялата политика на България преди години. Говоря за Волен Сидеров и последвалите безумия. Статистиката и простата математика са доста ясни тук, при 120 човека НЕ може да има ефективно работеща система.

Може би ще изтъкнете аргумента, че в някой по-големи държави от нас имат по-малко депутати, и сте прави, но те имат други закони, правила и интереси. Тази цифра не е измислена от нищо. Тя е съобразена с законите, народа и политиката. Аз лично бих гласувал броят им да се увеличи, вместо да се намаля. И не, депутатските заплати и премии не са толкова много на фона на общите държавни разходи.

Този въпрос в комбинация с първия означава даването на властта на една много малка група хора, която може да седи в сянка. Точно обратното на това за което се бори двуметровият еродит.

Въпрос 6

Подкрепяте ли директорите на областните дирекции на МВР и началниците на районните управления в областните дирекции на МВР да се избират с мажоритарна избирателна система с абсолютно мнозинство в два тура

Ох боже мои, искам да разбера по какви логически пътища са достигнали до този въпрос, може би съм прост и не разбирам, но ако това се приеме, отново означава, че не може да се прилагат общи политики на национално ниво, а всеки локален феодал ще си дърпа чергата към него.

Представете си малък град , 1-2 човека са богати, те са „помогнали“ за издигането на шефове на репресивните органи  в техния район и да кажем, че някой от тези господа е решил да се прибере пиян с новия си джип и прави инцидент. Този, който ще трябва да го съди/разследва/арестува, е този, който е в зависимост от него. Има ли смисъл да продължавам? Имате виждане за действителността в България, имате и въображение. Помислете…

Комбинацията от тези 3 въпроса реално правят така, че местни феодали ще имат абсолютна власт и ще са тотално недосегаеми. Останалите въпроси от референдума за мен са напълно нормални, но тези 3 са меко казано опасни.

Може би някой ще изтъкне аргумента, че щом изборът ще е директно от народа, феодалът няма да може да сложи негови хора. Ако това е вашият аргумент, не знам под каква скала сте живели. В един малък град едно предприятие може да дава основния поминък. Какво ли ще стане, ако шефът на това предприятие „помоли“ всички свой служители да подкрепят опреден човек? Не, това не може да се случи, нали? Ха, Ха, Ха!

Една маймуна не се пуска от клона докато не се е хванала за друг. Това което се предлага е не да се пуснем от клона без да се държим за друг, а направо да си теглим куршума сами.

От кога куцо, кьораво и сакато си мисли, че може да представлява народа?

Какво представлява Dependency Injection (DI)

Този пост е инспириран от коментар в предишен пост където започна лека дискусия относно създаването на нови инстанции на обекти в самите обекти. Но нека да започнем от самото начало:

Какво точно е DI

DI е част от общо приети добри практики в програмирането подобно на S.O.L.I.D, които не са абсолютни и задължителни, но съобразяването с тях, доколкото е възможно, води до по-добра архитектура, намалява „спагети код“, премахва скритите зависимости, позволява по-доброто преизползване на код и много други хубави работи. D в S.O.L.I.D е за  Dependency Injection.

D в S.O.L.I.D е за Dependency inversion, което е различно от DI.
Много имплементации обединяват Dependency Injection и Dependency Inversion в едно.

Идеята е изключително проста, DI позволява класовете да не се интересуват от създаването на своите зависимости, а да ги получават на готово. Нека да видим следния код:

class Payment{    
    public function __construct(){
        $this->gataway = new PayPal();
        $this->db = new MySQLDB();
        $this->invoice = new Invoice();
    }
} 

Примера е изкуствено опростен, но мисля че се вижда ясно какво се опитваме да направим – да извършим плащане през PayPal, да го отразим в базата и да издадем фактура, като за това се грижи бизнес логиката в класа Payment, или още по-просто казано – имаме обект, който за да си свърши работата има нужда от външни за него ресурси.

И точно тук имаме огромен проблем, самият клас Payment създава всички свой зависимости в себе си, които от своя страна може да имат свой собствени зависимости. Това е изключително лоша практика поради много причини, но някой от основните са, че ние сме създали пряка зависимост – този клас за да работи трябва да има достъп до другите класове с техния namespacе и тяхната конкретна имплементация. Този клас може да бъде използван само в тази „среда“, ако решим да го изнесем като библиотека ще трябва да вземем и останалите класове от които зависи и да задължим потребителя който ще го използва да използва и нашите класове за DB, Invoice, PayPal. Това е кошмарно, никой уважаващ себе си софтуерен архитект не би допуснал това да се случи.

Другият, според мен, по-голям проблем е, че няма лесен начин за подмяна на имплементация. Какво ще стане ако имаме нужда в определена ситуация да използваме друг payment процесор, примерно Stripe? Останалата логика е еднаква, разликата е кой ще обработи плащането. Единия вариант е да правим различни „магии“ с наследяването или не дай си боже с рефлекции и магически методи (не го правете, така ще се застреляте, че няма оправяне). Другата опция е следната „класика“:

class Payment{    
    public function __construct($gataway){
        if($gataway=="PayPal"){
            $this->gataway = new PayPal();
        }
        else{
            $this->gataway =n ew Stripe();
        }        
        $this->db=new MySQLDB();
        $this->invoice = new Invoice();
    }
}

Изглежда сякаш проблемът е решен, но не е. Даже напротив, създали сме още по-лоша ситуация при която страдаме от всички недостатъци на предишния подход но сме добавили и допълнителни зависимости. Не е особено трудно да си представите какво ще стане с този конструктор след няколко итерации на продукта, добавяне на нови изисквания и имплементации – конструктор с прекалено много IF/ELSE и тотален кошмар при поддръжка, разширяване и тестване.

Инжектиране на зависимости

Значи излиза, че проблемът е в създаването на обекти в самия обект, добре, какво ще стане ако тези зависимости ги предаваме като параметри:

class Payment{    
    public function __construct($gataway,$db,$invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Изглежда сякаш проблемът е решен, обекта вече чака на готово зависимостите, но това е просто прехвърляне на сложността от едно място на друго. Преди сложността бе в самия обект, сега е задължение на този, който ще използва обекта да знае всичките му зависимости и да се съобрази с тях.

Кода написан по следния начина по-горе има и друг проблем, специфичен за слабо типизираните езици като PHP – конструктора приема някаква променлива, но тя може да е всичко, не сме задължили предаването на точно определен тип. Какво ще стане ако за $db се подаде String? Ами всичко ще гръмне. Конкретно в PHP това се решава така:

class Payment{    
    public function __construct(PayPal $gataway,MySQLDB $db,Invoice $invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Така задължаваме използването на точно определени класове, не може да подадем String или нещо друго в конструктора. Обаче все още не е решен друг проблем – какво правим ако искаме да сменим имплементацията, примерно искаме да използваме Stripe? Не може да подадем Stripe обект защото конструктора очаква PayPal обект. Едната опция, която в някой частни случай е добра, но като цяло трябва да се избягва е да имаме общ базов клас:

class PaymentProcessor{
    
    public function pay(){}
}

class PayPal extends PaymentProcessor{}

class Stripe extends PaymentProcessor{}

class Payment{
    
    public function __construct(PaymentProcessor $gataway,MySQLDB $db,Invoice $invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Забележете, че вече Payment не очаква Paypal или Stripe, а очаква PaymentProcessor. По този начин, ако някой реши да си прави негов си процесор трябва само да наследи базовия клас PaymentProcessor и всичко ще работи, защото ние гарантирано, че метода pay() ще е наличен. Искам отново да отбележа, че това са изкуствено опростени примери, в реална ситуация може би ще е по-добре да се използва абстрактен клас, но всичко зависи от конкретните нужди.

Изглежда има напредък, махнахме зависимостите от самия обект, също така позволихме подмяна на имплементацията използвайки базови класове, но и това не е идеален вариант. Все още има зависимост към базовия клас – PaymentProcessor. Ако искаме да изнесем класа си в библиотека ще трябва да включим и PaymentProcessor заедно с неговите зависимости. Може да не ви се струва много, но колкото по-малко зависимости имаме, толкова по-добре. При по-комплексни системи тези „малки“ зависимости ескалират много неприятно.

Кодиране спрямо интерфейс

Нека да помислим какво е необходимо на класа Payment, като се съсредоточим конкретно за payment процесора, същите правила важат и а останалите класове.

Единственото необходимо е инстанцията която се предава да има серия от точно определени методи за да гарантираме, че когато Payment се опита да извика метода pay() той ще съществува. Как може да го направим като не използваме базови/абстрактни класове? Ами много е просто – интерфейси.

Ако не сте запознати (а трябва) интерфейсите са договор. Те нямат имплементация, те задължават класа който ги имплементира да има методите описани в интерфейса. Доста по-просто е отколкото звучи:

interface PaymentProcessor{
    
    public function pay(){}
}

class PayPal implements PaymentProcessor{}

class Stripe implements PaymentProcessor{}

class Payment{
    
    public function __construct(PaymentProcessor $gataway,MySQLDB $db,Invoice $invoice){            
        $this->gataway = $gataway
        $this->db = $db;
        $this->invoice = $invoice;
    }
}

Разгледайте кода по-горе внимателно, разликите са много малки, но много съществени. Създаваме интерфейс PaymentProcessor който задължава всеки клас който го имплеметира да има метода pay(). След което казваме на класа Payment, че ще приема само и единствено обекти, които са имплементирали интерфейса PaymentProcessor. По този начин е гарантирано, че обекта ще има метода pay() и няма да изгърми с МethodNotFound  или подобно.

Но най-голямото предимство на кодирането спрямо интерфейс е, че ние нямаме зависимост спрямо имплементация. Когато се използва базов/абстрактен клас ние имаме серия от методи, които имат конкретна имплементация (в базовия клас) и задължаваме всички да се съобразяват с нея. А това е излишно. Единственото от което се интересува класа Payment е да има обект, който има метод pay() който ще извърши плащането и евентуално ще върне резултат. Каква е имплементацията на pay() няма значение.

И сега ако искаме да изнесем класа си в библиотека ще е лесно, ще трябва да включим само интерфейсите и никаква конкретна задължаваща имплеменация. Това е основата на така наречения Dependency Inversion, някъде може да срещнете абревиатурата IoC (Inversion of Control) което е същото нещо, като изключим семантичните разлики и дефиниции, но това не е DI, това е техника която работи много добре с DI.

Още проблеми

До момента решихме един от проблемите, а именно как да премахнем ненужните зависимости като кодираме спрямо интерфейс, и това само по себе си е много добре, но все още остава сложността по създаването на обектите – за да направим нова инстанция на Payment ще трябва да направим нова инстанция на класове за PaymentProcessor, Invoice и DB. На пръв поглед това не е кой знае какъв проблем, все пак всичко е ясно и стриктно. Обаче не е точно така. Нека разгледаме следната ситуация, на много места в програмата ни ще имаме нужда от база данни, и ако сме добри програмисти ще сме кодирали базата данни спрямо интерфейс, и там където трябва база данни ще си правим конкретна инстанция и ще я предаваме на различните обекти. Примерно:

interface iDB{
    
    public function select(){}
    public function insert(){}
}

class MySQLDB implements iDB{}

class PostgresqlDB implements iDB{}

class User{
    public function __construct(iDB $db){}
}

class Account{
    public function __construct(iDB $db){}
}

$db = new MySQLDB();
$user = new User($db);
$account = new Account($db);

Едва ли някой някога някъде ще реализира DB по този начин, но опитайте се да разберете идеята, а не конкретната имплементация.

Правим инстанция на конкретен клас и го предаваме на всички обекти, по този начин, ако решим в един момент да използваме PostgresqlDB само ще трябва да сменим инстанцията. Обаче на практика нещата не са толкова прости. Имаме стотици обекти със своите зависимости, ако трябва да сменим имплементацията ще трябва да отидем ръчно да я сменим на много места. Предполагам веднага се досещате, че може да използваме нещо като Registry или „глобална“ променлива, която ще държи инстанцията на DB. Тоест, само на едно място правим new iDB и всички които зависят от нея използват тази „променлива“. Така ще се наложи да сменим кода само на едно място. Звучи логично, но практиката сочи друго.

Използването на глобални променливи и Registry само по себе си води до проблеми, но най-вече ако се избере този подход какво правим, ако различните класове имат нужда от различни инстанции. Един и същи клас, просто различни инстанции. Понеже държим само една инстанция в глобална променлива (или някъде другаде) всички ще ползват една и съща инстанция, което често е нежелано.

Също така често се случва да правим инстанция на клас и да предаваме зависимостите му, които обаче също имат зависимости, които също имат зависимости….

Много бързо може да попаднем в ситуация при която е много трудно да напишем код за нова инстанция. Не защото нещо не е ясно, а защото е много „замотано“ и управлението на всички тези инстанции може лесно да се превърне в една голяма безумна серия от IF/ELSE забутани в някой файл с коментар от типа на:

While writing this code only me and god knew hоw it works. Now only god knows

DI в действие

DI е механизъм, който (най-често) използва кодиране спрямо интерфейси за да оправи цялата сложност по създаването на новите инстанции и тяхното инжектиране. Различните езици и библиотеки имат различни имплементации, но всички се свеждат до следните прости стъпки:

  • Пишете си кода спрямо интерфейси
  • Декларирайте зависимости на обект като опишете интерфейсите в конструктора на обекта
  • Дефинирайте коя конкретна имплементация трябва да се използва е момента (най-често в конфигурационен файл) и решете какво да е поведението и, дали да е само една, или всеки път да се прави нова инстанция

Това е, нищо сложно, понеже DI контейнера се грижи за всичко останало.

Ще се опитам да дам донякъде реалистичен (силно опростен) пример от света на PHP и Laravel как точно се случват нещата, но всички езици и frameworks имат множество DI библиотеки, които се различават и имат различни възможности.

interface SessionStorage{
  public function get( $key );
  public function set( $key, $value );
}

class FileSession implements SessionStorage{

  public function get( $key ){}

  public function set( $key, $value ){}
}

class MysqlSession implements SessionStorage{

  
  public function get( $key ){}

  public function set( $key, $value ){}
}

class Session{

  protected $session;

  public function __construct( SessionStorage $session ){
    $this->session = $session;
  }
}

App:bind( 'SessionStorage', 'MysqlSession' );

$session = $this->app->make('Session');

Нека да видим какво точно се случва тук. Първо правим интерфейс какво трябва да може да прави  всеки един SessionStorage клас. След това декларираме конкретните имплементации. До тук е ясно. Магията е в последните два реда.

App:bind( 'SessionStorage', 'MysqlSession' );

Тук казваме на Laravel, че когато нещо някъде има нужда от SessionStorage ще използва MysqlSession

$session = $this->app->make('Session');

А така караме DI контейнера да направи нова инстанция на Session, която зависи от интерфейса SessionStorage. В този случай обекта Session ще получи автоматично MysqlSession в конструктора си. Ако в последствие решим, че искаме да използваме FileSession ще трябва да сменим само един ред:

App:bind( 'SessionStorage', 'FileSession' );

Разбира се, това е много елементарен пример, но показва ясно колко работа може да си спестим. Този подход работи много добре с тестване, continuous integration и автоматизация, защото кое какво използва се определя на едно място, което може да е конфигурационен файл.

Също така повечето хубави DI контейнери имат много възможности, добавяне на условия кога коя имплементация да се използва, дали да е една за всички или не, тагове, рециклиране…. Но ако разберете тази проста идея няма да имате затруднения в разбирането на останалите детайли.

Някой от вас ще си кажат, че това може да го постигнете и с нещо като Factory. Има допирни точки, но при Factory шаблона трябва да се опишете всичко на ръка, което ще доведе до безумна серия от IF/ELSE или нещо подобно. С DI този процес е автоматизиран. Също така в PHP света (и не само) има тенденция да се правят спецификации и стандарти за интерфейси. Примерно какви са интерфейсите за кеширане, за HTTTP заявки и подобни, и всички библиотеки започват да пишат спрямо тях. При използване на DI и общи интерфейси може да подмените огромна подсистема само с един ред код.

Недостатъци на DI

Това не е панацея, DI има своите проблеми и недостатъци, но ситуацията е, че тези недостатъци са по-малкото зло, а и някой от тях може да се премахнат или намалят използвайки добри практики. Ето някой от основните критики.

Кода ни е силно зависим от самата DI библиотека Не може лесно да сменим DI контейнера. Иронично DI, който се бори със зависимостите, създава зависимост. Но според мен това не винаги е проблем, от гледна точка, че DI е част от framework-а който използваме, Ако имаме причина да подменяме целия framework явно имаме по-големи проблеми от DI контейнера.

Често може да се загубим от интерфейси, особено при по-големи проекти. Решението на този проблем е добра софтуерна архитектура – нещо което така или иначе трябва да се прави независимо от езика и проекта.

Честа критика е, че DI реално скрива сложността и създава нов слой между частите на приложението ни. Еми, то тази сложност трябва да отиде някъде, нека поне да е на място където може да се контролира.

Изисква повече знания  – ами то сложен професионален проект така или иначе си ги изисква.

Забавя производителността – понеже DI ползва (най-често) рефлекция има известно забавяне понеже всеки обект трябва да се провери, да се види от какво зависи и да се вземе конкретната имплементация. В зависимост от конкретната реализация това време може да е доста сериозно. Също така има нужда от малко повече RAM. Но добрите DI контейнери са силно оптимизирани и отнемат само няколко милисекунди. Може да видите сравнение между различните DI в света на PHP  в този много детайлен пост (цък)

Заключение

Dependency injection е механизъм който се е доказал като успешна практика за големи дълги проекти, които се развиват с години. Концепцията е тествана в битки на много езици и като изключим някой части на чистото функционално програмиране, се препоръчва да се използва винаги когато може.

Времето за научаване на конкретен DI контейнер не е голямо, по-големият проблем е програмистите да сменят мисленето си и да започнат да пишат кода в контекста на DI.

Дори и да не се използва DI, писането спрямо интерфейси ще е полезно за проекта за напред. Много хора критикуват Java, че прекаляват с OOP и интерфейсите, но това е начина по който може да държите проект от няколко милиона реда код 10 години, който се пише от 1000 различни екипа и все още да работи и да се развива.

Разбира се, ако не сте фенове може да минете на чисто функционално програмиране 🙂

Уточнение:

В статията разглеждам две концепции, Dependency Injection и Dependency Inversion. Двете работят много добре заедно, но не е задължително винаги да се използват в комбинация. Може да имаме Dependency Injection без да пишем спрямо интерфейси, а примерно с абстрактни класове, също така може да пишем спрямо интерфейси и да не използваме Dependency Injection.

Как е подреден IT сектора в България

Забелязвам, че често хората, най-вече начинаещите, не са напълно наясно, че в България има 3 основни типа фирми в IT и ще се опитам да дам малко яснота. В никакъв случай тази статия не претендира за пълнота, идеята и е да опиша сбито основните сектори и техните основни разлики. Това не са абсолютни граници, някои фирми и проекти често не могат да се определят категорично в някой от секторите.

StartUp

Всеки е чувал този термин, ако сте поне малко на ти с компютрите малко вероятно е да нямате поне един познат, който да се е занимавал с някакъв StartUp. Но какво точно представлява това? Най-общо казано StartUp е новосъздаден продукт (независимо дали говорим за услуга или физически продукт) който получава финансиране от някой инвеститор в замяна на процент от компанията. StarUp фирмите често пробват новаторски и интересни идеи, които понякога успяват, понякога не. Самият бизнес модел е много комплексен и аз не смятам, че имам необходимите познания да го разисквам в детайли, но това не е целта на тази статия. Най-важното което трябва да разберат хората е, че инвеститори подпомагат новаторски идеи, при това не една и две. Голяма част от тези идеи няма да успеят, но инвеститорите са наясно с това. На тях е необходимо само малък процент наистина да успеят. Никой няма да се сърди, че 10 идеи са пропаднали, но 11-та се е оказала SnapChat. Това правят инвеститорите, хвърлят мрежата и виждат какво ще се улови в нея. Само че мрежата е много добре премислена, пресметната и анализирана.

Какви качества са необходими за да работите в StartUp

Основната идея на StartUp е максимално бързо да се извади продукт на пазара. Не е задължително той да бъде напълно завършен или перфектен. Най-важното е времето – всичко трябва да стане бързо. По тази причина основния тип програмисти които се търсят са средно и напреднало ниво. Може би най-характерното за този тип компании е тяхната нагласа и желание да „променят света“, да извадят следващия продукт който ще се използва от всички, или ще реши някой сериозен проблем. По тази причина се търсят хора, които вярват в тази идея, мотивирани са това да се случи, и са склонни да отделят повече от своето време и енергия, отколкото принципно се изисква.

Какви са заплатите в StartUp

Няма как да обобщя заплатите в толкова разнороден сектор, също така много зависи в кой етап от развитието си е проекта, но често се предлагат по-ниски заплати в замяна на процент от фирмата. А понякога заплатите са по-ниски само срещу обещание за бъдеща по-голяма заплата при „гарантирания“ успех на продукта. Може да мислите за това сякаш служителя влага собственото си време и умения в продукта, а не средства, както инвеститора. Ако продукта стане успешен тогава заплатите ще зависят от конкретната политика на фирмата.

Предимства

  • Често се започва от самото начало, без наследен код и технологии
  • Решенията се взимат от екипа
  • Често се експериментира и се използват най-новите технологии, които дори не са се доказали. Всичко е на гребена на вълната
  • Силно мотивирани хора
  • Реална възможност за сериозни приходи, ако продуктът успее

Недостатъци

  • Всичко се променя в движение
  • Динамиката и натоварването са доста големи, което за някои хора може да не е комфортно
  • Рискът за провал не е малък. Не кода и техническата реализация са основната причина за „провал“ на StartUp

Продуктово-ориентирани фирми

Много фирми имат екипи, които разработват един или няколко продукта, които обслужват самите фирми. Типичен пример е компания, която разработва счетоводен и ТРЗ софтуер. Това е продуктът, всички работят по него, компанията го продава. Разбира се, има много вариации, може да се разработва продукт който обслужва нуждите на други фирми. Обикновено всички решения за развитието на този продукт се взимат от фирмата която го разработва. Това позволява по-детайлно планиране и управление на процеси и ресурси.

Какви качества са необходими за да работите в продуктово-ориентираните фирми

Тук няма ясни тенденции, има всякакви примери. Поради недостиг на персонал много фирми имат стажове, обучителни програми или цели академии. Не е рядкост в тези компании да започват хора с малко знания и практика като се залага на потенциала на кандидата. Точно за това са тези стажове и обучения, за да се преценят кандидатите в които ще бъде инвестирано. В момента продуктово-ориентираните фирми са предпочитани от повечето старши програмисти заради множеството предимства и по-балансираната работна среда и условия на труд.

Какви са заплатите в продуктово-ориентираните фирми

Това е сектора с най-високи заплати. Отново правя уточнението, че това е обобщено. Винаги има изключения. Причината е, че самите фирми са заинтересовани да задържат служителите си, които са запознати със спецификата, някои от тях са станали тесни специалисти. Никой не иска да сменя части на добре работеща машина. Някой компании имат точно обратния подход, те са организирали процеса си така, че ако има голямо текучество на персонал, това да не повлияе на приходите, но по мои наблюдения тези фирми не са толкова много. В тези фирми заплатите са по-ниски.

Предимства

  • Добро заплащане
  • Инвестиции в професионалното развитие. Платени курсове, платени билети за конференции и подобни
  • В повечето случаи добре подреден работен процес
  • Ясни отговорности, задължения и задачи
  • Ясна визия какво трябва да се случи
  • Дългосрочни отношения
  • Специализиране и развиване на сериозни умения в точно определени технологии. За някой това може да е недостатък, но аз го намирам за предимство.

Недостатъци

  • Много рутинна работа и еднообразие. За някой това може да е желано.
  • Свръх тясната специализация закърнява други умения. По тази причина някои компании периодично сменят задачите на служителите си за да може да се развиват  и в други технологии
  • Често се работи с наследен код и технологии, чиято подмяна е трудна, ако въобще е възможно.

Аутсорс и дигитални агенции

Това е най-големият сектор в България, който буквално се къса по шевовете. Най-голямото търсене на специалисти е точно тук. Ако не сте запознати с термина, аутсорсинг, най-грубо може да се опише като наемане на група от специалисти за решаването на точно определена задача. Не е необходимо да бъде цялостен проект, може да бъде една малка част от по-голям проект. Някои компании предлагат цялостен пакет услуги, от дизайн, разработка, поддръжка, SEO … Най-голямата особеност на този сектор е, че клиентите често не са технически лица. За пример, местна пицария иска страница и мобилно приложение. Те са добри в пиците, не в IT, за това се свързват с някоя дигитална агенция, която изгражда всичко необходимо. Друг пример е голяма компания разделя свой проект на по-малки части и ги разпределя на няколко екипа по света, като всеки екип прави само малка част. Това се прави за намаляване на риска, намаляване на разходите и отпадането от поддържането на голям IT отдел.

Какви качества са необходими за да работите в аутсорс и дигитални агенции

България е предпочитана локация за по-бързо реализуеми проекти. Разбира се има и изключения, но повечето поръчки са за малки локални проекти и временни нужди на маркетинга. Поради тази причина, заедно с факта че липсват над 33 000 специалиста, в аутсорс сектора повечето хора са начинаещи или напреднали. Никой няма да откаже на старши програмист или старши дизайнер, но  тенденцията е старшите да се махат от аутсорса започвайки свой бизнес (startup или freelance) или минавайки в продуктово-базирани фирми. Това е най-лесният сектор в който начинаещ програмист може да влезе в „играта“ и да започне да трупа реални умения и практика. Искам да спомена за една малка група фирми в България, които са аутсорс, но са се специализирали в дългосрочни, сложни и мащабни проекти. При тях обикновено се взимат старши специалисти и управлението им се доближава до това на продуктово-базираните фирми.

Предимства

  • Лесно се започва работа в тези компании.
  • Обикновено се работи с модерни и актуални технологии. Може да ги видите как работят на практика.
  • Има голямо разнообразие, понеже екипите и проектите се сменят често. За някой това може да е недостатък.
  • Често е необходимо да имате множество умения в различни технологии и можете да прилагате и развивате тези умения.
  • Отговорността на служителя е ниска. За някой това може би е недостатък.

Недостатъци

  • Ниско заплащане с ограничена възможност за растеж. Заплата на служителя е пряко свързана с цената на която е нает. Разбира се, има и изключения, ако фирмата е договорила по-високи цени на час.
  • Клиентите често не са технически лица. Комуникацията с тях е проблематична и често заданията са неясни или технически невъзможни. Добре организираните компании имат PM и AM които седят между клиента и програмиста, но често има фрустрация.
  • Работи се с голяма динамика. Клиентът е платил за точно определени часове, които са договорени преди началото на проекта. Предоговарянето на цената и крайните срокове е  труден процес.
  • Текучеството на хора е голямо.
  • Ограничено кариерно развитие. Тук също има изключения.
  • Понякога има проект чието задание е да се оправят „белите“ от предишна аутсорс фирма. Пренаписването не е опция. Клиентът вече е инвестирал сериозна сума и е трудно да му се обясни защо трябва да дава същите пари за същото нещо отново.

Няма да разглеждам другите два „сектора“ – R&D и freelance, понеже R&D в България е наистина малко, а freelance е толкова индивидуално, че ще е глупаво да се опитам да слагам някакви граници. Но все пак ще спомена с няколко думи, че при freelance всичко зависи от вашите умения да намерите добрия клиент. Има freelance които взимат по $50 – $100 на час, но има и такива които работят за $5 на час. Всичко зависи от вашите умения, контакти и имидж. Най-специфичното при freelance е, че вие сте човека армия, вие сте мениджър на себе си, вие сте PM, вие сте AM, вие сте изпълнителя. Мит е, че при freelance нямате шефове и разполагате с времето си напълно. Най-трудното нещо е да намерите правилните клиенти и да изградите подходящото доверие, за да може да започнете да взимате високото заплащане. Но ако успеете може да вадите изключително високи доходи, високи не за България, а високи за която и да е точка на света. Не е рядка практиката няколко приятеля с различни умения да работят заедно като freelance по общи проекти, и така да започнете свой бизнес. Един full-stack разработчик, един дизайнер и можете да започвате.

Заключение

Опитах се максимално сбито да посоча предимствата и недостатъците на сектора, но сами виждате, че някой от нещата могат да бъдат определени като добри или лоши в зависимост от вашата нагласа. Със сигурност има пропуснати детайли, и ще се радвам да ги споделите в коментарите. Няма знатни правила, няма ясни граници. Всичко се свежда до конкретна фирма. Ако нито едно от горните не ви допада, винаги има опцията да опитате да направите нещо свое. StartUp не е единствената опция за започване на собствен бизнес.

 

 

 

Защо съм „зъл“ на интервютата

Вчера водих поредното интервю и след краят му колегата който също участваше ме погледна учуден и ми каза в прав текст – „Ти си голям задник, защо така закопа това момче„.

Наистина бях леко агресивен, но не в смисъла на физическа агресия, а в смисъла, че показах на момчето колко нереалистична представа има за уменията си, пазара на труда в България и като цяло в IT сектора.

Нека да дам малко контекст, преди да се опитам да обясня основната теза. Момче на около 28 години, с завършено техническо образование и 8 години професионален опит в IT, в частност  PHP. Според CV-то е почти идеалния кандидат за нас. Но както се казва – „На думи и CV-та всички сме богове“, за това има серия от интервюта, за да се види кой кой е.

Започнах да задавам стандартни въпроси за да се ориентирам най-общо за нивото му, интересно бе, че не знаеше коя е последната версия на PHP, според него бе 5.6. Също така не знаеше какво представляват traits, нещо което го има в PHP от 2012 година. Добре, казах си аз, не му се е налагало да ги ползва – не ги е ползвал. Ако може да мисли ще разбере колко хитра идея са и как се използват ефективно. Следващият ми въпрос беше „Каква е разликата между предаване по стойност и предаване по референция“ при което разбрах, че дори не знае каква е тази концепция. Не в PHP, а като цяло в програмирането. Хайде стига де, 8 години практика, техническо образование и да не знаеш, че съществува такова нещо е все едно да попиташ счетоводител каква е разликата между дебит и кредит и да получиш отговор „Не знам, никога не съм ги ползвал“. А тази концепция има значение, има ОГРОМНО значение, когато се пише код. Повечето езици я правят „прозрачна“, не се налага да се мисли, но когато кода зависи от нея и не се съобразиш – страшни бели стават.

Човека искаше доста висока заплата, не мога да кажа колко заради конфиденциалността, но да кажем, че искаше повече отколкото взима Президента и Министър председателя на България. Лошо няма, докато не си поискаш никой няма да ти даде, а и всеки работодател ще е щастлив да плаща 100 лева на месец вместо 1000, и всеки трябва да иска толкова колкото смята, че заслужава, но не това е от значение. От значение е каква бе неговата самооценка за уменията му и за пазара на труда в България.

Той се определя като senior developer  в PHP и MySQL и смята, че заслужава такава висока заплата. Ето тук е проблема, динамичния пазар на IT в България и хроничната липса на специалисти води до такова разглезване и нереалистична преценка. Липсват над 33 000 специалисти в сектора (според някой анализи са и повече) и всевъзможни фирми почнаха да промотират всевъзможни курсове с гръмки заглавия от типа на „Стани програмист за 2 месеца, стартова заплата 3000 лева чисто„. Разбирам тези фирми, има пазар – експлоатират го, а вече стана и силно конкурентен, нормално е да има подобни изцепки, но никой няма да даде 3000 лева на начинаещ, нека бъдем реалисти. А в конкретния случай човека искаше доста, ама доста над 3000. Да, единични фирми може и да дадат такава заплата на начинаещ, защото са отчаяни, или искат да изчистят едни пари, но това са изключенията, не правилото.

Помислете си, 3000 лева на месец – чисто. Приемаме, че това е заплатата която обещават разни фирми ако завършите курсовете им. Това са 1500 евро. Предполагам имате познати във Германия, Англия, Франция…. попитайте ги колко взимат хората там, но СЛЕД данъците. С колко пари се прибират в края на месеца? В някой държави данъците са над 60% от заплатата. Ще го кажа така, много хора на запад ще са много доволни ако успеят в края на месеца да имат 1500 евро в джоба си. Не че няма по-високи заплати, има, но тук говорим за някаква сравнителна линия между България и запада, който винаги ни се бута за пример, нали за да успеем да разберем дали дано нещо е малко или голямо трябва да го сравним с нещо друго. Колко взима един човек, който тепърва започва своята професионална кариера?
3000 лева на месец за българския стандарт, ами някой хора и за 1 година не вадят по толкова. А ако имате собствено жилище и не плащате наеми бих казал, че не е толкова зле. А ако пък сте добри и взимате повече от 3000, което е нормално за нашия пазар, още по-добре.

Защо тогава така сериозно ударих егото му, защо бях толкова остър, нали до сега обяснявам, че всеки може и трябва да иска колкото заслужава?

Отговорът е много прост, след интервюто той може да направи 2 неща, едното е да си каже „Егати и задника, на какъв ми се прави тоя, за какъв се мисли, по-добре, че няма да работя с такива кретени“ и ще бъде прав, в неговите очи и в неговия свят. Ще продължи с нереалистичните си самооценки и очаквания и в един момент някак си ще излезе, че всички в тази държава са кретени, задници и не го оценяват. „Аз съм егати пича, но България не ме обича„. И ще бъде прав, за него си, в неговия малък свят, тотално откъснат от реалността.

Другото нещо което може да направи е да си помисли „Чакай малко, изложих се, но се изложих не защото този задник е по-добър от мен  – изложих се защото уменията ми не са на необходимото ниво и претенциите които имам може би надскачат реалните ми възможности. Я да си седна на задника и да стана по-добър. Има толкова много книги, курсове, уроци, материали. Просто трябва да седна и систематично да повиша нивото си – да стана по-добър специалист.

Вие преценете кое е по-правилното, аз акъл не давам. Всеки сам избира как да е нещастен, но егото на човек понякога трябва да бъде мачкано, защото това е един от най-ефикасните начини за корекция на самооценката. И не, не говоря за гаврене, извращения и унижения, но човек не може да се самооцени. Самооценката е следствие от средата, казано по-ясно – самооценката се изгражда спрямо обратната връзка на хората с които общувате. Не всяко чуждо мнение е вярно, но сумарно обратната връзка дава доста добра представа за реалността. Ако трябва да влизаме в чисто философски разсъждения може даже да кажем, че реалността е изградена от обратната връзка на нашите действия със средата, но нека да не задълбаваме.

За това съм задник, и смятам, че така трябва да се постъпва в подобни ситуации. Може би не е професионално, това е единствения разумен аргумент заради който често се сдържам.

Ако искате да бъдете добър в каквото и да е трябва да имате ясна преценка за уменията си и това е наистина трудно за постигане. Причината е така наречения „Dunning–Kruger“ ефект. Може би сте чували израза „Толкова си тъп, че не можеш да разбереш колко тъп си„. Това е доста циничен вариант на горепосочения ефект който накратко гласи, че колкото по-некомпетентен е даден човек, толкова по нереалистични са неговите представи, очаквания и преценки. Правени са стотици, ако ли не и хиляди проучвания по темата, и всички водят до един и същи извод – добрия специалист не е този, който има най-много умения, а този, който има реална представа за своите умения.

„Dunning–Kruger“ ефекта често се визуализира със следната диаграма:

Тя доста ясно показва, че в началото хората имаме много грешна представа за това какви са ни уменията, след което постепенно преценката ни започва да се коригира спрямо опита и обратната връзка от хората и средата, до момента в който реалността и нашата представа за реалността съвпаднат.

Самата тема е изключително интересна (заради това откритие авторите получават Нобелова награда) и има страхотни статии които разкриват много „мръсни“ детайли от човешката природа, които реално са виновни за това поведение, но егото влияе много в тази крива, особено в началото.

За това съм задник (понякога), защото колкото по-бързо започне кривата да спада, толкова по-бързо човек ще се „оправи“. Който иска да ми се сърди да ми се сърди. Който мисли, че съм гадно копеле, ами гадно копеле съм, но за тези 10-на процента от хората, които ще си седнат на задниците и ще разберат, че са в грешка, това ще е полезно и от тях ще излезе нещо стабилно.

На мен ми се случи същото нещо в началото на професионалното ми развитие, но с доста по-тежки последствия. Така ми „набиха канчето“, че трябваше да се консултирам с терапевт. Тогава псувах, обиждах, ненавиждах и имах такава агресия в себе си, че бе плашещо. Сега обаче съм благодарен на тези хора, че много рано ме свалиха на земята, защото после щях да падна от още по-високо.

Без бой не става, боя изгражда, той не разгражда“ – много умни думи на Камен Донев. Дали ще е физически бой или бой по егото няма значение. Ви да познавате боксьор който се е научил да се боксира без да са го били? Лекоатлет без навяхвания, разтежения и подобни контузии, музикант без лоша песен? Няма, няма и да има, защото точно тези „неуспехи“, „провали“, „унижения“, „травми“ са нещото, което бутат кривата в правилната посока.

Така че, шамар от един задник може да бъде много по-полезен от похвала от един пухльо!

Ако все пак не сте ме разбрали, аз не съм закопал човека с трудни въпроси (от алгоритми или структури от данни), аз го питах елементарни неща. Човека идва с претенции за старши, иска заплата на старши, казва, че последните няколко години е работил като старши а не може да каже каква е последната версия на технологията в която е „старши“. Едва ли има работодател който ще взема на сериозно човек, с претенции за „старши“ който не знае дали има разлика между малки и големи букви в имената на променливите – сериозно? Въобще не се стигна до нормалните въпроси за „старши“. Ако момчето имаше покритие на претенциите си, заплатата която поиска е напълно реалистична за нашият пазар, и най-вероятно щеше да я получи.

Коментарите ескалираха неочаквано много. Единственият проблем с момчето бе, че силно е надценил текущите си умения. Това не го прави лош човек, лош разработчик, още по-малко означава, че не може да се развие. Всеки е бил начинаещ в един момент, всеки се е учил, всеки се е надценявал.

Уточнение:

Не знам защо но много от вас си помислиха, че аз съм обиждал или унижавал момчето. Не е така. Който ме познава знае, че за да обидя някой трябва доста да се е постарал. Това което направих е, че не му помагах да отговори на въпросите които задавах и просто му задавах друг въпрос. Когато това се направи с подходящата интонация има силен ефект, но наистина, аз МНОГО рядко си позволявам да обиждам, осъждам или злепоставям човек, ако го правя, го правя по най-недвусмисления начин.

Уточнение 2:

Моля за разбиране за правописа и граматиката. Не мога да направя нищо по въпроса. Причината е състояние, което не ми позволява да се оправя с правопис и граматика. Мислете за това като недъг, а не като некадърност. Опитвал съм се, но е извън възможностите ми. Отнема ми около 10 секунди да разбера кое е буквата ч и ц във всяка една дума. Срам ме е, но и невролозите не са сигурни защо е така. Мога да чета по 5-6 страници в минута осмисляйки съдържанието, но не мога да пиша грамотно. Извинявам се и моля за разбиране. Благодаря!

Уточнение 3:

Ама то аз съм за бой, цялото това чудо е било заради такова глупаво неразбиране, че момчето е искало 3К, а аз съм смятал, че това е било прекалено много за старши програмист в България.
Добре, дължа извинение на всички в този случай. Всеки който се е почувствал засегнат моля да ме извини, ако е възможно. Нека да се опитам да изясня нещата, доколкото е възможно на този етап:

-Момчето искаше МНОГО повече от 3000 лева.
-Според мен 3000 лева чисто на месец за старши програмист в България клони към долният минимум на реалните заплати в момента. Има фирми, които се опитват да минават „тънко“, но 3000 и нагоре е повече от нормално и реалистично за старши програмист в България.

И отново се извинявам за това недоразумение, не зная как се е получило, близки мой хора четоха публикацията и НЕ я разбраха грешно.

Интересни роботи във Facebook

Днес ми се случи нещо доста интересно, поглеждам във Facebook да видя някакви неща по курса и виждам, че имам интересна покана за приятелство от девойче с френско име. FB ми казва, че имаме много общи познати. Стана ми интересно, все пак имам познати във Франция и общувам често с чужденци, помислих си, че е наистина е някоя личност, с която сме имали общо. Я по конференции, я по някой проект.

Профилът изглежда нормален, снимки, месторабота, някаква що-годе реална активност. Решавам да приема поканата и буквално 5 секунди след приемането получавам съобщение от девойчето, което ми се извинява, че ме е добавя като приятел без да се познаваме и изтърсва някакво замотано извинение.

До тук добре, но тук започва интересното, тя започва със серия „общи“ въпроси от типа на от къде съм, с какво се занимавам, като всичко става под формата на диалог и тя „споделя“ същите неща за себе си. Много правилен изказ, използване на разговорен английски и следене на контекста на разговора, реално пише по-добре от мен и има по-добър изказ от мен.

Разговора се развива доста бързо, но няма конкретна насока или цел, small talk както се казва, но отново отбелязвам, че всичко е в правилен контекст и логическа последователност.

Първото нещо което ми направи впечатление е, че скорошните и приятели са само българи. Помислих си, че знае български и за това писах едно съобщение на български. Тя ми отговори, че не знае този език. Разговора продължава с тази разлика, че тя явно започва да прави рапорт с мен – за незапознатите рапорт е предизвикване на симпатия и добронамерено отношение в отсрещната личност, което често се използва при свалки и подобни.

Разговора продължава, аз участвам в него, защо все още не съм разбрал коя е тази и за какво се бори. Тя започва да задава все по-лични въпроси, женен ли съм, деца имам ли, къде точно работя, как съм със здравето – само да отбележа, че скоростта на разговора е нетипично бърза. Повечето хора не могат да пишат толкова бързо без грешки.

Разбира се, когато непознат започне да ми задава такива въпроси моето правило е да не давам никаква информация. За това се нарича лично пространство, то си е за мен и хората които съм допуснал до него. Това си е мое нещо, така смятам, че е правилно в моя малък свят. Но тя продължава да прави по-силен рапорт и да настоява да получи подобна информация.

Всичко изглежда наред в разговора като изключим, че се запознава само с българи, пише страшно бързо и иска по много хитър начин лична информация. Французойка да пише на английски без грешки си е чудо само по себе си. Нищо против французите и техния интелект, но който е общувал с тях знае много добре какво им е отношението към английския.

Нещо започна да ми святка в главата, но не мога да определя какво е, а и взима да ми писва, аз съм на 33, свалки по FB – хайде да не е 🙂

Решавам да я питам от къде ме е намерила и ме е добавила – изненадващо тя се забавя при което получавам отговор „аз съм на 26 години“. Тотално извън контекст, тотално извън логиката на разговора. Може да е объркала чата, често се случва ако чатиш с 10 човека и естествено след около минута получавам съобщение „Извинявай грешен чат“.

Всичко е много добре, но аз отново задавам въпроса си, но под различна форма – как ме е намерила. Отново 1 минута мълчание и отново отговор извън контекста.

Тука ми светна, че може би говоря с бот, при това много много интелигентен бот. В последствие разбрах, че съм го извадил извън контекста заради словореда и правописна грешка на моите въпроси.

Сега вече със силно съмнение, че е бот реших да изпробвам до къде са му възможностите – първо прехвърлих разговора към чисто информационна тема и фактология. Бота последва контекста и да ви  кажа честно останах МНОГО изненадан, всичко бе точно, оставаш с впечатлението, че говориш с истински еродиран човек. Малко са лабораториите с интелект, който може да се оправи с това:

Аз: Преди много време бях в Богота, хубаво място

Бот: Винаги съм искала да отида в Колумбия, всички казват, че е хубаво място

Добре, казах си аз, явно си играя с нещо доста сериозно и продължих да го „тествам“ и единствения път когато се „дънеше“ бе когато имах наистина омазан словоред и правописни грешки, но въпреки всичко успяваше да се върне в разговора и контекста. За аматьор в невроните мрежи и AI като мен това си е доста впечатляващо.

Реших наистина да бутна нещата до край и си спомних един пост, в който автора обясняваше как може да излъже convolutional neural network за класифициране на изображения да си мисли, че куче на снимката всъщност е топка за бейзбол, и естествено бе (почти) успял манипулирайки само няколко пиксела (за съжаление не мога да намеря линк към статията)

Не искам да влизам в детайлите как точно става, и аз не съм напълно сигурен, понеже обяснението беше доста математическо, но мисля, че бях разбрал принципа. Всяка една неврона мрежа е толкова „силна“ колкото е нейното обучение. Когато NN попадне на сет който не е познат резултата често е random. Разбира се, това е много генерализирано обобщение на много сложна тема, но NN може да се оправя само с неща за които е обучена. NN обучен да разпознава животни на снимки може да намери куче независимо как е заснето и каква е породата му, но няма никакъв шанс да намери права лопата или голф 2-ка на снимката .

Започнах да правя изречения в стил Камен Донев : „гледа ли междузвездни войни, не мисля, че филма е по-хубав от марс, защото стартрек повече няма да се снима от дисни в русия“

Очаквах тотален краш, но въпреки всичко бота се опита да се върне в разговора, но определено нямаше запис който включва стартрек, марс, дисни, москва и междузвездни войни заедено. В този момент вече си личеше, че е бот, но още съм силно удивен как се опитваше да намери смисъл в това и да се върне в разговор, като някак си пак успяваше да попита за някаква лична информация.

Честно да ви кажа, това бе бот с превъзходен AI. Много хора биха се вързали веднага, че това е истински човек и биха получили симпатия към него. Някой даже биха казали, че този бот е по-умен и оправен от много девойчета във FB, и ако си седят в нормален контекст на разговор и започнат да флиртуват с него кой знае колко време ще отнеме, преди да разберат какво точно е това.

Сега като се замисля, днес AI флиртува с мен. Случва ми се за първи път, а и не съм чул някой друг с подобен опит. Леле мале, замислете се, преди 10 години AI можеше едвам едвам да се използва за автоматична телефонна централа с 10-на фрази, при това не много ефективно. Сега AI флиртува. Баси, едновременно съм впечатлен и леко озадачен. Какво ли ще е след 10 години.

Не зная кой го е пуснал и каква е целта на този бот, но това не е нещо, което някой може да си забърка във къщи. Това е по възможностите на компании като Google, Facebook, IBM… Дори и Apple нямат необходимия капацитет да го направят.

Не знам защо, но асоциирам това с изказването на Зукербърг, че тази година FB ще пусне пълен функционален AI. Може би си го тестват? Кой знае…

Последното нещо което писах в чата бе: „So you are very clever bot, I’m impressed“ При което чата се блокира и девойчето не се появява в търсенето. Не знам какво се случва, когато някой те блокира, може би е точно това.

Очакват ни интересни времена, определено, но да не забравяме, че едно китайско проклятие е „Пожелавам ти да живееш в интересни времена“

Разбира се, да не пропускаме и следният вариант – тя си е била истински човек, който по някаква причина си търси познати в България и като съм казал, че е бот може да се е обидила и да ме е блокирала. Това е теста на Тюринг – ако след разговор не можеш категорично да определиш дали си говорил с човек или робот. Почти го издържа, почти. Още няколко годинки и ще стане МНОГО интересно…

Google тестват вход в системата им без парола

Днес google обявиха, че започват тестове за вход в системата им без парола (линк)

Идеята е доста проста, вместо email е парола въвеждате само email, и на телефона си получавате нотификация дали позволявате достъп. Ако отговорите с Да влизате в системата (през браузъра). Изглежда доста удобно, и определено премахва проблема със слабите пароли или откраднати пароли, НО…

Какво става ако телефонът ви бъде откраднат? Google обясняват, че очакват вие да сте си защитили телефона с отпечатък, парола или нещо подобно. Ами ако не сте?

Това не е решаване на проблема, това е прехвърляне на проблема на друго място. Вместо да си направите труда еднократно да си създадете добра парола, или пък да използвате някой кадърен мениджър на ключове, а от тях има страшно качествени, ще трябва цялата сигурност да се изнесе в телефона.

Не хейтя, просто искам да кажа, че ако човек НЕ се научи да спазва елементарни правила при работата с личната си информация и чип в главата да му сложат пак няма да го спаси от глупостта му.

Ето 2 хипотетични сценария, които не са ми много ясни:

  • Минавате на тази система и не използвате парола, след 1 година сте си забравили каква парола сте имали. Открадват ви телефона, искате да премахнете този телефон от списъка,но не може да влезете в системата, защото са ви откраднали телефона, и не си спомняте паролата.
  • Забравяте да си заключите телефона, или пък някой знае pin кода ви, или пък е добавил своя отпечатък в телефона ви. отивате до тоалетната, някой влиза в акаунта ви и прави бели. Ако се чудите защо ще позволите на някого да си регистрира отпечатък в телефонът ви, или ще ви знае паролата помислете малко. Ревност, измами, манипулации.

Така че, това което ще правят НЕ добавя нищо ново като ниво на сигурност, даже бих казал, че отваря нови вектори на атака. Накратко, най-сигурният начин да си опазите паролата в която и да е система, е да спазвате основна хигиена и да влагата малко мисъл в действията си.

 

Ще водя курс по Python3 в SoftUni

Аз и Борис Червенков ще водим курс по Python3 в SoftUni – 12 лекции по 4 астрономически часа. Курсът ще бъде малко по-различен от обичайните. Всички лекции ще се водят нас двамата, едновременно, и ще има МНОГО задачи. Курсът е безплатен, сертификата е платен (по желание). Има възможност и за Online обучение, но присъствието в залата ще ви даде МНОГО повече.
За повече информация:
https://softuni.bg/trainings/1281/python-programming-january-2016

Заради голямия флейм ето какво каза Светлин наков по темата:

  • аз не съм ректор, поне не официално, понякога се бъзикам, че съм е-ректор
  • имам диплома за доктор и за доцент (може да се провери в регистъра на научните степени), но избягвам да споменавам за това, защото не смятам, че е някакъв плюс за студентите и за СофтУни
  • СофтУни не е акредитиран ВУЗ. Издаваме наши сертификати, а който иска може да получи диплома от университет-партньор като учи още 1-2 години при тях с признаване на нашитр изпити.
  • В СофтУни нямаме факултети.

 

Защо „големите“ даряват всичките си пари за благотворителност

Предполагам сте забелязали тази тенденция, че милиардери, собственици на големи компании, в един момент решават да дарят 99% от всичките си пари за благотворителност. Това хора като Бик Гейтс, Тим Кук и стотици други. В този списък скоро влезе и Марк Зукербърг – създателя на Facebook.

Какви прекрасни хора, колко благородни. Направили са пари от нищо, и няма да си ги носят в гороба, по-добре да ги дарят, да може и другите да имат. Ех, идилия. Но истината е малко по-различна.

Съкратената версия е следната:
Различни икономически организации (наричайте ги както искате) непрекъснато следят за идеи, и за правилните хора зад тези идеи. Когато видят такава идея, която отговаря на техните цили те се свързват с тези хора и им казват „Това са банките с които ще работите и от които ще вземете финансиране, това са адвокатите, които ще оправят всичко, това са хората, с които ще комуникирате, правете идеята“. И тя я правят. Когато обаче идеята се развие и стане доходоносна идва време да се плати сметката. Няма безплатен обяд. „Създателите“ на тази идея даряват всичките си пари на точно определени фондове, от където тези организации могат да ги използват за каквото си решат и никой не може да проследи парите.

Казано иначе, много от тези хора, които са успели ей така като на филм не са направили много, те са просто лицата пред проектите. Всички решения, контакти, конфликти, бизнес сделки са контролирани от мозъчни тръстове. Един прост пример, който е гледал презентации на Зукербърг ще остане с впечатлението, че този човек няма уменията да създаде такъв голям бизнес. Как тогава успява? Ами успява, защото непрекъснато му е помагано. Искам да уточня, че не хейтя Зукербърг, нито пък му завиждам, споделям наблюдения, че той няма необходимите умения (нито пък аз)

Как една малка фирма в USA може да сключи сделка с компания като Samsung приложението им да бъде инсталирано на всички телефони, и то не само исталирано, ами не може да се махне. От къде контакти за това? Примери много.

Само 5 от тези хора са дарили общо 178.1 милиарда. Помислете, 178.1 милиарда от 5 човека. За тези пари може да се оправи водата в цяла Aфрика, примерно.
LCH е Женева струва около 10 милиарда – най-големият научен експеримент в цяла човешка история е под 10% от дарената сума на 5 от дарителите. Опитвам се да ви дам разумен мащаб да разберете колко пари се даряват, и ако те наистина отиваха за някакви такива цели – определено щяхме да видим резултати.

Защо го пиша това – защото искам да имате по-ясна представа за действителността, и да не си мислите, че може сами да направите някакъв проект в тези размери. Можете, но ако ви помогнат. Ако ви помогнат, ще трябва да платите сметката. Ако откажете ще бъдете купени или съсипани от армия юристи, патенти, тълкувания на закони и подобни. Случвало се е много пъти, има достатъчно фактология в мрежата, ще се случва много пъти. Никой не иска някое младо хлапе да му обърка бизнес за милиарди.

Това е простата истина. Това не означава, че всички тези хора са лоши. Те просто си изпълняват договорките. Но наистина ми става криво като виждам как те биват издигани на пиедестали, които не е много сигурно дали заслужават. Аз съдя за хората по действията, дали са пари някъде – хубаво, но какъв е резултата от даването на тези пари?

Параграф 22 с Google

Ако не знаете какво е „Параграф 22“ това е нещо като да си забравиш ключовете в колата, или за да си инсталираш winzip ти трябва winzip за да разархивираш инсталатор. Всъщност романа на Джоузеф Хелър е много повече от това, но той е станал нарицателно за всякакви затворени цикли, най-вече в бюрокрацията.

Като всеки що годе нормален човек и аз имам gmail, няма как иначе да имаш youtube канал и какво ли още не, и преди години реших да видя мога ли да правя пари от AdSence, оказа се, че не може, поне не и за простосмъртните. Една седмица преди да ми платят ми блокираха акаунта без обяснение. Това стана преди 4-5 години. Майната му си казах, но после разбрах, че не само при мен правят този номер. Но не и това е проблема, проблема е, че в момента аз съм с блокиран AdSence акаунт, който автоматично ми блокира и възможността за монетизиране на видеа от youtube.

След няколко часа търсене успях да намеря една мижава форма с която да се свържа с „някой“ който да ми каже как може да ми възстановят акаунта. Оказа се, че получих автоматичен отговор в който най-общо ми казаха „Няма да ти го възстановим – духай“. Няма обяснения, няма възможности, няма дори и човек с който да комуникираш.

Добре, казах си аз, ще направя друг профил, така или иначе проекта ще е през юредическо лице. Направих си gmail, направих си всичко като ТЕ изискват, дадох си и телефона и… ми блокираха новия акаунт без обяснение, без нищо. Автоматичен отговор и цитат от споразумението им в който се казва „може да блокираме профили когато си искаме по каквато си искаме причина, и няма нужда да ви плащаме ако имате пари и нямате право да мрънкате.“

След доста търсене, питане и мотане разбрах, че google е разбрал, че това съм аз, спрямо телефонен номер, IP адреси и кой знае още какво, и понеже аз имам блокиран профил на общи начала блокират и новия. И пак няма с кого да се свържеш.

Е добре бе мама ви проста, ясно ми е, че имате политика, правила ама това вече е прекалено. Нито може да си оправя стария профил,нито мога да си създам нов. Сега какво трябва да направя? Да си измисля самоличност, да си купя нов телефон само заради това? И в един момент като се засекат двата акунта на един браузър пак ще ми го блокират, и ако имам пари там ще ги загубя.

Явно gmail профила е нещо повече от самоличност, то е до живот. Що за простотия. А най-много ме е яд, че не ми казват защо е блокиран, или какви са опциите да се оправи тази ситуация. И как може да няма един човек с който да се свържеш, не по телефон, по поща е достатъчно. Имат съпорт, но за потребители правещи над $xxxна месец.

Направо ще си каже човек, че имат нещо лично против мен 🙂 защото аз имам много лично против тях.

Някой да знае как мога да се свържа с някой, който да напсувам – тоест да попитам какъв им е проблема?

За това не харесвам монополистите, правят си каквото си искат, а понеже са монополисти си косвено принуден да правиш нещата с тях.