Обновить
26
ApeCoder@ApeCoder

Разработчик

6
Подписчики
Отправить сообщение

А где там первая попытка Али а где вторая? Если в таблице дата только второй попытке то ничего противоречащего утверждению я не вижу.

Как именно не сходится? В таблице все, кроме Алибабы и MS, меньше 82,304

А я вот как-то по чужим стектрейсам догадываюсь. Да и в своих (в релизной конфигурации) не всегда есть номера строк — в логах сервисов и прочее. А еще мне удобнее сразу видеть название куска, а не идти по стеку вверх и мотать исходники до коммента.

Фактически вы разрабатваете что-то что используется Васей как отдельный модуль. То есть есть high cohension внутри этого метода и low coupling с Васиным кодом. Сам по себе факт того, что это надо это признак для рефакторинга. Тесты нужны и для того, чтобы выявлять такие моменты.

Если это большой метод, то почему нельзя его вынести в отдельный класс или написать test-specific descendant для тестирования или сделать публичным, если это маленький метод почему нельзя чтобы коллега его добавил при разработке.

То есть названия функций в стектрейсах абсолютно бесполезны?

Get-DataFromWMI | %{ New-Object PSObject -Prop  @{ ComputerName =$_.Name, MyProperty = $_.XXX}}
(поскольку создана для Васи, который будет её юзать через два дня).

А почему юнит тест не может это покрыть?

Поинт не в атрибутах, а в том, что если все равно все на рефлекшене в тестах, то не надо стратегий :). Исключения можно хоть просто в самом тесте написать

Если рефлексию использовать для проверки, то можно не гененировать "стратегии" а тестировать только IsEquivalent. Подмножество свойств, которые надо сравнивать можно задать либо атрибутами либо выделить в отдельный класс (OrderHeader, OrderState, OrderVersion)

  1. Почему нельзя переопределить стандартный Equals а надо использовать IsEquivalent
  2. Зачем надо вводить новый слой косвенности на стратегиях, если все равно все сводится к тестированию через reflection? Можно было бы просто либо сравнивать через reflection либо просто в тесте перебирать свойства по очереди и их менять и проверять сто при разичии хотя бы в любом одном свойстве IsEquivalent возвращает true.

Понятно. В обычном императивном коде строки более насыщены (т.е. тут фактически каждый параметр на отдельной строке, при просто вызове функции будет несколько переметров на одной. Больше имеют значение семантические единицы, а не синтаксические

Что такое "деструктор в начале функции"?

Кстати в RFC K это маленькие функции а не числа


K(t) = 5A827999 ( 0 <= t <= 19)
K(t) = 6ED9EBA1 (20 <= t <= 39)
K(t) = 8F1BBCDC (40 <= t <= 59)
K(t) = CA62C1D6 (60 <= t <= 79).


private static (UInt32 A, UInt32 B, UInt32 C, UInt32 D, UInt32 E) DoIntermediateHashCalculationRounds(
            uint[] W,
            uint A,
            uint B,
            uint C,
            uint D,
            uint E)
        {
            for (var i = 0; i < 80; i++)
            {
                var (f, K) = GetHashingRoundParameters(i);

                var nextA = SHA1CircularShift(5, A) + f(B, C, D) + E + W[i] + K;
                E = D;
                D = C;
                C = SHA1CircularShift(30, B);
                B = A;
                A = nextA;
            }
            return (A, B, C, D, E);
        }

        private static (Func<uint, uint, uint, uint> f, UInt32 K) GetHashingRoundParameters(int roundIndex)
        {
            var parameterIndex = roundIndex / 20;
            Func<uint, uint, uint, uint>[] f = { f0, f1, f2, f3 };
            UInt32[] K = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };
            return (f[parameterIndex], K[parameterIndex]);
        }
Сильное заявление. Я предпочел бы заменить их мнемоническими константами.

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

10 аргументов в DoIntermediateHashCalculationRounds намекают что что-то не то.

В принципе, да, ABCD по сути типа массива промежуточных значений. Можно сделать структуру и передавать как целое (надо посмотреть, как это лучше C#)


В вызывающей функции появился цикл на 4, аналога которого вообще нет в ТЗ, и надо догадаться, что он задает диапазоны для t.

Я посмотрел перед этим Rozetta Code там для Ruby такая же штука и мне было понятно :)

взял вот отсюда


И отрефакторил функцию SHA1ProcessMessageBlock
https://pastebin.com/YRwsBG2M


Мне кажется, так взаимосвязи и что на что влияет понятнее

То есть написать по-другому нельзя? В чем тогда претензия к автору кода?

Претензий нет. Возможно он сделал все что мог. Но тут мы вроде договорились оптимизации не рассмативать
Я не могу. Насколько я помню С можно по крайней мере декларировать что используется в конкретном куске, а что нет.


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

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


Потому что это написано в ТЗ. Наше дело реализовать, математические доказательства тут неважны.

Если полный алгоритм написан в ТЗ — фактически надо разбивать на функции алгоритм в ТЗ. Чтобы было понятно.


Нет. Нам передали неизвестный нам алгоритм, который надо понять и предположительно исправить ошибку. Что удобнее понимать — в том виде в котором он есть, или если бы он дополнительно был разбит на много функций?

В том виде в котором он есть проще установить соответсвие в ТЗ. Если в ТЗ он правильно написан, то сверкой проще найти ошибку.


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


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

Ok. Постараюсь найти что-нибудь на C# и отрефакторить

Предложите свой вариант. Только полный, а не одну абстрактную функцию без тела.

Ну вот еще, это надо все это переписывать на язык, в котором можно все это нормально выразить.


Не знаю, почему они так написали, в описании ясно сказано — состоит из 80 раундов.

Зачем они написали комменты вообще? Почему важно, чтобы мы знали что вход что выход.


И-и вот мы снова к этому пришли. Чтобы что-то изменить в незнакомом алгоритме, надо его понять.

А кто говорил, что это не так? Чтобы его понять надо чтобы автор алгоритма передал что и почему он сделал. То есть почему первые N итераций так, а последующе M итераций сяк.


В данном случае мы имеем дело с вырожденным примером — нам передали уже готовый алгоритм, а мы его просто переводим с одного формального языка на другой, не понимая что и зачем — так?


Но тем не менее все равно можно рефакторингом а не комментариями выразить то, что мы о нем знаем. Хотя бы входы и выходы отдельных частей

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность