Задать вопрос
  • Какова все-таки надежность софтверного RAID-1?

    @lesha_penguin
    У вас возникли «непонятки» из-за того, что вы смешали два абсолютно разных понятия «надежность raid1» и «особенности дистрибутива».

    Насчет первого пункта (надежность raid1) — у вас как раз все очень хорошо! ;) Основная задача raid1 какая? Сохранять информацию! И судя по всему с ней он справляется! Да, вылетел у вас диск, заменили на новый — рейд пересобрался — информация цела — значит все ок! Raid1 свою задачу выполнил! Just as planned!

    Насчет второго пункта, который собственно и вызвал ваш вопрос. Конкретный дистрибутив, в момент загрузки, увидев один или более raid-массивов в degraded не захотел стартовать «в штатном режиме». Ну, так это особенности конкретного дистрибутива.
    Ответ написан
    5 комментариев
  • Обработка ошибок?

    @lesha_penguin
    Не надо «форсить» ошибку там, где ее нет. Пустой результат — тоже результат. Но бывают и ошибки. Самый лучший пример как и в каких случаях это делается «по-взрослому» это… внезапно… сервер баз данных. Самый простой и очень понятный пример когда ошибка, а когда пустой результат:

    Если вы пошлете корректный запрос, например, «SELECT * FROM table WHERE field1=100» но в таблице нет таких записей в которых поле field1=100 сервер вам корректно вернет пустой ответ.

    Однако, если вы в этот же сервер пошлете заведомо ошибочный запрос, вроде «SELECT * FROM тут_нет_такой_таблицы WHERE и_поля_тоже_нет='всем буй'» сервер вам вернет ошибку. Точно, также ошибка вам вернется, если на сервере произошел таймаут, дедлок, или что-то подобное.

    Примерно, такого поведения пользователь ждет и от вашего приложения. Не надо ставить людей в «когнитивный диссонанс», принцип наименьшего удивления — хороший принцип.
    Ответ написан
    Комментировать
  • Подключить к сети компьютеры с одинаковыми mac адресами?

    @lesha_penguin
    Костыльно, но решение возможно. Курите слово «ebtables». Смешное для рускоязычного человека уха название (кстати, ethernet bridge tables, аналогично iptables, если что) ;) Но в нем есть так нужная Вам возможность делать dnat и snat на уровне MAC-адресов.

    А дальше покупаете самый простой комп, втыкаете в него под завязку сетевых карт, ставите линукс по минимуму, настраиваете ebtables и пусть он у вас ethernet bridge-ом для вашей локалки.
    Ответ написан
  • Синхронизация в Си или чем отличается вывод в файл от вывода в stdout

    @lesha_penguin
    1. Стандартный вывод никак не отличается от остальных файлов. Собственно, стандартным выводом может быть любой файл, терминал, пайп, сокет… и т.д. Это на уровне самой «оси».

    2. Но ваша «проблема» — не на уровне оси, а на уровне абстракции FILE* из «stdio.h». Ваша проблема это «проблема» буферизации ввода/вывода. Ввод/вывод который «stdio.h» он идет не напрямую, а через буфер. Который может быть «без буферизации» / «построчная буферизация» / «полная буферизация». И это не баг а фича, буферизация способна нехило увеличить производительность ввода вывода.
    Когда библиотека времени исполнения инициализирует stdin,stdout,stderr для дескрипторов 0,1,2 она смотрит на типы файлов (спрашивает у оси). И если это «терминал» то включает построчную буферизацию (т.е. системный вызов write() реально происходит когда заполняется строка до '\n'), а если «файл» то полную (т.е. пока буфер не заполнится его в файл не сбрасываем, либо по явному вызову fflush(sdtout);).

    3. Собственно, вам поможет явное выполнение:
    setlinebuf(stdout); // Включаем построчную буферизацию, как для терминала
    


    Все! Вы конечно, можете вообще выключить буферизацию, но этого не стоит делать.
    Ответ написан
    1 комментарий
  • Где найти команду для стартапа?

    @lesha_penguin
    >Нет команды. Все фермы стартапов, найденные мной и живые до сих пор, работают только со сформировавшимися командами.

    Совершенно верно! Потому что эфемерная «идея» сама по себе это еще не реальный «проект», под который кто-то даст деньги! И наличие комманды, работающей над проектом, это и есть как бы минимальный «залог успеха». Т.е., залог того что идея не останется голой идеей, а все-таки, найдет свое воплощение. У вас есть, вернее, планируется, некоторый «проект». Вот, так давайте его «Проектом» и называйте! Правильная терминология важна для правильной постановки задач!

    И еще, я Вам сейчас скажу вещь, которая Вас, возможно удивит: Если смотреть на это как на «проект» с точки зрения реализации «идеи», то оказывается НЕТ НИКАКОЙ РАЗНИЦЫ что это за проект: идея реализации очередного стартапа или идея открытия продуктового магазина.
    Вам в любом случае придется проходить определенные этапы в реализации. В данном случае, сейчас у Вас важный этап «найти комманду».

    > Короче, где и как собрать команду заинтересованных разработчиков человеку, не вхожему в ИТ тусовки и не имеющему знакомых среди программистов нужного профиля?

    А вот над этим пунктом остановимся поподробнее… Вам нужно найти, тех, кого заинтересует участие в нем… [простите, что?!?!]?!?!
    Давайте сначала четко проясним этот момент, что означает «участник проекта»!

    Так вот, интерес и участие у Участников проекта бывает разное:

    * Соучредитель — человек, который вместе с Вами вкладывает в проект Свое Время и Свои Деньги. И он идет на Все Риски, на равне с Вами! Вы сами понимаете, для участника — Соучредителя это «доля в бизнесе»+участие в управленческих решениях, никак иначе! Именно так и нужно изначально вести разговор по поиску. Выбор «Соучредителя» — это просто песец какое ответственное дело! И если с участником-«Соучредителем» у Вас есть хоть какие-то взаимные недопонимания, то сразу предупреждаю: Ваш проект разлетится в клочья, едва он начнет «взлетать». Ну, Типа, Я Вас предупредил! ;)

    * Арихитектор Проекта — человек, который обладает некоторым опытом и навыками для постороения «ахитектуры» проекта с «нуля. Архитекторы — люди, способные „запустить в работу“ бизнес-процессы, люди способные видеть „подводные камни“. Те, которые знают как сделать с практической точки зрения то, что называется „реализация“. Это те, кто способен взять ответственность за определенный „фронт работ“. Для них участие в проекте — в первую очередь „профессиональный“ интерес, возможность „поднять свою планку“. НО (!NB!) в отличии от участника — »Соучредителя", участник-«Архитектор» в основном в проекте является хоть и Дорогостоящим, но-таки, НАЕМНЫМ СОТРУДНИКОМ. Да, вы можете «заманивать» профессионала «перспективами», хороший профессионал, если почувствует что «в проекте что-то есть для него интересное и перспективное», конечно «заманиться». Однако, Вы же понимаете, и профессионал прекрасно понимает что «у вас он получает 20-30 т.р. в мес, а в состоявшейся конторе он мог бы легко получать ниминум 100-120 т.р., и ВСЕ что его держит это ИНТЕРЕС и ПЕРСПЕКТИВА». Так вот, не надо лишать «профессионала» этой перспективы! Поэтому разговоры «извини, проект пока не взлетел, в этом месяца денег нет» сразу оставьте при себе! Если не хотите «провала в отвественном направлении», лучше с себя последнюю рубашку снять, но деньги найти! (в противном случае, сразу надо было изначально вести с ним разговор не как с «архитектором», а как с «учредителем»).

    * Рабочие руки — Тот, кто берет на себя всю рутину. Выбор не так критичен, как для «архитектора», но если среди «Рабочих рук» большая «текучка кадров» — звезд с неба вам точно не видать! И это человек, которого вы берете на зарплату. Кстати, важный момент: Если «Архитектор» это человек с опытом, то на «Рабочие Руки» потянет и студент после института. Хотя обычно участника-«Рабочие рукит» выбирает в плане профпригодности для данного проекта «Архитектор» (вы-то в тонкостях дела все-равно нихрена не понимаете), однако все разговоры «о зарплате» с ним ведете лично Вы (либо участник-«Соучредитель»).

    * Разовый Исполнитель — Для единоразовых работ. Собственно, для Исполнителя разовых работ глубоко «фиолетово» стартап вы там или кто, у него таких как Вы миллион. Есть у вас деньги или нет, а уж тем более ваши «наполеоновские планы» разовому исполнителю еще более «ультрафиолетовы». Соотвественно, c «Разовым исполнителем» оставьте всю лирику и больше конкретики, ведь все вы все выбираете «по рыночным ценам» и только рекомендации друзей у вас тут «навигационный компас».

    * Спонсор — Вообще-то «Спонсор» нужен проекту в реальном взлете, когда вам реально потребуются большие средства. Но… «на данном этапе» — ХРЕН ВАМ!!! Пока у вас «идея» не доросла до более-менее ощутимого «проекта», никто Вам и копейки не даст, грустно но факт! Т.е. Сейчас никто для вашего проекта не выступит Спонсором, конечно, если этот Спонсор" Вам ЛИЧНО, ни папа, ни мама, ни дядя, ни тетя, не брат и не сват.

    Ну, вот, с понятиями «что такое участник» и «что такое участие» определились? Теперь вам более-менее понятно как и с кем говорить про «комманду для стартапа»?
    Ответ написан
    1 комментарий
  • Вопрос по теме синхронизации?

    @lesha_penguin
    Если меняет поле только один поток, а все остальные только читают — то да (только volatile у поля не забываем).
    Ответ написан
    9 комментариев
  • Почему Линус не любит C++?

    @lesha_penguin
    <Мысль_вслух>Если существует специальный «ад для говнокодеров», то наверняка, одним из самых жестких наказаний в нем была бы отладка того говнокода, который, который в С++ получается по принципу «делается более просто и изящно».</Мысль_вслух>

    Если начинать «от сотворения мира»:

    1) Как известно C++ был был придуман Страуструпом, мы не будем умалять его «ученные регалии» (ученных-то наград куча, но они по сути единственное чего «добился человек», кстати, 90% прямо или косвенно за c++). Однако, заметим, что Страуструп — как раз есть пример «чистого теоретика» (в отличии от «практика»-Торвальдса), т.е. является человеком за свою жизнь не принимавшим участия в разработке ни одного серьезного реального программного проекта. По сути компилятор c++ — единственное более-менее практическое дело в его жизни. Соотвественно о том с какими проблемами приходится сталкиваться в реальном «software development-е» с «высоты его ООП-теорий» он имеет весьма посредственное представление.

    2) Как верно заметили, в упомянутой статье, изначально это был как раз «Це с классами», т.е. изначально НЕ БОЛЕЕ ЧЕМ «академическая» попытка навернуть на C отдельные элементы «обьектности» (типа, Smalltalk обьектный, а давайте попробуем сделать такое на более низком уровне). Кстати, могу Вам сказать, что с C++ я впервые познакомился в 80-90е годы, когда языком «ученной среды» был Фортран, языком «системщиков» Си, а для обучения «всех непрофильных специальностей» основам программирования использовались Basic и Pascal. Да, но правда «тогдашний C++ 80» отличался от нынешнего — он реально производил впечатление «просто прикольной поделки» (на память помню, что например, тогда не было и половины привычного функционала например таких вещей как всяких «reinterpret_cast-ов» или namespac-ов.). Кстати, да… барабанная дробь… НЕ БЫЛО STL!!!

    3) Наверное Страуструповский «Це с классами», наверное так бы и остался в списке «прикольных поделок» в аналах истории, если бы не одно обстоятельство: «ВНЕЗАПНО» произошел «софтверный бум», соотвественно: a) «элитных» «олдскульных» программистов стало резко не хватать b) «требования к качеству софта» резко упали c) понадобилось средство для генерации достаточно низкоуровневого «говнокода в промышленных масштабах». И как ни странно, (ага, угадали, именно с появлением в C++ STL-я) C++ так и не избавившись от своих «академических болячек» был брошен в пучину «мейнстрима».

    4) Вам говорят истинную правду, когда говорят, что «C++» это маркетинговое название для «Це с классами». Да, это так. И можно сказать, к великому сожалению, он нашел свою рыночную нишу. (Сейчас любой дурак может легко «освоить C++ за 21 день (с бустом и стлем)», при этом не умея даже внятно ответить на простой вопрос «Если ты такой умный, обьясни тогда почему, c$k@, у тебя программа течет по памяти и падает», (про такие «неполиткорректные вопросы», как «зачем писать 100 строк на то, что пишется в две-три», мы вообще тактично молчим, а то, мало ли, может у человека «сдельная зарплата» за количество строк ;) ), зато с видом крутого Беара Грилса можно обсуждать такие «высокие материи» как «Паттерны» и «чистый ООП»).

    5) И к самому большему сожалению, в некоторых случаях альтернативы нет. Да, Я еще не встречал ни одного программиста, который в действительно реальной разработке софта активно использовал бы C++ и при этом от него бы не плевался. У C++ есть «Огромный ПЛЮС» — Его Мультипарадигменность! По-сути это его единственный плюс, позволяющий «не уйти в дебри» (типа попыток запихнуть «main()» в обьект только ради «идеи чистого ООП»)!

    6) А теперь, после такого «исторического» вступления еще раз перечистайте внимательно письмо Торвальдса, высказывание человека который лучше многих «теоретиков чистого ООП» знает как это оно «на собственной шкуре» разрабатывать сложные системы, и комментарии от хабраюзеров, которые «на живой практике» знают «почем фунт лиха» в топике. Под большинством утверждений я лично бы поставил свою подпись золотыми буквами.
    Ответ написан
    5 комментариев
  • Какой виртуализатор не требует аппаратной виртуализации?

    @lesha_penguin
    Все «контейнерные» виртуализаторы (OpenVZ, Lxc, FreeBSD Jail,...) аппаратную виртуализацию не требуют. Точнее сказать, они ее просто не используют за ненадобностью, поскольку контейнеры исполняются как изолированные группы процессов под управляющим общего ядра операционной системы.

    Главное достоинство: контейнеры «легче», не нужно тянуть пусть даже в паравиртуализации guestовое ядро. Главный недостаток: слой изоляции «тоньше», вы не можете запустить Windows в Linux-контейнере.
    Ответ написан
    Комментировать
  • Как спроектировать real-time списывание денег со счета пользователя?

    @lesha_penguin
    > Стоимость размещения фиксирована (скажем, 100 рублей в сутки).

    Тогда в чем проблема?

    Сколько времени минимум должно провисеть данное обьявление всегда известно!

    Этот параметр меняется в меньшую строну при размещении еще одного обьявления тем же юзером.
    Этот параметр меняется в большую сторону при «пополнении баланса» и при снятии других обьявлений.

    Так что событийная модель обработки данных вполне решит вашу проблему.
    Ответ написан
  • Портирование LGPL-библиотеки и лицензия?

    @lesha_penguin
    Сначала маленькое терминологическое уточнение:

    Обычно под термином «портировать» имеется ввиду вполне определенный процесс. Адаптацию работающего кода на другую OS или другую аппаратную платформу. Т.е. например, имеется у вас библиотека работающая на x86/x86_64 но которая никах не работает на других платформах. Вы берете и «допиливаете» десяточек-соточку строк кода, после чего эта библиотека начинает волшебным образом собираться под ARM. Библиотека при этом остается тем, чем была, в том числе под той же LGPL-лицензией, просто будет включать ваш патч.

    Однако если я правильно вас понял, вы собираетесь написать некий код на другом языке программирования, который реализует схожую функциональность? Но в данном случае ни о каком «портировании» речи не идет. Соотвественно, вы пишете 100% свой код, под своей лицензией.

    Или же вы хотите сделать language binding (т.е. «обвес» вокруг имеющейся библиотеки), для вызова функций библиотеки из другого языка. Но в случае «языкового обвеса», вы саму LGPL-библиотеку не модифицируете, а пишете код который просто вызывает функции из нее. А LGPL это позволяет (LGPL-библиотеки можно юзать в проприетарных проектах as is).
    Ответ написан
    5 комментариев
  • Учет компьютеров и оргтехники в компании. Сервис (желательно) или приложение

    @lesha_penguin
    Позвольте сперва уточнить что означает «настоятельные просьбы»?
    Эти 2 человека, (те, которые занимающиеся железом) являются вашими непосредственными подчинеными или нет? Если это Ваши Подчиненые, то что за агрументы «лень наклейки с инвентарными номерами сделать»? Письменный приказ о проведении инвентаризации и подпись этих двух сотрудников что с этим приказом о проведении инвентаризации ознакомлены!
    Ответ написан
    8 комментариев
  • Потерял свой домен, и сайт впридачу. Можно ли вернуть?

    @lesha_penguin
    >… Однажды мне этот проект надоел… решил домен не продлевать. С ФТП хостера всю информацию снес, провайдера уведомил, из аккаунта домен убрал. Про сайт забыл....

    Простите, но в данном случае формулировка «воровство», мне кажется, совсем некорректна. Ваш домен и сайт никто не взламывал, и никто насильно не уводил, вы сам от него отказались.
    Ответ написан
    Комментировать
  • Работа на (почти) две ставки

    @lesha_penguin
    Рабойте, пока вы молоды, пока для вас это ново и увлекательно, пока хватает энтузиазма, пока есть тяга. Короче, вперед, пока это вас не напрягает. Лучше приобрести подобный ценный опыт сейчас, потому что ближе к 30 годам обычно такой героизм проходит. ;)
    Ответ написан
    1 комментарий
  • Документирование ит инфраструктуры?

    @lesha_penguin
    Если инфраструктура обширная, то имеет смысл иметь для разных нужд разные разрезы с разной детализацией. Организация данных — лучше табличная, в силу простоты и интуитивности.

    Итак, естественно напрашиваются следующие таблички:

    1) Кабельное хозяйство. Минимальная таблица вида:

    комната|#розетки|свитч|#порта|маркировка на кабеле(если есть)

    В пределе можно снабдить графическими схемами.

    2) Физическое расположение серверов по стойкам. Надо иметь если количество серверов приближается к заветному числу «дофига». Кстати, всякие «юниты» типа дисковых полок и ленточных библиотек тоже имеет смысл считать как «сервер».Минимально:

    стойка|полка|сервер|надписи на сервере

    3) MAC-адреса интерфейсов cерверов. Назначенные IP-адреса включая алиасы и всякую «виртуалку».

    4) Железная начинка серверов. При принятиях решений о плановых апгрейдах — must have.
    Кстати, насчет «железной начинки», имеет смысл отдельно иметь «таблицу запчастей», чтобы свести к минимуму вероятность возникновения простоя из-за того, что, например, не нашлось скази-винта нужного размера, чтобы быстро подменить в рейд.
    Кстати, обязательно указывать такие вещи как ограничения железа, например тип оперативки, количество слотов, и пр.

    5) Программное обеспечение установленное на серверах. Кстати, если есть что-то лицензируемое, то иметь обязательно, причем с указанием дат лицензий. Чтобы «истекшая внезапно» лицензия не стала «сюрпризом»;)

    6) Если есть жесткое фаерволирование — то табличка

    сервер|сервис

    7) Табличка следующего вида.

    сервер|ответственный сотрудник|телефон

    8) Схема электропитания. минимально:

    сервер|розетка|ups

    9) Календарь плановых работ на серверах.
    всякие апгрейды, переезды, замены вносим сюда (чтобы, сами понимаете согласовывать свои действия с другими)

    10) Инвентаризация рабочих станций — железо.

    11) Инвентаризация рабочих станций — установленный софт. MUST HAVE, особенно с указанием сроков действия лицензий всякого софта!

    12) Табличка расположения рабочих станций по комнатам

    рабочая станция|комната|#розетки

    13) Закрепление рабочих станций за сотрудниками

    рабочая станция|ответственный сотрудник|отдел/должность

    14) MAC-адреса и IP рабочих станций. Кстати, если дофига сотрудников юзают всяческие личные ноутбуки/планшеты/смартфоны, то тоже лучше не полениться включить это все в таблицу соответствия MAC-адресов, назначенных IP с указанием сотрудника в комментариях.

    15) Табличка с запасом запчастей для рабочих станций.

    16) Формулизованный доступ сотрудников.

    сотрудник|должность|сервер|сервис|коммент

    Нужно иметь, особенно если сотрудников дофига. Да и позволяет быстро детектировать «паранормальную активность» всякой малвари, не оставляя сомнений в том, нормально это или нет, что с компьютера бухгалтера тети Маши идет соединение по ssh к mysql серверу.

    17) Набор табличек для «связи с внешним миром». Должна иметься, если существует всяческие резервные каналы, VPNы, пробросы портов и пр. Естественно каждая запись с указанием ответственного сотрудника и телефон.

    18) Если работа 24x7 то графики дежурств админов.

    Вот, с подобным набором табличек, даже «два с половиной админа» способны будут поддерживать без суеты и головной боли порядок даже в очень крупной организации с большой инфраструктурой!

    P.S.: Феншуя Вам в проводах!
    Ответ написан
    1 комментарий
  • Реализацию выделения области фото и комментирования?

    @lesha_penguin
    Вариант 1) Новомодный Canvas. Можно делать что угодно, любые свистоперделки и украшетельства ограничены лишь полетом бурной фантазии, можете хоть замутить мини-графический редактор. Но существенный минус: работать будет только в очень новых браузерах.
    Вариант 2) Старый-добрый прямоугольный Div, спозиционированный над картинкой. Реализация — дешево и сердито: mousedown над картинкой — запоминаем мышинную x1,y1, а когда происходит mouseup — берем мышинную x2,y2 и натягиваем div в позиции x1,y1 шириной x2-x1 высотой y2-y1. Выглядеть возможно будет кондово, но зато поплясав несколько минут с бубном можно заставить работать даже в доисторических браузерах.
    Ответ написан
    Комментировать
  • Как оптимизировать проверку в базе наличия записи (чтобы не сделать дубль)?

    @lesha_penguin
    Ответ на Ваш вопрос будет сильно зависеть от того, зачем вы проверяете на наличие имеющейся записи? Если для того чтобы сделать INSERT если записи нет и UPDATE если запись уже есть, то возможно вам стоит применить конструкцию ON DUPLICATE KEY, тем самым сможете во-первых возложить проверку на БД, во вторых, получите возможность лить данные пачкой, и в третих уберете лишний оверхед появляющийся от позаписного исполнения.
    Ответ написан
  • Как сохранить драгоценное время и нервы ?

    @lesha_penguin
    Если Вам всякие службы сообщений нужны для коммуникации по работе — то древний принцип «разделяй и властвуй»: есть Личная Аська а есть Рабочая Аська, есть Личный телефон а есть Рабочий телефон, есть Личный Jabber а есть Рабочий Jabber, есть Личный Скайп а есть Рабочий Скайп, есть Личный Email а есть Рабочий Email… и т.д. полное разделение контактов, сразу почувствуете насколько ваш день станет продуктивнее когда из него исчезнет пустой треп!

    И ни в коем случае, не поддавайтесь соблазну, не позволяйте «перетекать контактам», иначе снова будете горько жалеть о бесцельно потраченном времени!

    Кстати, если вам какое-то средство не нужно для работы — то просто вырубайте без колебаний! Тоже экономит массу времени и сил!
    Ответ написан
    Комментировать
  • RAID не панацея или как повысить безопасность?

    @lesha_penguin
    1) SMART-мониторинг. Если бы вы хоть иногда смотрели, что вам говорит smart вы бы предприняли меры задолго до столь внезапной кончины.
    2) Не использовать 5 рейд. Плохое решение во всех отношениях, скупой платит дважды.
    3) Бекапы (Капитан Очевидность, извините, не удержался)
    4) Когда выбираете диски для сервака, смотрите такую характеристику, как наработка на отказ. Учтите, что те говновинты, что заполонили все прилавки никак не расчитаны на жесткую эксплуатацию 24x7.
    5) У винтов должно быть хорошее охлаждение, они не любят перегрева. В идеале же винты должны стоять в вентилируемых корзинах.
    Ответ написан
    2 комментария
  • Sendmsg с файловым дескриптором, открытым в обоих процессах?

    @lesha_penguin
    Посылать надо не в теле сообщения, а в auxiliary data через cmsg_level==SOL_SOCKET и cmsg_type==SCM_RIGHTS то результат будет аналогичный dup.

    Только для начала нужно разрешить передачу через setsockopt(fd,SOL_SOCKET,SO_PASSCRED,&enable,sizeof(enable));

    В общем man unix; man cmsg; man setsockopt
    Ответ написан
    1 комментарий
  • Git, определение границ ветки

    @lesha_penguin
    Лучше всего посмотреть git log --graph это по крайней мере даст наглядное понятие что и когда разветвлялось и сливалось.

    Понятие же «граница» для таких нелинейных систем управления версиями как git весьма условно. У вас может быть целое дерево девелоперских веток, ответвляющихся от основной или от других девелоперских, а потом много раз сливающихся.
    Ответ написан
    Комментировать