All streams
Search
Write a publication
Pull to refresh
63
0.5
Михаил @michael_v89

Программист

Send message
В информатике уже есть свои законы и теории — теория реляционных баз данных, принципы ООП, лямбда-исчисление, основы дизайна и юзабилити. Это и есть идеи, а программа, использующая эти идеи — это реализация. Уравнения Максвелла — это идея, но нельзя сделать один универсальный прибор, который эту идею реализует. Который будет одновременно и рацией, и электромотором, и карманным фонариком. И одну универсальную операционную систему сделать нельзя. Потому что цели у них разные, реализации разные, и даже устройства, на которых они работают, тоже разные.
— В laravel используется компонент из symphony. Как можно заметить, там куча проверок со словом trusted в названии.

— Как именно будет работать $request->getUri() зависит от реализации. Если кто-то сделает небезопасную реализацию, которая просто возвращает HTTP_HOST как есть без всяких проверок, значит тот кто разрабатывал и тот кто использует сам себе злобный буратино.

— Уровень опасности от такого использования заголовков примерно такой же, как если бы кто-то в HTML коде написал
<?= $_GET['id'] ?>
а мы бы в id передали код на javascript. Это не уязвимость в HTTP_HOST или в PHP. Просто не надо выводить недоверенные неэкранированные данные.
Приведите пожалуйста рабочий пример такого редиректа, выше вас уже просили об этом. Руками через telnet или curl естественно можно любые заголовки указать.
Поиграл немного с заголовками и редиректами. Теоретически, чтобы описанный метод сработал, надо чтобы "hacker.com" и "user.com" находились на одном хостинге, а браузер принимал редирект вида:
Location: http://www.hacker.com http://www.user.com

Тогда "www.hacker.com" попал бы в "Host", а строка " http://www.user.com" (с пробелом) считалась бы страницей и попала в "GET".

Браузеры такой редирект не принимают, реакция следующая:
Firefox: Firefox не может найти сервер www.hacker.com%20http
Chrome: Не удается найти DNS address сервера www.hacker.com%20http
IE: Не удается отобразить эту страницу

Если попытаться как-то модифицировать URL:
Location: http://www.hacker.com:http://www.user.com

то реакция будет такая:
Firefox: Ошибка искажения содержимого
Chrome: [молча ничего не загружает]
IE: Не удается отобразить эту страницу
Программа выделила сама себе память, что-то туда записала и выполнила. В чужой процесс не лезет, функция VirtualAlloc() импортирована явно, без использования GetProcAddress(). Что тут подозрительного? Мне кажется, здесь только поведение самого кода можно проверять.

PS: Знакомый рассказывал, что если сделать простой шифровальщик с XOR и не убирать статическую линковку с CRT, то антивирусы почти не реагируют, иногда может 1-2 предупреждения о подозрительности выдают. Если убрать или еще как-то уменьшать размер, сразу появляется куча срабатываний.
Насколько я понял из описания парадокса на википедии, его причины в изменении соотношений при суммировании показателей. В примере с поступлением же больше присутствует потеря информации при обощении (хотя статистические причины тоже есть).

Преувеличенный аналог примера из статьи. Допустим, у нас 2 факультета — учитель труда и педагог-психолог. На первый проходной балл 60, на второй 90. У всех поступающих балл меньше 90. Все мужчины подали заявление на первый факультет, все женщины на второй. Соответственно, все мужчины поступили, все женщины нет. Но у женщин условия поступления были другие, что в общей таблице не учитывается.

Я правильно понимаю, или где-то ошибся в рассуждениях?
Отладочное исключение. Генерироваться само не может, используется для, собственно, отладки.

Я бы сказал, оно в основном само и генерируется. Например, при установленном флаге TF оно генерируется после выполнения каждой инструкции. Что и используется отладчиками для трассировки и пошагового выполнения.
Итак, у нас есть метод findOne($id). Он получает данные из БД, делает $model = new User(), и устанавливает свойство $model->address = $dbData['address'], при этом $dbData['address'] = null. Вызывается метод __set().
Что именно вы предлагаете в нем делать, что означает "делать валидацию грамотно"? Считать, что NULL не является пустым значением и не бросать RequiredException? Или при загрузке из БД устанавливать специальную константу $model->scenario = "LOAD_FROM_DB", а в сеттере или валидаторе ее проверять?
Как именно вы используете эту иерархию с UserShortPassword, UserSimplePassword, если у вас всегда нужно ловить MultiException?
Ну и да:

$errors = $user->getErrors();
$passwordErrors = $errors['password'];  // можно isset добавить

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

Я поэтому и попросил привести пример (а не абстрактный участок кода), где это действительно будет нужно.

Зачем вы присваиваете модели данных пустое значения поля ради того, чтобы не показывать во view это значение?

Это просто пример, в общем случае у нас могут быть значения, которые можно присваивать из программы, но нельзя присваивать из пользовательского ввода. Другой пример — поле было необязательным, в базе куча записей с пустым значением, потом решили сделать обязательным, при загрузке из БД вызывается __set(), который бросает исключение.
Ваш код в статье ничем не отличается от эквивалентного кода без исключений.

$user = new User;
$user->load($_POST);

if ($user->save()) {
  redirect('hello.php');
} else {
  $this->view->assign('errors', $user->getErrors());
}

Можете привести какой-нибудь пример, где такое использование исключений дает что-нибудь полезное?

Еще такой вопрос. Допустим, перед повторным показом формы мне надо установить для поля пустое значение, которое пользователь должен заполнить. Например, сбросить пароль при ошибке авторизации. Получается, я делаю $model->password = '' и получаю исключение RequiredException?
Согласен, кое-где я преувеличил.
Для начала надо определиться с терминологией. Под знанием алгоритмов я понимаю знание алгоритмов обработки стандартных структур данных и умение оценивать их сложность в O-нотации — обходы графов, сложность различных сортировок и т.д. Примерно такой же смысл вкладывается авторами статей на эту тему. Насколько я понял, вы в своей статье называете это "детали теории вычислений".

Вся статья как раз о том, зачем нужно знать алгоритмы тем, кому нетривиальное не требуется.

Я говорю о том, что доказательства, приведенные в статье, ничего не доказывают — неправильно объясняют причины и не доказывают необходимость знания алгоритмов для выполнения любых задач.
Вырвал из контекста я те фразы, на основе которых в статье идет дальнейшее доказательство.

бесцельно потраченное время в классе по теории вычислений и алгоритмическому анализу

У вас эта мысль высказывается несколько раз. Я допускаю, что кто-то может быть обижен, но чтобы все "абстрактные программисты"? Поэтому и назвал передергиванием.

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

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

В-третьих – есть множество задач, которые нельзя решить простым вызовом API библиотеки или фреймворка. Что вы будете делать в таком случае? Тратить часы на поиски возможных решений и просить помощи у друга?

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

примитивный text-wrap в одном из визуальных компонентов

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

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

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

В свою очередь я вам привел другие примеры с таким же вопросом, ответить на которые вы не захотели.

понимание того, что происходит внутрях полезно знать всем

Понимание принципов работы и знание алгоритмов это не одно и то же.

Собственно, зачем я это все пишу. Я хочу сказать, что факт незнания программистом алгоритмов означает только то, что он не знает алгоритмы. Он ничего не говорит ни о знаниях и навыках в другой области, ни о сложности решаемых задач, ни даже об умении разобраться в алгоритмах в дальнейшем.
чтобы писать простенькие сайты и скрипты, не нужно особого знания алгоритмов и структур данных

А если не простенькие сайты и скрипты? Учетные системы какие-нибудь? Или загрузчик ОС? Или драйвер для FAT или NTFS для этого загрузчика?

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

Вот давайте не передергивать, уж от программиста-коллеги я бы такого не ожидал. Меня вот не учили алгоритмическому анализу, и до недавнего времени я был не в курсе, что такое O-нотация. Да, вот так, представляете? Такой вот у нас был университет. Да, мы делали реализации списков и деревьев. И я даже сам потом их делал для лабораторных, потому что меня немного пугали километровые объявления шаблонов из STL.

включая язык, на котором вы пишите.

Это вообще прекрасно, я даже не буду это комментировать)
(и это не опечатка, так как 2 раза встречается в тексте статьи)

и не бежали в гугл каждый раз, когда нужно сделать что-то нетривиальное.

Так о том и речь, что нетривиальное в большинстве случаев не требуется.

Какую бы задачу вы не решали – будь то простой сайт с выборкой данных из БД, или баш скрипт на сервере, вы будете использовать какие-то структуры данных.

При этом мне не надо знать, как они работают. Мне надо уметь ими пользоваться.

Почему в C# нежелательно использовать ArrayList, а вместо него использовать List?

Вот если я буду использовать List или ArrayList, и у меня вдруг все будет тормозить, я возьму и поищу информацию об этом. А в задачи, где это надо на этапе проектирования, я не лезу. Да и новичков в компании к таким задачам обычно не подпускают.

В-третьих – есть множество задач, которые нельзя решить простым вызовом API библиотеки или фреймворка. Что вы будете делать в таком случае?

Я, представьте себе, поищу информацию о том, как такие задачи решаются. А если в описании мне будет что-то непонятно, я поищу информацию и об этом.

Если же ваша работа заключается в написание SQL запроса и вбивание команды в консоль, то хочу вас огорчить: вы не программист

Позволю себе дать ссылку на свой же коммент: https://habrahabr.ru/post/279093/#comment_8803823
Вы считаете, что описанные там задачи не требуют навыков программирования?
В свое время задумался над закономерностями простых чисел. Получилось примерно так.



Первое уравнение имеет решения в точках, кратных N, второе в точках, кратных 1 (целые числа).

Рассмотрим первое уравнение отдельно. Заменим константу N на переменную y, получится трехмерный график z = sin(pi*x/y). Выглядит он как график синуса, у которого волна увеличивается с увеличением y.

В плоскости x = P, где P — некоторое целое число, уравнение будет такое:


График для P = 8


Уравнение имеет решения во всех точках y, где P/y дает целое число; y при этом может быть дробным, например 1.33(3) = 8 / 6.

Трехмерный график нам больше не нужен, поэтому для наглядности можно вернуться в 2 измерения и заменить обозначения y и z на обозначения x и y.

Чтобы найти целочисленные решения, можно сделать так.
Оба уравнения возведем в квадрат, точки пересечения с 0 от этого не изменятся. У первого уравнения график выше оси X. Второе уравнение возьмем со знаком минус, график ниже оси X.




График для P = 8 (точки пересечения: 1, 2, 4, 8):




Так вот. Число P является простым, если на промежутке [1, P] есть всего 2 решения — 1 и P.

При решении у меня получилась такая система:




Что в принципе и логично: x — целое число, P/x — другое целое число. Поэтому ничего особенного здесь нет, просто интересное наблюдение.
Если установлено расширение php_intl, можно вот так сделать:

$result = (new \MessageFormatter('ru-RU', '{n, spellout}'))->format(['n' => 321]);
echo $result;
// триста двадцать один

$result = (new \MessageFormatter('ru-RU', '{n, spellout,%spellout-cardinal-feminine}'))->format(['n' => 321]);
echo $result;
// триста двадцать одна
Таких сценариев больше, чем кажется. "Поле {fieldname} должно быть заполнено". Вместо {fieldname} может быть какое угодно название, при этом в верстке это просто одно строка текста. "Привет, {username}". "Привет" переводить надо, {username} нет. По пробелу разбивать?
Это может подойти для простых сайтов с парой страниц, но не более. Для сложных проще управлять переводами на своем сервере, чем на удаленном CDN.
Запросить в репозитории переведённый текст, передав как параметры исходный текст и контекст.
контекст было бы удобно задавать вроде URL:selector

Навскидку такие минусы:
— Верстка поменялась — половина переводов не работает.
— Перевод фраз с переменными числами, разные словоформы для разных чисел — 2 files, 10 files / 2 файла, 10 файлов
— Локализация дат — месяц-день-год или день-месяц-год
— Перевод многозначных слов типа "on", "from" или "to". Можно каждое такое слово оборачивать в span с определенным классом, но это кажется не очень удобным решением.
В универе делал модифицированный алгоритм быстрой сортировки, который сортирует только по краям массива, для лабораторной по визуализации опытов Пирсона. Надо было обозначить в результатах опытов некоторый рукав недалеко от верхней и нижней границы, который укладывается в заданную вероятность. Думаю, у кого-нибудь в работе могут быть похожие задачи.

А по работе не приходилось.

картинка

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

(первый коммент на этом сайте, написан вчера утром, пока одобрили, уже 10 раз про него написали))
Есть научно-фантастическая книжка на эту тему — «Мутант-59».

Information

Rating
1,928-th
Location
Россия
Registered
Activity