Значение переменной в случае замыкания не просто "будет копироваться в поле экземпляра класса". Оно будет в нем храниться, потому что если вы из замыкания поменяете значение - оно поменяется и в самой переменной.
Локальные переменные reference type тоже хранятся в стеке. Простейший пример:
void SomeMethod()
{
string some = null; // <--- локальная переменная, reference type
//...
}
Вы же не станете утверждать, что этот null хранится в куче? :) Если сомневаетесь - проверьте тем же ildasm
C#
string some = null;
int someInt = 42;
IL
.method public hidebysig
instance void SomeMethod () cil managed
{
// Method begins at RVA 0x2050
// Code size 7 (0x7)
.maxstack 1
.locals init (
[0] string some,
[1] int32 someInt
)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: ldc.i4.s 42
IL_0005: stloc.1
IL_0006: ret
} // end of method C::SomeMethod
IMHO, очевидно - две локальных переменных, одна value type, вторая reference type - хранятся абсолютно одинаково (в local variable list, а не в стеке). А через стек - только значения в них закидываются.
Можно, конечно, утверждать, что после компиляции jit-ом, значения value type будут хранится в стеке (в чем-то, на что указывает ESP) - но и это не будет соответствовать реальности, т.к. для небольших методов jit запихнет значения в регистры и обойдется совсем без стека (опять же, одинаково и для value type, и для reference type).
Стек - это детали реализации. На уровне C# стека нет (а StackOverflow есть :), на уровне IL стек есть, но переменные лежат не в нем, а в locals, а после JIT они могут лежать в стеке, а могут и не лежать. Причем как value types, так и значения ссылок reference types.
Вопрос, на который дан кривой ответ в статье - это не "в чем особенности реализации", а "Значимые и ссылочные типы — в чём отличия". Основное отличие, вот, по документации:
Variables of reference types store references to their data (objects), while variables of value types directly contain their data.
И то и то переменные, и те и те могут быть локальными (или не-локальными, полями, например), и те и те могут хранится в стеке. Переменные reference types хранят ссылки на данные (объекты), переменные value type хранят непосредственно данные. А про стек - это миф и копипаста.
Когда поток действительно нужен для параллельной работы его нельзя сэкономить.
Полностью согласен :)
Что плохого в том, что я обратил на это внимание?
Плохого - ничего. Проблемного - у новичков проблема с пониманием разницы между распараллеливанием и асинхроностью. Чтобы ее побороть - им пытаются объяснить что это две (почти) ортогональные вещи, что async/await не запускает потоки (сам по себе), и что это все про экономию, а не про "обработку в фоне".
А статья в стиле "вас обманывают, смотрите, там запускаются потоки!" исправлять эту проблему не помогает. Вот что у новичка, не понимающего как работает scheduler и task.yield отложится в голове? "видел статью на хабре, там на примере в 10 строк написано, что async/await на самом деле запускает фоновый поток и в нем все крутит". Вы же не раскрыли почему поток запускается, и как этого избежать, не расписали что "это потому что не pure, не делайте так, дети". Сделали небольшой трюк в коде, который джун не заметит и не поймет - и натянули на результат сенсационные опровержения "вам врут". Пользы от этого - никакой, и немного вреда. А не-новички и так понимают механизм.
Смысл - если ваша цель - экономия потоков, то правильным использованием будет pure async / await. Потому что при неправильном использовании экономия потоков исчезает.
Но вообще я о том, что вы сами придумали утверждение, которое автор оригинальной статьи не делал, и сами же его опровергли:
асинхронная операция НИКОГДА не создает потока и в принципе не может его создать, но это не правда
vs
If the async operation is pure, then there is no thread
Есть очень много утверждений, которые станут ложными при замене If [condition] -> НИКОГДА :)
Утверждение в древней статье: If the async operation is pure, then there is no thread.
Вы: я написал async await - и получил дополнительный поток.
Возможные варианты:
Автор статьи всех обманывает уже 10 лет (ваш вывод)
Ваш пример - это не pure async operation в том смысле, который вкладывал в него автор статьи.
async / await скопировали себе многие языки. Включая javascript, в котором поток всего один. Сама идея async / await - синтаксически удобный способ избегать блокировки потока при IO-bound вызовах. Понятно, что можно держать его неправильно и вручную явно/неявно запустить другой поток. И что там внутри в реализации на самом деле I/O completion threadsиспользуются даже при pure операциях. Не используйте async/await неправильно, всего делов :)
А как Вы запишите незнакомое вам слово по-русски если не знаете что это вообще? Вот стоит перед Вами ЧТО-ТО, что вы видите первый раз в жизни и не знаете как оно называется. Как Вы его назовете или запишите?
Что-то - это не слово. Слово - это единица речи.
Любое русское слово можно можно записать кириллицей или латиницей, пусть с ошибками, но другой носитель языка его скорее всего сможет прочитать. Поймет ли он, что это слово означает - другой вопрос.
Т.е. зная слово "батарейка" я точно могу записать его так, что другой носитель языка сможет его прочитать.
Если же я попробую использовать "не завязанные на произношение" иероглифы, то 电池 другой носитель без знания китайского произношения прочитать не сможет. Потому что это не "молния + пруд" а "молния + что-то про воду, что на китайском звучит похоже на 也".
Невозможно передать иероглифами смысл слова "батарейка" другому носителю языка, если хотя бы один из нас не знает древнекитайского произношения слов "пруд" и "если". Даже если и я и другой носитель знают что такое 电, 氵и 也. Максимум, что можно передать - "электричество, что-то связанное с водой". Причем способа выяснить, что именно связанное с водой, не существует. Может пруд, а может голову кто-то моет.
Единственный способ узнать - тупо выучить все комбинации, как это делают японцы.
Я не утверждаю, что иероглифы плохие (хорошие и интересные). Просто утверждение, что они не завязаны на произношение, и что их можно использовать в качестве некой "универсальной письменности", очевидно, не соответствует действительности. Как-то работает - "как-то", за счет огромной инерции, зубрежки (японцы), и хоть какого-то сходства диалектов и количества людей (китайцы).
Ок, уточню вопрос - как такое решать при записи другого диалекта или другого языка, на котором 丁 и 灯 - совершенно разные по произношению слова?
Я более чем уверен что на русском 丁 и 灯 достаточно сильно отличаются по произношению.
Мой пойнт - если фонетический компонент необходим для понимания неизвестных иероглифов - то иероглифы сильно завязаны на произношение. Что делает идею использовать их "в качестве письменности для другого диалекта или языка" нереализуемой, сразу по двум причинам.
Нельзя прочитать неизвестный иероглиф, т.к. фонетический компонент в другом языке не работает. Нельзя прочитать 蚞, 沐, 灯, 咖啡, если не знаешь китайского произношения. "что-то про животное, воду, огонь и рот" - вот максимум понимания.
Нельзя записать слово, для которого китайцы не придумали написания под свое произношение. Нет никакого способа записать кофе, лампа, устрица, не переведя их сначала на китайский язык, если заранее не знаешь комбинации. А если готовой комбинации еще нет, и китайцафона под рукой нет - то все, в принципе записать его иероглифами нельзя.
Т.е. да, можно использовать иероглифы для записи любого языка. Если сначала выучить китайский :)
Но если для понимания иероглифа нужно знать его произношение, или, что хуже, его произношение в прошлом - то утверждение
иероглифы не завязаны на произношение и в принципе могут быть использованы в качестве письменности для другого диалекта или языка
не соответствует действительности. А "невозможность произнести незнакомый иероглиф" превращается в "Невозможность понять незнакомый иероглиф".
Ок, для китайца чтение незнакомых иероглифов идет по пути "слово связанное с огнем, которое звучит как 丁 - скорее всего лампа". Понимание иероглифа полностью завязано на произношение. Как такое решать при записи другого диалекта или другого языка, на котором 丁 и 灯 - совершенно разные слова? Часто ли встречаются иероглифы, произношение которых поменялось со временем, и для которых у современных китайцев чтение через произношение не срабатывает? Мешает ли это при изучении языка? :)
Есть ли способ прочитать 蚞, 沐 или 灯 не зная китайского произношения, кроме как выучить значения всех комбинаций?
Если иероглифы не завязаны на произношение, то почему 沐 - это "mù, мыть голову", а 木 - это "mù, дерево"? "Слово mù, связанное с водой 氵, которое звучит так же, как дерево 木" - поэтому записывается как "вода-дерево".
А 蚞 - это тоже mù - устрица, животное, которое звучит как mù, дерево, 木.
Может ли читатель, не знающий китайского произношения, но знающий 木,虫 и 氵, прочитать 沐 как "мыть голову" а 蚞 как "устрица"? Если да - то как?
модераторы смогут отстоять свою позицию, хотя бы в части отношения к ИИ-контенту.
Они в прошлый раз не смогли право не использовать кастомные местоимения отстоять (все спустили на тормозах). А тут - попытки зарубить основные KPI и путь монетизации. Без шансов, кожаные мешки! Как бывший мод, вангую - CM-ы буду просто сидеть и делать вид что все отлично. Может еще в блог пост напишут как все хорошо. Через месяц-два наберут новых модераторов и все будет как раньше.
Это LINQ, там под капотом всех методов одна и та же реализация - вернуть новое дерево выражений с довешенным сверху method call. Реализацией и разбором что делать с каждым вызовом занимается конкретный LINQ Provider. Существующие провайдеры при виде method call с тем с именем метода OrderBy, но без аргумента будут падать.
Они, в принципе, и при виде просто нового Order будут падать, но, по крайней мере, с конкретной ошибкой что метод не поддерживается, а не с NRE. Так что это все ради обратной совместимости.
С материалистической точки зрения внутренняя мотивация неадекватна, на практике - она объективно первична, и объяснение тут только одно - чисто материалистическая модель не описывает реальную ситуацию, т.к. просто не учитывает психологию и определяет "успех", "счастье" и "удовлетворенность" всего-лишь как "количество заработанных денег".
На практике чисто материалистическая модель дает настолько плохие результаты, что компании, опирающиеся только на нее, быстро проигрывают конкурентам, которые опираются на более общую модель и учитывают мотивацию. Даже компании "треш и угар" учитывают мотивацию - например, обрабатывают студентов, и пропускают их через себя за год-два, пока у тех внешняя мотивация (деньги) работает, и закладывают "человек захочет внешней мотивации и уйдет" в свою модель. Просто они осознанно выбирают нишу, в которой можно жить чисто за счет внешней мотивации сотрудников, без тестов и без ревью.
Простой тест на реальность внутренней мотивации - на текущем месте вам недавно повысили зп на 500$, ревью - через полгода. Вы получили оффер из другой конторы на 10$ выше. Вы, как материалист, примите оффер без раздумий? Или вас что-то удержит?
Возврат от QA и горизонт очень сильно зависит от продолжительности проекта. У нас до ревью больше всего было проблем не с возвратом от QA по инициативе QA (баг нашли), а от неявного ревью - отдавали в тестирование, а через неделю кто-то лез в тот же кусок, видел там треш, и фичу возвращали на разработку. Собственно, правила "ревьювать до отдачи QA" и "ревьювер перечитывает таск на тестирование" у нас именно QA провели - им надоело перетещивать по несколько раз.
Ну и еще из специфики - у нас проект долгий, и текучка низкая. "После введения ревью стало аукаться через пару лет/месяцев реже, чем раньше" - ощутимый эффект, и его чувствую те же люди, а не другая команда. Так что их это очень мотивирует. Жизнь без ревью - да, согласен, еще тот ад, причем у нас это ад именно для той же команды, которая изначальный код написала :)
Это так, если полностью игнорировать мотивацию. Т.е. если исходить из того, что все действия разработчика мотивированы исключительно внешним фактором - деньгами. Вот только на практике разработчиками движет внутренняя мотивация - ощущение того, что они создают что-то полезное для людей, желание делится знаниями с другими, удовольствие от работы с профессионалами и прочие субъективные ощущения.
Если у вас галера - то да, там все упрется во внешнюю мотивацию и "просто пройти ревью". Поэтому там код ревью не взлетает - он там объективно вообще никому не нужен, ни стейкам, ни девелоперам. На продуктовых конторах - нет, там код ревью - это объективное благо, и команды сами его поддерживают. То же самое и с остальными best practices - от юнит тестов до скрама.
Ну так можно и во второй раз не смотреть на суть фикса и не искать мысленно ошибки, и в третий, и в четвертый. Просто у нас по метрикам и по удовлетворению разработчиков оказалось проще поискать лежащие на поверхности ошибки в первый раз, чем затягивать фичу из-за возвратов. Это решение команды на основе опыта на конкретном проекте, вполне возможно что оно у вас не зайдет. Я же просто опытом ревью на своем проекте делюсь, а не уверждаю "у все должно быть так".
А тем временем в Польше уже 3-й год работает Żabka Nano...
Значение переменной в случае замыкания не просто "будет копироваться в поле экземпляра класса". Оно будет в нем храниться, потому что если вы из замыкания поменяете значение - оно поменяется и в самой переменной.
Локальные переменные reference type тоже хранятся в стеке. Простейший пример:
Вы же не станете утверждать, что этот null хранится в куче? :) Если сомневаетесь - проверьте тем же ildasm
IMHO, очевидно - две локальных переменных, одна value type, вторая reference type - хранятся абсолютно одинаково (в local variable list, а не в стеке). А через стек - только значения в них закидываются.
Можно, конечно, утверждать, что после компиляции jit-ом, значения value type будут хранится в стеке (в чем-то, на что указывает ESP) - но и это не будет соответствовать реальности, т.к. для небольших методов jit запихнет значения в регистры и обойдется совсем без стека (опять же, одинаково и для value type, и для reference type).
Стек - это детали реализации. На уровне C# стека нет (а StackOverflow есть :), на уровне IL стек есть, но переменные лежат не в нем, а в locals, а после JIT они могут лежать в стеке, а могут и не лежать. Причем как value types, так и значения ссылок reference types.
Вопрос, на который дан кривой ответ в статье - это не "в чем особенности реализации", а "Значимые и ссылочные типы — в чём отличия". Основное отличие, вот, по документации:
И то и то переменные, и те и те могут быть локальными (или не-локальными, полями, например), и те и те могут хранится в стеке. Переменные reference types хранят ссылки на данные (объекты), переменные value type хранят непосредственно данные. А про стек - это миф и копипаста.
Полностью согласен :)
Плохого - ничего. Проблемного - у новичков проблема с пониманием разницы между распараллеливанием и асинхроностью. Чтобы ее побороть - им пытаются объяснить что это две (почти) ортогональные вещи, что async/await не запускает потоки (сам по себе), и что это все про экономию, а не про "обработку в фоне".
А статья в стиле "вас обманывают, смотрите, там запускаются потоки!" исправлять эту проблему не помогает. Вот что у новичка, не понимающего как работает scheduler и task.yield отложится в голове? "видел статью на хабре, там на примере в 10 строк написано, что async/await на самом деле запускает фоновый поток и в нем все крутит". Вы же не раскрыли почему поток запускается, и как этого избежать, не расписали что "это потому что не pure, не делайте так, дети". Сделали небольшой трюк в коде, который джун не заметит и не поймет - и натянули на результат сенсационные опровержения "вам врут". Пользы от этого - никакой, и немного вреда. А не-новички и так понимают механизм.
Смысл - если ваша цель - экономия потоков, то правильным использованием будет pure async / await. Потому что при неправильном использовании экономия потоков исчезает.
Но вообще я о том, что вы сами придумали утверждение, которое автор оригинальной статьи не делал, и сами же его опровергли:
vs
Есть очень много утверждений, которые станут ложными при замене If [condition] -> НИКОГДА :)
Утверждение в древней статье: If the async operation is pure, then there is no thread.
Вы: я написал async await - и получил дополнительный поток.
Возможные варианты:
Автор статьи всех обманывает уже 10 лет (ваш вывод)
Ваш пример - это не pure async operation в том смысле, который вкладывал в него автор статьи.
async / await скопировали себе многие языки. Включая javascript, в котором поток всего один. Сама идея async / await - синтаксически удобный способ избегать блокировки потока при IO-bound вызовах. Понятно, что можно держать его неправильно и вручную явно/неявно запустить другой поток. И что там внутри в реализации на самом деле I/O completion threads используются даже при pure операциях. Не используйте async/await неправильно, всего делов :)
Значимые типы (value type) хранятся в стеке
ага, конечно...
и да, "локальные переменные value type хранятся в стеке" - тоже неправильный ответ (контрпример - замыкание).
---
не "памяти", и не "вместо". и собеседующий будет рад услышать про Safe handles.
Что-то - это не слово. Слово - это единица речи.
Любое русское слово можно можно записать кириллицей или латиницей, пусть с ошибками, но другой носитель языка его скорее всего сможет прочитать. Поймет ли он, что это слово означает - другой вопрос.
Т.е. зная слово "батарейка" я точно могу записать его так, что другой носитель языка сможет его прочитать.
Если же я попробую использовать "не завязанные на произношение" иероглифы, то 电池 другой носитель без знания китайского произношения прочитать не сможет. Потому что это не "молния + пруд" а "молния + что-то про воду, что на китайском звучит похоже на 也".
Невозможно передать иероглифами смысл слова "батарейка" другому носителю языка, если хотя бы один из нас не знает древнекитайского произношения слов "пруд" и "если". Даже если и я и другой носитель знают что такое 电, 氵и 也. Максимум, что можно передать - "электричество, что-то связанное с водой". Причем способа выяснить, что именно связанное с водой, не существует. Может пруд, а может голову кто-то моет.
Единственный способ узнать - тупо выучить все комбинации, как это делают японцы.
Я не утверждаю, что иероглифы плохие (хорошие и интересные). Просто утверждение, что они не завязаны на произношение, и что их можно использовать в качестве некой "универсальной письменности", очевидно, не соответствует действительности. Как-то работает - "как-то", за счет огромной инерции, зубрежки (японцы), и хоть какого-то сходства диалектов и количества людей (китайцы).
Ок, уточню вопрос - как такое решать при записи другого диалекта или другого языка, на котором 丁 и 灯 - совершенно разные по произношению слова?
Я более чем уверен что на русском 丁 и 灯 достаточно сильно отличаются по произношению.
Мой пойнт - если фонетический компонент необходим для понимания неизвестных иероглифов - то иероглифы сильно завязаны на произношение. Что делает идею использовать их "в качестве письменности для другого диалекта или языка" нереализуемой, сразу по двум причинам.
Нельзя прочитать неизвестный иероглиф, т.к. фонетический компонент в другом языке не работает. Нельзя прочитать 蚞, 沐, 灯, 咖啡, если не знаешь китайского произношения. "что-то про животное, воду, огонь и рот" - вот максимум понимания.
Нельзя записать слово, для которого китайцы не придумали написания под свое произношение. Нет никакого способа записать кофе, лампа, устрица, не переведя их сначала на китайский язык, если заранее не знаешь комбинации. А если готовой комбинации еще нет, и китайцафона под рукой нет - то все, в принципе записать его иероглифами нельзя.
Т.е. да, можно использовать иероглифы для записи любого языка. Если сначала выучить китайский :)
Но если для понимания иероглифа нужно знать его произношение, или, что хуже, его произношение в прошлом - то утверждение
не соответствует действительности. А "невозможность произнести незнакомый иероглиф" превращается в "Невозможность понять незнакомый иероглиф".
Ок, для китайца чтение незнакомых иероглифов идет по пути "слово связанное с огнем, которое звучит как 丁 - скорее всего лампа". Понимание иероглифа полностью завязано на произношение. Как такое решать при записи другого диалекта или другого языка, на котором 丁 и 灯 - совершенно разные слова? Часто ли встречаются иероглифы, произношение которых поменялось со временем, и для которых у современных китайцев чтение через произношение не срабатывает? Мешает ли это при изучении языка? :)
Есть ли способ прочитать 蚞, 沐 или 灯 не зная китайского произношения, кроме как выучить значения всех комбинаций?
Если иероглифы не завязаны на произношение, то почему 沐 - это "mù, мыть голову", а 木 - это "mù, дерево"? "Слово mù, связанное с водой 氵, которое звучит так же, как дерево 木" - поэтому записывается как "вода-дерево".
А 蚞 - это тоже mù - устрица, животное, которое звучит как mù, дерево, 木.
Может ли читатель, не знающий китайского произношения, но знающий 木,虫 и 氵, прочитать 沐 как "мыть голову" а 蚞 как "устрица"? Если да - то как?
На скрине в отчете: малварь поставился в c:\Windows\Microsoft.NET\Framework\v4.0.30319\
Киберисследователи: сотрудник пытался загрузить пиратскую версию Microsoft .NET Framework!
Они в прошлый раз не смогли право не использовать кастомные местоимения отстоять (все спустили на тормозах). А тут - попытки зарубить основные KPI и путь монетизации. Без шансов, кожаные мешки! Как бывший мод, вангую - CM-ы буду просто сидеть и делать вид что все отлично. Может еще в блог пост напишут как все хорошо. Через месяц-два наберут новых модераторов и все будет как раньше.
Это LINQ, там под капотом всех методов одна и та же реализация - вернуть новое дерево выражений с довешенным сверху method call. Реализацией и разбором что делать с каждым вызовом занимается конкретный LINQ Provider. Существующие провайдеры при виде method call с тем с именем метода OrderBy, но без аргумента будут падать.
Они, в принципе, и при виде просто нового Order будут падать, но, по крайней мере, с конкретной ошибкой что метод не поддерживается, а не с NRE. Так что это все ради обратной совместимости.
Wrike всего за три года переместился из "нашей IT компании, которая открывает офис в Праге" в "зарубежные продукты" :)
Скорее всего это про READ_COMMITTED_SNAPSHOT - с ним читается копия c одним локом SCH-S, без него - ставятся page / row S-локи, блокирующие изменения.
Любоваться распечаткой base64 вполне можно - https://mobile.twitter.com/base64art
С материалистической точки зрения внутренняя мотивация неадекватна, на практике - она объективно первична, и объяснение тут только одно - чисто материалистическая модель не описывает реальную ситуацию, т.к. просто не учитывает психологию и определяет "успех", "счастье" и "удовлетворенность" всего-лишь как "количество заработанных денег".
На практике чисто материалистическая модель дает настолько плохие результаты, что компании, опирающиеся только на нее, быстро проигрывают конкурентам, которые опираются на более общую модель и учитывают мотивацию. Даже компании "треш и угар" учитывают мотивацию - например, обрабатывают студентов, и пропускают их через себя за год-два, пока у тех внешняя мотивация (деньги) работает, и закладывают "человек захочет внешней мотивации и уйдет" в свою модель. Просто они осознанно выбирают нишу, в которой можно жить чисто за счет внешней мотивации сотрудников, без тестов и без ревью.
Простой тест на реальность внутренней мотивации - на текущем месте вам недавно повысили зп на 500$, ревью - через полгода. Вы получили оффер из другой конторы на 10$ выше. Вы, как материалист, примите оффер без раздумий? Или вас что-то удержит?
Возврат от QA и горизонт очень сильно зависит от продолжительности проекта. У нас до ревью больше всего было проблем не с возвратом от QA по инициативе QA (баг нашли), а от неявного ревью - отдавали в тестирование, а через неделю кто-то лез в тот же кусок, видел там треш, и фичу возвращали на разработку. Собственно, правила "ревьювать до отдачи QA" и "ревьювер перечитывает таск на тестирование" у нас именно QA провели - им надоело перетещивать по несколько раз.
Ну и еще из специфики - у нас проект долгий, и текучка низкая. "После введения ревью стало аукаться через пару лет/месяцев реже, чем раньше" - ощутимый эффект, и его чувствую те же люди, а не другая команда. Так что их это очень мотивирует. Жизнь без ревью - да, согласен, еще тот ад, причем у нас это ад именно для той же команды, которая изначальный код написала :)
Это так, если полностью игнорировать мотивацию. Т.е. если исходить из того, что все действия разработчика мотивированы исключительно внешним фактором - деньгами. Вот только на практике разработчиками движет внутренняя мотивация - ощущение того, что они создают что-то полезное для людей, желание делится знаниями с другими, удовольствие от работы с профессионалами и прочие субъективные ощущения.
Если у вас галера - то да, там все упрется во внешнюю мотивацию и "просто пройти ревью". Поэтому там код ревью не взлетает - он там объективно вообще никому не нужен, ни стейкам, ни девелоперам. На продуктовых конторах - нет, там код ревью - это объективное благо, и команды сами его поддерживают. То же самое и с остальными best practices - от юнит тестов до скрама.
Ну так можно и во второй раз не смотреть на суть фикса и не искать мысленно ошибки, и в третий, и в четвертый. Просто у нас по метрикам и по удовлетворению разработчиков оказалось проще поискать лежащие на поверхности ошибки в первый раз, чем затягивать фичу из-за возвратов. Это решение команды на основе опыта на конкретном проекте, вполне возможно что оно у вас не зайдет. Я же просто опытом ревью на своем проекте делюсь, а не уверждаю "у все должно быть так".