про граблі в компіляторах

На днях наткнулись на прикольну багу неочевидну поведінку компілятора C#. Нехай у нас є три тести:

    var p1 = new SqlParameter("@p", Convert.ToInt32(1));
   
var p2 = new SqlParameter("@p", 1);
   
Assert.AreEqual(p1.Value, p2.Value); // PASS

   
var x = 0;
    p1
= new SqlParameter("@p", Convert.ToInt32(x));
    p2
= new SqlParameter("@p", x);
   
Assert.AreEqual(p1.Value, p2.Value); // PASS

    p1
= new SqlParameter("@p", Convert.ToInt32(0));
    p2
= new SqlParameter("@p", 0);
   
Assert.AreEqual(p1.Value, p2.Value); // FAIL!?

На перший погляд вони аналогічні. Але чомусь останній падає із меседжем:

  Expected: 0
 
But was:  null

Тобто в змінній р1 у нас 0, а в р2 чомусь null. Чому так? У компілятора C# є одна маловідома фіча: цілочисельний літерал і константа із значенням "0" неявно кастяться до будь-якого енума. Відповідно, оскільки у конструктора SqlParameter є дві перегрузки: одна із параметрами (string, object), а друга із (string, SqlDbType), то компілятор вибирає більш конкретну - другу. Нагадаю, що це спрацьовує тільки у випадку, якщо ми передаємо константу значення (або літерал) і воно рівне нулю.

Кейс не те щоб дуже частий, але напоротись можна і то дуже неприємно. 

До речі, автори решарпера судячи по всьому не знають про цю поведінку, бо їх дітище з спокійною душею підсовує ці граблі:

Отаке.

про смартфони

Подумалось тут, що нинішня ситуація на ринку мобільних ОС до болі нагадує те, що творилось на ринку персональних комп’ютерів років 30 тому. Є фактично першовідкривач ринку, який можливо не був першим, але першим зробив продукт справді юзабельним. І є продукт, який має відкриту архітектуру, під яку роблять рішення всі, кому не лінь. Перший сходу захопив ринок, і зробив продукт масовим. Другий з’явився пізніше і довший час пас задніх, але за рахунок відкритості і доступності потихеньку підминає під себе ринок. 30 років тому це були Apple зі своїм Apple II/Lisa/Macintosh і IBM/Microsoft з IBM-PC. Зараз це все той же Apple в тій же ролі тільки з iPhone і Google з своїм Android. У мене зараз нема сумнівів, що Андроїд захопить 90%+ ринку мобільних рішень менше ніж за 5-10 років, точно так само як колись IBM-PC захопив ринок персоналок. А iPhone так і лишиться продуктом для обраних. 

П.С. Навіяно оцим.

People think focus means saying yes to the thing you’ve got to focus on. But that’s not what it means at all. It means saying no to the hundred other good ideas that there are. You have to pick carefully. I’m actually as proud of the things we haven’t done as the things I have done. Innovation is saying ‘no’ to 1,000 things.

And it comes from saying no to 1,000 things to make sure we don’t get on the wrong track or try to do too much. We’re always thinking about new markets we could enter, but it’s only by saying no that you can concentrate on the things that are really important.

Steve Jobs
You should always understand at least one layer below what you are coding.
Lee Campbell

про процеси

При проектуванні будь-якої системи потрібно дотримуватись балансу між простотою і гнучкістю. Якщо ти проектуєш консольну утилітку, яка виконує одну просту функцію - підхід має бути один. Якщо ж метою є створити систему ентерпрайз рівня, яка буде працювати на тисячі серверів - зовсім інший. 

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

Ми приділяємо купу уваги архітектурі продуктів, які пишемо, але часто забуваємо про те, що ми самі теж є системою, яка росте і вимагає періодичного рефакторінгу. Найсумніше те, що найчастіше цей рефакторінг робиться вже тоді, коли у компанії починаються серйозні проблеми через архітектуру, яка не змогла масштабуватися до наявних розмірів. 

Головне при проектуванні і рефакторінгу - це не забувати, що чим більша система, тим меншу роль в ній грають низькорівневі рішення і тим більшу - архітектура. У випадку компанії архітектурою є не конкретні люди, а процеси і взаємодія. Звучить трохи парадоксально, але конкретні особистості не грають ролі, якщо правильно поставити процеси і взаємодію. Це ажніяк не зменшує ролі таланту конкретної людини - правильно поставлені процеси дають можливість цьому таланту розкритись і працювати на всі 100%. Працівник з коефіцієнтом талановитості 5 в таких умовах буде значно ефективнішим, ніж мегамозок з коефіцієнтом 10, який через бардак і нечіткі повноваження може розкрити свій талант тільки на 20%. 

Ваш К.О.

Щойно зловив отаке при спробі збілдати один проект. Добре що не Epic =)

про незамінних людей

Дуже часто буває так, що на софтверному проекті є люди, які працюють там роками і відіграють ключову роль в команді. Всі довкола розуміють, що якщо забрати таку людину - все почне валитись і буде дуже-дуже погано. Тому керівництво навіть не розглядає можливості замінити цю людину. Їй підвищують заробітну платню, дають бонуси, прислухаються до її думки і т.п. А тим часом людина сидить і порпається у не першої свіжості коді, потихенку дуріючи від рутини. Окей, іноді попадаються нетривіальні задачі, але все одно хочеться подихати свіжим повітрям і попрацювати над чимось новим. Якщо цього вчасно не помітити - цей чувак може перегоріти і, наприклад, звільнитись. Проект від цього якщо не завалиться, то ввійде в стан тимчасової кризи, з якої його потрібно буде витягувати героїчними зусиллями всіх, кому не пощастить бути за це відповідальним.

Є така приказка: “святе місце порожнім не буває”. Якщо ви заберете з проекту його лідера - хтось обовязково стане на його місце. Питання тільки в тому, чи він народиться в муках, чи процес пройде плавно і спокійно. В ідеалі можна і потрібно заміняти людей поступово. Плавно і контрольовано. Роздаємо частину своїх обовязків решті команди. Спостерігаємо як справляються і у випадку форс-мажорів прикриваємо їх. Підтягуємо нових людей, якщо не справляються регулярно. Повторюємо до готовності.

Якщо правильно поставити цей процес - проект може навіть не помітити що з нього пішла ключова людина.

А незамінних людей не буває.

Программист должен обладать способностью первоклассного математика к абстракции и логическому мышлению в сочетании с эдисоновским талантом сооружать все, что угодно из нулей и единиц. Он должен сочетать аккуратность бухгалтера с проницательностью разведчика, фантазию автора детективных романов с трезвой практичностью экономиста
Академик А.П. Ершов