Просидев на одном предприятии несколько лет...
От: vaa  
Дата: 06.08.21 02:28
Оценка: 1 (1) :)
https://habr.com/ru/post/571342/
Читаю комменты второй день и . Парадоксально на мой взгляд, но никто до сих пор(региться не охота)
не отметил:
1. быть может отказали почуяв крутого кулцхакера(конкурента).
слышал в крупных компаниях есть такое ограничение — слишком умных не брать, чтобы не взломали систему.
2. "Просидев на одном предприятии несколько лет...", таки зачем срываться? похоже на минутную слабость.
3. почему-то все крутые прогеры пока только накидывают критики, но никто не показал образцовое решение.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Отредактировано 06.08.2021 2:30 Разраб . Предыдущая версия .
Re: Просидев на одном предприятии несколько лет...
От: nikkit  
Дата: 06.08.21 03:54
Оценка: 2 (1) +2
vaa>2. "Просидев на одном предприятии несколько лет...", таки зачем срываться? похоже на минутную слабость.

не знаю как насчет у всех, но у людей имеет место такое явление, как выгорание. знаю по себе. в этом случае и себя насилуешь и проекту пользу перестаешь приносить. выход вижу один — валить и длительный отпуск. тогда только отпускает.
Re: Просидев на одном предприятии несколько лет...
От: CEMb  
Дата: 06.08.21 08:04
Оценка: 2 (2) +1
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/


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

vaa>Читаю комменты второй день и . Парадоксально на мой взгляд, но никто до сих пор(региться не охота)

vaa>не отметил:
vaa>1. быть может отказали почуяв крутого кулцхакера(конкурента).
vaa>слышал в крупных компаниях есть такое ограничение — слишком умных не брать, чтобы не взломали систему.
Там было первым пунктом: хотят взять джуна на кикинга (англ. мальчика для битья). Хороший технический специалист в угол не загоняется ни при каких условиях. Если только сам не накосячил. Даже если и сам накосячил. Тем более, если сам накосячил.

vaa>2. "Просидев на одном предприятии несколько лет...", таки зачем срываться? похоже на минутную слабость.

Человек так устроен, что хочет попробовать все альтернативы. Особенно человек мужского пола, но это уже детали. Как люди говорят: лучше попробовать и пожалеть, чем не попробовать и пожалеть. Ну вот эта формула всегда срабатывает, когда подворачивается случай. Да и вообще нужно двигаться и развиваться. Ну или хотя бы просто двигаться.

vaa>3. почему-то все крутые прогеры пока только накидывают критики, но никто не показал образцовое решение.

Вот, кстати, чем крутой прогер отличается от простого:
— Крутой прогер никогда не тратит время на доказательства того, что он крутой прогер.
— Крутой прогер знает, что образцовые решения бывают только для образцовых задач. Как сферический конь для цилиндричкой лошади вакуума.
— Крутой прогер пришет только то, что нужно для дела. Поэтому некоторые по незнанию удивляются крутым прогерам, которые долго ничего не пишут.
— Крутой прогер, к тому же, не станет лезть в код и выдавать критику, он и так всё поймёт, пообщавшись с крутым прогером, как я это сделал в первой строчке. Ну в самом деле, вы же не разбираете компьютер на запчасти, чтобы понять, как хорошо он работает? Если только вы сам не компьютер, тогда можно. А так вам просто нужно увидеть его в процессе работы, и всё станет ясно.
Re[2]: Просидев на одном предприятии несколько лет...
От: vaa  
Дата: 06.08.21 09:17
Оценка:
Здравствуйте, CEMb, Вы писали:
CEM>Человек так устроен, что хочет попробовать все альтернативы.
да, уж. как говорила одна знакомая бухгалтер: под лежачий камень вода не течёт.
Тогда я и соскочил с места 10-летней насидки.
Факторов на то повлиявших было много.
Но главное найти свое место в обществе.
Сейчас понимаю любое действие по большому счету бессмысленно. Особенно в обществе потребления.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Просидев на одном предприятии несколько лет...
От: кубик  
Дата: 06.08.21 10:25
Оценка: +8 :))
Ничего улыбательного здесь нет, это просто "О работе".
Не стоит идти в фирму где пишут "задание Вы выполнили действительно отвратительно, халтурно". Это хамство.
Надо идти где отвечают вежливо: "Спасибо за Ваше потраченое время и желание работать в нашей фирме! В настоящее время нам бы хотелось найти человека с бОльшим опытом в данной технологии. Благодарим Вас еще раз и Желаем успехов в вашем профессиональном пути!"
Re[2]: Просидев на одном предприятии несколько лет...
От: hardcase Пират http://nemerle.org
Дата: 06.08.21 11:02
Оценка:
Здравствуйте, кубик, Вы писали:

К>Надо идти где отвечают вежливо: "Спасибо за Ваше потраченое время и желание работать в нашей фирме! В настоящее время нам бы хотелось найти человека с бОльшим опытом в данной технологии. Благодарим Вас еще раз и Желаем успехов в вашем профессиональном пути!"


ИЧСХ, автор хабрапоста вполне годный код написал.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Просидев на одном предприятии несколько лет...
От: _FRED_ Черногория
Дата: 06.08.21 13:47
Оценка: 3 (1) :))) :))) :))) :))) :))) :)))
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/


Так в исходниках табы же! Автору повезло что, хоть, не побили :о))

  Поехал я как-то в отпуск…
…и во время отдыха хорошо так прилетело мне из-за моей собственной неуклюжести тяжёлой деревянной рамой от окна прямо в глаз, синяк получился смачный. Когда пришёл в офис, коллег заинтересовало это украшение, а мне до того обидно было рассказывать как всё случилось на самом деле, что я каждый раз придумывал новую историю. Одна из них была про собеседование:

В отпуске я был за границей и, уже отдохнув и начав скучать, решил сходить на собеседование. Пришёл, поговорили о том, о сём, попросили меня на доске написать код одной не сложной операции. Я написал. Один из собеседующих смотрит так внимательно на доску и вдруг спрашивает: а что это у вас тут в коде пробелами отступы сделаны, а не удобными табами? А я ему: да ну что вы, какие табы, XXI век на дворе. пробелы наши всё! Вот так, слово-заслово, мы и подрались
Help will always be given at Hogwarts to those who ask for it.
Re: Просидев на одном предприятии несколько лет...
От: B0FEE664  
Дата: 06.08.21 16:43
Оценка: :)
Здравствуйте, vaa, Вы писали:

vaa>3. почему-то все крутые прогеры пока только накидывают критики, но никто не показал образцовое решение.

Какой самобытный код!
Я очарован этим кодом.
  Опасно! Не для слабых умов. При чтении можно заработать вывих мозга:
using System;

namespace TestApp
{
    /// <summary>
    /// Класс для задания и расчета времени по расписанию.
    /// </summary>
    public class Schedule
    {
        private const string _placeholder = "*"; // Звездочка означает любое возможное значение.
        private const string _defaultMilliseconds = "0"; // fff - миллисекунды (0-999). Если не указаны, то 0

        internal readonly byte[] _years =        new byte[101]; // год (2000-2100)
        internal readonly byte[] _months =       new byte[12]; // месяц (1-12)
        internal readonly byte[] _days =         new byte[32]; // число месяца (1-31 или 32)
        internal readonly byte[] _weekDays =     new byte[7]; // день недели (0-6)
        internal readonly byte[] _hours =        new byte[24]; // часы (0-23)
        internal readonly byte[] _minutes =      new byte[60]; // минуты (0-59)
        internal readonly byte[] _seconds =      new byte[60]; // секунды (0-59)
        internal readonly byte[] _milliseconds = new byte[1000]; // миллисекунды (0-999)

        /// <summary>
        /// Создает пустой экземпляр, который будет соответствовать
        /// расписанию типа "*.*.* * *:*:*.*" (раз в 1 мс).
        /// </summary>
        public Schedule ()
            : this ("*.*.* * *:*:*.*")
        {
        }

        /// <summary>
        /// Создает экземпляр из строки с представлением расписания.
        /// </summary>
        /// <param name="scheduleString">Строка расписания.
        /// Формат строки:
        ///     yyyy.MM.dd w HH:mm:ss.fff
        ///     yyyy.MM.dd HH:mm:ss.fff
        ///     HH:mm:ss.fff
        ///     yyyy.MM.dd w HH:mm:ss
        ///     yyyy.MM.dd HH:mm:ss
        ///     HH:mm:ss
        /// Где yyyy - год (2000-2100)
        ///     MM - месяц (1-12)
        ///     dd - число месяца (1-31 или 32). 32 означает последнее число месяца
        ///     w - день недели (0-6). 0 - воскресенье, 6 - суббота
        ///     HH - часы (0-23)
        ///     mm - минуты (0-59)
        ///     ss - секунды (0-59)
        ///     fff - миллисекунды (0-999). Если не указаны, то 0
        /// Каждую часть даты/времени можно задавать в виде списков и диапазонов.
        /// Например:
        ///     1,2,3-5,10-20/3
        ///     означает список 1,2,3,4,5,10,13,16,19
        /// Дробью задается шаг в списке.
        /// Звездочка означает любое возможное значение.
        /// Например (для часов):
        ///     */4
        ///     означает 0,4,8,12,16,20
        /// Вместо списка чисел месяца можно указать 32. Это означает последнее
        /// число любого месяца.
        /// Пример:
        ///     *.9.*/2 1-5 10:00:00.000
        ///     означает 10:00 во все дни с пн. по пт. по нечетным числам в сентябре
        ///     *:00:00
        ///     означает начало любого часа
        ///     *.*.01 01:30:00
        ///     означает 01:30 по первым числам каждого месяца
        /// </param>
        public Schedule (string scheduleString)
        {
            // конструктор большой по объёму исходника, но выполняет лишь простейшие действия и не выделяет память
            if (scheduleString == null)
            {
                throw new ArgumentNullException (nameof (scheduleString));
            }

            var dotPosition1 = scheduleString.IndexOf ('.');
            var dotPosition2 = (dotPosition1 < 0) ?
                -1 :
                scheduleString.IndexOf ('.', dotPosition1 + 1);
            var dotPosition3 = (dotPosition2 < 0) ?
                -1 :
                scheduleString.IndexOf ('.', dotPosition2 + 1);
            var colonPosition1 = scheduleString.IndexOf (':');
            var colonPosition2 = (colonPosition1 < 0) ?
                -1 :
                scheduleString.IndexOf (':', colonPosition1 + 1);
            if (colonPosition2 < 0)
            {
                // два двоеточия есть во всех форматах
                throw new FormatException ();
            }
            var spacePosition1 = scheduleString.IndexOf (' ');
            var spacePosition2 = (spacePosition1 < 0) ?
                -1 :
                scheduleString.IndexOf (' ', spacePosition1 + 1);

            ReadOnlySpan<char> yearPart;
            ReadOnlySpan<char> monthPart;
            ReadOnlySpan<char> dayPart;
            ReadOnlySpan<char> weekDayPart;
            ReadOnlySpan<char> hourPart;
            ReadOnlySpan<char> minutePart;
            ReadOnlySpan<char> secondPart;
            ReadOnlySpan<char> millisecondPart;
            if (
                (dotPosition1 >= 0) &&
                (dotPosition2 >= 0) &&
                (dotPosition3 >= 0) &&
                (colonPosition1 > dotPosition2) &&
                (dotPosition3 > colonPosition2))
            {
                // yyyy.MM.dd w HH:mm:ss.fff  или  yyyy.MM.dd HH:mm:ss.fff
                yearPart = scheduleString.AsSpan (0, dotPosition1);
                monthPart = scheduleString.AsSpan (dotPosition1 + 1, dotPosition2 - dotPosition1 - 1);
                dayPart = scheduleString.AsSpan (dotPosition2 + 1, spacePosition1 - dotPosition2 - 1);
                weekDayPart = (spacePosition2 < 0) ?
                    _placeholder :
                    scheduleString.AsSpan (spacePosition1 + 1, spacePosition2 - spacePosition1 - 1);
                hourPart = (spacePosition2 < 0) ?
                    scheduleString.AsSpan (spacePosition1 + 1, colonPosition1 - spacePosition1 - 1) :
                    scheduleString.AsSpan (spacePosition2 + 1, colonPosition1 - spacePosition2 - 1);
                minutePart = scheduleString.AsSpan (colonPosition1 + 1, colonPosition2 - colonPosition1 - 1);
                secondPart = scheduleString.AsSpan (colonPosition2 + 1, dotPosition3 - colonPosition2 - 1);
                millisecondPart = scheduleString.AsSpan (dotPosition3 + 1);
            }
            else
            {
                if (
                    (dotPosition1 >= 0) &&
                    (dotPosition2 >= 0) &&
                    (dotPosition3 < 0) &&
                    (colonPosition1 > dotPosition2))
                {
                    // yyyy.MM.dd w HH:mm:ss  или  yyyy.MM.dd HH:mm:ss
                    yearPart = scheduleString.AsSpan (0, dotPosition1);
                    monthPart = scheduleString.AsSpan (dotPosition1 + 1, dotPosition2 - dotPosition1 - 1);
                    dayPart = scheduleString.AsSpan (dotPosition2 + 1, spacePosition1 - dotPosition2 - 1);
                    weekDayPart = (spacePosition2 < 0) ?
                        _placeholder :
                        scheduleString.AsSpan (spacePosition1 + 1, spacePosition2 - spacePosition1 - 1);
                    hourPart = (spacePosition2 < 0) ?
                        scheduleString.AsSpan (spacePosition1 + 1, colonPosition1 - spacePosition1 - 1) :
                        scheduleString.AsSpan (spacePosition2 + 1, colonPosition1 - spacePosition2 - 1);
                    minutePart = scheduleString.AsSpan (colonPosition1 + 1, colonPosition2 - colonPosition1 - 1);
                    secondPart = scheduleString.AsSpan (colonPosition2 + 1);
                    millisecondPart = _defaultMilliseconds;
                }
                else
                {
                    if (
                        (dotPosition1 >= 0) &&
                        (dotPosition2 < 0) &&
                        (colonPosition2 < dotPosition1))
                    {
                        // HH:mm:ss.fff
                        yearPart = _placeholder;
                        monthPart = _placeholder;
                        dayPart = _placeholder;
                        weekDayPart = _placeholder;
                        hourPart = scheduleString.AsSpan (0, colonPosition1);
                        minutePart = scheduleString.AsSpan (colonPosition1 + 1, colonPosition2 - colonPosition1 - 1);
                        secondPart = scheduleString.AsSpan (colonPosition2 + 1, dotPosition1 - colonPosition2 - 1);
                        millisecondPart = scheduleString.AsSpan (dotPosition1 + 1);
                    }
                    else
                    {
                        if (dotPosition1 < 0)
                        {
                            // HH:mm:ss
                            yearPart = _placeholder;
                            monthPart = _placeholder;
                            dayPart = _placeholder;
                            weekDayPart = _placeholder;
                            hourPart = scheduleString.AsSpan (0, colonPosition1);
                            minutePart = scheduleString.AsSpan (colonPosition1 + 1, colonPosition2 - colonPosition1 - 1);
                            secondPart = scheduleString.AsSpan (colonPosition2 + 1);
                            millisecondPart = _defaultMilliseconds;
                        }
                        else
                        {
                            throw new FormatException ("Unrecognized schedule.");
                        }
                    }
                }
            }

            ParsePart (yearPart,        _years,        2000);
            ParsePart (monthPart,       _months,       1);
            ParsePart (dayPart,         _days,         1);
            ParsePart (weekDayPart,     _weekDays,     0);
            ParsePart (hourPart,        _hours,        0);
            ParsePart (minutePart,      _minutes,      0);
            ParsePart (secondPart,      _seconds,      0);
            ParsePart (millisecondPart, _milliseconds, 0);
        }

        /// <summary>
        /// Возвращает следующий ближайший к заданному времени момент в расписании или
        /// само заданное время, если оно есть в расписании.
        /// </summary>
        /// <param name="t1">Заданное время</param>
        /// <returns>Ближайший момент времени в расписании</returns>
        public DateTime NearestEvent(DateTime t1)
        {
            // цикл проверки каждый раз после корректировки времени, макс. кол-во итераций: 100 + 11 + 31 + 23 + 59 + 59 = 283
            while (true)
            {
                var yearOffset = t1.Year - 2000;
                if ((yearOffset < 0) || (yearOffset >= _years.Length))
                {
                    throw new InvalidOperationException ("Year out of range");
                }

                if (_years[yearOffset] > 0)
                {
                    if (_months[t1.Month - 1] > 0)
                    {
                        var isLastDayInMonth = t1.Day == DateTime.DaysInMonth (t1.Year, t1.Month);
                        // 32-й день означает последнее число месяца
                        if (((_days[t1.Day - 1] > 0) || (isLastDayInMonth && (_days[31] > 0))) && (_weekDays[(int)t1.DayOfWeek] > 0))
                        {
                            if (_hours[t1.Hour] > 0)
                            {
                                if (_minutes[t1.Minute] > 0)
                                {
                                    if (_seconds[t1.Second] > 0)
                                    {
                                        var millisecond = t1.Millisecond;
                                        do
                                        {
                                            if (_milliseconds[millisecond] > 0)
                                            {
                                                return new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, t1.Minute, t1.Second, millisecond);
                                            }

                                            millisecond++;
                                        } while (millisecond < _milliseconds.Length);
                                    }
                                    t1 = new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, t1.Minute, t1.Second).AddSeconds (1);
                                }
                                else
                                {
                                    t1 = new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, t1.Minute, 0).AddMinutes (1);
                                }
                            }
                            else
                            {
                                t1 = new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, 0, 0).AddHours (1);
                            }
                        }
                        else
                        {
                            t1 = new DateTime (t1.Year, t1.Month, t1.Day).AddDays (1);
                        }
                    }
                    else
                    {
                        t1 = new DateTime (t1.Year, t1.Month, 1).AddMonths (1);
                    }
                }
                else
                {
                    t1 = new DateTime (t1.Year, 1, 1).AddYears (1);
                }
            }
        }

        /// <summary>
        /// Возвращает предыдущий ближайший к заданному времени момент в расписании или
        /// само заданное время, если оно есть в расписании.
        /// </summary>
        /// <param name="t1">Заданное время</param>
        /// <returns>Ближайший момент времени в расписании</returns>
        public DateTime NearestPrevEvent(DateTime t1)
        {
            // цикл проверки каждый раз после корректировки времени, макс. кол-во итераций: 100 + 11 + 31 + 23 + 59 + 59 = 283
            while (true)
            {
                var yearOffset = t1.Year - 2000;
                if ((yearOffset < 0) || (yearOffset >= _years.Length))
                {
                    throw new InvalidOperationException ("Year out of range");
                }

                if (_years[yearOffset] > 0)
                {
                    if (_months[t1.Month - 1] > 0)
                    {
                        var isLastDayInMonth = t1.Day == DateTime.DaysInMonth (t1.Year, t1.Month);
                        // 32-й день означает последнее число месяца
                        if (((_days[t1.Day - 1] > 0) || (isLastDayInMonth && (_days[31] > 0))) && (_weekDays[(int)t1.DayOfWeek] > 0))
                        {
                            if (_hours[t1.Hour] > 0)
                            {
                                if (_minutes[t1.Minute] > 0)
                                {
                                    if (_seconds[t1.Second] > 0)
                                    {
                                        var millisecond = t1.Millisecond;
                                        do
                                        {
                                            if (_milliseconds[millisecond] > 0)
                                            {
                                                return new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, t1.Minute, t1.Second, millisecond);
                                            }

                                            millisecond--;
                                        } while (millisecond >= 0);
                                    }
                                    t1 = new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, t1.Minute, t1.Second).AddMilliseconds (-1);
                                }
                                else
                                {
                                    t1 = new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, t1.Minute, 0).AddMilliseconds (-1);
                                }
                            }
                            else
                            {
                                t1 = new DateTime (t1.Year, t1.Month, t1.Day, t1.Hour, 0, 0).AddMilliseconds (-1);
                            }
                        }
                        else
                        {
                            t1 = new DateTime (t1.Year, t1.Month, t1.Day).AddMilliseconds (-1);
                        }
                    }
                    else
                    {
                        t1 = new DateTime (t1.Year, t1.Month, 1).AddMilliseconds (-1);
                    }
                }
                else
                {
                    t1 = new DateTime (t1.Year, 1, 1).AddMilliseconds (-1);
                }
            }
        }

        /// <summary>
        /// Возвращает следующий момент времени в расписании.
        /// </summary>
        /// <param name="t1">Время, от которого нужно отступить</param>
        /// <returns>Следующий момент времени в расписании</returns>
        public DateTime NextEvent(DateTime t1)
        {
            return NearestEvent (t1.AddMilliseconds (1));
        }

        /// <summary>
        /// Возвращает предыдущий момент времени в расписании.
        /// </summary>
        /// <param name="t1">Время, от которого нужно отступить</param>
        /// <returns>Предыдущий момент времени в расписании</returns>
        public DateTime PrevEvent(DateTime t1)
        {
            return NearestPrevEvent (t1.AddMilliseconds (-1));
        }

        /// <summary>
        /// Заполняет указанный массив ненулевыми значениями для тех индексов, которые указаны в partStr.
        /// </summary>
        /// <param name="partStr">Текстовый список диапазонов.</param>
        /// <param name="allowedValues">Массив, в котором будут отмечены ненулевым значением указанные в partStr числа.</param>
        /// <param name="offset">Смещение, которое будет вычитаться для всех чисел, указанных в partStr.</param>
        private static void ParsePart (ReadOnlySpan<char> partStr, byte[] allowedValues, int offset)
        {
            // Каждую часть даты/времени можно задавать в виде списков и диапазонов.
            // Например:
            //     1,2,3-5,10-20/3
            //     означает список 1,2,3,4,5,10,13,16,19
            // Дробью задается шаг в списке.
            // Звездочка означает любое возможное значение.

            if (partStr.Length < 1)
            {
                throw new FormatException ("Invalid part");
            }

            var idx = 0;
            while (idx < partStr.Length)
            {
                int number1;
                int number2;
                if (partStr[idx] == '*')
                {
                    idx++;
                    number1 = 0;
                    number2 = allowedValues.Length - 1;
                }
                else
                {
                    number1 = ParseNumber (partStr, ref idx) - offset;
                    if ((number1 < 0) || (number1 >= allowedValues.Length))
                    {
                        throw new FormatException ("Number out of range.");
                    }

                    number2 = number1;
                    if ((idx < partStr.Length) && (partStr[idx] == '-'))
                    {
                        idx++;
                        number2 = ParseNumber (partStr, ref idx) - offset;
                        if ((number2 < 0) || (number2 >= allowedValues.Length))
                        {
                            throw new FormatException ("Number out of range.");
                        }
                    }
                }

                var period = 1;
                if (idx < partStr.Length)
                {
                    switch (partStr[idx])
                    {
                        case '/':
                            idx++;
                            period = ParseNumber (partStr, ref idx);
                            break;
                        case ',':
                            idx++;
                            break;
                        default:
                            throw new FormatException ("Invalid character.");
                    }
                }

                for (var i = number1; i <= number2; i += period)
                {
                    allowedValues[i] = 1;
                }
            }
        }

        // возвращает число, полученное из текстового представленая в partStr начиная с индекса в idx
        private static int ParseNumber (ReadOnlySpan<char> partStr, ref int idx)
        {
            var number = 0;
            while ((idx < partStr.Length) && (partStr[idx] >= '0') && (partStr[idx] <= '9'))
            {
                number = 10 * number + partStr[idx] - '0';
                idx++;
            }

            return number;
        }
    }
}
И каждый день — без права на ошибку...
Re: Просидев на одном предприятии несколько лет...
От: scf  
Дата: 06.08.21 17:27
Оценка: +2
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/

vaa>Читаю комменты второй день и . Парадоксально на мой взгляд, но никто до сих пор(региться не охота)

Ну это, простите, жесть. Код джуна с математическим бэкграундом.
Паттерны в конструкторе можно и нужно парсить регуляркой, очевидно же, что никто не будет в проде создавать 100500 расписаний, а вот NearestEvent будут вызывать много и часто.
Мартин плачет кровавыми слезами — ну что за уровни вложенности, на дворе 21 век и все компиляторы умеют в инлайнинг.
Перезапись аргумента метода в теле — тоже так себе идея.
Ок, мы решили понять задание буквально и сделать "круче всего" (эх, где мой юношеский максимализм). Но где тогда часовой пояс, по которому всё это считается? И где обширный коммент, объясняющий, как это работает и какие есть тонкости?

Я вообще сделал бы коммент а-ля "календарь — штука сложная вычислительно и в принципе, летнее/зимнее время, leap second и изменения в законодательстве, касающегося времени, сложны и, скорее всего, не важны для шедулера, поэтому у нас всё будет в UTC"

P.S. И, конечно, сначала посмотрел бы, как умные люди это уже реализовали
Re: Просидев на одном предприятии несколько лет...
От: Mr.Delphist  
Дата: 06.08.21 17:52
Оценка: 8 (3) +2
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/

vaa>Читаю комменты второй день и . Парадоксально на мой взгляд, но никто до сих пор(региться не охота)
vaa>не отметил:
vaa>1. быть может отказали почуяв крутого кулцхакера(конкурента).
vaa>слышал в крупных компаниях есть такое ограничение — слишком умных не брать, чтобы не взломали систему.
vaa>2. "Просидев на одном предприятии несколько лет...", таки зачем срываться? похоже на минутную слабость.
vaa>3. почему-то все крутые прогеры пока только накидывают критики, но никто не показал образцовое решение.

Таки глянул код — статья получилась резонансная, сыпется из разных мест ленты, пришлось читать. Ну и что могу сказать: я бы тоже не взял. Ровно по той же причине, почему не взял бы себя-раннего с точки зрения себя-сегодняшнего.

1) Всё врукопашку. Человек вроде не новичок, и даже знает про RegExp, но в итоге вся работа по парсингу входной строки — через простыню IndexOf. Не то что токенайзер или Linq, даже обычный Split отсутствует.
Чем это плохо: случись изменение в формате строки -> старый код в утиль, целиком. Со всеми юнит-тестами и бенчмарками.

2) Длинные методы, многоуровневые if. По сути, продолжение предыдущего пункта. Читая такой код, понимаешь, что имеешь дело с эдаким C#-ассемблером, дампом мыслленного решения, существующего в голове автора.
Чем это плохо: приходится "дизассемблирвоать" эту простыню, чтобы понять, какую проблему решает код, почему в этот if зайти надо, а в следующий — нет. Потому что настоящий "исходник" — так и остаётся в голове автора. Телепатию пока не завезли, увы. Ну и как говорилось выше — цена изменений.

3) Постановка задачи и "что такое эффективаность для заказчика". Вместо уточнения "вам пуговицы или халат с поясом, сделать из рогожи или из дубовой доски" принимается одностороннее решение "пуговицы будут перламутровыми, так эффективней". В общем, классика мема "что хотел заказчик".

Выводы:
1) Надо уметь не только язык (это обычно самое простое), но и инфраструктуру прикладных библиотек вокруг него.
2) Работа в команде — отдельный вид деятельности, и он необходим хотя бы как этап проф-развития, каким бы гением ты ни был.
3) If at first you don't succeed, try, try again.
Re[2]: Просидев на одном предприятии несколько лет...
От: Блудов Павел Россия  
Дата: 07.08.21 13:37
Оценка:
Здравствуйте, scf, Вы писали:

scf>P.S. И, конечно, сначала посмотрел бы, как умные люди это уже реализовали


Не-не-не, не нужно смотреть. Там точно такая же простыня, но с регулярками.
Re[2]: Просидев на одном предприятии несколько лет...
От: B0FEE664  
Дата: 07.08.21 14:43
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>1) Всё врукопашку. Человек вроде не новичок, и даже знает про RegExp, ...

MD>Чем это плохо: случись изменение в формате строки -> старый код в утиль, целиком. Со всеми юнит-тестами и бенчмарками.

Если использовать RegExp, то будет такая же ситуация.

MD>2) Длинные методы, многоуровневые if. По сути, продолжение предыдущего пункта. Читая такой код, понимаешь, что имеешь дело с эдаким C#-ассемблером, дампом мыслленного решения, существующего в голове автора.

Ой, да ладно! Там все if'ы однотипные и читаются влёт.

MD>Чем это плохо: приходится "дизассемблирвоать" эту простыню, чтобы понять, какую проблему решает код, почему в этот if зайти надо, а в следующий — нет. Потому что настоящий "исходник" — так и остаётся в голове автора. Телепатию пока не завезли, увы. Ну и как говорилось выше — цена изменений.


В отличии от парсинга эту часть легко изменить. Однако, следует заменить, что максимальное количество итераций подсчитано не верно: там произведение должно быть, а не сумма.

MD>3) Постановка задачи и "что такое эффективаность для заказчика". Вместо уточнения "вам пуговицы или халат с поясом, сделать из рогожи или из дубовой доски" принимается одностороннее решение "пуговицы будут перламутровыми, так эффективней". В общем, классика мема "что хотел заказчик".


Не согласен. В задании ясно сказано: "класс должен быть эффективным и не использовать много памяти и ресурсов даже тогда, когда в расписании задано много значений. Например очень много значений с шагом в одну миллисекунду." Я понимаю это как требование оптимизацию по памяти, а не по скорости => надо было хранить саму строку расписания и парсить её при каждом запросе.

MD>Выводы:

MD>1) Надо уметь не только язык (это обычно самое простое), но и инфраструктуру прикладных библиотек вокруг него.

Не, надо просто угадать, что там в головах у программистов этой конторы. Требования могут быть прямо противоположными, а раз получить комментариев по заданию не удалось, значит результат — лотерея. Ну, или писать несколько решений, а это много работы.

MD>2) Работа в команде — отдельный вид деятельности, и он необходим хотя бы как этап проф-развития, каким бы гением ты ни был.

А если стиль работы в команде не известен?

MD>3) If at first you don't succeed, try, try again.

Не, тут следует заметить, что "0 — воскресенье, 6 — суббота" — это значит, что задание переводное. Возможно имело смысл поискать (на английском) готовое решение, а не страдать изобретением велосипеда.
И каждый день — без права на ошибку...
Re[2]: Просидев на одном предприятии несколько лет...
От: viellsky  
Дата: 07.08.21 16:56
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Таки глянул код — статья получилась резонансная, сыпется из разных мест ленты, пришлось читать. Ну и что могу сказать: я бы тоже не взял. Ровно по той же причине, почему не взял бы себя-раннего с точки зрения себя-сегодняшнего.

Взял/не взял — это одно. А вот почему код охарактеризовали "задание Вы выполнили действительно отвратительно, халтурно" — совсем другое.

MD>1) Всё врукопашку. Человек вроде не новичок, и даже знает про RegExp, но в итоге вся работа по парсингу входной строки — через простыню IndexOf. Не то что токенайзер или Linq, даже обычный Split отсутствует.

MD>Чем это плохо: случись изменение в формате строки -> старый код в утиль, целиком. Со всеми юнит-тестами и бенчмарками.
Юнит-тесту как-то все равно — вручную ты парсишь или вызовом регэкспа. Да и почему старый код в утиль, тоже не понятно — объем изменений может отличаться, да, но опять же — про расход памяти/ресурсов в требованиях написано, а вот про повышенную стойкость к изменению формата — нет. Спорная претензия, в общем.

MD>2) Длинные методы, многоуровневые if. По сути, продолжение предыдущего пункта. Читая такой код, понимаешь, что имеешь дело с эдаким C#-ассемблером, дампом мыслленного решения, существующего в голове автора.

MD>Чем это плохо: приходится "дизассемблирвоать" эту простыню, чтобы понять, какую проблему решает код, почему в этот if зайти надо, а в следующий — нет. Потому что настоящий "исходник" — так и остаётся в голове автора. Телепатию пока не завезли, увы. Ну и как говорилось выше — цена изменений.

Жути нагнал — все не так плохо тут. Ничего сверхдлинного или сверхвложного нет. Если и считать это недостатком — то явно не критичным. Про телепатию вывод сделан наспех по формальным признакам.

MD>3) Постановка задачи и "что такое эффективаность для заказчика". Вместо уточнения "вам пуговицы или халат с поясом, сделать из рогожи или из дубовой доски" принимается одностороннее решение "пуговицы будут перламутровыми, так эффективней". В общем, классика мема "что хотел заказчик".

Автор спрашивал:

Поскольку многие указали, что надо было уточнять детали у заказчика, поясняю: я пытался, но меня принципиально не хотели соединять со специалистами, со мной общался только HR

Re[3]: Просидев на одном предприятии несколько лет...
От: Sharov Россия  
Дата: 08.08.21 00:26
Оценка: :)
Здравствуйте, hardcase, Вы писали:

H>ИЧСХ, автор хабрапоста вполне годный код написал.


Не, у него там дикая вложенность на ровном месте. Там читались абстракции для всяких последовательностей +
переложить большую часть проблем с учетом всяческих високосных годов на DataTime. Видно, что человек из R&D.
Кодом людям нужно помогать!
Re[3]: Просидев на одном предприятии несколько лет...
От: Mr.Delphist  
Дата: 09.08.21 09:14
Оценка:
Здравствуйте, viellsky, Вы писали:

V>Взял/не взял — это одно. А вот почему код охарактеризовали "задание Вы выполнили действительно отвратительно, халтурно" — совсем другое.


О, то отдельная песня. Уже не про соискателя, а про HR-процесс. Единственынй плюсик который там можно поставить — что соискателю ОТВЕТИЛИ, вместо молчаливого вышвыривания в корзину.
Re: Просидев на одном предприятии несколько лет...
От: rosencrantz США  
Дата: 09.08.21 17:21
Оценка: +1
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/

vaa>Читаю комменты второй день и . Парадоксально на мой взгляд, но никто до сих пор(региться не охота)
vaa>не отметил:
vaa>1. быть может отказали почуяв крутого кулцхакера(конкурента).
vaa>слышал в крупных компаниях есть такое ограничение — слишком умных не брать, чтобы не взломали систему.
vaa>2. "Просидев на одном предприятии несколько лет...", таки зачем срываться? похоже на минутную слабость.
vaa>3. почему-то все крутые прогеры пока только накидывают критики, но никто не показал образцовое решение.

Мне код не нравится — выглядит как "авторский".

1. Для чтения выражений нужно какой-то внятный парсер с внятной грамматикой, или хотя бы регулярные выражения. Чтобы грамматика была не в комментах, а в чём-то более-менее компьютерном. Чтобы можно было красиво ругаться "что qwerty не выглядит как число от 1 до 12".

2. Решение никак не порезано на отдельные логические куски — программу невозможно читать по частям, только как монолит. Я бы попытался дизайнить в сторону "композиции триггеров". Парсим -> дерево разбора -> составной триггер.
Re: Просидев на одном предприятии несколько лет...
От: AlexMld Россия  
Дата: 09.08.21 19:45
Оценка: :))
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/


Вот это что?

internal readonly byte[] _years =        new byte[101]; // год (2000-2100)
internal readonly byte[] _months =       new byte[12]; // месяц (1-12)
internal readonly byte[] _days =         new byte[32]; // число месяца (1-31 или 32)
internal readonly byte[] _weekDays =     new byte[7]; // день недели (0-6)
internal readonly byte[] _hours =        new byte[24]; // часы (0-23)
internal readonly byte[] _minutes =      new byte[60]; // минуты (0-59)
internal readonly byte[] _seconds =      new byte[60]; // секунды (0-59)
internal readonly byte[] _milliseconds = new byte[1000]; // миллисекунды (0-999)


Зачем, например, под миллисекунды 1000 байт? По байту на каждое возможное значение? 60 байт на секунды, 60 на минуты и т.п. Зачем? Странный какой-то код у него.
Re[2]: Просидев на одном предприятии несколько лет...
От: bnk СССР http://unmanagedvisio.com/
Дата: 09.08.21 19:53
Оценка:
Здравствуйте, AlexMld, Вы писали:

AM>Вот это что?


Структура данных для вычисления пересечения интервалов...

AM>Зачем, например, под миллисекунды 1000 байт? По байту на каждое возможное значение? 60 байт на секунды, 60 на минуты и т.п. Зачем? Странный какой-то код у него.


А что не так, ты бы по-другому сделал? Вроде бы все верно, или нет?
Альтернатива — задавать интервалами, но это неэффективно.
Отредактировано 09.08.2021 19:56 bnk . Предыдущая версия .
Re[3]: Просидев на одном предприятии несколько лет...
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 09.08.21 21:49
Оценка: +1
Здравствуйте, bnk, Вы писали:

bnk>Структура данных для вычисления пересечения интервалов...

Да не, код реально говно. Можно было разить, на сущности, ввести абстракции.
bnk>А что не так, ты бы по-другому сделал? Вроде бы все верно, или нет?
Я не совсем понял задание, но вроде бы хранить всё это можно в банальном красно-чёрном дереве в UTC, тогда слева у тебя всё, что раньше, а справа, всё что позже.
bnk>Альтернатива — задавать интервалами, но это неэффективно.
Зависит от степени извращённости.
Sic luceat lux!
Re: Просидев на одном предприятии несколько лет...
От: mgu  
Дата: 10.08.21 01:48
Оценка:
Здравствуйте, vaa, Вы писали:

vaa>https://habr.com/ru/post/571342/

vaa>Читаю комменты второй день и .
vaa>3. почему-то все крутые прогеры пока только накидывают критики, но никто не показал образцовое решение.

Крутые прогеры(тм) обсуждают var vs. тип. Сразу видно, что не лохи, у которых пробелы vs. табуляция.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.